atom.io 0.6.8 → 0.7.0

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 (214) hide show
  1. package/README.md +21 -2
  2. package/dist/index.d.mts +42 -461
  3. package/dist/index.d.ts +42 -461
  4. package/dist/index.js +128 -1792
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +75 -1742
  7. package/dist/index.mjs.map +1 -1
  8. package/internal/dist/index.d.mts +342 -0
  9. package/internal/dist/index.d.ts +342 -0
  10. package/internal/dist/index.js +1873 -0
  11. package/internal/dist/index.js.map +1 -0
  12. package/internal/dist/index.mjs +1798 -0
  13. package/internal/dist/index.mjs.map +1 -0
  14. package/internal/package.json +15 -0
  15. package/internal/src/atom/create-atom.ts +75 -0
  16. package/internal/src/atom/delete-atom.ts +10 -0
  17. package/internal/src/atom/index.ts +3 -0
  18. package/{src/internal → internal/src/atom}/is-default.ts +4 -2
  19. package/internal/src/caching.ts +21 -0
  20. package/internal/src/families/create-atom-family.ts +59 -0
  21. package/internal/src/families/create-readonly-selector-family.ts +45 -0
  22. package/internal/src/families/create-selector-family.ts +67 -0
  23. package/internal/src/families/index.ts +3 -0
  24. package/internal/src/get-state-internal.ts +23 -0
  25. package/internal/src/index.ts +13 -0
  26. package/internal/src/mutable/create-mutable-atom-family.ts +25 -0
  27. package/internal/src/mutable/create-mutable-atom.ts +49 -0
  28. package/internal/src/mutable/get-json-token.ts +22 -0
  29. package/internal/src/mutable/get-update-token.ts +20 -0
  30. package/internal/src/mutable/index.ts +17 -0
  31. package/internal/src/mutable/is-atom-token-mutable.ts +7 -0
  32. package/internal/src/mutable/tracker-family.ts +61 -0
  33. package/internal/src/mutable/tracker.ts +164 -0
  34. package/internal/src/mutable/transceiver.ts +110 -0
  35. package/internal/src/operation.ts +68 -0
  36. package/{src/internal → internal/src}/selector/create-read-write-selector.ts +10 -13
  37. package/{src/internal → internal/src}/selector/create-readonly-selector.ts +9 -8
  38. package/internal/src/selector/create-selector.ts +65 -0
  39. package/{src/internal → internal/src}/selector/index.ts +1 -0
  40. package/internal/src/selector/lookup-selector-sources.ts +20 -0
  41. package/{src/internal → internal/src}/selector/register-selector.ts +13 -9
  42. package/{src/internal → internal/src}/selector/trace-selector-atoms.ts +4 -2
  43. package/{src/internal → internal/src}/selector/update-selector-atoms.ts +4 -3
  44. package/internal/src/set-state/become.ts +10 -0
  45. package/internal/src/set-state/copy-mutable-if-needed.ts +23 -0
  46. package/internal/src/set-state/copy-mutable-in-transaction.ts +59 -0
  47. package/internal/src/set-state/copy-mutable-into-new-store.ts +34 -0
  48. package/internal/src/set-state/emit-update.ts +23 -0
  49. package/internal/src/set-state/evict-downstream.ts +39 -0
  50. package/internal/src/set-state/index.ts +2 -0
  51. package/internal/src/set-state/set-atom-state.ts +38 -0
  52. package/internal/src/set-state/set-selector-state.ts +19 -0
  53. package/internal/src/set-state/set-state-internal.ts +18 -0
  54. package/internal/src/set-state/stow-update.ts +42 -0
  55. package/internal/src/store/deposit.ts +43 -0
  56. package/internal/src/store/index.ts +5 -0
  57. package/internal/src/store/lookup.ts +26 -0
  58. package/internal/src/store/store.ts +154 -0
  59. package/internal/src/store/withdraw-new-family-member.ts +53 -0
  60. package/internal/src/store/withdraw.ts +113 -0
  61. package/internal/src/subject.ts +21 -0
  62. package/internal/src/subscribe/index.ts +1 -0
  63. package/internal/src/subscribe/recall-state.ts +19 -0
  64. package/internal/src/subscribe/subscribe-to-root-atoms.ts +47 -0
  65. package/{src/internal → internal/src}/timeline/add-atom-to-timeline.ts +50 -29
  66. package/internal/src/timeline/index.ts +3 -0
  67. package/{src/internal → internal/src/timeline}/time-travel-internal.ts +6 -6
  68. package/{src/internal → internal/src/timeline}/timeline-internal.ts +20 -12
  69. package/{src/internal → internal/src}/transaction/abort-transaction.ts +1 -1
  70. package/{src/internal → internal/src}/transaction/apply-transaction.ts +25 -18
  71. package/{src/internal → internal/src}/transaction/build-transaction.ts +12 -6
  72. package/{src/internal → internal/src}/transaction/index.ts +3 -2
  73. package/{src/internal → internal/src}/transaction/redo-transaction.ts +4 -5
  74. package/{src/internal → internal/src/transaction}/transaction-internal.ts +16 -13
  75. package/{src/internal → internal/src}/transaction/undo-transaction.ts +4 -5
  76. package/introspection/dist/index.d.mts +12 -260
  77. package/introspection/dist/index.d.ts +12 -260
  78. package/introspection/dist/index.js +125 -140
  79. package/introspection/dist/index.js.map +1 -1
  80. package/introspection/dist/index.mjs +103 -116
  81. package/introspection/dist/index.mjs.map +1 -1
  82. package/{src/introspection → introspection/src}/attach-atom-index.ts +41 -30
  83. package/{src/introspection → introspection/src}/attach-introspection-states.ts +6 -10
  84. package/introspection/src/attach-selector-index.ts +90 -0
  85. package/{src/introspection → introspection/src}/attach-timeline-family.ts +16 -16
  86. package/introspection/src/attach-timeline-index.ts +38 -0
  87. package/introspection/src/attach-transaction-index.ts +40 -0
  88. package/{src/introspection → introspection/src}/attach-transaction-logs.ts +11 -8
  89. package/json/dist/index.d.mts +41 -2
  90. package/json/dist/index.d.ts +41 -2
  91. package/json/dist/index.js +88 -48
  92. package/json/dist/index.js.map +1 -1
  93. package/json/dist/index.mjs +76 -13
  94. package/json/dist/index.mjs.map +1 -1
  95. package/json/src/index.ts +5 -0
  96. package/json/src/select-json-family.ts +35 -0
  97. package/json/src/select-json.ts +22 -0
  98. package/package.json +105 -57
  99. package/react/dist/index.d.mts +9 -17
  100. package/react/dist/index.d.ts +9 -17
  101. package/react/dist/index.js +45 -77
  102. package/react/dist/index.js.map +1 -1
  103. package/react/dist/index.mjs +18 -34
  104. package/react/dist/index.mjs.map +1 -1
  105. package/react/src/store-context.tsx +12 -0
  106. package/react/src/store-hooks.ts +36 -0
  107. package/react-devtools/dist/index.css +1 -1
  108. package/react-devtools/dist/index.css.map +1 -1
  109. package/react-devtools/dist/index.d.mts +199 -230
  110. package/react-devtools/dist/index.d.ts +199 -230
  111. package/react-devtools/dist/index.js +610 -2466
  112. package/react-devtools/dist/index.js.map +1 -1
  113. package/react-devtools/dist/index.mjs +543 -2401
  114. package/react-devtools/dist/index.mjs.map +1 -1
  115. package/{src/react-devtools → react-devtools/src}/AtomIODevtools.tsx +5 -3
  116. package/{src/react-devtools → react-devtools/src}/Button.tsx +2 -3
  117. package/{src/react-devtools → react-devtools/src}/StateEditor.tsx +3 -2
  118. package/{src/react-devtools → react-devtools/src}/StateIndex.tsx +7 -4
  119. package/{src/react-devtools → react-devtools/src}/TimelineIndex.tsx +7 -11
  120. package/{src/react-devtools → react-devtools/src}/TransactionIndex.tsx +4 -4
  121. package/{src/react-devtools → react-devtools/src}/Updates.tsx +9 -4
  122. package/{src/react-devtools → react-devtools/src}/index.ts +5 -5
  123. package/realtime-react/dist/index.d.mts +9 -25
  124. package/realtime-react/dist/index.d.ts +9 -25
  125. package/realtime-react/dist/index.js +75 -193
  126. package/realtime-react/dist/index.js.map +1 -1
  127. package/realtime-react/dist/index.mjs +44 -148
  128. package/realtime-react/dist/index.mjs.map +1 -1
  129. package/realtime-react/src/index.ts +7 -0
  130. package/{src/realtime-react → realtime-react/src}/realtime-context.tsx +3 -4
  131. package/realtime-react/src/use-pull-family-member.ts +15 -0
  132. package/realtime-react/src/use-pull-mutable-family-member.ts +20 -0
  133. package/realtime-react/src/use-pull-mutable.ts +17 -0
  134. package/realtime-react/src/use-pull.ts +15 -0
  135. package/realtime-react/src/use-push.ts +19 -0
  136. package/realtime-react/src/use-server-action.ts +18 -0
  137. package/realtime-testing/dist/index.d.mts +49 -0
  138. package/realtime-testing/dist/index.d.ts +49 -0
  139. package/realtime-testing/dist/index.js +147 -0
  140. package/realtime-testing/dist/index.js.map +1 -0
  141. package/realtime-testing/dist/index.mjs +116 -0
  142. package/realtime-testing/dist/index.mjs.map +1 -0
  143. package/{src/realtime-testing → realtime-testing/src}/setup-realtime-test.tsx +10 -8
  144. package/src/atom.ts +64 -8
  145. package/src/index.ts +36 -29
  146. package/src/logger.ts +7 -7
  147. package/src/selector.ts +5 -5
  148. package/src/silo.ts +49 -43
  149. package/src/subscribe.ts +27 -22
  150. package/src/timeline.ts +9 -4
  151. package/src/transaction.ts +3 -4
  152. package/transceivers/set-rtx/dist/index.d.mts +39 -0
  153. package/transceivers/set-rtx/dist/index.d.ts +39 -0
  154. package/transceivers/set-rtx/dist/index.js +213 -0
  155. package/transceivers/set-rtx/dist/index.js.map +1 -0
  156. package/transceivers/set-rtx/dist/index.mjs +211 -0
  157. package/transceivers/set-rtx/dist/index.mjs.map +1 -0
  158. package/{realtime → transceivers/set-rtx}/package.json +1 -1
  159. package/transceivers/set-rtx/src/index.ts +1 -0
  160. package/transceivers/set-rtx/src/set-rtx.ts +242 -0
  161. package/realtime/dist/index.d.mts +0 -25
  162. package/realtime/dist/index.d.ts +0 -25
  163. package/realtime/dist/index.js +0 -190
  164. package/realtime/dist/index.js.map +0 -1
  165. package/realtime/dist/index.mjs +0 -151
  166. package/realtime/dist/index.mjs.map +0 -1
  167. package/src/internal/atom-internal.ts +0 -54
  168. package/src/internal/families-internal.ts +0 -144
  169. package/src/internal/get.ts +0 -129
  170. package/src/internal/index.ts +0 -15
  171. package/src/internal/operation.ts +0 -139
  172. package/src/internal/selector/lookup-selector-sources.ts +0 -16
  173. package/src/internal/selector-internal.ts +0 -58
  174. package/src/internal/set.ts +0 -99
  175. package/src/internal/store.ts +0 -151
  176. package/src/internal/subscribe-internal.ts +0 -88
  177. package/src/internal/timeline/index.ts +0 -1
  178. package/src/introspection/attach-selector-index.ts +0 -77
  179. package/src/introspection/attach-timeline-index.ts +0 -36
  180. package/src/introspection/attach-transaction-index.ts +0 -38
  181. package/src/json/index.ts +0 -1
  182. package/src/json/select-json.ts +0 -18
  183. package/src/react/store-context.tsx +0 -13
  184. package/src/react/store-hooks.ts +0 -47
  185. package/src/react-explorer/AtomIOExplorer.tsx +0 -218
  186. package/src/react-explorer/explorer-effects.ts +0 -20
  187. package/src/react-explorer/explorer-states.ts +0 -217
  188. package/src/react-explorer/index.ts +0 -23
  189. package/src/react-explorer/space-states.ts +0 -72
  190. package/src/react-explorer/view-states.ts +0 -41
  191. package/src/realtime/README.md +0 -33
  192. package/src/realtime/hook-composition/expose-family.ts +0 -101
  193. package/src/realtime/hook-composition/expose-single.ts +0 -38
  194. package/src/realtime/hook-composition/expose-timeline.ts +0 -60
  195. package/src/realtime/hook-composition/index.ts +0 -12
  196. package/src/realtime/hook-composition/receive-state.ts +0 -29
  197. package/src/realtime/hook-composition/receive-transaction.ts +0 -18
  198. package/src/realtime/index.ts +0 -1
  199. package/src/realtime-react/index.ts +0 -3
  200. package/src/realtime-react/realtime-hooks.ts +0 -39
  201. package/src/realtime-react/realtime-state.ts +0 -10
  202. package/src/realtime-react/use-pull-family-member.ts +0 -26
  203. package/src/realtime-react/use-pull-family.ts +0 -24
  204. package/src/realtime-react/use-pull.ts +0 -24
  205. package/src/realtime-react/use-push.ts +0 -27
  206. package/src/realtime-react/use-server-action.ts +0 -33
  207. package/src/tracker/index.ts +0 -3
  208. package/src/tracker/tracker.ts +0 -61
  209. package/src/web-effects/index.ts +0 -1
  210. package/src/web-effects/storage.ts +0 -30
  211. /package/{src/introspection → introspection/src}/index.ts +0 -0
  212. /package/{src/react → react/src}/index.ts +0 -0
  213. /package/{src/react-devtools → react-devtools/src}/devtools.scss +0 -0
  214. /package/{src/realtime-testing → realtime-testing/src}/index.ts +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/setup-realtime-test.tsx","../../../anvl/src/object/entries.ts"],"names":["clients"],"mappings":"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","sourcesContent":["import * as http from \"http\"\n\nimport { type RenderResult, prettyDOM, render } from \"@testing-library/react\"\nimport * as AtomIO from \"atom.io\"\nimport * as Internal from \"atom.io/internal\"\nimport * as AR from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-react\"\nimport * as Happy from \"happy-dom\"\nimport * as React from \"react\"\nimport * as SocketIO from \"socket.io\"\nimport type { Socket as ClientSocket } from \"socket.io-client\"\nimport { io } from \"socket.io-client\"\n\nimport { recordToEntries } from \"~/packages/anvl/src/object\"\n\nexport type TestSetupOptions = {\n\tserver: (tools: { socket: SocketIO.Socket; silo: AtomIO.Silo }) => void\n}\nexport type TestSetupOptions__SingleClient = TestSetupOptions & {\n\tclient: React.FC\n}\nexport type TestSetupOptions__MultiClient<ClientNames extends string> =\n\tTestSetupOptions & {\n\t\tclients: {\n\t\t\t[K in ClientNames]: React.FC\n\t\t}\n\t}\n\nexport type RealtimeTestTools = {\n\tname: string\n\tsilo: AtomIO.Silo\n\tdispose: () => void\n}\nexport type RealtimeTestClient = RealtimeTestTools & {\n\trenderResult: RenderResult\n\tprettyPrint: () => void\n\treconnect: () => void\n\tdisconnect: () => void\n}\nexport type RealtimeTestServer = RealtimeTestTools & {\n\tport: number\n}\n\nexport type RealtimeTestAPI = {\n\tserver: RealtimeTestServer\n\tteardown: () => void\n}\nexport type RealtimeTestAPI__SingleClient = RealtimeTestAPI & {\n\tclient: RealtimeTestClient\n}\nexport type RealtimeTestAPI__MultiClient<ClientNames extends string> =\n\tRealtimeTestAPI & {\n\t\tclients: Record<ClientNames, RealtimeTestClient>\n\t}\n\nexport const setupRealtimeTestServer = (\n\toptions: TestSetupOptions,\n): RealtimeTestServer => {\n\tconst httpServer = http.createServer((_, res) => res.end(`Hello World!`))\n\tconst address = httpServer.listen().address()\n\tconst port =\n\t\ttypeof address === `string` ? 80 : address === null ? null : address.port\n\tif (port === null) throw new Error(`Could not determine port for test server`)\n\tconst server = new SocketIO.Server(httpServer)\n\tconst silo = new AtomIO.Silo(`SERVER`, Internal.IMPLICIT.STORE)\n\n\tserver.on(`connection`, (socket: SocketIO.Socket) => {\n\t\toptions.server({ socket, silo })\n\t})\n\n\tconst dispose = () => {\n\t\tserver.close()\n\t\tInternal.clearStore(silo.store)\n\t}\n\n\treturn {\n\t\tname: `SERVER`,\n\t\tsilo,\n\t\tdispose,\n\t\tport,\n\t}\n}\nexport const setupRealtimeTestClient = (\n\toptions: TestSetupOptions__SingleClient,\n\tname: string,\n\tport: number,\n): RealtimeTestClient => {\n\tconst socket: ClientSocket = io(`http://localhost:${port}/`)\n\tconst silo = new AtomIO.Silo(name, Internal.IMPLICIT.STORE)\n\n\tconst { document } = new Happy.Window()\n\tdocument.body.innerHTML = `<div id=\"app\"></div>`\n\tconst renderResult = render(\n\t\t<AR.StoreProvider store={silo.store}>\n\t\t\t<RTC.RealtimeProvider socket={socket}>\n\t\t\t\t<options.client />\n\t\t\t</RTC.RealtimeProvider>\n\t\t</AR.StoreProvider>,\n\t\t{\n\t\t\tcontainer: document.querySelector(`#app`) as unknown as HTMLElement,\n\t\t},\n\t)\n\n\tconst prettyPrint = () => console.log(prettyDOM(renderResult.container))\n\n\tconst disconnect = () => socket.disconnect()\n\tconst reconnect = () => socket.connect()\n\n\tconst dispose = () => {\n\t\tsocket.disconnect()\n\t\tInternal.clearStore(silo.store)\n\t}\n\n\treturn {\n\t\tname,\n\t\tsilo,\n\t\trenderResult,\n\t\tprettyPrint,\n\t\tdisconnect,\n\t\treconnect,\n\t\tdispose,\n\t}\n}\n\nexport const singleClient = (\n\toptions: TestSetupOptions__SingleClient,\n): RealtimeTestAPI__SingleClient => {\n\tconst server = setupRealtimeTestServer(options)\n\tconst client = setupRealtimeTestClient(options, `CLIENT`, server.port)\n\n\treturn {\n\t\tclient,\n\t\tserver,\n\t\tteardown: () => {\n\t\t\tclient.dispose()\n\t\t\tserver.dispose()\n\t\t},\n\t}\n}\n\nexport const multiClient = <ClientNames extends string>(\n\toptions: TestSetupOptions__MultiClient<ClientNames>,\n): RealtimeTestAPI__MultiClient<ClientNames> => {\n\tconst server = setupRealtimeTestServer(options)\n\tconst clients = recordToEntries(options.clients).reduce(\n\t\t(clients, [name, client]) => ({\n\t\t\t...clients,\n\t\t\t[name]: setupRealtimeTestClient({ ...options, client }, name, server.port),\n\t\t}),\n\t\t{} as Record<ClientNames, RealtimeTestClient>,\n\t)\n\n\treturn {\n\t\tclients,\n\t\tserver,\n\t\tteardown: () => {\n\t\t\trecordToEntries(clients).forEach(([, client]) => client.dispose())\n\t\t\tserver.dispose()\n\t\t},\n\t}\n}\n","export type Entries<K extends keyof any, V> = [key: K, value: V][]\n\nexport const recordToEntries = <K extends keyof any, V>(\n\tobj: Record<K, V>,\n): Entries<K, V> => Object.entries(obj) as Entries<K, V>\n\nexport const entriesToRecord = <K extends keyof any, V>(\n\tentries: Entries<K, V>,\n): Record<K, V> => Object.fromEntries(entries) as Record<K, V>\n"]}
