@legendapp/state 3.0.0-alpha.0 → 3.0.0-alpha.2
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/.DS_Store +0 -0
- package/CHANGELOG.md +1 -827
- package/LICENSE +1 -21
- package/README.md +1 -141
- package/as/arrayAsRecord.d.mts +5 -0
- package/as/arrayAsRecord.d.ts +5 -0
- package/as/arrayAsRecord.js +28 -0
- package/as/arrayAsRecord.mjs +26 -0
- package/as/arrayAsSet.d.mts +5 -0
- package/as/arrayAsSet.d.ts +5 -0
- package/as/arrayAsSet.js +13 -0
- package/as/arrayAsSet.mjs +11 -0
- package/as/arrayAsString.d.mts +5 -0
- package/as/arrayAsString.d.ts +5 -0
- package/as/arrayAsString.js +13 -0
- package/as/arrayAsString.mjs +11 -0
- package/as/numberAsString.d.mts +5 -0
- package/as/numberAsString.d.ts +5 -0
- package/as/numberAsString.js +13 -0
- package/as/numberAsString.mjs +11 -0
- package/as/recordAsArray.d.mts +5 -0
- package/as/recordAsArray.d.ts +5 -0
- package/as/recordAsArray.js +25 -0
- package/as/recordAsArray.mjs +23 -0
- package/as/recordAsString.d.mts +5 -0
- package/as/recordAsString.d.ts +5 -0
- package/as/recordAsString.js +13 -0
- package/as/recordAsString.mjs +11 -0
- package/as/setAsArray.d.mts +5 -0
- package/as/setAsArray.d.ts +5 -0
- package/as/setAsArray.js +13 -0
- package/as/setAsArray.mjs +11 -0
- package/as/setAsString.d.mts +5 -0
- package/as/setAsString.d.ts +5 -0
- package/as/setAsString.js +13 -0
- package/as/setAsString.mjs +11 -0
- package/as/stringAsArray.d.mts +5 -0
- package/as/stringAsArray.d.ts +5 -0
- package/as/stringAsArray.js +13 -0
- package/as/stringAsArray.mjs +11 -0
- package/as/stringAsNumber.d.mts +5 -0
- package/as/stringAsNumber.d.ts +5 -0
- package/as/stringAsNumber.js +16 -0
- package/as/stringAsNumber.mjs +14 -0
- package/as/stringAsRecord.d.mts +5 -0
- package/as/stringAsRecord.d.ts +5 -0
- package/as/stringAsRecord.js +15 -0
- package/as/stringAsRecord.mjs +13 -0
- package/as/stringAsSet.d.mts +5 -0
- package/as/stringAsSet.d.ts +5 -0
- package/as/stringAsSet.js +13 -0
- package/as/stringAsSet.mjs +11 -0
- package/babel.d.mts +21 -0
- package/babel.d.ts +21 -2
- package/babel.js +57 -53
- package/babel.mjs +65 -0
- package/config/enable$GetSet.js +13 -14
- package/config/enable$GetSet.mjs +13 -14
- package/config/enableReactComponents.d.mts +9 -0
- package/config/enableReactComponents.d.ts +4 -2
- package/config/enableReactComponents.js +13 -10
- package/config/enableReactComponents.mjs +13 -10
- package/config/enableReactNativeComponents.d.mts +22 -0
- package/config/enableReactNativeComponents.d.ts +6 -4
- package/config/enableReactNativeComponents.js +43 -47
- package/config/enableReactNativeComponents.mjs +43 -47
- package/config/enableReactTracking.d.mts +7 -0
- package/config/enableReactTracking.d.ts +3 -2
- package/config/enableReactTracking.js +33 -38
- package/config/enableReactTracking.mjs +33 -38
- package/config/enableReactUse.d.mts +10 -0
- package/config/enableReactUse.d.ts +4 -1
- package/config/enableReactUse.js +15 -14
- package/config/enableReactUse.mjs +15 -14
- package/config/{enable$GetSet.d.ts → enable_GetSet.d.mts} +4 -2
- package/config/enable_GetSet.d.ts +10 -0
- package/config/enable_PeekAssign.d.mts +10 -0
- package/config/enable_PeekAssign.d.ts +4 -2
- package/config/enable_PeekAssign.js +13 -14
- package/config/enable_PeekAssign.mjs +13 -14
- package/helpers/pageHash.d.mts +9 -0
- package/helpers/pageHash.d.ts +2 -0
- package/helpers/pageHash.js +25 -30
- package/helpers/pageHash.mjs +25 -30
- package/helpers/pageHashParams.d.mts +9 -0
- package/helpers/pageHashParams.d.ts +2 -0
- package/helpers/pageHashParams.js +34 -37
- package/helpers/pageHashParams.mjs +34 -37
- package/helpers/time.d.mts +6 -0
- package/helpers/time.d.ts +6 -3
- package/helpers/time.js +17 -17
- package/helpers/time.mjs +17 -17
- package/helpers/trackHistory.d.mts +6 -0
- package/helpers/trackHistory.d.ts +6 -0
- package/helpers/trackHistory.js +21 -0
- package/helpers/trackHistory.mjs +19 -0
- package/helpers/undoRedo.d.mts +37 -0
- package/helpers/undoRedo.d.ts +37 -0
- package/helpers/undoRedo.js +68 -0
- package/helpers/undoRedo.mjs +66 -0
- package/index.d.mts +404 -0
- package/index.d.ts +371 -28
- package/index.js +2003 -2164
- package/index.mjs +2003 -2164
- package/package.json +254 -185
- package/persist-plugins/async-storage.d.mts +18 -0
- package/persist-plugins/async-storage.d.ts +6 -3
- package/persist-plugins/async-storage.js +79 -86
- package/persist-plugins/async-storage.mjs +79 -86
- package/persist-plugins/indexeddb.d.mts +29 -0
- package/persist-plugins/indexeddb.d.ts +6 -3
- package/persist-plugins/indexeddb.js +331 -348
- package/persist-plugins/indexeddb.mjs +331 -348
- package/persist-plugins/local-storage.d.mts +23 -0
- package/persist-plugins/local-storage.d.ts +8 -5
- package/persist-plugins/local-storage.js +74 -76
- package/persist-plugins/local-storage.mjs +74 -76
- package/persist-plugins/mmkv.d.mts +18 -0
- package/persist-plugins/mmkv.d.ts +6 -3
- package/persist-plugins/mmkv.js +82 -86
- package/persist-plugins/mmkv.mjs +82 -86
- package/react-hooks/createObservableHook.d.mts +5 -0
- package/react-hooks/createObservableHook.d.ts +4 -1
- package/react-hooks/createObservableHook.js +29 -30
- package/react-hooks/createObservableHook.mjs +25 -30
- package/react-hooks/useHover.d.mts +5 -0
- package/react-hooks/useHover.d.ts +5 -3
- package/react-hooks/useHover.js +29 -29
- package/react-hooks/useHover.mjs +29 -29
- package/react-hooks/useMeasure.d.mts +9 -0
- package/react-hooks/useMeasure.d.ts +5 -2
- package/react-hooks/useMeasure.js +30 -32
- package/react-hooks/useMeasure.mjs +30 -32
- package/react-hooks/useObservableNextRouter.d.mts +35 -0
- package/react-hooks/useObservableNextRouter.d.ts +9 -7
- package/react-hooks/useObservableNextRouter.js +64 -77
- package/react-hooks/useObservableNextRouter.mjs +60 -77
- package/react.d.mts +157 -0
- package/react.d.ts +157 -21
- package/react.js +458 -749
- package/react.mjs +457 -752
- package/sync-plugins/crud.d.mts +54 -0
- package/sync-plugins/crud.d.ts +12 -10
- package/sync-plugins/crud.js +253 -270
- package/sync-plugins/crud.mjs +253 -270
- package/sync-plugins/fetch.d.mts +21 -0
- package/sync-plugins/fetch.d.ts +7 -4
- package/sync-plugins/fetch.js +50 -37
- package/sync-plugins/fetch.mjs +50 -37
- package/sync-plugins/keel.d.mts +108 -0
- package/sync-plugins/keel.d.ts +17 -15
- package/sync-plugins/keel.js +229 -462
- package/sync-plugins/keel.mjs +227 -464
- package/sync-plugins/supabase.d.mts +39 -0
- package/sync-plugins/supabase.d.ts +16 -14
- package/sync-plugins/supabase.js +128 -128
- package/sync-plugins/supabase.mjs +128 -128
- package/sync-plugins/tanstack-query.d.mts +14 -0
- package/sync-plugins/tanstack-query.d.ts +7 -4
- package/sync-plugins/tanstack-query.js +51 -57
- package/sync-plugins/tanstack-query.mjs +51 -57
- package/sync-plugins/tanstack-react-query.d.mts +8 -0
- package/sync-plugins/tanstack-react-query.d.ts +6 -1
- package/sync-plugins/tanstack-react-query.js +2 -2
- package/sync-plugins/tanstack-react-query.mjs +2 -2
- package/sync.d.mts +351 -0
- package/sync.d.ts +349 -9
- package/sync.js +909 -962
- package/sync.mjs +919 -972
- package/trace.d.mts +9 -0
- package/trace.d.ts +9 -4
- package/trace.js +72 -62
- package/trace.mjs +72 -62
- package/types/babel.d.ts +1 -12
- package/babel.js.map +0 -1
- package/config/enable$GetSet.js.map +0 -1
- package/config/enable$GetSet.mjs.map +0 -1
- package/config/enableReactComponents.js.map +0 -1
- package/config/enableReactComponents.mjs.map +0 -1
- package/config/enableReactNativeComponents.js.map +0 -1
- package/config/enableReactNativeComponents.mjs.map +0 -1
- package/config/enableReactTracking.js.map +0 -1
- package/config/enableReactTracking.mjs.map +0 -1
- package/config/enableReactUse.js.map +0 -1
- package/config/enableReactUse.mjs.map +0 -1
- package/config/enable_PeekAssign.js.map +0 -1
- package/config/enable_PeekAssign.mjs.map +0 -1
- package/helpers/pageHash.js.map +0 -1
- package/helpers/pageHash.mjs.map +0 -1
- package/helpers/pageHashParams.js.map +0 -1
- package/helpers/pageHashParams.mjs.map +0 -1
- package/helpers/time.js.map +0 -1
- package/helpers/time.mjs.map +0 -1
- package/history.d.ts +0 -1
- package/history.js +0 -24
- package/history.js.map +0 -1
- package/history.mjs +0 -22
- package/history.mjs.map +0 -1
- package/index.js.map +0 -1
- package/index.mjs.map +0 -1
- package/persist-plugins/async-storage.js.map +0 -1
- package/persist-plugins/async-storage.mjs.map +0 -1
- package/persist-plugins/indexeddb.js.map +0 -1
- package/persist-plugins/indexeddb.mjs.map +0 -1
- package/persist-plugins/local-storage.js.map +0 -1
- package/persist-plugins/local-storage.mjs.map +0 -1
- package/persist-plugins/mmkv.js.map +0 -1
- package/persist-plugins/mmkv.mjs.map +0 -1
- package/react-hooks/createObservableHook.js.map +0 -1
- package/react-hooks/createObservableHook.mjs.map +0 -1
- package/react-hooks/useHover.js.map +0 -1
- package/react-hooks/useHover.mjs.map +0 -1
- package/react-hooks/useMeasure.js.map +0 -1
- package/react-hooks/useMeasure.mjs.map +0 -1
- package/react-hooks/useObservableNextRouter.js.map +0 -1
- package/react-hooks/useObservableNextRouter.mjs.map +0 -1
- package/react.js.map +0 -1
- package/react.mjs.map +0 -1
- package/src/ObservableObject.ts +0 -1350
- package/src/ObservablePrimitive.ts +0 -62
- package/src/babel/index.ts +0 -83
- package/src/batching.ts +0 -357
- package/src/computed.ts +0 -18
- package/src/config/enable$GetSet.ts +0 -30
- package/src/config/enableReactComponents.ts +0 -26
- package/src/config/enableReactNativeComponents.ts +0 -102
- package/src/config/enableReactTracking.ts +0 -62
- package/src/config/enableReactUse.ts +0 -32
- package/src/config/enable_PeekAssign.ts +0 -31
- package/src/config.ts +0 -47
- package/src/createObservable.ts +0 -47
- package/src/event.ts +0 -26
- package/src/globals.ts +0 -235
- package/src/helpers/pageHash.ts +0 -41
- package/src/helpers/pageHashParams.ts +0 -55
- package/src/helpers/time.ts +0 -30
- package/src/helpers.ts +0 -231
- package/src/history/trackHistory.ts +0 -29
- package/src/history/undoRedo.ts +0 -111
- package/src/is.ts +0 -63
- package/src/linked.ts +0 -17
- package/src/observable.ts +0 -32
- package/src/observableInterfaces.ts +0 -151
- package/src/observableTypes.ts +0 -232
- package/src/observe.ts +0 -89
- package/src/old-plugins/firebase.ts +0 -1053
- package/src/onChange.ts +0 -146
- package/src/persist/configureObservablePersistence.ts +0 -7
- package/src/persist/fieldTransformer.ts +0 -149
- package/src/persist/observablePersistRemoteFunctionsAdapter.ts +0 -39
- package/src/persist/persistObservable.ts +0 -1034
- package/src/persist-plugins/async-storage.ts +0 -99
- package/src/persist-plugins/indexeddb.ts +0 -432
- package/src/persist-plugins/local-storage.ts +0 -86
- package/src/persist-plugins/mmkv.ts +0 -91
- package/src/proxy.ts +0 -28
- package/src/react/Computed.tsx +0 -8
- package/src/react/For.tsx +0 -116
- package/src/react/Memo.tsx +0 -4
- package/src/react/Reactive.tsx +0 -53
- package/src/react/Show.tsx +0 -33
- package/src/react/Switch.tsx +0 -43
- package/src/react/react-globals.ts +0 -3
- package/src/react/reactInterfaces.ts +0 -32
- package/src/react/reactive-observer.tsx +0 -210
- package/src/react/useComputed.ts +0 -36
- package/src/react/useEffectOnce.ts +0 -41
- package/src/react/useIsMounted.ts +0 -16
- package/src/react/useMount.ts +0 -15
- package/src/react/useObservable.ts +0 -24
- package/src/react/useObservableReducer.ts +0 -52
- package/src/react/useObservableState.ts +0 -30
- package/src/react/useObserve.ts +0 -54
- package/src/react/useObserveEffect.ts +0 -40
- package/src/react/usePauseProvider.tsx +0 -16
- package/src/react/useSelector.ts +0 -167
- package/src/react/useUnmount.ts +0 -8
- package/src/react/useWhen.ts +0 -9
- package/src/react-hooks/createObservableHook.ts +0 -53
- package/src/react-hooks/useHover.ts +0 -40
- package/src/react-hooks/useMeasure.ts +0 -48
- package/src/react-hooks/useObservableNextRouter.ts +0 -137
- package/src/retry.ts +0 -71
- package/src/setupTracking.ts +0 -26
- package/src/sync/activateSyncedNode.ts +0 -128
- package/src/sync/configureObservableSync.ts +0 -7
- package/src/sync/persistTypes.ts +0 -216
- package/src/sync/syncHelpers.ts +0 -180
- package/src/sync/syncObservable.ts +0 -1056
- package/src/sync/syncObservableAdapter.ts +0 -31
- package/src/sync/syncTypes.ts +0 -189
- package/src/sync/synced.ts +0 -21
- package/src/sync-plugins/crud.ts +0 -412
- package/src/sync-plugins/fetch.ts +0 -80
- package/src/sync-plugins/keel.ts +0 -495
- package/src/sync-plugins/supabase.ts +0 -249
- package/src/sync-plugins/tanstack-query.ts +0 -113
- package/src/sync-plugins/tanstack-react-query.ts +0 -12
- package/src/trace/traceHelpers.ts +0 -11
- package/src/trace/useTraceListeners.ts +0 -34
- package/src/trace/useTraceUpdates.ts +0 -24
- package/src/trace/useVerifyNotTracking.ts +0 -33
- package/src/trace/useVerifyOneRender.ts +0 -10
- package/src/trackSelector.ts +0 -52
- package/src/tracking.ts +0 -43
- package/src/types/babel.d.ts +0 -12
- package/src/when.ts +0 -75
- package/sync-plugins/crud.js.map +0 -1
- package/sync-plugins/crud.mjs.map +0 -1
- package/sync-plugins/fetch.js.map +0 -1
- package/sync-plugins/fetch.mjs.map +0 -1
- package/sync-plugins/keel.js.map +0 -1
- package/sync-plugins/keel.mjs.map +0 -1
- package/sync-plugins/supabase.js.map +0 -1
- package/sync-plugins/supabase.mjs.map +0 -1
- package/sync-plugins/tanstack-query.js.map +0 -1
- package/sync-plugins/tanstack-query.mjs.map +0 -1
- package/sync-plugins/tanstack-react-query.js.map +0 -1
- package/sync-plugins/tanstack-react-query.mjs.map +0 -1
- package/sync.js.map +0 -1
- package/sync.mjs.map +0 -1
- package/trace.js.map +0 -1
- package/trace.mjs.map +0 -1
package/sync.mjs
CHANGED
|
@@ -1,1065 +1,1012 @@
|
|
|
1
|
-
import { isObject, isDate, isNullOrUndefined, isString,
|
|
1
|
+
import { isObject, isDate, isNullOrUndefined, isString, endBatch, beginBatch, isFunction, observable, when, linked, internal, isPromise, mergeIntoObservable, isEmpty, shouldIgnoreUnobserved, whenReady, constructObjectWithPath, deconstructObjectWithPath, setAtPath, isArray } from '@legendapp/state';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// sync.ts
|
|
4
|
+
|
|
5
|
+
// src/sync/configureObservableSync.ts
|
|
6
|
+
var observableSyncConfiguration = {};
|
|
4
7
|
function configureObservableSync(options) {
|
|
5
|
-
|
|
8
|
+
Object.assign(observableSyncConfiguration, options);
|
|
6
9
|
}
|
|
7
|
-
|
|
8
10
|
function removeNullUndefined(a, recursive) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
const out = {};
|
|
12
|
+
Object.keys(a).forEach((key) => {
|
|
13
|
+
if (a[key] !== null && a[key] !== void 0) {
|
|
14
|
+
out[key] = recursive && isObject(a[key]) ? removeNullUndefined(a[key]) : a[key];
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
return out;
|
|
16
18
|
}
|
|
17
19
|
function diffObjects(obj1, obj2, deep = false) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
20
|
+
const diff = {};
|
|
21
|
+
if (!obj1)
|
|
22
|
+
return obj2 || diff;
|
|
23
|
+
if (!obj2)
|
|
24
|
+
return obj1 || diff;
|
|
25
|
+
const keys = /* @__PURE__ */ new Set([...Object.keys(obj1), ...Object.keys(obj2)]);
|
|
26
|
+
keys.forEach((key) => {
|
|
27
|
+
const o1 = obj1[key];
|
|
28
|
+
const o2 = obj2[key];
|
|
29
|
+
if (deep ? !deepEqual(o1, o2) : o1 !== o2) {
|
|
30
|
+
if (!isDate(o1) || !isDate(o2) || o1.getTime() !== o2.getTime()) {
|
|
31
|
+
diff[key] = o2;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
return diff;
|
|
34
36
|
}
|
|
35
37
|
function deepEqual(a, b, ignoreFields, nullVsUndefined) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
38
|
+
if (a === b) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
if (isNullOrUndefined(a) !== isNullOrUndefined(b)) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
if (nullVsUndefined) {
|
|
45
|
+
a = removeNullUndefined(
|
|
46
|
+
a,
|
|
47
|
+
/*recursive*/
|
|
48
|
+
true
|
|
49
|
+
);
|
|
50
|
+
b = removeNullUndefined(
|
|
51
|
+
b,
|
|
52
|
+
/*recursive*/
|
|
53
|
+
true
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
const replacer = ignoreFields ? (key, value) => ignoreFields.includes(key) ? void 0 : value : void 0;
|
|
57
|
+
return JSON.stringify(a, replacer) === JSON.stringify(b, replacer);
|
|
50
58
|
}
|
|
51
59
|
function combineTransforms(...transforms) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
60
|
+
return {
|
|
61
|
+
load: (value, method) => {
|
|
62
|
+
let inValue = value;
|
|
63
|
+
transforms.forEach((transform) => {
|
|
64
|
+
if (transform.load) {
|
|
65
|
+
inValue = transform.load(inValue, method);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
return inValue;
|
|
69
|
+
},
|
|
70
|
+
save: (value) => {
|
|
71
|
+
let outValue = value;
|
|
72
|
+
transforms.forEach((transform) => {
|
|
73
|
+
if (transform.save) {
|
|
74
|
+
outValue = transform.save(outValue);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
return outValue;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
72
80
|
}
|
|
73
|
-
|
|
81
|
+
var ISO8601 = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/;
|
|
74
82
|
function transformStringifyKeys(...keys) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
83
|
+
return {
|
|
84
|
+
load: (value) => {
|
|
85
|
+
keys.forEach((key) => {
|
|
86
|
+
const keyRemote = isObject(key) ? key.from : key;
|
|
87
|
+
const keyLocal = isObject(key) ? key.to : key;
|
|
88
|
+
const v = value[keyRemote];
|
|
89
|
+
if (!isNullOrUndefined(v)) {
|
|
90
|
+
value[keyLocal] = isString(v) ? JSON.parse(v) : v;
|
|
91
|
+
}
|
|
92
|
+
if (keyLocal !== keyRemote) {
|
|
93
|
+
delete value[keyRemote];
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
return value;
|
|
97
|
+
},
|
|
98
|
+
save: (value) => {
|
|
99
|
+
keys.forEach((key) => {
|
|
100
|
+
const keyRemote = isObject(key) ? key.from : key;
|
|
101
|
+
const keyLocal = isObject(key) ? key.to : key;
|
|
102
|
+
const v = value[keyLocal];
|
|
103
|
+
if (!isNullOrUndefined(v) && !isString(v)) {
|
|
104
|
+
value[keyRemote] = JSON.stringify(v);
|
|
105
|
+
}
|
|
106
|
+
if (keyLocal !== keyRemote) {
|
|
107
|
+
delete value[keyLocal];
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
return value;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
105
113
|
}
|
|
106
114
|
function transformStringifyDates(...args) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
115
|
+
return {
|
|
116
|
+
load: (value) => {
|
|
117
|
+
const keys = args.length > 0 ? args : Object.keys(value);
|
|
118
|
+
for (let i = 0; i < keys.length; i++) {
|
|
119
|
+
const key = keys[i];
|
|
120
|
+
const keyValue = value[key];
|
|
121
|
+
if (isString(keyValue) && keyValue.match(ISO8601)) {
|
|
122
|
+
value[key] = new Date(keyValue);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return value;
|
|
126
|
+
},
|
|
127
|
+
save: (value) => {
|
|
128
|
+
const keys = args.length > 0 ? args : Object.keys(value);
|
|
129
|
+
for (let i = 0; i < keys.length; i++) {
|
|
130
|
+
const key = keys[i];
|
|
131
|
+
const keyValue = value[key];
|
|
132
|
+
if (isDate(keyValue)) {
|
|
133
|
+
value[key] = keyValue.toISOString();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return value;
|
|
137
|
+
}
|
|
138
|
+
};
|
|
131
139
|
}
|
|
132
|
-
|
|
133
140
|
function syncObservableAdapter({ get, set }) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
});
|
|
147
|
-
params.onGet();
|
|
148
|
-
// eslint-disable-next-line no-empty
|
|
149
|
-
}
|
|
150
|
-
catch (_a) { }
|
|
141
|
+
const ret = {};
|
|
142
|
+
if (get) {
|
|
143
|
+
ret.get = async (params) => {
|
|
144
|
+
try {
|
|
145
|
+
let value = get(params);
|
|
146
|
+
if (isPromise(value)) {
|
|
147
|
+
value = await value;
|
|
148
|
+
}
|
|
149
|
+
params.onChange({
|
|
150
|
+
value,
|
|
151
|
+
lastSync: params.lastSync,
|
|
152
|
+
mode: params.mode
|
|
151
153
|
});
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
156
|
-
|
|
154
|
+
params.onGet();
|
|
155
|
+
} catch (e) {
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
if (set) {
|
|
160
|
+
ret.set = set;
|
|
161
|
+
}
|
|
162
|
+
return ret;
|
|
157
163
|
}
|
|
158
164
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
165
|
+
// src/sync/syncObservable.ts
|
|
166
|
+
var { createPreviousHandler, clone, getValueAtPath, globalState, symbolLinked, getNode, getNodeValue } = internal;
|
|
167
|
+
var mapSyncPlugins = /* @__PURE__ */ new WeakMap();
|
|
168
|
+
var metadatas = /* @__PURE__ */ new WeakMap();
|
|
169
|
+
var promisesLocalSaves = /* @__PURE__ */ new Set();
|
|
163
170
|
function parseLocalConfig(config) {
|
|
164
|
-
|
|
165
|
-
? isString(config)
|
|
166
|
-
? { table: config, config: { name: config } }
|
|
167
|
-
: { table: config.name, config }
|
|
168
|
-
: {};
|
|
171
|
+
return config ? isString(config) ? { table: config, config: { name: config } } : { table: config.name, config } : {};
|
|
169
172
|
}
|
|
170
173
|
function doInOrder(arg1, arg2) {
|
|
171
|
-
|
|
174
|
+
return isPromise(arg1) ? arg1.then(arg2) : arg2(arg1);
|
|
172
175
|
}
|
|
173
176
|
function onChangeRemote(cb) {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
// apply to any side effects
|
|
181
|
-
globalState$1.isLoadingRemote = false;
|
|
182
|
-
endBatch(true);
|
|
177
|
+
endBatch(true);
|
|
178
|
+
globalState.isLoadingRemote = true;
|
|
179
|
+
beginBatch();
|
|
180
|
+
cb();
|
|
181
|
+
globalState.isLoadingRemote = false;
|
|
182
|
+
endBatch(true);
|
|
183
183
|
}
|
|
184
184
|
function transformSaveData(value, path, pathTypes, { transform }) {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
185
|
+
if (transform == null ? void 0 : transform.save) {
|
|
186
|
+
const constructed = constructObjectWithPath(path, pathTypes, value);
|
|
187
|
+
const saved = transform.save(constructed);
|
|
188
|
+
value = deconstructObjectWithPath(path, pathTypes, saved);
|
|
189
|
+
}
|
|
190
|
+
return value;
|
|
191
191
|
}
|
|
192
192
|
function transformLoadData(value, { transform }, doUserTransform, method) {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
193
|
+
if (doUserTransform && (transform == null ? void 0 : transform.load)) {
|
|
194
|
+
value = transform.load(value, method);
|
|
195
|
+
}
|
|
196
|
+
return value;
|
|
197
197
|
}
|
|
198
198
|
async function updateMetadataImmediate(value$, localState, syncState, syncOptions, newMetadata) {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
199
|
+
const saves = Array.from(promisesLocalSaves);
|
|
200
|
+
if (saves.length > 0) {
|
|
201
|
+
await Promise.all(saves);
|
|
202
|
+
}
|
|
203
|
+
const { pluginPersist } = localState;
|
|
204
|
+
const { table, config } = parseLocalConfig(syncOptions == null ? void 0 : syncOptions.persist);
|
|
205
|
+
const oldMetadata = metadatas.get(value$);
|
|
206
|
+
const { lastSync, pending } = newMetadata;
|
|
207
|
+
const needsUpdate = pending || lastSync && (!oldMetadata || lastSync !== oldMetadata.lastSync);
|
|
208
|
+
if (needsUpdate) {
|
|
209
|
+
const metadata = Object.assign({}, oldMetadata, newMetadata);
|
|
210
|
+
metadatas.set(value$, metadata);
|
|
211
|
+
if (pluginPersist) {
|
|
212
|
+
await pluginPersist.setMetadata(table, metadata, config);
|
|
202
213
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
const { lastSync, pending } = newMetadata;
|
|
208
|
-
const needsUpdate = pending || (lastSync && (!oldMetadata || lastSync !== oldMetadata.lastSync));
|
|
209
|
-
if (needsUpdate) {
|
|
210
|
-
const metadata = Object.assign({}, oldMetadata, newMetadata);
|
|
211
|
-
metadatas.set(value$, metadata);
|
|
212
|
-
if (pluginPersist) {
|
|
213
|
-
await pluginPersist.setMetadata(table, metadata, config);
|
|
214
|
-
}
|
|
215
|
-
if (lastSync) {
|
|
216
|
-
syncState.assign({
|
|
217
|
-
lastSync: lastSync,
|
|
218
|
-
});
|
|
219
|
-
}
|
|
214
|
+
if (lastSync) {
|
|
215
|
+
syncState.assign({
|
|
216
|
+
lastSync
|
|
217
|
+
});
|
|
220
218
|
}
|
|
219
|
+
}
|
|
221
220
|
}
|
|
222
221
|
function updateMetadata(value$, localState, syncState, syncOptions, newMetadata) {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
222
|
+
if (localState.timeoutSaveMetadata) {
|
|
223
|
+
clearTimeout(localState.timeoutSaveMetadata);
|
|
224
|
+
}
|
|
225
|
+
localState.timeoutSaveMetadata = setTimeout(
|
|
226
|
+
() => updateMetadataImmediate(value$, localState, syncState, syncOptions, newMetadata),
|
|
227
|
+
0
|
|
228
|
+
);
|
|
227
229
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
230
|
+
var _queuedChanges = [];
|
|
231
|
+
var _queuedRemoteChanges = /* @__PURE__ */ new Map();
|
|
232
|
+
var _queuedRemoteChangesTimeouts = /* @__PURE__ */ new Map();
|
|
231
233
|
function mergeChanges(changes) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
}
|
|
248
|
-
else {
|
|
249
|
-
changesByPath.set(pathStr, change);
|
|
250
|
-
changesOut.push(change);
|
|
251
|
-
}
|
|
234
|
+
const changesByPath = /* @__PURE__ */ new Map();
|
|
235
|
+
const changesOut = [];
|
|
236
|
+
for (let i = 0; i < changes.length; i++) {
|
|
237
|
+
const change = changes[i];
|
|
238
|
+
const pathStr = change.path.join("/");
|
|
239
|
+
const existing = changesByPath.get(pathStr);
|
|
240
|
+
if (existing) {
|
|
241
|
+
if (change.valueAtPath === existing.prevAtPath) {
|
|
242
|
+
changesOut.splice(changesOut.indexOf(change), 1);
|
|
243
|
+
} else {
|
|
244
|
+
existing.valueAtPath = change.valueAtPath;
|
|
245
|
+
}
|
|
246
|
+
} else {
|
|
247
|
+
changesByPath.set(pathStr, change);
|
|
248
|
+
changesOut.push(change);
|
|
252
249
|
}
|
|
253
|
-
|
|
250
|
+
}
|
|
251
|
+
return changesOut;
|
|
254
252
|
}
|
|
255
253
|
function mergeQueuedChanges(allChanges) {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
}
|
|
274
|
-
value.valuePrevious = previousByObs.get(obs);
|
|
275
|
-
targetMap.set(obs, value);
|
|
254
|
+
const changesByObsRemote = /* @__PURE__ */ new Map();
|
|
255
|
+
const changesByObsLocal = /* @__PURE__ */ new Map();
|
|
256
|
+
const previousByObs = /* @__PURE__ */ new Map();
|
|
257
|
+
const outRemote = /* @__PURE__ */ new Map();
|
|
258
|
+
const outLocal = /* @__PURE__ */ new Map();
|
|
259
|
+
for (let i = 0; i < allChanges.length; i++) {
|
|
260
|
+
const value = allChanges[i];
|
|
261
|
+
const { value$: obs, changes, inRemoteChange, getPrevious } = value;
|
|
262
|
+
const targetMap = inRemoteChange ? outRemote : outLocal;
|
|
263
|
+
const changesMap = inRemoteChange ? changesByObsRemote : changesByObsLocal;
|
|
264
|
+
const existing = changesMap.get(obs);
|
|
265
|
+
const newChanges = existing ? [...existing, ...changes] : changes;
|
|
266
|
+
const merged = mergeChanges(newChanges);
|
|
267
|
+
changesMap.set(obs, merged);
|
|
268
|
+
value.changes = merged;
|
|
269
|
+
if (!previousByObs.has(obs)) {
|
|
270
|
+
previousByObs.set(obs, getPrevious());
|
|
276
271
|
}
|
|
277
|
-
|
|
272
|
+
value.valuePrevious = previousByObs.get(obs);
|
|
273
|
+
targetMap.set(obs, value);
|
|
274
|
+
}
|
|
275
|
+
return Array.from(outRemote.values()).concat(Array.from(outLocal.values()));
|
|
278
276
|
}
|
|
279
277
|
async function processQueuedChanges() {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
_queuedRemoteChanges.get(change.syncOptions).push(change);
|
|
293
|
-
}
|
|
278
|
+
var _a, _b;
|
|
279
|
+
const queuedChanges = mergeQueuedChanges(_queuedChanges);
|
|
280
|
+
_queuedChanges = [];
|
|
281
|
+
const pendingSyncOptions = /* @__PURE__ */ new Set();
|
|
282
|
+
for (let i = 0; i < queuedChanges.length; i++) {
|
|
283
|
+
const change = queuedChanges[i];
|
|
284
|
+
if (!change.inRemoteChange) {
|
|
285
|
+
if (!_queuedRemoteChanges.has(change.syncOptions)) {
|
|
286
|
+
_queuedRemoteChanges.set(change.syncOptions, []);
|
|
287
|
+
}
|
|
288
|
+
pendingSyncOptions.add(change.syncOptions);
|
|
289
|
+
_queuedRemoteChanges.get(change.syncOptions).push(change);
|
|
294
290
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
await Promise.all(queuedChanges.map(prepChangeRemote));
|
|
311
|
-
await Promise.all(preppedChangesLocal.map(doChangeLocal));
|
|
312
|
-
for (const options of pendingSyncOptions) {
|
|
313
|
-
const timeout = (_a = options.debounceSet) !== null && _a !== void 0 ? _a : observableSyncConfiguration === null || observableSyncConfiguration === void 0 ? void 0 : observableSyncConfiguration.debounceSet;
|
|
314
|
-
const timeoutSaveRemote = _queuedRemoteChangesTimeouts.get(options);
|
|
315
|
-
const run = () => processQueuedRemoteChanges(options);
|
|
316
|
-
if (timeout) {
|
|
317
|
-
if (timeoutSaveRemote) {
|
|
318
|
-
clearTimeout(timeoutSaveRemote);
|
|
319
|
-
}
|
|
320
|
-
_queuedRemoteChangesTimeouts.set(options, setTimeout(run, timeout));
|
|
321
|
-
}
|
|
322
|
-
else {
|
|
323
|
-
run();
|
|
324
|
-
}
|
|
291
|
+
}
|
|
292
|
+
const preppedChangesLocal = await Promise.all(queuedChanges.map(prepChangeLocal));
|
|
293
|
+
await Promise.all(queuedChanges.map(prepChangeRemote));
|
|
294
|
+
await Promise.all(preppedChangesLocal.map(doChangeLocal));
|
|
295
|
+
for (const options of pendingSyncOptions) {
|
|
296
|
+
const timeout = (_b = options.debounceSet) != null ? _b : (_a = observableSyncConfiguration) == null ? void 0 : _a.debounceSet;
|
|
297
|
+
const timeoutSaveRemote = _queuedRemoteChangesTimeouts.get(options);
|
|
298
|
+
const run = () => processQueuedRemoteChanges(options);
|
|
299
|
+
if (timeout) {
|
|
300
|
+
if (timeoutSaveRemote) {
|
|
301
|
+
clearTimeout(timeoutSaveRemote);
|
|
302
|
+
}
|
|
303
|
+
_queuedRemoteChangesTimeouts.set(options, setTimeout(run, timeout));
|
|
304
|
+
} else {
|
|
305
|
+
run();
|
|
325
306
|
}
|
|
307
|
+
}
|
|
326
308
|
}
|
|
327
309
|
async function processQueuedRemoteChanges(syncOptions) {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
310
|
+
const arr = _queuedRemoteChanges.get(syncOptions);
|
|
311
|
+
if (arr == null ? void 0 : arr.length) {
|
|
312
|
+
const queuedRemoteChanges = mergeQueuedChanges(arr);
|
|
313
|
+
_queuedRemoteChanges.set(syncOptions, []);
|
|
314
|
+
const preppedChangesRemote = await Promise.all(queuedRemoteChanges.map(prepChangeRemote));
|
|
315
|
+
preppedChangesRemote.forEach(doChangeRemote);
|
|
316
|
+
}
|
|
335
317
|
}
|
|
336
318
|
async function prepChangeLocal(queuedChange) {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
}
|
|
352
|
-
const changesLocal = [];
|
|
353
|
-
const changesPaths = new Set();
|
|
354
|
-
let promisesTransform = [];
|
|
355
|
-
// Reverse order
|
|
356
|
-
for (let i = changes.length - 1; i >= 0; i--) {
|
|
357
|
-
const { path } = changes[i];
|
|
358
|
-
let found = false;
|
|
359
|
-
// Optimization to only save the latest update at each path. We might have multiple changes at the same path
|
|
360
|
-
// and we only need the latest value, so it starts from the end of the array, skipping any earlier changes
|
|
361
|
-
// already processed. If a later change modifies a parent of an earlier change (which happens on delete()
|
|
362
|
-
// it should be ignored as it's superseded by the parent modification.
|
|
363
|
-
if (changesPaths.size > 0) {
|
|
364
|
-
for (let u = 0; u < path.length; u++) {
|
|
365
|
-
if (changesPaths.has((u === path.length - 1 ? path : path.slice(0, u + 1)).join('/'))) {
|
|
366
|
-
found = true;
|
|
367
|
-
break;
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
if (!found) {
|
|
372
|
-
const pathStr = path.join('/');
|
|
373
|
-
changesPaths.add(pathStr);
|
|
374
|
-
const { prevAtPath, valueAtPath, pathTypes } = changes[i];
|
|
375
|
-
if (saveLocal) {
|
|
376
|
-
const promiseTransformLocal = transformSaveData(valueAtPath, path, pathTypes, configLocal);
|
|
377
|
-
promisesTransform.push(doInOrder(promiseTransformLocal, (valueTransformed) => {
|
|
378
|
-
// Prepare the local change with the transformed path/value
|
|
379
|
-
changesLocal.push({
|
|
380
|
-
path,
|
|
381
|
-
pathTypes,
|
|
382
|
-
prevAtPath,
|
|
383
|
-
valueAtPath: valueTransformed,
|
|
384
|
-
pathStr,
|
|
385
|
-
});
|
|
386
|
-
}));
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
// If there's any transform promises, wait for them before saving
|
|
391
|
-
promisesTransform = promisesTransform.filter(Boolean);
|
|
392
|
-
if (promisesTransform.length > 0) {
|
|
393
|
-
await Promise.all(promisesTransform);
|
|
394
|
-
}
|
|
395
|
-
return { queuedChange, changesLocal, saveRemote };
|
|
319
|
+
const { syncState, changes, localState, syncOptions, inRemoteChange, isApplyingPending } = queuedChange;
|
|
320
|
+
const persist = syncOptions.persist;
|
|
321
|
+
const { pluginSync } = localState;
|
|
322
|
+
const { config: configLocal } = parseLocalConfig(persist);
|
|
323
|
+
const configRemote = syncOptions;
|
|
324
|
+
const saveLocal = (persist == null ? void 0 : persist.name) && !configLocal.readonly && !isApplyingPending && syncState.isPersistEnabled.peek();
|
|
325
|
+
const saveRemote = !!(!inRemoteChange && (pluginSync == null ? void 0 : pluginSync.set) && (configRemote == null ? void 0 : configRemote.enableSync) !== false && syncState.isSyncEnabled.peek());
|
|
326
|
+
if (saveLocal || saveRemote) {
|
|
327
|
+
if (saveLocal && !syncState.isPersistLoaded.peek()) {
|
|
328
|
+
console.error(
|
|
329
|
+
"[legend-state] WARNING: An observable was changed before being loaded from persist",
|
|
330
|
+
persist
|
|
331
|
+
);
|
|
332
|
+
return void 0;
|
|
396
333
|
}
|
|
334
|
+
const changesLocal = [];
|
|
335
|
+
const changesPaths = /* @__PURE__ */ new Set();
|
|
336
|
+
let promisesTransform = [];
|
|
337
|
+
for (let i = changes.length - 1; i >= 0; i--) {
|
|
338
|
+
const { path } = changes[i];
|
|
339
|
+
let found = false;
|
|
340
|
+
if (changesPaths.size > 0) {
|
|
341
|
+
for (let u = 0; u < path.length; u++) {
|
|
342
|
+
if (changesPaths.has((u === path.length - 1 ? path : path.slice(0, u + 1)).join("/"))) {
|
|
343
|
+
found = true;
|
|
344
|
+
break;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
if (!found) {
|
|
349
|
+
const pathStr = path.join("/");
|
|
350
|
+
changesPaths.add(pathStr);
|
|
351
|
+
const { prevAtPath, valueAtPath, pathTypes } = changes[i];
|
|
352
|
+
if (saveLocal) {
|
|
353
|
+
const promiseTransformLocal = transformSaveData(
|
|
354
|
+
valueAtPath,
|
|
355
|
+
path,
|
|
356
|
+
pathTypes,
|
|
357
|
+
configLocal
|
|
358
|
+
);
|
|
359
|
+
promisesTransform.push(
|
|
360
|
+
doInOrder(promiseTransformLocal, (valueTransformed) => {
|
|
361
|
+
changesLocal.push({
|
|
362
|
+
path,
|
|
363
|
+
pathTypes,
|
|
364
|
+
prevAtPath,
|
|
365
|
+
valueAtPath: valueTransformed,
|
|
366
|
+
pathStr
|
|
367
|
+
});
|
|
368
|
+
})
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
promisesTransform = promisesTransform.filter(Boolean);
|
|
374
|
+
if (promisesTransform.length > 0) {
|
|
375
|
+
await Promise.all(promisesTransform);
|
|
376
|
+
}
|
|
377
|
+
return { queuedChange, changesLocal, saveRemote };
|
|
378
|
+
}
|
|
397
379
|
}
|
|
398
380
|
async function prepChangeRemote(queuedChange) {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
381
|
+
const {
|
|
382
|
+
syncState,
|
|
383
|
+
changes,
|
|
384
|
+
localState,
|
|
385
|
+
syncOptions,
|
|
386
|
+
inRemoteChange,
|
|
387
|
+
isApplyingPending,
|
|
388
|
+
valuePrevious
|
|
389
|
+
} = queuedChange;
|
|
390
|
+
const persist = syncOptions.persist;
|
|
391
|
+
const { pluginSync } = localState;
|
|
392
|
+
const { config: configLocal } = parseLocalConfig(persist);
|
|
393
|
+
const configRemote = syncOptions;
|
|
394
|
+
const saveLocal = persist && !configLocal.readonly && !isApplyingPending && syncState.isPersistEnabled.peek();
|
|
395
|
+
const saveRemote = !inRemoteChange && (pluginSync == null ? void 0 : pluginSync.set) && (configRemote == null ? void 0 : configRemote.enableSync) !== false && syncState.isSyncEnabled.peek();
|
|
396
|
+
if (saveLocal || saveRemote) {
|
|
397
|
+
if (saveLocal && !syncState.isPersistLoaded.peek()) {
|
|
398
|
+
console.error(
|
|
399
|
+
"[legend-state] WARNING: An observable was changed before being loaded from persist",
|
|
400
|
+
persist
|
|
401
|
+
);
|
|
402
|
+
return void 0;
|
|
403
|
+
}
|
|
404
|
+
const changesRemote = [];
|
|
405
|
+
const changesPaths = /* @__PURE__ */ new Set();
|
|
406
|
+
let promisesTransform = [];
|
|
407
|
+
for (let i = changes.length - 1; i >= 0; i--) {
|
|
408
|
+
const { path } = changes[i];
|
|
409
|
+
let found = false;
|
|
410
|
+
if (changesPaths.size > 0) {
|
|
411
|
+
for (let u = 0; u < path.length; u++) {
|
|
412
|
+
if (changesPaths.has((u === path.length - 1 ? path : path.slice(0, u + 1)).join("/"))) {
|
|
413
|
+
found = true;
|
|
414
|
+
break;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
if (!found) {
|
|
419
|
+
const pathStr = path.join("/");
|
|
420
|
+
changesPaths.add(pathStr);
|
|
421
|
+
const { prevAtPath, valueAtPath, pathTypes } = changes[i];
|
|
422
|
+
if (saveRemote) {
|
|
423
|
+
const promiseTransformRemote = transformSaveData(
|
|
424
|
+
valueAtPath,
|
|
425
|
+
path,
|
|
426
|
+
pathTypes,
|
|
427
|
+
configRemote || {}
|
|
428
|
+
);
|
|
429
|
+
promisesTransform.push(
|
|
430
|
+
doInOrder(promiseTransformRemote, (valueTransformed) => {
|
|
431
|
+
var _a;
|
|
432
|
+
if (!localState.pendingChanges) {
|
|
433
|
+
localState.pendingChanges = {};
|
|
434
|
+
}
|
|
435
|
+
let found2 = false;
|
|
436
|
+
for (let i2 = 0; !found2 && i2 < path.length - 1; i2++) {
|
|
437
|
+
const pathParent = path.slice(0, i2 + 1).join("/");
|
|
438
|
+
if ((_a = localState.pendingChanges[pathParent]) == null ? void 0 : _a.v) {
|
|
439
|
+
found2 = true;
|
|
440
|
+
const pathChild = path.slice(i2 + 1);
|
|
441
|
+
const pathTypesChild = pathTypes.slice(i2 + 1);
|
|
442
|
+
setAtPath(
|
|
443
|
+
localState.pendingChanges[pathParent].v,
|
|
444
|
+
pathChild,
|
|
445
|
+
pathTypesChild,
|
|
446
|
+
valueAtPath
|
|
447
|
+
);
|
|
428
448
|
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
const
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
const promiseTransformRemote = transformSaveData(valueAtPath, path, pathTypes, configRemote || {});
|
|
436
|
-
promisesTransform.push(doInOrder(promiseTransformRemote, (valueTransformed) => {
|
|
437
|
-
var _a;
|
|
438
|
-
// Prepare pending changes
|
|
439
|
-
if (!localState.pendingChanges) {
|
|
440
|
-
localState.pendingChanges = {};
|
|
441
|
-
}
|
|
442
|
-
// First look for existing pending changes at a higher level than this change
|
|
443
|
-
// If they exist then merge this change into it
|
|
444
|
-
let found = false;
|
|
445
|
-
for (let i = 0; !found && i < path.length - 1; i++) {
|
|
446
|
-
const pathParent = path.slice(0, i + 1).join('/');
|
|
447
|
-
if ((_a = localState.pendingChanges[pathParent]) === null || _a === void 0 ? void 0 : _a.v) {
|
|
448
|
-
found = true;
|
|
449
|
-
const pathChild = path.slice(i + 1);
|
|
450
|
-
const pathTypesChild = pathTypes.slice(i + 1);
|
|
451
|
-
setAtPath(localState.pendingChanges[pathParent].v, pathChild, pathTypesChild, valueAtPath);
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
if (!found) {
|
|
455
|
-
// If an existing pending change is deeper than this change, just delete it
|
|
456
|
-
// in favor of this wider change
|
|
457
|
-
for (const key in localState.pendingChanges) {
|
|
458
|
-
if (key !== pathStr && key.startsWith(pathStr)) {
|
|
459
|
-
delete localState.pendingChanges[key];
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
// The "p" saved in pending should be the previous state before changes,
|
|
463
|
-
// so don't overwrite it if it already exists
|
|
464
|
-
if (!localState.pendingChanges[pathStr]) {
|
|
465
|
-
localState.pendingChanges[pathStr] = { p: prevAtPath !== null && prevAtPath !== void 0 ? prevAtPath : null, t: pathTypes };
|
|
466
|
-
}
|
|
467
|
-
// Pending value is the untransformed value because it gets loaded without transformment
|
|
468
|
-
// and forwarded through to onObsChange where it gets transformed before save
|
|
469
|
-
localState.pendingChanges[pathStr].v = valueAtPath;
|
|
470
|
-
}
|
|
471
|
-
// Prepare the remote change with the transformed path/value
|
|
472
|
-
changesRemote.push({
|
|
473
|
-
path,
|
|
474
|
-
pathTypes,
|
|
475
|
-
prevAtPath,
|
|
476
|
-
valueAtPath: valueTransformed,
|
|
477
|
-
pathStr,
|
|
478
|
-
valuePrevious,
|
|
479
|
-
});
|
|
480
|
-
}));
|
|
449
|
+
}
|
|
450
|
+
if (!found2) {
|
|
451
|
+
for (const key in localState.pendingChanges) {
|
|
452
|
+
if (key !== pathStr && key.startsWith(pathStr)) {
|
|
453
|
+
delete localState.pendingChanges[key];
|
|
454
|
+
}
|
|
481
455
|
}
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
456
|
+
if (!localState.pendingChanges[pathStr]) {
|
|
457
|
+
localState.pendingChanges[pathStr] = { p: prevAtPath != null ? prevAtPath : null, t: pathTypes };
|
|
458
|
+
}
|
|
459
|
+
localState.pendingChanges[pathStr].v = valueAtPath;
|
|
460
|
+
}
|
|
461
|
+
changesRemote.push({
|
|
462
|
+
path,
|
|
463
|
+
pathTypes,
|
|
464
|
+
prevAtPath,
|
|
465
|
+
valueAtPath: valueTransformed,
|
|
466
|
+
pathStr,
|
|
467
|
+
valuePrevious
|
|
468
|
+
});
|
|
469
|
+
})
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
promisesTransform = promisesTransform.filter(Boolean);
|
|
475
|
+
if (promisesTransform.length > 0) {
|
|
476
|
+
await Promise.all(promisesTransform);
|
|
490
477
|
}
|
|
478
|
+
return { queuedChange, changesRemote };
|
|
479
|
+
}
|
|
491
480
|
}
|
|
492
481
|
async function doChangeLocal(changeInfo) {
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
});
|
|
515
|
-
// Keep track of local save promises so that updateMetadata runs only after everything is saved
|
|
516
|
-
promisesLocalSaves.add(promiseSet);
|
|
517
|
-
// await the local save before proceeding to save remotely
|
|
518
|
-
await promiseSet;
|
|
519
|
-
}
|
|
482
|
+
if (!changeInfo)
|
|
483
|
+
return;
|
|
484
|
+
const { queuedChange, changesLocal, saveRemote } = changeInfo;
|
|
485
|
+
const { value$: obs, syncState, localState, syncOptions } = queuedChange;
|
|
486
|
+
const { pluginPersist } = localState;
|
|
487
|
+
const persist = syncOptions.persist;
|
|
488
|
+
const { table, config: configLocal } = parseLocalConfig(persist);
|
|
489
|
+
const shouldSaveMetadata = persist == null ? void 0 : persist.retrySync;
|
|
490
|
+
if (saveRemote && shouldSaveMetadata) {
|
|
491
|
+
await updateMetadataImmediate(obs, localState, syncState, syncOptions, {
|
|
492
|
+
pending: localState.pendingChanges
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
if (changesLocal.length > 0) {
|
|
496
|
+
let promiseSet = pluginPersist.set(table, changesLocal, configLocal);
|
|
497
|
+
if (promiseSet) {
|
|
498
|
+
promiseSet = promiseSet.then(() => {
|
|
499
|
+
promisesLocalSaves.delete(promiseSet);
|
|
500
|
+
});
|
|
501
|
+
promisesLocalSaves.add(promiseSet);
|
|
502
|
+
await promiseSet;
|
|
520
503
|
}
|
|
504
|
+
}
|
|
521
505
|
}
|
|
522
506
|
async function doChangeRemote(changeInfo) {
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
507
|
+
var _a, _b;
|
|
508
|
+
if (!changeInfo)
|
|
509
|
+
return;
|
|
510
|
+
const { queuedChange, changesRemote } = changeInfo;
|
|
511
|
+
const { value$: obs, syncState, localState, syncOptions, valuePrevious: previous } = queuedChange;
|
|
512
|
+
const { pluginPersist, pluginSync } = localState;
|
|
513
|
+
const persist = syncOptions.persist;
|
|
514
|
+
const { table, config: configLocal } = parseLocalConfig(persist);
|
|
515
|
+
const { allowSetIfGetError, onBeforeSet, onSetError, waitForSet, onAfterSet } = syncOptions || {};
|
|
516
|
+
const shouldSaveMetadata = persist == null ? void 0 : persist.retrySync;
|
|
517
|
+
if (changesRemote.length > 0) {
|
|
518
|
+
await when(() => syncState.isLoaded.get() || allowSetIfGetError && syncState.error.get());
|
|
519
|
+
if (waitForSet) {
|
|
520
|
+
const waitFor = isFunction(waitForSet) ? waitForSet({ changes: changesRemote, value: obs.peek() }) : waitForSet;
|
|
521
|
+
if (waitFor) {
|
|
522
|
+
await when(waitFor);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
let value = obs.peek();
|
|
526
|
+
const transformSave = (_a = syncOptions == null ? void 0 : syncOptions.transform) == null ? void 0 : _a.save;
|
|
527
|
+
if (transformSave) {
|
|
528
|
+
value = transformSave(clone(value));
|
|
529
|
+
}
|
|
530
|
+
onBeforeSet == null ? void 0 : onBeforeSet();
|
|
531
|
+
localState.numSavesOutstanding = (localState.numSavesOutstanding || 0) + 1;
|
|
532
|
+
let savedPromise = pluginSync.set({
|
|
533
|
+
value$: obs,
|
|
534
|
+
syncState,
|
|
535
|
+
options: syncOptions,
|
|
536
|
+
changes: changesRemote,
|
|
537
|
+
value,
|
|
538
|
+
valuePrevious: previous
|
|
539
|
+
});
|
|
540
|
+
if (isPromise(savedPromise)) {
|
|
541
|
+
savedPromise = savedPromise.catch((err) => onSetError == null ? void 0 : onSetError(err));
|
|
542
|
+
}
|
|
543
|
+
const saved = await savedPromise;
|
|
544
|
+
localState.numSavesOutstanding--;
|
|
545
|
+
if (saved !== void 0) {
|
|
546
|
+
const pathStrs = Array.from(new Set(changesRemote.map((change) => change.pathStr)));
|
|
547
|
+
const { changes, lastSync } = saved;
|
|
548
|
+
if (pathStrs.length > 0) {
|
|
549
|
+
let transformedChanges = void 0;
|
|
550
|
+
const metadata = {};
|
|
551
|
+
if (persist) {
|
|
552
|
+
const pendingMetadata = (_b = pluginPersist.getMetadata(table, configLocal)) == null ? void 0 : _b.pending;
|
|
553
|
+
const pending = localState.pendingChanges;
|
|
554
|
+
for (let i = 0; i < pathStrs.length; i++) {
|
|
555
|
+
const pathStr = pathStrs[i];
|
|
556
|
+
if (pendingMetadata == null ? void 0 : pendingMetadata[pathStr]) {
|
|
557
|
+
delete pendingMetadata[pathStr];
|
|
558
|
+
metadata.pending = pendingMetadata;
|
|
542
559
|
}
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
valuePrevious: previous,
|
|
559
|
-
});
|
|
560
|
-
if (isPromise(savedPromise)) {
|
|
561
|
-
savedPromise = savedPromise.catch((err) => onSetError === null || onSetError === void 0 ? void 0 : onSetError(err));
|
|
562
|
-
}
|
|
563
|
-
const saved = await savedPromise;
|
|
564
|
-
localState.numSavesOutstanding--;
|
|
565
|
-
// If this remote save changed anything then update cache and metadata
|
|
566
|
-
// Because save happens after a timeout and they're batched together, some calls to save will
|
|
567
|
-
// return saved data and others won't, so those can be ignored.
|
|
568
|
-
if (saved !== undefined) {
|
|
569
|
-
const pathStrs = Array.from(new Set(changesRemote.map((change) => change.pathStr)));
|
|
570
|
-
const { changes, lastSync } = saved;
|
|
571
|
-
if (pathStrs.length > 0) {
|
|
572
|
-
let transformedChanges = undefined;
|
|
573
|
-
const metadata = {};
|
|
574
|
-
if (persist) {
|
|
575
|
-
const pendingMetadata = (_b = pluginPersist.getMetadata(table, configLocal)) === null || _b === void 0 ? void 0 : _b.pending;
|
|
576
|
-
const pending = localState.pendingChanges;
|
|
577
|
-
for (let i = 0; i < pathStrs.length; i++) {
|
|
578
|
-
const pathStr = pathStrs[i];
|
|
579
|
-
// Clear pending for this path
|
|
580
|
-
if (pendingMetadata === null || pendingMetadata === void 0 ? void 0 : pendingMetadata[pathStr]) {
|
|
581
|
-
// Remove pending from persisted medata state
|
|
582
|
-
delete pendingMetadata[pathStr];
|
|
583
|
-
metadata.pending = pendingMetadata;
|
|
584
|
-
}
|
|
585
|
-
// Clear pending for this path if not already removed by above
|
|
586
|
-
// pendingMetadata === pending sometimes
|
|
587
|
-
if (pending === null || pending === void 0 ? void 0 : pending[pathStr]) {
|
|
588
|
-
// Remove pending from local state
|
|
589
|
-
delete pending[pathStr];
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
if (lastSync) {
|
|
593
|
-
metadata.lastSync = lastSync;
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
// Remote can optionally have data that needs to be merged back into the observable,
|
|
597
|
-
// for example Firebase may update dateModified with the server timestamp
|
|
598
|
-
if (changes && !isEmpty(changes)) {
|
|
599
|
-
transformedChanges = transformLoadData(changes, syncOptions, false, 'set');
|
|
600
|
-
}
|
|
601
|
-
if (localState.numSavesOutstanding > 0) {
|
|
602
|
-
if (transformedChanges) {
|
|
603
|
-
if (!localState.pendingSaveResults) {
|
|
604
|
-
localState.pendingSaveResults = [];
|
|
605
|
-
}
|
|
606
|
-
localState.pendingSaveResults.push(transformedChanges);
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
else {
|
|
610
|
-
let allChanges = [...(localState.pendingSaveResults || []), transformedChanges].filter((v) => v !== undefined);
|
|
611
|
-
if (allChanges.length > 0) {
|
|
612
|
-
if (allChanges.some((change) => isPromise(change))) {
|
|
613
|
-
allChanges = await Promise.all(allChanges);
|
|
614
|
-
}
|
|
615
|
-
onChangeRemote(() => mergeIntoObservable(obs, ...allChanges));
|
|
616
|
-
}
|
|
617
|
-
if (persist) {
|
|
618
|
-
if (shouldSaveMetadata && !isEmpty(metadata)) {
|
|
619
|
-
updateMetadata(obs, localState, syncState, syncOptions, metadata);
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
localState.pendingSaveResults = [];
|
|
623
|
-
}
|
|
624
|
-
onAfterSet === null || onAfterSet === void 0 ? void 0 : onAfterSet();
|
|
560
|
+
if (pending == null ? void 0 : pending[pathStr]) {
|
|
561
|
+
delete pending[pathStr];
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
if (lastSync) {
|
|
565
|
+
metadata.lastSync = lastSync;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
if (changes && !isEmpty(changes)) {
|
|
569
|
+
transformedChanges = transformLoadData(changes, syncOptions, false, "set");
|
|
570
|
+
}
|
|
571
|
+
if (localState.numSavesOutstanding > 0) {
|
|
572
|
+
if (transformedChanges) {
|
|
573
|
+
if (!localState.pendingSaveResults) {
|
|
574
|
+
localState.pendingSaveResults = [];
|
|
625
575
|
}
|
|
576
|
+
localState.pendingSaveResults.push(transformedChanges);
|
|
577
|
+
}
|
|
578
|
+
} else {
|
|
579
|
+
let allChanges = [...localState.pendingSaveResults || [], transformedChanges].filter(
|
|
580
|
+
(v) => v !== void 0
|
|
581
|
+
);
|
|
582
|
+
if (allChanges.length > 0) {
|
|
583
|
+
if (allChanges.some((change) => isPromise(change))) {
|
|
584
|
+
allChanges = await Promise.all(allChanges);
|
|
585
|
+
}
|
|
586
|
+
onChangeRemote(() => mergeIntoObservable(obs, ...allChanges));
|
|
587
|
+
}
|
|
588
|
+
if (persist) {
|
|
589
|
+
if (shouldSaveMetadata && !isEmpty(metadata)) {
|
|
590
|
+
updateMetadata(obs, localState, syncState, syncOptions, metadata);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
localState.pendingSaveResults = [];
|
|
626
594
|
}
|
|
595
|
+
onAfterSet == null ? void 0 : onAfterSet();
|
|
596
|
+
}
|
|
627
597
|
}
|
|
598
|
+
}
|
|
628
599
|
}
|
|
629
600
|
function onObsChange(value$, syncState, localState, syncOptions, { changes, loading, remote, getPrevious }) {
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
queueMicrotask(processQueuedChanges);
|
|
646
|
-
}
|
|
601
|
+
if (!loading) {
|
|
602
|
+
const inRemoteChange = remote;
|
|
603
|
+
const isApplyingPending = localState.isApplyingPending;
|
|
604
|
+
_queuedChanges.push({
|
|
605
|
+
value$,
|
|
606
|
+
syncState,
|
|
607
|
+
localState,
|
|
608
|
+
syncOptions,
|
|
609
|
+
changes,
|
|
610
|
+
inRemoteChange,
|
|
611
|
+
isApplyingPending,
|
|
612
|
+
getPrevious
|
|
613
|
+
});
|
|
614
|
+
if (_queuedChanges.length === 1) {
|
|
615
|
+
queueMicrotask(processQueuedChanges);
|
|
647
616
|
}
|
|
617
|
+
}
|
|
648
618
|
}
|
|
649
619
|
async function loadLocal(value$, syncOptions, syncState, localState) {
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
localState.pendingChanges = metadata.pending;
|
|
693
|
-
syncState.assign({
|
|
694
|
-
lastSync: metadata.lastSync,
|
|
695
|
-
});
|
|
696
|
-
}
|
|
697
|
-
// Merge the data from local cache into the default state
|
|
698
|
-
if (value !== undefined) {
|
|
699
|
-
const { transform } = config;
|
|
700
|
-
value = transformLoadData(value, { transform }, true, 'get');
|
|
701
|
-
if (isPromise(value)) {
|
|
702
|
-
value = await value;
|
|
703
|
-
}
|
|
704
|
-
// isLoadingLocal prevents saving remotely when two different caches
|
|
705
|
-
// are set on the same observable
|
|
706
|
-
internal$1.globalState.isLoadingLocal = true;
|
|
707
|
-
// We want to merge the local data on top of any initial state the object is created with
|
|
708
|
-
if (value === null && (!prevValue || prevValue[symbolLinked$1])) {
|
|
709
|
-
value$.set(value);
|
|
710
|
-
}
|
|
711
|
-
else {
|
|
712
|
-
mergeIntoObservable(value$, value);
|
|
713
|
-
}
|
|
714
|
-
internal$1.globalState.isLoadingLocal = false;
|
|
715
|
-
}
|
|
716
|
-
getNodeValue$1(getNode(node.state)).clearPersist = () => Promise.all([
|
|
717
|
-
persistPlugin.deleteTable(table, config),
|
|
718
|
-
persistPlugin.deleteMetadata(table, config),
|
|
719
|
-
]);
|
|
620
|
+
var _a, _b, _c;
|
|
621
|
+
const { persist } = syncOptions;
|
|
622
|
+
if (persist) {
|
|
623
|
+
const PersistPlugin = persist.plugin || ((_a = observableSyncConfiguration.persist) == null ? void 0 : _a.plugin);
|
|
624
|
+
const { table, config } = parseLocalConfig(persist);
|
|
625
|
+
const node = getNode(value$);
|
|
626
|
+
if (!PersistPlugin) {
|
|
627
|
+
throw new Error("Local persist is not configured");
|
|
628
|
+
}
|
|
629
|
+
if (!mapSyncPlugins.has(PersistPlugin)) {
|
|
630
|
+
const persistPlugin2 = new PersistPlugin();
|
|
631
|
+
const mapValue = { plugin: persistPlugin2, initialized: observable(false) };
|
|
632
|
+
mapSyncPlugins.set(PersistPlugin, mapValue);
|
|
633
|
+
if (persistPlugin2.initialize) {
|
|
634
|
+
const initializePromise = (_c = persistPlugin2.initialize) == null ? void 0 : _c.call(persistPlugin2, ((_b = observableSyncConfiguration) == null ? void 0 : _b.persist) || {});
|
|
635
|
+
if (isPromise(initializePromise)) {
|
|
636
|
+
await initializePromise;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
mapValue.initialized.set(true);
|
|
640
|
+
}
|
|
641
|
+
const { plugin, initialized: initialized$ } = mapSyncPlugins.get(PersistPlugin);
|
|
642
|
+
const persistPlugin = plugin;
|
|
643
|
+
localState.pluginPersist = persistPlugin;
|
|
644
|
+
if (!initialized$.peek()) {
|
|
645
|
+
await when(initialized$);
|
|
646
|
+
}
|
|
647
|
+
if (persistPlugin.loadTable) {
|
|
648
|
+
const promise = persistPlugin.loadTable(table, config);
|
|
649
|
+
if (promise) {
|
|
650
|
+
await promise;
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
const prevValue = getNodeValue(node);
|
|
654
|
+
let value = persistPlugin.getTable(table, prevValue, config);
|
|
655
|
+
const metadata = persistPlugin.getMetadata(table, config);
|
|
656
|
+
if (metadata) {
|
|
657
|
+
metadatas.set(value$, metadata);
|
|
658
|
+
localState.pendingChanges = metadata.pending;
|
|
659
|
+
syncState.assign({
|
|
660
|
+
lastSync: metadata.lastSync
|
|
661
|
+
});
|
|
720
662
|
}
|
|
721
|
-
|
|
663
|
+
if (value !== void 0) {
|
|
664
|
+
const { transform } = config;
|
|
665
|
+
value = transformLoadData(value, { transform }, true, "get");
|
|
666
|
+
if (isPromise(value)) {
|
|
667
|
+
value = await value;
|
|
668
|
+
}
|
|
669
|
+
internal.globalState.isLoadingLocal = true;
|
|
670
|
+
if (value === null && (!prevValue || prevValue[symbolLinked])) {
|
|
671
|
+
value$.set(value);
|
|
672
|
+
} else {
|
|
673
|
+
mergeIntoObservable(value$, value);
|
|
674
|
+
}
|
|
675
|
+
internal.globalState.isLoadingLocal = false;
|
|
676
|
+
}
|
|
677
|
+
getNodeValue(getNode(node.state)).clearPersist = () => Promise.all([
|
|
678
|
+
persistPlugin.deleteTable(table, config),
|
|
679
|
+
persistPlugin.deleteMetadata(table, config)
|
|
680
|
+
]);
|
|
681
|
+
}
|
|
682
|
+
syncState.isPersistLoaded.set(true);
|
|
722
683
|
}
|
|
723
684
|
function syncObservable(obs$, syncOptionsOrSynced) {
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
updateMetadata(obs$, localState, syncState, syncOptions, {
|
|
811
|
-
pending,
|
|
812
|
-
});
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
onChangeRemote(() => {
|
|
816
|
-
if (mode === 'assign' && isObject(value)) {
|
|
817
|
-
obs$.assign(value);
|
|
818
|
-
}
|
|
819
|
-
else if (mode === 'append' && isArray(value)) {
|
|
820
|
-
obs$.push(...value);
|
|
821
|
-
}
|
|
822
|
-
else if (mode === 'prepend' && isArray(value)) {
|
|
823
|
-
obs$.splice(0, 0, ...value);
|
|
824
|
-
}
|
|
825
|
-
else if (mode === 'merge') {
|
|
826
|
-
mergeIntoObservable(obs$, value);
|
|
827
|
-
}
|
|
828
|
-
else {
|
|
829
|
-
obs$.set(value);
|
|
830
|
-
}
|
|
831
|
-
});
|
|
832
|
-
}
|
|
833
|
-
if (lastSync && syncOptions.persist) {
|
|
834
|
-
updateMetadata(obs$, localState, syncState, syncOptions, {
|
|
835
|
-
lastSync,
|
|
836
|
-
});
|
|
685
|
+
let syncOptions = syncOptionsOrSynced;
|
|
686
|
+
if (isFunction(syncOptions)) {
|
|
687
|
+
syncOptions = syncOptions()[symbolLinked];
|
|
688
|
+
}
|
|
689
|
+
const node = getNode(obs$);
|
|
690
|
+
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && (!obs$ || !node)) {
|
|
691
|
+
throw new Error("[legend-state] syncObservable called with undefined observable");
|
|
692
|
+
}
|
|
693
|
+
syncOptions = {
|
|
694
|
+
syncMode: "auto",
|
|
695
|
+
...observableSyncConfiguration,
|
|
696
|
+
...removeNullUndefined(syncOptions || {})
|
|
697
|
+
};
|
|
698
|
+
const localState = {};
|
|
699
|
+
let sync;
|
|
700
|
+
const syncState = node.state = observable({
|
|
701
|
+
isPersistLoaded: false,
|
|
702
|
+
isLoaded: !syncOptions.get,
|
|
703
|
+
isPersistEnabled: true,
|
|
704
|
+
isSyncEnabled: true,
|
|
705
|
+
clearPersist: void 0,
|
|
706
|
+
sync: () => Promise.resolve(),
|
|
707
|
+
getPendingChanges: () => localState.pendingChanges
|
|
708
|
+
});
|
|
709
|
+
loadLocal(obs$, syncOptions, syncState, localState);
|
|
710
|
+
localState.pluginSync = syncObservableAdapter(syncOptions);
|
|
711
|
+
if (syncOptions.get) {
|
|
712
|
+
let isSynced = false;
|
|
713
|
+
let isSubscribed = false;
|
|
714
|
+
let unsubscribe = void 0;
|
|
715
|
+
sync = async () => {
|
|
716
|
+
var _a, _b;
|
|
717
|
+
if (isSynced && shouldIgnoreUnobserved(node, sync)) {
|
|
718
|
+
if (unsubscribe) {
|
|
719
|
+
isSubscribed = false;
|
|
720
|
+
unsubscribe();
|
|
721
|
+
unsubscribe = void 0;
|
|
722
|
+
}
|
|
723
|
+
return;
|
|
724
|
+
}
|
|
725
|
+
const lastSync = (_a = metadatas.get(obs$)) == null ? void 0 : _a.lastSync;
|
|
726
|
+
const pending = localState.pendingChanges;
|
|
727
|
+
const get = (_b = localState.pluginSync.get) == null ? void 0 : _b.bind(localState.pluginSync);
|
|
728
|
+
if (get) {
|
|
729
|
+
const runGet = () => {
|
|
730
|
+
const onChange = async ({ value, mode, lastSync: lastSync2 }) => {
|
|
731
|
+
mode = mode || syncOptions.mode || "set";
|
|
732
|
+
if (value !== void 0) {
|
|
733
|
+
value = transformLoadData(value, syncOptions, true, "get");
|
|
734
|
+
if (isPromise(value)) {
|
|
735
|
+
value = await value;
|
|
736
|
+
}
|
|
737
|
+
const pending2 = localState.pendingChanges;
|
|
738
|
+
const currentValue = obs$.peek();
|
|
739
|
+
if (pending2) {
|
|
740
|
+
let didChangeMetadata = false;
|
|
741
|
+
Object.keys(pending2).forEach((key) => {
|
|
742
|
+
const p = key.split("/").filter((p2) => p2 !== "");
|
|
743
|
+
const { v, t } = pending2[key];
|
|
744
|
+
if (t.length === 0 || !value) {
|
|
745
|
+
if (isObject(value) && isObject(v)) {
|
|
746
|
+
Object.assign(value, v);
|
|
747
|
+
} else {
|
|
748
|
+
value = v;
|
|
749
|
+
}
|
|
750
|
+
} else if (value[p[0]] !== void 0) {
|
|
751
|
+
const curValue = getValueAtPath(currentValue, p);
|
|
752
|
+
const newValue = getValueAtPath(value, p);
|
|
753
|
+
if (JSON.stringify(curValue) === JSON.stringify(newValue)) {
|
|
754
|
+
delete pending2[key];
|
|
755
|
+
didChangeMetadata = true;
|
|
756
|
+
} else {
|
|
757
|
+
value = setAtPath(
|
|
758
|
+
value,
|
|
759
|
+
p,
|
|
760
|
+
t,
|
|
761
|
+
v,
|
|
762
|
+
"merge",
|
|
763
|
+
obs$.peek(),
|
|
764
|
+
(path, value2) => {
|
|
765
|
+
delete pending2[key];
|
|
766
|
+
pending2[path.join("/")] = {
|
|
767
|
+
p: null,
|
|
768
|
+
v: value2,
|
|
769
|
+
t: t.slice(0, path.length)
|
|
770
|
+
};
|
|
837
771
|
}
|
|
838
|
-
|
|
839
|
-
get({
|
|
840
|
-
state: syncState,
|
|
841
|
-
value$: obs$,
|
|
842
|
-
options: syncOptions,
|
|
843
|
-
lastSync,
|
|
844
|
-
dateModified: lastSync,
|
|
845
|
-
onError: (error) => {
|
|
846
|
-
var _a;
|
|
847
|
-
(_a = syncOptions.onGetError) === null || _a === void 0 ? void 0 : _a.call(syncOptions, error);
|
|
848
|
-
},
|
|
849
|
-
onGet: () => {
|
|
850
|
-
node.state.assign({
|
|
851
|
-
isLoaded: true,
|
|
852
|
-
error: undefined,
|
|
853
|
-
});
|
|
854
|
-
},
|
|
855
|
-
onChange,
|
|
856
|
-
});
|
|
857
|
-
if (!isSubscribed && syncOptions.subscribe) {
|
|
858
|
-
isSubscribed = true;
|
|
859
|
-
unsubscribe = syncOptions.subscribe({
|
|
860
|
-
node,
|
|
861
|
-
value$: obs$,
|
|
862
|
-
update: (params) => {
|
|
863
|
-
when(node.state.isLoaded, () => {
|
|
864
|
-
params.mode || (params.mode = syncOptions.mode || 'merge');
|
|
865
|
-
onChange(params);
|
|
866
|
-
});
|
|
867
|
-
},
|
|
868
|
-
refresh: () => when(node.state.isLoaded, sync),
|
|
869
|
-
});
|
|
772
|
+
);
|
|
870
773
|
}
|
|
871
|
-
|
|
872
|
-
runGet();
|
|
873
|
-
}
|
|
874
|
-
else {
|
|
875
|
-
node.state.assign({
|
|
876
|
-
isLoaded: true,
|
|
877
|
-
error: undefined,
|
|
774
|
+
}
|
|
878
775
|
});
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
const value = getNodeValue$1(node);
|
|
897
|
-
onObsChange(obs$, syncState, localState, syncOptions, {
|
|
898
|
-
value,
|
|
899
|
-
loading: false,
|
|
900
|
-
remote: false,
|
|
901
|
-
getPrevious: createPreviousHandler(value, changes),
|
|
902
|
-
changes,
|
|
903
|
-
});
|
|
904
|
-
localState.isApplyingPending = false;
|
|
776
|
+
if (didChangeMetadata) {
|
|
777
|
+
updateMetadata(obs$, localState, syncState, syncOptions, {
|
|
778
|
+
pending: pending2
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
onChangeRemote(() => {
|
|
783
|
+
if (mode === "assign" && isObject(value)) {
|
|
784
|
+
obs$.assign(value);
|
|
785
|
+
} else if (mode === "append" && isArray(value)) {
|
|
786
|
+
obs$.push(...value);
|
|
787
|
+
} else if (mode === "prepend" && isArray(value)) {
|
|
788
|
+
obs$.splice(0, 0, ...value);
|
|
789
|
+
} else if (mode === "merge") {
|
|
790
|
+
mergeIntoObservable(obs$, value);
|
|
791
|
+
} else {
|
|
792
|
+
obs$.set(value);
|
|
905
793
|
}
|
|
794
|
+
});
|
|
906
795
|
}
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
const onAllPersistLoaded = () => {
|
|
912
|
-
var _a, _b;
|
|
913
|
-
let parentNode = node;
|
|
914
|
-
while (parentNode) {
|
|
915
|
-
if (((_b = (_a = parentNode.state) === null || _a === void 0 ? void 0 : _a.isPersistLoaded) === null || _b === void 0 ? void 0 : _b.get()) === false) {
|
|
916
|
-
return false;
|
|
796
|
+
if (lastSync2 && syncOptions.persist) {
|
|
797
|
+
updateMetadata(obs$, localState, syncState, syncOptions, {
|
|
798
|
+
lastSync: lastSync2
|
|
799
|
+
});
|
|
917
800
|
}
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
801
|
+
};
|
|
802
|
+
get({
|
|
803
|
+
state: syncState,
|
|
804
|
+
value$: obs$,
|
|
805
|
+
options: syncOptions,
|
|
806
|
+
lastSync,
|
|
807
|
+
dateModified: lastSync,
|
|
808
|
+
onError: (error) => {
|
|
809
|
+
var _a2;
|
|
810
|
+
(_a2 = syncOptions.onGetError) == null ? void 0 : _a2.call(syncOptions, error);
|
|
811
|
+
},
|
|
812
|
+
onGet: () => {
|
|
813
|
+
node.state.assign({
|
|
814
|
+
isLoaded: true,
|
|
815
|
+
error: void 0
|
|
816
|
+
});
|
|
817
|
+
},
|
|
818
|
+
onChange
|
|
819
|
+
});
|
|
820
|
+
if (!isSubscribed && syncOptions.subscribe) {
|
|
821
|
+
isSubscribed = true;
|
|
822
|
+
unsubscribe = syncOptions.subscribe({
|
|
823
|
+
node,
|
|
824
|
+
value$: obs$,
|
|
825
|
+
update: (params) => {
|
|
826
|
+
when(node.state.isLoaded, () => {
|
|
827
|
+
params.mode || (params.mode = syncOptions.mode || "merge");
|
|
828
|
+
onChange(params);
|
|
829
|
+
});
|
|
830
|
+
},
|
|
831
|
+
refresh: () => when(node.state.isLoaded, sync)
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
};
|
|
835
|
+
runGet();
|
|
836
|
+
} else {
|
|
837
|
+
node.state.assign({
|
|
838
|
+
isLoaded: true,
|
|
839
|
+
error: void 0
|
|
840
|
+
});
|
|
841
|
+
}
|
|
842
|
+
if (!isSynced) {
|
|
843
|
+
isSynced = true;
|
|
844
|
+
await when(() => syncState.isLoaded.get() || syncOptions.allowSetIfGetError && syncState.error.get());
|
|
845
|
+
if (pending && !isEmpty(pending)) {
|
|
846
|
+
localState.isApplyingPending = true;
|
|
847
|
+
const keys = Object.keys(pending);
|
|
848
|
+
const changes = [];
|
|
849
|
+
for (let i = 0; i < keys.length; i++) {
|
|
850
|
+
const key = keys[i];
|
|
851
|
+
const path = key.split("/").filter((p2) => p2 !== "");
|
|
852
|
+
const { p, v, t } = pending[key];
|
|
853
|
+
changes.push({ path, valueAtPath: v, prevAtPath: p, pathTypes: t });
|
|
854
|
+
}
|
|
855
|
+
const value = getNodeValue(node);
|
|
856
|
+
onObsChange(obs$, syncState, localState, syncOptions, {
|
|
857
|
+
value,
|
|
858
|
+
loading: false,
|
|
859
|
+
remote: false,
|
|
860
|
+
getPrevious: createPreviousHandler(value, changes),
|
|
861
|
+
changes
|
|
862
|
+
});
|
|
863
|
+
localState.isApplyingPending = false;
|
|
864
|
+
}
|
|
865
|
+
}
|
|
921
866
|
};
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
867
|
+
syncState.assign({ sync });
|
|
868
|
+
}
|
|
869
|
+
const onAllPersistLoaded = () => {
|
|
870
|
+
var _a, _b;
|
|
871
|
+
let parentNode = node;
|
|
872
|
+
while (parentNode) {
|
|
873
|
+
if (((_b = (_a = parentNode.state) == null ? void 0 : _a.isPersistLoaded) == null ? void 0 : _b.get()) === false) {
|
|
874
|
+
return false;
|
|
875
|
+
}
|
|
876
|
+
parentNode = parentNode.parent;
|
|
877
|
+
}
|
|
878
|
+
return true;
|
|
879
|
+
};
|
|
880
|
+
when(onAllPersistLoaded, function() {
|
|
881
|
+
if (syncOptions.get && syncOptions.syncMode === "auto") {
|
|
882
|
+
sync();
|
|
883
|
+
}
|
|
884
|
+
if ((syncOptions == null ? void 0 : syncOptions.set) || (syncOptions == null ? void 0 : syncOptions.persist)) {
|
|
885
|
+
obs$.onChange(
|
|
886
|
+
onObsChange.bind(this, obs$, syncState, localState, syncOptions)
|
|
887
|
+
);
|
|
888
|
+
}
|
|
889
|
+
});
|
|
890
|
+
return syncState;
|
|
933
891
|
}
|
|
934
|
-
|
|
935
|
-
const { getProxy, globalState, runWithRetry, symbolLinked, setNodeValue, getNodeValue } = internal$1;
|
|
892
|
+
var { getProxy, globalState: globalState2, runWithRetry, symbolLinked: symbolLinked2, setNodeValue, getNodeValue: getNodeValue2 } = internal;
|
|
936
893
|
function enableActivateSyncedNode() {
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
updateLastSync,
|
|
960
|
-
mode: params.mode,
|
|
961
|
-
refresh,
|
|
962
|
-
};
|
|
963
|
-
const ret = get(paramsToGet);
|
|
964
|
-
params.mode = paramsToGet.mode;
|
|
965
|
-
return ret;
|
|
966
|
-
});
|
|
967
|
-
promiseReturn = value;
|
|
968
|
-
return value;
|
|
969
|
-
};
|
|
970
|
-
}
|
|
971
|
-
if (set) {
|
|
972
|
-
// TODO: Work out these types better
|
|
973
|
-
pluginRemote.set = async (params) => {
|
|
974
|
-
var _a, _b;
|
|
975
|
-
if ((_a = node.state) === null || _a === void 0 ? void 0 : _a.isLoaded.get()) {
|
|
976
|
-
const retryAttempts = { attemptNum: 0, retry: retry || ((_b = params.options) === null || _b === void 0 ? void 0 : _b.retry) };
|
|
977
|
-
return runWithRetry(node, retryAttempts, async (retryEvent) => {
|
|
978
|
-
let changes = {};
|
|
979
|
-
let maxModified = 0;
|
|
980
|
-
if (!node.state.isLoaded.peek()) {
|
|
981
|
-
await whenReady(node.state.isLoaded);
|
|
982
|
-
}
|
|
983
|
-
const cancelRetry = () => {
|
|
984
|
-
retryEvent.cancel = true;
|
|
985
|
-
};
|
|
986
|
-
await set({
|
|
987
|
-
...params,
|
|
988
|
-
node,
|
|
989
|
-
update: (params) => {
|
|
990
|
-
const { value, lastSync } = params;
|
|
991
|
-
maxModified = Math.max(lastSync || 0, maxModified);
|
|
992
|
-
changes = mergeIntoObservable(changes, value);
|
|
993
|
-
},
|
|
994
|
-
retryNum: retryAttempts.attemptNum,
|
|
995
|
-
cancelRetry,
|
|
996
|
-
refresh,
|
|
997
|
-
fromSubscribe: false,
|
|
998
|
-
});
|
|
999
|
-
return { changes, lastSync: maxModified || undefined };
|
|
1000
|
-
});
|
|
1001
|
-
}
|
|
1002
|
-
};
|
|
1003
|
-
}
|
|
1004
|
-
const nodeVal = getNodeValue(node);
|
|
1005
|
-
if (promiseReturn !== undefined) {
|
|
1006
|
-
newValue = promiseReturn;
|
|
1007
|
-
}
|
|
1008
|
-
else if (nodeVal !== undefined && !isFunction(nodeVal)) {
|
|
1009
|
-
newValue = nodeVal;
|
|
1010
|
-
}
|
|
1011
|
-
else {
|
|
1012
|
-
newValue = initial;
|
|
1013
|
-
}
|
|
1014
|
-
setNodeValue(node, promiseReturn ? undefined : newValue);
|
|
1015
|
-
// @ts-expect-error TODO fix these types
|
|
1016
|
-
syncState = syncObservable(obs$, { ...node.activationState, ...pluginRemote });
|
|
1017
|
-
return { update: onChange, value: newValue };
|
|
1018
|
-
}
|
|
1019
|
-
else {
|
|
1020
|
-
// If it is not a Synced
|
|
1021
|
-
let update = undefined;
|
|
1022
|
-
const get = async (params) => {
|
|
1023
|
-
update = params.refresh;
|
|
1024
|
-
if (isPromise(newValue)) {
|
|
1025
|
-
try {
|
|
1026
|
-
newValue = await newValue;
|
|
1027
|
-
}
|
|
1028
|
-
catch (_a) {
|
|
1029
|
-
// TODO Once we have global retry settings this should retry
|
|
1030
|
-
}
|
|
1031
|
-
}
|
|
1032
|
-
return newValue;
|
|
894
|
+
globalState2.activateSyncedNode = function activateSyncedNode(node, newValue) {
|
|
895
|
+
const obs$ = getProxy(node);
|
|
896
|
+
if (node.activationState) {
|
|
897
|
+
const { get, initial, set, retry } = node.activationState;
|
|
898
|
+
let onChange = void 0;
|
|
899
|
+
const pluginRemote = {};
|
|
900
|
+
let promiseReturn = void 0;
|
|
901
|
+
let syncState;
|
|
902
|
+
const refresh = () => syncState == null ? void 0 : syncState.sync();
|
|
903
|
+
if (get) {
|
|
904
|
+
pluginRemote.get = (params) => {
|
|
905
|
+
var _a;
|
|
906
|
+
onChange = params.onChange;
|
|
907
|
+
const updateLastSync = (lastSync) => params.lastSync = lastSync;
|
|
908
|
+
const existingValue = getNodeValue2(node);
|
|
909
|
+
const value = runWithRetry(node, { attemptNum: 0, retry: retry || ((_a = params.options) == null ? void 0 : _a.retry) }, () => {
|
|
910
|
+
const paramsToGet = {
|
|
911
|
+
value: isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked2]) ? void 0 : existingValue,
|
|
912
|
+
lastSync: params.lastSync,
|
|
913
|
+
updateLastSync,
|
|
914
|
+
mode: params.mode,
|
|
915
|
+
refresh
|
|
1033
916
|
};
|
|
1034
|
-
|
|
1035
|
-
|
|
917
|
+
const ret = get(paramsToGet);
|
|
918
|
+
params.mode = paramsToGet.mode;
|
|
919
|
+
return ret;
|
|
920
|
+
});
|
|
921
|
+
promiseReturn = value;
|
|
922
|
+
return value;
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
if (set) {
|
|
926
|
+
pluginRemote.set = async (params) => {
|
|
927
|
+
var _a, _b;
|
|
928
|
+
if ((_a = node.state) == null ? void 0 : _a.isLoaded.get()) {
|
|
929
|
+
const retryAttempts = { attemptNum: 0, retry: retry || ((_b = params.options) == null ? void 0 : _b.retry) };
|
|
930
|
+
return runWithRetry(node, retryAttempts, async (retryEvent) => {
|
|
931
|
+
let changes = {};
|
|
932
|
+
let maxModified = 0;
|
|
933
|
+
if (!node.state.isLoaded.peek()) {
|
|
934
|
+
await whenReady(node.state.isLoaded);
|
|
935
|
+
}
|
|
936
|
+
const cancelRetry = () => {
|
|
937
|
+
retryEvent.cancel = true;
|
|
938
|
+
};
|
|
939
|
+
await set({
|
|
940
|
+
...params,
|
|
941
|
+
node,
|
|
942
|
+
update: (params2) => {
|
|
943
|
+
const { value, lastSync } = params2;
|
|
944
|
+
maxModified = Math.max(lastSync || 0, maxModified);
|
|
945
|
+
changes = mergeIntoObservable(changes, value);
|
|
946
|
+
},
|
|
947
|
+
retryNum: retryAttempts.attemptNum,
|
|
948
|
+
cancelRetry,
|
|
949
|
+
refresh,
|
|
950
|
+
fromSubscribe: false
|
|
951
|
+
});
|
|
952
|
+
return { changes, lastSync: maxModified || void 0 };
|
|
1036
953
|
});
|
|
1037
|
-
|
|
1038
|
-
}
|
|
1039
|
-
|
|
954
|
+
}
|
|
955
|
+
};
|
|
956
|
+
}
|
|
957
|
+
const nodeVal = getNodeValue2(node);
|
|
958
|
+
if (promiseReturn !== void 0) {
|
|
959
|
+
newValue = promiseReturn;
|
|
960
|
+
} else if (nodeVal !== void 0 && !isFunction(nodeVal)) {
|
|
961
|
+
newValue = nodeVal;
|
|
962
|
+
} else {
|
|
963
|
+
newValue = initial;
|
|
964
|
+
}
|
|
965
|
+
setNodeValue(node, promiseReturn ? void 0 : newValue);
|
|
966
|
+
syncState = syncObservable(obs$, { ...node.activationState, ...pluginRemote });
|
|
967
|
+
return { update: onChange, value: newValue };
|
|
968
|
+
} else {
|
|
969
|
+
let update = void 0;
|
|
970
|
+
const get = async (params) => {
|
|
971
|
+
update = params.refresh;
|
|
972
|
+
if (isPromise(newValue)) {
|
|
973
|
+
try {
|
|
974
|
+
newValue = await newValue;
|
|
975
|
+
} catch (e) {
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
return newValue;
|
|
979
|
+
};
|
|
980
|
+
syncObservable(obs$, {
|
|
981
|
+
get
|
|
982
|
+
});
|
|
983
|
+
return { update, value: newValue };
|
|
984
|
+
}
|
|
985
|
+
};
|
|
1040
986
|
}
|
|
1041
987
|
|
|
988
|
+
// src/sync/synced.ts
|
|
1042
989
|
function synced(params) {
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
990
|
+
installPersistActivateNode();
|
|
991
|
+
if (isFunction(params)) {
|
|
992
|
+
params = { get: params };
|
|
993
|
+
}
|
|
994
|
+
return linked({ ...params, synced: true });
|
|
1048
995
|
}
|
|
1049
|
-
|
|
996
|
+
var didInstall = false;
|
|
1050
997
|
function installPersistActivateNode() {
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
998
|
+
if (!didInstall) {
|
|
999
|
+
enableActivateSyncedNode();
|
|
1000
|
+
didInstall = true;
|
|
1001
|
+
}
|
|
1055
1002
|
}
|
|
1056
1003
|
|
|
1004
|
+
// sync.ts
|
|
1057
1005
|
function isInRemoteChange() {
|
|
1058
|
-
|
|
1006
|
+
return internal.globalState.isLoadingRemote;
|
|
1059
1007
|
}
|
|
1060
|
-
|
|
1061
|
-
|
|
1008
|
+
var internal3 = {
|
|
1009
|
+
observableSyncConfiguration
|
|
1062
1010
|
};
|
|
1063
1011
|
|
|
1064
|
-
export { combineTransforms, configureObservableSync, deepEqual, diffObjects, internal, isInRemoteChange, mapSyncPlugins, onChangeRemote, removeNullUndefined, syncObservable, synced, transformStringifyDates, transformStringifyKeys };
|
|
1065
|
-
//# sourceMappingURL=sync.mjs.map
|
|
1012
|
+
export { combineTransforms, configureObservableSync, deepEqual, diffObjects, internal3 as internal, isInRemoteChange, mapSyncPlugins, onChangeRemote, removeNullUndefined, syncObservable, synced, transformStringifyDates, transformStringifyKeys };
|