@@ -173,11 +173,11 @@ type BatchPriority = 0 | 1 | 2
173173
174174type Batch = [
175175 /** high priority listeners */
176- priority0 : Set < ( ) => void > ,
176+ priority0 : Set < ( batch : Batch ) => void > ,
177177 /** atom listeners */
178- priority1 : Set < ( ) => void > ,
178+ priority1 : Set < ( batch : Batch ) => void > ,
179179 /** atom mount hooks */
180- priority2 : Set < ( ) => void > ,
180+ priority2 : Set < ( batch : Batch ) => void > ,
181181] & {
182182 /** changed Atoms */
183183 C : Set < AnyAtom >
@@ -189,7 +189,7 @@ const createBatch = (): Batch =>
189189const addBatchFunc = (
190190 batch : Batch ,
191191 priority : BatchPriority ,
192- fn : ( ) => void ,
192+ fn : ( batch : Batch ) => void ,
193193) => {
194194 batch [ priority ] . add ( fn )
195195}
@@ -203,21 +203,20 @@ const registerBatchAtom = (
203203 batch . C . add ( atom )
204204 atomState . u ?.( batch )
205205 const scheduleListeners = ( ) => {
206- atomState . m ?. l . forEach ( ( listener ) => addBatchFunc ( batch , 1 , listener ) )
206+ atomState . m ?. l . forEach ( ( listener ) =>
207+ addBatchFunc ( batch , 1 , ( ) => listener ( ) ) ,
208+ )
207209 }
208210 addBatchFunc ( batch , 1 , scheduleListeners )
209211 }
210212}
211213
212- const flushBatch = (
213- batch : Batch ,
214- recomputeDependents : ( batch : Batch ) => void ,
215- ) => {
214+ const flushBatch = ( batch : Batch ) => {
216215 let error : AnyError
217216 let hasError = false
218- const call = ( fn : ( ) => void ) => {
217+ const call = ( fn : ( batch : Batch ) => void ) => {
219218 try {
220- fn ( )
219+ fn ( batch )
221220 } catch ( e ) {
222221 if ( ! hasError ) {
223222 error = e
@@ -226,8 +225,6 @@ const flushBatch = (
226225 }
227226 }
228227 while ( batch . C . size || batch . some ( ( channel ) => channel . size ) ) {
229- recomputeDependents ( batch )
230- batch . C . clear ( )
231228 for ( const channel of batch ) {
232229 channel . forEach ( call )
233230 channel . clear ( )
@@ -380,7 +377,7 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
380377 const batch = createBatch ( )
381378 addDependency ( atom , atomState , a , aState )
382379 mountDependencies ( batch , atom , atomState )
383- recomputeAndFlushBatch ( batch )
380+ flushBatch ( batch )
384381 }
385382 }
386383 }
@@ -422,7 +419,7 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
422419 if ( atomState . m ) {
423420 const batch = createBatch ( )
424421 mountDependencies ( batch , atom , atomState )
425- recomputeAndFlushBatch ( batch )
422+ flushBatch ( batch )
426423 }
427424 }
428425 valueOrPromise . then ( complete , complete )
@@ -441,18 +438,23 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
441438 const readAtom = < Value > ( atom : Atom < Value > ) : Value =>
442439 returnAtomValue ( readAtomState ( undefined , atom ) )
443440
444- const getMountedDependents = < Value > (
441+ const getMountedOrBatchDependents = < Value > (
445442 atomState : AtomState < Value > ,
446443 ) : Map < AnyAtom , AtomState > => {
447- const mountedDependents = new Map < AnyAtom , AtomState > ( )
448- const dependents = new Set ( [ ...( atomState . m ?. t || [ ] ) , ...atomState . p ] )
449- for ( const a of dependents ) {
444+ const dependents = new Map < AnyAtom , AtomState > ( )
445+ for ( const a of atomState . m ?. t || [ ] ) {
450446 const aState = ensureAtomState ( a )
451447 if ( aState . m ) {
452- mountedDependents . set ( a , aState )
448+ dependents . set ( a , aState )
453449 }
454450 }
455- return mountedDependents
451+ for ( const atomWithPendingPromise of atomState . p ) {
452+ dependents . set (
453+ atomWithPendingPromise ,
454+ ensureAtomState ( atomWithPendingPromise ) ,
455+ )
456+ }
457+ return dependents
456458 }
457459
458460 const dirtyDependents = < Value > ( atomState : AtomState < Value > ) => {
@@ -465,7 +467,7 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
465467 continue
466468 }
467469 aState . x = true
468- for ( const [ , s ] of getMountedDependents ( aState ) ) {
470+ for ( const [ , s ] of getMountedOrBatchDependents ( aState ) ) {
469471 if ( ! dependents . has ( s ) ) {
470472 dependents . add ( s )
471473 stack . push ( s )
@@ -512,7 +514,7 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
512514 }
513515 visiting . add ( a )
514516 // Push unvisited dependents onto the stack
515- for ( const [ d , s ] of getMountedDependents ( aState ) ) {
517+ for ( const [ d , s ] of getMountedOrBatchDependents ( aState ) ) {
516518 if ( a !== d && ! visiting . has ( d ) ) {
517519 stack . push ( [ d , s ] )
518520 }
@@ -539,11 +541,9 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
539541 }
540542 delete aState . x
541543 }
544+ batch . C . clear ( )
542545 }
543546
544- const recomputeAndFlushBatch = ( batch : Batch ) =>
545- flushBatch ( batch , recomputeDependents )
546-
547547 const writeAtomState = < Value , Args extends unknown [ ] , Result > (
548548 batch : Batch ,
549549 atom : WritableAtom < Value , Args , Result > ,
@@ -569,6 +569,7 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
569569 mountDependencies ( batch , a , aState )
570570 if ( prevEpochNumber !== aState . n ) {
571571 dirtyDependents ( aState )
572+ addBatchFunc ( batch , 0 , recomputeDependents )
572573 registerBatchAtom ( batch , a , aState )
573574 }
574575 return undefined as R
@@ -577,7 +578,7 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
577578 }
578579 } finally {
579580 if ( ! isSync ) {
580- recomputeAndFlushBatch ( batch )
581+ flushBatch ( batch )
581582 }
582583 }
583584 }
@@ -596,7 +597,7 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
596597 try {
597598 return writeAtomState ( batch , atom , ...args )
598599 } finally {
599- recomputeAndFlushBatch ( batch )
600+ flushBatch ( batch )
600601 }
601602 }
602603
@@ -653,7 +654,7 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
653654 return writeAtomState ( batch , atom , ...args )
654655 } finally {
655656 if ( ! isSync ) {
656- recomputeAndFlushBatch ( batch )
657+ flushBatch ( batch )
657658 }
658659 }
659660 }
@@ -690,7 +691,7 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
690691 // unmount self
691692 const onUnmount = atomState . m . u
692693 if ( onUnmount ) {
693- addBatchFunc ( batch , 2 , ( ) => onUnmount ( batch ) )
694+ addBatchFunc ( batch , 2 , onUnmount )
694695 }
695696 delete atomState . m
696697 atomState . h ?.( batch )
@@ -710,12 +711,12 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
710711 const mounted = mountAtom ( batch , atom , atomState )
711712 const listeners = mounted . l
712713 listeners . add ( listener )
713- recomputeAndFlushBatch ( batch )
714+ flushBatch ( batch )
714715 return ( ) => {
715716 listeners . delete ( listener )
716717 const batch = createBatch ( )
717718 unmountAtom ( batch , atom , atomState )
718- recomputeAndFlushBatch ( batch )
719+ flushBatch ( batch )
719720 }
720721 }
721722
0 commit comments