mirror of https://github.com/sveltejs/svelte
Merge 29f4cc7348 into 020242d6be
commit
c4e87caef1
@ -0,0 +1,7 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
fix: $effect.pending() should not be affected by uncommitted forks
|
||||
|
||||
$effect.pending() and boundary pending snippets were incorrectly triggered by async work inside an uncommitted fork. The `increment_pending()` function in the async reactivity module now checks whether the current batch is a fork (`batch.is_fork`). If it is, the boundary's pending count is left untouched — only the batch's own pending count is updated so that `commit` can still await the async work. This makes `$effect.pending()` behave consistently with `$state.eager()`, which is similarly unaffected by uncommitted forks.
|
||||
@ -0,0 +1,44 @@
|
||||
import { tick } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
async test({ assert, target }) {
|
||||
const [shift, increment, commit] = target.querySelectorAll('button');
|
||||
|
||||
shift.click();
|
||||
await tick();
|
||||
|
||||
// baseline: count 0, even, nothing pending
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<button>shift</button>
|
||||
<button>increment</button>
|
||||
<button>commit</button>
|
||||
<p>count: 0</p>
|
||||
<p>eager: 0</p>
|
||||
<p>pending: 0</p>
|
||||
<p>even</p>
|
||||
`
|
||||
);
|
||||
|
||||
// start a fork that changes state, but does NOT commit it.
|
||||
// $effect.pending() must stay 0 — the fork's async work has not
|
||||
// been committed, so it must not surface as pending
|
||||
increment.click();
|
||||
await tick();
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<button>shift</button>
|
||||
<button>increment</button>
|
||||
<button>commit</button>
|
||||
<p>count: 0</p>
|
||||
<p>eager: 0</p>
|
||||
<p>pending: 0</p>
|
||||
<p>even</p>
|
||||
`
|
||||
);
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,38 @@
|
||||
<script>
|
||||
import { fork } from 'svelte';
|
||||
|
||||
let count = $state(0);
|
||||
|
||||
const resolvers = [];
|
||||
let f = null;
|
||||
|
||||
function push(value) {
|
||||
const { promise, resolve } = Promise.withResolvers();
|
||||
resolvers.push(() => resolve(value));
|
||||
return promise;
|
||||
}
|
||||
</script>
|
||||
|
||||
<button onclick={() => resolvers.shift()?.()}>shift</button>
|
||||
<button onclick={async () => {
|
||||
f = await fork(() => {
|
||||
count += 1;
|
||||
});
|
||||
}}>increment</button>
|
||||
<button onclick={() => f?.commit()}>commit</button>
|
||||
|
||||
<p>count: {count}</p>
|
||||
<p>eager: {$state.eager(count)}</p>
|
||||
<p>pending: {$effect.pending()}</p>
|
||||
|
||||
<svelte:boundary>
|
||||
{#if await push(count) % 2 === 0}
|
||||
<p>even</p>
|
||||
{:else}
|
||||
<p>odd</p>
|
||||
{/if}
|
||||
|
||||
{#snippet pending()}
|
||||
<p>loading...</p>
|
||||
{/snippet}
|
||||
</svelte:boundary>
|
||||
Loading…
Reference in new issue