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