grid-apps-cmms/src/moto/broker.js

80 lines
No EOL
2.1 KiB
JavaScript

class Broker {
constructor() {
this.topics = {};
}
topics() {
return Object.keys(this.topics);
}
subscribe(topic, listener) {
if (Array.isArray(topic)) {
for (let t of topic) {
this.subscribe(t, listener);
}
return;
}
let topics = this.topics;
let channel = topics[topic];
if (!channel) {
channel = topics[topic] = [];
}
if (channel.indexOf(listener) < 0) {
channel.push(listener);
this.publish(".topic.add", topic);
}
}
unsubscribe(topic, listener) {
let channel = this.topics[topic];
if (!channel) {
return;
}
let index = channel.indexOf(listener);
if (index < 0) {
return;
}
channel.splice(index,1);
if (channel.length === 0) {
delete this.topics[topic];
this.publish(".topic.remove", topic);
}
}
publish(topic, message, options = {}) {
if (Array.isArray(topic)) {
for (let t of topic) {
this.publish(t, message, options);
}
return;
}
if (topic !== ".topic.publish") {
this.publish(".topic.publish", {topic, message, options});
}
let channel = this.topics[topic];
if (channel && channel.length) {
for (let listener of channel) {
try {
listener(message, topic, options);
} catch (e) {
// console.log({listener_error: e, topic, options, listener});
setTimeout(() => { throw e }, 1);
}
}
}
}
// return function bound to a topic
bind(topic, message, options) {
let broker = this;
return function(msg, opt) {
broker.publish(topic, message || msg, options || opt);
}
}
}
// establish default broker when GridApp container present
let gapp = self.gapp;
if (gapp && !gapp.broker) {
gapp.broker = new Broker();
}