atom.io 0.21.0 → 0.22.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 (99) hide show
  1. package/data/dist/index.cjs +139 -66
  2. package/data/dist/index.d.ts +6 -0
  3. package/data/dist/index.js +3 -3
  4. package/data/src/join.ts +135 -56
  5. package/data/src/struct-family.ts +2 -2
  6. package/dist/{chunk-RT43TVKP.js → chunk-GVHKIJ3G.js} +1 -1
  7. package/dist/{chunk-KGZGBCYS.js → chunk-JA4V7TJY.js} +135 -62
  8. package/dist/index.cjs +2 -7
  9. package/dist/index.d.ts +29 -14
  10. package/dist/index.js +4 -8
  11. package/ephemeral/dist/index.cjs +11 -0
  12. package/ephemeral/dist/index.js +9 -0
  13. package/ephemeral/package.json +16 -0
  14. package/ephemeral/src/index.ts +1 -0
  15. package/eslint-plugin/dist/index.cjs +156 -1
  16. package/eslint-plugin/dist/index.js +156 -1
  17. package/eslint-plugin/src/rules/index.ts +1 -0
  18. package/eslint-plugin/src/rules/lifespan.ts +204 -0
  19. package/eslint-plugin/src/rules/synchronous-selector-dependencies.ts +1 -65
  20. package/eslint-plugin/src/walk.ts +73 -0
  21. package/immortal/dist/index.cjs +100 -0
  22. package/immortal/dist/index.js +97 -0
  23. package/immortal/package.json +16 -0
  24. package/immortal/src/index.ts +2 -0
  25. package/immortal/src/molecule.ts +134 -0
  26. package/immortal/src/seek-state.ts +60 -0
  27. package/internal/dist/index.cjs +211 -194
  28. package/internal/dist/index.d.ts +30 -14
  29. package/internal/dist/index.js +210 -194
  30. package/internal/src/atom/dispose-atom.ts +4 -1
  31. package/internal/src/families/create-readonly-selector-family.ts +9 -9
  32. package/internal/src/families/create-regular-atom-family.ts +15 -20
  33. package/internal/src/families/create-writable-selector-family.ts +6 -7
  34. package/internal/src/families/find-in-store.ts +11 -5
  35. package/internal/src/families/index.ts +2 -0
  36. package/internal/src/families/init-family-member.ts +91 -0
  37. package/internal/src/families/seek-in-store.ts +106 -0
  38. package/internal/src/future.ts +6 -20
  39. package/internal/src/get-state/get-from-store.ts +2 -3
  40. package/internal/src/mutable/create-mutable-atom-family.ts +17 -23
  41. package/internal/src/mutable/create-mutable-atom.ts +3 -1
  42. package/internal/src/mutable/get-json-family.ts +2 -2
  43. package/internal/src/mutable/get-json-token.ts +27 -12
  44. package/internal/src/mutable/tracker-family.ts +14 -12
  45. package/internal/src/mutable/tracker.ts +2 -24
  46. package/internal/src/not-found-error.ts +11 -3
  47. package/internal/src/operation.ts +0 -1
  48. package/internal/src/selector/create-readonly-selector.ts +2 -2
  49. package/internal/src/selector/create-writable-selector.ts +2 -2
  50. package/internal/src/selector/dispose-selector.ts +40 -23
  51. package/internal/src/selector/register-selector.ts +8 -5
  52. package/internal/src/set-state/set-into-store.ts +2 -2
  53. package/internal/src/store/index.ts +0 -1
  54. package/internal/src/store/store.ts +18 -5
  55. package/internal/src/subscribe/recall-state.ts +3 -3
  56. package/internal/src/subscribe/subscribe-to-state.ts +18 -5
  57. package/internal/src/transaction/build-transaction.ts +7 -2
  58. package/introspection/dist/index.cjs +39 -65
  59. package/introspection/dist/index.js +39 -65
  60. package/introspection/src/attach-atom-index.ts +38 -48
  61. package/introspection/src/attach-introspection-states.ts +0 -1
  62. package/introspection/src/attach-selector-index.ts +45 -50
  63. package/introspection/src/attach-timeline-family.ts +2 -17
  64. package/json/dist/index.cjs +38 -4
  65. package/json/dist/index.js +40 -6
  66. package/json/src/select-json-family.ts +46 -7
  67. package/package.json +31 -11
  68. package/react/dist/index.cjs +1 -1
  69. package/react/dist/index.js +1 -1
  70. package/react/src/use-json.ts +1 -1
  71. package/react-devtools/dist/index.cjs +11 -10
  72. package/react-devtools/dist/index.js +2 -1
  73. package/react-devtools/src/StateIndex.tsx +2 -1
  74. package/react-devtools/src/TimelineIndex.tsx +2 -1
  75. package/react-devtools/src/TransactionIndex.tsx +7 -7
  76. package/realtime-client/dist/index.cjs +3 -3
  77. package/realtime-client/dist/index.js +3 -3
  78. package/realtime-client/src/pull-mutable-atom-family-member.ts +1 -1
  79. package/realtime-client/src/pull-mutable-atom.ts +1 -1
  80. package/realtime-client/src/sync-continuity.ts +1 -2
  81. package/realtime-react/dist/index.cjs +1 -1
  82. package/realtime-react/dist/index.js +1 -1
  83. package/realtime-server/dist/index.cjs +18 -17
  84. package/realtime-server/dist/index.js +7 -6
  85. package/realtime-server/src/realtime-continuity-synchronizer.ts +5 -3
  86. package/realtime-server/src/realtime-mutable-family-provider.ts +2 -1
  87. package/realtime-server/src/realtime-mutable-provider.ts +1 -1
  88. package/realtime-testing/dist/index.cjs +6 -2
  89. package/realtime-testing/dist/index.js +8 -5
  90. package/realtime-testing/src/setup-realtime-test.tsx +5 -2
  91. package/src/atom.ts +10 -4
  92. package/src/index.ts +1 -2
  93. package/src/selector.ts +10 -4
  94. package/src/silo.ts +3 -3
  95. package/src/transaction.ts +5 -2
  96. package/src/validators.ts +0 -6
  97. package/internal/src/store/withdraw-new-family-member.ts +0 -69
  98. /package/{src → ephemeral/src}/find-state.ts +0 -0
  99. /package/src/{dispose.ts → dispose-state.ts} +0 -0
