atom.io 0.8.1 → 0.8.2

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 (36) hide show
  1. package/package.json +11 -8
  2. package/react-devtools/dist/index.js +3 -3
  3. package/react-devtools/dist/index.js.map +1 -1
  4. package/react-devtools/dist/index.mjs +3 -3
  5. package/react-devtools/dist/index.mjs.map +1 -1
  6. package/realtime-client/dist/index.d.mts +21 -0
  7. package/realtime-client/dist/index.d.ts +21 -0
  8. package/realtime-client/dist/index.js +173 -0
  9. package/realtime-client/dist/index.js.map +1 -0
  10. package/realtime-client/dist/index.mjs +144 -0
  11. package/realtime-client/dist/index.mjs.map +1 -0
  12. package/realtime-client/package.json +15 -0
  13. package/realtime-client/src/index.ts +7 -0
  14. package/realtime-client/src/realtime-state.ts +10 -0
  15. package/realtime-client/src/use-pull-family-member.ts +26 -0
  16. package/realtime-client/src/use-pull-mutable-family-member.ts +38 -0
  17. package/realtime-client/src/use-pull-mutable.ts +32 -0
  18. package/realtime-client/src/use-pull.ts +19 -0
  19. package/realtime-client/src/use-push.ts +25 -0
  20. package/realtime-client/src/use-server-action.ts +49 -0
  21. package/realtime-server/dist/index.d.mts +25 -0
  22. package/realtime-server/dist/index.d.ts +25 -0
  23. package/realtime-server/dist/index.js +316 -0
  24. package/realtime-server/dist/index.js.map +1 -0
  25. package/realtime-server/dist/index.mjs +289 -0
  26. package/realtime-server/dist/index.mjs.map +1 -0
  27. package/realtime-server/package.json +15 -0
  28. package/realtime-server/src/README.md +33 -0
  29. package/realtime-server/src/hook-composition/expose-family.ts +105 -0
  30. package/realtime-server/src/hook-composition/expose-mutable-family.ts +127 -0
  31. package/realtime-server/src/hook-composition/expose-mutable.ts +45 -0
  32. package/realtime-server/src/hook-composition/expose-single.ts +39 -0
  33. package/realtime-server/src/hook-composition/index.ts +14 -0
  34. package/realtime-server/src/hook-composition/receive-state.ts +30 -0
  35. package/realtime-server/src/hook-composition/receive-transaction.ts +37 -0
  36. package/realtime-server/src/index.ts +1 -0
