mirror of https://github.com/sveltejs/svelte
parent
8ab778b621
commit
28fb668d48
@ -0,0 +1,31 @@
|
|||||||
|
import { tick } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
const buttons =
|
||||||
|
'<button>a</button><button>b</button><button>resolve a1</button><button>resolve b1</button>';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target }) {
|
||||||
|
await tick();
|
||||||
|
const [a, b, resolve_a1, resolve_b1] = target.querySelectorAll('button');
|
||||||
|
|
||||||
|
assert.htmlEqual(target.innerHTML, `<p>0</p><p>0</p>${buttons}`);
|
||||||
|
|
||||||
|
// batch A waits on its key; batch B registers its key right away
|
||||||
|
a.click();
|
||||||
|
await tick();
|
||||||
|
b.click();
|
||||||
|
await tick();
|
||||||
|
assert.htmlEqual(target.innerHTML, `<p>0</p><p>0</p>${buttons}`);
|
||||||
|
|
||||||
|
// the older batch commits first
|
||||||
|
resolve_a1.click();
|
||||||
|
await tick();
|
||||||
|
assert.htmlEqual(target.innerHTML, `<p>0</p><p>1</p>${buttons}`);
|
||||||
|
|
||||||
|
// the newer batch commits with its own branch
|
||||||
|
resolve_b1.click();
|
||||||
|
await tick();
|
||||||
|
assert.htmlEqual(target.innerHTML, `<p>1</p><p>B</p>${buttons}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
<script>
|
||||||
|
let a = $state(0);
|
||||||
|
let b = $state(0);
|
||||||
|
let pend = false;
|
||||||
|
|
||||||
|
const pending = new Map();
|
||||||
|
|
||||||
|
function delay(key, value) {
|
||||||
|
if (!pend) return value;
|
||||||
|
return new Promise((resolve) => pending.set(key, () => resolve(value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolve(key) {
|
||||||
|
pending.get(key)();
|
||||||
|
pending.delete(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
const k = $derived(b === 0 ? await delay(`a${a}`, a) : 'B');
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<p>{await delay(`b${b}`, b)}</p>
|
||||||
|
|
||||||
|
{#key k}
|
||||||
|
<p>{k}</p>
|
||||||
|
{/key}
|
||||||
|
|
||||||
|
<button onclick={() => { pend = true; a = 1; }}>a</button>
|
||||||
|
<button onclick={() => { pend = true; b = 1; }}>b</button>
|
||||||
|
<button onclick={() => resolve('a1')}>resolve a1</button>
|
||||||
|
<button onclick={() => resolve('b1')}>resolve b1</button>
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
import { tick } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
const buttons =
|
||||||
|
'<button>X</button><button>Y</button><button>Z</button><button>W</button><button>resolve e</button><button>resolve x1</button>';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target, logs }) {
|
||||||
|
await tick();
|
||||||
|
const [X, Y, Z, W, resolve_e, resolve_x1] = target.querySelectorAll('button');
|
||||||
|
|
||||||
|
assert.htmlEqual(target.innerHTML, `<p>n = 0</p><p>x = 0</p>${buttons}`);
|
||||||
|
|
||||||
|
// X is deferred on its own await
|
||||||
|
X.click();
|
||||||
|
await tick();
|
||||||
|
// Y is deferred on the await inside the new branch
|
||||||
|
Y.click();
|
||||||
|
await tick();
|
||||||
|
// Z hides that branch again, merges into Y, which merges into X
|
||||||
|
Z.click();
|
||||||
|
await tick();
|
||||||
|
assert.htmlEqual(target.innerHTML, `<p>n = 0</p><p>x = 0</p>${buttons}`);
|
||||||
|
assert.deepEqual(logs, ['delay x0', 'delay x1', 'delay e']);
|
||||||
|
|
||||||
|
// the branch's await resolves while it is hidden
|
||||||
|
resolve_e.click();
|
||||||
|
await tick();
|
||||||
|
// W shows the branch again and merges into X
|
||||||
|
W.click();
|
||||||
|
await tick();
|
||||||
|
|
||||||
|
// nothing is pending any more, so X commits
|
||||||
|
resolve_x1.click();
|
||||||
|
await tick();
|
||||||
|
assert.htmlEqual(target.innerHTML, `<p>n = 4</p><p>x = 1</p><p>cond: e</p>${buttons}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
<script>
|
||||||
|
let n = $state(0);
|
||||||
|
let x = $state(0);
|
||||||
|
let cond = $state(false);
|
||||||
|
let pend = false;
|
||||||
|
|
||||||
|
const pending = new Map();
|
||||||
|
|
||||||
|
function delay(key, value) {
|
||||||
|
console.log(`delay ${key}`);
|
||||||
|
if (!pend) return value;
|
||||||
|
return new Promise((resolve) => pending.set(key, () => resolve(value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolve(key) {
|
||||||
|
pending.get(key)();
|
||||||
|
pending.delete(key);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:boundary>
|
||||||
|
<p>n = {n}</p>
|
||||||
|
<p>x = {await delay(`x${x}`, x)}</p>
|
||||||
|
{#if cond}
|
||||||
|
<p>cond: {await delay('e', 'e')}</p>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#snippet pending()}
|
||||||
|
<p>loading</p>
|
||||||
|
{/snippet}
|
||||||
|
</svelte:boundary>
|
||||||
|
|
||||||
|
<button onclick={() => { pend = true; n++; x = 1; }}>X</button>
|
||||||
|
<button onclick={() => { n++; cond = true; }}>Y</button>
|
||||||
|
<button onclick={() => { n++; cond = false; }}>Z</button>
|
||||||
|
<button onclick={() => { n++; cond = true; }}>W</button>
|
||||||
|
<button onclick={() => resolve('e')}>resolve e</button>
|
||||||
|
<button onclick={() => resolve('x1')}>resolve x1</button>
|
||||||
Loading…
Reference in new issue