Skip to content

Commit dd90c4d

Browse files
committed
refactor(vanilla): moved (un)mount guards into their respective functions. (suggestion)
1 parent 419ab5c commit dd90c4d

File tree

1 file changed

+29
-48
lines changed

1 file changed

+29
-48
lines changed

src/vanilla/store.ts

+29-48
Original file line numberDiff line numberDiff line change
@@ -473,26 +473,6 @@ export const createStore = () => {
473473
const readAtom = <Value>(atom: Atom<Value>): Value =>
474474
returnAtomValue(readAtomState(atom))
475475

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-
496476
const recomputeDependents = (atom: AnyAtom): void => {
497477
const getDependents = (a: AnyAtom): Dependents => {
498478
const dependents = new Set(mountedMap.get(a)?.t)
@@ -615,16 +595,19 @@ export const createStore = () => {
615595
initialDependent?: AnyAtom,
616596
onMountQueue?: (() => void)[],
617597
): Mounted => {
598+
const existingMount = mountedMap.get(atom)
599+
if (existingMount) {
600+
if (initialDependent) {
601+
existingMount.t.add(initialDependent)
602+
}
603+
return existingMount
604+
}
605+
618606
const queue = onMountQueue || []
619607
// mount dependencies before mounting self
620608
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)
628611
}
629612
})
630613
// recompute atom state
@@ -654,9 +637,17 @@ export const createStore = () => {
654637
return mounted
655638
}
656639

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+
}
658649
// unmount self
659-
const onUnmount = mountedMap.get(atom)?.u
650+
const onUnmount = mounted.u
660651
if (onUnmount) {
661652
onUnmount()
662653
}
@@ -673,12 +664,10 @@ export const createStore = () => {
673664
}
674665
atomState.d.forEach((_, a) => {
675666
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)
682671
}
683672
}
684673
})
@@ -707,20 +696,12 @@ export const createStore = () => {
707696
}
708697
})
709698
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)
719700
})
720701
maybeUnmountAtomSet.forEach((a) => {
721702
const mounted = mountedMap.get(a)
722-
if (mounted && canUnmountAtom(a, mounted)) {
723-
unmountAtom(a)
703+
if (mounted) {
704+
tryUnmountAtom(a, mounted)
724705
}
725706
})
726707
}
@@ -784,7 +765,7 @@ export const createStore = () => {
784765
}
785766

786767
const subscribeAtom = (atom: AnyAtom, listener: () => void) => {
787-
const mounted = addAtom(atom)
768+
const mounted = mountAtom(atom)
788769
const flushed = flushPending([atom])
789770
const listeners = mounted.l
790771
listeners.add(listener)
@@ -795,7 +776,7 @@ export const createStore = () => {
795776
}
796777
return () => {
797778
listeners.delete(listener)
798-
delAtom(atom)
779+
tryUnmountAtom(atom, mounted)
799780
if (import.meta.env?.MODE !== 'production') {
800781
// devtools uses this to detect if it _can_ unmount or not
801782
storeListenersRev2.forEach((l) => l({ type: 'unsub' }))

0 commit comments

Comments
 (0)