@@ -473,26 +473,6 @@ export const createStore = () => {
473
473
const readAtom = < Value > ( atom : Atom < Value > ) : Value =>
474
474
returnAtomValue ( readAtomState ( atom ) )
475
475
476
- const addAtom = ( atom : AnyAtom ) : Mounted => {
477
- let mounted = mountedMap . get ( atom )
478
- if ( ! mounted ) {
479
- mounted = mountAtom ( atom )
480
- }
481
- return mounted
482
- }
483
-
484
- // FIXME doesn't work with mutually dependent atoms
485
- const canUnmountAtom = ( atom : AnyAtom , mounted : Mounted ) =>
486
- ! mounted . l . size &&
487
- ( ! mounted . t . size || ( mounted . t . size === 1 && mounted . t . has ( atom ) ) )
488
-
489
- const delAtom = ( atom : AnyAtom ) : void => {
490
- const mounted = mountedMap . get ( atom )
491
- if ( mounted && canUnmountAtom ( atom , mounted ) ) {
492
- unmountAtom ( atom )
493
- }
494
- }
495
-
496
476
const recomputeDependents = ( atom : AnyAtom ) : void => {
497
477
const getDependents = ( a : AnyAtom ) : Dependents => {
498
478
const dependents = new Set ( mountedMap . get ( a ) ?. t )
@@ -615,16 +595,19 @@ export const createStore = () => {
615
595
initialDependent ?: AnyAtom ,
616
596
onMountQueue ?: ( ( ) => void ) [ ] ,
617
597
) : Mounted => {
598
+ const existingMount = mountedMap . get ( atom )
599
+ if ( existingMount ) {
600
+ if ( initialDependent ) {
601
+ existingMount . t . add ( initialDependent )
602
+ }
603
+ return existingMount
604
+ }
605
+
618
606
const queue = onMountQueue || [ ]
619
607
// mount dependencies before mounting self
620
608
getAtomState ( atom ) ?. d . forEach ( ( _ , a ) => {
621
- const aMounted = mountedMap . get ( a )
622
- if ( aMounted ) {
623
- aMounted . t . add ( atom ) // add dependent
624
- } else {
625
- if ( a !== atom ) {
626
- mountAtom ( a , atom , queue )
627
- }
609
+ if ( a !== atom ) {
610
+ mountAtom ( a , atom , queue )
628
611
}
629
612
} )
630
613
// recompute atom state
@@ -654,9 +637,17 @@ export const createStore = () => {
654
637
return mounted
655
638
}
656
639
657
- const unmountAtom = < Value > ( atom : Atom < Value > ) : void => {
640
+ // FIXME doesn't work with mutually dependent atoms
641
+ const canUnmountAtom = ( atom : AnyAtom , mounted : Mounted ) =>
642
+ ! mounted . l . size &&
643
+ ( ! mounted . t . size || ( mounted . t . size === 1 && mounted . t . has ( atom ) ) )
644
+
645
+ const tryUnmountAtom = < Value > ( atom : Atom < Value > , mounted : Mounted ) : void => {
646
+ if ( ! canUnmountAtom ( atom , mounted ) ) {
647
+ return
648
+ }
658
649
// unmount self
659
- const onUnmount = mountedMap . get ( atom ) ? .u
650
+ const onUnmount = mounted . u
660
651
if ( onUnmount ) {
661
652
onUnmount ( )
662
653
}
@@ -673,12 +664,10 @@ export const createStore = () => {
673
664
}
674
665
atomState . d . forEach ( ( _ , a ) => {
675
666
if ( a !== atom ) {
676
- const mounted = mountedMap . get ( a )
677
- if ( mounted ) {
678
- mounted . t . delete ( atom )
679
- if ( canUnmountAtom ( a , mounted ) ) {
680
- unmountAtom ( a )
681
- }
667
+ const mountedDep = mountedMap . get ( a )
668
+ if ( mountedDep ) {
669
+ mountedDep . t . delete ( atom )
670
+ tryUnmountAtom ( a , mountedDep )
682
671
}
683
672
}
684
673
} )
@@ -707,20 +696,12 @@ export const createStore = () => {
707
696
}
708
697
} )
709
698
depSet . forEach ( ( a ) => {
710
- const mounted = mountedMap . get ( a )
711
- if ( mounted ) {
712
- mounted . t . add ( atom ) // add to dependents
713
- } else if ( mountedMap . has ( atom ) ) {
714
- // we mount dependencies only when atom is already mounted
715
- // Note: we should revisit this when you find other issues
716
- // https://github.com/pmndrs/jotai/issues/942
717
- mountAtom ( a , atom )
718
- }
699
+ mountAtom ( a , atom )
719
700
} )
720
701
maybeUnmountAtomSet . forEach ( ( a ) => {
721
702
const mounted = mountedMap . get ( a )
722
- if ( mounted && canUnmountAtom ( a , mounted ) ) {
723
- unmountAtom ( a )
703
+ if ( mounted ) {
704
+ tryUnmountAtom ( a , mounted )
724
705
}
725
706
} )
726
707
}
@@ -784,7 +765,7 @@ export const createStore = () => {
784
765
}
785
766
786
767
const subscribeAtom = ( atom : AnyAtom , listener : ( ) => void ) => {
787
- const mounted = addAtom ( atom )
768
+ const mounted = mountAtom ( atom )
788
769
const flushed = flushPending ( [ atom ] )
789
770
const listeners = mounted . l
790
771
listeners . add ( listener )
@@ -795,7 +776,7 @@ export const createStore = () => {
795
776
}
796
777
return ( ) => {
797
778
listeners . delete ( listener )
798
- delAtom ( atom )
779
+ tryUnmountAtom ( atom , mounted )
799
780
if ( import . meta. env ?. MODE !== 'production' ) {
800
781
// devtools uses this to detect if it _can_ unmount or not
801
782
storeListenersRev2 . forEach ( ( l ) => l ( { type : 'unsub' } ) )
0 commit comments