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
JavaScript
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;