atom.io 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +38 -10
  2. package/dist/index.d.mts +598 -0
  3. package/dist/index.d.ts +51 -14
  4. package/dist/index.js +143 -28
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +142 -28
  7. package/dist/index.mjs.map +1 -1
  8. package/json/dist/index.d.mts +18 -0
  9. package/json/dist/index.d.ts +18 -0
  10. package/json/dist/index.js +51 -0
  11. package/json/dist/index.js.map +1 -0
  12. package/json/dist/index.mjs +15 -0
  13. package/json/dist/index.mjs.map +1 -0
  14. package/json/package.json +15 -0
  15. package/package.json +34 -7
  16. package/react/dist/index.d.mts +17 -0
  17. package/react-devtools/dist/index.d.mts +15 -0
  18. package/react-devtools/dist/index.js +1 -1
  19. package/react-devtools/dist/index.js.map +1 -1
  20. package/react-devtools/dist/index.mjs +1 -1
  21. package/react-devtools/dist/index.mjs.map +1 -1
  22. package/realtime/dist/index.d.mts +25 -0
  23. package/realtime/dist/index.d.ts +25 -0
  24. package/realtime/dist/index.js +168 -0
  25. package/realtime/dist/index.js.map +1 -0
  26. package/realtime/dist/index.mjs +130 -0
  27. package/realtime/dist/index.mjs.map +1 -0
  28. package/realtime/package.json +15 -0
  29. package/src/index.ts +22 -0
  30. package/src/internal/atom-internal.ts +1 -1
  31. package/src/internal/families-internal.ts +3 -3
  32. package/src/internal/get.ts +22 -12
  33. package/src/internal/selector-internal.ts +10 -0
  34. package/src/internal/set.ts +1 -1
  35. package/src/internal/store.ts +1 -1
  36. package/src/internal/subscribe-internal.ts +5 -0
  37. package/src/internal/timeline-internal.ts +13 -1
  38. package/src/internal/transaction-internal.ts +24 -9
  39. package/src/json/index.ts +1 -0
  40. package/src/json/select-json.ts +18 -0
  41. package/src/react-explorer/explorer-states.ts +5 -5
  42. package/src/react-explorer/index.ts +1 -1
  43. package/src/react-explorer/space-states.ts +6 -7
  44. package/src/realtime/hook-composition/expose-family.ts +101 -0
  45. package/src/realtime/hook-composition/expose-single.ts +38 -0
  46. package/src/realtime/hook-composition/index.ts +11 -0
  47. package/src/realtime/hook-composition/receive-transaction.ts +19 -0
  48. package/src/realtime/index.ts +1 -0
  49. package/src/realtime-client/hook-composition/compose-realtime-hooks.ts +62 -0
  50. package/src/realtime-client/hook-composition/realtime-client-family-member.ts +28 -0
  51. package/src/realtime-client/hook-composition/realtime-client-family.ts +26 -0
  52. package/src/realtime-client/hook-composition/realtime-client-single.ts +24 -0
  53. package/src/realtime-client/hook-composition/realtime-client-transaction.ts +35 -0
  54. package/src/realtime-client/index.ts +1 -0
  55. package/src/selector.ts +9 -6
  56. package/src/silo.ts +45 -0
  57. package/src/subscribe.ts +13 -1
  58. package/src/transaction.ts +11 -4
