atom.io 0.40.5 → 0.40.7

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 (163) hide show
  1. package/README.md +1 -1
  2. package/dist/data/index.d.ts +1 -1
  3. package/dist/employ-socket-D6wgByWh.js +12 -0
  4. package/dist/employ-socket-D6wgByWh.js.map +1 -0
  5. package/dist/has-role-hv4-hJMw.js +1149 -0
  6. package/dist/has-role-hv4-hJMw.js.map +1 -0
  7. package/dist/internal/index.d.ts +248 -248
  8. package/dist/internal/index.d.ts.map +1 -1
  9. package/dist/internal/index.js +570 -1712
  10. package/dist/internal/index.js.map +1 -1
  11. package/dist/introspection/index.d.ts +1 -1
  12. package/dist/is-fn-DY1wZ-md.js +10 -0
  13. package/dist/is-fn-DY1wZ-md.js.map +1 -0
  14. package/dist/main/index.d.ts +33 -33
  15. package/dist/main/index.d.ts.map +1 -1
  16. package/dist/main/index.js +2 -2
  17. package/dist/main/index.js.map +1 -1
  18. package/dist/mutex-store-CSvxY9i3.js +11 -0
  19. package/dist/mutex-store-CSvxY9i3.js.map +1 -0
  20. package/dist/react/index.d.ts +5 -21
  21. package/dist/react/index.d.ts.map +1 -1
  22. package/dist/react/index.js.map +1 -1
  23. package/dist/react-devtools/index.js +7 -7
  24. package/dist/react-devtools/index.js.map +1 -1
  25. package/dist/realtime/index.d.ts +7 -15
  26. package/dist/realtime/index.d.ts.map +1 -1
  27. package/dist/realtime/index.js +3 -33
  28. package/dist/realtime/index.js.map +1 -1
  29. package/dist/realtime-client/index.d.ts +5 -5
  30. package/dist/realtime-client/index.d.ts.map +1 -1
  31. package/dist/realtime-client/index.js +92 -69
  32. package/dist/realtime-client/index.js.map +1 -1
  33. package/dist/realtime-react/index.d.ts +17 -10
  34. package/dist/realtime-react/index.d.ts.map +1 -1
  35. package/dist/realtime-react/index.js +41 -41
  36. package/dist/realtime-react/index.js.map +1 -1
  37. package/dist/realtime-server/index.d.ts +60 -53
  38. package/dist/realtime-server/index.d.ts.map +1 -1
  39. package/dist/realtime-server/index.js +592 -485
  40. package/dist/realtime-server/index.js.map +1 -1
  41. package/dist/realtime-testing/index.d.ts +1 -2
  42. package/dist/realtime-testing/index.d.ts.map +1 -1
  43. package/dist/realtime-testing/index.js +25 -18
  44. package/dist/realtime-testing/index.js.map +1 -1
  45. package/dist/shared-room-store-COGGKqes.js +32 -0
  46. package/dist/shared-room-store-COGGKqes.js.map +1 -0
  47. package/dist/shared-room-store-D2o4ZLjC.d.ts +15 -0
  48. package/dist/shared-room-store-D2o4ZLjC.d.ts.map +1 -0
  49. package/dist/web/index.d.ts +3 -3
  50. package/dist/web/index.d.ts.map +1 -1
  51. package/dist/web/index.js +4 -3
  52. package/dist/web/index.js.map +1 -1
  53. package/package.json +12 -12
  54. package/src/internal/atom/create-regular-atom.ts +5 -4
  55. package/src/internal/atom/dispose-atom.ts +7 -2
  56. package/src/internal/atom/has-role.ts +3 -3
  57. package/src/internal/caching.ts +4 -2
  58. package/src/internal/families/create-readonly-held-selector-family.ts +2 -1
  59. package/src/internal/families/create-readonly-pure-selector-family.ts +5 -2
  60. package/src/internal/families/create-regular-atom-family.ts +2 -1
  61. package/src/internal/families/create-writable-held-selector-family.ts +2 -1
  62. package/src/internal/families/create-writable-pure-selector-family.ts +5 -2
  63. package/src/internal/families/dispose-from-store.ts +4 -4
  64. package/src/internal/families/find-in-store.ts +10 -10
  65. package/src/internal/families/get-family-of-token.ts +2 -2
  66. package/src/internal/families/index.ts +1 -0
  67. package/src/internal/families/mint-in-store.ts +54 -19
  68. package/src/internal/families/seek-in-store.ts +1 -1
  69. package/src/internal/get-state/get-fallback.ts +2 -2
  70. package/src/internal/get-state/get-from-store.ts +5 -5
  71. package/src/internal/get-state/read-or-compute-value.ts +1 -1
  72. package/src/internal/get-state/reduce-reference.ts +8 -6
  73. package/src/internal/index.ts +2 -220
  74. package/src/internal/molecule.ts +1 -2
  75. package/src/internal/mutable/create-mutable-atom-family.ts +3 -2
  76. package/src/internal/mutable/create-mutable-atom.ts +4 -2
  77. package/src/internal/mutable/get-json-family.ts +1 -1
  78. package/src/internal/mutable/get-update-family.ts +1 -1
  79. package/src/internal/mutable/tracker-family.ts +2 -1
  80. package/src/internal/mutable/tracker.ts +5 -8
  81. package/src/internal/safe-compute.ts +1 -1
  82. package/src/internal/selector/create-readonly-held-selector.ts +2 -1
  83. package/src/internal/selector/create-readonly-pure-selector.ts +2 -1
  84. package/src/internal/selector/create-writable-held-selector.ts +2 -1
  85. package/src/internal/selector/create-writable-pure-selector.ts +2 -1
  86. package/src/internal/selector/dispose-selector.ts +3 -2
  87. package/src/internal/selector/register-selector.ts +8 -5
  88. package/src/internal/selector/trace-selector-atoms.ts +2 -1
  89. package/src/internal/set-state/dispatch-state-update.ts +3 -2
  90. package/src/internal/set-state/evict-downstream.ts +1 -1
  91. package/src/internal/set-state/operate-on-store.ts +16 -22
  92. package/src/internal/set-state/reset-atom-or-selector.ts +5 -3
  93. package/src/internal/set-state/reset-in-store.ts +5 -5
  94. package/src/internal/set-state/set-atom-or-selector.ts +2 -2
  95. package/src/internal/set-state/set-atom.ts +4 -2
  96. package/src/internal/set-state/set-into-store.ts +21 -39
  97. package/src/internal/set-state/set-selector.ts +3 -2
  98. package/src/internal/state-types.ts +228 -0
  99. package/src/internal/store/deposit.ts +4 -4
  100. package/src/internal/store/index.ts +0 -1
  101. package/src/internal/store/store.ts +9 -9
  102. package/src/internal/store/withdraw.ts +4 -4
  103. package/src/internal/subscribe/recall-state.ts +1 -1
  104. package/src/internal/subscribe/subscribe-to-root-atoms.ts +1 -12
  105. package/src/internal/subscribe/subscribe-to-transaction.ts +3 -2
  106. package/src/internal/transaction/build-transaction.ts +3 -2
  107. package/src/internal/transaction/index.ts +1 -23
  108. package/src/internal/transaction/is-root-store.ts +4 -1
  109. package/src/internal/transaction/transaction-meta-progress.ts +22 -0
  110. package/src/main/atom.ts +1 -2
  111. package/src/main/find-state.ts +5 -5
  112. package/src/main/get-state.ts +4 -4
  113. package/src/main/realm.ts +2 -2
  114. package/src/main/set-state.ts +10 -10
  115. package/src/react/parse-state-overloads.ts +3 -3
  116. package/src/react/use-i.ts +6 -4
  117. package/src/react/use-loadable.ts +4 -30
  118. package/src/react/use-o.ts +6 -4
  119. package/src/react-devtools/store.ts +6 -6
  120. package/src/realtime/index.ts +1 -0
  121. package/src/realtime/mutex-store.ts +11 -0
  122. package/src/realtime/realtime-continuity.ts +1 -5
  123. package/src/realtime-client/pull-atom-family-member.ts +14 -17
  124. package/src/realtime-client/pull-atom.ts +1 -1
  125. package/src/realtime-client/pull-mutable-atom-family-member.ts +16 -12
  126. package/src/realtime-client/pull-selector-family-member.ts +8 -35
  127. package/src/realtime-client/pull-selector-roots.ts +90 -0
  128. package/src/realtime-client/pull-selector.ts +2 -27
  129. package/src/realtime-client/push-state.ts +33 -5
  130. package/src/realtime-client/realtime-client-stores/client-main-store.ts +2 -5
  131. package/src/realtime-react/index.ts +2 -1
  132. package/src/realtime-react/realtime-context.tsx +9 -5
  133. package/src/realtime-react/use-pull-atom-family-member.ts +2 -3
  134. package/src/realtime-react/use-pull-mutable-family-member.ts +2 -3
  135. package/src/realtime-react/use-pull-selector-family-member.ts +5 -6
  136. package/src/realtime-react/use-push.ts +7 -3
  137. package/src/realtime-react/use-realtime-service.ts +11 -11
  138. package/src/realtime-react/use-single-effect.ts +11 -14
  139. package/src/realtime-server/{realtime-server-stores/server-sync-store.ts → continuity/continuity-store.ts} +1 -1
  140. package/src/realtime-server/continuity/prepare-to-sync-realtime-continuity.ts +1 -1
  141. package/src/realtime-server/continuity/prepare-to-track-client-acknowledgement.ts +3 -5
  142. package/src/realtime-server/continuity/subscribe-to-continuity-actions.ts +1 -1
  143. package/src/realtime-server/employ-socket.ts +14 -0
  144. package/src/realtime-server/index.ts +2 -20
  145. package/src/realtime-server/ipc-sockets/child-socket.ts +125 -66
  146. package/src/realtime-server/ipc-sockets/custom-socket.ts +16 -14
  147. package/src/realtime-server/ipc-sockets/parent-socket.ts +81 -58
  148. package/src/realtime-server/realtime-family-provider.ts +78 -29
  149. package/src/realtime-server/realtime-mutable-family-provider.ts +80 -31
  150. package/src/realtime-server/realtime-mutable-provider.ts +30 -22
  151. package/src/realtime-server/realtime-server-stores/index.ts +0 -2
  152. package/src/realtime-server/realtime-server-stores/server-room-external-store.ts +77 -36
  153. package/src/realtime-server/realtime-server-stores/server-user-store.ts +12 -1
  154. package/src/realtime-server/realtime-state-provider.ts +30 -29
  155. package/src/realtime-server/realtime-state-receiver.ts +62 -16
  156. package/src/realtime-server/server-config.ts +9 -0
  157. package/src/realtime-server/socket-interface.ts +14 -0
  158. package/src/realtime-testing/setup-realtime-test.tsx +56 -23
  159. package/src/web/index.ts +1 -1
  160. package/src/web/{persist-sync.ts → storage-sync.ts} +5 -2
  161. package/src/internal/store/mint-or-counterfeit.ts +0 -108
  162. package/src/realtime-react/on-mount.ts +0 -5
  163. 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-hv4-hJMw.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 {
@@ -519,407 +471,9 @@ var Junction = class Junction {
519
471
  };
520
472
 
521
473
  //#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;
474
+ //#region src/internal/reserved-keys.ts
475
+ function isReservedIntrospectionKey(value) {
476
+ return value.startsWith(`🔍 `);
923
477
  }
924
478
 
925
479
  //#endregion
@@ -938,140 +492,6 @@ function actUponStore(store, token, id) {
938
492
  };
939
493
  }
