Skip to content

Commit 36a73fa

Browse files
authored
fix: avoid flushing sync with $inspect (#13239)
* fix: avoid flushing sync with $inspect * add test
1 parent 3d25672 commit 36a73fa

File tree

4 files changed

+66
-18
lines changed

4 files changed

+66
-18
lines changed

.changeset/hot-glasses-roll.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: avoid flushing sync with $inspect

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

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ import {
1616
update_effect,
1717
derived_sources,
1818
set_derived_sources,
19-
flush_sync,
20-
check_dirtiness
19+
check_dirtiness,
20+
set_is_flushing_effect,
21+
is_flushing_effect
2122
} from '../runtime.js';
2223
import { equals, safe_equals } from './equality.js';
2324
import {
@@ -170,23 +171,21 @@ export function set(source, value) {
170171

171172
if (DEV && inspect_effects.size > 0) {
172173
const inspects = Array.from(inspect_effects);
173-
if (current_effect === null) {
174-
// Triggering an effect sync can tear the signal graph, so to avoid this we need
175-
// to ensure the graph has been flushed before triggering any inspect effects.
176-
// Only needed when there's currently no effect, and flushing with one present
177-
// could have other unintended consequences, like effects running out of order.
178-
// This is expensive, but given this is a DEV mode only feature, it should be fine
179-
flush_sync();
180-
}
181-
for (const effect of inspects) {
182-
// Mark clean inspect-effects as maybe dirty and then check their dirtiness
183-
// instead of just updating the effects - this way we avoid overfiring.
184-
if ((effect.f & CLEAN) !== 0) {
185-
set_signal_status(effect, MAYBE_DIRTY);
186-
}
187-
if (check_dirtiness(effect)) {
188-
update_effect(effect);
174+
var previously_flushing_effect = is_flushing_effect;
175+
set_is_flushing_effect(true);
176+
try {
177+
for (const effect of inspects) {
178+
// Mark clean inspect-effects as maybe dirty and then check their dirtiness
179+
// instead of just updating the effects - this way we avoid overfiring.
180+
if ((effect.f & CLEAN) !== 0) {
181+
set_signal_status(effect, MAYBE_DIRTY);
182+
}
183+
if (check_dirtiness(effect)) {
184+
update_effect(effect);
185+
}
189186
}
187+
} finally {
188+
set_is_flushing_effect(previously_flushing_effect);
190189
}
191190
inspect_effects.clear();
192191
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { test } from '../../test';
2+
import { flushSync } from 'svelte';
3+
4+
export default test({
5+
async test({ assert, target, logs }) {
6+
const [b1] = target.querySelectorAll('button');
7+
flushSync(() => {
8+
b1.click();
9+
});
10+
flushSync(() => {
11+
b1.click();
12+
});
13+
assert.deepEqual(logs, [
14+
'effect',
15+
0,
16+
'in-increment',
17+
1,
18+
'effect',
19+
1,
20+
'in-increment',
21+
2,
22+
'effect',
23+
2
24+
]);
25+
}
26+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<script>
2+
let count = $state(0);
3+
4+
function increment() {
5+
count += 1;
6+
console.log("in-increment", count);
7+
}
8+
9+
$effect(() => {
10+
console.log("effect", count);
11+
});
12+
13+
$inspect(count);
14+
</script>
15+
16+
<button onclick={increment}>
17+
clicks: {count}
18+
</button>

0 commit comments

Comments
 (0)