atom.io 0.17.0 → 0.18.1
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 +62 -40
- package/data/dist/index.cjs.map +1 -1
- package/data/dist/index.d.ts +8 -2
- package/data/dist/index.js +64 -42
- package/data/dist/index.js.map +1 -1
- package/data/src/dict.ts +8 -4
- package/data/src/join.ts +74 -33
- package/data/src/struct-family.ts +18 -17
- package/dist/chunk-IZHOMSXA.js +331 -0
- package/dist/chunk-IZHOMSXA.js.map +1 -0
- package/dist/chunk-JDUNWJFB.js +18 -0
- package/dist/chunk-JDUNWJFB.js.map +1 -0
- package/dist/index.cjs +4 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +66 -51
- package/dist/index.js +5 -11
- package/dist/index.js.map +1 -1
- package/internal/dist/index.cjs +187 -58
- package/internal/dist/index.cjs.map +1 -1
- package/internal/dist/index.d.ts +95 -71
- package/internal/dist/index.js +179 -53
- package/internal/dist/index.js.map +1 -1
- package/internal/src/arbitrary.ts +3 -0
- package/internal/src/atom/delete-atom.ts +7 -6
- package/internal/src/caching.ts +6 -4
- package/internal/src/families/find-in-store.ts +16 -0
- package/internal/src/get-environment-data.ts +4 -7
- package/internal/src/index.ts +6 -5
- package/internal/src/ingest-updates/ingest-atom-update.ts +6 -2
- package/internal/src/ingest-updates/ingest-transaction-update.ts +0 -1
- package/internal/src/selector/create-standalone-selector.ts +0 -2
- package/internal/src/set-state/copy-mutable-if-needed.ts +5 -0
- package/internal/src/set-state/emit-update.ts +25 -11
- package/internal/src/set-state/set-atom.ts +15 -18
- package/internal/src/store/store.ts +14 -2
- package/internal/src/store/withdraw.ts +72 -2
- package/internal/src/subscribe/subscribe-to-timeline.ts +2 -2
- package/internal/src/subscribe/subscribe-to-transaction.ts +2 -2
- package/internal/src/timeline/create-timeline.ts +12 -1
- package/internal/src/transaction/act-upon-store.ts +19 -0
- package/internal/src/transaction/apply-transaction.ts +6 -1
- package/internal/src/transaction/assign-transaction-to-continuity.ts +18 -0
- package/internal/src/transaction/build-transaction.ts +7 -6
- package/internal/src/transaction/create-transaction.ts +1 -1
- package/internal/src/transaction/get-epoch-number.ts +40 -0
- package/internal/src/transaction/index.ts +10 -1
- package/internal/src/transaction/set-epoch-number.ts +30 -0
- package/introspection/dist/index.cjs.map +1 -1
- package/introspection/dist/index.d.ts +3 -3
- package/introspection/dist/index.js.map +1 -1
- package/introspection/src/attach-introspection-states.ts +6 -2
- package/introspection/src/attach-timeline-family.ts +5 -2
- package/introspection/src/attach-transaction-logs.ts +2 -2
- package/json/dist/index.d.ts +3 -1
- package/json/src/index.ts +4 -0
- package/package.json +241 -230
- package/react/dist/index.cjs.map +1 -1
- package/react/dist/index.d.ts +1 -1
- package/react/dist/index.js.map +1 -1
- package/react/src/use-json.ts +1 -1
- package/react-devtools/dist/index.cjs +131 -134
- package/react-devtools/dist/index.cjs.map +1 -1
- package/react-devtools/dist/index.css +2 -2
- package/react-devtools/dist/index.css.map +1 -1
- package/react-devtools/dist/index.d.ts +3 -3
- package/react-devtools/dist/index.js +91 -108
- package/react-devtools/dist/index.js.map +1 -1
- package/react-devtools/src/StateEditor.tsx +4 -4
- package/react-devtools/src/StateIndex.tsx +1 -4
- package/react-devtools/src/TimelineIndex.tsx +3 -3
- package/react-devtools/src/TransactionIndex.tsx +9 -8
- package/react-devtools/src/index.ts +2 -2
- package/realtime/dist/index.cjs +120 -0
- package/realtime/dist/index.cjs.map +1 -0
- package/realtime/dist/index.d.ts +146 -0
- package/realtime/dist/index.js +111 -0
- package/realtime/dist/index.js.map +1 -0
- package/realtime/package.json +16 -0
- package/realtime/src/index.ts +2 -0
- package/realtime/src/realtime-continuity.ts +162 -0
- package/realtime/src/shared-room-store.ts +48 -0
- package/realtime-client/dist/index.cjs +424 -170
- package/realtime-client/dist/index.cjs.map +1 -1
- package/realtime-client/dist/index.d.ts +15 -11
- package/realtime-client/dist/index.js +96 -177
- package/realtime-client/dist/index.js.map +1 -1
- package/realtime-client/src/index.ts +8 -7
- package/realtime-client/src/{pull-family-member.ts → pull-atom-family-member.ts} +2 -2
- package/realtime-client/src/{pull-state.ts → pull-atom.ts} +2 -2
- package/realtime-client/src/{pull-mutable-family-member.ts → pull-mutable-atom-family-member.ts} +6 -6
- package/realtime-client/src/{pull-mutable.ts → pull-mutable-atom.ts} +1 -1
- package/realtime-client/src/pull-selector-family-member.ts +42 -0
- package/realtime-client/src/pull-selector.ts +38 -0
- package/realtime-client/src/realtime-client-stores/client-main-store.ts +12 -2
- package/realtime-client/src/realtime-client-stores/client-sync-store.ts +7 -7
- package/realtime-client/src/sync-continuity.ts +368 -0
- package/realtime-react/dist/index.cjs +367 -27
- package/realtime-react/dist/index.cjs.map +1 -1
- package/realtime-react/dist/index.d.ts +24 -8
- package/realtime-react/dist/index.js +38 -22
- package/realtime-react/dist/index.js.map +1 -1
- package/realtime-react/src/index.ts +6 -5
- package/realtime-react/src/use-pull-atom-family-member.ts +21 -0
- package/realtime-react/src/{use-sync.ts → use-pull-atom.ts} +4 -4
- package/realtime-react/src/{use-pull-mutable.ts → use-pull-mutable-atom.ts} +4 -3
- package/realtime-react/src/use-pull-mutable-family-member.ts +9 -4
- package/realtime-react/src/use-pull-selector-family-member.ts +21 -0
- package/realtime-react/src/{use-pull.ts → use-pull-selector.ts} +7 -5
- package/realtime-react/src/use-push.ts +3 -2
- package/realtime-react/src/use-server-action.ts +3 -2
- package/realtime-react/src/use-sync-continuity.ts +12 -0
- package/realtime-server/dist/index.cjs +769 -371
- package/realtime-server/dist/index.cjs.map +1 -1
- package/realtime-server/dist/index.d.ts +130 -60
- package/realtime-server/dist/index.js +753 -361
- package/realtime-server/dist/index.js.map +1 -1
- package/realtime-server/src/index.ts +17 -3
- package/realtime-server/src/ipc-sockets/child-socket.ts +135 -0
- package/realtime-server/src/ipc-sockets/custom-socket.ts +90 -0
- package/realtime-server/src/ipc-sockets/index.ts +3 -0
- package/realtime-server/src/ipc-sockets/parent-socket.ts +185 -0
- package/realtime-server/src/realtime-action-receiver.ts +8 -5
- package/realtime-server/src/realtime-continuity-synchronizer.ts +376 -0
- package/realtime-server/src/realtime-family-provider.ts +30 -71
- package/realtime-server/src/realtime-mutable-family-provider.ts +24 -86
- package/realtime-server/src/realtime-server-stores/index.ts +4 -1
- package/realtime-server/src/realtime-server-stores/realtime-continuity-store.ts +109 -0
- package/realtime-server/src/realtime-server-stores/server-room-external-actions.ts +64 -0
- package/realtime-server/src/realtime-server-stores/server-room-external-store.ts +42 -0
- package/realtime-server/src/realtime-server-stores/server-sync-store.ts +51 -98
- package/realtime-server/src/realtime-server-stores/server-user-store.ts +14 -29
- package/realtime-server/src/realtime-state-receiver.ts +0 -1
- package/realtime-testing/dist/index.cjs +34 -32
- package/realtime-testing/dist/index.cjs.map +1 -1
- package/realtime-testing/dist/index.d.ts +1 -0
- package/realtime-testing/dist/index.js +33 -31
- package/realtime-testing/dist/index.js.map +1 -1
- package/realtime-testing/src/setup-realtime-test.tsx +44 -32
- package/src/atom.ts +49 -31
- package/src/logger.ts +14 -5
- package/src/selector.ts +44 -25
- package/src/subscribe.ts +2 -1
- package/src/timeline.ts +4 -4
- package/src/transaction.ts +13 -17
- package/src/validators.ts +15 -9
- package/dist/chunk-H4Q5FTPZ.js +0 -11
- package/dist/chunk-H4Q5FTPZ.js.map +0 -1
- package/internal/src/set-state/copy-mutable-in-transaction.ts +0 -19
- package/realtime-client/src/sync-server-action.ts +0 -170
- package/realtime-client/src/sync-state.ts +0 -19
- package/realtime-react/src/use-pull-family-member.ts +0 -16
- package/realtime-react/src/use-sync-server-action.ts +0 -16
- package/realtime-server/src/realtime-action-synchronizer.ts +0 -152
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AtomToken } from "atom.io"
|
|
2
2
|
|
|
3
3
|
import type { Store } from ".."
|
|
4
|
-
import { deleteSelector, newest } from ".."
|
|
4
|
+
import { deleteSelector, getUpdateToken, newest } from ".."
|
|
5
5
|
|
|
6
|
-
export function deleteAtom(
|
|
7
|
-
atomToken: RegularAtomToken<unknown>,
|
|
8
|
-
store: Store,
|
|
9
|
-
): void {
|
|
6
|
+
export function deleteAtom(atomToken: AtomToken<unknown>, store: Store): void {
|
|
10
7
|
const target = newest(store)
|
|
11
8
|
const { key } = atomToken
|
|
12
9
|
const atom = target.atoms.get(key)
|
|
@@ -35,5 +32,9 @@ export function deleteAtom(
|
|
|
35
32
|
target.selectorAtoms.delete(key)
|
|
36
33
|
target.atomsThatAreDefault.delete(key)
|
|
37
34
|
target.timelineAtoms.delete(key)
|
|
35
|
+
if (atomToken.type === `mutable_atom`) {
|
|
36
|
+
const updateToken = getUpdateToken(atomToken)
|
|
37
|
+
deleteAtom(updateToken, store)
|
|
38
|
+
}
|
|
38
39
|
store.logger.info(`🔥`, `atom`, `${key}`, `deleted`)
|
|
39
40
|
}
|
package/internal/src/caching.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { StateUpdate } from "atom.io"
|
|
2
|
-
import type
|
|
2
|
+
import { type ReadableState, isChildStore } from "."
|
|
3
3
|
import { Future } from "./future"
|
|
4
|
-
import {
|
|
4
|
+
import { copyMutableIfNeeded } from "./set-state/copy-mutable-if-needed"
|
|
5
5
|
import type { Store } from "./store"
|
|
6
6
|
import type { Subject } from "./subject"
|
|
7
7
|
|
|
@@ -54,8 +54,10 @@ export const readCachedValue = <T>(
|
|
|
54
54
|
target: Store,
|
|
55
55
|
): T => {
|
|
56
56
|
let value = target.valueMap.get(token.key) as T
|
|
57
|
-
if (token.type === `
|
|
58
|
-
|
|
57
|
+
if (token.type === `mutable_atom` && isChildStore(target)) {
|
|
58
|
+
const { parent } = target
|
|
59
|
+
const copiedValue = copyMutableIfNeeded(token, parent, target)
|
|
60
|
+
value = copiedValue
|
|
59
61
|
}
|
|
60
62
|
return value
|
|
61
63
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Json } from "atom.io/json"
|
|
2
2
|
|
|
3
3
|
import type {
|
|
4
|
+
AtomFamilyToken,
|
|
5
|
+
AtomToken,
|
|
4
6
|
MutableAtomFamilyToken,
|
|
5
7
|
MutableAtomToken,
|
|
6
8
|
ReadableFamilyToken,
|
|
@@ -9,6 +11,8 @@ import type {
|
|
|
9
11
|
ReadonlySelectorToken,
|
|
10
12
|
RegularAtomFamilyToken,
|
|
11
13
|
RegularAtomToken,
|
|
14
|
+
SelectorFamilyToken,
|
|
15
|
+
SelectorToken,
|
|
12
16
|
WritableFamilyToken,
|
|
13
17
|
WritableSelectorFamilyToken,
|
|
14
18
|
WritableSelectorToken,
|
|
@@ -35,6 +39,12 @@ export function findInStore<T, K extends Json.Serializable, Key extends K>(
|
|
|
35
39
|
store: Store,
|
|
36
40
|
): RegularAtomToken<T>
|
|
37
41
|
|
|
42
|
+
export function findInStore<T, K extends Json.Serializable, Key extends K>(
|
|
43
|
+
token: AtomFamilyToken<T, K>,
|
|
44
|
+
key: Key,
|
|
45
|
+
store: Store,
|
|
46
|
+
): AtomToken<T>
|
|
47
|
+
|
|
38
48
|
export function findInStore<T, K extends Json.Serializable, Key extends K>(
|
|
39
49
|
token: WritableSelectorFamilyToken<T, K>,
|
|
40
50
|
key: Key,
|
|
@@ -47,6 +57,12 @@ export function findInStore<T, K extends Json.Serializable, Key extends K>(
|
|
|
47
57
|
store: Store,
|
|
48
58
|
): ReadonlySelectorToken<T>
|
|
49
59
|
|
|
60
|
+
export function findInStore<T, K extends Json.Serializable, Key extends K>(
|
|
61
|
+
token: SelectorFamilyToken<T, K>,
|
|
62
|
+
key: Key,
|
|
63
|
+
store: Store,
|
|
64
|
+
): SelectorToken<T>
|
|
65
|
+
|
|
50
66
|
export function findInStore<T, K extends Json.Serializable, Key extends K>(
|
|
51
67
|
token: WritableFamilyToken<T, K>,
|
|
52
68
|
key: Key,
|
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
import type { Store } from "./store"
|
|
2
2
|
|
|
3
3
|
export type EnvironmentData = {
|
|
4
|
-
|
|
4
|
+
window: typeof window | undefined
|
|
5
|
+
global: typeof global | undefined
|
|
5
6
|
store: Store
|
|
6
7
|
}
|
|
7
8
|
|
|
8
9
|
export function getEnvironmentData(store: Store): EnvironmentData {
|
|
9
10
|
return {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
? typeof global === `object`
|
|
13
|
-
? `node`
|
|
14
|
-
: `unknown`
|
|
15
|
-
: `browser`,
|
|
11
|
+
window: typeof window === `undefined` ? undefined : window,
|
|
12
|
+
global: typeof global === `undefined` ? undefined : global,
|
|
16
13
|
store,
|
|
17
14
|
}
|
|
18
15
|
}
|
package/internal/src/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type { Store } from "./store"
|
|
|
6
6
|
import type { Subject } from "./subject"
|
|
7
7
|
|
|
8
8
|
export * from "./atom"
|
|
9
|
+
export * from "./arbitrary"
|
|
9
10
|
export * from "./caching"
|
|
10
11
|
export * from "./lineage"
|
|
11
12
|
export * from "./families"
|
|
@@ -26,14 +27,14 @@ export * from "./subscribe"
|
|
|
26
27
|
export * from "./timeline"
|
|
27
28
|
export * from "./transaction"
|
|
28
29
|
|
|
29
|
-
export type
|
|
30
|
+
export type AtomIOState = {
|
|
30
31
|
key: string
|
|
31
32
|
family?: FamilyMetadata
|
|
32
33
|
install: (store: Store) => void
|
|
33
34
|
subject: Subject<{ newValue: any; oldValue: any }>
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
export type RegularAtom<T> =
|
|
37
|
+
export type RegularAtom<T> = AtomIOState & {
|
|
37
38
|
type: `atom`
|
|
38
39
|
default: T | (() => T)
|
|
39
40
|
cleanup?: () => void
|
|
@@ -41,7 +42,7 @@ export type RegularAtom<T> = BaseStateData & {
|
|
|
41
42
|
export type MutableAtom<
|
|
42
43
|
T extends Transceiver<any>,
|
|
43
44
|
J extends Json.Serializable,
|
|
44
|
-
> =
|
|
45
|
+
> = AtomIOState &
|
|
45
46
|
JsonInterface<T, J> & {
|
|
46
47
|
type: `mutable_atom`
|
|
47
48
|
default: T | (() => T)
|
|
@@ -51,12 +52,12 @@ export type Atom<T> =
|
|
|
51
52
|
| RegularAtom<T>
|
|
52
53
|
| (T extends Transceiver<any> ? MutableAtom<T, any> : never)
|
|
53
54
|
|
|
54
|
-
export type WritableSelector<T> =
|
|
55
|
+
export type WritableSelector<T> = AtomIOState & {
|
|
55
56
|
type: `selector`
|
|
56
57
|
get: () => T
|
|
57
58
|
set: (newValue: T | ((oldValue: T) => T)) => void
|
|
58
59
|
}
|
|
59
|
-
export type ReadonlySelector<T> =
|
|
60
|
+
export type ReadonlySelector<T> = AtomIOState & {
|
|
60
61
|
type: `readonly_selector`
|
|
61
62
|
get: () => T
|
|
62
63
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { KeyedStateUpdate } from "atom.io"
|
|
1
|
+
import type { KeyedStateUpdate, RegularAtomToken } from "atom.io"
|
|
2
2
|
|
|
3
3
|
import { setIntoStore } from "../set-state"
|
|
4
4
|
import type { Store } from "../store"
|
|
@@ -10,5 +10,9 @@ export function ingestAtomUpdate(
|
|
|
10
10
|
): void {
|
|
11
11
|
const { key, newValue, oldValue } = atomUpdate
|
|
12
12
|
const value = applying === `newValue` ? newValue : oldValue
|
|
13
|
-
|
|
13
|
+
const token: RegularAtomToken<unknown> = { key, type: `atom` }
|
|
14
|
+
if (atomUpdate.family) {
|
|
15
|
+
Object.assign(token, { family: atomUpdate.family })
|
|
16
|
+
}
|
|
17
|
+
setIntoStore(token, value, store)
|
|
14
18
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
FamilyMetadata,
|
|
3
2
|
ReadonlySelectorOptions,
|
|
4
3
|
ReadonlySelectorToken,
|
|
5
4
|
WritableSelectorOptions,
|
|
@@ -7,7 +6,6 @@ import type {
|
|
|
7
6
|
} from "atom.io"
|
|
8
7
|
|
|
9
8
|
import type { Store } from "../store"
|
|
10
|
-
import type { Subject } from "../subject"
|
|
11
9
|
import { createReadonlySelector } from "./create-readonly-selector"
|
|
12
10
|
import { createWritableSelector } from "./create-writable-selector"
|
|
13
11
|
|
|
@@ -9,7 +9,12 @@ export function copyMutableIfNeeded<T extends Transceiver<any>>(
|
|
|
9
9
|
): T {
|
|
10
10
|
const originValue = origin.valueMap.get(atom.key)
|
|
11
11
|
const targetValue = target.valueMap.get(atom.key)
|
|
12
|
+
|
|
12
13
|
if (originValue === targetValue) {
|
|
14
|
+
if (originValue === undefined) {
|
|
15
|
+
return typeof atom.default === `function` ? atom.default() : atom.default
|
|
16
|
+
}
|
|
17
|
+
|
|
13
18
|
origin.logger.info(`📃`, `atom`, `${atom.key}`, `copying`)
|
|
14
19
|
const jsonValue = atom.toJson(originValue)
|
|
15
20
|
const copiedValue = atom.fromJson(jsonValue)
|
|
@@ -8,16 +8,30 @@ export const emitUpdate = <T>(
|
|
|
8
8
|
update: StateUpdate<T>,
|
|
9
9
|
store: Store,
|
|
10
10
|
): void => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
11
|
+
switch (state.type) {
|
|
12
|
+
case `mutable_atom`:
|
|
13
|
+
store.logger.info(
|
|
14
|
+
`📢`,
|
|
15
|
+
state.type,
|
|
16
|
+
state.key,
|
|
17
|
+
`is now (`,
|
|
18
|
+
update.newValue,
|
|
19
|
+
`) subscribers:`,
|
|
20
|
+
state.subject.subscribers,
|
|
21
|
+
)
|
|
22
|
+
break
|
|
23
|
+
default:
|
|
24
|
+
store.logger.info(
|
|
25
|
+
`📢`,
|
|
26
|
+
state.type,
|
|
27
|
+
state.key,
|
|
28
|
+
`went (`,
|
|
29
|
+
update.oldValue,
|
|
30
|
+
`->`,
|
|
31
|
+
update.newValue,
|
|
32
|
+
`) subscribers:`,
|
|
33
|
+
state.subject.subscribers,
|
|
34
|
+
)
|
|
35
|
+
}
|
|
22
36
|
state.subject.next(update)
|
|
23
37
|
}
|
|
@@ -5,9 +5,9 @@ import { readOrComputeValue } from "../get-state/read-or-compute-value"
|
|
|
5
5
|
import type { Transceiver } from "../mutable"
|
|
6
6
|
import { markDone } from "../operation"
|
|
7
7
|
import type { Store } from "../store"
|
|
8
|
-
import { isRootStore } from "../transaction/is-root-store"
|
|
8
|
+
import { isChildStore, isRootStore } from "../transaction/is-root-store"
|
|
9
9
|
import { become } from "./become"
|
|
10
|
-
import {
|
|
10
|
+
import { copyMutableIfNeeded } from "./copy-mutable-if-needed"
|
|
11
11
|
import { emitUpdate } from "./emit-update"
|
|
12
12
|
import { evictDownStream } from "./evict-downstream"
|
|
13
13
|
import { stowUpdate } from "./stow-update"
|
|
@@ -18,7 +18,12 @@ export const setAtom = <T>(
|
|
|
18
18
|
target: Store,
|
|
19
19
|
): void => {
|
|
20
20
|
const oldValue = readOrComputeValue(atom, target)
|
|
21
|
-
let newValue =
|
|
21
|
+
let newValue = oldValue
|
|
22
|
+
if (atom.type === `mutable_atom` && isChildStore(target)) {
|
|
23
|
+
const { parent } = target
|
|
24
|
+
const copiedValue = copyMutableIfNeeded(atom, parent, target)
|
|
25
|
+
newValue = copiedValue
|
|
26
|
+
}
|
|
22
27
|
newValue = become(next)(newValue)
|
|
23
28
|
target.logger.info(`📝`, `atom`, atom.key, `set to`, newValue)
|
|
24
29
|
newValue = cacheValue(atom.key, newValue, atom.subject, target)
|
|
@@ -36,22 +41,14 @@ export const setAtom = <T>(
|
|
|
36
41
|
} else if (atom.key.startsWith(`*`)) {
|
|
37
42
|
const mutableKey = atom.key.slice(1)
|
|
38
43
|
const mutableAtom = target.atoms.get(mutableKey) as Atom<any>
|
|
39
|
-
let
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
`❌`,
|
|
45
|
-
`mutable_atom`,
|
|
46
|
-
mutableKey,
|
|
47
|
-
`could not be updated.`,
|
|
48
|
-
typeof output === `number`
|
|
49
|
-
? `Expected update number ${
|
|
50
|
-
mutable.cacheUpdateNumber + 1
|
|
51
|
-
}, but got ${output}`
|
|
52
|
-
: output,
|
|
53
|
-
)
|
|
44
|
+
let transceiver: Transceiver<any> = target.valueMap.get(mutableKey)
|
|
45
|
+
if (mutableAtom.type === `mutable_atom` && isChildStore(target)) {
|
|
46
|
+
const { parent } = target
|
|
47
|
+
const copiedValue = copyMutableIfNeeded(mutableAtom, parent, target)
|
|
48
|
+
transceiver = copiedValue
|
|
54
49
|
}
|
|
50
|
+
const accepted = transceiver.do(update.newValue) === null
|
|
51
|
+
if (accepted) evictDownStream(mutableAtom, target)
|
|
55
52
|
}
|
|
56
53
|
}
|
|
57
54
|
}
|
|
@@ -32,6 +32,7 @@ import type {
|
|
|
32
32
|
TransactionEpoch,
|
|
33
33
|
TransactionProgress,
|
|
34
34
|
} from "../transaction"
|
|
35
|
+
import { isRootStore } from "../transaction/is-root-store"
|
|
35
36
|
|
|
36
37
|
export class Store implements Lineage {
|
|
37
38
|
public parent: Store | null = null
|
|
@@ -93,7 +94,11 @@ export class Store implements Lineage {
|
|
|
93
94
|
}
|
|
94
95
|
public operation: OperationProgress = { open: false }
|
|
95
96
|
public transactionMeta: TransactionEpoch | TransactionProgress<ƒn> = {
|
|
96
|
-
epoch:
|
|
97
|
+
epoch: new Map<string, number>(),
|
|
98
|
+
actionContinuities: new Junction({
|
|
99
|
+
between: [`continuity`, `action`],
|
|
100
|
+
cardinality: `1:n`,
|
|
101
|
+
}),
|
|
97
102
|
}
|
|
98
103
|
|
|
99
104
|
public config: {
|
|
@@ -121,7 +126,14 @@ export class Store implements Lineage {
|
|
|
121
126
|
if (store !== null) {
|
|
122
127
|
this.valueMap = new Map(store?.valueMap)
|
|
123
128
|
this.operation = { ...store?.operation }
|
|
124
|
-
|
|
129
|
+
if (isRootStore(store)) {
|
|
130
|
+
this.transactionMeta = {
|
|
131
|
+
epoch: new Map(store?.transactionMeta.epoch),
|
|
132
|
+
actionContinuities: new Junction(
|
|
133
|
+
store?.transactionMeta.actionContinuities.toJSON(),
|
|
134
|
+
),
|
|
135
|
+
}
|
|
136
|
+
}
|
|
125
137
|
|
|
126
138
|
this.config = {
|
|
127
139
|
...store?.config,
|
|
@@ -1,18 +1,31 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
AtomFamily,
|
|
3
|
+
AtomFamilyToken,
|
|
2
4
|
AtomToken,
|
|
5
|
+
MutableAtomFamily,
|
|
6
|
+
MutableAtomFamilyToken,
|
|
3
7
|
MutableAtomToken,
|
|
4
8
|
ReadableToken,
|
|
9
|
+
ReadonlySelectorFamily,
|
|
10
|
+
ReadonlySelectorFamilyToken,
|
|
5
11
|
ReadonlySelectorToken,
|
|
12
|
+
RegularAtomFamily,
|
|
13
|
+
RegularAtomFamilyToken,
|
|
6
14
|
RegularAtomToken,
|
|
15
|
+
SelectorFamily,
|
|
16
|
+
SelectorFamilyToken,
|
|
7
17
|
SelectorToken,
|
|
8
18
|
TimelineManageable,
|
|
9
19
|
TimelineToken,
|
|
10
20
|
TransactionToken,
|
|
21
|
+
WritableSelectorFamily,
|
|
22
|
+
WritableSelectorFamilyToken,
|
|
11
23
|
WritableSelectorToken,
|
|
12
24
|
WritableToken,
|
|
13
25
|
ƒn,
|
|
14
26
|
} from "atom.io"
|
|
15
27
|
|
|
28
|
+
import type { Json } from "atom.io/json"
|
|
16
29
|
import type {
|
|
17
30
|
Atom,
|
|
18
31
|
MutableAtom,
|
|
@@ -28,7 +41,24 @@ import type { Timeline } from "../timeline"
|
|
|
28
41
|
import type { Transaction } from "../transaction"
|
|
29
42
|
import type { Store } from "./store"
|
|
30
43
|
|
|
31
|
-
export type Withdrawable =
|
|
44
|
+
export type Withdrawable =
|
|
45
|
+
| Atom<any>
|
|
46
|
+
| AtomFamily<any, any>
|
|
47
|
+
| MutableAtom<any, any>
|
|
48
|
+
| MutableAtomFamily<any, any, any>
|
|
49
|
+
| ReadableState<any>
|
|
50
|
+
| ReadableState<any>
|
|
51
|
+
| ReadonlySelector<any>
|
|
52
|
+
| ReadonlySelectorFamily<any, any>
|
|
53
|
+
| RegularAtom<any>
|
|
54
|
+
| RegularAtomFamily<any, any>
|
|
55
|
+
| Selector<any>
|
|
56
|
+
| SelectorFamily<any, any>
|
|
57
|
+
| Timeline<any>
|
|
58
|
+
| Transaction<any>
|
|
59
|
+
| WritableSelector<any>
|
|
60
|
+
| WritableSelectorFamily<any, any>
|
|
61
|
+
| WritableState<any>
|
|
32
62
|
|
|
33
63
|
export function withdraw<T>(
|
|
34
64
|
token: RegularAtomToken<T>,
|
|
@@ -62,6 +92,36 @@ export function withdraw<T>(
|
|
|
62
92
|
token: ReadableToken<T>,
|
|
63
93
|
store: Store,
|
|
64
94
|
): ReadableState<T> | undefined
|
|
95
|
+
|
|
96
|
+
export function withdraw<T, K extends Json.Serializable>(
|
|
97
|
+
token: RegularAtomFamilyToken<T, K>,
|
|
98
|
+
store: Store,
|
|
99
|
+
): RegularAtomFamily<T, K> | undefined
|
|
100
|
+
export function withdraw<
|
|
101
|
+
T extends Transceiver<any>,
|
|
102
|
+
J extends Json.Serializable,
|
|
103
|
+
K extends Json.Serializable,
|
|
104
|
+
>(
|
|
105
|
+
token: MutableAtomFamilyToken<T, J, K>,
|
|
106
|
+
store: Store,
|
|
107
|
+
): MutableAtomFamily<T, J, K> | undefined
|
|
108
|
+
export function withdraw<T, K extends Json.Serializable>(
|
|
109
|
+
token: AtomFamilyToken<T>,
|
|
110
|
+
store: Store,
|
|
111
|
+
): AtomFamily<T, any> | undefined
|
|
112
|
+
export function withdraw<T, K extends Json.Serializable>(
|
|
113
|
+
token: ReadonlySelectorFamilyToken<T, K>,
|
|
114
|
+
store: Store,
|
|
115
|
+
): ReadonlySelectorFamily<T, any> | undefined
|
|
116
|
+
export function withdraw<T, K extends Json.Serializable>(
|
|
117
|
+
token: WritableSelectorFamilyToken<T, K>,
|
|
118
|
+
store: Store,
|
|
119
|
+
): WritableSelectorFamily<T, any> | undefined
|
|
120
|
+
export function withdraw<T, K extends Json.Serializable>(
|
|
121
|
+
token: SelectorFamilyToken<T, K>,
|
|
122
|
+
store: Store,
|
|
123
|
+
): SelectorFamily<T, any> | undefined
|
|
124
|
+
|
|
65
125
|
export function withdraw<T>(
|
|
66
126
|
token: TransactionToken<T>,
|
|
67
127
|
store: Store,
|
|
@@ -72,11 +132,15 @@ export function withdraw<T>(
|
|
|
72
132
|
): Timeline<T extends TimelineManageable ? T : never> | undefined
|
|
73
133
|
export function withdraw<T>(
|
|
74
134
|
token:
|
|
135
|
+
| RegularAtomFamilyToken<T, any>
|
|
75
136
|
| RegularAtomToken<T>
|
|
137
|
+
| SelectorFamilyToken<T, any>
|
|
76
138
|
| SelectorToken<T>
|
|
77
139
|
| TimelineToken<T>
|
|
78
140
|
| TransactionToken<T>
|
|
79
|
-
| (T extends Transceiver<any>
|
|
141
|
+
| (T extends Transceiver<any>
|
|
142
|
+
? MutableAtomFamilyToken<T, any, any> | MutableAtomToken<T, any>
|
|
143
|
+
: never),
|
|
80
144
|
store: Store,
|
|
81
145
|
): Withdrawable | undefined {
|
|
82
146
|
let withdrawn: Withdrawable | undefined
|
|
@@ -93,6 +157,12 @@ export function withdraw<T>(
|
|
|
93
157
|
case `readonly_selector`:
|
|
94
158
|
withdrawn = target.readonlySelectors.get(token.key)
|
|
95
159
|
break
|
|
160
|
+
case `atom_family`:
|
|
161
|
+
case `mutable_atom_family`:
|
|
162
|
+
case `selector_family`:
|
|
163
|
+
case `readonly_selector_family`:
|
|
164
|
+
withdrawn = target.families.get(token.key)
|
|
165
|
+
break
|
|
96
166
|
case `timeline`:
|
|
97
167
|
withdrawn = target.timelines.get(token.key)
|
|
98
168
|
break
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { TimelineManageable, TimelineToken, TimelineUpdate } from "atom.io"
|
|
2
|
-
import type { Store } from "
|
|
3
|
-
import { withdraw } from "
|
|
2
|
+
import type { Store } from ".."
|
|
3
|
+
import { withdraw } from ".."
|
|
4
4
|
|
|
5
5
|
export const subscribeToTimeline = <ManagedAtom extends TimelineManageable>(
|
|
6
6
|
token: TimelineToken<ManagedAtom>,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { TransactionToken, TransactionUpdateHandler, ƒn } from "atom.io"
|
|
2
|
-
import type { Store } from "
|
|
3
|
-
import { withdraw } from "
|
|
2
|
+
import type { Store } from ".."
|
|
3
|
+
import { withdraw } from ".."
|
|
4
4
|
|
|
5
5
|
export const subscribeToTransaction = <ƒ extends ƒn>(
|
|
6
6
|
token: TransactionToken<ƒ>,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
AtomFamily,
|
|
3
|
+
AtomFamilyToken,
|
|
3
4
|
FamilyMetadata,
|
|
4
5
|
StateUpdate,
|
|
5
6
|
TimelineManageable,
|
|
@@ -86,7 +87,17 @@ export function createTimeline<ManagedAtom extends TimelineManageable>(
|
|
|
86
87
|
tokenOrFamily.type === `atom_family` ||
|
|
87
88
|
tokenOrFamily.type === `mutable_atom_family`
|
|
88
89
|
) {
|
|
89
|
-
const
|
|
90
|
+
const familyToken: AtomFamilyToken<any> = tokenOrFamily
|
|
91
|
+
const family = withdraw(familyToken, store)
|
|
92
|
+
if (family === undefined) {
|
|
93
|
+
store.logger.error(
|
|
94
|
+
`❌`,
|
|
95
|
+
`timeline`,
|
|
96
|
+
options.key,
|
|
97
|
+
`Failed to add family "${familyToken.key}" because it does not exist in the store`,
|
|
98
|
+
)
|
|
99
|
+
continue
|
|
100
|
+
}
|
|
90
101
|
const familyKey = family.key
|
|
91
102
|
target.timelineAtoms.set({ atomKey: familyKey, timelineKey })
|
|
92
103
|
family.subject.subscribe(`timeline:${options.key}`, (token) => {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { TransactionToken, ƒn } from "atom.io"
|
|
2
|
+
|
|
3
|
+
import { NotFoundError } from "../not-found-error"
|
|
4
|
+
import type { Store } from "../store"
|
|
5
|
+
import { withdraw } from "../store"
|
|
6
|
+
|
|
7
|
+
export function actUponStore<ƒ extends ƒn>(
|
|
8
|
+
token: TransactionToken<ƒ>,
|
|
9
|
+
id: string,
|
|
10
|
+
store: Store,
|
|
11
|
+
): (...parameters: Parameters<ƒ>) => ReturnType<ƒ> {
|
|
12
|
+
return (...parameters: Parameters<ƒ>): ReturnType<ƒ> => {
|
|
13
|
+
const tx = withdraw(token, store)
|
|
14
|
+
if (tx) {
|
|
15
|
+
return tx.run(parameters, id)
|
|
16
|
+
}
|
|
17
|
+
throw new NotFoundError(token, store)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -5,6 +5,7 @@ import { newest } from "../lineage"
|
|
|
5
5
|
import { withdraw } from "../store"
|
|
6
6
|
import type { Store } from "../store"
|
|
7
7
|
import { isChildStore, isRootStore } from "./is-root-store"
|
|
8
|
+
import { setEpochNumberOfAction } from "./set-epoch-number"
|
|
8
9
|
|
|
9
10
|
export const applyTransaction = <ƒ extends ƒn>(
|
|
10
11
|
output: ReturnType<ƒ>,
|
|
@@ -59,7 +60,11 @@ export const applyTransaction = <ƒ extends ƒn>(
|
|
|
59
60
|
}
|
|
60
61
|
ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent)
|
|
61
62
|
if (isRootStore(parent)) {
|
|
62
|
-
|
|
63
|
+
setEpochNumberOfAction(
|
|
64
|
+
child.transactionMeta.update.key,
|
|
65
|
+
child.transactionMeta.update.epoch,
|
|
66
|
+
parent,
|
|
67
|
+
)
|
|
63
68
|
const myTransaction = withdraw<ƒ>(
|
|
64
69
|
{ key: child.transactionMeta.update.key, type: `transaction` },
|
|
65
70
|
store,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Store } from "../store"
|
|
2
|
+
import { isRootStore } from "./is-root-store"
|
|
3
|
+
|
|
4
|
+
export function assignTransactionToContinuity(
|
|
5
|
+
continuityKey: string,
|
|
6
|
+
transactionKey: string,
|
|
7
|
+
store: Store,
|
|
8
|
+
): void {
|
|
9
|
+
const isRoot = isRootStore(store)
|
|
10
|
+
if (!isRoot) {
|
|
11
|
+
return
|
|
12
|
+
}
|
|
13
|
+
const { epoch, actionContinuities } = store.transactionMeta
|
|
14
|
+
actionContinuities.set(continuityKey, transactionKey)
|
|
15
|
+
if (!epoch.has(continuityKey)) {
|
|
16
|
+
epoch.set(continuityKey, -1)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { runTransaction } from "atom.io"
|
|
2
1
|
import type { findState, ƒn } from "atom.io"
|
|
3
2
|
|
|
4
3
|
import { Junction } from "~/packages/rel8/junction/src"
|
|
5
4
|
|
|
6
5
|
import type { TransactionProgress } from "."
|
|
6
|
+
import { actUponStore, getEpochNumberOfAction } from "."
|
|
7
|
+
import { arbitrary } from "../arbitrary"
|
|
7
8
|
import { findInStore } from "../families"
|
|
8
9
|
import { getEnvironmentData } from "../get-environment-data"
|
|
9
10
|
import { getFromStore } from "../get-state"
|
|
@@ -12,13 +13,12 @@ import { newest } from "../lineage"
|
|
|
12
13
|
import { setIntoStore } from "../set-state"
|
|
13
14
|
import type { Store } from "../store"
|
|
14
15
|
import type { ChildStore, RootStore } from "./is-root-store"
|
|
15
|
-
import { isRootStore } from "./is-root-store"
|
|
16
16
|
|
|
17
17
|
export const buildTransaction = (
|
|
18
18
|
key: string,
|
|
19
19
|
params: any[],
|
|
20
20
|
store: Store,
|
|
21
|
-
id
|
|
21
|
+
id: string,
|
|
22
22
|
): ChildStore => {
|
|
23
23
|
const parent = newest(store) as ChildStore | RootStore
|
|
24
24
|
const childBase: Omit<ChildStore, `transactionMeta`> = {
|
|
@@ -44,12 +44,13 @@ export const buildTransaction = (
|
|
|
44
44
|
selectors: new LazyMap(parent.selectors),
|
|
45
45
|
valueMap: new LazyMap(parent.valueMap),
|
|
46
46
|
}
|
|
47
|
+
const epoch = getEpochNumberOfAction(key, store)
|
|
47
48
|
const transactionMeta: TransactionProgress<ƒn> = {
|
|
48
49
|
phase: `building` as const,
|
|
49
50
|
update: {
|
|
50
51
|
key,
|
|
51
|
-
id
|
|
52
|
-
epoch:
|
|
52
|
+
id,
|
|
53
|
+
epoch: epoch === undefined ? NaN : epoch + 1,
|
|
53
54
|
updates: [],
|
|
54
55
|
params,
|
|
55
56
|
output: undefined,
|
|
@@ -57,7 +58,7 @@ export const buildTransaction = (
|
|
|
57
58
|
transactors: {
|
|
58
59
|
get: (token) => getFromStore(token, child),
|
|
59
60
|
set: (token, value) => setIntoStore(token, value, child),
|
|
60
|
-
run: (token, id) =>
|
|
61
|
+
run: (token, id = arbitrary()) => actUponStore(token, id, child),
|
|
61
62
|
find: ((token, key) => findInStore(token, key, child)) as typeof findState,
|
|
62
63
|
env: () => getEnvironmentData(child),
|
|
63
64
|
},
|
|
@@ -28,7 +28,7 @@ export function createTransaction<ƒ extends ƒn>(
|
|
|
28
28
|
const newTransaction: Transaction<ƒ> = {
|
|
29
29
|
key: options.key,
|
|
30
30
|
type: `transaction`,
|
|
31
|
-
run: (params: Parameters<ƒ>, id
|
|
31
|
+
run: (params: Parameters<ƒ>, id: string) => {
|
|
32
32
|
const childStore = buildTransaction(options.key, params, store, id)
|
|
33
33
|
try {
|
|
34
34
|
const target = newest(store)
|