UNPKG

@blakewatson/datastore

Version:

Save data to IndexedDB using localStorage APIs.

253 lines (251 loc) 8.55 kB
var _DataStoreExports = (() => { var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // DataStore.js var DataStore_exports = {}; __export(DataStore_exports, { default: () => DataStore }); var DEFAULT_DB_NAME = "Default DB"; var DEFAULT_STORE_NAME = "data"; var DataStore = class _DataStore { /** @type {string | null} */ dbName = null; /** @type {string | null} */ storeName = null; /** * Create a new database with one or more stores. * @param {SetupDbOptions} options */ static setupDb(options) { const { name, version = 1, storesToCreate = DEFAULT_STORE_NAME, onUpgradeNeeded = null } = options; return new Promise((resolve, reject) => { const request = indexedDB.open(name, version); request.onerror = (event) => { console.error("Error opening database:", event.target.error); reject(new Error("Error opening database")); }; request.onsuccess = (event) => { resolve(request.result); }; request.onupgradeneeded = (event) => { const db = request.result; const existingStores = db.objectStoreNames; const dataStoreInstances = []; if (Array.isArray(storesToCreate)) { storesToCreate.forEach((storeName) => { if (existingStores.contains(storeName)) { return; } db.createObjectStore(storeName); dataStoreInstances.push(new _DataStore(name, storeName)); }); } else { if (existingStores.contains(storesToCreate)) { return; } db.createObjectStore(storesToCreate); dataStoreInstances.push(new _DataStore(name, storesToCreate)); } if (onUpgradeNeeded) { onUpgradeNeeded(db, dataStoreInstances); } }; }); } /** * @param {string} dbName * @param {string} storeName */ constructor(dbName = DEFAULT_DB_NAME, storeName = DEFAULT_STORE_NAME) { this.dbName = dbName; this.storeName = storeName; } getDb() { return new Promise((resolve, reject) => { const request = indexedDB.open(this.dbName, this.version); request.onerror = (event) => { console.error("Error opening database:", event.target.error); reject(new Error("Error opening database")); }; request.onsuccess = (event) => { resolve(request.result); }; request.onupgradeneeded = (event) => { console.log("Upgrade needed"); const db = request.result; const existingStores = db.objectStoreNames; if (!existingStores.contains(this.storeName)) { db.createObjectStore(this.storeName); } }; }); } /** @param {string | number} key */ async getItem(key) { const db = await this.getDb(); if (typeof key === "number") { key = key.toString(); } if (typeof key !== "string") { throw new Error("Key must be a string"); } return new Promise((resolve, reject) => { if (!this.storeName) { reject(new Error("Store name not set")); return; } const transaction = db.transaction(this.storeName, "readonly"); transaction.onerror = (event) => reject(transaction.error); const store = transaction.objectStore(this.storeName); const request = store.get(key); request.onerror = (event) => reject(request.error); request.onsuccess = () => { resolve(request.result); db.close(); }; }); } /** * @param {string | number} key * @param {any} value */ async setItem(key, value) { const db = await this.getDb(); if (typeof key === "number") { key = key.toString(); } if (typeof key !== "string") { throw new Error("Key must be a string"); } return ( /** @type {Promise<void>} */ new Promise((resolve, reject) => { if (!this.storeName) { reject(new Error("Store name not set")); return; } const transaction = db.transaction(this.storeName, "readwrite"); transaction.onerror = (event) => reject(transaction.error); const store = transaction.objectStore(this.storeName); const request = store.put(value, key); request.onerror = (event) => reject(request.error); request.onsuccess = () => { db.close(); resolve(); }; }) ); } /** @param {string | number} key */ async removeItem(key) { const db = await this.getDb(); if (typeof key === "number") { key = key.toString(); } if (typeof key !== "string") { throw new Error("Key must be a string"); } return ( /** @type {Promise<void>} */ new Promise((resolve, reject) => { if (!this.storeName) { reject(new Error("Store name not set")); return; } const transaction = db.transaction(this.storeName, "readwrite"); transaction.onerror = (event) => reject(transaction.error); const store = transaction.objectStore(this.storeName); const request = store.delete(key); request.onerror = (event) => reject(request.error); request.onsuccess = () => { db.close(); resolve(); }; }) ); } async keys() { const db = await this.getDb(); return new Promise((resolve, reject) => { if (!this.storeName) { reject(new Error("Store name not set")); return; } const transaction = db.transaction(this.storeName, "readonly"); transaction.onerror = (event) => reject(transaction.error); const store = transaction.objectStore(this.storeName); const request = store.getAllKeys(); request.onerror = (event) => reject(request.error); request.onsuccess = () => { resolve(request.result); db.close(); }; }); } async count() { const db = await this.getDb(); return new Promise((resolve, reject) => { if (!this.storeName) { reject(new Error("Store name not set")); return; } const transaction = db.transaction(this.storeName, "readonly"); transaction.onerror = (event) => reject(transaction.error); const store = transaction.objectStore(this.storeName); const request = store.count(); request.onerror = (event) => reject(request.error); request.onsuccess = () => { resolve(request.result); db.close(); }; }); } async length() { return this.count(); } async clear() { const db = await this.getDb(); return ( /** @type {Promise<void>} */ new Promise((resolve, reject) => { if (!this.storeName) { reject(new Error("Store name not set")); return; } const transaction = db.transaction(this.storeName, "readwrite"); transaction.onerror = (event) => reject(transaction.error); const store = transaction.objectStore(this.storeName); const request = store.clear(); request.onerror = (event) => reject(request.error); request.onsuccess = () => { db.close(); resolve(); }; }) ); } }; return __toCommonJS(DataStore_exports); })(); self.DataStore = _DataStoreExports.default;