UNPKG

sync-idb-kvs

Version:

Synchronous IndexedDB Key-Value Store(Requires async Initialization)

114 lines 4.4 kB
export class SyncIDBStorage { static async create(dbName = "SyncStorageDB", storeName = "kvStore") { const s = new SyncIDBStorage(dbName, storeName); await s._initDB(); return s; } constructor(dbName = "SyncStorageDB", storeName = "kvStore") { this.dbName = dbName; this.storeName = storeName; this.db = null; this.memoryCache = {}; // メモリキャッシュ this.uncommited = 0; } async _initDB() { return new Promise((resolve, reject) => { const request = indexedDB.open(this.dbName, 1); request.onupgradeneeded = (event) => { const db = event.target.result; if (!db.objectStoreNames.contains(this.storeName)) { db.createObjectStore(this.storeName); } }; request.onsuccess = (event) => { this.db = event.target.result; this._loadAllData().then(resolve).catch(reject); }; request.onerror = (event) => reject(event.target.error); }); } async _loadAllData() { return new Promise((resolve, reject) => { const transaction = this.db.transaction(this.storeName, "readonly"); const store = transaction.objectStore(this.storeName); const request = store.getAllKeys(); request.onsuccess = async () => { const keys = request.result; const values = await Promise.all(keys.map(key => this._getFromIndexedDB(key))); keys.forEach((key, i) => { if (!(key in this.memoryCache)) { this.memoryCache[key] = values[i] ?? ""; } }); resolve(); }; request.onerror = (event) => reject(event.target.error); }); } getItem(key) { return this.memoryCache[key] ?? null; } setItem(key, value) { this.memoryCache[key] = value; this._saveToIndexedDB(key, value); } removeItem(key) { delete this.memoryCache[key]; this._deleteFromIndexedDB(key); } itemExists(key) { return key in this.memoryCache; } keys() { return Object.keys(this.memoryCache)[Symbol.iterator](); } async reload(key) { const value = await this._getFromIndexedDB(key); if (value) { if (value !== this.memoryCache[key]) { this.memoryCache[key] = value; } } else { if (key in this.memoryCache) { delete this.memoryCache[key]; } } return value; } async _getFromIndexedDB(key) { return new Promise((resolve, reject) => { if (!this.db) return resolve(null); const transaction = this.db.transaction(this.storeName, "readonly"); const store = transaction.objectStore(this.storeName); const request = store.get(key); request.onsuccess = () => resolve(request.result ?? null); request.onerror = () => reject(request.error); }); } async _saveToIndexedDB(key, value) { return new Promise((resolve, reject) => { this.uncommited++; if (!this.db) return resolve(); const transaction = this.db.transaction(this.storeName, "readwrite"); const store = transaction.objectStore(this.storeName); const request = store.put(value, key); request.onsuccess = () => resolve(); request.onerror = (event) => reject(event.target.error); }).finally(() => { this.uncommited--; }); } async _deleteFromIndexedDB(key) { return new Promise((resolve, reject) => { if (!this.db) return resolve(); const transaction = this.db.transaction(this.storeName, "readwrite"); const store = transaction.objectStore(this.storeName); const request = store.delete(key); request.onsuccess = () => resolve(); request.onerror = (event) => reject(event.target.error); }); } } //# sourceMappingURL=index.js.map