atom.io 0.24.5 → 0.24.6

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.
@@ -112,187 +112,69 @@ function isChildStore(store) {
112
112
  return `phase` in store.transactionMeta;
113
113
  }
114
114
 
115
- // internal/src/store/store.ts
116
- var Store = class {
117
- constructor(config, store = null) {
118
- this.parent = null;
119
- this.child = null;
120
- this.valueMap = /* @__PURE__ */ new Map();
121
- this.atoms = /* @__PURE__ */ new Map();
122
- this.selectors = /* @__PURE__ */ new Map();
123
- this.readonlySelectors = /* @__PURE__ */ new Map();
124
- this.trackers = /* @__PURE__ */ new Map();
125
- this.families = /* @__PURE__ */ new Map();
126
- this.timelines = /* @__PURE__ */ new Map();
127
- this.transactions = /* @__PURE__ */ new Map();
128
- this.atomsThatAreDefault = /* @__PURE__ */ new Set();
129
- this.timelineAtoms = new Junction({
130
- between: [`timelineKey`, `atomKey`],
131
- cardinality: `1:n`
132
- });
133
- this.selectorAtoms = new Junction({
134
- between: [`selectorKey`, `atomKey`],
135
- cardinality: `n:n`
136
- });
137
- this.selectorGraph = new Junction(
138
- {
139
- between: [`upstreamSelectorKey`, `downstreamSelectorKey`],
140
- cardinality: `n:n`
141
- },
142
- {
143
- makeContentKey: (...keys) => keys.sort().join(`:`)
144
- }
115
+ // internal/src/transaction/abort-transaction.ts
116
+ var abortTransaction = (store) => {
117
+ const target = newest(store);
118
+ if (!isChildStore(target)) {
119
+ store.logger.warn(
120
+ `\u{1F41E}`,
121
+ `transaction`,
122
+ `???`,
123
+ `abortTransaction called outside of a transaction. This is probably a bug in AtomIO.`
145
124
  );
146
- this.molecules = /* @__PURE__ */ new Map();
147
- this.moleculeFamilies = /* @__PURE__ */ new Map();
148
- this.miscResources = /* @__PURE__ */ new Map();
149
- this.on = {
150
- atomCreation: new Subject(),
151
- atomDisposal: new Subject(),
152
- selectorCreation: new Subject(),
153
- selectorDisposal: new Subject(),
154
- timelineCreation: new Subject(),
155
- transactionCreation: new Subject(),
156
- transactionApplying: new StatefulSubject(
157
- null
158
- ),
159
- operationClose: new Subject(),
160
- moleculeCreationStart: new Subject(),
161
- moleculeCreationDone: new Subject(),
162
- moleculeDisposal: new Subject()
163
- };
164
- this.operation = { open: false };
165
- this.transactionMeta = {
166
- epoch: /* @__PURE__ */ new Map(),
167
- actionContinuities: new Junction({
168
- between: [`continuity`, `action`],
169
- cardinality: `1:n`
170
- })
171
- };
172
- this.config = {
173
- name: `IMPLICIT_STORE`,
174
- lifespan: `ephemeral`
175
- };
176
- this.loggers = [
177
- new AtomIOLogger(`warn`, (_, __, key) => !key.includes(`\u{1F441}\u200D\u{1F5E8}`))
178
- ];
179
- this.logger = {
180
- error: (...messages) => {
181
- for (const logger of this.loggers) logger.error(...messages);
182
- },
183
- info: (...messages) => {
184
- for (const logger of this.loggers) logger.info(...messages);
185
- },
186
- warn: (...messages) => {
187
- for (const logger of this.loggers) logger.warn(...messages);
188
- }
189
- };
190
- if (store !== null) {
191
- this.valueMap = new Map(store == null ? void 0 : store.valueMap);
192
- this.operation = __spreadValues({}, store == null ? void 0 : store.operation);
193
- if (isRootStore(store)) {
194
- this.transactionMeta = {
195
- epoch: new Map(store == null ? void 0 : store.transactionMeta.epoch),
196
- actionContinuities: new Junction(
197
- store == null ? void 0 : store.transactionMeta.actionContinuities.toJSON()
198
- )
199
- };
200
- }
201
- this.config = __spreadValues(__spreadValues({}, store == null ? void 0 : store.config), config);
202
- for (const [, family] of store.families) {
203
- family.install(this);
204
- }
205
- const mutableHelpers = /* @__PURE__ */ new Set();
206
- for (const [, atom] of store.atoms) {
207
- if (mutableHelpers.has(atom.key)) {
208
- continue;
209
- }
210
- atom.install(this);
211
- if (atom.type === `mutable_atom`) {
212
- const originalJsonToken = getJsonToken(atom, store);
213
- const originalUpdateToken = getUpdateToken(atom);
214
- mutableHelpers.add(originalJsonToken.key);
215
- mutableHelpers.add(originalUpdateToken.key);
216
- }
217
- }
218
- for (const [, selector] of store.readonlySelectors) {
219
- selector.install(this);
220
- }
221
- for (const [, selector] of store.selectors) {
222
- if (mutableHelpers.has(selector.key)) {
223
- continue;
224
- }
225
- selector.install(this);
226
- }
227
- for (const [, tx] of store.transactions) {
228
- tx.install(this);
229
- }
230
- for (const [, timeline] of store.timelines) {
231
- timeline.install(this);
232
- }
233
- }
125
+ return;
234
126
  }
127
+ store.logger.info(
128
+ `\u{1FA82}`,
129
+ `transaction`,
130
+ target.transactionMeta.update.key,
131
+ `Aborting transaction`
132
+ );
133
+ target.parent.child = null;
235
134
  };
236
- var IMPLICIT = {
237
- STORE_INTERNAL: void 0,
238
- get STORE() {
239
- var _a;
240
- return (_a = this.STORE_INTERNAL) != null ? _a : this.STORE_INTERNAL = new Store({
241
- name: `IMPLICIT_STORE`,
242
- lifespan: `ephemeral`
243
- });
135
+
136
+ // internal/src/not-found-error.ts
137
+ var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
138
+ function prettyPrintTokenType(token) {
139
+ switch (token.type) {
140
+ case `atom_family`:
141
+ return `Atom Family`;
142
+ case `molecule_family`:
143
+ return `Molecule Family`;
144
+ case `readonly_selector`:
145
+ return `Readonly Selector`;
146
+ case `readonly_selector_family`:
147
+ return `Readonly Selector Family`;
148
+ case `selector_family`:
149
+ return `Selector Family`;
150
+ default:
151
+ return capitalize(token.type);
244
152
  }
245
- };
246
- var clearStore = (store) => {
247
- const { config } = store;
248
- for (const disposable of store.miscResources.values()) {
249
- disposable[Symbol.dispose]();
153
+ }
154
+ var NotFoundError = class extends Error {
155
+ constructor(token, store) {
156
+ super(
157
+ `${prettyPrintTokenType(token)} "${token.key}" not found in store "${store.config.name}".`
158
+ );
250
159
  }
251
- Object.assign(store, new Store(config));
252
- store.config = config;
253
160
  };
254
- function withdraw(token, store) {
255
- let withdrawn;
256
- let target = store;
257
- while (target !== null) {
258
- switch (token.type) {
259
- case `atom`:
260
- case `mutable_atom`:
261
- withdrawn = target.atoms.get(token.key);
262
- break;
263
- case `selector`:
264
- withdrawn = target.selectors.get(token.key);
265
- break;
266
- case `readonly_selector`:
267
- withdrawn = target.readonlySelectors.get(token.key);
268
- break;
269
- case `atom_family`:
270
- case `mutable_atom_family`:
271
- case `selector_family`:
272
- case `readonly_selector_family`:
273
- withdrawn = target.families.get(token.key);
274
- break;
275
- case `timeline`:
276
- withdrawn = target.timelines.get(token.key);
277
- break;
278
- case `transaction`:
279
- withdrawn = target.transactions.get(token.key);
280
- break;
281
- case `molecule`:
282
- withdrawn = target.molecules.get(stringifyJson(token.key));
283
- break;
284
- case `molecule_family`:
285
- withdrawn = target.moleculeFamilies.get(token.key);
286
- break;
287
- }
288
- if (withdrawn) {
289
- return withdrawn;
161
+
162
+ // internal/src/transaction/act-upon-store.ts
163
+ function actUponStore(token, id, store) {
164
+ return (...parameters) => {
165
+ const tx = withdraw(token, store);
166
+ if (tx) {
167
+ return tx.run(parameters, id);
290
168
  }
291
- target = target.child;
292
- }
293
- throw new NotFoundError(token, store);
169
+ throw new NotFoundError(token, store);
170
+ };
294
171
  }
295
172
 
173
+ // internal/src/set-state/become.ts
174
+ var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(
175
+ originalThing instanceof Function ? originalThing() : originalThing
176
+ ) : nextVersionOfThing;
177
+
296
178
  // internal/src/get-state/read-or-compute-value.ts
297
179
  var readOrComputeValue = (state, target) => {
298
180
  if (target.valueMap.has(state.key)) {
@@ -313,176 +195,6 @@ var readOrComputeValue = (state, target) => {
313
195
  );
314
196
  return state.default instanceof Function ? state.default() : state.default;
315
197
  };
316
- function createRegularAtomFamily(options, store) {
317
- const subject = new Subject();
318
- const atomFamily = Object.assign(
319
- (key) => {
320
- const subKey = stringifyJson(key);
321
- const family = { key: options.key, subKey };
322
- const fullKey = `${options.key}(${subKey})`;
323
- const target = newest(store);
324
- const def = options.default;
325
- const individualOptions = {
326
- key: fullKey,
327
- default: def instanceof Function ? def(key) : def
328
- };
329
- if (options.effects) {
330
- individualOptions.effects = options.effects(key);
331
- }
332
- const token = createRegularAtom(individualOptions, family, target);
333
- subject.next({ type: `state_creation`, token });
334
- return token;
335
- },
336
- {
337
- key: options.key,
338
- type: `atom_family`,
339
- subject,
340
- install: (s) => createRegularAtomFamily(options, s)
341
- }
342
- );
343
- store.families.set(options.key, atomFamily);
344
- return atomFamily;
345
- }
346
-
347
- // internal/src/families/create-atom-family.ts
348
- function createAtomFamily(options, store) {
349
- const isMutable2 = `mutable` in options;
350
- if (isMutable2) {
351
- return createMutableAtomFamily(options, store);
352
- }
353
- return createRegularAtomFamily(options, store);
354
- }
355
- function createReadonlySelectorFamily(options, store) {
356
- const subject = new Subject();
357
- const readonlySelectorFamily = Object.assign(
358
- (key) => {
359
- const subKey = stringifyJson(key);
360
- const family = { key: options.key, subKey };
361
- const fullKey = `${options.key}(${subKey})`;
362
- const target = newest(store);
363
- const token = createReadonlySelector(
364
- {
365
- key: fullKey,
366
- get: options.get(key)
367
- },
368
- family,
369
- target
370
- );
371
- subject.next({ type: `state_creation`, token });
372
- return token;
373
- },
374
- {
375
- key: options.key,
376
- type: `readonly_selector_family`,
377
- subject,
378
- install: (s) => createReadonlySelectorFamily(options, s)
379
- }
380
- );
381
- store.families.set(options.key, readonlySelectorFamily);
382
- return readonlySelectorFamily;
383
- }
384
- function createWritableSelectorFamily(options, store) {
385
- const subject = new Subject();
386
- const selectorFamily = Object.assign(
387
- (key) => {
388
- const subKey = stringifyJson(key);
389
- const family = { key: options.key, subKey };
390
- const fullKey = `${options.key}(${subKey})`;
391
- const target = newest(store);
392
- const token = createWritableSelector(
393
- {
394
- key: fullKey,
395
- get: options.get(key),
396
- set: options.set(key)
397
- },
398
- family,
399
- target
400
- );
401
- subject.next({ type: `state_creation`, token });
402
- return token;
403
- },
404
- {
405
- key: options.key,
406
- type: `selector_family`,
407
- subject,
408
- install: (s) => createWritableSelectorFamily(options, s)
409
- }
410
- );
411
- store.families.set(options.key, selectorFamily);
412
- return selectorFamily;
413
- }
414
-
415
- // internal/src/families/create-selector-family.ts
416
- function createSelectorFamily(options, store) {
417
- const isWritable = `set` in options;
418
- if (isWritable) {
419
- return createWritableSelectorFamily(options, store);
420
- }
421
- return createReadonlySelectorFamily(options, store);
422
- }
423
-
424
- // internal/src/transaction/abort-transaction.ts
425
- var abortTransaction = (store) => {
426
- const target = newest(store);
427
- if (!isChildStore(target)) {
428
- store.logger.warn(
429
- `\u{1F41E}`,
430
- `transaction`,
431
- `???`,
432
- `abortTransaction called outside of a transaction. This is probably a bug in AtomIO.`
433
- );
434
- return;
435
- }
436
- store.logger.info(
437
- `\u{1FA82}`,
438
- `transaction`,
439
- target.transactionMeta.update.key,
440
- `Aborting transaction`
441
- );
442
- target.parent.child = null;
443
- };
444
-
445
- // internal/src/not-found-error.ts
446
- var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
447
- function prettyPrintTokenType(token) {
448
- switch (token.type) {
449
- case `atom_family`:
450
- return `Atom Family`;
451
- case `molecule_family`:
452
- return `Molecule Family`;
453
- case `readonly_selector`:
454
- return `Readonly Selector`;
455
- case `readonly_selector_family`:
456
- return `Readonly Selector Family`;
457
- case `selector_family`:
458
- return `Selector Family`;
459
- default:
460
- return capitalize(token.type);
461
- }
462
- }
463
- var NotFoundError = class extends Error {
464
- constructor(token, store) {
465
- super(
466
- `${prettyPrintTokenType(token)} "${token.key}" not found in store "${store.config.name}".`
467
- );
468
- }
469
- };
470
-
471
- // internal/src/transaction/act-upon-store.ts
472
- function actUponStore(token, id, store) {
473
- return (...parameters) => {
474
- const tx = withdraw(token, store);
475
- if (tx) {
476
- return tx.run(parameters, id);
477
- }
478
- throw new NotFoundError(token, store);
479
- };
480
- }
481
-
482
- // internal/src/set-state/become.ts
483
- var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(
484
- originalThing instanceof Function ? originalThing() : originalThing
485
- ) : nextVersionOfThing;
486
198
 
487
199
  // internal/src/operation.ts
488
200
  var openOperation = (token, store) => {
@@ -579,8 +291,9 @@ var emitUpdate = (state, update, store) => {
579
291
 
580
292
  // internal/src/set-state/evict-downstream.ts
581
293
  var evictDownStream = (atom, store) => {
582
- const downstreamKeys = store.selectorAtoms.getRelatedKeys(atom.key);
583
- store.logger.info(
294
+ const target = newest(store);
295
+ const downstreamKeys = target.selectorAtoms.getRelatedKeys(atom.key);
296
+ target.logger.info(
584
297
  `\u{1F9F9}`,
585
298
  atom.type,
586
299
  atom.key,
@@ -588,20 +301,20 @@ var evictDownStream = (atom, store) => {
588
301
  downstreamKeys != null ? downstreamKeys : `to evict`
589
302
  );
590
303
  if (downstreamKeys) {
591
- if (store.operation.open) {
592
- store.logger.info(
304
+ if (target.operation.open) {
305
+ target.logger.info(
593
306
  `\u{1F9F9}`,
594
307
  atom.type,
595
308
  atom.key,
596
- `[ ${[...store.operation.done].join(`, `)} ] already done`
309
+ `[ ${[...target.operation.done].join(`, `)} ] already done`
597
310
  );
598
311
  }
599
312
  for (const key of downstreamKeys) {
600
- if (isDone(key, store)) {
313
+ if (isDone(key, target)) {
601
314
  continue;
602
315
  }
603
- evictCachedValue(key, store);
604
- markDone(key, store);
316
+ evictCachedValue(key, target);
317
+ markDone(key, target);
605
318
  }
606
319
  }
607
320
  };
@@ -737,574 +450,463 @@ function ingestAtomUpdate(applying, atomUpdate, store) {
737
450
  }
738
451
  setIntoStore(token, value, store);
739
452
  }
740
-
741
- // internal/src/molecule/create-molecule-family.ts
742
- function createMoleculeFamily(options, store) {
743
- var _a;
453
+ function createRegularAtomFamily(options, store) {
744
454
  const subject = new Subject();
745
- const token = {
746
- type: `molecule_family`,
747
- key: options.key,
748
- dependsOn: (_a = options.dependsOn) != null ? _a : `all`
749
- };
750
- const family = __spreadProps(__spreadValues({}, token), {
751
- subject,
752
- new: options.new
753
- });
754
- store.moleculeFamilies.set(options.key, family);
755
- return token;
455
+ const atomFamily = Object.assign(
456
+ (key) => {
457
+ const subKey = stringifyJson(key);
458
+ const family = { key: options.key, subKey };
459
+ const fullKey = `${options.key}(${subKey})`;
460
+ const target = newest(store);
461
+ const def = options.default;
462
+ const individualOptions = {
463
+ key: fullKey,
464
+ default: def instanceof Function ? def(key) : def
465
+ };
466
+ if (options.effects) {
467
+ individualOptions.effects = options.effects(key);
468
+ }
469
+ const token = createRegularAtom(individualOptions, family, target);
470
+ subject.next({ type: `state_creation`, token });
471
+ return token;
472
+ },
473
+ {
474
+ key: options.key,
475
+ type: `atom_family`,
476
+ subject,
477
+ install: (s) => createRegularAtomFamily(options, s)
478
+ }
479
+ );
480
+ store.families.set(options.key, atomFamily);
481
+ return atomFamily;
756
482
  }
757
483
 
758
- // internal/src/molecule/grow-molecule-in-store.ts
759
- function growMoleculeInStore(molecule, family, store) {
760
- const stateToken = initFamilyMemberInStore(family, molecule.key, store);
761
- molecule.tokens.set(stateToken.key, stateToken);
762
- const isTransaction = isChildStore(store) && store.transactionMeta.phase === `building`;
763
- if (isTransaction) {
764
- store.transactionMeta.update.updates.push({
765
- type: `state_creation`,
766
- token: stateToken
767
- });
768
- } else {
769
- molecule.subject.next({ type: `state_creation`, token: stateToken });
484
+ // internal/src/families/create-atom-family.ts
485
+ function createAtomFamily(options, store) {
486
+ const isMutable2 = `mutable` in options;
487
+ if (isMutable2) {
488
+ return createMutableAtomFamily(options, store);
770
489
  }
771
- return stateToken;
490
+ return createRegularAtomFamily(options, store);
772
491
  }
773
492
 
774
- // internal/src/get-environment-data.ts
775
- function getEnvironmentData(store) {
776
- return {
777
- store
778
- };
779
- }
493
+ // internal/src/keys.ts
494
+ var isAtomKey = (key, store) => newest(store).atoms.has(key);
495
+ var isSelectorKey = (key, store) => newest(store).selectors.has(key);
496
+ var isReadonlySelectorKey = (key, store) => newest(store).readonlySelectors.has(key);
497
+ var isStateKey = (key, store) => isAtomKey(key, store) || isSelectorKey(key, store) || isReadonlySelectorKey(key, store);
780
498
 
781
- // internal/src/get-state/get-from-store.ts
782
- function getFromStore(token, store) {
783
- if (token.type === `molecule`) {
784
- try {
785
- const molecule = withdraw(token, store);
786
- return molecule.instance;
787
- } catch (_) {
788
- return void 0;
789
- }
790
- }
791
- const state = withdraw(token, store);
792
- return readOrComputeValue(state, store);
793
- }
794
- var Molecule = class {
795
- constructor(ctx, key, family) {
796
- this.key = key;
797
- this.type = `molecule`;
798
- this.subject = new Subject();
799
- this.tokens = /* @__PURE__ */ new Map();
800
- this.above = /* @__PURE__ */ new Map();
801
- this.below = /* @__PURE__ */ new Map();
802
- this.joins = /* @__PURE__ */ new Map();
803
- this.stringKey = stringifyJson(key);
804
- if (family) {
805
- this.family = family;
806
- }
807
- if (ctx) {
808
- if (Array.isArray(ctx)) {
809
- for (const molecule of ctx) {
810
- this.above.set(molecule.stringKey, molecule);
811
- }
812
- } else {
813
- this.above.set(ctx.stringKey, ctx);
814
- }
815
- }
816
- }
499
+ // internal/src/selector/get-selector-dependency-keys.ts
500
+ var getSelectorDependencyKeys = (key, store) => {
501
+ const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(source, store));
502
+ return sources;
817
503
  };
818
504
 
819
- // internal/src/molecule/make-molecule-in-store.ts
820
- function makeMoleculeInStore(store, context, familyToken, key, ...params) {
821
- const target = newest(store);
822
- const token = {
823
- type: `molecule`,
824
- key,
825
- family: familyToken
826
- };
827
- const contextArray = Array.isArray(context) ? context : [context];
828
- const owners = contextArray.map((ctx) => {
829
- if (ctx instanceof Molecule) {
830
- return ctx;
831
- }
832
- const stringKey = stringifyJson(ctx.key);
833
- const molecule2 = store.molecules.get(stringKey);
834
- if (!molecule2) {
505
+ // internal/src/selector/trace-selector-atoms.ts
506
+ var traceSelectorAtoms = (selectorKey, directDependencyKey, store) => {
507
+ const rootKeys = [];
508
+ const indirectDependencyKeys = getSelectorDependencyKeys(
509
+ directDependencyKey,
510
+ store
511
+ );
512
+ let depth = 0;
513
+ while (indirectDependencyKeys.length > 0) {
514
+ const indirectDependencyKey = indirectDependencyKeys.shift();
515
+ ++depth;
516
+ if (depth > 99999) {
835
517
  throw new Error(
836
- `Molecule ${stringKey} not found in store "${store.config.name}"`
518
+ `Maximum selector dependency depth exceeded (> 99999) in selector "${selectorKey}". This is likely due to a circular dependency.`
837
519
  );
838
520
  }
839
- return molecule2;
840
- });
841
- const family = withdraw(familyToken, store);
842
- const molecule = new Molecule(owners, key, family);
843
- target.molecules.set(stringifyJson(key), molecule);
844
- for (const owner of owners) {
845
- owner.below.set(molecule.stringKey, molecule);
521
+ if (!isAtomKey(indirectDependencyKey, store)) {
522
+ indirectDependencyKeys.push(
523
+ ...getSelectorDependencyKeys(indirectDependencyKey, store)
524
+ );
525
+ } else if (!rootKeys.includes(indirectDependencyKey)) {
526
+ rootKeys.push(indirectDependencyKey);
527
+ }
846
528
  }
847
- const transactors = {
848
- get: (t) => getFromStore(t, newest(store)),
849
- set: (t, newValue) => {
850
- setIntoStore(t, newValue, newest(store));
851
- },
852
- seek: (t, k) => seekInStore(t, k, newest(store)),
853
- json: (t) => getJsonToken(t, newest(store)),
854
- run: (t, i = arbitrary()) => actUponStore(t, i, newest(store)),
855
- make: (ctx, f, k, ...args) => makeMoleculeInStore(newest(store), ctx, f, k, ...args),
856
- dispose: (t) => {
857
- disposeFromStore(t, newest(store));
858
- },
859
- env: () => getEnvironmentData(newest(store)),
860
- bond: (f) => growMoleculeInStore(
861
- molecule,
862
- withdraw(f, store),
863
- newest(store)
864
- ),
865
- claim: (below, options) => {
866
- const { exclusive } = options;
867
- const belowMolecule = newest(store).molecules.get(stringifyJson(below.key));
868
- if (belowMolecule) {
869
- if (exclusive) {
870
- for (const value of belowMolecule.above.values()) {
871
- value.below.delete(belowMolecule.stringKey);
872
- }
873
- belowMolecule.above.clear();
874
- belowMolecule.above.set(molecule.stringKey, molecule);
875
- molecule.below.set(belowMolecule.stringKey, belowMolecule);
876
- } else {
877
- belowMolecule.above.set(molecule.stringKey, molecule);
878
- molecule.below.set(belowMolecule.stringKey, belowMolecule);
879
- }
529
+ return rootKeys;
530
+ };
531
+ var traceAllSelectorAtoms = (selector, store) => {
532
+ const selectorKey = selector.key;
533
+ const directDependencyKeys = getSelectorDependencyKeys(selectorKey, store);
534
+ return directDependencyKeys.flatMap(
535
+ (depKey) => isAtomKey(depKey, store) ? depKey : traceSelectorAtoms(selectorKey, depKey, store)
536
+ );
537
+ };
538
+
539
+ // internal/src/selector/update-selector-atoms.ts
540
+ var updateSelectorAtoms = (selectorKey, dependency, store) => {
541
+ const target = newest(store);
542
+ if (dependency.type === `atom` || dependency.type === `mutable_atom`) {
543
+ target.selectorAtoms.set({
544
+ selectorKey,
545
+ atomKey: dependency.key
546
+ });
547
+ store.logger.info(
548
+ `\u{1F50D}`,
549
+ `selector`,
550
+ selectorKey,
551
+ `discovers root atom "${dependency.key}"`
552
+ );
553
+ } else {
554
+ const rootKeys = traceSelectorAtoms(selectorKey, dependency.key, store);
555
+ store.logger.info(
556
+ `\u{1F50D}`,
557
+ `selector`,
558
+ selectorKey,
559
+ `discovers root atoms: [ ${rootKeys.map((key) => `"${key}"`).join(`, `)} ]`
560
+ );
561
+ for (const atomKey of rootKeys) {
562
+ target.selectorAtoms = target.selectorAtoms.set({
563
+ selectorKey,
564
+ atomKey
565
+ });
566
+ }
567
+ }
568
+ };
569
+
570
+ // internal/src/selector/register-selector.ts
571
+ var registerSelector = (selectorKey, store) => ({
572
+ get: (dependency) => {
573
+ const target = newest(store);
574
+ const dependencyState = withdraw(dependency, store);
575
+ const dependencyValue = readOrComputeValue(dependencyState, store);
576
+ store.logger.info(
577
+ `\u{1F50C}`,
578
+ `selector`,
579
+ selectorKey,
580
+ `registers dependency ( "${dependency.key}" =`,
581
+ dependencyValue,
582
+ `)`
583
+ );
584
+ target.selectorGraph.set(
585
+ {
586
+ upstreamSelectorKey: dependency.key,
587
+ downstreamSelectorKey: selectorKey
588
+ },
589
+ {
590
+ source: dependency.key
880
591
  }
881
- },
882
- join: (joinToken) => {
883
- const join = getJoin(joinToken, store);
884
- join.molecules.set(stringifyJson(key), molecule);
885
- molecule.joins.set(joinToken.key, join);
886
- return joinToken;
887
- },
888
- spawn: (f, k, ...p) => makeMoleculeInStore(
889
- newest(store),
890
- [molecule],
891
- withdraw(f, store),
892
- k,
893
- ...p
894
- )
592
+ );
593
+ updateSelectorAtoms(selectorKey, dependency, store);
594
+ return dependencyValue;
595
+ },
596
+ set: (WritableToken, newValue) => {
597
+ const target = newest(store);
598
+ const state = withdraw(WritableToken, target);
599
+ setAtomOrSelector(state, newValue, target);
600
+ },
601
+ find: (token, key) => findInStore(token, key, store),
602
+ seek: (token, key) => seekInStore(token, key, store),
603
+ json: (token) => getJsonToken(token, store)
604
+ });
605
+
606
+ // internal/src/selector/create-readonly-selector.ts
607
+ var createReadonlySelector = (options, family, store) => {
608
+ const target = newest(store);
609
+ const subject = new Subject();
610
+ const { get, find, seek, json } = registerSelector(options.key, target);
611
+ const getSelf = () => {
612
+ const value = options.get({ get, find, seek, json });
613
+ cacheValue(options.key, value, subject, newest(store));
614
+ return value;
895
615
  };
896
- const Constructor = family.new;
897
- molecule.instance = new Constructor(transactors, token.key, ...params);
898
- const update = {
899
- type: `molecule_creation`,
900
- token,
901
- family,
902
- context: contextArray,
903
- params
616
+ const readonlySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
617
+ subject,
618
+ install: (s) => createReadonlySelector(options, family, s),
619
+ get: getSelf,
620
+ type: `readonly_selector`
621
+ }), family && { family });
622
+ target.readonlySelectors.set(options.key, readonlySelector);
623
+ const initialValue = getSelf();
624
+ store.logger.info(
625
+ `\u2728`,
626
+ readonlySelector.type,
627
+ readonlySelector.key,
628
+ `=`,
629
+ initialValue
630
+ );
631
+ const token = {
632
+ key: options.key,
633
+ type: `readonly_selector`
904
634
  };
905
- const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
906
- if (isTransaction) {
907
- target.transactionMeta.update.updates.push(update);
908
- } else {
909
- family.subject.next(update);
635
+ if (family) {
636
+ token.family = family;
910
637
  }
911
638
  return token;
912
- }
639
+ };
913
640
 
914
- // internal/src/ingest-updates/ingest-creation-disposal.ts
915
- function ingestCreationEvent(update, applying, store) {
916
- switch (applying) {
917
- case `newValue`: {
918
- createInStore(update.token, store);
919
- break;
920
- }
921
- case `oldValue`: {
922
- disposeFromStore(update.token, store);
923
- break;
641
+ // internal/src/selector/create-writable-selector.ts
642
+ var createWritableSelector = (options, family, store) => {
643
+ const target = newest(store);
644
+ const subject = new Subject();
645
+ const transactors = registerSelector(options.key, target);
646
+ const { find, get, seek, json } = transactors;
647
+ const readonlyTransactors = { find, get, seek, json };
648
+ const getSelf = (innerTarget = newest(store)) => {
649
+ const value = options.get(readonlyTransactors);
650
+ cacheValue(options.key, value, subject, innerTarget);
651
+ return value;
652
+ };
653
+ const setSelf = (next) => {
654
+ const innerTarget = newest(store);
655
+ const oldValue = getSelf(innerTarget);
656
+ const newValue = become(next)(oldValue);
657
+ store.logger.info(
658
+ `\u{1F4DD}`,
659
+ `selector`,
660
+ options.key,
661
+ `set (`,
662
+ oldValue,
663
+ `->`,
664
+ newValue,
665
+ `)`
666
+ );
667
+ cacheValue(options.key, newValue, subject, innerTarget);
668
+ markDone(options.key, innerTarget);
669
+ if (isRootStore(innerTarget)) {
670
+ subject.next({ newValue, oldValue });
924
671
  }
672
+ options.set(transactors, newValue);
673
+ };
674
+ const mySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
675
+ subject,
676
+ install: (s) => createWritableSelector(options, family, s),
677
+ get: getSelf,
678
+ set: setSelf,
679
+ type: `selector`
680
+ }), family && { family });
681
+ target.selectors.set(options.key, mySelector);
682
+ const initialValue = getSelf();
683
+ store.logger.info(`\u2728`, mySelector.type, mySelector.key, `=`, initialValue);
684
+ const token = {
685
+ key: options.key,
686
+ type: `selector`
687
+ };
688
+ if (family) {
689
+ token.family = family;
925
690
  }
926
- }
927
- function ingestDisposalEvent(update, applying, store) {
928
- switch (applying) {
929
- case `newValue`: {
930
- disposeFromStore(update.token, store);
931
- break;
932
- }
933
- case `oldValue`: {
934
- createInStore(update.token, store);
935
- store.valueMap.set(update.token.key, update.value);
936
- break;
937
- }
691
+ return token;
692
+ };
693
+
694
+ // internal/src/selector/create-standalone-selector.ts
695
+ function createStandaloneSelector(options, store) {
696
+ const isWritable = `set` in options;
697
+ if (isWritable) {
698
+ const state2 = createWritableSelector(options, void 0, store);
699
+ store.on.selectorCreation.next(state2);
700
+ return state2;
938
701
  }
702
+ const state = createReadonlySelector(options, void 0, store);
703
+ store.on.selectorCreation.next(state);
704
+ return state;
939
705
  }
940
- function createInStore(token, store) {
941
- if (token.family) {
942
- const family = store.families.get(token.family.key);
943
- if (family) {
944
- const molecule = store.molecules.get(token.family.subKey);
945
- if (molecule) {
946
- growMoleculeInStore(molecule, family, store);
947
- return;
706
+
707
+ // internal/src/selector/dispose-selector.ts
708
+ function disposeSelector(selectorToken, store) {
709
+ var _a;
710
+ const target = newest(store);
711
+ const { key } = selectorToken;
712
+ const selector = (_a = target.selectors.get(key)) != null ? _a : target.readonlySelectors.get(key);
713
+ if (!selector) {
714
+ store.logger.info(
715
+ `\u274C`,
716
+ `selector`,
717
+ key,
718
+ `Tried to dispose selector, but it does not exist in the store.`
719
+ );
720
+ } else if (!selector.family) {
721
+ store.logger.error(
722
+ `\u274C`,
723
+ `selector`,
724
+ key,
725
+ `Standalone selectors cannot be disposed.`
726
+ );
727
+ } else {
728
+ const molecule = target.molecules.get(selector.family.subKey);
729
+ if (molecule) {
730
+ molecule.tokens.delete(key);
731
+ }
732
+ switch (selectorToken.type) {
733
+ case `selector`:
734
+ {
735
+ target.selectors.delete(key);
736
+ const family = withdraw(
737
+ { key: selector.family.key, type: `selector_family` },
738
+ store
739
+ );
740
+ family.subject.next({
741
+ type: `state_disposal`,
742
+ token: selectorToken
743
+ });
744
+ }
745
+ break;
746
+ case `readonly_selector`:
747
+ {
748
+ target.readonlySelectors.delete(key);
749
+ const family = withdraw(
750
+ { key: selector.family.key, type: `readonly_selector_family` },
751
+ store
752
+ );
753
+ family.subject.next({
754
+ type: `state_disposal`,
755
+ token: selectorToken
756
+ });
757
+ }
758
+ break;
759
+ }
760
+ target.valueMap.delete(key);
761
+ target.selectorAtoms.delete(key);
762
+ const downstreamTokens = target.selectorGraph.getRelationEntries({ upstreamSelectorKey: key }).filter(([_, { source }]) => source === key).map(
763
+ ([downstreamSelectorKey]) => {
764
+ var _a2;
765
+ return (_a2 = target.selectors.get(downstreamSelectorKey)) != null ? _a2 : target.readonlySelectors.get(downstreamSelectorKey);
948
766
  }
949
- if (store.config.lifespan === `immortal`) {
950
- throw new Error(`No molecule found for key "${token.family.subKey}"`);
767
+ );
768
+ for (const downstreamToken of downstreamTokens) {
769
+ if (downstreamToken) {
770
+ disposeSelector(downstreamToken, store);
951
771
  }
952
- initFamilyMemberInStore(family, parseJson(token.family.subKey), store);
772
+ }
773
+ target.selectorGraph.delete(key);
774
+ store.logger.info(`\u{1F525}`, selectorToken.type, key, `deleted`);
775
+ if (isChildStore(target) && target.transactionMeta.phase === `building`) {
776
+ target.transactionMeta.update.updates.push({
777
+ type: `state_disposal`,
778
+ token: selectorToken
779
+ });
780
+ } else {
781
+ store.on.selectorDisposal.next(selectorToken);
953
782
  }
954
783
  }
955
784
  }
956
- function ingestMoleculeCreationEvent(update, applying, store) {
957
- switch (applying) {
958
- case `newValue`:
959
- makeMoleculeInStore(
960
- store,
961
- update.context[0],
962
- update.family,
963
- update.token.key,
964
- ...update.params
785
+
786
+ // internal/src/families/create-readonly-selector-family.ts
787
+ function createReadonlySelectorFamily(options, store) {
788
+ const subject = new Subject();
789
+ const readonlySelectorFamily = Object.assign(
790
+ (key) => {
791
+ const subKey = stringifyJson(key);
792
+ const family = { key: options.key, subKey };
793
+ const fullKey = `${options.key}(${subKey})`;
794
+ const target = newest(store);
795
+ const token = createReadonlySelector(
796
+ {
797
+ key: fullKey,
798
+ get: options.get(key)
799
+ },
800
+ family,
801
+ target
965
802
  );
966
- break;
967
- case `oldValue`:
968
- disposeFromStore(update.token, store);
969
- break;
970
- }
803
+ subject.next({ type: `state_creation`, token });
804
+ return token;
805
+ },
806
+ {
807
+ key: options.key,
808
+ type: `readonly_selector_family`,
809
+ subject,
810
+ install: (s) => createReadonlySelectorFamily(options, s)
811
+ }
812
+ );
813
+ store.families.set(options.key, readonlySelectorFamily);
814
+ return readonlySelectorFamily;
971
815
  }
972
- function ingestMoleculeDisposalEvent(update, applying, store) {
973
- switch (applying) {
974
- case `newValue`:
975
- disposeFromStore(update.token, store);
976
- break;
977
- case `oldValue`:
978
- makeMoleculeInStore(
979
- store,
980
- update.context[0],
981
- update.family,
982
- update.token.key
816
+ function createWritableSelectorFamily(options, store) {
817
+ const subject = new Subject();
818
+ const selectorFamily = Object.assign(
819
+ (key) => {
820
+ const subKey = stringifyJson(key);
821
+ const family = { key: options.key, subKey };
822
+ const fullKey = `${options.key}(${subKey})`;
823
+ const target = newest(store);
824
+ const token = createWritableSelector(
825
+ {
826
+ key: fullKey,
827
+ get: options.get(key),
828
+ set: options.set(key)
829
+ },
830
+ family,
831
+ target
983
832
  );
984
- break;
985
- }
833
+ subject.next({ type: `state_creation`, token });
834
+ return token;
835
+ },
836
+ {
837
+ key: options.key,
838
+ type: `selector_family`,
839
+ subject,
840
+ install: (s) => createWritableSelectorFamily(options, s)
841
+ }
842
+ );
843
+ store.families.set(options.key, selectorFamily);
844
+ return selectorFamily;
986
845
  }
987
846
 
988
- // internal/src/ingest-updates/ingest-selector-update.ts
989
- function ingestSelectorUpdate(applying, selectorUpdate, store) {
990
- const updates = applying === `newValue` ? selectorUpdate.atomUpdates : [...selectorUpdate.atomUpdates].reverse();
991
- for (const atomUpdate of updates) {
992
- ingestAtomUpdate(applying, atomUpdate, store);
847
+ // internal/src/families/create-selector-family.ts
848
+ function createSelectorFamily(options, store) {
849
+ const isWritable = `set` in options;
850
+ if (isWritable) {
851
+ return createWritableSelectorFamily(options, store);
993
852
  }
853
+ return createReadonlySelectorFamily(options, store);
994
854
  }
995
855
 
996
- // internal/src/ingest-updates/ingest-transaction-update.ts
997
- function ingestTransactionUpdate(applying, transactionUpdate, store) {
998
- const updates = applying === `newValue` ? transactionUpdate.updates : [...transactionUpdate.updates].reverse();
999
- for (const updateFromTransaction of updates) {
1000
- switch (updateFromTransaction.type) {
1001
- case `atom_update`:
1002
- case `selector_update`:
1003
- ingestAtomUpdate(applying, updateFromTransaction, store);
1004
- break;
1005
- case `state_creation`:
1006
- ingestCreationEvent(updateFromTransaction, applying, store);
1007
- break;
1008
- case `state_disposal`:
1009
- ingestDisposalEvent(updateFromTransaction, applying, store);
1010
- break;
1011
- case `molecule_creation`:
1012
- ingestMoleculeCreationEvent(updateFromTransaction, applying, store);
1013
- break;
1014
- case `molecule_disposal`:
1015
- ingestMoleculeDisposalEvent(updateFromTransaction, applying, store);
1016
- break;
1017
- case `transaction_update`:
1018
- ingestTransactionUpdate(applying, updateFromTransaction, store);
1019
- break;
856
+ // internal/src/molecule/dispose-molecule.ts
857
+ function disposeMolecule(token, store) {
858
+ var _a;
859
+ let molecule;
860
+ try {
861
+ molecule = withdraw(token, store);
862
+ } catch (thrown) {
863
+ if (thrown instanceof Error) {
864
+ store.logger.error(
865
+ `\u{1F41E}`,
866
+ `molecule`,
867
+ JSON.stringify(token.key),
868
+ `Failed to dispose molecule, because it was not found in the store.`,
869
+ thrown.message
870
+ );
1020
871
  }
1021
- }
1022
- }
1023
-
1024
- // internal/src/transaction/set-epoch-number.ts
1025
- function setEpochNumberOfContinuity(continuityKey, newEpoch, store) {
1026
- const isRoot = isRootStore(store);
1027
- if (isRoot && continuityKey) {
1028
- store.transactionMeta.epoch.set(continuityKey, newEpoch);
1029
- }
1030
- }
1031
- function setEpochNumberOfAction(transactionKey, newEpoch, store) {
1032
- const isRoot = isRootStore(store);
1033
- if (!isRoot) {
1034
872
  return;
1035
873
  }
1036
- const continuityKey = store.transactionMeta.actionContinuities.getRelatedKey(transactionKey);
1037
- if (continuityKey !== void 0) {
1038
- store.transactionMeta.epoch.set(continuityKey, newEpoch);
874
+ const { family } = token;
875
+ const context = [];
876
+ for (const above of molecule.above.values()) {
877
+ context.push(deposit(above));
1039
878
  }
1040
- }
1041
-
1042
- // internal/src/transaction/apply-transaction.ts
1043
- var applyTransaction = (output, store) => {
1044
- var _a;
1045
- const child = newest(store);
1046
- const { parent } = child;
1047
- if (parent === null || !isChildStore(child) || ((_a = child.transactionMeta) == null ? void 0 : _a.phase) !== `building`) {
1048
- store.logger.warn(
1049
- `\u{1F41E}`,
1050
- `transaction`,
1051
- `???`,
1052
- `applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`
1053
- );
1054
- return;
1055
- }
1056
- child.transactionMeta.phase = `applying`;
1057
- child.transactionMeta.update.output = output;
1058
- parent.child = null;
1059
- parent.on.transactionApplying.next(child.transactionMeta);
1060
- const { updates } = child.transactionMeta.update;
1061
- store.logger.info(
1062
- `\u{1F6C4}`,
1063
- `transaction`,
1064
- child.transactionMeta.update.key,
1065
- `Applying transaction with ${updates.length} updates:`,
1066
- updates
1067
- );
1068
- ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
1069
- if (isRootStore(parent)) {
1070
- setEpochNumberOfAction(
1071
- child.transactionMeta.update.key,
1072
- child.transactionMeta.update.epoch,
1073
- parent
1074
- );
1075
- const myTransaction = withdraw(
1076
- { key: child.transactionMeta.update.key, type: `transaction` },
1077
- store
1078
- );
1079
- myTransaction == null ? void 0 : myTransaction.subject.next(child.transactionMeta.update);
1080
- store.logger.info(
1081
- `\u{1F6EC}`,
1082
- `transaction`,
1083
- child.transactionMeta.update.key,
1084
- `Finished applying transaction.`
1085
- );
1086
- } else if (isChildStore(parent)) {
1087
- parent.transactionMeta.update.updates.push(child.transactionMeta.update);
1088
- }
1089
- parent.on.transactionApplying.next(null);
1090
- };
1091
-
1092
- // internal/src/transaction/assign-transaction-to-continuity.ts
1093
- function assignTransactionToContinuity(continuityKey, transactionKey, store) {
1094
- const isRoot = isRootStore(store);
1095
- if (!isRoot) {
1096
- return;
1097
- }
1098
- const { epoch, actionContinuities } = store.transactionMeta;
1099
- actionContinuities.set(continuityKey, transactionKey);
1100
- if (!epoch.has(continuityKey)) {
1101
- epoch.set(continuityKey, -1);
1102
- }
1103
- }
1104
-
1105
- // internal/src/lazy-map.ts
1106
- var LazyMap = class extends Map {
1107
- constructor(source) {
1108
- super();
1109
- this.source = source;
1110
- this.deleted = /* @__PURE__ */ new Set();
1111
- }
1112
- get(key) {
1113
- const has = super.has(key);
1114
- if (has) {
1115
- return super.get(key);
1116
- }
1117
- if (!this.deleted.has(key) && this.source.has(key)) {
1118
- const value = this.source.get(key);
1119
- return value;
1120
- }
1121
- return void 0;
1122
- }
1123
- set(key, value) {
1124
- this.deleted.delete(key);
1125
- return super.set(key, value);
1126
- }
1127
- hasOwn(key) {
1128
- return super.has(key);
1129
- }
1130
- has(key) {
1131
- return !this.deleted.has(key) && (super.has(key) || this.source.has(key));
1132
- }
1133
- delete(key) {
1134
- this.deleted.add(key);
1135
- return super.delete(key);
1136
- }
1137
- };
1138
-
1139
- // internal/src/transaction/build-transaction.ts
1140
- var buildTransaction = (key, params, store, id) => {
1141
- const parent = newest(store);
1142
- const childBase = {
1143
- parent,
1144
- child: null,
1145
- on: parent.on,
1146
- loggers: parent.loggers,
1147
- logger: parent.logger,
1148
- config: parent.config,
1149
- atoms: new LazyMap(parent.atoms),
1150
- atomsThatAreDefault: new Set(parent.atomsThatAreDefault),
1151
- families: new LazyMap(parent.families),
1152
- operation: { open: false },
1153
- readonlySelectors: new LazyMap(parent.readonlySelectors),
1154
- timelines: new LazyMap(parent.timelines),
1155
- timelineAtoms: new Junction(parent.timelineAtoms.toJSON()),
1156
- trackers: /* @__PURE__ */ new Map(),
1157
- transactions: new LazyMap(parent.transactions),
1158
- selectorAtoms: new Junction(parent.selectorAtoms.toJSON()),
1159
- selectorGraph: new Junction(parent.selectorGraph.toJSON(), {
1160
- makeContentKey: (...keys) => keys.sort().join(`:`)
1161
- }),
1162
- selectors: new LazyMap(parent.selectors),
1163
- valueMap: new LazyMap(parent.valueMap),
1164
- molecules: new LazyMap(parent.molecules),
1165
- moleculeFamilies: new LazyMap(parent.moleculeFamilies),
1166
- miscResources: new LazyMap(parent.miscResources)
1167
- };
1168
- const epoch = getEpochNumberOfAction(key, store);
1169
- const transactionMeta = {
1170
- phase: `building`,
1171
- update: {
1172
- type: `transaction_update`,
1173
- key,
1174
- id,
1175
- epoch: epoch === void 0 ? Number.NaN : epoch + 1,
1176
- updates: [],
1177
- params,
1178
- output: void 0
1179
- },
1180
- transactors: {
1181
- get: (token) => getFromStore(token, child),
1182
- set: (token, value) => {
1183
- setIntoStore(token, value, child);
1184
- },
1185
- run: (token, identifier = arbitrary()) => actUponStore(token, identifier, child),
1186
- find: (token, k) => findInStore(token, k, child),
1187
- seek: (token, k) => seekInStore(token, k, child),
1188
- json: (token) => getJsonToken(token, child),
1189
- make: (context, family, k, ...args) => makeMoleculeInStore(child, context, family, k, ...args),
1190
- dispose: (token) => {
1191
- disposeFromStore(token, child);
1192
- },
1193
- env: () => getEnvironmentData(child)
1194
- }
1195
- };
1196
- const child = Object.assign(childBase, {
1197
- transactionMeta
1198
- });
1199
- parent.child = child;
1200
- store.logger.info(
1201
- `\u{1F6EB}`,
1202
- `transaction`,
1203
- key,
1204
- `Building transaction with params:`,
1205
- params
1206
- );
1207
- return child;
1208
- };
1209
-
1210
- // internal/src/transaction/create-transaction.ts
1211
- function createTransaction(options, store) {
1212
- const newTransaction = {
1213
- key: options.key,
1214
- type: `transaction`,
1215
- run: (params, id) => {
1216
- const childStore = buildTransaction(options.key, params, store, id);
1217
- try {
1218
- const target2 = newest(store);
1219
- const { transactors } = childStore.transactionMeta;
1220
- const output = options.do(transactors, ...params);
1221
- applyTransaction(output, target2);
1222
- return output;
1223
- } catch (thrown) {
1224
- abortTransaction(target);
1225
- store.logger.warn(`\u{1F4A5}`, `transaction`, options.key, `caught:`, thrown);
1226
- throw thrown;
1227
- }
1228
- },
1229
- install: (s) => createTransaction(options, s),
1230
- subject: new Subject()
1231
- };
1232
- const target = newest(store);
1233
- target.transactions.set(newTransaction.key, newTransaction);
1234
- const token = deposit(newTransaction);
1235
- store.on.transactionCreation.next(token);
1236
- return token;
1237
- }
1238
-
1239
- // internal/src/transaction/get-epoch-number.ts
1240
- function getContinuityKey(transactionKey, store) {
1241
- const isRoot = isRootStore(store);
1242
- const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
1243
- return continuity;
1244
- }
1245
- function getEpochNumberOfContinuity(continuityKey, store) {
1246
- const isRoot = isRootStore(store);
1247
- const epoch = isRoot && continuityKey ? store.transactionMeta.epoch.get(continuityKey) : void 0;
1248
- return epoch;
1249
- }
1250
- function getEpochNumberOfAction(transactionKey, store) {
1251
- const isRoot = isRootStore(store);
1252
- const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
1253
- const epoch = isRoot && continuity !== void 0 ? store.transactionMeta.epoch.get(continuity) : void 0;
1254
- return epoch;
1255
- }
1256
-
1257
- // internal/src/transaction/index.ts
1258
- var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
1259
-
1260
- // internal/src/molecule/dispose-molecule.ts
1261
- function disposeMolecule(token, store) {
1262
- var _a;
1263
- let molecule;
1264
- try {
1265
- molecule = withdraw(token, store);
1266
- } catch (thrown) {
1267
- if (thrown instanceof Error) {
1268
- store.logger.error(
1269
- `\u{1F41E}`,
1270
- `molecule`,
1271
- JSON.stringify(token.key),
1272
- `Failed to dispose molecule, because it was not found in the store.`,
1273
- thrown.message
1274
- );
1275
- }
1276
- return;
1277
- }
1278
- const { family } = token;
1279
- for (const state of molecule.tokens.values()) {
1280
- disposeFromStore(state, store);
1281
- }
1282
- for (const child of molecule.below.values()) {
1283
- if (((_a = child.family) == null ? void 0 : _a.dependsOn) === `all`) {
1284
- disposeMolecule(child, store);
1285
- } else {
1286
- child.above.delete(molecule.stringKey);
1287
- if (child.above.size === 0) {
1288
- disposeMolecule(child, store);
1289
- }
1290
- }
879
+ const values = [];
880
+ for (const stateToken of molecule.tokens.values()) {
881
+ const tokenFamily = stateToken.family;
882
+ values.push([tokenFamily.key, store.valueMap.get(stateToken.key)]);
1291
883
  }
1292
- molecule.below.clear();
1293
884
  if (family) {
1294
885
  const Formula = withdraw(family, store);
1295
886
  const disposalEvent = {
1296
887
  type: `molecule_disposal`,
1297
888
  token,
1298
889
  family,
1299
- context: [...molecule.above.values()].map((m) => deposit(m)),
1300
- familyKeys: [...molecule.tokens.values()].map((t) => {
1301
- var _a2;
1302
- return (_a2 = t.family) == null ? void 0 : _a2.key;
1303
- }).filter((k) => typeof k === `string`)
890
+ context,
891
+ values
1304
892
  };
1305
893
  if (token.family) {
1306
894
  disposalEvent.family = token.family;
1307
895
  }
896
+ for (const state of molecule.tokens.values()) {
897
+ disposeFromStore(state, store);
898
+ }
899
+ for (const child of molecule.below.values()) {
900
+ if (((_a = child.family) == null ? void 0 : _a.dependsOn) === `all`) {
901
+ disposeMolecule(child, store);
902
+ } else {
903
+ child.above.delete(molecule.stringKey);
904
+ if (child.above.size === 0) {
905
+ disposeMolecule(child, store);
906
+ }
907
+ }
908
+ }
909
+ molecule.below.clear();
1308
910
  const isTransaction = isChildStore(store) && store.transactionMeta.phase === `building`;
1309
911
  if (isTransaction) {
1310
912
  store.transactionMeta.update.updates.push(disposalEvent);
@@ -1347,13 +949,8 @@ function initFamilyMemberInStore(token, key, store) {
1347
949
  }
1348
950
  const state = family(key);
1349
951
  const target = newest(store);
1350
- if (state.family) {
1351
- if (isChildStore(target) && target.transactionMeta.phase === `building`) {
1352
- target.transactionMeta.update.updates.push({
1353
- type: `state_creation`,
1354
- token: state
1355
- });
1356
- } else {
952
+ if (state.family && target.moleculeInProgress === null) {
953
+ if (isRootStore(target)) {
1357
954
  switch (state.type) {
1358
955
  case `atom`:
1359
956
  case `mutable_atom`:
@@ -1364,6 +961,11 @@ function initFamilyMemberInStore(token, key, store) {
1364
961
  store.on.selectorCreation.next(state);
1365
962
  break;
1366
963
  }
964
+ } else if (isChildStore(target) && target.on.transactionApplying.state === null) {
965
+ target.transactionMeta.update.updates.push({
966
+ type: `state_creation`,
967
+ token: state
968
+ });
1367
969
  }
1368
970
  }
1369
971
  return state;
@@ -1411,291 +1013,715 @@ function findInStore(token, key, store) {
1411
1013
  return state;
1412
1014
  }
1413
1015
 
1414
- // internal/src/keys.ts
1415
- var isAtomKey = (key, store) => newest(store).atoms.has(key);
1416
- var isSelectorKey = (key, store) => newest(store).selectors.has(key);
1417
- var isReadonlySelectorKey = (key, store) => newest(store).readonlySelectors.has(key);
1418
- var isStateKey = (key, store) => isAtomKey(key, store) || isSelectorKey(key, store) || isReadonlySelectorKey(key, store);
1016
+ // internal/src/molecule/create-molecule-family.ts
1017
+ function createMoleculeFamily(options, store) {
1018
+ var _a;
1019
+ const subject = new Subject();
1020
+ const token = {
1021
+ type: `molecule_family`,
1022
+ key: options.key,
1023
+ dependsOn: (_a = options.dependsOn) != null ? _a : `all`
1024
+ };
1025
+ const family = __spreadProps(__spreadValues({}, token), {
1026
+ subject,
1027
+ new: options.new
1028
+ });
1029
+ store.moleculeFamilies.set(options.key, family);
1030
+ return token;
1031
+ }
1419
1032
 
1420
- // internal/src/selector/get-selector-dependency-keys.ts
1421
- var getSelectorDependencyKeys = (key, store) => {
1422
- const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(source, store));
1423
- return sources;
1424
- };
1033
+ // internal/src/molecule/grow-molecule-in-store.ts
1034
+ function growMoleculeInStore(molecule, family, store) {
1035
+ const stateToken = initFamilyMemberInStore(family, molecule.key, store);
1036
+ molecule.tokens.set(stateToken.key, stateToken);
1037
+ const isTransaction = isChildStore(store) && store.transactionMeta.phase === `building`;
1038
+ const moleculeInProgress = store.moleculeInProgress === molecule.key;
1039
+ if (!isTransaction && !moleculeInProgress) {
1040
+ molecule.subject.next({ type: `state_creation`, token: stateToken });
1041
+ }
1042
+ return stateToken;
1043
+ }
1425
1044
 
1426
- // internal/src/selector/trace-selector-atoms.ts
1427
- var traceSelectorAtoms = (selectorKey, directDependencyKey, store) => {
1428
- const rootKeys = [];
1429
- const indirectDependencyKeys = getSelectorDependencyKeys(
1430
- directDependencyKey,
1045
+ // internal/src/get-environment-data.ts
1046
+ function getEnvironmentData(store) {
1047
+ return {
1431
1048
  store
1432
- );
1433
- let depth = 0;
1434
- while (indirectDependencyKeys.length > 0) {
1435
- const indirectDependencyKey = indirectDependencyKeys.shift();
1436
- ++depth;
1437
- if (depth > 99999) {
1438
- throw new Error(
1439
- `Maximum selector dependency depth exceeded (> 99999) in selector "${selectorKey}". This is likely due to a circular dependency.`
1440
- );
1049
+ };
1050
+ }
1051
+
1052
+ // internal/src/get-state/get-from-store.ts
1053
+ function getFromStore(token, store) {
1054
+ if (token.type === `molecule`) {
1055
+ try {
1056
+ const molecule = withdraw(token, store);
1057
+ return molecule.instance;
1058
+ } catch (_) {
1059
+ return void 0;
1441
1060
  }
1442
- if (!isAtomKey(indirectDependencyKey, store)) {
1443
- indirectDependencyKeys.push(
1444
- ...getSelectorDependencyKeys(indirectDependencyKey, store)
1445
- );
1446
- } else if (!rootKeys.includes(indirectDependencyKey)) {
1447
- rootKeys.push(indirectDependencyKey);
1061
+ }
1062
+ const state = withdraw(token, store);
1063
+ return readOrComputeValue(state, store);
1064
+ }
1065
+ var Molecule = class {
1066
+ constructor(ctx, key, family) {
1067
+ this.key = key;
1068
+ this.type = `molecule`;
1069
+ this.subject = new Subject();
1070
+ this.tokens = /* @__PURE__ */ new Map();
1071
+ this.above = /* @__PURE__ */ new Map();
1072
+ this.below = /* @__PURE__ */ new Map();
1073
+ this.joins = /* @__PURE__ */ new Map();
1074
+ this.stringKey = stringifyJson(key);
1075
+ if (family) {
1076
+ this.family = family;
1077
+ }
1078
+ if (ctx) {
1079
+ if (Array.isArray(ctx)) {
1080
+ for (const molecule of ctx) {
1081
+ this.above.set(molecule.stringKey, molecule);
1082
+ }
1083
+ } else {
1084
+ this.above.set(ctx.stringKey, ctx);
1085
+ }
1448
1086
  }
1449
1087
  }
1450
- return rootKeys;
1451
- };
1452
- var traceAllSelectorAtoms = (selector, store) => {
1453
- const selectorKey = selector.key;
1454
- const directDependencyKeys = getSelectorDependencyKeys(selectorKey, store);
1455
- return directDependencyKeys.flatMap(
1456
- (depKey) => isAtomKey(depKey, store) ? depKey : traceSelectorAtoms(selectorKey, depKey, store)
1457
- );
1458
1088
  };
1459
1089
 
1460
- // internal/src/selector/update-selector-atoms.ts
1461
- var updateSelectorAtoms = (selectorKey, dependency, store) => {
1090
+ // internal/src/molecule/make-molecule-in-store.ts
1091
+ function makeMoleculeInStore(store, context, familyToken, key, ...params) {
1462
1092
  const target = newest(store);
1463
- if (dependency.type === `atom` || dependency.type === `mutable_atom`) {
1464
- target.selectorAtoms.set({
1465
- selectorKey,
1466
- atomKey: dependency.key
1467
- });
1468
- store.logger.info(
1469
- `\u{1F50D}`,
1470
- `selector`,
1471
- selectorKey,
1472
- `discovers root atom "${dependency.key}"`
1473
- );
1474
- } else {
1475
- const rootKeys = traceSelectorAtoms(selectorKey, dependency.key, store);
1476
- store.logger.info(
1477
- `\u{1F50D}`,
1478
- `selector`,
1479
- selectorKey,
1480
- `discovers root atoms: [ ${rootKeys.map((key) => `"${key}"`).join(`, `)} ]`
1481
- );
1482
- for (const atomKey of rootKeys) {
1483
- target.selectorAtoms = target.selectorAtoms.set({
1484
- selectorKey,
1485
- atomKey
1486
- });
1093
+ target.moleculeInProgress = key;
1094
+ const contextArray = Array.isArray(context) ? context : [context];
1095
+ const owners = contextArray.map((ctx) => {
1096
+ if (ctx instanceof Molecule) {
1097
+ return ctx;
1098
+ }
1099
+ const stringKey = stringifyJson(ctx.key);
1100
+ const molecule2 = store.molecules.get(stringKey);
1101
+ if (!molecule2) {
1102
+ throw new Error(
1103
+ `Molecule ${stringKey} not found in store "${store.config.name}"`
1104
+ );
1487
1105
  }
1106
+ return molecule2;
1107
+ });
1108
+ const molecule = new Molecule(owners, key, familyToken);
1109
+ target.molecules.set(stringifyJson(key), molecule);
1110
+ for (const owner of owners) {
1111
+ owner.below.set(molecule.stringKey, molecule);
1488
1112
  }
1489
- };
1490
-
1491
- // internal/src/selector/register-selector.ts
1492
- var registerSelector = (selectorKey, store) => ({
1493
- get: (dependency) => {
1494
- const target = newest(store);
1495
- const dependencyState = withdraw(dependency, store);
1496
- const dependencyValue = readOrComputeValue(dependencyState, store);
1497
- store.logger.info(
1498
- `\u{1F50C}`,
1499
- `selector`,
1500
- selectorKey,
1501
- `registers dependency ( "${dependency.key}" =`,
1502
- dependencyValue,
1503
- `)`
1504
- );
1505
- target.selectorGraph.set(
1506
- {
1507
- upstreamSelectorKey: dependency.key,
1508
- downstreamSelectorKey: selectorKey
1509
- },
1510
- {
1511
- source: dependency.key
1113
+ const transactors = {
1114
+ get: (t) => getFromStore(t, newest(store)),
1115
+ set: (t, newValue) => {
1116
+ setIntoStore(t, newValue, newest(store));
1117
+ },
1118
+ seek: (t, k) => seekInStore(t, k, newest(store)),
1119
+ json: (t) => getJsonToken(t, newest(store)),
1120
+ run: (t, i = arbitrary()) => actUponStore(t, i, newest(store)),
1121
+ make: (ctx, f, k, ...args) => makeMoleculeInStore(newest(store), ctx, f, k, ...args),
1122
+ dispose: (t) => {
1123
+ disposeFromStore(t, newest(store));
1124
+ },
1125
+ env: () => getEnvironmentData(newest(store)),
1126
+ bond: (f) => growMoleculeInStore(
1127
+ molecule,
1128
+ withdraw(f, store),
1129
+ newest(store)
1130
+ ),
1131
+ claim: (below, options) => {
1132
+ const { exclusive } = options;
1133
+ const belowMolecule = newest(store).molecules.get(stringifyJson(below.key));
1134
+ if (belowMolecule) {
1135
+ if (exclusive) {
1136
+ for (const value of belowMolecule.above.values()) {
1137
+ value.below.delete(belowMolecule.stringKey);
1138
+ }
1139
+ belowMolecule.above.clear();
1140
+ belowMolecule.above.set(molecule.stringKey, molecule);
1141
+ molecule.below.set(belowMolecule.stringKey, belowMolecule);
1142
+ } else {
1143
+ belowMolecule.above.set(molecule.stringKey, molecule);
1144
+ molecule.below.set(belowMolecule.stringKey, belowMolecule);
1145
+ }
1512
1146
  }
1513
- );
1514
- updateSelectorAtoms(selectorKey, dependency, store);
1515
- return dependencyValue;
1516
- },
1517
- set: (WritableToken, newValue) => {
1518
- const state = withdraw(WritableToken, store);
1519
- setAtomOrSelector(state, newValue, store);
1520
- },
1521
- find: (token, key) => findInStore(token, key, store),
1522
- seek: (token, key) => seekInStore(token, key, store),
1523
- json: (token) => getJsonToken(token, store)
1524
- });
1525
-
1526
- // internal/src/selector/create-readonly-selector.ts
1527
- var createReadonlySelector = (options, family, store) => {
1528
- const target = newest(store);
1529
- const subject = new Subject();
1530
- const { get, find, seek, json } = registerSelector(options.key, target);
1531
- const getSelf = () => {
1532
- const value = options.get({ get, find, seek, json });
1533
- cacheValue(options.key, value, subject, newest(store));
1534
- return value;
1147
+ },
1148
+ join: (joinToken) => {
1149
+ const join = getJoin(joinToken, store);
1150
+ join.molecules.set(stringifyJson(key), molecule);
1151
+ molecule.joins.set(joinToken.key, join);
1152
+ return joinToken;
1153
+ },
1154
+ spawn: (f, k, ...p) => makeMoleculeInStore(
1155
+ newest(store),
1156
+ [molecule],
1157
+ withdraw(f, store),
1158
+ k,
1159
+ ...p
1160
+ )
1535
1161
  };
1536
- const readonlySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
1537
- subject,
1538
- install: (s) => createReadonlySelector(options, family, s),
1539
- get: getSelf,
1540
- type: `readonly_selector`
1541
- }), family && { family });
1542
- target.readonlySelectors.set(options.key, readonlySelector);
1543
- const initialValue = getSelf();
1544
- store.logger.info(
1545
- `\u2728`,
1546
- readonlySelector.type,
1547
- readonlySelector.key,
1548
- `=`,
1549
- initialValue
1550
- );
1162
+ const family = withdraw(familyToken, store);
1163
+ const Constructor = family.new;
1164
+ molecule.instance = new Constructor(transactors, key, ...params);
1551
1165
  const token = {
1552
- key: options.key,
1553
- type: `readonly_selector`
1554
- };
1555
- if (family) {
1556
- token.family = family;
1166
+ type: `molecule`,
1167
+ key,
1168
+ family: familyToken
1169
+ };
1170
+ const update = {
1171
+ type: `molecule_creation`,
1172
+ token,
1173
+ family: familyToken,
1174
+ context: contextArray,
1175
+ params
1176
+ };
1177
+ if (isRootStore(target)) {
1178
+ family.subject.next(update);
1179
+ } else if (isChildStore(target) && target.on.transactionApplying.state === null) {
1180
+ target.transactionMeta.update.updates.push(update);
1557
1181
  }
1182
+ target.moleculeInProgress = null;
1558
1183
  return token;
1559
- };
1184
+ }
1560
1185
 
1561
- // internal/src/selector/create-writable-selector.ts
1562
- var createWritableSelector = (options, family, store) => {
1563
- const target = newest(store);
1564
- const subject = new Subject();
1565
- const transactors = registerSelector(options.key, target);
1566
- const { find, get, seek, json } = transactors;
1567
- const readonlyTransactors = { find, get, seek, json };
1568
- const getSelf = () => {
1569
- const value = options.get(readonlyTransactors);
1570
- cacheValue(options.key, value, subject, newest(store));
1571
- return value;
1572
- };
1573
- const setSelf = (next) => {
1574
- const oldValue = getSelf();
1575
- const newValue = become(next)(oldValue);
1576
- store.logger.info(
1577
- `\u{1F4DD}`,
1578
- `selector`,
1579
- options.key,
1580
- `set (`,
1581
- oldValue,
1582
- `->`,
1583
- newValue,
1584
- `)`
1585
- );
1586
- cacheValue(options.key, newValue, subject, store);
1587
- markDone(options.key, store);
1588
- if (isRootStore(target)) {
1589
- subject.next({ newValue, oldValue });
1186
+ // internal/src/ingest-updates/ingest-creation-disposal.ts
1187
+ function ingestCreationEvent(update, applying, store) {
1188
+ switch (applying) {
1189
+ case `newValue`: {
1190
+ createInStore(update.token, store);
1191
+ break;
1192
+ }
1193
+ case `oldValue`: {
1194
+ disposeFromStore(update.token, store);
1195
+ break;
1590
1196
  }
1591
- options.set(transactors, newValue);
1592
- };
1593
- const mySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
1594
- subject,
1595
- install: (s) => createWritableSelector(options, family, s),
1596
- get: getSelf,
1597
- set: setSelf,
1598
- type: `selector`
1599
- }), family && { family });
1600
- target.selectors.set(options.key, mySelector);
1601
- const initialValue = getSelf();
1602
- store.logger.info(`\u2728`, mySelector.type, mySelector.key, `=`, initialValue);
1603
- const token = {
1604
- key: options.key,
1605
- type: `selector`
1606
- };
1607
- if (family) {
1608
- token.family = family;
1609
1197
  }
1610
- return token;
1611
- };
1198
+ }
1199
+ function ingestDisposalEvent(update, applying, store) {
1200
+ switch (applying) {
1201
+ case `newValue`: {
1202
+ disposeFromStore(update.token, store);
1203
+ break;
1204
+ }
1205
+ case `oldValue`: {
1206
+ createInStore(update.token, store);
1207
+ store.valueMap.set(update.token.key, update.value);
1208
+ break;
1209
+ }
1210
+ }
1211
+ }
1212
+ function createInStore(token, store) {
1213
+ if (token.family) {
1214
+ const family = store.families.get(token.family.key);
1215
+ if (family) {
1216
+ const molecule = store.molecules.get(token.family.subKey);
1217
+ if (molecule) {
1218
+ growMoleculeInStore(molecule, family, store);
1219
+ return;
1220
+ }
1221
+ if (store.config.lifespan === `immortal`) {
1222
+ throw new Error(`No molecule found for key "${token.family.subKey}"`);
1223
+ }
1224
+ initFamilyMemberInStore(family, parseJson(token.family.subKey), store);
1225
+ }
1226
+ }
1227
+ }
1228
+ function ingestMoleculeCreationEvent(update, applying, store) {
1229
+ switch (applying) {
1230
+ case `newValue`:
1231
+ makeMoleculeInStore(
1232
+ store,
1233
+ update.context,
1234
+ update.family,
1235
+ update.token.key,
1236
+ ...update.params
1237
+ );
1238
+ break;
1239
+ case `oldValue`:
1240
+ disposeFromStore(update.token, store);
1241
+ break;
1242
+ }
1243
+ }
1244
+ function ingestMoleculeDisposalEvent(update, applying, store) {
1245
+ switch (applying) {
1246
+ case `newValue`:
1247
+ disposeFromStore(update.token, store);
1248
+ break;
1249
+ case `oldValue`:
1250
+ {
1251
+ const moleculeToken = makeMoleculeInStore(
1252
+ store,
1253
+ update.context,
1254
+ update.family,
1255
+ update.token.key
1256
+ );
1257
+ for (const [familyKey, value] of update.values) {
1258
+ const memberKey = `${familyKey}(${stringifyJson(moleculeToken.key)})`;
1259
+ const molecule = withdraw(moleculeToken, store);
1260
+ const alreadyCreated = molecule.tokens.has(memberKey);
1261
+ const family = store.families.get(familyKey);
1262
+ if (family && !alreadyCreated) {
1263
+ growMoleculeInStore(molecule, family, store);
1264
+ }
1265
+ store.valueMap.set(memberKey, value);
1266
+ }
1267
+ }
1268
+ break;
1269
+ }
1270
+ }
1612
1271
 
1613
- // internal/src/selector/create-standalone-selector.ts
1614
- function createStandaloneSelector(options, store) {
1615
- const isWritable = `set` in options;
1616
- if (isWritable) {
1617
- const state2 = createWritableSelector(options, void 0, store);
1618
- store.on.selectorCreation.next(state2);
1619
- return state2;
1272
+ // internal/src/ingest-updates/ingest-selector-update.ts
1273
+ function ingestSelectorUpdate(applying, selectorUpdate, store) {
1274
+ const updates = applying === `newValue` ? selectorUpdate.atomUpdates : [...selectorUpdate.atomUpdates].reverse();
1275
+ for (const atomUpdate of updates) {
1276
+ ingestAtomUpdate(applying, atomUpdate, store);
1620
1277
  }
1621
- const state = createReadonlySelector(options, void 0, store);
1622
- store.on.selectorCreation.next(state);
1623
- return state;
1624
1278
  }
1625
1279
 
1626
- // internal/src/selector/dispose-selector.ts
1627
- function disposeSelector(selectorToken, store) {
1280
+ // internal/src/ingest-updates/ingest-transaction-update.ts
1281
+ function ingestTransactionUpdate(applying, transactionUpdate, store) {
1282
+ const updates = applying === `newValue` ? transactionUpdate.updates : [...transactionUpdate.updates].reverse();
1283
+ for (const updateFromTransaction of updates) {
1284
+ switch (updateFromTransaction.type) {
1285
+ case `atom_update`:
1286
+ case `selector_update`:
1287
+ ingestAtomUpdate(applying, updateFromTransaction, store);
1288
+ break;
1289
+ case `state_creation`:
1290
+ ingestCreationEvent(updateFromTransaction, applying, store);
1291
+ break;
1292
+ case `state_disposal`:
1293
+ ingestDisposalEvent(updateFromTransaction, applying, store);
1294
+ break;
1295
+ case `molecule_creation`:
1296
+ ingestMoleculeCreationEvent(updateFromTransaction, applying, store);
1297
+ break;
1298
+ case `molecule_disposal`:
1299
+ ingestMoleculeDisposalEvent(updateFromTransaction, applying, store);
1300
+ break;
1301
+ case `transaction_update`:
1302
+ ingestTransactionUpdate(applying, updateFromTransaction, store);
1303
+ break;
1304
+ }
1305
+ }
1306
+ }
1307
+
1308
+ // internal/src/transaction/set-epoch-number.ts
1309
+ function setEpochNumberOfContinuity(continuityKey, newEpoch, store) {
1310
+ const isRoot = isRootStore(store);
1311
+ if (isRoot && continuityKey) {
1312
+ store.transactionMeta.epoch.set(continuityKey, newEpoch);
1313
+ }
1314
+ }
1315
+ function setEpochNumberOfAction(transactionKey, newEpoch, store) {
1316
+ const isRoot = isRootStore(store);
1317
+ if (!isRoot) {
1318
+ return;
1319
+ }
1320
+ const continuityKey = store.transactionMeta.actionContinuities.getRelatedKey(transactionKey);
1321
+ if (continuityKey !== void 0) {
1322
+ store.transactionMeta.epoch.set(continuityKey, newEpoch);
1323
+ }
1324
+ }
1325
+
1326
+ // internal/src/transaction/apply-transaction.ts
1327
+ var applyTransaction = (output, store) => {
1628
1328
  var _a;
1629
- const target = newest(store);
1630
- const { key } = selectorToken;
1631
- const selector = (_a = target.selectors.get(key)) != null ? _a : target.readonlySelectors.get(key);
1632
- if (!selector) {
1633
- store.logger.info(
1634
- `\u274C`,
1635
- `selector`,
1636
- key,
1637
- `Tried to dispose selector, but it does not exist in the store.`
1329
+ const child = newest(store);
1330
+ const { parent } = child;
1331
+ if (parent === null || !isChildStore(child) || ((_a = child.transactionMeta) == null ? void 0 : _a.phase) !== `building`) {
1332
+ store.logger.warn(
1333
+ `\u{1F41E}`,
1334
+ `transaction`,
1335
+ `???`,
1336
+ `applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`
1638
1337
  );
1639
- } else if (!selector.family) {
1640
- store.logger.error(
1641
- `\u274C`,
1642
- `selector`,
1643
- key,
1644
- `Standalone selectors cannot be disposed.`
1338
+ return;
1339
+ }
1340
+ child.transactionMeta.phase = `applying`;
1341
+ child.transactionMeta.update.output = output;
1342
+ parent.child = null;
1343
+ parent.on.transactionApplying.next(child.transactionMeta);
1344
+ const { updates } = child.transactionMeta.update;
1345
+ store.logger.info(
1346
+ `\u{1F6C4}`,
1347
+ `transaction`,
1348
+ child.transactionMeta.update.key,
1349
+ `Applying transaction with ${updates.length} updates:`,
1350
+ updates
1351
+ );
1352
+ ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
1353
+ if (isRootStore(parent)) {
1354
+ setEpochNumberOfAction(
1355
+ child.transactionMeta.update.key,
1356
+ child.transactionMeta.update.epoch,
1357
+ parent
1645
1358
  );
1646
- } else {
1647
- switch (selectorToken.type) {
1648
- case `selector`:
1649
- {
1650
- target.selectors.delete(key);
1651
- const family = withdraw(
1652
- { key: selector.family.key, type: `selector_family` },
1653
- store
1654
- );
1655
- family.subject.next({
1656
- type: `state_disposal`,
1657
- token: selectorToken
1658
- });
1659
- }
1359
+ const myTransaction = withdraw(
1360
+ { key: child.transactionMeta.update.key, type: `transaction` },
1361
+ store
1362
+ );
1363
+ myTransaction == null ? void 0 : myTransaction.subject.next(child.transactionMeta.update);
1364
+ store.logger.info(
1365
+ `\u{1F6EC}`,
1366
+ `transaction`,
1367
+ child.transactionMeta.update.key,
1368
+ `Finished applying transaction.`
1369
+ );
1370
+ } else if (isChildStore(parent)) {
1371
+ parent.transactionMeta.update.updates.push(child.transactionMeta.update);
1372
+ }
1373
+ parent.on.transactionApplying.next(null);
1374
+ };
1375
+
1376
+ // internal/src/transaction/assign-transaction-to-continuity.ts
1377
+ function assignTransactionToContinuity(continuityKey, transactionKey, store) {
1378
+ const isRoot = isRootStore(store);
1379
+ if (!isRoot) {
1380
+ return;
1381
+ }
1382
+ const { epoch, actionContinuities } = store.transactionMeta;
1383
+ actionContinuities.set(continuityKey, transactionKey);
1384
+ if (!epoch.has(continuityKey)) {
1385
+ epoch.set(continuityKey, -1);
1386
+ }
1387
+ }
1388
+
1389
+ // internal/src/lazy-map.ts
1390
+ var LazyMap = class extends Map {
1391
+ constructor(source) {
1392
+ super();
1393
+ this.source = source;
1394
+ this.deleted = /* @__PURE__ */ new Set();
1395
+ }
1396
+ get(key) {
1397
+ const has = super.has(key);
1398
+ if (has) {
1399
+ return super.get(key);
1400
+ }
1401
+ if (!this.deleted.has(key) && this.source.has(key)) {
1402
+ const value = this.source.get(key);
1403
+ return value;
1404
+ }
1405
+ return void 0;
1406
+ }
1407
+ set(key, value) {
1408
+ this.deleted.delete(key);
1409
+ return super.set(key, value);
1410
+ }
1411
+ hasOwn(key) {
1412
+ return super.has(key);
1413
+ }
1414
+ has(key) {
1415
+ return !this.deleted.has(key) && (super.has(key) || this.source.has(key));
1416
+ }
1417
+ delete(key) {
1418
+ this.deleted.add(key);
1419
+ return super.delete(key);
1420
+ }
1421
+ };
1422
+
1423
+ // internal/src/transaction/build-transaction.ts
1424
+ var buildTransaction = (key, params, store, id) => {
1425
+ const parent = newest(store);
1426
+ const childBase = {
1427
+ parent,
1428
+ child: null,
1429
+ on: parent.on,
1430
+ loggers: parent.loggers,
1431
+ logger: parent.logger,
1432
+ config: parent.config,
1433
+ atoms: new LazyMap(parent.atoms),
1434
+ atomsThatAreDefault: new Set(parent.atomsThatAreDefault),
1435
+ families: new LazyMap(parent.families),
1436
+ operation: { open: false },
1437
+ readonlySelectors: new LazyMap(parent.readonlySelectors),
1438
+ timelines: new LazyMap(parent.timelines),
1439
+ timelineTopics: new Junction(parent.timelineTopics.toJSON()),
1440
+ trackers: /* @__PURE__ */ new Map(),
1441
+ transactions: new LazyMap(parent.transactions),
1442
+ selectorAtoms: new Junction(parent.selectorAtoms.toJSON()),
1443
+ selectorGraph: new Junction(parent.selectorGraph.toJSON(), {
1444
+ makeContentKey: (...keys) => keys.sort().join(`:`)
1445
+ }),
1446
+ selectors: new LazyMap(parent.selectors),
1447
+ valueMap: new LazyMap(parent.valueMap),
1448
+ molecules: new LazyMap(parent.molecules),
1449
+ moleculeFamilies: new LazyMap(parent.moleculeFamilies),
1450
+ moleculeInProgress: parent.moleculeInProgress,
1451
+ miscResources: new LazyMap(parent.miscResources)
1452
+ };
1453
+ const epoch = getEpochNumberOfAction(key, store);
1454
+ const transactionMeta = {
1455
+ phase: `building`,
1456
+ update: {
1457
+ type: `transaction_update`,
1458
+ key,
1459
+ id,
1460
+ epoch: epoch === void 0 ? Number.NaN : epoch + 1,
1461
+ updates: [],
1462
+ params,
1463
+ output: void 0
1464
+ },
1465
+ transactors: {
1466
+ get: (token) => getFromStore(token, child),
1467
+ set: (token, value) => {
1468
+ setIntoStore(token, value, child);
1469
+ },
1470
+ run: (token, identifier = arbitrary()) => actUponStore(token, identifier, child),
1471
+ find: (token, k) => findInStore(token, k, child),
1472
+ seek: (token, k) => seekInStore(token, k, child),
1473
+ json: (token) => getJsonToken(token, child),
1474
+ make: (context, family, k, ...args) => makeMoleculeInStore(child, context, family, k, ...args),
1475
+ dispose: (token) => {
1476
+ disposeFromStore(token, child);
1477
+ },
1478
+ env: () => getEnvironmentData(child)
1479
+ }
1480
+ };
1481
+ const child = Object.assign(childBase, {
1482
+ transactionMeta
1483
+ });
1484
+ parent.child = child;
1485
+ store.logger.info(
1486
+ `\u{1F6EB}`,
1487
+ `transaction`,
1488
+ key,
1489
+ `Building transaction with params:`,
1490
+ params
1491
+ );
1492
+ return child;
1493
+ };
1494
+
1495
+ // internal/src/transaction/create-transaction.ts
1496
+ function createTransaction(options, store) {
1497
+ const newTransaction = {
1498
+ key: options.key,
1499
+ type: `transaction`,
1500
+ run: (params, id) => {
1501
+ const childStore = buildTransaction(options.key, params, store, id);
1502
+ try {
1503
+ const target2 = newest(store);
1504
+ const { transactors } = childStore.transactionMeta;
1505
+ const output = options.do(transactors, ...params);
1506
+ applyTransaction(output, target2);
1507
+ return output;
1508
+ } catch (thrown) {
1509
+ abortTransaction(target);
1510
+ store.logger.warn(`\u{1F4A5}`, `transaction`, options.key, `caught:`, thrown);
1511
+ throw thrown;
1512
+ }
1513
+ },
1514
+ install: (s) => createTransaction(options, s),
1515
+ subject: new Subject()
1516
+ };
1517
+ const target = newest(store);
1518
+ target.transactions.set(newTransaction.key, newTransaction);
1519
+ const token = deposit(newTransaction);
1520
+ store.on.transactionCreation.next(token);
1521
+ return token;
1522
+ }
1523
+
1524
+ // internal/src/transaction/get-epoch-number.ts
1525
+ function getContinuityKey(transactionKey, store) {
1526
+ const isRoot = isRootStore(store);
1527
+ const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
1528
+ return continuity;
1529
+ }
1530
+ function getEpochNumberOfContinuity(continuityKey, store) {
1531
+ const isRoot = isRootStore(store);
1532
+ const epoch = isRoot && continuityKey ? store.transactionMeta.epoch.get(continuityKey) : void 0;
1533
+ return epoch;
1534
+ }
1535
+ function getEpochNumberOfAction(transactionKey, store) {
1536
+ const isRoot = isRootStore(store);
1537
+ const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
1538
+ const epoch = isRoot && continuity !== void 0 ? store.transactionMeta.epoch.get(continuity) : void 0;
1539
+ return epoch;
1540
+ }
1541
+
1542
+ // internal/src/transaction/index.ts
1543
+ var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
1544
+
1545
+ // internal/src/store/store.ts
1546
+ var Store = class {
1547
+ constructor(config, store = null) {
1548
+ this.parent = null;
1549
+ this.child = null;
1550
+ this.valueMap = /* @__PURE__ */ new Map();
1551
+ this.atoms = /* @__PURE__ */ new Map();
1552
+ this.selectors = /* @__PURE__ */ new Map();
1553
+ this.readonlySelectors = /* @__PURE__ */ new Map();
1554
+ this.atomsThatAreDefault = /* @__PURE__ */ new Set();
1555
+ this.selectorAtoms = new Junction({
1556
+ between: [`selectorKey`, `atomKey`],
1557
+ cardinality: `n:n`
1558
+ });
1559
+ this.selectorGraph = new Junction(
1560
+ {
1561
+ between: [`upstreamSelectorKey`, `downstreamSelectorKey`],
1562
+ cardinality: `n:n`
1563
+ },
1564
+ {
1565
+ makeContentKey: (...keys) => keys.sort().join(`:`)
1566
+ }
1567
+ );
1568
+ this.trackers = /* @__PURE__ */ new Map();
1569
+ this.families = /* @__PURE__ */ new Map();
1570
+ this.transactions = /* @__PURE__ */ new Map();
1571
+ this.transactionMeta = {
1572
+ epoch: /* @__PURE__ */ new Map(),
1573
+ actionContinuities: new Junction({
1574
+ between: [`continuity`, `action`],
1575
+ cardinality: `1:n`
1576
+ })
1577
+ };
1578
+ this.timelines = /* @__PURE__ */ new Map();
1579
+ this.timelineTopics = new Junction({
1580
+ between: [`timelineKey`, `topicKey`],
1581
+ cardinality: `1:n`
1582
+ });
1583
+ this.molecules = /* @__PURE__ */ new Map();
1584
+ this.moleculeFamilies = /* @__PURE__ */ new Map();
1585
+ this.moleculeInProgress = null;
1586
+ this.miscResources = /* @__PURE__ */ new Map();
1587
+ this.on = {
1588
+ atomCreation: new Subject(),
1589
+ atomDisposal: new Subject(),
1590
+ selectorCreation: new Subject(),
1591
+ selectorDisposal: new Subject(),
1592
+ timelineCreation: new Subject(),
1593
+ transactionCreation: new Subject(),
1594
+ transactionApplying: new StatefulSubject(
1595
+ null
1596
+ ),
1597
+ operationClose: new Subject(),
1598
+ moleculeCreationStart: new Subject(),
1599
+ moleculeCreationDone: new Subject(),
1600
+ moleculeDisposal: new Subject()
1601
+ };
1602
+ this.operation = { open: false };
1603
+ this.config = {
1604
+ name: `IMPLICIT_STORE`,
1605
+ lifespan: `ephemeral`
1606
+ };
1607
+ this.loggers = [
1608
+ new AtomIOLogger(`warn`, (_, __, key) => !key.includes(`\u{1F441}\u200D\u{1F5E8}`))
1609
+ ];
1610
+ this.logger = {
1611
+ error: (...messages) => {
1612
+ for (const logger of this.loggers) logger.error(...messages);
1613
+ },
1614
+ info: (...messages) => {
1615
+ for (const logger of this.loggers) logger.info(...messages);
1616
+ },
1617
+ warn: (...messages) => {
1618
+ for (const logger of this.loggers) logger.warn(...messages);
1619
+ }
1620
+ };
1621
+ if (store !== null) {
1622
+ this.valueMap = new Map(store == null ? void 0 : store.valueMap);
1623
+ this.operation = __spreadValues({}, store == null ? void 0 : store.operation);
1624
+ if (isRootStore(store)) {
1625
+ this.transactionMeta = {
1626
+ epoch: new Map(store == null ? void 0 : store.transactionMeta.epoch),
1627
+ actionContinuities: new Junction(
1628
+ store == null ? void 0 : store.transactionMeta.actionContinuities.toJSON()
1629
+ )
1630
+ };
1631
+ }
1632
+ this.config = __spreadValues(__spreadValues({}, store == null ? void 0 : store.config), config);
1633
+ for (const [, family] of store.families) {
1634
+ family.install(this);
1635
+ }
1636
+ const mutableHelpers = /* @__PURE__ */ new Set();
1637
+ for (const [, atom] of store.atoms) {
1638
+ if (mutableHelpers.has(atom.key)) {
1639
+ continue;
1640
+ }
1641
+ atom.install(this);
1642
+ if (atom.type === `mutable_atom`) {
1643
+ const originalJsonToken = getJsonToken(atom, store);
1644
+ const originalUpdateToken = getUpdateToken(atom);
1645
+ mutableHelpers.add(originalJsonToken.key);
1646
+ mutableHelpers.add(originalUpdateToken.key);
1647
+ }
1648
+ }
1649
+ for (const [, selector] of store.readonlySelectors) {
1650
+ selector.install(this);
1651
+ }
1652
+ for (const [, selector] of store.selectors) {
1653
+ if (mutableHelpers.has(selector.key)) {
1654
+ continue;
1655
+ }
1656
+ selector.install(this);
1657
+ }
1658
+ for (const [, tx] of store.transactions) {
1659
+ tx.install(this);
1660
+ }
1661
+ for (const [, timeline] of store.timelines) {
1662
+ timeline.install(this);
1663
+ }
1664
+ }
1665
+ }
1666
+ };
1667
+ var IMPLICIT = {
1668
+ STORE_INTERNAL: void 0,
1669
+ get STORE() {
1670
+ var _a;
1671
+ return (_a = this.STORE_INTERNAL) != null ? _a : this.STORE_INTERNAL = new Store({
1672
+ name: `IMPLICIT_STORE`,
1673
+ lifespan: `ephemeral`
1674
+ });
1675
+ }
1676
+ };
1677
+ var clearStore = (store) => {
1678
+ const { config } = store;
1679
+ for (const disposable of store.miscResources.values()) {
1680
+ disposable[Symbol.dispose]();
1681
+ }
1682
+ Object.assign(store, new Store(config));
1683
+ store.config = config;
1684
+ };
1685
+ function withdraw(token, store) {
1686
+ let withdrawn;
1687
+ let target = store;
1688
+ while (target !== null) {
1689
+ switch (token.type) {
1690
+ case `atom`:
1691
+ case `mutable_atom`:
1692
+ withdrawn = target.atoms.get(token.key);
1693
+ break;
1694
+ case `selector`:
1695
+ withdrawn = target.selectors.get(token.key);
1696
+ break;
1697
+ case `readonly_selector`:
1698
+ withdrawn = target.readonlySelectors.get(token.key);
1699
+ break;
1700
+ case `atom_family`:
1701
+ case `mutable_atom_family`:
1702
+ case `selector_family`:
1703
+ case `readonly_selector_family`:
1704
+ withdrawn = target.families.get(token.key);
1705
+ break;
1706
+ case `timeline`:
1707
+ withdrawn = target.timelines.get(token.key);
1708
+ break;
1709
+ case `transaction`:
1710
+ withdrawn = target.transactions.get(token.key);
1660
1711
  break;
1661
- case `readonly_selector`:
1662
- {
1663
- target.readonlySelectors.delete(key);
1664
- const family = withdraw(
1665
- { key: selector.family.key, type: `readonly_selector_family` },
1666
- store
1667
- );
1668
- family.subject.next({
1669
- type: `state_disposal`,
1670
- token: selectorToken
1671
- });
1672
- }
1712
+ case `molecule`:
1713
+ withdrawn = target.molecules.get(stringifyJson(token.key));
1714
+ break;
1715
+ case `molecule_family`:
1716
+ withdrawn = target.moleculeFamilies.get(token.key);
1673
1717
  break;
1674
1718
  }
1675
- target.valueMap.delete(key);
1676
- target.selectorAtoms.delete(key);
1677
- const downstreamTokens = target.selectorGraph.getRelationEntries({ upstreamSelectorKey: key }).filter(([_, { source }]) => source === key).map(
1678
- ([downstreamSelectorKey]) => {
1679
- var _a2;
1680
- return (_a2 = target.selectors.get(downstreamSelectorKey)) != null ? _a2 : target.readonlySelectors.get(downstreamSelectorKey);
1681
- }
1682
- );
1683
- for (const downstreamToken of downstreamTokens) {
1684
- if (downstreamToken) {
1685
- disposeSelector(downstreamToken, store);
1686
- }
1687
- }
1688
- target.selectorGraph.delete(key);
1689
- store.logger.info(`\u{1F525}`, selectorToken.type, key, `deleted`);
1690
- if (isChildStore(target) && target.transactionMeta.phase === `building`) {
1691
- target.transactionMeta.update.updates.push({
1692
- type: `state_disposal`,
1693
- token: selectorToken
1694
- });
1695
- } else {
1696
- store.on.selectorDisposal.next(selectorToken);
1719
+ if (withdrawn) {
1720
+ return withdrawn;
1697
1721
  }
1722
+ target = target.child;
1698
1723
  }
1724
+ throw new NotFoundError(token, store);
1699
1725
  }
1700
1726
 
1701
1727
  // internal/src/subscribe/recall-state.ts
@@ -1892,7 +1918,7 @@ var Tracker = class {
1892
1918
  subscribeToState(
1893
1919
  latestUpdateState,
1894
1920
  ({ newValue, oldValue }) => {
1895
- const timelineId = target.timelineAtoms.getRelatedKey(
1921
+ const timelineId = target.timelineTopics.getRelatedKey(
1896
1922
  latestUpdateState.key
1897
1923
  );
1898
1924
  if (timelineId) {
@@ -2343,6 +2369,10 @@ function disposeAtom(atomToken, store) {
2343
2369
  token: atomToken,
2344
2370
  value: lastValue
2345
2371
  });
2372
+ const molecule = target.molecules.get(atom.family.subKey);
2373
+ if (molecule) {
2374
+ molecule.tokens.delete(key);
2375
+ }
2346
2376
  target.atoms.delete(key);
2347
2377
  target.valueMap.delete(key);
2348
2378
  const selectorKeys = target.selectorAtoms.getRelatedKeys(key);
@@ -2356,7 +2386,7 @@ function disposeAtom(atomToken, store) {
2356
2386
  }
2357
2387
  target.selectorAtoms.delete(key);
2358
2388
  target.atomsThatAreDefault.delete(key);
2359
- target.timelineAtoms.delete(key);
2389
+ target.timelineTopics.delete(key);
2360
2390
  if (atomToken.type === `mutable_atom`) {
2361
2391
  const updateToken = getUpdateToken(atomToken);
2362
2392
  disposeAtom(updateToken, store);
@@ -2373,26 +2403,123 @@ function disposeAtom(atomToken, store) {
2373
2403
  }
2374
2404
  }
2375
2405
  }
2376
-
2377
- // internal/src/timeline/add-atom-to-timeline.ts
2378
- var addAtomToTimeline = (atomToken, tl, store) => {
2406
+ function createTimeline(options, store, data) {
2407
+ var _a;
2408
+ const tl = __spreadProps(__spreadValues({
2409
+ type: `timeline`,
2410
+ key: options.key,
2411
+ at: 0,
2412
+ timeTraveling: null,
2413
+ selectorTime: null,
2414
+ transactionKey: null
2415
+ }, data), {
2416
+ history: (_a = data == null ? void 0 : data.history.map((update) => __spreadValues({}, update))) != null ? _a : [],
2417
+ install: (s) => createTimeline(options, s, tl),
2418
+ subject: new Subject(),
2419
+ subscriptions: /* @__PURE__ */ new Map()
2420
+ });
2421
+ if (options.shouldCapture) {
2422
+ tl.shouldCapture = options.shouldCapture;
2423
+ }
2424
+ const timelineKey = options.key;
2425
+ const target = newest(store);
2426
+ for (const initialTopic of options.scope) {
2427
+ switch (initialTopic.type) {
2428
+ case `atom`:
2429
+ case `mutable_atom`:
2430
+ {
2431
+ const atomToken = initialTopic;
2432
+ const atomKey = atomToken.key;
2433
+ let existingTimelineKey = target.timelineTopics.getRelatedKey(atomKey);
2434
+ if (`family` in atomToken) {
2435
+ const familyKey = atomToken.family.key;
2436
+ existingTimelineKey = target.timelineTopics.getRelatedKey(familyKey);
2437
+ if (existingTimelineKey) {
2438
+ store.logger.error(
2439
+ `\u274C`,
2440
+ `timeline`,
2441
+ options.key,
2442
+ `Failed to add atom "${atomKey}" because its family "${familyKey}" already belongs to timeline "${existingTimelineKey}"`
2443
+ );
2444
+ continue;
2445
+ }
2446
+ }
2447
+ if (existingTimelineKey) {
2448
+ store.logger.error(
2449
+ `\u274C`,
2450
+ `timeline`,
2451
+ options.key,
2452
+ `Failed to add atom "${atomKey}" because it already belongs to timeline "${existingTimelineKey}"`
2453
+ );
2454
+ continue;
2455
+ }
2456
+ addAtomToTimeline(atomToken, tl, store);
2457
+ }
2458
+ break;
2459
+ case `atom_family`:
2460
+ case `mutable_atom_family`:
2461
+ {
2462
+ const familyToken = initialTopic;
2463
+ const familyKey = familyToken.key;
2464
+ const existingTimelineKey = target.timelineTopics.getRelatedKey(familyKey);
2465
+ if (existingTimelineKey) {
2466
+ store.logger.error(
2467
+ `\u274C`,
2468
+ `timeline`,
2469
+ options.key,
2470
+ `Failed to add atom family "${familyKey}" because it already belongs to timeline "${existingTimelineKey}"`
2471
+ );
2472
+ continue;
2473
+ }
2474
+ addAtomFamilyToTimeline(familyToken, tl, store);
2475
+ }
2476
+ break;
2477
+ case `molecule_family`:
2478
+ {
2479
+ const familyToken = initialTopic;
2480
+ const familyKey = familyToken.key;
2481
+ const existingTimelineKey = target.timelineTopics.getRelatedKey(familyKey);
2482
+ if (existingTimelineKey) {
2483
+ store.logger.error(
2484
+ `\u274C`,
2485
+ `timeline`,
2486
+ options.key,
2487
+ `Failed to add molecule family "${familyKey}" because it already belongs to timeline "${existingTimelineKey}"`
2488
+ );
2489
+ continue;
2490
+ }
2491
+ addMoleculeFamilyToTimeline(familyToken, tl, store);
2492
+ }
2493
+ break;
2494
+ }
2495
+ }
2496
+ store.timelines.set(options.key, tl);
2497
+ const token = {
2498
+ key: timelineKey,
2499
+ type: `timeline`
2500
+ };
2501
+ store.on.timelineCreation.next(token);
2502
+ return token;
2503
+ }
2504
+ function addAtomToTimeline(atomToken, tl, store) {
2379
2505
  let maybeAtom = withdraw(atomToken, store);
2380
2506
  if (maybeAtom.type === `mutable_atom`) {
2381
2507
  const updateToken = getUpdateToken(maybeAtom);
2382
2508
  maybeAtom = withdraw(updateToken, store);
2383
2509
  }
2384
2510
  const atom = maybeAtom;
2385
- store.timelineAtoms.set({ atomKey: atom.key, timelineKey: tl.key });
2511
+ store.timelineTopics.set(
2512
+ { topicKey: atom.key, timelineKey: tl.key },
2513
+ { topicType: `atom` }
2514
+ );
2386
2515
  tl.subscriptions.set(
2387
2516
  atom.key,
2388
2517
  atom.subject.subscribe(`timeline`, (update) => {
2389
- var _a, _b, _c, _d, _e, _f;
2518
+ var _a, _b, _c, _d, _e;
2390
2519
  const target = newest(store);
2391
2520
  const currentSelectorKey = store.operation.open && store.operation.token.type === `selector` ? store.operation.token.key : null;
2392
2521
  const currentSelectorTime = store.operation.open && store.operation.token.type === `selector` ? store.operation.time : null;
2393
- const { transactionApplying } = target.on;
2394
- const currentTransactionKey = (_a = transactionApplying.state) == null ? void 0 : _a.update.key;
2395
- const currentTransactionInstanceId = (_b = transactionApplying.state) == null ? void 0 : _b.update.id;
2522
+ const txUpdateInProgress = (_a = target.on.transactionApplying.state) == null ? void 0 : _a.update;
2396
2523
  store.logger.info(
2397
2524
  `\u23F3`,
2398
2525
  `timeline`,
@@ -2403,109 +2530,11 @@ var addAtomToTimeline = (atomToken, tl, store) => {
2403
2530
  update.oldValue,
2404
2531
  `->`,
2405
2532
  update.newValue,
2406
- currentTransactionKey ? `in transaction "${currentTransactionKey}"` : currentSelectorKey ? `in selector "${currentSelectorKey}"` : ``
2533
+ txUpdateInProgress ? `in transaction "${txUpdateInProgress.key}"` : currentSelectorKey ? `in selector "${currentSelectorKey}"` : ``
2407
2534
  );
2408
2535
  if (tl.timeTraveling === null) {
2409
- if (tl.selectorTime && tl.selectorTime !== currentSelectorTime) {
2410
- const mostRecentUpdate = tl.history.at(-1);
2411
- if (mostRecentUpdate === void 0) {
2412
- throw new Error(
2413
- `Timeline "${tl.key}" has a selectorTime, but no history. This is most likely a bug in AtomIO.`
2414
- );
2415
- }
2416
- }
2417
- if (currentTransactionKey) {
2418
- const txToken = {
2419
- key: currentTransactionKey,
2420
- type: `transaction`
2421
- };
2422
- const currentTransaction = withdraw(txToken, store);
2423
- if (tl.transactionKey !== currentTransactionKey) {
2424
- if (tl.transactionKey) {
2425
- store.logger.error(
2426
- `\u{1F41E}`,
2427
- `timeline`,
2428
- tl.key,
2429
- `unable to resolve transaction "${tl.transactionKey}. This is probably a bug in AtomIO.`
2430
- );
2431
- }
2432
- tl.transactionKey = currentTransactionKey;
2433
- const unsubscribe = currentTransaction.subject.subscribe(
2434
- `timeline:${tl.key}`,
2435
- (transactionUpdate) => {
2436
- var _a2, _b2;
2437
- unsubscribe();
2438
- if (tl.timeTraveling === null && currentTransactionInstanceId) {
2439
- if (tl.at !== tl.history.length) {
2440
- tl.history.splice(tl.at);
2441
- }
2442
- const filterUpdates = (updates2) => updates2.filter((updateFromTx) => {
2443
- var _a3, _b3;
2444
- const newestStore = newest(store);
2445
- if (`updates` in updateFromTx) {
2446
- return true;
2447
- }
2448
- const atomOrFamilyKeys = newestStore.timelineAtoms.getRelatedKeys(tl.key);
2449
- if (!atomOrFamilyKeys) {
2450
- return false;
2451
- }
2452
- let key;
2453
- let familyKey;
2454
- switch (updateFromTx.type) {
2455
- case `state_creation`:
2456
- case `state_disposal`:
2457
- key = updateFromTx.token.key;
2458
- familyKey = (_a3 = updateFromTx.token.family) == null ? void 0 : _a3.key;
2459
- break;
2460
- case `molecule_creation`:
2461
- case `molecule_disposal`:
2462
- break;
2463
- default:
2464
- key = updateFromTx.key;
2465
- familyKey = (_b3 = updateFromTx.family) == null ? void 0 : _b3.key;
2466
- break;
2467
- }
2468
- if (key === void 0) {
2469
- return false;
2470
- }
2471
- if (atomOrFamilyKeys.has(key)) {
2472
- return true;
2473
- }
2474
- if (familyKey !== void 0) {
2475
- return atomOrFamilyKeys.has(familyKey);
2476
- }
2477
- return false;
2478
- }).map((updateFromTx) => {
2479
- if (`updates` in updateFromTx) {
2480
- return __spreadProps(__spreadValues({}, updateFromTx), {
2481
- updates: filterUpdates(updateFromTx.updates)
2482
- });
2483
- }
2484
- return updateFromTx;
2485
- });
2486
- const updates = filterUpdates(transactionUpdate.updates);
2487
- const timelineTransactionUpdate = __spreadProps(__spreadValues({
2488
- timestamp: Date.now()
2489
- }, transactionUpdate), {
2490
- updates
2491
- });
2492
- const willCapture = (_b2 = (_a2 = tl.shouldCapture) == null ? void 0 : _a2.call(tl, timelineTransactionUpdate, tl)) != null ? _b2 : true;
2493
- if (willCapture) {
2494
- tl.history.push(timelineTransactionUpdate);
2495
- tl.at = tl.history.length;
2496
- tl.subject.next(timelineTransactionUpdate);
2497
- }
2498
- }
2499
- tl.transactionKey = null;
2500
- store.logger.info(
2501
- `\u231B`,
2502
- `timeline`,
2503
- tl.key,
2504
- `got a transaction_update "${transactionUpdate.key}"`
2505
- );
2506
- }
2507
- );
2508
- }
2536
+ if (txUpdateInProgress) {
2537
+ joinTransaction(tl, txUpdateInProgress, store);
2509
2538
  } else if (currentSelectorKey && currentSelectorTime) {
2510
2539
  let latestUpdate = tl.history.at(-1);
2511
2540
  if (currentSelectorTime !== tl.selectorTime) {
@@ -2548,7 +2577,7 @@ var addAtomToTimeline = (atomToken, tl, store) => {
2548
2577
  }
2549
2578
  }
2550
2579
  if (latestUpdate) {
2551
- const willCaptureSelectorUpdate = (_d = (_c = tl.shouldCapture) == null ? void 0 : _c.call(tl, latestUpdate, tl)) != null ? _d : true;
2580
+ const willCaptureSelectorUpdate = (_c = (_b = tl.shouldCapture) == null ? void 0 : _b.call(tl, latestUpdate, tl)) != null ? _c : true;
2552
2581
  if (willCaptureSelectorUpdate) {
2553
2582
  tl.subject.next(latestUpdate);
2554
2583
  } else {
@@ -2572,7 +2601,7 @@ var addAtomToTimeline = (atomToken, tl, store) => {
2572
2601
  if (atom.family) {
2573
2602
  atomUpdate.family = atom.family;
2574
2603
  }
2575
- const willCapture = (_f = (_e = tl.shouldCapture) == null ? void 0 : _e.call(tl, atomUpdate, tl)) != null ? _f : true;
2604
+ const willCapture = (_e = (_d = tl.shouldCapture) == null ? void 0 : _d.call(tl, atomUpdate, tl)) != null ? _e : true;
2576
2605
  store.logger.info(
2577
2606
  `\u231B`,
2578
2607
  `timeline`,
@@ -2588,181 +2617,207 @@ var addAtomToTimeline = (atomToken, tl, store) => {
2588
2617
  }
2589
2618
  })
2590
2619
  );
2591
- };
2592
- function createTimeline(options, store, data) {
2593
- var _a, _b;
2594
- const tl = __spreadProps(__spreadValues({
2595
- type: `timeline`,
2596
- key: options.key,
2597
- at: 0,
2598
- timeTraveling: null,
2599
- selectorTime: null,
2600
- transactionKey: null
2601
- }, data), {
2602
- history: (_a = data == null ? void 0 : data.history.map((update) => __spreadValues({}, update))) != null ? _a : [],
2603
- install: (s) => createTimeline(options, s, tl),
2604
- subject: new Subject(),
2605
- subscriptions: /* @__PURE__ */ new Map()
2606
- });
2607
- if (options.shouldCapture) {
2608
- tl.shouldCapture = options.shouldCapture;
2620
+ }
2621
+ function addAtomFamilyToTimeline(atomFamilyToken, tl, store) {
2622
+ var _a;
2623
+ const family = withdraw(atomFamilyToken, store);
2624
+ store.timelineTopics.set(
2625
+ { topicKey: family.key, timelineKey: tl.key },
2626
+ { topicType: `atom_family` }
2627
+ );
2628
+ tl.subscriptions.set(
2629
+ family.key,
2630
+ family.subject.subscribe(`timeline`, (creationOrDisposal) => {
2631
+ handleStateLifecycleEvent(creationOrDisposal, tl, store);
2632
+ })
2633
+ );
2634
+ for (const atom of store.atoms.values()) {
2635
+ if (((_a = atom.family) == null ? void 0 : _a.key) === family.key) {
2636
+ addAtomToTimeline(atom, tl, store);
2637
+ }
2609
2638
  }
2610
- const timelineKey = options.key;
2611
- const target = newest(store);
2612
- for (const tokenOrFamily of options.scope) {
2613
- let atomKey = tokenOrFamily.key;
2614
- switch (tokenOrFamily.type) {
2615
- case `atom_family`:
2616
- case `mutable_atom_family`:
2617
- {
2618
- const familyToken = tokenOrFamily;
2619
- const family = withdraw(familyToken, store);
2620
- const familyKey = family.key;
2621
- target.timelineAtoms.set({ atomKey: familyKey, timelineKey });
2622
- tl.subscriptions.set(
2623
- family.key,
2624
- family.subject.subscribe(
2625
- `timeline:${options.key}`,
2626
- (creationOrDisposal) => {
2627
- handleStateLifecycleEvent(creationOrDisposal, tl, store);
2639
+ }
2640
+ function addMoleculeFamilyToTimeline(familyToken, tl, store) {
2641
+ store.timelineTopics.set(
2642
+ { topicKey: familyToken.key, timelineKey: tl.key },
2643
+ { topicType: `molecule_family` }
2644
+ );
2645
+ const family = store.moleculeFamilies.get(familyToken.key);
2646
+ if (family) {
2647
+ tl.subscriptions.set(
2648
+ familyToken.key,
2649
+ family.subject.subscribe(`timeline:${tl.key}`, (creationOrDisposal) => {
2650
+ var _a, _b, _c, _d;
2651
+ store.logger.info(
2652
+ `\u{1F41E}`,
2653
+ `timeline`,
2654
+ tl.key,
2655
+ `got a molecule creation or disposal`,
2656
+ creationOrDisposal
2657
+ );
2658
+ switch (creationOrDisposal.type) {
2659
+ case `molecule_creation`:
2660
+ {
2661
+ store.timelineTopics.set(
2662
+ {
2663
+ topicKey: creationOrDisposal.token.key,
2664
+ timelineKey: tl.key
2665
+ },
2666
+ { topicType: `molecule` }
2667
+ );
2668
+ const txUpdateInProgress = (_a = newest(store).on.transactionApplying.state) == null ? void 0 : _a.update;
2669
+ if (txUpdateInProgress) {
2670
+ joinTransaction(tl, txUpdateInProgress, store);
2671
+ } else if (tl.timeTraveling === null) {
2672
+ const event = Object.assign(creationOrDisposal, {
2673
+ timestamp: Date.now()
2674
+ });
2675
+ tl.history.push(event);
2676
+ tl.at = tl.history.length;
2677
+ tl.subject.next(event);
2628
2678
  }
2629
- )
2630
- );
2631
- for (const atom of target.atoms.values()) {
2632
- if (((_b = atom.family) == null ? void 0 : _b.key) === familyKey) {
2633
- addAtomToTimeline(atom, tl, store);
2634
- }
2635
- }
2636
- }
2637
- break;
2638
- case `atom`:
2639
- case `mutable_atom`:
2640
- {
2641
- let atom = withdraw(tokenOrFamily, store);
2642
- if (isMutable(atom)) {
2643
- const updateAtom = withdraw(getUpdateToken(atom), store);
2644
- atom = updateAtom;
2645
- atomKey = atom.key;
2646
- }
2647
- if (`family` in atom) {
2648
- const familyTimelineKey = target.timelineAtoms.getRelatedKey(
2649
- atom.family.key
2650
- );
2651
- if (familyTimelineKey) {
2652
- store.logger.error(
2653
- `\u274C`,
2654
- `timeline`,
2655
- options.key,
2656
- `Failed to add atom "${atom.key}" because its family "${atom.family.key}" already belongs to timeline "${familyTimelineKey}"`
2679
+ const molecule = withdraw(creationOrDisposal.token, store);
2680
+ for (const token of molecule.tokens.values()) {
2681
+ switch (token.type) {
2682
+ case `atom`:
2683
+ case `mutable_atom`:
2684
+ addAtomToTimeline(token, tl, store);
2685
+ break;
2686
+ }
2687
+ }
2688
+ tl.subscriptions.set(
2689
+ molecule.key,
2690
+ molecule.subject.subscribe(
2691
+ `timeline:${tl.key}`,
2692
+ (stateCreationOrDisposal) => {
2693
+ handleStateLifecycleEvent(stateCreationOrDisposal, tl, store);
2694
+ }
2695
+ )
2657
2696
  );
2658
- continue;
2659
2697
  }
2698
+ break;
2699
+ case `molecule_disposal`:
2700
+ {
2701
+ const txUpdateInProgress = (_b = newest(store).on.transactionApplying.state) == null ? void 0 : _b.update;
2702
+ if (txUpdateInProgress) {
2703
+ joinTransaction(tl, txUpdateInProgress, store);
2704
+ } else if (tl.timeTraveling === null) {
2705
+ const event = Object.assign(creationOrDisposal, {
2706
+ timestamp: Date.now()
2707
+ });
2708
+ tl.history.push(event);
2709
+ tl.at = tl.history.length;
2710
+ tl.subject.next(event);
2711
+ }
2712
+ const moleculeKey = creationOrDisposal.token.key;
2713
+ (_c = tl.subscriptions.get(moleculeKey)) == null ? void 0 : _c();
2714
+ tl.subscriptions.delete(moleculeKey);
2715
+ for (const [familyKey] of creationOrDisposal.values) {
2716
+ const stateKey = `${familyKey}(${stringifyJson(moleculeKey)})`;
2717
+ (_d = tl.subscriptions.get(stateKey)) == null ? void 0 : _d();
2718
+ tl.subscriptions.delete(stateKey);
2719
+ store.timelineTopics.delete(stateKey);
2720
+ }
2721
+ }
2722
+ break;
2723
+ }
2724
+ })
2725
+ );
2726
+ }
2727
+ }
2728
+ function joinTransaction(tl, txUpdateInProgress, store) {
2729
+ const currentTxKey = txUpdateInProgress.key;
2730
+ const currentTxInstanceId = txUpdateInProgress.id;
2731
+ const currentTxToken = {
2732
+ key: currentTxKey,
2733
+ type: `transaction`
2734
+ };
2735
+ const currentTransaction = withdraw(currentTxToken, store);
2736
+ if (currentTxKey && tl.transactionKey === null) {
2737
+ tl.transactionKey = currentTxKey;
2738
+ const unsubscribe = currentTransaction.subject.subscribe(
2739
+ `timeline:${tl.key}`,
2740
+ (transactionUpdate) => {
2741
+ var _a, _b;
2742
+ unsubscribe();
2743
+ tl.transactionKey = null;
2744
+ if (tl.timeTraveling === null && currentTxInstanceId) {
2745
+ if (tl.at !== tl.history.length) {
2746
+ tl.history.splice(tl.at);
2660
2747
  }
2661
- const existingTimelineKey = target.timelineAtoms.getRelatedKey(atomKey);
2662
- if (existingTimelineKey) {
2663
- store.logger.error(
2664
- `\u274C`,
2665
- `timeline`,
2666
- options.key,
2667
- `Failed to add atom "${atomKey}" because it already belongs to timeline "${existingTimelineKey}"`
2668
- );
2669
- continue;
2748
+ const timelineTopics = store.timelineTopics.getRelatedKeys(tl.key);
2749
+ const updates = filterTransactionUpdates(
2750
+ transactionUpdate.updates,
2751
+ timelineTopics
2752
+ );
2753
+ const timelineTransactionUpdate = __spreadProps(__spreadValues({
2754
+ timestamp: Date.now()
2755
+ }, transactionUpdate), {
2756
+ updates
2757
+ });
2758
+ const willCapture = (_b = (_a = tl.shouldCapture) == null ? void 0 : _a.call(tl, timelineTransactionUpdate, tl)) != null ? _b : true;
2759
+ if (willCapture) {
2760
+ tl.history.push(timelineTransactionUpdate);
2761
+ tl.at = tl.history.length;
2762
+ tl.subject.next(timelineTransactionUpdate);
2670
2763
  }
2671
- addAtomToTimeline(atom, tl, store);
2672
2764
  }
2765
+ }
2766
+ );
2767
+ }
2768
+ }
2769
+ function filterTransactionUpdates(updates, timelineTopics) {
2770
+ return updates.filter((updateFromTx) => {
2771
+ if (updateFromTx.type === `transaction_update`) {
2772
+ return true;
2773
+ }
2774
+ let key;
2775
+ switch (updateFromTx.type) {
2776
+ case `state_creation`:
2777
+ case `state_disposal`:
2778
+ case `molecule_creation`:
2779
+ case `molecule_disposal`:
2780
+ key = updateFromTx.token.key;
2673
2781
  break;
2674
- case `molecule_family`:
2675
- {
2676
- const family = store.moleculeFamilies.get(tokenOrFamily.key);
2677
- if (family) {
2678
- tl.subscriptions.set(
2679
- tokenOrFamily.key,
2680
- family.subject.subscribe(
2681
- `timeline:${options.key}`,
2682
- (creationOrDisposal) => {
2683
- var _a2, _b2;
2684
- switch (creationOrDisposal.type) {
2685
- case `molecule_creation`:
2686
- {
2687
- const molecule = store.molecules.get(
2688
- stringifyJson(creationOrDisposal.token.key)
2689
- );
2690
- if (molecule) {
2691
- const event = Object.assign(creationOrDisposal, {
2692
- timestamp: Date.now()
2693
- });
2694
- tl.history.push(event);
2695
- tl.at = tl.history.length;
2696
- tl.subject.next(event);
2697
- for (const token2 of molecule.tokens.values()) {
2698
- switch (token2.type) {
2699
- case `atom`:
2700
- case `mutable_atom`:
2701
- addAtomToTimeline(token2, tl, store);
2702
- break;
2703
- }
2704
- }
2705
- tl.subscriptions.set(
2706
- molecule.key,
2707
- molecule.subject.subscribe(
2708
- `timeline:${options.key}`,
2709
- (stateCreationOrDisposal) => {
2710
- handleStateLifecycleEvent(
2711
- stateCreationOrDisposal,
2712
- tl,
2713
- store
2714
- );
2715
- }
2716
- )
2717
- );
2718
- }
2719
- }
2720
- break;
2721
- case `molecule_disposal`:
2722
- (_a2 = tl.subscriptions.get(creationOrDisposal.token.key)) == null ? void 0 : _a2();
2723
- tl.subscriptions.delete(creationOrDisposal.token.key);
2724
- for (const familyKey of creationOrDisposal.familyKeys) {
2725
- const stateKey = `${familyKey}(${stringifyJson(
2726
- creationOrDisposal.token.key
2727
- )})`;
2728
- (_b2 = tl.subscriptions.get(stateKey)) == null ? void 0 : _b2();
2729
- tl.subscriptions.delete(stateKey);
2730
- }
2731
- break;
2732
- }
2733
- }
2734
- )
2735
- );
2736
- }
2737
- }
2782
+ default:
2783
+ key = updateFromTx.key;
2738
2784
  break;
2739
2785
  }
2740
- }
2741
- store.timelines.set(options.key, tl);
2742
- const token = {
2743
- key: timelineKey,
2744
- type: `timeline`
2745
- };
2746
- store.on.timelineCreation.next(token);
2747
- return token;
2786
+ return timelineTopics.has(key);
2787
+ }).map((updateFromTx) => {
2788
+ if (`updates` in updateFromTx) {
2789
+ return __spreadProps(__spreadValues({}, updateFromTx), {
2790
+ updates: filterTransactionUpdates(
2791
+ updateFromTx.updates,
2792
+ timelineTopics
2793
+ )
2794
+ });
2795
+ }
2796
+ return updateFromTx;
2797
+ });
2748
2798
  }
2749
2799
  function handleStateLifecycleEvent(event, tl, store) {
2750
- var _a;
2800
+ var _a, _b;
2751
2801
  const timestamp = Date.now();
2752
2802
  const timelineEvent = Object.assign(event, {
2753
2803
  timestamp
2754
2804
  });
2755
2805
  if (!tl.timeTraveling) {
2756
- tl.history.push(timelineEvent);
2757
- tl.at = tl.history.length;
2758
- tl.subject.next(timelineEvent);
2806
+ const txUpdateInProgress = (_a = newest(store).on.transactionApplying.state) == null ? void 0 : _a.update;
2807
+ if (txUpdateInProgress) {
2808
+ joinTransaction(tl, txUpdateInProgress, store);
2809
+ } else {
2810
+ tl.history.push(timelineEvent);
2811
+ tl.at = tl.history.length;
2812
+ tl.subject.next(timelineEvent);
2813
+ }
2759
2814
  }
2760
2815
  switch (event.type) {
2761
2816
  case `state_creation`:
2762
2817
  addAtomToTimeline(event.token, tl, store);
2763
2818
  break;
2764
2819
  case `state_disposal`:
2765
- (_a = tl.subscriptions.get(event.token.key)) == null ? void 0 : _a();
2820
+ (_b = tl.subscriptions.get(event.token.key)) == null ? void 0 : _b();
2766
2821
  tl.subscriptions.delete(event.token.key);
2767
2822
  break;
2768
2823
  }
@@ -2844,4 +2899,4 @@ var timeTravel = (action, token, store) => {
2844
2899
  );
2845
2900
  };
2846
2901
 
2847
- export { FamilyTracker, Future, IMPLICIT, LazyMap, Molecule, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, addAtomToTimeline, applyTransaction, arbitrary, assignTransactionToContinuity, become, buildTransaction, cacheValue, clearStore, closeOperation, createAtomFamily, createMoleculeFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelector, createReadonlySelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneAtom, createStandaloneSelector, createTimeline, createTransaction, createWritableSelector, deposit, disposeAtom, disposeFromStore, disposeMolecule, disposeSelector, evictCachedValue, findInStore, getContinuityKey, getEnvironmentData, getEpochNumberOfAction, getEpochNumberOfContinuity, getFromStore, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getUpdateToken, growMoleculeInStore, ingestAtomUpdate, ingestCreationEvent, ingestDisposalEvent, ingestMoleculeCreationEvent, ingestMoleculeDisposalEvent, ingestSelectorUpdate, ingestTransactionUpdate, initFamilyMemberInStore, isAtomDefault, isAtomKey, isChildStore, isDone, isMutable, isReadonlySelectorKey, isRootStore, isSelectorKey, isStateKey, isTransceiver, makeMoleculeInStore, markAtomAsDefault, markAtomAsNotDefault, markDone, newest, openOperation, readCachedValue, readOrComputeValue, registerSelector, seekInStore, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeToRootAtoms, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, updateSelectorAtoms, withdraw };
2902
+ export { FamilyTracker, Future, IMPLICIT, LazyMap, Molecule, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, applyTransaction, arbitrary, assignTransactionToContinuity, become, buildTransaction, cacheValue, clearStore, closeOperation, createAtomFamily, createMoleculeFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelector, createReadonlySelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneAtom, createStandaloneSelector, createTimeline, createTransaction, createWritableSelector, deposit, disposeAtom, disposeFromStore, disposeMolecule, disposeSelector, evictCachedValue, findInStore, getContinuityKey, getEnvironmentData, getEpochNumberOfAction, getEpochNumberOfContinuity, getFromStore, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getUpdateToken, growMoleculeInStore, ingestAtomUpdate, ingestCreationEvent, ingestDisposalEvent, ingestMoleculeCreationEvent, ingestMoleculeDisposalEvent, ingestSelectorUpdate, ingestTransactionUpdate, initFamilyMemberInStore, isAtomDefault, isAtomKey, isChildStore, isDone, isMutable, isReadonlySelectorKey, isRootStore, isSelectorKey, isStateKey, isTransceiver, makeMoleculeInStore, markAtomAsDefault, markAtomAsNotDefault, markDone, newest, openOperation, readCachedValue, readOrComputeValue, registerSelector, seekInStore, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeToRootAtoms, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, updateSelectorAtoms, withdraw };