atom.io 0.6.8 → 0.6.9

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.
Files changed (130) hide show
  1. package/dist/index.d.mts +226 -258
  2. package/dist/index.d.ts +226 -258
  3. package/dist/index.js +28 -1917
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +5 -1877
  6. package/dist/index.mjs.map +1 -1
  7. package/introspection/dist/index.d.mts +117 -171
  8. package/introspection/dist/index.d.ts +117 -171
  9. package/introspection/dist/index.js +6 -346
  10. package/introspection/dist/index.js.map +1 -1
  11. package/introspection/dist/index.mjs +5 -324
  12. package/introspection/dist/index.mjs.map +1 -1
  13. package/json/dist/index.d.mts +32 -1
  14. package/json/dist/index.d.ts +32 -1
  15. package/json/dist/index.js +31 -48
  16. package/json/dist/index.js.map +1 -1
  17. package/json/dist/index.mjs +6 -14
  18. package/json/dist/index.mjs.map +1 -1
  19. package/package.json +22 -14
  20. package/react/dist/index.js +34 -83
  21. package/react/dist/index.js.map +1 -1
  22. package/react/dist/index.mjs +7 -43
  23. package/react/dist/index.mjs.map +1 -1
  24. package/react-devtools/dist/index.css +1 -50
  25. package/react-devtools/dist/index.css.map +1 -1
  26. package/react-devtools/dist/index.d.mts +124 -188
  27. package/react-devtools/dist/index.d.ts +124 -188
  28. package/react-devtools/dist/index.js +56 -4674
  29. package/react-devtools/dist/index.js.map +1 -1
  30. package/react-devtools/dist/index.mjs +19 -4642
  31. package/react-devtools/dist/index.mjs.map +1 -1
  32. package/realtime/dist/index.d.mts +1 -3
  33. package/realtime/dist/index.d.ts +1 -3
  34. package/realtime/dist/index.js +26 -184
  35. package/realtime/dist/index.js.map +1 -1
  36. package/realtime/dist/index.mjs +4 -148
  37. package/realtime/dist/index.mjs.map +1 -1
  38. package/realtime-react/dist/index.d.mts +2 -4
  39. package/realtime-react/dist/index.d.ts +2 -4
  40. package/realtime-react/dist/index.js +41 -214
  41. package/realtime-react/dist/index.js.map +1 -1
  42. package/realtime-react/dist/index.mjs +9 -169
  43. package/realtime-react/dist/index.mjs.map +1 -1
  44. package/src/atom.ts +4 -3
  45. package/src/index.ts +12 -9
  46. package/src/logger.ts +5 -5
  47. package/src/selector.ts +3 -3
  48. package/src/silo.ts +36 -39
  49. package/src/subscribe.ts +24 -19
  50. package/src/timeline.ts +9 -4
  51. package/src/transaction.ts +3 -4
  52. package/src/internal/atom-internal.ts +0 -54
  53. package/src/internal/families-internal.ts +0 -144
  54. package/src/internal/get.ts +0 -129
  55. package/src/internal/index.ts +0 -15
  56. package/src/internal/is-default.ts +0 -35
  57. package/src/internal/operation.ts +0 -139
  58. package/src/internal/selector/create-read-write-selector.ts +0 -68
  59. package/src/internal/selector/create-readonly-selector.ts +0 -48
  60. package/src/internal/selector/index.ts +0 -4
  61. package/src/internal/selector/lookup-selector-sources.ts +0 -16
  62. package/src/internal/selector/register-selector.ts +0 -57
  63. package/src/internal/selector/trace-selector-atoms.ts +0 -43
  64. package/src/internal/selector/update-selector-atoms.ts +0 -33
  65. package/src/internal/selector-internal.ts +0 -58
  66. package/src/internal/set.ts +0 -99
  67. package/src/internal/store.ts +0 -151
  68. package/src/internal/subscribe-internal.ts +0 -88
  69. package/src/internal/time-travel-internal.ts +0 -91
  70. package/src/internal/timeline/add-atom-to-timeline.ts +0 -168
  71. package/src/internal/timeline/index.ts +0 -1
  72. package/src/internal/timeline-internal.ts +0 -107
  73. package/src/internal/transaction/abort-transaction.ts +0 -12
  74. package/src/internal/transaction/apply-transaction.ts +0 -57
  75. package/src/internal/transaction/build-transaction.ts +0 -33
  76. package/src/internal/transaction/index.ts +0 -25
  77. package/src/internal/transaction/redo-transaction.ts +0 -23
  78. package/src/internal/transaction/undo-transaction.ts +0 -23
  79. package/src/internal/transaction-internal.ts +0 -61
  80. package/src/introspection/attach-atom-index.ts +0 -73
  81. package/src/introspection/attach-introspection-states.ts +0 -42
  82. package/src/introspection/attach-selector-index.ts +0 -77
  83. package/src/introspection/attach-timeline-family.ts +0 -59
  84. package/src/introspection/attach-timeline-index.ts +0 -36
  85. package/src/introspection/attach-transaction-index.ts +0 -38
  86. package/src/introspection/attach-transaction-logs.ts +0 -40
  87. package/src/introspection/index.ts +0 -20
  88. package/src/json/index.ts +0 -1
  89. package/src/json/select-json.ts +0 -18
  90. package/src/react/index.ts +0 -2
  91. package/src/react/store-context.tsx +0 -13
  92. package/src/react/store-hooks.ts +0 -47
  93. package/src/react-devtools/AtomIODevtools.tsx +0 -107
  94. package/src/react-devtools/Button.tsx +0 -24
  95. package/src/react-devtools/StateEditor.tsx +0 -74
  96. package/src/react-devtools/StateIndex.tsx +0 -156
  97. package/src/react-devtools/TimelineIndex.tsx +0 -92
  98. package/src/react-devtools/TransactionIndex.tsx +0 -70
  99. package/src/react-devtools/Updates.tsx +0 -145
  100. package/src/react-devtools/devtools.scss +0 -310
  101. package/src/react-devtools/index.ts +0 -72
  102. package/src/react-explorer/AtomIOExplorer.tsx +0 -218
  103. package/src/react-explorer/explorer-effects.ts +0 -20
  104. package/src/react-explorer/explorer-states.ts +0 -217
  105. package/src/react-explorer/index.ts +0 -23
  106. package/src/react-explorer/space-states.ts +0 -72
  107. package/src/react-explorer/view-states.ts +0 -41
  108. package/src/realtime/README.md +0 -33
  109. package/src/realtime/hook-composition/expose-family.ts +0 -101
  110. package/src/realtime/hook-composition/expose-single.ts +0 -38
  111. package/src/realtime/hook-composition/expose-timeline.ts +0 -60
  112. package/src/realtime/hook-composition/index.ts +0 -12
  113. package/src/realtime/hook-composition/receive-state.ts +0 -29
  114. package/src/realtime/hook-composition/receive-transaction.ts +0 -18
  115. package/src/realtime/index.ts +0 -1
  116. package/src/realtime-react/index.ts +0 -3
  117. package/src/realtime-react/realtime-context.tsx +0 -30
  118. package/src/realtime-react/realtime-hooks.ts +0 -39
  119. package/src/realtime-react/realtime-state.ts +0 -10
  120. package/src/realtime-react/use-pull-family-member.ts +0 -26
  121. package/src/realtime-react/use-pull-family.ts +0 -24
  122. package/src/realtime-react/use-pull.ts +0 -24
  123. package/src/realtime-react/use-push.ts +0 -27
  124. package/src/realtime-react/use-server-action.ts +0 -33
  125. package/src/realtime-testing/index.ts +0 -1
  126. package/src/realtime-testing/setup-realtime-test.tsx +0 -159
  127. package/src/tracker/index.ts +0 -3
  128. package/src/tracker/tracker.ts +0 -61
  129. package/src/web-effects/index.ts +0 -1
  130. package/src/web-effects/storage.ts +0 -30
