diff --git a/packages/svelte/src/internal/client/dom/blocks/boundary.js b/packages/svelte/src/internal/client/dom/blocks/boundary.js index 5b46427383..c8eb3ba6d8 100644 --- a/packages/svelte/src/internal/client/dom/blocks/boundary.js +++ b/packages/svelte/src/internal/client/dom/blocks/boundary.js @@ -164,13 +164,13 @@ export function boundary(node, props, children) { } // @ts-ignore - var sources = boundary.fn.sources; - for (var [source, entry] of sources) { - if (source.v !== entry.v) { - mark_reactions(source, DIRTY, source); + var forks = boundary.fn.forks; + for (var [signal, entry] of forks) { + if (signal.v !== entry.v) { + mark_reactions(signal, DIRTY); } } - sources.clear(); + forks.clear(); for (const fn of callbacks) fn(); callbacks.clear(); @@ -314,7 +314,7 @@ export function boundary(node, props, children) { }; // @ts-ignore - boundary.fn.sources = new Map(); + boundary.fn.forks = new Map(); // @ts-ignore boundary.fn.is_pending = () => props.pending; diff --git a/packages/svelte/src/internal/client/reactivity/sources.js b/packages/svelte/src/internal/client/reactivity/sources.js index f24eb5e904..9aff5c3250 100644 --- a/packages/svelte/src/internal/client/reactivity/sources.js +++ b/packages/svelte/src/internal/client/reactivity/sources.js @@ -170,7 +170,7 @@ export function set(source, value) { export function internal_set(source, value) { if (!source.equals(value)) { - mark_reactions(source, DIRTY, source); + mark_reactions(source, DIRTY); var old_value = source.v; source.v = value; @@ -258,10 +258,9 @@ export function update_pre(source, d = 1) { /** * @param {Value} signal * @param {number} status should be DIRTY or MAYBE_DIRTY - * @param {Source} [source] * @returns {void} */ -export function mark_reactions(signal, status, source) { +export function mark_reactions(signal, status) { var reactions = signal.reactions; if (reactions === null) return; @@ -289,9 +288,9 @@ export function mark_reactions(signal, status, source) { // If the signal a) was previously clean or b) is an unowned derived, then mark it if ((flags & (CLEAN | UNOWNED)) !== 0) { if ((flags & DERIVED) !== 0) { - mark_reactions(/** @type {Derived} */ (reaction), MAYBE_DIRTY, source); + mark_reactions(/** @type {Derived} */ (reaction), MAYBE_DIRTY); } else { - schedule_effect(/** @type {Effect} */ (reaction), source); + schedule_effect(/** @type {Effect} */ (reaction)); } } } diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 5d3bf020ed..008b94623e 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -40,7 +40,7 @@ import { update_derived } from './reactivity/deriveds.js'; import * as e from './errors.js'; -import { FILENAME } from '../../constants.js'; +import { FILENAME, UNINITIALIZED } from '../../constants.js'; import { tracing_mode_flag } from '../flags/index.js'; import { tracing_expressions, get_stack } from './dev/tracing.js'; import { @@ -783,24 +783,44 @@ function flush_deferred() { } } +/** + * @param {Source | Derived} signal + * @param {any} forks + */ +function fork_dependencies(signal, forks) { + var entry = forks.get(signal); + if (entry === undefined) { + entry = { v: signal.v }; + forks.set(signal, entry); + if ((signal.f & DERIVED) !== 0) { + var deps = /** @type {Derived} */ (signal).deps; + if (deps !== null) { + for (var i = 0; i < deps.length; i++) { + fork_dependencies(deps[i], forks); + } + } + } + } +} + /** * @param {Effect} signal - * @param {Source} [source] * @returns {void} */ -export function schedule_effect(signal, source) { - if (source && (signal.f & ASYNC_DERIVED) !== 0) { +export function schedule_effect(signal) { + if ((signal.f & ASYNC_DERIVED) !== 0) { if (active_effect === signal) { set_signal_status(signal, MAYBE_DIRTY); return; } var boundary = get_boundary(signal); // @ts-ignore - var sources = boundary.fn.sources; - var entry = sources.get(source); - if (entry === undefined) { - entry = { v: source.v }; - sources.set(source, entry); + var forks = boundary.fn.forks; + var deps = signal.deps; + if (deps !== null) { + for (var i = 0; i < deps.length; i++) { + fork_dependencies(deps[i], forks); + } } } @@ -1043,28 +1063,32 @@ export function get(signal) { } } - var value = signal.v; + var value = /** @type {V} */ (UNINITIALIZED); - if (is_derived) { - derived = /** @type {Derived} */ (signal); + var target_effect = event_boundary_effect ?? active_effect; - if (check_dirtiness(derived)) { - update_derived(derived); + if (target_effect !== null && !is_flushing_async_derived) { + var boundary = get_boundary(target_effect); + if (boundary !== null) { + // @ts-ignore + var forks = boundary.fn.forks; + var entry = forks.get(signal); + if (entry !== undefined) { + value = entry.v; + } } - value = signal.v; - } else { - var target_effect = event_boundary_effect ?? active_effect; - - if (target_effect !== null && !is_flushing_async_derived) { - var boundary = get_boundary(target_effect); - if (boundary !== null) { - // @ts-ignore - var sources = boundary.fn.sources; - var entry = sources.get(signal); - if (entry !== undefined) { - value = entry.v; - } + } + + if (value === UNINITIALIZED) { + if (is_derived) { + derived = /** @type {Derived} */ (signal); + + if (check_dirtiness(derived)) { + update_derived(derived); } + value = signal.v; + } else { + value = signal.v; } }