atom.io 0.16.1 → 0.16.3

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 (99) hide show
  1. package/data/dist/index.cjs +31 -14
  2. package/data/dist/index.cjs.map +1 -1
  3. package/data/dist/index.js +31 -14
  4. package/data/dist/index.js.map +1 -1
  5. package/data/src/join.ts +31 -14
  6. package/dist/chunk-H4Q5FTPZ.js +11 -0
  7. package/dist/chunk-H4Q5FTPZ.js.map +1 -0
  8. package/dist/index.cjs +7 -14
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.ts +8 -7
  11. package/dist/index.js +8 -14
  12. package/dist/index.js.map +1 -1
  13. package/internal/dist/index.cjs +240 -193
  14. package/internal/dist/index.cjs.map +1 -1
  15. package/internal/dist/index.d.ts +30 -9
  16. package/internal/dist/index.js +233 -194
  17. package/internal/dist/index.js.map +1 -1
  18. package/internal/src/families/find-in-store.ts +74 -0
  19. package/internal/src/families/index.ts +1 -0
  20. package/internal/src/ingest-updates/ingest-transaction-update.ts +1 -0
  21. package/internal/src/mutable/tracker.ts +37 -32
  22. package/internal/src/mutable/transceiver.ts +1 -1
  23. package/internal/src/not-found-error.ts +14 -3
  24. package/internal/src/operation.ts +2 -1
  25. package/internal/src/selector/create-writable-selector.ts +2 -1
  26. package/internal/src/selector/register-selector.ts +5 -4
  27. package/internal/src/set-state/set-atom.ts +23 -6
  28. package/internal/src/set-state/stow-update.ts +2 -4
  29. package/internal/src/store/store.ts +13 -4
  30. package/internal/src/timeline/add-atom-to-timeline.ts +5 -5
  31. package/internal/src/transaction/abort-transaction.ts +2 -1
  32. package/internal/src/transaction/apply-transaction.ts +5 -3
  33. package/internal/src/transaction/build-transaction.ts +17 -10
  34. package/internal/src/transaction/create-transaction.ts +2 -3
  35. package/internal/src/transaction/index.ts +3 -2
  36. package/internal/src/transaction/is-root-store.ts +23 -0
  37. package/package.json +10 -10
  38. package/react/dist/index.cjs +27 -21
  39. package/react/dist/index.cjs.map +1 -1
  40. package/react/dist/index.d.ts +8 -2
  41. package/react/dist/index.js +27 -21
  42. package/react/dist/index.js.map +1 -1
  43. package/react/src/index.ts +4 -1
  44. package/react/src/use-i.ts +36 -0
  45. package/react/src/use-json.ts +38 -0
  46. package/react/src/use-o.ts +34 -0
  47. package/react/src/use-tl.ts +45 -0
  48. package/realtime-client/dist/index.cjs +163 -62
  49. package/realtime-client/dist/index.cjs.map +1 -1
  50. package/realtime-client/dist/index.d.ts +10 -6
  51. package/realtime-client/dist/index.js +153 -60
  52. package/realtime-client/dist/index.js.map +1 -1
  53. package/realtime-client/src/index.ts +2 -1
  54. package/realtime-client/src/pull-state.ts +4 -3
  55. package/realtime-client/src/{realtime-client-store.ts → realtime-client-stores/client-main-store.ts} +0 -8
  56. package/realtime-client/src/realtime-client-stores/client-sync-store.ts +15 -0
  57. package/realtime-client/src/realtime-client-stores/index.ts +2 -0
  58. package/realtime-client/src/sync-server-action.ts +131 -39
  59. package/realtime-client/src/sync-state.ts +19 -0
  60. package/realtime-react/dist/index.cjs +43 -26
  61. package/realtime-react/dist/index.cjs.map +1 -1
  62. package/realtime-react/dist/index.d.ts +3 -1
  63. package/realtime-react/dist/index.js +41 -25
  64. package/realtime-react/dist/index.js.map +1 -1
  65. package/realtime-react/src/index.ts +1 -0
  66. package/realtime-react/src/on-mount.ts +3 -21
  67. package/realtime-react/src/use-realtime-service.ts +1 -1
  68. package/realtime-react/src/use-server-action.ts +1 -1
  69. package/realtime-react/src/use-single-effect.ts +29 -0
  70. package/realtime-react/src/use-sync-server-action.ts +5 -8
  71. package/realtime-react/src/use-sync.ts +17 -0
  72. package/realtime-server/dist/index.cjs +242 -48
  73. package/realtime-server/dist/index.cjs.map +1 -1
  74. package/realtime-server/dist/index.d.ts +147 -9
  75. package/realtime-server/dist/index.js +232 -51
  76. package/realtime-server/dist/index.js.map +1 -1
  77. package/realtime-server/src/index.ts +2 -0
  78. package/realtime-server/src/realtime-action-receiver.ts +4 -3
  79. package/realtime-server/src/realtime-action-synchronizer.ts +100 -13
  80. package/realtime-server/src/realtime-family-provider.ts +10 -6
  81. package/realtime-server/src/realtime-mutable-family-provider.ts +15 -18
  82. package/realtime-server/src/realtime-mutable-provider.ts +1 -0
  83. package/realtime-server/src/realtime-server-stores/index.ts +2 -0
  84. package/realtime-server/src/realtime-server-stores/server-sync-store.ts +115 -0
  85. package/realtime-server/src/realtime-server-stores/server-user-store.ts +45 -0
  86. package/realtime-server/src/realtime-state-provider.ts +16 -8
  87. package/realtime-server/src/realtime-state-receiver.ts +1 -0
  88. package/realtime-server/src/realtime-state-synchronizer.ts +23 -0
  89. package/realtime-testing/dist/index.cjs +65 -26
  90. package/realtime-testing/dist/index.cjs.map +1 -1
  91. package/realtime-testing/dist/index.d.ts +11 -7
  92. package/realtime-testing/dist/index.js +64 -26
  93. package/realtime-testing/dist/index.js.map +1 -1
  94. package/realtime-testing/src/setup-realtime-test.tsx +83 -43
  95. package/src/find-state.ts +8 -16
  96. package/src/logger.ts +16 -11
  97. package/src/transaction.ts +4 -4
  98. package/react/src/store-hooks.ts +0 -87
  99. package/realtime-server/src/realtime-server-store.ts +0 -39
