/**
 * WebSocket implements a browser-side WebSocket specification.
 * @module Client
 */
"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = _default;

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));

var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));

var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));

var _eventemitter = require("eventemitter3");

function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }

function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }

var WebSocketBrowserImpl = /*#__PURE__*/function (_EventEmitter) {
  (0, _inherits2["default"])(WebSocketBrowserImpl, _EventEmitter);

  var _super = _createSuper(WebSocketBrowserImpl);

  /** Instantiate a WebSocket class
   * @constructor
   * @param {String} address - url to a websocket server
   * @param {(Object)} options - websocket options
   * @param {(String|Array)} protocols - a list of protocols
   * @return {WebSocketBrowserImpl} - returns a WebSocket instance
   */
  function WebSocketBrowserImpl(address, options, protocols) {
    var _this;

    (0, _classCallCheck2["default"])(this, WebSocketBrowserImpl);
    _this = _super.call(this);
    _this.socket = new window.WebSocket(address, protocols);

    _this.socket.onopen = function () {
      return _this.emit("open");
    };

    _this.socket.onmessage = function (event) {
      return _this.emit("message", event.data);
    };

    _this.socket.onerror = function (error) {
      return _this.emit("error", error);
    };

    _this.socket.onclose = function (event) {
      _this.emit("close", event.code, event.reason);
    };

    return _this;
  }
  /**
   * Sends data through a websocket connection
   * @method
   * @param {(String|Object)} data - data to be sent via websocket
   * @param {Object} optionsOrCallback - ws options
   * @param {Function} callback - a callback called once the data is sent
   * @return {Undefined}
   */


  (0, _createClass2["default"])(WebSocketBrowserImpl, [{
    key: "send",
    value: function send(data, optionsOrCallback, callback) {
      var cb = callback || optionsOrCallback;

      try {
        this.socket.send(data);
        cb();
      } catch (error) {
        cb(error);
      }
    }
    /**
     * Closes an underlying socket
     * @method
     * @param {Number} code - status code explaining why the connection is being closed
     * @param {String} reason - a description why the connection is closing
     * @return {Undefined}
     * @throws {Error}
     */

  }, {
    key: "close",
    value: function close(code, reason) {
      this.socket.close(code, reason);
    }
  }, {
    key: "addEventListener",
    value: function addEventListener(type, listener, options) {
      this.socket.addEventListener(type, listener, options);
    }
  }]);
  return WebSocketBrowserImpl;
}(_eventemitter.EventEmitter);
/**
 * factory method for common WebSocket instance
 * @method
 * @param {String} address - url to a websocket server
 * @param {(Object)} options - websocket options
 * @return {Undefined}
 */


function _default(address, options) {
  return new WebSocketBrowserImpl(address, options);
}