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