diff --git a/packages/core/api/index.js b/packages/core/api/index.js index 63c93d5fb..407c4fb64 100644 --- a/packages/core/api/index.js +++ b/packages/core/api/index.js @@ -237,7 +237,7 @@ class Database { } async lastSynced() { - return this.storage.read("lastSynced"); + return (await this.storage.read("lastSynced")) || 0; } sync(full = true, force = false) { diff --git a/packages/core/api/sync/__tests__/sync.test.js b/packages/core/api/sync/__tests__/sync.test.js index d11858e4c..580931e6d 100644 --- a/packages/core/api/sync/__tests__/sync.test.js +++ b/packages/core/api/sync/__tests__/sync.test.js @@ -181,6 +181,26 @@ test.skip( 60 * 1000 ); +test( + "issue: running force sync from device A makes device B always download everything", + async () => { + const deviceA = await initializeDevice("deviceA"); + const deviceB = await initializeDevice("deviceB"); + + await syncAndWait(deviceA, deviceB, true); + + const handler = jest.fn(); + deviceB.eventManager.subscribe(EVENTS.syncProgress, handler); + + await deviceB.sync(true); + + expect(handler).not.toHaveBeenCalled(); + + await cleanup(deviceB); + }, + 60 * 1000 +); + /** * * @param {string} id @@ -240,13 +260,13 @@ function waitForSyncCompleted(device) { * @param {Database} deviceB * @returns */ -function syncAndWait(deviceA, deviceB) { +function syncAndWait(deviceA, deviceB, force = false) { return new Promise((resolve) => { const ref = deviceB.eventManager.subscribe(EVENTS.syncCompleted, () => { ref.unsubscribe(); resolve(); }); - deviceA.sync(true); + deviceA.sync(true, force); }); } diff --git a/packages/core/api/sync/index.js b/packages/core/api/sync/index.js index fe9c391c1..9384ef0c7 100644 --- a/packages/core/api/sync/index.js +++ b/packages/core/api/sync/index.js @@ -109,8 +109,8 @@ class Sync { ); }); - this.connection.on("RemoteSyncCompleted", () => { - this.onRemoteSyncCompleted(); + this.connection.on("RemoteSyncCompleted", (lastSynced) => { + this.onRemoteSyncCompleted(lastSynced); }); } @@ -120,7 +120,7 @@ class Sync { * @param {boolean} force * @param {Object} ignoredIds */ - async start(full, force) { + async start(full, force, serverLastSynced) { this.connection.onclose(() => { throw new Error("Connection closed."); }); @@ -136,7 +136,7 @@ class Sync { } else if (serverResponse) { await this.stop(serverResponse.lastSynced); } else { - await this.stop(oldLastSynced); + await this.stop(serverLastSynced || oldLastSynced); } } @@ -146,7 +146,7 @@ class Sync { await this.conflicts.recalculate(); - let lastSynced = (await this.db.lastSynced()) || 0; + let lastSynced = await this.db.lastSynced(); if (isForceSync) lastSynced = 0; const oldLastSynced = lastSynced; @@ -155,15 +155,10 @@ class Sync { async fetch(lastSynced) { const serverResponse = await new Promise((resolve, reject) => { - let serverLastSynced = 0; - let _synced = false; - let counter = { count: 0 }; this.connection.stream("FetchItems", lastSynced).subscribe({ next: async (/** @type {SyncTransferItem} */ syncStatus) => { const { total, item, synced, lastSynced } = syncStatus; - serverLastSynced = lastSynced; - _synced = synced; try { if (synced || !item) return; @@ -173,15 +168,14 @@ class Sync { const progress = total - counter.count; sendSyncProgressEvent( this.db.eventManager, - "download", + `download`, total, progress ); } catch (e) { reject(e); } finally { - if (--counter.count <= 0) - resolve({ synced: _synced, lastSynced: serverLastSynced }); + if (--counter.count <= 0) resolve({ synced, lastSynced }); } }, complete: () => {}, @@ -327,8 +321,8 @@ class Sync { /** * @private */ - async onRemoteSyncCompleted() { - await this.start(false, false); + async onRemoteSyncCompleted(lastSynced) { + await this.start(false, false, lastSynced); } /**