import { statSync } from "node:fs"; import { resolve } from "node:path"; const root = process.cwd(); const watchedFiles = [ resolve(root, "scripts/caserun-native-server.ts"), resolve(root, "scripts/caserun-native-fixtures.ts") ]; let child: ReturnType | null = null; let signature = sourceSignature(); let stopping = false; let restarting = false; function sourceSignature(): string | null { try { return watchedFiles.map((path) => { const source = statSync(path); return `${path}:${source.mtimeMs}:${source.size}`; }).join("|"); } catch (error) { if (error instanceof Error && "code" in error && error.code === "ENOENT") return null; throw error; } } function startChild(reason: string): void { const spawned = spawnNativeServer(); child = spawned; console.log(JSON.stringify({ event: "caserun-native-reload", mode: "native-test", reason, pid: spawned.pid })); void spawned.exited.then((exitCode) => { if (!stopping && child === spawned) console.log(JSON.stringify({ event: "caserun-native-exit", exitCode })); }); } function spawnNativeServer() { return Bun.spawn([process.execPath, "scripts/caserun-native-server.ts"], { cwd: root, stdin: "ignore", stdout: "inherit", stderr: "inherit" }); } async function stopChild(): Promise { const runningChild = child; if (!runningChild) return; if (runningChild.exitCode === null) runningChild.kill("SIGTERM"); await runningChild.exited; if (child === runningChild) child = null; } startChild("initial"); async function reloadIfChanged(): Promise { if (stopping || restarting) return; const nextSignature = sourceSignature(); if (nextSignature === null || nextSignature === signature) return; signature = nextSignature; restarting = true; try { await stopChild(); if (!stopping) startChild("source-change"); } finally { restarting = false; } } const timer = setInterval(() => void reloadIfChanged(), 100); async function shutdown(): Promise { if (stopping) return; stopping = true; clearInterval(timer); await stopChild(); process.exit(0); } process.on("SIGINT", () => void shutdown()); process.on("SIGTERM", () => void shutdown());