@@ -0,0 +1,25 @@
1
+ import * as AtomIO from 'atom.io';
2
+ import * as SocketIO from 'socket.io';
3
+
4
+ type Primitive = boolean | number | string | null;
5
+ type Serializable = Primitive | Readonly<{
6
+ [key: string]: Serializable;
7
+ }> | ReadonlyArray<Serializable>;
8
+ type JsonObj<Key extends string = string, Value extends Serializable = Serializable> = Record<Key, Value>;
9
+ type JsonArr<Element extends Serializable = Serializable> = ReadonlyArray<Element>;
10
+ type Json = JsonArr | JsonObj | Primitive;
11
+
12
+ declare const useExposeSingle: ({ socket, store }: ServerConfig) => <J extends Json>(token: AtomIO.StateToken<J>) => () => void;
13
+
14
+ declare const useExposeFamily: ({ socket, store }: ServerConfig) => <J extends Json>(family: AtomIO.AtomFamily<J, AtomIO.Serializable> | AtomIO.SelectorFamily<J, AtomIO.Serializable>, index: AtomIO.StateToken<Set<string>>) => () => void;
15
+
16
+ type ƒn = (...parameters: any[]) => any;
17
+
18
+ declare const useReceiveTransaction: ({ socket, store }: ServerConfig) => <ƒ extends ƒn>(tx: AtomIO.TransactionToken<ƒ>) => () => void;
19
+
20
+ type ServerConfig = {
21
+ socket: SocketIO.Socket;
22
+ store?: AtomIO.__INTERNAL__.Store;
23
+ };
24
+
25
+ export { ServerConfig, useExposeFamily, useExposeSingle, useReceiveTransaction };
@@ -0,0 +1,25 @@
1
+ import * as AtomIO from 'atom.io';
2
+ import * as SocketIO from 'socket.io';
3
+
4
+ type Primitive = boolean | number | string | null;
5
+ type Serializable = Primitive | Readonly<{
6
+ [key: string]: Serializable;
7
+ }> | ReadonlyArray<Serializable>;
8
+ type JsonObj<Key extends string = string, Value extends Serializable = Serializable> = Record<Key, Value>;
9
+ type JsonArr<Element extends Serializable = Serializable> = ReadonlyArray<Element>;
10
+ type Json = JsonArr | JsonObj | Primitive;
11
+
12
+ declare const useExposeSingle: ({ socket, store }: ServerConfig) => <J extends Json>(token: AtomIO.StateToken<J>) => () => void;
13
+
14
+ declare const useExposeFamily: ({ socket, store }: ServerConfig) => <J extends Json>(family: AtomIO.AtomFamily<J, AtomIO.Serializable> | AtomIO.SelectorFamily<J, AtomIO.Serializable>, index: AtomIO.StateToken<Set<string>>) => () => void;
15
+
16
+ type ƒn = (...parameters: any[]) => any;
17
+
18
+ declare const useReceiveTransaction: ({ socket, store }: ServerConfig) => <ƒ extends ƒn>(tx: AtomIO.TransactionToken<ƒ>) => () => void;
19
+
20
+ type ServerConfig = {
21
+ socket: SocketIO.Socket;
22
+ store?: AtomIO.__INTERNAL__.Store;
23
+ };
24
+
25
+ export { ServerConfig, useExposeFamily, useExposeSingle, useReceiveTransaction };
@@ -0,0 +1,168 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+
29
+ // ../src/realtime/index.ts
30
+ var realtime_exports = {};
31
+ __export(realtime_exports, {
32
+ useExposeFamily: () => useExposeFamily,
33
+ useExposeSingle: () => useExposeSingle,
34
+ useReceiveTransaction: () => useReceiveTransaction
35
+ });
36
+ module.exports = __toCommonJS(realtime_exports);
37
+
38
+ // ../src/realtime/hook-composition/expose-single.ts
39
+ var AtomIO = __toESM(require("atom.io"));
40
+ var useExposeSingle = ({ socket, store }) => {
41
+ return function exposeSingle(token) {
42
+ let unsubscribeFromStateUpdates = null;
43
+ const fillUnsubRequest = () => {
44
+ socket.off(`unsub:${token.key}`, fillUnsubRequest);
45
+ unsubscribeFromStateUpdates == null ? void 0 : unsubscribeFromStateUpdates();
46
+ unsubscribeFromStateUpdates = null;
47
+ };
48
+ const fillSubRequest = () => {
49
+ socket.emit(`serve:${token.key}`, AtomIO.getState(token, store));
50
+ unsubscribeFromStateUpdates = AtomIO.subscribe(
51
+ token,
52
+ ({ newValue }) => {
53
+ socket.emit(`serve:${token.key}`, newValue);
54
+ },
55
+ store
56
+ );
57
+ socket.on(`unsub:${token.key}`, fillUnsubRequest);
58
+ };
59
+ socket.on(`sub:${token.key}`, fillSubRequest);
60
+ return () => {
61
+ socket.off(`sub:${token.key}`, fillSubRequest);
62
+ unsubscribeFromStateUpdates == null ? void 0 : unsubscribeFromStateUpdates();
63
+ };
64
+ };
65
+ };
66
+
67
+ // ../../anvl/src/json/index.ts
68
+ var import_function = require("fp-ts/function");
69
+ var parseJson = (str) => JSON.parse(str);
70
+
71
+ // ../src/realtime/hook-composition/expose-family.ts
72
+ var AtomIO2 = __toESM(require("atom.io"));
73
+ var subscribeToTokenCreation = (family, handleTokenCreation) => {
74
+ const subscription = family.type === `atom_family` ? family.subject.subscribe(handleTokenCreation) : family.subject.subscribe(handleTokenCreation);
75
+ return () => subscription.unsubscribe();
76
+ };
77
+ var useExposeFamily = ({ socket, store }) => {
78
+ return function exposeFamily(family, index) {
79
+ const unsubSingleCallbacksByKey = /* @__PURE__ */ new Map();
80
+ const unsubFamilyCallbacksByKey = /* @__PURE__ */ new Map();
81
+ const fillFamilyUnsubRequest = () => {
82
+ unsubFamilyCallbacksByKey.forEach((unsub) => unsub());
83
+ unsubFamilyCallbacksByKey.clear();
84
+ socket.off(`unsub:${family.key}`, fillFamilyUnsubRequest);
85
+ };
86
+ const fillSingleUnsubRequest = (key) => {
87
+ socket.off(`unsub:${key}`, fillSingleUnsubRequest);
88
+ const unsub = unsubSingleCallbacksByKey.get(key);
89
+ if (unsub) {
90
+ unsub();
91
+ unsubSingleCallbacksByKey.delete(key);
92
+ }
93
+ };
94
+ const fillSubRequest = (subKey) => {
95
+ if (subKey === void 0) {
96
+ const keys = AtomIO2.getState(index, store);
97
+ keys.forEach((key) => {
98
+ var _a;
99
+ const token = family(key);
100
+ socket.emit(
101
+ `serve:${family.key}`,
102
+ parseJson(((_a = token.family) == null ? void 0 : _a.subKey) || `null`),
103
+ AtomIO2.getState(token, store)
104
+ );
105
+ });
106
+ const unsubscribeFromTokenCreation = subscribeToTokenCreation(
107
+ family,
108
+ (token) => {
109
+ const unsub = AtomIO2.subscribe(
110
+ token,
111
+ ({ newValue }) => {
112
+ var _a;
113
+ socket.emit(
114
+ `serve:${family.key}`,
115
+ parseJson(((_a = token.family) == null ? void 0 : _a.subKey) || `null`),
116
+ newValue
117
+ );
118
+ },
119
+ store
120
+ );
121
+ unsubFamilyCallbacksByKey.set(token.key, unsub);
122
+ }
123
+ );
124
+ unsubFamilyCallbacksByKey.set(family.key, unsubscribeFromTokenCreation);
125
+ socket.on(`unsub:${family.key}`, fillFamilyUnsubRequest);
126
+ } else {
127
+ const token = family(subKey);
128
+ socket.emit(`serve:${token.key}`, AtomIO2.getState(token, store));
129
+ const unsubscribe = AtomIO2.subscribe(
130
+ token,
131
+ ({ newValue }) => {
132
+ socket.emit(`serve:${token.key}`, newValue);
133
+ },
134
+ store
135
+ );
136
+ unsubSingleCallbacksByKey.set(token.key, unsubscribe);
137
+ socket.on(`unsub:${token.key}`, () => {
138
+ fillSingleUnsubRequest(token.key);
139
+ });
140
+ }
141
+ };
142
+ socket.on(`sub:${family.key}`, fillSubRequest);
143
+ return () => {
144
+ socket.off(`sub:${family.key}`, fillSubRequest);
145
+ unsubFamilyCallbacksByKey.forEach((unsub) => unsub());
146
+ unsubSingleCallbacksByKey.forEach((unsub) => unsub());
147
+ unsubFamilyCallbacksByKey.clear();
148
+ unsubSingleCallbacksByKey.clear();
149
+ };
150
+ };
151
+ };
152
+
153
+ // ../src/realtime/hook-composition/receive-transaction.ts
154
+ var AtomIO3 = __toESM(require("atom.io"));
155
+ var useReceiveTransaction = ({ socket, store }) => {
156
+ return function receiveTransaction(tx) {
157
+ const fillTransactionRequest = (update) => AtomIO3.runTransaction(tx, store)(...update.params);
158
+ socket.on(`tx:${tx.key}`, fillTransactionRequest);
159
+ return () => socket.off(`tx:${tx.key}`, fillTransactionRequest);
160
+ };
161
+ };
162
+ // Annotate the CommonJS export names for ESM import in node:
163
+ 0 && (module.exports = {
164
+ useExposeFamily,
165
+ useExposeSingle,
166
+ useReceiveTransaction
167
+ });
168
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/realtime/index.ts","../../src/realtime/hook-composition/expose-single.ts","../../../anvl/src/json/index.ts","../../src/realtime/hook-composition/expose-family.ts","../../src/realtime/hook-composition/receive-transaction.ts"],"sourcesContent":["export * from \"./hook-composition\"\n","import type { Json } from \"anvl/json\"\nimport * as AtomIO from \"atom.io\"\n\nimport type { ServerConfig } from \"..\"\n\n/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\nexport const useExposeSingle = ({ socket, store }: ServerConfig) => {\n return function exposeSingle<J extends Json>(\n token: AtomIO.StateToken<J>\n ): () => void {\n let unsubscribeFromStateUpdates: (() => void) | null = null\n\n const fillUnsubRequest = () => {\n socket.off(`unsub:${token.key}`, fillUnsubRequest)\n unsubscribeFromStateUpdates?.()\n unsubscribeFromStateUpdates = null\n }\n\n const fillSubRequest = () => {\n socket.emit(`serve:${token.key}`, AtomIO.getState(token, store))\n unsubscribeFromStateUpdates = AtomIO.subscribe(\n token,\n ({ newValue }) => {\n socket.emit(`serve:${token.key}`, newValue)\n },\n store\n )\n socket.on(`unsub:${token.key}`, fillUnsubRequest)\n }\n\n socket.on(`sub:${token.key}`, fillSubRequest)\n\n return () => {\n socket.off(`sub:${token.key}`, fillSubRequest)\n unsubscribeFromStateUpdates?.()\n }\n }\n}\n","import { pipe } from \"fp-ts/function\"\n\nexport * from \"./refine\"\nexport * from \"./json-interface\"\n\nexport const serializeSet = <T>(set: Set<T>): string =>\n pipe(set, Array.from, JSON.stringify)\n\nexport const deserializeSet = <T>(str: string): Set<T> =>\n pipe(str, JSON.parse, Array.from, (a) => new Set(a as T[]))\n\nexport type Primitive = boolean | number | string | null\n\nexport type Serializable =\n | Primitive\n | Readonly<{ [key: string]: Serializable }>\n | ReadonlyArray<Serializable>\n\nexport type JsonObj<\n Key extends string = string,\n Value extends Serializable = Serializable\n> = Record<Key, Value>\n\nexport type JsonArr<Element extends Serializable = Serializable> =\n ReadonlyArray<Element>\n\nexport type Json = JsonArr | JsonObj | Primitive\n\nexport const parseJson = <J extends Json, S extends Stringified<J> | string>(\n str: S | string\n): S extends Stringified<J> ? J : Json => JSON.parse(str)\n\nexport type Stringified<J extends Json> = string & { __json: J }\n\nexport const stringifyJson = <J extends Json>(json: J): Stringified<J> =>\n JSON.stringify(json) as Stringified<J>\n\nexport type Empty = Record<string, never>\n\nexport const JSON_TYPE_NAMES = [\n `array`,\n `boolean`,\n `null`,\n `number`,\n `object`,\n `string`,\n] as const\n\nexport type JsonTypeName = (typeof JSON_TYPE_NAMES)[number]\n\nexport interface JsonTypes extends Record<JsonTypeName, Json> {\n array: JsonArr\n boolean: boolean\n null: null\n number: number\n object: JsonObj\n string: string\n}\n\nexport const JSON_DEFAULTS: JsonTypes = {\n array: [],\n boolean: false,\n null: null,\n number: 0,\n object: {},\n string: ``,\n}\n","import type { Json } from \"anvl/json\"\nimport { parseJson } from \"anvl/json\"\nimport * as AtomIO from \"atom.io\"\n\nimport type { ServerConfig } from \"..\"\n\nconst subscribeToTokenCreation = <T>(\n family: AtomIO.AtomFamily<T> | AtomIO.SelectorFamily<T>,\n handleTokenCreation: (token: AtomIO.StateToken<T>) => void\n): (() => void) => {\n const subscription =\n family.type === `atom_family`\n ? family.subject.subscribe(handleTokenCreation)\n : family.subject.subscribe(handleTokenCreation)\n return () => subscription.unsubscribe()\n}\n\n/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\nexport const useExposeFamily = ({ socket, store }: ServerConfig) => {\n return function exposeFamily<J extends Json>(\n family: AtomIO.AtomFamily<J> | AtomIO.SelectorFamily<J>,\n index: AtomIO.StateToken<Set<string>>\n ): () => void {\n const unsubSingleCallbacksByKey = new Map<string, () => void>()\n const unsubFamilyCallbacksByKey = new Map<string, () => void>()\n\n const fillFamilyUnsubRequest = () => {\n unsubFamilyCallbacksByKey.forEach((unsub) => unsub())\n unsubFamilyCallbacksByKey.clear()\n socket.off(`unsub:${family.key}`, fillFamilyUnsubRequest)\n }\n\n const fillSingleUnsubRequest = (key: string) => {\n socket.off(`unsub:${key}`, fillSingleUnsubRequest)\n const unsub = unsubSingleCallbacksByKey.get(key)\n if (unsub) {\n unsub()\n unsubSingleCallbacksByKey.delete(key)\n }\n }\n\n const fillSubRequest = (subKey?: AtomIO.Serializable) => {\n if (subKey === undefined) {\n const keys = AtomIO.getState(index, store)\n keys.forEach((key) => {\n const token = family(key)\n socket.emit(\n `serve:${family.key}`,\n parseJson(token.family?.subKey || `null`),\n AtomIO.getState(token, store)\n )\n })\n\n const unsubscribeFromTokenCreation = subscribeToTokenCreation(\n family,\n (token) => {\n const unsub = AtomIO.subscribe(\n token,\n ({ newValue }) => {\n socket.emit(\n `serve:${family.key}`,\n parseJson(token.family?.subKey || `null`),\n newValue\n )\n },\n store\n )\n unsubFamilyCallbacksByKey.set(token.key, unsub)\n }\n )\n unsubFamilyCallbacksByKey.set(family.key, unsubscribeFromTokenCreation)\n\n socket.on(`unsub:${family.key}`, fillFamilyUnsubRequest)\n } else {\n const token = family(subKey)\n socket.emit(`serve:${token.key}`, AtomIO.getState(token, store))\n const unsubscribe = AtomIO.subscribe(\n token,\n ({ newValue }) => {\n socket.emit(`serve:${token.key}`, newValue)\n },\n store\n )\n unsubSingleCallbacksByKey.set(token.key, unsubscribe)\n socket.on(`unsub:${token.key}`, () => {\n fillSingleUnsubRequest(token.key)\n })\n }\n }\n\n socket.on(`sub:${family.key}`, fillSubRequest)\n\n return () => {\n socket.off(`sub:${family.key}`, fillSubRequest)\n unsubFamilyCallbacksByKey.forEach((unsub) => unsub())\n unsubSingleCallbacksByKey.forEach((unsub) => unsub())\n unsubFamilyCallbacksByKey.clear()\n unsubSingleCallbacksByKey.clear()\n }\n }\n}\n","import * as AtomIO from \"atom.io\"\n\nimport type { ƒn } from \"~/packages/anvl/src/function\"\n\nimport type { ServerConfig } from \".\"\n\nexport const useReceiveTransaction = ({ socket, store }: ServerConfig) => {\n return function receiveTransaction<ƒ extends ƒn>(\n tx: AtomIO.TransactionToken<ƒ>\n ): () => void {\n const fillTransactionRequest = (\n update: AtomIO.__INTERNAL__.TransactionUpdate<ƒ>\n ) => AtomIO.runTransaction<ƒ>(tx, store)(...update.params)\n\n socket.on(`tx:${tx.key}`, fillTransactionRequest)\n\n return () => socket.off(`tx:${tx.key}`, fillTransactionRequest)\n }\n}\n"],"mappings":"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","names":["AtomIO","AtomIO"]}
@@ -0,0 +1,130 @@
1
+ // ../src/realtime/hook-composition/expose-single.ts
2
+ import * as AtomIO from "atom.io";
3
+ var useExposeSingle = ({ socket, store }) => {
4
+ return function exposeSingle(token) {
5
+ let unsubscribeFromStateUpdates = null;
6
+ const fillUnsubRequest = () => {
7
+ socket.off(`unsub:${token.key}`, fillUnsubRequest);
8
+ unsubscribeFromStateUpdates == null ? void 0 : unsubscribeFromStateUpdates();
9
+ unsubscribeFromStateUpdates = null;
10
+ };
11
+ const fillSubRequest = () => {
12
+ socket.emit(`serve:${token.key}`, AtomIO.getState(token, store));
13
+ unsubscribeFromStateUpdates = AtomIO.subscribe(
14
+ token,
15
+ ({ newValue }) => {
16
+ socket.emit(`serve:${token.key}`, newValue);
17
+ },
18
+ store
19
+ );
20
+ socket.on(`unsub:${token.key}`, fillUnsubRequest);
21
+ };
22
+ socket.on(`sub:${token.key}`, fillSubRequest);
23
+ return () => {
24
+ socket.off(`sub:${token.key}`, fillSubRequest);
25
+ unsubscribeFromStateUpdates == null ? void 0 : unsubscribeFromStateUpdates();
26
+ };
27
+ };
28
+ };
29
+
30
+ // ../../anvl/src/json/index.ts
31
+ import { pipe } from "fp-ts/function";
32
+ var parseJson = (str) => JSON.parse(str);
33
+
34
+ // ../src/realtime/hook-composition/expose-family.ts
35
+ import * as AtomIO2 from "atom.io";
36
+ var subscribeToTokenCreation = (family, handleTokenCreation) => {
37
+ const subscription = family.type === `atom_family` ? family.subject.subscribe(handleTokenCreation) : family.subject.subscribe(handleTokenCreation);
38
+ return () => subscription.unsubscribe();
39
+ };
40
+ var useExposeFamily = ({ socket, store }) => {
41
+ return function exposeFamily(family, index) {
42
+ const unsubSingleCallbacksByKey = /* @__PURE__ */ new Map();
43
+ const unsubFamilyCallbacksByKey = /* @__PURE__ */ new Map();
44
+ const fillFamilyUnsubRequest = () => {
45
+ unsubFamilyCallbacksByKey.forEach((unsub) => unsub());
46
+ unsubFamilyCallbacksByKey.clear();
47
+ socket.off(`unsub:${family.key}`, fillFamilyUnsubRequest);
48
+ };
49
+ const fillSingleUnsubRequest = (key) => {
50
+ socket.off(`unsub:${key}`, fillSingleUnsubRequest);
51
+ const unsub = unsubSingleCallbacksByKey.get(key);
52
+ if (unsub) {
53
+ unsub();
54
+ unsubSingleCallbacksByKey.delete(key);
55
+ }
56
+ };
57
+ const fillSubRequest = (subKey) => {
58
+ if (subKey === void 0) {
59
+ const keys = AtomIO2.getState(index, store);
60
+ keys.forEach((key) => {
61
+ var _a;
62
+ const token = family(key);
63
+ socket.emit(
64
+ `serve:${family.key}`,
65
+ parseJson(((_a = token.family) == null ? void 0 : _a.subKey) || `null`),
66
+ AtomIO2.getState(token, store)
67
+ );
68
+ });
69
+ const unsubscribeFromTokenCreation = subscribeToTokenCreation(
70
+ family,
71
+ (token) => {
72
+ const unsub = AtomIO2.subscribe(
73
+ token,
74
+ ({ newValue }) => {
75
+ var _a;
76
+ socket.emit(
77
+ `serve:${family.key}`,
78
+ parseJson(((_a = token.family) == null ? void 0 : _a.subKey) || `null`),
79
+ newValue
80
+ );
81
+ },
82
+ store
83
+ );
84
+ unsubFamilyCallbacksByKey.set(token.key, unsub);
85
+ }
86
+ );
87
+ unsubFamilyCallbacksByKey.set(family.key, unsubscribeFromTokenCreation);
88
+ socket.on(`unsub:${family.key}`, fillFamilyUnsubRequest);
89
+ } else {
90
+ const token = family(subKey);
91
+ socket.emit(`serve:${token.key}`, AtomIO2.getState(token, store));
92
+ const unsubscribe = AtomIO2.subscribe(
93
+ token,
94
+ ({ newValue }) => {
95
+ socket.emit(`serve:${token.key}`, newValue);
96
+ },
97
+ store
98
+ );
99
+ unsubSingleCallbacksByKey.set(token.key, unsubscribe);
100
+ socket.on(`unsub:${token.key}`, () => {
101
+ fillSingleUnsubRequest(token.key);
102
+ });
103
+ }
104
+ };
105
+ socket.on(`sub:${family.key}`, fillSubRequest);
106
+ return () => {
107
+ socket.off(`sub:${family.key}`, fillSubRequest);
108
+ unsubFamilyCallbacksByKey.forEach((unsub) => unsub());
109
+ unsubSingleCallbacksByKey.forEach((unsub) => unsub());
110
+ unsubFamilyCallbacksByKey.clear();
111
+ unsubSingleCallbacksByKey.clear();
112
+ };
113
+ };
114
+ };
115
+
116
+ // ../src/realtime/hook-composition/receive-transaction.ts
117
+ import * as AtomIO3 from "atom.io";
118
+ var useReceiveTransaction = ({ socket, store }) => {
119
+ return function receiveTransaction(tx) {
120
+ const fillTransactionRequest = (update) => AtomIO3.runTransaction(tx, store)(...update.params);
121
+ socket.on(`tx:${tx.key}`, fillTransactionRequest);
122
+ return () => socket.off(`tx:${tx.key}`, fillTransactionRequest);
123
+ };
124
+ };
125
+ export {
126
+ useExposeFamily,
127
+ useExposeSingle,
128
+ useReceiveTransaction
129
+ };
130
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/realtime/hook-composition/expose-single.ts","../../../anvl/src/json/index.ts","../../src/realtime/hook-composition/expose-family.ts","../../src/realtime/hook-composition/receive-transaction.ts"],"sourcesContent":["import type { Json } from \"anvl/json\"\nimport * as AtomIO from \"atom.io\"\n\nimport type { ServerConfig } from \"..\"\n\n/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\nexport const useExposeSingle = ({ socket, store }: ServerConfig) => {\n return function exposeSingle<J extends Json>(\n token: AtomIO.StateToken<J>\n ): () => void {\n let unsubscribeFromStateUpdates: (() => void) | null = null\n\n const fillUnsubRequest = () => {\n socket.off(`unsub:${token.key}`, fillUnsubRequest)\n unsubscribeFromStateUpdates?.()\n unsubscribeFromStateUpdates = null\n }\n\n const fillSubRequest = () => {\n socket.emit(`serve:${token.key}`, AtomIO.getState(token, store))\n unsubscribeFromStateUpdates = AtomIO.subscribe(\n token,\n ({ newValue }) => {\n socket.emit(`serve:${token.key}`, newValue)\n },\n store\n )\n socket.on(`unsub:${token.key}`, fillUnsubRequest)\n }\n\n socket.on(`sub:${token.key}`, fillSubRequest)\n\n return () => {\n socket.off(`sub:${token.key}`, fillSubRequest)\n unsubscribeFromStateUpdates?.()\n }\n }\n}\n","import { pipe } from \"fp-ts/function\"\n\nexport * from \"./refine\"\nexport * from \"./json-interface\"\n\nexport const serializeSet = <T>(set: Set<T>): string =>\n pipe(set, Array.from, JSON.stringify)\n\nexport const deserializeSet = <T>(str: string): Set<T> =>\n pipe(str, JSON.parse, Array.from, (a) => new Set(a as T[]))\n\nexport type Primitive = boolean | number | string | null\n\nexport type Serializable =\n | Primitive\n | Readonly<{ [key: string]: Serializable }>\n | ReadonlyArray<Serializable>\n\nexport type JsonObj<\n Key extends string = string,\n Value extends Serializable = Serializable\n> = Record<Key, Value>\n\nexport type JsonArr<Element extends Serializable = Serializable> =\n ReadonlyArray<Element>\n\nexport type Json = JsonArr | JsonObj | Primitive\n\nexport const parseJson = <J extends Json, S extends Stringified<J> | string>(\n str: S | string\n): S extends Stringified<J> ? J : Json => JSON.parse(str)\n\nexport type Stringified<J extends Json> = string & { __json: J }\n\nexport const stringifyJson = <J extends Json>(json: J): Stringified<J> =>\n JSON.stringify(json) as Stringified<J>\n\nexport type Empty = Record<string, never>\n\nexport const JSON_TYPE_NAMES = [\n `array`,\n `boolean`,\n `null`,\n `number`,\n `object`,\n `string`,\n] as const\n\nexport type JsonTypeName = (typeof JSON_TYPE_NAMES)[number]\n\nexport interface JsonTypes extends Record<JsonTypeName, Json> {\n array: JsonArr\n boolean: boolean\n null: null\n number: number\n object: JsonObj\n string: string\n}\n\nexport const JSON_DEFAULTS: JsonTypes = {\n array: [],\n boolean: false,\n null: null,\n number: 0,\n object: {},\n string: ``,\n}\n","import type { Json } from \"anvl/json\"\nimport { parseJson } from \"anvl/json\"\nimport * as AtomIO from \"atom.io\"\n\nimport type { ServerConfig } from \"..\"\n\nconst subscribeToTokenCreation = <T>(\n family: AtomIO.AtomFamily<T> | AtomIO.SelectorFamily<T>,\n handleTokenCreation: (token: AtomIO.StateToken<T>) => void\n): (() => void) => {\n const subscription =\n family.type === `atom_family`\n ? family.subject.subscribe(handleTokenCreation)\n : family.subject.subscribe(handleTokenCreation)\n return () => subscription.unsubscribe()\n}\n\n/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\nexport const useExposeFamily = ({ socket, store }: ServerConfig) => {\n return function exposeFamily<J extends Json>(\n family: AtomIO.AtomFamily<J> | AtomIO.SelectorFamily<J>,\n index: AtomIO.StateToken<Set<string>>\n ): () => void {\n const unsubSingleCallbacksByKey = new Map<string, () => void>()\n const unsubFamilyCallbacksByKey = new Map<string, () => void>()\n\n const fillFamilyUnsubRequest = () => {\n unsubFamilyCallbacksByKey.forEach((unsub) => unsub())\n unsubFamilyCallbacksByKey.clear()\n socket.off(`unsub:${family.key}`, fillFamilyUnsubRequest)\n }\n\n const fillSingleUnsubRequest = (key: string) => {\n socket.off(`unsub:${key}`, fillSingleUnsubRequest)\n const unsub = unsubSingleCallbacksByKey.get(key)\n if (unsub) {\n unsub()\n unsubSingleCallbacksByKey.delete(key)\n }\n }\n\n const fillSubRequest = (subKey?: AtomIO.Serializable) => {\n if (subKey === undefined) {\n const keys = AtomIO.getState(index, store)\n keys.forEach((key) => {\n const token = family(key)\n socket.emit(\n `serve:${family.key}`,\n parseJson(token.family?.subKey || `null`),\n AtomIO.getState(token, store)\n )\n })\n\n const unsubscribeFromTokenCreation = subscribeToTokenCreation(\n family,\n (token) => {\n const unsub = AtomIO.subscribe(\n token,\n ({ newValue }) => {\n socket.emit(\n `serve:${family.key}`,\n parseJson(token.family?.subKey || `null`),\n newValue\n )\n },\n store\n )\n unsubFamilyCallbacksByKey.set(token.key, unsub)\n }\n )\n unsubFamilyCallbacksByKey.set(family.key, unsubscribeFromTokenCreation)\n\n socket.on(`unsub:${family.key}`, fillFamilyUnsubRequest)\n } else {\n const token = family(subKey)\n socket.emit(`serve:${token.key}`, AtomIO.getState(token, store))\n const unsubscribe = AtomIO.subscribe(\n token,\n ({ newValue }) => {\n socket.emit(`serve:${token.key}`, newValue)\n },\n store\n )\n unsubSingleCallbacksByKey.set(token.key, unsubscribe)\n socket.on(`unsub:${token.key}`, () => {\n fillSingleUnsubRequest(token.key)\n })\n }\n }\n\n socket.on(`sub:${family.key}`, fillSubRequest)\n\n return () => {\n socket.off(`sub:${family.key}`, fillSubRequest)\n unsubFamilyCallbacksByKey.forEach((unsub) => unsub())\n unsubSingleCallbacksByKey.forEach((unsub) => unsub())\n unsubFamilyCallbacksByKey.clear()\n unsubSingleCallbacksByKey.clear()\n }\n }\n}\n","import * as AtomIO from \"atom.io\"\n\nimport type { ƒn } from \"~/packages/anvl/src/function\"\n\nimport type { ServerConfig } from \".\"\n\nexport const useReceiveTransaction = ({ socket, store }: ServerConfig) => {\n return function receiveTransaction<ƒ extends ƒn>(\n tx: AtomIO.TransactionToken<ƒ>\n ): () => void {\n const fillTransactionRequest = (\n update: AtomIO.__INTERNAL__.TransactionUpdate<ƒ>\n ) => AtomIO.runTransaction<ƒ>(tx, store)(...update.params)\n\n socket.on(`tx:${tx.key}`, fillTransactionRequest)\n\n return () => socket.off(`tx:${tx.key}`, fillTransactionRequest)\n }\n}\n"],"mappings":";AACA,YAAY,YAAY;AAKjB,IAAM,kBAAkB,CAAC,EAAE,QAAQ,MAAM,MAAoB;AAClE,SAAO,SAAS,aACd,OACY;AACZ,QAAI,8BAAmD;AAEvD,UAAM,mBAAmB,MAAM;AAC7B,aAAO,IAAI,SAAS,MAAM,OAAO,gBAAgB;AACjD;AACA,oCAA8B;AAAA,IAChC;AAEA,UAAM,iBAAiB,MAAM;AAC3B,aAAO,KAAK,SAAS,MAAM,OAAc,gBAAS,OAAO,KAAK,CAAC;AAC/D,oCAAqC;AAAA,QACnC;AAAA,QACA,CAAC,EAAE,SAAS,MAAM;AAChB,iBAAO,KAAK,SAAS,MAAM,OAAO,QAAQ;AAAA,QAC5C;AAAA,QACA;AAAA,MACF;AACA,aAAO,GAAG,SAAS,MAAM,OAAO,gBAAgB;AAAA,IAClD;AAEA,WAAO,GAAG,OAAO,MAAM,OAAO,cAAc;AAE5C,WAAO,MAAM;AACX,aAAO,IAAI,OAAO,MAAM,OAAO,cAAc;AAC7C;AAAA,IACF;AAAA,EACF;AACF;;;ACrCA,SAAS,YAAY;AA4Bd,IAAM,YAAY,CACvB,QACwC,KAAK,MAAM,GAAG;;;AC5BxD,YAAYA,aAAY;AAIxB,IAAM,2BAA2B,CAC/B,QACA,wBACiB;AACjB,QAAM,eACJ,OAAO,SAAS,gBACZ,OAAO,QAAQ,UAAU,mBAAmB,IAC5C,OAAO,QAAQ,UAAU,mBAAmB;AAClD,SAAO,MAAM,aAAa,YAAY;AACxC;AAGO,IAAM,kBAAkB,CAAC,EAAE,QAAQ,MAAM,MAAoB;AAClE,SAAO,SAAS,aACd,QACA,OACY;AACZ,UAAM,4BAA4B,oBAAI,IAAwB;AAC9D,UAAM,4BAA4B,oBAAI,IAAwB;AAE9D,UAAM,yBAAyB,MAAM;AACnC,gCAA0B,QAAQ,CAAC,UAAU,MAAM,CAAC;AACpD,gCAA0B,MAAM;AAChC,aAAO,IAAI,SAAS,OAAO,OAAO,sBAAsB;AAAA,IAC1D;AAEA,UAAM,yBAAyB,CAAC,QAAgB;AAC9C,aAAO,IAAI,SAAS,OAAO,sBAAsB;AACjD,YAAM,QAAQ,0BAA0B,IAAI,GAAG;AAC/C,UAAI,OAAO;AACT,cAAM;AACN,kCAA0B,OAAO,GAAG;AAAA,MACtC;AAAA,IACF;AAEA,UAAM,iBAAiB,CAAC,WAAiC;AACvD,UAAI,WAAW,QAAW;AACxB,cAAM,OAAc,iBAAS,OAAO,KAAK;AACzC,aAAK,QAAQ,CAAC,QAAQ;AA5C9B;AA6CU,gBAAM,QAAQ,OAAO,GAAG;AACxB,iBAAO;AAAA,YACL,SAAS,OAAO;AAAA,YAChB,YAAU,WAAM,WAAN,mBAAc,WAAU,MAAM;AAAA,YACjC,iBAAS,OAAO,KAAK;AAAA,UAC9B;AAAA,QACF,CAAC;AAED,cAAM,+BAA+B;AAAA,UACnC;AAAA,UACA,CAAC,UAAU;AACT,kBAAM,QAAe;AAAA,cACnB;AAAA,cACA,CAAC,EAAE,SAAS,MAAM;AA1DhC;AA2DgB,uBAAO;AAAA,kBACL,SAAS,OAAO;AAAA,kBAChB,YAAU,WAAM,WAAN,mBAAc,WAAU,MAAM;AAAA,kBACxC;AAAA,gBACF;AAAA,cACF;AAAA,cACA;AAAA,YACF;AACA,sCAA0B,IAAI,MAAM,KAAK,KAAK;AAAA,UAChD;AAAA,QACF;AACA,kCAA0B,IAAI,OAAO,KAAK,4BAA4B;AAEtE,eAAO,GAAG,SAAS,OAAO,OAAO,sBAAsB;AAAA,MACzD,OAAO;AACL,cAAM,QAAQ,OAAO,MAAM;AAC3B,eAAO,KAAK,SAAS,MAAM,OAAc,iBAAS,OAAO,KAAK,CAAC;AAC/D,cAAM,cAAqB;AAAA,UACzB;AAAA,UACA,CAAC,EAAE,SAAS,MAAM;AAChB,mBAAO,KAAK,SAAS,MAAM,OAAO,QAAQ;AAAA,UAC5C;AAAA,UACA;AAAA,QACF;AACA,kCAA0B,IAAI,MAAM,KAAK,WAAW;AACpD,eAAO,GAAG,SAAS,MAAM,OAAO,MAAM;AACpC,iCAAuB,MAAM,GAAG;AAAA,QAClC,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO,GAAG,OAAO,OAAO,OAAO,cAAc;AAE7C,WAAO,MAAM;AACX,aAAO,IAAI,OAAO,OAAO,OAAO,cAAc;AAC9C,gCAA0B,QAAQ,CAAC,UAAU,MAAM,CAAC;AACpD,gCAA0B,QAAQ,CAAC,UAAU,MAAM,CAAC;AACpD,gCAA0B,MAAM;AAChC,gCAA0B,MAAM;AAAA,IAClC;AAAA,EACF;AACF;;;ACpGA,YAAYC,aAAY;AAMjB,IAAM,wBAAwB,CAAC,EAAE,QAAQ,MAAM,MAAoB;AACxE,SAAO,SAAS,mBACd,IACY;AACZ,UAAM,yBAAyB,CAC7B,WACU,uBAAkB,IAAI,KAAK,EAAE,GAAG,OAAO,MAAM;AAEzD,WAAO,GAAG,MAAM,GAAG,OAAO,sBAAsB;AAEhD,WAAO,MAAM,OAAO,IAAI,MAAM,GAAG,OAAO,sBAAsB;AAAA,EAChE;AACF;","names":["AtomIO","AtomIO"]}
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "atom.io-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
@@ -1,3 +1,5 @@
1
+ import { capitalize } from "~/packages/anvl/src/string/capitalize"
2
+
1
3
  import {
2
4
  IMPLICIT,
3
5
  closeOperation,
@@ -14,21 +16,25 @@ import type { Store } from "./internal/store"
14
16
  export * from "./atom"
15
17
  export * from "./logger"
16
18
  export * from "./selector"
19
+ export * from "./silo"
17
20
  export * from "./subscribe"
18
21
  export * from "./timeline"
19
22
  export * from "./transaction"
20
23
  export { __INTERNAL__ }
24
+ export type { Store } from "./internal/store"
21
25
  export type { Serializable } from "~/packages/anvl/src/json"
22
26
 
23
27
  export type AtomToken<_> = {
24
28
  key: string
25
29
  type: `atom`
26
30
  family?: FamilyMetadata
31
+ __brand?: _
27
32
  }
28
33
  export type SelectorToken<_> = {
29
34
  key: string
30
35
  type: `selector`
31
36
  family?: FamilyMetadata
37
+ __brand?: _
32
38
  }
33
39
  export type StateToken<T> = AtomToken<T> | SelectorToken<T>
34
40
 
@@ -36,6 +42,7 @@ export type ReadonlySelectorToken<_> = {
36
42
  key: string
37
43
  type: `readonly_selector`
38
44
  family?: FamilyMetadata
45
+ __brand?: _
39
46
  }
40
47
 
41
48
  export type FamilyMetadata = {
@@ -46,6 +53,7 @@ export type FamilyMetadata = {
46
53
  export type TransactionToken<_> = {
47
54
  key: string
48
55
  type: `transaction`
56
+ __brand?: _
49
57
  }
50
58
 
51
59
  export const getState = <T>(
@@ -53,6 +61,13 @@ export const getState = <T>(
53
61
  store: Store = IMPLICIT.STORE
54
62
  ): T => {
55
63
  const state = withdraw<T>(token, store)
64
+ if (state === null) {
65
+ throw new Error(
66
+ `${capitalize(token.type)} "${token.key}" not found in store "${
67
+ store.config.name
68
+ }".`
69
+ )
70
+ }
56
71
  return getState__INTERNAL(state, store)
57
72
  }
58
73
 
@@ -70,6 +85,13 @@ export const setState = <T, New extends T>(
70
85
  return
71
86
  }
72
87
  const state = withdraw(token, store)
88
+ if (state === null) {
89
+ throw new Error(
90
+ `${capitalize(token.type)} "${token.key}" not found in store "${
91
+ store.config.name
92
+ }".`
93
+ )
94
+ }
73
95
  setState__INTERNAL(state, value, store)
74
96
  closeOperation(store)
75
97
  }
@@ -51,5 +51,5 @@ export function atom__INTERNAL<T>(
51
51
  })
52
52
  )
53
53
  store.subject.atomCreation.next(token)
54
- return token
54
+ return token as AtomToken<T>
55
55
  }
