From 4866aa233359e8d307122e14cb56196beaa94b22 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Tue, 2 Jun 2026 13:26:53 +0200 Subject: [PATCH] don't bail self-invalidation in async mode + don't mark reactions on initial run not marking without not bailing makes two tests fail, revealing that the "don't self-invalidate in async mode" change would actually be a subtle breaking change --- .../svelte/src/internal/client/reactivity/batch.js | 10 ++++++---- .../svelte/src/internal/client/reactivity/deriveds.js | 8 +++----- packages/svelte/src/internal/client/runtime.js | 1 - 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/svelte/src/internal/client/reactivity/batch.js b/packages/svelte/src/internal/client/reactivity/batch.js index bdc2bdae42..566adc5b03 100644 --- a/packages/svelte/src/internal/client/reactivity/batch.js +++ b/packages/svelte/src/internal/client/reactivity/batch.js @@ -287,18 +287,20 @@ export class Batch { if (this.#committed) return; current_batch = this; - this.#started = true; if (flush_count++ > 1000) { this.#unlink(); infinite_loop_guard(); } - // TODO we only need to do this for re-runs - for (const [source, snapshot] of this.current) { - mark_reactions(this, source, snapshot.wv, null); + if (this.#started) { + for (const [source, snapshot] of this.current) { + mark_reactions(this, source, snapshot.wv, null); + } } + this.#started = true; + if (DEV) { // track all the values that were updated during this flush, // so that they can be reset afterwards diff --git a/packages/svelte/src/internal/client/reactivity/deriveds.js b/packages/svelte/src/internal/client/reactivity/deriveds.js index 6352c66b17..99a809dbaa 100644 --- a/packages/svelte/src/internal/client/reactivity/deriveds.js +++ b/packages/svelte/src/internal/client/reactivity/deriveds.js @@ -1,6 +1,5 @@ -/** @import { Derived, Effect, Reaction, Source, Value } from '#client' */ +/** @import { Derived, Effect, Source, Value } from '#client' */ /** @import { Batch } from './batch.js'; */ -/** @import { Boundary } from '../dom/blocks/boundary.js'; */ import { DEV } from 'esm-env'; import { ERROR_VALUE, @@ -26,14 +25,13 @@ import { write_version, skipped_deps, new_deps, - is_destroying_effect, - current_sources + is_destroying_effect } from '../runtime.js'; import { equals, safe_equals } from './equality.js'; import * as e from '../errors.js'; import * as w from '../warnings.js'; import { async_effect, destroy_effect, destroy_effect_children, teardown } from './effects.js'; -import { eager_effects, internal_set, set_eager_effects, source, state } from './sources.js'; +import { eager_effects, internal_set, set_eager_effects, state } from './sources.js'; import { get_error } from '../../shared/dev.js'; import { async_mode_flag, tracing_mode_flag } from '../../flags/index.js'; import { component_context } from '../context.js'; diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index b4dcc04b30..78f4179890 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -300,7 +300,6 @@ export function update_reaction(reaction) { // ensure that if any of those untracked writes result in re-invalidation // of the current effect, then that happens accordingly if ( - !async_mode_flag && is_runes() && untracked_writes !== null && !untracking &&