atom.io 0.40.0 → 0.40.2

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 (134) hide show
  1. package/dist/data/index.d.ts +1 -1
  2. package/dist/data/index.d.ts.map +1 -1
  3. package/dist/data/index.js.map +1 -1
  4. package/dist/internal/index.d.ts +205 -196
  5. package/dist/internal/index.d.ts.map +1 -1
  6. package/dist/internal/index.js +145 -107
  7. package/dist/internal/index.js.map +1 -1
  8. package/dist/introspection/index.d.ts +6 -6
  9. package/dist/introspection/index.d.ts.map +1 -1
  10. package/dist/introspection/index.js.map +1 -1
  11. package/dist/main/index.d.ts +93 -66
  12. package/dist/main/index.d.ts.map +1 -1
  13. package/dist/main/index.js +16 -13
  14. package/dist/main/index.js.map +1 -1
  15. package/dist/react/index.d.ts +14 -14
  16. package/dist/react/index.d.ts.map +1 -1
  17. package/dist/react/index.js.map +1 -1
  18. package/dist/react-devtools/index.js +1 -1
  19. package/dist/react-devtools/index.js.map +1 -1
  20. package/dist/realtime-client/index.d.ts +3 -3
  21. package/dist/realtime-client/index.d.ts.map +1 -1
  22. package/dist/realtime-client/index.js +3 -4
  23. package/dist/realtime-client/index.js.map +1 -1
  24. package/dist/realtime-server/index.d.ts +2 -2
  25. package/dist/realtime-server/index.d.ts.map +1 -1
  26. package/package.json +2 -2
  27. package/src/data/struct.ts +2 -2
  28. package/src/internal/atom/create-regular-atom.ts +11 -9
  29. package/src/internal/atom/dispose-atom.ts +11 -8
  30. package/src/internal/atom/has-role.ts +1 -1
  31. package/src/internal/caching.ts +15 -15
  32. package/src/internal/events/ingest-creation-disposal.ts +1 -1
  33. package/src/internal/families/create-readonly-held-selector-family.ts +3 -4
  34. package/src/internal/families/create-readonly-pure-selector-family.ts +25 -23
  35. package/src/internal/families/create-regular-atom-family.ts +21 -15
  36. package/src/internal/families/create-selector-family.ts +15 -15
  37. package/src/internal/families/create-writable-held-selector-family.ts +2 -2
  38. package/src/internal/families/create-writable-pure-selector-family.ts +25 -21
  39. package/src/internal/families/dispose-from-store.ts +17 -7
  40. package/src/internal/families/find-in-store.ts +23 -23
  41. package/src/internal/families/get-family-of-token.ts +17 -17
  42. package/src/internal/families/mint-in-store.ts +10 -10
  43. package/src/internal/families/seek-in-store.ts +26 -26
  44. package/src/internal/get-state/get-fallback.ts +8 -8
  45. package/src/internal/get-state/get-from-store.ts +20 -8
  46. package/src/internal/get-state/read-or-compute-value.ts +78 -14
  47. package/src/internal/get-state/reduce-reference.ts +10 -10
  48. package/src/internal/index.ts +65 -60
  49. package/src/internal/install-into-store.ts +2 -1
  50. package/src/internal/join/create-join.ts +2 -2
  51. package/src/internal/join/find-relations-in-store.ts +2 -2
  52. package/src/internal/join/get-internal-relations-from-store.ts +2 -2
  53. package/src/internal/join/get-join.ts +5 -2
  54. package/src/internal/join/join-internal.ts +30 -26
  55. package/src/internal/lineage.ts +12 -1
  56. package/src/internal/molecule.ts +64 -36
  57. package/src/internal/mutable/create-mutable-atom-family.ts +5 -5
  58. package/src/internal/mutable/create-mutable-atom.ts +2 -2
  59. package/src/internal/mutable/get-json-family.ts +3 -2
  60. package/src/internal/mutable/get-update-family.ts +7 -5
  61. package/src/internal/mutable/tracker-family.ts +8 -4
  62. package/src/internal/mutable/tracker.ts +5 -1
  63. package/src/internal/operation.ts +4 -2
  64. package/src/internal/selector/create-readonly-held-selector.ts +2 -2
  65. package/src/internal/selector/create-readonly-pure-selector.ts +10 -8
  66. package/src/internal/selector/create-standalone-selector.ts +10 -10
  67. package/src/internal/selector/create-writable-held-selector.ts +2 -2
  68. package/src/internal/selector/create-writable-pure-selector.ts +11 -9
  69. package/src/internal/selector/dispose-selector.ts +2 -2
  70. package/src/internal/selector/register-selector.ts +2 -2
  71. package/src/internal/selector/trace-selector-atoms.ts +3 -3
  72. package/src/internal/selector/update-selector-atoms.ts +1 -1
  73. package/src/internal/set-state/become.ts +1 -3
  74. package/src/internal/set-state/dispatch-state-update.ts +10 -6
  75. package/src/internal/set-state/evict-downstream.ts +4 -1
  76. package/src/internal/set-state/operate-on-store.ts +16 -10
  77. package/src/internal/set-state/reset-atom-or-selector.ts +7 -7
  78. package/src/internal/set-state/reset-in-store.ts +17 -16
  79. package/src/internal/set-state/set-atom-or-selector.ts +1 -1
  80. package/src/internal/set-state/set-atom.ts +1 -1
  81. package/src/internal/set-state/set-into-store.ts +34 -7
  82. package/src/internal/set-state/set-selector.ts +1 -1
  83. package/src/internal/store/deposit.ts +38 -30
  84. package/src/internal/store/mint-or-counterfeit.ts +23 -23
  85. package/src/internal/store/store.ts +23 -21
  86. package/src/internal/store/withdraw.ts +68 -62
  87. package/src/internal/subscribe/recall-state.ts +4 -1
  88. package/src/internal/subscribe/subscribe-to-root-atoms.ts +2 -2
  89. package/src/internal/subscribe/subscribe-to-state.ts +4 -4
  90. package/src/internal/timeline/create-timeline.ts +11 -10
  91. package/src/internal/timeline/time-travel.ts +4 -3
  92. package/src/internal/transaction/abort-transaction.ts +3 -15
  93. package/src/internal/transaction/act-upon-store.ts +1 -5
  94. package/src/internal/transaction/apply-transaction.ts +3 -15
  95. package/src/internal/transaction/assign-transaction-to-continuity.ts +2 -7
  96. package/src/internal/transaction/build-transaction.ts +2 -3
  97. package/src/internal/transaction/create-transaction.ts +5 -6
  98. package/src/internal/transaction/get-epoch-number.ts +1 -7
  99. package/src/internal/transaction/set-epoch-number.ts +4 -12
  100. package/src/introspection/attach-atom-index.ts +2 -2
  101. package/src/introspection/attach-introspection-states.ts +4 -2
  102. package/src/introspection/attach-selector-index.ts +4 -2
  103. package/src/introspection/attach-timeline-family.ts +15 -13
  104. package/src/introspection/attach-timeline-index.ts +1 -1
  105. package/src/introspection/attach-transaction-index.ts +1 -1
  106. package/src/introspection/attach-transaction-logs.ts +6 -4
  107. package/src/introspection/attach-type-selectors.ts +4 -3
  108. package/src/introspection/index.ts +3 -5
  109. package/src/main/atom.ts +14 -8
  110. package/src/main/dispose-state.ts +1 -5
  111. package/src/main/events.ts +26 -26
  112. package/src/main/get-state.ts +10 -11
  113. package/src/main/realm.ts +36 -12
  114. package/src/main/reset-state.ts +5 -9
  115. package/src/main/selector.ts +40 -24
  116. package/src/main/set-state.ts +8 -11
  117. package/src/main/silo.ts +4 -3
  118. package/src/main/timeline.ts +5 -3
  119. package/src/main/tokens.ts +72 -44
  120. package/src/main/validators.ts +4 -4
  121. package/src/react/parse-state-overloads.ts +10 -10
  122. package/src/react/store-context.tsx +3 -3
  123. package/src/react/use-i.ts +6 -6
  124. package/src/react/use-loadable.ts +15 -15
  125. package/src/react/use-o.ts +9 -9
  126. package/src/react-devtools/Button.tsx +3 -2
  127. package/src/react-devtools/StateEditor.tsx +5 -3
  128. package/src/react-devtools/StateIndex.tsx +6 -4
  129. package/src/react-devtools/TimelineIndex.tsx +0 -2
  130. package/src/react-devtools/Updates.tsx +1 -1
  131. package/src/react-devtools/store.ts +18 -9
  132. package/src/realtime-client/continuity/register-and-attempt-confirmed-update.ts +4 -8
  133. package/src/realtime-client/sync-continuity.ts +2 -2
  134. package/src/realtime-server/index.ts +2 -2
