@@ -209,7 +209,10 @@ const registerBatchAtom = (
209209 }
210210}
211211
212- const flushBatch = ( batch : Batch ) => {
212+ const flushBatch = (
213+ batch : Batch ,
214+ recomputeDependents : ( batch : Batch ) => void ,
215+ ) => {
213216 let error : AnyError
214217 let hasError = false
215218 const call = ( fn : ( ) => void ) => {
@@ -223,6 +226,7 @@ const flushBatch = (batch: Batch) => {
223226 }
224227 }
225228 while ( batch . C . size || batch . some ( ( channel ) => channel . size ) ) {
229+ recomputeDependents ( batch )
226230 batch . C . clear ( )
227231 for ( const channel of batch ) {
228232 channel . forEach ( call )
@@ -377,7 +381,7 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
377381 const batch = createBatch ( )
378382 addDependency ( atom , atomState , a , aState )
379383 mountDependencies ( batch , atom , atomState )
380- flushBatch ( batch )
384+ recomputeAndFlushBatch ( batch )
381385 }
382386 }
383387 }
@@ -419,7 +423,7 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
419423 if ( atomState . m ) {
420424 const batch = createBatch ( )
421425 mountDependencies ( batch , atom , atomState )
422- flushBatch ( batch )
426+ recomputeAndFlushBatch ( batch )
423427 }
424428 }
425429 valueOrPromise . then ( complete , complete )
@@ -458,24 +462,20 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
458462 return dependents
459463 }
460464
461- const dirtyDependents = < Value > (
462- batch : Batch ,
463- atom : Atom < Value > ,
464- atomState : AtomState < Value > ,
465- ) => {
466- const dependents = new Map < AnyAtom , AtomState > ( [ [ atom , atomState ] ] )
467- const stack : [ AnyAtom , AtomState ] [ ] = [ [ atom , atomState ] ]
465+ const dirtyDependents = < Value > ( atomState : AtomState < Value > ) => {
466+ const dependents = new Set < AtomState > ( [ atomState ] )
467+ const stack : AtomState [ ] = [ atomState ]
468468 while ( stack . length > 0 ) {
469- const [ a , aState ] = stack . pop ( ) !
469+ const aState = stack . pop ( ) !
470470 if ( aState . x ) {
471471 // already dirty
472472 continue
473473 }
474474 aState . x = true
475- for ( const [ d , s ] of getMountedOrBatchDependents ( batch , a , aState ) ) {
476- if ( ! dependents . has ( d ) ) {
477- dependents . set ( d , s )
478- stack . push ( [ d , s ] )
475+ for ( const [ , s ] of getMountedOrBatchDependents ( aState ) ) {
476+ if ( ! dependents . has ( s ) ) {
477+ dependents . add ( s )
478+ stack . push ( s )
479479 }
480480 }
481481 }
@@ -497,7 +497,7 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
497497 // Visit the root atom. This is the only atom in the dependency graph
498498 // without incoming edges, which is one reason we can simplify the algorithm
499499 const stack : [ a : AnyAtom , aState : AtomState ] [ ] = Array . from (
500- batch . D . keys ( ) ,
500+ batch . C ,
501501 ( atom ) => [ atom , ensureAtomState ( atom ) ] ,
502502 )
503503 while ( stack . length > 0 ) {
@@ -532,7 +532,7 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
532532 const [ a , aState , prevEpochNumber ] = topSortedReversed [ i ] !
533533 let hasChangedDeps = false
534534 for ( const dep of aState . d . keys ( ) ) {
535- if ( dep !== a && batch . D . has ( dep ) ) {
535+ if ( dep !== a && batch . C . has ( dep ) ) {
536536 hasChangedDeps = true
537537 break
538538 }
@@ -548,6 +548,9 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
548548 }
549549 }
550550
551+ const recomputeAndFlushBatch = ( batch : Batch ) =>
552+ flushBatch ( batch , recomputeDependents )
553+
551554 const writeAtomState = < Value , Args extends unknown [ ] , Result > (
552555 batch : Batch ,
553556 atom : WritableAtom < Value , Args , Result > ,
@@ -572,8 +575,7 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
572575 setAtomStateValueOrPromise ( a , aState , v )
573576 mountDependencies ( batch , a , aState )
574577 if ( prevEpochNumber !== aState . n ) {
575- dirtyDependents ( batch , a , aState )
576- batch . R = recomputeDependents
578+ dirtyDependents ( aState )
577579 registerBatchAtom ( batch , a , aState )
578580 }
579581 return undefined as R
@@ -582,7 +584,7 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
582584 }
583585 } finally {
584586 if ( ! isSync ) {
585- flushBatch ( batch )
587+ recomputeAndFlushBatch ( batch )
586588 }
587589 }
588590 }
@@ -601,7 +603,7 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
601603 try {
602604 return writeAtomState ( batch , atom , ...args )
603605 } finally {
604- flushBatch ( batch )
606+ recomputeAndFlushBatch ( batch )
605607 }
606608 }
607609
@@ -658,7 +660,7 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
658660 return writeAtomState ( batch , atom , ...args )
659661 } finally {
660662 if ( ! isSync ) {
661- flushBatch ( batch )
663+ recomputeAndFlushBatch ( batch )
662664 }
663665 }
664666 }
@@ -715,12 +717,12 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
715717 const mounted = mountAtom ( batch , atom , atomState )
716718 const listeners = mounted . l
717719 listeners . add ( listener )
718- flushBatch ( batch )
720+ recomputeAndFlushBatch ( batch )
719721 return ( ) => {
720722 listeners . delete ( listener )
721723 const batch = createBatch ( )
722724 unmountAtom ( batch , atom , atomState )
723- flushBatch ( batch )
725+ recomputeAndFlushBatch ( batch )
724726 }
725727 }
726728
0 commit comments