chore: add dist for IDB InvalidStateError reconnect

This commit is contained in:
Thodoris Greasidis 2017-05-14 15:42:23 +03:00
parent 719b74dc1f
commit 6c159b8e6b
4 changed files with 588 additions and 324 deletions

454
dist/localforage.js vendored
View File

@ -470,6 +470,10 @@ var supportsBlobs;
var dbContexts;
var toString = Object.prototype.toString;
// Transaction Modes
var READ_ONLY = 'readonly';
var READ_WRITE = 'readwrite';
// Transform a binary string to an array buffer, because otherwise
// weird stuff happens when you try to work with the binary string directly.
// It is known.
@ -502,7 +506,7 @@ function _binStringToArrayBuffer(bin) {
//
function _checkBlobSupportWithoutCaching(idb) {
return new Promise$1(function (resolve) {
var txn = idb.transaction(DETECT_BLOB_SUPPORT_STORE, 'readwrite');
var txn = idb.transaction(DETECT_BLOB_SUPPORT_STORE, READ_WRITE);
var blob = createBlob(['']);
txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob, 'key');
@ -572,6 +576,19 @@ function _advanceReadiness(dbInfo) {
}
}
function _rejectReadiness(dbInfo, err) {
var dbContext = dbContexts[dbInfo.name];
// Dequeue a deferred operation.
var deferredOperation = dbContext.deferredOperations.pop();
// Reject its promise (which is part of the database readiness
// chain of promises).
if (deferredOperation) {
deferredOperation.reject(err);
}
}
function _getConnection(dbInfo, upgradeNeeded) {
return new Promise$1(function (resolve, reject) {
@ -714,6 +731,51 @@ function _fullyReady(callback) {
return promise;
}
// Try to establish a new db connection to replace the
// current one which is broken (i.e. experiencing
// InvalidStateError while creating a transaction).
function _tryReconnect(dbInfo) {
_deferReadiness(dbInfo);
var dbContext = dbContexts[dbInfo.name];
var forages = dbContext.forages;
for (var i = 0; i < forages.length; i++) {
if (forages[i]._dbInfo.db) {
forages[i]._dbInfo.db.close();
forages[i]._dbInfo.db = null;
}
}
return _getConnection(dbInfo, false).then(function (db) {
for (var j = 0; j < forages.length; j++) {
forages[j]._dbInfo.db = db;
}
})["catch"](function (err) {
_rejectReadiness(dbInfo, err);
throw err;
});
}
// FF doesn't like Promises (micro-tasks) and IDDB store operations,
// so we have to do it with callbacks
function createTransaction(dbInfo, mode, callback) {
try {
var tx = dbInfo.db.transaction(dbInfo.storeName, mode);
callback(null, tx);
} catch (err) {
if (!dbInfo.db || err.name === 'InvalidStateError') {
return _tryReconnect(dbInfo).then(function () {
var tx = dbInfo.db.transaction(dbInfo.storeName, mode);
callback(null, tx);
});
}
callback(err);
}
}
// Open the IndexedDB database (automatically creates one if one didn't
// previously exist), using any options set in the config.
function _initStorage(options) {
@ -820,24 +882,33 @@ function getItem(key, callback) {
var promise = new Promise$1(function (resolve, reject) {
self.ready().then(function () {
var dbInfo = self._dbInfo;
var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);
var req = store.get(key);
req.onsuccess = function () {
var value = req.result;
if (value === undefined) {
value = null;
createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) {
if (err) {
return reject(err);
}
if (_isEncodedBlob(value)) {
value = _decodeBlob(value);
}
resolve(value);
};
req.onerror = function () {
reject(req.error);
};
try {
var store = transaction.objectStore(self._dbInfo.storeName);
var req = store.get(key);
req.onsuccess = function () {
var value = req.result;
if (value === undefined) {
value = null;
}
if (_isEncodedBlob(value)) {
value = _decodeBlob(value);
}
resolve(value);
};
req.onerror = function () {
reject(req.error);
};
} catch (e) {
reject(e);
}
});
})["catch"](reject);
});
@ -851,35 +922,46 @@ function iterate(iterator, callback) {
var promise = new Promise$1(function (resolve, reject) {
self.ready().then(function () {
var dbInfo = self._dbInfo;
var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);
var req = store.openCursor();
var iterationNumber = 1;
req.onsuccess = function () {
var cursor = req.result;
if (cursor) {
var value = cursor.value;
if (_isEncodedBlob(value)) {
value = _decodeBlob(value);
}
var result = iterator(value, cursor.key, iterationNumber++);
if (result !== void 0) {
resolve(result);
} else {
cursor["continue"]();
}
} else {
resolve();
createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) {
if (err) {
return reject(err);
}
};
req.onerror = function () {
reject(req.error);
};
try {
var store = transaction.objectStore(self._dbInfo.storeName);
var req = store.openCursor();
var iterationNumber = 1;
req.onsuccess = function () {
var cursor = req.result;
if (cursor) {
var value = cursor.value;
if (_isEncodedBlob(value)) {
value = _decodeBlob(value);
}
var result = iterator(value, cursor.key, iterationNumber++);
// when the iterator callback retuns any
// (non-`undefined`) value, then we stop
// the iteration immediately
if (result !== void 0) {
resolve(result);
} else {
cursor["continue"]();
}
} else {
resolve();
}
};
req.onerror = function () {
reject(req.error);
};
} catch (e) {
reject(e);
}
});
})["catch"](reject);
});
@ -911,35 +993,44 @@ function setItem(key, value, callback) {
}
return value;
}).then(function (value) {
var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');
var store = transaction.objectStore(dbInfo.storeName);
var req = store.put(value, key);
// The reason we don't _save_ null is because IE 10 does
// not support saving the `null` type in IndexedDB. How
// ironic, given the bug below!
// See: https://github.com/mozilla/localForage/issues/161
if (value === null) {
value = undefined;
}
transaction.oncomplete = function () {
// Cast to undefined so the value passed to
// callback/promise is the same as what one would get out
// of `getItem()` later. This leads to some weirdness
// (setItem('foo', undefined) will return `null`), but
// it's not my fault localStorage is our baseline and that
// it's weird.
if (value === undefined) {
value = null;
createTransaction(self._dbInfo, READ_WRITE, function (err, transaction) {
if (err) {
return reject(err);
}
resolve(value);
};
transaction.onabort = transaction.onerror = function () {
var err = req.error ? req.error : req.transaction.error;
reject(err);
};
try {
var store = transaction.objectStore(self._dbInfo.storeName);
var req = store.put(value, key);
// The reason we don't _save_ null is because IE 10 does
// not support saving the `null` type in IndexedDB. How
// ironic, given the bug below!
// See: https://github.com/mozilla/localForage/issues/161
if (value === null) {
value = undefined;
}
transaction.oncomplete = function () {
// Cast to undefined so the value passed to
// callback/promise is the same as what one would get out
// of `getItem()` later. This leads to some weirdness
// (setItem('foo', undefined) will return `null`), but
// it's not my fault localStorage is our baseline and that
// it's weird.
if (value === undefined) {
value = null;
}
resolve(value);
};
transaction.onabort = transaction.onerror = function () {
var err = req.error ? req.error : req.transaction.error;
reject(err);
};
} catch (e) {
reject(e);
}
});
})["catch"](reject);
});
@ -958,30 +1049,37 @@ function removeItem(key, callback) {
var promise = new Promise$1(function (resolve, reject) {
self.ready().then(function () {
var dbInfo = self._dbInfo;
var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');
var store = transaction.objectStore(dbInfo.storeName);
createTransaction(self._dbInfo, READ_WRITE, function (err, transaction) {
if (err) {
return reject(err);
}
// We use a Grunt task to make this safe for IE and some
// versions of Android (including those used by Cordova).
// Normally IE won't like `.delete()` and will insist on
// using `['delete']()`, but we have a build step that
// fixes this for us now.
var req = store["delete"](key);
transaction.oncomplete = function () {
resolve();
};
try {
var store = transaction.objectStore(self._dbInfo.storeName);
// We use a Grunt task to make this safe for IE and some
// versions of Android (including those used by Cordova).
// Normally IE won't like `.delete()` and will insist on
// using `['delete']()`, but we have a build step that
// fixes this for us now.
var req = store["delete"](key);
transaction.oncomplete = function () {
resolve();
};
transaction.onerror = function () {
reject(req.error);
};
transaction.onerror = function () {
reject(req.error);
};
// The request will be also be aborted if we've exceeded our storage
// space.
transaction.onabort = function () {
var err = req.error ? req.error : req.transaction.error;
reject(err);
};
// The request will be also be aborted if we've exceeded our storage
// space.
transaction.onabort = function () {
var err = req.error ? req.error : req.transaction.error;
reject(err);
};
} catch (e) {
reject(e);
}
});
})["catch"](reject);
});
@ -994,19 +1092,27 @@ function clear(callback) {
var promise = new Promise$1(function (resolve, reject) {
self.ready().then(function () {
var dbInfo = self._dbInfo;
var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');
var store = transaction.objectStore(dbInfo.storeName);
var req = store.clear();
createTransaction(self._dbInfo, READ_WRITE, function (err, transaction) {
if (err) {
return reject(err);
}
transaction.oncomplete = function () {
resolve();
};
try {
var store = transaction.objectStore(self._dbInfo.storeName);
var req = store.clear();
transaction.onabort = transaction.onerror = function () {
var err = req.error ? req.error : req.transaction.error;
reject(err);
};
transaction.oncomplete = function () {
resolve();
};
transaction.onabort = transaction.onerror = function () {
var err = req.error ? req.error : req.transaction.error;
reject(err);
};
} catch (e) {
reject(e);
}
});
})["catch"](reject);
});
@ -1019,17 +1125,26 @@ function length(callback) {
var promise = new Promise$1(function (resolve, reject) {
self.ready().then(function () {
var dbInfo = self._dbInfo;
var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);
var req = store.count();
createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) {
if (err) {
return reject(err);
}
req.onsuccess = function () {
resolve(req.result);
};
try {
var store = transaction.objectStore(self._dbInfo.storeName);
var req = store.count();
req.onerror = function () {
reject(req.error);
};
req.onsuccess = function () {
resolve(req.result);
};
req.onerror = function () {
reject(req.error);
};
} catch (e) {
reject(e);
}
});
})["catch"](reject);
});
@ -1048,40 +1163,49 @@ function key(n, callback) {
}
self.ready().then(function () {
var dbInfo = self._dbInfo;
var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);
var advanced = false;
var req = store.openCursor();
req.onsuccess = function () {
var cursor = req.result;
if (!cursor) {
// this means there weren't enough keys
resolve(null);
return;
createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) {
if (err) {
return reject(err);
}
if (n === 0) {
// We have the first key, return it if that's what they
// wanted.
resolve(cursor.key);
} else {
if (!advanced) {
// Otherwise, ask the cursor to skip ahead n
// records.
advanced = true;
cursor.advance(n);
} else {
// When we get here, we've got the nth key.
resolve(cursor.key);
}
}
};
try {
var store = transaction.objectStore(self._dbInfo.storeName);
var advanced = false;
var req = store.openCursor();
req.onerror = function () {
reject(req.error);
};
req.onsuccess = function () {
var cursor = req.result;
if (!cursor) {
// this means there weren't enough keys
resolve(null);
return;
}
if (n === 0) {
// We have the first key, return it if that's what they
// wanted.
resolve(cursor.key);
} else {
if (!advanced) {
// Otherwise, ask the cursor to skip ahead n
// records.
advanced = true;
cursor.advance(n);
} else {
// When we get here, we've got the nth key.
resolve(cursor.key);
}
}
};
req.onerror = function () {
reject(req.error);
};
} catch (e) {
reject(e);
}
});
})["catch"](reject);
});
@ -1094,27 +1218,35 @@ function keys(callback) {
var promise = new Promise$1(function (resolve, reject) {
self.ready().then(function () {
var dbInfo = self._dbInfo;
var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);
var req = store.openCursor();
var keys = [];
req.onsuccess = function () {
var cursor = req.result;
if (!cursor) {
resolve(keys);
return;
createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) {
if (err) {
return reject(err);
}
keys.push(cursor.key);
cursor["continue"]();
};
try {
var store = transaction.objectStore(self._dbInfo.storeName);
var req = store.openCursor();
var keys = [];
req.onerror = function () {
reject(req.error);
};
req.onsuccess = function () {
var cursor = req.result;
if (!cursor) {
resolve(keys);
return;
}
keys.push(cursor.key);
cursor["continue"]();
};
req.onerror = function () {
reject(req.error);
};
} catch (e) {
reject(e);
}
});
})["catch"](reject);
});

