UNPKG

svelte-idb-store

Version:

A library that allows you to sync the value of your Svelte stores with IndexedDB

96 lines (95 loc) 3.29 kB
import { openDB, deleteDB } from "idb"; class IDB { db; name; store = "data"; index = "id"; key; initialValue; isBrowser = typeof window !== "undefined" && "indexedDB" in window; constructor(name, key, initialValue, callback) { this.name = name; this.key = key; this.initialValue = initialValue; if (!this.isBrowser) return; this.open().then(creating => callback && callback(creating)); } open = async () => { let creating = false; this.db = await openDB(this.name, undefined, { upgrade: db => { if (!db.objectStoreNames.contains(this.store)) { const store = db.createObjectStore(this.store, { autoIncrement: true }); if (this.key) { store.createIndex(this.index, this.key, { unique: true }); } creating = true; } } }); if (creating && this.initialValue) { await this.set(this.initialValue); } return creating; }; } export class IDBArray extends IDB { get = () => this.db.getAll(this.store); set = async (val) => { await this.db.clear(this.store); const tx = this.db.transaction(this.store, "readwrite"); await Promise.all(val.map((value, i) => tx.store.put(JSON.parse(JSON.stringify(value)), i))); await tx.done; return val; }; getItem = (id) => this.db.getFromIndex(this.store, this.index, id); setItem = async (val) => { const key = this.key && (await this.db.getKeyFromIndex(this.store, this.index, val[this.key])); await this.db.put(this.store, JSON.parse(JSON.stringify(val)), key); return this.get(); }; removeItem = async (id) => { const key = this.key && (await this.db.getKeyFromIndex(this.store, this.index, id)); if (key !== undefined) { await this.db.delete(this.store, key); } return this.get(); }; clear = async () => { await this.db.clear(this.store); return []; }; } export class IDBObject extends IDB { get = async () => { let res = {}; let cursor = await this.db.transaction(this.store).store.openCursor(); while (cursor) { res[cursor.key.toString()] = cursor.value; cursor = await cursor.continue(); } return res; }; set = async (val) => { const tx = this.db.transaction(this.store, "readwrite"); await Promise.all(Object.entries(val).map(([key, value]) => tx.store.put(JSON.parse(JSON.stringify(value)), key))); await tx.done; return val; }; getItem = (id) => this.db.get(this.store, id); setItem = async (id, val) => { await this.db.put(this.store, JSON.parse(JSON.stringify(val)), id); return this.get(); }; removeItem = async (id) => { await this.db.delete(this.store, id); return this.get(); }; clear = async () => { await this.db.clear(this.store); return {}; }; } export const exists = async (name) => (await indexedDB.databases()).some(db => db.name === name); export const remove = deleteDB;