diff --git a/packages/svelte/src/internal/client/reactivity/batch.js b/packages/svelte/src/internal/client/reactivity/batch.js index e321e8478d..2970a44b61 100644 --- a/packages/svelte/src/internal/client/reactivity/batch.js +++ b/packages/svelte/src/internal/client/reactivity/batch.js @@ -2,7 +2,9 @@ import { CLEAN, DIRTY } from '#client/constants'; import { flush_queued_effects, + process_effects, schedule_effect, + set_queued_root_effects, set_signal_status, update_effect } from '../runtime.js'; @@ -52,9 +54,28 @@ export class Batch { /** @type {Set} */ skipped_effects = new Set(); - apply() { + apply() {} + + /** + * + * @param {Effect[]} root_effects + */ + process(root_effects) { + set_queued_root_effects([]); + var current_values = new Map(); + for (const batch of batches) { + if (batch === this) continue; + + for (const [source, previous] of batch.#previous) { + if (!this.#current.has(source)) { + current_values.set(source, source.v); + source.v = previous; + } + } + } + for (const [source, current] of this.#current) { // TODO this shouldn't be necessary, but tests fail otherwise, // presumably because we need a try-finally somewhere, and the @@ -72,42 +93,33 @@ export class Batch { schedule_effect(e); } - for (const batch of batches) { - if (batch === this) continue; - - for (const [source, previous] of batch.#previous) { - if (!this.#previous.has(source)) { - current_values.set(source, source.v); - source.v = previous; - } - } - } - this.render_effects = []; this.effects = []; - return () => { - if (this.async_effects.length === 0 && this.settled()) { - var render_effects = this.render_effects; - var effects = this.effects; - - this.render_effects = []; - this.effects = []; + for (const root of root_effects) { + process_effects(this, root); + } - // commit changes - for (const fn of this.#callbacks) { - fn(); - } + if (this.async_effects.length === 0 && this.settled()) { + var render_effects = this.render_effects; + var effects = this.effects; - this.#callbacks.clear(); + this.render_effects = []; + this.effects = []; - flush_queued_effects(render_effects); - flush_queued_effects(effects); - } else { - for (const e of this.render_effects) set_signal_status(e, CLEAN); - for (const e of this.effects) set_signal_status(e, CLEAN); + // commit changes + for (const fn of this.#callbacks) { + fn(); } + this.#callbacks.clear(); + + flush_queued_effects(render_effects); + flush_queued_effects(effects); + } else { + for (const e of this.render_effects) set_signal_status(e, CLEAN); + for (const e of this.effects) set_signal_status(e, CLEAN); + for (const [source, value] of current_values) { source.v = value; } @@ -117,7 +129,7 @@ export class Batch { } this.async_effects = []; - }; + } } /** diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index d39d384247..43ceb408bd 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -77,6 +77,11 @@ export function set_is_destroying_effect(value) { /** @type {Effect[]} */ let queued_root_effects = []; +/** @param {Effect[]} v */ +export function set_queued_root_effects(v) { + queued_root_effects = v; +} + /** @type {Effect[]} Stack of effects, dev only */ let dev_effect_stack = []; // Handle signal reactivity tree dependencies and reactions @@ -695,16 +700,7 @@ function flush_queued_root_effects() { infinite_loop_guard(); } - var revert = batch.apply(); - - var root_effects = queued_root_effects; - queued_root_effects = []; - - for (const root of root_effects) { - process_effects(batch, root); - } - - revert(); + batch.process(queued_root_effects); old_values.clear(); } @@ -805,7 +801,7 @@ export function schedule_effect(signal) { * @param {Batch} batch * @param {Effect} root */ -function process_effects(batch, root) { +export function process_effects(batch, root) { root.f ^= CLEAN; var effect = root.first;