atom.io 0.37.0 → 0.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/internal/index.d.ts +32 -33
  2. package/dist/internal/index.d.ts.map +1 -1
  3. package/dist/internal/index.js +200 -133
  4. package/dist/internal/index.js.map +1 -1
  5. package/dist/json/index.d.ts +1 -1
  6. package/dist/json/index.d.ts.map +1 -1
  7. package/dist/json/index.js.map +1 -1
  8. package/dist/main/index.d.ts +6 -3
  9. package/dist/main/index.d.ts.map +1 -1
  10. package/dist/main/index.js +22 -2
  11. package/dist/main/index.js.map +1 -1
  12. package/package.json +2 -2
  13. package/src/internal/atom/dispose-atom.ts +11 -6
  14. package/src/internal/families/create-readonly-held-selector-family.ts +2 -4
  15. package/src/internal/families/create-readonly-pure-selector-family.ts +2 -4
  16. package/src/internal/families/create-regular-atom-family.ts +7 -5
  17. package/src/internal/families/create-writable-held-selector-family.ts +3 -4
  18. package/src/internal/families/create-writable-pure-selector-family.ts +2 -4
  19. package/src/internal/families/find-in-store.ts +7 -1
  20. package/src/internal/families/get-family-of-token.ts +21 -24
  21. package/src/internal/families/mint-in-store.ts +59 -35
  22. package/src/internal/get-state/get-fallback.ts +57 -0
  23. package/src/internal/get-state/get-from-store.ts +10 -47
  24. package/src/internal/get-state/reduce-reference.ts +66 -0
  25. package/src/internal/index.ts +17 -30
  26. package/src/internal/ingest-updates/ingest-creation-disposal.ts +4 -3
  27. package/src/internal/molecule.ts +5 -5
  28. package/src/internal/mutable/create-mutable-atom-family.ts +4 -8
  29. package/src/internal/mutable/get-json-token.ts +2 -1
  30. package/src/internal/not-found-error.ts +2 -3
  31. package/src/internal/operation.ts +1 -1
  32. package/src/internal/selector/register-selector.ts +17 -24
  33. package/src/internal/selector/update-selector-atoms.ts +2 -2
  34. package/src/internal/set-state/operate-on-store.ts +17 -13
  35. package/src/internal/set-state/set-into-store.ts +2 -2
  36. package/src/internal/store/index.ts +1 -1
  37. package/src/internal/store/{counterfeit.ts → mint-or-counterfeit.ts} +27 -15
  38. package/src/internal/subscribe/subscribe-to-state.ts +2 -0
  39. package/src/internal/timeline/create-timeline.ts +2 -0
  40. package/src/json/index.ts +3 -3
  41. package/src/main/logger.ts +26 -4
  42. package/src/internal/pretty-print.ts +0 -7
@@ -1,5 +1,5 @@
1
1
  import { parseJson, stringifyJson } from "atom.io/json";
2
- import { Anarchy, AtomIOLogger } from "atom.io";
2
+ import { Anarchy, AtomIOLogger, PRETTY_TOKEN_TYPES } from "atom.io";
3
3
  import { SetRTX } from "atom.io/transceivers/set-rtx";
4
4
 
5
5
  //#region src/internal/arbitrary.ts
@@ -43,7 +43,19 @@ var CircularBuffer = class CircularBuffer {
43
43
  };
44
44
 
45
45
  //#endregion
