deno.land / x / jotai@v1.8.4 / src / devtools / useAtomsSnapshot.ts

useAtomsSnapshot.ts
نووسراو ببینە
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import { useContext, useEffect, useState } from 'react'import { SECRET_INTERNAL_getScopeContext as getScopeContext } from 'jotai'import type { Atom } from '../core/atom'import { DEV_GET_ATOM_STATE, DEV_GET_MOUNTED, DEV_GET_MOUNTED_ATOMS, DEV_SUBSCRIBE_STATE,} from '../core/store'
type Scope = NonNullable<Parameters<typeof getScopeContext>[0]>type AnyAtomValue = unknowntype AnyAtom = Atom<AnyAtomValue>type AtomsValues = Map<AnyAtom, AnyAtomValue> // immutabletype AtomsDependents = Map<AnyAtom, Set<AnyAtom>> // immutabletype AtomsSnapshot = Readonly<{ values: AtomsValues dependents: AtomsDependents}>
const isEqualAtomsValues = (left: AtomsValues, right: AtomsValues) => left.size === right.size && Array.from(left).every(([left, v]) => Object.is(right.get(left), v))
const isEqualAtomsDependents = ( left: AtomsDependents, right: AtomsDependents) => left.size === right.size && Array.from(left).every(([a, dLeft]) => { const dRight = right.get(a) return ( dRight && dLeft.size === dRight.size && Array.from(dLeft).every((d) => dRight.has(d)) ) })
export function useAtomsSnapshot(scope?: Scope): AtomsSnapshot { const ScopeContext = getScopeContext(scope) const scopeContainer = useContext(ScopeContext) const store = scopeContainer.s
const [atomsSnapshot, setAtomsSnapshot] = useState<AtomsSnapshot>(() => ({ values: new Map(), dependents: new Map(), }))
useEffect(() => { if (!store[DEV_SUBSCRIBE_STATE]) return
let prevValues: AtomsValues = new Map() let prevDependents: AtomsDependents = new Map() const invalidatedAtoms = new Set<AnyAtom>() const callback = () => { const values: AtomsValues = new Map() const dependents: AtomsDependents = new Map() let hasNewInvalidatedAtoms = false for (const atom of store[DEV_GET_MOUNTED_ATOMS]() || []) { const atomState = store[DEV_GET_ATOM_STATE](atom) if (atomState) { if (!atomState.y) { if ('p' in atomState) { // ignore entirely if we have invalidated promise atoms return } if (!invalidatedAtoms.has(atom)) { invalidatedAtoms.add(atom) hasNewInvalidatedAtoms = true } } if ('v' in atomState) { values.set(atom, atomState.v) } } const mounted = store[DEV_GET_MOUNTED](atom) if (mounted) { dependents.set(atom, mounted.t) } } if (hasNewInvalidatedAtoms) { // ignore entirely if we have new invalidated atoms return } if ( isEqualAtomsValues(prevValues, values) && isEqualAtomsDependents(prevDependents, dependents) ) { // not changed return } prevValues = values prevDependents = dependents invalidatedAtoms.clear() setAtomsSnapshot({ values, dependents }) } const unsubscribe = store[DEV_SUBSCRIBE_STATE](callback) callback() return unsubscribe }, [store])
return atomsSnapshot}
jotai

Version Info

Tagged at
2 years ago