@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.
@@ -1,4 +1,4 @@
1
- import type { BaseItem, StorageAdapter, ReactivityAdapter, Changeset } from '@signaldb/core';
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
- storageAdapter?: (id: string, registerErrorHandler: (handler: (error: Error) => void) => void) => StorageAdapter<any, any>;
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 persistenceReady: Promise<void>;
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
- * @returns True if the collection is currently beeing synced, false otherwise.
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 O, modify as g, randomId as $, DefaultDataAdapter as N, Collection as y } from "@signaldb/core";
2
- function E(h, e, t = {}) {
3
- let s, n;
4
- const { leading: o = !1, trailing: a = !0 } = t;
5
- function c(...r) {
6
- const i = o && !s, l = a && !s;
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 && (n = h.apply(this, r));
9
- }, e), i ? n = h.apply(this, r) : l || (n = null), n;
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 c;
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((n) => {
24
- throw s(n), n;
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(h, e) {
50
- const t = [], s = Object.keys(h), n = Object.keys(e), o = /* @__PURE__ */ new Set([...s, ...n]);
51
- for (const a of o)
52
- if (e[a] !== h[a])
53
- if (typeof e[a] == "object" && typeof h[a] == "object" && e[a] != null && h[a] != null) {
54
- const c = C(h[a], e[a]);
55
- for (const r of c)
56
- t.push(`${a}.${r}`);
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(h, e) {
62
- const t = [], s = [], n = /* @__PURE__ */ new Map(), o = [], a = new Map(h.map((r) => [r.id, r])), c = new Map(e.map((r) => [r.id, r]));
63
- for (const [r, i] of a) {
64
- const l = c.get(r);
65
- l ? O(l, i) || (n.set(l.id, C(i, l)), s.push(l)) : o.push(i);
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 [r, i] of c)
68
- a.has(r) || t.push(i);
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: n,
73
- removed: o
72
+ modifiedFields: o,
73
+ removed: n
74
74
  };
75
75
  }
76
- function w(h, e) {
76
+ function g(l, e) {
77
77
  if (e.items != null)
78
78
  return e.items;
79
- const t = h || [];
79
+ const t = l || [];
80
80
  return e.changes.added.forEach((s) => {
81
- const n = t.findIndex((o) => o.id === s.id);
82
- n === -1 ? t.push(s) : t[n] = s;
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 n = t.findIndex((o) => o.id === s.id);
85
- n === -1 ? t.push(s) : t[n] = s;
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 n = t.findIndex((o) => o.id === s.id);
88
- n !== -1 && t.splice(n, 1);
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(h, e) {
92
- const t = new Map(h.map((s) => [s.id, s]));
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 n = t.get(s.data.id);
98
- t.set(s.data.id, n ? { ...n, ...s.data } : s.data);
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 n = t.get(s.data.id);
101
- t.set(s.data.id, n ? g(n, s.data.modifier) : g({ id: s.data.id }, s.data.modifier));
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(h) {
106
- return h.added.length > 0 || h.modified.length > 0 || h.removed.length > 0;
105
+ function v(l) {
106
+ return l.added.length > 0 || l.modified.length > 0 || l.removed.length > 0;
107
107
  }
108
- function M(h, e) {
109
- return v(f(h, e));
108
+ function M(l, e) {
109
+ return v(f(l, e));
110
110
  }
111
- async function F({ changes: h, lastSnapshot: e, data: t, pull: s, push: n, insert: o, update: a, remove: c, batch: r }) {
112
- let i = t, l = e || [], p = w(e, i);
113
- if (h.length > 0) {
114
- const u = P(l, h);
115
- if (M(l, u)) {
116
- const S = P(p, h), m = f(p, S);
117
- v(m) && (await n(m), i = await s(), p = w(p, i)), l = u;
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(l, i.items) : i.changes;
121
- return await r(async () => {
122
- await Promise.all(d.added.map((u) => o(u))), await Promise.all(d.modified.map((u) => a(u.id, { $set: u }))), await Promise.all(d.removed.map((u) => c(u.id)));
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
- persistenceReady;
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.createStorageAdapter("changes"), n = this.createStorageAdapter("snapshots"), o = this.createStorageAdapter("sync-operations"), a = new N({
157
- storage: (c) => {
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`, a, {
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`, a, {
163
+ }), this.syncOperations = new y(`${this.options.id}-sync-operations`, s, {
183
164
  indices: ["collectionName", "status"],
184
165
  reactivity: t
185
- }), this.persistenceReady = Promise.all([
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 = E(this.flushScheduledPushes, this.options.debounceTime ?? 100);
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 = (o) => {
225
+ const s = (n) => {
257
226
  for (const a of this.remoteChanges)
258
- if (a != null && a.collectionName === o.collectionName && a.type === o.type && !(o.type === "remove" && a.data !== o.data) && a.data.id === o.data.id)
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
- }, n = (o, a) => {
262
- const c = [...this.remoteChanges];
263
- for (let r = 0; r < c.length; r += 1) {
264
- const i = c[r];
265
- i != null && i.collectionName === o && (i.type === "remove" && i.data !== a || i.data.id === a && (c[r] = null));
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 = c.filter((r) => r != null);
236
+ this.remoteChanges = r.filter((c) => c != null);
268
237
  };
269
- e.on("added", (o) => {
270
- if (s({ collectionName: t.name, type: "insert", data: o })) {
271
- n(t.name, o.id);
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: o
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: o }, a) => {
285
- const c = { id: o, modifier: a };
286
- if (s({ collectionName: t.name, type: "update", data: c })) {
287
- n(t.name, o);
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: c
263
+ data: r
295
264
  }).then(() => {
296
265
  this.getCollectionProperties(t.name).syncPaused || this.schedulePush(t.name);
297
- }).catch((r) => {
298
- this.options.onError && this.options.onError(this.getCollectionProperties(t.name).options, r);
266
+ }).catch((c) => {
267
+ this.options.onError && this.options.onError(this.getCollectionProperties(t.name).options, c);
299
268
  });
300
- }), e.on("removed", ({ id: o }) => {
301
- if (s({ collectionName: t.name, type: "remove", data: o })) {
302
- n(t.name, o);
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: o
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((o) => {
316
- this.options.onError && this.options.onError(this.getCollectionProperties(t.name).options, o);
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 (n) => {
346
- if (n == null)
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 o = Date.now(), a = await this.syncOperations.insert({
350
- start: o,
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, n).then(async () => {
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: o } },
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 (c) => {
367
- throw this.options.onError && this.options.onError(this.getCollectionProperties(e).options, c), await this.syncOperations.updateOne({ id: a }, {
368
- $set: { status: "error", end: Date.now(), error: c.stack || c.message }
369
- }), c;
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
- * @returns True if the collection is currently beeing synced, false otherwise.
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
- return this.syncOperations.findOne({
391
+ isSyncing(e, t) {
392
+ const s = this.syncOperations.findOne({
423
393
  ...e ? { collectionName: e } : {},
424
394
  status: "active"
425
- }, { fields: { status: 1 } }) != null;
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.persistenceReady;
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: n } = this.getCollectionProperties(e);
446
- await n;
447
- const o = this.syncOperations.find({
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 c = null;
426
+ let r = null;
455
427
  await new Promise((i) => {
456
428
  setTimeout(i, 0);
457
429
  });
458
- const r = async () => {
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
- o || (c = await this.syncOperations.insert({
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 l = await this.options.pull(s, {
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, l);
458
+ await this.syncWithData(e, h);
485
459
  };
486
- await (t?.force ? r() : this.getSyncQueue(e).add(r)).catch(async (i) => {
487
- throw c != null && (this.options.onError && this.options.onError(s, i), await this.syncOperations.updateOne({ id: c }, {
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
- }), c != null && (await this.syncOperations.removeMany({
491
- id: { $ne: c },
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: c }, {
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: n } = this.getCollectionProperties(e), o = Date.now(), a = this.syncOperations.findOne({
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
- }), c = this.snapshots.findOne({
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
- }), r = this.changes.find({
496
+ reactive: !1,
497
+ async: !0
498
+ }), c = await this.changes.find({
523
499
  collectionName: e,
524
- time: { $lte: o }
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: r,
531
- lastSnapshot: c?.items,
507
+ changes: c,
508
+ lastSnapshot: r?.items,
532
509
  data: t,
533
- pull: () => this.options.pull(n, {
510
+ pull: () => this.options.pull(o, {
534
511
  lastFinishedSyncStart: a?.start,
535
512
  lastFinishedSyncEnd: a?.end
536
513
  }),
537
- push: (i) => this.options.push(n, {
514
+ push: (i) => this.options.push(o, {
538
515
  changes: i,
539
- rawChanges: r
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, l) => {
529
+ update: async (i, h) => {
553
530
  this.remoteChanges.push({
554
531
  collectionName: e,
555
532
  type: "insert",
556
- data: { id: i, ...l.$set }
533
+ data: { id: i, ...h.$set }
557
534
  }, {
558
535
  collectionName: e,
559
536
  type: "update",
560
- data: { id: i, modifier: l }
537
+ data: { id: i, modifier: h }
561
538
  }), await s.updateOne({ id: i }, {
562
- ...l,
539
+ ...h,
563
540
  $setOnInsert: { id: i }
564
541
  }, { upsert: !0 });
565
542
  },
566
543
  remove: async (i) => {
567
- s.findOne({
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: o }
558
+ time: { $lte: n }
582
559
  }), await this.changes.removeMany({
583
560
  collectionName: e,
584
- id: { $in: r.map((d) => d.id) }
561
+ id: { $in: c.map((d) => d.id) }
585
562
  }), await this.snapshots.insert({
586
- time: o,
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) => {