atom.io 0.39.0 β 0.40.0
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/data/index.js.map +1 -1
- package/dist/eslint-plugin/index.js +2 -1
- package/dist/eslint-plugin/index.js.map +1 -1
- package/dist/internal/index.d.ts +14 -8
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +129 -87
- package/dist/internal/index.js.map +1 -1
- package/dist/introspection/index.d.ts.map +1 -1
- package/dist/introspection/index.js.map +1 -1
- package/dist/json/index.d.ts.map +1 -1
- package/dist/json/index.js.map +1 -1
- package/dist/main/index.d.ts +8 -7
- package/dist/main/index.d.ts.map +1 -1
- package/dist/main/index.js.map +1 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +43 -2
- package/dist/react/index.js.map +1 -1
- package/dist/react-devtools/index.d.ts.map +1 -1
- package/dist/react-devtools/index.js +12 -10
- package/dist/react-devtools/index.js.map +1 -1
- package/dist/realtime/index.d.ts.map +1 -1
- package/dist/realtime/index.js.map +1 -1
- package/dist/realtime-client/index.js.map +1 -1
- package/dist/realtime-react/index.js.map +1 -1
- package/dist/realtime-server/index.d.ts.map +1 -1
- package/dist/realtime-server/index.js.map +1 -1
- package/dist/realtime-testing/index.d.ts.map +1 -1
- package/dist/realtime-testing/index.js.map +1 -1
- package/dist/transceivers/set-rtx/index.d.ts.map +1 -1
- package/dist/transceivers/set-rtx/index.js.map +1 -1
- package/dist/web/index.js.map +1 -1
- package/package.json +8 -8
- package/src/internal/events/ingest-selector-update.ts +13 -4
- package/src/internal/families/create-regular-atom-family.ts +3 -2
- package/src/internal/get-state/read-or-compute-value.ts +2 -1
- package/src/internal/get-state/reduce-reference.ts +15 -2
- package/src/internal/is-fn.ts +9 -0
- package/src/internal/operation.ts +3 -1
- package/src/internal/set-state/become.ts +11 -6
- package/src/internal/set-state/dispatch-state-update.ts +15 -12
- package/src/internal/set-state/operate-on-store.ts +3 -1
- package/src/internal/set-state/reset-atom-or-selector.ts +7 -7
- package/src/internal/set-state/set-atom-or-selector.ts +3 -2
- package/src/internal/set-state/set-atom.ts +4 -3
- package/src/internal/set-state/set-selector.ts +8 -7
- package/src/internal/timeline/create-timeline.ts +133 -98
- package/src/internal/timeline/time-travel.ts +42 -31
- package/src/internal/transaction/apply-transaction.ts +2 -2
- package/src/internal/transaction/build-transaction.ts +1 -1
- package/src/main/events.ts +8 -2
- package/src/main/logger.ts +1 -1
- package/src/main/timeline.ts +1 -7
- package/src/react-devtools/Updates.tsx +14 -9
- package/src/react-devtools/json-editor/editors-by-type/array-editor.tsx +1 -1
- package/src/react-devtools/json-editor/editors-by-type/object-editor.tsx +2 -3
- package/src/react-devtools/json-editor/editors-by-type/utilities/array-elements.ts +1 -1
- package/src/react-devtools/json-editor/editors-by-type/utilities/object-properties.ts +1 -1
- package/dist/use-o-DXPncKmZ.js +0 -47
- package/dist/use-o-DXPncKmZ.js.map +0 -1
package/dist/internal/index.js
CHANGED
|
@@ -663,7 +663,8 @@ function openOperation(store, token) {
|
|
|
663
663
|
done: /* @__PURE__ */ new Set(),
|
|
664
664
|
prev: /* @__PURE__ */ new Map(),
|
|
665
665
|
timestamp: Date.now(),
|
|
666
|
-
token
|
|
666
|
+
token,
|
|
667
|
+
subEvents: []
|
|
667
668
|
};
|
|
668
669
|
store.logger.info(`β`, token.type, token.key, `operation start in store "${store.config.name}"${isChildStore(store) ? ` ${store.transactionMeta.phase} "${store.transactionMeta.update.token.key}"` : ``}`);
|
|
669
670
|
return store;
|
|
@@ -798,6 +799,14 @@ function evictCachedValue(target, key) {
|
|
|
798
799
|
target.logger.info(`π`, `state`, key, `evicted`);
|
|
799
800
|
}
|
|
800
801
|
|
|
802
|
+
//#endregion
|
|
803
|
+
//#region src/internal/is-fn.ts
|
|
804
|
+
const NON_CTOR_FN_REGEX = /^\[object (?:Async|Generator|AsyncGenerator)?Function\]$/;
|
|
805
|
+
function isFn(input) {
|
|
806
|
+
const protoString = Object.prototype.toString.call(input);
|
|
807
|
+
return NON_CTOR_FN_REGEX.test(protoString);
|
|
808
|
+
}
|
|
809
|
+
|
|
801
810
|
//#endregion
|
|
802
811
|
//#region src/internal/get-state/read-or-compute-value.ts
|
|
803
812
|
function readOrComputeValue(target, state, mut) {
|
|
@@ -813,7 +822,7 @@ function readOrComputeValue(target, state, mut) {
|
|
|
813
822
|
return state.getFrom(target);
|
|
814
823
|
case `atom`: {
|
|
815
824
|
let def;
|
|
816
|
-
if (state.default
|
|
825
|
+
if (isFn(state.default)) {
|
|
817
826
|
def = state.default();
|
|
818
827
|
target.logger.info(`β¨`, state.type, key, `computed default`, def);
|
|
819
828
|
} else {
|
|
@@ -893,18 +902,24 @@ function actUponStore(store, token, id) {
|
|
|
893
902
|
|
|
894
903
|
//#endregion
|
|
895
904
|
//#region src/internal/set-state/become.ts
|
|
896
|
-
|
|
905
|
+
function become(nextVersionOfThing, originalThing) {
|
|
906
|
+
if (isFn(nextVersionOfThing)) return nextVersionOfThing(originalThing);
|
|
907
|
+
return nextVersionOfThing;
|
|
908
|
+
}
|
|
897
909
|
|
|
898
910
|
//#endregion
|
|
899
911
|
//#region src/internal/set-state/set-atom.ts
|
|
900
912
|
const setAtom = (target, atom, next) => {
|
|
901
913
|
const oldValue = readOrComputeValue(target, atom, `mut`);
|
|
902
|
-
let newValue = become(next
|
|
914
|
+
let newValue = become(next, oldValue);
|
|
903
915
|
target.logger.info(`β`, `atom`, atom.key, `setting value`, newValue);
|
|
904
916
|
newValue = writeToCache(target, atom, newValue);
|
|
905
917
|
markDone(target, atom.key);
|
|
906
918
|
evictDownstreamFromAtom(target, atom);
|
|
907
|
-
return
|
|
919
|
+
return {
|
|
920
|
+
oldValue,
|
|
921
|
+
newValue
|
|
922
|
+
};
|
|
908
923
|
};
|
|
909
924
|
|
|
910
925
|
//#endregion
|
|
@@ -914,7 +929,7 @@ function resetAtom(target, atom) {
|
|
|
914
929
|
case `mutable_atom`: return setAtom(target, atom, new atom.class());
|
|
915
930
|
case `atom`: {
|
|
916
931
|
let def = atom.default;
|
|
917
|
-
if (def
|
|
932
|
+
if (isFn(def)) def = def();
|
|
918
933
|
return setAtom(target, atom, def);
|
|
919
934
|
}
|
|
920
935
|
}
|
|
@@ -936,7 +951,10 @@ function resetAtomOrSelector(target, state) {
|
|
|
936
951
|
dispatchOrDeferStateUpdate(target, state, rootProtoUpdate, false);
|
|
937
952
|
}
|
|
938
953
|
const newValue = state.getFrom(target);
|
|
939
|
-
protoUpdate =
|
|
954
|
+
protoUpdate = {
|
|
955
|
+
oldValue,
|
|
956
|
+
newValue
|
|
957
|
+
};
|
|
940
958
|
}
|
|
941
959
|
break;
|
|
942
960
|
}
|
|
@@ -975,20 +993,23 @@ function setSelector(target, selector, next) {
|
|
|
975
993
|
const { type, key } = selector;
|
|
976
994
|
switch (selector.type) {
|
|
977
995
|
case `writable_pure_selector`:
|
|
978
|
-
oldValue =
|
|
979
|
-
newValue = become(next
|
|
980
|
-
writeToCache(target, selector, newValue);
|
|
996
|
+
oldValue = readOrComputeValue(target, selector, `mut`);
|
|
997
|
+
newValue = become(next, oldValue);
|
|
998
|
+
newValue = writeToCache(target, selector, newValue);
|
|
981
999
|
break;
|
|
982
1000
|
case `writable_held_selector`:
|
|
983
1001
|
constant = selector.const;
|
|
984
|
-
become(next
|
|
1002
|
+
become(next, constant);
|
|
985
1003
|
oldValue = constant;
|
|
986
1004
|
newValue = constant;
|
|
987
1005
|
}
|
|
988
1006
|
target.logger.info(`β`, type, key, `setting to`, newValue);
|
|
989
1007
|
markDone(target, key);
|
|
990
1008
|
selector.setSelf(newValue);
|
|
991
|
-
return
|
|
1009
|
+
return {
|
|
1010
|
+
oldValue,
|
|
1011
|
+
newValue
|
|
1012
|
+
};
|
|
992
1013
|
}
|
|
993
1014
|
|
|
994
1015
|
//#endregion
|
|
@@ -1247,9 +1268,10 @@ function ingestMoleculeTransferEvent(store, event, applying) {
|
|
|
1247
1268
|
//#region src/internal/events/ingest-selector-update.ts
|
|
1248
1269
|
function ingestSelectorUpdateEvent(store, selectorUpdate, applying) {
|
|
1249
1270
|
let updates;
|
|
1250
|
-
if (applying === `newValue`) updates = selectorUpdate.
|
|
1251
|
-
else updates = selectorUpdate.
|
|
1252
|
-
for (const atomUpdate of updates)
|
|
1271
|
+
if (applying === `newValue`) updates = selectorUpdate.subEvents;
|
|
1272
|
+
else updates = selectorUpdate.subEvents.toReversed();
|
|
1273
|
+
for (const atomUpdate of updates) if (atomUpdate.type === `state_creation`) ingestCreationEvent(store, atomUpdate, applying);
|
|
1274
|
+
else ingestAtomUpdateEvent(store, atomUpdate, applying);
|
|
1253
1275
|
}
|
|
1254
1276
|
|
|
1255
1277
|
//#endregion
|
|
@@ -1326,7 +1348,7 @@ function applyTransaction(store, output) {
|
|
|
1326
1348
|
parent.child = null;
|
|
1327
1349
|
parent.on.transactionApplying.next(child.transactionMeta);
|
|
1328
1350
|
const { subEvents: updates } = child.transactionMeta.update;
|
|
1329
|
-
store.logger.info(`π`, `transaction`, child.transactionMeta.update.token.key, `
|
|
1351
|
+
store.logger.info(`π`, `transaction`, child.transactionMeta.update.token.key, `applying ${updates.length} subEvents:`, updates);
|
|
1330
1352
|
ingestTransactionOutcomeEvent(parent, child.transactionMeta.update, `newValue`);
|
|
1331
1353
|
if (isRootStore(parent)) {
|
|
1332
1354
|
setEpochNumberOfAction(parent, child.transactionMeta.update.token.key, child.transactionMeta.update.epoch);
|
|
@@ -1335,7 +1357,7 @@ function applyTransaction(store, output) {
|
|
|
1335
1357
|
type: `transaction`
|
|
1336
1358
|
});
|
|
1337
1359
|
myTransaction?.subject.next(child.transactionMeta.update);
|
|
1338
|
-
store.logger.info(`π¬`, `transaction`, child.transactionMeta.update.token.key, `
|
|
1360
|
+
store.logger.info(`π¬`, `transaction`, child.transactionMeta.update.token.key, `applied`);
|
|
1339
1361
|
} else if (isChildStore(parent)) parent.transactionMeta.update.subEvents.push(child.transactionMeta.update);
|
|
1340
1362
|
parent.on.transactionApplying.next(null);
|
|
1341
1363
|
}
|
|
@@ -1421,7 +1443,7 @@ const buildTransaction = (store, token, params, id) => {
|
|
|
1421
1443
|
};
|
|
1422
1444
|
const child = Object.assign(childBase, { transactionMeta });
|
|
1423
1445
|
parent.child = child;
|
|
1424
|
-
store.logger.info(`π«`, `transaction`, token.key, `
|
|
1446
|
+
store.logger.info(`π«`, `transaction`, token.key, `building with params:`, params);
|
|
1425
1447
|
return child;
|
|
1426
1448
|
};
|
|
1427
1449
|
|
|
@@ -1468,17 +1490,19 @@ const TRANSACTION_PHASES = [
|
|
|
1468
1490
|
|
|
1469
1491
|
//#endregion
|
|
1470
1492
|
//#region src/internal/set-state/dispatch-state-update.ts
|
|
1471
|
-
function dispatchOrDeferStateUpdate(target, state,
|
|
1493
|
+
function dispatchOrDeferStateUpdate(target, state, { oldValue, newValue }, stateIsNewlyCreated, family) {
|
|
1472
1494
|
const token = deposit(state);
|
|
1473
1495
|
if (stateIsNewlyCreated && family) {
|
|
1474
1496
|
state.subject.next({ newValue });
|
|
1475
1497
|
const stateCreationEvent = {
|
|
1498
|
+
write: true,
|
|
1476
1499
|
type: `state_creation`,
|
|
1477
1500
|
subType: `writable`,
|
|
1478
1501
|
token,
|
|
1479
1502
|
timestamp: Date.now(),
|
|
1480
1503
|
value: newValue
|
|
1481
1504
|
};
|
|
1505
|
+
target.operation.subEvents.push(stateCreationEvent);
|
|
1482
1506
|
const familySubject = family.subject;
|
|
1483
1507
|
familySubject.next(stateCreationEvent);
|
|
1484
1508
|
const innerTarget = newest(target);
|
|
@@ -1505,11 +1529,11 @@ function dispatchOrDeferStateUpdate(target, state, [oldValue, newValue], stateIs
|
|
|
1505
1529
|
if (isRootStore(target)) {
|
|
1506
1530
|
switch (type) {
|
|
1507
1531
|
case `mutable_atom`:
|
|
1508
|
-
target.logger.info(`π’`, type, key, `is now (`, newValue, `) subscribers:`, subject.subscribers);
|
|
1532
|
+
target.logger.info(`π’`, type, key, `is now (`, newValue, `) subscribers:`, subject.subscribers.keys());
|
|
1509
1533
|
break;
|
|
1510
1534
|
case `atom`:
|
|
1511
1535
|
case `writable_pure_selector`:
|
|
1512
|
-
case `writable_held_selector`: target.logger.info(`π’`, type, key, `went (`, oldValue, `->`, newValue, `) subscribers:`, subject.subscribers);
|
|
1536
|
+
case `writable_held_selector`: target.logger.info(`π’`, type, key, `went (`, oldValue, `->`, newValue, `) subscribers:`, subject.subscribers.keys());
|
|
1513
1537
|
}
|
|
1514
1538
|
subject.next(update);
|
|
1515
1539
|
}
|
|
@@ -2037,7 +2061,7 @@ function createRegularAtomFamily(store, options, internalRoles) {
|
|
|
2037
2061
|
const def = options.default;
|
|
2038
2062
|
const individualOptions = {
|
|
2039
2063
|
key: fullKey,
|
|
2040
|
-
default: def
|
|
2064
|
+
default: isFn(def) ? () => def(key) : def
|
|
2041
2065
|
};
|
|
2042
2066
|
if (options.effects) individualOptions.effects = options.effects(key);
|
|
2043
2067
|
const token = createRegularAtom(target, individualOptions, family);
|
|
@@ -2050,7 +2074,7 @@ function createRegularAtomFamily(store, options, internalRoles) {
|
|
|
2050
2074
|
internalRoles
|
|
2051
2075
|
});
|
|
2052
2076
|
store.families.set(options.key, atomFamily$1);
|
|
2053
|
-
if (options.default
|
|
2077
|
+
if (isFn(options.default) === false) store.defaults.set(options.key, options.default);
|
|
2054
2078
|
return familyToken;
|
|
2055
2079
|
}
|
|
2056
2080
|
|
|
@@ -2288,9 +2312,22 @@ function reduceReference(store, ...params) {
|
|
|
2288
2312
|
const isCounterfeit = `counterfeit` in token;
|
|
2289
2313
|
const isNewlyCreated = Boolean(brandNewToken) && isCounterfeit === false;
|
|
2290
2314
|
if (isNewlyCreated && family) {
|
|
2315
|
+
let subType;
|
|
2316
|
+
switch (token.type) {
|
|
2317
|
+
case `readonly_pure_selector`:
|
|
2318
|
+
case `readonly_held_selector`:
|
|
2319
|
+
subType = `readable`;
|
|
2320
|
+
break;
|
|
2321
|
+
case `atom`:
|
|
2322
|
+
case `mutable_atom`:
|
|
2323
|
+
case `writable_pure_selector`:
|
|
2324
|
+
case `writable_held_selector`:
|
|
2325
|
+
subType = `writable`;
|
|
2326
|
+
break;
|
|
2327
|
+
}
|
|
2291
2328
|
const stateCreationEvent = {
|
|
2292
2329
|
type: `state_creation`,
|
|
2293
|
-
subType
|
|
2330
|
+
subType,
|
|
2294
2331
|
token,
|
|
2295
2332
|
timestamp: Date.now()
|
|
2296
2333
|
};
|
|
@@ -3501,7 +3538,6 @@ function createTimeline(store, options, data) {
|
|
|
3501
3538
|
subject: new Subject(),
|
|
3502
3539
|
subscriptions: /* @__PURE__ */ new Map()
|
|
3503
3540
|
};
|
|
3504
|
-
if (options.shouldCapture) tl.shouldCapture = options.shouldCapture;
|
|
3505
3541
|
const timelineKey = options.key;
|
|
3506
3542
|
const target = newest(store);
|
|
3507
3543
|
for (const initialTopic of options.scope) switch (initialTopic.type) {
|
|
@@ -3567,60 +3603,19 @@ function addAtomToTimeline(store, atomToken, tl) {
|
|
|
3567
3603
|
const txUpdateInProgress = target.on.transactionApplying.state?.update;
|
|
3568
3604
|
store.logger.info(`β³`, `timeline`, tl.key, `atom`, atomToken.key, `went`, update.oldValue, `->`, update.newValue, txUpdateInProgress ? `in transaction "${txUpdateInProgress.token.key}"` : currentSelectorToken ? `in selector "${currentSelectorToken.key}"` : ``);
|
|
3569
3605
|
if (tl.timeTraveling === null) if (txUpdateInProgress) joinTransaction(store, tl, txUpdateInProgress);
|
|
3570
|
-
else if (currentSelectorToken && currentSelectorTime)
|
|
3571
|
-
|
|
3572
|
-
if (currentSelectorTime !== tl.selectorTime) {
|
|
3573
|
-
latestUpdate = {
|
|
3574
|
-
type: `selector_update`,
|
|
3575
|
-
timestamp: currentSelectorTime,
|
|
3576
|
-
token: currentSelectorToken,
|
|
3577
|
-
atomUpdates: []
|
|
3578
|
-
};
|
|
3579
|
-
latestUpdate.atomUpdates.push({
|
|
3580
|
-
type: `atom_update`,
|
|
3581
|
-
token: atomToken,
|
|
3582
|
-
update,
|
|
3583
|
-
timestamp: Date.now()
|
|
3584
|
-
});
|
|
3585
|
-
if (tl.at !== tl.history.length) tl.history.splice(tl.at);
|
|
3586
|
-
tl.history.push(latestUpdate);
|
|
3587
|
-
store.logger.info(`β`, `timeline`, tl.key, `got a selector_update "${currentSelectorToken.key}" with`, latestUpdate.atomUpdates.map((atomUpdate) => atomUpdate.token.key));
|
|
3588
|
-
tl.at = tl.history.length;
|
|
3589
|
-
tl.selectorTime = currentSelectorTime;
|
|
3590
|
-
} else if (latestUpdate?.type === `selector_update`) {
|
|
3591
|
-
latestUpdate.atomUpdates.push({
|
|
3592
|
-
type: `atom_update`,
|
|
3593
|
-
token: atomToken,
|
|
3594
|
-
update,
|
|
3595
|
-
timestamp: Date.now()
|
|
3596
|
-
});
|
|
3597
|
-
store.logger.info(`β`, `timeline`, tl.key, `set selector_update "${currentSelectorToken.key}" to`, latestUpdate?.atomUpdates.map((atomUpdate) => atomUpdate.token.key));
|
|
3598
|
-
}
|
|
3599
|
-
if (latestUpdate) {
|
|
3600
|
-
const willCaptureSelectorUpdate = tl.shouldCapture?.(latestUpdate, tl) ?? true;
|
|
3601
|
-
if (willCaptureSelectorUpdate) tl.subject.next(latestUpdate);
|
|
3602
|
-
else {
|
|
3603
|
-
tl.history.pop();
|
|
3604
|
-
tl.at = tl.history.length;
|
|
3605
|
-
}
|
|
3606
|
-
}
|
|
3607
|
-
} else {
|
|
3606
|
+
else if (currentSelectorToken && currentSelectorTime) buildSelectorUpdate(store, tl, atomToken, update, currentSelectorToken, currentSelectorTime);
|
|
3607
|
+
else {
|
|
3608
3608
|
const timestamp = Date.now();
|
|
3609
3609
|
tl.selectorTime = null;
|
|
3610
|
-
if (tl.at !== tl.history.length) tl.history.splice(tl.at);
|
|
3611
3610
|
const atomUpdate = {
|
|
3611
|
+
write: true,
|
|
3612
3612
|
type: `atom_update`,
|
|
3613
3613
|
token: deposit(atom),
|
|
3614
3614
|
update,
|
|
3615
3615
|
timestamp
|
|
3616
3616
|
};
|
|
3617
|
-
const willCapture = tl.shouldCapture?.(atomUpdate, tl) ?? true;
|
|
3618
3617
|
store.logger.info(`β`, `timeline`, tl.key, `got an atom_update to "${atom.key}"`);
|
|
3619
|
-
|
|
3620
|
-
tl.history.push(atomUpdate);
|
|
3621
|
-
tl.at = tl.history.length;
|
|
3622
|
-
tl.subject.next(atomUpdate);
|
|
3623
|
-
}
|
|
3618
|
+
addToHistory(tl, atomUpdate);
|
|
3624
3619
|
}
|
|
3625
3620
|
}));
|
|
3626
3621
|
}
|
|
@@ -3649,23 +3644,55 @@ function joinTransaction(store, tl, txUpdateInProgress) {
|
|
|
3649
3644
|
unsubscribe();
|
|
3650
3645
|
tl.transactionKey = null;
|
|
3651
3646
|
if (tl.timeTraveling === null && currentTxInstanceId) {
|
|
3652
|
-
if (tl.at !== tl.history.length) tl.history.splice(tl.at);
|
|
3653
3647
|
const timelineTopics = store.timelineTopics.getRelatedKeys(tl.key);
|
|
3654
3648
|
const subEventsFiltered = filterTransactionSubEvents(transactionUpdate.subEvents, timelineTopics);
|
|
3655
3649
|
const timelineTransactionUpdate = {
|
|
3650
|
+
write: true,
|
|
3656
3651
|
...transactionUpdate,
|
|
3657
3652
|
subEvents: subEventsFiltered
|
|
3658
3653
|
};
|
|
3659
|
-
|
|
3660
|
-
if (willCapture) {
|
|
3661
|
-
tl.history.push(timelineTransactionUpdate);
|
|
3662
|
-
tl.at = tl.history.length;
|
|
3663
|
-
tl.subject.next(timelineTransactionUpdate);
|
|
3664
|
-
}
|
|
3654
|
+
addToHistory(tl, timelineTransactionUpdate);
|
|
3665
3655
|
}
|
|
3666
3656
|
});
|
|
3667
3657
|
}
|
|
3668
3658
|
}
|
|
3659
|
+
function buildSelectorUpdate(store, tl, atomToken, eventOrUpdate, currentSelectorToken, currentSelectorTime) {
|
|
3660
|
+
let latestUpdate = tl.history.at(-1);
|
|
3661
|
+
if (currentSelectorTime !== tl.selectorTime) {
|
|
3662
|
+
const selectorUpdate = latestUpdate = {
|
|
3663
|
+
write: true,
|
|
3664
|
+
type: `selector_update`,
|
|
3665
|
+
timestamp: currentSelectorTime,
|
|
3666
|
+
token: currentSelectorToken,
|
|
3667
|
+
subEvents: []
|
|
3668
|
+
};
|
|
3669
|
+
if (`type` in eventOrUpdate) latestUpdate.subEvents.push(eventOrUpdate);
|
|
3670
|
+
else latestUpdate.subEvents.push({
|
|
3671
|
+
type: `atom_update`,
|
|
3672
|
+
token: atomToken,
|
|
3673
|
+
update: eventOrUpdate,
|
|
3674
|
+
timestamp: Date.now()
|
|
3675
|
+
});
|
|
3676
|
+
addToHistory(tl, latestUpdate);
|
|
3677
|
+
tl.selectorTime = currentSelectorTime;
|
|
3678
|
+
store.logger.info(`β`, `timeline`, tl.key, `got a selector_update "${currentSelectorToken.key}" with`, latestUpdate.subEvents.map((event) => event.token.key));
|
|
3679
|
+
const operation = store.operation;
|
|
3680
|
+
const unsub = store.on.operationClose.subscribe(`timeline:${tl.key} (needs to gather nested selector creations)`, () => {
|
|
3681
|
+
unsub();
|
|
3682
|
+
if (operation.open) selectorUpdate.subEvents = [...operation.subEvents, ...selectorUpdate.subEvents];
|
|
3683
|
+
});
|
|
3684
|
+
} else if (latestUpdate?.type === `selector_update`) {
|
|
3685
|
+
if (`type` in eventOrUpdate) latestUpdate.subEvents.push(eventOrUpdate);
|
|
3686
|
+
else latestUpdate.subEvents.push({
|
|
3687
|
+
type: `atom_update`,
|
|
3688
|
+
token: atomToken,
|
|
3689
|
+
update: eventOrUpdate,
|
|
3690
|
+
timestamp: Date.now()
|
|
3691
|
+
});
|
|
3692
|
+
store.logger.info(`β`, `timeline`, tl.key, `set selector_update "${currentSelectorToken.key}" to`, latestUpdate?.subEvents.map((event) => event.token.key));
|
|
3693
|
+
}
|
|
3694
|
+
if (latestUpdate) tl.subject.next(latestUpdate);
|
|
3695
|
+
}
|
|
3669
3696
|
function filterTransactionSubEvents(updates, timelineTopics) {
|
|
3670
3697
|
return updates.filter((updateFromTx) => {
|
|
3671
3698
|
if (updateFromTx.type === `transaction_outcome`) return true;
|
|
@@ -3694,16 +3721,15 @@ function filterTransactionSubEvents(updates, timelineTopics) {
|
|
|
3694
3721
|
});
|
|
3695
3722
|
}
|
|
3696
3723
|
function handleStateLifecycleEvent(store, event, tl) {
|
|
3724
|
+
const currentSelectorToken = store.operation.open && store.operation.token.type === `writable_pure_selector` ? store.operation.token : null;
|
|
3725
|
+
const currentSelectorTime = store.operation.open && store.operation.token.type === `writable_pure_selector` ? store.operation.timestamp : null;
|
|
3697
3726
|
if (!tl.timeTraveling) {
|
|
3698
3727
|
const target = newest(store);
|
|
3699
3728
|
if (isChildStore(target)) {} else {
|
|
3700
3729
|
const txUpdateInProgress = target.on.transactionApplying.state;
|
|
3701
3730
|
if (txUpdateInProgress) joinTransaction(store, tl, txUpdateInProgress.update);
|
|
3702
|
-
else
|
|
3703
|
-
|
|
3704
|
-
tl.at = tl.history.length;
|
|
3705
|
-
tl.subject.next(event);
|
|
3706
|
-
}
|
|
3731
|
+
else if (currentSelectorToken && currentSelectorTime && event.type === `state_creation`) buildSelectorUpdate(store, tl, event.token, event, currentSelectorToken, currentSelectorTime);
|
|
3732
|
+
else addToHistory(tl, event);
|
|
3707
3733
|
}
|
|
3708
3734
|
}
|
|
3709
3735
|
switch (event.type) {
|
|
@@ -3716,6 +3742,12 @@ function handleStateLifecycleEvent(store, event, tl) {
|
|
|
3716
3742
|
break;
|
|
3717
3743
|
}
|
|
3718
3744
|
}
|
|
3745
|
+
function addToHistory(tl, event) {
|
|
3746
|
+
if (tl.at !== tl.history.length) tl.history.splice(tl.at);
|
|
3747
|
+
tl.history.push(event);
|
|
3748
|
+
tl.at = tl.history.length;
|
|
3749
|
+
tl.subject.next(event);
|
|
3750
|
+
}
|
|
3719
3751
|
|
|
3720
3752
|
//#endregion
|
|
3721
3753
|
//#region src/internal/timeline/time-travel.ts
|
|
@@ -3731,10 +3763,21 @@ const timeTravel = (store, action, token) => {
|
|
|
3731
3763
|
return;
|
|
3732
3764
|
}
|
|
3733
3765
|
timelineData.timeTraveling = action === `redo` ? `into_future` : `into_past`;
|
|
3734
|
-
|
|
3735
|
-
|
|
3766
|
+
let nextIndex = timelineData.at;
|
|
3767
|
+
let events;
|
|
3768
|
+
switch (action) {
|
|
3769
|
+
case `undo`:
|
|
3770
|
+
--nextIndex;
|
|
3771
|
+
while (nextIndex !== 0 && timelineData.history[nextIndex].write !== true) --nextIndex;
|
|
3772
|
+
events = timelineData.history.slice(nextIndex, timelineData.at).reverse();
|
|
3773
|
+
break;
|
|
3774
|
+
case `redo`:
|
|
3775
|
+
++nextIndex;
|
|
3776
|
+
events = timelineData.history.slice(timelineData.at, nextIndex);
|
|
3777
|
+
}
|
|
3778
|
+
timelineData.at = nextIndex;
|
|
3736
3779
|
const applying = action === `redo` ? `newValue` : `oldValue`;
|
|
3737
|
-
switch (event.type) {
|
|
3780
|
+
for (const event of events) switch (event.type) {
|
|
3738
3781
|
case `atom_update`:
|
|
3739
3782
|
ingestAtomUpdateEvent(store, event, applying);
|
|
3740
3783
|
break;
|
|
@@ -3753,10 +3796,9 @@ const timeTravel = (store, action, token) => {
|
|
|
3753
3796
|
case `molecule_creation`:
|
|
3754
3797
|
case `molecule_disposal`:
|
|
3755
3798
|
}
|
|
3756
|
-
if (action === `redo`) ++timelineData.at;
|
|
3757
3799
|
timelineData.subject.next(action);
|
|
3758
3800
|
timelineData.timeTraveling = null;
|
|
3759
|
-
store.logger.info(
|
|
3801
|
+
store.logger.info(`βΈοΈ`, `timeline`, token.key, `"${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`);
|
|
3760
3802
|
};
|
|
3761
3803
|
|
|
3762
3804
|
//#endregion
|