diff --git a/packages/svelte/src/internal/client/reactivity/deriveds.js b/packages/svelte/src/internal/client/reactivity/deriveds.js index f897a4e738..5a43c18aa5 100644 --- a/packages/svelte/src/internal/client/reactivity/deriveds.js +++ b/packages/svelte/src/internal/client/reactivity/deriveds.js @@ -1,7 +1,6 @@ import { DEV } from 'esm-env'; import { CLEAN, DERIVED, UNINITIALIZED, UNOWNED } from '../constants.js'; import { current_consumer, current_effect } from '../runtime.js'; -import { push_reference } from './utils.js'; import { default_equals, safe_equal } from './equality.js'; /** @@ -11,15 +10,15 @@ import { default_equals, safe_equal } from './equality.js'; */ /*#__NO_SIDE_EFFECTS__*/ export function derived(fn) { - const is_unowned = current_effect === null; - const flags = is_unowned ? DERIVED | UNOWNED : DERIVED; + let flags = DERIVED | CLEAN; + if (current_effect === null) flags |= UNOWNED; /** @type {import('#client').Derived} */ const signal = { c: null, d: null, e: default_equals, - f: flags | CLEAN, + f: flags, i: fn, r: null, // @ts-expect-error @@ -35,7 +34,11 @@ export function derived(fn) { } if (current_consumer !== null) { - push_reference(current_consumer, signal); + if (current_consumer.r === null) { + current_consumer.r = [signal]; + } else { + current_consumer.r.push(signal); + } } return signal; diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js index 58f69ed682..7e2c0624d9 100644 --- a/packages/svelte/src/internal/client/reactivity/effects.js +++ b/packages/svelte/src/internal/client/reactivity/effects.js @@ -18,7 +18,6 @@ import { ROOT_EFFECT, DESTROYED } from '../constants.js'; -import { push_reference } from './utils.js'; /** * @param {import('./types.js').EffectType} type @@ -45,7 +44,8 @@ function create_effect(type, fn, sync, schedule) { out: null, dom: null, ran: false, - parent: current_effect + parent: current_effect, + children: null }; if (DEV) { @@ -55,7 +55,12 @@ function create_effect(type, fn, sync, schedule) { if (current_effect !== null) { signal.l = current_effect.l + 1; - push_reference(current_effect, signal); + + if (current_effect.children === null) { + current_effect.children = [signal]; + } else { + current_effect.children.push(signal); + } } if (schedule) { @@ -240,8 +245,8 @@ function pause_children(effect, transitions, local) { } } - if (effect.r) { - for (const child of effect.r) { + if (effect.children) { + for (const child of effect.children) { pause_children(child, transitions, false); // TODO separate child effects from child deriveds } } @@ -263,8 +268,8 @@ export function destroy_effect(effect) { remove(effect.dom); } - if (effect.r) { - for (const child of effect.r) { + if (effect.children) { + for (const child of effect.children) { destroy_effect(child); } } @@ -286,8 +291,8 @@ function resume_children(effect, local) { execute_effect(/** @type {import('#client').Effect} */ (effect)); } - if (effect.r) { - for (const child of effect.r) { + if (effect.children) { + for (const child of effect.children) { resume_children(child, false); } } diff --git a/packages/svelte/src/internal/client/reactivity/types.d.ts b/packages/svelte/src/internal/client/reactivity/types.d.ts index 93fa7249b2..529260f8bf 100644 --- a/packages/svelte/src/internal/client/reactivity/types.d.ts +++ b/packages/svelte/src/internal/client/reactivity/types.d.ts @@ -67,8 +67,8 @@ export interface Effect { f: SignalFlags; /** init: The function that we invoke for effects and computeds */ i: null | (() => void | (() => void)); - /** references: Anything that a signal owns */ - r: null | Reaction[]; + /** deriveds belonging to this effect */ + r: null | Derived[]; /** teardown */ v: null | (() => void); /** level: the depth from the root signal, used for ordering render/pre-effects topologically **/ @@ -83,8 +83,8 @@ export interface Effect { dom: null | TemplateNode | Array; /** Whether the effect ran or not */ ran: boolean; - /** The parent effect */ parent: null | Effect; + children: null | Effect[]; } export type Reaction = Derived | Effect; diff --git a/packages/svelte/src/internal/client/reactivity/utils.js b/packages/svelte/src/internal/client/reactivity/utils.js deleted file mode 100644 index ed7f50c664..0000000000 --- a/packages/svelte/src/internal/client/reactivity/utils.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * @param {import('#client').Reaction} target_signal - * @param {import('#client').Reaction} ref_signal - * @returns {void} - */ -export function push_reference(target_signal, ref_signal) { - const references = target_signal.r; - if (references === null) { - target_signal.r = [ref_signal]; - } else { - references.push(ref_signal); - } -} diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 282ebf3497..905cfb8d86 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -356,16 +356,16 @@ function remove_consumers(signal, start_index) { } /** - * @param {import('#client').Reaction} signal + * @param {import('#client').Effect} effect * @returns {void} */ -function destroy_references(signal) { - const references = signal.r; - signal.r = null; - if (references !== null) { +function destroy_references(effect) { + const deriveds = effect.r; + effect.r = null; + if (deriveds !== null) { let i; - for (i = 0; i < references.length; i++) { - destroy_signal(references[i]); + for (i = 0; i < deriveds.length; i++) { + destroy_signal(deriveds[i]); } } } @@ -656,7 +656,6 @@ export async function tick() { function update_derived(signal, force_schedule) { const previous_updating_derived = updating_derived; updating_derived = true; - destroy_references(signal); const value = execute_signal_fn(signal); updating_derived = previous_updating_derived; const status =