add test, fix block resolution

pull/16971/head
Rich Harris 2 weeks ago
parent cfa87a9c37
commit 925dbebdd6

@ -157,12 +157,7 @@ export class Batch {
this.#traverse_effect_tree(root, target);
}
// if there is no outstanding async work, commit
if (this.#pending === 0) {
// commit before flushing effects, since that may result in
// another batch being created
this.#commit();
}
this.#resolve();
if (this.#blocking_pending > 0) {
this.#defer_effects(target.effects);
@ -300,8 +295,8 @@ export class Batch {
// this can happen if a new batch was created during `flush_effects()`
return;
}
} else if (this.#pending === 0) {
this.#commit();
} else {
this.#resolve();
}
this.deactivate();
@ -317,16 +312,19 @@ export class Batch {
}
}
/**
* Append and remove branches to/from the DOM
*/
#commit() {
for (const fn of this.#callbacks) {
fn();
#resolve() {
if (this.#blocking_pending === 0) {
// append/remove branches
for (const fn of this.#callbacks) fn();
this.#callbacks.clear();
}
this.#callbacks.clear();
if (this.#pending === 0) {
this.#commit();
}
}
#commit() {
// If there are other pending batches, they now need to be 'rebased' —
// in other words, we re-run block/async effects with the newly
// committed state, unless the batch in question has a more

@ -0,0 +1,63 @@
import { tick } from 'svelte';
import { test } from '../../test';
export default test({
async test({ assert, target }) {
const [increment, shift] = target.querySelectorAll('button');
shift.click();
await tick();
shift.click();
await tick();
assert.htmlEqual(
target.innerHTML,
`
<button>0</button>
<button>shift</button>
<p>even</p>
<p>0</p>
`
);
increment.click();
await tick();
assert.htmlEqual(
target.innerHTML,
`
<button>1</button>
<button>shift</button>
<p>even</p>
<p>0</p>
`
);
shift.click();
await tick();
assert.htmlEqual(
target.innerHTML,
`
<button>1</button>
<button>shift</button>
<p>odd</p>
<p>loading...</p>
`
);
shift.click();
await tick();
assert.htmlEqual(
target.innerHTML,
`
<button>1</button>
<button>shift</button>
<p>odd</p>
<p>1</p>
`
);
}
});

@ -0,0 +1,36 @@
<script>
let resolvers = [];
function push(value) {
const { promise, resolve } = Promise.withResolvers();
resolvers.push(() => resolve(value));
return promise;
}
let count = $state(0);
</script>
<button onclick={() => count += 1}>{$state.eager(count)}</button>
<button onclick={() => resolvers.shift()?.()}>shift</button>
<svelte:boundary>
{#if await push(count) % 2 === 0}
<p>even</p>
{:else}
<p>odd</p>
{/if}
{#key count}
<svelte:boundary>
<p>{await push(count)}</p>
{#snippet pending()}
<p>loading...</p>
{/snippet}
</svelte:boundary>
{/key}
{#snippet pending()}
<p>loading...</p>
{/snippet}
</svelte:boundary>
Loading…
Cancel
Save