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
package/src/atom.ts
CHANGED
|
@@ -45,23 +45,30 @@ export type RegularAtomFamilyOptions<T, K extends Json.Serializable> = {
|
|
|
45
45
|
effects?: (key: K) => AtomEffect<T>[]
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
export type RegularAtomFamily<
|
|
49
|
-
T,
|
|
50
|
-
K extends Json.Serializable = Json.Serializable,
|
|
51
|
-
> = ((key: K) => RegularAtomToken<T>) & {
|
|
52
|
-
key: string
|
|
53
|
-
type: `atom_family`
|
|
54
|
-
subject: Subject<RegularAtomToken<T>>
|
|
55
|
-
install: (store: Store) => void
|
|
56
|
-
__T?: T
|
|
57
|
-
__K?: K
|
|
58
|
-
}
|
|
59
48
|
export type RegularAtomFamilyToken<T, K extends Json.Serializable> = {
|
|
60
49
|
key: string
|
|
61
50
|
type: `atom_family`
|
|
62
51
|
__T?: T
|
|
63
52
|
__K?: K
|
|
64
53
|
}
|
|
54
|
+
// biome-ignore format: intersection
|
|
55
|
+
export type RegularAtomFamilyTokenWithCall<
|
|
56
|
+
T,
|
|
57
|
+
K extends Json.Serializable,
|
|
58
|
+
> =
|
|
59
|
+
& RegularAtomFamilyToken<T, K>
|
|
60
|
+
& {
|
|
61
|
+
/** @deprecated Prefer the `findState`, `findInStore`, or `find` functions. */
|
|
62
|
+
(key: K): RegularAtomToken<T>
|
|
63
|
+
}
|
|
64
|
+
// biome-ignore format: intersection
|
|
65
|
+
export type RegularAtomFamily<T, K extends Json.Serializable> =
|
|
66
|
+
& RegularAtomFamilyToken<T, K>
|
|
67
|
+
& {
|
|
68
|
+
(key: K): RegularAtomToken<T>
|
|
69
|
+
subject: Subject<RegularAtomToken<T>>
|
|
70
|
+
install: (store: Store) => void
|
|
71
|
+
}
|
|
65
72
|
|
|
66
73
|
// biome-ignore format: intersection
|
|
67
74
|
export type MutableAtomFamilyOptions<
|
|
@@ -77,23 +84,6 @@ export type MutableAtomFamilyOptions<
|
|
|
77
84
|
mutable: true,
|
|
78
85
|
}
|
|
79
86
|
|
|
80
|
-
// biome-ignore format: intersection
|
|
81
|
-
export type MutableAtomFamily<
|
|
82
|
-
T extends Transceiver<any>,
|
|
83
|
-
J extends Json.Serializable,
|
|
84
|
-
K extends Json.Serializable,
|
|
85
|
-
> =
|
|
86
|
-
& JsonInterface<T, J>
|
|
87
|
-
& ((key: K) => MutableAtomToken<T, J>)
|
|
88
|
-
& {
|
|
89
|
-
key: string
|
|
90
|
-
type: `mutable_atom_family`
|
|
91
|
-
subject: Subject<MutableAtomToken<T, J>>
|
|
92
|
-
install: (store: Store) => void
|
|
93
|
-
__T?: T
|
|
94
|
-
__J?: J
|
|
95
|
-
__K?: K
|
|
96
|
-
}
|
|
97
87
|
export type MutableAtomFamilyToken<
|
|
98
88
|
T extends Transceiver<any>,
|
|
99
89
|
J extends Json.Serializable,
|
|
@@ -105,6 +95,30 @@ export type MutableAtomFamilyToken<
|
|
|
105
95
|
__J?: J
|
|
106
96
|
__K?: K
|
|
107
97
|
}
|
|
98
|
+
// biome-ignore format: intersection
|
|
99
|
+
export type MutableAtomFamilyTokenWithCall<
|
|
100
|
+
T extends Transceiver<any>,
|
|
101
|
+
J extends Json.Serializable,
|
|
102
|
+
K extends Json.Serializable,
|
|
103
|
+
> =
|
|
104
|
+
& MutableAtomFamilyToken<T, J, K>
|
|
105
|
+
& {
|
|
106
|
+
/** @deprecated Prefer the `findState`, `findInStore`, or `find` functions. */
|
|
107
|
+
(key: K): MutableAtomToken<T, J>
|
|
108
|
+
}
|
|
109
|
+
// biome-ignore format: intersection
|
|
110
|
+
export type MutableAtomFamily<
|
|
111
|
+
T extends Transceiver<any>,
|
|
112
|
+
J extends Json.Serializable,
|
|
113
|
+
K extends Json.Serializable,
|
|
114
|
+
> =
|
|
115
|
+
& JsonInterface<T, J>
|
|
116
|
+
& MutableAtomFamilyToken<T, J, K>
|
|
117
|
+
& {
|
|
118
|
+
(key: K): MutableAtomToken<T, J>
|
|
119
|
+
subject: Subject<MutableAtomToken<T, J>>
|
|
120
|
+
install: (store: Store) => void
|
|
121
|
+
}
|
|
108
122
|
|
|
109
123
|
export type AtomFamily<T, K extends Json.Serializable = Json.Serializable> =
|
|
110
124
|
| MutableAtomFamily<T extends Transceiver<any> ? T : never, any, K>
|
|
@@ -117,14 +131,18 @@ export function atomFamily<
|
|
|
117
131
|
T extends Transceiver<any>,
|
|
118
132
|
J extends Json.Serializable,
|
|
119
133
|
K extends Json.Serializable,
|
|
120
|
-
>(
|
|
134
|
+
>(
|
|
135
|
+
options: MutableAtomFamilyOptions<T, J, K>,
|
|
136
|
+
): MutableAtomFamilyTokenWithCall<T, J, K>
|
|
121
137
|
export function atomFamily<T, K extends Json.Serializable>(
|
|
122
138
|
options: RegularAtomFamilyOptions<T, K>,
|
|
123
|
-
):
|
|
139
|
+
): RegularAtomFamilyTokenWithCall<T, K>
|
|
124
140
|
export function atomFamily<T, K extends Json.Serializable>(
|
|
125
141
|
options:
|
|
126
142
|
| MutableAtomFamilyOptions<any, any, any>
|
|
127
143
|
| RegularAtomFamilyOptions<T, K>,
|
|
128
|
-
):
|
|
144
|
+
):
|
|
145
|
+
| MutableAtomFamilyTokenWithCall<any, any, any>
|
|
146
|
+
| RegularAtomFamilyTokenWithCall<T, K> {
|
|
129
147
|
return createAtomFamily(options, IMPLICIT.STORE)
|
|
130
148
|
}
|
package/src/logger.ts
CHANGED
|
@@ -6,20 +6,23 @@ const LoggerIconDictionary = {
|
|
|
6
6
|
"⏮️": `Transaction undo`,
|
|
7
7
|
"⏳": `Timeline event partially captured`,
|
|
8
8
|
"⏹️": `Time-travel complete`,
|
|
9
|
-
"💁": `Notice`,
|
|
10
|
-
"🔄": `Realtime transaction synchronized`,
|
|
11
9
|
"✅": `Realtime transaction success`,
|
|
12
10
|
"✨": `Computation complete`,
|
|
13
11
|
"❌": `Conflict prevents attempted action`,
|
|
14
12
|
"⭕": `Operation start`,
|
|
15
13
|
"🐞": `Possible bug in AtomIO`,
|
|
16
14
|
"👀": `Subscription added`,
|
|
15
|
+
"👋": `Greeting`,
|
|
16
|
+
"👍": `Realtime acknowledgment`,
|
|
17
17
|
"👪": `Family member added`,
|
|
18
|
+
"💁": `Notice`,
|
|
19
|
+
"💥": `Caught`,
|
|
18
20
|
"📁": `Stow update`,
|
|
19
21
|
"📃": `Copy mutable`,
|
|
20
22
|
"📖": `Read state`,
|
|
21
23
|
"📝": `Write state`,
|
|
22
24
|
"📢": `Notify subscribers`,
|
|
25
|
+
"🔄": `Realtime transaction synchronized`,
|
|
23
26
|
"🔌": `Register dependency`,
|
|
24
27
|
"🔍": `Discover root`,
|
|
25
28
|
"🔥": `Delete state`,
|
|
@@ -27,8 +30,8 @@ const LoggerIconDictionary = {
|
|
|
27
30
|
"🔨": `Create immutable atom`,
|
|
28
31
|
"🔴": `Operation complete`,
|
|
29
32
|
"🗑": `Evict cached value`,
|
|
30
|
-
"💥": `Caught`,
|
|
31
33
|
"🙈": `Subscription canceled`,
|
|
34
|
+
"🚀": `Performance measure`,
|
|
32
35
|
"🛄": `Apply transaction`,
|
|
33
36
|
"🛠️": `Install atom into store`,
|
|
34
37
|
"🛫": `Begin transaction`,
|
|
@@ -36,14 +39,20 @@ const LoggerIconDictionary = {
|
|
|
36
39
|
"🧮": `Computing selector`,
|
|
37
40
|
"🧹": `Prepare to evict`,
|
|
38
41
|
"🪂": `Abort transaction`,
|
|
39
|
-
"
|
|
42
|
+
"🤞": `Realtime optimistic update enqueued`,
|
|
43
|
+
"👈": `Realtime confirmed update enqueued`,
|
|
44
|
+
"🧑⚖️": `Realtime update beginning reconciliation`,
|
|
45
|
+
"🛎️": `Realtime transaction received`,
|
|
46
|
+
"🔭": `Determining realtime perspective`,
|
|
47
|
+
"🖌": `Redacting realtime update`,
|
|
48
|
+
"👁": `Determining perspective`,
|
|
40
49
|
} as const
|
|
41
50
|
export type LoggerIcon = keyof typeof LoggerIconDictionary
|
|
42
51
|
export type TokenDenomination =
|
|
43
52
|
| `atom`
|
|
53
|
+
| `continuity`
|
|
44
54
|
| `mutable_atom`
|
|
45
55
|
| `readonly_selector`
|
|
46
|
-
| `realtime_sync_group`
|
|
47
56
|
| `selector`
|
|
48
57
|
| `state`
|
|
49
58
|
| `timeline`
|
package/src/selector.ts
CHANGED
|
@@ -41,41 +41,58 @@ export type ReadonlySelectorFamilyOptions<T, K extends Json.Serializable> = {
|
|
|
41
41
|
get: (key: K) => Read<() => T>
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
export type WritableSelectorFamily<
|
|
45
|
-
T,
|
|
46
|
-
K extends Json.Serializable = Json.Serializable,
|
|
47
|
-
> = ((key: K) => WritableSelectorToken<T>) & {
|
|
48
|
-
key: string
|
|
49
|
-
type: `selector_family`
|
|
50
|
-
subject: Subject<WritableSelectorToken<T>>
|
|
51
|
-
install: (store: Store) => void
|
|
52
|
-
__T?: T
|
|
53
|
-
__K?: K
|
|
54
|
-
}
|
|
55
44
|
export type WritableSelectorFamilyToken<T, K extends Json.Serializable> = {
|
|
56
45
|
key: string
|
|
57
46
|
type: `selector_family`
|
|
58
47
|
__T?: T
|
|
59
48
|
__K?: K
|
|
60
49
|
}
|
|
61
|
-
|
|
62
|
-
export type
|
|
50
|
+
// biome-ignore format: intersection
|
|
51
|
+
export type WritableSelectorFamilyTokenWithCall<
|
|
63
52
|
T,
|
|
64
|
-
K extends Json.Serializable
|
|
65
|
-
> =
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
53
|
+
K extends Json.Serializable,
|
|
54
|
+
> =
|
|
55
|
+
& WritableSelectorFamilyToken<T, K>
|
|
56
|
+
& {
|
|
57
|
+
/** @deprecated Prefer the `findState`, `findInStore`, or `find` functions. */
|
|
58
|
+
(key: K): WritableSelectorToken<T>
|
|
59
|
+
}
|
|
60
|
+
// biome-ignore format: intersection
|
|
61
|
+
export type WritableSelectorFamily<T, K extends Json.Serializable> =
|
|
62
|
+
& WritableSelectorFamilyToken<T, K>
|
|
63
|
+
& {
|
|
64
|
+
(key: K): WritableSelectorToken<T>
|
|
65
|
+
subject: Subject<WritableSelectorToken<T>>
|
|
66
|
+
install: (store: Store) => void
|
|
67
|
+
}
|
|
68
|
+
|
|
73
69
|
export type ReadonlySelectorFamilyToken<T, K extends Json.Serializable> = {
|
|
74
70
|
key: string
|
|
75
71
|
type: `readonly_selector_family`
|
|
76
72
|
__T?: T
|
|
77
73
|
__K?: K
|
|
78
74
|
}
|
|
75
|
+
// biome-ignore format: intersection
|
|
76
|
+
export type ReadonlySelectorFamilyTokenWithCall<
|
|
77
|
+
T,
|
|
78
|
+
K extends Json.Serializable,
|
|
79
|
+
> =
|
|
80
|
+
& ReadonlySelectorFamilyToken<T, K>
|
|
81
|
+
& {
|
|
82
|
+
/** @deprecated Prefer the `findState`, `findInStore`, or `find` functions. */
|
|
83
|
+
(key: K): ReadonlySelectorToken<T>
|
|
84
|
+
}
|
|
85
|
+
// biome-ignore format: intersection
|
|
86
|
+
export type ReadonlySelectorFamily<T, K extends Json.Serializable> =
|
|
87
|
+
& ((key: K) => ReadonlySelectorToken<T>)
|
|
88
|
+
& {
|
|
89
|
+
key: string
|
|
90
|
+
type: `readonly_selector_family`
|
|
91
|
+
subject: Subject<ReadonlySelectorToken<T>>
|
|
92
|
+
install: (store: Store) => void
|
|
93
|
+
__T?: T
|
|
94
|
+
__K?: K
|
|
95
|
+
}
|
|
79
96
|
|
|
80
97
|
export type SelectorFamily<T, K extends Json.Serializable> =
|
|
81
98
|
| ReadonlySelectorFamily<T, K>
|
|
@@ -86,14 +103,16 @@ export type SelectorFamilyToken<T, K extends Json.Serializable> =
|
|
|
86
103
|
|
|
87
104
|
export function selectorFamily<T, K extends Json.Serializable>(
|
|
88
105
|
options: WritableSelectorFamilyOptions<T, K>,
|
|
89
|
-
):
|
|
106
|
+
): WritableSelectorFamilyTokenWithCall<T, K>
|
|
90
107
|
export function selectorFamily<T, K extends Json.Serializable>(
|
|
91
108
|
options: ReadonlySelectorFamilyOptions<T, K>,
|
|
92
|
-
):
|
|
109
|
+
): ReadonlySelectorFamilyTokenWithCall<T, K>
|
|
93
110
|
export function selectorFamily<T, K extends Json.Serializable>(
|
|
94
111
|
options:
|
|
95
112
|
| ReadonlySelectorFamilyOptions<T, K>
|
|
96
113
|
| WritableSelectorFamilyOptions<T, K>,
|
|
97
|
-
):
|
|
114
|
+
):
|
|
115
|
+
| ReadonlySelectorFamilyTokenWithCall<T, K>
|
|
116
|
+
| WritableSelectorFamilyTokenWithCall<T, K> {
|
|
98
117
|
return createSelectorFamily(options, IMPLICIT.STORE)
|
|
99
118
|
}
|
package/src/subscribe.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Store } from "atom.io/internal"
|
|
2
2
|
import {
|
|
3
3
|
IMPLICIT,
|
|
4
|
+
arbitrary,
|
|
4
5
|
subscribeToState,
|
|
5
6
|
subscribeToTimeline,
|
|
6
7
|
subscribeToTransaction,
|
|
@@ -49,7 +50,7 @@ export function subscribe<M extends TimelineManageable>(
|
|
|
49
50
|
export function subscribe(
|
|
50
51
|
token: ReadableToken<any> | TimelineToken<any> | TransactionToken<any>,
|
|
51
52
|
handleUpdate: (update: any) => void,
|
|
52
|
-
key: string =
|
|
53
|
+
key: string = arbitrary(),
|
|
53
54
|
store = IMPLICIT.STORE,
|
|
54
55
|
): () => void {
|
|
55
56
|
switch (token.type) {
|
package/src/timeline.ts
CHANGED
|
@@ -6,14 +6,14 @@ import type {
|
|
|
6
6
|
} from "atom.io/internal"
|
|
7
7
|
import { IMPLICIT, createTimeline, timeTravel } from "atom.io/internal"
|
|
8
8
|
|
|
9
|
-
import type {
|
|
9
|
+
import type { AtomFamilyToken, AtomToken } from "."
|
|
10
10
|
|
|
11
|
-
export type TimelineManageable =
|
|
11
|
+
export type TimelineManageable = AtomFamilyToken<any, any> | AtomToken<any>
|
|
12
12
|
|
|
13
|
-
export type TimelineToken<
|
|
13
|
+
export type TimelineToken<M> = {
|
|
14
14
|
key: string
|
|
15
15
|
type: `timeline`
|
|
16
|
-
|
|
16
|
+
__M?: M
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export type TimelineOptions<ManagedAtom extends TimelineManageable> = {
|
package/src/transaction.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import type { EnvironmentData
|
|
2
|
-
import {
|
|
1
|
+
import type { EnvironmentData } from "atom.io/internal"
|
|
2
|
+
import {
|
|
3
|
+
IMPLICIT,
|
|
4
|
+
actUponStore,
|
|
5
|
+
arbitrary,
|
|
6
|
+
createTransaction,
|
|
7
|
+
} from "atom.io/internal"
|
|
3
8
|
|
|
4
9
|
import type {
|
|
5
10
|
KeyedStateUpdate,
|
|
@@ -77,18 +82,9 @@ export function transaction<ƒ extends ƒn>(
|
|
|
77
82
|
return createTransaction(options, IMPLICIT.STORE)
|
|
78
83
|
}
|
|
79
84
|
|
|
80
|
-
export
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
(...parameters: Parameters<ƒ>): ReturnType<ƒ> => {
|
|
87
|
-
const tx = withdraw(token, store)
|
|
88
|
-
if (tx) {
|
|
89
|
-
return tx.run(parameters, id)
|
|
90
|
-
}
|
|
91
|
-
throw new Error(
|
|
92
|
-
`Cannot run transaction "${token.key}": transaction not found in store "${store.config.name}".`,
|
|
93
|
-
)
|
|
94
|
-
}
|
|
85
|
+
export function runTransaction<ƒ extends ƒn>(
|
|
86
|
+
token: TransactionToken<ƒ>,
|
|
87
|
+
id = arbitrary(),
|
|
88
|
+
): (...parameters: Parameters<ƒ>) => ReturnType<ƒ> {
|
|
89
|
+
return actUponStore(token, id, IMPLICIT.STORE)
|
|
90
|
+
}
|
package/src/validators.ts
CHANGED
|
@@ -1,23 +1,29 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
MutableAtomFamily,
|
|
3
|
+
MutableAtomFamilyToken,
|
|
3
4
|
MutableAtomToken,
|
|
4
5
|
ReadableFamily,
|
|
6
|
+
ReadableFamilyToken,
|
|
5
7
|
ReadableToken,
|
|
6
8
|
ReadonlySelectorFamily,
|
|
9
|
+
ReadonlySelectorFamilyToken,
|
|
7
10
|
ReadonlySelectorToken,
|
|
8
11
|
RegularAtomFamily,
|
|
12
|
+
RegularAtomFamilyToken,
|
|
9
13
|
RegularAtomToken,
|
|
10
14
|
WritableFamily,
|
|
15
|
+
WritableFamilyToken,
|
|
11
16
|
WritableSelectorFamily,
|
|
17
|
+
WritableSelectorFamilyToken,
|
|
12
18
|
WritableSelectorToken,
|
|
13
19
|
WritableToken,
|
|
14
20
|
} from "atom.io"
|
|
15
21
|
|
|
16
22
|
export type TokenType<
|
|
17
|
-
Comparison extends
|
|
23
|
+
Comparison extends ReadableFamilyToken<any, any> | ReadableToken<any>,
|
|
18
24
|
> = Comparison extends ReadableToken<infer RepresentedValue>
|
|
19
25
|
? RepresentedValue
|
|
20
|
-
: Comparison extends
|
|
26
|
+
: Comparison extends ReadableFamilyToken<infer RepresentedValue, any>
|
|
21
27
|
? RepresentedValue
|
|
22
28
|
: never
|
|
23
29
|
|
|
@@ -52,31 +58,31 @@ export function isToken<KnownToken extends ReadableToken<any>>(
|
|
|
52
58
|
return knownToken.key === unknownToken.key
|
|
53
59
|
}
|
|
54
60
|
|
|
55
|
-
export function belongsTo<Family extends
|
|
61
|
+
export function belongsTo<Family extends RegularAtomFamilyToken<any, any>>(
|
|
56
62
|
family: Family,
|
|
57
63
|
unknownToken: ReadableToken<any>,
|
|
58
64
|
): unknownToken is RegularAtomToken<TokenType<Family>>
|
|
59
|
-
export function belongsTo<Family extends
|
|
65
|
+
export function belongsTo<Family extends MutableAtomFamilyToken<any, any, any>>(
|
|
60
66
|
family: Family,
|
|
61
67
|
unknownToken: ReadableToken<any>,
|
|
62
68
|
): unknownToken is MutableAtomToken<TokenType<Family>, any>
|
|
63
|
-
export function belongsTo<Family extends
|
|
69
|
+
export function belongsTo<Family extends WritableSelectorFamilyToken<any, any>>(
|
|
64
70
|
family: Family,
|
|
65
71
|
unknownToken: ReadableToken<any>,
|
|
66
72
|
): unknownToken is WritableSelectorToken<TokenType<Family>>
|
|
67
|
-
export function belongsTo<Family extends
|
|
73
|
+
export function belongsTo<Family extends ReadonlySelectorFamilyToken<any, any>>(
|
|
68
74
|
family: Family,
|
|
69
75
|
unknownToken: ReadableToken<any>,
|
|
70
76
|
): unknownToken is ReadonlySelectorToken<TokenType<Family>>
|
|
71
|
-
export function belongsTo<Family extends
|
|
77
|
+
export function belongsTo<Family extends WritableFamilyToken<any, any>>(
|
|
72
78
|
family: Family,
|
|
73
79
|
unknownToken: ReadableToken<any>,
|
|
74
80
|
): unknownToken is WritableToken<TokenType<Family>>
|
|
75
|
-
export function belongsTo<Family extends
|
|
81
|
+
export function belongsTo<Family extends ReadableFamilyToken<any, any>>(
|
|
76
82
|
family: Family,
|
|
77
83
|
unknownToken: ReadableToken<any>,
|
|
78
84
|
): unknownToken is ReadableToken<TokenType<Family>>
|
|
79
|
-
export function belongsTo<Family extends
|
|
85
|
+
export function belongsTo<Family extends ReadableFamilyToken<any, any>>(
|
|
80
86
|
family: Family,
|
|
81
87
|
unknownToken: ReadableToken<any>,
|
|
82
88
|
): unknownToken is ReadableToken<TokenType<Family>> {
|
package/dist/chunk-H4Q5FTPZ.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
// internal/src/transaction/is-root-store.ts
|
|
2
|
-
function isRootStore(store) {
|
|
3
|
-
return `epoch` in store.transactionMeta;
|
|
4
|
-
}
|
|
5
|
-
function isChildStore(store) {
|
|
6
|
-
return `phase` in store.transactionMeta;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export { isChildStore, isRootStore };
|
|
10
|
-
//# sourceMappingURL=out.js.map
|
|
11
|
-
//# sourceMappingURL=chunk-H4Q5FTPZ.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../internal/src/transaction/is-root-store.ts"],"names":[],"mappings":";AAgBO,SAAS,YAAY,OAAkC;AAC7D,SAAO,WAAW,MAAM;AACzB;AAEO,SAAS,aAAa,OAAmC;AAC/D,SAAO,WAAW,MAAM;AACzB","sourcesContent":["import type { ƒn } from \"atom.io\"\n\nimport type { TransactionEpoch, TransactionProgress } from \".\"\nimport type { Store } from \"../store\"\n\nexport interface RootStore extends Store {\n\ttransactionMeta: TransactionEpoch\n\tparent: null\n\tchild: ChildStore | null\n}\nexport interface ChildStore extends Store {\n\ttransactionMeta: TransactionProgress<ƒn>\n\tparent: ChildStore | RootStore\n\tchild: ChildStore | null\n}\n\nexport function isRootStore(store: Store): store is RootStore {\n\treturn `epoch` in store.transactionMeta\n}\n\nexport function isChildStore(store: Store): store is ChildStore {\n\treturn `phase` in store.transactionMeta\n}\n"]}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { newest } from ".."
|
|
2
|
-
import type { Atom, Store } from ".."
|
|
3
|
-
import { copyMutableIfNeeded } from "./copy-mutable-if-needed"
|
|
4
|
-
|
|
5
|
-
export function copyMutableIfWithinTransaction<T>(
|
|
6
|
-
oldValue: T,
|
|
7
|
-
atom: Atom<T>,
|
|
8
|
-
store: Store,
|
|
9
|
-
): T {
|
|
10
|
-
const target = newest(store)
|
|
11
|
-
const parent = target.parent
|
|
12
|
-
if (parent !== null) {
|
|
13
|
-
if (atom.type === `mutable_atom`) {
|
|
14
|
-
const copiedValue = copyMutableIfNeeded(atom, parent, target)
|
|
15
|
-
return copiedValue
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
return oldValue
|
|
19
|
-
}
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import * as AtomIO from "atom.io"
|
|
2
|
-
import * as Internal from "atom.io/internal"
|
|
3
|
-
import type { Socket } from "socket.io-client"
|
|
4
|
-
|
|
5
|
-
import { isRootStore } from "../../internal/src/transaction/is-root-store"
|
|
6
|
-
import {
|
|
7
|
-
confirmedUpdateQueueState,
|
|
8
|
-
optimisticUpdateQueueState,
|
|
9
|
-
} from "./realtime-client-stores"
|
|
10
|
-
|
|
11
|
-
export function syncAction<ƒ extends AtomIO.ƒn>(
|
|
12
|
-
token: AtomIO.TransactionToken<ƒ>,
|
|
13
|
-
socket: Socket,
|
|
14
|
-
store: Internal.Store,
|
|
15
|
-
): () => void {
|
|
16
|
-
const optimisticQueue = Internal.getFromStore(
|
|
17
|
-
optimisticUpdateQueueState,
|
|
18
|
-
store,
|
|
19
|
-
)
|
|
20
|
-
const confirmedQueue = Internal.getFromStore(confirmedUpdateQueueState, store)
|
|
21
|
-
|
|
22
|
-
const unsubscribeFromLocalUpdates = Internal.subscribeToTransaction(
|
|
23
|
-
token,
|
|
24
|
-
(clientUpdate) => {
|
|
25
|
-
const optimisticUpdateQueueIndex = optimisticQueue.findIndex(
|
|
26
|
-
(update) => update.id === clientUpdate.id,
|
|
27
|
-
)
|
|
28
|
-
if (optimisticUpdateQueueIndex === -1) {
|
|
29
|
-
Internal.setIntoStore(
|
|
30
|
-
optimisticUpdateQueueState,
|
|
31
|
-
(queue) => {
|
|
32
|
-
queue.push(clientUpdate)
|
|
33
|
-
queue.sort((a, b) => a.epoch - b.epoch)
|
|
34
|
-
return queue
|
|
35
|
-
},
|
|
36
|
-
store,
|
|
37
|
-
)
|
|
38
|
-
socket.emit(`tx-run:${token.key}`, clientUpdate)
|
|
39
|
-
} else {
|
|
40
|
-
Internal.setIntoStore(
|
|
41
|
-
optimisticUpdateQueueState,
|
|
42
|
-
(queue) => {
|
|
43
|
-
queue[optimisticUpdateQueueIndex] = clientUpdate
|
|
44
|
-
return queue
|
|
45
|
-
},
|
|
46
|
-
store,
|
|
47
|
-
)
|
|
48
|
-
socket.emit(`tx-run:${token.key}`, clientUpdate)
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
`tx-run:${token.key}`,
|
|
52
|
-
store,
|
|
53
|
-
)
|
|
54
|
-
const reconcileUpdates = (
|
|
55
|
-
optimisticUpdate: AtomIO.TransactionUpdate<ƒ>,
|
|
56
|
-
confirmedUpdate: AtomIO.TransactionUpdate<ƒ>,
|
|
57
|
-
) => {
|
|
58
|
-
Internal.setIntoStore(
|
|
59
|
-
optimisticUpdateQueueState,
|
|
60
|
-
(queue) => {
|
|
61
|
-
queue.shift()
|
|
62
|
-
return queue
|
|
63
|
-
},
|
|
64
|
-
store,
|
|
65
|
-
)
|
|
66
|
-
if (optimisticUpdate.id === confirmedUpdate.id) {
|
|
67
|
-
const clientResult = JSON.stringify(optimisticUpdate.updates)
|
|
68
|
-
const serverResult = JSON.stringify(confirmedUpdate.updates)
|
|
69
|
-
if (clientResult === serverResult) {
|
|
70
|
-
store.logger.info(
|
|
71
|
-
`✅`,
|
|
72
|
-
`transaction`,
|
|
73
|
-
token.key,
|
|
74
|
-
`results for ${optimisticUpdate.id} match between client and server`,
|
|
75
|
-
)
|
|
76
|
-
socket.emit(`tx-ack:${token.key}`, confirmedUpdate.epoch)
|
|
77
|
-
return
|
|
78
|
-
}
|
|
79
|
-
} else {
|
|
80
|
-
// id mismatch
|
|
81
|
-
store.logger.info(
|
|
82
|
-
`❌`,
|
|
83
|
-
`transaction`,
|
|
84
|
-
token.key,
|
|
85
|
-
`${store.config.name} thought update #${confirmedUpdate.epoch} was ${optimisticUpdate.key}:${optimisticUpdate.id}, but it was actually ${confirmedUpdate.key}:${confirmedUpdate.id}`,
|
|
86
|
-
)
|
|
87
|
-
}
|
|
88
|
-
for (const subsequentOptimistic of optimisticQueue.toReversed()) {
|
|
89
|
-
Internal.ingestTransactionUpdate(`oldValue`, subsequentOptimistic, store)
|
|
90
|
-
}
|
|
91
|
-
Internal.ingestTransactionUpdate(`oldValue`, optimisticUpdate, store)
|
|
92
|
-
Internal.ingestTransactionUpdate(`newValue`, confirmedUpdate, store)
|
|
93
|
-
socket.emit(`tx-ack:${token.key}`, confirmedUpdate.epoch)
|
|
94
|
-
for (const subsequentOptimistic of optimisticQueue) {
|
|
95
|
-
const token = Object.assign(
|
|
96
|
-
{ type: `transaction` } as const,
|
|
97
|
-
subsequentOptimistic,
|
|
98
|
-
)
|
|
99
|
-
const { id, params } = subsequentOptimistic
|
|
100
|
-
AtomIO.runTransaction(token, id, store)(...params)
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const registerAndAttemptConfirmedUpdate = (
|
|
105
|
-
confirmedUpdate: AtomIO.TransactionUpdate<ƒ>,
|
|
106
|
-
) => {
|
|
107
|
-
const zerothOptimisticUpdate = optimisticQueue[0]
|
|
108
|
-
if (zerothOptimisticUpdate) {
|
|
109
|
-
if (zerothOptimisticUpdate.epoch === confirmedUpdate.epoch) {
|
|
110
|
-
reconcileUpdates(zerothOptimisticUpdate, confirmedUpdate)
|
|
111
|
-
for (const nextConfirmed of confirmedQueue) {
|
|
112
|
-
const nextOptimistic = optimisticQueue[0]
|
|
113
|
-
if (nextConfirmed.epoch === nextOptimistic.epoch) {
|
|
114
|
-
reconcileUpdates(nextOptimistic, nextConfirmed)
|
|
115
|
-
} else {
|
|
116
|
-
break
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
} else {
|
|
120
|
-
// epoch mismatch
|
|
121
|
-
|
|
122
|
-
const hasEnqueuedOptimisticUpdate = optimisticQueue.some(
|
|
123
|
-
(update) => update.epoch === confirmedUpdate.epoch,
|
|
124
|
-
)
|
|
125
|
-
if (hasEnqueuedOptimisticUpdate) {
|
|
126
|
-
Internal.setIntoStore(
|
|
127
|
-
confirmedUpdateQueueState,
|
|
128
|
-
(queue) => {
|
|
129
|
-
queue.push(confirmedUpdate)
|
|
130
|
-
queue.sort((a, b) => a.epoch - b.epoch)
|
|
131
|
-
return queue
|
|
132
|
-
},
|
|
133
|
-
store,
|
|
134
|
-
)
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
} else {
|
|
138
|
-
if (
|
|
139
|
-
isRootStore(store) &&
|
|
140
|
-
store.transactionMeta.epoch === confirmedUpdate.epoch - 1
|
|
141
|
-
) {
|
|
142
|
-
Internal.ingestTransactionUpdate(`newValue`, confirmedUpdate, store)
|
|
143
|
-
socket.emit(`tx-ack:${token.key}`, confirmedUpdate.epoch)
|
|
144
|
-
store.transactionMeta.epoch = confirmedUpdate.epoch
|
|
145
|
-
} else if (isRootStore(store)) {
|
|
146
|
-
store.logger.info(
|
|
147
|
-
`❌`,
|
|
148
|
-
`transaction`,
|
|
149
|
-
token.key,
|
|
150
|
-
`received out-of-order update from server`,
|
|
151
|
-
{
|
|
152
|
-
clientEpoch: store.transactionMeta.epoch,
|
|
153
|
-
serverEpoch: confirmedUpdate.epoch,
|
|
154
|
-
},
|
|
155
|
-
)
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
socket.off(`tx-new:${token.key}`, registerAndAttemptConfirmedUpdate)
|
|
160
|
-
socket.on(`tx-new:${token.key}`, registerAndAttemptConfirmedUpdate)
|
|
161
|
-
socket.emit(`tx-sub:${token.key}`)
|
|
162
|
-
const unsubscribeFromIncomingUpdates = () => {
|
|
163
|
-
socket.off(`tx-new:${token.key}`, registerAndAttemptConfirmedUpdate)
|
|
164
|
-
socket.emit(`tx-unsub:${token.key}`)
|
|
165
|
-
}
|
|
166
|
-
return () => {
|
|
167
|
-
unsubscribeFromLocalUpdates()
|
|
168
|
-
unsubscribeFromIncomingUpdates()
|
|
169
|
-
}
|
|
170
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type * as AtomIO from "atom.io"
|
|
2
|
-
import { type Store, setIntoStore } from "atom.io/internal"
|
|
3
|
-
import type { Json } from "atom.io/json"
|
|
4
|
-
import type { Socket } from "socket.io-client"
|
|
5
|
-
|
|
6
|
-
export function syncState<J extends Json.Serializable>(
|
|
7
|
-
token: AtomIO.WritableToken<J>,
|
|
8
|
-
socket: Socket,
|
|
9
|
-
store: Store,
|
|
10
|
-
): () => void {
|
|
11
|
-
const setServedValue = (data: J) => {
|
|
12
|
-
setIntoStore(token, data, store)
|
|
13
|
-
}
|
|
14
|
-
socket.on(`value:${token.key}`, setServedValue)
|
|
15
|
-
socket.emit(`get:${token.key}`)
|
|
16
|
-
return () => {
|
|
17
|
-
socket.off(`value:${token.key}`, setServedValue)
|
|
18
|
-
}
|
|
19
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type * as AtomIO from "atom.io"
|
|
2
|
-
import type { Json } from "atom.io/json"
|
|
3
|
-
import { StoreContext } from "atom.io/react"
|
|
4
|
-
import * as RTC from "atom.io/realtime-client"
|
|
5
|
-
import * as React from "react"
|
|
6
|
-
|
|
7
|
-
import { useRealtimeService } from "./use-realtime-service"
|
|
8
|
-
|
|
9
|
-
export function usePullFamilyMember<J extends Json.Serializable>(
|
|
10
|
-
token: AtomIO.WritableToken<J>,
|
|
11
|
-
): void {
|
|
12
|
-
const store = React.useContext(StoreContext)
|
|
13
|
-
useRealtimeService(`pull:${token.key}`, (socket) =>
|
|
14
|
-
RTC.pullFamilyMember(token, socket, store),
|
|
15
|
-
)
|
|
16
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import * as AtomIO from "atom.io"
|
|
2
|
-
import { StoreContext } from "atom.io/react"
|
|
3
|
-
import * as RTC from "atom.io/realtime-client"
|
|
4
|
-
import * as React from "react"
|
|
5
|
-
|
|
6
|
-
import { useRealtimeService } from "./use-realtime-service"
|
|
7
|
-
|
|
8
|
-
export function useSyncAction<ƒ extends AtomIO.ƒn>(
|
|
9
|
-
token: AtomIO.TransactionToken<ƒ>,
|
|
10
|
-
): (...parameters: Parameters<ƒ>) => ReturnType<ƒ> {
|
|
11
|
-
const store = React.useContext(StoreContext)
|
|
12
|
-
useRealtimeService(`tx-sync:${token.key}`, (socket) => {
|
|
13
|
-
return RTC.syncAction(token, socket, store)
|
|
14
|
-
})
|
|
15
|
-
return AtomIO.runTransaction(token, undefined, store)
|
|
16
|
-
}
|