diff --git a/packages/svelte/src/internal/client/reactivity/deriveds.js b/packages/svelte/src/internal/client/reactivity/deriveds.js index b258e486ba..dd31cc154b 100644 --- a/packages/svelte/src/internal/client/reactivity/deriveds.js +++ b/packages/svelte/src/internal/client/reactivity/deriveds.js @@ -3,7 +3,6 @@ import { CLEAN, DERIVED, DESTROYED, DIRTY, MAYBE_DIRTY, UNOWNED } from '../const import { current_reaction, current_effect, - destroy_children, remove_reactions, set_signal_status, mark_reactions, @@ -11,6 +10,7 @@ import { execute_reaction_fn } from '../runtime.js'; import { equals, safe_equals } from './equality.js'; +import { destroy_effect } from './effects.js'; export let updating_derived = false; @@ -42,10 +42,11 @@ export function derived(fn) { } if (current_reaction !== null && (current_reaction.f & DERIVED) !== 0) { - if (current_reaction.deriveds === null) { - current_reaction.deriveds = [signal]; + var current_derived = /** @type {import('#client').Derived} */ (current_reaction); + if (current_derived.deriveds === null) { + current_derived.deriveds = [signal]; } else { - current_reaction.deriveds.push(signal); + current_derived.deriveds.push(signal); } } @@ -64,6 +65,27 @@ export function derived_safe_equal(fn) { return signal; } +/** + * @param {import('./types.js').Derived} signal + * @returns {void} + */ +function destroy_derived_children(signal) { + // TODO: should it be possible to create effects in deriveds given they're meant to be pure? + if (signal.effects) { + for (var i = 0; i < signal.effects.length; i += 1) { + destroy_effect(signal.effects[i]); + } + signal.effects = null; + } + + if (signal.deriveds) { + for (i = 0; i < signal.deriveds.length; i += 1) { + destroy_derived(signal.deriveds[i]); + } + signal.deriveds = null; + } +} + /** * @param {import('#client').Derived} derived * @param {boolean} force_schedule @@ -72,7 +94,7 @@ export function derived_safe_equal(fn) { export function update_derived(derived, force_schedule) { var previous_updating_derived = updating_derived; updating_derived = true; - destroy_children(derived); + destroy_derived_children(derived); var value = execute_reaction_fn(derived); updating_derived = previous_updating_derived; @@ -98,7 +120,7 @@ export function update_derived(derived, force_schedule) { * @returns {void} */ export function destroy_derived(signal) { - destroy_children(signal); + destroy_derived_children(signal); remove_reactions(signal, 0); set_signal_status(signal, DESTROYED); diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js index f4f52fff11..680bef6a0d 100644 --- a/packages/svelte/src/internal/client/reactivity/effects.js +++ b/packages/svelte/src/internal/client/reactivity/effects.js @@ -46,7 +46,6 @@ function create_effect(type, fn, sync) { f: type | DIRTY, fn, effects: null, - deriveds: null, teardown: null, ctx: current_component_context, transitions: null diff --git a/packages/svelte/src/internal/client/reactivity/types.d.ts b/packages/svelte/src/internal/client/reactivity/types.d.ts index a4afb6c468..3686e372b0 100644 --- a/packages/svelte/src/internal/client/reactivity/types.d.ts +++ b/packages/svelte/src/internal/client/reactivity/types.d.ts @@ -23,13 +23,13 @@ export interface Reaction extends Signal { deps: null | Value[]; /** Effects created inside this signal */ effects: null | Effect[]; - /** Deriveds created inside this signal */ - deriveds: null | Derived[]; } export interface Derived extends Value, Reaction { /** The derived function */ fn: () => V; + /** Deriveds created inside this signal */ + deriveds: null | Derived[]; } export interface Effect extends Reaction { diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 0354e2d1aa..27c8f82f0a 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -349,7 +349,7 @@ export function remove_reactions(signal, start_index) { } /** - * @param {import('./types.js').Reaction} signal + * @param {import('./types.js').Effect} signal * @returns {void} */ export function destroy_children(signal) { @@ -359,13 +359,6 @@ export function destroy_children(signal) { } signal.effects = null; } - - if (signal.deriveds) { - for (i = 0; i < signal.deriveds.length; i += 1) { - destroy_derived(signal.deriveds[i]); - } - signal.deriveds = null; - } } /**