Skip to content

Commit 983083f

Browse files
committed
suspend batch, not boundary
1 parent 3e17010 commit 983083f

File tree

7 files changed

+90
-18
lines changed

7 files changed

+90
-18
lines changed

packages/svelte/src/internal/client/dom/blocks/boundary.js

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -416,17 +416,6 @@ export function capture(track = true) {
416416
};
417417
}
418418

419-
// TODO we should probably be incrementing the current batch, not the boundary?
420-
export function suspend() {
421-
let boundary = get_pending_boundary();
422-
423-
boundary.update_pending_count(1);
424-
425-
return function unsuspend() {
426-
boundary.update_pending_count(-1);
427-
};
428-
}
429-
430419
/**
431420
* Wraps an `await` expression in such a way that the effect context that was
432421
* active before the expression evaluated can be reapplied afterwards —

packages/svelte/src/internal/client/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ export {
9898
props_id,
9999
with_script
100100
} from './dom/template.js';
101+
export { suspend } from './reactivity/batch.js';
101102
export {
102103
async_derived,
103104
user_derived as derived,
@@ -135,7 +136,7 @@ export {
135136
update_store,
136137
mark_store_binding
137138
} from './reactivity/store.js';
138-
export { boundary, pending, save, suspend } from './dom/blocks/boundary.js';
139+
export { boundary, pending, save } from './dom/blocks/boundary.js';
139140
export { set_text } from './render.js';
140141
export {
141142
get,

packages/svelte/src/internal/client/reactivity/batch.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/** @import { Derived, Effect, Source } from '#client' */
22
import { CLEAN, DIRTY } from '#client/constants';
33
import { deferred } from '../../shared/utils.js';
4+
import { get_pending_boundary } from '../dom/blocks/boundary.js';
45
import {
56
flush_queued_effects,
67
flush_queued_root_effects,
@@ -275,6 +276,8 @@ export class Batch {
275276

276277
this.render_effects = [];
277278
this.effects = [];
279+
280+
this.flush();
278281
}
279282
}
280283

@@ -322,6 +325,20 @@ export class Batch {
322325
}
323326
}
324327

328+
export function suspend() {
329+
var boundary = get_pending_boundary();
330+
var batch = /** @type {Batch} */ (current_batch);
331+
var pending = boundary.pending;
332+
333+
boundary.update_pending_count(1);
334+
if (!pending) batch.increment();
335+
336+
return function unsuspend() {
337+
boundary.update_pending_count(-1);
338+
if (!pending) batch.decrement();
339+
};
340+
}
341+
325342
/**
326343
* Forcibly remove all current batches, to prevent cross-talk between tests
327344
*/

packages/svelte/src/internal/client/reactivity/deriveds.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,6 @@ export function async_derived(fn, location) {
152152

153153
from_async_derived = null;
154154

155-
if (should_suspend) {
156-
boundary.update_pending_count(-1);
157-
if (!pending) batch.decrement();
158-
}
159-
160155
if (!pending) batch.restore();
161156

162157
if (error) {
@@ -185,7 +180,10 @@ export function async_derived(fn, location) {
185180
}
186181
}
187182

188-
if (!pending) batch.flush();
183+
if (should_suspend) {
184+
boundary.update_pending_count(-1);
185+
if (!pending) batch.decrement();
186+
}
189187
};
190188

191189
promise.then(handler, (e) => handler(null, e || 'unknown'));
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<script>
2+
let { promise } = $props();
3+
4+
let value = await promise;
5+
</script>
6+
7+
<p>{value}</p>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { tick } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
async test({ assert, target }) {
6+
const [toggle, hello] = target.querySelectorAll('button');
7+
8+
assert.htmlEqual(
9+
target.innerHTML,
10+
`
11+
<button>toggle</button>
12+
<button>hello</button>
13+
`
14+
);
15+
16+
toggle.click();
17+
await tick();
18+
19+
assert.htmlEqual(
20+
target.innerHTML,
21+
`
22+
<button>toggle</button>
23+
<button>hello</button>
24+
`
25+
);
26+
27+
hello.click();
28+
await tick();
29+
30+
assert.htmlEqual(
31+
target.innerHTML,
32+
`
33+
<button>toggle</button>
34+
<button>hello</button>
35+
<p>condition is true</p>
36+
<p>hello</p>
37+
`
38+
);
39+
}
40+
});
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<script>
2+
import Child from './Child.svelte';
3+
4+
let condition = $state(false);
5+
let deferred = $state(Promise.withResolvers());
6+
</script>
7+
8+
<button onclick={() => condition = !condition}>toggle</button>
9+
<button onclick={() => deferred.resolve('hello')}>hello</button>
10+
11+
<svelte:boundary>
12+
{#if condition}
13+
<p>condition is {condition}</p>
14+
<Child promise={deferred.promise} />
15+
{/if}
16+
17+
{#snippet pending()}
18+
<p>pending</p>
19+
{/snippet}
20+
</svelte:boundary>

0 commit comments

Comments
 (0)