From 514c8ea1886fa07e22e8fab1a270ccccf83511e7 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 11 Mar 2024 16:58:24 -0400 Subject: [PATCH] separate reaction.r into reaction.effects and reaction.deriveds --- .../internal/client/reactivity/deriveds.js | 15 +++++---- .../src/internal/client/reactivity/effects.js | 31 ++++++++----------- .../src/internal/client/reactivity/types.d.ts | 15 ++++----- .../svelte/src/internal/client/runtime.js | 25 +++++++-------- 4 files changed, 42 insertions(+), 44 deletions(-) diff --git a/packages/svelte/src/internal/client/reactivity/deriveds.js b/packages/svelte/src/internal/client/reactivity/deriveds.js index 5f0f85ab0e..db49bb1610 100644 --- a/packages/svelte/src/internal/client/reactivity/deriveds.js +++ b/packages/svelte/src/internal/client/reactivity/deriveds.js @@ -7,7 +7,6 @@ import { remove_reactions, set_signal_status } from '../runtime.js'; -import { push_reference } from './effects.js'; import { default_equals, safe_equals } from './equality.js'; /** @@ -27,9 +26,9 @@ export function derived(fn) { eq: default_equals, f: flags, fn, - r: null, - // @ts-expect-error - v: UNINITIALIZED, + effects: null, + deriveds: null, + v: /** @type {V} */ (UNINITIALIZED), w: 0 }; @@ -38,7 +37,11 @@ export function derived(fn) { } if (current_reaction !== null) { - push_reference(current_reaction, signal); + if (current_reaction.deriveds === null) { + current_reaction.deriveds = [signal]; + } else { + current_reaction.deriveds.push(signal); + } } return signal; @@ -64,6 +67,6 @@ export function destroy_derived(signal) { destroy_references(signal); remove_reactions(signal, 0); // @ts-expect-error `signal.i` cannot be `null` while the signal is alive - signal.fn = signal.r = signal.x = signal.b = signal.deps = signal.reactions = null; + signal.fn = signal.effects = signal.x = signal.b = signal.deps = signal.reactions = null; 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 8fcfc69f26..222954d08c 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_block, current_component_context, current_effect, + current_reaction, destroy_references, flush_local_render_effects, get, @@ -17,20 +18,6 @@ import { set } from './sources.js'; import { is_array } from '../utils.js'; import { run_all } from '../../common.js'; -/** - * @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); - } -} - /** * @param {import('./types.js').EffectType} type * @param {(() => void | (() => void)) | ((b: import('#client').Block) => void | (() => void))} fn @@ -47,7 +34,8 @@ function create_effect(type, fn, sync, block, schedule) { f: type | DIRTY, l: 0, fn, - r: null, + effects: null, + deriveds: null, v: null, w: 0, ctx: current_component_context, @@ -56,8 +44,15 @@ function create_effect(type, fn, sync, block, schedule) { if (current_effect !== null) { signal.l = current_effect.l + 1; - if ((type & MANAGED) === 0) { - push_reference(current_effect, signal); + } + + if ((type & MANAGED) === 0) { + if (current_reaction !== null) { + if (current_reaction.effects === null) { + current_reaction.effects = [signal]; + } else { + current_reaction.effects.push(signal); + } } } @@ -253,7 +248,7 @@ export function destroy_effect(signal) { const destroy = signal.y; destroy_references(signal); remove_reactions(signal, 0); - signal.fn = signal.r = signal.y = signal.ctx = signal.block = signal.deps = null; + signal.fn = signal.effects = signal.y = signal.ctx = signal.block = signal.deps = null; set_signal_status(signal, DESTROYED); if (destroy !== null) { if (is_array(destroy)) { diff --git a/packages/svelte/src/internal/client/reactivity/types.d.ts b/packages/svelte/src/internal/client/reactivity/types.d.ts index a5d5f266a8..bd3b0db021 100644 --- a/packages/svelte/src/internal/client/reactivity/types.d.ts +++ b/packages/svelte/src/internal/client/reactivity/types.d.ts @@ -25,11 +25,10 @@ export interface Derived extends Source { deps: null | Value[]; /** The derived function */ fn: () => V; - - // TODO get rid of these - - /** references: Anything that a signal owns */ - r: null | Reaction[]; + /** Effects created inside this signal */ + effects: null | Effect[]; + /** Deriveds created inside this signal */ + deriveds: null | Derived[]; } export interface DerivedDebug extends Derived { @@ -49,8 +48,10 @@ export type Effect = { f: number; /** init: The function that we invoke for effects and computeds */ fn: null | (() => void | (() => void)) | ((b: Block, s: Signal) => void | (() => void)); - /** references: Anything that a signal owns */ - r: null | Reaction[]; + /** Effects created inside this signal */ + effects: null | Effect[]; + /** Deriveds created inside this signal */ + deriveds: null | Derived[]; /** value: The latest value for this signal, doubles as the teardown for effects */ v: null | Function; /** level: the depth from the root signal, used for ordering render/pre-effects topologically **/ diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index b6c9481b2a..bd932ffb0e 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -373,19 +373,18 @@ export function remove_reactions(signal, start_index) { * @returns {void} */ export function destroy_references(signal) { - const references = signal.r; - signal.r = null; - if (references !== null) { - let i; - for (i = 0; i < references.length; i++) { - var reference = references[i]; - if ((reference.f & DERIVED) !== 0) { - // TODO make signal.r only contain deriveds or effects - destroy_derived(/** @type {import('#client').Derived} */ (reference)); - } else { - destroy_effect(/** @type {import('#client').Effect} */ (reference)); - } + 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 (var i = 0; i < signal.deriveds.length; i += 1) { + destroy_derived(signal.deriveds[i]); } + signal.deriveds = null; } } @@ -822,7 +821,7 @@ export function invalidate_inner_signals(fn) { * @returns {void} */ function mark_subtree_children_inert(signal, inert, visited_blocks) { - const references = signal.r; + const references = signal.effects; if (references !== null) { let i; for (i = 0; i < references.length; i++) {