atom.io 0.22.0 → 0.23.1
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/data/dist/index.cjs +17 -1
- package/data/dist/index.js +1 -1
- package/data/src/join.ts +30 -1
- package/dist/chunk-6MLFYN32.js +18 -0
- package/dist/{chunk-JA4V7TJY.js → chunk-7DT3PVS3.js} +18 -2
- package/dist/chunk-OAYGID5B.js +27 -0
- package/dist/index.cjs +2 -11
- package/dist/index.d.ts +51 -23
- package/dist/index.js +2 -11
- package/ephemeral/dist/index.d.ts +12 -0
- package/eslint-plugin/dist/index.cjs +0 -1
- package/eslint-plugin/dist/index.d.ts +73 -0
- package/eslint-plugin/dist/index.js +0 -1
- package/eslint-plugin/src/rules/lifespan.ts +0 -1
- package/immortal/dist/index.cjs +180 -20
- package/immortal/dist/index.d.ts +103 -0
- package/immortal/dist/index.js +134 -19
- package/immortal/src/index.ts +1 -0
- package/immortal/src/make-molecule.ts +222 -0
- package/immortal/src/molecule.ts +49 -16
- package/immortal/src/seek-state.ts +15 -2
- package/internal/dist/index.cjs +1119 -754
- package/internal/dist/index.d.ts +109 -12
- package/internal/dist/index.js +1098 -760
- package/internal/src/atom/create-regular-atom.ts +0 -2
- package/internal/src/atom/create-standalone-atom.ts +6 -2
- package/internal/src/atom/dispose-atom.ts +22 -2
- package/internal/src/families/create-readonly-selector-family.ts +7 -2
- package/internal/src/families/create-regular-atom-family.ts +6 -2
- package/internal/src/families/create-writable-selector-family.ts +7 -2
- package/internal/src/families/dispose-from-store.ts +22 -0
- package/internal/src/families/find-in-store.ts +0 -1
- package/internal/src/families/index.ts +1 -0
- package/internal/src/families/init-family-member.ts +22 -1
- package/internal/src/families/seek-in-store.ts +23 -6
- package/internal/src/ingest-updates/index.ts +1 -0
- package/internal/src/ingest-updates/ingest-creation-disposal.ts +104 -0
- package/internal/src/ingest-updates/ingest-transaction-update.ts +26 -4
- package/internal/src/mutable/create-mutable-atom-family.ts +6 -2
- package/internal/src/mutable/create-mutable-atom.ts +0 -2
- package/internal/src/mutable/get-json-token.ts +0 -1
- package/internal/src/mutable/tracker-family.ts +7 -7
- package/internal/src/not-found-error.ts +5 -0
- package/internal/src/selector/create-readonly-selector.ts +2 -3
- package/internal/src/selector/create-standalone-selector.ts +6 -2
- package/internal/src/selector/create-writable-selector.ts +2 -3
- package/internal/src/selector/dispose-selector.ts +32 -5
- package/internal/src/selector/register-selector.ts +2 -0
- package/internal/src/set-state/stow-update.ts +5 -1
- package/internal/src/store/deposit.ts +41 -7
- package/internal/src/store/store.ts +11 -0
- package/internal/src/store/withdraw.ts +28 -1
- package/internal/src/timeline/add-atom-to-timeline.ts +206 -182
- package/internal/src/timeline/create-timeline.ts +181 -60
- package/internal/src/timeline/time-travel.ts +20 -0
- package/internal/src/transaction/apply-transaction.ts +2 -12
- package/internal/src/transaction/build-transaction.ts +11 -2
- package/introspection/dist/index.cjs +2 -1
- package/introspection/dist/index.js +2 -1
- package/introspection/src/attach-timeline-family.ts +1 -0
- package/json/dist/index.cjs +3 -3
- package/json/dist/index.js +6 -5
- package/json/src/select-json-family.ts +3 -4
- package/package.json +8 -5
- package/react-devtools/dist/index.cjs +58 -47
- package/react-devtools/dist/index.js +60 -48
- package/react-devtools/src/TimelineIndex.tsx +15 -13
- package/react-devtools/src/Updates.tsx +41 -32
- package/realtime-server/dist/index.cjs +21 -10
- package/realtime-server/dist/index.d.ts +1 -1
- package/realtime-server/dist/index.js +21 -11
- package/realtime-server/src/realtime-server-stores/server-sync-store.ts +21 -11
- package/realtime-testing/dist/index.cjs +1 -0
- package/realtime-testing/dist/index.js +1 -1
- package/src/atom.ts +9 -3
- package/src/dispose-state.ts +3 -12
- package/src/index.ts +4 -0
- package/src/selector.ts +3 -3
- package/src/subscribe.ts +8 -4
- package/src/timeline.ts +18 -1
- package/src/transaction.ts +56 -4
- package/dist/chunk-BF4MVQF6.js +0 -44
package/internal/dist/index.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { Junction } from '../../dist/chunk-FTONNX2R.js';
|
|
2
|
+
import { parseJson } from '../../dist/chunk-OAYGID5B.js';
|
|
2
3
|
import { __spreadValues, __spreadProps } from '../../dist/chunk-F2X4B4VY.js';
|
|
3
|
-
import { stringifyJson, selectJson, parseJson, selectJsonFamily } from 'atom.io/json';
|
|
4
|
+
import { stringifyJson, selectJson, parseJson as parseJson$1, selectJsonFamily } from 'atom.io/json';
|
|
4
5
|
import { AtomIOLogger } from 'atom.io';
|
|
6
|
+
import { disposeMolecule, makeMoleculeInStore } from 'atom.io/immortal';
|
|
7
|
+
import * as Internal from 'atom.io/internal';
|
|
5
8
|
|
|
6
9
|
// internal/src/arbitrary.ts
|
|
7
10
|
function arbitrary(random = Math.random) {
|
|
@@ -60,14 +63,26 @@ function newest(scion) {
|
|
|
60
63
|
|
|
61
64
|
// internal/src/store/deposit.ts
|
|
62
65
|
function deposit(state) {
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
const { type } = state;
|
|
67
|
+
switch (type) {
|
|
68
|
+
case `atom`:
|
|
69
|
+
case `molecule_family`:
|
|
70
|
+
case `mutable_atom`:
|
|
71
|
+
case `selector`:
|
|
72
|
+
case `readonly_selector`:
|
|
73
|
+
case `transaction`: {
|
|
74
|
+
const token = {
|
|
75
|
+
key: state.key,
|
|
76
|
+
type: state.type
|
|
77
|
+
};
|
|
78
|
+
if (`family` in state) {
|
|
79
|
+
token.family = state.family;
|
|
80
|
+
}
|
|
81
|
+
return token;
|
|
82
|
+
}
|
|
83
|
+
case `molecule`:
|
|
84
|
+
return state.token;
|
|
69
85
|
}
|
|
70
|
-
return token;
|
|
71
86
|
}
|
|
72
87
|
|
|
73
88
|
// internal/src/subject.ts
|
|
@@ -143,6 +158,7 @@ var Store = class {
|
|
|
143
158
|
}
|
|
144
159
|
);
|
|
145
160
|
this.molecules = /* @__PURE__ */ new Map();
|
|
161
|
+
this.moleculeFamilies = /* @__PURE__ */ new Map();
|
|
146
162
|
this.miscResources = /* @__PURE__ */ new Map();
|
|
147
163
|
this.on = {
|
|
148
164
|
atomCreation: new Subject(),
|
|
@@ -154,7 +170,10 @@ var Store = class {
|
|
|
154
170
|
transactionApplying: new StatefulSubject(
|
|
155
171
|
null
|
|
156
172
|
),
|
|
157
|
-
operationClose: new Subject()
|
|
173
|
+
operationClose: new Subject(),
|
|
174
|
+
moleculeCreationStart: new Subject(),
|
|
175
|
+
moleculeCreationDone: new Subject(),
|
|
176
|
+
moleculeDisposal: new Subject()
|
|
158
177
|
};
|
|
159
178
|
this.operation = { open: false };
|
|
160
179
|
this.transactionMeta = {
|
|
@@ -249,8 +268,6 @@ var clearStore = (store) => {
|
|
|
249
268
|
Object.assign(store, new Store(config));
|
|
250
269
|
store.config = config;
|
|
251
270
|
};
|
|
252
|
-
|
|
253
|
-
// internal/src/store/withdraw.ts
|
|
254
271
|
function withdraw(token, store) {
|
|
255
272
|
let withdrawn;
|
|
256
273
|
let target = store;
|
|
@@ -278,6 +295,12 @@ function withdraw(token, store) {
|
|
|
278
295
|
case `transaction`:
|
|
279
296
|
withdrawn = target.transactions.get(token.key);
|
|
280
297
|
break;
|
|
298
|
+
case `molecule`:
|
|
299
|
+
withdrawn = target.molecules.get(stringifyJson(token.key));
|
|
300
|
+
break;
|
|
301
|
+
case `molecule_family`:
|
|
302
|
+
withdrawn = target.moleculeFamilies.get(token.key);
|
|
303
|
+
break;
|
|
281
304
|
}
|
|
282
305
|
if (withdrawn) {
|
|
283
306
|
return withdrawn;
|
|
@@ -324,7 +347,7 @@ function createRegularAtomFamily(options, store) {
|
|
|
324
347
|
individualOptions.effects = options.effects(key);
|
|
325
348
|
}
|
|
326
349
|
const token = createRegularAtom(individualOptions, family, target);
|
|
327
|
-
subject.next(token);
|
|
350
|
+
subject.next({ type: `state_creation`, token });
|
|
328
351
|
return token;
|
|
329
352
|
},
|
|
330
353
|
{
|
|
@@ -362,7 +385,7 @@ function createReadonlySelectorFamily(options, store) {
|
|
|
362
385
|
family,
|
|
363
386
|
target
|
|
364
387
|
);
|
|
365
|
-
subject.next(token);
|
|
388
|
+
subject.next({ type: `state_creation`, token });
|
|
366
389
|
return token;
|
|
367
390
|
},
|
|
368
391
|
{
|
|
@@ -392,7 +415,7 @@ function createWritableSelectorFamily(options, store) {
|
|
|
392
415
|
family,
|
|
393
416
|
target
|
|
394
417
|
);
|
|
395
|
-
subject.next(token);
|
|
418
|
+
subject.next({ type: `state_creation`, token });
|
|
396
419
|
return token;
|
|
397
420
|
},
|
|
398
421
|
{
|
|
@@ -414,6 +437,21 @@ function createSelectorFamily(options, store) {
|
|
|
414
437
|
}
|
|
415
438
|
return createReadonlySelectorFamily(options, store);
|
|
416
439
|
}
|
|
440
|
+
function disposeFromStore(token, store = Internal.IMPLICIT.STORE) {
|
|
441
|
+
switch (token.type) {
|
|
442
|
+
case `atom`:
|
|
443
|
+
case `mutable_atom`:
|
|
444
|
+
Internal.disposeAtom(token, store);
|
|
445
|
+
break;
|
|
446
|
+
case `selector`:
|
|
447
|
+
case `readonly_selector`:
|
|
448
|
+
Internal.disposeSelector(token, store);
|
|
449
|
+
break;
|
|
450
|
+
case `molecule`:
|
|
451
|
+
disposeMolecule(token, store);
|
|
452
|
+
break;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
417
455
|
|
|
418
456
|
// internal/src/not-found-error.ts
|
|
419
457
|
var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
|
|
@@ -421,6 +459,8 @@ function prettyPrintTokenType(token) {
|
|
|
421
459
|
switch (token.type) {
|
|
422
460
|
case `atom_family`:
|
|
423
461
|
return `Atom Family`;
|
|
462
|
+
case `molecule_family`:
|
|
463
|
+
return `Molecule Family`;
|
|
424
464
|
case `readonly_selector`:
|
|
425
465
|
return `Readonly Selector`;
|
|
426
466
|
case `readonly_selector_family`:
|
|
@@ -439,53 +479,36 @@ var NotFoundError = class extends Error {
|
|
|
439
479
|
}
|
|
440
480
|
};
|
|
441
481
|
|
|
442
|
-
// internal/src/
|
|
443
|
-
|
|
444
|
-
const familyKey = token.key;
|
|
445
|
-
const family = store.families.get(familyKey);
|
|
446
|
-
if (family === void 0) {
|
|
447
|
-
throw new NotFoundError(token, store);
|
|
448
|
-
}
|
|
449
|
-
const state = family(key);
|
|
450
|
-
return state;
|
|
451
|
-
}
|
|
452
|
-
function seekInStore(token, key, store) {
|
|
453
|
-
const subKey = stringifyJson(key);
|
|
454
|
-
const fullKey = `${token.key}(${subKey})`;
|
|
482
|
+
// internal/src/transaction/abort-transaction.ts
|
|
483
|
+
var abortTransaction = (store) => {
|
|
455
484
|
const target = newest(store);
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
case `selector_family`: {
|
|
463
|
-
state = target.selectors.get(fullKey);
|
|
464
|
-
break;
|
|
465
|
-
}
|
|
466
|
-
case `readonly_selector_family`:
|
|
467
|
-
state = target.readonlySelectors.get(fullKey);
|
|
468
|
-
break;
|
|
469
|
-
}
|
|
470
|
-
if (state) {
|
|
471
|
-
return deposit(state);
|
|
472
|
-
}
|
|
473
|
-
return state;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
// internal/src/families/find-in-store.ts
|
|
477
|
-
function findInStore(token, key, store) {
|
|
478
|
-
if (store.config.lifespan === `immortal`) {
|
|
479
|
-
throw new Error(
|
|
480
|
-
`Do not use \`find\` or \`findState\` in an immortal store. Prefer \`seek\` or \`seekState\`.`
|
|
485
|
+
if (!isChildStore(target)) {
|
|
486
|
+
store.logger.warn(
|
|
487
|
+
`\u{1F41E}`,
|
|
488
|
+
`transaction`,
|
|
489
|
+
`???`,
|
|
490
|
+
`abortTransaction called outside of a transaction. This is probably a bug in AtomIO.`
|
|
481
491
|
);
|
|
492
|
+
return;
|
|
482
493
|
}
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
494
|
+
store.logger.info(
|
|
495
|
+
`\u{1FA82}`,
|
|
496
|
+
`transaction`,
|
|
497
|
+
target.transactionMeta.update.key,
|
|
498
|
+
`Aborting transaction`
|
|
499
|
+
);
|
|
500
|
+
target.parent.child = null;
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
// internal/src/transaction/act-upon-store.ts
|
|
504
|
+
function actUponStore(token, id, store) {
|
|
505
|
+
return (...parameters) => {
|
|
506
|
+
const tx = withdraw(token, store);
|
|
507
|
+
if (tx) {
|
|
508
|
+
return tx.run(parameters, id);
|
|
509
|
+
}
|
|
510
|
+
throw new NotFoundError(token, store);
|
|
511
|
+
};
|
|
489
512
|
}
|
|
490
513
|
|
|
491
514
|
// internal/src/set-state/become.ts
|
|
@@ -641,7 +664,10 @@ var stowUpdate = (state, update, store) => {
|
|
|
641
664
|
if (!shouldStow) {
|
|
642
665
|
return;
|
|
643
666
|
}
|
|
644
|
-
const atomUpdate = __spreadValues({
|
|
667
|
+
const atomUpdate = __spreadValues({
|
|
668
|
+
type: `atom_update`,
|
|
669
|
+
key
|
|
670
|
+
}, update);
|
|
645
671
|
if (state.family) {
|
|
646
672
|
atomUpdate.family = state.family;
|
|
647
673
|
}
|
|
@@ -734,162 +760,613 @@ function setIntoStore(token, value, store) {
|
|
|
734
760
|
closeOperation(store);
|
|
735
761
|
}
|
|
736
762
|
|
|
737
|
-
// internal/src/
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
const indirectDependencyKeys = getSelectorDependencyKeys(
|
|
753
|
-
directDependencyKey,
|
|
754
|
-
store
|
|
755
|
-
);
|
|
756
|
-
let depth = 0;
|
|
757
|
-
while (indirectDependencyKeys.length > 0) {
|
|
758
|
-
const indirectDependencyKey = indirectDependencyKeys.shift();
|
|
759
|
-
++depth;
|
|
760
|
-
if (depth > 99999) {
|
|
761
|
-
throw new Error(
|
|
762
|
-
`Maximum selector dependency depth exceeded (> 99999) in selector "${selectorKey}". This is likely due to a circular dependency.`
|
|
763
|
-
);
|
|
763
|
+
// internal/src/ingest-updates/ingest-atom-update.ts
|
|
764
|
+
function ingestAtomUpdate(applying, atomUpdate, store) {
|
|
765
|
+
const { key, newValue, oldValue } = atomUpdate;
|
|
766
|
+
const value = applying === `newValue` ? newValue : oldValue;
|
|
767
|
+
const token = { key, type: `atom` };
|
|
768
|
+
if (atomUpdate.family) {
|
|
769
|
+
Object.assign(token, { family: atomUpdate.family });
|
|
770
|
+
}
|
|
771
|
+
setIntoStore(token, value, store);
|
|
772
|
+
}
|
|
773
|
+
function ingestCreationEvent(update, applying, store) {
|
|
774
|
+
switch (applying) {
|
|
775
|
+
case `newValue`: {
|
|
776
|
+
createInStore(update.token, store);
|
|
777
|
+
break;
|
|
764
778
|
}
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
);
|
|
769
|
-
} else if (!rootKeys.includes(indirectDependencyKey)) {
|
|
770
|
-
rootKeys.push(indirectDependencyKey);
|
|
779
|
+
case `oldValue`: {
|
|
780
|
+
disposeFromStore(update.token, store);
|
|
781
|
+
break;
|
|
771
782
|
}
|
|
772
783
|
}
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
var updateSelectorAtoms = (selectorKey, dependency, store) => {
|
|
785
|
-
const target = newest(store);
|
|
786
|
-
if (dependency.type === `atom` || dependency.type === `mutable_atom`) {
|
|
787
|
-
target.selectorAtoms.set({
|
|
788
|
-
selectorKey,
|
|
789
|
-
atomKey: dependency.key
|
|
790
|
-
});
|
|
791
|
-
store.logger.info(
|
|
792
|
-
`\u{1F50D}`,
|
|
793
|
-
`selector`,
|
|
794
|
-
selectorKey,
|
|
795
|
-
`discovers root atom "${dependency.key}"`
|
|
796
|
-
);
|
|
797
|
-
} else {
|
|
798
|
-
const rootKeys = traceSelectorAtoms(selectorKey, dependency.key, store);
|
|
799
|
-
store.logger.info(
|
|
800
|
-
`\u{1F50D}`,
|
|
801
|
-
`selector`,
|
|
802
|
-
selectorKey,
|
|
803
|
-
`discovers root atoms: [ ${rootKeys.map((key) => `"${key}"`).join(`, `)} ]`
|
|
804
|
-
);
|
|
805
|
-
for (const atomKey of rootKeys) {
|
|
806
|
-
target.selectorAtoms = target.selectorAtoms.set({
|
|
807
|
-
selectorKey,
|
|
808
|
-
atomKey
|
|
809
|
-
});
|
|
784
|
+
}
|
|
785
|
+
function ingestDisposalEvent(update, applying, store) {
|
|
786
|
+
switch (applying) {
|
|
787
|
+
case `newValue`: {
|
|
788
|
+
disposeFromStore(update.token, store);
|
|
789
|
+
break;
|
|
790
|
+
}
|
|
791
|
+
case `oldValue`: {
|
|
792
|
+
createInStore(update.token, store);
|
|
793
|
+
store.valueMap.set(update.token.key, update.value);
|
|
794
|
+
break;
|
|
810
795
|
}
|
|
811
796
|
}
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
`\u{1F50C}`,
|
|
822
|
-
`selector`,
|
|
823
|
-
selectorKey,
|
|
824
|
-
`registers dependency ( "${dependency.key}" =`,
|
|
825
|
-
dependencyValue,
|
|
826
|
-
`)`
|
|
827
|
-
);
|
|
828
|
-
target.selectorGraph.set(
|
|
829
|
-
{
|
|
830
|
-
upstreamSelectorKey: dependency.key,
|
|
831
|
-
downstreamSelectorKey: selectorKey
|
|
832
|
-
},
|
|
833
|
-
{
|
|
834
|
-
source: dependency.key
|
|
797
|
+
}
|
|
798
|
+
function createInStore(token, store) {
|
|
799
|
+
if (token.family) {
|
|
800
|
+
const family = store.families.get(token.family.key);
|
|
801
|
+
if (family) {
|
|
802
|
+
const molecule = store.molecules.get(token.family.subKey);
|
|
803
|
+
if (molecule) {
|
|
804
|
+
molecule.bond(family);
|
|
805
|
+
return;
|
|
835
806
|
}
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
const state = withdraw(WritableToken, store);
|
|
842
|
-
setAtomOrSelector(state, newValue, store);
|
|
843
|
-
},
|
|
844
|
-
find: (token, key) => findInStore(token, key, store),
|
|
845
|
-
seek: (token, key) => seekInStore(token, key, store)
|
|
846
|
-
});
|
|
847
|
-
|
|
848
|
-
// internal/src/selector/create-readonly-selector.ts
|
|
849
|
-
var createReadonlySelector = (options, family, store) => {
|
|
850
|
-
const target = newest(store);
|
|
851
|
-
const subject = new Subject();
|
|
852
|
-
const { get, find, seek } = registerSelector(options.key, target);
|
|
853
|
-
const getSelf = () => {
|
|
854
|
-
const value = options.get({ get, find, seek });
|
|
855
|
-
cacheValue(options.key, value, subject, newest(store));
|
|
856
|
-
return value;
|
|
857
|
-
};
|
|
858
|
-
const readonlySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
|
|
859
|
-
subject,
|
|
860
|
-
install: (s) => createReadonlySelector(options, family, s),
|
|
861
|
-
get: getSelf,
|
|
862
|
-
type: `readonly_selector`
|
|
863
|
-
}), family && { family });
|
|
864
|
-
target.readonlySelectors.set(options.key, readonlySelector);
|
|
865
|
-
const initialValue = getSelf();
|
|
866
|
-
store.logger.info(
|
|
867
|
-
`\u2728`,
|
|
868
|
-
readonlySelector.type,
|
|
869
|
-
readonlySelector.key,
|
|
870
|
-
`=`,
|
|
871
|
-
initialValue
|
|
872
|
-
);
|
|
873
|
-
const token = {
|
|
874
|
-
key: options.key,
|
|
875
|
-
type: `readonly_selector`
|
|
876
|
-
};
|
|
877
|
-
if (family) {
|
|
878
|
-
token.family = family;
|
|
807
|
+
if (store.config.lifespan === `immortal`) {
|
|
808
|
+
throw new Error(`No molecule found for key "${token.family.subKey}"`);
|
|
809
|
+
}
|
|
810
|
+
initFamilyMember(family, parseJson(token.family.subKey), store);
|
|
811
|
+
}
|
|
879
812
|
}
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
813
|
+
}
|
|
814
|
+
function ingestMoleculeCreationEvent(update, applying, store) {
|
|
815
|
+
switch (applying) {
|
|
816
|
+
case `newValue`:
|
|
817
|
+
makeMoleculeInStore(
|
|
818
|
+
store,
|
|
819
|
+
update.context[0],
|
|
820
|
+
update.family,
|
|
821
|
+
update.token.key,
|
|
822
|
+
...update.params
|
|
823
|
+
);
|
|
824
|
+
break;
|
|
825
|
+
case `oldValue`:
|
|
826
|
+
disposeMolecule(update.token, store);
|
|
827
|
+
break;
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
function ingestMoleculeDisposalEvent(update, applying, store) {
|
|
831
|
+
switch (applying) {
|
|
832
|
+
case `newValue`:
|
|
833
|
+
disposeMolecule(update.token, store);
|
|
834
|
+
break;
|
|
835
|
+
case `oldValue`:
|
|
836
|
+
makeMoleculeInStore(
|
|
837
|
+
store,
|
|
838
|
+
update.context[0],
|
|
839
|
+
update.family,
|
|
840
|
+
update.token.key
|
|
841
|
+
);
|
|
842
|
+
break;
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
// internal/src/ingest-updates/ingest-selector-update.ts
|
|
847
|
+
function ingestSelectorUpdate(applying, selectorUpdate, store) {
|
|
848
|
+
const updates = applying === `newValue` ? selectorUpdate.atomUpdates : [...selectorUpdate.atomUpdates].reverse();
|
|
849
|
+
for (const atomUpdate of updates) {
|
|
850
|
+
ingestAtomUpdate(applying, atomUpdate, store);
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
// internal/src/ingest-updates/ingest-transaction-update.ts
|
|
855
|
+
function ingestTransactionUpdate(applying, transactionUpdate, store) {
|
|
856
|
+
const updates = applying === `newValue` ? transactionUpdate.updates : [...transactionUpdate.updates].reverse();
|
|
857
|
+
for (const updateFromTransaction of updates) {
|
|
858
|
+
switch (updateFromTransaction.type) {
|
|
859
|
+
case `atom_update`:
|
|
860
|
+
case `selector_update`:
|
|
861
|
+
ingestAtomUpdate(applying, updateFromTransaction, store);
|
|
862
|
+
break;
|
|
863
|
+
case `state_creation`:
|
|
864
|
+
ingestCreationEvent(updateFromTransaction, applying, store);
|
|
865
|
+
break;
|
|
866
|
+
case `state_disposal`:
|
|
867
|
+
ingestDisposalEvent(updateFromTransaction, applying, store);
|
|
868
|
+
break;
|
|
869
|
+
case `molecule_creation`:
|
|
870
|
+
ingestMoleculeCreationEvent(updateFromTransaction, applying, store);
|
|
871
|
+
break;
|
|
872
|
+
case `molecule_disposal`:
|
|
873
|
+
ingestMoleculeDisposalEvent(updateFromTransaction, applying, store);
|
|
874
|
+
break;
|
|
875
|
+
case `transaction_update`:
|
|
876
|
+
ingestTransactionUpdate(applying, updateFromTransaction, store);
|
|
877
|
+
break;
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
// internal/src/transaction/set-epoch-number.ts
|
|
883
|
+
function setEpochNumberOfContinuity(continuityKey, newEpoch, store) {
|
|
884
|
+
const isRoot = isRootStore(store);
|
|
885
|
+
if (isRoot && continuityKey) {
|
|
886
|
+
store.transactionMeta.epoch.set(continuityKey, newEpoch);
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
function setEpochNumberOfAction(transactionKey, newEpoch, store) {
|
|
890
|
+
const isRoot = isRootStore(store);
|
|
891
|
+
if (!isRoot) {
|
|
892
|
+
return;
|
|
893
|
+
}
|
|
894
|
+
const continuityKey = store.transactionMeta.actionContinuities.getRelatedKey(transactionKey);
|
|
895
|
+
if (continuityKey !== void 0) {
|
|
896
|
+
store.transactionMeta.epoch.set(continuityKey, newEpoch);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
// internal/src/transaction/apply-transaction.ts
|
|
901
|
+
var applyTransaction = (output, store) => {
|
|
902
|
+
var _a;
|
|
903
|
+
const child = newest(store);
|
|
904
|
+
const { parent } = child;
|
|
905
|
+
if (parent === null || !isChildStore(child) || ((_a = child.transactionMeta) == null ? void 0 : _a.phase) !== `building`) {
|
|
906
|
+
store.logger.warn(
|
|
907
|
+
`\u{1F41E}`,
|
|
908
|
+
`transaction`,
|
|
909
|
+
`???`,
|
|
910
|
+
`applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`
|
|
911
|
+
);
|
|
912
|
+
return;
|
|
913
|
+
}
|
|
914
|
+
child.transactionMeta.phase = `applying`;
|
|
915
|
+
child.transactionMeta.update.output = output;
|
|
916
|
+
parent.child = null;
|
|
917
|
+
parent.on.transactionApplying.next(child.transactionMeta);
|
|
918
|
+
const { updates } = child.transactionMeta.update;
|
|
919
|
+
store.logger.info(
|
|
920
|
+
`\u{1F6C4}`,
|
|
921
|
+
`transaction`,
|
|
922
|
+
child.transactionMeta.update.key,
|
|
923
|
+
`Applying transaction with ${updates.length} updates:`,
|
|
924
|
+
updates
|
|
925
|
+
);
|
|
926
|
+
for (const tracker of child.trackers.values()) {
|
|
927
|
+
const mutableKey = tracker.mutableState.key;
|
|
928
|
+
if (!parent.atoms.has(mutableKey)) {
|
|
929
|
+
const atom = child.atoms.get(mutableKey);
|
|
930
|
+
atom == null ? void 0 : atom.install(parent);
|
|
931
|
+
}
|
|
932
|
+
tracker.dispose();
|
|
933
|
+
}
|
|
934
|
+
ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
|
|
935
|
+
if (isRootStore(parent)) {
|
|
936
|
+
setEpochNumberOfAction(
|
|
937
|
+
child.transactionMeta.update.key,
|
|
938
|
+
child.transactionMeta.update.epoch,
|
|
939
|
+
parent
|
|
940
|
+
);
|
|
941
|
+
const myTransaction = withdraw(
|
|
942
|
+
{ key: child.transactionMeta.update.key, type: `transaction` },
|
|
943
|
+
store
|
|
944
|
+
);
|
|
945
|
+
myTransaction == null ? void 0 : myTransaction.subject.next(child.transactionMeta.update);
|
|
946
|
+
store.logger.info(
|
|
947
|
+
`\u{1F6EC}`,
|
|
948
|
+
`transaction`,
|
|
949
|
+
child.transactionMeta.update.key,
|
|
950
|
+
`Finished applying transaction.`
|
|
951
|
+
);
|
|
952
|
+
} else if (isChildStore(parent)) {
|
|
953
|
+
parent.transactionMeta.update.updates.push(child.transactionMeta.update);
|
|
954
|
+
}
|
|
955
|
+
parent.on.transactionApplying.next(null);
|
|
956
|
+
};
|
|
957
|
+
|
|
958
|
+
// internal/src/transaction/assign-transaction-to-continuity.ts
|
|
959
|
+
function assignTransactionToContinuity(continuityKey, transactionKey, store) {
|
|
960
|
+
const isRoot = isRootStore(store);
|
|
961
|
+
if (!isRoot) {
|
|
962
|
+
return;
|
|
963
|
+
}
|
|
964
|
+
const { epoch, actionContinuities } = store.transactionMeta;
|
|
965
|
+
actionContinuities.set(continuityKey, transactionKey);
|
|
966
|
+
if (!epoch.has(continuityKey)) {
|
|
967
|
+
epoch.set(continuityKey, -1);
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
// internal/src/get-environment-data.ts
|
|
972
|
+
function getEnvironmentData(store) {
|
|
973
|
+
return {
|
|
974
|
+
window: typeof window === `undefined` ? void 0 : window,
|
|
975
|
+
global: typeof global === `undefined` ? void 0 : global,
|
|
976
|
+
store
|
|
977
|
+
};
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
// internal/src/get-state/get-from-store.ts
|
|
981
|
+
function getFromStore(token, store) {
|
|
982
|
+
const state = withdraw(token, store);
|
|
983
|
+
return readOrComputeValue(state, store);
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
// internal/src/lazy-map.ts
|
|
987
|
+
var LazyMap = class extends Map {
|
|
988
|
+
constructor(source) {
|
|
989
|
+
super();
|
|
990
|
+
this.source = source;
|
|
991
|
+
this.deleted = /* @__PURE__ */ new Set();
|
|
992
|
+
}
|
|
993
|
+
get(key) {
|
|
994
|
+
const has = super.has(key);
|
|
995
|
+
if (has) {
|
|
996
|
+
return super.get(key);
|
|
997
|
+
}
|
|
998
|
+
if (!this.deleted.has(key) && this.source.has(key)) {
|
|
999
|
+
const value = this.source.get(key);
|
|
1000
|
+
return value;
|
|
1001
|
+
}
|
|
1002
|
+
return void 0;
|
|
1003
|
+
}
|
|
1004
|
+
set(key, value) {
|
|
1005
|
+
this.deleted.delete(key);
|
|
1006
|
+
return super.set(key, value);
|
|
1007
|
+
}
|
|
1008
|
+
hasOwn(key) {
|
|
1009
|
+
return super.has(key);
|
|
1010
|
+
}
|
|
1011
|
+
has(key) {
|
|
1012
|
+
return !this.deleted.has(key) && (super.has(key) || this.source.has(key));
|
|
1013
|
+
}
|
|
1014
|
+
delete(key) {
|
|
1015
|
+
this.deleted.add(key);
|
|
1016
|
+
return super.delete(key);
|
|
1017
|
+
}
|
|
1018
|
+
};
|
|
1019
|
+
|
|
1020
|
+
// internal/src/transaction/build-transaction.ts
|
|
1021
|
+
var buildTransaction = (key, params, store, id) => {
|
|
1022
|
+
const parent = newest(store);
|
|
1023
|
+
const childBase = {
|
|
1024
|
+
parent,
|
|
1025
|
+
child: null,
|
|
1026
|
+
on: parent.on,
|
|
1027
|
+
loggers: parent.loggers,
|
|
1028
|
+
logger: parent.logger,
|
|
1029
|
+
config: parent.config,
|
|
1030
|
+
atoms: new LazyMap(parent.atoms),
|
|
1031
|
+
atomsThatAreDefault: new Set(parent.atomsThatAreDefault),
|
|
1032
|
+
families: new LazyMap(parent.families),
|
|
1033
|
+
operation: { open: false },
|
|
1034
|
+
readonlySelectors: new LazyMap(parent.readonlySelectors),
|
|
1035
|
+
timelines: new LazyMap(parent.timelines),
|
|
1036
|
+
timelineAtoms: new Junction(parent.timelineAtoms.toJSON()),
|
|
1037
|
+
trackers: /* @__PURE__ */ new Map(),
|
|
1038
|
+
transactions: new LazyMap(parent.transactions),
|
|
1039
|
+
selectorAtoms: new Junction(parent.selectorAtoms.toJSON()),
|
|
1040
|
+
selectorGraph: new Junction(parent.selectorGraph.toJSON(), {
|
|
1041
|
+
makeContentKey: (...keys) => keys.sort().join(`:`)
|
|
1042
|
+
}),
|
|
1043
|
+
selectors: new LazyMap(parent.selectors),
|
|
1044
|
+
valueMap: new LazyMap(parent.valueMap),
|
|
1045
|
+
molecules: new LazyMap(parent.molecules),
|
|
1046
|
+
moleculeFamilies: new LazyMap(parent.moleculeFamilies),
|
|
1047
|
+
miscResources: new LazyMap(parent.miscResources)
|
|
1048
|
+
};
|
|
1049
|
+
const epoch = getEpochNumberOfAction(key, store);
|
|
1050
|
+
const transactionMeta = {
|
|
1051
|
+
phase: `building`,
|
|
1052
|
+
update: {
|
|
1053
|
+
type: `transaction_update`,
|
|
1054
|
+
key,
|
|
1055
|
+
id,
|
|
1056
|
+
epoch: epoch === void 0 ? Number.NaN : epoch + 1,
|
|
1057
|
+
updates: [],
|
|
1058
|
+
params,
|
|
1059
|
+
output: void 0
|
|
1060
|
+
},
|
|
1061
|
+
transactors: {
|
|
1062
|
+
get: (token) => getFromStore(token, child),
|
|
1063
|
+
set: (token, value) => {
|
|
1064
|
+
setIntoStore(token, value, child);
|
|
1065
|
+
},
|
|
1066
|
+
run: (token, identifier = arbitrary()) => actUponStore(token, identifier, child),
|
|
1067
|
+
find: (token, k) => findInStore(token, k, child),
|
|
1068
|
+
seek: (token, k) => seekInStore(token, k, child),
|
|
1069
|
+
json: (token) => getJsonToken(token, child),
|
|
1070
|
+
make: (context, family, k, ...args) => makeMoleculeInStore(child, context, family, k, ...args),
|
|
1071
|
+
dispose: (token) => {
|
|
1072
|
+
disposeFromStore(token, child);
|
|
1073
|
+
},
|
|
1074
|
+
env: () => getEnvironmentData(child)
|
|
1075
|
+
}
|
|
1076
|
+
};
|
|
1077
|
+
const child = Object.assign(childBase, {
|
|
1078
|
+
transactionMeta
|
|
1079
|
+
});
|
|
1080
|
+
parent.child = child;
|
|
1081
|
+
store.logger.info(
|
|
1082
|
+
`\u{1F6EB}`,
|
|
1083
|
+
`transaction`,
|
|
1084
|
+
key,
|
|
1085
|
+
`Building transaction with params:`,
|
|
1086
|
+
params
|
|
1087
|
+
);
|
|
1088
|
+
return child;
|
|
1089
|
+
};
|
|
1090
|
+
|
|
1091
|
+
// internal/src/transaction/create-transaction.ts
|
|
1092
|
+
function createTransaction(options, store) {
|
|
1093
|
+
const newTransaction = {
|
|
1094
|
+
key: options.key,
|
|
1095
|
+
type: `transaction`,
|
|
1096
|
+
run: (params, id) => {
|
|
1097
|
+
const childStore = buildTransaction(options.key, params, store, id);
|
|
1098
|
+
try {
|
|
1099
|
+
const target2 = newest(store);
|
|
1100
|
+
const { transactors } = childStore.transactionMeta;
|
|
1101
|
+
const output = options.do(transactors, ...params);
|
|
1102
|
+
applyTransaction(output, target2);
|
|
1103
|
+
return output;
|
|
1104
|
+
} catch (thrown) {
|
|
1105
|
+
abortTransaction(target);
|
|
1106
|
+
store.logger.warn(`\u{1F4A5}`, `transaction`, options.key, `caught:`, thrown);
|
|
1107
|
+
throw thrown;
|
|
1108
|
+
}
|
|
1109
|
+
},
|
|
1110
|
+
install: (s) => createTransaction(options, s),
|
|
1111
|
+
subject: new Subject()
|
|
1112
|
+
};
|
|
1113
|
+
const target = newest(store);
|
|
1114
|
+
target.transactions.set(newTransaction.key, newTransaction);
|
|
1115
|
+
const token = deposit(newTransaction);
|
|
1116
|
+
store.on.transactionCreation.next(token);
|
|
1117
|
+
return token;
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
// internal/src/transaction/get-epoch-number.ts
|
|
1121
|
+
function getContinuityKey(transactionKey, store) {
|
|
1122
|
+
const isRoot = isRootStore(store);
|
|
1123
|
+
const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
|
|
1124
|
+
return continuity;
|
|
1125
|
+
}
|
|
1126
|
+
function getEpochNumberOfContinuity(continuityKey, store) {
|
|
1127
|
+
const isRoot = isRootStore(store);
|
|
1128
|
+
const epoch = isRoot && continuityKey ? store.transactionMeta.epoch.get(continuityKey) : void 0;
|
|
1129
|
+
return epoch;
|
|
1130
|
+
}
|
|
1131
|
+
function getEpochNumberOfAction(transactionKey, store) {
|
|
1132
|
+
const isRoot = isRootStore(store);
|
|
1133
|
+
const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
|
|
1134
|
+
const epoch = isRoot && continuity !== void 0 ? store.transactionMeta.epoch.get(continuity) : void 0;
|
|
1135
|
+
return epoch;
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
// internal/src/transaction/index.ts
|
|
1139
|
+
var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
|
|
1140
|
+
|
|
1141
|
+
// internal/src/families/init-family-member.ts
|
|
1142
|
+
function initFamilyMember(token, key, store) {
|
|
1143
|
+
const familyKey = token.key;
|
|
1144
|
+
const family = store.families.get(familyKey);
|
|
1145
|
+
if (family === void 0) {
|
|
1146
|
+
throw new NotFoundError(token, store);
|
|
1147
|
+
}
|
|
1148
|
+
const state = family(key);
|
|
1149
|
+
const target = newest(store);
|
|
1150
|
+
if (state.family) {
|
|
1151
|
+
if (isChildStore(target) && target.transactionMeta.phase === `building`) {
|
|
1152
|
+
target.transactionMeta.update.updates.push({
|
|
1153
|
+
type: `state_creation`,
|
|
1154
|
+
token: state
|
|
1155
|
+
});
|
|
1156
|
+
} else {
|
|
1157
|
+
switch (state.type) {
|
|
1158
|
+
case `atom`:
|
|
1159
|
+
case `mutable_atom`:
|
|
1160
|
+
store.on.atomCreation.next(state);
|
|
1161
|
+
break;
|
|
1162
|
+
case `selector`:
|
|
1163
|
+
case `readonly_selector`:
|
|
1164
|
+
store.on.selectorCreation.next(state);
|
|
1165
|
+
break;
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
return state;
|
|
1170
|
+
}
|
|
1171
|
+
function seekInStore(token, key, store) {
|
|
1172
|
+
const subKey = stringifyJson(key);
|
|
1173
|
+
const fullKey = `${token.key}(${subKey})`;
|
|
1174
|
+
const target = newest(store);
|
|
1175
|
+
let state;
|
|
1176
|
+
switch (token.type) {
|
|
1177
|
+
case `atom_family`:
|
|
1178
|
+
case `mutable_atom_family`:
|
|
1179
|
+
state = target.atoms.get(fullKey);
|
|
1180
|
+
break;
|
|
1181
|
+
case `selector_family`:
|
|
1182
|
+
state = target.selectors.get(fullKey);
|
|
1183
|
+
break;
|
|
1184
|
+
case `readonly_selector_family`:
|
|
1185
|
+
state = target.readonlySelectors.get(fullKey);
|
|
1186
|
+
break;
|
|
1187
|
+
case `molecule_family`:
|
|
1188
|
+
state = target.molecules.get(stringifyJson(key));
|
|
1189
|
+
if (state) {
|
|
1190
|
+
return deposit(state);
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
if (state) {
|
|
1194
|
+
return deposit(state);
|
|
1195
|
+
}
|
|
1196
|
+
return state;
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
// internal/src/families/find-in-store.ts
|
|
1200
|
+
function findInStore(token, key, store) {
|
|
1201
|
+
if (store.config.lifespan === `immortal`) {
|
|
1202
|
+
throw new Error(
|
|
1203
|
+
`Do not use \`find\` or \`findState\` in an immortal store. Prefer \`seek\` or \`seekState\`.`
|
|
1204
|
+
);
|
|
1205
|
+
}
|
|
1206
|
+
let state = seekInStore(token, key, store);
|
|
1207
|
+
if (state) {
|
|
1208
|
+
return state;
|
|
1209
|
+
}
|
|
1210
|
+
state = initFamilyMember(token, key, store);
|
|
1211
|
+
return state;
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
// internal/src/keys.ts
|
|
1215
|
+
var isAtomKey = (key, store) => newest(store).atoms.has(key);
|
|
1216
|
+
var isSelectorKey = (key, store) => newest(store).selectors.has(key);
|
|
1217
|
+
var isReadonlySelectorKey = (key, store) => newest(store).readonlySelectors.has(key);
|
|
1218
|
+
var isStateKey = (key, store) => isAtomKey(key, store) || isSelectorKey(key, store) || isReadonlySelectorKey(key, store);
|
|
1219
|
+
|
|
1220
|
+
// internal/src/selector/get-selector-dependency-keys.ts
|
|
1221
|
+
var getSelectorDependencyKeys = (key, store) => {
|
|
1222
|
+
const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(source, store));
|
|
1223
|
+
return sources;
|
|
1224
|
+
};
|
|
1225
|
+
|
|
1226
|
+
// internal/src/selector/trace-selector-atoms.ts
|
|
1227
|
+
var traceSelectorAtoms = (selectorKey, directDependencyKey, store) => {
|
|
1228
|
+
const rootKeys = [];
|
|
1229
|
+
const indirectDependencyKeys = getSelectorDependencyKeys(
|
|
1230
|
+
directDependencyKey,
|
|
1231
|
+
store
|
|
1232
|
+
);
|
|
1233
|
+
let depth = 0;
|
|
1234
|
+
while (indirectDependencyKeys.length > 0) {
|
|
1235
|
+
const indirectDependencyKey = indirectDependencyKeys.shift();
|
|
1236
|
+
++depth;
|
|
1237
|
+
if (depth > 99999) {
|
|
1238
|
+
throw new Error(
|
|
1239
|
+
`Maximum selector dependency depth exceeded (> 99999) in selector "${selectorKey}". This is likely due to a circular dependency.`
|
|
1240
|
+
);
|
|
1241
|
+
}
|
|
1242
|
+
if (!isAtomKey(indirectDependencyKey, store)) {
|
|
1243
|
+
indirectDependencyKeys.push(
|
|
1244
|
+
...getSelectorDependencyKeys(indirectDependencyKey, store)
|
|
1245
|
+
);
|
|
1246
|
+
} else if (!rootKeys.includes(indirectDependencyKey)) {
|
|
1247
|
+
rootKeys.push(indirectDependencyKey);
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
return rootKeys;
|
|
1251
|
+
};
|
|
1252
|
+
var traceAllSelectorAtoms = (selector, store) => {
|
|
1253
|
+
const selectorKey = selector.key;
|
|
1254
|
+
const directDependencyKeys = getSelectorDependencyKeys(selectorKey, store);
|
|
1255
|
+
return directDependencyKeys.flatMap(
|
|
1256
|
+
(depKey) => isAtomKey(depKey, store) ? depKey : traceSelectorAtoms(selectorKey, depKey, store)
|
|
1257
|
+
);
|
|
1258
|
+
};
|
|
1259
|
+
|
|
1260
|
+
// internal/src/selector/update-selector-atoms.ts
|
|
1261
|
+
var updateSelectorAtoms = (selectorKey, dependency, store) => {
|
|
1262
|
+
const target = newest(store);
|
|
1263
|
+
if (dependency.type === `atom` || dependency.type === `mutable_atom`) {
|
|
1264
|
+
target.selectorAtoms.set({
|
|
1265
|
+
selectorKey,
|
|
1266
|
+
atomKey: dependency.key
|
|
1267
|
+
});
|
|
1268
|
+
store.logger.info(
|
|
1269
|
+
`\u{1F50D}`,
|
|
1270
|
+
`selector`,
|
|
1271
|
+
selectorKey,
|
|
1272
|
+
`discovers root atom "${dependency.key}"`
|
|
1273
|
+
);
|
|
1274
|
+
} else {
|
|
1275
|
+
const rootKeys = traceSelectorAtoms(selectorKey, dependency.key, store);
|
|
1276
|
+
store.logger.info(
|
|
1277
|
+
`\u{1F50D}`,
|
|
1278
|
+
`selector`,
|
|
1279
|
+
selectorKey,
|
|
1280
|
+
`discovers root atoms: [ ${rootKeys.map((key) => `"${key}"`).join(`, `)} ]`
|
|
1281
|
+
);
|
|
1282
|
+
for (const atomKey of rootKeys) {
|
|
1283
|
+
target.selectorAtoms = target.selectorAtoms.set({
|
|
1284
|
+
selectorKey,
|
|
1285
|
+
atomKey
|
|
1286
|
+
});
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
};
|
|
1290
|
+
|
|
1291
|
+
// internal/src/selector/register-selector.ts
|
|
1292
|
+
var registerSelector = (selectorKey, store) => ({
|
|
1293
|
+
get: (dependency) => {
|
|
1294
|
+
const target = newest(store);
|
|
1295
|
+
const dependencyState = withdraw(dependency, store);
|
|
1296
|
+
const dependencyValue = readOrComputeValue(dependencyState, store);
|
|
1297
|
+
store.logger.info(
|
|
1298
|
+
`\u{1F50C}`,
|
|
1299
|
+
`selector`,
|
|
1300
|
+
selectorKey,
|
|
1301
|
+
`registers dependency ( "${dependency.key}" =`,
|
|
1302
|
+
dependencyValue,
|
|
1303
|
+
`)`
|
|
1304
|
+
);
|
|
1305
|
+
target.selectorGraph.set(
|
|
1306
|
+
{
|
|
1307
|
+
upstreamSelectorKey: dependency.key,
|
|
1308
|
+
downstreamSelectorKey: selectorKey
|
|
1309
|
+
},
|
|
1310
|
+
{
|
|
1311
|
+
source: dependency.key
|
|
1312
|
+
}
|
|
1313
|
+
);
|
|
1314
|
+
updateSelectorAtoms(selectorKey, dependency, store);
|
|
1315
|
+
return dependencyValue;
|
|
1316
|
+
},
|
|
1317
|
+
set: (WritableToken, newValue) => {
|
|
1318
|
+
const state = withdraw(WritableToken, store);
|
|
1319
|
+
setAtomOrSelector(state, newValue, store);
|
|
1320
|
+
},
|
|
1321
|
+
find: (token, key) => findInStore(token, key, store),
|
|
1322
|
+
seek: (token, key) => seekInStore(token, key, store),
|
|
1323
|
+
json: (token) => getJsonToken(token, store)
|
|
1324
|
+
});
|
|
1325
|
+
|
|
1326
|
+
// internal/src/selector/create-readonly-selector.ts
|
|
1327
|
+
var createReadonlySelector = (options, family, store) => {
|
|
1328
|
+
const target = newest(store);
|
|
1329
|
+
const subject = new Subject();
|
|
1330
|
+
const { get, find, seek, json } = registerSelector(options.key, target);
|
|
1331
|
+
const getSelf = () => {
|
|
1332
|
+
const value = options.get({ get, find, seek, json });
|
|
1333
|
+
cacheValue(options.key, value, subject, newest(store));
|
|
1334
|
+
return value;
|
|
1335
|
+
};
|
|
1336
|
+
const readonlySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
|
|
1337
|
+
subject,
|
|
1338
|
+
install: (s) => createReadonlySelector(options, family, s),
|
|
1339
|
+
get: getSelf,
|
|
1340
|
+
type: `readonly_selector`
|
|
1341
|
+
}), family && { family });
|
|
1342
|
+
target.readonlySelectors.set(options.key, readonlySelector);
|
|
1343
|
+
const initialValue = getSelf();
|
|
1344
|
+
store.logger.info(
|
|
1345
|
+
`\u2728`,
|
|
1346
|
+
readonlySelector.type,
|
|
1347
|
+
readonlySelector.key,
|
|
1348
|
+
`=`,
|
|
1349
|
+
initialValue
|
|
1350
|
+
);
|
|
1351
|
+
const token = {
|
|
1352
|
+
key: options.key,
|
|
1353
|
+
type: `readonly_selector`
|
|
1354
|
+
};
|
|
1355
|
+
if (family) {
|
|
1356
|
+
token.family = family;
|
|
1357
|
+
}
|
|
1358
|
+
return token;
|
|
1359
|
+
};
|
|
1360
|
+
|
|
1361
|
+
// internal/src/selector/create-writable-selector.ts
|
|
1362
|
+
var createWritableSelector = (options, family, store) => {
|
|
1363
|
+
const target = newest(store);
|
|
1364
|
+
const subject = new Subject();
|
|
1365
|
+
const transactors = registerSelector(options.key, target);
|
|
1366
|
+
const { find, get, seek, json } = transactors;
|
|
1367
|
+
const readonlyTransactors = { find, get, seek, json };
|
|
1368
|
+
const getSelf = () => {
|
|
1369
|
+
const value = options.get(readonlyTransactors);
|
|
893
1370
|
cacheValue(options.key, value, subject, newest(store));
|
|
894
1371
|
return value;
|
|
895
1372
|
};
|
|
@@ -930,7 +1407,6 @@ var createWritableSelector = (options, family, store) => {
|
|
|
930
1407
|
if (family) {
|
|
931
1408
|
token.family = family;
|
|
932
1409
|
}
|
|
933
|
-
store.on.selectorCreation.next(token);
|
|
934
1410
|
return token;
|
|
935
1411
|
};
|
|
936
1412
|
|
|
@@ -938,19 +1414,23 @@ var createWritableSelector = (options, family, store) => {
|
|
|
938
1414
|
function createStandaloneSelector(options, store) {
|
|
939
1415
|
const isWritable = `set` in options;
|
|
940
1416
|
if (isWritable) {
|
|
941
|
-
|
|
1417
|
+
const state2 = createWritableSelector(options, void 0, store);
|
|
1418
|
+
store.on.selectorCreation.next(state2);
|
|
1419
|
+
return state2;
|
|
942
1420
|
}
|
|
943
|
-
|
|
1421
|
+
const state = createReadonlySelector(options, void 0, store);
|
|
1422
|
+
store.on.selectorCreation.next(state);
|
|
1423
|
+
return state;
|
|
944
1424
|
}
|
|
945
1425
|
|
|
946
1426
|
// internal/src/selector/dispose-selector.ts
|
|
947
|
-
function
|
|
1427
|
+
function disposeSelector2(selectorToken, store) {
|
|
948
1428
|
var _a;
|
|
949
1429
|
const target = newest(store);
|
|
950
1430
|
const { key } = selectorToken;
|
|
951
1431
|
const selector = (_a = target.selectors.get(key)) != null ? _a : target.readonlySelectors.get(key);
|
|
952
1432
|
if (!selector) {
|
|
953
|
-
store.logger.
|
|
1433
|
+
store.logger.info(
|
|
954
1434
|
`\u274C`,
|
|
955
1435
|
`selector`,
|
|
956
1436
|
key,
|
|
@@ -966,10 +1446,30 @@ function disposeSelector(selectorToken, store) {
|
|
|
966
1446
|
} else {
|
|
967
1447
|
switch (selectorToken.type) {
|
|
968
1448
|
case `selector`:
|
|
969
|
-
|
|
1449
|
+
{
|
|
1450
|
+
target.selectors.delete(key);
|
|
1451
|
+
const family = withdraw(
|
|
1452
|
+
{ key: selector.family.key, type: `selector_family` },
|
|
1453
|
+
store
|
|
1454
|
+
);
|
|
1455
|
+
family.subject.next({
|
|
1456
|
+
type: `state_disposal`,
|
|
1457
|
+
token: selectorToken
|
|
1458
|
+
});
|
|
1459
|
+
}
|
|
970
1460
|
break;
|
|
971
1461
|
case `readonly_selector`:
|
|
972
|
-
|
|
1462
|
+
{
|
|
1463
|
+
target.readonlySelectors.delete(key);
|
|
1464
|
+
const family = withdraw(
|
|
1465
|
+
{ key: selector.family.key, type: `readonly_selector_family` },
|
|
1466
|
+
store
|
|
1467
|
+
);
|
|
1468
|
+
family.subject.next({
|
|
1469
|
+
type: `state_disposal`,
|
|
1470
|
+
token: selectorToken
|
|
1471
|
+
});
|
|
1472
|
+
}
|
|
973
1473
|
break;
|
|
974
1474
|
}
|
|
975
1475
|
target.valueMap.delete(key);
|
|
@@ -982,12 +1482,19 @@ function disposeSelector(selectorToken, store) {
|
|
|
982
1482
|
);
|
|
983
1483
|
for (const downstreamToken of downstreamTokens) {
|
|
984
1484
|
if (downstreamToken) {
|
|
985
|
-
|
|
1485
|
+
disposeSelector2(downstreamToken, store);
|
|
986
1486
|
}
|
|
987
1487
|
}
|
|
988
1488
|
target.selectorGraph.delete(key);
|
|
989
1489
|
store.logger.info(`\u{1F525}`, selectorToken.type, key, `deleted`);
|
|
990
|
-
|
|
1490
|
+
if (isChildStore(target) && target.transactionMeta.phase === `building`) {
|
|
1491
|
+
target.transactionMeta.update.updates.push({
|
|
1492
|
+
type: `state_disposal`,
|
|
1493
|
+
token: selectorToken
|
|
1494
|
+
});
|
|
1495
|
+
} else {
|
|
1496
|
+
store.on.selectorDisposal.next(selectorToken);
|
|
1497
|
+
}
|
|
991
1498
|
}
|
|
992
1499
|
}
|
|
993
1500
|
|
|
@@ -1323,7 +1830,6 @@ function createMutableAtom(options, family, store) {
|
|
|
1323
1830
|
if (!family) {
|
|
1324
1831
|
selectJson(token, options, store);
|
|
1325
1832
|
}
|
|
1326
|
-
store.on.atomCreation.next(token);
|
|
1327
1833
|
return token;
|
|
1328
1834
|
}
|
|
1329
1835
|
var FamilyTracker = class {
|
|
@@ -1338,19 +1844,19 @@ var FamilyTracker = class {
|
|
|
1338
1844
|
this.mutableAtoms = mutableAtoms;
|
|
1339
1845
|
this.mutableAtoms.subject.subscribe(
|
|
1340
1846
|
`store=${store.config.name}::tracker-atom-family`,
|
|
1341
|
-
(
|
|
1342
|
-
if (
|
|
1343
|
-
const key = parseJson(
|
|
1847
|
+
(event) => {
|
|
1848
|
+
if (event.token.family) {
|
|
1849
|
+
const key = parseJson$1(event.token.family.subKey);
|
|
1344
1850
|
seekInStore(this.latestUpdateAtoms, key, store);
|
|
1345
|
-
new Tracker(
|
|
1851
|
+
new Tracker(event.token, store);
|
|
1346
1852
|
}
|
|
1347
1853
|
}
|
|
1348
1854
|
);
|
|
1349
1855
|
this.latestUpdateAtoms.subject.subscribe(
|
|
1350
1856
|
`store=${store.config.name}::tracker-atom-family`,
|
|
1351
|
-
(
|
|
1352
|
-
if (
|
|
1353
|
-
const key = parseJson(
|
|
1857
|
+
(event) => {
|
|
1858
|
+
if (event.token.family) {
|
|
1859
|
+
const key = parseJson$1(event.token.family.subKey);
|
|
1354
1860
|
const mutableAtomToken = seekInStore(this.mutableAtoms, key, store);
|
|
1355
1861
|
if (mutableAtomToken) {
|
|
1356
1862
|
new Tracker(mutableAtomToken, store);
|
|
@@ -1381,7 +1887,7 @@ function createMutableAtomFamily(options, store) {
|
|
|
1381
1887
|
individualOptions.effects = options.effects(key);
|
|
1382
1888
|
}
|
|
1383
1889
|
const token = createMutableAtom(individualOptions, family, target);
|
|
1384
|
-
subject.next(token);
|
|
1890
|
+
subject.next({ type: `state_creation`, token });
|
|
1385
1891
|
return token;
|
|
1386
1892
|
},
|
|
1387
1893
|
{
|
|
@@ -1597,7 +2103,6 @@ function createRegularAtom(options, family, store) {
|
|
|
1597
2103
|
}
|
|
1598
2104
|
};
|
|
1599
2105
|
}
|
|
1600
|
-
store.on.atomCreation.next(token);
|
|
1601
2106
|
return token;
|
|
1602
2107
|
}
|
|
1603
2108
|
|
|
@@ -1605,13 +2110,17 @@ function createRegularAtom(options, family, store) {
|
|
|
1605
2110
|
function createStandaloneAtom(options, store) {
|
|
1606
2111
|
const isMutable2 = `mutable` in options;
|
|
1607
2112
|
if (isMutable2) {
|
|
1608
|
-
|
|
2113
|
+
const state2 = createMutableAtom(options, void 0, store);
|
|
2114
|
+
store.on.atomCreation.next(state2);
|
|
2115
|
+
return state2;
|
|
1609
2116
|
}
|
|
1610
|
-
|
|
2117
|
+
const state = createRegularAtom(options, void 0, store);
|
|
2118
|
+
store.on.atomCreation.next(state);
|
|
2119
|
+
return state;
|
|
1611
2120
|
}
|
|
1612
2121
|
|
|
1613
2122
|
// internal/src/atom/dispose-atom.ts
|
|
1614
|
-
function
|
|
2123
|
+
function disposeAtom2(atomToken, store) {
|
|
1615
2124
|
var _a, _b;
|
|
1616
2125
|
const target = newest(store);
|
|
1617
2126
|
const { key } = atomToken;
|
|
@@ -1627,6 +2136,13 @@ function disposeAtom(atomToken, store) {
|
|
|
1627
2136
|
store.logger.error(`\u274C`, `atom`, key, `Standalone atoms cannot be disposed.`);
|
|
1628
2137
|
} else {
|
|
1629
2138
|
(_a = atom.cleanup) == null ? void 0 : _a.call(atom);
|
|
2139
|
+
const lastValue = store.valueMap.get(atom.key);
|
|
2140
|
+
const family = withdraw({ key: atom.family.key, type: `atom_family` }, store);
|
|
2141
|
+
family.subject.next({
|
|
2142
|
+
type: `state_disposal`,
|
|
2143
|
+
token: atomToken,
|
|
2144
|
+
value: lastValue
|
|
2145
|
+
});
|
|
1630
2146
|
target.atoms.delete(key);
|
|
1631
2147
|
target.valueMap.delete(key);
|
|
1632
2148
|
const selectorKeys = target.selectorAtoms.getRelatedKeys(key);
|
|
@@ -1634,7 +2150,7 @@ function disposeAtom(atomToken, store) {
|
|
|
1634
2150
|
for (const selectorKey of selectorKeys) {
|
|
1635
2151
|
const token = (_b = target.selectors.get(selectorKey)) != null ? _b : target.readonlySelectors.get(selectorKey);
|
|
1636
2152
|
if (token) {
|
|
1637
|
-
|
|
2153
|
+
disposeSelector2(token, store);
|
|
1638
2154
|
}
|
|
1639
2155
|
}
|
|
1640
2156
|
}
|
|
@@ -1643,94 +2159,21 @@ function disposeAtom(atomToken, store) {
|
|
|
1643
2159
|
target.timelineAtoms.delete(key);
|
|
1644
2160
|
if (atomToken.type === `mutable_atom`) {
|
|
1645
2161
|
const updateToken = getUpdateToken(atomToken);
|
|
1646
|
-
|
|
2162
|
+
disposeAtom2(updateToken, store);
|
|
1647
2163
|
store.trackers.delete(key);
|
|
1648
2164
|
}
|
|
1649
2165
|
store.logger.info(`\u{1F525}`, `atom`, key, `deleted`);
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
function getEnvironmentData(store) {
|
|
1656
|
-
return {
|
|
1657
|
-
window: typeof window === `undefined` ? void 0 : window,
|
|
1658
|
-
global: typeof global === `undefined` ? void 0 : global,
|
|
1659
|
-
store
|
|
1660
|
-
};
|
|
1661
|
-
}
|
|
1662
|
-
|
|
1663
|
-
// internal/src/get-state/get-from-store.ts
|
|
1664
|
-
function getFromStore(token, store) {
|
|
1665
|
-
const state = withdraw(token, store);
|
|
1666
|
-
return readOrComputeValue(state, store);
|
|
1667
|
-
}
|
|
1668
|
-
|
|
1669
|
-
// internal/src/ingest-updates/ingest-atom-update.ts
|
|
1670
|
-
function ingestAtomUpdate(applying, atomUpdate, store) {
|
|
1671
|
-
const { key, newValue, oldValue } = atomUpdate;
|
|
1672
|
-
const value = applying === `newValue` ? newValue : oldValue;
|
|
1673
|
-
const token = { key, type: `atom` };
|
|
1674
|
-
if (atomUpdate.family) {
|
|
1675
|
-
Object.assign(token, { family: atomUpdate.family });
|
|
1676
|
-
}
|
|
1677
|
-
setIntoStore(token, value, store);
|
|
1678
|
-
}
|
|
1679
|
-
|
|
1680
|
-
// internal/src/ingest-updates/ingest-selector-update.ts
|
|
1681
|
-
function ingestSelectorUpdate(applying, selectorUpdate, store) {
|
|
1682
|
-
const updates = applying === `newValue` ? selectorUpdate.atomUpdates : [...selectorUpdate.atomUpdates].reverse();
|
|
1683
|
-
for (const atomUpdate of updates) {
|
|
1684
|
-
ingestAtomUpdate(applying, atomUpdate, store);
|
|
1685
|
-
}
|
|
1686
|
-
}
|
|
1687
|
-
|
|
1688
|
-
// internal/src/ingest-updates/ingest-transaction-update.ts
|
|
1689
|
-
function ingestTransactionUpdate(applying, transactionUpdate, store) {
|
|
1690
|
-
const updates = applying === `newValue` ? transactionUpdate.updates : [...transactionUpdate.updates].reverse();
|
|
1691
|
-
for (const updateFromTransaction of updates) {
|
|
1692
|
-
if (`newValue` in updateFromTransaction) {
|
|
1693
|
-
ingestAtomUpdate(applying, updateFromTransaction, store);
|
|
2166
|
+
if (isChildStore(target) && target.transactionMeta.phase === `building`) {
|
|
2167
|
+
target.transactionMeta.update.updates.push({
|
|
2168
|
+
type: `state_disposal`,
|
|
2169
|
+
token: atomToken
|
|
2170
|
+
});
|
|
1694
2171
|
} else {
|
|
1695
|
-
|
|
2172
|
+
store.on.atomDisposal.next(atomToken);
|
|
1696
2173
|
}
|
|
1697
2174
|
}
|
|
1698
2175
|
}
|
|
1699
2176
|
|
|
1700
|
-
// internal/src/lazy-map.ts
|
|
1701
|
-
var LazyMap = class extends Map {
|
|
1702
|
-
constructor(source) {
|
|
1703
|
-
super();
|
|
1704
|
-
this.source = source;
|
|
1705
|
-
this.deleted = /* @__PURE__ */ new Set();
|
|
1706
|
-
}
|
|
1707
|
-
get(key) {
|
|
1708
|
-
const has = super.has(key);
|
|
1709
|
-
if (has) {
|
|
1710
|
-
return super.get(key);
|
|
1711
|
-
}
|
|
1712
|
-
if (!this.deleted.has(key) && this.source.has(key)) {
|
|
1713
|
-
const value = this.source.get(key);
|
|
1714
|
-
return value;
|
|
1715
|
-
}
|
|
1716
|
-
return void 0;
|
|
1717
|
-
}
|
|
1718
|
-
set(key, value) {
|
|
1719
|
-
this.deleted.delete(key);
|
|
1720
|
-
return super.set(key, value);
|
|
1721
|
-
}
|
|
1722
|
-
hasOwn(key) {
|
|
1723
|
-
return super.has(key);
|
|
1724
|
-
}
|
|
1725
|
-
has(key) {
|
|
1726
|
-
return !this.deleted.has(key) && (super.has(key) || this.source.has(key));
|
|
1727
|
-
}
|
|
1728
|
-
delete(key) {
|
|
1729
|
-
this.deleted.add(key);
|
|
1730
|
-
return super.delete(key);
|
|
1731
|
-
}
|
|
1732
|
-
};
|
|
1733
|
-
|
|
1734
2177
|
// internal/src/timeline/add-atom-to-timeline.ts
|
|
1735
2178
|
var addAtomToTimeline = (atomToken, tl, store) => {
|
|
1736
2179
|
let maybeAtom = withdraw(atomToken, store);
|
|
@@ -1740,188 +2183,212 @@ var addAtomToTimeline = (atomToken, tl, store) => {
|
|
|
1740
2183
|
}
|
|
1741
2184
|
const atom = maybeAtom;
|
|
1742
2185
|
store.timelineAtoms.set({ atomKey: atom.key, timelineKey: tl.key });
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
if (
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
}
|
|
1772
|
-
if (currentTransactionKey) {
|
|
1773
|
-
const txToken = {
|
|
1774
|
-
key: currentTransactionKey,
|
|
1775
|
-
type: `transaction`
|
|
1776
|
-
};
|
|
1777
|
-
const currentTransaction = withdraw(txToken, store);
|
|
1778
|
-
if (tl.transactionKey !== currentTransactionKey) {
|
|
1779
|
-
if (tl.transactionKey) {
|
|
1780
|
-
store.logger.error(
|
|
1781
|
-
`\u{1F41E}`,
|
|
1782
|
-
`timeline`,
|
|
1783
|
-
tl.key,
|
|
1784
|
-
`unable to resolve transaction "${tl.transactionKey}. This is probably a bug in AtomIO.`
|
|
2186
|
+
tl.subscriptions.set(
|
|
2187
|
+
atom.key,
|
|
2188
|
+
atom.subject.subscribe(`timeline`, (update) => {
|
|
2189
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2190
|
+
const target = newest(store);
|
|
2191
|
+
const currentSelectorKey = store.operation.open && store.operation.token.type === `selector` ? store.operation.token.key : null;
|
|
2192
|
+
const currentSelectorTime = store.operation.open && store.operation.token.type === `selector` ? store.operation.time : null;
|
|
2193
|
+
const { transactionApplying } = target.on;
|
|
2194
|
+
const currentTransactionKey = (_a = transactionApplying.state) == null ? void 0 : _a.update.key;
|
|
2195
|
+
const currentTransactionInstanceId = (_b = transactionApplying.state) == null ? void 0 : _b.update.id;
|
|
2196
|
+
store.logger.info(
|
|
2197
|
+
`\u23F3`,
|
|
2198
|
+
`timeline`,
|
|
2199
|
+
tl.key,
|
|
2200
|
+
`atom`,
|
|
2201
|
+
atomToken.key,
|
|
2202
|
+
`went`,
|
|
2203
|
+
update.oldValue,
|
|
2204
|
+
`->`,
|
|
2205
|
+
update.newValue,
|
|
2206
|
+
currentTransactionKey ? `in transaction "${currentTransactionKey}"` : currentSelectorKey ? `in selector "${currentSelectorKey}"` : ``
|
|
2207
|
+
);
|
|
2208
|
+
if (tl.timeTraveling === null) {
|
|
2209
|
+
if (tl.selectorTime && tl.selectorTime !== currentSelectorTime) {
|
|
2210
|
+
const mostRecentUpdate = tl.history.at(-1);
|
|
2211
|
+
if (mostRecentUpdate === void 0) {
|
|
2212
|
+
throw new Error(
|
|
2213
|
+
`Timeline "${tl.key}" has a selectorTime, but no history. This is most likely a bug in AtomIO.`
|
|
1785
2214
|
);
|
|
1786
2215
|
}
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
2216
|
+
}
|
|
2217
|
+
if (currentTransactionKey) {
|
|
2218
|
+
const txToken = {
|
|
2219
|
+
key: currentTransactionKey,
|
|
2220
|
+
type: `transaction`
|
|
2221
|
+
};
|
|
2222
|
+
const currentTransaction = withdraw(txToken, store);
|
|
2223
|
+
if (tl.transactionKey !== currentTransactionKey) {
|
|
2224
|
+
if (tl.transactionKey) {
|
|
2225
|
+
store.logger.error(
|
|
2226
|
+
`\u{1F41E}`,
|
|
2227
|
+
`timeline`,
|
|
2228
|
+
tl.key,
|
|
2229
|
+
`unable to resolve transaction "${tl.transactionKey}. This is probably a bug in AtomIO.`
|
|
2230
|
+
);
|
|
2231
|
+
}
|
|
2232
|
+
tl.transactionKey = currentTransactionKey;
|
|
2233
|
+
const unsubscribe = currentTransaction.subject.subscribe(
|
|
2234
|
+
`timeline:${tl.key}`,
|
|
2235
|
+
(transactionUpdate) => {
|
|
2236
|
+
var _a2, _b2;
|
|
2237
|
+
unsubscribe();
|
|
2238
|
+
if (tl.timeTraveling === null && currentTransactionInstanceId) {
|
|
2239
|
+
if (tl.at !== tl.history.length) {
|
|
2240
|
+
tl.history.splice(tl.at);
|
|
1801
2241
|
}
|
|
1802
|
-
const
|
|
1803
|
-
|
|
1804
|
-
(
|
|
1805
|
-
|
|
1806
|
-
return
|
|
2242
|
+
const filterUpdates = (updates2) => updates2.filter((updateFromTx) => {
|
|
2243
|
+
var _a3, _b3;
|
|
2244
|
+
const newestStore = newest(store);
|
|
2245
|
+
if (`updates` in updateFromTx) {
|
|
2246
|
+
return true;
|
|
2247
|
+
}
|
|
2248
|
+
const atomOrFamilyKeys = newestStore.timelineAtoms.getRelatedKeys(tl.key);
|
|
2249
|
+
if (!atomOrFamilyKeys) {
|
|
2250
|
+
return false;
|
|
1807
2251
|
}
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
2252
|
+
let key;
|
|
2253
|
+
let familyKey;
|
|
2254
|
+
switch (updateFromTx.type) {
|
|
2255
|
+
case `state_creation`:
|
|
2256
|
+
case `state_disposal`:
|
|
2257
|
+
key = updateFromTx.token.key;
|
|
2258
|
+
familyKey = (_a3 = updateFromTx.token.family) == null ? void 0 : _a3.key;
|
|
2259
|
+
break;
|
|
2260
|
+
case `molecule_creation`:
|
|
2261
|
+
case `molecule_disposal`:
|
|
2262
|
+
break;
|
|
2263
|
+
default:
|
|
2264
|
+
key = updateFromTx.key;
|
|
2265
|
+
familyKey = (_b3 = updateFromTx.family) == null ? void 0 : _b3.key;
|
|
2266
|
+
break;
|
|
2267
|
+
}
|
|
2268
|
+
if (key === void 0) {
|
|
2269
|
+
return false;
|
|
2270
|
+
}
|
|
2271
|
+
if (atomOrFamilyKeys.has(key)) {
|
|
2272
|
+
return true;
|
|
2273
|
+
}
|
|
2274
|
+
if (familyKey !== void 0) {
|
|
2275
|
+
return atomOrFamilyKeys.has(familyKey);
|
|
2276
|
+
}
|
|
2277
|
+
return false;
|
|
2278
|
+
}).map((updateFromTx) => {
|
|
2279
|
+
if (`updates` in updateFromTx) {
|
|
2280
|
+
return __spreadProps(__spreadValues({}, updateFromTx), {
|
|
2281
|
+
updates: filterUpdates(updateFromTx.updates)
|
|
2282
|
+
});
|
|
2283
|
+
}
|
|
2284
|
+
return updateFromTx;
|
|
2285
|
+
});
|
|
2286
|
+
const updates = filterUpdates(transactionUpdate.updates);
|
|
2287
|
+
const timelineTransactionUpdate = __spreadProps(__spreadValues({
|
|
2288
|
+
timestamp: Date.now()
|
|
2289
|
+
}, transactionUpdate), {
|
|
2290
|
+
updates
|
|
2291
|
+
});
|
|
2292
|
+
const willCapture = (_b2 = (_a2 = tl.shouldCapture) == null ? void 0 : _a2.call(tl, timelineTransactionUpdate, tl)) != null ? _b2 : true;
|
|
2293
|
+
if (willCapture) {
|
|
2294
|
+
tl.history.push(timelineTransactionUpdate);
|
|
2295
|
+
tl.at = tl.history.length;
|
|
2296
|
+
tl.subject.next(timelineTransactionUpdate);
|
|
1814
2297
|
}
|
|
1815
|
-
return updateFromTx;
|
|
1816
|
-
});
|
|
1817
|
-
const updates = filterUpdates(transactionUpdate.updates);
|
|
1818
|
-
const timelineTransactionUpdate = __spreadProps(__spreadValues({
|
|
1819
|
-
type: `transaction_update`,
|
|
1820
|
-
timestamp: Date.now()
|
|
1821
|
-
}, transactionUpdate), {
|
|
1822
|
-
updates
|
|
1823
|
-
});
|
|
1824
|
-
const willCapture = (_b2 = (_a2 = tl.shouldCapture) == null ? void 0 : _a2.call(tl, timelineTransactionUpdate, tl)) != null ? _b2 : true;
|
|
1825
|
-
if (willCapture) {
|
|
1826
|
-
tl.history.push(timelineTransactionUpdate);
|
|
1827
|
-
tl.at = tl.history.length;
|
|
1828
|
-
tl.subject.next(timelineTransactionUpdate);
|
|
1829
2298
|
}
|
|
2299
|
+
tl.transactionKey = null;
|
|
2300
|
+
store.logger.info(
|
|
2301
|
+
`\u231B`,
|
|
2302
|
+
`timeline`,
|
|
2303
|
+
tl.key,
|
|
2304
|
+
`got a transaction_update "${transactionUpdate.key}"`
|
|
2305
|
+
);
|
|
1830
2306
|
}
|
|
1831
|
-
|
|
2307
|
+
);
|
|
2308
|
+
}
|
|
2309
|
+
} else if (currentSelectorKey && currentSelectorTime) {
|
|
2310
|
+
let latestUpdate = tl.history.at(-1);
|
|
2311
|
+
if (currentSelectorTime !== tl.selectorTime) {
|
|
2312
|
+
latestUpdate = {
|
|
2313
|
+
type: `selector_update`,
|
|
2314
|
+
timestamp: currentSelectorTime,
|
|
2315
|
+
key: currentSelectorKey,
|
|
2316
|
+
atomUpdates: []
|
|
2317
|
+
};
|
|
2318
|
+
latestUpdate.atomUpdates.push(__spreadValues({
|
|
2319
|
+
key: atom.key,
|
|
2320
|
+
type: `atom_update`
|
|
2321
|
+
}, update));
|
|
2322
|
+
if (tl.at !== tl.history.length) {
|
|
2323
|
+
tl.history.splice(tl.at);
|
|
2324
|
+
}
|
|
2325
|
+
tl.history.push(latestUpdate);
|
|
2326
|
+
store.logger.info(
|
|
2327
|
+
`\u231B`,
|
|
2328
|
+
`timeline`,
|
|
2329
|
+
tl.key,
|
|
2330
|
+
`got a selector_update "${currentSelectorKey}" with`,
|
|
2331
|
+
latestUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key)
|
|
2332
|
+
);
|
|
2333
|
+
tl.at = tl.history.length;
|
|
2334
|
+
tl.selectorTime = currentSelectorTime;
|
|
2335
|
+
} else {
|
|
2336
|
+
if ((latestUpdate == null ? void 0 : latestUpdate.type) === `selector_update`) {
|
|
2337
|
+
latestUpdate.atomUpdates.push(__spreadValues({
|
|
2338
|
+
key: atom.key,
|
|
2339
|
+
type: `atom_update`
|
|
2340
|
+
}, update));
|
|
1832
2341
|
store.logger.info(
|
|
1833
2342
|
`\u231B`,
|
|
1834
2343
|
`timeline`,
|
|
1835
2344
|
tl.key,
|
|
1836
|
-
`
|
|
2345
|
+
`set selector_update "${currentSelectorKey}" to`,
|
|
2346
|
+
latestUpdate == null ? void 0 : latestUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key)
|
|
1837
2347
|
);
|
|
1838
2348
|
}
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
type: `atom_update`
|
|
1853
|
-
}, update));
|
|
2349
|
+
}
|
|
2350
|
+
if (latestUpdate) {
|
|
2351
|
+
const willCaptureSelectorUpdate = (_d = (_c = tl.shouldCapture) == null ? void 0 : _c.call(tl, latestUpdate, tl)) != null ? _d : true;
|
|
2352
|
+
if (willCaptureSelectorUpdate) {
|
|
2353
|
+
tl.subject.next(latestUpdate);
|
|
2354
|
+
} else {
|
|
2355
|
+
tl.history.pop();
|
|
2356
|
+
tl.at = tl.history.length;
|
|
2357
|
+
}
|
|
2358
|
+
}
|
|
2359
|
+
} else {
|
|
2360
|
+
const timestamp = Date.now();
|
|
2361
|
+
tl.selectorTime = null;
|
|
1854
2362
|
if (tl.at !== tl.history.length) {
|
|
1855
2363
|
tl.history.splice(tl.at);
|
|
1856
2364
|
}
|
|
1857
|
-
|
|
2365
|
+
const atomUpdate = {
|
|
2366
|
+
type: `atom_update`,
|
|
2367
|
+
timestamp,
|
|
2368
|
+
key: atom.key,
|
|
2369
|
+
oldValue: update.oldValue,
|
|
2370
|
+
newValue: update.newValue
|
|
2371
|
+
};
|
|
2372
|
+
if (atom.family) {
|
|
2373
|
+
atomUpdate.family = atom.family;
|
|
2374
|
+
}
|
|
2375
|
+
const willCapture = (_f = (_e = tl.shouldCapture) == null ? void 0 : _e.call(tl, atomUpdate, tl)) != null ? _f : true;
|
|
1858
2376
|
store.logger.info(
|
|
1859
2377
|
`\u231B`,
|
|
1860
2378
|
`timeline`,
|
|
1861
2379
|
tl.key,
|
|
1862
|
-
`got
|
|
1863
|
-
latestUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key)
|
|
2380
|
+
`got an atom_update to "${atom.key}"`
|
|
1864
2381
|
);
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
} else {
|
|
1868
|
-
if ((latestUpdate == null ? void 0 : latestUpdate.type) === `selector_update`) {
|
|
1869
|
-
latestUpdate.atomUpdates.push(__spreadValues({
|
|
1870
|
-
key: atom.key,
|
|
1871
|
-
type: `atom_update`
|
|
1872
|
-
}, update));
|
|
1873
|
-
store.logger.info(
|
|
1874
|
-
`\u231B`,
|
|
1875
|
-
`timeline`,
|
|
1876
|
-
tl.key,
|
|
1877
|
-
`set selector_update "${currentSelectorKey}" to`,
|
|
1878
|
-
latestUpdate == null ? void 0 : latestUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key)
|
|
1879
|
-
);
|
|
1880
|
-
}
|
|
1881
|
-
}
|
|
1882
|
-
if (latestUpdate) {
|
|
1883
|
-
const willCaptureSelectorUpdate = (_d = (_c = tl.shouldCapture) == null ? void 0 : _c.call(tl, latestUpdate, tl)) != null ? _d : true;
|
|
1884
|
-
if (willCaptureSelectorUpdate) {
|
|
1885
|
-
tl.subject.next(latestUpdate);
|
|
1886
|
-
} else {
|
|
1887
|
-
tl.history.pop();
|
|
2382
|
+
if (willCapture) {
|
|
2383
|
+
tl.history.push(atomUpdate);
|
|
1888
2384
|
tl.at = tl.history.length;
|
|
2385
|
+
tl.subject.next(atomUpdate);
|
|
1889
2386
|
}
|
|
1890
2387
|
}
|
|
1891
|
-
} else {
|
|
1892
|
-
const timestamp = Date.now();
|
|
1893
|
-
tl.selectorTime = null;
|
|
1894
|
-
if (tl.at !== tl.history.length) {
|
|
1895
|
-
tl.history.splice(tl.at);
|
|
1896
|
-
}
|
|
1897
|
-
const atomUpdate = {
|
|
1898
|
-
type: `atom_update`,
|
|
1899
|
-
timestamp,
|
|
1900
|
-
key: atom.key,
|
|
1901
|
-
oldValue: update.oldValue,
|
|
1902
|
-
newValue: update.newValue
|
|
1903
|
-
};
|
|
1904
|
-
if (atom.family) {
|
|
1905
|
-
atomUpdate.family = atom.family;
|
|
1906
|
-
}
|
|
1907
|
-
const willCapture = (_f = (_e = tl.shouldCapture) == null ? void 0 : _e.call(tl, atomUpdate, tl)) != null ? _f : true;
|
|
1908
|
-
store.logger.info(
|
|
1909
|
-
`\u231B`,
|
|
1910
|
-
`timeline`,
|
|
1911
|
-
tl.key,
|
|
1912
|
-
`got an atom_update to "${atom.key}"`
|
|
1913
|
-
);
|
|
1914
|
-
if (willCapture) {
|
|
1915
|
-
tl.history.push(atomUpdate);
|
|
1916
|
-
tl.at = tl.history.length;
|
|
1917
|
-
tl.subject.next(atomUpdate);
|
|
1918
|
-
}
|
|
1919
2388
|
}
|
|
1920
|
-
}
|
|
1921
|
-
|
|
2389
|
+
})
|
|
2390
|
+
);
|
|
1922
2391
|
};
|
|
1923
|
-
|
|
1924
|
-
// internal/src/timeline/create-timeline.ts
|
|
1925
2392
|
function createTimeline(options, store, data) {
|
|
1926
2393
|
var _a, _b;
|
|
1927
2394
|
const tl = __spreadProps(__spreadValues({
|
|
@@ -1934,60 +2401,141 @@ function createTimeline(options, store, data) {
|
|
|
1934
2401
|
}, data), {
|
|
1935
2402
|
history: (_a = data == null ? void 0 : data.history.map((update) => __spreadValues({}, update))) != null ? _a : [],
|
|
1936
2403
|
install: (s) => createTimeline(options, s, tl),
|
|
1937
|
-
subject: new Subject()
|
|
2404
|
+
subject: new Subject(),
|
|
2405
|
+
subscriptions: /* @__PURE__ */ new Map()
|
|
1938
2406
|
});
|
|
1939
2407
|
if (options.shouldCapture) {
|
|
1940
2408
|
tl.shouldCapture = options.shouldCapture;
|
|
1941
2409
|
}
|
|
1942
2410
|
const timelineKey = options.key;
|
|
1943
2411
|
const target = newest(store);
|
|
1944
|
-
for (const tokenOrFamily of options.
|
|
2412
|
+
for (const tokenOrFamily of options.scope) {
|
|
1945
2413
|
let atomKey = tokenOrFamily.key;
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
const updateAtom = withdraw(getUpdateToken(atom), store);
|
|
1963
|
-
atom = updateAtom;
|
|
1964
|
-
atomKey = atom.key;
|
|
1965
|
-
}
|
|
1966
|
-
if (`family` in atom) {
|
|
1967
|
-
const familyTimelineKey = target.timelineAtoms.getRelatedKey(
|
|
1968
|
-
atom.family.key
|
|
1969
|
-
);
|
|
1970
|
-
if (familyTimelineKey) {
|
|
1971
|
-
store.logger.error(
|
|
1972
|
-
`\u274C`,
|
|
1973
|
-
`timeline`,
|
|
1974
|
-
options.key,
|
|
1975
|
-
`Failed to add atom "${atom.key}" because its family "${atom.family.key}" already belongs to timeline "${familyTimelineKey}"`
|
|
2414
|
+
switch (tokenOrFamily.type) {
|
|
2415
|
+
case `atom_family`:
|
|
2416
|
+
case `mutable_atom_family`:
|
|
2417
|
+
{
|
|
2418
|
+
const familyToken = tokenOrFamily;
|
|
2419
|
+
const family = withdraw(familyToken, store);
|
|
2420
|
+
const familyKey = family.key;
|
|
2421
|
+
target.timelineAtoms.set({ atomKey: familyKey, timelineKey });
|
|
2422
|
+
tl.subscriptions.set(
|
|
2423
|
+
family.key,
|
|
2424
|
+
family.subject.subscribe(
|
|
2425
|
+
`timeline:${options.key}`,
|
|
2426
|
+
(creationOrDisposal) => {
|
|
2427
|
+
handleStateLifecycleEvent(creationOrDisposal, tl, store);
|
|
2428
|
+
}
|
|
2429
|
+
)
|
|
1976
2430
|
);
|
|
1977
|
-
|
|
2431
|
+
for (const atom of target.atoms.values()) {
|
|
2432
|
+
if (((_b = atom.family) == null ? void 0 : _b.key) === familyKey) {
|
|
2433
|
+
addAtomToTimeline(atom, tl, store);
|
|
2434
|
+
}
|
|
2435
|
+
}
|
|
1978
2436
|
}
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
2437
|
+
break;
|
|
2438
|
+
case `atom`:
|
|
2439
|
+
case `mutable_atom`:
|
|
2440
|
+
{
|
|
2441
|
+
let atom = withdraw(tokenOrFamily, store);
|
|
2442
|
+
if (isMutable(atom)) {
|
|
2443
|
+
const updateAtom = withdraw(getUpdateToken(atom), store);
|
|
2444
|
+
atom = updateAtom;
|
|
2445
|
+
atomKey = atom.key;
|
|
2446
|
+
}
|
|
2447
|
+
if (`family` in atom) {
|
|
2448
|
+
const familyTimelineKey = target.timelineAtoms.getRelatedKey(
|
|
2449
|
+
atom.family.key
|
|
2450
|
+
);
|
|
2451
|
+
if (familyTimelineKey) {
|
|
2452
|
+
store.logger.error(
|
|
2453
|
+
`\u274C`,
|
|
2454
|
+
`timeline`,
|
|
2455
|
+
options.key,
|
|
2456
|
+
`Failed to add atom "${atom.key}" because its family "${atom.family.key}" already belongs to timeline "${familyTimelineKey}"`
|
|
2457
|
+
);
|
|
2458
|
+
continue;
|
|
2459
|
+
}
|
|
2460
|
+
}
|
|
2461
|
+
const existingTimelineKey = target.timelineAtoms.getRelatedKey(atomKey);
|
|
2462
|
+
if (existingTimelineKey) {
|
|
2463
|
+
store.logger.error(
|
|
2464
|
+
`\u274C`,
|
|
2465
|
+
`timeline`,
|
|
2466
|
+
options.key,
|
|
2467
|
+
`Failed to add atom "${atomKey}" because it already belongs to timeline "${existingTimelineKey}"`
|
|
2468
|
+
);
|
|
2469
|
+
continue;
|
|
2470
|
+
}
|
|
2471
|
+
addAtomToTimeline(atom, tl, store);
|
|
2472
|
+
}
|
|
2473
|
+
break;
|
|
2474
|
+
case `molecule_family`:
|
|
2475
|
+
{
|
|
2476
|
+
const family = store.moleculeFamilies.get(tokenOrFamily.key);
|
|
2477
|
+
if (family) {
|
|
2478
|
+
tl.subscriptions.set(
|
|
2479
|
+
tokenOrFamily.key,
|
|
2480
|
+
family.subject.subscribe(
|
|
2481
|
+
`timeline:${options.key}`,
|
|
2482
|
+
(creationOrDisposal) => {
|
|
2483
|
+
var _a2, _b2;
|
|
2484
|
+
switch (creationOrDisposal.type) {
|
|
2485
|
+
case `molecule_creation`:
|
|
2486
|
+
{
|
|
2487
|
+
const molecule = store.molecules.get(
|
|
2488
|
+
stringifyJson(creationOrDisposal.token.key)
|
|
2489
|
+
);
|
|
2490
|
+
if (molecule) {
|
|
2491
|
+
const event = Object.assign(creationOrDisposal, {
|
|
2492
|
+
timestamp: Date.now()
|
|
2493
|
+
});
|
|
2494
|
+
tl.history.push(event);
|
|
2495
|
+
tl.at = tl.history.length;
|
|
2496
|
+
tl.subject.next(event);
|
|
2497
|
+
for (const token2 of molecule.tokens) {
|
|
2498
|
+
switch (token2.type) {
|
|
2499
|
+
case `atom`:
|
|
2500
|
+
case `mutable_atom`:
|
|
2501
|
+
addAtomToTimeline(token2, tl, store);
|
|
2502
|
+
break;
|
|
2503
|
+
}
|
|
2504
|
+
}
|
|
2505
|
+
tl.subscriptions.set(
|
|
2506
|
+
molecule.key,
|
|
2507
|
+
molecule.subject.subscribe(
|
|
2508
|
+
`timeline:${options.key}`,
|
|
2509
|
+
(stateCreationOrDisposal) => {
|
|
2510
|
+
handleStateLifecycleEvent(
|
|
2511
|
+
stateCreationOrDisposal,
|
|
2512
|
+
tl,
|
|
2513
|
+
store
|
|
2514
|
+
);
|
|
2515
|
+
}
|
|
2516
|
+
)
|
|
2517
|
+
);
|
|
2518
|
+
}
|
|
2519
|
+
}
|
|
2520
|
+
break;
|
|
2521
|
+
case `molecule_disposal`:
|
|
2522
|
+
(_a2 = tl.subscriptions.get(creationOrDisposal.token.key)) == null ? void 0 : _a2();
|
|
2523
|
+
tl.subscriptions.delete(creationOrDisposal.token.key);
|
|
2524
|
+
for (const familyKey of creationOrDisposal.familyKeys) {
|
|
2525
|
+
const stateKey = `${familyKey}(${stringifyJson(
|
|
2526
|
+
creationOrDisposal.token.key
|
|
2527
|
+
)})`;
|
|
2528
|
+
(_b2 = tl.subscriptions.get(stateKey)) == null ? void 0 : _b2();
|
|
2529
|
+
tl.subscriptions.delete(stateKey);
|
|
2530
|
+
}
|
|
2531
|
+
break;
|
|
2532
|
+
}
|
|
2533
|
+
}
|
|
2534
|
+
)
|
|
2535
|
+
);
|
|
2536
|
+
}
|
|
2537
|
+
}
|
|
2538
|
+
break;
|
|
1991
2539
|
}
|
|
1992
2540
|
}
|
|
1993
2541
|
store.timelines.set(options.key, tl);
|
|
@@ -1998,6 +2546,27 @@ function createTimeline(options, store, data) {
|
|
|
1998
2546
|
store.on.timelineCreation.next(token);
|
|
1999
2547
|
return token;
|
|
2000
2548
|
}
|
|
2549
|
+
function handleStateLifecycleEvent(event, tl, store) {
|
|
2550
|
+
var _a;
|
|
2551
|
+
const timestamp = Date.now();
|
|
2552
|
+
const timelineEvent = Object.assign(event, {
|
|
2553
|
+
timestamp
|
|
2554
|
+
});
|
|
2555
|
+
if (!tl.timeTraveling) {
|
|
2556
|
+
tl.history.push(timelineEvent);
|
|
2557
|
+
tl.at = tl.history.length;
|
|
2558
|
+
tl.subject.next(timelineEvent);
|
|
2559
|
+
}
|
|
2560
|
+
switch (event.type) {
|
|
2561
|
+
case `state_creation`:
|
|
2562
|
+
addAtomToTimeline(event.token, tl, store);
|
|
2563
|
+
break;
|
|
2564
|
+
case `state_disposal`:
|
|
2565
|
+
(_a = tl.subscriptions.get(event.token.key)) == null ? void 0 : _a();
|
|
2566
|
+
tl.subscriptions.delete(event.token.key);
|
|
2567
|
+
break;
|
|
2568
|
+
}
|
|
2569
|
+
}
|
|
2001
2570
|
|
|
2002
2571
|
// internal/src/timeline/time-travel.ts
|
|
2003
2572
|
var timeTravel = (action, token, store) => {
|
|
@@ -2045,6 +2614,22 @@ var timeTravel = (action, token, store) => {
|
|
|
2045
2614
|
ingestTransactionUpdate(applying, update, store);
|
|
2046
2615
|
break;
|
|
2047
2616
|
}
|
|
2617
|
+
case `state_creation`: {
|
|
2618
|
+
ingestCreationEvent(update, applying, store);
|
|
2619
|
+
break;
|
|
2620
|
+
}
|
|
2621
|
+
case `state_disposal`: {
|
|
2622
|
+
ingestDisposalEvent(update, applying, store);
|
|
2623
|
+
break;
|
|
2624
|
+
}
|
|
2625
|
+
case `molecule_creation`: {
|
|
2626
|
+
ingestMoleculeCreationEvent(update, applying, store);
|
|
2627
|
+
break;
|
|
2628
|
+
}
|
|
2629
|
+
case `molecule_disposal`: {
|
|
2630
|
+
ingestMoleculeDisposalEvent(update, applying, store);
|
|
2631
|
+
break;
|
|
2632
|
+
}
|
|
2048
2633
|
}
|
|
2049
2634
|
if (action === `redo`) {
|
|
2050
2635
|
++timelineData.at;
|
|
@@ -2059,251 +2644,4 @@ var timeTravel = (action, token, store) => {
|
|
|
2059
2644
|
);
|
|
2060
2645
|
};
|
|
2061
2646
|
|
|
2062
|
-
|
|
2063
|
-
var abortTransaction = (store) => {
|
|
2064
|
-
const target = newest(store);
|
|
2065
|
-
if (!isChildStore(target)) {
|
|
2066
|
-
store.logger.warn(
|
|
2067
|
-
`\u{1F41E}`,
|
|
2068
|
-
`transaction`,
|
|
2069
|
-
`???`,
|
|
2070
|
-
`abortTransaction called outside of a transaction. This is probably a bug in AtomIO.`
|
|
2071
|
-
);
|
|
2072
|
-
return;
|
|
2073
|
-
}
|
|
2074
|
-
store.logger.info(
|
|
2075
|
-
`\u{1FA82}`,
|
|
2076
|
-
`transaction`,
|
|
2077
|
-
target.transactionMeta.update.key,
|
|
2078
|
-
`Aborting transaction`
|
|
2079
|
-
);
|
|
2080
|
-
target.parent.child = null;
|
|
2081
|
-
};
|
|
2082
|
-
|
|
2083
|
-
// internal/src/transaction/act-upon-store.ts
|
|
2084
|
-
function actUponStore(token, id, store) {
|
|
2085
|
-
return (...parameters) => {
|
|
2086
|
-
const tx = withdraw(token, store);
|
|
2087
|
-
if (tx) {
|
|
2088
|
-
return tx.run(parameters, id);
|
|
2089
|
-
}
|
|
2090
|
-
throw new NotFoundError(token, store);
|
|
2091
|
-
};
|
|
2092
|
-
}
|
|
2093
|
-
|
|
2094
|
-
// internal/src/transaction/set-epoch-number.ts
|
|
2095
|
-
function setEpochNumberOfContinuity(continuityKey, newEpoch, store) {
|
|
2096
|
-
const isRoot = isRootStore(store);
|
|
2097
|
-
if (isRoot && continuityKey) {
|
|
2098
|
-
store.transactionMeta.epoch.set(continuityKey, newEpoch);
|
|
2099
|
-
}
|
|
2100
|
-
}
|
|
2101
|
-
function setEpochNumberOfAction(transactionKey, newEpoch, store) {
|
|
2102
|
-
const isRoot = isRootStore(store);
|
|
2103
|
-
if (!isRoot) {
|
|
2104
|
-
return;
|
|
2105
|
-
}
|
|
2106
|
-
const continuityKey = store.transactionMeta.actionContinuities.getRelatedKey(transactionKey);
|
|
2107
|
-
if (continuityKey !== void 0) {
|
|
2108
|
-
store.transactionMeta.epoch.set(continuityKey, newEpoch);
|
|
2109
|
-
}
|
|
2110
|
-
}
|
|
2111
|
-
|
|
2112
|
-
// internal/src/transaction/apply-transaction.ts
|
|
2113
|
-
var applyTransaction = (output, store) => {
|
|
2114
|
-
var _a;
|
|
2115
|
-
const child = newest(store);
|
|
2116
|
-
const { parent } = child;
|
|
2117
|
-
if (parent === null || !isChildStore(child) || ((_a = child.transactionMeta) == null ? void 0 : _a.phase) !== `building`) {
|
|
2118
|
-
store.logger.warn(
|
|
2119
|
-
`\u{1F41E}`,
|
|
2120
|
-
`transaction`,
|
|
2121
|
-
`???`,
|
|
2122
|
-
`applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`
|
|
2123
|
-
);
|
|
2124
|
-
return;
|
|
2125
|
-
}
|
|
2126
|
-
child.transactionMeta.phase = `applying`;
|
|
2127
|
-
child.transactionMeta.update.output = output;
|
|
2128
|
-
parent.child = null;
|
|
2129
|
-
parent.on.transactionApplying.next(child.transactionMeta);
|
|
2130
|
-
const { updates } = child.transactionMeta.update;
|
|
2131
|
-
store.logger.info(
|
|
2132
|
-
`\u{1F6C4}`,
|
|
2133
|
-
`transaction`,
|
|
2134
|
-
child.transactionMeta.update.key,
|
|
2135
|
-
`Applying transaction with ${updates.length} updates:`,
|
|
2136
|
-
updates
|
|
2137
|
-
);
|
|
2138
|
-
for (const tracker of child.trackers.values()) {
|
|
2139
|
-
const mutableKey = tracker.mutableState.key;
|
|
2140
|
-
if (!parent.atoms.has(mutableKey)) {
|
|
2141
|
-
const atom = child.atoms.get(mutableKey);
|
|
2142
|
-
atom == null ? void 0 : atom.install(parent);
|
|
2143
|
-
}
|
|
2144
|
-
tracker.dispose();
|
|
2145
|
-
}
|
|
2146
|
-
for (const atom of child.atoms.values()) {
|
|
2147
|
-
if (!parent.atoms.has(atom.key)) {
|
|
2148
|
-
parent.atoms.set(atom.key, atom);
|
|
2149
|
-
parent.valueMap.set(atom.key, atom.default);
|
|
2150
|
-
parent.logger.info(
|
|
2151
|
-
`\u{1F528}`,
|
|
2152
|
-
`transaction`,
|
|
2153
|
-
child.transactionMeta.update.key,
|
|
2154
|
-
`Adding atom "${atom.key}"`
|
|
2155
|
-
);
|
|
2156
|
-
}
|
|
2157
|
-
}
|
|
2158
|
-
ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
|
|
2159
|
-
if (isRootStore(parent)) {
|
|
2160
|
-
setEpochNumberOfAction(
|
|
2161
|
-
child.transactionMeta.update.key,
|
|
2162
|
-
child.transactionMeta.update.epoch,
|
|
2163
|
-
parent
|
|
2164
|
-
);
|
|
2165
|
-
const myTransaction = withdraw(
|
|
2166
|
-
{ key: child.transactionMeta.update.key, type: `transaction` },
|
|
2167
|
-
store
|
|
2168
|
-
);
|
|
2169
|
-
myTransaction == null ? void 0 : myTransaction.subject.next(child.transactionMeta.update);
|
|
2170
|
-
store.logger.info(
|
|
2171
|
-
`\u{1F6EC}`,
|
|
2172
|
-
`transaction`,
|
|
2173
|
-
child.transactionMeta.update.key,
|
|
2174
|
-
`Finished applying transaction.`
|
|
2175
|
-
);
|
|
2176
|
-
} else if (isChildStore(parent)) {
|
|
2177
|
-
parent.transactionMeta.update.updates.push(child.transactionMeta.update);
|
|
2178
|
-
}
|
|
2179
|
-
parent.on.transactionApplying.next(null);
|
|
2180
|
-
};
|
|
2181
|
-
|
|
2182
|
-
// internal/src/transaction/assign-transaction-to-continuity.ts
|
|
2183
|
-
function assignTransactionToContinuity(continuityKey, transactionKey, store) {
|
|
2184
|
-
const isRoot = isRootStore(store);
|
|
2185
|
-
if (!isRoot) {
|
|
2186
|
-
return;
|
|
2187
|
-
}
|
|
2188
|
-
const { epoch, actionContinuities } = store.transactionMeta;
|
|
2189
|
-
actionContinuities.set(continuityKey, transactionKey);
|
|
2190
|
-
if (!epoch.has(continuityKey)) {
|
|
2191
|
-
epoch.set(continuityKey, -1);
|
|
2192
|
-
}
|
|
2193
|
-
}
|
|
2194
|
-
|
|
2195
|
-
// internal/src/transaction/build-transaction.ts
|
|
2196
|
-
var buildTransaction = (key, params, store, id) => {
|
|
2197
|
-
const parent = newest(store);
|
|
2198
|
-
const childBase = {
|
|
2199
|
-
parent,
|
|
2200
|
-
child: null,
|
|
2201
|
-
on: parent.on,
|
|
2202
|
-
loggers: parent.loggers,
|
|
2203
|
-
logger: parent.logger,
|
|
2204
|
-
config: parent.config,
|
|
2205
|
-
atoms: new LazyMap(parent.atoms),
|
|
2206
|
-
atomsThatAreDefault: new Set(parent.atomsThatAreDefault),
|
|
2207
|
-
families: new LazyMap(parent.families),
|
|
2208
|
-
operation: { open: false },
|
|
2209
|
-
readonlySelectors: new LazyMap(parent.readonlySelectors),
|
|
2210
|
-
timelines: new LazyMap(parent.timelines),
|
|
2211
|
-
timelineAtoms: new Junction(parent.timelineAtoms.toJSON()),
|
|
2212
|
-
trackers: /* @__PURE__ */ new Map(),
|
|
2213
|
-
transactions: new LazyMap(parent.transactions),
|
|
2214
|
-
selectorAtoms: new Junction(parent.selectorAtoms.toJSON()),
|
|
2215
|
-
selectorGraph: new Junction(parent.selectorGraph.toJSON(), {
|
|
2216
|
-
makeContentKey: (...keys) => keys.sort().join(`:`)
|
|
2217
|
-
}),
|
|
2218
|
-
selectors: new LazyMap(parent.selectors),
|
|
2219
|
-
valueMap: new LazyMap(parent.valueMap),
|
|
2220
|
-
molecules: new LazyMap(parent.molecules),
|
|
2221
|
-
miscResources: new LazyMap(parent.miscResources)
|
|
2222
|
-
};
|
|
2223
|
-
const epoch = getEpochNumberOfAction(key, store);
|
|
2224
|
-
const transactionMeta = {
|
|
2225
|
-
phase: `building`,
|
|
2226
|
-
update: {
|
|
2227
|
-
key,
|
|
2228
|
-
id,
|
|
2229
|
-
epoch: epoch === void 0 ? Number.NaN : epoch + 1,
|
|
2230
|
-
updates: [],
|
|
2231
|
-
params,
|
|
2232
|
-
output: void 0
|
|
2233
|
-
},
|
|
2234
|
-
transactors: {
|
|
2235
|
-
get: (token) => getFromStore(token, child),
|
|
2236
|
-
set: (token, value) => {
|
|
2237
|
-
setIntoStore(token, value, child);
|
|
2238
|
-
},
|
|
2239
|
-
run: (token, identifier = arbitrary()) => actUponStore(token, identifier, child),
|
|
2240
|
-
find: (token, k) => findInStore(token, k, child),
|
|
2241
|
-
seek: (token, k) => seekInStore(token, k, child),
|
|
2242
|
-
env: () => getEnvironmentData(child)
|
|
2243
|
-
}
|
|
2244
|
-
};
|
|
2245
|
-
const child = Object.assign(childBase, {
|
|
2246
|
-
transactionMeta
|
|
2247
|
-
});
|
|
2248
|
-
parent.child = child;
|
|
2249
|
-
store.logger.info(
|
|
2250
|
-
`\u{1F6EB}`,
|
|
2251
|
-
`transaction`,
|
|
2252
|
-
key,
|
|
2253
|
-
`Building transaction with params:`,
|
|
2254
|
-
params
|
|
2255
|
-
);
|
|
2256
|
-
return child;
|
|
2257
|
-
};
|
|
2258
|
-
|
|
2259
|
-
// internal/src/transaction/create-transaction.ts
|
|
2260
|
-
function createTransaction(options, store) {
|
|
2261
|
-
const newTransaction = {
|
|
2262
|
-
key: options.key,
|
|
2263
|
-
type: `transaction`,
|
|
2264
|
-
run: (params, id) => {
|
|
2265
|
-
const childStore = buildTransaction(options.key, params, store, id);
|
|
2266
|
-
try {
|
|
2267
|
-
const target2 = newest(store);
|
|
2268
|
-
const { transactors } = childStore.transactionMeta;
|
|
2269
|
-
const output = options.do(transactors, ...params);
|
|
2270
|
-
applyTransaction(output, target2);
|
|
2271
|
-
return output;
|
|
2272
|
-
} catch (thrown) {
|
|
2273
|
-
abortTransaction(target);
|
|
2274
|
-
store.logger.warn(`\u{1F4A5}`, `transaction`, options.key, `caught:`, thrown);
|
|
2275
|
-
throw thrown;
|
|
2276
|
-
}
|
|
2277
|
-
},
|
|
2278
|
-
install: (s) => createTransaction(options, s),
|
|
2279
|
-
subject: new Subject()
|
|
2280
|
-
};
|
|
2281
|
-
const target = newest(store);
|
|
2282
|
-
target.transactions.set(newTransaction.key, newTransaction);
|
|
2283
|
-
const token = deposit(newTransaction);
|
|
2284
|
-
store.on.transactionCreation.next(token);
|
|
2285
|
-
return token;
|
|
2286
|
-
}
|
|
2287
|
-
|
|
2288
|
-
// internal/src/transaction/get-epoch-number.ts
|
|
2289
|
-
function getContinuityKey(transactionKey, store) {
|
|
2290
|
-
const isRoot = isRootStore(store);
|
|
2291
|
-
const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
|
|
2292
|
-
return continuity;
|
|
2293
|
-
}
|
|
2294
|
-
function getEpochNumberOfContinuity(continuityKey, store) {
|
|
2295
|
-
const isRoot = isRootStore(store);
|
|
2296
|
-
const epoch = isRoot && continuityKey ? store.transactionMeta.epoch.get(continuityKey) : void 0;
|
|
2297
|
-
return epoch;
|
|
2298
|
-
}
|
|
2299
|
-
function getEpochNumberOfAction(transactionKey, store) {
|
|
2300
|
-
const isRoot = isRootStore(store);
|
|
2301
|
-
const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
|
|
2302
|
-
const epoch = isRoot && continuity !== void 0 ? store.transactionMeta.epoch.get(continuity) : void 0;
|
|
2303
|
-
return epoch;
|
|
2304
|
-
}
|
|
2305
|
-
|
|
2306
|
-
// internal/src/transaction/index.ts
|
|
2307
|
-
var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
|
|
2308
|
-
|
|
2309
|
-
export { FamilyTracker, Future, IMPLICIT, LazyMap, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, addAtomToTimeline, applyTransaction, arbitrary, assignTransactionToContinuity, become, buildTransaction, cacheValue, clearStore, closeOperation, createAtomFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelector, createReadonlySelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneAtom, createStandaloneSelector, createTimeline, createTransaction, createWritableSelector, deposit, disposeAtom, disposeSelector, evictCachedValue, findInStore, getContinuityKey, getEnvironmentData, getEpochNumberOfAction, getEpochNumberOfContinuity, getFromStore, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getUpdateToken, ingestAtomUpdate, ingestSelectorUpdate, ingestTransactionUpdate, initFamilyMember, isAtomDefault, isAtomKey, isChildStore, isDone, isMutable, isReadonlySelectorKey, isRootStore, isSelectorKey, isStateKey, isTransceiver, markAtomAsDefault, markAtomAsNotDefault, markDone, newest, openOperation, readCachedValue, readOrComputeValue, registerSelector, seekInStore, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeToRootAtoms, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, updateSelectorAtoms, withdraw };
|
|
2647
|
+
export { FamilyTracker, Future, IMPLICIT, LazyMap, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, addAtomToTimeline, applyTransaction, arbitrary, assignTransactionToContinuity, become, buildTransaction, cacheValue, clearStore, closeOperation, createAtomFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelector, createReadonlySelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneAtom, createStandaloneSelector, createTimeline, createTransaction, createWritableSelector, deposit, disposeAtom2 as disposeAtom, disposeFromStore, disposeSelector2 as disposeSelector, evictCachedValue, findInStore, getContinuityKey, getEnvironmentData, getEpochNumberOfAction, getEpochNumberOfContinuity, getFromStore, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getUpdateToken, ingestAtomUpdate, ingestCreationEvent, ingestDisposalEvent, ingestMoleculeCreationEvent, ingestMoleculeDisposalEvent, ingestSelectorUpdate, ingestTransactionUpdate, initFamilyMember, isAtomDefault, isAtomKey, isChildStore, isDone, isMutable, isReadonlySelectorKey, isRootStore, isSelectorKey, isStateKey, isTransceiver, markAtomAsDefault, markAtomAsNotDefault, markDone, newest, openOperation, readCachedValue, readOrComputeValue, registerSelector, seekInStore, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeToRootAtoms, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, updateSelectorAtoms, withdraw };
|