@@ -1,7 +1,8 @@
1
1
  import { Junction } from '../../dist/chunk-NYTGCPHB.js';
2
+ import { isChildStore, isRootStore } from '../../dist/chunk-H4Q5FTPZ.js';
2
3
  import { __spreadValues, __spreadProps } from '../../dist/chunk-PZLG2HP3.js';
3
- import { AtomIOLogger, findInStore, getState, setState, runTransaction } from 'atom.io';
4
- import { selectJson, stringifyJson, parseJson, selectJsonFamily } from 'atom.io/json';
4
+ import { AtomIOLogger, getState, setState, runTransaction } from 'atom.io';
5
+ import { stringifyJson, selectJson, parseJson, selectJsonFamily } from 'atom.io/json';
5
6
  import { withdraw as withdraw$1 } from 'atom.io/internal';
6
7
 
7
8
  // internal/src/lineage.ts
@@ -91,11 +92,15 @@ var Store = class {
91
92
  selectorCreation: new Subject(),
92
93
  transactionCreation: new Subject(),
93
94
  timelineCreation: new Subject(),
94
- transactionApplying: new StatefulSubject(null),
95
+ transactionApplying: new StatefulSubject(
96
+ null
97
+ ),
95
98
  operationClose: new Subject()
96
99
  };
97
100
  this.operation = { open: false };
98
- this.transactionMeta = null;
101
+ this.transactionMeta = {
102
+ epoch: -1
103
+ };
99
104
  this.config = {
100
105
  name: `IMPLICIT_STORE`
101
106
  };
