diff --git a/packages/svelte/src/internal/client/constants.js b/packages/svelte/src/internal/client/constants.js index 50a7a21ae8..67b73f54a7 100644 --- a/packages/svelte/src/internal/client/constants.js +++ b/packages/svelte/src/internal/client/constants.js @@ -1,3 +1,4 @@ +// General flags export const DERIVED = 1 << 1; export const EFFECT = 1 << 2; export const RENDER_EFFECT = 1 << 3; @@ -5,13 +6,13 @@ export const BLOCK_EFFECT = 1 << 4; export const BRANCH_EFFECT = 1 << 5; export const ROOT_EFFECT = 1 << 6; export const BOUNDARY_EFFECT = 1 << 7; -export const UNOWNED = 1 << 8; -export const DISCONNECTED = 1 << 9; export const CLEAN = 1 << 10; export const DIRTY = 1 << 11; export const MAYBE_DIRTY = 1 << 12; export const INERT = 1 << 13; export const DESTROYED = 1 << 14; + +// Flags exclusive to effects export const EFFECT_RAN = 1 << 15; /** 'Transparent' effects do not create a transition boundary */ export const EFFECT_TRANSPARENT = 1 << 16; @@ -20,6 +21,11 @@ export const HEAD_EFFECT = 1 << 18; export const EFFECT_PRESERVED = 1 << 19; export const USER_EFFECT = 1 << 20; +// Flags exclusive to deriveds +export const UNOWNED = 1 << 8; +export const DISCONNECTED = 1 << 9; +export const WAS_MARKED = 1 << 15; + // Flags used for async export const REACTION_IS_UPDATING = 1 << 21; export const ASYNC = 1 << 22; diff --git a/packages/svelte/src/internal/client/reactivity/deriveds.js b/packages/svelte/src/internal/client/reactivity/deriveds.js index 06ae0f6d7a..5a3dee4b7f 100644 --- a/packages/svelte/src/internal/client/reactivity/deriveds.js +++ b/packages/svelte/src/internal/client/reactivity/deriveds.js @@ -10,7 +10,8 @@ import { MAYBE_DIRTY, STALE_REACTION, UNOWNED, - ASYNC + ASYNC, + WAS_MARKED } from '#client/constants'; import { active_reaction, @@ -326,6 +327,7 @@ export function execute_derived(derived) { stack.push(derived); + derived.f &= ~WAS_MARKED; destroy_derived_effects(derived); value = update_reaction(derived); } finally { @@ -335,6 +337,7 @@ export function execute_derived(derived) { } } else { try { + derived.f &= ~WAS_MARKED; destroy_derived_effects(derived); value = update_reaction(derived); } finally { diff --git a/packages/svelte/src/internal/client/reactivity/sources.js b/packages/svelte/src/internal/client/reactivity/sources.js index c5dcff9cfb..05d15b7cc8 100644 --- a/packages/svelte/src/internal/client/reactivity/sources.js +++ b/packages/svelte/src/internal/client/reactivity/sources.js @@ -27,7 +27,8 @@ import { MAYBE_DIRTY, BLOCK_EFFECT, ROOT_EFFECT, - ASYNC + ASYNC, + WAS_MARKED } from '#client/constants'; import * as e from '../errors.js'; import { legacy_mode_flag, tracing_mode_flag } from '../../flags/index.js'; @@ -331,7 +332,8 @@ function mark_reactions(signal, status) { set_signal_status(reaction, status); } - if ((flags & DERIVED) !== 0) { + if ((flags & DERIVED) !== 0 && (flags & WAS_MARKED) === 0) { + reaction.f |= WAS_MARKED; mark_reactions(/** @type {Derived} */ (reaction), MAYBE_DIRTY); } else if (not_dirty) { if ((flags & BLOCK_EFFECT) !== 0) { diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index a146659bf6..2e6f05b4b1 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -20,7 +20,8 @@ import { DISCONNECTED, REACTION_IS_UPDATING, STALE_REACTION, - ERROR_VALUE + ERROR_VALUE, + WAS_MARKED } from './constants.js'; import { old_values } from './reactivity/sources.js'; import { @@ -161,6 +162,10 @@ export function is_dirty(reaction) { var dependencies = reaction.deps; var is_unowned = (flags & UNOWNED) !== 0; + if (flags & DERIVED) { + reaction.f &= ~WAS_MARKED; + } + if (dependencies !== null) { var i; var dependency;