@legendapp/state 2.2.0-next.7 → 2.2.0-next.71
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/README.md +4 -2
- package/babel.js.map +1 -1
- package/config/enable$get.d.ts +8 -0
- package/config/enable$get.js +24 -0
- package/config/enable$get.js.map +1 -0
- package/config/enable$get.mjs +21 -0
- package/config/enable$get.mjs.map +1 -0
- package/config/enableReactComponents.js.map +1 -1
- package/config/enableReactComponents.mjs.map +1 -1
- package/config/enableReactNativeComponents.js.map +1 -1
- package/config/enableReactNativeComponents.mjs.map +1 -1
- package/config/enableReactTracking.d.ts +0 -9
- package/config/enableReactTracking.js.map +1 -1
- package/config/enableReactTracking.mjs.map +1 -1
- package/config/enableReactUse.d.ts +1 -1
- package/config/enableReactUse.js +1 -0
- package/config/enableReactUse.js.map +1 -1
- package/config/enableReactUse.mjs +1 -0
- package/config/enableReactUse.mjs.map +1 -1
- package/config/enable_peek.d.ts +8 -0
- package/config/{enableDirectPeek.js → enable_peek.js} +6 -3
- package/config/enable_peek.js.map +1 -0
- package/config/{enableDirectPeek.mjs → enable_peek.mjs} +5 -3
- package/config/enable_peek.mjs.map +1 -0
- package/helpers/fetch.d.ts +4 -3
- package/helpers/fetch.js.map +1 -1
- package/helpers/fetch.mjs.map +1 -1
- package/helpers/pageHash.js.map +1 -1
- package/helpers/pageHash.mjs.map +1 -1
- package/helpers/pageHashParams.js.map +1 -1
- package/helpers/pageHashParams.mjs.map +1 -1
- package/helpers/time.d.ts +2 -2
- package/helpers/time.js.map +1 -1
- package/helpers/time.mjs.map +1 -1
- package/history.js +2 -2
- package/history.js.map +1 -1
- package/history.mjs +3 -3
- package/history.mjs.map +1 -1
- package/index.d.ts +30 -9
- package/index.js +877 -661
- package/index.js.map +1 -1
- package/index.mjs +874 -658
- package/index.mjs.map +1 -1
- package/package.json +22 -25
- package/persist-plugins/async-storage.d.ts +3 -3
- package/persist-plugins/async-storage.js +8 -7
- package/persist-plugins/async-storage.js.map +1 -1
- package/persist-plugins/async-storage.mjs +9 -8
- package/persist-plugins/async-storage.mjs.map +1 -1
- package/persist-plugins/fetch.js.map +1 -1
- package/persist-plugins/fetch.mjs.map +1 -1
- package/persist-plugins/firebase.d.ts +1 -1
- package/persist-plugins/firebase.js +12 -11
- package/persist-plugins/firebase.js.map +1 -1
- package/persist-plugins/firebase.mjs +13 -12
- package/persist-plugins/firebase.mjs.map +1 -1
- package/persist-plugins/indexeddb.d.ts +10 -10
- package/persist-plugins/indexeddb.js +2 -2
- package/persist-plugins/indexeddb.js.map +1 -1
- package/persist-plugins/indexeddb.mjs +2 -2
- package/persist-plugins/indexeddb.mjs.map +1 -1
- package/persist-plugins/local-storage.d.ts +3 -4
- package/persist-plugins/local-storage.js +19 -7
- package/persist-plugins/local-storage.js.map +1 -1
- package/persist-plugins/local-storage.mjs +20 -9
- package/persist-plugins/local-storage.mjs.map +1 -1
- package/persist-plugins/mmkv.d.ts +8 -8
- package/persist-plugins/mmkv.js +5 -4
- package/persist-plugins/mmkv.js.map +1 -1
- package/persist-plugins/mmkv.mjs +6 -5
- package/persist-plugins/mmkv.mjs.map +1 -1
- package/persist-plugins/query.js.map +1 -1
- package/persist-plugins/query.mjs.map +1 -1
- package/persist.d.ts +2 -14
- package/persist.js +1250 -268
- package/persist.js.map +1 -1
- package/persist.mjs +1250 -269
- 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/useHover.js.map +1 -1
- package/react-hooks/useHover.mjs.map +1 -1
- package/react-hooks/useMeasure.js.map +1 -1
- package/react-hooks/useMeasure.mjs.map +1 -1
- package/react-hooks/useObservableNextRouter.js.map +1 -1
- package/react-hooks/useObservableNextRouter.mjs.map +1 -1
- package/react-hooks/useObservableQuery.js.map +1 -1
- package/react-hooks/useObservableQuery.mjs.map +1 -1
- package/react-hooks/usePersistedObservable.d.ts +5 -3
- package/react-hooks/usePersistedObservable.js +5 -2
- package/react-hooks/usePersistedObservable.js.map +1 -1
- package/react-hooks/usePersistedObservable.mjs +5 -2
- package/react-hooks/usePersistedObservable.mjs.map +1 -1
- package/react.js +61 -75
- package/react.js.map +1 -1
- package/react.mjs +61 -75
- package/react.mjs.map +1 -1
- package/src/ObservableObject.ts +1184 -0
- package/src/ObservablePrimitive.ts +62 -0
- package/src/babel/index.ts +70 -0
- package/src/batching.ts +372 -0
- package/src/computed.ts +16 -0
- package/src/config/enable$get.ts +30 -0
- package/src/config/enableReactComponents.ts +26 -0
- package/src/config/enableReactNativeComponents.ts +102 -0
- package/src/config/enableReactTracking.ts +60 -0
- package/src/config/enableReactUse.ts +23 -0
- package/src/config/enable_peek.ts +31 -0
- package/src/config.ts +47 -0
- package/src/createObservable.ts +46 -0
- package/src/event.ts +26 -0
- package/src/globals.ts +224 -0
- package/src/helpers/fetch.ts +26 -0
- package/src/helpers/pageHash.ts +41 -0
- package/src/helpers/pageHashParams.ts +55 -0
- package/src/helpers/time.ts +30 -0
- package/src/helpers.ts +221 -0
- package/src/history/trackHistory.ts +29 -0
- package/src/is.ts +56 -0
- package/src/linked.ts +6 -0
- package/src/observable.ts +32 -0
- package/src/observableInterfaces.ts +165 -0
- package/src/observableTypes.ts +221 -0
- package/src/observe.ts +89 -0
- package/src/onChange.ts +136 -0
- package/src/persist/configureObservablePersistence.ts +7 -0
- package/src/persist/fieldTransformer.ts +149 -0
- package/src/persist/observablePersistRemoteFunctionsAdapter.ts +39 -0
- package/src/persist/persistObservable.ts +1029 -0
- package/src/persist-plugins/async-storage.ts +102 -0
- package/src/persist-plugins/fetch.ts +33 -0
- package/src/persist-plugins/firebase.ts +1050 -0
- package/src/persist-plugins/indexeddb.ts +433 -0
- package/src/persist-plugins/local-storage.ts +90 -0
- package/src/persist-plugins/mmkv.ts +90 -0
- package/src/persist-plugins/query.ts +133 -0
- package/src/persistTypes.ts +226 -0
- package/src/proxy.ts +28 -0
- package/src/react/Computed.tsx +7 -0
- package/src/react/For.tsx +116 -0
- package/src/react/Memo.tsx +4 -0
- package/src/react/Reactive.tsx +53 -0
- package/src/react/Show.tsx +33 -0
- package/src/react/Switch.tsx +43 -0
- package/src/react/react-globals.ts +3 -0
- package/src/react/{reactInterfaces.d.ts → reactInterfaces.ts} +15 -7
- package/src/react/reactive-observer.tsx +210 -0
- package/src/react/useComputed.ts +36 -0
- package/src/react/useEffectOnce.ts +41 -0
- package/src/react/useIsMounted.ts +16 -0
- package/src/react/useMount.ts +15 -0
- package/src/react/useObservable.ts +24 -0
- package/src/react/useObservableReducer.ts +52 -0
- package/src/react/useObservableState.ts +30 -0
- package/src/react/useObserve.ts +54 -0
- package/src/react/useObserveEffect.ts +40 -0
- package/src/react/usePauseProvider.tsx +13 -0
- package/src/react/useSelector.ts +167 -0
- package/src/react/useUnmount.ts +8 -0
- package/src/react/useWhen.ts +9 -0
- package/src/react-hooks/createObservableHook.ts +53 -0
- package/src/react-hooks/useFetch.ts +16 -0
- package/src/react-hooks/useHover.ts +40 -0
- package/src/react-hooks/useMeasure.ts +48 -0
- package/src/react-hooks/useObservableNextRouter.ts +137 -0
- package/src/react-hooks/useObservableQuery.ts +205 -0
- package/src/react-hooks/usePersistedObservable.ts +24 -0
- package/src/retry.ts +69 -0
- package/src/setupTracking.ts +26 -0
- package/src/sync/activateSyncedNode.ts +146 -0
- package/src/sync/configureObservableSync.ts +7 -0
- package/src/sync/syncHelpers.ts +15 -0
- package/src/sync/syncObservable.ts +989 -0
- package/src/sync/syncObservableAdapter.ts +30 -0
- package/src/sync/synced.ts +20 -0
- package/src/sync-plugins/fetch.ts +42 -0
- package/src/syncTypes.ts +163 -0
- package/src/trace/traceHelpers.ts +11 -0
- package/src/trace/useTraceListeners.ts +34 -0
- package/src/trace/useTraceUpdates.ts +24 -0
- package/src/trace/useVerifyNotTracking.ts +33 -0
- package/src/trace/useVerifyOneRender.ts +10 -0
- package/src/trackSelector.ts +52 -0
- package/src/tracking.ts +43 -0
- package/src/types/babel.d.ts +12 -0
- package/src/when.ts +70 -0
- package/sync-plugins/fetch.d.ts +11 -0
- package/sync-plugins/fetch.js +24 -0
- package/sync-plugins/fetch.js.map +1 -0
- package/sync-plugins/fetch.mjs +22 -0
- package/sync-plugins/fetch.mjs.map +1 -0
- package/sync.d.ts +8 -0
- package/sync.js +919 -0
- package/sync.js.map +1 -0
- package/sync.mjs +912 -0
- package/sync.mjs.map +1 -0
- package/trace.js +13 -10
- package/trace.js.map +1 -1
- package/trace.mjs +11 -8
- package/trace.mjs.map +1 -1
- package/types/babel.d.ts +3 -3
- package/config/enableDirectAccess.d.ts +0 -7
- package/config/enableDirectAccess.js +0 -25
- package/config/enableDirectAccess.js.map +0 -1
- package/config/enableDirectAccess.mjs +0 -23
- package/config/enableDirectAccess.mjs.map +0 -1
- package/config/enableDirectPeek.d.ts +0 -7
- package/config/enableDirectPeek.js.map +0 -1
- package/config/enableDirectPeek.mjs.map +0 -1
- 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/ObservableObject.d.ts +0 -14
- package/src/ObservablePrimitive.d.ts +0 -7
- package/src/babel/index.d.ts +0 -17
- package/src/batching.d.ts +0 -6
- package/src/computed.d.ts +0 -4
- package/src/config/enableDirectAccess.d.ts +0 -7
- package/src/config/enableDirectPeek.d.ts +0 -7
- package/src/config/enableReactComponents.d.ts +0 -7
- package/src/config/enableReactDirectRender.d.ts +0 -2
- package/src/config/enableReactNativeComponents.d.ts +0 -20
- package/src/config/enableReactTracking.d.ts +0 -15
- package/src/config/enableReactUse.d.ts +0 -7
- package/src/config.d.ts +0 -8
- package/src/createObservable.d.ts +0 -2
- package/src/event.d.ts +0 -2
- package/src/globals.d.ts +0 -32
- package/src/helpers/fetch.d.ts +0 -6
- package/src/helpers/pageHash.d.ts +0 -7
- package/src/helpers/pageHashParams.d.ts +0 -7
- package/src/helpers/time.d.ts +0 -3
- package/src/helpers.d.ts +0 -13
- package/src/history/trackHistory.d.ts +0 -4
- package/src/is.d.ts +0 -10
- package/src/observable.d.ts +0 -16
- package/src/observableInterfaces.d.ts +0 -456
- package/src/observe.d.ts +0 -6
- package/src/onChange.d.ts +0 -7
- package/src/persist/configureObservablePersistence.d.ts +0 -3
- package/src/persist/fieldTransformer.d.ts +0 -8
- package/src/persist/observablePersistRemoteFunctionsAdapter.d.ts +0 -2
- package/src/persist/persistActivateNode.d.ts +0 -1
- package/src/persist/persistHelpers.d.ts +0 -1
- package/src/persist/persistObservable.d.ts +0 -25
- package/src/persist-plugins/async-storage.d.ts +0 -14
- package/src/persist-plugins/fetch.d.ts +0 -10
- package/src/persist-plugins/firebase.d.ts +0 -51
- package/src/persist-plugins/indexeddb.d.ts +0 -25
- package/src/persist-plugins/local-storage.d.ts +0 -21
- package/src/persist-plugins/mmkv.d.ts +0 -14
- package/src/persist-plugins/query.d.ts +0 -18
- package/src/proxy.d.ts +0 -5
- package/src/react/Computed.d.ts +0 -5
- package/src/react/For.d.ts +0 -15
- package/src/react/Memo.d.ts +0 -3
- package/src/react/Reactive.d.ts +0 -9
- package/src/react/Show.d.ts +0 -18
- package/src/react/Switch.d.ts +0 -14
- package/src/react/react-globals.d.ts +0 -3
- package/src/react/reactive-observer.d.ts +0 -14
- package/src/react/useComputed.d.ts +0 -5
- package/src/react/useEffectOnce.d.ts +0 -1
- package/src/react/useIsMounted.d.ts +0 -2
- package/src/react/useMount.d.ts +0 -2
- package/src/react/useObservable.d.ts +0 -9
- package/src/react/useObservableReducer.d.ts +0 -7
- package/src/react/useObservableState.d.ts +0 -2
- package/src/react/useObserve.d.ts +0 -4
- package/src/react/useObserveEffect.d.ts +0 -4
- package/src/react/usePauseProvider.d.ts +0 -8
- package/src/react/useSelector.d.ts +0 -3
- package/src/react/useUnmount.d.ts +0 -2
- package/src/react/useWhen.d.ts +0 -3
- package/src/react-hooks/createObservableHook.d.ts +0 -2
- package/src/react-hooks/useFetch.d.ts +0 -6
- package/src/react-hooks/useHover.d.ts +0 -3
- package/src/react-hooks/useMeasure.d.ts +0 -6
- package/src/react-hooks/useObservableNextRouter.d.ts +0 -33
- package/src/react-hooks/useObservableQuery.d.ts +0 -6
- package/src/react-hooks/usePersistedObservable.d.ts +0 -11
- package/src/retry.d.ts +0 -9
- package/src/setupTracking.d.ts +0 -2
- package/src/trace/traceHelpers.d.ts +0 -2
- package/src/trace/useTraceListeners.d.ts +0 -1
- package/src/trace/useTraceUpdates.d.ts +0 -1
- package/src/trace/useVerifyNotTracking.d.ts +0 -1
- package/src/trace/useVerifyOneRender.d.ts +0 -1
- package/src/trackSelector.d.ts +0 -7
- package/src/tracking.d.ts +0 -13
- package/src/when.d.ts +0 -3
package/index.mjs
CHANGED
|
@@ -6,14 +6,17 @@ function isString(obj) {
|
|
|
6
6
|
return typeof obj === 'string';
|
|
7
7
|
}
|
|
8
8
|
function isObject(obj) {
|
|
9
|
-
return !!obj && typeof obj === 'object' && !isArray(obj);
|
|
9
|
+
return !!obj && typeof obj === 'object' && !(obj instanceof Date) && !isArray(obj);
|
|
10
10
|
}
|
|
11
11
|
function isFunction(obj) {
|
|
12
12
|
return typeof obj === 'function';
|
|
13
13
|
}
|
|
14
14
|
function isPrimitive(arg) {
|
|
15
15
|
const type = typeof arg;
|
|
16
|
-
return arg !== undefined && type !== 'object' && type !== 'function';
|
|
16
|
+
return arg !== undefined && (isDate(arg) || (type !== 'object' && type !== 'function'));
|
|
17
|
+
}
|
|
18
|
+
function isDate(obj) {
|
|
19
|
+
return obj instanceof Date;
|
|
17
20
|
}
|
|
18
21
|
function isSymbol(obj) {
|
|
19
22
|
return typeof obj === 'symbol';
|
|
@@ -38,6 +41,9 @@ function isEmpty(obj) {
|
|
|
38
41
|
}
|
|
39
42
|
return true;
|
|
40
43
|
}
|
|
44
|
+
function isNullOrUndefined(value) {
|
|
45
|
+
return value === undefined || value === null;
|
|
46
|
+
}
|
|
41
47
|
const setPrimitives = new Set(['boolean', 'string', 'number']);
|
|
42
48
|
/** @internal */
|
|
43
49
|
function isActualPrimitive(arg) {
|
|
@@ -53,72 +59,110 @@ const symbolGetNode = Symbol('getNode');
|
|
|
53
59
|
const symbolDelete = /* @__PURE__ */ Symbol('delete');
|
|
54
60
|
const symbolOpaque = Symbol('opaque');
|
|
55
61
|
const optimized = Symbol('optimized');
|
|
56
|
-
|
|
57
|
-
const extraPrimitiveActivators = new Map();
|
|
58
|
-
const extraPrimitiveProps = new Map();
|
|
62
|
+
const symbolLinked = Symbol('linked');
|
|
59
63
|
const globalState = {
|
|
60
64
|
isLoadingLocal: false,
|
|
61
65
|
isMerging: false,
|
|
62
|
-
isLoadingRemote
|
|
63
|
-
|
|
66
|
+
isLoadingRemote: false,
|
|
67
|
+
activateSyncedNode: undefined,
|
|
68
|
+
pendingNodes: new Map(),
|
|
69
|
+
dirtyNodes: new Set(),
|
|
70
|
+
replacer: undefined,
|
|
71
|
+
reviver: undefined,
|
|
64
72
|
};
|
|
65
|
-
function
|
|
66
|
-
return
|
|
67
|
-
}
|
|
68
|
-
function
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
function getPathType(value) {
|
|
74
|
+
return isArray(value) ? 'array' : value instanceof Map ? 'map' : value instanceof Set ? 'set' : 'object';
|
|
75
|
+
}
|
|
76
|
+
function replacer(key, value) {
|
|
77
|
+
if (value instanceof Map) {
|
|
78
|
+
return {
|
|
79
|
+
__LSType: 'Map',
|
|
80
|
+
value: Array.from(value.entries()), // or with spread: value: [...value]
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
else if (value instanceof Set) {
|
|
84
|
+
return {
|
|
85
|
+
__LSType: 'Set',
|
|
86
|
+
value: Array.from(value), // or with spread: value: [...value]
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
else if (globalState.replacer) {
|
|
90
|
+
value = globalState.replacer(key, value);
|
|
91
|
+
}
|
|
92
|
+
return value;
|
|
71
93
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
94
|
+
const ISO8601 = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/;
|
|
95
|
+
function reviver(key, value) {
|
|
96
|
+
if (value) {
|
|
97
|
+
if (typeof value === 'string' && ISO8601.test(value)) {
|
|
98
|
+
return new Date(value);
|
|
99
|
+
}
|
|
100
|
+
if (typeof value === 'object') {
|
|
101
|
+
if (value.__LSType === 'Map') {
|
|
102
|
+
return new Map(value.value);
|
|
103
|
+
}
|
|
104
|
+
else if (value.__LSType === 'Set') {
|
|
105
|
+
return new Set(value.value);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (globalState.reviver) {
|
|
109
|
+
value = globalState.reviver(key, value);
|
|
110
|
+
}
|
|
79
111
|
}
|
|
112
|
+
return value;
|
|
113
|
+
}
|
|
114
|
+
function safeStringify(value) {
|
|
115
|
+
return JSON.stringify(value, replacer);
|
|
116
|
+
}
|
|
117
|
+
function safeParse(value) {
|
|
118
|
+
return JSON.parse(value, reviver);
|
|
119
|
+
}
|
|
120
|
+
function clone(value) {
|
|
121
|
+
return safeParse(safeStringify(value));
|
|
122
|
+
}
|
|
123
|
+
function isObservable(obs) {
|
|
124
|
+
return !!obs && !!obs[symbolGetNode];
|
|
80
125
|
}
|
|
81
126
|
function getNode(obs) {
|
|
82
127
|
return obs && obs[symbolGetNode];
|
|
83
128
|
}
|
|
84
|
-
function
|
|
129
|
+
function isEvent(obs) {
|
|
85
130
|
var _a;
|
|
131
|
+
return obs && ((_a = obs[symbolGetNode]) === null || _a === void 0 ? void 0 : _a.isEvent);
|
|
132
|
+
}
|
|
133
|
+
function setNodeValue(node, newValue) {
|
|
134
|
+
var _a, _b, _c;
|
|
86
135
|
const parentNode = (_a = node.parent) !== null && _a !== void 0 ? _a : node;
|
|
87
136
|
const key = node.parent ? node.key : '_';
|
|
88
137
|
const isDelete = newValue === symbolDelete;
|
|
89
138
|
if (isDelete)
|
|
90
139
|
newValue = undefined;
|
|
91
140
|
// Get the value of the parent
|
|
92
|
-
// const parentValue = isRoot ? node.root : ensureNodeValue(node);
|
|
93
141
|
const parentValue = node.parent ? ensureNodeValue(parentNode) : parentNode.root;
|
|
94
142
|
// Save the previous value first
|
|
95
143
|
const prevValue = parentValue[key];
|
|
96
144
|
const isFunc = isFunction(newValue);
|
|
97
145
|
// Compute newValue if newValue is a function or an observable
|
|
98
|
-
newValue = !parentNode.isAssigning && isFunc ? newValue(prevValue) : newValue;
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
node.
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
146
|
+
newValue = !parentNode.isAssigning && isFunc && !isFunction(prevValue) ? newValue(prevValue) : newValue;
|
|
147
|
+
if (!globalState.isMerging ||
|
|
148
|
+
prevValue === undefined ||
|
|
149
|
+
isFunction(prevValue) ||
|
|
150
|
+
!((_c = (_b = node.parent) === null || _b === void 0 ? void 0 : _b.functions) === null || _c === void 0 ? void 0 : _c.get(key))) {
|
|
151
|
+
try {
|
|
152
|
+
parentNode.isSetting = (parentNode.isSetting || 0) + 1;
|
|
153
|
+
// Save the new value
|
|
154
|
+
if (isDelete) {
|
|
155
|
+
delete parentValue[key];
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
parentValue[key] = newValue;
|
|
159
|
+
}
|
|
110
160
|
}
|
|
111
|
-
|
|
112
|
-
|
|
161
|
+
finally {
|
|
162
|
+
parentNode.isSetting--;
|
|
113
163
|
}
|
|
114
164
|
}
|
|
115
|
-
|
|
116
|
-
parentNode.isSetting--;
|
|
117
|
-
}
|
|
118
|
-
if (parentNode.root.locked && parentNode.root.set) {
|
|
119
|
-
parentNode.root.set(parentNode.root._);
|
|
120
|
-
}
|
|
121
|
-
return { prevValue, newValue, parentValue };
|
|
165
|
+
return { prevValue, newValue };
|
|
122
166
|
}
|
|
123
167
|
const arrNodeKeys = [];
|
|
124
168
|
function getNodeValue(node) {
|
|
@@ -135,14 +179,8 @@ function getNodeValue(node) {
|
|
|
135
179
|
}
|
|
136
180
|
return child;
|
|
137
181
|
}
|
|
138
|
-
const cloneFunction = (originalFunction) => {
|
|
139
|
-
const length = originalFunction.length;
|
|
140
|
-
return length > 1
|
|
141
|
-
? (arg1, arg2) => originalFunction(arg1, arg2)
|
|
142
|
-
: (...args) => originalFunction(...args);
|
|
143
|
-
};
|
|
144
182
|
function getChildNode(node, key, asFunction) {
|
|
145
|
-
var _a;
|
|
183
|
+
var _a, _b;
|
|
146
184
|
// Get the child by key
|
|
147
185
|
let child = (_a = node.children) === null || _a === void 0 ? void 0 : _a.get(key);
|
|
148
186
|
// Create the child node if it doesn't already exist
|
|
@@ -153,11 +191,13 @@ function getChildNode(node, key, asFunction) {
|
|
|
153
191
|
key,
|
|
154
192
|
lazy: true,
|
|
155
193
|
};
|
|
156
|
-
|
|
157
|
-
|
|
194
|
+
// Lookup functions are bound with the child key
|
|
195
|
+
if (((_b = node.lazyFn) === null || _b === void 0 ? void 0 : _b.length) === 1) {
|
|
196
|
+
asFunction = node.lazyFn.bind(node, key);
|
|
158
197
|
}
|
|
159
|
-
|
|
160
|
-
child = Object.assign(
|
|
198
|
+
if (isFunction(asFunction)) {
|
|
199
|
+
child = Object.assign(() => { }, child);
|
|
200
|
+
child.lazyFn = asFunction;
|
|
161
201
|
}
|
|
162
202
|
if (!node.children) {
|
|
163
203
|
node.children = new Map();
|
|
@@ -168,7 +208,7 @@ function getChildNode(node, key, asFunction) {
|
|
|
168
208
|
}
|
|
169
209
|
function ensureNodeValue(node) {
|
|
170
210
|
let value = getNodeValue(node);
|
|
171
|
-
if (!value) {
|
|
211
|
+
if (!value || isFunction(value)) {
|
|
172
212
|
if (isChildNodeValue(node)) {
|
|
173
213
|
const parent = ensureNodeValue(node.parent);
|
|
174
214
|
value = parent[node.key] = {};
|
|
@@ -181,17 +221,19 @@ function ensureNodeValue(node) {
|
|
|
181
221
|
}
|
|
182
222
|
function findIDKey(obj, node) {
|
|
183
223
|
var _a, _b;
|
|
184
|
-
let idKey =
|
|
185
|
-
?
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
? '
|
|
189
|
-
: '
|
|
190
|
-
? '
|
|
191
|
-
: '
|
|
192
|
-
? '
|
|
193
|
-
:
|
|
194
|
-
|
|
224
|
+
let idKey = isObservable(obj)
|
|
225
|
+
? undefined
|
|
226
|
+
: isObject(obj)
|
|
227
|
+
? 'id' in obj
|
|
228
|
+
? 'id'
|
|
229
|
+
: 'key' in obj
|
|
230
|
+
? 'key'
|
|
231
|
+
: '_id' in obj
|
|
232
|
+
? '_id'
|
|
233
|
+
: '__id' in obj
|
|
234
|
+
? '__id'
|
|
235
|
+
: undefined
|
|
236
|
+
: undefined;
|
|
195
237
|
if (!idKey && node.parent) {
|
|
196
238
|
const k = node.key + '_keyExtractor';
|
|
197
239
|
const keyExtractor = (_b = (_a = node.functions) === null || _a === void 0 ? void 0 : _a.get(k)) !== null && _b !== void 0 ? _b : getNodeValue(node.parent)[node.key + '_keyExtractor'];
|
|
@@ -201,26 +243,20 @@ function findIDKey(obj, node) {
|
|
|
201
243
|
}
|
|
202
244
|
return idKey;
|
|
203
245
|
}
|
|
204
|
-
function extractFunction(node, key, fnOrComputed
|
|
246
|
+
function extractFunction(node, key, fnOrComputed) {
|
|
205
247
|
if (!node.functions) {
|
|
206
248
|
node.functions = new Map();
|
|
207
249
|
}
|
|
208
250
|
node.functions.set(key, fnOrComputed);
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
node.root.toActivate = [];
|
|
213
|
-
}
|
|
214
|
-
node.root.toActivate.push(computedChildNode);
|
|
215
|
-
}
|
|
251
|
+
}
|
|
252
|
+
function equals(a, b) {
|
|
253
|
+
return a === b || (isDate(a) && isDate(b) && +a === +b);
|
|
216
254
|
}
|
|
217
255
|
|
|
218
256
|
let timeout;
|
|
219
257
|
let numInBatch = 0;
|
|
220
258
|
let isRunningBatch = false;
|
|
221
259
|
let didDelayEndBatch = false;
|
|
222
|
-
let _afterBatch = [];
|
|
223
|
-
let _queuedBatches = [];
|
|
224
260
|
let _batchMap = new Map();
|
|
225
261
|
function onActionTimeout() {
|
|
226
262
|
if (_batchMap.size > 0) {
|
|
@@ -239,23 +275,34 @@ function isArraySubset(mainArr, subsetArr) {
|
|
|
239
275
|
return true;
|
|
240
276
|
}
|
|
241
277
|
function createPreviousHandlerInner(value, changes) {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
278
|
+
try {
|
|
279
|
+
// Clones the current state and inject the previous data at the changed path
|
|
280
|
+
let cloned = value ? clone(value) : {};
|
|
281
|
+
for (let i = 0; i < changes.length; i++) {
|
|
282
|
+
const { path, prevAtPath } = changes[i];
|
|
283
|
+
let o = cloned;
|
|
284
|
+
if (path.length > 0) {
|
|
285
|
+
let i;
|
|
286
|
+
for (i = 0; i < path.length - 1; i++) {
|
|
287
|
+
o = o[path[i]];
|
|
288
|
+
}
|
|
289
|
+
const key = path[i];
|
|
290
|
+
if (o instanceof Map) {
|
|
291
|
+
o.set(key, prevAtPath);
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
o[key] = prevAtPath;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
cloned = prevAtPath;
|
|
251
299
|
}
|
|
252
|
-
o[path[i]] = prevAtPath;
|
|
253
|
-
}
|
|
254
|
-
else {
|
|
255
|
-
clone = prevAtPath;
|
|
256
300
|
}
|
|
301
|
+
return cloned;
|
|
302
|
+
}
|
|
303
|
+
catch (_a) {
|
|
304
|
+
return undefined;
|
|
257
305
|
}
|
|
258
|
-
return clone;
|
|
259
306
|
}
|
|
260
307
|
function createPreviousHandler(value, changes) {
|
|
261
308
|
// Create a function that generates the previous state
|
|
@@ -268,9 +315,13 @@ function createPreviousHandler(value, changes) {
|
|
|
268
315
|
function notify(node, value, prev, level, whenOptimizedOnlyIf) {
|
|
269
316
|
// Run immediate listeners if there are any
|
|
270
317
|
const changesInBatch = new Map();
|
|
271
|
-
computeChangesRecursive(changesInBatch, node,
|
|
318
|
+
computeChangesRecursive(changesInBatch, node,
|
|
319
|
+
/*loading*/ globalState.isLoadingLocal,
|
|
320
|
+
/*remote*/ globalState.isLoadingRemote, value, [], [], value, prev,
|
|
272
321
|
/*immediate*/ true, level, whenOptimizedOnlyIf);
|
|
273
|
-
|
|
322
|
+
if (changesInBatch.size) {
|
|
323
|
+
batchNotifyChanges(changesInBatch, /*immediate*/ true);
|
|
324
|
+
}
|
|
274
325
|
// Update the current batch
|
|
275
326
|
const existing = _batchMap.get(node);
|
|
276
327
|
if (existing) {
|
|
@@ -278,14 +329,21 @@ function notify(node, value, prev, level, whenOptimizedOnlyIf) {
|
|
|
278
329
|
// TODO: level, whenOptimizedOnlyIf
|
|
279
330
|
}
|
|
280
331
|
else {
|
|
281
|
-
_batchMap.set(node, {
|
|
332
|
+
_batchMap.set(node, {
|
|
333
|
+
value,
|
|
334
|
+
prev,
|
|
335
|
+
level,
|
|
336
|
+
whenOptimizedOnlyIf,
|
|
337
|
+
remote: globalState.isLoadingRemote,
|
|
338
|
+
loading: globalState.isLoadingLocal,
|
|
339
|
+
});
|
|
282
340
|
}
|
|
283
341
|
// If not in a batch run it immediately
|
|
284
342
|
if (numInBatch <= 0) {
|
|
285
343
|
runBatch();
|
|
286
344
|
}
|
|
287
345
|
}
|
|
288
|
-
function computeChangesAtNode(changesInBatch, node, value, path, pathTypes, valueAtPath, prevAtPath, immediate, level, whenOptimizedOnlyIf) {
|
|
346
|
+
function computeChangesAtNode(changesInBatch, node, loading, remote, value, path, pathTypes, valueAtPath, prevAtPath, immediate, level, whenOptimizedOnlyIf) {
|
|
289
347
|
// If there are listeners at this node compute the changes that need to be run
|
|
290
348
|
if (immediate ? node.listenersImmediate : node.listeners) {
|
|
291
349
|
const change = {
|
|
@@ -306,18 +364,21 @@ function computeChangesAtNode(changesInBatch, node, value, path, pathTypes, valu
|
|
|
306
364
|
changesInBatch.set(node, {
|
|
307
365
|
level,
|
|
308
366
|
value,
|
|
367
|
+
remote,
|
|
368
|
+
loading,
|
|
309
369
|
whenOptimizedOnlyIf,
|
|
310
370
|
changes: [change],
|
|
311
371
|
});
|
|
312
372
|
}
|
|
313
373
|
}
|
|
314
374
|
}
|
|
315
|
-
function computeChangesRecursive(changesInBatch, node, value, path, pathTypes, valueAtPath, prevAtPath, immediate, level, whenOptimizedOnlyIf) {
|
|
375
|
+
function computeChangesRecursive(changesInBatch, node, loading, remote, value, path, pathTypes, valueAtPath, prevAtPath, immediate, level, whenOptimizedOnlyIf) {
|
|
316
376
|
// Do the compute at this node
|
|
317
|
-
computeChangesAtNode(changesInBatch, node, value, path, pathTypes, valueAtPath, prevAtPath, immediate, level, whenOptimizedOnlyIf);
|
|
377
|
+
computeChangesAtNode(changesInBatch, node, loading, remote, value, path, pathTypes, valueAtPath, prevAtPath, immediate, level, whenOptimizedOnlyIf);
|
|
318
378
|
if (node.linkedFromNodes) {
|
|
319
379
|
for (const linkedFromNode of node.linkedFromNodes) {
|
|
320
|
-
|
|
380
|
+
const childNode = getNodeAtPath(linkedFromNode, path);
|
|
381
|
+
computeChangesRecursive(changesInBatch, childNode, loading, remote, valueAtPath, [], [], valueAtPath, prevAtPath, immediate, 0, whenOptimizedOnlyIf);
|
|
321
382
|
}
|
|
322
383
|
}
|
|
323
384
|
// If not root notify up through parents
|
|
@@ -325,14 +386,14 @@ function computeChangesRecursive(changesInBatch, node, value, path, pathTypes, v
|
|
|
325
386
|
const parent = node.parent;
|
|
326
387
|
if (parent) {
|
|
327
388
|
const parentValue = getNodeValue(parent);
|
|
328
|
-
computeChangesRecursive(changesInBatch, parent, parentValue, [node.key].concat(path), [(
|
|
389
|
+
computeChangesRecursive(changesInBatch, parent, loading, remote, parentValue, [node.key].concat(path), [getPathType(value)].concat(pathTypes), valueAtPath, prevAtPath, immediate, level + 1, whenOptimizedOnlyIf);
|
|
329
390
|
}
|
|
330
391
|
}
|
|
331
392
|
}
|
|
332
393
|
function batchNotifyChanges(changesInBatch, immediate) {
|
|
333
394
|
const listenersNotified = new Set();
|
|
334
395
|
// For each change in the batch, notify all of the listeners
|
|
335
|
-
changesInBatch.forEach(({ changes, level, value, whenOptimizedOnlyIf }, node) => {
|
|
396
|
+
changesInBatch.forEach(({ changes, level, value, loading, remote, whenOptimizedOnlyIf }, node) => {
|
|
336
397
|
const listeners = immediate ? node.listenersImmediate : node.listeners;
|
|
337
398
|
if (listeners) {
|
|
338
399
|
let listenerParams;
|
|
@@ -349,6 +410,8 @@ function batchNotifyChanges(changesInBatch, immediate) {
|
|
|
349
410
|
if (!noArgs && !listenerParams) {
|
|
350
411
|
listenerParams = {
|
|
351
412
|
value,
|
|
413
|
+
loading,
|
|
414
|
+
remote,
|
|
352
415
|
getPrevious: createPreviousHandler(value, changes),
|
|
353
416
|
changes,
|
|
354
417
|
};
|
|
@@ -364,32 +427,30 @@ function batchNotifyChanges(changesInBatch, immediate) {
|
|
|
364
427
|
});
|
|
365
428
|
}
|
|
366
429
|
function runBatch() {
|
|
430
|
+
const dirtyNodes = Array.from(globalState.dirtyNodes);
|
|
431
|
+
globalState.dirtyNodes.clear();
|
|
432
|
+
dirtyNodes.forEach((node) => {
|
|
433
|
+
var _a;
|
|
434
|
+
(_a = node.dirtyFn) === null || _a === void 0 ? void 0 : _a.call(node);
|
|
435
|
+
node.dirtyFn = undefined;
|
|
436
|
+
});
|
|
367
437
|
// Save batch locally and reset _batchMap first because a new batch could begin while looping over callbacks.
|
|
368
|
-
// This can happen with
|
|
438
|
+
// This can happen with computeds for example.
|
|
369
439
|
const map = _batchMap;
|
|
370
440
|
_batchMap = new Map();
|
|
371
441
|
const changesInBatch = new Map();
|
|
372
442
|
// First compute all of the changes at each node. It's important to do this first before
|
|
373
443
|
// running all the notifications because createPreviousHandler depends on knowing
|
|
374
444
|
// all of the changes happening at the node.
|
|
375
|
-
map.forEach(({ value, prev, level, whenOptimizedOnlyIf }, node) => {
|
|
376
|
-
computeChangesRecursive(changesInBatch, node, value, [], [], value, prev, false, level, whenOptimizedOnlyIf);
|
|
445
|
+
map.forEach(({ value, prev, level, loading, remote, whenOptimizedOnlyIf }, node) => {
|
|
446
|
+
computeChangesRecursive(changesInBatch, node, loading, remote, value, [], [], value, prev, false, level, whenOptimizedOnlyIf);
|
|
377
447
|
});
|
|
378
448
|
// Once all changes are computed, notify all listeners for each node with the computed changes.
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
function batch(fn, onComplete) {
|
|
382
|
-
if (onComplete) {
|
|
383
|
-
// If there's an onComplete we need a batch that's fully isolated from others to ensure it wraps only the given changes.
|
|
384
|
-
// So if already batching, push this batch onto a queue and run it after the current batch is fully done.
|
|
385
|
-
if (isRunningBatch) {
|
|
386
|
-
_queuedBatches.push([fn, onComplete]);
|
|
387
|
-
return;
|
|
388
|
-
}
|
|
389
|
-
else {
|
|
390
|
-
_afterBatch.push(onComplete);
|
|
391
|
-
}
|
|
449
|
+
if (changesInBatch.size) {
|
|
450
|
+
batchNotifyChanges(changesInBatch, false);
|
|
392
451
|
}
|
|
452
|
+
}
|
|
453
|
+
function batch(fn) {
|
|
393
454
|
beginBatch();
|
|
394
455
|
try {
|
|
395
456
|
fn();
|
|
@@ -418,45 +479,57 @@ function endBatch(force) {
|
|
|
418
479
|
timeout = undefined;
|
|
419
480
|
}
|
|
420
481
|
numInBatch = 0;
|
|
421
|
-
// Save batch locally and reset _batch first because a new batch could begin while looping over callbacks.
|
|
422
|
-
// This can happen with observableComputed for example.
|
|
423
|
-
const after = _afterBatch;
|
|
424
|
-
if (after.length) {
|
|
425
|
-
_afterBatch = [];
|
|
426
|
-
}
|
|
427
482
|
isRunningBatch = true;
|
|
428
483
|
runBatch();
|
|
429
484
|
isRunningBatch = false;
|
|
430
|
-
// Run after functions at the end of this batch before running the next batch.
|
|
431
|
-
// This needs to run before the delayed endBatch because the after functions need
|
|
432
|
-
// to run before any side effects of the batch
|
|
433
|
-
for (let i = 0; i < after.length; i++) {
|
|
434
|
-
after[i]();
|
|
435
|
-
}
|
|
436
485
|
// If an endBatch was delayed run it now
|
|
437
486
|
if (didDelayEndBatch) {
|
|
438
487
|
didDelayEndBatch = false;
|
|
439
488
|
endBatch(true);
|
|
440
489
|
}
|
|
441
|
-
const queued = _queuedBatches;
|
|
442
|
-
if (queued.length) {
|
|
443
|
-
_queuedBatches = [];
|
|
444
|
-
for (let i = 0; i < queued.length; i++) {
|
|
445
|
-
const [fn, onComplete] = queued[i];
|
|
446
|
-
batch(fn, onComplete);
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
490
|
}
|
|
450
491
|
}
|
|
451
492
|
}
|
|
493
|
+
function getNodeAtPath(obj, path) {
|
|
494
|
+
let o = obj;
|
|
495
|
+
for (let i = 0; i < path.length; i++) {
|
|
496
|
+
const p = path[i];
|
|
497
|
+
o = getChildNode(o, p);
|
|
498
|
+
}
|
|
499
|
+
return o;
|
|
500
|
+
}
|
|
452
501
|
|
|
453
|
-
function
|
|
454
|
-
|
|
455
|
-
|
|
502
|
+
function createObservable(value, makePrimitive, extractPromise, createObject, createPrimitive) {
|
|
503
|
+
if (isObservable(value)) {
|
|
504
|
+
return value;
|
|
505
|
+
}
|
|
506
|
+
const valueIsPromise = isPromise(value);
|
|
507
|
+
const valueIsFunction = isFunction(value);
|
|
508
|
+
const root = {
|
|
509
|
+
_: value,
|
|
510
|
+
};
|
|
511
|
+
let node = {
|
|
512
|
+
root,
|
|
513
|
+
lazy: true,
|
|
514
|
+
};
|
|
515
|
+
if (valueIsFunction) {
|
|
516
|
+
node = Object.assign(() => { }, node);
|
|
517
|
+
node.lazyFn = value;
|
|
518
|
+
}
|
|
519
|
+
const prim = makePrimitive || isActualPrimitive(value);
|
|
520
|
+
const obs = prim
|
|
521
|
+
? new createPrimitive(node)
|
|
522
|
+
: createObject(node);
|
|
523
|
+
if (valueIsPromise) {
|
|
524
|
+
setNodeValue(node, undefined);
|
|
525
|
+
extractPromise(node, value);
|
|
526
|
+
}
|
|
527
|
+
return obs;
|
|
456
528
|
}
|
|
529
|
+
|
|
457
530
|
function computeSelector(selector, e, retainObservable) {
|
|
458
531
|
let c = selector;
|
|
459
|
-
if (isFunction(c)) {
|
|
532
|
+
if (!isObservable(c) && isFunction(c)) {
|
|
460
533
|
c = e ? c(e) : c();
|
|
461
534
|
}
|
|
462
535
|
return isObservable(c) && !retainObservable ? c.get() : c;
|
|
@@ -472,45 +545,49 @@ function opaqueObject(value) {
|
|
|
472
545
|
}
|
|
473
546
|
return value;
|
|
474
547
|
}
|
|
475
|
-
function
|
|
476
|
-
var _a;
|
|
477
|
-
const root = (_a = getNode(obs)) === null || _a === void 0 ? void 0 : _a.root;
|
|
478
|
-
if (root) {
|
|
479
|
-
root.locked = value;
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
function setAtPath(obj, path, pathTypes, value, fullObj, restore) {
|
|
548
|
+
function setAtPath(obj, path, pathTypes, value, mode, fullObj, restore) {
|
|
483
549
|
let o = obj;
|
|
484
550
|
let oFull = fullObj;
|
|
551
|
+
let p = undefined;
|
|
485
552
|
if (path.length > 0) {
|
|
486
553
|
for (let i = 0; i < path.length; i++) {
|
|
487
|
-
|
|
488
|
-
if (
|
|
489
|
-
// Don't set if the value is the same. This prevents creating a new key
|
|
490
|
-
// when setting undefined on an object without this key
|
|
491
|
-
if (o[p] !== value) {
|
|
492
|
-
o[p] = value;
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
else if (o[p] === symbolDelete) {
|
|
554
|
+
p = path[i];
|
|
555
|
+
if (o[p] === symbolDelete) {
|
|
496
556
|
// If this was previously deleted, restore it
|
|
497
557
|
if (oFull) {
|
|
498
558
|
o[p] = oFull[p];
|
|
499
559
|
restore === null || restore === void 0 ? void 0 : restore(path.slice(0, i + 1), o[p]);
|
|
500
560
|
}
|
|
501
|
-
|
|
561
|
+
return obj;
|
|
502
562
|
}
|
|
503
563
|
else if (o[p] === undefined || o[p] === null) {
|
|
504
|
-
o[p] = pathTypes[i]
|
|
564
|
+
o[p] = initializePathType(pathTypes[i]);
|
|
505
565
|
}
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
oFull
|
|
566
|
+
if (i < path.length - 1) {
|
|
567
|
+
o = o[p];
|
|
568
|
+
if (oFull) {
|
|
569
|
+
oFull = oFull[p];
|
|
570
|
+
}
|
|
509
571
|
}
|
|
510
572
|
}
|
|
511
573
|
}
|
|
574
|
+
// Don't set if the value is the same. This prevents creating a new key
|
|
575
|
+
// when setting undefined on an object without this key
|
|
576
|
+
if (p === undefined) {
|
|
577
|
+
if (mode === 'merge') {
|
|
578
|
+
obj = _mergeIntoObservable(obj, value);
|
|
579
|
+
}
|
|
580
|
+
else {
|
|
581
|
+
obj = value;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
512
584
|
else {
|
|
513
|
-
|
|
585
|
+
if (mode === 'merge') {
|
|
586
|
+
o[p] = _mergeIntoObservable(o[p], value);
|
|
587
|
+
}
|
|
588
|
+
else {
|
|
589
|
+
o[p] = value;
|
|
590
|
+
}
|
|
514
591
|
}
|
|
515
592
|
return obj;
|
|
516
593
|
}
|
|
@@ -519,8 +596,8 @@ function setInObservableAtPath(obs, path, pathTypes, value, mode) {
|
|
|
519
596
|
let v = value;
|
|
520
597
|
for (let i = 0; i < path.length; i++) {
|
|
521
598
|
const p = path[i];
|
|
522
|
-
if (!o.peek()[p]
|
|
523
|
-
o[p].set([]);
|
|
599
|
+
if (!o.peek()[p]) {
|
|
600
|
+
o[p].set(initializePathType(pathTypes[i]));
|
|
524
601
|
}
|
|
525
602
|
o = o[p];
|
|
526
603
|
v = v[p];
|
|
@@ -532,6 +609,9 @@ function setInObservableAtPath(obs, path, pathTypes, value, mode) {
|
|
|
532
609
|
else if (mode === 'assign' && o.assign && isObject(o.peek())) {
|
|
533
610
|
o.assign(v);
|
|
534
611
|
}
|
|
612
|
+
else if (mode === 'merge') {
|
|
613
|
+
mergeIntoObservable(o, v);
|
|
614
|
+
}
|
|
535
615
|
else {
|
|
536
616
|
o.set(v);
|
|
537
617
|
}
|
|
@@ -561,7 +641,9 @@ function _mergeIntoObservable(target, source) {
|
|
|
561
641
|
const key = keys[i];
|
|
562
642
|
const sourceValue = source[key];
|
|
563
643
|
if (sourceValue === symbolDelete) {
|
|
564
|
-
needsSet && ((_a = target[key]) === null || _a === void 0 ? void 0 : _a.delete)
|
|
644
|
+
needsSet && ((_a = target[key]) === null || _a === void 0 ? void 0 : _a.delete)
|
|
645
|
+
? target[key].delete()
|
|
646
|
+
: delete target[key];
|
|
565
647
|
}
|
|
566
648
|
else {
|
|
567
649
|
const isObj = isObject(sourceValue);
|
|
@@ -594,7 +676,7 @@ function constructObjectWithPath(path, pathTypes, value) {
|
|
|
594
676
|
let o = (out = {});
|
|
595
677
|
for (let i = 0; i < path.length; i++) {
|
|
596
678
|
const p = path[i];
|
|
597
|
-
o[p] = i === path.length - 1 ? value : pathTypes[i]
|
|
679
|
+
o[p] = i === path.length - 1 ? value : initializePathType(pathTypes[i]);
|
|
598
680
|
o = o[p];
|
|
599
681
|
}
|
|
600
682
|
}
|
|
@@ -607,7 +689,7 @@ function deconstructObjectWithPath(path, pathTypes, value) {
|
|
|
607
689
|
let o = value;
|
|
608
690
|
for (let i = 0; i < path.length; i++) {
|
|
609
691
|
const p = path[i];
|
|
610
|
-
o = o ? o[p] : pathTypes[i]
|
|
692
|
+
o = o ? o[p] : initializePathType(pathTypes[i]);
|
|
611
693
|
}
|
|
612
694
|
return o;
|
|
613
695
|
}
|
|
@@ -618,8 +700,21 @@ function setSilently(obs, newValue) {
|
|
|
618
700
|
const node = getNode(obs);
|
|
619
701
|
return setNodeValue(node, newValue).newValue;
|
|
620
702
|
}
|
|
703
|
+
function initializePathType(pathType) {
|
|
704
|
+
switch (pathType) {
|
|
705
|
+
case 'array':
|
|
706
|
+
return [];
|
|
707
|
+
case 'object':
|
|
708
|
+
return {};
|
|
709
|
+
case 'map':
|
|
710
|
+
return new Map();
|
|
711
|
+
case 'set':
|
|
712
|
+
return new Set();
|
|
713
|
+
}
|
|
714
|
+
}
|
|
621
715
|
|
|
622
|
-
function onChange(node, callback, options = {}) {
|
|
716
|
+
function onChange(node, callback, options = {}, fromLinks) {
|
|
717
|
+
var _a;
|
|
623
718
|
const { initial, immediate, noArgs } = options;
|
|
624
719
|
const { trackingType } = options;
|
|
625
720
|
let listeners = immediate ? node.listenersImmediate : node.listeners;
|
|
@@ -632,7 +727,6 @@ function onChange(node, callback, options = {}) {
|
|
|
632
727
|
node.listeners = listeners;
|
|
633
728
|
}
|
|
634
729
|
}
|
|
635
|
-
checkActivate(node);
|
|
636
730
|
const listener = {
|
|
637
731
|
listener: callback,
|
|
638
732
|
track: trackingType,
|
|
@@ -643,6 +737,8 @@ function onChange(node, callback, options = {}) {
|
|
|
643
737
|
const value = getNodeValue(node);
|
|
644
738
|
callback({
|
|
645
739
|
value,
|
|
740
|
+
loading: true,
|
|
741
|
+
remote: false,
|
|
646
742
|
changes: [
|
|
647
743
|
{
|
|
648
744
|
path: [],
|
|
@@ -654,7 +750,80 @@ function onChange(node, callback, options = {}) {
|
|
|
654
750
|
getPrevious: () => undefined,
|
|
655
751
|
});
|
|
656
752
|
}
|
|
657
|
-
|
|
753
|
+
let extraDisposes;
|
|
754
|
+
function addLinkedNodeListeners(childNode, cb = callback, from) {
|
|
755
|
+
// Don't add listeners for the same node more than once
|
|
756
|
+
if (!(fromLinks === null || fromLinks === void 0 ? void 0 : fromLinks.has(childNode))) {
|
|
757
|
+
fromLinks || (fromLinks = new Set());
|
|
758
|
+
fromLinks.add(from || node);
|
|
759
|
+
cb || (cb = callback);
|
|
760
|
+
const childOptions = {
|
|
761
|
+
trackingType: true,
|
|
762
|
+
...options,
|
|
763
|
+
};
|
|
764
|
+
// onChange for the linked node
|
|
765
|
+
extraDisposes = [...(extraDisposes || []), onChange(childNode, cb, childOptions, fromLinks)];
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
// Add listeners for linked to nodes
|
|
769
|
+
if (node.linkedToNode) {
|
|
770
|
+
addLinkedNodeListeners(node.linkedToNode);
|
|
771
|
+
}
|
|
772
|
+
// Add listeners for linked from nodes
|
|
773
|
+
(_a = node.linkedFromNodes) === null || _a === void 0 ? void 0 : _a.forEach((linkedFromNode) => addLinkedNodeListeners(linkedFromNode));
|
|
774
|
+
// Go up through the parents and add listeners for linked from nodes
|
|
775
|
+
let parent = node.parent;
|
|
776
|
+
let pathParent = [node.key];
|
|
777
|
+
while (parent) {
|
|
778
|
+
if (parent.linkedFromNodes) {
|
|
779
|
+
for (const linkedFromNode of parent.linkedFromNodes) {
|
|
780
|
+
if (!(fromLinks === null || fromLinks === void 0 ? void 0 : fromLinks.has(linkedFromNode))) {
|
|
781
|
+
const cb = createCb(linkedFromNode, pathParent, callback);
|
|
782
|
+
addLinkedNodeListeners(linkedFromNode, cb, parent);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
pathParent = [parent.key, ...pathParent];
|
|
787
|
+
parent = parent.parent;
|
|
788
|
+
}
|
|
789
|
+
return () => {
|
|
790
|
+
listeners.delete(listener);
|
|
791
|
+
extraDisposes === null || extraDisposes === void 0 ? void 0 : extraDisposes.forEach((fn) => fn());
|
|
792
|
+
};
|
|
793
|
+
}
|
|
794
|
+
function createCb(linkedFromNode, path, callback) {
|
|
795
|
+
// Create a callback for a path that calls it with the current value at the path
|
|
796
|
+
let { valueAtPath: prevAtPath } = getValueAtPath(getNodeValue(linkedFromNode), path);
|
|
797
|
+
return function ({ value: valueA, loading, remote }) {
|
|
798
|
+
const { valueAtPath, pathTypes } = getValueAtPath(valueA, path);
|
|
799
|
+
if (valueAtPath !== prevAtPath) {
|
|
800
|
+
callback({
|
|
801
|
+
value: valueAtPath,
|
|
802
|
+
loading,
|
|
803
|
+
remote,
|
|
804
|
+
changes: [
|
|
805
|
+
{
|
|
806
|
+
path,
|
|
807
|
+
pathTypes,
|
|
808
|
+
prevAtPath,
|
|
809
|
+
valueAtPath,
|
|
810
|
+
},
|
|
811
|
+
],
|
|
812
|
+
getPrevious: () => prevAtPath,
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
prevAtPath = valueAtPath;
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
function getValueAtPath(obj, path) {
|
|
819
|
+
let o = obj;
|
|
820
|
+
const pathTypes = [];
|
|
821
|
+
for (let i = 0; o && i < path.length; i++) {
|
|
822
|
+
pathTypes.push(isArray(o) ? 'array' : 'object');
|
|
823
|
+
const p = path[i];
|
|
824
|
+
o = o[p];
|
|
825
|
+
}
|
|
826
|
+
return { valueAtPath: o, pathTypes };
|
|
658
827
|
}
|
|
659
828
|
|
|
660
829
|
function setupTracking(nodes, update, noArgs, immediate) {
|
|
@@ -715,42 +884,39 @@ function updateTracking(node, track) {
|
|
|
715
884
|
|
|
716
885
|
function trackSelector(selector, update, observeEvent, observeOptions, createResubscribe) {
|
|
717
886
|
var _a;
|
|
718
|
-
let nodes;
|
|
719
|
-
let value;
|
|
720
887
|
let dispose;
|
|
721
|
-
let tracker;
|
|
722
888
|
let resubscribe;
|
|
723
889
|
let updateFn = update;
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
(_a = tracker.traceListeners) === null || _a === void 0 ? void 0 : _a.call(tracker, nodes);
|
|
738
|
-
if (tracker.traceUpdates) {
|
|
739
|
-
updateFn = tracker.traceUpdates(update);
|
|
740
|
-
}
|
|
741
|
-
// Clear tracing so it doesn't leak to other components
|
|
742
|
-
tracker.traceListeners = undefined;
|
|
743
|
-
tracker.traceUpdates = undefined;
|
|
744
|
-
}
|
|
890
|
+
beginTracking();
|
|
891
|
+
const value = selector ? computeSelector(selector, observeEvent, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.fromComputed) : selector;
|
|
892
|
+
const tracker = tracking.current;
|
|
893
|
+
const nodes = tracker.nodes;
|
|
894
|
+
endTracking();
|
|
895
|
+
if ((process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') && tracker && nodes) {
|
|
896
|
+
(_a = tracker.traceListeners) === null || _a === void 0 ? void 0 : _a.call(tracker, nodes);
|
|
897
|
+
if (tracker.traceUpdates) {
|
|
898
|
+
updateFn = tracker.traceUpdates(update);
|
|
899
|
+
}
|
|
900
|
+
// Clear tracing so it doesn't leak to other components
|
|
901
|
+
tracker.traceListeners = undefined;
|
|
902
|
+
tracker.traceUpdates = undefined;
|
|
745
903
|
}
|
|
746
904
|
if (!(observeEvent === null || observeEvent === void 0 ? void 0 : observeEvent.cancel)) {
|
|
747
905
|
// Do tracing if it was requested
|
|
748
906
|
// useSyncExternalStore doesn't subscribe until after the component mount.
|
|
749
907
|
// We want to subscribe immediately so we don't miss any updates
|
|
750
908
|
dispose = setupTracking(nodes, updateFn, false, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.immediate);
|
|
751
|
-
|
|
909
|
+
if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
|
|
910
|
+
resubscribe = createResubscribe
|
|
911
|
+
? () => {
|
|
912
|
+
dispose === null || dispose === void 0 ? void 0 : dispose();
|
|
913
|
+
dispose = setupTracking(nodes, updateFn);
|
|
914
|
+
return dispose;
|
|
915
|
+
}
|
|
916
|
+
: undefined;
|
|
917
|
+
}
|
|
752
918
|
}
|
|
753
|
-
return { value, dispose, resubscribe };
|
|
919
|
+
return { nodes, value, dispose, resubscribe };
|
|
754
920
|
}
|
|
755
921
|
|
|
756
922
|
function observe(selectorOrRun, reactionOrOptions, options) {
|
|
@@ -775,9 +941,11 @@ function observe(selectorOrRun, reactionOrOptions, options) {
|
|
|
775
941
|
delete e.value;
|
|
776
942
|
// Dispose listeners from previous run
|
|
777
943
|
dispose === null || dispose === void 0 ? void 0 : dispose();
|
|
778
|
-
const { dispose: _dispose, value } = trackSelector(selectorOrRun, update, e, options);
|
|
944
|
+
const { dispose: _dispose, value, nodes } = trackSelector(selectorOrRun, update, e, options);
|
|
779
945
|
dispose = _dispose;
|
|
780
946
|
e.value = value;
|
|
947
|
+
e.nodes = nodes;
|
|
948
|
+
e.refresh = update;
|
|
781
949
|
if (e.onCleanupReaction) {
|
|
782
950
|
e.onCleanupReaction();
|
|
783
951
|
e.onCleanupReaction = undefined;
|
|
@@ -785,7 +953,9 @@ function observe(selectorOrRun, reactionOrOptions, options) {
|
|
|
785
953
|
endBatch();
|
|
786
954
|
// Call the reaction if there is one and the value changed
|
|
787
955
|
if (reaction &&
|
|
788
|
-
((options === null || options === void 0 ? void 0 : options.fromComputed) ||
|
|
956
|
+
((options === null || options === void 0 ? void 0 : options.fromComputed) ||
|
|
957
|
+
((e.num > 0 || !isEvent(selectorOrRun)) &&
|
|
958
|
+
(e.previous !== e.value || typeof e.value === 'object')))) {
|
|
789
959
|
reaction(e);
|
|
790
960
|
}
|
|
791
961
|
// Update the previous value
|
|
@@ -811,6 +981,7 @@ function _when(predicate, effect, checkReady) {
|
|
|
811
981
|
return effect ? predicate.then(effect) : predicate;
|
|
812
982
|
}
|
|
813
983
|
let value;
|
|
984
|
+
let effectValue;
|
|
814
985
|
// Create a wrapping fn that calls the effect if predicate returns true
|
|
815
986
|
function run(e) {
|
|
816
987
|
const ret = computeSelector(predicate);
|
|
@@ -823,7 +994,7 @@ function _when(predicate, effect, checkReady) {
|
|
|
823
994
|
}
|
|
824
995
|
function doEffect() {
|
|
825
996
|
// If value is truthy then run the effect
|
|
826
|
-
effect === null || effect === void 0 ? void 0 : effect(value);
|
|
997
|
+
effectValue = effect === null || effect === void 0 ? void 0 : effect(value);
|
|
827
998
|
}
|
|
828
999
|
// Run in an observe
|
|
829
1000
|
observe(run, doEffect);
|
|
@@ -833,17 +1004,17 @@ function _when(predicate, effect, checkReady) {
|
|
|
833
1004
|
return effect ? value.then(effect) : value;
|
|
834
1005
|
}
|
|
835
1006
|
else if (value !== undefined) {
|
|
836
|
-
return Promise.resolve(value);
|
|
1007
|
+
return effect ? effectValue : Promise.resolve(value);
|
|
837
1008
|
}
|
|
838
1009
|
else {
|
|
839
1010
|
// Wrap it in a promise
|
|
840
1011
|
const promise = new Promise((resolve) => {
|
|
841
1012
|
if (effect) {
|
|
842
1013
|
const originalEffect = effect;
|
|
843
|
-
effect = (value) => {
|
|
1014
|
+
effect = ((value) => {
|
|
844
1015
|
const effectValue = originalEffect(value);
|
|
845
|
-
resolve(effectValue);
|
|
846
|
-
};
|
|
1016
|
+
resolve(isPromise(effectValue) ? effectValue.then((value) => value) : effectValue);
|
|
1017
|
+
});
|
|
847
1018
|
}
|
|
848
1019
|
else {
|
|
849
1020
|
effect = resolve;
|
|
@@ -859,64 +1030,6 @@ function whenReady(predicate, effect) {
|
|
|
859
1030
|
return _when(predicate, effect, true);
|
|
860
1031
|
}
|
|
861
1032
|
|
|
862
|
-
function createObservable(value, makePrimitive, extractPromise, createObject, createPrimitive) {
|
|
863
|
-
const valueIsPromise = isPromise(value);
|
|
864
|
-
const valueIsFunction = isFunction(value);
|
|
865
|
-
const root = {
|
|
866
|
-
_: value,
|
|
867
|
-
};
|
|
868
|
-
let node = {
|
|
869
|
-
root,
|
|
870
|
-
lazy: true,
|
|
871
|
-
};
|
|
872
|
-
if (valueIsFunction) {
|
|
873
|
-
node = Object.assign(cloneFunction(value), node);
|
|
874
|
-
}
|
|
875
|
-
const prim = makePrimitive || isActualPrimitive(value);
|
|
876
|
-
const obs = prim
|
|
877
|
-
? new createPrimitive(node)
|
|
878
|
-
: createObject(node);
|
|
879
|
-
if (valueIsPromise) {
|
|
880
|
-
setNodeValue(node, undefined);
|
|
881
|
-
extractPromise(node, value);
|
|
882
|
-
}
|
|
883
|
-
return obs;
|
|
884
|
-
}
|
|
885
|
-
|
|
886
|
-
function setupRetry(retryOptions, refresh, attemptNum) {
|
|
887
|
-
const timeout = {};
|
|
888
|
-
let didGiveUp = false;
|
|
889
|
-
const { backoff, delay = 1000, infinite, times = 3, maxDelay = 30000 } = retryOptions;
|
|
890
|
-
let handleError;
|
|
891
|
-
attemptNum.current++;
|
|
892
|
-
if (infinite || attemptNum.current < times) {
|
|
893
|
-
const delayTime = Math.min(delay * (backoff === 'constant' ? 1 : 2 ** attemptNum.current), maxDelay);
|
|
894
|
-
handleError = () => {
|
|
895
|
-
timeout.current = setTimeout(refresh, delayTime);
|
|
896
|
-
};
|
|
897
|
-
}
|
|
898
|
-
else {
|
|
899
|
-
handleError = () => {
|
|
900
|
-
didGiveUp = true;
|
|
901
|
-
};
|
|
902
|
-
}
|
|
903
|
-
if (typeof window !== 'undefined') {
|
|
904
|
-
window.addEventListener('online', () => {
|
|
905
|
-
if (didGiveUp || timeout) {
|
|
906
|
-
if (timeout) {
|
|
907
|
-
clearTimeout(timeout.current);
|
|
908
|
-
timeout.current = undefined;
|
|
909
|
-
}
|
|
910
|
-
// Restart the backoff when coming back online
|
|
911
|
-
attemptNum.current = 0;
|
|
912
|
-
didGiveUp = false;
|
|
913
|
-
refresh();
|
|
914
|
-
}
|
|
915
|
-
});
|
|
916
|
-
}
|
|
917
|
-
return { handleError, timeout };
|
|
918
|
-
}
|
|
919
|
-
|
|
920
1033
|
const ArrayModifiers = new Set([
|
|
921
1034
|
'copyWithin',
|
|
922
1035
|
'fill',
|
|
@@ -935,9 +1048,9 @@ const ArrayLoopers = new Set([
|
|
|
935
1048
|
'find',
|
|
936
1049
|
'findIndex',
|
|
937
1050
|
'forEach',
|
|
938
|
-
'includes',
|
|
939
1051
|
'join',
|
|
940
1052
|
'map',
|
|
1053
|
+
'reduce',
|
|
941
1054
|
'some',
|
|
942
1055
|
]);
|
|
943
1056
|
const ArrayLoopersReturn = new Set(['filter', 'find']);
|
|
@@ -957,7 +1070,8 @@ if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
|
|
|
957
1070
|
}
|
|
958
1071
|
function collectionSetter(node, target, prop, ...args) {
|
|
959
1072
|
var _a;
|
|
960
|
-
if (prop === 'push') {
|
|
1073
|
+
if (prop === 'push' && args.length === 1) {
|
|
1074
|
+
// Fast path for push to just append to the end
|
|
961
1075
|
setKey(node, target.length + '', args[0]);
|
|
962
1076
|
}
|
|
963
1077
|
else {
|
|
@@ -980,7 +1094,7 @@ function getKeys(obj, isArr, isMap) {
|
|
|
980
1094
|
return isArr ? undefined : obj ? (isMap ? Array.from(obj.keys()) : Object.keys(obj)) : [];
|
|
981
1095
|
}
|
|
982
1096
|
function updateNodes(parent, obj, prevValue) {
|
|
983
|
-
var _a, _b;
|
|
1097
|
+
var _a, _b, _c;
|
|
984
1098
|
if ((process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') &&
|
|
985
1099
|
typeof __devUpdateNodes !== 'undefined' &&
|
|
986
1100
|
isObject(obj)) {
|
|
@@ -1009,8 +1123,9 @@ function updateNodes(parent, obj, prevValue) {
|
|
|
1009
1123
|
let prevChildrenById;
|
|
1010
1124
|
let moved;
|
|
1011
1125
|
const isMap = obj instanceof Map;
|
|
1126
|
+
const isPrevMap = prevValue instanceof Map;
|
|
1012
1127
|
const keys = getKeys(obj, isArr, isMap);
|
|
1013
|
-
const keysPrev = getKeys(prevValue, isArr,
|
|
1128
|
+
const keysPrev = getKeys(prevValue, isArr, isPrevMap);
|
|
1014
1129
|
const length = ((_a = (keys || obj)) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
|
1015
1130
|
const lengthPrev = ((_b = (keysPrev || prevValue)) === null || _b === void 0 ? void 0 : _b.length) || 0;
|
|
1016
1131
|
let idField;
|
|
@@ -1027,15 +1142,22 @@ function updateNodes(parent, obj, prevValue) {
|
|
|
1027
1142
|
isIdFieldFunction = isFunction(idField);
|
|
1028
1143
|
prevChildrenById = new Map();
|
|
1029
1144
|
moved = [];
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1145
|
+
}
|
|
1146
|
+
const keysSeen = process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test'
|
|
1147
|
+
? new Set()
|
|
1148
|
+
: undefined;
|
|
1149
|
+
if (parent.children) {
|
|
1150
|
+
for (let i = 0; i < prevValue.length; i++) {
|
|
1151
|
+
const p = prevValue[i];
|
|
1152
|
+
if (p) {
|
|
1153
|
+
const child = parent.children.get(i + '');
|
|
1154
|
+
if (child) {
|
|
1155
|
+
if (!obj[i]) {
|
|
1156
|
+
// If the previous value is not in the new array and it
|
|
1157
|
+
// is an activated, disable its listeners
|
|
1158
|
+
handleDeletedChild(child, p);
|
|
1159
|
+
}
|
|
1160
|
+
if (idField) {
|
|
1039
1161
|
const key = isIdFieldFunction
|
|
1040
1162
|
? idField(p)
|
|
1041
1163
|
: p[idField];
|
|
@@ -1062,14 +1184,9 @@ function updateNodes(parent, obj, prevValue) {
|
|
|
1062
1184
|
if (!keys.includes(key)) {
|
|
1063
1185
|
hasADiff = true;
|
|
1064
1186
|
const child = getChildNode(parent, key);
|
|
1065
|
-
const prev =
|
|
1187
|
+
const prev = isPrevMap ? prevValue.get(key) : prevValue[key];
|
|
1066
1188
|
if (prev !== undefined) {
|
|
1067
|
-
|
|
1068
|
-
updateNodes(child, undefined, prev);
|
|
1069
|
-
}
|
|
1070
|
-
if (child.listeners || child.listenersImmediate) {
|
|
1071
|
-
notify(child, undefined, prev, 0);
|
|
1072
|
-
}
|
|
1189
|
+
handleDeletedChild(child, prev);
|
|
1073
1190
|
}
|
|
1074
1191
|
}
|
|
1075
1192
|
}
|
|
@@ -1080,16 +1197,31 @@ function updateNodes(parent, obj, prevValue) {
|
|
|
1080
1197
|
let didMove = false;
|
|
1081
1198
|
for (let i = 0; i < length; i++) {
|
|
1082
1199
|
const key = isArr ? i + '' : keys[i];
|
|
1083
|
-
|
|
1084
|
-
const prev =
|
|
1085
|
-
let isDiff = value
|
|
1200
|
+
let value = isMap ? obj.get(key) : obj[key];
|
|
1201
|
+
const prev = isPrevMap ? prevValue === null || prevValue === void 0 ? void 0 : prevValue.get(key) : prevValue === null || prevValue === void 0 ? void 0 : prevValue[key];
|
|
1202
|
+
let isDiff = !equals(value, prev);
|
|
1086
1203
|
if (isDiff) {
|
|
1087
1204
|
const id = idField && value
|
|
1088
1205
|
? isIdFieldFunction
|
|
1089
1206
|
? idField(value)
|
|
1090
1207
|
: value[idField]
|
|
1091
1208
|
: undefined;
|
|
1092
|
-
|
|
1209
|
+
const existingChild = (_c = parent.children) === null || _c === void 0 ? void 0 : _c.get(key);
|
|
1210
|
+
if (isObservable(value)) {
|
|
1211
|
+
const valueNode = getNode(value);
|
|
1212
|
+
if ((existingChild === null || existingChild === void 0 ? void 0 : existingChild.linkedToNode) === valueNode) {
|
|
1213
|
+
const targetValue = getNodeValue(valueNode);
|
|
1214
|
+
isMap ? obj.set(key, targetValue) : (obj[key] = targetValue);
|
|
1215
|
+
continue;
|
|
1216
|
+
}
|
|
1217
|
+
const obs = value;
|
|
1218
|
+
value = () => obs;
|
|
1219
|
+
}
|
|
1220
|
+
let child = getChildNode(parent, key, value);
|
|
1221
|
+
if (!child.lazy && (isFunction(value) || isObservable(value))) {
|
|
1222
|
+
reactivateNode(child, value);
|
|
1223
|
+
peekInternal(child);
|
|
1224
|
+
}
|
|
1093
1225
|
// Detect moves within an array. Need to move the original proxy to the new position to keep
|
|
1094
1226
|
// the proxy stable, so that listeners to this node will be unaffected by the array shift.
|
|
1095
1227
|
if (isArr && id !== undefined) {
|
|
@@ -1119,7 +1251,10 @@ function updateNodes(parent, obj, prevValue) {
|
|
|
1119
1251
|
if (isDiff) {
|
|
1120
1252
|
// Array has a new / modified element
|
|
1121
1253
|
// If object iterate through its children
|
|
1122
|
-
if (
|
|
1254
|
+
if (isFunction(value) || isObservable(value)) {
|
|
1255
|
+
extractFunctionOrComputed(parent, key, value);
|
|
1256
|
+
}
|
|
1257
|
+
else if (isPrimitive(value)) {
|
|
1123
1258
|
hasADiff = true;
|
|
1124
1259
|
}
|
|
1125
1260
|
else {
|
|
@@ -1160,6 +1295,19 @@ function updateNodes(parent, obj, prevValue) {
|
|
|
1160
1295
|
}
|
|
1161
1296
|
return retValue !== null && retValue !== void 0 ? retValue : false;
|
|
1162
1297
|
}
|
|
1298
|
+
function handleDeletedChild(child, p) {
|
|
1299
|
+
var _a, _b;
|
|
1300
|
+
// If the previous value is not in the new array and it
|
|
1301
|
+
// is an activated, disable its listeners
|
|
1302
|
+
(_a = child.linkedToNodeDispose) === null || _a === void 0 ? void 0 : _a.call(child);
|
|
1303
|
+
(_b = child.activatedObserveDispose) === null || _b === void 0 ? void 0 : _b.call(child);
|
|
1304
|
+
if (!isPrimitive(p)) {
|
|
1305
|
+
updateNodes(child, undefined, p);
|
|
1306
|
+
}
|
|
1307
|
+
if (child.listeners || child.listenersImmediate) {
|
|
1308
|
+
notify(child, undefined, p, 0);
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1163
1311
|
function getProxy(node, p, asFunction) {
|
|
1164
1312
|
// Get the child node if p prop
|
|
1165
1313
|
if (p !== undefined)
|
|
@@ -1167,6 +1315,15 @@ function getProxy(node, p, asFunction) {
|
|
|
1167
1315
|
// Create a proxy if not already cached and return it
|
|
1168
1316
|
return (node.proxy || (node.proxy = new Proxy(node, proxyHandler)));
|
|
1169
1317
|
}
|
|
1318
|
+
function flushPending() {
|
|
1319
|
+
// Need to short circuit the computed batching because the user called get() or peek()
|
|
1320
|
+
// in which case the set needs to run immediately so that the values are up to date.
|
|
1321
|
+
if (globalState.pendingNodes.size > 0) {
|
|
1322
|
+
const nodes = Array.from(globalState.pendingNodes.values());
|
|
1323
|
+
globalState.pendingNodes.clear();
|
|
1324
|
+
nodes.forEach((fn) => fn());
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1170
1327
|
const proxyHandler = {
|
|
1171
1328
|
get(node, p, receiver) {
|
|
1172
1329
|
var _a;
|
|
@@ -1178,12 +1335,19 @@ const proxyHandler = {
|
|
|
1178
1335
|
if (p === symbolGetNode) {
|
|
1179
1336
|
return node;
|
|
1180
1337
|
}
|
|
1181
|
-
|
|
1338
|
+
if (p === 'apply') {
|
|
1339
|
+
const nodeValue = getNodeValue(node);
|
|
1340
|
+
if (isFunction(nodeValue)) {
|
|
1341
|
+
return nodeValue.apply;
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
let value = peekInternal(node, /*activateRecursive*/ p === 'get');
|
|
1182
1345
|
// If this node is linked to another observable then forward to the target's handler.
|
|
1183
1346
|
// The exception is onChange because it needs to listen to this node for changes.
|
|
1184
1347
|
// This needs to be below peek because it activates there.
|
|
1185
|
-
|
|
1186
|
-
|
|
1348
|
+
const targetNode = node.linkedToNode || (value === null || value === void 0 ? void 0 : value[symbolGetNode]);
|
|
1349
|
+
if (targetNode && p !== 'onChange') {
|
|
1350
|
+
return proxyHandler.get(targetNode, p, receiver);
|
|
1187
1351
|
}
|
|
1188
1352
|
if (value instanceof Map || value instanceof WeakMap || value instanceof Set || value instanceof WeakSet) {
|
|
1189
1353
|
const ret = handlerMapSet(node, p, value);
|
|
@@ -1194,6 +1358,9 @@ const proxyHandler = {
|
|
|
1194
1358
|
const fn = observableFns.get(p);
|
|
1195
1359
|
// If this is an observable function, call it
|
|
1196
1360
|
if (fn) {
|
|
1361
|
+
if (p === 'get' || p === 'peek') {
|
|
1362
|
+
flushPending();
|
|
1363
|
+
}
|
|
1197
1364
|
return function (a, b, c) {
|
|
1198
1365
|
const l = arguments.length;
|
|
1199
1366
|
// Array call and apply are slow so micro-optimize this hot path.
|
|
@@ -1211,33 +1378,11 @@ const proxyHandler = {
|
|
|
1211
1378
|
}
|
|
1212
1379
|
};
|
|
1213
1380
|
}
|
|
1214
|
-
if (node.isComputed) {
|
|
1215
|
-
if (node.proxyFn && !fn) {
|
|
1216
|
-
return node.proxyFn(p);
|
|
1217
|
-
}
|
|
1218
|
-
else {
|
|
1219
|
-
checkActivate(node);
|
|
1220
|
-
}
|
|
1221
|
-
}
|
|
1222
1381
|
const property = observableProperties.get(p);
|
|
1223
1382
|
if (property) {
|
|
1224
1383
|
return property.get(node);
|
|
1225
1384
|
}
|
|
1226
|
-
|
|
1227
|
-
const isValuePrimitive = isPrimitive(value);
|
|
1228
|
-
// If accessing a key that doesn't already exist, and this node has been activated with extra keys
|
|
1229
|
-
// then return the values that were set. This is used by enableLegendStateReact for example.
|
|
1230
|
-
if (value === undefined || value === null || isValuePrimitive) {
|
|
1231
|
-
if (extraPrimitiveProps.size && (node.isActivatedPrimitive || extraPrimitiveActivators.has(p))) {
|
|
1232
|
-
node.isActivatedPrimitive = true;
|
|
1233
|
-
const vPrim = extraPrimitiveProps.get(p);
|
|
1234
|
-
if (vPrim !== undefined) {
|
|
1235
|
-
return isFunction(vPrim) ? vPrim(getProxy(node)) : vPrim;
|
|
1236
|
-
}
|
|
1237
|
-
}
|
|
1238
|
-
}
|
|
1239
|
-
// /TODOV3 Remove this
|
|
1240
|
-
const vProp = value === null || value === void 0 ? void 0 : value[p];
|
|
1385
|
+
let vProp = value === null || value === void 0 ? void 0 : value[p];
|
|
1241
1386
|
if (isObject(value) && value[symbolOpaque]) {
|
|
1242
1387
|
return vProp;
|
|
1243
1388
|
}
|
|
@@ -1250,6 +1395,11 @@ const proxyHandler = {
|
|
|
1250
1395
|
return getProxy(node, p, fnOrComputed);
|
|
1251
1396
|
}
|
|
1252
1397
|
}
|
|
1398
|
+
if (isNullOrUndefined(value) && vProp === undefined && (ArrayModifiers.has(p) || ArrayLoopers.has(p))) {
|
|
1399
|
+
value = [];
|
|
1400
|
+
setNodeValue(node, value);
|
|
1401
|
+
vProp = value[p];
|
|
1402
|
+
}
|
|
1253
1403
|
// Handle function calls
|
|
1254
1404
|
if (isFunction(vProp)) {
|
|
1255
1405
|
if (isArray(value)) {
|
|
@@ -1261,30 +1411,29 @@ const proxyHandler = {
|
|
|
1261
1411
|
// Update that this node was accessed for observers
|
|
1262
1412
|
updateTracking(node);
|
|
1263
1413
|
return function (cbOrig, thisArg) {
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1414
|
+
const isReduce = p === 'reduce';
|
|
1415
|
+
const cbWrapped = isReduce
|
|
1416
|
+
? (previousValue, currentValue, currentIndex, array) => {
|
|
1417
|
+
return cbOrig(previousValue, getProxy(node, currentIndex + '', currentValue), currentIndex, array);
|
|
1418
|
+
}
|
|
1419
|
+
: (val, index, array) => {
|
|
1420
|
+
return cbOrig(getProxy(node, index + '', val), index, array);
|
|
1421
|
+
};
|
|
1422
|
+
if (isReduce || !ArrayLoopersReturn.has(p)) {
|
|
1423
|
+
return value[p](cbWrapped, thisArg);
|
|
1267
1424
|
}
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
if (
|
|
1274
|
-
|
|
1275
|
-
if (isFind) {
|
|
1276
|
-
return proxy;
|
|
1277
|
-
}
|
|
1278
|
-
else {
|
|
1279
|
-
out.push(proxy);
|
|
1280
|
-
}
|
|
1425
|
+
const isFind = p === 'find';
|
|
1426
|
+
const out = [];
|
|
1427
|
+
for (let i = 0; i < value.length; i++) {
|
|
1428
|
+
if (cbWrapped(value[i], i, value)) {
|
|
1429
|
+
const proxy = getProxy(node, i + '');
|
|
1430
|
+
if (isFind) {
|
|
1431
|
+
return proxy;
|
|
1281
1432
|
}
|
|
1433
|
+
out.push(proxy);
|
|
1282
1434
|
}
|
|
1283
|
-
return isFind ? undefined : out;
|
|
1284
|
-
}
|
|
1285
|
-
else {
|
|
1286
|
-
return value[p](cbWrapped, thisArg);
|
|
1287
1435
|
}
|
|
1436
|
+
return isFind ? undefined : out;
|
|
1288
1437
|
};
|
|
1289
1438
|
}
|
|
1290
1439
|
}
|
|
@@ -1299,10 +1448,6 @@ const proxyHandler = {
|
|
|
1299
1448
|
return vProp;
|
|
1300
1449
|
}
|
|
1301
1450
|
}
|
|
1302
|
-
// TODOV3: Remove "state"
|
|
1303
|
-
if (vProp === undefined && (p === 'state' || p === '_state') && node.state) {
|
|
1304
|
-
return node.state;
|
|
1305
|
-
}
|
|
1306
1451
|
// Return an observable proxy to the property
|
|
1307
1452
|
return getProxy(node, p);
|
|
1308
1453
|
},
|
|
@@ -1312,12 +1457,13 @@ const proxyHandler = {
|
|
|
1312
1457
|
return value !== null && typeof value === 'object' ? Reflect.getPrototypeOf(value) : null;
|
|
1313
1458
|
},
|
|
1314
1459
|
ownKeys(node) {
|
|
1315
|
-
|
|
1460
|
+
// TODO: Temporary workaround to fix a bug - the first peek may not return the correct value
|
|
1461
|
+
// if the value is a cached. This fixes the test "cache with initial ownKeys"
|
|
1462
|
+
peekInternal(node);
|
|
1463
|
+
const value = get(node, true);
|
|
1316
1464
|
if (isPrimitive(value))
|
|
1317
1465
|
return [];
|
|
1318
1466
|
const keys = value ? Reflect.ownKeys(value) : [];
|
|
1319
|
-
// Update that this node was accessed for observers
|
|
1320
|
-
updateTracking(node, true);
|
|
1321
1467
|
// This is required to fix this error:
|
|
1322
1468
|
// TypeError: 'getOwnPropertyDescriptor' on proxy: trap reported non-configurability for
|
|
1323
1469
|
// property 'length' which is either non-existent or configurable in the proxy node
|
|
@@ -1367,22 +1513,21 @@ const proxyHandler = {
|
|
|
1367
1513
|
},
|
|
1368
1514
|
apply(target, thisArg, argArray) {
|
|
1369
1515
|
// If it's a function call it as a function
|
|
1370
|
-
return Reflect.apply(target, thisArg, argArray);
|
|
1516
|
+
return Reflect.apply(target.lazyFn || target, thisArg, argArray);
|
|
1371
1517
|
},
|
|
1372
1518
|
};
|
|
1373
1519
|
function set(node, newValue) {
|
|
1374
1520
|
if (node.parent) {
|
|
1375
|
-
|
|
1521
|
+
setKey(node.parent, node.key, newValue);
|
|
1376
1522
|
}
|
|
1377
1523
|
else {
|
|
1378
|
-
|
|
1524
|
+
setKey(node, '_', newValue);
|
|
1379
1525
|
}
|
|
1380
1526
|
}
|
|
1381
1527
|
function toggle(node) {
|
|
1382
1528
|
const value = getNodeValue(node);
|
|
1383
|
-
if (value === undefined || isBoolean(value)) {
|
|
1529
|
+
if (value === undefined || value === null || isBoolean(value)) {
|
|
1384
1530
|
set(node, !value);
|
|
1385
|
-
return !value;
|
|
1386
1531
|
}
|
|
1387
1532
|
else if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
|
|
1388
1533
|
throw new Error('[legend-state] Cannot toggle a non-boolean value');
|
|
@@ -1394,31 +1539,27 @@ function setKey(node, key, newValue, level) {
|
|
|
1394
1539
|
console.warn(`[legend-state] Set an HTMLElement into state. You probably don't want to do that.`);
|
|
1395
1540
|
}
|
|
1396
1541
|
}
|
|
1397
|
-
if (node.root.locked && !node.root.set) {
|
|
1398
|
-
// This happens when modifying a locked observable such as a computed.
|
|
1399
|
-
// If merging this could be happening deep in a hierarchy so we don't want to throw errors so we'll just do nothing.
|
|
1400
|
-
// This could happen during persistence local load for example.
|
|
1401
|
-
if (globalState.isMerging) {
|
|
1402
|
-
return;
|
|
1403
|
-
}
|
|
1404
|
-
else {
|
|
1405
|
-
throw new Error(process.env.NODE_ENV === 'development'
|
|
1406
|
-
? '[legend-state] Cannot modify an observable while it is locked. Please make sure that you unlock the observable before making changes.'
|
|
1407
|
-
: '[legend-state] Modified locked observable');
|
|
1408
|
-
}
|
|
1409
|
-
}
|
|
1410
1542
|
const isRoot = !node.parent && key === '_';
|
|
1543
|
+
if (node.parent && !getNodeValue(node) && !isFunction(newValue)) {
|
|
1544
|
+
set(node, { [key]: newValue });
|
|
1545
|
+
}
|
|
1411
1546
|
// Get the child node for updating and notifying
|
|
1412
|
-
const childNode = isRoot ? node : getChildNode(node, key,
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1547
|
+
const childNode = isRoot ? node : getChildNode(node, key, newValue);
|
|
1548
|
+
if (isObservable(newValue)) {
|
|
1549
|
+
setToObservable(childNode, newValue);
|
|
1550
|
+
}
|
|
1551
|
+
else {
|
|
1552
|
+
// Set the raw value on the parent object
|
|
1553
|
+
const { newValue: savedValue, prevValue } = setNodeValue(childNode, newValue);
|
|
1554
|
+
const isPrim = isPrimitive(savedValue) || savedValue instanceof Date;
|
|
1555
|
+
if (!equals(savedValue, prevValue)) {
|
|
1556
|
+
updateNodesAndNotify(node, savedValue, prevValue, childNode, isPrim, isRoot, level);
|
|
1557
|
+
}
|
|
1558
|
+
if (!isPrim) {
|
|
1559
|
+
childNode.needsExtract = true;
|
|
1560
|
+
}
|
|
1561
|
+
extractFunctionOrComputed(node, key, savedValue);
|
|
1419
1562
|
}
|
|
1420
|
-
extractFunctionOrComputed(node, parentValue, key, savedValue);
|
|
1421
|
-
return isFunc ? savedValue : isRoot ? getProxy(node) : getProxy(node, key);
|
|
1422
1563
|
}
|
|
1423
1564
|
function assign(node, value) {
|
|
1424
1565
|
const proxy = getProxy(node);
|
|
@@ -1443,7 +1584,13 @@ function deleteFn(node, key) {
|
|
|
1443
1584
|
key = node.key;
|
|
1444
1585
|
node = node.parent;
|
|
1445
1586
|
}
|
|
1446
|
-
|
|
1587
|
+
const value = getNodeValue(node);
|
|
1588
|
+
if (isArray(value)) {
|
|
1589
|
+
collectionSetter(node, value, 'splice', key, 1);
|
|
1590
|
+
}
|
|
1591
|
+
else {
|
|
1592
|
+
setKey(node, key !== null && key !== void 0 ? key : '_', symbolDelete, /*level*/ -1);
|
|
1593
|
+
}
|
|
1447
1594
|
}
|
|
1448
1595
|
function handlerMapSet(node, p, value) {
|
|
1449
1596
|
const vProp = value === null || value === void 0 ? void 0 : value[p];
|
|
@@ -1523,8 +1670,11 @@ function handlerMapSet(node, p, value) {
|
|
|
1523
1670
|
function updateNodesAndNotify(node, newValue, prevValue, childNode, isPrim, isRoot, level) {
|
|
1524
1671
|
if (!childNode)
|
|
1525
1672
|
childNode = node;
|
|
1526
|
-
// Make sure we don't call too many listeners for
|
|
1673
|
+
// Make sure we don't call too many listeners for every property set
|
|
1527
1674
|
beginBatch();
|
|
1675
|
+
if (isPrim === undefined) {
|
|
1676
|
+
isPrim = isPrimitive(newValue);
|
|
1677
|
+
}
|
|
1528
1678
|
let hasADiff = isPrim;
|
|
1529
1679
|
let whenOptimizedOnlyIf = false;
|
|
1530
1680
|
// If new value is an object or array update notify down the tree
|
|
@@ -1544,7 +1694,7 @@ function updateNodesAndNotify(node, newValue, prevValue, childNode, isPrim, isRo
|
|
|
1544
1694
|
}
|
|
1545
1695
|
endBatch();
|
|
1546
1696
|
}
|
|
1547
|
-
function extractPromise(node, value, setter
|
|
1697
|
+
function extractPromise(node, value, setter) {
|
|
1548
1698
|
if (!node.state) {
|
|
1549
1699
|
node.state = createObservable({
|
|
1550
1700
|
isLoaded: false,
|
|
@@ -1560,30 +1710,29 @@ function extractPromise(node, value, setter, handleError) {
|
|
|
1560
1710
|
})
|
|
1561
1711
|
.catch((error) => {
|
|
1562
1712
|
node.state.error.set(error);
|
|
1563
|
-
if (handleError) {
|
|
1564
|
-
handleError(error);
|
|
1565
|
-
}
|
|
1566
1713
|
});
|
|
1567
1714
|
}
|
|
1568
|
-
function extractFunctionOrComputed(node,
|
|
1715
|
+
function extractFunctionOrComputed(node, k, v, activateRecursive) {
|
|
1569
1716
|
if (isPromise(v)) {
|
|
1570
1717
|
const childNode = getChildNode(node, k);
|
|
1571
1718
|
extractPromise(childNode, v);
|
|
1572
1719
|
setNodeValue(childNode, undefined);
|
|
1573
1720
|
}
|
|
1721
|
+
else if (isObservable(v)) {
|
|
1722
|
+
const fn = () => v;
|
|
1723
|
+
extractFunction(node, k, fn);
|
|
1724
|
+
const childNode = getChildNode(node, k, fn);
|
|
1725
|
+
const targetNode = getNode(v);
|
|
1726
|
+
// Set node to target's value if activating or it's already activated
|
|
1727
|
+
const initialValue = activateRecursive || !targetNode.lazy ? peekInternal(targetNode) : undefined;
|
|
1728
|
+
setNodeValue(childNode, initialValue);
|
|
1729
|
+
}
|
|
1574
1730
|
else if (typeof v === 'function') {
|
|
1575
1731
|
extractFunction(node, k, v);
|
|
1576
|
-
delete obj[k];
|
|
1577
1732
|
}
|
|
1578
|
-
else if (typeof v == 'object' && v !== null && v !== undefined) {
|
|
1579
|
-
const childNode =
|
|
1580
|
-
|
|
1581
|
-
extractFunction(node, k, v, childNode);
|
|
1582
|
-
delete obj[k];
|
|
1583
|
-
}
|
|
1584
|
-
else {
|
|
1585
|
-
return true;
|
|
1586
|
-
}
|
|
1733
|
+
else if (activateRecursive && typeof v == 'object' && v !== null && v !== undefined) {
|
|
1734
|
+
const childNode = getChildNode(node, k);
|
|
1735
|
+
checkLazy(childNode, v, activateRecursive);
|
|
1587
1736
|
}
|
|
1588
1737
|
}
|
|
1589
1738
|
function get(node, options) {
|
|
@@ -1593,210 +1742,285 @@ function get(node, options) {
|
|
|
1593
1742
|
return peek(node);
|
|
1594
1743
|
}
|
|
1595
1744
|
function peek(node) {
|
|
1596
|
-
const value =
|
|
1745
|
+
const value = peekInternal(node, true);
|
|
1746
|
+
return value;
|
|
1747
|
+
}
|
|
1748
|
+
function peekInternal(node, activateRecursive) {
|
|
1749
|
+
if (node.dirtyFn) {
|
|
1750
|
+
node.dirtyFn();
|
|
1751
|
+
globalState.dirtyNodes.delete(node);
|
|
1752
|
+
node.dirtyFn = undefined;
|
|
1753
|
+
}
|
|
1754
|
+
let value = getNodeValue(node);
|
|
1755
|
+
value = checkLazy(node, value, !!activateRecursive);
|
|
1756
|
+
return value;
|
|
1757
|
+
}
|
|
1758
|
+
function checkLazy(node, value, activateRecursive) {
|
|
1597
1759
|
// If node is not yet lazily computed go do that
|
|
1598
1760
|
const lazy = node.lazy;
|
|
1599
1761
|
if (lazy) {
|
|
1762
|
+
const lazyFn = node.lazyFn;
|
|
1600
1763
|
delete node.lazy;
|
|
1601
|
-
if (isFunction(
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1764
|
+
if (isFunction(lazyFn)) {
|
|
1765
|
+
if (lazyFn.length === 1) {
|
|
1766
|
+
// This is a lookup function, so return a record object
|
|
1767
|
+
value = {};
|
|
1768
|
+
}
|
|
1769
|
+
else {
|
|
1770
|
+
if (node.parent) {
|
|
1771
|
+
const parentValue = getNodeValue(node.parent);
|
|
1772
|
+
if (parentValue) {
|
|
1773
|
+
delete parentValue[node.key];
|
|
1774
|
+
}
|
|
1775
|
+
else {
|
|
1776
|
+
node.root._ = undefined;
|
|
1777
|
+
}
|
|
1608
1778
|
}
|
|
1779
|
+
value = activateNodeFunction(node, lazyFn);
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
if (lazy || node.needsExtract || activateRecursive) {
|
|
1784
|
+
for (const key in value) {
|
|
1785
|
+
if (hasOwnProperty.call(value, key)) {
|
|
1786
|
+
extractFunctionOrComputed(node, key, value[key], activateRecursive);
|
|
1609
1787
|
}
|
|
1610
1788
|
}
|
|
1611
1789
|
}
|
|
1612
|
-
// Check if computed needs to activate
|
|
1613
|
-
checkActivate(node);
|
|
1614
1790
|
return value;
|
|
1615
1791
|
}
|
|
1616
|
-
function
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
const onSet = (onSetFnParam) => {
|
|
1624
|
-
state.onSetFn = onSetFnParam;
|
|
1625
|
-
};
|
|
1626
|
-
// The onSet function handles the observable being set
|
|
1627
|
-
// and forwards the set elsewhere
|
|
1628
|
-
const updateLastSync = (fn) => {
|
|
1629
|
-
state.lastSync.value = fn;
|
|
1630
|
-
};
|
|
1631
|
-
// The subscribe function runs a function that listens to
|
|
1632
|
-
// a data source and sends updates into the observable
|
|
1633
|
-
const subscribe = (fn) => {
|
|
1634
|
-
if (!state.subscriber) {
|
|
1635
|
-
state.subscriber = fn;
|
|
1636
|
-
}
|
|
1637
|
-
};
|
|
1638
|
-
const cache = (fn) => {
|
|
1639
|
-
if (!state.cacheOptions) {
|
|
1640
|
-
state.cacheOptions = isFunction(fn) ? fn() : fn;
|
|
1641
|
-
}
|
|
1642
|
-
return new Promise((resolve) => {
|
|
1643
|
-
const wait = () => {
|
|
1644
|
-
if (node.state) {
|
|
1645
|
-
when(node.state.isLoadedLocal, () => {
|
|
1646
|
-
const dateModified = node.state.dateModified.get();
|
|
1647
|
-
resolve({ dateModified, value: peek(node) });
|
|
1648
|
-
});
|
|
1649
|
-
}
|
|
1650
|
-
else {
|
|
1651
|
-
queueMicrotask(wait);
|
|
1652
|
-
}
|
|
1653
|
-
};
|
|
1654
|
-
wait();
|
|
1655
|
-
});
|
|
1656
|
-
};
|
|
1657
|
-
const retry = (params) => {
|
|
1658
|
-
if (!state.retryOptions) {
|
|
1659
|
-
state.retryOptions = params || {};
|
|
1660
|
-
}
|
|
1661
|
-
};
|
|
1662
|
-
// The proxy function simply marks the node as a proxy with this function
|
|
1663
|
-
// so that child nodes will be created with this function, and then simply
|
|
1664
|
-
// activated as a function
|
|
1665
|
-
const proxy = (fn) => {
|
|
1666
|
-
node.proxyFn2 = fn;
|
|
1667
|
-
};
|
|
1668
|
-
return {
|
|
1669
|
-
onSet,
|
|
1670
|
-
proxy,
|
|
1671
|
-
cache,
|
|
1672
|
-
retry,
|
|
1673
|
-
subscribe,
|
|
1674
|
-
updateLastSync,
|
|
1675
|
-
obs$: getProxy(node),
|
|
1676
|
-
};
|
|
1792
|
+
function reactivateNode(node, lazyFn) {
|
|
1793
|
+
var _a, _b;
|
|
1794
|
+
(_a = node.activatedObserveDispose) === null || _a === void 0 ? void 0 : _a.call(node);
|
|
1795
|
+
(_b = node.linkedToNodeDispose) === null || _b === void 0 ? void 0 : _b.call(node);
|
|
1796
|
+
node.activatedObserveDispose = node.linkedToNodeDispose = node.linkedToNode = undefined;
|
|
1797
|
+
node.lazyFn = lazyFn;
|
|
1798
|
+
node.lazy = true;
|
|
1677
1799
|
}
|
|
1678
1800
|
function activateNodeFunction(node, lazyFn) {
|
|
1679
|
-
let prevTarget
|
|
1680
|
-
let curTarget
|
|
1801
|
+
// let prevTarget$: Observable<any>;
|
|
1802
|
+
// let curTarget$: Observable<any>;
|
|
1681
1803
|
let update;
|
|
1682
1804
|
let wasPromise;
|
|
1683
|
-
let
|
|
1684
|
-
const
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1805
|
+
let ignoreThisUpdate;
|
|
1806
|
+
const activateFn = lazyFn;
|
|
1807
|
+
let activatedValue;
|
|
1808
|
+
let disposes = [];
|
|
1809
|
+
let refreshFn;
|
|
1810
|
+
function markDirty() {
|
|
1811
|
+
node.dirtyFn = refreshFn;
|
|
1812
|
+
globalState.dirtyNodes.add(node);
|
|
1813
|
+
}
|
|
1814
|
+
node.activatedObserveDispose = observe(() => {
|
|
1815
|
+
var _a, _b, _c, _d;
|
|
1689
1816
|
// Run the function at this node
|
|
1690
|
-
let value =
|
|
1691
|
-
// If target is an observable,
|
|
1692
|
-
// and set up an onSet to write changes back to it
|
|
1817
|
+
let value = activateFn();
|
|
1818
|
+
// If target is an observable, make this node a link to it
|
|
1693
1819
|
if (isObservable(value)) {
|
|
1694
|
-
|
|
1695
|
-
curTarget$ = value;
|
|
1696
|
-
params.onSet(({ value: newValue, getPrevious }) => {
|
|
1697
|
-
// Don't set the target observable if the target has changed since the last run
|
|
1698
|
-
if (!prevTarget$ || curTarget$ === prevTarget$) {
|
|
1699
|
-
// Set the node value back to what it was before before setting it.
|
|
1700
|
-
// This is a workaround for linked objects because it might not notify
|
|
1701
|
-
// if setting a property of an object
|
|
1702
|
-
// TODO: Is there a way to not do this? Or at least only do it in a
|
|
1703
|
-
// small subset of cases?
|
|
1704
|
-
setNodeValue(getNode(curTarget$), getPrevious());
|
|
1705
|
-
// Set the value on the curTarget
|
|
1706
|
-
curTarget$.set(newValue);
|
|
1707
|
-
}
|
|
1708
|
-
});
|
|
1709
|
-
// Get the value from the observable because we still want the raw value
|
|
1710
|
-
// for the effect.
|
|
1711
|
-
value = value.get();
|
|
1820
|
+
value = setToObservable(node, value);
|
|
1712
1821
|
}
|
|
1713
|
-
|
|
1714
|
-
|
|
1822
|
+
if (isFunction(value)) {
|
|
1823
|
+
value = value();
|
|
1824
|
+
}
|
|
1825
|
+
const activated = !isObservable(value)
|
|
1826
|
+
? value === null || value === void 0 ? void 0 : value[symbolLinked]
|
|
1827
|
+
: undefined;
|
|
1828
|
+
if (activated) {
|
|
1829
|
+
node.activationState = activated;
|
|
1830
|
+
value = undefined;
|
|
1715
1831
|
}
|
|
1832
|
+
ignoreThisUpdate = false;
|
|
1833
|
+
wasPromise = isPromise(value);
|
|
1716
1834
|
// Activate this node if not activated already (may be called recursively)
|
|
1717
1835
|
// TODO: Is calling recursively bad? If so can it be fixed?
|
|
1718
1836
|
if (!node.activated) {
|
|
1719
1837
|
node.activated = true;
|
|
1720
|
-
|
|
1721
|
-
|
|
1838
|
+
let activateNodeFn = activateNodeBase;
|
|
1839
|
+
// If this is a Synced then run it through persistence instead of base
|
|
1840
|
+
if (activated === null || activated === void 0 ? void 0 : activated.synced) {
|
|
1841
|
+
activateNodeFn = globalState.activateSyncedNode;
|
|
1842
|
+
ignoreThisUpdate = true;
|
|
1843
|
+
}
|
|
1844
|
+
const { update: newUpdate, value: newValue } = activateNodeFn(node, value);
|
|
1845
|
+
update = newUpdate;
|
|
1846
|
+
value = newValue !== null && newValue !== void 0 ? newValue : activated === null || activated === void 0 ? void 0 : activated.initial;
|
|
1847
|
+
}
|
|
1848
|
+
else if (node.activationState) {
|
|
1849
|
+
const activated = node.activationState;
|
|
1850
|
+
if ((_b = (_a = node.state) === null || _a === void 0 ? void 0 : _a.peek()) === null || _b === void 0 ? void 0 : _b.sync) {
|
|
1851
|
+
node.state.sync();
|
|
1852
|
+
ignoreThisUpdate = true;
|
|
1853
|
+
}
|
|
1854
|
+
else {
|
|
1855
|
+
value = (_d = (_c = activated.get) === null || _c === void 0 ? void 0 : _c.call(activated)) !== null && _d !== void 0 ? _d : activated.initial;
|
|
1856
|
+
}
|
|
1722
1857
|
}
|
|
1723
|
-
|
|
1858
|
+
// value is undefined if it's in a persisted retry
|
|
1859
|
+
wasPromise = wasPromise || isPromise(value);
|
|
1724
1860
|
return value;
|
|
1725
|
-
}, (
|
|
1726
|
-
if (!
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
if (
|
|
1731
|
-
if (
|
|
1732
|
-
|
|
1861
|
+
}, (e) => {
|
|
1862
|
+
if (!ignoreThisUpdate) {
|
|
1863
|
+
const { value, nodes, refresh } = e;
|
|
1864
|
+
refreshFn = refresh;
|
|
1865
|
+
if (!wasPromise || !globalState.isLoadingRemote) {
|
|
1866
|
+
if (wasPromise) {
|
|
1867
|
+
if (node.activationState) {
|
|
1868
|
+
const { initial } = node.activationState;
|
|
1869
|
+
if (value && isPromise(value)) {
|
|
1870
|
+
// Extract the promise to make it set the value/error when it comes in
|
|
1871
|
+
extractPromise(node, value, update);
|
|
1872
|
+
}
|
|
1873
|
+
// Set this to undefined only if it's replacing the activation function,
|
|
1874
|
+
// so we don't overwrite it if it already has real data from either local
|
|
1875
|
+
// cache or a previous run
|
|
1876
|
+
if (isFunction(getNodeValue(node))) {
|
|
1877
|
+
setNodeValue(node, initial !== null && initial !== void 0 ? initial : undefined);
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
else if (node.activated) {
|
|
1881
|
+
// Extract the promise to make it set the value/error when it comes in
|
|
1882
|
+
extractPromise(node, value, update);
|
|
1883
|
+
// Set this to undefined only if it's replacing the activation function,
|
|
1884
|
+
// so we don't overwrite it if it already has real data from either local
|
|
1885
|
+
// cache or a previous run
|
|
1886
|
+
if (isFunction(getNodeValue(node))) {
|
|
1887
|
+
setNodeValue(node, undefined);
|
|
1888
|
+
}
|
|
1733
1889
|
}
|
|
1734
|
-
const { handleError, timeout } = setupRetry(retryOptions, refresh, attemptNum);
|
|
1735
|
-
onError = handleError;
|
|
1736
|
-
timeoutRetry = timeout;
|
|
1737
1890
|
}
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1891
|
+
else {
|
|
1892
|
+
activatedValue = value;
|
|
1893
|
+
if (node.state.isLoaded.peek()) {
|
|
1894
|
+
node.isComputing = true;
|
|
1895
|
+
set(node, value);
|
|
1896
|
+
node.isComputing = false;
|
|
1897
|
+
}
|
|
1898
|
+
else {
|
|
1899
|
+
setNodeValue(node, value);
|
|
1900
|
+
node.state.assign({
|
|
1901
|
+
isLoaded: true,
|
|
1902
|
+
error: undefined,
|
|
1903
|
+
});
|
|
1904
|
+
}
|
|
1745
1905
|
}
|
|
1746
1906
|
}
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
});
|
|
1753
|
-
}
|
|
1907
|
+
disposes.forEach((fn) => fn());
|
|
1908
|
+
disposes = [];
|
|
1909
|
+
nodes === null || nodes === void 0 ? void 0 : nodes.forEach(({ node }) => {
|
|
1910
|
+
disposes.push(onChange(node, markDirty, { immediate: true }));
|
|
1911
|
+
});
|
|
1754
1912
|
}
|
|
1755
|
-
|
|
1913
|
+
e.cancel = true;
|
|
1914
|
+
}, { fromComputed: true });
|
|
1915
|
+
return activatedValue;
|
|
1756
1916
|
}
|
|
1757
|
-
|
|
1758
|
-
const { onSetFn, subscriber } = node.activationState;
|
|
1759
|
-
let isSetting = false;
|
|
1917
|
+
function activateNodeBase(node, value) {
|
|
1760
1918
|
if (!node.state) {
|
|
1761
1919
|
node.state = createObservable({
|
|
1762
1920
|
isLoaded: false,
|
|
1763
1921
|
}, false, extractPromise, getProxy);
|
|
1764
1922
|
}
|
|
1765
|
-
if (
|
|
1766
|
-
const
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1923
|
+
if (node.activationState) {
|
|
1924
|
+
const { set: setFn, get: getFn, initial } = node.activationState;
|
|
1925
|
+
value = getFn === null || getFn === void 0 ? void 0 : getFn();
|
|
1926
|
+
if (value == undefined || value === null) {
|
|
1927
|
+
value = initial;
|
|
1928
|
+
}
|
|
1929
|
+
if (setFn) {
|
|
1930
|
+
let allChanges = [];
|
|
1931
|
+
let latestValue = undefined;
|
|
1932
|
+
let runNumber = 0;
|
|
1933
|
+
const runChanges = (listenerParams) => {
|
|
1934
|
+
// Don't call the set if this is the first value coming in
|
|
1935
|
+
if (allChanges.length > 0) {
|
|
1936
|
+
let changes;
|
|
1937
|
+
let value;
|
|
1938
|
+
let loading = false;
|
|
1939
|
+
let remote = false;
|
|
1940
|
+
let getPrevious;
|
|
1941
|
+
if (listenerParams) {
|
|
1942
|
+
changes = listenerParams.changes;
|
|
1943
|
+
value = listenerParams.value;
|
|
1944
|
+
loading = listenerParams.loading;
|
|
1945
|
+
remote = listenerParams.remote;
|
|
1946
|
+
getPrevious = listenerParams.getPrevious;
|
|
1947
|
+
}
|
|
1948
|
+
else {
|
|
1949
|
+
// If this is called by flushPending then get the change array
|
|
1950
|
+
// that we've been building up.
|
|
1951
|
+
changes = allChanges;
|
|
1952
|
+
value = latestValue;
|
|
1953
|
+
getPrevious = createPreviousHandler(value, changes);
|
|
1954
|
+
}
|
|
1955
|
+
allChanges = [];
|
|
1956
|
+
latestValue = undefined;
|
|
1957
|
+
globalState.pendingNodes.delete(node);
|
|
1958
|
+
runNumber++;
|
|
1959
|
+
const thisRunNumber = runNumber;
|
|
1960
|
+
const run = () => {
|
|
1961
|
+
if (thisRunNumber !== runNumber) {
|
|
1962
|
+
// set may get called multiple times before it loads so ignore any previous runs
|
|
1963
|
+
return;
|
|
1964
|
+
}
|
|
1965
|
+
node.isComputing = true;
|
|
1966
|
+
setFn({
|
|
1967
|
+
value,
|
|
1968
|
+
changes,
|
|
1969
|
+
loading,
|
|
1970
|
+
remote,
|
|
1971
|
+
getPrevious,
|
|
1972
|
+
});
|
|
1973
|
+
node.isComputing = false;
|
|
1974
|
+
};
|
|
1975
|
+
whenReady(node.state.isLoaded, run);
|
|
1775
1976
|
}
|
|
1776
|
-
}
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1977
|
+
};
|
|
1978
|
+
const onChangeImmediate = ({ value, changes }) => {
|
|
1979
|
+
if (!node.isComputing) {
|
|
1980
|
+
if (changes.length > 1 || !isFunction(changes[0].prevAtPath)) {
|
|
1981
|
+
latestValue = value;
|
|
1982
|
+
if (allChanges.length > 0) {
|
|
1983
|
+
changes = changes.filter((change) => !isArraySubset(allChanges[0].path, change.path));
|
|
1984
|
+
}
|
|
1985
|
+
allChanges.push(...changes);
|
|
1986
|
+
globalState.pendingNodes.set(node, runChanges);
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1989
|
+
};
|
|
1990
|
+
// Create an immediate listener to mark this node as pending. Then actually run
|
|
1991
|
+
// the changes at the end of the batch so everything is properly batched.
|
|
1992
|
+
// However, this can be short circuited if the user calls get() or peek()
|
|
1993
|
+
// in which case the set needs to run immediately so that the values are up to date.
|
|
1994
|
+
onChange(node, onChangeImmediate, { immediate: true });
|
|
1995
|
+
onChange(node, runChanges);
|
|
1996
|
+
}
|
|
1787
1997
|
}
|
|
1788
1998
|
const update = ({ value }) => {
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
if (!isSetting) {
|
|
1999
|
+
if (!node.isComputing) {
|
|
2000
|
+
node.isComputing = true;
|
|
1792
2001
|
set(node, value);
|
|
2002
|
+
node.isComputing = false;
|
|
1793
2003
|
}
|
|
1794
2004
|
};
|
|
1795
|
-
|
|
1796
|
-
|
|
2005
|
+
return { update, value };
|
|
2006
|
+
}
|
|
2007
|
+
function setToObservable(node, value) {
|
|
2008
|
+
var _a;
|
|
2009
|
+
// If the computed is a proxy to another observable
|
|
2010
|
+
// link it to the target observable
|
|
2011
|
+
const linkedNode = getNode(value);
|
|
2012
|
+
if (linkedNode !== node && (linkedNode === null || linkedNode === void 0 ? void 0 : linkedNode.linkedToNode) !== node) {
|
|
2013
|
+
node.linkedToNode = linkedNode;
|
|
2014
|
+
linkedNode.linkedFromNodes || (linkedNode.linkedFromNodes = new Set());
|
|
2015
|
+
linkedNode.linkedFromNodes.add(node);
|
|
2016
|
+
(_a = node.linkedToNodeDispose) === null || _a === void 0 ? void 0 : _a.call(node);
|
|
2017
|
+
node.linkedToNodeDispose = onChange(linkedNode, () => {
|
|
2018
|
+
value = peek(linkedNode);
|
|
2019
|
+
set(node, value);
|
|
2020
|
+
}, { initial: true }, new Set([node]));
|
|
1797
2021
|
}
|
|
1798
|
-
return
|
|
1799
|
-
}
|
|
2022
|
+
return value;
|
|
2023
|
+
}
|
|
1800
2024
|
|
|
1801
2025
|
const fns = ['get', 'set', 'peek', 'onChange', 'toggle'];
|
|
1802
2026
|
function ObservablePrimitiveClass(node) {
|
|
@@ -1813,8 +2037,14 @@ function proto(key, fn) {
|
|
|
1813
2037
|
return fn.call(this, this._node, ...args);
|
|
1814
2038
|
};
|
|
1815
2039
|
}
|
|
1816
|
-
proto('peek',
|
|
1817
|
-
|
|
2040
|
+
proto('peek', (node) => {
|
|
2041
|
+
flushPending();
|
|
2042
|
+
return peek(node);
|
|
2043
|
+
});
|
|
2044
|
+
proto('get', (node, options) => {
|
|
2045
|
+
flushPending();
|
|
2046
|
+
return get(node, options);
|
|
2047
|
+
});
|
|
1818
2048
|
proto('set', set);
|
|
1819
2049
|
proto('onChange', onChange);
|
|
1820
2050
|
// Getters
|
|
@@ -1826,13 +2056,12 @@ Object.defineProperty(ObservablePrimitiveClass.prototype, symbolGetNode, {
|
|
|
1826
2056
|
});
|
|
1827
2057
|
ObservablePrimitiveClass.prototype.toggle = function () {
|
|
1828
2058
|
const value = this.peek();
|
|
1829
|
-
if (value === undefined || isBoolean(value)) {
|
|
2059
|
+
if (value === undefined || value === null || isBoolean(value)) {
|
|
1830
2060
|
this.set(!value);
|
|
1831
2061
|
}
|
|
1832
2062
|
else if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
|
|
1833
2063
|
throw new Error('[legend-state] Cannot toggle a non-boolean value');
|
|
1834
2064
|
}
|
|
1835
|
-
return !value;
|
|
1836
2065
|
};
|
|
1837
2066
|
ObservablePrimitiveClass.prototype.delete = function () {
|
|
1838
2067
|
this.set(undefined);
|
|
@@ -1845,92 +2074,26 @@ function observable(value) {
|
|
|
1845
2074
|
function observablePrimitive(value) {
|
|
1846
2075
|
return createObservable(value, true, extractPromise, getProxy, ObservablePrimitiveClass);
|
|
1847
2076
|
}
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
function computed(compute, set$1) {
|
|
1851
|
-
// Create an observable for this computed variable
|
|
1852
|
-
const obs = observable();
|
|
1853
|
-
lockObservable(obs, true);
|
|
2077
|
+
function syncState(obs) {
|
|
1854
2078
|
const node = getNode(obs);
|
|
1855
|
-
node.
|
|
1856
|
-
|
|
1857
|
-
const setInner = function (val) {
|
|
1858
|
-
const prevNode = node.linkedToNode;
|
|
1859
|
-
// If it was previously linked to a node remove self
|
|
1860
|
-
// from its linkedFromNodes
|
|
1861
|
-
if (prevNode) {
|
|
1862
|
-
prevNode.linkedFromNodes.delete(node);
|
|
1863
|
-
node.linkedToNode = undefined;
|
|
1864
|
-
}
|
|
1865
|
-
const { parentOther } = node;
|
|
1866
|
-
if (isObservable(val)) {
|
|
1867
|
-
// If the computed is a proxy to another observable
|
|
1868
|
-
// link it to the target observable
|
|
1869
|
-
const linkedNode = getNode(val);
|
|
1870
|
-
node.linkedToNode = linkedNode;
|
|
1871
|
-
if (!linkedNode.linkedFromNodes) {
|
|
1872
|
-
linkedNode.linkedFromNodes = new Set();
|
|
1873
|
-
}
|
|
1874
|
-
linkedNode.linkedFromNodes.add(node);
|
|
1875
|
-
if (node.parentOther) {
|
|
1876
|
-
onChange(linkedNode, ({ value }) => {
|
|
1877
|
-
setNodeValue(node.parentOther, value);
|
|
1878
|
-
}, { initial: true });
|
|
1879
|
-
}
|
|
1880
|
-
// If the target observable is different then notify for the change
|
|
1881
|
-
if (prevNode) {
|
|
1882
|
-
const value = getNodeValue(linkedNode);
|
|
1883
|
-
const prevValue = getNodeValue(prevNode);
|
|
1884
|
-
notify(node, value, prevValue, 0);
|
|
1885
|
-
}
|
|
1886
|
-
}
|
|
1887
|
-
else if (val !== obs.peek()) {
|
|
1888
|
-
// Unlock computed node before setting the value
|
|
1889
|
-
lockObservable(obs, false);
|
|
1890
|
-
const setter = isSetAfterActivated ? set : setNodeValue;
|
|
1891
|
-
// Update the computed value
|
|
1892
|
-
setter(node, val);
|
|
1893
|
-
// If the computed is a child of an observable set the value on it
|
|
1894
|
-
if (parentOther) {
|
|
1895
|
-
let didUnlock = false;
|
|
1896
|
-
if (parentOther.root.locked) {
|
|
1897
|
-
parentOther.root.locked = false;
|
|
1898
|
-
didUnlock = true;
|
|
1899
|
-
}
|
|
1900
|
-
setter(parentOther, val);
|
|
1901
|
-
if (didUnlock) {
|
|
1902
|
-
parentOther.root.locked = true;
|
|
1903
|
-
}
|
|
1904
|
-
}
|
|
1905
|
-
// Re-lock the computed node
|
|
1906
|
-
lockObservable(obs, true);
|
|
1907
|
-
}
|
|
1908
|
-
else if (parentOther) {
|
|
1909
|
-
setNodeValue(parentOther, val);
|
|
1910
|
-
}
|
|
1911
|
-
isSetAfterActivated = true;
|
|
1912
|
-
};
|
|
1913
|
-
// Lazily activate the observable when get is called
|
|
1914
|
-
node.root.activate = () => {
|
|
1915
|
-
node.root.activate = undefined;
|
|
1916
|
-
observe(compute, ({ value }) => {
|
|
1917
|
-
if (isPromise(value)) {
|
|
1918
|
-
value.then((v) => setInner(v));
|
|
1919
|
-
}
|
|
1920
|
-
else {
|
|
1921
|
-
setInner(value);
|
|
1922
|
-
}
|
|
1923
|
-
}, { immediate: true, fromComputed: true });
|
|
1924
|
-
};
|
|
1925
|
-
if (set$1) {
|
|
1926
|
-
node.root.set = (value) => {
|
|
1927
|
-
batch(() => set$1(value));
|
|
1928
|
-
};
|
|
2079
|
+
if (!node.state) {
|
|
2080
|
+
peekInternal(node);
|
|
1929
2081
|
}
|
|
1930
|
-
|
|
2082
|
+
if (!node.state) {
|
|
2083
|
+
node.state = observable({});
|
|
2084
|
+
}
|
|
2085
|
+
return node.state;
|
|
2086
|
+
}
|
|
2087
|
+
|
|
2088
|
+
function computed(get, set) {
|
|
2089
|
+
return observable(set ? () => ({ [symbolLinked]: { get, set: ({ value }) => set(value) } }) : get);
|
|
2090
|
+
}
|
|
2091
|
+
|
|
2092
|
+
function linked(params) {
|
|
2093
|
+
return (() => ({ [symbolLinked]: params }));
|
|
1931
2094
|
}
|
|
1932
2095
|
|
|
1933
|
-
function configureLegendState({ observableFunctions, observableProperties: observableProperties$1, }) {
|
|
2096
|
+
function configureLegendState({ observableFunctions, observableProperties: observableProperties$1, jsonReplacer, jsonReviver, }) {
|
|
1934
2097
|
if (observableFunctions) {
|
|
1935
2098
|
for (const key in observableFunctions) {
|
|
1936
2099
|
const fn = observableFunctions[key];
|
|
@@ -1955,6 +2118,12 @@ function configureLegendState({ observableFunctions, observableProperties: obser
|
|
|
1955
2118
|
});
|
|
1956
2119
|
}
|
|
1957
2120
|
}
|
|
2121
|
+
if (jsonReplacer) {
|
|
2122
|
+
globalState.replacer = jsonReplacer;
|
|
2123
|
+
}
|
|
2124
|
+
if (jsonReviver) {
|
|
2125
|
+
globalState.reviver = jsonReviver;
|
|
2126
|
+
}
|
|
1958
2127
|
}
|
|
1959
2128
|
|
|
1960
2129
|
function event() {
|
|
@@ -1981,50 +2150,97 @@ function event() {
|
|
|
1981
2150
|
}
|
|
1982
2151
|
|
|
1983
2152
|
function proxy(get, set) {
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2153
|
+
return observable((key) => set
|
|
2154
|
+
? linked({
|
|
2155
|
+
get: () => get(key),
|
|
2156
|
+
set: ({ value }) => set(key, value),
|
|
2157
|
+
})
|
|
2158
|
+
: get(key));
|
|
2159
|
+
}
|
|
2160
|
+
|
|
2161
|
+
function calculateRetryDelay(retryOptions, attemptNum) {
|
|
2162
|
+
const { backoff, delay = 1000, infinite, times = 3, maxDelay = 30000 } = retryOptions;
|
|
2163
|
+
if (infinite || attemptNum < times) {
|
|
2164
|
+
const delayTime = Math.min(delay * (backoff === 'constant' ? 1 : 2 ** attemptNum), maxDelay);
|
|
2165
|
+
return delayTime;
|
|
2166
|
+
}
|
|
2167
|
+
return null;
|
|
2168
|
+
}
|
|
2169
|
+
function createRetryTimeout(retryOptions, attemptNum, fn) {
|
|
2170
|
+
const delayTime = calculateRetryDelay(retryOptions, attemptNum);
|
|
2171
|
+
if (delayTime) {
|
|
2172
|
+
return setTimeout(fn, delayTime);
|
|
2173
|
+
}
|
|
2174
|
+
}
|
|
2175
|
+
function runWithRetry(node, state, fn) {
|
|
2176
|
+
const { retry, waitFor } = node.activationState;
|
|
2177
|
+
const e = { cancel: false };
|
|
2178
|
+
let value = undefined;
|
|
2179
|
+
if (waitFor) {
|
|
2180
|
+
value = whenReady(waitFor, () => {
|
|
2181
|
+
node.activationState.waitFor = undefined;
|
|
2182
|
+
return fn(e);
|
|
2183
|
+
});
|
|
2184
|
+
}
|
|
2185
|
+
else {
|
|
2186
|
+
value = fn(e);
|
|
2187
|
+
}
|
|
2188
|
+
if (isPromise(value) && retry) {
|
|
2189
|
+
let timeoutRetry;
|
|
2190
|
+
return new Promise((resolve) => {
|
|
2191
|
+
const run = () => {
|
|
2192
|
+
value
|
|
2193
|
+
.then((val) => {
|
|
2194
|
+
node.activationState.persistedRetry = false;
|
|
2195
|
+
resolve(val);
|
|
2196
|
+
})
|
|
2197
|
+
.catch(() => {
|
|
2198
|
+
state.attemptNum++;
|
|
2199
|
+
if (timeoutRetry) {
|
|
2200
|
+
clearTimeout(timeoutRetry);
|
|
2201
|
+
}
|
|
2202
|
+
if (!e.cancel) {
|
|
2203
|
+
timeoutRetry = createRetryTimeout(retry, state.attemptNum, () => {
|
|
2204
|
+
value = fn(e);
|
|
2205
|
+
run();
|
|
2206
|
+
});
|
|
2207
|
+
}
|
|
2208
|
+
})
|
|
2209
|
+
.finally(() => {
|
|
2210
|
+
node.activationState.persistedRetry = false;
|
|
2004
2211
|
});
|
|
2005
|
-
}
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
}
|
|
2009
|
-
return
|
|
2212
|
+
};
|
|
2213
|
+
run();
|
|
2214
|
+
});
|
|
2215
|
+
}
|
|
2216
|
+
return value;
|
|
2010
2217
|
}
|
|
2011
2218
|
|
|
2012
2219
|
const internal = {
|
|
2220
|
+
createPreviousHandler,
|
|
2221
|
+
clone,
|
|
2013
2222
|
ensureNodeValue,
|
|
2014
2223
|
findIDKey,
|
|
2015
2224
|
get,
|
|
2016
2225
|
getNode,
|
|
2226
|
+
getNodeValue,
|
|
2227
|
+
getPathType,
|
|
2017
2228
|
getProxy,
|
|
2018
2229
|
globalState,
|
|
2230
|
+
initializePathType,
|
|
2019
2231
|
observableFns,
|
|
2020
2232
|
optimized,
|
|
2021
2233
|
peek,
|
|
2234
|
+
runWithRetry,
|
|
2235
|
+
safeParse,
|
|
2236
|
+
safeStringify,
|
|
2022
2237
|
set,
|
|
2023
2238
|
setAtPath,
|
|
2024
2239
|
setNodeValue,
|
|
2025
|
-
|
|
2240
|
+
symbolLinked,
|
|
2026
2241
|
symbolDelete,
|
|
2242
|
+
tracking,
|
|
2027
2243
|
};
|
|
2028
2244
|
|
|
2029
|
-
export { ObservablePrimitiveClass, batch, beginBatch, beginTracking,
|
|
2245
|
+
export { ObservablePrimitiveClass, batch, beginBatch, beginTracking, computeSelector, computed, configureLegendState, constructObjectWithPath, deconstructObjectWithPath, endBatch, endTracking, event, findIDKey, getNode, getNodeValue, getObservableIndex, hasOwnProperty, internal, isArray, isBoolean, isDate, isEmpty, isFunction, isNullOrUndefined, isObject, isObservable, isObservableValueReady, isPrimitive, isPromise, isString, isSymbol, linked, mergeIntoObservable, observable, observablePrimitive, observe, opaqueObject, optimized, proxy, setAtPath, setInObservableAtPath, setSilently, setupTracking, symbolDelete, syncState, trackSelector, tracking, updateTracking, when, whenReady };
|
|
2030
2246
|
//# sourceMappingURL=index.mjs.map
|