atom.io 0.6.2 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +27 -15
- package/dist/index.d.ts +27 -15
- package/dist/index.js +44 -24
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +44 -24
- package/dist/index.mjs.map +1 -1
- package/json/dist/index.d.mts +18 -0
- package/json/dist/index.d.ts +18 -0
- package/json/dist/index.js +51 -0
- package/json/dist/index.js.map +1 -0
- package/json/dist/index.mjs +15 -0
- package/json/dist/index.mjs.map +1 -0
- package/json/package.json +13 -13
- package/package.json +31 -12
- package/react/dist/index.d.mts +24 -0
- package/react/dist/index.d.ts +24 -0
- package/react/dist/index.js +87 -0
- package/react/dist/index.js.map +1 -0
- package/react/dist/index.mjs +45 -0
- package/react/dist/index.mjs.map +1 -0
- package/react/package.json +13 -13
- package/react-devtools/dist/index.css +26 -0
- package/react-devtools/dist/index.css.map +1 -0
- package/react-devtools/dist/index.d.mts +15 -0
- package/react-devtools/dist/index.d.ts +15 -0
- package/react-devtools/dist/index.js +2108 -0
- package/react-devtools/dist/index.js.map +1 -0
- package/react-devtools/dist/index.mjs +2080 -0
- package/react-devtools/dist/index.mjs.map +1 -0
- package/react-devtools/package.json +13 -13
- package/realtime/dist/index.d.mts +27 -0
- package/realtime/dist/index.d.ts +27 -0
- package/realtime/dist/index.js +191 -0
- package/realtime/dist/index.js.map +1 -0
- package/realtime/dist/index.mjs +152 -0
- package/realtime/dist/index.mjs.map +1 -0
- package/realtime/package.json +13 -13
- package/realtime-react/dist/index.d.mts +45 -0
- package/realtime-react/dist/index.d.ts +45 -0
- package/realtime-react/dist/index.js +217 -0
- package/realtime-react/dist/index.js.map +1 -0
- package/realtime-react/dist/index.mjs +172 -0
- package/realtime-react/dist/index.mjs.map +1 -0
- package/realtime-react/package.json +13 -13
- package/realtime-testing/dist/index.d.mts +49 -0
- package/realtime-testing/dist/index.d.ts +49 -0
- package/realtime-testing/dist/index.js +165 -0
- package/realtime-testing/dist/index.js.map +1 -0
- package/realtime-testing/dist/index.mjs +129 -0
- package/realtime-testing/dist/index.mjs.map +1 -0
- package/realtime-testing/package.json +15 -0
- package/src/atom.ts +16 -17
- package/src/index.ts +59 -59
- package/src/internal/atom-internal.ts +37 -37
- package/src/internal/families-internal.ts +115 -116
- package/src/internal/get.ts +83 -83
- package/src/internal/index.ts +1 -0
- package/src/internal/is-default.ts +17 -17
- package/src/internal/meta/attach-meta.ts +7 -7
- package/src/internal/meta/meta-state.ts +115 -115
- package/src/internal/operation.ts +93 -93
- package/src/internal/selector/create-read-write-selector.ts +47 -47
- package/src/internal/selector/create-readonly-selector.ts +38 -38
- package/src/internal/selector/lookup-selector-sources.ts +9 -9
- package/src/internal/selector/register-selector.ts +44 -44
- package/src/internal/selector/trace-selector-atoms.ts +30 -30
- package/src/internal/selector/update-selector-atoms.ts +25 -25
- package/src/internal/selector-internal.ts +38 -39
- package/src/internal/set.ts +78 -78
- package/src/internal/store.ts +119 -119
- package/src/internal/subject.ts +24 -0
- package/src/internal/subscribe-internal.ts +62 -62
- package/src/internal/time-travel-internal.ts +76 -76
- package/src/internal/timeline/add-atom-to-timeline.ts +158 -153
- package/src/internal/timeline-internal.ts +81 -82
- package/src/internal/transaction/abort-transaction.ts +8 -8
- package/src/internal/transaction/apply-transaction.ts +41 -41
- package/src/internal/transaction/build-transaction.ts +28 -28
- package/src/internal/transaction/index.ts +7 -7
- package/src/internal/transaction/redo-transaction.ts +13 -13
- package/src/internal/transaction/undo-transaction.ts +13 -13
- package/src/internal/transaction-internal.ts +49 -49
- package/src/json/select-json.ts +12 -12
- package/src/logger.ts +30 -30
- package/src/react/store-context.tsx +5 -6
- package/src/react/store-hooks.ts +19 -20
- package/src/react-devtools/AtomIODevtools.tsx +85 -85
- package/src/react-devtools/StateEditor.tsx +54 -55
- package/src/react-devtools/TokenList.tsx +49 -45
- package/src/react-explorer/AtomIOExplorer.tsx +198 -187
- package/src/react-explorer/explorer-effects.ts +11 -11
- package/src/react-explorer/explorer-states.ts +186 -193
- package/src/react-explorer/index.ts +11 -11
- package/src/react-explorer/space-states.ts +48 -50
- package/src/react-explorer/view-states.ts +25 -25
- package/src/realtime/hook-composition/expose-family.ts +81 -81
- package/src/realtime/hook-composition/expose-single.ts +26 -26
- package/src/realtime/hook-composition/expose-timeline.ts +60 -0
- package/src/realtime/hook-composition/index.ts +2 -2
- package/src/realtime/hook-composition/receive-state.ts +18 -18
- package/src/realtime/hook-composition/receive-transaction.ts +8 -8
- package/src/realtime-react/realtime-context.tsx +18 -19
- package/src/realtime-react/realtime-hooks.ts +17 -17
- package/src/realtime-react/realtime-state.ts +4 -4
- package/src/realtime-react/use-pull-family-member.ts +16 -17
- package/src/realtime-react/use-pull-family.ts +14 -15
- package/src/realtime-react/use-pull.ts +13 -14
- package/src/realtime-react/use-push.ts +16 -17
- package/src/realtime-react/use-server-action.ts +22 -23
- package/src/realtime-testing/index.ts +1 -0
- package/src/realtime-testing/setup-realtime-test.tsx +159 -0
- package/src/selector.ts +26 -27
- package/src/silo.ts +38 -38
- package/src/subscribe.ts +68 -68
- package/src/timeline.ts +13 -13
- package/src/transaction.ts +28 -28
- package/src/web-effects/storage.ts +17 -17
package/src/atom.ts
CHANGED
|
@@ -1,43 +1,42 @@
|
|
|
1
|
-
import type * as Rx from "rxjs"
|
|
2
|
-
|
|
3
1
|
import type { Serializable } from "~/packages/anvl/src/json"
|
|
4
2
|
|
|
5
3
|
import type { AtomToken } from "."
|
|
4
|
+
import type { Subject } from "./internal"
|
|
6
5
|
import { atomFamily__INTERNAL, atom__INTERNAL } from "./internal"
|
|
7
6
|
|
|
8
7
|
export type Effectors<T> = {
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
setSelf: <V extends T>(next: V | ((oldValue: T) => V)) => void
|
|
9
|
+
onSet: (callback: (options: { newValue: T; oldValue: T }) => void) => void
|
|
11
10
|
}
|
|
12
11
|
|
|
13
12
|
export type AtomEffect<T> = (tools: Effectors<T>) => void
|
|
14
13
|
|
|
15
14
|
export type AtomOptions<T> = {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
key: string
|
|
16
|
+
default: T | (() => T)
|
|
17
|
+
effects?: AtomEffect<T>[]
|
|
19
18
|
}
|
|
20
19
|
|
|
21
20
|
export function atom<T>(options: AtomOptions<T>): AtomToken<T> {
|
|
22
|
-
|
|
21
|
+
return atom__INTERNAL<T>(options)
|
|
23
22
|
}
|
|
24
23
|
|
|
25
24
|
export type AtomFamilyOptions<T, K extends Serializable> = {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
key: string
|
|
26
|
+
default: T | ((key: K) => T)
|
|
27
|
+
effects?: (key: K) => AtomEffect<T>[]
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
export type AtomFamily<T, K extends Serializable = Serializable> = ((
|
|
32
|
-
|
|
31
|
+
key: K,
|
|
33
32
|
) => AtomToken<T>) & {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
key: string
|
|
34
|
+
type: `atom_family`
|
|
35
|
+
subject: Subject<AtomToken<T>>
|
|
37
36
|
}
|
|
38
37
|
|
|
39
38
|
export function atomFamily<T, K extends Serializable>(
|
|
40
|
-
|
|
39
|
+
options: AtomFamilyOptions<T, K>,
|
|
41
40
|
): AtomFamily<T, K> {
|
|
42
|
-
|
|
41
|
+
return atomFamily__INTERNAL<T, K>(options)
|
|
43
42
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { capitalize } from "~/packages/anvl/src/string/capitalize"
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
IMPLICIT,
|
|
5
|
+
closeOperation,
|
|
6
|
+
openOperation,
|
|
7
|
+
getState__INTERNAL,
|
|
8
|
+
setState__INTERNAL,
|
|
9
|
+
isAtomDefault,
|
|
10
|
+
isSelectorDefault,
|
|
11
|
+
withdraw,
|
|
12
12
|
} from "./internal"
|
|
13
13
|
import * as __INTERNAL__ from "./internal"
|
|
14
14
|
import type { Store } from "./internal/store"
|
|
@@ -25,75 +25,75 @@ export type { Store } from "./internal/store"
|
|
|
25
25
|
export type { Serializable } from "~/packages/anvl/src/json"
|
|
26
26
|
|
|
27
27
|
export type AtomToken<_> = {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
key: string
|
|
29
|
+
type: `atom`
|
|
30
|
+
family?: FamilyMetadata
|
|
31
|
+
__brand?: _
|
|
32
32
|
}
|
|
33
33
|
export type SelectorToken<_> = {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
key: string
|
|
35
|
+
type: `selector`
|
|
36
|
+
family?: FamilyMetadata
|
|
37
|
+
__brand?: _
|
|
38
38
|
}
|
|
39
39
|
export type StateToken<T> = AtomToken<T> | SelectorToken<T>
|
|
40
40
|
|
|
41
41
|
export type ReadonlySelectorToken<_> = {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
key: string
|
|
43
|
+
type: `readonly_selector`
|
|
44
|
+
family?: FamilyMetadata
|
|
45
|
+
__brand?: _
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
export type FamilyMetadata = {
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
key: string
|
|
50
|
+
subKey: string
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
export const getState = <T>(
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
token: ReadonlySelectorToken<T> | StateToken<T>,
|
|
55
|
+
store: Store = IMPLICIT.STORE,
|
|
56
56
|
): T => {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
57
|
+
const state = withdraw<T>(token, store)
|
|
58
|
+
if (state === null) {
|
|
59
|
+
throw new Error(
|
|
60
|
+
`${capitalize(token.type)} "${token.key}" not found in store "${
|
|
61
|
+
store.config.name
|
|
62
|
+
}".`,
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
return getState__INTERNAL(state, store)
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
export const setState = <T, New extends T>(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
token: StateToken<T>,
|
|
70
|
+
value: New | ((oldValue: T) => New),
|
|
71
|
+
store: Store = IMPLICIT.STORE,
|
|
72
72
|
): void => {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
73
|
+
try {
|
|
74
|
+
openOperation(token, store)
|
|
75
|
+
} catch (thrown) {
|
|
76
|
+
if (!(typeof thrown === `symbol`)) {
|
|
77
|
+
throw thrown
|
|
78
|
+
}
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
const state = withdraw(token, store)
|
|
82
|
+
if (state === null) {
|
|
83
|
+
throw new Error(
|
|
84
|
+
`${capitalize(token.type)} "${token.key}" not found in store "${
|
|
85
|
+
store.config.name
|
|
86
|
+
}".`,
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
setState__INTERNAL(state, value, store)
|
|
90
|
+
closeOperation(store)
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
export const isDefault = (
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
token: ReadonlySelectorToken<unknown> | StateToken<unknown>,
|
|
95
|
+
store: Store = IMPLICIT.STORE,
|
|
96
96
|
): boolean =>
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
token.type === `atom`
|
|
98
|
+
? isAtomDefault(token.key, store)
|
|
99
|
+
: isSelectorDefault(token.key, store)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import HAMT from "hamt_plus"
|
|
2
|
-
import * as Rx from "rxjs"
|
|
3
2
|
|
|
3
|
+
import { Subject } from "."
|
|
4
4
|
import { deposit } from "./get"
|
|
5
5
|
import { markAtomAsDefault } from "./is-default"
|
|
6
6
|
import { cacheValue, hasKeyBeenUsed } from "./operation"
|
|
@@ -12,44 +12,44 @@ import { setState, subscribe } from ".."
|
|
|
12
12
|
import type { AtomOptions } from "../atom"
|
|
13
13
|
|
|
14
14
|
export type Atom<T> = {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
key: string
|
|
16
|
+
type: `atom`
|
|
17
|
+
family?: FamilyMetadata
|
|
18
|
+
subject: Subject<{ newValue: T; oldValue: T }>
|
|
19
|
+
default: T
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export function atom__INTERNAL<T>(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
options: AtomOptions<T>,
|
|
24
|
+
family?: FamilyMetadata,
|
|
25
|
+
store: Store = IMPLICIT.STORE,
|
|
26
26
|
): AtomToken<T> {
|
|
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
|
-
|
|
27
|
+
const core = target(store)
|
|
28
|
+
if (hasKeyBeenUsed(options.key, store)) {
|
|
29
|
+
store.config.logger?.error?.(
|
|
30
|
+
`Key "${options.key}" already exists in the store.`,
|
|
31
|
+
)
|
|
32
|
+
return deposit(core.atoms.get(options.key))
|
|
33
|
+
}
|
|
34
|
+
const subject = new Subject<{ newValue: T; oldValue: T }>()
|
|
35
|
+
const newAtom = {
|
|
36
|
+
...options,
|
|
37
|
+
subject,
|
|
38
|
+
type: `atom`,
|
|
39
|
+
...(family && { family }),
|
|
40
|
+
} as const
|
|
41
|
+
const initialValue =
|
|
42
|
+
options.default instanceof Function ? options.default() : options.default
|
|
43
|
+
core.atoms = HAMT.set(newAtom.key, newAtom, core.atoms)
|
|
44
|
+
markAtomAsDefault(options.key, store)
|
|
45
|
+
cacheValue(options.key, initialValue, store)
|
|
46
|
+
const token = deposit(newAtom)
|
|
47
|
+
options.effects?.forEach((effect) =>
|
|
48
|
+
effect({
|
|
49
|
+
setSelf: (next) => setState(token, next, store),
|
|
50
|
+
onSet: (handle: UpdateHandler<T>) => subscribe(token, handle, store),
|
|
51
|
+
}),
|
|
52
|
+
)
|
|
53
|
+
store.subject.atomCreation.next(token)
|
|
54
|
+
return token as AtomToken<T>
|
|
55
55
|
}
|
|
@@ -1,142 +1,141 @@
|
|
|
1
|
-
import * as Rx from "rxjs"
|
|
2
|
-
|
|
3
1
|
import type { Serializable } from "~/packages/anvl/src/json"
|
|
4
2
|
import { stringifyJson } from "~/packages/anvl/src/json"
|
|
5
3
|
|
|
6
4
|
import type { Store } from "."
|
|
7
5
|
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
Subject,
|
|
7
|
+
atom__INTERNAL,
|
|
8
|
+
withdraw,
|
|
9
|
+
selector__INTERNAL,
|
|
10
|
+
target,
|
|
11
|
+
deposit,
|
|
12
|
+
IMPLICIT,
|
|
14
13
|
} from "."
|
|
15
14
|
import type {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
15
|
+
AtomFamily,
|
|
16
|
+
AtomFamilyOptions,
|
|
17
|
+
AtomToken,
|
|
18
|
+
FamilyMetadata,
|
|
19
|
+
ReadonlySelectorFamily,
|
|
20
|
+
ReadonlySelectorFamilyOptions,
|
|
21
|
+
ReadonlySelectorToken,
|
|
22
|
+
SelectorFamily,
|
|
23
|
+
SelectorFamilyOptions,
|
|
24
|
+
SelectorToken,
|
|
26
25
|
} from ".."
|
|
27
26
|
|
|
28
27
|
export function atomFamily__INTERNAL<T, K extends Serializable>(
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
options: AtomFamilyOptions<T, K>,
|
|
29
|
+
store: Store = IMPLICIT.STORE,
|
|
31
30
|
): AtomFamily<T, K> {
|
|
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
|
-
|
|
31
|
+
const subject = new Subject<AtomToken<T>>()
|
|
32
|
+
return Object.assign(
|
|
33
|
+
(key: K): AtomToken<T> => {
|
|
34
|
+
const subKey = stringifyJson(key)
|
|
35
|
+
const family: FamilyMetadata = { key: options.key, subKey }
|
|
36
|
+
const fullKey = `${options.key}(${subKey})`
|
|
37
|
+
const existing = withdraw({ key: fullKey, type: `atom` }, store)
|
|
38
|
+
const token: AtomToken<any> = existing
|
|
39
|
+
? deposit(existing)
|
|
40
|
+
: atom__INTERNAL<T>(
|
|
41
|
+
{
|
|
42
|
+
key: fullKey,
|
|
43
|
+
default:
|
|
44
|
+
options.default instanceof Function
|
|
45
|
+
? options.default(key)
|
|
46
|
+
: options.default,
|
|
47
|
+
effects: options.effects?.(key),
|
|
48
|
+
},
|
|
49
|
+
family,
|
|
50
|
+
store,
|
|
51
|
+
)
|
|
52
|
+
subject.next(token)
|
|
53
|
+
return token
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
key: options.key,
|
|
57
|
+
type: `atom_family`,
|
|
58
|
+
subject,
|
|
59
|
+
} as const,
|
|
60
|
+
)
|
|
62
61
|
}
|
|
63
62
|
|
|
64
63
|
export function readonlySelectorFamily__INTERNAL<T, K extends Serializable>(
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
options: ReadonlySelectorFamilyOptions<T, K>,
|
|
65
|
+
store?: Store,
|
|
67
66
|
): ReadonlySelectorFamily<T, K> {
|
|
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
|
-
|
|
67
|
+
const core = target(store)
|
|
68
|
+
const subject = new Subject<ReadonlySelectorToken<T>>()
|
|
69
|
+
return Object.assign(
|
|
70
|
+
(key: K): ReadonlySelectorToken<T> => {
|
|
71
|
+
const subKey = stringifyJson(key)
|
|
72
|
+
const family: FamilyMetadata = { key: options.key, subKey }
|
|
73
|
+
const fullKey = `${options.key}(${subKey})`
|
|
74
|
+
const existing = core.readonlySelectors.get(fullKey)
|
|
75
|
+
if (existing) {
|
|
76
|
+
return deposit(existing)
|
|
77
|
+
}
|
|
78
|
+
return selector__INTERNAL<T>(
|
|
79
|
+
{
|
|
80
|
+
key: fullKey,
|
|
81
|
+
get: options.get(key),
|
|
82
|
+
},
|
|
83
|
+
family,
|
|
84
|
+
store,
|
|
85
|
+
) as ReadonlySelectorToken<T>
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
key: options.key,
|
|
89
|
+
type: `readonly_selector_family`,
|
|
90
|
+
subject,
|
|
91
|
+
} as const,
|
|
92
|
+
) as ReadonlySelectorFamily<T, K>
|
|
94
93
|
}
|
|
95
94
|
|
|
96
95
|
export function selectorFamily__INTERNAL<T, K extends Serializable>(
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
options: SelectorFamilyOptions<T, K>,
|
|
97
|
+
store?: Store,
|
|
99
98
|
): SelectorFamily<T, K>
|
|
100
99
|
export function selectorFamily__INTERNAL<T, K extends Serializable>(
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
options: ReadonlySelectorFamilyOptions<T, K>,
|
|
101
|
+
store?: Store,
|
|
103
102
|
): ReadonlySelectorFamily<T, K>
|
|
104
103
|
export function selectorFamily__INTERNAL<T, K extends Serializable>(
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
options: ReadonlySelectorFamilyOptions<T, K> | SelectorFamilyOptions<T, K>,
|
|
105
|
+
store: Store = IMPLICIT.STORE,
|
|
107
106
|
): ReadonlySelectorFamily<T, K> | SelectorFamily<T, K> {
|
|
108
|
-
|
|
107
|
+
const isReadonly = !(`set` in options)
|
|
109
108
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
109
|
+
if (isReadonly) {
|
|
110
|
+
return readonlySelectorFamily__INTERNAL(options, store)
|
|
111
|
+
}
|
|
112
|
+
const core = target(store)
|
|
113
|
+
const subject = new Subject<SelectorToken<T>>()
|
|
115
114
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
115
|
+
return Object.assign(
|
|
116
|
+
(key: K): SelectorToken<T> => {
|
|
117
|
+
const subKey = stringifyJson(key)
|
|
118
|
+
const family: FamilyMetadata = { key: options.key, subKey }
|
|
119
|
+
const fullKey = `${options.key}(${subKey})`
|
|
120
|
+
const existing = core.selectors.get(fullKey)
|
|
121
|
+
if (existing) {
|
|
122
|
+
return deposit(existing)
|
|
123
|
+
}
|
|
124
|
+
const token = selector__INTERNAL<T>(
|
|
125
|
+
{
|
|
126
|
+
key: fullKey,
|
|
127
|
+
get: options.get(key),
|
|
128
|
+
set: options.set(key),
|
|
129
|
+
},
|
|
130
|
+
family,
|
|
131
|
+
store,
|
|
132
|
+
)
|
|
133
|
+
subject.next(token)
|
|
134
|
+
return token
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
key: options.key,
|
|
138
|
+
type: `selector_family`,
|
|
139
|
+
} as const,
|
|
140
|
+
) as SelectorFamily<T, K>
|
|
142
141
|
}
|