atom.io 0.14.7 → 0.15.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 (81) hide show
  1. package/README.md +5 -0
  2. package/data/dist/index.cjs +200 -218
  3. package/data/dist/index.cjs.map +1 -1
  4. package/data/dist/index.d.ts +16 -7
  5. package/data/dist/index.js +202 -221
  6. package/data/dist/index.js.map +1 -1
  7. package/data/src/join.ts +295 -292
  8. package/data/src/struct-family.ts +2 -2
  9. package/data/src/struct.ts +2 -2
  10. package/dist/chunk-S7R5MU6A.js +137 -0
  11. package/dist/chunk-S7R5MU6A.js.map +1 -0
  12. package/dist/index.cjs +3 -20
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.ts +15 -8
  15. package/dist/index.js +1 -151
  16. package/dist/index.js.map +1 -1
  17. package/internal/dist/index.cjs +275 -200
  18. package/internal/dist/index.cjs.map +1 -1
  19. package/internal/dist/index.d.ts +43 -36
  20. package/internal/dist/index.js +221 -193
  21. package/internal/dist/index.js.map +1 -1
  22. package/internal/src/atom/create-atom.ts +5 -86
  23. package/internal/src/atom/create-regular-atom.ts +92 -0
  24. package/internal/src/atom/index.ts +16 -0
  25. package/internal/src/atom/is-default.ts +0 -5
  26. package/internal/src/caching.ts +14 -16
  27. package/internal/src/families/create-atom-family.ts +20 -46
  28. package/internal/src/families/create-readonly-selector-family.ts +1 -0
  29. package/internal/src/families/create-regular-atom-family.ts +72 -0
  30. package/internal/src/families/create-selector-family.ts +2 -0
  31. package/internal/src/families/index.ts +1 -0
  32. package/internal/src/mutable/create-mutable-atom-family.ts +2 -2
  33. package/internal/src/mutable/create-mutable-atom.ts +8 -3
  34. package/internal/src/mutable/get-update-family.ts +1 -1
  35. package/internal/src/mutable/is-mutable.ts +3 -30
  36. package/internal/src/mutable/tracker-family.ts +2 -2
  37. package/internal/src/mutable/tracker.ts +5 -5
  38. package/internal/src/operation.ts +14 -18
  39. package/internal/src/selector/create-read-write-selector.ts +2 -3
  40. package/internal/src/selector/create-selector.ts +1 -1
  41. package/internal/src/selector/register-selector.ts +9 -14
  42. package/internal/src/set-state/evict-downstream.ts +3 -5
  43. package/internal/src/set-state/set-atom.ts +14 -17
  44. package/internal/src/store/store.ts +23 -19
  45. package/internal/src/store/withdraw.ts +32 -70
  46. package/internal/src/subscribe/subscribe-to-root-atoms.ts +5 -3
  47. package/internal/src/subscribe/subscribe-to-state.ts +5 -3
  48. package/internal/src/transaction/apply-transaction.ts +20 -2
  49. package/internal/src/transaction/build-transaction.ts +19 -11
  50. package/internal/src/transaction/create-transaction.ts +6 -11
  51. package/internal/src/transaction/index.ts +2 -3
  52. package/introspection/dist/index.cjs +6 -6
  53. package/introspection/dist/index.cjs.map +1 -1
  54. package/introspection/dist/index.d.ts +3 -3
  55. package/introspection/dist/index.js +7 -7
  56. package/introspection/dist/index.js.map +1 -1
  57. package/introspection/src/attach-atom-index.ts +7 -2
  58. package/introspection/src/attach-selector-index.ts +7 -2
  59. package/introspection/src/attach-timeline-family.ts +5 -2
  60. package/introspection/src/attach-timeline-index.ts +2 -2
  61. package/introspection/src/attach-transaction-index.ts +2 -2
  62. package/introspection/src/attach-transaction-logs.ts +2 -2
  63. package/package.json +10 -8
  64. package/react/dist/index.cjs +9 -12
  65. package/react/dist/index.cjs.map +1 -1
  66. package/react/dist/index.js +9 -12
  67. package/react/dist/index.js.map +1 -1
  68. package/react/src/store-hooks.ts +10 -12
  69. package/react-devtools/dist/index.d.ts +17 -11
  70. package/src/atom.ts +8 -17
  71. package/src/selector.ts +3 -1
  72. package/src/set-state.ts +1 -3
  73. package/src/silo.ts +2 -14
  74. package/src/transaction.ts +17 -6
  75. package/transceivers/set-rtx/dist/index.cjs +2 -1
  76. package/transceivers/set-rtx/dist/index.cjs.map +1 -1
  77. package/transceivers/set-rtx/dist/index.js +2 -1
  78. package/transceivers/set-rtx/dist/index.js.map +1 -1
  79. package/transceivers/set-rtx/src/set-rtx.ts +2 -1
  80. package/internal/src/transaction/redo-transaction.ts +0 -27
  81. package/internal/src/transaction/undo-transaction.ts +0 -27
@@ -1,8 +1,23 @@
1
+ import { getState as getState$1, setState as setState$1, runTransaction } from '../../dist/chunk-S7R5MU6A.js';
1
2
  import { Junction } from '../../dist/chunk-NYTGCPHB.js';
2
3
  import { __spreadValues, __spreadProps } from '../../dist/chunk-PZLG2HP3.js';
