fix(frontend): break useMany reconcile feedback loop

The reconcile effect read `handles.length` / `handles[i]` for the
"unchanged?" early-exit optimisation and then `handles.splice(...)`
to publish the new array. Reading `handles` inside the effect
registered it as a dependency; the subsequent splice re-fired the
effect; ad infinitum (Svelte threw
`effect_update_depth_exceeded`).

Wrap the comparison reads in `untrack` so the effect's only
tracked dependency stays `getSpecs()`. The splice still fires the
downstream readers of `handles` (the whole point of `useMany`'s
reactivity); it just doesn't re-enter its own producer.
This commit is contained in:
Diego Imbert
2026-05-15 15:17:05 +02:00
parent 2d432c6308
commit 7ccb2b7941
+8 -1
View File
@@ -415,7 +415,14 @@ export const UserDraft = {
// are cached by mapKey, so two reconciles with the same spec set
// produce reference-equal arrays. Avoids dirtying downstream
// reactive readers on no-op `$effect` re-runs.
const unchanged = handles.length === next.length && handles.every((h, i) => h === next[i])
//
// The read side is wrapped in `untrack` so the effect doesn't
// register `handles` as one of its own dependencies; otherwise
// the splice below would re-fire the effect, splice again, …
// (Svelte raises `effect_update_depth_exceeded`).
const unchanged = untrack(
() => handles.length === next.length && handles.every((h, i) => h === next[i])
)
if (!unchanged) handles.splice(0, handles.length, ...next)
}