File tree Expand file tree Collapse file tree 2 files changed +72
-8
lines changed
Expand file tree Collapse file tree 2 files changed +72
-8
lines changed Original file line number Diff line number Diff 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 ) ) {
Original file line number Diff line number Diff 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 ) ;
You can’t perform that action at this time.
0 commit comments