UNPKG

localforage-indexes

Version:

plugin for localforage to work with indexes in indexedDb

301 lines (254 loc) 11.8 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('localforage')) : typeof define === 'function' && define.amd ? define(['exports', 'localforage'], factory) : (factory((global.localforagePluginBoilerplate = global.localforagePluginBoilerplate || {}),global.localforage)); }(this, function (exports,localforage) { 'use strict'; localforage = 'default' in localforage ? localforage['default'] : localforage; /* * Resolves a store created in versionchange transaction * @param {localforage} localforageInstance * @param {callback function} action - action to perform on store * HACK: callback is used instead of Promise because Firefox & Safari destroy * transactions that are passed through promise * @param {callback function} finished - called after action is preformed * @return {Promise} { * store - store's indexes can be modified * request - version update connection * dbInfo - container with indexedDb config * newVersion - current version of indexedDb * oldVersion - previous version of indexedDb * } */ function _upgradeStore(localforageInstance, action, finished) { return localforageInstance.ready().then(function () { var dbInfo = localforageInstance._dbInfo; if (!(dbInfo.db instanceof IDBDatabase)) { return finished(new Error('Driver ' + localforageInstance.driver() + ' does not support indexing')); } dbInfo.db.close(); var request = getIDB().open(dbInfo.name, dbInfo.db.version + 1); request.onupgradeneeded = function (_ref) { var newVersion = _ref.newVersion, oldVersion = _ref.oldVersion; dbInfo.db = request.result; var store = request.transaction.objectStore(dbInfo.storeName); action({ store: store, dbInfo: dbInfo, newVersion: newVersion, oldVersion: oldVersion }); }; request.onerror = function (e) { e.preventDefault(); finished(request.error); }; request.onsuccess = function () { return finished(); }; }); } function _getIndex(localforageInstance, indexName) { var dbInfo = localforageInstance._dbInfo; var storeName = dbInfo.storeName; return dbInfo.db.transaction(storeName, 'readonly').objectStore(storeName).index(indexName); } function _executePromiseOrCallback(promise, callback) { if (typeof callback === 'function') { var resolve = function resolve(result) { return callback(null, result); }; var reject = function reject(error) { return callback(error); }; return promise(resolve, reject); } return new Promise(promise); } function _resolveParams(options, callback) { if (typeof options === 'function') { callback = options; options = undefined; } return { options: options, callback: callback }; } function getIDB() { /* global indexedDB,webkitIndexedDB,mozIndexedDB,OIndexedDB,msIndexedDB */ try { if (typeof indexedDB !== 'undefined') { return indexedDB; } if (typeof webkitIndexedDB !== 'undefined') { return webkitIndexedDB; } if (typeof mozIndexedDB !== 'undefined') { return mozIndexedDB; } if (typeof OIndexedDB !== 'undefined') { return OIndexedDB; } if (typeof msIndexedDB !== 'undefined') { return msIndexedDB; } throw new Error("indexedDb not supported by browser"); } catch (e) { throw e; } } function handleMethodCall(localforageInstance, methodName, args) { return localforageInstance.ready().then(function () { var promise = localforageInstance._baseMethods[methodName].apply(localforageInstance, args); return promise; }); } // wraps the localForage methods of the WrappedLibraryMethods array and // allows you to execute code before & after their invocation function wireUpMethods(localforageInstance) { var WrappedLibraryMethods = ['clear', 'getItem', 'iterate', 'key', 'keys', 'length', 'removeItem', 'setItem']; function wireUpMethod(localforageInstance, methodName) { localforageInstance._baseMethods = localforageInstance._baseMethods || {}; localforageInstance._baseMethods[methodName] = localforageInstance[methodName]; localforageInstance[methodName] = function () { return handleMethodCall(this, methodName, arguments); }; } for (var i = 0, len = WrappedLibraryMethods.length; i < len; i++) { var methodName = WrappedLibraryMethods[i]; wireUpMethod(localforageInstance, methodName); } } // place your plugin initialization logic here // useful in case that you need to preserve a state function setup(localforageInstance) { if (!localforageInstance._pluginPrivateVariables) { localforageInstance._pluginPrivateVariables = { listOfImportantThings: [], callCount: 0 }; // in case you need to observe the invocation of some methods wireUpMethods(localforageInstance); } } /* * Creates index * @param {String} indexName * @param {String} keyPath, indexDb key path, keys separated with dot * @param {Object} options, indexDb index creation options * @param {Function<err | index>} callback * @return {Promise<index>} resolves with new index, rejects if index is present */ function createIndex(indexName, keyPath, options, callback) { var _resolveParams2 = _resolveParams(options, callback); options = _resolveParams2.options; callback = _resolveParams2.callback; var localforageInstance = this; setup(localforageInstance); return _executePromiseOrCallback(function (resolve, reject) { _upgradeStore(localforageInstance, function (_ref) { var store = _ref.store, dbInfo = _ref.dbInfo, newVersion = _ref.newVersion, oldVersion = _ref.oldVersion; if (store.indexNames.contains(indexName)) { return reject(new Error('The database "' + dbInfo.name + '" has been upgraded from version ' + oldVersion + ' to version ' + newVersion + ', but the index "' + indexName + '" in the storage "' + dbInfo.storeName + '" already exists.')); } store.createIndex(indexName, keyPath, options || {}); }, function (err) { if (err) return reject(err); resolve(_getIndex(localforageInstance, indexName)); }).catch(function (err) { reject(err); }); }, callback); } /* * Gets index * @param {String} indexName * @param {Function<err | index>} callback * @return {Promise<index>} resolves with an index, rejects if index is not found */ function getIndex(indexName, callback) { var localforageInstance = this; setup(localforageInstance); return _executePromiseOrCallback(function (resolve, reject) { localforageInstance.ready().then(function () { return resolve(_getIndex(localforageInstance, indexName)); }).catch(reject); }, callback); } /* * Deletes then recreates index * Use to change index keyPath or options * @param {String} indexName * @param {String} keyPath, indexDb key path, keys separated with dot * @param {Object} options, indexDb index creation options * @param {Function<err | index>} callback * @return {Promise<index>} resolves with updated index, rejects if index is present */ function updateIndex(indexName, keyPath, options, callback) { var _resolveParams3 = _resolveParams(options, callback); options = _resolveParams3.options; callback = _resolveParams3.callback; var localforageInstance = this; setup(localforageInstance); return _executePromiseOrCallback(function (resolve, reject) { _upgradeStore(localforageInstance, function (_ref2) { var store = _ref2.store, dbInfo = _ref2.dbInfo, newVersion = _ref2.newVersion, oldVersion = _ref2.oldVersion; if (!store.indexNames.contains(indexName)) { return reject(new Error('The database "' + dbInfo.name + '" has been upgraded from version ' + oldVersion + ' to version ' + newVersion + ', but the index "' + indexName + '" in the storage "' + dbInfo.storeName + '" does not exists.')); } store.deleteIndex(indexName); store.createIndex(indexName, keyPath, options); }, function (err) { if (err) return reject(err); resolve(_getIndex(localforageInstance, indexName)); }).catch(function (err) { reject(err); }); }, callback); } /* * Deletes index * @param {String} indexName * @param {Function<err>} callback * @return {Promise} resolves when index is delted, rejects if index isn't present */ function deleteIndex(indexName, callback) { var localforageInstance = this; setup(localforageInstance); return _executePromiseOrCallback(function (resolve, reject) { _upgradeStore(localforageInstance, function (_ref3) { var store = _ref3.store, dbInfo = _ref3.dbInfo, newVersion = _ref3.newVersion, oldVersion = _ref3.oldVersion; if (!store.indexNames.contains(indexName)) { return reject(new Error('The database "' + dbInfo.name + '" has been upgraded from version ' + oldVersion + ' to version ' + newVersion + ', but the index "' + indexName + '" in the storage "' + dbInfo.storeName + '" does not exists.')); } store.deleteIndex(indexName); }, function (err) { if (err) return reject(err); resolve(); }).catch(function (err) { reject(err); }); }, callback); } // add your plugin method to every localForage instance function extendPrototype(localforage) { var localforagePrototype = Object.getPrototypeOf(localforage); if (localforagePrototype) { localforagePrototype.createIndex = createIndex; localforagePrototype.getIndex = getIndex; localforagePrototype.updateIndex = updateIndex; localforagePrototype.deleteIndex = deleteIndex; } return localforage; } var extendPrototypeResult = extendPrototype(localforage); exports.createIndex = createIndex; exports.getIndex = getIndex; exports.updateIndex = updateIndex; exports.deleteIndex = deleteIndex; exports.extendPrototype = extendPrototype; exports.extendPrototypeResult = extendPrototypeResult; Object.defineProperty(exports, '__esModule', { value: true }); }));