Commit b0f722a0 authored by Guillaume Royer's avatar Guillaume Royer

feat(elasticlunr storage): handle multiple tab shared index

- use localStorage to notify changes between tabs on the same domain
parent e0efbb85
...@@ -19,11 +19,30 @@ ...@@ -19,11 +19,30 @@
*/ */
/*jslint sloppy: true, nomen: true */ /*jslint sloppy: true, nomen: true */
/*global jIO, RSVP, Blob, Query, elasticlunr */ /*global jIO, RSVP, Blob, Query, elasticlunr, localStorage */
(function (jIO, RSVP, Blob, Query, elasticlunr) { (function (jIO, RSVP, Blob, Query, elasticlunr, localStorage) {
'use strict'; 'use strict';
var elasticlunrStorageKey = 'jio_elasticlunr'; var elasticlunrStorageKey = 'jio_elasticlunr',
notifyChangeKey = elasticlunrStorageKey + '_notify';
function notifyIndexChanged() {
localStorage.setItem(notifyChangeKey, JSON.stringify({
type: 'update',
date: new Date()
}));
// no need to keep the actual value
localStorage.removeItem(notifyChangeKey);
}
function listenIndexChanged(context) {
window.addEventListener('storage', function (event) {
// since we remove the item after setting it, make sure we only run once
if (event.newValue && event.key === notifyChangeKey) {
context._onIndexChanged();
}
});
}
function findDuplicates(array) { function findDuplicates(array) {
var sorted = array.slice().sort(), var sorted = array.slice().sort(),
...@@ -149,8 +168,16 @@ ...@@ -149,8 +168,16 @@
this._sub_storage.__type; this._sub_storage.__type;
this._index_id = spec.id || 'id'; this._index_id = spec.id || 'id';
this._index_fields = spec.index_fields || []; this._index_fields = spec.index_fields || [];
listenIndexChanged(this);
} }
ElasticlunrStorage.prototype._onIndexChanged = function () {
// force-reload index from storage
this._index = null;
this._getIndex();
};
ElasticlunrStorage.prototype._getIndex = function () { ElasticlunrStorage.prototype._getIndex = function () {
var context = this; var context = this;
...@@ -181,6 +208,9 @@ ...@@ -181,6 +208,9 @@
ElasticlunrStorage.prototype._saveIndex = function () { ElasticlunrStorage.prototype._saveIndex = function () {
var context = this; var context = this;
// notify other tabs that the index has changed
notifyIndexChanged();
return this._getIndex() return this._getIndex()
.push(function (index) { .push(function (index) {
var data = JSON.stringify(index); var data = JSON.stringify(index);
...@@ -336,4 +366,4 @@ ...@@ -336,4 +366,4 @@
}; };
jIO.addStorage('elasticlunr', ElasticlunrStorage); jIO.addStorage('elasticlunr', ElasticlunrStorage);
}(jIO, RSVP, Blob, Query, elasticlunr)); }(jIO, RSVP, Blob, Query, elasticlunr, localStorage));
/*jslint nomen: true */ /*jslint nomen: true */
/*global jIO, QUnit, sinon, Blob, elasticlunr */ /*global jIO, QUnit, sinon, Blob, elasticlunr, localStorage */
(function (jIO, QUnit, sinon, Blob, elasticlunr) { (function (jIO, QUnit, sinon, Blob, elasticlunr, localStorage) {
"use strict"; "use strict";
var test = QUnit.test, var test = QUnit.test,
stop = QUnit.stop, stop = QUnit.stop,
...@@ -1261,7 +1261,15 @@ ...@@ -1261,7 +1261,15 @@
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// ElasticlunrStorage.__storage._saveIndex // ElasticlunrStorage.__storage._saveIndex
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
module("ElasticlunrStorage.__storage._saveIndex"); module("ElasticlunrStorage.__storage._saveIndex", {
setup: function () {
this.notifyIndexChangedStub = sinon.stub(localStorage, "setItem");
},
teardown: function () {
this.notifyIndexChangedStub.restore();
delete this.notifyIndexChangedStub;
}
});
test("stores index as attachment", function () { test("stores index as attachment", function () {
Index200.prototype.getAttachment = function () { Index200.prototype.getAttachment = function () {
...@@ -1277,7 +1285,8 @@ ...@@ -1277,7 +1285,8 @@
type: "elasticlunr200" type: "elasticlunr200"
} }
}), }),
blob = new Blob(["{}"]); blob = new Blob(["{}"]),
context = this;
jio.__storage._getIndex = function () { jio.__storage._getIndex = function () {
return new RSVP.Queue().push(function () { return new RSVP.Queue().push(function () {
...@@ -1301,11 +1310,15 @@ ...@@ -1301,11 +1310,15 @@
}; };
stop(); stop();
expect(4); expect(5);
jio.__storage._saveIndex() jio.__storage._saveIndex()
.then(function (result) { .then(function (result) {
equal(result, "OK"); equal(result, "OK");
ok(
context.notifyIndexChangedStub.called,
"load index count " + context.callCount
);
}) })
.fail(function (error) { .fail(function (error) {
ok(false, error); ok(false, error);
...@@ -1314,4 +1327,4 @@ ...@@ -1314,4 +1327,4 @@
start(); start();
}); });
}); });
}(jIO, QUnit, sinon, Blob, elasticlunr)); }(jIO, QUnit, sinon, Blob, elasticlunr, localStorage));
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