@legendapp/state 2.2.0-next.7 → 2.2.0-next.9
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/config/enableDirectAccess.d.ts +1 -1
- package/config/enableDirectPeek.d.ts +1 -1
- package/config/enableReactTracking.d.ts +4 -3
- package/config/enableReactTracking.js.map +1 -1
- package/config/enableReactTracking.mjs.map +1 -1
- package/config/enableReactUse.d.ts +1 -1
- package/helpers/fetch.d.ts +4 -3
- package/helpers/fetch.js.map +1 -1
- package/helpers/fetch.mjs.map +1 -1
- package/helpers/time.d.ts +2 -2
- package/history.js.map +1 -1
- package/history.mjs.map +1 -1
- package/index.d.ts +6 -1
- package/index.js +257 -207
- package/index.js.map +1 -1
- package/index.mjs +257 -208
- package/index.mjs.map +1 -1
- package/package.json +2 -10
- package/persist-plugins/firebase.js.map +1 -1
- package/persist-plugins/firebase.mjs.map +1 -1
- package/persist.d.ts +7 -5
- package/persist.js +132 -65
- package/persist.js.map +1 -1
- package/persist.mjs +133 -66
- package/persist.mjs.map +1 -1
- package/react-hooks/createObservableHook.js +1 -1
- package/react-hooks/createObservableHook.js.map +1 -1
- package/react-hooks/createObservableHook.mjs +1 -1
- package/react-hooks/createObservableHook.mjs.map +1 -1
- package/react-hooks/useFetch.d.ts +4 -3
- package/react-hooks/useFetch.js.map +1 -1
- package/react-hooks/useFetch.mjs.map +1 -1
- package/react-hooks/useObservableQuery.js.map +1 -1
- package/react-hooks/useObservableQuery.mjs.map +1 -1
- package/react.js +2 -0
- package/react.js.map +1 -1
- package/react.mjs +2 -0
- package/react.mjs.map +1 -1
- package/src/ObservableObject.d.ts +4 -3
- package/src/ObservablePrimitive.d.ts +2 -1
- package/src/activated.d.ts +3 -0
- package/src/computed.d.ts +1 -1
- package/src/config/enableDirectAccess.d.ts +1 -1
- package/src/config/enableDirectPeek.d.ts +1 -1
- package/src/config/enableReactTracking.d.ts +4 -3
- package/src/config/enableReactUse.d.ts +1 -1
- package/src/createObservable.d.ts +2 -2
- package/src/globals.d.ts +6 -3
- package/src/helpers/fetch.d.ts +4 -3
- package/src/helpers/time.d.ts +2 -2
- package/src/helpers.d.ts +3 -2
- package/src/history/trackHistory.d.ts +1 -1
- package/src/observable.d.ts +7 -12
- package/src/observableInterfaces.d.ts +30 -327
- package/src/observableTypes.d.ts +92 -0
- package/src/persistTypes.d.ts +224 -0
- package/src/proxy.d.ts +2 -1
- package/src/react/Computed.d.ts +1 -1
- package/src/react/reactInterfaces.d.ts +2 -1
- package/src/react/usePauseProvider.d.ts +3 -3
- package/src/react-hooks/useFetch.d.ts +4 -3
- package/src/trackSelector.d.ts +1 -1
package/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var types = require('@babel/types');
|
|
4
|
+
|
|
3
5
|
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
4
6
|
function isArray(obj) {
|
|
5
7
|
return Array.isArray(obj);
|
|
@@ -55,6 +57,7 @@ const symbolGetNode = Symbol('getNode');
|
|
|
55
57
|
const symbolDelete = /* @__PURE__ */ Symbol('delete');
|
|
56
58
|
const symbolOpaque = Symbol('opaque');
|
|
57
59
|
const optimized = Symbol('optimized');
|
|
60
|
+
const symbolActivated = Symbol('activated');
|
|
58
61
|
// TODOV3 Remove these
|
|
59
62
|
const extraPrimitiveActivators = new Map();
|
|
60
63
|
const extraPrimitiveProps = new Map();
|
|
@@ -158,8 +161,16 @@ function getChildNode(node, key, asFunction) {
|
|
|
158
161
|
if (asFunction) {
|
|
159
162
|
child = Object.assign(cloneFunction(asFunction), child);
|
|
160
163
|
}
|
|
161
|
-
else
|
|
162
|
-
|
|
164
|
+
else {
|
|
165
|
+
if (node.activationState) {
|
|
166
|
+
const { lookup } = node.activationState;
|
|
167
|
+
if (lookup) {
|
|
168
|
+
child = Object.assign(lookup.bind(node, key), child);
|
|
169
|
+
if (isFunction(child)) {
|
|
170
|
+
extractFunction(node, key, child);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
163
174
|
}
|
|
164
175
|
if (!node.children) {
|
|
165
176
|
node.children = new Map();
|
|
@@ -204,9 +215,11 @@ function findIDKey(obj, node) {
|
|
|
204
215
|
return idKey;
|
|
205
216
|
}
|
|
206
217
|
function extractFunction(node, key, fnOrComputed, computedChildNode) {
|
|
218
|
+
var _a;
|
|
207
219
|
if (!node.functions) {
|
|
208
220
|
node.functions = new Map();
|
|
209
221
|
}
|
|
222
|
+
(_a = node.children) === null || _a === void 0 ? void 0 : _a.delete(key);
|
|
210
223
|
node.functions.set(key, fnOrComputed);
|
|
211
224
|
if (computedChildNode) {
|
|
212
225
|
computedChildNode.parentOther = getChildNode(node, key);
|
|
@@ -217,6 +230,12 @@ function extractFunction(node, key, fnOrComputed, computedChildNode) {
|
|
|
217
230
|
}
|
|
218
231
|
}
|
|
219
232
|
|
|
233
|
+
function activated(params) {
|
|
234
|
+
return (() => ({
|
|
235
|
+
[symbolActivated]: params,
|
|
236
|
+
}));
|
|
237
|
+
}
|
|
238
|
+
|
|
220
239
|
let timeout;
|
|
221
240
|
let numInBatch = 0;
|
|
222
241
|
let isRunningBatch = false;
|
|
@@ -452,13 +471,37 @@ function endBatch(force) {
|
|
|
452
471
|
}
|
|
453
472
|
}
|
|
454
473
|
|
|
474
|
+
function createObservable(value, makePrimitive, extractPromise, createObject, createPrimitive) {
|
|
475
|
+
const valueIsPromise = isPromise(value);
|
|
476
|
+
const valueIsFunction = isFunction(value);
|
|
477
|
+
const root = {
|
|
478
|
+
_: value,
|
|
479
|
+
};
|
|
480
|
+
let node = {
|
|
481
|
+
root,
|
|
482
|
+
lazy: true,
|
|
483
|
+
};
|
|
484
|
+
if (valueIsFunction) {
|
|
485
|
+
node = Object.assign(cloneFunction(value), node);
|
|
486
|
+
}
|
|
487
|
+
const prim = makePrimitive || isActualPrimitive(value);
|
|
488
|
+
const obs = prim
|
|
489
|
+
? new createPrimitive(node)
|
|
490
|
+
: createObject(node);
|
|
491
|
+
if (valueIsPromise) {
|
|
492
|
+
setNodeValue(node, undefined);
|
|
493
|
+
extractPromise(node, value);
|
|
494
|
+
}
|
|
495
|
+
return obs;
|
|
496
|
+
}
|
|
497
|
+
|
|
455
498
|
function isEvent(obs) {
|
|
456
499
|
var _a;
|
|
457
500
|
return obs && ((_a = obs[symbolGetNode]) === null || _a === void 0 ? void 0 : _a.isEvent);
|
|
458
501
|
}
|
|
459
502
|
function computeSelector(selector, e, retainObservable) {
|
|
460
503
|
let c = selector;
|
|
461
|
-
if (isFunction(c)) {
|
|
504
|
+
if (!isObservable(c) && isFunction(c)) {
|
|
462
505
|
c = e ? c(e) : c();
|
|
463
506
|
}
|
|
464
507
|
return isObservable(c) && !retainObservable ? c.get() : c;
|
|
@@ -563,7 +606,9 @@ function _mergeIntoObservable(target, source) {
|
|
|
563
606
|
const key = keys[i];
|
|
564
607
|
const sourceValue = source[key];
|
|
565
608
|
if (sourceValue === symbolDelete) {
|
|
566
|
-
needsSet && ((_a = target[key]) === null || _a === void 0 ? void 0 : _a.delete)
|
|
609
|
+
needsSet && ((_a = target[key]) === null || _a === void 0 ? void 0 : _a.delete)
|
|
610
|
+
? target[key].delete()
|
|
611
|
+
: delete target[key];
|
|
567
612
|
}
|
|
568
613
|
else {
|
|
569
614
|
const isObj = isObject(sourceValue);
|
|
@@ -807,6 +852,40 @@ function observe(selectorOrRun, reactionOrOptions, options) {
|
|
|
807
852
|
};
|
|
808
853
|
}
|
|
809
854
|
|
|
855
|
+
function setupRetry(retryOptions, refresh, attemptNum) {
|
|
856
|
+
const timeout = {};
|
|
857
|
+
let didGiveUp = false;
|
|
858
|
+
const { backoff, delay = 1000, infinite, times = 3, maxDelay = 30000 } = retryOptions;
|
|
859
|
+
let handleError;
|
|
860
|
+
attemptNum.current++;
|
|
861
|
+
if (infinite || attemptNum.current < times) {
|
|
862
|
+
const delayTime = Math.min(delay * (backoff === 'constant' ? 1 : 2 ** attemptNum.current), maxDelay);
|
|
863
|
+
handleError = () => {
|
|
864
|
+
timeout.current = setTimeout(refresh, delayTime);
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
else {
|
|
868
|
+
handleError = () => {
|
|
869
|
+
didGiveUp = true;
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
if (typeof window !== 'undefined') {
|
|
873
|
+
window.addEventListener('online', () => {
|
|
874
|
+
if (didGiveUp || timeout) {
|
|
875
|
+
if (timeout) {
|
|
876
|
+
clearTimeout(timeout.current);
|
|
877
|
+
timeout.current = undefined;
|
|
878
|
+
}
|
|
879
|
+
// Restart the backoff when coming back online
|
|
880
|
+
attemptNum.current = 0;
|
|
881
|
+
didGiveUp = false;
|
|
882
|
+
refresh();
|
|
883
|
+
}
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
return { handleError, timeout };
|
|
887
|
+
}
|
|
888
|
+
|
|
810
889
|
function _when(predicate, effect, checkReady) {
|
|
811
890
|
// If predicate is a regular Promise skip all the observable stuff
|
|
812
891
|
if (isPromise(predicate)) {
|
|
@@ -861,64 +940,6 @@ function whenReady(predicate, effect) {
|
|
|
861
940
|
return _when(predicate, effect, true);
|
|
862
941
|
}
|
|
863
942
|
|
|
864
|
-
function createObservable(value, makePrimitive, extractPromise, createObject, createPrimitive) {
|
|
865
|
-
const valueIsPromise = isPromise(value);
|
|
866
|
-
const valueIsFunction = isFunction(value);
|
|
867
|
-
const root = {
|
|
868
|
-
_: value,
|
|
869
|
-
};
|
|
870
|
-
let node = {
|
|
871
|
-
root,
|
|
872
|
-
lazy: true,
|
|
873
|
-
};
|
|
874
|
-
if (valueIsFunction) {
|
|
875
|
-
node = Object.assign(cloneFunction(value), node);
|
|
876
|
-
}
|
|
877
|
-
const prim = makePrimitive || isActualPrimitive(value);
|
|
878
|
-
const obs = prim
|
|
879
|
-
? new createPrimitive(node)
|
|
880
|
-
: createObject(node);
|
|
881
|
-
if (valueIsPromise) {
|
|
882
|
-
setNodeValue(node, undefined);
|
|
883
|
-
extractPromise(node, value);
|
|
884
|
-
}
|
|
885
|
-
return obs;
|
|
886
|
-
}
|
|
887
|
-
|
|
888
|
-
function setupRetry(retryOptions, refresh, attemptNum) {
|
|
889
|
-
const timeout = {};
|
|
890
|
-
let didGiveUp = false;
|
|
891
|
-
const { backoff, delay = 1000, infinite, times = 3, maxDelay = 30000 } = retryOptions;
|
|
892
|
-
let handleError;
|
|
893
|
-
attemptNum.current++;
|
|
894
|
-
if (infinite || attemptNum.current < times) {
|
|
895
|
-
const delayTime = Math.min(delay * (backoff === 'constant' ? 1 : 2 ** attemptNum.current), maxDelay);
|
|
896
|
-
handleError = () => {
|
|
897
|
-
timeout.current = setTimeout(refresh, delayTime);
|
|
898
|
-
};
|
|
899
|
-
}
|
|
900
|
-
else {
|
|
901
|
-
handleError = () => {
|
|
902
|
-
didGiveUp = true;
|
|
903
|
-
};
|
|
904
|
-
}
|
|
905
|
-
if (typeof window !== 'undefined') {
|
|
906
|
-
window.addEventListener('online', () => {
|
|
907
|
-
if (didGiveUp || timeout) {
|
|
908
|
-
if (timeout) {
|
|
909
|
-
clearTimeout(timeout.current);
|
|
910
|
-
timeout.current = undefined;
|
|
911
|
-
}
|
|
912
|
-
// Restart the backoff when coming back online
|
|
913
|
-
attemptNum.current = 0;
|
|
914
|
-
didGiveUp = false;
|
|
915
|
-
refresh();
|
|
916
|
-
}
|
|
917
|
-
});
|
|
918
|
-
}
|
|
919
|
-
return { handleError, timeout };
|
|
920
|
-
}
|
|
921
|
-
|
|
922
943
|
const ArrayModifiers = new Set([
|
|
923
944
|
'copyWithin',
|
|
924
945
|
'fill',
|
|
@@ -1396,12 +1417,14 @@ function setKey(node, key, newValue, level) {
|
|
|
1396
1417
|
console.warn(`[legend-state] Set an HTMLElement into state. You probably don't want to do that.`);
|
|
1397
1418
|
}
|
|
1398
1419
|
}
|
|
1420
|
+
const isRoot = !node.parent && key === '_';
|
|
1421
|
+
// TODOv3 root locking will be removed with old computeds
|
|
1399
1422
|
if (node.root.locked && !node.root.set) {
|
|
1400
1423
|
// This happens when modifying a locked observable such as a computed.
|
|
1401
1424
|
// If merging this could be happening deep in a hierarchy so we don't want to throw errors so we'll just do nothing.
|
|
1402
1425
|
// This could happen during persistence local load for example.
|
|
1403
1426
|
if (globalState.isMerging) {
|
|
1404
|
-
return;
|
|
1427
|
+
return isRoot ? getProxy(node) : getProxy(node, key);
|
|
1405
1428
|
}
|
|
1406
1429
|
else {
|
|
1407
1430
|
throw new Error(process.env.NODE_ENV === 'development'
|
|
@@ -1409,7 +1432,9 @@ function setKey(node, key, newValue, level) {
|
|
|
1409
1432
|
: '[legend-state] Modified locked observable');
|
|
1410
1433
|
}
|
|
1411
1434
|
}
|
|
1412
|
-
|
|
1435
|
+
if (node.parent && !getNodeValue(node)) {
|
|
1436
|
+
return set(node, { [key]: newValue });
|
|
1437
|
+
}
|
|
1413
1438
|
// Get the child node for updating and notifying
|
|
1414
1439
|
const childNode = isRoot ? node : getChildNode(node, key, isFunction(newValue) ? newValue : undefined);
|
|
1415
1440
|
// Set the raw value on the parent object
|
|
@@ -1595,19 +1620,17 @@ function get(node, options) {
|
|
|
1595
1620
|
return peek(node);
|
|
1596
1621
|
}
|
|
1597
1622
|
function peek(node) {
|
|
1598
|
-
|
|
1623
|
+
let value = getNodeValue(node);
|
|
1599
1624
|
// If node is not yet lazily computed go do that
|
|
1600
1625
|
const lazy = node.lazy;
|
|
1601
1626
|
if (lazy) {
|
|
1602
1627
|
delete node.lazy;
|
|
1603
1628
|
if (isFunction(node) || isFunction(lazy)) {
|
|
1604
|
-
activateNodeFunction(node, lazy);
|
|
1629
|
+
value = activateNodeFunction(node, lazy);
|
|
1605
1630
|
}
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
extractFunctionOrComputed(node, value, key, value[key]);
|
|
1610
|
-
}
|
|
1631
|
+
for (const key in value) {
|
|
1632
|
+
if (hasOwnProperty.call(value, key)) {
|
|
1633
|
+
extractFunctionOrComputed(node, value, key, value[key]);
|
|
1611
1634
|
}
|
|
1612
1635
|
}
|
|
1613
1636
|
}
|
|
@@ -1615,138 +1638,112 @@ function peek(node) {
|
|
|
1615
1638
|
checkActivate(node);
|
|
1616
1639
|
return value;
|
|
1617
1640
|
}
|
|
1618
|
-
function createNodeActivationParams(node) {
|
|
1619
|
-
node.activationState = {
|
|
1620
|
-
lastSync: {},
|
|
1621
|
-
};
|
|
1622
|
-
const state = node.activationState;
|
|
1623
|
-
// The onSet function handles the observable being set
|
|
1624
|
-
// and forwards the set elsewhere
|
|
1625
|
-
const onSet = (onSetFnParam) => {
|
|
1626
|
-
state.onSetFn = onSetFnParam;
|
|
1627
|
-
};
|
|
1628
|
-
// The onSet function handles the observable being set
|
|
1629
|
-
// and forwards the set elsewhere
|
|
1630
|
-
const updateLastSync = (fn) => {
|
|
1631
|
-
state.lastSync.value = fn;
|
|
1632
|
-
};
|
|
1633
|
-
// The subscribe function runs a function that listens to
|
|
1634
|
-
// a data source and sends updates into the observable
|
|
1635
|
-
const subscribe = (fn) => {
|
|
1636
|
-
if (!state.subscriber) {
|
|
1637
|
-
state.subscriber = fn;
|
|
1638
|
-
}
|
|
1639
|
-
};
|
|
1640
|
-
const cache = (fn) => {
|
|
1641
|
-
if (!state.cacheOptions) {
|
|
1642
|
-
state.cacheOptions = isFunction(fn) ? fn() : fn;
|
|
1643
|
-
}
|
|
1644
|
-
return new Promise((resolve) => {
|
|
1645
|
-
const wait = () => {
|
|
1646
|
-
if (node.state) {
|
|
1647
|
-
when(node.state.isLoadedLocal, () => {
|
|
1648
|
-
const dateModified = node.state.dateModified.get();
|
|
1649
|
-
resolve({ dateModified, value: peek(node) });
|
|
1650
|
-
});
|
|
1651
|
-
}
|
|
1652
|
-
else {
|
|
1653
|
-
queueMicrotask(wait);
|
|
1654
|
-
}
|
|
1655
|
-
};
|
|
1656
|
-
wait();
|
|
1657
|
-
});
|
|
1658
|
-
};
|
|
1659
|
-
const retry = (params) => {
|
|
1660
|
-
if (!state.retryOptions) {
|
|
1661
|
-
state.retryOptions = params || {};
|
|
1662
|
-
}
|
|
1663
|
-
};
|
|
1664
|
-
// The proxy function simply marks the node as a proxy with this function
|
|
1665
|
-
// so that child nodes will be created with this function, and then simply
|
|
1666
|
-
// activated as a function
|
|
1667
|
-
const proxy = (fn) => {
|
|
1668
|
-
node.proxyFn2 = fn;
|
|
1669
|
-
};
|
|
1670
|
-
return {
|
|
1671
|
-
onSet,
|
|
1672
|
-
proxy,
|
|
1673
|
-
cache,
|
|
1674
|
-
retry,
|
|
1675
|
-
subscribe,
|
|
1676
|
-
updateLastSync,
|
|
1677
|
-
obs$: getProxy(node),
|
|
1678
|
-
};
|
|
1679
|
-
}
|
|
1680
1641
|
function activateNodeFunction(node, lazyFn) {
|
|
1681
|
-
let prevTarget
|
|
1682
|
-
let curTarget
|
|
1642
|
+
// let prevTarget$: Observable<any>;
|
|
1643
|
+
// let curTarget$: Observable<any>;
|
|
1683
1644
|
let update;
|
|
1684
1645
|
let wasPromise;
|
|
1685
1646
|
let timeoutRetry;
|
|
1686
1647
|
const attemptNum = { current: 0 };
|
|
1687
|
-
const
|
|
1688
|
-
const refresh = () => node.state.refreshNum.set((v) => v + 1);
|
|
1648
|
+
const activateFn = (isFunction(node) ? node : lazyFn);
|
|
1649
|
+
const refresh = () => { var _a; return (_a = node.state) === null || _a === void 0 ? void 0 : _a.refreshNum.set((v) => v + 1); };
|
|
1650
|
+
let activatedValue;
|
|
1689
1651
|
observe(() => {
|
|
1690
|
-
|
|
1652
|
+
var _a, _b, _c, _d;
|
|
1653
|
+
// const params = createNodeActivationParams(node);
|
|
1691
1654
|
// Run the function at this node
|
|
1692
|
-
let value =
|
|
1693
|
-
// If target is an observable,
|
|
1694
|
-
// and set up an onSet to write changes back to it
|
|
1655
|
+
let value = activateFn();
|
|
1656
|
+
// If target is an observable, make this node a link to it
|
|
1695
1657
|
if (isObservable(value)) {
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1658
|
+
// If the computed is a proxy to another observable
|
|
1659
|
+
// link it to the target observable
|
|
1660
|
+
const linkedNode = getNode(value);
|
|
1661
|
+
const prevNode = node.linkedToNode;
|
|
1662
|
+
node.linkedToNode = linkedNode;
|
|
1663
|
+
if (!linkedNode.linkedFromNodes) {
|
|
1664
|
+
linkedNode.linkedFromNodes = new Set();
|
|
1665
|
+
}
|
|
1666
|
+
linkedNode.linkedFromNodes.add(node);
|
|
1667
|
+
onChange(linkedNode, ({ value: newValue }) => {
|
|
1668
|
+
value = newValue;
|
|
1669
|
+
set(node, value);
|
|
1670
|
+
}, { initial: true });
|
|
1671
|
+
// If the target observable is different then notify for the change
|
|
1672
|
+
if (prevNode) {
|
|
1673
|
+
const value = getNodeValue(linkedNode);
|
|
1674
|
+
const prevValue = getNodeValue(prevNode);
|
|
1675
|
+
notify(node, value, prevValue, 0);
|
|
1676
|
+
}
|
|
1714
1677
|
}
|
|
1715
|
-
|
|
1716
|
-
|
|
1678
|
+
if (isFunction(value)) {
|
|
1679
|
+
value = value();
|
|
1680
|
+
}
|
|
1681
|
+
const activated = value === null || value === void 0 ? void 0 : value[symbolActivated];
|
|
1682
|
+
if (activated) {
|
|
1683
|
+
node.activationState = activated;
|
|
1684
|
+
value = activated.initial;
|
|
1717
1685
|
}
|
|
1686
|
+
wasPromise = isPromise(value);
|
|
1718
1687
|
// Activate this node if not activated already (may be called recursively)
|
|
1719
1688
|
// TODO: Is calling recursively bad? If so can it be fixed?
|
|
1720
1689
|
if (!node.activated) {
|
|
1721
1690
|
node.activated = true;
|
|
1691
|
+
const isCached = !!((_a = node.activationState) === null || _a === void 0 ? void 0 : _a.cache);
|
|
1692
|
+
wasPromise = wasPromise || !!isCached;
|
|
1722
1693
|
const activateNodeFn = wasPromise ? globalState.activateNode : activateNodeBase;
|
|
1723
|
-
update = activateNodeFn(node, refresh, !!wasPromise, value)
|
|
1694
|
+
const { update: newUpdate, value: newValue } = activateNodeFn(node, refresh, !!wasPromise, value);
|
|
1695
|
+
update = newUpdate;
|
|
1696
|
+
value = newValue;
|
|
1697
|
+
}
|
|
1698
|
+
else if (node.activationState) {
|
|
1699
|
+
if (!node.activationState.persistedRetry) {
|
|
1700
|
+
const activated = node.activationState;
|
|
1701
|
+
value = (_c = (_b = activated.get) === null || _b === void 0 ? void 0 : _b.call(activated, {})) !== null && _c !== void 0 ? _c : activated.initial;
|
|
1702
|
+
}
|
|
1724
1703
|
}
|
|
1725
|
-
|
|
1704
|
+
wasPromise = wasPromise || isPromise(value);
|
|
1705
|
+
(_d = node.state) === null || _d === void 0 ? void 0 : _d.refreshNum.get();
|
|
1726
1706
|
return value;
|
|
1727
1707
|
}, ({ value }) => {
|
|
1728
1708
|
if (!globalState.isLoadingRemote$.peek()) {
|
|
1729
1709
|
if (wasPromise) {
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
if (
|
|
1734
|
-
|
|
1710
|
+
if (node.activationState) {
|
|
1711
|
+
const { retry, initial } = node.activationState;
|
|
1712
|
+
let onError;
|
|
1713
|
+
if (retry) {
|
|
1714
|
+
if (timeoutRetry === null || timeoutRetry === void 0 ? void 0 : timeoutRetry.current) {
|
|
1715
|
+
clearTimeout(timeoutRetry.current);
|
|
1716
|
+
}
|
|
1717
|
+
const { handleError, timeout } = setupRetry(retry, refresh, attemptNum);
|
|
1718
|
+
onError = handleError;
|
|
1719
|
+
timeoutRetry = timeout;
|
|
1720
|
+
node.activationState.onError = onError;
|
|
1721
|
+
}
|
|
1722
|
+
if (value && isPromise(value)) {
|
|
1723
|
+
// Extract the promise to make it set the value/error when it comes in
|
|
1724
|
+
extractPromise(node, value, update, onError);
|
|
1725
|
+
}
|
|
1726
|
+
// Set this to undefined only if it's replacing the activation function,
|
|
1727
|
+
// so we don't overwrite it if it already has real data from either local
|
|
1728
|
+
// cache or a previous run
|
|
1729
|
+
if (isFunction(getNodeValue(node))) {
|
|
1730
|
+
setNodeValue(node, initial !== null && initial !== void 0 ? initial : undefined);
|
|
1735
1731
|
}
|
|
1736
|
-
const { handleError, timeout } = setupRetry(retryOptions, refresh, attemptNum);
|
|
1737
|
-
onError = handleError;
|
|
1738
|
-
timeoutRetry = timeout;
|
|
1739
1732
|
}
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1733
|
+
else if (node.activated) {
|
|
1734
|
+
let onError;
|
|
1735
|
+
// Extract the promise to make it set the value/error when it comes in
|
|
1736
|
+
extractPromise(node, value, update, onError);
|
|
1737
|
+
// Set this to undefined only if it's replacing the activation function,
|
|
1738
|
+
// so we don't overwrite it if it already has real data from either local
|
|
1739
|
+
// cache or a previous run
|
|
1740
|
+
if (isFunction(getNodeValue(node))) {
|
|
1741
|
+
setNodeValue(node, undefined);
|
|
1742
|
+
}
|
|
1747
1743
|
}
|
|
1748
1744
|
}
|
|
1749
1745
|
else {
|
|
1746
|
+
activatedValue = value;
|
|
1750
1747
|
set(node, value);
|
|
1751
1748
|
node.state.assign({
|
|
1752
1749
|
isLoaded: true,
|
|
@@ -1755,49 +1752,100 @@ function activateNodeFunction(node, lazyFn) {
|
|
|
1755
1752
|
}
|
|
1756
1753
|
}
|
|
1757
1754
|
}, { immediate: true, fromComputed: true });
|
|
1755
|
+
return activatedValue;
|
|
1758
1756
|
}
|
|
1759
|
-
const activateNodeBase = (globalState.activateNode = function activateNodeBase(node, refresh, wasPromise) {
|
|
1760
|
-
const { onSetFn, subscriber } = node.activationState;
|
|
1761
|
-
let isSetting = false;
|
|
1757
|
+
const activateNodeBase = (globalState.activateNode = function activateNodeBase(node, refresh, wasPromise, value) {
|
|
1762
1758
|
if (!node.state) {
|
|
1763
1759
|
node.state = createObservable({
|
|
1764
1760
|
isLoaded: false,
|
|
1765
1761
|
}, false, extractPromise, getProxy);
|
|
1766
1762
|
}
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1763
|
+
let isSetting = false;
|
|
1764
|
+
let isSettingFromSubscribe = false;
|
|
1765
|
+
let _mode = 'set';
|
|
1766
|
+
if (node.activationState) {
|
|
1767
|
+
const { onSet, subscribe, get, initial, retry, waitFor } = node.activationState;
|
|
1768
|
+
// @ts-expect-error asdf
|
|
1769
|
+
const run = () => get({ updateLastSync: types.noop, setMode: (mode) => (_mode = mode) });
|
|
1770
|
+
value = get
|
|
1771
|
+
? waitFor
|
|
1772
|
+
? new Promise((resolve) => {
|
|
1773
|
+
whenReady(waitFor, () => {
|
|
1774
|
+
resolve(run());
|
|
1776
1775
|
});
|
|
1776
|
+
})
|
|
1777
|
+
: run()
|
|
1778
|
+
: undefined;
|
|
1779
|
+
if (value == undefined || value === null) {
|
|
1780
|
+
value = initial;
|
|
1781
|
+
}
|
|
1782
|
+
let timeoutRetry;
|
|
1783
|
+
if (onSet) {
|
|
1784
|
+
const doSet = (params) => {
|
|
1785
|
+
// Don't call the set if this is the first value coming in
|
|
1786
|
+
if (!isSetting || isSettingFromSubscribe) {
|
|
1787
|
+
if (node.state.isLoaded.get() &&
|
|
1788
|
+
(params.changes.length > 1 || !isFunction(params.changes[0].prevAtPath))) {
|
|
1789
|
+
const attemptNum = { current: 0 };
|
|
1790
|
+
const run = () => {
|
|
1791
|
+
let onError;
|
|
1792
|
+
if (retry) {
|
|
1793
|
+
if (timeoutRetry === null || timeoutRetry === void 0 ? void 0 : timeoutRetry.current) {
|
|
1794
|
+
clearTimeout(timeoutRetry.current);
|
|
1795
|
+
}
|
|
1796
|
+
const { handleError, timeout } = setupRetry(retry, run, attemptNum);
|
|
1797
|
+
onError = handleError;
|
|
1798
|
+
timeoutRetry = timeout;
|
|
1799
|
+
}
|
|
1800
|
+
isSetting = true;
|
|
1801
|
+
batch(() => onSet(params, {
|
|
1802
|
+
node,
|
|
1803
|
+
update,
|
|
1804
|
+
refresh,
|
|
1805
|
+
onError,
|
|
1806
|
+
fromSubscribe: isSettingFromSubscribe,
|
|
1807
|
+
}), () => {
|
|
1808
|
+
isSetting = false;
|
|
1809
|
+
});
|
|
1810
|
+
};
|
|
1811
|
+
run();
|
|
1812
|
+
}
|
|
1777
1813
|
}
|
|
1778
|
-
}
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1814
|
+
};
|
|
1815
|
+
onChange(node, doSet, wasPromise ? undefined : { immediate: true });
|
|
1816
|
+
}
|
|
1817
|
+
if (process.env.NODE_ENV === 'development' && node.activationState.cache) {
|
|
1818
|
+
// TODO Better message
|
|
1819
|
+
console.log('[legend-state] Using cache without setting up persistence first');
|
|
1820
|
+
}
|
|
1821
|
+
if (process.env.NODE_ENV === 'development' && node.activationState.retry) {
|
|
1822
|
+
// TODO Better message
|
|
1823
|
+
console.log('[legend-state] Using retry without setting up persistence first');
|
|
1824
|
+
}
|
|
1825
|
+
if (subscribe) {
|
|
1826
|
+
const updateFromSubscribe = (params) => {
|
|
1827
|
+
isSettingFromSubscribe = true;
|
|
1828
|
+
update(params);
|
|
1829
|
+
isSettingFromSubscribe = false;
|
|
1830
|
+
};
|
|
1831
|
+
subscribe({ node, update: updateFromSubscribe, refresh });
|
|
1832
|
+
}
|
|
1789
1833
|
}
|
|
1790
|
-
const update = ({ value }) => {
|
|
1834
|
+
const update = ({ value, mode }) => {
|
|
1791
1835
|
// TODO: This isSetting might not be necessary? Tests still work if removing it.
|
|
1792
1836
|
// Write tests that would break it if removed? I'd guess a combination of subscribe and
|
|
1793
1837
|
if (!isSetting) {
|
|
1794
|
-
|
|
1838
|
+
isSetting = true;
|
|
1839
|
+
if (_mode === 'assign' || mode === 'assign') {
|
|
1840
|
+
assign(node, value);
|
|
1841
|
+
}
|
|
1842
|
+
else {
|
|
1843
|
+
set(node, value);
|
|
1844
|
+
}
|
|
1845
|
+
isSetting = false;
|
|
1795
1846
|
}
|
|
1796
1847
|
};
|
|
1797
|
-
|
|
1798
|
-
subscriber({ update, refresh });
|
|
1799
|
-
}
|
|
1800
|
-
return { update };
|
|
1848
|
+
return { update, value };
|
|
1801
1849
|
});
|
|
1802
1850
|
|
|
1803
1851
|
const fns = ['get', 'set', 'peek', 'onChange', 'toggle'];
|
|
@@ -2025,10 +2073,12 @@ const internal = {
|
|
|
2025
2073
|
setAtPath,
|
|
2026
2074
|
setNodeValue,
|
|
2027
2075
|
setupRetry,
|
|
2076
|
+
symbolActivated,
|
|
2028
2077
|
symbolDelete,
|
|
2029
2078
|
};
|
|
2030
2079
|
|
|
2031
2080
|
exports.ObservablePrimitiveClass = ObservablePrimitiveClass;
|
|
2081
|
+
exports.activated = activated;
|
|
2032
2082
|
exports.batch = batch;
|
|
2033
2083
|
exports.beginBatch = beginBatch;
|
|
2034
2084
|
exports.beginTracking = beginTracking;
|