Skip to content

Commit 436a6c3

Browse files
authored
fix: improve $inspect batching (#9902)
* fix: improve $inspect batching * fix dev bug * simplify * simplify
1 parent a9a5b11 commit 436a6c3

File tree

3 files changed

+51
-7
lines changed

3 files changed

+51
-7
lines changed

.changeset/heavy-ears-rule.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: improve $inspect batching

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import {
77
source,
88
updating_derived,
99
UNINITIALIZED,
10-
mutable_source
10+
mutable_source,
11+
batch_inspect
1112
} from '../runtime.js';
1213
import {
1314
define_property,
@@ -166,8 +167,17 @@ const handler = {
166167
metadata.s.set(prop, s);
167168
}
168169

169-
const value = s !== undefined ? get(s) : Reflect.get(target, prop, receiver);
170-
return value === UNINITIALIZED ? undefined : value;
170+
if (s !== undefined) {
171+
const value = get(s);
172+
return value === UNINITIALIZED ? undefined : value;
173+
}
174+
175+
if (DEV) {
176+
if (typeof target[prop] === 'function' && prop !== Symbol.iterator) {
177+
return batch_inspect(target, prop, receiver);
178+
}
179+
}
180+
return Reflect.get(target, prop, receiver);
171181
},
172182

173183
getOwnPropertyDescriptor(target, prop) {

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

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ let current_scheduler_mode = FLUSH_MICROTASK;
3737
// Used for handling scheduling
3838
let is_micro_task_queued = false;
3939
let is_task_queued = false;
40+
// Used for $inspect
41+
export let is_batching_effect = false;
4042

4143
// Handle effect queues
4244

@@ -62,8 +64,8 @@ let current_dependencies = null;
6264
let current_dependencies_index = 0;
6365
/** @type {null | import('./types.js').Signal[]} */
6466
let current_untracked_writes = null;
65-
// Handling capturing of signals from object property getters
66-
let current_should_capture_signal = false;
67+
/** @type {null | import('./types.js').Signal} */
68+
let last_inspected_signal = null;
6769
/** If `true`, `get`ting the signal should not register it as a dependency */
6870
export let current_untracking = false;
6971
/** Exists to opt out of the mutation validation for stores which may be set for the first time during a derivation */
@@ -110,6 +112,29 @@ function is_runes(context) {
110112
return component_context !== null && component_context.r;
111113
}
112114

115+
/**
116+
* @param {import("./proxy/proxy.js").StateObject} target
117+
* @param {string | symbol} prop
118+
* @param {any} receiver
119+
*/
120+
export function batch_inspect(target, prop, receiver) {
121+
const value = Reflect.get(target, prop, receiver);
122+
return function () {
123+
const previously_batching_effect = is_batching_effect;
124+
is_batching_effect = true;
125+
try {
126+
return Reflect.apply(value, receiver, arguments);
127+
} finally {
128+
is_batching_effect = previously_batching_effect;
129+
if (last_inspected_signal !== null) {
130+
// @ts-expect-error
131+
for (const fn of last_inspected_signal.inspect) fn();
132+
last_inspected_signal = null;
133+
}
134+
}
135+
};
136+
}
137+
113138
/**
114139
* @param {null | import('./types.js').ComponentContext} context_stack_item
115140
* @returns {void}
@@ -1053,8 +1078,12 @@ export function set_signal_value(signal, value) {
10531078

10541079
// @ts-expect-error
10551080
if (DEV && signal.inspect) {
1056-
// @ts-expect-error
1057-
for (const fn of signal.inspect) fn();
1081+
if (is_batching_effect) {
1082+
last_inspected_signal = signal;
1083+
} else {
1084+
// @ts-expect-error
1085+
for (const fn of signal.inspect) fn();
1086+
}
10581087
}
10591088
}
10601089
}

0 commit comments

Comments
 (0)