atom.io 0.13.0 → 0.14.1

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 (141) hide show
  1. package/data/dist/index.cjs +1473 -52
  2. package/data/dist/index.cjs.map +1 -1
  3. package/data/dist/index.d.cts +315 -16
  4. package/data/dist/index.js +10 -267
  5. package/data/dist/index.js.map +1 -1
  6. package/data/package.json +5 -5
  7. package/data/src/join.ts +3 -3
  8. package/dist/chunk-5VJ77LZE.js +176 -0
  9. package/dist/chunk-5VJ77LZE.js.map +1 -0
  10. package/dist/chunk-CK7GNCU5.js +309 -0
  11. package/dist/chunk-CK7GNCU5.js.map +1 -0
  12. package/dist/chunk-KW7RA7IM.js +67 -0
  13. package/dist/chunk-KW7RA7IM.js.map +1 -0
  14. package/dist/chunk-LFXB7Y6M.js +68 -0
  15. package/dist/chunk-LFXB7Y6M.js.map +1 -0
  16. package/dist/chunk-NYCVSXQB.js +181 -0
  17. package/dist/chunk-NYCVSXQB.js.map +1 -0
  18. package/dist/chunk-TE3ZSTQ6.js +2516 -0
  19. package/dist/chunk-TE3ZSTQ6.js.map +1 -0
  20. package/dist/index.cjs +2250 -126
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +272 -25
  23. package/dist/index.js +1 -215
  24. package/dist/index.js.map +1 -1
  25. package/dist/metafile-cjs.json +1 -1
  26. package/internal/dist/index.cjs +885 -684
  27. package/internal/dist/index.cjs.map +1 -1
  28. package/internal/dist/index.d.cts +230 -24
  29. package/internal/dist/index.js +1 -2171
  30. package/internal/dist/index.js.map +1 -1
  31. package/internal/package.json +5 -5
  32. package/internal/src/atom/create-atom.ts +3 -2
  33. package/internal/src/mutable/create-mutable-atom.ts +3 -2
  34. package/internal/src/mutable/tracker.ts +6 -4
  35. package/internal/src/selector/register-selector.ts +1 -1
  36. package/internal/src/selector/update-selector-atoms.ts +3 -3
  37. package/internal/src/subscribe/index.ts +3 -0
  38. package/internal/src/subscribe/recall-state.ts +0 -6
  39. package/internal/src/subscribe/subscribe-to-state.ts +47 -0
  40. package/internal/src/subscribe/subscribe-to-timeline.ts +28 -0
  41. package/internal/src/subscribe/subscribe-to-transaction.ts +33 -0
  42. package/introspection/dist/index.cjs +1618 -46
  43. package/introspection/dist/index.cjs.map +1 -1
  44. package/introspection/dist/index.d.cts +374 -4
  45. package/introspection/dist/index.js +2 -316
  46. package/introspection/dist/index.js.map +1 -1
  47. package/introspection/package.json +5 -5
  48. package/json/dist/index.cjs +1560 -8
  49. package/json/dist/index.cjs.map +1 -1
  50. package/json/dist/index.d.cts +371 -7
  51. package/json/dist/index.js +1 -76
  52. package/json/dist/index.js.map +1 -1
  53. package/json/package.json +5 -5
  54. package/package.json +10 -9
  55. package/react/dist/index.cjs +1638 -10
  56. package/react/dist/index.cjs.map +1 -1
  57. package/react/dist/index.d.cts +383 -5
  58. package/react/dist/index.js +2 -31
  59. package/react/dist/index.js.map +1 -1
  60. package/react/package.json +5 -5
  61. package/react/src/store-hooks.ts +52 -3
  62. package/react-devtools/dist/index.cjs +2268 -198
  63. package/react-devtools/dist/index.cjs.map +1 -1
  64. package/react-devtools/dist/index.css +2 -2
  65. package/react-devtools/dist/index.d.cts +148 -24
  66. package/react-devtools/dist/index.js +57 -297
  67. package/react-devtools/dist/index.js.map +1 -1
  68. package/react-devtools/package.json +5 -5
  69. package/realtime-client/dist/index.cjs +1585 -34
  70. package/realtime-client/dist/index.cjs.map +1 -1
  71. package/realtime-client/dist/index.d.cts +382 -11
  72. package/realtime-client/dist/index.js +2 -164
  73. package/realtime-client/dist/index.js.map +1 -1
  74. package/realtime-client/package.json +5 -5
  75. package/realtime-client/src/use-push.ts +4 -4
  76. package/realtime-client/src/use-server-action.ts +4 -4
  77. package/realtime-react/dist/index.cjs +1782 -35
  78. package/realtime-react/dist/index.cjs.map +1 -1
  79. package/realtime-react/dist/index.d.cts +49 -9
  80. package/realtime-react/dist/index.js +4 -66
  81. package/realtime-react/dist/index.js.map +1 -1
  82. package/realtime-react/package.json +5 -5
  83. package/realtime-server/dist/index.cjs +1627 -60
  84. package/realtime-server/dist/index.cjs.map +1 -1
  85. package/realtime-server/dist/index.d.cts +391 -11
  86. package/realtime-server/dist/index.js +59 -32
  87. package/realtime-server/dist/index.js.map +1 -1
  88. package/realtime-server/package.json +6 -6
  89. package/realtime-server/src/hook-composition/expose-family.ts +7 -3
  90. package/realtime-server/src/hook-composition/expose-mutable-family.ts +13 -5
  91. package/realtime-server/src/hook-composition/expose-mutable.ts +11 -3
  92. package/realtime-server/src/hook-composition/expose-single.ts +6 -2
  93. package/realtime-server/src/hook-composition/receive-transaction.ts +14 -5
  94. package/realtime-testing/dist/index.cjs +2352 -16
  95. package/realtime-testing/dist/index.cjs.map +1 -1
  96. package/realtime-testing/dist/index.d.cts +486 -3
  97. package/realtime-testing/dist/index.js +10 -31
  98. package/realtime-testing/dist/index.js.map +1 -1
  99. package/realtime-testing/package.json +5 -5
  100. package/src/subscribe.ts +37 -91
  101. package/transceivers/set-rtx/dist/index.cjs +31 -10
  102. package/transceivers/set-rtx/dist/index.cjs.map +1 -1
  103. package/transceivers/set-rtx/dist/index.d.cts +29 -3
  104. package/transceivers/set-rtx/dist/index.js +2 -3
  105. package/transceivers/set-rtx/dist/index.js.map +1 -1
  106. package/transceivers/set-rtx/package.json +6 -6
  107. package/data/dist/index.d.ts +0 -158
  108. package/data/dist/metafile-cjs.json +0 -1
  109. package/data/dist/metafile-esm.json +0 -1
  110. package/dist/index.d.ts +0 -243
  111. package/dist/metafile-esm.json +0 -1
  112. package/internal/dist/index.d.ts +0 -414
  113. package/internal/dist/metafile-cjs.json +0 -1
  114. package/internal/dist/metafile-esm.json +0 -1
  115. package/introspection/dist/index.d.ts +0 -24
  116. package/introspection/dist/metafile-cjs.json +0 -1
  117. package/introspection/dist/metafile-esm.json +0 -1
  118. package/json/dist/index.d.ts +0 -51
  119. package/json/dist/metafile-cjs.json +0 -1
  120. package/json/dist/metafile-esm.json +0 -1
  121. package/react/dist/index.d.ts +0 -16
  122. package/react/dist/metafile-cjs.json +0 -1
  123. package/react/dist/metafile-esm.json +0 -1
  124. package/react-devtools/dist/index.d.ts +0 -341
  125. package/react-devtools/dist/metafile-cjs.json +0 -1
  126. package/react-devtools/dist/metafile-esm.json +0 -1
  127. package/realtime-client/dist/index.d.ts +0 -21
  128. package/realtime-client/dist/metafile-cjs.json +0 -1
  129. package/realtime-client/dist/metafile-esm.json +0 -1
  130. package/realtime-react/dist/index.d.ts +0 -27
  131. package/realtime-react/dist/metafile-cjs.json +0 -1
  132. package/realtime-react/dist/metafile-esm.json +0 -1
  133. package/realtime-server/dist/index.d.ts +0 -25
  134. package/realtime-server/dist/metafile-cjs.json +0 -1
  135. package/realtime-server/dist/metafile-esm.json +0 -1
  136. package/realtime-testing/dist/index.d.ts +0 -49
  137. package/realtime-testing/dist/metafile-cjs.json +0 -1
  138. package/realtime-testing/dist/metafile-esm.json +0 -1
  139. package/transceivers/set-rtx/dist/index.d.ts +0 -40
  140. package/transceivers/set-rtx/dist/metafile-cjs.json +0 -1
  141. package/transceivers/set-rtx/dist/metafile-esm.json +0 -1