46
- //#region src/internal/store/counterfeit.ts
46
+ //#region src/internal/store/deposit.ts
47
+ function deposit(state) {
48
+ const token = {
49
+ key: state.key,
50
+ type: state.type
51
+ };
52
+ if (`family` in state) token.family = state.family;
53
+ return token;
54
+ }
55
+
56
+ //#endregion
57
+ //#region src/internal/store/mint-or-counterfeit.ts
58
+ const COUNTERFEIT = Symbol(`counterfeit`);
47
59
  const FAMILY_MEMBER_TOKEN_TYPES = {
48
60
  atom_family: `atom`,
49
61
  molecule_family: `molecule`,
@@ -53,33 +65,22 @@ const FAMILY_MEMBER_TOKEN_TYPES = {
53
65
  writable_held_selector_family: `writable_held_selector`,
54
66
  writable_pure_selector_family: `writable_pure_selector`
55
67
  };
56
- function counterfeit(token, key) {
68
+ function mint(token, key, counterfeit) {
57
69
  const subKey = stringifyJson(key);
58
70
  const fullKey = `${token.key}(${subKey})`;
59
71
  const type = FAMILY_MEMBER_TOKEN_TYPES[token.type];
60
72
  const stateToken = {
61
73
  key: fullKey,
62
- type
74
+ type,
75
+ family: {
76
+ key: token.key,
77
+ subKey
78
+ }
63
79
  };
64
- Object.assign(stateToken, { family: {
65
- key: token.key,
66
- subKey
67
- } });
68
- Object.assign(stateToken, { counterfeit: true });
80
+ if (counterfeit) stateToken.counterfeit = true;
69
81
  return stateToken;
70
82
  }
71
83
 
72
- //#endregion
73
- //#region src/internal/store/deposit.ts
74
- function deposit(state) {
75
- const token = {
76
- key: state.key,
77
- type: state.type
78
- };
79
- if (`family` in state) token.family = state.family;
80
- return token;
81
- }
82
-
83
84
  //#endregion
84
85
  //#region src/internal/junction.ts
85
86
  var Junction = class {
@@ -382,6 +383,37 @@ const recallState = (store, state) => {
382
383
  return target.valueMap.get(state.key);
383
384
  };
384
385
 
386
+ //#endregion
387
+ //#region src/internal/get-state/get-fallback.ts
388
+ function getFallback(store, token, family, subKey) {
389
+ const disposal = store.disposalTraces.buffer.find((item) => item?.key === stringifyJson(subKey));
390
+ store.logger.error(`❌`, token.type, token.key, `gets a fallback value because key`, subKey, `is not allocated`, disposal ? `This key was previously disposed:\n${disposal.trace}` : `(no previous disposal trace found)`);
391
+ switch (family.type) {
392
+ case `mutable_atom_family`: {
393
+ if (store.defaults.has(family.key)) return store.defaults.get(family.key);
394
+ const defaultValue = new family.class();
395
+ store.defaults.set(family.key, defaultValue);
396
+ return defaultValue;
397
+ }
398
+ case `atom_family`: {
399
+ if (store.defaults.has(family.key)) return store.defaults.get(family.key);
400
+ const def = family.default;
401
+ const defaultValue = def(subKey);
402
+ store.defaults.set(family.key, defaultValue);
403
+ return defaultValue;
404
+ }
405
+ case `readonly_pure_selector_family`:
406
+ case `writable_pure_selector_family`:
407
+ case `readonly_held_selector_family`:
408
+ case `writable_held_selector_family`: {
409
+ if (store.defaults.has(family.key)) return store.defaults.get(family.key);
410
+ const defaultValue = family.default(subKey);
411
+ store.defaults.set(family.key, defaultValue);
412
+ return defaultValue;
413
+ }
414
+ }
415
+ }
416
+
385
417
  //#endregion
386
418
  //#region src/internal/future.ts
387
419
  /**
@@ -452,7 +484,7 @@ function isChildStore(store) {
452
484
  function openOperation(store, token) {
453
485
  if (store.operation.open) {
454
486
  const rejectionTime = performance.now();
455
- store.logger.info(`❗`, token.type, token.key, `deferring setState at T-${rejectionTime} until setState for "${store.operation.token.key}" is done`);
487
+ store.logger.info(`🚫`, token.type, token.key, `deferring setState at T-${rejectionTime} until setState for "${store.operation.token.key}" is done`);
456
488
  return rejectionTime;
457
489
  }
458
490
  store.operation = {
@@ -626,10 +658,10 @@ function readOrComputeValue(target, state, mut) {
626
658
  //#endregion
627
659
  //#region src/internal/families/get-family-of-token.ts
628
660
  function getFamilyOfToken(store, token) {
629
- if (token.family) {
630
- const family = store.families.get(token.family.key);
631
- if (family) return family;
632
- }
661
+ return withdraw(store, {
662
+ key: token.family.key,
663
+ type: `${token.type}_family`
664
+ });
633
665
  }
634
666
 
635
667
  //#endregion
@@ -644,23 +676,11 @@ const abortTransaction = (store) => {
644
676
  target.parent.child = null;
645
677
  };
646
678
 
647
- //#endregion
648
- //#region src/internal/capitalize.ts
649
- function capitalize(string) {
650
- return string[0].toUpperCase() + string.slice(1);
651
- }
652
-
653
- //#endregion
654
- //#region src/internal/pretty-print.ts
655
- function prettyPrintTokenType(token) {
656
- return token.type.split(`_`).map(capitalize).join(` `);
657
- }
658
-
659
679
  //#endregion
660
680
  //#region src/internal/not-found-error.ts
661
681
  var NotFoundError = class extends Error {
662
682
  constructor(token, store) {
663
- super(`${prettyPrintTokenType(token)} ${stringifyJson(token.key)} not found in store "${store.config.name}".`);
683
+ super(`${PRETTY_TOKEN_TYPES[token.type]} ${stringifyJson(token.key)} not found in store "${store.config.name}".`);
664
684
  }
665
685
  };
666
686
 
@@ -773,7 +793,7 @@ function resetAtomOrSelector(target, state) {
773
793
  //#endregion
774
794
  //#region src/internal/set-state/set-into-store.ts
775
795
  function setIntoStore(store, ...params) {
776
- operateOnStore(store, true, ...params);
796
+ operateOnStore(store, OWN_OP, ...params);
777
797
  }
778
798
 
779
799
  //#endregion
@@ -895,7 +915,7 @@ function allocateIntoStore(store, provenance, key, dependsOn = `any`) {
895
915
  else target.on.moleculeCreation.next(creationEvent);
896
916
  for (const claim of invalidKeys) {
897
917
  const disposal = store.disposalTraces.buffer.find((item) => item?.key === claim);
898
- store.logger.error(`❌`, `molecule`, key, `allocation failed:`, `Could not allocate to ${claim} in store "${store.config.name}".`, disposal ? `\n ${claim} was most recently disposed\n${disposal.trace}` : `No previous disposal trace for ${claim} was found.`);
918
+ store.logger.error(`❌`, `key`, key, `allocation failed:`, `Could not allocate to ${claim} in store "${store.config.name}".`, disposal ? `\n ${claim} was most recently disposed\n${disposal.trace}` : `No previous disposal trace for ${claim} was found.`);
899
919
  }
900
920
  return key;
901
921
  }
@@ -910,7 +930,7 @@ function deallocateFromStore(store, claim) {
910
930
  const molecule = store.molecules.get(stringKey);
911
931
  if (!molecule) {
912
932
  const disposal = store.disposalTraces.buffer.find((item) => item?.key === stringKey);
913
- store.logger.error(`❌`, `molecule`, 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.`);
933
+ 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.`);
914
934
  return;
915
935
  }
916
936
  const joinKeys = store.moleculeJoins.getRelatedKeys(molecule.key);
@@ -964,14 +984,14 @@ function claimWithinStore(store, newProvenance, claim, exclusive) {
964
984
  const molecule = target.molecules.get(stringKey);
965
985
  if (!molecule) {
966
986
  const disposal = store.disposalTraces.buffer.find((item) => item?.key === stringKey);
967
- store.logger.error(`❌`, `molecule`, claim, `claim failed:`, `Could not allocate to ${stringKey} in store "${store.config.name}".`, disposal ? `\n ${stringKey} was most recently disposed\n${disposal.trace}` : `No previous disposal trace for ${stringKey} was found.`);
987
+ store.logger.error(`❌`, `key`, stringKey, `claim failed:`, `Could not allocate to ${stringKey} in store "${store.config.name}".`, disposal ? `\n ${stringKey} was most recently disposed\n${disposal.trace}` : `No previous disposal trace for ${stringKey} was found.`);
968
988
  return claim;
969
989
  }
970
990
  const newProvenanceKey = stringifyJson(newProvenance);
971
991
  const newProvenanceMolecule = target.molecules.get(newProvenanceKey);
972
992
  if (!newProvenanceMolecule) {
973
993
  const disposal = store.disposalTraces.buffer.find((item) => item?.key === newProvenanceKey);
974
- store.logger.error(`❌`, `molecule`, claim, `claim failed:`, `Could not allocate to ${newProvenanceKey} in store "${store.config.name}".`, disposal ? `\n ${newProvenanceKey} was most recently disposed\n${disposal.trace}` : `No previous disposal trace for ${newProvenanceKey} was found.`);
994
+ store.logger.error(`❌`, `key`, claim, `claim failed:`, `Could not allocate to ${newProvenanceKey} in store "${store.config.name}".`, disposal ? `\n ${newProvenanceKey} was most recently disposed\n${disposal.trace}` : `No previous disposal trace for ${newProvenanceKey} was found.`);
975
995
  return claim;
976
996
  }
977
997
  const priorProvenance = store.moleculeGraph.getRelationEntries({ downstreamMoleculeKey: molecule.stringKey }).filter(([, { source }]) => source !== stringKey).map(([key]) => parseJson(key));
@@ -1020,7 +1040,7 @@ function createInStore(update, store) {
1020
1040
  const { family: familyMeta } = update.token;
1021
1041
  if (familyMeta) {
1022
1042
  const family = store.families.get(familyMeta.key);
1023
- if (family) findInStore(store, family, parseJson(familyMeta.subKey));
1043
+ if (family) mintInStore(store, family, parseJson(familyMeta.subKey), MUST_CREATE);
1024
1044
  }
1025
1045
  }
1026
1046
  function ingestMoleculeCreationEvent(update, applying, store) {
@@ -1045,7 +1065,7 @@ function ingestMoleculeDisposalEvent(update, applying, store) {
1045
1065
  for (const [familyKey, value] of update.values) {
1046
1066
  const family = store.families.get(familyKey);
1047
1067
  if (family) {
1048
- findInStore(store, family, update.key);
1068
+ mintInStore(store, family, update.key, MUST_CREATE);
1049
1069
  const memberKey = `${familyKey}(${stringifyJson(update.key)})`;
1050
1070
  store.valueMap.set(memberKey, value);
1051
1071
  }
@@ -1338,42 +1358,57 @@ function initFamilyMemberInStore(store, token, key) {
1338
1358
 
1339
1359
  //#endregion
1340
1360
  //#region src/internal/families/mint-in-store.ts
1341
- function mintInStore(store, familyToken, key) {
1361
+ const MUST_CREATE = Symbol(`MUST_NOT_EXIST`);
1362
+ function mintInStore(store, familyToken, key, shouldCreate) {
1363
+ let stateToken;
1364
+ let willCreate;
1365
+ switch (shouldCreate) {
1366
+ case MUST_CREATE:
1367
+ willCreate = true;
1368
+ break;
1369
+ case void 0:
1370
+ willCreate = false;
1371
+ break;
1372
+ }
1342
1373
  const stringKey = stringifyJson(key);
1343
1374
  const molecule = store.molecules.get(stringKey);
1344
1375
  if (!molecule && store.config.lifespan === `immortal`) {
1345
- const fakeToken = counterfeit(familyToken, key);
1346
- store.logger.error(`❌`, fakeToken.type, fakeToken.key, `was not found in store "${store.config.name}"; returned a counterfeit token.`);
1376
+ const fakeToken = mint(familyToken, key, COUNTERFEIT);
1377
+ store.logger.warn(`💣`, `key`, stringKey, `was used to mint a counterfeit token for`, familyToken.type, `"${familyToken.key}"`);
1347
1378
  return fakeToken;
1348
1379
  }
1349
- const newStateToken = initFamilyMemberInStore(store, familyToken, key);
1350
- const target = newest(store);
1351
- if (newStateToken.family) {
1352
- if (isRootStore(target)) switch (newStateToken.type) {
1353
- case `atom`:
1354
- case `mutable_atom`:
1355
- store.on.atomCreation.next(newStateToken);
1356
- break;
1357
- case `writable_pure_selector`:
1358
- case `readonly_pure_selector`:
1359
- case `writable_held_selector`:
1360
- case `readonly_held_selector`:
1361
- store.on.selectorCreation.next(newStateToken);
1362
- break;
1380
+ if (willCreate) {
1381
+ stateToken = initFamilyMemberInStore(store, familyToken, key);
1382
+ const target = newest(store);
1383
+ if (stateToken.family) {
1384
+ if (isRootStore(target)) switch (stateToken.type) {
1385
+ case `atom`:
1386
+ case `mutable_atom`:
1387
+ store.on.atomCreation.next(stateToken);
1388
+ break;
1389
+ case `writable_pure_selector`:
1390
+ case `readonly_pure_selector`:
1391
+ case `writable_held_selector`:
1392
+ case `readonly_held_selector`:
1393
+ store.on.selectorCreation.next(stateToken);
1394
+ break;
1395
+ }
1396
+ else if (isChildStore(target) && target.on.transactionApplying.state === null) target.transactionMeta.update.subEvents.push({
1397
+ type: `state_creation`,
1398
+ token: stateToken,
1399
+ timestamp: Date.now()
1400
+ });
1363
1401
  }
1364
- else if (isChildStore(target) && target.on.transactionApplying.state === null) target.transactionMeta.update.subEvents.push({
1365
- type: `state_creation`,
1366
- token: newStateToken,
1367
- timestamp: Date.now()
1368
- });
1369
- }
1370
- if (molecule) target.moleculeData.set(stringKey, familyToken.key);
1371
- return newStateToken;
1402
+ if (molecule) target.moleculeData.set(stringKey, familyToken.key);
1403
+ } else stateToken = mint(familyToken, key);
1404
+ return stateToken;
1372
1405
  }
1373
1406
 
1374
1407
  //#endregion
1375
1408
  //#region src/internal/set-state/operate-on-store.ts
1376
- function operateOnStore(store, ownOp, ...params) {
1409
+ const OWN_OP = Symbol(`OWN_OP`);
1410
+ const JOIN_OP = Symbol(`JOIN_OP`);
1411
+ function operateOnStore(store, opMode, ...params) {
1377
1412
  let existingToken;
1378
1413
  let brandNewToken;
1379
1414
  let token;
@@ -1383,12 +1418,12 @@ function operateOnStore(store, ownOp, ...params) {
1383
1418
  if (params.length === 2) {
1384
1419
  token = params[0];
1385
1420
  value = params[1];
1386
- if (token.family) {
1421
+ if (`family` in token) {
1387
1422
  family = getFamilyOfToken(store, token);
1388
1423
  key = parseJson(token.family.subKey);
1389
1424
  existingToken = seekInStore(store, family, key);
1390
1425
  if (!existingToken) {
1391
- brandNewToken = mintInStore(store, family, key);
1426
+ brandNewToken = mintInStore(store, family, key, MUST_CREATE);
1392
1427
  token = brandNewToken;
1393
1428
  } else token = existingToken;
1394
1429
  }
@@ -1398,13 +1433,13 @@ function operateOnStore(store, ownOp, ...params) {
1398
1433
  value = params[2];
1399
1434
  existingToken = seekInStore(store, family, key);
1400
1435
  if (!existingToken) {
1401
- brandNewToken = mintInStore(store, family, key);
1436
+ brandNewToken = mintInStore(store, family, key, MUST_CREATE);
1402
1437
  token = brandNewToken;
1403
1438
  } else token = existingToken;
1404
1439
  }
1405
1440
  const action = value === RESET_STATE ? `reset` : `set`;
1406
1441
  let target;
1407
- if (ownOp) {
1442
+ if (opMode === OWN_OP) {
1408
1443
  const result = openOperation(store, token);
1409
1444
  const rejected = typeof result === `number`;
1410
1445
  if (rejected) {
@@ -1412,7 +1447,7 @@ function operateOnStore(store, ownOp, ...params) {
1412
1447
  const unsubscribe = store.on.operationClose.subscribe(`waiting to ${action} "${token.key}" at T-${rejectionTime}`, function waitUntilOperationCloseToSetState() {
1413
1448
  unsubscribe();
1414
1449
  store.logger.info(`🟢`, token.type, token.key, `resuming deferred`, action, `from T-${rejectionTime}`);
1415
- operateOnStore(store, ownOp, token, value);
1450
+ operateOnStore(store, opMode, token, value);
1416
1451
  });
1417
1452
  return;
1418
1453
  }
@@ -1421,7 +1456,7 @@ function operateOnStore(store, ownOp, ...params) {
1421
1456
  if (`counterfeit` in token && `family` in token) {
1422
1457
  const subKey = token.family.subKey;
1423
1458
  const disposal = store.disposalTraces.buffer.find((item) => item?.key === subKey);
1424
- store.logger.error(`❌`, token.type, token.key, `could not be`, action, `because it was not found in the store "${store.config.name}".`, disposal ? `This state was previously disposed:\n${disposal.trace}` : `No previous disposal trace was found.`);
1459
+ store.logger.error(`❌`, token.type, token.key, `could not be`, action, `because key`, subKey, `is not allocated.`, disposal ? `this key was previously disposed:${disposal.trace}` : `(no previous disposal trace found)`);
1425
1460
  return;
1426
1461
  }
1427
1462
  const state = withdraw(target, token);
@@ -1430,7 +1465,7 @@ function operateOnStore(store, ownOp, ...params) {
1430
1465
  else protoUpdate = setAtomOrSelector(target, state, value);
1431
1466
  const isNewlyCreated = Boolean(brandNewToken);
1432
1467
  dispatchOrDeferStateUpdate(target, state, protoUpdate, isNewlyCreated);
1433
- if (ownOp) closeOperation(target);
1468
+ if (opMode === OWN_OP) closeOperation(target);
1434
1469
  }
1435
1470
 
1436
1471
  //#endregion
@@ -1492,25 +1527,26 @@ function registerSelector(store, selectorType, selectorKey, covered) {
1492
1527
  return {
1493
1528
  get: (...params) => {
1494
1529
  const target = newest(store);
1495
- let dependency;
1496
- if (params.length === 2) {
1497
- const [family, key] = params;
1498
- dependency = findInStore(store, family, key);
1499
- } else [dependency] = params;
1500
- const dependencyState = withdraw(store, dependency);
1501
- const dependencyValue = readOrComputeValue(store, dependencyState);
1502
- const dependencyKey = dependency.key;
1503
- store.logger.info(`🔌`, selectorType, selectorKey, `registers dependency ( "${dependencyKey}" =`, dependencyValue, `)`);
1530
+ const { token, familyToken, subKey } = reduceReference(store, ...params);
1531
+ let dependencyValue;
1532
+ if (`counterfeit` in token && familyToken && subKey) {
1533
+ const dependencyFamily = withdraw(store, familyToken);
1534
+ dependencyValue = getFallback(store, token, dependencyFamily, subKey);
1535
+ } else {
1536
+ const dependency = withdraw(store, token);
1537
+ dependencyValue = readOrComputeValue(store, dependency);
1538
+ }
1539
+ store.logger.info(`🔌`, selectorType, selectorKey, `registers dependency ( "${token.key}" =`, dependencyValue, `)`);
1504
1540
  target.selectorGraph.set({
1505
- upstreamSelectorKey: dependencyKey,
1541
+ upstreamSelectorKey: token.key,
1506
1542
  downstreamSelectorKey: selectorKey
1507
- }, { source: dependency.key });
1508
- updateSelectorAtoms(store, selectorType, selectorKey, dependency, covered);
1543
+ }, { source: token.key });
1544
+ updateSelectorAtoms(store, selectorType, selectorKey, token, covered);
1509
1545
  return dependencyValue;
1510
1546
  },
1511
1547
  set: ((...params) => {
1512
1548
  const target = newest(store);
1513
- operateOnStore(target, false, ...params);
1549
+ operateOnStore(target, JOIN_OP, ...params);
1514
1550
  }),
1515
1551
  find: ((...args) => findInStore(store, ...args)),
1516
1552
  json: (token) => getJsonToken(store, token)
@@ -1818,7 +1854,7 @@ function createReadonlyPureSelectorFamily(store, options, internalRoles) {
1818
1854
  type
1819
1855
  };
1820
1856
  const existing = store.families.get(familyKey);
1821
- if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
1857
+ if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${PRETTY_TOKEN_TYPES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
1822
1858
  const subject = new Subject();
1823
1859
  const familyFunction = (key) => {
1824
1860
  const subKey = stringifyJson(key);
@@ -1864,7 +1900,7 @@ function createRegularAtomFamily(store, options, internalRoles) {
1864
1900
  type: `atom_family`
1865
1901
  };
1866
1902
  const existing = store.families.get(options.key);
1867
- if (existing) store.logger.error(`❗`, `atom_family`, options.key, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
1903
+ if (existing) store.logger.error(`❗`, `atom_family`, options.key, `Overwriting an existing ${PRETTY_TOKEN_TYPES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
1868
1904
  const subject = new Subject();
1869
1905
  const familyFunction = (key) => {
1870
1906
  const subKey = stringifyJson(key);
@@ -1889,12 +1925,13 @@ function createRegularAtomFamily(store, options, internalRoles) {
1889
1925
  return token;
1890
1926
  };
1891
1927
  const atomFamily$1 = Object.assign(familyFunction, familyToken, {
1928
+ default: options.default,
1892
1929
  subject,
1893
1930
  install: (s) => createRegularAtomFamily(s, options),
1894
1931
  internalRoles
1895
1932
  });
1896
1933
  store.families.set(options.key, atomFamily$1);
1897
- store.defaults.set(options.key, options.default);
1934
+ if (options.default instanceof Function === false) store.defaults.set(options.key, options.default);
1898
1935
  return familyToken;
1899
1936
  }
1900
1937
 
@@ -1908,7 +1945,7 @@ function createReadonlyHeldSelectorFamily(store, options, internalRoles) {
1908
1945
  type
1909
1946
  };
1910
1947
  const existing = store.families.get(familyKey);
1911
- if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
1948
+ if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${PRETTY_TOKEN_TYPES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
1912
1949
  const subject = new Subject();
1913
1950
  const familyFunction = (key) => {
1914
1951
  const subKey = stringifyJson(key);
@@ -1950,7 +1987,7 @@ function createWritableHeldSelectorFamily(store, options, internalRoles) {
1950
1987
  type
1951
1988
  };
1952
1989
  const existing = store.families.get(familyKey);
1953
- if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
1990
+ if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${PRETTY_TOKEN_TYPES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
1954
1991
  const subject = new Subject();
1955
1992
  const familyFunction = (key) => {
1956
1993
  const subKey = stringifyJson(key);
@@ -1993,7 +2030,7 @@ function createWritablePureSelectorFamily(store, options, internalRoles) {
1993
2030
  type
1994
2031
  };
1995
2032
  const existing = store.families.get(familyKey);
1996
- if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
2033
+ if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${PRETTY_TOKEN_TYPES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
1997
2034
  const subject = new Subject();
1998
2035
  const familyFunction = (key) => {
1999
2036
  const subKey = stringifyJson(key);
@@ -2071,6 +2108,7 @@ function seekInStore(store, token, key) {
2071
2108
  //#endregion
2072
2109
  //#region src/internal/families/find-in-store.ts
2073
2110
  function findInStore(store, familyToken, key) {
2111
+ withdraw(store, familyToken);
2074
2112
  const existingStateToken = seekInStore(store, familyToken, key);
2075
2113
  if (existingStateToken) return existingStateToken;
2076
2114
  const newStateToken = mintInStore(store, familyToken, key);
@@ -2109,37 +2147,58 @@ function disposeFromStore(store, ...params) {
2109
2147
  }
2110
2148
 
2111
2149
  //#endregion
2112
- //#region src/internal/get-state/get-from-store.ts
2113
- function getFromStore(store, ...params) {
2150
+ //#region src/internal/get-state/reduce-reference.ts
2151
+ function reduceReference(store, ...params) {
2152
+ let existingToken;
2153
+ let brandNewToken;
2154
+ let familyToken;
2155
+ let subKey;
2114
2156
  let token;
2115
- let family;
2116
- let key;
2117
- if (params.length === 1) token = params[0];
2118
- else {
2119
- family = params[0];
2120
- key = params[1];
2121
- token = findInStore(store, family, key);
2122
- }
2123
- if (`counterfeit` in token && `family` in token) {
2124
- family = store.families.get(token.family.key);
2125
- const subKey = token.family.subKey;
2126
- const disposal = store.disposalTraces.buffer.find((item) => item?.key === subKey);
2127
- store.logger.error(`❌`, token.type, token.key, `could not be retrieved because it was not found in the store "${store.config.name}".`, disposal ? `This state was previously disposed:\n${disposal.trace}` : `No previous disposal trace was found.`);
2128
- switch (family.type) {
2129
- case `atom_family`:
2130
- case `mutable_atom_family`: return store.defaults.get(family.key);
2131
- case `readonly_pure_selector_family`:
2132
- case `writable_pure_selector_family`:
2133
- case `readonly_held_selector_family`:
2134
- case `writable_held_selector_family`: {
2135
- if (store.defaults.has(family.key)) return store.defaults.get(token.family.key);
2136
- const defaultValue = withdraw(store, family).default(subKey);
2137
- store.defaults.set(family.key, defaultValue);
2138
- return defaultValue;
2139
- }
2157
+ if (params.length === 1) {
2158
+ token = params[0];
2159
+ if (`family` in token) {
2160
+ familyToken = getFamilyOfToken(store, token);
2161
+ withdraw(store, familyToken);
2162
+ subKey = parseJson(token.family.subKey);
2163
+ existingToken = seekInStore(store, familyToken, subKey);
2164
+ if (`counterfeit` in token) return {
2165
+ token,
2166
+ familyToken,
2167
+ subKey,
2168
+ isNew: false
2169
+ };
2170
+ if (!existingToken) {
2171
+ brandNewToken = mintInStore(store, familyToken, subKey, MUST_CREATE);
2172
+ token = brandNewToken;
2173
+ } else token = existingToken;
2140
2174
  }
2175
+ } else {
2176
+ familyToken = params[0];
2177
+ subKey = params[1];
2178
+ existingToken = seekInStore(store, familyToken, subKey);
2179
+ if (!existingToken) {
2180
+ brandNewToken = mintInStore(store, familyToken, subKey, MUST_CREATE);
2181
+ token = brandNewToken;
2182
+ } else token = existingToken;
2183
+ }
2184
+ return {
2185
+ token,
2186
+ familyToken,
2187
+ subKey,
2188
+ isNew: Boolean(brandNewToken)
2189
+ };
2190
+ }
2191
+
2192
+ //#endregion
2193
+ //#region src/internal/get-state/get-from-store.ts
2194
+ function getFromStore(store, ...params) {
2195
+ const { token, familyToken, subKey } = reduceReference(store, ...params);
2196
+ if (`counterfeit` in token && familyToken && subKey) {
2197
+ const family = withdraw(store, familyToken);
2198
+ return getFallback(store, token, family, subKey);
2141
2199
  }
2142
- return readOrComputeValue(store, withdraw(store, token));
2200
+ const state = withdraw(store, token);
2201
+ return readOrComputeValue(store, state);
2143
2202
  }
2144
2203
 
2145
2204
  //#endregion
@@ -2168,6 +2227,7 @@ function subscribeToState(store, token, key, handleUpdate) {
2168
2227
  });
2169
2228
  } else handleUpdate(update);
2170
2229
  }
2230
+ reduceReference(store, token);
2171
2231
  const state = withdraw(store, token);
2172
2232
  store.logger.info(`👀`, state.type, state.key, `Adding subscription "${key}"`);
2173
2233
  const isSelector = state.type === `writable_pure_selector` || state.type === `readonly_pure_selector`;
@@ -2470,7 +2530,7 @@ function createMutableAtomFamily(store, options, internalRoles) {
2470
2530
  type: `mutable_atom_family`
2471
2531
  };
2472
2532
  const existing = store.families.get(options.key);
2473
- if (existing) store.logger.error(`❗`, `mutable_atom_family`, options.key, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
2533
+ if (existing) store.logger.error(`❗`, `mutable_atom_family`, options.key, `Overwriting an existing ${PRETTY_TOKEN_TYPES[existing.type]} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
2474
2534
  const subject = new Subject();
2475
2535
  const familyFunction = (key) => {
2476
2536
  const subKey = stringifyJson(key);
@@ -2494,6 +2554,7 @@ function createMutableAtomFamily(store, options, internalRoles) {
2494
2554
  return token;
2495
2555
  };
2496
2556
  const atomFamily$1 = Object.assign(familyFunction, familyToken, {
2557
+ class: options.class,
2497
2558
  subject,
2498
2559
  install: (s) => createMutableAtomFamily(s, options),
2499
2560
  internalRoles
@@ -2530,7 +2591,7 @@ const getJsonToken = (store, mutableAtomToken) => {
2530
2591
  type: `writable_pure_selector_family`
2531
2592
  };
2532
2593
  const family = withdraw(target, jsonFamilyToken);
2533
- const subKey = JSON.parse(mutableAtomToken.family.subKey);
2594
+ const subKey = parseJson(mutableAtomToken.family.subKey);
2534
2595
  const jsonToken = findInStore(store, family, subKey);
2535
2596
  return jsonToken;
2536
2597
  }
@@ -2760,10 +2821,9 @@ function disposeAtom(store, atomToken) {
2760
2821
  else {
2761
2822
  atom.cleanup?.();
2762
2823
  const lastValue = store.valueMap.get(atom.key);
2763
- const atomFamily$1 = withdraw(store, {
2764
- key: family.key,
2765
- type: `atom_family`
2766
- });
2824
+ const familyToken = getFamilyOfToken(store, atomToken);
2825
+ const atomFamily$1 = withdraw(store, familyToken);
2826
+ const subject = atomFamily$1.subject;
2767
2827
  const disposal = {
2768
2828
  type: `state_disposal`,
2769
2829
  subType: `atom`,
@@ -2771,7 +2831,7 @@ function disposeAtom(store, atomToken) {
2771
2831
  value: lastValue,
2772
2832
  timestamp: Date.now()
2773
2833
  };
2774
- atomFamily$1.subject.next(disposal);
2834
+ subject.next(disposal);
2775
2835
  const isChild = isChildStore(target);
2776
2836
  target.atoms.delete(key);
2777
2837
  target.valueMap.delete(key);
@@ -2802,6 +2862,12 @@ function hasRole(atom, role) {
2802
2862
  return atom.internalRoles.includes(role);
2803
2863
  }
2804
2864
 
2865
+ //#endregion
2866
+ //#region src/internal/capitalize.ts
2867
+ function capitalize(string) {
2868
+ return string[0].toUpperCase() + string.slice(1);
2869
+ }
2870
+
2805
2871
  //#endregion
2806
2872
  //#region src/internal/install-into-store.ts
2807
2873
  /**
@@ -3359,6 +3425,7 @@ function createTimeline(store, options, data) {
3359
3425
  return token;
3360
3426
  }
3361
3427
  function addAtomToTimeline(store, atomToken, tl) {
3428
+ reduceReference(store, atomToken);
3362
3429
  let maybeAtom = withdraw(store, atomToken);
3363
3430
  if (maybeAtom.type === `mutable_atom`) {
3364
3431
  const updateToken = getUpdateToken(maybeAtom);
@@ -3569,5 +3636,5 @@ const timeTravel = (store, action, token) => {
3569
3636
  };
3570
3637
 
3571
3638
  //#endregion
3572
- export { CircularBuffer, FAMILY_MEMBER_TOKEN_TYPES, FamilyTracker, Future, IMPLICIT, INTERNAL_ROLES, Join, Junction, LazyMap, NotFoundError, RESET_STATE, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, allocateIntoStore, applyTransaction, arbitrary, assignTransactionToContinuity, become, buildTransaction, capitalize, claimWithinStore, clearStore, closeOperation, counterfeit, 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, ingestAtomUpdate, ingestCreationEvent, ingestDisposalEvent, ingestMoleculeCreationEvent, ingestMoleculeDisposalEvent, ingestMoleculeTransferEvent, ingestSelectorUpdate, ingestTransactionUpdate, initFamilyMemberInStore, installIntoStore, isAtomKey, isChildStore, isDone, isReadonlySelectorKey, isReservedIntrospectionKey, isRootStore, isSelectorKey, isStateKey, isTransceiver, makeRootMoleculeInStore, markDone, newest, openOperation, prettyPrintTokenType, readFromCache, readOrComputeValue, recallState, registerSelector, resetAtomOrSelector, resetInStore, seekInStore, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeInStore, subscribeToRootDependency, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceRootSelectorAtoms, updateSelectorAtoms, withdraw, writeToCache };
3639
+ export { COUNTERFEIT, CircularBuffer, FAMILY_MEMBER_TOKEN_TYPES, FamilyTracker, Future, IMPLICIT, INTERNAL_ROLES, Join, Junction, LazyMap, NotFoundError, RESET_STATE, 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, ingestAtomUpdate, ingestCreationEvent, ingestDisposalEvent, ingestMoleculeCreationEvent, ingestMoleculeDisposalEvent, ingestMoleculeTransferEvent, ingestSelectorUpdate, ingestTransactionUpdate, initFamilyMemberInStore, 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 };
3573
3640
  //# sourceMappingURL=index.js.map