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