diff --git a/packages/svelte/src/internal/client/dom/blocks/boundary.js b/packages/svelte/src/internal/client/dom/blocks/boundary.js index 57641c7a9c..8d85b24421 100644 --- a/packages/svelte/src/internal/client/dom/blocks/boundary.js +++ b/packages/svelte/src/internal/client/dom/blocks/boundary.js @@ -306,7 +306,7 @@ export class Boundary { if (this.#main_effect !== null) { // TODO do we also need to `resume_effect` here? - schedule_effect(this.#main_effect); + // schedule_effect(this.#main_effect); } } } diff --git a/packages/svelte/src/internal/client/reactivity/deriveds.js b/packages/svelte/src/internal/client/reactivity/deriveds.js index 390aa51115..5a385ce0b3 100644 --- a/packages/svelte/src/internal/client/reactivity/deriveds.js +++ b/packages/svelte/src/internal/client/reactivity/deriveds.js @@ -138,7 +138,8 @@ export function async_derived(fn, location) { internal_set(signal, v); }); } else { - internal_set(signal, v); + signal.v = v; + // internal_set(signal, v); } if (DEV && location !== undefined) { diff --git a/packages/svelte/src/internal/client/reactivity/forks.js b/packages/svelte/src/internal/client/reactivity/forks.js index 1c04f3104c..f450d215f9 100644 --- a/packages/svelte/src/internal/client/reactivity/forks.js +++ b/packages/svelte/src/internal/client/reactivity/forks.js @@ -1,5 +1,4 @@ /** @import { Effect, Source } from '#client' */ - import { flush_sync } from '../runtime.js'; import { internal_set } from './sources.js'; @@ -17,48 +16,57 @@ export class Fork { /** @type {Map} */ previous = new Map(); + /** @type {Map} */ + current = new Map(); + /** @type {Set} */ skipped_effects = new Set(); #pending = 0; - /** - * @param {Source} source - * @param {any} value - */ - capture(source, value) { - if (!this.previous.has(source)) { - this.previous.set(source, value); - } - } - - /** - * - * @param {() => void} fn - */ - flush(fn) { + apply() { var values = new Map(); + for (const source of this.previous.keys()) { + values.set(source, source.v); + } + for (const fork of forks) { if (fork === this) continue; for (const [source, previous] of fork.previous) { - if (this.previous.has(source)) continue; - - values.set(source, source.v); - source.v = previous; - // internal_set(source, previous); + if (!values.has(source)) { + values.set(source, source.v); + // internal_set(source, previous); + source.v = previous; + } } } - try { - fn(); - } finally { + for (const [source, current] of this.current) { + source.v = current; + // internal_set(source, current); + } + + return () => { for (const [source, value] of values) { - // internal_set(source, value); source.v = value; } + + active_fork = null; + }; + } + + /** + * @param {Source} source + * @param {any} value + */ + capture(source, value) { + if (!this.previous.has(source)) { + this.previous.set(source, value); } + + this.current.set(source, source.v); } remove() { diff --git a/packages/svelte/src/internal/client/reactivity/sources.js b/packages/svelte/src/internal/client/reactivity/sources.js index 33a23251ea..20b36b3cc0 100644 --- a/packages/svelte/src/internal/client/reactivity/sources.js +++ b/packages/svelte/src/internal/client/reactivity/sources.js @@ -170,6 +170,8 @@ export function set(source, value) { * @returns {V} */ export function internal_set(source, value) { + // console.trace('internal_set', source.v, value); + if (!source.equals(value)) { var old_value = source.v; source.v = value; diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index f642d704b4..340ec0fe9f 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -695,6 +695,9 @@ function flush_queued_root_effects(root_effects) { var previously_flushing_effect = is_flushing_effect; is_flushing_effect = true; + var fork = /** @type {Fork} */ (active_fork); + var revert = fork.apply(); + try { for (var i = 0; i < length; i++) { var effect = root_effects[i]; @@ -703,17 +706,23 @@ function flush_queued_root_effects(root_effects) { effect.f ^= CLEAN; } - var fork = /** @type {Fork} */ (active_fork); var collected_effects = process_effects(effect); if (fork.settled()) { flush_queued_effects(collected_effects); - fork.remove(); } } } finally { is_flushing_effect = previously_flushing_effect; - Fork.unset(); + + // TODO this doesn't seem quite right — may run into + // interesting cases where there are multiple roots. + // it'll do for now though + if (fork.settled()) { + fork.remove(); + } + + revert(); } }