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.
- package/README.md +21 -2
- package/dist/index.d.mts +42 -461
- package/dist/index.d.ts +42 -461
- package/dist/index.js +128 -1792
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +75 -1742
- package/dist/index.mjs.map +1 -1
- package/internal/dist/index.d.mts +342 -0
- package/internal/dist/index.d.ts +342 -0
- package/internal/dist/index.js +1873 -0
- package/internal/dist/index.js.map +1 -0
- package/internal/dist/index.mjs +1798 -0
- package/internal/dist/index.mjs.map +1 -0
- package/internal/package.json +15 -0
- package/internal/src/atom/create-atom.ts +75 -0
- package/internal/src/atom/delete-atom.ts +10 -0
- package/internal/src/atom/index.ts +3 -0
- package/{src/internal → internal/src/atom}/is-default.ts +4 -2
- package/internal/src/caching.ts +21 -0
- package/internal/src/families/create-atom-family.ts +59 -0
- package/internal/src/families/create-readonly-selector-family.ts +45 -0
- package/internal/src/families/create-selector-family.ts +67 -0
- package/internal/src/families/index.ts +3 -0
- package/internal/src/get-state-internal.ts +23 -0
- package/internal/src/index.ts +13 -0
- package/internal/src/mutable/create-mutable-atom-family.ts +25 -0
- package/internal/src/mutable/create-mutable-atom.ts +49 -0
- package/internal/src/mutable/get-json-token.ts +22 -0
- package/internal/src/mutable/get-update-token.ts +20 -0
- package/internal/src/mutable/index.ts +17 -0
- package/internal/src/mutable/is-atom-token-mutable.ts +7 -0
- package/internal/src/mutable/tracker-family.ts +61 -0
- package/internal/src/mutable/tracker.ts +164 -0
- package/internal/src/mutable/transceiver.ts +110 -0
- package/internal/src/operation.ts +68 -0
- package/{src/internal → internal/src}/selector/create-read-write-selector.ts +10 -13
- package/{src/internal → internal/src}/selector/create-readonly-selector.ts +9 -8
- package/internal/src/selector/create-selector.ts +65 -0
- package/{src/internal → internal/src}/selector/index.ts +1 -0
- package/internal/src/selector/lookup-selector-sources.ts +20 -0
- package/{src/internal → internal/src}/selector/register-selector.ts +13 -9
- package/{src/internal → internal/src}/selector/trace-selector-atoms.ts +4 -2
- package/{src/internal → internal/src}/selector/update-selector-atoms.ts +4 -3
- package/internal/src/set-state/become.ts +10 -0
- package/internal/src/set-state/copy-mutable-if-needed.ts +23 -0
- package/internal/src/set-state/copy-mutable-in-transaction.ts +59 -0
- package/internal/src/set-state/copy-mutable-into-new-store.ts +34 -0
- package/internal/src/set-state/emit-update.ts +23 -0
- package/internal/src/set-state/evict-downstream.ts +39 -0
- package/internal/src/set-state/index.ts +2 -0
- package/internal/src/set-state/set-atom-state.ts +38 -0
- package/internal/src/set-state/set-selector-state.ts +19 -0
- package/internal/src/set-state/set-state-internal.ts +18 -0
- package/internal/src/set-state/stow-update.ts +42 -0
- package/internal/src/store/deposit.ts +43 -0
- package/internal/src/store/index.ts +5 -0
- package/internal/src/store/lookup.ts +26 -0
- package/internal/src/store/store.ts +154 -0
- package/internal/src/store/withdraw-new-family-member.ts +53 -0
- package/internal/src/store/withdraw.ts +113 -0
- package/internal/src/subject.ts +21 -0
- package/internal/src/subscribe/index.ts +1 -0
- package/internal/src/subscribe/recall-state.ts +19 -0
- package/internal/src/subscribe/subscribe-to-root-atoms.ts +47 -0
- package/{src/internal → internal/src}/timeline/add-atom-to-timeline.ts +50 -29
- package/internal/src/timeline/index.ts +3 -0
- package/{src/internal → internal/src/timeline}/time-travel-internal.ts +6 -6
- package/{src/internal → internal/src/timeline}/timeline-internal.ts +20 -12
- package/{src/internal → internal/src}/transaction/abort-transaction.ts +1 -1
- package/{src/internal → internal/src}/transaction/apply-transaction.ts +25 -18
- package/{src/internal → internal/src}/transaction/build-transaction.ts +12 -6
- package/{src/internal → internal/src}/transaction/index.ts +3 -2
- package/{src/internal → internal/src}/transaction/redo-transaction.ts +4 -5
- package/{src/internal → internal/src/transaction}/transaction-internal.ts +16 -13
- package/{src/internal → internal/src}/transaction/undo-transaction.ts +4 -5
- package/introspection/dist/index.d.mts +12 -260
- package/introspection/dist/index.d.ts +12 -260
- package/introspection/dist/index.js +125 -140
- package/introspection/dist/index.js.map +1 -1
- package/introspection/dist/index.mjs +103 -116
- package/introspection/dist/index.mjs.map +1 -1
- package/{src/introspection → introspection/src}/attach-atom-index.ts +41 -30
- package/{src/introspection → introspection/src}/attach-introspection-states.ts +6 -10
- package/introspection/src/attach-selector-index.ts +90 -0
- package/{src/introspection → introspection/src}/attach-timeline-family.ts +16 -16
- package/introspection/src/attach-timeline-index.ts +38 -0
- package/introspection/src/attach-transaction-index.ts +40 -0
- package/{src/introspection → introspection/src}/attach-transaction-logs.ts +11 -8
- package/json/dist/index.d.mts +41 -2
- package/json/dist/index.d.ts +41 -2
- package/json/dist/index.js +88 -48
- package/json/dist/index.js.map +1 -1
- package/json/dist/index.mjs +76 -13
- package/json/dist/index.mjs.map +1 -1
- package/json/src/index.ts +5 -0
- package/json/src/select-json-family.ts +35 -0
- package/json/src/select-json.ts +22 -0
- package/package.json +105 -57
- package/react/dist/index.d.mts +9 -17
- package/react/dist/index.d.ts +9 -17
- package/react/dist/index.js +45 -77
- package/react/dist/index.js.map +1 -1
- package/react/dist/index.mjs +18 -34
- package/react/dist/index.mjs.map +1 -1
- package/react/src/store-context.tsx +12 -0
- package/react/src/store-hooks.ts +36 -0
- package/react-devtools/dist/index.css +1 -1
- package/react-devtools/dist/index.css.map +1 -1
- package/react-devtools/dist/index.d.mts +199 -230
- package/react-devtools/dist/index.d.ts +199 -230
- package/react-devtools/dist/index.js +610 -2466
- package/react-devtools/dist/index.js.map +1 -1
- package/react-devtools/dist/index.mjs +543 -2401
- package/react-devtools/dist/index.mjs.map +1 -1
- package/{src/react-devtools → react-devtools/src}/AtomIODevtools.tsx +5 -3
- package/{src/react-devtools → react-devtools/src}/Button.tsx +2 -3
- package/{src/react-devtools → react-devtools/src}/StateEditor.tsx +3 -2
- package/{src/react-devtools → react-devtools/src}/StateIndex.tsx +7 -4
- package/{src/react-devtools → react-devtools/src}/TimelineIndex.tsx +7 -11
- package/{src/react-devtools → react-devtools/src}/TransactionIndex.tsx +4 -4
- package/{src/react-devtools → react-devtools/src}/Updates.tsx +9 -4
- package/{src/react-devtools → react-devtools/src}/index.ts +5 -5
- package/realtime-react/dist/index.d.mts +9 -25
- package/realtime-react/dist/index.d.ts +9 -25
- package/realtime-react/dist/index.js +75 -193
- package/realtime-react/dist/index.js.map +1 -1
- package/realtime-react/dist/index.mjs +44 -148
- package/realtime-react/dist/index.mjs.map +1 -1
- package/realtime-react/src/index.ts +7 -0
- package/{src/realtime-react → realtime-react/src}/realtime-context.tsx +3 -4
- package/realtime-react/src/use-pull-family-member.ts +15 -0
- package/realtime-react/src/use-pull-mutable-family-member.ts +20 -0
- package/realtime-react/src/use-pull-mutable.ts +17 -0
- package/realtime-react/src/use-pull.ts +15 -0
- package/realtime-react/src/use-push.ts +19 -0
- package/realtime-react/src/use-server-action.ts +18 -0
- package/realtime-testing/dist/index.d.mts +49 -0
- package/realtime-testing/dist/index.d.ts +49 -0
- package/realtime-testing/dist/index.js +147 -0
- package/realtime-testing/dist/index.js.map +1 -0
- package/realtime-testing/dist/index.mjs +116 -0
- package/realtime-testing/dist/index.mjs.map +1 -0
- package/{src/realtime-testing → realtime-testing/src}/setup-realtime-test.tsx +10 -8
- package/src/atom.ts +64 -8
- package/src/index.ts +36 -29
- package/src/logger.ts +7 -7
- package/src/selector.ts +5 -5
- package/src/silo.ts +49 -43
- package/src/subscribe.ts +27 -22
- package/src/timeline.ts +9 -4
- package/src/transaction.ts +3 -4
- package/transceivers/set-rtx/dist/index.d.mts +39 -0
- package/transceivers/set-rtx/dist/index.d.ts +39 -0
- package/transceivers/set-rtx/dist/index.js +213 -0
- package/transceivers/set-rtx/dist/index.js.map +1 -0
- package/transceivers/set-rtx/dist/index.mjs +211 -0
- package/transceivers/set-rtx/dist/index.mjs.map +1 -0
- package/{realtime → transceivers/set-rtx}/package.json +1 -1
- package/transceivers/set-rtx/src/index.ts +1 -0
- package/transceivers/set-rtx/src/set-rtx.ts +242 -0
- package/realtime/dist/index.d.mts +0 -25
- package/realtime/dist/index.d.ts +0 -25
- package/realtime/dist/index.js +0 -190
- package/realtime/dist/index.js.map +0 -1
- package/realtime/dist/index.mjs +0 -151
- package/realtime/dist/index.mjs.map +0 -1
- package/src/internal/atom-internal.ts +0 -54
- package/src/internal/families-internal.ts +0 -144
- package/src/internal/get.ts +0 -129
- package/src/internal/index.ts +0 -15
- package/src/internal/operation.ts +0 -139
- package/src/internal/selector/lookup-selector-sources.ts +0 -16
- package/src/internal/selector-internal.ts +0 -58
- package/src/internal/set.ts +0 -99
- package/src/internal/store.ts +0 -151
- package/src/internal/subscribe-internal.ts +0 -88
- package/src/internal/timeline/index.ts +0 -1
- package/src/introspection/attach-selector-index.ts +0 -77
- package/src/introspection/attach-timeline-index.ts +0 -36
- package/src/introspection/attach-transaction-index.ts +0 -38
- package/src/json/index.ts +0 -1
- package/src/json/select-json.ts +0 -18
- package/src/react/store-context.tsx +0 -13
- package/src/react/store-hooks.ts +0 -47
- package/src/react-explorer/AtomIOExplorer.tsx +0 -218
- package/src/react-explorer/explorer-effects.ts +0 -20
- package/src/react-explorer/explorer-states.ts +0 -217
- package/src/react-explorer/index.ts +0 -23
- package/src/react-explorer/space-states.ts +0 -72
- package/src/react-explorer/view-states.ts +0 -41
- package/src/realtime/README.md +0 -33
- package/src/realtime/hook-composition/expose-family.ts +0 -101
- package/src/realtime/hook-composition/expose-single.ts +0 -38
- package/src/realtime/hook-composition/expose-timeline.ts +0 -60
- package/src/realtime/hook-composition/index.ts +0 -12
- package/src/realtime/hook-composition/receive-state.ts +0 -29
- package/src/realtime/hook-composition/receive-transaction.ts +0 -18
- package/src/realtime/index.ts +0 -1
- package/src/realtime-react/index.ts +0 -3
- package/src/realtime-react/realtime-hooks.ts +0 -39
- package/src/realtime-react/realtime-state.ts +0 -10
- package/src/realtime-react/use-pull-family-member.ts +0 -26
- package/src/realtime-react/use-pull-family.ts +0 -24
- package/src/realtime-react/use-pull.ts +0 -24
- package/src/realtime-react/use-push.ts +0 -27
- package/src/realtime-react/use-server-action.ts +0 -33
- package/src/tracker/index.ts +0 -3
- package/src/tracker/tracker.ts +0 -61
- package/src/web-effects/index.ts +0 -1
- package/src/web-effects/storage.ts +0 -30
- /package/{src/introspection → introspection/src}/index.ts +0 -0
- /package/{src/react → react/src}/index.ts +0 -0
- /package/{src/react-devtools → react-devtools/src}/devtools.scss +0 -0
- /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
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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 {
|
|
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
|
|
21
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
24
|
-
export type
|
|
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 =
|
|
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 =
|
|
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 {
|
|
1
|
+
import { IMPLICIT } from "atom.io/internal"
|
|
2
|
+
import type { Store } from "atom.io/internal"
|
|
2
3
|
|
|
3
|
-
|
|
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
|
-
//
|
|
25
|
-
store.config.logger![logLevel] =
|
|
24
|
+
// biome-ignore lint/style/noNonNullAssertion: we just set it
|
|
25
|
+
store.config.logger![logLevel] = NO_OP
|
|
26
26
|
} else {
|
|
27
|
-
//
|
|
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] !==
|
|
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 {
|
|
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
|
|
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
|
|
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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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 "
|
|
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
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
}
|