@ -89,9 +89,16 @@ export function set_current_effect(effect) {
current _effect = effect ;
}
/** @type {null | import('#client').Value[]} */
export let current _dependencies = null ;
let current _dependencies _index = 0 ;
/ * *
* The dependencies of the reaction that is currently being executed . In many cases ,
* the dependencies are unchanged between runs , and so this will be ` null ` unless
* and until a new dependency is accessed — we track this via ` skipped_deps `
* @ type { null | import ( '#client' ) . Value [ ] }
* /
export let new _deps = null ;
let skipped _deps = 0 ;
/ * *
* Tracks writes that the effect it 's executed in doesn' t listen to yet ,
* so that the dependency can be added to the effect later on if it then reads it
@ -296,42 +303,37 @@ function handle_error(error, effect, component_context) {
* @ returns { V }
* /
export function update _reaction ( reaction ) {
var previous _dep endencies = current _dependencie s;
var previous _ dependencies_index = current _dependencies _index ;
var previous _dep s = new _dep s;
var previous _ skipped_deps = skipped _deps ;
var previous _untracked _writes = current _untracked _writes ;
var previous _reaction = current _reaction ;
var previous _skip _reaction = current _skip _reaction ;
current_dependencie s = /** @type {null | import('#client').Value[]} */ ( null ) ;
current_dependencies _index = 0 ;
new_dep s = /** @type {null | import('#client').Value[]} */ ( null ) ;
skipped_deps = 0 ;
current _untracked _writes = null ;
current _reaction = ( reaction . f & ( BRANCH _EFFECT | ROOT _EFFECT ) ) === 0 ? reaction : null ;
current _skip _reaction = ! is _flushing _effect && ( reaction . f & UNOWNED ) !== 0 ;
try {
var result = /** @type {Function} */ ( 0 , reaction . fn ) ( ) ;
var dep endencie s = /** @type {import('#client').Value<unknown>[]} **/ ( reaction . deps ) ;
var dep s = reaction . deps ;
if ( current_dependencie s !== null ) {
if ( new_dep s !== null ) {
var dependency ;
var i ;
if ( dependencies !== null ) {
var deps _length = dependencies . length ;
if ( deps !== null ) {
/** All dependencies of the reaction, including those tracked on the previous run */
var array =
current _dependencies _index === 0
? current _dependencies
: dependencies . slice ( 0 , current _dependencies _index ) . concat ( current _dependencies ) ;
var array = skipped _deps === 0 ? new _deps : deps . slice ( 0 , skipped _deps ) . concat ( new _deps ) ;
// If we have more than 16 elements in the array then use a Set for faster performance
// TODO: evaluate if we should always just use a Set or not here?
var set =
array . length > 16 && deps _length - current _dependencies _index > 1 ? new Set ( array ) : null ;
var set = array . length > 16 ? new Set ( array ) : null ;
for ( i = current _dependencies _index ; i < deps _length ; i ++ ) {
dependency = dependencies [ i ] ;
// Remove dependencies that should no longer be tracked
for ( i = skipped _deps ; i < deps . length ; i ++ ) {
dependency = deps [ i ] ;
if ( set !== null ? ! set . has ( dependency ) : ! array . includes ( dependency ) ) {
remove _reaction ( reaction , dependency ) ;
@ -339,20 +341,18 @@ export function update_reaction(reaction) {
}
}
if ( dep endencie s !== null && current_dependencies _index > 0 ) {
dep endencies. length = current _dependencies _index + current _dependencie s. length ;
for ( i = 0 ; i < current_dependencie s. length ; i ++ ) {
dep endencies[ current _dependencies _index + i ] = current _dependencie s[ i ] ;
if ( dep s !== null && skipped_deps > 0 ) {
dep s. length = skipped _deps + new _dep s. length ;
for ( i = 0 ; i < new_dep s. length ; i ++ ) {
dep s[ skipped _deps + i ] = new _dep s[ i ] ;
}
} else {
reaction . deps = /** @type {import('#client').Value<V>[]} **/ (
dependencies = current _dependencies
) ;
reaction . deps = deps = new _deps ;
}
if ( ! current _skip _reaction ) {
for ( i = current_dependencies _index ; i < dependencie s. length ; i ++ ) {
dependency = dep endencie s[ i ] ;
for ( i = skipped_deps ; i < dep s. length ; i ++ ) {
dependency = dep s[ i ] ;
var reactions = dependency . reactions ;
if ( reactions === null ) {
@ -365,15 +365,15 @@ export function update_reaction(reaction) {
}
}
}
} else if ( dep endencie s !== null && current_dependencies _index < dependencie s. length ) {
remove _reactions ( reaction , current_dependencies _index ) ;
dep endencies. length = current _dependencies _index ;
} else if ( dep s !== null && skipped_deps < dep s. length ) {
remove _reactions ( reaction , skipped_deps ) ;
dep s. length = skipped _deps ;
}
return result ;
} finally {
current_dependencies = previous _dependencie s;
current_dependencies _index = previous _dependencies _index ;
new_deps = previous _dep s;
skipped_deps = previous _skipped _deps ;
current _untracked _writes = previous _untracked _writes ;
current _reaction = previous _reaction ;
current _skip _reaction = previous _skip _reaction ;
@ -755,7 +755,8 @@ export async function tick() {
* @ returns { V }
* /
export function get ( signal ) {
const flags = signal . f ;
var flags = signal . f ;
if ( ( flags & DESTROYED ) !== 0 ) {
return signal . v ;
}
@ -766,26 +767,25 @@ export function get(signal) {
// Register the dependency on the current reaction signal.
if ( current _reaction !== null ) {
const unowned = ( current _reaction . f & UNOWNED ) !== 0 ;
const dependencies = current _reaction . deps ;
if (
current _dependencies === null &&
dependencies !== null &&
dependencies [ current _dependencies _index ] === signal &&
! ( unowned && current _effect !== null )
) {
current _dependencies _index ++ ;
} else if (
dependencies === null ||
current _dependencies _index === 0 ||
dependencies [ current _dependencies _index - 1 ] !== signal
) {
if ( current _dependencies === null ) {
current _dependencies = [ signal ] ;
} else if ( current _dependencies [ current _dependencies . length - 1 ] !== signal ) {
current _dependencies . push ( signal ) ;
var deps = current _reaction . deps ;
// If the signal is accessing the same dependencies in the same
// order as it did last time, increment `skipped_deps`
// rather than updating `new_deps`, which creates GC cost
if ( new _deps === null && deps !== null && deps [ skipped _deps ] === signal ) {
skipped _deps ++ ;
}
// Otherwise, create or push to `new_deps`, but only if this
// dependency wasn't the last one that was accessed
else if ( deps === null || skipped _deps === 0 || deps [ skipped _deps - 1 ] !== signal ) {
if ( new _deps === null ) {
new _deps = [ signal ] ;
} else if ( new _deps [ new _deps . length - 1 ] !== signal ) {
new _deps . push ( signal ) ;
}
}
if (
current _untracked _writes !== null &&
current _effect !== null &&