atom.io 0.6.7 → 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 (129) hide show
  1. package/dist/index.d.mts +241 -263
  2. package/dist/index.d.ts +241 -263
  3. package/dist/index.js +28 -1911
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +5 -1871
  6. package/dist/index.mjs.map +1 -1
  7. package/introspection/dist/index.d.mts +121 -176
  8. package/introspection/dist/index.d.ts +121 -176
  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 +37 -8
  14. package/json/dist/index.d.ts +37 -8
  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 +30 -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 -42
  25. package/react-devtools/dist/index.css.map +1 -1
  26. package/react-devtools/dist/index.d.mts +128 -193
  27. package/react-devtools/dist/index.d.ts +128 -193
  28. package/react-devtools/dist/index.js +56 -4154
  29. package/react-devtools/dist/index.js.map +1 -1
  30. package/react-devtools/dist/index.mjs +19 -4117
  31. package/react-devtools/dist/index.mjs.map +1 -1
  32. package/realtime/dist/index.d.mts +7 -11
  33. package/realtime/dist/index.d.ts +7 -11
  34. package/realtime/dist/index.js +26 -185
  35. package/realtime/dist/index.js.map +1 -1
  36. package/realtime/dist/index.mjs +4 -149
  37. package/realtime/dist/index.mjs.map +1 -1
  38. package/realtime-react/dist/index.d.mts +12 -16
  39. package/realtime-react/dist/index.d.ts +12 -16
  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 +7 -6
  45. package/src/index.ts +12 -9
  46. package/src/logger.ts +5 -5
  47. package/src/selector.ts +16 -14
  48. package/src/silo.ts +36 -39
  49. package/src/subscribe.ts +25 -20
  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 -141
  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 -66
  59. package/src/internal/selector/create-readonly-selector.ts +0 -46
  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/subject.ts +0 -24
  69. package/src/internal/subscribe-internal.ts +0 -88
  70. package/src/internal/time-travel-internal.ts +0 -91
  71. package/src/internal/timeline/add-atom-to-timeline.ts +0 -168
  72. package/src/internal/timeline/index.ts +0 -1
  73. package/src/internal/timeline-internal.ts +0 -107
  74. package/src/internal/transaction/abort-transaction.ts +0 -12
  75. package/src/internal/transaction/apply-transaction.ts +0 -57
  76. package/src/internal/transaction/build-transaction.ts +0 -33
  77. package/src/internal/transaction/index.ts +0 -25
  78. package/src/internal/transaction/redo-transaction.ts +0 -23
  79. package/src/internal/transaction/undo-transaction.ts +0 -23
  80. package/src/internal/transaction-internal.ts +0 -61
  81. package/src/introspection/attach-atom-index.ts +0 -73
  82. package/src/introspection/attach-introspection-states.ts +0 -42
  83. package/src/introspection/attach-selector-index.ts +0 -77
  84. package/src/introspection/attach-timeline-family.ts +0 -59
  85. package/src/introspection/attach-timeline-index.ts +0 -36
  86. package/src/introspection/attach-transaction-index.ts +0 -38
  87. package/src/introspection/attach-transaction-logs.ts +0 -40
  88. package/src/introspection/index.ts +0 -20
  89. package/src/json/index.ts +0 -1
  90. package/src/json/select-json.ts +0 -18
  91. package/src/react/index.ts +0 -2
  92. package/src/react/store-context.tsx +0 -13
  93. package/src/react/store-hooks.ts +0 -47
  94. package/src/react-devtools/AtomIODevtools.tsx +0 -107
  95. package/src/react-devtools/Button.tsx +0 -24
  96. package/src/react-devtools/StateEditor.tsx +0 -70
  97. package/src/react-devtools/StateIndex.tsx +0 -153
  98. package/src/react-devtools/TimelineIndex.tsx +0 -92
  99. package/src/react-devtools/TransactionIndex.tsx +0 -70
  100. package/src/react-devtools/Updates.tsx +0 -145
  101. package/src/react-devtools/devtools.scss +0 -311
  102. package/src/react-devtools/index.ts +0 -72
  103. package/src/react-explorer/AtomIOExplorer.tsx +0 -218
  104. package/src/react-explorer/explorer-effects.ts +0 -20
  105. package/src/react-explorer/explorer-states.ts +0 -217
  106. package/src/react-explorer/index.ts +0 -23
  107. package/src/react-explorer/space-states.ts +0 -72
  108. package/src/react-explorer/view-states.ts +0 -41
  109. package/src/realtime/README.md +0 -33
  110. package/src/realtime/hook-composition/expose-family.ts +0 -101
  111. package/src/realtime/hook-composition/expose-single.ts +0 -38
  112. package/src/realtime/hook-composition/expose-timeline.ts +0 -60
  113. package/src/realtime/hook-composition/index.ts +0 -12
  114. package/src/realtime/hook-composition/receive-state.ts +0 -29
  115. package/src/realtime/hook-composition/receive-transaction.ts +0 -18
  116. package/src/realtime/index.ts +0 -1
  117. package/src/realtime-react/index.ts +0 -3
  118. package/src/realtime-react/realtime-context.tsx +0 -30
  119. package/src/realtime-react/realtime-hooks.ts +0 -39
  120. package/src/realtime-react/realtime-state.ts +0 -10
  121. package/src/realtime-react/use-pull-family-member.ts +0 -26
  122. package/src/realtime-react/use-pull-family.ts +0 -24
  123. package/src/realtime-react/use-pull.ts +0 -22
  124. package/src/realtime-react/use-push.ts +0 -25
  125. package/src/realtime-react/use-server-action.ts +0 -33
  126. package/src/realtime-testing/index.ts +0 -1
  127. package/src/realtime-testing/setup-realtime-test.tsx +0 -159
  128. package/src/web-effects/index.ts +0 -1
  129. package/src/web-effects/storage.ts +0 -30
