fix: reconnected deep derived signals to graph (#12350)

* fix: fixed derived disconnected issues

* add test

* changeset

* lint

* refactor

* Update packages/svelte/src/internal/client/reactivity/deriveds.js

Co-authored-by: Rich Harris <rich.harris@vercel.com>

* Update packages/svelte/src/internal/client/runtime.js

Co-authored-by: Rich Harris <rich.harris@vercel.com>

* address feedback

* tweak

* tweak

* simplify

* lint

---------

Co-authored-by: Rich Harris <rich.harris@vercel.com>
pull/12355/head
Dominic Gannaway 4 months ago committed by GitHub
parent 787e091a5e
commit 202f1dd819
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: reconnected deep derived signals to graph

@ -171,8 +171,17 @@ export function check_dirtiness(reaction) {
if (dependencies !== null) {
var is_unowned = (flags & UNOWNED) !== 0;
var i;
if ((flags & DISCONNECTED) !== 0) {
for (i = 0; i < dependencies.length; i++) {
(dependencies[i].reactions ??= []).push(reaction);
}
for (var i = 0; i < dependencies.length; i++) {
reaction.f ^= DISCONNECTED;
}
for (i = 0; i < dependencies.length; i++) {
var dependency = dependencies[i];
if (check_dirtiness(/** @type {import('#client').Derived} */ (dependency))) {
@ -771,25 +780,6 @@ export function get(signal) {
if (check_dirtiness(derived)) {
update_derived(derived);
}
if ((flags & DISCONNECTED) !== 0) {
// reconnect to the graph
deps = derived.deps;
if (deps !== null) {
for (var i = 0; i < deps.length; i++) {
var dep = deps[i];
var reactions = dep.reactions;
if (reactions === null) {
dep.reactions = [derived];
} else if (!reactions.includes(derived)) {
reactions.push(derived);
}
}
}
derived.f ^= DISCONNECTED;
}
}
return signal.v;

@ -550,6 +550,40 @@ describe('signals', () => {
};
});
test('deriveds update upon reconnection #3', () => {
let a = source(false);
let b = source(false);
let c = derived(() => $.get(a) || $.get(b));
let d = derived(() => $.get(c));
let e = derived(() => $.get(d));
return () => {
const log: string[] = [];
let destroy = effect_root(() => {
render_effect(() => {
$.get(e);
log.push('init');
});
});
destroy();
destroy = effect_root(() => {
render_effect(() => {
$.get(e);
log.push('update');
});
});
assert.deepEqual(log, ['init', 'update']);
set(a, true);
flushSync();
assert.deepEqual(log, ['init', 'update', 'update']);
};
});
test('unowned deriveds are not added as reactions', () => {
var count = source(0);

Loading…
Cancel
Save