-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstores.ts
69 lines (59 loc) · 2.01 KB
/
stores.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
import { getHash } from './hash.ts'
import { InitStoreOptions, StoreApi, initStore } from './store.ts'
import { Maybe, getValue } from './utils.ts'
// ----------------------------------------
// Type definitions
export type StoreApiWithKey<
T extends Record<string, any>,
TKey extends Record<string, any>,
TProps extends Record<string, any> = Record<string, never>,
> = StoreApi<T> & TProps & { key: TKey; keyHash: string }
export type StoresApi<
T extends Record<string, any>,
TKey extends Record<string, any>,
TProps extends Record<string, any> = Record<string, never>,
> = {
stores: Map<string, StoreApiWithKey<T, TKey, TProps>>
getStore: (key?: Maybe<TKey>) => StoreApiWithKey<T, TKey, TProps>
}
export type StoresInitializer<
T extends Record<string, any>,
TKey extends Record<string, any>,
TProps extends Record<string, any> = Record<string, never>,
> = T | ((store: StoreApiWithKey<T, TKey, TProps>) => T)
export type InitStoresOptions<
T extends Record<string, any>,
TKey extends Record<string, any>,
> = InitStoreOptions<T> & {
hashKeyFn?: (obj: TKey) => string
}
// ----------------------------------------
// Source code
export const initStores = <
T extends Record<string, any>,
TKey extends Record<string, any>,
TProps extends Record<string, any> = Record<string, never>,
>(
initializer: StoresInitializer<T, TKey, TProps>,
options: InitStoresOptions<T, TKey> = {},
): StoresApi<T, TKey, TProps> => {
const { hashKeyFn = getHash } = options
const stores = new Map<string, StoreApiWithKey<T, TKey, TProps>>()
const getStore = (_key?: Maybe<TKey>) => {
const key = _key || ({} as TKey)
const keyHash = hashKeyFn(key)
if (!stores.has(keyHash)) {
const store = initStore<T, { key: TKey; keyHash: string } & TProps>((storeApi) => {
storeApi.key = key
storeApi.keyHash = keyHash
return getValue(initializer, storeApi)
}, options)
stores.set(keyHash, store)
}
return stores.get(keyHash)!
}
return {
stores,
getStore,
}
}