fix: Derived stores are re-evaluated on invalid upstream state #10557
+103
−12
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Svelte 5 rewrite
This PR specifically targets svelte 5 though the issue this PR addresses is relevant to svelte 5 and svelte 4.
I would be happy to make a svelte 4 PR once this one is resolved.
Before submitting the PR, please make sure you do the following
This PR addresses #10376.
Currently, a change to a store's value only causes stores which are immediately dependent on it to be invalidated. Svelte does not propagate invalidation downstream to subsequent derived stores, and this can cause issues when two criteria are met:
Svelte's current implementation correctly handles dependency diamonds, but such cases do not meet the second criterion; unequal path length.
Example
Consider the following example:
This creates a dependency graph something like:
Svelte's Current Implementation
With sveltes current implementation, the derived store c will prematurely evaluate every time store a changes.
In the example above, if we change the input to
2
, the current implementation will go through the following sequence:Following the diagram, it's clear at point (5) that store
c
is evaluating prematurely. At point (5) storec
believes both its dependencies to be valid, but in fact onlya
has been resolved at this point.The correct behaviour would be for invalidations to be "deep" and for resolution to only occur once all dependencies are fully resolved. Thus in the given example,
c
should only emit once for each change toa
.