fuzzyworld

when-am-i / files / scripts / lib / server.mts

server.mts

Blame: the commit that last changed each line · file · history

48a625b7 2026-06-19 Pavel Safronov1// Dev-server lifecycle for the screenshot scripts: reuse a running Vite server
2// on 5173 if there is one, otherwise start one and stop it when finished.
3
4import { spawn, type ChildProcess } from 'node:child_process';
5import http from 'node:http';
6import path from 'node:path';
7import { fileURLToPath } from 'node:url';
8
9const __dirname = path.dirname(fileURLToPath(import.meta.url));
10export const REPO_ROOT = path.resolve(__dirname, '../..');
68dcf3ed 2026-06-25 Pavel Safronov11
12// Port is overridable via SCREENSHOT_PORT so screenshots can be generated
13// against *this* checkout even when another Vite server (e.g. a parallel
14// Conductor workspace) already holds the default 5173. Defaults to 5173.
15const PORT = process.env.SCREENSHOT_PORT ?? '5173';
16export const BASE_URL = `http://127.0.0.1:${PORT}/when-am-i/`;
48a625b7 2026-06-19 Pavel Safronov17
18function isUp(url: string): Promise<boolean> {
19 return new Promise((resolve) => {
20 const req = http.get(url, (res) => {
21 res.resume();
22 resolve(true);
23 });
24 req.on('error', () => resolve(false));
25 req.setTimeout(1000, () => {
26 req.destroy();
27 resolve(false);
28 });
29 });
30}
31
32const wait = (ms: number) => new Promise((r) => setTimeout(r, ms));
33
34export interface DevServer {
35 stop: () => void;
36}
37
38export async function startDevServer(): Promise<DevServer> {
39 if (await isUp(BASE_URL)) {
40 console.log(' ℹ️ Reusing the dev server already running on :5173');
41 return { stop: () => {} };
42 }
43
68dcf3ed 2026-06-25 Pavel Safronov44 console.log(` 🚀 Starting Vite dev server on :${PORT}…`);
45 const proc: ChildProcess = spawn('npx', ['vite', '--port', PORT, '--strictPort'], {
48a625b7 2026-06-19 Pavel Safronov46 cwd: REPO_ROOT,
47 stdio: 'ignore',
48 });
49
50 const start = Date.now();
51 while (Date.now() - start < 30_000) {
52 if (await isUp(BASE_URL)) {
53 console.log(' ✅ Dev server ready');
54 return { stop: () => proc.kill() };
55 }
56 await wait(500);
57 }
58 proc.kill();
59 throw new Error('Dev server did not start within 30s');
60}