fix: make unnecessary commit work less likely (#18263)

While looking at
https://github.com/sveltejs/svelte/issues/18221#issuecomment-4497918414
and trying to understand how the invariant can happen I noticed that we
are not correctly filtering during commit.
- we were not ignoring deriveds
- we were not comparing the correct values (checking `source.v` instead
of the saved value) and not checking if their "is a derived" state
differs

I'm not able to come up with a test where something fails without these
(possibly because it's more about an optimization to do less reruns and
not about correctness) fixes, but they do make sense.
pull/18271/head
Simon H 1 month ago committed by GitHub
parent 91a42e2ed6
commit 4656e6895d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: make unnecessary commit work less likely

@ -677,8 +677,10 @@ export class Batch {
if (!batch.#started) continue;
// Re-run async/block effects that depend on distinct values changed in both batches
var others = [...batch.current.keys()].filter((s) => !this.current.has(s));
// Re-run async/block effects that depend on distinct values changed in both batches (ignoring deriveds)
var others = [...batch.current.keys()].filter(
(s) => !(/** @type {[any, boolean]} */ (batch.current.get(s))[1]) && !this.current.has(s)
);
if (others.length === 0) {
if (is_earlier) {
@ -718,11 +720,14 @@ export class Batch {
}
checked = new Map();
var current_unequal = [...batch.current.keys()].filter((c) =>
this.current.has(c)
? /** @type {[any, boolean]} */ (this.current.get(c))[0] !== c.v
: true
);
var current_unequal = [...batch.current]
.filter(([c, v1]) => {
const v2 = this.current.get(c);
if (!v2) return true;
// Either their values are different or one is a derived but not the other
return v2[0] !== v1[0] || v2[1] !== v1[1];
})
.map(([c]) => c);
if (current_unequal.length > 0) {
for (const effect of this.#new_effects) {

Loading…
Cancel
Save