@signaldb/sync 2.0.0-beta.0 → 2.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/dist/SyncManager.d.ts +6 -9
- package/dist/index.mjs +156 -178
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +2 -2
- package/dist/index.umd.js.map +1 -1
- package/package.json +2 -2
package/dist/SyncManager.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BaseItem,
|
|
1
|
+
import type { BaseItem, DataAdapter, ReactivityAdapter, Changeset } from '@signaldb/core';
|
|
2
2
|
import { Collection } from '@signaldb/core';
|
|
3
3
|
import PromiseQueue from './utils/PromiseQueue';
|
|
4
4
|
import type { Change, LoadResponse, Snapshot, SyncOperation } from './types';
|
|
@@ -19,7 +19,7 @@ interface Options<CollectionOptions extends Record<string, any>, ItemType extend
|
|
|
19
19
|
}) => Promise<void>;
|
|
20
20
|
registerRemoteChange?: (collectionOptions: SyncOptions<CollectionOptions>, onChange: (data?: LoadResponse<ItemType>) => Promise<void>) => CleanupFunction | Promise<CleanupFunction>;
|
|
21
21
|
id?: string;
|
|
22
|
-
|
|
22
|
+
dataAdapter?: DataAdapter;
|
|
23
23
|
reactivity?: ReactivityAdapter;
|
|
24
24
|
onError?: (collectionOptions: SyncOptions<CollectionOptions>, error: Error) => void;
|
|
25
25
|
autostart?: boolean;
|
|
@@ -66,7 +66,7 @@ export default class SyncManager<CollectionOptions extends Record<string, any>,
|
|
|
66
66
|
protected scheduledPushes: Set<string>;
|
|
67
67
|
protected remoteChanges: Omit<Change, 'id' | 'time'>[];
|
|
68
68
|
protected syncQueues: Map<string, PromiseQueue>;
|
|
69
|
-
protected
|
|
69
|
+
protected collectionsReady: Promise<void>;
|
|
70
70
|
protected isDisposed: boolean;
|
|
71
71
|
protected instanceId: string;
|
|
72
72
|
protected id: string;
|
|
@@ -84,10 +84,6 @@ export default class SyncManager<CollectionOptions extends Record<string, any>,
|
|
|
84
84
|
* @param [options.debounceTime] The time in milliseconds to debounce push operations.
|
|
85
85
|
*/
|
|
86
86
|
constructor(options: Options<CollectionOptions, ItemType, IdType>);
|
|
87
|
-
protected createStorageAdapter(name: string): {
|
|
88
|
-
adapter: StorageAdapter<any, any>;
|
|
89
|
-
handler: (error: Error) => void;
|
|
90
|
-
} | undefined;
|
|
91
87
|
protected getSyncQueue(name: string): PromiseQueue;
|
|
92
88
|
/**
|
|
93
89
|
* Clears all internal data structures
|
|
@@ -154,9 +150,10 @@ export default class SyncManager<CollectionOptions extends Record<string, any>,
|
|
|
154
150
|
/**
|
|
155
151
|
* Checks if a collection is currently beeing synced
|
|
156
152
|
* @param [name] Name of the collection. If not provided, it will check if any collection is currently beeing synced.
|
|
157
|
-
* @
|
|
153
|
+
* @param [async] If true, it will check for active syncs in the database. This is useful if you have multiple instances of the application running.
|
|
154
|
+
* @returns True if the collection is currently beeing synced, false otherwise. If async is true, it will return a promise that resolves to true or false.
|
|
158
155
|
*/
|
|
159
|
-
isSyncing(name?: string): boolean;
|
|
156
|
+
isSyncing<Async extends boolean = false>(name?: string, async?: Async): Async extends true ? Promise<boolean> : boolean;
|
|
160
157
|
/**
|
|
161
158
|
* Checks if the sync manager is ready to sync.
|
|
162
159
|
* @returns A promise that resolves when the sync manager is ready to sync.
|
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { isEqual as
|
|
2
|
-
function
|
|
3
|
-
let s,
|
|
4
|
-
const { leading:
|
|
5
|
-
function
|
|
6
|
-
const i =
|
|
1
|
+
import { isEqual as N, modify as w, randomId as S, DefaultDataAdapter as E, Collection as y } from "@signaldb/core";
|
|
2
|
+
function $(l, e, t = {}) {
|
|
3
|
+
let s, o;
|
|
4
|
+
const { leading: n = !1, trailing: a = !0 } = t;
|
|
5
|
+
function r(...c) {
|
|
6
|
+
const i = n && !s, h = a && !s;
|
|
7
7
|
return s && clearTimeout(s), s = setTimeout(() => {
|
|
8
|
-
s = null, a && !i && (
|
|
9
|
-
}, e), i ?
|
|
8
|
+
s = null, a && !i && (o = l.apply(this, c));
|
|
9
|
+
}, e), i ? o = l.apply(this, c) : h || (o = null), o;
|
|
10
10
|
}
|
|
11
|
-
return
|
|
11
|
+
return r;
|
|
12
12
|
}
|
|
13
13
|
class D {
|
|
14
14
|
queue = [];
|
|
@@ -20,8 +20,8 @@ class D {
|
|
|
20
20
|
*/
|
|
21
21
|
add(e) {
|
|
22
22
|
return new Promise((t, s) => {
|
|
23
|
-
this.queue.push(() => e().then(t).catch((
|
|
24
|
-
throw s(
|
|
23
|
+
this.queue.push(() => e().then(t).catch((o) => {
|
|
24
|
+
throw s(o), o;
|
|
25
25
|
})), this.dequeue();
|
|
26
26
|
});
|
|
27
27
|
}
|
|
@@ -46,80 +46,80 @@ class D {
|
|
|
46
46
|
}));
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
function C(
|
|
50
|
-
const t = [], s = Object.keys(
|
|
51
|
-
for (const a of
|
|
52
|
-
if (e[a] !==
|
|
53
|
-
if (typeof e[a] == "object" && typeof
|
|
54
|
-
const
|
|
55
|
-
for (const
|
|
56
|
-
t.push(`${a}.${
|
|
49
|
+
function C(l, e) {
|
|
50
|
+
const t = [], s = Object.keys(l), o = Object.keys(e), n = /* @__PURE__ */ new Set([...s, ...o]);
|
|
51
|
+
for (const a of n)
|
|
52
|
+
if (e[a] !== l[a])
|
|
53
|
+
if (typeof e[a] == "object" && typeof l[a] == "object" && e[a] != null && l[a] != null) {
|
|
54
|
+
const r = C(l[a], e[a]);
|
|
55
|
+
for (const c of r)
|
|
56
|
+
t.push(`${a}.${c}`);
|
|
57
57
|
} else
|
|
58
58
|
t.push(a);
|
|
59
59
|
return t;
|
|
60
60
|
}
|
|
61
|
-
function f(
|
|
62
|
-
const t = [], s = [],
|
|
63
|
-
for (const [
|
|
64
|
-
const
|
|
65
|
-
|
|
61
|
+
function f(l, e) {
|
|
62
|
+
const t = [], s = [], o = /* @__PURE__ */ new Map(), n = [], a = new Map(l.map((c) => [c.id, c])), r = new Map(e.map((c) => [c.id, c]));
|
|
63
|
+
for (const [c, i] of a) {
|
|
64
|
+
const h = r.get(c);
|
|
65
|
+
h ? N(h, i) || (o.set(h.id, C(i, h)), s.push(h)) : n.push(i);
|
|
66
66
|
}
|
|
67
|
-
for (const [
|
|
68
|
-
a.has(
|
|
67
|
+
for (const [c, i] of r)
|
|
68
|
+
a.has(c) || t.push(i);
|
|
69
69
|
return {
|
|
70
70
|
added: t,
|
|
71
71
|
modified: s,
|
|
72
|
-
modifiedFields:
|
|
73
|
-
removed:
|
|
72
|
+
modifiedFields: o,
|
|
73
|
+
removed: n
|
|
74
74
|
};
|
|
75
75
|
}
|
|
76
|
-
function
|
|
76
|
+
function g(l, e) {
|
|
77
77
|
if (e.items != null)
|
|
78
78
|
return e.items;
|
|
79
|
-
const t =
|
|
79
|
+
const t = l || [];
|
|
80
80
|
return e.changes.added.forEach((s) => {
|
|
81
|
-
const
|
|
82
|
-
|
|
81
|
+
const o = t.findIndex((n) => n.id === s.id);
|
|
82
|
+
o === -1 ? t.push(s) : t[o] = s;
|
|
83
83
|
}), e.changes.modified.forEach((s) => {
|
|
84
|
-
const
|
|
85
|
-
|
|
84
|
+
const o = t.findIndex((n) => n.id === s.id);
|
|
85
|
+
o === -1 ? t.push(s) : t[o] = s;
|
|
86
86
|
}), e.changes.removed.forEach((s) => {
|
|
87
|
-
const
|
|
88
|
-
|
|
87
|
+
const o = t.findIndex((n) => n.id === s.id);
|
|
88
|
+
o !== -1 && t.splice(o, 1);
|
|
89
89
|
}), t;
|
|
90
90
|
}
|
|
91
|
-
function P(
|
|
92
|
-
const t = new Map(
|
|
91
|
+
function P(l, e) {
|
|
92
|
+
const t = new Map(l.map((s) => [s.id, s]));
|
|
93
93
|
return e.forEach((s) => {
|
|
94
94
|
if (s.type === "remove")
|
|
95
95
|
t.delete(s.data);
|
|
96
96
|
else if (s.type === "insert") {
|
|
97
|
-
const
|
|
98
|
-
t.set(s.data.id,
|
|
97
|
+
const o = t.get(s.data.id);
|
|
98
|
+
t.set(s.data.id, o ? { ...o, ...s.data } : s.data);
|
|
99
99
|
} else {
|
|
100
|
-
const
|
|
101
|
-
t.set(s.data.id,
|
|
100
|
+
const o = t.get(s.data.id);
|
|
101
|
+
t.set(s.data.id, o ? w(o, s.data.modifier) : w({ id: s.data.id }, s.data.modifier));
|
|
102
102
|
}
|
|
103
103
|
}), [...t.values()];
|
|
104
104
|
}
|
|
105
|
-
function v(
|
|
106
|
-
return
|
|
105
|
+
function v(l) {
|
|
106
|
+
return l.added.length > 0 || l.modified.length > 0 || l.removed.length > 0;
|
|
107
107
|
}
|
|
108
|
-
function M(
|
|
109
|
-
return v(f(
|
|
108
|
+
function M(l, e) {
|
|
109
|
+
return v(f(l, e));
|
|
110
110
|
}
|
|
111
|
-
async function F({ changes:
|
|
112
|
-
let i = t,
|
|
113
|
-
if (
|
|
114
|
-
const u = P(
|
|
115
|
-
if (M(
|
|
116
|
-
const
|
|
117
|
-
v(m) && (await
|
|
111
|
+
async function F({ changes: l, lastSnapshot: e, data: t, pull: s, push: o, insert: n, update: a, remove: r, batch: c }) {
|
|
112
|
+
let i = t, h = e || [], p = g(e, i);
|
|
113
|
+
if (l.length > 0) {
|
|
114
|
+
const u = P(h, l);
|
|
115
|
+
if (M(h, u)) {
|
|
116
|
+
const O = P(p, l), m = f(p, O);
|
|
117
|
+
v(m) && (await o(m), i = await s(), p = g(p, i)), h = u;
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
|
-
const d = i.changes == null ? f(
|
|
121
|
-
return await
|
|
122
|
-
await Promise.all(d.added.map((u) =>
|
|
120
|
+
const d = i.changes == null ? f(h, i.items) : i.changes;
|
|
121
|
+
return await c(async () => {
|
|
122
|
+
await Promise.all(d.added.map((u) => n(u))), await Promise.all(d.modified.map((u) => a(u.id, { $set: u }))), await Promise.all(d.removed.map((u) => r(u.id)));
|
|
123
123
|
}), p;
|
|
124
124
|
}
|
|
125
125
|
class b {
|
|
@@ -131,9 +131,9 @@ class b {
|
|
|
131
131
|
scheduledPushes = /* @__PURE__ */ new Set();
|
|
132
132
|
remoteChanges = [];
|
|
133
133
|
syncQueues = /* @__PURE__ */ new Map();
|
|
134
|
-
|
|
134
|
+
collectionsReady;
|
|
135
135
|
isDisposed = !1;
|
|
136
|
-
instanceId =
|
|
136
|
+
instanceId = S();
|
|
137
137
|
id;
|
|
138
138
|
debouncedFlush;
|
|
139
139
|
/**
|
|
@@ -153,53 +153,22 @@ class b {
|
|
|
153
153
|
autostart: !0,
|
|
154
154
|
...e
|
|
155
155
|
}, this.id = this.options.id || "default-sync-manager";
|
|
156
|
-
const { reactivity: t } = this.options, s = this.
|
|
157
|
-
|
|
158
|
-
if (c === `${this.options.id}-changes`)
|
|
159
|
-
return s?.adapter;
|
|
160
|
-
if (c === `${this.options.id}-snapshots`)
|
|
161
|
-
return n?.adapter;
|
|
162
|
-
if (c === `${this.options.id}-sync-operations`)
|
|
163
|
-
return o?.adapter;
|
|
164
|
-
throw new Error(`Unknown storage name: ${c}`);
|
|
165
|
-
},
|
|
166
|
-
onError: (c, r) => {
|
|
167
|
-
if (c === "changes")
|
|
168
|
-
return s?.handler(r);
|
|
169
|
-
if (c === "snapshots")
|
|
170
|
-
return n?.handler(r);
|
|
171
|
-
if (c === "sync-operations")
|
|
172
|
-
return o?.handler(r);
|
|
173
|
-
throw new Error(`Error in unknown storage name: ${c}`, { cause: r });
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
this.changes = new y(`${this.options.id}-changes`, a, {
|
|
156
|
+
const { reactivity: t } = this.options, s = this.options.dataAdapter ?? new E();
|
|
157
|
+
this.changes = new y(`${this.options.id}-changes`, s, {
|
|
177
158
|
indices: ["collectionName"],
|
|
178
159
|
reactivity: t
|
|
179
|
-
}), this.snapshots = new y(`${this.options.id}-snapshots`,
|
|
160
|
+
}), this.snapshots = new y(`${this.options.id}-snapshots`, s, {
|
|
180
161
|
indices: ["collectionName"],
|
|
181
162
|
reactivity: t
|
|
182
|
-
}), this.syncOperations = new y(`${this.options.id}-sync-operations`,
|
|
163
|
+
}), this.syncOperations = new y(`${this.options.id}-sync-operations`, s, {
|
|
183
164
|
indices: ["collectionName", "status"],
|
|
184
165
|
reactivity: t
|
|
185
|
-
}), this.
|
|
166
|
+
}), this.collectionsReady = Promise.all([
|
|
186
167
|
this.syncOperations.isReady(),
|
|
187
168
|
this.changes.isReady(),
|
|
188
169
|
this.snapshots.isReady()
|
|
189
170
|
]).then(() => {
|
|
190
|
-
}), this.changes.setMaxListeners(1e3), this.snapshots.setMaxListeners(1e3), this.syncOperations.setMaxListeners(1e3), this.debouncedFlush =
|
|
191
|
-
}
|
|
192
|
-
createStorageAdapter(e) {
|
|
193
|
-
if (this.options.storageAdapter == null)
|
|
194
|
-
return;
|
|
195
|
-
let t = () => {
|
|
196
|
-
};
|
|
197
|
-
return {
|
|
198
|
-
adapter: this.options.storageAdapter(`${this.id}-${e}`, (n) => {
|
|
199
|
-
t = n;
|
|
200
|
-
}),
|
|
201
|
-
handler: (n) => t(n)
|
|
202
|
-
};
|
|
171
|
+
}), this.changes.setMaxListeners(1e3), this.snapshots.setMaxListeners(1e3), this.syncOperations.setMaxListeners(1e3), this.debouncedFlush = $(this.flushScheduledPushes, this.options.debounceTime ?? 100);
|
|
203
172
|
}
|
|
204
173
|
getSyncQueue(e) {
|
|
205
174
|
return this.syncQueues.get(e) == null && this.syncQueues.set(e, new D()), this.syncQueues.get(e);
|
|
@@ -253,67 +222,67 @@ class b {
|
|
|
253
222
|
syncPaused: !0
|
|
254
223
|
// always start paused as the autostart will start it
|
|
255
224
|
});
|
|
256
|
-
const s = (
|
|
225
|
+
const s = (n) => {
|
|
257
226
|
for (const a of this.remoteChanges)
|
|
258
|
-
if (a != null && a.collectionName ===
|
|
227
|
+
if (a != null && a.collectionName === n.collectionName && a.type === n.type && !(n.type === "remove" && a.data !== n.data) && a.data.id === n.data.id)
|
|
259
228
|
return !0;
|
|
260
229
|
return !1;
|
|
261
|
-
},
|
|
262
|
-
const
|
|
263
|
-
for (let
|
|
264
|
-
const i = c
|
|
265
|
-
i != null && i.collectionName ===
|
|
230
|
+
}, o = (n, a) => {
|
|
231
|
+
const r = [...this.remoteChanges];
|
|
232
|
+
for (let c = 0; c < r.length; c += 1) {
|
|
233
|
+
const i = r[c];
|
|
234
|
+
i != null && i.collectionName === n && (i.type === "remove" && i.data !== a || i.data.id === a && (r[c] = null));
|
|
266
235
|
}
|
|
267
|
-
this.remoteChanges =
|
|
236
|
+
this.remoteChanges = r.filter((c) => c != null);
|
|
268
237
|
};
|
|
269
|
-
e.on("added", (
|
|
270
|
-
if (s({ collectionName: t.name, type: "insert", data:
|
|
271
|
-
|
|
238
|
+
e.on("added", (n) => {
|
|
239
|
+
if (s({ collectionName: t.name, type: "insert", data: n })) {
|
|
240
|
+
o(t.name, n.id);
|
|
272
241
|
return;
|
|
273
242
|
}
|
|
274
243
|
this.changes.insert({
|
|
275
244
|
collectionName: t.name,
|
|
276
245
|
time: Date.now(),
|
|
277
246
|
type: "insert",
|
|
278
|
-
data:
|
|
247
|
+
data: n
|
|
279
248
|
}).then(() => {
|
|
280
249
|
this.getCollectionProperties(t.name).syncPaused || this.schedulePush(t.name);
|
|
281
250
|
}).catch((a) => {
|
|
282
251
|
this.options.onError && this.options.onError(this.getCollectionProperties(t.name).options, a);
|
|
283
252
|
});
|
|
284
|
-
}), e.on("changed", ({ id:
|
|
285
|
-
const
|
|
286
|
-
if (s({ collectionName: t.name, type: "update", data:
|
|
287
|
-
|
|
253
|
+
}), e.on("changed", ({ id: n }, a) => {
|
|
254
|
+
const r = { id: n, modifier: a };
|
|
255
|
+
if (s({ collectionName: t.name, type: "update", data: r })) {
|
|
256
|
+
o(t.name, n);
|
|
288
257
|
return;
|
|
289
258
|
}
|
|
290
259
|
this.changes.insert({
|
|
291
260
|
collectionName: t.name,
|
|
292
261
|
time: Date.now(),
|
|
293
262
|
type: "update",
|
|
294
|
-
data:
|
|
263
|
+
data: r
|
|
295
264
|
}).then(() => {
|
|
296
265
|
this.getCollectionProperties(t.name).syncPaused || this.schedulePush(t.name);
|
|
297
|
-
}).catch((
|
|
298
|
-
this.options.onError && this.options.onError(this.getCollectionProperties(t.name).options,
|
|
266
|
+
}).catch((c) => {
|
|
267
|
+
this.options.onError && this.options.onError(this.getCollectionProperties(t.name).options, c);
|
|
299
268
|
});
|
|
300
|
-
}), e.on("removed", ({ id:
|
|
301
|
-
if (s({ collectionName: t.name, type: "remove", data:
|
|
302
|
-
|
|
269
|
+
}), e.on("removed", ({ id: n }) => {
|
|
270
|
+
if (s({ collectionName: t.name, type: "remove", data: n })) {
|
|
271
|
+
o(t.name, n);
|
|
303
272
|
return;
|
|
304
273
|
}
|
|
305
274
|
this.changes.insert({
|
|
306
275
|
collectionName: t.name,
|
|
307
276
|
time: Date.now(),
|
|
308
277
|
type: "remove",
|
|
309
|
-
data:
|
|
278
|
+
data: n
|
|
310
279
|
}).then(() => {
|
|
311
280
|
this.getCollectionProperties(t.name).syncPaused || this.schedulePush(t.name);
|
|
312
281
|
}).catch((a) => {
|
|
313
282
|
this.options.onError && this.options.onError(this.getCollectionProperties(t.name).options, a);
|
|
314
283
|
});
|
|
315
|
-
}), this.options.autostart && this.startSync(t.name).catch((
|
|
316
|
-
this.options.onError && this.options.onError(this.getCollectionProperties(t.name).options,
|
|
284
|
+
}), this.options.autostart && this.startSync(t.name).catch((n) => {
|
|
285
|
+
this.options.onError && this.options.onError(this.getCollectionProperties(t.name).options, n);
|
|
317
286
|
});
|
|
318
287
|
}
|
|
319
288
|
flushScheduledPushes() {
|
|
@@ -342,31 +311,31 @@ class b {
|
|
|
342
311
|
if (!t.syncPaused)
|
|
343
312
|
return;
|
|
344
313
|
this.schedulePush(e);
|
|
345
|
-
const s = this.options.registerRemoteChange ? await this.options.registerRemoteChange(t.options, async (
|
|
346
|
-
if (
|
|
314
|
+
const s = this.options.registerRemoteChange ? await this.options.registerRemoteChange(t.options, async (o) => {
|
|
315
|
+
if (o == null)
|
|
347
316
|
await this.sync(e);
|
|
348
317
|
else {
|
|
349
|
-
const
|
|
350
|
-
start:
|
|
318
|
+
const n = Date.now(), a = await this.syncOperations.insert({
|
|
319
|
+
start: n,
|
|
351
320
|
collectionName: e,
|
|
352
321
|
instanceId: this.instanceId,
|
|
353
322
|
status: "active"
|
|
354
323
|
});
|
|
355
|
-
await this.syncWithData(e,
|
|
324
|
+
await this.syncWithData(e, o).then(async () => {
|
|
356
325
|
await this.syncOperations.removeMany({
|
|
357
326
|
id: { $ne: a },
|
|
358
327
|
collectionName: e,
|
|
359
328
|
$or: [
|
|
360
|
-
{ end: { $lte:
|
|
329
|
+
{ end: { $lte: n } },
|
|
361
330
|
{ status: "active" }
|
|
362
331
|
]
|
|
363
332
|
}), await this.syncOperations.updateOne({ id: a }, {
|
|
364
333
|
$set: { status: "done", end: Date.now() }
|
|
365
334
|
});
|
|
366
|
-
}).catch(async (
|
|
367
|
-
throw this.options.onError && this.options.onError(this.getCollectionProperties(e).options,
|
|
368
|
-
$set: { status: "error", end: Date.now(), error:
|
|
369
|
-
}),
|
|
335
|
+
}).catch(async (r) => {
|
|
336
|
+
throw this.options.onError && this.options.onError(this.getCollectionProperties(e).options, r), await this.syncOperations.updateOne({ id: a }, {
|
|
337
|
+
$set: { status: "error", end: Date.now(), error: r.stack || r.message }
|
|
338
|
+
}), r;
|
|
370
339
|
});
|
|
371
340
|
}
|
|
372
341
|
}) : void 0;
|
|
@@ -416,20 +385,22 @@ ${e.map((t) => `${t.id}: ${t.error.message}`).join(`
|
|
|
416
385
|
/**
|
|
417
386
|
* Checks if a collection is currently beeing synced
|
|
418
387
|
* @param [name] Name of the collection. If not provided, it will check if any collection is currently beeing synced.
|
|
419
|
-
* @
|
|
388
|
+
* @param [async] If true, it will check for active syncs in the database. This is useful if you have multiple instances of the application running.
|
|
389
|
+
* @returns True if the collection is currently beeing synced, false otherwise. If async is true, it will return a promise that resolves to true or false.
|
|
420
390
|
*/
|
|
421
|
-
isSyncing(e) {
|
|
422
|
-
|
|
391
|
+
isSyncing(e, t) {
|
|
392
|
+
const s = this.syncOperations.findOne({
|
|
423
393
|
...e ? { collectionName: e } : {},
|
|
424
394
|
status: "active"
|
|
425
|
-
}, { fields: { status: 1 } })
|
|
395
|
+
}, { fields: { status: 1 }, async: t });
|
|
396
|
+
return s instanceof Promise ? s.then((o) => o != null) : s != null;
|
|
426
397
|
}
|
|
427
398
|
/**
|
|
428
399
|
* Checks if the sync manager is ready to sync.
|
|
429
400
|
* @returns A promise that resolves when the sync manager is ready to sync.
|
|
430
401
|
*/
|
|
431
402
|
async isReady() {
|
|
432
|
-
await this.
|
|
403
|
+
await this.collectionsReady;
|
|
433
404
|
}
|
|
434
405
|
/**
|
|
435
406
|
* Starts the sync process for a collection
|
|
@@ -442,59 +413,62 @@ ${e.map((t) => `${t.id}: ${t.error.message}`).join(`
|
|
|
442
413
|
if (this.isDisposed)
|
|
443
414
|
throw new Error("SyncManager is disposed");
|
|
444
415
|
await this.isReady();
|
|
445
|
-
const { options: s, readyPromise:
|
|
446
|
-
await
|
|
447
|
-
const
|
|
416
|
+
const { options: s, readyPromise: o } = this.getCollectionProperties(e);
|
|
417
|
+
await o;
|
|
418
|
+
const n = await this.syncOperations.find({
|
|
448
419
|
collectionName: e,
|
|
449
420
|
instanceId: this.instanceId,
|
|
450
421
|
status: "active"
|
|
451
422
|
}, {
|
|
452
|
-
reactive: !1
|
|
423
|
+
reactive: !1,
|
|
424
|
+
async: !0
|
|
453
425
|
}).count() > 0, a = Date.now();
|
|
454
|
-
let
|
|
426
|
+
let r = null;
|
|
455
427
|
await new Promise((i) => {
|
|
456
428
|
setTimeout(i, 0);
|
|
457
429
|
});
|
|
458
|
-
const
|
|
459
|
-
const i = this.syncOperations.findOne({
|
|
430
|
+
const c = async () => {
|
|
431
|
+
const i = await this.syncOperations.findOne({
|
|
460
432
|
collectionName: e,
|
|
461
433
|
status: "done"
|
|
462
434
|
}, {
|
|
463
435
|
sort: { end: -1 },
|
|
464
|
-
reactive: !1
|
|
436
|
+
reactive: !1,
|
|
437
|
+
async: !0
|
|
465
438
|
});
|
|
466
|
-
if (t?.onlyWithChanges && this.changes.find({
|
|
439
|
+
if (t?.onlyWithChanges && await this.changes.find({
|
|
467
440
|
collectionName: e,
|
|
468
441
|
time: { $lte: a }
|
|
469
442
|
}, {
|
|
470
443
|
sort: { time: 1 },
|
|
471
|
-
reactive: !1
|
|
444
|
+
reactive: !1,
|
|
445
|
+
async: !0
|
|
472
446
|
}).count() === 0)
|
|
473
447
|
return;
|
|
474
|
-
|
|
448
|
+
n || (r = await this.syncOperations.insert({
|
|
475
449
|
start: a,
|
|
476
450
|
collectionName: e,
|
|
477
451
|
instanceId: this.instanceId,
|
|
478
452
|
status: "active"
|
|
479
453
|
}));
|
|
480
|
-
const
|
|
454
|
+
const h = await this.options.pull(s, {
|
|
481
455
|
lastFinishedSyncStart: i?.start,
|
|
482
456
|
lastFinishedSyncEnd: i?.end
|
|
483
457
|
});
|
|
484
|
-
await this.syncWithData(e,
|
|
458
|
+
await this.syncWithData(e, h);
|
|
485
459
|
};
|
|
486
|
-
await (t?.force ?
|
|
487
|
-
throw
|
|
460
|
+
await (t?.force ? c() : this.getSyncQueue(e).add(c)).catch(async (i) => {
|
|
461
|
+
throw r != null && (this.options.onError && this.options.onError(s, i), await this.syncOperations.updateOne({ id: r }, {
|
|
488
462
|
$set: { status: "error", end: Date.now(), error: i.stack || i.message }
|
|
489
463
|
})), i;
|
|
490
|
-
}),
|
|
491
|
-
id: { $ne:
|
|
464
|
+
}), r != null && (await this.syncOperations.removeMany({
|
|
465
|
+
id: { $ne: r },
|
|
492
466
|
collectionName: e,
|
|
493
467
|
$or: [
|
|
494
468
|
{ end: { $lte: a } },
|
|
495
469
|
{ status: "active" }
|
|
496
470
|
]
|
|
497
|
-
}), await this.syncOperations.updateOne({ id:
|
|
471
|
+
}), await this.syncOperations.updateOne({ id: r }, {
|
|
498
472
|
$set: { status: "done", end: Date.now() }
|
|
499
473
|
}));
|
|
500
474
|
}
|
|
@@ -508,35 +482,38 @@ ${e.map((t) => `${t.id}: ${t.error.message}`).join(`
|
|
|
508
482
|
});
|
|
509
483
|
}
|
|
510
484
|
async syncWithData(e, t) {
|
|
511
|
-
const { collection: s, options:
|
|
485
|
+
const { collection: s, options: o } = this.getCollectionProperties(e), n = Date.now(), a = await this.syncOperations.findOne({
|
|
512
486
|
collectionName: e,
|
|
513
487
|
status: "done"
|
|
514
488
|
}, {
|
|
515
489
|
sort: { end: -1 },
|
|
516
|
-
reactive: !1
|
|
517
|
-
|
|
490
|
+
reactive: !1,
|
|
491
|
+
async: !0
|
|
492
|
+
}), r = await this.snapshots.findOne({
|
|
518
493
|
collectionName: e
|
|
519
494
|
}, {
|
|
520
495
|
sort: { time: -1 },
|
|
521
|
-
reactive: !1
|
|
522
|
-
|
|
496
|
+
reactive: !1,
|
|
497
|
+
async: !0
|
|
498
|
+
}), c = await this.changes.find({
|
|
523
499
|
collectionName: e,
|
|
524
|
-
time: { $lte:
|
|
500
|
+
time: { $lte: n }
|
|
525
501
|
}, {
|
|
526
502
|
sort: { time: 1 },
|
|
527
|
-
reactive: !1
|
|
503
|
+
reactive: !1,
|
|
504
|
+
async: !0
|
|
528
505
|
}).fetch();
|
|
529
506
|
await F({
|
|
530
|
-
changes:
|
|
531
|
-
lastSnapshot:
|
|
507
|
+
changes: c,
|
|
508
|
+
lastSnapshot: r?.items,
|
|
532
509
|
data: t,
|
|
533
|
-
pull: () => this.options.pull(
|
|
510
|
+
pull: () => this.options.pull(o, {
|
|
534
511
|
lastFinishedSyncStart: a?.start,
|
|
535
512
|
lastFinishedSyncEnd: a?.end
|
|
536
513
|
}),
|
|
537
|
-
push: (i) => this.options.push(
|
|
514
|
+
push: (i) => this.options.push(o, {
|
|
538
515
|
changes: i,
|
|
539
|
-
rawChanges:
|
|
516
|
+
rawChanges: c
|
|
540
517
|
}),
|
|
541
518
|
insert: async (i) => {
|
|
542
519
|
this.remoteChanges.push({
|
|
@@ -549,24 +526,24 @@ ${e.map((t) => `${t.id}: ${t.error.message}`).join(`
|
|
|
549
526
|
data: { id: i.id, modifier: { $set: i } }
|
|
550
527
|
}), await s.replaceOne({ id: i.id }, i, { upsert: !0 });
|
|
551
528
|
},
|
|
552
|
-
update: async (i,
|
|
529
|
+
update: async (i, h) => {
|
|
553
530
|
this.remoteChanges.push({
|
|
554
531
|
collectionName: e,
|
|
555
532
|
type: "insert",
|
|
556
|
-
data: { id: i, ...
|
|
533
|
+
data: { id: i, ...h.$set }
|
|
557
534
|
}, {
|
|
558
535
|
collectionName: e,
|
|
559
536
|
type: "update",
|
|
560
|
-
data: { id: i, modifier:
|
|
537
|
+
data: { id: i, modifier: h }
|
|
561
538
|
}), await s.updateOne({ id: i }, {
|
|
562
|
-
...
|
|
539
|
+
...h,
|
|
563
540
|
$setOnInsert: { id: i }
|
|
564
541
|
}, { upsert: !0 });
|
|
565
542
|
},
|
|
566
543
|
remove: async (i) => {
|
|
567
|
-
s.
|
|
544
|
+
await s.find({
|
|
568
545
|
id: i
|
|
569
|
-
}, { reactive: !1 }) && (this.remoteChanges.push({
|
|
546
|
+
}, { reactive: !1, async: !0 }).count() > 0 && (this.remoteChanges.push({
|
|
570
547
|
collectionName: e,
|
|
571
548
|
type: "remove",
|
|
572
549
|
data: i
|
|
@@ -578,29 +555,30 @@ ${e.map((t) => `${t.id}: ${t.error.message}`).join(`
|
|
|
578
555
|
}).then(async (i) => {
|
|
579
556
|
if (await this.snapshots.removeMany({
|
|
580
557
|
collectionName: e,
|
|
581
|
-
time: { $lte:
|
|
558
|
+
time: { $lte: n }
|
|
582
559
|
}), await this.changes.removeMany({
|
|
583
560
|
collectionName: e,
|
|
584
|
-
id: { $in:
|
|
561
|
+
id: { $in: c.map((d) => d.id) }
|
|
585
562
|
}), await this.snapshots.insert({
|
|
586
|
-
time:
|
|
563
|
+
time: n,
|
|
587
564
|
collectionName: e,
|
|
588
565
|
items: i
|
|
589
566
|
}), await new Promise((d) => {
|
|
590
567
|
setTimeout(d, 0);
|
|
591
|
-
}), this.changes.find({
|
|
568
|
+
}), await this.changes.find({
|
|
592
569
|
collectionName: e
|
|
593
|
-
}, { reactive: !1 }).count() > 0) {
|
|
570
|
+
}, { reactive: !1, async: !0 }).count() > 0) {
|
|
594
571
|
await this.sync(e, {
|
|
595
572
|
force: !0,
|
|
596
573
|
onlyWithChanges: !0
|
|
597
574
|
});
|
|
598
575
|
return;
|
|
599
576
|
}
|
|
600
|
-
const p = s.find({
|
|
577
|
+
const p = await s.find({
|
|
601
578
|
id: { $nin: i.map((d) => d.id) }
|
|
602
579
|
}, {
|
|
603
|
-
reactive: !1
|
|
580
|
+
reactive: !1,
|
|
581
|
+
async: !0
|
|
604
582
|
}).map((d) => d.id);
|
|
605
583
|
await s.batch(async () => {
|
|
606
584
|
await Promise.all(i.map(async (d) => {
|