@v4fire/core
Version:
V4Fire core library
108 lines (85 loc) • 2.59 kB
text/typescript
/*!
* V4Fire Core
* https://github.com/V4Fire/Core
*
* Released under the MIT license
* https://github.com/V4Fire/Core/blob/master/LICENSE
*/
import type {
AsyncEngineOptions,
StoreMode
} from 'core/kv-storage/engines/browser-indexeddb/interface';
/**
* Implementation of persistent asynchronous key-value storage based on IndexedDB
*/
export default class KVStorageIndexedDBEngine {
protected db: Promise<IDBDatabase>;
protected storeName: string;
constructor({dbName = 'kv-storage-db', storeName = 'kv-storage'}: AsyncEngineOptions = {}) {
this.storeName = storeName;
const
openRequest = indexedDB.open(dbName);
this.db = new Promise((r) => {
openRequest.onupgradeneeded = () => {
const
db = openRequest.result;
if (!db.objectStoreNames.contains(storeName)) {
db.createObjectStore(storeName);
}
};
openRequest.onsuccess = () => {
r(openRequest.result);
};
});
}
async get(key: IDBValidKey): Promise<unknown> {
const store = await this.getStore('readonly');
return promisifyRequestToStore(store.get(key));
}
async set(key: IDBValidKey, value: unknown): Promise<void> {
const store = await this.getStore('readwrite');
await promisifyRequestToStore(store.put(value, key));
}
async remove(key: IDBValidKey): Promise<void> {
const store = await this.getStore('readwrite');
await promisifyRequestToStore(store.delete(key));
}
async keys(): Promise<IDBValidKey[]> {
const
store = await this.getStore('readonly');
// eslint-disable-next-line @typescript-eslint/unbound-method
if (Object.isFunction(store.getAllKeys)) {
return promisifyRequestToStore(store.getAllKeys());
}
return new Promise((resolve, reject) => {
const
request = store.openCursor(),
keys: IDBValidKey[] = [];
request.onerror = () => reject(request.error);
request.onsuccess = () => {
const
cursor = request.result;
if (cursor) {
keys.push(cursor.primaryKey);
cursor.continue();
} else {
resolve(keys);
}
};
});
}
async clear(): Promise<void> {
const store = await this.getStore('readwrite');
return promisifyRequestToStore(store.clear());
}
protected async getStore(mode: StoreMode): Promise<IDBObjectStore> {
const db = await this.db;
return db.transaction(this.storeName, mode).objectStore(this.storeName);
}
}
function promisifyRequestToStore<T>(request: IDBRequest<T>): Promise<T> {
return new Promise((resolve, reject) => {
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
}