atom.io 0.11.0 → 0.12.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 (172) hide show
  1. package/data/dist/index.cjs +614 -0
  2. package/data/dist/index.cjs.map +1 -0
  3. package/data/dist/index.d.cts +158 -0
  4. package/data/dist/index.d.ts +118 -1
  5. package/data/dist/index.js +551 -30
  6. package/data/dist/index.js.map +1 -1
  7. package/data/dist/metafile-cjs.json +1 -0
  8. package/data/dist/metafile-esm.json +1 -0
  9. package/data/package.json +4 -3
  10. package/data/src/index.ts +1 -0
  11. package/data/src/join.ts +450 -0
  12. package/data/src/struct-family.ts +34 -24
  13. package/data/src/struct.ts +6 -8
  14. package/dist/index.cjs +257 -0
  15. package/dist/index.cjs.map +1 -0
  16. package/dist/{index.d.mts → index.d.cts} +10 -11
  17. package/dist/index.d.ts +10 -11
  18. package/dist/index.js +63 -104
  19. package/dist/index.js.map +1 -1
  20. package/dist/metafile-cjs.json +1 -0
  21. package/dist/metafile-esm.json +1 -0
  22. package/internal/dist/{index.mjs → index.cjs} +692 -503
  23. package/internal/dist/index.cjs.map +1 -0
  24. package/internal/dist/{index.d.mts → index.d.cts} +114 -105
  25. package/internal/dist/index.d.ts +114 -105
  26. package/internal/dist/index.js +628 -563
  27. package/internal/dist/index.js.map +1 -1
  28. package/internal/dist/metafile-cjs.json +1 -0
  29. package/internal/dist/metafile-esm.json +1 -0
  30. package/internal/package.json +4 -3
  31. package/internal/src/atom/create-atom.ts +29 -16
  32. package/internal/src/atom/delete-atom.ts +25 -6
  33. package/internal/src/atom/is-default.ts +4 -17
  34. package/internal/src/caching.ts +28 -23
  35. package/internal/src/families/create-atom-family.ts +3 -2
  36. package/internal/src/families/create-readonly-selector-family.ts +1 -1
  37. package/internal/src/families/create-selector-family.ts +4 -4
  38. package/internal/src/index.ts +2 -1
  39. package/internal/src/mutable/create-mutable-atom-family.ts +2 -2
  40. package/internal/src/mutable/create-mutable-atom.ts +1 -2
  41. package/internal/src/mutable/get-json-family.ts +22 -0
  42. package/internal/src/mutable/get-json-token.ts +1 -0
  43. package/internal/src/mutable/index.ts +1 -0
  44. package/internal/src/mutable/tracker-family.ts +1 -2
  45. package/internal/src/mutable/tracker.ts +8 -6
  46. package/internal/src/mutable/transceiver.ts +2 -0
  47. package/internal/src/not-found-error.ts +27 -0
  48. package/internal/src/operation.ts +2 -3
  49. package/internal/src/{get-state-internal.ts → read-or-compute-value.ts} +13 -6
  50. package/internal/src/selector/create-selector.ts +6 -7
  51. package/internal/src/selector/delete-selector.ts +37 -0
  52. package/internal/src/selector/index.ts +2 -1
  53. package/internal/src/selector/register-selector.ts +7 -7
  54. package/internal/src/set-state/copy-mutable-in-transaction.ts +3 -2
  55. package/internal/src/set-state/emit-update.ts +1 -3
  56. package/internal/src/set-state/evict-downstream.ts +6 -8
  57. package/internal/src/set-state/index.ts +1 -1
  58. package/internal/src/set-state/{set-state-internal.ts → set-atom-or-selector.ts} +2 -3
  59. package/internal/src/set-state/set-atom.ts +5 -6
  60. package/internal/src/store/store.ts +1 -1
  61. package/internal/src/store/withdraw-new-family-member.ts +6 -6
  62. package/internal/src/subscribe/recall-state.ts +1 -2
  63. package/internal/src/subscribe/subscribe-to-root-atoms.ts +2 -2
  64. package/internal/src/timeline/add-atom-to-timeline.ts +5 -16
  65. package/internal/src/timeline/{timeline-internal.ts → create-timeline.ts} +4 -5
  66. package/internal/src/timeline/index.ts +2 -2
  67. package/internal/src/timeline/time-travel.ts +89 -0
  68. package/internal/src/transaction/{transaction-internal.ts → create-transaction.ts} +6 -5
  69. package/internal/src/transaction/index.ts +2 -3
  70. package/introspection/dist/{index.mjs → index.cjs} +54 -29
  71. package/introspection/dist/index.cjs.map +1 -0
  72. package/introspection/dist/{index.d.mts → index.d.cts} +2 -2
  73. package/introspection/dist/index.d.ts +2 -2
  74. package/introspection/dist/index.js +32 -49
  75. package/introspection/dist/index.js.map +1 -1
  76. package/introspection/dist/metafile-cjs.json +1 -0
  77. package/introspection/dist/metafile-esm.json +1 -0
  78. package/introspection/package.json +4 -3
  79. package/introspection/src/attach-introspection-states.ts +2 -2
  80. package/introspection/src/attach-selector-index.ts +8 -4
  81. package/json/dist/{index.mjs → index.cjs} +20 -7
  82. package/json/dist/{index.mjs.map → index.cjs.map} +1 -1
  83. package/json/dist/{index.d.mts → index.d.cts} +1 -1
  84. package/json/dist/index.d.ts +1 -1
  85. package/json/dist/index.js +6 -19
  86. package/json/dist/index.js.map +1 -1
  87. package/json/dist/metafile-cjs.json +1 -0
  88. package/json/dist/metafile-esm.json +1 -0
  89. package/json/package.json +4 -3
  90. package/package.json +48 -47
  91. package/react/dist/index.cjs +59 -0
  92. package/react/dist/index.cjs.map +1 -0
  93. package/react/dist/index.js +20 -42
  94. package/react/dist/index.js.map +1 -1
  95. package/react/dist/metafile-cjs.json +1 -0
  96. package/react/dist/metafile-esm.json +1 -0
  97. package/react/package.json +4 -3
  98. package/react/src/store-hooks.ts +8 -2
  99. package/react-devtools/dist/{index.mjs → index.cjs} +286 -240
  100. package/react-devtools/dist/index.cjs.map +1 -0
  101. package/react-devtools/dist/{index.d.mts → index.d.cts} +29 -17
  102. package/react-devtools/dist/index.d.ts +29 -17
  103. package/react-devtools/dist/index.js +251 -273
  104. package/react-devtools/dist/index.js.map +1 -1
  105. package/react-devtools/dist/metafile-cjs.json +1 -0
  106. package/react-devtools/dist/metafile-esm.json +1 -0
  107. package/react-devtools/package.json +4 -3
  108. package/react-devtools/src/StateEditor.tsx +8 -8
  109. package/realtime-client/dist/{index.mjs → index.cjs} +50 -21
  110. package/realtime-client/dist/index.js +20 -49
  111. package/realtime-client/dist/metafile-cjs.json +1 -0
  112. package/realtime-client/dist/metafile-esm.json +1 -0
  113. package/realtime-client/package.json +4 -3
  114. package/realtime-react/dist/index.cjs +99 -0
  115. package/realtime-react/dist/index.js +35 -66
  116. package/realtime-react/dist/metafile-cjs.json +1 -0
  117. package/realtime-react/dist/metafile-esm.json +1 -0
  118. package/realtime-react/package.json +4 -3
  119. package/realtime-server/dist/{index.mjs → index.cjs} +67 -40
  120. package/realtime-server/dist/index.js +39 -66
  121. package/realtime-server/dist/metafile-cjs.json +1 -0
  122. package/realtime-server/dist/metafile-esm.json +1 -0
  123. package/realtime-server/package.json +4 -3
  124. package/realtime-testing/dist/{index.mjs → index.cjs} +54 -23
  125. package/realtime-testing/dist/index.js +22 -53
  126. package/realtime-testing/dist/metafile-cjs.json +1 -0
  127. package/realtime-testing/dist/metafile-esm.json +1 -0
  128. package/realtime-testing/package.json +4 -3
  129. package/src/atom.ts +6 -8
  130. package/src/dispose.ts +18 -0
  131. package/src/get-state.ts +16 -0
  132. package/src/index.ts +3 -1
  133. package/src/logger.ts +1 -1
  134. package/src/selector.ts +3 -3
  135. package/src/set-state.ts +22 -0
  136. package/src/silo.ts +7 -8
  137. package/src/timeline.ts +6 -11
  138. package/src/transaction.ts +2 -2
  139. package/transceivers/set-rtx/dist/{index.mjs → index.cjs} +40 -36
  140. package/transceivers/set-rtx/dist/index.cjs.map +1 -0
  141. package/transceivers/set-rtx/dist/{index.d.mts → index.d.cts} +2 -1
  142. package/transceivers/set-rtx/dist/index.d.ts +2 -1
  143. package/transceivers/set-rtx/dist/index.js +37 -37
  144. package/transceivers/set-rtx/dist/index.js.map +1 -1
  145. package/transceivers/set-rtx/dist/metafile-cjs.json +1 -0
  146. package/transceivers/set-rtx/dist/metafile-esm.json +1 -0
  147. package/transceivers/set-rtx/package.json +4 -3
  148. package/transceivers/set-rtx/src/set-rtx.ts +29 -26
  149. package/data/dist/index.d.mts +0 -41
  150. package/data/dist/index.mjs +0 -82
  151. package/data/dist/index.mjs.map +0 -1
  152. package/dist/index.mjs +0 -215
  153. package/dist/index.mjs.map +0 -1
  154. package/internal/dist/index.mjs.map +0 -1
  155. package/internal/src/set-state/set-selector-state.ts +0 -8
  156. package/internal/src/timeline/time-travel-internal.ts +0 -109
  157. package/introspection/dist/index.mjs.map +0 -1
  158. package/react/dist/index.mjs +0 -29
  159. package/react/dist/index.mjs.map +0 -1
  160. package/react-devtools/dist/index.mjs.map +0 -1
  161. package/realtime-react/dist/index.mjs +0 -68
  162. package/src/get-set.ts +0 -48
  163. package/transceivers/set-rtx/dist/index.mjs.map +0 -1
  164. /package/react/dist/{index.d.mts → index.d.cts} +0 -0
  165. /package/realtime-client/dist/{index.mjs.map → index.cjs.map} +0 -0
  166. /package/realtime-client/dist/{index.d.mts → index.d.cts} +0 -0
  167. /package/realtime-react/dist/{index.mjs.map → index.cjs.map} +0 -0
  168. /package/realtime-react/dist/{index.d.mts → index.d.cts} +0 -0
  169. /package/realtime-server/dist/{index.mjs.map → index.cjs.map} +0 -0
  170. /package/realtime-server/dist/{index.d.mts → index.d.cts} +0 -0
  171. /package/realtime-testing/dist/{index.mjs.map → index.cjs.map} +0 -0
  172. /package/realtime-testing/dist/{index.d.mts → index.d.cts} +0 -0