@@ -0,0 +1,116 @@
1
+ import * as http from 'http';
2
+ import { render, prettyDOM } from '@testing-library/react';
3
+ import * as AtomIO from 'atom.io';
4
+ import * as Internal from 'atom.io/internal';
5
+ import * as AR from 'atom.io/react';
6
+ import * as RTC from 'atom.io/realtime-react';
7
+ import * as Happy from 'happy-dom';
8
+ import * as SocketIO from 'socket.io';
9
+ import { io } from 'socket.io-client';
10
+ import { jsx } from 'react/jsx-runtime';
11
+
12
+ var __defProp = Object.defineProperty;
13
+ var __defProps = Object.defineProperties;
14
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
15
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
16
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
17
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
18
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
19
+ var __spreadValues = (a, b) => {
20
+ for (var prop in b || (b = {}))
21
+ if (__hasOwnProp.call(b, prop))
22
+ __defNormalProp(a, prop, b[prop]);
23
+ if (__getOwnPropSymbols)
24
+ for (var prop of __getOwnPropSymbols(b)) {
25
+ if (__propIsEnum.call(b, prop))
26
+ __defNormalProp(a, prop, b[prop]);
27
+ }
28
+ return a;
29
+ };
30
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
31
+
32
+ // ../../anvl/src/object/entries.ts
33
+ var recordToEntries = (obj) => Object.entries(obj);
34
+ var setupRealtimeTestServer = (options) => {
35
+ const httpServer = http.createServer((_, res) => res.end(`Hello World!`));
36
+ const address = httpServer.listen().address();
37
+ const port = typeof address === `string` ? 80 : address === null ? null : address.port;
38
+ if (port === null)
39
+ throw new Error(`Could not determine port for test server`);
40
+ const server = new SocketIO.Server(httpServer);
41
+ const silo = new AtomIO.Silo(`SERVER`, Internal.IMPLICIT.STORE);
42
+ server.on(`connection`, (socket) => {
43
+ options.server({ socket, silo });
44
+ });
45
+ const dispose = () => {
46
+ server.close();
47
+ Internal.clearStore(silo.store);
48
+ };
49
+ return {
50
+ name: `SERVER`,
51
+ silo,
52
+ dispose,
53
+ port
54
+ };
55
+ };
56
+ var setupRealtimeTestClient = (options, name, port) => {
57
+ const socket = io(`http://localhost:${port}/`);
58
+ const silo = new AtomIO.Silo(name, Internal.IMPLICIT.STORE);
59
+ const { document } = new Happy.Window();
60
+ document.body.innerHTML = `<div id="app"></div>`;
61
+ const renderResult = render(
62
+ /* @__PURE__ */ jsx(AR.StoreProvider, { store: silo.store, children: /* @__PURE__ */ jsx(RTC.RealtimeProvider, { socket, children: /* @__PURE__ */ jsx(options.client, {}) }) }),
63
+ {
64
+ container: document.querySelector(`#app`)
65
+ }
66
+ );
67
+ const prettyPrint = () => console.log(prettyDOM(renderResult.container));
68
+ const disconnect = () => socket.disconnect();
69
+ const reconnect = () => socket.connect();
70
+ const dispose = () => {
71
+ socket.disconnect();
72
+ Internal.clearStore(silo.store);
73
+ };
74
+ return {
75
+ name,
76
+ silo,
77
+ renderResult,
78
+ prettyPrint,
79
+ disconnect,
80
+ reconnect,
81
+ dispose
82
+ };
83
+ };
84
+ var singleClient = (options) => {
85
+ const server = setupRealtimeTestServer(options);
86
+ const client = setupRealtimeTestClient(options, `CLIENT`, server.port);
87
+ return {
88
+ client,
89
+ server,
90
+ teardown: () => {
91
+ client.dispose();
92
+ server.dispose();
93
+ }
94
+ };
95
+ };
96
+ var multiClient = (options) => {
97
+ const server = setupRealtimeTestServer(options);
98
+ const clients = recordToEntries(options.clients).reduce(
99
+ (clients2, [name, client]) => __spreadProps(__spreadValues({}, clients2), {
100
+ [name]: setupRealtimeTestClient(__spreadProps(__spreadValues({}, options), { client }), name, server.port)
101
+ }),
102
+ {}
103
+ );
104
+ return {
105
+ clients,
106
+ server,
107
+ teardown: () => {
108
+ recordToEntries(clients).forEach(([, client]) => client.dispose());
109
+ server.dispose();
110
+ }
111
+ };
112
+ };
113
+
114
+ export { multiClient, setupRealtimeTestClient, setupRealtimeTestServer, singleClient };
115
+ //# sourceMappingURL=out.js.map
116
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/setup-realtime-test.tsx","../../../anvl/src/object/entries.ts"],"names":["clients"],"mappings":"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","sourcesContent":["import * as http from \"http\"\n\nimport { type RenderResult, prettyDOM, render } from \"@testing-library/react\"\nimport * as AtomIO from \"atom.io\"\nimport * as Internal from \"atom.io/internal\"\nimport * as AR from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-react\"\nimport * as Happy from \"happy-dom\"\nimport * as React from \"react\"\nimport * as SocketIO from \"socket.io\"\nimport type { Socket as ClientSocket } from \"socket.io-client\"\nimport { io } from \"socket.io-client\"\n\nimport { recordToEntries } from \"~/packages/anvl/src/object\"\n\nexport type TestSetupOptions = {\n\tserver: (tools: { socket: SocketIO.Socket; silo: AtomIO.Silo }) => void\n}\nexport type TestSetupOptions__SingleClient = TestSetupOptions & {\n\tclient: React.FC\n}\nexport type TestSetupOptions__MultiClient<ClientNames extends string> =\n\tTestSetupOptions & {\n\t\tclients: {\n\t\t\t[K in ClientNames]: React.FC\n\t\t}\n\t}\n\nexport type RealtimeTestTools = {\n\tname: string\n\tsilo: AtomIO.Silo\n\tdispose: () => void\n}\nexport type RealtimeTestClient = RealtimeTestTools & {\n\trenderResult: RenderResult\n\tprettyPrint: () => void\n\treconnect: () => void\n\tdisconnect: () => void\n}\nexport type RealtimeTestServer = RealtimeTestTools & {\n\tport: number\n}\n\nexport type RealtimeTestAPI = {\n\tserver: RealtimeTestServer\n\tteardown: () => void\n}\nexport type RealtimeTestAPI__SingleClient = RealtimeTestAPI & {\n\tclient: RealtimeTestClient\n}\nexport type RealtimeTestAPI__MultiClient<ClientNames extends string> =\n\tRealtimeTestAPI & {\n\t\tclients: Record<ClientNames, RealtimeTestClient>\n\t}\n\nexport const setupRealtimeTestServer = (\n\toptions: TestSetupOptions,\n): RealtimeTestServer => {\n\tconst httpServer = http.createServer((_, res) => res.end(`Hello World!`))\n\tconst address = httpServer.listen().address()\n\tconst port =\n\t\ttypeof address === `string` ? 80 : address === null ? null : address.port\n\tif (port === null) throw new Error(`Could not determine port for test server`)\n\tconst server = new SocketIO.Server(httpServer)\n\tconst silo = new AtomIO.Silo(`SERVER`, Internal.IMPLICIT.STORE)\n\n\tserver.on(`connection`, (socket: SocketIO.Socket) => {\n\t\toptions.server({ socket, silo })\n\t})\n\n\tconst dispose = () => {\n\t\tserver.close()\n\t\tInternal.clearStore(silo.store)\n\t}\n\n\treturn {\n\t\tname: `SERVER`,\n\t\tsilo,\n\t\tdispose,\n\t\tport,\n\t}\n}\nexport const setupRealtimeTestClient = (\n\toptions: TestSetupOptions__SingleClient,\n\tname: string,\n\tport: number,\n): RealtimeTestClient => {\n\tconst socket: ClientSocket = io(`http://localhost:${port}/`)\n\tconst silo = new AtomIO.Silo(name, Internal.IMPLICIT.STORE)\n\n\tconst { document } = new Happy.Window()\n\tdocument.body.innerHTML = `<div id=\"app\"></div>`\n\tconst renderResult = render(\n\t\t<AR.StoreProvider store={silo.store}>\n\t\t\t<RTC.RealtimeProvider socket={socket}>\n\t\t\t\t<options.client />\n\t\t\t</RTC.RealtimeProvider>\n\t\t</AR.StoreProvider>,\n\t\t{\n\t\t\tcontainer: document.querySelector(`#app`) as unknown as HTMLElement,\n\t\t},\n\t)\n\n\tconst prettyPrint = () => console.log(prettyDOM(renderResult.container))\n\n\tconst disconnect = () => socket.disconnect()\n\tconst reconnect = () => socket.connect()\n\n\tconst dispose = () => {\n\t\tsocket.disconnect()\n\t\tInternal.clearStore(silo.store)\n\t}\n\n\treturn {\n\t\tname,\n\t\tsilo,\n\t\trenderResult,\n\t\tprettyPrint,\n\t\tdisconnect,\n\t\treconnect,\n\t\tdispose,\n\t}\n}\n\nexport const singleClient = (\n\toptions: TestSetupOptions__SingleClient,\n): RealtimeTestAPI__SingleClient => {\n\tconst server = setupRealtimeTestServer(options)\n\tconst client = setupRealtimeTestClient(options, `CLIENT`, server.port)\n\n\treturn {\n\t\tclient,\n\t\tserver,\n\t\tteardown: () => {\n\t\t\tclient.dispose()\n\t\t\tserver.dispose()\n\t\t},\n\t}\n}\n\nexport const multiClient = <ClientNames extends string>(\n\toptions: TestSetupOptions__MultiClient<ClientNames>,\n): RealtimeTestAPI__MultiClient<ClientNames> => {\n\tconst server = setupRealtimeTestServer(options)\n\tconst clients = recordToEntries(options.clients).reduce(\n\t\t(clients, [name, client]) => ({\n\t\t\t...clients,\n\t\t\t[name]: setupRealtimeTestClient({ ...options, client }, name, server.port),\n\t\t}),\n\t\t{} as Record<ClientNames, RealtimeTestClient>,\n\t)\n\n\treturn {\n\t\tclients,\n\t\tserver,\n\t\tteardown: () => {\n\t\t\trecordToEntries(clients).forEach(([, client]) => client.dispose())\n\t\t\tserver.dispose()\n\t\t},\n\t}\n}\n","export type Entries<K extends keyof any, V> = [key: K, value: V][]\n\nexport const recordToEntries = <K extends keyof any, V>(\n\tobj: Record<K, V>,\n): Entries<K, V> => Object.entries(obj) as Entries<K, V>\n\nexport const entriesToRecord = <K extends keyof any, V>(\n\tentries: Entries<K, V>,\n): Record<K, V> => Object.fromEntries(entries) as Record<K, V>\n"]}
@@ -1,16 +1,18 @@
1
1
  import * as http from "http"
