atom.io 0.31.0 → 0.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/data/dist/index.d.ts +867 -101
  2. package/data/dist/index.js +10 -558
  3. package/data/src/index.ts +0 -2
  4. package/data/src/struct-family.ts +1 -1
  5. package/data/src/struct.ts +1 -2
  6. package/dist/chunk-354XQWHH.js +153 -0
  7. package/dist/chunk-4LWKCEW3.js +14 -0
  8. package/dist/chunk-5F2V7S3B.js +83 -0
  9. package/dist/chunk-ECOMOMUN.js +631 -0
  10. package/dist/{chunk-42UH5F5Q.js → chunk-GY2XQYZY.js} +2051 -755
  11. package/dist/chunk-NF7FJKJD.js +107 -0
  12. package/dist/chunk-R3ZUK5EH.js +1024 -0
  13. package/dist/chunk-Z2UJW4NQ.js +523 -0
  14. package/dist/index.d.ts +855 -127
  15. package/dist/index.js +1 -143
  16. package/eslint-plugin/dist/index.d.ts +1 -30
  17. package/eslint-plugin/dist/index.js +0 -146
  18. package/eslint-plugin/src/index.ts +0 -1
  19. package/eslint-plugin/src/rules/index.ts +0 -1
  20. package/internal/dist/index.d.ts +794 -70
  21. package/internal/dist/index.js +1 -2
  22. package/internal/src/atom/create-regular-atom.ts +3 -3
  23. package/internal/src/atom/dispose-atom.ts +4 -13
  24. package/internal/src/atom/is-default.ts +3 -3
  25. package/internal/src/caching.ts +5 -5
  26. package/internal/src/capitalize.ts +3 -0
  27. package/internal/src/families/create-readonly-selector-family.ts +5 -6
  28. package/internal/src/families/create-writable-selector-family.ts +1 -4
  29. package/internal/src/families/dispose-from-store.ts +3 -13
  30. package/internal/src/families/find-in-store.ts +1 -6
  31. package/internal/src/get-state/get-from-store.ts +2 -2
  32. package/internal/src/get-state/read-or-compute-value.ts +1 -1
  33. package/internal/src/index.ts +19 -9
  34. package/internal/src/ingest-updates/ingest-creation-disposal.ts +2 -3
  35. package/internal/src/install-into-store.ts +48 -0
  36. package/internal/src/join/edit-relations-in-store.ts +32 -0
  37. package/internal/src/join/find-relations-in-store.ts +124 -0
  38. package/internal/src/join/get-internal-relations-from-store.ts +14 -0
  39. package/internal/src/join/get-join.ts +31 -0
  40. package/internal/src/join/index.ts +5 -0
  41. package/{data/src/join.ts → internal/src/join/join-internal.ts} +20 -429
  42. package/internal/src/keys.ts +7 -7
  43. package/internal/src/molecule.ts +299 -0
  44. package/internal/src/mutable/create-mutable-atom-family.ts +1 -1
  45. package/internal/src/mutable/create-mutable-atom.ts +3 -3
  46. package/internal/src/mutable/get-json-token.ts +1 -1
  47. package/internal/src/mutable/tracker-family.ts +19 -17
  48. package/internal/src/mutable/tracker.ts +8 -8
  49. package/internal/src/not-found-error.ts +8 -30
  50. package/internal/src/pretty-print.ts +2 -13
  51. package/internal/src/selector/create-readonly-selector.ts +3 -7
  52. package/internal/src/selector/create-writable-selector.ts +4 -4
  53. package/internal/src/selector/dispose-selector.ts +20 -11
  54. package/internal/src/selector/get-selector-dependency-keys.ts +1 -1
  55. package/internal/src/selector/register-selector.ts +7 -17
  56. package/internal/src/selector/trace-selector-atoms.ts +2 -2
  57. package/internal/src/set-state/copy-mutable-if-needed.ts +1 -1
  58. package/internal/src/set-state/emit-update.ts +1 -1
  59. package/internal/src/set-state/evict-downstream.ts +1 -1
  60. package/internal/src/set-state/set-atom-or-selector.ts +1 -1
  61. package/internal/src/set-state/set-atom.ts +10 -10
  62. package/internal/src/set-state/set-into-store.ts +2 -2
  63. package/internal/src/set-state/stow-update.ts +1 -1
  64. package/internal/src/store/deposit.ts +10 -8
  65. package/internal/src/store/store.ts +1 -1
  66. package/internal/src/store/withdraw.ts +34 -53
  67. package/internal/src/subscribe/recall-state.ts +1 -1
  68. package/internal/src/subscribe/subscribe-in-store.ts +3 -3
  69. package/internal/src/subscribe/subscribe-to-root-atoms.ts +3 -3
  70. package/internal/src/subscribe/subscribe-to-state.ts +5 -5
  71. package/internal/src/subscribe/subscribe-to-timeline.ts +3 -3
  72. package/internal/src/subscribe/subscribe-to-transaction.ts +3 -3
  73. package/internal/src/timeline/create-timeline.ts +17 -37
  74. package/internal/src/transaction/act-upon-store.ts +2 -2
  75. package/internal/src/transaction/apply-transaction.ts +5 -5
  76. package/internal/src/transaction/assign-transaction-to-continuity.ts +1 -1
  77. package/internal/src/transaction/build-transaction.ts +5 -8
  78. package/internal/src/transaction/create-transaction.ts +3 -3
  79. package/internal/src/transaction/get-epoch-number.ts +3 -3
  80. package/internal/src/transaction/set-epoch-number.ts +2 -2
  81. package/introspection/dist/index.d.ts +922 -6
  82. package/introspection/dist/index.js +2 -620
  83. package/json/dist/index.d.ts +899 -5
  84. package/json/dist/index.js +1 -81
  85. package/json/src/select-json-family.ts +3 -14
  86. package/package.json +27 -45
  87. package/react/dist/index.d.ts +921 -3
  88. package/react/dist/index.js +2 -82
  89. package/react/src/use-o.ts +1 -1
  90. package/react/src/use-tl.ts +2 -2
  91. package/react-devtools/dist/index.css +16 -14
  92. package/react-devtools/dist/index.d.ts +26 -1
  93. package/react-devtools/dist/index.js +6 -6
  94. package/react-devtools/src/devtools.scss +16 -14
  95. package/realtime/dist/index.d.ts +202 -8
  96. package/realtime/dist/index.js +2 -107
  97. package/realtime/src/realtime-continuity.ts +2 -2
  98. package/realtime/src/shared-room-store.ts +1 -2
  99. package/realtime-client/dist/index.d.ts +960 -22
  100. package/realtime-client/dist/index.js +3 -509
  101. package/realtime-client/src/continuity/register-and-attempt-confirmed-update.ts +3 -3
  102. package/realtime-client/src/continuity/use-conceal-state.ts +1 -1
  103. package/realtime-client/src/pull-atom-family-member.ts +2 -2
  104. package/realtime-client/src/pull-atom.ts +2 -2
  105. package/realtime-client/src/pull-mutable-atom-family-member.ts +2 -2
  106. package/realtime-client/src/pull-mutable-atom.ts +2 -2
  107. package/realtime-client/src/pull-selector-family-member.ts +4 -4
  108. package/realtime-client/src/pull-selector.ts +4 -4
  109. package/realtime-client/src/push-state.ts +5 -10
  110. package/realtime-client/src/server-action.ts +4 -4
  111. package/realtime-client/src/sync-continuity.ts +6 -6
  112. package/realtime-react/dist/index.d.ts +166 -12
  113. package/realtime-react/dist/index.js +5 -154
  114. package/realtime-react/src/use-pull-atom-family-member.ts +1 -1
  115. package/realtime-react/src/use-pull-atom.ts +1 -1
  116. package/realtime-react/src/use-pull-mutable-atom.ts +1 -1
  117. package/realtime-react/src/use-pull-mutable-family-member.ts +1 -1
  118. package/realtime-react/src/use-pull-selector-family-member.ts +1 -1
  119. package/realtime-react/src/use-pull-selector.ts +1 -1
  120. package/realtime-react/src/use-push.ts +1 -1
  121. package/realtime-react/src/use-server-action.ts +2 -2
  122. package/realtime-react/src/use-sync-continuity.ts +1 -1
  123. package/realtime-server/dist/index.d.ts +971 -28
  124. package/realtime-server/dist/index.js +3 -1001
  125. package/realtime-server/src/continuity/prepare-to-serve-transaction-request.ts +1 -1
  126. package/realtime-server/src/continuity/prepare-to-sync-realtime-continuity.ts +3 -3
  127. package/realtime-server/src/continuity/subscribe-to-continuity-actions.ts +2 -2
  128. package/realtime-server/src/continuity/subscribe-to-continuity-perpectives.ts +2 -2
  129. package/realtime-server/src/ipc-sockets/child-socket.ts +0 -1
  130. package/realtime-server/src/realtime-action-receiver.ts +1 -1
  131. package/realtime-server/src/realtime-family-provider.ts +2 -2
  132. package/realtime-server/src/realtime-mutable-family-provider.ts +2 -2
  133. package/realtime-server/src/realtime-mutable-provider.ts +2 -2
  134. package/realtime-server/src/realtime-server-stores/server-room-external-actions.ts +2 -1
  135. package/realtime-server/src/realtime-server-stores/server-room-external-store.ts +1 -1
  136. package/realtime-server/src/realtime-server-stores/server-user-store.ts +1 -2
  137. package/realtime-server/src/realtime-state-provider.ts +2 -2
  138. package/realtime-testing/dist/index.d.ts +1091 -3
  139. package/realtime-testing/dist/index.js +23 -26
  140. package/realtime-testing/src/setup-realtime-test.tsx +6 -5
  141. package/src/atom.ts +53 -29
  142. package/src/dispose-state.ts +12 -2
  143. package/{ephemeral/src → src}/find-state.ts +35 -25
  144. package/src/get-state.ts +16 -0
  145. package/src/index.ts +77 -3
  146. package/src/join.ts +218 -0
  147. package/src/realm.ts +169 -0
  148. package/src/selector.ts +20 -0
  149. package/src/set-state.ts +16 -8
  150. package/src/silo.ts +13 -7
  151. package/src/timeline.ts +1 -1
  152. package/src/transaction.ts +4 -8
  153. package/transceivers/set-rtx/dist/index.d.ts +37 -2
  154. package/transceivers/set-rtx/dist/index.js +1 -212
  155. package/transceivers/set-rtx/src/set-rtx.ts +4 -1
  156. package/web/dist/index.d.ts +30 -1
  157. package/web/dist/index.js +1 -15
  158. package/data/src/until.ts +0 -15
  159. package/dist/chunk-ICGFFQ3H.js +0 -272
  160. package/ephemeral/dist/index.d.ts +0 -57
  161. package/ephemeral/dist/index.js +0 -9
  162. package/ephemeral/package.json +0 -13
  163. package/ephemeral/src/index.ts +0 -1
  164. package/eslint-plugin/src/rules/lifespan.ts +0 -203
  165. package/immortal/dist/index.d.ts +0 -12
  166. package/immortal/dist/index.js +0 -9
  167. package/immortal/package.json +0 -13
  168. package/immortal/src/index.ts +0 -1
  169. package/immortal/src/seek-state.ts +0 -60
  170. package/src/allocate.ts +0 -443
  171. package/src/molecule.ts +0 -16
@@ -1,7 +1,10 @@
1
- import { deallocateFromStore, allocateIntoStore, claimWithinStore } from './chunk-ICGFFQ3H.js';
2
- import { stringifyJson, parseJson, selectJson, selectJsonFamily } from 'atom.io/json';
3
- import { AtomIOLogger } from 'atom.io';
4
- import { subscribeToTimeline, subscribeToTransaction, subscribeToState, arbitrary as arbitrary$1 } from 'atom.io/internal';
1
+ // json/src/entries.ts
2
+ function fromEntries(entries) {
3
+ return Object.fromEntries(entries);
4
+ }
5
+ function toEntries(obj) {
6
+ return Object.entries(obj);
7
+ }
5
8
 
6
9
  // internal/src/arbitrary.ts
7
10
  function arbitrary(random = Math.random) {
@@ -93,6 +96,8 @@ var CircularBuffer = class _CircularBuffer {
93
96
  return copy;
94
97
  }
95
98
  };
