New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@october/reconnecting-websocket

Package Overview
Dependencies
Maintainers
11
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@october/reconnecting-websocket - npm Package Compare versions

Comparing version 1.0.1 to 1.0.2

998

dist/reconnecting-websocket-amd.js
define(function () { 'use strict';
class Event {
constructor(type, target) {
this.target = target;
this.type = type;
}
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
class ErrorEvent extends Event {
constructor(error, target) {
super('error', target);
this.message = error.message;
this.error = error;
}
};
var createClass = 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);
}
}
class CloseEvent extends Event {
constructor(code = 1000, reason = '', target) {
super('close', target);
this.wasClean = true;
this.code = code;
this.reason = reason;
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
var inherits = function (subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
/*!
* Reconnecting WebSocket
* by Pedro Ladaria <pedro.ladaria@gmail.com>
* https://github.com/pladaria/reconnecting-websocket
* License MIT
*/
const getGlobalWebSocket = () => {
if (typeof WebSocket !== 'undefined') {
// @ts-ignore
return WebSocket;
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
});
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
};
var possibleConstructorReturn = function (self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return call && (typeof call === "object" || typeof call === "function") ? call : self;
};
var slicedToArray = function () {
function sliceIterator(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
};
/**
* Returns true if given argument looks like a WebSocket class
*/
const isWebSocket = (w) => typeof w === 'function' && w.CLOSING === 2;
const DEFAULT = {
maxReconnectionDelay: 10000,
minReconnectionDelay: 1000 + Math.random() * 4000,
minUptime: 5000,
reconnectionDelayGrowFactor: 1.3,
connectionTimeout: 4000,
maxRetries: Infinity,
debug: false,
};
class ReconnectingWebSocket {
constructor(url, protocols, options = {}) {
this._listeners = {
error: [],
message: [],
open: [],
close: [],
};
this._retryCount = -1;
this._shouldReconnect = true;
this._connectLock = false;
this._binaryType = 'blob';
this.eventToHandler = new Map([
['open', this._handleOpen.bind(this)],
['close', this._handleClose.bind(this)],
['error', this._handleError.bind(this)],
['message', this._handleMessage.bind(this)],
]);
/**
* An event listener to be called when the WebSocket connection's readyState changes to CLOSED
*/
this.onclose = undefined;
/**
* An event listener to be called when an error occurs
*/
this.onerror = undefined;
/**
* An event listener to be called when a message is received from the server
*/
this.onmessage = undefined;
/**
* An event listener to be called when the WebSocket connection's readyState changes to OPEN;
* this indicates that the connection is ready to send and receive data
*/
this.onopen = undefined;
this._url = url;
this._protocols = protocols;
this._options = options;
this._connect();
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"]) _i["return"]();
} finally {
if (_d) throw _e;
}
static get CONNECTING() {
return 0;
}
static get OPEN() {
return 1;
}
static get CLOSING() {
return 2;
}
static get CLOSED() {
return 3;
}
get CONNECTING() {
return ReconnectingWebSocket.CONNECTING;
}
get OPEN() {
return ReconnectingWebSocket.OPEN;
}
get CLOSING() {
return ReconnectingWebSocket.CLOSING;
}
get CLOSED() {
return ReconnectingWebSocket.CLOSED;
}
get binaryType() {
return this._ws ? this._ws.binaryType : this._binaryType;
}
set binaryType(value) {
this._binaryType = value;
if (this._ws) {
// @ts-ignore
this._ws.binaryType = value;
}
}
/**
* Returns the number or connection retries
*/
get retryCount() {
return Math.max(this._retryCount, 0);
}
/**
* The number of bytes of data that have been queued using calls to send() but not yet
* transmitted to the network. This value resets to zero once all queued data has been sent.
* This value does not reset to zero when the connection is closed; if you keep calling send(),
* this will continue to climb. Read only
*/
get bufferedAmount() {
return this._ws ? this._ws.bufferedAmount : 0;
}
/**
* The extensions selected by the server. This is currently only the empty string or a list of
* extensions as negotiated by the connection
*/
get extensions() {
return this._ws ? this._ws.extensions : '';
}
/**
* A string indicating the name of the sub-protocol the server selected;
* this will be one of the strings specified in the protocols parameter when creating the
* WebSocket object
*/
get protocol() {
return this._ws ? this._ws.protocol : '';
}
/**
* The current state of the connection; this is one of the Ready state constants
*/
get readyState() {
return this._ws ? this._ws.readyState : ReconnectingWebSocket.CONNECTING;
}
/**
* The URL as resolved by the constructor
*/
get url() {
return this._ws ? this._ws.url : '';
}
/**
* Closes the WebSocket connection or connection attempt, if any. If the connection is already
* CLOSED, this method does nothing
*/
close(code, reason) {
this._shouldReconnect = false;
if (!this._ws || this._ws.readyState === this.CLOSED) {
return;
}
this._ws.close(code, reason);
}
/**
* Closes the WebSocket connection or connection attempt and connects again.
* Resets retry counter;
*/
reconnect(code, reason) {
this._shouldReconnect = true;
this._retryCount = -1;
if (!this._ws || this._ws.readyState === this.CLOSED) {
this._connect();
}
this._disconnect(code, reason);
this._connect();
}
/**
* Enqueues the specified data to be transmitted to the server over the WebSocket connection
*/
send(data) {
if (this._ws) {
this._ws.send(data);
}
}
/**
* Register an event handler of a specific event type
*/
addEventListener(type, listener) {
if (this._listeners[type]) {
// @ts-ignore
this._listeners[type].push(listener);
}
}
/**
* Removes an event listener
*/
removeEventListener(type, listener) {
if (this._listeners[type]) {
// @ts-ignore
this._listeners[type] = this._listeners[type].filter(l => l !== listener);
}
}
_debug(...params) {
if (this._options.debug) {
// tslint:disable-next-line
console.log('RWS>', ...params);
}
}
_getNextDelay() {
let delay = 0;
if (this._retryCount > 0) {
const { reconnectionDelayGrowFactor = DEFAULT.reconnectionDelayGrowFactor, minReconnectionDelay = DEFAULT.minReconnectionDelay, maxReconnectionDelay = DEFAULT.maxReconnectionDelay, } = this._options;
delay =
minReconnectionDelay + Math.pow(this._retryCount - 1, reconnectionDelayGrowFactor);
if (delay > maxReconnectionDelay) {
delay = maxReconnectionDelay;
}
}
this._debug('next delay', delay);
return delay;
}
_wait() {
return new Promise(resolve => {
setTimeout(resolve, this._getNextDelay());
});
}
/**
* @return Promise<string>
*/
_getNextUrl(urlProvider) {
if (typeof urlProvider === 'string') {
return Promise.resolve(urlProvider);
}
if (typeof urlProvider === 'function') {
const url = urlProvider();
if (typeof url === 'string') {
return Promise.resolve(url);
}
if (url.then) {
return url;
}
}
throw Error('Invalid URL');
}
_connect() {
if (this._connectLock) {
return;
}
this._connectLock = true;
const { maxRetries = DEFAULT.maxRetries, connectionTimeout = DEFAULT.connectionTimeout, WebSocket = getGlobalWebSocket(), } = this._options;
if (this._retryCount >= maxRetries) {
this._debug('max retries reached', this._retryCount, '>=', maxRetries);
return;
}
this._retryCount++;
this._debug('connect', this._retryCount);
this._removeListeners();
if (!isWebSocket(WebSocket)) {
throw Error('No valid WebSocket class provided');
}
this._wait()
.then(() => this._getNextUrl(this._url))
.then(url => {
this._debug('connect', { url, protocols: this._protocols });
this._ws = new WebSocket(url, this._protocols);
// @ts-ignore
this._ws.binaryType = this._binaryType;
this._connectLock = false;
this._addListeners();
this._connectTimeout = setTimeout(() => this._handleTimeout(), connectionTimeout);
});
}
_handleTimeout() {
this._debug('timeout event');
this._handleError(new ErrorEvent(Error('TIMEOUT'), this));
}
_disconnect(code, reason) {
clearTimeout(this._connectTimeout);
if (!this._ws) {
return;
}
this._removeListeners();
try {
this._ws.close(code, reason);
this._handleClose(new CloseEvent(code, reason, this));
}
catch (error) {
// ignore
}
}
_acceptOpen() {
this._retryCount = 0;
}
_handleOpen(event) {
this._debug('open event');
const { minUptime = DEFAULT.minUptime } = this._options;
clearTimeout(this._connectTimeout);
this._uptimeTimeout = setTimeout(() => this._acceptOpen(), minUptime);
this._debug('assign binary type');
// @ts-ignore
this._ws.binaryType = this._binaryType;
if (this.onopen) {
this.onopen(event);
}
this._listeners.open.forEach(listener => listener(event));
}
_handleMessage(event) {
this._debug('message event');
if (this.onmessage) {
this.onmessage(event);
}
this._listeners.message.forEach(listener => listener(event));
}
_handleError(event) {
this._debug('error event', event.message);
this._disconnect(undefined, event.message === 'TIMEOUT' ? 'timeout' : undefined);
if (this.onerror) {
this.onerror(event);
}
this._debug('exec error listeners');
this._listeners.error.forEach(listener => listener(event));
this._connect();
}
_handleClose(event) {
this._debug('close event');
if (this.onclose) {
this.onclose(event);
}
this._listeners.close.forEach(listener => listener(event));
}
/**
* Remove event listeners to WebSocket instance
*/
_removeListeners() {
if (!this._ws) {
return;
}
this._debug('removeListeners');
for (const [type, handler] of this.eventToHandler) {
this._ws.removeEventListener(type, handler);
}
}
/**
* Assign event listeners to WebSocket instance
*/
_addListeners() {
this._debug('addListeners');
for (const [type, handler] of this.eventToHandler) {
this._ws.addEventListener(type, handler);
}
}
}
return _arr;
}
return ReconnectingWebSocket;
return function (arr, i) {
if (Array.isArray(arr)) {
return arr;
} else if (Symbol.iterator in Object(arr)) {
return sliceIterator(arr, i);
} else {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
};
}();
var Event = function Event(type, target) {
classCallCheck(this, Event);
this.target = target;
this.type = type;
};
var ErrorEvent = function (_Event) {
inherits(ErrorEvent, _Event);
function ErrorEvent(error, target) {
classCallCheck(this, ErrorEvent);
var _this = possibleConstructorReturn(this, (ErrorEvent.__proto__ || Object.getPrototypeOf(ErrorEvent)).call(this, 'error', target));
_this.message = error.message;
_this.error = error;
return _this;
}
return ErrorEvent;
}(Event);
var CloseEvent = function (_Event2) {
inherits(CloseEvent, _Event2);
function CloseEvent() {
var code = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1000;
var reason = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
var target = arguments[2];
classCallCheck(this, CloseEvent);
var _this2 = possibleConstructorReturn(this, (CloseEvent.__proto__ || Object.getPrototypeOf(CloseEvent)).call(this, 'close', target));
_this2.wasClean = true;
_this2.code = code;
_this2.reason = reason;
return _this2;
}
return CloseEvent;
}(Event);
/*!
* Reconnecting WebSocket
* by Pedro Ladaria <pedro.ladaria@gmail.com>
* https://github.com/pladaria/reconnecting-websocket
* License MIT
*/
var getGlobalWebSocket = function getGlobalWebSocket() {
if (typeof WebSocket !== 'undefined') {
// @ts-ignore
return WebSocket;
}
};
/**
* Returns true if given argument looks like a WebSocket class
*/
var isWebSocket = function isWebSocket(w) {
return typeof w === 'function' && w.CLOSING === 2;
};
var DEFAULT = {
maxReconnectionDelay: 10000,
minReconnectionDelay: 1000 + Math.random() * 4000,
minUptime: 5000,
reconnectionDelayGrowFactor: 1.3,
connectionTimeout: 4000,
maxRetries: Infinity,
debug: false
};
var ReconnectingWebSocket = function () {
function ReconnectingWebSocket(url, protocols) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
classCallCheck(this, ReconnectingWebSocket);
this._listeners = {
error: [],
message: [],
open: [],
close: []
};
this._retryCount = -1;
this._shouldReconnect = true;
this._connectLock = false;
this._binaryType = 'blob';
this.eventToHandler = new Map([['open', this._handleOpen.bind(this)], ['close', this._handleClose.bind(this)], ['error', this._handleError.bind(this)], ['message', this._handleMessage.bind(this)]]);
/**
* An event listener to be called when the WebSocket connection's readyState changes to CLOSED
*/
this.onclose = undefined;
/**
* An event listener to be called when an error occurs
*/
this.onerror = undefined;
/**
* An event listener to be called when a message is received from the server
*/
this.onmessage = undefined;
/**
* An event listener to be called when the WebSocket connection's readyState changes to OPEN;
* this indicates that the connection is ready to send and receive data
*/
this.onopen = undefined;
this._url = url;
this._protocols = protocols;
this._options = options;
this._connect();
}
createClass(ReconnectingWebSocket, [{
key: 'close',
/**
* Closes the WebSocket connection or connection attempt, if any. If the connection is already
* CLOSED, this method does nothing
*/
value: function close(code, reason) {
this._shouldReconnect = false;
if (!this._ws || this._ws.readyState === this.CLOSED) {
return;
}
this._ws.close(code, reason);
}
/**
* Closes the WebSocket connection or connection attempt and connects again.
* Resets retry counter;
*/
}, {
key: 'reconnect',
value: function reconnect(code, reason) {
this._shouldReconnect = true;
this._retryCount = -1;
if (!this._ws || this._ws.readyState === this.CLOSED) {
this._connect();
}
this._disconnect(code, reason);
this._connect();
}
/**
* Enqueues the specified data to be transmitted to the server over the WebSocket connection
*/
}, {
key: 'send',
value: function send(data) {
if (this._ws) {
this._ws.send(data);
}
}
/**
* Register an event handler of a specific event type
*/
}, {
key: 'addEventListener',
value: function addEventListener(type, listener) {
if (this._listeners[type]) {
// @ts-ignore
this._listeners[type].push(listener);
}
}
/**
* Removes an event listener
*/
}, {
key: 'removeEventListener',
value: function removeEventListener(type, listener) {
if (this._listeners[type]) {
// @ts-ignore
this._listeners[type] = this._listeners[type].filter(function (l) {
return l !== listener;
});
}
}
}, {
key: '_debug',
value: function _debug() {
if (this._options.debug) {
var _console;
for (var _len = arguments.length, params = Array(_len), _key = 0; _key < _len; _key++) {
params[_key] = arguments[_key];
}
// tslint:disable-next-line
(_console = console).log.apply(_console, ['RWS>'].concat(params));
}
}
}, {
key: '_getNextDelay',
value: function _getNextDelay() {
var delay = 0;
if (this._retryCount > 0) {
var _options = this._options,
_options$reconnection = _options.reconnectionDelayGrowFactor,
reconnectionDelayGrowFactor = _options$reconnection === undefined ? DEFAULT.reconnectionDelayGrowFactor : _options$reconnection,
_options$minReconnect = _options.minReconnectionDelay,
minReconnectionDelay = _options$minReconnect === undefined ? DEFAULT.minReconnectionDelay : _options$minReconnect,
_options$maxReconnect = _options.maxReconnectionDelay,
maxReconnectionDelay = _options$maxReconnect === undefined ? DEFAULT.maxReconnectionDelay : _options$maxReconnect;
delay = minReconnectionDelay + Math.pow(this._retryCount - 1, reconnectionDelayGrowFactor);
if (delay > maxReconnectionDelay) {
delay = maxReconnectionDelay;
}
}
this._debug('next delay', delay);
return delay;
}
}, {
key: '_wait',
value: function _wait() {
var _this = this;
return new Promise(function (resolve) {
setTimeout(resolve, _this._getNextDelay());
});
}
/**
* @return Promise<string>
*/
}, {
key: '_getNextUrl',
value: function _getNextUrl(urlProvider) {
if (typeof urlProvider === 'string') {
return Promise.resolve(urlProvider);
}
if (typeof urlProvider === 'function') {
var url = urlProvider();
if (typeof url === 'string') {
return Promise.resolve(url);
}
if (url.then) {
return url;
}
}
throw Error('Invalid URL');
}
}, {
key: '_connect',
value: function _connect() {
var _this2 = this;
if (this._connectLock) {
return;
}
this._connectLock = true;
var _options2 = this._options,
_options2$maxRetries = _options2.maxRetries,
maxRetries = _options2$maxRetries === undefined ? DEFAULT.maxRetries : _options2$maxRetries,
_options2$connectionT = _options2.connectionTimeout,
connectionTimeout = _options2$connectionT === undefined ? DEFAULT.connectionTimeout : _options2$connectionT,
_options2$WebSocket = _options2.WebSocket,
WebSocket = _options2$WebSocket === undefined ? getGlobalWebSocket() : _options2$WebSocket;
if (this._retryCount >= maxRetries) {
this._debug('max retries reached', this._retryCount, '>=', maxRetries);
return;
}
this._retryCount++;
this._debug('connect', this._retryCount);
this._removeListeners();
if (!isWebSocket(WebSocket)) {
throw Error('No valid WebSocket class provided');
}
this._wait().then(function () {
return _this2._getNextUrl(_this2._url);
}).then(function (url) {
_this2._debug('connect', { url: url, protocols: _this2._protocols });
_this2._ws = new WebSocket(url, _this2._protocols);
// @ts-ignore
_this2._ws.binaryType = _this2._binaryType;
_this2._connectLock = false;
_this2._addListeners();
_this2._connectTimeout = setTimeout(function () {
return _this2._handleTimeout();
}, connectionTimeout);
});
}
}, {
key: '_handleTimeout',
value: function _handleTimeout() {
this._debug('timeout event');
this._handleError(new ErrorEvent(Error('TIMEOUT'), this));
}
}, {
key: '_disconnect',
value: function _disconnect(code, reason) {
clearTimeout(this._connectTimeout);
if (!this._ws) {
return;
}
this._removeListeners();
try {
this._ws.close(code, reason);
this._handleClose(new CloseEvent(code, reason, this));
} catch (error) {
// ignore
}
}
}, {
key: '_acceptOpen',
value: function _acceptOpen() {
this._retryCount = 0;
}
}, {
key: '_handleOpen',
value: function _handleOpen(event) {
var _this3 = this;
this._debug('open event');
var _options$minUptime = this._options.minUptime,
minUptime = _options$minUptime === undefined ? DEFAULT.minUptime : _options$minUptime;
clearTimeout(this._connectTimeout);
this._uptimeTimeout = setTimeout(function () {
return _this3._acceptOpen();
}, minUptime);
this._debug('assign binary type');
// @ts-ignore
this._ws.binaryType = this._binaryType;
if (this.onopen) {
this.onopen(event);
}
this._listeners.open.forEach(function (listener) {
return listener(event);
});
}
}, {
key: '_handleMessage',
value: function _handleMessage(event) {
this._debug('message event');
if (this.onmessage) {
this.onmessage(event);
}
this._listeners.message.forEach(function (listener) {
return listener(event);
});
}
}, {
key: '_handleError',
value: function _handleError(event) {
this._debug('error event', event.message);
// https://github.com/pladaria/reconnecting-websocket/pull/69
this._disconnect(4008, event.message === 'TIMEOUT' ? 'timeout' : undefined);
if (this.onerror) {
this.onerror(event);
}
this._debug('exec error listeners');
this._listeners.error.forEach(function (listener) {
return listener(event);
});
this._connect();
}
}, {
key: '_handleClose',
value: function _handleClose(event) {
this._debug('close event');
if (this.onclose) {
this.onclose(event);
}
this._listeners.close.forEach(function (listener) {
return listener(event);
});
}
/**
* Remove event listeners to WebSocket instance
*/
}, {
key: '_removeListeners',
value: function _removeListeners() {
if (!this._ws) {
return;
}
this._debug('removeListeners');
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = this.eventToHandler[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var _ref = _step.value;
var _ref2 = slicedToArray(_ref, 2);
var type = _ref2[0];
var handler = _ref2[1];
this._ws.removeEventListener(type, handler);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
/**
* Assign event listeners to WebSocket instance
*/
}, {
key: '_addListeners',
value: function _addListeners() {
this._debug('addListeners');
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = this.eventToHandler[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var _ref3 = _step2.value;
var _ref4 = slicedToArray(_ref3, 2);
var type = _ref4[0];
var handler = _ref4[1];
this._ws.addEventListener(type, handler);
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
}
}, {
key: 'CONNECTING',
get: function get$$1() {
return ReconnectingWebSocket.CONNECTING;
}
}, {
key: 'OPEN',
get: function get$$1() {
return ReconnectingWebSocket.OPEN;
}
}, {
key: 'CLOSING',
get: function get$$1() {
return ReconnectingWebSocket.CLOSING;
}
}, {
key: 'CLOSED',
get: function get$$1() {
return ReconnectingWebSocket.CLOSED;
}
}, {
key: 'binaryType',
get: function get$$1() {
return this._ws ? this._ws.binaryType : this._binaryType;
},
set: function set$$1(value) {
this._binaryType = value;
if (this._ws) {
// @ts-ignore
this._ws.binaryType = value;
}
}
/**
* Returns the number or connection retries
*/
}, {
key: 'retryCount',
get: function get$$1() {
return Math.max(this._retryCount, 0);
}
/**
* The number of bytes of data that have been queued using calls to send() but not yet
* transmitted to the network. This value resets to zero once all queued data has been sent.
* This value does not reset to zero when the connection is closed; if you keep calling send(),
* this will continue to climb. Read only
*/
}, {
key: 'bufferedAmount',
get: function get$$1() {
return this._ws ? this._ws.bufferedAmount : 0;
}
/**
* The extensions selected by the server. This is currently only the empty string or a list of
* extensions as negotiated by the connection
*/
}, {
key: 'extensions',
get: function get$$1() {
return this._ws ? this._ws.extensions : '';
}
/**
* A string indicating the name of the sub-protocol the server selected;
* this will be one of the strings specified in the protocols parameter when creating the
* WebSocket object
*/
}, {
key: 'protocol',
get: function get$$1() {
return this._ws ? this._ws.protocol : '';
}
/**
* The current state of the connection; this is one of the Ready state constants
*/
}, {
key: 'readyState',
get: function get$$1() {
return this._ws ? this._ws.readyState : ReconnectingWebSocket.CONNECTING;
}
/**
* The URL as resolved by the constructor
*/
}, {
key: 'url',
get: function get$$1() {
return this._ws ? this._ws.url : '';
}
}], [{
key: 'CONNECTING',
get: function get$$1() {
return 0;
}
}, {
key: 'OPEN',
get: function get$$1() {
return 1;
}
}, {
key: 'CLOSING',
get: function get$$1() {
return 2;
}
}, {
key: 'CLOSED',
get: function get$$1() {
return 3;
}
}]);
return ReconnectingWebSocket;
}();
return ReconnectingWebSocket;
});
'use strict';
class Event {
constructor(type, target) {
this.target = target;
this.type = type;
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
var createClass = 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);
}
}
class ErrorEvent extends Event {
constructor(error, target) {
super('error', target);
this.message = error.message;
this.error = error;
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
var inherits = function (subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
}
class CloseEvent extends Event {
constructor(code = 1000, reason = '', target) {
super('close', target);
this.wasClean = true;
this.code = code;
this.reason = reason;
});
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
};
var possibleConstructorReturn = function (self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return call && (typeof call === "object" || typeof call === "function") ? call : self;
};
var slicedToArray = function () {
function sliceIterator(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"]) _i["return"]();
} finally {
if (_d) throw _e;
}
}
}
return _arr;
}
return function (arr, i) {
if (Array.isArray(arr)) {
return arr;
} else if (Symbol.iterator in Object(arr)) {
return sliceIterator(arr, i);
} else {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
};
}();
var Event = function Event(type, target) {
classCallCheck(this, Event);
this.target = target;
this.type = type;
};
var ErrorEvent = function (_Event) {
inherits(ErrorEvent, _Event);
function ErrorEvent(error, target) {
classCallCheck(this, ErrorEvent);
var _this = possibleConstructorReturn(this, (ErrorEvent.__proto__ || Object.getPrototypeOf(ErrorEvent)).call(this, 'error', target));
_this.message = error.message;
_this.error = error;
return _this;
}
return ErrorEvent;
}(Event);
var CloseEvent = function (_Event2) {
inherits(CloseEvent, _Event2);
function CloseEvent() {
var code = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1000;
var reason = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
var target = arguments[2];
classCallCheck(this, CloseEvent);
var _this2 = possibleConstructorReturn(this, (CloseEvent.__proto__ || Object.getPrototypeOf(CloseEvent)).call(this, 'close', target));
_this2.wasClean = true;
_this2.code = code;
_this2.reason = reason;
return _this2;
}
return CloseEvent;
}(Event);
/*!

@@ -31,3 +136,3 @@ * Reconnecting WebSocket

*/
const getGlobalWebSocket = () => {
var getGlobalWebSocket = function getGlobalWebSocket() {
if (typeof WebSocket !== 'undefined') {

@@ -41,4 +146,6 @@ // @ts-ignore

*/
const isWebSocket = (w) => typeof w === 'function' && w.CLOSING === 2;
const DEFAULT = {
var isWebSocket = function isWebSocket(w) {
return typeof w === 'function' && w.CLOSING === 2;
};
var DEFAULT = {
maxReconnectionDelay: 10000,

@@ -50,6 +157,10 @@ minReconnectionDelay: 1000 + Math.random() * 4000,

maxRetries: Infinity,
debug: false,
debug: false
};
class ReconnectingWebSocket {
constructor(url, protocols, options = {}) {
var ReconnectingWebSocket = function () {
function ReconnectingWebSocket(url, protocols) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
classCallCheck(this, ReconnectingWebSocket);
this._listeners = {

@@ -59,3 +170,3 @@ error: [],

open: [],
close: [],
close: []
};

@@ -66,8 +177,3 @@ this._retryCount = -1;

this._binaryType = 'blob';
this.eventToHandler = new Map([
['open', this._handleOpen.bind(this)],
['close', this._handleClose.bind(this)],
['error', this._handleError.bind(this)],
['message', this._handleMessage.bind(this)],
]);
this.eventToHandler = new Map([['open', this._handleOpen.bind(this)], ['close', this._handleClose.bind(this)], ['error', this._handleError.bind(this)], ['message', this._handleMessage.bind(this)]]);
/**

@@ -95,279 +201,457 @@ * An event listener to be called when the WebSocket connection's readyState changes to CLOSED

}
static get CONNECTING() {
return 0;
}
static get OPEN() {
return 1;
}
static get CLOSING() {
return 2;
}
static get CLOSED() {
return 3;
}
get CONNECTING() {
return ReconnectingWebSocket.CONNECTING;
}
get OPEN() {
return ReconnectingWebSocket.OPEN;
}
get CLOSING() {
return ReconnectingWebSocket.CLOSING;
}
get CLOSED() {
return ReconnectingWebSocket.CLOSED;
}
get binaryType() {
return this._ws ? this._ws.binaryType : this._binaryType;
}
set binaryType(value) {
this._binaryType = value;
if (this._ws) {
// @ts-ignore
this._ws.binaryType = value;
createClass(ReconnectingWebSocket, [{
key: 'close',
/**
* Closes the WebSocket connection or connection attempt, if any. If the connection is already
* CLOSED, this method does nothing
*/
value: function close(code, reason) {
this._shouldReconnect = false;
if (!this._ws || this._ws.readyState === this.CLOSED) {
return;
}
this._ws.close(code, reason);
}
}
/**
* Returns the number or connection retries
*/
get retryCount() {
return Math.max(this._retryCount, 0);
}
/**
* The number of bytes of data that have been queued using calls to send() but not yet
* transmitted to the network. This value resets to zero once all queued data has been sent.
* This value does not reset to zero when the connection is closed; if you keep calling send(),
* this will continue to climb. Read only
*/
get bufferedAmount() {
return this._ws ? this._ws.bufferedAmount : 0;
}
/**
* The extensions selected by the server. This is currently only the empty string or a list of
* extensions as negotiated by the connection
*/
get extensions() {
return this._ws ? this._ws.extensions : '';
}
/**
* A string indicating the name of the sub-protocol the server selected;
* this will be one of the strings specified in the protocols parameter when creating the
* WebSocket object
*/
get protocol() {
return this._ws ? this._ws.protocol : '';
}
/**
* The current state of the connection; this is one of the Ready state constants
*/
get readyState() {
return this._ws ? this._ws.readyState : ReconnectingWebSocket.CONNECTING;
}
/**
* The URL as resolved by the constructor
*/
get url() {
return this._ws ? this._ws.url : '';
}
/**
* Closes the WebSocket connection or connection attempt, if any. If the connection is already
* CLOSED, this method does nothing
*/
close(code, reason) {
this._shouldReconnect = false;
if (!this._ws || this._ws.readyState === this.CLOSED) {
return;
}
this._ws.close(code, reason);
}
/**
* Closes the WebSocket connection or connection attempt and connects again.
* Resets retry counter;
*/
reconnect(code, reason) {
this._shouldReconnect = true;
this._retryCount = -1;
if (!this._ws || this._ws.readyState === this.CLOSED) {
/**
* Closes the WebSocket connection or connection attempt and connects again.
* Resets retry counter;
*/
}, {
key: 'reconnect',
value: function reconnect(code, reason) {
this._shouldReconnect = true;
this._retryCount = -1;
if (!this._ws || this._ws.readyState === this.CLOSED) {
this._connect();
}
this._disconnect(code, reason);
this._connect();
}
this._disconnect(code, reason);
this._connect();
}
/**
* Enqueues the specified data to be transmitted to the server over the WebSocket connection
*/
send(data) {
if (this._ws) {
this._ws.send(data);
/**
* Enqueues the specified data to be transmitted to the server over the WebSocket connection
*/
}, {
key: 'send',
value: function send(data) {
if (this._ws) {
this._ws.send(data);
}
}
}
/**
* Register an event handler of a specific event type
*/
addEventListener(type, listener) {
if (this._listeners[type]) {
// @ts-ignore
this._listeners[type].push(listener);
/**
* Register an event handler of a specific event type
*/
}, {
key: 'addEventListener',
value: function addEventListener(type, listener) {
if (this._listeners[type]) {
// @ts-ignore
this._listeners[type].push(listener);
}
}
}
/**
* Removes an event listener
*/
removeEventListener(type, listener) {
if (this._listeners[type]) {
// @ts-ignore
this._listeners[type] = this._listeners[type].filter(l => l !== listener);
/**
* Removes an event listener
*/
}, {
key: 'removeEventListener',
value: function removeEventListener(type, listener) {
if (this._listeners[type]) {
// @ts-ignore
this._listeners[type] = this._listeners[type].filter(function (l) {
return l !== listener;
});
}
}
}
_debug(...params) {
if (this._options.debug) {
// tslint:disable-next-line
console.log('RWS>', ...params);
}, {
key: '_debug',
value: function _debug() {
if (this._options.debug) {
var _console;
for (var _len = arguments.length, params = Array(_len), _key = 0; _key < _len; _key++) {
params[_key] = arguments[_key];
}
// tslint:disable-next-line
(_console = console).log.apply(_console, ['RWS>'].concat(params));
}
}
}
_getNextDelay() {
let delay = 0;
if (this._retryCount > 0) {
const { reconnectionDelayGrowFactor = DEFAULT.reconnectionDelayGrowFactor, minReconnectionDelay = DEFAULT.minReconnectionDelay, maxReconnectionDelay = DEFAULT.maxReconnectionDelay, } = this._options;
delay =
minReconnectionDelay + Math.pow(this._retryCount - 1, reconnectionDelayGrowFactor);
if (delay > maxReconnectionDelay) {
delay = maxReconnectionDelay;
}, {
key: '_getNextDelay',
value: function _getNextDelay() {
var delay = 0;
if (this._retryCount > 0) {
var _options = this._options,
_options$reconnection = _options.reconnectionDelayGrowFactor,
reconnectionDelayGrowFactor = _options$reconnection === undefined ? DEFAULT.reconnectionDelayGrowFactor : _options$reconnection,
_options$minReconnect = _options.minReconnectionDelay,
minReconnectionDelay = _options$minReconnect === undefined ? DEFAULT.minReconnectionDelay : _options$minReconnect,
_options$maxReconnect = _options.maxReconnectionDelay,
maxReconnectionDelay = _options$maxReconnect === undefined ? DEFAULT.maxReconnectionDelay : _options$maxReconnect;
delay = minReconnectionDelay + Math.pow(this._retryCount - 1, reconnectionDelayGrowFactor);
if (delay > maxReconnectionDelay) {
delay = maxReconnectionDelay;
}
}
this._debug('next delay', delay);
return delay;
}
this._debug('next delay', delay);
return delay;
}
_wait() {
return new Promise(resolve => {
setTimeout(resolve, this._getNextDelay());
});
}
/**
* @return Promise<string>
*/
_getNextUrl(urlProvider) {
if (typeof urlProvider === 'string') {
return Promise.resolve(urlProvider);
}, {
key: '_wait',
value: function _wait() {
var _this = this;
return new Promise(function (resolve) {
setTimeout(resolve, _this._getNextDelay());
});
}
if (typeof urlProvider === 'function') {
const url = urlProvider();
if (typeof url === 'string') {
return Promise.resolve(url);
/**
* @return Promise<string>
*/
}, {
key: '_getNextUrl',
value: function _getNextUrl(urlProvider) {
if (typeof urlProvider === 'string') {
return Promise.resolve(urlProvider);
}
if (url.then) {
return url;
if (typeof urlProvider === 'function') {
var url = urlProvider();
if (typeof url === 'string') {
return Promise.resolve(url);
}
if (url.then) {
return url;
}
}
throw Error('Invalid URL');
}
throw Error('Invalid URL');
}
_connect() {
if (this._connectLock) {
return;
}, {
key: '_connect',
value: function _connect() {
var _this2 = this;
if (this._connectLock) {
return;
}
this._connectLock = true;
var _options2 = this._options,
_options2$maxRetries = _options2.maxRetries,
maxRetries = _options2$maxRetries === undefined ? DEFAULT.maxRetries : _options2$maxRetries,
_options2$connectionT = _options2.connectionTimeout,
connectionTimeout = _options2$connectionT === undefined ? DEFAULT.connectionTimeout : _options2$connectionT,
_options2$WebSocket = _options2.WebSocket,
WebSocket = _options2$WebSocket === undefined ? getGlobalWebSocket() : _options2$WebSocket;
if (this._retryCount >= maxRetries) {
this._debug('max retries reached', this._retryCount, '>=', maxRetries);
return;
}
this._retryCount++;
this._debug('connect', this._retryCount);
this._removeListeners();
if (!isWebSocket(WebSocket)) {
throw Error('No valid WebSocket class provided');
}
this._wait().then(function () {
return _this2._getNextUrl(_this2._url);
}).then(function (url) {
_this2._debug('connect', { url: url, protocols: _this2._protocols });
_this2._ws = new WebSocket(url, _this2._protocols);
// @ts-ignore
_this2._ws.binaryType = _this2._binaryType;
_this2._connectLock = false;
_this2._addListeners();
_this2._connectTimeout = setTimeout(function () {
return _this2._handleTimeout();
}, connectionTimeout);
});
}
this._connectLock = true;
const { maxRetries = DEFAULT.maxRetries, connectionTimeout = DEFAULT.connectionTimeout, WebSocket = getGlobalWebSocket(), } = this._options;
if (this._retryCount >= maxRetries) {
this._debug('max retries reached', this._retryCount, '>=', maxRetries);
return;
}, {
key: '_handleTimeout',
value: function _handleTimeout() {
this._debug('timeout event');
this._handleError(new ErrorEvent(Error('TIMEOUT'), this));
}
this._retryCount++;
this._debug('connect', this._retryCount);
this._removeListeners();
if (!isWebSocket(WebSocket)) {
throw Error('No valid WebSocket class provided');
}, {
key: '_disconnect',
value: function _disconnect(code, reason) {
clearTimeout(this._connectTimeout);
if (!this._ws) {
return;
}
this._removeListeners();
try {
this._ws.close(code, reason);
this._handleClose(new CloseEvent(code, reason, this));
} catch (error) {
// ignore
}
}
this._wait()
.then(() => this._getNextUrl(this._url))
.then(url => {
this._debug('connect', { url, protocols: this._protocols });
this._ws = new WebSocket(url, this._protocols);
}, {
key: '_acceptOpen',
value: function _acceptOpen() {
this._retryCount = 0;
}
}, {
key: '_handleOpen',
value: function _handleOpen(event) {
var _this3 = this;
this._debug('open event');
var _options$minUptime = this._options.minUptime,
minUptime = _options$minUptime === undefined ? DEFAULT.minUptime : _options$minUptime;
clearTimeout(this._connectTimeout);
this._uptimeTimeout = setTimeout(function () {
return _this3._acceptOpen();
}, minUptime);
this._debug('assign binary type');
// @ts-ignore
this._ws.binaryType = this._binaryType;
this._connectLock = false;
this._addListeners();
this._connectTimeout = setTimeout(() => this._handleTimeout(), connectionTimeout);
});
}
_handleTimeout() {
this._debug('timeout event');
this._handleError(new ErrorEvent(Error('TIMEOUT'), this));
}
_disconnect(code, reason) {
clearTimeout(this._connectTimeout);
if (!this._ws) {
return;
if (this.onopen) {
this.onopen(event);
}
this._listeners.open.forEach(function (listener) {
return listener(event);
});
}
this._removeListeners();
try {
this._ws.close(code, reason);
this._handleClose(new CloseEvent(code, reason, this));
}, {
key: '_handleMessage',
value: function _handleMessage(event) {
this._debug('message event');
if (this.onmessage) {
this.onmessage(event);
}
this._listeners.message.forEach(function (listener) {
return listener(event);
});
}
catch (error) {
// ignore
}, {
key: '_handleError',
value: function _handleError(event) {
this._debug('error event', event.message);
// https://github.com/pladaria/reconnecting-websocket/pull/69
this._disconnect(4008, event.message === 'TIMEOUT' ? 'timeout' : undefined);
if (this.onerror) {
this.onerror(event);
}
this._debug('exec error listeners');
this._listeners.error.forEach(function (listener) {
return listener(event);
});
this._connect();
}
}
_acceptOpen() {
this._retryCount = 0;
}
_handleOpen(event) {
this._debug('open event');
const { minUptime = DEFAULT.minUptime } = this._options;
clearTimeout(this._connectTimeout);
this._uptimeTimeout = setTimeout(() => this._acceptOpen(), minUptime);
this._debug('assign binary type');
// @ts-ignore
this._ws.binaryType = this._binaryType;
if (this.onopen) {
this.onopen(event);
}, {
key: '_handleClose',
value: function _handleClose(event) {
this._debug('close event');
if (this.onclose) {
this.onclose(event);
}
this._listeners.close.forEach(function (listener) {
return listener(event);
});
}
this._listeners.open.forEach(listener => listener(event));
}
_handleMessage(event) {
this._debug('message event');
if (this.onmessage) {
this.onmessage(event);
/**
* Remove event listeners to WebSocket instance
*/
}, {
key: '_removeListeners',
value: function _removeListeners() {
if (!this._ws) {
return;
}
this._debug('removeListeners');
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = this.eventToHandler[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var _ref = _step.value;
var _ref2 = slicedToArray(_ref, 2);
var type = _ref2[0];
var handler = _ref2[1];
this._ws.removeEventListener(type, handler);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
this._listeners.message.forEach(listener => listener(event));
}
_handleError(event) {
this._debug('error event', event.message);
this._disconnect(undefined, event.message === 'TIMEOUT' ? 'timeout' : undefined);
if (this.onerror) {
this.onerror(event);
/**
* Assign event listeners to WebSocket instance
*/
}, {
key: '_addListeners',
value: function _addListeners() {
this._debug('addListeners');
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = this.eventToHandler[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var _ref3 = _step2.value;
var _ref4 = slicedToArray(_ref3, 2);
var type = _ref4[0];
var handler = _ref4[1];
this._ws.addEventListener(type, handler);
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
}
this._debug('exec error listeners');
this._listeners.error.forEach(listener => listener(event));
this._connect();
}
_handleClose(event) {
this._debug('close event');
if (this.onclose) {
this.onclose(event);
}, {
key: 'CONNECTING',
get: function get$$1() {
return ReconnectingWebSocket.CONNECTING;
}
this._listeners.close.forEach(listener => listener(event));
}
/**
* Remove event listeners to WebSocket instance
*/
_removeListeners() {
if (!this._ws) {
return;
}, {
key: 'OPEN',
get: function get$$1() {
return ReconnectingWebSocket.OPEN;
}
this._debug('removeListeners');
for (const [type, handler] of this.eventToHandler) {
this._ws.removeEventListener(type, handler);
}, {
key: 'CLOSING',
get: function get$$1() {
return ReconnectingWebSocket.CLOSING;
}
}
/**
* Assign event listeners to WebSocket instance
*/
_addListeners() {
this._debug('addListeners');
for (const [type, handler] of this.eventToHandler) {
this._ws.addEventListener(type, handler);
}, {
key: 'CLOSED',
get: function get$$1() {
return ReconnectingWebSocket.CLOSED;
}
}
}
}, {
key: 'binaryType',
get: function get$$1() {
return this._ws ? this._ws.binaryType : this._binaryType;
},
set: function set$$1(value) {
this._binaryType = value;
if (this._ws) {
// @ts-ignore
this._ws.binaryType = value;
}
}
/**
* Returns the number or connection retries
*/
}, {
key: 'retryCount',
get: function get$$1() {
return Math.max(this._retryCount, 0);
}
/**
* The number of bytes of data that have been queued using calls to send() but not yet
* transmitted to the network. This value resets to zero once all queued data has been sent.
* This value does not reset to zero when the connection is closed; if you keep calling send(),
* this will continue to climb. Read only
*/
}, {
key: 'bufferedAmount',
get: function get$$1() {
return this._ws ? this._ws.bufferedAmount : 0;
}
/**
* The extensions selected by the server. This is currently only the empty string or a list of
* extensions as negotiated by the connection
*/
}, {
key: 'extensions',
get: function get$$1() {
return this._ws ? this._ws.extensions : '';
}
/**
* A string indicating the name of the sub-protocol the server selected;
* this will be one of the strings specified in the protocols parameter when creating the
* WebSocket object
*/
}, {
key: 'protocol',
get: function get$$1() {
return this._ws ? this._ws.protocol : '';
}
/**
* The current state of the connection; this is one of the Ready state constants
*/
}, {
key: 'readyState',
get: function get$$1() {
return this._ws ? this._ws.readyState : ReconnectingWebSocket.CONNECTING;
}
/**
* The URL as resolved by the constructor
*/
}, {
key: 'url',
get: function get$$1() {
return this._ws ? this._ws.url : '';
}
}], [{
key: 'CONNECTING',
get: function get$$1() {
return 0;
}
}, {
key: 'OPEN',
get: function get$$1() {
return 1;
}
}, {
key: 'CLOSING',
get: function get$$1() {
return 2;
}
}, {
key: 'CLOSED',
get: function get$$1() {
return 3;
}
}]);
return ReconnectingWebSocket;
}();
module.exports = ReconnectingWebSocket;
var ReconnectingWebSocket = (function () {
'use strict';
'use strict';
class Event {
constructor(type, target) {
this.target = target;
this.type = type;
}
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
class ErrorEvent extends Event {
constructor(error, target) {
super('error', target);
this.message = error.message;
this.error = error;
}
};
var createClass = 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);
}
}
class CloseEvent extends Event {
constructor(code = 1000, reason = '', target) {
super('close', target);
this.wasClean = true;
this.code = code;
this.reason = reason;
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
var inherits = function (subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
/*!
* Reconnecting WebSocket
* by Pedro Ladaria <pedro.ladaria@gmail.com>
* https://github.com/pladaria/reconnecting-websocket
* License MIT
*/
const getGlobalWebSocket = () => {
if (typeof WebSocket !== 'undefined') {
// @ts-ignore
return WebSocket;
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
});
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
};
var possibleConstructorReturn = function (self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return call && (typeof call === "object" || typeof call === "function") ? call : self;
};
var slicedToArray = function () {
function sliceIterator(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
};
/**
* Returns true if given argument looks like a WebSocket class
*/
const isWebSocket = (w) => typeof w === 'function' && w.CLOSING === 2;
const DEFAULT = {
maxReconnectionDelay: 10000,
minReconnectionDelay: 1000 + Math.random() * 4000,
minUptime: 5000,
reconnectionDelayGrowFactor: 1.3,
connectionTimeout: 4000,
maxRetries: Infinity,
debug: false,
};
class ReconnectingWebSocket {
constructor(url, protocols, options = {}) {
this._listeners = {
error: [],
message: [],
open: [],
close: [],
};
this._retryCount = -1;
this._shouldReconnect = true;
this._connectLock = false;
this._binaryType = 'blob';
this.eventToHandler = new Map([
['open', this._handleOpen.bind(this)],
['close', this._handleClose.bind(this)],
['error', this._handleError.bind(this)],
['message', this._handleMessage.bind(this)],
]);
/**
* An event listener to be called when the WebSocket connection's readyState changes to CLOSED
*/
this.onclose = undefined;
/**
* An event listener to be called when an error occurs
*/
this.onerror = undefined;
/**
* An event listener to be called when a message is received from the server
*/
this.onmessage = undefined;
/**
* An event listener to be called when the WebSocket connection's readyState changes to OPEN;
* this indicates that the connection is ready to send and receive data
*/
this.onopen = undefined;
this._url = url;
this._protocols = protocols;
this._options = options;
this._connect();
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"]) _i["return"]();
} finally {
if (_d) throw _e;
}
static get CONNECTING() {
return 0;
}
static get OPEN() {
return 1;
}
static get CLOSING() {
return 2;
}
static get CLOSED() {
return 3;
}
get CONNECTING() {
return ReconnectingWebSocket.CONNECTING;
}
get OPEN() {
return ReconnectingWebSocket.OPEN;
}
get CLOSING() {
return ReconnectingWebSocket.CLOSING;
}
get CLOSED() {
return ReconnectingWebSocket.CLOSED;
}
get binaryType() {
return this._ws ? this._ws.binaryType : this._binaryType;
}
set binaryType(value) {
this._binaryType = value;
if (this._ws) {
// @ts-ignore
this._ws.binaryType = value;
}
}
/**
* Returns the number or connection retries
*/
get retryCount() {
return Math.max(this._retryCount, 0);
}
/**
* The number of bytes of data that have been queued using calls to send() but not yet
* transmitted to the network. This value resets to zero once all queued data has been sent.
* This value does not reset to zero when the connection is closed; if you keep calling send(),
* this will continue to climb. Read only
*/
get bufferedAmount() {
return this._ws ? this._ws.bufferedAmount : 0;
}
/**
* The extensions selected by the server. This is currently only the empty string or a list of
* extensions as negotiated by the connection
*/
get extensions() {
return this._ws ? this._ws.extensions : '';
}
/**
* A string indicating the name of the sub-protocol the server selected;
* this will be one of the strings specified in the protocols parameter when creating the
* WebSocket object
*/
get protocol() {
return this._ws ? this._ws.protocol : '';
}
/**
* The current state of the connection; this is one of the Ready state constants
*/
get readyState() {
return this._ws ? this._ws.readyState : ReconnectingWebSocket.CONNECTING;
}
/**
* The URL as resolved by the constructor
*/
get url() {
return this._ws ? this._ws.url : '';
}
/**
* Closes the WebSocket connection or connection attempt, if any. If the connection is already
* CLOSED, this method does nothing
*/
close(code, reason) {
this._shouldReconnect = false;
if (!this._ws || this._ws.readyState === this.CLOSED) {
return;
}
this._ws.close(code, reason);
}
/**
* Closes the WebSocket connection or connection attempt and connects again.
* Resets retry counter;
*/
reconnect(code, reason) {
this._shouldReconnect = true;
this._retryCount = -1;
if (!this._ws || this._ws.readyState === this.CLOSED) {
this._connect();
}
this._disconnect(code, reason);
this._connect();
}
/**
* Enqueues the specified data to be transmitted to the server over the WebSocket connection
*/
send(data) {
if (this._ws) {
this._ws.send(data);
}
}
/**
* Register an event handler of a specific event type
*/
addEventListener(type, listener) {
if (this._listeners[type]) {
// @ts-ignore
this._listeners[type].push(listener);
}
}
/**
* Removes an event listener
*/
removeEventListener(type, listener) {
if (this._listeners[type]) {
// @ts-ignore
this._listeners[type] = this._listeners[type].filter(l => l !== listener);
}
}
_debug(...params) {
if (this._options.debug) {
// tslint:disable-next-line
console.log('RWS>', ...params);
}
}
_getNextDelay() {
let delay = 0;
if (this._retryCount > 0) {
const { reconnectionDelayGrowFactor = DEFAULT.reconnectionDelayGrowFactor, minReconnectionDelay = DEFAULT.minReconnectionDelay, maxReconnectionDelay = DEFAULT.maxReconnectionDelay, } = this._options;
delay =
minReconnectionDelay + Math.pow(this._retryCount - 1, reconnectionDelayGrowFactor);
if (delay > maxReconnectionDelay) {
delay = maxReconnectionDelay;
}
}
this._debug('next delay', delay);
return delay;
}
_wait() {
return new Promise(resolve => {
setTimeout(resolve, this._getNextDelay());
});
}
/**
* @return Promise<string>
*/
_getNextUrl(urlProvider) {
if (typeof urlProvider === 'string') {
return Promise.resolve(urlProvider);
}
if (typeof urlProvider === 'function') {
const url = urlProvider();
if (typeof url === 'string') {
return Promise.resolve(url);
}
if (url.then) {
return url;
}
}
throw Error('Invalid URL');
}
_connect() {
if (this._connectLock) {
return;
}
this._connectLock = true;
const { maxRetries = DEFAULT.maxRetries, connectionTimeout = DEFAULT.connectionTimeout, WebSocket = getGlobalWebSocket(), } = this._options;
if (this._retryCount >= maxRetries) {
this._debug('max retries reached', this._retryCount, '>=', maxRetries);
return;
}
this._retryCount++;
this._debug('connect', this._retryCount);
this._removeListeners();
if (!isWebSocket(WebSocket)) {
throw Error('No valid WebSocket class provided');
}
this._wait()
.then(() => this._getNextUrl(this._url))
.then(url => {
this._debug('connect', { url, protocols: this._protocols });
this._ws = new WebSocket(url, this._protocols);
// @ts-ignore
this._ws.binaryType = this._binaryType;
this._connectLock = false;
this._addListeners();
this._connectTimeout = setTimeout(() => this._handleTimeout(), connectionTimeout);
});
}
_handleTimeout() {
this._debug('timeout event');
this._handleError(new ErrorEvent(Error('TIMEOUT'), this));
}
_disconnect(code, reason) {
clearTimeout(this._connectTimeout);
if (!this._ws) {
return;
}
this._removeListeners();
try {
this._ws.close(code, reason);
this._handleClose(new CloseEvent(code, reason, this));
}
catch (error) {
// ignore
}
}
_acceptOpen() {
this._retryCount = 0;
}
_handleOpen(event) {
this._debug('open event');
const { minUptime = DEFAULT.minUptime } = this._options;
clearTimeout(this._connectTimeout);
this._uptimeTimeout = setTimeout(() => this._acceptOpen(), minUptime);
this._debug('assign binary type');
// @ts-ignore
this._ws.binaryType = this._binaryType;
if (this.onopen) {
this.onopen(event);
}
this._listeners.open.forEach(listener => listener(event));
}
_handleMessage(event) {
this._debug('message event');
if (this.onmessage) {
this.onmessage(event);
}
this._listeners.message.forEach(listener => listener(event));
}
_handleError(event) {
this._debug('error event', event.message);
this._disconnect(undefined, event.message === 'TIMEOUT' ? 'timeout' : undefined);
if (this.onerror) {
this.onerror(event);
}
this._debug('exec error listeners');
this._listeners.error.forEach(listener => listener(event));
this._connect();
}
_handleClose(event) {
this._debug('close event');
if (this.onclose) {
this.onclose(event);
}
this._listeners.close.forEach(listener => listener(event));
}
/**
* Remove event listeners to WebSocket instance
*/
_removeListeners() {
if (!this._ws) {
return;
}
this._debug('removeListeners');
for (const [type, handler] of this.eventToHandler) {
this._ws.removeEventListener(type, handler);
}
}
/**
* Assign event listeners to WebSocket instance
*/
_addListeners() {
this._debug('addListeners');
for (const [type, handler] of this.eventToHandler) {
this._ws.addEventListener(type, handler);
}
}
}
return _arr;
}
return ReconnectingWebSocket;
return function (arr, i) {
if (Array.isArray(arr)) {
return arr;
} else if (Symbol.iterator in Object(arr)) {
return sliceIterator(arr, i);
} else {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
};
}();
var Event = function Event(type, target) {
classCallCheck(this, Event);
this.target = target;
this.type = type;
};
var ErrorEvent = function (_Event) {
inherits(ErrorEvent, _Event);
function ErrorEvent(error, target) {
classCallCheck(this, ErrorEvent);
var _this = possibleConstructorReturn(this, (ErrorEvent.__proto__ || Object.getPrototypeOf(ErrorEvent)).call(this, 'error', target));
_this.message = error.message;
_this.error = error;
return _this;
}
return ErrorEvent;
}(Event);
var CloseEvent = function (_Event2) {
inherits(CloseEvent, _Event2);
function CloseEvent() {
var code = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1000;
var reason = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
var target = arguments[2];
classCallCheck(this, CloseEvent);
var _this2 = possibleConstructorReturn(this, (CloseEvent.__proto__ || Object.getPrototypeOf(CloseEvent)).call(this, 'close', target));
_this2.wasClean = true;
_this2.code = code;
_this2.reason = reason;
return _this2;
}
return CloseEvent;
}(Event);
/*!
* Reconnecting WebSocket
* by Pedro Ladaria <pedro.ladaria@gmail.com>
* https://github.com/pladaria/reconnecting-websocket
* License MIT
*/
var getGlobalWebSocket = function getGlobalWebSocket() {
if (typeof WebSocket !== 'undefined') {
// @ts-ignore
return WebSocket;
}
};
/**
* Returns true if given argument looks like a WebSocket class
*/
var isWebSocket = function isWebSocket(w) {
return typeof w === 'function' && w.CLOSING === 2;
};
var DEFAULT = {
maxReconnectionDelay: 10000,
minReconnectionDelay: 1000 + Math.random() * 4000,
minUptime: 5000,
reconnectionDelayGrowFactor: 1.3,
connectionTimeout: 4000,
maxRetries: Infinity,
debug: false
};
var ReconnectingWebSocket = function () {
function ReconnectingWebSocket(url, protocols) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
classCallCheck(this, ReconnectingWebSocket);
this._listeners = {
error: [],
message: [],
open: [],
close: []
};
this._retryCount = -1;
this._shouldReconnect = true;
this._connectLock = false;
this._binaryType = 'blob';
this.eventToHandler = new Map([['open', this._handleOpen.bind(this)], ['close', this._handleClose.bind(this)], ['error', this._handleError.bind(this)], ['message', this._handleMessage.bind(this)]]);
/**
* An event listener to be called when the WebSocket connection's readyState changes to CLOSED
*/
this.onclose = undefined;
/**
* An event listener to be called when an error occurs
*/
this.onerror = undefined;
/**
* An event listener to be called when a message is received from the server
*/
this.onmessage = undefined;
/**
* An event listener to be called when the WebSocket connection's readyState changes to OPEN;
* this indicates that the connection is ready to send and receive data
*/
this.onopen = undefined;
this._url = url;
this._protocols = protocols;
this._options = options;
this._connect();
}
createClass(ReconnectingWebSocket, [{
key: 'close',
/**
* Closes the WebSocket connection or connection attempt, if any. If the connection is already
* CLOSED, this method does nothing
*/
value: function close(code, reason) {
this._shouldReconnect = false;
if (!this._ws || this._ws.readyState === this.CLOSED) {
return;
}
this._ws.close(code, reason);
}
/**
* Closes the WebSocket connection or connection attempt and connects again.
* Resets retry counter;
*/
}, {
key: 'reconnect',
value: function reconnect(code, reason) {
this._shouldReconnect = true;
this._retryCount = -1;
if (!this._ws || this._ws.readyState === this.CLOSED) {
this._connect();
}
this._disconnect(code, reason);
this._connect();
}
/**
* Enqueues the specified data to be transmitted to the server over the WebSocket connection
*/
}, {
key: 'send',
value: function send(data) {
if (this._ws) {
this._ws.send(data);
}
}
/**
* Register an event handler of a specific event type
*/
}, {
key: 'addEventListener',
value: function addEventListener(type, listener) {
if (this._listeners[type]) {
// @ts-ignore
this._listeners[type].push(listener);
}
}
/**
* Removes an event listener
*/
}, {
key: 'removeEventListener',
value: function removeEventListener(type, listener) {
if (this._listeners[type]) {
// @ts-ignore
this._listeners[type] = this._listeners[type].filter(function (l) {
return l !== listener;
});
}
}
}, {
key: '_debug',
value: function _debug() {
if (this._options.debug) {
var _console;
for (var _len = arguments.length, params = Array(_len), _key = 0; _key < _len; _key++) {
params[_key] = arguments[_key];
}
// tslint:disable-next-line
(_console = console).log.apply(_console, ['RWS>'].concat(params));
}
}
}, {
key: '_getNextDelay',
value: function _getNextDelay() {
var delay = 0;
if (this._retryCount > 0) {
var _options = this._options,
_options$reconnection = _options.reconnectionDelayGrowFactor,
reconnectionDelayGrowFactor = _options$reconnection === undefined ? DEFAULT.reconnectionDelayGrowFactor : _options$reconnection,
_options$minReconnect = _options.minReconnectionDelay,
minReconnectionDelay = _options$minReconnect === undefined ? DEFAULT.minReconnectionDelay : _options$minReconnect,
_options$maxReconnect = _options.maxReconnectionDelay,
maxReconnectionDelay = _options$maxReconnect === undefined ? DEFAULT.maxReconnectionDelay : _options$maxReconnect;
delay = minReconnectionDelay + Math.pow(this._retryCount - 1, reconnectionDelayGrowFactor);
if (delay > maxReconnectionDelay) {
delay = maxReconnectionDelay;
}
}
this._debug('next delay', delay);
return delay;
}
}, {
key: '_wait',
value: function _wait() {
var _this = this;
return new Promise(function (resolve) {
setTimeout(resolve, _this._getNextDelay());
});
}
/**
* @return Promise<string>
*/
}, {
key: '_getNextUrl',
value: function _getNextUrl(urlProvider) {
if (typeof urlProvider === 'string') {
return Promise.resolve(urlProvider);
}
if (typeof urlProvider === 'function') {
var url = urlProvider();
if (typeof url === 'string') {
return Promise.resolve(url);
}
if (url.then) {
return url;
}
}
throw Error('Invalid URL');
}
}, {
key: '_connect',
value: function _connect() {
var _this2 = this;
if (this._connectLock) {
return;
}
this._connectLock = true;
var _options2 = this._options,
_options2$maxRetries = _options2.maxRetries,
maxRetries = _options2$maxRetries === undefined ? DEFAULT.maxRetries : _options2$maxRetries,
_options2$connectionT = _options2.connectionTimeout,
connectionTimeout = _options2$connectionT === undefined ? DEFAULT.connectionTimeout : _options2$connectionT,
_options2$WebSocket = _options2.WebSocket,
WebSocket = _options2$WebSocket === undefined ? getGlobalWebSocket() : _options2$WebSocket;
if (this._retryCount >= maxRetries) {
this._debug('max retries reached', this._retryCount, '>=', maxRetries);
return;
}
this._retryCount++;
this._debug('connect', this._retryCount);
this._removeListeners();
if (!isWebSocket(WebSocket)) {
throw Error('No valid WebSocket class provided');
}
this._wait().then(function () {
return _this2._getNextUrl(_this2._url);
}).then(function (url) {
_this2._debug('connect', { url: url, protocols: _this2._protocols });
_this2._ws = new WebSocket(url, _this2._protocols);
// @ts-ignore
_this2._ws.binaryType = _this2._binaryType;
_this2._connectLock = false;
_this2._addListeners();
_this2._connectTimeout = setTimeout(function () {
return _this2._handleTimeout();
}, connectionTimeout);
});
}
}, {
key: '_handleTimeout',
value: function _handleTimeout() {
this._debug('timeout event');
this._handleError(new ErrorEvent(Error('TIMEOUT'), this));
}
}, {
key: '_disconnect',
value: function _disconnect(code, reason) {
clearTimeout(this._connectTimeout);
if (!this._ws) {
return;
}
this._removeListeners();
try {
this._ws.close(code, reason);
this._handleClose(new CloseEvent(code, reason, this));
} catch (error) {
// ignore
}
}
}, {
key: '_acceptOpen',
value: function _acceptOpen() {
this._retryCount = 0;
}
}, {
key: '_handleOpen',
value: function _handleOpen(event) {
var _this3 = this;
this._debug('open event');
var _options$minUptime = this._options.minUptime,
minUptime = _options$minUptime === undefined ? DEFAULT.minUptime : _options$minUptime;
clearTimeout(this._connectTimeout);
this._uptimeTimeout = setTimeout(function () {
return _this3._acceptOpen();
}, minUptime);
this._debug('assign binary type');
// @ts-ignore
this._ws.binaryType = this._binaryType;
if (this.onopen) {
this.onopen(event);
}
this._listeners.open.forEach(function (listener) {
return listener(event);
});
}
}, {
key: '_handleMessage',
value: function _handleMessage(event) {
this._debug('message event');
if (this.onmessage) {
this.onmessage(event);
}
this._listeners.message.forEach(function (listener) {
return listener(event);
});
}
}, {
key: '_handleError',
value: function _handleError(event) {
this._debug('error event', event.message);
// https://github.com/pladaria/reconnecting-websocket/pull/69
this._disconnect(4008, event.message === 'TIMEOUT' ? 'timeout' : undefined);
if (this.onerror) {
this.onerror(event);
}
this._debug('exec error listeners');
this._listeners.error.forEach(function (listener) {
return listener(event);
});
this._connect();
}
}, {
key: '_handleClose',
value: function _handleClose(event) {
this._debug('close event');
if (this.onclose) {
this.onclose(event);
}
this._listeners.close.forEach(function (listener) {
return listener(event);
});
}
/**
* Remove event listeners to WebSocket instance
*/
}, {
key: '_removeListeners',
value: function _removeListeners() {
if (!this._ws) {
return;
}
this._debug('removeListeners');
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = this.eventToHandler[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var _ref = _step.value;
var _ref2 = slicedToArray(_ref, 2);
var type = _ref2[0];
var handler = _ref2[1];
this._ws.removeEventListener(type, handler);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
/**
* Assign event listeners to WebSocket instance
*/
}, {
key: '_addListeners',
value: function _addListeners() {
this._debug('addListeners');
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = this.eventToHandler[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var _ref3 = _step2.value;
var _ref4 = slicedToArray(_ref3, 2);
var type = _ref4[0];
var handler = _ref4[1];
this._ws.addEventListener(type, handler);
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
}
}, {
key: 'CONNECTING',
get: function get$$1() {
return ReconnectingWebSocket.CONNECTING;
}
}, {
key: 'OPEN',
get: function get$$1() {
return ReconnectingWebSocket.OPEN;
}
}, {
key: 'CLOSING',
get: function get$$1() {
return ReconnectingWebSocket.CLOSING;
}
}, {
key: 'CLOSED',
get: function get$$1() {
return ReconnectingWebSocket.CLOSED;
}
}, {
key: 'binaryType',
get: function get$$1() {
return this._ws ? this._ws.binaryType : this._binaryType;
},
set: function set$$1(value) {
this._binaryType = value;
if (this._ws) {
// @ts-ignore
this._ws.binaryType = value;
}
}
/**
* Returns the number or connection retries
*/
}, {
key: 'retryCount',
get: function get$$1() {
return Math.max(this._retryCount, 0);
}
/**
* The number of bytes of data that have been queued using calls to send() but not yet
* transmitted to the network. This value resets to zero once all queued data has been sent.
* This value does not reset to zero when the connection is closed; if you keep calling send(),
* this will continue to climb. Read only
*/
}, {
key: 'bufferedAmount',
get: function get$$1() {
return this._ws ? this._ws.bufferedAmount : 0;
}
/**
* The extensions selected by the server. This is currently only the empty string or a list of
* extensions as negotiated by the connection
*/
}, {
key: 'extensions',
get: function get$$1() {
return this._ws ? this._ws.extensions : '';
}
/**
* A string indicating the name of the sub-protocol the server selected;
* this will be one of the strings specified in the protocols parameter when creating the
* WebSocket object
*/
}, {
key: 'protocol',
get: function get$$1() {
return this._ws ? this._ws.protocol : '';
}
/**
* The current state of the connection; this is one of the Ready state constants
*/
}, {
key: 'readyState',
get: function get$$1() {
return this._ws ? this._ws.readyState : ReconnectingWebSocket.CONNECTING;
}
/**
* The URL as resolved by the constructor
*/
}, {
key: 'url',
get: function get$$1() {
return this._ws ? this._ws.url : '';
}
}], [{
key: 'CONNECTING',
get: function get$$1() {
return 0;
}
}, {
key: 'OPEN',
get: function get$$1() {
return 1;
}
}, {
key: 'CLOSING',
get: function get$$1() {
return 2;
}
}, {
key: 'CLOSED',
get: function get$$1() {
return 3;
}
}]);
return ReconnectingWebSocket;
}();
return ReconnectingWebSocket;
}());

@@ -1,1 +0,1 @@

var ReconnectingWebSocket=function(){"use strict";class e{constructor(e,t){this.target=t,this.type=e}}class t extends e{constructor(e,t){super("error",t),this.message=e.message,this.error=e}}class s extends e{constructor(e=1e3,t="",s){super("close",s),this.wasClean=!0,this.code=e,this.reason=t}}const i=()=>{if("undefined"!=typeof WebSocket)return WebSocket},n=e=>"function"==typeof e&&2===e.CLOSING,o={maxReconnectionDelay:1e4,minReconnectionDelay:1e3+4e3*Math.random(),minUptime:5e3,reconnectionDelayGrowFactor:1.3,connectionTimeout:4e3,maxRetries:1/0,debug:!1};class r{constructor(e,t,s={}){this._listeners={error:[],message:[],open:[],close:[]},this._retryCount=-1,this._shouldReconnect=!0,this._connectLock=!1,this._binaryType="blob",this.eventToHandler=new Map([["open",this._handleOpen.bind(this)],["close",this._handleClose.bind(this)],["error",this._handleError.bind(this)],["message",this._handleMessage.bind(this)]]),this.onclose=void 0,this.onerror=void 0,this.onmessage=void 0,this.onopen=void 0,this._url=e,this._protocols=t,this._options=s,this._connect()}static get CONNECTING(){return 0}static get OPEN(){return 1}static get CLOSING(){return 2}static get CLOSED(){return 3}get CONNECTING(){return r.CONNECTING}get OPEN(){return r.OPEN}get CLOSING(){return r.CLOSING}get CLOSED(){return r.CLOSED}get binaryType(){return this._ws?this._ws.binaryType:this._binaryType}set binaryType(e){this._binaryType=e,this._ws&&(this._ws.binaryType=e)}get retryCount(){return Math.max(this._retryCount,0)}get bufferedAmount(){return this._ws?this._ws.bufferedAmount:0}get extensions(){return this._ws?this._ws.extensions:""}get protocol(){return this._ws?this._ws.protocol:""}get readyState(){return this._ws?this._ws.readyState:r.CONNECTING}get url(){return this._ws?this._ws.url:""}close(e,t){this._shouldReconnect=!1,this._ws&&this._ws.readyState!==this.CLOSED&&this._ws.close(e,t)}reconnect(e,t){this._shouldReconnect=!0,this._retryCount=-1,this._ws&&this._ws.readyState!==this.CLOSED||this._connect(),this._disconnect(e,t),this._connect()}send(e){this._ws&&this._ws.send(e)}addEventListener(e,t){this._listeners[e]&&this._listeners[e].push(t)}removeEventListener(e,t){this._listeners[e]&&(this._listeners[e]=this._listeners[e].filter(e=>e!==t))}_debug(...e){this._options.debug&&console.log("RWS>",...e)}_getNextDelay(){let e=0;if(this._retryCount>0){const{reconnectionDelayGrowFactor:t=o.reconnectionDelayGrowFactor,minReconnectionDelay:s=o.minReconnectionDelay,maxReconnectionDelay:i=o.maxReconnectionDelay}=this._options;(e=s+Math.pow(this._retryCount-1,t))>i&&(e=i)}return this._debug("next delay",e),e}_wait(){return new Promise(e=>{setTimeout(e,this._getNextDelay())})}_getNextUrl(e){if("string"==typeof e)return Promise.resolve(e);if("function"==typeof e){const t=e();if("string"==typeof t)return Promise.resolve(t);if(t.then)return t}throw Error("Invalid URL")}_connect(){if(this._connectLock)return;this._connectLock=!0;const{maxRetries:e=o.maxRetries,connectionTimeout:t=o.connectionTimeout,WebSocket:s=i()}=this._options;if(this._retryCount>=e)this._debug("max retries reached",this._retryCount,">=",e);else{if(this._retryCount++,this._debug("connect",this._retryCount),this._removeListeners(),!n(s))throw Error("No valid WebSocket class provided");this._wait().then(()=>this._getNextUrl(this._url)).then(e=>{this._debug("connect",{url:e,protocols:this._protocols}),this._ws=new s(e,this._protocols),this._ws.binaryType=this._binaryType,this._connectLock=!1,this._addListeners(),this._connectTimeout=setTimeout(()=>this._handleTimeout(),t)})}}_handleTimeout(){this._debug("timeout event"),this._handleError(new t(Error("TIMEOUT"),this))}_disconnect(e,t){if(clearTimeout(this._connectTimeout),this._ws){this._removeListeners();try{this._ws.close(e,t),this._handleClose(new s(e,t,this))}catch(e){}}}_acceptOpen(){this._retryCount=0}_handleOpen(e){this._debug("open event");const{minUptime:t=o.minUptime}=this._options;clearTimeout(this._connectTimeout),this._uptimeTimeout=setTimeout(()=>this._acceptOpen(),t),this._debug("assign binary type"),this._ws.binaryType=this._binaryType,this.onopen&&this.onopen(e),this._listeners.open.forEach(t=>t(e))}_handleMessage(e){this._debug("message event"),this.onmessage&&this.onmessage(e),this._listeners.message.forEach(t=>t(e))}_handleError(e){this._debug("error event",e.message),this._disconnect(void 0,"TIMEOUT"===e.message?"timeout":void 0),this.onerror&&this.onerror(e),this._debug("exec error listeners"),this._listeners.error.forEach(t=>t(e)),this._connect()}_handleClose(e){this._debug("close event"),this.onclose&&this.onclose(e),this._listeners.close.forEach(t=>t(e))}_removeListeners(){if(this._ws){this._debug("removeListeners");for(const[e,t]of this.eventToHandler)this._ws.removeEventListener(e,t)}}_addListeners(){this._debug("addListeners");for(const[e,t]of this.eventToHandler)this._ws.addEventListener(e,t)}}return r}();
var ReconnectingWebSocket=function(){"use strict";var e=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},t=function(){function e(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(t,n,i){return n&&e(t.prototype,n),i&&e(t,i),t}}(),n=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)},i=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t},r=function(){function e(e,t){var n=[],i=!0,r=!1,o=void 0;try{for(var s,u=e[Symbol.iterator]();!(i=(s=u.next()).done)&&(n.push(s.value),!t||n.length!==t);i=!0);}catch(e){r=!0,o=e}finally{try{!i&&u.return&&u.return()}finally{if(r)throw o}}return n}return function(t,n){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t))return e(t,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),o=function t(n,i){e(this,t),this.target=i,this.type=n},s=function(t){function r(t,n){e(this,r);var o=i(this,(r.__proto__||Object.getPrototypeOf(r)).call(this,"error",n));return o.message=t.message,o.error=t,o}return n(r,t),r}(o),u=function(t){function r(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1e3,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",o=arguments[2];e(this,r);var s=i(this,(r.__proto__||Object.getPrototypeOf(r)).call(this,"close",o));return s.wasClean=!0,s.code=t,s.reason=n,s}return n(r,t),r}(o),c=function(){if("undefined"!=typeof WebSocket)return WebSocket},a=function(e){return"function"==typeof e&&2===e.CLOSING},h={maxReconnectionDelay:1e4,minReconnectionDelay:1e3+4e3*Math.random(),minUptime:5e3,reconnectionDelayGrowFactor:1.3,connectionTimeout:4e3,maxRetries:1/0,debug:!1};return function(){function n(t,i){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};e(this,n),this._listeners={error:[],message:[],open:[],close:[]},this._retryCount=-1,this._shouldReconnect=!0,this._connectLock=!1,this._binaryType="blob",this.eventToHandler=new Map([["open",this._handleOpen.bind(this)],["close",this._handleClose.bind(this)],["error",this._handleError.bind(this)],["message",this._handleMessage.bind(this)]]),this.onclose=void 0,this.onerror=void 0,this.onmessage=void 0,this.onopen=void 0,this._url=t,this._protocols=i,this._options=r,this._connect()}return t(n,[{key:"close",value:function(e,t){this._shouldReconnect=!1,this._ws&&this._ws.readyState!==this.CLOSED&&this._ws.close(e,t)}},{key:"reconnect",value:function(e,t){this._shouldReconnect=!0,this._retryCount=-1,this._ws&&this._ws.readyState!==this.CLOSED||this._connect(),this._disconnect(e,t),this._connect()}},{key:"send",value:function(e){this._ws&&this._ws.send(e)}},{key:"addEventListener",value:function(e,t){this._listeners[e]&&this._listeners[e].push(t)}},{key:"removeEventListener",value:function(e,t){this._listeners[e]&&(this._listeners[e]=this._listeners[e].filter(function(e){return e!==t}))}},{key:"_debug",value:function(){if(this._options.debug){for(var e,t=arguments.length,n=Array(t),i=0;i<t;i++)n[i]=arguments[i];(e=console).log.apply(e,["RWS>"].concat(n))}}},{key:"_getNextDelay",value:function(){var e=0;if(this._retryCount>0){var t=this._options,n=t.reconnectionDelayGrowFactor,i=void 0===n?h.reconnectionDelayGrowFactor:n,r=t.minReconnectionDelay,o=void 0===r?h.minReconnectionDelay:r,s=t.maxReconnectionDelay,u=void 0===s?h.maxReconnectionDelay:s;e=o+Math.pow(this._retryCount-1,i),e>u&&(e=u)}return this._debug("next delay",e),e}},{key:"_wait",value:function(){var e=this;return new Promise(function(t){setTimeout(t,e._getNextDelay())})}},{key:"_getNextUrl",value:function(e){if("string"==typeof e)return Promise.resolve(e);if("function"==typeof e){var t=e();if("string"==typeof t)return Promise.resolve(t);if(t.then)return t}throw Error("Invalid URL")}},{key:"_connect",value:function(){var e=this;if(!this._connectLock){this._connectLock=!0;var t=this._options,n=t.maxRetries,i=void 0===n?h.maxRetries:n,r=t.connectionTimeout,o=void 0===r?h.connectionTimeout:r,s=t.WebSocket,u=void 0===s?c():s;if(this._retryCount>=i)return void this._debug("max retries reached",this._retryCount,">=",i);if(this._retryCount++,this._debug("connect",this._retryCount),this._removeListeners(),!a(u))throw Error("No valid WebSocket class provided");this._wait().then(function(){return e._getNextUrl(e._url)}).then(function(t){e._debug("connect",{url:t,protocols:e._protocols}),e._ws=new u(t,e._protocols),e._ws.binaryType=e._binaryType,e._connectLock=!1,e._addListeners(),e._connectTimeout=setTimeout(function(){return e._handleTimeout()},o)})}}},{key:"_handleTimeout",value:function(){this._debug("timeout event"),this._handleError(new s(Error("TIMEOUT"),this))}},{key:"_disconnect",value:function(e,t){if(clearTimeout(this._connectTimeout),this._ws){this._removeListeners();try{this._ws.close(e,t),this._handleClose(new u(e,t,this))}catch(e){}}}},{key:"_acceptOpen",value:function(){this._retryCount=0}},{key:"_handleOpen",value:function(e){var t=this;this._debug("open event");var n=this._options.minUptime,i=void 0===n?h.minUptime:n;clearTimeout(this._connectTimeout),this._uptimeTimeout=setTimeout(function(){return t._acceptOpen()},i),this._debug("assign binary type"),this._ws.binaryType=this._binaryType,this.onopen&&this.onopen(e),this._listeners.open.forEach(function(t){return t(e)})}},{key:"_handleMessage",value:function(e){this._debug("message event"),this.onmessage&&this.onmessage(e),this._listeners.message.forEach(function(t){return t(e)})}},{key:"_handleError",value:function(e){this._debug("error event",e.message),this._disconnect(4008,"TIMEOUT"===e.message?"timeout":void 0),this.onerror&&this.onerror(e),this._debug("exec error listeners"),this._listeners.error.forEach(function(t){return t(e)}),this._connect()}},{key:"_handleClose",value:function(e){this._debug("close event"),this.onclose&&this.onclose(e),this._listeners.close.forEach(function(t){return t(e)})}},{key:"_removeListeners",value:function(){if(this._ws){this._debug("removeListeners");var e=!0,t=!1,n=void 0;try{for(var i,o=this.eventToHandler[Symbol.iterator]();!(e=(i=o.next()).done);e=!0){var s=i.value,u=r(s,2),c=u[0],a=u[1];this._ws.removeEventListener(c,a)}}catch(e){t=!0,n=e}finally{try{!e&&o.return&&o.return()}finally{if(t)throw n}}}}},{key:"_addListeners",value:function(){this._debug("addListeners");var e=!0,t=!1,n=void 0;try{for(var i,o=this.eventToHandler[Symbol.iterator]();!(e=(i=o.next()).done);e=!0){var s=i.value,u=r(s,2),c=u[0],a=u[1];this._ws.addEventListener(c,a)}}catch(e){t=!0,n=e}finally{try{!e&&o.return&&o.return()}finally{if(t)throw n}}}},{key:"CONNECTING",get:function(){return n.CONNECTING}},{key:"OPEN",get:function(){return n.OPEN}},{key:"CLOSING",get:function(){return n.CLOSING}},{key:"CLOSED",get:function(){return n.CLOSED}},{key:"binaryType",get:function(){return this._ws?this._ws.binaryType:this._binaryType},set:function(e){this._binaryType=e,this._ws&&(this._ws.binaryType=e)}},{key:"retryCount",get:function(){return Math.max(this._retryCount,0)}},{key:"bufferedAmount",get:function(){return this._ws?this._ws.bufferedAmount:0}},{key:"extensions",get:function(){return this._ws?this._ws.extensions:""}},{key:"protocol",get:function(){return this._ws?this._ws.protocol:""}},{key:"readyState",get:function(){return this._ws?this._ws.readyState:n.CONNECTING}},{key:"url",get:function(){return this._ws?this._ws.url:""}}],[{key:"CONNECTING",get:function(){return 0}},{key:"OPEN",get:function(){return 1}},{key:"CLOSING",get:function(){return 2}},{key:"CLOSED",get:function(){return 3}}]),n}()}();

@@ -0,1 +1,7 @@

/*!
* Reconnecting WebSocket
* by Pedro Ladaria <pedro.ladaria@gmail.com>
* https://github.com/pladaria/reconnecting-websocket
* License MIT
*/
import { CloseEvent, ErrorEvent, Event, WebSocketEventMap } from './events';

@@ -111,25 +117,25 @@ export declare type Options = {

removeEventListener<K extends keyof WebSocketEventMap>(type: K, listener: ((event: WebSocketEventMap[K]) => void)): void;
private _debug(...params);
private _getNextDelay();
private _wait();
private _debug;
private _getNextDelay;
private _wait;
/**
* @return Promise<string>
*/
private _getNextUrl(urlProvider);
private _connect();
private _handleTimeout();
private _disconnect(code?, reason?);
private _acceptOpen();
private _handleOpen(event);
private _handleMessage(event);
private _handleError(event);
private _handleClose(event);
private _getNextUrl;
private _connect;
private _handleTimeout;
private _disconnect;
private _acceptOpen;
private _handleOpen;
private _handleMessage;
private _handleError;
private _handleClose;
/**
* Remove event listeners to WebSocket instance
*/
private _removeListeners();
private _removeListeners;
/**
* Assign event listeners to WebSocket instance
*/
private _addListeners();
private _addListeners;
}
{
"name": "@october/reconnecting-websocket",
"version": "1.0.1",
"version": "1.0.2",
"description": "Reconnecting WebSocket",
"main": "./dist/reconnecting-websocket-cjs.js",
"modules": "./dist/reconnecting-websocket.mjs",
"types": "./dist/reconnecting-websocket.d.ts",

@@ -32,2 +33,4 @@ "scripts": {

"ava": "^0.25.0",
"babel-plugin-external-helpers": "^6.22.0",
"babel-preset-env": "^1.7.0",
"coveralls": "^3.0.0",

@@ -41,2 +44,3 @@ "del-cli": "^1.1.0",

"rollup": "^0.59.1",
"rollup-plugin-babel": "^3.0.7",
"rollup-plugin-typescript2": "^0.14.0",

@@ -70,3 +74,16 @@ "tslint": "^5.10.0",

}
},
"babel": {
"presets": [
[
"env",
{
"modules": false
}
]
],
"plugins": [
"external-helpers"
]
}
}

@@ -390,3 +390,4 @@ /*!

this._debug('error event', event.message);
this._disconnect(undefined, event.message === 'TIMEOUT' ? 'timeout' : undefined);
// https://github.com/pladaria/reconnecting-websocket/pull/69
this._disconnect(4008, event.message === 'TIMEOUT' ? 'timeout' : undefined);

@@ -393,0 +394,0 @@ if (this.onerror) {

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc