mirror of https://github.com/sveltejs/svelte
fix: ensure signal graph is consistent before triggering $inspect signals (#13153)
Fixes #13146. Sync effects are not possible with Svelte 5's push-pull system because they can make can break the reactive graph – which is also why we don't permit writes within a derived too. The same problem is occurring here, as inspect effects are run sync – they are actually happening as part of an existing derived – which means they're a bit like writes in a derived and can cause tearing to the reactive signal graph. To avoid this we can call flushSync just before invoking these effects, as that should ensure the graph is made consistent again. Also another issue I found was that we don't "reset" the inspect_effects Set when we enter a derived – which we should as a derived can create it's own local state that should have no bearing on the parent inspect effect.pull/13198/head
parent
941f83b5a8
commit
56f41e1d96
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: ensure signal graph is consistent before triggering $inspect signals
|
@ -0,0 +1,16 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
compileOptions: {
|
||||||
|
dev: true
|
||||||
|
},
|
||||||
|
|
||||||
|
async test({ assert, logs, target }) {
|
||||||
|
const [btn] = target.querySelectorAll('button');
|
||||||
|
btn.click();
|
||||||
|
btn.click();
|
||||||
|
await Promise.resolve();
|
||||||
|
|
||||||
|
assert.deepEqual(logs, ['init', [], 'update', [{}], 'update', [{}, {}]]);
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,35 @@
|
|||||||
|
<script>
|
||||||
|
class Rect{
|
||||||
|
x = $state();
|
||||||
|
y = $state();
|
||||||
|
|
||||||
|
constructor(x, y){
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Node{
|
||||||
|
pos = $state({ x: 0, y: 0 });
|
||||||
|
rect = $derived(new Rect(this.pos.x, this.pos.y));
|
||||||
|
|
||||||
|
constructor(pos){
|
||||||
|
this.pos = pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const nodes = $state([]);
|
||||||
|
|
||||||
|
const rects = $derived(nodes.map(n => n.rect));
|
||||||
|
|
||||||
|
$inspect(rects);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={()=>{
|
||||||
|
nodes.push(new Node({x: Math.floor(Math.random()*100), y: Math.floor(Math.random()*100)}));
|
||||||
|
}}>add</button>
|
||||||
|
<ul>
|
||||||
|
{#each rects as rect}
|
||||||
|
<li>{rect.x} - {rect.y}</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
Loading…
Reference in new issue