atom.io 0.16.2 → 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 (90) hide show
  1. package/dist/chunk-H4Q5FTPZ.js +11 -0
  2. package/dist/chunk-H4Q5FTPZ.js.map +1 -0
  3. package/dist/index.cjs +1 -11
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.ts +6 -6
  6. package/dist/index.js +2 -11
  7. package/dist/index.js.map +1 -1
  8. package/internal/dist/index.cjs +225 -183
  9. package/internal/dist/index.cjs.map +1 -1
  10. package/internal/dist/index.d.ts +30 -9
  11. package/internal/dist/index.js +218 -184
  12. package/internal/dist/index.js.map +1 -1
  13. package/internal/src/families/find-in-store.ts +74 -0
  14. package/internal/src/families/index.ts +1 -0
  15. package/internal/src/ingest-updates/ingest-transaction-update.ts +1 -0
  16. package/internal/src/mutable/tracker.ts +28 -25
  17. package/internal/src/mutable/transceiver.ts +1 -1
  18. package/internal/src/not-found-error.ts +14 -3
  19. package/internal/src/operation.ts +2 -1
  20. package/internal/src/selector/create-writable-selector.ts +2 -1
  21. package/internal/src/selector/register-selector.ts +5 -4
  22. package/internal/src/set-state/set-atom.ts +16 -2
  23. package/internal/src/set-state/stow-update.ts +2 -4
  24. package/internal/src/store/store.ts +13 -4
  25. package/internal/src/timeline/add-atom-to-timeline.ts +5 -5
  26. package/internal/src/transaction/abort-transaction.ts +2 -1
  27. package/internal/src/transaction/apply-transaction.ts +5 -3
  28. package/internal/src/transaction/build-transaction.ts +16 -9
  29. package/internal/src/transaction/create-transaction.ts +2 -3
  30. package/internal/src/transaction/index.ts +3 -2
  31. package/internal/src/transaction/is-root-store.ts +23 -0
  32. package/package.json +10 -10
  33. package/react/dist/index.cjs +27 -21
  34. package/react/dist/index.cjs.map +1 -1
  35. package/react/dist/index.d.ts +8 -2
  36. package/react/dist/index.js +27 -21
  37. package/react/dist/index.js.map +1 -1
  38. package/react/src/index.ts +4 -1
  39. package/react/src/use-i.ts +36 -0
  40. package/react/src/use-json.ts +38 -0
  41. package/react/src/use-o.ts +34 -0
  42. package/react/src/use-tl.ts +45 -0
  43. package/realtime-client/dist/index.cjs +163 -63
  44. package/realtime-client/dist/index.cjs.map +1 -1
  45. package/realtime-client/dist/index.d.ts +10 -6
  46. package/realtime-client/dist/index.js +153 -61
  47. package/realtime-client/dist/index.js.map +1 -1
  48. package/realtime-client/src/index.ts +2 -1
  49. package/realtime-client/src/pull-state.ts +4 -3
  50. package/realtime-client/src/{realtime-client-store.ts → realtime-client-stores/client-main-store.ts} +0 -8
  51. package/realtime-client/src/realtime-client-stores/client-sync-store.ts +15 -0
  52. package/realtime-client/src/realtime-client-stores/index.ts +2 -0
  53. package/realtime-client/src/sync-server-action.ts +131 -40
  54. package/realtime-client/src/sync-state.ts +19 -0
  55. package/realtime-react/dist/index.cjs +43 -26
  56. package/realtime-react/dist/index.cjs.map +1 -1
  57. package/realtime-react/dist/index.d.ts +3 -1
  58. package/realtime-react/dist/index.js +41 -25
  59. package/realtime-react/dist/index.js.map +1 -1
  60. package/realtime-react/src/index.ts +1 -0
  61. package/realtime-react/src/on-mount.ts +3 -21
  62. package/realtime-react/src/use-realtime-service.ts +1 -1
  63. package/realtime-react/src/use-single-effect.ts +29 -0
  64. package/realtime-react/src/use-sync-server-action.ts +4 -7
  65. package/realtime-react/src/use-sync.ts +17 -0
  66. package/realtime-server/dist/index.cjs +223 -40
  67. package/realtime-server/dist/index.cjs.map +1 -1
  68. package/realtime-server/dist/index.d.ts +140 -9
  69. package/realtime-server/dist/index.js +213 -43
  70. package/realtime-server/dist/index.js.map +1 -1
  71. package/realtime-server/src/index.ts +2 -0
  72. package/realtime-server/src/realtime-action-synchronizer.ts +87 -12
  73. package/realtime-server/src/realtime-family-provider.ts +2 -2
  74. package/realtime-server/src/realtime-mutable-family-provider.ts +2 -1
  75. package/realtime-server/src/realtime-server-stores/index.ts +2 -0
  76. package/realtime-server/src/realtime-server-stores/server-sync-store.ts +115 -0
  77. package/realtime-server/src/realtime-server-stores/server-user-store.ts +45 -0
  78. package/realtime-server/src/realtime-state-provider.ts +15 -8
  79. package/realtime-server/src/realtime-state-synchronizer.ts +23 -0
  80. package/realtime-testing/dist/index.cjs +65 -26
  81. package/realtime-testing/dist/index.cjs.map +1 -1
  82. package/realtime-testing/dist/index.d.ts +11 -7
  83. package/realtime-testing/dist/index.js +64 -26
  84. package/realtime-testing/dist/index.js.map +1 -1
  85. package/realtime-testing/src/setup-realtime-test.tsx +83 -43
  86. package/src/find-state.ts +8 -16
  87. package/src/logger.ts +1 -0
  88. package/src/transaction.ts +3 -3
  89. package/react/src/store-hooks.ts +0 -87
  90. 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,7 +935,7 @@ 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
