Skip to content

Commit 04b686b

Browse files
committed
fix: ensure deferred effects are properly revived after async operations (fixes #17304)
1 parent 0cdc431 commit 04b686b

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: ensure deferred effects are properly revived after async operations (fixes #17304)
6+
7+
When using `async` in SvelteKit with preloading data (via `data-sveltekit-preload-data` or `preloadData()`), `$effect` callbacks were not firing even though values were updating. This was because when forks are committed (which SvelteKit's preload uses), the `revive()` method wasn't ensuring the batch was properly activated before scheduling deferred effects. This fix ensures the batch context is correct when reviving effects.

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,13 @@ export class Batch {
483483
}
484484

485485
revive() {
486+
// Ensure the batch is active before scheduling effects
487+
// This is critical for fork commits (used by SvelteKit's preload)
488+
var was_current = current_batch === this;
489+
if (!was_current) {
490+
this.activate();
491+
}
492+
486493
for (const e of this.#dirty_effects) {
487494
set_signal_status(e, DIRTY);
488495
schedule_effect(e);
@@ -496,7 +503,14 @@ export class Batch {
496503
this.#dirty_effects = [];
497504
this.#maybe_dirty_effects = [];
498505

499-
this.flush();
506+
// Always flush if we have pending work that needs to be resolved
507+
if (this.#pending === 0 || queued_root_effects.length > 0) {
508+
this.flush();
509+
}
510+
511+
if (!was_current) {
512+
this.deactivate();
513+
}
500514
}
501515

502516
/** @param {() => void} fn */

0 commit comments

Comments
 (0)