@ -130,11 +130,13 @@ export class Batch {
# maybe _dirty _effects = new Set ( ) ;
/ * *
* A set of branches that still exist , but will be destroyed when this batch
* is committed — we skip over these during ` process `
* @ type { Set < Effect > }
* A map of branches that still exist , but will be destroyed when this batch
* is committed — we skip over these during ` process ` .
* The value contains child effects that were dirty / maybe _dirty before being reset ,
* so they can be rescheduled if the branch survives .
* @ type { Map < Effect , { d : Effect [ ] , m : Effect [ ] } > }
* /
skipped _effects = new Set ( ) ;
skipped _effects = new Map ( ) ;
is _fork = false ;
@ -144,6 +146,38 @@ export class Batch {
return this . is _fork || this . # blocking _pending > 0 ;
}
/ * *
* Add an effect to the skipped _effects map and reset its children
* @ param { Effect } effect
* /
skip _effect ( effect ) {
if ( ! this . skipped _effects . has ( effect ) ) {
this . skipped _effects . set ( effect , { d : [ ] , m : [ ] } ) ;
}
}
/ * *
* Remove an effect from the skipped _effects map and reschedule
* any tracked dirty / maybe _dirty child effects
* @ param { Effect } effect
* /
unskip _effect ( effect ) {
var tracked = this . skipped _effects . get ( effect ) ;
if ( tracked ) {
this . skipped _effects . delete ( effect ) ;
for ( var e of tracked . d ) {
set _signal _status ( e , DIRTY ) ;
schedule _effect ( e ) ;
}
for ( var e of tracked . m ) {
set _signal _status ( e , MAYBE _DIRTY ) ;
schedule _effect ( e ) ;
}
}
}
/ * *
*
* @ param { Effect [ ] } root _effects
@ -172,8 +206,8 @@ export class Batch {
this . # defer _effects ( render _effects ) ;
this . # defer _effects ( effects ) ;
for ( const e of this . skipped _effects ) {
reset _branch ( e );
for ( const [ e , t ] of this . skipped _effects ) {
reset _branch ( e , t );
}
} else {
// append/remove branches
@ -887,20 +921,28 @@ export function eager(fn) {
/ * *
* Mark all the effects inside a skipped branch CLEAN , so that
* they can be correctly rescheduled later
* they can be correctly rescheduled later . Tracks dirty and maybe _dirty
* effects so they can be rescheduled if the branch survives .
* @ param { Effect } effect
* @ param { { d : Effect [ ] , m : Effect [ ] } } tracked
* /
function reset _branch ( effect ) {
function reset _branch ( effect , tracked ) {
// clean branch = nothing dirty inside, no need to traverse further
if ( ( effect . f & BRANCH _EFFECT ) !== 0 && ( effect . f & CLEAN ) !== 0 ) {
return ;
}
if ( ( effect . f & DIRTY ) !== 0 ) {
tracked . d . push ( effect ) ;
} else if ( ( effect . f & MAYBE _DIRTY ) !== 0 ) {
tracked . m . push ( effect ) ;
}
set _signal _status ( effect , CLEAN ) ;
var e = effect . first ;
while ( e !== null ) {
reset _branch ( e ) ;
reset _branch ( e , tracked );
e = e . next ;
}
}