@@ -36,7 +36,7 @@ export function atomFamily__INTERNAL<T, K extends Serializable>(
36
36
  const family: FamilyMetadata = { key: options.key, subKey }
37
37
  const fullKey = `${options.key}(${subKey})`
38
38
  const existing = withdraw({ key: fullKey, type: `atom` }, store)
39
- const token = existing
39
+ const token: AtomToken<any> = existing
40
40
  ? deposit(existing)
41
41
  : atom__INTERNAL<T>(
42
42
  {
@@ -62,7 +62,7 @@ export function atomFamily__INTERNAL<T, K extends Serializable>(
62
62
  }
63
63
 
64
64
  export function readonlySelectorFamily__INTERNAL<T, K extends Serializable>(
65
- options: SelectorFamilyOptions<T, K>,
65
+ options: ReadonlySelectorFamilyOptions<T, K>,
66
66
  store?: Store
67
67
  ): ReadonlySelectorFamily<T, K> {
68
68
  const core = target(store)
@@ -108,7 +108,7 @@ export function selectorFamily__INTERNAL<T, K extends Serializable>(
108
108
  const isReadonly = !(`set` in options)
109
109
 
110
110
  if (isReadonly) {
111
- return readonlySelectorFamily__INTERNAL(options as any, store)
111
+ return readonlySelectorFamily__INTERNAL(options, store)
112
112
  }
113
113
  const core = target(store)
114
114
  const subject = new Rx.Subject<SelectorToken<T>>()
@@ -1,5 +1,7 @@
1
1
  import HAMT from "hamt_plus"
2
2
 
3
+ import type { ƒn } from "~/packages/anvl/src/function"
4
+
3
5
  import type { Atom, ReadonlySelector, Selector, Store } from "."
4
6
  import { target, isValueCached, readCachedValue, IMPLICIT } from "."
5
7
  import type {
@@ -9,7 +11,6 @@ import type {
9
11
  StateToken,
10
12
  Transaction,
11
13
  TransactionToken,
12
- ƒn,
13
14
  } from ".."
14
15
 
15
16
  export const computeSelectorState = <T>(
@@ -26,27 +27,30 @@ export function lookup(
26
27
  : HAMT.has(key, core.selectors)
27
28
  ? `selector`
28
29
  : `readonly_selector`
29
- return { key, type }
30
+ return { key, type } as any
30
31
  }
31
32
 
32
- export function withdraw<T>(token: AtomToken<T>, store: Store): Atom<T>
33
- export function withdraw<T>(token: SelectorToken<T>, store: Store): Selector<T>
33
+ export function withdraw<T>(token: AtomToken<T>, store: Store): Atom<T> | null
34
+ export function withdraw<T>(
35
+ token: SelectorToken<T>,
36
+ store: Store
37
+ ): Selector<T> | null
34
38
  export function withdraw<T>(
35
39
  token: StateToken<T>,
36
40
  store: Store
37
- ): Atom<T> | Selector<T>
41
+ ): Atom<T> | Selector<T> | null
38
42
  export function withdraw<T>(
39
43
  token: ReadonlySelectorToken<T>,
40
44
  store: Store
41
- ): ReadonlySelector<T>
45
+ ): ReadonlySelector<T> | null
42
46
  export function withdraw<T>(
43
47
  token: TransactionToken<T>,
44
48
  store: Store
45
- ): Transaction<T extends ƒn ? T : never>
49
+ ): Transaction<T extends ƒn ? T : never> | null
46
50
  export function withdraw<T>(
47
51
  token: ReadonlySelectorToken<T> | StateToken<T>,
48
52
  store: Store
49
- ): Atom<T> | ReadonlySelector<T> | Selector<T>
53
+ ): Atom<T> | ReadonlySelector<T> | Selector<T> | null
50
54
  export function withdraw<T>(
51
55
  token: ReadonlySelectorToken<T> | StateToken<T> | TransactionToken<T>,
52
56
  store: Store
@@ -54,13 +58,15 @@ export function withdraw<T>(
54
58
  | Atom<T>
55
59
  | ReadonlySelector<T>
56
60
  | Selector<T>
57
- | Transaction<T extends ƒn ? T : never> {
61
+ | Transaction<T extends ƒn ? T : never>
62
+ | null {
58
63
  const core = target(store)
59
64
  return (
60
65
  HAMT.get(token.key, core.atoms) ??
61
66
  HAMT.get(token.key, core.selectors) ??
62
67
  HAMT.get(token.key, core.readonlySelectors) ??
63
- HAMT.get(token.key, core.transactions)
68
+ HAMT.get(token.key, core.transactions) ??
69
+ null
64
70
  )
65
71
  }
66
72
 
@@ -80,12 +86,16 @@ export function deposit<T>(
80
86
  | ReadonlySelector<T>
81
87
  | Selector<T>
82
88
  | Transaction<T extends ƒn ? T : never>
83
- ): ReadonlySelectorToken<T> | StateToken<T> | TransactionToken<T> {
89
+ ):
90
+ | AtomToken<T>
91
+ | ReadonlySelectorToken<T>
92
+ | SelectorToken<T>
93
+ | TransactionToken<T> {
84
94
  return {
85
95
  key: state.key,
86
96
  type: state.type,
87
97
  ...(`family` in state && { family: state.family }),
88
- }
98
+ } as any
89
99
  }
90
100
 
91
101
  export const getState__INTERNAL = <T>(
@@ -135,6 +135,11 @@ export const registerSelector = (
135
135
  .some(({ source }) => source === dependency.key)
136
136
 
137
137
  const dependencyState = withdraw(dependency, store)
138
+ if (dependencyState === null) {
139
+ throw new Error(
140
+ `State "${dependency.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`
141
+ )
142
+ }
138
143
  const dependencyValue = getState__INTERNAL(dependencyState, store)
139
144
 
140
145
  if (alreadyRegistered) {
@@ -160,6 +165,11 @@ export const registerSelector = (
160
165
  },
161
166
  set: (stateToken, newValue) => {
162
167
  const state = withdraw(stateToken, store)
168
+ if (state === null) {
169
+ throw new Error(
170
+ `State "${stateToken.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`
171
+ )
172
+ }
163
173
  setState__INTERNAL(state, newValue, store)
164
174
  },
165
175
  })
@@ -61,7 +61,7 @@ export const setAtomState = <T>(
61
61
  const newValue = become(next)(oldValue)
62
62
  store.config.logger?.info(`<< setting atom "${atom.key}" to`, newValue)
63
63
  cacheValue(atom.key, newValue, store)
64
- if (isAtomDefault(atom.key)) {
64
+ if (isAtomDefault(atom.key, store)) {
65
65
  markAtomAsNotDefault(atom.key, store)
66
66
  }
67
67
  markDone(atom.key, store)
@@ -2,6 +2,7 @@ import type { Hamt } from "hamt_plus"
2
2
  import HAMT from "hamt_plus"
3
3
  import * as Rx from "rxjs"
4
4
 
5
+ import type { ƒn } from "~/packages/anvl/src/function"
5
6
  import { doNothing } from "~/packages/anvl/src/function"
6
7
  import { Join } from "~/packages/anvl/src/join"
7
8
 
@@ -22,7 +23,6 @@ import type {
22
23
  TimelineToken,
23
24
  Transaction,
24
25
  TransactionToken,
25
- ƒn,
26
26
  } from ".."
27
27
 
28
28
  export type StoreCore = Pick<