Update postie to have multiple inbox

Signed-off-by: Ajay Bura <ajbura@gmail.com>
This commit is contained in:
Ajay Bura 2022-03-03 18:33:58 +05:30
parent b0c4c53880
commit 8df630ee0c

View file

@ -5,28 +5,28 @@ class Postie {
_getSubscribers(topic) { _getSubscribers(topic) {
const subscribers = this._topics.get(topic); const subscribers = this._topics.get(topic);
if (typeof subscribers === 'undefined') { if (subscribers === undefined) {
throw new Error(`Topic:"${topic}" doesn't exist.`); throw new Error(`Topic:"${topic}" doesn't exist.`);
} }
return subscribers; return subscribers;
} }
_getSubscriber(topic, address) { _getInboxes(topic, address) {
const subscribers = this._getSubscribers(topic); const subscribers = this._getSubscribers(topic);
const subscriber = subscribers.get(address); const inboxes = subscribers.get(address);
if (typeof subscriber === 'undefined') { if (inboxes === undefined) {
throw new Error(`Subscriber on topic:"${topic}" at address:"${address}" doesn't exist.`); throw new Error(`Inbox on topic:"${topic}" at address:"${address}" doesn't exist.`);
} }
return subscriber; return inboxes;
} }
hasTopic(topic) { hasTopic(topic) {
return typeof this._topics.get(topic) !== 'undefined'; return this._topics.get(topic) !== undefined;
} }
hasSubscriber(topic, address) { hasSubscriber(topic, address) {
const subscribers = this._getSubscribers(topic); const subscribers = this._getSubscribers(topic);
return typeof subscribers.get(address) !== 'undefined'; return subscribers.get(address) !== undefined;
} }
hasTopicAndSubscriber(topic, address) { hasTopicAndSubscriber(topic, address) {
@ -45,24 +45,29 @@ class Postie {
throw new TypeError('Inbox must be a function.'); throw new TypeError('Inbox must be a function.');
} }
if (typeof this._topics.get(topic) === 'undefined') { if (this._topics.has(topic) === false) {
this._topics.set(topic, new Map()); this._topics.set(topic, new Map());
} }
const subscribers = this._topics.get(topic); const subscribers = this._topics.get(topic);
if (subscribers.get(address)) {
throw new Error(`Subscription on topic:"${topic}" at address:"${address}" already exist.`); const inboxes = subscribers.get(address) ?? new Set();
} inboxes.add(inbox);
subscribers.set(address, inbox); subscribers.set(address, inboxes);
return () => this.unsubscribe(topic, address, inbox);
} }
unsubscribe(topic, address) { unsubscribe(topic, address, inbox) {
const subscribers = this._getSubscribers(topic); const subscribers = this._getSubscribers(topic);
if (subscribers.has(address)) { if (!subscribers) throw new Error(`Unable to unsubscribe. Topic: "${topic}" doesn't exist.`);
subscribers.delete(address);
} else throw new Error(`Unable to unsubscribe. Subscriber on topic:"${topic}" at address:"${address}" doesn't exist`); const inboxes = subscribers.get(address);
if (subscribers.size === 0) { if (!inboxes) throw new Error(`Unable to unsubscribe. Subscriber on topic:"${topic}" at address:"${address}" doesn't exist`);
this._topics.delete(topic);
} if (!inboxes.delete(inbox)) throw new Error('Unable to unsubscribe. Inbox doesn\'t exist');
if (inboxes.size === 0) subscribers.delete(address);
if (subscribers.size === 0) this._topics.delete(topic);
} }
/** /**
@ -71,20 +76,21 @@ class Postie {
* @param {*} data - Data to deliver to subscriber * @param {*} data - Data to deliver to subscriber
*/ */
post(topic, address, data) { post(topic, address, data) {
const sendPost = (subscriber, addr) => { const sendPost = (inboxes, addr) => {
if (typeof subscriber === 'undefined') { if (inboxes === undefined) {
throw new Error(`Unable to post on topic:"${topic}" at address:"${addr}". Subscriber doesn't exist.`); throw new Error(`Unable to post on topic:"${topic}" at address:"${addr}". Subscriber doesn't exist.`);
} }
subscriber(data); inboxes.forEach((inbox) => inbox(data));
}; };
if (Array.isArray(address)) {
if (typeof address === 'string') {
sendPost(this._getInboxes(topic, address), address);
return;
}
const subscribers = this._getSubscribers(topic); const subscribers = this._getSubscribers(topic);
address.forEach((addr) => { address.forEach((addr) => {
sendPost(subscribers.get(addr), addr); sendPost(subscribers.get(addr), addr);
}); });
return;
}
sendPost(this._getSubscriber(topic, address), address);
} }
} }