104 lines
3.8 KiB
TypeScript
Executable File
104 lines
3.8 KiB
TypeScript
Executable File
import { Lock } from "@hibas123/utils";
|
|
|
|
import { DB, openDb, Transaction } from "idb";
|
|
|
|
export default class IDB {
|
|
initLock = new Lock();
|
|
db: DB;
|
|
constructor(database: string, private stores: string[]) {
|
|
let lock = this.initLock.getLock();
|
|
lock.then(async l => {
|
|
|
|
let v = localStorage.getItem(database + "_version");
|
|
let version = 0;
|
|
if (v) version = Number(v)
|
|
let lastStoresS = localStorage.getItem(database + "_stores");
|
|
if (!lastStoresS) lastStoresS = "";
|
|
let lastStores = lastStoresS.split(",").filter(e => e !== "");
|
|
|
|
if (!stores.every(e => lastStores.indexOf(e) >= 0) || !lastStores.every(e => stores.indexOf(e) >= 0)) version++;
|
|
|
|
localStorage.setItem(database + "_version", version.toString());
|
|
localStorage.setItem(database + "_stores", stores.join(","));
|
|
|
|
this.db = await openDb(database, version, db => {
|
|
console.log("IndexedDB need update")
|
|
stores.forEach(store => {
|
|
if (!db.objectStoreNames.contains(store))
|
|
db.createObjectStore(store);
|
|
})
|
|
})
|
|
console.log("Got DATABASE", this.db)
|
|
l.release();
|
|
})
|
|
}
|
|
|
|
transaction(...stores: string[] | { name: string }[]) {
|
|
if (stores.length < 1) stores = this.stores;
|
|
let s: string[];
|
|
if (typeof stores[0] === "string")
|
|
s = <any>stores
|
|
else
|
|
s = (<any>stores).map(e => e.name)
|
|
|
|
return this.db.transaction(s, "readwrite")
|
|
}
|
|
|
|
getStore<T = any>(name: string) {
|
|
return {
|
|
name: name,
|
|
transaction: () => {
|
|
return this.db.transaction(name, "readwrite")
|
|
},
|
|
get: async (key: string, transaction?: Transaction): Promise<T> => {
|
|
(await this.initLock.getLock()).release()
|
|
return (transaction || this.db.transaction(name))
|
|
.objectStore(name).get(key);
|
|
},
|
|
|
|
getAll: async (transaction?: Transaction): Promise<T[]> => {
|
|
(await this.initLock.getLock()).release()
|
|
return (transaction || this.db.transaction(name))
|
|
.objectStore(name).getAll();
|
|
},
|
|
|
|
set: async (key: string, val: T, transaction?: Transaction) => {
|
|
(await this.initLock.getLock()).release()
|
|
const tx = (transaction || this.db.transaction(name, "readwrite"));
|
|
tx.objectStore(name).put(val, key);
|
|
return tx.complete;
|
|
},
|
|
|
|
delete: async (key: string, transaction?: Transaction) => {
|
|
(await this.initLock.getLock()).release()
|
|
const tx = (transaction || this.db.transaction(name, "readwrite"));
|
|
tx.objectStore(name).delete(key);
|
|
return tx.complete;
|
|
},
|
|
|
|
clear: async (transaction?: Transaction) => {
|
|
(await this.initLock.getLock()).release()
|
|
const tx = (transaction || this.db.transaction(name, "readwrite"));
|
|
tx.objectStore(name).clear();
|
|
return tx.complete;
|
|
},
|
|
|
|
keys: async (transaction?: Transaction): Promise<string[]> => {
|
|
(await this.initLock.getLock()).release()
|
|
const tx = (transaction || this.db.transaction(name));
|
|
const keys: string[] = [];
|
|
const store = tx.objectStore(name);
|
|
|
|
// This would be store.getAllKeys(), but it isn't supported by Edge or Safari.
|
|
// openKeyCursor isn't supported by Safari, so we fall back
|
|
(store.iterateKeyCursor || store.iterateCursor).call(store, (cursor: any) => {
|
|
if (!cursor) return;
|
|
keys.push(cursor.key);
|
|
cursor.continue();
|
|
});
|
|
|
|
return tx.complete.then(() => keys);
|
|
}
|
|
}
|
|
}
|
|
} |