From 5497b3d0bccc578a2de8e08f9d45eeb33d02d055 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Sun, 12 May 2024 18:08:40 +0100 Subject: [PATCH] fix: ensure all effect cleanup functions are untracked (#11567) * fix: ensure all effect cleanup functions are untracked * add test --------- Co-authored-by: Rich Harris --- .changeset/dirty-eyes-itch.md | 5 +++++ .../src/internal/client/reactivity/effects.js | 5 +++++ .../svelte/src/internal/client/runtime.js | 5 +++++ .../effect-untrack-teardown/_config.js | 4 ++++ .../effect-untrack-teardown/main.svelte | 19 +++++++++++++++++++ 5 files changed, 38 insertions(+) create mode 100644 .changeset/dirty-eyes-itch.md create mode 100644 packages/svelte/tests/runtime-runes/samples/effect-untrack-teardown/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/effect-untrack-teardown/main.svelte diff --git a/.changeset/dirty-eyes-itch.md b/.changeset/dirty-eyes-itch.md new file mode 100644 index 0000000000..a134e973c2 --- /dev/null +++ b/.changeset/dirty-eyes-itch.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: ensure all effect cleanup functions are untracked diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js index fe2fc12a4d..6411e8109a 100644 --- a/packages/svelte/src/internal/client/reactivity/effects.js +++ b/packages/svelte/src/internal/client/reactivity/effects.js @@ -3,6 +3,7 @@ import { current_component_context, current_effect, current_reaction, + current_untracking, destroy_effect_children, dev_current_component_function, execute_effect, @@ -14,6 +15,7 @@ import { set_is_destroying_effect, set_is_flushing_effect, set_signal_status, + set_untracking, untrack } from '../runtime.js'; import { @@ -295,11 +297,14 @@ export function execute_effect_teardown(effect) { var teardown = effect.teardown; if (teardown !== null) { const previously_destroying_effect = is_destroying_effect; + const previous_untracking = current_untracking; set_is_destroying_effect(true); + set_untracking(true); try { teardown.call(null); } finally { set_is_destroying_effect(previously_destroying_effect); + set_untracking(previous_untracking); } } } diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 4cdfb4de25..ddbeaafe36 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -48,6 +48,11 @@ export function set_is_destroying_effect(value) { is_destroying_effect = value; } +/** @param {boolean} value */ +export function set_untracking(value) { + current_untracking = value; +} + // Used for $inspect export let is_batching_effect = false; let is_inspecting_signal = false; diff --git a/packages/svelte/tests/runtime-runes/samples/effect-untrack-teardown/_config.js b/packages/svelte/tests/runtime-runes/samples/effect-untrack-teardown/_config.js new file mode 100644 index 0000000000..ab5722723a --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/effect-untrack-teardown/_config.js @@ -0,0 +1,4 @@ +import { test } from '../../test'; + +// nothing to test here — if the teardown function is not untracked, effect will loop +export default test({}); diff --git a/packages/svelte/tests/runtime-runes/samples/effect-untrack-teardown/main.svelte b/packages/svelte/tests/runtime-runes/samples/effect-untrack-teardown/main.svelte new file mode 100644 index 0000000000..a2a7adef61 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/effect-untrack-teardown/main.svelte @@ -0,0 +1,19 @@ + + +{#key key} +
test
+{/key}