Files
kamilkrzywda 1983d17099
CI / build + unit + e2e (pull_request) Successful in 11m7s
push updated state to clients over SSE (ISS-129)
2026-09-22 20:44:13 +00:00

30 lines
1.1 KiB
TypeScript

// ISS-129 (v0.57.0): in-process fan-out registry for the SSE state stream (/api/events). The app
// runs as one long-lived server process (`next start`; instrumentation.ts already keeps background
// sim state alive) — no new dependencies, no WS upgrade needed. The Set lives on globalThis because
// Next.js gives instrumentation.ts (where broadcast() fires from the background tick) and route
// handlers (where subscribe() happens in /api/events) separate module instances; a plain `let` would
// give each its own empty set and no push would ever be delivered.
type Push = (text: string) => void;
const g = globalThis as unknown as { __flightSseSubscribers?: Set<Push> };
const subscribers: Set<Push> = (g.__flightSseSubscribers ??= new Set());
export function subscribe(fn: Push): () => void {
subscribers.add(fn);
return () => {
subscribers.delete(fn);
};
}
// Call each subscriber safely — one dead stream must not take the others down.
export function broadcast(text: string): void {
for (const fn of [...subscribers]) {
try {
fn(text);
} catch {
// subscriber's stream is gone; its own cleanup unsubscribes it
}
}
}