All files Publisher.js

100% Statements 27/27
100% Branches 40/40
33.33% Functions 1/3
100% Lines 26/26
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 971x                               72x 36x 12x 12x 12x   36x                 42x 21x 11x   21x 21x                 6x 3x                 6x 3x                   42x 6x 15x 5x 3x   2x 1x       6x             10x                 1x      
import {
    Events
} from './Events.js';
 
/**
 * @author Michael Duve <mduve@designmail.net>
 * @file Publish/Subscribe pattern
 * @copyright Michael Duve 2016
 */
export class Publisher {
 
    /**
     * @constructor
     * @param {Number} id = 0 - id of parent instance
     * @return {Publisher} singleton instance of Publisher for chaining
     */
    constructor(id = 0) {
        if (!Publisher.instances[id]) {
            this.subscribers = {};
            this.id = id;
            Publisher.instances[id] = this;
        }
        return Publisher.instances[id];
    }
 
    /**
     * subscribe to a topic
     * @param  {String} type = "any" - a topic
     * @param  {Function} fn = function(){} - a function to callback
     * @return {Publisher} instance of Publisher for chaining
     */
    subscribe(type = "any", fn = function() {}) {
        if (this.subscribers[type] === undefined) {
            this.subscribers[type] = [];
        }
        this.subscribers[type].push(fn);
        return this;
    }
 
    /**
     * unsubscribe from a topic
     * @param  {String} type = "any" - a topic
     * @param  {Function} fn = function(){} - a function to callback
     * @return {Publisher} instance of Publisher for chaining
     */
    unsubscribe(type = "any", fn = function() {}) {
        return this.handle(Events.Publisher.UNSUBSCRIBE, type, fn);
    }
 
    /**
     * publish to a topic
     * @param  {String} type = "any" - a topic
     * @param  {Function} arg = [] - list of parameters
     * @return {Publisher} instance of Publisher for chaining
     */
    publish(type = "any", arg = []) {
        return this.handle(Events.Publisher.PUBLISH, type, arg);
    }
 
    /**
     * handle subscribe to a topic
     * @param  {String} action - eventname
     * @param  {String} type = "any" - a topic
     * @param  {Object} a function to callback or arguments
     * @return {Publisher} instance of Publisher for chaining
     */
    handle(action, type, data) {
        const subs = (this.subscribers[type] !== undefined) ? this.subscribers[type] : [];
        for (const [i, fn] of subs.entries()) {
            if (action === Events.Publisher.PUBLISH) {
                fn(data);
            } else {
                if (fn === data) {
                    subs.splice(i, 1);
                }
            }
        }
        return this;
    }
 
    /**
     * destroys singleton instance
     */
    destroy() {
        Publisher.instances[this.id] = null;
    }
 
}
 
/**
 * singleton instance wrapper
 * @type {Object}
 */
Publisher.instances = {
 
};