atom.io 0.6.8 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/README.md +21 -2
  2. package/dist/index.d.mts +42 -461
  3. package/dist/index.d.ts +42 -461
  4. package/dist/index.js +128 -1792
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +75 -1742
  7. package/dist/index.mjs.map +1 -1
  8. package/internal/dist/index.d.mts +342 -0
  9. package/internal/dist/index.d.ts +342 -0
  10. package/internal/dist/index.js +1873 -0
  11. package/internal/dist/index.js.map +1 -0
  12. package/internal/dist/index.mjs +1798 -0
  13. package/internal/dist/index.mjs.map +1 -0
  14. package/internal/package.json +15 -0
  15. package/internal/src/atom/create-atom.ts +75 -0
  16. package/internal/src/atom/delete-atom.ts +10 -0
  17. package/internal/src/atom/index.ts +3 -0
  18. package/{src/internal → internal/src/atom}/is-default.ts +4 -2
  19. package/internal/src/caching.ts +21 -0
  20. package/internal/src/families/create-atom-family.ts +59 -0
  21. package/internal/src/families/create-readonly-selector-family.ts +45 -0
  22. package/internal/src/families/create-selector-family.ts +67 -0
  23. package/internal/src/families/index.ts +3 -0
  24. package/internal/src/get-state-internal.ts +23 -0
  25. package/internal/src/index.ts +13 -0
  26. package/internal/src/mutable/create-mutable-atom-family.ts +25 -0
  27. package/internal/src/mutable/create-mutable-atom.ts +49 -0
  28. package/internal/src/mutable/get-json-token.ts +22 -0
  29. package/internal/src/mutable/get-update-token.ts +20 -0
  30. package/internal/src/mutable/index.ts +17 -0
  31. package/internal/src/mutable/is-atom-token-mutable.ts +7 -0
  32. package/internal/src/mutable/tracker-family.ts +61 -0
  33. package/internal/src/mutable/tracker.ts +164 -0
  34. package/internal/src/mutable/transceiver.ts +110 -0
  35. package/internal/src/operation.ts +68 -0
  36. package/{src/internal → internal/src}/selector/create-read-write-selector.ts +10 -13
  37. package/{src/internal → internal/src}/selector/create-readonly-selector.ts +9 -8
  38. package/internal/src/selector/create-selector.ts +65 -0
  39. package/{src/internal → internal/src}/selector/index.ts +1 -0
  40. package/internal/src/selector/lookup-selector-sources.ts +20 -0
  41. package/{src/internal → internal/src}/selector/register-selector.ts +13 -9
  42. package/{src/internal → internal/src}/selector/trace-selector-atoms.ts +4 -2
  43. package/{src/internal → internal/src}/selector/update-selector-atoms.ts +4 -3
  44. package/internal/src/set-state/become.ts +10 -0
  45. package/internal/src/set-state/copy-mutable-if-needed.ts +23 -0
  46. package/internal/src/set-state/copy-mutable-in-transaction.ts +59 -0
  47. package/internal/src/set-state/copy-mutable-into-new-store.ts +34 -0
  48. package/internal/src/set-state/emit-update.ts +23 -0
  49. package/internal/src/set-state/evict-downstream.ts +39 -0
  50. package/internal/src/set-state/index.ts +2 -0
  51. package/internal/src/set-state/set-atom-state.ts +38 -0
  52. package/internal/src/set-state/set-selector-state.ts +19 -0
  53. package/internal/src/set-state/set-state-internal.ts +18 -0
  54. package/internal/src/set-state/stow-update.ts +42 -0
  55. package/internal/src/store/deposit.ts +43 -0
  56. package/internal/src/store/index.ts +5 -0
  57. package/internal/src/store/lookup.ts +26 -0
  58. package/internal/src/store/store.ts +154 -0
  59. package/internal/src/store/withdraw-new-family-member.ts +53 -0
  60. package/internal/src/store/withdraw.ts +113 -0
  61. package/internal/src/subject.ts +21 -0
  62. package/internal/src/subscribe/index.ts +1 -0
  63. package/internal/src/subscribe/recall-state.ts +19 -0
  64. package/internal/src/subscribe/subscribe-to-root-atoms.ts +47 -0
  65. package/{src/internal → internal/src}/timeline/add-atom-to-timeline.ts +50 -29
  66. package/internal/src/timeline/index.ts +3 -0
  67. package/{src/internal → internal/src/timeline}/time-travel-internal.ts +6 -6
  68. package/{src/internal → internal/src/timeline}/timeline-internal.ts +20 -12
  69. package/{src/internal → internal/src}/transaction/abort-transaction.ts +1 -1
  70. package/{src/internal → internal/src}/transaction/apply-transaction.ts +25 -18
  71. package/{src/internal → internal/src}/transaction/build-transaction.ts +12 -6
  72. package/{src/internal → internal/src}/transaction/index.ts +3 -2
  73. package/{src/internal → internal/src}/transaction/redo-transaction.ts +4 -5
  74. package/{src/internal → internal/src/transaction}/transaction-internal.ts +16 -13
  75. package/{src/internal → internal/src}/transaction/undo-transaction.ts +4 -5
  76. package/introspection/dist/index.d.mts +12 -260
  77. package/introspection/dist/index.d.ts +12 -260
  78. package/introspection/dist/index.js +125 -140
  79. package/introspection/dist/index.js.map +1 -1
  80. package/introspection/dist/index.mjs +103 -116
  81. package/introspection/dist/index.mjs.map +1 -1
  82. package/{src/introspection → introspection/src}/attach-atom-index.ts +41 -30
  83. package/{src/introspection → introspection/src}/attach-introspection-states.ts +6 -10
  84. package/introspection/src/attach-selector-index.ts +90 -0
  85. package/{src/introspection → introspection/src}/attach-timeline-family.ts +16 -16
  86. package/introspection/src/attach-timeline-index.ts +38 -0
  87. package/introspection/src/attach-transaction-index.ts +40 -0
  88. package/{src/introspection → introspection/src}/attach-transaction-logs.ts +11 -8
  89. package/json/dist/index.d.mts +41 -2
  90. package/json/dist/index.d.ts +41 -2
  91. package/json/dist/index.js +88 -48
  92. package/json/dist/index.js.map +1 -1
  93. package/json/dist/index.mjs +76 -13
  94. package/json/dist/index.mjs.map +1 -1
  95. package/json/src/index.ts +5 -0
  96. package/json/src/select-json-family.ts +35 -0
  97. package/json/src/select-json.ts +22 -0
  98. package/package.json +105 -57
  99. package/react/dist/index.d.mts +9 -17
  100. package/react/dist/index.d.ts +9 -17
  101. package/react/dist/index.js +45 -77
  102. package/react/dist/index.js.map +1 -1
  103. package/react/dist/index.mjs +18 -34
  104. package/react/dist/index.mjs.map +1 -1
  105. package/react/src/store-context.tsx +12 -0
  106. package/react/src/store-hooks.ts +36 -0
  107. package/react-devtools/dist/index.css +1 -1
  108. package/react-devtools/dist/index.css.map +1 -1
  109. package/react-devtools/dist/index.d.mts +199 -230
  110. package/react-devtools/dist/index.d.ts +199 -230
  111. package/react-devtools/dist/index.js +610 -2466
  112. package/react-devtools/dist/index.js.map +1 -1
  113. package/react-devtools/dist/index.mjs +543 -2401
  114. package/react-devtools/dist/index.mjs.map +1 -1
  115. package/{src/react-devtools → react-devtools/src}/AtomIODevtools.tsx +5 -3
  116. package/{src/react-devtools → react-devtools/src}/Button.tsx +2 -3
  117. package/{src/react-devtools → react-devtools/src}/StateEditor.tsx +3 -2
  118. package/{src/react-devtools → react-devtools/src}/StateIndex.tsx +7 -4
  119. package/{src/react-devtools → react-devtools/src}/TimelineIndex.tsx +7 -11
  120. package/{src/react-devtools → react-devtools/src}/TransactionIndex.tsx +4 -4
  121. package/{src/react-devtools → react-devtools/src}/Updates.tsx +9 -4
  122. package/{src/react-devtools → react-devtools/src}/index.ts +5 -5
  123. package/realtime-react/dist/index.d.mts +9 -25
  124. package/realtime-react/dist/index.d.ts +9 -25
  125. package/realtime-react/dist/index.js +75 -193
  126. package/realtime-react/dist/index.js.map +1 -1
  127. package/realtime-react/dist/index.mjs +44 -148
  128. package/realtime-react/dist/index.mjs.map +1 -1
  129. package/realtime-react/src/index.ts +7 -0
  130. package/{src/realtime-react → realtime-react/src}/realtime-context.tsx +3 -4
  131. package/realtime-react/src/use-pull-family-member.ts +15 -0
  132. package/realtime-react/src/use-pull-mutable-family-member.ts +20 -0
  133. package/realtime-react/src/use-pull-mutable.ts +17 -0
  134. package/realtime-react/src/use-pull.ts +15 -0
  135. package/realtime-react/src/use-push.ts +19 -0
  136. package/realtime-react/src/use-server-action.ts +18 -0
  137. package/realtime-testing/dist/index.d.mts +49 -0
  138. package/realtime-testing/dist/index.d.ts +49 -0
  139. package/realtime-testing/dist/index.js +147 -0
  140. package/realtime-testing/dist/index.js.map +1 -0
  141. package/realtime-testing/dist/index.mjs +116 -0
  142. package/realtime-testing/dist/index.mjs.map +1 -0
  143. package/{src/realtime-testing → realtime-testing/src}/setup-realtime-test.tsx +10 -8
  144. package/src/atom.ts +64 -8
  145. package/src/index.ts +36 -29
  146. package/src/logger.ts +7 -7
  147. package/src/selector.ts +5 -5
  148. package/src/silo.ts +49 -43
  149. package/src/subscribe.ts +27 -22
  150. package/src/timeline.ts +9 -4
  151. package/src/transaction.ts +3 -4
  152. package/transceivers/set-rtx/dist/index.d.mts +39 -0
  153. package/transceivers/set-rtx/dist/index.d.ts +39 -0
  154. package/transceivers/set-rtx/dist/index.js +213 -0
  155. package/transceivers/set-rtx/dist/index.js.map +1 -0
  156. package/transceivers/set-rtx/dist/index.mjs +211 -0
  157. package/transceivers/set-rtx/dist/index.mjs.map +1 -0
  158. package/{realtime → transceivers/set-rtx}/package.json +1 -1
  159. package/transceivers/set-rtx/src/index.ts +1 -0
  160. package/transceivers/set-rtx/src/set-rtx.ts +242 -0
  161. package/realtime/dist/index.d.mts +0 -25
  162. package/realtime/dist/index.d.ts +0 -25
  163. package/realtime/dist/index.js +0 -190
  164. package/realtime/dist/index.js.map +0 -1
  165. package/realtime/dist/index.mjs +0 -151
  166. package/realtime/dist/index.mjs.map +0 -1
  167. package/src/internal/atom-internal.ts +0 -54
  168. package/src/internal/families-internal.ts +0 -144
  169. package/src/internal/get.ts +0 -129
  170. package/src/internal/index.ts +0 -15
  171. package/src/internal/operation.ts +0 -139
  172. package/src/internal/selector/lookup-selector-sources.ts +0 -16
  173. package/src/internal/selector-internal.ts +0 -58
  174. package/src/internal/set.ts +0 -99
  175. package/src/internal/store.ts +0 -151
  176. package/src/internal/subscribe-internal.ts +0 -88
  177. package/src/internal/timeline/index.ts +0 -1
  178. package/src/introspection/attach-selector-index.ts +0 -77
  179. package/src/introspection/attach-timeline-index.ts +0 -36
  180. package/src/introspection/attach-transaction-index.ts +0 -38
  181. package/src/json/index.ts +0 -1
  182. package/src/json/select-json.ts +0 -18
  183. package/src/react/store-context.tsx +0 -13
  184. package/src/react/store-hooks.ts +0 -47
  185. package/src/react-explorer/AtomIOExplorer.tsx +0 -218
  186. package/src/react-explorer/explorer-effects.ts +0 -20
  187. package/src/react-explorer/explorer-states.ts +0 -217
  188. package/src/react-explorer/index.ts +0 -23
  189. package/src/react-explorer/space-states.ts +0 -72
  190. package/src/react-explorer/view-states.ts +0 -41
  191. package/src/realtime/README.md +0 -33
  192. package/src/realtime/hook-composition/expose-family.ts +0 -101
  193. package/src/realtime/hook-composition/expose-single.ts +0 -38
  194. package/src/realtime/hook-composition/expose-timeline.ts +0 -60
  195. package/src/realtime/hook-composition/index.ts +0 -12
  196. package/src/realtime/hook-composition/receive-state.ts +0 -29
  197. package/src/realtime/hook-composition/receive-transaction.ts +0 -18
  198. package/src/realtime/index.ts +0 -1
  199. package/src/realtime-react/index.ts +0 -3
  200. package/src/realtime-react/realtime-hooks.ts +0 -39
  201. package/src/realtime-react/realtime-state.ts +0 -10
  202. package/src/realtime-react/use-pull-family-member.ts +0 -26
  203. package/src/realtime-react/use-pull-family.ts +0 -24
  204. package/src/realtime-react/use-pull.ts +0 -24
  205. package/src/realtime-react/use-push.ts +0 -27
  206. package/src/realtime-react/use-server-action.ts +0 -33
  207. package/src/tracker/index.ts +0 -3
  208. package/src/tracker/tracker.ts +0 -61
  209. package/src/web-effects/index.ts +0 -1
  210. package/src/web-effects/storage.ts +0 -30
  211. /package/{src/introspection → introspection/src}/index.ts +0 -0
  212. /package/{src/react → react/src}/index.ts +0 -0
  213. /package/{src/react-devtools → react-devtools/src}/devtools.scss +0 -0
  214. /package/{src/realtime-testing → realtime-testing/src}/index.ts +0 -0
