@ -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 _branches = 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 _branches map and reset its children
* @ param { Effect } effect
* /
skip _effect ( effect ) {
if ( ! this . # skipped _branches . has ( effect ) ) {
this . # skipped _branches . set ( effect , { d : [ ] , m : [ ] } ) ;
}
}
/ * *
* Remove an effect from the # skipped _branches map and reschedule
* any tracked dirty / maybe _dirty child effects
* @ param { Effect } effect
* /
unskip _effect ( effect ) {
var tracked = this . # skipped _branches . get ( effect ) ;
if ( tracked ) {
this . # skipped _branches . delete ( effect ) ;
for ( var e of tracked . d ) {
set _signal _status ( e , DIRTY ) ;
schedule _effect ( e ) ;
}
for ( 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 _ effect s) {
reset _branch ( e );
for ( const [ e , t ] of this . # skipped _ branch es) {
reset _branch ( e , t );
}
} else {
// append/remove branches
@ -220,7 +254,7 @@ export class Batch {
var is _branch = ( flags & ( BRANCH _EFFECT | ROOT _EFFECT ) ) !== 0 ;
var is _skippable _branch = is _branch && ( flags & CLEAN ) !== 0 ;
var skip = is _skippable _branch || ( flags & INERT ) !== 0 || this . skipped _ effect s. has ( effect ) ;
var skip = is _skippable _branch || ( flags & INERT ) !== 0 || this . # skipped _ branch es. has ( effect ) ;
// Inside a `<svelte:boundary>` with a pending snippet,
// all effects are deferred until the boundary resolves
@ -807,7 +841,8 @@ export function schedule_effect(signal) {
var flags = effect . f ;
// if the effect is being scheduled because a parent (each/await/etc) block
// updated an internal source, bail out or we'll cause a second flush
// updated an internal source, or because a branch is being unskipped,
// bail out or we'll cause a second flush
if (
is _flushing &&
effect === active _effect &&
@ -887,20 +922,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 ;
}
}