@anfenn/zync 0.3.3 → 0.4.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/README.md +27 -22
- package/dist/index.cjs +178 -76
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -6
- package/dist/index.d.ts +19 -6
- package/dist/index.js +175 -75
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -23,9 +23,40 @@ function newLogger(base, min) {
|
|
|
23
23
|
|
|
24
24
|
// src/helpers.ts
|
|
25
25
|
var SYNC_FIELDS = ["_localId", "updated_at", "deleted"];
|
|
26
|
-
function
|
|
26
|
+
function createLocalId() {
|
|
27
27
|
return crypto.randomUUID();
|
|
28
28
|
}
|
|
29
|
+
function sleep(ms) {
|
|
30
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
31
|
+
}
|
|
32
|
+
function changeKeysTo(input, toIdKey, toUpdatedAtKey, toDeletedKey) {
|
|
33
|
+
if (!input) return input;
|
|
34
|
+
const isArray = Array.isArray(input);
|
|
35
|
+
const result = (isArray ? input : [input]).map((item) => {
|
|
36
|
+
const { id, updated_at, deleted, ...rest } = item;
|
|
37
|
+
return {
|
|
38
|
+
[toIdKey]: id,
|
|
39
|
+
[toUpdatedAtKey]: updated_at,
|
|
40
|
+
[toDeletedKey]: deleted,
|
|
41
|
+
...rest
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
return isArray ? result : result[0];
|
|
45
|
+
}
|
|
46
|
+
function changeKeysFrom(input, fromIdKey, fromUpdatedAtKey, fromDeletedKey) {
|
|
47
|
+
if (!input) return input;
|
|
48
|
+
const isArray = Array.isArray(input);
|
|
49
|
+
const result = (isArray ? input : [input]).map((item) => {
|
|
50
|
+
const { [fromIdKey]: id, [fromUpdatedAtKey]: updated_at, [fromDeletedKey]: deleted, ...rest } = item;
|
|
51
|
+
return {
|
|
52
|
+
id,
|
|
53
|
+
updated_at,
|
|
54
|
+
deleted,
|
|
55
|
+
...rest
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
return isArray ? result : result[0];
|
|
59
|
+
}
|
|
29
60
|
function orderFor(a) {
|
|
30
61
|
switch (a) {
|
|
31
62
|
case "create" /* Create */:
|
|
@@ -42,8 +73,8 @@ function omitSyncFields(item) {
|
|
|
42
73
|
return result;
|
|
43
74
|
}
|
|
44
75
|
function samePendingVersion(get, stateKey, localId, version) {
|
|
45
|
-
const
|
|
46
|
-
const curChange =
|
|
76
|
+
const pending = get().syncState.pendingChanges || [];
|
|
77
|
+
const curChange = pending.find((p) => p.localId === localId && p.stateKey === stateKey);
|
|
47
78
|
return curChange?.version === version;
|
|
48
79
|
}
|
|
49
80
|
function removeFromPendingChanges(set, localId, stateKey) {
|
|
@@ -77,7 +108,7 @@ function tryAddToPendingChanges(pendingChanges, stateKey, changes) {
|
|
|
77
108
|
queueItem.changes = { ...queueItem.changes, ...omittedItem };
|
|
78
109
|
}
|
|
79
110
|
} else if (action === "remove" /* Remove */ || hasChanges) {
|
|
80
|
-
pendingChanges.push({ action, stateKey, localId, id: change.id, version: 1, changes: omittedItem });
|
|
111
|
+
pendingChanges.push({ action, stateKey, localId, id: change.id, version: 1, changes: omittedItem, current: omitSyncFields(change.currentItem) });
|
|
81
112
|
}
|
|
82
113
|
}
|
|
83
114
|
}
|
|
@@ -89,6 +120,23 @@ function setPendingChangeToUpdate(get, stateKey, localId, id) {
|
|
|
89
120
|
if (id) change.id = id;
|
|
90
121
|
}
|
|
91
122
|
}
|
|
123
|
+
function tryUpdateConflicts(pendingChanges, conflicts) {
|
|
124
|
+
if (!conflicts) return conflicts;
|
|
125
|
+
const newConflicts = { ...conflicts };
|
|
126
|
+
for (const change of pendingChanges) {
|
|
127
|
+
const conflict = newConflicts[change.localId];
|
|
128
|
+
if (conflict && change.changes) {
|
|
129
|
+
const newFields = conflict.fields.map((f) => {
|
|
130
|
+
if (f.key in change.changes) {
|
|
131
|
+
return { ...f, localValue: change.changes[f.key] };
|
|
132
|
+
}
|
|
133
|
+
return f;
|
|
134
|
+
});
|
|
135
|
+
newConflicts[change.localId] = { stateKey: conflict.stateKey, fields: newFields };
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return newConflicts;
|
|
139
|
+
}
|
|
92
140
|
function findApi(stateKey, syncApi) {
|
|
93
141
|
const api = syncApi[stateKey];
|
|
94
142
|
if (!api || !api.add || !api.update || !api.remove || !api.list || !api.firstLoad) {
|
|
@@ -130,6 +178,50 @@ function findChanges(current, updated) {
|
|
|
130
178
|
}
|
|
131
179
|
return changesMap;
|
|
132
180
|
}
|
|
181
|
+
function hasKeysOrUndefined(obj) {
|
|
182
|
+
return Object.keys(obj).length === 0 ? void 0 : obj;
|
|
183
|
+
}
|
|
184
|
+
function hasConflicts(get, localId) {
|
|
185
|
+
const state = get();
|
|
186
|
+
if (state.syncState.conflicts) {
|
|
187
|
+
return !!state.syncState.conflicts[localId];
|
|
188
|
+
}
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
function resolveConflict(set, localId, keepLocalFields) {
|
|
192
|
+
set((state) => {
|
|
193
|
+
const syncState = state.syncState || {};
|
|
194
|
+
const conflicts = syncState.conflicts || {};
|
|
195
|
+
const conflict = conflicts[localId];
|
|
196
|
+
if (conflict) {
|
|
197
|
+
const items = state[conflict.stateKey];
|
|
198
|
+
const item = items.find((i) => i._localId === localId);
|
|
199
|
+
if (!item) {
|
|
200
|
+
return state;
|
|
201
|
+
}
|
|
202
|
+
const resolved = { ...item };
|
|
203
|
+
let pendingChanges = [...syncState.pendingChanges];
|
|
204
|
+
if (!keepLocalFields) {
|
|
205
|
+
for (const field of conflict.fields) {
|
|
206
|
+
resolved[field.key] = field.remoteValue;
|
|
207
|
+
}
|
|
208
|
+
pendingChanges = pendingChanges.filter((p) => !(p.stateKey === conflict.stateKey && p.localId === localId));
|
|
209
|
+
}
|
|
210
|
+
const nextItems = items.map((i) => i._localId === localId ? resolved : i);
|
|
211
|
+
const nextConflicts = { ...conflicts };
|
|
212
|
+
delete nextConflicts[localId];
|
|
213
|
+
return {
|
|
214
|
+
[conflict.stateKey]: nextItems,
|
|
215
|
+
syncState: {
|
|
216
|
+
...syncState,
|
|
217
|
+
pendingChanges,
|
|
218
|
+
conflicts: hasKeysOrUndefined(nextConflicts)
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
return state;
|
|
223
|
+
});
|
|
224
|
+
}
|
|
133
225
|
|
|
134
226
|
// src/pull.ts
|
|
135
227
|
async function pull(set, get, stateKey, api, logger, conflictResolutionStrategy) {
|
|
@@ -140,7 +232,8 @@ async function pull(set, get, stateKey, api, logger, conflictResolutionStrategy)
|
|
|
140
232
|
if (!serverData?.length) return;
|
|
141
233
|
let newest = lastPulledAt;
|
|
142
234
|
set((state) => {
|
|
143
|
-
|
|
235
|
+
let pendingChanges = [...state.syncState.pendingChanges];
|
|
236
|
+
const conflicts = { ...state.syncState.conflicts };
|
|
144
237
|
const localItems = state[stateKey] || [];
|
|
145
238
|
let nextItems = [...localItems];
|
|
146
239
|
const localById = new Map(localItems.filter((l) => l.id).map((l) => [l.id, l]));
|
|
@@ -164,43 +257,43 @@ async function pull(set, get, stateKey, api, logger, conflictResolutionStrategy)
|
|
|
164
257
|
if (localItem) {
|
|
165
258
|
const pendingChange = pendingChanges.find((p) => p.stateKey === stateKey && p.localId === localItem._localId);
|
|
166
259
|
if (pendingChange) {
|
|
260
|
+
logger.debug(`[zync] pull:conflict-strategy:${conflictResolutionStrategy} stateKey=${stateKey} id=${remote.id}`);
|
|
167
261
|
switch (conflictResolutionStrategy) {
|
|
168
|
-
case "
|
|
169
|
-
logger.debug(`[zync] pull:conflict-strategy:${conflictResolutionStrategy} stateKey=${stateKey} id=${remote.id}`);
|
|
262
|
+
case "client-wins":
|
|
170
263
|
break;
|
|
171
|
-
case "
|
|
172
|
-
const merged = {
|
|
173
|
-
...remote,
|
|
174
|
-
_localId: localItem._localId
|
|
175
|
-
};
|
|
264
|
+
case "server-wins": {
|
|
265
|
+
const merged = { ...remote, _localId: localItem._localId };
|
|
176
266
|
nextItems = nextItems.map((i) => i._localId === localItem._localId ? merged : i);
|
|
177
|
-
|
|
267
|
+
pendingChanges = pendingChanges.filter((p) => !(p.stateKey === stateKey && p.localId === localItem._localId));
|
|
178
268
|
break;
|
|
179
269
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
270
|
+
case "try-shallow-merge": {
|
|
271
|
+
const changes = pendingChange.changes || {};
|
|
272
|
+
const current = pendingChange.current || {};
|
|
273
|
+
const fields = Object.entries(changes).filter(([k, localValue]) => k in current && k in remote && current[k] !== remote[k] && localValue !== remote[k]).map(([key, localValue]) => ({ key, localValue, remoteValue: remote[key] }));
|
|
274
|
+
if (fields.length > 0) {
|
|
275
|
+
logger.warn(`[zync] pull:${conflictResolutionStrategy}:conflicts-found`, JSON.stringify(fields, null, 4));
|
|
276
|
+
conflicts[localItem._localId] = { stateKey, fields };
|
|
277
|
+
} else {
|
|
278
|
+
const localChangedKeys = Object.keys(changes);
|
|
279
|
+
const preservedLocal = { _localId: localItem._localId };
|
|
280
|
+
for (const k of localChangedKeys) {
|
|
281
|
+
if (k in localItem) preservedLocal[k] = localItem[k];
|
|
282
|
+
}
|
|
283
|
+
const merged = { ...remote, ...preservedLocal };
|
|
284
|
+
nextItems = nextItems.map((i) => i._localId === localItem._localId ? merged : i);
|
|
285
|
+
delete conflicts[localItem._localId];
|
|
286
|
+
}
|
|
192
287
|
break;
|
|
288
|
+
}
|
|
193
289
|
}
|
|
194
290
|
} else {
|
|
195
|
-
const merged = {
|
|
196
|
-
...localItem,
|
|
197
|
-
...remote
|
|
198
|
-
};
|
|
291
|
+
const merged = { ...localItem, ...remote };
|
|
199
292
|
nextItems = nextItems.map((i) => i._localId === localItem._localId ? merged : i);
|
|
200
293
|
logger.debug(`[zync] pull:merge-remote stateKey=${stateKey} id=${remote.id}`);
|
|
201
294
|
}
|
|
202
295
|
} else {
|
|
203
|
-
nextItems = [...nextItems, { ...remote, _localId:
|
|
296
|
+
nextItems = [...nextItems, { ...remote, _localId: createLocalId() }];
|
|
204
297
|
logger.debug(`[zync] pull:add stateKey=${stateKey} id=${remote.id}`);
|
|
205
298
|
}
|
|
206
299
|
}
|
|
@@ -208,6 +301,8 @@ async function pull(set, get, stateKey, api, logger, conflictResolutionStrategy)
|
|
|
208
301
|
[stateKey]: nextItems,
|
|
209
302
|
syncState: {
|
|
210
303
|
...state.syncState || {},
|
|
304
|
+
pendingChanges,
|
|
305
|
+
conflicts: hasKeysOrUndefined(conflicts),
|
|
211
306
|
lastPulled: {
|
|
212
307
|
...state.syncState.lastPulled || {},
|
|
213
308
|
[stateKey]: newest.toISOString()
|
|
@@ -234,6 +329,10 @@ async function pushOne(set, get, change, api, logger, setAndQueueToSync, missing
|
|
|
234
329
|
removeFromPendingChanges(set, localId, stateKey);
|
|
235
330
|
break;
|
|
236
331
|
case "update" /* Update */: {
|
|
332
|
+
if (hasConflicts(get, change.localId)) {
|
|
333
|
+
logger.warn(`[zync] push:update:skipping-with-conflicts stateKey=${stateKey} localId=${localId} id=${id}`);
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
237
336
|
const exists = await api.update(id, changesClone);
|
|
238
337
|
if (exists) {
|
|
239
338
|
logger.debug(`[zync] push:update:success stateKey=${stateKey} localId=${localId} id=${id}`);
|
|
@@ -260,7 +359,7 @@ async function pushOne(set, get, change, api, logger, setAndQueueToSync, missing
|
|
|
260
359
|
case "insert-remote-record": {
|
|
261
360
|
const newItem = {
|
|
262
361
|
...item,
|
|
263
|
-
_localId:
|
|
362
|
+
_localId: createLocalId(),
|
|
264
363
|
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
265
364
|
};
|
|
266
365
|
setAndQueueToSync((s) => ({
|
|
@@ -339,7 +438,7 @@ async function startFirstLoad(set, syncApi, logger) {
|
|
|
339
438
|
} else {
|
|
340
439
|
next.push({
|
|
341
440
|
...remote,
|
|
342
|
-
_localId:
|
|
441
|
+
_localId: createLocalId()
|
|
343
442
|
});
|
|
344
443
|
}
|
|
345
444
|
}
|
|
@@ -453,17 +552,17 @@ function createIndexedDBStorage(options) {
|
|
|
453
552
|
}
|
|
454
553
|
|
|
455
554
|
// src/index.ts
|
|
456
|
-
var SyncAction = /* @__PURE__ */ ((
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
return
|
|
555
|
+
var SyncAction = /* @__PURE__ */ ((SyncAction3) => {
|
|
556
|
+
SyncAction3["Create"] = "create";
|
|
557
|
+
SyncAction3["Update"] = "update";
|
|
558
|
+
SyncAction3["Remove"] = "remove";
|
|
559
|
+
return SyncAction3;
|
|
461
560
|
})(SyncAction || {});
|
|
462
|
-
var DEFAULT_SYNC_INTERVAL_MILLIS =
|
|
561
|
+
var DEFAULT_SYNC_INTERVAL_MILLIS = 2e3;
|
|
463
562
|
var DEFAULT_LOGGER = console;
|
|
464
563
|
var DEFAULT_MIN_LOG_LEVEL = "debug";
|
|
465
564
|
var DEFAULT_MISSING_REMOTE_RECORD_STRATEGY = "ignore";
|
|
466
|
-
var DEFAULT_CONFLICT_RESOLUTION_STRATEGY = "
|
|
565
|
+
var DEFAULT_CONFLICT_RESOLUTION_STRATEGY = "client-wins";
|
|
467
566
|
function createWithSync(stateCreator, persistOptions, syncApi, syncOptions = {}) {
|
|
468
567
|
const store = create(persistWithSync(stateCreator, persistOptions, syncApi, syncOptions));
|
|
469
568
|
return new Promise((resolve) => {
|
|
@@ -500,7 +599,8 @@ function persistWithSync(stateCreator, persistOptions, syncApi, syncOptions = {}
|
|
|
500
599
|
syncState: {
|
|
501
600
|
firstLoadDone: syncState.firstLoadDone,
|
|
502
601
|
pendingChanges: syncState.pendingChanges,
|
|
503
|
-
lastPulled: syncState.lastPulled
|
|
602
|
+
lastPulled: syncState.lastPulled,
|
|
603
|
+
conflicts: syncState.conflicts
|
|
504
604
|
}
|
|
505
605
|
};
|
|
506
606
|
},
|
|
@@ -509,7 +609,7 @@ function persistWithSync(stateCreator, persistOptions, syncApi, syncOptions = {}
|
|
|
509
609
|
return {
|
|
510
610
|
...state,
|
|
511
611
|
syncState: {
|
|
512
|
-
...state.syncState,
|
|
612
|
+
...state.syncState || {},
|
|
513
613
|
status: "idle"
|
|
514
614
|
// this confirms 'hydrating' is done
|
|
515
615
|
}
|
|
@@ -517,13 +617,12 @@ function persistWithSync(stateCreator, persistOptions, syncApi, syncOptions = {}
|
|
|
517
617
|
}
|
|
518
618
|
};
|
|
519
619
|
const creator = (set, get, storeApi) => {
|
|
520
|
-
let
|
|
620
|
+
let syncTimerStarted = false;
|
|
521
621
|
async function syncOnce() {
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
set((state2) => ({
|
|
622
|
+
if (get().syncState.status !== "idle") return;
|
|
623
|
+
set((state) => ({
|
|
525
624
|
syncState: {
|
|
526
|
-
...
|
|
625
|
+
...state.syncState || {},
|
|
527
626
|
status: "syncing"
|
|
528
627
|
}
|
|
529
628
|
}));
|
|
@@ -558,24 +657,13 @@ function persistWithSync(stateCreator, persistOptions, syncApi, syncOptions = {}
|
|
|
558
657
|
logger.error(`[zync] push:error change=${change}`, err);
|
|
559
658
|
}
|
|
560
659
|
}
|
|
561
|
-
set((
|
|
660
|
+
set((state) => ({
|
|
562
661
|
syncState: {
|
|
563
|
-
...
|
|
662
|
+
...state.syncState || {},
|
|
564
663
|
status: "idle",
|
|
565
664
|
error: firstSyncError
|
|
566
665
|
}
|
|
567
666
|
}));
|
|
568
|
-
if (get().syncState.pendingChanges.length > 0 && !firstSyncError) {
|
|
569
|
-
await syncOnce();
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
function setAndSyncOnce(partial) {
|
|
573
|
-
if (typeof partial === "function") {
|
|
574
|
-
set((state) => ({ ...partial(state) }));
|
|
575
|
-
} else {
|
|
576
|
-
set(partial);
|
|
577
|
-
}
|
|
578
|
-
syncOnce();
|
|
579
667
|
}
|
|
580
668
|
function setAndQueueToSync(partial) {
|
|
581
669
|
if (typeof partial === "function") {
|
|
@@ -583,7 +671,6 @@ function persistWithSync(stateCreator, persistOptions, syncApi, syncOptions = {}
|
|
|
583
671
|
} else {
|
|
584
672
|
set((state) => newSyncState(state, partial));
|
|
585
673
|
}
|
|
586
|
-
syncOnce();
|
|
587
674
|
}
|
|
588
675
|
function newSyncState(state, partial) {
|
|
589
676
|
const pendingChanges = state.syncState.pendingChanges || [];
|
|
@@ -593,11 +680,13 @@ function persistWithSync(stateCreator, persistOptions, syncApi, syncOptions = {}
|
|
|
593
680
|
const changes = findChanges(current, updated);
|
|
594
681
|
tryAddToPendingChanges(pendingChanges, stateKey, changes);
|
|
595
682
|
});
|
|
683
|
+
const conflicts = tryUpdateConflicts(pendingChanges, state.syncState.conflicts);
|
|
596
684
|
return {
|
|
597
685
|
...partial,
|
|
598
686
|
syncState: {
|
|
599
687
|
...state.syncState || {},
|
|
600
|
-
pendingChanges
|
|
688
|
+
pendingChanges,
|
|
689
|
+
conflicts
|
|
601
690
|
}
|
|
602
691
|
};
|
|
603
692
|
}
|
|
@@ -605,18 +694,26 @@ function persistWithSync(stateCreator, persistOptions, syncApi, syncOptions = {}
|
|
|
605
694
|
set((state) => ({
|
|
606
695
|
syncState: {
|
|
607
696
|
...state.syncState || {},
|
|
608
|
-
enabled
|
|
697
|
+
status: enabled ? "idle" : "disabled"
|
|
609
698
|
}
|
|
610
699
|
}));
|
|
611
|
-
|
|
700
|
+
startSyncTimer(enabled);
|
|
612
701
|
addVisibilityChangeListener(enabled);
|
|
613
702
|
}
|
|
614
|
-
function
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
703
|
+
function startSyncTimer(start) {
|
|
704
|
+
if (start) {
|
|
705
|
+
tryStart();
|
|
706
|
+
} else {
|
|
707
|
+
syncTimerStarted = false;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
async function tryStart() {
|
|
711
|
+
if (syncTimerStarted) return;
|
|
712
|
+
syncTimerStarted = true;
|
|
713
|
+
while (true) {
|
|
714
|
+
if (!syncTimerStarted) break;
|
|
715
|
+
await syncOnce();
|
|
716
|
+
await sleep(syncInterval);
|
|
620
717
|
}
|
|
621
718
|
}
|
|
622
719
|
function addVisibilityChangeListener(add) {
|
|
@@ -629,24 +726,25 @@ function persistWithSync(stateCreator, persistOptions, syncApi, syncOptions = {}
|
|
|
629
726
|
function onVisibilityChange() {
|
|
630
727
|
if (document.visibilityState === "visible") {
|
|
631
728
|
logger.debug("[zync] sync:start-in-foreground");
|
|
632
|
-
|
|
729
|
+
startSyncTimer(true);
|
|
633
730
|
} else {
|
|
634
731
|
logger.debug("[zync] sync:pause-in-background");
|
|
635
|
-
|
|
732
|
+
startSyncTimer(false);
|
|
636
733
|
}
|
|
637
734
|
}
|
|
638
735
|
storeApi.sync = {
|
|
639
736
|
enable,
|
|
640
|
-
startFirstLoad: () => startFirstLoad(set, syncApi, logger)
|
|
737
|
+
startFirstLoad: () => startFirstLoad(set, syncApi, logger),
|
|
738
|
+
resolveConflict: (localId, keepLocal) => resolveConflict(set, localId, keepLocal)
|
|
641
739
|
};
|
|
642
|
-
const userState = stateCreator(
|
|
740
|
+
const userState = stateCreator(set, get, setAndQueueToSync);
|
|
643
741
|
return {
|
|
644
742
|
...userState,
|
|
645
743
|
syncState: {
|
|
646
744
|
// set defaults
|
|
647
745
|
status: "hydrating",
|
|
648
746
|
error: void 0,
|
|
649
|
-
|
|
747
|
+
conflicts: void 0,
|
|
650
748
|
firstLoadDone: false,
|
|
651
749
|
pendingChanges: [],
|
|
652
750
|
lastPulled: {}
|
|
@@ -657,9 +755,11 @@ function persistWithSync(stateCreator, persistOptions, syncApi, syncOptions = {}
|
|
|
657
755
|
}
|
|
658
756
|
export {
|
|
659
757
|
SyncAction,
|
|
758
|
+
changeKeysFrom,
|
|
759
|
+
changeKeysTo,
|
|
660
760
|
createIndexedDBStorage,
|
|
761
|
+
createLocalId,
|
|
661
762
|
createWithSync,
|
|
662
|
-
nextLocalId,
|
|
663
763
|
persistWithSync
|
|
664
764
|
};
|
|
665
765
|
//# sourceMappingURL=index.js.map
|