@ -209,18 +209,28 @@ export function check_dirtiness(reaction) {
( is _disconnected || is _unowned _connected ) &&
( active _effect === null || ( active _effect . f & DESTROYED ) === 0 )
) {
var derived = /** @type {Derived} */ ( reaction ) ;
var parent = derived . parent ;
for ( i = 0 ; i < length ; i ++ ) {
dependency = dependencies [ i ] ;
// We always re-add all reactions (even duplicates) if the derived was
// previously disconnected
if ( is _disconnected || ! dependency ? . reactions ? . includes ( reaction ) ) {
( dependency . reactions ? ? = [ ] ) . push ( reaction ) ;
// previously disconnected, however we don't if it was unowned as we
// de-duplicate dependencies in that case
if ( is _disconnected || ! dependency ? . reactions ? . includes ( derived ) ) {
( dependency . reactions ? ? = [ ] ) . push ( derived ) ;
}
}
if ( is _disconnected ) {
reaction . f ^= DISCONNECTED ;
derived . f ^= DISCONNECTED ;
}
// If the unowned derived is now fully connected to the graph again (it's unowned and reconnected, has a parent
// and the parent is not unowned), then we can mark it as connected again, removing the need for the unowned
// flag
if ( is _unowned _connected && parent !== null && ( parent . f & UNOWNED ) === 0 ) {
derived . f ^= UNOWNED ;
}
}
@ -423,15 +433,9 @@ export function update_reaction(reaction) {
skipped _deps = 0 ;
untracked _writes = null ;
active _reaction = ( flags & ( BRANCH _EFFECT | ROOT _EFFECT ) ) === 0 ? reaction : null ;
// prettier-ignore
skip _reaction =
( flags & UNOWNED ) !== 0 &&
( ! is _flushing _effect ||
// If we were previously not in a reactive context and we're reading an unowned derived
// that was created inside another reaction, then we don't fully know the real owner and thus
// we need to skip adding any reactions for this unowned
( ( previous _reaction === null || previous _untracking ) &&
/** @type {Derived} */ ( reaction ) . parent !== null ) ) ;
( ! is _flushing _effect || previous _reaction === null || previous _untracking ) ;
derived _sources = null ;
set _component _context ( reaction . ctx ) ;
@ -697,10 +701,7 @@ function flush_queued_root_effects(root_effects) {
effect . f ^= CLEAN ;
}
/** @type {Effect[]} */
var collected _effects = [ ] ;
process _effects ( effect , collected _effects ) ;
var collected _effects = process _effects ( effect ) ;
flush _queued _effects ( collected _effects ) ;
}
} finally {
@ -804,13 +805,14 @@ export function schedule_effect(signal) {
* effects to be flushed .
*
* @ param { Effect } effect
* @ param { Effect [ ] } collected_ effects
* @ param { Effect [ ] } effects
* @ param { Boundary } [ boundary ]
* @ returns { void }
* @ returns { Effect [ ] }
* /
function process _effects ( effect , collected _effects , boundary ) {
function process _effects ( effect , effects = [ ] , boundary ) {
var current _effect = effect . first ;
var current _effect = effect . first ;
var effects = [ ] ;
main _loop : while ( current _effect !== null ) {
var flags = current _effect . f ;
@ -825,7 +827,7 @@ function process_effects(effect, collected_effects, boundary) {
} else if ( ( flags & BOUNDARY _EFFECT ) !== 0 ) {
var b = /** @type {Boundary} */ ( current _effect . b ) ;
process _effects ( current _effect , collected_ effects, b ) ;
process _effects ( current _effect , effects, b ) ;
if ( ! b . suspended ) {
// no more async work to happen
@ -859,6 +861,30 @@ function process_effects(effect, collected_effects, boundary) {
}
} else if ( ( flags & EFFECT ) !== 0 ) {
effects . push ( current _effect ) ;
} else if ( is _branch ) {
current _effect . f ^= CLEAN ;
} else {
// Ensure we set the effect to be the active reaction
// to ensure that unowned deriveds are correctly tracked
// because we're flushing the current effect
var previous _active _reaction = active _reaction ;
try {
active _reaction = current _effect ;
if ( check _dirtiness ( current _effect ) ) {
update _effect ( current _effect ) ;
}
} catch ( error ) {
handle _error ( error , current _effect , null , current _effect . ctx ) ;
} finally {
active _reaction = previous _active _reaction ;
}
}
var child = current _effect . first ;
if ( child !== null ) {
current _effect = child ;
continue ;
}
}
@ -882,13 +908,7 @@ function process_effects(effect, collected_effects, boundary) {
current _effect = sibling ;
}
// We might be dealing with many effects here, far more than can be spread into
// an array push call (callstack overflow). So let's deal with each effect in a loop.
for ( var i = 0 ; i < effects . length ; i ++ ) {
child = effects [ i ] ;
collected _effects . push ( child ) ;
process _effects ( child , collected _effects ) ;
}
return effects ;
}
/ * *
@ -985,7 +1005,10 @@ export function get(signal) {
skipped _deps ++ ;
} else if ( new _deps === null ) {
new _deps = [ signal ] ;
} else {
} else if ( ! skip _reaction || ! new _deps . includes ( signal ) ) {
// Normally we can push duplicated dependencies to `new_deps`, but if we're inside
// an unowned derived because skip_reaction is true, then we need to ensure that
// we don't have duplicates
new _deps . push ( signal ) ;
}
}