-
-
Notifications
You must be signed in to change notification settings - Fork 567
/
useHydrateAtoms.ts
58 lines (48 loc) 路 1.65 KB
/
useHydrateAtoms.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
import { useStore } from '../../react.ts'
import type { WritableAtom } from '../../vanilla.ts'
type Store = ReturnType<typeof useStore>
type Options = Parameters<typeof useStore>[0] & {
dangerouslyForceHydrate?: boolean
}
type AnyWritableAtom = WritableAtom<unknown, any[], any>
type InferAtomTuples<T> = {
[K in keyof T]: T[K] extends readonly [infer A, unknown]
? A extends WritableAtom<unknown, infer Args, any>
? readonly [A, Args[0]]
: T[K]
: never
}
// For internal use only
// This can be changed without notice.
export type INTERNAL_InferAtomTuples<T> = InferAtomTuples<T>
const hydratedMap: WeakMap<Store, WeakSet<AnyWritableAtom>> = new WeakMap()
export function useHydrateAtoms<
T extends (readonly [AnyWritableAtom, unknown])[],
>(values: InferAtomTuples<T>, options?: Options): void
export function useHydrateAtoms<T extends Map<AnyWritableAtom, unknown>>(
values: T,
options?: Options,
): void
export function useHydrateAtoms<
T extends Iterable<readonly [AnyWritableAtom, unknown]>,
>(values: InferAtomTuples<T>, options?: Options): void
export function useHydrateAtoms<
T extends Iterable<readonly [AnyWritableAtom, unknown]>,
>(values: T, options?: Options) {
const store = useStore(options)
const hydratedSet = getHydratedSet(store)
for (const [atom, value] of values) {
if (!hydratedSet.has(atom) || options?.dangerouslyForceHydrate) {
hydratedSet.add(atom)
store.set(atom, value)
}
}
}
const getHydratedSet = (store: Store) => {
let hydratedSet = hydratedMap.get(store)
if (!hydratedSet) {
hydratedSet = new WeakSet()
hydratedMap.set(store, hydratedSet)
}
return hydratedSet
}