@legendapp/state 3.0.0-alpha.8 → 3.0.0-beta.0
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 +104 -80
- package/index.d.ts +104 -80
- package/index.js +328 -318
- package/index.mjs +325 -316
- 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 -24
- package/sync-plugins/crud.d.ts +21 -24
- package/sync-plugins/crud.js +241 -140
- package/sync-plugins/crud.mjs +243 -142
- 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 -100
- package/sync-plugins/keel.mjs +147 -100
- package/sync-plugins/supabase.d.mts +19 -9
- package/sync-plugins/supabase.d.ts +19 -9
- package/sync-plugins/supabase.js +52 -22
- package/sync-plugins/supabase.mjs +53 -23
- 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 +492 -293
- package/sync.mjs +498 -299
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,103 +553,148 @@ 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
|
-
value = transformSave(
|
|
532
|
-
}
|
|
533
|
-
onBeforeSet == null ? void 0 : onBeforeSet();
|
|
534
|
-
localState.numSavesOutstanding = (localState.numSavesOutstanding || 0) + 1;
|
|
535
|
-
let savedPromise = pluginSync.set({
|
|
536
|
-
value$: obs,
|
|
537
|
-
syncState,
|
|
538
|
-
options: syncOptions,
|
|
539
|
-
changes: changesRemote,
|
|
540
|
-
value,
|
|
541
|
-
valuePrevious: previous
|
|
542
|
-
});
|
|
543
|
-
if (state.isPromise(savedPromise)) {
|
|
544
|
-
savedPromise = savedPromise.catch((err) => onSetError == null ? void 0 : onSetError(err));
|
|
586
|
+
value = transformSave(value);
|
|
545
587
|
}
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
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(() => {
|
|
643
|
+
didError = true;
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
if (!didError) {
|
|
647
|
+
const pathStrs = Array.from(new Set(changesRemote.map((change) => change.pathStr)));
|
|
648
|
+
const { value: changes, lastSync } = updateResult || {};
|
|
649
|
+
if (pathStrs.length > 0) {
|
|
650
|
+
let transformedChanges = void 0;
|
|
651
|
+
const metadata = {};
|
|
652
|
+
if (saveLocal) {
|
|
653
|
+
const pendingMetadata = (_b = pluginPersist.getMetadata(table, configLocal)) == null ? void 0 : _b.pending;
|
|
654
|
+
const pending = localState.pendingChanges;
|
|
655
|
+
for (let i = 0; i < pathStrs.length; i++) {
|
|
656
|
+
const pathStr = pathStrs[i];
|
|
657
|
+
if (pendingMetadata == null ? void 0 : pendingMetadata[pathStr]) {
|
|
658
|
+
delete pendingMetadata[pathStr];
|
|
659
|
+
metadata.pending = pendingMetadata;
|
|
660
|
+
}
|
|
661
|
+
if (pending == null ? void 0 : pending[pathStr]) {
|
|
662
|
+
delete pending[pathStr];
|
|
663
|
+
}
|
|
562
664
|
}
|
|
563
|
-
if (
|
|
564
|
-
|
|
665
|
+
if (lastSync) {
|
|
666
|
+
metadata.lastSync = lastSync;
|
|
565
667
|
}
|
|
566
668
|
}
|
|
567
|
-
if (
|
|
568
|
-
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
if (changes && !state.isEmpty(changes)) {
|
|
572
|
-
transformedChanges = transformLoadData(changes, syncOptions, false, "set");
|
|
573
|
-
}
|
|
574
|
-
if (localState.numSavesOutstanding > 0) {
|
|
575
|
-
if (transformedChanges) {
|
|
576
|
-
if (!localState.pendingSaveResults) {
|
|
577
|
-
localState.pendingSaveResults = [];
|
|
578
|
-
}
|
|
579
|
-
localState.pendingSaveResults.push(transformedChanges);
|
|
669
|
+
if (changes && !state.isEmpty(changes)) {
|
|
670
|
+
transformedChanges = transformLoadData(changes, syncOptions, false, "set");
|
|
580
671
|
}
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
);
|
|
585
|
-
if (allChanges.length > 0) {
|
|
586
|
-
if (allChanges.some((change) => state.isPromise(change))) {
|
|
587
|
-
allChanges = await Promise.all(allChanges);
|
|
672
|
+
if (transformedChanges !== void 0) {
|
|
673
|
+
if (state.isPromise(transformedChanges)) {
|
|
674
|
+
transformedChanges = await transformedChanges;
|
|
588
675
|
}
|
|
589
|
-
onChangeRemote(() => state.mergeIntoObservable(obs
|
|
676
|
+
onChangeRemote(() => state.mergeIntoObservable(obs$, transformedChanges));
|
|
590
677
|
}
|
|
591
678
|
if (saveLocal) {
|
|
592
679
|
if (shouldSaveMetadata && !state.isEmpty(metadata)) {
|
|
593
|
-
updateMetadata(obs
|
|
680
|
+
updateMetadata(obs$, localState, syncState2, syncOptions, metadata);
|
|
594
681
|
}
|
|
595
682
|
}
|
|
596
|
-
localState.pendingSaveResults = [];
|
|
597
683
|
}
|
|
684
|
+
state$.numPendingSets.set((v) => v - 1);
|
|
685
|
+
state$.isSetting.set(state$.numPendingSets.peek() > 0);
|
|
598
686
|
onAfterSet == null ? void 0 : onAfterSet();
|
|
599
687
|
}
|
|
600
688
|
}
|
|
601
689
|
}
|
|
602
690
|
}
|
|
603
|
-
function onObsChange(value$,
|
|
604
|
-
if (!
|
|
605
|
-
const inRemoteChange =
|
|
691
|
+
function onObsChange(value$, syncState2, localState, syncOptions, { changes, isFromPersist, isFromSync, getPrevious }) {
|
|
692
|
+
if (!isFromPersist) {
|
|
693
|
+
const inRemoteChange = isFromSync;
|
|
606
694
|
const isApplyingPending = localState.isApplyingPending;
|
|
607
695
|
_queuedChanges.push({
|
|
608
696
|
value$,
|
|
609
|
-
syncState,
|
|
697
|
+
syncState: syncState2,
|
|
610
698
|
localState,
|
|
611
699
|
syncOptions,
|
|
612
700
|
changes,
|
|
@@ -619,19 +707,22 @@ function onObsChange(value$, syncState, localState, syncOptions, { changes, load
|
|
|
619
707
|
}
|
|
620
708
|
}
|
|
621
709
|
}
|
|
622
|
-
async function loadLocal(value$, syncOptions, syncState
|
|
710
|
+
async function loadLocal(value$, syncOptions, syncState$, localState) {
|
|
623
711
|
var _a, _b, _c;
|
|
624
712
|
const { persist } = syncOptions;
|
|
625
713
|
const node = getNode(value$);
|
|
626
714
|
const nodeValue = getNodeValue(getNode(node.state));
|
|
715
|
+
const syncStateValue = syncState$.peek();
|
|
716
|
+
const prevResetPersistence = nodeValue.resetPersistence;
|
|
627
717
|
if (persist == null ? void 0 : persist.name) {
|
|
628
718
|
const PersistPlugin = persist.plugin || ((_a = observableSyncConfiguration.persist) == null ? void 0 : _a.plugin);
|
|
629
719
|
const { table, config } = parseLocalConfig(persist);
|
|
720
|
+
syncStateValue.numPendingLocalLoads = (syncStateValue.numPendingLocalLoads || 0) + 1;
|
|
630
721
|
if (!PersistPlugin) {
|
|
631
722
|
throw new Error("Local persist is not configured");
|
|
632
723
|
}
|
|
633
724
|
if (!mapSyncPlugins.has(PersistPlugin)) {
|
|
634
|
-
const persistPlugin2 = new PersistPlugin();
|
|
725
|
+
const persistPlugin2 = state.isFunction(PersistPlugin) ? new PersistPlugin() : PersistPlugin;
|
|
635
726
|
const mapValue = { plugin: persistPlugin2, initialized: state.observable(false) };
|
|
636
727
|
mapSyncPlugins.set(PersistPlugin, mapValue);
|
|
637
728
|
if (persistPlugin2.initialize) {
|
|
@@ -660,7 +751,7 @@ async function loadLocal(value$, syncOptions, syncState, localState) {
|
|
|
660
751
|
if (metadata) {
|
|
661
752
|
metadatas.set(value$, metadata);
|
|
662
753
|
localState.pendingChanges = metadata.pending;
|
|
663
|
-
syncState
|
|
754
|
+
syncState$.assign({
|
|
664
755
|
lastSync: metadata.lastSync
|
|
665
756
|
});
|
|
666
757
|
}
|
|
@@ -678,15 +769,19 @@ async function loadLocal(value$, syncOptions, syncState, localState) {
|
|
|
678
769
|
}
|
|
679
770
|
state.internal.globalState.isLoadingLocal = false;
|
|
680
771
|
}
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
772
|
+
syncStateValue.numPendingLocalLoads--;
|
|
773
|
+
nodeValue.resetPersistence = () => Promise.all(
|
|
774
|
+
[
|
|
775
|
+
prevResetPersistence,
|
|
776
|
+
persistPlugin.deleteTable(table, config),
|
|
777
|
+
persistPlugin.deleteMetadata(table, config)
|
|
778
|
+
].filter(Boolean)
|
|
779
|
+
);
|
|
685
780
|
} else {
|
|
686
|
-
nodeValue.
|
|
687
|
-
};
|
|
781
|
+
nodeValue.resetPersistence = () => prevResetPersistence == null ? void 0 : prevResetPersistence();
|
|
688
782
|
}
|
|
689
|
-
|
|
783
|
+
nodeValue.clearPersist = nodeValue.resetPersistence;
|
|
784
|
+
syncState$.isPersistLoaded.set(!(syncStateValue.numPendingLocalLoads > 0));
|
|
690
785
|
}
|
|
691
786
|
function syncObservable(obs$, syncOptionsOrSynced) {
|
|
692
787
|
let syncOptions = syncOptionsOrSynced;
|
|
@@ -697,7 +792,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
697
792
|
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && (!obs$ || !node)) {
|
|
698
793
|
throw new Error("[legend-state] syncObservable called with undefined observable");
|
|
699
794
|
}
|
|
700
|
-
syncOptions =
|
|
795
|
+
syncOptions = deepMerge(
|
|
701
796
|
{
|
|
702
797
|
syncMode: "auto"
|
|
703
798
|
},
|
|
@@ -706,24 +801,54 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
706
801
|
);
|
|
707
802
|
const localState = {};
|
|
708
803
|
let sync;
|
|
709
|
-
const syncState =
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
804
|
+
const syncState$ = state.syncState(obs$);
|
|
805
|
+
const syncStateValue = getNodeValue(getNode(syncState$));
|
|
806
|
+
allSyncStates.set(syncState$, node);
|
|
807
|
+
syncStateValue.getPendingChanges = () => localState.pendingChanges;
|
|
808
|
+
let errorHandled = false;
|
|
809
|
+
const onGetError = (error, params) => {
|
|
810
|
+
var _a;
|
|
811
|
+
syncState$.error.set(error);
|
|
812
|
+
if (!errorHandled) {
|
|
813
|
+
(_a = syncOptions.onError) == null ? void 0 : _a.call(syncOptions, error, { ...params, value$: obs$ });
|
|
814
|
+
}
|
|
815
|
+
errorHandled = true;
|
|
816
|
+
};
|
|
817
|
+
loadLocal(obs$, syncOptions, syncState$, localState);
|
|
818
|
+
let isWaitingForLoad = !!syncOptions.get;
|
|
819
|
+
if (isWaitingForLoad) {
|
|
820
|
+
syncStateValue.numPendingRemoteLoads = (syncStateValue.numPendingRemoteLoads || 0) + 1;
|
|
821
|
+
}
|
|
822
|
+
syncState$.isLoaded.set(!syncState$.numPendingRemoteLoads.peek());
|
|
823
|
+
let isSynced = false;
|
|
824
|
+
let isSubscribed = false;
|
|
825
|
+
let unsubscribe = void 0;
|
|
826
|
+
const applyPending = (pending) => {
|
|
827
|
+
if (pending && !state.isEmpty(pending)) {
|
|
828
|
+
localState.isApplyingPending = true;
|
|
829
|
+
const keys = Object.keys(pending);
|
|
830
|
+
const changes = [];
|
|
831
|
+
for (let i = 0; i < keys.length; i++) {
|
|
832
|
+
const key = keys[i];
|
|
833
|
+
const path = key.split("/").filter((p2) => p2 !== "");
|
|
834
|
+
const { p, v, t } = pending[key];
|
|
835
|
+
changes.push({ path, valueAtPath: v, prevAtPath: p, pathTypes: t });
|
|
836
|
+
}
|
|
837
|
+
const value = getNodeValue(node);
|
|
838
|
+
onObsChange(obs$, syncState$, localState, syncOptions, {
|
|
839
|
+
value,
|
|
840
|
+
isFromPersist: false,
|
|
841
|
+
isFromSync: false,
|
|
842
|
+
getPrevious: createPreviousHandler(value, changes),
|
|
843
|
+
changes
|
|
844
|
+
});
|
|
845
|
+
localState.isApplyingPending = false;
|
|
846
|
+
}
|
|
847
|
+
};
|
|
720
848
|
if (syncOptions.get) {
|
|
721
|
-
let isSynced = false;
|
|
722
|
-
let isSubscribed = false;
|
|
723
|
-
let unsubscribe = void 0;
|
|
724
849
|
sync = async () => {
|
|
725
|
-
var _a
|
|
726
|
-
if (isSynced && state.shouldIgnoreUnobserved(node, sync)) {
|
|
850
|
+
var _a;
|
|
851
|
+
if (isSynced && (!getNodeValue(getNode(syncState$)).isSyncEnabled || state.shouldIgnoreUnobserved(node, sync))) {
|
|
727
852
|
if (unsubscribe) {
|
|
728
853
|
isSubscribed = false;
|
|
729
854
|
unsubscribe();
|
|
@@ -733,9 +858,11 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
733
858
|
}
|
|
734
859
|
const lastSync = (_a = metadatas.get(obs$)) == null ? void 0 : _a.lastSync;
|
|
735
860
|
const pending = localState.pendingChanges;
|
|
736
|
-
const get =
|
|
861
|
+
const get = syncOptions.get;
|
|
737
862
|
if (get) {
|
|
863
|
+
const { waitFor } = syncOptions;
|
|
738
864
|
const runGet = () => {
|
|
865
|
+
var _a2;
|
|
739
866
|
const onChange = async ({ value, mode, lastSync: lastSync2 }) => {
|
|
740
867
|
mode = mode || syncOptions.mode || "set";
|
|
741
868
|
if (value !== void 0) {
|
|
@@ -748,9 +875,11 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
748
875
|
if (pending2) {
|
|
749
876
|
let didChangeMetadata = false;
|
|
750
877
|
Object.keys(pending2).forEach((key) => {
|
|
751
|
-
const p = key.split("/").filter((
|
|
878
|
+
const p = key.split("/").filter((k) => k !== "");
|
|
752
879
|
const { v, t } = pending2[key];
|
|
753
880
|
if (t.length === 0 || !value) {
|
|
881
|
+
const oldValue = clone(value);
|
|
882
|
+
pending2[key].p = oldValue;
|
|
754
883
|
if (state.isObject(value) && state.isObject(v)) {
|
|
755
884
|
Object.assign(value, v);
|
|
756
885
|
} else {
|
|
@@ -763,6 +892,8 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
763
892
|
delete pending2[key];
|
|
764
893
|
didChangeMetadata = true;
|
|
765
894
|
} else {
|
|
895
|
+
const oldValue = clone(value);
|
|
896
|
+
pending2[key].p = getValueAtPath(oldValue, p);
|
|
766
897
|
value = state.setAtPath(
|
|
767
898
|
value,
|
|
768
899
|
p,
|
|
@@ -782,18 +913,27 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
782
913
|
}
|
|
783
914
|
}
|
|
784
915
|
});
|
|
785
|
-
if (didChangeMetadata) {
|
|
786
|
-
updateMetadata(obs$, localState, syncState
|
|
916
|
+
if (didChangeMetadata && syncOptions.persist) {
|
|
917
|
+
updateMetadata(obs$, localState, syncState$, syncOptions, {
|
|
787
918
|
pending: pending2
|
|
788
919
|
});
|
|
789
920
|
}
|
|
790
921
|
}
|
|
791
922
|
onChangeRemote(() => {
|
|
792
|
-
if (
|
|
923
|
+
if (state.isPlainObject(value)) {
|
|
924
|
+
value = state.ObservableHint.plain(value);
|
|
925
|
+
}
|
|
926
|
+
if (mode === "assign") {
|
|
793
927
|
obs$.assign(value);
|
|
794
|
-
} else if (mode === "append"
|
|
928
|
+
} else if (mode === "append") {
|
|
929
|
+
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && !state.isArray(value)) {
|
|
930
|
+
console.error("[legend-state] mode:append expects the value to be an array");
|
|
931
|
+
}
|
|
795
932
|
obs$.push(...value);
|
|
796
|
-
} else if (mode === "prepend"
|
|
933
|
+
} else if (mode === "prepend") {
|
|
934
|
+
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && !state.isArray(value)) {
|
|
935
|
+
console.error("[legend-state] mode:prepend expects the value to be an array");
|
|
936
|
+
}
|
|
797
937
|
obs$.splice(0, 0, ...value);
|
|
798
938
|
} else if (mode === "merge") {
|
|
799
939
|
state.mergeIntoObservable(obs$, value);
|
|
@@ -803,78 +943,180 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
803
943
|
});
|
|
804
944
|
}
|
|
805
945
|
if (lastSync2 && syncOptions.persist) {
|
|
806
|
-
updateMetadata(obs$, localState, syncState
|
|
946
|
+
updateMetadata(obs$, localState, syncState$, syncOptions, {
|
|
807
947
|
lastSync: lastSync2
|
|
808
948
|
});
|
|
809
949
|
}
|
|
810
950
|
};
|
|
811
|
-
|
|
812
|
-
|
|
951
|
+
if (node.activationState) {
|
|
952
|
+
node.activationState.onChange = onChange;
|
|
953
|
+
}
|
|
954
|
+
if (!isSubscribed && syncOptions.subscribe) {
|
|
955
|
+
const subscribe = syncOptions.subscribe;
|
|
956
|
+
isSubscribed = true;
|
|
957
|
+
const doSubscribe = () => {
|
|
958
|
+
const subscribeParams = {
|
|
959
|
+
node,
|
|
960
|
+
value$: obs$,
|
|
961
|
+
lastSync,
|
|
962
|
+
update: (params) => {
|
|
963
|
+
state.when(syncState$.isLoaded, () => {
|
|
964
|
+
state.when(waitFor || true, () => {
|
|
965
|
+
params.mode || (params.mode = syncOptions.mode || "merge");
|
|
966
|
+
onChange(params);
|
|
967
|
+
});
|
|
968
|
+
});
|
|
969
|
+
},
|
|
970
|
+
refresh: () => state.when(syncState$.isLoaded, sync),
|
|
971
|
+
onError: (error) => onGetError(error, { source: "subscribe", subscribeParams })
|
|
972
|
+
};
|
|
973
|
+
unsubscribe = subscribe(subscribeParams);
|
|
974
|
+
};
|
|
975
|
+
if (waitFor) {
|
|
976
|
+
state.whenReady(waitFor, doSubscribe);
|
|
977
|
+
} else {
|
|
978
|
+
doSubscribe();
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
const existingValue = getNodeValue(node);
|
|
982
|
+
const onError = (error) => onGetError(error, { getParams, source: "get" });
|
|
983
|
+
const getParams = {
|
|
984
|
+
node,
|
|
813
985
|
value$: obs$,
|
|
986
|
+
value: state.isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked]) ? void 0 : existingValue,
|
|
987
|
+
mode: syncOptions.mode,
|
|
988
|
+
refresh: sync,
|
|
814
989
|
options: syncOptions,
|
|
815
990
|
lastSync,
|
|
816
|
-
|
|
817
|
-
onError
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
991
|
+
updateLastSync: (lastSync2) => getParams.lastSync = lastSync2,
|
|
992
|
+
onError,
|
|
993
|
+
retryNum: 0,
|
|
994
|
+
cancelRetry: false
|
|
995
|
+
};
|
|
996
|
+
let modeBeforeReset = void 0;
|
|
997
|
+
const beforeGetParams = {
|
|
998
|
+
value: getParams.value,
|
|
999
|
+
lastSync,
|
|
1000
|
+
pendingChanges: pending && !state.isEmpty(pending) ? pending : void 0,
|
|
1001
|
+
clearPendingChanges: async () => {
|
|
1002
|
+
localState.pendingChanges = {};
|
|
1003
|
+
await updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
|
|
1004
|
+
pending: localState.pendingChanges
|
|
825
1005
|
});
|
|
826
1006
|
},
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
refresh: () => state.when(node.state.isLoaded, sync)
|
|
1007
|
+
resetCache: () => {
|
|
1008
|
+
var _a3;
|
|
1009
|
+
modeBeforeReset = getParams.mode;
|
|
1010
|
+
getParams.mode = "set";
|
|
1011
|
+
return (_a3 = syncStateValue.resetPersistence) == null ? void 0 : _a3.call(syncStateValue);
|
|
1012
|
+
},
|
|
1013
|
+
cancel: false
|
|
1014
|
+
};
|
|
1015
|
+
(_a2 = syncOptions.onBeforeGet) == null ? void 0 : _a2.call(syncOptions, beforeGetParams);
|
|
1016
|
+
if (!beforeGetParams.cancel) {
|
|
1017
|
+
syncState$.assign({
|
|
1018
|
+
numPendingGets: (syncStateValue.numPendingGets || 0) + 1,
|
|
1019
|
+
isGetting: true
|
|
841
1020
|
});
|
|
1021
|
+
const got = runWithRetry(
|
|
1022
|
+
getParams,
|
|
1023
|
+
syncOptions.retry,
|
|
1024
|
+
(retryEvent) => {
|
|
1025
|
+
const params = getParams;
|
|
1026
|
+
params.cancelRetry = retryEvent.cancelRetry;
|
|
1027
|
+
params.retryNum = retryEvent.retryNum;
|
|
1028
|
+
return get(params);
|
|
1029
|
+
},
|
|
1030
|
+
onError
|
|
1031
|
+
);
|
|
1032
|
+
const numGets = node.numGets = (node.numGets || 0) + 1;
|
|
1033
|
+
const handle = (value) => {
|
|
1034
|
+
syncState$.numPendingGets.set((v) => v - 1);
|
|
1035
|
+
if (isWaitingForLoad) {
|
|
1036
|
+
isWaitingForLoad = false;
|
|
1037
|
+
syncStateValue.numPendingRemoteLoads--;
|
|
1038
|
+
}
|
|
1039
|
+
if (numGets >= (node.getNumResolved || 0)) {
|
|
1040
|
+
node.getNumResolved = node.numGets;
|
|
1041
|
+
onChange({
|
|
1042
|
+
value,
|
|
1043
|
+
lastSync: getParams.lastSync,
|
|
1044
|
+
mode: getParams.mode
|
|
1045
|
+
});
|
|
1046
|
+
}
|
|
1047
|
+
if (modeBeforeReset) {
|
|
1048
|
+
getParams.mode = modeBeforeReset;
|
|
1049
|
+
modeBeforeReset = void 0;
|
|
1050
|
+
}
|
|
1051
|
+
syncState$.assign({
|
|
1052
|
+
isLoaded: syncStateValue.numPendingRemoteLoads < 1,
|
|
1053
|
+
error: void 0,
|
|
1054
|
+
isGetting: syncStateValue.numPendingGets > 0
|
|
1055
|
+
});
|
|
1056
|
+
};
|
|
1057
|
+
if (state.isPromise(got)) {
|
|
1058
|
+
got.then(handle).catch(onError);
|
|
1059
|
+
} else {
|
|
1060
|
+
handle(got);
|
|
1061
|
+
}
|
|
842
1062
|
}
|
|
843
1063
|
};
|
|
844
|
-
|
|
1064
|
+
if (waitFor) {
|
|
1065
|
+
state.whenReady(waitFor, () => state.trackSelector(runGet, sync));
|
|
1066
|
+
} else {
|
|
1067
|
+
state.trackSelector(runGet, sync);
|
|
1068
|
+
}
|
|
845
1069
|
} else {
|
|
846
|
-
|
|
1070
|
+
syncState$.assign({
|
|
847
1071
|
isLoaded: true,
|
|
848
1072
|
error: void 0
|
|
849
1073
|
});
|
|
850
1074
|
}
|
|
851
1075
|
if (!isSynced) {
|
|
852
1076
|
isSynced = true;
|
|
853
|
-
await state.when(
|
|
854
|
-
|
|
855
|
-
localState.isApplyingPending = true;
|
|
856
|
-
const keys = Object.keys(pending);
|
|
857
|
-
const changes = [];
|
|
858
|
-
for (let i = 0; i < keys.length; i++) {
|
|
859
|
-
const key = keys[i];
|
|
860
|
-
const path = key.split("/").filter((p2) => p2 !== "");
|
|
861
|
-
const { p, v, t } = pending[key];
|
|
862
|
-
changes.push({ path, valueAtPath: v, prevAtPath: p, pathTypes: t });
|
|
863
|
-
}
|
|
864
|
-
const value = getNodeValue(node);
|
|
865
|
-
onObsChange(obs$, syncState, localState, syncOptions, {
|
|
866
|
-
value,
|
|
867
|
-
loading: false,
|
|
868
|
-
remote: false,
|
|
869
|
-
getPrevious: createPreviousHandler(value, changes),
|
|
870
|
-
changes
|
|
871
|
-
});
|
|
872
|
-
localState.isApplyingPending = false;
|
|
873
|
-
}
|
|
1077
|
+
await state.when(syncState$.isLoaded);
|
|
1078
|
+
applyPending(pending);
|
|
874
1079
|
}
|
|
875
1080
|
};
|
|
876
|
-
|
|
1081
|
+
syncStateValue.sync = sync;
|
|
1082
|
+
} else {
|
|
1083
|
+
if (!isSynced) {
|
|
1084
|
+
applyPending(localState.pendingChanges);
|
|
1085
|
+
}
|
|
877
1086
|
}
|
|
1087
|
+
syncStateValue.reset = async () => {
|
|
1088
|
+
const wasPersistEnabled = syncStateValue.isPersistEnabled;
|
|
1089
|
+
const wasSyncEnabled = syncStateValue.isSyncEnabled;
|
|
1090
|
+
const metadata = metadatas.get(obs$);
|
|
1091
|
+
if (metadata) {
|
|
1092
|
+
Object.assign(metadata, { lastSync: void 0, pending: void 0 });
|
|
1093
|
+
}
|
|
1094
|
+
Object.assign(syncStateValue, {
|
|
1095
|
+
isPersistEnabled: false,
|
|
1096
|
+
isSyncEnabled: false,
|
|
1097
|
+
lastSync: void 0,
|
|
1098
|
+
numPendingGets: 0,
|
|
1099
|
+
isLoaded: false,
|
|
1100
|
+
isGetting: false,
|
|
1101
|
+
isSetting: false,
|
|
1102
|
+
numPendingSets: 0,
|
|
1103
|
+
syncCount: 0
|
|
1104
|
+
});
|
|
1105
|
+
isSynced = false;
|
|
1106
|
+
isSubscribed = false;
|
|
1107
|
+
unsubscribe == null ? void 0 : unsubscribe();
|
|
1108
|
+
unsubscribe = void 0;
|
|
1109
|
+
const promise = syncStateValue.resetPersistence();
|
|
1110
|
+
onChangeRemote(() => {
|
|
1111
|
+
var _a;
|
|
1112
|
+
obs$.set((_a = syncOptions.initial) != null ? _a : void 0);
|
|
1113
|
+
});
|
|
1114
|
+
syncState$.isLoaded.set(false);
|
|
1115
|
+
syncStateValue.isPersistEnabled = wasPersistEnabled;
|
|
1116
|
+
syncStateValue.isSyncEnabled = wasSyncEnabled;
|
|
1117
|
+
node.dirtyFn = sync;
|
|
1118
|
+
await promise;
|
|
1119
|
+
};
|
|
878
1120
|
const onAllPersistLoaded = () => {
|
|
879
1121
|
var _a, _b;
|
|
880
1122
|
let parentNode = node;
|
|
@@ -892,77 +1134,27 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
892
1134
|
}
|
|
893
1135
|
if ((syncOptions == null ? void 0 : syncOptions.set) || (syncOptions == null ? void 0 : syncOptions.persist)) {
|
|
894
1136
|
obs$.onChange(
|
|
895
|
-
onObsChange.bind(this, obs$, syncState
|
|
1137
|
+
onObsChange.bind(this, obs$, syncState$, localState, syncOptions)
|
|
896
1138
|
);
|
|
897
1139
|
}
|
|
898
1140
|
});
|
|
899
|
-
return syncState
|
|
1141
|
+
return syncState$;
|
|
900
1142
|
}
|
|
901
|
-
var { getProxy, globalState: globalState2,
|
|
1143
|
+
var { getProxy, globalState: globalState2, setNodeValue, getNodeValue: getNodeValue2 } = state.internal;
|
|
902
1144
|
function enableActivateSyncedNode() {
|
|
903
1145
|
globalState2.activateSyncedNode = function activateSyncedNode(node, newValue) {
|
|
904
1146
|
const obs$ = getProxy(node);
|
|
905
1147
|
if (node.activationState) {
|
|
906
|
-
const {
|
|
907
|
-
|
|
908
|
-
|
|
1148
|
+
const {
|
|
1149
|
+
get: getOrig,
|
|
1150
|
+
initial,
|
|
1151
|
+
set,
|
|
1152
|
+
onChange
|
|
1153
|
+
} = node.activationState;
|
|
909
1154
|
let promiseReturn = void 0;
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
pluginRemote.get = (params) => {
|
|
914
|
-
var _a;
|
|
915
|
-
onChange = params.onChange;
|
|
916
|
-
const updateLastSync = (lastSync) => params.lastSync = lastSync;
|
|
917
|
-
const existingValue = getNodeValue2(node);
|
|
918
|
-
const value = runWithRetry(node, { attemptNum: 0, retry: retry || ((_a = params.options) == null ? void 0 : _a.retry) }, () => {
|
|
919
|
-
const paramsToGet = {
|
|
920
|
-
value: state.isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked2]) ? void 0 : existingValue,
|
|
921
|
-
lastSync: params.lastSync,
|
|
922
|
-
updateLastSync,
|
|
923
|
-
mode: params.mode,
|
|
924
|
-
refresh
|
|
925
|
-
};
|
|
926
|
-
const ret = get(paramsToGet);
|
|
927
|
-
params.mode = paramsToGet.mode;
|
|
928
|
-
return ret;
|
|
929
|
-
});
|
|
930
|
-
promiseReturn = value;
|
|
931
|
-
return value;
|
|
932
|
-
};
|
|
933
|
-
}
|
|
934
|
-
if (set) {
|
|
935
|
-
pluginRemote.set = async (params) => {
|
|
936
|
-
var _a, _b;
|
|
937
|
-
if ((_a = node.state) == null ? void 0 : _a.isLoaded.get()) {
|
|
938
|
-
const retryAttempts = { attemptNum: 0, retry: retry || ((_b = params.options) == null ? void 0 : _b.retry) };
|
|
939
|
-
return runWithRetry(node, retryAttempts, async (retryEvent) => {
|
|
940
|
-
let changes = {};
|
|
941
|
-
let maxModified = 0;
|
|
942
|
-
if (!node.state.isLoaded.peek()) {
|
|
943
|
-
await state.whenReady(node.state.isLoaded);
|
|
944
|
-
}
|
|
945
|
-
const cancelRetry = () => {
|
|
946
|
-
retryEvent.cancel = true;
|
|
947
|
-
};
|
|
948
|
-
await set({
|
|
949
|
-
...params,
|
|
950
|
-
node,
|
|
951
|
-
update: (params2) => {
|
|
952
|
-
const { value, lastSync } = params2;
|
|
953
|
-
maxModified = Math.max(lastSync || 0, maxModified);
|
|
954
|
-
changes = state.mergeIntoObservable(changes, value);
|
|
955
|
-
},
|
|
956
|
-
retryNum: retryAttempts.attemptNum,
|
|
957
|
-
cancelRetry,
|
|
958
|
-
refresh,
|
|
959
|
-
fromSubscribe: false
|
|
960
|
-
});
|
|
961
|
-
return { changes, lastSync: maxModified || void 0 };
|
|
962
|
-
});
|
|
963
|
-
}
|
|
964
|
-
};
|
|
965
|
-
}
|
|
1155
|
+
const get = getOrig ? (params) => {
|
|
1156
|
+
return promiseReturn = getOrig(params);
|
|
1157
|
+
} : void 0;
|
|
966
1158
|
const nodeVal = getNodeValue2(node);
|
|
967
1159
|
if (promiseReturn !== void 0) {
|
|
968
1160
|
newValue = promiseReturn;
|
|
@@ -972,7 +1164,7 @@ function enableActivateSyncedNode() {
|
|
|
972
1164
|
newValue = initial;
|
|
973
1165
|
}
|
|
974
1166
|
setNodeValue(node, promiseReturn ? void 0 : newValue);
|
|
975
|
-
|
|
1167
|
+
syncObservable(obs$, { ...node.activationState, get, set });
|
|
976
1168
|
return { update: onChange, value: newValue };
|
|
977
1169
|
} else {
|
|
978
1170
|
let update = void 0;
|
|
@@ -1009,21 +1201,28 @@ function installPersistActivateNode() {
|
|
|
1009
1201
|
didInstall = true;
|
|
1010
1202
|
}
|
|
1011
1203
|
}
|
|
1204
|
+
var { deepMerge: deepMerge2 } = state.internal;
|
|
1205
|
+
function configureSynced(fnOrOrigOptions, origOptions) {
|
|
1206
|
+
const fn = origOptions ? fnOrOrigOptions : synced;
|
|
1207
|
+
origOptions = origOptions != null ? origOptions : fnOrOrigOptions;
|
|
1208
|
+
return (options) => {
|
|
1209
|
+
const merged = deepMerge2(origOptions, options);
|
|
1210
|
+
return fn(merged);
|
|
1211
|
+
};
|
|
1212
|
+
}
|
|
1012
1213
|
|
|
1013
1214
|
// sync.ts
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
var internal3 = {
|
|
1018
|
-
observableSyncConfiguration
|
|
1215
|
+
var internal4 = {
|
|
1216
|
+
observableSyncConfiguration,
|
|
1217
|
+
waitForSet
|
|
1019
1218
|
};
|
|
1020
1219
|
|
|
1021
1220
|
exports.combineTransforms = combineTransforms;
|
|
1022
1221
|
exports.configureObservableSync = configureObservableSync;
|
|
1222
|
+
exports.configureSynced = configureSynced;
|
|
1023
1223
|
exports.deepEqual = deepEqual;
|
|
1024
1224
|
exports.diffObjects = diffObjects;
|
|
1025
|
-
exports.internal =
|
|
1026
|
-
exports.isInRemoteChange = isInRemoteChange;
|
|
1225
|
+
exports.internal = internal4;
|
|
1027
1226
|
exports.mapSyncPlugins = mapSyncPlugins;
|
|
1028
1227
|
exports.onChangeRemote = onChangeRemote;
|
|
1029
1228
|
exports.removeNullUndefined = removeNullUndefined;
|