@legendapp/state 3.0.0-beta.4 → 3.0.0-beta.41
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/README.md +2 -2
- 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 +46 -8
- package/index.d.ts +46 -8
- package/index.js +267 -75
- package/index.mjs +267 -75
- package/package.json +35 -1
- package/persist-plugins/async-storage.js +17 -9
- package/persist-plugins/async-storage.mjs +17 -9
- package/persist-plugins/expo-sqlite.d.mts +19 -0
- package/persist-plugins/expo-sqlite.d.ts +19 -0
- package/persist-plugins/expo-sqlite.js +72 -0
- package/persist-plugins/expo-sqlite.mjs +69 -0
- package/persist-plugins/indexeddb.js +13 -3
- package/persist-plugins/indexeddb.mjs +13 -3
- 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 +7 -0
- package/react-web.d.ts +7 -0
- package/react-web.js +39 -0
- package/react-web.mjs +37 -0
- package/react.d.mts +59 -26
- package/react.d.ts +59 -26
- package/react.js +136 -87
- package/react.mjs +135 -89
- package/sync-plugins/crud.d.mts +24 -9
- package/sync-plugins/crud.d.ts +24 -9
- package/sync-plugins/crud.js +267 -123
- package/sync-plugins/crud.mjs +268 -124
- package/sync-plugins/firebase.d.mts +7 -3
- package/sync-plugins/firebase.d.ts +7 -3
- package/sync-plugins/firebase.js +214 -64
- package/sync-plugins/firebase.mjs +215 -65
- package/sync-plugins/keel.d.mts +12 -13
- package/sync-plugins/keel.d.ts +12 -13
- package/sync-plugins/keel.js +60 -52
- package/sync-plugins/keel.mjs +61 -48
- package/sync-plugins/supabase.d.mts +10 -5
- package/sync-plugins/supabase.d.ts +10 -5
- package/sync-plugins/supabase.js +90 -33
- package/sync-plugins/supabase.mjs +91 -34
- package/sync-plugins/tanstack-query.d.mts +3 -3
- package/sync-plugins/tanstack-query.d.ts +3 -3
- package/sync-plugins/tanstack-query.js +1 -1
- package/sync-plugins/tanstack-query.mjs +1 -1
- package/sync.d.mts +17 -8
- package/sync.d.ts +17 -8
- package/sync.js +448 -307
- package/sync.mjs +446 -307
- 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,38 +170,50 @@ 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));
|
|
180
|
+
mapRetryTimeouts.delete(retryId);
|
|
169
181
|
}
|
|
182
|
+
const clearRetryState = () => {
|
|
183
|
+
if (timeoutRetry !== void 0) {
|
|
184
|
+
clearTimeout(timeoutRetry);
|
|
185
|
+
timeoutRetry = void 0;
|
|
186
|
+
}
|
|
187
|
+
mapRetryTimeouts.delete(retryId);
|
|
188
|
+
};
|
|
170
189
|
return new Promise((resolve, reject) => {
|
|
171
190
|
const run = () => {
|
|
172
191
|
value.then((val) => {
|
|
192
|
+
state.retryNum = 0;
|
|
193
|
+
clearRetryState();
|
|
173
194
|
resolve(val);
|
|
174
195
|
}).catch((error) => {
|
|
175
|
-
|
|
176
|
-
if (timeoutRetry) {
|
|
196
|
+
if (timeoutRetry !== void 0) {
|
|
177
197
|
clearTimeout(timeoutRetry);
|
|
198
|
+
timeoutRetry = void 0;
|
|
178
199
|
}
|
|
179
|
-
|
|
180
|
-
|
|
200
|
+
state.retryNum++;
|
|
201
|
+
if (state.cancelRetry) {
|
|
202
|
+
clearRetryState();
|
|
203
|
+
reject(error);
|
|
204
|
+
return;
|
|
181
205
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
206
|
+
const timeout = createRetryTimeout(retryOptions, state.retryNum, () => {
|
|
207
|
+
value = fn(state);
|
|
208
|
+
run();
|
|
209
|
+
});
|
|
210
|
+
if (timeout === false) {
|
|
211
|
+
state.cancelRetry = true;
|
|
212
|
+
clearRetryState();
|
|
213
|
+
reject(error);
|
|
214
|
+
} else {
|
|
215
|
+
timeoutRetry = timeout;
|
|
216
|
+
mapRetryTimeouts.set(retryId, timeout);
|
|
194
217
|
}
|
|
195
218
|
});
|
|
196
219
|
};
|
|
@@ -199,6 +222,7 @@ function runWithRetry(state, retryOptions, fn, onError) {
|
|
|
199
222
|
}
|
|
200
223
|
return value;
|
|
201
224
|
} catch (error) {
|
|
225
|
+
mapRetryTimeouts.delete(retryId);
|
|
202
226
|
return Promise.reject(error);
|
|
203
227
|
}
|
|
204
228
|
}
|
|
@@ -208,9 +232,34 @@ async function waitForSet(waitForSet2, changes, value, params = {}) {
|
|
|
208
232
|
await when(waitFn);
|
|
209
233
|
}
|
|
210
234
|
}
|
|
235
|
+
var { clone } = internal;
|
|
236
|
+
function createRevertChanges(obs$, changes) {
|
|
237
|
+
return () => {
|
|
238
|
+
const previous = applyChanges(
|
|
239
|
+
clone(obs$.peek()),
|
|
240
|
+
changes,
|
|
241
|
+
/*applyPrevious*/
|
|
242
|
+
true
|
|
243
|
+
);
|
|
244
|
+
onChangeRemote(() => {
|
|
245
|
+
obs$.set(previous);
|
|
246
|
+
});
|
|
247
|
+
};
|
|
248
|
+
}
|
|
211
249
|
|
|
212
250
|
// src/sync/syncObservable.ts
|
|
213
|
-
var {
|
|
251
|
+
var {
|
|
252
|
+
clone: clone2,
|
|
253
|
+
createPreviousHandler,
|
|
254
|
+
deepMerge,
|
|
255
|
+
getNode,
|
|
256
|
+
getNodeValue,
|
|
257
|
+
getValueAtPath,
|
|
258
|
+
globalState,
|
|
259
|
+
registerMiddleware,
|
|
260
|
+
symbolLinked,
|
|
261
|
+
setNodeValue
|
|
262
|
+
} = internal;
|
|
214
263
|
var mapSyncPlugins = /* @__PURE__ */ new WeakMap();
|
|
215
264
|
var allSyncStates = /* @__PURE__ */ new Map();
|
|
216
265
|
var metadatas = /* @__PURE__ */ new WeakMap();
|
|
@@ -221,7 +270,7 @@ function parseLocalConfig(config) {
|
|
|
221
270
|
function doInOrder(arg1, arg2) {
|
|
222
271
|
return isPromise$1(arg1) ? arg1.then(arg2) : arg2(arg1);
|
|
223
272
|
}
|
|
224
|
-
function
|
|
273
|
+
function onChangeRemote2(cb) {
|
|
225
274
|
endBatch(true);
|
|
226
275
|
globalState.isLoadingRemote = true;
|
|
227
276
|
beginBatch();
|
|
@@ -249,7 +298,7 @@ function transformLoadData(value, { transform }, doUserTransform, method) {
|
|
|
249
298
|
}
|
|
250
299
|
return value;
|
|
251
300
|
}
|
|
252
|
-
async function updateMetadataImmediate(value$, localState,
|
|
301
|
+
async function updateMetadataImmediate(value$, localState, syncState$, syncOptions, newMetadata) {
|
|
253
302
|
const saves = Array.from(promisesLocalSaves);
|
|
254
303
|
if (saves.length > 0) {
|
|
255
304
|
await Promise.all(saves);
|
|
@@ -264,7 +313,7 @@ async function updateMetadataImmediate(value$, localState, syncState2, syncOptio
|
|
|
264
313
|
await pluginPersist.setMetadata(table, metadata, config);
|
|
265
314
|
}
|
|
266
315
|
if (lastSync) {
|
|
267
|
-
|
|
316
|
+
syncState$.assign({
|
|
268
317
|
lastSync
|
|
269
318
|
});
|
|
270
319
|
}
|
|
@@ -273,10 +322,10 @@ function updateMetadata(value$, localState, syncState2, syncOptions, newMetadata
|
|
|
273
322
|
if (localState.timeoutSaveMetadata) {
|
|
274
323
|
clearTimeout(localState.timeoutSaveMetadata);
|
|
275
324
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
);
|
|
325
|
+
metadatas.set(value$, { ...metadatas.get(value$) || {}, ...newMetadata });
|
|
326
|
+
localState.timeoutSaveMetadata = setTimeout(() => {
|
|
327
|
+
updateMetadataImmediate(value$, localState, syncState2, syncOptions, metadatas.get(value$));
|
|
328
|
+
}, 0);
|
|
280
329
|
}
|
|
281
330
|
var _queuedChanges = [];
|
|
282
331
|
var _queuedRemoteChanges = /* @__PURE__ */ new Map();
|
|
@@ -290,13 +339,35 @@ function mergeChanges(changes) {
|
|
|
290
339
|
const existing = changesByPath.get(pathStr);
|
|
291
340
|
if (existing) {
|
|
292
341
|
if (change.valueAtPath === existing.prevAtPath) {
|
|
293
|
-
changesOut.
|
|
342
|
+
const idx = changesOut.indexOf(existing);
|
|
343
|
+
if (idx >= 0) {
|
|
344
|
+
changesOut.splice(idx, 1);
|
|
345
|
+
}
|
|
346
|
+
changesByPath.delete(pathStr);
|
|
294
347
|
} else {
|
|
295
348
|
existing.valueAtPath = change.valueAtPath;
|
|
349
|
+
existing.pathTypes = change.pathTypes;
|
|
296
350
|
}
|
|
297
351
|
} else {
|
|
298
|
-
|
|
299
|
-
|
|
352
|
+
let found = false;
|
|
353
|
+
for (let u = 0; u < change.path.length; u++) {
|
|
354
|
+
const path = change.path.slice(0, u).join("/");
|
|
355
|
+
if (changesByPath.has(path)) {
|
|
356
|
+
const remaining = change.path.slice(u);
|
|
357
|
+
setAtPath(
|
|
358
|
+
changesByPath.get(path).valueAtPath,
|
|
359
|
+
remaining,
|
|
360
|
+
change.pathTypes.slice(u),
|
|
361
|
+
change.valueAtPath
|
|
362
|
+
);
|
|
363
|
+
found = true;
|
|
364
|
+
break;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
if (!found) {
|
|
368
|
+
changesByPath.set(pathStr, change);
|
|
369
|
+
changesOut.push(change);
|
|
370
|
+
}
|
|
300
371
|
}
|
|
301
372
|
}
|
|
302
373
|
return changesOut;
|
|
@@ -578,7 +649,7 @@ async function doChangeRemote(changeInfo) {
|
|
|
578
649
|
if (waitForSetParam) {
|
|
579
650
|
await waitForSet(waitForSetParam, changesRemote, obs$.peek());
|
|
580
651
|
}
|
|
581
|
-
let value =
|
|
652
|
+
let value = clone2(obs$.peek());
|
|
582
653
|
const transformSave = (_a = syncOptions == null ? void 0 : syncOptions.transform) == null ? void 0 : _a.save;
|
|
583
654
|
if (transformSave) {
|
|
584
655
|
value = transformSave(value);
|
|
@@ -591,33 +662,41 @@ async function doChangeRemote(changeInfo) {
|
|
|
591
662
|
onBeforeSet == null ? void 0 : onBeforeSet(beforeSetParams);
|
|
592
663
|
if (!beforeSetParams.cancel) {
|
|
593
664
|
let updateResult = void 0;
|
|
594
|
-
let
|
|
595
|
-
const
|
|
665
|
+
let lastErrorHandled;
|
|
666
|
+
const onSetError = (error, params, noThrow) => {
|
|
596
667
|
var _a2;
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
668
|
+
if (lastErrorHandled !== error) {
|
|
669
|
+
if (!params) {
|
|
670
|
+
params = {
|
|
671
|
+
setParams,
|
|
672
|
+
source: "set",
|
|
673
|
+
type: "set",
|
|
674
|
+
input: value,
|
|
675
|
+
retry: setParams,
|
|
676
|
+
revert: createRevertChanges(setParams.value$, setParams.changes)
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
state$.error.set(error);
|
|
680
|
+
(_a2 = syncOptions.onError) == null ? void 0 : _a2.call(syncOptions, error, params);
|
|
681
|
+
lastErrorHandled = error;
|
|
682
|
+
if (!noThrow) {
|
|
683
|
+
throw error;
|
|
684
|
+
}
|
|
605
685
|
}
|
|
606
|
-
errorHandled = true;
|
|
607
686
|
};
|
|
608
687
|
const setParams = {
|
|
609
688
|
node,
|
|
610
689
|
value$: obs$,
|
|
611
690
|
changes: changesRemote,
|
|
612
691
|
value,
|
|
613
|
-
onError,
|
|
692
|
+
onError: onSetError,
|
|
614
693
|
update: (params) => {
|
|
615
694
|
if (updateResult) {
|
|
616
|
-
const { value: value2,
|
|
695
|
+
const { value: value2, mode, changes } = params;
|
|
617
696
|
updateResult = {
|
|
618
|
-
lastSync: Math.max(updateResult.lastSync || 0, lastSync || 0),
|
|
619
697
|
value: deepMerge(updateResult.value, value2),
|
|
620
|
-
mode
|
|
698
|
+
mode,
|
|
699
|
+
changes: changes ? [...updateResult.changes || [], ...changes] : updateResult.changes
|
|
621
700
|
};
|
|
622
701
|
} else {
|
|
623
702
|
updateResult = params;
|
|
@@ -627,26 +706,23 @@ async function doChangeRemote(changeInfo) {
|
|
|
627
706
|
retryNum: 0,
|
|
628
707
|
cancelRetry: false
|
|
629
708
|
};
|
|
630
|
-
const savedPromise = runWithRetry(
|
|
631
|
-
setParams
|
|
632
|
-
|
|
633
|
-
async () => {
|
|
634
|
-
return syncOptions.set(setParams);
|
|
635
|
-
},
|
|
636
|
-
onError
|
|
637
|
-
);
|
|
709
|
+
const savedPromise = runWithRetry(setParams, syncOptions.retry, node, async () => {
|
|
710
|
+
return syncOptions.set(setParams);
|
|
711
|
+
});
|
|
638
712
|
let didError = false;
|
|
639
713
|
if (isPromise$1(savedPromise)) {
|
|
640
714
|
await savedPromise.catch((error) => {
|
|
641
715
|
didError = true;
|
|
642
716
|
if (!syncOptions.retry) {
|
|
643
|
-
|
|
717
|
+
onSetError(error, void 0, true);
|
|
644
718
|
}
|
|
645
719
|
});
|
|
646
720
|
}
|
|
647
|
-
if (!didError) {
|
|
648
|
-
const
|
|
649
|
-
const
|
|
721
|
+
if (!didError || (updateResult == null ? void 0 : updateResult.changes)) {
|
|
722
|
+
const { value: updateValue, changes: updateChanges = changesRemote } = updateResult || {};
|
|
723
|
+
const pathStrs = Array.from(
|
|
724
|
+
new Set(updateChanges.map((change) => change.pathStr))
|
|
725
|
+
);
|
|
650
726
|
if (pathStrs.length > 0) {
|
|
651
727
|
let transformedChanges = void 0;
|
|
652
728
|
const metadata = {};
|
|
@@ -663,18 +739,15 @@ async function doChangeRemote(changeInfo) {
|
|
|
663
739
|
delete pending[pathStr];
|
|
664
740
|
}
|
|
665
741
|
}
|
|
666
|
-
if (lastSync) {
|
|
667
|
-
metadata.lastSync = lastSync;
|
|
668
|
-
}
|
|
669
742
|
}
|
|
670
|
-
if (
|
|
671
|
-
transformedChanges = transformLoadData(
|
|
743
|
+
if (updateValue && !isEmpty(updateValue)) {
|
|
744
|
+
transformedChanges = transformLoadData(updateValue, syncOptions, false, "set");
|
|
672
745
|
}
|
|
673
746
|
if (transformedChanges !== void 0) {
|
|
674
747
|
if (isPromise$1(transformedChanges)) {
|
|
675
748
|
transformedChanges = await transformedChanges;
|
|
676
749
|
}
|
|
677
|
-
|
|
750
|
+
onChangeRemote2(() => mergeIntoObservable(obs$, transformedChanges));
|
|
678
751
|
}
|
|
679
752
|
if (saveLocal) {
|
|
680
753
|
if (shouldSaveMetadata && !isEmpty(metadata)) {
|
|
@@ -741,9 +814,20 @@ async function loadLocal(value$, syncOptions, syncState$, localState) {
|
|
|
741
814
|
await when(initialized$);
|
|
742
815
|
}
|
|
743
816
|
if (persistPlugin.loadTable) {
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
817
|
+
try {
|
|
818
|
+
const promise = persistPlugin.loadTable(table, config);
|
|
819
|
+
if (promise) {
|
|
820
|
+
await promise;
|
|
821
|
+
}
|
|
822
|
+
} catch (err) {
|
|
823
|
+
if (process.env.NODE_ENV === "development") {
|
|
824
|
+
console.error(
|
|
825
|
+
"[legend-state] Error loading local cache. This would be a crashing error in production.",
|
|
826
|
+
err
|
|
827
|
+
);
|
|
828
|
+
} else {
|
|
829
|
+
throw err;
|
|
830
|
+
}
|
|
747
831
|
}
|
|
748
832
|
}
|
|
749
833
|
const prevValue = getNodeValue(node);
|
|
@@ -762,12 +846,14 @@ async function loadLocal(value$, syncOptions, syncState$, localState) {
|
|
|
762
846
|
if (isPromise$1(value)) {
|
|
763
847
|
value = await value;
|
|
764
848
|
}
|
|
849
|
+
node.root.isLoadingLocal = true;
|
|
765
850
|
internal.globalState.isLoadingLocal = true;
|
|
766
851
|
if (value === null && (!prevValue || prevValue[symbolLinked])) {
|
|
767
852
|
value$.set(value);
|
|
768
853
|
} else {
|
|
769
854
|
mergeIntoObservable(value$, value);
|
|
770
855
|
}
|
|
856
|
+
node.root.isLoadingLocal = false;
|
|
771
857
|
internal.globalState.isLoadingLocal = false;
|
|
772
858
|
}
|
|
773
859
|
syncStateValue.numPendingLocalLoads--;
|
|
@@ -779,6 +865,11 @@ async function loadLocal(value$, syncOptions, syncState$, localState) {
|
|
|
779
865
|
].filter(Boolean)
|
|
780
866
|
);
|
|
781
867
|
} else {
|
|
868
|
+
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && persist && persist.plugin && !Object.hasOwn(persist, "name")) {
|
|
869
|
+
console.warn(
|
|
870
|
+
"[legend-state] Trying to syncObservable without `name` defined. Please include a `name` property in the `persist` configuration."
|
|
871
|
+
);
|
|
872
|
+
}
|
|
782
873
|
nodeValue.resetPersistence = () => prevResetPersistence == null ? void 0 : prevResetPersistence();
|
|
783
874
|
}
|
|
784
875
|
nodeValue.clearPersist = nodeValue.resetPersistence;
|
|
@@ -806,14 +897,24 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
806
897
|
const syncStateValue = getNodeValue(getNode(syncState$));
|
|
807
898
|
allSyncStates.set(syncState$, node);
|
|
808
899
|
syncStateValue.getPendingChanges = () => localState.pendingChanges;
|
|
809
|
-
let
|
|
810
|
-
const onGetError = (error, params) => {
|
|
900
|
+
let lastErrorHandled;
|
|
901
|
+
const onGetError = (error, params, noThrow) => {
|
|
811
902
|
var _a;
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
903
|
+
if (lastErrorHandled !== error) {
|
|
904
|
+
if (!params) {
|
|
905
|
+
params = {
|
|
906
|
+
source: "get",
|
|
907
|
+
type: "get",
|
|
908
|
+
retry: params
|
|
909
|
+
};
|
|
910
|
+
}
|
|
911
|
+
syncState$.error.set(error);
|
|
912
|
+
(_a = syncOptions.onError) == null ? void 0 : _a.call(syncOptions, error, params);
|
|
913
|
+
lastErrorHandled = error;
|
|
914
|
+
if (!noThrow) {
|
|
915
|
+
throw error;
|
|
916
|
+
}
|
|
815
917
|
}
|
|
816
|
-
errorHandled = true;
|
|
817
918
|
};
|
|
818
919
|
loadLocal(obs$, syncOptions, syncState$, localState);
|
|
819
920
|
let isWaitingForLoad = !!syncOptions.get;
|
|
@@ -823,33 +924,39 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
823
924
|
syncState$.isLoaded.set(!syncState$.numPendingRemoteLoads.peek());
|
|
824
925
|
let isSynced = false;
|
|
825
926
|
let isSubscribed = false;
|
|
927
|
+
let isApplyingPendingAfterSync = false;
|
|
826
928
|
let unsubscribe = void 0;
|
|
827
929
|
const applyPending = (pending) => {
|
|
828
930
|
if (pending && !isEmpty(pending)) {
|
|
829
|
-
localState.isApplyingPending = true;
|
|
830
931
|
const keys = Object.keys(pending);
|
|
932
|
+
const value = getNodeValue(node);
|
|
831
933
|
const changes = [];
|
|
832
934
|
for (let i = 0; i < keys.length; i++) {
|
|
833
935
|
const key = keys[i];
|
|
834
936
|
const path = key.split("/").filter((p2) => p2 !== "");
|
|
835
|
-
const { p,
|
|
836
|
-
|
|
937
|
+
const { p, t, v } = pending[key];
|
|
938
|
+
const valueAtPath = getValueAtPath(value, path);
|
|
939
|
+
if (isApplyingPendingAfterSync || !deepEqual(valueAtPath, v)) {
|
|
940
|
+
changes.push({ path, valueAtPath: v, prevAtPath: p, pathTypes: t });
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
if (changes.length > 0) {
|
|
944
|
+
localState.isApplyingPending = true;
|
|
945
|
+
onObsChange(obs$, syncState$, localState, syncOptions, {
|
|
946
|
+
value,
|
|
947
|
+
isFromPersist: false,
|
|
948
|
+
isFromSync: false,
|
|
949
|
+
getPrevious: createPreviousHandler(value, changes),
|
|
950
|
+
changes
|
|
951
|
+
});
|
|
952
|
+
localState.isApplyingPending = false;
|
|
837
953
|
}
|
|
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
954
|
}
|
|
848
955
|
};
|
|
849
956
|
const { get, subscribe } = syncOptions;
|
|
850
957
|
if (get || subscribe) {
|
|
851
|
-
|
|
852
|
-
|
|
958
|
+
const callSync = () => sync();
|
|
959
|
+
sync = async (options) => {
|
|
853
960
|
if (isSynced && (!getNodeValue(getNode(syncState$)).isSyncEnabled || shouldIgnoreUnobserved(node, sync))) {
|
|
854
961
|
if (unsubscribe) {
|
|
855
962
|
isSubscribed = false;
|
|
@@ -858,243 +965,262 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
858
965
|
}
|
|
859
966
|
return;
|
|
860
967
|
}
|
|
861
|
-
const
|
|
968
|
+
const metadata = metadatas.get(obs$);
|
|
969
|
+
if (metadata && (options == null ? void 0 : options.resetLastSync)) {
|
|
970
|
+
metadata.lastSync = void 0;
|
|
971
|
+
syncState$.lastSync.set(void 0);
|
|
972
|
+
}
|
|
973
|
+
const lastSync = metadata == null ? void 0 : metadata.lastSync;
|
|
862
974
|
const pending = localState.pendingChanges;
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
975
|
+
const { waitFor } = syncOptions;
|
|
976
|
+
const runGet = () => {
|
|
977
|
+
var _a;
|
|
978
|
+
const onChange = async ({ value, mode, lastSync: lastSync2 }) => {
|
|
866
979
|
var _a2;
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
value = v;
|
|
888
|
-
}
|
|
889
|
-
} else if (value[p[0]] !== void 0) {
|
|
890
|
-
const curValue = getValueAtPath(currentValue, p);
|
|
891
|
-
const newValue = getValueAtPath(value, p);
|
|
892
|
-
if (JSON.stringify(curValue) === JSON.stringify(newValue)) {
|
|
893
|
-
delete pending2[key];
|
|
894
|
-
didChangeMetadata = true;
|
|
895
|
-
} else {
|
|
896
|
-
const oldValue = clone(value);
|
|
897
|
-
pending2[key].p = getValueAtPath(oldValue, p);
|
|
898
|
-
value = setAtPath(
|
|
899
|
-
value,
|
|
900
|
-
p,
|
|
901
|
-
t,
|
|
902
|
-
v,
|
|
903
|
-
"merge",
|
|
904
|
-
obs$.peek(),
|
|
905
|
-
(path, value2) => {
|
|
906
|
-
delete pending2[key];
|
|
907
|
-
pending2[path.join("/")] = {
|
|
908
|
-
p: null,
|
|
909
|
-
v: value2,
|
|
910
|
-
t: t.slice(0, path.length)
|
|
911
|
-
};
|
|
912
|
-
}
|
|
913
|
-
);
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
});
|
|
917
|
-
if (didChangeMetadata && syncOptions.persist) {
|
|
918
|
-
updateMetadata(obs$, localState, syncState$, syncOptions, {
|
|
919
|
-
pending: pending2
|
|
920
|
-
});
|
|
921
|
-
}
|
|
922
|
-
}
|
|
923
|
-
onChangeRemote(() => {
|
|
924
|
-
if (isPlainObject(value)) {
|
|
925
|
-
value = ObservableHint.plain(value);
|
|
926
|
-
}
|
|
927
|
-
if (mode === "assign") {
|
|
928
|
-
obs$.assign(value);
|
|
929
|
-
} else if (mode === "append") {
|
|
930
|
-
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && !isArray(value)) {
|
|
931
|
-
console.error("[legend-state] mode:append expects the value to be an array");
|
|
980
|
+
mode = mode || syncOptions.mode || "set";
|
|
981
|
+
if (value !== void 0) {
|
|
982
|
+
value = transformLoadData(value, syncOptions, true, "get");
|
|
983
|
+
if (isPromise$1(value)) {
|
|
984
|
+
value = await value;
|
|
985
|
+
}
|
|
986
|
+
const pending2 = localState.pendingChanges;
|
|
987
|
+
const currentValue = obs$.peek();
|
|
988
|
+
if (pending2) {
|
|
989
|
+
let didChangeMetadata = false;
|
|
990
|
+
Object.keys(pending2).forEach((key) => {
|
|
991
|
+
const p = key.split("/").filter((k) => k !== "");
|
|
992
|
+
const { v, t } = pending2[key];
|
|
993
|
+
if (t.length === 0 || !value) {
|
|
994
|
+
const oldValue = clone2(value);
|
|
995
|
+
pending2[key].p = key ? oldValue[key] : oldValue;
|
|
996
|
+
if (isObject(value) && isObject(v)) {
|
|
997
|
+
Object.assign(value, key ? { [key]: v } : v);
|
|
998
|
+
} else if (!key) {
|
|
999
|
+
value = v;
|
|
932
1000
|
}
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
1001
|
+
} else if (value[p[0]] !== void 0) {
|
|
1002
|
+
const curValue = getValueAtPath(currentValue, p);
|
|
1003
|
+
const newValue = getValueAtPath(value, p);
|
|
1004
|
+
if (JSON.stringify(curValue) === JSON.stringify(newValue)) {
|
|
1005
|
+
delete pending2[key];
|
|
1006
|
+
didChangeMetadata = true;
|
|
1007
|
+
} else {
|
|
1008
|
+
const oldValue = clone2(value);
|
|
1009
|
+
pending2[key].p = getValueAtPath(oldValue, p);
|
|
1010
|
+
didChangeMetadata = true;
|
|
1011
|
+
value = setAtPath(
|
|
1012
|
+
value,
|
|
1013
|
+
p,
|
|
1014
|
+
t,
|
|
1015
|
+
v,
|
|
1016
|
+
"merge",
|
|
1017
|
+
obs$.peek(),
|
|
1018
|
+
(path, value2) => {
|
|
1019
|
+
delete pending2[key];
|
|
1020
|
+
pending2[path.join("/")] = {
|
|
1021
|
+
p: null,
|
|
1022
|
+
v: value2,
|
|
1023
|
+
t: t.slice(0, path.length)
|
|
1024
|
+
};
|
|
1025
|
+
}
|
|
1026
|
+
);
|
|
937
1027
|
}
|
|
938
|
-
obs$.splice(0, 0, ...value);
|
|
939
|
-
} else if (mode === "merge") {
|
|
940
|
-
mergeIntoObservable(obs$, value);
|
|
941
|
-
} else {
|
|
942
|
-
obs$.set(value);
|
|
943
1028
|
}
|
|
944
1029
|
});
|
|
1030
|
+
if (didChangeMetadata && syncOptions.persist) {
|
|
1031
|
+
updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
|
|
1032
|
+
pending: pending2
|
|
1033
|
+
});
|
|
1034
|
+
}
|
|
945
1035
|
}
|
|
946
|
-
if (
|
|
947
|
-
|
|
948
|
-
lastSync: lastSync2
|
|
949
|
-
});
|
|
1036
|
+
if (options == null ? void 0 : options.resetLastSync) {
|
|
1037
|
+
setNodeValue(node, (_a2 = syncOptions.initial) != null ? _a2 : void 0);
|
|
950
1038
|
}
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
1039
|
+
onChangeRemote2(() => {
|
|
1040
|
+
if (isPlainObject(value)) {
|
|
1041
|
+
value = ObservableHint.plain(value);
|
|
1042
|
+
}
|
|
1043
|
+
if (mode === "assign") {
|
|
1044
|
+
obs$.assign(value);
|
|
1045
|
+
} else if (mode === "append") {
|
|
1046
|
+
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && !isArray(value)) {
|
|
1047
|
+
console.error("[legend-state] mode:append expects the value to be an array");
|
|
1048
|
+
}
|
|
1049
|
+
obs$.push(...value);
|
|
1050
|
+
} else if (mode === "prepend") {
|
|
1051
|
+
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && !isArray(value)) {
|
|
1052
|
+
console.error("[legend-state] mode:prepend expects the value to be an array");
|
|
1053
|
+
}
|
|
1054
|
+
obs$.splice(0, 0, ...value);
|
|
1055
|
+
} else if (mode === "merge") {
|
|
1056
|
+
mergeIntoObservable(obs$, value);
|
|
1057
|
+
} else {
|
|
1058
|
+
obs$.set(value);
|
|
1059
|
+
}
|
|
1060
|
+
});
|
|
954
1061
|
}
|
|
955
|
-
if (
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
const subscribeParams = {
|
|
960
|
-
node,
|
|
961
|
-
value$: obs$,
|
|
962
|
-
lastSync,
|
|
963
|
-
update: (params) => {
|
|
964
|
-
when(
|
|
965
|
-
() => !get || syncState$.isLoaded.get(),
|
|
966
|
-
() => {
|
|
967
|
-
when(waitFor || true, () => {
|
|
968
|
-
params.mode || (params.mode = syncOptions.mode || "merge");
|
|
969
|
-
onChange(params);
|
|
970
|
-
if (!syncState$.isLoaded.peek()) {
|
|
971
|
-
syncState$.assign({
|
|
972
|
-
isLoaded: syncStateValue.numPendingRemoteLoads < 1,
|
|
973
|
-
error: void 0,
|
|
974
|
-
isGetting: syncStateValue.numPendingGets > 0
|
|
975
|
-
});
|
|
976
|
-
}
|
|
977
|
-
});
|
|
978
|
-
}
|
|
979
|
-
);
|
|
980
|
-
},
|
|
981
|
-
refresh: () => when(syncState$.isLoaded, sync),
|
|
982
|
-
onError: (error) => onGetError(error, { source: "subscribe", subscribeParams })
|
|
983
|
-
};
|
|
984
|
-
unsubscribe = subscribe2(subscribeParams);
|
|
985
|
-
};
|
|
986
|
-
if (waitFor) {
|
|
987
|
-
whenReady(waitFor, doSubscribe);
|
|
988
|
-
} else {
|
|
989
|
-
doSubscribe();
|
|
990
|
-
}
|
|
1062
|
+
if (lastSync2 && syncOptions.persist) {
|
|
1063
|
+
updateMetadata(obs$, localState, syncState$, syncOptions, {
|
|
1064
|
+
lastSync: lastSync2
|
|
1065
|
+
});
|
|
991
1066
|
}
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
1067
|
+
};
|
|
1068
|
+
if (node.activationState) {
|
|
1069
|
+
node.activationState.onChange = onChange;
|
|
1070
|
+
}
|
|
1071
|
+
if (!isSubscribed && syncOptions.subscribe) {
|
|
1072
|
+
const subscribe2 = syncOptions.subscribe;
|
|
1073
|
+
const doSubscribe = () => {
|
|
1074
|
+
isSubscribed = true;
|
|
1075
|
+
const subscribeParams = {
|
|
996
1076
|
node,
|
|
997
1077
|
value$: obs$,
|
|
998
|
-
value: isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked]) ? void 0 : existingValue,
|
|
999
|
-
mode: syncOptions.mode,
|
|
1000
|
-
refresh: sync,
|
|
1001
|
-
options: syncOptions,
|
|
1002
|
-
lastSync,
|
|
1003
|
-
updateLastSync: (lastSync2) => getParams.lastSync = lastSync2,
|
|
1004
|
-
onError,
|
|
1005
|
-
retryNum: 0,
|
|
1006
|
-
cancelRetry: false
|
|
1007
|
-
};
|
|
1008
|
-
let modeBeforeReset = void 0;
|
|
1009
|
-
const beforeGetParams = {
|
|
1010
|
-
value: getParams.value,
|
|
1011
1078
|
lastSync,
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1079
|
+
update: (params) => {
|
|
1080
|
+
when(
|
|
1081
|
+
() => !get || syncState$.isLoaded.get(),
|
|
1082
|
+
() => {
|
|
1083
|
+
when(waitFor || true, () => {
|
|
1084
|
+
params.mode || (params.mode = syncOptions.mode || "merge");
|
|
1085
|
+
onChange(params);
|
|
1086
|
+
if (!syncState$.isLoaded.peek()) {
|
|
1087
|
+
syncState$.assign({
|
|
1088
|
+
isLoaded: syncStateValue.numPendingRemoteLoads < 1,
|
|
1089
|
+
error: void 0,
|
|
1090
|
+
isGetting: syncStateValue.numPendingGets > 0
|
|
1091
|
+
});
|
|
1092
|
+
}
|
|
1093
|
+
});
|
|
1094
|
+
}
|
|
1095
|
+
);
|
|
1024
1096
|
},
|
|
1025
|
-
|
|
1097
|
+
refresh: () => when(syncState$.isLoaded, callSync),
|
|
1098
|
+
onError: (error) => onGetError(error, {
|
|
1099
|
+
source: "subscribe",
|
|
1100
|
+
subscribeParams,
|
|
1101
|
+
type: "get",
|
|
1102
|
+
retry: {}
|
|
1103
|
+
})
|
|
1026
1104
|
};
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1105
|
+
unsubscribe = subscribe2(subscribeParams);
|
|
1106
|
+
registerMiddleware(node, "listeners-cleared", () => {
|
|
1107
|
+
if (unsubscribe) {
|
|
1108
|
+
isSubscribed = false;
|
|
1109
|
+
unsubscribe();
|
|
1110
|
+
unsubscribe = void 0;
|
|
1111
|
+
}
|
|
1112
|
+
});
|
|
1113
|
+
registerMiddleware(node, "listener-added", () => {
|
|
1114
|
+
if (!isSubscribed) {
|
|
1115
|
+
doSubscribe();
|
|
1116
|
+
}
|
|
1117
|
+
});
|
|
1118
|
+
};
|
|
1119
|
+
if (waitFor) {
|
|
1120
|
+
whenReady(waitFor, doSubscribe);
|
|
1121
|
+
} else {
|
|
1122
|
+
doSubscribe();
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
const existingValue = getNodeValue(node);
|
|
1126
|
+
if (get) {
|
|
1127
|
+
const getParams = {
|
|
1128
|
+
node,
|
|
1129
|
+
value$: obs$,
|
|
1130
|
+
value: isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked]) ? void 0 : existingValue,
|
|
1131
|
+
mode: syncOptions.mode,
|
|
1132
|
+
refresh: sync,
|
|
1133
|
+
options: syncOptions,
|
|
1134
|
+
lastSync,
|
|
1135
|
+
updateLastSync: (lastSync2) => getParams.lastSync = lastSync2,
|
|
1136
|
+
onError: onGetError,
|
|
1137
|
+
retryNum: 0,
|
|
1138
|
+
cancelRetry: false
|
|
1139
|
+
};
|
|
1140
|
+
let modeBeforeReset = void 0;
|
|
1141
|
+
const beforeGetParams = {
|
|
1142
|
+
value: getParams.value,
|
|
1143
|
+
lastSync,
|
|
1144
|
+
pendingChanges: pending && !isEmpty(pending) ? pending : void 0,
|
|
1145
|
+
clearPendingChanges: async () => {
|
|
1146
|
+
localState.pendingChanges = {};
|
|
1147
|
+
await updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
|
|
1148
|
+
pending: localState.pendingChanges
|
|
1032
1149
|
});
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1150
|
+
},
|
|
1151
|
+
resetCache: () => {
|
|
1152
|
+
var _a2;
|
|
1153
|
+
modeBeforeReset = getParams.mode;
|
|
1154
|
+
getParams.mode = "set";
|
|
1155
|
+
return (_a2 = syncStateValue.resetPersistence) == null ? void 0 : _a2.call(syncStateValue);
|
|
1156
|
+
},
|
|
1157
|
+
cancel: false
|
|
1158
|
+
};
|
|
1159
|
+
(_a = syncOptions.onBeforeGet) == null ? void 0 : _a.call(syncOptions, beforeGetParams);
|
|
1160
|
+
if (!beforeGetParams.cancel) {
|
|
1161
|
+
syncState$.assign({
|
|
1162
|
+
numPendingGets: (syncStateValue.numPendingGets || 0) + 1,
|
|
1163
|
+
isGetting: true
|
|
1164
|
+
});
|
|
1165
|
+
const got = runWithRetry(getParams, syncOptions.retry, node, (retryEvent) => {
|
|
1166
|
+
const params = getParams;
|
|
1167
|
+
params.cancelRetry = retryEvent.cancelRetry;
|
|
1168
|
+
params.retryNum = retryEvent.retryNum;
|
|
1169
|
+
return get(params);
|
|
1170
|
+
});
|
|
1171
|
+
const numGets = node.numGets = (node.numGets || 0) + 1;
|
|
1172
|
+
const handle = (value) => {
|
|
1173
|
+
syncState$.numPendingGets.set((v) => v - 1);
|
|
1174
|
+
if (isWaitingForLoad) {
|
|
1175
|
+
isWaitingForLoad = false;
|
|
1176
|
+
syncStateValue.numPendingRemoteLoads--;
|
|
1177
|
+
}
|
|
1178
|
+
if (numGets >= (node.getNumResolved || 0)) {
|
|
1179
|
+
node.getNumResolved = node.numGets;
|
|
1180
|
+
onChange({
|
|
1181
|
+
value,
|
|
1182
|
+
lastSync: getParams.lastSync,
|
|
1183
|
+
mode: getParams.mode
|
|
1067
1184
|
});
|
|
1068
|
-
};
|
|
1069
|
-
if (isPromise$1(got)) {
|
|
1070
|
-
got.then(handle).catch(onError);
|
|
1071
|
-
} else {
|
|
1072
|
-
handle(got);
|
|
1073
1185
|
}
|
|
1186
|
+
if (modeBeforeReset) {
|
|
1187
|
+
getParams.mode = modeBeforeReset;
|
|
1188
|
+
modeBeforeReset = void 0;
|
|
1189
|
+
}
|
|
1190
|
+
syncState$.assign({
|
|
1191
|
+
isLoaded: syncStateValue.numPendingRemoteLoads < 1,
|
|
1192
|
+
error: void 0,
|
|
1193
|
+
isGetting: syncStateValue.numPendingGets > 0
|
|
1194
|
+
});
|
|
1195
|
+
};
|
|
1196
|
+
if (isPromise$1(got)) {
|
|
1197
|
+
got.then(handle).catch((error) => {
|
|
1198
|
+
onGetError(error, { getParams, source: "get", type: "get", retry: getParams }, true);
|
|
1199
|
+
});
|
|
1200
|
+
} else {
|
|
1201
|
+
handle(got);
|
|
1074
1202
|
}
|
|
1075
1203
|
}
|
|
1076
|
-
};
|
|
1077
|
-
if (waitFor) {
|
|
1078
|
-
whenReady(waitFor, () => trackSelector(runGet, sync));
|
|
1079
|
-
} else {
|
|
1080
|
-
trackSelector(runGet, sync);
|
|
1081
1204
|
}
|
|
1205
|
+
};
|
|
1206
|
+
if (waitFor) {
|
|
1207
|
+
whenReady(waitFor, () => trackSelector(runGet, callSync));
|
|
1082
1208
|
} else {
|
|
1083
|
-
|
|
1084
|
-
isLoaded: true,
|
|
1085
|
-
error: void 0
|
|
1086
|
-
});
|
|
1209
|
+
trackSelector(runGet, callSync);
|
|
1087
1210
|
}
|
|
1088
1211
|
if (!isSynced) {
|
|
1089
1212
|
isSynced = true;
|
|
1090
|
-
|
|
1213
|
+
isApplyingPendingAfterSync = true;
|
|
1091
1214
|
applyPending(pending);
|
|
1215
|
+
isApplyingPendingAfterSync = false;
|
|
1092
1216
|
}
|
|
1093
1217
|
};
|
|
1094
1218
|
syncStateValue.sync = sync;
|
|
1095
1219
|
} else {
|
|
1096
1220
|
if (!isSynced) {
|
|
1221
|
+
isApplyingPendingAfterSync = true;
|
|
1097
1222
|
applyPending(localState.pendingChanges);
|
|
1223
|
+
isApplyingPendingAfterSync = false;
|
|
1098
1224
|
}
|
|
1099
1225
|
}
|
|
1100
1226
|
syncStateValue.reset = async () => {
|
|
@@ -1104,7 +1230,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
1104
1230
|
if (metadata) {
|
|
1105
1231
|
Object.assign(metadata, { lastSync: void 0, pending: void 0 });
|
|
1106
1232
|
}
|
|
1107
|
-
|
|
1233
|
+
const newState = {
|
|
1108
1234
|
isPersistEnabled: false,
|
|
1109
1235
|
isSyncEnabled: false,
|
|
1110
1236
|
lastSync: void 0,
|
|
@@ -1114,13 +1240,14 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
1114
1240
|
isSetting: false,
|
|
1115
1241
|
numPendingSets: 0,
|
|
1116
1242
|
syncCount: 0
|
|
1117
|
-
}
|
|
1243
|
+
};
|
|
1244
|
+
Object.assign(syncStateValue, newState);
|
|
1118
1245
|
isSynced = false;
|
|
1119
1246
|
isSubscribed = false;
|
|
1120
1247
|
unsubscribe == null ? void 0 : unsubscribe();
|
|
1121
1248
|
unsubscribe = void 0;
|
|
1122
1249
|
const promise = syncStateValue.resetPersistence();
|
|
1123
|
-
|
|
1250
|
+
onChangeRemote2(() => {
|
|
1124
1251
|
var _a;
|
|
1125
1252
|
obs$.set((_a = syncOptions.initial) != null ? _a : void 0);
|
|
1126
1253
|
});
|
|
@@ -1130,6 +1257,14 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
1130
1257
|
node.dirtyFn = sync;
|
|
1131
1258
|
await promise;
|
|
1132
1259
|
};
|
|
1260
|
+
syncState$.lastSync.onChange(({ value }) => {
|
|
1261
|
+
const metadata = metadatas.get(obs$);
|
|
1262
|
+
if (metadata && metadata.lastSync !== value) {
|
|
1263
|
+
updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
|
|
1264
|
+
lastSync: value
|
|
1265
|
+
});
|
|
1266
|
+
}
|
|
1267
|
+
});
|
|
1133
1268
|
const onAllPersistLoaded = () => {
|
|
1134
1269
|
var _a, _b;
|
|
1135
1270
|
let parentNode = node;
|
|
@@ -1153,7 +1288,10 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
1153
1288
|
});
|
|
1154
1289
|
return syncState$;
|
|
1155
1290
|
}
|
|
1156
|
-
|
|
1291
|
+
function getAllSyncStates() {
|
|
1292
|
+
return Array.from(allSyncStates.entries());
|
|
1293
|
+
}
|
|
1294
|
+
var { getProxy, globalState: globalState2, setNodeValue: setNodeValue2, getNodeValue: getNodeValue2 } = internal;
|
|
1157
1295
|
function enableActivateSyncedNode() {
|
|
1158
1296
|
globalState2.activateSyncedNode = function activateSyncedNode(node, newValue) {
|
|
1159
1297
|
const obs$ = getProxy(node);
|
|
@@ -1176,7 +1314,7 @@ function enableActivateSyncedNode() {
|
|
|
1176
1314
|
} else {
|
|
1177
1315
|
newValue = initial;
|
|
1178
1316
|
}
|
|
1179
|
-
|
|
1317
|
+
setNodeValue2(node, promiseReturn ? void 0 : newValue);
|
|
1180
1318
|
syncObservable(obs$, { ...node.activationState, get, set });
|
|
1181
1319
|
return { update: onChange, value: newValue };
|
|
1182
1320
|
} else {
|
|
@@ -1225,9 +1363,10 @@ function configureSynced(fnOrOrigOptions, origOptions) {
|
|
|
1225
1363
|
}
|
|
1226
1364
|
|
|
1227
1365
|
// sync.ts
|
|
1228
|
-
var
|
|
1366
|
+
var internal5 = {
|
|
1229
1367
|
observableSyncConfiguration,
|
|
1230
|
-
waitForSet
|
|
1368
|
+
waitForSet,
|
|
1369
|
+
runWithRetry
|
|
1231
1370
|
};
|
|
1232
1371
|
|
|
1233
|
-
export { combineTransforms, configureObservableSync, configureSynced, deepEqual, diffObjects,
|
|
1372
|
+
export { combineTransforms, configureObservableSync, configureSynced, createRevertChanges, deepEqual, diffObjects, getAllSyncStates, internal5 as internal, mapSyncPlugins, onChangeRemote2 as onChangeRemote, removeNullUndefined, syncObservable, synced, transformStringifyDates, transformStringifyKeys };
|