@@ -0,0 +1,1798 @@
1
+ import * as AtomIO from 'atom.io';
2
+ import { setState, getState, subscribe } from 'atom.io';
3
+ import { selectJson, stringifyJson, parseJson, selectJsonFamily } from 'atom.io/json';
4
+
5
+ var __defProp = Object.defineProperty;
6
+ var __defProps = Object.defineProperties;
7
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
8
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
9
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
11
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12
+ var __spreadValues = (a, b) => {
13
+ for (var prop in b || (b = {}))
14
+ if (__hasOwnProp.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ if (__getOwnPropSymbols)
17
+ for (var prop of __getOwnPropSymbols(b)) {
18
+ if (__propIsEnum.call(b, prop))
19
+ __defNormalProp(a, prop, b[prop]);
20
+ }
21
+ return a;
22
+ };
23
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
24
+
25
+ // src/store/deposit.ts
26
+ function deposit(state) {
27
+ const token = {
28
+ key: state.key,
29
+ type: state.type
30
+ };
31
+ if (`family` in state) {
32
+ token.family = state.family;
33
+ }
34
+ return token;
35
+ }
36
+
37
+ // src/subject.ts
38
+ var Subject = class {
39
+ constructor() {
40
+ this.subscribers = /* @__PURE__ */ new Map();
41
+ }
42
+ subscribe(key, subscriber) {
43
+ this.subscribers.set(key, subscriber);
44
+ const unsubscribe = () => this.unsubscribe(key);
45
+ return unsubscribe;
46
+ }
47
+ unsubscribe(key) {
48
+ this.subscribers.delete(key);
49
+ }
50
+ next(value) {
51
+ for (const subscriber of this.subscribers.values()) {
52
+ subscriber(value);
53
+ }
54
+ }
55
+ };
56
+
57
+ // src/transaction/abort-transaction.ts
58
+ var abortTransaction = (store) => {
59
+ var _a, _b;
60
+ if (store.transactionStatus.phase === `idle`) {
61
+ (_a = store.config.logger) == null ? void 0 : _a.warn(
62
+ `abortTransaction called outside of a transaction. This is probably a bug.`
63
+ );
64
+ return;
65
+ }
66
+ store.transactionStatus = { phase: `idle` };
67
+ (_b = store.config.logger) == null ? void 0 : _b.info(`\u{1FA82}`, `transaction fail`);
68
+ };
69
+ var applyTransaction = (output, store) => {
70
+ var _a, _b, _c, _d, _e;
71
+ if (store.transactionStatus.phase !== `building`) {
72
+ (_a = store.config.logger) == null ? void 0 : _a.warn(
73
+ `abortTransaction called outside of a transaction. This is probably a bug.`
74
+ );
75
+ return;
76
+ }
77
+ store.transactionStatus.phase = `applying`;
78
+ store.transactionStatus.output = output;
79
+ const { atomUpdates } = store.transactionStatus;
80
+ (_b = store.config.logger) == null ? void 0 : _b.info(
81
+ `\u{1F6C3} applying transaction "${store.transactionStatus.key}" with ${atomUpdates.length} updates.`
82
+ );
83
+ (_c = store.config.logger) == null ? void 0 : _c.info(`\u{1F6C3} the updates are:`, atomUpdates);
84
+ for (const { key, newValue } of atomUpdates) {
85
+ const token = { key, type: `atom` };
86
+ if (!store.valueMap.has(token.key)) {
87
+ if (token.family) {
88
+ const family = store.families.get(token.family.key);
89
+ if (family) {
90
+ family(token.family.subKey);
91
+ }
92
+ } else {
93
+ const newAtom = store.transactionStatus.core.atoms.get(token.key);
94
+ if (!newAtom) {
95
+ throw new Error(
96
+ `Absurd Error: Atom "${token.key}" not found while copying updates from transaction "${store.transactionStatus.key}" to store "${store.config.name}"`
97
+ );
98
+ }
99
+ store.atoms.set(newAtom.key, newAtom);
100
+ store.valueMap.set(newAtom.key, newAtom.default);
101
+ (_d = store.config.logger) == null ? void 0 : _d.info(`\u{1F527}`, `add atom "${newAtom.key}"`);
102
+ }
103
+ }
104
+ setState(token, newValue, store);
105
+ }
106
+ const myTransaction = withdraw(
107
+ { key: store.transactionStatus.key, type: `transaction` },
108
+ store
109
+ );
110
+ if (myTransaction === null) {
111
+ throw new Error(
112
+ `Transaction "${store.transactionStatus.key}" not found. Absurd. How is this running?`
113
+ );
114
+ }
115
+ myTransaction.subject.next({
116
+ key: store.transactionStatus.key,
117
+ atomUpdates,
118
+ output,
119
+ params: store.transactionStatus.params
120
+ });
121
+ store.transactionStatus = { phase: `idle` };
122
+ (_e = store.config.logger) == null ? void 0 : _e.info(`\u{1F6EC}`, `transaction "${myTransaction.key}" applied`);
123
+ };
124
+
125
+ // ../../rel8/junction/src/junction.ts
126
+ var Junction = class {
127
+ constructor(data, config) {
128
+ this.relations = /* @__PURE__ */ new Map();
129
+ this.contents = /* @__PURE__ */ new Map();
130
+ this.makeContentKey = (a, b) => `${a}:${b}`;
131
+ var _a, _b;
132
+ this.a = data.between[0];
133
+ this.b = data.between[1];
134
+ this.cardinality = data.cardinality;
135
+ this.relations = new Map((_a = data.relations) == null ? void 0 : _a.map(([a, b]) => [a, new Set(b)]));
136
+ this.contents = new Map(data.contents);
137
+ this.isContent = (_b = config == null ? void 0 : config.isContent) != null ? _b : null;
138
+ if (config == null ? void 0 : config.makeContentKey) {
139
+ this.makeContentKey = config.makeContentKey;
140
+ }
141
+ if (config == null ? void 0 : config.externalStore) {
142
+ const externalStore = config.externalStore;
143
+ this.has = (a, b) => externalStore.has(a, b);
144
+ this.addRelation = (a, b) => {
145
+ externalStore.addRelation(a, b);
146
+ return this;
147
+ };
148
+ this.deleteRelation = (a, b) => {
149
+ externalStore.deleteRelation(a, b);
150
+ return this;
151
+ };
152
+ this.getRelatedKeys = (key) => externalStore.getRelatedKeys(key);
153
+ if (externalStore.getContent) {
154
+ this.getContentInternal = (contentKey) => {
155
+ return externalStore.getContent(contentKey);
156
+ };
157
+ this.setContent = (contentKey, content) => {
158
+ externalStore.setContent(contentKey, content);
159
+ return this;
160
+ };
161
+ this.deleteContent = (contentKey) => {
162
+ externalStore.deleteContent(contentKey);
163
+ return this;
164
+ };
165
+ }
166
+ }
167
+ }
168
+ getRelatedKeys(key) {
169
+ return this.relations.get(key);
170
+ }
171
+ addRelation(a, b) {
172
+ const aRelations = this.relations.get(a);
173
+ const bRelations = this.relations.get(b);
174
+ if (aRelations) {
175
+ aRelations.add(b);
176
+ } else {
177
+ this.relations.set(a, /* @__PURE__ */ new Set([b]));
178
+ }
179
+ if (bRelations) {
180
+ bRelations.add(a);
181
+ } else {
182
+ this.relations.set(b, /* @__PURE__ */ new Set([a]));
183
+ }
184
+ }
185
+ deleteRelation(a, b) {
186
+ const aRelations = this.relations.get(a);
187
+ if (aRelations) {
188
+ aRelations.delete(b);
189
+ if (aRelations.size === 0) {
190
+ this.relations.delete(a);
191
+ }
192
+ const bRelations = this.relations.get(b);
193
+ if (bRelations) {
194
+ bRelations.delete(a);
195
+ if (bRelations.size === 0) {
196
+ this.relations.delete(b);
197
+ }
198
+ }
199
+ }
200
+ }
201
+ getContentInternal(contentKey) {
202
+ return this.contents.get(contentKey);
203
+ }
204
+ setContent(contentKey, content) {
205
+ this.contents.set(contentKey, content);
206
+ }
207
+ deleteContent(contentKey) {
208
+ this.contents.delete(contentKey);
209
+ }
210
+ toJSON() {
211
+ return {
212
+ between: [this.a, this.b],
213
+ cardinality: this.cardinality,
214
+ relations: [...this.relations.entries()].map(([a, b]) => [a, [...b]]),
215
+ contents: [...this.contents.entries()]
216
+ };
217
+ }
218
+ set(a, ...rest) {
219
+ var _a;
220
+ const b = (
221
+ // @ts-expect-error we deduce hereby that this.b may index a
222
+ typeof rest[0] === `string` ? rest[0] : a[this.b]
223
+ );
224
+ const content = ((_a = rest[1]) != null ? _a : typeof rest[0] === `string`) ? void 0 : rest[0];
225
+ a = typeof a === `string` ? a : a[this.a];
226
+ switch (this.cardinality) {
227
+ case `1:1`: {
228
+ const bPrev = this.getRelatedKey(a);
229
+ if (bPrev && bPrev !== b)
230
+ this.delete(bPrev, a);
231
+ }
232
+ case `1:n`: {
233
+ const aPrev = this.getRelatedKey(b);
234
+ if (aPrev && aPrev !== a)
235
+ this.delete(aPrev, b);
236
+ }
237
+ }
238
+ this.addRelation(a, b);
239
+ if (content) {
240
+ const contentKey = this.makeContentKey(a, b);
241
+ this.setContent(contentKey, content);
242
+ }
243
+ return this;
244
+ }
245
+ delete(x, b) {
246
+ b = typeof b === `string` ? b : x[this.b];
247
+ const a = typeof x === `string` ? x : x[this.a];
248
+ if (a === void 0 && typeof b === `string`) {
249
+ const bRelations = this.getRelatedKeys(b);
250
+ if (bRelations) {
251
+ bRelations.forEach((a2) => this.delete(a2, b));
252
+ }
253
+ }
254
+ if (typeof a === `string` && b === void 0) {
255
+ const aRelations = this.getRelatedKeys(a);
256
+ if (aRelations) {
257
+ aRelations.forEach((b2) => {
258
+ this.delete(a, b2);
259
+ });
260
+ }
261
+ }
262
+ if (typeof a === `string` && typeof b === `string`) {
263
+ this.deleteRelation(a, b);
264
+ const contentKey = this.makeContentKey(a, b);
265
+ this.deleteContent(contentKey);
266
+ }
267
+ return this;
268
+ }
269
+ getRelatedKey(key) {
270
+ const relations = this.getRelatedKeys(key);
271
+ if (relations) {
272
+ if (relations.size > 1) {
273
+ console.warn(
274
+ `${relations.size} related keys were found for key "${key}": (${[
275
+ ...relations
276
+ ].map((k) => `"${k}"`).join(`, `)}). Only one related key was expected.`
277
+ );
278
+ }
279
+ for (const relation of relations) {
280
+ return relation;
281
+ }
282
+ }
283
+ }
284
+ getContent(a, b) {
285
+ const contentKey = this.makeContentKey(a, b);
286
+ return this.getContentInternal(contentKey);
287
+ }
288
+ getRelationEntries(input) {
289
+ const a = input[this.a];
290
+ const b = input[this.b];
291
+ if (a !== void 0 && b === void 0) {
292
+ const aRelations = this.getRelatedKeys(a);
293
+ if (aRelations) {
294
+ return [...aRelations].map((b2) => {
295
+ var _a;
296
+ return [b2, (_a = this.getContent(a, b2)) != null ? _a : null];
297
+ });
298
+ }
299
+ }
300
+ if (a === void 0 && b !== void 0) {
301
+ const bRelations = this.getRelatedKeys(b);
302
+ if (bRelations) {
303
+ return [...bRelations].map((a2) => {
304
+ var _a;
305
+ return [a2, (_a = this.getContent(a2, b)) != null ? _a : null];
306
+ });
307
+ }
308
+ }
309
+ return [];
310
+ }
311
+ has(a, b) {
312
+ var _a;
313
+ if (b) {
314
+ const setA = this.getRelatedKeys(a);
315
+ return (_a = setA == null ? void 0 : setA.has(b)) != null ? _a : false;
316
+ }
317
+ return this.relations.has(a);
318
+ }
319
+ };
320
+
321
+ // src/transaction/build-transaction.ts
322
+ var buildTransaction = (key, params, store) => {
323
+ var _a;
324
+ store.transactionStatus = {
325
+ key,
326
+ phase: `building`,
327
+ time: Date.now(),
328
+ core: {
329
+ atoms: new Map(store.atoms),
330
+ atomsThatAreDefault: new Set(store.atomsThatAreDefault),
331
+ families: new Map(store.families),
332
+ operation: { open: false },
333
+ readonlySelectors: new Map(store.readonlySelectors),
334
+ timelines: new Map(store.timelines),
335
+ timelineAtoms: new Junction(store.timelineAtoms.toJSON()),
336
+ trackers: /* @__PURE__ */ new Map(),
337
+ transactions: new Map(store.transactions),
338
+ selectorAtoms: new Junction(store.selectorAtoms.toJSON()),
339
+ selectorGraph: new Junction(store.selectorGraph.toJSON(), {
340
+ makeContentKey: (...keys) => keys.sort().join(`:`)
341
+ }),
342
+ selectors: new Map(store.selectors),
343
+ valueMap: new Map(store.valueMap)
344
+ },
345
+ atomUpdates: [],
346
+ params,
347
+ output: void 0
348
+ };
349
+ (_a = store.config.logger) == null ? void 0 : _a.info(
350
+ `\u{1F6EB}`,
351
+ `transaction "${key}" building in store "${store.config.name}"`
352
+ );
353
+ };
354
+
355
+ // src/transaction/transaction-internal.ts
356
+ function transaction__INTERNAL(options, store = IMPLICIT.STORE) {
357
+ const newTransaction = {
358
+ key: options.key,
359
+ type: `transaction`,
360
+ run: (...params) => {
361
+ var _a;
362
+ buildTransaction(options.key, params, store);
363
+ try {
364
+ const output = options.do(
365
+ {
366
+ get: (token2) => getState(token2, store),
367
+ set: (token2, value) => setState(token2, value, store)
368
+ },
369
+ ...params
370
+ );
371
+ applyTransaction(output, store);
372
+ return output;
373
+ } catch (thrown) {
374
+ abortTransaction(store);
375
+ (_a = store.config.logger) == null ? void 0 : _a.error(
376
+ `Transaction "${options.key}" failed in store "${store.config.name}":`,
377
+ thrown
378
+ );
379
+ throw thrown;
380
+ }
381
+ },
382
+ install: (store2) => transaction__INTERNAL(options, store2),
383
+ subject: new Subject()
384
+ };
385
+ const core = target(store);
386
+ core.transactions.set(newTransaction.key, newTransaction);
387
+ const token = deposit(newTransaction);
388
+ store.subject.transactionCreation.next(token);
389
+ return token;
390
+ }
391
+ var target = (store = IMPLICIT.STORE) => store.transactionStatus.phase === `building` ? store.transactionStatus.core : store;
392
+ var redoTransactionUpdate = (update, store) => {
393
+ var _a;
394
+ (_a = store.config.logger) == null ? void 0 : _a.info(` \u23ED redo transaction "${update.key}" (redo)`);
395
+ for (const { key, newValue } of update.atomUpdates) {
396
+ const token = { key, type: `atom` };
397
+ const state = withdraw(token, store);
398
+ if (state === null) {
399
+ throw new Error(
400
+ `State "${token.key}" not found in this store. This is surprising, because we are navigating the history of the store.`
401
+ );
402
+ }
403
+ setState(state, newValue, store);
404
+ }
405
+ };
406
+ var undoTransactionUpdate = (update, store) => {
407
+ var _a;
408
+ (_a = store.config.logger) == null ? void 0 : _a.info(` \u23EE undo transaction "${update.key}" (undo)`);
409
+ for (const { key, oldValue } of update.atomUpdates) {
410
+ const token = { key, type: `atom` };
411
+ const state = withdraw(token, store);
412
+ if (state === null) {
413
+ throw new Error(
414
+ `State "${token.key}" not found in this store. This is surprising, because we are navigating the history of the store.`
415
+ );
416
+ }
417
+ setState(state, oldValue, store);
418
+ }
419
+ };
420
+
421
+ // src/transaction/index.ts
422
+ var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
423
+
424
+ // src/store/lookup.ts
425
+ function lookup(key, store) {
426
+ var _a;
427
+ const core = target(store);
428
+ let type = core.atoms.has(key) ? `atom` : core.selectors.has(key) ? `selector` : core.readonlySelectors.has(key) ? `readonly_selector` : ``;
429
+ if (!type) {
430
+ const errorId = Math.random().toString(36);
431
+ type = `\u{1F6A8} This state could not be found by lookup! Check the console for "${errorId}"`;
432
+ (_a = store.config.logger) == null ? void 0 : _a.error(
433
+ `${errorId}: Key "${key}" does not exist in the store.`
434
+ );
435
+ }
436
+ return { key, type };
437
+ }
438
+
439
+ // src/store/store.ts
440
+ var Store = class {
441
+ constructor(name, store = null) {
442
+ this.valueMap = /* @__PURE__ */ new Map();
443
+ this.atoms = /* @__PURE__ */ new Map();
444
+ this.selectors = /* @__PURE__ */ new Map();
445
+ this.readonlySelectors = /* @__PURE__ */ new Map();
446
+ this.trackers = /* @__PURE__ */ new Map();
447
+ this.families = /* @__PURE__ */ new Map();
448
+ this.timelines = /* @__PURE__ */ new Map();
449
+ this.transactions = /* @__PURE__ */ new Map();
450
+ this.atomsThatAreDefault = /* @__PURE__ */ new Set();
451
+ this.timelineAtoms = new Junction({
452
+ between: [`timelineKey`, `atomKey`],
453
+ cardinality: `1:n`
454
+ });
455
+ this.selectorAtoms = new Junction({
456
+ between: [`selectorKey`, `atomKey`],
457
+ cardinality: `n:n`
458
+ });
459
+ this.selectorGraph = new Junction(
460
+ {
461
+ between: [`upstreamSelectorKey`, `downstreamSelectorKey`],
462
+ cardinality: `n:n`
463
+ },
464
+ {
465
+ makeContentKey: (...keys) => keys.sort().join(`:`)
466
+ }
467
+ );
468
+ this.subject = {
469
+ atomCreation: new Subject(),
470
+ selectorCreation: new Subject(),
471
+ transactionCreation: new Subject(),
472
+ timelineCreation: new Subject(),
473
+ operationStatus: new Subject()
474
+ };
475
+ this.operation = { open: false };
476
+ this.transactionStatus = { phase: `idle` };
477
+ this.config = {
478
+ name: `IMPLICIT_STORE`,
479
+ logger: __spreadProps(__spreadValues({}, console), { info: () => void 0 }),
480
+ logger__INTERNAL: console
481
+ };
482
+ var _a;
483
+ if (store !== null) {
484
+ this.valueMap = new Map(store == null ? void 0 : store.valueMap);
485
+ this.operation = __spreadValues({}, store == null ? void 0 : store.operation);
486
+ this.transactionStatus = __spreadValues({}, store == null ? void 0 : store.transactionStatus);
487
+ this.config = __spreadProps(__spreadValues({}, store == null ? void 0 : store.config), {
488
+ logger__INTERNAL: console,
489
+ logger: __spreadValues(__spreadProps(__spreadValues({}, console), {
490
+ info: () => void 0
491
+ }), (_a = store == null ? void 0 : store.config) == null ? void 0 : _a.logger),
492
+ name
493
+ });
494
+ }
495
+ store == null ? void 0 : store.atoms.forEach((atom) => {
496
+ atom.install(this);
497
+ });
498
+ store == null ? void 0 : store.readonlySelectors.forEach((selector) => {
499
+ selector.install(this);
500
+ });
501
+ store == null ? void 0 : store.selectors.forEach((selector) => {
502
+ selector.install(this);
503
+ });
504
+ store == null ? void 0 : store.transactions.forEach((tx) => {
505
+ tx.install(this);
506
+ });
507
+ store == null ? void 0 : store.timelines.forEach((timeline) => {
508
+ timeline.install(this);
509
+ });
510
+ }
511
+ };
512
+ var IMPLICIT = {
513
+ STORE_INTERNAL: void 0,
514
+ get STORE() {
515
+ var _a;
516
+ return (_a = this.STORE_INTERNAL) != null ? _a : this.STORE_INTERNAL = new Store(`IMPLICIT_STORE`);
517
+ }
518
+ };
519
+ var clearStore = (store = IMPLICIT.STORE) => {
520
+ const { config } = store;
521
+ Object.assign(store, new Store(config.name));
522
+ store.config = config;
523
+ };
524
+
525
+ // src/timeline/add-atom-to-timeline.ts
526
+ var addAtomToTimeline = (atomToken, tl, store = IMPLICIT.STORE) => {
527
+ const atom = withdraw(atomToken, store);
528
+ if (atom === null) {
529
+ throw new Error(
530
+ `Cannot subscribe to atom "${atomToken.key}" because it has not been initialized in store "${store.config.name}"`
531
+ );
532
+ }
533
+ atom.subject.subscribe(`timeline`, (update) => {
534
+ var _a, _b, _c, _d, _e;
535
+ const currentSelectorKey = store.operation.open && store.operation.token.type === `selector` ? store.operation.token.key : null;
536
+ const currentSelectorTime = store.operation.open && store.operation.token.type === `selector` ? store.operation.time : null;
537
+ const currentTransactionKey = store.transactionStatus.phase === `applying` ? store.transactionStatus.key : null;
538
+ const currentTransactionTime = store.transactionStatus.phase === `applying` ? store.transactionStatus.time : null;
539
+ (_a = store.config.logger) == null ? void 0 : _a.info(
540
+ `\u23F3 timeline "${tl.key}" saw atom "${atomToken.key}" go (`,
541
+ update.oldValue,
542
+ `->`,
543
+ update.newValue,
544
+ currentTransactionKey ? `) in transaction "${currentTransactionKey}"` : currentSelectorKey ? `) in selector "${currentSelectorKey}"` : `)`
545
+ );
546
+ if (tl.timeTraveling === null) {
547
+ if (tl.selectorTime && tl.selectorTime !== currentSelectorTime) {
548
+ const mostRecentUpdate = tl.history.at(-1);
549
+ if (mostRecentUpdate === void 0) {
550
+ throw new Error(
551
+ `Timeline "${tl.key}" has a selectorTime, but no history. This is most likely a bug in AtomIO.`
552
+ );
553
+ }
554
+ }
555
+ if (currentTransactionKey && store.transactionStatus.phase === `applying`) {
556
+ const currentTransaction = withdraw(
557
+ { key: currentTransactionKey, type: `transaction` },
558
+ store
559
+ );
560
+ if (currentTransaction === null) {
561
+ throw new Error(
562
+ `Transaction "${currentTransactionKey}" not found in store "${store.config.name}". This is surprising, because we are in the application phase of "${currentTransactionKey}".`
563
+ );
564
+ }
565
+ if (tl.transactionKey !== currentTransactionKey) {
566
+ if (tl.transactionKey) {
567
+ (_b = store.config.logger) == null ? void 0 : _b.error(
568
+ `Timeline "${tl.key}" was unable to resolve transaction "${tl.transactionKey}. This is probably a bug.`
569
+ );
570
+ }
571
+ tl.transactionKey = currentTransactionKey;
572
+ const unsubscribe = currentTransaction.subject.subscribe(
573
+ `timeline:${tl.key}`,
574
+ (update2) => {
575
+ var _a2;
576
+ unsubscribe();
577
+ if (tl.timeTraveling === null && currentTransactionTime) {
578
+ if (tl.at !== tl.history.length) {
579
+ tl.history.splice(tl.at);
580
+ }
581
+ const atomUpdates = update2.atomUpdates.filter((atomUpdate) => {
582
+ const core = target(store);
583
+ const atomOrFamilyKeys = core.timelineAtoms.getRelatedKeys(
584
+ tl.key
585
+ );
586
+ return atomOrFamilyKeys ? [...atomOrFamilyKeys].some(
587
+ (key) => {
588
+ var _a3;
589
+ return key === atomUpdate.key || key === ((_a3 = atomUpdate.family) == null ? void 0 : _a3.key);
590
+ }
591
+ ) : false;
592
+ });
593
+ const timelineTransactionUpdate = __spreadProps(__spreadValues({
594
+ type: `transaction_update`,
595
+ timestamp: currentTransactionTime
596
+ }, update2), {
597
+ atomUpdates
598
+ });
599
+ tl.history.push(timelineTransactionUpdate);
600
+ tl.at = tl.history.length;
601
+ tl.subject.next(timelineTransactionUpdate);
602
+ }
603
+ tl.transactionKey = null;
604
+ (_a2 = store.config.logger) == null ? void 0 : _a2.info(
605
+ `\u231B timeline "${tl.key}" got a transaction_update "${update2.key}"`
606
+ );
607
+ }
608
+ );
609
+ }
610
+ } else if (currentSelectorKey && currentSelectorTime) {
611
+ let latestUpdate = tl.history.at(-1);
612
+ if (currentSelectorTime !== tl.selectorTime) {
613
+ latestUpdate = {
614
+ type: `selector_update`,
615
+ timestamp: currentSelectorTime,
616
+ key: currentSelectorKey,
617
+ atomUpdates: []
618
+ };
619
+ latestUpdate.atomUpdates.push(__spreadValues({
620
+ key: atom.key,
621
+ type: `atom_update`
622
+ }, update));
623
+ if (tl.at !== tl.history.length) {
624
+ tl.history.splice(tl.at);
625
+ }
626
+ tl.history.push(latestUpdate);
627
+ (_c = store.config.logger) == null ? void 0 : _c.info(
628
+ `\u231B timeline "${tl.key}" got a selector_update "${currentSelectorKey}" with`,
629
+ latestUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key)
630
+ );
631
+ tl.at = tl.history.length;
632
+ tl.selectorTime = currentSelectorTime;
633
+ } else {
634
+ if ((latestUpdate == null ? void 0 : latestUpdate.type) === `selector_update`) {
635
+ latestUpdate.atomUpdates.push(__spreadValues({
636
+ key: atom.key,
637
+ type: `atom_update`
638
+ }, update));
639
+ (_d = store.config.logger) == null ? void 0 : _d.info(
640
+ ` \u231B timeline "${tl.key}" set selector_update "${currentSelectorKey}" to`,
641
+ latestUpdate == null ? void 0 : latestUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key)
642
+ );
643
+ }
644
+ }
645
+ if (latestUpdate)
646
+ tl.subject.next(latestUpdate);
647
+ } else {
648
+ const timestamp = Date.now();
649
+ tl.selectorTime = null;
650
+ if (tl.at !== tl.history.length) {
651
+ tl.history.splice(tl.at);
652
+ }
653
+ const atomUpdate = {
654
+ type: `atom_update`,
655
+ timestamp,
656
+ key: atom.key,
657
+ oldValue: update.oldValue,
658
+ newValue: update.newValue
659
+ };
660
+ if (atom.family) {
661
+ atomUpdate.family = atom.family;
662
+ }
663
+ tl.history.push(atomUpdate);
664
+ tl.subject.next(atomUpdate);
665
+ (_e = store.config.logger) == null ? void 0 : _e.info(
666
+ `\u231B timeline "${tl.key}" got an atom_update to "${atom.key}"`
667
+ );
668
+ tl.at = tl.history.length;
669
+ }
670
+ }
671
+ });
672
+ };
673
+ var redo__INTERNAL = (token, store = IMPLICIT.STORE) => {
674
+ var _a, _b, _c, _d;
675
+ (_a = store.config.logger) == null ? void 0 : _a.info(`\u23E9 redo "${token.key}"`);
676
+ const timelineData = store.timelines.get(token.key);
677
+ if (!timelineData) {
678
+ (_b = store.config.logger) == null ? void 0 : _b.error(
679
+ `Failed to redo on timeline "${token.key}". This timeline has not been initialized.`
680
+ );
681
+ return;
682
+ }
683
+ if (timelineData.at === timelineData.history.length) {
684
+ (_c = store.config.logger) == null ? void 0 : _c.warn(
685
+ `Failed to redo at the end of timeline "${token.key}". There is nothing to redo.`
686
+ );
687
+ return;
688
+ }
689
+ timelineData.timeTraveling = `into_future`;
690
+ const update = timelineData.history[timelineData.at];
691
+ switch (update.type) {
692
+ case `atom_update`: {
693
+ const { key, newValue } = update;
694
+ setState({ key, type: `atom` }, newValue, store);
695
+ break;
696
+ }
697
+ case `selector_update`:
698
+ case `transaction_update`: {
699
+ for (const atomUpdate of update.atomUpdates) {
700
+ const { key, newValue } = atomUpdate;
701
+ setState({ key, type: `atom` }, newValue, store);
702
+ }
703
+ break;
704
+ }
705
+ }
706
+ ++timelineData.at;
707
+ timelineData.subject.next(`redo`);
708
+ timelineData.timeTraveling = null;
709
+ (_d = store.config.logger) == null ? void 0 : _d.info(
710
+ `\u23F9\uFE0F "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`
711
+ );
712
+ };
713
+ var undo__INTERNAL = (token, store = IMPLICIT.STORE) => {
714
+ var _a, _b, _c, _d;
715
+ (_a = store.config.logger) == null ? void 0 : _a.info(`\u23EA undo "${token.key}"`);
716
+ const timelineData = store.timelines.get(token.key);
717
+ if (!timelineData) {
718
+ (_b = store.config.logger) == null ? void 0 : _b.error(
719
+ `Failed to undo on timeline "${token.key}". This timeline has not been initialized.`
720
+ );
721
+ return;
722
+ }
723
+ if (timelineData.at === 0) {
724
+ (_c = store.config.logger) == null ? void 0 : _c.warn(
725
+ `Failed to undo at the beginning of timeline "${token.key}". There is nothing to undo.`
726
+ );
727
+ return;
728
+ }
729
+ timelineData.timeTraveling = `into_past`;
730
+ --timelineData.at;
731
+ const update = timelineData.history[timelineData.at];
732
+ switch (update.type) {
733
+ case `atom_update`: {
734
+ const { key, oldValue } = update;
735
+ setState({ key, type: `atom` }, oldValue, store);
736
+ break;
737
+ }
738
+ case `selector_update`:
739
+ case `transaction_update`: {
740
+ for (const atomUpdate of [...update.atomUpdates].reverse()) {
741
+ const { key, oldValue } = atomUpdate;
742
+ setState({ key, type: `atom` }, oldValue, store);
743
+ }
744
+ break;
745
+ }
746
+ }
747
+ timelineData.subject.next(`undo`);
748
+ timelineData.timeTraveling = null;
749
+ (_d = store.config.logger) == null ? void 0 : _d.info(
750
+ `\u23F9\uFE0F "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`
751
+ );
752
+ };
753
+
754
+ // src/timeline/timeline-internal.ts
755
+ function timeline__INTERNAL(options, store = IMPLICIT.STORE, data = null) {
756
+ var _a, _b, _c;
757
+ const tl = __spreadProps(__spreadValues({
758
+ type: `timeline`,
759
+ key: options.key,
760
+ at: 0,
761
+ timeTraveling: null,
762
+ selectorTime: null,
763
+ transactionKey: null
764
+ }, data), {
765
+ history: (_a = data == null ? void 0 : data.history.map((update) => __spreadValues({}, update))) != null ? _a : [],
766
+ install: (store2) => timeline__INTERNAL(options, store2, tl),
767
+ subject: new Subject()
768
+ });
769
+ const core = target(store);
770
+ for (const tokenOrFamily of options.atoms) {
771
+ const timelineKey = core.timelineAtoms.getRelatedKey(tokenOrFamily.key);
772
+ if (timelineKey) {
773
+ (_b = store.config.logger) == null ? void 0 : _b.error(
774
+ `\u274C Failed to add atom "${tokenOrFamily.key}" to timeline "${options.key}" because it belongs to timeline "${timelineKey}"`
775
+ );
776
+ continue;
777
+ }
778
+ if (tokenOrFamily.type === `atom_family`) {
779
+ const family = tokenOrFamily;
780
+ family.subject.subscribe(`timeline:${options.key}`, (token2) => {
781
+ if (!core.atoms.has(token2.key)) {
782
+ addAtomToTimeline(token2, tl, store);
783
+ }
784
+ });
785
+ } else {
786
+ const token2 = tokenOrFamily;
787
+ if (`family` in token2 && token2.family) {
788
+ const familyTimelineKey = core.timelineAtoms.getRelatedKey(
789
+ token2.family.key
790
+ );
791
+ if (familyTimelineKey) {
792
+ (_c = store.config.logger) == null ? void 0 : _c.error(
793
+ `\u274C Failed to add atom "${token2.key}" to timeline "${options.key}" because its family "${token2.family.key}" belongs to timeline "${familyTimelineKey}"`
794
+ );
795
+ continue;
796
+ }
797
+ }
798
+ addAtomToTimeline(token2, tl, store);
799
+ }
800
+ core.timelineAtoms = core.timelineAtoms.set({
801
+ atomKey: tokenOrFamily.key,
802
+ timelineKey: options.key
803
+ });
804
+ }
805
+ store.timelines.set(options.key, tl);
806
+ const token = {
807
+ key: options.key,
808
+ type: `timeline`
809
+ };
810
+ store.subject.timelineCreation.next(token);
811
+ return token;
812
+ }
813
+
814
+ // src/store/withdraw.ts
815
+ function withdraw(token, store) {
816
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
817
+ let core = target(store);
818
+ let state = (_d = (_c = (_b = (_a = core.atoms.get(token.key)) != null ? _a : core.selectors.get(token.key)) != null ? _b : core.readonlySelectors.get(token.key)) != null ? _c : core.transactions.get(token.key)) != null ? _d : core.timelines.get(token.key);
819
+ if (state) {
820
+ return state;
821
+ }
822
+ if (store.transactionStatus.phase === `applying`) {
823
+ core = store.transactionStatus.core;
824
+ state = (_h = (_g = (_f = (_e = core.atoms.get(token.key)) != null ? _e : core.selectors.get(token.key)) != null ? _f : core.readonlySelectors.get(token.key)) != null ? _g : core.transactions.get(token.key)) != null ? _h : core.timelines.get(token.key);
825
+ if (state) {
826
+ (_i = store.config.logger) == null ? void 0 : _i.info(`\u{1F6E0}\uFE0F add ${token.type} "${token.key}"`);
827
+ switch (state.type) {
828
+ case `atom`: {
829
+ store.atoms.set(token.key, state);
830
+ store.valueMap.set(token.key, state.default);
831
+ const stateKey = state.key;
832
+ const familyKey = (_j = state.family) == null ? void 0 : _j.key;
833
+ let timelineKey = core.timelineAtoms.getRelatedKey(stateKey);
834
+ if (timelineKey === void 0 && typeof familyKey === `string`) {
835
+ timelineKey = core.timelineAtoms.getRelatedKey(familyKey);
836
+ }
837
+ const timeline = typeof timelineKey === `string` ? store.timelines.get(timelineKey) : void 0;
838
+ if (timeline) {
839
+ addAtomToTimeline(state, timeline, store);
840
+ }
841
+ break;
842
+ }
843
+ case `selector`:
844
+ core.selectors.set(token.key, state);
845
+ break;
846
+ case `readonly_selector`:
847
+ core.readonlySelectors.set(token.key, state);
848
+ break;
849
+ case `transaction`:
850
+ core.transactions.set(token.key, state);
851
+ break;
852
+ case `timeline`:
853
+ core.timelines.set(token.key, state);
854
+ break;
855
+ }
856
+ return state;
857
+ }
858
+ }
859
+ return null;
860
+ }
861
+
862
+ // src/store/withdraw-new-family-member.ts
863
+ function withdrawNewFamilyMember(token, store) {
864
+ var _a;
865
+ (_a = store.config.logger) == null ? void 0 : _a.info(
866
+ `\u{1F46A} creating new family member "${token.key}" in store "${store.config.name}"`
867
+ );
868
+ if (token.family) {
869
+ const core = target(store);
870
+ const family = core.families.get(token.family.key);
871
+ if (family) {
872
+ const jsonSubKey = JSON.parse(token.family.subKey);
873
+ family(jsonSubKey);
874
+ const state = withdraw(token, store);
875
+ return state;
876
+ }
877
+ }
878
+ return null;
879
+ }
880
+
881
+ // src/caching.ts
882
+ var cacheValue = (key, value, store = IMPLICIT.STORE) => {
883
+ target(store).valueMap.set(key, value);
884
+ };
885
+ var readCachedValue = (key, store = IMPLICIT.STORE) => target(store).valueMap.get(key);
886
+ var isValueCached = (key, store = IMPLICIT.STORE) => target(store).valueMap.has(key);
887
+ var Tracker = class {
888
+ constructor(mutableState, store = IMPLICIT.STORE) {
889
+ this.unsubscribeFromInnerValue = null;
890
+ this.mutableState = mutableState;
891
+ this.latestUpdateState = this.initializeState(mutableState, store);
892
+ this.observeCore(mutableState, this.latestUpdateState, store);
893
+ this.updateCore(mutableState, this.latestUpdateState, store);
894
+ const core = target(store);
895
+ core.trackers.set(mutableState.key, this);
896
+ }
897
+ initializeState(mutableState, store = IMPLICIT.STORE) {
898
+ const latestUpdateStateKey = `*${mutableState.key}`;
899
+ deleteAtom(latestUpdateStateKey, target(store));
900
+ const familyMetaData = mutableState.family ? {
901
+ key: `*${mutableState.family.key}`,
902
+ subKey: mutableState.family.subKey
903
+ } : void 0;
904
+ const latestUpdateState = createAtom(
905
+ {
906
+ key: latestUpdateStateKey,
907
+ default: null
908
+ },
909
+ familyMetaData,
910
+ store
911
+ );
912
+ return latestUpdateState;
913
+ }
914
+ observeCore(mutableState, latestUpdateState, store = IMPLICIT.STORE) {
915
+ const originalInnerValue = AtomIO.getState(mutableState, store);
916
+ this.unsubscribeFromInnerValue = originalInnerValue.subscribe(
917
+ `tracker:${store.config.name}:${store.transactionStatus.phase === `idle` ? `main` : store.transactionStatus.key}`,
918
+ (update) => {
919
+ const unsubscribe = store.subject.operationStatus.subscribe(
920
+ mutableState.key,
921
+ () => {
922
+ unsubscribe();
923
+ AtomIO.setState(latestUpdateState, update, store);
924
+ }
925
+ );
926
+ }
927
+ );
928
+ AtomIO.subscribe(
929
+ mutableState,
930
+ (update) => {
931
+ var _a;
932
+ if (update.newValue !== update.oldValue) {
933
+ (_a = this.unsubscribeFromInnerValue) == null ? void 0 : _a.call(this);
934
+ this.unsubscribeFromInnerValue = update.newValue.subscribe(
935
+ `tracker:${store.config.name}:${store.transactionStatus.phase === `idle` ? `main` : store.transactionStatus.key}`,
936
+ (update2) => {
937
+ const unsubscribe = store.subject.operationStatus.subscribe(
938
+ mutableState.key,
939
+ () => {
940
+ unsubscribe();
941
+ AtomIO.setState(latestUpdateState, update2, store);
942
+ }
943
+ );
944
+ }
945
+ );
946
+ }
947
+ },
948
+ `${store.config.name}: tracker observing inner value`,
949
+ store
950
+ );
951
+ }
952
+ updateCore(mutableState, latestUpdateState, store = IMPLICIT.STORE) {
953
+ AtomIO.subscribe(
954
+ latestUpdateState,
955
+ ({ newValue, oldValue }) => {
956
+ const timelineId = store.timelineAtoms.getRelatedKey(
957
+ latestUpdateState.key
958
+ );
959
+ if (timelineId) {
960
+ const timelineData = store.timelines.get(timelineId);
961
+ if (timelineData == null ? void 0 : timelineData.timeTraveling) {
962
+ const unsubscribe2 = AtomIO.subscribeToTimeline(
963
+ { key: timelineId, type: `timeline` },
964
+ (update) => {
965
+ unsubscribe2();
966
+ AtomIO.setState(
967
+ mutableState,
968
+ (transceiver) => {
969
+ if (update === `redo` && newValue) {
970
+ transceiver.do(newValue);
971
+ } else if (update === `undo` && oldValue) {
972
+ transceiver.undo(oldValue);
973
+ }
974
+ return transceiver;
975
+ },
976
+ store
977
+ );
978
+ }
979
+ );
980
+ return;
981
+ }
982
+ }
983
+ const unsubscribe = store.subject.operationStatus.subscribe(
984
+ latestUpdateState.key,
985
+ () => {
986
+ unsubscribe();
987
+ if (newValue) {
988
+ AtomIO.setState(
989
+ mutableState,
990
+ (transceiver) => (transceiver.do(newValue), transceiver),
991
+ store
992
+ );
993
+ }
994
+ }
995
+ );
996
+ },
997
+ `${store.config.name}: tracker observing latest update`,
998
+ store
999
+ );
1000
+ }
1001
+ };
1002
+
1003
+ // src/mutable/create-mutable-atom.ts
1004
+ function createMutableAtom(options, store = IMPLICIT.STORE) {
1005
+ var _a;
1006
+ (_a = store.config.logger) == null ? void 0 : _a.info(
1007
+ `\u{1F527} creating mutable atom "${options.key}" in store "${store.config.name}"`
1008
+ );
1009
+ const coreState = createAtom(options, void 0, store);
1010
+ new Tracker(coreState, store);
1011
+ const jsonState = selectJson(coreState, options, store);
1012
+ AtomIO.subscribe(
1013
+ jsonState,
1014
+ () => {
1015
+ var _a2;
1016
+ (_a2 = store.config.logger) == null ? void 0 : _a2.info(
1017
+ `\u{1F50D} tracker-initializer:${store == null ? void 0 : store.config.name}:${store.transactionStatus.phase === `idle` ? `main` : store.transactionStatus.key}`,
1018
+ `Initializing tracker for ${coreState.key}`
1019
+ );
1020
+ const trackerHasBeenInitialized = target(store).trackers.has(coreState.key);
1021
+ if (!trackerHasBeenInitialized) {
1022
+ new Tracker(coreState, store);
1023
+ }
1024
+ },
1025
+ `tracker-initializer:${store == null ? void 0 : store.config.name}:${store.transactionStatus.phase === `idle` ? `main` : store.transactionStatus.key}`
1026
+ );
1027
+ return coreState;
1028
+ }
1029
+ function createAtomFamily(options, store = IMPLICIT.STORE) {
1030
+ const subject = new Subject();
1031
+ const atomFamily = Object.assign(
1032
+ (key) => {
1033
+ const subKey = stringifyJson(key);
1034
+ const family = { key: options.key, subKey };
1035
+ const fullKey = `${options.key}(${subKey})`;
1036
+ const existing = withdraw({ key: fullKey, type: `atom` }, store);
1037
+ let token;
1038
+ if (existing) {
1039
+ token = deposit(existing);
1040
+ } else {
1041
+ const individualOptions = {
1042
+ key: fullKey,
1043
+ default: options.default instanceof Function ? options.default(key) : options.default
1044
+ };
1045
+ if (options.effects) {
1046
+ individualOptions.effects = options.effects(key);
1047
+ }
1048
+ token = createAtom(individualOptions, family, store);
1049
+ subject.next(token);
1050
+ }
1051
+ return token;
1052
+ },
1053
+ {
1054
+ key: options.key,
1055
+ type: `atom_family`,
1056
+ subject
1057
+ }
1058
+ );
1059
+ const core = target(store);
1060
+ core.families.set(options.key, atomFamily);
1061
+ return atomFamily;
1062
+ }
1063
+
1064
+ // src/selector/lookup-selector-sources.ts
1065
+ var lookupSelectorSources = (key, store) => {
1066
+ const sources = target(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => lookup(source, store));
1067
+ return sources;
1068
+ };
1069
+
1070
+ // src/get-state-internal.ts
1071
+ var getState__INTERNAL = (state, store = IMPLICIT.STORE) => {
1072
+ var _a, _b, _c;
1073
+ if (isValueCached(state.key, store)) {
1074
+ (_a = store.config.logger) == null ? void 0 : _a.info(`>> read "${state.key}"`);
1075
+ return readCachedValue(state.key, store);
1076
+ }
1077
+ if (state.type !== `atom`) {
1078
+ (_b = store.config.logger) == null ? void 0 : _b.info(`-> calc "${state.key}"`);
1079
+ return state.get();
1080
+ }
1081
+ (_c = store.config.logger) == null ? void 0 : _c.error(
1082
+ `Attempted to get atom "${state.key}", which was never initialized in store "${store.config.name}".`
1083
+ );
1084
+ return state.default;
1085
+ };
1086
+
1087
+ // src/set-state/become.ts
1088
+ var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(
1089
+ originalThing instanceof Function ? originalThing() : originalThing
1090
+ ) : nextVersionOfThing;
1091
+
1092
+ // src/operation.ts
1093
+ var openOperation = (token, store) => {
1094
+ var _a, _b;
1095
+ const core = target(store);
1096
+ if (core.operation.open) {
1097
+ (_a = store.config.logger) == null ? void 0 : _a.error(
1098
+ `\u274C failed to setState to "${token.key}" during a setState for "${core.operation.token.key}"`
1099
+ );
1100
+ throw Symbol(`violation`);
1101
+ }
1102
+ core.operation = {
1103
+ open: true,
1104
+ done: /* @__PURE__ */ new Set(),
1105
+ prev: new Map(store.valueMap),
1106
+ time: Date.now(),
1107
+ token
1108
+ };
1109
+ (_b = store.config.logger) == null ? void 0 : _b.info(
1110
+ `\u2B55 operation start from "${token.key}" in store "${store.config.name}"${store.transactionStatus.phase === `idle` ? `` : ` ${store.transactionStatus.phase} "${store.transactionStatus.key}"`}`
1111
+ );
1112
+ };
1113
+ var closeOperation = (store) => {
1114
+ var _a;
1115
+ const core = target(store);
1116
+ core.operation = { open: false };
1117
+ (_a = store.config.logger) == null ? void 0 : _a.info(`\u{1F534} operation done`);
1118
+ store.subject.operationStatus.next(core.operation);
1119
+ };
1120
+ var isDone = (key, store = IMPLICIT.STORE) => {
1121
+ var _a;
1122
+ const core = target(store);
1123
+ if (!core.operation.open) {
1124
+ (_a = store.config.logger) == null ? void 0 : _a.warn(
1125
+ `isDone called outside of an operation. This is probably a bug.`
1126
+ );
1127
+ return true;
1128
+ }
1129
+ return core.operation.done.has(key);
1130
+ };
1131
+ var markDone = (key, store = IMPLICIT.STORE) => {
1132
+ var _a;
1133
+ const core = target(store);
1134
+ if (!core.operation.open) {
1135
+ (_a = store.config.logger) == null ? void 0 : _a.warn(
1136
+ `markDone called outside of an operation. This is probably a bug.`
1137
+ );
1138
+ return;
1139
+ }
1140
+ core.operation.done.add(key);
1141
+ };
1142
+
1143
+ // src/set-state/copy-mutable-if-needed.ts
1144
+ function copyMutableIfNeeded(atom, transform, origin, target3) {
1145
+ var _a;
1146
+ const originValue = origin.valueMap.get(atom.key);
1147
+ const targetValue = target3.valueMap.get(atom.key);
1148
+ if (originValue === targetValue) {
1149
+ (_a = origin.config.logger) == null ? void 0 : _a.info(`\u{1F4C3} copying`, `${atom.key}`);
1150
+ const copiedValue = transform.fromJson(transform.toJson(originValue));
1151
+ target3.valueMap.set(atom.key, copiedValue);
1152
+ new Tracker(atom, origin);
1153
+ return copiedValue;
1154
+ }
1155
+ return targetValue;
1156
+ }
1157
+
1158
+ // src/set-state/copy-mutable-in-transaction.ts
1159
+ function copyMutableIfWithinTransaction(atom, store) {
1160
+ var _a;
1161
+ if (store.transactionStatus.phase === `building` || store.transactionStatus.phase === `applying`) {
1162
+ if (`toJson` in atom && `fromJson` in atom) {
1163
+ (_a = store.config.logger) == null ? void 0 : _a.info(
1164
+ `\u{1F4C4} copyMutableIfWithinTransaction: ${atom.key} is mutable`
1165
+ );
1166
+ const copiedValue = copyMutableIfNeeded(
1167
+ atom,
1168
+ atom,
1169
+ store,
1170
+ store.transactionStatus.core
1171
+ );
1172
+ return copiedValue;
1173
+ }
1174
+ if (`family` in atom) {
1175
+ const family = store.transactionStatus.core.families.get(atom.family.key);
1176
+ if (family && family.type === `atom_family`) {
1177
+ const result = copyMutableFamilyMemberWithinTransaction(
1178
+ atom,
1179
+ family,
1180
+ store,
1181
+ store.transactionStatus.core
1182
+ );
1183
+ if (result) {
1184
+ return result;
1185
+ }
1186
+ }
1187
+ }
1188
+ }
1189
+ return getState__INTERNAL(atom, store);
1190
+ }
1191
+ function copyMutableFamilyMemberWithinTransaction(atom, family, origin, target3) {
1192
+ if (`toJson` in family && `fromJson` in family) {
1193
+ const copyCreated = copyMutableIfNeeded(atom, family, origin, target3);
1194
+ return copyCreated;
1195
+ }
1196
+ return null;
1197
+ }
1198
+
1199
+ // src/set-state/emit-update.ts
1200
+ var emitUpdate = (state, update, store) => {
1201
+ const { key } = state;
1202
+ const { logger } = store.config;
1203
+ logger == null ? void 0 : logger.info(
1204
+ `\u{1F4E2} ${state.type} "${key}" went (`,
1205
+ update.oldValue,
1206
+ `->`,
1207
+ update.newValue,
1208
+ `)`
1209
+ );
1210
+ logger == null ? void 0 : logger.info(`\u{1F4E2} notifying subscribers:`, state.subject.subscribers);
1211
+ state.subject.next(update);
1212
+ };
1213
+
1214
+ // src/set-state/evict-downstream.ts
1215
+ var evictDownStream = (state, store = IMPLICIT.STORE) => {
1216
+ var _a, _b, _c, _d, _e, _f, _g;
1217
+ const core = target(store);
1218
+ const downstreamKeys = core.selectorAtoms.getRelatedKeys(state.key);
1219
+ (_b = store.config.logger) == null ? void 0 : _b.info(
1220
+ ` || ${(_a = downstreamKeys == null ? void 0 : downstreamKeys.size) != null ? _a : `none`} downstream:`,
1221
+ downstreamKeys
1222
+ );
1223
+ if (core.operation.open) {
1224
+ (_c = store.config.logger) == null ? void 0 : _c.info(` ||`, [...core.operation.done], `already done`);
1225
+ }
1226
+ if (downstreamKeys) {
1227
+ for (const key of downstreamKeys) {
1228
+ if (isDone(key, store)) {
1229
+ (_d = store.config.logger) == null ? void 0 : _d.info(` || ${key} already done`);
1230
+ continue;
1231
+ }
1232
+ const state2 = (_e = core.selectors.get(key)) != null ? _e : core.readonlySelectors.get(key);
1233
+ if (!state2) {
1234
+ (_f = store.config.logger) == null ? void 0 : _f.info(
1235
+ ` || ${key} was not found in selectors or readonlySelectors`
1236
+ );
1237
+ return;
1238
+ }
1239
+ core.valueMap.delete(key);
1240
+ (_g = store.config.logger) == null ? void 0 : _g.info(` xx evicted "${key}"`);
1241
+ markDone(key, store);
1242
+ }
1243
+ }
1244
+ };
1245
+
1246
+ // src/set-state/stow-update.ts
1247
+ function shouldUpdateBeStowed(key, update) {
1248
+ if (isTransceiver(update.newValue)) {
1249
+ return false;
1250
+ }
1251
+ if (key.includes(`\u{1F441}\u200D\u{1F5E8}`)) {
1252
+ return false;
1253
+ }
1254
+ return true;
1255
+ }
1256
+ var stowUpdate = (state, update, store) => {
1257
+ var _a;
1258
+ const { key } = state;
1259
+ const { logger } = store.config;
1260
+ if (store.transactionStatus.phase !== `building`) {
1261
+ (_a = store.config.logger) == null ? void 0 : _a.warn(
1262
+ `stowUpdate called outside of a transaction. This is probably a bug.`
1263
+ );
1264
+ return;
1265
+ }
1266
+ const shouldStow = shouldUpdateBeStowed(key, update);
1267
+ if (!shouldStow) {
1268
+ return;
1269
+ }
1270
+ const atomUpdate = __spreadValues({ key }, update);
1271
+ if (state.family) {
1272
+ atomUpdate.family = state.family;
1273
+ }
1274
+ store.transactionStatus.atomUpdates.push(atomUpdate);
1275
+ logger == null ? void 0 : logger.info(`\u{1F4DD} ${key} stowed (`, update.oldValue, `->`, update.newValue, `)`);
1276
+ };
1277
+
1278
+ // src/set-state/set-atom-state.ts
1279
+ var setAtomState = (atom, next, store = IMPLICIT.STORE) => {
1280
+ var _a, _b;
1281
+ const oldValue = getState__INTERNAL(atom, store);
1282
+ let newValue = copyMutableIfWithinTransaction(atom, store);
1283
+ newValue = become(next)(newValue);
1284
+ (_a = store.config.logger) == null ? void 0 : _a.info(`<< setting atom "${atom.key}" to`, newValue);
1285
+ cacheValue(atom.key, newValue, store);
1286
+ if (isAtomDefault(atom.key, store)) {
1287
+ markAtomAsNotDefault(atom.key, store);
1288
+ }
1289
+ markDone(atom.key, store);
1290
+ (_b = store.config.logger) == null ? void 0 : _b.info(
1291
+ ` || evicting caches downstream from "${atom.key}"`
1292
+ );
1293
+ evictDownStream(atom, store);
1294
+ const update = { oldValue, newValue };
1295
+ if (store.transactionStatus.phase !== `building`) {
1296
+ emitUpdate(atom, update, store);
1297
+ } else {
1298
+ stowUpdate(atom, update, store);
1299
+ }
1300
+ };
1301
+
1302
+ // src/set-state/set-selector-state.ts
1303
+ var setSelectorState = (selector, next, store = IMPLICIT.STORE) => {
1304
+ var _a, _b;
1305
+ const oldValue = getState__INTERNAL(selector, store);
1306
+ const newValue = become(next)(oldValue);
1307
+ (_a = store.config.logger) == null ? void 0 : _a.info(`<< setting selector "${selector.key}" to`, newValue);
1308
+ (_b = store.config.logger) == null ? void 0 : _b.info(` || propagating change made to "${selector.key}"`);
1309
+ selector.set(newValue);
1310
+ };
1311
+
1312
+ // src/set-state/set-state-internal.ts
1313
+ var setState__INTERNAL = (state, value, store = IMPLICIT.STORE) => {
1314
+ if (`set` in state) {
1315
+ setSelectorState(state, value, store);
1316
+ } else {
1317
+ setAtomState(state, value, store);
1318
+ }
1319
+ };
1320
+
1321
+ // src/selector/trace-selector-atoms.ts
1322
+ var traceSelectorAtoms = (selectorKey, dependency, store) => {
1323
+ const roots = [];
1324
+ const sources = lookupSelectorSources(dependency.key, store);
1325
+ let depth = 0;
1326
+ while (sources.length > 0) {
1327
+ const source = sources.shift();
1328
+ ++depth;
1329
+ if (depth > 999) {
1330
+ throw new Error(
1331
+ `Maximum selector dependency depth exceeded in selector "${selectorKey}".`
1332
+ );
1333
+ }
1334
+ if (source.type !== `atom`) {
1335
+ sources.push(...lookupSelectorSources(source.key, store));
1336
+ } else {
1337
+ roots.push(source);
1338
+ }
1339
+ }
1340
+ return roots;
1341
+ };
1342
+ var traceAllSelectorAtoms = (selectorKey, store) => {
1343
+ const sources = lookupSelectorSources(selectorKey, store);
1344
+ return sources.flatMap(
1345
+ (source) => source.type === `atom` ? source : traceSelectorAtoms(selectorKey, source, store)
1346
+ );
1347
+ };
1348
+
1349
+ // src/selector/update-selector-atoms.ts
1350
+ var updateSelectorAtoms = (selectorKey, dependency, store) => {
1351
+ var _a, _b;
1352
+ const core = target(store);
1353
+ if (dependency.type === `atom`) {
1354
+ core.selectorAtoms = core.selectorAtoms.set({
1355
+ selectorKey,
1356
+ atomKey: dependency.key
1357
+ });
1358
+ (_a = store.config.logger) == null ? void 0 : _a.info(
1359
+ ` || adding root for "${selectorKey}": ${dependency.key}`
1360
+ );
1361
+ return;
1362
+ }
1363
+ const roots = traceSelectorAtoms(selectorKey, dependency, store);
1364
+ (_b = store.config.logger) == null ? void 0 : _b.info(
1365
+ ` || adding roots for "${selectorKey}":`,
1366
+ roots.map((r) => r.key)
1367
+ );
1368
+ for (const root of roots) {
1369
+ core.selectorAtoms = core.selectorAtoms.set({
1370
+ selectorKey,
1371
+ atomKey: root.key
1372
+ });
1373
+ }
1374
+ };
1375
+
1376
+ // src/selector/register-selector.ts
1377
+ var registerSelector = (selectorKey, store = IMPLICIT.STORE) => ({
1378
+ get: (dependency) => {
1379
+ var _a, _b;
1380
+ const core = target(store);
1381
+ const alreadyRegistered = core.selectorGraph.getRelationEntries({ downstreamSelectorKey: selectorKey }).some(([_, { source }]) => source === dependency.key);
1382
+ const dependencyState = withdraw(dependency, store);
1383
+ if (dependencyState === null) {
1384
+ throw new Error(
1385
+ `State "${dependency.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`
1386
+ );
1387
+ }
1388
+ const dependencyValue = getState__INTERNAL(dependencyState, store);
1389
+ if (alreadyRegistered) {
1390
+ (_a = store.config.logger) == null ? void 0 : _a.info(
1391
+ ` || ${selectorKey} <- ${dependency.key} =`,
1392
+ dependencyValue
1393
+ );
1394
+ } else {
1395
+ (_b = store.config.logger) == null ? void 0 : _b.info(
1396
+ `\u{1F50C} registerSelector "${selectorKey}" <- ( "${dependency.key}" =`,
1397
+ dependencyValue,
1398
+ `)`
1399
+ );
1400
+ core.selectorGraph = core.selectorGraph.set(
1401
+ {
1402
+ upstreamSelectorKey: dependency.key,
1403
+ downstreamSelectorKey: selectorKey
1404
+ },
1405
+ {
1406
+ source: dependency.key
1407
+ }
1408
+ );
1409
+ }
1410
+ updateSelectorAtoms(selectorKey, dependency, store);
1411
+ return dependencyValue;
1412
+ },
1413
+ set: (stateToken, newValue) => {
1414
+ const state = withdraw(stateToken, store);
1415
+ if (state === null) {
1416
+ throw new Error(
1417
+ `State "${stateToken.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`
1418
+ );
1419
+ }
1420
+ setState__INTERNAL(state, newValue, store);
1421
+ }
1422
+ });
1423
+
1424
+ // src/selector/create-read-write-selector.ts
1425
+ var createReadWriteSelector = (options, family, store, core) => {
1426
+ var _a;
1427
+ const subject = new Subject();
1428
+ const { get, set } = registerSelector(options.key, store);
1429
+ const getSelf = () => {
1430
+ const value = options.get({ get });
1431
+ cacheValue(options.key, value, store);
1432
+ return value;
1433
+ };
1434
+ const setSelf = (next) => {
1435
+ var _a2;
1436
+ const oldValue = getSelf();
1437
+ (_a2 = store.config.logger) == null ? void 0 : _a2.info(
1438
+ ` <- "${options.key}" went (`,
1439
+ oldValue,
1440
+ `->`,
1441
+ next,
1442
+ `)`
1443
+ );
1444
+ const newValue = become(next)(oldValue);
1445
+ cacheValue(options.key, newValue, store);
1446
+ markDone(options.key, store);
1447
+ if (store.transactionStatus.phase === `idle`) {
1448
+ subject.next({ newValue, oldValue });
1449
+ }
1450
+ options.set({ get, set }, newValue);
1451
+ };
1452
+ const mySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
1453
+ subject,
1454
+ install: (s) => createSelector(options, family, s),
1455
+ get: getSelf,
1456
+ set: setSelf,
1457
+ type: `selector`
1458
+ }), family && { family });
1459
+ core.selectors.set(options.key, mySelector);
1460
+ const initialValue = getSelf();
1461
+ (_a = store.config.logger) == null ? void 0 : _a.info(` \u2728 "${options.key}" =`, initialValue);
1462
+ const token = {
1463
+ key: options.key,
1464
+ type: `selector`
1465
+ };
1466
+ if (family) {
1467
+ token.family = family;
1468
+ }
1469
+ store.subject.selectorCreation.next(token);
1470
+ return token;
1471
+ };
1472
+
1473
+ // src/selector/create-readonly-selector.ts
1474
+ var createReadonlySelector = (options, family, store, core) => {
1475
+ var _a;
1476
+ const subject = new Subject();
1477
+ const { get } = registerSelector(options.key, store);
1478
+ const getSelf = () => {
1479
+ const value = options.get({ get });
1480
+ cacheValue(options.key, value, store);
1481
+ return value;
1482
+ };
1483
+ const readonlySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
1484
+ subject,
1485
+ install: (s) => createSelector(options, family, s),
1486
+ get: getSelf,
1487
+ type: `readonly_selector`
1488
+ }), family && { family });
1489
+ core.readonlySelectors.set(options.key, readonlySelector);
1490
+ const initialValue = getSelf();
1491
+ (_a = store.config.logger) == null ? void 0 : _a.info(` \u2728 "${options.key}" =`, initialValue);
1492
+ const token = {
1493
+ key: options.key,
1494
+ type: `readonly_selector`
1495
+ };
1496
+ if (family) {
1497
+ token.family = family;
1498
+ }
1499
+ store.subject.selectorCreation.next(token);
1500
+ return token;
1501
+ };
1502
+
1503
+ // src/selector/create-selector.ts
1504
+ function createSelector(options, family, store = IMPLICIT.STORE) {
1505
+ var _a, _b;
1506
+ const core = target(store);
1507
+ const existingWritable = core.selectors.get(options.key);
1508
+ const existingReadonly = core.readonlySelectors.get(options.key);
1509
+ if (existingWritable || existingReadonly) {
1510
+ (_b = (_a = store.config.logger) == null ? void 0 : _a.error) == null ? void 0 : _b.call(
1511
+ _a,
1512
+ `Tried to create ${existingReadonly ? `readonly selector` : `selector`}`,
1513
+ `"${options.key}", but it already exists in the store.`,
1514
+ `(Ignore if you are using hot module replacement.)`
1515
+ );
1516
+ }
1517
+ if (`set` in options) {
1518
+ return createReadWriteSelector(options, family, store, core);
1519
+ }
1520
+ return createReadonlySelector(options, family, store, core);
1521
+ }
1522
+
1523
+ // src/families/create-readonly-selector-family.ts
1524
+ function createReadonlySelectorFamily(options, store) {
1525
+ const core = target(store);
1526
+ const subject = new Subject();
1527
+ return Object.assign(
1528
+ (key) => {
1529
+ const subKey = stringifyJson(key);
1530
+ const family = { key: options.key, subKey };
1531
+ const fullKey = `${options.key}(${subKey})`;
1532
+ const existing = core.readonlySelectors.get(fullKey);
1533
+ if (existing) {
1534
+ return deposit(existing);
1535
+ }
1536
+ return createSelector(
1537
+ {
1538
+ key: fullKey,
1539
+ get: options.get(key)
1540
+ },
1541
+ family,
1542
+ store
1543
+ );
1544
+ },
1545
+ {
1546
+ key: options.key,
1547
+ type: `readonly_selector_family`,
1548
+ subject
1549
+ }
1550
+ );
1551
+ }
1552
+ function createSelectorFamily(options, store = IMPLICIT.STORE) {
1553
+ const isReadonly = !(`set` in options);
1554
+ if (isReadonly) {
1555
+ return createReadonlySelectorFamily(options, store);
1556
+ }
1557
+ const core = target(store);
1558
+ const subject = new Subject();
1559
+ const selectorFamily = Object.assign(
1560
+ (key) => {
1561
+ const subKey = stringifyJson(key);
1562
+ const family = { key: options.key, subKey };
1563
+ const fullKey = `${options.key}(${subKey})`;
1564
+ const existing = core.selectors.get(fullKey);
1565
+ if (existing) {
1566
+ return deposit(existing);
1567
+ }
1568
+ const token = createSelector(
1569
+ {
1570
+ key: fullKey,
1571
+ get: options.get(key),
1572
+ set: options.set(key)
1573
+ },
1574
+ family,
1575
+ store
1576
+ );
1577
+ subject.next(token);
1578
+ return token;
1579
+ },
1580
+ {
1581
+ key: options.key,
1582
+ type: `selector_family`
1583
+ }
1584
+ );
1585
+ core.families.set(options.key, selectorFamily);
1586
+ return selectorFamily;
1587
+ }
1588
+
1589
+ // src/mutable/tracker-family.ts
1590
+ var FamilyTracker = class {
1591
+ constructor(findMutableState, store = IMPLICIT.STORE) {
1592
+ this.findLatestUpdateState = createAtomFamily(
1593
+ {
1594
+ key: `*${findMutableState.key}`,
1595
+ default: null
1596
+ },
1597
+ store
1598
+ );
1599
+ this.findMutableState = findMutableState;
1600
+ this.findMutableState.subject.subscribe(
1601
+ `store=${store.config.name}::tracker-atom-family`,
1602
+ (atomToken) => {
1603
+ if (atomToken.family) {
1604
+ const key = parseJson(atomToken.family.subKey);
1605
+ this.findLatestUpdateState(key);
1606
+ new Tracker(atomToken, store);
1607
+ }
1608
+ }
1609
+ );
1610
+ this.findLatestUpdateState.subject.subscribe(
1611
+ `store=${store.config.name}::tracker-atom-family`,
1612
+ (atomToken) => {
1613
+ if (atomToken.family) {
1614
+ const key = parseJson(atomToken.family.subKey);
1615
+ const mutableAtomToken = this.findMutableState(key);
1616
+ new Tracker(mutableAtomToken, store);
1617
+ }
1618
+ }
1619
+ );
1620
+ }
1621
+ };
1622
+
1623
+ // src/mutable/create-mutable-atom-family.ts
1624
+ function createMutableAtomFamily(options, store = IMPLICIT.STORE) {
1625
+ const coreFamily = Object.assign(
1626
+ createAtomFamily(options, store),
1627
+ options
1628
+ );
1629
+ selectJsonFamily(coreFamily, options);
1630
+ new FamilyTracker(coreFamily, store);
1631
+ return coreFamily;
1632
+ }
1633
+
1634
+ // src/mutable/get-json-token.ts
1635
+ var getJsonToken = (mutableAtomToken) => {
1636
+ const key = mutableAtomToken.family ? `${mutableAtomToken.family.key}:JSON(${mutableAtomToken.family.subKey})` : `${mutableAtomToken.key}:JSON`;
1637
+ const jsonToken = { type: `selector`, key };
1638
+ if (mutableAtomToken.family) {
1639
+ jsonToken.family = {
1640
+ key: `${mutableAtomToken.family.key}:JSON`,
1641
+ subKey: mutableAtomToken.family.subKey
1642
+ };
1643
+ }
1644
+ return jsonToken;
1645
+ };
1646
+
1647
+ // src/mutable/get-update-token.ts
1648
+ var getUpdateToken = (mutableAtomToken) => {
1649
+ const key = `*${mutableAtomToken.key}`;
1650
+ const updateToken = { type: `atom`, key };
1651
+ if (mutableAtomToken.family) {
1652
+ updateToken.family = {
1653
+ key: `*${mutableAtomToken.family.key}`,
1654
+ subKey: mutableAtomToken.family.subKey
1655
+ };
1656
+ }
1657
+ return updateToken;
1658
+ };
1659
+
1660
+ // src/mutable/is-atom-token-mutable.ts
1661
+ function isAtomTokenMutable(token) {
1662
+ return token.key.endsWith(`::mutable`);
1663
+ }
1664
+
1665
+ // src/mutable/transceiver.ts
1666
+ function isTransceiver(value) {
1667
+ return typeof value === `object` && value !== null && `do` in value && `undo` in value && `subscribe` in value;
1668
+ }
1669
+
1670
+ // src/mutable/index.ts
1671
+ var isAtomMutable = (atom) => `isMutable` in atom;
1672
+
1673
+ // src/atom/is-default.ts
1674
+ var isAtomDefault = (key, store = IMPLICIT.STORE) => {
1675
+ const core = target(store);
1676
+ return core.atomsThatAreDefault.has(key);
1677
+ };
1678
+ var markAtomAsDefault = (key, store = IMPLICIT.STORE) => {
1679
+ const core = target(store);
1680
+ core.atomsThatAreDefault = new Set(core.atomsThatAreDefault).add(key);
1681
+ };
1682
+ var markAtomAsNotDefault = (key, store = IMPLICIT.STORE) => {
1683
+ const core = target(store);
1684
+ core.atomsThatAreDefault = new Set(target(store).atomsThatAreDefault);
1685
+ core.atomsThatAreDefault.delete(key);
1686
+ };
1687
+ var isSelectorDefault = (key, store = IMPLICIT.STORE) => {
1688
+ const roots = traceAllSelectorAtoms(key, store);
1689
+ return roots.every((root) => isAtomDefault(root.key, store));
1690
+ };
1691
+
1692
+ // src/atom/create-atom.ts
1693
+ function createAtom(options, family, store = IMPLICIT.STORE) {
1694
+ var _a, _b, _c, _d, _e;
1695
+ (_b = (_a = store.config.logger) == null ? void 0 : _a.info) == null ? void 0 : _b.call(
1696
+ _a,
1697
+ `\u{1F528} creating atom "${options.key}" in store "${store.config.name}"`
1698
+ );
1699
+ const core = target(store);
1700
+ const existing = core.atoms.get(options.key);
1701
+ if (existing) {
1702
+ (_d = (_c = store.config.logger) == null ? void 0 : _c.error) == null ? void 0 : _d.call(
1703
+ _c,
1704
+ `Tried to create atom "${options.key}",`,
1705
+ `but it already exists in the store.`,
1706
+ `(Ignore if you are using hot module replacement.)`
1707
+ );
1708
+ return deposit(existing);
1709
+ }
1710
+ const subject = new Subject();
1711
+ const newAtom = __spreadValues(__spreadProps(__spreadValues({}, options), {
1712
+ type: `atom`,
1713
+ install: (store2) => {
1714
+ var _a2, _b2;
1715
+ (_b2 = (_a2 = store2.config.logger) == null ? void 0 : _a2.info) == null ? void 0 : _b2.call(
1716
+ _a2,
1717
+ `\u{1F6E0}\uFE0F installing atom "${options.key}" in store "${store2.config.name}"`
1718
+ );
1719
+ return `mutable` in options ? createMutableAtom(options, store2) : createAtom(options, void 0, store2);
1720
+ },
1721
+ subject
1722
+ }), family && { family });
1723
+ const initialValue = options.default instanceof Function ? options.default() : options.default;
1724
+ core.atoms.set(newAtom.key, newAtom);
1725
+ markAtomAsDefault(options.key, store);
1726
+ cacheValue(options.key, initialValue, store);
1727
+ const token = deposit(newAtom);
1728
+ for (const effect of (_e = options.effects) != null ? _e : []) {
1729
+ effect({
1730
+ setSelf: (next) => setState(token, next, store),
1731
+ onSet: (handle) => subscribe(token, handle, `effect[${subject.subscribers.size}]`, store)
1732
+ });
1733
+ }
1734
+ store.subject.atomCreation.next(token);
1735
+ return token;
1736
+ }
1737
+
1738
+ // src/atom/delete-atom.ts
1739
+ function deleteAtom(key, core = IMPLICIT.STORE) {
1740
+ core.atoms.delete(key);
1741
+ core.valueMap.delete(key);
1742
+ core.selectorAtoms.delete(key);
1743
+ core.atomsThatAreDefault.delete(key);
1744
+ core.timelineAtoms.delete(key);
1745
+ }
1746
+
1747
+ // src/subscribe/recall-state.ts
1748
+ var recallState = (state, store = IMPLICIT.STORE) => {
1749
+ var _a;
1750
+ const core = target(store);
1751
+ if (!core.operation.open) {
1752
+ (_a = store.config.logger) == null ? void 0 : _a.warn(
1753
+ `recall called outside of an operation. This is probably a bug.`
1754
+ );
1755
+ return core.valueMap.get(state.key);
1756
+ }
1757
+ return core.operation.prev.get(state.key);
1758
+ };
1759
+
1760
+ // src/subscribe/subscribe-to-root-atoms.ts
1761
+ var subscribeToRootAtoms = (state, store) => {
1762
+ const dependencySubscriptions = `default` in state ? null : traceAllSelectorAtoms(state.key, store).map((atomToken) => {
1763
+ const atom = withdraw(atomToken, store);
1764
+ if (atom === null) {
1765
+ throw new Error(
1766
+ `Atom "${atomToken.key}", a dependency of selector "${state.key}", not found in store "${store.config.name}".`
1767
+ );
1768
+ }
1769
+ return atom.subject.subscribe(
1770
+ `${state.type}:${state.key}`,
1771
+ (atomChange) => {
1772
+ var _a, _b;
1773
+ (_a = store.config.logger) == null ? void 0 : _a.info(
1774
+ `\u{1F4E2} selector "${state.key}" saw root "${atomToken.key}" go (`,
1775
+ atomChange.oldValue,
1776
+ `->`,
1777
+ atomChange.newValue,
1778
+ `)`
1779
+ );
1780
+ const oldValue = recallState(state, store);
1781
+ const newValue = getState__INTERNAL(state, store);
1782
+ (_b = store.config.logger) == null ? void 0 : _b.info(
1783
+ ` <- "${state.key}" went (`,
1784
+ oldValue,
1785
+ `->`,
1786
+ newValue,
1787
+ `)`
1788
+ );
1789
+ state.subject.next({ newValue, oldValue });
1790
+ }
1791
+ );
1792
+ });
1793
+ return dependencySubscriptions;
1794
+ };
1795
+
1796
+ export { FamilyTracker, IMPLICIT, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, addAtomToTimeline, applyTransaction, become, buildTransaction, cacheValue, clearStore, closeOperation, createAtom, createAtomFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelectorFamily, createSelector, createSelectorFamily, deleteAtom, deposit, getJsonToken, getState__INTERNAL, getUpdateToken, isAtomDefault, isAtomMutable, isAtomTokenMutable, isDone, isSelectorDefault, isTransceiver, isValueCached, lookup, lookupSelectorSources, markAtomAsDefault, markAtomAsNotDefault, markDone, openOperation, readCachedValue, redoTransactionUpdate, redo__INTERNAL, registerSelector, setState__INTERNAL, subscribeToRootAtoms, target, timeline__INTERNAL, traceAllSelectorAtoms, traceSelectorAtoms, transaction__INTERNAL, undoTransactionUpdate, undo__INTERNAL, updateSelectorAtoms, withdraw, withdrawNewFamilyMember };
1797
+ //# sourceMappingURL=out.js.map
1798
+ //# sourceMappingURL=index.mjs.map