jakearchibald / idb

IndexedDB, but with promises
https://www.npmjs.com/package/idb
ISC License
6.34k stars 357 forks source link

Can't do async data migrations in the sync upgrade function #281

Closed lkarabeg closed 2 years ago

lkarabeg commented 2 years ago

It seems that all methods of retrieving items from a store return a promise, which can't be awaited in the upgrade function.

Let's say my blogPost type has changed. The ID used to be a number, but is now a string, Then it would be nice to be able to do something like this:

upgrade(db, oldVersion, newVersion, transaction) {
           const blogPosts = await db.getAll('blogPosts') // Oh, no! We can't await anything here
           db.deleteObjectStore('blogPosts')
           // Re-create the store with the new schema
           // Remap and save all the items
      }

It would be nice if the upgrade function was async so that this type of thing can be done.

Is there any workaround for this?

jakearchibald commented 2 years ago

Put async before upgrade?

lkarabeg commented 2 years ago

I assume upgrade is not awaited, so if there are multiple migrations and it takes a bit of time, then the database object could be put to use in application code while the store is in some intermediate state.

jakearchibald commented 2 years ago

It follows usual transaction rules https://github.com/jakearchibald/idb#transaction-lifetime

lkarabeg commented 2 years ago

Sorry if I'm missing your point, but I want to be sure the upgrade is complete when the openDB promise resolves.

const db = await openDB<AppDb>("appData", currentVersion, {
      async upgrade(db, oldVersion, newVersion, transaction) {
        // Do a ton of stuff
      },
     ...
})
const allItems = await db.getAll('things') // Is the upgrade certainly done by now?
jakearchibald commented 2 years ago

Yep, that's how it works

lkarabeg commented 2 years ago

That's amazing, thanks for your help!

jakearchibald commented 2 years ago

No problem! The lifetime of IDB transitions is pretty weird, unfortunately I can't really change that 😄