From 92d2b1f1e3e3c8dd024a0592222121e3191ff330 Mon Sep 17 00:00:00 2001 From: Matei-Paul Trandafir Date: Fri, 13 Jun 2025 18:19:22 +0300 Subject: [PATCH] Fix the bug --- .../svelte/src/internal/client/constants.js | 1 + .../src/internal/client/reactivity/effects.js | 10 ++++++---- packages/svelte/src/internal/client/runtime.js | 17 +++++++++++++++-- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/packages/svelte/src/internal/client/constants.js b/packages/svelte/src/internal/client/constants.js index 98cef658bf..e9be00c17d 100644 --- a/packages/svelte/src/internal/client/constants.js +++ b/packages/svelte/src/internal/client/constants.js @@ -21,6 +21,7 @@ export const INSPECT_EFFECT = 1 << 18; export const HEAD_EFFECT = 1 << 19; export const EFFECT_HAS_DERIVED = 1 << 20; export const EFFECT_IS_UPDATING = 1 << 21; +export const TEMPLATE_EFFECT = 1 << 22; export const STATE_SYMBOL = Symbol('$state'); export const LEGACY_PROPS = Symbol('legacy props'); diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js index 54994b9bd1..d0ad8466c4 100644 --- a/packages/svelte/src/internal/client/reactivity/effects.js +++ b/packages/svelte/src/internal/client/reactivity/effects.js @@ -32,7 +32,8 @@ import { HEAD_EFFECT, MAYBE_DIRTY, EFFECT_HAS_DERIVED, - BOUNDARY_EFFECT + BOUNDARY_EFFECT, + TEMPLATE_EFFECT } from '#client/constants'; import { set } from './sources.js'; import * as e from '../errors.js'; @@ -329,6 +330,7 @@ export function render_effect(fn) { /** * @param {(...expressions: any) => void | (() => void)} fn * @param {Array<() => any>} thunks + * @param {(fn: () => T) => Derived} d * @returns {Effect} */ export function template_effect(fn, thunks = [], d = derived) { @@ -343,12 +345,12 @@ export function template_effect(fn, thunks = [], d = derived) { define_property(inner, 'name', { value: '{expression}' }); const deriveds = thunks.map(d); - block(inner); + block(inner, TEMPLATE_EFFECT); }); } const deriveds = thunks.map(d); - return block(() => fn(...deriveds.map(get))); + return block(() => fn(...deriveds.map(get)), TEMPLATE_EFFECT); } /** @@ -606,7 +608,7 @@ function resume_children(effect, local) { // If a dependency of this effect changed while it was paused, // schedule the effect to update - if (check_dirtiness(effect)) { + if (check_dirtiness(effect, true)) { set_signal_status(effect, DIRTY); schedule_effect(effect); } diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 9544060959..0efdcb8f44 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -22,7 +22,8 @@ import { ROOT_EFFECT, LEGACY_DERIVED_PROP, DISCONNECTED, - EFFECT_IS_UPDATING + EFFECT_IS_UPDATING, + TEMPLATE_EFFECT } from './constants.js'; import { flush_tasks } from './dom/task.js'; import { internal_set, old_values } from './reactivity/sources.js'; @@ -151,9 +152,10 @@ export function increment_write_version() { * Determines whether a derived or effect is dirty. * If it is MAYBE_DIRTY, will set the status to CLEAN * @param {Reaction} reaction + * @param {boolean} [resuming] * @returns {boolean} */ -export function check_dirtiness(reaction) { +export function check_dirtiness(reaction, resuming = false) { var flags = reaction.f; if ((flags & DIRTY) !== 0) { @@ -203,6 +205,17 @@ export function check_dirtiness(reaction) { dependency = dependencies[i]; if (check_dirtiness(/** @type {Derived} */ (dependency))) { + /* Don't execute deriveds of template effects when unpausing, for example when outer resumes + + {#if outer} + {#if inner} + {inner.func()} + {/if} + {/if} + + inner might be undefined, so don't eagerly execute `inner.func()` + */ + if (resuming && (reaction.f & TEMPLATE_EFFECT) !== 0) return true; update_derived(/** @type {Derived} */ (dependency)); }