@legendapp/state 3.0.0-alpha.9 → 3.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.DS_Store +0 -0
- package/config/configureLegendState.d.mts +13 -0
- package/config/configureLegendState.d.ts +13 -0
- package/config/configureLegendState.js +45 -0
- package/config/configureLegendState.mjs +43 -0
- 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/helpers/trackHistory.js +2 -2
- package/helpers/trackHistory.mjs +2 -2
- package/index.d.mts +103 -79
- package/index.d.ts +103 -79
- package/index.js +326 -316
- package/index.mjs +323 -314
- package/package.json +36 -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 +8 -4
- package/persist-plugins/async-storage.mjs +8 -5
- package/persist-plugins/indexeddb.d.mts +6 -4
- package/persist-plugins/indexeddb.d.ts +6 -4
- package/persist-plugins/indexeddb.js +35 -15
- package/persist-plugins/indexeddb.mjs +35 -16
- package/persist-plugins/mmkv.d.mts +5 -1
- package/persist-plugins/mmkv.d.ts +5 -1
- package/persist-plugins/mmkv.js +10 -5
- package/persist-plugins/mmkv.mjs +10 -6
- package/react-reactive/enableReactComponents.d.mts +9 -0
- package/react-reactive/enableReactComponents.d.ts +9 -0
- package/react-reactive/enableReactComponents.js +19 -0
- package/react-reactive/enableReactComponents.mjs +17 -0
- package/react-reactive/enableReactNativeComponents.d.mts +22 -0
- package/react-reactive/enableReactNativeComponents.d.ts +22 -0
- package/react-reactive/enableReactNativeComponents.js +53 -0
- package/react-reactive/enableReactNativeComponents.mjs +51 -0
- package/react-reactive/enableReactive.d.mts +5 -0
- package/react-reactive/enableReactive.d.ts +5 -0
- package/react-reactive/enableReactive.js +24 -0
- package/react-reactive/enableReactive.mjs +22 -0
- package/react-reactive/enableReactive.native.d.mts +5 -0
- package/react-reactive/enableReactive.native.d.ts +5 -0
- package/react-reactive/enableReactive.native.js +58 -0
- package/react-reactive/enableReactive.native.mjs +56 -0
- package/react-reactive/enableReactive.web.d.mts +5 -0
- package/react-reactive/enableReactive.web.d.ts +5 -0
- package/react-reactive/enableReactive.web.js +58 -0
- package/react-reactive/enableReactive.web.mjs +56 -0
- package/react.d.mts +39 -34
- package/react.d.ts +39 -34
- package/react.js +39 -17
- package/react.mjs +39 -17
- package/sync-plugins/crud.d.mts +21 -23
- package/sync-plugins/crud.d.ts +21 -23
- package/sync-plugins/crud.js +224 -112
- package/sync-plugins/crud.mjs +226 -114
- package/sync-plugins/fetch.js +12 -8
- package/sync-plugins/fetch.mjs +13 -9
- package/sync-plugins/firebase.d.mts +27 -0
- package/sync-plugins/firebase.d.ts +27 -0
- package/sync-plugins/firebase.js +373 -0
- package/sync-plugins/firebase.mjs +368 -0
- package/sync-plugins/keel.d.mts +43 -26
- package/sync-plugins/keel.d.ts +43 -26
- package/sync-plugins/keel.js +145 -99
- package/sync-plugins/keel.mjs +147 -99
- package/sync-plugins/supabase.d.mts +19 -9
- package/sync-plugins/supabase.d.ts +19 -9
- package/sync-plugins/supabase.js +52 -21
- package/sync-plugins/supabase.mjs +53 -22
- package/sync-plugins/tanstack-query.d.mts +2 -2
- package/sync-plugins/tanstack-query.d.ts +2 -2
- package/sync-plugins/tanstack-query.js +22 -5
- package/sync-plugins/tanstack-query.mjs +22 -5
- package/sync-plugins/tanstack-react-query.d.mts +1 -1
- package/sync-plugins/tanstack-react-query.d.ts +1 -1
- package/sync-plugins/tanstack-react-query.js +8 -1
- package/sync-plugins/tanstack-react-query.mjs +8 -1
- package/sync.d.mts +74 -200
- package/sync.d.ts +74 -200
- package/sync.js +498 -281
- package/sync.mjs +503 -286
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,84 @@ function transformStringifyDates(...args) {
|
|
|
139
137
|
}
|
|
140
138
|
};
|
|
141
139
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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;
|
|
152
|
+
}
|
|
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;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
var mapRetryTimeouts = /* @__PURE__ */ new Map();
|
|
164
|
+
function runWithRetry(state, retryOptions, fn, onError) {
|
|
165
|
+
try {
|
|
166
|
+
let value = fn(state);
|
|
167
|
+
if (isPromise(value) && retryOptions) {
|
|
168
|
+
let timeoutRetry;
|
|
169
|
+
if (mapRetryTimeouts.has(state.node)) {
|
|
170
|
+
clearTimeout(mapRetryTimeouts.get(state.node));
|
|
158
171
|
}
|
|
159
|
-
|
|
172
|
+
return new Promise((resolve, reject) => {
|
|
173
|
+
const run = () => {
|
|
174
|
+
value.then((val) => {
|
|
175
|
+
resolve(val);
|
|
176
|
+
}).catch((error) => {
|
|
177
|
+
state.retryNum++;
|
|
178
|
+
if (timeoutRetry) {
|
|
179
|
+
clearTimeout(timeoutRetry);
|
|
180
|
+
}
|
|
181
|
+
if (onError) {
|
|
182
|
+
onError(error, state);
|
|
183
|
+
}
|
|
184
|
+
if (!state.cancelRetry) {
|
|
185
|
+
const timeout = createRetryTimeout(retryOptions, state.retryNum, () => {
|
|
186
|
+
value = fn(state);
|
|
187
|
+
run();
|
|
188
|
+
});
|
|
189
|
+
if (timeout === false) {
|
|
190
|
+
state.cancelRetry = true;
|
|
191
|
+
reject(error);
|
|
192
|
+
} else {
|
|
193
|
+
mapRetryTimeouts.set(state.node, timeout);
|
|
194
|
+
timeoutRetry = timeout;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
};
|
|
199
|
+
run();
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
return value;
|
|
203
|
+
} catch (error) {
|
|
204
|
+
return Promise.reject(error);
|
|
160
205
|
}
|
|
161
|
-
|
|
162
|
-
|
|
206
|
+
}
|
|
207
|
+
async function waitForSet(waitForSet2, changes, value, params = {}) {
|
|
208
|
+
const waitFn = state.isFunction(waitForSet2) ? waitForSet2({ changes, value, ...params }) : waitForSet2;
|
|
209
|
+
if (waitFn) {
|
|
210
|
+
await state.when(waitFn);
|
|
163
211
|
}
|
|
164
|
-
return ret;
|
|
165
212
|
}
|
|
166
213
|
|
|
167
214
|
// src/sync/syncObservable.ts
|
|
168
|
-
var {
|
|
215
|
+
var { clone, deepMerge, getNode, getNodeValue, getValueAtPath, globalState, symbolLinked, createPreviousHandler } = state.internal;
|
|
169
216
|
var mapSyncPlugins = /* @__PURE__ */ new WeakMap();
|
|
217
|
+
var allSyncStates = /* @__PURE__ */ new Map();
|
|
170
218
|
var metadatas = /* @__PURE__ */ new WeakMap();
|
|
171
219
|
var promisesLocalSaves = /* @__PURE__ */ new Set();
|
|
172
220
|
function parseLocalConfig(config) {
|
|
@@ -183,13 +231,19 @@ function onChangeRemote(cb) {
|
|
|
183
231
|
globalState.isLoadingRemote = false;
|
|
184
232
|
state.endBatch(true);
|
|
185
233
|
}
|
|
186
|
-
function transformSaveData(value, path, pathTypes, { transform }) {
|
|
234
|
+
async function transformSaveData(value, path, pathTypes, { transform }) {
|
|
187
235
|
if (transform == null ? void 0 : transform.save) {
|
|
188
236
|
const constructed = state.constructObjectWithPath(path, pathTypes, value);
|
|
189
|
-
const saved = transform.save(constructed);
|
|
190
|
-
value =
|
|
237
|
+
const saved = await transform.save(constructed);
|
|
238
|
+
value = saved;
|
|
239
|
+
const outPath = [];
|
|
240
|
+
for (let i = 0; i < path.length; i++) {
|
|
241
|
+
outPath[i] = Object.keys(value)[0];
|
|
242
|
+
value = value[outPath[i]];
|
|
243
|
+
}
|
|
244
|
+
path = outPath;
|
|
191
245
|
}
|
|
192
|
-
return value;
|
|
246
|
+
return { value, path };
|
|
193
247
|
}
|
|
194
248
|
function transformLoadData(value, { transform }, doUserTransform, method) {
|
|
195
249
|
if (doUserTransform && (transform == null ? void 0 : transform.load)) {
|
|
@@ -197,13 +251,13 @@ function transformLoadData(value, { transform }, doUserTransform, method) {
|
|
|
197
251
|
}
|
|
198
252
|
return value;
|
|
199
253
|
}
|
|
200
|
-
async function updateMetadataImmediate(value$, localState,
|
|
254
|
+
async function updateMetadataImmediate(value$, localState, syncState2, syncOptions, newMetadata) {
|
|
201
255
|
const saves = Array.from(promisesLocalSaves);
|
|
202
256
|
if (saves.length > 0) {
|
|
203
257
|
await Promise.all(saves);
|
|
204
258
|
}
|
|
205
259
|
const { pluginPersist } = localState;
|
|
206
|
-
const { table, config } = parseLocalConfig(syncOptions
|
|
260
|
+
const { table, config } = parseLocalConfig(syncOptions.persist);
|
|
207
261
|
const oldMetadata = metadatas.get(value$);
|
|
208
262
|
const { lastSync } = newMetadata;
|
|
209
263
|
const metadata = Object.assign({}, oldMetadata, newMetadata);
|
|
@@ -212,17 +266,17 @@ async function updateMetadataImmediate(value$, localState, syncState, syncOption
|
|
|
212
266
|
await pluginPersist.setMetadata(table, metadata, config);
|
|
213
267
|
}
|
|
214
268
|
if (lastSync) {
|
|
215
|
-
|
|
269
|
+
syncState2.assign({
|
|
216
270
|
lastSync
|
|
217
271
|
});
|
|
218
272
|
}
|
|
219
273
|
}
|
|
220
|
-
function updateMetadata(value$, localState,
|
|
274
|
+
function updateMetadata(value$, localState, syncState2, syncOptions, newMetadata) {
|
|
221
275
|
if (localState.timeoutSaveMetadata) {
|
|
222
276
|
clearTimeout(localState.timeoutSaveMetadata);
|
|
223
277
|
}
|
|
224
278
|
localState.timeoutSaveMetadata = setTimeout(
|
|
225
|
-
() => updateMetadataImmediate(value$, localState,
|
|
279
|
+
() => updateMetadataImmediate(value$, localState, syncState2, syncOptions, newMetadata),
|
|
226
280
|
0
|
|
227
281
|
);
|
|
228
282
|
}
|
|
@@ -250,26 +304,21 @@ function mergeChanges(changes) {
|
|
|
250
304
|
return changesOut;
|
|
251
305
|
}
|
|
252
306
|
function mergeQueuedChanges(allChanges) {
|
|
253
|
-
const
|
|
254
|
-
const
|
|
255
|
-
const previousByObs = /* @__PURE__ */ new Map();
|
|
307
|
+
const changesByOptionsRemote = /* @__PURE__ */ new Map();
|
|
308
|
+
const changesByOptionsLocal = /* @__PURE__ */ new Map();
|
|
256
309
|
const outRemote = /* @__PURE__ */ new Map();
|
|
257
310
|
const outLocal = /* @__PURE__ */ new Map();
|
|
258
311
|
for (let i = 0; i < allChanges.length; i++) {
|
|
259
312
|
const value = allChanges[i];
|
|
260
|
-
const {
|
|
313
|
+
const { changes, inRemoteChange, syncOptions } = value;
|
|
261
314
|
const targetMap = inRemoteChange ? outRemote : outLocal;
|
|
262
|
-
const changesMap = inRemoteChange ?
|
|
263
|
-
const existing = changesMap.get(
|
|
315
|
+
const changesMap = inRemoteChange ? changesByOptionsRemote : changesByOptionsLocal;
|
|
316
|
+
const existing = changesMap.get(syncOptions);
|
|
264
317
|
const newChanges = existing ? [...existing, ...changes] : changes;
|
|
265
318
|
const merged = mergeChanges(newChanges);
|
|
266
|
-
changesMap.set(
|
|
319
|
+
changesMap.set(syncOptions, merged);
|
|
267
320
|
value.changes = merged;
|
|
268
|
-
|
|
269
|
-
previousByObs.set(obs, getPrevious());
|
|
270
|
-
}
|
|
271
|
-
value.valuePrevious = previousByObs.get(obs);
|
|
272
|
-
targetMap.set(obs, value);
|
|
321
|
+
targetMap.set(syncOptions, value);
|
|
273
322
|
}
|
|
274
323
|
return Array.from(outRemote.values()).concat(Array.from(outLocal.values()));
|
|
275
324
|
}
|
|
@@ -315,15 +364,13 @@ async function processQueuedRemoteChanges(syncOptions) {
|
|
|
315
364
|
}
|
|
316
365
|
}
|
|
317
366
|
async function prepChangeLocal(queuedChange) {
|
|
318
|
-
const { syncState, changes,
|
|
367
|
+
const { syncState: syncState2, changes, syncOptions, inRemoteChange, isApplyingPending } = queuedChange;
|
|
319
368
|
const persist = syncOptions.persist;
|
|
320
|
-
const { pluginSync } = localState;
|
|
321
369
|
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());
|
|
370
|
+
const saveLocal = (persist == null ? void 0 : persist.name) && !configLocal.readonly && !isApplyingPending && syncState2.isPersistEnabled.peek();
|
|
371
|
+
const saveRemote = !!(!inRemoteChange && (syncOptions == null ? void 0 : syncOptions.set) && syncState2.isSyncEnabled.peek());
|
|
325
372
|
if (saveLocal || saveRemote) {
|
|
326
|
-
if (saveLocal && !
|
|
373
|
+
if (saveLocal && !syncState2.isPersistLoaded.peek()) {
|
|
327
374
|
console.error(
|
|
328
375
|
"[legend-state] WARNING: An observable was changed before being loaded from persist",
|
|
329
376
|
persist
|
|
@@ -356,13 +403,13 @@ async function prepChangeLocal(queuedChange) {
|
|
|
356
403
|
configLocal
|
|
357
404
|
);
|
|
358
405
|
promisesTransform.push(
|
|
359
|
-
doInOrder(promiseTransformLocal, (valueTransformed) => {
|
|
406
|
+
doInOrder(promiseTransformLocal, ({ value: valueTransformed, path: pathTransformed }) => {
|
|
360
407
|
changesLocal.push({
|
|
361
|
-
path,
|
|
408
|
+
path: pathTransformed,
|
|
362
409
|
pathTypes,
|
|
363
410
|
prevAtPath,
|
|
364
411
|
valueAtPath: valueTransformed,
|
|
365
|
-
pathStr
|
|
412
|
+
pathStr: path === pathTransformed ? pathStr : pathTransformed.join("/")
|
|
366
413
|
});
|
|
367
414
|
})
|
|
368
415
|
);
|
|
@@ -378,22 +425,19 @@ async function prepChangeLocal(queuedChange) {
|
|
|
378
425
|
}
|
|
379
426
|
async function prepChangeRemote(queuedChange) {
|
|
380
427
|
const {
|
|
381
|
-
syncState,
|
|
428
|
+
syncState: syncState2,
|
|
382
429
|
changes,
|
|
383
430
|
localState,
|
|
384
431
|
syncOptions,
|
|
385
432
|
inRemoteChange,
|
|
386
|
-
isApplyingPending
|
|
387
|
-
valuePrevious
|
|
433
|
+
isApplyingPending
|
|
388
434
|
} = queuedChange;
|
|
389
435
|
const persist = syncOptions.persist;
|
|
390
|
-
const { pluginSync } = localState;
|
|
391
436
|
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();
|
|
437
|
+
const saveLocal = persist && !configLocal.readonly && !isApplyingPending && syncState2.isPersistEnabled.peek();
|
|
438
|
+
const saveRemote = !inRemoteChange && (syncOptions == null ? void 0 : syncOptions.set) && syncState2.isSyncEnabled.peek();
|
|
395
439
|
if (saveLocal || saveRemote) {
|
|
396
|
-
if (saveLocal && !
|
|
440
|
+
if (saveLocal && !syncState2.isPersistLoaded.peek()) {
|
|
397
441
|
console.error(
|
|
398
442
|
"[legend-state] WARNING: An observable was changed before being loaded from persist",
|
|
399
443
|
persist
|
|
@@ -423,20 +467,20 @@ async function prepChangeRemote(queuedChange) {
|
|
|
423
467
|
valueAtPath,
|
|
424
468
|
path,
|
|
425
469
|
pathTypes,
|
|
426
|
-
|
|
470
|
+
syncOptions || {}
|
|
427
471
|
);
|
|
428
472
|
promisesTransform.push(
|
|
429
|
-
doInOrder(promiseTransformRemote, (valueTransformed) => {
|
|
473
|
+
doInOrder(promiseTransformRemote, ({ value: valueTransformed, path: pathTransformed }) => {
|
|
430
474
|
var _a;
|
|
431
475
|
if (!localState.pendingChanges) {
|
|
432
476
|
localState.pendingChanges = {};
|
|
433
477
|
}
|
|
434
478
|
let found2 = false;
|
|
435
|
-
for (let i2 = 0; !found2 && i2 <
|
|
436
|
-
const pathParent =
|
|
479
|
+
for (let i2 = 0; !found2 && i2 < pathTransformed.length - 1; i2++) {
|
|
480
|
+
const pathParent = pathTransformed.slice(0, i2 + 1).join("/");
|
|
437
481
|
if ((_a = localState.pendingChanges[pathParent]) == null ? void 0 : _a.v) {
|
|
438
482
|
found2 = true;
|
|
439
|
-
const pathChild =
|
|
483
|
+
const pathChild = pathTransformed.slice(i2 + 1);
|
|
440
484
|
const pathTypesChild = pathTypes.slice(i2 + 1);
|
|
441
485
|
state.setAtPath(
|
|
442
486
|
localState.pendingChanges[pathParent].v,
|
|
@@ -458,12 +502,11 @@ async function prepChangeRemote(queuedChange) {
|
|
|
458
502
|
localState.pendingChanges[pathStr].v = valueAtPath;
|
|
459
503
|
}
|
|
460
504
|
changesRemote.push({
|
|
461
|
-
path,
|
|
505
|
+
path: pathTransformed,
|
|
462
506
|
pathTypes,
|
|
463
507
|
prevAtPath,
|
|
464
508
|
valueAtPath: valueTransformed,
|
|
465
|
-
pathStr
|
|
466
|
-
valuePrevious
|
|
509
|
+
pathStr
|
|
467
510
|
});
|
|
468
511
|
})
|
|
469
512
|
);
|
|
@@ -481,7 +524,7 @@ async function doChangeLocal(changeInfo) {
|
|
|
481
524
|
if (!changeInfo)
|
|
482
525
|
return;
|
|
483
526
|
const { queuedChange, changesLocal, saveRemote } = changeInfo;
|
|
484
|
-
const { value$: obs, syncState, localState, syncOptions } = queuedChange;
|
|
527
|
+
const { value$: obs, syncState: syncState2, localState, syncOptions } = queuedChange;
|
|
485
528
|
const { pluginPersist } = localState;
|
|
486
529
|
const persist = syncOptions.persist;
|
|
487
530
|
const saveLocal = !!(persist == null ? void 0 : persist.name);
|
|
@@ -489,7 +532,7 @@ async function doChangeLocal(changeInfo) {
|
|
|
489
532
|
const { table, config: configLocal } = parseLocalConfig(persist);
|
|
490
533
|
const shouldSaveMetadata = persist == null ? void 0 : persist.retrySync;
|
|
491
534
|
if (saveRemote && shouldSaveMetadata) {
|
|
492
|
-
await updateMetadataImmediate(obs, localState,
|
|
535
|
+
await updateMetadataImmediate(obs, localState, syncState2, syncOptions, {
|
|
493
536
|
pending: localState.pendingChanges
|
|
494
537
|
});
|
|
495
538
|
}
|
|
@@ -510,88 +553,151 @@ async function doChangeRemote(changeInfo) {
|
|
|
510
553
|
if (!changeInfo)
|
|
511
554
|
return;
|
|
512
555
|
const { queuedChange, changesRemote } = changeInfo;
|
|
513
|
-
const { value$: obs
|
|
514
|
-
const { pluginPersist
|
|
556
|
+
const { value$: obs$, syncState: syncState2, localState, syncOptions } = queuedChange;
|
|
557
|
+
const { pluginPersist } = localState;
|
|
558
|
+
const node = getNode(obs$);
|
|
559
|
+
const state$ = node.state;
|
|
515
560
|
const persist = syncOptions.persist;
|
|
516
561
|
const { table, config: configLocal } = parseLocalConfig(persist);
|
|
517
|
-
const {
|
|
562
|
+
const { onBeforeSet, waitForSet: waitForSetParam, onAfterSet } = syncOptions || {};
|
|
518
563
|
const shouldSaveMetadata = persist == null ? void 0 : persist.retrySync;
|
|
519
564
|
const saveLocal = !!(persist == null ? void 0 : persist.name);
|
|
520
565
|
if (changesRemote.length > 0) {
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
const
|
|
524
|
-
if (
|
|
525
|
-
|
|
566
|
+
if (!syncState2.isLoaded.peek()) {
|
|
567
|
+
await state.when(syncState2.isLoaded);
|
|
568
|
+
const pending = localState.pendingChanges;
|
|
569
|
+
if (pending) {
|
|
570
|
+
changesRemote.forEach((change) => {
|
|
571
|
+
const key = change.pathStr;
|
|
572
|
+
const pendingAtPath = pending[key];
|
|
573
|
+
if (!state.isNullOrUndefined(pendingAtPath)) {
|
|
574
|
+
const { p } = pendingAtPath;
|
|
575
|
+
change.prevAtPath = p;
|
|
576
|
+
}
|
|
577
|
+
});
|
|
526
578
|
}
|
|
527
579
|
}
|
|
528
|
-
|
|
580
|
+
if (waitForSetParam) {
|
|
581
|
+
await waitForSet(waitForSetParam, changesRemote, obs$.peek());
|
|
582
|
+
}
|
|
583
|
+
let value = clone(obs$.peek());
|
|
529
584
|
const transformSave = (_a = syncOptions == null ? void 0 : syncOptions.transform) == null ? void 0 : _a.save;
|
|
530
585
|
if (transformSave) {
|
|
531
586
|
value = transformSave(value);
|
|
532
587
|
}
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
588
|
+
state$.numPendingSets.set((v) => (v || 0) + 1);
|
|
589
|
+
state$.isSetting.set(true);
|
|
590
|
+
const beforeSetParams = {
|
|
591
|
+
cancel: false
|
|
592
|
+
};
|
|
593
|
+
onBeforeSet == null ? void 0 : onBeforeSet(beforeSetParams);
|
|
594
|
+
if (!beforeSetParams.cancel) {
|
|
595
|
+
let updateResult = void 0;
|
|
596
|
+
let errorHandled = false;
|
|
597
|
+
const onError = (error, retryParams) => {
|
|
598
|
+
var _a2;
|
|
599
|
+
state$.error.set(error);
|
|
600
|
+
if (!errorHandled) {
|
|
601
|
+
(_a2 = syncOptions.onError) == null ? void 0 : _a2.call(syncOptions, error, {
|
|
602
|
+
setParams,
|
|
603
|
+
source: "set",
|
|
604
|
+
value$: obs$,
|
|
605
|
+
retryParams
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
errorHandled = true;
|
|
609
|
+
};
|
|
610
|
+
const setParams = {
|
|
611
|
+
node,
|
|
612
|
+
value$: obs$,
|
|
613
|
+
changes: changesRemote,
|
|
614
|
+
value,
|
|
615
|
+
onError,
|
|
616
|
+
update: (params) => {
|
|
617
|
+
if (updateResult) {
|
|
618
|
+
const { value: value2, lastSync, mode } = params;
|
|
619
|
+
updateResult = {
|
|
620
|
+
lastSync: Math.max(updateResult.lastSync || 0, lastSync || 0),
|
|
621
|
+
value: deepMerge(updateResult.value, value2),
|
|
622
|
+
mode
|
|
623
|
+
};
|
|
624
|
+
} else {
|
|
625
|
+
updateResult = params;
|
|
626
|
+
}
|
|
627
|
+
},
|
|
628
|
+
refresh: syncState2.sync,
|
|
629
|
+
retryNum: 0,
|
|
630
|
+
cancelRetry: false
|
|
631
|
+
};
|
|
632
|
+
const savedPromise = runWithRetry(
|
|
633
|
+
setParams,
|
|
634
|
+
syncOptions.retry,
|
|
635
|
+
async () => {
|
|
636
|
+
return syncOptions.set(setParams);
|
|
637
|
+
},
|
|
638
|
+
onError
|
|
639
|
+
);
|
|
640
|
+
let didError = false;
|
|
641
|
+
if (state.isPromise(savedPromise)) {
|
|
642
|
+
await savedPromise.catch((error) => {
|
|
643
|
+
didError = true;
|
|
644
|
+
if (!syncOptions.retry) {
|
|
645
|
+
onError(error);
|
|
646
|
+
}
|
|
647
|
+
});
|
|
648
|
+
}
|
|
649
|
+
if (!didError) {
|
|
650
|
+
const pathStrs = Array.from(new Set(changesRemote.map((change) => change.pathStr)));
|
|
651
|
+
const { value: changes, lastSync } = updateResult || {};
|
|
652
|
+
if (pathStrs.length > 0) {
|
|
653
|
+
let transformedChanges = void 0;
|
|
654
|
+
const metadata = {};
|
|
655
|
+
if (saveLocal) {
|
|
656
|
+
const pendingMetadata = (_b = pluginPersist.getMetadata(table, configLocal)) == null ? void 0 : _b.pending;
|
|
657
|
+
const pending = localState.pendingChanges;
|
|
658
|
+
for (let i = 0; i < pathStrs.length; i++) {
|
|
659
|
+
const pathStr = pathStrs[i];
|
|
660
|
+
if (pendingMetadata == null ? void 0 : pendingMetadata[pathStr]) {
|
|
661
|
+
delete pendingMetadata[pathStr];
|
|
662
|
+
metadata.pending = pendingMetadata;
|
|
663
|
+
}
|
|
664
|
+
if (pending == null ? void 0 : pending[pathStr]) {
|
|
665
|
+
delete pending[pathStr];
|
|
666
|
+
}
|
|
560
667
|
}
|
|
561
|
-
if (
|
|
562
|
-
|
|
668
|
+
if (lastSync) {
|
|
669
|
+
metadata.lastSync = lastSync;
|
|
563
670
|
}
|
|
564
671
|
}
|
|
565
|
-
if (
|
|
566
|
-
|
|
672
|
+
if (changes && !state.isEmpty(changes)) {
|
|
673
|
+
transformedChanges = transformLoadData(changes, syncOptions, false, "set");
|
|
567
674
|
}
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
if (state.isPromise(transformedChanges)) {
|
|
574
|
-
transformedChanges = await transformedChanges;
|
|
675
|
+
if (transformedChanges !== void 0) {
|
|
676
|
+
if (state.isPromise(transformedChanges)) {
|
|
677
|
+
transformedChanges = await transformedChanges;
|
|
678
|
+
}
|
|
679
|
+
onChangeRemote(() => state.mergeIntoObservable(obs$, transformedChanges));
|
|
575
680
|
}
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
updateMetadata(obs, localState, syncState, syncOptions, metadata);
|
|
681
|
+
if (saveLocal) {
|
|
682
|
+
if (shouldSaveMetadata && !state.isEmpty(metadata)) {
|
|
683
|
+
updateMetadata(obs$, localState, syncState2, syncOptions, metadata);
|
|
684
|
+
}
|
|
581
685
|
}
|
|
582
686
|
}
|
|
687
|
+
state$.numPendingSets.set((v) => v - 1);
|
|
688
|
+
state$.isSetting.set(state$.numPendingSets.peek() > 0);
|
|
583
689
|
onAfterSet == null ? void 0 : onAfterSet();
|
|
584
690
|
}
|
|
585
691
|
}
|
|
586
692
|
}
|
|
587
693
|
}
|
|
588
|
-
function onObsChange(value$,
|
|
589
|
-
if (!
|
|
590
|
-
const inRemoteChange =
|
|
694
|
+
function onObsChange(value$, syncState2, localState, syncOptions, { changes, isFromPersist, isFromSync, getPrevious }) {
|
|
695
|
+
if (!isFromPersist) {
|
|
696
|
+
const inRemoteChange = isFromSync;
|
|
591
697
|
const isApplyingPending = localState.isApplyingPending;
|
|
592
698
|
_queuedChanges.push({
|
|
593
699
|
value$,
|
|
594
|
-
syncState,
|
|
700
|
+
syncState: syncState2,
|
|
595
701
|
localState,
|
|
596
702
|
syncOptions,
|
|
597
703
|
changes,
|
|
@@ -604,19 +710,22 @@ function onObsChange(value$, syncState, localState, syncOptions, { changes, load
|
|
|
604
710
|
}
|
|
605
711
|
}
|
|
606
712
|
}
|
|
607
|
-
async function loadLocal(value$, syncOptions, syncState
|
|
713
|
+
async function loadLocal(value$, syncOptions, syncState$, localState) {
|
|
608
714
|
var _a, _b, _c;
|
|
609
715
|
const { persist } = syncOptions;
|
|
610
716
|
const node = getNode(value$);
|
|
611
717
|
const nodeValue = getNodeValue(getNode(node.state));
|
|
718
|
+
const syncStateValue = syncState$.peek();
|
|
719
|
+
const prevResetPersistence = nodeValue.resetPersistence;
|
|
612
720
|
if (persist == null ? void 0 : persist.name) {
|
|
613
721
|
const PersistPlugin = persist.plugin || ((_a = observableSyncConfiguration.persist) == null ? void 0 : _a.plugin);
|
|
614
722
|
const { table, config } = parseLocalConfig(persist);
|
|
723
|
+
syncStateValue.numPendingLocalLoads = (syncStateValue.numPendingLocalLoads || 0) + 1;
|
|
615
724
|
if (!PersistPlugin) {
|
|
616
725
|
throw new Error("Local persist is not configured");
|
|
617
726
|
}
|
|
618
727
|
if (!mapSyncPlugins.has(PersistPlugin)) {
|
|
619
|
-
const persistPlugin2 = new PersistPlugin();
|
|
728
|
+
const persistPlugin2 = state.isFunction(PersistPlugin) ? new PersistPlugin() : PersistPlugin;
|
|
620
729
|
const mapValue = { plugin: persistPlugin2, initialized: state.observable(false) };
|
|
621
730
|
mapSyncPlugins.set(PersistPlugin, mapValue);
|
|
622
731
|
if (persistPlugin2.initialize) {
|
|
@@ -645,7 +754,7 @@ async function loadLocal(value$, syncOptions, syncState, localState) {
|
|
|
645
754
|
if (metadata) {
|
|
646
755
|
metadatas.set(value$, metadata);
|
|
647
756
|
localState.pendingChanges = metadata.pending;
|
|
648
|
-
syncState
|
|
757
|
+
syncState$.assign({
|
|
649
758
|
lastSync: metadata.lastSync
|
|
650
759
|
});
|
|
651
760
|
}
|
|
@@ -663,15 +772,19 @@ async function loadLocal(value$, syncOptions, syncState, localState) {
|
|
|
663
772
|
}
|
|
664
773
|
state.internal.globalState.isLoadingLocal = false;
|
|
665
774
|
}
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
775
|
+
syncStateValue.numPendingLocalLoads--;
|
|
776
|
+
nodeValue.resetPersistence = () => Promise.all(
|
|
777
|
+
[
|
|
778
|
+
prevResetPersistence,
|
|
779
|
+
persistPlugin.deleteTable(table, config),
|
|
780
|
+
persistPlugin.deleteMetadata(table, config)
|
|
781
|
+
].filter(Boolean)
|
|
782
|
+
);
|
|
670
783
|
} else {
|
|
671
|
-
nodeValue.
|
|
672
|
-
};
|
|
784
|
+
nodeValue.resetPersistence = () => prevResetPersistence == null ? void 0 : prevResetPersistence();
|
|
673
785
|
}
|
|
674
|
-
|
|
786
|
+
nodeValue.clearPersist = nodeValue.resetPersistence;
|
|
787
|
+
syncState$.isPersistLoaded.set(!(syncStateValue.numPendingLocalLoads > 0));
|
|
675
788
|
}
|
|
676
789
|
function syncObservable(obs$, syncOptionsOrSynced) {
|
|
677
790
|
let syncOptions = syncOptionsOrSynced;
|
|
@@ -682,7 +795,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
682
795
|
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && (!obs$ || !node)) {
|
|
683
796
|
throw new Error("[legend-state] syncObservable called with undefined observable");
|
|
684
797
|
}
|
|
685
|
-
syncOptions =
|
|
798
|
+
syncOptions = deepMerge(
|
|
686
799
|
{
|
|
687
800
|
syncMode: "auto"
|
|
688
801
|
},
|
|
@@ -691,24 +804,54 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
691
804
|
);
|
|
692
805
|
const localState = {};
|
|
693
806
|
let sync;
|
|
694
|
-
const syncState =
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
807
|
+
const syncState$ = state.syncState(obs$);
|
|
808
|
+
const syncStateValue = getNodeValue(getNode(syncState$));
|
|
809
|
+
allSyncStates.set(syncState$, node);
|
|
810
|
+
syncStateValue.getPendingChanges = () => localState.pendingChanges;
|
|
811
|
+
let errorHandled = false;
|
|
812
|
+
const onGetError = (error, params) => {
|
|
813
|
+
var _a;
|
|
814
|
+
syncState$.error.set(error);
|
|
815
|
+
if (!errorHandled) {
|
|
816
|
+
(_a = syncOptions.onError) == null ? void 0 : _a.call(syncOptions, error, { ...params, value$: obs$ });
|
|
817
|
+
}
|
|
818
|
+
errorHandled = true;
|
|
819
|
+
};
|
|
820
|
+
loadLocal(obs$, syncOptions, syncState$, localState);
|
|
821
|
+
let isWaitingForLoad = !!syncOptions.get;
|
|
822
|
+
if (isWaitingForLoad) {
|
|
823
|
+
syncStateValue.numPendingRemoteLoads = (syncStateValue.numPendingRemoteLoads || 0) + 1;
|
|
824
|
+
}
|
|
825
|
+
syncState$.isLoaded.set(!syncState$.numPendingRemoteLoads.peek());
|
|
826
|
+
let isSynced = false;
|
|
827
|
+
let isSubscribed = false;
|
|
828
|
+
let unsubscribe = void 0;
|
|
829
|
+
const applyPending = (pending) => {
|
|
830
|
+
if (pending && !state.isEmpty(pending)) {
|
|
831
|
+
localState.isApplyingPending = true;
|
|
832
|
+
const keys = Object.keys(pending);
|
|
833
|
+
const changes = [];
|
|
834
|
+
for (let i = 0; i < keys.length; i++) {
|
|
835
|
+
const key = keys[i];
|
|
836
|
+
const path = key.split("/").filter((p2) => p2 !== "");
|
|
837
|
+
const { p, v, t } = pending[key];
|
|
838
|
+
changes.push({ path, valueAtPath: v, prevAtPath: p, pathTypes: t });
|
|
839
|
+
}
|
|
840
|
+
const value = getNodeValue(node);
|
|
841
|
+
onObsChange(obs$, syncState$, localState, syncOptions, {
|
|
842
|
+
value,
|
|
843
|
+
isFromPersist: false,
|
|
844
|
+
isFromSync: false,
|
|
845
|
+
getPrevious: createPreviousHandler(value, changes),
|
|
846
|
+
changes
|
|
847
|
+
});
|
|
848
|
+
localState.isApplyingPending = false;
|
|
849
|
+
}
|
|
850
|
+
};
|
|
705
851
|
if (syncOptions.get) {
|
|
706
|
-
let isSynced = false;
|
|
707
|
-
let isSubscribed = false;
|
|
708
|
-
let unsubscribe = void 0;
|
|
709
852
|
sync = async () => {
|
|
710
|
-
var _a
|
|
711
|
-
if (isSynced && state.shouldIgnoreUnobserved(node, sync)) {
|
|
853
|
+
var _a;
|
|
854
|
+
if (isSynced && (!getNodeValue(getNode(syncState$)).isSyncEnabled || state.shouldIgnoreUnobserved(node, sync))) {
|
|
712
855
|
if (unsubscribe) {
|
|
713
856
|
isSubscribed = false;
|
|
714
857
|
unsubscribe();
|
|
@@ -718,9 +861,11 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
718
861
|
}
|
|
719
862
|
const lastSync = (_a = metadatas.get(obs$)) == null ? void 0 : _a.lastSync;
|
|
720
863
|
const pending = localState.pendingChanges;
|
|
721
|
-
const get =
|
|
864
|
+
const get = syncOptions.get;
|
|
722
865
|
if (get) {
|
|
866
|
+
const { waitFor } = syncOptions;
|
|
723
867
|
const runGet = () => {
|
|
868
|
+
var _a2;
|
|
724
869
|
const onChange = async ({ value, mode, lastSync: lastSync2 }) => {
|
|
725
870
|
mode = mode || syncOptions.mode || "set";
|
|
726
871
|
if (value !== void 0) {
|
|
@@ -733,9 +878,11 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
733
878
|
if (pending2) {
|
|
734
879
|
let didChangeMetadata = false;
|
|
735
880
|
Object.keys(pending2).forEach((key) => {
|
|
736
|
-
const p = key.split("/").filter((
|
|
881
|
+
const p = key.split("/").filter((k) => k !== "");
|
|
737
882
|
const { v, t } = pending2[key];
|
|
738
883
|
if (t.length === 0 || !value) {
|
|
884
|
+
const oldValue = clone(value);
|
|
885
|
+
pending2[key].p = oldValue;
|
|
739
886
|
if (state.isObject(value) && state.isObject(v)) {
|
|
740
887
|
Object.assign(value, v);
|
|
741
888
|
} else {
|
|
@@ -748,6 +895,8 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
748
895
|
delete pending2[key];
|
|
749
896
|
didChangeMetadata = true;
|
|
750
897
|
} else {
|
|
898
|
+
const oldValue = clone(value);
|
|
899
|
+
pending2[key].p = getValueAtPath(oldValue, p);
|
|
751
900
|
value = state.setAtPath(
|
|
752
901
|
value,
|
|
753
902
|
p,
|
|
@@ -767,18 +916,27 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
767
916
|
}
|
|
768
917
|
}
|
|
769
918
|
});
|
|
770
|
-
if (didChangeMetadata) {
|
|
771
|
-
updateMetadata(obs$, localState, syncState
|
|
919
|
+
if (didChangeMetadata && syncOptions.persist) {
|
|
920
|
+
updateMetadata(obs$, localState, syncState$, syncOptions, {
|
|
772
921
|
pending: pending2
|
|
773
922
|
});
|
|
774
923
|
}
|
|
775
924
|
}
|
|
776
925
|
onChangeRemote(() => {
|
|
777
|
-
if (
|
|
926
|
+
if (state.isPlainObject(value)) {
|
|
927
|
+
value = state.ObservableHint.plain(value);
|
|
928
|
+
}
|
|
929
|
+
if (mode === "assign") {
|
|
778
930
|
obs$.assign(value);
|
|
779
|
-
} else if (mode === "append"
|
|
931
|
+
} else if (mode === "append") {
|
|
932
|
+
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && !state.isArray(value)) {
|
|
933
|
+
console.error("[legend-state] mode:append expects the value to be an array");
|
|
934
|
+
}
|
|
780
935
|
obs$.push(...value);
|
|
781
|
-
} else if (mode === "prepend"
|
|
936
|
+
} else if (mode === "prepend") {
|
|
937
|
+
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && !state.isArray(value)) {
|
|
938
|
+
console.error("[legend-state] mode:prepend expects the value to be an array");
|
|
939
|
+
}
|
|
782
940
|
obs$.splice(0, 0, ...value);
|
|
783
941
|
} else if (mode === "merge") {
|
|
784
942
|
state.mergeIntoObservable(obs$, value);
|
|
@@ -788,78 +946,180 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
788
946
|
});
|
|
789
947
|
}
|
|
790
948
|
if (lastSync2 && syncOptions.persist) {
|
|
791
|
-
updateMetadata(obs$, localState, syncState
|
|
949
|
+
updateMetadata(obs$, localState, syncState$, syncOptions, {
|
|
792
950
|
lastSync: lastSync2
|
|
793
951
|
});
|
|
794
952
|
}
|
|
795
953
|
};
|
|
796
|
-
|
|
797
|
-
|
|
954
|
+
if (node.activationState) {
|
|
955
|
+
node.activationState.onChange = onChange;
|
|
956
|
+
}
|
|
957
|
+
if (!isSubscribed && syncOptions.subscribe) {
|
|
958
|
+
const subscribe = syncOptions.subscribe;
|
|
959
|
+
isSubscribed = true;
|
|
960
|
+
const doSubscribe = () => {
|
|
961
|
+
const subscribeParams = {
|
|
962
|
+
node,
|
|
963
|
+
value$: obs$,
|
|
964
|
+
lastSync,
|
|
965
|
+
update: (params) => {
|
|
966
|
+
state.when(syncState$.isLoaded, () => {
|
|
967
|
+
state.when(waitFor || true, () => {
|
|
968
|
+
params.mode || (params.mode = syncOptions.mode || "merge");
|
|
969
|
+
onChange(params);
|
|
970
|
+
});
|
|
971
|
+
});
|
|
972
|
+
},
|
|
973
|
+
refresh: () => state.when(syncState$.isLoaded, sync),
|
|
974
|
+
onError: (error) => onGetError(error, { source: "subscribe", subscribeParams })
|
|
975
|
+
};
|
|
976
|
+
unsubscribe = subscribe(subscribeParams);
|
|
977
|
+
};
|
|
978
|
+
if (waitFor) {
|
|
979
|
+
state.whenReady(waitFor, doSubscribe);
|
|
980
|
+
} else {
|
|
981
|
+
doSubscribe();
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
const existingValue = getNodeValue(node);
|
|
985
|
+
const onError = (error) => onGetError(error, { getParams, source: "get" });
|
|
986
|
+
const getParams = {
|
|
987
|
+
node,
|
|
798
988
|
value$: obs$,
|
|
989
|
+
value: state.isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked]) ? void 0 : existingValue,
|
|
990
|
+
mode: syncOptions.mode,
|
|
991
|
+
refresh: sync,
|
|
799
992
|
options: syncOptions,
|
|
800
993
|
lastSync,
|
|
801
|
-
|
|
802
|
-
onError
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
994
|
+
updateLastSync: (lastSync2) => getParams.lastSync = lastSync2,
|
|
995
|
+
onError,
|
|
996
|
+
retryNum: 0,
|
|
997
|
+
cancelRetry: false
|
|
998
|
+
};
|
|
999
|
+
let modeBeforeReset = void 0;
|
|
1000
|
+
const beforeGetParams = {
|
|
1001
|
+
value: getParams.value,
|
|
1002
|
+
lastSync,
|
|
1003
|
+
pendingChanges: pending && !state.isEmpty(pending) ? pending : void 0,
|
|
1004
|
+
clearPendingChanges: async () => {
|
|
1005
|
+
localState.pendingChanges = {};
|
|
1006
|
+
await updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
|
|
1007
|
+
pending: localState.pendingChanges
|
|
810
1008
|
});
|
|
811
1009
|
},
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
refresh: () => state.when(node.state.isLoaded, sync)
|
|
1010
|
+
resetCache: () => {
|
|
1011
|
+
var _a3;
|
|
1012
|
+
modeBeforeReset = getParams.mode;
|
|
1013
|
+
getParams.mode = "set";
|
|
1014
|
+
return (_a3 = syncStateValue.resetPersistence) == null ? void 0 : _a3.call(syncStateValue);
|
|
1015
|
+
},
|
|
1016
|
+
cancel: false
|
|
1017
|
+
};
|
|
1018
|
+
(_a2 = syncOptions.onBeforeGet) == null ? void 0 : _a2.call(syncOptions, beforeGetParams);
|
|
1019
|
+
if (!beforeGetParams.cancel) {
|
|
1020
|
+
syncState$.assign({
|
|
1021
|
+
numPendingGets: (syncStateValue.numPendingGets || 0) + 1,
|
|
1022
|
+
isGetting: true
|
|
826
1023
|
});
|
|
1024
|
+
const got = runWithRetry(
|
|
1025
|
+
getParams,
|
|
1026
|
+
syncOptions.retry,
|
|
1027
|
+
(retryEvent) => {
|
|
1028
|
+
const params = getParams;
|
|
1029
|
+
params.cancelRetry = retryEvent.cancelRetry;
|
|
1030
|
+
params.retryNum = retryEvent.retryNum;
|
|
1031
|
+
return get(params);
|
|
1032
|
+
},
|
|
1033
|
+
onError
|
|
1034
|
+
);
|
|
1035
|
+
const numGets = node.numGets = (node.numGets || 0) + 1;
|
|
1036
|
+
const handle = (value) => {
|
|
1037
|
+
syncState$.numPendingGets.set((v) => v - 1);
|
|
1038
|
+
if (isWaitingForLoad) {
|
|
1039
|
+
isWaitingForLoad = false;
|
|
1040
|
+
syncStateValue.numPendingRemoteLoads--;
|
|
1041
|
+
}
|
|
1042
|
+
if (numGets >= (node.getNumResolved || 0)) {
|
|
1043
|
+
node.getNumResolved = node.numGets;
|
|
1044
|
+
onChange({
|
|
1045
|
+
value,
|
|
1046
|
+
lastSync: getParams.lastSync,
|
|
1047
|
+
mode: getParams.mode
|
|
1048
|
+
});
|
|
1049
|
+
}
|
|
1050
|
+
if (modeBeforeReset) {
|
|
1051
|
+
getParams.mode = modeBeforeReset;
|
|
1052
|
+
modeBeforeReset = void 0;
|
|
1053
|
+
}
|
|
1054
|
+
syncState$.assign({
|
|
1055
|
+
isLoaded: syncStateValue.numPendingRemoteLoads < 1,
|
|
1056
|
+
error: void 0,
|
|
1057
|
+
isGetting: syncStateValue.numPendingGets > 0
|
|
1058
|
+
});
|
|
1059
|
+
};
|
|
1060
|
+
if (state.isPromise(got)) {
|
|
1061
|
+
got.then(handle).catch(onError);
|
|
1062
|
+
} else {
|
|
1063
|
+
handle(got);
|
|
1064
|
+
}
|
|
827
1065
|
}
|
|
828
1066
|
};
|
|
829
|
-
|
|
1067
|
+
if (waitFor) {
|
|
1068
|
+
state.whenReady(waitFor, () => state.trackSelector(runGet, sync));
|
|
1069
|
+
} else {
|
|
1070
|
+
state.trackSelector(runGet, sync);
|
|
1071
|
+
}
|
|
830
1072
|
} else {
|
|
831
|
-
|
|
1073
|
+
syncState$.assign({
|
|
832
1074
|
isLoaded: true,
|
|
833
1075
|
error: void 0
|
|
834
1076
|
});
|
|
835
1077
|
}
|
|
836
1078
|
if (!isSynced) {
|
|
837
1079
|
isSynced = true;
|
|
838
|
-
await state.when(
|
|
839
|
-
|
|
840
|
-
localState.isApplyingPending = true;
|
|
841
|
-
const keys = Object.keys(pending);
|
|
842
|
-
const changes = [];
|
|
843
|
-
for (let i = 0; i < keys.length; i++) {
|
|
844
|
-
const key = keys[i];
|
|
845
|
-
const path = key.split("/").filter((p2) => p2 !== "");
|
|
846
|
-
const { p, v, t } = pending[key];
|
|
847
|
-
changes.push({ path, valueAtPath: v, prevAtPath: p, pathTypes: t });
|
|
848
|
-
}
|
|
849
|
-
const value = getNodeValue(node);
|
|
850
|
-
onObsChange(obs$, syncState, localState, syncOptions, {
|
|
851
|
-
value,
|
|
852
|
-
loading: false,
|
|
853
|
-
remote: false,
|
|
854
|
-
getPrevious: createPreviousHandler(value, changes),
|
|
855
|
-
changes
|
|
856
|
-
});
|
|
857
|
-
localState.isApplyingPending = false;
|
|
858
|
-
}
|
|
1080
|
+
await state.when(syncState$.isLoaded);
|
|
1081
|
+
applyPending(pending);
|
|
859
1082
|
}
|
|
860
1083
|
};
|
|
861
|
-
|
|
1084
|
+
syncStateValue.sync = sync;
|
|
1085
|
+
} else {
|
|
1086
|
+
if (!isSynced) {
|
|
1087
|
+
applyPending(localState.pendingChanges);
|
|
1088
|
+
}
|
|
862
1089
|
}
|
|
1090
|
+
syncStateValue.reset = async () => {
|
|
1091
|
+
const wasPersistEnabled = syncStateValue.isPersistEnabled;
|
|
1092
|
+
const wasSyncEnabled = syncStateValue.isSyncEnabled;
|
|
1093
|
+
const metadata = metadatas.get(obs$);
|
|
1094
|
+
if (metadata) {
|
|
1095
|
+
Object.assign(metadata, { lastSync: void 0, pending: void 0 });
|
|
1096
|
+
}
|
|
1097
|
+
Object.assign(syncStateValue, {
|
|
1098
|
+
isPersistEnabled: false,
|
|
1099
|
+
isSyncEnabled: false,
|
|
1100
|
+
lastSync: void 0,
|
|
1101
|
+
numPendingGets: 0,
|
|
1102
|
+
isLoaded: false,
|
|
1103
|
+
isGetting: false,
|
|
1104
|
+
isSetting: false,
|
|
1105
|
+
numPendingSets: 0,
|
|
1106
|
+
syncCount: 0
|
|
1107
|
+
});
|
|
1108
|
+
isSynced = false;
|
|
1109
|
+
isSubscribed = false;
|
|
1110
|
+
unsubscribe == null ? void 0 : unsubscribe();
|
|
1111
|
+
unsubscribe = void 0;
|
|
1112
|
+
const promise = syncStateValue.resetPersistence();
|
|
1113
|
+
onChangeRemote(() => {
|
|
1114
|
+
var _a;
|
|
1115
|
+
obs$.set((_a = syncOptions.initial) != null ? _a : void 0);
|
|
1116
|
+
});
|
|
1117
|
+
syncState$.isLoaded.set(false);
|
|
1118
|
+
syncStateValue.isPersistEnabled = wasPersistEnabled;
|
|
1119
|
+
syncStateValue.isSyncEnabled = wasSyncEnabled;
|
|
1120
|
+
node.dirtyFn = sync;
|
|
1121
|
+
await promise;
|
|
1122
|
+
};
|
|
863
1123
|
const onAllPersistLoaded = () => {
|
|
864
1124
|
var _a, _b;
|
|
865
1125
|
let parentNode = node;
|
|
@@ -877,77 +1137,27 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
877
1137
|
}
|
|
878
1138
|
if ((syncOptions == null ? void 0 : syncOptions.set) || (syncOptions == null ? void 0 : syncOptions.persist)) {
|
|
879
1139
|
obs$.onChange(
|
|
880
|
-
onObsChange.bind(this, obs$, syncState
|
|
1140
|
+
onObsChange.bind(this, obs$, syncState$, localState, syncOptions)
|
|
881
1141
|
);
|
|
882
1142
|
}
|
|
883
1143
|
});
|
|
884
|
-
return syncState
|
|
1144
|
+
return syncState$;
|
|
885
1145
|
}
|
|
886
|
-
var { getProxy, globalState: globalState2,
|
|
1146
|
+
var { getProxy, globalState: globalState2, setNodeValue, getNodeValue: getNodeValue2 } = state.internal;
|
|
887
1147
|
function enableActivateSyncedNode() {
|
|
888
1148
|
globalState2.activateSyncedNode = function activateSyncedNode(node, newValue) {
|
|
889
1149
|
const obs$ = getProxy(node);
|
|
890
1150
|
if (node.activationState) {
|
|
891
|
-
const {
|
|
892
|
-
|
|
893
|
-
|
|
1151
|
+
const {
|
|
1152
|
+
get: getOrig,
|
|
1153
|
+
initial,
|
|
1154
|
+
set,
|
|
1155
|
+
onChange
|
|
1156
|
+
} = node.activationState;
|
|
894
1157
|
let promiseReturn = void 0;
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
pluginRemote.get = (params) => {
|
|
899
|
-
var _a;
|
|
900
|
-
onChange = params.onChange;
|
|
901
|
-
const updateLastSync = (lastSync) => params.lastSync = lastSync;
|
|
902
|
-
const existingValue = getNodeValue2(node);
|
|
903
|
-
const value = runWithRetry(node, { attemptNum: 0, retry: retry || ((_a = params.options) == null ? void 0 : _a.retry) }, () => {
|
|
904
|
-
const paramsToGet = {
|
|
905
|
-
value: state.isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked2]) ? void 0 : existingValue,
|
|
906
|
-
lastSync: params.lastSync,
|
|
907
|
-
updateLastSync,
|
|
908
|
-
mode: params.mode,
|
|
909
|
-
refresh
|
|
910
|
-
};
|
|
911
|
-
const ret = get(paramsToGet);
|
|
912
|
-
params.mode = paramsToGet.mode;
|
|
913
|
-
return ret;
|
|
914
|
-
});
|
|
915
|
-
promiseReturn = value;
|
|
916
|
-
return value;
|
|
917
|
-
};
|
|
918
|
-
}
|
|
919
|
-
if (set) {
|
|
920
|
-
pluginRemote.set = async (params) => {
|
|
921
|
-
var _a, _b;
|
|
922
|
-
if ((_a = node.state) == null ? void 0 : _a.isLoaded.get()) {
|
|
923
|
-
const retryAttempts = { attemptNum: 0, retry: retry || ((_b = params.options) == null ? void 0 : _b.retry) };
|
|
924
|
-
return runWithRetry(node, retryAttempts, async (retryEvent) => {
|
|
925
|
-
let changes = {};
|
|
926
|
-
let maxModified = 0;
|
|
927
|
-
if (!node.state.isLoaded.peek()) {
|
|
928
|
-
await state.whenReady(node.state.isLoaded);
|
|
929
|
-
}
|
|
930
|
-
const cancelRetry = () => {
|
|
931
|
-
retryEvent.cancel = true;
|
|
932
|
-
};
|
|
933
|
-
await set({
|
|
934
|
-
...params,
|
|
935
|
-
node,
|
|
936
|
-
update: (params2) => {
|
|
937
|
-
const { value, lastSync } = params2;
|
|
938
|
-
maxModified = Math.max(lastSync || 0, maxModified);
|
|
939
|
-
changes = state.mergeIntoObservable(changes, value);
|
|
940
|
-
},
|
|
941
|
-
retryNum: retryAttempts.attemptNum,
|
|
942
|
-
cancelRetry,
|
|
943
|
-
refresh,
|
|
944
|
-
fromSubscribe: false
|
|
945
|
-
});
|
|
946
|
-
return { changes, lastSync: maxModified || void 0 };
|
|
947
|
-
});
|
|
948
|
-
}
|
|
949
|
-
};
|
|
950
|
-
}
|
|
1158
|
+
const get = getOrig ? (params) => {
|
|
1159
|
+
return promiseReturn = getOrig(params);
|
|
1160
|
+
} : void 0;
|
|
951
1161
|
const nodeVal = getNodeValue2(node);
|
|
952
1162
|
if (promiseReturn !== void 0) {
|
|
953
1163
|
newValue = promiseReturn;
|
|
@@ -957,7 +1167,7 @@ function enableActivateSyncedNode() {
|
|
|
957
1167
|
newValue = initial;
|
|
958
1168
|
}
|
|
959
1169
|
setNodeValue(node, promiseReturn ? void 0 : newValue);
|
|
960
|
-
|
|
1170
|
+
syncObservable(obs$, { ...node.activationState, get, set });
|
|
961
1171
|
return { update: onChange, value: newValue };
|
|
962
1172
|
} else {
|
|
963
1173
|
let update = void 0;
|
|
@@ -994,21 +1204,28 @@ function installPersistActivateNode() {
|
|
|
994
1204
|
didInstall = true;
|
|
995
1205
|
}
|
|
996
1206
|
}
|
|
1207
|
+
var { deepMerge: deepMerge2 } = state.internal;
|
|
1208
|
+
function configureSynced(fnOrOrigOptions, origOptions) {
|
|
1209
|
+
const fn = origOptions ? fnOrOrigOptions : synced;
|
|
1210
|
+
origOptions = origOptions != null ? origOptions : fnOrOrigOptions;
|
|
1211
|
+
return (options) => {
|
|
1212
|
+
const merged = deepMerge2(origOptions, options);
|
|
1213
|
+
return fn(merged);
|
|
1214
|
+
};
|
|
1215
|
+
}
|
|
997
1216
|
|
|
998
1217
|
// sync.ts
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
var internal3 = {
|
|
1003
|
-
observableSyncConfiguration
|
|
1218
|
+
var internal4 = {
|
|
1219
|
+
observableSyncConfiguration,
|
|
1220
|
+
waitForSet
|
|
1004
1221
|
};
|
|
1005
1222
|
|
|
1006
1223
|
exports.combineTransforms = combineTransforms;
|
|
1007
1224
|
exports.configureObservableSync = configureObservableSync;
|
|
1225
|
+
exports.configureSynced = configureSynced;
|
|
1008
1226
|
exports.deepEqual = deepEqual;
|
|
1009
1227
|
exports.diffObjects = diffObjects;
|
|
1010
|
-
exports.internal =
|
|
1011
|
-
exports.isInRemoteChange = isInRemoteChange;
|
|
1228
|
+
exports.internal = internal4;
|
|
1012
1229
|
exports.mapSyncPlugins = mapSyncPlugins;
|
|
1013
1230
|
exports.onChangeRemote = onChangeRemote;
|
|
1014
1231
|
exports.removeNullUndefined = removeNullUndefined;
|