Skip to content

Commit 93f8329

Browse files
authored
fix: ensure $inspect effects are fine-grain (#13199)
Don't fire effects that don't need to rerun. Fixes #13189
1 parent a7a4778 commit 93f8329

File tree

7 files changed

+98
-3
lines changed

7 files changed

+98
-3
lines changed

.changeset/polite-pugs-attend.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: ensure $inspect effects are fine-grain

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ import {
1616
update_effect,
1717
derived_sources,
1818
set_derived_sources,
19-
flush_sync
19+
flush_sync,
20+
check_dirtiness
2021
} from '../runtime.js';
2122
import { equals, safe_equals } from './equality.js';
2223
import {
@@ -178,7 +179,14 @@ export function set(source, value) {
178179
flush_sync();
179180
}
180181
for (const effect of inspects) {
181-
update_effect(effect);
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);
189+
}
182190
}
183191
inspect_effects.clear();
184192
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ export function set_dev_current_component_function(fn) {
153153
}
154154

155155
export function increment_version() {
156-
return current_version++;
156+
return ++current_version;
157157
}
158158

159159
/** @returns {boolean} */
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script>
2+
import {getContext} from 'svelte';
3+
4+
let { children, value} = $props();
5+
6+
let listContext = getContext('list');
7+
8+
let selected = $derived(listContext?.selectedValue === value);
9+
10+
$inspect(value, selected);
11+
</script>
12+
13+
<div class:selected>{@render children()}</div>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<script>
2+
import {setContext} from 'svelte';
3+
4+
let {children, selectedValue} = $props();
5+
6+
let listContext = $state({ selectedValue});
7+
8+
$effect(() => {
9+
listContext.selectedValue = selectedValue;
10+
});
11+
12+
setContext('list',listContext);
13+
</script>
14+
15+
<div class="list">
16+
{@render children()}
17+
</div>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
compileOptions: {
6+
dev: true
7+
},
8+
9+
async test({ assert, target, logs }) {
10+
const button = target.querySelector('button');
11+
12+
flushSync(() => {
13+
button?.click();
14+
});
15+
16+
assert.deepEqual(logs, [
17+
'init',
18+
'0',
19+
true,
20+
'init',
21+
'1',
22+
false,
23+
'init',
24+
'2',
25+
false,
26+
'update',
27+
'0',
28+
false,
29+
'update',
30+
'1',
31+
true
32+
]);
33+
}
34+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<script>
2+
import List from './List.svelte';
3+
import Item from './Item.svelte';
4+
5+
let selectedIndex = $state(0);
6+
let selectedValue = $derived(`${selectedIndex}`);
7+
8+
const changeSelection = () => {
9+
selectedIndex = (selectedIndex + 1)%3;
10+
};
11+
</script>
12+
13+
<List {selectedValue}>
14+
<Item value="0">First</Item>
15+
<Item value="1">Second</Item>
16+
<Item value="2">Third</Item>
17+
</List>
18+
<button onclick={changeSelection}>Change Selection</button>

0 commit comments

Comments
 (0)