From 8939bbfbc288bdc31dfb884a946855979b56700b Mon Sep 17 00:00:00 2001 From: Elliott Johnson Date: Mon, 3 Nov 2025 18:19:54 -0700 Subject: [PATCH] fix never-expiring cache entries --- .../src/internal/client/reactivity/cache.js | 8 +++----- .../src/internal/client/reactivity/effects.js | 17 ++++++++++++++--- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/packages/svelte/src/internal/client/reactivity/cache.js b/packages/svelte/src/internal/client/reactivity/cache.js index 132b904af8..471d780a70 100644 --- a/packages/svelte/src/internal/client/reactivity/cache.js +++ b/packages/svelte/src/internal/client/reactivity/cache.js @@ -1,7 +1,7 @@ import { BaseCacheObserver } from '../../shared/cache-observer.js'; import { ObservableCache } from '../../shared/observable-cache.js'; import { tick } from '../runtime.js'; -import { render_effect } from './effects.js'; +import { get_effect_validation_error_code, render_effect } from './effects.js'; /** @typedef {{ count: number, item: any }} Entry */ /** @type {ObservableCache} */ @@ -18,8 +18,8 @@ export function cache(key, fn) { const entry = client_cache.get(key); const maybe_remove = create_remover(key); - let tracking = true; - try { + const tracking = get_effect_validation_error_code() === null; + if (tracking) { render_effect(() => { if (entry) entry.count++; return () => { @@ -29,8 +29,6 @@ export function cache(key, fn) { maybe_remove(entry); }; }); - } catch { - tracking = false; } if (cached) { diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js index 2c9e4db911..922d53a00e 100644 --- a/packages/svelte/src/internal/client/reactivity/effects.js +++ b/packages/svelte/src/internal/client/reactivity/effects.js @@ -48,17 +48,28 @@ import { without_reactive_context } from '../dom/elements/bindings/shared.js'; * @param {'$effect' | '$effect.pre' | '$inspect'} rune */ export function validate_effect(rune) { + const code = get_effect_validation_error_code(); + if (code === null) return; + e[code](rune); +} + +/** + * @returns {'effect_orphan' | 'effect_in_unowned_derived' | 'effect_in_teardown' | null} + */ +export function get_effect_validation_error_code() { if (active_effect === null && active_reaction === null) { - e.effect_orphan(rune); + return 'effect_orphan'; } if (active_reaction !== null && (active_reaction.f & UNOWNED) !== 0 && active_effect === null) { - e.effect_in_unowned_derived(); + return 'effect_in_unowned_derived'; } if (is_destroying_effect) { - e.effect_in_teardown(rune); + return 'effect_in_teardown'; } + + return null; } /**