Skip to content

Commit 293bdfd

Browse files
committed
revised
1 parent f6a489e commit 293bdfd

File tree

2 files changed

+72
-8
lines changed

2 files changed

+72
-8
lines changed

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

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,13 @@ export function update_reaction(reaction) {
414414
skipped_deps = 0;
415415
untracked_writes = null;
416416
active_reaction = (flags & (BRANCH_EFFECT | ROOT_EFFECT)) === 0 ? reaction : null;
417-
skip_reaction = !is_flushing_effect && (flags & UNOWNED) !== 0;
417+
// prettier-ignore
418+
skip_reaction =
419+
(flags & UNOWNED) !== 0 &&
420+
(!is_flushing_effect ||
421+
(/** @type {Derived} */ (reaction).parent !== null &&
422+
(/** @type {Derived} */ (reaction).parent.f & DERIVED) !== 0));
423+
418424
derived_sources = null;
419425
set_component_context(reaction.ctx);
420426
untracking = false;
@@ -946,14 +952,14 @@ export function get(signal) {
946952
var parent = derived.parent;
947953

948954
if (parent !== null) {
949-
// Attach the derived to the nearest parent effect or derived
950-
if ((parent.f & DERIVED) !== 0) {
951-
var parent_derived = /** @type {Derived} */ (parent);
952-
953-
if (!parent_derived.children?.includes(derived)) {
954-
(parent_derived.children ??= []).push(derived);
955-
}
955+
// If the derived is owned by another derived then mark it as unowned
956+
// as the derived value might have been shared and thus we cannot determine
957+
// a true
958+
if ((parent.f & DERIVED) !== 0 && (parent.f & UNOWNED) === 0) {
959+
debugger;
960+
derived.f ^= UNOWNED;
956961
} else {
962+
// Otherwise we can attach the derieved to the parent effect
957963
var parent_effect = /** @type {Effect} */ (parent);
958964

959965
if (!parent_effect.deriveds?.includes(derived)) {

packages/svelte/tests/signals/test.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,64 @@ describe('signals', () => {
538538
};
539539
});
540540

541+
test('mixed nested deriveds correctly cleanup when no longer connected to graph #1', () => {
542+
let a: Derived<unknown>;
543+
let b: Derived<unknown>;
544+
let s = state(0);
545+
546+
const destroy = effect_root(() => {
547+
render_effect(() => {
548+
a = derived(() => {
549+
b = derived(() => {
550+
$.get(s);
551+
});
552+
$.untrack(() => {
553+
$.get(b);
554+
});
555+
$.get(s);
556+
});
557+
$.get(a);
558+
});
559+
});
560+
561+
return () => {
562+
flushSync();
563+
assert.equal(a?.deps?.length, 1);
564+
assert.equal(s?.reactions?.length, 1);
565+
destroy();
566+
assert.equal(s?.reactions, null);
567+
};
568+
});
569+
570+
test('mixed nested deriveds correctly cleanup when no longer connected to graph #2', () => {
571+
let a: Derived<unknown>;
572+
let b: Derived<unknown>;
573+
let s = state(0);
574+
575+
const destroy = effect_root(() => {
576+
render_effect(() => {
577+
a = derived(() => {
578+
b = derived(() => {
579+
$.get(s);
580+
});
581+
effect_root(() => {
582+
$.get(b);
583+
});
584+
$.get(s);
585+
});
586+
$.get(a);
587+
});
588+
});
589+
590+
return () => {
591+
flushSync();
592+
assert.equal(a?.deps?.length, 1);
593+
assert.equal(s?.reactions?.length, 1);
594+
destroy();
595+
assert.equal(s?.reactions, null);
596+
};
597+
});
598+
541599
test('deriveds update upon reconnection #1', () => {
542600
let a = state(false);
543601
let b = state(false);

0 commit comments

Comments
 (0)