@legendapp/state 2.2.0-next.41 → 2.2.0-next.43
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 +1 -1
- package/index.js +185 -222
- package/index.js.map +1 -1
- package/index.mjs +186 -221
- package/index.mjs.map +1 -1
- package/package.json +1 -6
- package/persist.d.ts +2 -15
- package/persist.js +56 -28
- package/persist.js.map +1 -1
- package/persist.mjs +56 -29
- package/persist.mjs.map +1 -1
- package/src/activated.d.ts +2 -3
- package/src/globals.d.ts +1 -3
- package/src/helpers.d.ts +1 -0
- package/src/observableInterfaces.d.ts +27 -21
- package/src/observableTypes.d.ts +6 -3
- package/src/onChange.d.ts +1 -1
- package/src/persist/synced.d.ts +2 -0
- package/src/persistTypes.d.ts +0 -3
- package/config/enableReactDirectRender.d.ts +0 -2
- package/config/enableReactDirectRender.js +0 -78
- package/config/enableReactDirectRender.js.map +0 -1
- package/config/enableReactDirectRender.mjs +0 -75
- package/config/enableReactDirectRender.mjs.map +0 -1
- package/src/config/enableReactDirectRender.d.ts +0 -2
package/index.d.ts
CHANGED
|
@@ -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
|
};
|
package/index.js
CHANGED
|
@@ -62,14 +62,11 @@ const symbolDelete = /* @__PURE__ */ Symbol('delete');
|
|
|
62
62
|
const symbolOpaque = Symbol('opaque');
|
|
63
63
|
const optimized = Symbol('optimized');
|
|
64
64
|
const symbolActivated = Symbol('activated');
|
|
65
|
-
// TODOV3 Remove these
|
|
66
|
-
const extraPrimitiveActivators = new Map();
|
|
67
|
-
const extraPrimitiveProps = new Map();
|
|
68
65
|
const globalState = {
|
|
69
66
|
isLoadingLocal: false,
|
|
70
67
|
isMerging: false,
|
|
71
68
|
isLoadingRemote$: undefined,
|
|
72
|
-
|
|
69
|
+
activateNodePersist: undefined,
|
|
73
70
|
pendingNodes: new Map(),
|
|
74
71
|
dirtyNodes: new Set(),
|
|
75
72
|
};
|
|
@@ -94,13 +91,6 @@ function setNodeValue(node, newValue) {
|
|
|
94
91
|
const isFunc = isFunction(newValue);
|
|
95
92
|
// Compute newValue if newValue is a function or an observable
|
|
96
93
|
newValue = !parentNode.isAssigning && isFunc ? newValue(prevValue) : newValue;
|
|
97
|
-
// If setting an observable, set a link to the observable instead
|
|
98
|
-
if (isObservable(newValue)) {
|
|
99
|
-
const val = newValue;
|
|
100
|
-
node.lazy = true;
|
|
101
|
-
node.lazyFn = () => val;
|
|
102
|
-
newValue = undefined;
|
|
103
|
-
}
|
|
104
94
|
if (!globalState.isMerging ||
|
|
105
95
|
prevValue === undefined ||
|
|
106
96
|
isFunction(prevValue) ||
|
|
@@ -137,7 +127,7 @@ function getNodeValue(node) {
|
|
|
137
127
|
return child;
|
|
138
128
|
}
|
|
139
129
|
function getChildNode(node, key, asFunction) {
|
|
140
|
-
var _a;
|
|
130
|
+
var _a, _b;
|
|
141
131
|
// Get the child by key
|
|
142
132
|
let child = (_a = node.children) === null || _a === void 0 ? void 0 : _a.get(key);
|
|
143
133
|
// Create the child node if it doesn't already exist
|
|
@@ -148,11 +138,9 @@ function getChildNode(node, key, asFunction) {
|
|
|
148
138
|
key,
|
|
149
139
|
lazy: true,
|
|
150
140
|
};
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
asFunction = lookup.bind(node, key);
|
|
155
|
-
}
|
|
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);
|
|
156
144
|
}
|
|
157
145
|
if (asFunction) {
|
|
158
146
|
child = Object.assign(() => { }, child);
|
|
@@ -167,7 +155,7 @@ function getChildNode(node, key, asFunction) {
|
|
|
167
155
|
}
|
|
168
156
|
function ensureNodeValue(node) {
|
|
169
157
|
let value = getNodeValue(node);
|
|
170
|
-
if (!value) {
|
|
158
|
+
if (!value || isFunction(value)) {
|
|
171
159
|
if (isChildNodeValue(node)) {
|
|
172
160
|
const parent = ensureNodeValue(node.parent);
|
|
173
161
|
value = parent[node.key] = {};
|
|
@@ -322,7 +310,8 @@ function computeChangesRecursive(changesInBatch, node, value, path, pathTypes, v
|
|
|
322
310
|
computeChangesAtNode(changesInBatch, node, value, path, pathTypes, valueAtPath, prevAtPath, immediate, level, whenOptimizedOnlyIf);
|
|
323
311
|
if (node.linkedFromNodes) {
|
|
324
312
|
for (const linkedFromNode of node.linkedFromNodes) {
|
|
325
|
-
|
|
313
|
+
const childNode = getNodeAtPath(linkedFromNode, path);
|
|
314
|
+
computeChangesRecursive(changesInBatch, childNode, valueAtPath, [], [], valueAtPath, prevAtPath, immediate, 0, whenOptimizedOnlyIf);
|
|
326
315
|
}
|
|
327
316
|
}
|
|
328
317
|
// If not root notify up through parents
|
|
@@ -461,6 +450,14 @@ function endBatch(force) {
|
|
|
461
450
|
}
|
|
462
451
|
}
|
|
463
452
|
}
|
|
453
|
+
function getNodeAtPath(obj, path) {
|
|
454
|
+
let o = obj;
|
|
455
|
+
for (let i = 0; i < path.length; i++) {
|
|
456
|
+
const p = path[i];
|
|
457
|
+
o = getChildNode(o, p);
|
|
458
|
+
}
|
|
459
|
+
return o;
|
|
460
|
+
}
|
|
464
461
|
|
|
465
462
|
function createObservable(value, makePrimitive, extractPromise, createObject, createPrimitive) {
|
|
466
463
|
const valueIsPromise = isPromise(value);
|
|
@@ -651,7 +648,8 @@ function setSilently(obs, newValue) {
|
|
|
651
648
|
return setNodeValue(node, newValue).newValue;
|
|
652
649
|
}
|
|
653
650
|
|
|
654
|
-
function onChange(node, callback, options = {}) {
|
|
651
|
+
function onChange(node, callback, options = {}, fromLinks) {
|
|
652
|
+
var _a;
|
|
655
653
|
const { initial, immediate, noArgs } = options;
|
|
656
654
|
const { trackingType } = options;
|
|
657
655
|
let listeners = immediate ? node.listenersImmediate : node.listeners;
|
|
@@ -685,15 +683,79 @@ function onChange(node, callback, options = {}) {
|
|
|
685
683
|
getPrevious: () => undefined,
|
|
686
684
|
});
|
|
687
685
|
}
|
|
688
|
-
let
|
|
686
|
+
let extraDisposes;
|
|
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))) {
|
|
690
|
+
fromLinks || (fromLinks = new Set());
|
|
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)];
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
// Add listeners for linked to nodes
|
|
689
702
|
if (node.linkedToNode) {
|
|
690
|
-
|
|
703
|
+
addLinkedNodeListeners(node.linkedToNode);
|
|
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
|
|
708
|
+
let parent = node.parent;
|
|
709
|
+
let pathParent = [node.key];
|
|
710
|
+
while (parent) {
|
|
711
|
+
if (parent.linkedFromNodes) {
|
|
712
|
+
for (const linkedFromNode of parent.linkedFromNodes) {
|
|
713
|
+
if (!(fromLinks === null || fromLinks === void 0 ? void 0 : fromLinks.has(linkedFromNode))) {
|
|
714
|
+
const cb = createCb(linkedFromNode, pathParent, callback);
|
|
715
|
+
addLinkedNodeListeners(linkedFromNode, cb, parent);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
pathParent = [parent.key, ...pathParent];
|
|
720
|
+
parent = parent.parent;
|
|
691
721
|
}
|
|
692
722
|
return () => {
|
|
693
723
|
listeners.delete(listener);
|
|
694
|
-
|
|
724
|
+
extraDisposes === null || extraDisposes === void 0 ? void 0 : extraDisposes.forEach((fn) => fn());
|
|
725
|
+
};
|
|
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;
|
|
695
747
|
};
|
|
696
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
|
+
}
|
|
697
759
|
|
|
698
760
|
function setupTracking(nodes, update, noArgs, immediate) {
|
|
699
761
|
let listeners = [];
|
|
@@ -902,65 +964,6 @@ function whenReady(predicate, effect) {
|
|
|
902
964
|
return _when(predicate, effect, true);
|
|
903
965
|
}
|
|
904
966
|
|
|
905
|
-
function calculateRetryDelay(retryOptions, attemptNum) {
|
|
906
|
-
const { backoff, delay = 1000, infinite, times = 3, maxDelay = 30000 } = retryOptions;
|
|
907
|
-
if (infinite || attemptNum < times) {
|
|
908
|
-
const delayTime = Math.min(delay * (backoff === 'constant' ? 1 : 2 ** attemptNum), maxDelay);
|
|
909
|
-
return delayTime;
|
|
910
|
-
}
|
|
911
|
-
return null;
|
|
912
|
-
}
|
|
913
|
-
function createRetryTimeout(retryOptions, attemptNum, fn) {
|
|
914
|
-
const delayTime = calculateRetryDelay(retryOptions, attemptNum);
|
|
915
|
-
if (delayTime) {
|
|
916
|
-
return setTimeout(fn, delayTime);
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
function runWithRetry(node, state, fn) {
|
|
920
|
-
const { retry, waitFor } = node.activationState;
|
|
921
|
-
const e = { cancel: false };
|
|
922
|
-
let value = undefined;
|
|
923
|
-
if (waitFor) {
|
|
924
|
-
value = whenReady(waitFor, () => {
|
|
925
|
-
node.activationState.waitFor = undefined;
|
|
926
|
-
return fn(e);
|
|
927
|
-
});
|
|
928
|
-
}
|
|
929
|
-
else {
|
|
930
|
-
value = fn(e);
|
|
931
|
-
}
|
|
932
|
-
if (isPromise(value) && retry) {
|
|
933
|
-
let timeoutRetry;
|
|
934
|
-
return new Promise((resolve) => {
|
|
935
|
-
const run = () => {
|
|
936
|
-
value
|
|
937
|
-
.then((val) => {
|
|
938
|
-
node.activationState.persistedRetry = false;
|
|
939
|
-
resolve(val);
|
|
940
|
-
})
|
|
941
|
-
.catch(() => {
|
|
942
|
-
state.attemptNum++;
|
|
943
|
-
if (timeoutRetry) {
|
|
944
|
-
clearTimeout(timeoutRetry);
|
|
945
|
-
}
|
|
946
|
-
if (!e.cancel) {
|
|
947
|
-
timeoutRetry = createRetryTimeout(retry, state.attemptNum, () => {
|
|
948
|
-
value = fn(e);
|
|
949
|
-
run();
|
|
950
|
-
});
|
|
951
|
-
}
|
|
952
|
-
})
|
|
953
|
-
.finally(() => {
|
|
954
|
-
node.activationState.persistedRetry = false;
|
|
955
|
-
});
|
|
956
|
-
};
|
|
957
|
-
run();
|
|
958
|
-
});
|
|
959
|
-
}
|
|
960
|
-
return value;
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
const noop = () => { };
|
|
964
967
|
const ArrayModifiers = new Set([
|
|
965
968
|
'copyWithin',
|
|
966
969
|
'fill',
|
|
@@ -979,7 +982,6 @@ const ArrayLoopers = new Set([
|
|
|
979
982
|
'find',
|
|
980
983
|
'findIndex',
|
|
981
984
|
'forEach',
|
|
982
|
-
'includes',
|
|
983
985
|
'join',
|
|
984
986
|
'map',
|
|
985
987
|
'some',
|
|
@@ -1249,7 +1251,6 @@ const proxyHandler = {
|
|
|
1249
1251
|
// The exception is onChange because it needs to listen to this node for changes.
|
|
1250
1252
|
// This needs to be below peek because it activates there.
|
|
1251
1253
|
if (node.linkedToNode && p !== 'onChange') {
|
|
1252
|
-
updateTracking(node);
|
|
1253
1254
|
return proxyHandler.get(node.linkedToNode, p, receiver);
|
|
1254
1255
|
}
|
|
1255
1256
|
if (value instanceof Map || value instanceof WeakMap || value instanceof Set || value instanceof WeakSet) {
|
|
@@ -1285,20 +1286,6 @@ const proxyHandler = {
|
|
|
1285
1286
|
if (property) {
|
|
1286
1287
|
return property.get(node);
|
|
1287
1288
|
}
|
|
1288
|
-
// TODOV3 Remove this
|
|
1289
|
-
const isValuePrimitive = isPrimitive(value);
|
|
1290
|
-
// If accessing a key that doesn't already exist, and this node has been activated with extra keys
|
|
1291
|
-
// then return the values that were set. This is used by enableLegendStateReact for example.
|
|
1292
|
-
if (value === undefined || value === null || isValuePrimitive) {
|
|
1293
|
-
if (extraPrimitiveProps.size && (node.isActivatedPrimitive || extraPrimitiveActivators.has(p))) {
|
|
1294
|
-
node.isActivatedPrimitive = true;
|
|
1295
|
-
const vPrim = extraPrimitiveProps.get(p);
|
|
1296
|
-
if (vPrim !== undefined) {
|
|
1297
|
-
return isFunction(vPrim) ? vPrim(getProxy(node)) : vPrim;
|
|
1298
|
-
}
|
|
1299
|
-
}
|
|
1300
|
-
}
|
|
1301
|
-
// /TODOV3 Remove this
|
|
1302
1289
|
let vProp = value === null || value === void 0 ? void 0 : value[p];
|
|
1303
1290
|
if (isObject(value) && value[symbolOpaque]) {
|
|
1304
1291
|
return vProp;
|
|
@@ -1679,8 +1666,14 @@ function peek(node) {
|
|
|
1679
1666
|
if (lazy) {
|
|
1680
1667
|
const lazyFn = node.lazyFn;
|
|
1681
1668
|
delete node.lazy;
|
|
1682
|
-
if (isFunction(
|
|
1683
|
-
|
|
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
|
+
}
|
|
1684
1677
|
}
|
|
1685
1678
|
}
|
|
1686
1679
|
if (lazy || node.needsExtract) {
|
|
@@ -1695,10 +1688,8 @@ function peek(node) {
|
|
|
1695
1688
|
function reactivateNode(node, lazyFn) {
|
|
1696
1689
|
var _a, _b;
|
|
1697
1690
|
(_a = node.activatedObserveDispose) === null || _a === void 0 ? void 0 : _a.call(node);
|
|
1698
|
-
node.activatedObserveDispose = undefined;
|
|
1699
1691
|
(_b = node.linkedToNodeDispose) === null || _b === void 0 ? void 0 : _b.call(node);
|
|
1700
|
-
node.linkedToNodeDispose = undefined;
|
|
1701
|
-
node.linkedToNode = undefined;
|
|
1692
|
+
node.activatedObserveDispose = node.linkedToNodeDispose = node.linkedToNode = undefined;
|
|
1702
1693
|
node.lazyFn = lazyFn;
|
|
1703
1694
|
node.lazy = true;
|
|
1704
1695
|
}
|
|
@@ -1709,7 +1700,6 @@ function activateNodeFunction(node, lazyFn) {
|
|
|
1709
1700
|
let wasPromise;
|
|
1710
1701
|
let ignoreThisUpdate;
|
|
1711
1702
|
const activateFn = lazyFn;
|
|
1712
|
-
const doRetry = () => { var _a; return (_a = node.state) === null || _a === void 0 ? void 0 : _a.refreshNum.set((v) => v + 1); };
|
|
1713
1703
|
let activatedValue;
|
|
1714
1704
|
let disposes = [];
|
|
1715
1705
|
let refreshFn;
|
|
@@ -1718,7 +1708,7 @@ function activateNodeFunction(node, lazyFn) {
|
|
|
1718
1708
|
globalState.dirtyNodes.add(node);
|
|
1719
1709
|
}
|
|
1720
1710
|
node.activatedObserveDispose = observe(() => {
|
|
1721
|
-
var _a, _b, _c, _d
|
|
1711
|
+
var _a, _b, _c, _d;
|
|
1722
1712
|
// const params = createNodeActivationParams(node);
|
|
1723
1713
|
// Run the function at this node
|
|
1724
1714
|
let value = activateFn();
|
|
@@ -1740,29 +1730,25 @@ function activateNodeFunction(node, lazyFn) {
|
|
|
1740
1730
|
// TODO: Is calling recursively bad? If so can it be fixed?
|
|
1741
1731
|
if (!node.activated) {
|
|
1742
1732
|
node.activated = true;
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
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);
|
|
1747
1740
|
update = newUpdate;
|
|
1748
1741
|
value = newValue !== null && newValue !== void 0 ? newValue : activated === null || activated === void 0 ? void 0 : activated.initial;
|
|
1749
1742
|
}
|
|
1750
1743
|
else if (node.activationState) {
|
|
1751
1744
|
if (!node.activationState.persistedRetry && !node.activationState.waitFor) {
|
|
1752
1745
|
const activated = node.activationState;
|
|
1753
|
-
if ((
|
|
1746
|
+
if ((_b = (_a = node.state) === null || _a === void 0 ? void 0 : _a.peek()) === null || _b === void 0 ? void 0 : _b.sync) {
|
|
1754
1747
|
node.state.sync();
|
|
1755
1748
|
ignoreThisUpdate = true;
|
|
1756
1749
|
}
|
|
1757
1750
|
else {
|
|
1758
|
-
value =
|
|
1759
|
-
(_e = (_d = activated.get) === null || _d === void 0 ? void 0 : _d.call(activated, {
|
|
1760
|
-
updateLastSync: noop,
|
|
1761
|
-
setMode: noop,
|
|
1762
|
-
lastSync: undefined,
|
|
1763
|
-
value: undefined,
|
|
1764
|
-
refresh: doRetry,
|
|
1765
|
-
})) !== 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;
|
|
1766
1752
|
}
|
|
1767
1753
|
}
|
|
1768
1754
|
else {
|
|
@@ -1771,7 +1757,6 @@ function activateNodeFunction(node, lazyFn) {
|
|
|
1771
1757
|
}
|
|
1772
1758
|
// value is undefined if it's in a persisted retry
|
|
1773
1759
|
wasPromise = wasPromise || isPromise(value);
|
|
1774
|
-
get(getNode((_f = node.state) === null || _f === void 0 ? void 0 : _f.refreshNum));
|
|
1775
1760
|
return value;
|
|
1776
1761
|
}, (e) => {
|
|
1777
1762
|
if (!ignoreThisUpdate) {
|
|
@@ -1827,29 +1812,16 @@ function activateNodeFunction(node, lazyFn) {
|
|
|
1827
1812
|
}, { fromComputed: true });
|
|
1828
1813
|
return activatedValue;
|
|
1829
1814
|
}
|
|
1830
|
-
|
|
1815
|
+
function activateNodeBase(node, value) {
|
|
1831
1816
|
if (!node.state) {
|
|
1832
1817
|
node.state = createObservable({
|
|
1833
1818
|
isLoaded: false,
|
|
1834
1819
|
}, false, extractPromise, getProxy);
|
|
1835
1820
|
}
|
|
1836
1821
|
let isSetting = false;
|
|
1837
|
-
let isSettingFromSubscribe = false;
|
|
1838
|
-
let _mode = 'set';
|
|
1839
1822
|
if (node.activationState) {
|
|
1840
|
-
const { onSet,
|
|
1841
|
-
value = getFn
|
|
1842
|
-
? runWithRetry(node, { attemptNum: 0 }, () => {
|
|
1843
|
-
return getFn({
|
|
1844
|
-
updateLastSync: noop,
|
|
1845
|
-
setMode: (mode) => (_mode = mode),
|
|
1846
|
-
lastSync: undefined,
|
|
1847
|
-
value: undefined,
|
|
1848
|
-
refresh,
|
|
1849
|
-
});
|
|
1850
|
-
})
|
|
1851
|
-
: undefined;
|
|
1852
|
-
// 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();
|
|
1853
1825
|
if (value == undefined || value === null) {
|
|
1854
1826
|
value = initial;
|
|
1855
1827
|
}
|
|
@@ -1885,49 +1857,22 @@ const activateNodeBase = (globalState.activateNode = function activateNodeBase(n
|
|
|
1885
1857
|
// set may get called multiple times before it loads so ignore any previous runs
|
|
1886
1858
|
return;
|
|
1887
1859
|
}
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
isSetting = true;
|
|
1895
|
-
let isProm = false;
|
|
1896
|
-
batch(() => {
|
|
1897
|
-
try {
|
|
1898
|
-
const val = onSet({
|
|
1899
|
-
value,
|
|
1900
|
-
changes,
|
|
1901
|
-
getPrevious,
|
|
1902
|
-
node,
|
|
1903
|
-
update,
|
|
1904
|
-
refresh,
|
|
1905
|
-
retryNum: retryAttempts.attemptNum,
|
|
1906
|
-
cancelRetry,
|
|
1907
|
-
fromSubscribe: isSettingFromSubscribe,
|
|
1908
|
-
});
|
|
1909
|
-
isProm = isPromise(val);
|
|
1910
|
-
if (isProm) {
|
|
1911
|
-
val.then(resolve).catch(reject);
|
|
1912
|
-
}
|
|
1913
|
-
}
|
|
1914
|
-
catch (e) {
|
|
1915
|
-
reject(e);
|
|
1916
|
-
}
|
|
1917
|
-
}, () => {
|
|
1918
|
-
if (!isProm) {
|
|
1919
|
-
isSetting = false;
|
|
1920
|
-
resolve();
|
|
1921
|
-
}
|
|
1922
|
-
});
|
|
1860
|
+
isSetting = true;
|
|
1861
|
+
batch(() => {
|
|
1862
|
+
onSet({
|
|
1863
|
+
value,
|
|
1864
|
+
changes,
|
|
1865
|
+
getPrevious,
|
|
1923
1866
|
});
|
|
1867
|
+
}, () => {
|
|
1868
|
+
isSetting = false;
|
|
1924
1869
|
});
|
|
1925
1870
|
};
|
|
1926
1871
|
whenReady(node.state.isLoaded, run);
|
|
1927
1872
|
}
|
|
1928
1873
|
};
|
|
1929
1874
|
const onChangeImmediate = ({ value, changes }) => {
|
|
1930
|
-
if (!isSetting
|
|
1875
|
+
if (!isSetting) {
|
|
1931
1876
|
if (changes.length > 1 || !isFunction(changes[0].prevAtPath)) {
|
|
1932
1877
|
latestValue = value;
|
|
1933
1878
|
if (allChanges.length > 0) {
|
|
@@ -1945,68 +1890,32 @@ const activateNodeBase = (globalState.activateNode = function activateNodeBase(n
|
|
|
1945
1890
|
onChange(node, onChangeImmediate, { immediate: true });
|
|
1946
1891
|
onChange(node, runChanges);
|
|
1947
1892
|
}
|
|
1948
|
-
if (process.env.NODE_ENV === 'development' && node.activationState.cache) {
|
|
1949
|
-
// TODO Better message
|
|
1950
|
-
console.log('[legend-state] Using cache without setting up persistence first');
|
|
1951
|
-
}
|
|
1952
|
-
if (process.env.NODE_ENV === 'development' && node.activationState.retry) {
|
|
1953
|
-
// TODO Better message
|
|
1954
|
-
console.log('[legend-state] Using retry without setting up persistence first');
|
|
1955
|
-
}
|
|
1956
|
-
if (subscribe) {
|
|
1957
|
-
const updateFromSubscribe = (params) => {
|
|
1958
|
-
whenReady(node.state.isLoaded, () => {
|
|
1959
|
-
isSettingFromSubscribe = true;
|
|
1960
|
-
update(params);
|
|
1961
|
-
isSettingFromSubscribe = false;
|
|
1962
|
-
});
|
|
1963
|
-
};
|
|
1964
|
-
subscribe({ node, update: updateFromSubscribe, refresh });
|
|
1965
|
-
}
|
|
1966
1893
|
}
|
|
1967
|
-
const update = ({ value
|
|
1894
|
+
const update = ({ value }) => {
|
|
1968
1895
|
// TODO: This isSetting might not be necessary? Tests still work if removing it.
|
|
1969
1896
|
// Write tests that would break it if removed? I'd guess a combination of subscribe and
|
|
1970
1897
|
if (!isSetting) {
|
|
1971
1898
|
isSetting = true;
|
|
1972
|
-
|
|
1973
|
-
assign(node, value);
|
|
1974
|
-
}
|
|
1975
|
-
else if (_mode === 'merge' || mode === 'merge') {
|
|
1976
|
-
mergeIntoObservable(getProxy(node), value);
|
|
1977
|
-
}
|
|
1978
|
-
else {
|
|
1979
|
-
set(node, value);
|
|
1980
|
-
}
|
|
1899
|
+
set(node, value);
|
|
1981
1900
|
isSetting = false;
|
|
1982
1901
|
}
|
|
1983
1902
|
};
|
|
1984
1903
|
return { update, value };
|
|
1985
|
-
}
|
|
1904
|
+
}
|
|
1986
1905
|
function setToObservable(node, value) {
|
|
1987
1906
|
var _a;
|
|
1988
1907
|
// If the computed is a proxy to another observable
|
|
1989
1908
|
// link it to the target observable
|
|
1990
1909
|
const linkedNode = getNode(value);
|
|
1991
1910
|
if (linkedNode !== node && (linkedNode === null || linkedNode === void 0 ? void 0 : linkedNode.linkedToNode) !== node) {
|
|
1992
|
-
const prevNode = node.linkedToNode;
|
|
1993
1911
|
node.linkedToNode = linkedNode;
|
|
1994
|
-
|
|
1995
|
-
linkedNode.linkedFromNodes = new Set();
|
|
1996
|
-
}
|
|
1912
|
+
linkedNode.linkedFromNodes || (linkedNode.linkedFromNodes = new Set());
|
|
1997
1913
|
linkedNode.linkedFromNodes.add(node);
|
|
1998
|
-
peek(linkedNode);
|
|
1999
1914
|
(_a = node.linkedToNodeDispose) === null || _a === void 0 ? void 0 : _a.call(node);
|
|
2000
1915
|
node.linkedToNodeDispose = onChange(linkedNode, () => {
|
|
2001
1916
|
value = peek(linkedNode);
|
|
2002
1917
|
set(node, value);
|
|
2003
|
-
}, { initial: true });
|
|
2004
|
-
// If the target observable is different then notify for the change
|
|
2005
|
-
if (prevNode) {
|
|
2006
|
-
const value = getNodeValue(linkedNode);
|
|
2007
|
-
const prevValue = getNodeValue(prevNode);
|
|
2008
|
-
notify(node, value, prevValue, 0);
|
|
2009
|
-
}
|
|
1918
|
+
}, { initial: true }, new Set([node]));
|
|
2010
1919
|
}
|
|
2011
1920
|
return value;
|
|
2012
1921
|
}
|
|
@@ -2136,14 +2045,70 @@ function event() {
|
|
|
2136
2045
|
}
|
|
2137
2046
|
|
|
2138
2047
|
function proxy(get, set) {
|
|
2139
|
-
return observable(
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
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;
|
|
2147
2112
|
}
|
|
2148
2113
|
|
|
2149
2114
|
const internal = {
|
|
@@ -2177,8 +2142,6 @@ exports.deconstructObjectWithPath = deconstructObjectWithPath;
|
|
|
2177
2142
|
exports.endBatch = endBatch;
|
|
2178
2143
|
exports.endTracking = endTracking;
|
|
2179
2144
|
exports.event = event;
|
|
2180
|
-
exports.extraPrimitiveActivators = extraPrimitiveActivators;
|
|
2181
|
-
exports.extraPrimitiveProps = extraPrimitiveProps;
|
|
2182
2145
|
exports.findIDKey = findIDKey;
|
|
2183
2146
|
exports.getNode = getNode;
|
|
2184
2147
|
exports.getNodeValue = getNodeValue;
|