File: development/js/utils/mediator.js
import type from './type';
/**
* Mediator utility
*
* @module Utils
* @class Utils.Mediator
* @static
*/
var topics = {},
unique = 0;
/**
* Unsubscribes all listeners from all channels
*
* @method unsubscribeAll
* @for Utils.Mediator
* @return {undefined}
*
* @example
* import mediator from './utils/mediator';
*
* mediator.unsubscribeAll();
*/
function unsubscribeAll () {
topics = {};
}
/**
* Subscribes a listener to a (optionally new) topic/channel on the mediator.
* Optionally accepts a third argument which defines the scope the listener
* is called upon (e. g. where "this" points to)
*
* @method subscribe
* @for Utils.Mediator
* @param {string} topic Topic or channel to subscribe to
* @param {function} handler The listener function to call on activation
* @param {any} [scope = undefined] Optional scope for the handler function
* @return {string} Identifier key to use when unsubscribing
*
* @example
* import mediator from './utils/mediator';
*
* const someChannelID = mediator.subscribe('some-channel', (data) => {
* console.log(data);
* });
*/
function subscribe (topic, handler, scope) {
var identifier,
func;
if (!topics.hasOwnProperty(topic)) {
topics[topic] = [];
}
identifier = 'mediator.' + topic + '.' + (unique += 1);
func = !type.isNil(scope) && type.isObject(scope) ?
handler.bind(scope) :
handler;
topics[topic].push({
id: identifier,
fn: func
});
return identifier;
}
/**
* Removes a previously made subscription
*
* @method unsubscribe
* @for Utils.Mediator
* @param {string} identifier Identifier key of channel to unsubscribe from
* @param {boolean} True on success
*
* @example
* import mediator from './utils/mediator';
*
* const someChannelID = mediator.subscribe('some-channel', (data) => {
* console.log(data);
* });
*
* // ... later in code ...
*
* mediator.unsubscribe(someChannelID);
*/
function unsubscribe (identifier) {
var topic;
if (!type.isString(identifier)) {
return false;
}
topic = identifier.split('.')[1];
if (!topics.hasOwnProperty(topic)) {
return false;
}
topics[topic] = topics[topic].filter((t) => t.id !== identifier);
return true;
}
/**
* Allows to push/publish data over a channel to connected listeners
*
* @method publish
* @for Utils.Mediator
* @param {string} topic Topic or channel to publish into
* @param {boolean} True if the topic exists
*
* @example
* import mediator from './utils/mediator';
*
* mediator.subscribe('some-channel', (data) => {
* console.log(data);
* });
*
* // ... later in code ...
*
* mediator.publish('some-channel', 1); // -> logs "1" into the console
*/
function publish (topic, data) {
if (!topics.hasOwnProperty(topic)) {
return false;
}
topics[topic].forEach((t) => t.fn(data));
return true;
}
export default {
subscribe: subscribe,
unsubscribe: unsubscribe,
unsubscribeAll: unsubscribeAll,
publish: publish
};