fix: ensure deferred effects are properly revived after async operations (fixes #17304)fix: ensure deferred effects are properly revived after async operati…#17307
Conversation
🦋 Changeset detectedLatest commit: 89c2a32 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
Pull request overview
This PR fixes an issue where $effect callbacks stop firing after async operations in SvelteKit's preload functionality. The root cause was that when forks are committed, the revive() method in the batch system wasn't ensuring proper batch activation before scheduling deferred effects.
Key Changes:
- Modified the
revive()method to activate the batch before scheduling effects when the batch is not current - Added conditional logic to determine when to flush based on pending work or queued effects
- Added deactivation after processing when the batch wasn't current initially
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| packages/svelte/src/internal/client/reactivity/batch.js | Modified revive() method to handle batch activation/deactivation and conditional flushing when reviving deferred effects after async operations |
| .changeset/fix-async-reactivity-17304.md | Added changeset documenting the patch fix for deferred effects not firing after async operations |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
As far as I can tell this is AI slop that does not fix the issue mentioned. I've opened #17335 to actually address this. |
Fixes #17304
Problem Description
When using
asyncin SvelteKit with preloading data (viadata-sveltekit-preload-dataorpreloadData()),$effectcallbacks stop firing even though$inspectshows the values are updating correctly.Reproduction
The issue can be reproduced with the StackBlitz example: https://stackblitz.com/edit/sveltekit-reactivity-loss
Steps to reproduce:
data-sveltekit-preload-data="hover"on a link$effectto open a dialog$effectdoesn't fireRoot Cause
The issue occurs in the batch system's
revive()method inpackages/svelte/src/internal/client/reactivity/batch.js.When SvelteKit's preload functionality is used, it creates a "fork" to speculatively load data. When this fork is committed, it calls
batch.revive()to reschedule any deferred effects. However, therevive()method wasn't ensuring that the batch was properly activated before scheduling effects.The sequence of events:
#dirty_effectsand#maybe_dirty_effectsarraysCLEANto allow them to be rescheduled laterrevive()is called to reschedule these effectsschedule_effect()would add effects toqueued_root_effects, but they wouldn't be processed correctly because the batch context wasn't activeSolution
The fix ensures that:
Changes Made
Modified the
revive()method inbatch.jsto:Impact
This fix ensures that effects are properly revived after async operations complete, which is critical for:
fork()APIThe change is minimal and focused on ensuring the correct batch context