From 1eaf0fb922df6971851db86e5ed2857841662ba7 Mon Sep 17 00:00:00 2001 From: Max Nowack Date: Wed, 11 Dec 2024 16:02:52 +0100 Subject: [PATCH] fix: reset to snapshot after successful sync --- packages/signaldb/src/SyncManager/index.ts | 49 +++++++++++++++++++--- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/packages/signaldb/src/SyncManager/index.ts b/packages/signaldb/src/SyncManager/index.ts index 4b130a08..335ad21f 100644 --- a/packages/signaldb/src/SyncManager/index.ts +++ b/packages/signaldb/src/SyncManager/index.ts @@ -538,12 +538,49 @@ export default class SyncManager< // delay sync operation update to next tick to allow other tasks to run first await new Promise((resolve) => { setTimeout(resolve, 0) }) + + const hasChanges = this.changes.find({ + collectionName: name, + }).count() > 0 + + if (hasChanges) { + // check if there are unsynced changes to push + // and sync again if there are any + await this.sync(name, { + force: true, + onlyWithChanges: true, + }) + } else { + // if there are no unsynced changes apply the last snapshot + // to make sure that collection and snapshot are in sync + + // find all items that are not in the snapshot + const nonExistingItemIds = collection.find({ + id: { $nin: snapshot.map(item => item.id) } as any, + }).map(item => item.id) as IdType[] + + // find all items that are in the snapshot but not in the collection + const existingItemIds = new Set(snapshot + .filter(item => collection.find({ id: item.id as any }).count() > 0) + .map(item => item.id)) + + collection.batch(() => { + // update all items that are in the snapshot + snapshot.forEach((item) => { + const itemExists = existingItemIds.has(item.id) + if (itemExists) { + collection.updateOne({ id: item.id as any }, { $set: item }) + } else { + collection.insert(item) + } + }) + + // remove all items that are not in the snapshot + nonExistingItemIds.forEach((id) => { + collection.removeOne({ id: id as any }) + }) + }) + } }) - // check if there are unsynced changes to push - // after the sync was finished successfully - .then(() => this.sync(name, { - force: true, - onlyWithChanges: true, - })) } }