@legendapp/state 3.0.0-beta.2 → 3.0.0-beta.20
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/config/enableReactComponents.js +3 -1
- package/config/enableReactComponents.mjs +3 -1
- package/config/enableReactTracking.d.mts +2 -1
- package/config/enableReactTracking.d.ts +2 -1
- package/config/enableReactTracking.js +32 -13
- package/config/enableReactTracking.mjs +32 -13
- package/index.d.mts +13 -4
- package/index.d.ts +13 -4
- package/index.js +70 -22
- package/index.mjs +70 -22
- package/package.json +22 -1
- package/persist-plugins/async-storage.js +17 -9
- package/persist-plugins/async-storage.mjs +17 -9
- package/react-native.d.mts +4 -0
- package/react-native.d.ts +4 -0
- package/react-native.js +53 -0
- package/react-native.mjs +40 -0
- package/react-reactive/Components.d.mts +19 -0
- package/react-reactive/Components.d.ts +19 -0
- package/react-reactive/Components.js +53 -0
- package/react-reactive/Components.mjs +40 -0
- package/react-reactive/enableReactComponents.d.mts +3 -2
- package/react-reactive/enableReactComponents.d.ts +3 -2
- package/react-reactive/enableReactComponents.js +10 -3
- package/react-reactive/enableReactComponents.mjs +10 -3
- package/react-reactive/enableReactNativeComponents.d.mts +3 -20
- package/react-reactive/enableReactNativeComponents.d.ts +3 -20
- package/react-reactive/enableReactNativeComponents.js +8 -3
- package/react-reactive/enableReactNativeComponents.mjs +8 -3
- package/react-reactive/enableReactive.js +10 -3
- package/react-reactive/enableReactive.mjs +10 -3
- package/react-reactive/enableReactive.native.js +8 -3
- package/react-reactive/enableReactive.native.mjs +8 -3
- package/react-reactive/enableReactive.web.js +8 -3
- package/react-reactive/enableReactive.web.mjs +8 -3
- package/react-web.d.mts +6 -0
- package/react-web.d.ts +6 -0
- package/react-web.js +39 -0
- package/react-web.mjs +37 -0
- package/react.d.mts +38 -20
- package/react.d.ts +38 -20
- package/react.js +36 -23
- package/react.mjs +37 -25
- package/sync-plugins/crud.d.mts +24 -9
- package/sync-plugins/crud.d.ts +24 -9
- package/sync-plugins/crud.js +199 -108
- package/sync-plugins/crud.mjs +200 -109
- package/sync-plugins/firebase.d.mts +7 -3
- package/sync-plugins/firebase.d.ts +7 -3
- package/sync-plugins/firebase.js +4 -2
- package/sync-plugins/firebase.mjs +4 -2
- package/sync-plugins/keel.d.mts +9 -13
- package/sync-plugins/keel.d.ts +9 -13
- package/sync-plugins/keel.js +52 -41
- package/sync-plugins/keel.mjs +53 -37
- package/sync-plugins/supabase.d.mts +7 -3
- package/sync-plugins/supabase.d.ts +7 -3
- package/sync-plugins/supabase.js +87 -31
- package/sync-plugins/supabase.mjs +88 -32
- package/sync-plugins/tanstack-query.d.mts +5 -5
- package/sync-plugins/tanstack-query.d.ts +5 -5
- package/sync-plugins/tanstack-query.js +10 -1
- package/sync-plugins/tanstack-query.mjs +10 -1
- package/sync-plugins/tanstack-react-query.d.mts +4 -2
- package/sync-plugins/tanstack-react-query.d.ts +4 -2
- package/sync.d.mts +16 -8
- package/sync.d.ts +16 -8
- package/sync.js +267 -174
- package/sync.mjs +266 -174
- package/trace.js +5 -6
- package/trace.mjs +5 -6
- package/types/reactive-native.d.ts +19 -0
- package/types/reactive-web.d.ts +7 -0
package/sync.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { isObject, isDate, isNullOrUndefined, isString, endBatch, beginBatch, isFunction, syncState, when, linked, internal, observable, isPromise as isPromise$1, mergeIntoObservable, isEmpty, shouldIgnoreUnobserved, whenReady, trackSelector, constructObjectWithPath, setAtPath, isPlainObject, ObservableHint, isArray } from '@legendapp/state';
|
|
1
|
+
import { isObject, isDate, isNullOrUndefined, isString, applyChanges, endBatch, beginBatch, isFunction, syncState, when, linked, internal, observable, isPromise as isPromise$1, mergeIntoObservable, isEmpty, shouldIgnoreUnobserved, whenReady, trackSelector, constructObjectWithPath, setAtPath, isPlainObject, ObservableHint, isArray } from '@legendapp/state';
|
|
2
|
+
import { onChangeRemote } from '@legendapp/state/sync';
|
|
2
3
|
|
|
3
4
|
// src/sync/configureObservableSync.ts
|
|
4
5
|
var observableSyncConfiguration = {};
|
|
@@ -33,12 +34,12 @@ function diffObjects(obj1, obj2, deep = false) {
|
|
|
33
34
|
return diff;
|
|
34
35
|
}
|
|
35
36
|
function deepEqual(a, b, ignoreFields, nullVsUndefined) {
|
|
36
|
-
if (a === b)
|
|
37
|
+
if (a === b)
|
|
37
38
|
return true;
|
|
38
|
-
|
|
39
|
-
if (isNullOrUndefined(a) !== isNullOrUndefined(b)) {
|
|
39
|
+
if (isNullOrUndefined(a) !== isNullOrUndefined(b))
|
|
40
40
|
return false;
|
|
41
|
-
|
|
41
|
+
if (!isObject(a) || !isObject(b))
|
|
42
|
+
return a === b;
|
|
42
43
|
if (nullVsUndefined) {
|
|
43
44
|
a = removeNullUndefined(
|
|
44
45
|
a,
|
|
@@ -51,8 +52,18 @@ function deepEqual(a, b, ignoreFields, nullVsUndefined) {
|
|
|
51
52
|
true
|
|
52
53
|
);
|
|
53
54
|
}
|
|
54
|
-
const
|
|
55
|
-
|
|
55
|
+
const keysA = Object.keys(a).filter((key) => !(ignoreFields == null ? void 0 : ignoreFields.includes(key)));
|
|
56
|
+
const keysB = Object.keys(b).filter((key) => !(ignoreFields == null ? void 0 : ignoreFields.includes(key)));
|
|
57
|
+
if (keysA.length !== keysB.length)
|
|
58
|
+
return false;
|
|
59
|
+
return keysA.every((key) => {
|
|
60
|
+
if (!Object.prototype.hasOwnProperty.call(b, key))
|
|
61
|
+
return false;
|
|
62
|
+
if (isDate(a[key]) && isDate(b[key])) {
|
|
63
|
+
return a[key].getTime() === b[key].getTime();
|
|
64
|
+
}
|
|
65
|
+
return deepEqual(a[key], b[key], ignoreFields, nullVsUndefined);
|
|
66
|
+
});
|
|
56
67
|
}
|
|
57
68
|
function combineTransforms(...transforms) {
|
|
58
69
|
return {
|
|
@@ -159,13 +170,13 @@ function createRetryTimeout(retryOptions, retryNum, fn) {
|
|
|
159
170
|
}
|
|
160
171
|
}
|
|
161
172
|
var mapRetryTimeouts = /* @__PURE__ */ new Map();
|
|
162
|
-
function runWithRetry(state, retryOptions,
|
|
173
|
+
function runWithRetry(state, retryOptions, retryId, fn) {
|
|
163
174
|
try {
|
|
164
175
|
let value = fn(state);
|
|
165
176
|
if (isPromise(value) && retryOptions) {
|
|
166
177
|
let timeoutRetry;
|
|
167
|
-
if (mapRetryTimeouts.has(
|
|
168
|
-
clearTimeout(mapRetryTimeouts.get(
|
|
178
|
+
if (mapRetryTimeouts.has(retryId)) {
|
|
179
|
+
clearTimeout(mapRetryTimeouts.get(retryId));
|
|
169
180
|
}
|
|
170
181
|
return new Promise((resolve, reject) => {
|
|
171
182
|
const run = () => {
|
|
@@ -176,9 +187,6 @@ function runWithRetry(state, retryOptions, fn, onError) {
|
|
|
176
187
|
if (timeoutRetry) {
|
|
177
188
|
clearTimeout(timeoutRetry);
|
|
178
189
|
}
|
|
179
|
-
if (onError) {
|
|
180
|
-
onError(error, state);
|
|
181
|
-
}
|
|
182
190
|
if (!state.cancelRetry) {
|
|
183
191
|
const timeout = createRetryTimeout(retryOptions, state.retryNum, () => {
|
|
184
192
|
value = fn(state);
|
|
@@ -188,7 +196,7 @@ function runWithRetry(state, retryOptions, fn, onError) {
|
|
|
188
196
|
state.cancelRetry = true;
|
|
189
197
|
reject(error);
|
|
190
198
|
} else {
|
|
191
|
-
mapRetryTimeouts.set(
|
|
199
|
+
mapRetryTimeouts.set(retryId, timeout);
|
|
192
200
|
timeoutRetry = timeout;
|
|
193
201
|
}
|
|
194
202
|
}
|
|
@@ -208,9 +216,23 @@ async function waitForSet(waitForSet2, changes, value, params = {}) {
|
|
|
208
216
|
await when(waitFn);
|
|
209
217
|
}
|
|
210
218
|
}
|
|
219
|
+
var { clone } = internal;
|
|
220
|
+
function createRevertChanges(obs$, changes) {
|
|
221
|
+
return () => {
|
|
222
|
+
const previous = applyChanges(
|
|
223
|
+
clone(obs$.peek()),
|
|
224
|
+
changes,
|
|
225
|
+
/*applyPrevious*/
|
|
226
|
+
true
|
|
227
|
+
);
|
|
228
|
+
onChangeRemote(() => {
|
|
229
|
+
obs$.set(previous);
|
|
230
|
+
});
|
|
231
|
+
};
|
|
232
|
+
}
|
|
211
233
|
|
|
212
234
|
// src/sync/syncObservable.ts
|
|
213
|
-
var { clone, deepMerge, getNode, getNodeValue, getValueAtPath, globalState, symbolLinked, createPreviousHandler } = internal;
|
|
235
|
+
var { clone: clone2, deepMerge, getNode, getNodeValue, getValueAtPath, globalState, symbolLinked, createPreviousHandler } = internal;
|
|
214
236
|
var mapSyncPlugins = /* @__PURE__ */ new WeakMap();
|
|
215
237
|
var allSyncStates = /* @__PURE__ */ new Map();
|
|
216
238
|
var metadatas = /* @__PURE__ */ new WeakMap();
|
|
@@ -221,7 +243,7 @@ function parseLocalConfig(config) {
|
|
|
221
243
|
function doInOrder(arg1, arg2) {
|
|
222
244
|
return isPromise$1(arg1) ? arg1.then(arg2) : arg2(arg1);
|
|
223
245
|
}
|
|
224
|
-
function
|
|
246
|
+
function onChangeRemote2(cb) {
|
|
225
247
|
endBatch(true);
|
|
226
248
|
globalState.isLoadingRemote = true;
|
|
227
249
|
beginBatch();
|
|
@@ -273,10 +295,10 @@ function updateMetadata(value$, localState, syncState2, syncOptions, newMetadata
|
|
|
273
295
|
if (localState.timeoutSaveMetadata) {
|
|
274
296
|
clearTimeout(localState.timeoutSaveMetadata);
|
|
275
297
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
);
|
|
298
|
+
metadatas.set(value$, { ...metadatas.get(value$) || {}, ...newMetadata });
|
|
299
|
+
localState.timeoutSaveMetadata = setTimeout(() => {
|
|
300
|
+
updateMetadataImmediate(value$, localState, syncState2, syncOptions, metadatas.get(value$));
|
|
301
|
+
}, 0);
|
|
280
302
|
}
|
|
281
303
|
var _queuedChanges = [];
|
|
282
304
|
var _queuedRemoteChanges = /* @__PURE__ */ new Map();
|
|
@@ -295,8 +317,25 @@ function mergeChanges(changes) {
|
|
|
295
317
|
existing.valueAtPath = change.valueAtPath;
|
|
296
318
|
}
|
|
297
319
|
} else {
|
|
298
|
-
|
|
299
|
-
|
|
320
|
+
let found = false;
|
|
321
|
+
for (let u = 0; u < change.path.length; u++) {
|
|
322
|
+
const path = change.path.slice(0, u).join("/");
|
|
323
|
+
if (changesByPath.has(path)) {
|
|
324
|
+
const remaining = change.path.slice(u);
|
|
325
|
+
setAtPath(
|
|
326
|
+
changesByPath.get(path).valueAtPath,
|
|
327
|
+
remaining,
|
|
328
|
+
change.pathTypes.slice(u),
|
|
329
|
+
change.valueAtPath
|
|
330
|
+
);
|
|
331
|
+
found = true;
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
if (!found) {
|
|
336
|
+
changesByPath.set(pathStr, change);
|
|
337
|
+
changesOut.push(change);
|
|
338
|
+
}
|
|
300
339
|
}
|
|
301
340
|
}
|
|
302
341
|
return changesOut;
|
|
@@ -578,7 +617,7 @@ async function doChangeRemote(changeInfo) {
|
|
|
578
617
|
if (waitForSetParam) {
|
|
579
618
|
await waitForSet(waitForSetParam, changesRemote, obs$.peek());
|
|
580
619
|
}
|
|
581
|
-
let value =
|
|
620
|
+
let value = clone2(obs$.peek());
|
|
582
621
|
const transformSave = (_a = syncOptions == null ? void 0 : syncOptions.transform) == null ? void 0 : _a.save;
|
|
583
622
|
if (transformSave) {
|
|
584
623
|
value = transformSave(value);
|
|
@@ -591,33 +630,41 @@ async function doChangeRemote(changeInfo) {
|
|
|
591
630
|
onBeforeSet == null ? void 0 : onBeforeSet(beforeSetParams);
|
|
592
631
|
if (!beforeSetParams.cancel) {
|
|
593
632
|
let updateResult = void 0;
|
|
594
|
-
let
|
|
595
|
-
const
|
|
633
|
+
let lastErrorHandled;
|
|
634
|
+
const onSetError = (error, params, noThrow) => {
|
|
596
635
|
var _a2;
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
636
|
+
if (lastErrorHandled !== error) {
|
|
637
|
+
if (!params) {
|
|
638
|
+
params = {
|
|
639
|
+
setParams,
|
|
640
|
+
source: "set",
|
|
641
|
+
type: "set",
|
|
642
|
+
input: value,
|
|
643
|
+
retry: setParams,
|
|
644
|
+
revert: createRevertChanges(setParams.value$, setParams.changes)
|
|
645
|
+
};
|
|
646
|
+
}
|
|
647
|
+
state$.error.set(error);
|
|
648
|
+
(_a2 = syncOptions.onError) == null ? void 0 : _a2.call(syncOptions, error, params);
|
|
649
|
+
lastErrorHandled = error;
|
|
650
|
+
if (!noThrow) {
|
|
651
|
+
throw error;
|
|
652
|
+
}
|
|
605
653
|
}
|
|
606
|
-
errorHandled = true;
|
|
607
654
|
};
|
|
608
655
|
const setParams = {
|
|
609
656
|
node,
|
|
610
657
|
value$: obs$,
|
|
611
658
|
changes: changesRemote,
|
|
612
659
|
value,
|
|
613
|
-
onError,
|
|
660
|
+
onError: onSetError,
|
|
614
661
|
update: (params) => {
|
|
615
662
|
if (updateResult) {
|
|
616
|
-
const { value: value2,
|
|
663
|
+
const { value: value2, mode, changes } = params;
|
|
617
664
|
updateResult = {
|
|
618
|
-
lastSync: Math.max(updateResult.lastSync || 0, lastSync || 0),
|
|
619
665
|
value: deepMerge(updateResult.value, value2),
|
|
620
|
-
mode
|
|
666
|
+
mode,
|
|
667
|
+
changes: changes ? [...updateResult.changes || [], ...changes] : updateResult.changes
|
|
621
668
|
};
|
|
622
669
|
} else {
|
|
623
670
|
updateResult = params;
|
|
@@ -627,26 +674,23 @@ async function doChangeRemote(changeInfo) {
|
|
|
627
674
|
retryNum: 0,
|
|
628
675
|
cancelRetry: false
|
|
629
676
|
};
|
|
630
|
-
const savedPromise = runWithRetry(
|
|
631
|
-
setParams
|
|
632
|
-
|
|
633
|
-
async () => {
|
|
634
|
-
return syncOptions.set(setParams);
|
|
635
|
-
},
|
|
636
|
-
onError
|
|
637
|
-
);
|
|
677
|
+
const savedPromise = runWithRetry(setParams, syncOptions.retry, node, async () => {
|
|
678
|
+
return syncOptions.set(setParams);
|
|
679
|
+
});
|
|
638
680
|
let didError = false;
|
|
639
681
|
if (isPromise$1(savedPromise)) {
|
|
640
682
|
await savedPromise.catch((error) => {
|
|
641
683
|
didError = true;
|
|
642
684
|
if (!syncOptions.retry) {
|
|
643
|
-
|
|
685
|
+
onSetError(error, void 0, true);
|
|
644
686
|
}
|
|
645
687
|
});
|
|
646
688
|
}
|
|
647
|
-
if (!didError) {
|
|
648
|
-
const
|
|
649
|
-
const
|
|
689
|
+
if (!didError || (updateResult == null ? void 0 : updateResult.changes)) {
|
|
690
|
+
const { value: updateValue, changes: updateChanges = changesRemote } = updateResult || {};
|
|
691
|
+
const pathStrs = Array.from(
|
|
692
|
+
new Set(updateChanges.map((change) => change.pathStr))
|
|
693
|
+
);
|
|
650
694
|
if (pathStrs.length > 0) {
|
|
651
695
|
let transformedChanges = void 0;
|
|
652
696
|
const metadata = {};
|
|
@@ -663,18 +707,15 @@ async function doChangeRemote(changeInfo) {
|
|
|
663
707
|
delete pending[pathStr];
|
|
664
708
|
}
|
|
665
709
|
}
|
|
666
|
-
if (lastSync) {
|
|
667
|
-
metadata.lastSync = lastSync;
|
|
668
|
-
}
|
|
669
710
|
}
|
|
670
|
-
if (
|
|
671
|
-
transformedChanges = transformLoadData(
|
|
711
|
+
if (updateValue && !isEmpty(updateValue)) {
|
|
712
|
+
transformedChanges = transformLoadData(updateValue, syncOptions, false, "set");
|
|
672
713
|
}
|
|
673
714
|
if (transformedChanges !== void 0) {
|
|
674
715
|
if (isPromise$1(transformedChanges)) {
|
|
675
716
|
transformedChanges = await transformedChanges;
|
|
676
717
|
}
|
|
677
|
-
|
|
718
|
+
onChangeRemote2(() => mergeIntoObservable(obs$, transformedChanges));
|
|
678
719
|
}
|
|
679
720
|
if (saveLocal) {
|
|
680
721
|
if (shouldSaveMetadata && !isEmpty(metadata)) {
|
|
@@ -741,9 +782,20 @@ async function loadLocal(value$, syncOptions, syncState$, localState) {
|
|
|
741
782
|
await when(initialized$);
|
|
742
783
|
}
|
|
743
784
|
if (persistPlugin.loadTable) {
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
785
|
+
try {
|
|
786
|
+
const promise = persistPlugin.loadTable(table, config);
|
|
787
|
+
if (promise) {
|
|
788
|
+
await promise;
|
|
789
|
+
}
|
|
790
|
+
} catch (err) {
|
|
791
|
+
if (process.env.NODE_ENV === "development") {
|
|
792
|
+
console.error(
|
|
793
|
+
"[legend-state] Error loading local cache. This would be a crashing error in production.",
|
|
794
|
+
err
|
|
795
|
+
);
|
|
796
|
+
} else {
|
|
797
|
+
throw err;
|
|
798
|
+
}
|
|
747
799
|
}
|
|
748
800
|
}
|
|
749
801
|
const prevValue = getNodeValue(node);
|
|
@@ -762,12 +814,14 @@ async function loadLocal(value$, syncOptions, syncState$, localState) {
|
|
|
762
814
|
if (isPromise$1(value)) {
|
|
763
815
|
value = await value;
|
|
764
816
|
}
|
|
817
|
+
node.root.isLoadingLocal = true;
|
|
765
818
|
internal.globalState.isLoadingLocal = true;
|
|
766
819
|
if (value === null && (!prevValue || prevValue[symbolLinked])) {
|
|
767
820
|
value$.set(value);
|
|
768
821
|
} else {
|
|
769
822
|
mergeIntoObservable(value$, value);
|
|
770
823
|
}
|
|
824
|
+
node.root.isLoadingLocal = false;
|
|
771
825
|
internal.globalState.isLoadingLocal = false;
|
|
772
826
|
}
|
|
773
827
|
syncStateValue.numPendingLocalLoads--;
|
|
@@ -806,14 +860,24 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
806
860
|
const syncStateValue = getNodeValue(getNode(syncState$));
|
|
807
861
|
allSyncStates.set(syncState$, node);
|
|
808
862
|
syncStateValue.getPendingChanges = () => localState.pendingChanges;
|
|
809
|
-
let
|
|
810
|
-
const onGetError = (error, params) => {
|
|
863
|
+
let lastErrorHandled;
|
|
864
|
+
const onGetError = (error, params, noThrow) => {
|
|
811
865
|
var _a;
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
866
|
+
if (lastErrorHandled !== error) {
|
|
867
|
+
if (!params) {
|
|
868
|
+
params = {
|
|
869
|
+
source: "get",
|
|
870
|
+
type: "get",
|
|
871
|
+
retry: params
|
|
872
|
+
};
|
|
873
|
+
}
|
|
874
|
+
syncState$.error.set(error);
|
|
875
|
+
(_a = syncOptions.onError) == null ? void 0 : _a.call(syncOptions, error, params);
|
|
876
|
+
lastErrorHandled = error;
|
|
877
|
+
if (!noThrow) {
|
|
878
|
+
throw error;
|
|
879
|
+
}
|
|
815
880
|
}
|
|
816
|
-
errorHandled = true;
|
|
817
881
|
};
|
|
818
882
|
loadLocal(obs$, syncOptions, syncState$, localState);
|
|
819
883
|
let isWaitingForLoad = !!syncOptions.get;
|
|
@@ -823,30 +887,37 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
823
887
|
syncState$.isLoaded.set(!syncState$.numPendingRemoteLoads.peek());
|
|
824
888
|
let isSynced = false;
|
|
825
889
|
let isSubscribed = false;
|
|
890
|
+
let isApplyingPendingAfterSync = false;
|
|
826
891
|
let unsubscribe = void 0;
|
|
827
892
|
const applyPending = (pending) => {
|
|
828
893
|
if (pending && !isEmpty(pending)) {
|
|
829
|
-
localState.isApplyingPending = true;
|
|
830
894
|
const keys = Object.keys(pending);
|
|
895
|
+
const value = getNodeValue(node);
|
|
831
896
|
const changes = [];
|
|
832
897
|
for (let i = 0; i < keys.length; i++) {
|
|
833
898
|
const key = keys[i];
|
|
834
899
|
const path = key.split("/").filter((p2) => p2 !== "");
|
|
835
|
-
const { p,
|
|
836
|
-
|
|
900
|
+
const { p, t, v } = pending[key];
|
|
901
|
+
const valueAtPath = getValueAtPath(value, path);
|
|
902
|
+
if (isApplyingPendingAfterSync || !deepEqual(valueAtPath, v)) {
|
|
903
|
+
changes.push({ path, valueAtPath: v, prevAtPath: p, pathTypes: t });
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
if (changes.length > 0) {
|
|
907
|
+
localState.isApplyingPending = true;
|
|
908
|
+
onObsChange(obs$, syncState$, localState, syncOptions, {
|
|
909
|
+
value,
|
|
910
|
+
isFromPersist: false,
|
|
911
|
+
isFromSync: false,
|
|
912
|
+
getPrevious: createPreviousHandler(value, changes),
|
|
913
|
+
changes
|
|
914
|
+
});
|
|
915
|
+
localState.isApplyingPending = false;
|
|
837
916
|
}
|
|
838
|
-
const value = getNodeValue(node);
|
|
839
|
-
onObsChange(obs$, syncState$, localState, syncOptions, {
|
|
840
|
-
value,
|
|
841
|
-
isFromPersist: false,
|
|
842
|
-
isFromSync: false,
|
|
843
|
-
getPrevious: createPreviousHandler(value, changes),
|
|
844
|
-
changes
|
|
845
|
-
});
|
|
846
|
-
localState.isApplyingPending = false;
|
|
847
917
|
}
|
|
848
918
|
};
|
|
849
|
-
|
|
919
|
+
const { get, subscribe } = syncOptions;
|
|
920
|
+
if (get || subscribe) {
|
|
850
921
|
sync = async () => {
|
|
851
922
|
var _a;
|
|
852
923
|
if (isSynced && (!getNodeValue(getNode(syncState$)).isSyncEnabled || shouldIgnoreUnobserved(node, sync))) {
|
|
@@ -859,8 +930,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
859
930
|
}
|
|
860
931
|
const lastSync = (_a = metadatas.get(obs$)) == null ? void 0 : _a.lastSync;
|
|
861
932
|
const pending = localState.pendingChanges;
|
|
862
|
-
|
|
863
|
-
if (get) {
|
|
933
|
+
if (get || subscribe) {
|
|
864
934
|
const { waitFor } = syncOptions;
|
|
865
935
|
const runGet = () => {
|
|
866
936
|
var _a2;
|
|
@@ -879,11 +949,11 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
879
949
|
const p = key.split("/").filter((k) => k !== "");
|
|
880
950
|
const { v, t } = pending2[key];
|
|
881
951
|
if (t.length === 0 || !value) {
|
|
882
|
-
const oldValue =
|
|
883
|
-
pending2[key].p = oldValue;
|
|
952
|
+
const oldValue = clone2(value);
|
|
953
|
+
pending2[key].p = key ? oldValue[key] : oldValue;
|
|
884
954
|
if (isObject(value) && isObject(v)) {
|
|
885
|
-
Object.assign(value, v);
|
|
886
|
-
} else {
|
|
955
|
+
Object.assign(value, key ? { [key]: v } : v);
|
|
956
|
+
} else if (!key) {
|
|
887
957
|
value = v;
|
|
888
958
|
}
|
|
889
959
|
} else if (value[p[0]] !== void 0) {
|
|
@@ -893,8 +963,9 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
893
963
|
delete pending2[key];
|
|
894
964
|
didChangeMetadata = true;
|
|
895
965
|
} else {
|
|
896
|
-
const oldValue =
|
|
966
|
+
const oldValue = clone2(value);
|
|
897
967
|
pending2[key].p = getValueAtPath(oldValue, p);
|
|
968
|
+
didChangeMetadata = true;
|
|
898
969
|
value = setAtPath(
|
|
899
970
|
value,
|
|
900
971
|
p,
|
|
@@ -915,12 +986,12 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
915
986
|
}
|
|
916
987
|
});
|
|
917
988
|
if (didChangeMetadata && syncOptions.persist) {
|
|
918
|
-
|
|
989
|
+
updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
|
|
919
990
|
pending: pending2
|
|
920
991
|
});
|
|
921
992
|
}
|
|
922
993
|
}
|
|
923
|
-
|
|
994
|
+
onChangeRemote2(() => {
|
|
924
995
|
if (isPlainObject(value)) {
|
|
925
996
|
value = ObservableHint.plain(value);
|
|
926
997
|
}
|
|
@@ -953,7 +1024,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
953
1024
|
node.activationState.onChange = onChange;
|
|
954
1025
|
}
|
|
955
1026
|
if (!isSubscribed && syncOptions.subscribe) {
|
|
956
|
-
const
|
|
1027
|
+
const subscribe2 = syncOptions.subscribe;
|
|
957
1028
|
isSubscribed = true;
|
|
958
1029
|
const doSubscribe = () => {
|
|
959
1030
|
const subscribeParams = {
|
|
@@ -961,17 +1032,32 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
961
1032
|
value$: obs$,
|
|
962
1033
|
lastSync,
|
|
963
1034
|
update: (params) => {
|
|
964
|
-
when(
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
1035
|
+
when(
|
|
1036
|
+
() => !get || syncState$.isLoaded.get(),
|
|
1037
|
+
() => {
|
|
1038
|
+
when(waitFor || true, () => {
|
|
1039
|
+
params.mode || (params.mode = syncOptions.mode || "merge");
|
|
1040
|
+
onChange(params);
|
|
1041
|
+
if (!syncState$.isLoaded.peek()) {
|
|
1042
|
+
syncState$.assign({
|
|
1043
|
+
isLoaded: syncStateValue.numPendingRemoteLoads < 1,
|
|
1044
|
+
error: void 0,
|
|
1045
|
+
isGetting: syncStateValue.numPendingGets > 0
|
|
1046
|
+
});
|
|
1047
|
+
}
|
|
1048
|
+
});
|
|
1049
|
+
}
|
|
1050
|
+
);
|
|
970
1051
|
},
|
|
971
1052
|
refresh: () => when(syncState$.isLoaded, sync),
|
|
972
|
-
onError: (error) => onGetError(error, {
|
|
1053
|
+
onError: (error) => onGetError(error, {
|
|
1054
|
+
source: "subscribe",
|
|
1055
|
+
subscribeParams,
|
|
1056
|
+
type: "get",
|
|
1057
|
+
retry: {}
|
|
1058
|
+
})
|
|
973
1059
|
};
|
|
974
|
-
unsubscribe =
|
|
1060
|
+
unsubscribe = subscribe2(subscribeParams);
|
|
975
1061
|
};
|
|
976
1062
|
if (waitFor) {
|
|
977
1063
|
whenReady(waitFor, doSubscribe);
|
|
@@ -980,85 +1066,87 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
980
1066
|
}
|
|
981
1067
|
}
|
|
982
1068
|
const existingValue = getNodeValue(node);
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1069
|
+
if (get) {
|
|
1070
|
+
const getParams = {
|
|
1071
|
+
node,
|
|
1072
|
+
value$: obs$,
|
|
1073
|
+
value: isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked]) ? void 0 : existingValue,
|
|
1074
|
+
mode: syncOptions.mode,
|
|
1075
|
+
refresh: sync,
|
|
1076
|
+
options: syncOptions,
|
|
1077
|
+
lastSync,
|
|
1078
|
+
updateLastSync: (lastSync2) => getParams.lastSync = lastSync2,
|
|
1079
|
+
onError: onGetError,
|
|
1080
|
+
retryNum: 0,
|
|
1081
|
+
cancelRetry: false
|
|
1082
|
+
};
|
|
1083
|
+
let modeBeforeReset = void 0;
|
|
1084
|
+
const beforeGetParams = {
|
|
1085
|
+
value: getParams.value,
|
|
1086
|
+
lastSync,
|
|
1087
|
+
pendingChanges: pending && !isEmpty(pending) ? pending : void 0,
|
|
1088
|
+
clearPendingChanges: async () => {
|
|
1089
|
+
localState.pendingChanges = {};
|
|
1090
|
+
await updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
|
|
1091
|
+
pending: localState.pendingChanges
|
|
1092
|
+
});
|
|
1093
|
+
},
|
|
1094
|
+
resetCache: () => {
|
|
1095
|
+
var _a3;
|
|
1096
|
+
modeBeforeReset = getParams.mode;
|
|
1097
|
+
getParams.mode = "set";
|
|
1098
|
+
return (_a3 = syncStateValue.resetPersistence) == null ? void 0 : _a3.call(syncStateValue);
|
|
1099
|
+
},
|
|
1100
|
+
cancel: false
|
|
1101
|
+
};
|
|
1102
|
+
(_a2 = syncOptions.onBeforeGet) == null ? void 0 : _a2.call(syncOptions, beforeGetParams);
|
|
1103
|
+
if (!beforeGetParams.cancel) {
|
|
1104
|
+
syncState$.assign({
|
|
1105
|
+
numPendingGets: (syncStateValue.numPendingGets || 0) + 1,
|
|
1106
|
+
isGetting: true
|
|
1006
1107
|
});
|
|
1007
|
-
|
|
1008
|
-
resetCache: () => {
|
|
1009
|
-
var _a3;
|
|
1010
|
-
modeBeforeReset = getParams.mode;
|
|
1011
|
-
getParams.mode = "set";
|
|
1012
|
-
return (_a3 = syncStateValue.resetPersistence) == null ? void 0 : _a3.call(syncStateValue);
|
|
1013
|
-
},
|
|
1014
|
-
cancel: false
|
|
1015
|
-
};
|
|
1016
|
-
(_a2 = syncOptions.onBeforeGet) == null ? void 0 : _a2.call(syncOptions, beforeGetParams);
|
|
1017
|
-
if (!beforeGetParams.cancel) {
|
|
1018
|
-
syncState$.assign({
|
|
1019
|
-
numPendingGets: (syncStateValue.numPendingGets || 0) + 1,
|
|
1020
|
-
isGetting: true
|
|
1021
|
-
});
|
|
1022
|
-
const got = runWithRetry(
|
|
1023
|
-
getParams,
|
|
1024
|
-
syncOptions.retry,
|
|
1025
|
-
(retryEvent) => {
|
|
1108
|
+
const got = runWithRetry(getParams, syncOptions.retry, node, (retryEvent) => {
|
|
1026
1109
|
const params = getParams;
|
|
1027
1110
|
params.cancelRetry = retryEvent.cancelRetry;
|
|
1028
1111
|
params.retryNum = retryEvent.retryNum;
|
|
1029
1112
|
return get(params);
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1113
|
+
});
|
|
1114
|
+
const numGets = node.numGets = (node.numGets || 0) + 1;
|
|
1115
|
+
const handle = (value) => {
|
|
1116
|
+
syncState$.numPendingGets.set((v) => v - 1);
|
|
1117
|
+
if (isWaitingForLoad) {
|
|
1118
|
+
isWaitingForLoad = false;
|
|
1119
|
+
syncStateValue.numPendingRemoteLoads--;
|
|
1120
|
+
}
|
|
1121
|
+
if (numGets >= (node.getNumResolved || 0)) {
|
|
1122
|
+
node.getNumResolved = node.numGets;
|
|
1123
|
+
onChange({
|
|
1124
|
+
value,
|
|
1125
|
+
lastSync: getParams.lastSync,
|
|
1126
|
+
mode: getParams.mode
|
|
1127
|
+
});
|
|
1128
|
+
}
|
|
1129
|
+
if (modeBeforeReset) {
|
|
1130
|
+
getParams.mode = modeBeforeReset;
|
|
1131
|
+
modeBeforeReset = void 0;
|
|
1132
|
+
}
|
|
1133
|
+
syncState$.assign({
|
|
1134
|
+
isLoaded: syncStateValue.numPendingRemoteLoads < 1,
|
|
1135
|
+
error: void 0,
|
|
1136
|
+
isGetting: syncStateValue.numPendingGets > 0
|
|
1046
1137
|
});
|
|
1138
|
+
};
|
|
1139
|
+
if (isPromise$1(got)) {
|
|
1140
|
+
got.then(handle).catch((error) => {
|
|
1141
|
+
onGetError(
|
|
1142
|
+
error,
|
|
1143
|
+
{ getParams, source: "get", type: "get", retry: getParams },
|
|
1144
|
+
true
|
|
1145
|
+
);
|
|
1146
|
+
});
|
|
1147
|
+
} else {
|
|
1148
|
+
handle(got);
|
|
1047
1149
|
}
|
|
1048
|
-
if (modeBeforeReset) {
|
|
1049
|
-
getParams.mode = modeBeforeReset;
|
|
1050
|
-
modeBeforeReset = void 0;
|
|
1051
|
-
}
|
|
1052
|
-
syncState$.assign({
|
|
1053
|
-
isLoaded: syncStateValue.numPendingRemoteLoads < 1,
|
|
1054
|
-
error: void 0,
|
|
1055
|
-
isGetting: syncStateValue.numPendingGets > 0
|
|
1056
|
-
});
|
|
1057
|
-
};
|
|
1058
|
-
if (isPromise$1(got)) {
|
|
1059
|
-
got.then(handle).catch(onError);
|
|
1060
|
-
} else {
|
|
1061
|
-
handle(got);
|
|
1062
1150
|
}
|
|
1063
1151
|
}
|
|
1064
1152
|
};
|
|
@@ -1075,14 +1163,17 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
1075
1163
|
}
|
|
1076
1164
|
if (!isSynced) {
|
|
1077
1165
|
isSynced = true;
|
|
1078
|
-
|
|
1166
|
+
isApplyingPendingAfterSync = true;
|
|
1079
1167
|
applyPending(pending);
|
|
1168
|
+
isApplyingPendingAfterSync = false;
|
|
1080
1169
|
}
|
|
1081
1170
|
};
|
|
1082
1171
|
syncStateValue.sync = sync;
|
|
1083
1172
|
} else {
|
|
1084
1173
|
if (!isSynced) {
|
|
1174
|
+
isApplyingPendingAfterSync = true;
|
|
1085
1175
|
applyPending(localState.pendingChanges);
|
|
1176
|
+
isApplyingPendingAfterSync = false;
|
|
1086
1177
|
}
|
|
1087
1178
|
}
|
|
1088
1179
|
syncStateValue.reset = async () => {
|
|
@@ -1108,7 +1199,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
1108
1199
|
unsubscribe == null ? void 0 : unsubscribe();
|
|
1109
1200
|
unsubscribe = void 0;
|
|
1110
1201
|
const promise = syncStateValue.resetPersistence();
|
|
1111
|
-
|
|
1202
|
+
onChangeRemote2(() => {
|
|
1112
1203
|
var _a;
|
|
1113
1204
|
obs$.set((_a = syncOptions.initial) != null ? _a : void 0);
|
|
1114
1205
|
});
|
|
@@ -1130,7 +1221,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
1130
1221
|
return true;
|
|
1131
1222
|
};
|
|
1132
1223
|
when(onAllPersistLoaded, function() {
|
|
1133
|
-
if (syncOptions.get && syncOptions.syncMode === "auto") {
|
|
1224
|
+
if ((syncOptions.get || syncOptions.subscribe) && syncOptions.syncMode === "auto") {
|
|
1134
1225
|
sync();
|
|
1135
1226
|
}
|
|
1136
1227
|
if ((syncOptions == null ? void 0 : syncOptions.set) || (syncOptions == null ? void 0 : syncOptions.persist)) {
|
|
@@ -1213,9 +1304,10 @@ function configureSynced(fnOrOrigOptions, origOptions) {
|
|
|
1213
1304
|
}
|
|
1214
1305
|
|
|
1215
1306
|
// sync.ts
|
|
1216
|
-
var
|
|
1307
|
+
var internal5 = {
|
|
1217
1308
|
observableSyncConfiguration,
|
|
1218
|
-
waitForSet
|
|
1309
|
+
waitForSet,
|
|
1310
|
+
runWithRetry
|
|
1219
1311
|
};
|
|
1220
1312
|
|
|
1221
|
-
export { combineTransforms, configureObservableSync, configureSynced, deepEqual, diffObjects,
|
|
1313
|
+
export { combineTransforms, configureObservableSync, configureSynced, createRevertChanges, deepEqual, diffObjects, internal5 as internal, mapSyncPlugins, onChangeRemote2 as onChangeRemote, removeNullUndefined, syncObservable, synced, transformStringifyDates, transformStringifyKeys };
|