Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/fix-async-reactivity-17304.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'svelte': patch
---

fix: ensure deferred effects are properly revived after async operations (fixes #17304)

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.
16 changes: 15 additions & 1 deletion packages/svelte/src/internal/client/reactivity/batch.js
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,13 @@ export class Batch {
}

revive() {
// Ensure the batch is active before scheduling effects
// This is critical for fork commits (used by SvelteKit's preload)
var was_current = current_batch === this;
if (!was_current) {
this.activate();
}

for (const e of this.#dirty_effects) {
set_signal_status(e, DIRTY);
schedule_effect(e);
Expand All @@ -496,7 +503,14 @@ export class Batch {
this.#dirty_effects = [];
this.#maybe_dirty_effects = [];

this.flush();
// Always flush if we have pending work that needs to be resolved
if (this.#pending === 0 || queued_root_effects.length > 0) {
this.flush();
}

if (!was_current) {
this.deactivate();
}
}

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