From ed12a54339a2a2b8a1d61dfd251984da0dede221 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 15 Apr 2026 22:26:04 +0200 Subject: [PATCH] fix(fileloader): use untrack to prevent infinite reload loop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit loadFile() reads fileUrl synchronously before its first await. When called from a \$effect, Svelte tracks that read and re-runs the effect every time fileUrl changes — i.e. after every successful load — causing an infinite cycle of file fetches and PdfViewer remounts. Fix: wrap the fileUrl read in untrack() so callers never accidentally subscribe to fileUrl changes. Co-Authored-By: Claude Sonnet 4.6 --- frontend/src/lib/hooks/useFileLoader.svelte.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frontend/src/lib/hooks/useFileLoader.svelte.ts b/frontend/src/lib/hooks/useFileLoader.svelte.ts index a2b7356e..f7e7feee 100644 --- a/frontend/src/lib/hooks/useFileLoader.svelte.ts +++ b/frontend/src/lib/hooks/useFileLoader.svelte.ts @@ -1,3 +1,5 @@ +import { untrack } from 'svelte'; + export function createFileLoader() { let fileUrl = $state(''); let isLoading = $state(false); @@ -6,7 +8,11 @@ export function createFileLoader() { async function loadFile(url: string): Promise { isLoading = true; fileError = ''; - if (fileUrl) URL.revokeObjectURL(fileUrl); + // untrack prevents callers ($effect) from accidentally subscribing to fileUrl. + // Without it, the calling effect would re-run every time fileUrl changes (i.e. + // on every successful load), creating an infinite load loop. + const prev = untrack(() => fileUrl); + if (prev) URL.revokeObjectURL(prev); fileUrl = ''; try { -- 2.49.1