@@ -31,44 +31,30 @@ function arbitrary(random = Math.random) {
31
31
  // internal/src/future.ts
32
32
  var Future = class extends Promise {
33
33
  constructor(executor) {
34
- let promise;
35
34
  let superResolve;
36
35
  let superReject;
37
36
  super((resolve, reject) => {
38
37
  superResolve = resolve;
39
38
  superReject = reject;
40
- promise = executor instanceof Promise ? executor : new Promise(executor);
41
- promise.then(
42
- (value) => {
43
- if (promise) {
44
- this.pass(promise, value);
45
- }
46
- },
47
- (reason) => {
48
- if (promise) {
49
- this.fail(promise, reason);
50
- }
51
- }
52
- );
53
39
  });
54
- this.destiny = promise;
55
40
  this.resolve = superResolve;
56
41
  this.reject = superReject;
42
+ this.use(executor instanceof Promise ? executor : new Promise(executor));
57
43
  }
58
44
  pass(promise, value) {
59
- if (promise === this.destiny) {
45
+ if (promise === this.fate) {
60
46
  this.resolve(value);
61
47
  }
62
48
  }
63
49
  fail(promise, reason) {
64
- if (promise === this.destiny) {
50
+ if (promise === this.fate) {
65
51
  this.reject(reason);
66
52
  }
67
53
  }
68
54
  use(value) {
69
55
  if (value instanceof Promise) {
70
56
  const promise = value;
71
- this.destiny = promise;
57
+ this.fate = promise;
72
58
  promise.then(
73
59
  (resolved) => {
74
60
  this.pass(promise, resolved);
@@ -79,7 +65,7 @@ var Future = class extends Promise {
79
65
  );
80
66
  } else {
81
67
  this.resolve(value);
82
- this.destiny = void 0;
68
+ this.fate = void 0;
83
69
  }
84
70
  }
85
71
  };
@@ -405,7 +391,7 @@ function isChildStore(store) {
405
391
 
406
392
  // internal/src/store/store.ts
407
393
  var Store = class {
408
- constructor(name, store = null) {
394
+ constructor(config, store = null) {
409
395
  this.parent = null;
410
396
  this.child = null;
411
397
  this.valueMap = /* @__PURE__ */ new Map();
@@ -434,6 +420,8 @@ var Store = class {
434
420
  makeContentKey: (...keys) => keys.sort().join(`:`)
435
421
  }
436
422
  );
423
+ this.molecules = /* @__PURE__ */ new Map();
424
+ this.miscResources = /* @__PURE__ */ new Map();
437
425
  this.on = {
438
426
  atomCreation: new Subject(),
439
427
  atomDisposal: new Subject(),
@@ -455,7 +443,8 @@ var Store = class {
455
443
  })
456
444
  };
457
445
  this.config = {
458
- name: `IMPLICIT_STORE`
446
+ name: `IMPLICIT_STORE`,
447
+ lifespan: `ephemeral`
459
448
  };
460
449
  this.loggers = [
461
450
  new atom_io.AtomIOLogger(`warn`, (_, __, key) => !key.includes(`\u{1F441}\u200D\u{1F5E8}`))
@@ -485,9 +474,7 @@ var Store = class {
485
474
  )
486
475
  };
487
476
  }
488
- this.config = __spreadProps(__spreadValues({}, store == null ? void 0 : store.config), {
489
- name
490
- });
477
+ this.config = __spreadValues(__spreadValues({}, store == null ? void 0 : store.config), config);
491
478
  for (const [, family] of store.families) {
492
479
  family.install(this);
493
480
  }
@@ -498,7 +485,7 @@ var Store = class {
498
485
  }
499
486
  atom.install(this);
500
487
  if (atom.type === `mutable_atom`) {
501
- const originalJsonToken = getJsonToken(atom);
488
+ const originalJsonToken = getJsonToken(atom, store);
502
489
  const originalUpdateToken = getUpdateToken(atom);
503
490
  mutableHelpers.add(originalJsonToken.key);
504
491
  mutableHelpers.add(originalUpdateToken.key);
@@ -526,12 +513,18 @@ var IMPLICIT = {
526
513
  STORE_INTERNAL: void 0,
527
514
  get STORE() {
528
515
  var _a;
529
- return (_a = this.STORE_INTERNAL) != null ? _a : this.STORE_INTERNAL = new Store(`IMPLICIT_STORE`);
516
+ return (_a = this.STORE_INTERNAL) != null ? _a : this.STORE_INTERNAL = new Store({
517
+ name: `IMPLICIT_STORE`,
518
+ lifespan: `ephemeral`
519
+ });
530
520
  }
531
521
  };
532
522
  var clearStore = (store) => {
533
523
  const { config } = store;
534
- Object.assign(store, new Store(config.name));
524
+ for (const disposable of store.miscResources.values()) {
525
+ disposable[Symbol.dispose]();
526
+ }
527
+ Object.assign(store, new Store(config));
535
528
  store.config = config;
536
529
  };
537
530
 
@@ -572,36 +565,6 @@ function withdraw(token, store) {
572
565
  throw new NotFoundError(token, store);
573
566
  }
574
567
 
575
- // internal/src/store/withdraw-new-family-member.ts
576
- function withdrawOrCreate(token, store) {
577
- try {
578
- const state = withdraw(token, store);
579
- return state;
580
- } catch (notFoundError) {
581
- if (token.family) {
582
- store.logger.info(
583
- `\u{1F46A}`,
584
- token.type,
585
- token.key,
586
- `creating new family member in store "${store.config.name}"`
587
- );
588
- const target = newest(store);
589
- const family = target.families.get(token.family.key);
590
- if (family) {
591
- const jsonSubKey = JSON.parse(token.family.subKey);
592
- family(jsonSubKey);
593
- const state = withdraw(token, store);
594
- return state;
595
- }
596
- throw new NotFoundError(
597
- { key: token.family.key, type: `${token.type}_family` },
598
- store
599
- );
600
- }
601
- throw notFoundError;
602
- }
603
- }
604
-
605
568
  // internal/src/get-state/read-or-compute-value.ts
606
569
  var readOrComputeValue = (state, target) => {
607
570
  if (target.valueMap.has(state.key)) {
@@ -629,22 +592,17 @@ function createRegularAtomFamily(options, store) {
629
592
  const subKey = json.stringifyJson(key);
630
593
  const family = { key: options.key, subKey };
631
594
  const fullKey = `${options.key}(${subKey})`;
632
- const target2 = newest(store);
633
- const atomAlreadyCreated = target2.atoms.has(fullKey);
634
- let token;
635
- if (atomAlreadyCreated) {
636
- token = { type: `atom`, key: fullKey, family };
637
- } else {
638
- const individualOptions = {
639
- key: fullKey,
640
- default: options.default instanceof Function ? options.default(key) : options.default
641
- };
642
- if (options.effects) {
643
- individualOptions.effects = options.effects(key);
644
- }
645
- token = createRegularAtom(individualOptions, family, store);
646
- subject.next(token);
595
+ const target = newest(store);
596
+ const def = options.default;
597
+ const individualOptions = {
598
+ key: fullKey,
599
+ default: def instanceof Function ? def(key) : def
600
+ };
601
+ if (options.effects) {
602
+ individualOptions.effects = options.effects(key);
647
603
  }
604
+ const token = createRegularAtom(individualOptions, family, target);
605
+ subject.next(token);
648
606
  return token;
649
607
  },
650
608
  {
@@ -654,8 +612,7 @@ function createRegularAtomFamily(options, store) {
654
612
  install: (s) => createRegularAtomFamily(options, s)
655
613
  }
656
614
  );
657
- const target = newest(store);
658
- target.families.set(options.key, atomFamily);
615
+ store.families.set(options.key, atomFamily);
659
616
  return atomFamily;
660
617
  }
661
618
 
@@ -671,22 +628,20 @@ function createReadonlySelectorFamily(options, store) {
671
628
  const subject = new Subject();
672
629
  const readonlySelectorFamily = Object.assign(
673
630
  (key) => {
674
- const target = newest(store);
675
631
  const subKey = json.stringifyJson(key);
676
632
  const family = { key: options.key, subKey };
677
633
  const fullKey = `${options.key}(${subKey})`;
678
- const existing = target.readonlySelectors.get(fullKey);
679
- if (existing) {
680
- return deposit(existing);
681
- }
682
- return createReadonlySelector(
634
+ const target = newest(store);
635
+ const token = createReadonlySelector(
683
636
  {
684
637
  key: fullKey,
685
638
  get: options.get(key)
686
639
  },
687
640
  family,
688
- store
641
+ target
689
642
  );
643
+ subject.next(token);
644
+ return token;
690
645
  },
691
646
  {
692
647
  key: options.key,
@@ -705,10 +660,7 @@ function createWritableSelectorFamily(options, store) {
705
660
  const subKey = json.stringifyJson(key);
706
661
  const family = { key: options.key, subKey };
707
662
  const fullKey = `${options.key}(${subKey})`;
708
- const existing = store.selectors.get(fullKey);
709
- if (existing) {
710
- return deposit(existing);
711
- }
663
+ const target = newest(store);
712
664
  const token = createWritableSelector(
713
665
  {
714
666
  key: fullKey,
@@ -716,7 +668,7 @@ function createWritableSelectorFamily(options, store) {
716
668
  set: options.set(key)
717
669
  },
718
670
  family,
719
- store
671
+ target
720
672
  );
721
673
  subject.next(token);
722
674
  return token;
@@ -744,10 +696,18 @@ function createSelectorFamily(options, store) {
744
696
  // internal/src/not-found-error.ts
745
697
  var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
746
698
  function prettyPrintTokenType(token) {
747
- if (token.type === `readonly_selector`) {
748
- return `Readonly Selector`;
699
+ switch (token.type) {
700
+ case `atom_family`:
701
+ return `Atom Family`;
702
+ case `readonly_selector`:
703
+ return `Readonly Selector`;
704
+ case `readonly_selector_family`:
705
+ return `Readonly Selector Family`;
706
+ case `selector_family`:
707
+ return `Selector Family`;
708
+ default:
709
+ return capitalize(token.type);
749
710
  }
750
- return capitalize(token.type);
751
711
  }
752
712
  var NotFoundError = class extends Error {
753
713
  constructor(token, store) {
@@ -757,8 +717,8 @@ var NotFoundError = class extends Error {
757
717
  }
758
718
  };
759
719
 
760
- // internal/src/families/find-in-store.ts
761
- function findInStore(token, key, store) {
720
+ // internal/src/families/init-family-member.ts
721
+ function initFamilyMember(token, key, store) {
762
722
  const familyKey = token.key;
763
723
  const family = store.families.get(familyKey);
764
724
  if (family === void 0) {
@@ -767,6 +727,44 @@ function findInStore(token, key, store) {
767
727
  const state = family(key);
768
728
  return state;
769
729
  }
730
+ function seekInStore(token, key, store) {
731
+ const subKey = json.stringifyJson(key);
732
+ const fullKey = `${token.key}(${subKey})`;
733
+ const target = newest(store);
734
+ let state;
735
+ switch (token.type) {
736
+ case `atom_family`:
737
+ case `mutable_atom_family`:
738
+ state = target.atoms.get(fullKey);
739
+ break;
740
+ case `selector_family`: {
741
+ state = target.selectors.get(fullKey);
742
+ break;
743
+ }
744
+ case `readonly_selector_family`:
745
+ state = target.readonlySelectors.get(fullKey);
746
+ break;
747
+ }
748
+ if (state) {
749
+ return deposit(state);
750
+ }
751
+ return state;
752
+ }
753
+
754
+ // internal/src/families/find-in-store.ts
755
+ function findInStore(token, key, store) {
756
+ if (store.config.lifespan === `immortal`) {
757
+ throw new Error(
758
+ `Do not use \`find\` or \`findState\` in an immortal store. Prefer \`seek\` or \`seekState\`.`
759
+ );
760
+ }
761
+ let state = seekInStore(token, key, store);
762
+ if (state) {
763
+ return state;
764
+ }
765
+ state = initFamilyMember(token, key, store);
766
+ return state;
767
+ }
770
768
 
771
769
  // internal/src/set-state/become.ts
772
770
  var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(
@@ -1009,7 +1007,7 @@ function setIntoStore(token, value, store) {
1009
1007
  );
1010
1008
  return;
1011
1009
  }
1012
- const state = withdrawOrCreate(token, store);
1010
+ const state = withdraw(token, store);
1013
1011
  setAtomOrSelector(state, value, store);
1014
1012
  closeOperation(store);
1015
1013
  }
@@ -1095,7 +1093,7 @@ var updateSelectorAtoms = (selectorKey, dependency, store) => {
1095
1093
  var registerSelector = (selectorKey, store) => ({
1096
1094
  get: (dependency) => {
1097
1095
  const target = newest(store);
1098
- const dependencyState = withdrawOrCreate(dependency, store);
1096
+ const dependencyState = withdraw(dependency, store);
1099
1097
  const dependencyValue = readOrComputeValue(dependencyState, store);
1100
1098
  store.logger.info(
1101
1099
  `\u{1F50C}`,
@@ -1118,19 +1116,20 @@ var registerSelector = (selectorKey, store) => ({
1118
1116
  return dependencyValue;
1119
1117
  },
1120
1118
  set: (WritableToken, newValue) => {
1121
- const state = withdrawOrCreate(WritableToken, store);
1119
+ const state = withdraw(WritableToken, store);
1122
1120
  setAtomOrSelector(state, newValue, store);
1123
1121
  },
1124
- find: (token, key) => findInStore(token, key, store)
1122
+ find: (token, key) => findInStore(token, key, store),
1123
+ seek: (token, key) => seekInStore(token, key, store)
1125
1124
  });
1126
1125
 
1127
1126
  // internal/src/selector/create-readonly-selector.ts
1128
1127
  var createReadonlySelector = (options, family, store) => {
1129
1128
  const target = newest(store);
1130
1129
  const subject = new Subject();
1131
- const { get, find } = registerSelector(options.key, target);
1130
+ const { get, find, seek } = registerSelector(options.key, target);
1132
1131
  const getSelf = () => {
1133
- const value = options.get({ get, find });
1132
+ const value = options.get({ get, find, seek });
1134
1133
  cacheValue(options.key, value, subject, newest(store));
1135
1134
  return value;
1136
1135
  };
@@ -1165,8 +1164,8 @@ var createWritableSelector = (options, family, store) => {
1165
1164
  const target = newest(store);
1166
1165
  const subject = new Subject();
1167
1166
  const transactors = registerSelector(options.key, target);
1168
- const { find, get } = transactors;
1169
- const readonlyTransactors = { find, get };
1167
+ const { find, get, seek } = transactors;
1168
+ const readonlyTransactors = { find, get, seek };
1170
1169
  const getSelf = () => {
1171
1170
  const value = options.get(readonlyTransactors);
1172
1171
  cacheValue(options.key, value, subject, newest(store));
@@ -1224,41 +1223,59 @@ function createStandaloneSelector(options, store) {
1224
1223
 
1225
1224
  // internal/src/selector/dispose-selector.ts
1226
1225
  function disposeSelector(selectorToken, store) {
1226
+ var _a;
1227
1227
  const target = newest(store);
1228
1228
  const { key } = selectorToken;
1229
- switch (selectorToken.type) {
1230
- case `selector`:
1231
- target.selectors.delete(key);
1232
- break;
1233
- case `readonly_selector`:
1234
- target.readonlySelectors.delete(key);
1235
- break;
1236
- }
1237
- target.valueMap.delete(key);
1238
- target.selectorAtoms.delete(key);
1239
- const downstreamTokens = target.selectorGraph.getRelationEntries({ upstreamSelectorKey: key }).filter(([_, { source }]) => source === key).map(
1240
- ([downstreamSelectorKey]) => {
1241
- var _a;
1242
- return (_a = target.selectors.get(downstreamSelectorKey)) != null ? _a : target.readonlySelectors.get(downstreamSelectorKey);
1229
+ const selector = (_a = target.selectors.get(key)) != null ? _a : target.readonlySelectors.get(key);
1230
+ if (!selector) {
1231
+ store.logger.error(
1232
+ `\u274C`,
1233
+ `selector`,
1234
+ key,
1235
+ `Tried to dispose selector, but it does not exist in the store.`
1236
+ );
1237
+ } else if (!selector.family) {
1238
+ store.logger.error(
1239
+ `\u274C`,
1240
+ `selector`,
1241
+ key,
1242
+ `Standalone selectors cannot be disposed.`
1243
+ );
1244
+ } else {
1245
+ switch (selectorToken.type) {
1246
+ case `selector`:
1247
+ target.selectors.delete(key);
1248
+ break;
1249
+ case `readonly_selector`:
1250
+ target.readonlySelectors.delete(key);
1251
+ break;
1243
1252
  }
1244
- );
1245
- for (const downstreamToken of downstreamTokens) {
1246
- if (downstreamToken) {
1247
- disposeSelector(downstreamToken, store);
1253
+ target.valueMap.delete(key);
1254
+ target.selectorAtoms.delete(key);
1255
+ const downstreamTokens = target.selectorGraph.getRelationEntries({ upstreamSelectorKey: key }).filter(([_, { source }]) => source === key).map(
1256
+ ([downstreamSelectorKey]) => {
1257
+ var _a2;
1258
+ return (_a2 = target.selectors.get(downstreamSelectorKey)) != null ? _a2 : target.readonlySelectors.get(downstreamSelectorKey);
1259
+ }
1260
+ );
1261
+ for (const downstreamToken of downstreamTokens) {
1262
+ if (downstreamToken) {
1263
+ disposeSelector(downstreamToken, store);
1264
+ }
1248
1265
  }
1266
+ target.selectorGraph.delete(key);
1267
+ store.logger.info(`\u{1F525}`, selectorToken.type, key, `deleted`);
1268
+ store.on.selectorDisposal.next(selectorToken);
1249
1269
  }
1250
- target.selectorGraph.delete(key);
1251
- store.logger.info(`\u{1F525}`, selectorToken.type, key, `deleted`);
1252
- store.on.selectorDisposal.next(selectorToken);
1253
1270
  }
1254
1271
 
1255
1272
  // internal/src/subscribe/recall-state.ts
1256
1273
  var recallState = (state, store) => {
1257
1274
  const target = newest(store);
1258
- if (!target.operation.open) {
1259
- return target.valueMap.get(state.key);
1275
+ if (target.operation.open) {
1276
+ return target.operation.prev.get(state.key);
1260
1277
  }
1261
- return target.operation.prev.get(state.key);
1278
+ return target.valueMap.get(state.key);
1262
1279
  };
1263
1280
 
1264
1281
  // internal/src/subscribe/subscribe-to-root-atoms.ts
@@ -1307,11 +1324,24 @@ var subscribeToRootAtoms = (selector, store) => {
1307
1324
 
1308
1325
  // internal/src/subscribe/subscribe-to-state.ts
1309
1326
  function subscribeToState(token, handleUpdate, key, store) {
1310
- const state = withdrawOrCreate(token, store);
1327
+ function safelyHandleUpdate(update) {
1328
+ if (store.operation.open) {
1329
+ const unsubscribe2 = store.on.operationClose.subscribe(
1330
+ `state subscription ${key}`,
1331
+ () => {
1332
+ unsubscribe2();
1333
+ handleUpdate(update);
1334
+ }
1335
+ );
1336
+ } else {
1337
+ handleUpdate(update);
1338
+ }
1339
+ }
1340
+ const state = withdraw(token, store);
1311
1341
  store.logger.info(`\u{1F440}`, state.type, state.key, `Adding subscription "${key}"`);
1312
1342
  const isSelector = state.type === `selector` || state.type === `readonly_selector`;
1313
1343
  let dependencyUnsubFunctions = null;
1314
- let updateHandler = handleUpdate;
1344
+ let updateHandler = safelyHandleUpdate;
1315
1345
  if (isSelector) {
1316
1346
  dependencyUnsubFunctions = subscribeToRootAtoms(state, store);
1317
1347
  updateHandler = (update) => {
@@ -1319,7 +1349,7 @@ function subscribeToState(token, handleUpdate, key, store) {
1319
1349
  dependencyUnsubFunctions.length = 0;
1320
1350
  dependencyUnsubFunctions.push(...subscribeToRootAtoms(state, store));
1321
1351
  }
1322
- handleUpdate(update);
1352
+ safelyHandleUpdate(update);
1323
1353
  };
1324
1354
  }
1325
1355
  const mainUnsubFunction = state.subject.subscribe(key, updateHandler);
@@ -1408,18 +1438,7 @@ var Tracker = class {
1408
1438
  this.unsubscribeFromInnerValue = originalInnerValue.subscribe(
1409
1439
  subscriptionKey,
1410
1440
  (update) => {
1411
- if (target.operation.open) {
1412
- const unsubscribe = target.on.operationClose.subscribe(
1413
- subscriptionKey,
1414
- () => {
1415
- unsubscribe();
1416
- setIntoStore(latestUpdateState, update, target);
1417
- }
1418
- );
1419
- } else {
1420
- setIntoStore(mutableState, (current) => current, target);
1421
- setIntoStore(latestUpdateState, update, target);
1422
- }
1441
+ setIntoStore(latestUpdateState, update, target);
1423
1442
  }
1424
1443
  );
1425
1444
  this.unsubscribeFromState = subscribeToState(
@@ -1430,18 +1449,7 @@ var Tracker = class {
1430
1449
  this.unsubscribeFromInnerValue = update.newValue.subscribe(
1431
1450
  subscriptionKey,
1432
1451
  (transceiverUpdate) => {
1433
- if (target.operation.open) {
1434
- const unsubscribe = target.on.operationClose.subscribe(
1435
- subscriptionKey,
1436
- () => {
1437
- unsubscribe();
1438
- setIntoStore(latestUpdateState, transceiverUpdate, target);
1439
- }
1440
- );
1441
- } else {
1442
- setIntoStore(mutableState, (current) => current, target);
1443
- setIntoStore(latestUpdateState, transceiverUpdate, target);
1444
- }
1452
+ setIntoStore(latestUpdateState, transceiverUpdate, target);
1445
1453
  }
1446
1454
  );
1447
1455
  }
@@ -1590,37 +1598,41 @@ function createMutableAtom(options, family, store) {
1590
1598
  };
1591
1599
  }
1592
1600
  new Tracker(token, store);
1593
- json.selectJson(token, options, store);
1601
+ if (!family) {
1602
+ json.selectJson(token, options, store);
1603
+ }
1594
1604
  store.on.atomCreation.next(token);
1595
1605
  return token;
1596
1606
  }
1597
1607
  var FamilyTracker = class {
1598
- constructor(findMutableState, store) {
1599
- this.findLatestUpdateState = createRegularAtomFamily(
1608
+ constructor(mutableAtoms, store) {
1609
+ this.latestUpdateAtoms = createRegularAtomFamily(
1600
1610
  {
1601
- key: `*${findMutableState.key}`,
1611
+ key: `*${mutableAtoms.key}`,
1602
1612
  default: null
1603
1613
  },
1604
1614
  store
1605
1615
  );
1606
- this.findMutableState = findMutableState;
1607
- this.findMutableState.subject.subscribe(
1616
+ this.mutableAtoms = mutableAtoms;
1617
+ this.mutableAtoms.subject.subscribe(
1608
1618
  `store=${store.config.name}::tracker-atom-family`,
1609
1619
  (atomToken) => {
1610
1620
  if (atomToken.family) {
1611
1621
  const key = json.parseJson(atomToken.family.subKey);
1612
- this.findLatestUpdateState(key);
1622
+ seekInStore(this.latestUpdateAtoms, key, store);
1613
1623
  new Tracker(atomToken, store);
1614
1624
  }
1615
1625
  }
1616
1626
  );
1617
- this.findLatestUpdateState.subject.subscribe(
1627
+ this.latestUpdateAtoms.subject.subscribe(
1618
1628
  `store=${store.config.name}::tracker-atom-family`,
1619
1629
  (atomToken) => {
1620
1630
  if (atomToken.family) {
1621
1631
  const key = json.parseJson(atomToken.family.subKey);
1622
- const mutableAtomToken = this.findMutableState(key);
1623
- new Tracker(mutableAtomToken, store);
1632
+ const mutableAtomToken = seekInStore(this.mutableAtoms, key, store);
1633
+ if (mutableAtomToken) {
1634
+ new Tracker(mutableAtomToken, store);
1635
+ }
1624
1636
  }
1625
1637
  }
1626
1638
  );
@@ -1635,25 +1647,19 @@ function createMutableAtomFamily(options, store) {
1635
1647
  const subKey = json.stringifyJson(key);
1636
1648
  const family = { key: options.key, subKey };
1637
1649
  const fullKey = `${options.key}(${subKey})`;
1638
- const target2 = newest(store);
1639
- const atomAlreadyCreated = target2.atoms.has(fullKey);
1640
- let token;
1641
- if (atomAlreadyCreated) {
1642
- token = { type: `mutable_atom`, key: fullKey, family };
1643
- } else {
1644
- const individualOptions = {
1645
- key: fullKey,
1646
- default: () => options.default(key),
1647
- toJson: options.toJson,
1648
- fromJson: options.fromJson,
1649
- mutable: true
1650
- };
1651
- if (options.effects) {
1652
- individualOptions.effects = options.effects(key);
1653
- }
1654
- token = createMutableAtom(individualOptions, family, store);
1655
- subject.next(token);
1650
+ const target = newest(store);
1651
+ const individualOptions = {
1652
+ key: fullKey,
1653
+ default: () => options.default(key),
1654
+ toJson: options.toJson,
1655
+ fromJson: options.fromJson,
1656
+ mutable: true
1657
+ };
1658
+ if (options.effects) {
1659
+ individualOptions.effects = options.effects(key);
1656
1660
  }
1661
+ const token = createMutableAtom(individualOptions, family, target);
1662
+ subject.next(token);
1657
1663
  return token;
1658
1664
  },
1659
1665
  {
@@ -1665,8 +1671,7 @@ function createMutableAtomFamily(options, store) {
1665
1671
  fromJson: options.fromJson
1666
1672
  }
1667
1673
  );
1668
- const target = newest(store);
1669
- target.families.set(options.key, atomFamily);
1674
+ store.families.set(options.key, atomFamily);
1670
1675
  json.selectJsonFamily(atomFamily, options, store);
1671
1676
  new FamilyTracker(atomFamily, store);
1672
1677
  return atomFamily;
@@ -1681,19 +1686,24 @@ var getJsonFamily = (mutableAtomFamily, store) => {
1681
1686
  };
1682
1687
 
1683
1688
  // internal/src/mutable/get-json-token.ts
1684
- var getJsonToken = (mutableAtomToken) => {
1685
- const key = mutableAtomToken.family ? `${mutableAtomToken.family.key}:JSON(${mutableAtomToken.family.subKey})` : `${mutableAtomToken.key}:JSON`;
1686
- const jsonToken = {
1687
- type: `selector`,
1688
- key
1689
- };
1689
+ var getJsonToken = (mutableAtomToken, store) => {
1690
1690
  if (mutableAtomToken.family) {
1691
- jsonToken.family = {
1692
- key: `${mutableAtomToken.family.key}:JSON`,
1693
- subKey: mutableAtomToken.family.subKey
1691
+ const target = newest(store);
1692
+ const jsonFamilyKey = `${mutableAtomToken.family.key}:JSON`;
1693
+ const jsonFamilyToken = {
1694
+ key: jsonFamilyKey,
1695
+ type: `selector_family`
1694
1696
  };
1697
+ const family = withdraw(jsonFamilyToken, target);
1698
+ const subKey = JSON.parse(mutableAtomToken.family.subKey);
1699
+ const jsonToken = findInStore(family, subKey, store);
1700
+ return jsonToken;
1695
1701
  }
1696
- return jsonToken;
1702
+ const token = {
1703
+ type: `selector`,
1704
+ key: `${mutableAtomToken.key}:JSON`
1705
+ };
1706
+ return token;
1697
1707
  };
1698
1708
 
1699
1709
  // internal/src/mutable/get-update-token.ts
@@ -1889,8 +1899,10 @@ function disposeAtom(atomToken, store) {
1889
1899
  `\u274C`,
1890
1900
  `atom`,
1891
1901
  key,
1892
- `Tried to delete atom, but it does not exist in the store.`
1902
+ `Tried to dispose atom, but it does not exist in the store.`
1893
1903
  );
1904
+ } else if (!atom.family) {
1905
+ store.logger.error(`\u274C`, `atom`, key, `Standalone atoms cannot be disposed.`);
1894
1906
  } else {
1895
1907
  (_a = atom.cleanup) == null ? void 0 : _a.call(atom);
1896
1908
  target.atoms.delete(key);
@@ -1910,6 +1922,7 @@ function disposeAtom(atomToken, store) {
1910
1922
  if (atomToken.type === `mutable_atom`) {
1911
1923
  const updateToken = getUpdateToken(atomToken);
1912
1924
  disposeAtom(updateToken, store);
1925
+ store.trackers.delete(key);
1913
1926
  }
1914
1927
  store.logger.info(`\u{1F525}`, `atom`, key, `deleted`);
1915
1928
  store.on.atomDisposal.next(atomToken);
@@ -1927,7 +1940,7 @@ function getEnvironmentData(store) {
1927
1940
 
1928
1941
  // internal/src/get-state/get-from-store.ts
1929
1942
  function getFromStore(token, store) {
1930
- const state = withdrawOrCreate(token, store);
1943
+ const state = withdraw(token, store);
1931
1944
  return readOrComputeValue(state, store);
1932
1945
  }
1933
1946
 
@@ -2481,7 +2494,9 @@ var buildTransaction = (key, params, store, id) => {
2481
2494
  makeContentKey: (...keys) => keys.sort().join(`:`)
2482
2495
  }),
2483
2496
  selectors: new LazyMap(parent.selectors),
2484
- valueMap: new LazyMap(parent.valueMap)
2497
+ valueMap: new LazyMap(parent.valueMap),
2498
+ molecules: new LazyMap(parent.molecules),
2499
+ miscResources: new LazyMap(parent.miscResources)
2485
2500
  };
2486
2501
  const epoch = getEpochNumberOfAction(key, store);
2487
2502
  const transactionMeta = {
@@ -2501,6 +2516,7 @@ var buildTransaction = (key, params, store, id) => {
2501
2516
  },
2502
2517
  run: (token, identifier = arbitrary()) => actUponStore(token, identifier, child),
2503
2518
  find: (token, k) => findInStore(token, k, child),
2519
+ seek: (token, k) => seekInStore(token, k, child),
2504
2520
  env: () => getEnvironmentData(child)
2505
2521
  }
2506
2522
  };
@@ -2619,6 +2635,7 @@ exports.getUpdateToken = getUpdateToken;
2619
2635
  exports.ingestAtomUpdate = ingestAtomUpdate;
2620
2636
  exports.ingestSelectorUpdate = ingestSelectorUpdate;
2621
2637
  exports.ingestTransactionUpdate = ingestTransactionUpdate;
2638
+ exports.initFamilyMember = initFamilyMember;
2622
2639
  exports.isAtomDefault = isAtomDefault;
2623
2640
  exports.isAtomKey = isAtomKey;
2624
2641
  exports.isChildStore = isChildStore;
@@ -2637,6 +2654,7 @@ exports.openOperation = openOperation;
2637
2654
  exports.readCachedValue = readCachedValue;
2638
2655
  exports.readOrComputeValue = readOrComputeValue;
2639
2656
  exports.registerSelector = registerSelector;
2657
+ exports.seekInStore = seekInStore;
2640
2658
  exports.setAtomOrSelector = setAtomOrSelector;
2641
2659
  exports.setEpochNumberOfAction = setEpochNumberOfAction;
2642
2660
  exports.setEpochNumberOfContinuity = setEpochNumberOfContinuity;
@@ -2650,4 +2668,3 @@ exports.traceAllSelectorAtoms = traceAllSelectorAtoms;
2650
2668
  exports.traceSelectorAtoms = traceSelectorAtoms;
2651
2669
  exports.updateSelectorAtoms = updateSelectorAtoms;
2652
2670
  exports.withdraw = withdraw;
2653
- exports.withdrawOrCreate = withdrawOrCreate;