Skip to content

Commit

Permalink
fix: avoid flushing sync with $inspect (#13239)
Browse files Browse the repository at this point in the history
* fix: avoid flushing sync with $inspect

* add test
  • Loading branch information
trueadm authored Sep 16, 2024
1 parent 3d25672 commit 36a73fa
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 18 deletions.
5 changes: 5 additions & 0 deletions .changeset/hot-glasses-roll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: avoid flushing sync with $inspect
35 changes: 17 additions & 18 deletions packages/svelte/src/internal/client/reactivity/sources.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ import {
update_effect,
derived_sources,
set_derived_sources,
flush_sync,
check_dirtiness
check_dirtiness,
set_is_flushing_effect,
is_flushing_effect
} from '../runtime.js';
import { equals, safe_equals } from './equality.js';
import {
Expand Down Expand Up @@ -170,23 +171,21 @@ export function set(source, value) {

if (DEV && inspect_effects.size > 0) {
const inspects = Array.from(inspect_effects);
if (current_effect === null) {
// Triggering an effect sync can tear the signal graph, so to avoid this we need
// to ensure the graph has been flushed before triggering any inspect effects.
// Only needed when there's currently no effect, and flushing with one present
// could have other unintended consequences, like effects running out of order.
// This is expensive, but given this is a DEV mode only feature, it should be fine
flush_sync();
}
for (const effect of inspects) {
// Mark clean inspect-effects as maybe dirty and then check their dirtiness
// instead of just updating the effects - this way we avoid overfiring.
if ((effect.f & CLEAN) !== 0) {
set_signal_status(effect, MAYBE_DIRTY);
}
if (check_dirtiness(effect)) {
update_effect(effect);
var previously_flushing_effect = is_flushing_effect;
set_is_flushing_effect(true);
try {
for (const effect of inspects) {
// Mark clean inspect-effects as maybe dirty and then check their dirtiness
// instead of just updating the effects - this way we avoid overfiring.
if ((effect.f & CLEAN) !== 0) {
set_signal_status(effect, MAYBE_DIRTY);
}
if (check_dirtiness(effect)) {
update_effect(effect);
}
}
} finally {
set_is_flushing_effect(previously_flushing_effect);
}
inspect_effects.clear();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { test } from '../../test';
import { flushSync } from 'svelte';

export default test({
async test({ assert, target, logs }) {
const [b1] = target.querySelectorAll('button');
flushSync(() => {
b1.click();
});
flushSync(() => {
b1.click();
});
assert.deepEqual(logs, [
'effect',
0,
'in-increment',
1,
'effect',
1,
'in-increment',
2,
'effect',
2
]);
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script>
let count = $state(0);
function increment() {
count += 1;
console.log("in-increment", count);
}
$effect(() => {
console.log("effect", count);
});
$inspect(count);
</script>

<button onclick={increment}>
clicks: {count}
</button>

0 comments on commit 36a73fa

Please sign in to comment.