atom.io 0.40.6 → 0.40.8

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 (186) hide show
  1. package/README.md +1 -1
  2. package/dist/data/index.d.ts +1 -1
  3. package/dist/data/index.js +1 -2
  4. package/dist/data/index.js.map +1 -1
  5. package/dist/employ-socket-D6wgByWh.js +12 -0
  6. package/dist/employ-socket-D6wgByWh.js.map +1 -0
  7. package/dist/eslint-plugin/index.js.map +1 -1
  8. package/dist/has-role-CMlaUlaf.js +1133 -0
  9. package/dist/has-role-CMlaUlaf.js.map +1 -0
  10. package/dist/internal/index.d.ts +248 -248
  11. package/dist/internal/index.d.ts.map +1 -1
  12. package/dist/internal/index.js +590 -1803
  13. package/dist/internal/index.js.map +1 -1
  14. package/dist/introspection/index.d.ts +1 -1
  15. package/dist/introspection/index.d.ts.map +1 -1
  16. package/dist/introspection/index.js +13 -32
  17. package/dist/introspection/index.js.map +1 -1
  18. package/dist/is-fn-DY1wZ-md.js +10 -0
  19. package/dist/is-fn-DY1wZ-md.js.map +1 -0
  20. package/dist/json/index.d.ts.map +1 -1
  21. package/dist/json/index.js.map +1 -1
  22. package/dist/main/index.d.ts +33 -33
  23. package/dist/main/index.d.ts.map +1 -1
  24. package/dist/main/index.js +3 -4
  25. package/dist/main/index.js.map +1 -1
  26. package/dist/mutex-store-CSvxY9i3.js +11 -0
  27. package/dist/mutex-store-CSvxY9i3.js.map +1 -0
  28. package/dist/react/index.d.ts +5 -5
  29. package/dist/react/index.d.ts.map +1 -1
  30. package/dist/react/index.js.map +1 -1
  31. package/dist/react-devtools/index.d.ts.map +1 -1
  32. package/dist/react-devtools/index.js +9 -11
  33. package/dist/react-devtools/index.js.map +1 -1
  34. package/dist/realtime/index.d.ts +7 -15
  35. package/dist/realtime/index.d.ts.map +1 -1
  36. package/dist/realtime/index.js +4 -35
  37. package/dist/realtime/index.js.map +1 -1
  38. package/dist/realtime-client/index.d.ts +6 -9
  39. package/dist/realtime-client/index.d.ts.map +1 -1
  40. package/dist/realtime-client/index.js +96 -88
  41. package/dist/realtime-client/index.js.map +1 -1
  42. package/dist/realtime-react/index.d.ts +17 -13
  43. package/dist/realtime-react/index.d.ts.map +1 -1
  44. package/dist/realtime-react/index.js +39 -50
  45. package/dist/realtime-react/index.js.map +1 -1
  46. package/dist/realtime-server/index.d.ts +83 -84
  47. package/dist/realtime-server/index.d.ts.map +1 -1
  48. package/dist/realtime-server/index.js +604 -543
  49. package/dist/realtime-server/index.js.map +1 -1
  50. package/dist/realtime-testing/index.d.ts +5 -4
  51. package/dist/realtime-testing/index.d.ts.map +1 -1
  52. package/dist/realtime-testing/index.js +35 -22
  53. package/dist/realtime-testing/index.js.map +1 -1
  54. package/dist/shared-room-store-BfW3nWif.js +31 -0
  55. package/dist/shared-room-store-BfW3nWif.js.map +1 -0
  56. package/dist/shared-room-store-D2o4ZLjC.d.ts +15 -0
  57. package/dist/shared-room-store-D2o4ZLjC.d.ts.map +1 -0
  58. package/dist/transceivers/set-rtx/index.d.ts.map +1 -1
  59. package/dist/transceivers/set-rtx/index.js +4 -8
  60. package/dist/transceivers/set-rtx/index.js.map +1 -1
  61. package/dist/web/index.d.ts +3 -3
  62. package/dist/web/index.d.ts.map +1 -1
  63. package/dist/web/index.js +4 -3
  64. package/dist/web/index.js.map +1 -1
  65. package/package.json +13 -13
  66. package/src/internal/atom/create-regular-atom.ts +5 -4
  67. package/src/internal/atom/dispose-atom.ts +7 -2
  68. package/src/internal/atom/has-role.ts +3 -3
  69. package/src/internal/caching.ts +4 -2
  70. package/src/internal/families/create-readonly-held-selector-family.ts +2 -1
  71. package/src/internal/families/create-readonly-pure-selector-family.ts +5 -2
  72. package/src/internal/families/create-regular-atom-family.ts +2 -1
  73. package/src/internal/families/create-writable-held-selector-family.ts +2 -1
  74. package/src/internal/families/create-writable-pure-selector-family.ts +5 -2
  75. package/src/internal/families/dispose-from-store.ts +4 -4
  76. package/src/internal/families/find-in-store.ts +10 -10
  77. package/src/internal/families/get-family-of-token.ts +2 -2
  78. package/src/internal/families/index.ts +1 -0
  79. package/src/internal/families/mint-in-store.ts +54 -19
  80. package/src/internal/families/seek-in-store.ts +1 -1
  81. package/src/internal/get-state/get-fallback.ts +2 -2
  82. package/src/internal/get-state/get-from-store.ts +5 -5
  83. package/src/internal/get-state/read-or-compute-value.ts +1 -1
  84. package/src/internal/get-state/reduce-reference.ts +8 -6
  85. package/src/internal/index.ts +2 -220
  86. package/src/internal/molecule.ts +1 -2
  87. package/src/internal/mutable/create-mutable-atom-family.ts +3 -2
  88. package/src/internal/mutable/create-mutable-atom.ts +4 -2
  89. package/src/internal/mutable/get-json-family.ts +1 -1
  90. package/src/internal/mutable/get-update-family.ts +1 -1
  91. package/src/internal/mutable/tracker-family.ts +2 -1
  92. package/src/internal/mutable/tracker.ts +71 -59
  93. package/src/internal/safe-compute.ts +1 -1
  94. package/src/internal/selector/create-readonly-held-selector.ts +2 -1
  95. package/src/internal/selector/create-readonly-pure-selector.ts +2 -1
  96. package/src/internal/selector/create-writable-held-selector.ts +2 -1
  97. package/src/internal/selector/create-writable-pure-selector.ts +2 -1
  98. package/src/internal/selector/dispose-selector.ts +3 -2
  99. package/src/internal/selector/register-selector.ts +8 -5
  100. package/src/internal/selector/trace-selector-atoms.ts +2 -1
  101. package/src/internal/set-state/dispatch-state-update.ts +3 -2
  102. package/src/internal/set-state/evict-downstream.ts +1 -1
  103. package/src/internal/set-state/operate-on-store.ts +16 -22
  104. package/src/internal/set-state/reset-atom-or-selector.ts +5 -3
  105. package/src/internal/set-state/reset-in-store.ts +5 -5
  106. package/src/internal/set-state/set-atom-or-selector.ts +2 -2
  107. package/src/internal/set-state/set-atom.ts +4 -2
  108. package/src/internal/set-state/set-into-store.ts +21 -39
  109. package/src/internal/set-state/set-selector.ts +3 -2
  110. package/src/internal/state-types.ts +228 -0
  111. package/src/internal/store/deposit.ts +4 -4
  112. package/src/internal/store/index.ts +0 -1
  113. package/src/internal/store/store.ts +9 -9
  114. package/src/internal/store/withdraw.ts +4 -4
  115. package/src/internal/subscribe/recall-state.ts +1 -1
  116. package/src/internal/subscribe/subscribe-to-root-atoms.ts +1 -12
  117. package/src/internal/subscribe/subscribe-to-state.ts +9 -0
  118. package/src/internal/subscribe/subscribe-to-transaction.ts +3 -2
  119. package/src/internal/transaction/build-transaction.ts +3 -2
  120. package/src/internal/transaction/index.ts +1 -23
  121. package/src/internal/transaction/is-root-store.ts +4 -1
  122. package/src/internal/transaction/transaction-meta-progress.ts +22 -0
  123. package/src/main/atom.ts +1 -2
  124. package/src/main/find-state.ts +5 -5
  125. package/src/main/get-state.ts +4 -4
  126. package/src/main/realm.ts +2 -2
  127. package/src/main/set-state.ts +10 -10
  128. package/src/react/parse-state-overloads.ts +3 -3
  129. package/src/react/use-i.ts +6 -4
  130. package/src/react/use-loadable.ts +4 -10
  131. package/src/react/use-o.ts +6 -4
  132. package/src/react-devtools/store.ts +6 -6
  133. package/src/realtime/index.ts +1 -0
  134. package/src/realtime/mutex-store.ts +11 -0
  135. package/src/realtime/realtime-continuity.ts +1 -5
  136. package/src/realtime-client/index.ts +0 -1
  137. package/src/realtime-client/pull-atom-family-member.ts +14 -17
  138. package/src/realtime-client/pull-atom.ts +1 -1
  139. package/src/realtime-client/pull-mutable-atom-family-member.ts +16 -12
  140. package/src/realtime-client/pull-selector-family-member.ts +8 -35
  141. package/src/realtime-client/pull-selector-roots.ts +90 -0
  142. package/src/realtime-client/pull-selector.ts +2 -27
  143. package/src/realtime-client/push-state.ts +33 -5
  144. package/src/realtime-client/realtime-client-stores/client-main-store.ts +2 -5
  145. package/src/realtime-react/index.ts +2 -2
  146. package/src/realtime-react/realtime-context.tsx +9 -5
  147. package/src/realtime-react/use-pull-atom-family-member.ts +2 -3
  148. package/src/realtime-react/use-pull-mutable-family-member.ts +2 -3
  149. package/src/realtime-react/use-pull-selector-family-member.ts +5 -6
  150. package/src/realtime-react/use-push.ts +7 -3
  151. package/src/realtime-react/use-realtime-service.ts +11 -11
  152. package/src/realtime-react/use-single-effect.ts +11 -14
  153. package/src/realtime-server/{realtime-server-stores/server-sync-store.ts → continuity/continuity-store.ts} +2 -27
  154. package/src/realtime-server/continuity/provide-continuity.ts +50 -0
  155. package/src/realtime-server/continuity/{subscribe-to-continuity-actions.ts → provide-outcomes.ts} +15 -13
  156. package/src/realtime-server/continuity/{subscribe-to-continuity-perpectives.ts → provide-perspectives.ts} +10 -8
  157. package/src/realtime-server/continuity/{prepare-to-send-initial-payload.ts → provide-startup-payloads.ts} +6 -4
  158. package/src/realtime-server/continuity/receive-action-requests.ts +68 -0
  159. package/src/realtime-server/continuity/track-acknowledgements.ts +46 -0
  160. package/src/realtime-server/employ-socket.ts +14 -0
  161. package/src/realtime-server/index.ts +3 -22
  162. package/src/realtime-server/ipc-sockets/child-socket.ts +125 -66
  163. package/src/realtime-server/ipc-sockets/custom-socket.ts +16 -14
  164. package/src/realtime-server/ipc-sockets/parent-socket.ts +98 -69
  165. package/src/realtime-server/realtime-family-provider.ts +78 -29
  166. package/src/realtime-server/realtime-mutable-family-provider.ts +80 -31
  167. package/src/realtime-server/realtime-mutable-provider.ts +30 -22
  168. package/src/realtime-server/realtime-server-stores/index.ts +0 -2
  169. package/src/realtime-server/realtime-server-stores/server-room-external-store.ts +77 -36
  170. package/src/realtime-server/realtime-server-stores/server-user-store.ts +12 -1
  171. package/src/realtime-server/realtime-state-provider.ts +30 -29
  172. package/src/realtime-server/realtime-state-receiver.ts +62 -16
  173. package/src/realtime-server/server-config.ts +8 -0
  174. package/src/realtime-server/socket-interface.ts +14 -0
  175. package/src/realtime-testing/setup-realtime-test.tsx +70 -31
  176. package/src/web/index.ts +1 -1
  177. package/src/web/{persist-sync.ts → storage-sync.ts} +5 -2
  178. package/src/internal/store/mint-or-counterfeit.ts +0 -108
  179. package/src/realtime-client/server-action.ts +0 -23
  180. package/src/realtime-react/on-mount.ts +0 -5
  181. package/src/realtime-react/use-server-action.ts +0 -19
  182. package/src/realtime-server/continuity/prepare-to-serve-transaction-request.ts +0 -59
  183. package/src/realtime-server/continuity/prepare-to-sync-realtime-continuity.ts +0 -145
  184. package/src/realtime-server/continuity/prepare-to-track-client-acknowledgement.ts +0 -41
  185. package/src/realtime-server/realtime-action-receiver.ts +0 -40
  186. package/src/realtime-server/realtime-server-stores/server-room-external-actions.ts +0 -79
@@ -1,5 +1,7 @@
1
- import { parseJson, stringifyJson } from "atom.io/json";
1
+ import { DO_NOT_CREATE, Future, INTERNAL_ROLES, JOIN_OP, NotFoundError, RESET_STATE, StatefulSubject, Subject, Tracker, become, closeOperation, createRegularAtom, deposit, eldest, evictCachedValue, evictDownstreamFromAtom, evictDownstreamFromSelector, getFallback, getFamilyOfToken, getFromStore, getSelectorDependencyKeys, hasRole, isAtomKey, isChildStore, isDone, isReadonlySelectorKey, isRootStore, isSelectorKey, isStateKey, isTransceiver, markDone, mintInStore, newest, openOperation, operateOnStore, readFromCache, readOrComputeValue, recallState, reduceReference, resetAtomOrSelector, resetInStore, seekInStore, setAtomOrSelector, setIntoStore, subscribeToRootDependency, subscribeToState, subscribeToTimeline, traceRootSelectorAtoms, withdraw, writeToCache } from "../has-role-CMlaUlaf.js";
2
+ import { isFn } from "../is-fn-DY1wZ-md.js";
2
3
  import { Anarchy, AtomIOLogger, PRETTY_TOKEN_TYPES } from "atom.io";
4
+ import { parseJson, stringifyJson } from "atom.io/json";
3
5
  import { SetRTX } from "atom.io/transceivers/set-rtx";
4
6
 
5
7
  //#region src/internal/arbitrary.ts
@@ -7,17 +9,6 @@ function arbitrary(random = Math.random) {
7
9
  return random().toString(36).slice(2);
8
10
  }
9
11
 
10
- //#endregion
11
- //#region src/internal/lineage.ts
12
- function newest(scion) {
13
- while (scion.child !== null) scion = scion.child;
14
- return scion;
15
- }
16
- function eldest(scion) {
17
- while (scion.parent !== null) scion = scion.parent;
18
- return scion;
19
- }
20
-
21
12
  //#endregion
22
13
  //#region src/internal/store/circular-buffer.ts
23
14
  var CircularBuffer = class CircularBuffer {
@@ -46,45 +37,6 @@ var CircularBuffer = class CircularBuffer {
46
37
  }
47
38
  };
48
39
 
49
- //#endregion
50
- //#region src/internal/store/deposit.ts
51
- function deposit(state) {
52
- const token = {
53
- key: state.key,
54
- type: state.type
55
- };
56
- if (`family` in state) token.family = state.family;
57
- return token;
58
- }
59
-
60
- //#endregion
61
- //#region src/internal/store/mint-or-counterfeit.ts
62
- const COUNTERFEIT = Symbol(`counterfeit`);
63
- const FAMILY_MEMBER_TOKEN_TYPES = {
64
- atom_family: `atom`,
65
- molecule_family: `molecule`,
66
- mutable_atom_family: `mutable_atom`,
67
- readonly_held_selector_family: `readonly_held_selector`,
68
- readonly_pure_selector_family: `readonly_pure_selector`,
69
- writable_held_selector_family: `writable_held_selector`,
70
- writable_pure_selector_family: `writable_pure_selector`
71
- };
72
- function mint(token, key, counterfeit) {
73
- const subKey = stringifyJson(key);
74
- const fullKey = `${token.key}(${subKey})`;
75
- const type = FAMILY_MEMBER_TOKEN_TYPES[token.type];
76
- const stateToken = {
77
- key: fullKey,
78
- type,
79
- family: {
80
- key: token.key,
81
- subKey
82
- }
83
- };
84
- if (counterfeit) stateToken.counterfeit = true;
85
- return stateToken;
86
- }
87
-
88
40
  //#endregion
89
41
  //#region src/internal/overlays/map-overlay.ts
