summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/lib/utils/pubsub.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/lib/utils/pubsub.js')
-rw-r--r--app/assets/javascripts/lib/utils/pubsub.js36
1 files changed, 36 insertions, 0 deletions
diff --git a/app/assets/javascripts/lib/utils/pubsub.js b/app/assets/javascripts/lib/utils/pubsub.js
new file mode 100644
index 00000000000..6a9da4e8003
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/pubsub.js
@@ -0,0 +1,36 @@
+/**
+ * @module message_queue
+ *
+ * Implements a simple, async messaging system with pub/sub mechanics. Useful for getting jQuery controls and Vue components to talk to each other.
+ */
+
+const topics = {};
+
+/**
+ * Publish a message to a topic with an optional payload. Listeners are invoked asynchronously. If there are no listeners for a topic, nothing happens.
+ */
+export function publish(topic, payload) {
+ const handlers = topics[topic];
+ if (!handlers) return;
+
+ handlers.forEach(handler => {
+ Promise.resolve()
+ .then(() => handler(payload))
+ .catch(e => {
+ throw e;
+ });
+ });
+}
+
+/**
+ * Subscribes to a topic. When a message is published on that topic, the handler will by called.
+ * @returns {Function} A function that unsubscribes the handler from the topic.
+ */
+export function subscribe(topic, handler) {
+ topics[topic] = topics[topic] || [];
+ topics[topic].push(handler);
+
+ return () => {
+ topics[topic] = topics[topic].filter(h => h !== handler);
+ };
+}