fix: prevent batches from getting intertwined (#16446)

* ensure batches are kept separate

* changeset

* activate batch before decrementing
pull/16450/head
Rich Harris 2 months ago committed by GitHub
parent cc05cbcf5c
commit 9a52007785
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: prevent batches from getting intertwined

@ -148,7 +148,7 @@ export class Boundary {
// need to use hydration boundary comments to report whether // need to use hydration boundary comments to report whether
// the pending or main block was rendered for a given // the pending or main block was rendered for a given
// boundary, and hydrate accordingly // boundary, and hydrate accordingly
queueMicrotask(() => { Batch.enqueue(() => {
this.#main_effect = this.#run(() => { this.#main_effect = this.#run(() => {
Batch.ensure(); Batch.ensure();
return branch(() => this.#children(this.#anchor)); return branch(() => this.#children(this.#anchor));

@ -49,6 +49,19 @@ export let batch_deriveds = null;
/** @type {Set<() => void>} */ /** @type {Set<() => void>} */
export let effect_pending_updates = new Set(); export let effect_pending_updates = new Set();
/** @type {Array<() => void>} */
let tasks = [];
function dequeue() {
const task = /** @type {() => void} */ (tasks.shift());
if (tasks.length > 0) {
queueMicrotask(dequeue);
}
task();
}
/** @type {Effect[]} */ /** @type {Effect[]} */
let queued_root_effects = []; let queued_root_effects = [];
@ -438,7 +451,7 @@ export class Batch {
batches.add(current_batch); batches.add(current_batch);
if (autoflush) { if (autoflush) {
queueMicrotask(() => { Batch.enqueue(() => {
if (current_batch !== batch) { if (current_batch !== batch) {
// a flushSync happened in the meantime // a flushSync happened in the meantime
return; return;
@ -451,6 +464,15 @@ export class Batch {
return current_batch; return current_batch;
} }
/** @param {() => void} task */
static enqueue(task) {
if (tasks.length === 0) {
queueMicrotask(dequeue);
}
tasks.unshift(task);
}
} }
/** /**
@ -593,7 +615,11 @@ export function suspend() {
return function unsuspend() { return function unsuspend() {
boundary.update_pending_count(-1); boundary.update_pending_count(-1);
if (!pending) batch.decrement();
if (!pending) {
batch.activate();
batch.decrement();
}
unset_context(); unset_context();
}; };

Loading…
Cancel
Save