@@ -457,6 +457,7 @@ const recomputeInvalidatedAtoms: RecomputeInvalidatedAtoms = (store) => {
457457 const mountedMap = buildingBlocks [ 1 ]
458458 const invalidatedAtoms = buildingBlocks [ 2 ]
459459 const changedAtoms = buildingBlocks [ 3 ]
460+ const storeHooks = buildingBlocks [ 6 ]
460461 const ensureAtomState = buildingBlocks [ 11 ]
461462 const readAtomState = buildingBlocks [ 14 ]
462463 const mountDependencies = buildingBlocks [ 17 ]
@@ -465,7 +466,11 @@ const recomputeInvalidatedAtoms: RecomputeInvalidatedAtoms = (store) => {
465466 // This is a topological sort via depth-first search, slightly modified from
466467 // what's described here for simplicity and performance reasons:
467468 // https://en.wikipedia.org/wiki/Topological_sorting#Depth-first_search
468- const topSortedReversed : [ atom : AnyAtom , atomState : AtomState ] [ ] = [ ]
469+ const topSortedReversed : [
470+ atom : AnyAtom ,
471+ atomState : AtomState ,
472+ epochNumber : EpochNumber ,
473+ ] [ ] = [ ]
469474 const visiting = new WeakSet < AnyAtom > ( )
470475 const visited = new WeakSet < AnyAtom > ( )
471476 // Visit the root atom. This is the only atom in the dependency graph
@@ -484,7 +489,7 @@ const recomputeInvalidatedAtoms: RecomputeInvalidatedAtoms = (store) => {
484489 // performance, we will simply push onto the end, and then will iterate in
485490 // reverse order later.
486491 if ( invalidatedAtoms . get ( a ) === aState . n ) {
487- topSortedReversed . push ( [ a , aState ] )
492+ topSortedReversed . push ( [ a , aState , aState . n ] )
488493 } else if (
489494 import . meta. env ?. MODE !== 'production' &&
490495 invalidatedAtoms . has ( a )
@@ -507,7 +512,7 @@ const recomputeInvalidatedAtoms: RecomputeInvalidatedAtoms = (store) => {
507512 // Step 2: use the topSortedReversed atom list to recompute all affected atoms
508513 // Track what's changed, so that we can short circuit when possible
509514 for ( let i = topSortedReversed . length - 1 ; i >= 0 ; -- i ) {
510- const [ a , aState ] = topSortedReversed [ i ] !
515+ const [ a , aState , prevEpochNumber ] = topSortedReversed [ i ] !
511516 let hasChangedDeps = false
512517 for ( const dep of aState . d . keys ( ) ) {
513518 if ( dep !== a && changedAtoms . has ( dep ) ) {
@@ -518,6 +523,10 @@ const recomputeInvalidatedAtoms: RecomputeInvalidatedAtoms = (store) => {
518523 if ( hasChangedDeps ) {
519524 readAtomState ( store , a )
520525 mountDependencies ( store , a )
526+ if ( prevEpochNumber !== aState . n ) {
527+ changedAtoms . add ( a )
528+ storeHooks . c ?.( a )
529+ }
521530 }
522531 invalidatedAtoms . delete ( a )
523532 }
0 commit comments