atom.io 0.15.5 → 0.16.0
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/data/dist/index.cjs +20 -22
- package/data/dist/index.cjs.map +1 -1
- package/data/dist/index.d.ts +6 -6
- package/data/dist/index.js +21 -23
- package/data/dist/index.js.map +1 -1
- package/data/src/dict.ts +6 -7
- package/data/src/join.ts +23 -23
- package/data/src/struct-family.ts +2 -2
- package/data/src/struct.ts +4 -5
- package/dist/index.cjs +12 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +67 -60
- package/dist/index.js +13 -6
- package/dist/index.js.map +1 -1
- package/internal/dist/index.cjs +912 -886
- package/internal/dist/index.cjs.map +1 -1
- package/internal/dist/index.d.ts +157 -162
- package/internal/dist/index.js +487 -460
- package/internal/dist/index.js.map +1 -1
- package/internal/src/atom/create-regular-atom.ts +9 -12
- package/internal/src/atom/create-standalone-atom.ts +33 -0
- package/internal/src/atom/delete-atom.ts +5 -2
- package/internal/src/atom/index.ts +1 -16
- package/internal/src/atom/is-default.ts +0 -1
- package/internal/src/caching.ts +6 -3
- package/internal/src/families/create-atom-family.ts +11 -7
- package/internal/src/families/create-readonly-selector-family.ts +4 -3
- package/internal/src/families/create-regular-atom-family.ts +12 -27
- package/internal/src/families/create-selector-family.ts +13 -49
- package/internal/src/families/create-writable-selector-family.ts +51 -0
- package/internal/src/index.ts +44 -3
- package/internal/src/lineage.ts +0 -7
- package/internal/src/mutable/create-mutable-atom-family.ts +61 -15
- package/internal/src/mutable/create-mutable-atom.ts +70 -25
- package/internal/src/mutable/get-json-family.ts +4 -5
- package/internal/src/mutable/get-json-token.ts +6 -3
- package/internal/src/mutable/get-update-token.ts +3 -3
- package/internal/src/mutable/index.ts +1 -7
- package/internal/src/mutable/is-mutable.ts +6 -7
- package/internal/src/mutable/tracker-family.ts +4 -4
- package/internal/src/mutable/tracker.ts +6 -6
- package/internal/src/read-or-compute-value.ts +6 -3
- package/internal/src/selector/create-readonly-selector.ts +2 -3
- package/internal/src/selector/create-standalone-selector.ts +32 -0
- package/internal/src/selector/{create-read-write-selector.ts → create-writable-selector.ts} +12 -9
- package/internal/src/selector/delete-selector.ts +2 -2
- package/internal/src/selector/index.ts +3 -1
- package/internal/src/selector/trace-selector-atoms.ts +3 -2
- package/internal/src/selector/update-selector-atoms.ts +1 -1
- package/internal/src/set-state/copy-mutable-if-needed.ts +5 -6
- package/internal/src/set-state/copy-mutable-in-transaction.ts +4 -36
- package/internal/src/set-state/emit-update.ts +2 -3
- package/internal/src/set-state/evict-downstream.ts +1 -1
- package/internal/src/set-state/set-atom-or-selector.ts +3 -3
- package/internal/src/set-state/set-atom.ts +8 -4
- package/internal/src/set-state/stow-update.ts +1 -1
- package/internal/src/store/deposit.ts +25 -13
- package/internal/src/store/store.ts +21 -21
- package/internal/src/store/withdraw-new-family-member.ts +16 -9
- package/internal/src/store/withdraw.ts +43 -19
- package/internal/src/subscribe/recall-state.ts +2 -6
- package/internal/src/subscribe/subscribe-to-root-atoms.ts +39 -41
- package/internal/src/subscribe/subscribe-to-state.ts +3 -1
- package/internal/src/timeline/add-atom-to-timeline.ts +5 -5
- package/internal/src/timeline/create-timeline.ts +19 -22
- package/introspection/dist/index.cjs +4 -8
- package/introspection/dist/index.cjs.map +1 -1
- package/introspection/dist/index.d.ts +5 -5
- package/introspection/dist/index.js +5 -9
- package/introspection/dist/index.js.map +1 -1
- package/introspection/src/attach-atom-index.ts +4 -5
- package/introspection/src/attach-selector-index.ts +4 -5
- package/introspection/src/attach-timeline-index.ts +6 -3
- package/introspection/src/attach-transaction-index.ts +6 -3
- package/introspection/src/index.ts +9 -5
- package/json/dist/index.cjs +3 -4
- package/json/dist/index.cjs.map +1 -1
- package/json/dist/index.d.ts +4 -3
- package/json/dist/index.js +4 -5
- package/json/dist/index.js.map +1 -1
- package/json/src/select-json-family.ts +24 -4
- package/json/src/select-json.ts +3 -4
- package/package.json +2 -2
- package/react-devtools/dist/index.cjs.map +1 -1
- package/react-devtools/dist/index.d.ts +9 -9
- package/react-devtools/dist/index.js.map +1 -1
- package/react-devtools/src/StateIndex.tsx +18 -10
- package/react-devtools/src/TimelineIndex.tsx +6 -2
- package/react-devtools/src/TransactionIndex.tsx +2 -2
- package/realtime-client/dist/index.cjs +27 -13
- package/realtime-client/dist/index.cjs.map +1 -1
- package/realtime-client/dist/index.d.ts +6 -4
- package/realtime-client/dist/index.js +20 -7
- package/realtime-client/dist/index.js.map +1 -1
- package/realtime-client/src/index.ts +4 -3
- package/realtime-client/src/server-action.ts +2 -55
- package/realtime-client/src/sync-server-action.ts +75 -0
- package/realtime-react/dist/index.cjs +22 -13
- package/realtime-react/dist/index.cjs.map +1 -1
- package/realtime-react/dist/index.d.ts +3 -1
- package/realtime-react/dist/index.js +20 -12
- package/realtime-react/dist/index.js.map +1 -1
- package/realtime-react/src/index.ts +1 -0
- package/realtime-react/src/use-server-action.ts +2 -4
- package/realtime-react/src/use-sync-server-action.ts +19 -0
- package/realtime-server/dist/index.cjs +83 -81
- package/realtime-server/dist/index.cjs.map +1 -1
- package/realtime-server/dist/index.d.ts +8 -8
- package/realtime-server/dist/index.js +58 -56
- package/realtime-server/dist/index.js.map +1 -1
- package/realtime-server/src/index.ts +15 -1
- package/realtime-server/src/{hook-composition/receive-transaction.ts → realtime-action-receiver.ts} +6 -2
- package/realtime-server/src/{hook-composition/sync-transaction.ts → realtime-action-synchronizer.ts} +10 -43
- package/realtime-server/src/{hook-composition/expose-family.ts → realtime-family-provider.ts} +9 -23
- package/realtime-server/src/{hook-composition/expose-mutable-family.ts → realtime-mutable-family-provider.ts} +4 -4
- package/realtime-server/src/{hook-composition/expose-mutable.ts → realtime-mutable-provider.ts} +4 -5
- package/realtime-server/src/realtime-server-store.ts +39 -0
- package/realtime-server/src/{hook-composition/expose-single.ts → realtime-state-provider.ts} +7 -8
- package/realtime-server/src/{hook-composition/receive-state.ts → realtime-state-receiver.ts} +7 -4
- package/src/atom.ts +39 -24
- package/src/find-state.ts +20 -19
- package/src/index.ts +41 -28
- package/src/logger.ts +1 -0
- package/src/selector.ts +31 -16
- package/src/silo.ts +45 -6
- package/src/subscribe.ts +1 -0
- package/src/validators.ts +35 -25
- package/internal/src/atom/create-atom.ts +0 -21
- package/internal/src/mutable/get-update-family.ts +0 -23
- package/internal/src/selector/create-selector.ts +0 -65
- package/realtime-server/src/hook-composition/index.ts +0 -15
- /package/realtime-client/src/{pull.ts → pull-state.ts} +0 -0
- /package/realtime-client/src/{push.ts → push-state.ts} +0 -0
- /package/realtime-client/src/{realtime-state.ts → realtime-client-store.ts} +0 -0
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
AtomOptions,
|
|
3
|
-
AtomToken,
|
|
4
2
|
FamilyMetadata,
|
|
5
3
|
MutableAtomOptions,
|
|
4
|
+
RegularAtomOptions,
|
|
5
|
+
RegularAtomToken,
|
|
6
6
|
UpdateHandler,
|
|
7
7
|
} from "atom.io"
|
|
8
8
|
import { setState } from "atom.io"
|
|
9
9
|
|
|
10
|
-
import type {
|
|
10
|
+
import type { RegularAtom } from ".."
|
|
11
11
|
import { cacheValue } from "../caching"
|
|
12
12
|
import { newest } from "../lineage"
|
|
13
|
-
import { createMutableAtom } from "../mutable"
|
|
14
13
|
import type { Store } from "../store"
|
|
15
14
|
import { deposit } from "../store"
|
|
16
15
|
import { Subject } from "../subject"
|
|
@@ -18,10 +17,10 @@ import { subscribeToState } from "../subscribe"
|
|
|
18
17
|
import { markAtomAsDefault } from "./is-default"
|
|
19
18
|
|
|
20
19
|
export function createRegularAtom<T>(
|
|
21
|
-
options:
|
|
20
|
+
options: MutableAtomOptions<any, any> | RegularAtomOptions<T>,
|
|
22
21
|
family: FamilyMetadata | undefined,
|
|
23
22
|
store: Store,
|
|
24
|
-
):
|
|
23
|
+
): RegularAtomToken<T> {
|
|
25
24
|
store.logger.info(
|
|
26
25
|
`🔨`,
|
|
27
26
|
`atom`,
|
|
@@ -30,7 +29,7 @@ export function createRegularAtom<T>(
|
|
|
30
29
|
)
|
|
31
30
|
const target = newest(store)
|
|
32
31
|
const existing = target.atoms.get(options.key)
|
|
33
|
-
if (existing) {
|
|
32
|
+
if (existing && existing.type === `atom`) {
|
|
34
33
|
store.logger.error(
|
|
35
34
|
`❌`,
|
|
36
35
|
`atom`,
|
|
@@ -40,7 +39,7 @@ export function createRegularAtom<T>(
|
|
|
40
39
|
return deposit(existing)
|
|
41
40
|
}
|
|
42
41
|
const subject = new Subject<{ newValue: T; oldValue: T }>()
|
|
43
|
-
const newAtom:
|
|
42
|
+
const newAtom: RegularAtom<T> = {
|
|
44
43
|
...options,
|
|
45
44
|
type: `atom`,
|
|
46
45
|
install: (store: Store) => {
|
|
@@ -50,9 +49,7 @@ export function createRegularAtom<T>(
|
|
|
50
49
|
options.key,
|
|
51
50
|
`installing in store "${store.config.name}"`,
|
|
52
51
|
)
|
|
53
|
-
return
|
|
54
|
-
? createMutableAtom(options, family, store)
|
|
55
|
-
: createRegularAtom(options, family, store)
|
|
52
|
+
return createRegularAtom(options, family, store)
|
|
56
53
|
},
|
|
57
54
|
subject,
|
|
58
55
|
} as const
|
|
@@ -88,5 +85,5 @@ export function createRegularAtom<T>(
|
|
|
88
85
|
}
|
|
89
86
|
}
|
|
90
87
|
store.on.atomCreation.next(token)
|
|
91
|
-
return token
|
|
88
|
+
return token
|
|
92
89
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AtomToken,
|
|
3
|
+
MutableAtomOptions,
|
|
4
|
+
MutableAtomToken,
|
|
5
|
+
RegularAtomOptions,
|
|
6
|
+
RegularAtomToken,
|
|
7
|
+
} from "atom.io"
|
|
8
|
+
import type { Json } from "atom.io/json"
|
|
9
|
+
|
|
10
|
+
import type { Transceiver } from "../mutable"
|
|
11
|
+
import { createMutableAtom } from "../mutable"
|
|
12
|
+
import type { Store } from "../store"
|
|
13
|
+
import { createRegularAtom } from "./create-regular-atom"
|
|
14
|
+
|
|
15
|
+
export function createStandaloneAtom<T>(
|
|
16
|
+
options: RegularAtomOptions<T>,
|
|
17
|
+
store: Store,
|
|
18
|
+
): RegularAtomToken<T>
|
|
19
|
+
export function createStandaloneAtom<
|
|
20
|
+
T extends Transceiver<any>,
|
|
21
|
+
J extends Json.Serializable,
|
|
22
|
+
>(options: MutableAtomOptions<T, J>, store: Store): MutableAtomToken<T, J>
|
|
23
|
+
export function createStandaloneAtom<T>(
|
|
24
|
+
options: MutableAtomOptions<any, any> | RegularAtomOptions<T>,
|
|
25
|
+
store: Store,
|
|
26
|
+
): AtomToken<T> {
|
|
27
|
+
const isMutable = `mutable` in options
|
|
28
|
+
|
|
29
|
+
if (isMutable) {
|
|
30
|
+
return createMutableAtom(options, undefined, store)
|
|
31
|
+
}
|
|
32
|
+
return createRegularAtom(options, undefined, store)
|
|
33
|
+
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RegularAtomToken } from "atom.io"
|
|
2
2
|
|
|
3
3
|
import type { Store } from ".."
|
|
4
4
|
import { deleteSelector, newest } from ".."
|
|
5
5
|
|
|
6
|
-
export function deleteAtom(
|
|
6
|
+
export function deleteAtom(
|
|
7
|
+
atomToken: RegularAtomToken<unknown>,
|
|
8
|
+
store: Store,
|
|
9
|
+
): void {
|
|
7
10
|
const target = newest(store)
|
|
8
11
|
const { key } = atomToken
|
|
9
12
|
const atom = target.atoms.get(key)
|
|
@@ -1,19 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import type { Store } from "../store"
|
|
3
|
-
import type { Subject } from "../subject"
|
|
4
|
-
|
|
5
|
-
export * from "./create-atom"
|
|
1
|
+
export * from "./create-standalone-atom"
|
|
6
2
|
export * from "./create-regular-atom"
|
|
7
3
|
export * from "./delete-atom"
|
|
8
4
|
export * from "./is-default"
|
|
9
|
-
|
|
10
|
-
export type Atom<T> = {
|
|
11
|
-
key: string
|
|
12
|
-
type: `atom`
|
|
13
|
-
mutable?: boolean
|
|
14
|
-
family?: FamilyMetadata
|
|
15
|
-
install: (store: Store) => void
|
|
16
|
-
subject: Subject<{ newValue: T; oldValue: T }>
|
|
17
|
-
default: T | (() => T)
|
|
18
|
-
cleanup?: () => void
|
|
19
|
-
}
|
package/internal/src/caching.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { StateUpdate } from "atom.io"
|
|
2
|
+
import type { ReadableState } from "."
|
|
3
3
|
import { Future } from "./future"
|
|
4
4
|
import { copyMutableIfWithinTransaction } from "./set-state/copy-mutable-in-transaction"
|
|
5
5
|
import type { Store } from "./store"
|
|
@@ -49,7 +49,10 @@ export function cacheValue<T>(
|
|
|
49
49
|
return value
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
export const readCachedValue = <T>(
|
|
52
|
+
export const readCachedValue = <T>(
|
|
53
|
+
token: ReadableState<any>,
|
|
54
|
+
target: Store,
|
|
55
|
+
): T => {
|
|
53
56
|
let value = target.valueMap.get(token.key) as T
|
|
54
57
|
if (token.type === `atom`) {
|
|
55
58
|
value = copyMutableIfWithinTransaction(value, token, target)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
AtomFamily,
|
|
3
|
-
AtomFamilyOptions,
|
|
4
2
|
MutableAtomFamily,
|
|
5
3
|
MutableAtomFamilyOptions,
|
|
4
|
+
RegularAtomFamily,
|
|
5
|
+
RegularAtomFamilyOptions,
|
|
6
6
|
} from "atom.io"
|
|
7
7
|
import type { Json } from "atom.io/json"
|
|
8
8
|
|
|
@@ -19,14 +19,18 @@ export function createAtomFamily<
|
|
|
19
19
|
store: Store,
|
|
20
20
|
): MutableAtomFamily<T, J, K>
|
|
21
21
|
export function createAtomFamily<T, K extends Json.Serializable>(
|
|
22
|
-
options:
|
|
22
|
+
options: RegularAtomFamilyOptions<T, K>,
|
|
23
23
|
store: Store,
|
|
24
|
-
):
|
|
24
|
+
): RegularAtomFamily<T, K>
|
|
25
25
|
export function createAtomFamily<T, K extends Json.Serializable>(
|
|
26
|
-
options:
|
|
26
|
+
options:
|
|
27
|
+
| MutableAtomFamilyOptions<any, any, any>
|
|
28
|
+
| RegularAtomFamilyOptions<T, K>,
|
|
27
29
|
store: Store,
|
|
28
|
-
):
|
|
29
|
-
|
|
30
|
+
): MutableAtomFamily<any, any, any> | RegularAtomFamily<T, K> {
|
|
31
|
+
const isMutable = `mutable` in options
|
|
32
|
+
|
|
33
|
+
if (isMutable) {
|
|
30
34
|
return createMutableAtomFamily(options, store)
|
|
31
35
|
}
|
|
32
36
|
return createRegularAtomFamily<T, K>(options, store)
|
|
@@ -8,8 +8,9 @@ import type { Json } from "atom.io/json"
|
|
|
8
8
|
import { stringifyJson } from "atom.io/json"
|
|
9
9
|
|
|
10
10
|
import { newest } from "../lineage"
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
11
|
+
import { createReadonlySelector } from "../selector"
|
|
12
|
+
import type { Store } from "../store"
|
|
13
|
+
import { deposit } from "../store"
|
|
13
14
|
import { Subject } from "../subject"
|
|
14
15
|
|
|
15
16
|
export function createReadonlySelectorFamily<T, K extends Json.Serializable>(
|
|
@@ -27,7 +28,7 @@ export function createReadonlySelectorFamily<T, K extends Json.Serializable>(
|
|
|
27
28
|
if (existing) {
|
|
28
29
|
return deposit(existing)
|
|
29
30
|
}
|
|
30
|
-
return
|
|
31
|
+
return createReadonlySelector(
|
|
31
32
|
{
|
|
32
33
|
key: fullKey,
|
|
33
34
|
get: options.get(key),
|
|
@@ -1,37 +1,35 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
AtomFamily,
|
|
3
|
-
AtomFamilyOptions,
|
|
4
|
-
AtomOptions,
|
|
5
|
-
AtomToken,
|
|
6
2
|
FamilyMetadata,
|
|
7
|
-
|
|
3
|
+
RegularAtomFamily,
|
|
4
|
+
RegularAtomFamilyOptions,
|
|
5
|
+
RegularAtomOptions,
|
|
6
|
+
RegularAtomToken,
|
|
8
7
|
} from "atom.io"
|
|
9
8
|
import type { Json } from "atom.io/json"
|
|
10
9
|
import { stringifyJson } from "atom.io/json"
|
|
11
10
|
|
|
12
11
|
import { createRegularAtom } from "../atom"
|
|
13
12
|
import { newest } from "../lineage"
|
|
14
|
-
import { createMutableAtom } from "../mutable"
|
|
15
13
|
import { deposit, withdraw } from "../store"
|
|
16
14
|
import type { Store } from "../store"
|
|
17
15
|
import { Subject } from "../subject"
|
|
18
16
|
|
|
19
17
|
export function createRegularAtomFamily<T, K extends Json.Serializable>(
|
|
20
|
-
options:
|
|
18
|
+
options: RegularAtomFamilyOptions<T, K>,
|
|
21
19
|
store: Store,
|
|
22
|
-
):
|
|
23
|
-
const subject = new Subject<
|
|
24
|
-
const atomFamily = Object.assign(
|
|
25
|
-
(key: K):
|
|
20
|
+
): RegularAtomFamily<T, K> {
|
|
21
|
+
const subject = new Subject<RegularAtomToken<T>>()
|
|
22
|
+
const atomFamily: RegularAtomFamily<T, K> = Object.assign(
|
|
23
|
+
(key: K): RegularAtomToken<any> => {
|
|
26
24
|
const subKey = stringifyJson(key)
|
|
27
25
|
const family: FamilyMetadata = { key: options.key, subKey }
|
|
28
26
|
const fullKey = `${options.key}(${subKey})`
|
|
29
27
|
const existing = withdraw({ key: fullKey, type: `atom` }, store)
|
|
30
|
-
let token:
|
|
28
|
+
let token: RegularAtomToken<any>
|
|
31
29
|
if (existing) {
|
|
32
30
|
token = deposit(existing)
|
|
33
31
|
} else {
|
|
34
|
-
const individualOptions:
|
|
32
|
+
const individualOptions: RegularAtomOptions<any> = {
|
|
35
33
|
key: fullKey,
|
|
36
34
|
default:
|
|
37
35
|
options.default instanceof Function
|
|
@@ -41,17 +39,7 @@ export function createRegularAtomFamily<T, K extends Json.Serializable>(
|
|
|
41
39
|
if (options.effects) {
|
|
42
40
|
individualOptions.effects = options.effects(key)
|
|
43
41
|
}
|
|
44
|
-
|
|
45
|
-
const mutableOptions = {
|
|
46
|
-
...individualOptions,
|
|
47
|
-
mutable: true,
|
|
48
|
-
toJson: options.toJson,
|
|
49
|
-
fromJson: options.fromJson,
|
|
50
|
-
} as const
|
|
51
|
-
token = createMutableAtom(mutableOptions, family, store)
|
|
52
|
-
} else {
|
|
53
|
-
token = createRegularAtom<T>(individualOptions, family, store)
|
|
54
|
-
}
|
|
42
|
+
token = createRegularAtom(individualOptions, family, store)
|
|
55
43
|
subject.next(token)
|
|
56
44
|
}
|
|
57
45
|
return token
|
|
@@ -63,9 +51,6 @@ export function createRegularAtomFamily<T, K extends Json.Serializable>(
|
|
|
63
51
|
install: (store: Store) => createRegularAtomFamily(options, store),
|
|
64
52
|
} as const,
|
|
65
53
|
)
|
|
66
|
-
if (`mutable` in options && typeof options.mutable === `boolean`) {
|
|
67
|
-
Object.assign(atomFamily, { mutable: options.mutable })
|
|
68
|
-
}
|
|
69
54
|
const target = newest(store)
|
|
70
55
|
target.families.set(options.key, atomFamily)
|
|
71
56
|
return atomFamily
|
|
@@ -1,69 +1,33 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
FamilyMetadata,
|
|
3
2
|
ReadonlySelectorFamily,
|
|
4
3
|
ReadonlySelectorFamilyOptions,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
SelectorToken,
|
|
4
|
+
WritableSelectorFamily,
|
|
5
|
+
WritableSelectorFamilyOptions,
|
|
8
6
|
} from "atom.io"
|
|
9
7
|
import type { Json } from "atom.io/json"
|
|
10
|
-
import { stringifyJson } from "atom.io/json"
|
|
11
8
|
|
|
12
|
-
import { newest } from "../lineage"
|
|
13
|
-
import { createSelector } from "../selector"
|
|
14
9
|
import type { Store } from "../store"
|
|
15
|
-
import { deposit } from "../store"
|
|
16
|
-
import { Subject } from "../subject"
|
|
17
10
|
import { createReadonlySelectorFamily } from "./create-readonly-selector-family"
|
|
11
|
+
import { createWritableSelectorFamily } from "./create-writable-selector-family"
|
|
18
12
|
|
|
19
13
|
export function createSelectorFamily<T, K extends Json.Serializable>(
|
|
20
|
-
options:
|
|
14
|
+
options: WritableSelectorFamilyOptions<T, K>,
|
|
21
15
|
store: Store,
|
|
22
|
-
):
|
|
16
|
+
): WritableSelectorFamily<T, K>
|
|
23
17
|
export function createSelectorFamily<T, K extends Json.Serializable>(
|
|
24
18
|
options: ReadonlySelectorFamilyOptions<T, K>,
|
|
25
19
|
store: Store,
|
|
26
20
|
): ReadonlySelectorFamily<T, K>
|
|
27
21
|
export function createSelectorFamily<T, K extends Json.Serializable>(
|
|
28
|
-
options:
|
|
22
|
+
options:
|
|
23
|
+
| ReadonlySelectorFamilyOptions<T, K>
|
|
24
|
+
| WritableSelectorFamilyOptions<T, K>,
|
|
29
25
|
store: Store,
|
|
30
|
-
): ReadonlySelectorFamily<T, K> |
|
|
31
|
-
const
|
|
26
|
+
): ReadonlySelectorFamily<T, K> | WritableSelectorFamily<T, K> {
|
|
27
|
+
const isWritable = `set` in options
|
|
32
28
|
|
|
33
|
-
if (
|
|
34
|
-
return
|
|
29
|
+
if (isWritable) {
|
|
30
|
+
return createWritableSelectorFamily(options, store)
|
|
35
31
|
}
|
|
36
|
-
|
|
37
|
-
const subject = new Subject<SelectorToken<T>>()
|
|
38
|
-
|
|
39
|
-
const selectorFamily = Object.assign(
|
|
40
|
-
(key: K): SelectorToken<T> => {
|
|
41
|
-
const subKey = stringifyJson(key)
|
|
42
|
-
const family: FamilyMetadata = { key: options.key, subKey }
|
|
43
|
-
const fullKey = `${options.key}(${subKey})`
|
|
44
|
-
const existing = target.selectors.get(fullKey)
|
|
45
|
-
if (existing) {
|
|
46
|
-
return deposit(existing)
|
|
47
|
-
}
|
|
48
|
-
const token = createSelector<T>(
|
|
49
|
-
{
|
|
50
|
-
key: fullKey,
|
|
51
|
-
get: options.get(key),
|
|
52
|
-
set: options.set(key),
|
|
53
|
-
},
|
|
54
|
-
family,
|
|
55
|
-
store,
|
|
56
|
-
)
|
|
57
|
-
subject.next(token)
|
|
58
|
-
return token
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
key: options.key,
|
|
62
|
-
type: `selector_family`,
|
|
63
|
-
subject,
|
|
64
|
-
install: (store: Store) => createSelectorFamily(options, store),
|
|
65
|
-
} as const,
|
|
66
|
-
) as SelectorFamily<T, K>
|
|
67
|
-
target.families.set(options.key, selectorFamily)
|
|
68
|
-
return selectorFamily
|
|
32
|
+
return createReadonlySelectorFamily(options, store)
|
|
69
33
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
FamilyMetadata,
|
|
3
|
+
WritableSelectorFamily,
|
|
4
|
+
WritableSelectorFamilyOptions,
|
|
5
|
+
WritableSelectorToken,
|
|
6
|
+
} from "atom.io"
|
|
7
|
+
import type { Json } from "atom.io/json"
|
|
8
|
+
import { stringifyJson } from "atom.io/json"
|
|
9
|
+
|
|
10
|
+
import { createWritableSelector } from "../selector"
|
|
11
|
+
import type { Store } from "../store"
|
|
12
|
+
import { deposit } from "../store"
|
|
13
|
+
import { Subject } from "../subject"
|
|
14
|
+
|
|
15
|
+
export function createWritableSelectorFamily<T, K extends Json.Serializable>(
|
|
16
|
+
options: WritableSelectorFamilyOptions<T, K>,
|
|
17
|
+
store: Store,
|
|
18
|
+
): WritableSelectorFamily<T, K> {
|
|
19
|
+
const subject = new Subject<WritableSelectorToken<T>>()
|
|
20
|
+
|
|
21
|
+
const selectorFamily = Object.assign(
|
|
22
|
+
(key: K): WritableSelectorToken<T> => {
|
|
23
|
+
const subKey = stringifyJson(key)
|
|
24
|
+
const family: FamilyMetadata = { key: options.key, subKey }
|
|
25
|
+
const fullKey = `${options.key}(${subKey})`
|
|
26
|
+
const existing = store.selectors.get(fullKey)
|
|
27
|
+
if (existing) {
|
|
28
|
+
return deposit(existing)
|
|
29
|
+
}
|
|
30
|
+
const token = createWritableSelector(
|
|
31
|
+
{
|
|
32
|
+
key: fullKey,
|
|
33
|
+
get: options.get(key),
|
|
34
|
+
set: options.set(key),
|
|
35
|
+
},
|
|
36
|
+
family,
|
|
37
|
+
store,
|
|
38
|
+
)
|
|
39
|
+
subject.next(token)
|
|
40
|
+
return token
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
key: options.key,
|
|
44
|
+
type: `selector_family`,
|
|
45
|
+
subject,
|
|
46
|
+
install: (store: Store) => createWritableSelectorFamily(options, store),
|
|
47
|
+
} as const,
|
|
48
|
+
) as WritableSelectorFamily<T, K>
|
|
49
|
+
store.families.set(options.key, selectorFamily)
|
|
50
|
+
return selectorFamily
|
|
51
|
+
}
|
package/internal/src/index.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { FamilyMetadata } from "atom.io"
|
|
2
|
+
import type { Json, JsonInterface } from "atom.io/json"
|
|
3
|
+
|
|
4
|
+
import type { Transceiver } from "./mutable"
|
|
5
|
+
import type { Store } from "./store"
|
|
6
|
+
import type { Subject } from "./subject"
|
|
3
7
|
|
|
4
8
|
export * from "./atom"
|
|
5
9
|
export * from "./caching"
|
|
@@ -22,4 +26,41 @@ export * from "./subscribe"
|
|
|
22
26
|
export * from "./timeline"
|
|
23
27
|
export * from "./transaction"
|
|
24
28
|
|
|
25
|
-
export type
|
|
29
|
+
export type BaseStateData = {
|
|
30
|
+
key: string
|
|
31
|
+
family?: FamilyMetadata
|
|
32
|
+
install: (store: Store) => void
|
|
33
|
+
subject: Subject<{ newValue: any; oldValue: any }>
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type RegularAtom<T> = BaseStateData & {
|
|
37
|
+
type: `atom`
|
|
38
|
+
default: T | (() => T)
|
|
39
|
+
cleanup?: () => void
|
|
40
|
+
}
|
|
41
|
+
export type MutableAtom<
|
|
42
|
+
T extends Transceiver<any>,
|
|
43
|
+
J extends Json.Serializable,
|
|
44
|
+
> = BaseStateData &
|
|
45
|
+
JsonInterface<T, J> & {
|
|
46
|
+
type: `mutable_atom`
|
|
47
|
+
default: T | (() => T)
|
|
48
|
+
cleanup?: () => void
|
|
49
|
+
}
|
|
50
|
+
export type Atom<T> =
|
|
51
|
+
| RegularAtom<T>
|
|
52
|
+
| (T extends Transceiver<any> ? MutableAtom<T, any> : never)
|
|
53
|
+
|
|
54
|
+
export type WritableSelector<T> = BaseStateData & {
|
|
55
|
+
type: `selector`
|
|
56
|
+
get: () => T
|
|
57
|
+
set: (newValue: T | ((oldValue: T) => T)) => void
|
|
58
|
+
}
|
|
59
|
+
export type ReadonlySelector<T> = BaseStateData & {
|
|
60
|
+
type: `readonly_selector`
|
|
61
|
+
get: () => T
|
|
62
|
+
}
|
|
63
|
+
export type Selector<T> = ReadonlySelector<T> | WritableSelector<T>
|
|
64
|
+
|
|
65
|
+
export type WritableState<T> = Atom<T> | WritableSelector<T>
|
|
66
|
+
export type ReadableState<T> = Atom<T> | Selector<T>
|
package/internal/src/lineage.ts
CHANGED
|
@@ -1,25 +1,71 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
MutableAtomFamily,
|
|
3
|
+
MutableAtomFamilyOptions,
|
|
4
|
+
MutableAtomOptions,
|
|
5
|
+
MutableAtomToken,
|
|
6
|
+
} from "atom.io"
|
|
7
|
+
import type { FamilyMetadata } from "atom.io"
|
|
2
8
|
import type { Json } from "atom.io/json"
|
|
3
9
|
import { selectJsonFamily } from "atom.io/json"
|
|
10
|
+
import { stringifyJson } from "atom.io/json"
|
|
4
11
|
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
12
|
+
import { newest } from "../lineage"
|
|
13
|
+
import { createMutableAtom } from "../mutable"
|
|
14
|
+
import { deposit, withdraw } from "../store"
|
|
15
|
+
import type { Store } from "../store"
|
|
16
|
+
import { Subject } from "../subject"
|
|
7
17
|
import { FamilyTracker } from "./tracker-family"
|
|
8
18
|
import type { Transceiver } from "./transceiver"
|
|
9
19
|
|
|
10
20
|
export function createMutableAtomFamily<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
21
|
+
T extends Transceiver<any>,
|
|
22
|
+
J extends Json.Serializable,
|
|
23
|
+
K extends string,
|
|
14
24
|
>(
|
|
15
|
-
options: MutableAtomFamilyOptions<
|
|
25
|
+
options: MutableAtomFamilyOptions<T, J, K>,
|
|
16
26
|
store: Store,
|
|
17
|
-
): MutableAtomFamily<
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
): MutableAtomFamily<T, J, K> {
|
|
28
|
+
const subject = new Subject<MutableAtomToken<T, J>>()
|
|
29
|
+
const atomFamily: MutableAtomFamily<T, J, K> = Object.assign(
|
|
30
|
+
(key: K): MutableAtomToken<T, J> => {
|
|
31
|
+
const subKey = stringifyJson(key)
|
|
32
|
+
const family: FamilyMetadata = { key: options.key, subKey }
|
|
33
|
+
const fullKey = `${options.key}(${subKey})`
|
|
34
|
+
const existing = withdraw({ key: fullKey, type: `mutable_atom` }, store)
|
|
35
|
+
let token: MutableAtomToken<T, J>
|
|
36
|
+
if (existing) {
|
|
37
|
+
token = deposit(existing)
|
|
38
|
+
} else {
|
|
39
|
+
const individualOptions: MutableAtomOptions<T, J> = {
|
|
40
|
+
key: fullKey,
|
|
41
|
+
default: () => options.default(key),
|
|
42
|
+
toJson: options.toJson,
|
|
43
|
+
fromJson: options.fromJson,
|
|
44
|
+
mutable: true,
|
|
45
|
+
}
|
|
46
|
+
if (options.effects) {
|
|
47
|
+
individualOptions.effects = options.effects(key)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
token = createMutableAtom(individualOptions, family, store)
|
|
51
|
+
|
|
52
|
+
subject.next(token)
|
|
53
|
+
}
|
|
54
|
+
return token
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
key: options.key,
|
|
58
|
+
type: `mutable_atom_family`,
|
|
59
|
+
subject,
|
|
60
|
+
install: (store: Store) => createMutableAtomFamily(options, store),
|
|
61
|
+
toJson: options.toJson,
|
|
62
|
+
fromJson: options.fromJson,
|
|
63
|
+
} as const,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
const target = newest(store)
|
|
67
|
+
target.families.set(options.key, atomFamily)
|
|
68
|
+
selectJsonFamily(atomFamily, options, store)
|
|
69
|
+
new FamilyTracker(atomFamily, store)
|
|
70
|
+
return atomFamily
|
|
25
71
|
}
|