99
+
100
+ // internal/src/store/counterfeit.ts
96
101
  var FAMILY_MEMBER_TOKEN_TYPES = {
97
102
  atom_family: `atom`,
98
103
  mutable_atom_family: `mutable_atom`,
@@ -130,349 +135,161 @@ function deposit(state) {
130
135
  return token;
131
136
  }
132
137
 
133
- // internal/src/junction.ts
134
- var Junction = class {
135
- a;
136
- b;
137
- cardinality;
138
- relations = /* @__PURE__ */ new Map();
139
- contents = /* @__PURE__ */ new Map();
140
- isAType;
141
- isBType;
142
- isContent;
143
- makeContentKey = (a, b) => `${a}:${b}`;
144
- warn;
145
- getRelatedKeys(key) {
146
- return this.relations.get(key);
147
- }
148
- addRelation(a, b) {
149
- let aRelations = this.relations.get(a);
150
- let bRelations = this.relations.get(b);
151
- if (aRelations) {
152
- aRelations.add(b);
153
- } else {
154
- aRelations = /* @__PURE__ */ new Set([b]);
155
- this.relations.set(a, aRelations);
156
- }
157
- if (bRelations) {
158
- bRelations.add(a);
159
- } else {
160
- bRelations = /* @__PURE__ */ new Set([a]);
161
- this.relations.set(b, bRelations);
162
- }
138
+ // src/atom.ts
139
+ function atom(options) {
140
+ return createStandaloneAtom(IMPLICIT.STORE, options);
141
+ }
142
+ function atomFamily(options) {
143
+ return createAtomFamily(IMPLICIT.STORE, options);
144
+ }
145
+
146
+ // src/dispose-state.ts
147
+ function disposeState(...[token, key]) {
148
+ if (key) {
149
+ disposeFromStore(IMPLICIT.STORE, token, key);
150
+ } else {
151
+ disposeFromStore(IMPLICIT.STORE, token);
163
152
  }
164
- deleteRelation(a, b) {
165
- const aRelations = this.relations.get(a);
166
- if (aRelations) {
167
- aRelations.delete(b);
168
- if (aRelations.size === 0) {
169
- this.relations.delete(a);
170
- }
171
- const bRelations = this.relations.get(b);
172
- if (bRelations) {
173
- bRelations.delete(a);
174
- if (bRelations.size === 0) {
175
- this.relations.delete(b);
176
- }
177
- }
178
- }
153
+ }
154
+
155
+ // src/find-state.ts
156
+ function findState(token, key) {
157
+ const state = findInStore(IMPLICIT.STORE, token, key);
158
+ return state;
159
+ }
160
+
161
+ // src/get-state.ts
162
+ function getState(...params) {
163
+ if (params.length === 2) {
164
+ return getFromStore(IMPLICIT.STORE, ...params);
179
165
  }
180
- replaceRelationsUnsafely(x, ys) {
181
- this.relations.set(x, new Set(ys));
182
- for (const y of ys) {
183
- const yRelations = (/* @__PURE__ */ new Set()).add(x);
184
- this.relations.set(y, yRelations);
166
+ return getFromStore(IMPLICIT.STORE, ...params);
167
+ }
168
+
169
+ // src/join.ts
170
+ function join(options, defaultContent, store = IMPLICIT.STORE) {
171
+ store.joins.set(options.key, new Join(options, defaultContent, store));
172
+ const token = {
173
+ key: options.key,
174
+ type: `join`,
175
+ a: options.between[0],
176
+ b: options.between[1],
177
+ cardinality: options.cardinality
178
+ };
179
+ return token;
180
+ }
181
+ function findRelations(token, key) {
182
+ return findRelationsInStore(token, key, IMPLICIT.STORE);
183
+ }
184
+ function editRelations(token, change) {
185
+ editRelationsInStore(token, change, IMPLICIT.STORE);
186
+ }
187
+ function getInternalRelations(token) {
188
+ return getInternalRelationsFromStore(token, IMPLICIT.STORE);
189
+ }
190
+
191
+ // src/logger.ts
192
+ var LOG_LEVELS = [`info`, `warn`, `error`];
193
+ var simpleLog = (logLevel) => (icon, denomination, tokenKey, message, ...rest) => {
194
+ console[logLevel](
195
+ `${icon} ${denomination} "${tokenKey}" ${message}`,
196
+ ...rest
197
+ );
198
+ };
199
+ var simpleLogger = {
200
+ error: simpleLog(`error`),
201
+ info: simpleLog(`info`),
202
+ warn: simpleLog(`warn`)
203
+ };
204
+ var AtomIOLogger = class {
205
+ constructor(logLevel, filter, logger = simpleLogger) {
206
+ this.logLevel = logLevel;
207
+ this.filter = filter;
208
+ this.logger = logger;
209
+ }
210
+ error = (...args) => {
211
+ if ((this.filter?.(...args) ?? true) && this.logLevel !== null) {
212
+ this.logger.error(...args);
185
213
  }
186
- }
187
- replaceRelationsSafely(x, ys) {
188
- const xRelationsPrev = this.relations.get(x);
189
- let a = this.isAType?.(x) ? x : undefined;
190
- let b = a === undefined ? x : undefined;
191
- if (xRelationsPrev) {
192
- for (const y of xRelationsPrev) {
193
- a ??= y;
194
- b ??= y;
195
- const yRelations = this.relations.get(y);
196
- if (yRelations) {
197
- if (yRelations.size === 1) {
198
- this.relations.delete(y);
199
- } else {
200
- yRelations.delete(x);
201
- }
202
- this.contents.delete(this.makeContentKey(a, b));
203
- }
204
- }
214
+ };
215
+ info = (...args) => {
216
+ if ((this.filter?.(...args) ?? true) && this.logLevel === `info`) {
217
+ this.logger.info(...args);
205
218
  }
206
- this.relations.set(x, new Set(ys));
207
- for (const y of ys) {
208
- let yRelations = this.relations.get(y);
209
- if (yRelations) {
210
- yRelations.add(x);
211
- } else {
212
- yRelations = (/* @__PURE__ */ new Set()).add(x);
213
- this.relations.set(y, yRelations);
214
- }
219
+ };
220
+ warn = (...args) => {
221
+ if ((this.filter?.(...args) ?? true) && this.logLevel !== `error` && this.logLevel !== null) {
222
+ this.logger.warn(...args);
215
223
  }
224
+ };
225
+ };
226
+
227
+ // src/realm.ts
228
+ var $claim = Symbol(`claim`);
229
+ var Realm = class {
230
+ store;
231
+ constructor(store = IMPLICIT.STORE) {
232
+ this.store = store;
233
+ makeRootMoleculeInStore(`root`, store);
234
+ }
235
+ allocate(provenance, key, attachmentStyle) {
236
+ return allocateIntoStore(
237
+ this.store,
238
+ provenance,
239
+ key,
240
+ attachmentStyle
241
+ );
216
242
  }
217
- getContentInternal(contentKey) {
218
- return this.contents.get(contentKey);
243
+ fuse(type, reagentA, reagentB) {
244
+ return fuseWithinStore(this.store, type, reagentA, reagentB);
219
245
  }
220
- setContent(contentKey, content) {
221
- this.contents.set(contentKey, content);
246
+ deallocate(claim) {
247
+ deallocateFromStore(this.store, claim);
222
248
  }
223
- deleteContent(contentKey) {
224
- this.contents.delete(contentKey);
249
+ claim(newProvenance, claim, exclusive) {
250
+ return claimWithinStore(this.store, newProvenance, claim, exclusive);
225
251
  }
226
- constructor(data, config) {
227
- this.a = data.between[0];
228
- this.b = data.between[1];
229
- this.cardinality = data.cardinality;
230
- if (!config?.externalStore) {
231
- this.relations = new Map(
232
- data.relations?.map(([x, ys]) => [x, new Set(ys)])
233
- );
234
- this.contents = new Map(data.contents);
235
- }
236
- this.isAType = config?.isAType ?? null;
237
- this.isBType = config?.isBType ?? null;
238
- this.isContent = config?.isContent ?? null;
239
- if (config?.makeContentKey) {
240
- this.makeContentKey = config.makeContentKey;
241
- }
242
- if (config?.externalStore) {
243
- const externalStore = config.externalStore;
244
- this.has = (a, b) => externalStore.has(a, b);
245
- this.addRelation = (a, b) => {
246
- externalStore.addRelation(a, b);
247
- };
248
- this.deleteRelation = (a, b) => {
249
- externalStore.deleteRelation(a, b);
250
- };
251
- this.replaceRelationsSafely = (a, bs) => {
252
- externalStore.replaceRelationsSafely(a, bs);
253
- };
254
- this.replaceRelationsUnsafely = (a, bs) => {
255
- externalStore.replaceRelationsUnsafely(a, bs);
256
- };
257
- this.getRelatedKeys = (key) => externalStore.getRelatedKeys(
258
- key
259
- );
260
- if (externalStore.getContent) {
261
- this.getContentInternal = (contentKey) => {
262
- return externalStore.getContent(contentKey);
263
- };
264
- this.setContent = (contentKey, content) => {
265
- externalStore.setContent(contentKey, content);
266
- };
267
- this.deleteContent = (contentKey) => {
268
- externalStore.deleteContent(contentKey);
269
- };
270
- }
271
- for (const [x, ys] of data.relations ?? []) {
272
- let a = this.isAType?.(x) ? x : undefined;
273
- let b = a === undefined ? x : undefined;
274
- for (const y of ys) {
275
- a ??= y;
276
- b ??= y;
277
- this.addRelation(a, b);
278
- }
279
- }
280
- for (const [contentKey, content] of data.contents ?? []) {
281
- this.setContent(contentKey, content);
282
- }
283
- }
284
- if (config?.warn) {
285
- this.warn = config.warn;
286
- }
252
+ };
253
+ var Anarchy = class {
254
+ store;
255
+ realm;
256
+ constructor(store = IMPLICIT.STORE) {
257
+ this.store = store;
258
+ this.realm = new Realm(store);
259
+ }
260
+ allocate(provenance, key, attachmentStyle) {
261
+ allocateIntoStore(
262
+ this.store,
263
+ provenance,
264
+ key,
265
+ attachmentStyle
266
+ );
287
267
  }
288
- toJSON() {
289
- return {
290
- between: [this.a, this.b],
291
- cardinality: this.cardinality,
292
- relations: [...this.relations.entries()].map(
293
- ([a, b]) => [a, [...b]]
294
- ),
295
- contents: [...this.contents.entries()]
296
- };
268
+ deallocate(key) {
269
+ deallocateFromStore(this.store, key);
297
270
  }
298
- set(...params) {
299
- let a;
300
- let b;
301
- let content;
302
- switch (params.length) {
303
- case 1: {
304
- const relation = params[0];
305
- a = relation[this.a];
306
- b = relation[this.b];
307
- content = undefined;
308
- break;
309
- }
310
- case 2: {
311
- const zeroth = params[0];
312
- if (typeof zeroth === `string`) {
313
- [a, b] = params;
314
- } else {
315
- a = zeroth[this.a];
316
- b = zeroth[this.b];
317
- content = params[1];
318
- }
319
- break;
320
- }
321
- default: {
322
- a = params[0];
323
- b = params[1];
324
- content = params[2];
325
- break;
326
- }
327
- }
328
- switch (this.cardinality) {
329
- // biome-ignore lint/suspicious/noFallthroughSwitchClause: perfect here
330
- case `1:1`: {
331
- const bPrev = this.getRelatedKey(a);
332
- if (bPrev && bPrev !== b) this.delete(a, bPrev);
333
- }
334
- case `1:n`: {
335
- const aPrev = this.getRelatedKey(b);
336
- if (aPrev && aPrev !== a) this.delete(aPrev, b);
337
- }
338
- }
339
- if (content) {
340
- const contentKey = this.makeContentKey(a, b);
341
- this.setContent(contentKey, content);
342
- }
343
- this.addRelation(a, b);
344
- return this;
345
- }
346
- delete(x, b) {
347
- b = typeof b === `string` ? b : x[this.b];
348
- const a = (
349
- // @ts-expect-error we deduce that this.a may index x
350
- typeof x === `string` ? x : x[this.a]
351
- );
352
- if (a === undefined && typeof b === `string`) {
353
- const bRelations = this.getRelatedKeys(b);
354
- if (bRelations) {
355
- for (const bRelation of bRelations) {
356
- this.delete(bRelation, b);
357
- }
358
- }
359
- }
360
- if (typeof a === `string` && b === undefined) {
361
- const aRelations = this.getRelatedKeys(a);
362
- if (aRelations) {
363
- for (const aRelation of aRelations) {
364
- this.delete(a, aRelation);
365
- }
366
- }
367
- }
368
- if (typeof a === `string` && typeof b === `string`) {
369
- this.deleteRelation(a, b);
370
- const contentKey = this.makeContentKey(a, b);
371
- this.deleteContent(contentKey);
372
- }
373
- return this;
374
- }
375
- getRelatedKey(key) {
376
- const relations = this.getRelatedKeys(key);
377
- if (relations) {
378
- if (relations.size > 1) {
379
- this.warn?.(
380
- `${relations.size} related keys were found for key "${key}": (${[
381
- ...relations
382
- ].map((k) => `"${k}"`).join(`, `)}). Only one related key was expected.`
383
- );
384
- }
385
- let singleRelation;
386
- for (const relation of relations) {
387
- singleRelation = relation;
388
- break;
389
- }
390
- return singleRelation;
391
- }
392
- }
393
- replaceRelations(x, relations, config) {
394
- const hasContent = !Array.isArray(relations);
395
- const ys = hasContent ? Object.keys(relations) : relations;
396
- if (config?.reckless) {
397
- this.replaceRelationsUnsafely(x, ys);
398
- } else {
399
- this.replaceRelationsSafely(x, ys);
400
- }
401
- if (hasContent) {
402
- for (const y of ys) {
403
- const contentKey = this.makeContentKey(x, y);
404
- const content = relations[y];
405
- this.setContent(contentKey, content);
406
- }
407
- }
408
- return this;
409
- }
410
- getContent(a, b) {
411
- const contentKey = this.makeContentKey(a, b);
412
- return this.getContentInternal(contentKey);
413
- }
414
- getRelationEntries(input) {
415
- const a = input[this.a];
416
- const b = input[this.b];
417
- if (a !== undefined && b === undefined) {
418
- const aRelations = this.getRelatedKeys(a);
419
- if (aRelations) {
420
- return [...aRelations].map((aRelation) => {
421
- return [aRelation, this.getContent(a, aRelation)];
422
- });
423
- }
424
- }
425
- if (a === undefined && b !== undefined) {
426
- const bRelations = this.getRelatedKeys(b);
427
- if (bRelations) {
428
- return [...bRelations].map((bRelation) => {
429
- return [bRelation, this.getContent(bRelation, b)];
430
- });
431
- }
432
- }
433
- return [];
434
- }
435
- has(a, b) {
436
- if (b) {
437
- const setA = this.getRelatedKeys(a);
438
- return setA?.has(b) ?? false;
439
- }
440
- return this.relations.has(a);
271
+ claim(newProvenance, key, exclusive) {
272
+ claimWithinStore(this.store, newProvenance, key, exclusive);
441
273
  }
442
274
  };
275
+ var T$ = `T$`;
443
276
 
444
- // internal/src/subject.ts
445
- var Subject = class {
446
- Subscriber;
447
- subscribers = /* @__PURE__ */ new Map();
448
- subscribe(key, subscriber) {
449
- this.subscribers.set(key, subscriber);
450
- const unsubscribe = () => {
451
- this.unsubscribe(key);
452
- };
453
- return unsubscribe;
454
- }
455
- unsubscribe(key) {
456
- this.subscribers.delete(key);
457
- }
458
- next(value) {
459
- const subscribers = this.subscribers.values();
460
- for (const subscriber of subscribers) {
461
- subscriber(value);
462
- }
463
- }
464
- };
465
- var StatefulSubject = class extends Subject {
466
- state;
467
- constructor(initialState) {
468
- super();
469
- this.state = initialState;
470
- }
471
- next(value) {
472
- this.state = value;
473
- super.next(value);
277
+ // src/selector.ts
278
+ function selector(options) {
279
+ return createStandaloneSelector(IMPLICIT.STORE, options);
280
+ }
281
+ function selectorFamily(options) {
282
+ return createSelectorFamily(IMPLICIT.STORE, options);
283
+ }
284
+
285
+ // src/set-state.ts
286
+ function setState(...params) {
287
+ if (params.length === 2) {
288
+ setIntoStore(IMPLICIT.STORE, ...params);
289
+ } else {
290
+ setIntoStore(IMPLICIT.STORE, ...params);
474
291
  }
475
- };
292
+ }
476
293
 
477
294
  // internal/src/transaction/is-root-store.ts
478
295
  function isRootStore(store) {
@@ -503,34 +320,29 @@ var abortTransaction = (store) => {
503
320
  target.parent.child = null;
504
321
  };
505
322
 
323
+ // internal/src/capitalize.ts
324
+ function capitalize(string) {
325
+ return string[0].toUpperCase() + string.slice(1);
326
+ }
327
+
506
328
  // internal/src/pretty-print.ts
507
- var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
508
329
  function prettyPrintTokenType(token) {
509
330
  return token.type.split(`_`).map(capitalize).join(` `);
510
331
  }
511
332
 
512
333
  // internal/src/not-found-error.ts
513
334
  var NotFoundError = class extends Error {
514
- constructor(...params) {
515
- const token = params[0];
516
- const store = params.length === 2 ? params[1] : params[2];
517
- if (params.length === 2) {
518
- super(
519
- `${prettyPrintTokenType(token)} ${stringifyJson(token.key)} not found in store "${store.config.name}".`
520
- );
521
- } else {
522
- const key = params[1];
523
- super(
524
- `${prettyPrintTokenType(token)} "${token.key}" member ${stringifyJson(key)} not found in store "${store.config.name}".`
525
- );
526
- }
335
+ constructor(token, store) {
336
+ super(
337
+ `${prettyPrintTokenType(token)} ${stringifyJson(token.key)} not found in store "${store.config.name}".`
338
+ );
527
339
  }
528
340
  };
529
341
 
530
342
  // internal/src/transaction/act-upon-store.ts
531
- function actUponStore(token, id, store) {
343
+ function actUponStore(store, token, id) {
532
344
  return (...parameters) => {
533
- const tx = withdraw(token, store);
345
+ const tx = withdraw(store, token);
534
346
  if (tx) {
535
347
  return tx.run(parameters, id);
536
348
  }
@@ -542,7 +354,7 @@ function actUponStore(token, id, store) {
542
354
  var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(originalThing) : nextVersionOfThing;
543
355
 
544
356
  // internal/src/get-state/read-or-compute-value.ts
545
- var readOrComputeValue = (state, target) => {
357
+ var readOrComputeValue = (target, state) => {
546
358
  if (target.valueMap.has(state.key)) {
547
359
  target.logger.info(`\u{1F4D6}`, state.type, state.key, `reading cached value`);
548
360
  return readCachedValue(state, target);
@@ -626,7 +438,7 @@ var markDone = (store, key) => {
626
438
  };
627
439
 
628
440
  // internal/src/set-state/emit-update.ts
629
- var emitUpdate = (state, update, store) => {
441
+ var emitUpdate = (store, state, update) => {
630
442
  switch (state.type) {
631
443
  case `mutable_atom`:
632
444
  store.logger.info(
@@ -656,13 +468,13 @@ var emitUpdate = (state, update, store) => {
656
468
  };
657
469
 
658
470
  // internal/src/set-state/evict-downstream.ts
659
- var evictDownStream = (atom, store) => {
471
+ var evictDownStream = (store, atom2) => {
660
472
  const target = newest(store);
661
- const downstreamKeys = target.selectorAtoms.getRelatedKeys(atom.key);
473
+ const downstreamKeys = target.selectorAtoms.getRelatedKeys(atom2.key);
662
474
  target.logger.info(
663
475
  `\u{1F9F9}`,
664
- atom.type,
665
- atom.key,
476
+ atom2.type,
477
+ atom2.key,
666
478
  downstreamKeys ? `evicting ${downstreamKeys.size} states downstream:` : `no downstream states`,
667
479
  downstreamKeys ?? `to evict`
668
480
  );
@@ -670,8 +482,8 @@ var evictDownStream = (atom, store) => {
670
482
  if (target.operation.open) {
671
483
  target.logger.info(
672
484
  `\u{1F9F9}`,
673
- atom.type,
674
- atom.key,
485
+ atom2.type,
486
+ atom2.key,
675
487
  `[ ${[...target.operation.done].join(`, `)} ] already done`
676
488
  );
677
489
  }
@@ -695,7 +507,7 @@ function shouldUpdateBeStowed(key, update) {
695
507
  }
696
508
  return true;
697
509
  }
698
- var stowUpdate = (state, update, store) => {
510
+ var stowUpdate = (store, state, update) => {
699
511
  const { key } = state;
700
512
  const target = newest(store);
701
513
  if (!isChildStore(target) || target.transactionMeta.phase !== `building`) {
@@ -733,45 +545,45 @@ var stowUpdate = (state, update, store) => {
733
545
  };
734
546
 
735
547
  // internal/src/set-state/set-atom.ts
736
- var setAtom = (atom, next, target) => {
737
- const oldValue = readOrComputeValue(atom, target);
548
+ var setAtom = (atom2, next, target) => {
549
+ const oldValue = readOrComputeValue(target, atom2);
738
550
  let newValue = oldValue;
739
- if (atom.type === `mutable_atom` && isChildStore(target)) {
551
+ if (atom2.type === `mutable_atom` && isChildStore(target)) {
740
552
  const { parent } = target;
741
- const copiedValue = copyMutableIfNeeded(atom, parent, target);
553
+ const copiedValue = copyMutableIfNeeded(target, atom2, parent);
742
554
  newValue = copiedValue;
743
555
  }
744
556
  newValue = become(next)(newValue);
745
- target.logger.info(`\u{1F4DD}`, `atom`, atom.key, `set to`, newValue);
746
- newValue = cacheValue(atom.key, newValue, atom.subject, target);
747
- if (isAtomDefault(atom.key, target)) {
748
- markAtomAsNotDefault(atom.key, target);
557
+ target.logger.info(`\u{1F4DD}`, `atom`, atom2.key, `set to`, newValue);
558
+ newValue = cacheValue(target, atom2.key, newValue, atom2.subject);
559
+ if (isAtomDefault(target, atom2.key)) {
560
+ markAtomAsNotDefault(target, atom2.key);
749
561
  }
750
- markDone(target, atom.key);
751
- evictDownStream(atom, target);
562
+ markDone(target, atom2.key);
563
+ evictDownStream(target, atom2);
752
564
  const update = { oldValue, newValue };
753
565
  if (isRootStore(target)) {
754
- emitUpdate(atom, update, target);
566
+ emitUpdate(target, atom2, update);
755
567
  } else if (target.parent) {
756
568
  if (target.on.transactionApplying.state === null) {
757
- stowUpdate(atom, update, target);
758
- } else if (atom.key.startsWith(`*`)) {
759
- const mutableKey = atom.key.slice(1);
569
+ stowUpdate(target, atom2, update);
570
+ } else if (atom2.key.startsWith(`*`)) {
571
+ const mutableKey = atom2.key.slice(1);
760
572
  const mutableAtom = target.atoms.get(mutableKey);
761
573
  let transceiver = target.valueMap.get(mutableKey);
762
574
  if (mutableAtom.type === `mutable_atom` && isChildStore(target)) {
763
575
  const { parent } = target;
764
- const copiedValue = copyMutableIfNeeded(mutableAtom, parent, target);
576
+ const copiedValue = copyMutableIfNeeded(target, mutableAtom, parent);
765
577
  transceiver = copiedValue;
766
578
  }
767
579
  const accepted = transceiver.do(update.newValue) === null;
768
- if (accepted) evictDownStream(mutableAtom, target);
580
+ if (accepted) evictDownStream(target, mutableAtom);
769
581
  }
770
582
  }
771
583
  };
772
584
 
773
585
  // internal/src/set-state/set-atom-or-selector.ts
774
- var setAtomOrSelector = (state, value, store) => {
586
+ var setAtomOrSelector = (store, state, value) => {
775
587
  switch (state.type) {
776
588
  case `atom`:
777
589
  case `mutable_atom`:
@@ -782,6 +594,41 @@ var setAtomOrSelector = (state, value, store) => {
782
594
  break;
783
595
  }
784
596
  };
597
+
598
+ // internal/src/subject.ts
599
+ var Subject = class {
600
+ Subscriber;
601
+ subscribers = /* @__PURE__ */ new Map();
602
+ subscribe(key, subscriber) {
603
+ this.subscribers.set(key, subscriber);
604
+ const unsubscribe = () => {
605
+ this.unsubscribe(key);
606
+ };
607
+ return unsubscribe;
608
+ }
609
+ unsubscribe(key) {
610
+ this.subscribers.delete(key);
611
+ }
612
+ next(value) {
613
+ const subscribers = this.subscribers.values();
614
+ for (const subscriber of subscribers) {
615
+ subscriber(value);
616
+ }
617
+ }
618
+ };
619
+ var StatefulSubject = class extends Subject {
620
+ state;
621
+ constructor(initialState) {
622
+ super();
623
+ this.state = initialState;
624
+ }
625
+ next(value) {
626
+ this.state = value;
627
+ super.next(value);
628
+ }
629
+ };
630
+
631
+ // internal/src/families/create-regular-atom-family.ts
785
632
  function createRegularAtomFamily(store, options, internalRoles) {
786
633
  const familyToken = {
787
634
  key: options.key,
@@ -816,12 +663,12 @@ function createRegularAtomFamily(store, options, internalRoles) {
816
663
  subject.next({ type: `state_creation`, token });
817
664
  return token;
818
665
  };
819
- const atomFamily = Object.assign(familyFunction, familyToken, {
666
+ const atomFamily2 = Object.assign(familyFunction, familyToken, {
820
667
  subject,
821
668
  install: (s) => createRegularAtomFamily(s, options),
822
669
  internalRoles
823
670
  });
824
- store.families.set(options.key, atomFamily);
671
+ store.families.set(options.key, atomFamily2);
825
672
  store.defaults.set(options.key, options.default);
826
673
  return familyToken;
827
674
  }
@@ -836,14 +683,14 @@ function createAtomFamily(store, options) {
836
683
  }
837
684
 
838
685
  // internal/src/keys.ts
839
- var isAtomKey = (key, store) => newest(store).atoms.has(key);
840
- var isSelectorKey = (key, store) => newest(store).selectors.has(key);
841
- var isReadonlySelectorKey = (key, store) => newest(store).readonlySelectors.has(key);
842
- var isStateKey = (key, store) => isAtomKey(key, store) || isSelectorKey(key, store) || isReadonlySelectorKey(key, store);
686
+ var isAtomKey = (store, key) => newest(store).atoms.has(key);
687
+ var isSelectorKey = (store, key) => newest(store).selectors.has(key);
688
+ var isReadonlySelectorKey = (store, key) => newest(store).readonlySelectors.has(key);
689
+ var isStateKey = (store, key) => isAtomKey(store, key) || isSelectorKey(store, key) || isReadonlySelectorKey(store, key);
843
690
 
844
691
  // internal/src/selector/get-selector-dependency-keys.ts
845
692
  var getSelectorDependencyKeys = (key, store) => {
846
- const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(source, store));
693
+ const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(store, source));
847
694
  return sources;
848
695
  };
849
696
 
@@ -860,7 +707,7 @@ var traceSelectorAtoms = (directDependencyKey, covered, store) => {
860
707
  continue;
861
708
  }
862
709
  covered.add(indirectDependencyKey);
863
- if (!isAtomKey(indirectDependencyKey, store)) {
710
+ if (!isAtomKey(store, indirectDependencyKey)) {
864
711
  indirectDependencyKeys.push(
865
712
  ...getSelectorDependencyKeys(indirectDependencyKey, store)
866
713
  );
@@ -870,12 +717,12 @@ var traceSelectorAtoms = (directDependencyKey, covered, store) => {
870
717
  }
871
718
  return rootKeys;
872
719
  };
873
- var traceAllSelectorAtoms = (selector, store) => {
874
- const selectorKey = selector.key;
720
+ var traceAllSelectorAtoms = (selector2, store) => {
721
+ const selectorKey = selector2.key;
875
722
  const directDependencyKeys = getSelectorDependencyKeys(selectorKey, store);
876
723
  const covered = /* @__PURE__ */ new Set();
877
724
  return directDependencyKeys.flatMap(
878
- (depKey) => isAtomKey(depKey, store) ? depKey : traceSelectorAtoms(depKey, covered, store)
725
+ (depKey) => isAtomKey(store, depKey) ? depKey : traceSelectorAtoms(depKey, covered, store)
879
726
  );
880
727
  };
881
728
 
@@ -922,8 +769,8 @@ var registerSelector = (selectorKey, covered, store) => ({
922
769
  } else {
923
770
  [dependency] = params;
924
771
  }
925
- const dependencyState = withdraw(dependency, store);
926
- const dependencyValue = readOrComputeValue(dependencyState, store);
772
+ const dependencyState = withdraw(store, dependency);
773
+ const dependencyValue = readOrComputeValue(store, dependencyState);
927
774
  store.logger.info(
928
775
  `\u{1F50C}`,
929
776
  `selector`,
@@ -954,18 +801,13 @@ var registerSelector = (selectorKey, covered, store) => ({
954
801
  const family = params[0];
955
802
  const key = params[1];
956
803
  value = params[2];
957
- const maybeToken = store.config.lifespan === `ephemeral` ? findInStore(store, family, key) : seekInStore(store, family, key);
958
- if (!maybeToken) {
959
- throw new NotFoundError(family, key, store);
960
- }
961
- token = maybeToken;
804
+ token = findInStore(store, family, key);
962
805
  }
963
806
  const target = newest(store);
964
- const state = withdraw(token, target);
965
- setAtomOrSelector(state, value, target);
807
+ const state = withdraw(target, token);
808
+ setAtomOrSelector(target, state, value);
966
809
  },
967
810
  find: (token, key) => findInStore(store, token, key),
968
- seek: (token, key) => seekInStore(store, token, key),
969
811
  json: (token) => getJsonToken(store, token)
970
812
  });
971
813
 
@@ -974,14 +816,10 @@ var createReadonlySelector = (store, options, family) => {
974
816
  const target = newest(store);
975
817
  const subject = new Subject();
976
818
  const covered = /* @__PURE__ */ new Set();
977
- const { get, find, seek, json } = registerSelector(
978
- options.key,
979
- covered,
980
- target
981
- );
819
+ const { get, find, json } = registerSelector(options.key, covered, target);
982
820
  const getSelf = () => {
983
- const value = options.get({ get, find, seek, json });
984
- cacheValue(options.key, value, subject, newest(store));
821
+ const value = options.get({ get, find, json });
822
+ cacheValue(newest(store), options.key, value, subject);
985
823
  covered.clear();
986
824
  return value;
987
825
  };
@@ -1018,11 +856,11 @@ var createWritableSelector = (store, options, family) => {
1018
856
  const subject = new Subject();
1019
857
  const covered = /* @__PURE__ */ new Set();
1020
858
  const setterToolkit = registerSelector(options.key, covered, target);
1021
- const { find, get, seek, json } = setterToolkit;
1022
- const getterToolkit = { find, get, seek, json };
859
+ const { find, get, json } = setterToolkit;
860
+ const getterToolkit = { find, get, json };
1023
861
  const getSelf = (getFn = options.get, innerTarget = newest(store)) => {
1024
862
  const value = getFn(getterToolkit);
1025
- cacheValue(options.key, value, subject, innerTarget);
863
+ cacheValue(innerTarget, options.key, value, subject);
1026
864
  covered.clear();
1027
865
  return value;
1028
866
  };
@@ -1040,7 +878,7 @@ var createWritableSelector = (store, options, family) => {
1040
878
  newValue,
1041
879
  `)`
1042
880
  );
1043
- cacheValue(options.key, newValue, subject, innerTarget);
881
+ cacheValue(innerTarget, options.key, newValue, subject);
1044
882
  markDone(innerTarget, options.key);
1045
883
  if (isRootStore(innerTarget)) {
1046
884
  subject.next({ newValue, oldValue });
@@ -1083,11 +921,11 @@ function createStandaloneSelector(store, options) {
1083
921
  }
1084
922
 
1085
923
  // internal/src/selector/dispose-selector.ts
1086
- function disposeSelector(selectorToken, store) {
924
+ function disposeSelector(store, selectorToken) {
1087
925
  const target = newest(store);
1088
926
  const { key } = selectorToken;
1089
- const selector = withdraw(selectorToken, target);
1090
- if (!selector.family) {
927
+ const selector2 = withdraw(target, selectorToken);
928
+ if (!selector2.family) {
1091
929
  store.logger.error(
1092
930
  `\u274C`,
1093
931
  `selector`,
@@ -1095,27 +933,35 @@ function disposeSelector(selectorToken, store) {
1095
933
  `Standalone selectors cannot be disposed.`
1096
934
  );
1097
935
  } else {
1098
- const molecule = target.molecules.get(selector.family.subKey);
936
+ const molecule = target.molecules.get(selector2.family.subKey);
1099
937
  if (molecule) {
1100
- target.moleculeData.delete(selector.family.subKey, selector.family.key);
938
+ target.moleculeData.delete(selector2.family.subKey, selector2.family.key);
1101
939
  }
940
+ let familyToken;
1102
941
  switch (selectorToken.type) {
1103
942
  case `selector`:
1104
943
  {
1105
944
  target.selectors.delete(key);
1106
- withdraw(
1107
- { key: selector.family.key, type: `selector_family` },
1108
- store
1109
- );
945
+ familyToken = {
946
+ key: selector2.family.key,
947
+ type: `selector_family`
948
+ };
949
+ const family = withdraw(store, familyToken);
950
+ family.subject.next({
951
+ type: `state_disposal`,
952
+ subType: `selector`,
953
+ token: selectorToken
954
+ });
1110
955
  }
1111
956
  break;
1112
957
  case `readonly_selector`:
1113
958
  {
1114
959
  target.readonlySelectors.delete(key);
1115
- const family = withdraw(
1116
- { key: selector.family.key, type: `readonly_selector_family` },
1117
- store
1118
- );
960
+ familyToken = {
961
+ key: selector2.family.key,
962
+ type: `readonly_selector_family`
963
+ };
964
+ const family = withdraw(store, familyToken);
1119
965
  family.subject.next({
1120
966
  type: `state_disposal`,
1121
967
  subType: `selector`,
@@ -1181,9 +1027,8 @@ function createReadonlySelectorFamily(store, options, internalRoles) {
1181
1027
  default: (key) => {
1182
1028
  const getFn = options.get(key);
1183
1029
  return getFn({
1184
- get: (...ps) => getFromStore(store, ...ps),
1185
- find: (token, k) => findInStore(store, token, k),
1186
- seek: (token, k) => seekInStore(store, token, k),
1030
+ get: (...args) => getFromStore(store, ...args),
1031
+ find: (...args) => findInStore(store, ...args),
1187
1032
  json: (token) => getJsonToken(store, token)
1188
1033
  });
1189
1034
  }
@@ -1191,6 +1036,8 @@ function createReadonlySelectorFamily(store, options, internalRoles) {
1191
1036
  store.families.set(options.key, readonlySelectorFamily);
1192
1037
  return familyToken;
1193
1038
  }
1039
+
1040
+ // internal/src/families/create-writable-selector-family.ts
1194
1041
  function createWritableSelectorFamily(store, options, internalRoles) {
1195
1042
  const familyToken = {
1196
1043
  key: options.key,
@@ -1225,7 +1072,7 @@ function createWritableSelectorFamily(store, options, internalRoles) {
1225
1072
  subject.next({ type: `state_creation`, token });
1226
1073
  return token;
1227
1074
  };
1228
- const selectorFamily = Object.assign(familyFunction, familyToken, {
1075
+ const selectorFamily2 = Object.assign(familyFunction, familyToken, {
1229
1076
  internalRoles,
1230
1077
  subject,
1231
1078
  install: (s) => createWritableSelectorFamily(s, options),
@@ -1234,12 +1081,11 @@ function createWritableSelectorFamily(store, options, internalRoles) {
1234
1081
  return getFn({
1235
1082
  get: (...ps) => getFromStore(store, ...ps),
1236
1083
  find: (token, k) => findInStore(store, token, k),
1237
- seek: (token, k) => seekInStore(store, token, k),
1238
1084
  json: (token) => getJsonToken(store, token)
1239
1085
  });
1240
1086
  }
1241
1087
  });
1242
- store.families.set(options.key, selectorFamily);
1088
+ store.families.set(options.key, selectorFamily2);
1243
1089
  return familyToken;
1244
1090
  }
1245
1091
 
@@ -1281,6 +1127,8 @@ function initFamilyMemberInStore(store, token, key) {
1281
1127
  }
1282
1128
  return state;
1283
1129
  }
1130
+
1131
+ // internal/src/families/seek-in-store.ts
1284
1132
  function seekInStore(store, token, key) {
1285
1133
  const subKey = stringifyJson(key);
1286
1134
  const fullKey = `${token.key}(${subKey})`;
@@ -1342,27 +1190,24 @@ function disposeFromStore(store, ...params) {
1342
1190
  token = maybeToken;
1343
1191
  }
1344
1192
  try {
1345
- withdraw(token, store);
1193
+ withdraw(store, token);
1346
1194
  } catch (thrown) {
1347
1195
  store.logger.error(
1348
1196
  `\u274C`,
1349
1197
  token.type,
1350
1198
  token.key,
1351
1199
  `could not be disposed because it was not found in the store "${store.config.name}".`
1352
- // disposal
1353
- // ? `\n This state was most recently disposed\n${disposal.trace}`
1354
- // : `No previous disposal trace was found.`,
1355
1200
  );
1356
1201
  return;
1357
1202
  }
1358
1203
  switch (token.type) {
1359
1204
  case `atom`:
1360
1205
  case `mutable_atom`:
1361
- disposeAtom(token, store);
1206
+ disposeAtom(store, token);
1362
1207
  break;
1363
1208
  case `selector`:
1364
1209
  case `readonly_selector`:
1365
- disposeSelector(token, store);
1210
+ disposeSelector(store, token);
1366
1211
  break;
1367
1212
  }
1368
1213
  }
@@ -1429,8 +1274,8 @@ ${disposal.trace}` : `No previous disposal trace was found.`
1429
1274
  );
1430
1275
  return;
1431
1276
  }
1432
- const state = withdraw(token, store);
1433
- setAtomOrSelector(state, value, store);
1277
+ const state = withdraw(store, token);
1278
+ setAtomOrSelector(store, state, value);
1434
1279
  closeOperation(store);
1435
1280
  }
1436
1281
 
@@ -1444,45 +1289,279 @@ function ingestAtomUpdate(applying, atomUpdate, store) {
1444
1289
  }
1445
1290
  setIntoStore(store, token, value);
1446
1291
  }
1447
- function ingestCreationEvent(update, applying, store) {
1448
- switch (applying) {
1449
- case `newValue`: {
1450
- createInStore(update, store);
1451
- break;
1292
+
1293
+ // internal/src/get-trace.ts
1294
+ function getTrace(error) {
1295
+ const { stack } = error;
1296
+ if (stack) {
1297
+ return `
1298
+ ` + stack.split(`
1299
+ `)?.slice(1)?.join(`
1300
+ `);
1301
+ }
1302
+ return ``;
1303
+ }
1304
+
1305
+ // internal/src/molecule.ts
1306
+ function makeRootMoleculeInStore(key, store = IMPLICIT.STORE) {
1307
+ const molecule = {
1308
+ key,
1309
+ stringKey: stringifyJson(key),
1310
+ dependsOn: `any`
1311
+ };
1312
+ store.molecules.set(stringifyJson(key), molecule);
1313
+ return key;
1314
+ }
1315
+ function allocateIntoStore(store, provenance, key, dependsOn = `any`) {
1316
+ const origin = provenance;
1317
+ const stringKey = stringifyJson(key);
1318
+ const invalidKeys = [];
1319
+ const target = newest(store);
1320
+ if (Array.isArray(origin)) {
1321
+ for (const formerClaim of origin) {
1322
+ const claimString = stringifyJson(formerClaim);
1323
+ const claim = target.molecules.get(claimString);
1324
+ if (claim) {
1325
+ store.moleculeGraph.set(claimString, stringKey, { source: claimString });
1326
+ } else {
1327
+ invalidKeys.push(claimString);
1328
+ }
1452
1329
  }
1453
- case `oldValue`: {
1454
- disposeFromStore(store, update.token);
1455
- break;
1330
+ } else {
1331
+ const claimString = stringifyJson(origin);
1332
+ const claim = target.molecules.get(claimString);
1333
+ if (claim) {
1334
+ store.moleculeGraph.set(claimString, stringKey, { source: claimString });
1335
+ } else {
1336
+ invalidKeys.push(claimString);
1456
1337
  }
1457
1338
  }
1339
+ if (invalidKeys.length === 0) {
1340
+ target.molecules.set(stringKey, { key, stringKey, dependsOn });
1341
+ }
1342
+ const creationEvent = {
1343
+ type: `molecule_creation`,
1344
+ key,
1345
+ provenance: origin
1346
+ };
1347
+ const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
1348
+ if (isTransaction) {
1349
+ target.transactionMeta.update.updates.push(creationEvent);
1350
+ } else {
1351
+ target.on.moleculeCreation.next(creationEvent);
1352
+ }
1353
+ for (const claim of invalidKeys) {
1354
+ const disposal = store.disposalTraces.buffer.find(
1355
+ (item) => item?.key === claim
1356
+ );
1357
+ store.logger.error(
1358
+ `\u274C`,
1359
+ `molecule`,
1360
+ key,
1361
+ `allocation failed:`,
1362
+ `Could not allocate to ${claim} in store "${store.config.name}".`,
1363
+ disposal ? `
1364
+ ${claim} was most recently disposed
1365
+ ${disposal.trace}` : `No previous disposal trace for ${claim} was found.`
1366
+ );
1367
+ }
1368
+ return key;
1458
1369
  }
1459
- function ingestDisposalEvent(update, applying, store) {
1460
- switch (applying) {
1461
- case `newValue`: {
1462
- disposeFromStore(store, update.token);
1463
- break;
1370
+ function fuseWithinStore(store, type, sideA, sideB) {
1371
+ const compoundKey = `T$--${type}==${sideA}++${sideB}`;
1372
+ const above = [sideA, sideB];
1373
+ allocateIntoStore(
1374
+ store,
1375
+ above,
1376
+ compoundKey,
1377
+ `all`
1378
+ );
1379
+ return compoundKey;
1380
+ }
1381
+ function deallocateFromStore(store, claim) {
1382
+ const stringKey = stringifyJson(claim);
1383
+ const molecule = store.molecules.get(stringKey);
1384
+ if (!molecule) {
1385
+ const disposal = store.disposalTraces.buffer.find(
1386
+ (item) => item?.key === stringKey
1387
+ );
1388
+ store.logger.error(
1389
+ `\u274C`,
1390
+ `molecule`,
1391
+ claim,
1392
+ `deallocation failed:`,
1393
+ `Could not find allocation for ${stringKey} in store "${store.config.name}".`,
1394
+ disposal ? `
1395
+ This state was most recently deallocated
1396
+ ${disposal.trace}` : `No previous disposal trace for ${stringKey} was found.`
1397
+ );
1398
+ return;
1399
+ }
1400
+ const joinKeys = store.moleculeJoins.getRelatedKeys(
1401
+ molecule.key
1402
+ );
1403
+ if (joinKeys) {
1404
+ for (const joinKey of joinKeys) {
1405
+ const join2 = store.joins.get(joinKey);
1406
+ if (join2) {
1407
+ join2.relations.delete(molecule.key);
1408
+ join2.molecules.delete(molecule.stringKey);
1409
+ }
1464
1410
  }
1465
- case `oldValue`: {
1466
- createInStore(update, store);
1467
- if (update.subType === `atom`) {
1468
- store.valueMap.set(update.token.key, update.value);
1411
+ }
1412
+ store.moleculeJoins.delete(molecule.stringKey);
1413
+ const provenance = [];
1414
+ const values = [];
1415
+ const disposalEvent = {
1416
+ type: `molecule_disposal`,
1417
+ key: molecule.key,
1418
+ values,
1419
+ provenance
1420
+ };
1421
+ const target = newest(store);
1422
+ target.molecules.delete(stringKey);
1423
+ const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
1424
+ if (isTransaction) {
1425
+ target.transactionMeta.update.updates.push(disposalEvent);
1426
+ }
1427
+ const relatedMolecules = store.moleculeGraph.getRelationEntries({
1428
+ downstreamMoleculeKey: molecule.stringKey
1429
+ });
1430
+ if (relatedMolecules) {
1431
+ for (const [relatedStringKey, { source }] of relatedMolecules) {
1432
+ if (source === molecule.stringKey) {
1433
+ const relatedKey = parseJson(relatedStringKey);
1434
+ deallocateFromStore(store, relatedKey);
1435
+ } else {
1436
+ provenance.push(source);
1469
1437
  }
1470
- break;
1471
1438
  }
1472
1439
  }
1473
- }
1474
- function createInStore(update, store) {
1475
- const { family: familyMeta } = update.token;
1476
- if (familyMeta) {
1477
- const family = store.families.get(familyMeta.key);
1478
- if (family) {
1479
- findInStore(store, family, parseJson(familyMeta.subKey));
1440
+ const familyKeys = target.moleculeData.getRelatedKeys(molecule.stringKey);
1441
+ if (familyKeys) {
1442
+ for (const familyKey of familyKeys) {
1443
+ const family = target.families.get(familyKey);
1444
+ const token = findInStore(store, family, molecule.key);
1445
+ values.push([family.key, token]);
1446
+ disposeFromStore(store, token);
1480
1447
  }
1481
1448
  }
1449
+ target.moleculeGraph.delete(molecule.stringKey);
1450
+ target.moleculeJoins.delete(molecule.stringKey);
1451
+ target.moleculeData.delete(molecule.stringKey);
1452
+ if (!isTransaction) {
1453
+ target.on.moleculeDisposal.next(disposalEvent);
1454
+ }
1455
+ target.molecules.delete(molecule.stringKey);
1456
+ const trace = getTrace(new Error());
1457
+ store.disposalTraces.add({ key: stringKey, trace });
1482
1458
  }
1483
- function ingestMoleculeCreationEvent(update, applying, store) {
1484
- switch (applying) {
1485
- case `newValue`:
1459
+ function claimWithinStore(store, newProvenance, claim, exclusive) {
1460
+ const stringKey = stringifyJson(claim);
1461
+ const target = newest(store);
1462
+ const molecule = target.molecules.get(stringKey);
1463
+ if (!molecule) {
1464
+ const disposal = store.disposalTraces.buffer.find(
1465
+ (item) => item?.key === stringKey
1466
+ );
1467
+ store.logger.error(
1468
+ `\u274C`,
1469
+ `molecule`,
1470
+ claim,
1471
+ `claim failed:`,
1472
+ `Could not allocate to ${stringKey} in store "${store.config.name}".`,
1473
+ disposal ? `
1474
+ ${stringKey} was most recently disposed
1475
+ ${disposal.trace}` : `No previous disposal trace for ${stringKey} was found.`
1476
+ );
1477
+ return claim;
1478
+ }
1479
+ const newProvenanceKey = stringifyJson(newProvenance);
1480
+ const newProvenanceMolecule = target.molecules.get(newProvenanceKey);
1481
+ if (!newProvenanceMolecule) {
1482
+ const disposal = store.disposalTraces.buffer.find(
1483
+ (item) => item?.key === newProvenanceKey
1484
+ );
1485
+ store.logger.error(
1486
+ `\u274C`,
1487
+ `molecule`,
1488
+ claim,
1489
+ `claim failed:`,
1490
+ `Could not allocate to ${newProvenanceKey} in store "${store.config.name}".`,
1491
+ disposal ? `
1492
+ ${newProvenanceKey} was most recently disposed
1493
+ ${disposal.trace}` : `No previous disposal trace for ${newProvenanceKey} was found.`
1494
+ );
1495
+ return claim;
1496
+ }
1497
+ const priorProvenance = store.moleculeGraph.getRelationEntries({
1498
+ downstreamMoleculeKey: molecule.stringKey
1499
+ }).filter(([, { source }]) => source !== stringKey).map(([key]) => parseJson(key));
1500
+ if (exclusive) {
1501
+ target.moleculeGraph.delete(stringKey);
1502
+ }
1503
+ target.moleculeGraph.set(
1504
+ {
1505
+ upstreamMoleculeKey: newProvenanceMolecule.stringKey,
1506
+ downstreamMoleculeKey: molecule.stringKey
1507
+ },
1508
+ {
1509
+ source: newProvenanceMolecule.stringKey
1510
+ }
1511
+ );
1512
+ const transferEvent = {
1513
+ type: `molecule_transfer`,
1514
+ key: molecule.key,
1515
+ from: priorProvenance,
1516
+ to: [newProvenanceMolecule.key]
1517
+ };
1518
+ const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
1519
+ if (isTransaction) {
1520
+ target.transactionMeta.update.updates.push(transferEvent);
1521
+ }
1522
+ return claim;
1523
+ }
1524
+
1525
+ // internal/src/ingest-updates/ingest-creation-disposal.ts
1526
+ function ingestCreationEvent(update, applying, store) {
1527
+ switch (applying) {
1528
+ case `newValue`: {
1529
+ createInStore(update, store);
1530
+ break;
1531
+ }
1532
+ case `oldValue`: {
1533
+ disposeFromStore(store, update.token);
1534
+ break;
1535
+ }
1536
+ }
1537
+ }
1538
+ function ingestDisposalEvent(update, applying, store) {
1539
+ switch (applying) {
1540
+ case `newValue`: {
1541
+ disposeFromStore(store, update.token);
1542
+ break;
1543
+ }
1544
+ case `oldValue`: {
1545
+ createInStore(update, store);
1546
+ if (update.subType === `atom`) {
1547
+ store.valueMap.set(update.token.key, update.value);
1548
+ }
1549
+ break;
1550
+ }
1551
+ }
1552
+ }
1553
+ function createInStore(update, store) {
1554
+ const { family: familyMeta } = update.token;
1555
+ if (familyMeta) {
1556
+ const family = store.families.get(familyMeta.key);
1557
+ if (family) {
1558
+ findInStore(store, family, parseJson(familyMeta.subKey));
1559
+ }
1560
+ }
1561
+ }
1562
+ function ingestMoleculeCreationEvent(update, applying, store) {
1563
+ switch (applying) {
1564
+ case `newValue`:
1486
1565
  allocateIntoStore(store, update.provenance, update.key);
1487
1566
  break;
1488
1567
  case `oldValue`:
@@ -1575,138 +1654,449 @@ function ingestTransactionUpdate(applying, transactionUpdate, store) {
1575
1654
  break;
1576
1655
  }
1577
1656
  }
1578
- }
1579
-
1580
- // internal/src/transaction/set-epoch-number.ts
1581
- function setEpochNumberOfContinuity(continuityKey, newEpoch, store) {
1582
- const isRoot = isRootStore(store);
1583
- if (isRoot && continuityKey) {
1584
- store.transactionMeta.epoch.set(continuityKey, newEpoch);
1585
- }
1586
- }
1587
- function setEpochNumberOfAction(transactionKey, newEpoch, store) {
1588
- const isRoot = isRootStore(store);
1589
- if (!isRoot) {
1590
- return;
1591
- }
1592
- const continuityKey = store.transactionMeta.actionContinuities.getRelatedKey(transactionKey);
1593
- if (continuityKey !== undefined) {
1594
- store.transactionMeta.epoch.set(continuityKey, newEpoch);
1595
- }
1596
- }
1597
-
1598
- // internal/src/transaction/apply-transaction.ts
1599
- var applyTransaction = (output, store) => {
1600
- const child = newest(store);
1601
- const { parent } = child;
1602
- if (parent === null || !isChildStore(child) || child.transactionMeta?.phase !== `building`) {
1603
- store.logger.warn(
1604
- `\u{1F41E}`,
1605
- `transaction`,
1606
- `???`,
1607
- `applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`
1608
- );
1609
- return;
1610
- }
1611
- child.transactionMeta.phase = `applying`;
1612
- child.transactionMeta.update.output = output;
1613
- parent.child = null;
1614
- parent.on.transactionApplying.next(child.transactionMeta);
1615
- const { updates } = child.transactionMeta.update;
1616
- store.logger.info(
1617
- `\u{1F6C4}`,
1618
- `transaction`,
1619
- child.transactionMeta.update.key,
1620
- `Applying transaction with ${updates.length} updates:`,
1621
- updates
1622
- );
1623
- ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
1624
- if (isRootStore(parent)) {
1625
- setEpochNumberOfAction(
1626
- child.transactionMeta.update.key,
1627
- child.transactionMeta.update.epoch,
1628
- parent
1629
- );
1630
- const myTransaction = withdraw(
1631
- { key: child.transactionMeta.update.key, type: `transaction` },
1632
- store
1633
- );
1634
- myTransaction?.subject.next(child.transactionMeta.update);
1635
- store.logger.info(
1636
- `\u{1F6EC}`,
1637
- `transaction`,
1638
- child.transactionMeta.update.key,
1639
- `Finished applying transaction.`
1657
+ }
1658
+
1659
+ // internal/src/transaction/set-epoch-number.ts
1660
+ function setEpochNumberOfContinuity(store, continuityKey, newEpoch) {
1661
+ const isRoot = isRootStore(store);
1662
+ if (isRoot && continuityKey) {
1663
+ store.transactionMeta.epoch.set(continuityKey, newEpoch);
1664
+ }
1665
+ }
1666
+ function setEpochNumberOfAction(store, transactionKey, newEpoch) {
1667
+ const isRoot = isRootStore(store);
1668
+ if (!isRoot) {
1669
+ return;
1670
+ }
1671
+ const continuityKey = store.transactionMeta.actionContinuities.getRelatedKey(transactionKey);
1672
+ if (continuityKey !== undefined) {
1673
+ store.transactionMeta.epoch.set(continuityKey, newEpoch);
1674
+ }
1675
+ }
1676
+
1677
+ // internal/src/transaction/apply-transaction.ts
1678
+ var applyTransaction = (output, store) => {
1679
+ const child = newest(store);
1680
+ const { parent } = child;
1681
+ if (parent === null || !isChildStore(child) || child.transactionMeta?.phase !== `building`) {
1682
+ store.logger.warn(
1683
+ `\u{1F41E}`,
1684
+ `transaction`,
1685
+ `???`,
1686
+ `applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`
1687
+ );
1688
+ return;
1689
+ }
1690
+ child.transactionMeta.phase = `applying`;
1691
+ child.transactionMeta.update.output = output;
1692
+ parent.child = null;
1693
+ parent.on.transactionApplying.next(child.transactionMeta);
1694
+ const { updates } = child.transactionMeta.update;
1695
+ store.logger.info(
1696
+ `\u{1F6C4}`,
1697
+ `transaction`,
1698
+ child.transactionMeta.update.key,
1699
+ `Applying transaction with ${updates.length} updates:`,
1700
+ updates
1701
+ );
1702
+ ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
1703
+ if (isRootStore(parent)) {
1704
+ setEpochNumberOfAction(
1705
+ parent,
1706
+ child.transactionMeta.update.key,
1707
+ child.transactionMeta.update.epoch
1708
+ );
1709
+ const myTransaction = withdraw(store, {
1710
+ key: child.transactionMeta.update.key,
1711
+ type: `transaction`
1712
+ });
1713
+ myTransaction?.subject.next(child.transactionMeta.update);
1714
+ store.logger.info(
1715
+ `\u{1F6EC}`,
1716
+ `transaction`,
1717
+ child.transactionMeta.update.key,
1718
+ `Finished applying transaction.`
1719
+ );
1720
+ } else if (isChildStore(parent)) {
1721
+ parent.transactionMeta.update.updates.push(child.transactionMeta.update);
1722
+ }
1723
+ parent.on.transactionApplying.next(null);
1724
+ };
1725
+
1726
+ // internal/src/transaction/assign-transaction-to-continuity.ts
1727
+ function assignTransactionToContinuity(store, continuityKey, transactionKey) {
1728
+ const isRoot = isRootStore(store);
1729
+ if (!isRoot) {
1730
+ return;
1731
+ }
1732
+ const { epoch, actionContinuities } = store.transactionMeta;
1733
+ actionContinuities.set(continuityKey, transactionKey);
1734
+ if (!epoch.has(continuityKey)) {
1735
+ epoch.set(continuityKey, -1);
1736
+ }
1737
+ }
1738
+
1739
+ // internal/src/get-environment-data.ts
1740
+ function getEnvironmentData(store) {
1741
+ return {
1742
+ store
1743
+ };
1744
+ }
1745
+
1746
+ // internal/src/get-state/get-from-store.ts
1747
+ function getFromStore(store, ...params) {
1748
+ let token;
1749
+ let family;
1750
+ let key;
1751
+ if (params.length === 1) {
1752
+ token = params[0];
1753
+ } else {
1754
+ family = params[0];
1755
+ key = params[1];
1756
+ token = findInStore(store, family, key);
1757
+ }
1758
+ if (`counterfeit` in token && `family` in token) {
1759
+ family = store.families.get(token.family.key);
1760
+ const subKey = token.family.subKey;
1761
+ const disposal = store.disposalTraces.buffer.find(
1762
+ (item) => item?.key === subKey
1763
+ );
1764
+ store.logger.error(
1765
+ `\u274C`,
1766
+ token.type,
1767
+ token.key,
1768
+ `could not be retrieved because it was not found in the store "${store.config.name}".`,
1769
+ disposal ? `This state was previously disposed:
1770
+ ${disposal.trace}` : `No previous disposal trace was found.`
1771
+ );
1772
+ switch (family.type) {
1773
+ case `atom_family`:
1774
+ case `mutable_atom_family`:
1775
+ return store.defaults.get(family.key);
1776
+ case `selector_family`:
1777
+ case `readonly_selector_family`: {
1778
+ if (store.defaults.has(family.key)) {
1779
+ return store.defaults.get(token.family.key);
1780
+ }
1781
+ const defaultValue = withdraw(store, family).default(subKey);
1782
+ store.defaults.set(family.key, defaultValue);
1783
+ return defaultValue;
1784
+ }
1785
+ }
1786
+ }
1787
+ return readOrComputeValue(store, withdraw(store, token));
1788
+ }
1789
+
1790
+ // internal/src/junction.ts
1791
+ var Junction = class {
1792
+ a;
1793
+ b;
1794
+ cardinality;
1795
+ relations = /* @__PURE__ */ new Map();
1796
+ contents = /* @__PURE__ */ new Map();
1797
+ isAType;
1798
+ isBType;
1799
+ isContent;
1800
+ makeContentKey = (a, b) => `${a}:${b}`;
1801
+ warn;
1802
+ getRelatedKeys(key) {
1803
+ return this.relations.get(key);
1804
+ }
1805
+ addRelation(a, b) {
1806
+ let aRelations = this.relations.get(a);
1807
+ let bRelations = this.relations.get(b);
1808
+ if (aRelations) {
1809
+ aRelations.add(b);
1810
+ } else {
1811
+ aRelations = /* @__PURE__ */ new Set([b]);
1812
+ this.relations.set(a, aRelations);
1813
+ }
1814
+ if (bRelations) {
1815
+ bRelations.add(a);
1816
+ } else {
1817
+ bRelations = /* @__PURE__ */ new Set([a]);
1818
+ this.relations.set(b, bRelations);
1819
+ }
1820
+ }
1821
+ deleteRelation(a, b) {
1822
+ const aRelations = this.relations.get(a);
1823
+ if (aRelations) {
1824
+ aRelations.delete(b);
1825
+ if (aRelations.size === 0) {
1826
+ this.relations.delete(a);
1827
+ }
1828
+ const bRelations = this.relations.get(b);
1829
+ if (bRelations) {
1830
+ bRelations.delete(a);
1831
+ if (bRelations.size === 0) {
1832
+ this.relations.delete(b);
1833
+ }
1834
+ }
1835
+ }
1836
+ }
1837
+ replaceRelationsUnsafely(x, ys) {
1838
+ this.relations.set(x, new Set(ys));
1839
+ for (const y of ys) {
1840
+ const yRelations = (/* @__PURE__ */ new Set()).add(x);
1841
+ this.relations.set(y, yRelations);
1842
+ }
1843
+ }
1844
+ replaceRelationsSafely(x, ys) {
1845
+ const xRelationsPrev = this.relations.get(x);
1846
+ let a = this.isAType?.(x) ? x : undefined;
1847
+ let b = a === undefined ? x : undefined;
1848
+ if (xRelationsPrev) {
1849
+ for (const y of xRelationsPrev) {
1850
+ a ??= y;
1851
+ b ??= y;
1852
+ const yRelations = this.relations.get(y);
1853
+ if (yRelations) {
1854
+ if (yRelations.size === 1) {
1855
+ this.relations.delete(y);
1856
+ } else {
1857
+ yRelations.delete(x);
1858
+ }
1859
+ this.contents.delete(this.makeContentKey(a, b));
1860
+ }
1861
+ }
1862
+ }
1863
+ this.relations.set(x, new Set(ys));
1864
+ for (const y of ys) {
1865
+ let yRelations = this.relations.get(y);
1866
+ if (yRelations) {
1867
+ yRelations.add(x);
1868
+ } else {
1869
+ yRelations = (/* @__PURE__ */ new Set()).add(x);
1870
+ this.relations.set(y, yRelations);
1871
+ }
1872
+ }
1873
+ }
1874
+ getContentInternal(contentKey) {
1875
+ return this.contents.get(contentKey);
1876
+ }
1877
+ setContent(contentKey, content) {
1878
+ this.contents.set(contentKey, content);
1879
+ }
1880
+ deleteContent(contentKey) {
1881
+ this.contents.delete(contentKey);
1882
+ }
1883
+ constructor(data, config) {
1884
+ this.a = data.between[0];
1885
+ this.b = data.between[1];
1886
+ this.cardinality = data.cardinality;
1887
+ if (!config?.externalStore) {
1888
+ this.relations = new Map(
1889
+ data.relations?.map(([x, ys]) => [x, new Set(ys)])
1890
+ );
1891
+ this.contents = new Map(data.contents);
1892
+ }
1893
+ this.isAType = config?.isAType ?? null;
1894
+ this.isBType = config?.isBType ?? null;
1895
+ this.isContent = config?.isContent ?? null;
1896
+ if (config?.makeContentKey) {
1897
+ this.makeContentKey = config.makeContentKey;
1898
+ }
1899
+ if (config?.externalStore) {
1900
+ const externalStore = config.externalStore;
1901
+ this.has = (a, b) => externalStore.has(a, b);
1902
+ this.addRelation = (a, b) => {
1903
+ externalStore.addRelation(a, b);
1904
+ };
1905
+ this.deleteRelation = (a, b) => {
1906
+ externalStore.deleteRelation(a, b);
1907
+ };
1908
+ this.replaceRelationsSafely = (a, bs) => {
1909
+ externalStore.replaceRelationsSafely(a, bs);
1910
+ };
1911
+ this.replaceRelationsUnsafely = (a, bs) => {
1912
+ externalStore.replaceRelationsUnsafely(a, bs);
1913
+ };
1914
+ this.getRelatedKeys = (key) => externalStore.getRelatedKeys(
1915
+ key
1916
+ );
1917
+ if (externalStore.getContent) {
1918
+ this.getContentInternal = (contentKey) => {
1919
+ return externalStore.getContent(contentKey);
1920
+ };
1921
+ this.setContent = (contentKey, content) => {
1922
+ externalStore.setContent(contentKey, content);
1923
+ };
1924
+ this.deleteContent = (contentKey) => {
1925
+ externalStore.deleteContent(contentKey);
1926
+ };
1927
+ }
1928
+ for (const [x, ys] of data.relations ?? []) {
1929
+ let a = this.isAType?.(x) ? x : undefined;
1930
+ let b = a === undefined ? x : undefined;
1931
+ for (const y of ys) {
1932
+ a ??= y;
1933
+ b ??= y;
1934
+ this.addRelation(a, b);
1935
+ }
1936
+ }
1937
+ for (const [contentKey, content] of data.contents ?? []) {
1938
+ this.setContent(contentKey, content);
1939
+ }
1940
+ }
1941
+ if (config?.warn) {
1942
+ this.warn = config.warn;
1943
+ }
1944
+ }
1945
+ toJSON() {
1946
+ return {
1947
+ between: [this.a, this.b],
1948
+ cardinality: this.cardinality,
1949
+ relations: [...this.relations.entries()].map(
1950
+ ([a, b]) => [a, [...b]]
1951
+ ),
1952
+ contents: [...this.contents.entries()]
1953
+ };
1954
+ }
1955
+ set(...params) {
1956
+ let a;
1957
+ let b;
1958
+ let content;
1959
+ switch (params.length) {
1960
+ case 1: {
1961
+ const relation = params[0];
1962
+ a = relation[this.a];
1963
+ b = relation[this.b];
1964
+ content = undefined;
1965
+ break;
1966
+ }
1967
+ case 2: {
1968
+ const zeroth = params[0];
1969
+ if (typeof zeroth === `string`) {
1970
+ [a, b] = params;
1971
+ } else {
1972
+ a = zeroth[this.a];
1973
+ b = zeroth[this.b];
1974
+ content = params[1];
1975
+ }
1976
+ break;
1977
+ }
1978
+ default: {
1979
+ a = params[0];
1980
+ b = params[1];
1981
+ content = params[2];
1982
+ break;
1983
+ }
1984
+ }
1985
+ switch (this.cardinality) {
1986
+ // biome-ignore lint/suspicious/noFallthroughSwitchClause: perfect here
1987
+ case `1:1`: {
1988
+ const bPrev = this.getRelatedKey(a);
1989
+ if (bPrev && bPrev !== b) this.delete(a, bPrev);
1990
+ }
1991
+ case `1:n`: {
1992
+ const aPrev = this.getRelatedKey(b);
1993
+ if (aPrev && aPrev !== a) this.delete(aPrev, b);
1994
+ }
1995
+ }
1996
+ if (content) {
1997
+ const contentKey = this.makeContentKey(a, b);
1998
+ this.setContent(contentKey, content);
1999
+ }
2000
+ this.addRelation(a, b);
2001
+ return this;
2002
+ }
2003
+ delete(x, b) {
2004
+ b = typeof b === `string` ? b : x[this.b];
2005
+ const a = (
2006
+ // @ts-expect-error we deduce that this.a may index x
2007
+ typeof x === `string` ? x : x[this.a]
1640
2008
  );
1641
- } else if (isChildStore(parent)) {
1642
- parent.transactionMeta.update.updates.push(child.transactionMeta.update);
2009
+ if (a === undefined && typeof b === `string`) {
2010
+ const bRelations = this.getRelatedKeys(b);
2011
+ if (bRelations) {
2012
+ for (const bRelation of bRelations) {
2013
+ this.delete(bRelation, b);
2014
+ }
2015
+ }
2016
+ }
2017
+ if (typeof a === `string` && b === undefined) {
2018
+ const aRelations = this.getRelatedKeys(a);
2019
+ if (aRelations) {
2020
+ for (const aRelation of aRelations) {
2021
+ this.delete(a, aRelation);
2022
+ }
2023
+ }
2024
+ }
2025
+ if (typeof a === `string` && typeof b === `string`) {
2026
+ this.deleteRelation(a, b);
2027
+ const contentKey = this.makeContentKey(a, b);
2028
+ this.deleteContent(contentKey);
2029
+ }
2030
+ return this;
1643
2031
  }
1644
- parent.on.transactionApplying.next(null);
1645
- };
1646
-
1647
- // internal/src/transaction/assign-transaction-to-continuity.ts
1648
- function assignTransactionToContinuity(continuityKey, transactionKey, store) {
1649
- const isRoot = isRootStore(store);
1650
- if (!isRoot) {
1651
- return;
2032
+ getRelatedKey(key) {
2033
+ const relations = this.getRelatedKeys(key);
2034
+ if (relations) {
2035
+ if (relations.size > 1) {
2036
+ this.warn?.(
2037
+ `${relations.size} related keys were found for key "${key}": (${[
2038
+ ...relations
2039
+ ].map((k) => `"${k}"`).join(`, `)}). Only one related key was expected.`
2040
+ );
2041
+ }
2042
+ let singleRelation;
2043
+ for (const relation of relations) {
2044
+ singleRelation = relation;
2045
+ break;
2046
+ }
2047
+ return singleRelation;
2048
+ }
1652
2049
  }
1653
- const { epoch, actionContinuities } = store.transactionMeta;
1654
- actionContinuities.set(continuityKey, transactionKey);
1655
- if (!epoch.has(continuityKey)) {
1656
- epoch.set(continuityKey, -1);
2050
+ replaceRelations(x, relations, config) {
2051
+ const hasContent = !Array.isArray(relations);
2052
+ const ys = hasContent ? Object.keys(relations) : relations;
2053
+ if (config?.reckless) {
2054
+ this.replaceRelationsUnsafely(x, ys);
2055
+ } else {
2056
+ this.replaceRelationsSafely(x, ys);
2057
+ }
2058
+ if (hasContent) {
2059
+ for (const y of ys) {
2060
+ const contentKey = this.makeContentKey(x, y);
2061
+ const content = relations[y];
2062
+ this.setContent(contentKey, content);
2063
+ }
2064
+ }
2065
+ return this;
1657
2066
  }
1658
- }
1659
-
1660
- // internal/src/get-environment-data.ts
1661
- function getEnvironmentData(store) {
1662
- return {
1663
- store
1664
- };
1665
- }
1666
-
1667
- // internal/src/get-state/get-from-store.ts
1668
- function getFromStore(store, ...params) {
1669
- let token;
1670
- let family;
1671
- let key;
1672
- if (params.length === 1) {
1673
- token = params[0];
1674
- } else {
1675
- family = params[0];
1676
- key = params[1];
1677
- token = findInStore(store, family, key);
2067
+ getContent(a, b) {
2068
+ const contentKey = this.makeContentKey(a, b);
2069
+ return this.getContentInternal(contentKey);
1678
2070
  }
1679
- if (`counterfeit` in token && `family` in token) {
1680
- family = store.families.get(token.family.key);
1681
- const subKey = token.family.subKey;
1682
- const disposal = store.disposalTraces.buffer.find(
1683
- (item) => item?.key === subKey
1684
- );
1685
- store.logger.error(
1686
- `\u274C`,
1687
- token.type,
1688
- token.key,
1689
- `could not be retrieved because it was not found in the store "${store.config.name}".`,
1690
- disposal ? `This state was previously disposed:
1691
- ${disposal.trace}` : `No previous disposal trace was found.`
1692
- );
1693
- switch (family.type) {
1694
- case `atom_family`:
1695
- case `mutable_atom_family`:
1696
- return store.defaults.get(family.key);
1697
- case `selector_family`:
1698
- case `readonly_selector_family`: {
1699
- if (store.defaults.has(family.key)) {
1700
- return store.defaults.get(token.family.key);
1701
- }
1702
- const defaultValue = withdraw(family, store).default(subKey);
1703
- store.defaults.set(family.key, defaultValue);
1704
- return defaultValue;
2071
+ getRelationEntries(input) {
2072
+ const a = input[this.a];
2073
+ const b = input[this.b];
2074
+ if (a !== undefined && b === undefined) {
2075
+ const aRelations = this.getRelatedKeys(a);
2076
+ if (aRelations) {
2077
+ return [...aRelations].map((aRelation) => {
2078
+ return [aRelation, this.getContent(a, aRelation)];
2079
+ });
2080
+ }
2081
+ }
2082
+ if (a === undefined && b !== undefined) {
2083
+ const bRelations = this.getRelatedKeys(b);
2084
+ if (bRelations) {
2085
+ return [...bRelations].map((bRelation) => {
2086
+ return [bRelation, this.getContent(bRelation, b)];
2087
+ });
1705
2088
  }
1706
2089
  }
2090
+ return [];
2091
+ }
2092
+ has(a, b) {
2093
+ if (b) {
2094
+ const setA = this.getRelatedKeys(a);
2095
+ return setA?.has(b) ?? false;
2096
+ }
2097
+ return this.relations.has(a);
1707
2098
  }
1708
- return readOrComputeValue(withdraw(token, store), store);
1709
- }
2099
+ };
1710
2100
 
1711
2101
  // internal/src/lazy-map.ts
1712
2102
  var LazyMap = class extends Map {
@@ -1743,7 +2133,7 @@ var LazyMap = class extends Map {
1743
2133
  };
1744
2134
 
1745
2135
  // internal/src/transaction/build-transaction.ts
1746
- var buildTransaction = (key, params, store, id) => {
2136
+ var buildTransaction = (store, key, params, id) => {
1747
2137
  const parent = newest(store);
1748
2138
  const childBase = {
1749
2139
  parent,
@@ -1782,7 +2172,7 @@ var buildTransaction = (key, params, store, id) => {
1782
2172
  }),
1783
2173
  miscResources: new LazyMap(parent.miscResources)
1784
2174
  };
1785
- const epoch = getEpochNumberOfAction(key, store);
2175
+ const epoch = getEpochNumberOfAction(store, key);
1786
2176
  const transactionMeta = {
1787
2177
  phase: `building`,
1788
2178
  update: {
@@ -1799,9 +2189,8 @@ var buildTransaction = (key, params, store, id) => {
1799
2189
  set: (...ps) => {
1800
2190
  setIntoStore(child, ...ps);
1801
2191
  },
1802
- run: (token, identifier = arbitrary()) => actUponStore(token, identifier, child),
2192
+ run: (token, identifier = arbitrary()) => actUponStore(child, token, identifier),
1803
2193
  find: (token, k) => findInStore(child, token, k),
1804
- seek: (token, k) => seekInStore(child, token, k),
1805
2194
  json: (token) => getJsonToken(child, token),
1806
2195
  dispose: (...ps) => {
1807
2196
  disposeFromStore(child, ...ps);
@@ -1824,12 +2213,12 @@ var buildTransaction = (key, params, store, id) => {
1824
2213
  };
1825
2214
 
1826
2215
  // internal/src/transaction/create-transaction.ts
1827
- function createTransaction(options, store) {
2216
+ function createTransaction(store, options) {
1828
2217
  const newTransaction = {
1829
2218
  key: options.key,
1830
2219
  type: `transaction`,
1831
2220
  run: (params, id) => {
1832
- const childStore = buildTransaction(options.key, params, store, id);
2221
+ const childStore = buildTransaction(store, options.key, params, id);
1833
2222
  try {
1834
2223
  const target2 = newest(store);
1835
2224
  const { toolkit } = childStore.transactionMeta;
@@ -1842,7 +2231,7 @@ function createTransaction(options, store) {
1842
2231
  throw thrown;
1843
2232
  }
1844
2233
  },
1845
- install: (s) => createTransaction(options, s),
2234
+ install: (s) => createTransaction(s, options),
1846
2235
  subject: new Subject()
1847
2236
  };
1848
2237
  const target = newest(store);
@@ -1852,26 +2241,138 @@ function createTransaction(options, store) {
1852
2241
  return token;
1853
2242
  }
1854
2243
 
1855
- // internal/src/transaction/get-epoch-number.ts
1856
- function getContinuityKey(transactionKey, store) {
1857
- const isRoot = isRootStore(store);
1858
- const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : undefined;
1859
- return continuity;
2244
+ // internal/src/transaction/get-epoch-number.ts
2245
+ function getContinuityKey(store, transactionKey) {
2246
+ const isRoot = isRootStore(store);
2247
+ const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : undefined;
2248
+ return continuity;
2249
+ }
2250
+ function getEpochNumberOfContinuity(store, continuityKey) {
2251
+ const isRoot = isRootStore(store);
2252
+ const epoch = isRoot && continuityKey ? store.transactionMeta.epoch.get(continuityKey) : undefined;
2253
+ return epoch;
2254
+ }
2255
+ function getEpochNumberOfAction(store, transactionKey) {
2256
+ const isRoot = isRootStore(store);
2257
+ const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : undefined;
2258
+ const epoch = isRoot && continuity !== undefined ? store.transactionMeta.epoch.get(continuity) : undefined;
2259
+ return epoch;
2260
+ }
2261
+
2262
+ // internal/src/transaction/index.ts
2263
+ var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
2264
+
2265
+ // internal/src/install-into-store.ts
2266
+ function installIntoStore(tokens, target, source) {
2267
+ const sourceNewest = newest(source);
2268
+ if (isChildStore(sourceNewest)) {
2269
+ source.logger.error(
2270
+ `\u274C`,
2271
+ `transaction`,
2272
+ sourceNewest.transactionMeta.update.key,
2273
+ `could not install the following tokens into store "${target.config.name} from "${source.config.name}":`,
2274
+ tokens,
2275
+ `${sourceNewest.config.name} is undergoing a transaction.`
2276
+ );
2277
+ return;
2278
+ }
2279
+ const targetNewest = newest(target);
2280
+ if (isChildStore(targetNewest)) {
2281
+ target.logger.error(
2282
+ `\u274C`,
2283
+ `transaction`,
2284
+ targetNewest.transactionMeta.update.key,
2285
+ `could not install the following tokens into store "${target.config.name} from "${source.config.name}":`,
2286
+ tokens,
2287
+ `${targetNewest.config.name} is undergoing a transaction.`
2288
+ );
2289
+ return;
2290
+ }
2291
+ for (const token of tokens) {
2292
+ const resource = withdraw(source, token);
2293
+ resource.install(target);
2294
+ }
2295
+ }
2296
+
2297
+ // src/silo.ts
2298
+ var Silo = class {
2299
+ store;
2300
+ atom;
2301
+ atomFamily;
2302
+ selector;
2303
+ selectorFamily;
2304
+ transaction;
2305
+ timeline;
2306
+ findState;
2307
+ getState;
2308
+ setState;
2309
+ disposeState;
2310
+ subscribe;
2311
+ undo;
2312
+ redo;
2313
+ runTransaction;
2314
+ install;
2315
+ constructor(config, fromStore = null) {
2316
+ const s = this.store = new Store(config, fromStore);
2317
+ this.atom = (options) => createStandaloneAtom(s, options);
2318
+ this.atomFamily = (options) => createAtomFamily(s, options);
2319
+ this.selector = (options) => createStandaloneSelector(s, options);
2320
+ this.selectorFamily = (options) => createSelectorFamily(s, options);
2321
+ this.transaction = (options) => createTransaction(s, options);
2322
+ this.timeline = (options) => createTimeline(s, options);
2323
+ this.findState = (...params) => findInStore(s, ...params);
2324
+ this.getState = (...params) => getFromStore(s, ...params);
2325
+ this.setState = (...params) => {
2326
+ setIntoStore(s, ...params);
2327
+ };
2328
+ this.disposeState = (...params) => {
2329
+ disposeFromStore(s, ...params);
2330
+ };
2331
+ this.subscribe = (...params) => subscribeInStore(s, ...params);
2332
+ this.undo = (token) => {
2333
+ timeTravel(s, `undo`, token);
2334
+ };
2335
+ this.redo = (token) => {
2336
+ timeTravel(s, `redo`, token);
2337
+ };
2338
+ this.runTransaction = (token, id = arbitrary()) => actUponStore(s, token, id);
2339
+ this.install = (tokens, source = IMPLICIT.STORE) => {
2340
+ installIntoStore(tokens, s, source);
2341
+ };
2342
+ }
2343
+ };
2344
+
2345
+ // src/subscribe.ts
2346
+ function subscribe(token, handleUpdate, key = arbitrary()) {
2347
+ return subscribeInStore(IMPLICIT.STORE, token, handleUpdate, key);
1860
2348
  }
1861
- function getEpochNumberOfContinuity(continuityKey, store) {
1862
- const isRoot = isRootStore(store);
1863
- const epoch = isRoot && continuityKey ? store.transactionMeta.epoch.get(continuityKey) : undefined;
1864
- return epoch;
2349
+
2350
+ // src/timeline.ts
2351
+ var timeline = (options) => {
2352
+ return createTimeline(IMPLICIT.STORE, options);
2353
+ };
2354
+ var redo = (tl) => {
2355
+ timeTravel(IMPLICIT.STORE, `redo`, tl);
2356
+ };
2357
+ var undo = (tl) => {
2358
+ timeTravel(IMPLICIT.STORE, `undo`, tl);
2359
+ };
2360
+
2361
+ // src/transaction.ts
2362
+ function transaction(options) {
2363
+ return createTransaction(IMPLICIT.STORE, options);
1865
2364
  }
1866
- function getEpochNumberOfAction(transactionKey, store) {
1867
- const isRoot = isRootStore(store);
1868
- const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : undefined;
1869
- const epoch = isRoot && continuity !== undefined ? store.transactionMeta.epoch.get(continuity) : undefined;
1870
- return epoch;
2365
+ function runTransaction(token, id = arbitrary()) {
2366
+ return actUponStore(IMPLICIT.STORE, token, id);
1871
2367
  }
1872
2368
 
1873
- // internal/src/transaction/index.ts
1874
- var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
2369
+ // src/validators.ts
2370
+ function isToken(knownToken, unknownToken) {
2371
+ return knownToken.key === unknownToken.key;
2372
+ }
2373
+ function belongsTo(family, unknownToken) {
2374
+ return family.key === unknownToken.family?.key;
2375
+ }
1875
2376
 
1876
2377
  // internal/src/store/store.ts
1877
2378
  var Store = class {
@@ -1998,32 +2499,32 @@ var Store = class {
1998
2499
  family.install(this);
1999
2500
  }
2000
2501
  const mutableHelpers = /* @__PURE__ */ new Set();
2001
- for (const [, atom] of store.atoms) {
2002
- if (mutableHelpers.has(atom.key)) {
2502
+ for (const [, atom2] of store.atoms) {
2503
+ if (mutableHelpers.has(atom2.key)) {
2003
2504
  continue;
2004
2505
  }
2005
- atom.install(this);
2006
- if (atom.type === `mutable_atom`) {
2007
- const originalJsonToken = getJsonToken(store, atom);
2008
- const originalUpdateToken = getUpdateToken(atom);
2506
+ atom2.install(this);
2507
+ if (atom2.type === `mutable_atom`) {
2508
+ const originalJsonToken = getJsonToken(store, atom2);
2509
+ const originalUpdateToken = getUpdateToken(atom2);
2009
2510
  mutableHelpers.add(originalJsonToken.key);
2010
2511
  mutableHelpers.add(originalUpdateToken.key);
2011
2512
  }
2012
2513
  }
2013
- for (const [, selector] of store.readonlySelectors) {
2014
- selector.install(this);
2514
+ for (const [, selector2] of store.readonlySelectors) {
2515
+ selector2.install(this);
2015
2516
  }
2016
- for (const [, selector] of store.selectors) {
2017
- if (mutableHelpers.has(selector.key)) {
2517
+ for (const [, selector2] of store.selectors) {
2518
+ if (mutableHelpers.has(selector2.key)) {
2018
2519
  continue;
2019
2520
  }
2020
- selector.install(this);
2521
+ selector2.install(this);
2021
2522
  }
2022
2523
  for (const [, tx] of store.transactions) {
2023
2524
  tx.install(this);
2024
2525
  }
2025
- for (const [, timeline] of store.timelines) {
2026
- timeline.install(this);
2526
+ for (const [, timeline2] of store.timelines) {
2527
+ timeline2.install(this);
2027
2528
  }
2028
2529
  }
2029
2530
  }
@@ -2049,7 +2550,7 @@ var clearStore = (store) => {
2049
2550
  };
2050
2551
 
2051
2552
  // internal/src/store/withdraw.ts
2052
- function withdraw(token, store) {
2553
+ function withdraw(store, token) {
2053
2554
  let withdrawn;
2054
2555
  let target = store;
2055
2556
  while (target !== null) {
@@ -2086,45 +2587,47 @@ function withdraw(token, store) {
2086
2587
  }
2087
2588
 
2088
2589
  // internal/src/subscribe/recall-state.ts
2089
- var recallState = (state, store) => {
2590
+ var recallState = (store, state) => {
2090
2591
  const target = newest(store);
2091
2592
  if (target.operation.open) {
2092
2593
  return target.operation.prev.get(state.key);
2093
2594
  }
2094
2595
  return target.valueMap.get(state.key);
2095
2596
  };
2096
- function subscribeInStore(store, token, handleUpdate, key = arbitrary$1()) {
2597
+
2598
+ // internal/src/subscribe/subscribe-in-store.ts
2599
+ function subscribeInStore(store, token, handleUpdate, key = arbitrary()) {
2097
2600
  switch (token.type) {
2098
2601
  case `atom`:
2099
2602
  case `mutable_atom`:
2100
2603
  case `readonly_selector`:
2101
2604
  case `selector`:
2102
- return subscribeToState(token, handleUpdate, key, store);
2605
+ return subscribeToState(store, token, key, handleUpdate);
2103
2606
  case `transaction`:
2104
- return subscribeToTransaction(token, handleUpdate, key, store);
2607
+ return subscribeToTransaction(store, token, key, handleUpdate);
2105
2608
  case `timeline`:
2106
- return subscribeToTimeline(token, handleUpdate, key, store);
2609
+ return subscribeToTimeline(store, token, key, handleUpdate);
2107
2610
  }
2108
2611
  }
2109
2612
 
2110
2613
  // internal/src/subscribe/subscribe-to-root-atoms.ts
2111
- var subscribeToRootAtoms = (selector, store) => {
2614
+ var subscribeToRootAtoms = (store, selector2) => {
2112
2615
  const target = newest(store);
2113
- const dependencySubscriptions = traceAllSelectorAtoms(selector, store).map(
2616
+ const dependencySubscriptions = traceAllSelectorAtoms(selector2, store).map(
2114
2617
  (atomKey) => {
2115
- const atom = target.atoms.get(atomKey);
2116
- if (atom === undefined) {
2618
+ const atom2 = target.atoms.get(atomKey);
2619
+ if (atom2 === undefined) {
2117
2620
  throw new Error(
2118
- `Atom "${atomKey}", a dependency of selector "${selector.key}", not found in store "${store.config.name}".`
2621
+ `Atom "${atomKey}", a dependency of selector "${selector2.key}", not found in store "${store.config.name}".`
2119
2622
  );
2120
2623
  }
2121
- return atom.subject.subscribe(
2122
- `${selector.type}:${selector.key}`,
2624
+ return atom2.subject.subscribe(
2625
+ `${selector2.type}:${selector2.key}`,
2123
2626
  (atomChange) => {
2124
2627
  store.logger.info(
2125
2628
  `\u{1F4E2}`,
2126
- selector.type,
2127
- selector.key,
2629
+ selector2.type,
2630
+ selector2.key,
2128
2631
  `root`,
2129
2632
  atomKey,
2130
2633
  `went`,
@@ -2132,18 +2635,18 @@ var subscribeToRootAtoms = (selector, store) => {
2132
2635
  `->`,
2133
2636
  atomChange.newValue
2134
2637
  );
2135
- const oldValue = recallState(selector, target);
2136
- const newValue = readOrComputeValue(selector, target);
2638
+ const oldValue = recallState(target, selector2);
2639
+ const newValue = readOrComputeValue(target, selector2);
2137
2640
  store.logger.info(
2138
2641
  `\u2728`,
2139
- selector.type,
2140
- selector.key,
2642
+ selector2.type,
2643
+ selector2.key,
2141
2644
  `went`,
2142
2645
  oldValue,
2143
2646
  `->`,
2144
2647
  newValue
2145
2648
  );
2146
- selector.subject.next({ newValue, oldValue });
2649
+ selector2.subject.next({ newValue, oldValue });
2147
2650
  }
2148
2651
  );
2149
2652
  }
@@ -2152,7 +2655,7 @@ var subscribeToRootAtoms = (selector, store) => {
2152
2655
  };
2153
2656
 
2154
2657
  // internal/src/subscribe/subscribe-to-state.ts
2155
- function subscribeToState2(token, handleUpdate, key, store) {
2658
+ function subscribeToState(store, token, key, handleUpdate) {
2156
2659
  function safelyHandleUpdate(update) {
2157
2660
  if (store.operation.open) {
2158
2661
  const unsubscribe2 = store.on.operationClose.subscribe(
@@ -2166,17 +2669,17 @@ function subscribeToState2(token, handleUpdate, key, store) {
2166
2669
  handleUpdate(update);
2167
2670
  }
2168
2671
  }
2169
- const state = withdraw(token, store);
2672
+ const state = withdraw(store, token);
2170
2673
  store.logger.info(`\u{1F440}`, state.type, state.key, `Adding subscription "${key}"`);
2171
2674
  const isSelector = state.type === `selector` || state.type === `readonly_selector`;
2172
2675
  let dependencyUnsubFunctions = null;
2173
2676
  let updateHandler = safelyHandleUpdate;
2174
2677
  if (isSelector) {
2175
- dependencyUnsubFunctions = subscribeToRootAtoms(state, store);
2678
+ dependencyUnsubFunctions = subscribeToRootAtoms(store, state);
2176
2679
  updateHandler = (update) => {
2177
2680
  if (dependencyUnsubFunctions) {
2178
2681
  dependencyUnsubFunctions.length = 0;
2179
- dependencyUnsubFunctions.push(...subscribeToRootAtoms(state, store));
2682
+ dependencyUnsubFunctions.push(...subscribeToRootAtoms(store, state));
2180
2683
  }
2181
2684
  safelyHandleUpdate(update);
2182
2685
  };
@@ -2200,8 +2703,8 @@ function subscribeToState2(token, handleUpdate, key, store) {
2200
2703
  }
2201
2704
 
2202
2705
  // internal/src/subscribe/subscribe-to-timeline.ts
2203
- var subscribeToTimeline2 = (token, handleUpdate, key, store) => {
2204
- const tl = withdraw(token, store);
2706
+ var subscribeToTimeline = (store, token, key, handleUpdate) => {
2707
+ const tl = withdraw(store, token);
2205
2708
  store.logger.info(`\u{1F440}`, `timeline`, token.key, `Adding subscription "${key}"`);
2206
2709
  const unsubscribe = tl.subject.subscribe(key, handleUpdate);
2207
2710
  return () => {
@@ -2216,8 +2719,8 @@ var subscribeToTimeline2 = (token, handleUpdate, key, store) => {
2216
2719
  };
2217
2720
 
2218
2721
  // internal/src/subscribe/subscribe-to-transaction.ts
2219
- var subscribeToTransaction2 = (token, handleUpdate, key, store) => {
2220
- const tx = withdraw(token, store);
2722
+ var subscribeToTransaction = (store, token, key, handleUpdate) => {
2723
+ const tx = withdraw(store, token);
2221
2724
  store.logger.info(
2222
2725
  `\u{1F440}`,
2223
2726
  `transaction`,
@@ -2272,8 +2775,10 @@ var Tracker = class {
2272
2775
  setIntoStore(target, latestUpdateState, update);
2273
2776
  }
2274
2777
  );
2275
- this.unsubscribeFromState = subscribeToState2(
2778
+ this.unsubscribeFromState = subscribeToState(
2779
+ target,
2276
2780
  mutableState,
2781
+ subscriptionKey,
2277
2782
  (update) => {
2278
2783
  if (update.newValue !== update.oldValue) {
2279
2784
  this.unsubscribeFromInnerValue();
@@ -2284,15 +2789,15 @@ var Tracker = class {
2284
2789
  }
2285
2790
  );
2286
2791
  }
2287
- },
2288
- subscriptionKey,
2289
- target
2792
+ }
2290
2793
  );
2291
2794
  }
2292
2795
  updateCore(mutableState, latestUpdateState, target) {
2293
2796
  const subscriptionKey = `tracker:${target.config.name}:${isChildStore(target) ? target.transactionMeta.update.key : `main`}:${mutableState.key}`;
2294
- subscribeToState2(
2797
+ subscribeToState(
2798
+ target,
2295
2799
  latestUpdateState,
2800
+ subscriptionKey,
2296
2801
  ({ newValue, oldValue }) => {
2297
2802
  const timelineId = target.timelineTopics.getRelatedKey(
2298
2803
  latestUpdateState.key
@@ -2300,8 +2805,10 @@ var Tracker = class {
2300
2805
  if (timelineId) {
2301
2806
  const timelineData = target.timelines.get(timelineId);
2302
2807
  if (timelineData?.timeTraveling) {
2303
- const unsubscribe2 = subscribeToTimeline2(
2808
+ const unsubscribe2 = subscribeToTimeline(
2809
+ target,
2304
2810
  { key: timelineId, type: `timeline` },
2811
+ subscriptionKey,
2305
2812
  (update) => {
2306
2813
  unsubscribe2();
2307
2814
  setIntoStore(target, mutableState, (transceiver) => {
@@ -2312,9 +2819,7 @@ var Tracker = class {
2312
2819
  }
2313
2820
  return transceiver;
2314
2821
  });
2315
- },
2316
- subscriptionKey,
2317
- target
2822
+ }
2318
2823
  );
2319
2824
  return;
2320
2825
  }
@@ -2342,14 +2847,12 @@ var Tracker = class {
2342
2847
  }
2343
2848
  }
2344
2849
  );
2345
- },
2346
- subscriptionKey,
2347
- target
2850
+ }
2348
2851
  );
2349
2852
  }
2350
2853
  mutableState;
2351
2854
  latestUpdateState;
2352
- dispose;
2855
+ [Symbol.dispose];
2353
2856
  constructor(mutableState, store) {
2354
2857
  this.mutableState = mutableState;
2355
2858
  const target = newest(store);
@@ -2357,7 +2860,7 @@ var Tracker = class {
2357
2860
  this.observeCore(mutableState, this.latestUpdateState, target);
2358
2861
  this.updateCore(mutableState, this.latestUpdateState, target);
2359
2862
  target.trackers.set(mutableState.key, this);
2360
- this.dispose = () => {
2863
+ this[Symbol.dispose] = () => {
2361
2864
  this.unsubscribeFromInnerValue();
2362
2865
  this.unsubscribeFromState();
2363
2866
  target.trackers.delete(mutableState.key);
@@ -2404,8 +2907,8 @@ function createMutableAtom(store, options, family) {
2404
2907
  }
2405
2908
  const initialValue = options.default();
2406
2909
  target.atoms.set(newAtom.key, newAtom);
2407
- markAtomAsDefault(options.key, store);
2408
- cacheValue(options.key, initialValue, subject, target);
2910
+ markAtomAsDefault(store, options.key);
2911
+ cacheValue(target, options.key, initialValue, subject);
2409
2912
  const token = deposit(newAtom);
2410
2913
  if (options.effects) {
2411
2914
  let effectIndex = 0;
@@ -2415,7 +2918,7 @@ function createMutableAtom(store, options, family) {
2415
2918
  setSelf: (next) => {
2416
2919
  setIntoStore(store, token, next);
2417
2920
  },
2418
- onSet: (handle) => subscribeToState2(token, handle, `effect[${effectIndex}]`, store)
2921
+ onSet: (handle) => subscribeToState(store, token, `effect[${effectIndex}]`, handle)
2419
2922
  });
2420
2923
  if (cleanup) {
2421
2924
  cleanupFunctions.push(cleanup);
@@ -2434,7 +2937,10 @@ function createMutableAtom(store, options, family) {
2434
2937
  }
2435
2938
  return token;
2436
2939
  }
2940
+
2941
+ // internal/src/mutable/tracker-family.ts
2437
2942
  var FamilyTracker = class {
2943
+ trackers = /* @__PURE__ */ new Map();
2438
2944
  Update;
2439
2945
  latestUpdateAtoms;
2440
2946
  mutableAtoms;
@@ -2447,26 +2953,27 @@ var FamilyTracker = class {
2447
2953
  },
2448
2954
  [`mutable`, `updates`]
2449
2955
  );
2450
- this.latestUpdateAtoms = withdraw(updateAtoms, store);
2956
+ this.latestUpdateAtoms = withdraw(store, updateAtoms);
2451
2957
  this.mutableAtoms = mutableAtoms;
2452
2958
  this.mutableAtoms.subject.subscribe(
2453
2959
  `store=${store.config.name}::tracker-atom-family`,
2454
2960
  (event) => {
2455
- if (event.token.family) {
2456
- const key = parseJson(event.token.family.subKey);
2457
- seekInStore(store, this.latestUpdateAtoms, key);
2458
- new Tracker(event.token, store);
2459
- }
2460
- }
2461
- );
2462
- this.latestUpdateAtoms.subject.subscribe(
2463
- `store=${store.config.name}::tracker-atom-family`,
2464
- (event) => {
2465
- if (event.token.family) {
2466
- const key = parseJson(event.token.family.subKey);
2467
- const mutableAtomToken = seekInStore(store, this.mutableAtoms, key);
2468
- if (mutableAtomToken) {
2469
- new Tracker(mutableAtomToken, store);
2961
+ const { type, token } = event;
2962
+ if (token.family) {
2963
+ const key = parseJson(token.family.subKey);
2964
+ switch (type) {
2965
+ case `state_creation`:
2966
+ this.trackers.set(key, new Tracker(token, store));
2967
+ break;
2968
+ case `state_disposal`:
2969
+ {
2970
+ const tracker = this.trackers.get(key);
2971
+ if (tracker) {
2972
+ tracker[Symbol.dispose]();
2973
+ this.trackers.delete(key);
2974
+ }
2975
+ }
2976
+ break;
2470
2977
  }
2471
2978
  }
2472
2979
  }
@@ -2511,16 +3018,16 @@ function createMutableAtomFamily(store, options, internalRoles) {
2511
3018
  subject.next({ type: `state_creation`, token });
2512
3019
  return token;
2513
3020
  };
2514
- const atomFamily = Object.assign(familyFunction, familyToken, {
3021
+ const atomFamily2 = Object.assign(familyFunction, familyToken, {
2515
3022
  subject,
2516
3023
  install: (s) => createMutableAtomFamily(s, options),
2517
3024
  toJson: options.toJson,
2518
3025
  fromJson: options.fromJson,
2519
3026
  internalRoles
2520
3027
  });
2521
- store.families.set(options.key, atomFamily);
2522
- selectJsonFamily(atomFamily, options, store);
2523
- new FamilyTracker(atomFamily, store);
3028
+ store.families.set(options.key, atomFamily2);
3029
+ selectJsonFamily(store, atomFamily2, options);
3030
+ new FamilyTracker(atomFamily2, store);
2524
3031
  return familyToken;
2525
3032
  }
2526
3033
 
@@ -2541,7 +3048,7 @@ var getJsonToken = (store, mutableAtomToken) => {
2541
3048
  key: jsonFamilyKey,
2542
3049
  type: `selector_family`
2543
3050
  };
2544
- const family = withdraw(jsonFamilyToken, target);
3051
+ const family = withdraw(target, jsonFamilyToken);
2545
3052
  const subKey = JSON.parse(mutableAtomToken.family.subKey);
2546
3053
  const jsonToken = findInStore(store, family, subKey);
2547
3054
  return jsonToken;
@@ -2582,25 +3089,25 @@ function isTransceiver(value) {
2582
3089
  }
2583
3090
 
2584
3091
  // internal/src/set-state/copy-mutable-if-needed.ts
2585
- function copyMutableIfNeeded(atom, origin, target) {
2586
- const originValue = origin.valueMap.get(atom.key);
2587
- const targetValue = target.valueMap.get(atom.key);
3092
+ function copyMutableIfNeeded(target, atom2, origin) {
3093
+ const originValue = origin.valueMap.get(atom2.key);
3094
+ const targetValue = target.valueMap.get(atom2.key);
2588
3095
  if (originValue === targetValue) {
2589
3096
  if (originValue === undefined) {
2590
- return typeof atom.default === `function` ? atom.default() : atom.default;
3097
+ return typeof atom2.default === `function` ? atom2.default() : atom2.default;
2591
3098
  }
2592
- origin.logger.info(`\u{1F4C3}`, `atom`, atom.key, `copying`);
2593
- const jsonValue = atom.toJson(originValue);
2594
- const copiedValue = atom.fromJson(jsonValue);
2595
- target.valueMap.set(atom.key, copiedValue);
2596
- new Tracker(atom, origin);
3099
+ origin.logger.info(`\u{1F4C3}`, `atom`, atom2.key, `copying`);
3100
+ const jsonValue = atom2.toJson(originValue);
3101
+ const copiedValue = atom2.fromJson(jsonValue);
3102
+ target.valueMap.set(atom2.key, copiedValue);
3103
+ new Tracker(atom2, origin);
2597
3104
  return copiedValue;
2598
3105
  }
2599
3106
  return targetValue;
2600
3107
  }
2601
3108
 
2602
3109
  // internal/src/caching.ts
2603
- function cacheValue(key, value, subject, target) {
3110
+ function cacheValue(target, key, value, subject) {
2604
3111
  const currentValue = target.valueMap.get(key);
2605
3112
  if (currentValue instanceof Future) {
2606
3113
  const future = currentValue;
@@ -2610,7 +3117,7 @@ function cacheValue(key, value, subject, target) {
2610
3117
  const future = new Future(value);
2611
3118
  target.valueMap.set(key, future);
2612
3119
  future.then((resolved) => {
2613
- cacheValue(key, resolved, subject, target);
3120
+ cacheValue(target, key, resolved, subject);
2614
3121
  subject.next({ newValue: resolved, oldValue: future });
2615
3122
  }).catch((thrown) => {
2616
3123
  target.logger.error(`\u{1F4A5}`, `state`, key, `rejected:`, thrown);
@@ -2624,7 +3131,7 @@ var readCachedValue = (token, target) => {
2624
3131
  let value = target.valueMap.get(token.key);
2625
3132
  if (token.type === `mutable_atom` && isChildStore(target)) {
2626
3133
  const { parent } = target;
2627
- const copiedValue = copyMutableIfNeeded(token, parent, target);
3134
+ const copiedValue = copyMutableIfNeeded(target, token, parent);
2628
3135
  value = copiedValue;
2629
3136
  }
2630
3137
  return value;
@@ -2633,9 +3140,9 @@ var evictCachedValue = (key, target) => {
2633
3140
  const currentValue = target.valueMap.get(key);
2634
3141
  if (currentValue instanceof Future) {
2635
3142
  const future = currentValue;
2636
- const selector = target.selectors.get(key) ?? target.readonlySelectors.get(key);
2637
- if (selector) {
2638
- future.use(selector.get());
3143
+ const selector2 = target.selectors.get(key) ?? target.readonlySelectors.get(key);
3144
+ if (selector2) {
3145
+ future.use(selector2.get());
2639
3146
  }
2640
3147
  return;
2641
3148
  }
@@ -2647,15 +3154,15 @@ var evictCachedValue = (key, target) => {
2647
3154
  };
2648
3155
 
2649
3156
  // internal/src/atom/is-default.ts
2650
- var isAtomDefault = (key, store) => {
3157
+ var isAtomDefault = (store, key) => {
2651
3158
  const core = newest(store);
2652
3159
  return core.atomsThatAreDefault.has(key);
2653
3160
  };
2654
- var markAtomAsDefault = (key, store) => {
3161
+ var markAtomAsDefault = (store, key) => {
2655
3162
  const core = newest(store);
2656
3163
  core.atomsThatAreDefault = new Set(core.atomsThatAreDefault).add(key);
2657
3164
  };
2658
- var markAtomAsNotDefault = (key, store) => {
3165
+ var markAtomAsNotDefault = (store, key) => {
2659
3166
  const core = newest(store);
2660
3167
  core.atomsThatAreDefault = new Set(newest(store).atomsThatAreDefault);
2661
3168
  core.atomsThatAreDefault.delete(key);
@@ -2703,8 +3210,8 @@ function createRegularAtom(store, options, family) {
2703
3210
  initialValue = options.default();
2704
3211
  }
2705
3212
  target.atoms.set(newAtom.key, newAtom);
2706
- markAtomAsDefault(options.key, store);
2707
- cacheValue(options.key, initialValue, subject, target);
3213
+ markAtomAsDefault(store, options.key);
3214
+ cacheValue(target, options.key, initialValue, subject);
2708
3215
  const token = deposit(newAtom);
2709
3216
  if (options.effects) {
2710
3217
  let effectIndex = 0;
@@ -2714,7 +3221,7 @@ function createRegularAtom(store, options, family) {
2714
3221
  setSelf: (next) => {
2715
3222
  setIntoStore(store, token, next);
2716
3223
  },
2717
- onSet: (handle) => subscribeToState2(token, handle, `effect[${effectIndex}]`, store)
3224
+ onSet: (handle) => subscribeToState(store, token, `effect[${effectIndex}]`, handle)
2718
3225
  });
2719
3226
  if (cleanup) {
2720
3227
  cleanupFunctions.push(cleanup);
@@ -2744,23 +3251,23 @@ function createStandaloneAtom(store, options) {
2744
3251
  }
2745
3252
 
2746
3253
  // internal/src/atom/dispose-atom.ts
2747
- function disposeAtom(atomToken, store) {
3254
+ function disposeAtom(store, atomToken) {
2748
3255
  const target = newest(store);
2749
3256
  const { key, family } = atomToken;
2750
- const atom = withdraw(atomToken, target);
3257
+ const atom2 = withdraw(target, atomToken);
2751
3258
  if (!family) {
2752
3259
  store.logger.error(`\u274C`, `atom`, key, `Standalone atoms cannot be disposed.`);
2753
3260
  } else {
2754
- atom.cleanup?.();
2755
- const lastValue = store.valueMap.get(atom.key);
2756
- const atomFamily = withdraw({ key: family.key, type: `atom_family` }, store);
3261
+ atom2.cleanup?.();
3262
+ const lastValue = store.valueMap.get(atom2.key);
3263
+ const atomFamily2 = withdraw(store, { key: family.key, type: `atom_family` });
2757
3264
  const disposal = {
2758
3265
  type: `state_disposal`,
2759
3266
  subType: `atom`,
2760
3267
  token: atomToken,
2761
3268
  value: lastValue
2762
3269
  };
2763
- atomFamily.subject.next(disposal);
3270
+ atomFamily2.subject.next(disposal);
2764
3271
  const isChild = isChildStore(target);
2765
3272
  target.atoms.delete(key);
2766
3273
  target.valueMap.delete(key);
@@ -2769,14 +3276,14 @@ function disposeAtom(atomToken, store) {
2769
3276
  store.timelineTopics.delete(key);
2770
3277
  if (atomToken.type === `mutable_atom`) {
2771
3278
  const updateToken = getUpdateToken(atomToken);
2772
- disposeAtom(updateToken, store);
3279
+ disposeAtom(store, updateToken);
2773
3280
  store.trackers.delete(key);
2774
3281
  }
2775
3282
  store.logger.info(`\u{1F525}`, `atom`, key, `deleted`);
2776
3283
  if (isChild && target.transactionMeta.phase === `building`) {
2777
3284
  const mostRecentUpdate = target.transactionMeta.update.updates.at(-1);
2778
3285
  const wasMoleculeDisposal = mostRecentUpdate?.type === `molecule_disposal`;
2779
- const updateAlreadyCaptured = wasMoleculeDisposal && mostRecentUpdate.values.some(([k]) => k === atom.family?.key);
3286
+ const updateAlreadyCaptured = wasMoleculeDisposal && mostRecentUpdate.values.some(([k]) => k === atom2.family?.key);
2780
3287
  if (!updateAlreadyCaptured) {
2781
3288
  target.transactionMeta.update.updates.push(disposal);
2782
3289
  }
@@ -2786,20 +3293,746 @@ function disposeAtom(atomToken, store) {
2786
3293
  }
2787
3294
  }
2788
3295
 
2789
- // internal/src/get-trace.ts
2790
- function getTrace(error) {
2791
- const { stack } = error;
2792
- if (stack) {
2793
- return `
2794
- ` + stack.split(`
2795
- `)?.slice(1)?.join(`
2796
- `);
3296
+ // transceivers/set-rtx/src/set-rtx.ts
3297
+ var SetRTX = class _SetRTX extends Set {
3298
+ mode = `record`;
3299
+ subject = new Subject();
3300
+ cacheLimit = 0;
3301
+ cache = [];
3302
+ cacheIdx = -1;
3303
+ cacheUpdateNumber = -1;
3304
+ constructor(values, cacheLimit = 0) {
3305
+ super(values);
3306
+ if (values instanceof _SetRTX) {
3307
+ this.parent = values;
3308
+ this.cacheUpdateNumber = values.cacheUpdateNumber;
3309
+ }
3310
+ if (cacheLimit) {
3311
+ this.cacheLimit = cacheLimit;
3312
+ this.cache = new Array(cacheLimit);
3313
+ this.subscribe(`auto cache`, (update) => {
3314
+ this.cacheIdx++;
3315
+ this.cacheIdx %= this.cacheLimit;
3316
+ this.cache[this.cacheIdx] = update;
3317
+ });
3318
+ }
2797
3319
  }
2798
- return ``;
3320
+ toJSON() {
3321
+ return {
3322
+ members: [...this],
3323
+ cache: this.cache,
3324
+ cacheLimit: this.cacheLimit,
3325
+ cacheIdx: this.cacheIdx,
3326
+ cacheUpdateNumber: this.cacheUpdateNumber
3327
+ };
3328
+ }
3329
+ static fromJSON(json) {
3330
+ const set = new _SetRTX(json.members, json.cacheLimit);
3331
+ set.cache = json.cache;
3332
+ set.cacheIdx = json.cacheIdx;
3333
+ set.cacheUpdateNumber = json.cacheUpdateNumber;
3334
+ return set;
3335
+ }
3336
+ add(value) {
3337
+ const result = super.add(value);
3338
+ if (this.mode === `record`) {
3339
+ this.cacheUpdateNumber++;
3340
+ this.emit(`add:${stringifyJson(value)}`);
3341
+ }
3342
+ return result;
3343
+ }
3344
+ clear() {
3345
+ const capturedContents = this.mode === `record` ? [...this] : null;
3346
+ super.clear();
3347
+ if (capturedContents) {
3348
+ this.cacheUpdateNumber++;
3349
+ this.emit(`clear:${JSON.stringify(capturedContents)}`);
3350
+ }
3351
+ }
3352
+ delete(value) {
3353
+ const result = super.delete(value);
3354
+ if (this.mode === `record`) {
3355
+ this.cacheUpdateNumber++;
3356
+ this.emit(`del:${stringifyJson(value)}`);
3357
+ }
3358
+ return result;
3359
+ }
3360
+ parent;
3361
+ child = null;
3362
+ transactionUpdates = null;
3363
+ transaction(run) {
3364
+ this.mode = `transaction`;
3365
+ this.transactionUpdates = [];
3366
+ this.child = new _SetRTX(this);
3367
+ const unsubscribe = this.child._subscribe(`transaction`, (update) => {
3368
+ this.transactionUpdates?.push(update);
3369
+ });
3370
+ try {
3371
+ const shouldCommit = run(this.child);
3372
+ if (shouldCommit) {
3373
+ for (const update of this.transactionUpdates) {
3374
+ this.doStep(update);
3375
+ }
3376
+ this.cacheUpdateNumber++;
3377
+ this.emit(`tx:${this.transactionUpdates.join(`;`)}`);
3378
+ }
3379
+ } catch (thrown) {
3380
+ console.warn(
3381
+ `Did not apply transaction to SetRTX; this error was thrown:`,
3382
+ thrown
3383
+ );
3384
+ throw thrown;
3385
+ } finally {
3386
+ unsubscribe();
3387
+ this.child = null;
3388
+ this.transactionUpdates = null;
3389
+ this.mode = `record`;
3390
+ }
3391
+ }
3392
+ _subscribe(key, fn) {
3393
+ return this.subject.subscribe(key, fn);
3394
+ }
3395
+ subscribe(key, fn) {
3396
+ return this.subject.subscribe(key, (update) => {
3397
+ fn(`${this.cacheUpdateNumber}=${update}`);
3398
+ });
3399
+ }
3400
+ emit(update) {
3401
+ this.subject.next(update);
3402
+ }
3403
+ doStep(update) {
3404
+ const typeValueBreak = update.indexOf(`:`);
3405
+ const type = update.substring(0, typeValueBreak);
3406
+ const value = update.substring(typeValueBreak + 1);
3407
+ switch (type) {
3408
+ case `add`:
3409
+ this.add(JSON.parse(value));
3410
+ break;
3411
+ case `clear`:
3412
+ this.clear();
3413
+ break;
3414
+ case `del`:
3415
+ this.delete(JSON.parse(value));
3416
+ break;
3417
+ case `tx`:
3418
+ for (const subUpdate of value.split(`;`)) {
3419
+ this.doStep(subUpdate);
3420
+ }
3421
+ }
3422
+ }
3423
+ getUpdateNumber(update) {
3424
+ const breakpoint = update.indexOf(`=`);
3425
+ return Number(update.substring(0, breakpoint));
3426
+ }
3427
+ do(update) {
3428
+ const breakpoint = update.indexOf(`=`);
3429
+ const updateNumber = Number(update.substring(0, breakpoint));
3430
+ const eventOffset = updateNumber - this.cacheUpdateNumber;
3431
+ const isFuture = eventOffset > 0;
3432
+ if (isFuture) {
3433
+ if (eventOffset === 1) {
3434
+ this.mode = `playback`;
3435
+ const innerUpdate = update.substring(breakpoint + 1);
3436
+ this.doStep(innerUpdate);
3437
+ this.mode = `record`;
3438
+ this.cacheUpdateNumber = updateNumber;
3439
+ return null;
3440
+ }
3441
+ return this.cacheUpdateNumber + 1;
3442
+ }
3443
+ if (Math.abs(eventOffset) < this.cacheLimit) {
3444
+ const eventIdx = this.cacheIdx + eventOffset;
3445
+ const cachedUpdate = this.cache[eventIdx];
3446
+ if (cachedUpdate === update) {
3447
+ return null;
3448
+ }
3449
+ this.mode = `playback`;
3450
+ let done = false;
3451
+ while (!done) {
3452
+ this.cacheIdx %= this.cacheLimit;
3453
+ const u = this.cache[this.cacheIdx];
3454
+ this.cacheIdx--;
3455
+ if (!u) {
3456
+ return `OUT_OF_RANGE`;
3457
+ }
3458
+ this.undo(u);
3459
+ done = this.cacheIdx === eventIdx - 1;
3460
+ }
3461
+ const innerUpdate = update.substring(breakpoint + 1);
3462
+ this.doStep(innerUpdate);
3463
+ this.mode = `record`;
3464
+ this.cacheUpdateNumber = updateNumber;
3465
+ return null;
3466
+ }
3467
+ return `OUT_OF_RANGE`;
3468
+ }
3469
+ undoStep(update) {
3470
+ const breakpoint = update.indexOf(`:`);
3471
+ const type = update.substring(0, breakpoint);
3472
+ const value = update.substring(breakpoint + 1);
3473
+ switch (type) {
3474
+ case `add`:
3475
+ this.delete(JSON.parse(value));
3476
+ break;
3477
+ case `del`:
3478
+ this.add(JSON.parse(value));
3479
+ break;
3480
+ case `clear`: {
3481
+ const values = JSON.parse(value);
3482
+ for (const v of values) this.add(v);
3483
+ break;
3484
+ }
3485
+ case `tx`: {
3486
+ const updates = value.split(`;`);
3487
+ for (let i = updates.length - 1; i >= 0; i--) {
3488
+ this.undoStep(updates[i]);
3489
+ }
3490
+ }
3491
+ }
3492
+ }
3493
+ undo(update) {
3494
+ const breakpoint = update.indexOf(`=`);
3495
+ const updateNumber = Number(update.substring(0, breakpoint));
3496
+ if (updateNumber === this.cacheUpdateNumber) {
3497
+ this.mode = `playback`;
3498
+ const innerUpdate = update.substring(breakpoint + 1);
3499
+ this.undoStep(innerUpdate);
3500
+ this.mode = `record`;
3501
+ this.cacheUpdateNumber--;
3502
+ return null;
3503
+ }
3504
+ return this.cacheUpdateNumber;
3505
+ }
3506
+ };
3507
+
3508
+ // internal/src/join/join-internal.ts
3509
+ var Join = class {
3510
+ toolkit;
3511
+ options;
3512
+ defaultContent;
3513
+ molecules = /* @__PURE__ */ new Map();
3514
+ relations;
3515
+ states;
3516
+ core;
3517
+ transact(toolkit, run) {
3518
+ const originalToolkit = this.toolkit;
3519
+ this.toolkit = toolkit;
3520
+ run(this);
3521
+ this.toolkit = originalToolkit;
3522
+ }
3523
+ store;
3524
+ realm;
3525
+ [Symbol.dispose]() {
3526
+ }
3527
+ constructor(options, defaultContent, store = IMPLICIT.STORE) {
3528
+ this.store = store;
3529
+ this.realm = new Anarchy(store);
3530
+ this.options = options;
3531
+ this.defaultContent = defaultContent;
3532
+ this.store.miscResources.set(`join:${options.key}`, this);
3533
+ this.realm.allocate(`root`, options.key);
3534
+ this.toolkit = {
3535
+ get: (...ps) => getFromStore(store, ...ps),
3536
+ set: (...ps) => {
3537
+ setIntoStore(store, ...ps);
3538
+ },
3539
+ find: (...ps) => findInStore(store, ...ps),
3540
+ json: (token) => getJsonToken(store, token)
3541
+ };
3542
+ const aSide = options.between[0];
3543
+ const bSide = options.between[1];
3544
+ const relatedKeysAtoms = createMutableAtomFamily(
3545
+ store,
3546
+ {
3547
+ key: `${options.key}/relatedKeys`,
3548
+ default: () => new SetRTX(),
3549
+ mutable: true,
3550
+ fromJson: (json) => SetRTX.fromJSON(json),
3551
+ toJson: (set) => set.toJSON()
3552
+ },
3553
+ [`join`, `relations`]
3554
+ );
3555
+ this.core = { relatedKeysAtoms };
3556
+ const getRelatedKeys = ({ get }, key) => get(relatedKeysAtoms, key);
3557
+ const addRelation = ({ set }, a, b) => {
3558
+ if (!this.store.molecules.has(stringifyJson(a))) {
3559
+ this.realm.allocate(options.key, a);
3560
+ }
3561
+ set(relatedKeysAtoms, a, (aKeys) => aKeys.add(b));
3562
+ set(relatedKeysAtoms, b, (bKeys) => bKeys.add(a));
3563
+ };
3564
+ const deleteRelation = ({ set }, a, b) => {
3565
+ set(relatedKeysAtoms, a, (aKeys) => {
3566
+ aKeys.delete(b);
3567
+ return aKeys;
3568
+ });
3569
+ set(relatedKeysAtoms, b, (bKeys) => {
3570
+ bKeys.delete(a);
3571
+ return bKeys;
3572
+ });
3573
+ };
3574
+ const replaceRelationsSafely = (toolkit, a, newRelationsOfA) => {
3575
+ const { find, get, set } = toolkit;
3576
+ const relationsOfAState = find(relatedKeysAtoms, a);
3577
+ const currentRelationsOfA = get(relationsOfAState);
3578
+ for (const currentRelationB of currentRelationsOfA) {
3579
+ const remainsRelated = newRelationsOfA.includes(currentRelationB);
3580
+ if (remainsRelated) {
3581
+ continue;
3582
+ }
3583
+ set(relatedKeysAtoms, currentRelationB, (relationsOfB) => {
3584
+ relationsOfB.delete(a);
3585
+ return relationsOfB;
3586
+ });
3587
+ }
3588
+ set(relationsOfAState, (relationsOfA) => {
3589
+ relationsOfA.transaction((nextRelationsOfA) => {
3590
+ nextRelationsOfA.clear();
3591
+ for (const newRelationB of newRelationsOfA) {
3592
+ const relationsOfB = getRelatedKeys(toolkit, newRelationB);
3593
+ const newRelationBIsAlreadyRelated = relationsOfB.has(a);
3594
+ if (this.relations.cardinality === `1:n`) {
3595
+ const previousOwnersToDispose = [];
3596
+ for (const previousOwner of relationsOfB) {
3597
+ if (previousOwner === a) {
3598
+ continue;
3599
+ }
3600
+ const previousOwnerRelations = getRelatedKeys(
3601
+ toolkit,
3602
+ previousOwner
3603
+ );
3604
+ previousOwnerRelations.delete(newRelationB);
3605
+ if (previousOwnerRelations.size === 0) {
3606
+ previousOwnersToDispose.push(previousOwner);
3607
+ }
3608
+ }
3609
+ if (!newRelationBIsAlreadyRelated && relationsOfB.size > 0) {
3610
+ relationsOfB.clear();
3611
+ }
3612
+ for (const previousOwner of previousOwnersToDispose) {
3613
+ const sorted = [newRelationB, previousOwner].sort();
3614
+ const compositeKey = `"${sorted[0]}:${sorted[1]}"`;
3615
+ this.molecules.delete(compositeKey);
3616
+ }
3617
+ }
3618
+ if (!newRelationBIsAlreadyRelated) {
3619
+ relationsOfB.add(a);
3620
+ }
3621
+ nextRelationsOfA.add(newRelationB);
3622
+ }
3623
+ return true;
3624
+ });
3625
+ return relationsOfA;
3626
+ });
3627
+ };
3628
+ const replaceRelationsUnsafely = (toolkit, a, newRelationsOfA) => {
3629
+ const { set } = toolkit;
3630
+ set(relatedKeysAtoms, a, (relationsOfA) => {
3631
+ relationsOfA.transaction((nextRelationsOfA) => {
3632
+ for (const newRelationB of newRelationsOfA) {
3633
+ nextRelationsOfA.add(newRelationB);
3634
+ }
3635
+ return true;
3636
+ });
3637
+ return relationsOfA;
3638
+ });
3639
+ for (const newRelationB of newRelationsOfA) {
3640
+ set(relatedKeysAtoms, newRelationB, (newRelationsB) => {
3641
+ newRelationsB.add(a);
3642
+ return newRelationsB;
3643
+ });
3644
+ }
3645
+ return true;
3646
+ };
3647
+ const has = (toolkit, a, b) => {
3648
+ const aKeys = getRelatedKeys(toolkit, a);
3649
+ return b ? aKeys.has(b) : aKeys.size > 0;
3650
+ };
3651
+ const baseExternalStoreConfiguration = {
3652
+ getRelatedKeys: (key) => getRelatedKeys(this.toolkit, key),
3653
+ addRelation: (a, b) => {
3654
+ this.store.moleculeJoins.set(
3655
+ a,
3656
+ options.key
3657
+ );
3658
+ this.store.moleculeJoins.set(
3659
+ b,
3660
+ options.key
3661
+ );
3662
+ addRelation(this.toolkit, a, b);
3663
+ },
3664
+ deleteRelation: (a, b) => {
3665
+ deleteRelation(this.toolkit, a, b);
3666
+ },
3667
+ replaceRelationsSafely: (a, bs) => {
3668
+ replaceRelationsSafely(this.toolkit, a, bs);
3669
+ },
3670
+ replaceRelationsUnsafely: (a, bs) => {
3671
+ replaceRelationsUnsafely(this.toolkit, a, bs);
3672
+ },
3673
+ has: (a, b) => has(this.toolkit, a, b)
3674
+ };
3675
+ let externalStore;
3676
+ let contentAtoms;
3677
+ if (defaultContent) {
3678
+ contentAtoms = createRegularAtomFamily(
3679
+ store,
3680
+ {
3681
+ key: `${options.key}/content`,
3682
+ default: defaultContent
3683
+ },
3684
+ [`join`, `content`]
3685
+ );
3686
+ const getContent = ({ get }, key) => get(contentAtoms, key);
3687
+ const setContent = ({ set }, key, content) => {
3688
+ set(contentAtoms, key, content);
3689
+ };
3690
+ const externalStoreWithContentConfiguration = {
3691
+ getContent: (contentKey) => {
3692
+ const content = getContent(this.toolkit, contentKey);
3693
+ return content;
3694
+ },
3695
+ setContent: (contentKey, content) => {
3696
+ setContent(this.toolkit, contentKey, content);
3697
+ },
3698
+ deleteContent: (contentKey) => {
3699
+ this.realm.deallocate(contentKey);
3700
+ }
3701
+ };
3702
+ externalStore = Object.assign(
3703
+ baseExternalStoreConfiguration,
3704
+ externalStoreWithContentConfiguration
3705
+ );
3706
+ } else {
3707
+ externalStore = baseExternalStoreConfiguration;
3708
+ }
3709
+ const relations = new Junction(
3710
+ options,
3711
+ {
3712
+ externalStore,
3713
+ isAType: options.isAType,
3714
+ isBType: options.isBType,
3715
+ makeContentKey: (...args) => {
3716
+ const [a, b] = args;
3717
+ const sorted = args.sort();
3718
+ const compositeKey = `${sorted[0]}:${sorted[1]}`;
3719
+ const aMolecule = store.molecules.get(stringifyJson(a));
3720
+ const bMolecule = store.molecules.get(stringifyJson(b));
3721
+ if (!aMolecule) {
3722
+ this.realm.allocate(options.key, a);
3723
+ }
3724
+ if (!bMolecule) {
3725
+ this.realm.allocate(options.key, b);
3726
+ }
3727
+ this.realm.allocate(a, compositeKey, `all`);
3728
+ this.realm.claim(b, compositeKey);
3729
+ this.store.moleculeJoins.set(compositeKey, options.key);
3730
+ return compositeKey;
3731
+ }
3732
+ }
3733
+ );
3734
+ const createSingleKeySelectorFamily = () => createReadonlySelectorFamily(
3735
+ store,
3736
+ {
3737
+ key: `${options.key}/singleRelatedKey`,
3738
+ get: (key) => ({ get }) => {
3739
+ const relatedKeys = get(relatedKeysAtoms, key);
3740
+ for (const relatedKey of relatedKeys) {
3741
+ return relatedKey;
3742
+ }
3743
+ return null;
3744
+ }
3745
+ },
3746
+ [`join`, `keys`]
3747
+ );
3748
+ const getMultipleKeySelectorFamily = () => {
3749
+ return createReadonlySelectorFamily(
3750
+ store,
3751
+ {
3752
+ key: `${options.key}/multipleRelatedKeys`,
3753
+ get: (key) => ({ get }) => {
3754
+ const jsonFamily = getJsonFamily(relatedKeysAtoms, store);
3755
+ const json = get(jsonFamily, key);
3756
+ return json.members;
3757
+ }
3758
+ },
3759
+ [`join`, `keys`]
3760
+ );
3761
+ };
3762
+ const createSingleEntrySelectorFamily = () => createReadonlySelectorFamily(
3763
+ store,
3764
+ {
3765
+ key: `${options.key}/singleRelatedEntry`,
3766
+ get: (x) => ({ get }) => {
3767
+ const relatedKeys = get(relatedKeysAtoms, x);
3768
+ for (const y of relatedKeys) {
3769
+ let a = relations.isAType?.(x) ? x : undefined;
3770
+ let b = a === undefined ? x : undefined;
3771
+ a ??= y;
3772
+ b ??= y;
3773
+ const contentKey = relations.makeContentKey(a, b);
3774
+ const content = get(contentAtoms, contentKey);
3775
+ return [y, content];
3776
+ }
3777
+ return null;
3778
+ }
3779
+ },
3780
+ [`join`, `entries`]
3781
+ );
3782
+ const getMultipleEntrySelectorFamily = () => createReadonlySelectorFamily(
3783
+ store,
3784
+ {
3785
+ key: `${options.key}/multipleRelatedEntries`,
3786
+ get: (x) => ({ get }) => {
3787
+ const jsonFamily = getJsonFamily(relatedKeysAtoms, store);
3788
+ const json = get(jsonFamily, x);
3789
+ return json.members.map((y) => {
3790
+ let a = relations.isAType?.(x) ? x : undefined;
3791
+ let b = a === undefined ? x : undefined;
3792
+ a ??= y;
3793
+ b ??= y;
3794
+ const contentKey = relations.makeContentKey(a, b);
3795
+ const content = get(contentAtoms, contentKey);
3796
+ return [y, content];
3797
+ });
3798
+ }
3799
+ },
3800
+ [`join`, `entries`]
3801
+ );
3802
+ switch (options.cardinality) {
3803
+ case `1:1`: {
3804
+ const singleRelatedKeySelectors = createSingleKeySelectorFamily();
3805
+ const stateKeyA = `${aSide}KeyOf${capitalize(bSide)}`;
3806
+ const stateKeyB = `${bSide}KeyOf${capitalize(aSide)}`;
3807
+ const baseStates = {
3808
+ [stateKeyA]: singleRelatedKeySelectors,
3809
+ [stateKeyB]: singleRelatedKeySelectors
3810
+ };
3811
+ let states;
3812
+ if (defaultContent) {
3813
+ const singleEntrySelectors = createSingleEntrySelectorFamily();
3814
+ const entriesStateKeyA = `${aSide}EntryOf${capitalize(bSide)}`;
3815
+ const entriesStateKeyB = `${bSide}EntryOf${capitalize(aSide)}`;
3816
+ const contentStates = {
3817
+ [entriesStateKeyA]: singleEntrySelectors,
3818
+ [entriesStateKeyB]: singleEntrySelectors
3819
+ };
3820
+ states = Object.assign(baseStates, contentStates);
3821
+ } else {
3822
+ states = baseStates;
3823
+ }
3824
+ this.relations = relations;
3825
+ this.states = states;
3826
+ break;
3827
+ }
3828
+ case `1:n`: {
3829
+ const singleRelatedKeySelectors = createSingleKeySelectorFamily();
3830
+ const multipleRelatedKeysSelectors = getMultipleKeySelectorFamily();
3831
+ const stateKeyA = `${aSide}KeyOf${capitalize(bSide)}`;
3832
+ const stateKeyB = `${bSide}KeysOf${capitalize(aSide)}`;
3833
+ const baseStates = {
3834
+ [stateKeyA]: singleRelatedKeySelectors,
3835
+ [stateKeyB]: multipleRelatedKeysSelectors
3836
+ };
3837
+ let states;
3838
+ if (defaultContent) {
3839
+ const singleRelatedEntrySelectors = createSingleEntrySelectorFamily();
3840
+ const multipleRelatedEntriesSelectors = getMultipleEntrySelectorFamily();
3841
+ const entriesStateKeyA = `${aSide}EntryOf${capitalize(bSide)}`;
3842
+ const entriesStateKeyB = `${bSide}EntriesOf${capitalize(
3843
+ aSide
3844
+ )}`;
3845
+ const contentStates = {
3846
+ [entriesStateKeyA]: singleRelatedEntrySelectors,
3847
+ [entriesStateKeyB]: multipleRelatedEntriesSelectors
3848
+ };
3849
+ states = Object.assign(baseStates, contentStates);
3850
+ } else {
3851
+ states = baseStates;
3852
+ }
3853
+ this.relations = relations;
3854
+ this.states = states;
3855
+ break;
3856
+ }
3857
+ default: {
3858
+ const multipleRelatedKeysSelectors = getMultipleKeySelectorFamily();
3859
+ const stateKeyA = `${aSide}KeysOf${capitalize(bSide)}`;
3860
+ const stateKeyB = `${bSide}KeysOf${capitalize(aSide)}`;
3861
+ const baseStates = {
3862
+ [stateKeyA]: multipleRelatedKeysSelectors,
3863
+ [stateKeyB]: multipleRelatedKeysSelectors
3864
+ };
3865
+ let states;
3866
+ if (defaultContent) {
3867
+ const multipleRelatedEntriesSelectors = getMultipleEntrySelectorFamily();
3868
+ const entriesStateKeyA = `${aSide}EntriesOf${capitalize(
3869
+ bSide
3870
+ )}`;
3871
+ const entriesStateKeyB = `${bSide}EntriesOf${capitalize(
3872
+ aSide
3873
+ )}`;
3874
+ const contentStates = {
3875
+ [entriesStateKeyA]: multipleRelatedEntriesSelectors,
3876
+ [entriesStateKeyB]: multipleRelatedEntriesSelectors
3877
+ };
3878
+ states = Object.assign(baseStates, contentStates);
3879
+ } else {
3880
+ states = baseStates;
3881
+ }
3882
+ this.relations = relations;
3883
+ this.states = states;
3884
+ }
3885
+ }
3886
+ }
3887
+ };
3888
+
3889
+ // internal/src/join/get-join.ts
3890
+ function getJoin(token, store) {
3891
+ let myJoin = store.joins.get(token.key);
3892
+ if (myJoin === undefined) {
3893
+ const rootJoinMap = IMPLICIT.STORE.joins;
3894
+ const rootJoin = rootJoinMap.get(token.key);
3895
+ if (rootJoin === undefined) {
3896
+ throw new Error(
3897
+ `Join "${token.key}" not found in store "${store.config.name}"`
3898
+ );
3899
+ }
3900
+ myJoin = new Join(rootJoin.options, rootJoin.defaultContent, store);
3901
+ store.joins.set(token.key, myJoin);
3902
+ }
3903
+ return myJoin;
3904
+ }
3905
+
3906
+ // internal/src/join/edit-relations-in-store.ts
3907
+ function editRelationsInStore(token, change, store) {
3908
+ const myJoin = getJoin(token, store);
3909
+ const target = newest(store);
3910
+ if (isChildStore(target)) {
3911
+ const { toolkit } = target.transactionMeta;
3912
+ myJoin.transact(toolkit, ({ relations }) => {
3913
+ change(relations);
3914
+ });
3915
+ } else {
3916
+ change(myJoin.relations);
3917
+ }
3918
+ }
3919
+
3920
+ // internal/src/join/find-relations-in-store.ts
3921
+ function findRelationsInStore(token, key, store) {
3922
+ const myJoin = getJoin(token, store);
3923
+ let relations;
3924
+ switch (token.cardinality) {
3925
+ case `1:1`: {
3926
+ const keyAB = `${token.a}KeyOf${capitalize(token.b)}`;
3927
+ const keyBA = `${token.b}KeyOf${capitalize(token.a)}`;
3928
+ relations = {
3929
+ get [keyAB]() {
3930
+ const familyAB = myJoin.states[keyAB];
3931
+ const state = findInStore(store, familyAB, key);
3932
+ return state;
3933
+ },
3934
+ get [keyBA]() {
3935
+ const familyBA = myJoin.states[keyBA];
3936
+ const state = findInStore(store, familyBA, key);
3937
+ return state;
3938
+ }
3939
+ };
3940
+ const entryAB = `${token.a}EntryOf${capitalize(token.b)}`;
3941
+ if (entryAB in myJoin.states) {
3942
+ const entryBA = `${token.b}EntryOf${capitalize(token.a)}`;
3943
+ Object.assign(relations, {
3944
+ get [entryAB]() {
3945
+ const familyAB = myJoin.states[entryAB];
3946
+ const state = findInStore(store, familyAB, key);
3947
+ return state;
3948
+ },
3949
+ get [entryBA]() {
3950
+ const familyBA = myJoin.states[entryBA];
3951
+ const state = findInStore(store, familyBA, key);
3952
+ return state;
3953
+ }
3954
+ });
3955
+ }
3956
+ break;
3957
+ }
3958
+ case `1:n`: {
3959
+ const keyAB = `${token.a}KeyOf${capitalize(token.b)}`;
3960
+ const keysBA = `${token.b}KeysOf${capitalize(token.a)}`;
3961
+ relations = {
3962
+ get [keyAB]() {
3963
+ const familyAB = myJoin.states[keyAB];
3964
+ const state = findInStore(store, familyAB, key);
3965
+ return state;
3966
+ },
3967
+ get [keysBA]() {
3968
+ const familyBA = myJoin.states[keysBA];
3969
+ const state = findInStore(store, familyBA, key);
3970
+ return state;
3971
+ }
3972
+ };
3973
+ const entryAB = `${token.a}EntryOf${capitalize(token.b)}`;
3974
+ if (entryAB in myJoin.states) {
3975
+ const entriesBA = `${token.b}EntriesOf${capitalize(token.a)}`;
3976
+ Object.assign(relations, {
3977
+ get [entryAB]() {
3978
+ const familyAB = myJoin.states[entryAB];
3979
+ const state = findInStore(store, familyAB, key);
3980
+ return state;
3981
+ },
3982
+ get [entriesBA]() {
3983
+ const familyBA = myJoin.states[entriesBA];
3984
+ const state = findInStore(store, familyBA, key);
3985
+ return state;
3986
+ }
3987
+ });
3988
+ }
3989
+ break;
3990
+ }
3991
+ case `n:n`: {
3992
+ const keysAB = `${token.a}KeysOf${capitalize(token.b)}`;
3993
+ const keysBA = `${token.b}KeysOf${capitalize(token.a)}`;
3994
+ relations = {
3995
+ get [keysAB]() {
3996
+ const familyAB = myJoin.states[keysAB];
3997
+ const state = findInStore(store, familyAB, key);
3998
+ return state;
3999
+ },
4000
+ get [keysBA]() {
4001
+ const familyBA = myJoin.states[keysBA];
4002
+ const state = findInStore(store, familyBA, key);
4003
+ return state;
4004
+ }
4005
+ };
4006
+ const entriesAB = `${token.a}EntriesOf${capitalize(token.b)}`;
4007
+ if (entriesAB in myJoin.states) {
4008
+ const entriesBA = `${token.b}EntriesOf${capitalize(token.a)}`;
4009
+ Object.assign(relations, {
4010
+ get [entriesAB]() {
4011
+ const familyAB = myJoin.states[entriesAB];
4012
+ const state = findInStore(store, familyAB, key);
4013
+ return state;
4014
+ },
4015
+ get [entriesBA]() {
4016
+ const familyBA = myJoin.states[entriesBA];
4017
+ const state = findInStore(store, familyBA, key);
4018
+ return state;
4019
+ }
4020
+ });
4021
+ }
4022
+ }
4023
+ }
4024
+ return relations;
4025
+ }
4026
+
4027
+ // internal/src/join/get-internal-relations-from-store.ts
4028
+ function getInternalRelationsFromStore(token, store) {
4029
+ const myJoin = getJoin(token, store);
4030
+ const family = myJoin.core.relatedKeysAtoms;
4031
+ return family;
2799
4032
  }
2800
4033
 
2801
4034
  // internal/src/timeline/create-timeline.ts
2802
- function createTimeline(options, store, data) {
4035
+ function createTimeline(store, options, data) {
2803
4036
  const tl = {
2804
4037
  type: `timeline`,
2805
4038
  key: options.key,
@@ -2809,7 +4042,7 @@ function createTimeline(options, store, data) {
2809
4042
  transactionKey: null,
2810
4043
  ...data,
2811
4044
  history: data?.history.map((update) => ({ ...update })) ?? [],
2812
- install: (s) => createTimeline(options, s, tl),
4045
+ install: (s) => createTimeline(s, options, tl),
2813
4046
  subject: new Subject(),
2814
4047
  subscriptions: /* @__PURE__ */ new Map()
2815
4048
  };
@@ -2848,7 +4081,7 @@ function createTimeline(options, store, data) {
2848
4081
  );
2849
4082
  continue;
2850
4083
  }
2851
- addAtomToTimeline(atomToken, tl, store);
4084
+ addAtomToTimeline(store, atomToken, tl);
2852
4085
  }
2853
4086
  break;
2854
4087
  case `atom_family`:
@@ -2866,7 +4099,7 @@ function createTimeline(options, store, data) {
2866
4099
  );
2867
4100
  continue;
2868
4101
  }
2869
- addAtomFamilyToTimeline(familyToken, tl, store);
4102
+ addAtomFamilyToTimeline(store, familyToken, tl);
2870
4103
  }
2871
4104
  break;
2872
4105
  }
@@ -2879,20 +4112,20 @@ function createTimeline(options, store, data) {
2879
4112
  store.on.timelineCreation.next(token);
2880
4113
  return token;
2881
4114
  }
2882
- function addAtomToTimeline(atomToken, tl, store) {
2883
- let maybeAtom = withdraw(atomToken, store);
4115
+ function addAtomToTimeline(store, atomToken, tl) {
4116
+ let maybeAtom = withdraw(store, atomToken);
2884
4117
  if (maybeAtom.type === `mutable_atom`) {
2885
4118
  const updateToken = getUpdateToken(maybeAtom);
2886
- maybeAtom = withdraw(updateToken, store);
4119
+ maybeAtom = withdraw(store, updateToken);
2887
4120
  }
2888
- const atom = maybeAtom;
4121
+ const atom2 = maybeAtom;
2889
4122
  store.timelineTopics.set(
2890
- { topicKey: atom.key, timelineKey: tl.key },
4123
+ { topicKey: atom2.key, timelineKey: tl.key },
2891
4124
  { topicType: `atom` }
2892
4125
  );
2893
4126
  tl.subscriptions.set(
2894
- atom.key,
2895
- atom.subject.subscribe(
4127
+ atom2.key,
4128
+ atom2.subject.subscribe(
2896
4129
  `timeline`,
2897
4130
  function timelineCapturesAtomUpdate(update) {
2898
4131
  const target = newest(store);
@@ -2913,7 +4146,7 @@ function addAtomToTimeline(atomToken, tl, store) {
2913
4146
  );
2914
4147
  if (tl.timeTraveling === null) {
2915
4148
  if (txUpdateInProgress) {
2916
- joinTransaction(tl, txUpdateInProgress, store);
4149
+ joinTransaction(store, tl, txUpdateInProgress);
2917
4150
  } else if (currentSelectorKey && currentSelectorTime) {
2918
4151
  let latestUpdate = tl.history.at(-1);
2919
4152
  if (currentSelectorTime !== tl.selectorTime) {
@@ -2924,7 +4157,7 @@ function addAtomToTimeline(atomToken, tl, store) {
2924
4157
  atomUpdates: []
2925
4158
  };
2926
4159
  latestUpdate.atomUpdates.push({
2927
- key: atom.key,
4160
+ key: atom2.key,
2928
4161
  type: `atom_update`,
2929
4162
  ...update
2930
4163
  });
@@ -2944,7 +4177,7 @@ function addAtomToTimeline(atomToken, tl, store) {
2944
4177
  } else {
2945
4178
  if (latestUpdate?.type === `selector_update`) {
2946
4179
  latestUpdate.atomUpdates.push({
2947
- key: atom.key,
4180
+ key: atom2.key,
2948
4181
  type: `atom_update`,
2949
4182
  ...update
2950
4183
  });
@@ -2975,19 +4208,19 @@ function addAtomToTimeline(atomToken, tl, store) {
2975
4208
  const atomUpdate = {
2976
4209
  type: `atom_update`,
2977
4210
  timestamp,
2978
- key: atom.key,
4211
+ key: atom2.key,
2979
4212
  oldValue: update.oldValue,
2980
4213
  newValue: update.newValue
2981
4214
  };
2982
- if (atom.family) {
2983
- atomUpdate.family = atom.family;
4215
+ if (atom2.family) {
4216
+ atomUpdate.family = atom2.family;
2984
4217
  }
2985
4218
  const willCapture = tl.shouldCapture?.(atomUpdate, tl) ?? true;
2986
4219
  store.logger.info(
2987
4220
  `\u231B`,
2988
4221
  `timeline`,
2989
4222
  tl.key,
2990
- `got an atom_update to "${atom.key}"`
4223
+ `got an atom_update to "${atom2.key}"`
2991
4224
  );
2992
4225
  if (willCapture) {
2993
4226
  tl.history.push(atomUpdate);
@@ -3000,8 +4233,8 @@ function addAtomToTimeline(atomToken, tl, store) {
3000
4233
  )
3001
4234
  );
3002
4235
  }
3003
- function addAtomFamilyToTimeline(atomFamilyToken, tl, store) {
3004
- const family = withdraw(atomFamilyToken, store);
4236
+ function addAtomFamilyToTimeline(store, atomFamilyToken, tl) {
4237
+ const family = withdraw(store, atomFamilyToken);
3005
4238
  store.timelineTopics.set(
3006
4239
  { topicKey: family.key, timelineKey: tl.key },
3007
4240
  { topicType: `atom_family` }
@@ -3011,24 +4244,24 @@ function addAtomFamilyToTimeline(atomFamilyToken, tl, store) {
3011
4244
  family.subject.subscribe(
3012
4245
  `timeline`,
3013
4246
  function timelineCapturesStateLifecycleEvent(creationOrDisposal) {
3014
- handleStateLifecycleEvent(creationOrDisposal, tl, store);
4247
+ handleStateLifecycleEvent(store, creationOrDisposal, tl);
3015
4248
  }
3016
4249
  )
3017
4250
  );
3018
- for (const atom of store.atoms.values()) {
3019
- if (atom.family?.key === family.key) {
3020
- addAtomToTimeline(atom, tl, store);
4251
+ for (const atom2 of store.atoms.values()) {
4252
+ if (atom2.family?.key === family.key) {
4253
+ addAtomToTimeline(store, atom2, tl);
3021
4254
  }
3022
4255
  }
3023
4256
  }
3024
- function joinTransaction(tl, txUpdateInProgress, store) {
4257
+ function joinTransaction(store, tl, txUpdateInProgress) {
3025
4258
  const currentTxKey = txUpdateInProgress.key;
3026
4259
  const currentTxInstanceId = txUpdateInProgress.id;
3027
4260
  const currentTxToken = {
3028
4261
  key: currentTxKey,
3029
4262
  type: `transaction`
3030
4263
  };
3031
- const currentTransaction = withdraw(currentTxToken, store);
4264
+ const currentTransaction = withdraw(store, currentTxToken);
3032
4265
  if (currentTxKey && tl.transactionKey === null) {
3033
4266
  tl.transactionKey = currentTxKey;
3034
4267
  const unsubscribe = currentTransaction.subject.subscribe(
@@ -3102,7 +4335,7 @@ function filterTransactionUpdates(updates, timelineTopics) {
3102
4335
  return updateFromTx;
3103
4336
  });
3104
4337
  }
3105
- function handleStateLifecycleEvent(event, tl, store) {
4338
+ function handleStateLifecycleEvent(store, event, tl) {
3106
4339
  const timestamp = Date.now();
3107
4340
  const timelineEvent = Object.assign(event, {
3108
4341
  timestamp
@@ -3112,7 +4345,7 @@ function handleStateLifecycleEvent(event, tl, store) {
3112
4345
  if (isChildStore(target)) ; else {
3113
4346
  const txUpdateInProgress = target.on.transactionApplying.state;
3114
4347
  if (txUpdateInProgress) {
3115
- joinTransaction(tl, txUpdateInProgress.update, store);
4348
+ joinTransaction(store, tl, txUpdateInProgress.update);
3116
4349
  } else {
3117
4350
  tl.history.push(timelineEvent);
3118
4351
  tl.at = tl.history.length;
@@ -3122,7 +4355,7 @@ function handleStateLifecycleEvent(event, tl, store) {
3122
4355
  }
3123
4356
  switch (event.type) {
3124
4357
  case `state_creation`:
3125
- addAtomToTimeline(event.token, tl, store);
4358
+ addAtomToTimeline(store, event.token, tl);
3126
4359
  break;
3127
4360
  case `state_disposal`:
3128
4361
  tl.subscriptions.get(event.token.key)?.();
@@ -3199,4 +4432,67 @@ var timeTravel = (store, action, token) => {
3199
4432
  );
3200
4433
  };
3201
4434
 
3202
- export { CircularBuffer, FAMILY_MEMBER_TOKEN_TYPES, FamilyTracker, Future, IMPLICIT, Junction, LazyMap, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, applyTransaction, arbitrary, assignTransactionToContinuity, become, buildTransaction, cacheValue, clearStore, closeOperation, counterfeit, createAtomFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelector, createReadonlySelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneAtom, createStandaloneSelector, createTimeline, createTransaction, createWritableSelector, createWritableSelectorFamily, deposit, disposeAtom, disposeFromStore, disposeSelector, evictCachedValue, findInStore, getContinuityKey, getEnvironmentData, getEpochNumberOfAction, getEpochNumberOfContinuity, getFromStore, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getTrace, getUpdateFamily, getUpdateToken, ingestAtomUpdate, ingestCreationEvent, ingestDisposalEvent, ingestMoleculeCreationEvent, ingestMoleculeDisposalEvent, ingestMoleculeTransferEvent, ingestSelectorUpdate, ingestTransactionUpdate, initFamilyMemberInStore, isAtomDefault, isAtomKey, isChildStore, isDone, isReadonlySelectorKey, isRootStore, isSelectorKey, isStateKey, isTransceiver, markAtomAsDefault, markAtomAsNotDefault, markDone, newest, openOperation, prettyPrintTokenType, readCachedValue, readOrComputeValue, recallState, registerSelector, seekInStore, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeInStore, subscribeToRootAtoms, subscribeToState2 as subscribeToState, subscribeToTimeline2 as subscribeToTimeline, subscribeToTransaction2 as subscribeToTransaction, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, updateSelectorAtoms, withdraw };
4435
+ // json/src/select-json.ts
4436
+ var selectJson = (atom2, transform, store = IMPLICIT.STORE) => {
4437
+ return createStandaloneSelector(store, {
4438
+ key: `${atom2.key}:JSON`,
4439
+ get: ({ get }) => transform.toJson(get(atom2)),
4440
+ set: ({ set }, newValue) => {
4441
+ set(atom2, transform.fromJson(newValue));
4442
+ }
4443
+ });
4444
+ };
4445
+
4446
+ // json/src/select-json-family.ts
4447
+ function selectJsonFamily(store, atomFamilyToken, transform) {
4448
+ const jsonFamily = createWritableSelectorFamily(
4449
+ store,
4450
+ {
4451
+ key: `${atomFamilyToken.key}:JSON`,
4452
+ get: (key) => ({ get }) => {
4453
+ const baseState = get(atomFamilyToken, key);
4454
+ return transform.toJson(baseState);
4455
+ },
4456
+ set: (key) => ({ set }, newValue) => {
4457
+ set(atomFamilyToken, key, transform.fromJson(newValue));
4458
+ }
4459
+ },
4460
+ [`mutable`, `json`]
4461
+ );
4462
+ return jsonFamily;
4463
+ }
4464
+
4465
+ // json/src/index.ts
4466
+ var parseJson = (str) => JSON.parse(str);
4467
+ var stringifyJson = (json) => JSON.stringify(json);
4468
+ var JSON_PROTOTYPES = [
4469
+ Array.prototype,
4470
+ Boolean.prototype,
4471
+ Number.prototype,
4472
+ Object.prototype,
4473
+ String.prototype
4474
+ ];
4475
+ var isJson = (input) => {
4476
+ if (input === null) return true;
4477
+ if (input === undefined) return false;
4478
+ const prototype = Object.getPrototypeOf(input);
4479
+ return JSON_PROTOTYPES.includes(prototype);
4480
+ };
4481
+ var JSON_TYPE_NAMES = [
4482
+ `array`,
4483
+ `boolean`,
4484
+ `null`,
4485
+ `number`,
4486
+ `object`,
4487
+ `string`
4488
+ ];
4489
+ var JSON_DEFAULTS = {
4490
+ array: [],
4491
+ boolean: false,
4492
+ null: null,
4493
+ number: 0,
4494
+ object: {},
4495
+ string: ``
4496
+ };
4497
+
4498
+ export { $claim, Anarchy, AtomIOLogger, CircularBuffer, FAMILY_MEMBER_TOKEN_TYPES, FamilyTracker, Future, IMPLICIT, JSON_DEFAULTS, JSON_TYPE_NAMES, Join, Junction, LOG_LEVELS, LazyMap, NotFoundError, Realm, SetRTX, Silo, StatefulSubject, Store, Subject, T$, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, allocateIntoStore, applyTransaction, arbitrary, assignTransactionToContinuity, atom, atomFamily, become, belongsTo, buildTransaction, cacheValue, capitalize, claimWithinStore, clearStore, closeOperation, counterfeit, createAtomFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelector, createReadonlySelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneAtom, createStandaloneSelector, createTimeline, createTransaction, createWritableSelector, deallocateFromStore, deposit, disposeAtom, disposeFromStore, disposeSelector, disposeState, editRelations, editRelationsInStore, evictCachedValue, findInStore, findRelations, findRelationsInStore, findState, fromEntries, fuseWithinStore, getContinuityKey, getEnvironmentData, getEpochNumberOfAction, getEpochNumberOfContinuity, getFromStore, getInternalRelations, getInternalRelationsFromStore, getJoin, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getState, getTrace, getUpdateFamily, getUpdateToken, ingestAtomUpdate, ingestCreationEvent, ingestDisposalEvent, ingestMoleculeCreationEvent, ingestMoleculeDisposalEvent, ingestMoleculeTransferEvent, ingestSelectorUpdate, ingestTransactionUpdate, initFamilyMemberInStore, isAtomDefault, isAtomKey, isChildStore, isDone, isJson, isReadonlySelectorKey, isRootStore, isSelectorKey, isStateKey, isToken, isTransceiver, join, makeRootMoleculeInStore, markAtomAsDefault, markAtomAsNotDefault, markDone, newest, openOperation, parseJson, prettyPrintTokenType, readCachedValue, readOrComputeValue, recallState, redo, registerSelector, runTransaction, seekInStore, selectJson, selectJsonFamily, selector, selectorFamily, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, setState, simpleLog, simpleLogger, stringifyJson, subscribe, subscribeInStore, subscribeToRootAtoms, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, timeline, toEntries, traceAllSelectorAtoms, traceSelectorAtoms, transaction, undo, updateSelectorAtoms, withdraw };