import { useEffect, useRef } from 'react'; /** How long the quiet has to hold before the screen calls itself ready. */ const quietMs = 150; /** * The readiness signal for the screenshot loop. `networkidle` will not do and cannot do: a live * run keeps the SSE open by construction. The screen says by itself when it has decided what to * draw — and "I am waiting" is a decision too, for a route that is shot for the sake of the * waiting. * * ⚠ The flag is ONE-WAY: once it has settled it never goes out again. It answers the screenshot * loop's question "has the screen come together already?", not "is the network quiet right now": * a background refetch on focus return and an update from a live run happen constantly and by * construction, and without the latch the frame would be shot in a race with them. A route shot for * the sake of the waiting does not touch the latch — it never gets as far as "ready". * * Two conditions of the latch, and each one was bought with a frame: * * 1. While NOT A SINGLE request has flown, there is no attribute at all. On the first effect * nothing is in flight, and the previous edition announced `ready` at that moment — the gate * shot the frame before the first read had started (found by acceptance S3.6). The absence of * the attribute the loop waits out silently, and the library is read by every screen. * 2. The quiet has to HOLD. The reads of the second wave — the book, the chapters, the bank — turn * on only after the library has answered, and between the waves the counter honestly drops to * zero: a latch without the hold closed in that pit, and `/scale` was shot with the line * "loading chapters…" (measured with a frame, not with reasoning). */ export function useScreenshotFlag(waiting: boolean): void { const started = useRef(false); const settled = useRef(false); useEffect(() => { if (waiting) started.current = true; if (!started.current) return; if (waiting || settled.current) { document.documentElement.dataset.screen = settled.current ? 'ready' : 'loading'; return; } const timer = setTimeout(() => { settled.current = true; document.documentElement.dataset.screen = 'ready'; }, quietMs); return () => { clearTimeout(timer); }; }, [waiting]); }