File diff suppressed because one or more lines are too long

View File

@ -134,6 +134,10 @@ var supportsBlobs;
var dbContexts;
var toString = Object.prototype.toString;
// Transaction Modes
var READ_ONLY = 'readonly';
var READ_WRITE = 'readwrite';
// Transform a binary string to an array buffer, because otherwise
// weird stuff happens when you try to work with the binary string directly.
// It is known.
@ -166,7 +170,7 @@ function _binStringToArrayBuffer(bin) {
//
function _checkBlobSupportWithoutCaching(idb) {
return new Promise$1(function (resolve) {
var txn = idb.transaction(DETECT_BLOB_SUPPORT_STORE, 'readwrite');
var txn = idb.transaction(DETECT_BLOB_SUPPORT_STORE, READ_WRITE);
var blob = createBlob(['']);
txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob, 'key');
@ -236,6 +240,19 @@ function _advanceReadiness(dbInfo) {
}
}
function _rejectReadiness(dbInfo, err) {
var dbContext = dbContexts[dbInfo.name];
// Dequeue a deferred operation.
var deferredOperation = dbContext.deferredOperations.pop();
// Reject its promise (which is part of the database readiness
// chain of promises).
if (deferredOperation) {
deferredOperation.reject(err);
}
}
function _getConnection(dbInfo, upgradeNeeded) {
return new Promise$1(function (resolve, reject) {
@ -378,6 +395,51 @@ function _fullyReady(callback) {
return promise;
}
// Try to establish a new db connection to replace the
// current one which is broken (i.e. experiencing
// InvalidStateError while creating a transaction).
function _tryReconnect(dbInfo) {
_deferReadiness(dbInfo);
var dbContext = dbContexts[dbInfo.name];
var forages = dbContext.forages;
for (var i = 0; i < forages.length; i++) {
if (forages[i]._dbInfo.db) {
forages[i]._dbInfo.db.close();
forages[i]._dbInfo.db = null;
}
}
return _getConnection(dbInfo, false).then(function (db) {
for (var j = 0; j < forages.length; j++) {
forages[j]._dbInfo.db = db;
}
})["catch"](function (err) {
_rejectReadiness(dbInfo, err);
throw err;
});
}
// FF doesn't like Promises (micro-tasks) and IDDB store operations,
// so we have to do it with callbacks
function createTransaction(dbInfo, mode, callback) {
try {
var tx = dbInfo.db.transaction(dbInfo.storeName, mode);
callback(null, tx);
} catch (err) {
if (!dbInfo.db || err.name === 'InvalidStateError') {
return _tryReconnect(dbInfo).then(function () {
var tx = dbInfo.db.transaction(dbInfo.storeName, mode);
callback(null, tx);
});
}
callback(err);
}
}
// Open the IndexedDB database (automatically creates one if one didn't
// previously exist), using any options set in the config.
function _initStorage(options) {
@ -484,24 +546,33 @@ function getItem(key, callback) {
var promise = new Promise$1(function (resolve, reject) {
self.ready().then(function () {
var dbInfo = self._dbInfo;
var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);
var req = store.get(key);
req.onsuccess = function () {
var value = req.result;
if (value === undefined) {
value = null;
createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) {
if (err) {
return reject(err);
}
if (_isEncodedBlob(value)) {
value = _decodeBlob(value);
}
resolve(value);
};
req.onerror = function () {
reject(req.error);
};
try {
var store = transaction.objectStore(self._dbInfo.storeName);
var req = store.get(key);
req.onsuccess = function () {
var value = req.result;
if (value === undefined) {
value = null;
}
if (_isEncodedBlob(value)) {
value = _decodeBlob(value);
}
resolve(value);
};
req.onerror = function () {
reject(req.error);
};
} catch (e) {
reject(e);
}
});
})["catch"](reject);
});
@ -515,35 +586,46 @@ function iterate(iterator, callback) {
var promise = new Promise$1(function (resolve, reject) {
self.ready().then(function () {
var dbInfo = self._dbInfo;
var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);
var req = store.openCursor();
var iterationNumber = 1;
req.onsuccess = function () {
var cursor = req.result;
if (cursor) {
var value = cursor.value;
if (_isEncodedBlob(value)) {
value = _decodeBlob(value);
}
var result = iterator(value, cursor.key, iterationNumber++);
if (result !== void 0) {
resolve(result);
} else {
cursor["continue"]();
}
} else {
resolve();
createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) {
if (err) {
return reject(err);
}
};
req.onerror = function () {
reject(req.error);
};
try {
var store = transaction.objectStore(self._dbInfo.storeName);
var req = store.openCursor();
var iterationNumber = 1;
req.onsuccess = function () {
var cursor = req.result;
if (cursor) {
var value = cursor.value;
if (_isEncodedBlob(value)) {
value = _decodeBlob(value);
}
var result = iterator(value, cursor.key, iterationNumber++);
// when the iterator callback retuns any
// (non-`undefined`) value, then we stop
// the iteration immediately
if (result !== void 0) {
resolve(result);
} else {
cursor["continue"]();
}
} else {
resolve();
}
};
req.onerror = function () {
reject(req.error);
};
} catch (e) {
reject(e);
}
});
})["catch"](reject);
});
@ -575,35 +657,44 @@ function setItem(key, value, callback) {
}
return value;
}).then(function (value) {
var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');
var store = transaction.objectStore(dbInfo.storeName);
var req = store.put(value, key);
// The reason we don't _save_ null is because IE 10 does
// not support saving the `null` type in IndexedDB. How
// ironic, given the bug below!
// See: https://github.com/mozilla/localForage/issues/161
if (value === null) {
value = undefined;
}
transaction.oncomplete = function () {
// Cast to undefined so the value passed to
// callback/promise is the same as what one would get out
// of `getItem()` later. This leads to some weirdness
// (setItem('foo', undefined) will return `null`), but
// it's not my fault localStorage is our baseline and that
// it's weird.
if (value === undefined) {
value = null;
createTransaction(self._dbInfo, READ_WRITE, function (err, transaction) {
if (err) {
return reject(err);
}
resolve(value);
};
transaction.onabort = transaction.onerror = function () {
var err = req.error ? req.error : req.transaction.error;
reject(err);
};
try {
var store = transaction.objectStore(self._dbInfo.storeName);
var req = store.put(value, key);
// The reason we don't _save_ null is because IE 10 does
// not support saving the `null` type in IndexedDB. How
// ironic, given the bug below!
// See: https://github.com/mozilla/localForage/issues/161
if (value === null) {
value = undefined;
}
transaction.oncomplete = function () {
// Cast to undefined so the value passed to
// callback/promise is the same as what one would get out
// of `getItem()` later. This leads to some weirdness
// (setItem('foo', undefined) will return `null`), but
// it's not my fault localStorage is our baseline and that
// it's weird.
if (value === undefined) {
value = null;
}
resolve(value);
};
transaction.onabort = transaction.onerror = function () {
var err = req.error ? req.error : req.transaction.error;
reject(err);
};
} catch (e) {
reject(e);
}
});
})["catch"](reject);
});
@ -622,30 +713,37 @@ function removeItem(key, callback) {
var promise = new Promise$1(function (resolve, reject) {
self.ready().then(function () {
var dbInfo = self._dbInfo;
var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');
var store = transaction.objectStore(dbInfo.storeName);
createTransaction(self._dbInfo, READ_WRITE, function (err, transaction) {
if (err) {
return reject(err);
}
// We use a Grunt task to make this safe for IE and some
// versions of Android (including those used by Cordova).
// Normally IE won't like `.delete()` and will insist on
// using `['delete']()`, but we have a build step that
// fixes this for us now.
var req = store["delete"](key);
transaction.oncomplete = function () {
resolve();
};
try {
var store = transaction.objectStore(self._dbInfo.storeName);
// We use a Grunt task to make this safe for IE and some
// versions of Android (including those used by Cordova).
// Normally IE won't like `.delete()` and will insist on
// using `['delete']()`, but we have a build step that
// fixes this for us now.
var req = store["delete"](key);
transaction.oncomplete = function () {
resolve();
};
transaction.onerror = function () {
reject(req.error);
};
transaction.onerror = function () {
reject(req.error);
};
// The request will be also be aborted if we've exceeded our storage
// space.
transaction.onabort = function () {
var err = req.error ? req.error : req.transaction.error;
reject(err);
};
// The request will be also be aborted if we've exceeded our storage
// space.
transaction.onabort = function () {
var err = req.error ? req.error : req.transaction.error;
reject(err);
};
} catch (e) {
reject(e);
}
});
})["catch"](reject);
});
@ -658,19 +756,27 @@ function clear(callback) {
var promise = new Promise$1(function (resolve, reject) {
self.ready().then(function () {
var dbInfo = self._dbInfo;
var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');
var store = transaction.objectStore(dbInfo.storeName);
var req = store.clear();
createTransaction(self._dbInfo, READ_WRITE, function (err, transaction) {
if (err) {
return reject(err);
}
transaction.oncomplete = function () {
resolve();
};
try {
var store = transaction.objectStore(self._dbInfo.storeName);
var req = store.clear();
transaction.onabort = transaction.onerror = function () {
var err = req.error ? req.error : req.transaction.error;
reject(err);
};
transaction.oncomplete = function () {
resolve();
};
transaction.onabort = transaction.onerror = function () {
var err = req.error ? req.error : req.transaction.error;
reject(err);
};
} catch (e) {
reject(e);
}
});
})["catch"](reject);
});
@ -683,17 +789,26 @@ function length(callback) {
var promise = new Promise$1(function (resolve, reject) {
self.ready().then(function () {
var dbInfo = self._dbInfo;
var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);
var req = store.count();
createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) {
if (err) {
return reject(err);
}
req.onsuccess = function () {
resolve(req.result);
};
try {
var store = transaction.objectStore(self._dbInfo.storeName);
var req = store.count();
req.onerror = function () {
reject(req.error);
};
req.onsuccess = function () {
resolve(req.result);
};
req.onerror = function () {
reject(req.error);
};
} catch (e) {
reject(e);
}
});
})["catch"](reject);
});
@ -712,40 +827,49 @@ function key(n, callback) {
}
self.ready().then(function () {
var dbInfo = self._dbInfo;
var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);
var advanced = false;
var req = store.openCursor();
req.onsuccess = function () {
var cursor = req.result;
if (!cursor) {
// this means there weren't enough keys
resolve(null);
return;
createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) {
if (err) {
return reject(err);
}
if (n === 0) {
// We have the first key, return it if that's what they
// wanted.
resolve(cursor.key);
} else {
if (!advanced) {
// Otherwise, ask the cursor to skip ahead n
// records.
advanced = true;
cursor.advance(n);
} else {
// When we get here, we've got the nth key.
resolve(cursor.key);
}
}
};
try {
var store = transaction.objectStore(self._dbInfo.storeName);
var advanced = false;
var req = store.openCursor();
req.onerror = function () {
reject(req.error);
};
req.onsuccess = function () {
var cursor = req.result;
if (!cursor) {
// this means there weren't enough keys
resolve(null);
return;
}
if (n === 0) {
// We have the first key, return it if that's what they
// wanted.
resolve(cursor.key);
} else {
if (!advanced) {
// Otherwise, ask the cursor to skip ahead n
// records.
advanced = true;
cursor.advance(n);
} else {
// When we get here, we've got the nth key.
resolve(cursor.key);
}
}
};
req.onerror = function () {
reject(req.error);
};
} catch (e) {
reject(e);
}
});
})["catch"](reject);
});
@ -758,27 +882,35 @@ function keys(callback) {
var promise = new Promise$1(function (resolve, reject) {
self.ready().then(function () {
var dbInfo = self._dbInfo;
var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);
var req = store.openCursor();
var keys = [];
req.onsuccess = function () {
var cursor = req.result;
if (!cursor) {
resolve(keys);
return;
createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) {
if (err) {
return reject(err);
}
keys.push(cursor.key);
cursor["continue"]();
};
try {
var store = transaction.objectStore(self._dbInfo.storeName);
var req = store.openCursor();
var keys = [];
req.onerror = function () {
reject(req.error);
};
req.onsuccess = function () {
var cursor = req.result;
if (!cursor) {
resolve(keys);
return;
}
keys.push(cursor.key);
cursor["continue"]();
};
req.onerror = function () {
reject(req.error);
};
} catch (e) {
reject(e);
}
});
})["catch"](reject);
});

File diff suppressed because one or more lines are too long