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.
@@ -387,187 +387,69 @@ function isChildStore(store) {
387
387
  return `phase` in store.transactionMeta;
388
388
  }
389
389
 
390
- // internal/src/store/store.ts
391
- var Store = class {
392
- constructor(config, store = null) {
393
- this.parent = null;
394
- this.child = null;
395
- this.valueMap = /* @__PURE__ */ new Map();
396
- this.atoms = /* @__PURE__ */ new Map();
397
- this.selectors = /* @__PURE__ */ new Map();
398
- this.readonlySelectors = /* @__PURE__ */ new Map();
399
- this.trackers = /* @__PURE__ */ new Map();
400
- this.families = /* @__PURE__ */ new Map();
401
- this.timelines = /* @__PURE__ */ new Map();
402
- this.transactions = /* @__PURE__ */ new Map();
403
- this.atomsThatAreDefault = /* @__PURE__ */ new Set();
404
- this.timelineAtoms = new Junction({
405
- between: [`timelineKey`, `atomKey`],
406
- cardinality: `1:n`
407
- });
408
- this.selectorAtoms = new Junction({
409
- between: [`selectorKey`, `atomKey`],
410
- cardinality: `n:n`
411
- });
412
- this.selectorGraph = new Junction(
413
- {
414
- between: [`upstreamSelectorKey`, `downstreamSelectorKey`],
415
- cardinality: `n:n`
416
- },
417
- {
418
- makeContentKey: (...keys) => keys.sort().join(`:`)
419
- }
390
+ // internal/src/transaction/abort-transaction.ts
391
+ var abortTransaction = (store) => {
392
+ const target = newest(store);
393
+ if (!isChildStore(target)) {
394
+ store.logger.warn(
395
+ `\u{1F41E}`,
396
+ `transaction`,
397
+ `???`,
398
+ `abortTransaction called outside of a transaction. This is probably a bug in AtomIO.`
420
399
  );
421
- this.molecules = /* @__PURE__ */ new Map();
422
- this.moleculeFamilies = /* @__PURE__ */ new Map();
423
- this.miscResources = /* @__PURE__ */ new Map();
424
- this.on = {
425
- atomCreation: new Subject(),
426
- atomDisposal: new Subject(),
427
- selectorCreation: new Subject(),
428
- selectorDisposal: new Subject(),
429
- timelineCreation: new Subject(),
430
- transactionCreation: new Subject(),
431
- transactionApplying: new StatefulSubject(
432
- null
433
- ),
434
- operationClose: new Subject(),
435
- moleculeCreationStart: new Subject(),
436
- moleculeCreationDone: new Subject(),
437
- moleculeDisposal: new Subject()
438
- };
439
- this.operation = { open: false };
440
- this.transactionMeta = {
441
- epoch: /* @__PURE__ */ new Map(),
442
- actionContinuities: new Junction({
443
- between: [`continuity`, `action`],
444
- cardinality: `1:n`
445
- })
446
- };
447
- this.config = {
448
- name: `IMPLICIT_STORE`,
449
- lifespan: `ephemeral`
450
- };
451
- this.loggers = [
452
- new atom_io.AtomIOLogger(`warn`, (_, __, key) => !key.includes(`\u{1F441}\u200D\u{1F5E8}`))
453
- ];
454
- this.logger = {
455
- error: (...messages) => {
456
- for (const logger of this.loggers) logger.error(...messages);
457
- },
458
- info: (...messages) => {
459
- for (const logger of this.loggers) logger.info(...messages);
460
- },
461
- warn: (...messages) => {
462
- for (const logger of this.loggers) logger.warn(...messages);
463
- }
464
- };
465
- if (store !== null) {
466
- this.valueMap = new Map(store == null ? void 0 : store.valueMap);
467
- this.operation = __spreadValues({}, store == null ? void 0 : store.operation);
468
- if (isRootStore(store)) {
469
- this.transactionMeta = {
470
- epoch: new Map(store == null ? void 0 : store.transactionMeta.epoch),
471
- actionContinuities: new Junction(
472
- store == null ? void 0 : store.transactionMeta.actionContinuities.toJSON()
473
- )
474
- };
475
- }
476
- this.config = __spreadValues(__spreadValues({}, store == null ? void 0 : store.config), config);
477
- for (const [, family] of store.families) {
478
- family.install(this);
479
- }
480
- const mutableHelpers = /* @__PURE__ */ new Set();
481
- for (const [, atom] of store.atoms) {
482
- if (mutableHelpers.has(atom.key)) {
483
- continue;
484
- }
485
- atom.install(this);
486
- if (atom.type === `mutable_atom`) {
487
- const originalJsonToken = getJsonToken(atom, store);
488
- const originalUpdateToken = getUpdateToken(atom);
489
- mutableHelpers.add(originalJsonToken.key);
490
- mutableHelpers.add(originalUpdateToken.key);
491
- }
492
- }
493
- for (const [, selector] of store.readonlySelectors) {
494
- selector.install(this);
495
- }
496
- for (const [, selector] of store.selectors) {
497
- if (mutableHelpers.has(selector.key)) {
498
- continue;
499
- }
500
- selector.install(this);
501
- }
502
- for (const [, tx] of store.transactions) {
503
- tx.install(this);
504
- }
505
- for (const [, timeline] of store.timelines) {
506
- timeline.install(this);
507
- }
508
- }
400
+ return;
509
401
  }
402
+ store.logger.info(
403
+ `\u{1FA82}`,
404
+ `transaction`,
405
+ target.transactionMeta.update.key,
406
+ `Aborting transaction`
407
+ );
408
+ target.parent.child = null;
510
409
  };
511
- var IMPLICIT = {
512
- STORE_INTERNAL: void 0,
513
- get STORE() {
514
- var _a;
515
- return (_a = this.STORE_INTERNAL) != null ? _a : this.STORE_INTERNAL = new Store({
516
- name: `IMPLICIT_STORE`,
517
- lifespan: `ephemeral`
518
- });
410
+
411
+ // internal/src/not-found-error.ts
412
+ var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
413
+ function prettyPrintTokenType(token) {
414
+ switch (token.type) {
415
+ case `atom_family`:
416
+ return `Atom Family`;
417
+ case `molecule_family`:
418
+ return `Molecule Family`;
419
+ case `readonly_selector`:
420
+ return `Readonly Selector`;
421
+ case `readonly_selector_family`:
422
+ return `Readonly Selector Family`;
423
+ case `selector_family`:
424
+ return `Selector Family`;
425
+ default:
426
+ return capitalize(token.type);
519
427
  }
520
- };
521
- var clearStore = (store) => {
522
- const { config } = store;
523
- for (const disposable of store.miscResources.values()) {
524
- disposable[Symbol.dispose]();
428
+ }
429
+ var NotFoundError = class extends Error {
430
+ constructor(token, store) {
431
+ super(
432
+ `${prettyPrintTokenType(token)} "${token.key}" not found in store "${store.config.name}".`
433
+ );
525
434
  }
526
- Object.assign(store, new Store(config));
527
- store.config = config;
528
435
  };
529
- function withdraw(token, store) {
530
- let withdrawn;
531
- let target = store;
532
- while (target !== null) {
533
- switch (token.type) {
534
- case `atom`:
535
- case `mutable_atom`:
536
- withdrawn = target.atoms.get(token.key);
537
- break;
538
- case `selector`:
539
- withdrawn = target.selectors.get(token.key);
540
- break;
541
- case `readonly_selector`:
542
- withdrawn = target.readonlySelectors.get(token.key);
543
- break;
544
- case `atom_family`:
545
- case `mutable_atom_family`:
546
- case `selector_family`:
547
- case `readonly_selector_family`:
548
- withdrawn = target.families.get(token.key);
549
- break;
550
- case `timeline`:
551
- withdrawn = target.timelines.get(token.key);
552
- break;
553
- case `transaction`:
554
- withdrawn = target.transactions.get(token.key);
555
- break;
556
- case `molecule`:
557
- withdrawn = target.molecules.get(json.stringifyJson(token.key));
558
- break;
559
- case `molecule_family`:
560
- withdrawn = target.moleculeFamilies.get(token.key);
561
- break;
562
- }
563
- if (withdrawn) {
564
- return withdrawn;
436
+
437
+ // internal/src/transaction/act-upon-store.ts
438
+ function actUponStore(token, id, store) {
439
+ return (...parameters) => {
440
+ const tx = withdraw(token, store);
441
+ if (tx) {
442
+ return tx.run(parameters, id);
565
443
  }
566
- target = target.child;
567
- }
568
- throw new NotFoundError(token, store);
444
+ throw new NotFoundError(token, store);
445
+ };
569
446
  }
570
447
 
448
+ // internal/src/set-state/become.ts
449
+ var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(
450
+ originalThing instanceof Function ? originalThing() : originalThing
451
+ ) : nextVersionOfThing;
452
+
571
453
  // internal/src/get-state/read-or-compute-value.ts
572
454
  var readOrComputeValue = (state, target) => {
573
455
  if (target.valueMap.has(state.key)) {
@@ -588,176 +470,6 @@ var readOrComputeValue = (state, target) => {
588
470
  );
589
471
  return state.default instanceof Function ? state.default() : state.default;
590
472
  };
591
- function createRegularAtomFamily(options, store) {
592
- const subject = new Subject();
593
- const atomFamily = Object.assign(
594
- (key) => {
595
- const subKey = json.stringifyJson(key);
596
- const family = { key: options.key, subKey };
597
- const fullKey = `${options.key}(${subKey})`;
598
- const target = newest(store);
599
- const def = options.default;
600
- const individualOptions = {
601
- key: fullKey,
602
- default: def instanceof Function ? def(key) : def
603
- };
604
- if (options.effects) {
605
- individualOptions.effects = options.effects(key);
606
- }
607
- const token = createRegularAtom(individualOptions, family, target);
608
- subject.next({ type: `state_creation`, token });
609
- return token;
610
- },
611
- {
612
- key: options.key,
613
- type: `atom_family`,
614
- subject,
615
- install: (s) => createRegularAtomFamily(options, s)
616
- }
617
- );
618
- store.families.set(options.key, atomFamily);
619
- return atomFamily;
620
- }
621
-
622
- // internal/src/families/create-atom-family.ts
623
- function createAtomFamily(options, store) {
624
- const isMutable2 = `mutable` in options;
625
- if (isMutable2) {
626
- return createMutableAtomFamily(options, store);
627
- }
628
- return createRegularAtomFamily(options, store);
629
- }
630
- function createReadonlySelectorFamily(options, store) {
631
- const subject = new Subject();
632
- const readonlySelectorFamily = Object.assign(
633
- (key) => {
634
- const subKey = json.stringifyJson(key);
635
- const family = { key: options.key, subKey };
636
- const fullKey = `${options.key}(${subKey})`;
637
- const target = newest(store);
638
- const token = createReadonlySelector(
639
- {
640
- key: fullKey,
641
- get: options.get(key)
642
- },
643
- family,
644
- target
645
- );
646
- subject.next({ type: `state_creation`, token });
647
- return token;
648
- },
649
- {
650
- key: options.key,
651
- type: `readonly_selector_family`,
652
- subject,
653
- install: (s) => createReadonlySelectorFamily(options, s)
654
- }
655
- );
656
- store.families.set(options.key, readonlySelectorFamily);
657
- return readonlySelectorFamily;
658
- }
659
- function createWritableSelectorFamily(options, store) {
660
- const subject = new Subject();
661
- const selectorFamily = Object.assign(
662
- (key) => {
663
- const subKey = json.stringifyJson(key);
664
- const family = { key: options.key, subKey };
665
- const fullKey = `${options.key}(${subKey})`;
666
- const target = newest(store);
667
- const token = createWritableSelector(
668
- {
669
- key: fullKey,
670
- get: options.get(key),
671
- set: options.set(key)
672
- },
673
- family,
674
- target
675
- );
676
- subject.next({ type: `state_creation`, token });
677
- return token;
678
- },
679
- {
680
- key: options.key,
681
- type: `selector_family`,
682
- subject,
683
- install: (s) => createWritableSelectorFamily(options, s)
684
- }
685
- );
686
- store.families.set(options.key, selectorFamily);
687
- return selectorFamily;
688
- }
689
-
690
- // internal/src/families/create-selector-family.ts
691
- function createSelectorFamily(options, store) {
692
- const isWritable = `set` in options;
693
- if (isWritable) {
694
- return createWritableSelectorFamily(options, store);
695
- }
696
- return createReadonlySelectorFamily(options, store);
697
- }
698
-
699
- // internal/src/transaction/abort-transaction.ts
700
- var abortTransaction = (store) => {
701
- const target = newest(store);
702
- if (!isChildStore(target)) {
703
- store.logger.warn(
704
- `\u{1F41E}`,
705
- `transaction`,
706
- `???`,
707
- `abortTransaction called outside of a transaction. This is probably a bug in AtomIO.`
708
- );
709
- return;
710
- }
711
- store.logger.info(
712
- `\u{1FA82}`,
713
- `transaction`,
714
- target.transactionMeta.update.key,
715
- `Aborting transaction`
716
- );
717
- target.parent.child = null;
718
- };
719
-
720
- // internal/src/not-found-error.ts
721
- var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
722
- function prettyPrintTokenType(token) {
723
- switch (token.type) {
724
- case `atom_family`:
725
- return `Atom Family`;
726
- case `molecule_family`:
727
- return `Molecule Family`;
728
- case `readonly_selector`:
729
- return `Readonly Selector`;
730
- case `readonly_selector_family`:
731
- return `Readonly Selector Family`;
732
- case `selector_family`:
733
- return `Selector Family`;
734
- default:
735
- return capitalize(token.type);
736
- }
737
- }
738
- var NotFoundError = class extends Error {
739
- constructor(token, store) {
740
- super(
741
- `${prettyPrintTokenType(token)} "${token.key}" not found in store "${store.config.name}".`
742
- );
743
- }
744
- };
745
-
746
- // internal/src/transaction/act-upon-store.ts
747
- function actUponStore(token, id, store) {
748
- return (...parameters) => {
749
- const tx = withdraw(token, store);
750
- if (tx) {
751
- return tx.run(parameters, id);
752
- }
753
- throw new NotFoundError(token, store);
754
- };
755
- }
756
-
757
- // internal/src/set-state/become.ts
758
- var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(
759
- originalThing instanceof Function ? originalThing() : originalThing
760
- ) : nextVersionOfThing;
761
473
 
762
474
  // internal/src/operation.ts
763
475
  var openOperation = (token, store) => {
@@ -854,8 +566,9 @@ var emitUpdate = (state, update, store) => {
854
566
 
855
567
  // internal/src/set-state/evict-downstream.ts
856
568
  var evictDownStream = (atom, store) => {
857
- const downstreamKeys = store.selectorAtoms.getRelatedKeys(atom.key);
858
- store.logger.info(
569
+ const target = newest(store);
570
+ const downstreamKeys = target.selectorAtoms.getRelatedKeys(atom.key);
571
+ target.logger.info(
859
572
  `\u{1F9F9}`,
860
573
  atom.type,
861
574
  atom.key,
@@ -863,20 +576,20 @@ var evictDownStream = (atom, store) => {
863
576
  downstreamKeys != null ? downstreamKeys : `to evict`
864
577
  );
865
578
  if (downstreamKeys) {
866
- if (store.operation.open) {
867
- store.logger.info(
579
+ if (target.operation.open) {
580
+ target.logger.info(
868
581
  `\u{1F9F9}`,
869
582
  atom.type,
870
583
  atom.key,
871
- `[ ${[...store.operation.done].join(`, `)} ] already done`
584
+ `[ ${[...target.operation.done].join(`, `)} ] already done`
872
585
  );
873
586
  }
874
587
  for (const key of downstreamKeys) {
875
- if (isDone(key, store)) {
588
+ if (isDone(key, target)) {
876
589
  continue;
877
590
  }
878
- evictCachedValue(key, store);
879
- markDone(key, store);
591
+ evictCachedValue(key, target);
592
+ markDone(key, target);
880
593
  }
881
594
  }
882
595
  };
@@ -1012,574 +725,463 @@ function ingestAtomUpdate(applying, atomUpdate, store) {
1012
725
  }
1013
726
  setIntoStore(token, value, store);
1014
727
  }
1015
-
1016
- // internal/src/molecule/create-molecule-family.ts
1017
- function createMoleculeFamily(options, store) {
1018
- var _a;
728
+ function createRegularAtomFamily(options, store) {
1019
729
  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;
730
+ const atomFamily = Object.assign(
731
+ (key) => {
732
+ const subKey = json.stringifyJson(key);
733
+ const family = { key: options.key, subKey };
734
+ const fullKey = `${options.key}(${subKey})`;
735
+ const target = newest(store);
736
+ const def = options.default;
737
+ const individualOptions = {
738
+ key: fullKey,
739
+ default: def instanceof Function ? def(key) : def
740
+ };
741
+ if (options.effects) {
742
+ individualOptions.effects = options.effects(key);
743
+ }
744
+ const token = createRegularAtom(individualOptions, family, target);
745
+ subject.next({ type: `state_creation`, token });
746
+ return token;
747
+ },
748
+ {
749
+ key: options.key,
750
+ type: `atom_family`,
751
+ subject,
752
+ install: (s) => createRegularAtomFamily(options, s)
753
+ }
754
+ );
755
+ store.families.set(options.key, atomFamily);
756
+ return atomFamily;
1031
757
  }
1032
758
 
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
- if (isTransaction) {
1039
- store.transactionMeta.update.updates.push({
1040
- type: `state_creation`,
1041
- token: stateToken
1042
- });
1043
- } else {
1044
- molecule.subject.next({ type: `state_creation`, token: stateToken });
759
+ // internal/src/families/create-atom-family.ts
760
+ function createAtomFamily(options, store) {
761
+ const isMutable2 = `mutable` in options;
762
+ if (isMutable2) {
763
+ return createMutableAtomFamily(options, store);
1045
764
  }
1046
- return stateToken;
765
+ return createRegularAtomFamily(options, store);
1047
766
  }
1048
767
 
1049
- // internal/src/get-environment-data.ts
1050
- function getEnvironmentData(store) {
1051
- return {
1052
- store
1053
- };
1054
- }
768
+ // internal/src/keys.ts
769
+ var isAtomKey = (key, store) => newest(store).atoms.has(key);
770
+ var isSelectorKey = (key, store) => newest(store).selectors.has(key);
771
+ var isReadonlySelectorKey = (key, store) => newest(store).readonlySelectors.has(key);
772
+ var isStateKey = (key, store) => isAtomKey(key, store) || isSelectorKey(key, store) || isReadonlySelectorKey(key, store);
1055
773
 
1056
- // internal/src/get-state/get-from-store.ts
1057
- function getFromStore(token, store) {
1058
- if (token.type === `molecule`) {
1059
- try {
1060
- const molecule = withdraw(token, store);
1061
- return molecule.instance;
1062
- } catch (_) {
1063
- return void 0;
1064
- }
1065
- }
1066
- const state = withdraw(token, store);
1067
- return readOrComputeValue(state, store);
1068
- }
1069
- var Molecule = class {
1070
- constructor(ctx, key, family) {
1071
- this.key = key;
1072
- this.type = `molecule`;
1073
- this.subject = new Subject();
1074
- this.tokens = /* @__PURE__ */ new Map();
1075
- this.above = /* @__PURE__ */ new Map();
1076
- this.below = /* @__PURE__ */ new Map();
1077
- this.joins = /* @__PURE__ */ new Map();
1078
- this.stringKey = json.stringifyJson(key);
1079
- if (family) {
1080
- this.family = family;
1081
- }
1082
- if (ctx) {
1083
- if (Array.isArray(ctx)) {
1084
- for (const molecule of ctx) {
1085
- this.above.set(molecule.stringKey, molecule);
1086
- }
1087
- } else {
1088
- this.above.set(ctx.stringKey, ctx);
1089
- }
1090
- }
1091
- }
774
+ // internal/src/selector/get-selector-dependency-keys.ts
775
+ var getSelectorDependencyKeys = (key, store) => {
776
+ const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(source, store));
777
+ return sources;
1092
778
  };
1093
779
 
1094
- // internal/src/molecule/make-molecule-in-store.ts
1095
- function makeMoleculeInStore(store, context, familyToken, key, ...params) {
1096
- const target = newest(store);
1097
- const token = {
1098
- type: `molecule`,
1099
- key,
1100
- family: familyToken
1101
- };
1102
- const contextArray = Array.isArray(context) ? context : [context];
1103
- const owners = contextArray.map((ctx) => {
1104
- if (ctx instanceof Molecule) {
1105
- return ctx;
1106
- }
1107
- const stringKey = json.stringifyJson(ctx.key);
1108
- const molecule2 = store.molecules.get(stringKey);
1109
- if (!molecule2) {
780
+ // internal/src/selector/trace-selector-atoms.ts
781
+ var traceSelectorAtoms = (selectorKey, directDependencyKey, store) => {
782
+ const rootKeys = [];
783
+ const indirectDependencyKeys = getSelectorDependencyKeys(
784
+ directDependencyKey,
785
+ store
786
+ );
787
+ let depth = 0;
788
+ while (indirectDependencyKeys.length > 0) {
789
+ const indirectDependencyKey = indirectDependencyKeys.shift();
790
+ ++depth;
791
+ if (depth > 99999) {
1110
792
  throw new Error(
1111
- `Molecule ${stringKey} not found in store "${store.config.name}"`
793
+ `Maximum selector dependency depth exceeded (> 99999) in selector "${selectorKey}". This is likely due to a circular dependency.`
1112
794
  );
1113
795
  }
1114
- return molecule2;
1115
- });
1116
- const family = withdraw(familyToken, store);
1117
- const molecule = new Molecule(owners, key, family);
1118
- target.molecules.set(json.stringifyJson(key), molecule);
1119
- for (const owner of owners) {
1120
- owner.below.set(molecule.stringKey, molecule);
796
+ if (!isAtomKey(indirectDependencyKey, store)) {
797
+ indirectDependencyKeys.push(
798
+ ...getSelectorDependencyKeys(indirectDependencyKey, store)
799
+ );
800
+ } else if (!rootKeys.includes(indirectDependencyKey)) {
801
+ rootKeys.push(indirectDependencyKey);
802
+ }
1121
803
  }
1122
- const transactors = {
1123
- get: (t) => getFromStore(t, newest(store)),
1124
- set: (t, newValue) => {
1125
- setIntoStore(t, newValue, newest(store));
1126
- },
1127
- seek: (t, k) => seekInStore(t, k, newest(store)),
1128
- json: (t) => getJsonToken(t, newest(store)),
1129
- run: (t, i = arbitrary()) => actUponStore(t, i, newest(store)),
1130
- make: (ctx, f, k, ...args) => makeMoleculeInStore(newest(store), ctx, f, k, ...args),
1131
- dispose: (t) => {
1132
- disposeFromStore(t, newest(store));
1133
- },
1134
- env: () => getEnvironmentData(newest(store)),
1135
- bond: (f) => growMoleculeInStore(
1136
- molecule,
1137
- withdraw(f, store),
1138
- newest(store)
1139
- ),
1140
- claim: (below, options) => {
1141
- const { exclusive } = options;
1142
- const belowMolecule = newest(store).molecules.get(json.stringifyJson(below.key));
1143
- if (belowMolecule) {
1144
- if (exclusive) {
1145
- for (const value of belowMolecule.above.values()) {
1146
- value.below.delete(belowMolecule.stringKey);
1147
- }
1148
- belowMolecule.above.clear();
1149
- belowMolecule.above.set(molecule.stringKey, molecule);
1150
- molecule.below.set(belowMolecule.stringKey, belowMolecule);
1151
- } else {
1152
- belowMolecule.above.set(molecule.stringKey, molecule);
1153
- molecule.below.set(belowMolecule.stringKey, belowMolecule);
1154
- }
804
+ return rootKeys;
805
+ };
806
+ var traceAllSelectorAtoms = (selector, store) => {
807
+ const selectorKey = selector.key;
808
+ const directDependencyKeys = getSelectorDependencyKeys(selectorKey, store);
809
+ return directDependencyKeys.flatMap(
810
+ (depKey) => isAtomKey(depKey, store) ? depKey : traceSelectorAtoms(selectorKey, depKey, store)
811
+ );
812
+ };
813
+
814
+ // internal/src/selector/update-selector-atoms.ts
815
+ var updateSelectorAtoms = (selectorKey, dependency, store) => {
816
+ const target = newest(store);
817
+ if (dependency.type === `atom` || dependency.type === `mutable_atom`) {
818
+ target.selectorAtoms.set({
819
+ selectorKey,
820
+ atomKey: dependency.key
821
+ });
822
+ store.logger.info(
823
+ `\u{1F50D}`,
824
+ `selector`,
825
+ selectorKey,
826
+ `discovers root atom "${dependency.key}"`
827
+ );
828
+ } else {
829
+ const rootKeys = traceSelectorAtoms(selectorKey, dependency.key, store);
830
+ store.logger.info(
831
+ `\u{1F50D}`,
832
+ `selector`,
833
+ selectorKey,
834
+ `discovers root atoms: [ ${rootKeys.map((key) => `"${key}"`).join(`, `)} ]`
835
+ );
836
+ for (const atomKey of rootKeys) {
837
+ target.selectorAtoms = target.selectorAtoms.set({
838
+ selectorKey,
839
+ atomKey
840
+ });
841
+ }
842
+ }
843
+ };
844
+
845
+ // internal/src/selector/register-selector.ts
846
+ var registerSelector = (selectorKey, store) => ({
847
+ get: (dependency) => {
848
+ const target = newest(store);
849
+ const dependencyState = withdraw(dependency, store);
850
+ const dependencyValue = readOrComputeValue(dependencyState, store);
851
+ store.logger.info(
852
+ `\u{1F50C}`,
853
+ `selector`,
854
+ selectorKey,
855
+ `registers dependency ( "${dependency.key}" =`,
856
+ dependencyValue,
857
+ `)`
858
+ );
859
+ target.selectorGraph.set(
860
+ {
861
+ upstreamSelectorKey: dependency.key,
862
+ downstreamSelectorKey: selectorKey
863
+ },
864
+ {
865
+ source: dependency.key
1155
866
  }
1156
- },
1157
- join: (joinToken) => {
1158
- const join = data.getJoin(joinToken, store);
1159
- join.molecules.set(json.stringifyJson(key), molecule);
1160
- molecule.joins.set(joinToken.key, join);
1161
- return joinToken;
1162
- },
1163
- spawn: (f, k, ...p) => makeMoleculeInStore(
1164
- newest(store),
1165
- [molecule],
1166
- withdraw(f, store),
1167
- k,
1168
- ...p
1169
- )
867
+ );
868
+ updateSelectorAtoms(selectorKey, dependency, store);
869
+ return dependencyValue;
870
+ },
871
+ set: (WritableToken, newValue) => {
872
+ const target = newest(store);
873
+ const state = withdraw(WritableToken, target);
874
+ setAtomOrSelector(state, newValue, target);
875
+ },
876
+ find: (token, key) => findInStore(token, key, store),
877
+ seek: (token, key) => seekInStore(token, key, store),
878
+ json: (token) => getJsonToken(token, store)
879
+ });
880
+
881
+ // internal/src/selector/create-readonly-selector.ts
882
+ var createReadonlySelector = (options, family, store) => {
883
+ const target = newest(store);
884
+ const subject = new Subject();
885
+ const { get, find, seek, json } = registerSelector(options.key, target);
886
+ const getSelf = () => {
887
+ const value = options.get({ get, find, seek, json });
888
+ cacheValue(options.key, value, subject, newest(store));
889
+ return value;
1170
890
  };
1171
- const Constructor = family.new;
1172
- molecule.instance = new Constructor(transactors, token.key, ...params);
1173
- const update = {
1174
- type: `molecule_creation`,
1175
- token,
1176
- family,
1177
- context: contextArray,
1178
- params
891
+ const readonlySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
892
+ subject,
893
+ install: (s) => createReadonlySelector(options, family, s),
894
+ get: getSelf,
895
+ type: `readonly_selector`
896
+ }), family && { family });
897
+ target.readonlySelectors.set(options.key, readonlySelector);
898
+ const initialValue = getSelf();
899
+ store.logger.info(
900
+ `\u2728`,
901
+ readonlySelector.type,
902
+ readonlySelector.key,
903
+ `=`,
904
+ initialValue
905
+ );
906
+ const token = {
907
+ key: options.key,
908
+ type: `readonly_selector`
1179
909
  };
1180
- const isTransaction = isChildStore(target) && target.transactionMeta.phase === `building`;
1181
- if (isTransaction) {
1182
- target.transactionMeta.update.updates.push(update);
1183
- } else {
1184
- family.subject.next(update);
910
+ if (family) {
911
+ token.family = family;
1185
912
  }
1186
913
  return token;
1187
- }
914
+ };
1188
915
 
1189
- // internal/src/ingest-updates/ingest-creation-disposal.ts
1190
- function ingestCreationEvent(update, applying, store) {
1191
- switch (applying) {
1192
- case `newValue`: {
1193
- createInStore(update.token, store);
1194
- break;
1195
- }
1196
- case `oldValue`: {
1197
- disposeFromStore(update.token, store);
1198
- break;
916
+ // internal/src/selector/create-writable-selector.ts
917
+ var createWritableSelector = (options, family, store) => {
918
+ const target = newest(store);
919
+ const subject = new Subject();
920
+ const transactors = registerSelector(options.key, target);
921
+ const { find, get, seek, json } = transactors;
922
+ const readonlyTransactors = { find, get, seek, json };
923
+ const getSelf = (innerTarget = newest(store)) => {
924
+ const value = options.get(readonlyTransactors);
925
+ cacheValue(options.key, value, subject, innerTarget);
926
+ return value;
927
+ };
928
+ const setSelf = (next) => {
929
+ const innerTarget = newest(store);
930
+ const oldValue = getSelf(innerTarget);
931
+ const newValue = become(next)(oldValue);
932
+ store.logger.info(
933
+ `\u{1F4DD}`,
934
+ `selector`,
935
+ options.key,
936
+ `set (`,
937
+ oldValue,
938
+ `->`,
939
+ newValue,
940
+ `)`
941
+ );
942
+ cacheValue(options.key, newValue, subject, innerTarget);
943
+ markDone(options.key, innerTarget);
944
+ if (isRootStore(innerTarget)) {
945
+ subject.next({ newValue, oldValue });
1199
946
  }
947
+ options.set(transactors, newValue);
948
+ };
949
+ const mySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
950
+ subject,
951
+ install: (s) => createWritableSelector(options, family, s),
952
+ get: getSelf,
953
+ set: setSelf,
954
+ type: `selector`
955
+ }), family && { family });
956
+ target.selectors.set(options.key, mySelector);
957
+ const initialValue = getSelf();
958
+ store.logger.info(`\u2728`, mySelector.type, mySelector.key, `=`, initialValue);
959
+ const token = {
960
+ key: options.key,
961
+ type: `selector`
962
+ };
963
+ if (family) {
964
+ token.family = family;
1200
965
  }
1201
- }
1202
- function ingestDisposalEvent(update, applying, store) {
1203
- switch (applying) {
1204
- case `newValue`: {
1205
- disposeFromStore(update.token, store);
1206
- break;
1207
- }
1208
- case `oldValue`: {
1209
- createInStore(update.token, store);
1210
- store.valueMap.set(update.token.key, update.value);
1211
- break;
1212
- }
966
+ return token;
967
+ };
968
+
969
+ // internal/src/selector/create-standalone-selector.ts
970
+ function createStandaloneSelector(options, store) {
971
+ const isWritable = `set` in options;
972
+ if (isWritable) {
973
+ const state2 = createWritableSelector(options, void 0, store);
974
+ store.on.selectorCreation.next(state2);
975
+ return state2;
1213
976
  }
977
+ const state = createReadonlySelector(options, void 0, store);
978
+ store.on.selectorCreation.next(state);
979
+ return state;
1214
980
  }
1215
- function createInStore(token, store) {
1216
- if (token.family) {
1217
- const family = store.families.get(token.family.key);
1218
- if (family) {
1219
- const molecule = store.molecules.get(token.family.subKey);
1220
- if (molecule) {
1221
- growMoleculeInStore(molecule, family, store);
1222
- return;
981
+
982
+ // internal/src/selector/dispose-selector.ts
983
+ function disposeSelector(selectorToken, store) {
984
+ var _a;
985
+ const target = newest(store);
986
+ const { key } = selectorToken;
987
+ const selector = (_a = target.selectors.get(key)) != null ? _a : target.readonlySelectors.get(key);
988
+ if (!selector) {
989
+ store.logger.info(
990
+ `\u274C`,
991
+ `selector`,
992
+ key,
993
+ `Tried to dispose selector, but it does not exist in the store.`
994
+ );
995
+ } else if (!selector.family) {
996
+ store.logger.error(
997
+ `\u274C`,
998
+ `selector`,
999
+ key,
1000
+ `Standalone selectors cannot be disposed.`
1001
+ );
1002
+ } else {
1003
+ const molecule = target.molecules.get(selector.family.subKey);
1004
+ if (molecule) {
1005
+ molecule.tokens.delete(key);
1006
+ }
1007
+ switch (selectorToken.type) {
1008
+ case `selector`:
1009
+ {
1010
+ target.selectors.delete(key);
1011
+ const family = withdraw(
1012
+ { key: selector.family.key, type: `selector_family` },
1013
+ store
1014
+ );
1015
+ family.subject.next({
1016
+ type: `state_disposal`,
1017
+ token: selectorToken
1018
+ });
1019
+ }
1020
+ break;
1021
+ case `readonly_selector`:
1022
+ {
1023
+ target.readonlySelectors.delete(key);
1024
+ const family = withdraw(
1025
+ { key: selector.family.key, type: `readonly_selector_family` },
1026
+ store
1027
+ );
1028
+ family.subject.next({
1029
+ type: `state_disposal`,
1030
+ token: selectorToken
1031
+ });
1032
+ }
1033
+ break;
1034
+ }
1035
+ target.valueMap.delete(key);
1036
+ target.selectorAtoms.delete(key);
1037
+ const downstreamTokens = target.selectorGraph.getRelationEntries({ upstreamSelectorKey: key }).filter(([_, { source }]) => source === key).map(
1038
+ ([downstreamSelectorKey]) => {
1039
+ var _a2;
1040
+ return (_a2 = target.selectors.get(downstreamSelectorKey)) != null ? _a2 : target.readonlySelectors.get(downstreamSelectorKey);
1223
1041
  }
1224
- if (store.config.lifespan === `immortal`) {
1225
- throw new Error(`No molecule found for key "${token.family.subKey}"`);
1042
+ );
1043
+ for (const downstreamToken of downstreamTokens) {
1044
+ if (downstreamToken) {
1045
+ disposeSelector(downstreamToken, store);
1226
1046
  }
1227
- initFamilyMemberInStore(family, json.parseJson(token.family.subKey), store);
1047
+ }
1048
+ target.selectorGraph.delete(key);
1049
+ store.logger.info(`\u{1F525}`, selectorToken.type, key, `deleted`);
1050
+ if (isChildStore(target) && target.transactionMeta.phase === `building`) {
1051
+ target.transactionMeta.update.updates.push({
1052
+ type: `state_disposal`,
1053
+ token: selectorToken
1054
+ });
1055
+ } else {
1056
+ store.on.selectorDisposal.next(selectorToken);
1228
1057
  }
1229
1058
  }
1230
1059
  }
1231
- function ingestMoleculeCreationEvent(update, applying, store) {
1232
- switch (applying) {
1233
- case `newValue`:
1234
- makeMoleculeInStore(
1235
- store,
1236
- update.context[0],
1237
- update.family,
1238
- update.token.key,
1239
- ...update.params
1060
+
1061
+ // internal/src/families/create-readonly-selector-family.ts
1062
+ function createReadonlySelectorFamily(options, store) {
1063
+ const subject = new Subject();
1064
+ const readonlySelectorFamily = Object.assign(
1065
+ (key) => {
1066
+ const subKey = json.stringifyJson(key);
1067
+ const family = { key: options.key, subKey };
1068
+ const fullKey = `${options.key}(${subKey})`;
1069
+ const target = newest(store);
1070
+ const token = createReadonlySelector(
1071
+ {
1072
+ key: fullKey,
1073
+ get: options.get(key)
1074
+ },
1075
+ family,
1076
+ target
1240
1077
  );
1241
- break;
1242
- case `oldValue`:
1243
- disposeFromStore(update.token, store);
1244
- break;
1245
- }
1078
+ subject.next({ type: `state_creation`, token });
1079
+ return token;
1080
+ },
1081
+ {
1082
+ key: options.key,
1083
+ type: `readonly_selector_family`,
1084
+ subject,
1085
+ install: (s) => createReadonlySelectorFamily(options, s)
1086
+ }
1087
+ );
1088
+ store.families.set(options.key, readonlySelectorFamily);
1089
+ return readonlySelectorFamily;
1246
1090
  }
1247
- function ingestMoleculeDisposalEvent(update, applying, store) {
1248
- switch (applying) {
1249
- case `newValue`:
1250
- disposeFromStore(update.token, store);
1251
- break;
1252
- case `oldValue`:
1253
- makeMoleculeInStore(
1254
- store,
1255
- update.context[0],
1256
- update.family,
1257
- update.token.key
1091
+ function createWritableSelectorFamily(options, store) {
1092
+ const subject = new Subject();
1093
+ const selectorFamily = Object.assign(
1094
+ (key) => {
1095
+ const subKey = json.stringifyJson(key);
1096
+ const family = { key: options.key, subKey };
1097
+ const fullKey = `${options.key}(${subKey})`;
1098
+ const target = newest(store);
1099
+ const token = createWritableSelector(
1100
+ {
1101
+ key: fullKey,
1102
+ get: options.get(key),
1103
+ set: options.set(key)
1104
+ },
1105
+ family,
1106
+ target
1258
1107
  );
1259
- break;
1260
- }
1108
+ subject.next({ type: `state_creation`, token });
1109
+ return token;
1110
+ },
1111
+ {
1112
+ key: options.key,
1113
+ type: `selector_family`,
1114
+ subject,
1115
+ install: (s) => createWritableSelectorFamily(options, s)
1116
+ }
1117
+ );
1118
+ store.families.set(options.key, selectorFamily);
1119
+ return selectorFamily;
1261
1120
  }
1262
1121
 
1263
- // internal/src/ingest-updates/ingest-selector-update.ts
1264
- function ingestSelectorUpdate(applying, selectorUpdate, store) {
1265
- const updates = applying === `newValue` ? selectorUpdate.atomUpdates : [...selectorUpdate.atomUpdates].reverse();
1266
- for (const atomUpdate of updates) {
1267
- ingestAtomUpdate(applying, atomUpdate, store);
1122
+ // internal/src/families/create-selector-family.ts
1123
+ function createSelectorFamily(options, store) {
1124
+ const isWritable = `set` in options;
1125
+ if (isWritable) {
1126
+ return createWritableSelectorFamily(options, store);
1268
1127
  }
1128
+ return createReadonlySelectorFamily(options, store);
1269
1129
  }
1270
1130
 
1271
- // internal/src/ingest-updates/ingest-transaction-update.ts
1272
- function ingestTransactionUpdate(applying, transactionUpdate, store) {
1273
- const updates = applying === `newValue` ? transactionUpdate.updates : [...transactionUpdate.updates].reverse();
1274
- for (const updateFromTransaction of updates) {
1275
- switch (updateFromTransaction.type) {
1276
- case `atom_update`:
1277
- case `selector_update`:
1278
- ingestAtomUpdate(applying, updateFromTransaction, store);
1279
- break;
1280
- case `state_creation`:
1281
- ingestCreationEvent(updateFromTransaction, applying, store);
1282
- break;
1283
- case `state_disposal`:
1284
- ingestDisposalEvent(updateFromTransaction, applying, store);
1285
- break;
1286
- case `molecule_creation`:
1287
- ingestMoleculeCreationEvent(updateFromTransaction, applying, store);
1288
- break;
1289
- case `molecule_disposal`:
1290
- ingestMoleculeDisposalEvent(updateFromTransaction, applying, store);
1291
- break;
1292
- case `transaction_update`:
1293
- ingestTransactionUpdate(applying, updateFromTransaction, store);
1294
- break;
1131
+ // internal/src/molecule/dispose-molecule.ts
1132
+ function disposeMolecule(token, store) {
1133
+ var _a;
1134
+ let molecule;
1135
+ try {
1136
+ molecule = withdraw(token, store);
1137
+ } catch (thrown) {
1138
+ if (thrown instanceof Error) {
1139
+ store.logger.error(
1140
+ `\u{1F41E}`,
1141
+ `molecule`,
1142
+ JSON.stringify(token.key),
1143
+ `Failed to dispose molecule, because it was not found in the store.`,
1144
+ thrown.message
1145
+ );
1295
1146
  }
1296
- }
1297
- }
1298
-
1299
- // internal/src/transaction/set-epoch-number.ts
1300
- function setEpochNumberOfContinuity(continuityKey, newEpoch, store) {
1301
- const isRoot = isRootStore(store);
1302
- if (isRoot && continuityKey) {
1303
- store.transactionMeta.epoch.set(continuityKey, newEpoch);
1304
- }
1305
- }
1306
- function setEpochNumberOfAction(transactionKey, newEpoch, store) {
1307
- const isRoot = isRootStore(store);
1308
- if (!isRoot) {
1309
1147
  return;
1310
1148
  }
1311
- const continuityKey = store.transactionMeta.actionContinuities.getRelatedKey(transactionKey);
1312
- if (continuityKey !== void 0) {
1313
- store.transactionMeta.epoch.set(continuityKey, newEpoch);
1149
+ const { family } = token;
1150
+ const context = [];
1151
+ for (const above of molecule.above.values()) {
1152
+ context.push(deposit(above));
1314
1153
  }
1315
- }
1316
-
1317
- // internal/src/transaction/apply-transaction.ts
1318
- var applyTransaction = (output, store) => {
1319
- var _a;
1320
- const child = newest(store);
1321
- const { parent } = child;
1322
- if (parent === null || !isChildStore(child) || ((_a = child.transactionMeta) == null ? void 0 : _a.phase) !== `building`) {
1323
- store.logger.warn(
1324
- `\u{1F41E}`,
1325
- `transaction`,
1326
- `???`,
1327
- `applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`
1328
- );
1329
- return;
1330
- }
1331
- child.transactionMeta.phase = `applying`;
1332
- child.transactionMeta.update.output = output;
1333
- parent.child = null;
1334
- parent.on.transactionApplying.next(child.transactionMeta);
1335
- const { updates } = child.transactionMeta.update;
1336
- store.logger.info(
1337
- `\u{1F6C4}`,
1338
- `transaction`,
1339
- child.transactionMeta.update.key,
1340
- `Applying transaction with ${updates.length} updates:`,
1341
- updates
1342
- );
1343
- ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
1344
- if (isRootStore(parent)) {
1345
- setEpochNumberOfAction(
1346
- child.transactionMeta.update.key,
1347
- child.transactionMeta.update.epoch,
1348
- parent
1349
- );
1350
- const myTransaction = withdraw(
1351
- { key: child.transactionMeta.update.key, type: `transaction` },
1352
- store
1353
- );
1354
- myTransaction == null ? void 0 : myTransaction.subject.next(child.transactionMeta.update);
1355
- store.logger.info(
1356
- `\u{1F6EC}`,
1357
- `transaction`,
1358
- child.transactionMeta.update.key,
1359
- `Finished applying transaction.`
1360
- );
1361
- } else if (isChildStore(parent)) {
1362
- parent.transactionMeta.update.updates.push(child.transactionMeta.update);
1363
- }
1364
- parent.on.transactionApplying.next(null);
1365
- };
1366
-
1367
- // internal/src/transaction/assign-transaction-to-continuity.ts
1368
- function assignTransactionToContinuity(continuityKey, transactionKey, store) {
1369
- const isRoot = isRootStore(store);
1370
- if (!isRoot) {
1371
- return;
1372
- }
1373
- const { epoch, actionContinuities } = store.transactionMeta;
1374
- actionContinuities.set(continuityKey, transactionKey);
1375
- if (!epoch.has(continuityKey)) {
1376
- epoch.set(continuityKey, -1);
1377
- }
1378
- }
1379
-
1380
- // internal/src/lazy-map.ts
1381
- var LazyMap = class extends Map {
1382
- constructor(source) {
1383
- super();
1384
- this.source = source;
1385
- this.deleted = /* @__PURE__ */ new Set();
1386
- }
1387
- get(key) {
1388
- const has = super.has(key);
1389
- if (has) {
1390
- return super.get(key);
1391
- }
1392
- if (!this.deleted.has(key) && this.source.has(key)) {
1393
- const value = this.source.get(key);
1394
- return value;
1395
- }
1396
- return void 0;
1397
- }
1398
- set(key, value) {
1399
- this.deleted.delete(key);
1400
- return super.set(key, value);
1401
- }
1402
- hasOwn(key) {
1403
- return super.has(key);
1404
- }
1405
- has(key) {
1406
- return !this.deleted.has(key) && (super.has(key) || this.source.has(key));
1407
- }
1408
- delete(key) {
1409
- this.deleted.add(key);
1410
- return super.delete(key);
1411
- }
1412
- };
1413
-
1414
- // internal/src/transaction/build-transaction.ts
1415
- var buildTransaction = (key, params, store, id) => {
1416
- const parent = newest(store);
1417
- const childBase = {
1418
- parent,
1419
- child: null,
1420
- on: parent.on,
1421
- loggers: parent.loggers,
1422
- logger: parent.logger,
1423
- config: parent.config,
1424
- atoms: new LazyMap(parent.atoms),
1425
- atomsThatAreDefault: new Set(parent.atomsThatAreDefault),
1426
- families: new LazyMap(parent.families),
1427
- operation: { open: false },
1428
- readonlySelectors: new LazyMap(parent.readonlySelectors),
1429
- timelines: new LazyMap(parent.timelines),
1430
- timelineAtoms: new Junction(parent.timelineAtoms.toJSON()),
1431
- trackers: /* @__PURE__ */ new Map(),
1432
- transactions: new LazyMap(parent.transactions),
1433
- selectorAtoms: new Junction(parent.selectorAtoms.toJSON()),
1434
- selectorGraph: new Junction(parent.selectorGraph.toJSON(), {
1435
- makeContentKey: (...keys) => keys.sort().join(`:`)
1436
- }),
1437
- selectors: new LazyMap(parent.selectors),
1438
- valueMap: new LazyMap(parent.valueMap),
1439
- molecules: new LazyMap(parent.molecules),
1440
- moleculeFamilies: new LazyMap(parent.moleculeFamilies),
1441
- miscResources: new LazyMap(parent.miscResources)
1442
- };
1443
- const epoch = getEpochNumberOfAction(key, store);
1444
- const transactionMeta = {
1445
- phase: `building`,
1446
- update: {
1447
- type: `transaction_update`,
1448
- key,
1449
- id,
1450
- epoch: epoch === void 0 ? Number.NaN : epoch + 1,
1451
- updates: [],
1452
- params,
1453
- output: void 0
1454
- },
1455
- transactors: {
1456
- get: (token) => getFromStore(token, child),
1457
- set: (token, value) => {
1458
- setIntoStore(token, value, child);
1459
- },
1460
- run: (token, identifier = arbitrary()) => actUponStore(token, identifier, child),
1461
- find: (token, k) => findInStore(token, k, child),
1462
- seek: (token, k) => seekInStore(token, k, child),
1463
- json: (token) => getJsonToken(token, child),
1464
- make: (context, family, k, ...args) => makeMoleculeInStore(child, context, family, k, ...args),
1465
- dispose: (token) => {
1466
- disposeFromStore(token, child);
1467
- },
1468
- env: () => getEnvironmentData(child)
1469
- }
1470
- };
1471
- const child = Object.assign(childBase, {
1472
- transactionMeta
1473
- });
1474
- parent.child = child;
1475
- store.logger.info(
1476
- `\u{1F6EB}`,
1477
- `transaction`,
1478
- key,
1479
- `Building transaction with params:`,
1480
- params
1481
- );
1482
- return child;
1483
- };
1484
-
1485
- // internal/src/transaction/create-transaction.ts
1486
- function createTransaction(options, store) {
1487
- const newTransaction = {
1488
- key: options.key,
1489
- type: `transaction`,
1490
- run: (params, id) => {
1491
- const childStore = buildTransaction(options.key, params, store, id);
1492
- try {
1493
- const target2 = newest(store);
1494
- const { transactors } = childStore.transactionMeta;
1495
- const output = options.do(transactors, ...params);
1496
- applyTransaction(output, target2);
1497
- return output;
1498
- } catch (thrown) {
1499
- abortTransaction(target);
1500
- store.logger.warn(`\u{1F4A5}`, `transaction`, options.key, `caught:`, thrown);
1501
- throw thrown;
1502
- }
1503
- },
1504
- install: (s) => createTransaction(options, s),
1505
- subject: new Subject()
1506
- };
1507
- const target = newest(store);
1508
- target.transactions.set(newTransaction.key, newTransaction);
1509
- const token = deposit(newTransaction);
1510
- store.on.transactionCreation.next(token);
1511
- return token;
1512
- }
1513
-
1514
- // internal/src/transaction/get-epoch-number.ts
1515
- function getContinuityKey(transactionKey, store) {
1516
- const isRoot = isRootStore(store);
1517
- const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
1518
- return continuity;
1519
- }
1520
- function getEpochNumberOfContinuity(continuityKey, store) {
1521
- const isRoot = isRootStore(store);
1522
- const epoch = isRoot && continuityKey ? store.transactionMeta.epoch.get(continuityKey) : void 0;
1523
- return epoch;
1524
- }
1525
- function getEpochNumberOfAction(transactionKey, store) {
1526
- const isRoot = isRootStore(store);
1527
- const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
1528
- const epoch = isRoot && continuity !== void 0 ? store.transactionMeta.epoch.get(continuity) : void 0;
1529
- return epoch;
1530
- }
1531
-
1532
- // internal/src/transaction/index.ts
1533
- var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
1534
-
1535
- // internal/src/molecule/dispose-molecule.ts
1536
- function disposeMolecule(token, store) {
1537
- var _a;
1538
- let molecule;
1539
- try {
1540
- molecule = withdraw(token, store);
1541
- } catch (thrown) {
1542
- if (thrown instanceof Error) {
1543
- store.logger.error(
1544
- `\u{1F41E}`,
1545
- `molecule`,
1546
- JSON.stringify(token.key),
1547
- `Failed to dispose molecule, because it was not found in the store.`,
1548
- thrown.message
1549
- );
1550
- }
1551
- return;
1552
- }
1553
- const { family } = token;
1554
- for (const state of molecule.tokens.values()) {
1555
- disposeFromStore(state, store);
1556
- }
1557
- for (const child of molecule.below.values()) {
1558
- if (((_a = child.family) == null ? void 0 : _a.dependsOn) === `all`) {
1559
- disposeMolecule(child, store);
1560
- } else {
1561
- child.above.delete(molecule.stringKey);
1562
- if (child.above.size === 0) {
1563
- disposeMolecule(child, store);
1564
- }
1565
- }
1154
+ const values = [];
1155
+ for (const stateToken of molecule.tokens.values()) {
1156
+ const tokenFamily = stateToken.family;
1157
+ values.push([tokenFamily.key, store.valueMap.get(stateToken.key)]);
1566
1158
  }
1567
- molecule.below.clear();
1568
1159
  if (family) {
1569
1160
  const Formula = withdraw(family, store);
1570
1161
  const disposalEvent = {
1571
1162
  type: `molecule_disposal`,
1572
1163
  token,
1573
1164
  family,
1574
- context: [...molecule.above.values()].map((m) => deposit(m)),
1575
- familyKeys: [...molecule.tokens.values()].map((t) => {
1576
- var _a2;
1577
- return (_a2 = t.family) == null ? void 0 : _a2.key;
1578
- }).filter((k) => typeof k === `string`)
1165
+ context,
1166
+ values
1579
1167
  };
1580
1168
  if (token.family) {
1581
1169
  disposalEvent.family = token.family;
1582
1170
  }
1171
+ for (const state of molecule.tokens.values()) {
1172
+ disposeFromStore(state, store);
1173
+ }
1174
+ for (const child of molecule.below.values()) {
1175
+ if (((_a = child.family) == null ? void 0 : _a.dependsOn) === `all`) {
1176
+ disposeMolecule(child, store);
1177
+ } else {
1178
+ child.above.delete(molecule.stringKey);
1179
+ if (child.above.size === 0) {
1180
+ disposeMolecule(child, store);
1181
+ }
1182
+ }
1183
+ }
1184
+ molecule.below.clear();
1583
1185
  const isTransaction = isChildStore(store) && store.transactionMeta.phase === `building`;
1584
1186
  if (isTransaction) {
1585
1187
  store.transactionMeta.update.updates.push(disposalEvent);
@@ -1622,13 +1224,8 @@ function initFamilyMemberInStore(token, key, store) {
1622
1224
  }
1623
1225
  const state = family(key);
1624
1226
  const target = newest(store);
1625
- if (state.family) {
1626
- if (isChildStore(target) && target.transactionMeta.phase === `building`) {
1627
- target.transactionMeta.update.updates.push({
1628
- type: `state_creation`,
1629
- token: state
1630
- });
1631
- } else {
1227
+ if (state.family && target.moleculeInProgress === null) {
1228
+ if (isRootStore(target)) {
1632
1229
  switch (state.type) {
1633
1230
  case `atom`:
1634
1231
  case `mutable_atom`:
@@ -1639,6 +1236,11 @@ function initFamilyMemberInStore(token, key, store) {
1639
1236
  store.on.selectorCreation.next(state);
1640
1237
  break;
1641
1238
  }
1239
+ } else if (isChildStore(target) && target.on.transactionApplying.state === null) {
1240
+ target.transactionMeta.update.updates.push({
1241
+ type: `state_creation`,
1242
+ token: state
1243
+ });
1642
1244
  }
1643
1245
  }
1644
1246
  return state;
@@ -1686,291 +1288,715 @@ function findInStore(token, key, store) {
1686
1288
  return state;
1687
1289
  }
1688
1290
 
1689
- // internal/src/keys.ts
1690
- var isAtomKey = (key, store) => newest(store).atoms.has(key);
1691
- var isSelectorKey = (key, store) => newest(store).selectors.has(key);
1692
- var isReadonlySelectorKey = (key, store) => newest(store).readonlySelectors.has(key);
1693
- var isStateKey = (key, store) => isAtomKey(key, store) || isSelectorKey(key, store) || isReadonlySelectorKey(key, store);
1291
+ // internal/src/molecule/create-molecule-family.ts
1292
+ function createMoleculeFamily(options, store) {
1293
+ var _a;
1294
+ const subject = new Subject();
1295
+ const token = {
1296
+ type: `molecule_family`,
1297
+ key: options.key,
1298
+ dependsOn: (_a = options.dependsOn) != null ? _a : `all`
1299
+ };
1300
+ const family = __spreadProps(__spreadValues({}, token), {
1301
+ subject,
1302
+ new: options.new
1303
+ });
1304
+ store.moleculeFamilies.set(options.key, family);
1305
+ return token;
1306
+ }
1694
1307
 
1695
- // internal/src/selector/get-selector-dependency-keys.ts
1696
- var getSelectorDependencyKeys = (key, store) => {
1697
- const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(source, store));
1698
- return sources;
1699
- };
1308
+ // internal/src/molecule/grow-molecule-in-store.ts
1309
+ function growMoleculeInStore(molecule, family, store) {
1310
+ const stateToken = initFamilyMemberInStore(family, molecule.key, store);
1311
+ molecule.tokens.set(stateToken.key, stateToken);
1312
+ const isTransaction = isChildStore(store) && store.transactionMeta.phase === `building`;
1313
+ const moleculeInProgress = store.moleculeInProgress === molecule.key;
1314
+ if (!isTransaction && !moleculeInProgress) {
1315
+ molecule.subject.next({ type: `state_creation`, token: stateToken });
1316
+ }
1317
+ return stateToken;
1318
+ }
1700
1319
 
1701
- // internal/src/selector/trace-selector-atoms.ts
1702
- var traceSelectorAtoms = (selectorKey, directDependencyKey, store) => {
1703
- const rootKeys = [];
1704
- const indirectDependencyKeys = getSelectorDependencyKeys(
1705
- directDependencyKey,
1320
+ // internal/src/get-environment-data.ts
1321
+ function getEnvironmentData(store) {
1322
+ return {
1706
1323
  store
1707
- );
1708
- let depth = 0;
1709
- while (indirectDependencyKeys.length > 0) {
1710
- const indirectDependencyKey = indirectDependencyKeys.shift();
1711
- ++depth;
1712
- if (depth > 99999) {
1713
- throw new Error(
1714
- `Maximum selector dependency depth exceeded (> 99999) in selector "${selectorKey}". This is likely due to a circular dependency.`
1715
- );
1324
+ };
1325
+ }
1326
+
1327
+ // internal/src/get-state/get-from-store.ts
1328
+ function getFromStore(token, store) {
1329
+ if (token.type === `molecule`) {
1330
+ try {
1331
+ const molecule = withdraw(token, store);
1332
+ return molecule.instance;
1333
+ } catch (_) {
1334
+ return void 0;
1716
1335
  }
1717
- if (!isAtomKey(indirectDependencyKey, store)) {
1718
- indirectDependencyKeys.push(
1719
- ...getSelectorDependencyKeys(indirectDependencyKey, store)
1720
- );
1721
- } else if (!rootKeys.includes(indirectDependencyKey)) {
1722
- rootKeys.push(indirectDependencyKey);
1336
+ }
1337
+ const state = withdraw(token, store);
1338
+ return readOrComputeValue(state, store);
1339
+ }
1340
+ var Molecule = class {
1341
+ constructor(ctx, key, family) {
1342
+ this.key = key;
1343
+ this.type = `molecule`;
1344
+ this.subject = new Subject();
1345
+ this.tokens = /* @__PURE__ */ new Map();
1346
+ this.above = /* @__PURE__ */ new Map();
1347
+ this.below = /* @__PURE__ */ new Map();
1348
+ this.joins = /* @__PURE__ */ new Map();
1349
+ this.stringKey = json.stringifyJson(key);
1350
+ if (family) {
1351
+ this.family = family;
1352
+ }
1353
+ if (ctx) {
1354
+ if (Array.isArray(ctx)) {
1355
+ for (const molecule of ctx) {
1356
+ this.above.set(molecule.stringKey, molecule);
1357
+ }
1358
+ } else {
1359
+ this.above.set(ctx.stringKey, ctx);
1360
+ }
1723
1361
  }
1724
1362
  }
1725
- return rootKeys;
1726
- };
1727
- var traceAllSelectorAtoms = (selector, store) => {
1728
- const selectorKey = selector.key;
1729
- const directDependencyKeys = getSelectorDependencyKeys(selectorKey, store);
1730
- return directDependencyKeys.flatMap(
1731
- (depKey) => isAtomKey(depKey, store) ? depKey : traceSelectorAtoms(selectorKey, depKey, store)
1732
- );
1733
1363
  };
1734
1364
 
1735
- // internal/src/selector/update-selector-atoms.ts
1736
- var updateSelectorAtoms = (selectorKey, dependency, store) => {
1365
+ // internal/src/molecule/make-molecule-in-store.ts
1366
+ function makeMoleculeInStore(store, context, familyToken, key, ...params) {
1737
1367
  const target = newest(store);
1738
- if (dependency.type === `atom` || dependency.type === `mutable_atom`) {
1739
- target.selectorAtoms.set({
1740
- selectorKey,
1741
- atomKey: dependency.key
1742
- });
1743
- store.logger.info(
1744
- `\u{1F50D}`,
1745
- `selector`,
1746
- selectorKey,
1747
- `discovers root atom "${dependency.key}"`
1748
- );
1749
- } else {
1750
- const rootKeys = traceSelectorAtoms(selectorKey, dependency.key, store);
1751
- store.logger.info(
1752
- `\u{1F50D}`,
1753
- `selector`,
1754
- selectorKey,
1755
- `discovers root atoms: [ ${rootKeys.map((key) => `"${key}"`).join(`, `)} ]`
1756
- );
1757
- for (const atomKey of rootKeys) {
1758
- target.selectorAtoms = target.selectorAtoms.set({
1759
- selectorKey,
1760
- atomKey
1761
- });
1368
+ target.moleculeInProgress = key;
1369
+ const contextArray = Array.isArray(context) ? context : [context];
1370
+ const owners = contextArray.map((ctx) => {
1371
+ if (ctx instanceof Molecule) {
1372
+ return ctx;
1373
+ }
1374
+ const stringKey = json.stringifyJson(ctx.key);
1375
+ const molecule2 = store.molecules.get(stringKey);
1376
+ if (!molecule2) {
1377
+ throw new Error(
1378
+ `Molecule ${stringKey} not found in store "${store.config.name}"`
1379
+ );
1762
1380
  }
1381
+ return molecule2;
1382
+ });
1383
+ const molecule = new Molecule(owners, key, familyToken);
1384
+ target.molecules.set(json.stringifyJson(key), molecule);
1385
+ for (const owner of owners) {
1386
+ owner.below.set(molecule.stringKey, molecule);
1763
1387
  }
1764
- };
1765
-
1766
- // internal/src/selector/register-selector.ts
1767
- var registerSelector = (selectorKey, store) => ({
1768
- get: (dependency) => {
1769
- const target = newest(store);
1770
- const dependencyState = withdraw(dependency, store);
1771
- const dependencyValue = readOrComputeValue(dependencyState, store);
1772
- store.logger.info(
1773
- `\u{1F50C}`,
1774
- `selector`,
1775
- selectorKey,
1776
- `registers dependency ( "${dependency.key}" =`,
1777
- dependencyValue,
1778
- `)`
1779
- );
1780
- target.selectorGraph.set(
1781
- {
1782
- upstreamSelectorKey: dependency.key,
1783
- downstreamSelectorKey: selectorKey
1784
- },
1785
- {
1786
- source: dependency.key
1388
+ const transactors = {
1389
+ get: (t) => getFromStore(t, newest(store)),
1390
+ set: (t, newValue) => {
1391
+ setIntoStore(t, newValue, newest(store));
1392
+ },
1393
+ seek: (t, k) => seekInStore(t, k, newest(store)),
1394
+ json: (t) => getJsonToken(t, newest(store)),
1395
+ run: (t, i = arbitrary()) => actUponStore(t, i, newest(store)),
1396
+ make: (ctx, f, k, ...args) => makeMoleculeInStore(newest(store), ctx, f, k, ...args),
1397
+ dispose: (t) => {
1398
+ disposeFromStore(t, newest(store));
1399
+ },
1400
+ env: () => getEnvironmentData(newest(store)),
1401
+ bond: (f) => growMoleculeInStore(
1402
+ molecule,
1403
+ withdraw(f, store),
1404
+ newest(store)
1405
+ ),
1406
+ claim: (below, options) => {
1407
+ const { exclusive } = options;
1408
+ const belowMolecule = newest(store).molecules.get(json.stringifyJson(below.key));
1409
+ if (belowMolecule) {
1410
+ if (exclusive) {
1411
+ for (const value of belowMolecule.above.values()) {
1412
+ value.below.delete(belowMolecule.stringKey);
1413
+ }
1414
+ belowMolecule.above.clear();
1415
+ belowMolecule.above.set(molecule.stringKey, molecule);
1416
+ molecule.below.set(belowMolecule.stringKey, belowMolecule);
1417
+ } else {
1418
+ belowMolecule.above.set(molecule.stringKey, molecule);
1419
+ molecule.below.set(belowMolecule.stringKey, belowMolecule);
1420
+ }
1787
1421
  }
1788
- );
1789
- updateSelectorAtoms(selectorKey, dependency, store);
1790
- return dependencyValue;
1791
- },
1792
- set: (WritableToken, newValue) => {
1793
- const state = withdraw(WritableToken, store);
1794
- setAtomOrSelector(state, newValue, store);
1795
- },
1796
- find: (token, key) => findInStore(token, key, store),
1797
- seek: (token, key) => seekInStore(token, key, store),
1798
- json: (token) => getJsonToken(token, store)
1799
- });
1800
-
1801
- // internal/src/selector/create-readonly-selector.ts
1802
- var createReadonlySelector = (options, family, store) => {
1803
- const target = newest(store);
1804
- const subject = new Subject();
1805
- const { get, find, seek, json } = registerSelector(options.key, target);
1806
- const getSelf = () => {
1807
- const value = options.get({ get, find, seek, json });
1808
- cacheValue(options.key, value, subject, newest(store));
1809
- return value;
1422
+ },
1423
+ join: (joinToken) => {
1424
+ const join = data.getJoin(joinToken, store);
1425
+ join.molecules.set(json.stringifyJson(key), molecule);
1426
+ molecule.joins.set(joinToken.key, join);
1427
+ return joinToken;
1428
+ },
1429
+ spawn: (f, k, ...p) => makeMoleculeInStore(
1430
+ newest(store),
1431
+ [molecule],
1432
+ withdraw(f, store),
1433
+ k,
1434
+ ...p
1435
+ )
1810
1436
  };
1811
- const readonlySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
1812
- subject,
1813
- install: (s) => createReadonlySelector(options, family, s),
1814
- get: getSelf,
1815
- type: `readonly_selector`
1816
- }), family && { family });
1817
- target.readonlySelectors.set(options.key, readonlySelector);
1818
- const initialValue = getSelf();
1819
- store.logger.info(
1820
- `\u2728`,
1821
- readonlySelector.type,
1822
- readonlySelector.key,
1823
- `=`,
1824
- initialValue
1825
- );
1437
+ const family = withdraw(familyToken, store);
1438
+ const Constructor = family.new;
1439
+ molecule.instance = new Constructor(transactors, key, ...params);
1826
1440
  const token = {
1827
- key: options.key,
1828
- type: `readonly_selector`
1829
- };
1830
- if (family) {
1831
- token.family = family;
1441
+ type: `molecule`,
1442
+ key,
1443
+ family: familyToken
1444
+ };
1445
+ const update = {
1446
+ type: `molecule_creation`,
1447
+ token,
1448
+ family: familyToken,
1449
+ context: contextArray,
1450
+ params
1451
+ };
1452
+ if (isRootStore(target)) {
1453
+ family.subject.next(update);
1454
+ } else if (isChildStore(target) && target.on.transactionApplying.state === null) {
1455
+ target.transactionMeta.update.updates.push(update);
1832
1456
  }
1457
+ target.moleculeInProgress = null;
1833
1458
  return token;
1834
- };
1459
+ }
1835
1460
 
1836
- // internal/src/selector/create-writable-selector.ts
1837
- var createWritableSelector = (options, family, store) => {
1838
- const target = newest(store);
1839
- const subject = new Subject();
1840
- const transactors = registerSelector(options.key, target);
1841
- const { find, get, seek, json } = transactors;
1842
- const readonlyTransactors = { find, get, seek, json };
1843
- const getSelf = () => {
1844
- const value = options.get(readonlyTransactors);
1845
- cacheValue(options.key, value, subject, newest(store));
1846
- return value;
1847
- };
1848
- const setSelf = (next) => {
1849
- const oldValue = getSelf();
1850
- const newValue = become(next)(oldValue);
1851
- store.logger.info(
1852
- `\u{1F4DD}`,
1853
- `selector`,
1854
- options.key,
1855
- `set (`,
1856
- oldValue,
1857
- `->`,
1858
- newValue,
1859
- `)`
1860
- );
1861
- cacheValue(options.key, newValue, subject, store);
1862
- markDone(options.key, store);
1863
- if (isRootStore(target)) {
1864
- subject.next({ newValue, oldValue });
1461
+ // internal/src/ingest-updates/ingest-creation-disposal.ts
1462
+ function ingestCreationEvent(update, applying, store) {
1463
+ switch (applying) {
1464
+ case `newValue`: {
1465
+ createInStore(update.token, store);
1466
+ break;
1467
+ }
1468
+ case `oldValue`: {
1469
+ disposeFromStore(update.token, store);
1470
+ break;
1865
1471
  }
1866
- options.set(transactors, newValue);
1867
- };
1868
- const mySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
1869
- subject,
1870
- install: (s) => createWritableSelector(options, family, s),
1871
- get: getSelf,
1872
- set: setSelf,
1873
- type: `selector`
1874
- }), family && { family });
1875
- target.selectors.set(options.key, mySelector);
1876
- const initialValue = getSelf();
1877
- store.logger.info(`\u2728`, mySelector.type, mySelector.key, `=`, initialValue);
1878
- const token = {
1879
- key: options.key,
1880
- type: `selector`
1881
- };
1882
- if (family) {
1883
- token.family = family;
1884
1472
  }
1885
- return token;
1886
- };
1473
+ }
1474
+ function ingestDisposalEvent(update, applying, store) {
1475
+ switch (applying) {
1476
+ case `newValue`: {
1477
+ disposeFromStore(update.token, store);
1478
+ break;
1479
+ }
1480
+ case `oldValue`: {
1481
+ createInStore(update.token, store);
1482
+ store.valueMap.set(update.token.key, update.value);
1483
+ break;
1484
+ }
1485
+ }
1486
+ }
1487
+ function createInStore(token, store) {
1488
+ if (token.family) {
1489
+ const family = store.families.get(token.family.key);
1490
+ if (family) {
1491
+ const molecule = store.molecules.get(token.family.subKey);
1492
+ if (molecule) {
1493
+ growMoleculeInStore(molecule, family, store);
1494
+ return;
1495
+ }
1496
+ if (store.config.lifespan === `immortal`) {
1497
+ throw new Error(`No molecule found for key "${token.family.subKey}"`);
1498
+ }
1499
+ initFamilyMemberInStore(family, json.parseJson(token.family.subKey), store);
1500
+ }
1501
+ }
1502
+ }
1503
+ function ingestMoleculeCreationEvent(update, applying, store) {
1504
+ switch (applying) {
1505
+ case `newValue`:
1506
+ makeMoleculeInStore(
1507
+ store,
1508
+ update.context,
1509
+ update.family,
1510
+ update.token.key,
1511
+ ...update.params
1512
+ );
1513
+ break;
1514
+ case `oldValue`:
1515
+ disposeFromStore(update.token, store);
1516
+ break;
1517
+ }
1518
+ }
1519
+ function ingestMoleculeDisposalEvent(update, applying, store) {
1520
+ switch (applying) {
1521
+ case `newValue`:
1522
+ disposeFromStore(update.token, store);
1523
+ break;
1524
+ case `oldValue`:
1525
+ {
1526
+ const moleculeToken = makeMoleculeInStore(
1527
+ store,
1528
+ update.context,
1529
+ update.family,
1530
+ update.token.key
1531
+ );
1532
+ for (const [familyKey, value] of update.values) {
1533
+ const memberKey = `${familyKey}(${json.stringifyJson(moleculeToken.key)})`;
1534
+ const molecule = withdraw(moleculeToken, store);
1535
+ const alreadyCreated = molecule.tokens.has(memberKey);
1536
+ const family = store.families.get(familyKey);
1537
+ if (family && !alreadyCreated) {
1538
+ growMoleculeInStore(molecule, family, store);
1539
+ }
1540
+ store.valueMap.set(memberKey, value);
1541
+ }
1542
+ }
1543
+ break;
1544
+ }
1545
+ }
1887
1546
 
1888
- // internal/src/selector/create-standalone-selector.ts
1889
- function createStandaloneSelector(options, store) {
1890
- const isWritable = `set` in options;
1891
- if (isWritable) {
1892
- const state2 = createWritableSelector(options, void 0, store);
1893
- store.on.selectorCreation.next(state2);
1894
- return state2;
1547
+ // internal/src/ingest-updates/ingest-selector-update.ts
1548
+ function ingestSelectorUpdate(applying, selectorUpdate, store) {
1549
+ const updates = applying === `newValue` ? selectorUpdate.atomUpdates : [...selectorUpdate.atomUpdates].reverse();
1550
+ for (const atomUpdate of updates) {
1551
+ ingestAtomUpdate(applying, atomUpdate, store);
1895
1552
  }
1896
- const state = createReadonlySelector(options, void 0, store);
1897
- store.on.selectorCreation.next(state);
1898
- return state;
1899
1553
  }
1900
1554
 
1901
- // internal/src/selector/dispose-selector.ts
1902
- function disposeSelector(selectorToken, store) {
1555
+ // internal/src/ingest-updates/ingest-transaction-update.ts
1556
+ function ingestTransactionUpdate(applying, transactionUpdate, store) {
1557
+ const updates = applying === `newValue` ? transactionUpdate.updates : [...transactionUpdate.updates].reverse();
1558
+ for (const updateFromTransaction of updates) {
1559
+ switch (updateFromTransaction.type) {
1560
+ case `atom_update`:
1561
+ case `selector_update`:
1562
+ ingestAtomUpdate(applying, updateFromTransaction, store);
1563
+ break;
1564
+ case `state_creation`:
1565
+ ingestCreationEvent(updateFromTransaction, applying, store);
1566
+ break;
1567
+ case `state_disposal`:
1568
+ ingestDisposalEvent(updateFromTransaction, applying, store);
1569
+ break;
1570
+ case `molecule_creation`:
1571
+ ingestMoleculeCreationEvent(updateFromTransaction, applying, store);
1572
+ break;
1573
+ case `molecule_disposal`:
1574
+ ingestMoleculeDisposalEvent(updateFromTransaction, applying, store);
1575
+ break;
1576
+ case `transaction_update`:
1577
+ ingestTransactionUpdate(applying, updateFromTransaction, store);
1578
+ break;
1579
+ }
1580
+ }
1581
+ }
1582
+
1583
+ // internal/src/transaction/set-epoch-number.ts
1584
+ function setEpochNumberOfContinuity(continuityKey, newEpoch, store) {
1585
+ const isRoot = isRootStore(store);
1586
+ if (isRoot && continuityKey) {
1587
+ store.transactionMeta.epoch.set(continuityKey, newEpoch);
1588
+ }
1589
+ }
1590
+ function setEpochNumberOfAction(transactionKey, newEpoch, store) {
1591
+ const isRoot = isRootStore(store);
1592
+ if (!isRoot) {
1593
+ return;
1594
+ }
1595
+ const continuityKey = store.transactionMeta.actionContinuities.getRelatedKey(transactionKey);
1596
+ if (continuityKey !== void 0) {
1597
+ store.transactionMeta.epoch.set(continuityKey, newEpoch);
1598
+ }
1599
+ }
1600
+
1601
+ // internal/src/transaction/apply-transaction.ts
1602
+ var applyTransaction = (output, store) => {
1903
1603
  var _a;
1904
- const target = newest(store);
1905
- const { key } = selectorToken;
1906
- const selector = (_a = target.selectors.get(key)) != null ? _a : target.readonlySelectors.get(key);
1907
- if (!selector) {
1908
- store.logger.info(
1909
- `\u274C`,
1910
- `selector`,
1911
- key,
1912
- `Tried to dispose selector, but it does not exist in the store.`
1604
+ const child = newest(store);
1605
+ const { parent } = child;
1606
+ if (parent === null || !isChildStore(child) || ((_a = child.transactionMeta) == null ? void 0 : _a.phase) !== `building`) {
1607
+ store.logger.warn(
1608
+ `\u{1F41E}`,
1609
+ `transaction`,
1610
+ `???`,
1611
+ `applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`
1913
1612
  );
1914
- } else if (!selector.family) {
1915
- store.logger.error(
1916
- `\u274C`,
1917
- `selector`,
1918
- key,
1919
- `Standalone selectors cannot be disposed.`
1613
+ return;
1614
+ }
1615
+ child.transactionMeta.phase = `applying`;
1616
+ child.transactionMeta.update.output = output;
1617
+ parent.child = null;
1618
+ parent.on.transactionApplying.next(child.transactionMeta);
1619
+ const { updates } = child.transactionMeta.update;
1620
+ store.logger.info(
1621
+ `\u{1F6C4}`,
1622
+ `transaction`,
1623
+ child.transactionMeta.update.key,
1624
+ `Applying transaction with ${updates.length} updates:`,
1625
+ updates
1626
+ );
1627
+ ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
1628
+ if (isRootStore(parent)) {
1629
+ setEpochNumberOfAction(
1630
+ child.transactionMeta.update.key,
1631
+ child.transactionMeta.update.epoch,
1632
+ parent
1920
1633
  );
1921
- } else {
1922
- switch (selectorToken.type) {
1923
- case `selector`:
1924
- {
1925
- target.selectors.delete(key);
1926
- const family = withdraw(
1927
- { key: selector.family.key, type: `selector_family` },
1928
- store
1929
- );
1930
- family.subject.next({
1931
- type: `state_disposal`,
1932
- token: selectorToken
1933
- });
1934
- }
1634
+ const myTransaction = withdraw(
1635
+ { key: child.transactionMeta.update.key, type: `transaction` },
1636
+ store
1637
+ );
1638
+ myTransaction == null ? void 0 : myTransaction.subject.next(child.transactionMeta.update);
1639
+ store.logger.info(
1640
+ `\u{1F6EC}`,
1641
+ `transaction`,
1642
+ child.transactionMeta.update.key,
1643
+ `Finished applying transaction.`
1644
+ );
1645
+ } else if (isChildStore(parent)) {
1646
+ parent.transactionMeta.update.updates.push(child.transactionMeta.update);
1647
+ }
1648
+ parent.on.transactionApplying.next(null);
1649
+ };
1650
+
1651
+ // internal/src/transaction/assign-transaction-to-continuity.ts
1652
+ function assignTransactionToContinuity(continuityKey, transactionKey, store) {
1653
+ const isRoot = isRootStore(store);
1654
+ if (!isRoot) {
1655
+ return;
1656
+ }
1657
+ const { epoch, actionContinuities } = store.transactionMeta;
1658
+ actionContinuities.set(continuityKey, transactionKey);
1659
+ if (!epoch.has(continuityKey)) {
1660
+ epoch.set(continuityKey, -1);
1661
+ }
1662
+ }
1663
+
1664
+ // internal/src/lazy-map.ts
1665
+ var LazyMap = class extends Map {
1666
+ constructor(source) {
1667
+ super();
1668
+ this.source = source;
1669
+ this.deleted = /* @__PURE__ */ new Set();
1670
+ }
1671
+ get(key) {
1672
+ const has = super.has(key);
1673
+ if (has) {
1674
+ return super.get(key);
1675
+ }
1676
+ if (!this.deleted.has(key) && this.source.has(key)) {
1677
+ const value = this.source.get(key);
1678
+ return value;
1679
+ }
1680
+ return void 0;
1681
+ }
1682
+ set(key, value) {
1683
+ this.deleted.delete(key);
1684
+ return super.set(key, value);
1685
+ }
1686
+ hasOwn(key) {
1687
+ return super.has(key);
1688
+ }
1689
+ has(key) {
1690
+ return !this.deleted.has(key) && (super.has(key) || this.source.has(key));
1691
+ }
1692
+ delete(key) {
1693
+ this.deleted.add(key);
1694
+ return super.delete(key);
1695
+ }
1696
+ };
1697
+
1698
+ // internal/src/transaction/build-transaction.ts
1699
+ var buildTransaction = (key, params, store, id) => {
1700
+ const parent = newest(store);
1701
+ const childBase = {
1702
+ parent,
1703
+ child: null,
1704
+ on: parent.on,
1705
+ loggers: parent.loggers,
1706
+ logger: parent.logger,
1707
+ config: parent.config,
1708
+ atoms: new LazyMap(parent.atoms),
1709
+ atomsThatAreDefault: new Set(parent.atomsThatAreDefault),
1710
+ families: new LazyMap(parent.families),
1711
+ operation: { open: false },
1712
+ readonlySelectors: new LazyMap(parent.readonlySelectors),
1713
+ timelines: new LazyMap(parent.timelines),
1714
+ timelineTopics: new Junction(parent.timelineTopics.toJSON()),
1715
+ trackers: /* @__PURE__ */ new Map(),
1716
+ transactions: new LazyMap(parent.transactions),
1717
+ selectorAtoms: new Junction(parent.selectorAtoms.toJSON()),
1718
+ selectorGraph: new Junction(parent.selectorGraph.toJSON(), {
1719
+ makeContentKey: (...keys) => keys.sort().join(`:`)
1720
+ }),
1721
+ selectors: new LazyMap(parent.selectors),
1722
+ valueMap: new LazyMap(parent.valueMap),
1723
+ molecules: new LazyMap(parent.molecules),
1724
+ moleculeFamilies: new LazyMap(parent.moleculeFamilies),
1725
+ moleculeInProgress: parent.moleculeInProgress,
1726
+ miscResources: new LazyMap(parent.miscResources)
1727
+ };
1728
+ const epoch = getEpochNumberOfAction(key, store);
1729
+ const transactionMeta = {
1730
+ phase: `building`,
1731
+ update: {
1732
+ type: `transaction_update`,
1733
+ key,
1734
+ id,
1735
+ epoch: epoch === void 0 ? Number.NaN : epoch + 1,
1736
+ updates: [],
1737
+ params,
1738
+ output: void 0
1739
+ },
1740
+ transactors: {
1741
+ get: (token) => getFromStore(token, child),
1742
+ set: (token, value) => {
1743
+ setIntoStore(token, value, child);
1744
+ },
1745
+ run: (token, identifier = arbitrary()) => actUponStore(token, identifier, child),
1746
+ find: (token, k) => findInStore(token, k, child),
1747
+ seek: (token, k) => seekInStore(token, k, child),
1748
+ json: (token) => getJsonToken(token, child),
1749
+ make: (context, family, k, ...args) => makeMoleculeInStore(child, context, family, k, ...args),
1750
+ dispose: (token) => {
1751
+ disposeFromStore(token, child);
1752
+ },
1753
+ env: () => getEnvironmentData(child)
1754
+ }
1755
+ };
1756
+ const child = Object.assign(childBase, {
1757
+ transactionMeta
1758
+ });
1759
+ parent.child = child;
1760
+ store.logger.info(
1761
+ `\u{1F6EB}`,
1762
+ `transaction`,
1763
+ key,
1764
+ `Building transaction with params:`,
1765
+ params
1766
+ );
1767
+ return child;
1768
+ };
1769
+
1770
+ // internal/src/transaction/create-transaction.ts
1771
+ function createTransaction(options, store) {
1772
+ const newTransaction = {
1773
+ key: options.key,
1774
+ type: `transaction`,
1775
+ run: (params, id) => {
1776
+ const childStore = buildTransaction(options.key, params, store, id);
1777
+ try {
1778
+ const target2 = newest(store);
1779
+ const { transactors } = childStore.transactionMeta;
1780
+ const output = options.do(transactors, ...params);
1781
+ applyTransaction(output, target2);
1782
+ return output;
1783
+ } catch (thrown) {
1784
+ abortTransaction(target);
1785
+ store.logger.warn(`\u{1F4A5}`, `transaction`, options.key, `caught:`, thrown);
1786
+ throw thrown;
1787
+ }
1788
+ },
1789
+ install: (s) => createTransaction(options, s),
1790
+ subject: new Subject()
1791
+ };
1792
+ const target = newest(store);
1793
+ target.transactions.set(newTransaction.key, newTransaction);
1794
+ const token = deposit(newTransaction);
1795
+ store.on.transactionCreation.next(token);
1796
+ return token;
1797
+ }
1798
+
1799
+ // internal/src/transaction/get-epoch-number.ts
1800
+ function getContinuityKey(transactionKey, store) {
1801
+ const isRoot = isRootStore(store);
1802
+ const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
1803
+ return continuity;
1804
+ }
1805
+ function getEpochNumberOfContinuity(continuityKey, store) {
1806
+ const isRoot = isRootStore(store);
1807
+ const epoch = isRoot && continuityKey ? store.transactionMeta.epoch.get(continuityKey) : void 0;
1808
+ return epoch;
1809
+ }
1810
+ function getEpochNumberOfAction(transactionKey, store) {
1811
+ const isRoot = isRootStore(store);
1812
+ const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
1813
+ const epoch = isRoot && continuity !== void 0 ? store.transactionMeta.epoch.get(continuity) : void 0;
1814
+ return epoch;
1815
+ }
1816
+
1817
+ // internal/src/transaction/index.ts
1818
+ var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
1819
+
1820
+ // internal/src/store/store.ts
1821
+ var Store = class {
1822
+ constructor(config, store = null) {
1823
+ this.parent = null;
1824
+ this.child = null;
1825
+ this.valueMap = /* @__PURE__ */ new Map();
1826
+ this.atoms = /* @__PURE__ */ new Map();
1827
+ this.selectors = /* @__PURE__ */ new Map();
1828
+ this.readonlySelectors = /* @__PURE__ */ new Map();
1829
+ this.atomsThatAreDefault = /* @__PURE__ */ new Set();
1830
+ this.selectorAtoms = new Junction({
1831
+ between: [`selectorKey`, `atomKey`],
1832
+ cardinality: `n:n`
1833
+ });
1834
+ this.selectorGraph = new Junction(
1835
+ {
1836
+ between: [`upstreamSelectorKey`, `downstreamSelectorKey`],
1837
+ cardinality: `n:n`
1838
+ },
1839
+ {
1840
+ makeContentKey: (...keys) => keys.sort().join(`:`)
1841
+ }
1842
+ );
1843
+ this.trackers = /* @__PURE__ */ new Map();
1844
+ this.families = /* @__PURE__ */ new Map();
1845
+ this.transactions = /* @__PURE__ */ new Map();
1846
+ this.transactionMeta = {
1847
+ epoch: /* @__PURE__ */ new Map(),
1848
+ actionContinuities: new Junction({
1849
+ between: [`continuity`, `action`],
1850
+ cardinality: `1:n`
1851
+ })
1852
+ };
1853
+ this.timelines = /* @__PURE__ */ new Map();
1854
+ this.timelineTopics = new Junction({
1855
+ between: [`timelineKey`, `topicKey`],
1856
+ cardinality: `1:n`
1857
+ });
1858
+ this.molecules = /* @__PURE__ */ new Map();
1859
+ this.moleculeFamilies = /* @__PURE__ */ new Map();
1860
+ this.moleculeInProgress = null;
1861
+ this.miscResources = /* @__PURE__ */ new Map();
1862
+ this.on = {
1863
+ atomCreation: new Subject(),
1864
+ atomDisposal: new Subject(),
1865
+ selectorCreation: new Subject(),
1866
+ selectorDisposal: new Subject(),
1867
+ timelineCreation: new Subject(),
1868
+ transactionCreation: new Subject(),
1869
+ transactionApplying: new StatefulSubject(
1870
+ null
1871
+ ),
1872
+ operationClose: new Subject(),
1873
+ moleculeCreationStart: new Subject(),
1874
+ moleculeCreationDone: new Subject(),
1875
+ moleculeDisposal: new Subject()
1876
+ };
1877
+ this.operation = { open: false };
1878
+ this.config = {
1879
+ name: `IMPLICIT_STORE`,
1880
+ lifespan: `ephemeral`
1881
+ };
1882
+ this.loggers = [
1883
+ new atom_io.AtomIOLogger(`warn`, (_, __, key) => !key.includes(`\u{1F441}\u200D\u{1F5E8}`))
1884
+ ];
1885
+ this.logger = {
1886
+ error: (...messages) => {
1887
+ for (const logger of this.loggers) logger.error(...messages);
1888
+ },
1889
+ info: (...messages) => {
1890
+ for (const logger of this.loggers) logger.info(...messages);
1891
+ },
1892
+ warn: (...messages) => {
1893
+ for (const logger of this.loggers) logger.warn(...messages);
1894
+ }
1895
+ };
1896
+ if (store !== null) {
1897
+ this.valueMap = new Map(store == null ? void 0 : store.valueMap);
1898
+ this.operation = __spreadValues({}, store == null ? void 0 : store.operation);
1899
+ if (isRootStore(store)) {
1900
+ this.transactionMeta = {
1901
+ epoch: new Map(store == null ? void 0 : store.transactionMeta.epoch),
1902
+ actionContinuities: new Junction(
1903
+ store == null ? void 0 : store.transactionMeta.actionContinuities.toJSON()
1904
+ )
1905
+ };
1906
+ }
1907
+ this.config = __spreadValues(__spreadValues({}, store == null ? void 0 : store.config), config);
1908
+ for (const [, family] of store.families) {
1909
+ family.install(this);
1910
+ }
1911
+ const mutableHelpers = /* @__PURE__ */ new Set();
1912
+ for (const [, atom] of store.atoms) {
1913
+ if (mutableHelpers.has(atom.key)) {
1914
+ continue;
1915
+ }
1916
+ atom.install(this);
1917
+ if (atom.type === `mutable_atom`) {
1918
+ const originalJsonToken = getJsonToken(atom, store);
1919
+ const originalUpdateToken = getUpdateToken(atom);
1920
+ mutableHelpers.add(originalJsonToken.key);
1921
+ mutableHelpers.add(originalUpdateToken.key);
1922
+ }
1923
+ }
1924
+ for (const [, selector] of store.readonlySelectors) {
1925
+ selector.install(this);
1926
+ }
1927
+ for (const [, selector] of store.selectors) {
1928
+ if (mutableHelpers.has(selector.key)) {
1929
+ continue;
1930
+ }
1931
+ selector.install(this);
1932
+ }
1933
+ for (const [, tx] of store.transactions) {
1934
+ tx.install(this);
1935
+ }
1936
+ for (const [, timeline] of store.timelines) {
1937
+ timeline.install(this);
1938
+ }
1939
+ }
1940
+ }
1941
+ };
1942
+ var IMPLICIT = {
1943
+ STORE_INTERNAL: void 0,
1944
+ get STORE() {
1945
+ var _a;
1946
+ return (_a = this.STORE_INTERNAL) != null ? _a : this.STORE_INTERNAL = new Store({
1947
+ name: `IMPLICIT_STORE`,
1948
+ lifespan: `ephemeral`
1949
+ });
1950
+ }
1951
+ };
1952
+ var clearStore = (store) => {
1953
+ const { config } = store;
1954
+ for (const disposable of store.miscResources.values()) {
1955
+ disposable[Symbol.dispose]();
1956
+ }
1957
+ Object.assign(store, new Store(config));
1958
+ store.config = config;
1959
+ };
1960
+ function withdraw(token, store) {
1961
+ let withdrawn;
1962
+ let target = store;
1963
+ while (target !== null) {
1964
+ switch (token.type) {
1965
+ case `atom`:
1966
+ case `mutable_atom`:
1967
+ withdrawn = target.atoms.get(token.key);
1968
+ break;
1969
+ case `selector`:
1970
+ withdrawn = target.selectors.get(token.key);
1971
+ break;
1972
+ case `readonly_selector`:
1973
+ withdrawn = target.readonlySelectors.get(token.key);
1974
+ break;
1975
+ case `atom_family`:
1976
+ case `mutable_atom_family`:
1977
+ case `selector_family`:
1978
+ case `readonly_selector_family`:
1979
+ withdrawn = target.families.get(token.key);
1980
+ break;
1981
+ case `timeline`:
1982
+ withdrawn = target.timelines.get(token.key);
1983
+ break;
1984
+ case `transaction`:
1985
+ withdrawn = target.transactions.get(token.key);
1935
1986
  break;
1936
- case `readonly_selector`:
1937
- {
1938
- target.readonlySelectors.delete(key);
1939
- const family = withdraw(
1940
- { key: selector.family.key, type: `readonly_selector_family` },
1941
- store
1942
- );
1943
- family.subject.next({
1944
- type: `state_disposal`,
1945
- token: selectorToken
1946
- });
1947
- }
1987
+ case `molecule`:
1988
+ withdrawn = target.molecules.get(json.stringifyJson(token.key));
1989
+ break;
1990
+ case `molecule_family`:
1991
+ withdrawn = target.moleculeFamilies.get(token.key);
1948
1992
  break;
1949
1993
  }
1950
- target.valueMap.delete(key);
1951
- target.selectorAtoms.delete(key);
1952
- const downstreamTokens = target.selectorGraph.getRelationEntries({ upstreamSelectorKey: key }).filter(([_, { source }]) => source === key).map(
1953
- ([downstreamSelectorKey]) => {
1954
- var _a2;
1955
- return (_a2 = target.selectors.get(downstreamSelectorKey)) != null ? _a2 : target.readonlySelectors.get(downstreamSelectorKey);
1956
- }
1957
- );
1958
- for (const downstreamToken of downstreamTokens) {
1959
- if (downstreamToken) {
1960
- disposeSelector(downstreamToken, store);
1961
- }
1962
- }
1963
- target.selectorGraph.delete(key);
1964
- store.logger.info(`\u{1F525}`, selectorToken.type, key, `deleted`);
1965
- if (isChildStore(target) && target.transactionMeta.phase === `building`) {
1966
- target.transactionMeta.update.updates.push({
1967
- type: `state_disposal`,
1968
- token: selectorToken
1969
- });
1970
- } else {
1971
- store.on.selectorDisposal.next(selectorToken);
1994
+ if (withdrawn) {
1995
+ return withdrawn;
1972
1996
  }
1997
+ target = target.child;
1973
1998
  }
1999
+ throw new NotFoundError(token, store);
1974
2000
  }
1975
2001
 
1976
2002
  // internal/src/subscribe/recall-state.ts
@@ -2167,7 +2193,7 @@ var Tracker = class {
2167
2193
  subscribeToState(
2168
2194
  latestUpdateState,
2169
2195
  ({ newValue, oldValue }) => {
2170
- const timelineId = target.timelineAtoms.getRelatedKey(
2196
+ const timelineId = target.timelineTopics.getRelatedKey(
2171
2197
  latestUpdateState.key
2172
2198
  );
2173
2199
  if (timelineId) {
@@ -2618,6 +2644,10 @@ function disposeAtom(atomToken, store) {
2618
2644
  token: atomToken,
2619
2645
  value: lastValue
2620
2646
  });
2647
+ const molecule = target.molecules.get(atom.family.subKey);
2648
+ if (molecule) {
2649
+ molecule.tokens.delete(key);
2650
+ }
2621
2651
  target.atoms.delete(key);
2622
2652
  target.valueMap.delete(key);
2623
2653
  const selectorKeys = target.selectorAtoms.getRelatedKeys(key);
@@ -2631,7 +2661,7 @@ function disposeAtom(atomToken, store) {
2631
2661
  }
2632
2662
  target.selectorAtoms.delete(key);
2633
2663
  target.atomsThatAreDefault.delete(key);
2634
- target.timelineAtoms.delete(key);
2664
+ target.timelineTopics.delete(key);
2635
2665
  if (atomToken.type === `mutable_atom`) {
2636
2666
  const updateToken = getUpdateToken(atomToken);
2637
2667
  disposeAtom(updateToken, store);
@@ -2648,26 +2678,123 @@ function disposeAtom(atomToken, store) {
2648
2678
  }
2649
2679
  }
2650
2680
  }
2651
-
2652
- // internal/src/timeline/add-atom-to-timeline.ts
2653
- var addAtomToTimeline = (atomToken, tl, store) => {
2681
+ function createTimeline(options, store, data) {
2682
+ var _a;
2683
+ const tl = __spreadProps(__spreadValues({
2684
+ type: `timeline`,
2685
+ key: options.key,
2686
+ at: 0,
2687
+ timeTraveling: null,
2688
+ selectorTime: null,
2689
+ transactionKey: null
2690
+ }, data), {
2691
+ history: (_a = data == null ? void 0 : data.history.map((update) => __spreadValues({}, update))) != null ? _a : [],
2692
+ install: (s) => createTimeline(options, s, tl),
2693
+ subject: new Subject(),
2694
+ subscriptions: /* @__PURE__ */ new Map()
2695
+ });
2696
+ if (options.shouldCapture) {
2697
+ tl.shouldCapture = options.shouldCapture;
2698
+ }
2699
+ const timelineKey = options.key;
2700
+ const target = newest(store);
2701
+ for (const initialTopic of options.scope) {
2702
+ switch (initialTopic.type) {
2703
+ case `atom`:
2704
+ case `mutable_atom`:
2705
+ {
2706
+ const atomToken = initialTopic;
2707
+ const atomKey = atomToken.key;
2708
+ let existingTimelineKey = target.timelineTopics.getRelatedKey(atomKey);
2709
+ if (`family` in atomToken) {
2710
+ const familyKey = atomToken.family.key;
2711
+ existingTimelineKey = target.timelineTopics.getRelatedKey(familyKey);
2712
+ if (existingTimelineKey) {
2713
+ store.logger.error(
2714
+ `\u274C`,
2715
+ `timeline`,
2716
+ options.key,
2717
+ `Failed to add atom "${atomKey}" because its family "${familyKey}" already belongs to timeline "${existingTimelineKey}"`
2718
+ );
2719
+ continue;
2720
+ }
2721
+ }
2722
+ if (existingTimelineKey) {
2723
+ store.logger.error(
2724
+ `\u274C`,
2725
+ `timeline`,
2726
+ options.key,
2727
+ `Failed to add atom "${atomKey}" because it already belongs to timeline "${existingTimelineKey}"`
2728
+ );
2729
+ continue;
2730
+ }
2731
+ addAtomToTimeline(atomToken, tl, store);
2732
+ }
2733
+ break;
2734
+ case `atom_family`:
2735
+ case `mutable_atom_family`:
2736
+ {
2737
+ const familyToken = initialTopic;
2738
+ const familyKey = familyToken.key;
2739
+ const existingTimelineKey = target.timelineTopics.getRelatedKey(familyKey);
2740
+ if (existingTimelineKey) {
2741
+ store.logger.error(
2742
+ `\u274C`,
2743
+ `timeline`,
2744
+ options.key,
2745
+ `Failed to add atom family "${familyKey}" because it already belongs to timeline "${existingTimelineKey}"`
2746
+ );
2747
+ continue;
2748
+ }
2749
+ addAtomFamilyToTimeline(familyToken, tl, store);
2750
+ }
2751
+ break;
2752
+ case `molecule_family`:
2753
+ {
2754
+ const familyToken = initialTopic;
2755
+ const familyKey = familyToken.key;
2756
+ const existingTimelineKey = target.timelineTopics.getRelatedKey(familyKey);
2757
+ if (existingTimelineKey) {
2758
+ store.logger.error(
2759
+ `\u274C`,
2760
+ `timeline`,
2761
+ options.key,
2762
+ `Failed to add molecule family "${familyKey}" because it already belongs to timeline "${existingTimelineKey}"`
2763
+ );
2764
+ continue;
2765
+ }
2766
+ addMoleculeFamilyToTimeline(familyToken, tl, store);
2767
+ }
2768
+ break;
2769
+ }
2770
+ }
2771
+ store.timelines.set(options.key, tl);
2772
+ const token = {
2773
+ key: timelineKey,
2774
+ type: `timeline`
2775
+ };
2776
+ store.on.timelineCreation.next(token);
2777
+ return token;
2778
+ }
2779
+ function addAtomToTimeline(atomToken, tl, store) {
2654
2780
  let maybeAtom = withdraw(atomToken, store);
2655
2781
  if (maybeAtom.type === `mutable_atom`) {
2656
2782
  const updateToken = getUpdateToken(maybeAtom);
2657
2783
  maybeAtom = withdraw(updateToken, store);
2658
2784
  }
2659
2785
  const atom = maybeAtom;
2660
- store.timelineAtoms.set({ atomKey: atom.key, timelineKey: tl.key });
2786
+ store.timelineTopics.set(
2787
+ { topicKey: atom.key, timelineKey: tl.key },
2788
+ { topicType: `atom` }
2789
+ );
2661
2790
  tl.subscriptions.set(
2662
2791
  atom.key,
2663
2792
  atom.subject.subscribe(`timeline`, (update) => {
2664
- var _a, _b, _c, _d, _e, _f;
2793
+ var _a, _b, _c, _d, _e;
2665
2794
  const target = newest(store);
2666
2795
  const currentSelectorKey = store.operation.open && store.operation.token.type === `selector` ? store.operation.token.key : null;
2667
2796
  const currentSelectorTime = store.operation.open && store.operation.token.type === `selector` ? store.operation.time : null;
2668
- const { transactionApplying } = target.on;
2669
- const currentTransactionKey = (_a = transactionApplying.state) == null ? void 0 : _a.update.key;
2670
- const currentTransactionInstanceId = (_b = transactionApplying.state) == null ? void 0 : _b.update.id;
2797
+ const txUpdateInProgress = (_a = target.on.transactionApplying.state) == null ? void 0 : _a.update;
2671
2798
  store.logger.info(
2672
2799
  `\u23F3`,
2673
2800
  `timeline`,
@@ -2678,109 +2805,11 @@ var addAtomToTimeline = (atomToken, tl, store) => {
2678
2805
  update.oldValue,
2679
2806
  `->`,
2680
2807
  update.newValue,
2681
- currentTransactionKey ? `in transaction "${currentTransactionKey}"` : currentSelectorKey ? `in selector "${currentSelectorKey}"` : ``
2808
+ txUpdateInProgress ? `in transaction "${txUpdateInProgress.key}"` : currentSelectorKey ? `in selector "${currentSelectorKey}"` : ``
2682
2809
  );
2683
2810
  if (tl.timeTraveling === null) {
2684
- if (tl.selectorTime && tl.selectorTime !== currentSelectorTime) {
2685
- const mostRecentUpdate = tl.history.at(-1);
2686
- if (mostRecentUpdate === void 0) {
2687
- throw new Error(
2688
- `Timeline "${tl.key}" has a selectorTime, but no history. This is most likely a bug in AtomIO.`
2689
- );
2690
- }
2691
- }
2692
- if (currentTransactionKey) {
2693
- const txToken = {
2694
- key: currentTransactionKey,
2695
- type: `transaction`
2696
- };
2697
- const currentTransaction = withdraw(txToken, store);
2698
- if (tl.transactionKey !== currentTransactionKey) {
2699
- if (tl.transactionKey) {
2700
- store.logger.error(
2701
- `\u{1F41E}`,
2702
- `timeline`,
2703
- tl.key,
2704
- `unable to resolve transaction "${tl.transactionKey}. This is probably a bug in AtomIO.`
2705
- );
2706
- }
2707
- tl.transactionKey = currentTransactionKey;
2708
- const unsubscribe = currentTransaction.subject.subscribe(
2709
- `timeline:${tl.key}`,
2710
- (transactionUpdate) => {
2711
- var _a2, _b2;
2712
- unsubscribe();
2713
- if (tl.timeTraveling === null && currentTransactionInstanceId) {
2714
- if (tl.at !== tl.history.length) {
2715
- tl.history.splice(tl.at);
2716
- }
2717
- const filterUpdates = (updates2) => updates2.filter((updateFromTx) => {
2718
- var _a3, _b3;
2719
- const newestStore = newest(store);
2720
- if (`updates` in updateFromTx) {
2721
- return true;
2722
- }
2723
- const atomOrFamilyKeys = newestStore.timelineAtoms.getRelatedKeys(tl.key);
2724
- if (!atomOrFamilyKeys) {
2725
- return false;
2726
- }
2727
- let key;
2728
- let familyKey;
2729
- switch (updateFromTx.type) {
2730
- case `state_creation`:
2731
- case `state_disposal`:
2732
- key = updateFromTx.token.key;
2733
- familyKey = (_a3 = updateFromTx.token.family) == null ? void 0 : _a3.key;
2734
- break;
2735
- case `molecule_creation`:
2736
- case `molecule_disposal`:
2737
- break;
2738
- default:
2739
- key = updateFromTx.key;
2740
- familyKey = (_b3 = updateFromTx.family) == null ? void 0 : _b3.key;
2741
- break;
2742
- }
2743
- if (key === void 0) {
2744
- return false;
2745
- }
2746
- if (atomOrFamilyKeys.has(key)) {
2747
- return true;
2748
- }
2749
- if (familyKey !== void 0) {
2750
- return atomOrFamilyKeys.has(familyKey);
2751
- }
2752
- return false;
2753
- }).map((updateFromTx) => {
2754
- if (`updates` in updateFromTx) {
2755
- return __spreadProps(__spreadValues({}, updateFromTx), {
2756
- updates: filterUpdates(updateFromTx.updates)
2757
- });
2758
- }
2759
- return updateFromTx;
2760
- });
2761
- const updates = filterUpdates(transactionUpdate.updates);
2762
- const timelineTransactionUpdate = __spreadProps(__spreadValues({
2763
- timestamp: Date.now()
2764
- }, transactionUpdate), {
2765
- updates
2766
- });
2767
- const willCapture = (_b2 = (_a2 = tl.shouldCapture) == null ? void 0 : _a2.call(tl, timelineTransactionUpdate, tl)) != null ? _b2 : true;
2768
- if (willCapture) {
2769
- tl.history.push(timelineTransactionUpdate);
2770
- tl.at = tl.history.length;
2771
- tl.subject.next(timelineTransactionUpdate);
2772
- }
2773
- }
2774
- tl.transactionKey = null;
2775
- store.logger.info(
2776
- `\u231B`,
2777
- `timeline`,
2778
- tl.key,
2779
- `got a transaction_update "${transactionUpdate.key}"`
2780
- );
2781
- }
2782
- );
2783
- }
2811
+ if (txUpdateInProgress) {
2812
+ joinTransaction(tl, txUpdateInProgress, store);
2784
2813
  } else if (currentSelectorKey && currentSelectorTime) {
2785
2814
  let latestUpdate = tl.history.at(-1);
2786
2815
  if (currentSelectorTime !== tl.selectorTime) {
@@ -2823,7 +2852,7 @@ var addAtomToTimeline = (atomToken, tl, store) => {
2823
2852
  }
2824
2853
  }
2825
2854
  if (latestUpdate) {
2826
- const willCaptureSelectorUpdate = (_d = (_c = tl.shouldCapture) == null ? void 0 : _c.call(tl, latestUpdate, tl)) != null ? _d : true;
2855
+ const willCaptureSelectorUpdate = (_c = (_b = tl.shouldCapture) == null ? void 0 : _b.call(tl, latestUpdate, tl)) != null ? _c : true;
2827
2856
  if (willCaptureSelectorUpdate) {
2828
2857
  tl.subject.next(latestUpdate);
2829
2858
  } else {
@@ -2847,7 +2876,7 @@ var addAtomToTimeline = (atomToken, tl, store) => {
2847
2876
  if (atom.family) {
2848
2877
  atomUpdate.family = atom.family;
2849
2878
  }
2850
- const willCapture = (_f = (_e = tl.shouldCapture) == null ? void 0 : _e.call(tl, atomUpdate, tl)) != null ? _f : true;
2879
+ const willCapture = (_e = (_d = tl.shouldCapture) == null ? void 0 : _d.call(tl, atomUpdate, tl)) != null ? _e : true;
2851
2880
  store.logger.info(
2852
2881
  `\u231B`,
2853
2882
  `timeline`,
@@ -2863,181 +2892,207 @@ var addAtomToTimeline = (atomToken, tl, store) => {
2863
2892
  }
2864
2893
  })
2865
2894
  );
2866
- };
2867
- function createTimeline(options, store, data) {
2868
- var _a, _b;
2869
- const tl = __spreadProps(__spreadValues({
2870
- type: `timeline`,
2871
- key: options.key,
2872
- at: 0,
2873
- timeTraveling: null,
2874
- selectorTime: null,
2875
- transactionKey: null
2876
- }, data), {
2877
- history: (_a = data == null ? void 0 : data.history.map((update) => __spreadValues({}, update))) != null ? _a : [],
2878
- install: (s) => createTimeline(options, s, tl),
2879
- subject: new Subject(),
2880
- subscriptions: /* @__PURE__ */ new Map()
2881
- });
2882
- if (options.shouldCapture) {
2883
- tl.shouldCapture = options.shouldCapture;
2895
+ }
2896
+ function addAtomFamilyToTimeline(atomFamilyToken, tl, store) {
2897
+ var _a;
2898
+ const family = withdraw(atomFamilyToken, store);
2899
+ store.timelineTopics.set(
2900
+ { topicKey: family.key, timelineKey: tl.key },
2901
+ { topicType: `atom_family` }
2902
+ );
2903
+ tl.subscriptions.set(
2904
+ family.key,
2905
+ family.subject.subscribe(`timeline`, (creationOrDisposal) => {
2906
+ handleStateLifecycleEvent(creationOrDisposal, tl, store);
2907
+ })
2908
+ );
2909
+ for (const atom of store.atoms.values()) {
2910
+ if (((_a = atom.family) == null ? void 0 : _a.key) === family.key) {
2911
+ addAtomToTimeline(atom, tl, store);
2912
+ }
2884
2913
  }
2885
- const timelineKey = options.key;
2886
- const target = newest(store);
2887
- for (const tokenOrFamily of options.scope) {
2888
- let atomKey = tokenOrFamily.key;
2889
- switch (tokenOrFamily.type) {
2890
- case `atom_family`:
2891
- case `mutable_atom_family`:
2892
- {
2893
- const familyToken = tokenOrFamily;
2894
- const family = withdraw(familyToken, store);
2895
- const familyKey = family.key;
2896
- target.timelineAtoms.set({ atomKey: familyKey, timelineKey });
2897
- tl.subscriptions.set(
2898
- family.key,
2899
- family.subject.subscribe(
2900
- `timeline:${options.key}`,
2901
- (creationOrDisposal) => {
2902
- handleStateLifecycleEvent(creationOrDisposal, tl, store);
2914
+ }
2915
+ function addMoleculeFamilyToTimeline(familyToken, tl, store) {
2916
+ store.timelineTopics.set(
2917
+ { topicKey: familyToken.key, timelineKey: tl.key },
2918
+ { topicType: `molecule_family` }
2919
+ );
2920
+ const family = store.moleculeFamilies.get(familyToken.key);
2921
+ if (family) {
2922
+ tl.subscriptions.set(
2923
+ familyToken.key,
2924
+ family.subject.subscribe(`timeline:${tl.key}`, (creationOrDisposal) => {
2925
+ var _a, _b, _c, _d;
2926
+ store.logger.info(
2927
+ `\u{1F41E}`,
2928
+ `timeline`,
2929
+ tl.key,
2930
+ `got a molecule creation or disposal`,
2931
+ creationOrDisposal
2932
+ );
2933
+ switch (creationOrDisposal.type) {
2934
+ case `molecule_creation`:
2935
+ {
2936
+ store.timelineTopics.set(
2937
+ {
2938
+ topicKey: creationOrDisposal.token.key,
2939
+ timelineKey: tl.key
2940
+ },
2941
+ { topicType: `molecule` }
2942
+ );
2943
+ const txUpdateInProgress = (_a = newest(store).on.transactionApplying.state) == null ? void 0 : _a.update;
2944
+ if (txUpdateInProgress) {
2945
+ joinTransaction(tl, txUpdateInProgress, store);
2946
+ } else if (tl.timeTraveling === null) {
2947
+ const event = Object.assign(creationOrDisposal, {
2948
+ timestamp: Date.now()
2949
+ });
2950
+ tl.history.push(event);
2951
+ tl.at = tl.history.length;
2952
+ tl.subject.next(event);
2903
2953
  }
2904
- )
2905
- );
2906
- for (const atom of target.atoms.values()) {
2907
- if (((_b = atom.family) == null ? void 0 : _b.key) === familyKey) {
2908
- addAtomToTimeline(atom, tl, store);
2909
- }
2910
- }
2911
- }
2912
- break;
2913
- case `atom`:
2914
- case `mutable_atom`:
2915
- {
2916
- let atom = withdraw(tokenOrFamily, store);
2917
- if (isMutable(atom)) {
2918
- const updateAtom = withdraw(getUpdateToken(atom), store);
2919
- atom = updateAtom;
2920
- atomKey = atom.key;
2921
- }
2922
- if (`family` in atom) {
2923
- const familyTimelineKey = target.timelineAtoms.getRelatedKey(
2924
- atom.family.key
2925
- );
2926
- if (familyTimelineKey) {
2927
- store.logger.error(
2928
- `\u274C`,
2929
- `timeline`,
2930
- options.key,
2931
- `Failed to add atom "${atom.key}" because its family "${atom.family.key}" already belongs to timeline "${familyTimelineKey}"`
2954
+ const molecule = withdraw(creationOrDisposal.token, store);
2955
+ for (const token of molecule.tokens.values()) {
2956
+ switch (token.type) {
2957
+ case `atom`:
2958
+ case `mutable_atom`:
2959
+ addAtomToTimeline(token, tl, store);
2960
+ break;
2961
+ }
2962
+ }
2963
+ tl.subscriptions.set(
2964
+ molecule.key,
2965
+ molecule.subject.subscribe(
2966
+ `timeline:${tl.key}`,
2967
+ (stateCreationOrDisposal) => {
2968
+ handleStateLifecycleEvent(stateCreationOrDisposal, tl, store);
2969
+ }
2970
+ )
2932
2971
  );
2933
- continue;
2934
2972
  }
2973
+ break;
2974
+ case `molecule_disposal`:
2975
+ {
2976
+ const txUpdateInProgress = (_b = newest(store).on.transactionApplying.state) == null ? void 0 : _b.update;
2977
+ if (txUpdateInProgress) {
2978
+ joinTransaction(tl, txUpdateInProgress, store);
2979
+ } else if (tl.timeTraveling === null) {
2980
+ const event = Object.assign(creationOrDisposal, {
2981
+ timestamp: Date.now()
2982
+ });
2983
+ tl.history.push(event);
2984
+ tl.at = tl.history.length;
2985
+ tl.subject.next(event);
2986
+ }
2987
+ const moleculeKey = creationOrDisposal.token.key;
2988
+ (_c = tl.subscriptions.get(moleculeKey)) == null ? void 0 : _c();
2989
+ tl.subscriptions.delete(moleculeKey);
2990
+ for (const [familyKey] of creationOrDisposal.values) {
2991
+ const stateKey = `${familyKey}(${json.stringifyJson(moleculeKey)})`;
2992
+ (_d = tl.subscriptions.get(stateKey)) == null ? void 0 : _d();
2993
+ tl.subscriptions.delete(stateKey);
2994
+ store.timelineTopics.delete(stateKey);
2995
+ }
2996
+ }
2997
+ break;
2998
+ }
2999
+ })
3000
+ );
3001
+ }
3002
+ }
3003
+ function joinTransaction(tl, txUpdateInProgress, store) {
3004
+ const currentTxKey = txUpdateInProgress.key;
3005
+ const currentTxInstanceId = txUpdateInProgress.id;
3006
+ const currentTxToken = {
3007
+ key: currentTxKey,
3008
+ type: `transaction`
3009
+ };
3010
+ const currentTransaction = withdraw(currentTxToken, store);
3011
+ if (currentTxKey && tl.transactionKey === null) {
3012
+ tl.transactionKey = currentTxKey;
3013
+ const unsubscribe = currentTransaction.subject.subscribe(
3014
+ `timeline:${tl.key}`,
3015
+ (transactionUpdate) => {
3016
+ var _a, _b;
3017
+ unsubscribe();
3018
+ tl.transactionKey = null;
3019
+ if (tl.timeTraveling === null && currentTxInstanceId) {
3020
+ if (tl.at !== tl.history.length) {
3021
+ tl.history.splice(tl.at);
2935
3022
  }
2936
- const existingTimelineKey = target.timelineAtoms.getRelatedKey(atomKey);
2937
- if (existingTimelineKey) {
2938
- store.logger.error(
2939
- `\u274C`,
2940
- `timeline`,
2941
- options.key,
2942
- `Failed to add atom "${atomKey}" because it already belongs to timeline "${existingTimelineKey}"`
2943
- );
2944
- continue;
3023
+ const timelineTopics = store.timelineTopics.getRelatedKeys(tl.key);
3024
+ const updates = filterTransactionUpdates(
3025
+ transactionUpdate.updates,
3026
+ timelineTopics
3027
+ );
3028
+ const timelineTransactionUpdate = __spreadProps(__spreadValues({
3029
+ timestamp: Date.now()
3030
+ }, transactionUpdate), {
3031
+ updates
3032
+ });
3033
+ const willCapture = (_b = (_a = tl.shouldCapture) == null ? void 0 : _a.call(tl, timelineTransactionUpdate, tl)) != null ? _b : true;
3034
+ if (willCapture) {
3035
+ tl.history.push(timelineTransactionUpdate);
3036
+ tl.at = tl.history.length;
3037
+ tl.subject.next(timelineTransactionUpdate);
2945
3038
  }
2946
- addAtomToTimeline(atom, tl, store);
2947
3039
  }
3040
+ }
3041
+ );
3042
+ }
3043
+ }
3044
+ function filterTransactionUpdates(updates, timelineTopics) {
3045
+ return updates.filter((updateFromTx) => {
3046
+ if (updateFromTx.type === `transaction_update`) {
3047
+ return true;
3048
+ }
3049
+ let key;
3050
+ switch (updateFromTx.type) {
3051
+ case `state_creation`:
3052
+ case `state_disposal`:
3053
+ case `molecule_creation`:
3054
+ case `molecule_disposal`:
3055
+ key = updateFromTx.token.key;
2948
3056
  break;
2949
- case `molecule_family`:
2950
- {
2951
- const family = store.moleculeFamilies.get(tokenOrFamily.key);
2952
- if (family) {
2953
- tl.subscriptions.set(
2954
- tokenOrFamily.key,
2955
- family.subject.subscribe(
2956
- `timeline:${options.key}`,
2957
- (creationOrDisposal) => {
2958
- var _a2, _b2;
2959
- switch (creationOrDisposal.type) {
2960
- case `molecule_creation`:
2961
- {
2962
- const molecule = store.molecules.get(
2963
- json.stringifyJson(creationOrDisposal.token.key)
2964
- );
2965
- if (molecule) {
2966
- const event = Object.assign(creationOrDisposal, {
2967
- timestamp: Date.now()
2968
- });
2969
- tl.history.push(event);
2970
- tl.at = tl.history.length;
2971
- tl.subject.next(event);
2972
- for (const token2 of molecule.tokens.values()) {
2973
- switch (token2.type) {
2974
- case `atom`:
2975
- case `mutable_atom`:
2976
- addAtomToTimeline(token2, tl, store);
2977
- break;
2978
- }
2979
- }
2980
- tl.subscriptions.set(
2981
- molecule.key,
2982
- molecule.subject.subscribe(
2983
- `timeline:${options.key}`,
2984
- (stateCreationOrDisposal) => {
2985
- handleStateLifecycleEvent(
2986
- stateCreationOrDisposal,
2987
- tl,
2988
- store
2989
- );
2990
- }
2991
- )
2992
- );
2993
- }
2994
- }
2995
- break;
2996
- case `molecule_disposal`:
2997
- (_a2 = tl.subscriptions.get(creationOrDisposal.token.key)) == null ? void 0 : _a2();
2998
- tl.subscriptions.delete(creationOrDisposal.token.key);
2999
- for (const familyKey of creationOrDisposal.familyKeys) {
3000
- const stateKey = `${familyKey}(${json.stringifyJson(
3001
- creationOrDisposal.token.key
3002
- )})`;
3003
- (_b2 = tl.subscriptions.get(stateKey)) == null ? void 0 : _b2();
3004
- tl.subscriptions.delete(stateKey);
3005
- }
3006
- break;
3007
- }
3008
- }
3009
- )
3010
- );
3011
- }
3012
- }
3057
+ default:
3058
+ key = updateFromTx.key;
3013
3059
  break;
3014
3060
  }
3015
- }
3016
- store.timelines.set(options.key, tl);
3017
- const token = {
3018
- key: timelineKey,
3019
- type: `timeline`
3020
- };
3021
- store.on.timelineCreation.next(token);
3022
- return token;
3061
+ return timelineTopics.has(key);
3062
+ }).map((updateFromTx) => {
3063
+ if (`updates` in updateFromTx) {
3064
+ return __spreadProps(__spreadValues({}, updateFromTx), {
3065
+ updates: filterTransactionUpdates(
3066
+ updateFromTx.updates,
3067
+ timelineTopics
3068
+ )
3069
+ });
3070
+ }
3071
+ return updateFromTx;
3072
+ });
3023
3073
  }
3024
3074
  function handleStateLifecycleEvent(event, tl, store) {
3025
- var _a;
3075
+ var _a, _b;
3026
3076
  const timestamp = Date.now();
3027
3077
  const timelineEvent = Object.assign(event, {
3028
3078
  timestamp
3029
3079
  });
3030
3080
  if (!tl.timeTraveling) {
3031
- tl.history.push(timelineEvent);
3032
- tl.at = tl.history.length;
3033
- tl.subject.next(timelineEvent);
3081
+ const txUpdateInProgress = (_a = newest(store).on.transactionApplying.state) == null ? void 0 : _a.update;
3082
+ if (txUpdateInProgress) {
3083
+ joinTransaction(tl, txUpdateInProgress, store);
3084
+ } else {
3085
+ tl.history.push(timelineEvent);
3086
+ tl.at = tl.history.length;
3087
+ tl.subject.next(timelineEvent);
3088
+ }
3034
3089
  }
3035
3090
  switch (event.type) {
3036
3091
  case `state_creation`:
3037
3092
  addAtomToTimeline(event.token, tl, store);
3038
3093
  break;
3039
3094
  case `state_disposal`:
3040
- (_a = tl.subscriptions.get(event.token.key)) == null ? void 0 : _a();
3095
+ (_b = tl.subscriptions.get(event.token.key)) == null ? void 0 : _b();
3041
3096
  tl.subscriptions.delete(event.token.key);
3042
3097
  break;
3043
3098
  }
@@ -3132,7 +3187,6 @@ exports.TRANSACTION_PHASES = TRANSACTION_PHASES;
3132
3187
  exports.Tracker = Tracker;
3133
3188
  exports.abortTransaction = abortTransaction;
3134
3189
  exports.actUponStore = actUponStore;
3135
- exports.addAtomToTimeline = addAtomToTimeline;
3136
3190
  exports.applyTransaction = applyTransaction;
3137
3191
  exports.arbitrary = arbitrary;
3138
3192
  exports.assignTransactionToContinuity = assignTransactionToContinuity;