blob: 6a33662ac46ee3e813e8c3cbcdeeb9839e01d774 [file] [log] [blame]
import EventEmitter from 'events';
import hasLocalStorage from './env/hasLocalStorage';
import pick from './pick';
import nextTick from './nextTick';
export default class Changes extends EventEmitter {
constructor() {
super();
this._listeners = {};
if (hasLocalStorage()) {
addEventListener("storage", (e) => {
this.emit(e.key);
});
}
}
addListener(dbName, id, db, opts) {
if (this._listeners[id]) {
return;
}
var inprogress = false;
var self = this;
function eventFunction() {
if (!self._listeners[id]) {
return;
}
if (inprogress) {
inprogress = 'waiting';
return;
}
inprogress = true;
var changesOpts = pick(opts, [
'style', 'include_docs', 'attachments', 'conflicts', 'filter',
'doc_ids', 'view', 'since', 'query_params', 'binary', 'return_docs'
]);
function onError() {
inprogress = false;
}
db.changes(changesOpts).on('change', function (c) {
if (c.seq > opts.since && !opts.cancelled) {
opts.since = c.seq;
opts.onChange(c);
}
}).on('complete', function () {
if (inprogress === 'waiting') {
nextTick(eventFunction);
}
inprogress = false;
}).on('error', onError);
}
this._listeners[id] = eventFunction;
this.on(dbName, eventFunction);
}
removeListener(dbName, id) {
if (!(id in this._listeners)) {
return;
}
super.removeListener(dbName, this._listeners[id]);
delete this._listeners[id];
}
notifyLocalWindows(dbName) {
//do a useless change on a storage thing
//in order to get other windows's listeners to activate
if (hasLocalStorage()) {
localStorage[dbName] = (localStorage[dbName] === "a") ? "b" : "a";
}
}
notify(dbName) {
this.emit(dbName);
this.notifyLocalWindows(dbName);
}
}