Skip to content

Commit 202f1dd

Browse files
trueadmRich-Harris
andauthored
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 <[email protected]> * Update packages/svelte/src/internal/client/runtime.js Co-authored-by: Rich Harris <[email protected]> * address feedback * tweak * tweak * simplify * lint --------- Co-authored-by: Rich Harris <[email protected]>
1 parent 787e091 commit 202f1dd

File tree

3 files changed

+49
-20
lines changed

3 files changed

+49
-20
lines changed

.changeset/smart-zoos-vanish.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: reconnected deep derived signals to graph

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

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,17 @@ export function check_dirtiness(reaction) {
171171

172172
if (dependencies !== null) {
173173
var is_unowned = (flags & UNOWNED) !== 0;
174+
var i;
175+
176+
if ((flags & DISCONNECTED) !== 0) {
177+
for (i = 0; i < dependencies.length; i++) {
178+
(dependencies[i].reactions ??= []).push(reaction);
179+
}
174180

175-
for (var i = 0; i < dependencies.length; i++) {
181+
reaction.f ^= DISCONNECTED;
182+
}
183+
184+
for (i = 0; i < dependencies.length; i++) {
176185
var dependency = dependencies[i];
177186

178187
if (check_dirtiness(/** @type {import('#client').Derived} */ (dependency))) {
@@ -771,25 +780,6 @@ export function get(signal) {
771780
if (check_dirtiness(derived)) {
772781
update_derived(derived);
773782
}
774-
775-
if ((flags & DISCONNECTED) !== 0) {
776-
// reconnect to the graph
777-
deps = derived.deps;
778-
779-
if (deps !== null) {
780-
for (var i = 0; i < deps.length; i++) {
781-
var dep = deps[i];
782-
var reactions = dep.reactions;
783-
if (reactions === null) {
784-
dep.reactions = [derived];
785-
} else if (!reactions.includes(derived)) {
786-
reactions.push(derived);
787-
}
788-
}
789-
}
790-
791-
derived.f ^= DISCONNECTED;
792-
}
793783
}
794784

795785
return signal.v;

packages/svelte/tests/signals/test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,40 @@ describe('signals', () => {
550550
};
551551
});
552552

553+
test('deriveds update upon reconnection #3', () => {
554+
let a = source(false);
555+
let b = source(false);
556+
557+
let c = derived(() => $.get(a) || $.get(b));
558+
let d = derived(() => $.get(c));
559+
let e = derived(() => $.get(d));
560+
561+
return () => {
562+
const log: string[] = [];
563+
let destroy = effect_root(() => {
564+
render_effect(() => {
565+
$.get(e);
566+
log.push('init');
567+
});
568+
});
569+
destroy();
570+
571+
destroy = effect_root(() => {
572+
render_effect(() => {
573+
$.get(e);
574+
log.push('update');
575+
});
576+
});
577+
578+
assert.deepEqual(log, ['init', 'update']);
579+
580+
set(a, true);
581+
flushSync();
582+
583+
assert.deepEqual(log, ['init', 'update', 'update']);
584+
};
585+
});
586+
553587
test('unowned deriveds are not added as reactions', () => {
554588
var count = source(0);
555589

0 commit comments

Comments
 (0)