From 034b540a776f58220782735c8d1303171d363bd4 Mon Sep 17 00:00:00 2001 From: xarmian Date: Sun, 31 May 2026 07:53:54 -0400 Subject: [PATCH] fix(web): de-reactify open-transition trackers in 3 more modals/banners (#687) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sweep follow-up to BUG-1687. ConnectBanner, CreateCollectionModal, and ConnectWorkspaceModal each tracked their open→close transition with a `$state` variable (`prevOpen`/`lastOpen`) that their `$effect`/`$effect.pre` both read and wrote — the same self-invalidating pattern that silently wedges Svelte's effect scheduler in production builds on close. Make each tracker a plain `let` (they're only used for edge-detection inside the effect), so the effects depend solely on `open`/`connectOpen` and never re-trigger themselves. Found via a codebase-wide audit; these were the only other genuine matches. --- web/src/lib/components/ConnectBanner.svelte | 7 +++++-- web/src/lib/components/ConnectWorkspaceModal.svelte | 5 ++++- .../components/collections/CreateCollectionModal.svelte | 7 +++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/web/src/lib/components/ConnectBanner.svelte b/web/src/lib/components/ConnectBanner.svelte index 542d58c7..a2a0860c 100644 --- a/web/src/lib/components/ConnectBanner.svelte +++ b/web/src/lib/components/ConnectBanner.svelte @@ -97,8 +97,11 @@ // doesn't know which tab actually triggered the agent connection; // any close is good-enough signal. Tracking `prevOpen` is the // minimum reactive shape to detect the open → closed transition - // without re-firing on every render. - let prevOpen = $state(false); + // without re-firing on every render. PLAIN variable (not $state): it's + // only read/written for edge-detection inside the effect below — making + // it $state makes the effect self-invalidating, which silently wedges + // the effect scheduler in prod builds (see BUG-1687 / ShareDialog). + let prevOpen = false; $effect.pre(() => { if (prevOpen && !connectOpen) { refreshHasAgentActivity(wsSlug); diff --git a/web/src/lib/components/ConnectWorkspaceModal.svelte b/web/src/lib/components/ConnectWorkspaceModal.svelte index 04a8b351..6314b0fd 100644 --- a/web/src/lib/components/ConnectWorkspaceModal.svelte +++ b/web/src/lib/components/ConnectWorkspaceModal.svelte @@ -57,7 +57,10 @@ // user manually switched tabs, so we use a $state seeded by an $effect // that fires only on the open→true transition. let activeTab = $state('cli'); - let lastOpen = $state(false); + // PLAIN variable (not $state): only used for edge-detection inside the + // effect below. As $state it makes the effect self-invalidating, which + // silently wedges the effect scheduler in prod builds (BUG-1687). + let lastOpen = false; $effect(() => { if (open && !lastOpen) { activeTab = mcpPublicUrl ? 'agent' : 'cli'; diff --git a/web/src/lib/components/collections/CreateCollectionModal.svelte b/web/src/lib/components/collections/CreateCollectionModal.svelte index 328e5d1a..2ed98d1f 100644 --- a/web/src/lib/components/collections/CreateCollectionModal.svelte +++ b/web/src/lib/components/collections/CreateCollectionModal.svelte @@ -108,8 +108,11 @@ } }); - // Track previous open state to detect open transitions - let prevOpen = $state(false); + // Track previous open state to detect open transitions. PLAIN variable + // (not $state): only used for edge-detection inside the effect below. + // As $state it makes the effect self-invalidating, silently wedging the + // effect scheduler in prod builds (see BUG-1687 / ShareDialog). + let prevOpen = false; // Reset to step 1 whenever the modal opens (false -> true transition) $effect.pre(() => {