@@ -119,7 +124,7 @@ var Store = class {
119
124
  if (store !== null) {
120
125
  this.valueMap = new Map(store == null ? void 0 : store.valueMap);
121
126
  this.operation = __spreadValues({}, store == null ? void 0 : store.operation);
122
- this.transactionMeta = null;
127
+ this.transactionMeta = __spreadValues({}, store == null ? void 0 : store.transactionMeta);
123
128
  this.config = __spreadProps(__spreadValues({}, store == null ? void 0 : store.config), {
124
129
  name
125
130
  });
@@ -332,6 +337,150 @@ var readOrComputeValue = (state, target) => {
332
337
  );
333
338
  return state.default instanceof Function ? state.default() : state.default;
334
339
  };
340
+ function createRegularAtomFamily(options, store) {
341
+ const subject = new Subject();
342
+ const atomFamily = Object.assign(
343
+ (key) => {
344
+ const subKey = stringifyJson(key);
345
+ const family = { key: options.key, subKey };
346
+ const fullKey = `${options.key}(${subKey})`;
347
+ const existing = withdraw({ key: fullKey, type: `atom` }, store);
348
+ let token;
349
+ if (existing) {
350
+ token = deposit(existing);
351
+ } else {
352
+ const individualOptions = {
353
+ key: fullKey,
354
+ default: options.default instanceof Function ? options.default(key) : options.default
355
+ };
356
+ if (options.effects) {
357
+ individualOptions.effects = options.effects(key);
358
+ }
359
+ token = createRegularAtom(individualOptions, family, store);
360
+ subject.next(token);
361
+ }
362
+ return token;
363
+ },
364
+ {
365
+ key: options.key,
366
+ type: `atom_family`,
367
+ subject,
368
+ install: (store2) => createRegularAtomFamily(options, store2)
369
+ }
370
+ );
371
+ const target = newest(store);
372
+ target.families.set(options.key, atomFamily);
373
+ return atomFamily;
374
+ }
375
+
376
+ // internal/src/families/create-atom-family.ts
377
+ function createAtomFamily(options, store) {
378
+ const isMutable2 = `mutable` in options;
379
+ if (isMutable2) {
380
+ return createMutableAtomFamily(options, store);
381
+ }
382
+ return createRegularAtomFamily(options, store);
383
+ }
384
+ function createReadonlySelectorFamily(options, store) {
385
+ const subject = new Subject();
386
+ const readonlySelectorFamily = Object.assign(
387
+ (key) => {
388
+ const target = newest(store);
389
+ const subKey = stringifyJson(key);
390
+ const family = { key: options.key, subKey };
391
+ const fullKey = `${options.key}(${subKey})`;
392
+ const existing = target.readonlySelectors.get(fullKey);
393
+ if (existing) {
394
+ return deposit(existing);
395
+ }
396
+ return createReadonlySelector(
397
+ {
398
+ key: fullKey,
399
+ get: options.get(key)
400
+ },
401
+ family,
402
+ store
403
+ );
404
+ },
405
+ {
406
+ key: options.key,
407
+ type: `readonly_selector_family`,
408
+ subject,
409
+ install: (store2) => createReadonlySelectorFamily(options, store2)
410
+ }
411
+ );
412
+ store.families.set(options.key, readonlySelectorFamily);
413
+ return readonlySelectorFamily;
414
+ }
415
+ function createWritableSelectorFamily(options, store) {
416
+ const subject = new Subject();
417
+ const selectorFamily = Object.assign(
418
+ (key) => {
419
+ const subKey = stringifyJson(key);
420
+ const family = { key: options.key, subKey };
421
+ const fullKey = `${options.key}(${subKey})`;
422
+ const existing = store.selectors.get(fullKey);
423
+ if (existing) {
424
+ return deposit(existing);
425
+ }
426
+ const token = createWritableSelector(
427
+ {
428
+ key: fullKey,
429
+ get: options.get(key),
430
+ set: options.set(key)
431
+ },
432
+ family,
433
+ store
434
+ );
435
+ subject.next(token);
436
+ return token;
437
+ },
438
+ {
439
+ key: options.key,
440
+ type: `selector_family`,
441
+ subject,
442
+ install: (store2) => createWritableSelectorFamily(options, store2)
443
+ }
444
+ );
445
+ store.families.set(options.key, selectorFamily);
446
+ return selectorFamily;
447
+ }
448
+
449
+ // internal/src/families/create-selector-family.ts
450
+ function createSelectorFamily(options, store) {
451
+ const isWritable = `set` in options;
452
+ if (isWritable) {
453
+ return createWritableSelectorFamily(options, store);
454
+ }
455
+ return createReadonlySelectorFamily(options, store);
456
+ }
457
+
458
+ // internal/src/not-found-error.ts
459
+ var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
460
+ function prettyPrintTokenType(token) {
461
+ if (token.type === `readonly_selector`) {
462
+ return `Readonly Selector`;
463
+ }
464
+ return capitalize(token.type);
465
+ }
466
+ var NotFoundError = class extends Error {
467
+ constructor(token, store) {
468
+ super(
469
+ `${prettyPrintTokenType(token)} "${token.key}" not found in store "${store.config.name}".`
470
+ );
471
+ }
472
+ };
473
+
474
+ // internal/src/families/find-in-store.ts
475
+ function findInStore(token, key, store) {
476
+ const familyKey = token.key;
477
+ const family = store.families.get(familyKey);
478
+ if (family === void 0) {
479
+ throw new NotFoundError(token, store);
480
+ }
481
+ const state = family(key);
482
+ return state;
483
+ }
335
484
 
336
485
  // internal/src/set-state/become.ts
337
486
  var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(
@@ -360,7 +509,7 @@ var openOperation = (token, store) => {
360
509
  `\u2B55`,
361
510
  token.type,
362
511
  token.key,
363
- `operation start in store "${store.config.name}"${store.transactionMeta === null ? `` : ` ${store.transactionMeta.phase} "${store.transactionMeta.update.key}"`}`
512
+ `operation start in store "${store.config.name}"${!isChildStore(store) ? `` : ` ${store.transactionMeta.phase} "${store.transactionMeta.update.key}"`}`
364
513
  );
365
514
  };
366
515
  var closeOperation = (store) => {
@@ -458,7 +607,7 @@ function shouldUpdateBeStowed(key, update) {
458
607
  var stowUpdate = (state, update, store) => {
459
608
  const { key } = state;
460
609
  const target = newest(store);
461
- if (target.transactionMeta === null || target.transactionMeta.phase !== `building`) {
610
+ if (!isChildStore(target) || target.transactionMeta.phase !== `building`) {
462
611
  store.logger.error(
463
612
  `\u{1F41E}`,
464
613
  `atom`,
@@ -501,14 +650,26 @@ var setAtom = (atom, next, target) => {
501
650
  markDone(atom.key, target);
502
651
  evictDownStream(atom, target);
503
652
  const update = { oldValue, newValue };
504
- if (target.transactionMeta === null) {
653
+ if (isRootStore(target)) {
505
654
  emitUpdate(atom, update, target);
506
- } else if (target.on.transactionApplying && target.parent) {
507
- stowUpdate(atom, update, target);
508
- if (atom.key.startsWith(`*`)) {
655
+ } else if (target.parent) {
656
+ if (target.on.transactionApplying.state === null) {
657
+ stowUpdate(atom, update, target);
658
+ } else if (atom.key.startsWith(`*`)) {
509
659
  const mutableKey = atom.key.slice(1);
510
- const mutable = target.valueMap.get(mutableKey);
511
- mutable.do(update.newValue);
660
+ const mutableAtom = target.atoms.get(mutableKey);
661
+ let mutable = target.valueMap.get(mutableKey);
662
+ mutable = copyMutableIfWithinTransaction(mutable, mutableAtom, target);
663
+ const output = mutable.do(update.newValue);
664
+ if (output !== null) {
665
+ target.logger.warn(
666
+ `\u274C`,
667
+ `mutable_atom`,
668
+ mutableKey,
669
+ `could not be updated.`,
670
+ typeof output === `number` ? `Expected update number ${mutable.cacheUpdateNumber + 1}, but got ${output}` : output
671
+ );
672
+ }
512
673
  }
513
674
  }
514
675
  };
@@ -606,11 +767,12 @@ var updateSelectorAtoms = (selectorKey, dependency, store) => {
606
767
  // internal/src/selector/register-selector.ts
607
768
  var registerSelector = (selectorKey, store) => ({
608
769
  get: (dependency) => {
770
+ var _a;
609
771
  const target = newest(store);
610
- const dependencyState = withdraw(dependency, store);
772
+ const dependencyState = (_a = withdraw(dependency, store)) != null ? _a : withdrawNewFamilyMember(dependency, store);
611
773
  if (dependencyState === void 0) {
612
774
  throw new Error(
613
- `State "${dependency.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`
775
+ `State "${dependency.key}" not found in store "${store.config.name}".`
614
776
  );
615
777
  }
616
778
  const dependencyValue = readOrComputeValue(dependencyState, store);
@@ -709,7 +871,7 @@ var createWritableSelector = (options, family, store) => {
709
871
  );
710
872
  cacheValue(options.key, newValue, subject, store);
711
873
  markDone(options.key, store);
712
- if (target.transactionMeta === null) {
874
+ if (isRootStore(target)) {
713
875
  subject.next({ newValue, oldValue });
714
876
  }
715
877
  options.set(transactors, newValue);
@@ -927,15 +1089,15 @@ var Tracker = class {
927
1089
  }
928
1090
  return latestUpdateState;
929
1091
  }
930
- observeCore(mutableState, latestUpdateState, store) {
931
- const originalInnerValue = getState(mutableState, store);
932
- const target = newest(store);
1092
+ observeCore(mutableState, latestUpdateState, target) {
1093
+ const subscriptionKey = `tracker:${target.config.name}:${isChildStore(target) ? target.transactionMeta.update.key : `main`}:${mutableState.key}`;
1094
+ const originalInnerValue = getState(mutableState, target);
933
1095
  this.unsubscribeFromInnerValue = originalInnerValue.subscribe(
934
- `tracker:${store.config.name}:${target.transactionMeta === null ? `main` : target.transactionMeta.update.key}`,
1096
+ subscriptionKey,
935
1097
  (update) => {
936
1098
  if (target.operation.open) {
937
1099
  const unsubscribe = target.on.operationClose.subscribe(
938
- mutableState.key,
1100
+ subscriptionKey,
939
1101
  () => {
940
1102
  unsubscribe();
941
1103
  setState(latestUpdateState, update, target);
@@ -952,39 +1114,39 @@ var Tracker = class {
952
1114
  (update) => {
953
1115
  if (update.newValue !== update.oldValue) {
954
1116
  this.unsubscribeFromInnerValue();
955
- const target2 = newest(store);
956
1117
  this.unsubscribeFromInnerValue = update.newValue.subscribe(
957
- `tracker:${store.config.name}:${target2.transactionMeta === null ? `main` : target2.transactionMeta.update.key}`,
1118
+ subscriptionKey,
958
1119
  (update2) => {
959
- if (target2.operation.open) {
960
- const unsubscribe = target2.on.operationClose.subscribe(
961
- mutableState.key,
1120
+ if (target.operation.open) {
1121
+ const unsubscribe = target.on.operationClose.subscribe(
1122
+ subscriptionKey,
962
1123
  () => {
963
1124
  unsubscribe();
964
- setState(latestUpdateState, update2, target2);
1125
+ setState(latestUpdateState, update2, target);
965
1126
  }
966
1127
  );
967
1128
  } else {
968
- setState(mutableState, (current) => current, target2);
969
- setState(latestUpdateState, update2, target2);
1129
+ setState(mutableState, (current) => current, target);
1130
+ setState(latestUpdateState, update2, target);
970
1131
  }
971
1132
  }
972
1133
  );
973
1134
  }
974
1135
  },
975
- `${store.config.name}: tracker observing inner value`,
976
- store
1136
+ subscriptionKey,
1137
+ target
977
1138
  );
978
1139
  }
979
- updateCore(mutableState, latestUpdateState, store) {
1140
+ updateCore(mutableState, latestUpdateState, target) {
1141
+ const subscriptionKey = `tracker:${target.config.name}:${isChildStore(target) ? target.transactionMeta.update.key : `main`}:${mutableState.key}`;
980
1142
  subscribeToState(
981
1143
  latestUpdateState,
982
1144
  ({ newValue, oldValue }) => {
983
- const timelineId = store.timelineAtoms.getRelatedKey(
1145
+ const timelineId = target.timelineAtoms.getRelatedKey(
984
1146
  latestUpdateState.key
985
1147
  );
986
1148
  if (timelineId) {
987
- const timelineData = store.timelines.get(timelineId);
1149
+ const timelineData = target.timelines.get(timelineId);
988
1150
  if (timelineData == null ? void 0 : timelineData.timeTraveling) {
989
1151
  const unsubscribe2 = subscribeToTimeline(
990
1152
  { key: timelineId, type: `timeline` },
@@ -1000,34 +1162,41 @@ var Tracker = class {
1000
1162
  }
1001
1163
  return transceiver;
1002
1164
  },
1003
- store
1165
+ target
1004
1166
  );
1005
1167
  },
1006
- `${mutableState.key}: tracker observing timeline`,
1007
- store
1168
+ subscriptionKey,
1169
+ target
1008
1170
  );
1009
1171
  return;
1010
1172
  }
1011
1173
  }
1012
- const unsubscribe = store.on.operationClose.subscribe(
1013
- latestUpdateState.key,
1174
+ const unsubscribe = target.on.operationClose.subscribe(
1175
+ subscriptionKey,
1014
1176
  () => {
1015
1177
  unsubscribe();
1016
- const mutable = getState(mutableState, store);
1178
+ const mutable = getState(mutableState, target);
1017
1179
  const updateNumber = newValue === null ? -1 : mutable.getUpdateNumber(newValue);
1018
1180
  const eventOffset = updateNumber - mutable.cacheUpdateNumber;
1019
1181
  if (newValue && eventOffset === 1) {
1020
1182
  setState(
1021
1183
  mutableState,
1022
1184
  (transceiver) => (transceiver.do(newValue), transceiver),
1023
- store
1185
+ target
1186
+ );
1187
+ } else {
1188
+ target.logger.info(
1189
+ `\u274C`,
1190
+ `mutable_atom`,
1191
+ mutableState.key,
1192
+ `could not be updated. Expected update number ${mutable.cacheUpdateNumber + 1}, but got ${updateNumber}`
1024
1193
  );
1025
1194
  }
1026
1195
  }
1027
1196
  );
1028
1197
  },
1029
- `${store.config.name}: tracker observing latest update`,
1030
- store
1198
+ subscriptionKey,
1199
+ target
1031
1200
  );
1032
1201
  }
1033
1202
  constructor(mutableState, store) {
@@ -1110,125 +1279,6 @@ function createMutableAtom(options, family, store) {
1110
1279
  store.on.atomCreation.next(token);
1111
1280
  return token;
1112
1281
  }
1113
- function createRegularAtomFamily(options, store) {
1114
- const subject = new Subject();
1115
- const atomFamily = Object.assign(
1116
- (key) => {
1117
- const subKey = stringifyJson(key);
1118
- const family = { key: options.key, subKey };
1119
- const fullKey = `${options.key}(${subKey})`;
1120
- const existing = withdraw({ key: fullKey, type: `atom` }, store);
1121
- let token;
1122
- if (existing) {
1123
- token = deposit(existing);
1124
- } else {
1125
- const individualOptions = {
1126
- key: fullKey,
1127
- default: options.default instanceof Function ? options.default(key) : options.default
1128
- };
1129
- if (options.effects) {
1130
- individualOptions.effects = options.effects(key);
1131
- }
1132
- token = createRegularAtom(individualOptions, family, store);
1133
- subject.next(token);
1134
- }
1135
- return token;
1136
- },
1137
- {
1138
- key: options.key,
1139
- type: `atom_family`,
1140
- subject,
1141
- install: (store2) => createRegularAtomFamily(options, store2)
1142
- }
1143
- );
1144
- const target = newest(store);
1145
- target.families.set(options.key, atomFamily);
1146
- return atomFamily;
1147
- }
1148
-
1149
- // internal/src/families/create-atom-family.ts
1150
- function createAtomFamily(options, store) {
1151
- const isMutable2 = `mutable` in options;
1152
- if (isMutable2) {
1153
- return createMutableAtomFamily(options, store);
1154
- }
1155
- return createRegularAtomFamily(options, store);
1156
- }
1157
- function createReadonlySelectorFamily(options, store) {
1158
- const subject = new Subject();
1159
- const readonlySelectorFamily = Object.assign(
1160
- (key) => {
1161
- const target = newest(store);
1162
- const subKey = stringifyJson(key);
1163
- const family = { key: options.key, subKey };
1164
- const fullKey = `${options.key}(${subKey})`;
1165
- const existing = target.readonlySelectors.get(fullKey);
1166
- if (existing) {
1167
- return deposit(existing);
1168
- }
1169
- return createReadonlySelector(
1170
- {
1171
- key: fullKey,
1172
- get: options.get(key)
1173
- },
1174
- family,
1175
- store
1176
- );
1177
- },
1178
- {
1179
- key: options.key,
1180
- type: `readonly_selector_family`,
1181
- subject,
1182
- install: (store2) => createReadonlySelectorFamily(options, store2)
1183
- }
1184
- );
1185
- store.families.set(options.key, readonlySelectorFamily);
1186
- return readonlySelectorFamily;
1187
- }
1188
- function createWritableSelectorFamily(options, store) {
1189
- const subject = new Subject();
1190
- const selectorFamily = Object.assign(
1191
- (key) => {
1192
- const subKey = stringifyJson(key);
1193
- const family = { key: options.key, subKey };
1194
- const fullKey = `${options.key}(${subKey})`;
1195
- const existing = store.selectors.get(fullKey);
1196
- if (existing) {
1197
- return deposit(existing);
1198
- }
1199
- const token = createWritableSelector(
1200
- {
1201
- key: fullKey,
1202
- get: options.get(key),
1203
- set: options.set(key)
1204
- },
1205
- family,
1206
- store
1207
- );
1208
- subject.next(token);
1209
- return token;
1210
- },
1211
- {
1212
- key: options.key,
1213
- type: `selector_family`,
1214
- subject,
1215
- install: (store2) => createWritableSelectorFamily(options, store2)
1216
- }
1217
- );
1218
- store.families.set(options.key, selectorFamily);
1219
- return selectorFamily;
1220
- }
1221
-
1222
- // internal/src/families/create-selector-family.ts
1223
- function createSelectorFamily(options, store) {
1224
- const isWritable = `set` in options;
1225
- if (isWritable) {
1226
- return createWritableSelectorFamily(options, store);
1227
- }
1228
- return createReadonlySelectorFamily(options, store);
1229
- }
1230
-
1231
- // internal/src/mutable/tracker-family.ts
1232
1282
  var FamilyTracker = class {
1233
1283
  constructor(findMutableState, store) {
1234
1284
  this.findLatestUpdateState = createRegularAtomFamily(
@@ -1543,22 +1593,6 @@ var LazyMap = class extends Map {
1543
1593
  }
1544
1594
  };
1545
1595
 
1546
- // internal/src/not-found-error.ts
1547
- var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
1548
- function prettyPrintTokenType(token) {
1549
- if (token.type === `readonly_selector`) {
1550
- return `Readonly Selector`;
1551
- }
1552
- return capitalize(token.type);
1553
- }
1554
- var NotFoundError = class extends Error {
1555
- constructor(token, store) {
1556
- super(
1557
- `${prettyPrintTokenType(token)} "${token.key}" not found in store "${store.config.name}".`
1558
- );
1559
- }
1560
- };
1561
-
1562
1596
  // internal/src/timeline/add-atom-to-timeline.ts
1563
1597
  var addAtomToTimeline = (atomToken, tl, store) => {
1564
1598
  let maybeAtom = withdraw(atomToken, store);
@@ -1578,8 +1612,9 @@ var addAtomToTimeline = (atomToken, tl, store) => {
1578
1612
  const target = newest(store);
1579
1613
  const currentSelectorKey = store.operation.open && store.operation.token.type === `selector` ? store.operation.token.key : null;
1580
1614
  const currentSelectorTime = store.operation.open && store.operation.token.type === `selector` ? store.operation.time : null;
1581
- const currentTransactionKey = (_a = target.on.transactionApplying.state) == null ? void 0 : _a.update.key;
1582
- const currentTransactionTime = (_b = target.on.transactionApplying.state) == null ? void 0 : _b.time;
1615
+ const { transactionApplying } = target.on;
1616
+ const currentTransactionKey = (_a = transactionApplying.state) == null ? void 0 : _a.update.key;
1617
+ const currentTransactionInstanceId = (_b = transactionApplying.state) == null ? void 0 : _b.update.id;
1583
1618
  store.logger.info(
1584
1619
  `\u23F3`,
1585
1620
  `timeline`,
@@ -1626,7 +1661,7 @@ var addAtomToTimeline = (atomToken, tl, store) => {
1626
1661
  (update2) => {
1627
1662
  var _a2, _b2;
1628
1663
  unsubscribe();
1629
- if (tl.timeTraveling === null && currentTransactionTime) {
1664
+ if (tl.timeTraveling === null && currentTransactionInstanceId) {
1630
1665
  if (tl.at !== tl.history.length) {
1631
1666
  tl.history.splice(tl.at);
1632
1667
  }
@@ -1653,7 +1688,7 @@ var addAtomToTimeline = (atomToken, tl, store) => {
1653
1688
  const updates = filterUpdates(update2.updates);
1654
1689
  const timelineTransactionUpdate = __spreadProps(__spreadValues({
1655
1690
  type: `transaction_update`,
1656
- timestamp: currentTransactionTime
1691
+ timestamp: Date.now()
1657
1692
  }, update2), {
1658
1693
  updates
1659
1694
  });
@@ -1915,7 +1950,7 @@ var timeTravel = (action, token, store) => {
1915
1950
  // internal/src/transaction/abort-transaction.ts
1916
1951
  var abortTransaction = (store) => {
1917
1952
  const target = newest(store);
1918
- if (target.transactionMeta === null || target.parent === null) {
1953
+ if (!isChildStore(target)) {
1919
1954
  store.logger.warn(
1920
1955
  `\u{1F41E}`,
1921
1956
  `transaction`,
@@ -1938,7 +1973,7 @@ var applyTransaction = (output, store) => {
1938
1973
  var _a;
1939
1974
  const child = newest(store);
1940
1975
  const { parent } = child;
1941
- if (parent === null || child.transactionMeta === null || ((_a = child.transactionMeta) == null ? void 0 : _a.phase) !== `building`) {
1976
+ if (parent === null || !isChildStore(child) || ((_a = child.transactionMeta) == null ? void 0 : _a.phase) !== `building`) {
1942
1977
  store.logger.warn(
1943
1978
  `\u{1F41E}`,
1944
1979
  `transaction`,
@@ -1980,7 +2015,8 @@ var applyTransaction = (output, store) => {
1980
2015
  }
1981
2016
  }
1982
2017
  ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
1983
- if (parent.transactionMeta === null) {
2018
+ if (isRootStore(parent)) {
2019
+ parent.transactionMeta.epoch = child.transactionMeta.update.epoch;
1984
2020
  const myTransaction = withdraw(
1985
2021
  { key: child.transactionMeta.update.key, type: `transaction` },
1986
2022
  store
@@ -1992,21 +2028,20 @@ var applyTransaction = (output, store) => {
1992
2028
  child.transactionMeta.update.key,
1993
2029
  `Finished applying transaction.`
1994
2030
  );
1995
- } else {
2031
+ } else if (isChildStore(parent)) {
1996
2032
  parent.transactionMeta.update.updates.push(child.transactionMeta.update);
1997
2033
  }
1998
2034
  parent.on.transactionApplying.next(null);
1999
2035
  };
2000
2036
  var buildTransaction = (key, params, store, id) => {
2001
2037
  const parent = newest(store);
2002
- const child = {
2038
+ const childBase = {
2003
2039
  parent,
2004
2040
  child: null,
2005
2041
  on: parent.on,
2006
2042
  loggers: parent.loggers,
2007
2043
  logger: parent.logger,
2008
2044
  config: parent.config,
2009
- transactionMeta: null,
2010
2045
  atoms: new LazyMap(parent.atoms),
2011
2046
  atomsThatAreDefault: new Set(parent.atomsThatAreDefault),
2012
2047
  families: new LazyMap(parent.families),
@@ -2023,12 +2058,12 @@ var buildTransaction = (key, params, store, id) => {
2023
2058
  selectors: new LazyMap(parent.selectors),
2024
2059
  valueMap: new LazyMap(parent.valueMap)
2025
2060
  };
2026
- child.transactionMeta = {
2061
+ const transactionMeta = {
2027
2062
  phase: `building`,
2028
- time: Date.now(),
2029
2063
  update: {
2030
2064
  key,
2031
2065
  id: id != null ? id : Math.random().toString(36).slice(2),
2066
+ epoch: isRootStore(parent) ? parent.transactionMeta.epoch + 1 : NaN,
2032
2067
  updates: [],
2033
2068
  params,
2034
2069
  output: void 0
@@ -2036,11 +2071,14 @@ var buildTransaction = (key, params, store, id) => {
2036
2071
  transactors: {
2037
2072
  get: (token) => getState(token, child),
2038
2073
  set: (token, value) => setState(token, value, child),
2039
- run: (token) => runTransaction(token, child),
2074
+ run: (token, id2) => runTransaction(token, id2, child),
2040
2075
  find: (token, key2) => findInStore(token, key2, child),
2041
2076
  env: () => getEnvironmentData(child)
2042
2077
  }
2043
2078
  };
2079
+ const child = Object.assign(childBase, {
2080
+ transactionMeta
2081
+ });
2044
2082
  parent.child = child;
2045
2083
  store.logger.info(
2046
2084
  `\u{1F6EB}`,
@@ -2049,6 +2087,7 @@ var buildTransaction = (key, params, store, id) => {
2049
2087
  `Building transaction with params:`,
2050
2088
  params
2051
2089
  );
2090
+ return child;
2052
2091
  };
2053
2092
 
2054
2093
  // internal/src/transaction/create-transaction.ts
@@ -2057,10 +2096,10 @@ function createTransaction(options, store) {
2057
2096
  key: options.key,
2058
2097
  type: `transaction`,
2059
2098
  run: (params, id) => {
2060
- buildTransaction(options.key, params, store, id);
2099
+ const childStore = buildTransaction(options.key, params, store, id);
2061
2100
  try {
2062
2101
  const target2 = newest(store);
2063
- const { transactors } = target2.transactionMeta;
2102
+ const { transactors } = childStore.transactionMeta;
2064
2103
  const output = options.do(transactors, ...params);
2065
2104
  applyTransaction(output, target2);
2066
2105
  return output;
@@ -2083,6 +2122,6 @@ function createTransaction(options, store) {
2083
2122
  // internal/src/transaction/index.ts
2084
2123
  var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
2085
2124
 
2086
- export { FamilyTracker, Future, IMPLICIT, LazyMap, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, addAtomToTimeline, applyTransaction, become, buildTransaction, cacheValue, clearStore, closeOperation, createAtomFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelector, createReadonlySelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneAtom, createStandaloneSelector, createTimeline, createTransaction, createWritableSelector, deleteAtom, deleteSelector, deposit, evictCachedValue, getEnvironmentData, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getUpdateToken, ingestAtomUpdate, ingestSelectorUpdate, ingestTransactionUpdate, isAtomDefault, isAtomKey, isDone, isMutable, isReadonlySelectorKey, isSelectorKey, isStateKey, isTransceiver, markAtomAsDefault, markAtomAsNotDefault, markDone, newest, openOperation, readCachedValue, readOrComputeValue, registerSelector, setAtomOrSelector, subscribeToRootAtoms, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, updateSelectorAtoms, withdraw, withdrawNewFamilyMember };
2125
+ export { FamilyTracker, Future, IMPLICIT, LazyMap, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, addAtomToTimeline, applyTransaction, become, buildTransaction, cacheValue, clearStore, closeOperation, createAtomFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelector, createReadonlySelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneAtom, createStandaloneSelector, createTimeline, createTransaction, createWritableSelector, deleteAtom, deleteSelector, deposit, evictCachedValue, findInStore, getEnvironmentData, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getUpdateToken, ingestAtomUpdate, ingestSelectorUpdate, ingestTransactionUpdate, isAtomDefault, isAtomKey, isDone, isMutable, isReadonlySelectorKey, isSelectorKey, isStateKey, isTransceiver, markAtomAsDefault, markAtomAsNotDefault, markDone, newest, openOperation, readCachedValue, readOrComputeValue, registerSelector, setAtomOrSelector, subscribeToRootAtoms, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, updateSelectorAtoms, withdraw, withdrawNewFamilyMember };
2087
2126
  //# sourceMappingURL=out.js.map
2088
2127
  //# sourceMappingURL=index.js.map