@@ -1,7 +1,5 @@
1
- 'use strict';
2
-
3
- var atom_io = require('atom.io');
4
- var json = require('atom.io/json');
1
+ import { AtomIOLogger, setState, getState, subscribe, subscribeToTimeline } from 'atom.io';
2
+ import { selectJson, stringifyJson, parseJson, selectJsonFamily } from 'atom.io/json';
5
3
 
6
4
  var __defProp = Object.defineProperty;
7
5
  var __defProps = Object.defineProperties;
@@ -42,6 +40,26 @@ var Future = class extends Promise {
42
40
  }
43
41
  };
44
42
 
43
+ // src/transaction/abort-transaction.ts
44
+ var abortTransaction = (store) => {
45
+ if (store.transactionStatus.phase === `idle`) {
46
+ store.logger.warn(
47
+ `\u{1F41E}`,
48
+ `transaction`,
49
+ `???`,
50
+ `abortTransaction called outside of a transaction. This is probably a bug in AtomIO.`
51
+ );
52
+ return;
53
+ }
54
+ store.logger.info(
55
+ `\u{1FA82}`,
56
+ `transaction`,
57
+ store.transactionStatus.key,
58
+ `Aborting transaction`
59
+ );
60
+ store.transactionStatus = { phase: `idle` };
61
+ };
62
+
45
63
  // src/store/deposit.ts