@@ -13,6 +13,10 @@ function newest(scion) {
13
13
  while (scion.child !== null) scion = scion.child;
14
14
  return scion;
15
15
  }
16
+ function eldest(scion) {
17
+ while (scion.parent !== null) scion = scion.parent;
18
+ return scion;
19
+ }
16
20
 
17
21
  //#endregion
18
22
  //#region src/internal/store/circular-buffer.ts
@@ -564,7 +568,7 @@ function getFallback(store, token, family, subKey) {
564
568
  if (store.defaults.has(family.key)) return store.defaults.get(family.key);
565
569
  const defaultValue = new family.class();
566
570
  store.defaults.set(family.key, defaultValue);
567
- return defaultValue;
571
+ return defaultValue.READONLY_VIEW;
568
572
  }
569
573
  case `atom_family`: {
570
574
  if (store.defaults.has(family.key)) return store.defaults.get(family.key);
@@ -815,17 +819,58 @@ function readOrComputeValue(target, state, mut) {
815
819
  const { key } = state;
816
820
  switch (state.type) {
817
821
  case `readonly_held_selector`:
818
- case `readonly_pure_selector`:
819
822
  case `writable_held_selector`:
820
- case `writable_pure_selector`:
821
823
  target.logger.info(`🧮`, state.type, key, `computing value`);
822
824
  return state.getFrom(target);
825
+ case `readonly_pure_selector`:
826
+ case `writable_pure_selector`: {
827
+ let val;
828
+ target.logger.info(`🧮`, state.type, key, `computing value`);
829
+ try {
830
+ val = state.getFrom(target);
831
+ if (val instanceof Promise) return val.catch((e) => {
832
+ target.logger.error(`💥`, state.type, key, `rejected:`, e);
833
+ if (state.catch) {
834
+ for (const Class of state.catch) if (e instanceof Class) return writeToCache(target, state, e);
835
+ }
836
+ throw e;
837
+ });
838
+ } catch (e) {
839
+ target.logger.error(`💥`, state.type, key, `rejected:`, e);
840
+ if (state.catch) {
841
+ for (const Class of state.catch) if (e instanceof Class) return writeToCache(target, state, e);
842
+ }
843
+ throw e;
844
+ }
845
+ const cachedValue = writeToCache(target, state, val);
846
+ return cachedValue;
847
+ }
823
848
  case `atom`: {
824
849
  let def;
825
- if (isFn(state.default)) {
850
+ if (isFn(state.default)) try {
826
851
  def = state.default();
827
- target.logger.info(`✨`, state.type, key, `computed default`, def);
828
- } else {
852
+ if (def instanceof Promise) def = def.catch((e) => {
853
+ target.logger.error(`💥`, state.type, key, `rejected:`, e);
854
+ if (state.catch) {
855
+ for (const Class of state.catch) if (e instanceof Class) {
856
+ def = writeToCache(target, state, e);
857
+ return def;
858
+ }
859
+ }
860
+ throw e;
861
+ });
862
+ } catch (e) {
863
+ target.logger.error(`💥`, state.type, key, `rejected:`, e);
864
+ if (state.catch) {
865
+ for (const Class of state.catch) if (e instanceof Class) {
866
+ def = writeToCache(target, state, e);
867
+ target.logger.info(`✨`, state.type, key, `computed default`, def);
868
+ return def;
869
+ }
870
+ }
871
+ throw e;
872
+ }
873
+ else {
829
874
  def = state.default;
830
875
  target.logger.info(`✨`, state.type, key, `using static default`, def);
831
876
  }
@@ -872,31 +917,17 @@ function mintInStore(store, family, key, mustCreate) {
872
917
 
873
918
  //#endregion
874
919
  //#region src/internal/transaction/abort-transaction.ts
875
- const abortTransaction = (store) => {
876
- const target = newest(store);
877
- if (!isChildStore(target)) {
878
- store.logger.warn(`🐞`, `transaction`, `???`, `abortTransaction called outside of a transaction. This is probably a bug in AtomIO.`);
879
- return;
880
- }
881
- store.logger.info(`🪂`, `transaction`, target.transactionMeta.update.token.key, `Aborting transaction`);
920
+ const abortTransaction = (target) => {
921
+ target.logger.info(`🪂`, `transaction`, target.transactionMeta.update.token.key, `Aborting transaction`);
882
922
  target.parent.child = null;
883
923
  };
884
924
 
885
- //#endregion
886
- //#region src/internal/not-found-error.ts
887
- var NotFoundError = class extends Error {
888
- constructor(token, store) {
889
- super(`${PRETTY_TOKEN_TYPES[token.type]} ${stringifyJson(token.key)} not found in store "${store.config.name}".`);
890
- }
891
- };
892
-
893
925
  //#endregion
894
926
  //#region src/internal/transaction/act-upon-store.ts
895
927
  function actUponStore(store, token, id) {
896
928
  return (...parameters) => {
897
929
  const tx = withdraw(store, token);
898
- if (tx) return tx.run(parameters, id);
899
- throw new NotFoundError(token, store);
930
+ return tx.run(parameters, id);
900
931
  };
901
932
  }
902
933
 
@@ -971,17 +1002,8 @@ function setIntoStore(store, ...params) {
971
1002
  //#region src/internal/set-state/reset-in-store.ts
972
1003
  const RESET_STATE = Symbol(`RESET`);
973
1004
  function resetInStore(store, ...params) {
974
- let token;
975
- let family;
976
- let key;
977
- if (params.length === 1) {
978
- token = params[0];
979
- setIntoStore(store, token, RESET_STATE);
980
- } else {
981
- family = params[0];
982
- key = params[1];
983
- setIntoStore(store, family, key, RESET_STATE);
984
- }
1005
+ const subParams = [...params, RESET_STATE];
1006
+ setIntoStore(store, ...subParams);
985
1007
  }
986
1008
 
987
1009
  //#endregion
@@ -1099,25 +1121,42 @@ function fuseWithinStore(store, type, sideA, sideB) {
1099
1121
  allocateIntoStore(store, above, compoundKey, `all`);
1100
1122
  return compoundKey;
1101
1123
  }
1102
- function deallocateFromStore(store, claim) {
1124
+ function createDeallocateTX(store) {
1125
+ return createTransaction(store, {
1126
+ key: `[Internal] deallocate`,
1127
+ do: (_, claim) => {
1128
+ deallocateFromStore(newest(store), claim);
1129
+ }
1130
+ });
1131
+ }
1132
+ function deallocateFromStore(target, claim) {
1103
1133
  const stringKey = stringifyJson(claim);
1104
- const molecule = store.molecules.get(stringKey);
1134
+ const molecule = target.molecules.get(stringKey);
1105
1135
  if (!molecule) {
1106
- const disposal = store.disposalTraces.buffer.find((item) => item?.key === stringKey);
1107
- store.logger.error(`❌`, `key`, claim, `deallocation failed:`, `Could not find allocation for ${stringKey} in store "${store.config.name}".`, disposal ? `\n This state was most recently deallocated\n${disposal.trace}` : `No previous disposal trace for ${stringKey} was found.`);
1136
+ const disposal = target.disposalTraces.buffer.find((item) => item?.key === stringKey);
1137
+ target.logger.error(`❌`, `key`, claim, `deallocation failed:`, `Could not find allocation for ${stringKey} in store "${target.config.name}".`, disposal ? `\n This state was most recently deallocated\n${disposal.trace}` : `No previous disposal trace for ${stringKey} was found.`);
1108
1138
  return;
1109
1139
  }
1110
- const joinKeys = store.moleculeJoins.getRelatedKeys(molecule.key);
1140
+ const joinKeys = target.moleculeJoins.getRelatedKeys(stringKey);
1111
1141
  if (joinKeys) for (const joinKey of joinKeys) {
1112
- const join$1 = store.joins.get(joinKey);
1113
- if (join$1) {
1114
- join$1.relations.delete(molecule.key);
1115
- join$1.molecules.delete(molecule.stringKey);
1116
- }
1142
+ const join$1 = target.joins.get(joinKey);
1143
+ if (join$1) join$1.relations.delete(claim);
1117
1144
  }
1118
- store.moleculeJoins.delete(molecule.stringKey);
1145
+ target.moleculeJoins.delete(stringKey);
1119
1146
  const provenance = [];
1120
1147
  const values = [];
1148
+ const relatedMolecules = target.moleculeGraph.getRelationEntries({ downstreamMoleculeKey: stringKey });
1149
+ if (relatedMolecules) for (const [relatedStringKey, { source }] of relatedMolecules) if (source === stringKey) {
1150
+ const relatedKey = parseJson(relatedStringKey);
1151
+ deallocateFromStore(target, relatedKey);
1152
+ } else provenance.push(source);
1153
+ const familyKeys = target.moleculeData.getRelatedKeys(molecule.stringKey);
1154
+ if (familyKeys) for (const familyKey of familyKeys) {
1155
+ const family = target.families.get(familyKey);
1156
+ const value = getFromStore(target, family, claim);
1157
+ values.push([family.key, value]);
1158
+ disposeFromStore(target, family, claim);
1159
+ }
1121
1160
  const disposalEvent = {
1122
1161
  type: `molecule_disposal`,
1123
1162
  key: molecule.key,
@@ -1125,34 +1164,28 @@ function deallocateFromStore(store, claim) {
1125
1164
  provenance,
1126
1165
  timestamp: Date.now()
1127
1166
  };
1128
- const target = newest(store);
1129
1167
  target.molecules.delete(stringKey);
1130
1168
  const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
1131
1169
  if (isTransaction) target.transactionMeta.update.subEvents.push(disposalEvent);
1132
- const relatedMolecules = store.moleculeGraph.getRelationEntries({ downstreamMoleculeKey: molecule.stringKey });
1133
- if (relatedMolecules) for (const [relatedStringKey, { source }] of relatedMolecules) if (source === molecule.stringKey) {
1134
- const relatedKey = parseJson(relatedStringKey);
1135
- deallocateFromStore(store, relatedKey);
1136
- } else provenance.push(source);
1137
- const familyKeys = target.moleculeData.getRelatedKeys(molecule.stringKey);
1138
- if (familyKeys) for (const familyKey of familyKeys) {
1139
- const family = target.families.get(familyKey);
1140
- const token = findInStore(store, family, molecule.key);
1141
- const value = getFromStore(store, token);
1142
- values.push([family.key, value]);
1143
- disposeFromStore(store, token);
1144
- }
1145
1170
  target.moleculeGraph.delete(molecule.stringKey);
1146
1171
  target.moleculeJoins.delete(molecule.stringKey);
1147
1172
  target.moleculeData.delete(molecule.stringKey);
1148
1173
  if (!isTransaction) target.on.moleculeDisposal.next(disposalEvent);
1149
1174
  target.molecules.delete(molecule.stringKey);
1150
1175
  const trace = getTrace(/* @__PURE__ */ new Error());
1151
- store.disposalTraces.add({
1176
+ target.disposalTraces.add({
1152
1177
  key: stringKey,
1153
1178
  trace
1154
1179
  });
1155
1180
  }
1181
+ function createClaimTX(store) {
1182
+ return createTransaction(store, {
1183
+ key: `[Internal] claim`,
1184
+ do: (_, newProvenance, claim, exclusive) => {
1185
+ claimWithinStore(store, newProvenance, claim, exclusive);
1186
+ }
1187
+ });
1188
+ }
1156
1189
  function claimWithinStore(store, newProvenance, claim, exclusive) {
1157
1190
  const stringKey = stringifyJson(claim);
1158
1191
  const target = newest(store);
@@ -1314,8 +1347,6 @@ function getEpochNumberOfContinuity(store, continuityKey) {
1314
1347
  return epoch;
1315
1348
  }
1316
1349
  function getEpochNumberOfAction(store, transactionKey) {
1317
- const isRoot = isRootStore(store);
1318
- if (!isRoot) return void 0;
1319
1350
  const continuityKey = getContinuityKey(store, transactionKey);
1320
1351
  if (continuityKey === void 0) return void 0;
1321
1352
  return getEpochNumberOfContinuity(store, continuityKey);
@@ -1324,12 +1355,9 @@ function getEpochNumberOfAction(store, transactionKey) {
1324
1355
  //#endregion
1325
1356
  //#region src/internal/transaction/set-epoch-number.ts
1326
1357
  function setEpochNumberOfContinuity(store, continuityKey, newEpoch) {
1327
- const isRoot = isRootStore(store);
1328
- if (isRoot && continuityKey) store.transactionMeta.epoch.set(continuityKey, newEpoch);
1358
+ store.transactionMeta.epoch.set(continuityKey, newEpoch);
1329
1359
  }
1330
1360
  function setEpochNumberOfAction(store, transactionKey, newEpoch) {
1331
- const isRoot = isRootStore(store);
1332
- if (!isRoot) return;
1333
1361
  const continuityKey = getContinuityKey(store, transactionKey);
1334
1362
  if (continuityKey !== void 0) store.transactionMeta.epoch.set(continuityKey, newEpoch);
1335
1363
  }
@@ -1339,10 +1367,6 @@ function setEpochNumberOfAction(store, transactionKey, newEpoch) {
1339
1367
  function applyTransaction(store, output) {
1340
1368
  const child = newest(store);
1341
1369
  const { parent } = child;
1342
- if (parent === null || !isChildStore(child) || child.transactionMeta?.phase !== `building`) {
1343
- store.logger.warn(`🐞`, `transaction`, `???`, `applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`);
1344
- return;
1345
- }
1346
1370
  child.transactionMeta.phase = `applying`;
1347
1371
  child.transactionMeta.update.output = output;
1348
1372
  parent.child = null;
@@ -1365,8 +1389,6 @@ function applyTransaction(store, output) {
1365
1389
  //#endregion
1366
1390
  //#region src/internal/transaction/assign-transaction-to-continuity.ts
1367
1391
  function assignTransactionToContinuity(store, continuityKey, transactionKey) {
1368
- const isRoot = isRootStore(store);
1369
- if (!isRoot) return;
1370
1392
  const { epoch, actionContinuities } = store.transactionMeta;
1371
1393
  actionContinuities.set(continuityKey, transactionKey);
1372
1394
  if (!epoch.has(continuityKey)) epoch.set(continuityKey, -1);
@@ -1457,15 +1479,14 @@ function createTransaction(store, options) {
1457
1479
  type: `transaction`,
1458
1480
  run: (params, id) => {
1459
1481
  const token$1 = deposit(newTransaction);
1460
- const childStore = buildTransaction(store, token$1, params, id);
1482
+ const target$1 = buildTransaction(store, token$1, params, id);
1461
1483
  try {
1462
- const target$1 = newest(store);
1463
- const { toolkit } = childStore.transactionMeta;
1484
+ const { toolkit } = target$1.transactionMeta;
1464
1485
  const output = options.do(toolkit, ...params);
1465
1486
  applyTransaction(target$1, output);
1466
1487
  return output;
1467
1488
  } catch (thrown) {
1468
- abortTransaction(target);
1489
+ abortTransaction(target$1);
1469
1490
  store.logger.warn(`💥`, `transaction`, key, `caught:`, thrown);
1470
1491
  throw thrown;
1471
1492
  }
@@ -1495,7 +1516,7 @@ function dispatchOrDeferStateUpdate(target, state, { oldValue, newValue }, state
1495
1516
  if (stateIsNewlyCreated && family) {
1496
1517
  state.subject.next({ newValue });
1497
1518
  const stateCreationEvent = {
1498
- write: true,
1519
+ checkpoint: true,
1499
1520
  type: `state_creation`,
1500
1521
  subType: `writable`,
1501
1522
  token,
@@ -2017,10 +2038,12 @@ function createReadonlyPureSelectorFamily(store, options, internalRoles) {
2017
2038
  };
2018
2039
  const fullKey = `${familyKey}(${subKey})`;
2019
2040
  const target = newest(store);
2020
- const token = createReadonlyPureSelector(target, {
2041
+ const individualOptions = {
2021
2042
  key: fullKey,
2022
2043
  get: options.get(key)
2023
- }, family);
2044
+ };
2045
+ if (options.catch) individualOptions.catch = options.catch;
2046
+ const token = createReadonlyPureSelector(target, individualOptions, family);
2024
2047
  return token;
2025
2048
  };
2026
2049
  const readonlySelectorFamily = Object.assign(familyFunction, familyToken, {
@@ -2034,7 +2057,8 @@ function createReadonlyPureSelectorFamily(store, options, internalRoles) {
2034
2057
  find: ((...args) => findInStore(store, ...args)),
2035
2058
  json: (token) => getJsonToken(store, token)
2036
2059
  });
2037
- }
2060
+ },
2061
+ ...options.catch ? { catch: options.catch } : {}
2038
2062
  });
2039
2063
  store.families.set(familyKey, readonlySelectorFamily);
2040
2064
  return familyToken;
@@ -2064,14 +2088,17 @@ function createRegularAtomFamily(store, options, internalRoles) {
2064
2088
  default: isFn(def) ? () => def(key) : def
2065
2089
  };
2066
2090
  if (options.effects) individualOptions.effects = options.effects(key);
2091
+ if (options.catch) individualOptions.catch = options.catch;
2067
2092
  const token = createRegularAtom(target, individualOptions, family);
2068
2093
  return token;
2069
2094
  };
2070
- const atomFamily$1 = Object.assign(familyFunction, familyToken, {
2095
+ const atomFamily$1 = Object.assign(familyFunction, {
2096
+ ...familyToken,
2071
2097
  default: options.default,
2072
2098
  subject,
2073
2099
  install: (s) => createRegularAtomFamily(s, options),
2074
- internalRoles
2100
+ internalRoles,
2101
+ ...options.catch ? { catch: options.catch } : {}
2075
2102
  });
2076
2103
  store.families.set(options.key, atomFamily$1);
2077
2104
  if (isFn(options.default) === false) store.defaults.set(options.key, options.default);
@@ -2173,11 +2200,13 @@ function createWritablePureSelectorFamily(store, options, internalRoles) {
2173
2200
  };
2174
2201
  const fullKey = `${familyKey}(${subKey})`;
2175
2202
  const target = newest(store);
2176
- const token = createWritablePureSelector(target, {
2203
+ const individualOptions = {
2177
2204
  key: fullKey,
2178
2205
  get: options.get(key),
2179
2206
  set: options.set(key)
2180
- }, family);
2207
+ };
2208
+ if (options.catch) individualOptions.catch = options.catch;
2209
+ const token = createWritablePureSelector(target, individualOptions, family);
2181
2210
  return token;
2182
2211
  };
2183
2212
  const selectorFamily$1 = Object.assign(familyFunction, familyToken, {
@@ -2191,7 +2220,8 @@ function createWritablePureSelectorFamily(store, options, internalRoles) {
2191
2220
  find: ((...args) => findInStore(store, ...args)),
2192
2221
  json: (token) => getJsonToken(store, token)
2193
2222
  });
2194
- }
2223
+ },
2224
+ ...options.catch ? { catch: options.catch } : {}
2195
2225
  });
2196
2226
  store.families.set(familyKey, selectorFamily$1);
2197
2227
  return familyToken;
@@ -2985,14 +3015,14 @@ function disposeAtom(store, atomToken) {
2985
3015
  const familyToken = getFamilyOfToken(store, atomToken);
2986
3016
  const atomFamily$1 = withdraw(store, familyToken);
2987
3017
  const subject = atomFamily$1.subject;
2988
- const disposal = {
3018
+ const disposalEvent = {
2989
3019
  type: `state_disposal`,
2990
3020
  subType: `atom`,
2991
3021
  token: atomToken,
2992
3022
  value: lastValue,
2993
3023
  timestamp: Date.now()
2994
3024
  };
2995
- subject.next(disposal);
3025
+ subject.next(disposalEvent);
2996
3026
  const isChild = isChildStore(target);
2997
3027
  target.atoms.delete(key);
2998
3028
  target.valueMap.delete(key);
@@ -3010,7 +3040,8 @@ function disposeAtom(store, atomToken) {
3010
3040
  const mostRecentUpdate = target.transactionMeta.update.subEvents.at(-1);
3011
3041
  const wasMoleculeDisposal = mostRecentUpdate?.type === `molecule_disposal`;
3012
3042
  const updateAlreadyCaptured = wasMoleculeDisposal && mostRecentUpdate.values.some(([k]) => k === atom.family?.key);
3013
- if (!updateAlreadyCaptured) target.transactionMeta.update.subEvents.push(disposal);
3043
+ const isTracker = hasRole(atom, `tracker:signal`);
3044
+ if (!updateAlreadyCaptured && !isTracker) target.transactionMeta.update.subEvents.push(disposalEvent);
3014
3045
  } else store.on.atomDisposal.next(atomToken);
3015
3046
  }
3016
3047
  }
@@ -3062,7 +3093,6 @@ var Join = class {
3062
3093
  toolkit;
3063
3094
  options;
3064
3095
  defaultContent;
3065
- molecules = /* @__PURE__ */ new Map();
3066
3096
  relations;
3067
3097
  states;
3068
3098
  core;
@@ -3112,6 +3142,9 @@ var Join = class {
3112
3142
  bKeys.delete(a);
3113
3143
  return bKeys;
3114
3144
  });
3145
+ const [x, y] = [a, b].sort();
3146
+ const compositeKey = `${x}:${y}`;
3147
+ this.store.moleculeJoins.delete(compositeKey);
3115
3148
  };
3116
3149
  const replaceRelationsSafely = (toolkit, a, newRelationsOfA) => {
3117
3150
  const { find, get, set } = toolkit;
@@ -3141,9 +3174,9 @@ var Join = class {
3141
3174
  }
3142
3175
  if (!newRelationBIsAlreadyRelated && relationsOfB.size > 0) relationsOfB.clear();
3143
3176
  for (const previousOwner of previousOwnersToDispose) {
3144
- const sorted = [newRelationB, previousOwner].sort();
3145
- const compositeKey = `"${sorted[0]}:${sorted[1]}"`;
3146
- this.molecules.delete(compositeKey);
3177
+ const [x, y] = [newRelationB, previousOwner].sort();
3178
+ const compositeKey = `${x}:${y}`;
3179
+ store.moleculeJoins.delete(compositeKey);
3147
3180
  }
3148
3181
  }
3149
3182
  if (!newRelationBIsAlreadyRelated) relationsOfB.add(a);
@@ -3176,8 +3209,8 @@ var Join = class {
3176
3209
  const baseExternalStoreConfiguration = {
3177
3210
  getRelatedKeys: (key) => getRelatedKeys(this.toolkit, key),
3178
3211
  addRelation: (a, b) => {
3179
- this.store.moleculeJoins.set(a, options.key);
3180
- this.store.moleculeJoins.set(b, options.key);
3212
+ this.store.moleculeJoins.set(`"${a}"`, options.key);
3213
+ this.store.moleculeJoins.set(`"${b}"`, options.key);
3181
3214
  addRelation(this.toolkit, a, b);
3182
3215
  },
3183
3216
  deleteRelation: (a, b) => {
@@ -3210,9 +3243,7 @@ var Join = class {
3210
3243
  setContent: (contentKey, content) => {
3211
3244
  setContent(this.toolkit, contentKey, content);
3212
3245
  },
3213
- deleteContent: (contentKey) => {
3214
- this.realm.deallocate(contentKey);
3215
- }
3246
+ deleteContent: (_) => {}
3216
3247
  };
3217
3248
  externalStore = Object.assign(baseExternalStoreConfiguration, externalStoreWithContentConfiguration);
3218
3249
  } else externalStore = baseExternalStoreConfiguration;
@@ -3222,8 +3253,8 @@ var Join = class {
3222
3253
  isBType: options.isBType,
3223
3254
  makeContentKey: (...args) => {
3224
3255
  const [a, b] = args;
3225
- const sorted = args.sort();
3226
- const compositeKey = `${sorted[0]}:${sorted[1]}`;
3256
+ const [x, y] = args.sort();
3257
+ const compositeKey = `${x}:${y}`;
3227
3258
  const aMolecule = store.molecules.get(stringifyJson(a));
3228
3259
  const bMolecule = store.molecules.get(stringifyJson(b));
3229
3260
  if (!aMolecule) this.realm.allocate(options.key, a);
@@ -3381,7 +3412,8 @@ function getJoin(token, store) {
3381
3412
  const rootJoinMap = IMPLICIT.STORE.joins;
3382
3413
  const rootJoin = rootJoinMap.get(token.key);
3383
3414
  if (rootJoin === void 0) throw new Error(`Join "${token.key}" not found in store "${store.config.name}"`);
3384
- myJoin = new Join(rootJoin.options, rootJoin.defaultContent, store);
3415
+ const root = eldest(store);
3416
+ myJoin = new Join(rootJoin.options, rootJoin.defaultContent, root);
3385
3417
  store.joins.set(token.key, myJoin);
3386
3418
  }
3387
3419
  return myJoin;
@@ -3516,6 +3548,14 @@ function getInternalRelationsFromStore(token, store) {
3516
3548
  return family;
3517
3549
  }
3518
3550
 
3551
+ //#endregion
3552
+ //#region src/internal/not-found-error.ts
3553
+ var NotFoundError = class extends Error {
3554
+ constructor(token, store) {
3555
+ super(`${PRETTY_TOKEN_TYPES[token.type]} ${stringifyJson(token.key)} not found in store "${store.config.name}".`);
3556
+ }
3557
+ };
3558
+
3519
3559
  //#endregion
3520
3560
  //#region src/internal/reserved-keys.ts
3521
3561
  function isReservedIntrospectionKey(value) {
@@ -3608,7 +3648,7 @@ function addAtomToTimeline(store, atomToken, tl) {
3608
3648
  const timestamp = Date.now();
3609
3649
  tl.selectorTime = null;
3610
3650
  const atomUpdate = {
3611
- write: true,
3651
+ checkpoint: true,
3612
3652
  type: `atom_update`,
3613
3653
  token: deposit(atom),
3614
3654
  update,
@@ -3647,7 +3687,7 @@ function joinTransaction(store, tl, txUpdateInProgress) {
3647
3687
  const timelineTopics = store.timelineTopics.getRelatedKeys(tl.key);
3648
3688
  const subEventsFiltered = filterTransactionSubEvents(transactionUpdate.subEvents, timelineTopics);
3649
3689
  const timelineTransactionUpdate = {
3650
- write: true,
3690
+ checkpoint: true,
3651
3691
  ...transactionUpdate,
3652
3692
  subEvents: subEventsFiltered
3653
3693
  };
@@ -3660,7 +3700,7 @@ function buildSelectorUpdate(store, tl, atomToken, eventOrUpdate, currentSelecto
3660
3700
  let latestUpdate = tl.history.at(-1);
3661
3701
  if (currentSelectorTime !== tl.selectorTime) {
3662
3702
  const selectorUpdate = latestUpdate = {
3663
- write: true,
3703
+ checkpoint: true,
3664
3704
  type: `selector_update`,
3665
3705
  timestamp: currentSelectorTime,
3666
3706
  token: currentSelectorToken,
@@ -3768,7 +3808,7 @@ const timeTravel = (store, action, token) => {
3768
3808
  switch (action) {
3769
3809
  case `undo`:
3770
3810
  --nextIndex;
3771
- while (nextIndex !== 0 && timelineData.history[nextIndex].write !== true) --nextIndex;
3811
+ while (nextIndex !== 0 && timelineData.history[nextIndex].checkpoint !== true) --nextIndex;
3772
3812
  events = timelineData.history.slice(nextIndex, timelineData.at).reverse();
3773
3813
  break;
3774
3814
  case `redo`:
@@ -3793,8 +3833,6 @@ const timeTravel = (store, action, token) => {
3793
3833
  case `state_disposal`:
3794
3834
  ingestDisposalEvent(store, event, applying);
3795
3835
  break;
3796
- case `molecule_creation`:
3797
- case `molecule_disposal`:
3798
3836
  }
3799
3837
  timelineData.subject.next(action);
3800
3838
  timelineData.timeTraveling = null;
@@ -3802,5 +3840,5 @@ const timeTravel = (store, action, token) => {
3802
3840
  };
3803
3841
 
3804
3842
  //#endregion
3805
- export { COUNTERFEIT, CircularBuffer, FAMILY_MEMBER_TOKEN_TYPES, FamilyTracker, Future, IMPLICIT, INTERNAL_ROLES, Join, Junction, MapOverlay, NotFoundError, RESET_STATE, RelationsOverlay, SetOverlay, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, allocateIntoStore, applyTransaction, arbitrary, assignTransactionToContinuity, become, buildTransaction, capitalize, claimWithinStore, clearStore, closeOperation, createJoin, createMutableAtom, createMutableAtomFamily, createReadonlyHeldSelector, createReadonlyPureSelector, createReadonlyPureSelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneSelector, createTimeline, createTransaction, createWritableHeldSelector, createWritablePureSelector, createWritablePureSelectorFamily, deallocateFromStore, deposit, disposeAtom, disposeFromStore, disposeSelector, editRelationsInStore, evictCachedValue, evictDownstreamFromAtom, evictDownstreamFromSelector, findInStore, findRelationsInStore, fuseWithinStore, getContinuityKey, getEnvironmentData, getEpochNumberOfAction, getEpochNumberOfContinuity, getFromStore, getInternalRelationsFromStore, getJoin, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getTrace, getUpdateFamily, getUpdateToken, hasRole, ingestAtomUpdateEvent, ingestCreationEvent, ingestDisposalEvent, ingestMoleculeCreationEvent, ingestMoleculeDisposalEvent, ingestMoleculeTransferEvent, ingestSelectorUpdateEvent, ingestTransactionOutcomeEvent, installIntoStore, isAtomKey, isChildStore, isDone, isReadonlySelectorKey, isReservedIntrospectionKey, isRootStore, isSelectorKey, isStateKey, isTransceiver, makeRootMoleculeInStore, markDone, mint, newest, openOperation, readFromCache, readOrComputeValue, recallState, registerSelector, resetAtomOrSelector, resetInStore, seekInStore, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeInStore, subscribeToRootDependency, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceRootSelectorAtoms, updateSelectorAtoms, withdraw, writeToCache };
3843
+ export { COUNTERFEIT, CircularBuffer, FAMILY_MEMBER_TOKEN_TYPES, FamilyTracker, Future, IMPLICIT, INTERNAL_ROLES, Join, Junction, MapOverlay, NotFoundError, RESET_STATE, RelationsOverlay, SetOverlay, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, allocateIntoStore, applyTransaction, arbitrary, assignTransactionToContinuity, become, buildTransaction, capitalize, claimWithinStore, clearStore, closeOperation, createClaimTX, createDeallocateTX, createJoin, createMutableAtom, createMutableAtomFamily, createReadonlyHeldSelector, createReadonlyPureSelector, createReadonlyPureSelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneSelector, createTimeline, createTransaction, createWritableHeldSelector, createWritablePureSelector, createWritablePureSelectorFamily, deallocateFromStore, deposit, disposeAtom, disposeFromStore, disposeSelector, editRelationsInStore, eldest, evictCachedValue, evictDownstreamFromAtom, evictDownstreamFromSelector, findInStore, findRelationsInStore, fuseWithinStore, getContinuityKey, getEnvironmentData, getEpochNumberOfAction, getEpochNumberOfContinuity, getFromStore, getInternalRelationsFromStore, getJoin, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getTrace, getUpdateFamily, getUpdateToken, hasRole, ingestAtomUpdateEvent, ingestCreationEvent, ingestDisposalEvent, ingestMoleculeCreationEvent, ingestMoleculeDisposalEvent, ingestMoleculeTransferEvent, ingestSelectorUpdateEvent, ingestTransactionOutcomeEvent, installIntoStore, isAtomKey, isChildStore, isDone, isReadonlySelectorKey, isReservedIntrospectionKey, isRootStore, isSelectorKey, isStateKey, isTransceiver, makeRootMoleculeInStore, markDone, mint, newest, openOperation, readFromCache, readOrComputeValue, recallState, registerSelector, resetAtomOrSelector, resetInStore, seekInStore, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeInStore, subscribeToRootDependency, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceRootSelectorAtoms, updateSelectorAtoms, withdraw, writeToCache };
3806
3844
  //# sourceMappingURL=index.js.map