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