From 48a781e2b14176392f3be571bd98404d9696ad44 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 5 May 2025 14:53:05 +0200 Subject: [PATCH] fix --- packages/svelte/src/internal/client/dom/blocks/async.js | 6 ++++-- packages/svelte/src/internal/client/reactivity/batch.js | 8 +++++--- .../svelte/src/internal/client/reactivity/deriveds.js | 4 ++-- .../svelte/src/internal/client/reactivity/effects.js | 9 ++++++--- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/packages/svelte/src/internal/client/dom/blocks/async.js b/packages/svelte/src/internal/client/dom/blocks/async.js index 18b0088d2f..25c37cafb0 100644 --- a/packages/svelte/src/internal/client/dom/blocks/async.js +++ b/packages/svelte/src/internal/client/dom/blocks/async.js @@ -15,14 +15,16 @@ export function async(node, expressions, fn) { var batch = /** @type {Batch} */ (current_batch); var effect = /** @type {Effect} */ (active_effect); + var boundary = get_pending_boundary(effect); + var ran = boundary.ran; var restore = capture(); boundary.increment(); Promise.all(expressions.map((fn) => async_derived(fn))).then((result) => { - batch?.restore(); + if (ran) batch.restore(); restore(); fn(node, ...result); @@ -30,7 +32,7 @@ export function async(node, expressions, fn) { // TODO is this necessary? schedule_effect(effect); - batch?.flush(); + if (ran) batch.flush(); boundary.decrement(); }); } diff --git a/packages/svelte/src/internal/client/reactivity/batch.js b/packages/svelte/src/internal/client/reactivity/batch.js index d3b8933ab8..08f84fc149 100644 --- a/packages/svelte/src/internal/client/reactivity/batch.js +++ b/packages/svelte/src/internal/client/reactivity/batch.js @@ -74,6 +74,8 @@ export class Batch { } for (const [source, current] of this.#current) { + current_values.set(source, source.v); + // TODO this shouldn't be necessary, but tests fail otherwise, // presumably because we need a try-finally somewhere, and the // source wasn't correctly reverted after the previous batch @@ -214,16 +216,16 @@ export class Batch { raf.tick(update_pending); } - current_batch = new Batch(); + const batch = (current_batch = new Batch()); batches.add(current_batch); queueMicrotask(() => { - if (current_batch === null) { + if (current_batch !== batch) { // a flushSync happened in the meantime return; } - current_batch.flush(); + batch.flush(); }); } diff --git a/packages/svelte/src/internal/client/reactivity/deriveds.js b/packages/svelte/src/internal/client/reactivity/deriveds.js index 03624b55a6..d48f9dd149 100644 --- a/packages/svelte/src/internal/client/reactivity/deriveds.js +++ b/packages/svelte/src/internal/client/reactivity/deriveds.js @@ -162,9 +162,9 @@ export function async_derived(fn, location) { } } - batch?.restore(); + if (ran) batch.restore(); internal_set(signal, v); - batch?.flush(); + if (ran) batch.flush(); if (DEV && location !== undefined) { recent_async_deriveds.add(signal); diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js index e2ffcd41dd..7ab989760a 100644 --- a/packages/svelte/src/internal/client/reactivity/effects.js +++ b/packages/svelte/src/internal/client/reactivity/effects.js @@ -40,7 +40,7 @@ import { DEV } from 'esm-env'; import { define_property } from '../../shared/utils.js'; import { get_next_sibling } from '../dom/operations.js'; import { async_derived, derived } from './deriveds.js'; -import { capture } from '../dom/blocks/boundary.js'; +import { capture, get_pending_boundary } from '../dom/blocks/boundary.js'; import { component_context, dev_current_component_function } from '../context.js'; import { current_batch, Batch } from './batch.js'; @@ -348,6 +348,9 @@ export function template_effect(fn, sync = [], async = [], d = derived) { var batch = /** @type {Batch} */ (current_batch); var restore = capture(); + var boundary = get_pending_boundary(parent); + var ran = boundary.ran; + Promise.all(async.map((expression) => async_derived(expression))).then((result) => { restore(); @@ -357,9 +360,9 @@ export function template_effect(fn, sync = [], async = [], d = derived) { var effect = create_template_effect(fn, [...sync.map(d), ...result]); - batch?.restore(); + if (ran) batch.restore(); schedule_effect(effect); - batch?.flush(); + if (ran) batch.flush(); }); } else { create_template_effect(fn, sync.map(d));