“MediaWiki:Gadget-localforage.js”的版本间的差异
星海-adminbot(讨论 | 贡献) (同步小工具) (1个标签:Bot) |
星海-interfacebot(讨论 | 贡献) 小 (跨站同步) (1个标签:Bot) |
||
第1行: | 第1行: | ||
− | /*! | + | /* <pre> */ |
− | + | /** | |
− | + | * ------------------------------------------------------------------------- | |
− | + | * !!! DON'T MODIFY THIS PAGE MANUALLY, YOUR CHANGES WILL BE OVERWRITTEN !!! | |
− | + | * ------------------------------------------------------------------------- | |
− | + | */ | |
− | + | var _addText = '{{GHIACode|page=GHIA:MoegirlPediaInterfaceCodes/blob/master/src/gadgets/localforage/MediaWiki:Gadget-localforage.js|user=[[U:AnnAngela]]|longId=3820b56ff2ac6eb2e6bb95dd82dd71db679b0c81|shortId=3820b56|message=auto: auto browserify - commit from GitHub Actions}}'; | |
− | + | ||
− | + | "use strict"; | |
− | + | (function () { | |
− | + | var _$localforage_1 = { exports: {} }; | |
− | + | (function (global) { | |
− | + | (function () { | |
− | + | (function (f) { if (typeof _$localforage_1.exports === "object" && "object" !== "undefined") { | |
− | + | _$localforage_1.exports = f(); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | var | ||
− | |||
− | function | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | else if (typeof define === "function" && define.amd) { | |
− | + | define([], f); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | else { | |
− | + | var g; | |
− | + | if (typeof window !== "undefined") { | |
− | + | g = window; | |
− | if (typeof | ||
− | |||
} | } | ||
− | + | else if (typeof global !== "undefined") { | |
− | + | g = global; | |
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | else if (typeof self !== "undefined") { | |
− | + | g = self; | |
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | else { | |
− | + | g = this; | |
− | |||
} | } | ||
− | + | g.localforage = f(); | |
− | + | } })(function () { | |
− | + | var define, module, exports; | |
− | } | + | return (function e(t, n, r) { function s(o, u) { if (!n[o]) { |
− | + | if (!t[o]) { | |
− | + | var a = "function" == "function" && require; | |
− | + | if (!u && a) | |
− | + | return a(o, !0); | |
− | + | if (i) | |
− | + | return i(o, !0); | |
− | + | var f = new Error("Cannot find module '" + o + "'"); | |
− | + | throw (f.code = "MODULE_NOT_FOUND", f); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | var l = n[o] = { exports: {} }; | |
− | + | t[o][0].call(l.exports, function (e) { var n = t[o][1][e]; return s(n ? n : e); }, l, l.exports, e, t, n, r); | |
− | + | } return n[o].exports; } var i = "function" == "function" && require; for (var o = 0; o < r.length; o++) | |
− | + | s(r[o]); return s; })({ 1: [function (_dereq_, module, exports) { | |
− | + | (function (global) { | |
− | } | + | 'use strict'; |
− | + | var Mutation = global.MutationObserver || global.WebKitMutationObserver; | |
− | + | var scheduleDrain; | |
− | + | { | |
− | + | if (Mutation) { | |
− | + | var called = 0; | |
− | + | var observer = new Mutation(nextTick); | |
− | + | var element = global.document.createTextNode(''); | |
− | + | observer.observe(element, { | |
− | + | characterData: true | |
− | + | }); | |
− | + | scheduleDrain = function () { | |
− | + | element.data = (called = ++called % 2); | |
− | + | }; | |
− | + | } | |
− | + | else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') { | |
− | + | var channel = new global.MessageChannel(); | |
− | + | channel.port1.onmessage = nextTick; | |
− | + | scheduleDrain = function () { | |
− | + | channel.port2.postMessage(0); | |
− | + | }; | |
− | + | } | |
− | + | else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) { | |
− | + | scheduleDrain = function () { | |
− | + | var scriptEl = global.document.createElement('script'); | |
− | + | scriptEl.onreadystatechange = function () { | |
− | + | nextTick(); | |
− | + | scriptEl.onreadystatechange = null; | |
− | + | scriptEl.parentNode.removeChild(scriptEl); | |
− | + | scriptEl = null; | |
− | + | }; | |
− | + | global.document.documentElement.appendChild(scriptEl); | |
− | + | }; | |
− | + | } | |
− | + | else { | |
− | + | scheduleDrain = function () { | |
− | + | setTimeout(nextTick, 0); | |
− | + | }; | |
− | + | } | |
− | + | } | |
− | + | var draining; | |
− | + | var queue = []; | |
− | + | function nextTick() { | |
− | + | draining = true; | |
− | + | var i, oldQueue; | |
− | + | var len = queue.length; | |
− | + | while (len) { | |
− | + | oldQueue = queue; | |
− | + | queue = []; | |
− | + | i = -1; | |
− | + | while (++i < len) { | |
− | + | oldQueue[i](); | |
− | + | } | |
− | + | len = queue.length; | |
− | + | } | |
− | + | draining = false; | |
− | + | } | |
− | + | module.exports = immediate; | |
− | + | function immediate(task) { | |
− | + | if (queue.push(task) === 1 && !draining) { | |
− | + | scheduleDrain(); | |
− | + | } | |
− | + | } | |
− | + | }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}); | |
− | + | }, {}], 2: [function (_dereq_, module, exports) { | |
− | + | 'use strict'; | |
− | + | var immediate = _dereq_(1); | |
− | + | function INTERNAL() { } | |
− | + | var handlers = {}; | |
− | + | var REJECTED = ['REJECTED']; | |
− | + | var FULFILLED = ['FULFILLED']; | |
− | + | var PENDING = ['PENDING']; | |
− | + | module.exports = Promise; | |
− | + | function Promise(resolver) { | |
− | + | if (typeof resolver !== 'function') { | |
− | + | throw new TypeError('resolver must be a function'); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | this.state = PENDING; | |
− | if ( | + | this.queue = []; |
− | + | this.outcome = void 0; | |
− | + | if (resolver !== INTERNAL) { | |
− | + | safelyResolveThenable(this, resolver); | |
} | } | ||
} | } | ||
− | + | Promise.prototype["catch"] = function (onRejected) { | |
− | + | return this.then(null, onRejected); | |
− | + | }; | |
− | + | Promise.prototype.then = function (onFulfilled, onRejected) { | |
− | + | if (typeof onFulfilled !== 'function' && this.state === FULFILLED || | |
− | + | typeof onRejected !== 'function' && this.state === REJECTED) { | |
− | + | return this; | |
− | + | } | |
− | + | var promise = new this.constructor(INTERNAL); | |
− | + | if (this.state !== PENDING) { | |
− | + | var resolver = this.state === FULFILLED ? onFulfilled : onRejected; | |
− | + | unwrap(promise, resolver, this.outcome); | |
− | + | } | |
− | + | else { | |
− | + | this.queue.push(new QueueItem(promise, onFulfilled, onRejected)); | |
− | + | } | |
− | + | return promise; | |
− | + | }; | |
− | + | function QueueItem(promise, onFulfilled, onRejected) { | |
− | + | this.promise = promise; | |
− | + | if (typeof onFulfilled === 'function') { | |
− | + | this.onFulfilled = onFulfilled; | |
− | + | this.callFulfilled = this.otherCallFulfilled; | |
− | + | } | |
− | + | if (typeof onRejected === 'function') { | |
− | + | this.onRejected = onRejected; | |
− | + | this.callRejected = this.otherCallRejected; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | |||
− | |||
} | } | ||
− | + | QueueItem.prototype.callFulfilled = function (value) { | |
− | + | handlers.resolve(this.promise, value); | |
− | + | }; | |
− | } | + | QueueItem.prototype.otherCallFulfilled = function (value) { |
− | + | unwrap(this.promise, this.onFulfilled, value); | |
− | + | }; | |
− | + | QueueItem.prototype.callRejected = function (value) { | |
− | + | handlers.reject(this.promise, value); | |
− | + | }; | |
− | + | QueueItem.prototype.otherCallRejected = function (value) { | |
− | + | unwrap(this.promise, this.onRejected, value); | |
− | + | }; | |
− | + | function unwrap(promise, func, value) { | |
− | + | immediate(function () { | |
− | + | var returnValue; | |
− | + | try { | |
− | + | returnValue = func(value); | |
− | + | } | |
− | + | catch (e) { | |
− | + | return handlers.reject(promise, e); | |
− | + | } | |
− | + | if (returnValue === promise) { | |
− | + | handlers.reject(promise, new TypeError('Cannot resolve promise with itself')); | |
− | + | } | |
− | + | else { | |
− | + | handlers.resolve(promise, returnValue); | |
− | + | } | |
− | + | }); | |
− | + | } | |
− | + | handlers.resolve = function (self, value) { | |
− | + | var result = tryCatch(getThen, value); | |
− | + | if (result.status === 'error') { | |
− | + | return handlers.reject(self, result.value); | |
− | + | } | |
− | + | var thenable = result.value; | |
− | + | if (thenable) { | |
− | + | safelyResolveThenable(self, thenable); | |
− | + | } | |
− | + | else { | |
− | + | self.state = FULFILLED; | |
− | + | self.outcome = value; | |
− | + | var i = -1; | |
− | + | var len = self.queue.length; | |
− | + | while (++i < len) { | |
− | + | self.queue[i].callFulfilled(value); | |
− | + | } | |
− | + | } | |
− | + | return self; | |
− | + | }; | |
− | + | handlers.reject = function (self, error) { | |
− | + | self.state = REJECTED; | |
− | + | self.outcome = error; | |
− | + | var i = -1; | |
− | + | var len = self.queue.length; | |
− | + | while (++i < len) { | |
− | + | self.queue[i].callRejected(error); | |
− | + | } | |
− | + | return self; | |
− | + | }; | |
− | + | function getThen(obj) { | |
− | + | var then = obj && obj.then; | |
− | + | if (obj && (typeof obj === 'object' || typeof obj === 'function') && typeof then === 'function') { | |
− | + | return function appyThen() { | |
− | + | then.apply(obj, arguments); | |
− | + | }; | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | function safelyResolveThenable(self, thenable) { | |
− | + | var called = false; | |
− | var | + | function onError(value) { |
− | + | if (called) { | |
− | + | return; | |
− | if ( | ||
− | |||
} | } | ||
− | + | called = true; | |
− | + | handlers.reject(self, value); | |
+ | } | ||
+ | function onSuccess(value) { | ||
+ | if (called) { | ||
+ | return; | ||
} | } | ||
− | resolve(value); | + | called = true; |
− | }; | + | handlers.resolve(self, value); |
− | + | } | |
− | + | function tryToUnwrap() { | |
− | }; | + | thenable(onSuccess, onError); |
− | } | + | } |
− | reject( | + | var result = tryCatch(tryToUnwrap); |
+ | if (result.status === 'error') { | ||
+ | onError(result.value); | ||
+ | } | ||
+ | } | ||
+ | function tryCatch(func, value) { | ||
+ | var out = {}; | ||
+ | try { | ||
+ | out.value = func(value); | ||
+ | out.status = 'success'; | ||
+ | } | ||
+ | catch (e) { | ||
+ | out.status = 'error'; | ||
+ | out.value = e; | ||
+ | } | ||
+ | return out; | ||
+ | } | ||
+ | Promise.resolve = resolve; | ||
+ | function resolve(value) { | ||
+ | if (value instanceof this) { | ||
+ | return value; | ||
+ | } | ||
+ | return handlers.resolve(new this(INTERNAL), value); | ||
+ | } | ||
+ | Promise.reject = reject; | ||
+ | function reject(reason) { | ||
+ | var promise = new this(INTERNAL); | ||
+ | return handlers.reject(promise, reason); | ||
} | } | ||
− | + | Promise.all = all; | |
− | + | function all(iterable) { | |
− | + | var self = this; | |
− | + | if (Object.prototype.toString.call(iterable) !== '[object Array]') { | |
− | + | return this.reject(new TypeError('must be an array')); | |
− | + | } | |
− | + | var len = iterable.length; | |
− | + | var called = false; | |
− | + | if (!len) { | |
− | + | return this.resolve([]); | |
− | + | } | |
− | + | var values = new Array(len); | |
− | + | var resolved = 0; | |
− | + | var i = -1; | |
+ | var promise = new this(INTERNAL); | ||
+ | while (++i < len) { | ||
+ | allResolver(iterable[i], i); | ||
+ | } | ||
+ | return promise; | ||
+ | function allResolver(value, i) { | ||
+ | self.resolve(value).then(resolveFromAll, function (error) { | ||
+ | if (!called) { | ||
+ | called = true; | ||
+ | handlers.reject(promise, error); | ||
+ | } | ||
+ | }); | ||
+ | function resolveFromAll(outValue) { | ||
+ | values[i] = outValue; | ||
+ | if (++resolved === len && !called) { | ||
+ | called = true; | ||
+ | handlers.resolve(promise, values); | ||
+ | } | ||
+ | } | ||
+ | } | ||
} | } | ||
− | + | Promise.race = race; | |
− | var | + | function race(iterable) { |
− | var | + | var self = this; |
− | var | + | if (Object.prototype.toString.call(iterable) !== '[object Array]') { |
− | + | return this.reject(new TypeError('must be an array')); | |
− | + | } | |
− | + | var len = iterable.length; | |
− | + | var called = false; | |
− | if ( | + | if (!len) { |
− | + | return this.resolve([]); | |
+ | } | ||
+ | var i = -1; | ||
+ | var promise = new this(INTERNAL); | ||
+ | while (++i < len) { | ||
+ | resolver(iterable[i]); | ||
+ | } | ||
+ | return promise; | ||
+ | function resolver(value) { | ||
+ | self.resolve(value).then(function (response) { | ||
+ | if (!called) { | ||
+ | called = true; | ||
+ | handlers.resolve(promise, response); | ||
} | } | ||
− | + | }, function (error) { | |
− | + | if (!called) { | |
− | + | called = true; | |
− | + | handlers.reject(promise, error); | |
− | if ( | ||
− | |||
− | |||
− | |||
} | } | ||
− | } | + | }); |
− | + | } | |
+ | } | ||
+ | }, { "1": 1 }], 3: [function (_dereq_, module, exports) { | ||
+ | (function (global) { | ||
+ | 'use strict'; | ||
+ | if (typeof global.Promise !== 'function') { | ||
+ | global.Promise = _dereq_(2); | ||
+ | } | ||
+ | }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}); | ||
+ | }, { "2": 2 }], 4: [function (_dereq_, module, exports) { | ||
+ | 'use strict'; | ||
+ | var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; | ||
+ | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { | ||
+ | throw new TypeError("Cannot call a class as a function"); | ||
+ | } } | ||
+ | function getIDB() { | ||
+ | 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; | ||
} | } | ||
− | } | + | } |
− | + | catch (e) { | |
− | + | return; | |
− | } | + | } |
− | |||
− | |||
} | } | ||
− | + | var idb = getIDB(); | |
− | + | function isIndexedDBValid() { | |
− | + | try { | |
− | + | if (!idb || !idb.open) { | |
− | + | return false; | |
− | + | } | |
− | + | var isSafari = typeof openDatabase !== 'undefined' && /(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent) && !/BlackBerry/.test(navigator.platform); | |
− | + | var hasFetch = typeof fetch === 'function' && fetch.toString().indexOf('[native code') !== -1; | |
− | + | return (!isSafari || hasFetch) && typeof indexedDB !== 'undefined' && | |
− | + | typeof IDBKeyRange !== 'undefined'; | |
− | + | } | |
− | + | catch (e) { | |
− | + | return false; | |
− | |||
− | |||
− | |||
− | return | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | function createBlob(parts, properties) { | |
− | + | parts = parts || []; | |
− | + | properties = properties || {}; | |
− | + | try { | |
− | + | return new Blob(parts, properties); | |
− | |||
− | |||
− | |||
} | } | ||
− | + | catch (e) { | |
− | + | if (e.name !== 'TypeError') { | |
− | + | throw e; | |
− | + | } | |
− | + | var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : WebKitBlobBuilder; | |
− | + | var builder = new Builder(); | |
− | + | for (var i = 0; i < parts.length; i += 1) { | |
− | + | builder.append(parts[i]); | |
− | |||
− | |||
} | } | ||
− | + | return builder.getBlob(properties.type); | |
− | }; | + | } |
− | + | } | |
− | var | + | if (typeof Promise === 'undefined') { |
− | + | _dereq_(3); | |
− | }; | + | } |
− | } | + | var Promise$1 = Promise; |
− | + | function executeCallback(promise, callback) { | |
+ | if (callback) { | ||
+ | promise.then(function (result) { | ||
+ | callback(null, result); | ||
+ | }, function (error) { | ||
+ | callback(error); | ||
+ | }); | ||
+ | } | ||
+ | } | ||
+ | function executeTwoCallbacks(promise, callback, errorCallback) { | ||
+ | if (typeof callback === 'function') { | ||
+ | promise.then(callback); | ||
+ | } | ||
+ | if (typeof errorCallback === 'function') { | ||
+ | promise["catch"](errorCallback); | ||
+ | } | ||
+ | } | ||
+ | function normalizeKey(key) { | ||
+ | if (typeof key !== 'string') { | ||
+ | console.warn(key + ' used as a key, but it is not a string.'); | ||
+ | key = String(key); | ||
+ | } | ||
+ | return key; | ||
+ | } | ||
+ | function getCallback() { | ||
+ | if (arguments.length && typeof arguments[arguments.length - 1] === 'function') { | ||
+ | return arguments[arguments.length - 1]; | ||
+ | } | ||
+ | } | ||
+ | var DETECT_BLOB_SUPPORT_STORE = 'local-forage-detect-blob-support'; | ||
+ | var supportsBlobs = void 0; | ||
+ | var dbContexts = {}; | ||
+ | var toString = Object.prototype.toString; | ||
+ | var READ_ONLY = 'readonly'; | ||
+ | var READ_WRITE = 'readwrite'; | ||
+ | function _binStringToArrayBuffer(bin) { | ||
+ | var length = bin.length; | ||
+ | var buf = new ArrayBuffer(length); | ||
+ | var arr = new Uint8Array(buf); | ||
+ | for (var i = 0; i < length; i++) { | ||
+ | arr[i] = bin.charCodeAt(i); | ||
+ | } | ||
+ | return buf; | ||
+ | } | ||
+ | function _checkBlobSupportWithoutCaching(idb) { | ||
+ | return new Promise$1(function (resolve) { | ||
+ | var txn = idb.transaction(DETECT_BLOB_SUPPORT_STORE, READ_WRITE); | ||
+ | var blob = createBlob(['']); | ||
+ | txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob, 'key'); | ||
+ | txn.onabort = function (e) { | ||
+ | e.preventDefault(); | ||
+ | e.stopPropagation(); | ||
+ | resolve(false); | ||
+ | }; | ||
+ | txn.oncomplete = function () { | ||
+ | var matchedChrome = navigator.userAgent.match(/Chrome\/(\d+)/); | ||
+ | var matchedEdge = navigator.userAgent.match(/Edge\//); | ||
+ | resolve(matchedEdge || !matchedChrome || parseInt(matchedChrome[1], 10) >= 43); | ||
+ | }; | ||
+ | })["catch"](function () { | ||
+ | return false; | ||
+ | }); | ||
} | } | ||
− | + | function _checkBlobSupport(idb) { | |
− | + | if (typeof supportsBlobs === 'boolean') { | |
− | + | return Promise$1.resolve(supportsBlobs); | |
− | + | } | |
− | + | return _checkBlobSupportWithoutCaching(idb).then(function (value) { | |
− | + | supportsBlobs = value; | |
− | + | return supportsBlobs; | |
− | + | }); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | function _deferReadiness(dbInfo) { | |
− | var | + | var dbContext = dbContexts[dbInfo.name]; |
− | + | var deferredOperation = {}; | |
− | + | deferredOperation.promise = new Promise$1(function (resolve, reject) { | |
− | + | deferredOperation.resolve = resolve; | |
− | + | deferredOperation.reject = reject; | |
− | + | }); | |
− | var | + | dbContext.deferredOperations.push(deferredOperation); |
− | + | if (!dbContext.dbReady) { | |
− | resolve | + | dbContext.dbReady = deferredOperation.promise; |
− | }; | + | } |
− | + | else { | |
− | + | dbContext.dbReady = dbContext.dbReady.then(function () { | |
− | } | + | return deferredOperation.promise; |
− | + | }); | |
− | + | } | |
− | |||
− | |||
− | |||
− | } | ||
− | |||
− | |||
} | } | ||
− | + | function _advanceReadiness(dbInfo) { | |
− | + | var dbContext = dbContexts[dbInfo.name]; | |
− | + | var deferredOperation = dbContext.deferredOperations.pop(); | |
− | + | if (deferredOperation) { | |
− | + | deferredOperation.resolve(); | |
− | + | return deferredOperation.promise; | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | function _rejectReadiness(dbInfo, err) { | |
− | var | + | var dbContext = dbContexts[dbInfo.name]; |
− | var | + | var deferredOperation = dbContext.deferredOperations.pop(); |
− | + | if (deferredOperation) { | |
− | + | deferredOperation.reject(err); | |
− | + | return deferredOperation.promise; | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | function _getConnection(dbInfo, upgradeNeeded) { | |
− | + | return new Promise$1(function (resolve, reject) { | |
− | + | dbContexts[dbInfo.name] = dbContexts[dbInfo.name] || createDbContext(); | |
− | + | if (dbInfo.db) { | |
− | + | if (upgradeNeeded) { | |
− | + | _deferReadiness(dbInfo); | |
− | + | dbInfo.db.close(); | |
− | + | } | |
− | + | else { | |
− | + | return resolve(dbInfo.db); | |
− | + | } | |
− | + | } | |
− | + | var dbArgs = [dbInfo.name]; | |
+ | if (upgradeNeeded) { | ||
+ | dbArgs.push(dbInfo.version); | ||
+ | } | ||
+ | var openreq = idb.open.apply(idb, dbArgs); | ||
+ | if (upgradeNeeded) { | ||
+ | openreq.onupgradeneeded = function (e) { | ||
+ | var db = openreq.result; | ||
+ | try { | ||
+ | db.createObjectStore(dbInfo.storeName); | ||
+ | if (e.oldVersion <= 1) { | ||
+ | db.createObjectStore(DETECT_BLOB_SUPPORT_STORE); | ||
+ | } | ||
+ | } | ||
+ | catch (ex) { | ||
+ | if (ex.name === 'ConstraintError') { | ||
+ | console.warn('The database "' + dbInfo.name + '"' + ' has been upgraded from version ' + e.oldVersion + ' to version ' + e.newVersion + ', but the storage "' + dbInfo.storeName + '" already exists.'); | ||
+ | } | ||
+ | else { | ||
+ | throw ex; | ||
+ | } | ||
+ | } | ||
+ | }; | ||
+ | } | ||
+ | openreq.onerror = function (e) { | ||
+ | e.preventDefault(); | ||
+ | reject(openreq.error); | ||
+ | }; | ||
+ | openreq.onsuccess = function () { | ||
+ | var db = openreq.result; | ||
+ | db.onversionchange = function (e) { | ||
+ | e.target.close(); | ||
+ | }; | ||
+ | resolve(db); | ||
+ | _advanceReadiness(dbInfo); | ||
+ | }; | ||
+ | }); | ||
} | } | ||
− | + | function _getOriginalConnection(dbInfo) { | |
− | + | return _getConnection(dbInfo, false); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | function _getUpgradedConnection(dbInfo) { | |
− | + | return _getConnection(dbInfo, true); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | function _isUpgradeNeeded(dbInfo, defaultVersion) { | |
− | var | + | if (!dbInfo.db) { |
− | var | + | return true; |
− | var | + | } |
− | + | var isNewStore = !dbInfo.db.objectStoreNames.contains(dbInfo.storeName); | |
− | + | var isDowngrade = dbInfo.version < dbInfo.db.version; | |
− | if (! | + | var isUpgrade = dbInfo.version > dbInfo.db.version; |
− | + | if (isDowngrade) { | |
− | + | if (dbInfo.version !== defaultVersion) { | |
− | + | console.warn('The database "' + dbInfo.name + '"' + " can't be downgraded from version " + dbInfo.db.version + ' to version ' + dbInfo.version + '.'); | |
} | } | ||
− | + | dbInfo.version = dbInfo.db.version; | |
− | + | } | |
− | + | if (isUpgrade || isNewStore) { | |
− | + | if (isNewStore) { | |
− | + | var incVersion = dbInfo.db.version + 1; | |
− | + | if (incVersion > dbInfo.version) { | |
− | + | dbInfo.version = incVersion; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
} | } | ||
+ | return true; | ||
+ | } | ||
+ | return false; | ||
+ | } | ||
+ | function _encodeBlob(blob) { | ||
+ | return new Promise$1(function (resolve, reject) { | ||
+ | var reader = new FileReader(); | ||
+ | reader.onerror = reject; | ||
+ | reader.onloadend = function (e) { | ||
+ | var base64 = btoa(e.target.result || ''); | ||
+ | resolve({ | ||
+ | __local_forage_encoded_blob: true, | ||
+ | data: base64, | ||
+ | type: blob.type | ||
+ | }); | ||
+ | }; | ||
+ | reader.readAsBinaryString(blob); | ||
+ | }); | ||
+ | } | ||
+ | function _decodeBlob(encodedBlob) { | ||
+ | var arrayBuff = _binStringToArrayBuffer(atob(encodedBlob.data)); | ||
+ | return createBlob([arrayBuff], { type: encodedBlob.type }); | ||
+ | } | ||
+ | function _isEncodedBlob(value) { | ||
+ | return value && value.__local_forage_encoded_blob; | ||
+ | } | ||
+ | function _fullyReady(callback) { | ||
+ | var self = this; | ||
+ | var promise = self._initReady().then(function () { | ||
+ | var dbContext = dbContexts[self._dbInfo.name]; | ||
+ | if (dbContext && dbContext.dbReady) { | ||
+ | return dbContext.dbReady; | ||
+ | } | ||
+ | }); | ||
+ | executeTwoCallbacks(promise, callback, callback); | ||
+ | return promise; | ||
+ | } | ||
+ | function _tryReconnect(dbInfo) { | ||
+ | _deferReadiness(dbInfo); | ||
+ | var dbContext = dbContexts[dbInfo.name]; | ||
+ | var forages = dbContext.forages; | ||
+ | for (var i = 0; i < forages.length; i++) { | ||
+ | var forage = forages[i]; | ||
+ | if (forage._dbInfo.db) { | ||
+ | forage._dbInfo.db.close(); | ||
+ | forage._dbInfo.db = null; | ||
+ | } | ||
+ | } | ||
+ | dbInfo.db = null; | ||
+ | return _getOriginalConnection(dbInfo).then(function (db) { | ||
+ | dbInfo.db = db; | ||
+ | if (_isUpgradeNeeded(dbInfo)) { | ||
+ | return _getUpgradedConnection(dbInfo); | ||
+ | } | ||
+ | return db; | ||
+ | }).then(function (db) { | ||
+ | dbInfo.db = dbContext.db = db; | ||
+ | for (var i = 0; i < forages.length; i++) { | ||
+ | forages[i]._dbInfo.db = db; | ||
+ | } | ||
+ | })["catch"](function (err) { | ||
+ | _rejectReadiness(dbInfo, err); | ||
+ | throw err; | ||
+ | }); | ||
+ | } | ||
+ | function createTransaction(dbInfo, mode, callback, retries) { | ||
+ | if (retries === undefined) { | ||
+ | retries = 1; | ||
+ | } | ||
+ | try { | ||
+ | var tx = dbInfo.db.transaction(dbInfo.storeName, mode); | ||
+ | callback(null, tx); | ||
+ | } | ||
+ | catch (err) { | ||
+ | if (retries > 0 && (!dbInfo.db || err.name === 'InvalidStateError' || err.name === 'NotFoundError')) { | ||
+ | return Promise$1.resolve().then(function () { | ||
+ | if (!dbInfo.db || err.name === 'NotFoundError' && !dbInfo.db.objectStoreNames.contains(dbInfo.storeName) && dbInfo.version <= dbInfo.db.version) { | ||
+ | if (dbInfo.db) { | ||
+ | dbInfo.version = dbInfo.db.version + 1; | ||
+ | } | ||
+ | return _getUpgradedConnection(dbInfo); | ||
+ | } | ||
+ | }).then(function () { | ||
+ | return _tryReconnect(dbInfo).then(function () { | ||
+ | createTransaction(dbInfo, mode, callback, retries - 1); | ||
+ | }); | ||
+ | })["catch"](callback); | ||
+ | } | ||
+ | callback(err); | ||
+ | } | ||
+ | } | ||
+ | function createDbContext() { | ||
+ | return { | ||
+ | forages: [], | ||
+ | db: null, | ||
+ | dbReady: null, | ||
+ | deferredOperations: [] | ||
}; | }; | ||
− | + | } | |
− | + | function _initStorage(options) { | |
+ | var self = this; | ||
+ | var dbInfo = { | ||
+ | db: null | ||
}; | }; | ||
− | } catch (e) { | + | if (options) { |
− | reject(e); | + | for (var i in options) { |
+ | dbInfo[i] = options[i]; | ||
+ | } | ||
+ | } | ||
+ | var dbContext = dbContexts[dbInfo.name]; | ||
+ | if (!dbContext) { | ||
+ | dbContext = createDbContext(); | ||
+ | dbContexts[dbInfo.name] = dbContext; | ||
+ | } | ||
+ | dbContext.forages.push(self); | ||
+ | if (!self._initReady) { | ||
+ | self._initReady = self.ready; | ||
+ | self.ready = _fullyReady; | ||
+ | } | ||
+ | var initPromises = []; | ||
+ | function ignoreErrors() { | ||
+ | return Promise$1.resolve(); | ||
+ | } | ||
+ | for (var j = 0; j < dbContext.forages.length; j++) { | ||
+ | var forage = dbContext.forages[j]; | ||
+ | if (forage !== self) { | ||
+ | initPromises.push(forage._initReady()["catch"](ignoreErrors)); | ||
+ | } | ||
+ | } | ||
+ | var forages = dbContext.forages.slice(0); | ||
+ | return Promise$1.all(initPromises).then(function () { | ||
+ | dbInfo.db = dbContext.db; | ||
+ | return _getOriginalConnection(dbInfo); | ||
+ | }).then(function (db) { | ||
+ | dbInfo.db = db; | ||
+ | if (_isUpgradeNeeded(dbInfo, self._defaultConfig.version)) { | ||
+ | return _getUpgradedConnection(dbInfo); | ||
+ | } | ||
+ | return db; | ||
+ | }).then(function (db) { | ||
+ | dbInfo.db = dbContext.db = db; | ||
+ | self._dbInfo = dbInfo; | ||
+ | for (var k = 0; k < forages.length; k++) { | ||
+ | var forage = forages[k]; | ||
+ | if (forage !== self) { | ||
+ | forage._dbInfo.db = dbInfo.db; | ||
+ | forage._dbInfo.version = dbInfo.version; | ||
+ | } | ||
+ | } | ||
+ | }); | ||
+ | } | ||
+ | function getItem(key, callback) { | ||
+ | var self = this; | ||
+ | key = normalizeKey(key); | ||
+ | var promise = new Promise$1(function (resolve, reject) { | ||
+ | self.ready().then(function () { | ||
+ | createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) { | ||
+ | if (err) { | ||
+ | return reject(err); | ||
+ | } | ||
+ | try { | ||
+ | var store = transaction.objectStore(self._dbInfo.storeName); | ||
+ | var req = store.get(key); | ||
+ | req.onsuccess = function () { | ||
+ | var value = req.result; | ||
+ | if (value === undefined) { | ||
+ | value = null; | ||
+ | } | ||
+ | if (_isEncodedBlob(value)) { | ||
+ | value = _decodeBlob(value); | ||
+ | } | ||
+ | resolve(value); | ||
+ | }; | ||
+ | req.onerror = function () { | ||
+ | reject(req.error); | ||
+ | }; | ||
+ | } | ||
+ | catch (e) { | ||
+ | reject(e); | ||
+ | } | ||
+ | }); | ||
+ | })["catch"](reject); | ||
+ | }); | ||
+ | executeCallback(promise, callback); | ||
+ | return promise; | ||
+ | } | ||
+ | function iterate(iterator, callback) { | ||
+ | var self = this; | ||
+ | var promise = new Promise$1(function (resolve, reject) { | ||
+ | self.ready().then(function () { | ||
+ | createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) { | ||
+ | if (err) { | ||
+ | return reject(err); | ||
+ | } | ||
+ | try { | ||
+ | var store = transaction.objectStore(self._dbInfo.storeName); | ||
+ | var req = store.openCursor(); | ||
+ | var iterationNumber = 1; | ||
+ | req.onsuccess = function () { | ||
+ | var cursor = req.result; | ||
+ | if (cursor) { | ||
+ | var value = cursor.value; | ||
+ | if (_isEncodedBlob(value)) { | ||
+ | value = _decodeBlob(value); | ||
+ | } | ||
+ | var result = iterator(value, cursor.key, iterationNumber++); | ||
+ | if (result !== void 0) { | ||
+ | resolve(result); | ||
+ | } | ||
+ | else { | ||
+ | cursor["continue"](); | ||
+ | } | ||
+ | } | ||
+ | else { | ||
+ | resolve(); | ||
+ | } | ||
+ | }; | ||
+ | req.onerror = function () { | ||
+ | reject(req.error); | ||
+ | }; | ||
+ | } | ||
+ | catch (e) { | ||
+ | reject(e); | ||
+ | } | ||
+ | }); | ||
+ | })["catch"](reject); | ||
+ | }); | ||
+ | executeCallback(promise, callback); | ||
+ | return promise; | ||
+ | } | ||
+ | function setItem(key, value, callback) { | ||
+ | var self = this; | ||
+ | key = normalizeKey(key); | ||
+ | var promise = new Promise$1(function (resolve, reject) { | ||
+ | var dbInfo; | ||
+ | self.ready().then(function () { | ||
+ | dbInfo = self._dbInfo; | ||
+ | if (toString.call(value) === '[object Blob]') { | ||
+ | return _checkBlobSupport(dbInfo.db).then(function (blobSupport) { | ||
+ | if (blobSupport) { | ||
+ | return value; | ||
+ | } | ||
+ | return _encodeBlob(value); | ||
+ | }); | ||
+ | } | ||
+ | return value; | ||
+ | }).then(function (value) { | ||
+ | createTransaction(self._dbInfo, READ_WRITE, function (err, transaction) { | ||
+ | if (err) { | ||
+ | return reject(err); | ||
+ | } | ||
+ | try { | ||
+ | var store = transaction.objectStore(self._dbInfo.storeName); | ||
+ | if (value === null) { | ||
+ | value = undefined; | ||
+ | } | ||
+ | var req = store.put(value, key); | ||
+ | transaction.oncomplete = function () { | ||
+ | if (value === undefined) { | ||
+ | value = null; | ||
+ | } | ||
+ | resolve(value); | ||
+ | }; | ||
+ | transaction.onabort = transaction.onerror = function () { | ||
+ | var err = req.error ? req.error : req.transaction.error; | ||
+ | reject(err); | ||
+ | }; | ||
+ | } | ||
+ | catch (e) { | ||
+ | reject(e); | ||
+ | } | ||
+ | }); | ||
+ | })["catch"](reject); | ||
+ | }); | ||
+ | executeCallback(promise, callback); | ||
+ | return promise; | ||
} | } | ||
− | + | function removeItem(key, callback) { | |
− | + | var self = this; | |
− | + | key = normalizeKey(key); | |
− | + | var promise = new Promise$1(function (resolve, reject) { | |
− | + | self.ready().then(function () { | |
− | + | createTransaction(self._dbInfo, READ_WRITE, function (err, transaction) { | |
− | + | if (err) { | |
− | + | return reject(err); | |
− | + | } | |
− | + | try { | |
− | + | var store = transaction.objectStore(self._dbInfo.storeName); | |
− | + | var req = store["delete"](key); | |
− | + | transaction.oncomplete = function () { | |
+ | resolve(); | ||
+ | }; | ||
+ | transaction.onerror = function () { | ||
+ | reject(req.error); | ||
+ | }; | ||
+ | transaction.onabort = function () { | ||
+ | var err = req.error ? req.error : req.transaction.error; | ||
+ | reject(err); | ||
+ | }; | ||
+ | } | ||
+ | catch (e) { | ||
+ | reject(e); | ||
+ | } | ||
+ | }); | ||
+ | })["catch"](reject); | ||
+ | }); | ||
+ | executeCallback(promise, callback); | ||
+ | return promise; | ||
+ | } | ||
+ | function clear(callback) { | ||
+ | var self = this; | ||
+ | var promise = new Promise$1(function (resolve, reject) { | ||
+ | self.ready().then(function () { | ||
+ | createTransaction(self._dbInfo, READ_WRITE, function (err, transaction) { | ||
+ | if (err) { | ||
+ | return reject(err); | ||
+ | } | ||
+ | try { | ||
+ | var store = transaction.objectStore(self._dbInfo.storeName); | ||
+ | var req = store.clear(); | ||
+ | transaction.oncomplete = function () { | ||
+ | resolve(); | ||
+ | }; | ||
+ | transaction.onabort = transaction.onerror = function () { | ||
+ | var err = req.error ? req.error : req.transaction.error; | ||
+ | reject(err); | ||
+ | }; | ||
+ | } | ||
+ | catch (e) { | ||
+ | reject(e); | ||
+ | } | ||
+ | }); | ||
+ | })["catch"](reject); | ||
+ | }); | ||
+ | executeCallback(promise, callback); | ||
+ | return promise; | ||
+ | } | ||
+ | function length(callback) { | ||
+ | var self = this; | ||
+ | var promise = new Promise$1(function (resolve, reject) { | ||
+ | self.ready().then(function () { | ||
+ | createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) { | ||
+ | if (err) { | ||
+ | return reject(err); | ||
+ | } | ||
+ | try { | ||
+ | var store = transaction.objectStore(self._dbInfo.storeName); | ||
+ | var req = store.count(); | ||
+ | req.onsuccess = function () { | ||
+ | resolve(req.result); | ||
+ | }; | ||
+ | req.onerror = function () { | ||
+ | reject(req.error); | ||
+ | }; | ||
+ | } | ||
+ | catch (e) { | ||
+ | reject(e); | ||
+ | } | ||
+ | }); | ||
+ | })["catch"](reject); | ||
+ | }); | ||
+ | executeCallback(promise, callback); | ||
+ | return promise; | ||
} | } | ||
− | + | function key(n, callback) { | |
− | var | + | var self = this; |
− | var | + | var promise = new Promise$1(function (resolve, reject) { |
− | + | if (n < 0) { | |
− | + | resolve(null); | |
− | |||
− | if ( | ||
− | resolve( | ||
return; | return; | ||
} | } | ||
− | + | self.ready().then(function () { | |
− | + | createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) { | |
− | + | if (err) { | |
− | + | return reject(err); | |
− | + | } | |
− | + | try { | |
− | + | var store = transaction.objectStore(self._dbInfo.storeName); | |
− | + | var advanced = false; | |
+ | var req = store.openKeyCursor(); | ||
+ | req.onsuccess = function () { | ||
+ | var cursor = req.result; | ||
+ | if (!cursor) { | ||
+ | resolve(null); | ||
+ | return; | ||
+ | } | ||
+ | if (n === 0) { | ||
+ | resolve(cursor.key); | ||
+ | } | ||
+ | else { | ||
+ | if (!advanced) { | ||
+ | advanced = true; | ||
+ | cursor.advance(n); | ||
+ | } | ||
+ | else { | ||
+ | resolve(cursor.key); | ||
+ | } | ||
+ | } | ||
+ | }; | ||
+ | req.onerror = function () { | ||
+ | reject(req.error); | ||
+ | }; | ||
+ | } | ||
+ | catch (e) { | ||
+ | reject(e); | ||
+ | } | ||
+ | }); | ||
+ | })["catch"](reject); | ||
+ | }); | ||
+ | executeCallback(promise, callback); | ||
+ | return promise; | ||
} | } | ||
− | + | function keys(callback) { | |
− | + | var self = this; | |
− | + | var promise = new Promise$1(function (resolve, reject) { | |
− | + | self.ready().then(function () { | |
− | + | createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) { | |
− | + | if (err) { | |
− | + | return reject(err); | |
− | + | } | |
− | + | try { | |
− | + | var store = transaction.objectStore(self._dbInfo.storeName); | |
− | + | var req = store.openKeyCursor(); | |
− | + | var keys = []; | |
− | + | req.onsuccess = function () { | |
− | + | var cursor = req.result; | |
− | + | if (!cursor) { | |
− | + | resolve(keys); | |
− | + | return; | |
− | + | } | |
− | + | keys.push(cursor.key); | |
− | + | cursor["continue"](); | |
− | + | }; | |
− | + | req.onerror = function () { | |
− | + | reject(req.error); | |
− | + | }; | |
− | + | } | |
− | + | catch (e) { | |
− | + | reject(e); | |
− | + | } | |
− | + | }); | |
− | + | })["catch"](reject); | |
− | + | }); | |
− | + | executeCallback(promise, callback); | |
− | + | return promise; | |
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | var dropDBPromise = new Promise$1(function(resolve, reject) { | + | function dropInstance(options, callback) { |
− | + | callback = getCallback.apply(this, arguments); | |
− | + | var currentConfig = this.config(); | |
− | + | options = typeof options !== 'function' && options || {}; | |
− | + | if (!options.name) { | |
− | + | options.name = options.name || currentConfig.name; | |
+ | options.storeName = options.storeName || currentConfig.storeName; | ||
+ | } | ||
+ | var self = this; | ||
+ | var promise; | ||
+ | if (!options.name) { | ||
+ | promise = Promise$1.reject('Invalid arguments'); | ||
+ | } | ||
+ | else { | ||
+ | var isCurrentDb = options.name === currentConfig.name && self._dbInfo.db; | ||
+ | var dbPromise = isCurrentDb ? Promise$1.resolve(self._dbInfo.db) : _getOriginalConnection(options).then(function (db) { | ||
+ | var dbContext = dbContexts[options.name]; | ||
+ | var forages = dbContext.forages; | ||
+ | dbContext.db = db; | ||
+ | for (var i = 0; i < forages.length; i++) { | ||
+ | forages[i]._dbInfo.db = db; | ||
+ | } | ||
+ | return db; | ||
+ | }); | ||
+ | if (!options.storeName) { | ||
+ | promise = dbPromise.then(function (db) { | ||
+ | _deferReadiness(options); | ||
+ | var dbContext = dbContexts[options.name]; | ||
+ | var forages = dbContext.forages; | ||
+ | db.close(); | ||
+ | for (var i = 0; i < forages.length; i++) { | ||
+ | var forage = forages[i]; | ||
+ | forage._dbInfo.db = null; | ||
+ | } | ||
+ | var dropDBPromise = new Promise$1(function (resolve, reject) { | ||
+ | var req = idb.deleteDatabase(options.name); | ||
+ | req.onerror = function () { | ||
+ | var db = req.result; | ||
+ | if (db) { | ||
+ | db.close(); | ||
+ | } | ||
+ | reject(req.error); | ||
+ | }; | ||
+ | req.onblocked = function () { | ||
+ | console.warn('dropInstance blocked for database "' + options.name + '" until all open connections are closed'); | ||
+ | }; | ||
+ | req.onsuccess = function () { | ||
+ | var db = req.result; | ||
+ | if (db) { | ||
+ | db.close(); | ||
+ | } | ||
+ | resolve(db); | ||
+ | }; | ||
+ | }); | ||
+ | return dropDBPromise.then(function (db) { | ||
+ | dbContext.db = db; | ||
+ | for (var i = 0; i < forages.length; i++) { | ||
+ | var _forage = forages[i]; | ||
+ | _advanceReadiness(_forage._dbInfo); | ||
+ | } | ||
+ | })["catch"](function (err) { | ||
+ | (_rejectReadiness(options, err) || Promise$1.resolve())["catch"](function () { }); | ||
+ | throw err; | ||
+ | }); | ||
+ | }); | ||
} | } | ||
− | reject(err); | + | else { |
− | + | promise = dbPromise.then(function (db) { | |
− | + | if (!db.objectStoreNames.contains(options.storeName)) { | |
− | + | return; | |
− | + | } | |
− | + | var newVersion = db.version + 1; | |
+ | _deferReadiness(options); | ||
+ | var dbContext = dbContexts[options.name]; | ||
+ | var forages = dbContext.forages; | ||
+ | db.close(); | ||
+ | for (var i = 0; i < forages.length; i++) { | ||
+ | var forage = forages[i]; | ||
+ | forage._dbInfo.db = null; | ||
+ | forage._dbInfo.version = newVersion; | ||
+ | } | ||
+ | var dropObjectPromise = new Promise$1(function (resolve, reject) { | ||
+ | var req = idb.open(options.name, newVersion); | ||
+ | req.onerror = function (err) { | ||
+ | var db = req.result; | ||
+ | db.close(); | ||
+ | reject(err); | ||
+ | }; | ||
+ | req.onupgradeneeded = function () { | ||
+ | var db = req.result; | ||
+ | db.deleteObjectStore(options.storeName); | ||
+ | }; | ||
+ | req.onsuccess = function () { | ||
+ | var db = req.result; | ||
+ | db.close(); | ||
+ | resolve(db); | ||
+ | }; | ||
+ | }); | ||
+ | return dropObjectPromise.then(function (db) { | ||
+ | dbContext.db = db; | ||
+ | for (var j = 0; j < forages.length; j++) { | ||
+ | var _forage2 = forages[j]; | ||
+ | _forage2._dbInfo.db = db; | ||
+ | _advanceReadiness(_forage2._dbInfo); | ||
+ | } | ||
+ | })["catch"](function (err) { | ||
+ | (_rejectReadiness(options, err) || Promise$1.resolve())["catch"](function () { }); | ||
+ | throw err; | ||
+ | }); | ||
+ | }); | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | executeCallback(promise, callback); | |
− | ( | + | return promise; |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | var | + | var asyncStorage = { |
− | + | _driver: 'asyncStorage', | |
− | + | _initStorage: _initStorage, | |
− | + | _support: isIndexedDBValid(), | |
− | + | iterate: iterate, | |
− | + | getItem: getItem, | |
− | + | setItem: setItem, | |
− | + | removeItem: removeItem, | |
− | + | clear: clear, | |
+ | length: length, | ||
+ | key: key, | ||
+ | keys: keys, | ||
+ | dropInstance: dropInstance | ||
+ | }; | ||
+ | function isWebSQLValid() { | ||
+ | return typeof openDatabase === 'function'; | ||
} | } | ||
− | var | + | var BASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; |
− | var | + | var BLOB_TYPE_PREFIX = '~~local_forage_type~'; |
− | + | var BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/; | |
− | + | var SERIALIZED_MARKER = '__lfsc__:'; | |
− | + | var SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length; | |
− | + | var TYPE_ARRAYBUFFER = 'arbf'; | |
− | + | var TYPE_BLOB = 'blob'; | |
− | + | var TYPE_INT8ARRAY = 'si08'; | |
− | + | var TYPE_UINT8ARRAY = 'ui08'; | |
− | + | var TYPE_UINT8CLAMPEDARRAY = 'uic8'; | |
− | + | var TYPE_INT16ARRAY = 'si16'; | |
− | + | var TYPE_INT32ARRAY = 'si32'; | |
− | + | var TYPE_UINT16ARRAY = 'ur16'; | |
− | + | var TYPE_UINT32ARRAY = 'ui32'; | |
− | + | var TYPE_FLOAT32ARRAY = 'fl32'; | |
− | }; | + | var TYPE_FLOAT64ARRAY = 'fl64'; |
− | } | + | var TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length; |
− | + | var toString$1 = Object.prototype.toString; | |
− | + | function stringToBuffer(serializedString) { | |
− | for ( | + | var bufferLength = serializedString.length * 0.75; |
− | + | var len = serializedString.length; | |
− | + | var i; | |
− | + | var p = 0; | |
+ | var encoded1, encoded2, encoded3, encoded4; | ||
+ | if (serializedString[serializedString.length - 1] === '=') { | ||
+ | bufferLength--; | ||
+ | if (serializedString[serializedString.length - 2] === '=') { | ||
+ | bufferLength--; | ||
+ | } | ||
+ | } | ||
+ | var buffer = new ArrayBuffer(bufferLength); | ||
+ | var bytes = new Uint8Array(buffer); | ||
+ | for (i = 0; i < len; i += 4) { | ||
+ | encoded1 = BASE_CHARS.indexOf(serializedString[i]); | ||
+ | encoded2 = BASE_CHARS.indexOf(serializedString[i + 1]); | ||
+ | encoded3 = BASE_CHARS.indexOf(serializedString[i + 2]); | ||
+ | encoded4 = BASE_CHARS.indexOf(serializedString[i + 3]); | ||
+ | bytes[p++] = encoded1 << 2 | encoded2 >> 4; | ||
+ | bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2; | ||
+ | bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63; | ||
+ | } | ||
+ | return buffer; | ||
+ | } | ||
+ | function bufferToString(buffer) { | ||
+ | var bytes = new Uint8Array(buffer); | ||
+ | var base64String = ''; | ||
+ | var i; | ||
+ | for (i = 0; i < bytes.length; i += 3) { | ||
+ | base64String += BASE_CHARS[bytes[i] >> 2]; | ||
+ | base64String += BASE_CHARS[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4]; | ||
+ | base64String += BASE_CHARS[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6]; | ||
+ | base64String += BASE_CHARS[bytes[i + 2] & 63]; | ||
+ | } | ||
+ | if (bytes.length % 3 === 2) { | ||
+ | base64String = base64String.substring(0, base64String.length - 1) + '='; | ||
+ | } | ||
+ | else if (bytes.length % 3 === 1) { | ||
+ | base64String = base64String.substring(0, base64String.length - 2) + '=='; | ||
} | } | ||
− | + | return base64String; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | function serialize(value, callback) { | |
− | + | var valueType = ''; | |
− | + | if (value) { | |
− | + | valueType = toString$1.call(value); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | var | ||
− | |||
− | |||
− | if ( | ||
− | |||
} | } | ||
− | + | if (value && (valueType === '[object ArrayBuffer]' || value.buffer && toString$1.call(value.buffer) === '[object ArrayBuffer]')) { | |
− | + | var buffer; | |
− | + | var marker = SERIALIZED_MARKER; | |
− | + | if (value instanceof ArrayBuffer) { | |
− | + | buffer = value; | |
− | + | marker += TYPE_ARRAYBUFFER; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | var | ||
− | var | ||
− | |||
− | |||
− | if ( | ||
− | |||
} | } | ||
− | + | else { | |
− | + | buffer = value.buffer; | |
− | + | if (valueType === '[object Int8Array]') { | |
− | + | marker += TYPE_INT8ARRAY; | |
− | + | } | |
− | + | else if (valueType === '[object Uint8Array]') { | |
+ | marker += TYPE_UINT8ARRAY; | ||
+ | } | ||
+ | else if (valueType === '[object Uint8ClampedArray]') { | ||
+ | marker += TYPE_UINT8CLAMPEDARRAY; | ||
+ | } | ||
+ | else if (valueType === '[object Int16Array]') { | ||
+ | marker += TYPE_INT16ARRAY; | ||
+ | } | ||
+ | else if (valueType === '[object Uint16Array]') { | ||
+ | marker += TYPE_UINT16ARRAY; | ||
+ | } | ||
+ | else if (valueType === '[object Int32Array]') { | ||
+ | marker += TYPE_INT32ARRAY; | ||
+ | } | ||
+ | else if (valueType === '[object Uint32Array]') { | ||
+ | marker += TYPE_UINT32ARRAY; | ||
+ | } | ||
+ | else if (valueType === '[object Float32Array]') { | ||
+ | marker += TYPE_FLOAT32ARRAY; | ||
+ | } | ||
+ | else if (valueType === '[object Float64Array]') { | ||
+ | marker += TYPE_FLOAT64ARRAY; | ||
+ | } | ||
+ | else { | ||
+ | callback(new Error('Failed to get type for BinaryArray')); | ||
+ | } | ||
} | } | ||
+ | callback(marker + bufferToString(buffer)); | ||
} | } | ||
− | + | else if (valueType === '[object Blob]') { | |
− | + | var fileReader = new FileReader(); | |
− | + | fileReader.onload = function () { | |
− | + | var str = BLOB_TYPE_PREFIX + value.type + '~' + bufferToString(this.result); | |
− | + | callback(SERIALIZED_MARKER + TYPE_BLOB + str); | |
− | + | }; | |
− | + | fileReader.readAsArrayBuffer(value); | |
− | + | } | |
− | + | else { | |
− | + | try { | |
− | + | callback(JSON.stringify(value)); | |
− | + | } | |
− | + | catch (e) { | |
− | + | console.error("Couldn't convert value into a JSON string: ", value); | |
− | + | callback(null, e); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | } | + | } |
} | } | ||
− | + | function deserialize(value) { | |
− | + | if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) { | |
− | + | return JSON.parse(value); | |
− | + | } | |
− | + | var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH); | |
− | + | var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH); | |
− | + | var blobType; | |
− | + | if (type === TYPE_BLOB && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) { | |
− | + | var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX); | |
− | + | blobType = matcher[1]; | |
− | + | serializedString = serializedString.substring(matcher[0].length); | |
− | + | } | |
− | + | var buffer = stringToBuffer(serializedString); | |
− | + | switch (type) { | |
− | + | case TYPE_ARRAYBUFFER: | |
− | + | return buffer; | |
− | + | case TYPE_BLOB: | |
− | + | return createBlob([buffer], { type: blobType }); | |
− | + | case TYPE_INT8ARRAY: | |
− | + | return new Int8Array(buffer); | |
− | + | case TYPE_UINT8ARRAY: | |
− | + | return new Uint8Array(buffer); | |
− | + | case TYPE_UINT8CLAMPEDARRAY: | |
− | + | return new Uint8ClampedArray(buffer); | |
− | + | case TYPE_INT16ARRAY: | |
− | + | return new Int16Array(buffer); | |
− | + | case TYPE_UINT16ARRAY: | |
− | + | return new Uint16Array(buffer); | |
− | + | case TYPE_INT32ARRAY: | |
− | + | return new Int32Array(buffer); | |
− | + | case TYPE_UINT32ARRAY: | |
− | + | return new Uint32Array(buffer); | |
− | + | case TYPE_FLOAT32ARRAY: | |
− | + | return new Float32Array(buffer); | |
− | + | case TYPE_FLOAT64ARRAY: | |
− | + | return new Float64Array(buffer); | |
− | + | default: | |
− | + | throw new Error('Unkown type: ' + type); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | var | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | var localforageSerializer = { | |
− | + | serialize: serialize, | |
− | + | deserialize: deserialize, | |
− | } | + | stringToBuffer: stringToBuffer, |
− | + | bufferToString: bufferToString | |
− | + | }; | |
− | + | function createDbTable(t, dbInfo, callback, errorCallback) { | |
− | + | t.executeSql('CREATE TABLE IF NOT EXISTS ' + dbInfo.storeName + ' ' + '(id INTEGER PRIMARY KEY, key unique, value)', [], callback, errorCallback); | |
− | + | } | |
− | + | function _initStorage$1(options) { | |
− | + | var self = this; | |
− | + | var dbInfo = { | |
− | + | db: null | |
− | + | }; | |
− | + | if (options) { | |
− | + | for (var i in options) { | |
− | + | dbInfo[i] = typeof options[i] !== 'string' ? options[i].toString() : options[i]; | |
− | + | } | |
− | + | } | |
− | + | var dbInfoPromise = new Promise$1(function (resolve, reject) { | |
− | + | try { | |
− | + | dbInfo.db = openDatabase(dbInfo.name, String(dbInfo.version), dbInfo.description, dbInfo.size); | |
− | + | } | |
− | + | catch (e) { | |
− | + | return reject(e); | |
− | + | } | |
− | + | dbInfo.db.transaction(function (t) { | |
− | + | createDbTable(t, dbInfo, function () { | |
− | + | self._dbInfo = dbInfo; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
resolve(); | resolve(); | ||
− | }, function(t, error) { | + | }, function (t, error) { |
reject(error); | reject(error); | ||
+ | }); | ||
+ | }, reject); | ||
+ | }); | ||
+ | dbInfo.serializer = localforageSerializer; | ||
+ | return dbInfoPromise; | ||
+ | } | ||
+ | function tryExecuteSql(t, dbInfo, sqlStatement, args, callback, errorCallback) { | ||
+ | t.executeSql(sqlStatement, args, callback, function (t, error) { | ||
+ | if (error.code === error.SYNTAX_ERR) { | ||
+ | t.executeSql('SELECT name FROM sqlite_master ' + "WHERE type='table' AND name = ?", [dbInfo.storeName], function (t, results) { | ||
+ | if (!results.rows.length) { | ||
+ | createDbTable(t, dbInfo, function () { | ||
+ | t.executeSql(sqlStatement, args, callback, errorCallback); | ||
+ | }, errorCallback); | ||
+ | } | ||
+ | else { | ||
+ | errorCallback(t, error); | ||
+ | } | ||
+ | }, errorCallback); | ||
+ | } | ||
+ | else { | ||
+ | errorCallback(t, error); | ||
+ | } | ||
+ | }, errorCallback); | ||
+ | } | ||
+ | function getItem$1(key, callback) { | ||
+ | var self = this; | ||
+ | key = normalizeKey(key); | ||
+ | var promise = new Promise$1(function (resolve, reject) { | ||
+ | self.ready().then(function () { | ||
+ | var dbInfo = self._dbInfo; | ||
+ | dbInfo.db.transaction(function (t) { | ||
+ | tryExecuteSql(t, dbInfo, 'SELECT * FROM ' + dbInfo.storeName + ' WHERE key = ? LIMIT 1', [key], function (t, results) { | ||
+ | var result = results.rows.length ? results.rows.item(0).value : null; | ||
+ | if (result) { | ||
+ | result = dbInfo.serializer.deserialize(result); | ||
+ | } | ||
+ | resolve(result); | ||
+ | }, function (t, error) { | ||
+ | reject(error); | ||
+ | }); | ||
+ | }); | ||
+ | })["catch"](reject); | ||
+ | }); | ||
+ | executeCallback(promise, callback); | ||
+ | return promise; | ||
+ | } | ||
+ | function iterate$1(iterator, callback) { | ||
+ | var self = this; | ||
+ | var promise = new Promise$1(function (resolve, reject) { | ||
+ | self.ready().then(function () { | ||
+ | var dbInfo = self._dbInfo; | ||
+ | dbInfo.db.transaction(function (t) { | ||
+ | tryExecuteSql(t, dbInfo, 'SELECT * FROM ' + dbInfo.storeName, [], function (t, results) { | ||
+ | var rows = results.rows; | ||
+ | var length = rows.length; | ||
+ | for (var i = 0; i < length; i++) { | ||
+ | var item = rows.item(i); | ||
+ | var result = item.value; | ||
+ | if (result) { | ||
+ | result = dbInfo.serializer.deserialize(result); | ||
+ | } | ||
+ | result = iterator(result, item.key, i + 1); | ||
+ | if (result !== void 0) { | ||
+ | resolve(result); | ||
+ | return; | ||
+ | } | ||
+ | } | ||
+ | resolve(); | ||
+ | }, function (t, error) { | ||
+ | reject(error); | ||
+ | }); | ||
+ | }); | ||
+ | })["catch"](reject); | ||
+ | }); | ||
+ | executeCallback(promise, callback); | ||
+ | return promise; | ||
+ | } | ||
+ | function _setItem(key, value, callback, retriesLeft) { | ||
+ | var self = this; | ||
+ | key = normalizeKey(key); | ||
+ | var promise = new Promise$1(function (resolve, reject) { | ||
+ | self.ready().then(function () { | ||
+ | if (value === undefined) { | ||
+ | value = null; | ||
+ | } | ||
+ | var originalValue = value; | ||
+ | var dbInfo = self._dbInfo; | ||
+ | dbInfo.serializer.serialize(value, function (value, error) { | ||
+ | if (error) { | ||
+ | reject(error); | ||
+ | } | ||
+ | else { | ||
+ | dbInfo.db.transaction(function (t) { | ||
+ | tryExecuteSql(t, dbInfo, 'INSERT OR REPLACE INTO ' + dbInfo.storeName + ' ' + '(key, value) VALUES (?, ?)', [key, value], function () { | ||
+ | resolve(originalValue); | ||
+ | }, function (t, error) { | ||
+ | reject(error); | ||
+ | }); | ||
+ | }, function (sqlError) { | ||
+ | if (sqlError.code === sqlError.QUOTA_ERR) { | ||
+ | if (retriesLeft > 0) { | ||
+ | resolve(_setItem.apply(self, [key, originalValue, callback, retriesLeft - 1])); | ||
+ | return; | ||
+ | } | ||
+ | reject(sqlError); | ||
+ | } | ||
+ | }); | ||
+ | } | ||
+ | }); | ||
+ | })["catch"](reject); | ||
+ | }); | ||
+ | executeCallback(promise, callback); | ||
+ | return promise; | ||
+ | } | ||
+ | function setItem$1(key, value, callback) { | ||
+ | return _setItem.apply(this, [key, value, callback, 1]); | ||
+ | } | ||
+ | function removeItem$1(key, callback) { | ||
+ | var self = this; | ||
+ | key = normalizeKey(key); | ||
+ | var promise = new Promise$1(function (resolve, reject) { | ||
+ | self.ready().then(function () { | ||
+ | var dbInfo = self._dbInfo; | ||
+ | dbInfo.db.transaction(function (t) { | ||
+ | tryExecuteSql(t, dbInfo, 'DELETE FROM ' + dbInfo.storeName + ' WHERE key = ?', [key], function () { | ||
+ | resolve(); | ||
+ | }, function (t, error) { | ||
+ | reject(error); | ||
+ | }); | ||
+ | }); | ||
+ | })["catch"](reject); | ||
+ | }); | ||
+ | executeCallback(promise, callback); | ||
+ | return promise; | ||
+ | } | ||
+ | function clear$1(callback) { | ||
+ | var self = this; | ||
+ | var promise = new Promise$1(function (resolve, reject) { | ||
+ | self.ready().then(function () { | ||
+ | var dbInfo = self._dbInfo; | ||
+ | dbInfo.db.transaction(function (t) { | ||
+ | tryExecuteSql(t, dbInfo, 'DELETE FROM ' + dbInfo.storeName, [], function () { | ||
+ | resolve(); | ||
+ | }, function (t, error) { | ||
+ | reject(error); | ||
+ | }); | ||
+ | }); | ||
+ | })["catch"](reject); | ||
+ | }); | ||
+ | executeCallback(promise, callback); | ||
+ | return promise; | ||
+ | } | ||
+ | function length$1(callback) { | ||
+ | var self = this; | ||
+ | var promise = new Promise$1(function (resolve, reject) { | ||
+ | self.ready().then(function () { | ||
+ | var dbInfo = self._dbInfo; | ||
+ | dbInfo.db.transaction(function (t) { | ||
+ | tryExecuteSql(t, dbInfo, 'SELECT COUNT(key) as c FROM ' + dbInfo.storeName, [], function (t, results) { | ||
+ | var result = results.rows.item(0).c; | ||
+ | resolve(result); | ||
+ | }, function (t, error) { | ||
+ | reject(error); | ||
+ | }); | ||
+ | }); | ||
+ | })["catch"](reject); | ||
+ | }); | ||
+ | executeCallback(promise, callback); | ||
+ | return promise; | ||
+ | } | ||
+ | function key$1(n, callback) { | ||
+ | var self = this; | ||
+ | var promise = new Promise$1(function (resolve, reject) { | ||
+ | self.ready().then(function () { | ||
+ | var dbInfo = self._dbInfo; | ||
+ | dbInfo.db.transaction(function (t) { | ||
+ | tryExecuteSql(t, dbInfo, 'SELECT key FROM ' + dbInfo.storeName + ' WHERE id = ? LIMIT 1', [n + 1], function (t, results) { | ||
+ | var result = results.rows.length ? results.rows.item(0).key : null; | ||
+ | resolve(result); | ||
+ | }, function (t, error) { | ||
+ | reject(error); | ||
+ | }); | ||
+ | }); | ||
+ | })["catch"](reject); | ||
+ | }); | ||
+ | executeCallback(promise, callback); | ||
+ | return promise; | ||
+ | } | ||
+ | function keys$1(callback) { | ||
+ | var self = this; | ||
+ | var promise = new Promise$1(function (resolve, reject) { | ||
+ | self.ready().then(function () { | ||
+ | var dbInfo = self._dbInfo; | ||
+ | dbInfo.db.transaction(function (t) { | ||
+ | tryExecuteSql(t, dbInfo, 'SELECT key FROM ' + dbInfo.storeName, [], function (t, results) { | ||
+ | var keys = []; | ||
+ | for (var i = 0; i < results.rows.length; i++) { | ||
+ | keys.push(results.rows.item(i).key); | ||
+ | } | ||
+ | resolve(keys); | ||
+ | }, function (t, error) { | ||
+ | reject(error); | ||
+ | }); | ||
+ | }); | ||
+ | })["catch"](reject); | ||
+ | }); | ||
+ | executeCallback(promise, callback); | ||
+ | return promise; | ||
+ | } | ||
+ | function getAllStoreNames(db) { | ||
+ | return new Promise$1(function (resolve, reject) { | ||
+ | db.transaction(function (t) { | ||
+ | t.executeSql('SELECT name FROM sqlite_master ' + "WHERE type='table' AND name <> '__WebKitDatabaseInfoTable__'", [], function (t, results) { | ||
+ | var storeNames = []; | ||
+ | for (var i = 0; i < results.rows.length; i++) { | ||
+ | storeNames.push(results.rows.item(i).name); | ||
+ | } | ||
+ | resolve({ | ||
+ | db: db, | ||
+ | storeNames: storeNames | ||
+ | }); | ||
+ | }, function (t, error) { | ||
+ | reject(error); | ||
+ | }); | ||
+ | }, function (sqlError) { | ||
+ | reject(sqlError); | ||
+ | }); | ||
+ | }); | ||
+ | } | ||
+ | function dropInstance$1(options, callback) { | ||
+ | callback = getCallback.apply(this, arguments); | ||
+ | var currentConfig = this.config(); | ||
+ | options = typeof options !== 'function' && options || {}; | ||
+ | if (!options.name) { | ||
+ | options.name = options.name || currentConfig.name; | ||
+ | options.storeName = options.storeName || currentConfig.storeName; | ||
+ | } | ||
+ | var self = this; | ||
+ | var promise; | ||
+ | if (!options.name) { | ||
+ | promise = Promise$1.reject('Invalid arguments'); | ||
+ | } | ||
+ | else { | ||
+ | promise = new Promise$1(function (resolve) { | ||
+ | var db; | ||
+ | if (options.name === currentConfig.name) { | ||
+ | db = self._dbInfo.db; | ||
+ | } | ||
+ | else { | ||
+ | db = openDatabase(options.name, '', '', 0); | ||
+ | } | ||
+ | if (!options.storeName) { | ||
+ | resolve(getAllStoreNames(db)); | ||
+ | } | ||
+ | else { | ||
+ | resolve({ | ||
+ | db: db, | ||
+ | storeNames: [options.storeName] | ||
+ | }); | ||
+ | } | ||
+ | }).then(function (operationInfo) { | ||
+ | return new Promise$1(function (resolve, reject) { | ||
+ | operationInfo.db.transaction(function (t) { | ||
+ | function dropTable(storeName) { | ||
+ | return new Promise$1(function (resolve, reject) { | ||
+ | t.executeSql('DROP TABLE IF EXISTS ' + storeName, [], function () { | ||
+ | resolve(); | ||
+ | }, function (t, error) { | ||
+ | reject(error); | ||
+ | }); | ||
+ | }); | ||
+ | } | ||
+ | var operations = []; | ||
+ | for (var i = 0, len = operationInfo.storeNames.length; i < len; i++) { | ||
+ | operations.push(dropTable(operationInfo.storeNames[i])); | ||
+ | } | ||
+ | Promise$1.all(operations).then(function () { | ||
+ | resolve(); | ||
+ | })["catch"](function (e) { | ||
+ | reject(e); | ||
+ | }); | ||
+ | }, function (sqlError) { | ||
+ | reject(sqlError); | ||
+ | }); | ||
}); | }); | ||
}); | }); | ||
} | } | ||
− | var | + | executeCallback(promise, callback); |
− | + | return promise; | |
− | + | } | |
+ | var webSQLStorage = { | ||
+ | _driver: 'webSQLStorage', | ||
+ | _initStorage: _initStorage$1, | ||
+ | _support: isWebSQLValid(), | ||
+ | iterate: iterate$1, | ||
+ | getItem: getItem$1, | ||
+ | setItem: setItem$1, | ||
+ | removeItem: removeItem$1, | ||
+ | clear: clear$1, | ||
+ | length: length$1, | ||
+ | key: key$1, | ||
+ | keys: keys$1, | ||
+ | dropInstance: dropInstance$1 | ||
+ | }; | ||
+ | function isLocalStorageValid() { | ||
+ | try { | ||
+ | return typeof localStorage !== 'undefined' && 'setItem' in localStorage && | ||
+ | !!localStorage.setItem; | ||
} | } | ||
− | + | catch (e) { | |
− | + | return false; | |
− | + | } | |
− | + | } | |
− | } | + | function _getKeyPrefix(options, defaultConfig) { |
− | } | + | var keyPrefix = options.name + '/'; |
− | + | if (options.storeName !== defaultConfig.storeName) { | |
− | + | keyPrefix += options.storeName + '/'; | |
− | + | } | |
− | + | return keyPrefix; | |
− | + | } | |
− | + | function checkIfLocalStorageThrows() { | |
− | + | var localStorageTestKey = '_localforage_support_test'; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
try { | try { | ||
− | localStorage.setItem( | + | localStorage.setItem(localStorageTestKey, true); |
− | + | localStorage.removeItem(localStorageTestKey); | |
− | } catch (e) { | + | return false; |
− | + | } | |
− | + | catch (e) { | |
− | + | return true; | |
− | + | } | |
+ | } | ||
+ | function _isLocalStorageUsable() { | ||
+ | return !checkIfLocalStorageThrows() || localStorage.length > 0; | ||
+ | } | ||
+ | function _initStorage$2(options) { | ||
+ | var self = this; | ||
+ | var dbInfo = {}; | ||
+ | if (options) { | ||
+ | for (var i in options) { | ||
+ | dbInfo[i] = options[i]; | ||
} | } | ||
− | |||
} | } | ||
+ | dbInfo.keyPrefix = _getKeyPrefix(options, self._defaultConfig); | ||
+ | if (!_isLocalStorageUsable()) { | ||
+ | return Promise$1.reject(); | ||
+ | } | ||
+ | self._dbInfo = dbInfo; | ||
+ | dbInfo.serializer = localforageSerializer; | ||
+ | return Promise$1.resolve(); | ||
} | } | ||
− | + | function clear$2(callback) { | |
− | + | var self = this; | |
− | + | var promise = self.ready().then(function () { | |
− | + | var keyPrefix = self._dbInfo.keyPrefix; | |
− | + | for (var i = localStorage.length - 1; i >= 0; i--) { | |
− | + | var key = localStorage.key(i); | |
− | + | if (key.indexOf(keyPrefix) === 0) { | |
− | + | localStorage.removeItem(key); | |
− | + | } | |
− | + | } | |
− | + | }); | |
− | + | executeCallback(promise, callback); | |
− | + | return promise; | |
− | + | } | |
− | + | function getItem$2(key, callback) { | |
− | + | var self = this; | |
− | + | key = normalizeKey(key); | |
− | + | var promise = self.ready().then(function () { | |
− | + | var dbInfo = self._dbInfo; | |
− | + | var result = localStorage.getItem(dbInfo.keyPrefix + key); | |
− | + | if (result) { | |
− | + | result = dbInfo.serializer.deserialize(result); | |
− | + | } | |
− | + | return result; | |
− | + | }); | |
− | + | executeCallback(promise, callback); | |
− | + | return promise; | |
− | + | } | |
− | + | function iterate$2(iterator, callback) { | |
− | + | var self = this; | |
+ | var promise = self.ready().then(function () { | ||
+ | var dbInfo = self._dbInfo; | ||
+ | var keyPrefix = dbInfo.keyPrefix; | ||
+ | var keyPrefixLength = keyPrefix.length; | ||
+ | var length = localStorage.length; | ||
+ | var iterationNumber = 1; | ||
+ | for (var i = 0; i < length; i++) { | ||
+ | var key = localStorage.key(i); | ||
+ | if (key.indexOf(keyPrefix) !== 0) { | ||
+ | continue; | ||
+ | } | ||
+ | var value = localStorage.getItem(key); | ||
+ | if (value) { | ||
+ | value = dbInfo.serializer.deserialize(value); | ||
+ | } | ||
+ | value = iterator(value, key.substring(keyPrefixLength), iterationNumber++); | ||
+ | if (value !== void 0) { | ||
+ | return value; | ||
+ | } | ||
+ | } | ||
+ | }); | ||
+ | executeCallback(promise, callback); | ||
+ | return promise; | ||
} | } | ||
− | + | function key$2(n, callback) { | |
− | + | var self = this; | |
− | + | var promise = self.ready().then(function () { | |
− | + | var dbInfo = self._dbInfo; | |
− | + | var result; | |
− | + | try { | |
− | + | result = localStorage.key(n); | |
− | + | } | |
− | + | catch (error) { | |
− | + | result = null; | |
− | + | } | |
− | + | if (result) { | |
− | + | result = result.substring(dbInfo.keyPrefix.length); | |
− | + | } | |
− | + | return result; | |
− | + | }); | |
− | + | executeCallback(promise, callback); | |
− | + | return promise; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | function keys$2(callback) { | |
− | + | var self = this; | |
− | + | var promise = self.ready().then(function () { | |
− | + | var dbInfo = self._dbInfo; | |
− | + | var length = localStorage.length; | |
− | + | var keys = []; | |
− | + | for (var i = 0; i < length; i++) { | |
− | + | var itemKey = localStorage.key(i); | |
− | + | if (itemKey.indexOf(dbInfo.keyPrefix) === 0) { | |
− | + | keys.push(itemKey.substring(dbInfo.keyPrefix.length)); | |
− | + | } | |
− | + | } | |
− | + | return keys; | |
− | + | }); | |
− | + | executeCallback(promise, callback); | |
− | + | return promise; | |
− | |||
− | |||
} | } | ||
− | + | function length$2(callback) { | |
− | + | var self = this; | |
− | + | var promise = self.keys().then(function (keys) { | |
− | + | return keys.length; | |
− | + | }); | |
− | + | executeCallback(promise, callback); | |
− | + | return promise; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | function removeItem$2(key, callback) { | |
− | + | var self = this; | |
+ | key = normalizeKey(key); | ||
+ | var promise = self.ready().then(function () { | ||
+ | var dbInfo = self._dbInfo; | ||
+ | localStorage.removeItem(dbInfo.keyPrefix + key); | ||
+ | }); | ||
+ | executeCallback(promise, callback); | ||
+ | return promise; | ||
} | } | ||
− | this | + | function setItem$2(key, value, callback) { |
− | + | var self = this; | |
− | + | key = normalizeKey(key); | |
− | + | var promise = self.ready().then(function () { | |
− | + | if (value === undefined) { | |
− | + | value = null; | |
− | + | } | |
− | + | var originalValue = value; | |
− | + | return new Promise$1(function (resolve, reject) { | |
− | + | var dbInfo = self._dbInfo; | |
− | + | dbInfo.serializer.serialize(value, function (value, error) { | |
− | + | if (error) { | |
− | + | reject(error); | |
− | + | } | |
− | + | else { | |
− | + | try { | |
− | + | localStorage.setItem(dbInfo.keyPrefix + key, value); | |
− | + | resolve(originalValue); | |
− | + | } | |
− | + | catch (e) { | |
− | + | if (e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') { | |
− | + | reject(e); | |
− | + | } | |
− | + | reject(e); | |
− | + | } | |
− | return; | + | } |
+ | }); | ||
+ | }); | ||
+ | }); | ||
+ | executeCallback(promise, callback); | ||
+ | return promise; | ||
} | } | ||
− | + | function dropInstance$2(options, callback) { | |
− | + | callback = getCallback.apply(this, arguments); | |
− | var | + | options = typeof options !== 'function' && options || {}; |
− | + | if (!options.name) { | |
− | + | var currentConfig = this.config(); | |
− | + | options.name = options.name || currentConfig.name; | |
− | + | options.storeName = options.storeName || currentConfig.storeName; | |
− | + | } | |
− | + | var self = this; | |
+ | var promise; | ||
+ | if (!options.name) { | ||
+ | promise = Promise$1.reject('Invalid arguments'); | ||
+ | } | ||
+ | else { | ||
+ | promise = new Promise$1(function (resolve) { | ||
+ | if (!options.storeName) { | ||
+ | resolve(options.name + '/'); | ||
+ | } | ||
+ | else { | ||
+ | resolve(_getKeyPrefix(options, self._defaultConfig)); | ||
+ | } | ||
+ | }).then(function (keyPrefix) { | ||
+ | for (var i = localStorage.length - 1; i >= 0; i--) { | ||
+ | var key = localStorage.key(i); | ||
+ | if (key.indexOf(keyPrefix) === 0) { | ||
+ | localStorage.removeItem(key); | ||
+ | } | ||
+ | } | ||
+ | }); | ||
} | } | ||
+ | executeCallback(promise, callback); | ||
+ | return promise; | ||
} | } | ||
− | var | + | var localStorageWrapper = { |
− | var | + | _driver: 'localStorageWrapper', |
− | + | _initStorage: _initStorage$2, | |
− | + | _support: isLocalStorageValid(), | |
− | + | iterate: iterate$2, | |
− | + | getItem: getItem$2, | |
− | + | setItem: setItem$2, | |
− | + | removeItem: removeItem$2, | |
− | + | clear: clear$2, | |
− | + | length: length$2, | |
− | + | key: key$2, | |
− | if ( | + | keys: keys$2, |
− | + | dropInstance: dropInstance$2 | |
+ | }; | ||
+ | var sameValue = function sameValue(x, y) { | ||
+ | return x === y || typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y); | ||
+ | }; | ||
+ | var includes = function includes(array, searchElement) { | ||
+ | var len = array.length; | ||
+ | var i = 0; | ||
+ | while (i < len) { | ||
+ | if (sameValue(array[i], searchElement)) { | ||
+ | return true; | ||
} | } | ||
+ | i++; | ||
} | } | ||
+ | return false; | ||
}; | }; | ||
− | + | var isArray = Array.isArray || function (arg) { | |
− | var | + | return Object.prototype.toString.call(arg) === '[object Array]'; |
− | + | }; | |
− | + | var DefinedDrivers = {}; | |
− | } | + | var DriverSupport = {}; |
− | + | var DefaultDrivers = { | |
− | + | INDEXEDDB: asyncStorage, | |
− | + | WEBSQL: webSQLStorage, | |
− | + | LOCALSTORAGE: localStorageWrapper | |
− | + | }; | |
− | + | var DefaultDriverOrder = [DefaultDrivers.INDEXEDDB._driver, DefaultDrivers.WEBSQL._driver, DefaultDrivers.LOCALSTORAGE._driver]; | |
+ | var OptionalDriverMethods = ['dropInstance']; | ||
+ | var LibraryMethods = ['clear', 'getItem', 'iterate', 'key', 'keys', 'length', 'removeItem', 'setItem'].concat(OptionalDriverMethods); | ||
+ | var DefaultConfig = { | ||
+ | description: '', | ||
+ | driver: DefaultDriverOrder.slice(), | ||
+ | name: 'localforage', | ||
+ | size: 4980736, | ||
+ | storeName: 'keyvaluepairs', | ||
+ | version: 1.0 | ||
}; | }; | ||
− | + | function callWhenReady(localForageInstance, libraryMethod) { | |
− | + | localForageInstance[libraryMethod] = function () { | |
− | + | var _args = arguments; | |
− | } | + | return localForageInstance.ready().then(function () { |
− | + | return localForageInstance[libraryMethod].apply(localForageInstance, _args); | |
+ | }); | ||
+ | }; | ||
+ | } | ||
+ | function extend() { | ||
+ | for (var i = 1; i < arguments.length; i++) { | ||
+ | var arg = arguments[i]; | ||
+ | if (arg) { | ||
+ | for (var _key in arg) { | ||
+ | if (arg.hasOwnProperty(_key)) { | ||
+ | if (isArray(arg[_key])) { | ||
+ | arguments[0][_key] = arg[_key].slice(); | ||
+ | } | ||
+ | else { | ||
+ | arguments[0][_key] = arg[_key]; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
} | } | ||
− | + | return arguments[0]; | |
− | |||
} | } | ||
− | + | var LocalForage = function () { | |
− | + | function LocalForage(options) { | |
− | + | _classCallCheck(this, LocalForage); | |
− | + | for (var driverTypeKey in DefaultDrivers) { | |
− | + | if (DefaultDrivers.hasOwnProperty(driverTypeKey)) { | |
− | + | var driver = DefaultDrivers[driverTypeKey]; | |
− | + | var driverName = driver._driver; | |
− | + | this[driverTypeKey] = driverName; | |
− | + | if (!DefinedDrivers[driverName]) { | |
− | + | this.defineDriver(driver); | |
− | + | } | |
− | + | } | |
− | + | } | |
− | + | this._defaultConfig = extend({}, DefaultConfig); | |
− | + | this._config = extend({}, this._defaultConfig, options); | |
− | + | this._driverSet = null; | |
− | + | this._initDriver = null; | |
− | + | this._ready = false; | |
− | + | this._dbInfo = null; | |
− | + | this._wrapLibraryMethodsWithReady(); | |
− | + | this.setDriver(this._config.driver)["catch"](function () { }); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | LocalForage.prototype.config = function config(options) { | |
− | var error = new Error("No available storage method found. | + | if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') { |
− | + | if (this._ready) { | |
− | + | return new Error("Can't call config() after localforage " + 'has been used.'); | |
− | + | } | |
− | + | for (var i in options) { | |
− | + | if (i === 'storeName') { | |
− | + | options[i] = options[i].replace(/\W/g, '_'); | |
− | + | } | |
− | + | if (i === 'version' && typeof options[i] !== 'number') { | |
− | + | return new Error('Database version must be a number.'); | |
− | + | } | |
− | + | this._config[i] = options[i]; | |
− | + | } | |
− | + | if ('driver' in options && options.driver) { | |
− | + | return this.setDriver(this._config.driver); | |
− | + | } | |
− | + | return true; | |
− | + | } | |
− | + | else if (typeof options === 'string') { | |
− | + | return this._config[options]; | |
− | + | } | |
− | + | else { | |
− | + | return this._config; | |
− | + | } | |
− | + | }; | |
− | + | LocalForage.prototype.defineDriver = function defineDriver(driverObject, callback, errorCallback) { | |
− | + | var promise = new Promise$1(function (resolve, reject) { | |
− | + | try { | |
− | + | var driverName = driverObject._driver; | |
− | + | var complianceError = new Error('Custom driver not compliant; see ' + 'https://mozilla.github.io/localForage/#definedriver'); | |
− | + | if (!driverObject._driver) { | |
− | + | reject(complianceError); | |
− | + | return; | |
− | + | } | |
− | + | var driverMethods = LibraryMethods.concat('_initStorage'); | |
− | + | for (var i = 0, len = driverMethods.length; i < len; i++) { | |
− | + | var driverMethodName = driverMethods[i]; | |
− | + | var isRequired = !includes(OptionalDriverMethods, driverMethodName); | |
− | + | if ((isRequired || driverObject[driverMethodName]) && typeof driverObject[driverMethodName] !== 'function') { | |
− | + | reject(complianceError); | |
− | + | return; | |
− | + | } | |
− | + | } | |
− | + | var configureMissingMethods = function configureMissingMethods() { | |
− | + | var methodNotImplementedFactory = function methodNotImplementedFactory(methodName) { | |
− | + | return function () { | |
− | + | var error = new Error('Method ' + methodName + ' is not implemented by the current driver'); | |
− | + | var promise = Promise$1.reject(error); | |
− | + | executeCallback(promise, arguments[arguments.length - 1]); | |
− | + | return promise; | |
− | + | }; | |
− | + | }; | |
− | + | for (var _i = 0, _len = OptionalDriverMethods.length; _i < _len; _i++) { | |
− | + | var optionalDriverMethod = OptionalDriverMethods[_i]; | |
− | + | if (!driverObject[optionalDriverMethod]) { | |
− | + | driverObject[optionalDriverMethod] = methodNotImplementedFactory(optionalDriverMethod); | |
− | + | } | |
− | + | } | |
− | + | }; | |
− | + | configureMissingMethods(); | |
− | + | var setDriverSupport = function setDriverSupport(support) { | |
− | + | if (DefinedDrivers[driverName]) { | |
− | + | console.info('Redefining LocalForage driver: ' + driverName); | |
− | + | } | |
− | + | DefinedDrivers[driverName] = driverObject; | |
− | + | DriverSupport[driverName] = support; | |
− | + | resolve(); | |
− | + | }; | |
− | } | + | if ('_support' in driverObject) { |
− | }, {} | + | if (driverObject._support && typeof driverObject._support === 'function') { |
− | }); | + | driverObject._support().then(setDriverSupport, reject); |
+ | } | ||
+ | else { | ||
+ | setDriverSupport(!!driverObject._support); | ||
+ | } | ||
+ | } | ||
+ | else { | ||
+ | setDriverSupport(true); | ||
+ | } | ||
+ | } | ||
+ | catch (e) { | ||
+ | reject(e); | ||
+ | } | ||
+ | }); | ||
+ | executeTwoCallbacks(promise, callback, errorCallback); | ||
+ | return promise; | ||
+ | }; | ||
+ | LocalForage.prototype.driver = function driver() { | ||
+ | return this._driver || null; | ||
+ | }; | ||
+ | LocalForage.prototype.getDriver = function getDriver(driverName, callback, errorCallback) { | ||
+ | var getDriverPromise = DefinedDrivers[driverName] ? Promise$1.resolve(DefinedDrivers[driverName]) : Promise$1.reject(new Error('Driver not found.')); | ||
+ | executeTwoCallbacks(getDriverPromise, callback, errorCallback); | ||
+ | return getDriverPromise; | ||
+ | }; | ||
+ | LocalForage.prototype.getSerializer = function getSerializer(callback) { | ||
+ | var serializerPromise = Promise$1.resolve(localforageSerializer); | ||
+ | executeTwoCallbacks(serializerPromise, callback); | ||
+ | return serializerPromise; | ||
+ | }; | ||
+ | LocalForage.prototype.ready = function ready(callback) { | ||
+ | var self = this; | ||
+ | var promise = self._driverSet.then(function () { | ||
+ | if (self._ready === null) { | ||
+ | self._ready = self._initDriver(); | ||
+ | } | ||
+ | return self._ready; | ||
+ | }); | ||
+ | executeTwoCallbacks(promise, callback, callback); | ||
+ | return promise; | ||
+ | }; | ||
+ | LocalForage.prototype.setDriver = function setDriver(drivers, callback, errorCallback) { | ||
+ | var self = this; | ||
+ | if (!isArray(drivers)) { | ||
+ | drivers = [drivers]; | ||
+ | } | ||
+ | var supportedDrivers = this._getSupportedDrivers(drivers); | ||
+ | function setDriverToConfig() { | ||
+ | self._config.driver = self.driver(); | ||
+ | } | ||
+ | function extendSelfWithDriver(driver) { | ||
+ | self._extend(driver); | ||
+ | setDriverToConfig(); | ||
+ | self._ready = self._initStorage(self._config); | ||
+ | return self._ready; | ||
+ | } | ||
+ | function initDriver(supportedDrivers) { | ||
+ | return function () { | ||
+ | var currentDriverIndex = 0; | ||
+ | function driverPromiseLoop() { | ||
+ | while (currentDriverIndex < supportedDrivers.length) { | ||
+ | var driverName = supportedDrivers[currentDriverIndex]; | ||
+ | currentDriverIndex++; | ||
+ | self._dbInfo = null; | ||
+ | self._ready = null; | ||
+ | return self.getDriver(driverName).then(extendSelfWithDriver)["catch"](driverPromiseLoop); | ||
+ | } | ||
+ | setDriverToConfig(); | ||
+ | var error = new Error('No available storage method found.'); | ||
+ | self._driverSet = Promise$1.reject(error); | ||
+ | return self._driverSet; | ||
+ | } | ||
+ | return driverPromiseLoop(); | ||
+ | }; | ||
+ | } | ||
+ | var oldDriverSetDone = this._driverSet !== null ? this._driverSet["catch"](function () { | ||
+ | return Promise$1.resolve(); | ||
+ | }) : Promise$1.resolve(); | ||
+ | this._driverSet = oldDriverSetDone.then(function () { | ||
+ | var driverName = supportedDrivers[0]; | ||
+ | self._dbInfo = null; | ||
+ | self._ready = null; | ||
+ | return self.getDriver(driverName).then(function (driver) { | ||
+ | self._driver = driver._driver; | ||
+ | setDriverToConfig(); | ||
+ | self._wrapLibraryMethodsWithReady(); | ||
+ | self._initDriver = initDriver(supportedDrivers); | ||
+ | }); | ||
+ | })["catch"](function () { | ||
+ | setDriverToConfig(); | ||
+ | var error = new Error('No available storage method found.'); | ||
+ | self._driverSet = Promise$1.reject(error); | ||
+ | return self._driverSet; | ||
+ | }); | ||
+ | executeTwoCallbacks(this._driverSet, callback, errorCallback); | ||
+ | return this._driverSet; | ||
+ | }; | ||
+ | LocalForage.prototype.supports = function supports(driverName) { | ||
+ | return !!DriverSupport[driverName]; | ||
+ | }; | ||
+ | LocalForage.prototype._extend = function _extend(libraryMethodsAndProperties) { | ||
+ | extend(this, libraryMethodsAndProperties); | ||
+ | }; | ||
+ | LocalForage.prototype._getSupportedDrivers = function _getSupportedDrivers(drivers) { | ||
+ | var supportedDrivers = []; | ||
+ | for (var i = 0, len = drivers.length; i < len; i++) { | ||
+ | var driverName = drivers[i]; | ||
+ | if (this.supports(driverName)) { | ||
+ | supportedDrivers.push(driverName); | ||
+ | } | ||
+ | } | ||
+ | return supportedDrivers; | ||
+ | }; | ||
+ | LocalForage.prototype._wrapLibraryMethodsWithReady = function _wrapLibraryMethodsWithReady() { | ||
+ | for (var i = 0, len = LibraryMethods.length; i < len; i++) { | ||
+ | callWhenReady(this, LibraryMethods[i]); | ||
+ | } | ||
+ | }; | ||
+ | LocalForage.prototype.createInstance = function createInstance(options) { | ||
+ | return new LocalForage(options); | ||
+ | }; | ||
+ | return LocalForage; | ||
+ | }(); | ||
+ | var localforage_js = new LocalForage(); | ||
+ | module.exports = localforage_js; | ||
+ | }, { "3": 3 }] }, {}, [4])(4); | ||
+ | }); | ||
+ | }).call(this); | ||
+ | }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}); | ||
+ | _$localforage_1 = _$localforage_1.exports; | ||
+ | var _$input_2 = {}; | ||
+ | (function (global) { | ||
+ | (function () { | ||
+ | "use strict"; | ||
+ | var _localforage = _interopRequireDefault(_$localforage_1); | ||
+ | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
+ | global["localforage"] = _localforage["default"]; | ||
+ | }).call(this); | ||
+ | }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}); | ||
+ | }()); | ||
+ | |||
+ | /* </pre> */ |
2022年9月6日 (二) 01:53的最新版本
/* <pre> */ /** * ------------------------------------------------------------------------- * !!! DON'T MODIFY THIS PAGE MANUALLY, YOUR CHANGES WILL BE OVERWRITTEN !!! * ------------------------------------------------------------------------- */ var _addText = '{{GHIACode|page=GHIA:MoegirlPediaInterfaceCodes/blob/master/src/gadgets/localforage/MediaWiki:Gadget-localforage.js|user=[[U:AnnAngela]]|longId=3820b56ff2ac6eb2e6bb95dd82dd71db679b0c81|shortId=3820b56|message=auto: auto browserify - commit from GitHub Actions}}'; "use strict"; (function () { var _$localforage_1 = { exports: {} }; (function (global) { (function () { (function (f) { if (typeof _$localforage_1.exports === "object" && "object" !== "undefined") { _$localforage_1.exports = f(); } else if (typeof define === "function" && define.amd) { define([], f); } else { var g; if (typeof window !== "undefined") { g = window; } else if (typeof global !== "undefined") { g = global; } else if (typeof self !== "undefined") { g = self; } else { g = this; } g.localforage = f(); } })(function () { var define, module, exports; return (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { var a = "function" == "function" && require; if (!u && a) return a(o, !0); if (i) return i(o, !0); var f = new Error("Cannot find module '" + o + "'"); throw (f.code = "MODULE_NOT_FOUND", f); } var l = n[o] = { exports: {} }; t[o][0].call(l.exports, function (e) { var n = t[o][1][e]; return s(n ? n : e); }, l, l.exports, e, t, n, r); } return n[o].exports; } var i = "function" == "function" && require; for (var o = 0; o < r.length; o++) s(r[o]); return s; })({ 1: [function (_dereq_, module, exports) { (function (global) { 'use strict'; var Mutation = global.MutationObserver || global.WebKitMutationObserver; var scheduleDrain; { if (Mutation) { var called = 0; var observer = new Mutation(nextTick); var element = global.document.createTextNode(''); observer.observe(element, { characterData: true }); scheduleDrain = function () { element.data = (called = ++called % 2); }; } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') { var channel = new global.MessageChannel(); channel.port1.onmessage = nextTick; scheduleDrain = function () { channel.port2.postMessage(0); }; } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) { scheduleDrain = function () { var scriptEl = global.document.createElement('script'); scriptEl.onreadystatechange = function () { nextTick(); scriptEl.onreadystatechange = null; scriptEl.parentNode.removeChild(scriptEl); scriptEl = null; }; global.document.documentElement.appendChild(scriptEl); }; } else { scheduleDrain = function () { setTimeout(nextTick, 0); }; } } var draining; var queue = []; function nextTick() { draining = true; var i, oldQueue; var len = queue.length; while (len) { oldQueue = queue; queue = []; i = -1; while (++i < len) { oldQueue[i](); } len = queue.length; } draining = false; } module.exports = immediate; function immediate(task) { if (queue.push(task) === 1 && !draining) { scheduleDrain(); } } }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}); }, {}], 2: [function (_dereq_, module, exports) { 'use strict'; var immediate = _dereq_(1); function INTERNAL() { } var handlers = {}; var REJECTED = ['REJECTED']; var FULFILLED = ['FULFILLED']; var PENDING = ['PENDING']; module.exports = Promise; function Promise(resolver) { if (typeof resolver !== 'function') { throw new TypeError('resolver must be a function'); } this.state = PENDING; this.queue = []; this.outcome = void 0; if (resolver !== INTERNAL) { safelyResolveThenable(this, resolver); } } Promise.prototype["catch"] = function (onRejected) { return this.then(null, onRejected); }; Promise.prototype.then = function (onFulfilled, onRejected) { if (typeof onFulfilled !== 'function' && this.state === FULFILLED || typeof onRejected !== 'function' && this.state === REJECTED) { return this; } var promise = new this.constructor(INTERNAL); if (this.state !== PENDING) { var resolver = this.state === FULFILLED ? onFulfilled : onRejected; unwrap(promise, resolver, this.outcome); } else { this.queue.push(new QueueItem(promise, onFulfilled, onRejected)); } return promise; }; function QueueItem(promise, onFulfilled, onRejected) { this.promise = promise; if (typeof onFulfilled === 'function') { this.onFulfilled = onFulfilled; this.callFulfilled = this.otherCallFulfilled; } if (typeof onRejected === 'function') { this.onRejected = onRejected; this.callRejected = this.otherCallRejected; } } QueueItem.prototype.callFulfilled = function (value) { handlers.resolve(this.promise, value); }; QueueItem.prototype.otherCallFulfilled = function (value) { unwrap(this.promise, this.onFulfilled, value); }; QueueItem.prototype.callRejected = function (value) { handlers.reject(this.promise, value); }; QueueItem.prototype.otherCallRejected = function (value) { unwrap(this.promise, this.onRejected, value); }; function unwrap(promise, func, value) { immediate(function () { var returnValue; try { returnValue = func(value); } catch (e) { return handlers.reject(promise, e); } if (returnValue === promise) { handlers.reject(promise, new TypeError('Cannot resolve promise with itself')); } else { handlers.resolve(promise, returnValue); } }); } handlers.resolve = function (self, value) { var result = tryCatch(getThen, value); if (result.status === 'error') { return handlers.reject(self, result.value); } var thenable = result.value; if (thenable) { safelyResolveThenable(self, thenable); } else { self.state = FULFILLED; self.outcome = value; var i = -1; var len = self.queue.length; while (++i < len) { self.queue[i].callFulfilled(value); } } return self; }; handlers.reject = function (self, error) { self.state = REJECTED; self.outcome = error; var i = -1; var len = self.queue.length; while (++i < len) { self.queue[i].callRejected(error); } return self; }; function getThen(obj) { var then = obj && obj.then; if (obj && (typeof obj === 'object' || typeof obj === 'function') && typeof then === 'function') { return function appyThen() { then.apply(obj, arguments); }; } } function safelyResolveThenable(self, thenable) { var called = false; function onError(value) { if (called) { return; } called = true; handlers.reject(self, value); } function onSuccess(value) { if (called) { return; } called = true; handlers.resolve(self, value); } function tryToUnwrap() { thenable(onSuccess, onError); } var result = tryCatch(tryToUnwrap); if (result.status === 'error') { onError(result.value); } } function tryCatch(func, value) { var out = {}; try { out.value = func(value); out.status = 'success'; } catch (e) { out.status = 'error'; out.value = e; } return out; } Promise.resolve = resolve; function resolve(value) { if (value instanceof this) { return value; } return handlers.resolve(new this(INTERNAL), value); } Promise.reject = reject; function reject(reason) { var promise = new this(INTERNAL); return handlers.reject(promise, reason); } Promise.all = all; function all(iterable) { var self = this; if (Object.prototype.toString.call(iterable) !== '[object Array]') { return this.reject(new TypeError('must be an array')); } var len = iterable.length; var called = false; if (!len) { return this.resolve([]); } var values = new Array(len); var resolved = 0; var i = -1; var promise = new this(INTERNAL); while (++i < len) { allResolver(iterable[i], i); } return promise; function allResolver(value, i) { self.resolve(value).then(resolveFromAll, function (error) { if (!called) { called = true; handlers.reject(promise, error); } }); function resolveFromAll(outValue) { values[i] = outValue; if (++resolved === len && !called) { called = true; handlers.resolve(promise, values); } } } } Promise.race = race; function race(iterable) { var self = this; if (Object.prototype.toString.call(iterable) !== '[object Array]') { return this.reject(new TypeError('must be an array')); } var len = iterable.length; var called = false; if (!len) { return this.resolve([]); } var i = -1; var promise = new this(INTERNAL); while (++i < len) { resolver(iterable[i]); } return promise; function resolver(value) { self.resolve(value).then(function (response) { if (!called) { called = true; handlers.resolve(promise, response); } }, function (error) { if (!called) { called = true; handlers.reject(promise, error); } }); } } }, { "1": 1 }], 3: [function (_dereq_, module, exports) { (function (global) { 'use strict'; if (typeof global.Promise !== 'function') { global.Promise = _dereq_(2); } }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}); }, { "2": 2 }], 4: [function (_dereq_, module, exports) { 'use strict'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function getIDB() { 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; } } catch (e) { return; } } var idb = getIDB(); function isIndexedDBValid() { try { if (!idb || !idb.open) { return false; } var isSafari = typeof openDatabase !== 'undefined' && /(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent) && !/BlackBerry/.test(navigator.platform); var hasFetch = typeof fetch === 'function' && fetch.toString().indexOf('[native code') !== -1; return (!isSafari || hasFetch) && typeof indexedDB !== 'undefined' && typeof IDBKeyRange !== 'undefined'; } catch (e) { return false; } } function createBlob(parts, properties) { parts = parts || []; properties = properties || {}; try { return new Blob(parts, properties); } catch (e) { if (e.name !== 'TypeError') { throw e; } var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : WebKitBlobBuilder; var builder = new Builder(); for (var i = 0; i < parts.length; i += 1) { builder.append(parts[i]); } return builder.getBlob(properties.type); } } if (typeof Promise === 'undefined') { _dereq_(3); } var Promise$1 = Promise; function executeCallback(promise, callback) { if (callback) { promise.then(function (result) { callback(null, result); }, function (error) { callback(error); }); } } function executeTwoCallbacks(promise, callback, errorCallback) { if (typeof callback === 'function') { promise.then(callback); } if (typeof errorCallback === 'function') { promise["catch"](errorCallback); } } function normalizeKey(key) { if (typeof key !== 'string') { console.warn(key + ' used as a key, but it is not a string.'); key = String(key); } return key; } function getCallback() { if (arguments.length && typeof arguments[arguments.length - 1] === 'function') { return arguments[arguments.length - 1]; } } var DETECT_BLOB_SUPPORT_STORE = 'local-forage-detect-blob-support'; var supportsBlobs = void 0; var dbContexts = {}; var toString = Object.prototype.toString; var READ_ONLY = 'readonly'; var READ_WRITE = 'readwrite'; function _binStringToArrayBuffer(bin) { var length = bin.length; var buf = new ArrayBuffer(length); var arr = new Uint8Array(buf); for (var i = 0; i < length; i++) { arr[i] = bin.charCodeAt(i); } return buf; } function _checkBlobSupportWithoutCaching(idb) { return new Promise$1(function (resolve) { var txn = idb.transaction(DETECT_BLOB_SUPPORT_STORE, READ_WRITE); var blob = createBlob(['']); txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob, 'key'); txn.onabort = function (e) { e.preventDefault(); e.stopPropagation(); resolve(false); }; txn.oncomplete = function () { var matchedChrome = navigator.userAgent.match(/Chrome\/(\d+)/); var matchedEdge = navigator.userAgent.match(/Edge\//); resolve(matchedEdge || !matchedChrome || parseInt(matchedChrome[1], 10) >= 43); }; })["catch"](function () { return false; }); } function _checkBlobSupport(idb) { if (typeof supportsBlobs === 'boolean') { return Promise$1.resolve(supportsBlobs); } return _checkBlobSupportWithoutCaching(idb).then(function (value) { supportsBlobs = value; return supportsBlobs; }); } function _deferReadiness(dbInfo) { var dbContext = dbContexts[dbInfo.name]; var deferredOperation = {}; deferredOperation.promise = new Promise$1(function (resolve, reject) { deferredOperation.resolve = resolve; deferredOperation.reject = reject; }); dbContext.deferredOperations.push(deferredOperation); if (!dbContext.dbReady) { dbContext.dbReady = deferredOperation.promise; } else { dbContext.dbReady = dbContext.dbReady.then(function () { return deferredOperation.promise; }); } } function _advanceReadiness(dbInfo) { var dbContext = dbContexts[dbInfo.name]; var deferredOperation = dbContext.deferredOperations.pop(); if (deferredOperation) { deferredOperation.resolve(); return deferredOperation.promise; } } function _rejectReadiness(dbInfo, err) { var dbContext = dbContexts[dbInfo.name]; var deferredOperation = dbContext.deferredOperations.pop(); if (deferredOperation) { deferredOperation.reject(err); return deferredOperation.promise; } } function _getConnection(dbInfo, upgradeNeeded) { return new Promise$1(function (resolve, reject) { dbContexts[dbInfo.name] = dbContexts[dbInfo.name] || createDbContext(); if (dbInfo.db) { if (upgradeNeeded) { _deferReadiness(dbInfo); dbInfo.db.close(); } else { return resolve(dbInfo.db); } } var dbArgs = [dbInfo.name]; if (upgradeNeeded) { dbArgs.push(dbInfo.version); } var openreq = idb.open.apply(idb, dbArgs); if (upgradeNeeded) { openreq.onupgradeneeded = function (e) { var db = openreq.result; try { db.createObjectStore(dbInfo.storeName); if (e.oldVersion <= 1) { db.createObjectStore(DETECT_BLOB_SUPPORT_STORE); } } catch (ex) { if (ex.name === 'ConstraintError') { console.warn('The database "' + dbInfo.name + '"' + ' has been upgraded from version ' + e.oldVersion + ' to version ' + e.newVersion + ', but the storage "' + dbInfo.storeName + '" already exists.'); } else { throw ex; } } }; } openreq.onerror = function (e) { e.preventDefault(); reject(openreq.error); }; openreq.onsuccess = function () { var db = openreq.result; db.onversionchange = function (e) { e.target.close(); }; resolve(db); _advanceReadiness(dbInfo); }; }); } function _getOriginalConnection(dbInfo) { return _getConnection(dbInfo, false); } function _getUpgradedConnection(dbInfo) { return _getConnection(dbInfo, true); } function _isUpgradeNeeded(dbInfo, defaultVersion) { if (!dbInfo.db) { return true; } var isNewStore = !dbInfo.db.objectStoreNames.contains(dbInfo.storeName); var isDowngrade = dbInfo.version < dbInfo.db.version; var isUpgrade = dbInfo.version > dbInfo.db.version; if (isDowngrade) { if (dbInfo.version !== defaultVersion) { console.warn('The database "' + dbInfo.name + '"' + " can't be downgraded from version " + dbInfo.db.version + ' to version ' + dbInfo.version + '.'); } dbInfo.version = dbInfo.db.version; } if (isUpgrade || isNewStore) { if (isNewStore) { var incVersion = dbInfo.db.version + 1; if (incVersion > dbInfo.version) { dbInfo.version = incVersion; } } return true; } return false; } function _encodeBlob(blob) { return new Promise$1(function (resolve, reject) { var reader = new FileReader(); reader.onerror = reject; reader.onloadend = function (e) { var base64 = btoa(e.target.result || ''); resolve({ __local_forage_encoded_blob: true, data: base64, type: blob.type }); }; reader.readAsBinaryString(blob); }); } function _decodeBlob(encodedBlob) { var arrayBuff = _binStringToArrayBuffer(atob(encodedBlob.data)); return createBlob([arrayBuff], { type: encodedBlob.type }); } function _isEncodedBlob(value) { return value && value.__local_forage_encoded_blob; } function _fullyReady(callback) { var self = this; var promise = self._initReady().then(function () { var dbContext = dbContexts[self._dbInfo.name]; if (dbContext && dbContext.dbReady) { return dbContext.dbReady; } }); executeTwoCallbacks(promise, callback, callback); return promise; } function _tryReconnect(dbInfo) { _deferReadiness(dbInfo); var dbContext = dbContexts[dbInfo.name]; var forages = dbContext.forages; for (var i = 0; i < forages.length; i++) { var forage = forages[i]; if (forage._dbInfo.db) { forage._dbInfo.db.close(); forage._dbInfo.db = null; } } dbInfo.db = null; return _getOriginalConnection(dbInfo).then(function (db) { dbInfo.db = db; if (_isUpgradeNeeded(dbInfo)) { return _getUpgradedConnection(dbInfo); } return db; }).then(function (db) { dbInfo.db = dbContext.db = db; for (var i = 0; i < forages.length; i++) { forages[i]._dbInfo.db = db; } })["catch"](function (err) { _rejectReadiness(dbInfo, err); throw err; }); } function createTransaction(dbInfo, mode, callback, retries) { if (retries === undefined) { retries = 1; } try { var tx = dbInfo.db.transaction(dbInfo.storeName, mode); callback(null, tx); } catch (err) { if (retries > 0 && (!dbInfo.db || err.name === 'InvalidStateError' || err.name === 'NotFoundError')) { return Promise$1.resolve().then(function () { if (!dbInfo.db || err.name === 'NotFoundError' && !dbInfo.db.objectStoreNames.contains(dbInfo.storeName) && dbInfo.version <= dbInfo.db.version) { if (dbInfo.db) { dbInfo.version = dbInfo.db.version + 1; } return _getUpgradedConnection(dbInfo); } }).then(function () { return _tryReconnect(dbInfo).then(function () { createTransaction(dbInfo, mode, callback, retries - 1); }); })["catch"](callback); } callback(err); } } function createDbContext() { return { forages: [], db: null, dbReady: null, deferredOperations: [] }; } function _initStorage(options) { var self = this; var dbInfo = { db: null }; if (options) { for (var i in options) { dbInfo[i] = options[i]; } } var dbContext = dbContexts[dbInfo.name]; if (!dbContext) { dbContext = createDbContext(); dbContexts[dbInfo.name] = dbContext; } dbContext.forages.push(self); if (!self._initReady) { self._initReady = self.ready; self.ready = _fullyReady; } var initPromises = []; function ignoreErrors() { return Promise$1.resolve(); } for (var j = 0; j < dbContext.forages.length; j++) { var forage = dbContext.forages[j]; if (forage !== self) { initPromises.push(forage._initReady()["catch"](ignoreErrors)); } } var forages = dbContext.forages.slice(0); return Promise$1.all(initPromises).then(function () { dbInfo.db = dbContext.db; return _getOriginalConnection(dbInfo); }).then(function (db) { dbInfo.db = db; if (_isUpgradeNeeded(dbInfo, self._defaultConfig.version)) { return _getUpgradedConnection(dbInfo); } return db; }).then(function (db) { dbInfo.db = dbContext.db = db; self._dbInfo = dbInfo; for (var k = 0; k < forages.length; k++) { var forage = forages[k]; if (forage !== self) { forage._dbInfo.db = dbInfo.db; forage._dbInfo.version = dbInfo.version; } } }); } function getItem(key, callback) { var self = this; key = normalizeKey(key); var promise = new Promise$1(function (resolve, reject) { self.ready().then(function () { createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) { if (err) { return reject(err); } try { var store = transaction.objectStore(self._dbInfo.storeName); var req = store.get(key); req.onsuccess = function () { var value = req.result; if (value === undefined) { value = null; } if (_isEncodedBlob(value)) { value = _decodeBlob(value); } resolve(value); }; req.onerror = function () { reject(req.error); }; } catch (e) { reject(e); } }); })["catch"](reject); }); executeCallback(promise, callback); return promise; } function iterate(iterator, callback) { var self = this; var promise = new Promise$1(function (resolve, reject) { self.ready().then(function () { createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) { if (err) { return reject(err); } try { var store = transaction.objectStore(self._dbInfo.storeName); var req = store.openCursor(); var iterationNumber = 1; req.onsuccess = function () { var cursor = req.result; if (cursor) { var value = cursor.value; if (_isEncodedBlob(value)) { value = _decodeBlob(value); } var result = iterator(value, cursor.key, iterationNumber++); if (result !== void 0) { resolve(result); } else { cursor["continue"](); } } else { resolve(); } }; req.onerror = function () { reject(req.error); }; } catch (e) { reject(e); } }); })["catch"](reject); }); executeCallback(promise, callback); return promise; } function setItem(key, value, callback) { var self = this; key = normalizeKey(key); var promise = new Promise$1(function (resolve, reject) { var dbInfo; self.ready().then(function () { dbInfo = self._dbInfo; if (toString.call(value) === '[object Blob]') { return _checkBlobSupport(dbInfo.db).then(function (blobSupport) { if (blobSupport) { return value; } return _encodeBlob(value); }); } return value; }).then(function (value) { createTransaction(self._dbInfo, READ_WRITE, function (err, transaction) { if (err) { return reject(err); } try { var store = transaction.objectStore(self._dbInfo.storeName); if (value === null) { value = undefined; } var req = store.put(value, key); transaction.oncomplete = function () { if (value === undefined) { value = null; } resolve(value); }; transaction.onabort = transaction.onerror = function () { var err = req.error ? req.error : req.transaction.error; reject(err); }; } catch (e) { reject(e); } }); })["catch"](reject); }); executeCallback(promise, callback); return promise; } function removeItem(key, callback) { var self = this; key = normalizeKey(key); var promise = new Promise$1(function (resolve, reject) { self.ready().then(function () { createTransaction(self._dbInfo, READ_WRITE, function (err, transaction) { if (err) { return reject(err); } try { var store = transaction.objectStore(self._dbInfo.storeName); var req = store["delete"](key); transaction.oncomplete = function () { resolve(); }; transaction.onerror = function () { reject(req.error); }; transaction.onabort = function () { var err = req.error ? req.error : req.transaction.error; reject(err); }; } catch (e) { reject(e); } }); })["catch"](reject); }); executeCallback(promise, callback); return promise; } function clear(callback) { var self = this; var promise = new Promise$1(function (resolve, reject) { self.ready().then(function () { createTransaction(self._dbInfo, READ_WRITE, function (err, transaction) { if (err) { return reject(err); } try { var store = transaction.objectStore(self._dbInfo.storeName); var req = store.clear(); transaction.oncomplete = function () { resolve(); }; transaction.onabort = transaction.onerror = function () { var err = req.error ? req.error : req.transaction.error; reject(err); }; } catch (e) { reject(e); } }); })["catch"](reject); }); executeCallback(promise, callback); return promise; } function length(callback) { var self = this; var promise = new Promise$1(function (resolve, reject) { self.ready().then(function () { createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) { if (err) { return reject(err); } try { var store = transaction.objectStore(self._dbInfo.storeName); var req = store.count(); req.onsuccess = function () { resolve(req.result); }; req.onerror = function () { reject(req.error); }; } catch (e) { reject(e); } }); })["catch"](reject); }); executeCallback(promise, callback); return promise; } function key(n, callback) { var self = this; var promise = new Promise$1(function (resolve, reject) { if (n < 0) { resolve(null); return; } self.ready().then(function () { createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) { if (err) { return reject(err); } try { var store = transaction.objectStore(self._dbInfo.storeName); var advanced = false; var req = store.openKeyCursor(); req.onsuccess = function () { var cursor = req.result; if (!cursor) { resolve(null); return; } if (n === 0) { resolve(cursor.key); } else { if (!advanced) { advanced = true; cursor.advance(n); } else { resolve(cursor.key); } } }; req.onerror = function () { reject(req.error); }; } catch (e) { reject(e); } }); })["catch"](reject); }); executeCallback(promise, callback); return promise; } function keys(callback) { var self = this; var promise = new Promise$1(function (resolve, reject) { self.ready().then(function () { createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) { if (err) { return reject(err); } try { var store = transaction.objectStore(self._dbInfo.storeName); var req = store.openKeyCursor(); var keys = []; req.onsuccess = function () { var cursor = req.result; if (!cursor) { resolve(keys); return; } keys.push(cursor.key); cursor["continue"](); }; req.onerror = function () { reject(req.error); }; } catch (e) { reject(e); } }); })["catch"](reject); }); executeCallback(promise, callback); return promise; } function dropInstance(options, callback) { callback = getCallback.apply(this, arguments); var currentConfig = this.config(); options = typeof options !== 'function' && options || {}; if (!options.name) { options.name = options.name || currentConfig.name; options.storeName = options.storeName || currentConfig.storeName; } var self = this; var promise; if (!options.name) { promise = Promise$1.reject('Invalid arguments'); } else { var isCurrentDb = options.name === currentConfig.name && self._dbInfo.db; var dbPromise = isCurrentDb ? Promise$1.resolve(self._dbInfo.db) : _getOriginalConnection(options).then(function (db) { var dbContext = dbContexts[options.name]; var forages = dbContext.forages; dbContext.db = db; for (var i = 0; i < forages.length; i++) { forages[i]._dbInfo.db = db; } return db; }); if (!options.storeName) { promise = dbPromise.then(function (db) { _deferReadiness(options); var dbContext = dbContexts[options.name]; var forages = dbContext.forages; db.close(); for (var i = 0; i < forages.length; i++) { var forage = forages[i]; forage._dbInfo.db = null; } var dropDBPromise = new Promise$1(function (resolve, reject) { var req = idb.deleteDatabase(options.name); req.onerror = function () { var db = req.result; if (db) { db.close(); } reject(req.error); }; req.onblocked = function () { console.warn('dropInstance blocked for database "' + options.name + '" until all open connections are closed'); }; req.onsuccess = function () { var db = req.result; if (db) { db.close(); } resolve(db); }; }); return dropDBPromise.then(function (db) { dbContext.db = db; for (var i = 0; i < forages.length; i++) { var _forage = forages[i]; _advanceReadiness(_forage._dbInfo); } })["catch"](function (err) { (_rejectReadiness(options, err) || Promise$1.resolve())["catch"](function () { }); throw err; }); }); } else { promise = dbPromise.then(function (db) { if (!db.objectStoreNames.contains(options.storeName)) { return; } var newVersion = db.version + 1; _deferReadiness(options); var dbContext = dbContexts[options.name]; var forages = dbContext.forages; db.close(); for (var i = 0; i < forages.length; i++) { var forage = forages[i]; forage._dbInfo.db = null; forage._dbInfo.version = newVersion; } var dropObjectPromise = new Promise$1(function (resolve, reject) { var req = idb.open(options.name, newVersion); req.onerror = function (err) { var db = req.result; db.close(); reject(err); }; req.onupgradeneeded = function () { var db = req.result; db.deleteObjectStore(options.storeName); }; req.onsuccess = function () { var db = req.result; db.close(); resolve(db); }; }); return dropObjectPromise.then(function (db) { dbContext.db = db; for (var j = 0; j < forages.length; j++) { var _forage2 = forages[j]; _forage2._dbInfo.db = db; _advanceReadiness(_forage2._dbInfo); } })["catch"](function (err) { (_rejectReadiness(options, err) || Promise$1.resolve())["catch"](function () { }); throw err; }); }); } } executeCallback(promise, callback); return promise; } var asyncStorage = { _driver: 'asyncStorage', _initStorage: _initStorage, _support: isIndexedDBValid(), iterate: iterate, getItem: getItem, setItem: setItem, removeItem: removeItem, clear: clear, length: length, key: key, keys: keys, dropInstance: dropInstance }; function isWebSQLValid() { return typeof openDatabase === 'function'; } var BASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; var BLOB_TYPE_PREFIX = '~~local_forage_type~'; var BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/; var SERIALIZED_MARKER = '__lfsc__:'; var SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length; var TYPE_ARRAYBUFFER = 'arbf'; var TYPE_BLOB = 'blob'; var TYPE_INT8ARRAY = 'si08'; var TYPE_UINT8ARRAY = 'ui08'; var TYPE_UINT8CLAMPEDARRAY = 'uic8'; var TYPE_INT16ARRAY = 'si16'; var TYPE_INT32ARRAY = 'si32'; var TYPE_UINT16ARRAY = 'ur16'; var TYPE_UINT32ARRAY = 'ui32'; var TYPE_FLOAT32ARRAY = 'fl32'; var TYPE_FLOAT64ARRAY = 'fl64'; var TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length; var toString$1 = Object.prototype.toString; function stringToBuffer(serializedString) { var bufferLength = serializedString.length * 0.75; var len = serializedString.length; var i; var p = 0; var encoded1, encoded2, encoded3, encoded4; if (serializedString[serializedString.length - 1] === '=') { bufferLength--; if (serializedString[serializedString.length - 2] === '=') { bufferLength--; } } var buffer = new ArrayBuffer(bufferLength); var bytes = new Uint8Array(buffer); for (i = 0; i < len; i += 4) { encoded1 = BASE_CHARS.indexOf(serializedString[i]); encoded2 = BASE_CHARS.indexOf(serializedString[i + 1]); encoded3 = BASE_CHARS.indexOf(serializedString[i + 2]); encoded4 = BASE_CHARS.indexOf(serializedString[i + 3]); bytes[p++] = encoded1 << 2 | encoded2 >> 4; bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2; bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63; } return buffer; } function bufferToString(buffer) { var bytes = new Uint8Array(buffer); var base64String = ''; var i; for (i = 0; i < bytes.length; i += 3) { base64String += BASE_CHARS[bytes[i] >> 2]; base64String += BASE_CHARS[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4]; base64String += BASE_CHARS[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6]; base64String += BASE_CHARS[bytes[i + 2] & 63]; } if (bytes.length % 3 === 2) { base64String = base64String.substring(0, base64String.length - 1) + '='; } else if (bytes.length % 3 === 1) { base64String = base64String.substring(0, base64String.length - 2) + '=='; } return base64String; } function serialize(value, callback) { var valueType = ''; if (value) { valueType = toString$1.call(value); } if (value && (valueType === '[object ArrayBuffer]' || value.buffer && toString$1.call(value.buffer) === '[object ArrayBuffer]')) { var buffer; var marker = SERIALIZED_MARKER; if (value instanceof ArrayBuffer) { buffer = value; marker += TYPE_ARRAYBUFFER; } else { buffer = value.buffer; if (valueType === '[object Int8Array]') { marker += TYPE_INT8ARRAY; } else if (valueType === '[object Uint8Array]') { marker += TYPE_UINT8ARRAY; } else if (valueType === '[object Uint8ClampedArray]') { marker += TYPE_UINT8CLAMPEDARRAY; } else if (valueType === '[object Int16Array]') { marker += TYPE_INT16ARRAY; } else if (valueType === '[object Uint16Array]') { marker += TYPE_UINT16ARRAY; } else if (valueType === '[object Int32Array]') { marker += TYPE_INT32ARRAY; } else if (valueType === '[object Uint32Array]') { marker += TYPE_UINT32ARRAY; } else if (valueType === '[object Float32Array]') { marker += TYPE_FLOAT32ARRAY; } else if (valueType === '[object Float64Array]') { marker += TYPE_FLOAT64ARRAY; } else { callback(new Error('Failed to get type for BinaryArray')); } } callback(marker + bufferToString(buffer)); } else if (valueType === '[object Blob]') { var fileReader = new FileReader(); fileReader.onload = function () { var str = BLOB_TYPE_PREFIX + value.type + '~' + bufferToString(this.result); callback(SERIALIZED_MARKER + TYPE_BLOB + str); }; fileReader.readAsArrayBuffer(value); } else { try { callback(JSON.stringify(value)); } catch (e) { console.error("Couldn't convert value into a JSON string: ", value); callback(null, e); } } } function deserialize(value) { if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) { return JSON.parse(value); } var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH); var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH); var blobType; if (type === TYPE_BLOB && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) { var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX); blobType = matcher[1]; serializedString = serializedString.substring(matcher[0].length); } var buffer = stringToBuffer(serializedString); switch (type) { case TYPE_ARRAYBUFFER: return buffer; case TYPE_BLOB: return createBlob([buffer], { type: blobType }); case TYPE_INT8ARRAY: return new Int8Array(buffer); case TYPE_UINT8ARRAY: return new Uint8Array(buffer); case TYPE_UINT8CLAMPEDARRAY: return new Uint8ClampedArray(buffer); case TYPE_INT16ARRAY: return new Int16Array(buffer); case TYPE_UINT16ARRAY: return new Uint16Array(buffer); case TYPE_INT32ARRAY: return new Int32Array(buffer); case TYPE_UINT32ARRAY: return new Uint32Array(buffer); case TYPE_FLOAT32ARRAY: return new Float32Array(buffer); case TYPE_FLOAT64ARRAY: return new Float64Array(buffer); default: throw new Error('Unkown type: ' + type); } } var localforageSerializer = { serialize: serialize, deserialize: deserialize, stringToBuffer: stringToBuffer, bufferToString: bufferToString }; function createDbTable(t, dbInfo, callback, errorCallback) { t.executeSql('CREATE TABLE IF NOT EXISTS ' + dbInfo.storeName + ' ' + '(id INTEGER PRIMARY KEY, key unique, value)', [], callback, errorCallback); } function _initStorage$1(options) { var self = this; var dbInfo = { db: null }; if (options) { for (var i in options) { dbInfo[i] = typeof options[i] !== 'string' ? options[i].toString() : options[i]; } } var dbInfoPromise = new Promise$1(function (resolve, reject) { try { dbInfo.db = openDatabase(dbInfo.name, String(dbInfo.version), dbInfo.description, dbInfo.size); } catch (e) { return reject(e); } dbInfo.db.transaction(function (t) { createDbTable(t, dbInfo, function () { self._dbInfo = dbInfo; resolve(); }, function (t, error) { reject(error); }); }, reject); }); dbInfo.serializer = localforageSerializer; return dbInfoPromise; } function tryExecuteSql(t, dbInfo, sqlStatement, args, callback, errorCallback) { t.executeSql(sqlStatement, args, callback, function (t, error) { if (error.code === error.SYNTAX_ERR) { t.executeSql('SELECT name FROM sqlite_master ' + "WHERE type='table' AND name = ?", [dbInfo.storeName], function (t, results) { if (!results.rows.length) { createDbTable(t, dbInfo, function () { t.executeSql(sqlStatement, args, callback, errorCallback); }, errorCallback); } else { errorCallback(t, error); } }, errorCallback); } else { errorCallback(t, error); } }, errorCallback); } function getItem$1(key, callback) { var self = this; key = normalizeKey(key); var promise = new Promise$1(function (resolve, reject) { self.ready().then(function () { var dbInfo = self._dbInfo; dbInfo.db.transaction(function (t) { tryExecuteSql(t, dbInfo, 'SELECT * FROM ' + dbInfo.storeName + ' WHERE key = ? LIMIT 1', [key], function (t, results) { var result = results.rows.length ? results.rows.item(0).value : null; if (result) { result = dbInfo.serializer.deserialize(result); } resolve(result); }, function (t, error) { reject(error); }); }); })["catch"](reject); }); executeCallback(promise, callback); return promise; } function iterate$1(iterator, callback) { var self = this; var promise = new Promise$1(function (resolve, reject) { self.ready().then(function () { var dbInfo = self._dbInfo; dbInfo.db.transaction(function (t) { tryExecuteSql(t, dbInfo, 'SELECT * FROM ' + dbInfo.storeName, [], function (t, results) { var rows = results.rows; var length = rows.length; for (var i = 0; i < length; i++) { var item = rows.item(i); var result = item.value; if (result) { result = dbInfo.serializer.deserialize(result); } result = iterator(result, item.key, i + 1); if (result !== void 0) { resolve(result); return; } } resolve(); }, function (t, error) { reject(error); }); }); })["catch"](reject); }); executeCallback(promise, callback); return promise; } function _setItem(key, value, callback, retriesLeft) { var self = this; key = normalizeKey(key); var promise = new Promise$1(function (resolve, reject) { self.ready().then(function () { if (value === undefined) { value = null; } var originalValue = value; var dbInfo = self._dbInfo; dbInfo.serializer.serialize(value, function (value, error) { if (error) { reject(error); } else { dbInfo.db.transaction(function (t) { tryExecuteSql(t, dbInfo, 'INSERT OR REPLACE INTO ' + dbInfo.storeName + ' ' + '(key, value) VALUES (?, ?)', [key, value], function () { resolve(originalValue); }, function (t, error) { reject(error); }); }, function (sqlError) { if (sqlError.code === sqlError.QUOTA_ERR) { if (retriesLeft > 0) { resolve(_setItem.apply(self, [key, originalValue, callback, retriesLeft - 1])); return; } reject(sqlError); } }); } }); })["catch"](reject); }); executeCallback(promise, callback); return promise; } function setItem$1(key, value, callback) { return _setItem.apply(this, [key, value, callback, 1]); } function removeItem$1(key, callback) { var self = this; key = normalizeKey(key); var promise = new Promise$1(function (resolve, reject) { self.ready().then(function () { var dbInfo = self._dbInfo; dbInfo.db.transaction(function (t) { tryExecuteSql(t, dbInfo, 'DELETE FROM ' + dbInfo.storeName + ' WHERE key = ?', [key], function () { resolve(); }, function (t, error) { reject(error); }); }); })["catch"](reject); }); executeCallback(promise, callback); return promise; } function clear$1(callback) { var self = this; var promise = new Promise$1(function (resolve, reject) { self.ready().then(function () { var dbInfo = self._dbInfo; dbInfo.db.transaction(function (t) { tryExecuteSql(t, dbInfo, 'DELETE FROM ' + dbInfo.storeName, [], function () { resolve(); }, function (t, error) { reject(error); }); }); })["catch"](reject); }); executeCallback(promise, callback); return promise; } function length$1(callback) { var self = this; var promise = new Promise$1(function (resolve, reject) { self.ready().then(function () { var dbInfo = self._dbInfo; dbInfo.db.transaction(function (t) { tryExecuteSql(t, dbInfo, 'SELECT COUNT(key) as c FROM ' + dbInfo.storeName, [], function (t, results) { var result = results.rows.item(0).c; resolve(result); }, function (t, error) { reject(error); }); }); })["catch"](reject); }); executeCallback(promise, callback); return promise; } function key$1(n, callback) { var self = this; var promise = new Promise$1(function (resolve, reject) { self.ready().then(function () { var dbInfo = self._dbInfo; dbInfo.db.transaction(function (t) { tryExecuteSql(t, dbInfo, 'SELECT key FROM ' + dbInfo.storeName + ' WHERE id = ? LIMIT 1', [n + 1], function (t, results) { var result = results.rows.length ? results.rows.item(0).key : null; resolve(result); }, function (t, error) { reject(error); }); }); })["catch"](reject); }); executeCallback(promise, callback); return promise; } function keys$1(callback) { var self = this; var promise = new Promise$1(function (resolve, reject) { self.ready().then(function () { var dbInfo = self._dbInfo; dbInfo.db.transaction(function (t) { tryExecuteSql(t, dbInfo, 'SELECT key FROM ' + dbInfo.storeName, [], function (t, results) { var keys = []; for (var i = 0; i < results.rows.length; i++) { keys.push(results.rows.item(i).key); } resolve(keys); }, function (t, error) { reject(error); }); }); })["catch"](reject); }); executeCallback(promise, callback); return promise; } function getAllStoreNames(db) { return new Promise$1(function (resolve, reject) { db.transaction(function (t) { t.executeSql('SELECT name FROM sqlite_master ' + "WHERE type='table' AND name <> '__WebKitDatabaseInfoTable__'", [], function (t, results) { var storeNames = []; for (var i = 0; i < results.rows.length; i++) { storeNames.push(results.rows.item(i).name); } resolve({ db: db, storeNames: storeNames }); }, function (t, error) { reject(error); }); }, function (sqlError) { reject(sqlError); }); }); } function dropInstance$1(options, callback) { callback = getCallback.apply(this, arguments); var currentConfig = this.config(); options = typeof options !== 'function' && options || {}; if (!options.name) { options.name = options.name || currentConfig.name; options.storeName = options.storeName || currentConfig.storeName; } var self = this; var promise; if (!options.name) { promise = Promise$1.reject('Invalid arguments'); } else { promise = new Promise$1(function (resolve) { var db; if (options.name === currentConfig.name) { db = self._dbInfo.db; } else { db = openDatabase(options.name, '', '', 0); } if (!options.storeName) { resolve(getAllStoreNames(db)); } else { resolve({ db: db, storeNames: [options.storeName] }); } }).then(function (operationInfo) { return new Promise$1(function (resolve, reject) { operationInfo.db.transaction(function (t) { function dropTable(storeName) { return new Promise$1(function (resolve, reject) { t.executeSql('DROP TABLE IF EXISTS ' + storeName, [], function () { resolve(); }, function (t, error) { reject(error); }); }); } var operations = []; for (var i = 0, len = operationInfo.storeNames.length; i < len; i++) { operations.push(dropTable(operationInfo.storeNames[i])); } Promise$1.all(operations).then(function () { resolve(); })["catch"](function (e) { reject(e); }); }, function (sqlError) { reject(sqlError); }); }); }); } executeCallback(promise, callback); return promise; } var webSQLStorage = { _driver: 'webSQLStorage', _initStorage: _initStorage$1, _support: isWebSQLValid(), iterate: iterate$1, getItem: getItem$1, setItem: setItem$1, removeItem: removeItem$1, clear: clear$1, length: length$1, key: key$1, keys: keys$1, dropInstance: dropInstance$1 }; function isLocalStorageValid() { try { return typeof localStorage !== 'undefined' && 'setItem' in localStorage && !!localStorage.setItem; } catch (e) { return false; } } function _getKeyPrefix(options, defaultConfig) { var keyPrefix = options.name + '/'; if (options.storeName !== defaultConfig.storeName) { keyPrefix += options.storeName + '/'; } return keyPrefix; } function checkIfLocalStorageThrows() { var localStorageTestKey = '_localforage_support_test'; try { localStorage.setItem(localStorageTestKey, true); localStorage.removeItem(localStorageTestKey); return false; } catch (e) { return true; } } function _isLocalStorageUsable() { return !checkIfLocalStorageThrows() || localStorage.length > 0; } function _initStorage$2(options) { var self = this; var dbInfo = {}; if (options) { for (var i in options) { dbInfo[i] = options[i]; } } dbInfo.keyPrefix = _getKeyPrefix(options, self._defaultConfig); if (!_isLocalStorageUsable()) { return Promise$1.reject(); } self._dbInfo = dbInfo; dbInfo.serializer = localforageSerializer; return Promise$1.resolve(); } function clear$2(callback) { var self = this; var promise = self.ready().then(function () { var keyPrefix = self._dbInfo.keyPrefix; for (var i = localStorage.length - 1; i >= 0; i--) { var key = localStorage.key(i); if (key.indexOf(keyPrefix) === 0) { localStorage.removeItem(key); } } }); executeCallback(promise, callback); return promise; } function getItem$2(key, callback) { var self = this; key = normalizeKey(key); var promise = self.ready().then(function () { var dbInfo = self._dbInfo; var result = localStorage.getItem(dbInfo.keyPrefix + key); if (result) { result = dbInfo.serializer.deserialize(result); } return result; }); executeCallback(promise, callback); return promise; } function iterate$2(iterator, callback) { var self = this; var promise = self.ready().then(function () { var dbInfo = self._dbInfo; var keyPrefix = dbInfo.keyPrefix; var keyPrefixLength = keyPrefix.length; var length = localStorage.length; var iterationNumber = 1; for (var i = 0; i < length; i++) { var key = localStorage.key(i); if (key.indexOf(keyPrefix) !== 0) { continue; } var value = localStorage.getItem(key); if (value) { value = dbInfo.serializer.deserialize(value); } value = iterator(value, key.substring(keyPrefixLength), iterationNumber++); if (value !== void 0) { return value; } } }); executeCallback(promise, callback); return promise; } function key$2(n, callback) { var self = this; var promise = self.ready().then(function () { var dbInfo = self._dbInfo; var result; try { result = localStorage.key(n); } catch (error) { result = null; } if (result) { result = result.substring(dbInfo.keyPrefix.length); } return result; }); executeCallback(promise, callback); return promise; } function keys$2(callback) { var self = this; var promise = self.ready().then(function () { var dbInfo = self._dbInfo; var length = localStorage.length; var keys = []; for (var i = 0; i < length; i++) { var itemKey = localStorage.key(i); if (itemKey.indexOf(dbInfo.keyPrefix) === 0) { keys.push(itemKey.substring(dbInfo.keyPrefix.length)); } } return keys; }); executeCallback(promise, callback); return promise; } function length$2(callback) { var self = this; var promise = self.keys().then(function (keys) { return keys.length; }); executeCallback(promise, callback); return promise; } function removeItem$2(key, callback) { var self = this; key = normalizeKey(key); var promise = self.ready().then(function () { var dbInfo = self._dbInfo; localStorage.removeItem(dbInfo.keyPrefix + key); }); executeCallback(promise, callback); return promise; } function setItem$2(key, value, callback) { var self = this; key = normalizeKey(key); var promise = self.ready().then(function () { if (value === undefined) { value = null; } var originalValue = value; return new Promise$1(function (resolve, reject) { var dbInfo = self._dbInfo; dbInfo.serializer.serialize(value, function (value, error) { if (error) { reject(error); } else { try { localStorage.setItem(dbInfo.keyPrefix + key, value); resolve(originalValue); } catch (e) { if (e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') { reject(e); } reject(e); } } }); }); }); executeCallback(promise, callback); return promise; } function dropInstance$2(options, callback) { callback = getCallback.apply(this, arguments); options = typeof options !== 'function' && options || {}; if (!options.name) { var currentConfig = this.config(); options.name = options.name || currentConfig.name; options.storeName = options.storeName || currentConfig.storeName; } var self = this; var promise; if (!options.name) { promise = Promise$1.reject('Invalid arguments'); } else { promise = new Promise$1(function (resolve) { if (!options.storeName) { resolve(options.name + '/'); } else { resolve(_getKeyPrefix(options, self._defaultConfig)); } }).then(function (keyPrefix) { for (var i = localStorage.length - 1; i >= 0; i--) { var key = localStorage.key(i); if (key.indexOf(keyPrefix) === 0) { localStorage.removeItem(key); } } }); } executeCallback(promise, callback); return promise; } var localStorageWrapper = { _driver: 'localStorageWrapper', _initStorage: _initStorage$2, _support: isLocalStorageValid(), iterate: iterate$2, getItem: getItem$2, setItem: setItem$2, removeItem: removeItem$2, clear: clear$2, length: length$2, key: key$2, keys: keys$2, dropInstance: dropInstance$2 }; var sameValue = function sameValue(x, y) { return x === y || typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y); }; var includes = function includes(array, searchElement) { var len = array.length; var i = 0; while (i < len) { if (sameValue(array[i], searchElement)) { return true; } i++; } return false; }; var isArray = Array.isArray || function (arg) { return Object.prototype.toString.call(arg) === '[object Array]'; }; var DefinedDrivers = {}; var DriverSupport = {}; var DefaultDrivers = { INDEXEDDB: asyncStorage, WEBSQL: webSQLStorage, LOCALSTORAGE: localStorageWrapper }; var DefaultDriverOrder = [DefaultDrivers.INDEXEDDB._driver, DefaultDrivers.WEBSQL._driver, DefaultDrivers.LOCALSTORAGE._driver]; var OptionalDriverMethods = ['dropInstance']; var LibraryMethods = ['clear', 'getItem', 'iterate', 'key', 'keys', 'length', 'removeItem', 'setItem'].concat(OptionalDriverMethods); var DefaultConfig = { description: '', driver: DefaultDriverOrder.slice(), name: 'localforage', size: 4980736, storeName: 'keyvaluepairs', version: 1.0 }; function callWhenReady(localForageInstance, libraryMethod) { localForageInstance[libraryMethod] = function () { var _args = arguments; return localForageInstance.ready().then(function () { return localForageInstance[libraryMethod].apply(localForageInstance, _args); }); }; } function extend() { for (var i = 1; i < arguments.length; i++) { var arg = arguments[i]; if (arg) { for (var _key in arg) { if (arg.hasOwnProperty(_key)) { if (isArray(arg[_key])) { arguments[0][_key] = arg[_key].slice(); } else { arguments[0][_key] = arg[_key]; } } } } } return arguments[0]; } var LocalForage = function () { function LocalForage(options) { _classCallCheck(this, LocalForage); for (var driverTypeKey in DefaultDrivers) { if (DefaultDrivers.hasOwnProperty(driverTypeKey)) { var driver = DefaultDrivers[driverTypeKey]; var driverName = driver._driver; this[driverTypeKey] = driverName; if (!DefinedDrivers[driverName]) { this.defineDriver(driver); } } } this._defaultConfig = extend({}, DefaultConfig); this._config = extend({}, this._defaultConfig, options); this._driverSet = null; this._initDriver = null; this._ready = false; this._dbInfo = null; this._wrapLibraryMethodsWithReady(); this.setDriver(this._config.driver)["catch"](function () { }); } LocalForage.prototype.config = function config(options) { if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') { if (this._ready) { return new Error("Can't call config() after localforage " + 'has been used.'); } for (var i in options) { if (i === 'storeName') { options[i] = options[i].replace(/\W/g, '_'); } if (i === 'version' && typeof options[i] !== 'number') { return new Error('Database version must be a number.'); } this._config[i] = options[i]; } if ('driver' in options && options.driver) { return this.setDriver(this._config.driver); } return true; } else if (typeof options === 'string') { return this._config[options]; } else { return this._config; } }; LocalForage.prototype.defineDriver = function defineDriver(driverObject, callback, errorCallback) { var promise = new Promise$1(function (resolve, reject) { try { var driverName = driverObject._driver; var complianceError = new Error('Custom driver not compliant; see ' + 'https://mozilla.github.io/localForage/#definedriver'); if (!driverObject._driver) { reject(complianceError); return; } var driverMethods = LibraryMethods.concat('_initStorage'); for (var i = 0, len = driverMethods.length; i < len; i++) { var driverMethodName = driverMethods[i]; var isRequired = !includes(OptionalDriverMethods, driverMethodName); if ((isRequired || driverObject[driverMethodName]) && typeof driverObject[driverMethodName] !== 'function') { reject(complianceError); return; } } var configureMissingMethods = function configureMissingMethods() { var methodNotImplementedFactory = function methodNotImplementedFactory(methodName) { return function () { var error = new Error('Method ' + methodName + ' is not implemented by the current driver'); var promise = Promise$1.reject(error); executeCallback(promise, arguments[arguments.length - 1]); return promise; }; }; for (var _i = 0, _len = OptionalDriverMethods.length; _i < _len; _i++) { var optionalDriverMethod = OptionalDriverMethods[_i]; if (!driverObject[optionalDriverMethod]) { driverObject[optionalDriverMethod] = methodNotImplementedFactory(optionalDriverMethod); } } }; configureMissingMethods(); var setDriverSupport = function setDriverSupport(support) { if (DefinedDrivers[driverName]) { console.info('Redefining LocalForage driver: ' + driverName); } DefinedDrivers[driverName] = driverObject; DriverSupport[driverName] = support; resolve(); }; if ('_support' in driverObject) { if (driverObject._support && typeof driverObject._support === 'function') { driverObject._support().then(setDriverSupport, reject); } else { setDriverSupport(!!driverObject._support); } } else { setDriverSupport(true); } } catch (e) { reject(e); } }); executeTwoCallbacks(promise, callback, errorCallback); return promise; }; LocalForage.prototype.driver = function driver() { return this._driver || null; }; LocalForage.prototype.getDriver = function getDriver(driverName, callback, errorCallback) { var getDriverPromise = DefinedDrivers[driverName] ? Promise$1.resolve(DefinedDrivers[driverName]) : Promise$1.reject(new Error('Driver not found.')); executeTwoCallbacks(getDriverPromise, callback, errorCallback); return getDriverPromise; }; LocalForage.prototype.getSerializer = function getSerializer(callback) { var serializerPromise = Promise$1.resolve(localforageSerializer); executeTwoCallbacks(serializerPromise, callback); return serializerPromise; }; LocalForage.prototype.ready = function ready(callback) { var self = this; var promise = self._driverSet.then(function () { if (self._ready === null) { self._ready = self._initDriver(); } return self._ready; }); executeTwoCallbacks(promise, callback, callback); return promise; }; LocalForage.prototype.setDriver = function setDriver(drivers, callback, errorCallback) { var self = this; if (!isArray(drivers)) { drivers = [drivers]; } var supportedDrivers = this._getSupportedDrivers(drivers); function setDriverToConfig() { self._config.driver = self.driver(); } function extendSelfWithDriver(driver) { self._extend(driver); setDriverToConfig(); self._ready = self._initStorage(self._config); return self._ready; } function initDriver(supportedDrivers) { return function () { var currentDriverIndex = 0; function driverPromiseLoop() { while (currentDriverIndex < supportedDrivers.length) { var driverName = supportedDrivers[currentDriverIndex]; currentDriverIndex++; self._dbInfo = null; self._ready = null; return self.getDriver(driverName).then(extendSelfWithDriver)["catch"](driverPromiseLoop); } setDriverToConfig(); var error = new Error('No available storage method found.'); self._driverSet = Promise$1.reject(error); return self._driverSet; } return driverPromiseLoop(); }; } var oldDriverSetDone = this._driverSet !== null ? this._driverSet["catch"](function () { return Promise$1.resolve(); }) : Promise$1.resolve(); this._driverSet = oldDriverSetDone.then(function () { var driverName = supportedDrivers[0]; self._dbInfo = null; self._ready = null; return self.getDriver(driverName).then(function (driver) { self._driver = driver._driver; setDriverToConfig(); self._wrapLibraryMethodsWithReady(); self._initDriver = initDriver(supportedDrivers); }); })["catch"](function () { setDriverToConfig(); var error = new Error('No available storage method found.'); self._driverSet = Promise$1.reject(error); return self._driverSet; }); executeTwoCallbacks(this._driverSet, callback, errorCallback); return this._driverSet; }; LocalForage.prototype.supports = function supports(driverName) { return !!DriverSupport[driverName]; }; LocalForage.prototype._extend = function _extend(libraryMethodsAndProperties) { extend(this, libraryMethodsAndProperties); }; LocalForage.prototype._getSupportedDrivers = function _getSupportedDrivers(drivers) { var supportedDrivers = []; for (var i = 0, len = drivers.length; i < len; i++) { var driverName = drivers[i]; if (this.supports(driverName)) { supportedDrivers.push(driverName); } } return supportedDrivers; }; LocalForage.prototype._wrapLibraryMethodsWithReady = function _wrapLibraryMethodsWithReady() { for (var i = 0, len = LibraryMethods.length; i < len; i++) { callWhenReady(this, LibraryMethods[i]); } }; LocalForage.prototype.createInstance = function createInstance(options) { return new LocalForage(options); }; return LocalForage; }(); var localforage_js = new LocalForage(); module.exports = localforage_js; }, { "3": 3 }] }, {}, [4])(4); }); }).call(this); }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}); _$localforage_1 = _$localforage_1.exports; var _$input_2 = {}; (function (global) { (function () { "use strict"; var _localforage = _interopRequireDefault(_$localforage_1); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } global["localforage"] = _localforage["default"]; }).call(this); }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}); }()); /* </pre> */