@@ -10,7 +10,7 @@ import {
10
10
define_property
11
11
} from '../shared/utils.js' ;
12
12
import { state as source , set } from './reactivity/sources.js' ;
13
- import { PROXY_PATH_SYMBOL , STATE_SYMBOL } from '#client/constants' ;
13
+ import { PROXY_PATH_SYMBOL , STATE_SYMBOL , DERIVED , BLOCK_EFFECT } from '#client/constants' ;
14
14
import { UNINITIALIZED } from '../../constants.js' ;
15
15
import * as e from './errors.js' ;
16
16
import { get_stack , tag } from './dev/tracing.js' ;
@@ -212,8 +212,22 @@ export function proxy(value) {
212
212
*/
213
213
cached_method = function ( ...args ) {
214
214
// preserve correct `this` binding and forward result.
215
+ const fn = /** @type {any } */ ( array_prototype ) [ prop ] ;
216
+
217
+ // if we are inside a template expression/derived or block effect,
218
+ // keep tracking so the runtime can still detect unsafe mutations.
219
+ if (
220
+ active_reaction !== null &&
221
+ ( active_reaction . f & ( DERIVED | BLOCK_EFFECT ) ) !== 0
222
+ ) {
223
+ // eslint-disable-next-line prefer-spread
224
+ return fn . apply ( this , args ) ;
225
+ }
226
+
227
+ // otherwise (ordinary user effect etc.) suppress dependency tracking
228
+ // so we avoid the self-invalidating loop.
215
229
// eslint-disable-next-line prefer-spread
216
- return untrack ( ( ) => /** @type { any } */ ( array_prototype ) [ prop ] . apply ( this , args ) ) ;
230
+ return untrack ( ( ) => fn . apply ( this , args ) ) ;
217
231
} ;
218
232
219
233
// give the wrapper a meaningful name for better debugging
0 commit comments