940
  } else if (target.parent) {
785
941
  if (target.on.transactionApplying.state === null) {
@@ -789,7 +945,16 @@ var setAtom = (atom, next, target) => {
789
945
  const mutableAtom = target.atoms.get(mutableKey);
790
946
  let mutable = target.valueMap.get(mutableKey);
791
947
  mutable = copyMutableIfWithinTransaction(mutable, mutableAtom, target);
792
- mutable.do(update.newValue);
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
+ }
793
958
  }
794
959
  }
795
960
  };
@@ -887,11 +1052,12 @@ var updateSelectorAtoms = (selectorKey, dependency, store) => {
887
1052
  // internal/src/selector/register-selector.ts
888
1053
  var registerSelector = (selectorKey, store) => ({
889
1054
  get: (dependency) => {
1055
+ var _a;
890
1056
  const target = newest(store);
891
- const dependencyState = withdraw(dependency, store);
1057
+ const dependencyState = (_a = withdraw(dependency, store)) != null ? _a : withdrawNewFamilyMember(dependency, store);
892
1058
  if (dependencyState === void 0) {
893
1059
  throw new Error(
894
- `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}".`
895
1061
  );
896
1062
  }
897
1063
  const dependencyValue = readOrComputeValue(dependencyState, store);
@@ -924,7 +1090,7 @@ var registerSelector = (selectorKey, store) => ({
924
1090
  }
925
1091
  setAtomOrSelector(state, newValue, store);
926
1092
  },
927
- find: (token, key) => atom_io.findInStore(token, key, store)
1093
+ find: (token, key) => findInStore(token, key, store)
928
1094
  });
929
1095
 
930
1096
  // internal/src/selector/create-readonly-selector.ts
@@ -990,7 +1156,7 @@ var createWritableSelector = (options, family, store) => {
990
1156
  );
991
1157
  cacheValue(options.key, newValue, subject, store);
992
1158
  markDone(options.key, store);
993
- if (target.transactionMeta === null) {
1159
+ if (isRootStore(target)) {
994
1160
  subject.next({ newValue, oldValue });
995
1161
  }
996
1162
  options.set(transactors, newValue);
@@ -1208,12 +1374,11 @@ var Tracker = class {
1208
1374
  }
1209
1375
  return latestUpdateState;
1210
1376
  }
1211
- observeCore(mutableState, latestUpdateState, store) {
1212
- const subscriptionKey = `tracker:${store.config.name}:${store.transactionMeta === null ? `main` : store.transactionMeta.update.key}:${mutableState.key}`;
1213
- const originalInnerValue = atom_io.getState(mutableState, store);
1214
- 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);
1215
1380
  this.unsubscribeFromInnerValue = originalInnerValue.subscribe(
1216
- `tracker:${store.config.name}:${target.transactionMeta === null ? `main` : target.transactionMeta.update.key}`,
1381
+ subscriptionKey,
1217
1382
  (update) => {
1218
1383
  if (target.operation.open) {
1219
1384
  const unsubscribe = target.on.operationClose.subscribe(
@@ -1234,40 +1399,39 @@ var Tracker = class {
1234
1399
  (update) => {
1235
1400
  if (update.newValue !== update.oldValue) {
1236
1401
  this.unsubscribeFromInnerValue();
1237
- const target2 = newest(store);
1238
1402
  this.unsubscribeFromInnerValue = update.newValue.subscribe(
1239
1403
  subscriptionKey,
1240
1404
  (update2) => {
1241
- if (target2.operation.open) {
1242
- const unsubscribe = target2.on.operationClose.subscribe(
1405
+ if (target.operation.open) {
1406
+ const unsubscribe = target.on.operationClose.subscribe(
1243
1407
  subscriptionKey,
1244
1408
  () => {
1245
1409
  unsubscribe();
1246
- atom_io.setState(latestUpdateState, update2, target2);
1410
+ atom_io.setState(latestUpdateState, update2, target);
1247
1411
  }
1248
1412
  );
1249
1413
  } else {
1250
- atom_io.setState(mutableState, (current) => current, target2);
1251
- atom_io.setState(latestUpdateState, update2, target2);
1414
+ atom_io.setState(mutableState, (current) => current, target);
1415
+ atom_io.setState(latestUpdateState, update2, target);
1252
1416
  }
1253
1417
  }
1254
1418
  );
1255
1419
  }
1256
1420
  },
1257
1421
  subscriptionKey,
1258
- store
1422
+ target
1259
1423
  );
1260
1424
  }
1261
- updateCore(mutableState, latestUpdateState, store) {
1262
- const subscriptionKey = `tracker:${store.config.name}:${store.transactionMeta === null ? `main` : store.transactionMeta.update.key}:${mutableState.key}`;
1425
+ updateCore(mutableState, latestUpdateState, target) {
1426
+ const subscriptionKey = `tracker:${target.config.name}:${isChildStore(target) ? target.transactionMeta.update.key : `main`}:${mutableState.key}`;
1263
1427
  subscribeToState(
1264
1428
  latestUpdateState,
1265
1429
  ({ newValue, oldValue }) => {
1266
- const timelineId = store.timelineAtoms.getRelatedKey(
1430
+ const timelineId = target.timelineAtoms.getRelatedKey(
1267
1431
  latestUpdateState.key
1268
1432
  );
1269
1433
  if (timelineId) {
1270
- const timelineData = store.timelines.get(timelineId);
1434
+ const timelineData = target.timelines.get(timelineId);
1271
1435
  if (timelineData == null ? void 0 : timelineData.timeTraveling) {
1272
1436
  const unsubscribe2 = subscribeToTimeline(
1273
1437
  { key: timelineId, type: `timeline` },
@@ -1283,34 +1447,41 @@ var Tracker = class {
1283
1447
  }
1284
1448
  return transceiver;
1285
1449
  },
1286
- store
1450
+ target
1287
1451
  );
1288
1452
  },
1289
1453
  subscriptionKey,
1290
- store
1454
+ target
1291
1455
  );
1292
1456
  return;
1293
1457
  }
1294
1458
  }
1295
- const unsubscribe = store.on.operationClose.subscribe(
1459
+ const unsubscribe = target.on.operationClose.subscribe(
1296
1460
  subscriptionKey,
1297
1461
  () => {
1298
1462
  unsubscribe();
1299
- const mutable = atom_io.getState(mutableState, store);
1463
+ const mutable = atom_io.getState(mutableState, target);
1300
1464
  const updateNumber = newValue === null ? -1 : mutable.getUpdateNumber(newValue);
1301
1465
  const eventOffset = updateNumber - mutable.cacheUpdateNumber;
1302
1466
  if (newValue && eventOffset === 1) {
1303
1467
  atom_io.setState(
1304
1468
  mutableState,
1305
1469
  (transceiver) => (transceiver.do(newValue), transceiver),
1306
- 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}`
1307
1478
  );
1308
1479
  }
1309
1480
  }
1310
1481
  );
1311
1482
  },
1312
1483
  subscriptionKey,
1313
- store
1484
+ target
1314
1485
  );
1315
1486
  }
1316
1487
  constructor(mutableState, store) {
@@ -1393,125 +1564,6 @@ function createMutableAtom(options, family, store) {
1393
1564
  store.on.atomCreation.next(token);
1394
1565
  return token;
1395
1566
  }
1396
- function createRegularAtomFamily(options, store) {
1397
- const subject = new Subject();
1398
- const atomFamily = Object.assign(
1399
- (key) => {
1400
- const subKey = json.stringifyJson(key);
1401
- const family = { key: options.key, subKey };
1402
- const fullKey = `${options.key}(${subKey})`;
1403
- const existing = withdraw({ key: fullKey, type: `atom` }, store);
1404
- let token;
1405
- if (existing) {
1406
- token = deposit(existing);
1407
- } else {
1408
- const individualOptions = {
1409
- key: fullKey,
1410
- default: options.default instanceof Function ? options.default(key) : options.default
1411
- };
1412
- if (options.effects) {
1413
- individualOptions.effects = options.effects(key);
1414
- }
1415
- token = createRegularAtom(individualOptions, family, store);
1416
- subject.next(token);
1417
- }
1418
- return token;
1419
- },
1420
- {
1421
- key: options.key,
1422
- type: `atom_family`,
1423
- subject,
1424
- install: (store2) => createRegularAtomFamily(options, store2)
1425
- }
1426
- );
1427
- const target = newest(store);
1428
- target.families.set(options.key, atomFamily);
1429
- return atomFamily;
1430
- }
1431
-
1432
- // internal/src/families/create-atom-family.ts
1433
- function createAtomFamily(options, store) {
1434
- const isMutable2 = `mutable` in options;
1435
- if (isMutable2) {
1436
- return createMutableAtomFamily(options, store);
1437
- }
1438
- return createRegularAtomFamily(options, store);
1439
- }
1440
- function createReadonlySelectorFamily(options, store) {
1441
- const subject = new Subject();
1442
- const readonlySelectorFamily = Object.assign(
1443
- (key) => {
1444
- const target = newest(store);
1445
- const subKey = json.stringifyJson(key);
1446
- const family = { key: options.key, subKey };
1447
- const fullKey = `${options.key}(${subKey})`;
1448
- const existing = target.readonlySelectors.get(fullKey);
1449
- if (existing) {
1450
- return deposit(existing);
1451
- }
1452
- return createReadonlySelector(
1453
- {
1454
- key: fullKey,
1455
- get: options.get(key)
1456
- },
1457
- family,
1458
- store
1459
- );
1460
- },
1461
- {
1462
- key: options.key,
1463
- type: `readonly_selector_family`,
1464
- subject,
1465
- install: (store2) => createReadonlySelectorFamily(options, store2)
1466
- }
1467
- );
1468
- store.families.set(options.key, readonlySelectorFamily);
1469
- return readonlySelectorFamily;
1470
- }
1471
- function createWritableSelectorFamily(options, store) {
1472
- const subject = new Subject();
1473
- const selectorFamily = Object.assign(
1474
- (key) => {
1475
- const subKey = json.stringifyJson(key);
1476
- const family = { key: options.key, subKey };
1477
- const fullKey = `${options.key}(${subKey})`;
1478
- const existing = store.selectors.get(fullKey);
1479
- if (existing) {
1480
- return deposit(existing);
1481
- }
1482
- const token = createWritableSelector(
1483
- {
1484
- key: fullKey,
1485
- get: options.get(key),
1486
- set: options.set(key)
1487
- },
1488
- family,
1489
- store
1490
- );
1491
- subject.next(token);
1492
- return token;
1493
- },
1494
- {
1495
- key: options.key,
1496
- type: `selector_family`,
1497
- subject,
1498
- install: (store2) => createWritableSelectorFamily(options, store2)
1499
- }
1500
- );
1501
- store.families.set(options.key, selectorFamily);
1502
- return selectorFamily;
1503
- }
1504
-
1505
- // internal/src/families/create-selector-family.ts
1506
- function createSelectorFamily(options, store) {
1507
- const isWritable = `set` in options;
1508
- if (isWritable) {
1509
- return createWritableSelectorFamily(options, store);
1510
- }
1511
- return createReadonlySelectorFamily(options, store);
1512
- }
1513
-
1514
- // internal/src/mutable/tracker-family.ts
1515
1567
  var FamilyTracker = class {
1516
1568
  constructor(findMutableState, store) {
1517
1569
  this.findLatestUpdateState = createRegularAtomFamily(
@@ -1826,22 +1878,6 @@ var LazyMap = class extends Map {
1826
1878
  }
1827
1879
  };
1828
1880
 
1829
- // internal/src/not-found-error.ts
1830
- var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
1831
- function prettyPrintTokenType(token) {
1832
- if (token.type === `readonly_selector`) {
1833
- return `Readonly Selector`;
1834
- }
1835
- return capitalize(token.type);
1836
- }
1837
- var NotFoundError = class extends Error {
1838
- constructor(token, store) {
1839
- super(
1840
- `${prettyPrintTokenType(token)} "${token.key}" not found in store "${store.config.name}".`
1841
- );
1842
- }
1843
- };
1844
-
1845
1881
  // internal/src/timeline/add-atom-to-timeline.ts
1846
1882
  var addAtomToTimeline = (atomToken, tl, store) => {
1847
1883
  let maybeAtom = withdraw(atomToken, store);
@@ -1861,8 +1897,9 @@ var addAtomToTimeline = (atomToken, tl, store) => {
1861
1897
  const target = newest(store);
1862
1898
  const currentSelectorKey = store.operation.open && store.operation.token.type === `selector` ? store.operation.token.key : null;
1863
1899
  const currentSelectorTime = store.operation.open && store.operation.token.type === `selector` ? store.operation.time : null;
1864
- const currentTransactionKey = (_a = target.on.transactionApplying.state) == null ? void 0 : _a.update.key;
1865
- 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;
1866
1903
  store.logger.info(
1867
1904
  `\u23F3`,
1868
1905
  `timeline`,
@@ -1909,7 +1946,7 @@ var addAtomToTimeline = (atomToken, tl, store) => {
1909
1946
  (update2) => {
1910
1947
  var _a2, _b2;
1911
1948
  unsubscribe();
1912
- if (tl.timeTraveling === null && currentTransactionTime) {
1949
+ if (tl.timeTraveling === null && currentTransactionInstanceId) {
1913
1950
  if (tl.at !== tl.history.length) {
1914
1951
  tl.history.splice(tl.at);
1915
1952
  }
@@ -1936,7 +1973,7 @@ var addAtomToTimeline = (atomToken, tl, store) => {
1936
1973
  const updates = filterUpdates(update2.updates);
1937
1974
  const timelineTransactionUpdate = __spreadProps(__spreadValues({
1938
1975
  type: `transaction_update`,
1939
- timestamp: currentTransactionTime
1976
+ timestamp: Date.now()
1940
1977
  }, update2), {
1941
1978
  updates
1942
1979
  });
@@ -2198,7 +2235,7 @@ var timeTravel = (action, token, store) => {
2198
2235
  // internal/src/transaction/abort-transaction.ts
2199
2236
  var abortTransaction = (store) => {
2200
2237
  const target = newest(store);
2201
- if (target.transactionMeta === null || target.parent === null) {
2238
+ if (!isChildStore(target)) {
2202
2239
  store.logger.warn(
2203
2240
  `\u{1F41E}`,
2204
2241
  `transaction`,
@@ -2221,7 +2258,7 @@ var applyTransaction = (output, store) => {
2221
2258
  var _a;
2222
2259
  const child = newest(store);
2223
2260
  const { parent } = child;
2224
- 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`) {
2225
2262
  store.logger.warn(
2226
2263
  `\u{1F41E}`,
2227
2264
  `transaction`,
@@ -2263,7 +2300,8 @@ var applyTransaction = (output, store) => {
2263
2300
  }
2264
2301
  }
2265
2302
  ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
2266
- if (parent.transactionMeta === null) {
2303
+ if (isRootStore(parent)) {
2304
+ parent.transactionMeta.epoch = child.transactionMeta.update.epoch;
2267
2305
  const myTransaction = withdraw(
2268
2306
  { key: child.transactionMeta.update.key, type: `transaction` },
2269
2307
  store
@@ -2275,21 +2313,20 @@ var applyTransaction = (output, store) => {
2275
2313
  child.transactionMeta.update.key,
2276
2314
  `Finished applying transaction.`
2277
2315
  );
2278
- } else {
2316
+ } else if (isChildStore(parent)) {
2279
2317
  parent.transactionMeta.update.updates.push(child.transactionMeta.update);
2280
2318
  }
2281
2319
  parent.on.transactionApplying.next(null);
2282
2320
  };
2283
2321
  var buildTransaction = (key, params, store, id) => {
2284
2322
  const parent = newest(store);
2285
- const child = {
2323
+ const childBase = {
2286
2324
  parent,
2287
2325
  child: null,
2288
2326
  on: parent.on,
2289
2327
  loggers: parent.loggers,
2290
2328
  logger: parent.logger,
2291
2329
  config: parent.config,
2292
- transactionMeta: null,
2293
2330
  atoms: new LazyMap(parent.atoms),
2294
2331
  atomsThatAreDefault: new Set(parent.atomsThatAreDefault),
2295
2332
  families: new LazyMap(parent.families),
@@ -2306,12 +2343,12 @@ var buildTransaction = (key, params, store, id) => {
2306
2343
  selectors: new LazyMap(parent.selectors),
2307
2344
  valueMap: new LazyMap(parent.valueMap)
2308
2345
  };
2309
- child.transactionMeta = {
2346
+ const transactionMeta = {
2310
2347
  phase: `building`,
2311
- time: Date.now(),
2312
2348
  update: {
2313
2349
  key,
2314
2350
  id: id != null ? id : Math.random().toString(36).slice(2),
2351
+ epoch: isRootStore(parent) ? parent.transactionMeta.epoch + 1 : NaN,
2315
2352
  updates: [],
2316
2353
  params,
2317
2354
  output: void 0
@@ -2320,10 +2357,13 @@ var buildTransaction = (key, params, store, id) => {
2320
2357
  get: (token) => atom_io.getState(token, child),
2321
2358
  set: (token, value) => atom_io.setState(token, value, child),
2322
2359
  run: (token, id2) => atom_io.runTransaction(token, id2, child),
2323
- find: (token, key2) => atom_io.findInStore(token, key2, child),
2360
+ find: (token, key2) => findInStore(token, key2, child),
2324
2361
  env: () => getEnvironmentData(child)
2325
2362
  }
2326
2363
  };
2364
+ const child = Object.assign(childBase, {
2365
+ transactionMeta
2366
+ });
2327
2367
  parent.child = child;
2328
2368
  store.logger.info(
2329
2369
  `\u{1F6EB}`,
@@ -2332,6 +2372,7 @@ var buildTransaction = (key, params, store, id) => {
2332
2372
  `Building transaction with params:`,
2333
2373
  params
2334
2374
  );
2375
+ return child;
2335
2376
  };
2336
2377
 
2337
2378
  // internal/src/transaction/create-transaction.ts
@@ -2340,10 +2381,10 @@ function createTransaction(options, store) {
2340
2381
  key: options.key,
2341
2382
  type: `transaction`,
2342
2383
  run: (params, id) => {
2343
- buildTransaction(options.key, params, store, id);
2384
+ const childStore = buildTransaction(options.key, params, store, id);
2344
2385
  try {
2345
2386
  const target2 = newest(store);
2346
- const { transactors } = target2.transactionMeta;
2387
+ const { transactors } = childStore.transactionMeta;
2347
2388
  const output = options.do(transactors, ...params);
2348
2389
  applyTransaction(output, target2);
2349
2390
  return output;
@@ -2401,6 +2442,7 @@ exports.deleteAtom = deleteAtom;
2401
2442
  exports.deleteSelector = deleteSelector;
2402
2443
  exports.deposit = deposit;
2403
2444
  exports.evictCachedValue = evictCachedValue;
2445
+ exports.findInStore = findInStore;
2404
2446
  exports.getEnvironmentData = getEnvironmentData;
2405
2447
  exports.getJsonFamily = getJsonFamily;
2406
2448
  exports.getJsonToken = getJsonToken;