mirror of
https://github.com/localForage/localForage.git
synced 2026-02-01 15:32:04 +00:00
chore: add dist for IDB InvalidStateError reconnect
This commit is contained in:
parent
719b74dc1f
commit
6c159b8e6b
454
dist/localforage.js
vendored
454
dist/localforage.js
vendored
@ -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);
|
||||
});
|
||||
|
||||
|
||||
2
dist/localforage.min.js
vendored
2
dist/localforage.min.js
vendored
File diff suppressed because one or more lines are too long
454
dist/localforage.nopromises.js
vendored
454
dist/localforage.nopromises.js
vendored
@ -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);
|
||||
});
|
||||
|
||||
|
||||
2
dist/localforage.nopromises.min.js
vendored
2
dist/localforage.nopromises.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user