(function webpackUniversalModuleDefinition(root, factory) {
|
if(typeof exports === 'object' && typeof module === 'object')
|
module.exports = factory();
|
else if(typeof define === 'function' && define.amd)
|
define("Centrifuge", [], factory);
|
else if(typeof exports === 'object')
|
exports["Centrifuge"] = factory();
|
else
|
root["Centrifuge"] = factory();
|
})(typeof self !== 'undefined' ? self : this, function() {
|
return /******/ (function(modules) { // webpackBootstrap
|
/******/ // The module cache
|
/******/ var installedModules = {};
|
/******/
|
/******/ // The require function
|
/******/ function __webpack_require__(moduleId) {
|
/******/
|
/******/ // Check if module is in cache
|
/******/ if(installedModules[moduleId]) {
|
/******/ return installedModules[moduleId].exports;
|
/******/ }
|
/******/ // Create a new module (and put it into the cache)
|
/******/ var module = installedModules[moduleId] = {
|
/******/ i: moduleId,
|
/******/ l: false,
|
/******/ exports: {}
|
/******/ };
|
/******/
|
/******/ // Execute the module function
|
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
/******/
|
/******/ // Flag the module as loaded
|
/******/ module.l = true;
|
/******/
|
/******/ // Return the exports of the module
|
/******/ return module.exports;
|
/******/ }
|
/******/
|
/******/
|
/******/ // expose the modules object (__webpack_modules__)
|
/******/ __webpack_require__.m = modules;
|
/******/
|
/******/ // expose the module cache
|
/******/ __webpack_require__.c = installedModules;
|
/******/
|
/******/ // define getter function for harmony exports
|
/******/ __webpack_require__.d = function(exports, name, getter) {
|
/******/ if(!__webpack_require__.o(exports, name)) {
|
/******/ Object.defineProperty(exports, name, {
|
/******/ configurable: false,
|
/******/ enumerable: true,
|
/******/ get: getter
|
/******/ });
|
/******/ }
|
/******/ };
|
/******/
|
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
/******/ __webpack_require__.n = function(module) {
|
/******/ var getter = module && module.__esModule ?
|
/******/ function getDefault() { return module['default']; } :
|
/******/ function getModuleExports() { return module; };
|
/******/ __webpack_require__.d(getter, 'a', getter);
|
/******/ return getter;
|
/******/ };
|
/******/
|
/******/ // Object.prototype.hasOwnProperty.call
|
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
/******/
|
/******/ // __webpack_public_path__
|
/******/ __webpack_require__.p = "";
|
/******/
|
/******/ // Load entry module and return exports
|
/******/ return __webpack_require__(__webpack_require__.s = 31);
|
/******/ })
|
/************************************************************************/
|
/******/ ({
|
|
/***/ 10:
|
/***/ (function(module, exports, __webpack_require__) {
|
|
"use strict";
|
/* WEBPACK VAR INJECTION */(function(global) {
|
|
Object.defineProperty(exports, "__esModule", {
|
value: true
|
});
|
exports.Centrifuge = undefined;
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
var _events = __webpack_require__(6);
|
|
var _events2 = _interopRequireDefault(_events);
|
|
var _subscription = __webpack_require__(11);
|
|
var _subscription2 = _interopRequireDefault(_subscription);
|
|
var _json = __webpack_require__(12);
|
|
var _utils = __webpack_require__(7);
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
function _possibleConstructorReturn(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; }
|
|
function _inherits(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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
var _errorTimeout = 'timeout';
|
var _errorConnectionClosed = 'connection closed';
|
|
var Centrifuge = exports.Centrifuge = function (_EventEmitter) {
|
_inherits(Centrifuge, _EventEmitter);
|
|
function Centrifuge(url, options) {
|
_classCallCheck(this, Centrifuge);
|
|
var _this = _possibleConstructorReturn(this, (Centrifuge.__proto__ || Object.getPrototypeOf(Centrifuge)).call(this));
|
|
_this._url = url;
|
_this._websocket = null;
|
_this._sockjs = null;
|
_this._isSockjs = false;
|
_this._binary = false;
|
_this._methodType = null;
|
_this._pushType = null;
|
_this._encoder = null;
|
_this._decoder = null;
|
_this._status = 'disconnected';
|
_this._reconnect = true;
|
_this._reconnecting = false;
|
_this._transport = null;
|
_this._transportName = null;
|
_this._transportClosed = true;
|
_this._messageId = 0;
|
_this._clientID = null;
|
_this._refreshRequired = false;
|
_this._subs = {};
|
_this._serverSubs = {};
|
_this._lastSeq = {};
|
_this._lastGen = {};
|
_this._lastEpoch = {};
|
_this._messages = [];
|
_this._isBatching = false;
|
_this._isSubscribeBatching = false;
|
_this._privateChannels = {};
|
_this._numRefreshFailed = 0;
|
_this._refreshTimeout = null;
|
_this._pingTimeout = null;
|
_this._pongTimeout = null;
|
_this._subRefreshTimeouts = {};
|
_this._retries = 0;
|
_this._callbacks = {};
|
_this._latency = null;
|
_this._latencyStart = null;
|
_this._connectData = null;
|
_this._token = null;
|
_this._xhrID = 0;
|
_this._xhrs = {};
|
_this._config = {
|
debug: false,
|
websocket: null,
|
sockjs: null,
|
promise: null,
|
minRetry: 1000,
|
maxRetry: 20000,
|
timeout: 5000,
|
ping: true,
|
pingInterval: 25000,
|
pongWaitTimeout: 5000,
|
privateChannelPrefix: '$',
|
onTransportClose: null,
|
sockjsServer: null,
|
sockjsTransports: ['websocket', 'xdr-streaming', 'xhr-streaming', 'eventsource', 'iframe-eventsource', 'iframe-htmlfile', 'xdr-polling', 'xhr-polling', 'iframe-xhr-polling', 'jsonp-polling'],
|
refreshEndpoint: '/centrifuge/refresh',
|
refreshHeaders: {},
|
refreshParams: {},
|
refreshData: {},
|
refreshAttempts: null,
|
refreshInterval: 1000,
|
onRefreshFailed: null,
|
onRefresh: null,
|
subscribeEndpoint: '/centrifuge/subscribe',
|
subscribeHeaders: {},
|
subscribeParams: {},
|
subRefreshInterval: 1000,
|
onPrivateSubscribe: null
|
};
|
_this._configure(options);
|
return _this;
|
}
|
|
_createClass(Centrifuge, [{
|
key: 'setToken',
|
value: function setToken(token) {
|
this._token = token;
|
}
|
}, {
|
key: 'setConnectData',
|
value: function setConnectData(data) {
|
this._connectData = data;
|
}
|
}, {
|
key: 'setRefreshHeaders',
|
value: function setRefreshHeaders(headers) {
|
this._config.refreshHeaders = headers;
|
}
|
}, {
|
key: 'setRefreshParams',
|
value: function setRefreshParams(params) {
|
this._config.refreshParams = params;
|
}
|
}, {
|
key: 'setRefreshData',
|
value: function setRefreshData(data) {
|
this._config.refreshData = data;
|
}
|
}, {
|
key: 'setSubscribeHeaders',
|
value: function setSubscribeHeaders(headers) {
|
this._config.subscribeHeaders = headers;
|
}
|
}, {
|
key: 'setSubscribeParams',
|
value: function setSubscribeParams(params) {
|
this._config.subscribeParams = params;
|
}
|
}, {
|
key: '_ajax',
|
value: function _ajax(url, params, headers, data, callback) {
|
var _this2 = this;
|
|
var query = '';
|
this._debug('sending AJAX request to', url, 'with data', JSON.stringify(data));
|
|
var xhr = global.XMLHttpRequest ? new global.XMLHttpRequest() : new global.ActiveXObject('Microsoft.XMLHTTP');
|
|
for (var i in params) {
|
if (params.hasOwnProperty(i)) {
|
if (query.length > 0) {
|
query += '&';
|
}
|
query += encodeURIComponent(i) + '=' + encodeURIComponent(params[i]);
|
}
|
}
|
if (query.length > 0) {
|
query = '?' + query;
|
}
|
xhr.open('POST', url + query, true);
|
if ('withCredentials' in xhr) {
|
xhr.withCredentials = true;
|
}
|
|
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
for (var headerName in headers) {
|
if (headers.hasOwnProperty(headerName)) {
|
xhr.setRequestHeader(headerName, headers[headerName]);
|
}
|
}
|
|
xhr.onreadystatechange = function () {
|
if (xhr.readyState === 4) {
|
if (xhr.status === 200) {
|
var _data = void 0,
|
parsed = false;
|
try {
|
_data = JSON.parse(xhr.responseText);
|
parsed = true;
|
} catch (e) {
|
callback({
|
error: 'Invalid JSON. Data was: ' + xhr.responseText,
|
status: 200,
|
data: null
|
});
|
}
|
if (parsed) {
|
// prevents double execution.
|
callback({
|
data: _data,
|
status: 200
|
});
|
}
|
} else {
|
_this2._log('wrong status code in AJAX response', xhr.status);
|
callback({
|
status: xhr.status,
|
data: null
|
});
|
}
|
}
|
};
|
setTimeout(function () {
|
return xhr.send(JSON.stringify(data));
|
}, 20);
|
return xhr;
|
}
|
}, {
|
key: '_log',
|
value: function _log() {
|
(0, _utils.log)('info', arguments);
|
}
|
}, {
|
key: '_debug',
|
value: function _debug() {
|
if (this._config.debug === true) {
|
(0, _utils.log)('debug', arguments);
|
}
|
}
|
}, {
|
key: '_websocketSupported',
|
value: function _websocketSupported() {
|
if (this._config.websocket !== null) {
|
return true;
|
}
|
return !(typeof WebSocket !== 'function' && (typeof WebSocket === 'undefined' ? 'undefined' : _typeof(WebSocket)) !== 'object');
|
}
|
}, {
|
key: '_setFormat',
|
value: function _setFormat(format) {
|
if (this._formatOverride(format)) {
|
return;
|
}
|
if (format === 'protobuf') {
|
throw new Error('not implemented by JSON only Centrifuge client – use client with Protobuf');
|
}
|
this._binary = false;
|
this._methodType = _json.JsonMethodType;
|
this._pushType = _json.JsonPushType;
|
this._encoder = new _json.JsonEncoder();
|
this._decoder = new _json.JsonDecoder();
|
}
|
}, {
|
key: '_formatOverride',
|
value: function _formatOverride(format) {
|
return false;
|
}
|
}, {
|
key: '_configure',
|
value: function _configure(configuration) {
|
if (!('Promise' in global)) {
|
throw new Error('Promise polyfill required');
|
}
|
|
(0, _utils.extend)(this._config, configuration || {});
|
this._debug('centrifuge config', this._config);
|
|
if (!this._url) {
|
throw new Error('url required');
|
}
|
|
if ((0, _utils.startsWith)(this._url, 'ws') && this._url.indexOf('format=protobuf') > -1) {
|
this._setFormat('protobuf');
|
} else {
|
this._setFormat('json');
|
}
|
|
if ((0, _utils.startsWith)(this._url, 'http')) {
|
this._debug('client will try to connect to SockJS endpoint');
|
if (this._config.sockjs !== null) {
|
this._debug('SockJS explicitly provided in options');
|
this._sockjs = this._config.sockjs;
|
} else {
|
if (typeof global.SockJS === 'undefined') {
|
throw new Error('SockJS not found, use ws:// in url or include SockJS');
|
}
|
this._debug('use globally defined SockJS');
|
this._sockjs = global.SockJS;
|
}
|
} else {
|
this._debug('client will connect to websocket endpoint');
|
}
|
}
|
}, {
|
key: '_setStatus',
|
value: function _setStatus(newStatus) {
|
if (this._status !== newStatus) {
|
this._debug('Status', this._status, '->', newStatus);
|
this._status = newStatus;
|
}
|
}
|
}, {
|
key: '_isDisconnected',
|
value: function _isDisconnected() {
|
return this._status === 'disconnected';
|
}
|
}, {
|
key: '_isConnecting',
|
value: function _isConnecting() {
|
return this._status === 'connecting';
|
}
|
}, {
|
key: '_isConnected',
|
value: function _isConnected() {
|
return this._status === 'connected';
|
}
|
}, {
|
key: '_nextMessageId',
|
value: function _nextMessageId() {
|
return ++this._messageId;
|
}
|
}, {
|
key: '_resetRetry',
|
value: function _resetRetry() {
|
this._debug('reset retries count to 0');
|
this._retries = 0;
|
}
|
}, {
|
key: '_getRetryInterval',
|
value: function _getRetryInterval() {
|
var interval = (0, _utils.backoff)(this._retries, this._config.minRetry, this._config.maxRetry);
|
|
this._retries += 1;
|
return interval;
|
}
|
}, {
|
key: '_abortInflightXHRs',
|
value: function _abortInflightXHRs() {
|
for (var xhrID in this._xhrs) {
|
try {
|
this._xhrs[xhrID].abort();
|
} catch (e) {
|
this._debug('error aborting xhr', e);
|
}
|
delete this._xhrs[xhrID];
|
}
|
}
|
}, {
|
key: '_clearConnectedState',
|
value: function _clearConnectedState(reconnect) {
|
this._clientID = null;
|
this._stopPing();
|
|
// fire errbacks of registered outgoing calls.
|
for (var id in this._callbacks) {
|
if (this._callbacks.hasOwnProperty(id)) {
|
var callbacks = this._callbacks[id];
|
clearTimeout(callbacks.timeout);
|
var errback = callbacks.errback;
|
if (!errback) {
|
continue;
|
}
|
errback({ error: this._createErrorObject('disconnected') });
|
}
|
}
|
this._callbacks = {};
|
|
// fire unsubscribe events
|
for (var channel in this._subs) {
|
if (this._subs.hasOwnProperty(channel)) {
|
var sub = this._subs[channel];
|
|
if (reconnect) {
|
if (sub._isSuccess()) {
|
sub._triggerUnsubscribe();
|
sub._recover = true;
|
}
|
if (sub._shouldResubscribe()) {
|
sub._setSubscribing();
|
}
|
} else {
|
sub._setUnsubscribed();
|
}
|
}
|
}
|
|
this._abortInflightXHRs();
|
|
// clear refresh timer
|
if (this._refreshTimeout !== null) {
|
clearTimeout(this._refreshTimeout);
|
this._refreshTimeout = null;
|
}
|
|
// clear sub refresh timers
|
for (var _channel in this._subRefreshTimeouts) {
|
if (this._subRefreshTimeouts.hasOwnProperty(_channel) && this._subRefreshTimeouts[_channel]) {
|
this._clearSubRefreshTimeout(_channel);
|
}
|
}
|
this._subRefreshTimeouts = {};
|
|
if (!this._reconnect) {
|
// completely clear subscriptions
|
this._subs = {};
|
}
|
}
|
}, {
|
key: '_isTransportOpen',
|
value: function _isTransportOpen() {
|
if (this._isSockjs) {
|
return this._transport && this._transport.transport && this._transport.transport.readyState === this._transport.transport.OPEN;
|
}
|
return this._transport && this._transport.readyState === this._transport.OPEN;
|
}
|
}, {
|
key: '_transportSend',
|
value: function _transportSend(commands) {
|
if (!commands.length) {
|
return true;
|
}
|
|
if (!this._isTransportOpen()) {
|
// resolve pending commands with error if transport is not open
|
for (var command in commands) {
|
var id = command.id;
|
if (!(id in this._callbacks)) {
|
continue;
|
}
|
var callbacks = this._callbacks[id];
|
clearTimeout(this._callbacks[id].timeout);
|
delete this._callbacks[id];
|
var errback = callbacks.errback;
|
errback({ error: this._createErrorObject(_errorConnectionClosed, 0) });
|
}
|
return false;
|
}
|
this._transport.send(this._encoder.encodeCommands(commands));
|
return true;
|
}
|
}, {
|
key: '_setupTransport',
|
value: function _setupTransport() {
|
var _this3 = this;
|
|
this._isSockjs = false;
|
|
// detect transport to use - SockJS or Websocket
|
if (this._sockjs !== null) {
|
var sockjsOptions = {
|
transports: this._config.sockjsTransports
|
};
|
|
if (this._config.sockjsServer !== null) {
|
sockjsOptions.server = this._config.sockjsServer;
|
}
|
this._isSockjs = true;
|
this._transport = new this._sockjs(this._url, null, sockjsOptions);
|
} else {
|
if (!this._websocketSupported()) {
|
this._debug('No Websocket support and no SockJS configured, can not connect');
|
return;
|
}
|
if (this._config.websocket !== null) {
|
this._websocket = this._config.websocket;
|
} else {
|
this._websocket = WebSocket;
|
}
|
this._transport = new this._websocket(this._url);
|
if (this._binary === true) {
|
this._transport.binaryType = 'arraybuffer';
|
}
|
}
|
|
this._transport.onopen = function () {
|
_this3._transportClosed = false;
|
|
if (_this3._isSockjs) {
|
_this3._transportName = 'sockjs-' + _this3._transport.transport;
|
_this3._transport.onheartbeat = function () {
|
return _this3._restartPing();
|
};
|
} else {
|
_this3._transportName = 'websocket';
|
}
|
|
// Can omit method here due to zero value.
|
var msg = {
|
// method: this._methodType.CONNECT
|
};
|
|
if (_this3._token || _this3._connectData) {
|
msg.params = {};
|
}
|
|
if (_this3._token) {
|
msg.params.token = _this3._token;
|
}
|
|
if (_this3._connectData) {
|
msg.params.data = _this3._connectData;
|
}
|
|
var subs = {};
|
var hasSubs = false;
|
for (var channel in _this3._serverSubs) {
|
if (_this3._serverSubs.hasOwnProperty(channel) && _this3._serverSubs[channel].recoverable) {
|
hasSubs = true;
|
var sub = {
|
'recover': true
|
};
|
if (_this3._serverSubs[channel].seq) {
|
sub['seq'] = _this3._serverSubs[channel].seq;
|
}
|
if (_this3._serverSubs[channel].gen) {
|
sub['gen'] = _this3._serverSubs[channel].gen;
|
}
|
if (_this3._serverSubs[channel].epoch) {
|
sub['epoch'] = _this3._serverSubs[channel].epoch;
|
}
|
subs[channel] = sub;
|
}
|
}
|
if (hasSubs) {
|
if (!msg.params) {
|
msg.params = {};
|
}
|
msg.params.subs = subs;
|
}
|
|
_this3._latencyStart = new Date();
|
_this3._call(msg).then(function (resolveCtx) {
|
_this3._connectResponse(_this3._decoder.decodeCommandResult(_this3._methodType.CONNECT, resolveCtx.result), hasSubs);
|
if (resolveCtx.next) {
|
resolveCtx.next();
|
}
|
}, function (rejectCtx) {
|
var err = rejectCtx.error;
|
if (err.code === 109) {
|
// token expired.
|
_this3._refreshRequired = true;
|
}
|
_this3._disconnect('connect error', true);
|
if (rejectCtx.next) {
|
rejectCtx.next();
|
}
|
});
|
};
|
|
this._transport.onerror = function (error) {
|
_this3._debug('transport level error', error);
|
};
|
|
this._transport.onclose = function (closeEvent) {
|
_this3._transportClosed = true;
|
var reason = _errorConnectionClosed;
|
var needReconnect = true;
|
|
if (closeEvent && 'reason' in closeEvent && closeEvent.reason) {
|
try {
|
var advice = JSON.parse(closeEvent.reason);
|
_this3._debug('reason is an advice object', advice);
|
reason = advice.reason;
|
needReconnect = advice.reconnect;
|
} catch (e) {
|
reason = closeEvent.reason;
|
_this3._debug('reason is a plain string', reason);
|
}
|
}
|
|
// onTransportClose callback should be executed every time transport was closed.
|
// This can be helpful to catch failed connection events (because our disconnect
|
// event only called once and every future attempts to connect do not fire disconnect
|
// event again).
|
if (_this3._config.onTransportClose !== null) {
|
_this3._config.onTransportClose({
|
event: closeEvent,
|
reason: reason,
|
reconnect: needReconnect
|
});
|
}
|
|
_this3._disconnect(reason, needReconnect);
|
|
if (_this3._reconnect === true) {
|
_this3._reconnecting = true;
|
var interval = _this3._getRetryInterval();
|
|
_this3._debug('reconnect after ' + interval + ' milliseconds');
|
setTimeout(function () {
|
if (_this3._reconnect === true) {
|
if (_this3._refreshRequired) {
|
_this3._refresh();
|
} else {
|
_this3._connect();
|
}
|
}
|
}, interval);
|
}
|
};
|
|
this._transport.onmessage = function (event) {
|
_this3._dataReceived(event.data);
|
};
|
}
|
}, {
|
key: 'rpc',
|
value: function rpc(data) {
|
var _this4 = this;
|
|
var msg = {
|
method: this._methodType.RPC,
|
params: {
|
data: data
|
}
|
};
|
|
if (!this.isConnected()) {
|
return Promise.reject(this._createErrorObject(_errorConnectionClosed, 0));
|
}
|
|
return this._call(msg).then(function (resolveCtx) {
|
if (resolveCtx.next) {
|
resolveCtx.next();
|
}
|
return _this4._decoder.decodeCommandResult(_this4._methodType.RPC, resolveCtx.result);
|
}, function (rejectCtx) {
|
if (rejectCtx.next) {
|
rejectCtx.next();
|
}
|
return Promise.reject(rejectCtx.error);
|
});
|
}
|
}, {
|
key: 'send',
|
value: function send(data) {
|
var msg = {
|
method: this._methodType.SEND,
|
params: {
|
data: data
|
}
|
};
|
|
if (!this.isConnected()) {
|
return Promise.reject(this._createErrorObject(_errorConnectionClosed, 0));
|
}
|
|
var sent = this._transportSend([msg]); // can send async message to server without id set
|
if (!sent) {
|
return Promise.reject(this._createErrorObject(_errorConnectionClosed, 0));
|
};
|
return Promise.resolve({});
|
}
|
}, {
|
key: 'publish',
|
value: function publish(channel, data) {
|
var msg = {
|
method: this._methodType.PUBLISH,
|
params: {
|
channel: channel,
|
data: data
|
}
|
};
|
|
if (!this.isConnected()) {
|
return Promise.reject(this._createErrorObject(_errorConnectionClosed, 0));
|
}
|
|
return this._call(msg).then(function (result) {
|
if (result.next) {
|
result.next();
|
}
|
return {};
|
});
|
}
|
}, {
|
key: '_dataReceived',
|
value: function _dataReceived(data) {
|
var _this5 = this;
|
|
var replies = this._decoder.decodeReplies(data);
|
// we have to guarantee order of events in replies processing - i.e. start processing
|
// next reply only when we finished processing of current one. Without syncing things in
|
// this way we could get wrong publication events order as reply promises resolve
|
// on next loop tick so for loop continues before we finished emitting all reply events.
|
var p = Promise.resolve();
|
|
var _loop = function _loop(i) {
|
if (replies.hasOwnProperty(i)) {
|
p = p.then(function () {
|
return _this5._dispatchReply(replies[i]);
|
});
|
}
|
};
|
|
for (var i in replies) {
|
_loop(i);
|
}
|
this._restartPing();
|
}
|
}, {
|
key: '_call',
|
value: function _call(msg) {
|
var _this6 = this;
|
|
return new Promise(function (resolve, reject) {
|
var id = _this6._addMessage(msg);
|
_this6._registerCall(id, resolve, reject);
|
});
|
}
|
}, {
|
key: '_connect',
|
value: function _connect() {
|
if (this.isConnected()) {
|
this._debug('connect called when already connected');
|
return;
|
}
|
if (this._status === 'connecting') {
|
return;
|
}
|
|
this._debug('start connecting');
|
this._setStatus('connecting');
|
this._clientID = null;
|
this._reconnect = true;
|
this._setupTransport();
|
}
|
}, {
|
key: '_disconnect',
|
value: function _disconnect(reason, shouldReconnect) {
|
|
var reconnect = shouldReconnect || false;
|
if (reconnect === false) {
|
this._reconnect = false;
|
}
|
|
if (this._isDisconnected()) {
|
if (!reconnect) {
|
this._clearConnectedState(reconnect);
|
}
|
return;
|
}
|
|
this._clearConnectedState(reconnect);
|
|
this._debug('disconnected:', reason, shouldReconnect);
|
this._setStatus('disconnected');
|
|
if (this._refreshTimeout) {
|
clearTimeout(this._refreshTimeout);
|
this._refreshTimeout = null;
|
}
|
if (this._reconnecting === false) {
|
// fire unsubscribe events for server side subs.
|
for (var channel in this._serverSubs) {
|
if (this._serverSubs.hasOwnProperty(channel)) {
|
this.emit('unsubscribe', { channel: channel });
|
}
|
}
|
this.emit('disconnect', {
|
reason: reason,
|
reconnect: reconnect
|
});
|
}
|
|
if (reconnect === false) {
|
this._subs = {};
|
this._serverSubs = {};
|
}
|
|
if (!this._transportClosed) {
|
this._transport.close();
|
}
|
}
|
}, {
|
key: '_refreshFailed',
|
value: function _refreshFailed() {
|
this._numRefreshFailed = 0;
|
if (!this._isDisconnected()) {
|
this._disconnect('refresh failed', false);
|
}
|
if (this._config.onRefreshFailed !== null) {
|
this._config.onRefreshFailed();
|
}
|
}
|
}, {
|
key: '_refresh',
|
value: function _refresh() {
|
var _this7 = this;
|
|
// ask application for new connection token.
|
this._debug('refresh token');
|
|
if (this._config.refreshAttempts === 0) {
|
this._debug('refresh attempts set to 0, do not send refresh request at all');
|
this._refreshFailed();
|
return;
|
}
|
|
if (this._refreshTimeout !== null) {
|
clearTimeout(this._refreshTimeout);
|
this._refreshTimeout = null;
|
}
|
|
var clientID = this._clientID;
|
var xhrID = this._newXHRID();
|
|
var cb = function cb(resp) {
|
if (xhrID in _this7._xhrs) {
|
delete _this7._xhrs[xhrID];
|
}
|
if (_this7._clientID !== clientID) {
|
return;
|
}
|
if (resp.error || resp.status !== 200) {
|
// We don't perform any connection status related actions here as we are
|
// relying on server that must close connection eventually.
|
if (resp.error) {
|
_this7._debug('error refreshing connection token', resp.error);
|
} else {
|
_this7._debug('error refreshing connection token: wrong status code', resp.status);
|
}
|
_this7._numRefreshFailed++;
|
if (_this7._refreshTimeout !== null) {
|
clearTimeout(_this7._refreshTimeout);
|
_this7._refreshTimeout = null;
|
}
|
if (_this7._config.refreshAttempts !== null && _this7._numRefreshFailed >= _this7._config.refreshAttempts) {
|
_this7._refreshFailed();
|
return;
|
}
|
var jitter = Math.round(Math.random() * 1000 * Math.max(_this7._numRefreshFailed, 20));
|
var interval = _this7._config.refreshInterval + jitter;
|
_this7._refreshTimeout = setTimeout(function () {
|
return _this7._refresh();
|
}, interval);
|
return;
|
}
|
_this7._numRefreshFailed = 0;
|
_this7._token = resp.data.token;
|
if (!_this7._token) {
|
_this7._refreshFailed();
|
return;
|
}
|
if (_this7._isDisconnected() && _this7._reconnect) {
|
_this7._debug('token refreshed, connect from scratch');
|
_this7._connect();
|
} else {
|
_this7._debug('send refreshed token');
|
var msg = {
|
method: _this7._methodType.REFRESH,
|
params: {
|
token: _this7._token
|
}
|
};
|
_this7._call(msg).then(function (resolveCtx) {
|
_this7._refreshResponse(_this7._decoder.decodeCommandResult(_this7._methodType.REFRESH, resolveCtx.result));
|
if (resolveCtx.next) {
|
resolveCtx.next();
|
}
|
}, function (rejectCtx) {
|
_this7._refreshError(rejectCtx.error);
|
if (rejectCtx.next) {
|
rejectCtx.next();
|
}
|
});
|
}
|
};
|
|
if (this._config.onRefresh !== null) {
|
var context = {};
|
this._config.onRefresh(context, cb);
|
} else {
|
var xhr = this._ajax(this._config.refreshEndpoint, this._config.refreshParams, this._config.refreshHeaders, this._config.refreshData, cb);
|
this._xhrs[xhrID] = xhr;
|
}
|
}
|
}, {
|
key: '_refreshError',
|
value: function _refreshError(err) {
|
var _this8 = this;
|
|
this._debug('refresh error', err);
|
if (this._refreshTimeout) {
|
clearTimeout(this._refreshTimeout);
|
this._refreshTimeout = null;
|
}
|
var interval = this._config.refreshInterval + Math.round(Math.random() * 1000);
|
this._refreshTimeout = setTimeout(function () {
|
return _this8._refresh();
|
}, interval);
|
}
|
}, {
|
key: '_refreshResponse',
|
value: function _refreshResponse(result) {
|
var _this9 = this;
|
|
if (this._refreshTimeout) {
|
clearTimeout(this._refreshTimeout);
|
this._refreshTimeout = null;
|
}
|
if (result.expires) {
|
this._clientID = result.client;
|
this._refreshTimeout = setTimeout(function () {
|
return _this9._refresh();
|
}, this._getTTLMilliseconds(result.ttl));
|
}
|
}
|
}, {
|
key: '_newXHRID',
|
value: function _newXHRID() {
|
this._xhrID++;
|
return this._xhrID;
|
}
|
}, {
|
key: '_subRefresh',
|
value: function _subRefresh(channel) {
|
var _this10 = this;
|
|
this._debug('refresh subscription token for channel', channel);
|
|
if (this._subRefreshTimeouts[channel] !== undefined) {
|
this._clearSubRefreshTimeout(channel);
|
} else {
|
return;
|
}
|
|
var clientID = this._clientID;
|
var xhrID = this._newXHRID();
|
|
var cb = function cb(resp) {
|
if (xhrID in _this10._xhrs) {
|
delete _this10._xhrs[xhrID];
|
}
|
if (resp.error || resp.status !== 200 || _this10._clientID !== clientID) {
|
return;
|
}
|
var channelsData = {};
|
if (resp.data.channels) {
|
for (var i in data.channels) {
|
var channelData = resp.data.channels[i];
|
if (!channelData.channel) {
|
continue;
|
}
|
channelsData[channelData.channel] = channelData.token;
|
}
|
}
|
|
var token = channelsData[channel];
|
if (!token) {
|
return;
|
}
|
var msg = {
|
method: _this10._methodType.SUB_REFRESH,
|
params: {
|
channel: channel,
|
token: token
|
}
|
};
|
|
var sub = _this10._getSub(channel);
|
if (sub === null) {
|
return;
|
}
|
|
_this10._call(msg).then(function (resolveCtx) {
|
_this10._subRefreshResponse(channel, _this10._decoder.decodeCommandResult(_this10._methodType.SUB_REFRESH, resolveCtx.result));
|
if (resolveCtx.next) {
|
resolveCtx.next();
|
}
|
}, function (rejectCtx) {
|
_this10._subRefreshError(channel, rejectCtx.error);
|
if (rejectCtx.next) {
|
rejectCtx.next();
|
}
|
});
|
};
|
|
var data = {
|
client: this._clientID,
|
channels: [channel]
|
};
|
|
if (this._config.onPrivateSubscribe !== null) {
|
this._config.onPrivateSubscribe({
|
data: data
|
}, cb);
|
} else {
|
var xhr = this._ajax(this._config.subscribeEndpoint, this._config.subscribeParams, this._config.subscribeHeaders, data, cb);
|
this._xhrs[xhrID] = xhr;
|
}
|
}
|
}, {
|
key: '_clearSubRefreshTimeout',
|
value: function _clearSubRefreshTimeout(channel) {
|
if (this._subRefreshTimeouts[channel] !== undefined) {
|
clearTimeout(this._subRefreshTimeouts[channel]);
|
delete this._subRefreshTimeouts[channel];
|
}
|
}
|
}, {
|
key: '_subRefreshError',
|
value: function _subRefreshError(channel, err) {
|
var _this11 = this;
|
|
this._debug('subscription refresh error', channel, err);
|
this._clearSubRefreshTimeout(channel);
|
var sub = this._getSub(channel);
|
if (sub === null) {
|
return;
|
}
|
var jitter = Math.round(Math.random() * 1000);
|
var subRefreshTimeout = setTimeout(function () {
|
return _this11._subRefresh(channel);
|
}, this._config.subRefreshInterval + jitter);
|
this._subRefreshTimeouts[channel] = subRefreshTimeout;
|
return;
|
}
|
}, {
|
key: '_subRefreshResponse',
|
value: function _subRefreshResponse(channel, result) {
|
var _this12 = this;
|
|
this._debug('subscription refresh success', channel);
|
this._clearSubRefreshTimeout(channel);
|
var sub = this._getSub(channel);
|
if (sub === null) {
|
return;
|
}
|
if (result.expires === true) {
|
var subRefreshTimeout = setTimeout(function () {
|
return _this12._subRefresh(channel);
|
}, this._getTTLMilliseconds(result.ttl));
|
this._subRefreshTimeouts[channel] = subRefreshTimeout;
|
}
|
return;
|
}
|
}, {
|
key: '_subscribe',
|
value: function _subscribe(sub, isResubscribe) {
|
var _this13 = this;
|
|
this._debug('subscribing on', sub.channel);
|
var channel = sub.channel;
|
|
if (!(channel in this._subs)) {
|
this._subs[channel] = sub;
|
}
|
|
if (!this.isConnected()) {
|
// subscribe will be called later
|
sub._setNew();
|
return;
|
}
|
|
sub._setSubscribing(isResubscribe);
|
|
var msg = {
|
method: this._methodType.SUBSCRIBE,
|
params: {
|
channel: channel
|
}
|
};
|
|
// If channel name does not start with privateChannelPrefix - then we
|
// can just send subscription message to Centrifuge. If channel name
|
// starts with privateChannelPrefix - then this is a private channel
|
// and we should ask web application backend for permission first.
|
if ((0, _utils.startsWith)(channel, this._config.privateChannelPrefix)) {
|
// private channel.
|
if (this._isSubscribeBatching) {
|
this._privateChannels[channel] = true;
|
} else {
|
this.startSubscribeBatching();
|
this._subscribe(sub);
|
this.stopSubscribeBatching();
|
}
|
} else {
|
var recover = sub._needRecover();
|
|
if (recover === true) {
|
msg.params.recover = true;
|
var seq = this._getLastSeq(channel);
|
if (seq) {
|
msg.params.seq = seq;
|
}
|
var gen = this._getLastGen(channel);
|
if (gen) {
|
msg.params.gen = gen;
|
}
|
var epoch = this._getLastEpoch(channel);
|
if (epoch) {
|
msg.params.epoch = epoch;
|
}
|
}
|
|
this._call(msg).then(function (resolveCtx) {
|
_this13._subscribeResponse(channel, recover, _this13._decoder.decodeCommandResult(_this13._methodType.SUBSCRIBE, resolveCtx.result));
|
if (resolveCtx.next) {
|
resolveCtx.next();
|
}
|
}, function (rejectCtx) {
|
_this13._subscribeError(channel, rejectCtx.error);
|
if (rejectCtx.next) {
|
rejectCtx.next();
|
}
|
});
|
}
|
}
|
}, {
|
key: '_unsubscribe',
|
value: function _unsubscribe(sub) {
|
if (this.isConnected()) {
|
// No need to unsubscribe in disconnected state - i.e. client already unsubscribed.
|
this._addMessage({
|
method: this._methodType.UNSUBSCRIBE,
|
params: {
|
channel: sub.channel
|
}
|
});
|
}
|
}
|
}, {
|
key: '_getTTLMilliseconds',
|
value: function _getTTLMilliseconds(ttl) {
|
// https://stackoverflow.com/questions/12633405/what-is-the-maximum-delay-for-setinterval
|
return Math.min(ttl * 1000, 2147483647);
|
}
|
}, {
|
key: 'getSub',
|
value: function getSub(channel) {
|
return this._getSub(channel);
|
}
|
}, {
|
key: '_getSub',
|
value: function _getSub(channel) {
|
var sub = this._subs[channel];
|
if (!sub) {
|
return null;
|
}
|
return sub;
|
}
|
}, {
|
key: '_connectResponse',
|
value: function _connectResponse(result, isRecover) {
|
var _this14 = this;
|
|
var wasReconnecting = this._reconnecting;
|
this._reconnecting = false;
|
this._resetRetry();
|
this._refreshRequired = false;
|
|
if (this.isConnected()) {
|
return;
|
}
|
|
if (this._latencyStart !== null) {
|
this._latency = new Date().getTime() - this._latencyStart.getTime();
|
this._latencyStart = null;
|
}
|
|
this._clientID = result.client;
|
this._setStatus('connected');
|
|
if (this._refreshTimeout) {
|
clearTimeout(this._refreshTimeout);
|
}
|
|
if (result.expires) {
|
this._refreshTimeout = setTimeout(function () {
|
return _this14._refresh();
|
}, this._getTTLMilliseconds(result.ttl));
|
}
|
|
this.startBatching();
|
this.startSubscribeBatching();
|
for (var channel in this._subs) {
|
if (this._subs.hasOwnProperty(channel)) {
|
var sub = this._subs[channel];
|
if (sub._shouldResubscribe()) {
|
this._subscribe(sub, wasReconnecting);
|
}
|
}
|
}
|
this.stopSubscribeBatching();
|
this.stopBatching();
|
|
this._startPing();
|
|
var ctx = {
|
client: result.client,
|
transport: this._transportName,
|
latency: this._latency
|
};
|
if (result.data) {
|
ctx.data = result.data;
|
}
|
|
this.emit('connect', ctx);
|
|
if (result.subs) {
|
this._processServerSubs(result.subs, isRecover);
|
}
|
}
|
}, {
|
key: '_processServerSubs',
|
value: function _processServerSubs(subs, isRecover) {
|
for (var channel in subs) {
|
if (subs.hasOwnProperty(channel)) {
|
var sub = subs[channel];
|
var recovered = sub.recovered === true;
|
var subCtx = { channel: channel, isResubscribe: isRecover, recovered: recovered };
|
this.emit('subscribe', subCtx);
|
}
|
}
|
for (var _channel2 in subs) {
|
if (subs.hasOwnProperty(_channel2)) {
|
var _sub = subs[_channel2];
|
if (_sub.recovered) {
|
var pubs = _sub.publications;
|
if (pubs && pubs.length > 0) {
|
pubs = pubs.reverse();
|
for (var i in pubs) {
|
if (pubs.hasOwnProperty(i)) {
|
this._handlePublication(_channel2, pubs[i]);
|
}
|
}
|
}
|
}
|
this._serverSubs[_channel2] = {
|
'seq': _sub.seq,
|
'gen': _sub.gen,
|
'epoch': _sub.epoch,
|
'recoverable': _sub.recoverable
|
};
|
}
|
}
|
}
|
}, {
|
key: '_stopPing',
|
value: function _stopPing() {
|
if (this._pongTimeout !== null) {
|
clearTimeout(this._pongTimeout);
|
this._pongTimeout = null;
|
}
|
if (this._pingTimeout !== null) {
|
clearTimeout(this._pingTimeout);
|
this._pingTimeout = null;
|
}
|
}
|
}, {
|
key: '_startPing',
|
value: function _startPing() {
|
var _this15 = this;
|
|
if (this._config.ping !== true || this._config.pingInterval <= 0) {
|
return;
|
}
|
if (!this.isConnected()) {
|
return;
|
}
|
|
this._pingTimeout = setTimeout(function () {
|
if (!_this15.isConnected()) {
|
_this15._stopPing();
|
return;
|
}
|
_this15.ping();
|
_this15._pongTimeout = setTimeout(function () {
|
_this15._disconnect('no ping', true);
|
}, _this15._config.pongWaitTimeout);
|
}, this._config.pingInterval);
|
}
|
}, {
|
key: '_restartPing',
|
value: function _restartPing() {
|
this._stopPing();
|
this._startPing();
|
}
|
}, {
|
key: '_subscribeError',
|
value: function _subscribeError(channel, error) {
|
var sub = this._getSub(channel);
|
if (!sub) {
|
return;
|
}
|
if (!sub._isSubscribing()) {
|
return;
|
}
|
if (error.code === 0 && error.message === _errorTimeout) {
|
// client side timeout.
|
this._disconnect('timeout', true);
|
return;
|
}
|
sub._setSubscribeError(error);
|
}
|
}, {
|
key: '_subscribeResponse',
|
value: function _subscribeResponse(channel, isRecover, result) {
|
var _this16 = this;
|
|
var sub = this._getSub(channel);
|
if (!sub) {
|
return;
|
}
|
if (!sub._isSubscribing()) {
|
return;
|
}
|
|
var recovered = false;
|
if ('recovered' in result) {
|
recovered = result.recovered;
|
}
|
sub._setSubscribeSuccess(recovered);
|
|
var pubs = result.publications;
|
if (pubs && pubs.length > 0) {
|
pubs = pubs.reverse();
|
for (var i in pubs) {
|
if (pubs.hasOwnProperty(i)) {
|
this._handlePublication(channel, pubs[i]);
|
}
|
}
|
}
|
|
if (result.recoverable && (!isRecover || !recovered)) {
|
this._lastSeq[channel] = result.seq || 0;
|
this._lastGen[channel] = result.gen || 0;
|
}
|
|
this._lastEpoch[channel] = result.epoch || '';
|
|
if (result.recoverable) {
|
sub._recoverable = true;
|
}
|
|
if (result.expires === true) {
|
var subRefreshTimeout = setTimeout(function () {
|
return _this16._subRefresh(channel);
|
}, this._getTTLMilliseconds(result.ttl));
|
this._subRefreshTimeouts[channel] = subRefreshTimeout;
|
}
|
}
|
}, {
|
key: '_handleReply',
|
value: function _handleReply(reply, next) {
|
var id = reply.id;
|
var result = reply.result;
|
|
if (!(id in this._callbacks)) {
|
next();
|
return;
|
}
|
var callbacks = this._callbacks[id];
|
clearTimeout(this._callbacks[id].timeout);
|
delete this._callbacks[id];
|
|
if (!(0, _utils.errorExists)(reply)) {
|
var callback = callbacks.callback;
|
if (!callback) {
|
return;
|
}
|
callback({ result: result, next: next });
|
} else {
|
var errback = callbacks.errback;
|
if (!errback) {
|
next();
|
return;
|
}
|
var error = reply.error;
|
errback({ error: error, next: next });
|
}
|
}
|
}, {
|
key: '_handleJoin',
|
value: function _handleJoin(channel, join) {
|
var ctx = { 'info': join.info };
|
var sub = this._getSub(channel);
|
if (!sub) {
|
ctx.channel = channel;
|
this.emit('join', ctx);
|
return;
|
}
|
sub.emit('join', ctx);
|
}
|
}, {
|
key: '_handleLeave',
|
value: function _handleLeave(channel, leave) {
|
var ctx = { 'info': leave.info };
|
var sub = this._getSub(channel);
|
if (!sub) {
|
ctx.channel = channel;
|
this.emit('leave', ctx);
|
return;
|
}
|
sub.emit('leave', ctx);
|
}
|
}, {
|
key: '_handleUnsub',
|
value: function _handleUnsub(channel, unsub) {
|
var ctx = {};
|
var sub = this._getSub(channel);
|
if (!sub) {
|
delete this._serverSubs[channel];
|
ctx.channel = channel;
|
this.emit('unsubscribe', ctx);
|
return;
|
}
|
sub.unsubscribe();
|
if (unsub.resubscribe === true) {
|
sub.subscribe();
|
}
|
}
|
}, {
|
key: '_handleSub',
|
value: function _handleSub(channel, sub) {
|
this._serverSubs[channel] = {
|
'seq': sub.seq,
|
'gen': sub.gen,
|
'epoch': sub.epoch,
|
'recoverable': sub.recoverable
|
};
|
var ctx = { 'channel': channel, isResubscribe: false, recovered: false };
|
this.emit('subscribe', ctx);
|
}
|
}, {
|
key: '_handlePublication',
|
value: function _handlePublication(channel, pub) {
|
var sub = this._getSub(channel);
|
var ctx = {
|
'data': pub.data,
|
'seq': pub.seq,
|
'gen': pub.gen
|
};
|
if (!sub) {
|
if (this._serverSubs[channel] !== undefined) {
|
if (pub.seq !== undefined) {
|
this._serverSubs[channel].seq = pub.seq;
|
}
|
if (pub.gen !== undefined) {
|
this._serverSubs[channel].gen = pub.gen;
|
}
|
}
|
ctx.channel = channel;
|
this.emit('publish', ctx);
|
return;
|
}
|
if (pub.seq !== undefined) {
|
this._lastSeq[channel] = pub.seq;
|
}
|
if (pub.gen !== undefined) {
|
this._lastGen[channel] = pub.gen;
|
}
|
sub.emit('publish', ctx);
|
}
|
}, {
|
key: '_handleMessage',
|
value: function _handleMessage(message) {
|
this.emit('message', message.data);
|
}
|
}, {
|
key: '_handlePush',
|
value: function _handlePush(data, next) {
|
var push = this._decoder.decodePush(data);
|
var type = 0;
|
if ('type' in push) {
|
type = push['type'];
|
}
|
var channel = push.channel;
|
|
if (type === this._pushType.PUBLICATION) {
|
var pub = this._decoder.decodePushData(this._pushType.PUBLICATION, push.data);
|
this._handlePublication(channel, pub);
|
} else if (type === this._pushType.MESSAGE) {
|
var message = this._decoder.decodePushData(this._pushType.MESSAGE, push.data);
|
this._handleMessage(message);
|
} else if (type === this._pushType.JOIN) {
|
var join = this._decoder.decodePushData(this._pushType.JOIN, push.data);
|
this._handleJoin(channel, join);
|
} else if (type === this._pushType.LEAVE) {
|
var leave = this._decoder.decodePushData(this._pushType.LEAVE, push.data);
|
this._handleLeave(channel, leave);
|
} else if (type === this._pushType.UNSUB) {
|
var unsub = this._decoder.decodePushData(this._pushType.UNSUB, push.data);
|
this._handleUnsub(channel, unsub);
|
} else if (type === this._pushType.SUB) {
|
var sub = this._decoder.decodePushData(this._pushType.SUB, push.data);
|
this._handleSub(channel, sub);
|
}
|
next();
|
}
|
}, {
|
key: '_dispatchReply',
|
value: function _dispatchReply(reply) {
|
var next;
|
var p = new Promise(function (resolve) {
|
next = resolve;
|
});
|
|
if (reply === undefined || reply === null) {
|
this._debug('dispatch: got undefined or null reply');
|
next();
|
return p;
|
}
|
|
var id = reply.id;
|
|
if (id && id > 0) {
|
this._handleReply(reply, next);
|
} else {
|
this._handlePush(reply.result, next);
|
}
|
|
return p;
|
}
|
}, {
|
key: '_flush',
|
value: function _flush() {
|
var messages = this._messages.slice(0);
|
this._messages = [];
|
this._transportSend(messages);
|
}
|
}, {
|
key: '_ping',
|
value: function _ping() {
|
var _this17 = this;
|
|
var msg = {
|
method: this._methodType.PING
|
};
|
this._call(msg).then(function (resolveCtx) {
|
_this17._pingResponse(_this17._decoder.decodeCommandResult(_this17._methodType.PING, resolveCtx.result));
|
if (resolveCtx.next) {
|
resolveCtx.next();
|
}
|
}, function (rejectCtx) {
|
_this17._debug('ping error', rejectCtx.error);
|
if (rejectCtx.next) {
|
rejectCtx.next();
|
}
|
});
|
}
|
}, {
|
key: '_pingResponse',
|
value: function _pingResponse(result) {
|
if (!this.isConnected()) {
|
return;
|
}
|
this._stopPing();
|
this._startPing();
|
}
|
}, {
|
key: '_getLastSeq',
|
value: function _getLastSeq(channel) {
|
var lastSeq = this._lastSeq[channel];
|
if (lastSeq) {
|
return lastSeq;
|
}
|
return 0;
|
}
|
}, {
|
key: '_getLastGen',
|
value: function _getLastGen(channel) {
|
var lastGen = this._lastGen[channel];
|
if (lastGen) {
|
return lastGen;
|
}
|
return 0;
|
}
|
}, {
|
key: '_getLastEpoch',
|
value: function _getLastEpoch(channel) {
|
var lastEpoch = this._lastEpoch[channel];
|
if (lastEpoch) {
|
return lastEpoch;
|
}
|
return '';
|
}
|
}, {
|
key: '_createErrorObject',
|
value: function _createErrorObject(message, code) {
|
var errObject = {
|
message: message,
|
code: code || 0
|
};
|
|
return errObject;
|
}
|
}, {
|
key: '_registerCall',
|
value: function _registerCall(id, callback, errback) {
|
var _this18 = this;
|
|
this._callbacks[id] = {
|
callback: callback,
|
errback: errback,
|
timeout: null
|
};
|
this._callbacks[id].timeout = setTimeout(function () {
|
delete _this18._callbacks[id];
|
if ((0, _utils.isFunction)(errback)) {
|
errback({ error: _this18._createErrorObject(_errorTimeout) });
|
}
|
}, this._config.timeout);
|
}
|
}, {
|
key: '_addMessage',
|
value: function _addMessage(message) {
|
var id = this._nextMessageId();
|
message.id = id;
|
if (this._isBatching === true) {
|
this._messages.push(message);
|
} else {
|
this._transportSend([message]);
|
}
|
return id;
|
}
|
}, {
|
key: 'isConnected',
|
value: function isConnected() {
|
return this._isConnected();
|
}
|
}, {
|
key: 'connect',
|
value: function connect() {
|
this._connect();
|
}
|
}, {
|
key: 'disconnect',
|
value: function disconnect() {
|
this._disconnect('client', false);
|
}
|
}, {
|
key: 'ping',
|
value: function ping() {
|
return this._ping();
|
}
|
}, {
|
key: 'startBatching',
|
value: function startBatching() {
|
// start collecting messages without sending them to Centrifuge until flush
|
// method called
|
this._isBatching = true;
|
}
|
}, {
|
key: 'stopBatching',
|
value: function stopBatching() {
|
this._isBatching = false;
|
this._flush();
|
}
|
}, {
|
key: 'startSubscribeBatching',
|
value: function startSubscribeBatching() {
|
// start collecting private channels to create bulk authentication
|
// request to subscribeEndpoint when stopSubscribeBatching will be called
|
this._isSubscribeBatching = true;
|
}
|
}, {
|
key: 'stopSubscribeBatching',
|
value: function stopSubscribeBatching() {
|
var _this19 = this;
|
|
// create request to subscribeEndpoint with collected private channels
|
// to ask if this client can subscribe on each channel
|
this._isSubscribeBatching = false;
|
var authChannels = this._privateChannels;
|
this._privateChannels = {};
|
|
var channels = [];
|
|
for (var channel in authChannels) {
|
if (authChannels.hasOwnProperty(channel)) {
|
var sub = this._getSub(channel);
|
if (!sub) {
|
continue;
|
}
|
channels.push(channel);
|
}
|
}
|
|
if (channels.length === 0) {
|
this._debug('no private channels found, no need to make request');
|
return;
|
}
|
|
var data = {
|
client: this._clientID,
|
channels: channels
|
};
|
|
var clientID = this._clientID;
|
var xhrID = this._newXHRID();
|
|
var cb = function cb(resp) {
|
if (xhrID in _this19._xhrs) {
|
delete _this19._xhrs[xhrID];
|
}
|
if (_this19._clientID !== clientID) {
|
return;
|
}
|
if (resp.error || resp.status !== 200) {
|
_this19._debug('authorization request failed');
|
for (var i in channels) {
|
if (channels.hasOwnProperty(i)) {
|
var _channel3 = channels[i];
|
_this19._subscribeError(_channel3, _this19._createErrorObject('authorization request failed'));
|
}
|
}
|
return;
|
}
|
|
var channelsData = {};
|
if (resp.data.channels) {
|
for (var _i in resp.data.channels) {
|
var channelData = resp.data.channels[_i];
|
if (!channelData.channel) {
|
continue;
|
}
|
channelsData[channelData.channel] = channelData.token;
|
}
|
}
|
|
// try to send all subscriptions in one request.
|
var batch = false;
|
|
if (!_this19._isBatching) {
|
_this19.startBatching();
|
batch = true;
|
}
|
|
for (var _i2 in channels) {
|
if (channels.hasOwnProperty(_i2)) {
|
var _ret2 = function () {
|
var channel = channels[_i2];
|
var token = channelsData[channel];
|
|
if (!token) {
|
// subscription:error
|
_this19._subscribeError(channel, _this19._createErrorObject('permission denied', 103));
|
return 'continue';
|
} else {
|
var msg = {
|
method: _this19._methodType.SUBSCRIBE,
|
params: {
|
channel: channel,
|
token: token
|
}
|
};
|
|
var _sub2 = _this19._getSub(channel);
|
if (_sub2 === null) {
|
return 'continue';
|
}
|
|
var recover = _sub2._needRecover();
|
|
if (recover === true) {
|
msg.params.recover = true;
|
var seq = _this19._getLastSeq(channel);
|
if (seq) {
|
msg.params.seq = seq;
|
}
|
var gen = _this19._getLastGen(channel);
|
if (gen) {
|
msg.params.gen = gen;
|
}
|
var epoch = _this19._getLastEpoch(channel);
|
if (epoch) {
|
msg.params.epoch = epoch;
|
}
|
}
|
_this19._call(msg).then(function (resolveCtx) {
|
_this19._subscribeResponse(channel, recover, _this19._decoder.decodeCommandResult(_this19._methodType.SUBSCRIBE, resolveCtx.result));
|
if (resolveCtx.next) {
|
resolveCtx.next();
|
}
|
}, function (rejectCtx) {
|
_this19._subscribeError(channel, rejectCtx.error);
|
if (rejectCtx.next) {
|
rejectCtx.next();
|
}
|
});
|
}
|
}();
|
|
if (_ret2 === 'continue') continue;
|
}
|
}
|
|
if (batch) {
|
_this19.stopBatching();
|
}
|
};
|
|
if (this._config.onPrivateSubscribe !== null) {
|
this._config.onPrivateSubscribe({
|
data: data
|
}, cb);
|
} else {
|
var xhr = this._ajax(this._config.subscribeEndpoint, this._config.subscribeParams, this._config.subscribeHeaders, data, cb);
|
this._xhrs[xhrID] = xhr;
|
}
|
}
|
}, {
|
key: 'subscribe',
|
value: function subscribe(channel, events) {
|
var currentSub = this._getSub(channel);
|
if (currentSub !== null) {
|
currentSub._setEvents(events);
|
if (currentSub._isUnsubscribed()) {
|
currentSub.subscribe();
|
}
|
return currentSub;
|
}
|
var sub = new _subscription2.default(this, channel, events);
|
this._subs[channel] = sub;
|
sub.subscribe();
|
return sub;
|
}
|
}]);
|
|
return Centrifuge;
|
}(_events2.default);
|
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3)))
|
|
/***/ }),
|
|
/***/ 11:
|
/***/ (function(module, exports, __webpack_require__) {
|
|
"use strict";
|
|
|
Object.defineProperty(exports, "__esModule", {
|
value: true
|
});
|
|
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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
var _events = __webpack_require__(6);
|
|
var _events2 = _interopRequireDefault(_events);
|
|
var _utils = __webpack_require__(7);
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
function _possibleConstructorReturn(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; }
|
|
function _inherits(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 } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
var _STATE_NEW = 0;
|
var _STATE_SUBSCRIBING = 1;
|
var _STATE_SUCCESS = 2;
|
var _STATE_ERROR = 3;
|
var _STATE_UNSUBSCRIBED = 4;
|
|
var Subscription = function (_EventEmitter) {
|
_inherits(Subscription, _EventEmitter);
|
|
function Subscription(centrifuge, channel, events) {
|
_classCallCheck(this, Subscription);
|
|
var _this = _possibleConstructorReturn(this, (Subscription.__proto__ || Object.getPrototypeOf(Subscription)).call(this));
|
|
_this.channel = channel;
|
_this._centrifuge = centrifuge;
|
_this._status = _STATE_NEW;
|
_this._error = null;
|
_this._isResubscribe = false;
|
_this._ready = false;
|
_this._subscriptionPromise = null;
|
_this._noResubscribe = false;
|
_this._recoverable = false;
|
_this._recover = false;
|
_this._setEvents(events);
|
_this._initializePromise();
|
_this._promises = {};
|
_this._promiseId = 0;
|
_this.on('error', function (errContext) {
|
this._centrifuge._debug('subscription error', errContext);
|
});
|
return _this;
|
}
|
|
_createClass(Subscription, [{
|
key: '_nextPromiseId',
|
value: function _nextPromiseId() {
|
return ++this._promiseId;
|
}
|
}, {
|
key: '_initializePromise',
|
value: function _initializePromise() {
|
var _this2 = this;
|
|
// this helps us to wait until subscription will successfully
|
// subscribe and call actions such as presence, history etc in
|
// synchronous way.
|
this._ready = false;
|
|
this._subscriptionPromise = new Promise(function (resolve, reject) {
|
_this2._resolve = function (value) {
|
_this2._ready = true;
|
resolve(value);
|
};
|
_this2._reject = function (err) {
|
_this2._ready = true;
|
reject(err);
|
};
|
}).then(function () {}, function () {});
|
}
|
}, {
|
key: '_needRecover',
|
value: function _needRecover() {
|
return this._recoverable === true && this._recover === true;
|
}
|
}, {
|
key: '_setEvents',
|
value: function _setEvents(events) {
|
if (!events) {
|
return;
|
}
|
if ((0, _utils.isFunction)(events)) {
|
// events is just a function to handle publication received from channel.
|
this.on('publish', events);
|
} else if (Object.prototype.toString.call(events) === Object.prototype.toString.call({})) {
|
var knownEvents = ['publish', 'join', 'leave', 'unsubscribe', 'subscribe', 'error'];
|
for (var i = 0, l = knownEvents.length; i < l; i++) {
|
var ev = knownEvents[i];
|
if (ev in events) {
|
this.on(ev, events[ev]);
|
}
|
}
|
}
|
}
|
}, {
|
key: '_isNew',
|
value: function _isNew() {
|
return this._status === _STATE_NEW;
|
}
|
}, {
|
key: '_isUnsubscribed',
|
value: function _isUnsubscribed() {
|
return this._status === _STATE_UNSUBSCRIBED;
|
}
|
}, {
|
key: '_isSubscribing',
|
value: function _isSubscribing() {
|
return this._status === _STATE_SUBSCRIBING;
|
}
|
}, {
|
key: '_isReady',
|
value: function _isReady() {
|
return this._status === _STATE_SUCCESS || this._status === _STATE_ERROR;
|
}
|
}, {
|
key: '_isSuccess',
|
value: function _isSuccess() {
|
return this._status === _STATE_SUCCESS;
|
}
|
}, {
|
key: '_isError',
|
value: function _isError() {
|
return this._status === _STATE_ERROR;
|
}
|
}, {
|
key: '_setNew',
|
value: function _setNew() {
|
this._status = _STATE_NEW;
|
}
|
}, {
|
key: '_setSubscribing',
|
value: function _setSubscribing(isResubscribe) {
|
this._isResubscribe = isResubscribe || false;
|
if (this._ready === true) {
|
// new promise for this subscription
|
this._initializePromise();
|
}
|
this._status = _STATE_SUBSCRIBING;
|
}
|
}, {
|
key: '_setSubscribeSuccess',
|
value: function _setSubscribeSuccess(recovered) {
|
if (this._status === _STATE_SUCCESS) {
|
return;
|
}
|
this._status = _STATE_SUCCESS;
|
var successContext = this._getSubscribeSuccessContext(recovered);
|
|
this._recover = false;
|
this.emit('subscribe', successContext);
|
this._resolve(successContext);
|
for (var id in this._promises) {
|
clearTimeout(this._promises[id].timeout);
|
this._promises[id].resolve();
|
delete this._promises[id];
|
}
|
}
|
}, {
|
key: '_setSubscribeError',
|
value: function _setSubscribeError(err) {
|
if (this._status === _STATE_ERROR) {
|
return;
|
}
|
this._status = _STATE_ERROR;
|
this._error = err;
|
var errContext = this._getSubscribeErrorContext();
|
this.emit('error', errContext);
|
this._reject(errContext);
|
for (var id in this._promises) {
|
clearTimeout(this._promises[id].timeout);
|
this._promises[id].reject(err);
|
delete this._promises[id];
|
}
|
}
|
}, {
|
key: '_triggerUnsubscribe',
|
value: function _triggerUnsubscribe() {
|
this.emit('unsubscribe', {
|
channel: this.channel
|
});
|
}
|
}, {
|
key: '_setUnsubscribed',
|
value: function _setUnsubscribed(noResubscribe) {
|
this._centrifuge._clearSubRefreshTimeout(this.channel);
|
if (this._status === _STATE_UNSUBSCRIBED) {
|
return;
|
}
|
var needTrigger = this._status === _STATE_SUCCESS;
|
this._status = _STATE_UNSUBSCRIBED;
|
if (noResubscribe === true) {
|
this._recover = false;
|
this._noResubscribe = true;
|
delete this._centrifuge._lastSeq[this.channel];
|
delete this._centrifuge._lastGen[this.channel];
|
delete this._centrifuge._lastEpoch[this.channel];
|
}
|
if (needTrigger) {
|
this._triggerUnsubscribe();
|
}
|
}
|
}, {
|
key: '_shouldResubscribe',
|
value: function _shouldResubscribe() {
|
return !this._noResubscribe;
|
}
|
}, {
|
key: '_getSubscribeSuccessContext',
|
value: function _getSubscribeSuccessContext(recovered) {
|
return {
|
channel: this.channel,
|
isResubscribe: this._isResubscribe,
|
recovered: recovered
|
};
|
}
|
}, {
|
key: '_getSubscribeErrorContext',
|
value: function _getSubscribeErrorContext() {
|
var subscribeErrorContext = this._error;
|
subscribeErrorContext.channel = this.channel;
|
subscribeErrorContext.isResubscribe = this._isResubscribe;
|
return subscribeErrorContext;
|
}
|
}, {
|
key: 'ready',
|
value: function ready(callback, errback) {
|
if (this._ready) {
|
if (this._isSuccess()) {
|
callback(this._getSubscribeSuccessContext());
|
} else {
|
errback(this._getSubscribeErrorContext());
|
}
|
}
|
}
|
}, {
|
key: 'subscribe',
|
value: function subscribe() {
|
if (this._status === _STATE_SUCCESS) {
|
return;
|
}
|
this._noResubscribe = false;
|
this._centrifuge._subscribe(this);
|
}
|
}, {
|
key: 'unsubscribe',
|
value: function unsubscribe() {
|
this._setUnsubscribed(true);
|
this._centrifuge._unsubscribe(this);
|
}
|
}, {
|
key: '_methodCall',
|
value: function _methodCall(message, type) {
|
var _this3 = this;
|
|
var methodCallPromise = new Promise(function (resolve, reject) {
|
var subPromise = void 0;
|
if (_this3._isSuccess()) {
|
subPromise = Promise.resolve();
|
} else if (_this3._isError()) {
|
subPromise = Promise.reject(_this3._error);
|
} else {
|
subPromise = new Promise(function (res, rej) {
|
var timeout = setTimeout(function () {
|
rej({ 'code': 0, 'message': 'timeout' });
|
}, _this3._centrifuge._config.timeout);
|
_this3._promises[_this3._nextPromiseId()] = {
|
timeout: timeout,
|
resolve: res,
|
reject: rej
|
};
|
});
|
}
|
subPromise.then(function () {
|
return _this3._centrifuge._call(message).then(function (resolveCtx) {
|
resolve(_this3._centrifuge._decoder.decodeCommandResult(type, resolveCtx.result));
|
if (resolveCtx.next) {
|
resolveCtx.next();
|
}
|
}, function (rejectCtx) {
|
reject(rejectCtx.error);
|
if (rejectCtx.next) {
|
rejectCtx.next();
|
}
|
});
|
}, function (error) {
|
reject(error);
|
});
|
});
|
return methodCallPromise;
|
}
|
}, {
|
key: 'publish',
|
value: function publish(data) {
|
return this._methodCall({
|
method: this._centrifuge._methodType.PUBLISH,
|
params: {
|
channel: this.channel,
|
data: data
|
}
|
}, this._centrifuge._methodType.PUBLISH);
|
}
|
}, {
|
key: 'presence',
|
value: function presence() {
|
return this._methodCall({
|
method: this._centrifuge._methodType.PRESENCE,
|
params: {
|
channel: this.channel
|
}
|
}, this._centrifuge._methodType.PRESENCE);
|
}
|
}, {
|
key: 'presenceStats',
|
value: function presenceStats() {
|
return this._methodCall({
|
method: this._centrifuge._methodType.PRESENCE_STATS,
|
params: {
|
channel: this.channel
|
}
|
}, this._centrifuge._methodType.PRESENCE_STATS);
|
}
|
}, {
|
key: 'history',
|
value: function history() {
|
return this._methodCall({
|
method: this._centrifuge._methodType.HISTORY,
|
params: {
|
channel: this.channel
|
}
|
}, this._centrifuge._methodType.HISTORY);
|
}
|
}]);
|
|
return Subscription;
|
}(_events2.default);
|
|
exports.default = Subscription;
|
module.exports = exports['default'];
|
|
/***/ }),
|
|
/***/ 12:
|
/***/ (function(module, exports, __webpack_require__) {
|
|
"use strict";
|
|
|
Object.defineProperty(exports, "__esModule", {
|
value: true
|
});
|
|
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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
var JsonMethodType = exports.JsonMethodType = {
|
CONNECT: 0,
|
SUBSCRIBE: 1,
|
UNSUBSCRIBE: 2,
|
PUBLISH: 3,
|
PRESENCE: 4,
|
PRESENCE_STATS: 5,
|
HISTORY: 6,
|
PING: 7,
|
SEND: 8,
|
RPC: 9,
|
REFRESH: 10,
|
SUB_REFRESH: 11
|
};
|
|
var JsonPushType = exports.JsonPushType = {
|
PUBLICATION: 0,
|
JOIN: 1,
|
LEAVE: 2,
|
UNSUB: 3,
|
MESSAGE: 4,
|
SUB: 5
|
};
|
|
var JsonEncoder = exports.JsonEncoder = function () {
|
function JsonEncoder() {
|
_classCallCheck(this, JsonEncoder);
|
}
|
|
_createClass(JsonEncoder, [{
|
key: 'encodeCommands',
|
value: function encodeCommands(commands) {
|
var encodedCommands = [];
|
for (var i in commands) {
|
if (commands.hasOwnProperty(i)) {
|
encodedCommands.push(JSON.stringify(commands[i]));
|
}
|
}
|
return encodedCommands.join('\n');
|
}
|
}]);
|
|
return JsonEncoder;
|
}();
|
|
var JsonDecoder = exports.JsonDecoder = function () {
|
function JsonDecoder() {
|
_classCallCheck(this, JsonDecoder);
|
}
|
|
_createClass(JsonDecoder, [{
|
key: 'decodeReplies',
|
value: function decodeReplies(data) {
|
var replies = [];
|
var encodedReplies = data.split('\n');
|
for (var i in encodedReplies) {
|
if (encodedReplies.hasOwnProperty(i)) {
|
if (!encodedReplies[i]) {
|
continue;
|
}
|
var reply = JSON.parse(encodedReplies[i]);
|
replies.push(reply);
|
}
|
}
|
return replies;
|
}
|
}, {
|
key: 'decodeCommandResult',
|
value: function decodeCommandResult(methodType, data) {
|
return data;
|
}
|
}, {
|
key: 'decodePush',
|
value: function decodePush(data) {
|
return data;
|
}
|
}, {
|
key: 'decodePushData',
|
value: function decodePushData(pushType, data) {
|
return data;
|
}
|
}]);
|
|
return JsonDecoder;
|
}();
|
|
/***/ }),
|
|
/***/ 3:
|
/***/ (function(module, exports) {
|
|
var g;
|
|
// This works in non-strict mode
|
g = (function() {
|
return this;
|
})();
|
|
try {
|
// This works if eval is allowed (see CSP)
|
g = g || Function("return this")() || (1,eval)("this");
|
} catch(e) {
|
// This works if the window reference is available
|
if(typeof window === "object")
|
g = window;
|
}
|
|
// g can still be undefined, but nothing to do about it...
|
// We return undefined, instead of nothing here, so it's
|
// easier to handle this case. if(!global) { ...}
|
|
module.exports = g;
|
|
|
/***/ }),
|
|
/***/ 31:
|
/***/ (function(module, exports, __webpack_require__) {
|
|
"use strict";
|
|
|
Object.defineProperty(exports, "__esModule", {
|
value: true
|
});
|
|
var _centrifuge = __webpack_require__(10);
|
|
exports.default = _centrifuge.Centrifuge;
|
module.exports = exports['default'];
|
|
/***/ }),
|
|
/***/ 6:
|
/***/ (function(module, exports, __webpack_require__) {
|
|
"use strict";
|
// Copyright Joyent, Inc. and other Node contributors.
|
//
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
// copy of this software and associated documentation files (the
|
// "Software"), to deal in the Software without restriction, including
|
// without limitation the rights to use, copy, modify, merge, publish,
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
// persons to whom the Software is furnished to do so, subject to the
|
// following conditions:
|
//
|
// The above copyright notice and this permission notice shall be included
|
// in all copies or substantial portions of the Software.
|
//
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
var R = typeof Reflect === 'object' ? Reflect : null
|
var ReflectApply = R && typeof R.apply === 'function'
|
? R.apply
|
: function ReflectApply(target, receiver, args) {
|
return Function.prototype.apply.call(target, receiver, args);
|
}
|
|
var ReflectOwnKeys
|
if (R && typeof R.ownKeys === 'function') {
|
ReflectOwnKeys = R.ownKeys
|
} else if (Object.getOwnPropertySymbols) {
|
ReflectOwnKeys = function ReflectOwnKeys(target) {
|
return Object.getOwnPropertyNames(target)
|
.concat(Object.getOwnPropertySymbols(target));
|
};
|
} else {
|
ReflectOwnKeys = function ReflectOwnKeys(target) {
|
return Object.getOwnPropertyNames(target);
|
};
|
}
|
|
function ProcessEmitWarning(warning) {
|
if (console && console.warn) console.warn(warning);
|
}
|
|
var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
|
return value !== value;
|
}
|
|
function EventEmitter() {
|
EventEmitter.init.call(this);
|
}
|
module.exports = EventEmitter;
|
|
// Backwards-compat with node 0.10.x
|
EventEmitter.EventEmitter = EventEmitter;
|
|
EventEmitter.prototype._events = undefined;
|
EventEmitter.prototype._eventsCount = 0;
|
EventEmitter.prototype._maxListeners = undefined;
|
|
// By default EventEmitters will print a warning if more than 10 listeners are
|
// added to it. This is a useful default which helps finding memory leaks.
|
var defaultMaxListeners = 10;
|
|
Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
|
enumerable: true,
|
get: function() {
|
return defaultMaxListeners;
|
},
|
set: function(arg) {
|
if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
|
throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
|
}
|
defaultMaxListeners = arg;
|
}
|
});
|
|
EventEmitter.init = function() {
|
|
if (this._events === undefined ||
|
this._events === Object.getPrototypeOf(this)._events) {
|
this._events = Object.create(null);
|
this._eventsCount = 0;
|
}
|
|
this._maxListeners = this._maxListeners || undefined;
|
};
|
|
// Obviously not all Emitters should be limited to 10. This function allows
|
// that to be increased. Set to zero for unlimited.
|
EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
|
if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
|
throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
|
}
|
this._maxListeners = n;
|
return this;
|
};
|
|
function $getMaxListeners(that) {
|
if (that._maxListeners === undefined)
|
return EventEmitter.defaultMaxListeners;
|
return that._maxListeners;
|
}
|
|
EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
|
return $getMaxListeners(this);
|
};
|
|
EventEmitter.prototype.emit = function emit(type) {
|
var args = [];
|
for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
|
var doError = (type === 'error');
|
|
var events = this._events;
|
if (events !== undefined)
|
doError = (doError && events.error === undefined);
|
else if (!doError)
|
return false;
|
|
// If there is no 'error' event listener then throw.
|
if (doError) {
|
var er;
|
if (args.length > 0)
|
er = args[0];
|
if (er instanceof Error) {
|
// Note: The comments on the `throw` lines are intentional, they show
|
// up in Node's output if this results in an unhandled exception.
|
throw er; // Unhandled 'error' event
|
}
|
// At least give some kind of context to the user
|
var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
|
err.context = er;
|
throw err; // Unhandled 'error' event
|
}
|
|
var handler = events[type];
|
|
if (handler === undefined)
|
return false;
|
|
if (typeof handler === 'function') {
|
ReflectApply(handler, this, args);
|
} else {
|
var len = handler.length;
|
var listeners = arrayClone(handler, len);
|
for (var i = 0; i < len; ++i)
|
ReflectApply(listeners[i], this, args);
|
}
|
|
return true;
|
};
|
|
function _addListener(target, type, listener, prepend) {
|
var m;
|
var events;
|
var existing;
|
|
if (typeof listener !== 'function') {
|
throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
|
}
|
|
events = target._events;
|
if (events === undefined) {
|
events = target._events = Object.create(null);
|
target._eventsCount = 0;
|
} else {
|
// To avoid recursion in the case that type === "newListener"! Before
|
// adding it to the listeners, first emit "newListener".
|
if (events.newListener !== undefined) {
|
target.emit('newListener', type,
|
listener.listener ? listener.listener : listener);
|
|
// Re-assign `events` because a newListener handler could have caused the
|
// this._events to be assigned to a new object
|
events = target._events;
|
}
|
existing = events[type];
|
}
|
|
if (existing === undefined) {
|
// Optimize the case of one listener. Don't need the extra array object.
|
existing = events[type] = listener;
|
++target._eventsCount;
|
} else {
|
if (typeof existing === 'function') {
|
// Adding the second element, need to change to array.
|
existing = events[type] =
|
prepend ? [listener, existing] : [existing, listener];
|
// If we've already got an array, just append.
|
} else if (prepend) {
|
existing.unshift(listener);
|
} else {
|
existing.push(listener);
|
}
|
|
// Check for listener leak
|
m = $getMaxListeners(target);
|
if (m > 0 && existing.length > m && !existing.warned) {
|
existing.warned = true;
|
// No error code for this since it is a Warning
|
// eslint-disable-next-line no-restricted-syntax
|
var w = new Error('Possible EventEmitter memory leak detected. ' +
|
existing.length + ' ' + String(type) + ' listeners ' +
|
'added. Use emitter.setMaxListeners() to ' +
|
'increase limit');
|
w.name = 'MaxListenersExceededWarning';
|
w.emitter = target;
|
w.type = type;
|
w.count = existing.length;
|
ProcessEmitWarning(w);
|
}
|
}
|
|
return target;
|
}
|
|
EventEmitter.prototype.addListener = function addListener(type, listener) {
|
return _addListener(this, type, listener, false);
|
};
|
|
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
|
|
EventEmitter.prototype.prependListener =
|
function prependListener(type, listener) {
|
return _addListener(this, type, listener, true);
|
};
|
|
function onceWrapper() {
|
var args = [];
|
for (var i = 0; i < arguments.length; i++) args.push(arguments[i]);
|
if (!this.fired) {
|
this.target.removeListener(this.type, this.wrapFn);
|
this.fired = true;
|
ReflectApply(this.listener, this.target, args);
|
}
|
}
|
|
function _onceWrap(target, type, listener) {
|
var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
|
var wrapped = onceWrapper.bind(state);
|
wrapped.listener = listener;
|
state.wrapFn = wrapped;
|
return wrapped;
|
}
|
|
EventEmitter.prototype.once = function once(type, listener) {
|
if (typeof listener !== 'function') {
|
throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
|
}
|
this.on(type, _onceWrap(this, type, listener));
|
return this;
|
};
|
|
EventEmitter.prototype.prependOnceListener =
|
function prependOnceListener(type, listener) {
|
if (typeof listener !== 'function') {
|
throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
|
}
|
this.prependListener(type, _onceWrap(this, type, listener));
|
return this;
|
};
|
|
// Emits a 'removeListener' event if and only if the listener was removed.
|
EventEmitter.prototype.removeListener =
|
function removeListener(type, listener) {
|
var list, events, position, i, originalListener;
|
|
if (typeof listener !== 'function') {
|
throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
|
}
|
|
events = this._events;
|
if (events === undefined)
|
return this;
|
|
list = events[type];
|
if (list === undefined)
|
return this;
|
|
if (list === listener || list.listener === listener) {
|
if (--this._eventsCount === 0)
|
this._events = Object.create(null);
|
else {
|
delete events[type];
|
if (events.removeListener)
|
this.emit('removeListener', type, list.listener || listener);
|
}
|
} else if (typeof list !== 'function') {
|
position = -1;
|
|
for (i = list.length - 1; i >= 0; i--) {
|
if (list[i] === listener || list[i].listener === listener) {
|
originalListener = list[i].listener;
|
position = i;
|
break;
|
}
|
}
|
|
if (position < 0)
|
return this;
|
|
if (position === 0)
|
list.shift();
|
else {
|
spliceOne(list, position);
|
}
|
|
if (list.length === 1)
|
events[type] = list[0];
|
|
if (events.removeListener !== undefined)
|
this.emit('removeListener', type, originalListener || listener);
|
}
|
|
return this;
|
};
|
|
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
|
|
EventEmitter.prototype.removeAllListeners =
|
function removeAllListeners(type) {
|
var listeners, events, i;
|
|
events = this._events;
|
if (events === undefined)
|
return this;
|
|
// not listening for removeListener, no need to emit
|
if (events.removeListener === undefined) {
|
if (arguments.length === 0) {
|
this._events = Object.create(null);
|
this._eventsCount = 0;
|
} else if (events[type] !== undefined) {
|
if (--this._eventsCount === 0)
|
this._events = Object.create(null);
|
else
|
delete events[type];
|
}
|
return this;
|
}
|
|
// emit removeListener for all listeners on all events
|
if (arguments.length === 0) {
|
var keys = Object.keys(events);
|
var key;
|
for (i = 0; i < keys.length; ++i) {
|
key = keys[i];
|
if (key === 'removeListener') continue;
|
this.removeAllListeners(key);
|
}
|
this.removeAllListeners('removeListener');
|
this._events = Object.create(null);
|
this._eventsCount = 0;
|
return this;
|
}
|
|
listeners = events[type];
|
|
if (typeof listeners === 'function') {
|
this.removeListener(type, listeners);
|
} else if (listeners !== undefined) {
|
// LIFO order
|
for (i = listeners.length - 1; i >= 0; i--) {
|
this.removeListener(type, listeners[i]);
|
}
|
}
|
|
return this;
|
};
|
|
function _listeners(target, type, unwrap) {
|
var events = target._events;
|
|
if (events === undefined)
|
return [];
|
|
var evlistener = events[type];
|
if (evlistener === undefined)
|
return [];
|
|
if (typeof evlistener === 'function')
|
return unwrap ? [evlistener.listener || evlistener] : [evlistener];
|
|
return unwrap ?
|
unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
|
}
|
|
EventEmitter.prototype.listeners = function listeners(type) {
|
return _listeners(this, type, true);
|
};
|
|
EventEmitter.prototype.rawListeners = function rawListeners(type) {
|
return _listeners(this, type, false);
|
};
|
|
EventEmitter.listenerCount = function(emitter, type) {
|
if (typeof emitter.listenerCount === 'function') {
|
return emitter.listenerCount(type);
|
} else {
|
return listenerCount.call(emitter, type);
|
}
|
};
|
|
EventEmitter.prototype.listenerCount = listenerCount;
|
function listenerCount(type) {
|
var events = this._events;
|
|
if (events !== undefined) {
|
var evlistener = events[type];
|
|
if (typeof evlistener === 'function') {
|
return 1;
|
} else if (evlistener !== undefined) {
|
return evlistener.length;
|
}
|
}
|
|
return 0;
|
}
|
|
EventEmitter.prototype.eventNames = function eventNames() {
|
return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
|
};
|
|
function arrayClone(arr, n) {
|
var copy = new Array(n);
|
for (var i = 0; i < n; ++i)
|
copy[i] = arr[i];
|
return copy;
|
}
|
|
function spliceOne(list, index) {
|
for (; index + 1 < list.length; index++)
|
list[index] = list[index + 1];
|
list.pop();
|
}
|
|
function unwrapListeners(arr) {
|
var ret = new Array(arr.length);
|
for (var i = 0; i < ret.length; ++i) {
|
ret[i] = arr[i].listener || arr[i];
|
}
|
return ret;
|
}
|
|
|
/***/ }),
|
|
/***/ 7:
|
/***/ (function(module, exports, __webpack_require__) {
|
|
"use strict";
|
/* WEBPACK VAR INJECTION */(function(global) {
|
|
Object.defineProperty(exports, "__esModule", {
|
value: true
|
});
|
exports.startsWith = startsWith;
|
exports.isFunction = isFunction;
|
exports.log = log;
|
exports.backoff = backoff;
|
exports.errorExists = errorExists;
|
exports.extend = extend;
|
function startsWith(value, prefix) {
|
return value.lastIndexOf(prefix, 0) === 0;
|
};
|
|
function isFunction(value) {
|
if (value === undefined || value === null) {
|
return false;
|
}
|
return typeof value === 'function';
|
};
|
|
function log(level, args) {
|
if (global.console) {
|
var logger = global.console[level];
|
|
if (isFunction(logger)) {
|
logger.apply(global.console, args);
|
}
|
}
|
};
|
|
function backoff(step, min, max) {
|
var jitter = 0.5 * Math.random();
|
var interval = Math.min(max, min * Math.pow(2, step + 1));
|
|
return Math.floor((1 - jitter) * interval);
|
};
|
|
function errorExists(data) {
|
return 'error' in data && data.error !== null;
|
};
|
|
function extend(a, b) {
|
for (var key in b) {
|
if (b.hasOwnProperty(key)) {
|
a[key] = b[key];
|
}
|
}
|
return a;
|
};
|
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3)))
|
|
/***/ })
|
|
/******/ });
|
});
|
//# sourceMappingURL=centrifuge.js.map
|