atom.io 0.40.7 → 0.40.9

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 (104) hide show
  1. package/dist/{chunk-Cl8Af3a2.js → chunk-CTAAG5j7.js} +3 -1
  2. package/dist/data/index.js +1 -2
  3. package/dist/data/index.js.map +1 -1
  4. package/dist/eslint-plugin/index.js +2 -3
  5. package/dist/eslint-plugin/index.js.map +1 -1
  6. package/dist/internal/index.d.ts +4 -3
  7. package/dist/internal/index.d.ts.map +1 -1
  8. package/dist/internal/index.js +1231 -176
  9. package/dist/internal/index.js.map +1 -1
  10. package/dist/introspection/index.d.ts.map +1 -1
  11. package/dist/introspection/index.js +13 -32
  12. package/dist/introspection/index.js.map +1 -1
  13. package/dist/json/index.d.ts.map +1 -1
  14. package/dist/json/index.js.map +1 -1
  15. package/dist/main/index.d.ts.map +1 -1
  16. package/dist/main/index.js +1 -2
  17. package/dist/main/index.js.map +1 -1
  18. package/dist/react/index.d.ts.map +1 -1
  19. package/dist/react/index.js.map +1 -1
  20. package/dist/react-devtools/index.d.ts.map +1 -1
  21. package/dist/react-devtools/index.js +2 -4
  22. package/dist/react-devtools/index.js.map +1 -1
  23. package/dist/realtime/index.d.ts +29 -5
  24. package/dist/realtime/index.d.ts.map +1 -1
  25. package/dist/realtime/index.js +47 -5
  26. package/dist/realtime/index.js.map +1 -1
  27. package/dist/realtime-client/index.d.ts +2 -6
  28. package/dist/realtime-client/index.d.ts.map +1 -1
  29. package/dist/realtime-client/index.js +6 -22
  30. package/dist/realtime-client/index.js.map +1 -1
  31. package/dist/realtime-react/index.d.ts +6 -9
  32. package/dist/realtime-react/index.d.ts.map +1 -1
  33. package/dist/realtime-react/index.js +4 -16
  34. package/dist/realtime-react/index.js.map +1 -1
  35. package/dist/realtime-server/index.d.ts +38 -57
  36. package/dist/realtime-server/index.d.ts.map +1 -1
  37. package/dist/realtime-server/index.js +128 -178
  38. package/dist/realtime-server/index.js.map +1 -1
  39. package/dist/realtime-testing/index.d.ts +2 -0
  40. package/dist/realtime-testing/index.d.ts.map +1 -1
  41. package/dist/realtime-testing/index.js +15 -9
  42. package/dist/realtime-testing/index.js.map +1 -1
  43. package/dist/transceivers/set-rtx/index.d.ts +1 -1
  44. package/dist/transceivers/set-rtx/index.d.ts.map +1 -1
  45. package/dist/transceivers/set-rtx/index.js +5 -9
  46. package/dist/transceivers/set-rtx/index.js.map +1 -1
  47. package/dist/transceivers/u-list/index.d.ts +29 -0
  48. package/dist/transceivers/u-list/index.d.ts.map +1 -0
  49. package/dist/transceivers/u-list/index.js +87 -0
  50. package/dist/transceivers/u-list/index.js.map +1 -0
  51. package/dist/web/index.js.map +1 -1
  52. package/package.json +17 -13
  53. package/src/internal/mutable/tracker.ts +61 -46
  54. package/src/internal/mutable/transceiver.ts +4 -4
  55. package/src/internal/set-state/index.ts +1 -0
  56. package/src/internal/subscribe/subscribe-to-state.ts +9 -0
  57. package/src/{realtime-server → realtime}/employ-socket.ts +2 -2
  58. package/src/realtime/index.ts +2 -0
  59. package/src/realtime/shared-room-store.ts +12 -11
  60. package/src/realtime-client/continuity/register-and-attempt-confirmed-update.ts +1 -1
  61. package/src/realtime-client/index.ts +0 -1
  62. package/src/realtime-client/push-state.ts +1 -2
  63. package/src/realtime-react/index.ts +0 -1
  64. package/src/realtime-react/use-single-effect.ts +1 -1
  65. package/src/realtime-server/continuity/continuity-store.ts +2 -27
  66. package/src/realtime-server/continuity/provide-continuity.ts +50 -0
  67. package/src/realtime-server/continuity/{subscribe-to-continuity-actions.ts → provide-outcomes.ts} +16 -14
  68. package/src/realtime-server/continuity/{subscribe-to-continuity-perpectives.ts → provide-perspectives.ts} +11 -10
  69. package/src/realtime-server/continuity/{prepare-to-send-initial-payload.ts → provide-startup-payloads.ts} +8 -6
  70. package/src/realtime-server/continuity/receive-action-requests.ts +66 -0
  71. package/src/realtime-server/continuity/{prepare-to-track-client-acknowledgement.ts → track-acknowledgements.ts} +15 -9
  72. package/src/realtime-server/index.ts +1 -3
  73. package/src/realtime-server/ipc-sockets/custom-socket.ts +4 -5
  74. package/src/realtime-server/ipc-sockets/parent-socket.ts +21 -17
  75. package/src/realtime-server/realtime-family-provider.ts +1 -1
  76. package/src/realtime-server/realtime-mutable-family-provider.ts +1 -1
  77. package/src/realtime-server/realtime-mutable-provider.ts +1 -1
  78. package/src/realtime-server/realtime-server-stores/server-room-external-store.ts +2 -2
  79. package/src/realtime-server/realtime-server-stores/server-user-store.ts +8 -9
  80. package/src/realtime-server/realtime-state-provider.ts +1 -1
  81. package/src/realtime-server/realtime-state-receiver.ts +3 -6
  82. package/src/realtime-server/server-config.ts +1 -3
  83. package/src/realtime-testing/setup-realtime-test.tsx +23 -18
  84. package/src/transceivers/set-rtx/set-rtx.ts +3 -3
  85. package/src/transceivers/u-list/index.ts +1 -0
  86. package/src/transceivers/u-list/u-list.ts +123 -0
  87. package/dist/employ-socket-D6wgByWh.js +0 -12
  88. package/dist/employ-socket-D6wgByWh.js.map +0 -1
  89. package/dist/has-role-hv4-hJMw.js +0 -1149
  90. package/dist/has-role-hv4-hJMw.js.map +0 -1
  91. package/dist/is-fn-DY1wZ-md.js +0 -10
  92. package/dist/is-fn-DY1wZ-md.js.map +0 -1
  93. package/dist/mutex-store-CSvxY9i3.js +0 -11
  94. package/dist/mutex-store-CSvxY9i3.js.map +0 -1
  95. package/dist/shared-room-store-COGGKqes.js +0 -32
  96. package/dist/shared-room-store-COGGKqes.js.map +0 -1
  97. package/dist/shared-room-store-D2o4ZLjC.d.ts +0 -15
  98. package/dist/shared-room-store-D2o4ZLjC.d.ts.map +0 -1
  99. package/src/realtime-client/server-action.ts +0 -23
  100. package/src/realtime-react/use-server-action.ts +0 -19
  101. package/src/realtime-server/continuity/prepare-to-serve-transaction-request.ts +0 -59
  102. package/src/realtime-server/continuity/prepare-to-sync-realtime-continuity.ts +0 -145
  103. package/src/realtime-server/realtime-action-receiver.ts +0 -40
  104. /package/src/{realtime-server → realtime}/socket-interface.ts +0 -0
@@ -1,5 +1,3 @@
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";
3
1
  import { Anarchy, AtomIOLogger, PRETTY_TOKEN_TYPES } from "atom.io";
4
2
  import { parseJson, stringifyJson } from "atom.io/json";
5
3
  import { SetRTX } from "atom.io/transceivers/set-rtx";
@@ -9,6 +7,120 @@ function arbitrary(random = Math.random) {
9
7
  return random().toString(36).slice(2);
10
8
  }
11
9
 
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
+ //#endregion
22
+ //#region src/internal/is-fn.ts
23
+ const NON_CTOR_FN_REGEX = /^\[object (?:Async|Generator|AsyncGenerator)?Function\]$/;
24
+ function isFn(input) {
25
+ const protoString = Object.prototype.toString.call(input);
26
+ return NON_CTOR_FN_REGEX.test(protoString);
27
+ }
28
+
29
+ //#endregion
30
+ //#region src/internal/set-state/become.ts
31
+ function become(nextVersionOfThing, originalThing) {
32
+ if (isFn(nextVersionOfThing)) return nextVersionOfThing(originalThing);
33
+ return nextVersionOfThing;
34
+ }
35
+
36
+ //#endregion
37
+ //#region src/internal/future.ts
38
+ /**
39
+ * A Promise whose incoming value can be hot swapped.
40
+ * @internal
41
+ * @private
42
+ * @typeParam T The type of the value that the promise will resolve to.
43
+ *
44
+ * @remarks
45
+ * Can be constructed like a Promise, or from an existing Promise.
46
+ */
47
+ var Future = class extends Promise {
48
+ fate;
49
+ resolve;
50
+ reject;
51
+ done = false;
52
+ constructor(executor) {
53
+ let superResolve;
54
+ let superReject;
55
+ super((resolve, reject) => {
56
+ superResolve = resolve;
57
+ superReject = reject;
58
+ });
59
+ this.resolve = superResolve;
60
+ this.reject = superReject;
61
+ this.use(executor instanceof Promise ? executor : new Promise(executor));
62
+ }
63
+ pass(promise, value) {
64
+ if (promise === this.fate) {
65
+ this.resolve(value);
66
+ this.done = true;
67
+ }
68
+ }
69
+ fail(promise, reason) {
70
+ if (promise === this.fate) {
71
+ this.reject(reason);
72
+ this.done = true;
73
+ }
74
+ }
75
+ use(value) {
76
+ if (this === value) return;
77
+ if (value instanceof Promise) {
78
+ const promise = value;
79
+ this.fate = promise;
80
+ promise.then((resolved) => {
81
+ this.pass(promise, resolved);
82
+ }, (reason) => {
83
+ this.fail(promise, reason);
84
+ });
85
+ } else {
86
+ this.resolve(value);
87
+ this.fate = void 0;
88
+ }
89
+ }
90
+ };
91
+
92
+ //#endregion
93
+ //#region src/internal/subject.ts
94
+ var Subject = class {
95
+ Subscriber;
96
+ subscribers = /* @__PURE__ */ new Map();
97
+ subscribe(key, subscriber) {
98
+ this.subscribers.set(key, subscriber);
99
+ const unsubscribe = () => {
100
+ this.unsubscribe(key);
101
+ };
102
+ return unsubscribe;
103
+ }
104
+ unsubscribe(key) {
105
+ this.subscribers.delete(key);
106
+ }
107
+ next(value) {
108
+ const subscribers = this.subscribers.values();
109
+ for (const subscriber of subscribers) subscriber(value);
110
+ }
111
+ };
112
+ var StatefulSubject = class extends Subject {
113
+ state;
114
+ constructor(initialState) {
115
+ super();
116
+ this.state = initialState;
117
+ }
118
+ next(value) {
119
+ this.state = value;
120
+ super.next(value);
121
+ }
122
+ };
123
+
12
124
  //#endregion
