@@ -25,7 +25,8 @@ import {
25
25
ROOT_EFFECT ,
26
26
LEGACY_DERIVED_PROP ,
27
27
DISCONNECTED ,
28
- BOUNDARY_EFFECT
28
+ BOUNDARY_EFFECT ,
29
+ REACTION_IS_UPDATING
29
30
} from './constants.js' ;
30
31
import { flush_tasks } from './dom/task.js' ;
31
32
import { add_owner } from './dev/ownership.js' ;
@@ -435,6 +436,7 @@ export function update_reaction(reaction) {
435
436
read_version ++ ;
436
437
437
438
try {
439
+ reaction . f |= REACTION_IS_UPDATING ;
438
440
var result = /** @type {Function } */ ( 0 , reaction . fn ) ( ) ;
439
441
var deps = reaction . deps ;
440
442
@@ -488,6 +490,7 @@ export function update_reaction(reaction) {
488
490
489
491
return result ;
490
492
} finally {
493
+ reaction . f ^= REACTION_IS_UPDATING ;
491
494
new_deps = previous_deps ;
492
495
skipped_deps = previous_skipped_deps ;
493
496
untracked_writes = previous_untracked_writes ;
@@ -776,7 +779,7 @@ export function schedule_effect(signal) {
776
779
var flags = effect . f ;
777
780
778
781
if ( ( flags & ( ROOT_EFFECT | BRANCH_EFFECT ) ) !== 0 ) {
779
- if ( ( flags & CLEAN ) === 0 ) return
782
+ if ( ( flags & CLEAN ) === 0 ) return ;
780
783
effect . f ^= CLEAN ;
781
784
}
782
785
}
@@ -938,18 +941,40 @@ export function get(signal) {
938
941
if ( derived_sources !== null && derived_sources . includes ( signal ) ) {
939
942
e . state_unsafe_local_read ( ) ;
940
943
}
944
+
941
945
var deps = active_reaction . deps ;
942
- if ( signal . rv < read_version ) {
943
- signal . rv = read_version ;
944
- // If the signal is accessing the same dependencies in the same
945
- // order as it did last time, increment `skipped_deps`
946
- // rather than updating `new_deps`, which creates GC cost
947
- if ( new_deps === null && deps !== null && deps [ skipped_deps ] === signal ) {
948
- skipped_deps ++ ;
949
- } else if ( new_deps === null ) {
950
- new_deps = [ signal ] ;
951
- } else {
952
- new_deps . push ( signal ) ;
946
+
947
+ if ( ( active_reaction . f & REACTION_IS_UPDATING ) !== 0 ) {
948
+ // we're in the effect init/update cycle
949
+ if ( signal . rv < read_version ) {
950
+ signal . rv = read_version ;
951
+
952
+ // If the signal is accessing the same dependencies in the same
953
+ // order as it did last time, increment `skipped_deps`
954
+ // rather than updating `new_deps`, which creates GC cost
955
+ if ( new_deps === null && deps !== null && deps [ skipped_deps ] === signal ) {
956
+ skipped_deps ++ ;
957
+ } else if ( new_deps === null ) {
958
+ new_deps = [ signal ] ;
959
+ } else {
960
+ new_deps . push ( signal ) ;
961
+ }
962
+ }
963
+ } else {
964
+ // we're adding a dependency outside the init/update cycle
965
+ // (i.e. after an `await`)
966
+ // TODO we probably want to disable this for user effects,
967
+ // otherwise it's a breaking change, albeit a desirable one?
968
+ if ( deps === null ) {
969
+ deps = [ signal ] ;
970
+ } else if ( ! deps . includes ( signal ) ) {
971
+ deps . push ( signal ) ;
972
+ }
973
+
974
+ if ( signal . reactions === null ) {
975
+ signal . reactions = [ active_reaction ] ;
976
+ } else if ( ! signal . reactions . includes ( active_reaction ) ) {
977
+ signal . reactions . push ( active_reaction ) ;
953
978
}
954
979
}
955
980
} else if ( is_derived && /** @type {Derived } */ ( signal ) . deps === null ) {
0 commit comments