text: "use strict";
  
  require("core-js/modules/es.array.filter");
  
  require("core-js/modules/es.array.for-each");
  
  require("core-js/modules/es.array.slice");
  
  require("core-js/modules/es.date.to-string");
  
  require("core-js/modules/es.object.define-properties");
  
  require("core-js/modules/es.object.define-property");
  
  require("core-js/modules/es.object.freeze");
  
  require("core-js/modules/es.object.keys");
  
  require("core-js/modules/es.object.to-string");
  
  require("core-js/modules/es.regexp.to-string");
  
  require("core-js/modules/web.dom-collections.for-each");
  
  require("core-js/modules/web.immediate");
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  exports["default"] = exports.Channel = void 0;
  
  var _utilDeprecate = _interopRequireDefault(require("util-deprecate"));
  
  var _tsDedent = _interopRequireDefault(require("ts-dedent"));
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
  
  function _templateObject() {
    var data = _taggedTemplateLiteral(["\n      channel.addPeerListener is deprecated\n    "]);
  
    _templateObject = function _templateObject() {
      return data;
    };
  
    return data;
  }
  
  function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  
  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
  
  var generateRandomId = function generateRandomId() {
    // generates a random 13 character string
    return Math.random().toString(16).slice(2);
  };
  
  var Channel = /*#__PURE__*/function () {
    function Channel() {
      var _this = this;
  
      var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
          transport = _ref.transport,
          _ref$async = _ref.async,
          async = _ref$async === void 0 ? false : _ref$async;
  
      _classCallCheck(this, Channel);
  
      this.isAsync = void 0;
      this.sender = generateRandomId();
      this.events = {};
      this.data = {};
      this.transport = void 0;
      this.addPeerListener = (0, _utilDeprecate["default"])(function (eventName, listener) {
        _this.addListener(eventName, listener);
      }, (0, _tsDedent["default"])(_templateObject()));
      this.isAsync = async;
  
      if (transport) {
        this.transport = transport;
        this.transport.setHandler(function (event) {
          return _this.handleEvent(event);
        });
      }
    }
  
    _createClass(Channel, [{
      key: "addListener",
      value: function addListener(eventName, listener) {
        this.events[eventName] = this.events[eventName] || [];
        this.events[eventName].push(listener);
      }
    }, {
      key: "emit",
      value: function emit(eventName) {
        var _this2 = this;
  
        for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
          args[_key - 1] = arguments[_key];
        }
  
        var event = {
          type: eventName,
          args: args,
          from: this.sender
        };
        var options = {};
  
        if (args.length >= 1 && args[0] && args[0].options) {
          options = args[0].options;
        }
  
        var handler = function handler() {
          if (_this2.transport) {
            _this2.transport.send(event, options);
          }
  
          _this2.handleEvent(event);
        };
  
        if (this.isAsync) {
          // todo I'm not sure how to test this
          setImmediate(handler);
        } else {
          handler();
        }
      }
    }, {
      key: "last",
      value: function last(eventName) {
        return this.data[eventName];
      }
    }, {
      key: "eventNames",
      value: function eventNames() {
        return Object.keys(this.events);
      }
    }, {
      key: "listenerCount",
      value: function listenerCount(eventName) {
        var listeners = this.listeners(eventName);
        return listeners ? listeners.length : 0;
      }
    }, {
      key: "listeners",
      value: function listeners(eventName) {
        var listeners = this.events[eventName];
        return listeners || undefined;
      }
    }, {
      key: "once",
      value: function once(eventName, listener) {
        var onceListener = this.onceListener(eventName, listener);
        this.addListener(eventName, onceListener);
      }
    }, {
      key: "removeAllListeners",
      value: function removeAllListeners(eventName) {
        if (!eventName) {
          this.events = {};
        } else if (this.events[eventName]) {
          delete this.events[eventName];
        }
      }
    }, {
      key: "removeListener",
      value: function removeListener(eventName, listener) {
        var listeners = this.listeners(eventName);
  
        if (listeners) {
          this.events[eventName] = listeners.filter(function (l) {
            return l !== listener;
          });
        }
      }
    }, {
      key: "on",
      value: function on(eventName, listener) {
        this.addListener(eventName, listener);
      }
    }, {
      key: "off",
      value: function off(eventName, listener) {
        this.removeListener(eventName, listener);
      }
    }, {
      key: "handleEvent",
      value: function handleEvent(event) {
        var listeners = this.listeners(event.type);
  
        if (listeners && listeners.length) {
          listeners.forEach(function (fn) {
            fn.apply(event, event.args);
          });
        }
  
        this.data[event.type] = event.args;
      }
    }, {
      key: "onceListener",
      value: function onceListener(eventName, listener) {
        var _this3 = this;
  
        var onceListener = function onceListener() {
          _this3.removeListener(eventName, onceListener);
  
          return listener.apply(void 0, arguments);
        };
  
        return onceListener;
      }
    }, {
      key: "hasTransport",
      get: function get() {
        return !!this.transport;
      }
    }]);
  
    return Channel;
  }();
  
  exports.Channel = Channel;
  var _default = Channel;
  exports["default"] = _default;