mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-13 21:01:21 +08:00
Correctness: - killLocalDashboard now waits for the process to actually exit (not just for /health to stop answering) before returning, so the replacement dashboard doesn't hit EADDRINUSE while the old socket is still held. - Bail out without waiting/SIGKILL when the recorded pid is gone (ESRCH) or owned by another process (EPERM, i.e. pid was recycled), avoiding a hang and reducing the chance of signalling an unrelated process. Quality / dedup: - Extract shared helpers: lib/own-package.ts (single source for reading the CLI's own package.json + bin resolution; now used by index.ts, sentry.ts, self-update.ts — was duplicated 3x) and lib/child-process.ts (forwardSignals, used by dev.ts, emulator.ts, self-update.ts). - Extract pure decision functions for testability: decideReexec() and shouldRestartDashboard()/processExists(). - Fix a stale comment that claimed jsdom is the test env (it's node). Tests: +35 cases — decideReexec branches, resolveBinName/parseOwnPackage, isVersionNewer edges (v-prefix, x.y, both-prerelease, large nums), resolveLatestVersion (TTL boundary, malformed/non-string body, fetch URL, npm_config_registry), buildNpxInvocation (windows, spaced/dashed args), shouldRestartDashboard table, killLocalDashboard early returns, dev-env-state back-compat + clobber. 167 pass.
23 lines
731 B
TypeScript
23 lines
731 B
TypeScript
import type { ChildProcess } from "child_process";
|
|
|
|
// Forward SIGINT/SIGTERM from this process to a spawned child until the
|
|
// returned cleanup function is called (call it once the child has exited).
|
|
// Killing is best-effort: a child that already exited throws, which we ignore.
|
|
export function forwardSignals(child: ChildProcess): () => void {
|
|
const forward = (signal: NodeJS.Signals) => () => {
|
|
try {
|
|
child.kill(signal);
|
|
} catch {
|
|
// best-effort
|
|
}
|
|
};
|
|
const onSigint = forward("SIGINT");
|
|
const onSigterm = forward("SIGTERM");
|
|
process.on("SIGINT", onSigint);
|
|
process.on("SIGTERM", onSigterm);
|
|
return () => {
|
|
process.off("SIGINT", onSigint);
|
|
process.off("SIGTERM", onSigterm);
|
|
};
|
|
}
|