diff --git a/apps/desktop/src/main/index.ts b/apps/desktop/src/main/index.ts index c91ef7c..eeaf345 100644 --- a/apps/desktop/src/main/index.ts +++ b/apps/desktop/src/main/index.ts @@ -1,13 +1,24 @@ import { spawn } from 'node:child_process' +import type { AddressInfo } from 'node:net' +import { createServer } from 'node:net' import { join } from 'node:path' import { app, BrowserWindow, shell } from 'electron' const DEV_SERVER_URL = 'http://localhost:3000' -const PROD_SERVER_PORT = 23_410 let mainWindow: BrowserWindow | null = null let serverProcess: ReturnType | null = null +const getAvailablePort = (): Promise => + new Promise((resolve, reject) => { + const server = createServer() + server.listen(0, () => { + const { port } = server.address() as AddressInfo + server.close(() => resolve(port)) + }) + server.on('error', reject) + }) + const isServerReady = async (url: string): Promise => { try { const response = await fetch(url, { method: 'HEAD' }) @@ -29,14 +40,14 @@ const waitForServer = async ( return false } -const spawnServer = (): string => { +const spawnServer = (port: number): string => { const binaryName = process.platform === 'win32' ? 'server.exe' : 'server' const binaryPath = join(process.resourcesPath, binaryName) serverProcess = spawn(binaryPath, [], { env: { ...process.env, - PORT: String(PROD_SERVER_PORT), + PORT: String(port), HOST: '127.0.0.1', }, stdio: 'pipe', @@ -54,14 +65,15 @@ const spawnServer = (): string => { console.error('Failed to start server:', err) }) - return `http://127.0.0.1:${PROD_SERVER_PORT}` + return `http://127.0.0.1:${port}` } -const getServerUrl = (): string => { +const getServerUrl = async (): Promise => { if (!app.isPackaged) { return DEV_SERVER_URL } - return spawnServer() + const port = await getAvailablePort() + return spawnServer(port) } const createWindow = async () => { @@ -87,7 +99,7 @@ const createWindow = async () => { } mainWindow.show() - const serverUrl = getServerUrl() + const serverUrl = await getServerUrl() console.log(`Waiting for server at ${serverUrl}...`) const ready = await waitForServer(serverUrl)