fix: ensure $inspect effects are fine-grain (#13199)

Don't fire effects that don't need to rerun. Fixes #13189
pull/13217/head
Dominic Gannaway 12 months ago committed by GitHub
parent a7a477804e
commit 93f8329b1b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: ensure $inspect effects are fine-grain

@ -16,7 +16,8 @@ import {
update_effect,
derived_sources,
set_derived_sources,
flush_sync
flush_sync,
check_dirtiness
} from '../runtime.js';
import { equals, safe_equals } from './equality.js';
import {
@ -178,7 +179,14 @@ export function set(source, value) {
flush_sync();
}
for (const effect of inspects) {
update_effect(effect);
// 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);
}
}
inspect_effects.clear();
}

@ -153,7 +153,7 @@ export function set_dev_current_component_function(fn) {
}
export function increment_version() {
return current_version++;
return ++current_version;
}
/** @returns {boolean} */

@ -0,0 +1,13 @@
<script>
import {getContext} from 'svelte';
let { children, value} = $props();
let listContext = getContext('list');
let selected = $derived(listContext?.selectedValue === value);
$inspect(value, selected);
</script>
<div class:selected>{@render children()}</div>

@ -0,0 +1,17 @@
<script>
import {setContext} from 'svelte';
let {children, selectedValue} = $props();
let listContext = $state({ selectedValue});
$effect(() => {
listContext.selectedValue = selectedValue;
});
setContext('list',listContext);
</script>
<div class="list">
{@render children()}
</div>

@ -0,0 +1,34 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
compileOptions: {
dev: true
},
async test({ assert, target, logs }) {
const button = target.querySelector('button');
flushSync(() => {
button?.click();
});
assert.deepEqual(logs, [
'init',
'0',
true,
'init',
'1',
false,
'init',
'2',
false,
'update',
'0',
false,
'update',
'1',
true
]);
}
});

@ -0,0 +1,18 @@
<script>
import List from './List.svelte';
import Item from './Item.svelte';
let selectedIndex = $state(0);
let selectedValue = $derived(`${selectedIndex}`);
const changeSelection = () => {
selectedIndex = (selectedIndex + 1)%3;
};
</script>
<List {selectedValue}>
<Item value="0">First</Item>
<Item value="1">Second</Item>
<Item value="2">Third</Item>
</List>
<button onclick={changeSelection}>Change Selection</button>
Loading…
Cancel
Save