From f06287e30dcf0ec82ca0361e1fb2a12f78d6a6e3 Mon Sep 17 00:00:00 2001 From: abhay-codes07 Date: Thu, 2 Jul 2026 08:54:47 +0530 Subject: [PATCH] fix(web): make the finished-processing refresh effect actually fire The effect in useProcessingDocuments that refetches document lists when a document finishes processing depended on [processingMap.keys, queryClient.refetchQueries]. Both are prototype methods - Map.prototype.keys is the same function object for every Map instance - so the dependencies never changed, the effect ran exactly once on mount (when both the previous and current id sets are empty), and the delayed documents-with-memories / dashboard-recents refetch never happened. The eslint-disable on the dependency array hid the lint error that would have caught this. Depend on processingMap itself, and memoize docs on data so the map's identity only changes when the poll payload changes (React Query's structural sharing keeps data referentially stable between identical polls). Without that, the map would get a new identity every render and each re-run's cleanup could cancel the pending 1s/4s refresh timers before they fire. --- apps/web/hooks/use-processing-documents.ts | 27 ++++++++++++++-------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/apps/web/hooks/use-processing-documents.ts b/apps/web/hooks/use-processing-documents.ts index 72ea06fda..99e5ca56e 100644 --- a/apps/web/hooks/use-processing-documents.ts +++ b/apps/web/hooks/use-processing-documents.ts @@ -37,12 +37,20 @@ export function useProcessingDocuments() { staleTime: 0, }) - const docs = - ( - data as - | { documents?: Array<{ id?: string | null; status?: string | null }> } - | undefined - )?.documents ?? [] + // Memoized on `data` (kept referentially stable between polls by React + // Query's structural sharing) so `processingMap` only changes identity + // when the poll payload actually changes — the effect below depends on it. + const docs = useMemo( + () => + ( + data as + | { + documents?: Array<{ id?: string | null; status?: string | null }> + } + | undefined + )?.documents ?? [], + [data], + ) const processingMap = useMemo(() => { const map = new Map() @@ -52,7 +60,6 @@ export function useProcessingDocuments() { } } return map - // eslint-disable-next-line react-hooks/exhaustive-deps }, [docs]) // Detect docs that just finished (present in previous poll, absent now). @@ -80,8 +87,10 @@ export function useProcessingDocuments() { clearTimeout(t1) clearTimeout(t2) } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [processingMap.keys, queryClient.refetchQueries]) + // `processingMap` (not `processingMap.keys` — that's the shared + // Map.prototype method, identical for every map, so the effect would + // never re-run and finished docs would never trigger a refresh). + }, [processingMap, queryClient]) return processingMap }