From 19d74d00d6210963eaaa3718c53e488f312e7460 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Thu, 23 Apr 2026 18:16:22 -0400 Subject: [PATCH] refactor(web): drop useDelayed sync-timeout hack; fix test timing instead MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The synchronous pre-timeout in the implementation was a band-aid for a missing flushSync() in the third test. $effect callbacks are scheduled as microtasks and don't run until flushed — the test set source=true before the initial effect had a chance to register the setTimeout, so advanceTimersByTime fired nothing. Proper fix: call flushSync() after $effect.root so the initial effect runs synchronously, then advance fake timers. Removed the duplicate setTimeout branch from useDelayed — one code path, no race. Co-Authored-By: Claude Opus 4.7 --- web/src/lib/utils/useDelayed.svelte.test.ts | 1 + web/src/lib/utils/useDelayed.svelte.ts | 9 --------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/web/src/lib/utils/useDelayed.svelte.test.ts b/web/src/lib/utils/useDelayed.svelte.test.ts index 90eea419..cd304853 100644 --- a/web/src/lib/utils/useDelayed.svelte.test.ts +++ b/web/src/lib/utils/useDelayed.svelte.test.ts @@ -61,6 +61,7 @@ describe('useDelayed', () => { const cleanup = $effect.root(() => { delayed = useDelayed(() => source, 100); }); + flushSync(); // run the initial $effect so the setTimeout is scheduled vi.advanceTimersByTime(200); expect(delayed.value).toBe(true); diff --git a/web/src/lib/utils/useDelayed.svelte.ts b/web/src/lib/utils/useDelayed.svelte.ts index b688275a..06eecc5e 100644 --- a/web/src/lib/utils/useDelayed.svelte.ts +++ b/web/src/lib/utils/useDelayed.svelte.ts @@ -11,15 +11,6 @@ export function useDelayed( let delayed = $state(false); let timeout: ReturnType | null = null; - // Schedule the initial timeout synchronously so tests that advance fake - // timers before the first reactive flush still see the correct value. - if (source()) { - timeout = setTimeout(() => { - delayed = true; - timeout = null; - }, delayMs); - } - $effect(() => { const v = source(); if (timeout) {