'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var wrapIdbValue = require('./wrap-idb-value.js'); /** * Open a database. * * @param name Name of the database. * @param version Schema version. * @param callbacks Additional callbacks. */ function openDB(name, version, { blocked, upgrade, blocking, terminated } = {}) { const request = indexedDB.open(name, version); const openPromise = wrapIdbValue.wrap(request); if (upgrade) { request.addEventListener('upgradeneeded', (event) => { upgrade(wrapIdbValue.wrap(request.result), event.oldVersion, event.newVersion, wrapIdbValue.wrap(request.transaction)); }); } if (blocked) request.addEventListener('blocked', () => blocked()); openPromise .then((db) => { if (terminated) db.addEventListener('close', () => terminated()); if (blocking) db.addEventListener('versionchange', () => blocking()); }) .catch(() => { }); return openPromise; } /** * Delete a database. * * @param name Name of the database. */ function deleteDB(name, { blocked } = {}) { const request = indexedDB.deleteDatabase(name); if (blocked) request.addEventListener('blocked', () => blocked()); return wrapIdbValue.wrap(request).then(() => undefined); } const readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count']; const writeMethods = ['put', 'add', 'delete', 'clear']; const cachedMethods = new Map(); function getMethod(target, prop) { if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === 'string')) { return; } if (cachedMethods.get(prop)) return cachedMethods.get(prop); const targetFuncName = prop.replace(/FromIndex$/, ''); const useIndex = prop !== targetFuncName; const isWrite = writeMethods.includes(targetFuncName); if ( // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge. !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName))) { return; } const method = async function (storeName, ...args) { // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :( const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly'); let target = tx.store; if (useIndex) target = target.index(args.shift()); // Must reject if op rejects. // If it's a write operation, must reject if tx.done rejects. // Must reject with op rejection first. // Must resolve with op value. // Must handle both promises (no unhandled rejections) return (await Promise.all([ target[targetFuncName](...args), isWrite && tx.done, ]))[0]; }; cachedMethods.set(prop, method); return method; } wrapIdbValue.replaceTraps((oldTraps) => ({ ...oldTraps, get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver), has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop), })); exports.unwrap = wrapIdbValue.unwrap; exports.wrap = wrapIdbValue.wrap; exports.deleteDB = deleteDB; exports.openDB = openDB;