Skip to content

Commit e954b99

Browse files
committed
fix
1 parent 54a17b5 commit e954b99

File tree

2 files changed

+32
-17
lines changed

2 files changed

+32
-17
lines changed

packages/svelte/src/internal/client/proxy.js

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
object_prototype
1010
} from '../shared/utils.js';
1111
import { check_ownership, widen_ownership } from './dev/ownership.js';
12-
import { source, set, state, set_call_onchange } from './reactivity/sources.js';
12+
import { source, set, state, batch_onchange } from './reactivity/sources.js';
1313
import { STATE_SYMBOL, STATE_SYMBOL_METADATA } from './constants.js';
1414
import { UNINITIALIZED } from '../../constants.js';
1515
import * as e from './errors.js';
@@ -173,16 +173,7 @@ export function proxy(value, options, parent = null, prev) {
173173
const value = Reflect.get(target, prop, receiver);
174174

175175
if (is_proxied_array && array_methods.includes(/** @type {string} */ (prop))) {
176-
// @ts-expect-error
177-
return (...args) => {
178-
set_call_onchange(false);
179-
const result = value.apply(receiver, args);
180-
set_call_onchange(true);
181-
182-
options?.onchange?.();
183-
184-
return result;
185-
};
176+
return batch_onchange(value);
186177
}
187178

188179
return value;

packages/svelte/src/internal/client/reactivity/sources.js

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,30 @@ export function set_inspect_effects(v) {
4545
inspect_effects = v;
4646
}
4747

48-
let call_onchange = true;
48+
/** @type {null | Set<() => void>} */
49+
let onchange_batch = null;
4950

50-
/** @param {boolean} v */
51-
export function set_call_onchange(v) {
52-
call_onchange = v;
51+
/**
52+
* @param {Function} fn
53+
*/
54+
export function batch_onchange(fn) {
55+
// @ts-expect-error
56+
return function (...args) {
57+
let previous_onchange_batch = onchange_batch;
58+
59+
try {
60+
onchange_batch = new Set();
61+
62+
// @ts-expect-error
63+
return fn.apply(this, args);
64+
} finally {
65+
for (const onchange of /** @type {Set<() => void>} */ (onchange_batch)) {
66+
onchange();
67+
}
68+
69+
onchange_batch = previous_onchange_batch;
70+
}
71+
};
5372
}
5473

5574
/**
@@ -199,8 +218,13 @@ export function internal_set(source, value) {
199218
source.v = value;
200219
source.wv = increment_write_version();
201220

202-
if (call_onchange) {
203-
untrack(() => source.o?.onchange?.());
221+
var onchange = source.o?.onchange;
222+
if (onchange) {
223+
if (onchange_batch) {
224+
onchange_batch.add(onchange);
225+
} else {
226+
onchange();
227+
}
204228
}
205229

206230
if (DEV && tracing_mode_flag) {

0 commit comments

Comments
 (0)