fix scan page tdz crash: break flush/stopFlushing useCallback cycle
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled

Prod minified bundle crashed with 'can't access lexical declaration 'o'
before initialization' because flush was memoized with stopFlushing in its
deps, and stopFlushing was memoized with flush in its deps — circular.
In dev this still worked (refs paper over TDZ), but Vite's minifier emitted
the declarations in an order that tripped the temporal dead zone.

Extract the interval-clearing into a plain inline helper (clearFlushTimer)
that both flush and stopFlushing call. flush no longer depends on
stopFlushing; the cycle is gone.
This commit is contained in:
2026-04-13 08:17:57 +02:00
parent 3c1c8dd8f0
commit e4c771d39e
2 changed files with 15 additions and 5 deletions

View File

@@ -0,0 +1 @@
{"sessionId":"7dcf4561-975e-4864-a297-1814a6ac9aea","pid":12187,"acquiredAt":1776060371368}

View File

@@ -49,6 +49,16 @@ export function ScanPage() {
const bufRef = useRef<SseBuf>(freshBuf());
const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);
// Stop the periodic flush interval. Inlined into flush() to avoid a
// circular useCallback dep (flush → stopFlushing → flush) that tripped
// TDZ in prod builds: "can't access lexical declaration 'o' before initialization".
const clearFlushTimer = () => {
if (timerRef.current) {
clearInterval(timerRef.current);
timerRef.current = null;
}
};
// Flush buffered SSE data to React state
const flush = useCallback(() => {
const b = bufRef.current;
@@ -72,16 +82,16 @@ export function ScanPage() {
setStatusLabel(`Scan complete — ${d.scanned ?? "?"} items, ${d.errors ?? 0} errors`);
setScanComplete(true);
setStatus((prev) => (prev ? { ...prev, running: false } : prev));
stopFlushing();
clearFlushTimer();
}
if (b.lost) {
b.lost = false;
setStatusLabel("Scan connection lost — refresh to see current status");
setStatus((prev) => (prev ? { ...prev, running: false } : prev));
stopFlushing();
clearFlushTimer();
}
}, [stopFlushing]);
}, []);
const startFlushing = useCallback(() => {
if (timerRef.current) return;
@@ -90,8 +100,7 @@ export function ScanPage() {
const stopFlushing = useCallback(() => {
if (!timerRef.current) return;
clearInterval(timerRef.current);
timerRef.current = null;
clearFlushTimer();
flush(); // final flush
}, [flush]);