Skip to content

Commit 9a52007

Browse files
authored
fix: prevent batches from getting intertwined (#16446)
* ensure batches are kept separate * changeset * activate batch before decrementing
1 parent cc05cbc commit 9a52007

File tree

3 files changed

+34
-3
lines changed

3 files changed

+34
-3
lines changed

.changeset/fresh-birds-jam.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: prevent batches from getting intertwined

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ export class Boundary {
148148
// need to use hydration boundary comments to report whether
149149
// the pending or main block was rendered for a given
150150
// boundary, and hydrate accordingly
151-
queueMicrotask(() => {
151+
Batch.enqueue(() => {
152152
this.#main_effect = this.#run(() => {
153153
Batch.ensure();
154154
return branch(() => this.#children(this.#anchor));

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

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,19 @@ export let batch_deriveds = null;
4949
/** @type {Set<() => void>} */
5050
export let effect_pending_updates = new Set();
5151

52+
/** @type {Array<() => void>} */
53+
let tasks = [];
54+
55+
function dequeue() {
56+
const task = /** @type {() => void} */ (tasks.shift());
57+
58+
if (tasks.length > 0) {
59+
queueMicrotask(dequeue);
60+
}
61+
62+
task();
63+
}
64+
5265
/** @type {Effect[]} */
5366
let queued_root_effects = [];
5467

@@ -438,7 +451,7 @@ export class Batch {
438451
batches.add(current_batch);
439452

440453
if (autoflush) {
441-
queueMicrotask(() => {
454+
Batch.enqueue(() => {
442455
if (current_batch !== batch) {
443456
// a flushSync happened in the meantime
444457
return;
@@ -451,6 +464,15 @@ export class Batch {
451464

452465
return current_batch;
453466
}
467+
468+
/** @param {() => void} task */
469+
static enqueue(task) {
470+
if (tasks.length === 0) {
471+
queueMicrotask(dequeue);
472+
}
473+
474+
tasks.unshift(task);
475+
}
454476
}
455477

456478
/**
@@ -593,7 +615,11 @@ export function suspend() {
593615

594616
return function unsuspend() {
595617
boundary.update_pending_count(-1);
596-
if (!pending) batch.decrement();
618+
619+
if (!pending) {
620+
batch.activate();
621+
batch.decrement();
622+
}
597623

598624
unset_context();
599625
};

0 commit comments

Comments
 (0)