| a | b |  | 
|---|
 | 0 | + | var IDBWrapper = require("idb-wrapper") | 
|---|
 | 0 | + |     , extend = require("xtend") | 
|---|
 | 0 | + |     , getCallback = require("./utils/getCallback") | 
|---|
 | 0 | + |     , getOptions = require("./utils/getOptions") | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |     , defaultOptions = { | 
|---|
 | 0 | + |         encoding: 'utf8' | 
|---|
 | 0 | + |         , keys: true | 
|---|
 | 0 | + |         , values: true | 
|---|
 | 0 | + |     } | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + | module.exports = idbup | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + | function idbup(path, defaults, callback) { | 
|---|
 | 0 | + |     var db = extend(new Object(), { | 
|---|
 | 0 | + |             put: onOpen(put) | 
|---|
 | 0 | + |             , del: onOpen(del) | 
|---|
 | 0 | + |             , get: onOpen(get) | 
|---|
 | 0 | + |             , batch: onOpen(batch) | 
|---|
 | 0 | + |             , open: open | 
|---|
 | 0 | + |             , close: close | 
|---|
 | 0 | + |             , isOpen: isOpen | 
|---|
 | 0 | + |             , isClosed: isClosed | 
|---|
 | 0 | + |         }) | 
|---|
 | 0 | + |         , idb | 
|---|
 | 0 | + |         , status = "new" | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |     if (typeof defaults === "function") { | 
|---|
 | 0 | + |         callback = defaults | 
|---|
 | 0 | + |         defaults = {} | 
|---|
 | 0 | + |     } | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |     defaults = extend({}, defaultOptions, defaults || {}) | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |     open(callback) | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |     return db | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |     function put(key, value, options, callback) { | 
|---|
 | 0 | + |         callback = getCallback(options, callback) | 
|---|
 | 0 | + |         options = getOptions(defaults, options) | 
|---|
 | 0 | + |          | 
|---|
 | 0 | + |         idb.put({ | 
|---|
 | 0 | + |             value: value | 
|---|
 | 0 | + |             , id: key | 
|---|
 | 0 | + |         }, function () { | 
|---|
 | 0 | + |             callback && callback(null) | 
|---|
 | 0 | + |         }, callback) | 
|---|
 | 0 | + |     } | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |     function del(key, options, callback) { | 
|---|
 | 0 | + |         callback = getCallback(options, callback) | 
|---|
 | 0 | + |         options = getOptions(defaults, options) | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |         idb.remove(key, function () { | 
|---|
 | 0 | + |             callback && callback(null) | 
|---|
 | 0 | + |         }, callback) | 
|---|
 | 0 | + |     } | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |     function get(key, options, callback) { | 
|---|
 | 0 | + |         callback = getCallback(options, callback) | 
|---|
 | 0 | + |         options = getOptions(defaults, options) | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |         idb.get(key, function (result) { | 
|---|
 | 0 | + |             callback && callback(null, result, key) | 
|---|
 | 0 | + |         }, callback) | 
|---|
 | 0 | + |     } | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |     function batch(arr, options, callback) { | 
|---|
 | 0 | + |         callback = getCallback(options, callback) | 
|---|
 | 0 | + |         options = getOptions(defaults, options) | 
|---|
 | 0 | + |         var _arr = arr.map(function (item) { | 
|---|
 | 0 | + |             var result = {} | 
|---|
 | 0 | + |                 , key = item.key | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |             if (item.type === "del") { | 
|---|
 | 0 | + |                 result.type = "remove" | 
|---|
 | 0 | + |             } else if (item.type === "put") { | 
|---|
 | 0 | + |                 result.type = "put" | 
|---|
 | 0 | + |                 result.value = { | 
|---|
 | 0 | + |                     value: item.value | 
|---|
 | 0 | + |                     , id: key | 
|---|
 | 0 | + |                 } | 
|---|
 | 0 | + |             } | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |             result.key = key | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |             return result | 
|---|
 | 0 | + |         }) | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |         idbBatch.call(idb, _arr, function () { | 
|---|
 | 0 | + |             callback && callback() | 
|---|
 | 0 | + |         }, callback) | 
|---|
 | 0 | + |     } | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |     function open(options, callback) { | 
|---|
 | 0 | + |         if (!options) callback = options | 
|---|
 | 0 | + |         if (status === "opening") { | 
|---|
 | 0 | + |             db.on("ready", callback) | 
|---|
 | 0 | + |         } else if (status === "opened") { | 
|---|
 | 0 | + |             close(_open) | 
|---|
 | 0 | + |         } else { | 
|---|
 | 0 | + |             _open() | 
|---|
 | 0 | + |         } | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |         function _open(err) { | 
|---|
 | 0 | + |             if (err) { | 
|---|
 | 0 | + |                 return callback(err) | 
|---|
 | 0 | + |             } | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |             status = "opening" | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |             idb = new IDBWrapper(extend({ | 
|---|
 | 0 | + |                 storeName: path | 
|---|
 | 0 | + |             }, defaults), function () { | 
|---|
 | 0 | + |                 status = "opened" | 
|---|
 | 0 | + |                 callback && callback(null, db) | 
|---|
 | 0 | + |             }) | 
|---|
 | 0 | + |         } | 
|---|
 | 0 | + |     } | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |     function close(callback) { | 
|---|
 | 0 | + |         if (status === "opened") { | 
|---|
 | 0 | + |             _close() | 
|---|
 | 0 | + |         } else if (status === "opening") { | 
|---|
 | 0 | + |             db.on("ready", _close) | 
|---|
 | 0 | + |         } else if (status === "closed") { | 
|---|
 | 0 | + |             callback && callback() | 
|---|
 | 0 | + |         } else if (status === "new") { | 
|---|
 | 0 | + |             var err = new Error("cannot close unopened db") | 
|---|
 | 0 | + |             if (callback) { | 
|---|
 | 0 | + |                 return callback(err) | 
|---|
 | 0 | + |             } | 
|---|
 | 0 | + |         } | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |         function _close() { | 
|---|
 | 0 | + |             idb.db.close() | 
|---|
 | 0 | + |             idb = null | 
|---|
 | 0 | + |             status = "closed" | 
|---|
 | 0 | + |             callback && callback() | 
|---|
 | 0 | + |         } | 
|---|
 | 0 | + |     } | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |     function isOpen() { | 
|---|
 | 0 | + |         return status === "opened" | 
|---|
 | 0 | + |     } | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |     function isClosed() { | 
|---|
 | 0 | + |         return status === "closed" | 
|---|
 | 0 | + |     } | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |     function onReady(callback) { | 
|---|
 | 0 | + |         if (status === "opened") { | 
|---|
 | 0 | + |             callback(idb) | 
|---|
 | 0 | + |         } else { | 
|---|
 | 0 | + |             db.on("ready", callback) | 
|---|
 | 0 | + |         } | 
|---|
 | 0 | + |     } | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |     function onOpen(operation) { | 
|---|
 | 0 | + |         return function opened() { | 
|---|
 | 0 | + |             var args = arguments | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |             onReady(function () { | 
|---|
 | 0 | + |                 operation.apply(null, args) | 
|---|
 | 0 | + |             }) | 
|---|
 | 0 | + |         } | 
|---|
 | 0 | + |     } | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |     // IDBWrapper batch implementation inlined. | 
|---|
 | 0 | + |     // Waiting for pull request | 
|---|
 | 0 | + |     function idbBatch(arr, onSuccess, onError) { | 
|---|
 | 0 | + |       onError || (onError = function (error) { | 
|---|
 | 0 | + |         console.error('Could not apply batch.', error); | 
|---|
 | 0 | + |       }); | 
|---|
 | 0 | + |       onSuccess = onSuccess || noop; | 
|---|
 | 0 | + |       var batchTransaction = this.db.transaction( | 
|---|
 | 0 | + |         [this.storeName] , this.consts.READ_WRITE); | 
|---|
 | 0 | + |       var count = arr.length; | 
|---|
 | 0 | + |       var called = false; | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |       arr.forEach(function (operation) { | 
|---|
 | 0 | + |         var type = operation.type; | 
|---|
 | 0 | + |         var key = operation.key; | 
|---|
 | 0 | + |         var value = operation.value; | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |         if (type === "remove") { | 
|---|
 | 0 | + |           var deleteRequest = batchTransaction | 
|---|
 | 0 | + |             .objectStore(this.storeName).delete(key); | 
|---|
 | 0 | + |           deleteRequest.onsuccess = function (event) { | 
|---|
 | 0 | + |             count--; | 
|---|
 | 0 | + |             if (count === 0 && !called) { | 
|---|
 | 0 | + |               called = true; | 
|---|
 | 0 | + |               onSuccess(); | 
|---|
 | 0 | + |             } | 
|---|
 | 0 | + |           }; | 
|---|
 | 0 | + |           deleteRequest.onerror = function (err) { | 
|---|
 | 0 | + |             batchTransaction.abort(); | 
|---|
 | 0 | + |             if (!called) { | 
|---|
 | 0 | + |               called = true; | 
|---|
 | 0 | + |               onError(err); | 
|---|
 | 0 | + |             } | 
|---|
 | 0 | + |           }; | 
|---|
 | 0 | + |         } else if (type === "put") { | 
|---|
 | 0 | + |           if (typeof value[this.keyPath] === 'undefined' && | 
|---|
 | 0 | + |             !this.features.hasAutoIncrement | 
|---|
 | 0 | + |           ) { | 
|---|
 | 0 | + |             value[this.keyPath] = this._getUID() | 
|---|
 | 0 | + |           } | 
|---|
 | 0 | + |           var putRequest = batchTransaction | 
|---|
 | 0 | + |             .objectStore(this.storeName).put(value) | 
|---|
 | 0 | + |           putRequest.onsuccess = function (event) { | 
|---|
 | 0 | + |             count--; | 
|---|
 | 0 | + |             if (count === 0 && !called) { | 
|---|
 | 0 | + |               called = true; | 
|---|
 | 0 | + |               onSuccess(); | 
|---|
 | 0 | + |             } | 
|---|
 | 0 | + |           }; | 
|---|
 | 0 | + |           putRequest.onerror = function (err) { | 
|---|
 | 0 | + |             batchTransaction.abort(); | 
|---|
 | 0 | + |             if (!called) { | 
|---|
 | 0 | + |               called = true; | 
|---|
 | 0 | + |               onError(err); | 
|---|
 | 0 | + |             } | 
|---|
 | 0 | + |           }; | 
|---|
 | 0 | + |         } | 
|---|
 | 0 | + |       }, this); | 
|---|
 | 0 | + |     } | 
|---|
 | 0 | + |  | 
|---|
 | 0 | + |     function noop() {} | 
|---|
 | 0 | + | } | 
|---|
| ... |  | 
|---|