From cf822c21337c93ffe6f189a31b0ed68012c4bcfb Mon Sep 17 00:00:00 2001 From: raythurnvoid <53383860+raythurnvoid@users.noreply.github.com> Date: Sat, 14 Jun 2025 18:59:07 +0100 Subject: [PATCH] Tweak to restore unsafe template mutation tracking --- packages/svelte/src/internal/client/proxy.js | 19 +++++++++++++++---- .../samples/array-push-in-effect/_config.js | 2 +- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/packages/svelte/src/internal/client/proxy.js b/packages/svelte/src/internal/client/proxy.js index ab32c32e83..086a97d90c 100644 --- a/packages/svelte/src/internal/client/proxy.js +++ b/packages/svelte/src/internal/client/proxy.js @@ -10,7 +10,7 @@ import { define_property } from '../shared/utils.js'; import { state as source, set } from './reactivity/sources.js'; -import { PROXY_PATH_SYMBOL, STATE_SYMBOL } from '#client/constants'; +import { PROXY_PATH_SYMBOL, STATE_SYMBOL, DERIVED, BLOCK_EFFECT } from '#client/constants'; import { UNINITIALIZED } from '../../constants.js'; import * as e from './errors.js'; import { get_stack, tag } from './dev/tracing.js'; @@ -199,7 +199,9 @@ export function proxy(value) { // internals) that the algorithm reads. if (is_proxied_array && typeof prop === 'string' && MUTATING_ARRAY_METHODS.has(prop)) { /** @type {Map} */ - const mutating_methods_cache = /** @type {Map} */ (proxied_array_mutating_methods_cache); + const mutating_methods_cache = /** @type {Map} */ ( + proxied_array_mutating_methods_cache + ); var cached_method = mutating_methods_cache.get(prop); @@ -212,8 +214,17 @@ export function proxy(value) { */ cached_method = function (...args) { // preserve correct `this` binding and forward result. - // eslint-disable-next-line prefer-spread - return untrack(() => /** @type {any} */ (array_prototype)[prop].apply(this, args)); + const fn = /** @type {any} */ (array_prototype)[prop]; + + // if we are inside a template expression/derived or block effect, + // keep tracking so the runtime can still detect unsafe mutations. + if (active_reaction !== null && (active_reaction.f & (DERIVED | BLOCK_EFFECT)) !== 0) { + return fn.apply(this, args); + } + + // otherwise (ordinary user effect etc.) suppress dependency tracking + // so we avoid the self-invalidating loop. + return untrack(() => fn.apply(this, args)); }; // give the wrapper a meaningful name for better debugging diff --git a/packages/svelte/tests/runtime-runes/samples/array-push-in-effect/_config.js b/packages/svelte/tests/runtime-runes/samples/array-push-in-effect/_config.js index a8ad512ed9..04798a715e 100644 --- a/packages/svelte/tests/runtime-runes/samples/array-push-in-effect/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/array-push-in-effect/_config.js @@ -30,4 +30,4 @@ export default test({ ` ); } -}); \ No newline at end of file +});