@legendapp/state 2.2.0-next.42 → 2.2.0-next.44
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 +3 -3
- package/index.js +164 -255
- package/index.js.map +1 -1
- package/index.mjs +165 -255
- package/index.mjs.map +1 -1
- package/package.json +1 -1
- package/persist.d.ts +2 -15
- package/persist.js +54 -26
- package/persist.js.map +1 -1
- package/persist.mjs +54 -27
- package/persist.mjs.map +1 -1
- package/src/activated.d.ts +2 -0
- package/src/globals.d.ts +2 -2
- package/src/observableInterfaces.d.ts +25 -19
- package/src/observableTypes.d.ts +8 -5
- package/src/persist/synced.d.ts +2 -0
- package/src/persistTypes.d.ts +0 -3
- package/src/synced.d.ts +0 -4
package/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { activated } from './src/activated';
|
|
2
2
|
export { batch, beginBatch, endBatch } from './src/batching';
|
|
3
3
|
export { computed } from './src/computed';
|
|
4
4
|
export { configureLegendState } from './src/config';
|
|
@@ -28,7 +28,7 @@ export declare const internal: {
|
|
|
28
28
|
isLoadingLocal: boolean;
|
|
29
29
|
isMerging: boolean;
|
|
30
30
|
isLoadingRemote$: import("./src/observableTypes").ObservablePrimitive<boolean>;
|
|
31
|
-
|
|
31
|
+
activateNodePersist: (node: import("./src/observableInterfaces").NodeValue, newValue: any) => {
|
|
32
32
|
update: import("./src/observableInterfaces").UpdateFn;
|
|
33
33
|
value: any;
|
|
34
34
|
};
|
|
@@ -42,6 +42,6 @@ export declare const internal: {
|
|
|
42
42
|
set: typeof set;
|
|
43
43
|
setAtPath: typeof setAtPath;
|
|
44
44
|
setNodeValue: typeof setNodeValue;
|
|
45
|
-
|
|
45
|
+
symbolActivated: symbol;
|
|
46
46
|
symbolDelete: symbol;
|
|
47
47
|
};
|
package/index.js
CHANGED
|
@@ -61,12 +61,12 @@ const symbolGetNode = Symbol('getNode');
|
|
|
61
61
|
const symbolDelete = /* @__PURE__ */ Symbol('delete');
|
|
62
62
|
const symbolOpaque = Symbol('opaque');
|
|
63
63
|
const optimized = Symbol('optimized');
|
|
64
|
-
const
|
|
64
|
+
const symbolActivated = Symbol('activated');
|
|
65
65
|
const globalState = {
|
|
66
66
|
isLoadingLocal: false,
|
|
67
67
|
isMerging: false,
|
|
68
68
|
isLoadingRemote$: undefined,
|
|
69
|
-
|
|
69
|
+
activateNodePersist: undefined,
|
|
70
70
|
pendingNodes: new Map(),
|
|
71
71
|
dirtyNodes: new Set(),
|
|
72
72
|
};
|
|
@@ -91,13 +91,6 @@ function setNodeValue(node, newValue) {
|
|
|
91
91
|
const isFunc = isFunction(newValue);
|
|
92
92
|
// Compute newValue if newValue is a function or an observable
|
|
93
93
|
newValue = !parentNode.isAssigning && isFunc ? newValue(prevValue) : newValue;
|
|
94
|
-
// If setting an observable, set a link to the observable instead
|
|
95
|
-
if (isObservable(newValue)) {
|
|
96
|
-
const val = newValue;
|
|
97
|
-
node.lazy = true;
|
|
98
|
-
node.lazyFn = () => val;
|
|
99
|
-
newValue = undefined;
|
|
100
|
-
}
|
|
101
94
|
if (!globalState.isMerging ||
|
|
102
95
|
prevValue === undefined ||
|
|
103
96
|
isFunction(prevValue) ||
|
|
@@ -134,7 +127,7 @@ function getNodeValue(node) {
|
|
|
134
127
|
return child;
|
|
135
128
|
}
|
|
136
129
|
function getChildNode(node, key, asFunction) {
|
|
137
|
-
var _a;
|
|
130
|
+
var _a, _b;
|
|
138
131
|
// Get the child by key
|
|
139
132
|
let child = (_a = node.children) === null || _a === void 0 ? void 0 : _a.get(key);
|
|
140
133
|
// Create the child node if it doesn't already exist
|
|
@@ -145,11 +138,9 @@ function getChildNode(node, key, asFunction) {
|
|
|
145
138
|
key,
|
|
146
139
|
lazy: true,
|
|
147
140
|
};
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
asFunction = lookup.bind(node, key);
|
|
152
|
-
}
|
|
141
|
+
// Lookup functions are bound with the child key
|
|
142
|
+
if (((_b = node.lazyFn) === null || _b === void 0 ? void 0 : _b.length) === 1) {
|
|
143
|
+
asFunction = node.lazyFn.bind(node, key);
|
|
153
144
|
}
|
|
154
145
|
if (asFunction) {
|
|
155
146
|
child = Object.assign(() => { }, child);
|
|
@@ -164,7 +155,7 @@ function getChildNode(node, key, asFunction) {
|
|
|
164
155
|
}
|
|
165
156
|
function ensureNodeValue(node) {
|
|
166
157
|
let value = getNodeValue(node);
|
|
167
|
-
if (!value) {
|
|
158
|
+
if (!value || isFunction(value)) {
|
|
168
159
|
if (isChildNodeValue(node)) {
|
|
169
160
|
const parent = ensureNodeValue(node.parent);
|
|
170
161
|
value = parent[node.key] = {};
|
|
@@ -206,13 +197,11 @@ function extractFunction(node, key, fnOrComputed) {
|
|
|
206
197
|
node.functions.set(key, fnOrComputed);
|
|
207
198
|
}
|
|
208
199
|
|
|
209
|
-
function
|
|
200
|
+
function activated(params) {
|
|
210
201
|
return (() => ({
|
|
211
|
-
[
|
|
202
|
+
[symbolActivated]: params,
|
|
212
203
|
}));
|
|
213
204
|
}
|
|
214
|
-
// TODOV3 Remove this for final release
|
|
215
|
-
const activated = synced;
|
|
216
205
|
|
|
217
206
|
let timeout;
|
|
218
207
|
let numInBatch = 0;
|
|
@@ -517,14 +506,6 @@ function opaqueObject(value) {
|
|
|
517
506
|
}
|
|
518
507
|
return value;
|
|
519
508
|
}
|
|
520
|
-
function getValueAtPath(obj, path) {
|
|
521
|
-
let o = obj;
|
|
522
|
-
for (let i = 0; o && i < path.length; i++) {
|
|
523
|
-
const p = path[i];
|
|
524
|
-
o = o[p];
|
|
525
|
-
}
|
|
526
|
-
return o;
|
|
527
|
-
}
|
|
528
509
|
function setAtPath(obj, path, pathTypes, value, fullObj, restore) {
|
|
529
510
|
let o = obj;
|
|
530
511
|
let oFull = fullObj;
|
|
@@ -668,6 +649,7 @@ function setSilently(obs, newValue) {
|
|
|
668
649
|
}
|
|
669
650
|
|
|
670
651
|
function onChange(node, callback, options = {}, fromLinks) {
|
|
652
|
+
var _a;
|
|
671
653
|
const { initial, immediate, noArgs } = options;
|
|
672
654
|
const { trackingType } = options;
|
|
673
655
|
let listeners = immediate ? node.listenersImmediate : node.listeners;
|
|
@@ -701,59 +683,36 @@ function onChange(node, callback, options = {}, fromLinks) {
|
|
|
701
683
|
getPrevious: () => undefined,
|
|
702
684
|
});
|
|
703
685
|
}
|
|
704
|
-
// TODO: This is really verbose, refactor it to be less code. But for now at least it's correct.
|
|
705
686
|
let extraDisposes;
|
|
706
|
-
|
|
707
|
-
|
|
687
|
+
function addLinkedNodeListeners(childNode, cb = callback, from) {
|
|
688
|
+
// Don't add listeners for the same node more than once
|
|
689
|
+
if (!(fromLinks === null || fromLinks === void 0 ? void 0 : fromLinks.has(childNode))) {
|
|
708
690
|
fromLinks || (fromLinks = new Set());
|
|
709
|
-
fromLinks.add(node);
|
|
710
|
-
|
|
711
|
-
|
|
691
|
+
fromLinks.add(from || node);
|
|
692
|
+
cb || (cb = callback);
|
|
693
|
+
const childOptions = {
|
|
694
|
+
trackingType: true,
|
|
695
|
+
...options,
|
|
696
|
+
};
|
|
697
|
+
// onChange for the linked node
|
|
698
|
+
extraDisposes = [...(extraDisposes || []), onChange(childNode, cb, childOptions, fromLinks)];
|
|
712
699
|
}
|
|
713
700
|
}
|
|
714
|
-
//
|
|
715
|
-
if (node.
|
|
716
|
-
|
|
717
|
-
if (!fromLinks || !fromLinks.has(linkedFromNode)) {
|
|
718
|
-
fromLinks || (fromLinks = new Set());
|
|
719
|
-
fromLinks.add(node);
|
|
720
|
-
fromLinks.add(linkedFromNode);
|
|
721
|
-
extraDisposes || (extraDisposes = []);
|
|
722
|
-
extraDisposes.push(onChange(linkedFromNode, callback, options, fromLinks));
|
|
723
|
-
}
|
|
724
|
-
}
|
|
701
|
+
// Add listeners for linked to nodes
|
|
702
|
+
if (node.linkedToNode) {
|
|
703
|
+
addLinkedNodeListeners(node.linkedToNode);
|
|
725
704
|
}
|
|
705
|
+
// Add listeners for linked from nodes
|
|
706
|
+
(_a = node.linkedFromNodes) === null || _a === void 0 ? void 0 : _a.forEach((linkedFromNode) => addLinkedNodeListeners(linkedFromNode));
|
|
707
|
+
// Go up through the parents and add listeners for linked from nodes
|
|
726
708
|
let parent = node.parent;
|
|
727
709
|
let pathParent = [node.key];
|
|
728
710
|
while (parent) {
|
|
729
711
|
if (parent.linkedFromNodes) {
|
|
730
712
|
for (const linkedFromNode of parent.linkedFromNodes) {
|
|
731
|
-
if (!fromLinks ||
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
fromLinks.add(linkedFromNode);
|
|
735
|
-
extraDisposes || (extraDisposes = []);
|
|
736
|
-
const path = pathParent;
|
|
737
|
-
const p = getValueAtPath(getNodeValue(linkedFromNode), path);
|
|
738
|
-
const prev = p ? JSON.parse(JSON.stringify(p)) : {};
|
|
739
|
-
const cb = ({ value: valueA }) => {
|
|
740
|
-
const value = getValueAtPath(valueA, path);
|
|
741
|
-
if (value !== prev) {
|
|
742
|
-
callback({
|
|
743
|
-
value,
|
|
744
|
-
changes: [
|
|
745
|
-
{
|
|
746
|
-
path,
|
|
747
|
-
pathTypes: path.map(() => 'object'), // TODO CHANGE
|
|
748
|
-
prevAtPath: prev,
|
|
749
|
-
valueAtPath: value,
|
|
750
|
-
},
|
|
751
|
-
],
|
|
752
|
-
getPrevious: () => prev,
|
|
753
|
-
});
|
|
754
|
-
}
|
|
755
|
-
};
|
|
756
|
-
extraDisposes.push(onChange(linkedFromNode, cb, { trackingType: true, ...options }, fromLinks));
|
|
713
|
+
if (!(fromLinks === null || fromLinks === void 0 ? void 0 : fromLinks.has(linkedFromNode))) {
|
|
714
|
+
const cb = createCb(linkedFromNode, pathParent, callback);
|
|
715
|
+
addLinkedNodeListeners(linkedFromNode, cb, parent);
|
|
757
716
|
}
|
|
758
717
|
}
|
|
759
718
|
}
|
|
@@ -765,6 +724,38 @@ function onChange(node, callback, options = {}, fromLinks) {
|
|
|
765
724
|
extraDisposes === null || extraDisposes === void 0 ? void 0 : extraDisposes.forEach((fn) => fn());
|
|
766
725
|
};
|
|
767
726
|
}
|
|
727
|
+
function createCb(linkedFromNode, path, callback) {
|
|
728
|
+
// Create a callback for a path that calls it with the current value at the path
|
|
729
|
+
let { valueAtPath: prevAtPath } = getValueAtPath(getNodeValue(linkedFromNode), path);
|
|
730
|
+
return function ({ value: valueA }) {
|
|
731
|
+
const { valueAtPath, pathTypes } = getValueAtPath(valueA, path);
|
|
732
|
+
if (valueAtPath !== prevAtPath) {
|
|
733
|
+
callback({
|
|
734
|
+
value: valueAtPath,
|
|
735
|
+
changes: [
|
|
736
|
+
{
|
|
737
|
+
path,
|
|
738
|
+
pathTypes,
|
|
739
|
+
prevAtPath,
|
|
740
|
+
valueAtPath,
|
|
741
|
+
},
|
|
742
|
+
],
|
|
743
|
+
getPrevious: () => prevAtPath,
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
prevAtPath = valueAtPath;
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
function getValueAtPath(obj, path) {
|
|
750
|
+
let o = obj;
|
|
751
|
+
const pathTypes = [];
|
|
752
|
+
for (let i = 0; o && i < path.length; i++) {
|
|
753
|
+
pathTypes.push(isArray(o) ? 'array' : 'object');
|
|
754
|
+
const p = path[i];
|
|
755
|
+
o = o[p];
|
|
756
|
+
}
|
|
757
|
+
return { valueAtPath: o, pathTypes };
|
|
758
|
+
}
|
|
768
759
|
|
|
769
760
|
function setupTracking(nodes, update, noArgs, immediate) {
|
|
770
761
|
let listeners = [];
|
|
@@ -973,65 +964,6 @@ function whenReady(predicate, effect) {
|
|
|
973
964
|
return _when(predicate, effect, true);
|
|
974
965
|
}
|
|
975
966
|
|
|
976
|
-
function calculateRetryDelay(retryOptions, attemptNum) {
|
|
977
|
-
const { backoff, delay = 1000, infinite, times = 3, maxDelay = 30000 } = retryOptions;
|
|
978
|
-
if (infinite || attemptNum < times) {
|
|
979
|
-
const delayTime = Math.min(delay * (backoff === 'constant' ? 1 : 2 ** attemptNum), maxDelay);
|
|
980
|
-
return delayTime;
|
|
981
|
-
}
|
|
982
|
-
return null;
|
|
983
|
-
}
|
|
984
|
-
function createRetryTimeout(retryOptions, attemptNum, fn) {
|
|
985
|
-
const delayTime = calculateRetryDelay(retryOptions, attemptNum);
|
|
986
|
-
if (delayTime) {
|
|
987
|
-
return setTimeout(fn, delayTime);
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
function runWithRetry(node, state, fn) {
|
|
991
|
-
const { retry, waitFor } = node.activationState;
|
|
992
|
-
const e = { cancel: false };
|
|
993
|
-
let value = undefined;
|
|
994
|
-
if (waitFor) {
|
|
995
|
-
value = whenReady(waitFor, () => {
|
|
996
|
-
node.activationState.waitFor = undefined;
|
|
997
|
-
return fn(e);
|
|
998
|
-
});
|
|
999
|
-
}
|
|
1000
|
-
else {
|
|
1001
|
-
value = fn(e);
|
|
1002
|
-
}
|
|
1003
|
-
if (isPromise(value) && retry) {
|
|
1004
|
-
let timeoutRetry;
|
|
1005
|
-
return new Promise((resolve) => {
|
|
1006
|
-
const run = () => {
|
|
1007
|
-
value
|
|
1008
|
-
.then((val) => {
|
|
1009
|
-
node.activationState.persistedRetry = false;
|
|
1010
|
-
resolve(val);
|
|
1011
|
-
})
|
|
1012
|
-
.catch(() => {
|
|
1013
|
-
state.attemptNum++;
|
|
1014
|
-
if (timeoutRetry) {
|
|
1015
|
-
clearTimeout(timeoutRetry);
|
|
1016
|
-
}
|
|
1017
|
-
if (!e.cancel) {
|
|
1018
|
-
timeoutRetry = createRetryTimeout(retry, state.attemptNum, () => {
|
|
1019
|
-
value = fn(e);
|
|
1020
|
-
run();
|
|
1021
|
-
});
|
|
1022
|
-
}
|
|
1023
|
-
})
|
|
1024
|
-
.finally(() => {
|
|
1025
|
-
node.activationState.persistedRetry = false;
|
|
1026
|
-
});
|
|
1027
|
-
};
|
|
1028
|
-
run();
|
|
1029
|
-
});
|
|
1030
|
-
}
|
|
1031
|
-
return value;
|
|
1032
|
-
}
|
|
1033
|
-
|
|
1034
|
-
const noop = () => { };
|
|
1035
967
|
const ArrayModifiers = new Set([
|
|
1036
968
|
'copyWithin',
|
|
1037
969
|
'fill',
|
|
@@ -1734,8 +1666,14 @@ function peek(node) {
|
|
|
1734
1666
|
if (lazy) {
|
|
1735
1667
|
const lazyFn = node.lazyFn;
|
|
1736
1668
|
delete node.lazy;
|
|
1737
|
-
if (isFunction(
|
|
1738
|
-
|
|
1669
|
+
if (isFunction(lazyFn)) {
|
|
1670
|
+
if (lazyFn.length === 1) {
|
|
1671
|
+
// This is a lookup function, so return a record object
|
|
1672
|
+
value = {};
|
|
1673
|
+
}
|
|
1674
|
+
else {
|
|
1675
|
+
value = activateNodeFunction(node, lazyFn);
|
|
1676
|
+
}
|
|
1739
1677
|
}
|
|
1740
1678
|
}
|
|
1741
1679
|
if (lazy || node.needsExtract) {
|
|
@@ -1750,10 +1688,8 @@ function peek(node) {
|
|
|
1750
1688
|
function reactivateNode(node, lazyFn) {
|
|
1751
1689
|
var _a, _b;
|
|
1752
1690
|
(_a = node.activatedObserveDispose) === null || _a === void 0 ? void 0 : _a.call(node);
|
|
1753
|
-
node.activatedObserveDispose = undefined;
|
|
1754
1691
|
(_b = node.linkedToNodeDispose) === null || _b === void 0 ? void 0 : _b.call(node);
|
|
1755
|
-
node.linkedToNodeDispose = undefined;
|
|
1756
|
-
node.linkedToNode = undefined;
|
|
1692
|
+
node.activatedObserveDispose = node.linkedToNodeDispose = node.linkedToNode = undefined;
|
|
1757
1693
|
node.lazyFn = lazyFn;
|
|
1758
1694
|
node.lazy = true;
|
|
1759
1695
|
}
|
|
@@ -1764,7 +1700,6 @@ function activateNodeFunction(node, lazyFn) {
|
|
|
1764
1700
|
let wasPromise;
|
|
1765
1701
|
let ignoreThisUpdate;
|
|
1766
1702
|
const activateFn = lazyFn;
|
|
1767
|
-
const doRetry = () => { var _a; return (_a = node.state) === null || _a === void 0 ? void 0 : _a.refreshNum.set((v) => v + 1); };
|
|
1768
1703
|
let activatedValue;
|
|
1769
1704
|
let disposes = [];
|
|
1770
1705
|
let refreshFn;
|
|
@@ -1773,7 +1708,7 @@ function activateNodeFunction(node, lazyFn) {
|
|
|
1773
1708
|
globalState.dirtyNodes.add(node);
|
|
1774
1709
|
}
|
|
1775
1710
|
node.activatedObserveDispose = observe(() => {
|
|
1776
|
-
var _a, _b, _c, _d
|
|
1711
|
+
var _a, _b, _c, _d;
|
|
1777
1712
|
// const params = createNodeActivationParams(node);
|
|
1778
1713
|
// Run the function at this node
|
|
1779
1714
|
let value = activateFn();
|
|
@@ -1784,7 +1719,7 @@ function activateNodeFunction(node, lazyFn) {
|
|
|
1784
1719
|
if (isFunction(value)) {
|
|
1785
1720
|
value = value();
|
|
1786
1721
|
}
|
|
1787
|
-
const activated = value === null || value === void 0 ? void 0 : value[
|
|
1722
|
+
const activated = value === null || value === void 0 ? void 0 : value[symbolActivated];
|
|
1788
1723
|
if (activated) {
|
|
1789
1724
|
node.activationState = activated;
|
|
1790
1725
|
value = undefined;
|
|
@@ -1795,29 +1730,25 @@ function activateNodeFunction(node, lazyFn) {
|
|
|
1795
1730
|
// TODO: Is calling recursively bad? If so can it be fixed?
|
|
1796
1731
|
if (!node.activated) {
|
|
1797
1732
|
node.activated = true;
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1733
|
+
let activateNodeFn = activateNodeBase;
|
|
1734
|
+
// If this is a Synced then run it through persistence instead of base
|
|
1735
|
+
if (activated === null || activated === void 0 ? void 0 : activated.synced) {
|
|
1736
|
+
activateNodeFn = globalState.activateNodePersist;
|
|
1737
|
+
wasPromise = true;
|
|
1738
|
+
}
|
|
1739
|
+
const { update: newUpdate, value: newValue } = activateNodeFn(node, value);
|
|
1802
1740
|
update = newUpdate;
|
|
1803
1741
|
value = newValue !== null && newValue !== void 0 ? newValue : activated === null || activated === void 0 ? void 0 : activated.initial;
|
|
1804
1742
|
}
|
|
1805
1743
|
else if (node.activationState) {
|
|
1806
1744
|
if (!node.activationState.persistedRetry && !node.activationState.waitFor) {
|
|
1807
1745
|
const activated = node.activationState;
|
|
1808
|
-
if ((
|
|
1746
|
+
if ((_b = (_a = node.state) === null || _a === void 0 ? void 0 : _a.peek()) === null || _b === void 0 ? void 0 : _b.sync) {
|
|
1809
1747
|
node.state.sync();
|
|
1810
1748
|
ignoreThisUpdate = true;
|
|
1811
1749
|
}
|
|
1812
1750
|
else {
|
|
1813
|
-
value =
|
|
1814
|
-
(_e = (_d = activated.get) === null || _d === void 0 ? void 0 : _d.call(activated, {
|
|
1815
|
-
updateLastSync: noop,
|
|
1816
|
-
setMode: noop,
|
|
1817
|
-
lastSync: undefined,
|
|
1818
|
-
value: undefined,
|
|
1819
|
-
refresh: doRetry,
|
|
1820
|
-
})) !== null && _e !== void 0 ? _e : activated.initial;
|
|
1751
|
+
value = (_d = (_c = activated.get) === null || _c === void 0 ? void 0 : _c.call(activated)) !== null && _d !== void 0 ? _d : activated.initial;
|
|
1821
1752
|
}
|
|
1822
1753
|
}
|
|
1823
1754
|
else {
|
|
@@ -1826,7 +1757,6 @@ function activateNodeFunction(node, lazyFn) {
|
|
|
1826
1757
|
}
|
|
1827
1758
|
// value is undefined if it's in a persisted retry
|
|
1828
1759
|
wasPromise = wasPromise || isPromise(value);
|
|
1829
|
-
get(getNode((_f = node.state) === null || _f === void 0 ? void 0 : _f.refreshNum));
|
|
1830
1760
|
return value;
|
|
1831
1761
|
}, (e) => {
|
|
1832
1762
|
if (!ignoreThisUpdate) {
|
|
@@ -1882,29 +1812,16 @@ function activateNodeFunction(node, lazyFn) {
|
|
|
1882
1812
|
}, { fromComputed: true });
|
|
1883
1813
|
return activatedValue;
|
|
1884
1814
|
}
|
|
1885
|
-
|
|
1815
|
+
function activateNodeBase(node, value) {
|
|
1886
1816
|
if (!node.state) {
|
|
1887
1817
|
node.state = createObservable({
|
|
1888
1818
|
isLoaded: false,
|
|
1889
1819
|
}, false, extractPromise, getProxy);
|
|
1890
1820
|
}
|
|
1891
1821
|
let isSetting = false;
|
|
1892
|
-
let isSettingFromSubscribe = false;
|
|
1893
|
-
let _mode = 'set';
|
|
1894
1822
|
if (node.activationState) {
|
|
1895
|
-
const { onSet,
|
|
1896
|
-
value = getFn
|
|
1897
|
-
? runWithRetry(node, { attemptNum: 0 }, () => {
|
|
1898
|
-
return getFn({
|
|
1899
|
-
updateLastSync: noop,
|
|
1900
|
-
setMode: (mode) => (_mode = mode),
|
|
1901
|
-
lastSync: undefined,
|
|
1902
|
-
value: undefined,
|
|
1903
|
-
refresh,
|
|
1904
|
-
});
|
|
1905
|
-
})
|
|
1906
|
-
: undefined;
|
|
1907
|
-
// TODO Should this have lastSync and value somehow?
|
|
1823
|
+
const { onSet, get: getFn, initial } = node.activationState;
|
|
1824
|
+
value = getFn === null || getFn === void 0 ? void 0 : getFn();
|
|
1908
1825
|
if (value == undefined || value === null) {
|
|
1909
1826
|
value = initial;
|
|
1910
1827
|
}
|
|
@@ -1940,49 +1857,22 @@ const activateNodeBase = (globalState.activateNode = function activateNodeBase(n
|
|
|
1940
1857
|
// set may get called multiple times before it loads so ignore any previous runs
|
|
1941
1858
|
return;
|
|
1942
1859
|
}
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
isSetting = true;
|
|
1950
|
-
let isProm = false;
|
|
1951
|
-
batch(() => {
|
|
1952
|
-
try {
|
|
1953
|
-
const val = onSet({
|
|
1954
|
-
value,
|
|
1955
|
-
changes,
|
|
1956
|
-
getPrevious,
|
|
1957
|
-
node,
|
|
1958
|
-
update,
|
|
1959
|
-
refresh,
|
|
1960
|
-
retryNum: retryAttempts.attemptNum,
|
|
1961
|
-
cancelRetry,
|
|
1962
|
-
fromSubscribe: isSettingFromSubscribe,
|
|
1963
|
-
});
|
|
1964
|
-
isProm = isPromise(val);
|
|
1965
|
-
if (isProm) {
|
|
1966
|
-
val.then(resolve).catch(reject);
|
|
1967
|
-
}
|
|
1968
|
-
}
|
|
1969
|
-
catch (e) {
|
|
1970
|
-
reject(e);
|
|
1971
|
-
}
|
|
1972
|
-
}, () => {
|
|
1973
|
-
if (!isProm) {
|
|
1974
|
-
isSetting = false;
|
|
1975
|
-
resolve();
|
|
1976
|
-
}
|
|
1977
|
-
});
|
|
1860
|
+
isSetting = true;
|
|
1861
|
+
batch(() => {
|
|
1862
|
+
onSet({
|
|
1863
|
+
value,
|
|
1864
|
+
changes,
|
|
1865
|
+
getPrevious,
|
|
1978
1866
|
});
|
|
1867
|
+
}, () => {
|
|
1868
|
+
isSetting = false;
|
|
1979
1869
|
});
|
|
1980
1870
|
};
|
|
1981
1871
|
whenReady(node.state.isLoaded, run);
|
|
1982
1872
|
}
|
|
1983
1873
|
};
|
|
1984
1874
|
const onChangeImmediate = ({ value, changes }) => {
|
|
1985
|
-
if (!isSetting
|
|
1875
|
+
if (!isSetting) {
|
|
1986
1876
|
if (changes.length > 1 || !isFunction(changes[0].prevAtPath)) {
|
|
1987
1877
|
latestValue = value;
|
|
1988
1878
|
if (allChanges.length > 0) {
|
|
@@ -2000,68 +1890,32 @@ const activateNodeBase = (globalState.activateNode = function activateNodeBase(n
|
|
|
2000
1890
|
onChange(node, onChangeImmediate, { immediate: true });
|
|
2001
1891
|
onChange(node, runChanges);
|
|
2002
1892
|
}
|
|
2003
|
-
if (process.env.NODE_ENV === 'development' && node.activationState.cache) {
|
|
2004
|
-
// TODO Better message
|
|
2005
|
-
console.log('[legend-state] Using cache without setting up persistence first');
|
|
2006
|
-
}
|
|
2007
|
-
if (process.env.NODE_ENV === 'development' && node.activationState.retry) {
|
|
2008
|
-
// TODO Better message
|
|
2009
|
-
console.log('[legend-state] Using retry without setting up persistence first');
|
|
2010
|
-
}
|
|
2011
|
-
if (subscribe) {
|
|
2012
|
-
const updateFromSubscribe = (params) => {
|
|
2013
|
-
whenReady(node.state.isLoaded, () => {
|
|
2014
|
-
isSettingFromSubscribe = true;
|
|
2015
|
-
update(params);
|
|
2016
|
-
isSettingFromSubscribe = false;
|
|
2017
|
-
});
|
|
2018
|
-
};
|
|
2019
|
-
subscribe({ node, update: updateFromSubscribe, refresh });
|
|
2020
|
-
}
|
|
2021
1893
|
}
|
|
2022
|
-
const update = ({ value
|
|
1894
|
+
const update = ({ value }) => {
|
|
2023
1895
|
// TODO: This isSetting might not be necessary? Tests still work if removing it.
|
|
2024
1896
|
// Write tests that would break it if removed? I'd guess a combination of subscribe and
|
|
2025
1897
|
if (!isSetting) {
|
|
2026
1898
|
isSetting = true;
|
|
2027
|
-
|
|
2028
|
-
assign(node, value);
|
|
2029
|
-
}
|
|
2030
|
-
else if (_mode === 'merge' || mode === 'merge') {
|
|
2031
|
-
mergeIntoObservable(getProxy(node), value);
|
|
2032
|
-
}
|
|
2033
|
-
else {
|
|
2034
|
-
set(node, value);
|
|
2035
|
-
}
|
|
1899
|
+
set(node, value);
|
|
2036
1900
|
isSetting = false;
|
|
2037
1901
|
}
|
|
2038
1902
|
};
|
|
2039
1903
|
return { update, value };
|
|
2040
|
-
}
|
|
1904
|
+
}
|
|
2041
1905
|
function setToObservable(node, value) {
|
|
2042
1906
|
var _a;
|
|
2043
1907
|
// If the computed is a proxy to another observable
|
|
2044
1908
|
// link it to the target observable
|
|
2045
1909
|
const linkedNode = getNode(value);
|
|
2046
1910
|
if (linkedNode !== node && (linkedNode === null || linkedNode === void 0 ? void 0 : linkedNode.linkedToNode) !== node) {
|
|
2047
|
-
const prevNode = node.linkedToNode;
|
|
2048
1911
|
node.linkedToNode = linkedNode;
|
|
2049
|
-
|
|
2050
|
-
linkedNode.linkedFromNodes = new Set();
|
|
2051
|
-
}
|
|
1912
|
+
linkedNode.linkedFromNodes || (linkedNode.linkedFromNodes = new Set());
|
|
2052
1913
|
linkedNode.linkedFromNodes.add(node);
|
|
2053
|
-
peek(linkedNode);
|
|
2054
1914
|
(_a = node.linkedToNodeDispose) === null || _a === void 0 ? void 0 : _a.call(node);
|
|
2055
1915
|
node.linkedToNodeDispose = onChange(linkedNode, () => {
|
|
2056
1916
|
value = peek(linkedNode);
|
|
2057
1917
|
set(node, value);
|
|
2058
1918
|
}, { initial: true }, new Set([node]));
|
|
2059
|
-
// If the target observable is different then notify for the change
|
|
2060
|
-
if (prevNode) {
|
|
2061
|
-
const value = getNodeValue(linkedNode);
|
|
2062
|
-
const prevValue = getNodeValue(prevNode);
|
|
2063
|
-
notify(node, value, prevValue, 0);
|
|
2064
|
-
}
|
|
2065
1919
|
}
|
|
2066
1920
|
return value;
|
|
2067
1921
|
}
|
|
@@ -2133,7 +1987,7 @@ globalState.isLoadingRemote$ = observable(false);
|
|
|
2133
1987
|
|
|
2134
1988
|
function computed(compute, set) {
|
|
2135
1989
|
return observable(set
|
|
2136
|
-
?
|
|
1990
|
+
? activated({
|
|
2137
1991
|
get: compute,
|
|
2138
1992
|
onSet: ({ value }) => set(value),
|
|
2139
1993
|
})
|
|
@@ -2191,14 +2045,70 @@ function event() {
|
|
|
2191
2045
|
}
|
|
2192
2046
|
|
|
2193
2047
|
function proxy(get, set) {
|
|
2194
|
-
return observable(
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2048
|
+
return observable((key) => set
|
|
2049
|
+
? activated({
|
|
2050
|
+
get: () => get(key),
|
|
2051
|
+
onSet: ({ value }) => set(key, value),
|
|
2052
|
+
})
|
|
2053
|
+
: get(key));
|
|
2054
|
+
}
|
|
2055
|
+
|
|
2056
|
+
function calculateRetryDelay(retryOptions, attemptNum) {
|
|
2057
|
+
const { backoff, delay = 1000, infinite, times = 3, maxDelay = 30000 } = retryOptions;
|
|
2058
|
+
if (infinite || attemptNum < times) {
|
|
2059
|
+
const delayTime = Math.min(delay * (backoff === 'constant' ? 1 : 2 ** attemptNum), maxDelay);
|
|
2060
|
+
return delayTime;
|
|
2061
|
+
}
|
|
2062
|
+
return null;
|
|
2063
|
+
}
|
|
2064
|
+
function createRetryTimeout(retryOptions, attemptNum, fn) {
|
|
2065
|
+
const delayTime = calculateRetryDelay(retryOptions, attemptNum);
|
|
2066
|
+
if (delayTime) {
|
|
2067
|
+
return setTimeout(fn, delayTime);
|
|
2068
|
+
}
|
|
2069
|
+
}
|
|
2070
|
+
function runWithRetry(node, state, fn) {
|
|
2071
|
+
const { retry, waitFor } = node.activationState;
|
|
2072
|
+
const e = { cancel: false };
|
|
2073
|
+
let value = undefined;
|
|
2074
|
+
if (waitFor) {
|
|
2075
|
+
value = whenReady(waitFor, () => {
|
|
2076
|
+
node.activationState.waitFor = undefined;
|
|
2077
|
+
return fn(e);
|
|
2078
|
+
});
|
|
2079
|
+
}
|
|
2080
|
+
else {
|
|
2081
|
+
value = fn(e);
|
|
2082
|
+
}
|
|
2083
|
+
if (isPromise(value) && retry) {
|
|
2084
|
+
let timeoutRetry;
|
|
2085
|
+
return new Promise((resolve) => {
|
|
2086
|
+
const run = () => {
|
|
2087
|
+
value
|
|
2088
|
+
.then((val) => {
|
|
2089
|
+
node.activationState.persistedRetry = false;
|
|
2090
|
+
resolve(val);
|
|
2091
|
+
})
|
|
2092
|
+
.catch(() => {
|
|
2093
|
+
state.attemptNum++;
|
|
2094
|
+
if (timeoutRetry) {
|
|
2095
|
+
clearTimeout(timeoutRetry);
|
|
2096
|
+
}
|
|
2097
|
+
if (!e.cancel) {
|
|
2098
|
+
timeoutRetry = createRetryTimeout(retry, state.attemptNum, () => {
|
|
2099
|
+
value = fn(e);
|
|
2100
|
+
run();
|
|
2101
|
+
});
|
|
2102
|
+
}
|
|
2103
|
+
})
|
|
2104
|
+
.finally(() => {
|
|
2105
|
+
node.activationState.persistedRetry = false;
|
|
2106
|
+
});
|
|
2107
|
+
};
|
|
2108
|
+
run();
|
|
2109
|
+
});
|
|
2110
|
+
}
|
|
2111
|
+
return value;
|
|
2202
2112
|
}
|
|
2203
2113
|
|
|
2204
2114
|
const internal = {
|
|
@@ -2215,7 +2125,7 @@ const internal = {
|
|
|
2215
2125
|
set,
|
|
2216
2126
|
setAtPath,
|
|
2217
2127
|
setNodeValue,
|
|
2218
|
-
|
|
2128
|
+
symbolActivated,
|
|
2219
2129
|
symbolDelete,
|
|
2220
2130
|
};
|
|
2221
2131
|
|
|
@@ -2264,7 +2174,6 @@ exports.setSilently = setSilently;
|
|
|
2264
2174
|
exports.setupTracking = setupTracking;
|
|
2265
2175
|
exports.symbolDelete = symbolDelete;
|
|
2266
2176
|
exports.syncState = syncState;
|
|
2267
|
-
exports.synced = synced;
|
|
2268
2177
|
exports.trackSelector = trackSelector;
|
|
2269
2178
|
exports.tracking = tracking;
|
|
2270
2179
|
exports.updateTracking = updateTracking;
|