3
- import { AtomIOLogger, getState, setState, runTransaction } from 'atom.io';
4
4
  import { selectJson, stringifyJson, parseJson, selectJsonFamily } from 'atom.io/json';
5
- import { withdraw as withdraw$1, subscribeToRootAtoms as subscribeToRootAtoms$1 } from 'atom.io/internal';
5
+ import { AtomIOLogger, getState, setState } from 'atom.io';
6
+ import { withdraw as withdraw$1 } from 'atom.io/internal';
7
+
8
+ // internal/src/lineage.ts
9
+ function newest(scion) {
10
+ while (scion.child !== null) {
11
+ scion = scion.child;
12
+ }
13
+ return scion;
14
+ }
15
+ function eldest(scion) {
16
+ while (scion.parent !== null) {
17
+ scion = scion.parent;
18
+ }
19
+ return scion;
20
+ }
6
21
 
7
22
  // internal/src/future.ts
8
23
  var Future = class extends Promise {
@@ -23,39 +38,24 @@ var Future = class extends Promise {
23
38
  }
24
39
  };
25
40
 
26
- // internal/src/lineage.ts
27
- function newest(scion) {
28
- while (scion.child !== null) {
29
- scion = scion.child;
30
- }
31
- return scion;
32
- }
33
- function eldest(scion) {
34
- while (scion.parent !== null) {
35
- scion = scion.parent;
36
- }
37
- return scion;
38
- }
39
-
40
41
  // internal/src/caching.ts