@@ -1,217 +0,0 @@
1
- import { lastOf } from "~/packages/anvl/src/array"
2
- import { now } from "~/packages/anvl/src/id"
3
- import { Join } from "~/packages/anvl/src/join"
4
- import type { Entries } from "~/packages/anvl/src/object"
5
-
6
- import { addToIndex, removeFromIndex } from "."
7
- import {
8
- makeSpaceLayoutNodeFamily,
9
- makeSpaceFamily,
10
- makeSpaceIndex,
11
- makeSpaceLayoutState,
12
- } from "./space-states"
13
- import type { View } from "./view-states"
14
- import {
15
- makeViewFocusedFamily,
16
- makeViewFamily,
17
- makeViewIndex,
18
- } from "./view-states"
19
- import type {
20
- AtomFamily,
21
- AtomToken,
22
- ReadonlySelectorFamily,
23
- SelectorFamily,
24
- Write,
25
- } from ".."
26
- import { selectorFamily, selector, transaction, atom } from ".."
27
- import { persistAtom } from "../web-effects"
28
-
29
- export const makeViewsPerSpaceState = (
30
- key: string,
31
- ): AtomToken<Join<null, `viewId`, `spaceId`>> =>
32
- atom<Join<null, `viewId`, `spaceId`>>({
33
- key: `${key}:views_per_space`,
34
- default: new Join({ relationType: `1:n` }).from(`viewId`).to(`spaceId`),
35
- effects: [
36
- persistAtom<Join<null, `viewId`, `spaceId`>>(localStorage)({
37
- stringify: (index) => JSON.stringify(index.toJSON()),
38
- parse: (json) =>
39
- Join.fromJSON(JSON.parse(json), {
40
- from: `viewId`,
41
- to: `spaceId`,
42
- }),
43
- })(`${key}:views_per_space`),
44
- ],
45
- })
46
-
47
- export const makeSpaceViewsFamily = (
48
- key: string,
49
- viewsPerSpaceState: AtomToken<Join<null, `viewId`, `spaceId`>>,
50
- ): ReadonlySelectorFamily<string[], string> =>
51
- selectorFamily<string[], string>({
52
- key: `${key}:space_views`,
53
- get: (spaceId) => ({ get }) => {
54
- const join = get(viewsPerSpaceState)
55
- const viewIds = join.getRelatedIds(spaceId)
56
- return viewIds
57
- },
58
- })
59
-
60
- export const makeSpaceFocusedViewFamily = (
61
- key: string,
62
- findSpaceViewsState: ReadonlySelectorFamily<string[], string>,
63
- findViewFocusedState: AtomFamily<number, string>,
64
- ): SelectorFamily<string | null, string> =>
65
- selectorFamily<string | null, string>({
66
- key: `${key}:space_focused_view`,
67
- get: (spaceKey) => ({ get }) => {
68
- const views = get(findSpaceViewsState(spaceKey))
69
- const viewsLastFocused = views.map((viewKey): [string, number] => [
70
- viewKey,
71
- get(findViewFocusedState(viewKey)),
72
- ])
73
- const lastFocused = lastOf(viewsLastFocused.sort((a, b) => b[1] - a[1]))
74
- return lastFocused ? lastFocused[0] : null
75
- },
76
- set: (spaceKey) => ({ get, set }, viewKey) => {
77
- if (viewKey === null) {
78
- return
79
- }
80
- const views = get(findSpaceViewsState(spaceKey))
81
- if (views.includes(viewKey)) {
82
- set(findViewFocusedState(viewKey), Date.now())
83
- } else {
84
- console.warn(`View ${viewKey} not found in space ${spaceKey}`)
85
- }
86
- },
87
- })
88
-
89
- type AddViewOptions = { spaceId?: string; path?: string }
90
- type SplitSpaceOptions = { parentId?: string }
91
-
92
- // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
93
- export const attachExplorerState = (key: string) => {
94
- const findSpaceState = makeSpaceFamily(key)
95
- const findViewState = makeViewFamily(key)
96
- const findViewFocusedState = makeViewFocusedFamily(key)
97
- const spaceIndexState = makeSpaceIndex(key)
98
- const spaceLayoutState = makeSpaceLayoutState(key)
99
- const viewIndexState = makeViewIndex(key)
100
- const viewsPerSpaceState = makeViewsPerSpaceState(key)
101
-
102
- const findSpaceLayoutNode = makeSpaceLayoutNodeFamily(key, spaceLayoutState)
103
- const findSpaceViewsState = makeSpaceViewsFamily(key, viewsPerSpaceState)
104
- const findSpaceFocusedViewState = makeSpaceFocusedViewFamily(
105
- key,
106
- findSpaceViewsState,
107
- findViewFocusedState,
108
- )
109
-
110
- const allViewsState = selector<Entries<string, View>>({
111
- key: `${key}:all_views`,
112
- get: ({ get }) => {
113
- const viewIndex = get(viewIndexState)
114
- return [...viewIndex].map((id) => [id, get(findViewState(id))])
115
- },
116
- })
117
-
118
- const writeOperationAddSpace: Write<(options?: SplitSpaceOptions) => string> =
119
- (transactors, { parentId = `root` } = {}) => {
120
- const { set } = transactors
121
- const key = `s-${now()}`
122
- addToIndex(transactors, { indexAtom: spaceIndexState, id: key })
123
- set(spaceLayoutState, (current) =>
124
- current.set({ parent: `parent:${parentId}`, child: key }, { size: 1 }),
125
- )
126
- set(findSpaceState(key), 1)
127
- return key
128
- }
129
-
130
- const writeOperationRemoveSpace: Write<(id: string) => void> = (
131
- transactors,
132
- id,
133
- ) => {
134
- removeFromIndex(transactors, { indexAtom: spaceIndexState, id })
135
- transactors.set(findSpaceState(id), null)
136
- }
137
-
138
- const writeOperationAddView: Write<(options?: AddViewOptions) => void> = (
139
- transactors,
140
- { spaceId: maybeSpaceId, path } = {},
141
- ) => {
142
- const { get, set } = transactors
143
- const id = `v-${now()}`
144
-
145
- addToIndex(transactors, { indexAtom: viewIndexState, id })
146
- set(
147
- findViewState(id),
148
- (current): View => ({
149
- ...current,
150
- location: {
151
- ...current.location,
152
- pathname: path ?? `/`,
153
- },
154
- }),
155
- )
156
- const spaceId =
157
- maybeSpaceId ??
158
- lastOf([...get(spaceIndexState)]) ??
159
- writeOperationAddSpace(transactors)
160
- set(findViewFocusedState(id), Date.now())
161
-
162
- set(viewsPerSpaceState, (current) => current.set({ spaceId, viewId: id }))
163
- set(findViewFocusedState(id), Date.now())
164
- }
165
-
166
- const writeOperationRemoveView: Write<(viewId: string) => void> = (
167
- transactors,
168
- viewId,
169
- ) => {
170
- const { set } = transactors
171
- removeFromIndex(transactors, { indexAtom: viewIndexState, id: viewId })
172
- set(viewsPerSpaceState, (current) => current.remove({ viewId }))
173
- set(findViewState(viewId), null)
174
- }
175
-
176
- const addView = transaction<(options?: AddViewOptions) => void>({
177
- key: `${key}:add_view`,
178
- do: writeOperationAddView,
179
- })
180
-
181
- const removeView = transaction({
182
- key: `${key}:remove_view`,
183
- do: writeOperationRemoveView,
184
- })
185
-
186
- const addSpace = transaction({
187
- key: `${key}:add_space`,
188
- do: writeOperationAddSpace,
189
- })
190
-
191
- const removeSpace = transaction({
192
- key: `${key}:remove_space`,
193
- do: writeOperationRemoveSpace,
194
- })
195
-
196
- return {
197
- addSpace,
198
- addView,
199
- allViewsState,
200
- findSpaceLayoutNode,
201
- findSpaceFocusedViewState,
202
- findSpaceState,
203
- findSpaceViewsState,
204
- findViewState,
205
- findViewFocusedState,
206
- removeSpace,
207
- removeView,
208
- spaceIndexState,
209
- spaceLayoutState,
210
- viewIndexState,
211
- viewsPerSpaceState,
212
- writeOperationAddSpace,
213
- writeOperationAddView,
214
- writeOperationRemoveSpace,
215
- writeOperationRemoveView,
216
- }
217
- }
@@ -1,23 +0,0 @@
1
- import type { AtomToken, Write } from "atom.io"
2
-
3
- export * from "./AtomIOExplorer"
4
-
5
- export type AtomicIndexOptions = {
6
- indexAtom: AtomToken<Set<string>>
7
- id: string
8
- }
9
-
10
- export const addToIndex: Write<(options: AtomicIndexOptions) => void> = (
11
- { set },
12
- { indexAtom, id },
13
- ): void => set(indexAtom, (currentSet) => new Set(currentSet).add(id))
14
-
15
- export const removeFromIndex: Write<(options: AtomicIndexOptions) => void> = (
16
- { set },
17
- { indexAtom, id },
18
- ): void =>
19
- set(indexAtom, (currentSet) => {
20
- const newSet = new Set(currentSet)
21
- newSet.delete(id)
22
- return newSet
23
- })
@@ -1,72 +0,0 @@
1
- import { Join } from "~/packages/anvl/src/join"
2
- import { parseJson, stringifyJson } from "~/packages/anvl/src/json"
3
- import { hasExactProperties } from "~/packages/anvl/src/object"
4
-
5
- import { persistStringSetAtom } from "./explorer-effects"
6
- import type { AtomToken, ReadonlySelectorFamily } from ".."
7
- import { SelectorFamily, selectorFamily } from ".."
8
- import type { AtomFamily } from "../atom"
9
- import { atom, atomFamily } from "../atom"
10
- import { lazyLocalStorageEffect, persistAtom } from "../web-effects"
11
-
12
- export const makeSpaceIndex = (key: string): AtomToken<Set<string>> =>
13
- atom<Set<string>>({
14
- key: `${key}:space_index`,
15
- default: new Set([`root`]),
16
- effects: [persistStringSetAtom(`${key}:space_index`)],
17
- })
18
-
19
- export const makeSpaceLayoutState = (
20
- key: string,
21
- ): AtomToken<Join<{ size: number }, `parent`, `child`>> =>
22
- atom({
23
- key: `${key}:space_layout`,
24
- default: new Join<{ size: number }>({ relationType: `1:n` })
25
- .from(`parent`)
26
- .to(`child`),
27
- effects: [
28
- persistAtom<Join<{ size: number }, `parent`, `child`>>(localStorage)({
29
- stringify: (join) => stringifyJson(join.toJSON()),
30
- parse: (string) => {
31
- try {
32
- const json = parseJson(string)
33
- const join = Join.fromJSON(json, {
34
- isContent: hasExactProperties({
35
- size: (v): v is number => typeof v === `number`,
36
- }),
37
- from: `parent`,
38
- to: `child`,
39
- })
40
- return join
41
- } catch (thrown) {
42
- console.error(`Error parsing spaceLayoutState from localStorage`)
43
- return new Join({ relationType: `1:n` })
44
- }
45
- },
46
- })(`${key}:space_layout`),
47
- ],
48
- })
49
-
50
- export const makeSpaceLayoutNodeFamily = (
51
- key: string,
52
- spaceLayoutState: AtomToken<Join<{ size: number }, `parent`, `child`>>,
53
- ): ReadonlySelectorFamily<{ childSpaceIds: string[]; size: number }, string> =>
54
- selectorFamily<{ childSpaceIds: string[]; size: number }, string>({
55
- key: `${key}:explorer_space`,
56
- get: (me) => ({ get }) => {
57
- const join = get(spaceLayoutState)
58
- const myFollowers = join.getRelatedIds(`parent:${me}`)
59
- const myLeader = join.getRelatedId(me)
60
- const { size } = myLeader
61
- ? join.getContent(myLeader, me) ?? { size: NaN }
62
- : { size: NaN }
63
- return { childSpaceIds: myFollowers, size }
64
- },
65
- })
66
-
67
- export const makeSpaceFamily = (key: string): AtomFamily<number, string> =>
68
- atomFamily<number, string>({
69
- key: `${key}:space`,
70
- default: 1,
71
- effects: (subKey) => [lazyLocalStorageEffect(`${key}:${subKey}`)],
72
- })
@@ -1,41 +0,0 @@
1
- import type { Location } from "react-router-dom"
2
-
3
- import { persistStringSetAtom } from "./explorer-effects"
4
- import type { AtomToken } from ".."
5
- import type { AtomFamily } from "../atom"
6
- import { atom, atomFamily } from "../atom"
7
- import { lazyLocalStorageEffect } from "../web-effects"
8
-
9
- export type View = {
10
- title: string
11
- location: Omit<Location, `state`>
12
- }
13
-
14
- export const makeViewFamily = (key: string): AtomFamily<View, string> =>
15
- atomFamily<View, string>({
16
- key: `${key}:view`,
17
- default: {
18
- title: ``,
19
- location: {
20
- pathname: ``,
21
- search: ``,
22
- hash: ``,
23
- key: ``,
24
- },
25
- },
26
- effects: (subKey) => [lazyLocalStorageEffect(`${key}:${subKey}`)],
27
- })
28
-
29
- export const makeViewIndex = (key: string): AtomToken<Set<string>> =>
30
- atom<Set<string>>({
31
- key: `${key}:view_index`,
32
- default: new Set(),
33
- effects: [persistStringSetAtom(`${key}:view_index`)],
34
- })
35
-
36
- export const makeViewFocusedFamily = (key: string): AtomFamily<number, string> =>
37
- atomFamily<number, string>({
38
- key: `${key}:view_focused`,
39
- default: 0,
40
- effects: (subKey) => [lazyLocalStorageEffect(`${key}:${subKey}`)],
41
- })
@@ -1,33 +0,0 @@
1
- # CLIENT ACTS AND REPORTS
2
- - [x] input event fires
3
- - [x] event handler runs transaction
4
- - [x] client store updates optimistically
5
- - [ ] on success
6
- - [ ] client generates transactionId and optimistic TransactionUpdate
7
- - [ ] client pushes TransactionUpdate to TimelineData.history
8
- - [ ] client sets TransactionUpdate in optimisticTransactions map by transactionId
9
- - [ ] client emits TransactionRequest { key, params, transactionId }
10
-
11
- # SERVER VALIDATES, INTEGRATES, AND BROADCASTS
12
- ## use
13
- - [x] server receives TransactionRequest
14
- - `{ key, params, transactionId }`
15
- - [ ] verify `transactionId` is unique
16
- - [ ] server adds timestamp to `TransactionRequest`
17
- - `{ key, params, transactionId, timestamp }`
18
- - [ ] server runs transaction, computing `TransactionUpdate` in the process
19
- - [ ] emit `TransactionUpdate`
20
- - `{ key, params, transactionId, timestamp, atomUpdates, output }`
21
- - [ ] server adds `TransactionUpdate` to TimelineData.history
22
-
23
- # CLIENT BEHOLDS AND REACTS
24
- - [ ] client receives official TransactionUpdate
25
- - [ ] client retrieves its own TransactionUpdate from optimisticTransactions map
26
- - [ ] client compares official and optimistic TransactionUpdates
27
- - [ ] (stringify atomUpdates and compare strict)
28
- - [ ] if match, client removes TransactionUpdate from optimisticTransactions map
29
- - [ ] if mismatch
30
- - [ ] client undoes timeline until it finds its own TransactionUpdate
31
- - [ ] client replaces its own TransactionUpdate with official TransactionUpdate
32
- - [ ] client removes its own TransactionUpdate from optimisticTransactions map
33
- - [ ] client redoes timeline until it reaches the "HEAD"
@@ -1,101 +0,0 @@
1
- import type { Json } from "anvl/json"
2
- import { parseJson } from "anvl/json"
3
- import * as AtomIO from "atom.io"
4
-
5
- import type { ServerConfig } from ".."
6
-
7
- const subscribeToTokenCreation = <T>(
8
- family: AtomIO.AtomFamily<T> | AtomIO.SelectorFamily<T>,
9
- handleTokenCreation: (token: AtomIO.StateToken<T>) => void,
10
- ): (() => void) => {
11
- const subscription =
12
- family.type === `atom_family`
13
- ? family.subject.subscribe(handleTokenCreation)
14
- : family.subject.subscribe(handleTokenCreation)
15
- return () => subscription.unsubscribe()
16
- }
17
-
18
- /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
19
- export const useExposeFamily = ({ socket, store }: ServerConfig) => {
20
- return function exposeFamily<J extends Json.Serializable>(
21
- family: AtomIO.AtomFamily<J> | AtomIO.SelectorFamily<J>,
22
- index: AtomIO.StateToken<Set<string>>,
23
- ): () => void {
24
- const unsubSingleCallbacksByKey = new Map<string, () => void>()
25
- const unsubFamilyCallbacksByKey = new Map<string, () => void>()
26
-
27
- const fillFamilyUnsubRequest = () => {
28
- unsubFamilyCallbacksByKey.forEach((unsub) => unsub())
29
- unsubFamilyCallbacksByKey.clear()
30
- socket.off(`unsub:${family.key}`, fillFamilyUnsubRequest)
31
- }
32
-
33
- const fillSingleUnsubRequest = (key: string) => {
34
- socket.off(`unsub:${key}`, fillSingleUnsubRequest)
35
- const unsub = unsubSingleCallbacksByKey.get(key)
36
- if (unsub) {
37
- unsub()
38
- unsubSingleCallbacksByKey.delete(key)
39
- }
40
- }
41
-
42
- const fillSubRequest = (subKey?: AtomIO.Json.Serializable) => {
43
- if (subKey === undefined) {
44
- const keys = AtomIO.getState(index, store)
45
- keys.forEach((key) => {
46
- const token = family(key)
47
- socket.emit(
48
- `serve:${family.key}`,
49
- parseJson(token.family?.subKey || `null`),
50
- AtomIO.getState(token, store),
51
- )
52
- })
53
-
54
- const unsubscribeFromTokenCreation = subscribeToTokenCreation(
55
- family,
56
- (token) => {
57
- const unsub = AtomIO.subscribe(
58
- token,
59
- ({ newValue }) => {
60
- socket.emit(
61
- `serve:${family.key}`,
62
- parseJson(token.family?.subKey || `null`),
63
- newValue,
64
- )
65
- },
66
- store,
67
- )
68
- unsubFamilyCallbacksByKey.set(token.key, unsub)
69
- },
70
- )
71
- unsubFamilyCallbacksByKey.set(family.key, unsubscribeFromTokenCreation)
72
-
73
- socket.on(`unsub:${family.key}`, fillFamilyUnsubRequest)
74
- } else {
75
- const token = family(subKey)
76
- socket.emit(`serve:${token.key}`, AtomIO.getState(token, store))
77
- const unsubscribe = AtomIO.subscribe(
78
- token,
79
- ({ newValue }) => {
80
- socket.emit(`serve:${token.key}`, newValue)
81
- },
82
- store,
83
- )
84
- unsubSingleCallbacksByKey.set(token.key, unsubscribe)
85
- socket.on(`unsub:${token.key}`, () => {
86
- fillSingleUnsubRequest(token.key)
87
- })
88
- }
89
- }
90
-
91
- socket.on(`sub:${family.key}`, fillSubRequest)
92
-
93
- return () => {
94
- socket.off(`sub:${family.key}`, fillSubRequest)
95
- unsubFamilyCallbacksByKey.forEach((unsub) => unsub())
96
- unsubSingleCallbacksByKey.forEach((unsub) => unsub())
97
- unsubFamilyCallbacksByKey.clear()
98
- unsubSingleCallbacksByKey.clear()
99
- }
100
- }
101
- }
@@ -1,38 +0,0 @@
1
- import type { Json } from "anvl/json"
2
- import * as AtomIO from "atom.io"
3
-
4
- import type { ServerConfig } from ".."
5
-
6
- /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
7
- export const useExposeSingle = ({ socket, store }: ServerConfig) => {
8
- return function exposeSingle<J extends Json.Serializable>(
9
- token: AtomIO.StateToken<J>,
10
- ): () => void {
11
- let unsubscribeFromStateUpdates: (() => void) | null = null
12
-
13
- const fillUnsubRequest = () => {
14
- socket.off(`unsub:${token.key}`, fillUnsubRequest)
15
- unsubscribeFromStateUpdates?.()
16
- unsubscribeFromStateUpdates = null
17
- }
18
-
19
- const fillSubRequest = () => {
20
- socket.emit(`serve:${token.key}`, AtomIO.getState(token, store))
21
- unsubscribeFromStateUpdates = AtomIO.subscribe(
22
- token,
23
- ({ newValue }) => {
24
- socket.emit(`serve:${token.key}`, newValue)
25
- },
26
- store,
27
- )
28
- socket.on(`unsub:${token.key}`, fillUnsubRequest)
29
- }
30
-
31
- socket.on(`sub:${token.key}`, fillSubRequest)
32
-
33
- return () => {
34
- socket.off(`sub:${token.key}`, fillSubRequest)
35
- unsubscribeFromStateUpdates?.()
36
- }
37
- }
38
- }
@@ -1,60 +0,0 @@
1
- import * as AtomIO from "atom.io"
2
-
3
- import { Join } from "~/packages/anvl/src/join"
4
-
5
- import type { ServerConfig } from "."
6
- import type { TimelineTransactionUpdate } from "../../internal"
7
-
8
- export type TransactionRequest = {
9
- key: string
10
- params: unknown[]
11
- transactionId: string
12
- }
13
-
14
- export const useExposeTimeline__UNSTABLE = ({
15
- socket,
16
- store,
17
- }: ServerConfig): ((tl: AtomIO.TimelineToken) => () => void) => {
18
- const timestampsOfTransactionsState = AtomIO.__INTERNAL__.atom__INTERNAL(
19
- {
20
- key: `timestampsOfTransactions`,
21
- default: new Join<null, `transactionId`, `timestamp`>({
22
- relationType: `1:1`,
23
- })
24
- .from(`transactionId`)
25
- .to(`timestamp`),
26
- },
27
- undefined,
28
- store,
29
- )
30
- return function exposeTimeline(tl: AtomIO.TimelineToken): () => void {
31
- const handleTransactionRequest = (update: TransactionRequest) => {
32
- AtomIO.runTransaction(
33
- { key: update.key, type: `transaction` },
34
- store,
35
- )(...update.params)
36
- }
37
-
38
- socket.on(`txr:${tl.key}`, handleTransactionRequest)
39
-
40
- const unsubscribeFromTimeline = AtomIO.subscribeToTimeline(
41
- tl,
42
- (update: TimelineTransactionUpdate) => {
43
- // const timestamp = update.timestamp.toString()
44
- // AtomIO.setState(
45
- // timestampsOfTransactionsState,
46
- // (j) => j.set(update),
47
- // store
48
- // )
49
- if (update.type === `transaction_update`) {
50
- socket.emit(`tl:${tl.key}`, update)
51
- }
52
- },
53
- )
54
-
55
- return () => {
56
- socket.off(`tlu:${tl.key}`, handleTransactionRequest)
57
- unsubscribeFromTimeline()
58
- }
59
- }
60
- }
@@ -1,12 +0,0 @@
1
- import type * as AtomIO from "atom.io"
2
- import type * as SocketIO from "socket.io"
3
-
4
- export * from "./expose-single"
5
- export * from "./expose-family"
6
- export * from "./receive-transaction"
7
- export * from "./receive-state"
8
-
9
- export type ServerConfig = {
10
- socket: SocketIO.Socket
11
- store?: AtomIO.__INTERNAL__.Store
12
- }
@@ -1,29 +0,0 @@
1
- import type { Json } from "anvl/json"
2
- import * as AtomIO from "atom.io"
3
-
4
- import type { ServerConfig } from ".."
5
-
6
- /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
7
- export const useReceiveState = ({ socket, store }: ServerConfig) => {
8
- return function receiveState<J extends Json.Serializable>(
9
- token: AtomIO.StateToken<J>,
10
- ): () => void {
11
- const publish = (newValue: J) => AtomIO.setState(token, newValue, store)
12
-
13
- const fillPubUnclaim = () => {
14
- socket.off(`pub:${token.key}`, publish)
15
- socket.off(`unclaim:${token.key}`, fillPubUnclaim)
16
- }
17
- const fillPubClaim = () => {
18
- socket.on(`pub:${token.key}`, publish)
19
- socket.on(`unclaim:${token.key}`, fillPubUnclaim)
20
- }
21
-
22
- socket.on(`claim:${token.key}`, fillPubClaim)
23
-
24
- return () => {
25
- socket.off(`claim:${token.key}`, fillPubClaim)
26
- socket.off(`pub:${token.key}`, publish)
27
- }
28
- }
29
- }
@@ -1,18 +0,0 @@
1
- import * as AtomIO from "atom.io"
2
-
3
- import type { ƒn } from "~/packages/anvl/src/function"
4
-
5
- import type { ServerConfig } from "."
6
-
7
- export const useReceiveTransaction = ({ socket, store }: ServerConfig) => {
8
- return function receiveTransaction<ƒ extends ƒn>(
9
- tx: AtomIO.TransactionToken<ƒ>,
10
- ): () => void {
11
- const fillTransactionRequest = (update: AtomIO.TransactionUpdate<ƒ>) =>
12
- AtomIO.runTransaction<ƒ>(tx, store)(...update.params)
13
-
14
- socket.on(`tx:${tx.key}`, fillTransactionRequest)
15
-
16
- return () => socket.off(`tx:${tx.key}`, fillTransactionRequest)
17
- }
18
- }
@@ -1 +0,0 @@
1
- export * from "./hook-composition"
@@ -1,3 +0,0 @@
1
- export * from "./realtime-context"
2
- export * from "./realtime-hooks"
3
- export * from "./realtime-state"
@@ -1,30 +0,0 @@
1
- import * as AR from "atom.io/react"
2
- import * as React from "react"
3
- import type { Socket } from "socket.io-client"
4
- import { io } from "socket.io-client"
5
-
6
- import { myIdState__INTERNAL } from "./realtime-state"
7
-
8
- export const RealtimeContext = React.createContext<{ socket: Socket }>({
9
- socket: io(),
10
- })
11
-
12
- export const RealtimeProvider: React.FC<{
13
- children: React.ReactNode
14
- socket: Socket
15
- }> = ({ children, socket }) => {
16
- const setMyId = AR.useI(myIdState__INTERNAL)
17
- React.useEffect(() => {
18
- socket.on(`connect`, () => {
19
- setMyId(socket.id)
20
- })
21
- socket.on(`disconnect`, () => {
22
- setMyId(null)
23
- })
24
- }, [socket, setMyId])
25
- return (
26
- <RealtimeContext.Provider value={{ socket }}>
27
- {children}
28
- </RealtimeContext.Provider>
29
- )
30
- }