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
@@ -369,11 +369,15 @@ var Store = class {
369
369
  selectorCreation: new Subject(),
370
370
  transactionCreation: new Subject(),
371
371
  timelineCreation: new Subject(),
372
- transactionApplying: new StatefulSubject(null),
372
+ transactionApplying: new StatefulSubject(
373
+ null
374
+ ),
373
375
  operationClose: new Subject()
374
376
  };
375
377
  this.operation = { open: false };
376
- this.transactionMeta = null;
378
+ this.transactionMeta = {
379
+ epoch: -1
380
+ };
377
381
  this.config = {
378
382
  name: `IMPLICIT_STORE`
379
383
  };
@@ -397,7 +401,7 @@ var Store = class {
397
401
  if (store !== null) {
398
402
  this.valueMap = new Map(store == null ? void 0 : store.valueMap);
399
403
  this.operation = __spreadValues({}, store == null ? void 0 : store.operation);
400
- this.transactionMeta = null;
404
+ this.transactionMeta = __spreadValues({}, store == null ? void 0 : store.transactionMeta);
401
405
  this.config = __spreadProps(__spreadValues({}, store == null ? void 0 : store.config), {
402
406
  name
403
407
  });
@@ -610,12 +614,164 @@ var readOrComputeValue = (state, target) => {
610
614
  );
611
615
  return state.default instanceof Function ? state.default() : state.default;
612
616
  };
617
+ function createRegularAtomFamily(options, store) {
618
+ const subject = new Subject();
619
+ const atomFamily = Object.assign(
620
+ (key) => {
621
+ const subKey = json.stringifyJson(key);
622
+ const family = { key: options.key, subKey };
623
+ const fullKey = `${options.key}(${subKey})`;
624
+ const existing = withdraw({ key: fullKey, type: `atom` }, store);
625
+ let token;
626
+ if (existing) {
627
+ token = deposit(existing);
628
+ } else {
629
+ const individualOptions = {
630
+ key: fullKey,
631
+ default: options.default instanceof Function ? options.default(key) : options.default
632
+ };
633
+ if (options.effects) {
634
+ individualOptions.effects = options.effects(key);
635
+ }
636
+ token = createRegularAtom(individualOptions, family, store);
637
+ subject.next(token);
638
+ }
639
+ return token;
640
+ },
641
+ {
642
+ key: options.key,
643
+ type: `atom_family`,
644
+ subject,
645
+ install: (store2) => createRegularAtomFamily(options, store2)
646
+ }
647
+ );
648
+ const target = newest(store);
649
+ target.families.set(options.key, atomFamily);
650
+ return atomFamily;
651
+ }
652
+
653
+ // internal/src/families/create-atom-family.ts
654
+ function createAtomFamily(options, store) {
655
+ const isMutable2 = `mutable` in options;
656
+ if (isMutable2) {
657
+ return createMutableAtomFamily(options, store);
658
+ }
659
+ return createRegularAtomFamily(options, store);
660
+ }
661
+ function createReadonlySelectorFamily(options, store) {
662
+ const subject = new Subject();
663
+ const readonlySelectorFamily = Object.assign(
664
+ (key) => {
665
+ const target = newest(store);
666
+ const subKey = json.stringifyJson(key);
667
+ const family = { key: options.key, subKey };
668
+ const fullKey = `${options.key}(${subKey})`;
669
+ const existing = target.readonlySelectors.get(fullKey);
670
+ if (existing) {
671
+ return deposit(existing);
672
+ }
673
+ return createReadonlySelector(
674
+ {
675
+ key: fullKey,
676
+ get: options.get(key)
677
+ },
678
+ family,
679
+ store
680
+ );
681
+ },
682
+ {
683
+ key: options.key,
684
+ type: `readonly_selector_family`,
685
+ subject,
686
+ install: (store2) => createReadonlySelectorFamily(options, store2)
687
+ }
688
+ );
689
+ store.families.set(options.key, readonlySelectorFamily);
690
+ return readonlySelectorFamily;
691
+ }
692
+ function createWritableSelectorFamily(options, store) {
693
+ const subject = new Subject();
694
+ const selectorFamily = Object.assign(
695
+ (key) => {
696
+ const subKey = json.stringifyJson(key);
697
+ const family = { key: options.key, subKey };
698
+ const fullKey = `${options.key}(${subKey})`;
699
+ const existing = store.selectors.get(fullKey);
700
+ if (existing) {
701
+ return deposit(existing);
702
+ }
703
+ const token = createWritableSelector(
704
+ {
705
+ key: fullKey,
706
+ get: options.get(key),
707
+ set: options.set(key)
708
+ },
709
+ family,
710
+ store
711
+ );
712
+ subject.next(token);
713
+ return token;
714
+ },
715
+ {
716
+ key: options.key,
717
+ type: `selector_family`,
718
+ subject,
719
+ install: (store2) => createWritableSelectorFamily(options, store2)
720
+ }
721
+ );
722
+ store.families.set(options.key, selectorFamily);
723
+ return selectorFamily;
724
+ }
725
+
726
+ // internal/src/families/create-selector-family.ts
727
+ function createSelectorFamily(options, store) {
728
+ const isWritable = `set` in options;
729
+ if (isWritable) {
730
+ return createWritableSelectorFamily(options, store);
731
+ }
732
+ return createReadonlySelectorFamily(options, store);
733
+ }
734
+
735
+ // internal/src/not-found-error.ts
736
+ var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
737
+ function prettyPrintTokenType(token) {
738
+ if (token.type === `readonly_selector`) {
739
+ return `Readonly Selector`;
740
+ }
741
+ return capitalize(token.type);
742
+ }
743
+ var NotFoundError = class extends Error {
744
+ constructor(token, store) {
745
+ super(
746
+ `${prettyPrintTokenType(token)} "${token.key}" not found in store "${store.config.name}".`
747
+ );
748
+ }
749
+ };
750
+
751
+ // internal/src/families/find-in-store.ts
752
+ function findInStore(token, key, store) {
753
+ const familyKey = token.key;
754
+ const family = store.families.get(familyKey);
755
+ if (family === void 0) {
756
+ throw new NotFoundError(token, store);
757
+ }
758
+ const state = family(key);
759
+ return state;
760
+ }
613
761
 
614
762
  // internal/src/set-state/become.ts
615
763
  var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(
616
764
  originalThing instanceof Function ? originalThing() : originalThing
617
765
  ) : nextVersionOfThing;
618
766
 
767
+ // internal/src/transaction/is-root-store.ts
768
+ function isRootStore(store) {
769
+ return `epoch` in store.transactionMeta;
770
+ }
771
+ function isChildStore(store) {
772
+ return `phase` in store.transactionMeta;
773
+ }
774
+
619
775
  // internal/src/operation.ts
620
776
  var openOperation = (token, store) => {
621
777
  if (store.operation.open) {
@@ -638,7 +794,7 @@ var openOperation = (token, store) => {
638
794
  `\u2B55`,
639
795
  token.type,
640
796
  token.key,
641
- `operation start in store "${store.config.name}"${store.transactionMeta === null ? `` : ` ${store.transactionMeta.phase} "${store.transactionMeta.update.key}"`}`
797
+ `operation start in store "${store.config.name}"${!isChildStore(store) ? `` : ` ${store.transactionMeta.phase} "${store.transactionMeta.update.key}"`}`
642
798
  );
643
799
  };
644
800
  var closeOperation = (store) => {
@@ -736,7 +892,7 @@ function shouldUpdateBeStowed(key, update) {
736
892
  var stowUpdate = (state, update, store) => {
737
893
  const { key } = state;
738
894
  const target = newest(store);
739
- if (target.transactionMeta === null || target.transactionMeta.phase !== `building`) {
895
+ if (!isChildStore(target) || target.transactionMeta.phase !== `building`) {
740
896
  store.logger.error(
741
897
  `\u{1F41E}`,
742
898
  `atom`,
@@ -779,14 +935,26 @@ var setAtom = (atom, next, target) => {
779
935
  markDone(atom.key, target);
780
936
  evictDownStream(atom, target);
781
937
  const update = { oldValue, newValue };
782
- if (target.transactionMeta === null) {
938
+ if (isRootStore(target)) {
783
939
  emitUpdate(atom, update, target);
784
- } else if (target.on.transactionApplying && target.parent) {
785
- stowUpdate(atom, update, target);
786
- if (atom.key.startsWith(`*`)) {
940
+ } else if (target.parent) {
941
+ if (target.on.transactionApplying.state === null) {
942
+ stowUpdate(atom, update, target);
943
+ } else if (atom.key.startsWith(`*`)) {
787
944
  const mutableKey = atom.key.slice(1);
788
- const mutable = target.valueMap.get(mutableKey);
789
- mutable.do(update.newValue);
945
+ const mutableAtom = target.atoms.get(mutableKey);
946
+ let mutable = target.valueMap.get(mutableKey);
947
+ mutable = copyMutableIfWithinTransaction(mutable, mutableAtom, target);
948
+ const output = mutable.do(update.newValue);
949
+ if (output !== null) {
950
+ target.logger.warn(
951
+ `\u274C`,
952
+ `mutable_atom`,
953
+ mutableKey,
954
+ `could not be updated.`,
955
+ typeof output === `number` ? `Expected update number ${mutable.cacheUpdateNumber + 1}, but got ${output}` : output
956
+ );
957
+ }
790
958
  }
791
959
  }
792
960
  };
@@ -884,11 +1052,12 @@ var updateSelectorAtoms = (selectorKey, dependency, store) => {
884
1052
  // internal/src/selector/register-selector.ts
885
1053
  var registerSelector = (selectorKey, store) => ({
886
1054
  get: (dependency) => {
1055
+ var _a;
887
1056
  const target = newest(store);
888
- const dependencyState = withdraw(dependency, store);
1057
+ const dependencyState = (_a = withdraw(dependency, store)) != null ? _a : withdrawNewFamilyMember(dependency, store);
889
1058
  if (dependencyState === void 0) {
890
1059
  throw new Error(
891
- `State "${dependency.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`
1060
+ `State "${dependency.key}" not found in store "${store.config.name}".`
892
1061
  );
893
1062
  }
894
1063
  const dependencyValue = readOrComputeValue(dependencyState, store);
@@ -921,7 +1090,7 @@ var registerSelector = (selectorKey, store) => ({
921
1090
  }
922
1091
  setAtomOrSelector(state, newValue, store);
923
1092
  },
924
- find: (token, key) => atom_io.findInStore(token, key, store)
1093
+ find: (token, key) => findInStore(token, key, store)
925
1094
  });
926
1095
 
927
1096
  // internal/src/selector/create-readonly-selector.ts
@@ -987,7 +1156,7 @@ var createWritableSelector = (options, family, store) => {
987
1156
  );
988
1157
  cacheValue(options.key, newValue, subject, store);
989
1158
  markDone(options.key, store);
990
- if (target.transactionMeta === null) {
1159
+ if (isRootStore(target)) {
991
1160
  subject.next({ newValue, oldValue });
992
1161
  }
993
1162
  options.set(transactors, newValue);
@@ -1205,15 +1374,15 @@ var Tracker = class {
1205
1374
  }
1206
1375
  return latestUpdateState;
1207
1376
  }
1208
- observeCore(mutableState, latestUpdateState, store) {
1209
- const originalInnerValue = atom_io.getState(mutableState, store);
1210
- const target = newest(store);
1377
+ observeCore(mutableState, latestUpdateState, target) {
1378
+ const subscriptionKey = `tracker:${target.config.name}:${isChildStore(target) ? target.transactionMeta.update.key : `main`}:${mutableState.key}`;
1379
+ const originalInnerValue = atom_io.getState(mutableState, target);
1211
1380
  this.unsubscribeFromInnerValue = originalInnerValue.subscribe(
1212
- `tracker:${store.config.name}:${target.transactionMeta === null ? `main` : target.transactionMeta.update.key}`,
1381
+ subscriptionKey,
1213
1382
  (update) => {
1214
1383
  if (target.operation.open) {
1215
1384
  const unsubscribe = target.on.operationClose.subscribe(
1216
- mutableState.key,
1385
+ subscriptionKey,
1217
1386
  () => {
1218
1387
  unsubscribe();
1219
1388
  atom_io.setState(latestUpdateState, update, target);
@@ -1230,39 +1399,39 @@ var Tracker = class {
1230
1399
  (update) => {
1231
1400
  if (update.newValue !== update.oldValue) {
1232
1401
  this.unsubscribeFromInnerValue();
1233
- const target2 = newest(store);
1234
1402
  this.unsubscribeFromInnerValue = update.newValue.subscribe(
1235
- `tracker:${store.config.name}:${target2.transactionMeta === null ? `main` : target2.transactionMeta.update.key}`,
1403
+ subscriptionKey,
1236
1404
  (update2) => {
1237
- if (target2.operation.open) {
1238
- const unsubscribe = target2.on.operationClose.subscribe(
1239
- mutableState.key,
1405
+ if (target.operation.open) {
1406
+ const unsubscribe = target.on.operationClose.subscribe(
1407
+ subscriptionKey,
1240
1408
  () => {
1241
1409
  unsubscribe();
1242
- atom_io.setState(latestUpdateState, update2, target2);
1410
+ atom_io.setState(latestUpdateState, update2, target);
1243
1411
  }
1244
1412
  );
1245
1413
  } else {
1246
- atom_io.setState(mutableState, (current) => current, target2);
1247
- atom_io.setState(latestUpdateState, update2, target2);
1414
+ atom_io.setState(mutableState, (current) => current, target);
1415
+ atom_io.setState(latestUpdateState, update2, target);
1248
1416
  }
1249
1417
  }
1250
1418
  );
1251
1419
  }
1252
1420
  },
1253
- `${store.config.name}: tracker observing inner value`,
1254
- store
1421
+ subscriptionKey,
1422
+ target
1255
1423
  );
1256
1424
  }
1257
- updateCore(mutableState, latestUpdateState, store) {
1425
+ updateCore(mutableState, latestUpdateState, target) {
1426
+ const subscriptionKey = `tracker:${target.config.name}:${isChildStore(target) ? target.transactionMeta.update.key : `main`}:${mutableState.key}`;
1258
1427
  subscribeToState(
1259
1428
  latestUpdateState,
1260
1429
  ({ newValue, oldValue }) => {
1261
- const timelineId = store.timelineAtoms.getRelatedKey(
1430
+ const timelineId = target.timelineAtoms.getRelatedKey(
1262
1431
  latestUpdateState.key
1263
1432
  );
1264
1433
  if (timelineId) {
1265
- const timelineData = store.timelines.get(timelineId);
1434
+ const timelineData = target.timelines.get(timelineId);
1266
1435
  if (timelineData == null ? void 0 : timelineData.timeTraveling) {
1267
1436
  const unsubscribe2 = subscribeToTimeline(
1268
1437
  { key: timelineId, type: `timeline` },
@@ -1278,34 +1447,41 @@ var Tracker = class {
1278
1447
  }
1279
1448
  return transceiver;
1280
1449
  },
1281
- store
1450
+ target
1282
1451
  );
1283
1452
  },
1284
- `${mutableState.key}: tracker observing timeline`,
1285
- store
1453
+ subscriptionKey,
1454
+ target
1286
1455
  );
1287
1456
  return;
1288
1457
  }
1289
1458
  }
1290
- const unsubscribe = store.on.operationClose.subscribe(
1291
- latestUpdateState.key,
1459
+ const unsubscribe = target.on.operationClose.subscribe(
1460
+ subscriptionKey,
1292
1461
  () => {
1293
1462
  unsubscribe();
1294
- const mutable = atom_io.getState(mutableState, store);
1463
+ const mutable = atom_io.getState(mutableState, target);
1295
1464
  const updateNumber = newValue === null ? -1 : mutable.getUpdateNumber(newValue);
1296
1465
  const eventOffset = updateNumber - mutable.cacheUpdateNumber;
1297
1466
  if (newValue && eventOffset === 1) {
1298
1467
  atom_io.setState(
1299
1468
  mutableState,
1300
1469
  (transceiver) => (transceiver.do(newValue), transceiver),
1301
- store
1470
+ target
1471
+ );
1472
+ } else {
1473
+ target.logger.info(
1474
+ `\u274C`,
1475
+ `mutable_atom`,
1476
+ mutableState.key,
1477
+ `could not be updated. Expected update number ${mutable.cacheUpdateNumber + 1}, but got ${updateNumber}`
1302
1478
  );
1303
1479
  }
1304
1480
  }
1305
1481
  );
1306
1482
  },
1307
- `${store.config.name}: tracker observing latest update`,
1308
- store
1483
+ subscriptionKey,
1484
+ target
1309
1485
  );
1310
1486
  }
1311
1487
  constructor(mutableState, store) {
@@ -1388,125 +1564,6 @@ function createMutableAtom(options, family, store) {
1388
1564
  store.on.atomCreation.next(token);
1389
1565
  return token;
1390
1566
  }
1391
- function createRegularAtomFamily(options, store) {
1392
- const subject = new Subject();
1393
- const atomFamily = Object.assign(
1394
- (key) => {
1395
- const subKey = json.stringifyJson(key);
1396
- const family = { key: options.key, subKey };
1397
- const fullKey = `${options.key}(${subKey})`;
1398
- const existing = withdraw({ key: fullKey, type: `atom` }, store);
1399
- let token;
1400
- if (existing) {
1401
- token = deposit(existing);
1402
- } else {
1403
- const individualOptions = {
1404
- key: fullKey,
1405
- default: options.default instanceof Function ? options.default(key) : options.default
1406
- };
1407
- if (options.effects) {
1408
- individualOptions.effects = options.effects(key);
1409
- }
1410
- token = createRegularAtom(individualOptions, family, store);
1411
- subject.next(token);
1412
- }
1413
- return token;
1414
- },
1415
- {
1416
- key: options.key,
1417
- type: `atom_family`,
1418
- subject,
1419
- install: (store2) => createRegularAtomFamily(options, store2)
1420
- }
1421
- );
1422
- const target = newest(store);
1423
- target.families.set(options.key, atomFamily);
1424
- return atomFamily;
1425
- }
1426
-
1427
- // internal/src/families/create-atom-family.ts
1428
- function createAtomFamily(options, store) {
1429
- const isMutable2 = `mutable` in options;
1430
- if (isMutable2) {
1431
- return createMutableAtomFamily(options, store);
1432
- }
1433
- return createRegularAtomFamily(options, store);
1434
- }
1435
- function createReadonlySelectorFamily(options, store) {
1436
- const subject = new Subject();
1437
- const readonlySelectorFamily = Object.assign(
1438
- (key) => {
1439
- const target = newest(store);
1440
- const subKey = json.stringifyJson(key);
1441
- const family = { key: options.key, subKey };
1442
- const fullKey = `${options.key}(${subKey})`;
1443
- const existing = target.readonlySelectors.get(fullKey);
1444
- if (existing) {
1445
- return deposit(existing);
1446
- }
1447
- return createReadonlySelector(
1448
- {
1449
- key: fullKey,
1450
- get: options.get(key)
1451
- },
1452
- family,
1453
- store
1454
- );
1455
- },
1456
- {
1457
- key: options.key,
1458
- type: `readonly_selector_family`,
1459
- subject,
1460
- install: (store2) => createReadonlySelectorFamily(options, store2)
1461
- }
1462
- );
1463
- store.families.set(options.key, readonlySelectorFamily);
1464
- return readonlySelectorFamily;
1465
- }
1466
- function createWritableSelectorFamily(options, store) {
1467
- const subject = new Subject();
1468
- const selectorFamily = Object.assign(
1469
- (key) => {
1470
- const subKey = json.stringifyJson(key);
1471
- const family = { key: options.key, subKey };
1472
- const fullKey = `${options.key}(${subKey})`;
1473
- const existing = store.selectors.get(fullKey);
1474
- if (existing) {
1475
- return deposit(existing);
1476
- }
1477
- const token = createWritableSelector(
1478
- {
1479
- key: fullKey,
1480
- get: options.get(key),
1481
- set: options.set(key)
1482
- },
1483
- family,
1484
- store
1485
- );
1486
- subject.next(token);
1487
- return token;
1488
- },
1489
- {
1490
- key: options.key,
1491
- type: `selector_family`,
1492
- subject,
1493
- install: (store2) => createWritableSelectorFamily(options, store2)
1494
- }
1495
- );
1496
- store.families.set(options.key, selectorFamily);
1497
- return selectorFamily;
1498
- }
1499
-
1500
- // internal/src/families/create-selector-family.ts
1501
- function createSelectorFamily(options, store) {
1502
- const isWritable = `set` in options;
1503
- if (isWritable) {
1504
- return createWritableSelectorFamily(options, store);
1505
- }
1506
- return createReadonlySelectorFamily(options, store);
1507
- }
1508
-
1509
- // internal/src/mutable/tracker-family.ts
1510
1567
  var FamilyTracker = class {
1511
1568
  constructor(findMutableState, store) {
1512
1569
  this.findLatestUpdateState = createRegularAtomFamily(
@@ -1821,22 +1878,6 @@ var LazyMap = class extends Map {
1821
1878
  }
1822
1879
  };
1823
1880
 
1824
- // internal/src/not-found-error.ts
1825
- var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
1826
- function prettyPrintTokenType(token) {
1827
- if (token.type === `readonly_selector`) {
1828
- return `Readonly Selector`;
1829
- }
1830
- return capitalize(token.type);
1831
- }
1832
- var NotFoundError = class extends Error {
1833
- constructor(token, store) {
1834
- super(
1835
- `${prettyPrintTokenType(token)} "${token.key}" not found in store "${store.config.name}".`
1836
- );
1837
- }
1838
- };
1839
-
1840
1881
  // internal/src/timeline/add-atom-to-timeline.ts
1841
1882
  var addAtomToTimeline = (atomToken, tl, store) => {
1842
1883
  let maybeAtom = withdraw(atomToken, store);
@@ -1856,8 +1897,9 @@ var addAtomToTimeline = (atomToken, tl, store) => {
1856
1897
  const target = newest(store);
1857
1898
  const currentSelectorKey = store.operation.open && store.operation.token.type === `selector` ? store.operation.token.key : null;
1858
1899
  const currentSelectorTime = store.operation.open && store.operation.token.type === `selector` ? store.operation.time : null;
1859
- const currentTransactionKey = (_a = target.on.transactionApplying.state) == null ? void 0 : _a.update.key;
1860
- const currentTransactionTime = (_b = target.on.transactionApplying.state) == null ? void 0 : _b.time;
1900
+ const { transactionApplying } = target.on;
1901
+ const currentTransactionKey = (_a = transactionApplying.state) == null ? void 0 : _a.update.key;
1902
+ const currentTransactionInstanceId = (_b = transactionApplying.state) == null ? void 0 : _b.update.id;
1861
1903
  store.logger.info(
1862
1904
  `\u23F3`,
1863
1905
  `timeline`,
@@ -1904,7 +1946,7 @@ var addAtomToTimeline = (atomToken, tl, store) => {
1904
1946
  (update2) => {
1905
1947
  var _a2, _b2;
1906
1948
  unsubscribe();
1907
- if (tl.timeTraveling === null && currentTransactionTime) {
1949
+ if (tl.timeTraveling === null && currentTransactionInstanceId) {
1908
1950
  if (tl.at !== tl.history.length) {
1909
1951
  tl.history.splice(tl.at);
1910
1952
  }
@@ -1931,7 +1973,7 @@ var addAtomToTimeline = (atomToken, tl, store) => {
1931
1973
  const updates = filterUpdates(update2.updates);
1932
1974
  const timelineTransactionUpdate = __spreadProps(__spreadValues({
1933
1975
  type: `transaction_update`,
1934
- timestamp: currentTransactionTime
1976
+ timestamp: Date.now()
1935
1977
  }, update2), {
1936
1978
  updates
1937
1979
  });
@@ -2193,7 +2235,7 @@ var timeTravel = (action, token, store) => {
2193
2235
  // internal/src/transaction/abort-transaction.ts
2194
2236
  var abortTransaction = (store) => {
2195
2237
  const target = newest(store);
2196
- if (target.transactionMeta === null || target.parent === null) {
2238
+ if (!isChildStore(target)) {
2197
2239
  store.logger.warn(
2198
2240
  `\u{1F41E}`,
2199
2241
  `transaction`,
@@ -2216,7 +2258,7 @@ var applyTransaction = (output, store) => {
2216
2258
  var _a;
2217
2259
  const child = newest(store);
2218
2260
  const { parent } = child;
2219
- if (parent === null || child.transactionMeta === null || ((_a = child.transactionMeta) == null ? void 0 : _a.phase) !== `building`) {
2261
+ if (parent === null || !isChildStore(child) || ((_a = child.transactionMeta) == null ? void 0 : _a.phase) !== `building`) {
2220
2262
  store.logger.warn(
2221
2263
  `\u{1F41E}`,
2222
2264
  `transaction`,
@@ -2258,7 +2300,8 @@ var applyTransaction = (output, store) => {
2258
2300
  }
2259
2301
  }
2260
2302
  ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
2261
- if (parent.transactionMeta === null) {
2303
+ if (isRootStore(parent)) {
2304
+ parent.transactionMeta.epoch = child.transactionMeta.update.epoch;
2262
2305
  const myTransaction = withdraw(
2263
2306
  { key: child.transactionMeta.update.key, type: `transaction` },
2264
2307
  store
@@ -2270,21 +2313,20 @@ var applyTransaction = (output, store) => {
2270
2313
  child.transactionMeta.update.key,
2271
2314
  `Finished applying transaction.`
2272
2315
  );
2273
- } else {
2316
+ } else if (isChildStore(parent)) {
2274
2317
  parent.transactionMeta.update.updates.push(child.transactionMeta.update);
2275
2318
  }
2276
2319
  parent.on.transactionApplying.next(null);
2277
2320
  };
2278
2321
  var buildTransaction = (key, params, store, id) => {
2279
2322
  const parent = newest(store);
2280
- const child = {
2323
+ const childBase = {
2281
2324
  parent,
2282
2325
  child: null,
2283
2326
  on: parent.on,
2284
2327
  loggers: parent.loggers,
2285
2328
  logger: parent.logger,
2286
2329
  config: parent.config,
2287
- transactionMeta: null,
2288
2330
  atoms: new LazyMap(parent.atoms),
2289
2331
  atomsThatAreDefault: new Set(parent.atomsThatAreDefault),
2290
2332
  families: new LazyMap(parent.families),
@@ -2301,12 +2343,12 @@ var buildTransaction = (key, params, store, id) => {
2301
2343
  selectors: new LazyMap(parent.selectors),
2302
2344
  valueMap: new LazyMap(parent.valueMap)
2303
2345
  };
2304
- child.transactionMeta = {
2346
+ const transactionMeta = {
2305
2347
  phase: `building`,
2306
- time: Date.now(),
2307
2348
  update: {
2308
2349
  key,
2309
2350
  id: id != null ? id : Math.random().toString(36).slice(2),
2351
+ epoch: isRootStore(parent) ? parent.transactionMeta.epoch + 1 : NaN,
2310
2352
  updates: [],
2311
2353
  params,
2312
2354
  output: void 0
@@ -2314,11 +2356,14 @@ var buildTransaction = (key, params, store, id) => {
2314
2356
  transactors: {
2315
2357
  get: (token) => atom_io.getState(token, child),
2316
2358
  set: (token, value) => atom_io.setState(token, value, child),
2317
- run: (token) => atom_io.runTransaction(token, child),
2318
- find: (token, key2) => atom_io.findInStore(token, key2, child),
2359
+ run: (token, id2) => atom_io.runTransaction(token, id2, child),
2360
+ find: (token, key2) => findInStore(token, key2, child),
2319
2361
  env: () => getEnvironmentData(child)
2320
2362
  }
2321
2363
  };
2364
+ const child = Object.assign(childBase, {
2365
+ transactionMeta
2366
+ });
2322
2367
  parent.child = child;
2323
2368
  store.logger.info(
2324
2369
  `\u{1F6EB}`,
@@ -2327,6 +2372,7 @@ var buildTransaction = (key, params, store, id) => {
2327
2372
  `Building transaction with params:`,
2328
2373
  params
2329
2374
  );
2375
+ return child;
2330
2376
  };
2331
2377
 
2332
2378
  // internal/src/transaction/create-transaction.ts
@@ -2335,10 +2381,10 @@ function createTransaction(options, store) {
2335
2381
  key: options.key,
2336
2382
  type: `transaction`,
2337
2383
  run: (params, id) => {
2338
- buildTransaction(options.key, params, store, id);
2384
+ const childStore = buildTransaction(options.key, params, store, id);
2339
2385
  try {
2340
2386
  const target2 = newest(store);
2341
- const { transactors } = target2.transactionMeta;
2387
+ const { transactors } = childStore.transactionMeta;
2342
2388
  const output = options.do(transactors, ...params);
2343
2389
  applyTransaction(output, target2);
2344
2390
  return output;
@@ -2396,6 +2442,7 @@ exports.deleteAtom = deleteAtom;
2396
2442
  exports.deleteSelector = deleteSelector;
2397
2443
  exports.deposit = deposit;
2398
2444
  exports.evictCachedValue = evictCachedValue;
2445
+ exports.findInStore = findInStore;
2399
2446
  exports.getEnvironmentData = getEnvironmentData;
2400
2447
  exports.getJsonFamily = getJsonFamily;
2401
2448
  exports.getJsonToken = getJsonToken;