bus.js

import { guid } from './random_utils.js';

const DIVIDER  = '@';

/**
 * An event bus. Not sure if we're going to need this. Haven't decided yet if we'll use the bus,
 * or return values directly. Returning values directly precludes loading data on demand, which
 * we might want to do.
 */
class EventBus {
  constructor() {
    this.listeners = new Map();
  }
  /**
   * Register a listener.
   * @param {String} eventType 
   * @param {Function} listener 
   * @return {String} an identifier that can be used later to unregister this listener
   */
  add(eventType, listener) {
    let oneGuid = guid();
    let eventMap = this.listeners.get(eventType) || new Map();
    eventMap.set(oneGuid, listener);
    this.listeners.set(eventType, eventMap);
    return `${eventType}${DIVIDER}${oneGuid}`;
  }
  /**
   * Remove the listener given the string provided during registration.
   * @param {String} listenerKey 
   */
  remove(listenerKey) {
    let [eventType, oneGuid] = listenerKey.split(DIVIDER);
    let eventMap = this.listeners.get(eventType);
    if (eventMap) {
      eventMap.delete(oneGuid);
    }
  }
  /**
   * 
   * @param {String} eventType 
   * @param {Object} payload 
   */
  fire(eventType, payload) {
    let eventMap = this.listeners.get(eventType);
    if (eventMap) {
      for (let listener of eventMap.values()) {
        listener(payload);
      }
    }
  }
}

export default EventBus;
export const BUS = new EventBus();