maxnowack / signaldb

SignalDB is a local JavaScript database with a MongoDB-like interface and TypeScript support, enabling optimistic UI with signal-based reactivity across multiple frameworks. It integrates easily with libraries like Angular, Solid.js, Preact, and Vue, simplifying data management with schema-less design, in-memory storage, and fast queries.
https://signaldb.js.org/
MIT License
274 stars 11 forks source link

`SyncManager` fails to find the `lastFinishedSync` when using an async persistence adapter #943

Closed obedm503 closed 3 weeks ago

obedm503 commented 3 weeks ago

The SyncManager fails to find the lastFinishedSync when using an async persistence adapter when attempting to start sync soon after creation. This issue only happens with async persistence adapters that might take several ms loading data like an indexeddb persister and not with sync persisters like local storage.

const syncManager = new SyncManager({  
  persistenceAdapter: (id) => idbPersister(id),
  pull: async ({ name, lastFinishedSyncEnd }) => {
    // lastFinishedSyncEnd is always undefined on the first sync
    const response = await fetch(`/api/collections/${collectionOptions.name}?since=${lastFinishedSyncStart}`)
    return await response.json()
  },
  // ...
})

const collection = new Collection()
syncManager.addCollection(collection, {
  name: 'todos',
})

syncManager.sync('todos') // will always load all the data instead of just data since `lastFinishedSyncEnd`

My current workaround is to delay calling sync or syncAll until syncManager.syncOperations, syncManager.changes, syncManager.remoteChanges, and syncManager.snapshots have all emitted the persistence.pullCompleted event once. This is not ideal because I'm using private properties. Ideally, the sync manager would emit some type of ready or init event once its internal collections have all loaded into memory.

maxnowack commented 3 weeks ago

I've just opened #949 With this PR, the SyncManager waits until the persistence adapters of the internal collections are ready before the sync starts