@@ -9,6 +9,8 @@ export function effect<T>(fn: () => T) {
99 state : ComputationState . STALE ,
1010 value : undefined ,
1111 compute ( ) {
12+ // In case the cleanup read an atom.
13+ // todo: test it
1214 CurrentComputation = undefined ! ;
1315 // `removeSources` is made by `runComputation`.
1416 unsubscribeEffect ( effectComputation ) ;
@@ -23,11 +25,12 @@ export function effect<T>(fn: () => T) {
2325
2426 // Remove sources and unsubscribe
2527 return ( ) => {
26- removeSources ( effectComputation ) ;
27- const currentComputation = CurrentComputation ;
28+ // In case the cleanup read an atom.
29+ // todo: test it
30+ const previousComputation = CurrentComputation ;
2831 CurrentComputation = undefined ! ;
2932 unsubscribeEffect ( effectComputation ) ;
30- CurrentComputation = currentComputation ! ;
33+ CurrentComputation = previousComputation ! ;
3134 } ;
3235}
3336export function derived < T > ( fn : ( ) => T ) : ( ) => T {
@@ -67,34 +70,27 @@ export function onWriteAtom(atom: Atom) {
6770 } ) ;
6871 batchProcessEffects ( ) ;
6972}
70- export function makeAtom ( ) : Atom {
71- const atom : Atom = {
72- value : undefined ,
73- observers : new Set ( ) ,
74- } ;
75- return atom ;
76- }
7773
74+ export function withoutReactivity < T extends ( ...args : any [ ] ) => any > ( fn : T ) : ReturnType < T > {
75+ return runWithComputation ( undefined ! , fn ) ;
76+ }
7877export function getCurrentComputation ( ) {
7978 return CurrentComputation ;
8079}
8180export function setComputation ( computation : Computation ) {
8281 CurrentComputation = computation ;
8382}
8483export function runWithComputation < T > ( computation : Computation , fn : ( ) => T ) : T {
85- const currentComputation = CurrentComputation ;
84+ const previousComputation = CurrentComputation ;
8685 CurrentComputation = computation ;
8786 let result : T ;
8887 try {
8988 result = fn ( ) ;
9089 } finally {
91- CurrentComputation = currentComputation ! ;
90+ CurrentComputation = previousComputation ! ;
9291 }
9392 return result ;
9493}
95- export function withoutReactivity < T extends ( ...args : any [ ] ) => any > ( fn : T ) : ReturnType < T > {
96- return runWithComputation ( undefined ! , fn ) ;
97- }
9894
9995function updateComputation ( computation : Computation ) {
10096 const state = computation . state ;
@@ -106,11 +102,11 @@ function updateComputation(computation: Computation) {
106102 // todo: test performance. We might want to avoid removing the atoms to
107103 // directly re-add them at compute. Especially as we are making them stale.
108104 removeSources ( computation ) ;
109- const executionContext = CurrentComputation ;
105+ const previousComputation = CurrentComputation ;
110106 CurrentComputation = computation ;
111107 computation . value = computation . compute ?.( ) ;
112108 computation . state = ComputationState . EXECUTED ;
113- CurrentComputation = executionContext ;
109+ CurrentComputation = previousComputation ;
114110}
115111
116112function removeSources ( computation : Computation ) {
@@ -149,24 +145,16 @@ function processEffects() {
149145}
150146
151147function unsubscribeEffect ( effectComputation : Computation ) {
148+ removeSources ( effectComputation ) ;
152149 cleanupEffect ( effectComputation ) ;
153- unsubscribeChildEffect ( effectComputation ) ;
154- }
155- /**
156- * Unsubscribe an execution context and all its children from all atoms
157- * they are subscribed to.
158- *
159- * @param parentEffect the context to unsubscribe
160- */
161- function unsubscribeChildEffect ( parentEffect : Computation ) {
162- for ( const children of parentEffect . childrenEffect ! ) {
163- cleanupEffect ( children ) ;
164- removeSources ( children ) ;
150+ for ( const children of effectComputation . childrenEffect ! ) {
165151 // Consider it executed to avoid it's re-execution
152+ // todo: make a test for it
166153 children . state = ComputationState . EXECUTED ;
167- unsubscribeChildEffect ( children ) ;
154+ removeSources ( children ) ;
155+ unsubscribeEffect ( children ) ;
168156 }
169- parentEffect . childrenEffect ! . length = 0 ;
157+ effectComputation . childrenEffect ! . length = 0 ;
170158}
171159function cleanupEffect ( computation : Computation ) {
172160 // the computation.value of an effect is a cleanup function
@@ -177,24 +165,6 @@ function cleanupEffect(computation: Computation) {
177165 }
178166}
179167
180- function computeSources ( derived : Derived < any , any > ) {
181- for ( const source of derived . sources ) {
182- if ( "sources" in source ) continue ;
183- computeDerived ( source as Derived < any , any > ) ;
184- }
185- }
186-
187- function computeDerived ( derived : Derived < any , any > ) {
188- if ( derived . state === ComputationState . EXECUTED ) {
189- onReadAtom ( derived ) ;
190- return derived . value ;
191- } else if ( derived . state === ComputationState . PENDING ) {
192- computeSources ( derived ) ;
193- }
194- onReadAtom ( derived ) ;
195- return derived . value ;
196- }
197-
198168function markDownstream < A , B > ( derived : Derived < A , B > ) {
199169 for ( const observer of derived . observers ) {
200170 // if the state has already been marked, skip it
@@ -204,6 +174,12 @@ function markDownstream<A, B>(derived: Derived<A, B>) {
204174 else Effects . push ( observer ) ;
205175 }
206176}
177+ function computeSources ( derived : Derived < any , any > ) {
178+ for ( const source of derived . sources ) {
179+ if ( "sources" in source ) continue ;
180+ updateComputation ( source as Derived < any , any > ) ;
181+ }
182+ }
207183
208184// For tests
209185
0 commit comments