suspend batch, not boundary

pull/15844/head
Rich Harris 3 months ago
parent 3e1701024b
commit 983083fb82

@ -416,17 +416,6 @@ export function capture(track = true) {
};
}
// TODO we should probably be incrementing the current batch, not the boundary?
export function suspend() {
let boundary = get_pending_boundary();
boundary.update_pending_count(1);
return function unsuspend() {
boundary.update_pending_count(-1);
};
}
/**
* Wraps an `await` expression in such a way that the effect context that was
* active before the expression evaluated can be reapplied afterwards

@ -98,6 +98,7 @@ export {
props_id,
with_script
} from './dom/template.js';
export { suspend } from './reactivity/batch.js';
export {
async_derived,
user_derived as derived,
@ -135,7 +136,7 @@ export {
update_store,
mark_store_binding
} from './reactivity/store.js';
export { boundary, pending, save, suspend } from './dom/blocks/boundary.js';
export { boundary, pending, save } from './dom/blocks/boundary.js';
export { set_text } from './render.js';
export {
get,

@ -1,6 +1,7 @@
/** @import { Derived, Effect, Source } from '#client' */
import { CLEAN, DIRTY } from '#client/constants';
import { deferred } from '../../shared/utils.js';
import { get_pending_boundary } from '../dom/blocks/boundary.js';
import {
flush_queued_effects,
flush_queued_root_effects,
@ -275,6 +276,8 @@ export class Batch {
this.render_effects = [];
this.effects = [];
this.flush();
}
}
@ -322,6 +325,20 @@ export class Batch {
}
}
export function suspend() {
var boundary = get_pending_boundary();
var batch = /** @type {Batch} */ (current_batch);
var pending = boundary.pending;
boundary.update_pending_count(1);
if (!pending) batch.increment();
return function unsuspend() {
boundary.update_pending_count(-1);
if (!pending) batch.decrement();
};
}
/**
* Forcibly remove all current batches, to prevent cross-talk between tests
*/

@ -152,11 +152,6 @@ export function async_derived(fn, location) {
from_async_derived = null;
if (should_suspend) {
boundary.update_pending_count(-1);
if (!pending) batch.decrement();
}
if (!pending) batch.restore();
if (error) {
@ -185,7 +180,10 @@ export function async_derived(fn, location) {
}
}
if (!pending) batch.flush();
if (should_suspend) {
boundary.update_pending_count(-1);
if (!pending) batch.decrement();
}
};
promise.then(handler, (e) => handler(null, e || 'unknown'));

@ -0,0 +1,7 @@
<script>
let { promise } = $props();
let value = await promise;
</script>
<p>{value}</p>

@ -0,0 +1,40 @@
import { tick } from 'svelte';
import { test } from '../../test';
export default test({
async test({ assert, target }) {
const [toggle, hello] = target.querySelectorAll('button');
assert.htmlEqual(
target.innerHTML,
`
<button>toggle</button>
<button>hello</button>
`
);
toggle.click();
await tick();
assert.htmlEqual(
target.innerHTML,
`
<button>toggle</button>
<button>hello</button>
`
);
hello.click();
await tick();
assert.htmlEqual(
target.innerHTML,
`
<button>toggle</button>
<button>hello</button>
<p>condition is true</p>
<p>hello</p>
`
);
}
});

@ -0,0 +1,20 @@
<script>
import Child from './Child.svelte';
let condition = $state(false);
let deferred = $state(Promise.withResolvers());
</script>
<button onclick={() => condition = !condition}>toggle</button>
<button onclick={() => deferred.resolve('hello')}>hello</button>
<svelte:boundary>
{#if condition}
<p>condition is {condition}</p>
<Child promise={deferred.promise} />
{/if}
{#snippet pending()}
<p>pending</p>
{/snippet}
</svelte:boundary>
Loading…
Cancel
Save