2
2
 
3
- import { prettyDOM, render, type RenderResult } from "@testing-library/react"
3
+ import { type RenderResult, prettyDOM, render } from "@testing-library/react"
4
4
  import * as AtomIO from "atom.io"
5
+ import * as Internal from "atom.io/internal"
5
6
  import * as AR from "atom.io/react"
6
7
  import * as RTC from "atom.io/realtime-react"
7
- import * as RR from "fp-ts/ReadonlyRecord"
8
8
  import * as Happy from "happy-dom"
9
9
  import * as React from "react"
10
10
  import * as SocketIO from "socket.io"
11
11
  import type { Socket as ClientSocket } from "socket.io-client"
12
12
  import { io } from "socket.io-client"
13
13
 
14
+ import { recordToEntries } from "~/packages/anvl/src/object"
15
+
14
16
  export type TestSetupOptions = {
15
17
  server: (tools: { socket: SocketIO.Socket; silo: AtomIO.Silo }) => void
16
18
  }
@@ -60,7 +62,7 @@ export const setupRealtimeTestServer = (
60
62
  typeof address === `string` ? 80 : address === null ? null : address.port
61
63
  if (port === null) throw new Error(`Could not determine port for test server`)
62
64
  const server = new SocketIO.Server(httpServer)
63
- const silo = AtomIO.silo(`SERVER`, AtomIO.__INTERNAL__.IMPLICIT.STORE)
65
+ const silo = new AtomIO.Silo(`SERVER`, Internal.IMPLICIT.STORE)
64
66
 
65
67
  server.on(`connection`, (socket: SocketIO.Socket) => {
66
68
  options.server({ socket, silo })
@@ -68,7 +70,7 @@ export const setupRealtimeTestServer = (
68
70
 
69
71
  const dispose = () => {
70
72
  server.close()
71
- AtomIO.__INTERNAL__.clearStore(silo.store)
73
+ Internal.clearStore(silo.store)
72
74
  }
73
75
 
74
76
  return {
@@ -84,7 +86,7 @@ export const setupRealtimeTestClient = (
84
86
  port: number,
85
87
  ): RealtimeTestClient => {
86
88
  const socket: ClientSocket = io(`http://localhost:${port}/`)
87
- const silo = AtomIO.silo(name, AtomIO.__INTERNAL__.IMPLICIT.STORE)
89
+ const silo = new AtomIO.Silo(name, Internal.IMPLICIT.STORE)
88
90
 
89
91
  const { document } = new Happy.Window()
90
92
  document.body.innerHTML = `<div id="app"></div>`
@@ -106,7 +108,7 @@ export const setupRealtimeTestClient = (
106
108
 
107
109
  const dispose = () => {
108
110
  socket.disconnect()
109
- AtomIO.__INTERNAL__.clearStore(silo.store)
111
+ Internal.clearStore(silo.store)
110
112
  }
111
113
 
112
114
  return {
@@ -140,7 +142,7 @@ export const multiClient = <ClientNames extends string>(
140
142
  options: TestSetupOptions__MultiClient<ClientNames>,
141
143
  ): RealtimeTestAPI__MultiClient<ClientNames> => {
142
144
  const server = setupRealtimeTestServer(options)
143
- const clients = RR.toEntries(options.clients).reduce(
145
+ const clients = recordToEntries(options.clients).reduce(
144
146
  (clients, [name, client]) => ({
145
147
  ...clients,
146
148
  [name]: setupRealtimeTestClient({ ...options, client }, name, server.port),
@@ -152,7 +154,7 @@ export const multiClient = <ClientNames extends string>(
152
154
  clients,
153
155
  server,
154
156
  teardown: () => {
155
- RR.toEntries(clients).forEach(([, client]) => client.dispose())
157
+ recordToEntries(clients).forEach(([, client]) => client.dispose())
156
158
  server.dispose()
157
159
  },
158
160
  }
package/src/atom.ts CHANGED
@@ -1,8 +1,13 @@
1
- import type { Json } from "~/packages/anvl/src/json"
1
+ import type { Subject, Transceiver } from "atom.io/internal"
2
+ import {
3
+ createAtom,
4
+ createAtomFamily,
5
+ createMutableAtom,
6
+ createMutableAtomFamily,
7
+ } from "atom.io/internal"
8
+ import type { Json, JsonInterface } from "atom.io/json"
2
9
 
3
- import type { AtomToken } from "."
4
- import type { Subject } from "./internal"
5
- import { atomFamily__INTERNAL, atom__INTERNAL } from "./internal"
10
+ import type { AtomToken, MutableAtomToken } from "."
6
11
 
7
12
  export type Effectors<T> = {
8
13
  setSelf: <V extends T>(next: V | ((oldValue: T) => V)) => void
@@ -16,9 +21,26 @@ export type AtomOptions<T> = {
16
21
  default: T | (() => T)
17
22
  effects?: AtomEffect<T>[]
18
23
  }
24
+ // biome-ignore format: complex intersection
25
+ export type MutableAtomOptions<T extends Transceiver<any>, J extends Json.Serializable> =
26
+ & JsonInterface<T, J>
27
+ & Omit<AtomOptions<T>, `default`>
28
+ & {
29
+ default: () => T
30
+ mutable: true
31
+ }
19
32
 
20
- export function atom<T>(options: AtomOptions<T>): AtomToken<T> {
21
- return atom__INTERNAL<T>(options)
33
+ export function atom<T extends Transceiver<any>, J extends Json.Serializable>(
34
+ options: MutableAtomOptions<T, J>,
35
+ ): MutableAtomToken<T, J>
36
+ export function atom<T>(options: AtomOptions<T>): AtomToken<T>
37
+ export function atom<T>(
38
+ options: AtomOptions<any> | MutableAtomOptions<any, any>,
39
+ ): AtomToken<any> {
40
+ if (`mutable` in options) {
41
+ return createMutableAtom(options)
42
+ }
43
+ return createAtom<T>(options)
22
44
  }
23
45
 
24
46
  export type AtomFamilyOptions<T, K extends Json.Serializable> = {
@@ -34,9 +56,43 @@ export type AtomFamily<T, K extends Json.Serializable = Json.Serializable> = ((
34
56
  type: `atom_family`
35
57
  subject: Subject<AtomToken<T>>
36
58
  }
59
+ // biome-ignore format: intersection
60
+ export type MutableAtomFamilyOptions<
61
+ T extends Transceiver<any>,
62
+ J extends Json.Serializable,
63
+ K extends Json.Serializable,
64
+ > =
65
+ & AtomFamilyOptions<T, K>
66
+ & JsonInterface<T, J>
67
+ & { mutable: true }
37
68
 
69
+ // biome-ignore format: intersection
70
+ export type MutableAtomFamily<
71
+ Core extends Transceiver<any>,
72
+ SerializableCore extends Json.Serializable,
73
+ Key extends Json.Serializable,
74
+ > =
75
+ & JsonInterface<Core, SerializableCore>
76
+ & ((key: Key) => MutableAtomToken<Core, SerializableCore>)
77
+ & {
78
+ key: `${string}::mutable`
79
+ type: `atom_family`
80
+ subject: Subject<MutableAtomToken<Core, SerializableCore>>
81
+ }
82
+
83
+ export function atomFamily<
84
+ T extends Transceiver<any>,
85
+ J extends Json.Serializable,
86
+ K extends Json.Serializable,
87
+ >(options: MutableAtomFamilyOptions<T, J, K>): MutableAtomFamily<T, J, K>
38
88
  export function atomFamily<T, K extends Json.Serializable>(
39
89
  options: AtomFamilyOptions<T, K>,
40
- ): AtomFamily<T, K> {
41
- return atomFamily__INTERNAL<T, K>(options)
90
+ ): AtomFamily<T, K>
91
+ export function atomFamily<T, K extends Json.Serializable>(
92
+ options: AtomFamilyOptions<T, K> | MutableAtomFamilyOptions<any, any, any>,
93
+ ): AtomFamily<T, K> | MutableAtomFamily<any, any, any> {
94
+ if (`mutable` in options) {
95
+ return createMutableAtomFamily(options)
96
+ }
97
+ return createAtomFamily<T, K>(options)
42
98
  }
package/src/index.ts CHANGED
@@ -1,28 +1,23 @@
1
- import { capitalize } from "~/packages/anvl/src/string/capitalize"
2
-
3
- import {
4
- IMPLICIT,
5
- closeOperation,
6
- openOperation,
7
- getState__INTERNAL,
8
- setState__INTERNAL,
9
- isAtomDefault,
10
- isSelectorDefault,
11
- withdraw,
12
- } from "./internal"
13
- import * as __INTERNAL__ from "./internal"
14
- import type { Store } from "./internal/store"
1
+ import * as IO from "atom.io/internal"
2
+ import type { Store, Transceiver } from "atom.io/internal"
3
+ import type { Json } from "atom.io/json"
15
4
 
16
5
  export * from "./atom"
17
6
  export * from "./logger"
18
7
  export * from "./selector"
19
8
  export * from "./silo"
20
- export * from "./subscribe"
9
+ export {
10
+ subscribe,
11
+ subscribeToTimeline,
12
+ subscribeToTransaction,
13
+ KeyedStateUpdate,
14
+ StateUpdate,
15
+ UpdateHandler,
16
+ } from "./subscribe"
21
17
  export * from "./timeline"
22
18
  export * from "./transaction"
23
- export { __INTERNAL__ }
24
- export type { Store } from "./internal/store"
25
- export type { Json } from "~/packages/anvl/src/json"
19
+
20
+ export type ƒn = (...parameters: any[]) => any
26
21
 
27
22
  export type AtomToken<_> = {
28
23
  key: string
@@ -30,6 +25,13 @@ export type AtomToken<_> = {
30
25
  family?: FamilyMetadata
31
26
  __brand?: _
32
27
  }
28
+ export interface MutableAtomToken<
29
+ T extends Transceiver<any>,
30
+ J extends Json.Serializable,
31
+ > extends AtomToken<T> {
32
+ __asJSON?: J
33
+ __update?: T extends Transceiver<infer Update> ? Update : never
34
+ }
33
35
  export type SelectorToken<_> = {
34
36
  key: string
35
37
  type: `selector`
@@ -50,11 +52,15 @@ export type FamilyMetadata = {
50
52
  subKey: string
51
53
  }
52
54
 
55
+ export const capitalize = (str: string): string =>
56
+ str[0].toUpperCase() + str.slice(1)
57
+
53
58
  export const getState = <T>(
54
59
  token: ReadonlySelectorToken<T> | StateToken<T>,
55
- store: Store = IMPLICIT.STORE,
60
+ store: Store = IO.IMPLICIT.STORE,
56
61
  ): T => {
57
- const state = withdraw<T>(token, store)
62
+ const state =
63
+ IO.withdraw(token, store) ?? IO.withdrawNewFamilyMember(token, store)
58
64
  if (state === null) {
59
65
  throw new Error(
60
66
  `${capitalize(token.type)} "${token.key}" not found in store "${
@@ -62,23 +68,24 @@ export const getState = <T>(
62
68
  }".`,
63
69
  )
64
70
  }
65
- return getState__INTERNAL(state, store)
71
+ return IO.getState__INTERNAL(state, store)
66
72
  }
67
73
 
68
74
  export const setState = <T, New extends T>(
69
75
  token: StateToken<T>,
70
76
  value: New | ((oldValue: T) => New),
71
- store: Store = IMPLICIT.STORE,
77
+ store: Store = IO.IMPLICIT.STORE,
72
78
  ): void => {
73
79
  try {
74
- openOperation(token, store)
80
+ IO.openOperation(token, store)
75
81
  } catch (thrown) {
76
82
  if (!(typeof thrown === `symbol`)) {
77
83
  throw thrown
78
84
  }
79
85
  return
80
86
  }
81
- const state = withdraw(token, store)
87
+ const state =
88
+ IO.withdraw(token, store) ?? IO.withdrawNewFamilyMember(token, store)
82
89
  if (state === null) {
83
90
  throw new Error(
84
91
  `${capitalize(token.type)} "${token.key}" not found in store "${
@@ -86,14 +93,14 @@ export const setState = <T, New extends T>(
86
93
  }".`,
87
94
  )
88
95
  }
89
- setState__INTERNAL(state, value, store)
90
- closeOperation(store)
96
+ IO.setState__INTERNAL(state, value, store)
97
+ IO.closeOperation(store)
91
98
  }
92
99
 
93
100
  export const isDefault = (
94
101
  token: ReadonlySelectorToken<unknown> | StateToken<unknown>,
95
- store: Store = IMPLICIT.STORE,
102
+ store: Store = IO.IMPLICIT.STORE,
96
103
  ): boolean =>
97
104
  token.type === `atom`
98
- ? isAtomDefault(token.key, store)
99
- : isSelectorDefault(token.key, store)
105
+ ? IO.isAtomDefault(token.key, store)
106
+ : IO.isSelectorDefault(token.key, store)
package/src/logger.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { doNothing } from "~/packages/anvl/src/function"
1
+ import { IMPLICIT } from "atom.io/internal"
2
+ import type { Store } from "atom.io/internal"
2
3
 
3
- import type { Store } from "./internal/store"
4
- import { IMPLICIT } from "./internal/store"
4
+ export const NO_OP = (): void => undefined
5
5
 
6
6
  export type Logger = Pick<Console, `error` | `info` | `warn`>
7
7
  export const LOG_LEVELS: ReadonlyArray<keyof Logger> = [
@@ -21,10 +21,10 @@ export const setLogLevel = (
21
21
  store.config.logger = { ...console }
22
22
  LOG_LEVELS.forEach((logLevel) => {
23
23
  if (LOG_LEVELS.indexOf(logLevel) < LOG_LEVELS.indexOf(preferredLevel)) {
24
- // rome-ignore lint/style/noNonNullAssertion: we just set it
25
- store.config.logger![logLevel] = doNothing
24
+ // biome-ignore lint/style/noNonNullAssertion: we just set it
25
+ store.config.logger![logLevel] = NO_OP
26
26
  } else {
27
- // rome-ignore lint/style/noNonNullAssertion: we just set it
27
+ // biome-ignore lint/style/noNonNullAssertion: we just set it
28
28
  store.config.logger![logLevel] = logger__INTERNAL[logLevel]
29
29
  }
30
30
  })
@@ -39,7 +39,7 @@ export const useLogger = (
39
39
  store.config.logger === null
40
40
  ? null
41
41
  : LOG_LEVELS.find(
42
- (logLevel) => store.config.logger?.[logLevel] !== doNothing,
42
+ (logLevel) => store.config.logger?.[logLevel] !== NO_OP,
43
43
  ) ?? null
44
44
  store.config.logger__INTERNAL = { ...logger }
45
45
  setLogLevel(currentLogLevel, store)
package/src/selector.ts CHANGED
@@ -1,8 +1,8 @@
1
- import type { Json } from "~/packages/anvl/src/json"
1
+ import type { Subject } from "atom.io/internal"
2
+ import { createSelector, createSelectorFamily } from "atom.io/internal"
3
+ import type { Json } from "atom.io/json"
2
4
 
3
5
  import type { ReadonlySelectorToken, SelectorToken } from "."
4
- import type { Subject } from "./internal"
5
- import { selectorFamily__INTERNAL, selector__INTERNAL } from "./internal"
6
6
  import type { Read, Write } from "./transaction"
7
7
 
8
8
  export type SelectorOptions<T> = {
@@ -22,7 +22,7 @@ export function selector<T>(
22
22
  export function selector<T>(
23
23
  options: ReadonlySelectorOptions<T> | SelectorOptions<T>,
24
24
  ): ReadonlySelectorToken<T> | SelectorToken<T> {
25
- return selector__INTERNAL(options)
25
+ return createSelector(options)
26
26
  }
27
27
 
28
28
  export type SelectorFamilyOptions<T, K extends Json.Serializable> = {
@@ -62,5 +62,5 @@ export function selectorFamily<T, K extends Json.Serializable>(
62
62
  export function selectorFamily<T, K extends Json.Serializable>(
63
63
  options: ReadonlySelectorFamilyOptions<T, K> | SelectorFamilyOptions<T, K>,
64
64
  ): ReadonlySelectorFamily<T, K> | SelectorFamily<T, K> {
65
- return selectorFamily__INTERNAL(options)
65
+ return createSelectorFamily(options)
66
66
  }
package/src/silo.ts CHANGED
@@ -1,53 +1,59 @@
1
- import type { redo, timeline, undo } from "."
2
- import { getState, setState, subscribe } from "."
3
- import type { atom, atomFamily } from "./atom"
4
- import type { Store } from "./internal"
5
1
  import {
6
- atomFamily__INTERNAL,
7
- atom__INTERNAL,
8
- createStore,
2
+ Store,
3
+ createAtom,
4
+ createAtomFamily,
5
+ createMutableAtom,
6
+ createMutableAtomFamily,
7
+ createSelector,
8
+ createSelectorFamily,
9
9
  redo__INTERNAL,
10
- selectorFamily__INTERNAL,
11
- selector__INTERNAL,
12
10
  timeline__INTERNAL,
13
11
  transaction__INTERNAL,
14
12
  undo__INTERNAL,
15
- } from "./internal"
13
+ } from "atom.io/internal"
14
+
15
+ import type { redo, timeline, undo } from "."
16
+ import { getState, setState, subscribe } from "."
17
+ import type { atom, atomFamily } from "./atom"
16
18
  import type { selector, selectorFamily } from "./selector"
17
19
  import type { transaction } from "./transaction"
18
20
 
19
- export type Silo = ReturnType<typeof silo>
20
-
21
- export const silo = (
22
- name: string,
23
- fromStore: Store | null = null,
24
- ): {
25
- store: Store
26
- atom: typeof atom
27
- atomFamily: typeof atomFamily
28
- selector: typeof selector
29
- selectorFamily: typeof selectorFamily
30
- transaction: typeof transaction
31
- timeline: typeof timeline
32
- getState: typeof getState
33
- setState: typeof setState
34
- subscribe: typeof subscribe
35
- undo: typeof undo
36
- redo: typeof redo
37
- } => {
38
- const store = createStore(name, fromStore)
39
- return {
40
- store,
41
- atom: (options) => atom__INTERNAL(options, undefined, store),
42
- atomFamily: (options) => atomFamily__INTERNAL(options, store),
43
- selector: (options) => selector__INTERNAL(options, undefined, store) as any,
44
- selectorFamily: (options) => selectorFamily__INTERNAL(options, store) as any,
45
- transaction: (options) => transaction__INTERNAL(options, store),
46
- timeline: (options) => timeline__INTERNAL(options, store),
47
- getState: (token) => getState(token, store),
48
- setState: (token, newValue) => setState(token, newValue, store),
49
- subscribe: (token, handler) => subscribe(token, handler, store),
50
- undo: (token) => undo__INTERNAL(token, store),
51
- redo: (token) => redo__INTERNAL(token, store),
21
+ export class Silo {
22
+ public store: Store
23
+ public atom: typeof atom
24
+ public atomFamily: typeof atomFamily
25
+ public selector: typeof selector
26
+ public selectorFamily: typeof selectorFamily
27
+ public transaction: typeof transaction
28
+ public timeline: typeof timeline
29
+ public getState: typeof getState
30
+ public setState: typeof setState
31
+ public subscribe: typeof subscribe
32
+ public undo: typeof undo
33
+ public redo: typeof redo
34
+ public constructor(name: string, fromStore: Store | null = null) {
35
+ const s = new Store(name, fromStore)
36
+ this.store = s
37
+ this.atom = (options) => {
38
+ if (`mutable` in options) {
39
+ return createMutableAtom(options, s)
40
+ }
41
+ return createAtom(options, undefined, s)
42
+ }
43
+ this.atomFamily = (options) => {
44
+ if (`mutable` in options) {
45
+ return createMutableAtomFamily(options, s) as any
46
+ }
47
+ return createAtomFamily(options, s)
48
+ }
49
+ this.selector = (options) => createSelector(options, undefined, s) as any
50
+ this.selectorFamily = (options) => createSelectorFamily(options, s) as any
51
+ this.transaction = (options) => transaction__INTERNAL(options, s)
52
+ this.timeline = (options) => timeline__INTERNAL(options, s)
53
+ this.getState = (token) => getState(token, s)
54
+ this.setState = (token, newValue) => setState(token, newValue, s)
55
+ this.subscribe = (token, handler, key) => subscribe(token, handler, key, s)
56
+ this.undo = (token) => undo__INTERNAL(token, s)
57
+ this.redo = (token) => redo__INTERNAL(token, s)
52
58
  }
53
59
  }