90
42
  var MapOverlay = class extends Map {
@@ -96,13 +48,8 @@ var MapOverlay = class extends Map {
96
48
  this.source = source;
97
49
  }
98
50
  get(key) {
99
- const has = super.has(key);
100
- if (has) return super.get(key);
101
- if (!this.deleted.has(key) && this.source.has(key)) {
102
- const value = this.source.get(key);
103
- return value;
104
- }
105
- return void 0;
51
+ if (super.has(key)) return super.get(key);
52
+ if (!this.deleted.has(key) && this.source.has(key)) return this.source.get(key);
106
53
  }
107
54
  set(key, value) {
108
55
  this.deleted.delete(key);
@@ -204,15 +151,13 @@ var RelationsOverlay = class extends Map {
204
151
  this.source = source;
205
152
  }
206
153
  get(key) {
207
- const has = super.has(key);
208
- if (has) return super.get(key);
154
+ if (super.has(key)) return super.get(key);
209
155
  if (!this.deleted.has(key) && this.source.has(key)) {
210
156
  const value = this.source.get(key);
211
157
  const valueOverlay = new SetOverlay(value);
212
158
  super.set(key, valueOverlay);
213
159
  return valueOverlay;
214
160
  }
215
- return void 0;
216
161
  }
217
162
  set(key, value) {
218
163
  this.deleted.delete(key);
@@ -486,10 +431,7 @@ var Junction = class Junction {
486
431
  return [];
487
432
  }
488
433
  has(a, b) {
489
- if (b) {
490
- const setA = this.getRelatedKeys(a);
491
- return setA?.has(b) ?? false;
492
- }
434
+ if (b) return this.getRelatedKeys(a)?.has(b) ?? false;
493
435
  return this.relations.has(a);
494
436
  }
495
437
  overlay() {
@@ -519,407 +461,9 @@ var Junction = class Junction {
519
461
  };
520
462
 
521
463
  //#endregion
522
- //#region src/internal/subject.ts
523
- var Subject = class {
524
- Subscriber;
525
- subscribers = /* @__PURE__ */ new Map();
526
- subscribe(key, subscriber) {
527
- this.subscribers.set(key, subscriber);
528
- const unsubscribe = () => {
529
- this.unsubscribe(key);
530
- };
531
- return unsubscribe;
532
- }
533
- unsubscribe(key) {
534
- this.subscribers.delete(key);
535
- }
536
- next(value) {
537
- const subscribers = this.subscribers.values();
538
- for (const subscriber of subscribers) subscriber(value);
539
- }
540
- };
541
- var StatefulSubject = class extends Subject {
542
- state;
543
- constructor(initialState) {
544
- super();
545
- this.state = initialState;
546
- }
547
- next(value) {
548
- this.state = value;
549
- super.next(value);
550
- }
551
- };
552
-
553
- //#endregion
554
- //#region src/internal/subscribe/recall-state.ts
555
- const recallState = (store, state) => {
556
- const target = newest(store);
557
- if (target.operation.open) return target.operation.prev.get(state.key);
558
- return target.valueMap.get(state.key);
559
- };
560
-
561
- //#endregion
562
- //#region src/internal/get-state/get-fallback.ts
563
- function getFallback(store, token, family, subKey) {
564
- const disposal = store.disposalTraces.buffer.find((item) => item?.key === stringifyJson(subKey));
565
- 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)`);
566
- switch (family.type) {
567
- case `mutable_atom_family`: {
568
- if (store.defaults.has(family.key)) return store.defaults.get(family.key);
569
- const defaultValue = new family.class();
570
- store.defaults.set(family.key, defaultValue);
571
- return defaultValue.READONLY_VIEW;
572
- }
573
- case `atom_family`: {
574
- if (store.defaults.has(family.key)) return store.defaults.get(family.key);
575
- const def = family.default;
576
- const defaultValue = def(subKey);
577
- store.defaults.set(family.key, defaultValue);
578
- return defaultValue;
579
- }
580
- case `readonly_pure_selector_family`:
581
- case `writable_pure_selector_family`:
582
- case `readonly_held_selector_family`:
583
- case `writable_held_selector_family`: {
584
- if (store.defaults.has(family.key)) return store.defaults.get(family.key);
585
- const defaultValue = family.default(subKey);
586
- store.defaults.set(family.key, defaultValue);
587
- return defaultValue;
588
- }
589
- }
590
- }
591
-
592
- //#endregion
593
- //#region src/internal/future.ts
594
- /**
595
- * A Promise whose incoming value can be hot swapped.
596
- * @internal
597
- * @private
598
- * @typeParam T The type of the value that the promise will resolve to.
599
- *
600
- * @remarks
601
- * Can be constructed like a Promise, or from an existing Promise.
602
- */
603
- var Future = class extends Promise {
604
- fate;
605
- resolve;
606
- reject;
607
- done = false;
608
- constructor(executor) {
609
- let superResolve;
610
- let superReject;
611
- super((resolve, reject) => {
612
- superResolve = resolve;
613
- superReject = reject;
614
- });
615
- this.resolve = superResolve;
616
- this.reject = superReject;
617
- this.use(executor instanceof Promise ? executor : new Promise(executor));
618
- }
619
- pass(promise, value) {
620
- if (promise === this.fate) {
621
- this.resolve(value);
622
- this.done = true;
623
- }
624
- }
625
- fail(promise, reason) {
626
- if (promise === this.fate) {
627
- this.reject(reason);
628
- this.done = true;
629
- }
630
- }
631
- use(value) {
632
- if (this === value) return;
633
- if (value instanceof Promise) {
634
- const promise = value;
635
- this.fate = promise;
636
- promise.then((resolved) => {
637
- this.pass(promise, resolved);
638
- }, (reason) => {
639
- this.fail(promise, reason);
640
- });
641
- } else {
642
- this.resolve(value);
643
- this.fate = void 0;
644
- }
645
- }
646
- };
647
-
648
- //#endregion
649
- //#region src/internal/transaction/is-root-store.ts
650
- function isRootStore(store) {
651
- return `epoch` in store.transactionMeta;
652
- }
653
- function isChildStore(store) {
654
- return `phase` in store.transactionMeta;
655
- }
656
-
657
- //#endregion
658
- //#region src/internal/operation.ts
659
- function openOperation(store, token) {
660
- if (store.operation.open) {
661
- const rejectionTime = performance.now();
662
- store.logger.info(`🚫`, token.type, token.key, `deferring setState at T-${rejectionTime} until setState for "${store.operation.token.key}" is done`);
663
- return rejectionTime;
664
- }
665
- store.operation = {
666
- open: true,
667
- done: /* @__PURE__ */ new Set(),
668
- prev: /* @__PURE__ */ new Map(),
669
- timestamp: Date.now(),
670
- token,
671
- subEvents: []
672
- };
673
- store.logger.info(`⭕`, token.type, token.key, `operation start in store "${store.config.name}"${isChildStore(store) ? ` ${store.transactionMeta.phase} "${store.transactionMeta.update.token.key}"` : ``}`);
674
- return store;
675
- }
676
- function closeOperation(store) {
677
- if (store.operation.open) store.logger.info(`🔴`, store.operation.token.type, store.operation.token.key, `operation done in store "${store.config.name}"`);
678
- store.operation = { open: false };
679
- store.on.operationClose.next(store.operation);
680
- }
681
- const isDone = (store, key) => {
682
- if (!store.operation.open) {
683
- store.logger.error(`🐞`, `unknown`, key, `isDone called outside of an operation. This is probably a bug in AtomIO.`);
684
- return true;
685
- }
686
- return store.operation.done.has(key);
687
- };
688
- const markDone = (store, key) => {
689
- if (!store.operation.open) {
690
- store.logger.error(`🐞`, `unknown`, key, `markDone called outside of an operation. This is probably a bug in AtomIO.`);
691
- return;
692
- }
693
- store.operation.done.add(key);
694
- };
695
-
696
- //#endregion
697
- //#region src/internal/set-state/evict-downstream.ts
698
- function evictDownstreamFromAtom(store, atom) {
699
- const target = newest(store);
700
- const { key, type } = atom;
701
- const downstreamKeys = target.selectorAtoms.getRelatedKeys(key);
702
- target.logger.info(`🧹`, type, key, downstreamKeys ? `evicting ${downstreamKeys.size} states downstream:` : `no downstream states`, downstreamKeys ?? `to evict`);
703
- if (downstreamKeys) {
704
- if (target.operation.open) target.logger.info(`🧹`, type, key, `[ ${[...target.operation.done].join(`, `)} ] already done`);
705
- for (const downstreamKey of downstreamKeys) {
706
- if (isDone(target, downstreamKey)) continue;
707
- evictCachedValue(target, downstreamKey);
708
- markDone(target, downstreamKey);
709
- }
710
- }
711
- }
712
- function evictDownstreamFromSelector(store, selectorKey) {
713
- const target = newest(store);
714
- const relationEntries = target.selectorGraph.getRelationEntries({ upstreamSelectorKey: selectorKey }).filter(([_, { source }]) => source === selectorKey);
715
- for (const [downstreamSelectorKey] of relationEntries) {
716
- if (isDone(target, downstreamSelectorKey)) continue;
717
- evictCachedValue(target, downstreamSelectorKey);
718
- markDone(target, downstreamSelectorKey);
719
- evictDownstreamFromSelector(store, downstreamSelectorKey);
720
- }
721
- }
722
-
723
- //#endregion
724
- //#region src/internal/caching.ts
725
- function writeToCache(target, state, value) {
726
- const { key, subject, type } = state;
727
- const currentValue = target.valueMap.get(key);
728
- if (currentValue instanceof Future && !currentValue.done) {
729
- const future = currentValue;
730
- if (value instanceof Promise) {
731
- future.use(value);
732
- return future;
733
- }
734
- target.valueMap.set(key, value);
735
- return value;
736
- }
737
- if (value instanceof Promise) {
738
- const future = new Future(value);
739
- target.valueMap.set(key, future);
740
- future.then(function handleResolvedFuture(resolved) {
741
- const current = target.valueMap.get(key);
742
- if (current === future) {
743
- openOperation(target, state);
744
- writeToCache(target, state, resolved);
745
- switch (type) {
746
- case `atom`:
747
- evictDownstreamFromAtom(target, state);
748
- break;
749
- case `readonly_pure_selector`:
750
- case `writable_pure_selector`:
751
- evictDownstreamFromSelector(target, key);
752
- break;
753
- }
754
- closeOperation(target);
755
- subject.next({
756
- newValue: resolved,
757
- oldValue: future
758
- });
759
- }
760
- }).catch((thrown) => {
761
- target.logger.error(`💥`, state.type, key, `rejected:`, thrown);
762
- });
763
- return future;
764
- }
765
- target.logger.info(`📝`, state.type, state.key, `writing to cache`, value);
766
- target.valueMap.set(key, value);
767
- return value;
768
- }
769
- /**
770
- * @param target - the newest layer of the store
771
- * @param state - the state to read from cache
772
- * @param mut - whether the value is intended to be mutable
773
- * @returns the state's current value
774
- */
775
- function readFromCache(target, state, mut) {
776
- target.logger.info(`📖`, state.type, state.key, `reading cached value`);
777
- let value = target.valueMap.get(state.key);
778
- const mayNeedToBeCopied = mut === `mut` && state.type === `mutable_atom` && isChildStore(target);
779
- if (mayNeedToBeCopied) {
780
- const mutableAtom$1 = state;
781
- const { parent } = target;
782
- if (target.valueMap.hasOwn(mutableAtom$1.key)) return value;
783
- const parentValue = parent.valueMap.get(mutableAtom$1.key);
784
- target.logger.info(`📃`, `atom`, mutableAtom$1.key, `copying`);
785
- const jsonValue = parentValue.toJSON();
786
- const copiedValue = mutableAtom$1.class.fromJSON(jsonValue);
787
- target.valueMap.set(mutableAtom$1.key, copiedValue);
788
- new Tracker(mutableAtom$1, parent);
789
- value = copiedValue;
790
- }
791
- return value;
792
- }
793
- function evictCachedValue(target, key) {
794
- const currentValue = target.valueMap.get(key);
795
- if (currentValue instanceof Future) {
796
- const selector = target.writableSelectors.get(key) ?? target.readonlySelectors.get(key);
797
- if (selector) selector.getFrom(target);
798
- return;
799
- }
800
- if (target.operation.open) target.operation.prev.set(key, currentValue);
801
- target.valueMap.delete(key);
802
- target.logger.info(`🗑`, `state`, key, `evicted`);
803
- }
804
-
805
- //#endregion
806
- //#region src/internal/is-fn.ts
807
- const NON_CTOR_FN_REGEX = /^\[object (?:Async|Generator|AsyncGenerator)?Function\]$/;
808
- function isFn(input) {
809
- const protoString = Object.prototype.toString.call(input);
810
- return NON_CTOR_FN_REGEX.test(protoString);
811
- }
812
-
813
- //#endregion
814
- //#region src/internal/safe-compute.ts
815
- function safeCompute(target, state) {
816
- const { type, key, catch: canCatch } = state;
817
- switch (type) {
818
- case `readonly_pure_selector`:
819
- case `writable_pure_selector`: {
820
- let val;
821
- target.logger.info(`🧮`, type, key, `computing value`);
822
- try {
823
- val = state.getFrom(target);
824
- if (val instanceof Promise) return val.catch((thrown) => {
825
- target.logger.error(`💥`, type, key, `rejected:`, thrown);
826
- if (canCatch) {
827
- for (const Class of canCatch) if (thrown instanceof Class) return thrown;
828
- }
829
- throw thrown;
830
- });
831
- } catch (e) {
832
- target.logger.error(`💥`, type, key, `rejected:`, e);
833
- if (canCatch) {
834
- for (const Class of canCatch) if (e instanceof Class) return writeToCache(target, state, e);
835
- }
836
- throw e;
837
- }
838
- const cachedValue = writeToCache(target, state, val);
839
- return cachedValue;
840
- }
841
- case `atom`: {
842
- let def;
843
- if (isFn(state.default)) try {
844
- def = state.default();
845
- if (def instanceof Promise) def = def.catch((thrown) => {
846
- target.logger.error(`💥`, type, key, `rejected:`, thrown);
847
- if (canCatch) {
848
- for (const Class of canCatch) if (thrown instanceof Class) return thrown;
849
- }
850
- throw thrown;
851
- });
852
- } catch (e) {
853
- target.logger.error(`💥`, type, key, `rejected:`, e);
854
- if (canCatch) {
855
- for (const Class of canCatch) if (e instanceof Class) {
856
- def = writeToCache(target, state, e);
857
- target.logger.info(`✨`, state.type, key, `computed default`, def);
858
- return def;
859
- }
860
- }
861
- throw e;
862
- }
863
- else {
864
- def = state.default;
865
- target.logger.info(`✨`, state.type, key, `using static default`, def);
866
- }
867
- const cachedValue = writeToCache(target, state, def);
868
- return cachedValue;
869
- }
870
- }
871
- }
872
-
873
- //#endregion
874
- //#region src/internal/get-state/read-or-compute-value.ts
875
- function readOrComputeValue(target, state, mut) {
876
- if (target.valueMap.has(state.key)) return readFromCache(target, state, mut);
877
- target.logger.info(`❔`, state.type, state.key, `value not found in cache`);
878
- const { key } = state;
879
- switch (state.type) {
880
- case `readonly_held_selector`:
881
- case `writable_held_selector`:
882
- target.logger.info(`🧮`, state.type, key, `computing value`);
883
- return state.getFrom(target);
884
- case `writable_pure_selector`:
885
- case `readonly_pure_selector`:
886
- case `atom`: return safeCompute(target, state);
887
- case `mutable_atom`: {
888
- const instance = new state.class();
889
- target.logger.info(`✨`, state.type, key, `created new instance`, instance);
890
- const cachedValue = writeToCache(target, state, instance);
891
- return cachedValue;
892
- }
893
- }
894
- }
895
-
896
- //#endregion
897
- //#region src/internal/families/get-family-of-token.ts
898
- function getFamilyOfToken(store, token) {
899
- return withdraw(store, {
900
- key: token.family.key,
901
- type: `${token.type}_family`
902
- });
903
- }
904
-
905
- //#endregion
906
- //#region src/internal/families/mint-in-store.ts
907
- const MUST_CREATE = Symbol(`MUST_CREATE`);
908
- function mintInStore(store, family, key, mustCreate) {
909
- const stringKey = stringifyJson(key);
910
- const molecule = store.molecules.get(stringKey);
911
- const cannotCreate = !molecule && store.config.lifespan === `immortal`;
912
- if (cannotCreate) {
913
- store.logger.warn(`💣`, `key`, stringKey, `was used to mint a counterfeit token for`, family.type, `"${family.key}"`);
914
- return mint(family, key, COUNTERFEIT);
915
- }
916
- let token;
917
- if (mustCreate === MUST_CREATE) {
918
- store.logger.info(`👪`, family.type, family.key, `adds member`, typeof key === `string` ? `\`${key}\`` : key);
919
- token = family.create(key);
920
- if (molecule) store.moleculeData.set(stringKey, family.key);
921
- } else token = mint(family, key);
922
- return token;
464
+ //#region src/internal/reserved-keys.ts
465
+ function isReservedIntrospectionKey(value) {
466
+ return value.startsWith(`🔍 `);
923
467
  }
924
468
 
925
469
  //#endregion
@@ -933,151 +477,15 @@ const abortTransaction = (target) => {
933
477
  //#region src/internal/transaction/act-upon-store.ts
934
478
  function actUponStore(store, token, id) {
935
479
  return (...parameters) => {
936
- const tx = withdraw(store, token);
937
- return tx.run(parameters, id);
938
- };
939
- }
940
-
941
- //#endregion
942
- //#region src/internal/set-state/become.ts
943
- function become(nextVersionOfThing, originalThing) {
944
- if (isFn(nextVersionOfThing)) return nextVersionOfThing(originalThing);
945
- return nextVersionOfThing;
946
- }
947
-
948
- //#endregion
949
- //#region src/internal/set-state/set-atom.ts
950
- const setAtom = (target, atom, next) => {
951
- const oldValue = readOrComputeValue(target, atom, `mut`);
952
- let newValue = become(next, oldValue);
953
- target.logger.info(`⭐`, `atom`, atom.key, `setting value`, newValue);
954
- newValue = writeToCache(target, atom, newValue);
955
- markDone(target, atom.key);
956
- evictDownstreamFromAtom(target, atom);
957
- return {
958
- oldValue,
959
- newValue
960
- };
961
- };
962
-
963
- //#endregion
964
- //#region src/internal/set-state/reset-atom-or-selector.ts
965
- function resetAtom(target, atom) {
966
- switch (atom.type) {
967
- case `mutable_atom`: return setAtom(target, atom, new atom.class());
968
- case `atom`: {
969
- let def;
970
- if (isFn(atom.default)) def = safeCompute(target, atom);
971
- else def = atom.default;
972
- return setAtom(target, atom, def);
973
- }
974
- }
975
- }
976
- function resetAtomOrSelector(target, state) {
977
- let protoUpdate;
978
- switch (state.type) {
979
- case `atom`:
980
- case `mutable_atom`:
981
- protoUpdate = resetAtom(target, state);
982
- break;
983
- case `writable_held_selector`:
984
- {
985
- const atoms = traceRootSelectorAtoms(target, state.key);
986
- for (const atom of atoms.values()) {
987
- const rootProtoUpdate = resetAtom(target, atom);
988
- dispatchOrDeferStateUpdate(target, state, rootProtoUpdate, false);
989
- }
990
- const value = state.getFrom(target);
991
- protoUpdate = {
992
- oldValue: value,
993
- newValue: value
994
- };
995
- }
996
- break;
997
- case `writable_pure_selector`:
998
- {
999
- const oldValue = safeCompute(target, state);
1000
- const atoms = traceRootSelectorAtoms(target, state.key);
1001
- for (const atom of atoms.values()) {
1002
- const rootProtoUpdate = resetAtom(target, atom);
1003
- dispatchOrDeferStateUpdate(target, state, rootProtoUpdate, false);
1004
- }
1005
- const newValue = safeCompute(target, state);
1006
- protoUpdate = {
1007
- oldValue,
1008
- newValue
1009
- };
1010
- }
1011
- break;
1012
- }
1013
- return protoUpdate;
1014
- }
1015
-
1016
- //#endregion
1017
- //#region src/internal/set-state/set-into-store.ts
1018
- function setIntoStore(store, ...params) {
1019
- operateOnStore(store, OWN_OP, ...params);
1020
- }
1021
-
1022
- //#endregion
1023
- //#region src/internal/set-state/reset-in-store.ts
1024
- const RESET_STATE = Symbol(`RESET`);
1025
- function resetInStore(store, ...params) {
1026
- const subParams = [...params, RESET_STATE];
1027
- setIntoStore(store, ...subParams);
1028
- }
1029
-
1030
- //#endregion
1031
- //#region src/internal/set-state/set-selector.ts
1032
- function setSelector(target, selector, next) {
1033
- let oldValue;
1034
- let newValue;
1035
- let constant;
1036
- const { type, key } = selector;
1037
- switch (selector.type) {
1038
- case `writable_pure_selector`:
1039
- oldValue = readOrComputeValue(target, selector, `mut`);
1040
- newValue = become(next, oldValue);
1041
- newValue = writeToCache(target, selector, newValue);
1042
- break;
1043
- case `writable_held_selector`:
1044
- constant = selector.const;
1045
- become(next, constant);
1046
- oldValue = constant;
1047
- newValue = constant;
1048
- }
1049
- target.logger.info(`⭐`, type, key, `setting to`, newValue);
1050
- markDone(target, key);
1051
- selector.setSelf(newValue);
1052
- return {
1053
- oldValue,
1054
- newValue
480
+ return withdraw(store, token).run(parameters, id);
1055
481
  };
1056
482
  }
1057
483
 
1058
- //#endregion
1059
- //#region src/internal/set-state/set-atom-or-selector.ts
1060
- const setAtomOrSelector = (target, state, value) => {
1061
- let protoUpdate;
1062
- switch (state.type) {
1063
- case `atom`:
1064
- case `mutable_atom`:
1065
- protoUpdate = setAtom(target, state, value);
1066
- break;
1067
- case `writable_pure_selector`:
1068
- case `writable_held_selector`:
1069
- protoUpdate = setSelector(target, state, value);
1070
- break;
1071
- }
1072
- return protoUpdate;
1073
- };
1074
-
1075
484
  //#endregion
1076
485
  //#region src/internal/events/ingest-atom-update.ts
1077
486
  function ingestAtomUpdateEvent(store, event, applying) {
1078
487
  const { token, update: { newValue, oldValue } } = event;
1079
- const value = applying === `newValue` ? newValue : oldValue;
1080
- setIntoStore(store, token, value);
488
+ setIntoStore(store, token, applying === `newValue` ? newValue : oldValue);
1081
489
  }
1082
490
 
1083
491
  //#endregion
@@ -1090,7 +498,7 @@ function getTrace(error) {
1090
498
 
1091
499
  //#endregion
1092
500
  //#region src/internal/molecule.ts
1093
- function makeRootMoleculeInStore(key, store = IMPLICIT.STORE) {
501
+ function makeRootMoleculeInStore(store, key) {
1094
502
  const molecule = {
1095
503
  key,
1096
504
  stringKey: stringifyJson(key),
@@ -1106,14 +514,12 @@ function allocateIntoStore(store, provenance, key, dependsOn = `any`) {
1106
514
  const target = newest(store);
1107
515
  if (Array.isArray(origin)) for (const formerClaim of origin) {
1108
516
  const claimString = stringifyJson(formerClaim);
1109
- const claim = target.molecules.get(claimString);
1110
- if (claim) store.moleculeGraph.set(claimString, stringKey, { source: claimString });
517
+ if (target.molecules.get(claimString)) store.moleculeGraph.set(claimString, stringKey, { source: claimString });
1111
518
  else invalidKeys.push(claimString);
1112
519
  }
1113
520
  else {
1114
521
  const claimString = stringifyJson(origin);
1115
- const claim = target.molecules.get(claimString);
1116
- if (claim) store.moleculeGraph.set(claimString, stringKey, { source: claimString });
522
+ if (target.molecules.get(claimString)) store.moleculeGraph.set(claimString, stringKey, { source: claimString });
1117
523
  else invalidKeys.push(claimString);
1118
524
  }
1119
525
  if (invalidKeys.length === 0) target.molecules.set(stringKey, {
@@ -1127,8 +533,7 @@ function allocateIntoStore(store, provenance, key, dependsOn = `any`) {
1127
533
  provenance: origin,
1128
534
  timestamp: Date.now()
1129
535
  };
1130
- const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
1131
- if (isTransaction) target.transactionMeta.update.subEvents.push(creationEvent);
536
+ if (isChildStore(target) && target.transactionMeta.phase === `building`) target.transactionMeta.update.subEvents.push(creationEvent);
1132
537
  else target.on.moleculeCreation.next(creationEvent);
1133
538
  for (const claim of invalidKeys) {
1134
539
  const disposal = store.disposalTraces.buffer.find((item) => item?.key === claim);
@@ -1138,8 +543,7 @@ function allocateIntoStore(store, provenance, key, dependsOn = `any`) {
1138
543
  }
1139
544
  function fuseWithinStore(store, type, sideA, sideB) {
1140
545
  const compoundKey = `T$--${type}==${sideA}++${sideB}`;
1141
- const above = [sideA, sideB];
1142
- allocateIntoStore(store, above, compoundKey, `all`);
546
+ allocateIntoStore(store, [sideA, sideB], compoundKey, `all`);
1143
547
  return compoundKey;
1144
548
  }
1145
549
  function createDeallocateTX(store) {
@@ -1237,8 +641,7 @@ function claimWithinStore(store, newProvenance, claim, exclusive) {
1237
641
  to: [newProvenanceMolecule.key],
1238
642
  timestamp: Date.now()
1239
643
  };
1240
- const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
1241
- if (isTransaction) target.transactionMeta.update.subEvents.push(transferEvent);
644
+ if (isChildStore(target) && target.transactionMeta.phase === `building`) target.transactionMeta.update.subEvents.push(transferEvent);
1242
645
  return claim;
1243
646
  }
1244
647
 
@@ -1360,16 +763,14 @@ function ingestTransactionOutcomeEvent(store, event, applying) {
1360
763
  //#endregion
1361
764
  //#region src/internal/transaction/get-epoch-number.ts
1362
765
  function getContinuityKey(store, transactionKey) {
1363
- const continuity = store.transactionMeta.actionContinuities.getRelatedKey(transactionKey);
1364
- return continuity;
766
+ return store.transactionMeta.actionContinuities.getRelatedKey(transactionKey);
1365
767
  }
1366
768
  function getEpochNumberOfContinuity(store, continuityKey) {
1367
- const epoch = store.transactionMeta.epoch.get(continuityKey);
1368
- return epoch;
769
+ return store.transactionMeta.epoch.get(continuityKey);
1369
770
  }
1370
771
  function getEpochNumberOfAction(store, transactionKey) {
1371
772
  const continuityKey = getContinuityKey(store, transactionKey);
1372
- if (continuityKey === void 0) return void 0;
773
+ if (continuityKey === void 0) return;
1373
774
  return getEpochNumberOfContinuity(store, continuityKey);
1374
775
  }
1375
776
 
@@ -1397,11 +798,10 @@ function applyTransaction(store, output) {
1397
798
  ingestTransactionOutcomeEvent(parent, child.transactionMeta.update, `newValue`);
1398
799
  if (isRootStore(parent)) {
1399
800
  setEpochNumberOfAction(parent, child.transactionMeta.update.token.key, child.transactionMeta.update.epoch);
1400
- const myTransaction = withdraw(store, {
801
+ withdraw(store, {
1401
802
  key: child.transactionMeta.update.token.key,
1402
803
  type: `transaction`
1403
- });
1404
- myTransaction?.subject.next(child.transactionMeta.update);
804
+ })?.subject.next(child.transactionMeta.update);
1405
805
  store.logger.info(`🛬`, `transaction`, child.transactionMeta.update.token.key, `applied`);
1406
806
  } else if (isChildStore(parent)) parent.transactionMeta.update.subEvents.push(child.transactionMeta.update);
1407
807
  parent.on.transactionApplying.next(null);
@@ -1500,14 +900,14 @@ function createTransaction(store, options) {
1500
900
  type: `transaction`,
1501
901
  run: (params, id) => {
1502
902
  const token$1 = deposit(newTransaction);
1503
- const target$1 = buildTransaction(store, token$1, params, id);
903
+ const target = buildTransaction(store, token$1, params, id);
1504
904
  try {
1505
- const { toolkit } = target$1.transactionMeta;
905
+ const { toolkit } = target.transactionMeta;
1506
906
  const output = options.do(toolkit, ...params);
1507
- applyTransaction(target$1, output);
907
+ applyTransaction(target, output);
1508
908
  return output;
1509
909
  } catch (thrown) {
1510
- abortTransaction(target$1);
910
+ abortTransaction(target);
1511
911
  store.logger.warn(`💥`, `transaction`, key, `caught:`, thrown);
1512
912
  throw thrown;
1513
913
  }
@@ -1515,15 +915,14 @@ function createTransaction(store, options) {
1515
915
  install: (s) => createTransaction(s, options),
1516
916
  subject: new Subject()
1517
917
  };
1518
- const target = newest(store);
1519
- target.transactions.set(key, newTransaction);
918
+ newest(store).transactions.set(key, newTransaction);
1520
919
  const token = deposit(newTransaction);
1521
920
  if (!transactionAlreadyExists) store.on.transactionCreation.next(token);
1522
921
  return token;
1523
922
  }
1524
923
 
1525
924
  //#endregion
1526
- //#region src/internal/transaction/index.ts
925
+ //#region src/internal/transaction/transaction-meta-progress.ts
1527
926
  const TRANSACTION_PHASES = [
1528
927
  `idle`,
1529
928
  `building`,
@@ -1531,512 +930,141 @@ const TRANSACTION_PHASES = [
1531
930
  ];
1532
931
 
1533
932
  //#endregion
1534
- //#region src/internal/set-state/dispatch-state-update.ts
1535
- function dispatchOrDeferStateUpdate(target, state, { oldValue, newValue }, stateIsNewlyCreated, family) {
1536
- const token = deposit(state);
1537
- if (stateIsNewlyCreated && family) {
1538
- state.subject.next({ newValue });
1539
- const stateCreationEvent = {
1540
- checkpoint: true,
1541
- type: `state_creation`,
1542
- subType: `writable`,
1543
- token,
1544
- timestamp: Date.now(),
1545
- value: newValue
1546
- };
1547
- target.operation.subEvents.push(stateCreationEvent);
1548
- const familySubject = family.subject;
1549
- familySubject.next(stateCreationEvent);
1550
- const innerTarget = newest(target);
1551
- if (token.family) {
1552
- if (isRootStore(innerTarget)) switch (token.type) {
1553
- case `atom`:
1554
- case `mutable_atom`:
1555
- target.on.atomCreation.next(token);
1556
- break;
1557
- case `writable_pure_selector`:
1558
- case `writable_held_selector`:
1559
- target.on.selectorCreation.next(token);
1560
- break;
1561
- }
1562
- else if (isChildStore(innerTarget) && innerTarget.on.transactionApplying.state === null) innerTarget.transactionMeta.update.subEvents.push(stateCreationEvent);
1563
- }
1564
- return;
1565
- }
1566
- const { key, subject, type } = state;
1567
- const update = {
1568
- oldValue: isTransceiver(oldValue) ? oldValue.READONLY_VIEW : oldValue,
1569
- newValue: isTransceiver(newValue) ? newValue.READONLY_VIEW : newValue
933
+ //#region src/internal/store/store.ts
934
+ var Store = class {
935
+ parent = null;
936
+ child = null;
937
+ valueMap = /* @__PURE__ */ new Map();
938
+ defaults = /* @__PURE__ */ new Map();
939
+ atoms = /* @__PURE__ */ new Map();
940
+ writableSelectors = /* @__PURE__ */ new Map();
941
+ readonlySelectors = /* @__PURE__ */ new Map();
942
+ atomsThatAreDefault = /* @__PURE__ */ new Set();
943
+ selectorAtoms = new Junction({
944
+ between: [`selectorKey`, `atomKey`],
945
+ cardinality: `n:n`
946
+ });
947
+ selectorGraph = new Junction({
948
+ between: [`upstreamSelectorKey`, `downstreamSelectorKey`],
949
+ cardinality: `n:n`
950
+ }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
951
+ trackers = /* @__PURE__ */ new Map();
952
+ families = /* @__PURE__ */ new Map();
953
+ joins = /* @__PURE__ */ new Map();
954
+ transactions = /* @__PURE__ */ new Map();
955
+ transactionMeta = {
956
+ epoch: /* @__PURE__ */ new Map(),
957
+ actionContinuities: new Junction({
958
+ between: [`continuity`, `action`],
959
+ cardinality: `1:n`
960
+ })
1570
961
  };
1571
- if (isRootStore(target)) {
1572
- switch (type) {
1573
- case `mutable_atom`:
1574
- target.logger.info(`📢`, type, key, `is now (`, newValue, `) subscribers:`, subject.subscribers.keys());
1575
- break;
1576
- case `atom`:
1577
- case `writable_pure_selector`:
1578
- case `writable_held_selector`: target.logger.info(`📢`, type, key, `went (`, oldValue, `->`, newValue, `) subscribers:`, subject.subscribers.keys());
1579
- }
1580
- subject.next(update);
1581
- }
1582
- if (isChildStore(target) && (type === `mutable_atom` || type === `atom`)) {
1583
- if (target.on.transactionApplying.state === null) {
1584
- if (isTransceiver(newValue)) return;
1585
- const { timestamp } = target.operation;
1586
- const atomUpdate = {
1587
- type: `atom_update`,
1588
- token,
1589
- timestamp,
1590
- update
1591
- };
1592
- target.transactionMeta.update.subEvents.push(atomUpdate);
1593
- target.logger.info(`📁`, `atom`, key, `stowed (`, oldValue, `->`, newValue, `)`);
1594
- return;
1595
- }
1596
- if (hasRole(state, `tracker:signal`)) {
1597
- const keyOfMutable = key.slice(1);
1598
- const mutable = target.atoms.get(keyOfMutable);
1599
- const transceiver = readOrComputeValue(target, mutable, `mut`);
1600
- const accepted = transceiver.do(update.newValue) === null;
1601
- if (accepted === true) evictDownstreamFromAtom(target, mutable);
1602
- }
1603
- }
1604
- }
1605
-
1606
- //#endregion
1607
- //#region src/internal/set-state/operate-on-store.ts
1608
- const OWN_OP = Symbol(`OWN_OP`);
1609
- const JOIN_OP = Symbol(`JOIN_OP`);
1610
- function operateOnStore(store, opMode, ...params) {
1611
- let existingToken;
1612
- let brandNewToken;
1613
- let token;
1614
- let family;
1615
- let key;
1616
- let value;
1617
- if (params.length === 2) {
1618
- token = params[0];
1619
- value = params[1];
1620
- if (`family` in token) {
1621
- family = getFamilyOfToken(store, token);
1622
- key = parseJson(token.family.subKey);
1623
- existingToken = seekInStore(store, family, key);
1624
- if (!existingToken) token = brandNewToken = mintInStore(store, family, key, MUST_CREATE);
1625
- else token = existingToken;
1626
- }
1627
- } else {
1628
- family = withdraw(store, params[0]);
1629
- key = params[1];
1630
- value = params[2];
1631
- existingToken = seekInStore(store, family, key);
1632
- if (!existingToken) token = brandNewToken = mintInStore(store, family, key, MUST_CREATE);
1633
- else token = existingToken;
1634
- }
1635
- const action = value === RESET_STATE ? `reset` : `set`;
1636
- let target;
1637
- if (opMode === OWN_OP) {
1638
- const result = openOperation(store, token);
1639
- const rejected = typeof result === `number`;
1640
- if (rejected) {
1641
- const rejectionTime = result;
1642
- const unsubscribe = store.on.operationClose.subscribe(`waiting to ${action} "${token.key}" at T-${rejectionTime}`, function waitUntilOperationCloseToSetState() {
1643
- unsubscribe();
1644
- store.logger.info(`🟢`, token.type, token.key, `resuming deferred`, action, `from T-${rejectionTime}`);
1645
- operateOnStore(store, opMode, token, value);
1646
- });
1647
- return;
1648
- }
1649
- target = result;
1650
- } else target = store;
1651
- if (`counterfeit` in token && `family` in token) {
1652
- const subKey = token.family.subKey;
1653
- const disposal = store.disposalTraces.buffer.find((item) => item?.key === subKey);
1654
- 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)`);
1655
- return;
1656
- }
1657
- const state = withdraw(target, token);
1658
- let protoUpdate;
1659
- if (value === RESET_STATE) protoUpdate = resetAtomOrSelector(target, state);
1660
- else protoUpdate = setAtomOrSelector(target, state, value);
1661
- const isNewlyCreated = Boolean(brandNewToken);
1662
- dispatchOrDeferStateUpdate(target, state, protoUpdate, isNewlyCreated, family);
1663
- if (opMode === OWN_OP) closeOperation(target);
1664
- }
1665
-
1666
- //#endregion
1667
- //#region src/internal/keys.ts
1668
- const isAtomKey = (store, key) => newest(store).atoms.has(key);
1669
- const isSelectorKey = (store, key) => newest(store).writableSelectors.has(key);
1670
- const isReadonlySelectorKey = (store, key) => newest(store).readonlySelectors.has(key);
1671
- const isStateKey = (store, key) => isAtomKey(store, key) || isSelectorKey(store, key) || isReadonlySelectorKey(store, key);
1672
-
1673
- //#endregion
1674
- //#region src/internal/selector/get-selector-dependency-keys.ts
1675
- function getSelectorDependencyKeys(store, key) {
1676
- const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(store, source));
1677
- return sources;
1678
- }
1679
-
1680
- //#endregion
1681
- //#region src/internal/selector/trace-selector-atoms.ts
1682
- function traceRootSelectorAtoms(store, selectorKey, covered = /* @__PURE__ */ new Set()) {
1683
- const dependencies = getSelectorDependencyKeys(store, selectorKey);
1684
- const roots = /* @__PURE__ */ new Map();
1685
- while (dependencies.length > 0) {
1686
- const dependencyKey = dependencies.pop();
1687
- if (covered.has(dependencyKey)) continue;
1688
- covered.add(dependencyKey);
1689
- if (isAtomKey(store, dependencyKey)) {
1690
- const atom = store.atoms.get(dependencyKey);
1691
- roots.set(atom.key, atom);
1692
- } else dependencies.push(...getSelectorDependencyKeys(store, dependencyKey));
1693
- }
1694
- return roots;
1695
- }
1696
-
1697
- //#endregion
1698
- //#region src/internal/selector/update-selector-atoms.ts
1699
- function updateSelectorAtoms(store, selectorType, selectorKey, dependency, covered) {
1700
- const target = newest(store);
1701
- const { type: dependencyType, key: dependencyKey } = dependency;
1702
- if (dependencyType === `atom` || dependencyType === `mutable_atom`) {
1703
- target.selectorAtoms.set({
1704
- selectorKey,
1705
- atomKey: dependencyKey
1706
- });
1707
- store.logger.info(`🔍`, selectorType, selectorKey, `discovers root atom "${dependencyKey}"`);
1708
- } else {
1709
- const rootKeys = traceRootSelectorAtoms(store, dependencyKey, covered);
1710
- store.logger.info(`🔍`, selectorType, selectorKey, `discovers root atoms: [ ${[...rootKeys.values()].map((root) => `"${root.key}"`).join(`, `)} ]`);
1711
- for (const { key: atomKey } of rootKeys.values()) target.selectorAtoms = target.selectorAtoms.set({
1712
- selectorKey,
1713
- atomKey
1714
- });
1715
- }
1716
- covered.add(dependencyKey);
1717
- }
1718
-
1719
- //#endregion
1720
- //#region src/internal/selector/register-selector.ts
1721
- function registerSelector(store, selectorType, selectorKey, covered) {
1722
- return {
1723
- get: (...params) => {
1724
- const target = newest(store);
1725
- const { token, family, subKey } = reduceReference(store, ...params);
1726
- let dependencyValue;
1727
- if (`counterfeit` in token && family && subKey) dependencyValue = getFallback(store, token, family, subKey);
1728
- else {
1729
- const dependency = withdraw(store, token);
1730
- dependencyValue = readOrComputeValue(store, dependency);
1731
- }
1732
- store.logger.info(`🔌`, selectorType, selectorKey, `registers dependency ( "${token.key}" =`, dependencyValue, `)`);
1733
- target.selectorGraph.set({
1734
- upstreamSelectorKey: token.key,
1735
- downstreamSelectorKey: selectorKey
1736
- }, { source: token.key });
1737
- updateSelectorAtoms(store, selectorType, selectorKey, token, covered);
1738
- return dependencyValue;
1739
- },
1740
- set: ((...params) => {
1741
- const target = newest(store);
1742
- operateOnStore(target, JOIN_OP, ...params);
1743
- }),
1744
- find: ((...args) => findInStore(store, ...args)),
1745
- json: (token) => getJsonToken(store, token)
1746
- };
1747
- }
1748
-
1749
- //#endregion
1750
- //#region src/internal/selector/create-readonly-held-selector.ts
1751
- function createReadonlyHeldSelector(store, options, family) {
1752
- const target = newest(store);
1753
- const subject = new Subject();
1754
- const covered = /* @__PURE__ */ new Set();
1755
- const { key, const: constant } = options;
1756
- const type = `readonly_held_selector`;
1757
- store.logger.info(`🔨`, type, key, `is being created`);
1758
- const { get, find, json } = registerSelector(target, type, key, covered);
1759
- const getFrom = (innerTarget) => {
1760
- const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
1761
- for (const [downstreamSelectorKey, { source }] of upstreamStates) if (source !== key) innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
1762
- innerTarget.selectorAtoms.delete(key);
1763
- options.get({
1764
- get,
1765
- find,
1766
- json
1767
- }, constant);
1768
- writeToCache(innerTarget, readonlySelector, constant);
1769
- store.logger.info(`✨`, type, key, `=`, constant);
1770
- covered.clear();
1771
- return constant;
1772
- };
1773
- const readonlySelector = {
1774
- ...options,
1775
- type,
1776
- subject,
1777
- getFrom,
1778
- install: (s) => createReadonlyHeldSelector(s, options, family)
1779
- };
1780
- if (family) readonlySelector.family = family;
1781
- target.readonlySelectors.set(key, readonlySelector);
1782
- const token = {
1783
- key,
1784
- type
1785
- };
1786
- if (family) token.family = family;
1787
- return token;
1788
- }
1789
-
1790
- //#endregion
1791
- //#region src/internal/selector/create-readonly-pure-selector.ts
1792
- function createReadonlyPureSelector(store, options, family) {
1793
- const target = newest(store);
1794
- const subject = new Subject();
1795
- const covered = /* @__PURE__ */ new Set();
1796
- const key = options.key;
1797
- const type = `readonly_pure_selector`;
1798
- store.logger.info(`🔨`, type, key, `is being created`);
1799
- const { get, find, json } = registerSelector(target, type, key, covered);
1800
- const getFrom = () => {
1801
- const innerTarget = newest(store);
1802
- const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
1803
- for (const [downstreamSelectorKey, { source }] of upstreamStates) if (source !== key) innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
1804
- innerTarget.selectorAtoms.delete(key);
1805
- const value = options.get({
1806
- get,
1807
- find,
1808
- json
1809
- });
1810
- const cached = writeToCache(innerTarget, readonlySelector, value);
1811
- store.logger.info(`✨`, type, key, `=`, cached);
1812
- covered.clear();
1813
- return cached;
1814
- };
1815
- const readonlySelector = {
1816
- ...options,
1817
- type,
1818
- subject,
1819
- getFrom,
1820
- install: (s) => createReadonlyPureSelector(s, options, family)
1821
- };
1822
- if (family) readonlySelector.family = family;
1823
- target.readonlySelectors.set(key, readonlySelector);
1824
- const token = {
1825
- key,
1826
- type
1827
- };
1828
- if (family) token.family = family;
1829
- return token;
1830
- }
1831
-
1832
- //#endregion
1833
- //#region src/internal/selector/create-writable-held-selector.ts
1834
- function createWritableHeldSelector(store, options, family) {
1835
- const target = newest(store);
1836
- const subject = new Subject();
1837
- const covered = /* @__PURE__ */ new Set();
1838
- const { key, const: constant } = options;
1839
- const type = `writable_held_selector`;
1840
- store.logger.info(`🔨`, type, key, `is being created`);
1841
- const setterToolkit = registerSelector(target, type, key, covered);
1842
- const { find, get, json } = setterToolkit;
1843
- const getterToolkit = {
1844
- find,
1845
- get,
1846
- json
1847
- };
1848
- const getFrom = (innerTarget) => {
1849
- const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
1850
- for (const [downstreamSelectorKey, { source }] of upstreamStates) if (source !== key) innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
1851
- innerTarget.selectorAtoms.delete(key);
1852
- options.get(getterToolkit, constant);
1853
- writeToCache(innerTarget, mySelector, constant);
1854
- store.logger.info(`✨`, type, key, `=`, constant);
1855
- covered.clear();
1856
- return constant;
1857
- };
1858
- const setSelf = () => {
1859
- options.set(setterToolkit, constant);
1860
- };
1861
- const mySelector = {
1862
- ...options,
1863
- type,
1864
- subject,
1865
- getFrom,
1866
- setSelf,
1867
- install: (s) => createWritableHeldSelector(s, options, family)
1868
- };
1869
- if (family) mySelector.family = family;
1870
- target.writableSelectors.set(key, mySelector);
1871
- const token = {
1872
- key,
1873
- type
1874
- };
1875
- if (family) token.family = family;
1876
- return token;
1877
- }
1878
-
1879
- //#endregion
1880
- //#region src/internal/selector/create-writable-pure-selector.ts
1881
- function createWritablePureSelector(store, options, family) {
1882
- const target = newest(store);
1883
- const subject = new Subject();
1884
- const covered = /* @__PURE__ */ new Set();
1885
- const key = options.key;
1886
- const type = `writable_pure_selector`;
1887
- store.logger.info(`🔨`, type, key, `is being created`);
1888
- const setterToolkit = registerSelector(target, type, key, covered);
1889
- const { find, get, json } = setterToolkit;
1890
- const getterToolkit = {
1891
- find,
1892
- get,
1893
- json
1894
- };
1895
- const getFrom = (innerTarget) => {
1896
- const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
1897
- for (const [downstreamSelectorKey, { source }] of upstreamStates) if (source !== key) innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
1898
- innerTarget.selectorAtoms.delete(key);
1899
- const value = options.get(getterToolkit);
1900
- const cached = writeToCache(innerTarget, mySelector, value);
1901
- store.logger.info(`✨`, type, key, `=`, cached);
1902
- covered.clear();
1903
- return cached;
1904
- };
1905
- const setSelf = (newValue) => {
1906
- options.set(setterToolkit, newValue);
962
+ timelines = /* @__PURE__ */ new Map();
963
+ timelineTopics = new Junction({
964
+ between: [`timelineKey`, `topicKey`],
965
+ cardinality: `1:n`
966
+ });
967
+ disposalTraces = new CircularBuffer(100);
968
+ molecules = /* @__PURE__ */ new Map();
969
+ moleculeJoins = new Junction({
970
+ between: [`moleculeKey`, `joinKey`],
971
+ cardinality: `n:n`
972
+ }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
973
+ moleculeGraph = new Junction({
974
+ between: [`upstreamMoleculeKey`, `downstreamMoleculeKey`],
975
+ cardinality: `n:n`
976
+ }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
977
+ moleculeData = new Junction({
978
+ between: [`moleculeKey`, `stateFamilyKey`],
979
+ cardinality: `n:n`
980
+ }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
981
+ miscResources = /* @__PURE__ */ new Map();
982
+ on = {
983
+ atomCreation: new Subject(),
984
+ atomDisposal: new Subject(),
985
+ selectorCreation: new Subject(),
986
+ selectorDisposal: new Subject(),
987
+ timelineCreation: new Subject(),
988
+ transactionCreation: new Subject(),
989
+ transactionApplying: new StatefulSubject(null),
990
+ operationClose: new Subject(),
991
+ moleculeCreation: new Subject(),
992
+ moleculeDisposal: new Subject()
1907
993
  };
1908
- const mySelector = {
1909
- ...options,
1910
- type,
1911
- subject,
1912
- getFrom,
1913
- setSelf,
1914
- install: (s) => createWritablePureSelector(s, options, family)
994
+ operation = { open: false };
995
+ config = {
996
+ name: `IMPLICIT_STORE`,
997
+ lifespan: `ephemeral`
1915
998
  };
1916
- if (family) mySelector.family = family;
1917
- target.writableSelectors.set(key, mySelector);
1918
- const token = {
1919
- key,
1920
- type
999
+ loggers = [new AtomIOLogger(`warn`, (_, __, key) => !isReservedIntrospectionKey(key))];
1000
+ logger = {
1001
+ error: (...messages) => {
1002
+ for (const logger of this.loggers) logger.error(...messages);
1003
+ },
1004
+ info: (...messages) => {
1005
+ for (const logger of this.loggers) logger.info(...messages);
1006
+ },
1007
+ warn: (...messages) => {
1008
+ for (const logger of this.loggers) logger.warn(...messages);
1009
+ }
1921
1010
  };
1922
- if (family) token.family = family;
1923
- return token;
1924
- }
1925
-
1926
- //#endregion
1927
- //#region src/internal/selector/create-standalone-selector.ts
1928
- function createStandaloneSelector(store, options) {
1929
- const isWritable = `set` in options;
1930
- const isHeld = `const` in options;
1931
- if (isHeld && isWritable) {
1932
- const state$1 = createWritableHeldSelector(store, options, void 0);
1933
- store.on.selectorCreation.next(state$1);
1934
- return state$1;
1935
- }
1936
- if (isHeld) {
1937
- const state$1 = createReadonlyHeldSelector(store, options, void 0);
1938
- store.on.selectorCreation.next(state$1);
1939
- return state$1;
1940
- }
1941
- if (isWritable) {
1942
- const state$1 = createWritablePureSelector(store, options, void 0);
1943
- store.on.selectorCreation.next(state$1);
1944
- return state$1;
1945
- }
1946
- const state = createReadonlyPureSelector(store, options, void 0);
1947
- store.on.selectorCreation.next(state);
1948
- return state;
1949
- }
1950
-
1951
- //#endregion
1952
- //#region src/internal/selector/dispose-selector.ts
1953
- function disposeSelector(store, selectorToken) {
1954
- const target = newest(store);
1955
- const { key, type, family: familyMeta } = selectorToken;
1956
- if (!familyMeta) store.logger.error(`❌`, type, key, `Standalone selectors cannot be disposed.`);
1957
- else {
1958
- const molecule = target.molecules.get(familyMeta.subKey);
1959
- if (molecule) target.moleculeData.delete(familyMeta.subKey, familyMeta.key);
1960
- let familyToken;
1961
- switch (selectorToken.type) {
1962
- case `writable_held_selector`:
1963
- {
1964
- target.writableSelectors.delete(key);
1965
- familyToken = {
1966
- key: familyMeta.key,
1967
- type: `writable_held_selector_family`
1968
- };
1969
- const family = withdraw(store, familyToken);
1970
- family.subject.next({
1971
- type: `state_disposal`,
1972
- subType: `selector`,
1973
- token: selectorToken,
1974
- timestamp: Date.now()
1975
- });
1976
- }
1977
- break;
1978
- case `writable_pure_selector`:
1979
- {
1980
- target.writableSelectors.delete(key);
1981
- familyToken = {
1982
- key: familyMeta.key,
1983
- type: `writable_pure_selector_family`
1984
- };
1985
- const family = withdraw(store, familyToken);
1986
- family.subject.next({
1987
- type: `state_disposal`,
1988
- subType: `selector`,
1989
- token: selectorToken,
1990
- timestamp: Date.now()
1991
- });
1992
- }
1993
- break;
1994
- case `readonly_held_selector`:
1995
- {
1996
- target.readonlySelectors.delete(key);
1997
- familyToken = {
1998
- key: familyMeta.key,
1999
- type: `readonly_held_selector_family`
2000
- };
2001
- const family = withdraw(store, familyToken);
2002
- family.subject.next({
2003
- type: `state_disposal`,
2004
- subType: `selector`,
2005
- token: selectorToken,
2006
- timestamp: Date.now()
2007
- });
2008
- }
2009
- break;
2010
- case `readonly_pure_selector`:
2011
- {
2012
- target.readonlySelectors.delete(key);
2013
- familyToken = {
2014
- key: familyMeta.key,
2015
- type: `readonly_pure_selector_family`
2016
- };
2017
- const family = withdraw(store, familyToken);
2018
- family.subject.next({
2019
- type: `state_disposal`,
2020
- subType: `selector`,
2021
- token: selectorToken,
2022
- timestamp: Date.now()
2023
- });
1011
+ constructor(config, store = null) {
1012
+ this.config = {
1013
+ ...store?.config,
1014
+ ...config
1015
+ };
1016
+ if (store !== null) {
1017
+ this.operation = { ...store?.operation };
1018
+ if (isRootStore(store)) this.transactionMeta = {
1019
+ epoch: new Map(store?.transactionMeta.epoch),
1020
+ actionContinuities: new Junction(store?.transactionMeta.actionContinuities.toJSON())
1021
+ };
1022
+ for (const [, family] of store.families) {
1023
+ if (family.internalRoles?.includes(`mutable`) || family.internalRoles?.includes(`join`)) continue;
1024
+ family.install(this);
1025
+ }
1026
+ const mutableHelpers = /* @__PURE__ */ new Set();
1027
+ for (const [, atom] of store.atoms) {
1028
+ if (mutableHelpers.has(atom.key)) continue;
1029
+ atom.install(this);
1030
+ if (atom.type === `mutable_atom`) {
1031
+ const originalJsonToken = getJsonToken(store, atom);
1032
+ const originalUpdateToken = getUpdateToken(atom);
1033
+ mutableHelpers.add(originalJsonToken.key);
1034
+ mutableHelpers.add(originalUpdateToken.key);
2024
1035
  }
2025
- break;
1036
+ }
1037
+ for (const [, selector] of store.readonlySelectors) selector.install(this);
1038
+ for (const [, selector] of store.writableSelectors) {
1039
+ if (mutableHelpers.has(selector.key)) continue;
1040
+ selector.install(this);
1041
+ }
1042
+ for (const [, tx] of store.transactions) tx.install(this);
1043
+ for (const [, timeline] of store.timelines) timeline.install(this);
2026
1044
  }
2027
- target.valueMap.delete(key);
2028
- target.selectorAtoms.delete(key);
2029
- target.selectorGraph.delete(key);
2030
- target.moleculeData.delete(familyMeta.key, familyMeta.subKey);
2031
- store.logger.info(`🔥`, selectorToken.type, key, `deleted`);
2032
- if (isChildStore(target) && target.transactionMeta.phase === `building`) target.transactionMeta.update.subEvents.push({
2033
- type: `state_disposal`,
2034
- subType: `selector`,
2035
- token: selectorToken,
2036
- timestamp: Date.now()
2037
- });
2038
- else store.on.selectorDisposal.next(selectorToken);
2039
1045
  }
1046
+ };
1047
+ const IMPLICIT = { get STORE() {
1048
+ globalThis.ATOM_IO_IMPLICIT_STORE ??= new Store({
1049
+ name: `IMPLICIT_STORE`,
1050
+ lifespan: `ephemeral`
1051
+ });
1052
+ return globalThis.ATOM_IO_IMPLICIT_STORE;
1053
+ } };
1054
+ const clearStore = (store) => {
1055
+ const { config } = store;
1056
+ for (const disposable of store.miscResources.values()) disposable[Symbol.dispose]();
1057
+ Object.assign(store, new Store(config));
1058
+ store.config = config;
1059
+ };
1060
+
1061
+ //#endregion
1062
+ //#region src/internal/families/find-in-store.ts
1063
+ function findInStore(store, familyToken, key) {
1064
+ const family = withdraw(store, familyToken);
1065
+ const existingStateToken = seekInStore(store, familyToken, key);
1066
+ if (existingStateToken) return existingStateToken;
1067
+ return mintInStore(DO_NOT_CREATE, store, family, key);
2040
1068
  }
2041
1069
 
2042
1070
  //#endregion
@@ -2073,8 +1101,7 @@ function createReadonlyPureSelectorFamily(store, options, internalRoles) {
2073
1101
  subject,
2074
1102
  install: (s) => createReadonlyPureSelectorFamily(s, options),
2075
1103
  default: (key) => {
2076
- const getFn = options.get(key);
2077
- return getFn({
1104
+ return options.get(key)({
2078
1105
  get: ((...args) => getFromStore(store, ...args)),
2079
1106
  find: ((...args) => findInStore(store, ...args)),
2080
1107
  json: (token) => getJsonToken(store, token)
@@ -2190,345 +1217,437 @@ function createWritableHeldSelectorFamily(store, options, internalRoles) {
2190
1217
  set: options.set(key)
2191
1218
  }, family);
2192
1219
  };
2193
- const selectorFamily$1 = {
2194
- ...familyToken,
2195
- create,
2196
- internalRoles,
1220
+ const selectorFamily$1 = {
1221
+ ...familyToken,
1222
+ create,
1223
+ internalRoles,
1224
+ subject,
1225
+ install: (s) => createWritableHeldSelectorFamily(s, options),
1226
+ default: options.const
1227
+ };
1228
+ store.families.set(familyKey, selectorFamily$1);
1229
+ return familyToken;
1230
+ }
1231
+
1232
+ //#endregion
1233
+ //#region src/internal/families/create-writable-pure-selector-family.ts
1234
+ function createWritablePureSelectorFamily(store, options, internalRoles) {
1235
+ const familyKey = options.key;
1236
+ const type = `writable_pure_selector_family`;
1237
+ const familyToken = {
1238
+ key: familyKey,
1239
+ type
1240
+ };
1241
+ const existing = store.families.get(familyKey);
1242
+ 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.`);
1243
+ const subject = new Subject();
1244
+ const create = (key) => {
1245
+ const subKey = stringifyJson(key);
1246
+ const family = {
1247
+ key: familyKey,
1248
+ subKey
1249
+ };
1250
+ const fullKey = `${familyKey}(${subKey})`;
1251
+ const target = newest(store);
1252
+ const individualOptions = {
1253
+ key: fullKey,
1254
+ get: options.get(key),
1255
+ set: options.set(key)
1256
+ };
1257
+ if (options.catch) individualOptions.catch = options.catch;
1258
+ return createWritablePureSelector(target, individualOptions, family);
1259
+ };
1260
+ const selectorFamily$1 = {
1261
+ ...familyToken,
1262
+ create,
1263
+ internalRoles,
1264
+ subject,
1265
+ install: (s) => createWritablePureSelectorFamily(s, options),
1266
+ default: (key) => {
1267
+ return options.get(key)({
1268
+ get: ((...args) => getFromStore(store, ...args)),
1269
+ find: ((...args) => findInStore(store, ...args)),
1270
+ json: (token) => getJsonToken(store, token)
1271
+ });
1272
+ }
1273
+ };
1274
+ store.families.set(familyKey, selectorFamily$1);
1275
+ return familyToken;
1276
+ }
1277
+
1278
+ //#endregion
1279
+ //#region src/internal/families/create-selector-family.ts
1280
+ function createSelectorFamily(store, options) {
1281
+ const isWritable = `set` in options;
1282
+ const isHeld = `const` in options;
1283
+ if (isHeld && isWritable) return createWritableHeldSelectorFamily(store, options, void 0);
1284
+ if (isHeld) return createReadonlyHeldSelectorFamily(store, options, void 0);
1285
+ if (isWritable) return createWritablePureSelectorFamily(store, options);
1286
+ return createReadonlyPureSelectorFamily(store, options);
1287
+ }
1288
+
1289
+ //#endregion
1290
+ //#region src/internal/families/dispose-from-store.ts
1291
+ function disposeFromStore(store, ...params) {
1292
+ let token;
1293
+ if (params.length === 1) token = params[0];
1294
+ else {
1295
+ const family = params[0];
1296
+ const key = params[1];
1297
+ token = findInStore(store, family, key);
1298
+ }
1299
+ try {
1300
+ withdraw(store, token);
1301
+ } catch (_) {
1302
+ store.logger.error(`❌`, token.type, token.key, `could not be disposed because it was not found in the store "${store.config.name}".`);
1303
+ return;
1304
+ }
1305
+ switch (token.type) {
1306
+ case `atom`:
1307
+ case `mutable_atom`:
1308
+ disposeAtom(store, token);
1309
+ break;
1310
+ case `writable_pure_selector`:
1311
+ case `readonly_pure_selector`:
1312
+ case `writable_held_selector`:
1313
+ case `readonly_held_selector`:
1314
+ disposeSelector(store, token);
1315
+ break;
1316
+ }
1317
+ }
1318
+
1319
+ //#endregion
1320
+ //#region src/internal/selector/update-selector-atoms.ts
1321
+ function updateSelectorAtoms(store, selectorType, selectorKey, dependency, covered) {
1322
+ const target = newest(store);
1323
+ const { type: dependencyType, key: dependencyKey } = dependency;
1324
+ if (dependencyType === `atom` || dependencyType === `mutable_atom`) {
1325
+ target.selectorAtoms.set({
1326
+ selectorKey,
1327
+ atomKey: dependencyKey
1328
+ });
1329
+ store.logger.info(`🔍`, selectorType, selectorKey, `discovers root atom "${dependencyKey}"`);
1330
+ } else {
1331
+ const rootKeys = traceRootSelectorAtoms(store, dependencyKey, covered);
1332
+ store.logger.info(`🔍`, selectorType, selectorKey, `discovers root atoms: [ ${[...rootKeys.values()].map((root) => `"${root.key}"`).join(`, `)} ]`);
1333
+ for (const { key: atomKey } of rootKeys.values()) target.selectorAtoms = target.selectorAtoms.set({
1334
+ selectorKey,
1335
+ atomKey
1336
+ });
1337
+ }
1338
+ covered.add(dependencyKey);
1339
+ }
1340
+
1341
+ //#endregion
1342
+ //#region src/internal/selector/register-selector.ts
1343
+ function registerSelector(store, selectorType, selectorKey, covered) {
1344
+ return {
1345
+ get: (...params) => {
1346
+ const target = newest(store);
1347
+ const { token, family, subKey } = reduceReference(store, ...params);
1348
+ let dependencyValue;
1349
+ if (`counterfeit` in token && family && subKey) dependencyValue = getFallback(store, token, family, subKey);
1350
+ else {
1351
+ const dependency = withdraw(store, token);
1352
+ dependencyValue = readOrComputeValue(store, dependency);
1353
+ }
1354
+ store.logger.info(`🔌`, selectorType, selectorKey, `registers dependency ( "${token.key}" =`, dependencyValue, `)`);
1355
+ target.selectorGraph.set({
1356
+ upstreamSelectorKey: token.key,
1357
+ downstreamSelectorKey: selectorKey
1358
+ }, { source: token.key });
1359
+ updateSelectorAtoms(store, selectorType, selectorKey, token, covered);
1360
+ return dependencyValue;
1361
+ },
1362
+ set: ((...params) => {
1363
+ const target = newest(store);
1364
+ operateOnStore(JOIN_OP, target, ...params);
1365
+ }),
1366
+ find: ((...args) => findInStore(store, ...args)),
1367
+ json: (token) => getJsonToken(store, token)
1368
+ };
1369
+ }
1370
+
1371
+ //#endregion
1372
+ //#region src/internal/selector/create-readonly-held-selector.ts
1373
+ function createReadonlyHeldSelector(store, options, family) {
1374
+ const target = newest(store);
1375
+ const subject = new Subject();
1376
+ const covered = /* @__PURE__ */ new Set();
1377
+ const { key, const: constant } = options;
1378
+ const type = `readonly_held_selector`;
1379
+ store.logger.info(`🔨`, type, key, `is being created`);
1380
+ const { get, find, json } = registerSelector(target, type, key, covered);
1381
+ const getFrom = (innerTarget) => {
1382
+ const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
1383
+ for (const [downstreamSelectorKey, { source }] of upstreamStates) if (source !== key) innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
1384
+ innerTarget.selectorAtoms.delete(key);
1385
+ options.get({
1386
+ get,
1387
+ find,
1388
+ json
1389
+ }, constant);
1390
+ writeToCache(innerTarget, readonlySelector, constant);
1391
+ store.logger.info(`✨`, type, key, `=`, constant);
1392
+ covered.clear();
1393
+ return constant;
1394
+ };
1395
+ const readonlySelector = {
1396
+ ...options,
1397
+ type,
1398
+ subject,
1399
+ getFrom,
1400
+ install: (s) => createReadonlyHeldSelector(s, options, family)
1401
+ };
1402
+ if (family) readonlySelector.family = family;
1403
+ target.readonlySelectors.set(key, readonlySelector);
1404
+ const token = {
1405
+ key,
1406
+ type
1407
+ };
1408
+ if (family) token.family = family;
1409
+ return token;
1410
+ }
1411
+
1412
+ //#endregion
1413
+ //#region src/internal/selector/create-readonly-pure-selector.ts
1414
+ function createReadonlyPureSelector(store, options, family) {
1415
+ const target = newest(store);
1416
+ const subject = new Subject();
1417
+ const covered = /* @__PURE__ */ new Set();
1418
+ const key = options.key;
1419
+ const type = `readonly_pure_selector`;
1420
+ store.logger.info(`🔨`, type, key, `is being created`);
1421
+ const { get, find, json } = registerSelector(target, type, key, covered);
1422
+ const getFrom = () => {
1423
+ const innerTarget = newest(store);
1424
+ const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
1425
+ for (const [downstreamSelectorKey, { source }] of upstreamStates) if (source !== key) innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
1426
+ innerTarget.selectorAtoms.delete(key);
1427
+ const value = options.get({
1428
+ get,
1429
+ find,
1430
+ json
1431
+ });
1432
+ const cached = writeToCache(innerTarget, readonlySelector, value);
1433
+ store.logger.info(`✨`, type, key, `=`, cached);
1434
+ covered.clear();
1435
+ return cached;
1436
+ };
1437
+ const readonlySelector = {
1438
+ ...options,
1439
+ type,
2197
1440
  subject,
2198
- install: (s) => createWritableHeldSelectorFamily(s, options),
2199
- default: options.const
1441
+ getFrom,
1442
+ install: (s) => createReadonlyPureSelector(s, options, family)
2200
1443
  };
2201
- store.families.set(familyKey, selectorFamily$1);
2202
- return familyToken;
1444
+ if (family) readonlySelector.family = family;
1445
+ target.readonlySelectors.set(key, readonlySelector);
1446
+ const token = {
1447
+ key,
1448
+ type
1449
+ };
1450
+ if (family) token.family = family;
1451
+ return token;
2203
1452
  }
2204
1453
 
2205
1454
  //#endregion
2206
- //#region src/internal/families/create-writable-pure-selector-family.ts
2207
- function createWritablePureSelectorFamily(store, options, internalRoles) {
2208
- const familyKey = options.key;
2209
- const type = `writable_pure_selector_family`;
2210
- const familyToken = {
2211
- key: familyKey,
2212
- type
2213
- };
2214
- const existing = store.families.get(familyKey);
2215
- 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.`);
1455
+ //#region src/internal/selector/create-writable-held-selector.ts
1456
+ function createWritableHeldSelector(store, options, family) {
1457
+ const target = newest(store);
2216
1458
  const subject = new Subject();
2217
- const create = (key) => {
2218
- const subKey = stringifyJson(key);
2219
- const family = {
2220
- key: familyKey,
2221
- subKey
2222
- };
2223
- const fullKey = `${familyKey}(${subKey})`;
2224
- const target = newest(store);
2225
- const individualOptions = {
2226
- key: fullKey,
2227
- get: options.get(key),
2228
- set: options.set(key)
2229
- };
2230
- if (options.catch) individualOptions.catch = options.catch;
2231
- return createWritablePureSelector(target, individualOptions, family);
1459
+ const covered = /* @__PURE__ */ new Set();
1460
+ const { key, const: constant } = options;
1461
+ const type = `writable_held_selector`;
1462
+ store.logger.info(`🔨`, type, key, `is being created`);
1463
+ const setterToolkit = registerSelector(target, type, key, covered);
1464
+ const { find, get, json } = setterToolkit;
1465
+ const getterToolkit = {
1466
+ find,
1467
+ get,
1468
+ json
2232
1469
  };
2233
- const selectorFamily$1 = {
2234
- ...familyToken,
2235
- create,
2236
- internalRoles,
1470
+ const getFrom = (innerTarget) => {
1471
+ const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
1472
+ for (const [downstreamSelectorKey, { source }] of upstreamStates) if (source !== key) innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
1473
+ innerTarget.selectorAtoms.delete(key);
1474
+ options.get(getterToolkit, constant);
1475
+ writeToCache(innerTarget, mySelector, constant);
1476
+ store.logger.info(`✨`, type, key, `=`, constant);
1477
+ covered.clear();
1478
+ return constant;
1479
+ };
1480
+ const setSelf = () => {
1481
+ options.set(setterToolkit, constant);
1482
+ };
1483
+ const mySelector = {
1484
+ ...options,
1485
+ type,
2237
1486
  subject,
2238
- install: (s) => createWritablePureSelectorFamily(s, options),
2239
- default: (key) => {
2240
- const getFn = options.get(key);
2241
- return getFn({
2242
- get: ((...args) => getFromStore(store, ...args)),
2243
- find: ((...args) => findInStore(store, ...args)),
2244
- json: (token) => getJsonToken(store, token)
2245
- });
2246
- }
1487
+ getFrom,
1488
+ setSelf,
1489
+ install: (s) => createWritableHeldSelector(s, options, family)
2247
1490
  };
2248
- store.families.set(familyKey, selectorFamily$1);
2249
- return familyToken;
2250
- }
2251
-
2252
- //#endregion
2253
- //#region src/internal/families/create-selector-family.ts
2254
- function createSelectorFamily(store, options) {
2255
- const isWritable = `set` in options;
2256
- const isHeld = `const` in options;
2257
- if (isHeld && isWritable) return createWritableHeldSelectorFamily(store, options, void 0);
2258
- if (isHeld) return createReadonlyHeldSelectorFamily(store, options, void 0);
2259
- if (isWritable) return createWritablePureSelectorFamily(store, options);
2260
- return createReadonlyPureSelectorFamily(store, options);
1491
+ if (family) mySelector.family = family;
1492
+ target.writableSelectors.set(key, mySelector);
1493
+ const token = {
1494
+ key,
1495
+ type
1496
+ };
1497
+ if (family) token.family = family;
1498
+ return token;
2261
1499
  }
2262
1500
 
2263
1501
  //#endregion
2264
- //#region src/internal/families/seek-in-store.ts
2265
- function seekInStore(store, token, key) {
2266
- const subKey = stringifyJson(key);
2267
- const fullKey = `${token.key}(${subKey})`;
1502
+ //#region src/internal/selector/create-writable-pure-selector.ts
1503
+ function createWritablePureSelector(store, options, family) {
2268
1504
  const target = newest(store);
2269
- let state;
2270
- switch (token.type) {
2271
- case `atom_family`:
2272
- case `mutable_atom_family`:
2273
- state = target.atoms.get(fullKey);
2274
- break;
2275
- case `writable_held_selector_family`:
2276
- case `writable_pure_selector_family`:
2277
- state = target.writableSelectors.get(fullKey);
2278
- break;
2279
- case `readonly_held_selector_family`:
2280
- case `readonly_pure_selector_family`:
2281
- state = target.readonlySelectors.get(fullKey);
2282
- break;
2283
- }
2284
- if (state) return deposit(state);
2285
- return state;
2286
- }
2287
-
2288
- //#endregion
2289
- //#region src/internal/families/find-in-store.ts
2290
- function findInStore(store, familyToken, key) {
2291
- const family = withdraw(store, familyToken);
2292
- const existingStateToken = seekInStore(store, familyToken, key);
2293
- if (existingStateToken) return existingStateToken;
2294
- const newStateToken = mintInStore(store, family, key);
2295
- return newStateToken;
1505
+ const subject = new Subject();
1506
+ const covered = /* @__PURE__ */ new Set();
1507
+ const key = options.key;
1508
+ const type = `writable_pure_selector`;
1509
+ store.logger.info(`🔨`, type, key, `is being created`);
1510
+ const setterToolkit = registerSelector(target, type, key, covered);
1511
+ const { find, get, json } = setterToolkit;
1512
+ const getterToolkit = {
1513
+ find,
1514
+ get,
1515
+ json
1516
+ };
1517
+ const getFrom = (innerTarget) => {
1518
+ const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
1519
+ for (const [downstreamSelectorKey, { source }] of upstreamStates) if (source !== key) innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
1520
+ innerTarget.selectorAtoms.delete(key);
1521
+ const value = options.get(getterToolkit);
1522
+ const cached = writeToCache(innerTarget, mySelector, value);
1523
+ store.logger.info(`✨`, type, key, `=`, cached);
1524
+ covered.clear();
1525
+ return cached;
1526
+ };
1527
+ const setSelf = (newValue) => {
1528
+ options.set(setterToolkit, newValue);
1529
+ };
1530
+ const mySelector = {
1531
+ ...options,
1532
+ type,
1533
+ subject,
1534
+ getFrom,
1535
+ setSelf,
1536
+ install: (s) => createWritablePureSelector(s, options, family)
1537
+ };
1538
+ if (family) mySelector.family = family;
1539
+ target.writableSelectors.set(key, mySelector);
1540
+ const token = {
1541
+ key,
1542
+ type
1543
+ };
1544
+ if (family) token.family = family;
1545
+ return token;
2296
1546
  }
2297
1547
 
2298
1548
  //#endregion
2299
- //#region src/internal/families/dispose-from-store.ts
2300
- function disposeFromStore(store, ...params) {
2301
- let token;
2302
- if (params.length === 1) token = params[0];
2303
- else {
2304
- const family = params[0];
2305
- const key = params[1];
2306
- const maybeToken = findInStore(store, family, key);
2307
- token = maybeToken;
2308
- }
2309
- try {
2310
- withdraw(store, token);
2311
- } catch (_) {
2312
- store.logger.error(`❌`, token.type, token.key, `could not be disposed because it was not found in the store "${store.config.name}".`);
2313
- return;
2314
- }
2315
- switch (token.type) {
2316
- case `atom`:
2317
- case `mutable_atom`:
2318
- disposeAtom(store, token);
2319
- break;
2320
- case `writable_pure_selector`:
2321
- case `readonly_pure_selector`:
2322
- case `writable_held_selector`:
2323
- case `readonly_held_selector`:
2324
- disposeSelector(store, token);
2325
- break;
1549
+ //#region src/internal/selector/create-standalone-selector.ts
1550
+ function createStandaloneSelector(store, options) {
1551
+ const isWritable = `set` in options;
1552
+ const isHeld = `const` in options;
1553
+ if (isHeld && isWritable) {
1554
+ const state$1 = createWritableHeldSelector(store, options, void 0);
1555
+ store.on.selectorCreation.next(state$1);
1556
+ return state$1;
2326
1557
  }
2327
- }
2328
-
2329
- //#endregion
2330
- //#region src/internal/get-state/reduce-reference.ts
2331
- function reduceReference(store, ...params) {
2332
- let existingToken;
2333
- let brandNewToken;
2334
- let family;
2335
- let subKey;
2336
- let token;
2337
- if (params.length === 1) {
2338
- token = params[0];
2339
- if (`family` in token) {
2340
- const familyToken = getFamilyOfToken(store, token);
2341
- family = withdraw(store, familyToken);
2342
- subKey = parseJson(token.family.subKey);
2343
- existingToken = seekInStore(store, familyToken, subKey);
2344
- if (`counterfeit` in token) return {
2345
- token,
2346
- family,
2347
- subKey,
2348
- isNew: false
2349
- };
2350
- if (!existingToken) {
2351
- brandNewToken = mintInStore(store, familyToken, subKey, MUST_CREATE);
2352
- token = brandNewToken;
2353
- } else token = existingToken;
2354
- }
2355
- } else {
2356
- family = withdraw(store, params[0]);
2357
- subKey = params[1];
2358
- existingToken = seekInStore(store, family, subKey);
2359
- if (!existingToken) {
2360
- brandNewToken = mintInStore(store, family, subKey, MUST_CREATE);
2361
- token = brandNewToken;
2362
- } else token = existingToken;
2363
- }
2364
- const isCounterfeit = `counterfeit` in token;
2365
- const isNewlyCreated = Boolean(brandNewToken) && isCounterfeit === false;
2366
- if (isNewlyCreated && family) {
2367
- let subType;
2368
- switch (token.type) {
2369
- case `readonly_pure_selector`:
2370
- case `readonly_held_selector`:
2371
- subType = `readable`;
2372
- break;
2373
- case `atom`:
2374
- case `mutable_atom`:
2375
- case `writable_pure_selector`:
2376
- case `writable_held_selector`:
2377
- subType = `writable`;
2378
- break;
2379
- }
2380
- const stateCreationEvent = {
2381
- type: `state_creation`,
2382
- subType,
2383
- token,
2384
- timestamp: Date.now()
2385
- };
2386
- const familySubject = family.subject;
2387
- familySubject.next(stateCreationEvent);
2388
- const target = newest(store);
2389
- if (token.family) {
2390
- if (isRootStore(target)) switch (token.type) {
2391
- case `atom`:
2392
- case `mutable_atom`:
2393
- store.on.atomCreation.next(token);
2394
- break;
2395
- case `writable_pure_selector`:
2396
- case `readonly_pure_selector`:
2397
- case `writable_held_selector`:
2398
- case `readonly_held_selector`:
2399
- store.on.selectorCreation.next(token);
2400
- break;
2401
- }
2402
- else if (isChildStore(target) && target.on.transactionApplying.state === null) target.transactionMeta.update.subEvents.push(stateCreationEvent);
2403
- }
1558
+ if (isHeld) {
1559
+ const state$1 = createReadonlyHeldSelector(store, options, void 0);
1560
+ store.on.selectorCreation.next(state$1);
1561
+ return state$1;
2404
1562
  }
2405
- return {
2406
- token,
2407
- family,
2408
- subKey,
2409
- isNew: Boolean(brandNewToken)
2410
- };
2411
- }
2412
-
2413
- //#endregion
2414
- //#region src/internal/get-state/get-from-store.ts
2415
- function getFromStore(store, ...params) {
2416
- const { token, family, subKey } = reduceReference(store, ...params);
2417
- if (`counterfeit` in token && family && subKey) return getFallback(store, token, family, subKey);
2418
- const state = withdraw(store, token);
2419
- return readOrComputeValue(store, state);
2420
- }
2421
-
2422
- //#endregion
2423
- //#region src/internal/subscribe/subscribe-to-root-atoms.ts
2424
- const subscribeToRootDependency = (target, selector, atom) => {
2425
- return atom.subject.subscribe(`${selector.type}:${selector.key}`, (atomChange) => {
2426
- target.logger.info(`📢`, selector.type, selector.key, `root`, atom.key, `went`, atomChange.oldValue, `->`, atomChange.newValue);
2427
- const oldValue = recallState(target, selector);
2428
- const newValue = readOrComputeValue(target, selector);
2429
- target.logger.info(`✨`, selector.type, selector.key, `went`, oldValue, `->`, newValue);
2430
- selector.subject.next({
2431
- newValue,
2432
- oldValue
2433
- });
2434
- });
2435
- };
2436
-
2437
- //#endregion
2438
- //#region src/internal/subscribe/subscribe-to-state.ts
2439
- function subscribeToState(store, token, key, handleUpdate) {
2440
- function safelyHandleUpdate(update) {
2441
- if (store.operation.open) {
2442
- const unsubscribe$1 = store.on.operationClose.subscribe(`state subscription ${key}`, () => {
2443
- unsubscribe$1();
2444
- handleUpdate(update);
2445
- });
2446
- } else handleUpdate(update);
2447
- }
2448
- reduceReference(store, token);
2449
- const state = withdraw(store, token);
2450
- store.logger.info(`👀`, state.type, state.key, `Adding subscription "${key}"`);
2451
- const isSelector = state.type === `writable_pure_selector` || state.type === `readonly_pure_selector`;
2452
- const rootSubs = /* @__PURE__ */ new Map();
2453
- let updateHandler = safelyHandleUpdate;
2454
- if (isSelector) {
2455
- readOrComputeValue(store, state);
2456
- for (const [atomKey, atom] of traceRootSelectorAtoms(store, state.key)) rootSubs.set(atomKey, subscribeToRootDependency(store, state, atom));
2457
- updateHandler = function updateRootsBeforeHandlingUpdate(update) {
2458
- const dependencies = traceRootSelectorAtoms(store, state.key);
2459
- for (const [previousRootKey, unsub] of rootSubs) {
2460
- const currentRoot = dependencies.get(previousRootKey);
2461
- if (currentRoot) dependencies.delete(previousRootKey);
2462
- else {
2463
- unsub();
2464
- rootSubs.delete(previousRootKey);
2465
- }
2466
- }
2467
- for (const [atomKey, atom] of dependencies) rootSubs.set(atomKey, subscribeToRootDependency(store, state, atom));
2468
- safelyHandleUpdate(update);
2469
- };
1563
+ if (isWritable) {
1564
+ const state$1 = createWritablePureSelector(store, options, void 0);
1565
+ store.on.selectorCreation.next(state$1);
1566
+ return state$1;
2470
1567
  }
2471
- const mainUnsubFunction = state.subject.subscribe(key, updateHandler);
2472
- const unsubscribe = () => {
2473
- store.logger.info(`🙈`, state.type, state.key, `Removing subscription "${key}"`);
2474
- mainUnsubFunction();
2475
- for (const unsubFromDependency of rootSubs.values()) unsubFromDependency();
2476
- };
2477
- return unsubscribe;
1568
+ const state = createReadonlyPureSelector(store, options, void 0);
1569
+ store.on.selectorCreation.next(state);
1570
+ return state;
2478
1571
  }
2479
1572
 
2480
1573
  //#endregion
2481
- //#region src/internal/store/withdraw.ts
2482
- function withdraw(store, token) {
2483
- let withdrawn;
2484
- let target = store;
2485
- while (target !== null) {
2486
- switch (token.type) {
2487
- case `atom`:
2488
- case `mutable_atom`:
2489
- withdrawn = target.atoms.get(token.key);
1574
+ //#region src/internal/selector/dispose-selector.ts
1575
+ function disposeSelector(store, selectorToken) {
1576
+ const target = newest(store);
1577
+ const { key, type, family: familyMeta } = selectorToken;
1578
+ if (!familyMeta) store.logger.error(`❌`, type, key, `Standalone selectors cannot be disposed.`);
1579
+ else {
1580
+ if (target.molecules.get(familyMeta.subKey)) target.moleculeData.delete(familyMeta.subKey, familyMeta.key);
1581
+ let familyToken;
1582
+ switch (selectorToken.type) {
1583
+ case `writable_held_selector`:
1584
+ target.writableSelectors.delete(key);
1585
+ familyToken = {
1586
+ key: familyMeta.key,
1587
+ type: `writable_held_selector_family`
1588
+ };
1589
+ withdraw(store, familyToken).subject.next({
1590
+ type: `state_disposal`,
1591
+ subType: `selector`,
1592
+ token: selectorToken,
1593
+ timestamp: Date.now()
1594
+ });
2490
1595
  break;
2491
1596
  case `writable_pure_selector`:
2492
- case `writable_held_selector`:
2493
- withdrawn = target.writableSelectors.get(token.key);
1597
+ target.writableSelectors.delete(key);
1598
+ familyToken = {
1599
+ key: familyMeta.key,
1600
+ type: `writable_pure_selector_family`
1601
+ };
1602
+ withdraw(store, familyToken).subject.next({
1603
+ type: `state_disposal`,
1604
+ subType: `selector`,
1605
+ token: selectorToken,
1606
+ timestamp: Date.now()
1607
+ });
2494
1608
  break;
2495
- case `readonly_pure_selector`:
2496
1609
  case `readonly_held_selector`:
2497
- withdrawn = target.readonlySelectors.get(token.key);
2498
- break;
2499
- case `atom_family`:
2500
- case `mutable_atom_family`:
2501
- case `writable_pure_selector_family`:
2502
- case `readonly_pure_selector_family`:
2503
- case `writable_held_selector_family`:
2504
- case `readonly_held_selector_family`:
2505
- withdrawn = target.families.get(token.key);
2506
- break;
2507
- case `timeline`:
2508
- withdrawn = target.timelines.get(token.key);
1610
+ target.readonlySelectors.delete(key);
1611
+ familyToken = {
1612
+ key: familyMeta.key,
1613
+ type: `readonly_held_selector_family`
1614
+ };
1615
+ withdraw(store, familyToken).subject.next({
1616
+ type: `state_disposal`,
1617
+ subType: `selector`,
1618
+ token: selectorToken,
1619
+ timestamp: Date.now()
1620
+ });
2509
1621
  break;
2510
- case `transaction`:
2511
- withdrawn = target.transactions.get(token.key);
1622
+ case `readonly_pure_selector`:
1623
+ target.readonlySelectors.delete(key);
1624
+ familyToken = {
1625
+ key: familyMeta.key,
1626
+ type: `readonly_pure_selector_family`
1627
+ };
1628
+ withdraw(store, familyToken).subject.next({
1629
+ type: `state_disposal`,
1630
+ subType: `selector`,
1631
+ token: selectorToken,
1632
+ timestamp: Date.now()
1633
+ });
2512
1634
  break;
2513
1635
  }
2514
- if (withdrawn) return withdrawn;
2515
- target = target.child;
1636
+ target.valueMap.delete(key);
1637
+ target.selectorAtoms.delete(key);
1638
+ target.selectorGraph.delete(key);
1639
+ target.moleculeData.delete(familyMeta.key, familyMeta.subKey);
1640
+ store.logger.info(`🔥`, selectorToken.type, key, `deleted`);
1641
+ if (isChildStore(target) && target.transactionMeta.phase === `building`) target.transactionMeta.update.subEvents.push({
1642
+ type: `state_disposal`,
1643
+ subType: `selector`,
1644
+ token: selectorToken,
1645
+ timestamp: Date.now()
1646
+ });
1647
+ else store.on.selectorDisposal.next(selectorToken);
2516
1648
  }
2517
- throw new NotFoundError(token, store);
2518
1649
  }
2519
1650
 
2520
- //#endregion
2521
- //#region src/internal/subscribe/subscribe-to-timeline.ts
2522
- const subscribeToTimeline = (store, token, key, handleUpdate) => {
2523
- const tl = withdraw(store, token);
2524
- store.logger.info(`👀`, `timeline`, token.key, `Adding subscription "${key}"`);
2525
- const unsubscribe = tl.subject.subscribe(key, handleUpdate);
2526
- return () => {
2527
- store.logger.info(`🙈`, `timeline`, token.key, `Removing subscription "${key}" from timeline`);
2528
- unsubscribe();
2529
- };
2530
- };
2531
-
2532
1651
  //#endregion
2533
1652
  //#region src/internal/subscribe/subscribe-to-transaction.ts
2534
1653
  const subscribeToTransaction = (store, token, key, handleUpdate) => {
@@ -2556,98 +1675,6 @@ function subscribeInStore(store, token, handleUpdate, key = arbitrary()) {
2556
1675
  }
2557
1676
  }
2558
1677
 
2559
- //#endregion
2560
- //#region src/internal/mutable/tracker.ts
2561
- /**
2562
- * @internal Give the tracker a transceiver state and a store, and it will
2563
- * subscribe to the transceiver's inner value. When the inner value changes,
2564
- * the tracker will update its own state to reflect the change.
2565
- */
2566
- var Tracker = class {
2567
- initializeSignalAtom(mutableState, store) {
2568
- const latestSignalStateKey = `*${mutableState.key}`;
2569
- store.atoms.delete(latestSignalStateKey);
2570
- store.valueMap.delete(latestSignalStateKey);
2571
- const familyMetaData = mutableState.family ? {
2572
- key: `*${mutableState.family.key}`,
2573
- subKey: mutableState.family.subKey
2574
- } : void 0;
2575
- const latestSignalState = createRegularAtom(store, {
2576
- key: latestSignalStateKey,
2577
- default: null
2578
- }, familyMetaData, [`tracker:signal`]);
2579
- if (store.parent?.valueMap.has(latestSignalStateKey)) {
2580
- const parentValue = store.parent.valueMap.get(latestSignalStateKey);
2581
- store.valueMap.set(latestSignalStateKey, parentValue);
2582
- }
2583
- return latestSignalState;
2584
- }
2585
- unsubscribeFromInnerValue;
2586
- unsubscribeFromState;
2587
- captureSignalsFromCore(mutableState, latestSignalState, target) {
2588
- const stateKey = mutableState.key;
2589
- const storeName = target.config.name;
2590
- const storeStatus = isChildStore(target) ? target.transactionMeta.update.token.key : `main`;
2591
- const subscriptionKey = `tracker:${storeName}:${storeStatus}:${stateKey}`;
2592
- const trackerCapturesOutboundSignal = (update) => {
2593
- setIntoStore(target, latestSignalState, update);
2594
- };
2595
- const originalInnerValue = getFromStore(target, mutableState);
2596
- this.unsubscribeFromInnerValue = originalInnerValue.subscribe(subscriptionKey, trackerCapturesOutboundSignal);
2597
- this.unsubscribeFromState = subscribeToState(target, mutableState, subscriptionKey, function trackerLooksForNewReference(update) {
2598
- if (update.newValue !== update.oldValue) {
2599
- this.unsubscribeFromInnerValue();
2600
- this.unsubscribeFromInnerValue = update.newValue.subscribe(subscriptionKey, trackerCapturesOutboundSignal);
2601
- }
2602
- }.bind(this));
2603
- }
2604
- supplySignalsToCore(mutableState, latestSignalState, target) {
2605
- const subscriptionKey = `tracker:${target.config.name}:${isChildStore(target) ? target.transactionMeta.update.token.key : `main`}:${mutableState.key}`;
2606
- subscribeToState(target, latestSignalState, subscriptionKey, function trackerCapturesInboundSignal({ newValue, oldValue }) {
2607
- const timelineId = target.timelineTopics.getRelatedKey(latestSignalState.key);
2608
- if (timelineId && target.timelines.get(timelineId)?.timeTraveling) {
2609
- const unsubscribe = subscribeToTimeline(target, {
2610
- key: timelineId,
2611
- type: `timeline`
2612
- }, subscriptionKey, function trackerWaitsForTimeTravelToFinish(update) {
2613
- unsubscribe();
2614
- setIntoStore(target, mutableState, (transceiver) => {
2615
- if (update === `redo` && newValue) transceiver.do(newValue);
2616
- else if (update === `undo` && oldValue) transceiver.undo(oldValue);
2617
- return transceiver;
2618
- });
2619
- });
2620
- return;
2621
- }
2622
- const mutable = getFromStore(target, mutableState);
2623
- const updateNumber = mutable.getUpdateNumber(newValue);
2624
- const eventOffset = updateNumber - mutable.cacheUpdateNumber;
2625
- if (newValue && eventOffset === 1) setIntoStore(target, mutableState, (transceiver) => (transceiver.do(newValue), transceiver));
2626
- else {
2627
- const expected = mutable.cacheUpdateNumber + 1;
2628
- target.logger.info(`❌`, `mutable_atom`, mutableState.key, `could not be updated. Expected update number`, expected, `but got`, updateNumber);
2629
- }
2630
- });
2631
- }
2632
- mutableAtomToken;
2633
- latestSignalToken;
2634
- [Symbol.dispose];
2635
- constructor(mutableAtomToken, store) {
2636
- const target = newest(store);
2637
- const latestSignalToken = this.initializeSignalAtom(mutableAtomToken, target);
2638
- this.mutableAtomToken = mutableAtomToken;
2639
- this.latestSignalToken = latestSignalToken;
2640
- this.captureSignalsFromCore(mutableAtomToken, latestSignalToken, target);
2641
- this.supplySignalsToCore(mutableAtomToken, latestSignalToken, target);
2642
- target.trackers.set(mutableAtomToken.key, this);
2643
- this[Symbol.dispose] = () => {
2644
- this.unsubscribeFromInnerValue();
2645
- this.unsubscribeFromState();
2646
- target.trackers.delete(mutableAtomToken.key);
2647
- };
2648
- }
2649
- };
2650
-
2651
1678
  //#endregion
2652
1679
  //#region src/internal/mutable/create-mutable-atom.ts
2653
1680
  function createMutableAtom(store, options, family) {
@@ -2790,8 +1817,7 @@ function createMutableAtomFamily(store, options, internalRoles) {
2790
1817
  const getJsonFamily = (mutableAtomFamily, store) => {
2791
1818
  const target = newest(store);
2792
1819
  const key = `${mutableAtomFamily.key}:JSON`;
2793
- const jsonFamily = target.families.get(key);
2794
- return jsonFamily;
1820
+ return target.families.get(key);
2795
1821
  };
2796
1822
 
2797
1823
  //#endregion
@@ -2799,21 +1825,18 @@ const getJsonFamily = (mutableAtomFamily, store) => {
2799
1825
  const getJsonToken = (store, mutableAtomToken) => {
2800
1826
  if (mutableAtomToken.family) {
2801
1827
  const target = newest(store);
2802
- const jsonFamilyKey = `${mutableAtomToken.family.key}:JSON`;
2803
1828
  const jsonFamilyToken = {
2804
- key: jsonFamilyKey,
1829
+ key: `${mutableAtomToken.family.key}:JSON`,
2805
1830
  type: `writable_pure_selector_family`
2806
1831
  };
2807
1832
  const family = withdraw(target, jsonFamilyToken);
2808
1833
  const subKey = parseJson(mutableAtomToken.family.subKey);
2809
- const jsonToken = findInStore(store, family, subKey);
2810
- return jsonToken;
1834
+ return findInStore(store, family, subKey);
2811
1835
  }
2812
- const token = {
1836
+ return {
2813
1837
  type: `writable_pure_selector`,
2814
1838
  key: `${mutableAtomToken.key}:JSON`
2815
1839
  };
2816
- return token;
2817
1840
  };
2818
1841
 
2819
1842
  //#endregion
@@ -2821,17 +1844,15 @@ const getJsonToken = (store, mutableAtomToken) => {
2821
1844
  const getUpdateFamily = (mutableAtomFamily, store) => {
2822
1845
  const target = newest(store);
2823
1846
  const key = `*${mutableAtomFamily.key}`;
2824
- const updateFamily = target.families.get(key);
2825
- return updateFamily;
1847
+ return target.families.get(key);
2826
1848
  };
2827
1849
 
2828
1850
  //#endregion
2829
1851
  //#region src/internal/mutable/get-update-token.ts
2830
1852
  const getUpdateToken = (mutableAtomToken) => {
2831
- const key = `*${mutableAtomToken.key}`;
2832
1853
  const updateToken = {
2833
1854
  type: `atom`,
2834
- key
1855
+ key: `*${mutableAtomToken.key}`
2835
1856
  };
2836
1857
  if (mutableAtomToken.family) updateToken.family = {
2837
1858
  key: `*${mutableAtomToken.family.key}`,
@@ -2840,191 +1861,6 @@ const getUpdateToken = (mutableAtomToken) => {
2840
1861
  return updateToken;
2841
1862
  };
2842
1863
 
2843
- //#endregion
2844
- //#region src/internal/mutable/transceiver.ts
2845
- function isTransceiver(value) {
2846
- return typeof value === `object` && value !== null && `do` in value && `undo` in value && `subscribe` in value && `cacheUpdateNumber` in value && `getUpdateNumber` in value && `READONLY_VIEW` in value && `toJSON` in value;
2847
- }
2848
-
2849
- //#endregion
2850
- //#region src/internal/store/store.ts
2851
- var Store = class {
2852
- parent = null;
2853
- child = null;
2854
- valueMap = /* @__PURE__ */ new Map();
2855
- defaults = /* @__PURE__ */ new Map();
2856
- atoms = /* @__PURE__ */ new Map();
2857
- writableSelectors = /* @__PURE__ */ new Map();
2858
- readonlySelectors = /* @__PURE__ */ new Map();
2859
- atomsThatAreDefault = /* @__PURE__ */ new Set();
2860
- selectorAtoms = new Junction({
2861
- between: [`selectorKey`, `atomKey`],
2862
- cardinality: `n:n`
2863
- });
2864
- selectorGraph = new Junction({
2865
- between: [`upstreamSelectorKey`, `downstreamSelectorKey`],
2866
- cardinality: `n:n`
2867
- }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
2868
- trackers = /* @__PURE__ */ new Map();
2869
- families = /* @__PURE__ */ new Map();
2870
- joins = /* @__PURE__ */ new Map();
2871
- transactions = /* @__PURE__ */ new Map();
2872
- transactionMeta = {
2873
- epoch: /* @__PURE__ */ new Map(),
2874
- actionContinuities: new Junction({
2875
- between: [`continuity`, `action`],
2876
- cardinality: `1:n`
2877
- })
2878
- };
2879
- timelines = /* @__PURE__ */ new Map();
2880
- timelineTopics = new Junction({
2881
- between: [`timelineKey`, `topicKey`],
2882
- cardinality: `1:n`
2883
- });
2884
- disposalTraces = new CircularBuffer(100);
2885
- molecules = /* @__PURE__ */ new Map();
2886
- moleculeJoins = new Junction({
2887
- between: [`moleculeKey`, `joinKey`],
2888
- cardinality: `n:n`
2889
- }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
2890
- moleculeGraph = new Junction({
2891
- between: [`upstreamMoleculeKey`, `downstreamMoleculeKey`],
2892
- cardinality: `n:n`
2893
- }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
2894
- moleculeData = new Junction({
2895
- between: [`moleculeKey`, `stateFamilyKey`],
2896
- cardinality: `n:n`
2897
- }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
2898
- miscResources = /* @__PURE__ */ new Map();
2899
- on = {
2900
- atomCreation: new Subject(),
2901
- atomDisposal: new Subject(),
2902
- selectorCreation: new Subject(),
2903
- selectorDisposal: new Subject(),
2904
- timelineCreation: new Subject(),
2905
- transactionCreation: new Subject(),
2906
- transactionApplying: new StatefulSubject(null),
2907
- operationClose: new Subject(),
2908
- moleculeCreation: new Subject(),
2909
- moleculeDisposal: new Subject()
2910
- };
2911
- operation = { open: false };
2912
- config = {
2913
- name: `IMPLICIT_STORE`,
2914
- lifespan: `ephemeral`
2915
- };
2916
- loggers = [new AtomIOLogger(`warn`, (_, __, key) => !isReservedIntrospectionKey(key))];
2917
- logger = {
2918
- error: (...messages) => {
2919
- for (const logger of this.loggers) logger.error(...messages);
2920
- },
2921
- info: (...messages) => {
2922
- for (const logger of this.loggers) logger.info(...messages);
2923
- },
2924
- warn: (...messages) => {
2925
- for (const logger of this.loggers) logger.warn(...messages);
2926
- }
2927
- };
2928
- constructor(config, store = null) {
2929
- this.config = {
2930
- ...store?.config,
2931
- ...config
2932
- };
2933
- if (store !== null) {
2934
- this.operation = { ...store?.operation };
2935
- if (isRootStore(store)) this.transactionMeta = {
2936
- epoch: new Map(store?.transactionMeta.epoch),
2937
- actionContinuities: new Junction(store?.transactionMeta.actionContinuities.toJSON())
2938
- };
2939
- for (const [, family] of store.families) {
2940
- if (family.internalRoles?.includes(`mutable`) || family.internalRoles?.includes(`join`)) continue;
2941
- family.install(this);
2942
- }
2943
- const mutableHelpers = /* @__PURE__ */ new Set();
2944
- for (const [, atom] of store.atoms) {
2945
- if (mutableHelpers.has(atom.key)) continue;
2946
- atom.install(this);
2947
- if (atom.type === `mutable_atom`) {
2948
- const originalJsonToken = getJsonToken(store, atom);
2949
- const originalUpdateToken = getUpdateToken(atom);
2950
- mutableHelpers.add(originalJsonToken.key);
2951
- mutableHelpers.add(originalUpdateToken.key);
2952
- }
2953
- }
2954
- for (const [, selector] of store.readonlySelectors) selector.install(this);
2955
- for (const [, selector] of store.writableSelectors) {
2956
- if (mutableHelpers.has(selector.key)) continue;
2957
- selector.install(this);
2958
- }
2959
- for (const [, tx] of store.transactions) tx.install(this);
2960
- for (const [, timeline] of store.timelines) timeline.install(this);
2961
- }
2962
- }
2963
- };
2964
- const IMPLICIT = { get STORE() {
2965
- globalThis.ATOM_IO_IMPLICIT_STORE ??= new Store({
2966
- name: `IMPLICIT_STORE`,
2967
- lifespan: `ephemeral`
2968
- });
2969
- return globalThis.ATOM_IO_IMPLICIT_STORE;
2970
- } };
2971
- const clearStore = (store) => {
2972
- const { config } = store;
2973
- for (const disposable of store.miscResources.values()) disposable[Symbol.dispose]();
2974
- Object.assign(store, new Store(config));
2975
- store.config = config;
2976
- };
2977
-
2978
- //#endregion
2979
- //#region src/internal/atom/create-regular-atom.ts
2980
- function createRegularAtom(store, options, family, internalRoles) {
2981
- const type = `atom`;
2982
- const { key } = options;
2983
- store.logger.info(`🔨`, type, key, `is being created`);
2984
- const target = newest(store);
2985
- const existing = target.atoms.get(key);
2986
- if (existing && existing.type === type) {
2987
- store.logger.error(`❌`, `atom`, key, `Tried to create atom, but it already exists in the store.`);
2988
- return deposit(existing);
2989
- }
2990
- const subject = new Subject();
2991
- const newAtom = {
2992
- ...options,
2993
- type,
2994
- install: (s) => {
2995
- s.logger.info(`🛠️`, type, key, `installing in store "${s.config.name}"`);
2996
- return createRegularAtom(s, options, family);
2997
- },
2998
- subject
2999
- };
3000
- if (family) newAtom.family = family;
3001
- if (internalRoles) newAtom.internalRoles = internalRoles;
3002
- target.atoms.set(key, newAtom);
3003
- const token = deposit(newAtom);
3004
- if (options.effects) {
3005
- let effectIndex = 0;
3006
- const cleanupFunctions = [];
3007
- for (const effect of options.effects) {
3008
- const cleanup = effect({
3009
- resetSelf: () => {
3010
- resetInStore(store, token);
3011
- },
3012
- setSelf: (next) => {
3013
- setIntoStore(store, token, next);
3014
- },
3015
- onSet: (handle) => subscribeToState(store, token, `effect[${effectIndex}]`, handle)
3016
- });
3017
- if (cleanup) cleanupFunctions.push(cleanup);
3018
- ++effectIndex;
3019
- }
3020
- newAtom.cleanup = () => {
3021
- for (const cleanup of cleanupFunctions) cleanup();
3022
- };
3023
- }
3024
- store.on.atomCreation.next(token);
3025
- return token;
3026
- }
3027
-
3028
1864
  //#endregion
3029
1865
  //#region src/internal/atom/dispose-atom.ts
3030
1866
  function disposeAtom(store, atomToken) {
@@ -3036,8 +1872,7 @@ function disposeAtom(store, atomToken) {
3036
1872
  atom.cleanup?.();
3037
1873
  const lastValue = store.valueMap.get(atom.key);
3038
1874
  const familyToken = getFamilyOfToken(store, atomToken);
3039
- const atomFamily$1 = withdraw(store, familyToken);
3040
- const subject = atomFamily$1.subject;
1875
+ const subject = withdraw(store, familyToken).subject;
3041
1876
  const disposalEvent = {
3042
1877
  type: `state_disposal`,
3043
1878
  subType: `atom`,
@@ -3061,22 +1896,13 @@ function disposeAtom(store, atomToken) {
3061
1896
  store.logger.info(`🔥`, `atom`, key, `deleted`);
3062
1897
  if (isChild && target.transactionMeta.phase === `building`) {
3063
1898
  const mostRecentUpdate = target.transactionMeta.update.subEvents.at(-1);
3064
- const wasMoleculeDisposal = mostRecentUpdate?.type === `molecule_disposal`;
3065
- const updateAlreadyCaptured = wasMoleculeDisposal && mostRecentUpdate.values.some(([k]) => k === atom.family?.key);
1899
+ const updateAlreadyCaptured = mostRecentUpdate?.type === `molecule_disposal` && mostRecentUpdate.values.some(([k]) => k === atom.family?.key);
3066
1900
  const isTracker = hasRole(atom, `tracker:signal`);
3067
1901
  if (!updateAlreadyCaptured && !isTracker) target.transactionMeta.update.subEvents.push(disposalEvent);
3068
1902
  } else store.on.atomDisposal.next(atomToken);
3069
1903
  }
3070
1904
  }
3071
1905
 
3072
- //#endregion
3073
- //#region src/internal/atom/has-role.ts
3074
- const INTERNAL_ROLES = [`tracker:signal`];
3075
- function hasRole(atom, role) {
3076
- if (`internalRoles` in atom === false) return false;
3077
- return atom.internalRoles.includes(role);
3078
- }
3079
-
3080
1906
  //#endregion
3081
1907
  //#region src/internal/capitalize.ts
3082
1908
  function capitalize(string) {
@@ -3104,10 +1930,7 @@ function installIntoStore(tokens, target, source) {
3104
1930
  target.logger.error(`❌`, `transaction`, targetNewest.transactionMeta.update.token.key, `could not install the following tokens into store "${target.config.name} from "${source.config.name}":`, tokens, `${targetNewest.config.name} is undergoing a transaction.`);
3105
1931
  return;
3106
1932
  }
3107
- for (const token of tokens) {
3108
- const resource = withdraw(source, token);
3109
- resource.install(target);
3110
- }
1933
+ for (const token of tokens) withdraw(source, token).install(target);
3111
1934
  }
3112
1935
 
3113
1936
  //#endregion
@@ -3174,8 +1997,7 @@ var Join = class {
3174
1997
  const relationsOfAState = find(relatedKeysAtoms, a);
3175
1998
  const currentRelationsOfA = get(relationsOfAState);
3176
1999
  for (const currentRelationB of currentRelationsOfA) {
3177
- const remainsRelated = newRelationsOfA.includes(currentRelationB);
3178
- if (remainsRelated) continue;
2000
+ if (newRelationsOfA.includes(currentRelationB)) continue;
3179
2001
  set(relatedKeysAtoms, currentRelationB, (relationsOfB) => {
3180
2002
  relationsOfB.delete(a);
3181
2003
  return relationsOfB;
@@ -3258,17 +2080,15 @@ var Join = class {
3258
2080
  const setContent = ({ set }, key, content) => {
3259
2081
  set(contentAtoms, key, content);
3260
2082
  };
3261
- const externalStoreWithContentConfiguration = {
2083
+ externalStore = Object.assign(baseExternalStoreConfiguration, {
3262
2084
  getContent: (contentKey) => {
3263
- const content = getContent(this.toolkit, contentKey);
3264
- return content;
2085
+ return getContent(this.toolkit, contentKey);
3265
2086
  },
3266
2087
  setContent: (contentKey, content) => {
3267
2088
  setContent(this.toolkit, contentKey, content);
3268
2089
  },
3269
2090
  deleteContent: (_) => {}
3270
- };
3271
- externalStore = Object.assign(baseExternalStoreConfiguration, externalStoreWithContentConfiguration);
2091
+ });
3272
2092
  } else externalStore = baseExternalStoreConfiguration;
3273
2093
  const relations = new Junction(options, {
3274
2094
  externalStore,
@@ -3301,8 +2121,7 @@ var Join = class {
3301
2121
  key: `${options.key}/multipleRelatedKeys`,
3302
2122
  get: (key) => ({ get }) => {
3303
2123
  const jsonFamily = getJsonFamily(relatedKeysAtoms, store);
3304
- const json = get(jsonFamily, key);
3305
- return json.members;
2124
+ return get(jsonFamily, key).members;
3306
2125
  }
3307
2126
  }, [`join`, `keys`]);
3308
2127
  };
@@ -3326,8 +2145,7 @@ var Join = class {
3326
2145
  key: `${options.key}/multipleRelatedEntries`,
3327
2146
  get: (x) => ({ get }) => {
3328
2147
  const jsonFamily = getJsonFamily(relatedKeysAtoms, store);
3329
- const json = get(jsonFamily, x);
3330
- return json.members.map((y) => {
2148
+ return get(jsonFamily, x).members.map((y) => {
3331
2149
  let a = relations.isAType?.(x) ? x : void 0;
3332
2150
  let b = a === void 0 ? x : void 0;
3333
2151
  a ??= y;
@@ -3417,14 +2235,13 @@ var Join = class {
3417
2235
  //#region src/internal/join/create-join.ts
3418
2236
  function createJoin(store, options, defaultContent) {
3419
2237
  store.joins.set(options.key, new Join(options, defaultContent, store));
3420
- const token = {
2238
+ return {
3421
2239
  key: options.key,
3422
2240
  type: `join`,
3423
2241
  a: options.between[0],
3424
2242
  b: options.between[1],
3425
2243
  cardinality: options.cardinality
3426
2244
  };
3427
- return token;
3428
2245
  }
3429
2246
 
3430
2247
  //#endregion
@@ -3432,8 +2249,7 @@ function createJoin(store, options, defaultContent) {
3432
2249
  function getJoin(token, store) {
3433
2250
  let myJoin = store.joins.get(token.key);
3434
2251
  if (myJoin === void 0) {
3435
- const rootJoinMap = IMPLICIT.STORE.joins;
3436
- const rootJoin = rootJoinMap.get(token.key);
2252
+ const rootJoin = IMPLICIT.STORE.joins.get(token.key);
3437
2253
  if (rootJoin === void 0) throw new Error(`Join "${token.key}" not found in store "${store.config.name}"`);
3438
2254
  const root = eldest(store);
3439
2255
  myJoin = new Join(rootJoin.options, rootJoin.defaultContent, root);
@@ -3467,13 +2283,11 @@ function findRelationsInStore(token, key, store) {
3467
2283
  relations = {
3468
2284
  get [keyAB]() {
3469
2285
  const familyAB = myJoin.states[keyAB];
3470
- const state = findInStore(store, familyAB, key);
3471
- return state;
2286
+ return findInStore(store, familyAB, key);
3472
2287
  },
3473
2288
  get [keyBA]() {
3474
2289
  const familyBA = myJoin.states[keyBA];
3475
- const state = findInStore(store, familyBA, key);
3476
- return state;
2290
+ return findInStore(store, familyBA, key);
3477
2291
  }
3478
2292
  };
3479
2293
  const entryAB = `${token.a}EntryOf${capitalize(token.b)}`;
@@ -3482,13 +2296,11 @@ function findRelationsInStore(token, key, store) {
3482
2296
  Object.assign(relations, {
3483
2297
  get [entryAB]() {
3484
2298
  const familyAB = myJoin.states[entryAB];
3485
- const state = findInStore(store, familyAB, key);
3486
- return state;
2299
+ return findInStore(store, familyAB, key);
3487
2300
  },
3488
2301
  get [entryBA]() {
3489
2302
  const familyBA = myJoin.states[entryBA];
3490
- const state = findInStore(store, familyBA, key);
3491
- return state;
2303
+ return findInStore(store, familyBA, key);
3492
2304
  }
3493
2305
  });
3494
2306
  }
@@ -3500,13 +2312,11 @@ function findRelationsInStore(token, key, store) {
3500
2312
  relations = {
3501
2313
  get [keyAB]() {
3502
2314
  const familyAB = myJoin.states[keyAB];
3503
- const state = findInStore(store, familyAB, key);
3504
- return state;
2315
+ return findInStore(store, familyAB, key);
3505
2316
  },
3506
2317
  get [keysBA]() {
3507
2318
  const familyBA = myJoin.states[keysBA];
3508
- const state = findInStore(store, familyBA, key);
3509
- return state;
2319
+ return findInStore(store, familyBA, key);
3510
2320
  }
3511
2321
  };
3512
2322
  const entryAB = `${token.a}EntryOf${capitalize(token.b)}`;
@@ -3515,13 +2325,11 @@ function findRelationsInStore(token, key, store) {
3515
2325
  Object.assign(relations, {
3516
2326
  get [entryAB]() {
3517
2327
  const familyAB = myJoin.states[entryAB];
3518
- const state = findInStore(store, familyAB, key);
3519
- return state;
2328
+ return findInStore(store, familyAB, key);
3520
2329
  },
3521
2330
  get [entriesBA]() {
3522
2331
  const familyBA = myJoin.states[entriesBA];
3523
- const state = findInStore(store, familyBA, key);
3524
- return state;
2332
+ return findInStore(store, familyBA, key);
3525
2333
  }
3526
2334
  });
3527
2335
  }
@@ -3533,13 +2341,11 @@ function findRelationsInStore(token, key, store) {
3533
2341
  relations = {
3534
2342
  get [keysAB]() {
3535
2343
  const familyAB = myJoin.states[keysAB];
3536
- const state = findInStore(store, familyAB, key);
3537
- return state;
2344
+ return findInStore(store, familyAB, key);
3538
2345
  },
3539
2346
  get [keysBA]() {
3540
2347
  const familyBA = myJoin.states[keysBA];
3541
- const state = findInStore(store, familyBA, key);
3542
- return state;
2348
+ return findInStore(store, familyBA, key);
3543
2349
  }
3544
2350
  };
3545
2351
  const entriesAB = `${token.a}EntriesOf${capitalize(token.b)}`;
@@ -3548,13 +2354,11 @@ function findRelationsInStore(token, key, store) {
3548
2354
  Object.assign(relations, {
3549
2355
  get [entriesAB]() {
3550
2356
  const familyAB = myJoin.states[entriesAB];
3551
- const state = findInStore(store, familyAB, key);
3552
- return state;
2357
+ return findInStore(store, familyAB, key);
3553
2358
  },
3554
2359
  get [entriesBA]() {
3555
2360
  const familyBA = myJoin.states[entriesBA];
3556
- const state = findInStore(store, familyBA, key);
3557
- return state;
2361
+ return findInStore(store, familyBA, key);
3558
2362
  }
3559
2363
  });
3560
2364
  }
@@ -3566,23 +2370,7 @@ function findRelationsInStore(token, key, store) {
3566
2370
  //#endregion
3567
2371
  //#region src/internal/join/get-internal-relations-from-store.ts
3568
2372
  function getInternalRelationsFromStore(token, store) {
3569
- const myJoin = getJoin(token, store);
3570
- const family = myJoin.core.relatedKeysAtoms;
3571
- return family;
3572
- }
3573
-
3574
- //#endregion
3575
- //#region src/internal/not-found-error.ts
3576
- var NotFoundError = class extends Error {
3577
- constructor(token, store) {
3578
- super(`${PRETTY_TOKEN_TYPES[token.type]} ${stringifyJson(token.key)} not found in store "${store.config.name}".`);
3579
- }
3580
- };
3581
-
3582
- //#endregion
3583
- //#region src/internal/reserved-keys.ts
3584
- function isReservedIntrospectionKey(value) {
3585
- return value.startsWith(`🔍 `);
2373
+ return getJoin(token, store).core.relatedKeysAtoms;
3586
2374
  }
3587
2375
 
3588
2376
  //#endregion
@@ -3696,11 +2484,10 @@ function addAtomFamilyToTimeline(store, atomFamilyToken, tl) {
3696
2484
  function joinTransaction(store, tl, txUpdateInProgress) {
3697
2485
  const currentTxKey = txUpdateInProgress.token.key;
3698
2486
  const currentTxInstanceId = txUpdateInProgress.id;
3699
- const currentTxToken = {
2487
+ const currentTransaction = withdraw(store, {
3700
2488
  key: currentTxKey,
3701
2489
  type: `transaction`
3702
- };
3703
- const currentTransaction = withdraw(store, currentTxToken);
2490
+ });
3704
2491
  if (currentTxKey && tl.transactionKey === null) {
3705
2492
  tl.transactionKey = currentTxKey;
3706
2493
  const unsubscribe = currentTransaction.subject.subscribe(`timeline:${tl.key}`, (transactionUpdate) => {
@@ -3863,5 +2650,5 @@ const timeTravel = (store, action, token) => {
3863
2650
  };
3864
2651
 
3865
2652
  //#endregion
3866
- 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 };
2653
+ export { CircularBuffer, 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, getFamilyOfToken, getFromStore, getInternalRelationsFromStore, getJoin, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getTrace, getUpdateFamily, getUpdateToken, hasRole, ingestAtomUpdateEvent, ingestCreationEvent, ingestDisposalEvent, ingestMoleculeCreationEvent, ingestMoleculeDisposalEvent, ingestMoleculeTransferEvent, ingestSelectorUpdateEvent, ingestTransactionOutcomeEvent, installIntoStore, isAtomKey, isChildStore, isDone, isFn, isReadonlySelectorKey, isReservedIntrospectionKey, isRootStore, isSelectorKey, isStateKey, isTransceiver, makeRootMoleculeInStore, markDone, newest, openOperation, readFromCache, readOrComputeValue, recallState, registerSelector, resetAtomOrSelector, resetInStore, seekInStore, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeInStore, subscribeToRootDependency, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceRootSelectorAtoms, updateSelectorAtoms, withdraw, writeToCache };
3867
2654
  //# sourceMappingURL=index.js.map