diff --git a/packages/svelte/src/internal/client/reactivity/deriveds.js b/packages/svelte/src/internal/client/reactivity/deriveds.js index b9e1511879..f0bbb10a31 100644 --- a/packages/svelte/src/internal/client/reactivity/deriveds.js +++ b/packages/svelte/src/internal/client/reactivity/deriveds.js @@ -1,6 +1,6 @@ import { DEV } from 'esm-env'; -import { CLEAN, DERIVED, UNINITIALIZED, UNOWNED } from '../constants.js'; -import { current_reaction, current_effect } from '../runtime.js'; +import { CLEAN, DERIVED, DESTROYED, UNINITIALIZED, UNOWNED } from '../constants.js'; +import { current_reaction, current_effect, set_signal_status } from '../runtime.js'; import { default_equals, safe_equal } from './equality.js'; /** @@ -54,3 +54,9 @@ export function derived_safe_equal(fn) { signal.eq = safe_equal; return signal; } + +/** @param {import('#client').Derived} derived */ +export function destroy_derived(derived) { + // TODO what needs to happen here, if anything? + set_signal_status(derived, DESTROYED); +} diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js index c6224fb648..5757a47cd5 100644 --- a/packages/svelte/src/internal/client/reactivity/effects.js +++ b/packages/svelte/src/internal/client/reactivity/effects.js @@ -17,6 +17,7 @@ import { ROOT_EFFECT, DESTROYED } from '../constants.js'; +import { destroy_derived } from './deriveds.js'; /** * @param {import('./types.js').EffectType} type @@ -248,7 +249,7 @@ function pause_children(effect, transitions, local) { } /** - * @param {import('#client').Effect} effect TODO this isn't just block effects, it's deriveds etc too + * @param {import('#client').Effect} effect */ export function destroy_effect(effect) { if ((effect.f & DESTROYED) !== 0) return; @@ -263,6 +264,21 @@ export function destroy_effect(effect) { remove(effect.dom); } + effect.v?.(); + + destroy_effect_children(effect); +} + +/** + * @param {import('#client').Effect} effect + */ +export function destroy_effect_children(effect) { + if (effect.r) { + for (const derived of effect.r) { + destroy_derived(derived); + } + } + if (effect.children) { for (const child of effect.children) { destroy_effect(child); diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index d81744fcc6..52f0993c3b 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -8,7 +8,7 @@ import { object_prototype } from './utils.js'; import { unstate } from './proxy.js'; -import { pre_effect } from './reactivity/effects.js'; +import { destroy_effect_children, pre_effect } from './reactivity/effects.js'; import { EFFECT, PRE_EFFECT, @@ -379,6 +379,9 @@ function destroy_references(effect) { } } +/** @param {import('#client').Derived} effect */ +function destroy_effect(effect) {} + /** * @param {import('#client').Effect} effect * @returns {void} @@ -399,7 +402,7 @@ export function execute_effect(effect) { if ((effect.f & BRANCH_EFFECT) === 0) { // branch effects (i.e. {#if ...} blocks) need to keep their references // TODO their children should detach themselves from signal.r when destroyed - destroy_references(effect); + destroy_effect_children(effect); } if (teardown !== null) {