/** Coalesce pushes, serialize refreshes, and recover missed events after reconnect or tab activation. */ export function betaUpdates(load: () => Promise, betaId?: () => number): () => void { let timer: ReturnType | undefined; let stopped = false, running = false, pending = false; const schedule = () => { pending = true; if (stopped || running || timer || document.hidden) return; timer = setTimeout(async () => { timer = undefined; if (stopped || document.hidden) return; running = true; pending = false; try { await load(); } catch { /* The page owns its error state; later events can retry. */ } finally { running = false; if (pending) schedule(); } }, 200); }; const changed = (event: Event) => { if (!betaId || (event as CustomEvent).detail?.betaId === betaId()) schedule(); }; const visible = () => { if (!document.hidden) schedule(); }; window.addEventListener('ec:beta-changed', changed); window.addEventListener('ec:pipeline-connected', schedule); window.addEventListener('ec:fleet-changed', schedule); document.addEventListener('visibilitychange', visible); return () => { stopped = true; clearTimeout(timer); window.removeEventListener('ec:beta-changed', changed); window.removeEventListener('ec:pipeline-connected', schedule); window.removeEventListener('ec:fleet-changed', schedule); document.removeEventListener('visibilitychange', visible); }; }