13
125
  //#region src/internal/store/circular-buffer.ts
14
126
  var CircularBuffer = class CircularBuffer {
@@ -37,6 +149,17 @@ var CircularBuffer = class CircularBuffer {
37
149
  }
38
150
  };
39
151
 
152
+ //#endregion
153
+ //#region src/internal/store/deposit.ts
154
+ function deposit(state) {
155
+ const token = {
156
+ key: state.key,
157
+ type: state.type
158
+ };
159
+ if (`family` in state) token.family = state.family;
160
+ return token;
161
+ }
162
+
40
163
  //#endregion
41
164
  //#region src/internal/overlays/map-overlay.ts
42
165
  var MapOverlay = class extends Map {
@@ -48,13 +171,8 @@ var MapOverlay = class extends Map {
48
171
  this.source = source;
49
172
  }
50
173
  get(key) {
51
- const has = super.has(key);
52
- if (has) return super.get(key);
53
- if (!this.deleted.has(key) && this.source.has(key)) {
54
- const value = this.source.get(key);
55
- return value;
56
- }
57
- return void 0;
174
+ if (super.has(key)) return super.get(key);
175
+ if (!this.deleted.has(key) && this.source.has(key)) return this.source.get(key);
58
176
  }
59
177
  set(key, value) {
60
178
  this.deleted.delete(key);
@@ -156,15 +274,13 @@ var RelationsOverlay = class extends Map {
156
274
  this.source = source;
157
275
  }
158
276
  get(key) {
159
- const has = super.has(key);
160
- if (has) return super.get(key);
277
+ if (super.has(key)) return super.get(key);
161
278
  if (!this.deleted.has(key) && this.source.has(key)) {
162
279
  const value = this.source.get(key);
163
280
  const valueOverlay = new SetOverlay(value);
164
281
  super.set(key, valueOverlay);
165
282
  return valueOverlay;
166
283
  }
167
- return void 0;
168
284
  }
169
285
  set(key, value) {
170
286
  this.deleted.delete(key);
@@ -438,10 +554,7 @@ var Junction = class Junction {
438
554
  return [];
439
555
  }
440
556
  has(a, b) {
441
- if (b) {
442
- const setA = this.getRelatedKeys(a);
443
- return setA?.has(b) ?? false;
444
- }
557
+ if (b) return this.getRelatedKeys(a)?.has(b) ?? false;
445
558
  return this.relations.has(a);
446
559
  }
447
560
  overlay() {
@@ -487,8 +600,7 @@ const abortTransaction = (target) => {
487
600
  //#region src/internal/transaction/act-upon-store.ts
488
601
  function actUponStore(store, token, id) {
489
602
  return (...parameters) => {
490
- const tx = withdraw(store, token);
491
- return tx.run(parameters, id);
603
+ return withdraw(store, token).run(parameters, id);
492
604
  };
493
605
  }
494
606
 
@@ -496,8 +608,7 @@ function actUponStore(store, token, id) {
496
608
  //#region src/internal/events/ingest-atom-update.ts
497
609
  function ingestAtomUpdateEvent(store, event, applying) {
498
610
  const { token, update: { newValue, oldValue } } = event;
499
- const value = applying === `newValue` ? newValue : oldValue;
500
- setIntoStore(store, token, value);
611
+ setIntoStore(store, token, applying === `newValue` ? newValue : oldValue);
501
612
  }
502
613
 
503
614
  //#endregion
@@ -526,14 +637,12 @@ function allocateIntoStore(store, provenance, key, dependsOn = `any`) {
526
637
  const target = newest(store);
527
638
  if (Array.isArray(origin)) for (const formerClaim of origin) {
528
639
  const claimString = stringifyJson(formerClaim);
529
- const claim = target.molecules.get(claimString);
530
- if (claim) store.moleculeGraph.set(claimString, stringKey, { source: claimString });
640
+ if (target.molecules.get(claimString)) store.moleculeGraph.set(claimString, stringKey, { source: claimString });
531
641
  else invalidKeys.push(claimString);
532
642
  }
533
643
  else {
534
644
  const claimString = stringifyJson(origin);
535
- const claim = target.molecules.get(claimString);
536
- if (claim) store.moleculeGraph.set(claimString, stringKey, { source: claimString });
645
+ if (target.molecules.get(claimString)) store.moleculeGraph.set(claimString, stringKey, { source: claimString });
537
646
  else invalidKeys.push(claimString);
538
647
  }
539
648
  if (invalidKeys.length === 0) target.molecules.set(stringKey, {
@@ -547,8 +656,7 @@ function allocateIntoStore(store, provenance, key, dependsOn = `any`) {
547
656
  provenance: origin,
548
657
  timestamp: Date.now()
549
658
  };
550
- const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
551
- if (isTransaction) target.transactionMeta.update.subEvents.push(creationEvent);
659
+ if (isChildStore(target) && target.transactionMeta.phase === `building`) target.transactionMeta.update.subEvents.push(creationEvent);
552
660
  else target.on.moleculeCreation.next(creationEvent);
553
661
  for (const claim of invalidKeys) {
554
662
  const disposal = store.disposalTraces.buffer.find((item) => item?.key === claim);
@@ -558,8 +666,7 @@ function allocateIntoStore(store, provenance, key, dependsOn = `any`) {
558
666
  }
559
667
  function fuseWithinStore(store, type, sideA, sideB) {
560
668
  const compoundKey = `T$--${type}==${sideA}++${sideB}`;
561
- const above = [sideA, sideB];
562
- allocateIntoStore(store, above, compoundKey, `all`);
669
+ allocateIntoStore(store, [sideA, sideB], compoundKey, `all`);
563
670
  return compoundKey;
564
671
  }
565
672
  function createDeallocateTX(store) {
@@ -657,8 +764,7 @@ function claimWithinStore(store, newProvenance, claim, exclusive) {
657
764
  to: [newProvenanceMolecule.key],
658
765
  timestamp: Date.now()
659
766
  };
660
- const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
661
- if (isTransaction) target.transactionMeta.update.subEvents.push(transferEvent);
767
+ if (isChildStore(target) && target.transactionMeta.phase === `building`) target.transactionMeta.update.subEvents.push(transferEvent);
662
768
  return claim;
663
769
  }
664
770
 
@@ -777,19 +883,26 @@ function ingestTransactionOutcomeEvent(store, event, applying) {
777
883
  }
778
884
  }
779
885
 
886
+ //#endregion
887
+ //#region src/internal/transaction/is-root-store.ts
888
+ function isRootStore(store) {
889
+ return `epoch` in store.transactionMeta;
890
+ }
891
+ function isChildStore(store) {
892
+ return `phase` in store.transactionMeta;
893
+ }
894
+
780
895
  //#endregion
781
896
  //#region src/internal/transaction/get-epoch-number.ts
782
897
  function getContinuityKey(store, transactionKey) {
783
- const continuity = store.transactionMeta.actionContinuities.getRelatedKey(transactionKey);
784
- return continuity;
898
+ return store.transactionMeta.actionContinuities.getRelatedKey(transactionKey);
785
899
  }
786
900
  function getEpochNumberOfContinuity(store, continuityKey) {
787
- const epoch = store.transactionMeta.epoch.get(continuityKey);
788
- return epoch;
901
+ return store.transactionMeta.epoch.get(continuityKey);
789
902
  }
790
903
  function getEpochNumberOfAction(store, transactionKey) {
791
904
  const continuityKey = getContinuityKey(store, transactionKey);
792
- if (continuityKey === void 0) return void 0;
905
+ if (continuityKey === void 0) return;
793
906
  return getEpochNumberOfContinuity(store, continuityKey);
794
907
  }
795
908
 
@@ -817,11 +930,10 @@ function applyTransaction(store, output) {
817
930
  ingestTransactionOutcomeEvent(parent, child.transactionMeta.update, `newValue`);
818
931
  if (isRootStore(parent)) {
819
932
  setEpochNumberOfAction(parent, child.transactionMeta.update.token.key, child.transactionMeta.update.epoch);
820
- const myTransaction = withdraw(store, {
933
+ withdraw(store, {
821
934
  key: child.transactionMeta.update.token.key,
822
935
  type: `transaction`
823
- });
824
- myTransaction?.subject.next(child.transactionMeta.update);
936
+ })?.subject.next(child.transactionMeta.update);
825
937
  store.logger.info(`🛬`, `transaction`, child.transactionMeta.update.token.key, `applied`);
826
938
  } else if (isChildStore(parent)) parent.transactionMeta.update.subEvents.push(child.transactionMeta.update);
827
939
  parent.on.transactionApplying.next(null);
@@ -920,14 +1032,14 @@ function createTransaction(store, options) {
920
1032
  type: `transaction`,
921
1033
  run: (params, id) => {
922
1034
  const token$1 = deposit(newTransaction);
923
- const target$1 = buildTransaction(store, token$1, params, id);
1035
+ const target = buildTransaction(store, token$1, params, id);
924
1036
  try {
925
- const { toolkit } = target$1.transactionMeta;
1037
+ const { toolkit } = target.transactionMeta;
926
1038
  const output = options.do(toolkit, ...params);
927
- applyTransaction(target$1, output);
1039
+ applyTransaction(target, output);
928
1040
  return output;
929
1041
  } catch (thrown) {
930
- abortTransaction(target$1);
1042
+ abortTransaction(target);
931
1043
  store.logger.warn(`💥`, `transaction`, key, `caught:`, thrown);
932
1044
  throw thrown;
933
1045
  }
@@ -935,8 +1047,7 @@ function createTransaction(store, options) {
935
1047
  install: (s) => createTransaction(s, options),
936
1048
  subject: new Subject()
937
1049
  };
938
- const target = newest(store);
939
- target.transactions.set(key, newTransaction);
1050
+ newest(store).transactions.set(key, newTransaction);
940
1051
  const token = deposit(newTransaction);
941
1052
  if (!transactionAlreadyExists) store.on.transactionCreation.next(token);
942
1053
  return token;
@@ -1079,14 +1190,349 @@ const clearStore = (store) => {
1079
1190
  store.config = config;
1080
1191
  };
1081
1192
 
1193
+ //#endregion
1194
+ //#region src/internal/not-found-error.ts
1195
+ var NotFoundError = class extends Error {
1196
+ constructor(token, store) {
1197
+ super(`${PRETTY_TOKEN_TYPES[token.type]} ${stringifyJson(token.key)} not found in store "${store.config.name}".`);
1198
+ }
1199
+ };
1200
+
1201
+ //#endregion
1202
+ //#region src/internal/store/withdraw.ts
1203
+ function withdraw(store, token) {
1204
+ let withdrawn;
1205
+ let target = store;
1206
+ while (target !== null) {
1207
+ switch (token.type) {
1208
+ case `atom`:
1209
+ case `mutable_atom`:
1210
+ withdrawn = target.atoms.get(token.key);
1211
+ break;
1212
+ case `writable_pure_selector`:
1213
+ case `writable_held_selector`:
1214
+ withdrawn = target.writableSelectors.get(token.key);
1215
+ break;
1216
+ case `readonly_pure_selector`:
1217
+ case `readonly_held_selector`:
1218
+ withdrawn = target.readonlySelectors.get(token.key);
1219
+ break;
1220
+ case `atom_family`:
1221
+ case `mutable_atom_family`:
1222
+ case `writable_pure_selector_family`:
1223
+ case `readonly_pure_selector_family`:
1224
+ case `writable_held_selector_family`:
1225
+ case `readonly_held_selector_family`:
1226
+ withdrawn = target.families.get(token.key);
1227
+ break;
1228
+ case `timeline`:
1229
+ withdrawn = target.timelines.get(token.key);
1230
+ break;
1231
+ case `transaction`:
1232
+ withdrawn = target.transactions.get(token.key);
1233
+ break;
1234
+ }
1235
+ if (withdrawn) return withdrawn;
1236
+ target = target.child;
1237
+ }
1238
+ throw new NotFoundError(token, store);
1239
+ }
1240
+
1241
+ //#endregion
1242
+ //#region src/internal/get-state/get-fallback.ts
1243
+ function getFallback(store, token, family, subKey) {
1244
+ const disposal = store.disposalTraces.buffer.find((item) => item?.key === stringifyJson(subKey));
1245
+ 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)`);
1246
+ switch (family.type) {
1247
+ case `mutable_atom_family`: {
1248
+ if (store.defaults.has(family.key)) return store.defaults.get(family.key);
1249
+ const defaultValue = new family.class();
1250
+ store.defaults.set(family.key, defaultValue);
1251
+ return defaultValue.READONLY_VIEW;
1252
+ }
1253
+ case `atom_family`: {
1254
+ if (store.defaults.has(family.key)) return store.defaults.get(family.key);
1255
+ const def = family.default;
1256
+ const defaultValue = def(subKey);
1257
+ store.defaults.set(family.key, defaultValue);
1258
+ return defaultValue;
1259
+ }
1260
+ case `readonly_pure_selector_family`:
1261
+ case `writable_pure_selector_family`:
1262
+ case `readonly_held_selector_family`:
1263
+ case `writable_held_selector_family`: {
1264
+ if (store.defaults.has(family.key)) return store.defaults.get(family.key);
1265
+ const defaultValue = family.default(subKey);
1266
+ store.defaults.set(family.key, defaultValue);
1267
+ return defaultValue;
1268
+ }
1269
+ }
1270
+ }
1271
+
1272
+ //#endregion
1273
+ //#region src/internal/safe-compute.ts
1274
+ function safeCompute(target, state) {
1275
+ const { type, key, catch: canCatch } = state;
1276
+ switch (type) {
1277
+ case `readonly_pure_selector`:
1278
+ case `writable_pure_selector`: {
1279
+ let val;
1280
+ target.logger.info(`🧮`, type, key, `computing value`);
1281
+ try {
1282
+ val = state.getFrom(target);
1283
+ if (val instanceof Promise) return val.catch((thrown) => {
1284
+ target.logger.error(`💥`, type, key, `rejected:`, thrown);
1285
+ if (canCatch) {
1286
+ for (const Class of canCatch) if (thrown instanceof Class) return thrown;
1287
+ }
1288
+ throw thrown;
1289
+ });
1290
+ } catch (e) {
1291
+ target.logger.error(`💥`, type, key, `rejected:`, e);
1292
+ if (canCatch) {
1293
+ for (const Class of canCatch) if (e instanceof Class) return writeToCache(target, state, e);
1294
+ }
1295
+ throw e;
1296
+ }
1297
+ return writeToCache(target, state, val);
1298
+ }
1299
+ case `atom`: {
1300
+ let def;
1301
+ if (isFn(state.default)) try {
1302
+ def = state.default();
1303
+ if (def instanceof Promise) def = def.catch((thrown) => {
1304
+ target.logger.error(`💥`, type, key, `rejected:`, thrown);
1305
+ if (canCatch) {
1306
+ for (const Class of canCatch) if (thrown instanceof Class) return thrown;
1307
+ }
1308
+ throw thrown;
1309
+ });
1310
+ } catch (e) {
1311
+ target.logger.error(`💥`, type, key, `rejected:`, e);
1312
+ if (canCatch) {
1313
+ for (const Class of canCatch) if (e instanceof Class) {
1314
+ def = writeToCache(target, state, e);
1315
+ target.logger.info(`✨`, state.type, key, `computed default`, def);
1316
+ return def;
1317
+ }
1318
+ }
1319
+ throw e;
1320
+ }
1321
+ else {
1322
+ def = state.default;
1323
+ target.logger.info(`✨`, state.type, key, `using static default`, def);
1324
+ }
1325
+ return writeToCache(target, state, def);
1326
+ }
1327
+ }
1328
+ }
1329
+
1330
+ //#endregion
1331
+ //#region src/internal/get-state/read-or-compute-value.ts
1332
+ function readOrComputeValue(target, state, mut) {
1333
+ if (target.valueMap.has(state.key)) return readFromCache(target, state, mut);
1334
+ target.logger.info(`❔`, state.type, state.key, `value not found in cache`);
1335
+ const { key } = state;
1336
+ switch (state.type) {
1337
+ case `readonly_held_selector`:
1338
+ case `writable_held_selector`:
1339
+ target.logger.info(`🧮`, state.type, key, `computing value`);
1340
+ return state.getFrom(target);
1341
+ case `writable_pure_selector`:
1342
+ case `readonly_pure_selector`:
1343
+ case `atom`: return safeCompute(target, state);
1344
+ case `mutable_atom`: {
1345
+ const instance = new state.class();
1346
+ target.logger.info(`✨`, state.type, key, `created new instance`, instance);
1347
+ return writeToCache(target, state, instance);
1348
+ }
1349
+ }
1350
+ }
1351
+
1352
+ //#endregion
1353
+ //#region src/internal/families/get-family-of-token.ts
1354
+ function getFamilyOfToken(store, token) {
1355
+ return withdraw(store, {
1356
+ key: token.family.key,
1357
+ type: `${token.type}_family`
1358
+ });
1359
+ }
1360
+
1361
+ //#endregion
1362
+ //#region src/internal/families/mint-in-store.ts
1363
+ const FAMILY_MEMBER_TOKEN_TYPES = {
1364
+ atom_family: `atom`,
1365
+ molecule_family: `molecule`,
1366
+ mutable_atom_family: `mutable_atom`,
1367
+ readonly_held_selector_family: `readonly_held_selector`,
1368
+ readonly_pure_selector_family: `readonly_pure_selector`,
1369
+ writable_held_selector_family: `writable_held_selector`,
1370
+ writable_pure_selector_family: `writable_pure_selector`
1371
+ };
1372
+ const MUST_CREATE = Symbol(`MUST_CREATE`);
1373
+ const DO_NOT_CREATE = Symbol(`DO_NOT_CREATE`);
1374
+ function mintInStore(mustCreate, store, family, key) {
1375
+ const stringKey = stringifyJson(key);
1376
+ const molecule = store.molecules.get(stringKey);
1377
+ if (!molecule && store.config.lifespan === `immortal`) {
1378
+ const { type: familyType, key: familyKey } = family;
1379
+ store.logger.warn(`💣`, `key`, stringKey, `was used to mint a counterfeit token for`, familyType, `"${familyKey}"`);
1380
+ const fullKey = `${familyKey}(${stringKey})`;
1381
+ const type = FAMILY_MEMBER_TOKEN_TYPES[familyType];
1382
+ return {
1383
+ counterfeit: true,
1384
+ key: fullKey,
1385
+ type,
1386
+ family: {
1387
+ key: familyKey,
1388
+ subKey: stringKey
1389
+ }
1390
+ };
1391
+ }
1392
+ let token;
1393
+ if (mustCreate === MUST_CREATE) {
1394
+ store.logger.info(`👪`, family.type, family.key, `adds member`, typeof key === `string` ? `\`${key}\`` : key);
1395
+ token = family.create(key);
1396
+ if (molecule) store.moleculeData.set(stringKey, family.key);
1397
+ } else {
1398
+ const { type: familyType, key: familyKey } = family;
1399
+ const fullKey = `${familyKey}(${stringKey})`;
1400
+ const type = FAMILY_MEMBER_TOKEN_TYPES[familyType];
1401
+ return {
1402
+ key: fullKey,
1403
+ type,
1404
+ family: {
1405
+ key: familyKey,
1406
+ subKey: stringKey
1407
+ }
1408
+ };
1409
+ }
1410
+ return token;
1411
+ }
1412
+
1413
+ //#endregion
1414
+ //#region src/internal/get-state/reduce-reference.ts
1415
+ function reduceReference(store, ...params) {
1416
+ let existingToken;
1417
+ let brandNewToken;
1418
+ let family;
1419
+ let subKey;
1420
+ let token;
1421
+ if (params.length === 1) {
1422
+ token = params[0];
1423
+ if (`family` in token) {
1424
+ const familyToken = getFamilyOfToken(store, token);
1425
+ family = withdraw(store, familyToken);
1426
+ subKey = parseJson(token.family.subKey);
1427
+ existingToken = seekInStore(store, familyToken, subKey);
1428
+ if (`counterfeit` in token) return {
1429
+ token,
1430
+ family,
1431
+ subKey,
1432
+ isNew: false
1433
+ };
1434
+ if (!existingToken) {
1435
+ brandNewToken = mintInStore(MUST_CREATE, store, familyToken, subKey);
1436
+ token = brandNewToken;
1437
+ } else token = existingToken;
1438
+ }
1439
+ } else {
1440
+ family = withdraw(store, params[0]);
1441
+ subKey = params[1];
1442
+ existingToken = seekInStore(store, family, subKey);
1443
+ if (!existingToken) {
1444
+ brandNewToken = mintInStore(MUST_CREATE, store, family, subKey);
1445
+ token = brandNewToken;
1446
+ } else token = existingToken;
1447
+ }
1448
+ const isCounterfeit = `counterfeit` in token;
1449
+ if (Boolean(brandNewToken) && isCounterfeit === false && family) {
1450
+ let subType;
1451
+ switch (token.type) {
1452
+ case `readonly_pure_selector`:
1453
+ case `readonly_held_selector`:
1454
+ subType = `readable`;
1455
+ break;
1456
+ case `atom`:
1457
+ case `mutable_atom`:
1458
+ case `writable_pure_selector`:
1459
+ case `writable_held_selector`:
1460
+ subType = `writable`;
1461
+ break;
1462
+ }
1463
+ const stateCreationEvent = {
1464
+ type: `state_creation`,
1465
+ subType,
1466
+ token,
1467
+ timestamp: Date.now()
1468
+ };
1469
+ family.subject.next(stateCreationEvent);
1470
+ const target = newest(store);
1471
+ if (token.family) {
1472
+ if (isRootStore(target)) switch (token.type) {
1473
+ case `atom`:
1474
+ case `mutable_atom`:
1475
+ store.on.atomCreation.next(token);
1476
+ break;
1477
+ case `writable_pure_selector`:
1478
+ case `readonly_pure_selector`:
1479
+ case `writable_held_selector`:
1480
+ case `readonly_held_selector`:
1481
+ store.on.selectorCreation.next(token);
1482
+ break;
1483
+ }
1484
+ else if (isChildStore(target) && target.on.transactionApplying.state === null) target.transactionMeta.update.subEvents.push(stateCreationEvent);
1485
+ }
1486
+ }
1487
+ return {
1488
+ token,
1489
+ family,
1490
+ subKey,
1491
+ isNew: Boolean(brandNewToken)
1492
+ };
1493
+ }
1494
+
1495
+ //#endregion
1496
+ //#region src/internal/get-state/get-from-store.ts
1497
+ function getFromStore(store, ...params) {
1498
+ const { token, family, subKey } = reduceReference(store, ...params);
1499
+ if (`counterfeit` in token && family && subKey) return getFallback(store, token, family, subKey);
1500
+ const state = withdraw(store, token);
1501
+ return readOrComputeValue(store, state);
1502
+ }
1503
+
1504
+ //#endregion
1505
+ //#region src/internal/families/seek-in-store.ts
1506
+ function seekInStore(store, token, key) {
1507
+ const subKey = stringifyJson(key);
1508
+ const fullKey = `${token.key}(${subKey})`;
1509
+ const target = newest(store);
1510
+ let state;
1511
+ switch (token.type) {
1512
+ case `atom_family`:
1513
+ case `mutable_atom_family`:
1514
+ state = target.atoms.get(fullKey);
1515
+ break;
1516
+ case `writable_held_selector_family`:
1517
+ case `writable_pure_selector_family`:
1518
+ state = target.writableSelectors.get(fullKey);
1519
+ break;
1520
+ case `readonly_held_selector_family`:
1521
+ case `readonly_pure_selector_family`:
1522
+ state = target.readonlySelectors.get(fullKey);
1523
+ break;
1524
+ }
1525
+ if (state) return deposit(state);
1526
+ return state;
1527
+ }
1528
+
1082
1529
  //#endregion
1083
1530
  //#region src/internal/families/find-in-store.ts
1084
1531
  function findInStore(store, familyToken, key) {
1085
1532
  const family = withdraw(store, familyToken);
1086
1533
  const existingStateToken = seekInStore(store, familyToken, key);
1087
1534
  if (existingStateToken) return existingStateToken;
1088
- const newStateToken = mintInStore(DO_NOT_CREATE, store, family, key);
1089
- return newStateToken;
1535
+ return mintInStore(DO_NOT_CREATE, store, family, key);
1090
1536
  }
1091
1537
 
1092
1538
  //#endregion
@@ -1123,8 +1569,7 @@ function createReadonlyPureSelectorFamily(store, options, internalRoles) {
1123
1569
  subject,
1124
1570
  install: (s) => createReadonlyPureSelectorFamily(s, options),
1125
1571
  default: (key) => {
1126
- const getFn = options.get(key);
1127
- return getFn({
1572
+ return options.get(key)({
1128
1573
  get: ((...args) => getFromStore(store, ...args)),
1129
1574
  find: ((...args) => findInStore(store, ...args)),
1130
1575
  json: (token) => getJsonToken(store, token)
@@ -1287,8 +1732,7 @@ function createWritablePureSelectorFamily(store, options, internalRoles) {
1287
1732
  subject,
1288
1733
  install: (s) => createWritablePureSelectorFamily(s, options),
1289
1734
  default: (key) => {
1290
- const getFn = options.get(key);
1291
- return getFn({
1735
+ return options.get(key)({
1292
1736
  get: ((...args) => getFromStore(store, ...args)),
1293
1737
  find: ((...args) => findInStore(store, ...args)),
1294
1738
  json: (token) => getJsonToken(store, token)
@@ -1318,8 +1762,7 @@ function disposeFromStore(store, ...params) {
1318
1762
  else {
1319
1763
  const family = params[0];
1320
1764
  const key = params[1];
1321
- const maybeToken = findInStore(store, family, key);
1322
- token = maybeToken;
1765
+ token = findInStore(store, family, key);
1323
1766
  }
1324
1767
  try {
1325
1768
  withdraw(store, token);
@@ -1341,6 +1784,330 @@ function disposeFromStore(store, ...params) {
1341
1784
  }
1342
1785
  }
1343
1786
 
1787
+ //#endregion
1788
+ //#region src/internal/operation.ts
1789
+ function openOperation(store, token) {
1790
+ if (store.operation.open) {
1791
+ const rejectionTime = performance.now();
1792
+ store.logger.info(`🚫`, token.type, token.key, `deferring setState at T-${rejectionTime} until setState for "${store.operation.token.key}" is done`);
1793
+ return rejectionTime;
1794
+ }
1795
+ store.operation = {
1796
+ open: true,
1797
+ done: /* @__PURE__ */ new Set(),
1798
+ prev: /* @__PURE__ */ new Map(),
1799
+ timestamp: Date.now(),
1800
+ token,
1801
+ subEvents: []
1802
+ };
1803
+ store.logger.info(`⭕`, token.type, token.key, `operation start in store "${store.config.name}"${isChildStore(store) ? ` ${store.transactionMeta.phase} "${store.transactionMeta.update.token.key}"` : ``}`);
1804
+ return store;
1805
+ }
1806
+ function closeOperation(store) {
1807
+ if (store.operation.open) store.logger.info(`🔴`, store.operation.token.type, store.operation.token.key, `operation done in store "${store.config.name}"`);
1808
+ store.operation = { open: false };
1809
+ store.on.operationClose.next(store.operation);
1810
+ }
1811
+ const isDone = (store, key) => {
1812
+ if (!store.operation.open) {
1813
+ store.logger.error(`🐞`, `unknown`, key, `isDone called outside of an operation. This is probably a bug in AtomIO.`);
1814
+ return true;
1815
+ }
1816
+ return store.operation.done.has(key);
1817
+ };
1818
+ const markDone = (store, key) => {
1819
+ if (!store.operation.open) {
1820
+ store.logger.error(`🐞`, `unknown`, key, `markDone called outside of an operation. This is probably a bug in AtomIO.`);
1821
+ return;
1822
+ }
1823
+ store.operation.done.add(key);
1824
+ };
1825
+
1826
+ //#endregion
1827
+ //#region src/internal/set-state/dispatch-state-update.ts
1828
+ function dispatchOrDeferStateUpdate(target, state, { oldValue, newValue }, stateIsNewlyCreated, family) {
1829
+ const token = deposit(state);
1830
+ if (stateIsNewlyCreated && family) {
1831
+ state.subject.next({ newValue });
1832
+ const stateCreationEvent = {
1833
+ checkpoint: true,
1834
+ type: `state_creation`,
1835
+ subType: `writable`,
1836
+ token,
1837
+ timestamp: Date.now(),
1838
+ value: newValue
1839
+ };
1840
+ target.operation.subEvents.push(stateCreationEvent);
1841
+ family.subject.next(stateCreationEvent);
1842
+ const innerTarget = newest(target);
1843
+ if (token.family) {
1844
+ if (isRootStore(innerTarget)) switch (token.type) {
1845
+ case `atom`:
1846
+ case `mutable_atom`:
1847
+ target.on.atomCreation.next(token);
1848
+ break;
1849
+ case `writable_pure_selector`:
1850
+ case `writable_held_selector`:
1851
+ target.on.selectorCreation.next(token);
1852
+ break;
1853
+ }
1854
+ else if (isChildStore(innerTarget) && innerTarget.on.transactionApplying.state === null) innerTarget.transactionMeta.update.subEvents.push(stateCreationEvent);
1855
+ }
1856
+ return;
1857
+ }
1858
+ const { key, subject, type } = state;
1859
+ const update = {
1860
+ oldValue: isTransceiver(oldValue) ? oldValue.READONLY_VIEW : oldValue,
1861
+ newValue: isTransceiver(newValue) ? newValue.READONLY_VIEW : newValue
1862
+ };
1863
+ if (isRootStore(target)) {
1864
+ switch (type) {
1865
+ case `mutable_atom`:
1866
+ target.logger.info(`📢`, type, key, `is now (`, newValue, `) subscribers:`, subject.subscribers.keys());
1867
+ break;
1868
+ case `atom`:
1869
+ case `writable_pure_selector`:
1870
+ case `writable_held_selector`: target.logger.info(`📢`, type, key, `went (`, oldValue, `->`, newValue, `) subscribers:`, subject.subscribers.keys());
1871
+ }
1872
+ subject.next(update);
1873
+ }
1874
+ if (isChildStore(target) && (type === `mutable_atom` || type === `atom`)) {
1875
+ if (target.on.transactionApplying.state === null) {
1876
+ if (isTransceiver(newValue)) return;
1877
+ const { timestamp } = target.operation;
1878
+ const atomUpdate = {
1879
+ type: `atom_update`,
1880
+ token,
1881
+ timestamp,
1882
+ update
1883
+ };
1884
+ target.transactionMeta.update.subEvents.push(atomUpdate);
1885
+ target.logger.info(`📁`, `atom`, key, `stowed (`, oldValue, `->`, newValue, `)`);
1886
+ return;
1887
+ }
1888
+ if (hasRole(state, `tracker:signal`)) {
1889
+ const keyOfMutable = key.slice(1);
1890
+ const mutable = target.atoms.get(keyOfMutable);
1891
+ if (readOrComputeValue(target, mutable, `mut`).do(update.newValue) === null === true) evictDownstreamFromAtom(target, mutable);
1892
+ }
1893
+ }
1894
+ }
1895
+
1896
+ //#endregion
1897
+ //#region src/internal/set-state/set-atom.ts
1898
+ const setAtom = (target, atom, next) => {
1899
+ const oldValue = readOrComputeValue(target, atom, `mut`);
1900
+ let newValue = become(next, oldValue);
1901
+ target.logger.info(`⭐`, `atom`, atom.key, `setting value`, newValue);
1902
+ newValue = writeToCache(target, atom, newValue);
1903
+ markDone(target, atom.key);
1904
+ evictDownstreamFromAtom(target, atom);
1905
+ return {
1906
+ oldValue,
1907
+ newValue
1908
+ };
1909
+ };
1910
+
1911
+ //#endregion
1912
+ //#region src/internal/set-state/reset-atom-or-selector.ts
1913
+ function resetAtom(target, atom) {
1914
+ switch (atom.type) {
1915
+ case `mutable_atom`: return setAtom(target, atom, new atom.class());
1916
+ case `atom`: {
1917
+ let def;
1918
+ if (isFn(atom.default)) def = safeCompute(target, atom);
1919
+ else def = atom.default;
1920
+ return setAtom(target, atom, def);
1921
+ }
1922
+ }
1923
+ }
1924
+ function resetAtomOrSelector(target, state) {
1925
+ let protoUpdate;
1926
+ switch (state.type) {
1927
+ case `atom`:
1928
+ case `mutable_atom`:
1929
+ protoUpdate = resetAtom(target, state);
1930
+ break;
1931
+ case `writable_held_selector`:
1932
+ {
1933
+ const atoms = traceRootSelectorAtoms(target, state.key);
1934
+ for (const atom of atoms.values()) {
1935
+ const rootProtoUpdate = resetAtom(target, atom);
1936
+ dispatchOrDeferStateUpdate(target, state, rootProtoUpdate, false);
1937
+ }
1938
+ const value = state.getFrom(target);
1939
+ protoUpdate = {
1940
+ oldValue: value,
1941
+ newValue: value
1942
+ };
1943
+ }
1944
+ break;
1945
+ case `writable_pure_selector`:
1946
+ {
1947
+ const oldValue = safeCompute(target, state);
1948
+ const atoms = traceRootSelectorAtoms(target, state.key);
1949
+ for (const atom of atoms.values()) {
1950
+ const rootProtoUpdate = resetAtom(target, atom);
1951
+ dispatchOrDeferStateUpdate(target, state, rootProtoUpdate, false);
1952
+ }
1953
+ const newValue = safeCompute(target, state);
1954
+ protoUpdate = {
1955
+ oldValue,
1956
+ newValue
1957
+ };
1958
+ }
1959
+ break;
1960
+ }
1961
+ return protoUpdate;
1962
+ }
1963
+
1964
+ //#endregion
1965
+ //#region src/internal/set-state/set-into-store.ts
1966
+ function setIntoStore(store, ...params) {
1967
+ operateOnStore(OWN_OP, store, ...params);
1968
+ }
1969
+
1970
+ //#endregion
1971
+ //#region src/internal/set-state/reset-in-store.ts
1972
+ const RESET_STATE = Symbol(`RESET`);
1973
+ function resetInStore(store, ...params) {
1974
+ const subParams = [...params, RESET_STATE];
1975
+ setIntoStore(store, ...subParams);
1976
+ }
1977
+
1978
+ //#endregion
1979
+ //#region src/internal/set-state/set-selector.ts
1980
+ function setSelector(target, selector, next) {
1981
+ let oldValue;
1982
+ let newValue;
1983
+ let constant;
1984
+ const { type, key } = selector;
1985
+ switch (selector.type) {
1986
+ case `writable_pure_selector`:
1987
+ oldValue = readOrComputeValue(target, selector, `mut`);
1988
+ newValue = become(next, oldValue);
1989
+ newValue = writeToCache(target, selector, newValue);
1990
+ break;
1991
+ case `writable_held_selector`:
1992
+ constant = selector.const;
1993
+ become(next, constant);
1994
+ oldValue = constant;
1995
+ newValue = constant;
1996
+ }
1997
+ target.logger.info(`⭐`, type, key, `setting to`, newValue);
1998
+ markDone(target, key);
1999
+ selector.setSelf(newValue);
2000
+ return {
2001
+ oldValue,
2002
+ newValue
2003
+ };
2004
+ }
2005
+
2006
+ //#endregion
2007
+ //#region src/internal/set-state/set-atom-or-selector.ts
2008
+ const setAtomOrSelector = (target, state, value) => {
2009
+ let protoUpdate;
2010
+ switch (state.type) {
2011
+ case `atom`:
2012
+ case `mutable_atom`:
2013
+ protoUpdate = setAtom(target, state, value);
2014
+ break;
2015
+ case `writable_pure_selector`:
2016
+ case `writable_held_selector`:
2017
+ protoUpdate = setSelector(target, state, value);
2018
+ break;
2019
+ }
2020
+ return protoUpdate;
2021
+ };
2022
+
2023
+ //#endregion
2024
+ //#region src/internal/set-state/operate-on-store.ts
2025
+ const OWN_OP = Symbol(`OWN_OP`);
2026
+ const JOIN_OP = Symbol(`JOIN_OP`);
2027
+ function operateOnStore(opMode, store, ...params) {
2028
+ let existingToken;
2029
+ let brandNewToken;
2030
+ let token;
2031
+ let family;
2032
+ let key;
2033
+ let value;
2034
+ if (params.length === 2) {
2035
+ token = params[0];
2036
+ value = params[1];
2037
+ if (`family` in token) {
2038
+ family = getFamilyOfToken(store, token);
2039
+ key = parseJson(token.family.subKey);
2040
+ existingToken = seekInStore(store, family, key);
2041
+ if (!existingToken) token = brandNewToken = mintInStore(MUST_CREATE, store, family, key);
2042
+ else token = existingToken;
2043
+ }
2044
+ } else {
2045
+ family = withdraw(store, params[0]);
2046
+ key = params[1];
2047
+ value = params[2];
2048
+ existingToken = seekInStore(store, family, key);
2049
+ if (!existingToken) token = brandNewToken = mintInStore(MUST_CREATE, store, family, key);
2050
+ else token = existingToken;
2051
+ }
2052
+ const action = value === RESET_STATE ? `reset` : `set`;
2053
+ let target;
2054
+ if (opMode === OWN_OP) {
2055
+ const result = openOperation(store, token);
2056
+ if (typeof result === `number`) {
2057
+ const rejectionTime = result;
2058
+ const unsubscribe = store.on.operationClose.subscribe(`waiting to ${action} "${token.key}" at T-${rejectionTime}`, function waitUntilOperationCloseToSetState() {
2059
+ unsubscribe();
2060
+ store.logger.info(`🟢`, token.type, token.key, `resuming deferred`, action, `from T-${rejectionTime}`);
2061
+ operateOnStore(opMode, store, token, value);
2062
+ });
2063
+ return;
2064
+ }
2065
+ target = result;
2066
+ } else target = store;
2067
+ if (`counterfeit` in token && `family` in token) {
2068
+ const subKey = token.family.subKey;
2069
+ const disposal = store.disposalTraces.buffer.find((item) => item?.key === subKey);
2070
+ 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)`);
2071
+ return;
2072
+ }
2073
+ const state = withdraw(target, token);
2074
+ let protoUpdate;
2075
+ if (value === RESET_STATE) protoUpdate = resetAtomOrSelector(target, state);
2076
+ else protoUpdate = setAtomOrSelector(target, state, value);
2077
+ dispatchOrDeferStateUpdate(target, state, protoUpdate, Boolean(brandNewToken), family);
2078
+ if (opMode === OWN_OP) closeOperation(target);
2079
+ }
2080
+
2081
+ //#endregion
2082
+ //#region src/internal/keys.ts
2083
+ const isAtomKey = (store, key) => newest(store).atoms.has(key);
2084
+ const isSelectorKey = (store, key) => newest(store).writableSelectors.has(key);
2085
+ const isReadonlySelectorKey = (store, key) => newest(store).readonlySelectors.has(key);
2086
+ const isStateKey = (store, key) => isAtomKey(store, key) || isSelectorKey(store, key) || isReadonlySelectorKey(store, key);
2087
+
2088
+ //#endregion
2089
+ //#region src/internal/selector/get-selector-dependency-keys.ts
2090
+ function getSelectorDependencyKeys(store, key) {
2091
+ return newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(store, source));
2092
+ }
2093
+
2094
+ //#endregion
2095
+ //#region src/internal/selector/trace-selector-atoms.ts
2096
+ function traceRootSelectorAtoms(store, selectorKey, covered = /* @__PURE__ */ new Set()) {
2097
+ const dependencies = getSelectorDependencyKeys(store, selectorKey);
2098
+ const roots = /* @__PURE__ */ new Map();
2099
+ while (dependencies.length > 0) {
2100
+ const dependencyKey = dependencies.pop();
2101
+ if (covered.has(dependencyKey)) continue;
2102
+ covered.add(dependencyKey);
2103
+ if (isAtomKey(store, dependencyKey)) {
2104
+ const atom = store.atoms.get(dependencyKey);
2105
+ roots.set(atom.key, atom);
2106
+ } else dependencies.push(...getSelectorDependencyKeys(store, dependencyKey));
2107
+ }
2108
+ return roots;
2109
+ }
2110
+
1344
2111
  //#endregion
1345
2112
  //#region src/internal/selector/update-selector-atoms.ts
1346
2113
  function updateSelectorAtoms(store, selectorType, selectorKey, dependency, covered) {
@@ -1602,73 +2369,60 @@ function disposeSelector(store, selectorToken) {
1602
2369
  const { key, type, family: familyMeta } = selectorToken;
1603
2370
  if (!familyMeta) store.logger.error(`❌`, type, key, `Standalone selectors cannot be disposed.`);
1604
2371
  else {
1605
- const molecule = target.molecules.get(familyMeta.subKey);
1606
- if (molecule) target.moleculeData.delete(familyMeta.subKey, familyMeta.key);
2372
+ if (target.molecules.get(familyMeta.subKey)) target.moleculeData.delete(familyMeta.subKey, familyMeta.key);
1607
2373
  let familyToken;
1608
2374
  switch (selectorToken.type) {
1609
2375
  case `writable_held_selector`:
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
- });
1623
- }
2376
+ target.writableSelectors.delete(key);
2377
+ familyToken = {
2378
+ key: familyMeta.key,
2379
+ type: `writable_held_selector_family`
2380
+ };
2381
+ withdraw(store, familyToken).subject.next({
2382
+ type: `state_disposal`,
2383
+ subType: `selector`,
2384
+ token: selectorToken,
2385
+ timestamp: Date.now()
2386
+ });
1624
2387
  break;
1625
2388
  case `writable_pure_selector`:
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
- }
2389
+ target.writableSelectors.delete(key);
2390
+ familyToken = {
2391
+ key: familyMeta.key,
2392
+ type: `writable_pure_selector_family`
2393
+ };
2394
+ withdraw(store, familyToken).subject.next({
2395
+ type: `state_disposal`,
2396
+ subType: `selector`,
2397
+ token: selectorToken,
2398
+ timestamp: Date.now()
2399
+ });
1640
2400
  break;
1641
2401
  case `readonly_held_selector`:
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
- }
2402
+ target.readonlySelectors.delete(key);
2403
+ familyToken = {
2404
+ key: familyMeta.key,
2405
+ type: `readonly_held_selector_family`
2406
+ };
2407
+ withdraw(store, familyToken).subject.next({
2408
+ type: `state_disposal`,
2409
+ subType: `selector`,
2410
+ token: selectorToken,
2411
+ timestamp: Date.now()
2412
+ });
1656
2413
  break;
1657
2414
  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
- }
2415
+ target.readonlySelectors.delete(key);
2416
+ familyToken = {
2417
+ key: familyMeta.key,
2418
+ type: `readonly_pure_selector_family`
2419
+ };
2420
+ withdraw(store, familyToken).subject.next({
2421
+ type: `state_disposal`,
2422
+ subType: `selector`,
2423
+ token: selectorToken,
2424
+ timestamp: Date.now()
2425
+ });
1672
2426
  break;
1673
2427
  }
1674
2428
  target.valueMap.delete(key);
@@ -1686,6 +2440,82 @@ function disposeSelector(store, selectorToken) {
1686
2440
  }
1687
2441
  }
1688
2442
 
2443
+ //#endregion
2444
+ //#region src/internal/subscribe/recall-state.ts
2445
+ const recallState = (store, state) => {
2446
+ const target = newest(store);
2447
+ if (target.operation.open) return target.operation.prev.get(state.key);
2448
+ return target.valueMap.get(state.key);
2449
+ };
2450
+
2451
+ //#endregion
2452
+ //#region src/internal/subscribe/subscribe-to-root-atoms.ts
2453
+ const subscribeToRootDependency = (target, selector, atom) => {
2454
+ return atom.subject.subscribe(`${selector.type}:${selector.key}`, (atomChange) => {
2455
+ target.logger.info(`📢`, selector.type, selector.key, `root`, atom.key, `went`, atomChange.oldValue, `->`, atomChange.newValue);
2456
+ const oldValue = recallState(target, selector);
2457
+ const newValue = readOrComputeValue(target, selector);
2458
+ target.logger.info(`✨`, selector.type, selector.key, `went`, oldValue, `->`, newValue);
2459
+ selector.subject.next({
2460
+ newValue,
2461
+ oldValue
2462
+ });
2463
+ });
2464
+ };
2465
+
2466
+ //#endregion
2467
+ //#region src/internal/subscribe/subscribe-to-state.ts
2468
+ function subscribeToState(store, token, key, handleUpdate) {
2469
+ function safelyHandleUpdate(update) {
2470
+ if (store.operation.open) {
2471
+ if (state?.type === `atom` && hasRole(state, `tracker:signal`) && `*` + store.operation.token.key === token.key && `inboundTracker` in handleUpdate) return;
2472
+ const unsubscribe$1 = store.on.operationClose.subscribe(`state subscription ${key}`, () => {
2473
+ unsubscribe$1();
2474
+ handleUpdate(update);
2475
+ });
2476
+ } else handleUpdate(update);
2477
+ }
2478
+ reduceReference(store, token);
2479
+ const state = withdraw(store, token);
2480
+ store.logger.info(`👀`, state.type, state.key, `Adding subscription "${key}"`);
2481
+ const isSelector = state.type === `writable_pure_selector` || state.type === `readonly_pure_selector`;
2482
+ const rootSubs = /* @__PURE__ */ new Map();
2483
+ let updateHandler = safelyHandleUpdate;
2484
+ if (isSelector) {
2485
+ readOrComputeValue(store, state);
2486
+ for (const [atomKey, atom] of traceRootSelectorAtoms(store, state.key)) rootSubs.set(atomKey, subscribeToRootDependency(store, state, atom));
2487
+ updateHandler = function updateRootsBeforeHandlingUpdate(update) {
2488
+ const dependencies = traceRootSelectorAtoms(store, state.key);
2489
+ for (const [previousRootKey, unsub] of rootSubs) if (dependencies.get(previousRootKey)) dependencies.delete(previousRootKey);
2490
+ else {
2491
+ unsub();
2492
+ rootSubs.delete(previousRootKey);
2493
+ }
2494
+ for (const [atomKey, atom] of dependencies) rootSubs.set(atomKey, subscribeToRootDependency(store, state, atom));
2495
+ safelyHandleUpdate(update);
2496
+ };
2497
+ }
2498
+ const mainUnsubFunction = state.subject.subscribe(key, updateHandler);
2499
+ const unsubscribe = () => {
2500
+ store.logger.info(`🙈`, state.type, state.key, `Removing subscription "${key}"`);
2501
+ mainUnsubFunction();
2502
+ for (const unsubFromDependency of rootSubs.values()) unsubFromDependency();
2503
+ };
2504
+ return unsubscribe;
2505
+ }
2506
+
2507
+ //#endregion
2508
+ //#region src/internal/subscribe/subscribe-to-timeline.ts
2509
+ const subscribeToTimeline = (store, token, key, handleUpdate) => {
2510
+ const tl = withdraw(store, token);
2511
+ store.logger.info(`👀`, `timeline`, token.key, `Adding subscription "${key}"`);
2512
+ const unsubscribe = tl.subject.subscribe(key, handleUpdate);
2513
+ return () => {
2514
+ store.logger.info(`🙈`, `timeline`, token.key, `Removing subscription "${key}" from timeline`);
2515
+ unsubscribe();
2516
+ };
2517
+ };
2518
+
1689
2519
  //#endregion
1690
2520
  //#region src/internal/subscribe/subscribe-to-transaction.ts
1691
2521
  const subscribeToTransaction = (store, token, key, handleUpdate) => {
@@ -1713,6 +2543,93 @@ function subscribeInStore(store, token, handleUpdate, key = arbitrary()) {
1713
2543
  }
1714
2544
  }
1715
2545
 
2546
+ //#endregion
2547
+ //#region src/internal/mutable/tracker.ts
2548
+ /**
2549
+ * @internal Give the tracker a transceiver state and a store, and it will
2550
+ * subscribe to the transceiver's inner value. When the inner value changes,
2551
+ * the tracker will update its own state to reflect the change.
2552
+ */
2553
+ var Tracker = class {
2554
+ initializeSignalAtom(mutableState, store) {
2555
+ const latestSignalStateKey = `*${mutableState.key}`;
2556
+ store.atoms.delete(latestSignalStateKey);
2557
+ store.valueMap.delete(latestSignalStateKey);
2558
+ const familyMetaData = mutableState.family ? {
2559
+ key: `*${mutableState.family.key}`,
2560
+ subKey: mutableState.family.subKey
2561
+ } : void 0;
2562
+ const latestSignalState = createRegularAtom(store, {
2563
+ key: latestSignalStateKey,
2564
+ default: null
2565
+ }, familyMetaData, [`tracker:signal`]);
2566
+ if (store.parent?.valueMap.has(latestSignalStateKey)) {
2567
+ const parentValue = store.parent.valueMap.get(latestSignalStateKey);
2568
+ store.valueMap.set(latestSignalStateKey, parentValue);
2569
+ }
2570
+ return latestSignalState;
2571
+ }
2572
+ unsubscribeFromInnerValue;
2573
+ unsubscribeFromState;
2574
+ captureSignalsFromCore(mutableState, latestSignalState, target) {
2575
+ const stateKey = mutableState.key;
2576
+ const storeName = target.config.name;
2577
+ const storeStatus = isChildStore(target) ? target.transactionMeta.update.token.key : `main`;
2578
+ const subscriptionKey = `tracker-from-core:${storeName}:${storeStatus}:${stateKey}`;
2579
+ const trackerCapturesOutboundSignal = (update) => {
2580
+ operateOnStore(JOIN_OP, target, latestSignalState, update);
2581
+ };
2582
+ this.unsubscribeFromInnerValue = getFromStore(target, mutableState).subscribe(subscriptionKey, trackerCapturesOutboundSignal);
2583
+ this.unsubscribeFromState = subscribeToState(target, mutableState, subscriptionKey, function trackerLooksForNewReference(update) {
2584
+ if (update.newValue !== update.oldValue) {
2585
+ this.unsubscribeFromInnerValue();
2586
+ this.unsubscribeFromInnerValue = update.newValue.subscribe(subscriptionKey, trackerCapturesOutboundSignal);
2587
+ }
2588
+ }.bind(this));
2589
+ }
2590
+ supplySignalsToCore(mutableState, latestSignalState, target) {
2591
+ const stateKey = mutableState.key;
2592
+ const storeName = target.config.name;
2593
+ const storeStatus = isChildStore(target) ? target.transactionMeta.update.token.key : `main`;
2594
+ const subscriptionKey = `tracker-to-core:${storeName}:${storeStatus}:${stateKey}`;
2595
+ subscribeToState(target, latestSignalState, subscriptionKey, Object.assign(function trackerCapturesInboundSignal({ newValue, oldValue }) {
2596
+ const timelineId = target.timelineTopics.getRelatedKey(latestSignalState.key);
2597
+ if (timelineId && target.timelines.get(timelineId)?.timeTraveling) {
2598
+ const unsubscribe = subscribeToTimeline(target, {
2599
+ key: timelineId,
2600
+ type: `timeline`
2601
+ }, subscriptionKey, function trackerWaitsForTimeTravelToFinish(update) {
2602
+ unsubscribe();
2603
+ setIntoStore(target, mutableState, (transceiver) => {
2604
+ if (update === `redo` && newValue) transceiver.do(newValue);
2605
+ else if (update === `undo` && oldValue) transceiver.undo(oldValue);
2606
+ return transceiver;
2607
+ });
2608
+ });
2609
+ return;
2610
+ }
2611
+ setIntoStore(target, mutableState, (transceiver) => (transceiver.do(newValue), transceiver));
2612
+ }, { inboundTracker: true }));
2613
+ }
2614
+ mutableAtomToken;
2615
+ latestSignalToken;
2616
+ [Symbol.dispose];
2617
+ constructor(mutableAtomToken, store) {
2618
+ const target = newest(store);
2619
+ const latestSignalToken = this.initializeSignalAtom(mutableAtomToken, target);
2620
+ this.mutableAtomToken = mutableAtomToken;
2621
+ this.latestSignalToken = latestSignalToken;
2622
+ this.captureSignalsFromCore(mutableAtomToken, latestSignalToken, target);
2623
+ this.supplySignalsToCore(mutableAtomToken, latestSignalToken, target);
2624
+ target.trackers.set(mutableAtomToken.key, this);
2625
+ this[Symbol.dispose] = () => {
2626
+ this.unsubscribeFromInnerValue();
2627
+ this.unsubscribeFromState();
2628
+ target.trackers.delete(mutableAtomToken.key);
2629
+ };
2630
+ }
2631
+ };
2632
+
1716
2633
  //#endregion
1717
2634
  //#region src/internal/mutable/create-mutable-atom.ts
1718
2635
  function createMutableAtom(store, options, family) {
@@ -1855,8 +2772,7 @@ function createMutableAtomFamily(store, options, internalRoles) {
1855
2772
  const getJsonFamily = (mutableAtomFamily, store) => {
1856
2773
  const target = newest(store);
1857
2774
  const key = `${mutableAtomFamily.key}:JSON`;
1858
- const jsonFamily = target.families.get(key);
1859
- return jsonFamily;
2775
+ return target.families.get(key);
1860
2776
  };
1861
2777
 
1862
2778
  //#endregion
@@ -1864,21 +2780,18 @@ const getJsonFamily = (mutableAtomFamily, store) => {
1864
2780
  const getJsonToken = (store, mutableAtomToken) => {
1865
2781
  if (mutableAtomToken.family) {
1866
2782
  const target = newest(store);
1867
- const jsonFamilyKey = `${mutableAtomToken.family.key}:JSON`;
1868
2783
  const jsonFamilyToken = {
1869
- key: jsonFamilyKey,
2784
+ key: `${mutableAtomToken.family.key}:JSON`,
1870
2785
  type: `writable_pure_selector_family`
1871
2786
  };
1872
2787
  const family = withdraw(target, jsonFamilyToken);
1873
2788
  const subKey = parseJson(mutableAtomToken.family.subKey);
1874
- const jsonToken = findInStore(store, family, subKey);
1875
- return jsonToken;
2789
+ return findInStore(store, family, subKey);
1876
2790
  }
1877
- const token = {
2791
+ return {
1878
2792
  type: `writable_pure_selector`,
1879
2793
  key: `${mutableAtomToken.key}:JSON`
1880
2794
  };
1881
- return token;
1882
2795
  };
1883
2796
 
1884
2797
  //#endregion
@@ -1886,17 +2799,15 @@ const getJsonToken = (store, mutableAtomToken) => {
1886
2799
  const getUpdateFamily = (mutableAtomFamily, store) => {
1887
2800
  const target = newest(store);
1888
2801
  const key = `*${mutableAtomFamily.key}`;
1889
- const updateFamily = target.families.get(key);
1890
- return updateFamily;
2802
+ return target.families.get(key);
1891
2803
  };
1892
2804
 
1893
2805
  //#endregion
1894
2806
  //#region src/internal/mutable/get-update-token.ts
1895
2807
  const getUpdateToken = (mutableAtomToken) => {
1896
- const key = `*${mutableAtomToken.key}`;
1897
2808
  const updateToken = {
1898
2809
  type: `atom`,
1899
- key
2810
+ key: `*${mutableAtomToken.key}`
1900
2811
  };
1901
2812
  if (mutableAtomToken.family) updateToken.family = {
1902
2813
  key: `*${mutableAtomToken.family.key}`,
@@ -1905,6 +2816,177 @@ const getUpdateToken = (mutableAtomToken) => {
1905
2816
  return updateToken;
1906
2817
  };
1907
2818
 
2819
+ //#endregion
2820
+ //#region src/internal/mutable/transceiver.ts
2821
+ function isTransceiver(value) {
2822
+ return typeof value === `object` && value !== null && `do` in value && `undo` in value && `subscribe` in value && `READONLY_VIEW` in value && `toJSON` in value;
2823
+ }
2824
+
2825
+ //#endregion
2826
+ //#region src/internal/caching.ts
2827
+ function writeToCache(target, state, value) {
2828
+ const { key, subject, type } = state;
2829
+ const currentValue = target.valueMap.get(key);
2830
+ if (currentValue instanceof Future && !currentValue.done) {
2831
+ const future = currentValue;
2832
+ if (value instanceof Promise) {
2833
+ future.use(value);
2834
+ return future;
2835
+ }
2836
+ target.valueMap.set(key, value);
2837
+ return value;
2838
+ }
2839
+ if (value instanceof Promise) {
2840
+ const future = new Future(value);
2841
+ target.valueMap.set(key, future);
2842
+ future.then(function handleResolvedFuture(resolved) {
2843
+ if (target.valueMap.get(key) === future) {
2844
+ openOperation(target, state);
2845
+ writeToCache(target, state, resolved);
2846
+ switch (type) {
2847
+ case `atom`:
2848
+ evictDownstreamFromAtom(target, state);
2849
+ break;
2850
+ case `readonly_pure_selector`:
2851
+ case `writable_pure_selector`:
2852
+ evictDownstreamFromSelector(target, key);
2853
+ break;
2854
+ }
2855
+ closeOperation(target);
2856
+ subject.next({
2857
+ newValue: resolved,
2858
+ oldValue: future
2859
+ });
2860
+ }
2861
+ }).catch((thrown) => {
2862
+ target.logger.error(`💥`, state.type, key, `rejected:`, thrown);
2863
+ });
2864
+ return future;
2865
+ }
2866
+ target.logger.info(`📝`, state.type, state.key, `writing to cache`, value);
2867
+ target.valueMap.set(key, value);
2868
+ return value;
2869
+ }
2870
+ /**
2871
+ * @param target - the newest layer of the store
2872
+ * @param state - the state to read from cache
2873
+ * @param mut - whether the value is intended to be mutable
2874
+ * @returns the state's current value
2875
+ */
2876
+ function readFromCache(target, state, mut) {
2877
+ target.logger.info(`📖`, state.type, state.key, `reading cached value`);
2878
+ let value = target.valueMap.get(state.key);
2879
+ if (mut === `mut` && state.type === `mutable_atom` && isChildStore(target)) {
2880
+ const mutableAtom$1 = state;
2881
+ const { parent } = target;
2882
+ if (target.valueMap.hasOwn(mutableAtom$1.key)) return value;
2883
+ const parentValue = parent.valueMap.get(mutableAtom$1.key);
2884
+ target.logger.info(`📃`, `atom`, mutableAtom$1.key, `copying`);
2885
+ const jsonValue = parentValue.toJSON();
2886
+ const copiedValue = mutableAtom$1.class.fromJSON(jsonValue);
2887
+ target.valueMap.set(mutableAtom$1.key, copiedValue);
2888
+ new Tracker(mutableAtom$1, parent);
2889
+ value = copiedValue;
2890
+ }
2891
+ return value;
2892
+ }
2893
+ function evictCachedValue(target, key) {
2894
+ const currentValue = target.valueMap.get(key);
2895
+ if (currentValue instanceof Future) {
2896
+ const selector = target.writableSelectors.get(key) ?? target.readonlySelectors.get(key);
2897
+ if (selector) selector.getFrom(target);
2898
+ return;
2899
+ }
2900
+ if (target.operation.open) target.operation.prev.set(key, currentValue);
2901
+ target.valueMap.delete(key);
2902
+ target.logger.info(`🗑`, `state`, key, `evicted`);
2903
+ }
2904
+
2905
+ //#endregion
2906
+ //#region src/internal/set-state/evict-downstream.ts
2907
+ function evictDownstreamFromAtom(store, atom) {
2908
+ const target = newest(store);
2909
+ const { key, type } = atom;
2910
+ const downstreamKeys = target.selectorAtoms.getRelatedKeys(key);
2911
+ target.logger.info(`🧹`, type, key, downstreamKeys ? `evicting ${downstreamKeys.size} states downstream:` : `no downstream states`, downstreamKeys ?? `to evict`);
2912
+ if (downstreamKeys) {
2913
+ if (target.operation.open) target.logger.info(`🧹`, type, key, `[ ${[...target.operation.done].join(`, `)} ] already done`);
2914
+ for (const downstreamKey of downstreamKeys) {
2915
+ if (isDone(target, downstreamKey)) continue;
2916
+ evictCachedValue(target, downstreamKey);
2917
+ markDone(target, downstreamKey);
2918
+ }
2919
+ }
2920
+ }
2921
+ function evictDownstreamFromSelector(store, selectorKey) {
2922
+ const target = newest(store);
2923
+ const relationEntries = target.selectorGraph.getRelationEntries({ upstreamSelectorKey: selectorKey }).filter(([_, { source }]) => source === selectorKey);
2924
+ for (const [downstreamSelectorKey] of relationEntries) {
2925
+ if (isDone(target, downstreamSelectorKey)) continue;
2926
+ evictCachedValue(target, downstreamSelectorKey);
2927
+ markDone(target, downstreamSelectorKey);
2928
+ evictDownstreamFromSelector(store, downstreamSelectorKey);
2929
+ }
2930
+ }
2931
+
2932
+ //#endregion
2933
+ //#region src/internal/atom/create-regular-atom.ts
2934
+ function createRegularAtom(store, options, family, internalRoles) {
2935
+ const type = `atom`;
2936
+ const { key } = options;
2937
+ store.logger.info(`🔨`, type, key, `is being created`);
2938
+ const target = newest(store);
2939
+ const existing = target.atoms.get(key);
2940
+ if (existing && existing.type === type) {
2941
+ store.logger.error(`❌`, `atom`, key, `Tried to create atom, but it already exists in the store.`);
2942
+ return deposit(existing);
2943
+ }
2944
+ const subject = new Subject();
2945
+ const newAtom = {
2946
+ ...options,
2947
+ type,
2948
+ install: (s) => {
2949
+ s.logger.info(`🛠️`, type, key, `installing in store "${s.config.name}"`);
2950
+ return createRegularAtom(s, options, family);
2951
+ },
2952
+ subject
2953
+ };
2954
+ if (family) newAtom.family = family;
2955
+ if (internalRoles) newAtom.internalRoles = internalRoles;
2956
+ target.atoms.set(key, newAtom);
2957
+ const token = deposit(newAtom);
2958
+ if (options.effects) {
2959
+ let effectIndex = 0;
2960
+ const cleanupFunctions = [];
2961
+ for (const effect of options.effects) {
2962
+ const cleanup = effect({
2963
+ resetSelf: () => {
2964
+ resetInStore(store, token);
2965
+ },
2966
+ setSelf: (next) => {
2967
+ setIntoStore(store, token, next);
2968
+ },
2969
+ onSet: (handle) => subscribeToState(store, token, `effect[${effectIndex}]`, handle)
2970
+ });
2971
+ if (cleanup) cleanupFunctions.push(cleanup);
2972
+ ++effectIndex;
2973
+ }
2974
+ newAtom.cleanup = () => {
2975
+ for (const cleanup of cleanupFunctions) cleanup();
2976
+ };
2977
+ }
2978
+ store.on.atomCreation.next(token);
2979
+ return token;
2980
+ }
2981
+
2982
+ //#endregion
2983
+ //#region src/internal/atom/has-role.ts
2984
+ const INTERNAL_ROLES = [`tracker:signal`];
2985
+ function hasRole(atom, role) {
2986
+ if (`internalRoles` in atom === false) return false;
2987
+ return atom.internalRoles.includes(role);
2988
+ }
2989
+
1908
2990
  //#endregion
1909
2991
  //#region src/internal/atom/dispose-atom.ts
1910
2992
  function disposeAtom(store, atomToken) {
@@ -1916,8 +2998,7 @@ function disposeAtom(store, atomToken) {
1916
2998
  atom.cleanup?.();
1917
2999
  const lastValue = store.valueMap.get(atom.key);
1918
3000
  const familyToken = getFamilyOfToken(store, atomToken);
1919
- const atomFamily$1 = withdraw(store, familyToken);
1920
- const subject = atomFamily$1.subject;
3001
+ const subject = withdraw(store, familyToken).subject;
1921
3002
  const disposalEvent = {
1922
3003
  type: `state_disposal`,
1923
3004
  subType: `atom`,
@@ -1941,8 +3022,7 @@ function disposeAtom(store, atomToken) {
1941
3022
  store.logger.info(`🔥`, `atom`, key, `deleted`);
1942
3023
  if (isChild && target.transactionMeta.phase === `building`) {
1943
3024
  const mostRecentUpdate = target.transactionMeta.update.subEvents.at(-1);
1944
- const wasMoleculeDisposal = mostRecentUpdate?.type === `molecule_disposal`;
1945
- const updateAlreadyCaptured = wasMoleculeDisposal && mostRecentUpdate.values.some(([k]) => k === atom.family?.key);
3025
+ const updateAlreadyCaptured = mostRecentUpdate?.type === `molecule_disposal` && mostRecentUpdate.values.some(([k]) => k === atom.family?.key);
1946
3026
  const isTracker = hasRole(atom, `tracker:signal`);
1947
3027
  if (!updateAlreadyCaptured && !isTracker) target.transactionMeta.update.subEvents.push(disposalEvent);
1948
3028
  } else store.on.atomDisposal.next(atomToken);
@@ -1976,10 +3056,7 @@ function installIntoStore(tokens, target, source) {
1976
3056
  target.logger.error(`❌`, `transaction`, targetNewest.transactionMeta.update.token.key, `could not install the following tokens into store "${target.config.name} from "${source.config.name}":`, tokens, `${targetNewest.config.name} is undergoing a transaction.`);
1977
3057
  return;
1978
3058
  }
1979
- for (const token of tokens) {
1980
- const resource = withdraw(source, token);
1981
- resource.install(target);
1982
- }
3059
+ for (const token of tokens) withdraw(source, token).install(target);
1983
3060
  }
1984
3061
 
1985
3062
  //#endregion
@@ -2046,8 +3123,7 @@ var Join = class {
2046
3123
  const relationsOfAState = find(relatedKeysAtoms, a);
2047
3124
  const currentRelationsOfA = get(relationsOfAState);
2048
3125
  for (const currentRelationB of currentRelationsOfA) {
2049
- const remainsRelated = newRelationsOfA.includes(currentRelationB);
2050
- if (remainsRelated) continue;
3126
+ if (newRelationsOfA.includes(currentRelationB)) continue;
2051
3127
  set(relatedKeysAtoms, currentRelationB, (relationsOfB) => {
2052
3128
  relationsOfB.delete(a);
2053
3129
  return relationsOfB;
@@ -2130,17 +3206,15 @@ var Join = class {
2130
3206
  const setContent = ({ set }, key, content) => {
2131
3207
  set(contentAtoms, key, content);
2132
3208
  };
2133
- const externalStoreWithContentConfiguration = {
3209
+ externalStore = Object.assign(baseExternalStoreConfiguration, {
2134
3210
  getContent: (contentKey) => {
2135
- const content = getContent(this.toolkit, contentKey);
2136
- return content;
3211
+ return getContent(this.toolkit, contentKey);
2137
3212
  },
2138
3213
  setContent: (contentKey, content) => {
2139
3214
  setContent(this.toolkit, contentKey, content);
2140
3215
  },
2141
3216
  deleteContent: (_) => {}
2142
- };
2143
- externalStore = Object.assign(baseExternalStoreConfiguration, externalStoreWithContentConfiguration);
3217
+ });
2144
3218
  } else externalStore = baseExternalStoreConfiguration;
2145
3219
  const relations = new Junction(options, {
2146
3220
  externalStore,
@@ -2173,8 +3247,7 @@ var Join = class {
2173
3247
  key: `${options.key}/multipleRelatedKeys`,
2174
3248
  get: (key) => ({ get }) => {
2175
3249
  const jsonFamily = getJsonFamily(relatedKeysAtoms, store);
2176
- const json = get(jsonFamily, key);
2177
- return json.members;
3250
+ return get(jsonFamily, key).members;
2178
3251
  }
2179
3252
  }, [`join`, `keys`]);
2180
3253
  };
@@ -2198,8 +3271,7 @@ var Join = class {
2198
3271
  key: `${options.key}/multipleRelatedEntries`,
2199
3272
  get: (x) => ({ get }) => {
2200
3273
  const jsonFamily = getJsonFamily(relatedKeysAtoms, store);
2201
- const json = get(jsonFamily, x);
2202
- return json.members.map((y) => {
3274
+ return get(jsonFamily, x).members.map((y) => {
2203
3275
  let a = relations.isAType?.(x) ? x : void 0;
2204
3276
  let b = a === void 0 ? x : void 0;
2205
3277
  a ??= y;
@@ -2289,14 +3361,13 @@ var Join = class {
2289
3361
  //#region src/internal/join/create-join.ts
2290
3362
  function createJoin(store, options, defaultContent) {
2291
3363
  store.joins.set(options.key, new Join(options, defaultContent, store));
2292
- const token = {
3364
+ return {
2293
3365
  key: options.key,
2294
3366
  type: `join`,
2295
3367
  a: options.between[0],
2296
3368
  b: options.between[1],
2297
3369
  cardinality: options.cardinality
2298
3370
  };
2299
- return token;
2300
3371
  }
2301
3372
 
2302
3373
  //#endregion
@@ -2304,8 +3375,7 @@ function createJoin(store, options, defaultContent) {
2304
3375
  function getJoin(token, store) {
2305
3376
  let myJoin = store.joins.get(token.key);
2306
3377
  if (myJoin === void 0) {
2307
- const rootJoinMap = IMPLICIT.STORE.joins;
2308
- const rootJoin = rootJoinMap.get(token.key);
3378
+ const rootJoin = IMPLICIT.STORE.joins.get(token.key);
2309
3379
  if (rootJoin === void 0) throw new Error(`Join "${token.key}" not found in store "${store.config.name}"`);
2310
3380
  const root = eldest(store);
2311
3381
  myJoin = new Join(rootJoin.options, rootJoin.defaultContent, root);
@@ -2339,13 +3409,11 @@ function findRelationsInStore(token, key, store) {
2339
3409
  relations = {
2340
3410
  get [keyAB]() {
2341
3411
  const familyAB = myJoin.states[keyAB];
2342
- const state = findInStore(store, familyAB, key);
2343
- return state;
3412
+ return findInStore(store, familyAB, key);
2344
3413
  },
2345
3414
  get [keyBA]() {
2346
3415
  const familyBA = myJoin.states[keyBA];
2347
- const state = findInStore(store, familyBA, key);
2348
- return state;
3416
+ return findInStore(store, familyBA, key);
2349
3417
  }
2350
3418
  };
2351
3419
  const entryAB = `${token.a}EntryOf${capitalize(token.b)}`;
@@ -2354,13 +3422,11 @@ function findRelationsInStore(token, key, store) {
2354
3422
  Object.assign(relations, {
2355
3423
  get [entryAB]() {
2356
3424
  const familyAB = myJoin.states[entryAB];
2357
- const state = findInStore(store, familyAB, key);
2358
- return state;
3425
+ return findInStore(store, familyAB, key);
2359
3426
  },
2360
3427
  get [entryBA]() {
2361
3428
  const familyBA = myJoin.states[entryBA];
2362
- const state = findInStore(store, familyBA, key);
2363
- return state;
3429
+ return findInStore(store, familyBA, key);
2364
3430
  }
2365
3431
  });
2366
3432
  }
@@ -2372,13 +3438,11 @@ function findRelationsInStore(token, key, store) {
2372
3438
  relations = {
2373
3439
  get [keyAB]() {
2374
3440
  const familyAB = myJoin.states[keyAB];
2375
- const state = findInStore(store, familyAB, key);
2376
- return state;
3441
+ return findInStore(store, familyAB, key);
2377
3442
  },
2378
3443
  get [keysBA]() {
2379
3444
  const familyBA = myJoin.states[keysBA];
2380
- const state = findInStore(store, familyBA, key);
2381
- return state;
3445
+ return findInStore(store, familyBA, key);
2382
3446
  }
2383
3447
  };
2384
3448
  const entryAB = `${token.a}EntryOf${capitalize(token.b)}`;
@@ -2387,13 +3451,11 @@ function findRelationsInStore(token, key, store) {
2387
3451
  Object.assign(relations, {
2388
3452
  get [entryAB]() {
2389
3453
  const familyAB = myJoin.states[entryAB];
2390
- const state = findInStore(store, familyAB, key);
2391
- return state;
3454
+ return findInStore(store, familyAB, key);
2392
3455
  },
2393
3456
  get [entriesBA]() {
2394
3457
  const familyBA = myJoin.states[entriesBA];
2395
- const state = findInStore(store, familyBA, key);
2396
- return state;
3458
+ return findInStore(store, familyBA, key);
2397
3459
  }
2398
3460
  });
2399
3461
  }
@@ -2405,13 +3467,11 @@ function findRelationsInStore(token, key, store) {
2405
3467
  relations = {
2406
3468
  get [keysAB]() {
2407
3469
  const familyAB = myJoin.states[keysAB];
2408
- const state = findInStore(store, familyAB, key);
2409
- return state;
3470
+ return findInStore(store, familyAB, key);
2410
3471
  },
2411
3472
  get [keysBA]() {
2412
3473
  const familyBA = myJoin.states[keysBA];
2413
- const state = findInStore(store, familyBA, key);
2414
- return state;
3474
+ return findInStore(store, familyBA, key);
2415
3475
  }
2416
3476
  };
2417
3477
  const entriesAB = `${token.a}EntriesOf${capitalize(token.b)}`;
@@ -2420,13 +3480,11 @@ function findRelationsInStore(token, key, store) {
2420
3480
  Object.assign(relations, {
2421
3481
  get [entriesAB]() {
2422
3482
  const familyAB = myJoin.states[entriesAB];
2423
- const state = findInStore(store, familyAB, key);
2424
- return state;
3483
+ return findInStore(store, familyAB, key);
2425
3484
  },
2426
3485
  get [entriesBA]() {
2427
3486
  const familyBA = myJoin.states[entriesBA];
2428
- const state = findInStore(store, familyBA, key);
2429
- return state;
3487
+ return findInStore(store, familyBA, key);
2430
3488
  }
2431
3489
  });
2432
3490
  }
@@ -2438,9 +3496,7 @@ function findRelationsInStore(token, key, store) {
2438
3496
  //#endregion
2439
3497
  //#region src/internal/join/get-internal-relations-from-store.ts
2440
3498
  function getInternalRelationsFromStore(token, store) {
2441
- const myJoin = getJoin(token, store);
2442
- const family = myJoin.core.relatedKeysAtoms;
2443
- return family;
3499
+ return getJoin(token, store).core.relatedKeysAtoms;
2444
3500
  }
2445
3501
 
2446
3502
  //#endregion
@@ -2554,11 +3610,10 @@ function addAtomFamilyToTimeline(store, atomFamilyToken, tl) {
2554
3610
  function joinTransaction(store, tl, txUpdateInProgress) {
2555
3611
  const currentTxKey = txUpdateInProgress.token.key;
2556
3612
  const currentTxInstanceId = txUpdateInProgress.id;
2557
- const currentTxToken = {
3613
+ const currentTransaction = withdraw(store, {
2558
3614
  key: currentTxKey,
2559
3615
  type: `transaction`
2560
- };
2561
- const currentTransaction = withdraw(store, currentTxToken);
3616
+ });
2562
3617
  if (currentTxKey && tl.transactionKey === null) {
2563
3618
  tl.transactionKey = currentTxKey;
2564
3619
  const unsubscribe = currentTransaction.subject.subscribe(`timeline:${tl.key}`, (transactionUpdate) => {
@@ -2721,5 +3776,5 @@ const timeTravel = (store, action, token) => {
2721
3776
  };
2722
3777
 
2723
3778
  //#endregion
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 };
3779
+ export { CircularBuffer, FamilyTracker, Future, IMPLICIT, INTERNAL_ROLES, JOIN_OP, Join, Junction, MapOverlay, NotFoundError, OWN_OP, 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, operateOnStore, readFromCache, readOrComputeValue, recallState, registerSelector, resetAtomOrSelector, resetInStore, seekInStore, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeInStore, subscribeToRootDependency, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceRootSelectorAtoms, updateSelectorAtoms, withdraw, writeToCache };
2725
3780
  //# sourceMappingURL=index.js.map