API Docs for:
Show:

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
};