Skip to content

Instantly share code, notes, and snippets.

@MaxMonteil
Created June 20, 2020 16:18
Show Gist options
  • Save MaxMonteil/f295bfcc8d46c4776207f13d606a3f88 to your computer and use it in GitHub Desktop.
Save MaxMonteil/f295bfcc8d46c4776207f13d606a3f88 to your computer and use it in GitHub Desktop.
A wrapper around idb for creating multiple stores whenever
import { openDB } from 'idb'
export class IdbWrapper {
static _freshStart = true
static _checking = false
static _dbCheck = null
static _version = 1
static _stores = new Set()
// On page (re)loads we need to check _version,
// this ensures we open with the correct version in getStore()
// as a result db versions do start at 1 instead of 0
_checkDbVersion (dbName) {
IdbWrapper._checking = true
return new Promise(resolve => {
openDB(dbName).then(db => {
IdbWrapper._stores = new Set(db.objectStoreNames)
// version should be the number of stores +1
IdbWrapper._version = db.objectStoreNames.length + 1
db.close() // always close db
IdbWrapper._freshStart = false
IdbWrapper._checking = false
resolve()
})
})
}
constructor (name, store) {
this._name = name
this._store = store
if (IdbWrapper._freshStart && !IdbWrapper._checking) {
IdbWrapper._dbCheck = this._checkDbVersion(this._name)
}
}
// stores are created here instead of the constructor,
// this way they're created only when needed
async getStore (store = this._store) {
await IdbWrapper._dbCheck
if (IdbWrapper._stores.has(store)) return openDB(this._name)
// I can't rely on db.objectStoreNames being up to date,
// especially when making 2+ stores in a row
IdbWrapper._stores.add(store)
IdbWrapper._version = IdbWrapper._stores.size + 1
return openDB(this._name, IdbWrapper._version, {
upgrade: db => db.createObjectStore(store),
})
}
// this function is for brevity since
// we always get the store then close the db
// it does mean we need to use strings for function names
_autoclose (func, ...args) {
return (async () => {
const db = await this.getStore()
const r = await db[func](...args)
db.close() // always close db
return r
})()
}
saveValue (key, val) {
return this._autoclose('put', this._store, val, key)
}
// other db functions as needed...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment