@legendapp/state 2.2.0-next.19 → 2.2.0-next.20
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/index.d.ts +5 -5
- package/index.js +109 -114
- package/index.js.map +1 -1
- package/index.mjs +109 -114
- package/index.mjs.map +1 -1
- package/package.json +1 -1
- package/persist-plugins/local-storage.js +1 -1
- package/persist-plugins/local-storage.js.map +1 -1
- package/persist-plugins/local-storage.mjs +1 -1
- package/persist-plugins/local-storage.mjs.map +1 -1
- package/persist.js +38 -94
- package/persist.js.map +1 -1
- package/persist.mjs +39 -95
- package/persist.mjs.map +1 -1
- package/src/ObservableObject.d.ts +1 -1
- package/src/retry.d.ts +4 -9
package/index.d.ts
CHANGED
|
@@ -3,21 +3,21 @@ export { batch, beginBatch, endBatch } from './src/batching';
|
|
|
3
3
|
export { computed } from './src/computed';
|
|
4
4
|
export { configureLegendState } from './src/config';
|
|
5
5
|
export { event } from './src/event';
|
|
6
|
-
export { computeSelector, constructObjectWithPath, deconstructObjectWithPath, getObservableIndex, isObservableValueReady, lockObservable, mergeIntoObservable, opaqueObject, setAtPath, setInObservableAtPath, setSilently, } from './src/helpers';
|
|
7
6
|
export { isObservable } from './src/globals';
|
|
7
|
+
export { computeSelector, constructObjectWithPath, deconstructObjectWithPath, getObservableIndex, isObservableValueReady, lockObservable, mergeIntoObservable, opaqueObject, setAtPath, setInObservableAtPath, setSilently, } from './src/helpers';
|
|
8
8
|
export { hasOwnProperty, isArray, isBoolean, isEmpty, isFunction, isObject, isPrimitive, isPromise, isString, isSymbol, } from './src/is';
|
|
9
9
|
export { observable, observablePrimitive, syncState } from './src/observable';
|
|
10
10
|
export * from './src/observableInterfaces';
|
|
11
|
-
export * from './src/
|
|
11
|
+
export * from './src/observableTypes';
|
|
12
12
|
export { observe } from './src/observe';
|
|
13
|
+
export * from './src/persistTypes';
|
|
13
14
|
export { proxy } from './src/proxy';
|
|
14
15
|
export { trackSelector } from './src/trackSelector';
|
|
15
16
|
export { when, whenReady } from './src/when';
|
|
16
|
-
export * from './src/observableTypes';
|
|
17
17
|
import { get, getProxy, peek, set } from './src/ObservableObject';
|
|
18
18
|
import { ensureNodeValue, findIDKey, getNode, setNodeValue } from './src/globals';
|
|
19
19
|
import { setAtPath } from './src/helpers';
|
|
20
|
-
import {
|
|
20
|
+
import { runWithRetry } from './src/retry';
|
|
21
21
|
export declare const internal: {
|
|
22
22
|
ensureNodeValue: typeof ensureNodeValue;
|
|
23
23
|
findIDKey: typeof findIDKey;
|
|
@@ -38,10 +38,10 @@ export declare const internal: {
|
|
|
38
38
|
observableFns: Map<string, (node: import("./src/observableInterfaces").NodeValue, ...args: any[]) => any>;
|
|
39
39
|
optimized: symbol;
|
|
40
40
|
peek: typeof peek;
|
|
41
|
+
runWithRetry: typeof runWithRetry;
|
|
41
42
|
set: typeof set;
|
|
42
43
|
setAtPath: typeof setAtPath;
|
|
43
44
|
setNodeValue: typeof setNodeValue;
|
|
44
|
-
setupRetry: typeof setupRetry;
|
|
45
45
|
symbolActivated: symbol;
|
|
46
46
|
symbolDelete: symbol;
|
|
47
47
|
};
|
package/index.js
CHANGED
|
@@ -483,6 +483,30 @@ function endBatch(force) {
|
|
|
483
483
|
}
|
|
484
484
|
}
|
|
485
485
|
|
|
486
|
+
function createObservable(value, makePrimitive, extractPromise, createObject, createPrimitive) {
|
|
487
|
+
const valueIsPromise = isPromise(value);
|
|
488
|
+
const valueIsFunction = isFunction(value);
|
|
489
|
+
const root = {
|
|
490
|
+
_: value,
|
|
491
|
+
};
|
|
492
|
+
let node = {
|
|
493
|
+
root,
|
|
494
|
+
lazy: true,
|
|
495
|
+
};
|
|
496
|
+
if (valueIsFunction) {
|
|
497
|
+
node = Object.assign(cloneFunction(value), node);
|
|
498
|
+
}
|
|
499
|
+
const prim = makePrimitive || isActualPrimitive(value);
|
|
500
|
+
const obs = prim
|
|
501
|
+
? new createPrimitive(node)
|
|
502
|
+
: createObject(node);
|
|
503
|
+
if (valueIsPromise) {
|
|
504
|
+
setNodeValue(node, undefined);
|
|
505
|
+
extractPromise(node, value);
|
|
506
|
+
}
|
|
507
|
+
return obs;
|
|
508
|
+
}
|
|
509
|
+
|
|
486
510
|
function isEvent(obs) {
|
|
487
511
|
var _a;
|
|
488
512
|
return obs && ((_a = obs[symbolGetNode]) === null || _a === void 0 ? void 0 : _a.isEvent);
|
|
@@ -654,30 +678,6 @@ function setSilently(obs, newValue) {
|
|
|
654
678
|
return setNodeValue(node, newValue).newValue;
|
|
655
679
|
}
|
|
656
680
|
|
|
657
|
-
function createObservable(value, makePrimitive, extractPromise, createObject, createPrimitive) {
|
|
658
|
-
const valueIsPromise = isPromise(value);
|
|
659
|
-
const valueIsFunction = isFunction(value);
|
|
660
|
-
const root = {
|
|
661
|
-
_: value,
|
|
662
|
-
};
|
|
663
|
-
let node = {
|
|
664
|
-
root,
|
|
665
|
-
lazy: true,
|
|
666
|
-
};
|
|
667
|
-
if (valueIsFunction) {
|
|
668
|
-
node = Object.assign(cloneFunction(value), node);
|
|
669
|
-
}
|
|
670
|
-
const prim = makePrimitive || isActualPrimitive(value);
|
|
671
|
-
const obs = prim
|
|
672
|
-
? new createPrimitive(node)
|
|
673
|
-
: createObject(node);
|
|
674
|
-
if (valueIsPromise) {
|
|
675
|
-
setNodeValue(node, undefined);
|
|
676
|
-
extractPromise(node, value);
|
|
677
|
-
}
|
|
678
|
-
return obs;
|
|
679
|
-
}
|
|
680
|
-
|
|
681
681
|
function onChange(node, callback, options = {}) {
|
|
682
682
|
const { initial, immediate, noArgs } = options;
|
|
683
683
|
const { trackingType } = options;
|
|
@@ -868,41 +868,6 @@ function observe(selectorOrRun, reactionOrOptions, options) {
|
|
|
868
868
|
};
|
|
869
869
|
}
|
|
870
870
|
|
|
871
|
-
function setupRetry(retryOptions, refresh, attemptNum) {
|
|
872
|
-
const timeout = {};
|
|
873
|
-
// let didGiveUp = false;
|
|
874
|
-
const { backoff, delay = 1000, infinite, times = 3, maxDelay = 30000 } = retryOptions;
|
|
875
|
-
let handleError;
|
|
876
|
-
attemptNum.current++;
|
|
877
|
-
if (infinite || attemptNum.current < times) {
|
|
878
|
-
const delayTime = Math.min(delay * (backoff === 'constant' ? 1 : 2 ** attemptNum.current), maxDelay);
|
|
879
|
-
handleError = () => {
|
|
880
|
-
timeout.current = setTimeout(refresh, delayTime);
|
|
881
|
-
};
|
|
882
|
-
}
|
|
883
|
-
else {
|
|
884
|
-
handleError = () => {
|
|
885
|
-
// didGiveUp = true;
|
|
886
|
-
};
|
|
887
|
-
}
|
|
888
|
-
// TODO: Make an easy way to opt into this if
|
|
889
|
-
// if (typeof window !== 'undefined') {
|
|
890
|
-
// window.addEventListener('online', () => {
|
|
891
|
-
// if (didGiveUp || timeout) {
|
|
892
|
-
// if (timeout) {
|
|
893
|
-
// clearTimeout(timeout.current);
|
|
894
|
-
// timeout.current = undefined;
|
|
895
|
-
// }
|
|
896
|
-
// // Restart the backoff when coming back online
|
|
897
|
-
// attemptNum.current = 0;
|
|
898
|
-
// didGiveUp = false;
|
|
899
|
-
// refresh();
|
|
900
|
-
// }
|
|
901
|
-
// });
|
|
902
|
-
// }
|
|
903
|
-
return { handleError, timeout };
|
|
904
|
-
}
|
|
905
|
-
|
|
906
871
|
function _when(predicate, effect, checkReady) {
|
|
907
872
|
// If predicate is a regular Promise skip all the observable stuff
|
|
908
873
|
if (isPromise(predicate)) {
|
|
@@ -958,6 +923,59 @@ function whenReady(predicate, effect) {
|
|
|
958
923
|
return _when(predicate, effect, true);
|
|
959
924
|
}
|
|
960
925
|
|
|
926
|
+
function calculateRetryDelay(retryOptions, attemptNum) {
|
|
927
|
+
const { backoff, delay = 1000, infinite, times = 3, maxDelay = 30000 } = retryOptions;
|
|
928
|
+
if (infinite || attemptNum < times) {
|
|
929
|
+
const delayTime = Math.min(delay * (backoff === 'constant' ? 1 : 2 ** attemptNum), maxDelay);
|
|
930
|
+
return delayTime;
|
|
931
|
+
}
|
|
932
|
+
return null;
|
|
933
|
+
}
|
|
934
|
+
function createRetryTimout(retryOptions, attemptNum, fn) {
|
|
935
|
+
const delayTime = calculateRetryDelay(retryOptions, attemptNum);
|
|
936
|
+
if (delayTime) {
|
|
937
|
+
return setTimeout(fn, delayTime);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
function runWithRetry(node, state, fn) {
|
|
941
|
+
const { retry, waitFor } = node.activationState;
|
|
942
|
+
let value = undefined;
|
|
943
|
+
if (waitFor) {
|
|
944
|
+
value = whenReady(waitFor, () => {
|
|
945
|
+
node.activationState.waitFor = undefined;
|
|
946
|
+
return fn();
|
|
947
|
+
});
|
|
948
|
+
}
|
|
949
|
+
else {
|
|
950
|
+
value = fn();
|
|
951
|
+
}
|
|
952
|
+
if (isPromise(value) && retry) {
|
|
953
|
+
let timeoutRetry;
|
|
954
|
+
return new Promise((resolve) => {
|
|
955
|
+
const run = () => {
|
|
956
|
+
value
|
|
957
|
+
.then((val) => {
|
|
958
|
+
node.activationState.persistedRetry = false;
|
|
959
|
+
resolve(val);
|
|
960
|
+
})
|
|
961
|
+
.catch(() => {
|
|
962
|
+
node.activationState.persistedRetry = true;
|
|
963
|
+
state.attemptNum++;
|
|
964
|
+
if (timeoutRetry) {
|
|
965
|
+
clearTimeout(timeoutRetry);
|
|
966
|
+
}
|
|
967
|
+
timeoutRetry = createRetryTimout(retry, state.attemptNum, () => {
|
|
968
|
+
value = fn();
|
|
969
|
+
run();
|
|
970
|
+
});
|
|
971
|
+
});
|
|
972
|
+
};
|
|
973
|
+
run();
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
return value;
|
|
977
|
+
}
|
|
978
|
+
|
|
961
979
|
const noop = () => { };
|
|
962
980
|
const ArrayModifiers = new Set([
|
|
963
981
|
'copyWithin',
|
|
@@ -1610,7 +1628,7 @@ function updateNodesAndNotify(node, newValue, prevValue, childNode, isPrim, isRo
|
|
|
1610
1628
|
}
|
|
1611
1629
|
endBatch();
|
|
1612
1630
|
}
|
|
1613
|
-
function extractPromise(node, value, setter
|
|
1631
|
+
function extractPromise(node, value, setter) {
|
|
1614
1632
|
if (!node.state) {
|
|
1615
1633
|
node.state = createObservable({
|
|
1616
1634
|
isLoaded: false,
|
|
@@ -1626,9 +1644,6 @@ function extractPromise(node, value, setter, handleError) {
|
|
|
1626
1644
|
})
|
|
1627
1645
|
.catch((error) => {
|
|
1628
1646
|
node.state.error.set(error);
|
|
1629
|
-
if (handleError) {
|
|
1630
|
-
handleError(error);
|
|
1631
|
-
}
|
|
1632
1647
|
});
|
|
1633
1648
|
}
|
|
1634
1649
|
function extractFunctionOrComputed(node, obj, k, v) {
|
|
@@ -1700,8 +1715,6 @@ function activateNodeFunction(node, lazyFn) {
|
|
|
1700
1715
|
// let curTarget$: Observable<any>;
|
|
1701
1716
|
let update;
|
|
1702
1717
|
let wasPromise;
|
|
1703
|
-
let timeoutRetry;
|
|
1704
|
-
const attemptNum = { current: 0 };
|
|
1705
1718
|
const activateFn = (isFunction(node) ? node : lazyFn);
|
|
1706
1719
|
const doRetry = () => { var _a; return (_a = node.state) === null || _a === void 0 ? void 0 : _a.refreshNum.set((v) => v + 1); };
|
|
1707
1720
|
let activatedValue;
|
|
@@ -1762,20 +1775,10 @@ function activateNodeFunction(node, lazyFn) {
|
|
|
1762
1775
|
if (!wasPromise || !globalState.isLoadingRemote$.peek()) {
|
|
1763
1776
|
if (wasPromise) {
|
|
1764
1777
|
if (node.activationState) {
|
|
1765
|
-
const {
|
|
1766
|
-
let onError;
|
|
1767
|
-
if (retry) {
|
|
1768
|
-
if (timeoutRetry === null || timeoutRetry === void 0 ? void 0 : timeoutRetry.current) {
|
|
1769
|
-
clearTimeout(timeoutRetry.current);
|
|
1770
|
-
}
|
|
1771
|
-
const { handleError, timeout } = setupRetry(retry, doRetry, attemptNum);
|
|
1772
|
-
onError = handleError;
|
|
1773
|
-
timeoutRetry = timeout;
|
|
1774
|
-
node.activationState.onError = onError;
|
|
1775
|
-
}
|
|
1778
|
+
const { initial } = node.activationState;
|
|
1776
1779
|
if (value && isPromise(value)) {
|
|
1777
1780
|
// Extract the promise to make it set the value/error when it comes in
|
|
1778
|
-
extractPromise(node, value, update
|
|
1781
|
+
extractPromise(node, value, update);
|
|
1779
1782
|
}
|
|
1780
1783
|
// Set this to undefined only if it's replacing the activation function,
|
|
1781
1784
|
// so we don't overwrite it if it already has real data from either local
|
|
@@ -1785,9 +1788,8 @@ function activateNodeFunction(node, lazyFn) {
|
|
|
1785
1788
|
}
|
|
1786
1789
|
}
|
|
1787
1790
|
else if (node.activated) {
|
|
1788
|
-
let onError;
|
|
1789
1791
|
// Extract the promise to make it set the value/error when it comes in
|
|
1790
|
-
extractPromise(node, value, update
|
|
1792
|
+
extractPromise(node, value, update);
|
|
1791
1793
|
// Set this to undefined only if it's replacing the activation function,
|
|
1792
1794
|
// so we don't overwrite it if it already has real data from either local
|
|
1793
1795
|
// cache or a previous run
|
|
@@ -1824,23 +1826,21 @@ const activateNodeBase = (globalState.activateNode = function activateNodeBase(n
|
|
|
1824
1826
|
let isSettingFromSubscribe = false;
|
|
1825
1827
|
let _mode = 'set';
|
|
1826
1828
|
if (node.activationState) {
|
|
1827
|
-
const { onSet, subscribe, get: getFn, initial
|
|
1828
|
-
// TODO Should this have lastSync and value somehow?
|
|
1829
|
-
const run = () => getFn({ updateLastSync: noop, setMode: (mode) => (_mode = mode), lastSync: undefined, value: undefined });
|
|
1829
|
+
const { onSet, subscribe, get: getFn, initial } = node.activationState;
|
|
1830
1830
|
value = getFn
|
|
1831
|
-
?
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
})
|
|
1838
|
-
|
|
1831
|
+
? runWithRetry(node, { attemptNum: 0 }, () => {
|
|
1832
|
+
return getFn({
|
|
1833
|
+
updateLastSync: noop,
|
|
1834
|
+
setMode: (mode) => (_mode = mode),
|
|
1835
|
+
lastSync: undefined,
|
|
1836
|
+
value: undefined,
|
|
1837
|
+
});
|
|
1838
|
+
})
|
|
1839
1839
|
: undefined;
|
|
1840
|
+
// TODO Should this have lastSync and value somehow?
|
|
1840
1841
|
if (value == undefined || value === null) {
|
|
1841
1842
|
value = initial;
|
|
1842
1843
|
}
|
|
1843
|
-
let timeoutRetry;
|
|
1844
1844
|
if (onSet) {
|
|
1845
1845
|
let allChanges = [];
|
|
1846
1846
|
let latestValue = undefined;
|
|
@@ -1868,33 +1868,28 @@ const activateNodeBase = (globalState.activateNode = function activateNodeBase(n
|
|
|
1868
1868
|
globalState.pendingNodes.delete(node);
|
|
1869
1869
|
runNumber++;
|
|
1870
1870
|
const thisRunNumber = runNumber;
|
|
1871
|
-
const attemptNum = { current: 0 };
|
|
1872
1871
|
const run = () => {
|
|
1873
1872
|
if (thisRunNumber !== runNumber) {
|
|
1874
1873
|
// set may get called multiple times before it loads so ignore any previous runs
|
|
1875
1874
|
return;
|
|
1876
1875
|
}
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
onError,
|
|
1895
|
-
fromSubscribe: isSettingFromSubscribe,
|
|
1896
|
-
}), () => {
|
|
1897
|
-
isSetting = false;
|
|
1876
|
+
return runWithRetry(node, { attemptNum: 0 }, () => {
|
|
1877
|
+
return new Promise((resolve, reject) => {
|
|
1878
|
+
isSetting = true;
|
|
1879
|
+
batch(() => onSet({
|
|
1880
|
+
value,
|
|
1881
|
+
changes,
|
|
1882
|
+
getPrevious,
|
|
1883
|
+
node,
|
|
1884
|
+
update,
|
|
1885
|
+
refresh,
|
|
1886
|
+
onError: reject,
|
|
1887
|
+
fromSubscribe: isSettingFromSubscribe,
|
|
1888
|
+
}), () => {
|
|
1889
|
+
isSetting = false;
|
|
1890
|
+
resolve();
|
|
1891
|
+
});
|
|
1892
|
+
});
|
|
1898
1893
|
});
|
|
1899
1894
|
};
|
|
1900
1895
|
whenReady(node.state.isLoaded, run);
|
|
@@ -2220,10 +2215,10 @@ const internal = {
|
|
|
2220
2215
|
observableFns,
|
|
2221
2216
|
optimized,
|
|
2222
2217
|
peek,
|
|
2218
|
+
runWithRetry,
|
|
2223
2219
|
set,
|
|
2224
2220
|
setAtPath,
|
|
2225
2221
|
setNodeValue,
|
|
2226
|
-
setupRetry,
|
|
2227
2222
|
symbolActivated,
|
|
2228
2223
|
symbolDelete,
|
|
2229
2224
|
};
|