@@ -180,14 +180,17 @@ export function check_dirtiness(reaction) {
180
180
update_derived ( /** @type {import('#client').Derived } **/ ( dependency ) ) ;
181
181
}
182
182
183
- var version = dependency . version ;
183
+ if ( ( reaction . f & DIRTY ) !== 0 ) {
184
+ // `reaction` might now be dirty, as a result of calling `update_derived`
185
+ return true ;
186
+ }
184
187
185
188
if ( is_unowned ) {
186
189
// If we're working with an unowned derived signal, then we need to check
187
190
// if our dependency write version is higher. If it is then we can assume
188
191
// that state has changed to a newer version and thus this unowned signal
189
192
// is also dirty.
190
- if ( version > /** @type {import('#client').Derived } */ ( reaction ) . version ) {
193
+ if ( dependency . version > /** @type {import('#client').Derived } */ ( reaction ) . version ) {
191
194
return true ;
192
195
}
193
196
@@ -197,14 +200,11 @@ export function check_dirtiness(reaction) {
197
200
// if linked to the dependency source – otherwise future updates will not be caught.
198
201
( dependency . reactions ??= [ ] ) . push ( reaction ) ;
199
202
}
200
- } else if ( ( reaction . f & DIRTY ) !== 0 ) {
201
- // `signal` might now be dirty, as a result of calling `check_dirtiness` and/or `update_derived`
202
- return true ;
203
203
} else if ( is_disconnected ) {
204
204
// It might be that the derived was was dereferenced from its dependencies but has now come alive again.
205
205
// In thise case, we need to re-attach it to the graph and mark it dirty if any of its dependencies have
206
206
// changed since.
207
- if ( version > /** @type {import('#client').Derived } */ ( reaction ) . version ) {
207
+ if ( dependency . version > /** @type {import('#client').Derived } */ ( reaction ) . version ) {
208
208
is_dirty = true ;
209
209
}
210
210
@@ -292,49 +292,49 @@ function handle_error(error, effect, component_context) {
292
292
293
293
/**
294
294
* @template V
295
- * @param {import('#client').Reaction } signal
295
+ * @param {import('#client').Reaction } reaction
296
296
* @returns {V }
297
297
*/
298
- export function execute_reaction_fn ( signal ) {
299
- const previous_dependencies = current_dependencies ;
300
- const previous_dependencies_index = current_dependencies_index ;
301
- const previous_untracked_writes = current_untracked_writes ;
302
- const previous_reaction = current_reaction ;
303
- const previous_skip_reaction = current_skip_reaction ;
298
+ export function update_reaction ( reaction ) {
299
+ var previous_dependencies = current_dependencies ;
300
+ var previous_dependencies_index = current_dependencies_index ;
301
+ var previous_untracked_writes = current_untracked_writes ;
302
+ var previous_reaction = current_reaction ;
303
+ var previous_skip_reaction = current_skip_reaction ;
304
304
305
305
current_dependencies = /** @type {null | import('#client').Value[] } */ ( null ) ;
306
306
current_dependencies_index = 0 ;
307
307
current_untracked_writes = null ;
308
- current_reaction = ( signal . f & ( BRANCH_EFFECT | ROOT_EFFECT ) ) === 0 ? signal : null ;
309
- current_skip_reaction = ! is_flushing_effect && ( signal . f & UNOWNED ) !== 0 ;
308
+ current_reaction = ( reaction . f & ( BRANCH_EFFECT | ROOT_EFFECT ) ) === 0 ? reaction : null ;
309
+ current_skip_reaction = ! is_flushing_effect && ( reaction . f & UNOWNED ) !== 0 ;
310
310
311
311
try {
312
- let res = /** @type {Function } */ ( 0 , signal . fn ) ( ) ;
313
- let dependencies = /** @type {import('#client').Value<unknown>[] } **/ ( signal . deps ) ;
312
+ var result = /** @type {Function } */ ( 0 , reaction . fn ) ( ) ;
313
+ var dependencies = /** @type {import('#client').Value<unknown>[] } **/ ( reaction . deps ) ;
314
+
314
315
if ( current_dependencies !== null ) {
315
- let i ;
316
+ var dependency ;
317
+ var i ;
318
+
316
319
if ( dependencies !== null ) {
317
- const deps_length = dependencies . length ;
318
- // Include any dependencies up until the current_dependencies_index.
319
- const full_current_dependencies =
320
+ var deps_length = dependencies . length ;
321
+
322
+ /** All dependencies of the reaction, including those tracked on the previous run */
323
+ var array =
320
324
current_dependencies_index === 0
321
325
? current_dependencies
322
326
: dependencies . slice ( 0 , current_dependencies_index ) . concat ( current_dependencies ) ;
323
- const current_dep_length = full_current_dependencies . length ;
327
+
324
328
// If we have more than 16 elements in the array then use a Set for faster performance
325
329
// TODO: evaluate if we should always just use a Set or not here?
326
- const full_current_dependencies_set =
327
- current_dep_length > 16 && deps_length - current_dependencies_index > 1
328
- ? new Set ( full_current_dependencies )
329
- : null ;
330
+ var set =
331
+ array . length > 16 && deps_length - current_dependencies_index > 1 ? new Set ( array ) : null ;
332
+
330
333
for ( i = current_dependencies_index ; i < deps_length ; i ++ ) {
331
- const dependency = dependencies [ i ] ;
332
- if (
333
- full_current_dependencies_set !== null
334
- ? ! full_current_dependencies_set . has ( dependency )
335
- : ! full_current_dependencies . includes ( dependency )
336
- ) {
337
- remove_reaction ( signal , dependency ) ;
334
+ dependency = dependencies [ i ] ;
335
+
336
+ if ( set !== null ? ! set . has ( dependency ) : ! array . includes ( dependency ) ) {
337
+ remove_reaction ( reaction , dependency ) ;
338
338
}
339
339
}
340
340
}
@@ -345,28 +345,32 @@ export function execute_reaction_fn(signal) {
345
345
dependencies [ current_dependencies_index + i ] = current_dependencies [ i ] ;
346
346
}
347
347
} else {
348
- signal . deps = /** @type {import('#client').Value<V>[] } **/ (
348
+ reaction . deps = /** @type {import('#client').Value<V>[] } **/ (
349
349
dependencies = current_dependencies
350
350
) ;
351
351
}
352
352
353
353
if ( ! current_skip_reaction ) {
354
354
for ( i = current_dependencies_index ; i < dependencies . length ; i ++ ) {
355
- const dependency = dependencies [ i ] ;
356
- const reactions = dependency . reactions ;
355
+ dependency = dependencies [ i ] ;
356
+ var reactions = dependency . reactions ;
357
357
358
358
if ( reactions === null ) {
359
- dependency . reactions = [ signal ] ;
360
- } else if ( reactions [ reactions . length - 1 ] !== signal && ! reactions . includes ( signal ) ) {
361
- reactions . push ( signal ) ;
359
+ dependency . reactions = [ reaction ] ;
360
+ } else if (
361
+ reactions [ reactions . length - 1 ] !== reaction &&
362
+ ! reactions . includes ( reaction )
363
+ ) {
364
+ reactions . push ( reaction ) ;
362
365
}
363
366
}
364
367
}
365
368
} else if ( dependencies !== null && current_dependencies_index < dependencies . length ) {
366
- remove_reactions ( signal , current_dependencies_index ) ;
369
+ remove_reactions ( reaction , current_dependencies_index ) ;
367
370
dependencies . length = current_dependencies_index ;
368
371
}
369
- return res ;
372
+
373
+ return result ;
370
374
} finally {
371
375
current_dependencies = previous_dependencies ;
372
376
current_dependencies_index = previous_dependencies_index ;
@@ -456,7 +460,7 @@ export function destroy_effect_children(signal, remove_dom = false) {
456
460
* @param {import('#client').Effect } effect
457
461
* @returns {void }
458
462
*/
459
- export function execute_effect ( effect ) {
463
+ export function update_effect ( effect ) {
460
464
var flags = effect . f ;
461
465
462
466
if ( ( flags & DESTROYED ) !== 0 ) {
@@ -484,7 +488,7 @@ export function execute_effect(effect) {
484
488
}
485
489
486
490
execute_effect_teardown ( effect ) ;
487
- var teardown = execute_reaction_fn ( effect ) ;
491
+ var teardown = update_reaction ( effect ) ;
488
492
effect . teardown = typeof teardown === 'function' ? teardown : null ;
489
493
} catch ( error ) {
490
494
handle_error ( /** @type {Error } */ ( error ) , effect , current_component_context ) ;
@@ -552,12 +556,12 @@ function flush_queued_effects(effects) {
552
556
var effect = effects [ i ] ;
553
557
554
558
if ( ( effect . f & ( DESTROYED | INERT ) ) === 0 && check_dirtiness ( effect ) ) {
555
- execute_effect ( effect ) ;
559
+ update_effect ( effect ) ;
556
560
557
561
// Effects with no dependencies or teardown do not get added to the effect tree.
558
562
// Deferred effects (e.g. `$effect(...)`) _are_ added to the tree because we
559
563
// don't know if we need to keep them until they are executed. Doing the check
560
- // here (rather than in `execute_effect `) allows us to skip the work for
564
+ // here (rather than in `update_effect `) allows us to skip the work for
561
565
// immediate effects.
562
566
if ( effect . deps === null && effect . first === null && effect . nodes === null ) {
563
567
if ( effect . teardown === null ) {
@@ -643,7 +647,7 @@ function process_effects(effect, collected_effects) {
643
647
644
648
if ( ( flags & RENDER_EFFECT ) !== 0 ) {
645
649
if ( ! is_branch && check_dirtiness ( current_effect ) ) {
646
- execute_effect ( current_effect ) ;
650
+ update_effect ( current_effect ) ;
647
651
// Child might have been mutated since running the effect
648
652
child = current_effect . first ;
649
653
}
@@ -843,11 +847,11 @@ export function invalidate_inner_signals(fn) {
843
847
844
848
/**
845
849
* @param {import('#client').Value } signal
846
- * @param {number } to_status should be DIRTY or MAYBE_DIRTY
850
+ * @param {number } status should be DIRTY or MAYBE_DIRTY
847
851
* @param {boolean } force_schedule
848
852
* @returns {void }
849
853
*/
850
- export function mark_reactions ( signal , to_status , force_schedule ) {
854
+ export function mark_reactions ( signal , status , force_schedule ) {
851
855
var reactions = signal . reactions ;
852
856
if ( reactions === null ) return ;
853
857
@@ -870,16 +874,11 @@ export function mark_reactions(signal, to_status, force_schedule) {
870
874
continue ;
871
875
}
872
876
873
- set_signal_status ( reaction , to_status ) ;
874
-
875
- // If the signal is not clean, then skip over it – with the exception of unowned signals that
876
- // are already maybe dirty. Unowned signals might be dirty because they are not captured as part of an
877
- // effect.
878
- var maybe_dirty = ( flags & MAYBE_DIRTY ) !== 0 ;
879
- var unowned = ( flags & UNOWNED ) !== 0 ;
877
+ set_signal_status ( reaction , status ) ;
880
878
881
- if ( ( flags & CLEAN ) !== 0 || ( maybe_dirty && unowned ) ) {
882
- if ( ( reaction . f & DERIVED ) !== 0 ) {
879
+ // If the signal a) was previously clean or b) is an unowned derived, then mark it
880
+ if ( ( flags & ( CLEAN | UNOWNED ) ) !== 0 ) {
881
+ if ( ( flags & DERIVED ) !== 0 ) {
883
882
mark_reactions (
884
883
/** @type {import('#client').Derived } */ ( reaction ) ,
885
884
MAYBE_DIRTY ,
0 commit comments