jsonstore-js
Version:
A javascript JSON data store with manifold abilities of data processing
104 lines (100 loc) • 3.25 kB
JavaScript
;
function PathListener(options) {
options = options || {};
this.deepEqual = options.deepEqual === true;
this.copyStore = options.copyStore;
this.listenerTree = {};
this.groupRefs = {};
this.store = options.store || {};
this.flashKeys = options.flashKeys || {};
}
PathListener.prototype = {
_copyData: function _copyData(data) {
if (data === undefined) return data;
return this.copyStore ? JSON.parse(JSON.stringify(data)) : data;
},
_removeListener: function _removeListener(listeners, cb) {
var index = listeners.indexOf(cb);
index > -1 && (listeners[index] = null);
return index;
},
registerListener: function registerListener(path, cb, group, check) {
group = typeof group === 'string' ? group : null;
check = group === null ? group !== false : check !== false;
var i = 0,
len = path.length,
pathItem = void 0,
treeRef = this.listenerTree,
listenerIndex = void 0;
while (i < len) {
pathItem = path[i++];
if (treeRef[pathItem] === undefined) {
treeRef[pathItem] = { children: {}, listeners: [] };
}
treeRef = i === len ? treeRef[pathItem] : treeRef[pathItem].children;
}
listenerIndex = treeRef.listeners.indexOf(cb);
listenerIndex = listenerIndex === -1 ? treeRef.listeners.push(cb) - 1 : listenerIndex;
if (group !== null) {
if (this.groupRefs[group] === undefined) {
this.groupRefs[group] = [];
}
this.groupRefs[group].push([treeRef.listeners, listenerIndex]);
}
if (check) {
this.checkPath(path);
}
},
checkPath: function checkPath(path) {
var _this = this;
var i = 0,
len = path.length,
pathItem = void 0,
treeRef = this.listenerTree,
dataRef = this.store;
while (i < len) {
if (dataRef === undefined) break;
pathItem = path[i++];
dataRef = dataRef[pathItem];
if (treeRef[pathItem] !== undefined) {
treeRef[pathItem].listeners.forEach(function (listener) {
typeof listener === 'function' && listener(_this._copyData(dataRef));
});
} else {
break;
}
treeRef = treeRef[pathItem].children;
}
if (path.length === 1 && this.flashKeys[path[0]]) {
this.store[path[0]] = null;
}
},
removeAllListeners: function removeAllListeners() {
this.listenerTree = {};
this.groupRefs = {};
},
removeListenerByPath: function removeListenerByPath(path, cb) {
if (typeof cb !== 'function') return void 0;
var i = 0,
len = path.length,
pathItem = void 0,
treeRef = this.listenerTree;
while (i < len) {
pathItem = path[i++];
if (treeRef[pathItem] === undefined) {
return void 0;
}
treeRef = i === len ? treeRef[pathItem] : treeRef[pathItem].children;
}
this._removeListener(treeRef.listeners, cb);
},
removeListenerByGroup: function removeListenerByGroup(group) {
var groupListeners = this.groupRefs[group];
if (groupListeners !== undefined) {
groupListeners.forEach(function (pair) {
typeof pair[0][pair[1]] === 'function' && (pair[0][pair[1]] = null);
});
}
}
};
module.exports = PathListener;