Files
2026-07-18 05:34:08 +02:00

76 lines
2.2 KiB
TypeScript

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<typeof spawnNativeServer> | 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<void> {
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<void> {
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<void> {
if (stopping) return;
stopping = true;
clearInterval(timer);
await stopChild();
process.exit(0);
}
process.on("SIGINT", () => void shutdown());
process.on("SIGTERM", () => void shutdown());