@@ -4,7 +4,6 @@ import { define_property, get_descriptors, get_prototype_of, index_of } from '..
44import {
55 destroy_block_effect_children ,
66 destroy_effect_children ,
7- destroy_effect_deriveds ,
87 execute_effect_teardown ,
98 unlink_effect
109} from './reactivity/effects.js' ;
@@ -28,7 +27,12 @@ import {
2827} from './constants.js' ;
2928import { flush_tasks } from './dom/task.js' ;
3029import { internal_set } from './reactivity/sources.js' ;
31- import { destroy_derived , execute_derived , update_derived } from './reactivity/deriveds.js' ;
30+ import {
31+ destroy_derived ,
32+ destroy_derived_effects ,
33+ execute_derived ,
34+ update_derived
35+ } from './reactivity/deriveds.js' ;
3236import * as e from './errors.js' ;
3337import { FILENAME } from '../../constants.js' ;
3438import { tracing_mode_flag } from '../flags/index.js' ;
@@ -405,7 +409,16 @@ export function update_reaction(reaction) {
405409 skipped_deps = 0 ;
406410 untracked_writes = null ;
407411 active_reaction = ( flags & ( BRANCH_EFFECT | ROOT_EFFECT ) ) === 0 ? reaction : null ;
408- skip_reaction = ! is_flushing_effect && ( flags & UNOWNED ) !== 0 ;
412+ // prettier-ignore
413+ skip_reaction =
414+ ( flags & UNOWNED ) !== 0 &&
415+ ( ! is_flushing_effect ||
416+ // If we were previously not in a reactive context and we're reading an unowned derived
417+ // that was created inside another reaction, then we don't fully know the real owner and thus
418+ // we need to skip adding any reactions for this unowned
419+ ( ( previous_reaction === null || previous_untracking ) &&
420+ /** @type {Derived } */ ( reaction ) . parent !== null ) ) ;
421+
409422 derived_sources = null ;
410423 set_component_context ( reaction . ctx ) ;
411424 untracking = false ;
@@ -513,6 +526,8 @@ function remove_reaction(signal, dependency) {
513526 if ( ( dependency . f & ( UNOWNED | DISCONNECTED ) ) === 0 ) {
514527 dependency . f ^= DISCONNECTED ;
515528 }
529+ // Disconnect any reactions owned by this reaction
530+ destroy_derived_effects ( /** @type {Derived } **/ ( dependency ) ) ;
516531 remove_reactions ( /** @type {Derived } **/ ( dependency ) , 0 ) ;
517532 }
518533}
@@ -560,7 +575,6 @@ export function update_effect(effect) {
560575 } else {
561576 destroy_effect_children ( effect ) ;
562577 }
563- destroy_effect_deriveds ( effect ) ;
564578
565579 execute_effect_teardown ( effect ) ;
566580 var teardown = update_reaction ( effect ) ;
@@ -930,30 +944,20 @@ export function get(signal) {
930944 new_deps . push ( signal ) ;
931945 }
932946 }
933- }
934-
935- if (
947+ } else if (
936948 is_derived &&
937949 /** @type {Derived } */ ( signal ) . deps === null &&
938- ( active_reaction === null || untracking || ( active_reaction . f & DERIVED ) !== 0 )
950+ /** @type { Derived } */ ( signal ) . effects === null
939951 ) {
940952 var derived = /** @type {Derived } */ ( signal ) ;
941953 var parent = derived . parent ;
942954
943955 if ( parent !== null ) {
944- // Attach the derived to the nearest parent effect or derived
945- if ( ( parent . f & DERIVED ) !== 0 ) {
946- var parent_derived = /** @type {Derived } */ ( parent ) ;
947-
948- if ( ! parent_derived . children ?. includes ( derived ) ) {
949- ( parent_derived . children ??= [ ] ) . push ( derived ) ;
950- }
951- } else {
952- var parent_effect = /** @type {Effect } */ ( parent ) ;
953-
954- if ( ! parent_effect . deriveds ?. includes ( derived ) ) {
955- ( parent_effect . deriveds ??= [ ] ) . push ( derived ) ;
956- }
956+ // If the derived is owned by another derived then mark it as unowned
957+ // as the derived value might have been referenced in a different context
958+ // since and thus its parent might not be its true owner anymore
959+ if ( ( parent . f & UNOWNED ) === 0 ) {
960+ derived . f ^= UNOWNED ;
957961 }
958962 }
959963 }
0 commit comments