Created
June 20, 2020 16:18
-
-
Save MaxMonteil/f295bfcc8d46c4776207f13d606a3f88 to your computer and use it in GitHub Desktop.
A wrapper around idb for creating multiple stores whenever
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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