define(["exports"], function (exports) {
  "use strict";

  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  exports.pub = pub;
  exports.sub = sub;
  exports.unsub = unsub;
  /**
   * Module core/pubsubhub
   *
   * Returns a singleton that can be used for message broadcasting
   * and message receiving. Replaces legacy "msg" code in ReSpec.
   */
  var name = exports.name = "core/pubsubhub";

  var subscriptions = new Map();

  function pub(topic) {
    for (var _len = arguments.length, data = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
      data[_key - 1] = arguments[_key];
    }

    if (!subscriptions.has(topic)) {
      return; // Nothing to do...
    }
    Array.from(subscriptions.get(topic)).forEach(function (cb) {
      return cb.apply(undefined, data);
    });
    if (window.parent === window.self) {
      return;
    }
    // If this is an iframe, postMessage parent (used in testing).
    var args = data
    // to structured clonable
    .map(function (arg) {
      return String(JSON.stringify(arg.stack || arg));
    });
    window.parent.postMessage({ topic: topic, args: args }, window.parent.location.origin);
  }
  /**
   * Subscribes to a message type.
   *
   * @param  {string} topic      The topic to subscribe to (e.g., "start-all")
   * @param  {Function} cb       Callback function
   * @param  {Boolean} opts.once Add prop "once" for single notification.
   * @return {Object}            An object that should be considered opaque,
   *                             used for unsubscribing from messages.
   */
  function sub(topic, cb) {
    var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { once: false };

    if (opts.once) {
      return sub(topic, function wrapper() {
        unsub({ topic: topic, cb: wrapper });
        cb.apply(undefined, arguments);
      });
    }
    if (subscriptions.has(topic)) {
      subscriptions.get(topic).add(cb);
    } else {
      subscriptions.set(topic, new Set([cb]));
    }
    return { topic: topic, cb: cb };
  }
  /**
   * Unsubscribe from messages.
   *
   * @param {Object} opaque The object that was returned from calling sub()
   */
  function unsub(_ref) {
    var topic = _ref.topic,
        cb = _ref.cb;

    // opaque is whatever is returned by sub()
    var callbacks = subscriptions.get(topic);
    if (!callbacks || !callbacks.has(cb)) {
      console.warn("Already unsubscribed:", topic, cb);
      return false;
    }
    return callbacks.delete(cb);
  }

  sub("error", function (err) {
    console.error(err, err.stack);
  });

  sub("warn", function (str) {
    console.warn(str);
  });
});
//# sourceMappingURL=pubsubhub.js.map