fix scan page tdz crash: break flush/stopFlushing useCallback cycle
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled
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:
1
.claude/scheduled_tasks.lock
Normal file
1
.claude/scheduled_tasks.lock
Normal file
@@ -0,0 +1 @@
|
||||
{"sessionId":"7dcf4561-975e-4864-a297-1814a6ac9aea","pid":12187,"acquiredAt":1776060371368}
|
||||
@@ -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]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user