dexie
Version:
A Minimalistic Wrapper for IndexedDB
1,432 lines (1,419 loc) • 209 kB
JavaScript
/*
* Dexie.js - a minimalistic wrapper for IndexedDB
* ===============================================
*
* By David Fahlander, david.fahlander@gmail.com
*
* Version 3.2.4, Tue May 30 2023
*
* https://dexie.org
*
* Apache License Version 2.0, January 2004, http://www.apache.org/licenses/
*/
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
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 __spreadArray(to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
}
var _global = typeof globalThis !== 'undefined' ? globalThis :
typeof self !== 'undefined' ? self :
typeof window !== 'undefined' ? window :
global;
var keys = Object.keys;
var isArray = Array.isArray;
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));
(typeof Reflect === "undefined" ? keys : Reflect.ownKeys)(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$1(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 || !hasOwn(obj, currentKeyPath))
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,FileSystemFileHandle,ArrayBuffer,DataView,Uint8ClampedArray,ImageBitmap,ImageData,Map,Set,CryptoKey"
.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]; });
arrayToObject(intrinsicTypeNames, function (x) { return [x, true]; });
var circularRefs = null;
function deepClone(any) {
circularRefs = typeof WeakMap !== 'undefined' && new WeakMap();
var rv = innerDeepClone(any);
circularRefs = null;
return rv;
}
function innerDeepClone(any) {
if (!any || typeof any !== 'object')
return any;
var rv = circularRefs && circularRefs.get(any);
if (rv)
return rv;
if (isArray(any)) {
rv = [];
circularRefs && circularRefs.set(any, rv);
for (var i = 0, l = any.length; i < l; ++i) {
rv.push(innerDeepClone(any[i]));
}
}
else if (intrinsicTypes.indexOf(any.constructor) >= 0) {
rv = any;
}
else {
var proto = getProto(any);
rv = proto === Object.prototype ? {} : Object.create(proto);
circularRefs && circularRefs.set(any, rv);
for (var prop in any) {
if (hasOwn(any, prop)) {
rv[prop] = innerDeepClone(any[prop]);
}
}
}
return rv;
}
var toString = {}.toString;
function toStringTag(o) {
return toString.call(o).slice(8, -1);
}
var iteratorSymbol = typeof Symbol !== 'undefined' ?
Symbol.iterator :
'@@iterator';
var getIteratorOf = typeof iteratorSymbol === "symbol" ? 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 {
getErrorWithStack.arguments;
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",
MissingAPI: "IndexedDB API missing. Please visit https://tinyurl.com/y2uuvskb"
};
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 = Object.keys(failures).map(function (pos) { return failures[pos]; });
this.failuresByPos = 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,
MAX_LONG_STACKS = 20, ZONE_ECHO_LIMIT = 100, _a$1 = typeof Promise === 'undefined' ?
[] :
(function () {
var globalP = Promise.resolve();
if (typeof crypto === 'undefined' || !crypto.subtle)
return [globalP, getProto(globalP), globalP];
var nativeP = crypto.subtle.digest("SHA-512", new Uint8Array([0]));
return [
nativeP,
getProto(nativeP),
globalP
];
})(), resolvedNativePromise = _a$1[0], nativePromiseProto = _a$1[1], resolvedGlobalPromise = _a$1[2], 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 = function (callback, args) {
microtickQueue.push([callback, args]);
if (needsNewPhysicalTick) {
schedulePhysicalTick();
needsNewPhysicalTick = false;
}
};
var isOutsideMicroTick = true,
needsNewPhysicalTick = true,
unhandledErrors = [],
rejectingErrors = [],
currentFulfiller = null, 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);
var cleanup = possibleAwait && !decrementExpectedAwaits();
var rv = new DexiePromise(function (resolve, reject) {
propagateToListener(_this, new Listener(nativeAwaitCompatibleWrap(onFulfilled, psd, possibleAwait, cleanup), nativeAwaitCompatibleWrap(onRejected, psd, possibleAwait, cleanup), 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; }
},
totalEchoes: { get: function () { return totalEchoes; } },
newPSD: newScope,
usePSD: usePSD,
scheduler: {
get: function () { return asap; },
set: function (value) { asap = 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(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(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(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, 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)
extend(psd, props);
++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() {
if (!task.awaits)
return false;
if (--task.awaits === 0)
task.id = 0;
task.echoes = task.awaits * ZONE_ECHO_LIMIT;
return true;
}
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, cleanup) {
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);
if (cleanup)
enqueueNativeMicroTask(decrementExpectedAwaits);
}
};
}
function getPatchedPromiseThen(origThen, zone) {
return function (onResolved, onRejected) {
return origThen.call(this, nativeAwaitCompatibleWrap(onResolved, zone), nativeAwaitCompatibleWrap(onRejected, zone));
};
}
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.idbdb || (!db._state.openComplete && (!PSD.letThrough && !db._vip))) {
if (db._state.openComplete) {
return rejection(new exceptions.DatabaseClosed(db._state.dbOpenError));
}
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();
db._state.PR1398_maxLoop = 3;
}
catch (ex) {
if (ex.name === errnames.InvalidState && db.isOpen() && --db._state.PR1398_maxLoop > 0) {
console.warn('Dexie: Need to reopen db');
db._close();
return db.open().then(function () { return tempTransaction(db, mode, storeNames, fn); });
}
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.2.4';
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<string | number | Date>.";
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
};
function workaroundForUndefinedPrimKey(keyPath) {
return typeof keyPath === "string" && !/\./.test(keyPath)
? function (obj) {
if (obj[keyPath] === undefined && (keyPath in obj)) {
obj = deepClone(obj);
delete obj[keyPath];
}
return obj;
}
: function (obj) { return obj; };
}
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 ne