940
494
 
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
1055
- };
1056
- }
1057
-
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
495
  //#endregion
1076
496
  //#region src/internal/events/ingest-atom-update.ts
1077
497
  function ingestAtomUpdateEvent(store, event, applying) {
@@ -1090,7 +510,7 @@ function getTrace(error) {
1090
510
 
1091
511
  //#endregion
1092
512
  //#region src/internal/molecule.ts
1093
- function makeRootMoleculeInStore(key, store = IMPLICIT.STORE) {
513
+ function makeRootMoleculeInStore(store, key) {
1094
514
  const molecule = {
1095
515
  key,
1096
516
  stringKey: stringifyJson(key),
@@ -1523,7 +943,7 @@ function createTransaction(store, options) {
1523
943
  }
1524
944
 
1525
945
  //#endregion
1526
- //#region src/internal/transaction/index.ts
946
+ //#region src/internal/transaction/transaction-meta-progress.ts
1527
947
  const TRANSACTION_PHASES = [
1528
948
  `idle`,
1529
949
  `building`,
@@ -1531,512 +951,142 @@ const TRANSACTION_PHASES = [
1531
951
  ];
1532
952
 
1533
953
  //#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
954
+ //#region src/internal/store/store.ts
955
+ var Store = class {
956
+ parent = null;
957
+ child = null;
958
+ valueMap = /* @__PURE__ */ new Map();
959
+ defaults = /* @__PURE__ */ new Map();
960
+ atoms = /* @__PURE__ */ new Map();
961
+ writableSelectors = /* @__PURE__ */ new Map();
962
+ readonlySelectors = /* @__PURE__ */ new Map();
963
+ atomsThatAreDefault = /* @__PURE__ */ new Set();
964
+ selectorAtoms = new Junction({
965
+ between: [`selectorKey`, `atomKey`],
966
+ cardinality: `n:n`
967
+ });
968
+ selectorGraph = new Junction({
969
+ between: [`upstreamSelectorKey`, `downstreamSelectorKey`],
970
+ cardinality: `n:n`
971
+ }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
972
+ trackers = /* @__PURE__ */ new Map();
973
+ families = /* @__PURE__ */ new Map();
974
+ joins = /* @__PURE__ */ new Map();
975
+ transactions = /* @__PURE__ */ new Map();
976
+ transactionMeta = {
977
+ epoch: /* @__PURE__ */ new Map(),
978
+ actionContinuities: new Junction({
979
+ between: [`continuity`, `action`],
980
+ cardinality: `1:n`
981
+ })
1570
982
  };
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);
983
+ timelines = /* @__PURE__ */ new Map();
984
+ timelineTopics = new Junction({
985
+ between: [`timelineKey`, `topicKey`],
986
+ cardinality: `1:n`
987
+ });
988
+ disposalTraces = new CircularBuffer(100);
989
+ molecules = /* @__PURE__ */ new Map();
990
+ moleculeJoins = new Junction({
991
+ between: [`moleculeKey`, `joinKey`],
992
+ cardinality: `n:n`
993
+ }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
994
+ moleculeGraph = new Junction({
995
+ between: [`upstreamMoleculeKey`, `downstreamMoleculeKey`],
996
+ cardinality: `n:n`
997
+ }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
998
+ moleculeData = new Junction({
999
+ between: [`moleculeKey`, `stateFamilyKey`],
1000
+ cardinality: `n:n`
1001
+ }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
1002
+ miscResources = /* @__PURE__ */ new Map();
1003
+ on = {
1004
+ atomCreation: new Subject(),
1005
+ atomDisposal: new Subject(),
1006
+ selectorCreation: new Subject(),
1007
+ selectorDisposal: new Subject(),
1008
+ timelineCreation: new Subject(),
1009
+ transactionCreation: new Subject(),
1010
+ transactionApplying: new StatefulSubject(null),
1011
+ operationClose: new Subject(),
1012
+ moleculeCreation: new Subject(),
1013
+ moleculeDisposal: new Subject()
1907
1014
  };
1908
- const mySelector = {
1909
- ...options,
1910
- type,
1911
- subject,
1912
- getFrom,
1913
- setSelf,
1914
- install: (s) => createWritablePureSelector(s, options, family)
1015
+ operation = { open: false };
1016
+ config = {
1017
+ name: `IMPLICIT_STORE`,
1018
+ lifespan: `ephemeral`
1915
1019
  };
1916
- if (family) mySelector.family = family;
1917
- target.writableSelectors.set(key, mySelector);
1918
- const token = {
1919
- key,
1920
- type
1020
+ loggers = [new AtomIOLogger(`warn`, (_, __, key) => !isReservedIntrospectionKey(key))];
1021
+ logger = {
1022
+ error: (...messages) => {
1023
+ for (const logger of this.loggers) logger.error(...messages);
1024
+ },
1025
+ info: (...messages) => {
1026
+ for (const logger of this.loggers) logger.info(...messages);
1027
+ },
1028
+ warn: (...messages) => {
1029
+ for (const logger of this.loggers) logger.warn(...messages);
1030
+ }
1921
1031
  };
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
- });
1032
+ constructor(config, store = null) {
1033
+ this.config = {
1034
+ ...store?.config,
1035
+ ...config
1036
+ };
1037
+ if (store !== null) {
1038
+ this.operation = { ...store?.operation };
1039
+ if (isRootStore(store)) this.transactionMeta = {
1040
+ epoch: new Map(store?.transactionMeta.epoch),
1041
+ actionContinuities: new Junction(store?.transactionMeta.actionContinuities.toJSON())
1042
+ };
1043
+ for (const [, family] of store.families) {
1044
+ if (family.internalRoles?.includes(`mutable`) || family.internalRoles?.includes(`join`)) continue;
1045
+ family.install(this);
1046
+ }
1047
+ const mutableHelpers = /* @__PURE__ */ new Set();
1048
+ for (const [, atom] of store.atoms) {
1049
+ if (mutableHelpers.has(atom.key)) continue;
1050
+ atom.install(this);
1051
+ if (atom.type === `mutable_atom`) {
1052
+ const originalJsonToken = getJsonToken(store, atom);
1053
+ const originalUpdateToken = getUpdateToken(atom);
1054
+ mutableHelpers.add(originalJsonToken.key);
1055
+ mutableHelpers.add(originalUpdateToken.key);
2024
1056
  }
2025
- break;
1057
+ }
1058
+ for (const [, selector] of store.readonlySelectors) selector.install(this);
1059
+ for (const [, selector] of store.writableSelectors) {
1060
+ if (mutableHelpers.has(selector.key)) continue;
1061
+ selector.install(this);
1062
+ }
1063
+ for (const [, tx] of store.transactions) tx.install(this);
1064
+ for (const [, timeline] of store.timelines) timeline.install(this);
2026
1065
  }
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
1066
  }
1067
+ };
1068
+ const IMPLICIT = { get STORE() {
1069
+ globalThis.ATOM_IO_IMPLICIT_STORE ??= new Store({
1070
+ name: `IMPLICIT_STORE`,
1071
+ lifespan: `ephemeral`
1072
+ });
1073
+ return globalThis.ATOM_IO_IMPLICIT_STORE;
1074
+ } };
1075
+ const clearStore = (store) => {
1076
+ const { config } = store;
1077
+ for (const disposable of store.miscResources.values()) disposable[Symbol.dispose]();
1078
+ Object.assign(store, new Store(config));
1079
+ store.config = config;
1080
+ };
1081
+
1082
+ //#endregion
1083
+ //#region src/internal/families/find-in-store.ts
1084
+ function findInStore(store, familyToken, key) {
1085
+ const family = withdraw(store, familyToken);
1086
+ const existingStateToken = seekInStore(store, familyToken, key);
1087
+ if (existingStateToken) return existingStateToken;
1088
+ const newStateToken = mintInStore(DO_NOT_CREATE, store, family, key);
1089
+ return newStateToken;
2040
1090
  }
2041
1091
 
2042
1092
  //#endregion
@@ -2117,19 +1167,57 @@ function createRegularAtomFamily(store, options, internalRoles) {
2117
1167
  create,
2118
1168
  default: options.default,
2119
1169
  subject,
2120
- install: (s) => createRegularAtomFamily(s, options),
2121
- internalRoles
1170
+ install: (s) => createRegularAtomFamily(s, options),
1171
+ internalRoles
1172
+ };
1173
+ store.families.set(options.key, atomFamily$1);
1174
+ if (isFn(options.default) === false) store.defaults.set(options.key, options.default);
1175
+ return familyToken;
1176
+ }
1177
+
1178
+ //#endregion
1179
+ //#region src/internal/families/create-readonly-held-selector-family.ts
1180
+ function createReadonlyHeldSelectorFamily(store, options, internalRoles) {
1181
+ const familyKey = options.key;
1182
+ const type = `readonly_held_selector_family`;
1183
+ const familyToken = {
1184
+ key: familyKey,
1185
+ type
1186
+ };
1187
+ const existing = store.families.get(familyKey);
1188
+ 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.`);
1189
+ const subject = new Subject();
1190
+ const create = (key) => {
1191
+ const subKey = stringifyJson(key);
1192
+ const family = {
1193
+ key: familyKey,
1194
+ subKey
1195
+ };
1196
+ const fullKey = `${familyKey}(${subKey})`;
1197
+ const target = newest(store);
1198
+ return createReadonlyHeldSelector(target, {
1199
+ key: fullKey,
1200
+ const: options.const(key),
1201
+ get: options.get(key)
1202
+ }, family);
1203
+ };
1204
+ const readonlySelectorFamily = {
1205
+ ...familyToken,
1206
+ create,
1207
+ internalRoles,
1208
+ subject,
1209
+ install: (s) => createReadonlyHeldSelectorFamily(s, options),
1210
+ default: options.const
2122
1211
  };
2123
- store.families.set(options.key, atomFamily$1);
2124
- if (isFn(options.default) === false) store.defaults.set(options.key, options.default);
1212
+ store.families.set(familyKey, readonlySelectorFamily);
2125
1213
  return familyToken;
2126
1214
  }
2127
1215
 
2128
1216
  //#endregion
2129
- //#region src/internal/families/create-readonly-held-selector-family.ts
2130
- function createReadonlyHeldSelectorFamily(store, options, internalRoles) {
1217
+ //#region src/internal/families/create-writable-held-selector-family.ts
1218
+ function createWritableHeldSelectorFamily(store, options, internalRoles) {
2131
1219
  const familyKey = options.key;
2132
- const type = `readonly_held_selector_family`;
1220
+ const type = `writable_held_selector_family`;
2133
1221
  const familyToken = {
2134
1222
  key: familyKey,
2135
1223
  type
@@ -2145,29 +1233,30 @@ function createReadonlyHeldSelectorFamily(store, options, internalRoles) {
2145
1233
  };
2146
1234
  const fullKey = `${familyKey}(${subKey})`;
2147
1235
  const target = newest(store);
2148
- return createReadonlyHeldSelector(target, {
1236
+ return createWritableHeldSelector(target, {
2149
1237
  key: fullKey,
2150
1238
  const: options.const(key),
2151
- get: options.get(key)
1239
+ get: options.get(key),
1240
+ set: options.set(key)
2152
1241
  }, family);
2153
1242
  };
2154
- const readonlySelectorFamily = {
1243
+ const selectorFamily$1 = {
2155
1244
  ...familyToken,
2156
1245
  create,
2157
1246
  internalRoles,
2158
1247
  subject,
2159
- install: (s) => createReadonlyHeldSelectorFamily(s, options),
1248
+ install: (s) => createWritableHeldSelectorFamily(s, options),
2160
1249
  default: options.const
2161
1250
  };
2162
- store.families.set(familyKey, readonlySelectorFamily);
1251
+ store.families.set(familyKey, selectorFamily$1);
2163
1252
  return familyToken;
2164
1253
  }
2165
1254
 
2166
1255
  //#endregion
2167
- //#region src/internal/families/create-writable-held-selector-family.ts
2168
- function createWritableHeldSelectorFamily(store, options, internalRoles) {
1256
+ //#region src/internal/families/create-writable-pure-selector-family.ts
1257
+ function createWritablePureSelectorFamily(store, options, internalRoles) {
2169
1258
  const familyKey = options.key;
2170
- const type = `writable_held_selector_family`;
1259
+ const type = `writable_pure_selector_family`;
2171
1260
  const familyToken = {
2172
1261
  key: familyKey,
2173
1262
  type
@@ -2183,352 +1272,420 @@ function createWritableHeldSelectorFamily(store, options, internalRoles) {
2183
1272
  };
2184
1273
  const fullKey = `${familyKey}(${subKey})`;
2185
1274
  const target = newest(store);
2186
- return createWritableHeldSelector(target, {
1275
+ const individualOptions = {
2187
1276
  key: fullKey,
2188
- const: options.const(key),
2189
1277
  get: options.get(key),
2190
1278
  set: options.set(key)
2191
- }, family);
1279
+ };
1280
+ if (options.catch) individualOptions.catch = options.catch;
1281
+ return createWritablePureSelector(target, individualOptions, family);
1282
+ };
1283
+ const selectorFamily$1 = {
1284
+ ...familyToken,
1285
+ create,
1286
+ internalRoles,
1287
+ subject,
1288
+ install: (s) => createWritablePureSelectorFamily(s, options),
1289
+ default: (key) => {
1290
+ const getFn = options.get(key);
1291
+ return getFn({
1292
+ get: ((...args) => getFromStore(store, ...args)),
1293
+ find: ((...args) => findInStore(store, ...args)),
1294
+ json: (token) => getJsonToken(store, token)
1295
+ });
1296
+ }
1297
+ };
1298
+ store.families.set(familyKey, selectorFamily$1);
1299
+ return familyToken;
1300
+ }
1301
+
1302
+ //#endregion
1303
+ //#region src/internal/families/create-selector-family.ts
1304
+ function createSelectorFamily(store, options) {
1305
+ const isWritable = `set` in options;
1306
+ const isHeld = `const` in options;
1307
+ if (isHeld && isWritable) return createWritableHeldSelectorFamily(store, options, void 0);
1308
+ if (isHeld) return createReadonlyHeldSelectorFamily(store, options, void 0);
1309
+ if (isWritable) return createWritablePureSelectorFamily(store, options);
1310
+ return createReadonlyPureSelectorFamily(store, options);
1311
+ }
1312
+
1313
+ //#endregion
1314
+ //#region src/internal/families/dispose-from-store.ts
1315
+ function disposeFromStore(store, ...params) {
1316
+ let token;
1317
+ if (params.length === 1) token = params[0];
1318
+ else {
1319
+ const family = params[0];
1320
+ const key = params[1];
1321
+ const maybeToken = findInStore(store, family, key);
1322
+ token = maybeToken;
1323
+ }
1324
+ try {
1325
+ withdraw(store, token);
1326
+ } catch (_) {
1327
+ store.logger.error(`❌`, token.type, token.key, `could not be disposed because it was not found in the store "${store.config.name}".`);
1328
+ return;
1329
+ }
1330
+ switch (token.type) {
1331
+ case `atom`:
1332
+ case `mutable_atom`:
1333
+ disposeAtom(store, token);
1334
+ break;
1335
+ case `writable_pure_selector`:
1336
+ case `readonly_pure_selector`:
1337
+ case `writable_held_selector`:
1338
+ case `readonly_held_selector`:
1339
+ disposeSelector(store, token);
1340
+ break;
1341
+ }
1342
+ }
1343
+
1344
+ //#endregion
1345
+ //#region src/internal/selector/update-selector-atoms.ts
1346
+ function updateSelectorAtoms(store, selectorType, selectorKey, dependency, covered) {
1347
+ const target = newest(store);
1348
+ const { type: dependencyType, key: dependencyKey } = dependency;
1349
+ if (dependencyType === `atom` || dependencyType === `mutable_atom`) {
1350
+ target.selectorAtoms.set({
1351
+ selectorKey,
1352
+ atomKey: dependencyKey
1353
+ });
1354
+ store.logger.info(`🔍`, selectorType, selectorKey, `discovers root atom "${dependencyKey}"`);
1355
+ } else {
1356
+ const rootKeys = traceRootSelectorAtoms(store, dependencyKey, covered);
1357
+ store.logger.info(`🔍`, selectorType, selectorKey, `discovers root atoms: [ ${[...rootKeys.values()].map((root) => `"${root.key}"`).join(`, `)} ]`);
1358
+ for (const { key: atomKey } of rootKeys.values()) target.selectorAtoms = target.selectorAtoms.set({
1359
+ selectorKey,
1360
+ atomKey
1361
+ });
1362
+ }
1363
+ covered.add(dependencyKey);
1364
+ }
1365
+
1366
+ //#endregion
1367
+ //#region src/internal/selector/register-selector.ts
1368
+ function registerSelector(store, selectorType, selectorKey, covered) {
1369
+ return {
1370
+ get: (...params) => {
1371
+ const target = newest(store);
1372
+ const { token, family, subKey } = reduceReference(store, ...params);
1373
+ let dependencyValue;
1374
+ if (`counterfeit` in token && family && subKey) dependencyValue = getFallback(store, token, family, subKey);
1375
+ else {
1376
+ const dependency = withdraw(store, token);
1377
+ dependencyValue = readOrComputeValue(store, dependency);
1378
+ }
1379
+ store.logger.info(`🔌`, selectorType, selectorKey, `registers dependency ( "${token.key}" =`, dependencyValue, `)`);
1380
+ target.selectorGraph.set({
1381
+ upstreamSelectorKey: token.key,
1382
+ downstreamSelectorKey: selectorKey
1383
+ }, { source: token.key });
1384
+ updateSelectorAtoms(store, selectorType, selectorKey, token, covered);
1385
+ return dependencyValue;
1386
+ },
1387
+ set: ((...params) => {
1388
+ const target = newest(store);
1389
+ operateOnStore(JOIN_OP, target, ...params);
1390
+ }),
1391
+ find: ((...args) => findInStore(store, ...args)),
1392
+ json: (token) => getJsonToken(store, token)
1393
+ };
1394
+ }
1395
+
1396
+ //#endregion
1397
+ //#region src/internal/selector/create-readonly-held-selector.ts
1398
+ function createReadonlyHeldSelector(store, options, family) {
1399
+ const target = newest(store);
1400
+ const subject = new Subject();
1401
+ const covered = /* @__PURE__ */ new Set();
1402
+ const { key, const: constant } = options;
1403
+ const type = `readonly_held_selector`;
1404
+ store.logger.info(`🔨`, type, key, `is being created`);
1405
+ const { get, find, json } = registerSelector(target, type, key, covered);
1406
+ const getFrom = (innerTarget) => {
1407
+ const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
1408
+ for (const [downstreamSelectorKey, { source }] of upstreamStates) if (source !== key) innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
1409
+ innerTarget.selectorAtoms.delete(key);
1410
+ options.get({
1411
+ get,
1412
+ find,
1413
+ json
1414
+ }, constant);
1415
+ writeToCache(innerTarget, readonlySelector, constant);
1416
+ store.logger.info(`✨`, type, key, `=`, constant);
1417
+ covered.clear();
1418
+ return constant;
1419
+ };
1420
+ const readonlySelector = {
1421
+ ...options,
1422
+ type,
1423
+ subject,
1424
+ getFrom,
1425
+ install: (s) => createReadonlyHeldSelector(s, options, family)
1426
+ };
1427
+ if (family) readonlySelector.family = family;
1428
+ target.readonlySelectors.set(key, readonlySelector);
1429
+ const token = {
1430
+ key,
1431
+ type
1432
+ };
1433
+ if (family) token.family = family;
1434
+ return token;
1435
+ }
1436
+
1437
+ //#endregion
1438
+ //#region src/internal/selector/create-readonly-pure-selector.ts
1439
+ function createReadonlyPureSelector(store, options, family) {
1440
+ const target = newest(store);
1441
+ const subject = new Subject();
1442
+ const covered = /* @__PURE__ */ new Set();
1443
+ const key = options.key;
1444
+ const type = `readonly_pure_selector`;
1445
+ store.logger.info(`🔨`, type, key, `is being created`);
1446
+ const { get, find, json } = registerSelector(target, type, key, covered);
1447
+ const getFrom = () => {
1448
+ const innerTarget = newest(store);
1449
+ const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
1450
+ for (const [downstreamSelectorKey, { source }] of upstreamStates) if (source !== key) innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
1451
+ innerTarget.selectorAtoms.delete(key);
1452
+ const value = options.get({
1453
+ get,
1454
+ find,
1455
+ json
1456
+ });
1457
+ const cached = writeToCache(innerTarget, readonlySelector, value);
1458
+ store.logger.info(`✨`, type, key, `=`, cached);
1459
+ covered.clear();
1460
+ return cached;
1461
+ };
1462
+ const readonlySelector = {
1463
+ ...options,
1464
+ type,
1465
+ subject,
1466
+ getFrom,
1467
+ install: (s) => createReadonlyPureSelector(s, options, family)
1468
+ };
1469
+ if (family) readonlySelector.family = family;
1470
+ target.readonlySelectors.set(key, readonlySelector);
1471
+ const token = {
1472
+ key,
1473
+ type
1474
+ };
1475
+ if (family) token.family = family;
1476
+ return token;
1477
+ }
1478
+
1479
+ //#endregion
1480
+ //#region src/internal/selector/create-writable-held-selector.ts
1481
+ function createWritableHeldSelector(store, options, family) {
1482
+ const target = newest(store);
1483
+ const subject = new Subject();
1484
+ const covered = /* @__PURE__ */ new Set();
1485
+ const { key, const: constant } = options;
1486
+ const type = `writable_held_selector`;
1487
+ store.logger.info(`🔨`, type, key, `is being created`);
1488
+ const setterToolkit = registerSelector(target, type, key, covered);
1489
+ const { find, get, json } = setterToolkit;
1490
+ const getterToolkit = {
1491
+ find,
1492
+ get,
1493
+ json
1494
+ };
1495
+ const getFrom = (innerTarget) => {
1496
+ const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
1497
+ for (const [downstreamSelectorKey, { source }] of upstreamStates) if (source !== key) innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
1498
+ innerTarget.selectorAtoms.delete(key);
1499
+ options.get(getterToolkit, constant);
1500
+ writeToCache(innerTarget, mySelector, constant);
1501
+ store.logger.info(`✨`, type, key, `=`, constant);
1502
+ covered.clear();
1503
+ return constant;
2192
1504
  };
2193
- const selectorFamily$1 = {
2194
- ...familyToken,
2195
- create,
2196
- internalRoles,
1505
+ const setSelf = () => {
1506
+ options.set(setterToolkit, constant);
1507
+ };
1508
+ const mySelector = {
1509
+ ...options,
1510
+ type,
2197
1511
  subject,
2198
- install: (s) => createWritableHeldSelectorFamily(s, options),
2199
- default: options.const
1512
+ getFrom,
1513
+ setSelf,
1514
+ install: (s) => createWritableHeldSelector(s, options, family)
2200
1515
  };
2201
- store.families.set(familyKey, selectorFamily$1);
2202
- return familyToken;
1516
+ if (family) mySelector.family = family;
1517
+ target.writableSelectors.set(key, mySelector);
1518
+ const token = {
1519
+ key,
1520
+ type
1521
+ };
1522
+ if (family) token.family = family;
1523
+ return token;
2203
1524
  }
2204
1525
 
2205
1526
  //#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.`);
1527
+ //#region src/internal/selector/create-writable-pure-selector.ts
1528
+ function createWritablePureSelector(store, options, family) {
1529
+ const target = newest(store);
2216
1530
  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);
1531
+ const covered = /* @__PURE__ */ new Set();
1532
+ const key = options.key;
1533
+ const type = `writable_pure_selector`;
1534
+ store.logger.info(`🔨`, type, key, `is being created`);
1535
+ const setterToolkit = registerSelector(target, type, key, covered);
1536
+ const { find, get, json } = setterToolkit;
1537
+ const getterToolkit = {
1538
+ find,
1539
+ get,
1540
+ json
2232
1541
  };
2233
- const selectorFamily$1 = {
2234
- ...familyToken,
2235
- create,
2236
- internalRoles,
1542
+ const getFrom = (innerTarget) => {
1543
+ const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
1544
+ for (const [downstreamSelectorKey, { source }] of upstreamStates) if (source !== key) innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
1545
+ innerTarget.selectorAtoms.delete(key);
1546
+ const value = options.get(getterToolkit);
1547
+ const cached = writeToCache(innerTarget, mySelector, value);
1548
+ store.logger.info(`✨`, type, key, `=`, cached);
1549
+ covered.clear();
1550
+ return cached;
1551
+ };
1552
+ const setSelf = (newValue) => {
1553
+ options.set(setterToolkit, newValue);
1554
+ };
1555
+ const mySelector = {
1556
+ ...options,
1557
+ type,
2237
1558
  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
- }
1559
+ getFrom,
1560
+ setSelf,
1561
+ install: (s) => createWritablePureSelector(s, options, family)
2247
1562
  };
2248
- store.families.set(familyKey, selectorFamily$1);
2249
- return familyToken;
1563
+ if (family) mySelector.family = family;
1564
+ target.writableSelectors.set(key, mySelector);
1565
+ const token = {
1566
+ key,
1567
+ type
1568
+ };
1569
+ if (family) token.family = family;
1570
+ return token;
2250
1571
  }
2251
1572
 
2252
1573
  //#endregion
2253
- //#region src/internal/families/create-selector-family.ts
2254
- function createSelectorFamily(store, options) {
1574
+ //#region src/internal/selector/create-standalone-selector.ts
1575
+ function createStandaloneSelector(store, options) {
2255
1576
  const isWritable = `set` in options;
2256
1577
  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);
2261
- }
2262
-
2263
- //#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})`;
2268
- 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;
2296
- }
2297
-
2298
- //#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;
1578
+ if (isHeld && isWritable) {
1579
+ const state$1 = createWritableHeldSelector(store, options, void 0);
1580
+ store.on.selectorCreation.next(state$1);
1581
+ return state$1;
2308
1582
  }
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;
1583
+ if (isHeld) {
1584
+ const state$1 = createReadonlyHeldSelector(store, options, void 0);
1585
+ store.on.selectorCreation.next(state$1);
1586
+ return state$1;
2314
1587
  }
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;
1588
+ if (isWritable) {
1589
+ const state$1 = createWritablePureSelector(store, options, void 0);
1590
+ store.on.selectorCreation.next(state$1);
1591
+ return state$1;
2326
1592
  }
1593
+ const state = createReadonlyPureSelector(store, options, void 0);
1594
+ store.on.selectorCreation.next(state);
1595
+ return state;
2327
1596
  }
2328
1597
 
2329
1598
  //#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`:
1599
+ //#region src/internal/selector/dispose-selector.ts
1600
+ function disposeSelector(store, selectorToken) {
1601
+ const target = newest(store);
1602
+ const { key, type, family: familyMeta } = selectorToken;
1603
+ if (!familyMeta) store.logger.error(`❌`, type, key, `Standalone selectors cannot be disposed.`);
1604
+ else {
1605
+ const molecule = target.molecules.get(familyMeta.subKey);
1606
+ if (molecule) target.moleculeData.delete(familyMeta.subKey, familyMeta.key);
1607
+ let familyToken;
1608
+ switch (selectorToken.type) {
2376
1609
  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
- }
2404
- }
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);
1610
+ {
1611
+ target.writableSelectors.delete(key);
1612
+ familyToken = {
1613
+ key: familyMeta.key,
1614
+ type: `writable_held_selector_family`
1615
+ };
1616
+ const family = withdraw(store, familyToken);
1617
+ family.subject.next({
1618
+ type: `state_disposal`,
1619
+ subType: `selector`,
1620
+ token: selectorToken,
1621
+ timestamp: Date.now()
1622
+ });
2465
1623
  }
2466
- }
2467
- for (const [atomKey, atom] of dependencies) rootSubs.set(atomKey, subscribeToRootDependency(store, state, atom));
2468
- safelyHandleUpdate(update);
2469
- };
2470
- }
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;
2478
- }
2479
-
2480
- //#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);
2490
1624
  break;
2491
1625
  case `writable_pure_selector`:
2492
- case `writable_held_selector`:
2493
- withdrawn = target.writableSelectors.get(token.key);
1626
+ {
1627
+ target.writableSelectors.delete(key);
1628
+ familyToken = {
1629
+ key: familyMeta.key,
1630
+ type: `writable_pure_selector_family`
1631
+ };
1632
+ const family = withdraw(store, familyToken);
1633
+ family.subject.next({
1634
+ type: `state_disposal`,
1635
+ subType: `selector`,
1636
+ token: selectorToken,
1637
+ timestamp: Date.now()
1638
+ });
1639
+ }
2494
1640
  break;
2495
- case `readonly_pure_selector`:
2496
1641
  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);
