atom.io 0.5.0 → 0.6.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/dist/index.d.mts +82 -66
- package/dist/index.d.ts +82 -66
- package/dist/index.js +482 -360
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +481 -360
- package/dist/index.mjs.map +1 -1
- package/json/dist/index.js.map +1 -1
- package/json/dist/index.mjs.map +1 -1
- package/package.json +12 -5
- package/react/dist/index.d.mts +18 -11
- package/react/dist/index.d.ts +18 -11
- package/react/dist/index.js +45 -21
- package/react/dist/index.js.map +1 -1
- package/react/dist/index.mjs +31 -21
- package/react/dist/index.mjs.map +1 -1
- package/react-devtools/dist/index.d.mts +4 -4
- package/react-devtools/dist/index.d.ts +4 -4
- package/react-devtools/dist/index.js.map +1 -1
- package/react-devtools/dist/index.mjs.map +1 -1
- package/realtime/dist/index.d.mts +3 -1
- package/realtime/dist/index.d.ts +3 -1
- package/realtime/dist/index.js +23 -0
- package/realtime/dist/index.js.map +1 -1
- package/realtime/dist/index.mjs +22 -0
- package/realtime/dist/index.mjs.map +1 -1
- package/realtime-react/dist/index.d.mts +45 -0
- package/realtime-react/dist/index.d.ts +45 -0
- package/realtime-react/dist/index.js +213 -0
- package/realtime-react/dist/index.js.map +1 -0
- package/realtime-react/dist/index.mjs +168 -0
- package/realtime-react/dist/index.mjs.map +1 -0
- package/realtime-react/package.json +15 -0
- package/src/index.ts +0 -6
- package/src/internal/get.ts +17 -3
- package/src/internal/index.ts +2 -0
- package/src/internal/meta/meta-state.ts +1 -1
- package/src/internal/operation.ts +3 -1
- package/src/internal/selector/create-read-write-selector.ts +62 -0
- package/src/internal/selector/create-readonly-selector.ts +52 -0
- package/src/internal/selector/index.ts +4 -0
- package/src/internal/selector/lookup-selector-sources.ts +16 -0
- package/src/internal/selector/register-selector.ts +57 -0
- package/src/internal/selector/trace-selector-atoms.ts +43 -0
- package/src/internal/selector/update-selector-atoms.ts +33 -0
- package/src/internal/selector-internal.ts +9 -207
- package/src/internal/store.ts +43 -16
- package/src/internal/subscribe-internal.ts +1 -1
- package/src/internal/time-travel-internal.ts +7 -7
- package/src/internal/timeline/add-atom-to-timeline.ts +164 -0
- package/src/internal/timeline/index.ts +1 -0
- package/src/internal/timeline-internal.ts +37 -156
- package/src/internal/transaction/abort-transaction.ts +12 -0
- package/src/internal/transaction/apply-transaction.ts +54 -0
- package/src/internal/transaction/build-transaction.ts +33 -0
- package/src/internal/transaction/index.ts +25 -0
- package/src/internal/transaction/redo-transaction.ts +23 -0
- package/src/internal/transaction/undo-transaction.ts +23 -0
- package/src/internal/transaction-internal.ts +14 -146
- package/src/react/index.ts +2 -46
- package/src/react/store-context.tsx +14 -0
- package/src/react/store-hooks.ts +48 -0
- package/src/react-devtools/AtomIODevtools.tsx +1 -1
- package/src/react-explorer/AtomIOExplorer.tsx +2 -2
- package/src/react-explorer/space-states.ts +2 -2
- package/src/realtime/README.md +33 -0
- package/src/realtime/hook-composition/index.ts +1 -0
- package/src/realtime/hook-composition/receive-state.ts +29 -0
- package/src/realtime/hook-composition/receive-transaction.ts +2 -3
- package/src/realtime-react/index.ts +3 -0
- package/src/realtime-react/realtime-context.tsx +31 -0
- package/src/realtime-react/realtime-hooks.ts +39 -0
- package/src/realtime-react/realtime-state.ts +10 -0
- package/src/realtime-react/use-pull-family-member.ts +27 -0
- package/src/realtime-react/use-pull-family.ts +25 -0
- package/src/realtime-react/use-pull.ts +23 -0
- package/src/realtime-react/use-push.ts +26 -0
- package/src/realtime-react/use-server-action.ts +34 -0
- package/src/silo.ts +12 -4
- package/src/subscribe.ts +30 -2
- package/src/timeline.ts +10 -0
- package/src/transaction.ts +15 -10
- package/src/realtime-client/hook-composition/compose-realtime-hooks.ts +0 -62
- package/src/realtime-client/hook-composition/realtime-client-family-member.ts +0 -28
- package/src/realtime-client/hook-composition/realtime-client-family.ts +0 -26
- package/src/realtime-client/hook-composition/realtime-client-single.ts +0 -24
- package/src/realtime-client/hook-composition/realtime-client-transaction.ts +0 -35
- package/src/realtime-client/index.ts +0 -1
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// ../src/realtime-react/realtime-context.tsx
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import * as AR from "atom.io/react";
|
|
4
|
+
import { io } from "socket.io-client";
|
|
5
|
+
|
|
6
|
+
// ../src/realtime-react/realtime-state.ts
|
|
7
|
+
import * as AtomIO from "atom.io";
|
|
8
|
+
var myIdState__INTERNAL = AtomIO.atom({
|
|
9
|
+
key: `myId__INTERNAL`,
|
|
10
|
+
default: null
|
|
11
|
+
});
|
|
12
|
+
var myIdState = AtomIO.selector({
|
|
13
|
+
key: `myId`,
|
|
14
|
+
get: ({ get }) => get(myIdState__INTERNAL)
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
// ../src/realtime-react/realtime-context.tsx
|
|
18
|
+
import { jsx } from "@emotion/react/jsx-runtime";
|
|
19
|
+
var RealtimeContext = React.createContext({
|
|
20
|
+
socket: io()
|
|
21
|
+
});
|
|
22
|
+
var RealtimeProvider = ({ children, socket }) => {
|
|
23
|
+
const setMyId = AR.useI(myIdState__INTERNAL);
|
|
24
|
+
React.useEffect(() => {
|
|
25
|
+
socket.on(`connect`, () => {
|
|
26
|
+
setMyId(socket.id);
|
|
27
|
+
});
|
|
28
|
+
socket.on(`disconnect`, () => {
|
|
29
|
+
setMyId(null);
|
|
30
|
+
});
|
|
31
|
+
}, [socket, setMyId]);
|
|
32
|
+
return /* @__PURE__ */ jsx(RealtimeContext.Provider, { value: { socket }, children });
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// ../src/realtime-react/use-pull.ts
|
|
36
|
+
import * as React3 from "react";
|
|
37
|
+
import * as AtomIO3 from "atom.io";
|
|
38
|
+
|
|
39
|
+
// ../src/react/store-context.tsx
|
|
40
|
+
import * as React2 from "react";
|
|
41
|
+
import * as AtomIO2 from "atom.io";
|
|
42
|
+
import { jsx as jsx2 } from "@emotion/react/jsx-runtime";
|
|
43
|
+
var StoreContext = React2.createContext(
|
|
44
|
+
AtomIO2.__INTERNAL__.IMPLICIT.STORE
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
// ../src/realtime-react/use-pull.ts
|
|
48
|
+
function usePull(token) {
|
|
49
|
+
const { socket } = React3.useContext(RealtimeContext);
|
|
50
|
+
const store = React3.useContext(StoreContext);
|
|
51
|
+
React3.useEffect(() => {
|
|
52
|
+
socket.on(`serve:${token.key}`, (data) => {
|
|
53
|
+
AtomIO3.setState(token, data, store);
|
|
54
|
+
});
|
|
55
|
+
socket.emit(`sub:${token.key}`);
|
|
56
|
+
return () => {
|
|
57
|
+
socket.off(`serve:${token.key}`);
|
|
58
|
+
socket.emit(`unsub:${token.key}`);
|
|
59
|
+
};
|
|
60
|
+
}, [token.key]);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ../src/realtime-react/use-pull-family.ts
|
|
64
|
+
import * as React4 from "react";
|
|
65
|
+
import * as AtomIO4 from "atom.io";
|
|
66
|
+
function usePullFamily(family) {
|
|
67
|
+
const { socket } = React4.useContext(RealtimeContext);
|
|
68
|
+
const store = React4.useContext(StoreContext);
|
|
69
|
+
React4.useEffect(() => {
|
|
70
|
+
socket.on(`serve:${family.key}`, (key, data) => {
|
|
71
|
+
AtomIO4.setState(family(key), data, store);
|
|
72
|
+
});
|
|
73
|
+
socket == null ? void 0 : socket.emit(`sub:${family.key}`);
|
|
74
|
+
return () => {
|
|
75
|
+
socket == null ? void 0 : socket.off(`serve:${family.key}`);
|
|
76
|
+
socket == null ? void 0 : socket.emit(`unsub:${family.key}`);
|
|
77
|
+
};
|
|
78
|
+
}, [family.key]);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// ../src/realtime-react/use-pull-family-member.ts
|
|
82
|
+
import * as React5 from "react";
|
|
83
|
+
import * as AtomIO5 from "atom.io";
|
|
84
|
+
function usePullFamilyMember(family, subKey) {
|
|
85
|
+
const token = family(subKey);
|
|
86
|
+
const { socket } = React5.useContext(RealtimeContext);
|
|
87
|
+
const store = React5.useContext(StoreContext);
|
|
88
|
+
React5.useEffect(() => {
|
|
89
|
+
socket == null ? void 0 : socket.on(`serve:${token.key}`, (data) => {
|
|
90
|
+
AtomIO5.setState(family(subKey), data, store);
|
|
91
|
+
});
|
|
92
|
+
socket == null ? void 0 : socket.emit(`sub:${family.key}`, subKey);
|
|
93
|
+
return () => {
|
|
94
|
+
socket == null ? void 0 : socket.off(`serve:${token.key}`);
|
|
95
|
+
socket == null ? void 0 : socket.emit(`unsub:${token.key}`);
|
|
96
|
+
};
|
|
97
|
+
}, [family.key]);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ../src/realtime-react/use-push.ts
|
|
101
|
+
import * as React6 from "react";
|
|
102
|
+
import * as AtomIO6 from "atom.io";
|
|
103
|
+
function usePush(token) {
|
|
104
|
+
const { socket } = React6.useContext(RealtimeContext);
|
|
105
|
+
const store = React6.useContext(StoreContext);
|
|
106
|
+
React6.useEffect(() => {
|
|
107
|
+
socket.emit(`claim:${token.key}`);
|
|
108
|
+
AtomIO6.subscribe(
|
|
109
|
+
token,
|
|
110
|
+
({ newValue }) => {
|
|
111
|
+
socket.emit(`pub:${token.key}`, newValue);
|
|
112
|
+
},
|
|
113
|
+
store
|
|
114
|
+
);
|
|
115
|
+
return () => {
|
|
116
|
+
socket.emit(`unclaim:${token.key}`);
|
|
117
|
+
};
|
|
118
|
+
}, [token.key]);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ../src/realtime-react/use-server-action.ts
|
|
122
|
+
import * as React7 from "react";
|
|
123
|
+
import * as AtomIO7 from "atom.io";
|
|
124
|
+
import { StoreContext as StoreContext2 } from "atom.io/react";
|
|
125
|
+
var TX_SUBS = /* @__PURE__ */ new Map();
|
|
126
|
+
function useServerAction(token) {
|
|
127
|
+
const store = React7.useContext(StoreContext2);
|
|
128
|
+
const { socket } = React7.useContext(RealtimeContext);
|
|
129
|
+
React7.useEffect(() => {
|
|
130
|
+
var _a;
|
|
131
|
+
const count = (_a = TX_SUBS.get(token.key)) != null ? _a : 0;
|
|
132
|
+
TX_SUBS.set(token.key, count + 1);
|
|
133
|
+
const unsubscribe = count === 0 ? AtomIO7.subscribeToTransaction(
|
|
134
|
+
token,
|
|
135
|
+
(update) => socket.emit(`tx:${token.key}`, update),
|
|
136
|
+
store
|
|
137
|
+
) : () => null;
|
|
138
|
+
return () => {
|
|
139
|
+
var _a2;
|
|
140
|
+
const newCount = (_a2 = TX_SUBS.get(token.key)) != null ? _a2 : 0;
|
|
141
|
+
TX_SUBS.set(token.key, newCount - 1);
|
|
142
|
+
unsubscribe();
|
|
143
|
+
};
|
|
144
|
+
}, [token.key]);
|
|
145
|
+
return AtomIO7.runTransaction(token, store);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// ../src/realtime-react/realtime-hooks.ts
|
|
149
|
+
var realtimeHooks = {
|
|
150
|
+
usePull,
|
|
151
|
+
usePullFamily,
|
|
152
|
+
usePullFamilyMember,
|
|
153
|
+
usePush,
|
|
154
|
+
useServerAction
|
|
155
|
+
};
|
|
156
|
+
export {
|
|
157
|
+
RealtimeContext,
|
|
158
|
+
RealtimeProvider,
|
|
159
|
+
myIdState,
|
|
160
|
+
myIdState__INTERNAL,
|
|
161
|
+
realtimeHooks,
|
|
162
|
+
usePull,
|
|
163
|
+
usePullFamily,
|
|
164
|
+
usePullFamilyMember,
|
|
165
|
+
usePush,
|
|
166
|
+
useServerAction
|
|
167
|
+
};
|
|
168
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/realtime-react/realtime-context.tsx","../../src/realtime-react/realtime-state.ts","../../src/realtime-react/use-pull.ts","../../src/react/store-context.tsx","../../src/realtime-react/use-pull-family.ts","../../src/realtime-react/use-pull-family-member.ts","../../src/realtime-react/use-push.ts","../../src/realtime-react/use-server-action.ts","../../src/realtime-react/realtime-hooks.ts"],"sourcesContent":["import * as React from \"react\"\n\nimport * as AR from \"atom.io/react\"\nimport type { Socket } from \"socket.io-client\"\nimport { io } from \"socket.io-client\"\n\nimport { myIdState__INTERNAL } from \"./realtime-state\"\n\nexport const RealtimeContext = React.createContext<{ socket: Socket }>({\n socket: io(),\n})\n\nexport const RealtimeProvider: React.FC<{\n children: React.ReactNode\n socket: Socket\n}> = ({ children, socket }) => {\n const setMyId = AR.useI(myIdState__INTERNAL)\n React.useEffect(() => {\n socket.on(`connect`, () => {\n setMyId(socket.id)\n })\n socket.on(`disconnect`, () => {\n setMyId(null)\n })\n }, [socket, setMyId])\n return (\n <RealtimeContext.Provider value={{ socket }}>\n {children}\n </RealtimeContext.Provider>\n )\n}\n","import * as AtomIO from \"atom.io\"\n\nexport const myIdState__INTERNAL = AtomIO.atom<string | null>({\n key: `myId__INTERNAL`,\n default: null,\n})\nexport const myIdState = AtomIO.selector<string | null>({\n key: `myId`,\n get: ({ get }) => get(myIdState__INTERNAL),\n})\n","import * as React from \"react\"\n\nimport * as AtomIO from \"atom.io\"\n\nimport type { Json } from \"~/packages/anvl/src/json\"\n\nimport { RealtimeContext } from \"./realtime-context\"\nimport { StoreContext } from \"../react\"\n\nexport function usePull<J extends Json>(token: AtomIO.StateToken<J>): void {\n const { socket } = React.useContext(RealtimeContext)\n const store = React.useContext(StoreContext)\n React.useEffect(() => {\n socket.on(`serve:${token.key}`, (data: J) => {\n AtomIO.setState(token, data, store)\n })\n socket.emit(`sub:${token.key}`)\n return () => {\n socket.off(`serve:${token.key}`)\n socket.emit(`unsub:${token.key}`)\n }\n }, [token.key])\n}\n","import * as React from \"react\"\n\nimport * as AtomIO from \"atom.io\"\n\nexport const StoreContext = React.createContext<AtomIO.Store>(\n AtomIO.__INTERNAL__.IMPLICIT.STORE\n)\n\nexport const StoreProvider: React.FC<{\n children: React.ReactNode\n store?: AtomIO.Store\n}> = ({ children, store = AtomIO.__INTERNAL__.IMPLICIT.STORE }) => (\n <StoreContext.Provider value={store}>{children}</StoreContext.Provider>\n)\n","import * as React from \"react\"\n\nimport * as AtomIO from \"atom.io\"\n\nimport type { Json } from \"~/packages/anvl/src/json\"\n\nimport { RealtimeContext } from \"./realtime-context\"\nimport { StoreContext } from \"../react\"\n\nexport function usePullFamily<J extends Json>(\n family: AtomIO.AtomFamily<J> | AtomIO.SelectorFamily<J>\n): void {\n const { socket } = React.useContext(RealtimeContext)\n const store = React.useContext(StoreContext)\n React.useEffect(() => {\n socket.on(`serve:${family.key}`, (key: Json, data: J) => {\n AtomIO.setState(family(key), data, store)\n })\n socket?.emit(`sub:${family.key}`)\n return () => {\n socket?.off(`serve:${family.key}`)\n socket?.emit(`unsub:${family.key}`)\n }\n }, [family.key])\n}\n","import * as React from \"react\"\n\nimport * as AtomIO from \"atom.io\"\n\nimport type { Json } from \"~/packages/anvl/src/json\"\n\nimport { RealtimeContext } from \"./realtime-context\"\nimport { StoreContext } from \"../react\"\n\nexport function usePullFamilyMember<J extends Json>(\n family: AtomIO.AtomFamily<J> | AtomIO.SelectorFamily<J>,\n subKey: AtomIO.Serializable\n): void {\n const token = family(subKey)\n const { socket } = React.useContext(RealtimeContext)\n const store = React.useContext(StoreContext)\n React.useEffect(() => {\n socket?.on(`serve:${token.key}`, (data: J) => {\n AtomIO.setState(family(subKey), data, store)\n })\n socket?.emit(`sub:${family.key}`, subKey)\n return () => {\n socket?.off(`serve:${token.key}`)\n socket?.emit(`unsub:${token.key}`)\n }\n }, [family.key])\n}\n","import * as React from \"react\"\n\nimport * as AtomIO from \"atom.io\"\n\nimport type { Json } from \"~/packages/anvl/src/json\"\n\nimport { RealtimeContext } from \"./realtime-context\"\nimport { StoreContext } from \"../react\"\n\nexport function usePush<J extends Json>(token: AtomIO.StateToken<J>): void {\n const { socket } = React.useContext(RealtimeContext)\n const store = React.useContext(StoreContext)\n React.useEffect(() => {\n socket.emit(`claim:${token.key}`)\n AtomIO.subscribe(\n token,\n ({ newValue }) => {\n socket.emit(`pub:${token.key}`, newValue)\n },\n store\n )\n return () => {\n socket.emit(`unclaim:${token.key}`)\n }\n }, [token.key])\n}\n","import * as React from \"react\"\n\nimport * as AtomIO from \"atom.io\"\nimport { StoreContext } from \"atom.io/react\"\n\nimport type { ƒn } from \"~/packages/anvl/src/function\"\n\nimport { RealtimeContext } from \"./realtime-context\"\n\nconst TX_SUBS = new Map<string, number>()\nexport function useServerAction<ƒ extends ƒn>(\n token: AtomIO.TransactionToken<ƒ>\n): (...parameters: Parameters<ƒ>) => ReturnType<ƒ> {\n const store = React.useContext(StoreContext)\n const { socket } = React.useContext(RealtimeContext)\n React.useEffect(() => {\n const count = TX_SUBS.get(token.key) ?? 0\n TX_SUBS.set(token.key, count + 1)\n const unsubscribe =\n count === 0\n ? AtomIO.subscribeToTransaction(\n token,\n (update) => socket.emit(`tx:${token.key}`, update),\n store\n )\n : () => null\n return () => {\n const newCount = TX_SUBS.get(token.key) ?? 0\n TX_SUBS.set(token.key, newCount - 1)\n unsubscribe()\n }\n }, [token.key])\n return AtomIO.runTransaction(token, store)\n}\n","import type * as AtomIO from \"atom.io\"\n\nimport type { ƒn } from \"~/packages/anvl/src/function\"\nimport type { Json } from \"~/packages/anvl/src/json\"\n\nimport { usePull } from \"./use-pull\"\nimport { usePullFamily } from \"./use-pull-family\"\nimport { usePullFamilyMember } from \"./use-pull-family-member\"\nimport { usePush } from \"./use-push\"\nimport { useServerAction } from \"./use-server-action\"\n\nexport type RealtimeHooks = {\n usePull: <J extends Json>(token: AtomIO.StateToken<J>) => void\n usePullFamily: <J extends Json>(\n family: AtomIO.AtomFamily<J> | AtomIO.SelectorFamily<J>\n ) => void\n usePullFamilyMember: <J extends Json>(\n family: AtomIO.AtomFamily<J> | AtomIO.SelectorFamily<J>,\n subKey: string\n ) => void\n usePush: <J extends Json>(token: AtomIO.StateToken<J>) => void\n useServerAction: <ƒ extends ƒn>(\n token: AtomIO.TransactionToken<ƒ>\n ) => (...parameters: Parameters<ƒ>) => ReturnType<ƒ>\n}\n\nexport const realtimeHooks: RealtimeHooks = {\n usePull,\n usePullFamily,\n usePullFamilyMember,\n usePush,\n useServerAction,\n}\n\nexport * from \"./use-pull\"\nexport * from \"./use-pull-family\"\nexport * from \"./use-pull-family-member\"\nexport * from \"./use-push\"\nexport * from \"./use-server-action\"\n"],"mappings":";AAAA,YAAY,WAAW;AAEvB,YAAY,QAAQ;AAEpB,SAAS,UAAU;;;ACJnB,YAAY,YAAY;AAEjB,IAAM,sBAA6B,YAAoB;AAAA,EAC5D,KAAK;AAAA,EACL,SAAS;AACX,CAAC;AACM,IAAM,YAAmB,gBAAwB;AAAA,EACtD,KAAK;AAAA,EACL,KAAK,CAAC,EAAE,IAAI,MAAM,IAAI,mBAAmB;AAC3C,CAAC;;;ADiBG;AAlBG,IAAM,kBAAwB,oBAAkC;AAAA,EACrE,QAAQ,GAAG;AACb,CAAC;AAEM,IAAM,mBAGR,CAAC,EAAE,UAAU,OAAO,MAAM;AAC7B,QAAM,UAAa,QAAK,mBAAmB;AAC3C,EAAM,gBAAU,MAAM;AACpB,WAAO,GAAG,WAAW,MAAM;AACzB,cAAQ,OAAO,EAAE;AAAA,IACnB,CAAC;AACD,WAAO,GAAG,cAAc,MAAM;AAC5B,cAAQ,IAAI;AAAA,IACd,CAAC;AAAA,EACH,GAAG,CAAC,QAAQ,OAAO,CAAC;AACpB,SACE,oBAAC,gBAAgB,UAAhB,EAAyB,OAAO,EAAE,OAAO,GACvC,UACH;AAEJ;;;AE9BA,YAAYA,YAAW;AAEvB,YAAYC,aAAY;;;ACFxB,YAAYC,YAAW;AAEvB,YAAYC,aAAY;AAUtB,gBAAAC,YAAA;AARK,IAAM,eAAqB;AAAA,EACzB,qBAAa,SAAS;AAC/B;;;ADGO,SAAS,QAAwB,OAAmC;AACzE,QAAM,EAAE,OAAO,IAAU,kBAAW,eAAe;AACnD,QAAM,QAAc,kBAAW,YAAY;AAC3C,EAAM,iBAAU,MAAM;AACpB,WAAO,GAAG,SAAS,MAAM,GAAG,IAAI,CAAC,SAAY;AAC3C,MAAO,iBAAS,OAAO,MAAM,KAAK;AAAA,IACpC,CAAC;AACD,WAAO,KAAK,OAAO,MAAM,GAAG,EAAE;AAC9B,WAAO,MAAM;AACX,aAAO,IAAI,SAAS,MAAM,GAAG,EAAE;AAC/B,aAAO,KAAK,SAAS,MAAM,GAAG,EAAE;AAAA,IAClC;AAAA,EACF,GAAG,CAAC,MAAM,GAAG,CAAC;AAChB;;;AEtBA,YAAYC,YAAW;AAEvB,YAAYC,aAAY;AAOjB,SAAS,cACd,QACM;AACN,QAAM,EAAE,OAAO,IAAU,kBAAW,eAAe;AACnD,QAAM,QAAc,kBAAW,YAAY;AAC3C,EAAM,iBAAU,MAAM;AACpB,WAAO,GAAG,SAAS,OAAO,GAAG,IAAI,CAAC,KAAW,SAAY;AACvD,MAAO,iBAAS,OAAO,GAAG,GAAG,MAAM,KAAK;AAAA,IAC1C,CAAC;AACD,qCAAQ,KAAK,OAAO,OAAO,GAAG;AAC9B,WAAO,MAAM;AACX,uCAAQ,IAAI,SAAS,OAAO,GAAG;AAC/B,uCAAQ,KAAK,SAAS,OAAO,GAAG;AAAA,IAClC;AAAA,EACF,GAAG,CAAC,OAAO,GAAG,CAAC;AACjB;;;ACxBA,YAAYC,YAAW;AAEvB,YAAYC,aAAY;AAOjB,SAAS,oBACd,QACA,QACM;AACN,QAAM,QAAQ,OAAO,MAAM;AAC3B,QAAM,EAAE,OAAO,IAAU,kBAAW,eAAe;AACnD,QAAM,QAAc,kBAAW,YAAY;AAC3C,EAAM,iBAAU,MAAM;AACpB,qCAAQ,GAAG,SAAS,MAAM,GAAG,IAAI,CAAC,SAAY;AAC5C,MAAO,iBAAS,OAAO,MAAM,GAAG,MAAM,KAAK;AAAA,IAC7C;AACA,qCAAQ,KAAK,OAAO,OAAO,GAAG,IAAI;AAClC,WAAO,MAAM;AACX,uCAAQ,IAAI,SAAS,MAAM,GAAG;AAC9B,uCAAQ,KAAK,SAAS,MAAM,GAAG;AAAA,IACjC;AAAA,EACF,GAAG,CAAC,OAAO,GAAG,CAAC;AACjB;;;AC1BA,YAAYC,YAAW;AAEvB,YAAYC,aAAY;AAOjB,SAAS,QAAwB,OAAmC;AACzE,QAAM,EAAE,OAAO,IAAU,kBAAW,eAAe;AACnD,QAAM,QAAc,kBAAW,YAAY;AAC3C,EAAM,iBAAU,MAAM;AACpB,WAAO,KAAK,SAAS,MAAM,GAAG,EAAE;AAChC,IAAO;AAAA,MACL;AAAA,MACA,CAAC,EAAE,SAAS,MAAM;AAChB,eAAO,KAAK,OAAO,MAAM,GAAG,IAAI,QAAQ;AAAA,MAC1C;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM;AACX,aAAO,KAAK,WAAW,MAAM,GAAG,EAAE;AAAA,IACpC;AAAA,EACF,GAAG,CAAC,MAAM,GAAG,CAAC;AAChB;;;ACzBA,YAAYC,YAAW;AAEvB,YAAYC,aAAY;AACxB,SAAS,gBAAAC,qBAAoB;AAM7B,IAAM,UAAU,oBAAI,IAAoB;AACjC,SAAS,gBACd,OACiD;AACjD,QAAM,QAAc,kBAAWC,aAAY;AAC3C,QAAM,EAAE,OAAO,IAAU,kBAAW,eAAe;AACnD,EAAM,iBAAU,MAAM;AAfxB;AAgBI,UAAM,SAAQ,aAAQ,IAAI,MAAM,GAAG,MAArB,YAA0B;AACxC,YAAQ,IAAI,MAAM,KAAK,QAAQ,CAAC;AAChC,UAAM,cACJ,UAAU,IACC;AAAA,MACL;AAAA,MACA,CAAC,WAAW,OAAO,KAAK,MAAM,MAAM,GAAG,IAAI,MAAM;AAAA,MACjD;AAAA,IACF,IACA,MAAM;AACZ,WAAO,MAAM;AA1BjB,UAAAC;AA2BM,YAAM,YAAWA,MAAA,QAAQ,IAAI,MAAM,GAAG,MAArB,OAAAA,MAA0B;AAC3C,cAAQ,IAAI,MAAM,KAAK,WAAW,CAAC;AACnC,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,MAAM,GAAG,CAAC;AACd,SAAc,uBAAe,OAAO,KAAK;AAC3C;;;ACPO,IAAM,gBAA+B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":["React","AtomIO","React","AtomIO","jsx","React","AtomIO","React","AtomIO","React","AtomIO","React","AtomIO","StoreContext","StoreContext","_a"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "atom.io-realtime-react",
|
|
3
|
+
"private": true,
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"types": "dist/index.d.ts",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"browser": "./dist/index.mjs",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -50,12 +50,6 @@ export type FamilyMetadata = {
|
|
|
50
50
|
subKey: string
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
export type TransactionToken<_> = {
|
|
54
|
-
key: string
|
|
55
|
-
type: `transaction`
|
|
56
|
-
__brand?: _
|
|
57
|
-
}
|
|
58
|
-
|
|
59
53
|
export const getState = <T>(
|
|
60
54
|
token: ReadonlySelectorToken<T> | StateToken<T>,
|
|
61
55
|
store: Store = IMPLICIT.STORE
|
package/src/internal/get.ts
CHANGED
|
@@ -2,14 +2,21 @@ import HAMT from "hamt_plus"
|
|
|
2
2
|
|
|
3
3
|
import type { ƒn } from "~/packages/anvl/src/function"
|
|
4
4
|
|
|
5
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
Atom,
|
|
7
|
+
ReadonlySelector,
|
|
8
|
+
Selector,
|
|
9
|
+
Store,
|
|
10
|
+
Timeline,
|
|
11
|
+
Transaction,
|
|
12
|
+
} from "."
|
|
6
13
|
import { target, isValueCached, readCachedValue, IMPLICIT } from "."
|
|
7
14
|
import type {
|
|
8
15
|
AtomToken,
|
|
9
16
|
ReadonlySelectorToken,
|
|
10
17
|
SelectorToken,
|
|
11
18
|
StateToken,
|
|
12
|
-
|
|
19
|
+
TimelineToken,
|
|
13
20
|
TransactionToken,
|
|
14
21
|
} from ".."
|
|
15
22
|
|
|
@@ -51,13 +58,19 @@ export function withdraw<T>(
|
|
|
51
58
|
token: ReadonlySelectorToken<T> | StateToken<T>,
|
|
52
59
|
store: Store
|
|
53
60
|
): Atom<T> | ReadonlySelector<T> | Selector<T> | null
|
|
61
|
+
export function withdraw<T>(token: TimelineToken, store: Store): Timeline | null
|
|
54
62
|
export function withdraw<T>(
|
|
55
|
-
token:
|
|
63
|
+
token:
|
|
64
|
+
| ReadonlySelectorToken<T>
|
|
65
|
+
| StateToken<T>
|
|
66
|
+
| TimelineToken
|
|
67
|
+
| TransactionToken<T>,
|
|
56
68
|
store: Store
|
|
57
69
|
):
|
|
58
70
|
| Atom<T>
|
|
59
71
|
| ReadonlySelector<T>
|
|
60
72
|
| Selector<T>
|
|
73
|
+
| Timeline
|
|
61
74
|
| Transaction<T extends ƒn ? T : never>
|
|
62
75
|
| null {
|
|
63
76
|
const core = target(store)
|
|
@@ -66,6 +79,7 @@ export function withdraw<T>(
|
|
|
66
79
|
HAMT.get(token.key, core.selectors) ??
|
|
67
80
|
HAMT.get(token.key, core.readonlySelectors) ??
|
|
68
81
|
HAMT.get(token.key, core.transactions) ??
|
|
82
|
+
HAMT.get(token.key, core.timelines) ??
|
|
69
83
|
null
|
|
70
84
|
)
|
|
71
85
|
}
|
package/src/internal/index.ts
CHANGED
|
@@ -5,9 +5,11 @@ export * from "./is-default"
|
|
|
5
5
|
export * as META from "./meta"
|
|
6
6
|
export * from "./operation"
|
|
7
7
|
export * from "./selector-internal"
|
|
8
|
+
export * from "./selector"
|
|
8
9
|
export * from "./set"
|
|
9
10
|
export * from "./store"
|
|
10
11
|
export * from "./subscribe-internal"
|
|
11
12
|
export * from "./time-travel-internal"
|
|
12
13
|
export * from "./timeline-internal"
|
|
13
14
|
export * from "./transaction-internal"
|
|
15
|
+
export * from "./transaction"
|
|
@@ -34,7 +34,9 @@ export const openOperation = (token: StateToken<any>, store: Store): void => {
|
|
|
34
34
|
time: Date.now(),
|
|
35
35
|
token,
|
|
36
36
|
}
|
|
37
|
-
store.config.logger?.info(
|
|
37
|
+
store.config.logger?.info(
|
|
38
|
+
`⭕ operation start from "${token.key}" in store "${store.config.name}"`
|
|
39
|
+
)
|
|
38
40
|
}
|
|
39
41
|
export const closeOperation = (store: Store): void => {
|
|
40
42
|
const core = target(store)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import HAMT from "hamt_plus"
|
|
2
|
+
import * as Rx from "rxjs"
|
|
3
|
+
|
|
4
|
+
import { become } from "~/packages/anvl/src/function"
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
type Store,
|
|
8
|
+
type Selector,
|
|
9
|
+
type StoreCore,
|
|
10
|
+
registerSelector,
|
|
11
|
+
selector__INTERNAL,
|
|
12
|
+
} from ".."
|
|
13
|
+
import type { FamilyMetadata, SelectorToken } from "../.."
|
|
14
|
+
import type { SelectorOptions } from "../../selector"
|
|
15
|
+
import { cacheValue, markDone } from "../operation"
|
|
16
|
+
|
|
17
|
+
export const createReadWriteSelector = <T>(
|
|
18
|
+
options: SelectorOptions<T>,
|
|
19
|
+
family: FamilyMetadata | undefined,
|
|
20
|
+
store: Store,
|
|
21
|
+
core: StoreCore
|
|
22
|
+
): SelectorToken<T> => {
|
|
23
|
+
const subject = new Rx.Subject<{ newValue: T; oldValue: T }>()
|
|
24
|
+
|
|
25
|
+
const { get, set } = registerSelector(options.key, store)
|
|
26
|
+
const getSelf = () => {
|
|
27
|
+
const value = options.get({ get })
|
|
28
|
+
cacheValue(options.key, value, store)
|
|
29
|
+
return value
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const setSelf = (next: T | ((oldValue: T) => T)): void => {
|
|
33
|
+
store.config.logger?.info(` <- "${options.key}" became`, next)
|
|
34
|
+
const oldValue = getSelf()
|
|
35
|
+
const newValue = become(next)(oldValue)
|
|
36
|
+
cacheValue(options.key, newValue, store)
|
|
37
|
+
markDone(options.key, store)
|
|
38
|
+
if (store.transactionStatus.phase === `idle`) {
|
|
39
|
+
subject.next({ newValue, oldValue })
|
|
40
|
+
}
|
|
41
|
+
options.set({ get, set }, newValue)
|
|
42
|
+
}
|
|
43
|
+
const mySelector: Selector<T> = {
|
|
44
|
+
...options,
|
|
45
|
+
subject,
|
|
46
|
+
install: (s: Store) => selector__INTERNAL(options, family, s),
|
|
47
|
+
get: getSelf,
|
|
48
|
+
set: setSelf,
|
|
49
|
+
type: `selector`,
|
|
50
|
+
...(family && { family }),
|
|
51
|
+
}
|
|
52
|
+
core.selectors = HAMT.set(options.key, mySelector, core.selectors)
|
|
53
|
+
const initialValue = getSelf()
|
|
54
|
+
store.config.logger?.info(` ✨ "${options.key}" =`, initialValue)
|
|
55
|
+
const token: SelectorToken<T> = {
|
|
56
|
+
key: options.key,
|
|
57
|
+
type: `selector`,
|
|
58
|
+
family,
|
|
59
|
+
}
|
|
60
|
+
store.subject.selectorCreation.next(token)
|
|
61
|
+
return token
|
|
62
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import HAMT from "hamt_plus"
|
|
2
|
+
import * as Rx from "rxjs"
|
|
3
|
+
|
|
4
|
+
import { registerSelector } from "./register-selector"
|
|
5
|
+
import type {
|
|
6
|
+
FamilyMetadata,
|
|
7
|
+
ReadonlySelectorOptions,
|
|
8
|
+
ReadonlySelectorToken,
|
|
9
|
+
Store,
|
|
10
|
+
} from "../.."
|
|
11
|
+
import { cacheValue } from "../operation"
|
|
12
|
+
import { selector__INTERNAL, type ReadonlySelector } from "../selector-internal"
|
|
13
|
+
import type { StoreCore } from "../store"
|
|
14
|
+
|
|
15
|
+
export const createReadonlySelector = <T>(
|
|
16
|
+
options: ReadonlySelectorOptions<T>,
|
|
17
|
+
family: FamilyMetadata | undefined,
|
|
18
|
+
store: Store,
|
|
19
|
+
core: StoreCore
|
|
20
|
+
): ReadonlySelectorToken<T> => {
|
|
21
|
+
const subject = new Rx.Subject<{ newValue: T; oldValue: T }>()
|
|
22
|
+
|
|
23
|
+
const { get } = registerSelector(options.key, store)
|
|
24
|
+
const getSelf = () => {
|
|
25
|
+
const value = options.get({ get })
|
|
26
|
+
cacheValue(options.key, value, store)
|
|
27
|
+
return value
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const readonlySelector: ReadonlySelector<T> = {
|
|
31
|
+
...options,
|
|
32
|
+
subject,
|
|
33
|
+
install: (s: Store) => selector__INTERNAL(options, family, s),
|
|
34
|
+
get: getSelf,
|
|
35
|
+
type: `readonly_selector`,
|
|
36
|
+
...(family && { family }),
|
|
37
|
+
}
|
|
38
|
+
core.readonlySelectors = HAMT.set(
|
|
39
|
+
options.key,
|
|
40
|
+
readonlySelector,
|
|
41
|
+
core.readonlySelectors
|
|
42
|
+
)
|
|
43
|
+
const initialValue = getSelf()
|
|
44
|
+
store.config.logger?.info(` ✨ "${options.key}" =`, initialValue)
|
|
45
|
+
const token: ReadonlySelectorToken<T> = {
|
|
46
|
+
key: options.key,
|
|
47
|
+
type: `readonly_selector`,
|
|
48
|
+
family,
|
|
49
|
+
}
|
|
50
|
+
store.subject.selectorCreation.next(token)
|
|
51
|
+
return token
|
|
52
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Store } from ".."
|
|
2
|
+
import { target, lookup } from ".."
|
|
3
|
+
import type { AtomToken, ReadonlySelectorToken, SelectorToken } from "../.."
|
|
4
|
+
|
|
5
|
+
export const lookupSelectorSources = (
|
|
6
|
+
key: string,
|
|
7
|
+
store: Store
|
|
8
|
+
): (
|
|
9
|
+
| AtomToken<unknown>
|
|
10
|
+
| ReadonlySelectorToken<unknown>
|
|
11
|
+
| SelectorToken<unknown>
|
|
12
|
+
)[] =>
|
|
13
|
+
target(store)
|
|
14
|
+
.selectorGraph.getRelations(key)
|
|
15
|
+
.filter(({ source }) => source !== key)
|
|
16
|
+
.map(({ source }) => lookup(source, store))
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { updateSelectorAtoms } from "./update-selector-atoms"
|
|
2
|
+
import type { Transactors } from "../../transaction"
|
|
3
|
+
import { getState__INTERNAL, withdraw } from "../get"
|
|
4
|
+
import { setState__INTERNAL } from "../set"
|
|
5
|
+
import type { Store } from "../store"
|
|
6
|
+
import { IMPLICIT } from "../store"
|
|
7
|
+
import { target } from "../transaction-internal"
|
|
8
|
+
|
|
9
|
+
export const registerSelector = (
|
|
10
|
+
selectorKey: string,
|
|
11
|
+
store: Store = IMPLICIT.STORE
|
|
12
|
+
): Transactors => ({
|
|
13
|
+
get: (dependency) => {
|
|
14
|
+
const core = target(store)
|
|
15
|
+
const alreadyRegistered = core.selectorGraph
|
|
16
|
+
.getRelations(selectorKey)
|
|
17
|
+
.some(({ source }) => source === dependency.key)
|
|
18
|
+
|
|
19
|
+
const dependencyState = withdraw(dependency, store)
|
|
20
|
+
if (dependencyState === null) {
|
|
21
|
+
throw new Error(
|
|
22
|
+
`State "${dependency.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
const dependencyValue = getState__INTERNAL(dependencyState, store)
|
|
26
|
+
|
|
27
|
+
if (alreadyRegistered) {
|
|
28
|
+
store.config.logger?.info(
|
|
29
|
+
` || ${selectorKey} <- ${dependency.key} =`,
|
|
30
|
+
dependencyValue
|
|
31
|
+
)
|
|
32
|
+
} else {
|
|
33
|
+
store.config.logger?.info(
|
|
34
|
+
`🔌 registerSelector "${selectorKey}" <- ( "${dependency.key}" =`,
|
|
35
|
+
dependencyValue,
|
|
36
|
+
`)`
|
|
37
|
+
)
|
|
38
|
+
core.selectorGraph = core.selectorGraph.set(
|
|
39
|
+
{ from: dependency.key, to: selectorKey },
|
|
40
|
+
{
|
|
41
|
+
source: dependency.key,
|
|
42
|
+
}
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
updateSelectorAtoms(selectorKey, dependency, store)
|
|
46
|
+
return dependencyValue
|
|
47
|
+
},
|
|
48
|
+
set: (stateToken, newValue) => {
|
|
49
|
+
const state = withdraw(stateToken, store)
|
|
50
|
+
if (state === null) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
`State "${stateToken.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
setState__INTERNAL(state, newValue, store)
|
|
56
|
+
},
|
|
57
|
+
})
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { lookupSelectorSources } from "./lookup-selector-sources"
|
|
2
|
+
import type { Store, AtomToken, ReadonlySelectorToken, StateToken } from "../.."
|
|
3
|
+
|
|
4
|
+
export const traceSelectorAtoms = (
|
|
5
|
+
selectorKey: string,
|
|
6
|
+
dependency: ReadonlySelectorToken<unknown> | StateToken<unknown>,
|
|
7
|
+
store: Store
|
|
8
|
+
): AtomToken<unknown>[] => {
|
|
9
|
+
const roots: AtomToken<unknown>[] = []
|
|
10
|
+
|
|
11
|
+
const sources = lookupSelectorSources(dependency.key, store)
|
|
12
|
+
let depth = 0
|
|
13
|
+
while (sources.length > 0) {
|
|
14
|
+
/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */
|
|
15
|
+
const source = sources.shift()!
|
|
16
|
+
++depth
|
|
17
|
+
if (depth > 999) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
`Maximum selector dependency depth exceeded in selector "${selectorKey}".`
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (source.type !== `atom`) {
|
|
24
|
+
sources.push(...lookupSelectorSources(source.key, store))
|
|
25
|
+
} else {
|
|
26
|
+
roots.push(source)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return roots
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const traceAllSelectorAtoms = (
|
|
34
|
+
selectorKey: string,
|
|
35
|
+
store: Store
|
|
36
|
+
): AtomToken<unknown>[] => {
|
|
37
|
+
const sources = lookupSelectorSources(selectorKey, store)
|
|
38
|
+
return sources.flatMap((source) =>
|
|
39
|
+
source.type === `atom`
|
|
40
|
+
? source
|
|
41
|
+
: traceSelectorAtoms(selectorKey, source, store)
|
|
42
|
+
)
|
|
43
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { traceSelectorAtoms } from "./trace-selector-atoms"
|
|
2
|
+
import type { Store } from ".."
|
|
3
|
+
import { target } from ".."
|
|
4
|
+
import type { ReadonlySelectorToken, StateToken } from "../.."
|
|
5
|
+
|
|
6
|
+
export const updateSelectorAtoms = (
|
|
7
|
+
selectorKey: string,
|
|
8
|
+
dependency: ReadonlySelectorToken<unknown> | StateToken<unknown>,
|
|
9
|
+
store: Store
|
|
10
|
+
): void => {
|
|
11
|
+
const core = target(store)
|
|
12
|
+
if (dependency.type === `atom`) {
|
|
13
|
+
core.selectorAtoms = core.selectorAtoms.set({
|
|
14
|
+
selectorKey,
|
|
15
|
+
atomKey: dependency.key,
|
|
16
|
+
})
|
|
17
|
+
store.config.logger?.info(
|
|
18
|
+
` || adding root for "${selectorKey}": ${dependency.key}`
|
|
19
|
+
)
|
|
20
|
+
return
|
|
21
|
+
}
|
|
22
|
+
const roots = traceSelectorAtoms(selectorKey, dependency, store)
|
|
23
|
+
store.config.logger?.info(
|
|
24
|
+
` || adding roots for "${selectorKey}":`,
|
|
25
|
+
roots.map((r) => r.key)
|
|
26
|
+
)
|
|
27
|
+
for (const root of roots) {
|
|
28
|
+
core.selectorAtoms = core.selectorAtoms.set({
|
|
29
|
+
selectorKey,
|
|
30
|
+
atomKey: root.key,
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
}
|