mirror of https://github.com/sveltejs/svelte
chore: test for batches flush fix (#16915)
Test for #16912 Also some explanation what the bug was: 1. async batch kicks off 2. outer async work succeeds, still something pending, so doesn't do anything for now 3. something unrelated writes to a signal (in the remote functions case it's the query writing to loading, raw etc), which creates a new batch 4. new batch executes. since there are multiple batches it takes the previous value which means if block is still alive. commits that, since no async work from the perspective of this branch 5. inner async work succeeds. now the batch has zero pending async work so it can flush. But the if block is no longer dirty since it was done by the other batch already -> never undos the other work #16912 fixes it by still traversing the tree which means the if block deletion is scheduled to commit later, which it then doespull/16243/merge
parent
844fab7798
commit
9c350cfdab
@ -0,0 +1,57 @@
|
||||
import { tick } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
async test({ assert, target }) {
|
||||
const shift = document.querySelector('button');
|
||||
shift?.click();
|
||||
await tick();
|
||||
shift?.click();
|
||||
await tick();
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<p>true</p>
|
||||
<button>toggle</button>
|
||||
<button>shift</button>
|
||||
`
|
||||
);
|
||||
|
||||
const toggle = target.querySelector('button');
|
||||
toggle?.click();
|
||||
await tick();
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<p>true</p>
|
||||
<button>toggle</button>
|
||||
<button>shift</button>
|
||||
`
|
||||
);
|
||||
|
||||
shift?.click();
|
||||
await tick();
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<p>true</p>
|
||||
<button>toggle</button>
|
||||
<button>shift</button>
|
||||
`
|
||||
);
|
||||
|
||||
shift?.click();
|
||||
await tick();
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<button>toggle</button>
|
||||
<button>shift</button>
|
||||
`
|
||||
);
|
||||
}
|
||||
});
|
@ -0,0 +1,41 @@
|
||||
<script>
|
||||
let show = $state(true);
|
||||
let count = $state(0);
|
||||
let queue = [];
|
||||
|
||||
function foo() {
|
||||
const {promise, resolve} = Promise.withResolvers();
|
||||
const s = show;
|
||||
queue.push(() => resolve(s));
|
||||
return promise;
|
||||
}
|
||||
|
||||
function bar() {
|
||||
const {promise, resolve} = Promise.withResolvers();
|
||||
const s = show;
|
||||
queue.push(() => {
|
||||
// This will create a new batch while the other batch is still in flight
|
||||
count++
|
||||
resolve(s);
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
$effect(() => { count; });
|
||||
</script>
|
||||
|
||||
<svelte:boundary>
|
||||
{#if await foo()}
|
||||
<p>{await bar()}</p>
|
||||
{/if}
|
||||
|
||||
<button onclick={() => {
|
||||
show = !show
|
||||
}}>toggle</button>
|
||||
|
||||
{#snippet pending()}
|
||||
<p>loading...</p>
|
||||
{/snippet}
|
||||
</svelte:boundary>
|
||||
|
||||
<button onclick={() => queue.shift()()}>shift</button>
|
Loading…
Reference in new issue