@@ -1,2173 +1,3 @@
1
- import { getState, setState, subscribe, subscribeToTimeline, AtomIOLogger, runTransaction } from 'atom.io';
2
- import { selectJson, stringifyJson, parseJson, selectJsonFamily } from 'atom.io/json';
3
-
4
- var __defProp = Object.defineProperty;
5
- var __defProps = Object.defineProperties;
6
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
7
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
- var __spreadValues = (a, b) => {
12
- for (var prop in b || (b = {}))
13
- if (__hasOwnProp.call(b, prop))
14
- __defNormalProp(a, prop, b[prop]);
15
- if (__getOwnPropSymbols)
16
- for (var prop of __getOwnPropSymbols(b)) {
17
- if (__propIsEnum.call(b, prop))
18
- __defNormalProp(a, prop, b[prop]);
19
- }
20
- return a;
21
- };
22
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
23
-
24
- // src/future.ts
25
- var Future = class extends Promise {
26
- constructor(executor) {
27
- super((resolve, reject) => {
28
- const pass = (value) => this.isCanceled ? reject(`canceled`) : resolve(value);
29
- const fail = (reason) => this.isCanceled ? reject(`canceled`) : reject(reason);
30
- if (typeof executor === `function`) {
31
- executor(pass, fail);
32
- } else {
33
- executor.then(pass, fail);
34
- }
35
- });
36
- this.isCanceled = false;
37
- }
38
- cancel() {
39
- this.isCanceled = true;
40
- }
41
- };
42
-
43
- // src/lineage.ts
44
- function newest(scion) {
45
- while (scion.child !== null) {
46
- scion = scion.child;
47
- }
48
- return scion;
49
- }
50
- function eldest(scion) {
51
- while (scion.parent !== null) {
52
- scion = scion.parent;
53
- }
54
- return scion;
55
- }
56
-
57
- // src/caching.ts
58
- function cacheValue(key, value, subject, store) {
59
- const target = newest(store);
60
- const currentValue = target.valueMap.get(key);
61
- if (currentValue instanceof Future) {
62
- currentValue.cancel();
63
- }
64
- if (value instanceof Promise) {
65
- const future = new Future(value);
66
- newest(store).valueMap.set(key, future);
67
- future.then((resolved) => {
68
- if (future.isCanceled) {
69
- return;
70
- }
71
- cacheValue(key, resolved, subject, store);
72
- subject.next({ newValue: resolved, oldValue: future });
73
- }).catch((thrown) => {
74
- if (thrown !== `canceled`) {
75
- store.logger.error(`\u{1F4A5}`, `state`, key, `rejected:`, thrown);
76
- }
77
- });
78
- return future;
79
- }
80
- target.valueMap.set(key, value);
81
- return value;
82
- }
83
- var readCachedValue = (key, store) => {
84
- return newest(store).valueMap.get(key);
85
- };
86
- var isValueCached = (key, store) => {
87
- return newest(store).valueMap.has(key);
88
- };
89
- var evictCachedValue = (key, store) => {
90
- const core = newest(store);
91
- const currentValue = core.valueMap.get(key);
92
- if (currentValue instanceof Future) {
93
- currentValue.cancel();
94
- }
95
- if (core.operation.open) {
96
- core.operation.prev.set(key, currentValue);
97
- }
98
- core.valueMap.delete(key);
99
- store.logger.info(`\u{1F5D1}`, `state`, key, `evicted`);
100
- };
101
- var Tracker = class {
102
- constructor(mutableState, store) {
103
- this.unsubscribeFromInnerValue = null;
104
- this.mutableState = mutableState;
105
- const target = newest(store);
106
- this.latestUpdateState = this.initializeState(mutableState, target);
107
- this.observeCore(mutableState, this.latestUpdateState, target);
108
- this.updateCore(mutableState, this.latestUpdateState, target);
109
- target.trackers.set(mutableState.key, this);
110
- }
111
- initializeState(mutableState, store) {
112
- const latestUpdateStateKey = `*${mutableState.key}`;
113
- deleteAtom({ type: `atom`, key: latestUpdateStateKey }, store);
114
- const familyMetaData = mutableState.family ? {
115
- key: `*${mutableState.family.key}`,
116
- subKey: mutableState.family.subKey
117
- } : void 0;
118
- const latestUpdateState = createAtom(
119
- {
120
- key: latestUpdateStateKey,
121
- default: null
122
- },
123
- familyMetaData,
124
- store
125
- );
126
- return latestUpdateState;
127
- }
128
- observeCore(mutableState, latestUpdateState, store) {
129
- const originalInnerValue = getState(mutableState, store);
130
- const target = newest(store);
131
- this.unsubscribeFromInnerValue = originalInnerValue.subscribe(
132
- `tracker:${store.config.name}:${target.transactionMeta === null ? `main` : target.transactionMeta.update.key}`,
133
- (update) => {
134
- const unsubscribe = store.subject.operationStatus.subscribe(
135
- mutableState.key,
136
- () => {
137
- unsubscribe();
138
- setState(latestUpdateState, update, store);
139
- }
140
- );
141
- }
142
- );
143
- subscribe(
144
- mutableState,
145
- (update) => {
146
- var _a;
147
- if (update.newValue !== update.oldValue) {
148
- (_a = this.unsubscribeFromInnerValue) == null ? void 0 : _a.call(this);
149
- const target2 = newest(store);
150
- this.unsubscribeFromInnerValue = update.newValue.subscribe(
151
- `tracker:${store.config.name}:${target2.transactionMeta === null ? `main` : target2.transactionMeta.update.key}`,
152
- (update2) => {
153
- const unsubscribe = store.subject.operationStatus.subscribe(
154
- mutableState.key,
155
- () => {
156
- unsubscribe();
157
- setState(latestUpdateState, update2, store);
158
- }
159
- );
160
- }
161
- );
162
- }
163
- },
164
- `${store.config.name}: tracker observing inner value`,
165
- store
166
- );
167
- }
168
- updateCore(mutableState, latestUpdateState, store) {
169
- subscribe(
170
- latestUpdateState,
171
- ({ newValue, oldValue }) => {
172
- const timelineId = store.timelineAtoms.getRelatedKey(
173
- latestUpdateState.key
174
- );
175
- if (timelineId) {
176
- const timelineData = store.timelines.get(timelineId);
177
- if (timelineData == null ? void 0 : timelineData.timeTraveling) {
178
- const unsubscribe2 = subscribeToTimeline(
179
- { key: timelineId, type: `timeline` },
180
- (update) => {
181
- unsubscribe2();
182
- setState(
183
- mutableState,
184
- (transceiver) => {
185
- if (update === `redo` && newValue) {
186
- transceiver.do(newValue);
187
- } else if (update === `undo` && oldValue) {
188
- transceiver.undo(oldValue);
189
- }
190
- return transceiver;
191
- },
192
- store
193
- );
194
- }
195
- );
196
- return;
197
- }
198
- }
199
- const unsubscribe = store.subject.operationStatus.subscribe(
200
- latestUpdateState.key,
201
- () => {
202
- unsubscribe();
203
- const mutable = getState(mutableState, store);
204
- const updateNumber = mutable.getUpdateNumber(newValue);
205
- const eventOffset = updateNumber - mutable.cacheUpdateNumber;
206
- if (newValue && eventOffset === 1) {
207
- setState(
208
- mutableState,
209
- (transceiver) => (transceiver.do(newValue), transceiver),
210
- store
211
- );
212
- }
213
- }
214
- );
215
- },
216
- `${store.config.name}: tracker observing latest update`,
217
- store
218
- );
219
- }
220
- };
221
-
222
- // src/mutable/create-mutable-atom.ts
223
- function createMutableAtom(options, store) {
224
- store.logger.info(
225
- `\u{1F527}`,
226
- `atom`,
227
- options.key,
228
- `creating in store "${store.config.name}"`
229
- );
230
- const coreState = createAtom(options, void 0, store);
231
- new Tracker(coreState, store);
232
- const jsonState = selectJson(coreState, options, store);
233
- const target = newest(store);
234
- subscribe(
235
- jsonState,
236
- () => {
237
- const trackerHasBeenInitialized = newest(store).trackers.has(coreState.key);
238
- if (!trackerHasBeenInitialized) {
239
- new Tracker(coreState, store);
240
- }
241
- },
242
- `tracker-initializer:${store == null ? void 0 : store.config.name}:${target.transactionMeta === null ? `main` : `${target.transactionMeta.update.key}`}`
243
- );
244
- return coreState;
245
- }
246
-
247
- // src/store/deposit.ts
248
- function deposit(state) {
249
- const token = {
250
- key: state.key,
251
- type: state.type
252
- };
253
- if (`family` in state) {
254
- token.family = state.family;
255
- }
256
- return token;
257
- }
258
-
259
- // ../../rel8/junction/src/junction.ts
260
- var Junction = class {
261
- constructor(data, config) {
262
- this.relations = /* @__PURE__ */ new Map();
263
- this.contents = /* @__PURE__ */ new Map();
264
- this.makeContentKey = (a, b) => `${a}:${b}`;
265
- var _a, _b, _c, _d;
266
- this.a = data.between[0];
267
- this.b = data.between[1];
268
- this.cardinality = data.cardinality;
269
- if (!(config == null ? void 0 : config.externalStore)) {
270
- this.relations = new Map((_a = data.relations) == null ? void 0 : _a.map(([a, b]) => [a, new Set(b)]));
271
- this.contents = new Map(data.contents);
272
- }
273
- this.isContent = (_b = config == null ? void 0 : config.isContent) != null ? _b : null;
274
- if (config == null ? void 0 : config.makeContentKey) {
275
- this.makeContentKey = config.makeContentKey;
276
- }
277
- if (config == null ? void 0 : config.externalStore) {
278
- const externalStore = config.externalStore;
279
- this.has = (a, b) => externalStore.has(a, b);
280
- this.addRelation = (a, b) => {
281
- externalStore.addRelation(a, b);
282
- };
283
- this.deleteRelation = (a, b) => {
284
- externalStore.deleteRelation(a, b);
285
- };
286
- this.replaceRelationsSafely = (a, bs) => {
287
- externalStore.replaceRelationsSafely(a, bs);
288
- };
289
- this.replaceRelationsUnsafely = (a, bs) => {
290
- externalStore.replaceRelationsUnsafely(a, bs);
291
- };
292
- this.getRelatedKeys = (key) => externalStore.getRelatedKeys(key);
293
- if (externalStore.getContent) {
294
- this.getContentInternal = (contentKey) => {
295
- return externalStore.getContent(contentKey);
296
- };
297
- this.setContent = (contentKey, content) => {
298
- externalStore.setContent(contentKey, content);
299
- };
300
- this.deleteContent = (contentKey) => {
301
- externalStore.deleteContent(contentKey);
302
- };
303
- }
304
- for (const [x, ys] of (_c = data.relations) != null ? _c : []) {
305
- for (const y of ys)
306
- this.addRelation(x, y);
307
- }
308
- for (const [contentKey, content] of (_d = data.contents) != null ? _d : []) {
309
- this.setContent(contentKey, content);
310
- }
311
- }
312
- }
313
- getRelatedKeys(key) {
314
- return this.relations.get(key);
315
- }
316
- addRelation(a, b) {
317
- let aRelations = this.relations.get(a);
318
- let bRelations = this.relations.get(b);
319
- if (aRelations) {
320
- aRelations.add(b);
321
- } else {
322
- aRelations = /* @__PURE__ */ new Set([b]);
323
- this.relations.set(a, aRelations);
324
- }
325
- if (bRelations) {
326
- bRelations.add(a);
327
- } else {
328
- bRelations = /* @__PURE__ */ new Set([a]);
329
- this.relations.set(b, bRelations);
330
- }
331
- }
332
- deleteRelation(a, b) {
333
- const aRelations = this.relations.get(a);
334
- if (aRelations) {
335
- aRelations.delete(b);
336
- if (aRelations.size === 0) {
337
- this.relations.delete(a);
338
- }
339
- const bRelations = this.relations.get(b);
340
- if (bRelations) {
341
- bRelations.delete(a);
342
- if (bRelations.size === 0) {
343
- this.relations.delete(b);
344
- }
345
- }
346
- }
347
- }
348
- replaceRelationsUnsafely(a, bs) {
349
- this.relations.set(a, new Set(bs));
350
- for (const b of bs) {
351
- const bRelations = /* @__PURE__ */ new Set([a]);
352
- this.relations.set(b, bRelations);
353
- }
354
- }
355
- replaceRelationsSafely(a, bs) {
356
- const aRelationsPrev = this.relations.get(a);
357
- if (aRelationsPrev) {
358
- for (const b of aRelationsPrev) {
359
- const bRelations = this.relations.get(b);
360
- if (bRelations) {
361
- if (bRelations.size === 1) {
362
- this.relations.delete(b);
363
- } else {
364
- bRelations.delete(a);
365
- }
366
- this.contents.delete(this.makeContentKey(a, b));
367
- }
368
- }
369
- }
370
- this.relations.set(a, new Set(bs));
371
- for (const b of bs) {
372
- let bRelations = this.relations.get(b);
373
- if (bRelations) {
374
- bRelations.add(a);
375
- } else {
376
- bRelations = /* @__PURE__ */ new Set([a]);
377
- this.relations.set(b, bRelations);
378
- }
379
- }
380
- }
381
- getContentInternal(contentKey) {
382
- return this.contents.get(contentKey);
383
- }
384
- setContent(contentKey, content) {
385
- this.contents.set(contentKey, content);
386
- }
387
- deleteContent(contentKey) {
388
- this.contents.delete(contentKey);
389
- }
390
- toJSON() {
391
- return {
392
- between: [this.a, this.b],
393
- cardinality: this.cardinality,
394
- relations: [...this.relations.entries()].map(([a, b]) => [a, [...b]]),
395
- contents: [...this.contents.entries()]
396
- };
397
- }
398
- set(a, ...rest) {
399
- var _a;
400
- const b = typeof rest[0] === `string` ? rest[0] : a[this.b];
401
- const content = ((_a = rest[1]) != null ? _a : typeof rest[0] === `string`) ? void 0 : rest[0];
402
- a = typeof a === `string` ? a : a[this.a];
403
- switch (this.cardinality) {
404
- case `1:1`: {
405
- const bPrev = this.getRelatedKey(a);
406
- if (bPrev && bPrev !== b)
407
- this.delete(bPrev, a);
408
- }
409
- case `1:n`: {
410
- const aPrev = this.getRelatedKey(b);
411
- if (aPrev && aPrev !== a)
412
- this.delete(aPrev, b);
413
- }
414
- }
415
- if (content) {
416
- const contentKey = this.makeContentKey(a, b);
417
- this.setContent(contentKey, content);
418
- }
419
- this.addRelation(a, b);
420
- return this;
421
- }
422
- delete(x, b) {
423
- b = typeof b === `string` ? b : x[this.b];
424
- const a = typeof x === `string` ? x : x[this.a];
425
- if (a === void 0 && typeof b === `string`) {
426
- const bRelations = this.getRelatedKeys(b);
427
- if (bRelations) {
428
- for (const a2 of bRelations) {
429
- this.delete(a2, b);
430
- }
431
- }
432
- }
433
- if (typeof a === `string` && b === void 0) {
434
- const aRelations = this.getRelatedKeys(a);
435
- if (aRelations) {
436
- for (const b2 of aRelations) {
437
- this.delete(a, b2);
438
- }
439
- }
440
- }
441
- if (typeof a === `string` && typeof b === `string`) {
442
- this.deleteRelation(a, b);
443
- const contentKey = this.makeContentKey(a, b);
444
- this.deleteContent(contentKey);
445
- }
446
- return this;
447
- }
448
- getRelatedKey(key) {
449
- const relations = this.getRelatedKeys(key);
450
- if (relations) {
451
- if (relations.size > 1) {
452
- console.warn(
453
- `${relations.size} related keys were found for key "${key}": (${[
454
- ...relations
455
- ].map((k) => `"${k}"`).join(`, `)}). Only one related key was expected.`
456
- );
457
- }
458
- for (const relation of relations) {
459
- return relation;
460
- }
461
- }
462
- }
463
- replaceRelations(a, relations, config) {
464
- const hasContent = !Array.isArray(relations);
465
- const bs = hasContent ? Object.keys(relations) : relations;
466
- if (config == null ? void 0 : config.reckless) {
467
- this.replaceRelationsUnsafely(a, bs);
468
- } else {
469
- this.replaceRelationsSafely(a, bs);
470
- }
471
- if (hasContent) {
472
- for (const b of bs) {
473
- const contentKey = this.makeContentKey(a, b);
474
- const content = relations[b];
475
- this.setContent(contentKey, content);
476
- }
477
- }
478
- return this;
479
- }
480
- getContent(a, b) {
481
- const contentKey = this.makeContentKey(a, b);
482
- return this.getContentInternal(contentKey);
483
- }
484
- getRelationEntries(input) {
485
- const a = input[this.a];
486
- const b = input[this.b];
487
- if (a !== void 0 && b === void 0) {
488
- const aRelations = this.getRelatedKeys(a);
489
- if (aRelations) {
490
- return [...aRelations].map((b2) => {
491
- var _a;
492
- return [b2, (_a = this.getContent(a, b2)) != null ? _a : null];
493
- });
494
- }
495
- }
496
- if (a === void 0 && b !== void 0) {
497
- const bRelations = this.getRelatedKeys(b);
498
- if (bRelations) {
499
- return [...bRelations].map((a2) => {
500
- var _a;
501
- return [a2, (_a = this.getContent(a2, b)) != null ? _a : null];
502
- });
503
- }
504
- }
505
- return [];
506
- }
507
- has(a, b) {
508
- var _a;
509
- if (b) {
510
- const setA = this.getRelatedKeys(a);
511
- return (_a = setA == null ? void 0 : setA.has(b)) != null ? _a : false;
512
- }
513
- return this.relations.has(a);
514
- }
515
- };
516
-
517
- // src/subject.ts
518
- var Subject = class {
519
- constructor() {
520
- this.subscribers = /* @__PURE__ */ new Map();
521
- }
522
- subscribe(key, subscriber) {
523
- this.subscribers.set(key, subscriber);
524
- const unsubscribe = () => this.unsubscribe(key);
525
- return unsubscribe;
526
- }
527
- unsubscribe(key) {
528
- this.subscribers.delete(key);
529
- }
530
- next(value) {
531
- for (const subscriber of this.subscribers.values()) {
532
- subscriber(value);
533
- }
534
- }
535
- };
536
- var StatefulSubject = class extends Subject {
537
- constructor(initialState) {
538
- super();
539
- this.state = initialState;
540
- }
541
- next(value) {
542
- this.state = value;
543
- super.next(value);
544
- }
545
- };
546
-
547
- // src/store/store.ts
548
- var Store = class {
549
- constructor(name, store = null) {
550
- this.parent = null;
551
- this.child = null;
552
- this.valueMap = /* @__PURE__ */ new Map();
553
- this.atoms = /* @__PURE__ */ new Map();
554
- this.selectors = /* @__PURE__ */ new Map();
555
- this.readonlySelectors = /* @__PURE__ */ new Map();
556
- this.trackers = /* @__PURE__ */ new Map();
557
- this.families = /* @__PURE__ */ new Map();
558
- this.timelines = /* @__PURE__ */ new Map();
559
- this.transactions = /* @__PURE__ */ new Map();
560
- this.atomsThatAreDefault = /* @__PURE__ */ new Set();
561
- this.timelineAtoms = new Junction({
562
- between: [`timelineKey`, `atomKey`],
563
- cardinality: `1:n`
564
- });
565
- this.selectorAtoms = new Junction({
566
- between: [`selectorKey`, `atomKey`],
567
- cardinality: `n:n`
568
- });
569
- this.selectorGraph = new Junction(
570
- {
571
- between: [`upstreamSelectorKey`, `downstreamSelectorKey`],
572
- cardinality: `n:n`
573
- },
574
- {
575
- makeContentKey: (...keys) => keys.sort().join(`:`)
576
- }
577
- );
578
- this.subject = {
579
- atomCreation: new Subject(),
580
- selectorCreation: new Subject(),
581
- transactionCreation: new Subject(),
582
- timelineCreation: new Subject(),
583
- transactionApplying: new StatefulSubject(null),
584
- operationStatus: new Subject()
585
- };
586
- this.operation = { open: false };
587
- this.transactionMeta = null;
588
- this.config = {
589
- name: `IMPLICIT_STORE`
590
- };
591
- this.loggers = [
592
- new AtomIOLogger(`warn`, (_, __, key) => !key.includes(`\u{1F441}\u200D\u{1F5E8}`))
593
- ];
594
- this.logger = {
595
- error: (...messages) => {
596
- for (const logger of this.loggers)
597
- logger.error(...messages);
598
- },
599
- info: (...messages) => {
600
- for (const logger of this.loggers)
601
- logger.info(...messages);
602
- },
603
- warn: (...messages) => {
604
- for (const logger of this.loggers)
605
- logger.warn(...messages);
606
- }
607
- };
608
- if (store !== null) {
609
- this.valueMap = new Map(store == null ? void 0 : store.valueMap);
610
- this.operation = __spreadValues({}, store == null ? void 0 : store.operation);
611
- this.transactionMeta = (store == null ? void 0 : store.transactionMeta) ? __spreadValues({}, store == null ? void 0 : store.transactionMeta) : null;
612
- this.config = __spreadProps(__spreadValues({}, store == null ? void 0 : store.config), {
613
- name
614
- });
615
- for (const [, atom] of store.atoms) {
616
- atom.install(this);
617
- }
618
- for (const [, selector] of store.readonlySelectors) {
619
- selector.install(this);
620
- }
621
- for (const [, selector] of store.selectors) {
622
- selector.install(this);
623
- }
624
- for (const [, tx] of store.transactions) {
625
- tx.install(this);
626
- }
627
- for (const [, timeline] of store.timelines) {
628
- timeline.install(this);
629
- }
630
- }
631
- }
632
- };
633
- var IMPLICIT = {
634
- STORE_INTERNAL: void 0,
635
- get STORE() {
636
- var _a;
637
- return (_a = this.STORE_INTERNAL) != null ? _a : this.STORE_INTERNAL = new Store(`IMPLICIT_STORE`);
638
- }
639
- };
640
- var clearStore = (store) => {
641
- const { config } = store;
642
- Object.assign(store, new Store(config.name));
643
- store.config = config;
644
- };
645
-
646
- // src/store/withdraw.ts
647
- function withdraw(token, store) {
648
- var _a, _b, _c, _d;
649
- const target = newest(store);
650
- const state = (_d = (_c = (_b = (_a = target.atoms.get(token.key)) != null ? _a : target.selectors.get(token.key)) != null ? _b : target.readonlySelectors.get(token.key)) != null ? _c : target.transactions.get(token.key)) != null ? _d : target.timelines.get(token.key);
651
- if (state) {
652
- return state;
653
- }
654
- return void 0;
655
- }
656
-
657
- // src/store/withdraw-new-family-member.ts
658
- function withdrawNewFamilyMember(token, store) {
659
- if (token.family) {
660
- store.logger.info(
661
- `\u{1F46A}`,
662
- token.type,
663
- token.key,
664
- `creating new family member in store "${store.config.name}"`
665
- );
666
- const target = newest(store);
667
- const family = target.families.get(token.family.key);
668
- if (family) {
669
- const jsonSubKey = JSON.parse(token.family.subKey);
670
- family(jsonSubKey);
671
- const state = withdraw(token, store);
672
- return state;
673
- }
674
- }
675
- return void 0;
676
- }
677
-
678
- // src/families/create-atom-family.ts
679
- function createAtomFamily(options, store) {
680
- const subject = new Subject();
681
- const atomFamily = Object.assign(
682
- (key) => {
683
- const subKey = stringifyJson(key);
684
- const family = { key: options.key, subKey };
685
- const fullKey = `${options.key}(${subKey})`;
686
- const existing = withdraw({ key: fullKey, type: `atom` }, store);
687
- let token;
688
- if (existing) {
689
- token = deposit(existing);
690
- } else {
691
- const individualOptions = {
692
- key: fullKey,
693
- default: options.default instanceof Function ? options.default(key) : options.default
694
- };
695
- if (options.effects) {
696
- individualOptions.effects = options.effects(key);
697
- }
698
- token = createAtom(individualOptions, family, store);
699
- subject.next(token);
700
- }
701
- return token;
702
- },
703
- {
704
- key: options.key,
705
- type: `atom_family`,
706
- subject
707
- }
708
- );
709
- const target = newest(store);
710
- target.families.set(options.key, atomFamily);
711
- return atomFamily;
712
- }
713
-
714
- // src/operation.ts
715
- var openOperation = (token, store) => {
716
- const target = newest(store);
717
- if (target.operation.open) {
718
- store.logger.error(
719
- `\u274C`,
720
- token.type,
721
- token.key,
722
- `failed to setState during a setState for "${target.operation.token.key}"`
723
- );
724
- return `rejection`;
725
- }
726
- target.operation = {
727
- open: true,
728
- done: /* @__PURE__ */ new Set(),
729
- prev: /* @__PURE__ */ new Map(),
730
- time: Date.now(),
731
- token
732
- };
733
- store.logger.info(
734
- `\u2B55`,
735
- token.type,
736
- token.key,
737
- `operation start in store "${store.config.name}"${target.transactionMeta === null ? `` : ` ${target.transactionMeta.phase} "${target.transactionMeta.update.key}"`}`
738
- );
739
- };
740
- var closeOperation = (store) => {
741
- const target = newest(store);
742
- if (target.operation.open) {
743
- store.logger.info(
744
- `\u{1F534}`,
745
- target.operation.token.type,
746
- target.operation.token.key,
747
- `operation done in store "${store.config.name}"`
748
- );
749
- }
750
- target.operation = { open: false };
751
- store.subject.operationStatus.next(target.operation);
752
- };
753
- var isDone = (key, store) => {
754
- const target = newest(store);
755
- if (!target.operation.open) {
756
- store.logger.warn(
757
- `\u{1F41E}`,
758
- `unknown`,
759
- key,
760
- `isDone called outside of an operation. This is probably a bug.`
761
- );
762
- return true;
763
- }
764
- return target.operation.done.has(key);
765
- };
766
- var markDone = (key, store) => {
767
- const target = newest(store);
768
- if (!target.operation.open) {
769
- store.logger.warn(
770
- `\u{1F41E}`,
771
- `unknown`,
772
- key,
773
- `markDone called outside of an operation. This is probably a bug.`
774
- );
775
- return;
776
- }
777
- target.operation.done.add(key);
778
- };
779
-
780
- // src/set-state/become.ts
781
- var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(
782
- originalThing instanceof Function ? originalThing() : originalThing
783
- ) : nextVersionOfThing;
784
-
785
- // src/read-or-compute-value.ts
786
- var readOrComputeValue = (state, store) => {
787
- if (isValueCached(state.key, store)) {
788
- store.logger.info(`\u{1F4D6}`, state.type, state.key, `reading cached value`);
789
- return readCachedValue(state.key, store);
790
- }
791
- if (state.type !== `atom`) {
792
- store.logger.info(`\u{1F9EE}`, state.type, state.key, `computing value`);
793
- return state.get();
794
- }
795
- const fallback = state.default instanceof Function ? state.default() : state.default;
796
- store.logger.info(
797
- `\u{1F481}`,
798
- `atom`,
799
- state.key,
800
- `could not find cached value; using default`,
801
- fallback
802
- );
803
- return state.default instanceof Function ? state.default() : state.default;
804
- };
805
-
806
- // src/set-state/copy-mutable-if-needed.ts
807
- function copyMutableIfNeeded(atom, transform, origin, target) {
808
- const originValue = origin.valueMap.get(atom.key);
809
- const targetValue = target.valueMap.get(atom.key);
810
- if (originValue === targetValue) {
811
- origin.logger.info(`\u{1F4C3}`, `atom`, `${atom.key}`, `copying`);
812
- const jsonValue = transform.toJson(originValue);
813
- const copiedValue = transform.fromJson(jsonValue);
814
- target.valueMap.set(atom.key, copiedValue);
815
- new Tracker(atom, origin);
816
- return copiedValue;
817
- }
818
- return targetValue;
819
- }
820
-
821
- // src/set-state/copy-mutable-in-transaction.ts
822
- function copyMutableIfWithinTransaction(oldValue, atom, store) {
823
- const target = newest(store);
824
- const parent = target.parent;
825
- if (parent !== null) {
826
- if (`toJson` in atom && `fromJson` in atom) {
827
- const copiedValue = copyMutableIfNeeded(atom, atom, parent, target);
828
- return copiedValue;
829
- }
830
- if (`family` in atom) {
831
- const family = parent.families.get(atom.family.key);
832
- if (family && family.type === `atom_family`) {
833
- const result = copyMutableFamilyMemberWithinTransaction(
834
- atom,
835
- family,
836
- parent,
837
- target
838
- );
839
- if (result) {
840
- return result;
841
- }
842
- }
843
- }
844
- }
845
- return oldValue;
846
- }
847
- function copyMutableFamilyMemberWithinTransaction(atom, family, origin, target) {
848
- if (`toJson` in family && `fromJson` in family) {
849
- const copyCreated = copyMutableIfNeeded(atom, family, origin, target);
850
- return copyCreated;
851
- }
852
- return null;
853
- }
854
-
855
- // src/set-state/emit-update.ts
856
- var emitUpdate = (state, update, store) => {
857
- store.logger.info(
858
- `\u{1F4E2}`,
859
- state.type,
860
- state.key,
861
- `went (`,
862
- update.oldValue,
863
- `->`,
864
- update.newValue,
865
- `) subscribers:`,
866
- state.subject.subscribers
867
- );
868
- state.subject.next(update);
869
- };
870
-
871
- // src/set-state/evict-downstream.ts
872
- var evictDownStream = (atom, store) => {
873
- const target = newest(store);
874
- const downstreamKeys = target.selectorAtoms.getRelatedKeys(atom.key);
875
- store.logger.info(
876
- `\u{1F9F9}`,
877
- atom.type,
878
- atom.key,
879
- downstreamKeys ? `evicting ${downstreamKeys.size} states downstream:` : `no downstream states`,
880
- downstreamKeys != null ? downstreamKeys : `to evict`
881
- );
882
- if (downstreamKeys) {
883
- if (target.operation.open) {
884
- store.logger.info(
885
- `\u{1F9F9}`,
886
- atom.type,
887
- atom.key,
888
- `[ ${[...target.operation.done].join(`, `)} ] already done`
889
- );
890
- }
891
- for (const key of downstreamKeys) {
892
- if (isDone(key, store)) {
893
- continue;
894
- }
895
- evictCachedValue(key, store);
896
- markDone(key, store);
897
- }
898
- }
899
- };
900
-
901
- // src/set-state/stow-update.ts
902
- function shouldUpdateBeStowed(key, update) {
903
- if (isTransceiver(update.newValue)) {
904
- return false;
905
- }
906
- if (key.includes(`\u{1F441}\u200D\u{1F5E8}`)) {
907
- return false;
908
- }
909
- return true;
910
- }
911
- var stowUpdate = (state, update, store) => {
912
- const { key } = state;
913
- const target = newest(store);
914
- if (target.transactionMeta === null || target.transactionMeta.phase !== `building`) {
915
- store.logger.error(
916
- `\u{1F41E}`,
917
- `atom`,
918
- key,
919
- `stowUpdate called outside of a transaction. This is probably a bug.`
920
- );
921
- return;
922
- }
923
- const shouldStow = shouldUpdateBeStowed(key, update);
924
- if (!shouldStow) {
925
- return;
926
- }
927
- const atomUpdate = __spreadValues({ key }, update);
928
- if (state.family) {
929
- atomUpdate.family = state.family;
930
- }
931
- target.transactionMeta.update.updates.push(atomUpdate);
932
- store.logger.info(
933
- `\u{1F4C1}`,
934
- `atom`,
935
- key,
936
- `stowed (`,
937
- update.oldValue,
938
- `->`,
939
- update.newValue,
940
- `)`
941
- );
942
- };
943
-
944
- // src/set-state/set-atom.ts
945
- var setAtom = (atom, next, store) => {
946
- const target = newest(store);
947
- const oldValue = readOrComputeValue(atom, store);
948
- let newValue = copyMutableIfWithinTransaction(oldValue, atom, store);
949
- newValue = become(next)(newValue);
950
- store.logger.info(`\u{1F4DD}`, `atom`, atom.key, `set to`, newValue);
951
- newValue = cacheValue(atom.key, newValue, atom.subject, store);
952
- if (isAtomDefault(atom.key, store)) {
953
- markAtomAsNotDefault(atom.key, store);
954
- }
955
- markDone(atom.key, store);
956
- evictDownStream(atom, store);
957
- const update = { oldValue, newValue };
958
- if (target.transactionMeta === null || target.transactionMeta.phase === `applying`) {
959
- emitUpdate(atom, update, store);
960
- } else {
961
- stowUpdate(atom, update, store);
962
- }
963
- };
964
-
965
- // src/set-state/set-atom-or-selector.ts
966
- var setAtomOrSelector = (state, value, store) => {
967
- if (state.type === `selector`) {
968
- state.set(value);
969
- } else {
970
- setAtom(state, value, store);
971
- }
972
- };
973
-
974
- // src/keys.ts
975
- var isAtomKey = (key, store) => newest(store).atoms.has(key);
976
- var isSelectorKey = (key, store) => newest(store).selectors.has(key);
977
- var isReadonlySelectorKey = (key, store) => newest(store).readonlySelectors.has(key);
978
- var isStateKey = (key, store) => isAtomKey(key, store) || isSelectorKey(key, store) || isReadonlySelectorKey(key, store);
979
-
980
- // src/selector/get-selector-dependency-keys.ts
981
- var getSelectorDependencyKeys = (key, store) => {
982
- const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(source, store));
983
- return sources;
984
- };
985
-
986
- // src/selector/trace-selector-atoms.ts
987
- var traceSelectorAtoms = (selectorKey, directDependencyKey, store) => {
988
- const rootKeys = [];
989
- const indirectDependencyKeys = getSelectorDependencyKeys(
990
- directDependencyKey,
991
- store
992
- );
993
- let depth = 0;
994
- while (indirectDependencyKeys.length > 0) {
995
- const indirectDependencyKey = indirectDependencyKeys.shift();
996
- ++depth;
997
- if (depth > 99999) {
998
- throw new Error(
999
- `Maximum selector dependency depth exceeded (> 99999) in selector "${selectorKey}". This is likely due to a circular dependency.`
1000
- );
1001
- }
1002
- if (!isAtomKey(indirectDependencyKey, store)) {
1003
- indirectDependencyKeys.push(
1004
- ...getSelectorDependencyKeys(indirectDependencyKey, store)
1005
- );
1006
- } else if (!rootKeys.includes(indirectDependencyKey)) {
1007
- rootKeys.push(indirectDependencyKey);
1008
- }
1009
- }
1010
- return rootKeys;
1011
- };
1012
- var traceAllSelectorAtoms = (selectorKey, store) => {
1013
- const directDependencyKeys = getSelectorDependencyKeys(selectorKey, store);
1014
- return directDependencyKeys.flatMap(
1015
- (depKey) => isAtomKey(depKey, store) ? depKey : traceSelectorAtoms(selectorKey, depKey, store)
1016
- );
1017
- };
1018
-
1019
- // src/selector/update-selector-atoms.ts
1020
- var updateSelectorAtoms = (selectorKey, dependency, store) => {
1021
- const core = newest(store);
1022
- if (dependency.type === `atom`) {
1023
- core.selectorAtoms = core.selectorAtoms.set({
1024
- selectorKey,
1025
- atomKey: dependency.key
1026
- });
1027
- store.logger.info(
1028
- `\u{1F50D}`,
1029
- `selector`,
1030
- selectorKey,
1031
- `discovers root atom "${dependency.key}"`
1032
- );
1033
- } else {
1034
- const rootKeys = traceSelectorAtoms(selectorKey, dependency.key, store);
1035
- store.logger.info(
1036
- `\u{1F50D}`,
1037
- `selector`,
1038
- selectorKey,
1039
- `discovers root atoms: [ ${rootKeys.map((key) => `"${key}"`).join(`, `)} ]`
1040
- );
1041
- for (const atomKey of rootKeys) {
1042
- core.selectorAtoms = core.selectorAtoms.set({
1043
- selectorKey,
1044
- atomKey
1045
- });
1046
- }
1047
- }
1048
- };
1049
-
1050
- // src/selector/register-selector.ts
1051
- var registerSelector = (selectorKey, store) => ({
1052
- get: (dependency) => {
1053
- const target = newest(store);
1054
- const alreadyRegistered = target.selectorGraph.getRelationEntries({ downstreamSelectorKey: selectorKey }).some(([_, { source }]) => source === dependency.key);
1055
- const dependencyState = withdraw(dependency, store);
1056
- if (dependencyState === void 0) {
1057
- throw new Error(
1058
- `State "${dependency.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`
1059
- );
1060
- }
1061
- const dependencyValue = readOrComputeValue(dependencyState, store);
1062
- store.logger.info(
1063
- `\u{1F50C}`,
1064
- `selector`,
1065
- selectorKey,
1066
- `registers dependency ( "${dependency.key}" =`,
1067
- dependencyValue,
1068
- `)`
1069
- );
1070
- if (!alreadyRegistered) {
1071
- target.selectorGraph = target.selectorGraph.set(
1072
- {
1073
- upstreamSelectorKey: dependency.key,
1074
- downstreamSelectorKey: selectorKey
1075
- },
1076
- {
1077
- source: dependency.key
1078
- }
1079
- );
1080
- }
1081
- updateSelectorAtoms(selectorKey, dependency, store);
1082
- return dependencyValue;
1083
- },
1084
- set: (stateToken, newValue) => {
1085
- const state = withdraw(stateToken, store);
1086
- if (state === void 0) {
1087
- throw new Error(
1088
- `State "${stateToken.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`
1089
- );
1090
- }
1091
- setAtomOrSelector(state, newValue, store);
1092
- }
1093
- });
1094
-
1095
- // src/selector/create-read-write-selector.ts
1096
- var createReadWriteSelector = (options, family, store) => {
1097
- const target = newest(store);
1098
- const subject = new Subject();
1099
- const { get, set } = registerSelector(options.key, store);
1100
- const getSelf = () => {
1101
- const value = options.get({ get });
1102
- cacheValue(options.key, value, subject, store);
1103
- return value;
1104
- };
1105
- const setSelf = (next) => {
1106
- const oldValue = getSelf();
1107
- const newValue = become(next)(oldValue);
1108
- store.logger.info(
1109
- `\u{1F4DD}`,
1110
- `selector`,
1111
- options.key,
1112
- `set (`,
1113
- oldValue,
1114
- `->`,
1115
- newValue,
1116
- `)`
1117
- );
1118
- cacheValue(options.key, newValue, subject, store);
1119
- markDone(options.key, store);
1120
- if (target.transactionMeta === null) {
1121
- subject.next({ newValue, oldValue });
1122
- }
1123
- options.set({ get, set }, newValue);
1124
- };
1125
- const mySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
1126
- subject,
1127
- install: (s) => createSelector(options, family, s),
1128
- get: getSelf,
1129
- set: setSelf,
1130
- type: `selector`
1131
- }), family && { family });
1132
- target.selectors.set(options.key, mySelector);
1133
- const initialValue = getSelf();
1134
- store.logger.info(`\u2728`, mySelector.type, mySelector.key, `=`, initialValue);
1135
- const token = {
1136
- key: options.key,
1137
- type: `selector`
1138
- };
1139
- if (family) {
1140
- token.family = family;
1141
- }
1142
- store.subject.selectorCreation.next(token);
1143
- return token;
1144
- };
1145
-
1146
- // src/selector/create-readonly-selector.ts
1147
- var createReadonlySelector = (options, family, store) => {
1148
- const target = newest(store);
1149
- const subject = new Subject();
1150
- const { get } = registerSelector(options.key, store);
1151
- const getSelf = () => {
1152
- const value = options.get({ get });
1153
- cacheValue(options.key, value, subject, store);
1154
- return value;
1155
- };
1156
- const readonlySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
1157
- subject,
1158
- install: (s) => createSelector(options, family, s),
1159
- get: getSelf,
1160
- type: `readonly_selector`
1161
- }), family && { family });
1162
- target.readonlySelectors.set(options.key, readonlySelector);
1163
- const initialValue = getSelf();
1164
- store.logger.info(
1165
- `\u2728`,
1166
- readonlySelector.type,
1167
- readonlySelector.key,
1168
- `=`,
1169
- initialValue
1170
- );
1171
- const token = {
1172
- key: options.key,
1173
- type: `readonly_selector`
1174
- };
1175
- if (family) {
1176
- token.family = family;
1177
- }
1178
- store.subject.selectorCreation.next(token);
1179
- return token;
1180
- };
1181
-
1182
- // src/selector/create-selector.ts
1183
- function createSelector(options, family, store) {
1184
- const target = newest(store);
1185
- const existingWritable = target.selectors.get(options.key);
1186
- const existingReadonly = target.readonlySelectors.get(options.key);
1187
- if (existingWritable || existingReadonly) {
1188
- store.logger.error(
1189
- `\u274C`,
1190
- existingReadonly ? `readonly_selector` : `selector`,
1191
- options.key,
1192
- `Tried to create selector, but it already exists in the store. (Ignore if you are in development using hot module replacement.)`
1193
- );
1194
- }
1195
- if (`set` in options) {
1196
- return createReadWriteSelector(options, family, store);
1197
- }
1198
- return createReadonlySelector(options, family, store);
1199
- }
1200
-
1201
- // src/selector/delete-selector.ts
1202
- function deleteSelector(selectorToken, store) {
1203
- const target = newest(store);
1204
- const { key } = selectorToken;
1205
- switch (selectorToken.type) {
1206
- case `selector`:
1207
- target.selectors.delete(key);
1208
- break;
1209
- case `readonly_selector`:
1210
- target.readonlySelectors.delete(key);
1211
- break;
1212
- }
1213
- target.valueMap.delete(key);
1214
- target.selectorAtoms.delete(key);
1215
- const downstreamTokens = target.selectorGraph.getRelationEntries({ upstreamSelectorKey: key }).filter(([_, { source }]) => source === key).map(
1216
- ([downstreamSelectorKey]) => {
1217
- var _a;
1218
- return (_a = target.selectors.get(downstreamSelectorKey)) != null ? _a : target.readonlySelectors.get(downstreamSelectorKey);
1219
- }
1220
- );
1221
- for (const downstreamToken of downstreamTokens) {
1222
- if (downstreamToken) {
1223
- deleteSelector(downstreamToken, store);
1224
- }
1225
- }
1226
- target.selectorGraph.delete(key);
1227
- store.logger.info(`\u{1F525}`, selectorToken.type, `${key}`, `deleted`);
1228
- }
1229
-
1230
- // src/families/create-readonly-selector-family.ts
1231
- function createReadonlySelectorFamily(options, store) {
1232
- const subject = new Subject();
1233
- return Object.assign(
1234
- (key) => {
1235
- const target = newest(store);
1236
- const subKey = stringifyJson(key);
1237
- const family = { key: options.key, subKey };
1238
- const fullKey = `${options.key}(${subKey})`;
1239
- const existing = target.readonlySelectors.get(fullKey);
1240
- if (existing) {
1241
- return deposit(existing);
1242
- }
1243
- return createSelector(
1244
- {
1245
- key: fullKey,
1246
- get: options.get(key)
1247
- },
1248
- family,
1249
- store
1250
- );
1251
- },
1252
- {
1253
- key: options.key,
1254
- type: `readonly_selector_family`,
1255
- subject
1256
- }
1257
- );
1258
- }
1259
- function createSelectorFamily(options, store) {
1260
- const isReadonly = !(`set` in options);
1261
- if (isReadonly) {
1262
- return createReadonlySelectorFamily(options, store);
1263
- }
1264
- const target = newest(store);
1265
- const subject = new Subject();
1266
- const selectorFamily = Object.assign(
1267
- (key) => {
1268
- const subKey = stringifyJson(key);
1269
- const family = { key: options.key, subKey };
1270
- const fullKey = `${options.key}(${subKey})`;
1271
- const existing = target.selectors.get(fullKey);
1272
- if (existing) {
1273
- return deposit(existing);
1274
- }
1275
- const token = createSelector(
1276
- {
1277
- key: fullKey,
1278
- get: options.get(key),
1279
- set: options.set(key)
1280
- },
1281
- family,
1282
- store
1283
- );
1284
- subject.next(token);
1285
- return token;
1286
- },
1287
- {
1288
- key: options.key,
1289
- type: `selector_family`
1290
- }
1291
- );
1292
- target.families.set(options.key, selectorFamily);
1293
- return selectorFamily;
1294
- }
1295
-
1296
- // src/mutable/tracker-family.ts
1297
- var FamilyTracker = class {
1298
- constructor(findMutableState, store) {
1299
- this.findLatestUpdateState = createAtomFamily(
1300
- {
1301
- key: `*${findMutableState.key}`,
1302
- default: null
1303
- },
1304
- store
1305
- );
1306
- this.findMutableState = findMutableState;
1307
- this.findMutableState.subject.subscribe(
1308
- `store=${store.config.name}::tracker-atom-family`,
1309
- (atomToken) => {
1310
- if (atomToken.family) {
1311
- const key = parseJson(atomToken.family.subKey);
1312
- this.findLatestUpdateState(key);
1313
- new Tracker(atomToken, store);
1314
- }
1315
- }
1316
- );
1317
- this.findLatestUpdateState.subject.subscribe(
1318
- `store=${store.config.name}::tracker-atom-family`,
1319
- (atomToken) => {
1320
- if (atomToken.family) {
1321
- const key = parseJson(atomToken.family.subKey);
1322
- const mutableAtomToken = this.findMutableState(key);
1323
- new Tracker(mutableAtomToken, store);
1324
- }
1325
- }
1326
- );
1327
- }
1328
- };
1329
-
1330
- // src/mutable/create-mutable-atom-family.ts
1331
- function createMutableAtomFamily(options, store) {
1332
- const coreFamily = Object.assign(
1333
- createAtomFamily(options, store),
1334
- options
1335
- );
1336
- selectJsonFamily(coreFamily, options);
1337
- new FamilyTracker(coreFamily, store);
1338
- return coreFamily;
1339
- }
1340
-
1341
- // src/mutable/get-json-family.ts
1342
- var getJsonFamily = (mutableAtomFamily, store) => {
1343
- const target = newest(store);
1344
- const key = `${mutableAtomFamily.key}:JSON`;
1345
- const jsonFamily = target.families.get(
1346
- key
1347
- );
1348
- return jsonFamily;
1349
- };
1350
-
1351
- // src/mutable/get-json-token.ts
1352
- var getJsonToken = (mutableAtomToken) => {
1353
- const key = mutableAtomToken.family ? `${mutableAtomToken.family.key}:JSON(${mutableAtomToken.family.subKey})` : `${mutableAtomToken.key}:JSON`;
1354
- const jsonToken = { type: `selector`, key };
1355
- if (mutableAtomToken.family) {
1356
- jsonToken.family = {
1357
- key: `${mutableAtomToken.family.key}:JSON`,
1358
- subKey: mutableAtomToken.family.subKey
1359
- };
1360
- }
1361
- return jsonToken;
1362
- };
1363
-
1364
- // src/mutable/get-update-token.ts
1365
- var getUpdateToken = (mutableAtomToken) => {
1366
- const key = `*${mutableAtomToken.key}`;
1367
- const updateToken = { type: `atom`, key };
1368
- if (mutableAtomToken.family) {
1369
- updateToken.family = {
1370
- key: `*${mutableAtomToken.family.key}`,
1371
- subKey: mutableAtomToken.family.subKey
1372
- };
1373
- }
1374
- return updateToken;
1375
- };
1376
-
1377
- // src/mutable/is-atom-token-mutable.ts
1378
- function isAtomTokenMutable(token) {
1379
- return token.key.endsWith(`::mutable`);
1380
- }
1381
-
1382
- // src/mutable/transceiver.ts
1383
- function isTransceiver(value) {
1384
- return typeof value === `object` && value !== null && `do` in value && `undo` in value && `subscribe` in value;
1385
- }
1386
-
1387
- // src/mutable/index.ts
1388
- var isAtomMutable = (atom) => `isMutable` in atom;
1389
-
1390
- // src/atom/is-default.ts
1391
- var isAtomDefault = (key, store) => {
1392
- const core = newest(store);
1393
- return core.atomsThatAreDefault.has(key);
1394
- };
1395
- var markAtomAsDefault = (key, store) => {
1396
- const core = newest(store);
1397
- core.atomsThatAreDefault = new Set(core.atomsThatAreDefault).add(key);
1398
- };
1399
- var markAtomAsNotDefault = (key, store) => {
1400
- const core = newest(store);
1401
- core.atomsThatAreDefault = new Set(newest(store).atomsThatAreDefault);
1402
- core.atomsThatAreDefault.delete(key);
1403
- };
1404
- var isSelectorDefault = (key, store) => {
1405
- const rootKeys = traceAllSelectorAtoms(key, store);
1406
- return rootKeys.every((rootKey) => isAtomDefault(rootKey, store));
1407
- };
1408
-
1409
- // src/atom/create-atom.ts
1410
- function createAtom(options, family, store) {
1411
- store.logger.info(
1412
- `\u{1F528}`,
1413
- `atom`,
1414
- options.key,
1415
- `creating in store "${store.config.name}"`
1416
- );
1417
- const target = newest(store);
1418
- const existing = target.atoms.get(options.key);
1419
- if (existing) {
1420
- store.logger.error(
1421
- `\u274C`,
1422
- `atom`,
1423
- options.key,
1424
- `Tried to create atom, but it already exists in the store.`,
1425
- `(Ignore if you are in development using hot module replacement.)`
1426
- );
1427
- return deposit(existing);
1428
- }
1429
- const subject = new Subject();
1430
- const newAtom = __spreadValues(__spreadProps(__spreadValues({}, options), {
1431
- type: `atom`,
1432
- install: (store2) => {
1433
- store2.logger.info(
1434
- `\u{1F6E0}\uFE0F`,
1435
- `atom`,
1436
- options.key,
1437
- `installing in store "${store2.config.name}"`
1438
- );
1439
- return `mutable` in options ? createMutableAtom(options, store2) : createAtom(options, void 0, store2);
1440
- },
1441
- subject
1442
- }), family && { family });
1443
- let initialValue = options.default;
1444
- if (options.default instanceof Function) {
1445
- initialValue = options.default();
1446
- }
1447
- target.atoms.set(newAtom.key, newAtom);
1448
- markAtomAsDefault(options.key, store);
1449
- cacheValue(options.key, initialValue, subject, store);
1450
- const token = deposit(newAtom);
1451
- if (options.effects) {
1452
- let effectIndex = 0;
1453
- const cleanupFunctions = [];
1454
- for (const effect of options.effects) {
1455
- const cleanup = effect({
1456
- setSelf: (next) => setState(token, next, store),
1457
- onSet: (handle) => subscribe(token, handle, `effect[${effectIndex}]`, store)
1458
- });
1459
- if (cleanup) {
1460
- cleanupFunctions.push(cleanup);
1461
- }
1462
- ++effectIndex;
1463
- }
1464
- newAtom.cleanup = () => {
1465
- for (const cleanup of cleanupFunctions) {
1466
- cleanup();
1467
- }
1468
- };
1469
- }
1470
- store.subject.atomCreation.next(token);
1471
- return token;
1472
- }
1473
-
1474
- // src/atom/delete-atom.ts
1475
- function deleteAtom(atomToken, store) {
1476
- var _a, _b;
1477
- const target = newest(store);
1478
- const { key } = atomToken;
1479
- const atom = target.atoms.get(key);
1480
- if (!atom) {
1481
- store.logger.error(
1482
- `\u274C`,
1483
- `atom`,
1484
- `${key}`,
1485
- `Tried to delete atom, but it does not exist in the store.`
1486
- );
1487
- }
1488
- (_a = atom == null ? void 0 : atom.cleanup) == null ? void 0 : _a.call(atom);
1489
- target.atoms.delete(key);
1490
- target.valueMap.delete(key);
1491
- const selectorKeys = target.selectorAtoms.getRelatedKeys(key);
1492
- if (selectorKeys) {
1493
- for (const selectorKey of selectorKeys) {
1494
- const token = (_b = target.selectors.get(selectorKey)) != null ? _b : target.readonlySelectors.get(selectorKey);
1495
- if (token) {
1496
- deleteSelector(token, store);
1497
- }
1498
- }
1499
- }
1500
- target.selectorAtoms.delete(key);
1501
- target.atomsThatAreDefault.delete(key);
1502
- target.timelineAtoms.delete(key);
1503
- store.logger.info(`\u{1F525}`, `atom`, `${key}`, `deleted`);
1504
- }
1505
-
1506
- // src/lazy-map.ts
1507
- var LazyMap = class extends Map {
1508
- constructor(source) {
1509
- super();
1510
- this.source = source;
1511
- this.deleted = /* @__PURE__ */ new Set();
1512
- }
1513
- get(key) {
1514
- const has = super.has(key);
1515
- if (has) {
1516
- return super.get(key);
1517
- }
1518
- if (!this.deleted.has(key) && this.source.has(key)) {
1519
- const value = this.source.get(key);
1520
- return value;
1521
- }
1522
- return void 0;
1523
- }
1524
- set(key, value) {
1525
- this.deleted.delete(key);
1526
- return super.set(key, value);
1527
- }
1528
- hasOwn(key) {
1529
- return super.has(key);
1530
- }
1531
- has(key) {
1532
- return !this.deleted.has(key) && (super.has(key) || this.source.has(key));
1533
- }
1534
- delete(key) {
1535
- this.deleted.add(key);
1536
- return super.delete(key);
1537
- }
1538
- };
1539
-
1540
- // src/not-found-error.ts
1541
- var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
1542
- function prettyPrintTokenType(token) {
1543
- if (token.type === `readonly_selector`) {
1544
- return `Readonly Selector`;
1545
- }
1546
- return capitalize(token.type);
1547
- }
1548
- var NotFoundError = class extends Error {
1549
- constructor(token, store) {
1550
- super(
1551
- `${prettyPrintTokenType(token)} "${token.key}" not found in store "${store.config.name}".`
1552
- );
1553
- }
1554
- };
1555
-
1556
- // src/subscribe/recall-state.ts
1557
- var recallState = (state, store) => {
1558
- const target = newest(store);
1559
- if (!target.operation.open) {
1560
- store.logger.warn(
1561
- `\u{1F41E}`,
1562
- state.type,
1563
- state.key,
1564
- `recall called outside of an operation. This is probably a bug.`
1565
- );
1566
- return target.valueMap.get(state.key);
1567
- }
1568
- return target.operation.prev.get(state.key);
1569
- };
1570
-
1571
- // src/subscribe/subscribe-to-root-atoms.ts
1572
- var subscribeToRootAtoms = (state, store) => {
1573
- const dependencySubscriptions = `default` in state ? null : traceAllSelectorAtoms(state.key, store).map((atomKey) => {
1574
- const atom = store.atoms.get(atomKey);
1575
- if (atom === void 0) {
1576
- throw new Error(
1577
- `Atom "${atomKey}", a dependency of selector "${state.key}", not found in store "${store.config.name}".`
1578
- );
1579
- }
1580
- return atom.subject.subscribe(
1581
- `${state.type}:${state.key}`,
1582
- (atomChange) => {
1583
- store.logger.info(
1584
- `\u{1F4E2}`,
1585
- state.type,
1586
- state.key,
1587
- `root`,
1588
- atomKey,
1589
- `went`,
1590
- atomChange.oldValue,
1591
- `->`,
1592
- atomChange.newValue
1593
- );
1594
- const oldValue = recallState(state, store);
1595
- const newValue = readOrComputeValue(state, store);
1596
- store.logger.info(
1597
- `\u2728`,
1598
- state.type,
1599
- state.key,
1600
- `went`,
1601
- oldValue,
1602
- `->`,
1603
- newValue
1604
- );
1605
- state.subject.next({ newValue, oldValue });
1606
- }
1607
- );
1608
- });
1609
- return dependencySubscriptions;
1610
- };
1611
-
1612
- // src/timeline/add-atom-to-timeline.ts
1613
- var addAtomToTimeline = (atomToken, tl, store) => {
1614
- const atom = withdraw(atomToken, store);
1615
- if (atom === void 0) {
1616
- throw new Error(
1617
- `Cannot subscribe to atom "${atomToken.key}" because it has not been initialized in store "${store.config.name}"`
1618
- );
1619
- }
1620
- atom.subject.subscribe(`timeline`, (update) => {
1621
- var _a, _b, _c, _d, _e, _f;
1622
- const target = newest(store);
1623
- const currentSelectorKey = store.operation.open && store.operation.token.type === `selector` ? store.operation.token.key : null;
1624
- const currentSelectorTime = store.operation.open && store.operation.token.type === `selector` ? store.operation.time : null;
1625
- const currentTransactionKey = (_a = target.subject.transactionApplying.state) == null ? void 0 : _a.update.key;
1626
- const currentTransactionTime = (_b = target.subject.transactionApplying.state) == null ? void 0 : _b.time;
1627
- store.logger.info(
1628
- `\u23F3`,
1629
- `timeline`,
1630
- tl.key,
1631
- `atom`,
1632
- atomToken.key,
1633
- `went`,
1634
- update.oldValue,
1635
- `->`,
1636
- update.newValue,
1637
- currentTransactionKey ? `in transaction "${currentTransactionKey}"` : currentSelectorKey ? `in selector "${currentSelectorKey}"` : ``
1638
- );
1639
- if (tl.timeTraveling === null) {
1640
- if (tl.selectorTime && tl.selectorTime !== currentSelectorTime) {
1641
- const mostRecentUpdate = tl.history.at(-1);
1642
- if (mostRecentUpdate === void 0) {
1643
- throw new Error(
1644
- `Timeline "${tl.key}" has a selectorTime, but no history. This is most likely a bug in AtomIO.`
1645
- );
1646
- }
1647
- }
1648
- if (currentTransactionKey) {
1649
- const currentTransaction = withdraw(
1650
- { key: currentTransactionKey, type: `transaction` },
1651
- store
1652
- );
1653
- if (currentTransaction === void 0) {
1654
- throw new Error(
1655
- `Transaction "${currentTransactionKey}" not found in store "${store.config.name}". This is surprising, because we are in the application phase of "${currentTransactionKey}".`
1656
- );
1657
- }
1658
- if (tl.transactionKey !== currentTransactionKey) {
1659
- if (tl.transactionKey) {
1660
- store.logger.error(
1661
- `\u{1F41E}`,
1662
- `timeline`,
1663
- tl.key,
1664
- `unable to resolve transaction "${tl.transactionKey}. This is probably a bug in AtomIO.`
1665
- );
1666
- }
1667
- tl.transactionKey = currentTransactionKey;
1668
- const unsubscribe = currentTransaction.subject.subscribe(
1669
- `timeline:${tl.key}`,
1670
- (update2) => {
1671
- var _a2, _b2;
1672
- unsubscribe();
1673
- if (tl.timeTraveling === null && currentTransactionTime) {
1674
- if (tl.at !== tl.history.length) {
1675
- tl.history.splice(tl.at);
1676
- }
1677
- const filterUpdates = (updates2) => updates2.filter((updateFromTx) => {
1678
- const target2 = newest(store);
1679
- if (`updates` in updateFromTx) {
1680
- return true;
1681
- }
1682
- const atomOrFamilyKeys = target2.timelineAtoms.getRelatedKeys(tl.key);
1683
- return atomOrFamilyKeys ? [...atomOrFamilyKeys].some(
1684
- (key) => {
1685
- var _a3;
1686
- return key === updateFromTx.key || key === ((_a3 = updateFromTx.family) == null ? void 0 : _a3.key);
1687
- }
1688
- ) : false;
1689
- }).map((updateFromTx) => {
1690
- if (`updates` in updateFromTx) {
1691
- return __spreadProps(__spreadValues({}, updateFromTx), {
1692
- updates: filterUpdates(updateFromTx.updates)
1693
- });
1694
- }
1695
- return updateFromTx;
1696
- });
1697
- const updates = filterUpdates(update2.updates);
1698
- const timelineTransactionUpdate = __spreadProps(__spreadValues({
1699
- type: `transaction_update`,
1700
- timestamp: currentTransactionTime
1701
- }, update2), {
1702
- updates
1703
- });
1704
- const willCapture = (_b2 = (_a2 = tl.shouldCapture) == null ? void 0 : _a2.call(tl, timelineTransactionUpdate, tl)) != null ? _b2 : true;
1705
- if (willCapture) {
1706
- tl.history.push(timelineTransactionUpdate);
1707
- tl.at = tl.history.length;
1708
- tl.subject.next(timelineTransactionUpdate);
1709
- }
1710
- }
1711
- tl.transactionKey = null;
1712
- store.logger.info(
1713
- `\u231B`,
1714
- `timeline`,
1715
- tl.key,
1716
- `got a transaction_update "${update2.key}"`
1717
- );
1718
- }
1719
- );
1720
- }
1721
- } else if (currentSelectorKey && currentSelectorTime) {
1722
- let latestUpdate = tl.history.at(-1);
1723
- if (currentSelectorTime !== tl.selectorTime) {
1724
- latestUpdate = {
1725
- type: `selector_update`,
1726
- timestamp: currentSelectorTime,
1727
- key: currentSelectorKey,
1728
- atomUpdates: []
1729
- };
1730
- latestUpdate.atomUpdates.push(__spreadValues({
1731
- key: atom.key,
1732
- type: `atom_update`
1733
- }, update));
1734
- if (tl.at !== tl.history.length) {
1735
- tl.history.splice(tl.at);
1736
- }
1737
- tl.history.push(latestUpdate);
1738
- store.logger.info(
1739
- `\u231B`,
1740
- `timeline`,
1741
- tl.key,
1742
- `got a selector_update "${currentSelectorKey}" with`,
1743
- latestUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key)
1744
- );
1745
- tl.at = tl.history.length;
1746
- tl.selectorTime = currentSelectorTime;
1747
- } else {
1748
- if ((latestUpdate == null ? void 0 : latestUpdate.type) === `selector_update`) {
1749
- latestUpdate.atomUpdates.push(__spreadValues({
1750
- key: atom.key,
1751
- type: `atom_update`
1752
- }, update));
1753
- store.logger.info(
1754
- `\u231B`,
1755
- `timeline`,
1756
- tl.key,
1757
- `set selector_update "${currentSelectorKey}" to`,
1758
- latestUpdate == null ? void 0 : latestUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key)
1759
- );
1760
- }
1761
- }
1762
- if (latestUpdate) {
1763
- const willCaptureSelectorUpdate = (_d = (_c = tl.shouldCapture) == null ? void 0 : _c.call(tl, latestUpdate, tl)) != null ? _d : true;
1764
- if (willCaptureSelectorUpdate) {
1765
- tl.subject.next(latestUpdate);
1766
- } else {
1767
- tl.history.pop();
1768
- tl.at = tl.history.length;
1769
- }
1770
- }
1771
- } else {
1772
- const timestamp = Date.now();
1773
- tl.selectorTime = null;
1774
- if (tl.at !== tl.history.length) {
1775
- tl.history.splice(tl.at);
1776
- }
1777
- const atomUpdate = {
1778
- type: `atom_update`,
1779
- timestamp,
1780
- key: atom.key,
1781
- oldValue: update.oldValue,
1782
- newValue: update.newValue
1783
- };
1784
- if (atom.family) {
1785
- atomUpdate.family = atom.family;
1786
- }
1787
- const willCapture = (_f = (_e = tl.shouldCapture) == null ? void 0 : _e.call(tl, atomUpdate, tl)) != null ? _f : true;
1788
- store.logger.info(
1789
- `\u231B`,
1790
- `timeline`,
1791
- tl.key,
1792
- `got an atom_update to "${atom.key}"`
1793
- );
1794
- if (willCapture) {
1795
- tl.history.push(atomUpdate);
1796
- tl.at = tl.history.length;
1797
- tl.subject.next(atomUpdate);
1798
- }
1799
- }
1800
- }
1801
- });
1802
- };
1803
-
1804
- // src/timeline/create-timeline.ts
1805
- function createTimeline(options, store, data) {
1806
- var _a, _b;
1807
- const tl = __spreadProps(__spreadValues({
1808
- type: `timeline`,
1809
- key: options.key,
1810
- at: 0,
1811
- timeTraveling: null,
1812
- selectorTime: null,
1813
- transactionKey: null
1814
- }, data), {
1815
- history: (_a = data == null ? void 0 : data.history.map((update) => __spreadValues({}, update))) != null ? _a : [],
1816
- install: (store2) => createTimeline(options, store2, tl),
1817
- subject: new Subject()
1818
- });
1819
- if (options.shouldCapture) {
1820
- tl.shouldCapture = options.shouldCapture;
1821
- }
1822
- const target = newest(store);
1823
- for (const tokenOrFamily of options.atoms) {
1824
- const timelineKey = target.timelineAtoms.getRelatedKey(tokenOrFamily.key);
1825
- if (timelineKey) {
1826
- store.logger.error(
1827
- `\u274C`,
1828
- `timeline`,
1829
- options.key,
1830
- `Failed to add atom "${tokenOrFamily.key}" because it already belongs to timeline "${timelineKey}"`
1831
- );
1832
- continue;
1833
- }
1834
- if (tokenOrFamily.type === `atom_family`) {
1835
- const family = tokenOrFamily;
1836
- family.subject.subscribe(`timeline:${options.key}`, (token2) => {
1837
- addAtomToTimeline(token2, tl, store);
1838
- });
1839
- for (const atom of target.atoms.values()) {
1840
- if (((_b = atom.family) == null ? void 0 : _b.key) === family.key) {
1841
- addAtomToTimeline(atom, tl, store);
1842
- }
1843
- }
1844
- } else {
1845
- const token2 = tokenOrFamily;
1846
- if (`family` in token2 && token2.family) {
1847
- const familyTimelineKey = target.timelineAtoms.getRelatedKey(
1848
- token2.family.key
1849
- );
1850
- if (familyTimelineKey) {
1851
- store.logger.error(
1852
- `\u274C`,
1853
- `timeline`,
1854
- options.key,
1855
- `Failed to add atom "${token2.key}" because its family "${token2.family.key}" already belongs to timeline "${familyTimelineKey}"`
1856
- );
1857
- continue;
1858
- }
1859
- }
1860
- addAtomToTimeline(token2, tl, store);
1861
- }
1862
- target.timelineAtoms = target.timelineAtoms.set({
1863
- atomKey: tokenOrFamily.key,
1864
- timelineKey: options.key
1865
- });
1866
- }
1867
- store.timelines.set(options.key, tl);
1868
- const token = {
1869
- key: options.key,
1870
- type: `timeline`
1871
- };
1872
- store.subject.timelineCreation.next(token);
1873
- return token;
1874
- }
1875
- var timeTravel = (direction, token, store) => {
1876
- const action = direction === `forward` ? `redo` : `undo`;
1877
- store.logger.info(
1878
- direction === `forward` ? `\u23E9` : `\u23EA`,
1879
- `timeline`,
1880
- token.key,
1881
- action
1882
- );
1883
- const timelineData = store.timelines.get(token.key);
1884
- if (!timelineData) {
1885
- store.logger.error(
1886
- `\u{1F41E}`,
1887
- `timeline`,
1888
- token.key,
1889
- `Failed to ${action}. This timeline has not been initialized.`
1890
- );
1891
- return;
1892
- }
1893
- if (direction === `forward` && timelineData.at === timelineData.history.length || direction === `backward` && timelineData.at === 0) {
1894
- store.logger.warn(
1895
- `\u{1F481}`,
1896
- `timeline`,
1897
- token.key,
1898
- `Failed to ${action} at the ${direction === `forward` ? `end` : `beginning`} of timeline "${token.key}". There is nothing to ${action}.`
1899
- );
1900
- return;
1901
- }
1902
- timelineData.timeTraveling = direction === `forward` ? `into_future` : `into_past`;
1903
- if (direction === `backward`) {
1904
- --timelineData.at;
1905
- }
1906
- const update = timelineData.history[timelineData.at];
1907
- const updateValues = (atomUpdate) => {
1908
- const { key, newValue, oldValue } = atomUpdate;
1909
- const value = direction === `forward` ? newValue : oldValue;
1910
- setState({ key, type: `atom` }, value, store);
1911
- };
1912
- const updateValuesFromTransactionUpdate = (transactionUpdate) => {
1913
- const updates = direction === `forward` ? transactionUpdate.updates : [...transactionUpdate.updates].reverse();
1914
- for (const updateFromTransaction of updates) {
1915
- if (`newValue` in updateFromTransaction) {
1916
- updateValues(updateFromTransaction);
1917
- } else {
1918
- updateValuesFromTransactionUpdate(updateFromTransaction);
1919
- }
1920
- }
1921
- };
1922
- switch (update.type) {
1923
- case `atom_update`: {
1924
- updateValues(update);
1925
- break;
1926
- }
1927
- case `selector_update`: {
1928
- const updates = direction === `forward` ? update.atomUpdates : [...update.atomUpdates].reverse();
1929
- for (const atomUpdate of updates) {
1930
- updateValues(atomUpdate);
1931
- }
1932
- break;
1933
- }
1934
- case `transaction_update`: {
1935
- updateValuesFromTransactionUpdate(update);
1936
- break;
1937
- }
1938
- }
1939
- if (direction === `forward`) {
1940
- ++timelineData.at;
1941
- }
1942
- timelineData.subject.next(action);
1943
- timelineData.timeTraveling = null;
1944
- store.logger.info(
1945
- `\u23F9\uFE0F`,
1946
- `timeline`,
1947
- token.key,
1948
- `"${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`
1949
- );
1950
- };
1951
-
1952
- // src/transaction/abort-transaction.ts
1953
- var abortTransaction = (store) => {
1954
- const target = newest(store);
1955
- if (target.transactionMeta === null || target.parent === null) {
1956
- store.logger.warn(
1957
- `\u{1F41E}`,
1958
- `transaction`,
1959
- `???`,
1960
- `abortTransaction called outside of a transaction. This is probably a bug in AtomIO.`
1961
- );
1962
- return;
1963
- }
1964
- store.logger.info(
1965
- `\u{1FA82}`,
1966
- `transaction`,
1967
- target.transactionMeta.update.key,
1968
- `Aborting transaction`
1969
- );
1970
- target.parent.child = null;
1971
- };
1972
- function ingestAtomUpdate(update, parent, child) {
1973
- var _a, _b, _c;
1974
- const { key, newValue } = update;
1975
- const token = { key, type: `atom` };
1976
- if (!parent.valueMap.has(token.key)) {
1977
- if (token.family) {
1978
- const family = parent.families.get(token.family.key);
1979
- if (family) {
1980
- family(token.family.subKey);
1981
- }
1982
- } else {
1983
- const newAtom = child.atoms.get(token.key);
1984
- if (!newAtom) {
1985
- throw new Error(
1986
- `Absurd Error: Atom "${token.key}" not found while copying updates from transaction "${(_a = child.transactionMeta) == null ? void 0 : _a.update.key}" to store "${parent.config.name}"`
1987
- );
1988
- }
1989
- parent.atoms.set(newAtom.key, newAtom);
1990
- parent.valueMap.set(newAtom.key, newAtom.default);
1991
- parent.logger.info(
1992
- `\u{1F528}`,
1993
- `transaction`,
1994
- (_c = (_b = child.transactionMeta) == null ? void 0 : _b.update.key) != null ? _c : `???`,
1995
- `Adding atom "${newAtom.key}"`
1996
- );
1997
- }
1998
- }
1999
- setState(token, newValue, parent);
2000
- }
2001
- function ingestTransactionUpdate(transactionUpdate, parent, child) {
2002
- for (const update of transactionUpdate.updates) {
2003
- if (`newValue` in update) {
2004
- ingestAtomUpdate(update, parent, child);
2005
- } else {
2006
- ingestTransactionUpdate(update, parent, child);
2007
- }
2008
- }
2009
- }
2010
- var applyTransaction = (output, store) => {
2011
- var _a;
2012
- const child = newest(store);
2013
- const { parent } = child;
2014
- if (parent === null || child.transactionMeta === null || ((_a = child.transactionMeta) == null ? void 0 : _a.phase) !== `building`) {
2015
- store.logger.warn(
2016
- `\u{1F41E}`,
2017
- `transaction`,
2018
- `???`,
2019
- `applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`
2020
- );
2021
- return;
2022
- }
2023
- child.transactionMeta.phase = `applying`;
2024
- child.transactionMeta.update.output = output;
2025
- parent.child = null;
2026
- parent.subject.transactionApplying.next(child.transactionMeta);
2027
- const { updates } = child.transactionMeta.update;
2028
- store.logger.info(
2029
- `\u{1F6C4}`,
2030
- `transaction`,
2031
- child.transactionMeta.update.key,
2032
- `Applying transaction with ${updates.length} updates:`,
2033
- updates
2034
- );
2035
- if (parent.transactionMeta === null) {
2036
- ingestTransactionUpdate(child.transactionMeta.update, parent, child);
2037
- const myTransaction = withdraw(
2038
- { key: child.transactionMeta.update.key, type: `transaction` },
2039
- store
2040
- );
2041
- myTransaction == null ? void 0 : myTransaction.subject.next(child.transactionMeta.update);
2042
- store.logger.info(
2043
- `\u{1F6EC}`,
2044
- `transaction`,
2045
- child.transactionMeta.update.key,
2046
- `Finished applying transaction.`
2047
- );
2048
- } else {
2049
- ingestTransactionUpdate(child.transactionMeta.update, parent, child);
2050
- parent.transactionMeta.update.updates.push(child.transactionMeta.update);
2051
- }
2052
- parent.subject.transactionApplying.next(null);
2053
- };
2054
-
2055
- // src/transaction/build-transaction.ts
2056
- var buildTransaction = (key, params, store) => {
2057
- const parent = newest(store);
2058
- parent.child = {
2059
- parent,
2060
- child: null,
2061
- subject: parent.subject,
2062
- loggers: parent.loggers,
2063
- logger: parent.logger,
2064
- config: parent.config,
2065
- transactionMeta: {
2066
- phase: `building`,
2067
- time: Date.now(),
2068
- update: {
2069
- key,
2070
- updates: [],
2071
- params,
2072
- output: void 0
2073
- }
2074
- },
2075
- atoms: new LazyMap(parent.atoms),
2076
- atomsThatAreDefault: new Set(parent.atomsThatAreDefault),
2077
- families: new LazyMap(parent.families),
2078
- operation: { open: false },
2079
- readonlySelectors: new LazyMap(parent.readonlySelectors),
2080
- timelines: new LazyMap(parent.timelines),
2081
- timelineAtoms: new Junction(parent.timelineAtoms.toJSON()),
2082
- trackers: /* @__PURE__ */ new Map(),
2083
- transactions: new LazyMap(parent.transactions),
2084
- selectorAtoms: new Junction(parent.selectorAtoms.toJSON()),
2085
- selectorGraph: new Junction(parent.selectorGraph.toJSON(), {
2086
- makeContentKey: (...keys) => keys.sort().join(`:`)
2087
- }),
2088
- selectors: new LazyMap(parent.selectors),
2089
- valueMap: new LazyMap(parent.valueMap)
2090
- };
2091
- store.logger.info(
2092
- `\u{1F6EB}`,
2093
- `transaction`,
2094
- key,
2095
- `Building transaction with params:`,
2096
- params
2097
- );
2098
- };
2099
- function createTransaction(options, store) {
2100
- const newTransaction = {
2101
- key: options.key,
2102
- type: `transaction`,
2103
- run: (...params) => {
2104
- buildTransaction(options.key, params, store);
2105
- try {
2106
- const output = options.do(
2107
- {
2108
- get: (token2) => getState(token2, store),
2109
- set: (token2, value) => setState(token2, value, store),
2110
- run: (token2) => runTransaction(token2, store)
2111
- },
2112
- ...params
2113
- );
2114
- applyTransaction(output, store);
2115
- return output;
2116
- } catch (thrown) {
2117
- abortTransaction(store);
2118
- store.logger.warn(`\u{1F4A5}`, `transaction`, options.key, `caught:`, thrown);
2119
- throw thrown;
2120
- }
2121
- },
2122
- install: (store2) => createTransaction(options, store2),
2123
- subject: new Subject()
2124
- };
2125
- const target = newest(store);
2126
- target.transactions.set(newTransaction.key, newTransaction);
2127
- const token = deposit(newTransaction);
2128
- store.subject.transactionCreation.next(token);
2129
- return token;
2130
- }
2131
- var redoTransactionUpdate = (transactionUpdate, store) => {
2132
- store.logger.info(`\u23ED\uFE0F`, `transaction`, transactionUpdate.key, `Redo`);
2133
- for (const update of transactionUpdate.updates) {
2134
- if (`newValue` in update) {
2135
- const { key, newValue } = update;
2136
- const token = { key, type: `atom` };
2137
- const state = withdraw(token, store);
2138
- if (state === void 0) {
2139
- throw new Error(
2140
- `State "${token.key}" not found in this store. This is surprising, because we are navigating the history of the store.`
2141
- );
2142
- }
2143
- setState(state, newValue, store);
2144
- } else {
2145
- redoTransactionUpdate(update, store);
2146
- }
2147
- }
2148
- };
2149
- var undoTransactionUpdate = (transactionUpdate, store) => {
2150
- store.logger.info(`\u23EE\uFE0F`, `transaction`, transactionUpdate.key, `Undo`);
2151
- for (const update of transactionUpdate.updates.reverse()) {
2152
- if (`newValue` in update) {
2153
- const { key, newValue } = update;
2154
- const token = { key, type: `atom` };
2155
- const state = withdraw(token, store);
2156
- if (state === void 0) {
2157
- throw new Error(
2158
- `State "${token.key}" not found in this store. This is surprising, because we are navigating the history of the store.`
2159
- );
2160
- }
2161
- setState(state, newValue, store);
2162
- } else {
2163
- undoTransactionUpdate(update, store);
2164
- }
2165
- }
2166
- };
2167
-
2168
- // src/transaction/index.ts
2169
- var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
2170
-
2171
- export { FamilyTracker, Future, IMPLICIT, LazyMap, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, addAtomToTimeline, applyTransaction, become, buildTransaction, cacheValue, clearStore, closeOperation, createAtom, createAtomFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelectorFamily, createSelector, createSelectorFamily, createTimeline, createTransaction, deleteAtom, deleteSelector, deposit, eldest, evictCachedValue, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getUpdateToken, isAtomDefault, isAtomKey, isAtomMutable, isAtomTokenMutable, isDone, isReadonlySelectorKey, isSelectorDefault, isSelectorKey, isStateKey, isTransceiver, isValueCached, markAtomAsDefault, markAtomAsNotDefault, markDone, newest, openOperation, readCachedValue, readOrComputeValue, redoTransactionUpdate, registerSelector, setAtomOrSelector, subscribeToRootAtoms, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, undoTransactionUpdate, updateSelectorAtoms, withdraw, withdrawNewFamilyMember };
1
+ export { FamilyTracker, Future, IMPLICIT, LazyMap, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, addAtomToTimeline, applyTransaction, become, buildTransaction, cacheValue, clearStore, closeOperation, createAtom, createAtomFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelectorFamily, createSelector, createSelectorFamily, createTimeline, createTransaction, deleteAtom, deleteSelector, deposit, eldest, evictCachedValue, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getUpdateToken, isAtomDefault, isAtomKey, isAtomMutable, isAtomTokenMutable, isDone, isReadonlySelectorKey, isSelectorDefault, isSelectorKey, isStateKey, isTransceiver, isValueCached, markAtomAsDefault, markAtomAsNotDefault, markDone, newest, openOperation, readCachedValue, readOrComputeValue, redoTransactionUpdate, registerSelector, setAtomOrSelector, subscribeToRootAtoms, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, undoTransactionUpdate, updateSelectorAtoms, withdraw, withdrawNewFamilyMember } from '../../dist/chunk-TE3ZSTQ6.js';
2172
2
  //# sourceMappingURL=out.js.map
2173
3
  //# sourceMappingURL=index.js.map