@@ -1,218 +0,0 @@
1
- import type { StoreHooks } from "atom.io/react"
2
- import type { FC, ReactNode } from "react"
3
- import { useEffect } from "react"
4
- import { Link, MemoryRouter, useLocation } from "react-router-dom"
5
-
6
- import { RecoverableErrorBoundary } from "~/packages/hamr/src/react-error-boundary"
7
- import type { WC } from "~/packages/hamr/src/react-json-editor"
8
-
9
- import { attachExplorerState } from "./explorer-states"
10
- import { setState } from ".."
11
- import { runTransaction } from "../transaction"
12
-
13
- export type ExplorerOptions = {
14
- key: string
15
- Components?: {
16
- SpaceWrapper: WC
17
- CloseSpaceButton: FC<{ onClick: () => void }>
18
- }
19
- storeHooks: StoreHooks
20
- }
21
-
22
- const DEFAULT_COMPONENTS: ExplorerOptions[`Components`] = {
23
- SpaceWrapper: ({ children }) => <div>{children}</div>,
24
- CloseSpaceButton: ({ onClick }) => (
25
- <button type="button" onClick={onClick}>
26
- X
27
- </button>
28
- ),
29
- }
30
-
31
- export const composeExplorer = ({
32
- key,
33
- Components,
34
- storeHooks: { useO, useIO },
35
- }: ExplorerOptions): ReturnType<typeof attachExplorerState> & {
36
- Explorer: FC<{ children: ReactNode }>
37
- useSetTitle: (viewId: string) => void
38
- } => {
39
- const { SpaceWrapper, CloseSpaceButton } = {
40
- ...DEFAULT_COMPONENTS,
41
- ...Components,
42
- }
43
-
44
- const state = attachExplorerState(key)
45
-
46
- const {
47
- addSpace,
48
- addView,
49
- allViewsState,
50
- findSpaceFocusedViewState,
51
- findSpaceLayoutNode,
52
- findSpaceViewsState,
53
- findViewFocusedState,
54
- findViewState,
55
- removeSpace,
56
- removeView,
57
- spaceLayoutState,
58
- viewIndexState,
59
- } = state
60
-
61
- const View: FC<{
62
- children: ReactNode
63
- viewId: string
64
- }> = ({ children, viewId }) => {
65
- const location = useLocation()
66
- const viewState = findViewState(viewId)
67
- const [view, setView] = useIO(viewState)
68
- useEffect(() => {
69
- setView((view) => ({ ...view, location }))
70
- }, [location.key])
71
- return (
72
- <div className="view">
73
- <header>
74
- <h1>{view.title}</h1>
75
- <CloseSpaceButton onClick={() => runTransaction(removeView)(viewId)} />
76
- </header>
77
- <main>{children}</main>
78
- <footer>
79
- <nav>
80
- {location.pathname.split(`/`).map((pathPiece, idx, array) =>
81
- pathPiece === `` && idx === 1 ? null : (
82
- <Link
83
- to={array.slice(0, idx + 1).join(`/`)}
84
- key={`${pathPiece}_${viewId}`}
85
- >
86
- {idx === 0 ? `home` : pathPiece}/
87
- </Link>
88
- ),
89
- )}
90
- </nav>
91
- </footer>
92
- </div>
93
- )
94
- }
95
-
96
- const Tab: FC<{ viewId: string; spaceId: string }> = ({ viewId, spaceId }) => {
97
- const view = useO(findViewState(viewId))
98
- const [spaceFocusedView, setSpaceFocusedView] = useIO(
99
- findSpaceFocusedViewState(spaceId),
100
- )
101
- const handleClick = () => setSpaceFocusedView(viewId)
102
- return (
103
- <div
104
- className={`tab ${spaceFocusedView === viewId ? `focused` : ``}`}
105
- onClick={handleClick}
106
- onKeyUp={handleClick}
107
- >
108
- {view.title}
109
- </div>
110
- )
111
- }
112
-
113
- const TabBar: FC<{
114
- spaceId: string
115
- viewIds: string[]
116
- }> = ({ spaceId, viewIds }) => {
117
- return (
118
- <nav className="tab-bar">
119
- {viewIds.map((viewId) => (
120
- <Tab key={viewId} viewId={viewId} spaceId={spaceId} />
121
- ))}
122
- </nav>
123
- )
124
- }
125
-
126
- const Space: FC<{
127
- children: ReactNode
128
- focusedViewId: string
129
- spaceId: string
130
- viewIds: string[]
131
- }> = ({ children, focusedViewId, spaceId, viewIds }) => {
132
- const view = useO(findViewState(focusedViewId))
133
- return (
134
- <div className="space">
135
- <RecoverableErrorBoundary>
136
- <MemoryRouter
137
- initialEntries={view.location ? [view.location.pathname] : []}
138
- >
139
- <TabBar spaceId={spaceId} viewIds={viewIds} />
140
- <View viewId={focusedViewId}>{children}</View>
141
- </MemoryRouter>
142
- </RecoverableErrorBoundary>
143
- </div>
144
- )
145
- }
146
-
147
- const Spaces: FC<{ children: ReactNode; spaceId?: string }> = ({
148
- children,
149
- spaceId = `root`,
150
- }) => {
151
- const spaceLayout = useO(findSpaceLayoutNode(spaceId))
152
- const viewIds = useO(findSpaceViewsState(spaceId))
153
- const focusedViewId = useO(findSpaceFocusedViewState(spaceId))
154
- return (
155
- <div className="spaces">
156
- {spaceLayout.childSpaceIds.length === 0 ? (
157
- focusedViewId ? (
158
- <Space
159
- focusedViewId={focusedViewId}
160
- spaceId={spaceId}
161
- viewIds={viewIds}
162
- >
163
- {children}
164
- </Space>
165
- ) : (
166
- `no view`
167
- )
168
- ) : (
169
- spaceLayout.childSpaceIds.map((childSpaceId) => (
170
- <Spaces key={childSpaceId} spaceId={childSpaceId}>
171
- {children}
172
- </Spaces>
173
- ))
174
- )}
175
- <button
176
- type="button"
177
- onClick={() => runTransaction(addView)({ spaceId })}
178
- >
179
- + View
180
- </button>
181
- <button
182
- type="button"
183
- onClick={() => runTransaction(addSpace)({ parentId: spaceId })}
184
- >
185
- + Space
186
- </button>
187
- </div>
188
- )
189
- }
190
-
191
- const Explorer: FC<{ children: ReactNode }> = ({ children }) => {
192
- return <Spaces>{children}</Spaces>
193
- }
194
-
195
- const useSetTitle = (title: string): void => {
196
- let location: ReturnType<typeof useLocation>
197
- try {
198
- location = useLocation()
199
- } catch (thrown) {
200
- console.warn(
201
- `Failed to set title to "${title}"; useSetTitle must be called within the children of Explorer`,
202
- )
203
- return
204
- }
205
- const views = useO(allViewsState)
206
- const locationView = views.find(
207
- ([, view]) => view.location.key === location.key,
208
- )
209
- const viewId = locationView?.[0] ?? null
210
- useEffect(() => {
211
- if (viewId) {
212
- setState(findViewState(viewId), (v) => ({ ...v, title }))
213
- }
214
- }, [viewId])
215
- }
216
-
217
- return { Explorer, useSetTitle, ...state }
218
- }
@@ -1,20 +0,0 @@
1
- import { isArray } from "~/packages/anvl/src/array"
2
- import { parseJson, stringifyJson } from "~/packages/anvl/src/json"
3
-
4
- import { persistAtom } from "../web-effects"
5
-
6
- export const persistStringSetAtom = persistAtom<Set<string>>(localStorage)({
7
- stringify: (set) => stringifyJson([...set]),
8
- parse: (string) => {
9
- try {
10
- const json = parseJson(string)
11
- const array = isArray((v): v is string => typeof v === `string`)(json)
12
- ? json
13
- : []
14
- return new Set(array)
15
- } catch (thrown) {
16
- console.error(`Error parsing spaceIndexState from localStorage`)
17
- return new Set()
18
- }
19
- },
20
- })
@@ -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"