@legendapp/state 3.0.0-alpha.2 → 3.0.0-alpha.21
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/CHANGELOG.md +831 -1
- package/LICENSE +21 -1
- package/README.md +141 -1
- package/babel.js +0 -2
- package/babel.mjs +0 -2
- package/helpers/trackHistory.js +2 -2
- package/helpers/trackHistory.mjs +2 -2
- package/index.d.mts +45 -32
- package/index.d.ts +45 -32
- package/index.js +234 -156
- package/index.mjs +234 -156
- package/package.json +6 -1
- package/persist-plugins/async-storage.d.mts +2 -2
- package/persist-plugins/async-storage.d.ts +2 -2
- package/persist-plugins/indexeddb.js +1 -1
- package/persist-plugins/indexeddb.mjs +1 -1
- package/react.d.mts +17 -14
- package/react.d.ts +17 -14
- package/react.js +55 -30
- package/react.mjs +56 -31
- package/sync-plugins/_transformObjectFields.d.mts +31 -0
- package/sync-plugins/_transformObjectFields.d.ts +31 -0
- package/sync-plugins/_transformObjectFields.js +114 -0
- package/sync-plugins/_transformObjectFields.mjs +110 -0
- package/sync-plugins/crud.d.mts +14 -23
- package/sync-plugins/crud.d.ts +14 -23
- package/sync-plugins/crud.js +205 -134
- package/sync-plugins/crud.mjs +206 -135
- package/sync-plugins/firebase.d.mts +26 -0
- package/sync-plugins/firebase.d.ts +26 -0
- package/sync-plugins/firebase.js +365 -0
- package/sync-plugins/firebase.mjs +360 -0
- package/sync-plugins/keel.d.mts +24 -8
- package/sync-plugins/keel.d.ts +24 -8
- package/sync-plugins/keel.js +32 -16
- package/sync-plugins/keel.mjs +32 -16
- package/sync-plugins/supabase.d.mts +1 -1
- package/sync-plugins/supabase.d.ts +1 -1
- package/sync-plugins/supabase.js +5 -4
- package/sync-plugins/supabase.mjs +6 -5
- package/sync-plugins/tanstack-query.d.mts +2 -2
- package/sync-plugins/tanstack-query.d.ts +2 -2
- package/sync-plugins/tanstack-query.js +3 -2
- package/sync-plugins/tanstack-query.mjs +3 -2
- package/sync-plugins/tanstack-react-query.d.mts +1 -1
- package/sync-plugins/tanstack-react-query.d.ts +1 -1
- package/sync.d.mts +38 -185
- package/sync.d.ts +38 -185
- package/sync.js +354 -296
- package/sync.mjs +356 -297
- package/types/babel.d.ts +12 -1
- package/.DS_Store +0 -0
- /package/config/{enable_GetSet.d.mts → enable$GetSet.d.mts} +0 -0
- /package/config/{enable_GetSet.d.ts → enable$GetSet.d.ts} +0 -0
package/sync.mjs
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { isObject, isDate, isNullOrUndefined, isString, endBatch, beginBatch, isFunction,
|
|
2
|
-
|
|
3
|
-
// sync.ts
|
|
1
|
+
import { isObject, isDate, isNullOrUndefined, isString, endBatch, beginBatch, isFunction, syncState, when, linked, internal, observable, isPromise, mergeIntoObservable, isEmpty, whenReady, trackSelector, shouldIgnoreUnobserved, constructObjectWithPath, setAtPath, isArray } from '@legendapp/state';
|
|
4
2
|
|
|
5
3
|
// src/sync/configureObservableSync.ts
|
|
6
4
|
var observableSyncConfiguration = {};
|
|
@@ -137,34 +135,19 @@ function transformStringifyDates(...args) {
|
|
|
137
135
|
}
|
|
138
136
|
};
|
|
139
137
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
lastSync: params.lastSync,
|
|
152
|
-
mode: params.mode
|
|
153
|
-
});
|
|
154
|
-
params.onGet();
|
|
155
|
-
} catch (e) {
|
|
156
|
-
}
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
if (set) {
|
|
160
|
-
ret.set = set;
|
|
161
|
-
}
|
|
162
|
-
return ret;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// src/sync/syncObservable.ts
|
|
166
|
-
var { createPreviousHandler, clone, getValueAtPath, globalState, symbolLinked, getNode, getNodeValue } = internal;
|
|
138
|
+
var {
|
|
139
|
+
clone,
|
|
140
|
+
deepMerge,
|
|
141
|
+
getNode,
|
|
142
|
+
getNodeValue,
|
|
143
|
+
getValueAtPath,
|
|
144
|
+
globalState,
|
|
145
|
+
runWithRetry,
|
|
146
|
+
symbolLinked,
|
|
147
|
+
createPreviousHandler
|
|
148
|
+
} = internal;
|
|
167
149
|
var mapSyncPlugins = /* @__PURE__ */ new WeakMap();
|
|
150
|
+
var allSyncStates = /* @__PURE__ */ new Map();
|
|
168
151
|
var metadatas = /* @__PURE__ */ new WeakMap();
|
|
169
152
|
var promisesLocalSaves = /* @__PURE__ */ new Set();
|
|
170
153
|
function parseLocalConfig(config) {
|
|
@@ -181,13 +164,19 @@ function onChangeRemote(cb) {
|
|
|
181
164
|
globalState.isLoadingRemote = false;
|
|
182
165
|
endBatch(true);
|
|
183
166
|
}
|
|
184
|
-
function transformSaveData(value, path, pathTypes, { transform }) {
|
|
167
|
+
async function transformSaveData(value, path, pathTypes, { transform }) {
|
|
185
168
|
if (transform == null ? void 0 : transform.save) {
|
|
186
169
|
const constructed = constructObjectWithPath(path, pathTypes, value);
|
|
187
|
-
const saved = transform.save(constructed);
|
|
188
|
-
value =
|
|
170
|
+
const saved = await transform.save(constructed);
|
|
171
|
+
value = saved;
|
|
172
|
+
const outPath = [];
|
|
173
|
+
for (let i = 0; i < path.length; i++) {
|
|
174
|
+
outPath[i] = Object.keys(value)[0];
|
|
175
|
+
value = value[outPath[i]];
|
|
176
|
+
}
|
|
177
|
+
path = outPath;
|
|
189
178
|
}
|
|
190
|
-
return value;
|
|
179
|
+
return { value, path };
|
|
191
180
|
}
|
|
192
181
|
function transformLoadData(value, { transform }, doUserTransform, method) {
|
|
193
182
|
if (doUserTransform && (transform == null ? void 0 : transform.load)) {
|
|
@@ -195,7 +184,7 @@ function transformLoadData(value, { transform }, doUserTransform, method) {
|
|
|
195
184
|
}
|
|
196
185
|
return value;
|
|
197
186
|
}
|
|
198
|
-
async function updateMetadataImmediate(value$, localState,
|
|
187
|
+
async function updateMetadataImmediate(value$, localState, syncState2, syncOptions, newMetadata) {
|
|
199
188
|
const saves = Array.from(promisesLocalSaves);
|
|
200
189
|
if (saves.length > 0) {
|
|
201
190
|
await Promise.all(saves);
|
|
@@ -203,27 +192,24 @@ async function updateMetadataImmediate(value$, localState, syncState, syncOption
|
|
|
203
192
|
const { pluginPersist } = localState;
|
|
204
193
|
const { table, config } = parseLocalConfig(syncOptions == null ? void 0 : syncOptions.persist);
|
|
205
194
|
const oldMetadata = metadatas.get(value$);
|
|
206
|
-
const { lastSync
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
lastSync
|
|
217
|
-
});
|
|
218
|
-
}
|
|
195
|
+
const { lastSync } = newMetadata;
|
|
196
|
+
const metadata = Object.assign({}, oldMetadata, newMetadata);
|
|
197
|
+
metadatas.set(value$, metadata);
|
|
198
|
+
if (pluginPersist) {
|
|
199
|
+
await pluginPersist.setMetadata(table, metadata, config);
|
|
200
|
+
}
|
|
201
|
+
if (lastSync) {
|
|
202
|
+
syncState2.assign({
|
|
203
|
+
lastSync
|
|
204
|
+
});
|
|
219
205
|
}
|
|
220
206
|
}
|
|
221
|
-
function updateMetadata(value$, localState,
|
|
207
|
+
function updateMetadata(value$, localState, syncState2, syncOptions, newMetadata) {
|
|
222
208
|
if (localState.timeoutSaveMetadata) {
|
|
223
209
|
clearTimeout(localState.timeoutSaveMetadata);
|
|
224
210
|
}
|
|
225
211
|
localState.timeoutSaveMetadata = setTimeout(
|
|
226
|
-
() => updateMetadataImmediate(value$, localState,
|
|
212
|
+
() => updateMetadataImmediate(value$, localState, syncState2, syncOptions, newMetadata),
|
|
227
213
|
0
|
|
228
214
|
);
|
|
229
215
|
}
|
|
@@ -251,26 +237,25 @@ function mergeChanges(changes) {
|
|
|
251
237
|
return changesOut;
|
|
252
238
|
}
|
|
253
239
|
function mergeQueuedChanges(allChanges) {
|
|
254
|
-
const
|
|
255
|
-
const
|
|
256
|
-
const
|
|
240
|
+
const changesByOptionsRemote = /* @__PURE__ */ new Map();
|
|
241
|
+
const changesByOptionsLocal = /* @__PURE__ */ new Map();
|
|
242
|
+
const previousByOptions = /* @__PURE__ */ new Map();
|
|
257
243
|
const outRemote = /* @__PURE__ */ new Map();
|
|
258
244
|
const outLocal = /* @__PURE__ */ new Map();
|
|
259
245
|
for (let i = 0; i < allChanges.length; i++) {
|
|
260
246
|
const value = allChanges[i];
|
|
261
|
-
const {
|
|
247
|
+
const { changes, inRemoteChange, getPrevious, syncOptions } = value;
|
|
262
248
|
const targetMap = inRemoteChange ? outRemote : outLocal;
|
|
263
|
-
const changesMap = inRemoteChange ?
|
|
264
|
-
const existing = changesMap.get(
|
|
249
|
+
const changesMap = inRemoteChange ? changesByOptionsRemote : changesByOptionsLocal;
|
|
250
|
+
const existing = changesMap.get(syncOptions);
|
|
265
251
|
const newChanges = existing ? [...existing, ...changes] : changes;
|
|
266
252
|
const merged = mergeChanges(newChanges);
|
|
267
|
-
changesMap.set(
|
|
253
|
+
changesMap.set(syncOptions, merged);
|
|
268
254
|
value.changes = merged;
|
|
269
|
-
if (!
|
|
270
|
-
|
|
255
|
+
if (!previousByOptions.has(syncOptions)) {
|
|
256
|
+
previousByOptions.set(syncOptions, getPrevious());
|
|
271
257
|
}
|
|
272
|
-
|
|
273
|
-
targetMap.set(obs, value);
|
|
258
|
+
targetMap.set(syncOptions, value);
|
|
274
259
|
}
|
|
275
260
|
return Array.from(outRemote.values()).concat(Array.from(outLocal.values()));
|
|
276
261
|
}
|
|
@@ -316,15 +301,13 @@ async function processQueuedRemoteChanges(syncOptions) {
|
|
|
316
301
|
}
|
|
317
302
|
}
|
|
318
303
|
async function prepChangeLocal(queuedChange) {
|
|
319
|
-
const { syncState, changes,
|
|
304
|
+
const { syncState: syncState2, changes, syncOptions, inRemoteChange, isApplyingPending } = queuedChange;
|
|
320
305
|
const persist = syncOptions.persist;
|
|
321
|
-
const { pluginSync } = localState;
|
|
322
306
|
const { config: configLocal } = parseLocalConfig(persist);
|
|
323
|
-
const
|
|
324
|
-
const
|
|
325
|
-
const saveRemote = !!(!inRemoteChange && (pluginSync == null ? void 0 : pluginSync.set) && (configRemote == null ? void 0 : configRemote.enableSync) !== false && syncState.isSyncEnabled.peek());
|
|
307
|
+
const saveLocal = (persist == null ? void 0 : persist.name) && !configLocal.readonly && !isApplyingPending && syncState2.isPersistEnabled.peek();
|
|
308
|
+
const saveRemote = !!(!inRemoteChange && (syncOptions == null ? void 0 : syncOptions.set) && syncState2.isSyncEnabled.peek());
|
|
326
309
|
if (saveLocal || saveRemote) {
|
|
327
|
-
if (saveLocal && !
|
|
310
|
+
if (saveLocal && !syncState2.isPersistLoaded.peek()) {
|
|
328
311
|
console.error(
|
|
329
312
|
"[legend-state] WARNING: An observable was changed before being loaded from persist",
|
|
330
313
|
persist
|
|
@@ -357,13 +340,13 @@ async function prepChangeLocal(queuedChange) {
|
|
|
357
340
|
configLocal
|
|
358
341
|
);
|
|
359
342
|
promisesTransform.push(
|
|
360
|
-
doInOrder(promiseTransformLocal, (valueTransformed) => {
|
|
343
|
+
doInOrder(promiseTransformLocal, ({ value: valueTransformed, path: pathTransformed }) => {
|
|
361
344
|
changesLocal.push({
|
|
362
|
-
path,
|
|
345
|
+
path: pathTransformed,
|
|
363
346
|
pathTypes,
|
|
364
347
|
prevAtPath,
|
|
365
348
|
valueAtPath: valueTransformed,
|
|
366
|
-
pathStr
|
|
349
|
+
pathStr: path === pathTransformed ? pathStr : pathTransformed.join("/")
|
|
367
350
|
});
|
|
368
351
|
})
|
|
369
352
|
);
|
|
@@ -379,22 +362,19 @@ async function prepChangeLocal(queuedChange) {
|
|
|
379
362
|
}
|
|
380
363
|
async function prepChangeRemote(queuedChange) {
|
|
381
364
|
const {
|
|
382
|
-
syncState,
|
|
365
|
+
syncState: syncState2,
|
|
383
366
|
changes,
|
|
384
367
|
localState,
|
|
385
368
|
syncOptions,
|
|
386
369
|
inRemoteChange,
|
|
387
|
-
isApplyingPending
|
|
388
|
-
valuePrevious
|
|
370
|
+
isApplyingPending
|
|
389
371
|
} = queuedChange;
|
|
390
372
|
const persist = syncOptions.persist;
|
|
391
|
-
const { pluginSync } = localState;
|
|
392
373
|
const { config: configLocal } = parseLocalConfig(persist);
|
|
393
|
-
const
|
|
394
|
-
const
|
|
395
|
-
const saveRemote = !inRemoteChange && (pluginSync == null ? void 0 : pluginSync.set) && (configRemote == null ? void 0 : configRemote.enableSync) !== false && syncState.isSyncEnabled.peek();
|
|
374
|
+
const saveLocal = persist && !configLocal.readonly && !isApplyingPending && syncState2.isPersistEnabled.peek();
|
|
375
|
+
const saveRemote = !inRemoteChange && (syncOptions == null ? void 0 : syncOptions.set) && syncState2.isSyncEnabled.peek();
|
|
396
376
|
if (saveLocal || saveRemote) {
|
|
397
|
-
if (saveLocal && !
|
|
377
|
+
if (saveLocal && !syncState2.isPersistLoaded.peek()) {
|
|
398
378
|
console.error(
|
|
399
379
|
"[legend-state] WARNING: An observable was changed before being loaded from persist",
|
|
400
380
|
persist
|
|
@@ -424,20 +404,20 @@ async function prepChangeRemote(queuedChange) {
|
|
|
424
404
|
valueAtPath,
|
|
425
405
|
path,
|
|
426
406
|
pathTypes,
|
|
427
|
-
|
|
407
|
+
syncOptions || {}
|
|
428
408
|
);
|
|
429
409
|
promisesTransform.push(
|
|
430
|
-
doInOrder(promiseTransformRemote, (valueTransformed) => {
|
|
410
|
+
doInOrder(promiseTransformRemote, ({ value: valueTransformed, path: pathTransformed }) => {
|
|
431
411
|
var _a;
|
|
432
412
|
if (!localState.pendingChanges) {
|
|
433
413
|
localState.pendingChanges = {};
|
|
434
414
|
}
|
|
435
415
|
let found2 = false;
|
|
436
|
-
for (let i2 = 0; !found2 && i2 <
|
|
437
|
-
const pathParent =
|
|
416
|
+
for (let i2 = 0; !found2 && i2 < pathTransformed.length - 1; i2++) {
|
|
417
|
+
const pathParent = pathTransformed.slice(0, i2 + 1).join("/");
|
|
438
418
|
if ((_a = localState.pendingChanges[pathParent]) == null ? void 0 : _a.v) {
|
|
439
419
|
found2 = true;
|
|
440
|
-
const pathChild =
|
|
420
|
+
const pathChild = pathTransformed.slice(i2 + 1);
|
|
441
421
|
const pathTypesChild = pathTypes.slice(i2 + 1);
|
|
442
422
|
setAtPath(
|
|
443
423
|
localState.pendingChanges[pathParent].v,
|
|
@@ -459,12 +439,11 @@ async function prepChangeRemote(queuedChange) {
|
|
|
459
439
|
localState.pendingChanges[pathStr].v = valueAtPath;
|
|
460
440
|
}
|
|
461
441
|
changesRemote.push({
|
|
462
|
-
path,
|
|
442
|
+
path: pathTransformed,
|
|
463
443
|
pathTypes,
|
|
464
444
|
prevAtPath,
|
|
465
445
|
valueAtPath: valueTransformed,
|
|
466
|
-
pathStr
|
|
467
|
-
valuePrevious
|
|
446
|
+
pathStr
|
|
468
447
|
});
|
|
469
448
|
})
|
|
470
449
|
);
|
|
@@ -482,24 +461,27 @@ async function doChangeLocal(changeInfo) {
|
|
|
482
461
|
if (!changeInfo)
|
|
483
462
|
return;
|
|
484
463
|
const { queuedChange, changesLocal, saveRemote } = changeInfo;
|
|
485
|
-
const { value$: obs, syncState, localState, syncOptions } = queuedChange;
|
|
464
|
+
const { value$: obs, syncState: syncState2, localState, syncOptions } = queuedChange;
|
|
486
465
|
const { pluginPersist } = localState;
|
|
487
466
|
const persist = syncOptions.persist;
|
|
488
|
-
const
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
if (changesLocal.length > 0) {
|
|
496
|
-
let promiseSet = pluginPersist.set(table, changesLocal, configLocal);
|
|
497
|
-
if (promiseSet) {
|
|
498
|
-
promiseSet = promiseSet.then(() => {
|
|
499
|
-
promisesLocalSaves.delete(promiseSet);
|
|
467
|
+
const saveLocal = !!(persist == null ? void 0 : persist.name);
|
|
468
|
+
if (saveLocal) {
|
|
469
|
+
const { table, config: configLocal } = parseLocalConfig(persist);
|
|
470
|
+
const shouldSaveMetadata = persist == null ? void 0 : persist.retrySync;
|
|
471
|
+
if (saveRemote && shouldSaveMetadata) {
|
|
472
|
+
await updateMetadataImmediate(obs, localState, syncState2, syncOptions, {
|
|
473
|
+
pending: localState.pendingChanges
|
|
500
474
|
});
|
|
501
|
-
|
|
502
|
-
|
|
475
|
+
}
|
|
476
|
+
if (changesLocal.length > 0) {
|
|
477
|
+
let promiseSet = pluginPersist.set(table, changesLocal, configLocal);
|
|
478
|
+
if (promiseSet) {
|
|
479
|
+
promiseSet = promiseSet.then(() => {
|
|
480
|
+
promisesLocalSaves.delete(promiseSet);
|
|
481
|
+
});
|
|
482
|
+
promisesLocalSaves.add(promiseSet);
|
|
483
|
+
await promiseSet;
|
|
484
|
+
}
|
|
503
485
|
}
|
|
504
486
|
}
|
|
505
487
|
}
|
|
@@ -508,47 +490,87 @@ async function doChangeRemote(changeInfo) {
|
|
|
508
490
|
if (!changeInfo)
|
|
509
491
|
return;
|
|
510
492
|
const { queuedChange, changesRemote } = changeInfo;
|
|
511
|
-
const { value$: obs
|
|
512
|
-
const { pluginPersist
|
|
493
|
+
const { value$: obs$, syncState: syncState2, localState, syncOptions } = queuedChange;
|
|
494
|
+
const { pluginPersist } = localState;
|
|
495
|
+
const node = getNode(obs$);
|
|
496
|
+
const state$ = node.state;
|
|
513
497
|
const persist = syncOptions.persist;
|
|
514
498
|
const { table, config: configLocal } = parseLocalConfig(persist);
|
|
515
|
-
const {
|
|
499
|
+
const { onBeforeSet, waitForSet, onAfterSet } = syncOptions || {};
|
|
516
500
|
const shouldSaveMetadata = persist == null ? void 0 : persist.retrySync;
|
|
501
|
+
const saveLocal = !!(persist == null ? void 0 : persist.name);
|
|
517
502
|
if (changesRemote.length > 0) {
|
|
518
|
-
|
|
503
|
+
if (!syncState2.isLoaded.peek()) {
|
|
504
|
+
await when(syncState2.isLoaded);
|
|
505
|
+
const pending = localState.pendingChanges;
|
|
506
|
+
if (pending) {
|
|
507
|
+
changesRemote.forEach((change) => {
|
|
508
|
+
const key = change.pathStr;
|
|
509
|
+
const pendingAtPath = pending[key];
|
|
510
|
+
if (!isNullOrUndefined(pendingAtPath)) {
|
|
511
|
+
const { p } = pendingAtPath;
|
|
512
|
+
change.prevAtPath = p;
|
|
513
|
+
}
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
}
|
|
519
517
|
if (waitForSet) {
|
|
520
|
-
const
|
|
521
|
-
if (
|
|
522
|
-
await when(
|
|
518
|
+
const waitFn = isFunction(waitForSet) ? waitForSet({ changes: changesRemote, value: obs$.peek() }) : waitForSet;
|
|
519
|
+
if (waitFn) {
|
|
520
|
+
await when(waitFn);
|
|
523
521
|
}
|
|
524
522
|
}
|
|
525
|
-
let value = obs
|
|
523
|
+
let value = clone(obs$.peek());
|
|
526
524
|
const transformSave = (_a = syncOptions == null ? void 0 : syncOptions.transform) == null ? void 0 : _a.save;
|
|
527
525
|
if (transformSave) {
|
|
528
|
-
value = transformSave(
|
|
526
|
+
value = transformSave(value);
|
|
529
527
|
}
|
|
528
|
+
state$.numPendingSets.set((v) => (v || 0) + 1);
|
|
529
|
+
state$.isSetting.set(true);
|
|
530
530
|
onBeforeSet == null ? void 0 : onBeforeSet();
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
531
|
+
let updateResult = void 0;
|
|
532
|
+
const onError = (error) => {
|
|
533
|
+
var _a2;
|
|
534
|
+
state$.error.set(error);
|
|
535
|
+
(_a2 = syncOptions.onSetError) == null ? void 0 : _a2.call(syncOptions, error, setParams);
|
|
536
|
+
};
|
|
537
|
+
const setParams = {
|
|
538
|
+
node,
|
|
539
|
+
value$: obs$,
|
|
536
540
|
changes: changesRemote,
|
|
537
541
|
value,
|
|
538
|
-
|
|
542
|
+
onError,
|
|
543
|
+
update: (params) => {
|
|
544
|
+
if (updateResult) {
|
|
545
|
+
const { value: value2, lastSync, mode } = params;
|
|
546
|
+
updateResult = {
|
|
547
|
+
lastSync: Math.max(updateResult.lastSync || 0, lastSync || 0),
|
|
548
|
+
value: deepMerge(updateResult.value, value2),
|
|
549
|
+
mode
|
|
550
|
+
};
|
|
551
|
+
} else {
|
|
552
|
+
updateResult = params;
|
|
553
|
+
}
|
|
554
|
+
},
|
|
555
|
+
refresh: syncState2.sync
|
|
556
|
+
};
|
|
557
|
+
let savedPromise = runWithRetry({ retryNum: 0, retry: syncOptions.retry }, async (retryEvent) => {
|
|
558
|
+
const params = setParams;
|
|
559
|
+
params.cancelRetry = retryEvent.cancelRetry;
|
|
560
|
+
params.retryNum = retryEvent.retryNum;
|
|
561
|
+
return syncOptions.set(params);
|
|
539
562
|
});
|
|
540
563
|
if (isPromise(savedPromise)) {
|
|
541
|
-
savedPromise = savedPromise.catch(
|
|
564
|
+
savedPromise = savedPromise.catch(onError);
|
|
542
565
|
}
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
if (saved !== void 0) {
|
|
566
|
+
await savedPromise;
|
|
567
|
+
if (!state$.error.peek()) {
|
|
546
568
|
const pathStrs = Array.from(new Set(changesRemote.map((change) => change.pathStr)));
|
|
547
|
-
const { changes, lastSync } =
|
|
569
|
+
const { value: changes, lastSync } = updateResult || {};
|
|
548
570
|
if (pathStrs.length > 0) {
|
|
549
571
|
let transformedChanges = void 0;
|
|
550
572
|
const metadata = {};
|
|
551
|
-
if (
|
|
573
|
+
if (saveLocal) {
|
|
552
574
|
const pendingMetadata = (_b = pluginPersist.getMetadata(table, configLocal)) == null ? void 0 : _b.pending;
|
|
553
575
|
const pending = localState.pendingChanges;
|
|
554
576
|
for (let i = 0; i < pathStrs.length; i++) {
|
|
@@ -568,42 +590,31 @@ async function doChangeRemote(changeInfo) {
|
|
|
568
590
|
if (changes && !isEmpty(changes)) {
|
|
569
591
|
transformedChanges = transformLoadData(changes, syncOptions, false, "set");
|
|
570
592
|
}
|
|
571
|
-
if (
|
|
572
|
-
if (transformedChanges) {
|
|
573
|
-
|
|
574
|
-
localState.pendingSaveResults = [];
|
|
575
|
-
}
|
|
576
|
-
localState.pendingSaveResults.push(transformedChanges);
|
|
577
|
-
}
|
|
578
|
-
} else {
|
|
579
|
-
let allChanges = [...localState.pendingSaveResults || [], transformedChanges].filter(
|
|
580
|
-
(v) => v !== void 0
|
|
581
|
-
);
|
|
582
|
-
if (allChanges.length > 0) {
|
|
583
|
-
if (allChanges.some((change) => isPromise(change))) {
|
|
584
|
-
allChanges = await Promise.all(allChanges);
|
|
585
|
-
}
|
|
586
|
-
onChangeRemote(() => mergeIntoObservable(obs, ...allChanges));
|
|
593
|
+
if (transformedChanges !== void 0) {
|
|
594
|
+
if (isPromise(transformedChanges)) {
|
|
595
|
+
transformedChanges = await transformedChanges;
|
|
587
596
|
}
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
597
|
+
onChangeRemote(() => mergeIntoObservable(obs$, transformedChanges));
|
|
598
|
+
}
|
|
599
|
+
if (saveLocal) {
|
|
600
|
+
if (shouldSaveMetadata && !isEmpty(metadata)) {
|
|
601
|
+
updateMetadata(obs$, localState, syncState2, syncOptions, metadata);
|
|
592
602
|
}
|
|
593
|
-
localState.pendingSaveResults = [];
|
|
594
603
|
}
|
|
595
|
-
onAfterSet == null ? void 0 : onAfterSet();
|
|
596
604
|
}
|
|
605
|
+
state$.numPendingSets.set((v) => v - 1);
|
|
606
|
+
state$.isSetting.set(state$.numPendingSets.peek() > 0);
|
|
607
|
+
onAfterSet == null ? void 0 : onAfterSet();
|
|
597
608
|
}
|
|
598
609
|
}
|
|
599
610
|
}
|
|
600
|
-
function onObsChange(value$,
|
|
601
|
-
if (!
|
|
602
|
-
const inRemoteChange =
|
|
611
|
+
function onObsChange(value$, syncState2, localState, syncOptions, { changes, isFromPersist, isFromSync, getPrevious }) {
|
|
612
|
+
if (!isFromPersist) {
|
|
613
|
+
const inRemoteChange = isFromSync;
|
|
603
614
|
const isApplyingPending = localState.isApplyingPending;
|
|
604
615
|
_queuedChanges.push({
|
|
605
616
|
value$,
|
|
606
|
-
syncState,
|
|
617
|
+
syncState: syncState2,
|
|
607
618
|
localState,
|
|
608
619
|
syncOptions,
|
|
609
620
|
changes,
|
|
@@ -616,13 +627,17 @@ function onObsChange(value$, syncState, localState, syncOptions, { changes, load
|
|
|
616
627
|
}
|
|
617
628
|
}
|
|
618
629
|
}
|
|
619
|
-
async function loadLocal(value$, syncOptions, syncState
|
|
630
|
+
async function loadLocal(value$, syncOptions, syncState$, localState) {
|
|
620
631
|
var _a, _b, _c;
|
|
621
632
|
const { persist } = syncOptions;
|
|
622
|
-
|
|
633
|
+
const node = getNode(value$);
|
|
634
|
+
const nodeValue = getNodeValue(getNode(node.state));
|
|
635
|
+
const syncStateValue = syncState$.peek();
|
|
636
|
+
const prevClearPersist = nodeValue.clearPersist;
|
|
637
|
+
if (persist == null ? void 0 : persist.name) {
|
|
623
638
|
const PersistPlugin = persist.plugin || ((_a = observableSyncConfiguration.persist) == null ? void 0 : _a.plugin);
|
|
624
639
|
const { table, config } = parseLocalConfig(persist);
|
|
625
|
-
|
|
640
|
+
syncStateValue.numPendingLocalLoads = (syncStateValue.numPendingLocalLoads || 0) + 1;
|
|
626
641
|
if (!PersistPlugin) {
|
|
627
642
|
throw new Error("Local persist is not configured");
|
|
628
643
|
}
|
|
@@ -656,7 +671,7 @@ async function loadLocal(value$, syncOptions, syncState, localState) {
|
|
|
656
671
|
if (metadata) {
|
|
657
672
|
metadatas.set(value$, metadata);
|
|
658
673
|
localState.pendingChanges = metadata.pending;
|
|
659
|
-
syncState
|
|
674
|
+
syncState$.assign({
|
|
660
675
|
lastSync: metadata.lastSync
|
|
661
676
|
});
|
|
662
677
|
}
|
|
@@ -674,12 +689,18 @@ async function loadLocal(value$, syncOptions, syncState, localState) {
|
|
|
674
689
|
}
|
|
675
690
|
internal.globalState.isLoadingLocal = false;
|
|
676
691
|
}
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
692
|
+
syncStateValue.numPendingLocalLoads--;
|
|
693
|
+
nodeValue.clearPersist = () => Promise.all(
|
|
694
|
+
[
|
|
695
|
+
prevClearPersist,
|
|
696
|
+
persistPlugin.deleteTable(table, config),
|
|
697
|
+
persistPlugin.deleteMetadata(table, config)
|
|
698
|
+
].filter(Boolean)
|
|
699
|
+
);
|
|
700
|
+
} else {
|
|
701
|
+
nodeValue.clearPersist = () => prevClearPersist == null ? void 0 : prevClearPersist();
|
|
681
702
|
}
|
|
682
|
-
syncState
|
|
703
|
+
syncState$.isPersistLoaded.set(!(syncStateValue.numPendingLocalLoads > 0));
|
|
683
704
|
}
|
|
684
705
|
function syncObservable(obs$, syncOptionsOrSynced) {
|
|
685
706
|
let syncOptions = syncOptionsOrSynced;
|
|
@@ -690,31 +711,59 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
690
711
|
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && (!obs$ || !node)) {
|
|
691
712
|
throw new Error("[legend-state] syncObservable called with undefined observable");
|
|
692
713
|
}
|
|
693
|
-
syncOptions =
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
714
|
+
syncOptions = deepMerge(
|
|
715
|
+
{
|
|
716
|
+
syncMode: "auto"
|
|
717
|
+
},
|
|
718
|
+
observableSyncConfiguration,
|
|
719
|
+
removeNullUndefined(syncOptions || {})
|
|
720
|
+
);
|
|
698
721
|
const localState = {};
|
|
699
722
|
let sync;
|
|
700
|
-
const syncState =
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
}
|
|
709
|
-
loadLocal(obs$, syncOptions, syncState
|
|
710
|
-
|
|
723
|
+
const syncState$ = syncState(obs$);
|
|
724
|
+
const syncStateValue = getNodeValue(getNode(syncState$));
|
|
725
|
+
allSyncStates.set(syncState$, node);
|
|
726
|
+
syncStateValue.getPendingChanges = () => localState.pendingChanges;
|
|
727
|
+
const onError = (error, getParams, source) => {
|
|
728
|
+
var _a;
|
|
729
|
+
syncState$.error.set(error);
|
|
730
|
+
(_a = syncOptions.onGetError) == null ? void 0 : _a.call(syncOptions, error, getParams, source);
|
|
731
|
+
};
|
|
732
|
+
loadLocal(obs$, syncOptions, syncState$, localState);
|
|
733
|
+
let isWaitingForLoad = !!syncOptions.get;
|
|
734
|
+
if (isWaitingForLoad) {
|
|
735
|
+
syncStateValue.numPendingRemoteLoads = (syncStateValue.numPendingRemoteLoads || 0) + 1;
|
|
736
|
+
}
|
|
737
|
+
syncState$.isLoaded.set(!syncState$.numPendingRemoteLoads.peek());
|
|
738
|
+
let isSynced = false;
|
|
739
|
+
const applyPending = (pending) => {
|
|
740
|
+
if (pending && !isEmpty(pending)) {
|
|
741
|
+
localState.isApplyingPending = true;
|
|
742
|
+
const keys = Object.keys(pending);
|
|
743
|
+
const changes = [];
|
|
744
|
+
for (let i = 0; i < keys.length; i++) {
|
|
745
|
+
const key = keys[i];
|
|
746
|
+
const path = key.split("/").filter((p2) => p2 !== "");
|
|
747
|
+
const { p, v, t } = pending[key];
|
|
748
|
+
changes.push({ path, valueAtPath: v, prevAtPath: p, pathTypes: t });
|
|
749
|
+
}
|
|
750
|
+
const value = getNodeValue(node);
|
|
751
|
+
onObsChange(obs$, syncState$, localState, syncOptions, {
|
|
752
|
+
value,
|
|
753
|
+
isFromPersist: false,
|
|
754
|
+
isFromSync: false,
|
|
755
|
+
getPrevious: createPreviousHandler(value, changes),
|
|
756
|
+
changes
|
|
757
|
+
});
|
|
758
|
+
localState.isApplyingPending = false;
|
|
759
|
+
}
|
|
760
|
+
};
|
|
711
761
|
if (syncOptions.get) {
|
|
712
|
-
let isSynced = false;
|
|
713
762
|
let isSubscribed = false;
|
|
714
763
|
let unsubscribe = void 0;
|
|
715
764
|
sync = async () => {
|
|
716
|
-
var _a
|
|
717
|
-
if (isSynced && shouldIgnoreUnobserved(node, sync)) {
|
|
765
|
+
var _a;
|
|
766
|
+
if (isSynced && (!getNodeValue(getNode(syncState$)).isSyncEnabled || shouldIgnoreUnobserved(node, sync))) {
|
|
718
767
|
if (unsubscribe) {
|
|
719
768
|
isSubscribed = false;
|
|
720
769
|
unsubscribe();
|
|
@@ -724,9 +773,10 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
724
773
|
}
|
|
725
774
|
const lastSync = (_a = metadatas.get(obs$)) == null ? void 0 : _a.lastSync;
|
|
726
775
|
const pending = localState.pendingChanges;
|
|
727
|
-
const get =
|
|
776
|
+
const get = syncOptions.get;
|
|
728
777
|
if (get) {
|
|
729
778
|
const runGet = () => {
|
|
779
|
+
var _a2;
|
|
730
780
|
const onChange = async ({ value, mode, lastSync: lastSync2 }) => {
|
|
731
781
|
mode = mode || syncOptions.mode || "set";
|
|
732
782
|
if (value !== void 0) {
|
|
@@ -739,9 +789,11 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
739
789
|
if (pending2) {
|
|
740
790
|
let didChangeMetadata = false;
|
|
741
791
|
Object.keys(pending2).forEach((key) => {
|
|
742
|
-
const p = key.split("/").filter((
|
|
792
|
+
const p = key.split("/").filter((k) => k !== "");
|
|
743
793
|
const { v, t } = pending2[key];
|
|
744
794
|
if (t.length === 0 || !value) {
|
|
795
|
+
const oldValue = clone(value);
|
|
796
|
+
pending2[key].p = oldValue;
|
|
745
797
|
if (isObject(value) && isObject(v)) {
|
|
746
798
|
Object.assign(value, v);
|
|
747
799
|
} else {
|
|
@@ -754,6 +806,8 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
754
806
|
delete pending2[key];
|
|
755
807
|
didChangeMetadata = true;
|
|
756
808
|
} else {
|
|
809
|
+
const oldValue = clone(value);
|
|
810
|
+
pending2[key].p = getValueAtPath(oldValue, p);
|
|
757
811
|
value = setAtPath(
|
|
758
812
|
value,
|
|
759
813
|
p,
|
|
@@ -773,18 +827,24 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
773
827
|
}
|
|
774
828
|
}
|
|
775
829
|
});
|
|
776
|
-
if (didChangeMetadata) {
|
|
777
|
-
updateMetadata(obs$, localState, syncState
|
|
830
|
+
if (didChangeMetadata && syncOptions.persist) {
|
|
831
|
+
updateMetadata(obs$, localState, syncState$, syncOptions, {
|
|
778
832
|
pending: pending2
|
|
779
833
|
});
|
|
780
834
|
}
|
|
781
835
|
}
|
|
782
836
|
onChangeRemote(() => {
|
|
783
|
-
if (mode === "assign"
|
|
837
|
+
if (mode === "assign") {
|
|
784
838
|
obs$.assign(value);
|
|
785
|
-
} else if (mode === "append"
|
|
839
|
+
} else if (mode === "append") {
|
|
840
|
+
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && !isArray(value)) {
|
|
841
|
+
console.error("[legend-state] mode:append expects the value to be an array");
|
|
842
|
+
}
|
|
786
843
|
obs$.push(...value);
|
|
787
|
-
} else if (mode === "prepend"
|
|
844
|
+
} else if (mode === "prepend") {
|
|
845
|
+
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && !isArray(value)) {
|
|
846
|
+
console.error("[legend-state] mode:prepend expects the value to be an array");
|
|
847
|
+
}
|
|
788
848
|
obs$.splice(0, 0, ...value);
|
|
789
849
|
} else if (mode === "merge") {
|
|
790
850
|
mergeIntoObservable(obs$, value);
|
|
@@ -794,77 +854,129 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
794
854
|
});
|
|
795
855
|
}
|
|
796
856
|
if (lastSync2 && syncOptions.persist) {
|
|
797
|
-
updateMetadata(obs$, localState, syncState
|
|
857
|
+
updateMetadata(obs$, localState, syncState$, syncOptions, {
|
|
798
858
|
lastSync: lastSync2
|
|
799
859
|
});
|
|
800
860
|
}
|
|
801
861
|
};
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
options: syncOptions,
|
|
806
|
-
lastSync,
|
|
807
|
-
dateModified: lastSync,
|
|
808
|
-
onError: (error) => {
|
|
809
|
-
var _a2;
|
|
810
|
-
(_a2 = syncOptions.onGetError) == null ? void 0 : _a2.call(syncOptions, error);
|
|
811
|
-
},
|
|
812
|
-
onGet: () => {
|
|
813
|
-
node.state.assign({
|
|
814
|
-
isLoaded: true,
|
|
815
|
-
error: void 0
|
|
816
|
-
});
|
|
817
|
-
},
|
|
818
|
-
onChange
|
|
819
|
-
});
|
|
862
|
+
if (node.activationState) {
|
|
863
|
+
node.activationState.onChange = onChange;
|
|
864
|
+
}
|
|
820
865
|
if (!isSubscribed && syncOptions.subscribe) {
|
|
821
866
|
isSubscribed = true;
|
|
822
867
|
unsubscribe = syncOptions.subscribe({
|
|
823
868
|
node,
|
|
824
869
|
value$: obs$,
|
|
870
|
+
lastSync,
|
|
825
871
|
update: (params) => {
|
|
826
|
-
when(
|
|
827
|
-
|
|
828
|
-
|
|
872
|
+
when(syncState$.isLoaded, () => {
|
|
873
|
+
when(waitFor || true, () => {
|
|
874
|
+
params.mode || (params.mode = syncOptions.mode || "merge");
|
|
875
|
+
onChange(params);
|
|
876
|
+
});
|
|
829
877
|
});
|
|
830
878
|
},
|
|
831
|
-
refresh: () => when(
|
|
879
|
+
refresh: () => when(syncState$.isLoaded, sync),
|
|
880
|
+
onError: (error) => onError(error, void 0, "subscribe")
|
|
832
881
|
});
|
|
833
882
|
}
|
|
883
|
+
const existingValue = getNodeValue(node);
|
|
884
|
+
const getParams = {
|
|
885
|
+
node,
|
|
886
|
+
value$: obs$,
|
|
887
|
+
value: isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked]) ? void 0 : existingValue,
|
|
888
|
+
mode: syncOptions.mode,
|
|
889
|
+
refresh: sync,
|
|
890
|
+
options: syncOptions,
|
|
891
|
+
lastSync,
|
|
892
|
+
updateLastSync: (lastSync2) => getParams.lastSync = lastSync2,
|
|
893
|
+
onError: (error) => onError(error, getParams, "get")
|
|
894
|
+
};
|
|
895
|
+
let modeBeforeReset = void 0;
|
|
896
|
+
(_a2 = syncOptions.onBeforeGet) == null ? void 0 : _a2.call(syncOptions, {
|
|
897
|
+
value: getParams.value,
|
|
898
|
+
lastSync,
|
|
899
|
+
pendingChanges: pending && !isEmpty(pending) ? pending : void 0,
|
|
900
|
+
clearPendingChanges: async () => {
|
|
901
|
+
localState.pendingChanges = {};
|
|
902
|
+
await updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
|
|
903
|
+
pending: localState.pendingChanges
|
|
904
|
+
});
|
|
905
|
+
},
|
|
906
|
+
resetCache: () => {
|
|
907
|
+
var _a3;
|
|
908
|
+
modeBeforeReset = getParams.mode;
|
|
909
|
+
getParams.mode = "set";
|
|
910
|
+
return (_a3 = syncStateValue.clearPersist) == null ? void 0 : _a3.call(syncStateValue);
|
|
911
|
+
}
|
|
912
|
+
});
|
|
913
|
+
syncState$.assign({
|
|
914
|
+
numPendingGets: (syncStateValue.numPendingGets || 0) + 1,
|
|
915
|
+
isGetting: true
|
|
916
|
+
});
|
|
917
|
+
const got = runWithRetry({ retryNum: 0, retry: syncOptions.retry }, (retryEvent) => {
|
|
918
|
+
const params = getParams;
|
|
919
|
+
params.cancelRetry = retryEvent.cancelRetry;
|
|
920
|
+
params.retryNum = retryEvent.retryNum;
|
|
921
|
+
return get(params);
|
|
922
|
+
});
|
|
923
|
+
const numGets = node.numGets = (node.numGets || 0) + 1;
|
|
924
|
+
const handle = (value) => {
|
|
925
|
+
syncState$.numPendingGets.set((v) => v - 1);
|
|
926
|
+
if (isWaitingForLoad) {
|
|
927
|
+
isWaitingForLoad = false;
|
|
928
|
+
syncStateValue.numPendingRemoteLoads--;
|
|
929
|
+
}
|
|
930
|
+
if (numGets >= (node.getNumResolved || 0)) {
|
|
931
|
+
node.getNumResolved = node.numGets;
|
|
932
|
+
onChange({
|
|
933
|
+
value,
|
|
934
|
+
lastSync: getParams.lastSync,
|
|
935
|
+
mode: getParams.mode
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
if (modeBeforeReset) {
|
|
939
|
+
getParams.mode = modeBeforeReset;
|
|
940
|
+
modeBeforeReset = void 0;
|
|
941
|
+
}
|
|
942
|
+
syncState$.assign({
|
|
943
|
+
isLoaded: syncStateValue.numPendingRemoteLoads < 1,
|
|
944
|
+
error: void 0,
|
|
945
|
+
isGetting: syncStateValue.numPendingGets > 0
|
|
946
|
+
});
|
|
947
|
+
};
|
|
948
|
+
if (isPromise(got)) {
|
|
949
|
+
got.then(handle);
|
|
950
|
+
} else {
|
|
951
|
+
handle(got);
|
|
952
|
+
}
|
|
834
953
|
};
|
|
835
|
-
|
|
954
|
+
const { waitFor } = syncOptions;
|
|
955
|
+
if (waitFor) {
|
|
956
|
+
if (node.activationState) {
|
|
957
|
+
node.activationState.waitFor = void 0;
|
|
958
|
+
}
|
|
959
|
+
whenReady(waitFor, () => trackSelector(runGet, sync));
|
|
960
|
+
} else {
|
|
961
|
+
trackSelector(runGet, sync);
|
|
962
|
+
}
|
|
836
963
|
} else {
|
|
837
|
-
|
|
964
|
+
syncState$.assign({
|
|
838
965
|
isLoaded: true,
|
|
839
966
|
error: void 0
|
|
840
967
|
});
|
|
841
968
|
}
|
|
842
969
|
if (!isSynced) {
|
|
843
970
|
isSynced = true;
|
|
844
|
-
await when(
|
|
845
|
-
|
|
846
|
-
localState.isApplyingPending = true;
|
|
847
|
-
const keys = Object.keys(pending);
|
|
848
|
-
const changes = [];
|
|
849
|
-
for (let i = 0; i < keys.length; i++) {
|
|
850
|
-
const key = keys[i];
|
|
851
|
-
const path = key.split("/").filter((p2) => p2 !== "");
|
|
852
|
-
const { p, v, t } = pending[key];
|
|
853
|
-
changes.push({ path, valueAtPath: v, prevAtPath: p, pathTypes: t });
|
|
854
|
-
}
|
|
855
|
-
const value = getNodeValue(node);
|
|
856
|
-
onObsChange(obs$, syncState, localState, syncOptions, {
|
|
857
|
-
value,
|
|
858
|
-
loading: false,
|
|
859
|
-
remote: false,
|
|
860
|
-
getPrevious: createPreviousHandler(value, changes),
|
|
861
|
-
changes
|
|
862
|
-
});
|
|
863
|
-
localState.isApplyingPending = false;
|
|
864
|
-
}
|
|
971
|
+
await when(syncState$.isLoaded);
|
|
972
|
+
applyPending(pending);
|
|
865
973
|
}
|
|
866
974
|
};
|
|
867
|
-
|
|
975
|
+
syncStateValue.sync = sync;
|
|
976
|
+
} else {
|
|
977
|
+
if (!isSynced) {
|
|
978
|
+
applyPending(localState.pendingChanges);
|
|
979
|
+
}
|
|
868
980
|
}
|
|
869
981
|
const onAllPersistLoaded = () => {
|
|
870
982
|
var _a, _b;
|
|
@@ -883,77 +995,27 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
883
995
|
}
|
|
884
996
|
if ((syncOptions == null ? void 0 : syncOptions.set) || (syncOptions == null ? void 0 : syncOptions.persist)) {
|
|
885
997
|
obs$.onChange(
|
|
886
|
-
onObsChange.bind(this, obs$, syncState
|
|
998
|
+
onObsChange.bind(this, obs$, syncState$, localState, syncOptions)
|
|
887
999
|
);
|
|
888
1000
|
}
|
|
889
1001
|
});
|
|
890
|
-
return syncState
|
|
1002
|
+
return syncState$;
|
|
891
1003
|
}
|
|
892
|
-
var { getProxy, globalState: globalState2,
|
|
1004
|
+
var { getProxy, globalState: globalState2, setNodeValue, getNodeValue: getNodeValue2 } = internal;
|
|
893
1005
|
function enableActivateSyncedNode() {
|
|
894
1006
|
globalState2.activateSyncedNode = function activateSyncedNode(node, newValue) {
|
|
895
1007
|
const obs$ = getProxy(node);
|
|
896
1008
|
if (node.activationState) {
|
|
897
|
-
const {
|
|
898
|
-
|
|
899
|
-
|
|
1009
|
+
const {
|
|
1010
|
+
get: getOrig,
|
|
1011
|
+
initial,
|
|
1012
|
+
set,
|
|
1013
|
+
onChange
|
|
1014
|
+
} = node.activationState;
|
|
900
1015
|
let promiseReturn = void 0;
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
pluginRemote.get = (params) => {
|
|
905
|
-
var _a;
|
|
906
|
-
onChange = params.onChange;
|
|
907
|
-
const updateLastSync = (lastSync) => params.lastSync = lastSync;
|
|
908
|
-
const existingValue = getNodeValue2(node);
|
|
909
|
-
const value = runWithRetry(node, { attemptNum: 0, retry: retry || ((_a = params.options) == null ? void 0 : _a.retry) }, () => {
|
|
910
|
-
const paramsToGet = {
|
|
911
|
-
value: isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked2]) ? void 0 : existingValue,
|
|
912
|
-
lastSync: params.lastSync,
|
|
913
|
-
updateLastSync,
|
|
914
|
-
mode: params.mode,
|
|
915
|
-
refresh
|
|
916
|
-
};
|
|
917
|
-
const ret = get(paramsToGet);
|
|
918
|
-
params.mode = paramsToGet.mode;
|
|
919
|
-
return ret;
|
|
920
|
-
});
|
|
921
|
-
promiseReturn = value;
|
|
922
|
-
return value;
|
|
923
|
-
};
|
|
924
|
-
}
|
|
925
|
-
if (set) {
|
|
926
|
-
pluginRemote.set = async (params) => {
|
|
927
|
-
var _a, _b;
|
|
928
|
-
if ((_a = node.state) == null ? void 0 : _a.isLoaded.get()) {
|
|
929
|
-
const retryAttempts = { attemptNum: 0, retry: retry || ((_b = params.options) == null ? void 0 : _b.retry) };
|
|
930
|
-
return runWithRetry(node, retryAttempts, async (retryEvent) => {
|
|
931
|
-
let changes = {};
|
|
932
|
-
let maxModified = 0;
|
|
933
|
-
if (!node.state.isLoaded.peek()) {
|
|
934
|
-
await whenReady(node.state.isLoaded);
|
|
935
|
-
}
|
|
936
|
-
const cancelRetry = () => {
|
|
937
|
-
retryEvent.cancel = true;
|
|
938
|
-
};
|
|
939
|
-
await set({
|
|
940
|
-
...params,
|
|
941
|
-
node,
|
|
942
|
-
update: (params2) => {
|
|
943
|
-
const { value, lastSync } = params2;
|
|
944
|
-
maxModified = Math.max(lastSync || 0, maxModified);
|
|
945
|
-
changes = mergeIntoObservable(changes, value);
|
|
946
|
-
},
|
|
947
|
-
retryNum: retryAttempts.attemptNum,
|
|
948
|
-
cancelRetry,
|
|
949
|
-
refresh,
|
|
950
|
-
fromSubscribe: false
|
|
951
|
-
});
|
|
952
|
-
return { changes, lastSync: maxModified || void 0 };
|
|
953
|
-
});
|
|
954
|
-
}
|
|
955
|
-
};
|
|
956
|
-
}
|
|
1016
|
+
const get = getOrig ? (params) => {
|
|
1017
|
+
return promiseReturn = getOrig(params);
|
|
1018
|
+
} : void 0;
|
|
957
1019
|
const nodeVal = getNodeValue2(node);
|
|
958
1020
|
if (promiseReturn !== void 0) {
|
|
959
1021
|
newValue = promiseReturn;
|
|
@@ -963,7 +1025,7 @@ function enableActivateSyncedNode() {
|
|
|
963
1025
|
newValue = initial;
|
|
964
1026
|
}
|
|
965
1027
|
setNodeValue(node, promiseReturn ? void 0 : newValue);
|
|
966
|
-
|
|
1028
|
+
syncObservable(obs$, { ...node.activationState, get, set });
|
|
967
1029
|
return { update: onChange, value: newValue };
|
|
968
1030
|
} else {
|
|
969
1031
|
let update = void 0;
|
|
@@ -1002,11 +1064,8 @@ function installPersistActivateNode() {
|
|
|
1002
1064
|
}
|
|
1003
1065
|
|
|
1004
1066
|
// sync.ts
|
|
1005
|
-
function isInRemoteChange() {
|
|
1006
|
-
return internal.globalState.isLoadingRemote;
|
|
1007
|
-
}
|
|
1008
1067
|
var internal3 = {
|
|
1009
1068
|
observableSyncConfiguration
|
|
1010
1069
|
};
|
|
1011
1070
|
|
|
1012
|
-
export { combineTransforms, configureObservableSync, deepEqual, diffObjects, internal3 as internal,
|
|
1071
|
+
export { combineTransforms, configureObservableSync, deepEqual, diffObjects, internal3 as internal, mapSyncPlugins, onChangeRemote, removeNullUndefined, syncObservable, synced, transformStringifyDates, transformStringifyKeys };
|