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
// the pending or main block was rendered for a given
// boundary, and hydrate accordingly
queueMicrotask(() => {
Batch.enqueue(() => {
this.#main_effect = this.#run(() => {
Batch.ensure();
return branch(() => this.#children(this.#anchor));

@ -49,6 +49,19 @@ export let batch_deriveds = null;
/** @type {Set<() => void>} */
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[]} */
let queued_root_effects = [];
@ -438,7 +451,7 @@ export class Batch {
batches.add(current_batch);
if (autoflush) {
queueMicrotask(() => {
Batch.enqueue(() => {
if (current_batch !== batch) {
// a flushSync happened in the meantime
return;
@ -451,6 +464,15 @@ export class 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() {
boundary.update_pending_count(-1);
if (!pending) batch.decrement();
if (!pending) {
batch.activate();
batch.decrement();
}
unset_context();
};

Loading…
Cancel
Save