@legendapp/state 2.2.0-next.4 → 2.2.0-next.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/babel.js.map +1 -1
- package/config/enableDirectAccess.d.ts +1 -1
- package/config/enableDirectPeek.d.ts +1 -1
- package/config/enableReactDirectRender.js.map +1 -1
- package/config/enableReactDirectRender.mjs.map +1 -1
- package/config/enableReactTracking.d.ts +4 -3
- package/config/enableReactTracking.js.map +1 -1
- package/config/enableReactTracking.mjs.map +1 -1
- package/config/enableReactUse.d.ts +1 -1
- package/helpers/fetch.d.ts +4 -3
- package/helpers/fetch.js.map +1 -1
- package/helpers/fetch.mjs.map +1 -1
- package/helpers/pageHash.js.map +1 -1
- package/helpers/pageHash.mjs.map +1 -1
- package/helpers/pageHashParams.js.map +1 -1
- package/helpers/pageHashParams.mjs.map +1 -1
- package/helpers/time.d.ts +2 -2
- package/helpers/time.js.map +1 -1
- package/helpers/time.mjs.map +1 -1
- package/history.js.map +1 -1
- package/history.mjs.map +1 -1
- package/index.d.ts +13 -4
- package/index.js +655 -448
- package/index.js.map +1 -1
- package/index.mjs +652 -447
- package/index.mjs.map +1 -1
- package/package.json +1 -12
- package/persist-plugins/async-storage.js.map +1 -1
- package/persist-plugins/async-storage.mjs.map +1 -1
- package/persist-plugins/fetch.js.map +1 -1
- package/persist-plugins/fetch.mjs.map +1 -1
- package/persist-plugins/firebase.js.map +1 -1
- package/persist-plugins/firebase.mjs.map +1 -1
- package/persist-plugins/indexeddb.js.map +1 -1
- package/persist-plugins/indexeddb.mjs.map +1 -1
- package/persist-plugins/local-storage.js +10 -2
- package/persist-plugins/local-storage.js.map +1 -1
- package/persist-plugins/local-storage.mjs +10 -2
- package/persist-plugins/local-storage.mjs.map +1 -1
- package/persist-plugins/mmkv.js.map +1 -1
- package/persist-plugins/mmkv.mjs.map +1 -1
- package/persist-plugins/query.js.map +1 -1
- package/persist-plugins/query.mjs.map +1 -1
- package/persist.d.ts +15 -1
- package/persist.js +412 -180
- package/persist.js.map +1 -1
- package/persist.mjs +413 -181
- package/persist.mjs.map +1 -1
- package/react-hooks/createObservableHook.js +1 -1
- package/react-hooks/createObservableHook.js.map +1 -1
- package/react-hooks/createObservableHook.mjs +1 -1
- package/react-hooks/createObservableHook.mjs.map +1 -1
- package/react-hooks/useFetch.d.ts +4 -3
- package/react-hooks/useFetch.js.map +1 -1
- package/react-hooks/useFetch.mjs.map +1 -1
- package/react-hooks/useHover.js.map +1 -1
- package/react-hooks/useHover.mjs.map +1 -1
- package/react-hooks/useMeasure.js.map +1 -1
- package/react-hooks/useMeasure.mjs.map +1 -1
- package/react-hooks/useObservableNextRouter.js.map +1 -1
- package/react-hooks/useObservableNextRouter.mjs.map +1 -1
- package/react-hooks/useObservableQuery.js.map +1 -1
- package/react-hooks/useObservableQuery.mjs.map +1 -1
- package/react-hooks/usePersistedObservable.d.ts +2 -2
- package/react-hooks/usePersistedObservable.js +4 -3
- package/react-hooks/usePersistedObservable.js.map +1 -1
- package/react-hooks/usePersistedObservable.mjs +4 -3
- package/react-hooks/usePersistedObservable.mjs.map +1 -1
- package/react.js +13 -8
- package/react.js.map +1 -1
- package/react.mjs +14 -9
- package/react.mjs.map +1 -1
- package/src/ObservableObject.d.ts +6 -4
- package/src/ObservablePrimitive.d.ts +2 -1
- package/src/activated.d.ts +3 -0
- package/src/batching.d.ts +3 -1
- package/src/computed.d.ts +3 -3
- package/src/config/enableDirectAccess.d.ts +1 -1
- package/src/config/enableDirectPeek.d.ts +1 -1
- package/src/config/enableReactTracking.d.ts +4 -3
- package/src/config/enableReactUse.d.ts +1 -1
- package/src/createObservable.d.ts +2 -2
- package/src/globals.d.ts +10 -8
- package/src/helpers/fetch.d.ts +4 -3
- package/src/helpers/time.d.ts +2 -2
- package/src/helpers.d.ts +3 -3
- package/src/history/trackHistory.d.ts +1 -1
- package/src/is.d.ts +2 -0
- package/src/observable.d.ts +7 -15
- package/src/observableInterfaces.d.ts +56 -348
- package/src/observableTypes.d.ts +85 -0
- package/src/persist/observablePersistRemoteFunctionsAdapter.d.ts +1 -1
- package/src/persist/persistActivateNode.d.ts +0 -17
- package/src/persist/persistHelpers.d.ts +1 -1
- package/src/persist/persistObservable.d.ts +2 -3
- package/src/persistTypes.d.ts +196 -0
- package/src/proxy.d.ts +5 -5
- package/src/react/Computed.d.ts +1 -1
- package/src/react/Switch.d.ts +3 -3
- package/src/react/reactInterfaces.d.ts +2 -1
- package/src/react/useComputed.d.ts +5 -5
- package/src/react/usePauseProvider.d.ts +3 -3
- package/src/react/useWhen.d.ts +2 -2
- package/src/react-hooks/useFetch.d.ts +4 -3
- package/src/react-hooks/usePersistedObservable.d.ts +2 -2
- package/src/retry.d.ts +6 -0
- package/src/trackSelector.d.ts +3 -2
- package/src/when.d.ts +6 -2
- package/trace.js.map +1 -1
- package/trace.mjs.map +1 -1
package/persist.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { symbolDelete, isString, isArray, isObject, constructObjectWithPath, deconstructObjectWithPath,
|
|
1
|
+
import { symbolDelete, isString, isArray, isObject, constructObjectWithPath, deconstructObjectWithPath, isPromise, getNode, observable, when, internal as internal$1, batch, mergeIntoObservable, isEmpty, isFunction, setAtPath, endBatch, setInObservableAtPath, getNodeValue, whenReady } from '@legendapp/state';
|
|
2
2
|
|
|
3
3
|
const observablePersistConfiguration = {};
|
|
4
4
|
function configureObservablePersistence(options) {
|
|
@@ -137,9 +137,21 @@ function observablePersistRemoteFunctionsAdapter({ get, set, }) {
|
|
|
137
137
|
const ret = {};
|
|
138
138
|
if (get) {
|
|
139
139
|
ret.get = (async (params) => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
140
|
+
try {
|
|
141
|
+
let value = get(params);
|
|
142
|
+
if (isPromise(value)) {
|
|
143
|
+
value = await value;
|
|
144
|
+
}
|
|
145
|
+
params.onChange({
|
|
146
|
+
value,
|
|
147
|
+
dateModified: params.dateModified,
|
|
148
|
+
lastSync: params.lastSync,
|
|
149
|
+
mode: params.mode,
|
|
150
|
+
});
|
|
151
|
+
params.onGet();
|
|
152
|
+
// eslint-disable-next-line no-empty
|
|
153
|
+
}
|
|
154
|
+
catch (_a) { }
|
|
143
155
|
});
|
|
144
156
|
}
|
|
145
157
|
if (set) {
|
|
@@ -148,6 +160,21 @@ function observablePersistRemoteFunctionsAdapter({ get, set, }) {
|
|
|
148
160
|
return ret;
|
|
149
161
|
}
|
|
150
162
|
|
|
163
|
+
function removeNullUndefined(val) {
|
|
164
|
+
if (val) {
|
|
165
|
+
Object.keys(val).forEach((key) => {
|
|
166
|
+
const v = val[key];
|
|
167
|
+
if (v === null || v === undefined) {
|
|
168
|
+
delete val[key];
|
|
169
|
+
}
|
|
170
|
+
else if (isObject(v)) {
|
|
171
|
+
removeNullUndefined(v);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
return val;
|
|
176
|
+
}
|
|
177
|
+
|
|
151
178
|
const { globalState: globalState$1 } = internal$1;
|
|
152
179
|
const mapPersistences = new WeakMap();
|
|
153
180
|
const metadatas = new WeakMap();
|
|
@@ -164,6 +191,7 @@ function doInOrder(arg1, arg2) {
|
|
|
164
191
|
}
|
|
165
192
|
function onChangeRemote(cb) {
|
|
166
193
|
when(() => !globalState$1.isLoadingRemote$.get(), () => {
|
|
194
|
+
endBatch(true);
|
|
167
195
|
// Remote changes should only update local state
|
|
168
196
|
globalState$1.isLoadingRemote$.set(true);
|
|
169
197
|
batch(cb, () => {
|
|
@@ -214,16 +242,19 @@ async function updateMetadataImmediate(obs, localState, syncState, persistOption
|
|
|
214
242
|
const { table, config } = parseLocalConfig(local);
|
|
215
243
|
// Save metadata
|
|
216
244
|
const oldMetadata = metadatas.get(obs);
|
|
217
|
-
const {
|
|
218
|
-
const needsUpdate = pending || (
|
|
245
|
+
const { lastSync, pending } = newMetadata;
|
|
246
|
+
const needsUpdate = pending || (lastSync && (!oldMetadata || lastSync !== oldMetadata.lastSync));
|
|
219
247
|
if (needsUpdate) {
|
|
220
248
|
const metadata = Object.assign({}, oldMetadata, newMetadata);
|
|
221
249
|
metadatas.set(obs, metadata);
|
|
222
250
|
if (persistenceLocal) {
|
|
223
251
|
await persistenceLocal.setMetadata(table, metadata, config);
|
|
224
252
|
}
|
|
225
|
-
if (
|
|
226
|
-
syncState.
|
|
253
|
+
if (lastSync) {
|
|
254
|
+
syncState.assign({
|
|
255
|
+
lastSync: lastSync,
|
|
256
|
+
dateModified: lastSync,
|
|
257
|
+
});
|
|
227
258
|
}
|
|
228
259
|
}
|
|
229
260
|
}
|
|
@@ -235,15 +266,54 @@ function updateMetadata(obs, localState, syncState, persistOptions, newMetadata)
|
|
|
235
266
|
localState.timeoutSaveMetadata = setTimeout(() => updateMetadataImmediate(obs, localState, syncState, persistOptions, newMetadata), ((_a = persistOptions === null || persistOptions === void 0 ? void 0 : persistOptions.remote) === null || _a === void 0 ? void 0 : _a.metadataTimeout) || 0);
|
|
236
267
|
}
|
|
237
268
|
let _queuedChanges = [];
|
|
269
|
+
let _queuedRemoteChanges = [];
|
|
270
|
+
let timeoutSaveRemote = undefined;
|
|
271
|
+
function mergeChanges(changes) {
|
|
272
|
+
const changesByPath = new Map();
|
|
273
|
+
const changesOut = [];
|
|
274
|
+
// TODO: This could be even more robust by going deeper into paths like the firebase plugin's _updatePendingSave
|
|
275
|
+
for (let i = 0; i < changes.length; i++) {
|
|
276
|
+
const change = changes[i];
|
|
277
|
+
const pathStr = change.path.join('/');
|
|
278
|
+
const existing = changesByPath.get(pathStr);
|
|
279
|
+
if (existing) {
|
|
280
|
+
existing.valueAtPath = change.valueAtPath;
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
changesByPath.set(pathStr, change);
|
|
284
|
+
changesOut.push(change);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return changesOut;
|
|
288
|
+
}
|
|
289
|
+
function mergeQueuedChanges(allChanges) {
|
|
290
|
+
const changesByObsRemote = new Map();
|
|
291
|
+
const changesByObsLocal = new Map();
|
|
292
|
+
const outRemote = new Map();
|
|
293
|
+
const outLocal = new Map();
|
|
294
|
+
for (let i = 0; i < allChanges.length; i++) {
|
|
295
|
+
const value = allChanges[i];
|
|
296
|
+
const { obs, changes, inRemoteChange } = value;
|
|
297
|
+
const changesMap = inRemoteChange ? changesByObsRemote : changesByObsLocal;
|
|
298
|
+
const existing = changesMap.get(obs);
|
|
299
|
+
const newChanges = existing ? [...existing, ...changes] : changes;
|
|
300
|
+
const merged = mergeChanges(newChanges);
|
|
301
|
+
changesMap.set(obs, merged);
|
|
302
|
+
value.changes = merged;
|
|
303
|
+
(inRemoteChange ? outRemote : outLocal).set(obs, value);
|
|
304
|
+
}
|
|
305
|
+
return Array.from(outRemote.values()).concat(Array.from(outLocal.values()));
|
|
306
|
+
}
|
|
238
307
|
async function processQueuedChanges() {
|
|
308
|
+
var _a;
|
|
239
309
|
// Get a local copy of the queued changes and clear the global queue
|
|
240
|
-
const queuedChanges = _queuedChanges;
|
|
310
|
+
const queuedChanges = mergeQueuedChanges(_queuedChanges);
|
|
241
311
|
_queuedChanges = [];
|
|
312
|
+
_queuedRemoteChanges.push(...queuedChanges.filter((c) => !c.inRemoteChange));
|
|
242
313
|
// Note: Summary of the order of operations these functions:
|
|
243
314
|
// 1. Prepare all changes for saving. This may involve waiting for promises if the user has asynchronous transform.
|
|
244
315
|
// We need to prepare all of the changes in the queue before saving so that the saves happen in the correct order,
|
|
245
316
|
// since some may take longer to transformSaveData than others.
|
|
246
|
-
const changes = await Promise.all(queuedChanges.map(prepChange));
|
|
247
317
|
// 2. Save pending to the metadata table first. If this is the only operation that succeeds, it would try to save
|
|
248
318
|
// the current value again on next load, which isn't too bad.
|
|
249
319
|
// 3. Save local changes to storage. If they never make it to remote, then on the next load they will be pending
|
|
@@ -251,25 +321,46 @@ async function processQueuedChanges() {
|
|
|
251
321
|
// 4. Wait for remote load or error if allowed
|
|
252
322
|
// 5. Save to remote
|
|
253
323
|
// 6. On successful save, merge changes (if any) back into observable
|
|
254
|
-
// 7. Lastly, update metadata to clear pending and update
|
|
324
|
+
// 7. Lastly, update metadata to clear pending and update lastSync. Doing this earlier could potentially cause
|
|
255
325
|
// sync inconsistences so it's very important that this is last.
|
|
256
|
-
|
|
326
|
+
const preppedChangesLocal = await Promise.all(queuedChanges.map(prepChangeLocal));
|
|
327
|
+
// TODO Clean this up: We only need to prep this now in ordre to save pending changes, don't need any of the other stuff. Should split that up?
|
|
328
|
+
await Promise.all(queuedChanges.map(prepChangeRemote));
|
|
329
|
+
await Promise.all(preppedChangesLocal.map(doChangeLocal));
|
|
330
|
+
const timeout = (_a = observablePersistConfiguration === null || observablePersistConfiguration === void 0 ? void 0 : observablePersistConfiguration.remoteOptions) === null || _a === void 0 ? void 0 : _a.saveTimeout;
|
|
331
|
+
if (timeout) {
|
|
332
|
+
if (timeoutSaveRemote) {
|
|
333
|
+
clearTimeout(timeoutSaveRemote);
|
|
334
|
+
}
|
|
335
|
+
timeoutSaveRemote = setTimeout(processQueuedRemoteChanges, timeout);
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
processQueuedRemoteChanges();
|
|
339
|
+
}
|
|
257
340
|
}
|
|
258
|
-
async function
|
|
341
|
+
async function processQueuedRemoteChanges() {
|
|
342
|
+
const queuedRemoteChanges = mergeQueuedChanges(_queuedRemoteChanges);
|
|
343
|
+
_queuedRemoteChanges = [];
|
|
344
|
+
const preppedChangesRemote = await Promise.all(queuedRemoteChanges.map(prepChangeRemote));
|
|
345
|
+
preppedChangesRemote.forEach(doChangeRemote);
|
|
346
|
+
}
|
|
347
|
+
async function prepChangeLocal(queuedChange) {
|
|
259
348
|
const { syncState, changes, localState, persistOptions, inRemoteChange, isApplyingPending } = queuedChange;
|
|
260
349
|
const local = persistOptions.local;
|
|
261
350
|
const { persistenceRemote } = localState;
|
|
262
351
|
const { config: configLocal } = parseLocalConfig(local);
|
|
263
352
|
const configRemote = persistOptions.remote;
|
|
264
353
|
const saveLocal = local && !configLocal.readonly && !isApplyingPending && syncState.isEnabledLocal.peek();
|
|
265
|
-
const saveRemote = !inRemoteChange &&
|
|
354
|
+
const saveRemote = !!(!inRemoteChange &&
|
|
355
|
+
(persistenceRemote === null || persistenceRemote === void 0 ? void 0 : persistenceRemote.set) &&
|
|
356
|
+
!(configRemote === null || configRemote === void 0 ? void 0 : configRemote.readonly) &&
|
|
357
|
+
syncState.isEnabledRemote.peek());
|
|
266
358
|
if (saveLocal || saveRemote) {
|
|
267
359
|
if (saveLocal && !syncState.isLoadedLocal.peek()) {
|
|
268
360
|
console.error('[legend-state] WARNING: An observable was changed before being loaded from persistence', local);
|
|
269
|
-
return;
|
|
361
|
+
return undefined;
|
|
270
362
|
}
|
|
271
363
|
const changesLocal = [];
|
|
272
|
-
const changesRemote = [];
|
|
273
364
|
const changesPaths = new Set();
|
|
274
365
|
let promisesTransform = [];
|
|
275
366
|
// Reverse order
|
|
@@ -308,6 +399,52 @@ async function prepChange(queuedChange) {
|
|
|
308
399
|
}
|
|
309
400
|
}));
|
|
310
401
|
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
// If there's any transform promises, wait for them before saving
|
|
405
|
+
promisesTransform = promisesTransform.filter(Boolean);
|
|
406
|
+
if (promisesTransform.length > 0) {
|
|
407
|
+
await Promise.all(promisesTransform);
|
|
408
|
+
}
|
|
409
|
+
return { queuedChange, changesLocal, saveRemote };
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
async function prepChangeRemote(queuedChange) {
|
|
413
|
+
const { syncState, changes, localState, persistOptions, inRemoteChange, isApplyingPending } = queuedChange;
|
|
414
|
+
const local = persistOptions.local;
|
|
415
|
+
const { persistenceRemote } = localState;
|
|
416
|
+
const { config: configLocal } = parseLocalConfig(local);
|
|
417
|
+
const configRemote = persistOptions.remote;
|
|
418
|
+
const saveLocal = local && !configLocal.readonly && !isApplyingPending && syncState.isEnabledLocal.peek();
|
|
419
|
+
const saveRemote = !inRemoteChange && (persistenceRemote === null || persistenceRemote === void 0 ? void 0 : persistenceRemote.set) && !(configRemote === null || configRemote === void 0 ? void 0 : configRemote.readonly) && syncState.isEnabledRemote.peek();
|
|
420
|
+
if (saveLocal || saveRemote) {
|
|
421
|
+
if (saveLocal && !syncState.isLoadedLocal.peek()) {
|
|
422
|
+
console.error('[legend-state] WARNING: An observable was changed before being loaded from persistence', local);
|
|
423
|
+
return undefined;
|
|
424
|
+
}
|
|
425
|
+
const changesRemote = [];
|
|
426
|
+
const changesPaths = new Set();
|
|
427
|
+
let promisesTransform = [];
|
|
428
|
+
// Reverse order
|
|
429
|
+
for (let i = changes.length - 1; i >= 0; i--) {
|
|
430
|
+
const { path } = changes[i];
|
|
431
|
+
let found = false;
|
|
432
|
+
// Optimization to only save the latest update at each path. We might have multiple changes at the same path
|
|
433
|
+
// and we only need the latest value, so it starts from the end of the array, skipping any earlier changes
|
|
434
|
+
// already processed. If a later change modifies a parent of an earlier change (which happens on delete()
|
|
435
|
+
// it should be ignored as it's superseded by the parent modification.
|
|
436
|
+
if (changesPaths.size > 0) {
|
|
437
|
+
for (let u = 0; u < path.length; u++) {
|
|
438
|
+
if (changesPaths.has((u === path.length - 1 ? path : path.slice(0, u + 1)).join('/'))) {
|
|
439
|
+
found = true;
|
|
440
|
+
break;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
if (!found) {
|
|
445
|
+
const pathStr = path.join('/');
|
|
446
|
+
changesPaths.add(pathStr);
|
|
447
|
+
const { prevAtPath, valueAtPath, pathTypes } = changes[i];
|
|
311
448
|
if (saveRemote) {
|
|
312
449
|
const promiseTransformRemote = transformOutData(valueAtPath, path, pathTypes, configRemote || {});
|
|
313
450
|
promisesTransform.push(doInOrder(promiseTransformRemote, ({ path: pathTransformed, value: valueTransformed }) => {
|
|
@@ -365,21 +502,20 @@ async function prepChange(queuedChange) {
|
|
|
365
502
|
if (promisesTransform.length > 0) {
|
|
366
503
|
await Promise.all(promisesTransform);
|
|
367
504
|
}
|
|
368
|
-
return { queuedChange,
|
|
505
|
+
return { queuedChange, changesRemote };
|
|
369
506
|
}
|
|
370
507
|
}
|
|
371
|
-
async function
|
|
372
|
-
var _a, _b, _c, _d;
|
|
508
|
+
async function doChangeLocal(changeInfo) {
|
|
373
509
|
if (!changeInfo)
|
|
374
510
|
return;
|
|
375
|
-
const { queuedChange, changesLocal,
|
|
511
|
+
const { queuedChange, changesLocal, saveRemote } = changeInfo;
|
|
376
512
|
const { obs, syncState, localState, persistOptions } = queuedChange;
|
|
377
|
-
const { persistenceLocal
|
|
513
|
+
const { persistenceLocal } = localState;
|
|
378
514
|
const local = persistOptions.local;
|
|
379
515
|
const { table, config: configLocal } = parseLocalConfig(local);
|
|
380
516
|
const configRemote = persistOptions.remote;
|
|
381
517
|
const shouldSaveMetadata = local && (configRemote === null || configRemote === void 0 ? void 0 : configRemote.offlineBehavior) === 'retry';
|
|
382
|
-
if (
|
|
518
|
+
if (saveRemote && shouldSaveMetadata) {
|
|
383
519
|
// First save pending changes before saving local or remote
|
|
384
520
|
await updateMetadataImmediate(obs, localState, syncState, persistOptions, {
|
|
385
521
|
pending: localState.pendingChanges,
|
|
@@ -399,29 +535,46 @@ async function doChange(changeInfo) {
|
|
|
399
535
|
await promiseSet;
|
|
400
536
|
}
|
|
401
537
|
}
|
|
538
|
+
}
|
|
539
|
+
async function doChangeRemote(changeInfo) {
|
|
540
|
+
var _a, _b;
|
|
541
|
+
if (!changeInfo)
|
|
542
|
+
return;
|
|
543
|
+
const { queuedChange, changesRemote } = changeInfo;
|
|
544
|
+
const { obs, syncState, localState, persistOptions } = queuedChange;
|
|
545
|
+
const { persistenceLocal, persistenceRemote } = localState;
|
|
546
|
+
const local = persistOptions.local;
|
|
547
|
+
const { table, config: configLocal } = parseLocalConfig(local);
|
|
548
|
+
const { offlineBehavior, allowSetIfError, onBeforeSet, onSetError, waitForSet, onSet } = persistOptions.remote || {};
|
|
549
|
+
const shouldSaveMetadata = local && offlineBehavior === 'retry';
|
|
402
550
|
if (changesRemote.length > 0) {
|
|
403
551
|
// Wait for remote to be ready before saving
|
|
404
|
-
await when(() => syncState.isLoaded.get() || (
|
|
552
|
+
await when(() => syncState.isLoaded.get() || (allowSetIfError && syncState.error.get()));
|
|
553
|
+
if (waitForSet) {
|
|
554
|
+
await when(isFunction(waitForSet) ? waitForSet(changesRemote) : waitForSet);
|
|
555
|
+
}
|
|
405
556
|
const value = obs.peek();
|
|
406
|
-
|
|
407
|
-
|
|
557
|
+
onBeforeSet === null || onBeforeSet === void 0 ? void 0 : onBeforeSet();
|
|
558
|
+
localState.numSavesOutstanding = (localState.numSavesOutstanding || 0) + 1;
|
|
559
|
+
const saved = await ((_a = persistenceRemote.set({
|
|
408
560
|
obs,
|
|
409
561
|
syncState: syncState,
|
|
410
562
|
options: persistOptions,
|
|
411
563
|
changes: changesRemote,
|
|
412
564
|
value,
|
|
413
|
-
})) === null ||
|
|
565
|
+
})) === null || _a === void 0 ? void 0 : _a.catch((err) => onSetError === null || onSetError === void 0 ? void 0 : onSetError(err)));
|
|
566
|
+
localState.numSavesOutstanding--;
|
|
414
567
|
// If this remote save changed anything then update persistence and metadata
|
|
415
568
|
// Because save happens after a timeout and they're batched together, some calls to save will
|
|
416
569
|
// return saved data and others won't, so those can be ignored.
|
|
417
570
|
if (saved) {
|
|
418
571
|
const pathStrs = Array.from(new Set(changesRemote.map((change) => change.pathStr)));
|
|
419
|
-
const { changes,
|
|
572
|
+
const { changes, lastSync } = saved;
|
|
420
573
|
if (pathStrs.length > 0) {
|
|
421
574
|
if (local) {
|
|
422
575
|
const metadata = {};
|
|
423
|
-
const pending = (
|
|
424
|
-
let transformedChanges =
|
|
576
|
+
const pending = (_b = persistenceLocal.getMetadata(table, configLocal)) === null || _b === void 0 ? void 0 : _b.pending;
|
|
577
|
+
let transformedChanges = undefined;
|
|
425
578
|
for (let i = 0; i < pathStrs.length; i++) {
|
|
426
579
|
const pathStr = pathStrs[i];
|
|
427
580
|
// Clear pending for this path
|
|
@@ -431,25 +584,37 @@ async function doChange(changeInfo) {
|
|
|
431
584
|
metadata.pending = pending;
|
|
432
585
|
}
|
|
433
586
|
}
|
|
434
|
-
if (
|
|
435
|
-
metadata.
|
|
587
|
+
if (lastSync) {
|
|
588
|
+
metadata.lastSync = lastSync;
|
|
436
589
|
}
|
|
437
590
|
// Remote can optionally have data that needs to be merged back into the observable,
|
|
438
591
|
// for example Firebase may update dateModified with the server timestamp
|
|
439
592
|
if (changes && !isEmpty(changes)) {
|
|
440
|
-
transformedChanges
|
|
593
|
+
transformedChanges = transformLoadData(changes, persistOptions.remote, false);
|
|
441
594
|
}
|
|
442
|
-
if (
|
|
443
|
-
if (transformedChanges
|
|
444
|
-
|
|
595
|
+
if (localState.numSavesOutstanding > 0) {
|
|
596
|
+
if (transformedChanges) {
|
|
597
|
+
if (!localState.pendingSaveResults) {
|
|
598
|
+
localState.pendingSaveResults = [];
|
|
599
|
+
}
|
|
600
|
+
localState.pendingSaveResults.push(transformedChanges);
|
|
445
601
|
}
|
|
446
|
-
onChangeRemote(() => mergeIntoObservable(obs, ...transformedChanges));
|
|
447
602
|
}
|
|
448
|
-
|
|
449
|
-
|
|
603
|
+
else {
|
|
604
|
+
let allChanges = [...(localState.pendingSaveResults || []), transformedChanges];
|
|
605
|
+
if (allChanges.length > 0) {
|
|
606
|
+
if (allChanges.some((change) => isPromise(change))) {
|
|
607
|
+
allChanges = await Promise.all(allChanges);
|
|
608
|
+
}
|
|
609
|
+
onChangeRemote(() => mergeIntoObservable(obs, ...allChanges));
|
|
610
|
+
}
|
|
611
|
+
if (shouldSaveMetadata && !isEmpty(metadata)) {
|
|
612
|
+
updateMetadata(obs, localState, syncState, persistOptions, metadata);
|
|
613
|
+
}
|
|
614
|
+
localState.pendingSaveResults = [];
|
|
450
615
|
}
|
|
451
616
|
}
|
|
452
|
-
|
|
617
|
+
onSet === null || onSet === void 0 ? void 0 : onSet();
|
|
453
618
|
}
|
|
454
619
|
}
|
|
455
620
|
}
|
|
@@ -497,7 +662,7 @@ async function loadLocal(obs, persistOptions, syncState, localState) {
|
|
|
497
662
|
}
|
|
498
663
|
const { persist: persistenceLocal, initialized } = mapPersistences.get(localPersistence);
|
|
499
664
|
localState.persistenceLocal = persistenceLocal;
|
|
500
|
-
if (!initialized.
|
|
665
|
+
if (!initialized.peek()) {
|
|
501
666
|
await when(initialized);
|
|
502
667
|
}
|
|
503
668
|
// If persistence has an asynchronous load, wait for it
|
|
@@ -511,12 +676,21 @@ async function loadLocal(obs, persistOptions, syncState, localState) {
|
|
|
511
676
|
let value = persistenceLocal.getTable(table, config);
|
|
512
677
|
const metadata = persistenceLocal.getMetadata(table, config);
|
|
513
678
|
if (metadata) {
|
|
679
|
+
// @ts-expect-error Migration from old version
|
|
680
|
+
if (!metadata.lastSync && metadata.modified) {
|
|
681
|
+
// @ts-expect-error Migration from old
|
|
682
|
+
metadata.lastSync = metadata.modified;
|
|
683
|
+
}
|
|
514
684
|
metadatas.set(obs, metadata);
|
|
515
685
|
localState.pendingChanges = metadata.pending;
|
|
516
|
-
|
|
686
|
+
// TODOV3 Remove dateModified
|
|
687
|
+
syncState.assign({
|
|
688
|
+
dateModified: metadata.lastSync,
|
|
689
|
+
lastSync: metadata.lastSync,
|
|
690
|
+
});
|
|
517
691
|
}
|
|
518
692
|
// Merge the data from local persistence into the default state
|
|
519
|
-
if (value !==
|
|
693
|
+
if (value !== undefined) {
|
|
520
694
|
const { transform, fieldTransforms } = config;
|
|
521
695
|
value = transformLoadData(value, { transform, fieldTransforms }, true);
|
|
522
696
|
if (isPromise(value)) {
|
|
@@ -527,7 +701,12 @@ async function loadLocal(obs, persistOptions, syncState, localState) {
|
|
|
527
701
|
// are set on the same observable
|
|
528
702
|
internal$1.globalState.isLoadingLocal = true;
|
|
529
703
|
// We want to merge the local data on top of any initial state the object is created with
|
|
530
|
-
|
|
704
|
+
if (value === null && !obs.peek()) {
|
|
705
|
+
obs.set(value);
|
|
706
|
+
}
|
|
707
|
+
else {
|
|
708
|
+
mergeIntoObservable(obs, value);
|
|
709
|
+
}
|
|
531
710
|
}, () => {
|
|
532
711
|
internal$1.globalState.isLoadingLocal = false;
|
|
533
712
|
});
|
|
@@ -540,18 +719,11 @@ async function loadLocal(obs, persistOptions, syncState, localState) {
|
|
|
540
719
|
}
|
|
541
720
|
syncState.isLoadedLocal.set(true);
|
|
542
721
|
}
|
|
543
|
-
function persistObservable(
|
|
544
|
-
var _a;
|
|
545
|
-
const obs = (isObservable(initialOrObservable)
|
|
546
|
-
? initialOrObservable
|
|
547
|
-
: observable(isFunction(initialOrObservable) ? initialOrObservable() : initialOrObservable));
|
|
722
|
+
function persistObservable(obs, persistOptions) {
|
|
548
723
|
const node = getNode(obs);
|
|
549
|
-
if (process.env.NODE_ENV === 'development' && ((_a = obs === null || obs === void 0 ? void 0 : obs.peek()) === null || _a === void 0 ? void 0 : _a._state)) {
|
|
550
|
-
console.warn('[legend-state] WARNING: persistObservable creates a property named "_state" but your observable already has "state" in it');
|
|
551
|
-
}
|
|
552
724
|
// Merge remote persist options with clobal options
|
|
553
725
|
if (persistOptions.remote) {
|
|
554
|
-
persistOptions.remote = Object.assign({}, observablePersistConfiguration.remoteOptions, persistOptions.remote);
|
|
726
|
+
persistOptions.remote = Object.assign({}, observablePersistConfiguration.remoteOptions, removeNullUndefined(persistOptions.remote));
|
|
555
727
|
}
|
|
556
728
|
let { remote } = persistOptions;
|
|
557
729
|
const { local } = persistOptions;
|
|
@@ -592,92 +764,95 @@ function persistObservable(initialOrObservable, persistOptions) {
|
|
|
592
764
|
let isSynced = false;
|
|
593
765
|
sync = async () => {
|
|
594
766
|
var _a, _b;
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
767
|
+
const lastSync = (_a = metadatas.get(obs)) === null || _a === void 0 ? void 0 : _a.lastSync;
|
|
768
|
+
const pending = localState.pendingChanges;
|
|
769
|
+
const get = (_b = localState.persistenceRemote.get) === null || _b === void 0 ? void 0 : _b.bind(localState.persistenceRemote);
|
|
770
|
+
if (get) {
|
|
771
|
+
const runGet = () => {
|
|
772
|
+
get({
|
|
773
|
+
state: syncState,
|
|
774
|
+
obs,
|
|
775
|
+
options: persistOptions,
|
|
776
|
+
lastSync,
|
|
777
|
+
dateModified: lastSync,
|
|
778
|
+
onError: (error) => {
|
|
779
|
+
var _a;
|
|
780
|
+
(_a = remote.onGetError) === null || _a === void 0 ? void 0 : _a.call(remote, error);
|
|
781
|
+
},
|
|
782
|
+
onGet: () => {
|
|
783
|
+
node.state.assign({
|
|
784
|
+
isLoaded: true,
|
|
785
|
+
error: undefined,
|
|
786
|
+
});
|
|
787
|
+
},
|
|
788
|
+
onChange: async ({ value, path = [], pathTypes = [], mode = 'set', lastSync }) => {
|
|
789
|
+
// Note: value is the constructed value, path is used for setInObservableAtPath
|
|
790
|
+
// to start the set into the observable from the path
|
|
791
|
+
if (value !== undefined) {
|
|
792
|
+
value = transformLoadData(value, remote, true);
|
|
793
|
+
if (isPromise(value)) {
|
|
794
|
+
value = await value;
|
|
617
795
|
}
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
// Note: value is the constructed value, path is used for setInObservableAtPath
|
|
625
|
-
// to start the set into the observable from the path
|
|
626
|
-
if (value !== undefined) {
|
|
627
|
-
value = transformLoadData(value, remote, true);
|
|
628
|
-
if (isPromise(value)) {
|
|
629
|
-
value = await value;
|
|
630
|
-
}
|
|
631
|
-
const invertedMap = remote.fieldTransforms && invertFieldMap(remote.fieldTransforms);
|
|
632
|
-
if (path.length && invertedMap) {
|
|
633
|
-
path = transformPath(path, pathTypes, invertedMap);
|
|
634
|
-
}
|
|
635
|
-
if (mode === 'dateModified') {
|
|
636
|
-
if (dateModified && !isEmpty(value)) {
|
|
637
|
-
onChangeRemote(() => {
|
|
638
|
-
setInObservableAtPath(obs, path, pathTypes, value, 'assign');
|
|
639
|
-
});
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
else {
|
|
643
|
-
const pending = localState.pendingChanges;
|
|
644
|
-
if (pending) {
|
|
645
|
-
Object.keys(pending).forEach((key) => {
|
|
646
|
-
const p = key.split('/').filter((p) => p !== '');
|
|
647
|
-
const { v, t } = pending[key];
|
|
648
|
-
if (value[p[0]] !== undefined) {
|
|
649
|
-
value = setAtPath(value, p, t, v, obs.peek(), (path, value) => {
|
|
650
|
-
delete pending[key];
|
|
651
|
-
pending[path.join('/')] = {
|
|
652
|
-
p: null,
|
|
653
|
-
v: value,
|
|
654
|
-
t: t.slice(0, path.length),
|
|
655
|
-
};
|
|
656
|
-
});
|
|
657
|
-
}
|
|
658
|
-
});
|
|
659
|
-
}
|
|
796
|
+
const invertedMap = remote.fieldTransforms && invertFieldMap(remote.fieldTransforms);
|
|
797
|
+
if (path.length && invertedMap) {
|
|
798
|
+
path = transformPath(path, pathTypes, invertedMap);
|
|
799
|
+
}
|
|
800
|
+
if (mode === 'lastSync' || mode === 'dateModified') {
|
|
801
|
+
if (lastSync && !isEmpty(value)) {
|
|
660
802
|
onChangeRemote(() => {
|
|
661
|
-
setInObservableAtPath(
|
|
803
|
+
setInObservableAtPath(
|
|
804
|
+
// @ts-expect-error Fix this type
|
|
805
|
+
obs, path, pathTypes, value, 'assign');
|
|
662
806
|
});
|
|
663
807
|
}
|
|
664
808
|
}
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
809
|
+
else {
|
|
810
|
+
const pending = localState.pendingChanges;
|
|
811
|
+
if (pending) {
|
|
812
|
+
Object.keys(pending).forEach((key) => {
|
|
813
|
+
const p = key.split('/').filter((p) => p !== '');
|
|
814
|
+
const { v, t } = pending[key];
|
|
815
|
+
if (t.length === 0 || !value) {
|
|
816
|
+
value = v;
|
|
817
|
+
}
|
|
818
|
+
else if (value[p[0]] !== undefined) {
|
|
819
|
+
value = setAtPath(value, p, t, v, obs.peek(), (path, value) => {
|
|
820
|
+
delete pending[key];
|
|
821
|
+
pending[path.join('/')] = {
|
|
822
|
+
p: null,
|
|
823
|
+
v: value,
|
|
824
|
+
t: t.slice(0, path.length),
|
|
825
|
+
};
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
});
|
|
829
|
+
}
|
|
830
|
+
onChangeRemote(() => {
|
|
831
|
+
// @ts-expect-error Fix this type
|
|
832
|
+
setInObservableAtPath(obs, path, pathTypes, value, mode);
|
|
668
833
|
});
|
|
669
834
|
}
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
835
|
+
}
|
|
836
|
+
if (lastSync && local) {
|
|
837
|
+
updateMetadata(obs, localState, syncState, persistOptions, {
|
|
838
|
+
lastSync,
|
|
839
|
+
});
|
|
840
|
+
}
|
|
841
|
+
},
|
|
842
|
+
});
|
|
843
|
+
};
|
|
844
|
+
runGet();
|
|
845
|
+
}
|
|
846
|
+
else {
|
|
847
|
+
node.state.assign({
|
|
848
|
+
isLoaded: true,
|
|
849
|
+
error: undefined,
|
|
850
|
+
});
|
|
851
|
+
}
|
|
852
|
+
if (!isSynced) {
|
|
853
|
+
isSynced = true;
|
|
678
854
|
// Wait for remote to be ready before saving pending
|
|
679
855
|
await when(() => syncState.isLoaded.get() || (remote.allowSetIfError && syncState.error.get()));
|
|
680
|
-
const pending = localState.pendingChanges;
|
|
681
856
|
if (pending && !isEmpty(pending)) {
|
|
682
857
|
localState.isApplyingPending = true;
|
|
683
858
|
const keys = Object.keys(pending);
|
|
@@ -690,6 +865,7 @@ function persistObservable(initialOrObservable, persistOptions) {
|
|
|
690
865
|
changes.push({ path, valueAtPath: v, prevAtPath: p, pathTypes: t });
|
|
691
866
|
}
|
|
692
867
|
// Send the changes into onObsChange so that they get persisted remotely
|
|
868
|
+
// TODO: Not sure why this needs to as unknown as Observable
|
|
693
869
|
onObsChange(obs, syncState, localState, persistOptions, {
|
|
694
870
|
value: obs.peek(),
|
|
695
871
|
// TODO getPrevious if any remote persistence layers need it
|
|
@@ -700,10 +876,7 @@ function persistObservable(initialOrObservable, persistOptions) {
|
|
|
700
876
|
}
|
|
701
877
|
}
|
|
702
878
|
};
|
|
703
|
-
|
|
704
|
-
if (remote.manual) {
|
|
705
|
-
syncState.assign({ sync });
|
|
706
|
-
}
|
|
879
|
+
syncState.assign({ sync });
|
|
707
880
|
}
|
|
708
881
|
// Wait for this node and all parent nodes up the hierarchy to be loaded
|
|
709
882
|
const onAllLoadedLocal = () => {
|
|
@@ -725,64 +898,123 @@ function persistObservable(initialOrObservable, persistOptions) {
|
|
|
725
898
|
}
|
|
726
899
|
obs.onChange(onObsChange.bind(this, obs, syncState, localState, persistOptions));
|
|
727
900
|
});
|
|
728
|
-
return
|
|
901
|
+
return syncState;
|
|
729
902
|
}
|
|
730
903
|
|
|
731
|
-
const { getProxy, globalState } = internal$1;
|
|
904
|
+
const { getProxy, globalState, runWithRetry, symbolActivated } = internal$1;
|
|
732
905
|
function persistActivateNode() {
|
|
733
906
|
globalState.activateNode = function activateNodePersist(node, refresh, wasPromise, newValue) {
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
params.
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
onSetFn(params, {
|
|
754
|
-
update: onChange,
|
|
755
|
-
updateLastSync: () => {
|
|
756
|
-
console.log('TODO updateLastSync');
|
|
757
|
-
},
|
|
758
|
-
applyRemoteChange: onChangeRemote,
|
|
907
|
+
if (node.activationState) {
|
|
908
|
+
// If it is an Activated
|
|
909
|
+
const { get, initial, onSet, subscribe, cache, retry, offlineBehavior, waitForSet } = node.activationState;
|
|
910
|
+
let onChange = undefined;
|
|
911
|
+
const pluginRemote = {};
|
|
912
|
+
if (get) {
|
|
913
|
+
pluginRemote.get = (params) => {
|
|
914
|
+
onChange = params.onChange;
|
|
915
|
+
const updateLastSync = (lastSync) => (params.lastSync = lastSync);
|
|
916
|
+
const setMode = (mode) => (params.mode = mode);
|
|
917
|
+
const nodeValue = getNodeValue(node);
|
|
918
|
+
const value = runWithRetry(node, { attemptNum: 0 }, () => {
|
|
919
|
+
return get({
|
|
920
|
+
value: isFunction(nodeValue) || (nodeValue === null || nodeValue === void 0 ? void 0 : nodeValue[symbolActivated]) ? undefined : nodeValue,
|
|
921
|
+
lastSync: params.lastSync,
|
|
922
|
+
updateLastSync,
|
|
923
|
+
setMode,
|
|
924
|
+
refresh,
|
|
925
|
+
});
|
|
759
926
|
});
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
927
|
+
return value;
|
|
928
|
+
};
|
|
929
|
+
}
|
|
930
|
+
if (onSet) {
|
|
931
|
+
// TODO: Work out these types better
|
|
932
|
+
pluginRemote.set = async (params) => {
|
|
933
|
+
var _a;
|
|
934
|
+
if ((_a = node.state) === null || _a === void 0 ? void 0 : _a.isLoaded.get()) {
|
|
935
|
+
const retryAttempts = { attemptNum: 0 };
|
|
936
|
+
return runWithRetry(node, retryAttempts, async (retryEvent) => {
|
|
937
|
+
let changes = {};
|
|
938
|
+
let maxModified = 0;
|
|
939
|
+
if (!node.state.isLoaded.peek()) {
|
|
940
|
+
await whenReady(node.state.isLoaded);
|
|
941
|
+
}
|
|
942
|
+
const cancelRetry = () => {
|
|
943
|
+
retryEvent.cancel = true;
|
|
944
|
+
};
|
|
945
|
+
await onSet({
|
|
946
|
+
...params,
|
|
947
|
+
node,
|
|
948
|
+
update: (params) => {
|
|
949
|
+
const { value, lastSync } = params;
|
|
950
|
+
maxModified = Math.max(lastSync || 0, maxModified);
|
|
951
|
+
changes = mergeIntoObservable(changes, value);
|
|
952
|
+
},
|
|
953
|
+
retryNum: retryAttempts.attemptNum,
|
|
954
|
+
cancelRetry,
|
|
955
|
+
refresh,
|
|
956
|
+
fromSubscribe: false,
|
|
957
|
+
});
|
|
958
|
+
return { changes, lastSync: maxModified || undefined };
|
|
959
|
+
});
|
|
769
960
|
}
|
|
770
|
-
|
|
771
|
-
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
if (subscribe) {
|
|
964
|
+
subscribe({
|
|
965
|
+
node,
|
|
966
|
+
update: (params) => {
|
|
967
|
+
if (!onChange) {
|
|
968
|
+
// TODO: Make this message better
|
|
969
|
+
console.log('[legend-state] Cannot update immediately before the first return');
|
|
970
|
+
}
|
|
971
|
+
else {
|
|
972
|
+
onChange(params);
|
|
973
|
+
}
|
|
974
|
+
},
|
|
975
|
+
refresh,
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
persistObservable(getProxy(node), {
|
|
979
|
+
pluginRemote,
|
|
980
|
+
...(cache || {}),
|
|
981
|
+
remote: {
|
|
982
|
+
retry: retry,
|
|
983
|
+
offlineBehavior,
|
|
984
|
+
waitForSet,
|
|
985
|
+
},
|
|
986
|
+
});
|
|
987
|
+
const nodeVal = getNodeValue(node);
|
|
988
|
+
if (nodeVal !== undefined) {
|
|
989
|
+
newValue = nodeVal;
|
|
990
|
+
}
|
|
991
|
+
else if (newValue === undefined) {
|
|
992
|
+
newValue = initial;
|
|
993
|
+
}
|
|
994
|
+
return { update: onChange, value: newValue };
|
|
995
|
+
}
|
|
996
|
+
else {
|
|
997
|
+
// If it is not an Activated
|
|
998
|
+
let onChange = undefined;
|
|
999
|
+
const pluginRemote = {
|
|
1000
|
+
get: async (params) => {
|
|
1001
|
+
onChange = params.onChange;
|
|
1002
|
+
if (isPromise(newValue)) {
|
|
1003
|
+
try {
|
|
1004
|
+
newValue = await newValue;
|
|
1005
|
+
}
|
|
1006
|
+
catch (_a) {
|
|
1007
|
+
// TODO Once we have global retry settings this should retry
|
|
1008
|
+
}
|
|
772
1009
|
}
|
|
1010
|
+
return newValue;
|
|
773
1011
|
},
|
|
774
|
-
|
|
775
|
-
|
|
1012
|
+
};
|
|
1013
|
+
persistObservable(getProxy(node), {
|
|
1014
|
+
pluginRemote,
|
|
776
1015
|
});
|
|
1016
|
+
return { update: onChange, value: newValue };
|
|
777
1017
|
}
|
|
778
|
-
persistObservable(getProxy(node), {
|
|
779
|
-
pluginRemote,
|
|
780
|
-
...(cacheOptions || {}),
|
|
781
|
-
remote: {
|
|
782
|
-
retry: retryOptions,
|
|
783
|
-
},
|
|
784
|
-
});
|
|
785
|
-
return { update: onChange };
|
|
786
1018
|
};
|
|
787
1019
|
}
|
|
788
1020
|
|