1642
+ {
1643
+ target.readonlySelectors.delete(key);
1644
+ familyToken = {
1645
+ key: familyMeta.key,
1646
+ type: `readonly_held_selector_family`
1647
+ };
1648
+ const family = withdraw(store, familyToken);
1649
+ family.subject.next({
1650
+ type: `state_disposal`,
1651
+ subType: `selector`,
1652
+ token: selectorToken,
1653
+ timestamp: Date.now()
1654
+ });
1655
+ }
2509
1656
  break;
2510
- case `transaction`:
2511
- withdrawn = target.transactions.get(token.key);
1657
+ case `readonly_pure_selector`:
1658
+ {
1659
+ target.readonlySelectors.delete(key);
1660
+ familyToken = {
1661
+ key: familyMeta.key,
1662
+ type: `readonly_pure_selector_family`
1663
+ };
1664
+ const family = withdraw(store, familyToken);
1665
+ family.subject.next({
1666
+ type: `state_disposal`,
1667
+ subType: `selector`,
1668
+ token: selectorToken,
1669
+ timestamp: Date.now()
1670
+ });
1671
+ }
2512
1672
  break;
2513
1673
  }
2514
- if (withdrawn) return withdrawn;
2515
- target = target.child;
1674
+ target.valueMap.delete(key);
1675
+ target.selectorAtoms.delete(key);
1676
+ target.selectorGraph.delete(key);
1677
+ target.moleculeData.delete(familyMeta.key, familyMeta.subKey);
1678
+ store.logger.info(`🔥`, selectorToken.type, key, `deleted`);
1679
+ if (isChildStore(target) && target.transactionMeta.phase === `building`) target.transactionMeta.update.subEvents.push({
1680
+ type: `state_disposal`,
1681
+ subType: `selector`,
1682
+ token: selectorToken,
1683
+ timestamp: Date.now()
1684
+ });
1685
+ else store.on.selectorDisposal.next(selectorToken);
2516
1686
  }
