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