41
- function cacheValue(key, value, subject, store) {
42
- const target = newest(store);
42
+ function cacheValue(key, value, subject, target) {
43
43
  const currentValue = target.valueMap.get(key);
44
44
  if (currentValue instanceof Future) {
45
45
  currentValue.cancel();
46
46
  }
47
47
  if (value instanceof Promise) {
48
48
  const future = new Future(value);
49
- newest(store).valueMap.set(key, future);
49
+ target.valueMap.set(key, future);
50
50
  future.then((resolved) => {
51
51
  if (future.isCanceled) {
52
52
  return;
53
53
  }
54
- cacheValue(key, resolved, subject, store);
54
+ cacheValue(key, resolved, subject, target);
55
55
  subject.next({ newValue: resolved, oldValue: future });
56
56
  }).catch((thrown) => {
57
57
  if (thrown !== `canceled`) {
58
- store.logger.error(`\u{1F4A5}`, `state`, key, `rejected:`, thrown);
58
+ target.logger.error(`\u{1F4A5}`, `state`, key, `rejected:`, thrown);
59
59
  }
60
60
  });
61
61
  return future;
@@ -63,23 +63,22 @@ function cacheValue(key, value, subject, store) {
63
63
  target.valueMap.set(key, value);
64
64
  return value;
65
65
  }
66
- var readCachedValue = (key, store) => {
67
- return newest(store).valueMap.get(key);
66
+ var readCachedValue = (key, target) => {
67
+ return target.valueMap.get(key);
68
68
  };
69
- var isValueCached = (key, store) => {
70
- return newest(store).valueMap.has(key);
69
+ var isValueCached = (key, target) => {
70
+ return target.valueMap.has(key);
71
71
  };
72
- var evictCachedValue = (key, store) => {
73
- const core = newest(store);
74
- const currentValue = core.valueMap.get(key);
72
+ var evictCachedValue = (key, target) => {
73
+ const currentValue = target.valueMap.get(key);
75
74
  if (currentValue instanceof Future) {
76
75
  currentValue.cancel();
77
76
  }
78
- if (core.operation.open) {
79
- core.operation.prev.set(key, currentValue);
77
+ if (target.operation.open) {
78
+ target.operation.prev.set(key, currentValue);
80
79
  }
81
- core.valueMap.delete(key);
82
- store.logger.info(`\u{1F5D1}`, `state`, key, `evicted`);
80
+ target.valueMap.delete(key);
81
+ target.logger.info(`\u{1F5D1}`, `state`, key, `evicted`);
83
82
  };
84
83
 
85
84
  // internal/src/read-or-compute-value.ts
@@ -105,17 +104,16 @@ var readOrComputeValue = (state, store) => {
105
104
 
106
105
  // internal/src/operation.ts
107
106
  var openOperation = (token, store) => {
108
- const target = newest(store);
109
- if (target.operation.open) {
107
+ if (store.operation.open) {
110
108
  store.logger.error(
111
109
  `\u274C`,
112
110
  token.type,
113
111
  token.key,
114
- `failed to setState during a setState for "${target.operation.token.key}"`
112
+ `failed to setState during a setState for "${store.operation.token.key}"`
115
113
  );
116
114
  return `rejection`;
117
115
  }
118
- target.operation = {
116
+ store.operation = {
119
117
  open: true,
120
118
  done: /* @__PURE__ */ new Set(),
121
119
  prev: /* @__PURE__ */ new Map(),
@@ -126,25 +124,23 @@ var openOperation = (token, store) => {
126
124
  `\u2B55`,
127
125
  token.type,
128
126
  token.key,
129
- `operation start in store "${store.config.name}"${target.transactionMeta === null ? `` : ` ${target.transactionMeta.phase} "${target.transactionMeta.update.key}"`}`
127
+ `operation start in store "${store.config.name}"${store.transactionMeta === null ? `` : ` ${store.transactionMeta.phase} "${store.transactionMeta.update.key}"`}`
130
128
  );
131
129
  };
132
130
  var closeOperation = (store) => {
133
- const target = newest(store);
134
- if (target.operation.open) {
131
+ if (store.operation.open) {
135
132
  store.logger.info(
136
133
  `\u{1F534}`,
137
- target.operation.token.type,
138
- target.operation.token.key,
134
+ store.operation.token.type,
135
+ store.operation.token.key,
139
136
  `operation done in store "${store.config.name}"`
140
137
  );
141
138
  }
142
- target.operation = { open: false };
143
- store.subject.operationStatus.next(target.operation);
139
+ store.operation = { open: false };
140
+ store.subject.operationStatus.next(store.operation);
144
141
  };
145
142
  var isDone = (key, store) => {
146
- const target = newest(store);
147
- if (!target.operation.open) {
143
+ if (!store.operation.open) {
148
144
  store.logger.warn(
149
145
  `\u{1F41E}`,
150
146
  `unknown`,
@@ -153,11 +149,10 @@ var isDone = (key, store) => {
153
149
  );
154
150
  return true;
155
151
  }
156
- return target.operation.done.has(key);
152
+ return store.operation.done.has(key);
157
153
  };
158
154
  var markDone = (key, store) => {
159
- const target = newest(store);
160
- if (!target.operation.open) {
155
+ if (!store.operation.open) {
161
156
  store.logger.warn(
162
157
  `\u{1F41E}`,
163
158
  `unknown`,
@@ -166,7 +161,7 @@ var markDone = (key, store) => {
166
161
  );
167
162
  return;
168
163
  }
169
- target.operation.done.add(key);
164
+ store.operation.done.add(key);
170
165
  };
171
166
 
172
167
  // internal/src/set-state/become.ts
@@ -272,8 +267,7 @@ var emitUpdate = (state, update, store) => {
272
267
 
273
268
  // internal/src/set-state/evict-downstream.ts
274
269
  var evictDownStream = (atom, store) => {
275
- const target = newest(store);
276
- const downstreamKeys = target.selectorAtoms.getRelatedKeys(atom.key);
270
+ const downstreamKeys = store.selectorAtoms.getRelatedKeys(atom.key);
277
271
  store.logger.info(
278
272
  `\u{1F9F9}`,
279
273
  atom.type,
@@ -282,12 +276,12 @@ var evictDownStream = (atom, store) => {
282
276
  downstreamKeys != null ? downstreamKeys : `to evict`
283
277
  );
284
278
  if (downstreamKeys) {
285
- if (target.operation.open) {
279
+ if (store.operation.open) {
286
280
  store.logger.info(
287
281
  `\u{1F9F9}`,
288
282
  atom.type,
289
283
  atom.key,
290
- `[ ${[...target.operation.done].join(`, `)} ] already done`
284
+ `[ ${[...store.operation.done].join(`, `)} ] already done`
291
285
  );
292
286
  }
293
287
  for (const key of downstreamKeys) {
@@ -344,23 +338,24 @@ var stowUpdate = (state, update, store) => {
344
338
  };
345
339
 
346
340
  // internal/src/set-state/set-atom.ts
347
- var setAtom = (atom, next, store) => {
348
- const target = newest(store);
349
- const oldValue = readOrComputeValue(atom, store);
350
- let newValue = copyMutableIfWithinTransaction(oldValue, atom, store);
341
+ var setAtom = (atom, next, target) => {
342
+ const oldValue = readOrComputeValue(atom, target);
343
+ let newValue = copyMutableIfWithinTransaction(oldValue, atom, target);
351
344
  newValue = become(next)(newValue);
352
- store.logger.info(`\u{1F4DD}`, `atom`, atom.key, `set to`, newValue);
353
- newValue = cacheValue(atom.key, newValue, atom.subject, store);
354
- if (isAtomDefault(atom.key, store)) {
355
- markAtomAsNotDefault(atom.key, store);
345
+ target.logger.info(`\u{1F4DD}`, `atom`, atom.key, `set to`, newValue);
346
+ newValue = cacheValue(atom.key, newValue, atom.subject, target);
347
+ if (isAtomDefault(atom.key, target)) {
348
+ markAtomAsNotDefault(atom.key, target);
356
349
  }
357
- markDone(atom.key, store);
358
- evictDownStream(atom, store);
350
+ markDone(atom.key, target);
351
+ evictDownStream(atom, target);
359
352
  const update = { oldValue, newValue };
360
- if (target.transactionMeta === null || target.transactionMeta.phase === `applying`) {
361
- emitUpdate(atom, update, store);
353
+ if (target.transactionMeta === null) {
354
+ emitUpdate(atom, update, target);
355
+ } else if (target.transactionMeta.phase === `applying` && target.parent) {
356
+ emitUpdate(atom, update, target.parent);
362
357
  } else {
363
- stowUpdate(atom, update, store);
358
+ stowUpdate(atom, update, target);
364
359
  }
365
360
  };
366
361
 
@@ -451,13 +446,29 @@ var Store = class {
451
446
  this.config = __spreadProps(__spreadValues({}, store == null ? void 0 : store.config), {
452
447
  name
453
448
  });
449
+ for (const [, family] of store.families) {
450
+ family.install(this);
451
+ }
452
+ const mutableHelpers = /* @__PURE__ */ new Set();
454
453
  for (const [, atom] of store.atoms) {
454
+ if (mutableHelpers.has(atom.key)) {
455
+ continue;
456
+ }
455
457
  atom.install(this);
458
+ if (`mutable` in atom) {
459
+ const originalJsonToken = getJsonToken(atom);
460
+ const originalUpdateToken = getUpdateToken(atom);
461
+ mutableHelpers.add(originalJsonToken.key);
462
+ mutableHelpers.add(originalUpdateToken.key);
463
+ }
456
464
  }
457
465
  for (const [, selector] of store.readonlySelectors) {
458
466
  selector.install(this);
459
467
  }
460
468
  for (const [, selector] of store.selectors) {
469
+ if (mutableHelpers.has(selector.key)) {
470
+ continue;
471
+ }
461
472
  selector.install(this);
462
473
  }
463
474
  for (const [, tx] of store.transactions) {
@@ -484,13 +495,31 @@ var clearStore = (store) => {
484
495
 
485
496
  // internal/src/store/withdraw.ts
486
497
  function withdraw(token, store) {
487
- var _a, _b, _c, _d;
488
- const target = newest(store);
489
- const state = (_d = (_c = (_b = (_a = target.atoms.get(token.key)) != null ? _a : target.selectors.get(token.key)) != null ? _b : target.readonlySelectors.get(token.key)) != null ? _c : target.transactions.get(token.key)) != null ? _d : target.timelines.get(token.key);
490
- if (state) {
491
- return state;
498
+ let withdrawn;
499
+ let target = store;
500
+ while (target !== null) {
501
+ switch (token.type) {
502
+ case `atom`:
503
+ withdrawn = target.atoms.get(token.key);
504
+ break;
505
+ case `selector`:
506
+ withdrawn = target.selectors.get(token.key);
507
+ break;
508
+ case `readonly_selector`:
509
+ withdrawn = target.readonlySelectors.get(token.key);
510
+ break;
511
+ case `timeline`:
512
+ withdrawn = target.timelines.get(token.key);
513
+ break;
514
+ case `transaction`:
515
+ withdrawn = target.transactions.get(token.key);
516
+ break;
517
+ }
518
+ if (withdrawn) {
519
+ return withdrawn;
520
+ }
521
+ target = target.child;
492
522
  }
493
- return void 0;
494
523
  }
495
524
 
496
525
  // internal/src/store/withdraw-new-family-member.ts
@@ -594,7 +623,6 @@ var updateSelectorAtoms = (selectorKey, dependency, store) => {
594
623
  var registerSelector = (selectorKey, store) => ({
595
624
  get: (dependency) => {
596
625
  const target = newest(store);
597
- const alreadyRegistered = target.selectorGraph.getRelationEntries({ downstreamSelectorKey: selectorKey }).some(([_, { source }]) => source === dependency.key);
598
626
  const dependencyState = withdraw(dependency, store);
599
627
  if (dependencyState === void 0) {
600
628
  throw new Error(
@@ -610,17 +638,15 @@ var registerSelector = (selectorKey, store) => ({
610
638
  dependencyValue,
611
639
  `)`
612
640
  );
613
- if (!alreadyRegistered) {
614
- target.selectorGraph.set(
615
- {
616
- upstreamSelectorKey: dependency.key,
617
- downstreamSelectorKey: selectorKey
618
- },
619
- {
620
- source: dependency.key
621
- }
622
- );
623
- }
641
+ target.selectorGraph.set(
642
+ {
643
+ upstreamSelectorKey: dependency.key,
644
+ downstreamSelectorKey: selectorKey
645
+ },
646
+ {
647
+ source: dependency.key
648
+ }
649
+ );
624
650
  updateSelectorAtoms(selectorKey, dependency, store);
625
651
  return dependencyValue;
626
652
  },
@@ -642,7 +668,7 @@ var createReadWriteSelector = (options, family, store) => {
642
668
  const { get, set } = registerSelector(options.key, store);
643
669
  const getSelf = () => {
644
670
  const value = options.get({ get });
645
- cacheValue(options.key, value, subject, store);
671
+ cacheValue(options.key, value, subject, newest(store));
646
672
  return value;
647
673
  };
648
674
  const setSelf = (next) => {
@@ -732,7 +758,7 @@ function createSelector(options, family, store) {
732
758
  `\u274C`,
733
759
  existingReadonly ? `readonly_selector` : `selector`,
734
760
  options.key,
735
- `Tried to create selector, but it already exists in the store. (Ignore if you are in development using hot module replacement.)`
761
+ `Tried to create selector, but it already exists in the store.`
736
762
  );
737
763
  }
738
764
  if (`set` in options) {
@@ -781,8 +807,9 @@ var recallState = (state, store) => {
781
807
 
782
808
  // internal/src/subscribe/subscribe-to-root-atoms.ts
783
809
  var subscribeToRootAtoms = (state, store) => {
810
+ const target = newest(store);
784
811
  const dependencySubscriptions = `default` in state ? null : traceAllSelectorAtoms(state.key, store).map((atomKey) => {
785
- const atom = store.atoms.get(atomKey);
812
+ const atom = target.atoms.get(atomKey);
786
813
  if (atom === void 0) {
787
814
  throw new Error(
788
815
  `Atom "${atomKey}", a dependency of selector "${state.key}", not found in store "${store.config.name}".`
@@ -802,8 +829,8 @@ var subscribeToRootAtoms = (state, store) => {
802
829
  `->`,
803
830
  atomChange.newValue
804
831
  );
805
- const oldValue = recallState(state, store);
806
- const newValue = readOrComputeValue(state, store);
832
+ const oldValue = recallState(state, target);
833
+ const newValue = readOrComputeValue(state, target);
807
834
  store.logger.info(
808
835
  `\u2728`,
809
836
  state.type,
@@ -819,8 +846,11 @@ var subscribeToRootAtoms = (state, store) => {
819
846
  });
820
847
  return dependencySubscriptions;
821
848
  };
849
+
850
+ // internal/src/subscribe/subscribe-to-state.ts
822
851
  function subscribeToState(token, handleUpdate, key, store) {
823
- const state = withdraw$1(token, store);
852
+ var _a;
853
+ const state = (_a = withdraw(token, store)) != null ? _a : withdrawNewFamilyMember(token, store);
824
854
  if (state === void 0) {
825
855
  throw new Error(
826
856
  `State "${token.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`
@@ -828,7 +858,7 @@ function subscribeToState(token, handleUpdate, key, store) {
828
858
  }
829
859
  const unsubFunction = state.subject.subscribe(key, handleUpdate);
830
860
  store.logger.info(`\u{1F440}`, state.type, state.key, `Adding subscription "${key}"`);
831
- const dependencyUnsubFunctions = state.type !== `atom` ? subscribeToRootAtoms$1(state, store) : null;
861
+ const dependencyUnsubFunctions = state.type !== `atom` ? subscribeToRootAtoms(state, store) : null;
832
862
  const unsubscribe = dependencyUnsubFunctions === null ? () => {
833
863
  store.logger.info(
834
864
  `\u{1F648}`,
@@ -905,6 +935,7 @@ var Tracker = class {
905
935
  target.trackers.set(mutableState.key, this);
906
936
  }
907
937
  initializeState(mutableState, store) {
938
+ var _a;
908
939
  const latestUpdateStateKey = `*${mutableState.key}`;
909
940
  store.atoms.delete(latestUpdateStateKey);
910
941
  store.valueMap.delete(latestUpdateStateKey);
@@ -912,7 +943,7 @@ var Tracker = class {
912
943
  key: `*${mutableState.family.key}`,
913
944
  subKey: mutableState.family.subKey
914
945
  } : void 0;
915
- const latestUpdateState = createAtom(
946
+ const latestUpdateState = createRegularAtom(
916
947
  {
917
948
  key: latestUpdateStateKey,
918
949
  default: null
@@ -920,7 +951,7 @@ var Tracker = class {
920
951
  familyMetaData,
921
952
  store
922
953
  );
923
- if (store.parent) {
954
+ if ((_a = store.parent) == null ? void 0 : _a.valueMap.has(latestUpdateStateKey)) {
924
955
  const parentValue = store.parent.valueMap.get(latestUpdateStateKey);
925
956
  store.valueMap.set(latestUpdateStateKey, parentValue);
926
957
  }
@@ -932,11 +963,11 @@ var Tracker = class {
932
963
  this.unsubscribeFromInnerValue = originalInnerValue.subscribe(
933
964
  `tracker:${store.config.name}:${target.transactionMeta === null ? `main` : target.transactionMeta.update.key}`,
934
965
  (update) => {
935
- const unsubscribe = store.subject.operationStatus.subscribe(
966
+ const unsubscribe = target.subject.operationStatus.subscribe(
936
967
  mutableState.key,
937
968
  () => {
938
969
  unsubscribe();
939
- setState(latestUpdateState, update, store);
970
+ setState(latestUpdateState, update, target);
940
971
  }
941
972
  );
942
973
  }
@@ -1023,14 +1054,14 @@ var Tracker = class {
1023
1054
  };
1024
1055
 
1025
1056
  // internal/src/mutable/create-mutable-atom.ts
1026
- function createMutableAtom(options, store) {
1057
+ function createMutableAtom(options, family, store) {
1027
1058
  store.logger.info(
1028
1059
  `\u{1F527}`,
1029
1060
  `atom`,
1030
1061
  options.key,
1031
1062
  `creating in store "${store.config.name}"`
1032
1063
  );
1033
- const coreState = createAtom(options, void 0, store);
1064
+ const coreState = createRegularAtom(options, family, store);
1034
1065
  new Tracker(coreState, store);
1035
1066
  const jsonState = selectJson(coreState, options, store);
1036
1067
  const target = newest(store);
@@ -1047,7 +1078,7 @@ function createMutableAtom(options, store) {
1047
1078
  );
1048
1079
  return coreState;
1049
1080
  }
1050
- function createAtomFamily(options, store) {
1081
+ function createRegularAtomFamily(options, store) {
1051
1082
  const subject = new Subject();
1052
1083
  const atomFamily = Object.assign(
1053
1084
  (key) => {
@@ -1066,7 +1097,16 @@ function createAtomFamily(options, store) {
1066
1097
  if (options.effects) {
1067
1098
  individualOptions.effects = options.effects(key);
1068
1099
  }
1069
- token = createAtom(individualOptions, family, store);
1100
+ if (`mutable` in options) {
1101
+ const mutableOptions = __spreadProps(__spreadValues({}, individualOptions), {
1102
+ mutable: true,
1103
+ toJson: options.toJson,
1104
+ fromJson: options.fromJson
1105
+ });
1106
+ token = createMutableAtom(mutableOptions, family, store);
1107
+ } else {
1108
+ token = createRegularAtom(individualOptions, family, store);
1109
+ }
1070
1110
  subject.next(token);
1071
1111
  }
1072
1112
  return token;
@@ -1074,7 +1114,8 @@ function createAtomFamily(options, store) {
1074
1114
  {
1075
1115
  key: options.key,
1076
1116
  type: `atom_family`,
1077
- subject
1117
+ subject,
1118
+ install: (store2) => createRegularAtomFamily(options, store2)
1078
1119
  }
1079
1120
  );
1080
1121
  if (`mutable` in options && typeof options.mutable === `boolean`) {
@@ -1084,6 +1125,14 @@ function createAtomFamily(options, store) {
1084
1125
  target.families.set(options.key, atomFamily);
1085
1126
  return atomFamily;
1086
1127
  }
1128
+
1129
+ // internal/src/families/create-atom-family.ts
1130
+ function createAtomFamily(options, store) {
1131
+ if (`mutable` in options) {
1132
+ return createMutableAtomFamily(options, store);
1133
+ }
1134
+ return createRegularAtomFamily(options, store);
1135
+ }
1087
1136
  function createReadonlySelectorFamily(options, store) {
1088
1137
  const subject = new Subject();
1089
1138
  return Object.assign(
@@ -1108,7 +1157,8 @@ function createReadonlySelectorFamily(options, store) {
1108
1157
  {
1109
1158
  key: options.key,
1110
1159
  type: `readonly_selector_family`,
1111
- subject
1160
+ subject,
1161
+ install: (store2) => createReadonlySelectorFamily(options, store2)
1112
1162
  }
1113
1163
  );
1114
1164
  }
@@ -1142,7 +1192,9 @@ function createSelectorFamily(options, store) {
1142
1192
  },
1143
1193
  {
1144
1194
  key: options.key,
1145
- type: `selector_family`
1195
+ type: `selector_family`,
1196
+ subject,
1197
+ install: (store2) => createSelectorFamily(options, store2)
1146
1198
  }
1147
1199
  );
1148
1200
  target.families.set(options.key, selectorFamily);
@@ -1152,7 +1204,7 @@ function createSelectorFamily(options, store) {
1152
1204
  // internal/src/mutable/tracker-family.ts
1153
1205
  var FamilyTracker = class {
1154
1206
  constructor(findMutableState, store) {
1155
- this.findLatestUpdateState = createAtomFamily(
1207
+ this.findLatestUpdateState = createRegularAtomFamily(
1156
1208
  {
1157
1209
  key: `*${findMutableState.key}`,
1158
1210
  default: null
@@ -1186,7 +1238,7 @@ var FamilyTracker = class {
1186
1238
  // internal/src/mutable/create-mutable-atom-family.ts
1187
1239
  function createMutableAtomFamily(options, store) {
1188
1240
  const coreFamily = Object.assign(
1189
- createAtomFamily(options, store),
1241
+ createRegularAtomFamily(options, store),
1190
1242
  options
1191
1243
  );
1192
1244
  selectJsonFamily(coreFamily, options);
@@ -1257,13 +1309,9 @@ var markAtomAsNotDefault = (key, store) => {
1257
1309
  core.atomsThatAreDefault = new Set(newest(store).atomsThatAreDefault);
1258
1310
  core.atomsThatAreDefault.delete(key);
1259
1311
  };
1260
- var isSelectorDefault = (key, store) => {
1261
- const rootKeys = traceAllSelectorAtoms(key, store);
1262
- return rootKeys.every((rootKey) => isAtomDefault(rootKey, store));
1263
- };
1264
1312
 
1265
- // internal/src/atom/create-atom.ts
1266
- function createAtom(options, family, store) {
1313
+ // internal/src/atom/create-regular-atom.ts
1314
+ function createRegularAtom(options, family, store) {
1267
1315
  store.logger.info(
1268
1316
  `\u{1F528}`,
1269
1317
  `atom`,
@@ -1277,13 +1325,12 @@ function createAtom(options, family, store) {
1277
1325
  `\u274C`,
1278
1326
  `atom`,
1279
1327
  options.key,
1280
- `Tried to create atom, but it already exists in the store.`,
1281
- `(Ignore if you are in development using hot module replacement.)`
1328
+ `Tried to create atom, but it already exists in the store.`
1282
1329
  );
1283
1330
  return deposit(existing);
1284
1331
  }
1285
1332
  const subject = new Subject();
1286
- const newAtom = __spreadValues(__spreadProps(__spreadValues({}, options), {
1333
+ const newAtom = __spreadProps(__spreadValues({}, options), {
1287
1334
  type: `atom`,
1288
1335
  install: (store2) => {
1289
1336
  store2.logger.info(
@@ -1292,17 +1339,20 @@ function createAtom(options, family, store) {
1292
1339
  options.key,
1293
1340
  `installing in store "${store2.config.name}"`
1294
1341
  );
1295
- return `mutable` in options ? createMutableAtom(options, store2) : createAtom(options, void 0, store2);
1342
+ return `mutable` in options ? createMutableAtom(options, family, store2) : createRegularAtom(options, family, store2);
1296
1343
  },
1297
1344
  subject
1298
- }), family && { family });
1345
+ });
1346
+ if (family) {
1347
+ newAtom.family = family;
1348
+ }
1299
1349
  let initialValue = options.default;
1300
1350
  if (options.default instanceof Function) {
1301
1351
  initialValue = options.default();
1302
1352
  }
1303
1353
  target.atoms.set(newAtom.key, newAtom);
1304
1354
  markAtomAsDefault(options.key, store);
1305
- cacheValue(options.key, initialValue, subject, store);
1355
+ cacheValue(options.key, initialValue, subject, target);
1306
1356
  const token = deposit(newAtom);
1307
1357
  if (options.effects) {
1308
1358
  let effectIndex = 0;
@@ -1327,6 +1377,14 @@ function createAtom(options, family, store) {
1327
1377
  return token;
1328
1378
  }
1329
1379
 
1380
+ // internal/src/atom/create-atom.ts
1381
+ function createAtom(options, family, store) {
1382
+ if (`mutable` in options) {
1383
+ return createMutableAtom(options, family, store);
1384
+ }
1385
+ return createRegularAtom(options, family, store);
1386
+ }
1387
+
1330
1388
  // internal/src/atom/delete-atom.ts
1331
1389
  function deleteAtom2(atomToken, store) {
1332
1390
  var _a, _b;
@@ -1608,26 +1666,10 @@ var addAtomToTimeline = (atomToken, tl, store) => {
1608
1666
  };
1609
1667
 
1610
1668
  // internal/src/mutable/is-mutable.ts
1611
- function isMutable(atomOrTokenOrFamily, store) {
1669
+ function isMutable(atomOrTokenOrFamily) {
1612
1670
  if (`mutable` in atomOrTokenOrFamily) {
1613
1671
  return atomOrTokenOrFamily.mutable;
1614
1672
  }
1615
- if (atomOrTokenOrFamily.type === `atom_family`) {
1616
- return false;
1617
- }
1618
- if (`default` in atomOrTokenOrFamily) {
1619
- return false;
1620
- }
1621
- if (!store) {
1622
- throw new Error(`Cannot check mutability without a store`);
1623
- }
1624
- const atom = withdraw(atomOrTokenOrFamily, store);
1625
- if (!atom) {
1626
- throw new Error(`Cannot check mutability without an atom`);
1627
- }
1628
- if (`mutable` in atom) {
1629
- return atom.mutable;
1630
- }
1631
1673
  return false;
1632
1674
  }
1633
1675
 
@@ -1888,8 +1930,27 @@ var applyTransaction = (output, store) => {
1888
1930
  `Applying transaction with ${updates.length} updates:`,
1889
1931
  updates
1890
1932
  );
1933
+ for (const tracker of child.trackers.values()) {
1934
+ const mutableKey = tracker.mutableState.key;
1935
+ if (!parent.atoms.has(mutableKey)) {
1936
+ const atom = child.atoms.get(mutableKey);
1937
+ atom == null ? void 0 : atom.install(parent);
1938
+ }
1939
+ }
1940
+ for (const atom of child.atoms.values()) {
1941
+ if (!parent.atoms.has(atom.key)) {
1942
+ parent.atoms.set(atom.key, atom);
1943
+ parent.valueMap.set(atom.key, atom.default);
1944
+ parent.logger.info(
1945
+ `\u{1F528}`,
1946
+ `transaction`,
1947
+ child.transactionMeta.update.key,
1948
+ `Adding atom "${atom.key}"`
1949
+ );
1950
+ }
1951
+ }
1952
+ ingestTransactionUpdate(child.transactionMeta.update, parent, child);
1891
1953
  if (parent.transactionMeta === null) {
1892
- ingestTransactionUpdate(child.transactionMeta.update, parent, child);
1893
1954
  const myTransaction = withdraw(
1894
1955
  { key: child.transactionMeta.update.key, type: `transaction` },
1895
1956
  store
@@ -1902,7 +1963,6 @@ var applyTransaction = (output, store) => {
1902
1963
  `Finished applying transaction.`
1903
1964
  );
1904
1965
  } else {
1905
- ingestTransactionUpdate(child.transactionMeta.update, parent, child);
1906
1966
  parent.transactionMeta.update.updates.push(child.transactionMeta.update);
1907
1967
  }
1908
1968
  parent.subject.transactionApplying.next(null);
@@ -1911,23 +1971,14 @@ var applyTransaction = (output, store) => {
1911
1971
  // internal/src/transaction/build-transaction.ts
1912
1972
  var buildTransaction = (key, params, store) => {
1913
1973
  const parent = newest(store);
1914
- parent.child = {
1974
+ const child = {
1915
1975
  parent,
1916
1976
  child: null,
1917
1977
  subject: parent.subject,
1918
1978
  loggers: parent.loggers,
1919
1979
  logger: parent.logger,
1920
1980
  config: parent.config,
1921
- transactionMeta: {
1922
- phase: `building`,
1923
- time: Date.now(),
1924
- update: {
1925
- key,
1926
- updates: [],
1927
- params,
1928
- output: void 0
1929
- }
1930
- },
1981
+ transactionMeta: null,
1931
1982
  atoms: new LazyMap(parent.atoms),
1932
1983
  atomsThatAreDefault: new Set(parent.atomsThatAreDefault),
1933
1984
  families: new LazyMap(parent.families),
@@ -1944,6 +1995,22 @@ var buildTransaction = (key, params, store) => {
1944
1995
  selectors: new LazyMap(parent.selectors),
1945
1996
  valueMap: new LazyMap(parent.valueMap)
1946
1997
  };
1998
+ child.transactionMeta = {
1999
+ phase: `building`,
2000
+ time: Date.now(),
2001
+ update: {
2002
+ key,
2003
+ updates: [],
2004
+ params,
2005
+ output: void 0
2006
+ },
2007
+ transactors: {
2008
+ get: (token) => getState$1(token, child),
2009
+ set: (token, value) => setState$1(token, value, child),
2010
+ run: (token) => runTransaction(token, child)
2011
+ }
2012
+ };
2013
+ parent.child = child;
1947
2014
  store.logger.info(
1948
2015
  `\u{1F6EB}`,
1949
2016
  `transaction`,
@@ -1952,6 +2019,8 @@ var buildTransaction = (key, params, store) => {
1952
2019
  params
1953
2020
  );
1954
2021
  };
2022
+
2023
+ // internal/src/transaction/create-transaction.ts
1955
2024
  function createTransaction(options, store) {
1956
2025
  const newTransaction = {
1957
2026
  key: options.key,
@@ -1959,18 +2028,13 @@ function createTransaction(options, store) {
1959
2028
  run: (...params) => {
1960
2029
  buildTransaction(options.key, params, store);
1961
2030
  try {
1962
- const output = options.do(
1963
- {
1964
- get: (token2) => getState(token2, store),
1965
- set: (token2, value) => setState(token2, value, store),
1966
- run: (token2) => runTransaction(token2, store)
1967
- },
1968
- ...params
1969
- );
1970
- applyTransaction(output, store);
2031
+ const target2 = newest(store);
2032
+ const { transactors } = target2.transactionMeta;
2033
+ const output = options.do(transactors, ...params);
2034
+ applyTransaction(output, target2);
1971
2035
  return output;
1972
2036
  } catch (thrown) {
1973
- abortTransaction(store);
2037
+ abortTransaction(target);
1974
2038
  store.logger.warn(`\u{1F4A5}`, `transaction`, options.key, `caught:`, thrown);
1975
2039
  throw thrown;
1976
2040
  }
@@ -1984,46 +2048,10 @@ function createTransaction(options, store) {
1984
2048
  store.subject.transactionCreation.next(token);
1985
2049
  return token;
1986
2050
  }
1987
- var redoTransactionUpdate = (transactionUpdate, store) => {
1988
- store.logger.info(`\u23ED\uFE0F`, `transaction`, transactionUpdate.key, `Redo`);
1989
- for (const update of transactionUpdate.updates) {
1990
- if (`newValue` in update) {
1991
- const { key, newValue } = update;
1992
- const token = { key, type: `atom` };
1993
- const state = withdraw(token, store);
1994
- if (state === void 0) {
1995
- throw new Error(
1996
- `State "${token.key}" not found in this store. This is surprising, because we are navigating the history of the store.`
1997
- );
1998
- }
1999
- setState(state, newValue, store);
2000
- } else {
2001
- redoTransactionUpdate(update, store);
2002
- }
2003
- }
2004
- };
2005
- var undoTransactionUpdate = (transactionUpdate, store) => {
2006
- store.logger.info(`\u23EE\uFE0F`, `transaction`, transactionUpdate.key, `Undo`);
2007
- for (const update of transactionUpdate.updates.reverse()) {
2008
- if (`newValue` in update) {
2009
- const { key, newValue } = update;
2010
- const token = { key, type: `atom` };
2011
- const state = withdraw(token, store);
2012
- if (state === void 0) {
2013
- throw new Error(
2014
- `State "${token.key}" not found in this store. This is surprising, because we are navigating the history of the store.`
2015
- );
2016
- }
2017
- setState(state, newValue, store);
2018
- } else {
2019
- undoTransactionUpdate(update, store);
2020
- }
2021
- }
2022
- };
2023
2051
 
2024
2052
  // internal/src/transaction/index.ts
2025
2053
  var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
2026
2054
 
2027
- export { FamilyTracker, Future, IMPLICIT, LazyMap, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, addAtomToTimeline, applyTransaction, become, buildTransaction, cacheValue, clearStore, closeOperation, createAtom, createAtomFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelectorFamily, createSelector, createSelectorFamily, createTimeline, createTransaction, deleteAtom2 as deleteAtom, deleteSelector, deposit, eldest, evictCachedValue, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getUpdateFamily, getUpdateToken, isAtomDefault, isAtomKey, isDone, isReadonlySelectorKey, isSelectorDefault, isSelectorKey, isStateKey, isTransceiver, isValueCached, markAtomAsDefault, markAtomAsNotDefault, markDone, newest, openOperation, readCachedValue, readOrComputeValue, redoTransactionUpdate, registerSelector, setAtomOrSelector, subscribeToRootAtoms, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, undoTransactionUpdate, updateSelectorAtoms, withdraw, withdrawNewFamilyMember };
2055
+ export { FamilyTracker, Future, IMPLICIT, LazyMap, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, addAtomToTimeline, applyTransaction, become, buildTransaction, cacheValue, clearStore, closeOperation, createAtom, createAtomFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelectorFamily, createRegularAtom, createRegularAtomFamily, createSelector, createSelectorFamily, createTimeline, createTransaction, deleteAtom2 as deleteAtom, deleteSelector, deposit, eldest, evictCachedValue, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getUpdateFamily, getUpdateToken, isAtomDefault, isAtomKey, isDone, isReadonlySelectorKey, isSelectorKey, isStateKey, isTransceiver, isValueCached, markAtomAsDefault, markAtomAsNotDefault, markDone, newest, openOperation, readCachedValue, readOrComputeValue, registerSelector, setAtomOrSelector, subscribeToRootAtoms, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, updateSelectorAtoms, withdraw, withdrawNewFamilyMember };
2028
2056
  //# sourceMappingURL=out.js.map
2029
2057
  //# sourceMappingURL=index.js.map