2517
- throw new NotFoundError(token, store);
2518
1687
  }
2519
1688
 
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
1689
  //#endregion
2533
1690
  //#region src/internal/subscribe/subscribe-to-transaction.ts
2534
1691
  const subscribeToTransaction = (store, token, key, handleUpdate) => {
@@ -2556,98 +1713,6 @@ function subscribeInStore(store, token, handleUpdate, key = arbitrary()) {
2556
1713
  }
2557
1714
  }
2558
1715
 
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
1716
  //#endregion
2652
1717
  //#region src/internal/mutable/create-mutable-atom.ts
2653
1718
  function createMutableAtom(store, options, family) {
@@ -2840,191 +1905,6 @@ const getUpdateToken = (mutableAtomToken) => {
2840
1905
  return updateToken;
2841
1906
  };
2842
1907
 
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
1908
  //#endregion
3029
1909
  //#region src/internal/atom/dispose-atom.ts
3030
1910
  function disposeAtom(store, atomToken) {
@@ -3069,14 +1949,6 @@ function disposeAtom(store, atomToken) {
3069
1949
  }
3070
1950
  }
3071
1951
 
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
1952
  //#endregion
3081
1953
  //#region src/internal/capitalize.ts
3082
1954
  function capitalize(string) {
@@ -3571,20 +2443,6 @@ function getInternalRelationsFromStore(token, store) {
3571
2443
  return family;
3572
2444
  }
3573
2445
 
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(`🔍 `);
3586
- }
3587
-
3588
2446
  //#endregion
3589
2447
  //#region src/internal/timeline/create-timeline.ts
3590
2448
  function createTimeline(store, options, data) {
@@ -3863,5 +2721,5 @@ const timeTravel = (store, action, token) => {
3863
2721
  };
3864
2722
 
3865
2723
  //#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 };
2724
+ 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
2725
  //# sourceMappingURL=index.js.map