46
64
  function deposit(state) {
47
65
  const token = {
@@ -60,12 +78,14 @@ var Junction = class {
60
78
  this.relations = /* @__PURE__ */ new Map();
61
79
  this.contents = /* @__PURE__ */ new Map();
62
80
  this.makeContentKey = (a, b) => `${a}:${b}`;
63
- var _a, _b;
81
+ var _a, _b, _c, _d;
64
82
  this.a = data.between[0];
65
83
  this.b = data.between[1];
66
84
  this.cardinality = data.cardinality;
67
- this.relations = new Map((_a = data.relations) == null ? void 0 : _a.map(([a, b]) => [a, new Set(b)]));
68
- this.contents = new Map(data.contents);
85
+ if (!(config == null ? void 0 : config.externalStore)) {
86
+ this.relations = new Map((_a = data.relations) == null ? void 0 : _a.map(([a, b]) => [a, new Set(b)]));
87
+ this.contents = new Map(data.contents);
88
+ }
69
89
  this.isContent = (_b = config == null ? void 0 : config.isContent) != null ? _b : null;
70
90
  if (config == null ? void 0 : config.makeContentKey) {
71
91
  this.makeContentKey = config.makeContentKey;
@@ -75,11 +95,15 @@ var Junction = class {
75
95
  this.has = (a, b) => externalStore.has(a, b);
76
96
  this.addRelation = (a, b) => {
77
97
  externalStore.addRelation(a, b);
78
- return this;
79
98
  };
80
99
  this.deleteRelation = (a, b) => {
81
100
  externalStore.deleteRelation(a, b);
82
- return this;
101
+ };
102
+ this.replaceRelationsSafely = (a, bs) => {
103
+ externalStore.replaceRelationsSafely(a, bs);
104
+ };
105
+ this.replaceRelationsUnsafely = (a, bs) => {
106
+ externalStore.replaceRelationsUnsafely(a, bs);
83
107
  };
84
108
  this.getRelatedKeys = (key) => externalStore.getRelatedKeys(key);
85
109
  if (externalStore.getContent) {
@@ -88,30 +112,37 @@ var Junction = class {
88
112
  };
89
113
  this.setContent = (contentKey, content) => {
90
114
  externalStore.setContent(contentKey, content);
91
- return this;
92
115
  };
93
116
  this.deleteContent = (contentKey) => {
94
117
  externalStore.deleteContent(contentKey);
95
- return this;
96
118
  };
97
119
  }
120
+ for (const [x, ys] of (_c = data.relations) != null ? _c : []) {
121
+ for (const y of ys)
122
+ this.addRelation(x, y);
123
+ }
124
+ for (const [contentKey, content] of (_d = data.contents) != null ? _d : []) {
125
+ this.setContent(contentKey, content);
126
+ }
98
127
  }
99
128
  }
100
129
  getRelatedKeys(key) {
101
130
  return this.relations.get(key);
102
131
  }
103
132
  addRelation(a, b) {
104
- const aRelations = this.relations.get(a);
105
- const bRelations = this.relations.get(b);
133
+ let aRelations = this.relations.get(a);
134
+ let bRelations = this.relations.get(b);
106
135
  if (aRelations) {
107
136
  aRelations.add(b);
108
137
  } else {
109
- this.relations.set(a, /* @__PURE__ */ new Set([b]));
138
+ aRelations = /* @__PURE__ */ new Set([b]);
139
+ this.relations.set(a, aRelations);
110
140
  }
111
141
  if (bRelations) {
112
142
  bRelations.add(a);
113
143
  } else {
114
- this.relations.set(b, /* @__PURE__ */ new Set([a]));
144
+ bRelations = /* @__PURE__ */ new Set([a]);
145
+ this.relations.set(b, bRelations);
115
146
  }
116
147
  }
117
148
  deleteRelation(a, b) {
@@ -130,6 +161,39 @@ var Junction = class {
130
161
  }
131
162
  }
132
163
  }
164
+ replaceRelationsUnsafely(a, bs) {
165
+ this.relations.set(a, new Set(bs));
166
+ for (const b of bs) {
167
+ const bRelations = /* @__PURE__ */ new Set([a]);
168
+ this.relations.set(b, bRelations);
169
+ }
170
+ }
171
+ replaceRelationsSafely(a, bs) {
172
+ const aRelationsPrev = this.relations.get(a);
173
+ if (aRelationsPrev) {
174
+ for (const b of aRelationsPrev) {
175
+ const bRelations = this.relations.get(b);
176
+ if (bRelations) {
177
+ if (bRelations.size === 1) {
178
+ this.relations.delete(b);
179
+ } else {
180
+ bRelations.delete(a);
181
+ }
182
+ this.contents.delete(this.makeContentKey(a, b));
183
+ }
184
+ }
185
+ }
186
+ this.relations.set(a, new Set(bs));
187
+ for (const b of bs) {
188
+ let bRelations = this.relations.get(b);
189
+ if (bRelations) {
190
+ bRelations.add(a);
191
+ } else {
192
+ bRelations = /* @__PURE__ */ new Set([a]);
193
+ this.relations.set(b, bRelations);
194
+ }
195
+ }
196
+ }
133
197
  getContentInternal(contentKey) {
134
198
  return this.contents.get(contentKey);
135
199
  }
@@ -149,10 +213,7 @@ var Junction = class {
149
213
  }
150
214
  set(a, ...rest) {
151
215
  var _a;
152
- const b = (
153
- // @ts-expect-error we deduce hereby that this.b may index a
154
- typeof rest[0] === `string` ? rest[0] : a[this.b]
155
- );
216
+ const b = typeof rest[0] === `string` ? rest[0] : a[this.b];
156
217
  const content = ((_a = rest[1]) != null ? _a : typeof rest[0] === `string`) ? void 0 : rest[0];
157
218
  a = typeof a === `string` ? a : a[this.a];
158
219
  switch (this.cardinality) {
@@ -167,11 +228,11 @@ var Junction = class {
167
228
  this.delete(aPrev, b);
168
229
  }
169
230
  }
170
- this.addRelation(a, b);
171
231
  if (content) {
172
232
  const contentKey = this.makeContentKey(a, b);
173
233
  this.setContent(contentKey, content);
174
234
  }
235
+ this.addRelation(a, b);
175
236
  return this;
176
237
  }
177
238
  delete(x, b) {
@@ -215,6 +276,23 @@ var Junction = class {
215
276
  }
216
277
  }
217
278
  }
279
+ replaceRelations(a, relations, config) {
280
+ const hasContent = !Array.isArray(relations);
281
+ const bs = hasContent ? Object.keys(relations) : relations;
282
+ if (config == null ? void 0 : config.reckless) {
283
+ this.replaceRelationsUnsafely(a, bs);
284
+ } else {
285
+ this.replaceRelationsSafely(a, bs);
286
+ }
287
+ if (hasContent) {
288
+ for (const b of bs) {
289
+ const contentKey = this.makeContentKey(a, b);
290
+ const content = relations[b];
291
+ this.setContent(contentKey, content);
292
+ }
293
+ }
294
+ return this;
295
+ }
218
296
  getContent(a, b) {
219
297
  const contentKey = this.makeContentKey(a, b);
220
298
  return this.getContentInternal(contentKey);
@@ -314,7 +392,7 @@ var Store = class {
314
392
  name: `IMPLICIT_STORE`
315
393
  };
316
394
  this.loggers = [
317
- new atom_io.AtomIOLogger(`warn`, (_, __, key) => !key.includes(`\u{1F441}\u200D\u{1F5E8}`))
395
+ new AtomIOLogger(`warn`, (_, __, key) => !key.includes(`\u{1F441}\u200D\u{1F5E8}`))
318
396
  ];
319
397
  this.logger = {
320
398
  error: (...messages) => {
@@ -362,209 +440,14 @@ var IMPLICIT = {
362
440
  return (_a = this.STORE_INTERNAL) != null ? _a : this.STORE_INTERNAL = new Store(`IMPLICIT_STORE`);
363
441
  }
364
442
  };
365
- var clearStore = (store = IMPLICIT.STORE) => {
443
+ var clearStore = (store) => {
366
444
  const { config } = store;
367
445
  Object.assign(store, new Store(config.name));
368
446
  store.config = config;
369
447
  };
370
448
 
371
- // src/transaction/abort-transaction.ts
372
- var abortTransaction = (store) => {
373
- if (store.transactionStatus.phase === `idle`) {
374
- store.logger.warn(
375
- `\u{1F41E}`,
376
- `transaction`,
377
- `???`,
378
- `abortTransaction called outside of a transaction. This is probably a bug in AtomIO.`
379
- );
380
- return;
381
- }
382
- store.logger.info(
383
- `\u{1FA82}`,
384
- `transaction`,
385
- store.transactionStatus.key,
386
- `Aborting transaction`
387
- );
388
- store.transactionStatus = { phase: `idle` };
389
- };
390
- var applyTransaction = (output, store) => {
391
- if (store.transactionStatus.phase !== `building`) {
392
- store.logger.warn(
393
- `\u{1F41E}`,
394
- `transaction`,
395
- `???`,
396
- `applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`
397
- );
398
- return;
399
- }
400
- store.transactionStatus.phase = `applying`;
401
- store.transactionStatus.output = output;
402
- const { atomUpdates } = store.transactionStatus;
403
- store.logger.info(
404
- `\u{1F6C4}`,
405
- `transaction`,
406
- store.transactionStatus.key,
407
- `Applying transaction with ${atomUpdates.length} updates:`,
408
- atomUpdates
409
- );
410
- for (const { key, newValue } of atomUpdates) {
411
- const token = { key, type: `atom` };
412
- if (!store.valueMap.has(token.key)) {
413
- if (token.family) {
414
- const family = store.families.get(token.family.key);
415
- if (family) {
416
- family(token.family.subKey);
417
- }
418
- } else {
419
- const newAtom = store.transactionStatus.core.atoms.get(token.key);
420
- if (!newAtom) {
421
- throw new Error(
422
- `Absurd Error: Atom "${token.key}" not found while copying updates from transaction "${store.transactionStatus.key}" to store "${store.config.name}"`
423
- );
424
- }
425
- store.atoms.set(newAtom.key, newAtom);
426
- store.valueMap.set(newAtom.key, newAtom.default);
427
- store.logger.info(
428
- `\u{1F528}`,
429
- `transaction`,
430
- store.transactionStatus.key,
431
- `Adding atom "${newAtom.key}"`
432
- );
433
- }
434
- }
435
- atom_io.setState(token, newValue, store);
436
- }
437
- const myTransaction = withdraw(
438
- { key: store.transactionStatus.key, type: `transaction` },
439
- store
440
- );
441
- if (myTransaction === void 0) {
442
- throw new Error(
443
- `Transaction "${store.transactionStatus.key}" not found. Absurd. How is this running?`
444
- );
445
- }
446
- myTransaction.subject.next({
447
- key: store.transactionStatus.key,
448
- atomUpdates,
449
- output,
450
- params: store.transactionStatus.params
451
- });
452
- store.logger.info(
453
- `\u{1F6EC}`,
454
- `transaction`,
455
- store.transactionStatus.key,
456
- `Finished applying transaction.`
457
- );
458
- store.transactionStatus = { phase: `idle` };
459
- };
460
-
461
- // src/transaction/build-transaction.ts
462
- var buildTransaction = (key, params, store) => {
463
- store.transactionStatus = {
464
- key,
465
- phase: `building`,
466
- time: Date.now(),
467
- core: {
468
- atoms: new Map(store.atoms),
469
- atomsThatAreDefault: new Set(store.atomsThatAreDefault),
470
- families: new Map(store.families),
471
- operation: { open: false },
472
- readonlySelectors: new Map(store.readonlySelectors),
473
- timelines: new Map(store.timelines),
474
- timelineAtoms: new Junction(store.timelineAtoms.toJSON()),
475
- trackers: /* @__PURE__ */ new Map(),
476
- transactions: new Map(store.transactions),
477
- selectorAtoms: new Junction(store.selectorAtoms.toJSON()),
478
- selectorGraph: new Junction(store.selectorGraph.toJSON(), {
479
- makeContentKey: (...keys) => keys.sort().join(`:`)
480
- }),
481
- selectors: new Map(store.selectors),
482
- valueMap: new Map(store.valueMap)
483
- },
484
- atomUpdates: [],
485
- params,
486
- output: void 0
487
- };
488
- store.logger.info(
489
- `\u{1F6EB}`,
490
- `transaction`,
491
- key,
492
- `Building transaction with params:`,
493
- params
494
- );
495
- };
496
-
497
- // src/transaction/transaction-internal.ts
498
- function transaction__INTERNAL(options, store = IMPLICIT.STORE) {
499
- const newTransaction = {
500
- key: options.key,
501
- type: `transaction`,
502
- run: (...params) => {
503
- buildTransaction(options.key, params, store);
504
- try {
505
- const output = options.do(
506
- {
507
- get: (token2) => atom_io.getState(token2, store),
508
- set: (token2, value) => atom_io.setState(token2, value, store)
509
- },
510
- ...params
511
- );
512
- applyTransaction(output, store);
513
- return output;
514
- } catch (thrown) {
515
- abortTransaction(store);
516
- store.logger.warn(`\u{1F4A5}`, `transaction`, options.key, `caught:`, thrown);
517
- throw thrown;
518
- }
519
- },
520
- install: (store2) => transaction__INTERNAL(options, store2),
521
- subject: new Subject()
522
- };
523
- const core = target(store);
524
- core.transactions.set(newTransaction.key, newTransaction);
525
- const token = deposit(newTransaction);
526
- store.subject.transactionCreation.next(token);
527
- return token;
528
- }
529
- var target = (store = IMPLICIT.STORE) => store.transactionStatus.phase === `building` ? store.transactionStatus.core : store;
530
- var redoTransactionUpdate = (update, store) => {
531
- store.logger.info(`\u23ED\uFE0F`, `transaction`, update.key, `Redo`);
532
- for (const { key, newValue } of update.atomUpdates) {
533
- const token = { key, type: `atom` };
534
- const state = withdraw(token, store);
535
- if (state === void 0) {
536
- throw new Error(
537
- `State "${token.key}" not found in this store. This is surprising, because we are navigating the history of the store.`
538
- );
539
- }
540
- atom_io.setState(state, newValue, store);
541
- }
542
- };
543
- var undoTransactionUpdate = (update, store) => {
544
- store.logger.info(
545
- `\u23EE\uFE0F`,
546
- `transaction`,
547
- update.key,
548
- `Undoing transaction update`,
549
- update
550
- );
551
- for (const { key, oldValue } of update.atomUpdates) {
552
- const token = { key, type: `atom` };
553
- const state = withdraw(token, store);
554
- if (state === void 0) {
555
- throw new Error(
556
- `State "${token.key}" not found in this store. This is surprising, because we are navigating the history of the store.`
557
- );
558
- }
559
- atom_io.setState(state, oldValue, store);
560
- }
561
- };
562
-
563
- // src/transaction/index.ts
564
- var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
565
-
566
449
  // src/timeline/add-atom-to-timeline.ts
567
- var addAtomToTimeline = (atomToken, tl, store = IMPLICIT.STORE) => {
450
+ var addAtomToTimeline = (atomToken, tl, store) => {
568
451
  const atom = withdraw(atomToken, store);
569
452
  if (atom === void 0) {
570
453
  throw new Error(
@@ -744,94 +627,133 @@ var addAtomToTimeline = (atomToken, tl, store = IMPLICIT.STORE) => {
744
627
  }
745
628
  });
746
629
  };
747
- var redo__INTERNAL = (token, store = IMPLICIT.STORE) => {
748
- store.logger.info(`\u23E9`, `timeline`, token.key, `redo`);
749
- const timelineData = store.timelines.get(token.key);
750
- if (!timelineData) {
751
- store.logger.error(
752
- `\u{1F41E}`,
753
- `timeline`,
754
- token.key,
755
- `Failed to redo. This timeline has not been initialized.`
756
- );
757
- return;
758
- }
759
- if (timelineData.at === timelineData.history.length) {
760
- store.logger.warn(
761
- `\u{1F481}`,
762
- `timeline`,
763
- token.key,
764
- `Failed to redo at the end of timeline "${token.key}". There is nothing to redo.`
765
- );
766
- return;
767
- }
768
- timelineData.timeTraveling = `into_future`;
769
- const update = timelineData.history[timelineData.at];
770
- switch (update.type) {
771
- case `atom_update`: {
772
- const { key, newValue } = update;
773
- atom_io.setState({ key, type: `atom` }, newValue, store);
774
- break;
775
- }
776
- case `selector_update`:
777
- case `transaction_update`: {
778
- for (const atomUpdate of update.atomUpdates) {
779
- const { key, newValue } = atomUpdate;
780
- atom_io.setState({ key, type: `atom` }, newValue, store);
630
+
631
+ // src/timeline/create-timeline.ts
632
+ function createTimeline(options, store, data) {
633
+ var _a, _b;
634
+ const tl = __spreadProps(__spreadValues({
635
+ type: `timeline`,
636
+ key: options.key,
637
+ at: 0,
638
+ timeTraveling: null,
639
+ selectorTime: null,
640
+ transactionKey: null
641
+ }, data), {
642
+ history: (_a = data == null ? void 0 : data.history.map((update) => __spreadValues({}, update))) != null ? _a : [],
643
+ install: (store2) => createTimeline(options, store2, tl),
644
+ subject: new Subject()
645
+ });
646
+ if (options.shouldCapture) {
647
+ tl.shouldCapture = options.shouldCapture;
648
+ }
649
+ const core = target(store);
650
+ for (const tokenOrFamily of options.atoms) {
651
+ const timelineKey = core.timelineAtoms.getRelatedKey(tokenOrFamily.key);
652
+ if (timelineKey) {
653
+ store.logger.error(
654
+ `\u274C`,
655
+ `timeline`,
656
+ options.key,
657
+ `Failed to add atom "${tokenOrFamily.key}" because it already belongs to timeline "${timelineKey}"`
658
+ );
659
+ continue;
660
+ }
661
+ if (tokenOrFamily.type === `atom_family`) {
662
+ const family = tokenOrFamily;
663
+ family.subject.subscribe(`timeline:${options.key}`, (token2) => {
664
+ addAtomToTimeline(token2, tl, store);
665
+ });
666
+ for (const atom of core.atoms.values()) {
667
+ if (((_b = atom.family) == null ? void 0 : _b.key) === family.key) {
668
+ addAtomToTimeline(atom, tl, store);
669
+ }
781
670
  }
782
- break;
671
+ } else {
672
+ const token2 = tokenOrFamily;
673
+ if (`family` in token2 && token2.family) {
674
+ const familyTimelineKey = core.timelineAtoms.getRelatedKey(
675
+ token2.family.key
676
+ );
677
+ if (familyTimelineKey) {
678
+ store.logger.error(
679
+ `\u274C`,
680
+ `timeline`,
681
+ options.key,
682
+ `Failed to add atom "${token2.key}" because its family "${token2.family.key}" already belongs to timeline "${familyTimelineKey}"`
683
+ );
684
+ continue;
685
+ }
686
+ }
687
+ addAtomToTimeline(token2, tl, store);
783
688
  }
689
+ core.timelineAtoms = core.timelineAtoms.set({
690
+ atomKey: tokenOrFamily.key,
691
+ timelineKey: options.key
692
+ });
784
693
  }
785
- ++timelineData.at;
786
- timelineData.subject.next(`redo`);
787
- timelineData.timeTraveling = null;
694
+ store.timelines.set(options.key, tl);
695
+ const token = {
696
+ key: options.key,
697
+ type: `timeline`
698
+ };
699
+ store.subject.timelineCreation.next(token);
700
+ return token;
701
+ }
702
+ var timeTravel = (direction, token, store) => {
703
+ const action = direction === `forward` ? `redo` : `undo`;
788
704
  store.logger.info(
789
- `\u23F9\uFE0F`,
705
+ direction === `forward` ? `\u23E9` : `\u23EA`,
790
706
  `timeline`,
791
707
  token.key,
792
- `"${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`
708
+ action
793
709
  );
794
- };
795
- var undo__INTERNAL = (token, store = IMPLICIT.STORE) => {
796
- store.logger.info(`\u23EA`, `timeline`, token.key, `undo`);
797
710
  const timelineData = store.timelines.get(token.key);
798
711
  if (!timelineData) {
799
712
  store.logger.error(
800
713
  `\u{1F41E}`,
801
714
  `timeline`,
802
715
  token.key,
803
- `Failed to undo. This timeline has not been initialized.`
716
+ `Failed to ${action}. This timeline has not been initialized.`
804
717
  );
805
718
  return;
806
719
  }
807
- if (timelineData.at === 0) {
720
+ if (direction === `forward` && timelineData.at === timelineData.history.length || direction === `backward` && timelineData.at === 0) {
808
721
  store.logger.warn(
809
722
  `\u{1F481}`,
810
723
  `timeline`,
811
724
  token.key,
812
- `Failed to undo at the beginning of timeline "${token.key}". There is nothing to undo.`
725
+ `Failed to ${action} at the ${direction === `forward` ? `end` : `beginning`} of timeline "${token.key}". There is nothing to ${action}.`
813
726
  );
814
727
  return;
815
728
  }
816
- timelineData.timeTraveling = `into_past`;
817
- --timelineData.at;
729
+ timelineData.timeTraveling = direction === `forward` ? `into_future` : `into_past`;
730
+ if (direction === `backward`) {
731
+ --timelineData.at;
732
+ }
818
733
  const update = timelineData.history[timelineData.at];
734
+ const updateValues = (atomUpdate) => {
735
+ const { key, newValue, oldValue } = atomUpdate;
736
+ const value = direction === `forward` ? newValue : oldValue;
737
+ setState({ key, type: `atom` }, value, store);
738
+ };
819
739
  switch (update.type) {
820
740
  case `atom_update`: {
821
- const { key, oldValue } = update;
822
- atom_io.setState({ key, type: `atom` }, oldValue, store);
741
+ updateValues(update);
823
742
  break;
824
743
  }
825
744
  case `selector_update`:
826
745
  case `transaction_update`: {
827
- for (const atomUpdate of [...update.atomUpdates].reverse()) {
828
- const { key, oldValue } = atomUpdate;
829
- atom_io.setState({ key, type: `atom` }, oldValue, store);
746
+ const updates = direction === `forward` ? update.atomUpdates : [...update.atomUpdates].reverse();
747
+ for (const atomUpdate of updates) {
748
+ updateValues(atomUpdate);
830
749
  }
831
750
  break;
832
751
  }
833
752
  }
834
- timelineData.subject.next(`undo`);
753
+ if (direction === `forward`) {
754
+ ++timelineData.at;
755
+ }
756
+ timelineData.subject.next(action);
835
757
  timelineData.timeTraveling = null;
836
758
  store.logger.info(
837
759
  `\u23F9\uFE0F`,
@@ -841,154 +763,257 @@ var undo__INTERNAL = (token, store = IMPLICIT.STORE) => {
841
763
  );
842
764
  };
843
765
 
844
- // src/timeline/timeline-internal.ts
845
- function timeline__INTERNAL(options, store = IMPLICIT.STORE, data = null) {
846
- var _a, _b;
847
- const tl = __spreadProps(__spreadValues({
848
- type: `timeline`,
849
- key: options.key,
850
- at: 0,
851
- timeTraveling: null,
852
- selectorTime: null,
853
- transactionKey: null
854
- }, data), {
855
- history: (_a = data == null ? void 0 : data.history.map((update) => __spreadValues({}, update))) != null ? _a : [],
856
- install: (store2) => timeline__INTERNAL(options, store2, tl),
857
- subject: new Subject()
858
- });
859
- if (options.shouldCapture) {
860
- tl.shouldCapture = options.shouldCapture;
766
+ // src/store/withdraw.ts
767
+ function withdraw(token, store) {
768
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
769
+ let core = target(store);
770
+ 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);
771
+ if (state) {
772
+ return state;
861
773
  }
862
- const core = target(store);
863
- for (const tokenOrFamily of options.atoms) {
864
- const timelineKey = core.timelineAtoms.getRelatedKey(tokenOrFamily.key);
865
- if (timelineKey) {
866
- store.logger.error(
867
- `\u274C`,
868
- `timeline`,
869
- options.key,
870
- `Failed to add atom "${tokenOrFamily.key}" because it already belongs to timeline "${timelineKey}"`
774
+ if (store.transactionStatus.phase === `applying`) {
775
+ core = store.transactionStatus.core;
776
+ 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);
777
+ if (state) {
778
+ store.logger.info(
779
+ `\u{1F6E0}\uFE0F`,
780
+ token.type,
781
+ token.key,
782
+ `add ${token.type} "${token.key}"`
871
783
  );
872
- continue;
784
+ switch (state.type) {
785
+ case `atom`: {
786
+ store.atoms.set(token.key, state);
787
+ store.valueMap.set(token.key, state.default);
788
+ const stateKey = state.key;
789
+ const familyKey = (_i = state.family) == null ? void 0 : _i.key;
790
+ let timelineKey = core.timelineAtoms.getRelatedKey(stateKey);
791
+ if (timelineKey === void 0 && typeof familyKey === `string`) {
792
+ timelineKey = core.timelineAtoms.getRelatedKey(familyKey);
793
+ }
794
+ const timeline = typeof timelineKey === `string` ? store.timelines.get(timelineKey) : void 0;
795
+ if (timeline) {
796
+ addAtomToTimeline(state, timeline, store);
797
+ }
798
+ break;
799
+ }
800
+ case `selector`:
801
+ core.selectors.set(token.key, state);
802
+ break;
803
+ case `readonly_selector`:
804
+ core.readonlySelectors.set(token.key, state);
805
+ break;
806
+ case `transaction`:
807
+ core.transactions.set(token.key, state);
808
+ break;
809
+ case `timeline`:
810
+ core.timelines.set(token.key, state);
811
+ break;
812
+ }
813
+ return state;
873
814
  }
874
- if (tokenOrFamily.type === `atom_family`) {
875
- const family = tokenOrFamily;
876
- family.subject.subscribe(`timeline:${options.key}`, (token2) => {
877
- addAtomToTimeline(token2, tl, store);
878
- });
879
- for (const atom of core.atoms.values()) {
880
- if (((_b = atom.family) == null ? void 0 : _b.key) === family.key) {
881
- addAtomToTimeline(atom, tl, store);
815
+ }
816
+ return void 0;
817
+ }
818
+
819
+ // src/store/withdraw-new-family-member.ts
820
+ function withdrawNewFamilyMember(token, store) {
821
+ if (token.family) {
822
+ store.logger.info(
823
+ `\u{1F46A}`,
824
+ token.type,
825
+ token.key,
826
+ `creating new family member in store "${store.config.name}"`
827
+ );
828
+ const core = target(store);
829
+ const family = core.families.get(token.family.key);
830
+ if (family) {
831
+ const jsonSubKey = JSON.parse(token.family.subKey);
832
+ family(jsonSubKey);
833
+ const state = withdraw(token, store);
834
+ return state;
835
+ }
836
+ }
837
+ return void 0;
838
+ }
839
+
840
+ // src/transaction/apply-transaction.ts
841
+ var applyTransaction = (output, store) => {
842
+ if (store.transactionStatus.phase !== `building`) {
843
+ store.logger.warn(
844
+ `\u{1F41E}`,
845
+ `transaction`,
846
+ `???`,
847
+ `applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`
848
+ );
849
+ return;
850
+ }
851
+ store.transactionStatus.phase = `applying`;
852
+ store.transactionStatus.output = output;
853
+ const { atomUpdates } = store.transactionStatus;
854
+ store.logger.info(
855
+ `\u{1F6C4}`,
856
+ `transaction`,
857
+ store.transactionStatus.key,
858
+ `Applying transaction with ${atomUpdates.length} updates:`,
859
+ atomUpdates
860
+ );
861
+ for (const { key, newValue } of atomUpdates) {
862
+ const token = { key, type: `atom` };
863
+ if (!store.valueMap.has(token.key)) {
864
+ if (token.family) {
865
+ const family = store.families.get(token.family.key);
866
+ if (family) {
867
+ family(token.family.subKey);
882
868
  }
869
+ } else {
870
+ const newAtom = store.transactionStatus.core.atoms.get(token.key);
871
+ if (!newAtom) {
872
+ throw new Error(
873
+ `Absurd Error: Atom "${token.key}" not found while copying updates from transaction "${store.transactionStatus.key}" to store "${store.config.name}"`
874
+ );
875
+ }
876
+ store.atoms.set(newAtom.key, newAtom);
877
+ store.valueMap.set(newAtom.key, newAtom.default);
878
+ store.logger.info(
879
+ `\u{1F528}`,
880
+ `transaction`,
881
+ store.transactionStatus.key,
882
+ `Adding atom "${newAtom.key}"`
883
+ );
883
884
  }
884
- } else {
885
- const token2 = tokenOrFamily;
886
- if (`family` in token2 && token2.family) {
887
- const familyTimelineKey = core.timelineAtoms.getRelatedKey(
888
- token2.family.key
885
+ }
886
+ setState(token, newValue, store);
887
+ }
888
+ const myTransaction = withdraw(
889
+ { key: store.transactionStatus.key, type: `transaction` },
890
+ store
891
+ );
892
+ if (myTransaction === void 0) {
893
+ throw new Error(
894
+ `Transaction "${store.transactionStatus.key}" not found. Absurd. How is this running?`
895
+ );
896
+ }
897
+ myTransaction.subject.next({
898
+ key: store.transactionStatus.key,
899
+ atomUpdates,
900
+ output,
901
+ params: store.transactionStatus.params
902
+ });
903
+ store.logger.info(
904
+ `\u{1F6EC}`,
905
+ `transaction`,
906
+ store.transactionStatus.key,
907
+ `Finished applying transaction.`
908
+ );
909
+ store.transactionStatus = { phase: `idle` };
910
+ };
911
+
912
+ // src/transaction/build-transaction.ts
913
+ var buildTransaction = (key, params, store) => {
914
+ store.transactionStatus = {
915
+ key,
916
+ phase: `building`,
917
+ time: Date.now(),
918
+ core: {
919
+ atoms: new Map(store.atoms),
920
+ atomsThatAreDefault: new Set(store.atomsThatAreDefault),
921
+ families: new Map(store.families),
922
+ operation: { open: false },
923
+ readonlySelectors: new Map(store.readonlySelectors),
924
+ timelines: new Map(store.timelines),
925
+ timelineAtoms: new Junction(store.timelineAtoms.toJSON()),
926
+ trackers: /* @__PURE__ */ new Map(),
927
+ transactions: new Map(store.transactions),
928
+ selectorAtoms: new Junction(store.selectorAtoms.toJSON()),
929
+ selectorGraph: new Junction(store.selectorGraph.toJSON(), {
930
+ makeContentKey: (...keys) => keys.sort().join(`:`)
931
+ }),
932
+ selectors: new Map(store.selectors),
933
+ valueMap: new Map(store.valueMap)
934
+ },
935
+ atomUpdates: [],
936
+ params,
937
+ output: void 0
938
+ };
939
+ store.logger.info(
940
+ `\u{1F6EB}`,
941
+ `transaction`,
942
+ key,
943
+ `Building transaction with params:`,
944
+ params
945
+ );
946
+ };
947
+ function createTransaction(options, store) {
948
+ const newTransaction = {
949
+ key: options.key,
950
+ type: `transaction`,
951
+ run: (...params) => {
952
+ buildTransaction(options.key, params, store);
953
+ try {
954
+ const output = options.do(
955
+ {
956
+ get: (token2) => getState(token2, store),
957
+ set: (token2, value) => setState(token2, value, store)
958
+ },
959
+ ...params
889
960
  );
890
- if (familyTimelineKey) {
891
- store.logger.error(
892
- `\u274C`,
893
- `timeline`,
894
- options.key,
895
- `Failed to add atom "${token2.key}" because its family "${token2.family.key}" already belongs to timeline "${familyTimelineKey}"`
896
- );
897
- continue;
898
- }
961
+ applyTransaction(output, store);
962
+ return output;
963
+ } catch (thrown) {
964
+ abortTransaction(store);
965
+ store.logger.warn(`\u{1F4A5}`, `transaction`, options.key, `caught:`, thrown);
966
+ throw thrown;
899
967
  }
900
- addAtomToTimeline(token2, tl, store);
901
- }
902
- core.timelineAtoms = core.timelineAtoms.set({
903
- atomKey: tokenOrFamily.key,
904
- timelineKey: options.key
905
- });
906
- }
907
- store.timelines.set(options.key, tl);
908
- const token = {
909
- key: options.key,
910
- type: `timeline`
968
+ },
969
+ install: (store2) => createTransaction(options, store2),
970
+ subject: new Subject()
911
971
  };
912
- store.subject.timelineCreation.next(token);
972
+ const core = target(store);
973
+ core.transactions.set(newTransaction.key, newTransaction);
974
+ const token = deposit(newTransaction);
975
+ store.subject.transactionCreation.next(token);
913
976
  return token;
914
977
  }
915
-
916
- // src/store/withdraw.ts
917
- function withdraw(token, store) {
918
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
919
- let core = target(store);
920
- 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);
921
- if (state) {
922
- return state;
923
- }
924
- if (store.transactionStatus.phase === `applying`) {
925
- core = store.transactionStatus.core;
926
- 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);
927
- if (state) {
928
- store.logger.info(
929
- `\u{1F6E0}\uFE0F`,
930
- token.type,
931
- token.key,
932
- `add ${token.type} "${token.key}"`
978
+ var target = (store) => store.transactionStatus.phase === `building` ? store.transactionStatus.core : store;
979
+ var redoTransactionUpdate = (update, store) => {
980
+ store.logger.info(`\u23ED\uFE0F`, `transaction`, update.key, `Redo`);
981
+ for (const { key, newValue } of update.atomUpdates) {
982
+ const token = { key, type: `atom` };
983
+ const state = withdraw(token, store);
984
+ if (state === void 0) {
985
+ throw new Error(
986
+ `State "${token.key}" not found in this store. This is surprising, because we are navigating the history of the store.`
933
987
  );
934
- switch (state.type) {
935
- case `atom`: {
936
- store.atoms.set(token.key, state);
937
- store.valueMap.set(token.key, state.default);
938
- const stateKey = state.key;
939
- const familyKey = (_i = state.family) == null ? void 0 : _i.key;
940
- let timelineKey = core.timelineAtoms.getRelatedKey(stateKey);
941
- if (timelineKey === void 0 && typeof familyKey === `string`) {
942
- timelineKey = core.timelineAtoms.getRelatedKey(familyKey);
943
- }
944
- const timeline = typeof timelineKey === `string` ? store.timelines.get(timelineKey) : void 0;
945
- if (timeline) {
946
- addAtomToTimeline(state, timeline, store);
947
- }
948
- break;
949
- }
950
- case `selector`:
951
- core.selectors.set(token.key, state);
952
- break;
953
- case `readonly_selector`:
954
- core.readonlySelectors.set(token.key, state);
955
- break;
956
- case `transaction`:
957
- core.transactions.set(token.key, state);
958
- break;
959
- case `timeline`:
960
- core.timelines.set(token.key, state);
961
- break;
962
- }
963
- return state;
964
988
  }
989
+ setState(state, newValue, store);
965
990
  }
966
- return void 0;
967
- }
968
-
969
- // src/store/withdraw-new-family-member.ts
970
- function withdrawNewFamilyMember(token, store) {
991
+ };
992
+ var undoTransactionUpdate = (update, store) => {
971
993
  store.logger.info(
972
- `\u{1F46A}`,
973
- token.type,
974
- token.key,
975
- `creating new family member in store "${store.config.name}"`
994
+ `\u23EE\uFE0F`,
995
+ `transaction`,
996
+ update.key,
997
+ `Undoing transaction update`,
998
+ update
976
999
  );
977
- if (token.family) {
978
- const core = target(store);
979
- const family = core.families.get(token.family.key);
980
- if (family) {
981
- const jsonSubKey = JSON.parse(token.family.subKey);
982
- family(jsonSubKey);
983
- const state = withdraw(token, store);
984
- return state;
1000
+ for (const { key, oldValue } of update.atomUpdates) {
1001
+ const token = { key, type: `atom` };
1002
+ const state = withdraw(token, store);
1003
+ if (state === void 0) {
1004
+ throw new Error(
1005
+ `State "${token.key}" not found in this store. This is surprising, because we are navigating the history of the store.`
1006
+ );
985
1007
  }
1008
+ setState(state, oldValue, store);
986
1009
  }
987
- return void 0;
988
- }
1010
+ };
1011
+
1012
+ // src/transaction/index.ts
1013
+ var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
989
1014
 
990
1015
  // src/caching.ts
991
- var cacheValue = (key, value, subject, store = IMPLICIT.STORE) => {
1016
+ function cacheValue(key, value, subject, store) {
992
1017
  const currentValue = target(store).valueMap.get(key);
993
1018
  if (currentValue instanceof Future) {
994
1019
  currentValue.cancel();
@@ -996,24 +1021,25 @@ var cacheValue = (key, value, subject, store = IMPLICIT.STORE) => {
996
1021
  if (value instanceof Promise) {
997
1022
  const future = new Future(value);
998
1023
  target(store).valueMap.set(key, future);
999
- future.then((value2) => {
1024
+ future.then((resolved) => {
1000
1025
  if (future.isCanceled) {
1001
1026
  return;
1002
1027
  }
1003
- cacheValue(key, value2, subject, store);
1004
- subject.next({ newValue: value2, oldValue: value2 });
1028
+ cacheValue(key, resolved, subject, store);
1029
+ subject.next({ newValue: resolved, oldValue: future });
1005
1030
  }).catch((thrown) => {
1006
1031
  if (thrown !== `canceled`) {
1007
1032
  store.logger.error(`\u{1F4A5}`, `state`, key, `rejected:`, thrown);
1008
1033
  }
1009
1034
  });
1010
- } else {
1011
- target(store).valueMap.set(key, value);
1035
+ return future;
1012
1036
  }
1013
- };
1014
- var readCachedValue = (key, store = IMPLICIT.STORE) => target(store).valueMap.get(key);
1015
- var isValueCached = (key, store = IMPLICIT.STORE) => target(store).valueMap.has(key);
1016
- var evictCachedValue = (key, store = IMPLICIT.STORE) => {
1037
+ target(store).valueMap.set(key, value);
1038
+ return value;
1039
+ }
1040
+ var readCachedValue = (key, store) => target(store).valueMap.get(key);
1041
+ var isValueCached = (key, store) => target(store).valueMap.has(key);
1042
+ var evictCachedValue = (key, store) => {
1017
1043
  const core = target(store);
1018
1044
  const currentValue = core.valueMap.get(key);
1019
1045
  if (currentValue instanceof Future) {
@@ -1026,7 +1052,7 @@ var evictCachedValue = (key, store = IMPLICIT.STORE) => {
1026
1052
  store.logger.info(`\u{1F5D1}`, `state`, key, `evicted`);
1027
1053
  };
1028
1054
  var Tracker = class {
1029
- constructor(mutableState, store = IMPLICIT.STORE) {
1055
+ constructor(mutableState, store) {
1030
1056
  this.unsubscribeFromInnerValue = null;
1031
1057
  this.mutableState = mutableState;
1032
1058
  this.latestUpdateState = this.initializeState(mutableState, store);
@@ -1035,7 +1061,7 @@ var Tracker = class {
1035
1061
  const core = target(store);
1036
1062
  core.trackers.set(mutableState.key, this);
1037
1063
  }
1038
- initializeState(mutableState, store = IMPLICIT.STORE) {
1064
+ initializeState(mutableState, store) {
1039
1065
  const latestUpdateStateKey = `*${mutableState.key}`;
1040
1066
  deleteAtom({ type: `atom`, key: latestUpdateStateKey }, store);
1041
1067
  const familyMetaData = mutableState.family ? {
@@ -1052,8 +1078,8 @@ var Tracker = class {
1052
1078
  );
1053
1079
  return latestUpdateState;
1054
1080
  }
1055
- observeCore(mutableState, latestUpdateState, store = IMPLICIT.STORE) {
1056
- const originalInnerValue = atom_io.getState(mutableState, store);
1081
+ observeCore(mutableState, latestUpdateState, store) {
1082
+ const originalInnerValue = getState(mutableState, store);
1057
1083
  this.unsubscribeFromInnerValue = originalInnerValue.subscribe(
1058
1084
  `tracker:${store.config.name}:${store.transactionStatus.phase === `idle` ? `main` : store.transactionStatus.key}`,
1059
1085
  (update) => {
@@ -1061,12 +1087,12 @@ var Tracker = class {
1061
1087
  mutableState.key,
1062
1088
  () => {
1063
1089
  unsubscribe();
1064
- atom_io.setState(latestUpdateState, update, store);
1090
+ setState(latestUpdateState, update, store);
1065
1091
  }
1066
1092
  );
1067
1093
  }
1068
1094
  );
1069
- atom_io.subscribe(
1095
+ subscribe(
1070
1096
  mutableState,
1071
1097
  (update) => {
1072
1098
  var _a;
@@ -1079,7 +1105,7 @@ var Tracker = class {
1079
1105
  mutableState.key,
1080
1106
  () => {
1081
1107
  unsubscribe();
1082
- atom_io.setState(latestUpdateState, update2, store);
1108
+ setState(latestUpdateState, update2, store);
1083
1109
  }
1084
1110
  );
1085
1111
  }
@@ -1090,8 +1116,8 @@ var Tracker = class {
1090
1116
  store
1091
1117
  );
1092
1118
  }
1093
- updateCore(mutableState, latestUpdateState, store = IMPLICIT.STORE) {
1094
- atom_io.subscribe(
1119
+ updateCore(mutableState, latestUpdateState, store) {
1120
+ subscribe(
1095
1121
  latestUpdateState,
1096
1122
  ({ newValue, oldValue }) => {
1097
1123
  const timelineId = store.timelineAtoms.getRelatedKey(
@@ -1100,11 +1126,11 @@ var Tracker = class {
1100
1126
  if (timelineId) {
1101
1127
  const timelineData = store.timelines.get(timelineId);
1102
1128
  if (timelineData == null ? void 0 : timelineData.timeTraveling) {
1103
- const unsubscribe2 = atom_io.subscribeToTimeline(
1129
+ const unsubscribe2 = subscribeToTimeline(
1104
1130
  { key: timelineId, type: `timeline` },
1105
1131
  (update) => {
1106
1132
  unsubscribe2();
1107
- atom_io.setState(
1133
+ setState(
1108
1134
  mutableState,
1109
1135
  (transceiver) => {
1110
1136
  if (update === `redo` && newValue) {
@@ -1125,8 +1151,11 @@ var Tracker = class {
1125
1151
  latestUpdateState.key,
1126
1152
  () => {
1127
1153
  unsubscribe();
1128
- if (newValue) {
1129
- atom_io.setState(
1154
+ const mutable = getState(mutableState, store);
1155
+ const updateNumber = mutable.getUpdateNumber(newValue);
1156
+ const eventOffset = updateNumber - mutable.cacheUpdateNumber;
1157
+ if (newValue && eventOffset === 1) {
1158
+ setState(
1130
1159
  mutableState,
1131
1160
  (transceiver) => (transceiver.do(newValue), transceiver),
1132
1161
  store
@@ -1142,7 +1171,7 @@ var Tracker = class {
1142
1171
  };
1143
1172
 
1144
1173
  // src/mutable/create-mutable-atom.ts
1145
- function createMutableAtom(options, store = IMPLICIT.STORE) {
1174
+ function createMutableAtom(options, store) {
1146
1175
  store.logger.info(
1147
1176
  `\u{1F527}`,
1148
1177
  `atom`,
@@ -1151,8 +1180,8 @@ function createMutableAtom(options, store = IMPLICIT.STORE) {
1151
1180
  );
1152
1181
  const coreState = createAtom(options, void 0, store);
1153
1182
  new Tracker(coreState, store);
1154
- const jsonState = json.selectJson(coreState, options, store);
1155
- atom_io.subscribe(
1183
+ const jsonState = selectJson(coreState, options, store);
1184
+ subscribe(
1156
1185
  jsonState,
1157
1186
  () => {
1158
1187
  const trackerHasBeenInitialized = target(store).trackers.has(coreState.key);
@@ -1164,11 +1193,11 @@ function createMutableAtom(options, store = IMPLICIT.STORE) {
1164
1193
  );
1165
1194
  return coreState;
1166
1195
  }
1167
- function createAtomFamily(options, store = IMPLICIT.STORE) {
1196
+ function createAtomFamily(options, store) {
1168
1197
  const subject = new Subject();
1169
1198
  const atomFamily = Object.assign(
1170
1199
  (key) => {
1171
- const subKey = json.stringifyJson(key);
1200
+ const subKey = stringifyJson(key);
1172
1201
  const family = { key: options.key, subKey };
1173
1202
  const fullKey = `${options.key}(${subKey})`;
1174
1203
  const existing = withdraw({ key: fullKey, type: `atom` }, store);
@@ -1199,37 +1228,6 @@ function createAtomFamily(options, store = IMPLICIT.STORE) {
1199
1228
  return atomFamily;
1200
1229
  }
1201
1230
 
1202
- // src/keys.ts
1203
- var isAtomKey = (key, store) => target(store).atoms.has(key);
1204
- var isSelectorKey = (key, store) => target(store).selectors.has(key);
1205
- var isReadonlySelectorKey = (key, store) => target(store).readonlySelectors.has(key);
1206
- var isStateKey = (key, store) => isAtomKey(key, store) || isSelectorKey(key, store) || isReadonlySelectorKey(key, store);
1207
-
1208
- // src/selector/get-selector-dependency-keys.ts
1209
- var getSelectorDependencyKeys = (key, store) => {
1210
- const sources = target(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(source, store));
1211
- return sources;
1212
- };
1213
-
1214
- // src/get-state-internal.ts
1215
- var getState__INTERNAL = (state, store = IMPLICIT.STORE) => {
1216
- if (isValueCached(state.key, store)) {
1217
- store.logger.info(`\u{1F4D6}`, state.type, state.key, `reading cached value`);
1218
- return readCachedValue(state.key, store);
1219
- }
1220
- if (state.type !== `atom`) {
1221
- store.logger.info(`\u{1F9EE}`, state.type, state.key, `calculating value`);
1222
- return state.get();
1223
- }
1224
- store.logger.error(`\u{1F41E}`, `atom`, state.key, `could not find cached value`);
1225
- return state.default;
1226
- };
1227
-
1228
- // src/set-state/become.ts
1229
- var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(
1230
- originalThing instanceof Function ? originalThing() : originalThing
1231
- ) : nextVersionOfThing;
1232
-
1233
1231
  // src/operation.ts
1234
1232
  var openOperation = (token, store) => {
1235
1233
  const core = target(store);
@@ -1269,7 +1267,7 @@ var closeOperation = (store) => {
1269
1267
  core.operation = { open: false };
1270
1268
  store.subject.operationStatus.next(core.operation);
1271
1269
  };
1272
- var isDone = (key, store = IMPLICIT.STORE) => {
1270
+ var isDone = (key, store) => {
1273
1271
  const core = target(store);
1274
1272
  if (!core.operation.open) {
1275
1273
  store.logger.warn(
@@ -1282,7 +1280,7 @@ var isDone = (key, store = IMPLICIT.STORE) => {
1282
1280
  }
1283
1281
  return core.operation.done.has(key);
1284
1282
  };
1285
- var markDone = (key, store = IMPLICIT.STORE) => {
1283
+ var markDone = (key, store) => {
1286
1284
  const core = target(store);
1287
1285
  if (!core.operation.open) {
1288
1286
  store.logger.warn(
@@ -1296,6 +1294,32 @@ var markDone = (key, store = IMPLICIT.STORE) => {
1296
1294
  core.operation.done.add(key);
1297
1295
  };
1298
1296
 
1297
+ // src/set-state/become.ts
1298
+ var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(
1299
+ originalThing instanceof Function ? originalThing() : originalThing
1300
+ ) : nextVersionOfThing;
1301
+
1302
+ // src/read-or-compute-value.ts
1303
+ var readOrComputeValue = (state, store) => {
1304
+ if (isValueCached(state.key, store)) {
1305
+ store.logger.info(`\u{1F4D6}`, state.type, state.key, `reading cached value`);
1306
+ return readCachedValue(state.key, store);
1307
+ }
1308
+ if (state.type !== `atom`) {
1309
+ store.logger.info(`\u{1F9EE}`, state.type, state.key, `computing value`);
1310
+ return state.get();
1311
+ }
1312
+ const fallback = state.default instanceof Function ? state.default() : state.default;
1313
+ store.logger.info(
1314
+ `\u{1F481}`,
1315
+ `atom`,
1316
+ state.key,
1317
+ `could not find cached value; using default`,
1318
+ fallback
1319
+ );
1320
+ return state.default instanceof Function ? state.default() : state.default;
1321
+ };
1322
+
1299
1323
  // src/set-state/copy-mutable-if-needed.ts
1300
1324
  function copyMutableIfNeeded(atom, transform, origin, target2) {
1301
1325
  const originValue = origin.valueMap.get(atom.key);
@@ -1311,7 +1335,7 @@ function copyMutableIfNeeded(atom, transform, origin, target2) {
1311
1335
  }
1312
1336
 
1313
1337
  // src/set-state/copy-mutable-in-transaction.ts
1314
- function copyMutableIfWithinTransaction(atom, store) {
1338
+ function copyMutableIfWithinTransaction(oldValue, atom, store) {
1315
1339
  if (store.transactionStatus.phase === `building` || store.transactionStatus.phase === `applying`) {
1316
1340
  if (`toJson` in atom && `fromJson` in atom) {
1317
1341
  const copiedValue = copyMutableIfNeeded(
@@ -1337,7 +1361,7 @@ function copyMutableIfWithinTransaction(atom, store) {
1337
1361
  }
1338
1362
  }
1339
1363
  }
1340
- return getState__INTERNAL(atom, store);
1364
+ return oldValue;
1341
1365
  }
1342
1366
  function copyMutableFamilyMemberWithinTransaction(atom, family, origin, target2) {
1343
1367
  if (`toJson` in family && `fromJson` in family) {
@@ -1349,8 +1373,7 @@ function copyMutableFamilyMemberWithinTransaction(atom, family, origin, target2)
1349
1373
 
1350
1374
  // src/set-state/emit-update.ts
1351
1375
  var emitUpdate = (state, update, store) => {
1352
- const { logger } = store;
1353
- logger.info(
1376
+ store.logger.info(
1354
1377
  `\u{1F4E2}`,
1355
1378
  state.type,
1356
1379
  state.key,
@@ -1365,18 +1388,17 @@ var emitUpdate = (state, update, store) => {
1365
1388
  };
1366
1389
 
1367
1390
  // src/set-state/evict-downstream.ts
1368
- var evictDownStream = (atom, store = IMPLICIT.STORE) => {
1369
- var _a;
1391
+ var evictDownStream = (atom, store) => {
1370
1392
  const core = target(store);
1371
1393
  const downstreamKeys = core.selectorAtoms.getRelatedKeys(atom.key);
1372
1394
  store.logger.info(
1373
1395
  `\u{1F9F9}`,
1374
1396
  atom.type,
1375
1397
  atom.key,
1376
- `evicting ${(_a = downstreamKeys == null ? void 0 : downstreamKeys.size) != null ? _a : 0} states downstream:`,
1377
- downstreamKeys
1398
+ downstreamKeys ? `evicting ${downstreamKeys.size} states downstream:` : `no downstream states`,
1399
+ downstreamKeys != null ? downstreamKeys : `to evict`
1378
1400
  );
1379
- if (downstreamKeys !== void 0) {
1401
+ if (downstreamKeys) {
1380
1402
  if (core.operation.open) {
1381
1403
  store.logger.info(
1382
1404
  `\u{1F9F9}`,
@@ -1438,12 +1460,12 @@ var stowUpdate = (state, update, store) => {
1438
1460
  };
1439
1461
 
1440
1462
  // src/set-state/set-atom.ts
1441
- var setAtom = (atom, next, store = IMPLICIT.STORE) => {
1442
- const oldValue = getState__INTERNAL(atom, store);
1443
- let newValue = copyMutableIfWithinTransaction(atom, store);
1463
+ var setAtom = (atom, next, store) => {
1464
+ const oldValue = readOrComputeValue(atom, store);
1465
+ let newValue = copyMutableIfWithinTransaction(oldValue, atom, store);
1444
1466
  newValue = become(next)(newValue);
1445
1467
  store.logger.info(`\u{1F4DD}`, `atom`, atom.key, `set to`, newValue);
1446
- cacheValue(atom.key, newValue, atom.subject, store);
1468
+ newValue = cacheValue(atom.key, newValue, atom.subject, store);
1447
1469
  if (isAtomDefault(atom.key, store)) {
1448
1470
  markAtomAsNotDefault(atom.key, store);
1449
1471
  }
@@ -1457,8 +1479,8 @@ var setAtom = (atom, next, store = IMPLICIT.STORE) => {
1457
1479
  }
1458
1480
  };
1459
1481
 
1460
- // src/set-state/set-state-internal.ts
1461
- var setState__INTERNAL = (state, value, store = IMPLICIT.STORE) => {
1482
+ // src/set-state/set-atom-or-selector.ts
1483
+ var setAtomOrSelector = (state, value, store) => {
1462
1484
  if (state.type === `selector`) {
1463
1485
  state.set(value);
1464
1486
  } else {
@@ -1466,6 +1488,18 @@ var setState__INTERNAL = (state, value, store = IMPLICIT.STORE) => {
1466
1488
  }
1467
1489
  };
1468
1490
 
1491
+ // src/keys.ts
1492
+ var isAtomKey = (key, store) => target(store).atoms.has(key);
1493
+ var isSelectorKey = (key, store) => target(store).selectors.has(key);
1494
+ var isReadonlySelectorKey = (key, store) => target(store).readonlySelectors.has(key);
1495
+ var isStateKey = (key, store) => isAtomKey(key, store) || isSelectorKey(key, store) || isReadonlySelectorKey(key, store);
1496
+
1497
+ // src/selector/get-selector-dependency-keys.ts
1498
+ var getSelectorDependencyKeys = (key, store) => {
1499
+ const sources = target(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(source, store));
1500
+ return sources;
1501
+ };
1502
+
1469
1503
  // src/selector/trace-selector-atoms.ts
1470
1504
  var traceSelectorAtoms = (selectorKey, directDependencyKey, store) => {
1471
1505
  const rootKeys = [];
@@ -1531,7 +1565,7 @@ var updateSelectorAtoms = (selectorKey, dependency, store) => {
1531
1565
  };
1532
1566
 
1533
1567
  // src/selector/register-selector.ts
1534
- var registerSelector = (selectorKey, store = IMPLICIT.STORE) => ({
1568
+ var registerSelector = (selectorKey, store) => ({
1535
1569
  get: (dependency) => {
1536
1570
  const core = target(store);
1537
1571
  const alreadyRegistered = core.selectorGraph.getRelationEntries({ downstreamSelectorKey: selectorKey }).some(([_, { source }]) => source === dependency.key);
@@ -1541,7 +1575,7 @@ var registerSelector = (selectorKey, store = IMPLICIT.STORE) => ({
1541
1575
  `State "${dependency.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`
1542
1576
  );
1543
1577
  }
1544
- const dependencyValue = getState__INTERNAL(dependencyState, store);
1578
+ const dependencyValue = readOrComputeValue(dependencyState, store);
1545
1579
  store.logger.info(
1546
1580
  `\u{1F50C}`,
1547
1581
  `selector`,
@@ -1571,7 +1605,7 @@ var registerSelector = (selectorKey, store = IMPLICIT.STORE) => ({
1571
1605
  `State "${stateToken.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`
1572
1606
  );
1573
1607
  }
1574
- setState__INTERNAL(state, newValue, store);
1608
+ setAtomOrSelector(state, newValue, store);
1575
1609
  }
1576
1610
  });
1577
1611
 
@@ -1661,7 +1695,7 @@ var createReadonlySelector = (options, family, store, core) => {
1661
1695
  };
1662
1696
 
1663
1697
  // src/selector/create-selector.ts
1664
- function createSelector(options, family, store = IMPLICIT.STORE) {
1698
+ function createSelector(options, family, store) {
1665
1699
  const core = target(store);
1666
1700
  const existingWritable = core.selectors.get(options.key);
1667
1701
  const existingReadonly = core.readonlySelectors.get(options.key);
@@ -1679,13 +1713,42 @@ function createSelector(options, family, store = IMPLICIT.STORE) {
1679
1713
  return createReadonlySelector(options, family, store, core);
1680
1714
  }
1681
1715
 
1716
+ // src/selector/delete-selector.ts
1717
+ function deleteSelector(selectorToken, store) {
1718
+ const core = target(store);
1719
+ const { key } = selectorToken;
1720
+ switch (selectorToken.type) {
1721
+ case `selector`:
1722
+ core.selectors.delete(key);
1723
+ break;
1724
+ case `readonly_selector`:
1725
+ core.readonlySelectors.delete(key);
1726
+ break;
1727
+ }
1728
+ core.valueMap.delete(key);
1729
+ core.selectorAtoms.delete(key);
1730
+ const downstreamTokens = core.selectorGraph.getRelationEntries({ upstreamSelectorKey: key }).filter(([_, { source }]) => source === key).map(
1731
+ ([downstreamSelectorKey]) => {
1732
+ var _a;
1733
+ return (_a = core.selectors.get(downstreamSelectorKey)) != null ? _a : core.readonlySelectors.get(downstreamSelectorKey);
1734
+ }
1735
+ );
1736
+ for (const downstreamToken of downstreamTokens) {
1737
+ if (downstreamToken) {
1738
+ deleteSelector(downstreamToken, store);
1739
+ }
1740
+ }
1741
+ core.selectorGraph.delete(key);
1742
+ store.logger.info(`\u{1F525}`, selectorToken.type, `${key}`, `deleted`);
1743
+ }
1744
+
1682
1745
  // src/families/create-readonly-selector-family.ts
1683
1746
  function createReadonlySelectorFamily(options, store) {
1684
1747
  const core = target(store);
1685
1748
  const subject = new Subject();
1686
1749
  return Object.assign(
1687
1750
  (key) => {
1688
- const subKey = json.stringifyJson(key);
1751
+ const subKey = stringifyJson(key);
1689
1752
  const family = { key: options.key, subKey };
1690
1753
  const fullKey = `${options.key}(${subKey})`;
1691
1754
  const existing = core.readonlySelectors.get(fullKey);
@@ -1708,7 +1771,7 @@ function createReadonlySelectorFamily(options, store) {
1708
1771
  }
1709
1772
  );
1710
1773
  }
1711
- function createSelectorFamily(options, store = IMPLICIT.STORE) {
1774
+ function createSelectorFamily(options, store) {
1712
1775
  const isReadonly = !(`set` in options);
1713
1776
  if (isReadonly) {
1714
1777
  return createReadonlySelectorFamily(options, store);
@@ -1717,7 +1780,7 @@ function createSelectorFamily(options, store = IMPLICIT.STORE) {
1717
1780
  const subject = new Subject();
1718
1781
  const selectorFamily = Object.assign(
1719
1782
  (key) => {
1720
- const subKey = json.stringifyJson(key);
1783
+ const subKey = stringifyJson(key);
1721
1784
  const family = { key: options.key, subKey };
1722
1785
  const fullKey = `${options.key}(${subKey})`;
1723
1786
  const existing = core.selectors.get(fullKey);
@@ -1747,7 +1810,7 @@ function createSelectorFamily(options, store = IMPLICIT.STORE) {
1747
1810
 
1748
1811
  // src/mutable/tracker-family.ts
1749
1812
  var FamilyTracker = class {
1750
- constructor(findMutableState, store = IMPLICIT.STORE) {
1813
+ constructor(findMutableState, store) {
1751
1814
  this.findLatestUpdateState = createAtomFamily(
1752
1815
  {
1753
1816
  key: `*${findMutableState.key}`,
@@ -1760,7 +1823,7 @@ var FamilyTracker = class {
1760
1823
  `store=${store.config.name}::tracker-atom-family`,
1761
1824
  (atomToken) => {
1762
1825
  if (atomToken.family) {
1763
- const key = json.parseJson(atomToken.family.subKey);
1826
+ const key = parseJson(atomToken.family.subKey);
1764
1827
  this.findLatestUpdateState(key);
1765
1828
  new Tracker(atomToken, store);
1766
1829
  }
@@ -1770,7 +1833,7 @@ var FamilyTracker = class {
1770
1833
  `store=${store.config.name}::tracker-atom-family`,
1771
1834
  (atomToken) => {
1772
1835
  if (atomToken.family) {
1773
- const key = json.parseJson(atomToken.family.subKey);
1836
+ const key = parseJson(atomToken.family.subKey);
1774
1837
  const mutableAtomToken = this.findMutableState(key);
1775
1838
  new Tracker(mutableAtomToken, store);
1776
1839
  }
@@ -1780,16 +1843,26 @@ var FamilyTracker = class {
1780
1843
  };
1781
1844
 
1782
1845
  // src/mutable/create-mutable-atom-family.ts
1783
- function createMutableAtomFamily(options, store = IMPLICIT.STORE) {
1846
+ function createMutableAtomFamily(options, store) {
1784
1847
  const coreFamily = Object.assign(
1785
1848
  createAtomFamily(options, store),
1786
1849
  options
1787
1850
  );
1788
- json.selectJsonFamily(coreFamily, options);
1851
+ selectJsonFamily(coreFamily, options);
1789
1852
  new FamilyTracker(coreFamily, store);
1790
1853
  return coreFamily;
1791
1854
  }
1792
1855
 
1856
+ // src/mutable/get-json-family.ts
1857
+ var getJsonFamily = (mutableAtomFamily, store) => {
1858
+ const core = target(store);
1859
+ const key = `${mutableAtomFamily.key}:JSON`;
1860
+ const jsonFamily = core.families.get(
1861
+ key
1862
+ );
1863
+ return jsonFamily;
1864
+ };
1865
+
1793
1866
  // src/mutable/get-json-token.ts
1794
1867
  var getJsonToken = (mutableAtomToken) => {
1795
1868
  const key = mutableAtomToken.family ? `${mutableAtomToken.family.key}:JSON(${mutableAtomToken.family.subKey})` : `${mutableAtomToken.key}:JSON`;
@@ -1830,27 +1903,26 @@ function isTransceiver(value) {
1830
1903
  var isAtomMutable = (atom) => `isMutable` in atom;
1831
1904
 
1832
1905
  // src/atom/is-default.ts
1833
- var isAtomDefault = (key, store = IMPLICIT.STORE) => {
1906
+ var isAtomDefault = (key, store) => {
1834
1907
  const core = target(store);
1835
1908
  return core.atomsThatAreDefault.has(key);
1836
1909
  };
1837
- var markAtomAsDefault = (key, store = IMPLICIT.STORE) => {
1910
+ var markAtomAsDefault = (key, store) => {
1838
1911
  const core = target(store);
1839
1912
  core.atomsThatAreDefault = new Set(core.atomsThatAreDefault).add(key);
1840
1913
  };
1841
- var markAtomAsNotDefault = (key, store = IMPLICIT.STORE) => {
1914
+ var markAtomAsNotDefault = (key, store) => {
1842
1915
  const core = target(store);
1843
1916
  core.atomsThatAreDefault = new Set(target(store).atomsThatAreDefault);
1844
1917
  core.atomsThatAreDefault.delete(key);
1845
1918
  };
1846
- var isSelectorDefault = (key, store = IMPLICIT.STORE) => {
1919
+ var isSelectorDefault = (key, store) => {
1847
1920
  const rootKeys = traceAllSelectorAtoms(key, store);
1848
1921
  return rootKeys.every((rootKey) => isAtomDefault(rootKey, store));
1849
1922
  };
1850
1923
 
1851
1924
  // src/atom/create-atom.ts
1852
- function createAtom(options, family, store = IMPLICIT.STORE) {
1853
- var _a;
1925
+ function createAtom(options, family, store) {
1854
1926
  store.logger.info(
1855
1927
  `\u{1F528}`,
1856
1928
  `atom`,
@@ -1883,35 +1955,87 @@ function createAtom(options, family, store = IMPLICIT.STORE) {
1883
1955
  },
1884
1956
  subject
1885
1957
  }), family && { family });
1886
- const initialValue = options.default instanceof Function ? options.default() : options.default;
1958
+ let initialValue = options.default;
1959
+ if (options.default instanceof Function) {
1960
+ initialValue = options.default();
1961
+ }
1887
1962
  core.atoms.set(newAtom.key, newAtom);
1888
1963
  markAtomAsDefault(options.key, store);
1889
1964
  cacheValue(options.key, initialValue, subject, store);
1890
1965
  const token = deposit(newAtom);
1891
- for (const effect of (_a = options.effects) != null ? _a : []) {
1892
- effect({
1893
- setSelf: (next) => atom_io.setState(token, next, store),
1894
- onSet: (handle) => atom_io.subscribe(token, handle, `effect[${subject.subscribers.size}]`, store)
1895
- });
1966
+ if (options.effects) {
1967
+ let effectIndex = 0;
1968
+ const cleanupFunctions = [];
1969
+ for (const effect of options.effects) {
1970
+ const cleanup = effect({
1971
+ setSelf: (next) => setState(token, next, store),
1972
+ onSet: (handle) => subscribe(token, handle, `effect[${effectIndex}]`, store)
1973
+ });
1974
+ if (cleanup) {
1975
+ cleanupFunctions.push(cleanup);
1976
+ }
1977
+ ++effectIndex;
1978
+ }
1979
+ newAtom.cleanup = () => {
1980
+ for (const cleanup of cleanupFunctions) {
1981
+ cleanup();
1982
+ }
1983
+ };
1896
1984
  }
1897
1985
  store.subject.atomCreation.next(token);
1898
1986
  return token;
1899
1987
  }
1900
1988
 
1901
1989
  // src/atom/delete-atom.ts
1902
- function deleteAtom(atomToken, store = IMPLICIT.STORE) {
1990
+ function deleteAtom(atomToken, store) {
1991
+ var _a, _b;
1903
1992
  const core = target(store);
1904
1993
  const { key } = atomToken;
1994
+ const atom = core.atoms.get(key);
1995
+ if (!atom) {
1996
+ store.logger.error(
1997
+ `\u274C`,
1998
+ `atom`,
1999
+ `${key}`,
2000
+ `Tried to delete atom, but it does not exist in the store.`
2001
+ );
2002
+ }
2003
+ (_a = atom == null ? void 0 : atom.cleanup) == null ? void 0 : _a.call(atom);
1905
2004
  core.atoms.delete(key);
1906
2005
  core.valueMap.delete(key);
2006
+ const selectorKeys = core.selectorAtoms.getRelatedKeys(key);
2007
+ if (selectorKeys) {
2008
+ for (const selectorKey of selectorKeys) {
2009
+ const token = (_b = core.selectors.get(selectorKey)) != null ? _b : core.readonlySelectors.get(selectorKey);
2010
+ if (token) {
2011
+ deleteSelector(token, store);
2012
+ }
2013
+ }
2014
+ }
1907
2015
  core.selectorAtoms.delete(key);
1908
2016
  core.atomsThatAreDefault.delete(key);
1909
2017
  core.timelineAtoms.delete(key);
1910
2018
  store.logger.info(`\u{1F525}`, `atom`, `${key}`, `deleted`);
1911
2019
  }
1912
2020
 
2021
+ // src/not-found-error.ts
2022
+ var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
2023
+ function prettyPrintTokenType(token) {
2024
+ if (token.type === `readonly_selector`) {
2025
+ return `Readonly Selector`;
2026
+ }
2027
+ return capitalize(token.type);
2028
+ }
2029
+ var NotFoundError = class extends Error {
2030
+ constructor(token, store) {
2031
+ super(
2032
+ `${prettyPrintTokenType(token)} "${token.key}" not found in store "${store.config.name}".`
2033
+ );
2034
+ }
2035
+ };
2036
+
1913
2037
  // src/subscribe/recall-state.ts
1914
- var recallState = (state, store = IMPLICIT.STORE) => {
2038
+ var recallState = (state, store) => {
1915
2039
  const core = target(store);
1916
2040
  if (!core.operation.open) {
1917
2041
  store.logger.warn(
@@ -1949,7 +2073,7 @@ var subscribeToRootAtoms = (state, store) => {
1949
2073
  atomChange.newValue
1950
2074
  );
1951
2075
  const oldValue = recallState(state, store);
1952
- const newValue = getState__INTERNAL(state, store);
2076
+ const newValue = readOrComputeValue(state, store);
1953
2077
  store.logger.info(
1954
2078
  `\u2728`,
1955
2079
  state.type,
@@ -1966,65 +2090,6 @@ var subscribeToRootAtoms = (state, store) => {
1966
2090
  return dependencySubscriptions;
1967
2091
  };
1968
2092
 
1969
- exports.FamilyTracker = FamilyTracker;
1970
- exports.Future = Future;
1971
- exports.IMPLICIT = IMPLICIT;
1972
- exports.Store = Store;
1973
- exports.Subject = Subject;
1974
- exports.TRANSACTION_PHASES = TRANSACTION_PHASES;
1975
- exports.Tracker = Tracker;
1976
- exports.abortTransaction = abortTransaction;
1977
- exports.addAtomToTimeline = addAtomToTimeline;
1978
- exports.applyTransaction = applyTransaction;
1979
- exports.become = become;
1980
- exports.buildTransaction = buildTransaction;
1981
- exports.cacheValue = cacheValue;
1982
- exports.clearStore = clearStore;
1983
- exports.closeOperation = closeOperation;
1984
- exports.createAtom = createAtom;
1985
- exports.createAtomFamily = createAtomFamily;
1986
- exports.createMutableAtom = createMutableAtom;
1987
- exports.createMutableAtomFamily = createMutableAtomFamily;
1988
- exports.createReadonlySelectorFamily = createReadonlySelectorFamily;
1989
- exports.createSelector = createSelector;
1990
- exports.createSelectorFamily = createSelectorFamily;
1991
- exports.deleteAtom = deleteAtom;
1992
- exports.deposit = deposit;
1993
- exports.evictCachedValue = evictCachedValue;
1994
- exports.getJsonToken = getJsonToken;
1995
- exports.getSelectorDependencyKeys = getSelectorDependencyKeys;
1996
- exports.getState__INTERNAL = getState__INTERNAL;
1997
- exports.getUpdateToken = getUpdateToken;
1998
- exports.isAtomDefault = isAtomDefault;
1999
- exports.isAtomKey = isAtomKey;
2000
- exports.isAtomMutable = isAtomMutable;
2001
- exports.isAtomTokenMutable = isAtomTokenMutable;
2002
- exports.isDone = isDone;
2003
- exports.isReadonlySelectorKey = isReadonlySelectorKey;
2004
- exports.isSelectorDefault = isSelectorDefault;
2005
- exports.isSelectorKey = isSelectorKey;
2006
- exports.isStateKey = isStateKey;
2007
- exports.isTransceiver = isTransceiver;
2008
- exports.isValueCached = isValueCached;
2009
- exports.markAtomAsDefault = markAtomAsDefault;
2010
- exports.markAtomAsNotDefault = markAtomAsNotDefault;
2011
- exports.markDone = markDone;
2012
- exports.openOperation = openOperation;
2013
- exports.readCachedValue = readCachedValue;
2014
- exports.redoTransactionUpdate = redoTransactionUpdate;
2015
- exports.redo__INTERNAL = redo__INTERNAL;
2016
- exports.registerSelector = registerSelector;
2017
- exports.setState__INTERNAL = setState__INTERNAL;
2018
- exports.subscribeToRootAtoms = subscribeToRootAtoms;
2019
- exports.target = target;
2020
- exports.timeline__INTERNAL = timeline__INTERNAL;
2021
- exports.traceAllSelectorAtoms = traceAllSelectorAtoms;
2022
- exports.traceSelectorAtoms = traceSelectorAtoms;
2023
- exports.transaction__INTERNAL = transaction__INTERNAL;
2024
- exports.undoTransactionUpdate = undoTransactionUpdate;
2025
- exports.undo__INTERNAL = undo__INTERNAL;
2026
- exports.updateSelectorAtoms = updateSelectorAtoms;
2027
- exports.withdraw = withdraw;
2028
- exports.withdrawNewFamilyMember = withdrawNewFamilyMember;
2093
+ export { FamilyTracker, Future, IMPLICIT, NotFoundError, 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, evictCachedValue, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getUpdateToken, isAtomDefault, isAtomKey, isAtomMutable, isAtomTokenMutable, isDone, isReadonlySelectorKey, isSelectorDefault, isSelectorKey, isStateKey, isTransceiver, isValueCached, markAtomAsDefault, markAtomAsNotDefault, markDone, openOperation, readCachedValue, readOrComputeValue, redoTransactionUpdate, registerSelector, setAtomOrSelector, subscribeToRootAtoms, target, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, undoTransactionUpdate, updateSelectorAtoms, withdraw, withdrawNewFamilyMember };
2029
2094
  //# sourceMappingURL=out.js.map
2030
2095
  //# sourceMappingURL=index.js.map