From a4e0eb13d8f78310b0eed43e5d392ec349b8545b Mon Sep 17 00:00:00 2001 From: xarmian Date: Sun, 31 May 2026 07:51:20 -0400 Subject: [PATCH] fix(share): stop ShareDialog effect from wedging the scheduler in prod (#686) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ShareDialog tracked the open transition with `let prevOpen = $state(false)` and an `$effect.pre` that both read and wrote `prevOpen` — a self-invalidating effect. In dev this trips `effect_update_depth_exceeded`; in a production build the guard differs and it silently wedges Svelte's global effect scheduler the moment `open` flips on close. Result: after opening+closing the share dialog, effects stop flushing app-wide — clicks change the URL but the view never re-renders (no error, no CPU spin). Make `prevOpen` a plain variable (it's only used for edge-detection inside the effect), so the effect depends solely on `open` and never re-triggers itself. --- web/src/lib/components/ShareDialog.svelte | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/web/src/lib/components/ShareDialog.svelte b/web/src/lib/components/ShareDialog.svelte index 35b8cd85..75ce0ed4 100644 --- a/web/src/lib/components/ShareDialog.svelte +++ b/web/src/lib/components/ShareDialog.svelte @@ -33,8 +33,12 @@ let newlyCreatedLinkId = $state(null); let deletingLinkId = $state(null); - // Track previous open state to detect open transitions - let prevOpen = $state(false); + // Track previous open state to detect open transitions. This is a PLAIN + // variable (not $state) on purpose: it's only read/written inside the + // effect below for edge-detection. Making it $state turned the effect + // into a self-invalidating loop (it writes a state it reads), which in a + // production build silently wedges Svelte's effect scheduler on close. + let prevOpen = false; $effect.pre(() => { if (open && !prevOpen) {