atom.io 0.6.2 → 0.6.4

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