import { createServer } from "vite"; import { Server as NodeHttpServer } from "node:http"; import { startApplicationRuntime, stopApplicationRuntime } from "../appview/src/runtime.ts"; import { attachMultiplayerEndpoint, inferMultiplayerBasePath, type MultiplayerEndpoint } from "../appview/src/multiplayer/server.ts"; let vite: Awaited> | null = null; let multiplayer: MultiplayerEndpoint | null = null; let closing: Promise | null = null; const portText = optionValue("port") ?? process.env.DEV_PORT ?? "5173"; const port = Number(portText); if (!/^\d+$/.test(portText) || !Number.isInteger(port) || port < 0 || port > 65535) { throw new Error("The Vite development port must be an integer between 0 and 65535."); } await startApplicationRuntime(); try { vite = await createServer({ server: { host: optionValue("host") ?? process.env.DEV_HOST ?? "127.0.0.1", port, strictPort: process.argv.includes("--strictPort") || process.argv.includes("--strict-port"), }, }); const viteHttpServer = vite.httpServer; if (!(viteHttpServer instanceof NodeHttpServer)) throw new Error("Vite did not provide a Node HTTP server for multiplayer upgrades."); multiplayer = attachMultiplayerEndpoint(viteHttpServer, { basePath: inferMultiplayerBasePath(), publicOrigin: null, trustedProxyIps: process.env.TRUSTED_PROXY_IPS?.split(",").map((value) => value.trim()).filter(Boolean) ?? [], passThroughUnknownUpgrades: true, }); await vite.listen(); vite.printUrls(); } catch (error) { await multiplayer?.close(); await vite?.close(); await stopApplicationRuntime(); throw error; } process.on("SIGTERM", () => { void close(); }); process.on("SIGINT", () => { void close(); }); function close(): Promise { if (closing) return closing; closing = (async () => { await multiplayer?.close(); await vite?.close(); await stopApplicationRuntime(); })(); return closing; } function optionValue(name: string): string | undefined { const option = `--${name}`; const inline = process.argv.find((argument) => argument.startsWith(`${option}=`)); if (inline) return inline.slice(option.length + 1); const index = process.argv.indexOf(option); const value = process.argv[index + 1]; return index < 0 || value === undefined || value.startsWith("-") ? undefined : value; }