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