diff --git a/.changeset/witty-phones-retire.md b/.changeset/witty-phones-retire.md new file mode 100644 index 000000000000..912410b6b05d --- /dev/null +++ b/.changeset/witty-phones-retire.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: handle duplicate signal dependencies gracefully diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 2283e547c7dd..bf5cfa65141e 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -419,10 +419,15 @@ function remove_reaction(signal, dependency) { export function remove_reactions(signal, start_index) { const dependencies = signal.deps; if (dependencies !== null) { - const active_dependencies = start_index === 0 ? null : dependencies.slice(0, start_index); + var active_dependencies = start_index === 0 ? null : dependencies.slice(0, start_index); + var visited = new Set(); let i; for (i = start_index; i < dependencies.length; i++) { const dependency = dependencies[i]; + if (visited.has(dependency)) { + continue; + } + visited.add(dependency); // Avoid removing a reaction if we know that it is active (start_index will not be 0) if (active_dependencies === null || !active_dependencies.includes(dependency)) { remove_reaction(signal, dependency); @@ -774,10 +779,7 @@ export function get(signal) { ) { if (current_dependencies === null) { current_dependencies = [signal]; - } else if ( - current_dependencies[current_dependencies.length - 1] !== signal && - !current_dependencies.includes(signal) - ) { + } else if (current_dependencies[current_dependencies.length - 1] !== signal) { current_dependencies.push(signal); } }