forked from boos/BoosAPI
feat: implement macOS notarization and ad-hoc signing in afterSign script
feat: add run-server script to manage server execution and compatibility checks feat: create main application logic for desktop with window management, server handling, and auto-updater test: add unit tests for desktop runtime helpers feat: implement desktop server environment configuration and health check test: add tests for server configuration and desktop routes feat: add native module guard for better-sqlite3 compatibility test: add tests for native module guard functionality test: add comprehensive tests for account verification feedback handling feat: implement account verification feedback helpers chore: add TypeScript configuration for desktop builds
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
type DesktopServerEnvInput = {
|
||||
inheritedEnv?: NodeJS.ProcessEnv;
|
||||
userDataDir: string;
|
||||
logsDir: string;
|
||||
port: number;
|
||||
};
|
||||
|
||||
type WaitForServerReadyInput = {
|
||||
url: string;
|
||||
fetcher?: (input: string, init?: RequestInit) => Promise<{ ok: boolean }>;
|
||||
timeoutMs?: number;
|
||||
intervalMs?: number;
|
||||
};
|
||||
|
||||
type ServerExitState = {
|
||||
code: number | null;
|
||||
signal: NodeJS.Signals | null;
|
||||
};
|
||||
|
||||
const DEFAULT_READY_TIMEOUT_MS = 30_000;
|
||||
const DEFAULT_READY_INTERVAL_MS = 250;
|
||||
|
||||
function delay(ms: number) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
export function buildDesktopServerEnv(input: DesktopServerEnvInput): NodeJS.ProcessEnv {
|
||||
return {
|
||||
...(input.inheritedEnv || {}),
|
||||
HOST: '127.0.0.1',
|
||||
PORT: String(input.port),
|
||||
DATA_DIR: input.userDataDir,
|
||||
METAPI_DESKTOP: '1',
|
||||
METAPI_LOG_DIR: input.logsDir,
|
||||
};
|
||||
}
|
||||
|
||||
export function createDesktopServerUrl(port: number): string {
|
||||
return `http://127.0.0.1:${port}`;
|
||||
}
|
||||
|
||||
export function createDesktopHealthUrl(port: number): string {
|
||||
return `${createDesktopServerUrl(port)}/api/desktop/health`;
|
||||
}
|
||||
|
||||
export async function waitForServerReady(input: WaitForServerReadyInput): Promise<void> {
|
||||
const fetcher = input.fetcher || ((url: string, init?: RequestInit) => fetch(url, init));
|
||||
const timeoutMs = input.timeoutMs ?? DEFAULT_READY_TIMEOUT_MS;
|
||||
const intervalMs = input.intervalMs ?? DEFAULT_READY_INTERVAL_MS;
|
||||
const startedAt = Date.now();
|
||||
|
||||
while (Date.now() - startedAt <= timeoutMs) {
|
||||
try {
|
||||
const response = await fetcher(input.url, { method: 'GET' });
|
||||
if (response.ok) return;
|
||||
} catch {
|
||||
// Retry until timeout.
|
||||
}
|
||||
await delay(intervalMs);
|
||||
}
|
||||
|
||||
throw new Error('Timed out waiting for metapi desktop server');
|
||||
}
|
||||
|
||||
export function isFatalServerExit(exitState: ServerExitState): boolean {
|
||||
return exitState.code !== null && exitState.code !== 0 && !exitState.signal;
|
||||
}
|
||||
Reference in New Issue
Block a user