@@ -0,0 +1,21 @@
1
+ import * as AtomIO from 'atom.io';
2
+ import { Store, Transceiver } from 'atom.io/internal';
3
+ import { Json } from 'atom.io/json';
4
+ import { Socket } from 'socket.io-client';
5
+
6
+ declare const myIdState__INTERNAL: AtomIO.AtomToken<string | null>;
7
+ declare const myIdState: AtomIO.ReadonlySelectorToken<string | null>;
8
+
9
+ declare function pullState<J extends Json.Serializable>(token: AtomIO.StateToken<J>, socket: Socket, store: Store): () => void;
10
+
11
+ declare function pullFamilyMember<J extends Json.Serializable>(token: AtomIO.AtomToken<J>, socket: Socket, store: Store): () => void;
12
+
13
+ declare function pullMutableState<T extends Transceiver<Json.Serializable>, J extends Json.Serializable>(token: AtomIO.MutableAtomToken<T, J>, socket: Socket, store: Store): () => void;
14
+
15
+ declare function pullMutableFamilyMember<T extends Transceiver<Json.Serializable>, J extends Json.Serializable>(token: AtomIO.MutableAtomToken<T, J>, socket: Socket, store: Store): () => void;
16
+
17
+ declare function pushState<J extends Json.Serializable>(token: AtomIO.StateToken<J>, socket: Socket, subscriptionKey: string, store: Store): () => void;
18
+
19
+ declare function synchronizeTransactionResults(token: AtomIO.TransactionToken<any>, socket: Socket, store: Store): () => void;
20
+
21
+ export { myIdState, myIdState__INTERNAL, pullFamilyMember, pullMutableFamilyMember, pullMutableState, pullState, pushState, synchronizeTransactionResults };
@@ -0,0 +1,21 @@
1
+ import * as AtomIO from 'atom.io';
2
+ import { Store, Transceiver } from 'atom.io/internal';
3
+ import { Json } from 'atom.io/json';
4
+ import { Socket } from 'socket.io-client';
5
+
6
+ declare const myIdState__INTERNAL: AtomIO.AtomToken<string | null>;
7
+ declare const myIdState: AtomIO.ReadonlySelectorToken<string | null>;
8
+
9
+ declare function pullState<J extends Json.Serializable>(token: AtomIO.StateToken<J>, socket: Socket, store: Store): () => void;
10
+
11
+ declare function pullFamilyMember<J extends Json.Serializable>(token: AtomIO.AtomToken<J>, socket: Socket, store: Store): () => void;
12
+
13
+ declare function pullMutableState<T extends Transceiver<Json.Serializable>, J extends Json.Serializable>(token: AtomIO.MutableAtomToken<T, J>, socket: Socket, store: Store): () => void;
14
+
15
+ declare function pullMutableFamilyMember<T extends Transceiver<Json.Serializable>, J extends Json.Serializable>(token: AtomIO.MutableAtomToken<T, J>, socket: Socket, store: Store): () => void;
16
+
17
+ declare function pushState<J extends Json.Serializable>(token: AtomIO.StateToken<J>, socket: Socket, subscriptionKey: string, store: Store): () => void;
18
+
19
+ declare function synchronizeTransactionResults(token: AtomIO.TransactionToken<any>, socket: Socket, store: Store): () => void;
20
+
21
+ export { myIdState, myIdState__INTERNAL, pullFamilyMember, pullMutableFamilyMember, pullMutableState, pullState, pushState, synchronizeTransactionResults };
@@ -0,0 +1,173 @@
1
+ 'use strict';
2
+
3
+ var AtomIO = require('atom.io');
4
+ var json = require('atom.io/json');
5
+ var internal = require('atom.io/internal');
6
+
7
+ function _interopNamespace(e) {
8
+ if (e && e.__esModule) return e;
9
+ var n = Object.create(null);
10
+ if (e) {
11
+ Object.keys(e).forEach(function (k) {
12
+ if (k !== 'default') {
13
+ var d = Object.getOwnPropertyDescriptor(e, k);
14
+ Object.defineProperty(n, k, d.get ? d : {
15
+ enumerable: true,
16
+ get: function () { return e[k]; }
17
+ });
18
+ }
19
+ });
20
+ }
21
+ n.default = e;
22
+ return Object.freeze(n);
23
+ }
24
+
25
+ var AtomIO__namespace = /*#__PURE__*/_interopNamespace(AtomIO);
26
+
27
+ // src/realtime-state.ts
28
+ var myIdState__INTERNAL = AtomIO__namespace.atom({
29
+ key: `myId__INTERNAL`,
30
+ default: null
31
+ });
32
+ var myIdState = AtomIO__namespace.selector({
33
+ key: `myId`,
34
+ get: ({ get }) => get(myIdState__INTERNAL)
35
+ });
36
+ function pullState(token, socket, store) {
37
+ socket.on(`serve:${token.key}`, (data) => {
38
+ AtomIO__namespace.setState(token, data, store);
39
+ });
40
+ socket.emit(`sub:${token.key}`);
41
+ return () => {
42
+ socket.off(`serve:${token.key}`);
43
+ socket.emit(`unsub:${token.key}`);
44
+ };
45
+ }
46
+ function pullFamilyMember(token, socket, store) {
47
+ if (!(`family` in token)) {
48
+ console.error(`Token is not a family member:`, token);
49
+ return () => {
50
+ };
51
+ }
52
+ const { key: familyKey, subKey: serializedSubKey } = token.family;
53
+ const subKey = json.parseJson(serializedSubKey);
54
+ socket == null ? void 0 : socket.on(`serve:${token.key}`, (data) => {
55
+ AtomIO__namespace.setState(token, data, store);
56
+ });
57
+ socket == null ? void 0 : socket.emit(`sub:${familyKey}`, subKey);
58
+ return () => {
59
+ socket == null ? void 0 : socket.off(`serve:${token.key}`);
60
+ socket == null ? void 0 : socket.emit(`unsub:${token.key}`);
61
+ };
62
+ }
63
+ function pullMutableState(token, socket, store) {
64
+ const jsonToken = internal.getJsonToken(token);
65
+ const updateToken = internal.getUpdateToken(token);
66
+ socket.on(`init:${token.key}`, (data) => {
67
+ AtomIO__namespace.setState(jsonToken, data, store);
68
+ });
69
+ socket.on(
70
+ `next:${token.key}`,
71
+ (data) => {
72
+ AtomIO__namespace.setState(updateToken, data, store);
73
+ }
74
+ );
75
+ socket.emit(`sub:${token.key}`);
76
+ return () => {
77
+ socket.off(`init:${token.key}`);
78
+ socket.off(`next:${token.key}`);
79
+ socket.emit(`unsub:${token.key}`);
80
+ };
81
+ }
82
+ function pullMutableFamilyMember(token, socket, store) {
83
+ if (!(`family` in token)) {
84
+ console.error(`Token is not a family member:`, token);
85
+ return () => {
86
+ };
87
+ }
88
+ const { key: familyKey, subKey: serializedSubKey } = token.family;
89
+ const subKey = json.parseJson(serializedSubKey);
90
+ socket == null ? void 0 : socket.on(`init:${token.key}`, (data) => {
91
+ const jsonToken = internal.getJsonToken(token);
92
+ AtomIO__namespace.setState(jsonToken, data, store);
93
+ });
94
+ socket == null ? void 0 : socket.on(
95
+ `next:${token.key}`,
96
+ (data) => {
97
+ const trackerToken = internal.getUpdateToken(token);
98
+ AtomIO__namespace.setState(trackerToken, data, store);
99
+ }
100
+ );
101
+ socket == null ? void 0 : socket.emit(`sub:${familyKey}`, subKey);
102
+ return () => {
103
+ socket == null ? void 0 : socket.off(`serve:${token.key}`);
104
+ socket == null ? void 0 : socket.emit(`unsub:${token.key}`);
105
+ };
106
+ }
107
+ function pushState(token, socket, subscriptionKey, store) {
108
+ socket.emit(`claim:${token.key}`);
109
+ AtomIO__namespace.subscribe(
110
+ token,
111
+ ({ newValue }) => {
112
+ socket.emit(`pub:${token.key}`, newValue);
113
+ },
114
+ subscriptionKey,
115
+ store
116
+ );
117
+ return () => {
118
+ socket.off(`pub:${token.key}`);
119
+ socket.emit(`unclaim:${token.key}`);
120
+ };
121
+ }
122
+ var TX_SUBS = /* @__PURE__ */ new Map();
123
+ function synchronizeTransactionResults(token, socket, store) {
124
+ var _a;
125
+ const count = (_a = TX_SUBS.get(token.key)) != null ? _a : 0;
126
+ TX_SUBS.set(token.key, count + 1);
127
+ const unsubscribe = count === 0 ? AtomIO__namespace.subscribeToTransaction(
128
+ token,
129
+ (clientUpdate) => {
130
+ const transactionId = Math.random().toString(36).slice(2);
131
+ const clientResult = JSON.stringify(clientUpdate);
132
+ const topic = `tx:sync:${transactionId}`;
133
+ const sync = (serverUpdate) => {
134
+ var _a2, _b, _c, _d, _e;
135
+ (_a2 = store.config.logger) == null ? void 0 : _a2.info(`Transaction ${token.key} synced`);
136
+ socket.off(topic, sync);
137
+ const serverResult = JSON.stringify(serverUpdate);
138
+ if (clientResult !== serverResult) {
139
+ (_b = store.config.logger) == null ? void 0 : _b.error(
140
+ `Transaction ${token.key} produced different results on client and server`
141
+ );
142
+ (_c = store.config.logger) == null ? void 0 : _c.error(`Client:`, clientResult);
143
+ (_d = store.config.logger) == null ? void 0 : _d.error(`Server:`, serverResult);
144
+ } else {
145
+ (_e = store.config.logger) == null ? void 0 : _e.info(
146
+ `Transaction ${token.key} results match`
147
+ );
148
+ }
149
+ };
150
+ socket.on(topic, sync);
151
+ socket.emit(`tx:${token.key}`, clientUpdate, transactionId);
152
+ },
153
+ `use-server-action`,
154
+ store
155
+ ) : () => null;
156
+ return () => {
157
+ var _a2;
158
+ const newCount = (_a2 = TX_SUBS.get(token.key)) != null ? _a2 : 0;
159
+ TX_SUBS.set(token.key, newCount - 1);
160
+ unsubscribe();
161
+ };
162
+ }
163
+
164
+ exports.myIdState = myIdState;
165
+ exports.myIdState__INTERNAL = myIdState__INTERNAL;
166
+ exports.pullFamilyMember = pullFamilyMember;
167
+ exports.pullMutableFamilyMember = pullMutableFamilyMember;
168
+ exports.pullMutableState = pullMutableState;
169
+ exports.pullState = pullState;
170
+ exports.pushState = pushState;
171
+ exports.synchronizeTransactionResults = synchronizeTransactionResults;
172
+ //# sourceMappingURL=out.js.map
173
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/realtime-state.ts","../src/use-pull.ts","../src/use-pull-family-member.ts","../src/use-pull-mutable.ts","../src/use-pull-mutable-family-member.ts","../src/use-push.ts","../src/use-server-action.ts"],"names":["AtomIO","getJsonToken","getUpdateToken","parseJson","_a"],"mappings":"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","sourcesContent":["import * as AtomIO from \"atom.io\"\n\nexport const myIdState__INTERNAL = AtomIO.atom<string | null>({\n\tkey: `myId__INTERNAL`,\n\tdefault: null,\n})\nexport const myIdState = AtomIO.selector<string | null>({\n\tkey: `myId`,\n\tget: ({ get }) => get(myIdState__INTERNAL),\n})\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullState<J extends Json.Serializable>(\n\ttoken: AtomIO.StateToken<J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tsocket.on(`serve:${token.key}`, (data) => {\n\t\tAtomIO.setState(token, data, store)\n\t})\n\tsocket.emit(`sub:${token.key}`)\n\treturn () => {\n\t\tsocket.off(`serve:${token.key}`)\n\t\tsocket.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { parseJson } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullFamilyMember<J extends Json.Serializable>(\n\ttoken: AtomIO.AtomToken<J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tif (!(`family` in token)) {\n\t\tconsole.error(`Token is not a family member:`, token)\n\t\treturn () => {}\n\t}\n\tconst { key: familyKey, subKey: serializedSubKey } = token.family\n\tconst subKey = parseJson(serializedSubKey)\n\tsocket?.on(`serve:${token.key}`, (data: J) => {\n\t\tAtomIO.setState(token, data, store)\n\t})\n\tsocket?.emit(`sub:${familyKey}`, subKey)\n\treturn () => {\n\t\tsocket?.off(`serve:${token.key}`)\n\t\tsocket?.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store, Transceiver } from \"atom.io/internal\"\nimport { getJsonToken, getUpdateToken } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullMutableState<\n\tT extends Transceiver<Json.Serializable>,\n\tJ extends Json.Serializable,\n>(\n\ttoken: AtomIO.MutableAtomToken<T, J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tconst jsonToken = getJsonToken(token)\n\tconst updateToken = getUpdateToken(token)\n\tsocket.on(`init:${token.key}`, (data: J) => {\n\t\tAtomIO.setState(jsonToken, data, store)\n\t})\n\tsocket.on(\n\t\t`next:${token.key}`,\n\t\t(data: T extends Transceiver<infer Update> ? Update : never) => {\n\t\t\tAtomIO.setState(updateToken, data, store)\n\t\t},\n\t)\n\tsocket.emit(`sub:${token.key}`)\n\treturn () => {\n\t\tsocket.off(`init:${token.key}`)\n\t\tsocket.off(`next:${token.key}`)\n\t\tsocket.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport { getJsonToken, getUpdateToken } from \"atom.io/internal\"\nimport type { Store, Transceiver } from \"atom.io/internal\"\nimport { parseJson } from \"atom.io/json\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullMutableFamilyMember<\n\tT extends Transceiver<Json.Serializable>,\n\tJ extends Json.Serializable,\n>(\n\ttoken: AtomIO.MutableAtomToken<T, J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tif (!(`family` in token)) {\n\t\tconsole.error(`Token is not a family member:`, token)\n\t\treturn () => {}\n\t}\n\tconst { key: familyKey, subKey: serializedSubKey } = token.family\n\tconst subKey = parseJson(serializedSubKey)\n\tsocket?.on(`init:${token.key}`, (data: J) => {\n\t\tconst jsonToken = getJsonToken(token)\n\t\tAtomIO.setState(jsonToken, data, store)\n\t})\n\tsocket?.on(\n\t\t`next:${token.key}`,\n\t\t(data: T extends Transceiver<infer Signal> ? Signal : never) => {\n\t\t\tconst trackerToken = getUpdateToken(token)\n\t\t\tAtomIO.setState(trackerToken, data, store)\n\t\t},\n\t)\n\tsocket?.emit(`sub:${familyKey}`, subKey)\n\treturn () => {\n\t\tsocket?.off(`serve:${token.key}`)\n\t\tsocket?.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pushState<J extends Json.Serializable>(\n\ttoken: AtomIO.StateToken<J>,\n\tsocket: Socket,\n\tsubscriptionKey: string,\n\tstore: Store,\n): () => void {\n\tsocket.emit(`claim:${token.key}`)\n\tAtomIO.subscribe(\n\t\ttoken,\n\t\t({ newValue }) => {\n\t\t\tsocket.emit(`pub:${token.key}`, newValue)\n\t\t},\n\t\tsubscriptionKey,\n\t\tstore,\n\t)\n\treturn () => {\n\t\tsocket.off(`pub:${token.key}`)\n\t\tsocket.emit(`unclaim:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Socket } from \"socket.io-client\"\n\nconst TX_SUBS = new Map<string, number>()\nexport function synchronizeTransactionResults(\n\ttoken: AtomIO.TransactionToken<any>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tconst count = TX_SUBS.get(token.key) ?? 0\n\tTX_SUBS.set(token.key, count + 1)\n\tconst unsubscribe =\n\t\tcount === 0\n\t\t\t? AtomIO.subscribeToTransaction(\n\t\t\t\t\ttoken,\n\t\t\t\t\t(clientUpdate) => {\n\t\t\t\t\t\tconst transactionId = Math.random().toString(36).slice(2)\n\t\t\t\t\t\tconst clientResult = JSON.stringify(clientUpdate)\n\t\t\t\t\t\tconst topic = `tx:sync:${transactionId}`\n\t\t\t\t\t\tconst sync = (serverUpdate: typeof clientUpdate) => {\n\t\t\t\t\t\t\tstore.config.logger?.info(`Transaction ${token.key} synced`)\n\t\t\t\t\t\t\tsocket.off(topic, sync)\n\t\t\t\t\t\t\tconst serverResult = JSON.stringify(serverUpdate)\n\t\t\t\t\t\t\tif (clientResult !== serverResult) {\n\t\t\t\t\t\t\t\tstore.config.logger?.error(\n\t\t\t\t\t\t\t\t\t`Transaction ${token.key} produced different results on client and server`,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tstore.config.logger?.error(`Client:`, clientResult)\n\t\t\t\t\t\t\t\tstore.config.logger?.error(`Server:`, serverResult)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tstore.config.logger?.info(\n\t\t\t\t\t\t\t\t\t`Transaction ${token.key} results match`,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsocket.on(topic, sync)\n\t\t\t\t\t\tsocket.emit(`tx:${token.key}`, clientUpdate, transactionId)\n\t\t\t\t\t},\n\t\t\t\t\t`use-server-action`,\n\t\t\t\t\tstore,\n\t\t\t )\n\t\t\t: () => null\n\treturn () => {\n\t\tconst newCount = TX_SUBS.get(token.key) ?? 0\n\t\tTX_SUBS.set(token.key, newCount - 1)\n\t\tunsubscribe()\n\t}\n}\n"]}
@@ -0,0 +1,144 @@
1
+ import * as AtomIO from 'atom.io';
2
+ import { parseJson } from 'atom.io/json';
3
+ import { getJsonToken, getUpdateToken } from 'atom.io/internal';
4
+
5
+ // src/realtime-state.ts
6
+ var myIdState__INTERNAL = AtomIO.atom({
7
+ key: `myId__INTERNAL`,
8
+ default: null
9
+ });
10
+ var myIdState = AtomIO.selector({
11
+ key: `myId`,
12
+ get: ({ get }) => get(myIdState__INTERNAL)
13
+ });
14
+ function pullState(token, socket, store) {
15
+ socket.on(`serve:${token.key}`, (data) => {
16
+ AtomIO.setState(token, data, store);
17
+ });
18
+ socket.emit(`sub:${token.key}`);
19
+ return () => {
20
+ socket.off(`serve:${token.key}`);
21
+ socket.emit(`unsub:${token.key}`);
22
+ };
23
+ }
24
+ function pullFamilyMember(token, socket, store) {
25
+ if (!(`family` in token)) {
26
+ console.error(`Token is not a family member:`, token);
27
+ return () => {
28
+ };
29
+ }
30
+ const { key: familyKey, subKey: serializedSubKey } = token.family;
31
+ const subKey = parseJson(serializedSubKey);
32
+ socket == null ? void 0 : socket.on(`serve:${token.key}`, (data) => {
33
+ AtomIO.setState(token, data, store);
34
+ });
35
+ socket == null ? void 0 : socket.emit(`sub:${familyKey}`, subKey);
36
+ return () => {
37
+ socket == null ? void 0 : socket.off(`serve:${token.key}`);
38
+ socket == null ? void 0 : socket.emit(`unsub:${token.key}`);
39
+ };
40
+ }
41
+ function pullMutableState(token, socket, store) {
42
+ const jsonToken = getJsonToken(token);
43
+ const updateToken = getUpdateToken(token);
44
+ socket.on(`init:${token.key}`, (data) => {
45
+ AtomIO.setState(jsonToken, data, store);
46
+ });
47
+ socket.on(
48
+ `next:${token.key}`,
49
+ (data) => {
50
+ AtomIO.setState(updateToken, data, store);
51
+ }
52
+ );
53
+ socket.emit(`sub:${token.key}`);
54
+ return () => {
55
+ socket.off(`init:${token.key}`);
56
+ socket.off(`next:${token.key}`);
57
+ socket.emit(`unsub:${token.key}`);
58
+ };
59
+ }
60
+ function pullMutableFamilyMember(token, socket, store) {
61
+ if (!(`family` in token)) {
62
+ console.error(`Token is not a family member:`, token);
63
+ return () => {
64
+ };
65
+ }
66
+ const { key: familyKey, subKey: serializedSubKey } = token.family;
67
+ const subKey = parseJson(serializedSubKey);
68
+ socket == null ? void 0 : socket.on(`init:${token.key}`, (data) => {
69
+ const jsonToken = getJsonToken(token);
70
+ AtomIO.setState(jsonToken, data, store);
71
+ });
72
+ socket == null ? void 0 : socket.on(
73
+ `next:${token.key}`,
74
+ (data) => {
75
+ const trackerToken = getUpdateToken(token);
76
+ AtomIO.setState(trackerToken, data, store);
77
+ }
78
+ );
79
+ socket == null ? void 0 : socket.emit(`sub:${familyKey}`, subKey);
80
+ return () => {
81
+ socket == null ? void 0 : socket.off(`serve:${token.key}`);
82
+ socket == null ? void 0 : socket.emit(`unsub:${token.key}`);
83
+ };
84
+ }
85
+ function pushState(token, socket, subscriptionKey, store) {
86
+ socket.emit(`claim:${token.key}`);
87
+ AtomIO.subscribe(
88
+ token,
89
+ ({ newValue }) => {
90
+ socket.emit(`pub:${token.key}`, newValue);
91
+ },
92
+ subscriptionKey,
93
+ store
94
+ );
95
+ return () => {
96
+ socket.off(`pub:${token.key}`);
97
+ socket.emit(`unclaim:${token.key}`);
98
+ };
99
+ }
100
+ var TX_SUBS = /* @__PURE__ */ new Map();
101
+ function synchronizeTransactionResults(token, socket, store) {
102
+ var _a;
103
+ const count = (_a = TX_SUBS.get(token.key)) != null ? _a : 0;
104
+ TX_SUBS.set(token.key, count + 1);
105
+ const unsubscribe = count === 0 ? AtomIO.subscribeToTransaction(
106
+ token,
107
+ (clientUpdate) => {
108
+ const transactionId = Math.random().toString(36).slice(2);
109
+ const clientResult = JSON.stringify(clientUpdate);
110
+ const topic = `tx:sync:${transactionId}`;
111
+ const sync = (serverUpdate) => {
112
+ var _a2, _b, _c, _d, _e;
113
+ (_a2 = store.config.logger) == null ? void 0 : _a2.info(`Transaction ${token.key} synced`);
114
+ socket.off(topic, sync);
115
+ const serverResult = JSON.stringify(serverUpdate);
116
+ if (clientResult !== serverResult) {
117
+ (_b = store.config.logger) == null ? void 0 : _b.error(
118
+ `Transaction ${token.key} produced different results on client and server`
119
+ );
120
+ (_c = store.config.logger) == null ? void 0 : _c.error(`Client:`, clientResult);
121
+ (_d = store.config.logger) == null ? void 0 : _d.error(`Server:`, serverResult);
122
+ } else {
123
+ (_e = store.config.logger) == null ? void 0 : _e.info(
124
+ `Transaction ${token.key} results match`
125
+ );
126
+ }
127
+ };
128
+ socket.on(topic, sync);
129
+ socket.emit(`tx:${token.key}`, clientUpdate, transactionId);
130
+ },
131
+ `use-server-action`,
132
+ store
133
+ ) : () => null;
134
+ return () => {
135
+ var _a2;
136
+ const newCount = (_a2 = TX_SUBS.get(token.key)) != null ? _a2 : 0;
137
+ TX_SUBS.set(token.key, newCount - 1);
138
+ unsubscribe();
139
+ };
140
+ }
141
+
142
+ export { myIdState, myIdState__INTERNAL, pullFamilyMember, pullMutableFamilyMember, pullMutableState, pullState, pushState, synchronizeTransactionResults };
143
+ //# sourceMappingURL=out.js.map
144
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/realtime-state.ts","../src/use-pull.ts","../src/use-pull-family-member.ts","../src/use-pull-mutable.ts","../src/use-pull-mutable-family-member.ts","../src/use-push.ts","../src/use-server-action.ts"],"names":["AtomIO","getJsonToken","getUpdateToken","parseJson","_a"],"mappings":"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","sourcesContent":["import * as AtomIO from \"atom.io\"\n\nexport const myIdState__INTERNAL = AtomIO.atom<string | null>({\n\tkey: `myId__INTERNAL`,\n\tdefault: null,\n})\nexport const myIdState = AtomIO.selector<string | null>({\n\tkey: `myId`,\n\tget: ({ get }) => get(myIdState__INTERNAL),\n})\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullState<J extends Json.Serializable>(\n\ttoken: AtomIO.StateToken<J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tsocket.on(`serve:${token.key}`, (data) => {\n\t\tAtomIO.setState(token, data, store)\n\t})\n\tsocket.emit(`sub:${token.key}`)\n\treturn () => {\n\t\tsocket.off(`serve:${token.key}`)\n\t\tsocket.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { parseJson } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullFamilyMember<J extends Json.Serializable>(\n\ttoken: AtomIO.AtomToken<J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tif (!(`family` in token)) {\n\t\tconsole.error(`Token is not a family member:`, token)\n\t\treturn () => {}\n\t}\n\tconst { key: familyKey, subKey: serializedSubKey } = token.family\n\tconst subKey = parseJson(serializedSubKey)\n\tsocket?.on(`serve:${token.key}`, (data: J) => {\n\t\tAtomIO.setState(token, data, store)\n\t})\n\tsocket?.emit(`sub:${familyKey}`, subKey)\n\treturn () => {\n\t\tsocket?.off(`serve:${token.key}`)\n\t\tsocket?.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store, Transceiver } from \"atom.io/internal\"\nimport { getJsonToken, getUpdateToken } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullMutableState<\n\tT extends Transceiver<Json.Serializable>,\n\tJ extends Json.Serializable,\n>(\n\ttoken: AtomIO.MutableAtomToken<T, J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tconst jsonToken = getJsonToken(token)\n\tconst updateToken = getUpdateToken(token)\n\tsocket.on(`init:${token.key}`, (data: J) => {\n\t\tAtomIO.setState(jsonToken, data, store)\n\t})\n\tsocket.on(\n\t\t`next:${token.key}`,\n\t\t(data: T extends Transceiver<infer Update> ? Update : never) => {\n\t\t\tAtomIO.setState(updateToken, data, store)\n\t\t},\n\t)\n\tsocket.emit(`sub:${token.key}`)\n\treturn () => {\n\t\tsocket.off(`init:${token.key}`)\n\t\tsocket.off(`next:${token.key}`)\n\t\tsocket.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport { getJsonToken, getUpdateToken } from \"atom.io/internal\"\nimport type { Store, Transceiver } from \"atom.io/internal\"\nimport { parseJson } from \"atom.io/json\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullMutableFamilyMember<\n\tT extends Transceiver<Json.Serializable>,\n\tJ extends Json.Serializable,\n>(\n\ttoken: AtomIO.MutableAtomToken<T, J>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tif (!(`family` in token)) {\n\t\tconsole.error(`Token is not a family member:`, token)\n\t\treturn () => {}\n\t}\n\tconst { key: familyKey, subKey: serializedSubKey } = token.family\n\tconst subKey = parseJson(serializedSubKey)\n\tsocket?.on(`init:${token.key}`, (data: J) => {\n\t\tconst jsonToken = getJsonToken(token)\n\t\tAtomIO.setState(jsonToken, data, store)\n\t})\n\tsocket?.on(\n\t\t`next:${token.key}`,\n\t\t(data: T extends Transceiver<infer Signal> ? Signal : never) => {\n\t\t\tconst trackerToken = getUpdateToken(token)\n\t\t\tAtomIO.setState(trackerToken, data, store)\n\t\t},\n\t)\n\tsocket?.emit(`sub:${familyKey}`, subKey)\n\treturn () => {\n\t\tsocket?.off(`serve:${token.key}`)\n\t\tsocket?.emit(`unsub:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pushState<J extends Json.Serializable>(\n\ttoken: AtomIO.StateToken<J>,\n\tsocket: Socket,\n\tsubscriptionKey: string,\n\tstore: Store,\n): () => void {\n\tsocket.emit(`claim:${token.key}`)\n\tAtomIO.subscribe(\n\t\ttoken,\n\t\t({ newValue }) => {\n\t\t\tsocket.emit(`pub:${token.key}`, newValue)\n\t\t},\n\t\tsubscriptionKey,\n\t\tstore,\n\t)\n\treturn () => {\n\t\tsocket.off(`pub:${token.key}`)\n\t\tsocket.emit(`unclaim:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Socket } from \"socket.io-client\"\n\nconst TX_SUBS = new Map<string, number>()\nexport function synchronizeTransactionResults(\n\ttoken: AtomIO.TransactionToken<any>,\n\tsocket: Socket,\n\tstore: Store,\n): () => void {\n\tconst count = TX_SUBS.get(token.key) ?? 0\n\tTX_SUBS.set(token.key, count + 1)\n\tconst unsubscribe =\n\t\tcount === 0\n\t\t\t? AtomIO.subscribeToTransaction(\n\t\t\t\t\ttoken,\n\t\t\t\t\t(clientUpdate) => {\n\t\t\t\t\t\tconst transactionId = Math.random().toString(36).slice(2)\n\t\t\t\t\t\tconst clientResult = JSON.stringify(clientUpdate)\n\t\t\t\t\t\tconst topic = `tx:sync:${transactionId}`\n\t\t\t\t\t\tconst sync = (serverUpdate: typeof clientUpdate) => {\n\t\t\t\t\t\t\tstore.config.logger?.info(`Transaction ${token.key} synced`)\n\t\t\t\t\t\t\tsocket.off(topic, sync)\n\t\t\t\t\t\t\tconst serverResult = JSON.stringify(serverUpdate)\n\t\t\t\t\t\t\tif (clientResult !== serverResult) {\n\t\t\t\t\t\t\t\tstore.config.logger?.error(\n\t\t\t\t\t\t\t\t\t`Transaction ${token.key} produced different results on client and server`,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tstore.config.logger?.error(`Client:`, clientResult)\n\t\t\t\t\t\t\t\tstore.config.logger?.error(`Server:`, serverResult)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tstore.config.logger?.info(\n\t\t\t\t\t\t\t\t\t`Transaction ${token.key} results match`,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsocket.on(topic, sync)\n\t\t\t\t\t\tsocket.emit(`tx:${token.key}`, clientUpdate, transactionId)\n\t\t\t\t\t},\n\t\t\t\t\t`use-server-action`,\n\t\t\t\t\tstore,\n\t\t\t )\n\t\t\t: () => null\n\treturn () => {\n\t\tconst newCount = TX_SUBS.get(token.key) ?? 0\n\t\tTX_SUBS.set(token.key, newCount - 1)\n\t\tunsubscribe()\n\t}\n}\n"]}
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "atom.io-realtime-client",
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
+ }
@@ -0,0 +1,7 @@
1
+ export * from "./realtime-state"
2
+ export * from "./use-pull"
3
+ export * from "./use-pull-family-member"
4
+ export * from "./use-pull-mutable"
5
+ export * from "./use-pull-mutable-family-member"
6
+ export * from "./use-push"
7
+ export * from "./use-server-action"
@@ -0,0 +1,10 @@
1
+ import * as AtomIO from "atom.io"
2
+
3
+ export const myIdState__INTERNAL = AtomIO.atom<string | null>({
4
+ key: `myId__INTERNAL`,
5
+ default: null,
6
+ })
7
+ export const myIdState = AtomIO.selector<string | null>({
8
+ key: `myId`,
9
+ get: ({ get }) => get(myIdState__INTERNAL),
10
+ })
@@ -0,0 +1,26 @@
1
+ import * as AtomIO from "atom.io"
2
+ import type { Store } from "atom.io/internal"
3
+ import type { Json } from "atom.io/json"
4
+ import { parseJson } from "atom.io/json"
5
+ import type { Socket } from "socket.io-client"
6
+
7
+ export function pullFamilyMember<J extends Json.Serializable>(
8
+ token: AtomIO.AtomToken<J>,
9
+ socket: Socket,
10
+ store: Store,
11
+ ): () => void {
12
+ if (!(`family` in token)) {
13
+ console.error(`Token is not a family member:`, token)
14
+ return () => {}
15
+ }
16
+ const { key: familyKey, subKey: serializedSubKey } = token.family
17
+ const subKey = parseJson(serializedSubKey)
18
+ socket?.on(`serve:${token.key}`, (data: J) => {
19
+ AtomIO.setState(token, data, store)
20
+ })
21
+ socket?.emit(`sub:${familyKey}`, subKey)
22
+ return () => {
23
+ socket?.off(`serve:${token.key}`)
24
+ socket?.emit(`unsub:${token.key}`)
25
+ }
26
+ }
@@ -0,0 +1,38 @@
1
+ import * as AtomIO from "atom.io"
2
+ import { getJsonToken, getUpdateToken } from "atom.io/internal"
3
+ import type { Store, Transceiver } from "atom.io/internal"
4
+ import { parseJson } from "atom.io/json"
5
+ import type { Json } from "atom.io/json"
6
+ import type { Socket } from "socket.io-client"
7
+
8
+ export function pullMutableFamilyMember<
9
+ T extends Transceiver<Json.Serializable>,
10
+ J extends Json.Serializable,
11
+ >(
12
+ token: AtomIO.MutableAtomToken<T, J>,
13
+ socket: Socket,
14
+ store: Store,
15
+ ): () => void {
16
+ if (!(`family` in token)) {
17
+ console.error(`Token is not a family member:`, token)
18
+ return () => {}
19
+ }
20
+ const { key: familyKey, subKey: serializedSubKey } = token.family
21
+ const subKey = parseJson(serializedSubKey)
22
+ socket?.on(`init:${token.key}`, (data: J) => {
23
+ const jsonToken = getJsonToken(token)
24
+ AtomIO.setState(jsonToken, data, store)
25
+ })
26
+ socket?.on(
27
+ `next:${token.key}`,
28
+ (data: T extends Transceiver<infer Signal> ? Signal : never) => {
29
+ const trackerToken = getUpdateToken(token)
30
+ AtomIO.setState(trackerToken, data, store)
31
+ },
32
+ )
33
+ socket?.emit(`sub:${familyKey}`, subKey)
34
+ return () => {
35
+ socket?.off(`serve:${token.key}`)
36
+ socket?.emit(`unsub:${token.key}`)
37
+ }
38
+ }
@@ -0,0 +1,32 @@
1
+ import * as AtomIO from "atom.io"
2
+ import type { Store, Transceiver } from "atom.io/internal"
3
+ import { getJsonToken, getUpdateToken } from "atom.io/internal"
4
+ import type { Json } from "atom.io/json"
5
+ import type { Socket } from "socket.io-client"
6
+
7
+ export function pullMutableState<
8
+ T extends Transceiver<Json.Serializable>,
9
+ J extends Json.Serializable,
10
+ >(
11
+ token: AtomIO.MutableAtomToken<T, J>,
12
+ socket: Socket,
13
+ store: Store,
14
+ ): () => void {
15
+ const jsonToken = getJsonToken(token)
16
+ const updateToken = getUpdateToken(token)
17
+ socket.on(`init:${token.key}`, (data: J) => {
18
+ AtomIO.setState(jsonToken, data, store)
19
+ })
20
+ socket.on(
21
+ `next:${token.key}`,
22
+ (data: T extends Transceiver<infer Update> ? Update : never) => {
23
+ AtomIO.setState(updateToken, data, store)
24
+ },
25
+ )
26
+ socket.emit(`sub:${token.key}`)
27
+ return () => {
28
+ socket.off(`init:${token.key}`)
29
+ socket.off(`next:${token.key}`)
30
+ socket.emit(`unsub:${token.key}`)
31
+ }
32
+ }
@@ -0,0 +1,19 @@
1
+ import * as AtomIO from "atom.io"
2
+ import type { Store } from "atom.io/internal"
3
+ import type { Json } from "atom.io/json"
4
+ import type { Socket } from "socket.io-client"
5
+
6
+ export function pullState<J extends Json.Serializable>(
7
+ token: AtomIO.StateToken<J>,
8
+ socket: Socket,
9
+ store: Store,
10
+ ): () => void {
11
+ socket.on(`serve:${token.key}`, (data) => {
12
+ AtomIO.setState(token, data, store)
13
+ })
14
+ socket.emit(`sub:${token.key}`)
15
+ return () => {
16
+ socket.off(`serve:${token.key}`)
17
+ socket.emit(`unsub:${token.key}`)
18
+ }
19
+ }
@@ -0,0 +1,25 @@
1
+ import * as AtomIO from "atom.io"
2
+ import type { Store } from "atom.io/internal"
3
+ import type { Json } from "atom.io/json"
4
+ import type { Socket } from "socket.io-client"
5
+
6
+ export function pushState<J extends Json.Serializable>(
7
+ token: AtomIO.StateToken<J>,
8
+ socket: Socket,
9
+ subscriptionKey: string,
10
+ store: Store,
11
+ ): () => void {
12
+ socket.emit(`claim:${token.key}`)
13
+ AtomIO.subscribe(
14
+ token,
15
+ ({ newValue }) => {
16
+ socket.emit(`pub:${token.key}`, newValue)
17
+ },
18
+ subscriptionKey,
19
+ store,
20
+ )
21
+ return () => {
22
+ socket.off(`pub:${token.key}`)
23
+ socket.emit(`unclaim:${token.key}`)
24
+ }
25
+ }
@@ -0,0 +1,49 @@
1
+ import * as AtomIO from "atom.io"
2
+ import type { Store } from "atom.io/internal"
3
+ import type { Socket } from "socket.io-client"
4
+
5
+ const TX_SUBS = new Map<string, number>()
6
+ export function synchronizeTransactionResults(
7
+ token: AtomIO.TransactionToken<any>,
8
+ socket: Socket,
9
+ store: Store,
10
+ ): () => void {
11
+ const count = TX_SUBS.get(token.key) ?? 0
12
+ TX_SUBS.set(token.key, count + 1)
13
+ const unsubscribe =
14
+ count === 0
15
+ ? AtomIO.subscribeToTransaction(
16
+ token,
17
+ (clientUpdate) => {
18
+ const transactionId = Math.random().toString(36).slice(2)
19
+ const clientResult = JSON.stringify(clientUpdate)
20
+ const topic = `tx:sync:${transactionId}`
21
+ const sync = (serverUpdate: typeof clientUpdate) => {
22
+ store.config.logger?.info(`Transaction ${token.key} synced`)
23
+ socket.off(topic, sync)
24
+ const serverResult = JSON.stringify(serverUpdate)
25
+ if (clientResult !== serverResult) {
26
+ store.config.logger?.error(
27
+ `Transaction ${token.key} produced different results on client and server`,
28
+ )
29
+ store.config.logger?.error(`Client:`, clientResult)
30
+ store.config.logger?.error(`Server:`, serverResult)
31
+ } else {
32
+ store.config.logger?.info(
33
+ `Transaction ${token.key} results match`,
34
+ )
35
+ }
36
+ }
37
+ socket.on(topic, sync)
38
+ socket.emit(`tx:${token.key}`, clientUpdate, transactionId)
39
+ },
40
+ `use-server-action`,
41
+ store,
42
+ )
43
+ : () => null
44
+ return () => {
45
+ const newCount = TX_SUBS.get(token.key) ?? 0
46
+ TX_SUBS.set(token.key, newCount - 1)
47
+ unsubscribe()
48
+ }
49
+ }
@@ -0,0 +1,25 @@
1
+ import { Transceiver, Store } from 'atom.io/internal';
2
+ import * as SocketIO from 'socket.io';
3
+ import * as AtomIO from 'atom.io';
4
+ import { StateToken } from 'atom.io';
5
+ import { Json } from 'atom.io/json';
6
+
7
+ declare const useExposeSingle: ({ socket, store }: ServerConfig) => <J extends Json.Serializable>(token: AtomIO.StateToken<J>) => () => void;
8
+
9
+ declare const useExposeFamily: ({ socket, store }: ServerConfig) => <J extends Json.Serializable>(family: AtomIO.AtomFamily<J, Json.Serializable> | AtomIO.SelectorFamily<J, Json.Serializable>, index: AtomIO.StateToken<Set<string>>) => () => void;
10
+
11
+ declare const useExposeMutable: ({ socket, store }: ServerConfig) => <Core extends Transceiver<Json.Serializable>, SerializableCore extends Json.Serializable>(token: AtomIO.MutableAtomToken<Core, SerializableCore>) => () => void;
12
+
13
+ declare const useExposeMutableFamily: ({ socket, store }: ServerConfig) => <Family extends AtomIO.MutableAtomFamily<Transceiver<Json.Serializable>, Json.Serializable, Json.Serializable>>(family: Family, index: AtomIO.StateToken<Set<string>>) => () => void;
14
+
15
+ declare const useReceiveTransaction: ({ socket, store }: ServerConfig) => <ƒ extends AtomIO.ƒn>(tx: AtomIO.TransactionToken<ƒ>) => () => void;
16
+ declare function useSyncTransaction({ socket, store }: ServerConfig): <ƒ extends AtomIO.ƒn>(tx: AtomIO.TransactionToken<ƒ>) => () => void;
17
+
18
+ declare const useReceiveState: ({ socket, store }: ServerConfig) => <J extends Json.Serializable>(token: StateToken<J>) => () => void;
19
+
20
+ type ServerConfig = {
21
+ socket: SocketIO.Socket;
22
+ store?: Store;
23
+ };
24
+
25
+ export { ServerConfig, useExposeFamily, useExposeMutable, useExposeMutableFamily, useExposeSingle, useReceiveState, useReceiveTransaction, useSyncTransaction };