/* * Dexie.js - a minimalistic wrapper for IndexedDB * =============================================== * * By David Fahlander, david.fahlander@gmail.com * * Version 3.0.2, Fri Jul 31 2020 * * http://dexie.org * * Apache License Version 2.0, January 2004, http://www.apache.org/licenses/ */ var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; function __spreadArrays() { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; } var keys = Object.keys; var isArray = Array.isArray; var _global = typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : global; if (typeof Promise !== 'undefined' && !_global.Promise) { _global.Promise = Promise; } function extend(obj, extension) { if (typeof extension !== 'object') return obj; keys(extension).forEach(function (key) { obj[key] = extension[key]; }); return obj; } var getProto = Object.getPrototypeOf; var _hasOwn = {}.hasOwnProperty; function hasOwn(obj, prop) { return _hasOwn.call(obj, prop); } function props(proto, extension) { if (typeof extension === 'function') extension = extension(getProto(proto)); keys(extension).forEach(function (key) { setProp(proto, key, extension[key]); }); } var defineProperty = Object.defineProperty; function setProp(obj, prop, functionOrGetSet, options) { defineProperty(obj, prop, extend(functionOrGetSet && hasOwn(functionOrGetSet, "get") && typeof functionOrGetSet.get === 'function' ? { get: functionOrGetSet.get, set: functionOrGetSet.set, configurable: true } : { value: functionOrGetSet, configurable: true, writable: true }, options)); } function derive(Child) { return { from: function (Parent) { Child.prototype = Object.create(Parent.prototype); setProp(Child.prototype, "constructor", Child); return { extend: props.bind(null, Child.prototype) }; } }; } var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; function getPropertyDescriptor(obj, prop) { var pd = getOwnPropertyDescriptor(obj, prop); var proto; return pd || (proto = getProto(obj)) && getPropertyDescriptor(proto, prop); } var _slice = [].slice; function slice(args, start, end) { return _slice.call(args, start, end); } function override(origFunc, overridedFactory) { return overridedFactory(origFunc); } function assert(b) { if (!b) throw new Error("Assertion Failed"); } function asap(fn) { if (_global.setImmediate) setImmediate(fn); else setTimeout(fn, 0); } function arrayToObject(array, extractor) { return array.reduce(function (result, item, i) { var nameAndValue = extractor(item, i); if (nameAndValue) result[nameAndValue[0]] = nameAndValue[1]; return result; }, {}); } function tryCatch(fn, onerror, args) { try { fn.apply(null, args); } catch (ex) { onerror && onerror(ex); } } function getByKeyPath(obj, keyPath) { if (hasOwn(obj, keyPath)) return obj[keyPath]; if (!keyPath) return obj; if (typeof keyPath !== 'string') { var rv = []; for (var i = 0, l = keyPath.length; i < l; ++i) { var val = getByKeyPath(obj, keyPath[i]); rv.push(val); } return rv; } var period = keyPath.indexOf('.'); if (period !== -1) { var innerObj = obj[keyPath.substr(0, period)]; return innerObj === undefined ? undefined : getByKeyPath(innerObj, keyPath.substr(period + 1)); } return undefined; } function setByKeyPath(obj, keyPath, value) { if (!obj || keyPath === undefined) return; if ('isFrozen' in Object && Object.isFrozen(obj)) return; if (typeof keyPath !== 'string' && 'length' in keyPath) { assert(typeof value !== 'string' && 'length' in value); for (var i = 0, l = keyPath.length; i < l; ++i) { setByKeyPath(obj, keyPath[i], value[i]); } } else { var period = keyPath.indexOf('.'); if (period !== -1) { var currentKeyPath = keyPath.substr(0, period); var remainingKeyPath = keyPath.substr(period + 1); if (remainingKeyPath === "") if (value === undefined) { if (isArray(obj) && !isNaN(parseInt(currentKeyPath))) obj.splice(currentKeyPath, 1); else delete obj[currentKeyPath]; } else obj[currentKeyPath] = value; else { var innerObj = obj[currentKeyPath]; if (!innerObj) innerObj = (obj[currentKeyPath] = {}); setByKeyPath(innerObj, remainingKeyPath, value); } } else { if (value === undefined) { if (isArray(obj) && !isNaN(parseInt(keyPath))) obj.splice(keyPath, 1); else delete obj[keyPath]; } else obj[keyPath] = value; } } } function delByKeyPath(obj, keyPath) { if (typeof keyPath === 'string') setByKeyPath(obj, keyPath, undefined); else if ('length' in keyPath) [].map.call(keyPath, function (kp) { setByKeyPath(obj, kp, undefined); }); } function shallowClone(obj) { var rv = {}; for (var m in obj) { if (hasOwn(obj, m)) rv[m] = obj[m]; } return rv; } var concat = [].concat; function flatten(a) { return concat.apply([], a); } var intrinsicTypeNames = "Boolean,String,Date,RegExp,Blob,File,FileList,ArrayBuffer,DataView,Uint8ClampedArray,ImageData,Map,Set" .split(',').concat(flatten([8, 16, 32, 64].map(function (num) { return ["Int", "Uint", "Float"].map(function (t) { return t + num + "Array"; }); }))).filter(function (t) { return _global[t]; }); var intrinsicTypes = intrinsicTypeNames.map(function (t) { return _global[t]; }); var intrinsicTypeNameSet = arrayToObject(intrinsicTypeNames, function (x) { return [x, true]; }); function deepClone(any) { if (!any || typeof any !== 'object') return any; var rv; if (isArray(any)) { rv = []; for (var i = 0, l = any.length; i < l; ++i) { rv.push(deepClone(any[i])); } } else if (intrinsicTypes.indexOf(any.constructor) >= 0) { rv = any; } else { rv = any.constructor ? Object.create(any.constructor.prototype) : {}; for (var prop in any) { if (hasOwn(any, prop)) { rv[prop] = deepClone(any[prop]); } } } return rv; } var toString = {}.toString; function toStringTag(o) { return toString.call(o).slice(8, -1); } var getValueOf = function (val, type) { return type === "Array" ? '' + val.map(function (v) { return getValueOf(v, toStringTag(v)); }) : type === "ArrayBuffer" ? '' + new Uint8Array(val) : type === "Date" ? val.getTime() : ArrayBuffer.isView(val) ? '' + new Uint8Array(val.buffer) : val; }; function getObjectDiff(a, b, rv, prfx) { rv = rv || {}; prfx = prfx || ''; keys(a).forEach(function (prop) { if (!hasOwn(b, prop)) rv[prfx + prop] = undefined; else { var ap = a[prop], bp = b[prop]; if (typeof ap === 'object' && typeof bp === 'object' && ap && bp) { var apTypeName = toStringTag(ap); var bpTypeName = toStringTag(bp); if (apTypeName === bpTypeName) { if (intrinsicTypeNameSet[apTypeName]) { if (getValueOf(ap, apTypeName) !== getValueOf(bp, bpTypeName)) { rv[prfx + prop] = b[prop]; } } else { getObjectDiff(ap, bp, rv, prfx + prop + "."); } } else { rv[prfx + prop] = b[prop]; } } else if (ap !== bp) rv[prfx + prop] = b[prop]; } }); keys(b).forEach(function (prop) { if (!hasOwn(a, prop)) { rv[prfx + prop] = b[prop]; } }); return rv; } var iteratorSymbol = typeof Symbol !== 'undefined' && Symbol.iterator; var getIteratorOf = iteratorSymbol ? function (x) { var i; return x != null && (i = x[iteratorSymbol]) && i.apply(x); } : function () { return null; }; var NO_CHAR_ARRAY = {}; function getArrayOf(arrayLike) { var i, a, x, it; if (arguments.length === 1) { if (isArray(arrayLike)) return arrayLike.slice(); if (this === NO_CHAR_ARRAY && typeof arrayLike === 'string') return [arrayLike]; if ((it = getIteratorOf(arrayLike))) { a = []; while (x = it.next(), !x.done) a.push(x.value); return a; } if (arrayLike == null) return [arrayLike]; i = arrayLike.length; if (typeof i === 'number') { a = new Array(i); while (i--) a[i] = arrayLike[i]; return a; } return [arrayLike]; } i = arguments.length; a = new Array(i); while (i--) a[i] = arguments[i]; return a; } var isAsyncFunction = typeof Symbol !== 'undefined' ? function (fn) { return fn[Symbol.toStringTag] === 'AsyncFunction'; } : function () { return false; }; var debug = typeof location !== 'undefined' && /^(http|https):\/\/(localhost|127\.0\.0\.1)/.test(location.href); function setDebug(value, filter) { debug = value; libraryFilter = filter; } var libraryFilter = function () { return true; }; var NEEDS_THROW_FOR_STACK = !new Error("").stack; function getErrorWithStack() { if (NEEDS_THROW_FOR_STACK) try { throw new Error(); } catch (e) { return e; } return new Error(); } function prettyStack(exception, numIgnoredFrames) { var stack = exception.stack; if (!stack) return ""; numIgnoredFrames = (numIgnoredFrames || 0); if (stack.indexOf(exception.name) === 0) numIgnoredFrames += (exception.name + exception.message).split('\n').length; return stack.split('\n') .slice(numIgnoredFrames) .filter(libraryFilter) .map(function (frame) { return "\n" + frame; }) .join(''); } var dexieErrorNames = [ 'Modify', 'Bulk', 'OpenFailed', 'VersionChange', 'Schema', 'Upgrade', 'InvalidTable', 'MissingAPI', 'NoSuchDatabase', 'InvalidArgument', 'SubTransaction', 'Unsupported', 'Internal', 'DatabaseClosed', 'PrematureCommit', 'ForeignAwait' ]; var idbDomErrorNames = [ 'Unknown', 'Constraint', 'Data', 'TransactionInactive', 'ReadOnly', 'Version', 'NotFound', 'InvalidState', 'InvalidAccess', 'Abort', 'Timeout', 'QuotaExceeded', 'Syntax', 'DataClone' ]; var errorList = dexieErrorNames.concat(idbDomErrorNames); var defaultTexts = { VersionChanged: "Database version changed by other database connection", DatabaseClosed: "Database has been closed", Abort: "Transaction aborted", TransactionInactive: "Transaction has already completed or failed" }; function DexieError(name, msg) { this._e = getErrorWithStack(); this.name = name; this.message = msg; } derive(DexieError).from(Error).extend({ stack: { get: function () { return this._stack || (this._stack = this.name + ": " + this.message + prettyStack(this._e, 2)); } }, toString: function () { return this.name + ": " + this.message; } }); function getMultiErrorMessage(msg, failures) { return msg + ". Errors: " + Object.keys(failures) .map(function (key) { return failures[key].toString(); }) .filter(function (v, i, s) { return s.indexOf(v) === i; }) .join('\n'); } function ModifyError(msg, failures, successCount, failedKeys) { this._e = getErrorWithStack(); this.failures = failures; this.failedKeys = failedKeys; this.successCount = successCount; this.message = getMultiErrorMessage(msg, failures); } derive(ModifyError).from(DexieError); function BulkError(msg, failures) { this._e = getErrorWithStack(); this.name = "BulkError"; this.failures = failures; this.message = getMultiErrorMessage(msg, failures); } derive(BulkError).from(DexieError); var errnames = errorList.reduce(function (obj, name) { return (obj[name] = name + "Error", obj); }, {}); var BaseException = DexieError; var exceptions = errorList.reduce(function (obj, name) { var fullName = name + "Error"; function DexieError(msgOrInner, inner) { this._e = getErrorWithStack(); this.name = fullName; if (!msgOrInner) { this.message = defaultTexts[name] || fullName; this.inner = null; } else if (typeof msgOrInner === 'string') { this.message = "" + msgOrInner + (!inner ? '' : '\n ' + inner); this.inner = inner || null; } else if (typeof msgOrInner === 'object') { this.message = msgOrInner.name + " " + msgOrInner.message; this.inner = msgOrInner; } } derive(DexieError).from(BaseException); obj[name] = DexieError; return obj; }, {}); exceptions.Syntax = SyntaxError; exceptions.Type = TypeError; exceptions.Range = RangeError; var exceptionMap = idbDomErrorNames.reduce(function (obj, name) { obj[name + "Error"] = exceptions[name]; return obj; }, {}); function mapError(domError, message) { if (!domError || domError instanceof DexieError || domError instanceof TypeError || domError instanceof SyntaxError || !domError.name || !exceptionMap[domError.name]) return domError; var rv = new exceptionMap[domError.name](message || domError.message, domError); if ("stack" in domError) { setProp(rv, "stack", { get: function () { return this.inner.stack; } }); } return rv; } var fullNameExceptions = errorList.reduce(function (obj, name) { if (["Syntax", "Type", "Range"].indexOf(name) === -1) obj[name + "Error"] = exceptions[name]; return obj; }, {}); fullNameExceptions.ModifyError = ModifyError; fullNameExceptions.DexieError = DexieError; fullNameExceptions.BulkError = BulkError; function nop() { } function mirror(val) { return val; } function pureFunctionChain(f1, f2) { if (f1 == null || f1 === mirror) return f2; return function (val) { return f2(f1(val)); }; } function callBoth(on1, on2) { return function () { on1.apply(this, arguments); on2.apply(this, arguments); }; } function hookCreatingChain(f1, f2) { if (f1 === nop) return f2; return function () { var res = f1.apply(this, arguments); if (res !== undefined) arguments[0] = res; var onsuccess = this.onsuccess, onerror = this.onerror; this.onsuccess = null; this.onerror = null; var res2 = f2.apply(this, arguments); if (onsuccess) this.onsuccess = this.onsuccess ? callBoth(onsuccess, this.onsuccess) : onsuccess; if (onerror) this.onerror = this.onerror ? callBoth(onerror, this.onerror) : onerror; return res2 !== undefined ? res2 : res; }; } function hookDeletingChain(f1, f2) { if (f1 === nop) return f2; return function () { f1.apply(this, arguments); var onsuccess = this.onsuccess, onerror = this.onerror; this.onsuccess = this.onerror = null; f2.apply(this, arguments); if (onsuccess) this.onsuccess = this.onsuccess ? callBoth(onsuccess, this.onsuccess) : onsuccess; if (onerror) this.onerror = this.onerror ? callBoth(onerror, this.onerror) : onerror; }; } function hookUpdatingChain(f1, f2) { if (f1 === nop) return f2; return function (modifications) { var res = f1.apply(this, arguments); extend(modifications, res); var onsuccess = this.onsuccess, onerror = this.onerror; this.onsuccess = null; this.onerror = null; var res2 = f2.apply(this, arguments); if (onsuccess) this.onsuccess = this.onsuccess ? callBoth(onsuccess, this.onsuccess) : onsuccess; if (onerror) this.onerror = this.onerror ? callBoth(onerror, this.onerror) : onerror; return res === undefined ? (res2 === undefined ? undefined : res2) : (extend(res, res2)); }; } function reverseStoppableEventChain(f1, f2) { if (f1 === nop) return f2; return function () { if (f2.apply(this, arguments) === false) return false; return f1.apply(this, arguments); }; } function promisableChain(f1, f2) { if (f1 === nop) return f2; return function () { var res = f1.apply(this, arguments); if (res && typeof res.then === 'function') { var thiz = this, i = arguments.length, args = new Array(i); while (i--) args[i] = arguments[i]; return res.then(function () { return f2.apply(thiz, args); }); } return f2.apply(this, arguments); }; } var INTERNAL = {}; var LONG_STACKS_CLIP_LIMIT = 100; var MAX_LONG_STACKS = 20; var ZONE_ECHO_LIMIT = 100; var _a = typeof Promise === 'undefined' ? [] : (function () { var globalP = Promise.resolve(); if (typeof crypto === 'undefined' || !crypto.subtle) return [globalP, globalP.__proto__, globalP]; var nativeP = crypto.subtle.digest("SHA-512", new Uint8Array([0])); return [ nativeP, nativeP.__proto__, globalP ]; })(); var resolvedNativePromise = _a[0]; var nativePromiseProto = _a[1]; var resolvedGlobalPromise = _a[2]; var nativePromiseThen = nativePromiseProto && nativePromiseProto.then; var NativePromise = resolvedNativePromise && resolvedNativePromise.constructor; var patchGlobalPromise = !!resolvedGlobalPromise; var stack_being_generated = false; var schedulePhysicalTick = resolvedGlobalPromise ? function () { resolvedGlobalPromise.then(physicalTick); } : _global.setImmediate ? setImmediate.bind(null, physicalTick) : _global.MutationObserver ? function () { var hiddenDiv = document.createElement("div"); (new MutationObserver(function () { physicalTick(); hiddenDiv = null; })).observe(hiddenDiv, { attributes: true }); hiddenDiv.setAttribute('i', '1'); } : function () { setTimeout(physicalTick, 0); }; var asap$1 = function (callback, args) { microtickQueue.push([callback, args]); if (needsNewPhysicalTick) { schedulePhysicalTick(); needsNewPhysicalTick = false; } }; var isOutsideMicroTick = true; var needsNewPhysicalTick = true; var unhandledErrors = []; var rejectingErrors = []; var currentFulfiller = null; var rejectionMapper = mirror; var globalPSD = { id: 'global', global: true, ref: 0, unhandleds: [], onunhandled: globalError, pgp: false, env: {}, finalize: function () { this.unhandleds.forEach(function (uh) { try { globalError(uh[0], uh[1]); } catch (e) { } }); } }; var PSD = globalPSD; var microtickQueue = []; var numScheduledCalls = 0; var tickFinalizers = []; function DexiePromise(fn) { if (typeof this !== 'object') throw new TypeError('Promises must be constructed via new'); this._listeners = []; this.onuncatched = nop; this._lib = false; var psd = (this._PSD = PSD); if (debug) { this._stackHolder = getErrorWithStack(); this._prev = null; this._numPrev = 0; } if (typeof fn !== 'function') { if (fn !== INTERNAL) throw new TypeError('Not a function'); this._state = arguments[1]; this._value = arguments[2]; if (this._state === false) handleRejection(this, this._value); return; } this._state = null; this._value = null; ++psd.ref; executePromiseTask(this, fn); } var thenProp = { get: function () { var psd = PSD, microTaskId = totalEchoes; function then(onFulfilled, onRejected) { var _this = this; var possibleAwait = !psd.global && (psd !== PSD || microTaskId !== totalEchoes); if (possibleAwait) decrementExpectedAwaits(); var rv = new DexiePromise(function (resolve, reject) { propagateToListener(_this, new Listener(nativeAwaitCompatibleWrap(onFulfilled, psd, possibleAwait), nativeAwaitCompatibleWrap(onRejected, psd, possibleAwait), resolve, reject, psd)); }); debug && linkToPreviousPromise(rv, this); return rv; } then.prototype = INTERNAL; return then; }, set: function (value) { setProp(this, 'then', value && value.prototype === INTERNAL ? thenProp : { get: function () { return value; }, set: thenProp.set }); } }; props(DexiePromise.prototype, { then: thenProp, _then: function (onFulfilled, onRejected) { propagateToListener(this, new Listener(null, null, onFulfilled, onRejected, PSD)); }, catch: function (onRejected) { if (arguments.length === 1) return this.then(null, onRejected); var type = arguments[0], handler = arguments[1]; return typeof type === 'function' ? this.then(null, function (err) { return err instanceof type ? handler(err) : PromiseReject(err); }) : this.then(null, function (err) { return err && err.name === type ? handler(err) : PromiseReject(err); }); }, finally: function (onFinally) { return this.then(function (value) { onFinally(); return value; }, function (err) { onFinally(); return PromiseReject(err); }); }, stack: { get: function () { if (this._stack) return this._stack; try { stack_being_generated = true; var stacks = getStack(this, [], MAX_LONG_STACKS); var stack = stacks.join("\nFrom previous: "); if (this._state !== null) this._stack = stack; return stack; } finally { stack_being_generated = false; } } }, timeout: function (ms, msg) { var _this = this; return ms < Infinity ? new DexiePromise(function (resolve, reject) { var handle = setTimeout(function () { return reject(new exceptions.Timeout(msg)); }, ms); _this.then(resolve, reject).finally(clearTimeout.bind(null, handle)); }) : this; } }); if (typeof Symbol !== 'undefined' && Symbol.toStringTag) setProp(DexiePromise.prototype, Symbol.toStringTag, 'Dexie.Promise'); globalPSD.env = snapShot(); function Listener(onFulfilled, onRejected, resolve, reject, zone) { this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; this.onRejected = typeof onRejected === 'function' ? onRejected : null; this.resolve = resolve; this.reject = reject; this.psd = zone; } props(DexiePromise, { all: function () { var values = getArrayOf.apply(null, arguments) .map(onPossibleParallellAsync); return new DexiePromise(function (resolve, reject) { if (values.length === 0) resolve([]); var remaining = values.length; values.forEach(function (a, i) { return DexiePromise.resolve(a).then(function (x) { values[i] = x; if (!--remaining) resolve(values); }, reject); }); }); }, resolve: function (value) { if (value instanceof DexiePromise) return value; if (value && typeof value.then === 'function') return new DexiePromise(function (resolve, reject) { value.then(resolve, reject); }); var rv = new DexiePromise(INTERNAL, true, value); linkToPreviousPromise(rv, currentFulfiller); return rv; }, reject: PromiseReject, race: function () { var values = getArrayOf.apply(null, arguments).map(onPossibleParallellAsync); return new DexiePromise(function (resolve, reject) { values.map(function (value) { return DexiePromise.resolve(value).then(resolve, reject); }); }); }, PSD: { get: function () { return PSD; }, set: function (value) { return PSD = value; } }, newPSD: newScope, usePSD: usePSD, scheduler: { get: function () { return asap$1; }, set: function (value) { asap$1 = value; } }, rejectionMapper: { get: function () { return rejectionMapper; }, set: function (value) { rejectionMapper = value; } }, follow: function (fn, zoneProps) { return new DexiePromise(function (resolve, reject) { return newScope(function (resolve, reject) { var psd = PSD; psd.unhandleds = []; psd.onunhandled = reject; psd.finalize = callBoth(function () { var _this = this; run_at_end_of_this_or_next_physical_tick(function () { _this.unhandleds.length === 0 ? resolve() : reject(_this.unhandleds[0]); }); }, psd.finalize); fn(); }, zoneProps, resolve, reject); }); } }); if (NativePromise) { if (NativePromise.allSettled) setProp(DexiePromise, "allSettled", function () { var possiblePromises = getArrayOf.apply(null, arguments).map(onPossibleParallellAsync); return new DexiePromise(function (resolve) { if (possiblePromises.length === 0) resolve([]); var remaining = possiblePromises.length; var results = new Array(remaining); possiblePromises.forEach(function (p, i) { return DexiePromise.resolve(p).then(function (value) { return results[i] = { status: "fulfilled", value: value }; }, function (reason) { return results[i] = { status: "rejected", reason: reason }; }) .then(function () { return --remaining || resolve(results); }); }); }); }); if (NativePromise.any && typeof AggregateError !== 'undefined') setProp(DexiePromise, "any", function () { var possiblePromises = getArrayOf.apply(null, arguments).map(onPossibleParallellAsync); return new DexiePromise(function (resolve, reject) { if (possiblePromises.length === 0) reject(new AggregateError([])); var remaining = possiblePromises.length; var failures = new Array(remaining); possiblePromises.forEach(function (p, i) { return DexiePromise.resolve(p).then(function (value) { return resolve(value); }, function (failure) { failures[i] = failure; if (!--remaining) reject(new AggregateError(failures)); }); }); }); }); } function executePromiseTask(promise, fn) { try { fn(function (value) { if (promise._state !== null) return; if (value === promise) throw new TypeError('A promise cannot be resolved with itself.'); var shouldExecuteTick = promise._lib && beginMicroTickScope(); if (value && typeof value.then === 'function') { executePromiseTask(promise, function (resolve, reject) { value instanceof DexiePromise ? value._then(resolve, reject) : value.then(resolve, reject); }); } else { promise._state = true; promise._value = value; propagateAllListeners(promise); } if (shouldExecuteTick) endMicroTickScope(); }, handleRejection.bind(null, promise)); } catch (ex) { handleRejection(promise, ex); } } function handleRejection(promise, reason) { rejectingErrors.push(reason); if (promise._state !== null) return; var shouldExecuteTick = promise._lib && beginMicroTickScope(); reason = rejectionMapper(reason); promise._state = false; promise._value = reason; debug && reason !== null && typeof reason === 'object' && !reason._promise && tryCatch(function () { var origProp = getPropertyDescriptor(reason, "stack"); reason._promise = promise; setProp(reason, "stack", { get: function () { return stack_being_generated ? origProp && (origProp.get ? origProp.get.apply(reason) : origProp.value) : promise.stack; } }); }); addPossiblyUnhandledError(promise); propagateAllListeners(promise); if (shouldExecuteTick) endMicroTickScope(); } function propagateAllListeners(promise) { var listeners = promise._listeners; promise._listeners = []; for (var i = 0, len = listeners.length; i < len; ++i) { propagateToListener(promise, listeners[i]); } var psd = promise._PSD; --psd.ref || psd.finalize(); if (numScheduledCalls === 0) { ++numScheduledCalls; asap$1(function () { if (--numScheduledCalls === 0) finalizePhysicalTick(); }, []); } } function propagateToListener(promise, listener) { if (promise._state === null) { promise._listeners.push(listener); return; } var cb = promise._state ? listener.onFulfilled : listener.onRejected; if (cb === null) { return (promise._state ? listener.resolve : listener.reject)(promise._value); } ++listener.psd.ref; ++numScheduledCalls; asap$1(callListener, [cb, promise, listener]); } function callListener(cb, promise, listener) { try { currentFulfiller = promise; var ret, value = promise._value; if (promise._state) { ret = cb(value); } else { if (rejectingErrors.length) rejectingErrors = []; ret = cb(value); if (rejectingErrors.indexOf(value) === -1) markErrorAsHandled(promise); } listener.resolve(ret); } catch (e) { listener.reject(e); } finally { currentFulfiller = null; if (--numScheduledCalls === 0) finalizePhysicalTick(); --listener.psd.ref || listener.psd.finalize(); } } function getStack(promise, stacks, limit) { if (stacks.length === limit) return stacks; var stack = ""; if (promise._state === false) { var failure = promise._value, errorName, message; if (failure != null) { errorName = failure.name || "Error"; message = failure.message || failure; stack = prettyStack(failure, 0); } else { errorName = failure; message = ""; } stacks.push(errorName + (message ? ": " + message : "") + stack); } if (debug) { stack = prettyStack(promise._stackHolder, 2); if (stack && stacks.indexOf(stack) === -1) stacks.push(stack); if (promise._prev) getStack(promise._prev, stacks, limit); } return stacks; } function linkToPreviousPromise(promise, prev) { var numPrev = prev ? prev._numPrev + 1 : 0; if (numPrev < LONG_STACKS_CLIP_LIMIT) { promise._prev = prev; promise._numPrev = numPrev; } } function physicalTick() { beginMicroTickScope() && endMicroTickScope(); } function beginMicroTickScope() { var wasRootExec = isOutsideMicroTick; isOutsideMicroTick = false; needsNewPhysicalTick = false; return wasRootExec; } function endMicroTickScope() { var callbacks, i, l; do { while (microtickQueue.length > 0) { callbacks = microtickQueue; microtickQueue = []; l = callbacks.length; for (i = 0; i < l; ++i) { var item = callbacks[i]; item[0].apply(null, item[1]); } } } while (microtickQueue.length > 0); isOutsideMicroTick = true; needsNewPhysicalTick = true; } function finalizePhysicalTick() { var unhandledErrs = unhandledErrors; unhandledErrors = []; unhandledErrs.forEach(function (p) { p._PSD.onunhandled.call(null, p._value, p); }); var finalizers = tickFinalizers.slice(0); var i = finalizers.length; while (i) finalizers[--i](); } function run_at_end_of_this_or_next_physical_tick(fn) { function finalizer() { fn(); tickFinalizers.splice(tickFinalizers.indexOf(finalizer), 1); } tickFinalizers.push(finalizer); ++numScheduledCalls; asap$1(function () { if (--numScheduledCalls === 0) finalizePhysicalTick(); }, []); } function addPossiblyUnhandledError(promise) { if (!unhandledErrors.some(function (p) { return p._value === promise._value; })) unhandledErrors.push(promise); } function markErrorAsHandled(promise) { var i = unhandledErrors.length; while (i) if (unhandledErrors[--i]._value === promise._value) { unhandledErrors.splice(i, 1); return; } } function PromiseReject(reason) { return new DexiePromise(INTERNAL, false, reason); } function wrap(fn, errorCatcher) { var psd = PSD; return function () { var wasRootExec = beginMicroTickScope(), outerScope = PSD; try { switchToZone(psd, true); return fn.apply(this, arguments); } catch (e) { errorCatcher && errorCatcher(e); } finally { switchToZone(outerScope, false); if (wasRootExec) endMicroTickScope(); } }; } var task = { awaits: 0, echoes: 0, id: 0 }; var taskCounter = 0; var zoneStack = []; var zoneEchoes = 0; var totalEchoes = 0; var zone_id_counter = 0; function newScope(fn, props$$1, a1, a2) { var parent = PSD, psd = Object.create(parent); psd.parent = parent; psd.ref = 0; psd.global = false; psd.id = ++zone_id_counter; var globalEnv = globalPSD.env; psd.env = patchGlobalPromise ? { Promise: DexiePromise, PromiseProp: { value: DexiePromise, configurable: true, writable: true }, all: DexiePromise.all, race: DexiePromise.race, allSettled: DexiePromise.allSettled, any: DexiePromise.any, resolve: DexiePromise.resolve, reject: DexiePromise.reject, nthen: getPatchedPromiseThen(globalEnv.nthen, psd), gthen: getPatchedPromiseThen(globalEnv.gthen, psd) } : {}; if (props$$1) extend(psd, props$$1); ++parent.ref; psd.finalize = function () { --this.parent.ref || this.parent.finalize(); }; var rv = usePSD(psd, fn, a1, a2); if (psd.ref === 0) psd.finalize(); return rv; } function incrementExpectedAwaits() { if (!task.id) task.id = ++taskCounter; ++task.awaits; task.echoes += ZONE_ECHO_LIMIT; return task.id; } function decrementExpectedAwaits(sourceTaskId) { if (!task.awaits || (sourceTaskId && sourceTaskId !== task.id)) return; if (--task.awaits === 0) task.id = 0; task.echoes = task.awaits * ZONE_ECHO_LIMIT; } if (('' + nativePromiseThen).indexOf('[native code]') === -1) { incrementExpectedAwaits = decrementExpectedAwaits = nop; } function onPossibleParallellAsync(possiblePromise) { if (task.echoes && possiblePromise && possiblePromise.constructor === NativePromise) { incrementExpectedAwaits(); return possiblePromise.then(function (x) { decrementExpectedAwaits(); return x; }, function (e) { decrementExpectedAwaits(); return rejection(e); }); } return possiblePromise; } function zoneEnterEcho(targetZone) { ++totalEchoes; if (!task.echoes || --task.echoes === 0) { task.echoes = task.id = 0; } zoneStack.push(PSD); switchToZone(targetZone, true); } function zoneLeaveEcho() { var zone = zoneStack[zoneStack.length - 1]; zoneStack.pop(); switchToZone(zone, false); } function switchToZone(targetZone, bEnteringZone) { var currentZone = PSD; if (bEnteringZone ? task.echoes && (!zoneEchoes++ || targetZone !== PSD) : zoneEchoes && (!--zoneEchoes || targetZone !== PSD)) { enqueueNativeMicroTask(bEnteringZone ? zoneEnterEcho.bind(null, targetZone) : zoneLeaveEcho); } if (targetZone === PSD) return; PSD = targetZone; if (currentZone === globalPSD) globalPSD.env = snapShot(); if (patchGlobalPromise) { var GlobalPromise_1 = globalPSD.env.Promise; var targetEnv = targetZone.env; nativePromiseProto.then = targetEnv.nthen; GlobalPromise_1.prototype.then = targetEnv.gthen; if (currentZone.global || targetZone.global) { Object.defineProperty(_global, 'Promise', targetEnv.PromiseProp); GlobalPromise_1.all = targetEnv.all; GlobalPromise_1.race = targetEnv.race; GlobalPromise_1.resolve = targetEnv.resolve; GlobalPromise_1.reject = targetEnv.reject; if (targetEnv.allSettled) GlobalPromise_1.allSettled = targetEnv.allSettled; if (targetEnv.any) GlobalPromise_1.any = targetEnv.any; } } } function snapShot() { var GlobalPromise = _global.Promise; return patchGlobalPromise ? { Promise: GlobalPromise, PromiseProp: Object.getOwnPropertyDescriptor(_global, "Promise"), all: GlobalPromise.all, race: GlobalPromise.race, allSettled: GlobalPromise.allSettled, any: GlobalPromise.any, resolve: GlobalPromise.resolve, reject: GlobalPromise.reject, nthen: nativePromiseProto.then, gthen: GlobalPromise.prototype.then } : {}; } function usePSD(psd, fn, a1, a2, a3) { var outerScope = PSD; try { switchToZone(psd, true); return fn(a1, a2, a3); } finally { switchToZone(outerScope, false); } } function enqueueNativeMicroTask(job) { nativePromiseThen.call(resolvedNativePromise, job); } function nativeAwaitCompatibleWrap(fn, zone, possibleAwait) { return typeof fn !== 'function' ? fn : function () { var outerZone = PSD; if (possibleAwait) incrementExpectedAwaits(); switchToZone(zone, true); try { return fn.apply(this, arguments); } finally { switchToZone(outerZone, false); } }; } function getPatchedPromiseThen(origThen, zone) { return function (onResolved, onRejected) { return origThen.call(this, nativeAwaitCompatibleWrap(onResolved, zone, false), nativeAwaitCompatibleWrap(onRejected, zone, false)); }; } var UNHANDLEDREJECTION = "unhandledrejection"; function globalError(err, promise) { var rv; try { rv = promise.onuncatched(err); } catch (e) { } if (rv !== false) try { var event, eventData = { promise: promise, reason: err }; if (_global.document && document.createEvent) { event = document.createEvent('Event'); event.initEvent(UNHANDLEDREJECTION, true, true); extend(event, eventData); } else if (_global.CustomEvent) { event = new CustomEvent(UNHANDLEDREJECTION, { detail: eventData }); extend(event, eventData); } if (event && _global.dispatchEvent) { dispatchEvent(event); if (!_global.PromiseRejectionEvent && _global.onunhandledrejection) try { _global.onunhandledrejection(event); } catch (_) { } } if (debug && event && !event.defaultPrevented) { console.warn("Unhandled rejection: " + (err.stack || err)); } } catch (e) { } } var rejection = DexiePromise.reject; function tempTransaction(db, mode, storeNames, fn) { if (!db._state.openComplete && (!PSD.letThrough)) { if (!db._state.isBeingOpened) { if (!db._options.autoOpen) return rejection(new exceptions.DatabaseClosed()); db.open().catch(nop); } return db._state.dbReadyPromise.then(function () { return tempTransaction(db, mode, storeNames, fn); }); } else { var trans = db._createTransaction(mode, storeNames, db._dbSchema); try { trans.create(); } catch (ex) { return rejection(ex); } return trans._promise(mode, function (resolve, reject) { return newScope(function () { PSD.trans = trans; return fn(resolve, reject, trans); }); }).then(function (result) { return trans._completion.then(function () { return result; }); }); } } var DEXIE_VERSION = '3.0.2'; var maxString = String.fromCharCode(65535); var minKey = -Infinity; var INVALID_KEY_ARGUMENT = "Invalid key provided. Keys must be of type string, number, Date or Array."; var STRING_EXPECTED = "String expected."; var connections = []; var isIEOrEdge = typeof navigator !== 'undefined' && /(MSIE|Trident|Edge)/.test(navigator.userAgent); var hasIEDeleteObjectStoreBug = isIEOrEdge; var hangsOnDeleteLargeKeyRange = isIEOrEdge; var dexieStackFrameFilter = function (frame) { return !/(dexie\.js|dexie\.min\.js)/.test(frame); }; var DBNAMES_DB = '__dbnames'; var READONLY = 'readonly'; var READWRITE = 'readwrite'; function combine(filter1, filter2) { return filter1 ? filter2 ? function () { return filter1.apply(this, arguments) && filter2.apply(this, arguments); } : filter1 : filter2; } var AnyRange = { type: 3 , lower: -Infinity, lowerOpen: false, upper: [[]], upperOpen: false }; var Table = (function () { function Table() { } Table.prototype._trans = function (mode, fn, writeLocked) { var trans = this._tx || PSD.trans; var tableName = this.name; function checkTableInTransaction(resolve, reject, trans) { if (!trans.schema[tableName]) throw new exceptions.NotFound("Table " + tableName + " not part of transaction"); return fn(trans.idbtrans, trans); } var wasRootExec = beginMicroTickScope(); try { return trans && trans.db === this.db ? trans === PSD.trans ? trans._promise(mode, checkTableInTransaction, writeLocked) : newScope(function () { return trans._promise(mode, checkTableInTransaction, writeLocked); }, { trans: trans, transless: PSD.transless || PSD }) : tempTransaction(this.db, mode, [this.name], checkTableInTransaction); } finally { if (wasRootExec) endMicroTickScope(); } }; Table.prototype.get = function (keyOrCrit, cb) { var _this = this; if (keyOrCrit && keyOrCrit.constructor === Object) return this.where(keyOrCrit).first(cb); return this._trans('readonly', function (trans) { return _this.core.get({ trans: trans, key: keyOrCrit }) .then(function (res) { return _this.hook.reading.fire(res); }); }).then(cb); }; Table.prototype.where = function (indexOrCrit) { if (typeof indexOrCrit === 'string') return new this.db.WhereClause(this, indexOrCrit); if (isArray(indexOrCrit)) return new this.db.WhereClause(this, "[" + indexOrCrit.join('+') + "]"); var keyPaths = keys(indexOrCrit); if (keyPaths.length === 1) return this .where(keyPaths[0]) .equals(indexOrCrit[keyPaths[0]]); var compoundIndex = this.schema.indexes.concat(this.schema.primKey).filter(function (ix) { return ix.compound && keyPaths.every(function (keyPath) { return ix.keyPath.indexOf(keyPath) >= 0; }) && ix.keyPath.every(function (keyPath) { return keyPaths.indexOf(keyPath) >= 0; }); })[0]; if (compoundIndex && this.db._maxKey !== maxString) return this .where(compoundIndex.name) .equals(compoundIndex.keyPath.map(function (kp) { return indexOrCrit[kp]; })); if (!compoundIndex && debug) console.warn("The query " + JSON.stringify(indexOrCrit) + " on " + this.name + " would benefit of a " + ("compound index [" + keyPaths.join('+') + "]")); var idxByName = this.schema.idxByName; var idb = this.db._deps.indexedDB; function equals(a, b) { try { return idb.cmp(a, b) === 0; } catch (e) { return false; } } var _a = keyPaths.reduce(function (_a, keyPath) { var prevIndex = _a[0], prevFilterFn = _a[1]; var index = idxByName[keyPath]; var value = indexOrCrit[keyPath]; return [ prevIndex || index, prevIndex || !index ? combine(prevFilterFn, index && index.multi ? function (x) { var prop = getByKeyPath(x, keyPath); return isArray(prop) && prop.some(function (item) { return equals(value, item); }); } : function (x) { return equals(value, getByKeyPath(x, keyPath)); }) : prevFilterFn ]; }, [null, null]), idx = _a[0], filterFunction = _a[1]; return idx ? this.where(idx.name).equals(indexOrCrit[idx.keyPath]) .filter(filterFunction) : compoundIndex ? this.filter(filterFunction) : this.where(keyPaths).equals(''); }; Table.prototype.filter = function (filterFunction) { return this.toCollection().and(filterFunction); }; Table.prototype.count = function (thenShortcut) { return this.toCollection().count(thenShortcut); }; Table.prototype.offset = function (offset) { return this.toCollection().offset(offset); }; Table.prototype.limit = function (numRows) { return this.toCollection().limit(numRows); }; Table.prototype.each = function (callback) { return this.toCollection().each(callback); }; Table.prototype.toArray = function (thenShortcut) { return this.toCollection().toArray(thenShortcut); }; Table.prototype.toCollection = function () { return new this.db.Collection(new this.db.WhereClause(this)); }; Table.prototype.orderBy = function (index) { return new this.db.Collection(new this.db.WhereClause(this, isArray(index) ? "[" + index.join('+') + "]" : index)); }; Table.prototype.reverse = function () { return this.toCollection().reverse(); }; Table.prototype.mapToClass = function (constructor) { this.schema.mappedClass = constructor; var readHook = function (obj) { if (!obj) return obj; var res = Object.create(constructor.prototype); for (var m in obj) if (hasOwn(obj, m)) try { res[m] = obj[m]; } catch (_) { } return res; }; if (this.schema.readHook) { this.hook.reading.unsubscribe(this.schema.readHook); } this.schema.readHook = readHook; this.hook("reading", readHook); return constructor; }; Table.prototype.defineClass = function () { function Class(content) { extend(this, content); } return this.mapToClass(Class); }; Table.prototype.add = function (obj, key) { var _this = this; return this._trans('readwrite', function (trans) { return _this.core.mutate({ trans: trans, type: 'add', keys: key != null ? [key] : null, values: [obj] }); }).then(function (res) { return res.numFailures ? DexiePromise.reject(res.failures[0]) : res.lastResult; }) .then(function (lastResult) { if (!_this.core.schema.primaryKey.outbound) { try { setByKeyPath(obj, _this.core.schema.primaryKey.keyPath, lastResult); } catch (_) { } } return lastResult; }); }; Table.prototype.update = function (keyOrObject, modifications) { if (typeof modifications !== 'object' || isArray(modifications)) throw new exceptions.InvalidArgument("Modifications must be an object."); if (typeof keyOrObject === 'object' && !isArray(keyOrObject)) { keys(modifications).forEach(function (keyPath) { setByKeyPath(keyOrObject, keyPath, modifications[keyPath]); }); var key = getByKeyPath(keyOrObject, this.schema.primKey.keyPath); if (key === undefined) return rejection(new exceptions.InvalidArgument("Given object does not contain its primary key")); return this.where(":id").equals(key).modify(modifications); } else { return this.where(":id").equals(keyOrObject).modify(modifications); } }; Table.prototype.put = function (obj, key) { var _this = this; return this._trans('readwrite', function (trans) { return _this.core.mutate({ trans: trans, type: 'put', values: [obj], keys: key != null ? [key] : null }); }) .then(function (res) { return res.numFailures ? DexiePromise.reject(res.failures[0]) : res.lastResult; }) .then(function (lastResult) { if (!_this.core.schema.primaryKey.outbound) { try { setByKeyPath(obj, _this.core.schema.primaryKey.keyPath, lastResult); } catch (_) { } } return lastResult; }); }; Table.prototype.delete = function (key) { var _this = this; return this._trans('readwrite', function (trans) { return _this.core.mutate({ trans: trans, type: 'delete', keys: [key] }); }) .then(function (res) { return res.numFailures ? DexiePromise.reject(res.failures[0]) : undefined; }); }; Table.prototype.clear = function () { var _this = this; return this._trans('readwrite', function (trans) { return _this.core.mutate({ trans: trans, type: 'deleteRange', range: AnyRange }); }) .then(function (res) { return res.numFailures ? DexiePromise.reject(res.failures[0]) : undefined; }); }; Table.prototype.bulkGet = function (keys$$1) { var _this = this; return this._trans('readonly', function (trans) { return _this.core.getMany({ keys: keys$$1, trans: trans }).then(function (result) { return result.map(function (res) { return _this.hook.reading.fire(res); }); }); }); }; Table.prototype.bulkAdd = function (objects, keysOrOptions, options) { var _this = this; var keys$$1 = Array.isArray(keysOrOptions) ? keysOrOptions : undefined; options = options || (keys$$1 ? undefined : keysOrOptions); var wantResults = options ? options.allKeys : undefined; return this._trans('readwrite', function (trans) { var outbound = _this.core.schema.primaryKey.outbound; if (!outbound && keys$$1) throw new exceptions.InvalidArgument("bulkAdd(): keys argument invalid on tables with inbound keys"); if (keys$$1 && keys$$1.length !== objects.length) throw new exceptions.InvalidArgument("Arguments objects and keys must have the same length"); var numObjects = objects.length; return _this.core.mutate({ trans: trans, type: 'add', keys: keys$$1, values: objects, wantResults: wantResults }) .then(function (_a) { var numFailures = _a.numFailures, results = _a.results, lastResult = _a.lastResult, failures = _a.failures; var result = wantResults ? results : lastResult; if (numFailures === 0) return result; throw new BulkError(_this.name + ".bulkAdd(): " + numFailures + " of " + numObjects + " operations failed", Object.keys(failures).map(function (pos) { return failures[pos]; })); }); }); }; Table.prototype.bulkPut = function (objects, keysOrOptions, options) { var _this = this; var keys$$1 = Array.isArray(keysOrOptions) ? keysOrOptions : undefined; options = options || (keys$$1 ? undefined : keysOrOptions); var wantResults = options ? options.allKeys : undefined; return this._trans('readwrite', function (trans) { var outbound = _this.core.schema.primaryKey.outbound; if (!outbound && keys$$1) throw new exceptions.InvalidArgument("bulkPut(): keys argument invalid on tables with inbound keys"); if (keys$$1 && keys$$1.length !== objects.length) throw new exceptions.InvalidArgument("Arguments objects and keys must have the same length"); var numObjects = objects.length; return _this.core.mutate({ trans: trans, type: 'put', keys: keys$$1, values: objects, wantResults: wantResults }) .then(function (_a) { var numFailures = _a.numFailures, results = _a.results, lastResult = _a.lastResult, failures = _a.failures; var result = wantResults ? results : lastResult; if (numFailures === 0) return result; throw new BulkError(_this.name + ".bulkPut(): " + numFailures + " of " + numObjects + " operations failed", Object.keys(failures).map(function (pos) { return failures[pos]; })); }); }); }; Table.prototype.bulkDelete = function (keys$$1) { var _this = this; var numKeys = keys$$1.length; return this._trans('readwrite', function (trans) { return _this.core.mutate({ trans: trans, type: 'delete', keys: keys$$1 }); }).then(function (_a) { var numFailures = _a.numFailures, lastResult = _a.lastResult, failures = _a.failures; if (numFailures === 0) return lastResult; throw new BulkError(_this.name + ".bulkDelete(): " + numFailures + " of " + numKeys + " operations failed", failures); }); }; return Table; }()); function Events(ctx) { var evs = {}; var rv = function (eventName, subscriber) { if (subscriber) { var i = arguments.length, args = new Array(i - 1); while (--i) args[i - 1] = arguments[i]; evs[eventName].subscribe.apply(null, args); return ctx; } else if (typeof (eventName) === 'string') { return evs[eventName]; } }; rv.addEventType = add; for (var i = 1, l = arguments.length; i < l; ++i) { add(arguments[i]); } return rv; function add(eventName, chainFunction, defaultFunction) { if (typeof eventName === 'object') return addConfiguredEvents(eventName); if (!chainFunction) chainFunction = reverseStoppableEventChain; if (!defaultFunction) defaultFunction = nop; var context = { subscribers: [], fire: defaultFunction, subscribe: function (cb) { if (context.subscribers.indexOf(cb) === -1) { context.subscribers.push(cb); context.fire = chainFunction(context.fire, cb); } }, unsubscribe: function (cb) { context.subscribers = context.subscribers.filter(function (fn) { return fn !== cb; }); context.fire = context.subscribers.reduce(chainFunction, defaultFunction); } }; evs[eventName] = rv[eventName] = context; return context; } function addConfiguredEvents(cfg) { keys(cfg).forEach(function (eventName) { var args = cfg[eventName]; if (isArray(args)) { add(eventName, cfg[eventName][0], cfg[eventName][1]); } else if (args === 'asap') { var context = add(eventName, mirror, function fire() { var i = arguments.length, args = new Array(i); while (i--) args[i] = arguments[i]; context.subscribers.forEach(function (fn) { asap(function fireEvent() { fn.apply(null, args); }); }); }); } else throw new exceptions.InvalidArgument("Invalid event config"); }); } } function makeClassConstructor(prototype, constructor) { derive(constructor).from({ prototype: prototype }); return constructor; } function createTableConstructor(db) { return makeClassConstructor(Table.prototype, function Table$$1(name, tableSchema, trans) { this.db = db; this._tx = trans; this.name = name; this.schema = tableSchema; this.hook = db._allTables[name] ? db._allTables[name].hook : Events(null, { "creating": [hookCreatingChain, nop], "reading": [pureFunctionChain, mirror], "updating": [hookUpdatingChain, nop], "deleting": [hookDeletingChain, nop] }); }); } function isPlainKeyRange(ctx, ignoreLimitFilter) { return !(ctx.filter || ctx.algorithm || ctx.or) && (ignoreLimitFilter ? ctx.justLimit : !ctx.replayFilter); } function addFilter(ctx, fn) { ctx.filter = combine(ctx.filter, fn); } function addReplayFilter(ctx, factory, isLimitFilter) { var curr = ctx.replayFilter; ctx.replayFilter = curr ? function () { return combine(curr(), factory()); } : factory; ctx.justLimit = isLimitFilter && !curr; } function addMatchFilter(ctx, fn) { ctx.isMatch = combine(ctx.isMatch, fn); } function getIndexOrStore(ctx, coreSchema) { if (ctx.isPrimKey) return coreSchema.primaryKey; var index = coreSchema.getIndexByKeyPath(ctx.index); if (!index) throw new exceptions.Schema("KeyPath " + ctx.index + " on object store " + coreSchema.name + " is not indexed"); return index; } function openCursor(ctx, coreTable, trans) { var index = getIndexOrStore(ctx, coreTable.schema); return coreTable.openCursor({ trans: trans, values: !ctx.keysOnly, reverse: ctx.dir === 'prev', unique: !!ctx.unique, query: { index: index, range: ctx.range } }); } function iter(ctx, fn, coreTrans, coreTable) { var filter = ctx.replayFilter ? combine(ctx.filter, ctx.replayFilter()) : ctx.filter; if (!ctx.or) { return iterate(openCursor(ctx, coreTable, coreTrans), combine(ctx.algorithm, filter), fn, !ctx.keysOnly && ctx.valueMapper); } else { var set_1 = {}; var union = function (item, cursor, advance) { if (!filter || filter(cursor, advance, function (result) { return cursor.stop(result); }, function (err) { return cursor.fail(err); })) { var primaryKey = cursor.primaryKey; var key = '' + primaryKey; if (key === '[object ArrayBuffer]') key = '' + new Uint8Array(primaryKey); if (!hasOwn(set_1, key)) { set_1[key] = true; fn(item, cursor, advance); } } }; return Promise.all([ ctx.or._iterate(union, coreTrans), iterate(openCursor(ctx, coreTable, coreTrans), ctx.algorithm, union, !ctx.keysOnly && ctx.valueMapper) ]); } } function iterate(cursorPromise, filter, fn, valueMapper) { var mappedFn = valueMapper ? function (x, c, a) { return fn(valueMapper(x), c, a); } : fn; var wrappedFn = wrap(mappedFn); return cursorPromise.then(function (cursor) { if (cursor) { return cursor.start(function () { var c = function () { return cursor.continue(); }; if (!filter || filter(cursor, function (advancer) { return c = advancer; }, function (val) { cursor.stop(val); c = nop; }, function (e) { cursor.fail(e); c = nop; })) wrappedFn(cursor.value, cursor, function (advancer) { return c = advancer; }); c(); }); } }); } var Collection = (function () { function Collection() { } Collection.prototype._read = function (fn, cb) { var ctx = this._ctx; return ctx.error ? ctx.table._trans(null, rejection.bind(null, ctx.error)) : ctx.table._trans('readonly', fn).then(cb); }; Collection.prototype._write = function (fn) { var ctx = this._ctx; return ctx.error ? ctx.table._trans(null, rejection.bind(null, ctx.error)) : ctx.table._trans('readwrite', fn, "locked"); }; Collection.prototype._addAlgorithm = function (fn) { var ctx = this._ctx; ctx.algorithm = combine(ctx.algorithm, fn); }; Collection.prototype._iterate = function (fn, coreTrans) { return iter(this._ctx, fn, coreTrans, this._ctx.table.core); }; Collection.prototype.clone = function (props$$1) { var rv = Object.create(this.constructor.prototype), ctx = Object.create(this._ctx); if (props$$1) extend(ctx, props$$1); rv._ctx = ctx; return rv; }; Collection.prototype.raw = function () { this._ctx.valueMapper = null; return this; }; Collection.prototype.each = function (fn) { var ctx = this._ctx; return this._read(function (trans) { return iter(ctx, fn, trans, ctx.table.core); }); }; Collection.prototype.count = function (cb) { var _this = this; return this._read(function (trans) { var ctx = _this._ctx; var coreTable = ctx.table.core; if (isPlainKeyRange(ctx, true)) { return coreTable.count({ trans: trans, query: { index: getIndexOrStore(ctx, coreTable.schema), range: ctx.range } }).then(function (count) { return Math.min(count, ctx.limit); }); } else { var count = 0; return iter(ctx, function () { ++count; return false; }, trans, coreTable) .then(function () { return count; }); } }).then(cb); }; Collection.prototype.sortBy = function (keyPath, cb) { var parts = keyPath.split('.').reverse(), lastPart = parts[0], lastIndex = parts.length - 1; function getval(obj, i) { if (i) return getval(obj[parts[i]], i - 1); return obj[lastPart]; } var order = this._ctx.dir === "next" ? 1 : -1; function sorter(a, b) { var aVal = getval(a, lastIndex), bVal = getval(b, lastIndex); return aVal < bVal ? -order : aVal > bVal ? order : 0; } return this.toArray(function (a) { return a.sort(sorter); }).then(cb); }; Collection.prototype.toArray = function (cb) { var _this = this; return this._read(function (trans) { var ctx = _this._ctx; if (ctx.dir === 'next' && isPlainKeyRange(ctx, true) && ctx.limit > 0) { var valueMapper_1 = ctx.valueMapper; var index = getIndexOrStore(ctx, ctx.table.core.schema); return ctx.table.core.query({ trans: trans, limit: ctx.limit, values: true, query: { index: index, range: ctx.range } }).then(function (_a) { var result = _a.result; return valueMapper_1 ? result.map(valueMapper_1) : result; }); } else { var a_1 = []; return iter(ctx, function (item) { return a_1.push(item); }, trans, ctx.table.core).then(function () { return a_1; }); } }, cb); }; Collection.prototype.offset = function (offset) { var ctx = this._ctx; if (offset <= 0) return this; ctx.offset += offset; if (isPlainKeyRange(ctx)) { addReplayFilter(ctx, function () { var offsetLeft = offset; return function (cursor, advance) { if (offsetLeft === 0) return true; if (offsetLeft === 1) { --offsetLeft; return false; } advance(function () { cursor.advance(offsetLeft); offsetLeft = 0; }); return false; }; }); } else { addReplayFilter(ctx, function () { var offsetLeft = offset; return function () { return (--offsetLeft < 0); }; }); } return this; }; Collection.prototype.limit = function (numRows) { this._ctx.limit = Math.min(this._ctx.limit, numRows); addReplayFilter(this._ctx, function () { var rowsLeft = numRows; return function (cursor, advance, resolve) { if (--rowsLeft <= 0) advance(resolve); return rowsLeft >= 0; }; }, true); return this; }; Collection.prototype.until = function (filterFunction, bIncludeStopEntry) { addFilter(this._ctx, function (cursor, advance, resolve) { if (filterFunction(cursor.value)) { advance(resolve); return bIncludeStopEntry; } else { return true; } }); return this; }; Collection.prototype.first = function (cb) { return this.limit(1).toArray(function (a) { return a[0]; }).then(cb); }; Collection.prototype.last = function (cb) { return this.reverse().first(cb); }; Collection.prototype.filter = function (filterFunction) { addFilter(this._ctx, function (cursor) { return filterFunction(cursor.value); }); addMatchFilter(this._ctx, filterFunction); return this; }; Collection.prototype.and = function (filter) { return this.filter(filter); }; Collection.prototype.or = function (indexName) { return new this.db.WhereClause(this._ctx.table, indexName, this); }; Collection.prototype.reverse = function () { this._ctx.dir = (this._ctx.dir === "prev" ? "next" : "prev"); if (this._ondirectionchange) this._ondirectionchange(this._ctx.dir); return this; }; Collection.prototype.desc = function () { return this.reverse(); }; Collection.prototype.eachKey = function (cb) { var ctx = this._ctx; ctx.keysOnly = !ctx.isMatch; return this.each(function (val, cursor) { cb(cursor.key, cursor); }); }; Collection.prototype.eachUniqueKey = function (cb) { this._ctx.unique = "unique"; return this.eachKey(cb); }; Collection.prototype.eachPrimaryKey = function (cb) { var ctx = this._ctx; ctx.keysOnly = !ctx.isMatch; return this.each(function (val, cursor) { cb(cursor.primaryKey, cursor); }); }; Collection.prototype.keys = function (cb) { var ctx = this._ctx; ctx.keysOnly = !ctx.isMatch; var a = []; return this.each(function (item, cursor) { a.push(cursor.key); }).then(function () { return a; }).then(cb); }; Collection.prototype.primaryKeys = function (cb) { var ctx = this._ctx; if (ctx.dir === 'next' && isPlainKeyRange(ctx, true) && ctx.limit > 0) { return this._read(function (trans) { var index = getIndexOrStore(ctx, ctx.table.core.schema); return ctx.table.core.query({ trans: trans, values: false, limit: ctx.limit, query: { index: index, range: ctx.range } }); }).then(function (_a) { var result = _a.result; return result; }).then(cb); } ctx.keysOnly = !ctx.isMatch; var a = []; return this.each(function (item, cursor) { a.push(cursor.primaryKey); }).then(function () { return a; }).then(cb); }; Collection.prototype.uniqueKeys = function (cb) { this._ctx.unique = "unique"; return this.keys(cb); }; Collection.prototype.firstKey = function (cb) { return this.limit(1).keys(function (a) { return a[0]; }).then(cb); }; Collection.prototype.lastKey = function (cb) { return this.reverse().firstKey(cb); }; Collection.prototype.distinct = function () { var ctx = this._ctx, idx = ctx.index && ctx.table.schema.idxByName[ctx.index]; if (!idx || !idx.multi) return this; var set = {}; addFilter(this._ctx, function (cursor) { var strKey = cursor.primaryKey.toString(); var found = hasOwn(set, strKey); set[strKey] = true; return !found; }); return this; }; Collection.prototype.modify = function (changes) { var _this = this; var ctx = this._ctx; return this._write(function (trans) { var modifyer; if (typeof changes === 'function') { modifyer = changes; } else { var keyPaths = keys(changes); var numKeys = keyPaths.length; modifyer = function (item) { var anythingModified = false; for (var i = 0; i < numKeys; ++i) { var keyPath = keyPaths[i], val = changes[keyPath]; if (getByKeyPath(item, keyPath) !== val) { setByKeyPath(item, keyPath, val); anythingModified = true; } } return anythingModified; }; } var coreTable = ctx.table.core; var _a = coreTable.schema.primaryKey, outbound = _a.outbound, extractKey = _a.extractKey; var limit = 'testmode' in Dexie ? 1 : 2000; var cmp = _this.db.core.cmp; var totalFailures = []; var successCount = 0; var failedKeys = []; var applyMutateResult = function (expectedCount, res) { var failures = res.failures, numFailures = res.numFailures; successCount += expectedCount - numFailures; for (var _i = 0, _a = keys(failures); _i < _a.length; _i++) { var pos = _a[_i]; totalFailures.push(failures[pos]); } }; return _this.clone().primaryKeys().then(function (keys$$1) { var nextChunk = function (offset) { var count = Math.min(limit, keys$$1.length - offset); return coreTable.getMany({ trans: trans, keys: keys$$1.slice(offset, offset + count) }).then(function (values) { var addValues = []; var putValues = []; var putKeys = outbound ? [] : null; var deleteKeys = []; for (var i = 0; i < count; ++i) { var origValue = values[i]; var ctx_1 = { value: deepClone(origValue), primKey: keys$$1[offset + i] }; if (modifyer.call(ctx_1, ctx_1.value, ctx_1) !== false) { if (ctx_1.value == null) { deleteKeys.push(keys$$1[offset + i]); } else if (!outbound && cmp(extractKey(origValue), extractKey(ctx_1.value)) !== 0) { deleteKeys.push(keys$$1[offset + i]); addValues.push(ctx_1.value); } else { putValues.push(ctx_1.value); if (outbound) putKeys.push(keys$$1[offset + i]); } } } return Promise.resolve(addValues.length > 0 && coreTable.mutate({ trans: trans, type: 'add', values: addValues }) .then(function (res) { for (var pos in res.failures) { deleteKeys.splice(parseInt(pos), 1); } applyMutateResult(addValues.length, res); })).then(function (res) { return putValues.length > 0 && coreTable.mutate({ trans: trans, type: 'put', keys: putKeys, values: putValues }) .then(function (res) { return applyMutateResult(putValues.length, res); }); }).then(function () { return deleteKeys.length > 0 && coreTable.mutate({ trans: trans, type: 'delete', keys: deleteKeys }) .then(function (res) { return applyMutateResult(deleteKeys.length, res); }); }).then(function () { return keys$$1.length > offset + count && nextChunk(offset + limit); }); }); }; return nextChunk(0).then(function () { if (totalFailures.length > 0) throw new ModifyError("Error modifying one or more objects", totalFailures, successCount, failedKeys); return keys$$1.length; }); }); }); }; Collection.prototype.delete = function () { var ctx = this._ctx, range = ctx.range; if (isPlainKeyRange(ctx) && ((ctx.isPrimKey && !hangsOnDeleteLargeKeyRange) || range.type === 3 )) { return this._write(function (trans) { var primaryKey = ctx.table.core.schema.primaryKey; var coreRange = range; return ctx.table.core.count({ trans: trans, query: { index: primaryKey, range: coreRange } }).then(function (count) { return ctx.table.core.mutate({ trans: trans, type: 'deleteRange', range: coreRange }) .then(function (_a) { var failures = _a.failures, lastResult = _a.lastResult, results = _a.results, numFailures = _a.numFailures; if (numFailures) throw new ModifyError("Could not delete some values", Object.keys(failures).map(function (pos) { return failures[pos]; }), count - numFailures); return count - numFailures; }); }); }); } return this.modify(function (value, ctx) { return ctx.value = null; }); }; return Collection; }()); function createCollectionConstructor(db) { return makeClassConstructor(Collection.prototype, function Collection$$1(whereClause, keyRangeGenerator) { this.db = db; var keyRange = AnyRange, error = null; if (keyRangeGenerator) try { keyRange = keyRangeGenerator(); } catch (ex) { error = ex; } var whereCtx = whereClause._ctx; var table = whereCtx.table; var readingHook = table.hook.reading.fire; this._ctx = { table: table, index: whereCtx.index, isPrimKey: (!whereCtx.index || (table.schema.primKey.keyPath && whereCtx.index === table.schema.primKey.name)), range: keyRange, keysOnly: false, dir: "next", unique: "", algorithm: null, filter: null, replayFilter: null, justLimit: true, isMatch: null, offset: 0, limit: Infinity, error: error, or: whereCtx.or, valueMapper: readingHook !== mirror ? readingHook : null }; }); } function simpleCompare(a, b) { return a < b ? -1 : a === b ? 0 : 1; } function simpleCompareReverse(a, b) { return a > b ? -1 : a === b ? 0 : 1; } function fail(collectionOrWhereClause, err, T) { var collection = collectionOrWhereClause instanceof WhereClause ? new collectionOrWhereClause.Collection(collectionOrWhereClause) : collectionOrWhereClause; collection._ctx.error = T ? new T(err) : new TypeError(err); return collection; } function emptyCollection(whereClause) { return new whereClause.Collection(whereClause, function () { return rangeEqual(""); }).limit(0); } function upperFactory(dir) { return dir === "next" ? function (s) { return s.toUpperCase(); } : function (s) { return s.toLowerCase(); }; } function lowerFactory(dir) { return dir === "next" ? function (s) { return s.toLowerCase(); } : function (s) { return s.toUpperCase(); }; } function nextCasing(key, lowerKey, upperNeedle, lowerNeedle, cmp, dir) { var length = Math.min(key.length, lowerNeedle.length); var llp = -1; for (var i = 0; i < length; ++i) { var lwrKeyChar = lowerKey[i]; if (lwrKeyChar !== lowerNeedle[i]) { if (cmp(key[i], upperNeedle[i]) < 0) return key.substr(0, i) + upperNeedle[i] + upperNeedle.substr(i + 1); if (cmp(key[i], lowerNeedle[i]) < 0) return key.substr(0, i) + lowerNeedle[i] + upperNeedle.substr(i + 1); if (llp >= 0) return key.substr(0, llp) + lowerKey[llp] + upperNeedle.substr(llp + 1); return null; } if (cmp(key[i], lwrKeyChar) < 0) llp = i; } if (length < lowerNeedle.length && dir === "next") return key + upperNeedle.substr(key.length); if (length < key.length && dir === "prev") return key.substr(0, upperNeedle.length); return (llp < 0 ? null : key.substr(0, llp) + lowerNeedle[llp] + upperNeedle.substr(llp + 1)); } function addIgnoreCaseAlgorithm(whereClause, match, needles, suffix) { var upper, lower, compare, upperNeedles, lowerNeedles, direction, nextKeySuffix, needlesLen = needles.length; if (!needles.every(function (s) { return typeof s === 'string'; })) { return fail(whereClause, STRING_EXPECTED); } function initDirection(dir) { upper = upperFactory(dir); lower = lowerFactory(dir); compare = (dir === "next" ? simpleCompare : simpleCompareReverse); var needleBounds = needles.map(function (needle) { return { lower: lower(needle), upper: upper(needle) }; }).sort(function (a, b) { return compare(a.lower, b.lower); }); upperNeedles = needleBounds.map(function (nb) { return nb.upper; }); lowerNeedles = needleBounds.map(function (nb) { return nb.lower; }); direction = dir; nextKeySuffix = (dir === "next" ? "" : suffix); } initDirection("next"); var c = new whereClause.Collection(whereClause, function () { return createRange(upperNeedles[0], lowerNeedles[needlesLen - 1] + suffix); }); c._ondirectionchange = function (direction) { initDirection(direction); }; var firstPossibleNeedle = 0; c._addAlgorithm(function (cursor, advance, resolve) { var key = cursor.key; if (typeof key !== 'string') return false; var lowerKey = lower(key); if (match(lowerKey, lowerNeedles, firstPossibleNeedle)) { return true; } else { var lowestPossibleCasing = null; for (var i = firstPossibleNeedle; i < needlesLen; ++i) { var casing = nextCasing(key, lowerKey, upperNeedles[i], lowerNeedles[i], compare, direction); if (casing === null && lowestPossibleCasing === null) firstPossibleNeedle = i + 1; else if (lowestPossibleCasing === null || compare(lowestPossibleCasing, casing) > 0) { lowestPossibleCasing = casing; } } if (lowestPossibleCasing !== null) { advance(function () { cursor.continue(lowestPossibleCasing + nextKeySuffix); }); } else { advance(resolve); } return false; } }); return c; } function createRange(lower, upper, lowerOpen, upperOpen) { return { type: 2 , lower: lower, upper: upper, lowerOpen: lowerOpen, upperOpen: upperOpen }; } function rangeEqual(value) { return { type: 1 , lower: value, upper: value }; } var WhereClause = (function () { function WhereClause() { } Object.defineProperty(WhereClause.prototype, "Collection", { get: function () { return this._ctx.table.db.Collection; }, enumerable: true, configurable: true }); WhereClause.prototype.between = function (lower, upper, includeLower, includeUpper) { includeLower = includeLower !== false; includeUpper = includeUpper === true; try { if ((this._cmp(lower, upper) > 0) || (this._cmp(lower, upper) === 0 && (includeLower || includeUpper) && !(includeLower && includeUpper))) return emptyCollection(this); return new this.Collection(this, function () { return createRange(lower, upper, !includeLower, !includeUpper); }); } catch (e) { return fail(this, INVALID_KEY_ARGUMENT); } }; WhereClause.prototype.equals = function (value) { return new this.Collection(this, function () { return rangeEqual(value); }); }; WhereClause.prototype.above = function (value) { if (value == null) return fail(this, INVALID_KEY_ARGUMENT); return new this.Collection(this, function () { return createRange(value, undefined, true); }); }; WhereClause.prototype.aboveOrEqual = function (value) { if (value == null) return fail(this, INVALID_KEY_ARGUMENT); return new this.Collection(this, function () { return createRange(value, undefined, false); }); }; WhereClause.prototype.below = function (value) { if (value == null) return fail(this, INVALID_KEY_ARGUMENT); return new this.Collection(this, function () { return createRange(undefined, value, false, true); }); }; WhereClause.prototype.belowOrEqual = function (value) { if (value == null) return fail(this, INVALID_KEY_ARGUMENT); return new this.Collection(this, function () { return createRange(undefined, value); }); }; WhereClause.prototype.startsWith = function (str) { if (typeof str !== 'string') return fail(this, STRING_EXPECTED); return this.between(str, str + maxString, true, true); }; WhereClause.prototype.startsWithIgnoreCase = function (str) { if (str === "") return this.startsWith(str); return addIgnoreCaseAlgorithm(this, function (x, a) { return x.indexOf(a[0]) === 0; }, [str], maxString); }; WhereClause.prototype.equalsIgnoreCase = function (str) { return addIgnoreCaseAlgorithm(this, function (x, a) { return x === a[0]; }, [str], ""); }; WhereClause.prototype.anyOfIgnoreCase = function () { var set = getArrayOf.apply(NO_CHAR_ARRAY, arguments); if (set.length === 0) return emptyCollection(this); return addIgnoreCaseAlgorithm(this, function (x, a) { return a.indexOf(x) !== -1; }, set, ""); }; WhereClause.prototype.startsWithAnyOfIgnoreCase = function () { var set = getArrayOf.apply(NO_CHAR_ARRAY, arguments); if (set.length === 0) return emptyCollection(this); return addIgnoreCaseAlgorithm(this, function (x, a) { return a.some(function (n) { return x.indexOf(n) === 0; }); }, set, maxString); }; WhereClause.prototype.anyOf = function () { var _this = this; var set = getArrayOf.apply(NO_CHAR_ARRAY, arguments); var compare = this._cmp; try { set.sort(compare); } catch (e) { return fail(this, INVALID_KEY_ARGUMENT); } if (set.length === 0) return emptyCollection(this); var c = new this.Collection(this, function () { return createRange(set[0], set[set.length - 1]); }); c._ondirectionchange = function (direction) { compare = (direction === "next" ? _this._ascending : _this._descending); set.sort(compare); }; var i = 0; c._addAlgorithm(function (cursor, advance, resolve) { var key = cursor.key; while (compare(key, set[i]) > 0) { ++i; if (i === set.length) { advance(resolve); return false; } } if (compare(key, set[i]) === 0) { return true; } else { advance(function () { cursor.continue(set[i]); }); return false; } }); return c; }; WhereClause.prototype.notEqual = function (value) { return this.inAnyRange([[minKey, value], [value, this.db._maxKey]], { includeLowers: false, includeUppers: false }); }; WhereClause.prototype.noneOf = function () { var set = getArrayOf.apply(NO_CHAR_ARRAY, arguments); if (set.length === 0) return new this.Collection(this); try { set.sort(this._ascending); } catch (e) { return fail(this, INVALID_KEY_ARGUMENT); } var ranges = set.reduce(function (res, val) { return res ? res.concat([[res[res.length - 1][1], val]]) : [[minKey, val]]; }, null); ranges.push([set[set.length - 1], this.db._maxKey]); return this.inAnyRange(ranges, { includeLowers: false, includeUppers: false }); }; WhereClause.prototype.inAnyRange = function (ranges, options) { var _this = this; var cmp = this._cmp, ascending = this._ascending, descending = this._descending, min = this._min, max = this._max; if (ranges.length === 0) return emptyCollection(this); if (!ranges.every(function (range) { return range[0] !== undefined && range[1] !== undefined && ascending(range[0], range[1]) <= 0; })) { return fail(this, "First argument to inAnyRange() must be an Array of two-value Arrays [lower,upper] where upper must not be lower than lower", exceptions.InvalidArgument); } var includeLowers = !options || options.includeLowers !== false; var includeUppers = options && options.includeUppers === true; function addRange(ranges, newRange) { var i = 0, l = ranges.length; for (; i < l; ++i) { var range = ranges[i]; if (cmp(newRange[0], range[1]) < 0 && cmp(newRange[1], range[0]) > 0) { range[0] = min(range[0], newRange[0]); range[1] = max(range[1], newRange[1]); break; } } if (i === l) ranges.push(newRange); return ranges; } var sortDirection = ascending; function rangeSorter(a, b) { return sortDirection(a[0], b[0]); } var set; try { set = ranges.reduce(addRange, []); set.sort(rangeSorter); } catch (ex) { return fail(this, INVALID_KEY_ARGUMENT); } var rangePos = 0; var keyIsBeyondCurrentEntry = includeUppers ? function (key) { return ascending(key, set[rangePos][1]) > 0; } : function (key) { return ascending(key, set[rangePos][1]) >= 0; }; var keyIsBeforeCurrentEntry = includeLowers ? function (key) { return descending(key, set[rangePos][0]) > 0; } : function (key) { return descending(key, set[rangePos][0]) >= 0; }; function keyWithinCurrentRange(key) { return !keyIsBeyondCurrentEntry(key) && !keyIsBeforeCurrentEntry(key); } var checkKey = keyIsBeyondCurrentEntry; var c = new this.Collection(this, function () { return createRange(set[0][0], set[set.length - 1][1], !includeLowers, !includeUppers); }); c._ondirectionchange = function (direction) { if (direction === "next") { checkKey = keyIsBeyondCurrentEntry; sortDirection = ascending; } else { checkKey = keyIsBeforeCurrentEntry; sortDirection = descending; } set.sort(rangeSorter); }; c._addAlgorithm(function (cursor, advance, resolve) { var key = cursor.key; while (checkKey(key)) { ++rangePos; if (rangePos === set.length) { advance(resolve); return false; } } if (keyWithinCurrentRange(key)) { return true; } else if (_this._cmp(key, set[rangePos][1]) === 0 || _this._cmp(key, set[rangePos][0]) === 0) { return false; } else { advance(function () { if (sortDirection === ascending) cursor.continue(set[rangePos][0]); else cursor.continue(set[rangePos][1]); }); return false; } }); return c; }; WhereClause.prototype.startsWithAnyOf = function () { var set = getArrayOf.apply(NO_CHAR_ARRAY, arguments); if (!set.every(function (s) { return typeof s === 'string'; })) { return fail(this, "startsWithAnyOf() only works with strings"); } if (set.length === 0) return emptyCollection(this); return this.inAnyRange(set.map(function (str) { return [str, str + maxString]; })); }; return WhereClause; }()); function createWhereClauseConstructor(db) { return makeClassConstructor(WhereClause.prototype, function WhereClause$$1(table, index, orCollection) { this.db = db; this._ctx = { table: table, index: index === ":id" ? null : index, or: orCollection }; var indexedDB = db._deps.indexedDB; if (!indexedDB) throw new exceptions.MissingAPI("indexedDB API missing"); this._cmp = this._ascending = indexedDB.cmp.bind(indexedDB); this._descending = function (a, b) { return indexedDB.cmp(b, a); }; this._max = function (a, b) { return indexedDB.cmp(a, b) > 0 ? a : b; }; this._min = function (a, b) { return indexedDB.cmp(a, b) < 0 ? a : b; }; this._IDBKeyRange = db._deps.IDBKeyRange; }); } function safariMultiStoreFix(storeNames) { return storeNames.length === 1 ? storeNames[0] : storeNames; } function getMaxKey(IdbKeyRange) { try { IdbKeyRange.only([[]]); return [[]]; } catch (e) { return maxString; } } function eventRejectHandler(reject) { return wrap(function (event) { preventDefault(event); reject(event.target.error); return false; }); } function preventDefault(event) { if (event.stopPropagation) event.stopPropagation(); if (event.preventDefault) event.preventDefault(); } var Transaction = (function () { function Transaction() { } Transaction.prototype._lock = function () { assert(!PSD.global); ++this._reculock; if (this._reculock === 1 && !PSD.global) PSD.lockOwnerFor = this; return this; }; Transaction.prototype._unlock = function () { assert(!PSD.global); if (--this._reculock === 0) { if (!PSD.global) PSD.lockOwnerFor = null; while (this._blockedFuncs.length > 0 && !this._locked()) { var fnAndPSD = this._blockedFuncs.shift(); try { usePSD(fnAndPSD[1], fnAndPSD[0]); } catch (e) { } } } return this; }; Transaction.prototype._locked = function () { return this._reculock && PSD.lockOwnerFor !== this; }; Transaction.prototype.create = function (idbtrans) { var _this = this; if (!this.mode) return this; var idbdb = this.db.idbdb; var dbOpenError = this.db._state.dbOpenError; assert(!this.idbtrans); if (!idbtrans && !idbdb) { switch (dbOpenError && dbOpenError.name) { case "DatabaseClosedError": throw new exceptions.DatabaseClosed(dbOpenError); case "MissingAPIError": throw new exceptions.MissingAPI(dbOpenError.message, dbOpenError); default: throw new exceptions.OpenFailed(dbOpenError); } } if (!this.active) throw new exceptions.TransactionInactive(); assert(this._completion._state === null); idbtrans = this.idbtrans = idbtrans || idbdb.transaction(safariMultiStoreFix(this.storeNames), this.mode); idbtrans.onerror = wrap(function (ev) { preventDefault(ev); _this._reject(idbtrans.error); }); idbtrans.onabort = wrap(function (ev) { preventDefault(ev); _this.active && _this._reject(new exceptions.Abort(idbtrans.error)); _this.active = false; _this.on("abort").fire(ev); }); idbtrans.oncomplete = wrap(function () { _this.active = false; _this._resolve(); }); return this; }; Transaction.prototype._promise = function (mode, fn, bWriteLock) { var _this = this; if (mode === 'readwrite' && this.mode !== 'readwrite') return rejection(new exceptions.ReadOnly("Transaction is readonly")); if (!this.active) return rejection(new exceptions.TransactionInactive()); if (this._locked()) { return new DexiePromise(function (resolve, reject) { _this._blockedFuncs.push([function () { _this._promise(mode, fn, bWriteLock).then(resolve, reject); }, PSD]); }); } else if (bWriteLock) { return newScope(function () { var p = new DexiePromise(function (resolve, reject) { _this._lock(); var rv = fn(resolve, reject, _this); if (rv && rv.then) rv.then(resolve, reject); }); p.finally(function () { return _this._unlock(); }); p._lib = true; return p; }); } else { var p = new DexiePromise(function (resolve, reject) { var rv = fn(resolve, reject, _this); if (rv && rv.then) rv.then(resolve, reject); }); p._lib = true; return p; } }; Transaction.prototype._root = function () { return this.parent ? this.parent._root() : this; }; Transaction.prototype.waitFor = function (promiseLike) { var root = this._root(); var promise = DexiePromise.resolve(promiseLike); if (root._waitingFor) { root._waitingFor = root._waitingFor.then(function () { return promise; }); } else { root._waitingFor = promise; root._waitingQueue = []; var store = root.idbtrans.objectStore(root.storeNames[0]); (function spin() { ++root._spinCount; while (root._waitingQueue.length) (root._waitingQueue.shift())(); if (root._waitingFor) store.get(-Infinity).onsuccess = spin; }()); } var currentWaitPromise = root._waitingFor; return new DexiePromise(function (resolve, reject) { promise.then(function (res) { return root._waitingQueue.push(wrap(resolve.bind(null, res))); }, function (err) { return root._waitingQueue.push(wrap(reject.bind(null, err))); }).finally(function () { if (root._waitingFor === currentWaitPromise) { root._waitingFor = null; } }); }); }; Transaction.prototype.abort = function () { this.active && this._reject(new exceptions.Abort()); this.active = false; }; Transaction.prototype.table = function (tableName) { var memoizedTables = (this._memoizedTables || (this._memoizedTables = {})); if (hasOwn(memoizedTables, tableName)) return memoizedTables[tableName]; var tableSchema = this.schema[tableName]; if (!tableSchema) { throw new exceptions.NotFound("Table " + tableName + " not part of transaction"); } var transactionBoundTable = new this.db.Table(tableName, tableSchema, this); transactionBoundTable.core = this.db.core.table(tableName); memoizedTables[tableName] = transactionBoundTable; return transactionBoundTable; }; return Transaction; }()); function createTransactionConstructor(db) { return makeClassConstructor(Transaction.prototype, function Transaction$$1(mode, storeNames, dbschema, parent) { var _this = this; this.db = db; this.mode = mode; this.storeNames = storeNames; this.schema = dbschema; this.idbtrans = null; this.on = Events(this, "complete", "error", "abort"); this.parent = parent || null; this.active = true; this._reculock = 0; this._blockedFuncs = []; this._resolve = null; this._reject = null; this._waitingFor = null; this._waitingQueue = null; this._spinCount = 0; this._completion = new DexiePromise(function (resolve, reject) { _this._resolve = resolve; _this._reject = reject; }); this._completion.then(function () { _this.active = false; _this.on.complete.fire(); }, function (e) { var wasActive = _this.active; _this.active = false; _this.on.error.fire(e); _this.parent ? _this.parent._reject(e) : wasActive && _this.idbtrans && _this.idbtrans.abort(); return rejection(e); }); }); } function createIndexSpec(name, keyPath, unique, multi, auto, compound, isPrimKey) { return { name: name, keyPath: keyPath, unique: unique, multi: multi, auto: auto, compound: compound, src: (unique && !isPrimKey ? '&' : '') + (multi ? '*' : '') + (auto ? "++" : "") + nameFromKeyPath(keyPath) }; } function nameFromKeyPath(keyPath) { return typeof keyPath === 'string' ? keyPath : keyPath ? ('[' + [].join.call(keyPath, '+') + ']') : ""; } function createTableSchema(name, primKey, indexes) { return { name: name, primKey: primKey, indexes: indexes, mappedClass: null, idxByName: arrayToObject(indexes, function (index) { return [index.name, index]; }) }; } function getKeyExtractor(keyPath) { if (keyPath == null) { return function () { return undefined; }; } else if (typeof keyPath === 'string') { return getSinglePathKeyExtractor(keyPath); } else { return function (obj) { return getByKeyPath(obj, keyPath); }; } } function getSinglePathKeyExtractor(keyPath) { var split = keyPath.split('.'); if (split.length === 1) { return function (obj) { return obj[keyPath]; }; } else { return function (obj) { return getByKeyPath(obj, keyPath); }; } } function getEffectiveKeys(primaryKey, req) { if (req.type === 'delete') return req.keys; return req.keys || req.values.map(primaryKey.extractKey); } function getExistingValues(table, req, effectiveKeys) { return req.type === 'add' ? Promise.resolve(new Array(req.values.length)) : table.getMany({ trans: req.trans, keys: effectiveKeys }); } function arrayify(arrayLike) { return [].slice.call(arrayLike); } var _id_counter = 0; function getKeyPathAlias(keyPath) { return keyPath == null ? ":id" : typeof keyPath === 'string' ? keyPath : "[" + keyPath.join('+') + "]"; } function createDBCore(db, indexedDB, IdbKeyRange, tmpTrans) { var cmp = indexedDB.cmp.bind(indexedDB); function extractSchema(db, trans) { var tables = arrayify(db.objectStoreNames); return { schema: { name: db.name, tables: tables.map(function (table) { return trans.objectStore(table); }).map(function (store) { var keyPath = store.keyPath, autoIncrement = store.autoIncrement; var compound = isArray(keyPath); var outbound = keyPath == null; var indexByKeyPath = {}; var result = { name: store.name, primaryKey: { name: null, isPrimaryKey: true, outbound: outbound, compound: compound, keyPath: keyPath, autoIncrement: autoIncrement, unique: true, extractKey: getKeyExtractor(keyPath) }, indexes: arrayify(store.indexNames).map(function (indexName) { return store.index(indexName); }) .map(function (index) { var name = index.name, unique = index.unique, multiEntry = index.multiEntry, keyPath = index.keyPath; var compound = isArray(keyPath); var result = { name: name, compound: compound, keyPath: keyPath, unique: unique, multiEntry: multiEntry, extractKey: getKeyExtractor(keyPath) }; indexByKeyPath[getKeyPathAlias(keyPath)] = result; return result; }), getIndexByKeyPath: function (keyPath) { return indexByKeyPath[getKeyPathAlias(keyPath)]; } }; indexByKeyPath[":id"] = result.primaryKey; if (keyPath != null) { indexByKeyPath[getKeyPathAlias(keyPath)] = result.primaryKey; } return result; }) }, hasGetAll: tables.length > 0 && ('getAll' in trans.objectStore(tables[0])) && !(typeof navigator !== 'undefined' && /Safari/.test(navigator.userAgent) && !/(Chrome\/|Edge\/)/.test(navigator.userAgent) && [].concat(navigator.userAgent.match(/Safari\/(\d*)/))[1] < 604) }; } function makeIDBKeyRange(range) { if (range.type === 3 ) return null; if (range.type === 4 ) throw new Error("Cannot convert never type to IDBKeyRange"); var lower = range.lower, upper = range.upper, lowerOpen = range.lowerOpen, upperOpen = range.upperOpen; var idbRange = lower === undefined ? upper === undefined ? null : IdbKeyRange.upperBound(upper, !!upperOpen) : upper === undefined ? IdbKeyRange.lowerBound(lower, !!lowerOpen) : IdbKeyRange.bound(lower, upper, !!lowerOpen, !!upperOpen); return idbRange; } function createDbCoreTable(tableSchema) { var tableName = tableSchema.name; function mutate(_a) { var trans = _a.trans, type = _a.type, keys$$1 = _a.keys, values = _a.values, range = _a.range, wantResults = _a.wantResults; return new Promise(function (resolve, reject) { resolve = wrap(resolve); var store = trans.objectStore(tableName); var outbound = store.keyPath == null; var isAddOrPut = type === "put" || type === "add"; if (!isAddOrPut && type !== 'delete' && type !== 'deleteRange') throw new Error("Invalid operation type: " + type); var length = (keys$$1 || values || { length: 1 }).length; if (keys$$1 && values && keys$$1.length !== values.length) { throw new Error("Given keys array must have same length as given values array."); } if (length === 0) return resolve({ numFailures: 0, failures: {}, results: [], lastResult: undefined }); var results = wantResults && __spreadArrays((keys$$1 ? keys$$1 : getEffectiveKeys(tableSchema.primaryKey, { type: type, keys: keys$$1, values: values }))); var req; var failures = []; var numFailures = 0; var errorHandler = function (event) { ++numFailures; preventDefault(event); if (results) results[event.target._reqno] = undefined; failures[event.target._reqno] = event.target.error; }; var setResult = function (_a) { var target = _a.target; results[target._reqno] = target.result; }; if (type === 'deleteRange') { if (range.type === 4 ) return resolve({ numFailures: numFailures, failures: failures, results: results, lastResult: undefined }); if (range.type === 3 ) req = store.clear(); else req = store.delete(makeIDBKeyRange(range)); } else { var _a = isAddOrPut ? outbound ? [values, keys$$1] : [values, null] : [keys$$1, null], args1 = _a[0], args2 = _a[1]; if (isAddOrPut) { for (var i = 0; i < length; ++i) { req = (args2 && args2[i] !== undefined ? store[type](args1[i], args2[i]) : store[type](args1[i])); req._reqno = i; if (results && results[i] === undefined) { req.onsuccess = setResult; } req.onerror = errorHandler; } } else { for (var i = 0; i < length; ++i) { req = store[type](args1[i]); req._reqno = i; req.onerror = errorHandler; } } } var done = function (event) { var lastResult = event.target.result; if (results) results[length - 1] = lastResult; resolve({ numFailures: numFailures, failures: failures, results: results, lastResult: lastResult }); }; req.onerror = function (event) { errorHandler(event); done(event); }; req.onsuccess = done; }); } function openCursor(_a) { var trans = _a.trans, values = _a.values, query = _a.query, reverse = _a.reverse, unique = _a.unique; return new Promise(function (resolve, reject) { resolve = wrap(resolve); var index = query.index, range = query.range; var store = trans.objectStore(tableName); var source = index.isPrimaryKey ? store : store.index(index.name); var direction = reverse ? unique ? "prevunique" : "prev" : unique ? "nextunique" : "next"; var req = values || !('openKeyCursor' in source) ? source.openCursor(makeIDBKeyRange(range), direction) : source.openKeyCursor(makeIDBKeyRange(range), direction); req.onerror = eventRejectHandler(reject); req.onsuccess = wrap(function (ev) { var cursor = req.result; if (!cursor) { resolve(null); return; } cursor.___id = ++_id_counter; cursor.done = false; var _cursorContinue = cursor.continue.bind(cursor); var _cursorContinuePrimaryKey = cursor.continuePrimaryKey; if (_cursorContinuePrimaryKey) _cursorContinuePrimaryKey = _cursorContinuePrimaryKey.bind(cursor); var _cursorAdvance = cursor.advance.bind(cursor); var doThrowCursorIsNotStarted = function () { throw new Error("Cursor not started"); }; var doThrowCursorIsStopped = function () { throw new Error("Cursor not stopped"); }; cursor.trans = trans; cursor.stop = cursor.continue = cursor.continuePrimaryKey = cursor.advance = doThrowCursorIsNotStarted; cursor.fail = wrap(reject); cursor.next = function () { var _this = this; var gotOne = 1; return this.start(function () { return gotOne-- ? _this.continue() : _this.stop(); }).then(function () { return _this; }); }; cursor.start = function (callback) { var iterationPromise = new Promise(function (resolveIteration, rejectIteration) { resolveIteration = wrap(resolveIteration); req.onerror = eventRejectHandler(rejectIteration); cursor.fail = rejectIteration; cursor.stop = function (value) { cursor.stop = cursor.continue = cursor.continuePrimaryKey = cursor.advance = doThrowCursorIsStopped; resolveIteration(value); }; }); var guardedCallback = function () { if (req.result) { try { callback(); } catch (err) { cursor.fail(err); } } else { cursor.done = true; cursor.start = function () { throw new Error("Cursor behind last entry"); }; cursor.stop(); } }; req.onsuccess = wrap(function (ev) { req.onsuccess = guardedCallback; guardedCallback(); }); cursor.continue = _cursorContinue; cursor.continuePrimaryKey = _cursorContinuePrimaryKey; cursor.advance = _cursorAdvance; guardedCallback(); return iterationPromise; }; resolve(cursor); }, reject); }); } function query(hasGetAll) { return function (request) { return new Promise(function (resolve, reject) { resolve = wrap(resolve); var trans = request.trans, values = request.values, limit = request.limit, query = request.query; var nonInfinitLimit = limit === Infinity ? undefined : limit; var index = query.index, range = query.range; var store = trans.objectStore(tableName); var source = index.isPrimaryKey ? store : store.index(index.name); var idbKeyRange = makeIDBKeyRange(range); if (limit === 0) return resolve({ result: [] }); if (hasGetAll) { var req = values ? source.getAll(idbKeyRange, nonInfinitLimit) : source.getAllKeys(idbKeyRange, nonInfinitLimit); req.onsuccess = function (event) { return resolve({ result: event.target.result }); }; req.onerror = eventRejectHandler(reject); } else { var count_1 = 0; var req_1 = values || !('openKeyCursor' in source) ? source.openCursor(idbKeyRange) : source.openKeyCursor(idbKeyRange); var result_1 = []; req_1.onsuccess = function (event) { var cursor = req_1.result; if (!cursor) return resolve({ result: result_1 }); result_1.push(values ? cursor.value : cursor.primaryKey); if (++count_1 === limit) return resolve({ result: result_1 }); cursor.continue(); }; req_1.onerror = eventRejectHandler(reject); } }); }; } return { name: tableName, schema: tableSchema, mutate: mutate, getMany: function (_a) { var trans = _a.trans, keys$$1 = _a.keys; return new Promise(function (resolve, reject) { resolve = wrap(resolve); var store = trans.objectStore(tableName); var length = keys$$1.length; var result = new Array(length); var keyCount = 0; var callbackCount = 0; var req; var successHandler = function (event) { var req = event.target; if ((result[req._pos] = req.result) != null) ; if (++callbackCount === keyCount) resolve(result); }; var errorHandler = eventRejectHandler(reject); for (var i = 0; i < length; ++i) { var key = keys$$1[i]; if (key != null) { req = store.get(keys$$1[i]); req._pos = i; req.onsuccess = successHandler; req.onerror = errorHandler; ++keyCount; } } if (keyCount === 0) resolve(result); }); }, get: function (_a) { var trans = _a.trans, key = _a.key; return new Promise(function (resolve, reject) { resolve = wrap(resolve); var store = trans.objectStore(tableName); var req = store.get(key); req.onsuccess = function (event) { return resolve(event.target.result); }; req.onerror = eventRejectHandler(reject); }); }, query: query(hasGetAll), openCursor: openCursor, count: function (_a) { var query = _a.query, trans = _a.trans; var index = query.index, range = query.range; return new Promise(function (resolve, reject) { var store = trans.objectStore(tableName); var source = index.isPrimaryKey ? store : store.index(index.name); var idbKeyRange = makeIDBKeyRange(range); var req = idbKeyRange ? source.count(idbKeyRange) : source.count(); req.onsuccess = wrap(function (ev) { return resolve(ev.target.result); }); req.onerror = eventRejectHandler(reject); }); } }; } var _a = extractSchema(db, tmpTrans), schema = _a.schema, hasGetAll = _a.hasGetAll; var tables = schema.tables.map(function (tableSchema) { return createDbCoreTable(tableSchema); }); var tableMap = {}; tables.forEach(function (table) { return tableMap[table.name] = table; }); return { stack: "dbcore", transaction: db.transaction.bind(db), table: function (name) { var result = tableMap[name]; if (!result) throw new Error("Table '" + name + "' not found"); return tableMap[name]; }, cmp: cmp, MIN_KEY: -Infinity, MAX_KEY: getMaxKey(IdbKeyRange), schema: schema }; } function createMiddlewareStack(stackImpl, middlewares) { return middlewares.reduce(function (down, _a) { var create = _a.create; return (__assign(__assign({}, down), create(down))); }, stackImpl); } function createMiddlewareStacks(middlewares, idbdb, _a, tmpTrans) { var IDBKeyRange = _a.IDBKeyRange, indexedDB = _a.indexedDB; var dbcore = createMiddlewareStack(createDBCore(idbdb, indexedDB, IDBKeyRange, tmpTrans), middlewares.dbcore); return { dbcore: dbcore }; } function generateMiddlewareStacks(db, tmpTrans) { var idbdb = tmpTrans.db; var stacks = createMiddlewareStacks(db._middlewares, idbdb, db._deps, tmpTrans); db.core = stacks.dbcore; db.tables.forEach(function (table) { var tableName = table.name; if (db.core.schema.tables.some(function (tbl) { return tbl.name === tableName; })) { table.core = db.core.table(tableName); if (db[tableName] instanceof db.Table) { db[tableName].core = table.core; } } }); } function setApiOnPlace(db, objs, tableNames, dbschema) { tableNames.forEach(function (tableName) { var schema = dbschema[tableName]; objs.forEach(function (obj) { if (!(tableName in obj)) { if (obj === db.Transaction.prototype || obj instanceof db.Transaction) { setProp(obj, tableName, { get: function () { return this.table(tableName); }, set: function (value) { defineProperty(this, tableName, { value: value, writable: true, configurable: true, enumerable: true }); } }); } else { obj[tableName] = new db.Table(tableName, schema); } } }); }); } function removeTablesApi(db, objs) { objs.forEach(function (obj) { for (var key in obj) { if (obj[key] instanceof db.Table) delete obj[key]; } }); } function lowerVersionFirst(a, b) { return a._cfg.version - b._cfg.version; } function runUpgraders(db, oldVersion, idbUpgradeTrans, reject) { var globalSchema = db._dbSchema; var trans = db._createTransaction('readwrite', db._storeNames, globalSchema); trans.create(idbUpgradeTrans); trans._completion.catch(reject); var rejectTransaction = trans._reject.bind(trans); var transless = PSD.transless || PSD; newScope(function () { PSD.trans = trans; PSD.transless = transless; if (oldVersion === 0) { keys(globalSchema).forEach(function (tableName) { createTable(idbUpgradeTrans, tableName, globalSchema[tableName].primKey, globalSchema[tableName].indexes); }); generateMiddlewareStacks(db, idbUpgradeTrans); DexiePromise.follow(function () { return db.on.populate.fire(trans); }).catch(rejectTransaction); } else updateTablesAndIndexes(db, oldVersion, trans, idbUpgradeTrans).catch(rejectTransaction); }); } function updateTablesAndIndexes(db, oldVersion, trans, idbUpgradeTrans) { var queue = []; var versions = db._versions; var globalSchema = db._dbSchema = buildGlobalSchema(db, db.idbdb, idbUpgradeTrans); var anyContentUpgraderHasRun = false; var versToRun = versions.filter(function (v) { return v._cfg.version >= oldVersion; }); versToRun.forEach(function (version) { queue.push(function () { var oldSchema = globalSchema; var newSchema = version._cfg.dbschema; adjustToExistingIndexNames(db, oldSchema, idbUpgradeTrans); adjustToExistingIndexNames(db, newSchema, idbUpgradeTrans); globalSchema = db._dbSchema = newSchema; var diff = getSchemaDiff(oldSchema, newSchema); diff.add.forEach(function (tuple) { createTable(idbUpgradeTrans, tuple[0], tuple[1].primKey, tuple[1].indexes); }); diff.change.forEach(function (change) { if (change.recreate) { throw new exceptions.Upgrade("Not yet support for changing primary key"); } else { var store_1 = idbUpgradeTrans.objectStore(change.name); change.add.forEach(function (idx) { return addIndex(store_1, idx); }); change.change.forEach(function (idx) { store_1.deleteIndex(idx.name); addIndex(store_1, idx); }); change.del.forEach(function (idxName) { return store_1.deleteIndex(idxName); }); } }); var contentUpgrade = version._cfg.contentUpgrade; if (contentUpgrade && version._cfg.version > oldVersion) { generateMiddlewareStacks(db, idbUpgradeTrans); anyContentUpgraderHasRun = true; var upgradeSchema_1 = shallowClone(newSchema); diff.del.forEach(function (table) { upgradeSchema_1[table] = oldSchema[table]; }); removeTablesApi(db, [db.Transaction.prototype]); setApiOnPlace(db, [db.Transaction.prototype], keys(upgradeSchema_1), upgradeSchema_1); trans.schema = upgradeSchema_1; var contentUpgradeIsAsync_1 = isAsyncFunction(contentUpgrade); if (contentUpgradeIsAsync_1) { incrementExpectedAwaits(); } var returnValue_1; var promiseFollowed = DexiePromise.follow(function () { returnValue_1 = contentUpgrade(trans); if (returnValue_1) { if (contentUpgradeIsAsync_1) { var decrementor = decrementExpectedAwaits.bind(null, null); returnValue_1.then(decrementor, decrementor); } } }); return (returnValue_1 && typeof returnValue_1.then === 'function' ? DexiePromise.resolve(returnValue_1) : promiseFollowed.then(function () { return returnValue_1; })); } }); queue.push(function (idbtrans) { if (!anyContentUpgraderHasRun || !hasIEDeleteObjectStoreBug) { var newSchema = version._cfg.dbschema; deleteRemovedTables(newSchema, idbtrans); } removeTablesApi(db, [db.Transaction.prototype]); setApiOnPlace(db, [db.Transaction.prototype], db._storeNames, db._dbSchema); trans.schema = db._dbSchema; }); }); function runQueue() { return queue.length ? DexiePromise.resolve(queue.shift()(trans.idbtrans)).then(runQueue) : DexiePromise.resolve(); } return runQueue().then(function () { createMissingTables(globalSchema, idbUpgradeTrans); }); } function getSchemaDiff(oldSchema, newSchema) { var diff = { del: [], add: [], change: [] }; var table; for (table in oldSchema) { if (!newSchema[table]) diff.del.push(table); } for (table in newSchema) { var oldDef = oldSchema[table], newDef = newSchema[table]; if (!oldDef) { diff.add.push([table, newDef]); } else { var change = { name: table, def: newDef, recreate: false, del: [], add: [], change: [] }; if (oldDef.primKey.src !== newDef.primKey.src && !isIEOrEdge ) { change.recreate = true; diff.change.push(change); } else { var oldIndexes = oldDef.idxByName; var newIndexes = newDef.idxByName; var idxName = void 0; for (idxName in oldIndexes) { if (!newIndexes[idxName]) change.del.push(idxName); } for (idxName in newIndexes) { var oldIdx = oldIndexes[idxName], newIdx = newIndexes[idxName]; if (!oldIdx) change.add.push(newIdx); else if (oldIdx.src !== newIdx.src) change.change.push(newIdx); } if (change.del.length > 0 || change.add.length > 0 || change.change.length > 0) { diff.change.push(change); } } } } return diff; } function createTable(idbtrans, tableName, primKey, indexes) { var store = idbtrans.db.createObjectStore(tableName, primKey.keyPath ? { keyPath: primKey.keyPath, autoIncrement: primKey.auto } : { autoIncrement: primKey.auto }); indexes.forEach(function (idx) { return addIndex(store, idx); }); return store; } function createMissingTables(newSchema, idbtrans) { keys(newSchema).forEach(function (tableName) { if (!idbtrans.db.objectStoreNames.contains(tableName)) { createTable(idbtrans, tableName, newSchema[tableName].primKey, newSchema[tableName].indexes); } }); } function deleteRemovedTables(newSchema, idbtrans) { for (var i = 0; i < idbtrans.db.objectStoreNames.length; ++i) { var storeName = idbtrans.db.objectStoreNames[i]; if (newSchema[storeName] == null) { idbtrans.db.deleteObjectStore(storeName); } } } function addIndex(store, idx) { store.createIndex(idx.name, idx.keyPath, { unique: idx.unique, multiEntry: idx.multi }); } function buildGlobalSchema(db, idbdb, tmpTrans) { var globalSchema = {}; var dbStoreNames = slice(idbdb.objectStoreNames, 0); dbStoreNames.forEach(function (storeName) { var store = tmpTrans.objectStore(storeName); var keyPath = store.keyPath; var primKey = createIndexSpec(nameFromKeyPath(keyPath), keyPath || "", false, false, !!store.autoIncrement, keyPath && typeof keyPath !== "string", true); var indexes = []; for (var j = 0; j < store.indexNames.length; ++j) { var idbindex = store.index(store.indexNames[j]); keyPath = idbindex.keyPath; var index = createIndexSpec(idbindex.name, keyPath, !!idbindex.unique, !!idbindex.multiEntry, false, keyPath && typeof keyPath !== "string", false); indexes.push(index); } globalSchema[storeName] = createTableSchema(storeName, primKey, indexes); }); return globalSchema; } function readGlobalSchema(db, idbdb, tmpTrans) { db.verno = idbdb.version / 10; var globalSchema = db._dbSchema = buildGlobalSchema(db, idbdb, tmpTrans); db._storeNames = slice(idbdb.objectStoreNames, 0); setApiOnPlace(db, [db._allTables], keys(globalSchema), globalSchema); } function adjustToExistingIndexNames(db, schema, idbtrans) { var storeNames = idbtrans.db.objectStoreNames; for (var i = 0; i < storeNames.length; ++i) { var storeName = storeNames[i]; var store = idbtrans.objectStore(storeName); db._hasGetAll = 'getAll' in store; for (var j = 0; j < store.indexNames.length; ++j) { var indexName = store.indexNames[j]; var keyPath = store.index(indexName).keyPath; var dexieName = typeof keyPath === 'string' ? keyPath : "[" + slice(keyPath).join('+') + "]"; if (schema[storeName]) { var indexSpec = schema[storeName].idxByName[dexieName]; if (indexSpec) { indexSpec.name = indexName; delete schema[storeName].idxByName[dexieName]; schema[storeName].idxByName[indexName] = indexSpec; } } } } if (typeof navigator !== 'undefined' && /Safari/.test(navigator.userAgent) && !/(Chrome\/|Edge\/)/.test(navigator.userAgent) && _global.WorkerGlobalScope && _global instanceof _global.WorkerGlobalScope && [].concat(navigator.userAgent.match(/Safari\/(\d*)/))[1] < 604) { db._hasGetAll = false; } } function parseIndexSyntax(primKeyAndIndexes) { return primKeyAndIndexes.split(',').map(function (index, indexNum) { index = index.trim(); var name = index.replace(/([&*]|\+\+)/g, ""); var keyPath = /^\[/.test(name) ? name.match(/^\[(.*)\]$/)[1].split('+') : name; return createIndexSpec(name, keyPath || null, /\&/.test(index), /\*/.test(index), /\+\+/.test(index), isArray(keyPath), indexNum === 0); }); } var Version = (function () { function Version() { } Version.prototype._parseStoresSpec = function (stores, outSchema) { keys(stores).forEach(function (tableName) { if (stores[tableName] !== null) { var indexes = parseIndexSyntax(stores[tableName]); var primKey = indexes.shift(); if (primKey.multi) throw new exceptions.Schema("Primary key cannot be multi-valued"); indexes.forEach(function (idx) { if (idx.auto) throw new exceptions.Schema("Only primary key can be marked as autoIncrement (++)"); if (!idx.keyPath) throw new exceptions.Schema("Index must have a name and cannot be an empty string"); }); outSchema[tableName] = createTableSchema(tableName, primKey, indexes); } }); }; Version.prototype.stores = function (stores) { var db = this.db; this._cfg.storesSource = this._cfg.storesSource ? extend(this._cfg.storesSource, stores) : stores; var versions = db._versions; var storesSpec = {}; var dbschema = {}; versions.forEach(function (version) { extend(storesSpec, version._cfg.storesSource); dbschema = (version._cfg.dbschema = {}); version._parseStoresSpec(storesSpec, dbschema); }); db._dbSchema = dbschema; removeTablesApi(db, [db._allTables, db, db.Transaction.prototype]); setApiOnPlace(db, [db._allTables, db, db.Transaction.prototype, this._cfg.tables], keys(dbschema), dbschema); db._storeNames = keys(dbschema); return this; }; Version.prototype.upgrade = function (upgradeFunction) { this._cfg.contentUpgrade = upgradeFunction; return this; }; return Version; }()); function createVersionConstructor(db) { return makeClassConstructor(Version.prototype, function Version$$1(versionNumber) { this.db = db; this._cfg = { version: versionNumber, storesSource: null, dbschema: {}, tables: {}, contentUpgrade: null }; }); } var databaseEnumerator; function DatabaseEnumerator(indexedDB) { var hasDatabasesNative = indexedDB && typeof indexedDB.databases === 'function'; var dbNamesTable; if (!hasDatabasesNative) { var db = new Dexie(DBNAMES_DB, { addons: [] }); db.version(1).stores({ dbnames: 'name' }); dbNamesTable = db.table('dbnames'); } return { getDatabaseNames: function () { return hasDatabasesNative ? DexiePromise.resolve(indexedDB.databases()).then(function (infos) { return infos .map(function (info) { return info.name; }) .filter(function (name) { return name !== DBNAMES_DB; }); }) : dbNamesTable.toCollection().primaryKeys(); }, add: function (name) { return !hasDatabasesNative && name !== DBNAMES_DB && dbNamesTable.put({ name: name }).catch(nop); }, remove: function (name) { return !hasDatabasesNative && name !== DBNAMES_DB && dbNamesTable.delete(name).catch(nop); } }; } function initDatabaseEnumerator(indexedDB) { try { databaseEnumerator = DatabaseEnumerator(indexedDB); } catch (e) { } } function vip(fn) { return newScope(function () { PSD.letThrough = true; return fn(); }); } function dexieOpen(db) { var state = db._state; var indexedDB = db._deps.indexedDB; if (state.isBeingOpened || db.idbdb) return state.dbReadyPromise.then(function () { return state.dbOpenError ? rejection(state.dbOpenError) : db; }); debug && (state.openCanceller._stackHolder = getErrorWithStack()); state.isBeingOpened = true; state.dbOpenError = null; state.openComplete = false; var resolveDbReady = state.dbReadyResolve, upgradeTransaction = null; return DexiePromise.race([state.openCanceller, new DexiePromise(function (resolve, reject) { if (!indexedDB) throw new exceptions.MissingAPI("indexedDB API not found. If using IE10+, make sure to run your code on a server URL " + "(not locally). If using old Safari versions, make sure to include indexedDB polyfill."); var dbName = db.name; var req = state.autoSchema ? indexedDB.open(dbName) : indexedDB.open(dbName, Math.round(db.verno * 10)); if (!req) throw new exceptions.MissingAPI("IndexedDB API not available"); req.onerror = eventRejectHandler(reject); req.onblocked = wrap(db._fireOnBlocked); req.onupgradeneeded = wrap(function (e) { upgradeTransaction = req.transaction; if (state.autoSchema && !db._options.allowEmptyDB) { req.onerror = preventDefault; upgradeTransaction.abort(); req.result.close(); var delreq = indexedDB.deleteDatabase(dbName); delreq.onsuccess = delreq.onerror = wrap(function () { reject(new exceptions.NoSuchDatabase("Database " + dbName + " doesnt exist")); }); } else { upgradeTransaction.onerror = eventRejectHandler(reject); var oldVer = e.oldVersion > Math.pow(2, 62) ? 0 : e.oldVersion; db.idbdb = req.result; runUpgraders(db, oldVer / 10, upgradeTransaction, reject); } }, reject); req.onsuccess = wrap(function () { upgradeTransaction = null; var idbdb = db.idbdb = req.result; var objectStoreNames = slice(idbdb.objectStoreNames); if (objectStoreNames.length > 0) try { var tmpTrans = idbdb.transaction(safariMultiStoreFix(objectStoreNames), 'readonly'); if (state.autoSchema) readGlobalSchema(db, idbdb, tmpTrans); else adjustToExistingIndexNames(db, db._dbSchema, tmpTrans); generateMiddlewareStacks(db, tmpTrans); } catch (e) { } connections.push(db); idbdb.onversionchange = wrap(function (ev) { state.vcFired = true; db.on("versionchange").fire(ev); }); databaseEnumerator.add(dbName); resolve(); }, reject); })]).then(function () { state.onReadyBeingFired = []; return DexiePromise.resolve(vip(db.on.ready.fire)).then(function fireRemainders() { if (state.onReadyBeingFired.length > 0) { var remainders = state.onReadyBeingFired.reduce(promisableChain, nop); state.onReadyBeingFired = []; return DexiePromise.resolve(vip(remainders)).then(fireRemainders); } }); }).finally(function () { state.onReadyBeingFired = null; }).then(function () { state.isBeingOpened = false; return db; }).catch(function (err) { try { upgradeTransaction && upgradeTransaction.abort(); } catch (e) { } state.isBeingOpened = false; db.close(); state.dbOpenError = err; return rejection(state.dbOpenError); }).finally(function () { state.openComplete = true; resolveDbReady(); }); } function awaitIterator(iterator) { var callNext = function (result) { return iterator.next(result); }, doThrow = function (error) { return iterator.throw(error); }, onSuccess = step(callNext), onError = step(doThrow); function step(getNext) { return function (val) { var next = getNext(val), value = next.value; return next.done ? value : (!value || typeof value.then !== 'function' ? isArray(value) ? Promise.all(value).then(onSuccess, onError) : onSuccess(value) : value.then(onSuccess, onError)); }; } return step(callNext)(); } function extractTransactionArgs(mode, _tableArgs_, scopeFunc) { var i = arguments.length; if (i < 2) throw new exceptions.InvalidArgument("Too few arguments"); var args = new Array(i - 1); while (--i) args[i - 1] = arguments[i]; scopeFunc = args.pop(); var tables = flatten(args); return [mode, tables, scopeFunc]; } function enterTransactionScope(db, mode, storeNames, parentTransaction, scopeFunc) { return DexiePromise.resolve().then(function () { var transless = PSD.transless || PSD; var trans = db._createTransaction(mode, storeNames, db._dbSchema, parentTransaction); var zoneProps = { trans: trans, transless: transless }; if (parentTransaction) { trans.idbtrans = parentTransaction.idbtrans; } else { trans.create(); } var scopeFuncIsAsync = isAsyncFunction(scopeFunc); if (scopeFuncIsAsync) { incrementExpectedAwaits(); } var returnValue; var promiseFollowed = DexiePromise.follow(function () { returnValue = scopeFunc.call(trans, trans); if (returnValue) { if (scopeFuncIsAsync) { var decrementor = decrementExpectedAwaits.bind(null, null); returnValue.then(decrementor, decrementor); } else if (typeof returnValue.next === 'function' && typeof returnValue.throw === 'function') { returnValue = awaitIterator(returnValue); } } }, zoneProps); return (returnValue && typeof returnValue.then === 'function' ? DexiePromise.resolve(returnValue).then(function (x) { return trans.active ? x : rejection(new exceptions.PrematureCommit("Transaction committed too early. See http://bit.ly/2kdckMn")); }) : promiseFollowed.then(function () { return returnValue; })).then(function (x) { if (parentTransaction) trans._resolve(); return trans._completion.then(function () { return x; }); }).catch(function (e) { trans._reject(e); return rejection(e); }); }); } function pad(a, value, count) { var result = isArray(a) ? a.slice() : [a]; for (var i = 0; i < count; ++i) result.push(value); return result; } function createVirtualIndexMiddleware(down) { return __assign(__assign({}, down), { table: function (tableName) { var table = down.table(tableName); var schema = table.schema; var indexLookup = {}; var allVirtualIndexes = []; function addVirtualIndexes(keyPath, keyTail, lowLevelIndex) { var keyPathAlias = getKeyPathAlias(keyPath); var indexList = (indexLookup[keyPathAlias] = indexLookup[keyPathAlias] || []); var keyLength = keyPath == null ? 0 : typeof keyPath === 'string' ? 1 : keyPath.length; var isVirtual = keyTail > 0; var virtualIndex = __assign(__assign({}, lowLevelIndex), { isVirtual: isVirtual, isPrimaryKey: !isVirtual && lowLevelIndex.isPrimaryKey, keyTail: keyTail, keyLength: keyLength, extractKey: getKeyExtractor(keyPath), unique: !isVirtual && lowLevelIndex.unique }); indexList.push(virtualIndex); if (!virtualIndex.isPrimaryKey) { allVirtualIndexes.push(virtualIndex); } if (keyLength > 1) { var virtualKeyPath = keyLength === 2 ? keyPath[0] : keyPath.slice(0, keyLength - 1); addVirtualIndexes(virtualKeyPath, keyTail + 1, lowLevelIndex); } indexList.sort(function (a, b) { return a.keyTail - b.keyTail; }); return virtualIndex; } var primaryKey = addVirtualIndexes(schema.primaryKey.keyPath, 0, schema.primaryKey); indexLookup[":id"] = [primaryKey]; for (var _i = 0, _a = schema.indexes; _i < _a.length; _i++) { var index = _a[_i]; addVirtualIndexes(index.keyPath, 0, index); } function findBestIndex(keyPath) { var result = indexLookup[getKeyPathAlias(keyPath)]; return result && result[0]; } function translateRange(range, keyTail) { return { type: range.type === 1 ? 2 : range.type, lower: pad(range.lower, range.lowerOpen ? down.MAX_KEY : down.MIN_KEY, keyTail), lowerOpen: true, upper: pad(range.upper, range.upperOpen ? down.MIN_KEY : down.MAX_KEY, keyTail), upperOpen: true }; } function translateRequest(req) { var index = req.query.index; return index.isVirtual ? __assign(__assign({}, req), { query: { index: index, range: translateRange(req.query.range, index.keyTail) } }) : req; } var result = __assign(__assign({}, table), { schema: __assign(__assign({}, schema), { primaryKey: primaryKey, indexes: allVirtualIndexes, getIndexByKeyPath: findBestIndex }), count: function (req) { return table.count(translateRequest(req)); }, query: function (req) { return table.query(translateRequest(req)); }, openCursor: function (req) { var _a = req.query.index, keyTail = _a.keyTail, isVirtual = _a.isVirtual, keyLength = _a.keyLength; if (!isVirtual) return table.openCursor(req); function createVirtualCursor(cursor) { function _continue(key) { key != null ? cursor.continue(pad(key, req.reverse ? down.MAX_KEY : down.MIN_KEY, keyTail)) : req.unique ? cursor.continue(pad(cursor.key, req.reverse ? down.MIN_KEY : down.MAX_KEY, keyTail)) : cursor.continue(); } var virtualCursor = Object.create(cursor, { continue: { value: _continue }, continuePrimaryKey: { value: function (key, primaryKey) { cursor.continuePrimaryKey(pad(key, down.MAX_KEY, keyTail), primaryKey); } }, key: { get: function () { var key = cursor.key; return keyLength === 1 ? key[0] : key.slice(0, keyLength); } }, value: { get: function () { return cursor.value; } } }); return virtualCursor; } return table.openCursor(translateRequest(req)) .then(function (cursor) { return cursor && createVirtualCursor(cursor); }); } }); return result; } }); } var virtualIndexMiddleware = { stack: "dbcore", name: "VirtualIndexMiddleware", level: 1, create: createVirtualIndexMiddleware }; var hooksMiddleware = { stack: "dbcore", name: "HooksMiddleware", level: 2, create: function (downCore) { return (__assign(__assign({}, downCore), { table: function (tableName) { var downTable = downCore.table(tableName); var primaryKey = downTable.schema.primaryKey; var tableMiddleware = __assign(__assign({}, downTable), { mutate: function (req) { var dxTrans = PSD.trans; var _a = dxTrans.table(tableName).hook, deleting = _a.deleting, creating = _a.creating, updating = _a.updating; switch (req.type) { case 'add': if (creating.fire === nop) break; return dxTrans._promise('readwrite', function () { return addPutOrDelete(req); }, true); case 'put': if (creating.fire === nop && updating.fire === nop) break; return dxTrans._promise('readwrite', function () { return addPutOrDelete(req); }, true); case 'delete': if (deleting.fire === nop) break; return dxTrans._promise('readwrite', function () { return addPutOrDelete(req); }, true); case 'deleteRange': if (deleting.fire === nop) break; return dxTrans._promise('readwrite', function () { return deleteRange(req); }, true); } return downTable.mutate(req); function addPutOrDelete(req) { var dxTrans = PSD.trans; var keys$$1 = req.keys || getEffectiveKeys(primaryKey, req); if (!keys$$1) throw new Error("Keys missing"); req = req.type === 'add' || req.type === 'put' ? __assign(__assign({}, req), { keys: keys$$1, wantResults: true }) : __assign({}, req); if (req.type !== 'delete') req.values = __spreadArrays(req.values); if (req.keys) req.keys = __spreadArrays(req.keys); return getExistingValues(downTable, req, keys$$1).then(function (existingValues) { var contexts = keys$$1.map(function (key, i) { var existingValue = existingValues[i]; var ctx = { onerror: null, onsuccess: null }; if (req.type === 'delete') { deleting.fire.call(ctx, key, existingValue, dxTrans); } else if (req.type === 'add' || existingValue === undefined) { var generatedPrimaryKey = creating.fire.call(ctx, key, req.values[i], dxTrans); if (key == null && generatedPrimaryKey != null) { key = generatedPrimaryKey; req.keys[i] = key; if (!primaryKey.outbound) { setByKeyPath(req.values[i], primaryKey.keyPath, key); } } } else { var objectDiff = getObjectDiff(existingValue, req.values[i]); var additionalChanges_1 = updating.fire.call(ctx, objectDiff, key, existingValue, dxTrans); if (additionalChanges_1) { var requestedValue_1 = req.values[i]; Object.keys(additionalChanges_1).forEach(function (keyPath) { setByKeyPath(requestedValue_1, keyPath, additionalChanges_1[keyPath]); }); } } return ctx; }); return downTable.mutate(req).then(function (_a) { var failures = _a.failures, results = _a.results, numFailures = _a.numFailures, lastResult = _a.lastResult; for (var i = 0; i < keys$$1.length; ++i) { var primKey = results ? results[i] : keys$$1[i]; var ctx = contexts[i]; if (primKey == null) { ctx.onerror && ctx.onerror(failures[i]); } else { ctx.onsuccess && ctx.onsuccess(req.type === 'put' && existingValues[i] ? req.values[i] : primKey ); } } return { failures: failures, results: results, numFailures: numFailures, lastResult: lastResult }; }).catch(function (error) { contexts.forEach(function (ctx) { return ctx.onerror && ctx.onerror(error); }); return Promise.reject(error); }); }); } function deleteRange(req) { return deleteNextChunk(req.trans, req.range, 10000); } function deleteNextChunk(trans, range, limit) { return downTable.query({ trans: trans, values: false, query: { index: primaryKey, range: range }, limit: limit }) .then(function (_a) { var result = _a.result; return addPutOrDelete({ type: 'delete', keys: result, trans: trans }).then(function (res) { if (res.numFailures > 0) return Promise.reject(res.failures[0]); if (result.length < limit) { return { failures: [], numFailures: 0, lastResult: undefined }; } else { return deleteNextChunk(trans, __assign(__assign({}, range), { lower: result[result.length - 1], lowerOpen: true }), limit); } }); }); } } }); return tableMiddleware; } })); } }; var Dexie = (function () { function Dexie(name, options) { var _this = this; this._middlewares = {}; this.verno = 0; var deps = Dexie.dependencies; this._options = options = __assign({ addons: Dexie.addons, autoOpen: true, indexedDB: deps.indexedDB, IDBKeyRange: deps.IDBKeyRange }, options); this._deps = { indexedDB: options.indexedDB, IDBKeyRange: options.IDBKeyRange }; var addons = options.addons; this._dbSchema = {}; this._versions = []; this._storeNames = []; this._allTables = {}; this.idbdb = null; var state = { dbOpenError: null, isBeingOpened: false, onReadyBeingFired: null, openComplete: false, dbReadyResolve: nop, dbReadyPromise: null, cancelOpen: nop, openCanceller: null, autoSchema: true }; state.dbReadyPromise = new DexiePromise(function (resolve) { state.dbReadyResolve = resolve; }); state.openCanceller = new DexiePromise(function (_, reject) { state.cancelOpen = reject; }); this._state = state; this.name = name; this.on = Events(this, "populate", "blocked", "versionchange", { ready: [promisableChain, nop] }); this.on.ready.subscribe = override(this.on.ready.subscribe, function (subscribe) { return function (subscriber, bSticky) { Dexie.vip(function () { var state = _this._state; if (state.openComplete) { if (!state.dbOpenError) DexiePromise.resolve().then(subscriber); if (bSticky) subscribe(subscriber); } else if (state.onReadyBeingFired) { state.onReadyBeingFired.push(subscriber); if (bSticky) subscribe(subscriber); } else { subscribe(subscriber); var db_1 = _this; if (!bSticky) subscribe(function unsubscribe() { db_1.on.ready.unsubscribe(subscriber); db_1.on.ready.unsubscribe(unsubscribe); }); } }); }; }); this.Collection = createCollectionConstructor(this); this.Table = createTableConstructor(this); this.Transaction = createTransactionConstructor(this); this.Version = createVersionConstructor(this); this.WhereClause = createWhereClauseConstructor(this); this.on("versionchange", function (ev) { if (ev.newVersion > 0) console.warn("Another connection wants to upgrade database '" + _this.name + "'. Closing db now to resume the upgrade."); else console.warn("Another connection wants to delete database '" + _this.name + "'. Closing db now to resume the delete request."); _this.close(); }); this.on("blocked", function (ev) { if (!ev.newVersion || ev.newVersion < ev.oldVersion) console.warn("Dexie.delete('" + _this.name + "') was blocked"); else console.warn("Upgrade '" + _this.name + "' blocked by other connection holding version " + ev.oldVersion / 10); }); this._maxKey = getMaxKey(options.IDBKeyRange); this._createTransaction = function (mode, storeNames, dbschema, parentTransaction) { return new _this.Transaction(mode, storeNames, dbschema, parentTransaction); }; this._fireOnBlocked = function (ev) { _this.on("blocked").fire(ev); connections .filter(function (c) { return c.name === _this.name && c !== _this && !c._state.vcFired; }) .map(function (c) { return c.on("versionchange").fire(ev); }); }; this.use(virtualIndexMiddleware); this.use(hooksMiddleware); addons.forEach(function (addon) { return addon(_this); }); } Dexie.prototype.version = function (versionNumber) { if (isNaN(versionNumber) || versionNumber < 0.1) throw new exceptions.Type("Given version is not a positive number"); versionNumber = Math.round(versionNumber * 10) / 10; if (this.idbdb || this._state.isBeingOpened) throw new exceptions.Schema("Cannot add version when database is open"); this.verno = Math.max(this.verno, versionNumber); var versions = this._versions; var versionInstance = versions.filter(function (v) { return v._cfg.version === versionNumber; })[0]; if (versionInstance) return versionInstance; versionInstance = new this.Version(versionNumber); versions.push(versionInstance); versions.sort(lowerVersionFirst); versionInstance.stores({}); this._state.autoSchema = false; return versionInstance; }; Dexie.prototype._whenReady = function (fn) { var _this = this; return this._state.openComplete || PSD.letThrough ? fn() : new DexiePromise(function (resolve, reject) { if (!_this._state.isBeingOpened) { if (!_this._options.autoOpen) { reject(new exceptions.DatabaseClosed()); return; } _this.open().catch(nop); } _this._state.dbReadyPromise.then(resolve, reject); }).then(fn); }; Dexie.prototype.use = function (_a) { var stack = _a.stack, create = _a.create, level = _a.level, name = _a.name; if (name) this.unuse({ stack: stack, name: name }); var middlewares = this._middlewares[stack] || (this._middlewares[stack] = []); middlewares.push({ stack: stack, create: create, level: level == null ? 10 : level, name: name }); middlewares.sort(function (a, b) { return a.level - b.level; }); return this; }; Dexie.prototype.unuse = function (_a) { var stack = _a.stack, name = _a.name, create = _a.create; if (stack && this._middlewares[stack]) { this._middlewares[stack] = this._middlewares[stack].filter(function (mw) { return create ? mw.create !== create : name ? mw.name !== name : false; }); } return this; }; Dexie.prototype.open = function () { return dexieOpen(this); }; Dexie.prototype.close = function () { var idx = connections.indexOf(this), state = this._state; if (idx >= 0) connections.splice(idx, 1); if (this.idbdb) { try { this.idbdb.close(); } catch (e) { } this.idbdb = null; } this._options.autoOpen = false; state.dbOpenError = new exceptions.DatabaseClosed(); if (state.isBeingOpened) state.cancelOpen(state.dbOpenError); state.dbReadyPromise = new DexiePromise(function (resolve) { state.dbReadyResolve = resolve; }); state.openCanceller = new DexiePromise(function (_, reject) { state.cancelOpen = reject; }); }; Dexie.prototype.delete = function () { var _this = this; var hasArguments = arguments.length > 0; var state = this._state; return new DexiePromise(function (resolve, reject) { var doDelete = function () { _this.close(); var req = _this._deps.indexedDB.deleteDatabase(_this.name); req.onsuccess = wrap(function () { databaseEnumerator.remove(_this.name); resolve(); }); req.onerror = eventRejectHandler(reject); req.onblocked = _this._fireOnBlocked; }; if (hasArguments) throw new exceptions.InvalidArgument("Arguments not allowed in db.delete()"); if (state.isBeingOpened) { state.dbReadyPromise.then(doDelete); } else { doDelete(); } }); }; Dexie.prototype.backendDB = function () { return this.idbdb; }; Dexie.prototype.isOpen = function () { return this.idbdb !== null; }; Dexie.prototype.hasBeenClosed = function () { var dbOpenError = this._state.dbOpenError; return dbOpenError && (dbOpenError.name === 'DatabaseClosed'); }; Dexie.prototype.hasFailed = function () { return this._state.dbOpenError !== null; }; Dexie.prototype.dynamicallyOpened = function () { return this._state.autoSchema; }; Object.defineProperty(Dexie.prototype, "tables", { get: function () { var _this = this; return keys(this._allTables).map(function (name) { return _this._allTables[name]; }); }, enumerable: true, configurable: true }); Dexie.prototype.transaction = function () { var args = extractTransactionArgs.apply(this, arguments); return this._transaction.apply(this, args); }; Dexie.prototype._transaction = function (mode, tables, scopeFunc) { var _this = this; var parentTransaction = PSD.trans; if (!parentTransaction || parentTransaction.db !== this || mode.indexOf('!') !== -1) parentTransaction = null; var onlyIfCompatible = mode.indexOf('?') !== -1; mode = mode.replace('!', '').replace('?', ''); var idbMode, storeNames; try { storeNames = tables.map(function (table) { var storeName = table instanceof _this.Table ? table.name : table; if (typeof storeName !== 'string') throw new TypeError("Invalid table argument to Dexie.transaction(). Only Table or String are allowed"); return storeName; }); if (mode == "r" || mode === READONLY) idbMode = READONLY; else if (mode == "rw" || mode == READWRITE) idbMode = READWRITE; else throw new exceptions.InvalidArgument("Invalid transaction mode: " + mode); if (parentTransaction) { if (parentTransaction.mode === READONLY && idbMode === READWRITE) { if (onlyIfCompatible) { parentTransaction = null; } else throw new exceptions.SubTransaction("Cannot enter a sub-transaction with READWRITE mode when parent transaction is READONLY"); } if (parentTransaction) { storeNames.forEach(function (storeName) { if (parentTransaction && parentTransaction.storeNames.indexOf(storeName) === -1) { if (onlyIfCompatible) { parentTransaction = null; } else throw new exceptions.SubTransaction("Table " + storeName + " not included in parent transaction."); } }); } if (onlyIfCompatible && parentTransaction && !parentTransaction.active) { parentTransaction = null; } } } catch (e) { return parentTransaction ? parentTransaction._promise(null, function (_, reject) { reject(e); }) : rejection(e); } var enterTransaction = enterTransactionScope.bind(null, this, idbMode, storeNames, parentTransaction, scopeFunc); return (parentTransaction ? parentTransaction._promise(idbMode, enterTransaction, "lock") : PSD.trans ? usePSD(PSD.transless, function () { return _this._whenReady(enterTransaction); }) : this._whenReady(enterTransaction)); }; Dexie.prototype.table = function (tableName) { if (!hasOwn(this._allTables, tableName)) { throw new exceptions.InvalidTable("Table " + tableName + " does not exist"); } return this._allTables[tableName]; }; return Dexie; }()); var Dexie$1 = Dexie; props(Dexie$1, __assign(__assign({}, fullNameExceptions), { delete: function (databaseName) { var db = new Dexie$1(databaseName); return db.delete(); }, exists: function (name) { return new Dexie$1(name, { addons: [] }).open().then(function (db) { db.close(); return true; }).catch('NoSuchDatabaseError', function () { return false; }); }, getDatabaseNames: function (cb) { return databaseEnumerator ? databaseEnumerator.getDatabaseNames().then(cb) : DexiePromise.resolve([]); }, defineClass: function () { function Class(content) { extend(this, content); } return Class; }, ignoreTransaction: function (scopeFunc) { return PSD.trans ? usePSD(PSD.transless, scopeFunc) : scopeFunc(); }, vip: vip, async: function (generatorFn) { return function () { try { var rv = awaitIterator(generatorFn.apply(this, arguments)); if (!rv || typeof rv.then !== 'function') return DexiePromise.resolve(rv); return rv; } catch (e) { return rejection(e); } }; }, spawn: function (generatorFn, args, thiz) { try { var rv = awaitIterator(generatorFn.apply(thiz, args || [])); if (!rv || typeof rv.then !== 'function') return DexiePromise.resolve(rv); return rv; } catch (e) { return rejection(e); } }, currentTransaction: { get: function () { return PSD.trans || null; } }, waitFor: function (promiseOrFunction, optionalTimeout) { var promise = DexiePromise.resolve(typeof promiseOrFunction === 'function' ? Dexie$1.ignoreTransaction(promiseOrFunction) : promiseOrFunction) .timeout(optionalTimeout || 60000); return PSD.trans ? PSD.trans.waitFor(promise) : promise; }, Promise: DexiePromise, debug: { get: function () { return debug; }, set: function (value) { setDebug(value, value === 'dexie' ? function () { return true; } : dexieStackFrameFilter); } }, derive: derive, extend: extend, props: props, override: override, Events: Events, getByKeyPath: getByKeyPath, setByKeyPath: setByKeyPath, delByKeyPath: delByKeyPath, shallowClone: shallowClone, deepClone: deepClone, getObjectDiff: getObjectDiff, asap: asap, minKey: minKey, addons: [], connections: connections, errnames: errnames, dependencies: (function () { try { return { indexedDB: _global.indexedDB || _global.mozIndexedDB || _global.webkitIndexedDB || _global.msIndexedDB, IDBKeyRange: _global.IDBKeyRange || _global.webkitIDBKeyRange }; } catch (e) { return { indexedDB: null, IDBKeyRange: null }; } })(), semVer: DEXIE_VERSION, version: DEXIE_VERSION.split('.') .map(function (n) { return parseInt(n); }) .reduce(function (p, c, i) { return p + (c / Math.pow(10, i * 2)); }), default: Dexie$1, Dexie: Dexie$1 })); Dexie$1.maxKey = getMaxKey(Dexie$1.dependencies.IDBKeyRange); initDatabaseEnumerator(Dexie.dependencies.indexedDB); DexiePromise.rejectionMapper = mapError; setDebug(debug, dexieStackFrameFilter); export default Dexie;