@legendapp/state 3.0.0-alpha.3 → 3.0.0-alpha.30
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/config/enable$GetSet.js +2 -1
- package/config/enable$GetSet.mjs +2 -1
- package/config/enableReactTracking.js +2 -1
- package/config/enableReactTracking.mjs +2 -1
- package/config/enableReactUse.js +2 -1
- package/config/enableReactUse.mjs +2 -1
- package/config/enable_PeekAssign.js +2 -1
- package/config/enable_PeekAssign.mjs +2 -1
- package/config.d.mts +13 -0
- package/config.d.ts +13 -0
- package/config.js +2052 -0
- package/config.mjs +2050 -0
- package/helpers/trackHistory.js +2 -2
- package/helpers/trackHistory.mjs +2 -2
- package/index.d.mts +21 -302
- package/index.d.ts +21 -302
- package/index.js +274 -318
- package/index.mjs +275 -317
- package/observableInterfaces-Dilj6F92.d.mts +282 -0
- package/observableInterfaces-Dilj6F92.d.ts +282 -0
- package/package.json +11 -1
- package/persist-plugins/async-storage.d.mts +6 -3
- package/persist-plugins/async-storage.d.ts +6 -3
- package/persist-plugins/async-storage.js +12 -4
- package/persist-plugins/async-storage.mjs +12 -5
- package/persist-plugins/indexeddb.d.mts +6 -4
- package/persist-plugins/indexeddb.d.ts +6 -4
- package/persist-plugins/indexeddb.js +16 -6
- package/persist-plugins/indexeddb.mjs +16 -7
- package/persist-plugins/mmkv.d.mts +5 -1
- package/persist-plugins/mmkv.d.ts +5 -1
- package/persist-plugins/mmkv.js +14 -5
- package/persist-plugins/mmkv.mjs +14 -6
- package/react.d.mts +18 -14
- package/react.d.ts +18 -14
- package/react.js +57 -32
- package/react.mjs +58 -33
- 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 +15 -23
- package/sync-plugins/crud.d.ts +15 -23
- package/sync-plugins/crud.js +213 -134
- package/sync-plugins/crud.mjs +214 -135
- package/sync-plugins/fetch.js +12 -8
- package/sync-plugins/fetch.mjs +13 -9
- package/sync-plugins/firebase.d.mts +26 -0
- package/sync-plugins/firebase.d.ts +26 -0
- package/sync-plugins/firebase.js +373 -0
- package/sync-plugins/firebase.mjs +368 -0
- package/sync-plugins/keel.d.mts +27 -10
- package/sync-plugins/keel.d.ts +27 -10
- package/sync-plugins/keel.js +40 -21
- package/sync-plugins/keel.mjs +40 -21
- package/sync-plugins/supabase.d.mts +12 -7
- package/sync-plugins/supabase.d.ts +12 -7
- package/sync-plugins/supabase.js +24 -13
- package/sync-plugins/supabase.mjs +25 -14
- 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 +68 -197
- package/sync.d.ts +68 -197
- package/sync.js +448 -283
- package/sync.mjs +454 -289
- 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.js
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
var state = require('@legendapp/state');
|
|
4
4
|
|
|
5
|
-
// sync.ts
|
|
6
|
-
|
|
7
5
|
// src/sync/configureObservableSync.ts
|
|
8
6
|
var observableSyncConfiguration = {};
|
|
9
7
|
function configureObservableSync(options) {
|
|
@@ -139,34 +137,74 @@ function transformStringifyDates(...args) {
|
|
|
139
137
|
}
|
|
140
138
|
};
|
|
141
139
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
mode: params.mode
|
|
155
|
-
});
|
|
156
|
-
params.onGet();
|
|
157
|
-
} catch (e) {
|
|
158
|
-
}
|
|
159
|
-
};
|
|
140
|
+
|
|
141
|
+
// src/is.ts
|
|
142
|
+
function isPromise(obj) {
|
|
143
|
+
return obj instanceof Promise;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// src/sync/retry.ts
|
|
147
|
+
function calculateRetryDelay(retryOptions, retryNum) {
|
|
148
|
+
const { backoff, delay = 1e3, infinite, times = 3, maxDelay = 3e4 } = retryOptions;
|
|
149
|
+
if (infinite || retryNum < times) {
|
|
150
|
+
const delayTime = Math.min(delay * (backoff === "constant" ? 1 : 2 ** retryNum), maxDelay);
|
|
151
|
+
return delayTime;
|
|
160
152
|
}
|
|
161
|
-
|
|
162
|
-
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
function createRetryTimeout(retryOptions, retryNum, fn) {
|
|
156
|
+
const delayTime = calculateRetryDelay(retryOptions, retryNum);
|
|
157
|
+
if (delayTime) {
|
|
158
|
+
return setTimeout(fn, delayTime);
|
|
159
|
+
} else {
|
|
160
|
+
return false;
|
|
163
161
|
}
|
|
164
|
-
|
|
162
|
+
}
|
|
163
|
+
var mapRetryTimeouts = /* @__PURE__ */ new Map();
|
|
164
|
+
function runWithRetry(state, retryOptions, fn, onError) {
|
|
165
|
+
let value = fn(state);
|
|
166
|
+
if (isPromise(value) && retryOptions) {
|
|
167
|
+
let timeoutRetry;
|
|
168
|
+
if (mapRetryTimeouts.has(state.node)) {
|
|
169
|
+
clearTimeout(mapRetryTimeouts.get(state.node));
|
|
170
|
+
}
|
|
171
|
+
return new Promise((resolve, reject) => {
|
|
172
|
+
const run = () => {
|
|
173
|
+
value.then((val) => {
|
|
174
|
+
resolve(val);
|
|
175
|
+
}).catch((error) => {
|
|
176
|
+
state.retryNum++;
|
|
177
|
+
if (timeoutRetry) {
|
|
178
|
+
clearTimeout(timeoutRetry);
|
|
179
|
+
}
|
|
180
|
+
if (onError) {
|
|
181
|
+
onError(error);
|
|
182
|
+
}
|
|
183
|
+
if (!state.cancelRetry) {
|
|
184
|
+
const timeout = createRetryTimeout(retryOptions, state.retryNum, () => {
|
|
185
|
+
value = fn(state);
|
|
186
|
+
run();
|
|
187
|
+
});
|
|
188
|
+
if (timeout === false) {
|
|
189
|
+
state.cancelRetry = true;
|
|
190
|
+
reject(error);
|
|
191
|
+
} else {
|
|
192
|
+
mapRetryTimeouts.set(state.node, timeout);
|
|
193
|
+
timeoutRetry = timeout;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
};
|
|
198
|
+
run();
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
return value;
|
|
165
202
|
}
|
|
166
203
|
|
|
167
204
|
// src/sync/syncObservable.ts
|
|
168
|
-
var {
|
|
205
|
+
var { clone, deepMerge, getNode, getNodeValue, getValueAtPath, globalState, symbolLinked, createPreviousHandler } = state.internal;
|
|
169
206
|
var mapSyncPlugins = /* @__PURE__ */ new WeakMap();
|
|
207
|
+
var allSyncStates = /* @__PURE__ */ new Map();
|
|
170
208
|
var metadatas = /* @__PURE__ */ new WeakMap();
|
|
171
209
|
var promisesLocalSaves = /* @__PURE__ */ new Set();
|
|
172
210
|
function parseLocalConfig(config) {
|
|
@@ -183,13 +221,19 @@ function onChangeRemote(cb) {
|
|
|
183
221
|
globalState.isLoadingRemote = false;
|
|
184
222
|
state.endBatch(true);
|
|
185
223
|
}
|
|
186
|
-
function transformSaveData(value, path, pathTypes, { transform }) {
|
|
224
|
+
async function transformSaveData(value, path, pathTypes, { transform }) {
|
|
187
225
|
if (transform == null ? void 0 : transform.save) {
|
|
188
226
|
const constructed = state.constructObjectWithPath(path, pathTypes, value);
|
|
189
|
-
const saved = transform.save(constructed);
|
|
190
|
-
value =
|
|
227
|
+
const saved = await transform.save(constructed);
|
|
228
|
+
value = saved;
|
|
229
|
+
const outPath = [];
|
|
230
|
+
for (let i = 0; i < path.length; i++) {
|
|
231
|
+
outPath[i] = Object.keys(value)[0];
|
|
232
|
+
value = value[outPath[i]];
|
|
233
|
+
}
|
|
234
|
+
path = outPath;
|
|
191
235
|
}
|
|
192
|
-
return value;
|
|
236
|
+
return { value, path };
|
|
193
237
|
}
|
|
194
238
|
function transformLoadData(value, { transform }, doUserTransform, method) {
|
|
195
239
|
if (doUserTransform && (transform == null ? void 0 : transform.load)) {
|
|
@@ -197,7 +241,7 @@ function transformLoadData(value, { transform }, doUserTransform, method) {
|
|
|
197
241
|
}
|
|
198
242
|
return value;
|
|
199
243
|
}
|
|
200
|
-
async function updateMetadataImmediate(value$, localState,
|
|
244
|
+
async function updateMetadataImmediate(value$, localState, syncState2, syncOptions, newMetadata) {
|
|
201
245
|
const saves = Array.from(promisesLocalSaves);
|
|
202
246
|
if (saves.length > 0) {
|
|
203
247
|
await Promise.all(saves);
|
|
@@ -212,17 +256,17 @@ async function updateMetadataImmediate(value$, localState, syncState, syncOption
|
|
|
212
256
|
await pluginPersist.setMetadata(table, metadata, config);
|
|
213
257
|
}
|
|
214
258
|
if (lastSync) {
|
|
215
|
-
|
|
259
|
+
syncState2.assign({
|
|
216
260
|
lastSync
|
|
217
261
|
});
|
|
218
262
|
}
|
|
219
263
|
}
|
|
220
|
-
function updateMetadata(value$, localState,
|
|
264
|
+
function updateMetadata(value$, localState, syncState2, syncOptions, newMetadata) {
|
|
221
265
|
if (localState.timeoutSaveMetadata) {
|
|
222
266
|
clearTimeout(localState.timeoutSaveMetadata);
|
|
223
267
|
}
|
|
224
268
|
localState.timeoutSaveMetadata = setTimeout(
|
|
225
|
-
() => updateMetadataImmediate(value$, localState,
|
|
269
|
+
() => updateMetadataImmediate(value$, localState, syncState2, syncOptions, newMetadata),
|
|
226
270
|
0
|
|
227
271
|
);
|
|
228
272
|
}
|
|
@@ -250,26 +294,21 @@ function mergeChanges(changes) {
|
|
|
250
294
|
return changesOut;
|
|
251
295
|
}
|
|
252
296
|
function mergeQueuedChanges(allChanges) {
|
|
253
|
-
const
|
|
254
|
-
const
|
|
255
|
-
const previousByObs = /* @__PURE__ */ new Map();
|
|
297
|
+
const changesByOptionsRemote = /* @__PURE__ */ new Map();
|
|
298
|
+
const changesByOptionsLocal = /* @__PURE__ */ new Map();
|
|
256
299
|
const outRemote = /* @__PURE__ */ new Map();
|
|
257
300
|
const outLocal = /* @__PURE__ */ new Map();
|
|
258
301
|
for (let i = 0; i < allChanges.length; i++) {
|
|
259
302
|
const value = allChanges[i];
|
|
260
|
-
const {
|
|
303
|
+
const { changes, inRemoteChange, syncOptions } = value;
|
|
261
304
|
const targetMap = inRemoteChange ? outRemote : outLocal;
|
|
262
|
-
const changesMap = inRemoteChange ?
|
|
263
|
-
const existing = changesMap.get(
|
|
305
|
+
const changesMap = inRemoteChange ? changesByOptionsRemote : changesByOptionsLocal;
|
|
306
|
+
const existing = changesMap.get(syncOptions);
|
|
264
307
|
const newChanges = existing ? [...existing, ...changes] : changes;
|
|
265
308
|
const merged = mergeChanges(newChanges);
|
|
266
|
-
changesMap.set(
|
|
309
|
+
changesMap.set(syncOptions, merged);
|
|
267
310
|
value.changes = merged;
|
|
268
|
-
|
|
269
|
-
previousByObs.set(obs, getPrevious());
|
|
270
|
-
}
|
|
271
|
-
value.valuePrevious = previousByObs.get(obs);
|
|
272
|
-
targetMap.set(obs, value);
|
|
311
|
+
targetMap.set(syncOptions, value);
|
|
273
312
|
}
|
|
274
313
|
return Array.from(outRemote.values()).concat(Array.from(outLocal.values()));
|
|
275
314
|
}
|
|
@@ -315,15 +354,13 @@ async function processQueuedRemoteChanges(syncOptions) {
|
|
|
315
354
|
}
|
|
316
355
|
}
|
|
317
356
|
async function prepChangeLocal(queuedChange) {
|
|
318
|
-
const { syncState, changes,
|
|
357
|
+
const { syncState: syncState2, changes, syncOptions, inRemoteChange, isApplyingPending } = queuedChange;
|
|
319
358
|
const persist = syncOptions.persist;
|
|
320
|
-
const { pluginSync } = localState;
|
|
321
359
|
const { config: configLocal } = parseLocalConfig(persist);
|
|
322
|
-
const
|
|
323
|
-
const
|
|
324
|
-
const saveRemote = !!(!inRemoteChange && (pluginSync == null ? void 0 : pluginSync.set) && (configRemote == null ? void 0 : configRemote.enableSync) !== false && syncState.isSyncEnabled.peek());
|
|
360
|
+
const saveLocal = (persist == null ? void 0 : persist.name) && !configLocal.readonly && !isApplyingPending && syncState2.isPersistEnabled.peek();
|
|
361
|
+
const saveRemote = !!(!inRemoteChange && (syncOptions == null ? void 0 : syncOptions.set) && syncState2.isSyncEnabled.peek());
|
|
325
362
|
if (saveLocal || saveRemote) {
|
|
326
|
-
if (saveLocal && !
|
|
363
|
+
if (saveLocal && !syncState2.isPersistLoaded.peek()) {
|
|
327
364
|
console.error(
|
|
328
365
|
"[legend-state] WARNING: An observable was changed before being loaded from persist",
|
|
329
366
|
persist
|
|
@@ -356,13 +393,13 @@ async function prepChangeLocal(queuedChange) {
|
|
|
356
393
|
configLocal
|
|
357
394
|
);
|
|
358
395
|
promisesTransform.push(
|
|
359
|
-
doInOrder(promiseTransformLocal, (valueTransformed) => {
|
|
396
|
+
doInOrder(promiseTransformLocal, ({ value: valueTransformed, path: pathTransformed }) => {
|
|
360
397
|
changesLocal.push({
|
|
361
|
-
path,
|
|
398
|
+
path: pathTransformed,
|
|
362
399
|
pathTypes,
|
|
363
400
|
prevAtPath,
|
|
364
401
|
valueAtPath: valueTransformed,
|
|
365
|
-
pathStr
|
|
402
|
+
pathStr: path === pathTransformed ? pathStr : pathTransformed.join("/")
|
|
366
403
|
});
|
|
367
404
|
})
|
|
368
405
|
);
|
|
@@ -378,22 +415,19 @@ async function prepChangeLocal(queuedChange) {
|
|
|
378
415
|
}
|
|
379
416
|
async function prepChangeRemote(queuedChange) {
|
|
380
417
|
const {
|
|
381
|
-
syncState,
|
|
418
|
+
syncState: syncState2,
|
|
382
419
|
changes,
|
|
383
420
|
localState,
|
|
384
421
|
syncOptions,
|
|
385
422
|
inRemoteChange,
|
|
386
|
-
isApplyingPending
|
|
387
|
-
valuePrevious
|
|
423
|
+
isApplyingPending
|
|
388
424
|
} = queuedChange;
|
|
389
425
|
const persist = syncOptions.persist;
|
|
390
|
-
const { pluginSync } = localState;
|
|
391
426
|
const { config: configLocal } = parseLocalConfig(persist);
|
|
392
|
-
const
|
|
393
|
-
const
|
|
394
|
-
const saveRemote = !inRemoteChange && (pluginSync == null ? void 0 : pluginSync.set) && (configRemote == null ? void 0 : configRemote.enableSync) !== false && syncState.isSyncEnabled.peek();
|
|
427
|
+
const saveLocal = persist && !configLocal.readonly && !isApplyingPending && syncState2.isPersistEnabled.peek();
|
|
428
|
+
const saveRemote = !inRemoteChange && (syncOptions == null ? void 0 : syncOptions.set) && syncState2.isSyncEnabled.peek();
|
|
395
429
|
if (saveLocal || saveRemote) {
|
|
396
|
-
if (saveLocal && !
|
|
430
|
+
if (saveLocal && !syncState2.isPersistLoaded.peek()) {
|
|
397
431
|
console.error(
|
|
398
432
|
"[legend-state] WARNING: An observable was changed before being loaded from persist",
|
|
399
433
|
persist
|
|
@@ -423,20 +457,20 @@ async function prepChangeRemote(queuedChange) {
|
|
|
423
457
|
valueAtPath,
|
|
424
458
|
path,
|
|
425
459
|
pathTypes,
|
|
426
|
-
|
|
460
|
+
syncOptions || {}
|
|
427
461
|
);
|
|
428
462
|
promisesTransform.push(
|
|
429
|
-
doInOrder(promiseTransformRemote, (valueTransformed) => {
|
|
463
|
+
doInOrder(promiseTransformRemote, ({ value: valueTransformed, path: pathTransformed }) => {
|
|
430
464
|
var _a;
|
|
431
465
|
if (!localState.pendingChanges) {
|
|
432
466
|
localState.pendingChanges = {};
|
|
433
467
|
}
|
|
434
468
|
let found2 = false;
|
|
435
|
-
for (let i2 = 0; !found2 && i2 <
|
|
436
|
-
const pathParent =
|
|
469
|
+
for (let i2 = 0; !found2 && i2 < pathTransformed.length - 1; i2++) {
|
|
470
|
+
const pathParent = pathTransformed.slice(0, i2 + 1).join("/");
|
|
437
471
|
if ((_a = localState.pendingChanges[pathParent]) == null ? void 0 : _a.v) {
|
|
438
472
|
found2 = true;
|
|
439
|
-
const pathChild =
|
|
473
|
+
const pathChild = pathTransformed.slice(i2 + 1);
|
|
440
474
|
const pathTypesChild = pathTypes.slice(i2 + 1);
|
|
441
475
|
state.setAtPath(
|
|
442
476
|
localState.pendingChanges[pathParent].v,
|
|
@@ -458,12 +492,11 @@ async function prepChangeRemote(queuedChange) {
|
|
|
458
492
|
localState.pendingChanges[pathStr].v = valueAtPath;
|
|
459
493
|
}
|
|
460
494
|
changesRemote.push({
|
|
461
|
-
path,
|
|
495
|
+
path: pathTransformed,
|
|
462
496
|
pathTypes,
|
|
463
497
|
prevAtPath,
|
|
464
498
|
valueAtPath: valueTransformed,
|
|
465
|
-
pathStr
|
|
466
|
-
valuePrevious
|
|
499
|
+
pathStr
|
|
467
500
|
});
|
|
468
501
|
})
|
|
469
502
|
);
|
|
@@ -481,24 +514,27 @@ async function doChangeLocal(changeInfo) {
|
|
|
481
514
|
if (!changeInfo)
|
|
482
515
|
return;
|
|
483
516
|
const { queuedChange, changesLocal, saveRemote } = changeInfo;
|
|
484
|
-
const { value$: obs, syncState, localState, syncOptions } = queuedChange;
|
|
517
|
+
const { value$: obs, syncState: syncState2, localState, syncOptions } = queuedChange;
|
|
485
518
|
const { pluginPersist } = localState;
|
|
486
519
|
const persist = syncOptions.persist;
|
|
487
|
-
const
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
if (changesLocal.length > 0) {
|
|
495
|
-
let promiseSet = pluginPersist.set(table, changesLocal, configLocal);
|
|
496
|
-
if (promiseSet) {
|
|
497
|
-
promiseSet = promiseSet.then(() => {
|
|
498
|
-
promisesLocalSaves.delete(promiseSet);
|
|
520
|
+
const saveLocal = !!(persist == null ? void 0 : persist.name);
|
|
521
|
+
if (saveLocal) {
|
|
522
|
+
const { table, config: configLocal } = parseLocalConfig(persist);
|
|
523
|
+
const shouldSaveMetadata = persist == null ? void 0 : persist.retrySync;
|
|
524
|
+
if (saveRemote && shouldSaveMetadata) {
|
|
525
|
+
await updateMetadataImmediate(obs, localState, syncState2, syncOptions, {
|
|
526
|
+
pending: localState.pendingChanges
|
|
499
527
|
});
|
|
500
|
-
|
|
501
|
-
|
|
528
|
+
}
|
|
529
|
+
if (changesLocal.length > 0) {
|
|
530
|
+
let promiseSet = pluginPersist.set(table, changesLocal, configLocal);
|
|
531
|
+
if (promiseSet) {
|
|
532
|
+
promiseSet = promiseSet.then(() => {
|
|
533
|
+
promisesLocalSaves.delete(promiseSet);
|
|
534
|
+
});
|
|
535
|
+
promisesLocalSaves.add(promiseSet);
|
|
536
|
+
await promiseSet;
|
|
537
|
+
}
|
|
502
538
|
}
|
|
503
539
|
}
|
|
504
540
|
}
|
|
@@ -507,47 +543,99 @@ async function doChangeRemote(changeInfo) {
|
|
|
507
543
|
if (!changeInfo)
|
|
508
544
|
return;
|
|
509
545
|
const { queuedChange, changesRemote } = changeInfo;
|
|
510
|
-
const { value$: obs
|
|
511
|
-
const { pluginPersist
|
|
546
|
+
const { value$: obs$, syncState: syncState2, localState, syncOptions } = queuedChange;
|
|
547
|
+
const { pluginPersist } = localState;
|
|
548
|
+
const node = getNode(obs$);
|
|
549
|
+
const state$ = node.state;
|
|
512
550
|
const persist = syncOptions.persist;
|
|
513
551
|
const { table, config: configLocal } = parseLocalConfig(persist);
|
|
514
|
-
const {
|
|
552
|
+
const { onBeforeSet, waitForSet, onAfterSet } = syncOptions || {};
|
|
515
553
|
const shouldSaveMetadata = persist == null ? void 0 : persist.retrySync;
|
|
554
|
+
const saveLocal = !!(persist == null ? void 0 : persist.name);
|
|
516
555
|
if (changesRemote.length > 0) {
|
|
517
|
-
|
|
556
|
+
if (!syncState2.isLoaded.peek()) {
|
|
557
|
+
await state.when(syncState2.isLoaded);
|
|
558
|
+
const pending = localState.pendingChanges;
|
|
559
|
+
if (pending) {
|
|
560
|
+
changesRemote.forEach((change) => {
|
|
561
|
+
const key = change.pathStr;
|
|
562
|
+
const pendingAtPath = pending[key];
|
|
563
|
+
if (!state.isNullOrUndefined(pendingAtPath)) {
|
|
564
|
+
const { p } = pendingAtPath;
|
|
565
|
+
change.prevAtPath = p;
|
|
566
|
+
}
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
}
|
|
518
570
|
if (waitForSet) {
|
|
519
|
-
const
|
|
520
|
-
if (
|
|
521
|
-
await state.when(
|
|
571
|
+
const waitFn = state.isFunction(waitForSet) ? waitForSet({ changes: changesRemote, value: obs$.peek() }) : waitForSet;
|
|
572
|
+
if (waitFn) {
|
|
573
|
+
await state.when(waitFn);
|
|
522
574
|
}
|
|
523
575
|
}
|
|
524
|
-
let value = obs
|
|
576
|
+
let value = clone(obs$.peek());
|
|
525
577
|
const transformSave = (_a = syncOptions == null ? void 0 : syncOptions.transform) == null ? void 0 : _a.save;
|
|
526
578
|
if (transformSave) {
|
|
527
|
-
value = transformSave(
|
|
579
|
+
value = transformSave(value);
|
|
528
580
|
}
|
|
581
|
+
state$.numPendingSets.set((v) => (v || 0) + 1);
|
|
582
|
+
state$.isSetting.set(true);
|
|
529
583
|
onBeforeSet == null ? void 0 : onBeforeSet();
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
584
|
+
let updateResult = void 0;
|
|
585
|
+
const onError = (error) => {
|
|
586
|
+
var _a2;
|
|
587
|
+
state$.error.set(error);
|
|
588
|
+
(_a2 = syncOptions.onSetError) == null ? void 0 : _a2.call(syncOptions, error, {
|
|
589
|
+
setParams,
|
|
590
|
+
source: "set",
|
|
591
|
+
value$: obs$
|
|
592
|
+
});
|
|
593
|
+
};
|
|
594
|
+
const setParams = {
|
|
595
|
+
node,
|
|
596
|
+
value$: obs$,
|
|
535
597
|
changes: changesRemote,
|
|
536
598
|
value,
|
|
537
|
-
|
|
538
|
-
|
|
599
|
+
onError,
|
|
600
|
+
update: (params) => {
|
|
601
|
+
if (updateResult) {
|
|
602
|
+
const { value: value2, lastSync, mode } = params;
|
|
603
|
+
updateResult = {
|
|
604
|
+
lastSync: Math.max(updateResult.lastSync || 0, lastSync || 0),
|
|
605
|
+
value: deepMerge(updateResult.value, value2),
|
|
606
|
+
mode
|
|
607
|
+
};
|
|
608
|
+
} else {
|
|
609
|
+
updateResult = params;
|
|
610
|
+
}
|
|
611
|
+
},
|
|
612
|
+
refresh: syncState2.sync,
|
|
613
|
+
retryNum: 0,
|
|
614
|
+
cancelRetry: false
|
|
615
|
+
};
|
|
616
|
+
let savedPromise = runWithRetry(
|
|
617
|
+
setParams,
|
|
618
|
+
syncOptions.retry,
|
|
619
|
+
async () => {
|
|
620
|
+
return syncOptions.set(setParams);
|
|
621
|
+
},
|
|
622
|
+
onError
|
|
623
|
+
);
|
|
624
|
+
let didError = false;
|
|
539
625
|
if (state.isPromise(savedPromise)) {
|
|
540
|
-
savedPromise = savedPromise.catch((
|
|
626
|
+
savedPromise = savedPromise.catch((error) => {
|
|
627
|
+
didError = true;
|
|
628
|
+
onError(error);
|
|
629
|
+
});
|
|
630
|
+
await savedPromise;
|
|
541
631
|
}
|
|
542
|
-
|
|
543
|
-
localState.numSavesOutstanding--;
|
|
544
|
-
if (saved !== void 0) {
|
|
632
|
+
if (!didError) {
|
|
545
633
|
const pathStrs = Array.from(new Set(changesRemote.map((change) => change.pathStr)));
|
|
546
|
-
const { changes, lastSync } =
|
|
634
|
+
const { value: changes, lastSync } = updateResult || {};
|
|
547
635
|
if (pathStrs.length > 0) {
|
|
548
636
|
let transformedChanges = void 0;
|
|
549
637
|
const metadata = {};
|
|
550
|
-
if (
|
|
638
|
+
if (saveLocal) {
|
|
551
639
|
const pendingMetadata = (_b = pluginPersist.getMetadata(table, configLocal)) == null ? void 0 : _b.pending;
|
|
552
640
|
const pending = localState.pendingChanges;
|
|
553
641
|
for (let i = 0; i < pathStrs.length; i++) {
|
|
@@ -567,42 +655,31 @@ async function doChangeRemote(changeInfo) {
|
|
|
567
655
|
if (changes && !state.isEmpty(changes)) {
|
|
568
656
|
transformedChanges = transformLoadData(changes, syncOptions, false, "set");
|
|
569
657
|
}
|
|
570
|
-
if (
|
|
571
|
-
if (transformedChanges) {
|
|
572
|
-
|
|
573
|
-
localState.pendingSaveResults = [];
|
|
574
|
-
}
|
|
575
|
-
localState.pendingSaveResults.push(transformedChanges);
|
|
658
|
+
if (transformedChanges !== void 0) {
|
|
659
|
+
if (state.isPromise(transformedChanges)) {
|
|
660
|
+
transformedChanges = await transformedChanges;
|
|
576
661
|
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
)
|
|
581
|
-
|
|
582
|
-
if (allChanges.some((change) => state.isPromise(change))) {
|
|
583
|
-
allChanges = await Promise.all(allChanges);
|
|
584
|
-
}
|
|
585
|
-
onChangeRemote(() => state.mergeIntoObservable(obs, ...allChanges));
|
|
586
|
-
}
|
|
587
|
-
if (persist) {
|
|
588
|
-
if (shouldSaveMetadata && !state.isEmpty(metadata)) {
|
|
589
|
-
updateMetadata(obs, localState, syncState, syncOptions, metadata);
|
|
590
|
-
}
|
|
662
|
+
onChangeRemote(() => state.mergeIntoObservable(obs$, transformedChanges));
|
|
663
|
+
}
|
|
664
|
+
if (saveLocal) {
|
|
665
|
+
if (shouldSaveMetadata && !state.isEmpty(metadata)) {
|
|
666
|
+
updateMetadata(obs$, localState, syncState2, syncOptions, metadata);
|
|
591
667
|
}
|
|
592
|
-
localState.pendingSaveResults = [];
|
|
593
668
|
}
|
|
594
|
-
onAfterSet == null ? void 0 : onAfterSet();
|
|
595
669
|
}
|
|
670
|
+
state$.numPendingSets.set((v) => v - 1);
|
|
671
|
+
state$.isSetting.set(state$.numPendingSets.peek() > 0);
|
|
672
|
+
onAfterSet == null ? void 0 : onAfterSet();
|
|
596
673
|
}
|
|
597
674
|
}
|
|
598
675
|
}
|
|
599
|
-
function onObsChange(value$,
|
|
600
|
-
if (!
|
|
601
|
-
const inRemoteChange =
|
|
676
|
+
function onObsChange(value$, syncState2, localState, syncOptions, { changes, isFromPersist, isFromSync, getPrevious }) {
|
|
677
|
+
if (!isFromPersist) {
|
|
678
|
+
const inRemoteChange = isFromSync;
|
|
602
679
|
const isApplyingPending = localState.isApplyingPending;
|
|
603
680
|
_queuedChanges.push({
|
|
604
681
|
value$,
|
|
605
|
-
syncState,
|
|
682
|
+
syncState: syncState2,
|
|
606
683
|
localState,
|
|
607
684
|
syncOptions,
|
|
608
685
|
changes,
|
|
@@ -615,13 +692,17 @@ function onObsChange(value$, syncState, localState, syncOptions, { changes, load
|
|
|
615
692
|
}
|
|
616
693
|
}
|
|
617
694
|
}
|
|
618
|
-
async function loadLocal(value$, syncOptions, syncState
|
|
695
|
+
async function loadLocal(value$, syncOptions, syncState$, localState) {
|
|
619
696
|
var _a, _b, _c;
|
|
620
697
|
const { persist } = syncOptions;
|
|
621
|
-
|
|
698
|
+
const node = getNode(value$);
|
|
699
|
+
const nodeValue = getNodeValue(getNode(node.state));
|
|
700
|
+
const syncStateValue = syncState$.peek();
|
|
701
|
+
const prevClearPersist = nodeValue.clearPersist;
|
|
702
|
+
if (persist == null ? void 0 : persist.name) {
|
|
622
703
|
const PersistPlugin = persist.plugin || ((_a = observableSyncConfiguration.persist) == null ? void 0 : _a.plugin);
|
|
623
704
|
const { table, config } = parseLocalConfig(persist);
|
|
624
|
-
|
|
705
|
+
syncStateValue.numPendingLocalLoads = (syncStateValue.numPendingLocalLoads || 0) + 1;
|
|
625
706
|
if (!PersistPlugin) {
|
|
626
707
|
throw new Error("Local persist is not configured");
|
|
627
708
|
}
|
|
@@ -655,7 +736,7 @@ async function loadLocal(value$, syncOptions, syncState, localState) {
|
|
|
655
736
|
if (metadata) {
|
|
656
737
|
metadatas.set(value$, metadata);
|
|
657
738
|
localState.pendingChanges = metadata.pending;
|
|
658
|
-
syncState
|
|
739
|
+
syncState$.assign({
|
|
659
740
|
lastSync: metadata.lastSync
|
|
660
741
|
});
|
|
661
742
|
}
|
|
@@ -673,12 +754,18 @@ async function loadLocal(value$, syncOptions, syncState, localState) {
|
|
|
673
754
|
}
|
|
674
755
|
state.internal.globalState.isLoadingLocal = false;
|
|
675
756
|
}
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
757
|
+
syncStateValue.numPendingLocalLoads--;
|
|
758
|
+
nodeValue.clearPersist = () => Promise.all(
|
|
759
|
+
[
|
|
760
|
+
prevClearPersist,
|
|
761
|
+
persistPlugin.deleteTable(table, config),
|
|
762
|
+
persistPlugin.deleteMetadata(table, config)
|
|
763
|
+
].filter(Boolean)
|
|
764
|
+
);
|
|
765
|
+
} else {
|
|
766
|
+
nodeValue.clearPersist = () => prevClearPersist == null ? void 0 : prevClearPersist();
|
|
680
767
|
}
|
|
681
|
-
syncState
|
|
768
|
+
syncState$.isPersistLoaded.set(!(syncStateValue.numPendingLocalLoads > 0));
|
|
682
769
|
}
|
|
683
770
|
function syncObservable(obs$, syncOptionsOrSynced) {
|
|
684
771
|
let syncOptions = syncOptionsOrSynced;
|
|
@@ -689,7 +776,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
689
776
|
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && (!obs$ || !node)) {
|
|
690
777
|
throw new Error("[legend-state] syncObservable called with undefined observable");
|
|
691
778
|
}
|
|
692
|
-
syncOptions =
|
|
779
|
+
syncOptions = deepMerge(
|
|
693
780
|
{
|
|
694
781
|
syncMode: "auto"
|
|
695
782
|
},
|
|
@@ -698,24 +785,50 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
698
785
|
);
|
|
699
786
|
const localState = {};
|
|
700
787
|
let sync;
|
|
701
|
-
const syncState =
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
}
|
|
710
|
-
loadLocal(obs$, syncOptions, syncState
|
|
711
|
-
|
|
788
|
+
const syncState$ = state.syncState(obs$);
|
|
789
|
+
const syncStateValue = getNodeValue(getNode(syncState$));
|
|
790
|
+
allSyncStates.set(syncState$, node);
|
|
791
|
+
syncStateValue.getPendingChanges = () => localState.pendingChanges;
|
|
792
|
+
const onGetError = (error, params) => {
|
|
793
|
+
var _a;
|
|
794
|
+
syncState$.error.set(error);
|
|
795
|
+
(_a = syncOptions.onGetError) == null ? void 0 : _a.call(syncOptions, error, { ...params, value$: obs$ });
|
|
796
|
+
};
|
|
797
|
+
loadLocal(obs$, syncOptions, syncState$, localState);
|
|
798
|
+
let isWaitingForLoad = !!syncOptions.get;
|
|
799
|
+
if (isWaitingForLoad) {
|
|
800
|
+
syncStateValue.numPendingRemoteLoads = (syncStateValue.numPendingRemoteLoads || 0) + 1;
|
|
801
|
+
}
|
|
802
|
+
syncState$.isLoaded.set(!syncState$.numPendingRemoteLoads.peek());
|
|
803
|
+
let isSynced = false;
|
|
804
|
+
let isSubscribed = false;
|
|
805
|
+
let unsubscribe = void 0;
|
|
806
|
+
const applyPending = (pending) => {
|
|
807
|
+
if (pending && !state.isEmpty(pending)) {
|
|
808
|
+
localState.isApplyingPending = true;
|
|
809
|
+
const keys = Object.keys(pending);
|
|
810
|
+
const changes = [];
|
|
811
|
+
for (let i = 0; i < keys.length; i++) {
|
|
812
|
+
const key = keys[i];
|
|
813
|
+
const path = key.split("/").filter((p2) => p2 !== "");
|
|
814
|
+
const { p, v, t } = pending[key];
|
|
815
|
+
changes.push({ path, valueAtPath: v, prevAtPath: p, pathTypes: t });
|
|
816
|
+
}
|
|
817
|
+
const value = getNodeValue(node);
|
|
818
|
+
onObsChange(obs$, syncState$, localState, syncOptions, {
|
|
819
|
+
value,
|
|
820
|
+
isFromPersist: false,
|
|
821
|
+
isFromSync: false,
|
|
822
|
+
getPrevious: createPreviousHandler(value, changes),
|
|
823
|
+
changes
|
|
824
|
+
});
|
|
825
|
+
localState.isApplyingPending = false;
|
|
826
|
+
}
|
|
827
|
+
};
|
|
712
828
|
if (syncOptions.get) {
|
|
713
|
-
let isSynced = false;
|
|
714
|
-
let isSubscribed = false;
|
|
715
|
-
let unsubscribe = void 0;
|
|
716
829
|
sync = async () => {
|
|
717
|
-
var _a
|
|
718
|
-
if (isSynced && state.shouldIgnoreUnobserved(node, sync)) {
|
|
830
|
+
var _a;
|
|
831
|
+
if (isSynced && (!getNodeValue(getNode(syncState$)).isSyncEnabled || state.shouldIgnoreUnobserved(node, sync))) {
|
|
719
832
|
if (unsubscribe) {
|
|
720
833
|
isSubscribed = false;
|
|
721
834
|
unsubscribe();
|
|
@@ -725,9 +838,11 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
725
838
|
}
|
|
726
839
|
const lastSync = (_a = metadatas.get(obs$)) == null ? void 0 : _a.lastSync;
|
|
727
840
|
const pending = localState.pendingChanges;
|
|
728
|
-
const get =
|
|
841
|
+
const get = syncOptions.get;
|
|
729
842
|
if (get) {
|
|
843
|
+
const { waitFor } = syncOptions;
|
|
730
844
|
const runGet = () => {
|
|
845
|
+
var _a2;
|
|
731
846
|
const onChange = async ({ value, mode, lastSync: lastSync2 }) => {
|
|
732
847
|
mode = mode || syncOptions.mode || "set";
|
|
733
848
|
if (value !== void 0) {
|
|
@@ -740,9 +855,11 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
740
855
|
if (pending2) {
|
|
741
856
|
let didChangeMetadata = false;
|
|
742
857
|
Object.keys(pending2).forEach((key) => {
|
|
743
|
-
const p = key.split("/").filter((
|
|
858
|
+
const p = key.split("/").filter((k) => k !== "");
|
|
744
859
|
const { v, t } = pending2[key];
|
|
745
860
|
if (t.length === 0 || !value) {
|
|
861
|
+
const oldValue = clone(value);
|
|
862
|
+
pending2[key].p = oldValue;
|
|
746
863
|
if (state.isObject(value) && state.isObject(v)) {
|
|
747
864
|
Object.assign(value, v);
|
|
748
865
|
} else {
|
|
@@ -755,6 +872,8 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
755
872
|
delete pending2[key];
|
|
756
873
|
didChangeMetadata = true;
|
|
757
874
|
} else {
|
|
875
|
+
const oldValue = clone(value);
|
|
876
|
+
pending2[key].p = getValueAtPath(oldValue, p);
|
|
758
877
|
value = state.setAtPath(
|
|
759
878
|
value,
|
|
760
879
|
p,
|
|
@@ -774,18 +893,24 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
774
893
|
}
|
|
775
894
|
}
|
|
776
895
|
});
|
|
777
|
-
if (didChangeMetadata) {
|
|
778
|
-
updateMetadata(obs$, localState, syncState
|
|
896
|
+
if (didChangeMetadata && syncOptions.persist) {
|
|
897
|
+
updateMetadata(obs$, localState, syncState$, syncOptions, {
|
|
779
898
|
pending: pending2
|
|
780
899
|
});
|
|
781
900
|
}
|
|
782
901
|
}
|
|
783
902
|
onChangeRemote(() => {
|
|
784
|
-
if (mode === "assign"
|
|
903
|
+
if (mode === "assign") {
|
|
785
904
|
obs$.assign(value);
|
|
786
|
-
} else if (mode === "append"
|
|
905
|
+
} else if (mode === "append") {
|
|
906
|
+
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && !state.isArray(value)) {
|
|
907
|
+
console.error("[legend-state] mode:append expects the value to be an array");
|
|
908
|
+
}
|
|
787
909
|
obs$.push(...value);
|
|
788
|
-
} else if (mode === "prepend"
|
|
910
|
+
} else if (mode === "prepend") {
|
|
911
|
+
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && !state.isArray(value)) {
|
|
912
|
+
console.error("[legend-state] mode:prepend expects the value to be an array");
|
|
913
|
+
}
|
|
789
914
|
obs$.splice(0, 0, ...value);
|
|
790
915
|
} else if (mode === "merge") {
|
|
791
916
|
state.mergeIntoObservable(obs$, value);
|
|
@@ -795,78 +920,162 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
795
920
|
});
|
|
796
921
|
}
|
|
797
922
|
if (lastSync2 && syncOptions.persist) {
|
|
798
|
-
updateMetadata(obs$, localState, syncState
|
|
923
|
+
updateMetadata(obs$, localState, syncState$, syncOptions, {
|
|
799
924
|
lastSync: lastSync2
|
|
800
925
|
});
|
|
801
926
|
}
|
|
802
927
|
};
|
|
803
|
-
|
|
804
|
-
|
|
928
|
+
if (node.activationState) {
|
|
929
|
+
node.activationState.onChange = onChange;
|
|
930
|
+
}
|
|
931
|
+
if (!isSubscribed && syncOptions.subscribe) {
|
|
932
|
+
const subscribe = syncOptions.subscribe;
|
|
933
|
+
isSubscribed = true;
|
|
934
|
+
const doSubscribe = () => {
|
|
935
|
+
const subscribeParams = {
|
|
936
|
+
node,
|
|
937
|
+
value$: obs$,
|
|
938
|
+
lastSync,
|
|
939
|
+
update: (params) => {
|
|
940
|
+
state.when(syncState$.isLoaded, () => {
|
|
941
|
+
state.when(waitFor || true, () => {
|
|
942
|
+
params.mode || (params.mode = syncOptions.mode || "merge");
|
|
943
|
+
onChange(params);
|
|
944
|
+
});
|
|
945
|
+
});
|
|
946
|
+
},
|
|
947
|
+
refresh: () => state.when(syncState$.isLoaded, sync),
|
|
948
|
+
onError: (error) => onGetError(error, { source: "subscribe", subscribeParams })
|
|
949
|
+
};
|
|
950
|
+
unsubscribe = subscribe(subscribeParams);
|
|
951
|
+
};
|
|
952
|
+
if (waitFor) {
|
|
953
|
+
state.whenReady(waitFor, doSubscribe);
|
|
954
|
+
} else {
|
|
955
|
+
doSubscribe();
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
const existingValue = getNodeValue(node);
|
|
959
|
+
const onError = (error) => onGetError(error, { getParams, source: "get" });
|
|
960
|
+
const getParams = {
|
|
961
|
+
node,
|
|
805
962
|
value$: obs$,
|
|
963
|
+
value: state.isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked]) ? void 0 : existingValue,
|
|
964
|
+
mode: syncOptions.mode,
|
|
965
|
+
refresh: sync,
|
|
806
966
|
options: syncOptions,
|
|
807
967
|
lastSync,
|
|
808
|
-
|
|
809
|
-
onError
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
968
|
+
updateLastSync: (lastSync2) => getParams.lastSync = lastSync2,
|
|
969
|
+
onError,
|
|
970
|
+
retryNum: 0,
|
|
971
|
+
cancelRetry: false
|
|
972
|
+
};
|
|
973
|
+
let modeBeforeReset = void 0;
|
|
974
|
+
(_a2 = syncOptions.onBeforeGet) == null ? void 0 : _a2.call(syncOptions, {
|
|
975
|
+
value: getParams.value,
|
|
976
|
+
lastSync,
|
|
977
|
+
pendingChanges: pending && !state.isEmpty(pending) ? pending : void 0,
|
|
978
|
+
clearPendingChanges: async () => {
|
|
979
|
+
localState.pendingChanges = {};
|
|
980
|
+
await updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
|
|
981
|
+
pending: localState.pendingChanges
|
|
817
982
|
});
|
|
818
983
|
},
|
|
819
|
-
|
|
984
|
+
resetCache: () => {
|
|
985
|
+
var _a3;
|
|
986
|
+
modeBeforeReset = getParams.mode;
|
|
987
|
+
getParams.mode = "set";
|
|
988
|
+
return (_a3 = syncStateValue.clearPersist) == null ? void 0 : _a3.call(syncStateValue);
|
|
989
|
+
}
|
|
820
990
|
});
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
991
|
+
syncState$.assign({
|
|
992
|
+
numPendingGets: (syncStateValue.numPendingGets || 0) + 1,
|
|
993
|
+
isGetting: true
|
|
994
|
+
});
|
|
995
|
+
const got = runWithRetry(
|
|
996
|
+
getParams,
|
|
997
|
+
syncOptions.retry,
|
|
998
|
+
(retryEvent) => {
|
|
999
|
+
const params = getParams;
|
|
1000
|
+
params.cancelRetry = retryEvent.cancelRetry;
|
|
1001
|
+
params.retryNum = retryEvent.retryNum;
|
|
1002
|
+
return get(params);
|
|
1003
|
+
},
|
|
1004
|
+
onError
|
|
1005
|
+
);
|
|
1006
|
+
const numGets = node.numGets = (node.numGets || 0) + 1;
|
|
1007
|
+
const handle = (value) => {
|
|
1008
|
+
syncState$.numPendingGets.set((v) => v - 1);
|
|
1009
|
+
if (isWaitingForLoad) {
|
|
1010
|
+
isWaitingForLoad = false;
|
|
1011
|
+
syncStateValue.numPendingRemoteLoads--;
|
|
1012
|
+
}
|
|
1013
|
+
if (numGets >= (node.getNumResolved || 0)) {
|
|
1014
|
+
node.getNumResolved = node.numGets;
|
|
1015
|
+
onChange({
|
|
1016
|
+
value,
|
|
1017
|
+
lastSync: getParams.lastSync,
|
|
1018
|
+
mode: getParams.mode
|
|
1019
|
+
});
|
|
1020
|
+
}
|
|
1021
|
+
if (modeBeforeReset) {
|
|
1022
|
+
getParams.mode = modeBeforeReset;
|
|
1023
|
+
modeBeforeReset = void 0;
|
|
1024
|
+
}
|
|
1025
|
+
syncState$.assign({
|
|
1026
|
+
isLoaded: syncStateValue.numPendingRemoteLoads < 1,
|
|
1027
|
+
error: void 0,
|
|
1028
|
+
isGetting: syncStateValue.numPendingGets > 0
|
|
833
1029
|
});
|
|
1030
|
+
};
|
|
1031
|
+
if (state.isPromise(got)) {
|
|
1032
|
+
got.then(handle);
|
|
1033
|
+
} else {
|
|
1034
|
+
handle(got);
|
|
834
1035
|
}
|
|
835
1036
|
};
|
|
836
|
-
|
|
1037
|
+
if (waitFor) {
|
|
1038
|
+
state.whenReady(waitFor, () => state.trackSelector(runGet, sync));
|
|
1039
|
+
} else {
|
|
1040
|
+
state.trackSelector(runGet, sync);
|
|
1041
|
+
}
|
|
837
1042
|
} else {
|
|
838
|
-
|
|
1043
|
+
syncState$.assign({
|
|
839
1044
|
isLoaded: true,
|
|
840
1045
|
error: void 0
|
|
841
1046
|
});
|
|
842
1047
|
}
|
|
843
1048
|
if (!isSynced) {
|
|
844
1049
|
isSynced = true;
|
|
845
|
-
await state.when(
|
|
846
|
-
|
|
847
|
-
localState.isApplyingPending = true;
|
|
848
|
-
const keys = Object.keys(pending);
|
|
849
|
-
const changes = [];
|
|
850
|
-
for (let i = 0; i < keys.length; i++) {
|
|
851
|
-
const key = keys[i];
|
|
852
|
-
const path = key.split("/").filter((p2) => p2 !== "");
|
|
853
|
-
const { p, v, t } = pending[key];
|
|
854
|
-
changes.push({ path, valueAtPath: v, prevAtPath: p, pathTypes: t });
|
|
855
|
-
}
|
|
856
|
-
const value = getNodeValue(node);
|
|
857
|
-
onObsChange(obs$, syncState, localState, syncOptions, {
|
|
858
|
-
value,
|
|
859
|
-
loading: false,
|
|
860
|
-
remote: false,
|
|
861
|
-
getPrevious: createPreviousHandler(value, changes),
|
|
862
|
-
changes
|
|
863
|
-
});
|
|
864
|
-
localState.isApplyingPending = false;
|
|
865
|
-
}
|
|
1050
|
+
await state.when(syncState$.isLoaded);
|
|
1051
|
+
applyPending(pending);
|
|
866
1052
|
}
|
|
867
1053
|
};
|
|
868
|
-
|
|
1054
|
+
syncStateValue.sync = sync;
|
|
1055
|
+
} else {
|
|
1056
|
+
if (!isSynced) {
|
|
1057
|
+
applyPending(localState.pendingChanges);
|
|
1058
|
+
}
|
|
869
1059
|
}
|
|
1060
|
+
syncStateValue.reset = async () => {
|
|
1061
|
+
var _a;
|
|
1062
|
+
const wasPersistEnabled = syncStateValue.isPersistEnabled;
|
|
1063
|
+
const wasSyncEnabled = syncStateValue.isSyncEnabled;
|
|
1064
|
+
syncStateValue.isPersistEnabled = false;
|
|
1065
|
+
syncStateValue.isSyncEnabled = false;
|
|
1066
|
+
syncStateValue.syncCount = 0;
|
|
1067
|
+
isSynced = false;
|
|
1068
|
+
isSubscribed = false;
|
|
1069
|
+
unsubscribe == null ? void 0 : unsubscribe();
|
|
1070
|
+
unsubscribe = void 0;
|
|
1071
|
+
const promise = syncStateValue.clearPersist();
|
|
1072
|
+
obs$.set((_a = syncOptions.initial) != null ? _a : void 0);
|
|
1073
|
+
syncState$.isLoaded.set(false);
|
|
1074
|
+
syncStateValue.isPersistEnabled = wasPersistEnabled;
|
|
1075
|
+
syncStateValue.isSyncEnabled = wasSyncEnabled;
|
|
1076
|
+
node.dirtyFn = sync;
|
|
1077
|
+
await promise;
|
|
1078
|
+
};
|
|
870
1079
|
const onAllPersistLoaded = () => {
|
|
871
1080
|
var _a, _b;
|
|
872
1081
|
let parentNode = node;
|
|
@@ -884,77 +1093,27 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
884
1093
|
}
|
|
885
1094
|
if ((syncOptions == null ? void 0 : syncOptions.set) || (syncOptions == null ? void 0 : syncOptions.persist)) {
|
|
886
1095
|
obs$.onChange(
|
|
887
|
-
onObsChange.bind(this, obs$, syncState
|
|
1096
|
+
onObsChange.bind(this, obs$, syncState$, localState, syncOptions)
|
|
888
1097
|
);
|
|
889
1098
|
}
|
|
890
1099
|
});
|
|
891
|
-
return syncState
|
|
1100
|
+
return syncState$;
|
|
892
1101
|
}
|
|
893
|
-
var { getProxy, globalState: globalState2,
|
|
1102
|
+
var { getProxy, globalState: globalState2, setNodeValue, getNodeValue: getNodeValue2 } = state.internal;
|
|
894
1103
|
function enableActivateSyncedNode() {
|
|
895
1104
|
globalState2.activateSyncedNode = function activateSyncedNode(node, newValue) {
|
|
896
1105
|
const obs$ = getProxy(node);
|
|
897
1106
|
if (node.activationState) {
|
|
898
|
-
const {
|
|
899
|
-
|
|
900
|
-
|
|
1107
|
+
const {
|
|
1108
|
+
get: getOrig,
|
|
1109
|
+
initial,
|
|
1110
|
+
set,
|
|
1111
|
+
onChange
|
|
1112
|
+
} = node.activationState;
|
|
901
1113
|
let promiseReturn = void 0;
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
pluginRemote.get = (params) => {
|
|
906
|
-
var _a;
|
|
907
|
-
onChange = params.onChange;
|
|
908
|
-
const updateLastSync = (lastSync) => params.lastSync = lastSync;
|
|
909
|
-
const existingValue = getNodeValue2(node);
|
|
910
|
-
const value = runWithRetry(node, { attemptNum: 0, retry: retry || ((_a = params.options) == null ? void 0 : _a.retry) }, () => {
|
|
911
|
-
const paramsToGet = {
|
|
912
|
-
value: state.isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked2]) ? void 0 : existingValue,
|
|
913
|
-
lastSync: params.lastSync,
|
|
914
|
-
updateLastSync,
|
|
915
|
-
mode: params.mode,
|
|
916
|
-
refresh
|
|
917
|
-
};
|
|
918
|
-
const ret = get(paramsToGet);
|
|
919
|
-
params.mode = paramsToGet.mode;
|
|
920
|
-
return ret;
|
|
921
|
-
});
|
|
922
|
-
promiseReturn = value;
|
|
923
|
-
return value;
|
|
924
|
-
};
|
|
925
|
-
}
|
|
926
|
-
if (set) {
|
|
927
|
-
pluginRemote.set = async (params) => {
|
|
928
|
-
var _a, _b;
|
|
929
|
-
if ((_a = node.state) == null ? void 0 : _a.isLoaded.get()) {
|
|
930
|
-
const retryAttempts = { attemptNum: 0, retry: retry || ((_b = params.options) == null ? void 0 : _b.retry) };
|
|
931
|
-
return runWithRetry(node, retryAttempts, async (retryEvent) => {
|
|
932
|
-
let changes = {};
|
|
933
|
-
let maxModified = 0;
|
|
934
|
-
if (!node.state.isLoaded.peek()) {
|
|
935
|
-
await state.whenReady(node.state.isLoaded);
|
|
936
|
-
}
|
|
937
|
-
const cancelRetry = () => {
|
|
938
|
-
retryEvent.cancel = true;
|
|
939
|
-
};
|
|
940
|
-
await set({
|
|
941
|
-
...params,
|
|
942
|
-
node,
|
|
943
|
-
update: (params2) => {
|
|
944
|
-
const { value, lastSync } = params2;
|
|
945
|
-
maxModified = Math.max(lastSync || 0, maxModified);
|
|
946
|
-
changes = state.mergeIntoObservable(changes, value);
|
|
947
|
-
},
|
|
948
|
-
retryNum: retryAttempts.attemptNum,
|
|
949
|
-
cancelRetry,
|
|
950
|
-
refresh,
|
|
951
|
-
fromSubscribe: false
|
|
952
|
-
});
|
|
953
|
-
return { changes, lastSync: maxModified || void 0 };
|
|
954
|
-
});
|
|
955
|
-
}
|
|
956
|
-
};
|
|
957
|
-
}
|
|
1114
|
+
const get = getOrig ? (params) => {
|
|
1115
|
+
return promiseReturn = getOrig(params);
|
|
1116
|
+
} : void 0;
|
|
958
1117
|
const nodeVal = getNodeValue2(node);
|
|
959
1118
|
if (promiseReturn !== void 0) {
|
|
960
1119
|
newValue = promiseReturn;
|
|
@@ -964,7 +1123,7 @@ function enableActivateSyncedNode() {
|
|
|
964
1123
|
newValue = initial;
|
|
965
1124
|
}
|
|
966
1125
|
setNodeValue(node, promiseReturn ? void 0 : newValue);
|
|
967
|
-
|
|
1126
|
+
syncObservable(obs$, { ...node.activationState, get, set });
|
|
968
1127
|
return { update: onChange, value: newValue };
|
|
969
1128
|
} else {
|
|
970
1129
|
let update = void 0;
|
|
@@ -1001,21 +1160,27 @@ function installPersistActivateNode() {
|
|
|
1001
1160
|
didInstall = true;
|
|
1002
1161
|
}
|
|
1003
1162
|
}
|
|
1163
|
+
var { deepMerge: deepMerge2 } = state.internal;
|
|
1164
|
+
function configureSynced(fnOrOrigOptions, origOptions) {
|
|
1165
|
+
const fn = origOptions ? fnOrOrigOptions : void 0;
|
|
1166
|
+
origOptions = origOptions != null ? origOptions : fnOrOrigOptions;
|
|
1167
|
+
return (options) => {
|
|
1168
|
+
const merged = deepMerge2(origOptions, options);
|
|
1169
|
+
return fn ? fn(merged) : merged;
|
|
1170
|
+
};
|
|
1171
|
+
}
|
|
1004
1172
|
|
|
1005
1173
|
// sync.ts
|
|
1006
|
-
|
|
1007
|
-
return state.internal.globalState.isLoadingRemote;
|
|
1008
|
-
}
|
|
1009
|
-
var internal3 = {
|
|
1174
|
+
var internal4 = {
|
|
1010
1175
|
observableSyncConfiguration
|
|
1011
1176
|
};
|
|
1012
1177
|
|
|
1013
1178
|
exports.combineTransforms = combineTransforms;
|
|
1014
1179
|
exports.configureObservableSync = configureObservableSync;
|
|
1180
|
+
exports.configureSynced = configureSynced;
|
|
1015
1181
|
exports.deepEqual = deepEqual;
|
|
1016
1182
|
exports.diffObjects = diffObjects;
|
|
1017
|
-
exports.internal =
|
|
1018
|
-
exports.isInRemoteChange = isInRemoteChange;
|
|
1183
|
+
exports.internal = internal4;
|
|
1019
1184
|
exports.mapSyncPlugins = mapSyncPlugins;
|
|
1020
1185
|
exports.onChangeRemote = onChangeRemote;
|
|
1021
1186
|
exports.removeNullUndefined = removeNullUndefined;
|