Commit 45be1eaf authored by Romain Courteaud's avatar Romain Courteaud

Release 3.44.0

parent 2411a6e0
...@@ -26,7 +26,7 @@ TESTDIR = test ...@@ -26,7 +26,7 @@ TESTDIR = test
EXAMPLEDIR = examples EXAMPLEDIR = examples
EXTERNALDIR = external EXTERNALDIR = external
VERSION = 3.43.0 VERSION = 3.44.0
JIOVERSION = ${DISTDIR}/jio-v${VERSION}.js JIOVERSION = ${DISTDIR}/jio-v${VERSION}.js
JIOLATEST = ${DISTDIR}/jio-latest.js JIOLATEST = ${DISTDIR}/jio-latest.js
JIONODEVERSION = ${DISTDIR}/jio-v${VERSION}-node.js JIONODEVERSION = ${DISTDIR}/jio-v${VERSION}-node.js
......
...@@ -10154,8 +10154,11 @@ var Blob = window.Blob, ...@@ -10154,8 +10154,11 @@ var Blob = window.Blob,
"use strict"; "use strict";
/* Safari does not define DOMError */ /* Safari does not define DOMError */
/* + compat issue with private Firefox */
if (window.DOMError === undefined) { if (window.DOMError === undefined) {
window.DOMError = {}; window.DOMError = function FakeDOMError(message) {
this.message = message;
};
} }
var util = {}, var util = {},
...@@ -12647,6 +12650,100 @@ var jIO = window.jIO, ...@@ -12647,6 +12650,100 @@ var jIO = window.jIO,
jIO.addStorage('replicate', ReplicateStorage); jIO.addStorage('replicate', ReplicateStorage);
}(jIO, RSVP, Rusha, jIO.util.stringify)); }(jIO, RSVP, Rusha, jIO.util.stringify));
/*
* JIO extension for resource replication.
* Copyright (C) 2021 Nexedi SA
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Free Software licenses or any of the Open Source
* Initiative approved licenses and Convey the resulting work. Corresponding
* source of such a combination shall include the source code for all other
* software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
* See https://www.nexedi.com/licensing for rationale and options.
*/
/*jslint nomen: true*/
/*global jIO*/
(function (jIO) {
"use strict";
function FallbackStorage(spec) {
this._sub_storage = this._current_storage = jIO.createJIO(spec.sub_storage);
if (spec.hasOwnProperty('fallback_storage')) {
this._fallback_storage = jIO.createJIO(spec.fallback_storage);
this._checked = false;
} else {
this._checked = true;
}
}
var method_name_list = [
'get',
'put',
'post',
'remove',
'buildQuery',
'getAttachment',
'putAttachment',
'allAttachments',
'repair'
],
i;
function methodFallback(method_name) {
return function () {
var storage = this,
queue = storage._current_storage[method_name].apply(
storage._current_storage,
arguments
),
argument_list = arguments;
if (!storage._checked) {
queue
.push(function (result) {
storage._checked = true;
return result;
}, function (error) {
storage._checked = true;
if ((error instanceof jIO.util.jIOError) &&
(error.status_code === 500)) {
// If storage is not working, use fallback instead
storage._current_storage = storage._fallback_storage;
return storage._current_storage[method_name].apply(
storage._current_storage,
argument_list
);
}
throw error;
});
}
return queue;
};
}
for (i = 0; i < method_name_list.length; i += 1) {
FallbackStorage.prototype[method_name_list[i]] =
methodFallback(method_name_list[i]);
}
FallbackStorage.prototype.hasCapacity = function hasCapacity(name) {
return (this._sub_storage.hasCapacity(name) &&
this._fallback_storage.hasCapacity(name));
};
jIO.addStorage('fallback', FallbackStorage);
}(jIO));
/* /*
* Copyright 2015, Nexedi SA * Copyright 2015, Nexedi SA
* *
...@@ -15095,11 +15192,8 @@ var jIO = window.jIO, ...@@ -15095,11 +15192,8 @@ var jIO = window.jIO,
if (atob(exec[1]) === id) { if (atob(exec[1]) === id) {
attachments[atob(exec[2])] = {}; attachments[atob(exec[2])] = {};
} }
} catch (error) { } catch (ignore) {
// Check if unable to decode base64 data // Check if unable to decode base64 data
if (!error instanceof ReferenceError) {
throw error;
}
} }
} }
} }
...@@ -15165,11 +15259,8 @@ var jIO = window.jIO, ...@@ -15165,11 +15259,8 @@ var jIO = window.jIO,
if (DOCUMENT_REGEXP.test(key)) { if (DOCUMENT_REGEXP.test(key)) {
try { try {
id = atob(DOCUMENT_REGEXP.exec(key)[1]); id = atob(DOCUMENT_REGEXP.exec(key)[1]);
} catch (error) { } catch (ignore) {
// Check if unable to decode base64 data // Check if unable to decode base64 data
if (!error instanceof ReferenceError) {
throw error;
}
} }
if (id !== undefined) { if (id !== undefined) {
id_dict[id] = null; id_dict[id] = null;
...@@ -15179,11 +15270,8 @@ var jIO = window.jIO, ...@@ -15179,11 +15270,8 @@ var jIO = window.jIO,
try { try {
id = atob(exec[1]); id = atob(exec[1]);
attachment = atob(exec[2]); attachment = atob(exec[2]);
} catch (error) { } catch (ignore) {
// Check if unable to decode base64 data // Check if unable to decode base64 data
if (!error instanceof ReferenceError) {
throw error;
}
} }
if (attachment !== undefined) { if (attachment !== undefined) {
if (!id_dict.hasOwnProperty(id)) { if (!id_dict.hasOwnProperty(id)) {
...@@ -15234,11 +15322,8 @@ var jIO = window.jIO, ...@@ -15234,11 +15322,8 @@ var jIO = window.jIO,
id: atob(DOCUMENT_REGEXP.exec(key)[1]), id: atob(DOCUMENT_REGEXP.exec(key)[1]),
value: {} value: {}
}); });
} catch (error) { } catch (ignore) {
// Check if unable to decode base64 data // Check if unable to decode base64 data
if (!error instanceof ReferenceError) {
throw error;
}
} }
} }
} }
......
...@@ -8127,8 +8127,11 @@ return new Parser; ...@@ -8127,8 +8127,11 @@ return new Parser;
"use strict"; "use strict";
/* Safari does not define DOMError */ /* Safari does not define DOMError */
/* + compat issue with private Firefox */
if (window.DOMError === undefined) { if (window.DOMError === undefined) {
window.DOMError = {}; window.DOMError = function FakeDOMError(message) {
this.message = message;
};
} }
var util = {}, var util = {},
...@@ -10924,6 +10927,100 @@ return new Parser; ...@@ -10924,6 +10927,100 @@ return new Parser;
jIO.addStorage('replicate', ReplicateStorage); jIO.addStorage('replicate', ReplicateStorage);
}(jIO, RSVP, Rusha, jIO.util.stringify)); }(jIO, RSVP, Rusha, jIO.util.stringify));
/*
* JIO extension for resource replication.
* Copyright (C) 2021 Nexedi SA
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Free Software licenses or any of the Open Source
* Initiative approved licenses and Convey the resulting work. Corresponding
* source of such a combination shall include the source code for all other
* software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
* See https://www.nexedi.com/licensing for rationale and options.
*/
/*jslint nomen: true*/
/*global jIO*/
(function (jIO) {
"use strict";
function FallbackStorage(spec) {
this._sub_storage = this._current_storage = jIO.createJIO(spec.sub_storage);
if (spec.hasOwnProperty('fallback_storage')) {
this._fallback_storage = jIO.createJIO(spec.fallback_storage);
this._checked = false;
} else {
this._checked = true;
}
}
var method_name_list = [
'get',
'put',
'post',
'remove',
'buildQuery',
'getAttachment',
'putAttachment',
'allAttachments',
'repair'
],
i;
function methodFallback(method_name) {
return function () {
var storage = this,
queue = storage._current_storage[method_name].apply(
storage._current_storage,
arguments
),
argument_list = arguments;
if (!storage._checked) {
queue
.push(function (result) {
storage._checked = true;
return result;
}, function (error) {
storage._checked = true;
if ((error instanceof jIO.util.jIOError) &&
(error.status_code === 500)) {
// If storage is not working, use fallback instead
storage._current_storage = storage._fallback_storage;
return storage._current_storage[method_name].apply(
storage._current_storage,
argument_list
);
}
throw error;
});
}
return queue;
};
}
for (i = 0; i < method_name_list.length; i += 1) {
FallbackStorage.prototype[method_name_list[i]] =
methodFallback(method_name_list[i]);
}
FallbackStorage.prototype.hasCapacity = function hasCapacity(name) {
return (this._sub_storage.hasCapacity(name) &&
this._fallback_storage.hasCapacity(name));
};
jIO.addStorage('fallback', FallbackStorage);
}(jIO));
/* /*
* Copyright 2015, Nexedi SA * Copyright 2015, Nexedi SA
* *
...@@ -14556,11 +14653,8 @@ return new Parser; ...@@ -14556,11 +14653,8 @@ return new Parser;
if (atob(exec[1]) === id) { if (atob(exec[1]) === id) {
attachments[atob(exec[2])] = {}; attachments[atob(exec[2])] = {};
} }
} catch (error) { } catch (ignore) {
// Check if unable to decode base64 data // Check if unable to decode base64 data
if (!error instanceof ReferenceError) {
throw error;
}
} }
} }
} }
...@@ -14626,11 +14720,8 @@ return new Parser; ...@@ -14626,11 +14720,8 @@ return new Parser;
if (DOCUMENT_REGEXP.test(key)) { if (DOCUMENT_REGEXP.test(key)) {
try { try {
id = atob(DOCUMENT_REGEXP.exec(key)[1]); id = atob(DOCUMENT_REGEXP.exec(key)[1]);
} catch (error) { } catch (ignore) {
// Check if unable to decode base64 data // Check if unable to decode base64 data
if (!error instanceof ReferenceError) {
throw error;
}
} }
if (id !== undefined) { if (id !== undefined) {
id_dict[id] = null; id_dict[id] = null;
...@@ -14640,11 +14731,8 @@ return new Parser; ...@@ -14640,11 +14731,8 @@ return new Parser;
try { try {
id = atob(exec[1]); id = atob(exec[1]);
attachment = atob(exec[2]); attachment = atob(exec[2]);
} catch (error) { } catch (ignore) {
// Check if unable to decode base64 data // Check if unable to decode base64 data
if (!error instanceof ReferenceError) {
throw error;
}
} }
if (attachment !== undefined) { if (attachment !== undefined) {
if (!id_dict.hasOwnProperty(id)) { if (!id_dict.hasOwnProperty(id)) {
...@@ -14695,11 +14783,8 @@ return new Parser; ...@@ -14695,11 +14783,8 @@ return new Parser;
id: atob(DOCUMENT_REGEXP.exec(key)[1]), id: atob(DOCUMENT_REGEXP.exec(key)[1]),
value: {} value: {}
}); });
} catch (error) { } catch (ignore) {
// Check if unable to decode base64 data // Check if unable to decode base64 data
if (!error instanceof ReferenceError) {
throw error;
}
} }
} }
} }
...@@ -14901,14 +14986,15 @@ return new Parser; ...@@ -14901,14 +14986,15 @@ return new Parser;
/*jslint nomen: true */ /*jslint nomen: true */
/*global indexedDB, jIO, RSVP, Blob, Math, IDBKeyRange, IDBOpenDBRequest, /*global indexedDB, jIO, RSVP, Blob, Math, IDBKeyRange, IDBOpenDBRequest,
DOMError, Event*/ DOMError, DOMException, Set*/
(function (indexedDB, jIO, RSVP, Blob, Math, IDBKeyRange, IDBOpenDBRequest, (function (indexedDB, jIO, RSVP, Blob, Math, IDBKeyRange, IDBOpenDBRequest,
DOMError) { DOMError, DOMException, Set) {
"use strict"; "use strict";
// Read only as changing it can lead to data corruption // Read only as changing it can lead to data corruption
var UNITE = 2000000; var UNITE = 2000000,
INDEX_PREFIX = 'doc.';
function IndexedDBStorage(description) { function IndexedDBStorage(description) {
if (typeof description.database !== "string" || if (typeof description.database !== "string" ||
...@@ -14917,6 +15003,8 @@ return new Parser; ...@@ -14917,6 +15003,8 @@ return new Parser;
"must be a non-empty string"); "must be a non-empty string");
} }
this._database_name = "jio:" + description.database; this._database_name = "jio:" + description.database;
this._version = description.version;
this._index_key_list = description.index_key_list || [];
} }
IndexedDBStorage.prototype.hasCapacity = function (name) { IndexedDBStorage.prototype.hasCapacity = function (name) {
...@@ -14927,35 +15015,65 @@ return new Parser; ...@@ -14927,35 +15015,65 @@ return new Parser;
return key_list.join("_"); return key_list.join("_");
} }
function handleUpgradeNeeded(evt) { function handleUpgradeNeeded(evt, index_key_list) {
var db = evt.target.result, var db = evt.target.result,
store; store,
current_store_list = Array.from(db.objectStoreNames),
current_index_list,
i,
index_key;
store = db.createObjectStore("metadata", { if (current_store_list.indexOf("metadata") === -1) {
keyPath: "_id", store = db.createObjectStore("metadata", {
autoIncrement: false keyPath: "_id",
}); autoIncrement: false
// It is not possible to use openKeyCursor on keypath directly });
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=19955 // It is not possible to use openKeyCursor on keypath directly
store.createIndex("_id", "_id", {unique: true}); // https://www.w3.org/Bugs/Public/show_bug.cgi?id=19955
store.createIndex("_id", "_id", {unique: true});
} else {
store = evt.target.transaction.objectStore("metadata");
}
store = db.createObjectStore("attachment", { current_index_list = new Set(store.indexNames);
keyPath: "_key_path", current_index_list.delete("_id");
autoIncrement: false for (i = 0; i < index_key_list.length; i += 1) {
}); // Prefix the index name to prevent conflict with _id
store.createIndex("_id", "_id", {unique: false}); index_key = INDEX_PREFIX + index_key_list[i];
if (current_index_list.has(index_key)) {
current_index_list.delete(index_key);
} else {
store.createIndex(index_key, index_key,
{unique: false});
}
}
current_index_list = Array.from(current_index_list);
for (i = 0; i < current_index_list.length; i += 1) {
store.deleteIndex(current_index_list[i]);
}
store = db.createObjectStore("blob", { if (current_store_list.indexOf("attachment") === -1) {
keyPath: "_key_path", store = db.createObjectStore("attachment", {
autoIncrement: false keyPath: "_key_path",
}); autoIncrement: false
store.createIndex("_id_attachment", });
["_id", "_attachment"], {unique: false}); store.createIndex("_id", "_id", {unique: false});
store.createIndex("_id", "_id", {unique: false}); }
if (current_store_list.indexOf("blob") === -1) {
store = db.createObjectStore("blob", {
keyPath: "_key_path",
autoIncrement: false
});
store.createIndex("_id_attachment",
["_id", "_attachment"], {unique: false});
store.createIndex("_id", "_id", {unique: false});
}
} }
function waitForOpenIndexedDB(db_name, callback) { function waitForOpenIndexedDB(storage, callback) {
var request; var request,
db_name = storage._database_name;
function canceller() { function canceller() {
if ((request !== undefined) && (request.result !== undefined)) { if ((request !== undefined) && (request.result !== undefined)) {
...@@ -14965,14 +15083,18 @@ return new Parser; ...@@ -14965,14 +15083,18 @@ return new Parser;
function resolver(resolve, reject) { function resolver(resolve, reject) {
// Open DB // // Open DB //
request = indexedDB.open(db_name); request = indexedDB.open(db_name, storage._version);
request.onerror = function (error) { request.onerror = function (error) {
canceller(); canceller();
if ((error !== undefined) && if ((error !== undefined) &&
(error.target instanceof IDBOpenDBRequest) && (error.target instanceof IDBOpenDBRequest) &&
(error.target.error instanceof DOMError)) { ((error.target.error instanceof DOMError) ||
reject("Connection to: " + db_name + " failed: " + (error.target.error instanceof DOMException))) {
error.target.error.message); reject(new jIO.util.jIOError(
"Connection to: " + db_name + " failed: " +
error.target.error.message,
500
));
} else { } else {
reject(error); reject(error);
} }
...@@ -14993,7 +15115,9 @@ return new Parser; ...@@ -14993,7 +15115,9 @@ return new Parser;
}; };
// Create DB if necessary // // Create DB if necessary //
request.onupgradeneeded = handleUpgradeNeeded; request.onupgradeneeded = function (evt) {
handleUpgradeNeeded(evt, storage._index_key_list);
};
request.onversionchange = function () { request.onversionchange = function () {
canceller(); canceller();
...@@ -15091,7 +15215,7 @@ return new Parser; ...@@ -15091,7 +15215,7 @@ return new Parser;
function pushIncludedMetadata(cursor) { function pushIncludedMetadata(cursor) {
result_list.push({ result_list.push({
"id": cursor.key, "id": cursor.primaryKey,
"value": {}, "value": {},
"doc": cursor.value.doc "doc": cursor.value.doc
}); });
...@@ -15099,24 +15223,25 @@ return new Parser; ...@@ -15099,24 +15223,25 @@ return new Parser;
function pushMetadata(cursor) { function pushMetadata(cursor) {
result_list.push({ result_list.push({
"id": cursor.key, "id": cursor.primaryKey,
"value": {} "value": {}
}); });
} }
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
return waitForOpenIndexedDB(context._database_name, function (db) { return waitForOpenIndexedDB(context, function (db) {
return waitForTransaction(db, ["metadata"], "readonly", return waitForTransaction(db, ["metadata"], "readonly",
function (tx) { function (tx) {
var key = "_id";
if (options.include_docs === true) { if (options.include_docs === true) {
return waitForAllSynchronousCursor( return waitForAllSynchronousCursor(
tx.objectStore("metadata").index("_id").openCursor(), tx.objectStore("metadata").index(key).openCursor(),
pushIncludedMetadata pushIncludedMetadata
); );
} }
return waitForAllSynchronousCursor( return waitForAllSynchronousCursor(
tx.objectStore("metadata").index("_id").openKeyCursor(), tx.objectStore("metadata").index(key).openKeyCursor(),
pushMetadata pushMetadata
); );
}); });
...@@ -15131,7 +15256,7 @@ return new Parser; ...@@ -15131,7 +15256,7 @@ return new Parser;
var context = this; var context = this;
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
return waitForOpenIndexedDB(context._database_name, function (db) { return waitForOpenIndexedDB(context, function (db) {
return waitForTransaction(db, ["metadata"], "readonly", return waitForTransaction(db, ["metadata"], "readonly",
function (tx) { function (tx) {
return waitForIDBRequest(tx.objectStore("metadata").get(id)); return waitForIDBRequest(tx.objectStore("metadata").get(id));
...@@ -15159,7 +15284,7 @@ return new Parser; ...@@ -15159,7 +15284,7 @@ return new Parser;
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
return waitForOpenIndexedDB(context._database_name, function (db) { return waitForOpenIndexedDB(context, function (db) {
return waitForTransaction(db, ["metadata", "attachment"], "readonly", return waitForTransaction(db, ["metadata", "attachment"], "readonly",
function (tx) { function (tx) {
return RSVP.all([ return RSVP.all([
...@@ -15188,7 +15313,7 @@ return new Parser; ...@@ -15188,7 +15313,7 @@ return new Parser;
}; };
IndexedDBStorage.prototype.put = function (id, metadata) { IndexedDBStorage.prototype.put = function (id, metadata) {
return waitForOpenIndexedDB(this._database_name, function (db) { return waitForOpenIndexedDB(this, function (db) {
return waitForTransaction(db, ["metadata"], "readwrite", return waitForTransaction(db, ["metadata"], "readwrite",
function (tx) { function (tx) {
return waitForIDBRequest(tx.objectStore("metadata").put({ return waitForIDBRequest(tx.objectStore("metadata").put({
...@@ -15200,7 +15325,7 @@ return new Parser; ...@@ -15200,7 +15325,7 @@ return new Parser;
}; };
IndexedDBStorage.prototype.remove = function (id) { IndexedDBStorage.prototype.remove = function (id) {
return waitForOpenIndexedDB(this._database_name, function (db) { return waitForOpenIndexedDB(this, function (db) {
return waitForTransaction(db, ["metadata", "attachment", "blob"], return waitForTransaction(db, ["metadata", "attachment", "blob"],
"readwrite", function (tx) { "readwrite", function (tx) {
...@@ -15244,10 +15369,10 @@ return new Parser; ...@@ -15244,10 +15369,10 @@ return new Parser;
if (options === undefined) { if (options === undefined) {
options = {}; options = {};
} }
var db_name = this._database_name, var start,
start,
end, end,
array_buffer_list = []; array_buffer_list = [],
context = this;
start = options.start || 0; start = options.start || 0;
end = options.end; end = options.end;
...@@ -15268,7 +15393,7 @@ return new Parser; ...@@ -15268,7 +15393,7 @@ return new Parser;
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
return waitForOpenIndexedDB(db_name, function (db) { return waitForOpenIndexedDB(context, function (db) {
return waitForTransaction(db, ["blob"], "readonly", return waitForTransaction(db, ["blob"], "readonly",
function (tx) { function (tx) {
var key_path = buildKeyPath([id, name]), var key_path = buildKeyPath([id, name]),
...@@ -15346,7 +15471,7 @@ return new Parser; ...@@ -15346,7 +15471,7 @@ return new Parser;
// Request the full blob // Request the full blob
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
return waitForOpenIndexedDB(db_name, function (db) { return waitForOpenIndexedDB(context, function (db) {
return waitForTransaction(db, ["attachment", "blob"], "readonly", return waitForTransaction(db, ["attachment", "blob"], "readonly",
function (tx) { function (tx) {
var key_path = buildKeyPath([id, name]), var key_path = buildKeyPath([id, name]),
...@@ -15413,7 +15538,7 @@ return new Parser; ...@@ -15413,7 +15538,7 @@ return new Parser;
}; };
IndexedDBStorage.prototype.putAttachment = function (id, name, blob) { IndexedDBStorage.prototype.putAttachment = function (id, name, blob) {
var db_name = this._database_name; var context = this;
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
// Split the blob first // Split the blob first
...@@ -15431,7 +15556,7 @@ return new Parser; ...@@ -15431,7 +15556,7 @@ return new Parser;
handled_size += UNITE; handled_size += UNITE;
} }
return waitForOpenIndexedDB(db_name, function (db) { return waitForOpenIndexedDB(context, function (db) {
return waitForTransaction(db, ["attachment", "blob"], "readwrite", return waitForTransaction(db, ["attachment", "blob"], "readwrite",
function (tx) { function (tx) {
var blob_store, var blob_store,
...@@ -15498,7 +15623,7 @@ return new Parser; ...@@ -15498,7 +15623,7 @@ return new Parser;
}; };
IndexedDBStorage.prototype.removeAttachment = function (id, name) { IndexedDBStorage.prototype.removeAttachment = function (id, name) {
return waitForOpenIndexedDB(this._database_name, function (db) { return waitForOpenIndexedDB(this, function (db) {
return waitForTransaction(db, ["attachment", "blob"], "readwrite", return waitForTransaction(db, ["attachment", "blob"], "readwrite",
function (tx) { function (tx) {
var promise_list = [], var promise_list = [],
...@@ -15530,7 +15655,8 @@ return new Parser; ...@@ -15530,7 +15655,8 @@ return new Parser;
}; };
jIO.addStorage("indexeddb", IndexedDBStorage); jIO.addStorage("indexeddb", IndexedDBStorage);
}(indexedDB, jIO, RSVP, Blob, Math, IDBKeyRange, IDBOpenDBRequest, DOMError)); }(indexedDB, jIO, RSVP, Blob, Math, IDBKeyRange, IDBOpenDBRequest, DOMError,
DOMException, Set));
/* /*
* Copyright 2015, Nexedi SA * Copyright 2015, Nexedi SA
* *
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
{ {
"name": "jio", "name": "jio",
"version": "v3.39.0", "version": "v3.44.0",
"license": "GPLv3+", "license": "GPLv3+",
"author": "Nexedi SA", "author": "Nexedi SA",
"contributors": [ "contributors": [
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment