@httptoolkit/subscriptions-transport-ws
Version:
A websocket transport for GraphQL subscriptions
1,495 lines (1,391 loc) • 81.1 kB
JavaScript
var SubscriptionsTransportWs =
/******/ (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 = 2);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (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;
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, '__esModule', {
value: true,
});
exports.Kind = void 0;
/**
* The set of allowed kind values for AST nodes.
*/
let Kind;
/**
* The enum type representing the possible kind values of AST nodes.
*
* @deprecated Please use `Kind`. Will be remove in v17.
*/
exports.Kind = Kind;
(function (Kind) {
Kind['NAME'] = 'Name';
Kind['DOCUMENT'] = 'Document';
Kind['OPERATION_DEFINITION'] = 'OperationDefinition';
Kind['VARIABLE_DEFINITION'] = 'VariableDefinition';
Kind['SELECTION_SET'] = 'SelectionSet';
Kind['FIELD'] = 'Field';
Kind['ARGUMENT'] = 'Argument';
Kind['FRAGMENT_SPREAD'] = 'FragmentSpread';
Kind['INLINE_FRAGMENT'] = 'InlineFragment';
Kind['FRAGMENT_DEFINITION'] = 'FragmentDefinition';
Kind['VARIABLE'] = 'Variable';
Kind['INT'] = 'IntValue';
Kind['FLOAT'] = 'FloatValue';
Kind['STRING'] = 'StringValue';
Kind['BOOLEAN'] = 'BooleanValue';
Kind['NULL'] = 'NullValue';
Kind['ENUM'] = 'EnumValue';
Kind['LIST'] = 'ListValue';
Kind['OBJECT'] = 'ObjectValue';
Kind['OBJECT_FIELD'] = 'ObjectField';
Kind['DIRECTIVE'] = 'Directive';
Kind['NAMED_TYPE'] = 'NamedType';
Kind['LIST_TYPE'] = 'ListType';
Kind['NON_NULL_TYPE'] = 'NonNullType';
Kind['SCHEMA_DEFINITION'] = 'SchemaDefinition';
Kind['OPERATION_TYPE_DEFINITION'] = 'OperationTypeDefinition';
Kind['SCALAR_TYPE_DEFINITION'] = 'ScalarTypeDefinition';
Kind['OBJECT_TYPE_DEFINITION'] = 'ObjectTypeDefinition';
Kind['FIELD_DEFINITION'] = 'FieldDefinition';
Kind['INPUT_VALUE_DEFINITION'] = 'InputValueDefinition';
Kind['INTERFACE_TYPE_DEFINITION'] = 'InterfaceTypeDefinition';
Kind['UNION_TYPE_DEFINITION'] = 'UnionTypeDefinition';
Kind['ENUM_TYPE_DEFINITION'] = 'EnumTypeDefinition';
Kind['ENUM_VALUE_DEFINITION'] = 'EnumValueDefinition';
Kind['INPUT_OBJECT_TYPE_DEFINITION'] = 'InputObjectTypeDefinition';
Kind['DIRECTIVE_DEFINITION'] = 'DirectiveDefinition';
Kind['SCHEMA_EXTENSION'] = 'SchemaExtension';
Kind['SCALAR_TYPE_EXTENSION'] = 'ScalarTypeExtension';
Kind['OBJECT_TYPE_EXTENSION'] = 'ObjectTypeExtension';
Kind['INTERFACE_TYPE_EXTENSION'] = 'InterfaceTypeExtension';
Kind['UNION_TYPE_EXTENSION'] = 'UnionTypeExtension';
Kind['ENUM_TYPE_EXTENSION'] = 'EnumTypeExtension';
Kind['INPUT_OBJECT_TYPE_EXTENSION'] = 'InputObjectTypeExtension';
})(Kind || (exports.Kind = Kind = {}));
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* WEBPACK VAR INJECTION */(function(global) {
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SubscriptionClient = void 0;
var _global = typeof global !== 'undefined' ? global : (typeof window !== 'undefined' ? window : {});
var NativeWebSocket = _global.WebSocket || _global.MozWebSocket;
var Backoff = __webpack_require__(3);
var eventemitter3_1 = __webpack_require__(4);
var is_string_1 = __webpack_require__(5);
var is_object_1 = __webpack_require__(6);
var printer_1 = __webpack_require__(7);
var getOperationAST_1 = __webpack_require__(14);
var symbol_observable_1 = __webpack_require__(15);
var protocol_1 = __webpack_require__(18);
var defaults_1 = __webpack_require__(19);
var message_types_1 = __webpack_require__(20);
var SubscriptionClient = (function () {
function SubscriptionClient(url, options, webSocketImpl, webSocketProtocols) {
var _a = (options || {}), _b = _a.connectionCallback, connectionCallback = _b === void 0 ? undefined : _b, _c = _a.connectionParams, connectionParams = _c === void 0 ? {} : _c, _d = _a.minTimeout, minTimeout = _d === void 0 ? defaults_1.MIN_WS_TIMEOUT : _d, _e = _a.timeout, timeout = _e === void 0 ? defaults_1.WS_TIMEOUT : _e, _f = _a.reconnect, reconnect = _f === void 0 ? false : _f, _g = _a.reconnectionAttempts, reconnectionAttempts = _g === void 0 ? Infinity : _g, _h = _a.lazy, lazy = _h === void 0 ? false : _h, _j = _a.inactivityTimeout, inactivityTimeout = _j === void 0 ? 0 : _j, _k = _a.wsOptionArguments, wsOptionArguments = _k === void 0 ? [] : _k;
this.wsImpl = webSocketImpl || NativeWebSocket;
if (!this.wsImpl) {
throw new Error('Unable to find native implementation, or alternative implementation for WebSocket!');
}
this.wsProtocols = webSocketProtocols || protocol_1.GRAPHQL_WS;
this.connectionCallback = connectionCallback;
this.url = url;
this.operations = {};
this.nextOperationId = 0;
this.minWsTimeout = minTimeout;
this.wsTimeout = timeout;
this.unsentMessagesQueue = [];
this.reconnect = reconnect;
this.reconnecting = false;
this.reconnectionAttempts = reconnectionAttempts;
this.lazy = !!lazy;
this.inactivityTimeout = inactivityTimeout;
this.closedByUser = false;
this.backoff = new Backoff({ jitter: 0.5 });
this.eventEmitter = new eventemitter3_1.EventEmitter();
this.middlewares = [];
this.client = null;
this.maxConnectTimeGenerator = this.createMaxConnectTimeGenerator();
this.connectionParams = this.getConnectionParams(connectionParams);
this.wsOptionArguments = wsOptionArguments;
if (!this.lazy) {
this.connect();
}
}
Object.defineProperty(SubscriptionClient.prototype, "status", {
get: function () {
if (this.client === null) {
return this.wsImpl.CLOSED;
}
return this.client.readyState;
},
enumerable: false,
configurable: true
});
SubscriptionClient.prototype.close = function (isForced, closedByUser) {
if (isForced === void 0) { isForced = true; }
if (closedByUser === void 0) { closedByUser = true; }
this.clearInactivityTimeout();
if (this.client !== null) {
this.closedByUser = closedByUser;
if (isForced) {
this.clearCheckConnectionInterval();
this.clearMaxConnectTimeout();
this.clearTryReconnectTimeout();
this.unsubscribeAll();
this.sendMessage(undefined, message_types_1.default.GQL_CONNECTION_TERMINATE, null);
}
this.client.close();
this.client.onopen = null;
this.client.onclose = null;
this.client.onmessage = null;
this.client.onerror = function () { };
this.client = null;
this.eventEmitter.emit('disconnected');
if (!isForced) {
this.tryReconnect();
}
}
};
SubscriptionClient.prototype.request = function (request) {
var _a;
var getObserver = this.getObserver.bind(this);
var executeOperation = this.executeOperation.bind(this);
var unsubscribe = this.unsubscribe.bind(this);
var opId;
this.clearInactivityTimeout();
return _a = {},
_a[symbol_observable_1.default] = function () {
return this;
},
_a.subscribe = function (observerOrNext, onError, onComplete) {
var observer = getObserver(observerOrNext, onError, onComplete);
opId = executeOperation(request, function (error, result) {
if (error === null && result === null) {
if (observer.complete) {
observer.complete();
}
}
else if (error) {
if (observer.error) {
observer.error(error[0]);
}
}
else {
if (observer.next) {
observer.next(result);
}
}
});
return {
unsubscribe: function () {
if (opId) {
unsubscribe(opId);
opId = null;
}
},
};
},
_a;
};
SubscriptionClient.prototype.on = function (eventName, callback, context) {
var handler = this.eventEmitter.on(eventName, callback, context);
return function () {
handler.off(eventName, callback, context);
};
};
SubscriptionClient.prototype.onConnected = function (callback, context) {
return this.on('connected', callback, context);
};
SubscriptionClient.prototype.onConnecting = function (callback, context) {
return this.on('connecting', callback, context);
};
SubscriptionClient.prototype.onDisconnected = function (callback, context) {
return this.on('disconnected', callback, context);
};
SubscriptionClient.prototype.onReconnected = function (callback, context) {
return this.on('reconnected', callback, context);
};
SubscriptionClient.prototype.onReconnecting = function (callback, context) {
return this.on('reconnecting', callback, context);
};
SubscriptionClient.prototype.onError = function (callback, context) {
return this.on('error', callback, context);
};
SubscriptionClient.prototype.unsubscribeAll = function () {
var _this = this;
Object.keys(this.operations).forEach(function (subId) {
_this.unsubscribe(subId);
});
};
SubscriptionClient.prototype.applyMiddlewares = function (options) {
var _this = this;
return new Promise(function (resolve, reject) {
var queue = function (funcs, scope) {
var next = function (error) {
if (error) {
reject(error);
}
else {
if (funcs.length > 0) {
var f = funcs.shift();
if (f) {
f.applyMiddleware.apply(scope, [options, next]);
}
}
else {
resolve(options);
}
}
};
next();
};
queue(__spreadArray([], _this.middlewares, true), _this);
});
};
SubscriptionClient.prototype.use = function (middlewares) {
var _this = this;
middlewares.map(function (middleware) {
if (typeof middleware.applyMiddleware === 'function') {
_this.middlewares.push(middleware);
}
else {
throw new Error('Middleware must implement the applyMiddleware function.');
}
});
return this;
};
SubscriptionClient.prototype.getConnectionParams = function (connectionParams) {
return function () { return new Promise(function (resolve, reject) {
if (typeof connectionParams === 'function') {
try {
return resolve(connectionParams.call(null));
}
catch (error) {
return reject(error);
}
}
resolve(connectionParams);
}); };
};
SubscriptionClient.prototype.executeOperation = function (options, handler) {
var _this = this;
if (this.client === null) {
this.connect();
}
var opId = this.generateOperationId();
this.operations[opId] = { options: options, handler: handler };
this.applyMiddlewares(options)
.then(function (processedOptions) {
_this.checkOperationOptions(processedOptions, handler);
if (_this.operations[opId]) {
_this.operations[opId] = { options: processedOptions, handler: handler };
_this.sendMessage(opId, message_types_1.default.GQL_START, processedOptions);
}
})
.catch(function (error) {
_this.unsubscribe(opId);
handler(_this.formatErrors(error));
});
return opId;
};
SubscriptionClient.prototype.getObserver = function (observerOrNext, error, complete) {
if (typeof observerOrNext === 'function') {
return {
next: function (v) { return observerOrNext(v); },
error: function (e) { return error && error(e); },
complete: function () { return complete && complete(); },
};
}
return observerOrNext;
};
SubscriptionClient.prototype.createMaxConnectTimeGenerator = function () {
var minValue = this.minWsTimeout;
var maxValue = this.wsTimeout;
return new Backoff({
min: minValue,
max: maxValue,
factor: 1.2,
});
};
SubscriptionClient.prototype.clearCheckConnectionInterval = function () {
if (this.checkConnectionIntervalId) {
clearInterval(this.checkConnectionIntervalId);
this.checkConnectionIntervalId = null;
}
};
SubscriptionClient.prototype.clearMaxConnectTimeout = function () {
if (this.maxConnectTimeoutId) {
clearTimeout(this.maxConnectTimeoutId);
this.maxConnectTimeoutId = null;
}
};
SubscriptionClient.prototype.clearTryReconnectTimeout = function () {
if (this.tryReconnectTimeoutId) {
clearTimeout(this.tryReconnectTimeoutId);
this.tryReconnectTimeoutId = null;
}
};
SubscriptionClient.prototype.clearInactivityTimeout = function () {
if (this.inactivityTimeoutId) {
clearTimeout(this.inactivityTimeoutId);
this.inactivityTimeoutId = null;
}
};
SubscriptionClient.prototype.setInactivityTimeout = function () {
var _this = this;
if (this.inactivityTimeout > 0 && Object.keys(this.operations).length === 0) {
this.inactivityTimeoutId = setTimeout(function () {
if (Object.keys(_this.operations).length === 0) {
_this.close();
}
}, this.inactivityTimeout);
}
};
SubscriptionClient.prototype.checkOperationOptions = function (options, handler) {
var query = options.query, variables = options.variables, operationName = options.operationName;
if (!query) {
throw new Error('Must provide a query.');
}
if (!handler) {
throw new Error('Must provide an handler.');
}
if ((!(0, is_string_1.default)(query) && !(0, getOperationAST_1.getOperationAST)(query, operationName)) ||
(operationName && !(0, is_string_1.default)(operationName)) ||
(variables && !(0, is_object_1.default)(variables))) {
throw new Error('Incorrect option types. query must be a string or a document,' +
'`operationName` must be a string, and `variables` must be an object.');
}
};
SubscriptionClient.prototype.buildMessage = function (id, type, payload) {
var payloadToReturn = payload && payload.query ? __assign(__assign({}, payload), { query: typeof payload.query === 'string' ? payload.query : (0, printer_1.print)(payload.query) }) :
payload;
return {
id: id,
type: type,
payload: payloadToReturn,
};
};
SubscriptionClient.prototype.formatErrors = function (errors) {
if (Array.isArray(errors)) {
return errors;
}
if (errors && errors.errors) {
return this.formatErrors(errors.errors);
}
if (errors && errors.message) {
return [errors];
}
return [{
name: 'FormatedError',
message: 'Unknown error',
originalError: errors,
}];
};
SubscriptionClient.prototype.sendMessage = function (id, type, payload) {
this.sendMessageRaw(this.buildMessage(id, type, payload));
};
SubscriptionClient.prototype.sendMessageRaw = function (message) {
switch (this.status) {
case this.wsImpl.OPEN:
var serializedMessage = JSON.stringify(message);
try {
JSON.parse(serializedMessage);
}
catch (e) {
this.eventEmitter.emit('error', new Error("Message must be JSON-serializable. Got: ".concat(message)));
}
this.client.send(serializedMessage);
break;
case this.wsImpl.CONNECTING:
this.unsentMessagesQueue.push(message);
break;
default:
if (!this.reconnecting) {
this.eventEmitter.emit('error', new Error('A message was not sent because socket is not connected, is closing or ' +
'is already closed. Message was: ' + JSON.stringify(message)));
}
}
};
SubscriptionClient.prototype.generateOperationId = function () {
return String(++this.nextOperationId);
};
SubscriptionClient.prototype.tryReconnect = function () {
var _this = this;
if (!this.reconnect || this.backoff.attempts >= this.reconnectionAttempts) {
return;
}
if (!this.reconnecting) {
Object.keys(this.operations).forEach(function (key) {
_this.unsentMessagesQueue.push(_this.buildMessage(key, message_types_1.default.GQL_START, _this.operations[key].options));
});
this.reconnecting = true;
}
this.clearTryReconnectTimeout();
var delay = this.backoff.duration();
this.tryReconnectTimeoutId = setTimeout(function () {
_this.connect();
}, delay);
};
SubscriptionClient.prototype.flushUnsentMessagesQueue = function () {
var _this = this;
this.unsentMessagesQueue.forEach(function (message) {
_this.sendMessageRaw(message);
});
this.unsentMessagesQueue = [];
};
SubscriptionClient.prototype.checkConnection = function () {
if (this.wasKeepAliveReceived) {
this.wasKeepAliveReceived = false;
return;
}
if (!this.reconnecting) {
this.close(false, true);
}
};
SubscriptionClient.prototype.checkMaxConnectTimeout = function () {
var _this = this;
this.clearMaxConnectTimeout();
this.maxConnectTimeoutId = setTimeout(function () {
if (_this.status !== _this.wsImpl.OPEN) {
_this.reconnecting = true;
_this.close(false, true);
}
}, this.maxConnectTimeGenerator.duration());
};
SubscriptionClient.prototype.connect = function () {
var _a;
var _this = this;
this.client = new ((_a = this.wsImpl).bind.apply(_a, __spreadArray([void 0, this.url, this.wsProtocols], this.wsOptionArguments, false)))();
this.checkMaxConnectTimeout();
this.client.onopen = function () { return __awaiter(_this, void 0, void 0, function () {
var connectionParams, error_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!(this.status === this.wsImpl.OPEN)) return [3, 4];
this.clearMaxConnectTimeout();
this.closedByUser = false;
this.eventEmitter.emit(this.reconnecting ? 'reconnecting' : 'connecting');
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4, this.connectionParams()];
case 2:
connectionParams = _a.sent();
this.sendMessage(undefined, message_types_1.default.GQL_CONNECTION_INIT, connectionParams);
this.flushUnsentMessagesQueue();
return [3, 4];
case 3:
error_1 = _a.sent();
this.sendMessage(undefined, message_types_1.default.GQL_CONNECTION_ERROR, error_1);
this.flushUnsentMessagesQueue();
return [3, 4];
case 4: return [2];
}
});
}); };
this.client.onclose = function () {
if (!_this.closedByUser) {
_this.close(false, false);
}
};
this.client.onerror = function (err) {
_this.eventEmitter.emit('error', err);
};
this.client.onmessage = function (_a) {
var data = _a.data;
_this.processReceivedData(data.toString());
};
};
SubscriptionClient.prototype.processReceivedData = function (receivedData) {
var parsedMessage;
var opId;
try {
parsedMessage = JSON.parse(receivedData);
opId = parsedMessage.id;
}
catch (e) {
throw new Error("Message must be JSON-parseable. Got: ".concat(receivedData));
}
if ([message_types_1.default.GQL_DATA,
message_types_1.default.GQL_COMPLETE,
message_types_1.default.GQL_ERROR,
].indexOf(parsedMessage.type) !== -1 && !this.operations[opId]) {
this.unsubscribe(opId);
return;
}
switch (parsedMessage.type) {
case message_types_1.default.GQL_CONNECTION_ERROR:
if (this.connectionCallback) {
this.connectionCallback(parsedMessage.payload);
}
break;
case message_types_1.default.GQL_CONNECTION_ACK:
this.eventEmitter.emit(this.reconnecting ? 'reconnected' : 'connected', parsedMessage.payload);
this.reconnecting = false;
this.backoff.reset();
this.maxConnectTimeGenerator.reset();
if (this.connectionCallback) {
this.connectionCallback();
}
break;
case message_types_1.default.GQL_COMPLETE:
var handler = this.operations[opId].handler;
delete this.operations[opId];
handler.call(this, null, null);
break;
case message_types_1.default.GQL_ERROR:
this.operations[opId].handler(this.formatErrors(parsedMessage.payload), null);
delete this.operations[opId];
break;
case message_types_1.default.GQL_DATA:
var parsedPayload = !parsedMessage.payload.errors ?
parsedMessage.payload : __assign(__assign({}, parsedMessage.payload), { errors: this.formatErrors(parsedMessage.payload.errors) });
this.operations[opId].handler(null, parsedPayload);
break;
case message_types_1.default.GQL_CONNECTION_KEEP_ALIVE:
var firstKA = typeof this.wasKeepAliveReceived === 'undefined';
this.wasKeepAliveReceived = true;
if (firstKA) {
this.checkConnection();
}
if (this.checkConnectionIntervalId) {
clearInterval(this.checkConnectionIntervalId);
this.checkConnection();
}
this.checkConnectionIntervalId = setInterval(this.checkConnection.bind(this), this.wsTimeout);
break;
default:
throw new Error('Invalid message type!');
}
};
SubscriptionClient.prototype.unsubscribe = function (opId) {
if (this.operations[opId]) {
delete this.operations[opId];
this.setInactivityTimeout();
this.sendMessage(opId, message_types_1.default.GQL_STOP, undefined);
}
};
return SubscriptionClient;
}());
exports.SubscriptionClient = SubscriptionClient;
//# sourceMappingURL=client.js.map
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))
/***/ }),
/* 3 */
/***/ (function(module, exports) {
/**
* Expose `Backoff`.
*/
module.exports = Backoff;
/**
* Initialize backoff timer with `opts`.
*
* - `min` initial timeout in milliseconds [100]
* - `max` max timeout [10000]
* - `jitter` [0]
* - `factor` [2]
*
* @param {Object} opts
* @api public
*/
function Backoff(opts) {
opts = opts || {};
this.ms = opts.min || 100;
this.max = opts.max || 10000;
this.factor = opts.factor || 2;
this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0;
this.attempts = 0;
}
/**
* Return the backoff duration.
*
* @return {Number}
* @api public
*/
Backoff.prototype.duration = function(){
var ms = this.ms * Math.pow(this.factor, this.attempts++);
if (this.jitter) {
var rand = Math.random();
var deviation = Math.floor(rand * this.jitter * ms);
ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation;
}
return Math.min(ms, this.max) | 0;
};
/**
* Reset the number of attempts.
*
* @api public
*/
Backoff.prototype.reset = function(){
this.attempts = 0;
};
/**
* Set the minimum duration
*
* @api public
*/
Backoff.prototype.setMin = function(min){
this.ms = min;
};
/**
* Set the maximum duration
*
* @api public
*/
Backoff.prototype.setMax = function(max){
this.max = max;
};
/**
* Set the jitter
*
* @api public
*/
Backoff.prototype.setJitter = function(jitter){
this.jitter = jitter;
};
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var has = Object.prototype.hasOwnProperty
, prefix = '~';
/**
* Constructor to create a storage for our `EE` objects.
* An `Events` instance is a plain object whose properties are event names.
*
* @constructor
* @private
*/
function Events() {}
//
// We try to not inherit from `Object.prototype`. In some engines creating an
// instance in this way is faster than calling `Object.create(null)` directly.
// If `Object.create(null)` is not supported we prefix the event names with a
// character to make sure that the built-in object properties are not
// overridden or used as an attack vector.
//
if (Object.create) {
Events.prototype = Object.create(null);
//
// This hack is needed because the `__proto__` property is still inherited in
// some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
//
if (!new Events().__proto__) prefix = false;
}
/**
* Representation of a single event listener.
*
* @param {Function} fn The listener function.
* @param {*} context The context to invoke the listener with.
* @param {Boolean} [once=false] Specify if the listener is a one-time listener.
* @constructor
* @private
*/
function EE(fn, context, once) {
this.fn = fn;
this.context = context;
this.once = once || false;
}
/**
* Add a listener for a given event.
*
* @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
* @param {(String|Symbol)} event The event name.
* @param {Function} fn The listener function.
* @param {*} context The context to invoke the listener with.
* @param {Boolean} once Specify if the listener is a one-time listener.
* @returns {EventEmitter}
* @private
*/
function addListener(emitter, event, fn, context, once) {
if (typeof fn !== 'function') {
throw new TypeError('The listener must be a function');
}
var listener = new EE(fn, context || emitter, once)
, evt = prefix ? prefix + event : event;
if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
else emitter._events[evt] = [emitter._events[evt], listener];
return emitter;
}
/**
* Clear event by name.
*
* @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
* @param {(String|Symbol)} evt The Event name.
* @private
*/
function clearEvent(emitter, evt) {
if (--emitter._eventsCount === 0) emitter._events = new Events();
else delete emitter._events[evt];
}
/**
* Minimal `EventEmitter` interface that is molded against the Node.js
* `EventEmitter` interface.
*
* @constructor
* @public
*/
function EventEmitter() {
this._events = new Events();
this._eventsCount = 0;
}
/**
* Return an array listing the events for which the emitter has registered
* listeners.
*
* @returns {Array}
* @public
*/
EventEmitter.prototype.eventNames = function eventNames() {
var names = []
, events
, name;
if (this._eventsCount === 0) return names;
for (name in (events = this._events)) {
if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
}
if (Object.getOwnPropertySymbols) {
return names.concat(Object.getOwnPropertySymbols(events));
}
return names;
};
/**
* Return the listeners registered for a given event.
*
* @param {(String|Symbol)} event The event name.
* @returns {Array} The registered listeners.
* @public
*/
EventEmitter.prototype.listeners = function listeners(event) {
var evt = prefix ? prefix + event : event
, handlers = this._events[evt];
if (!handlers) return [];
if (handlers.fn) return [handlers.fn];
for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
ee[i] = handlers[i].fn;
}
return ee;
};
/**
* Return the number of listeners listening to a given event.
*
* @param {(String|Symbol)} event The event name.
* @returns {Number} The number of listeners.
* @public
*/
EventEmitter.prototype.listenerCount = function listenerCount(event) {
var evt = prefix ? prefix + event : event
, listeners = this._events[evt];
if (!listeners) return 0;
if (listeners.fn) return 1;
return listeners.length;
};
/**
* Calls each of the listeners registered for a given event.
*
* @param {(String|Symbol)} event The event name.
* @returns {Boolean} `true` if the event had listeners, else `false`.
* @public
*/
EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
var evt = prefix ? prefix + event : event;
if (!this._events[evt]) return false;
var listeners = this._events[evt]
, len = arguments.length
, args
, i;
if (listeners.fn) {
if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
switch (len) {
case 1: return listeners.fn.call(listeners.context), true;
case 2: return listeners.fn.call(listeners.context, a1), true;
case 3: return listeners.fn.call(listeners.context, a1, a2), true;
case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
}
for (i = 1, args = new Array(len -1); i < len; i++) {
args[i - 1] = arguments[i];
}
listeners.fn.apply(listeners.context, args);
} else {
var length = listeners.length
, j;
for (i = 0; i < length; i++) {
if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
switch (len) {
case 1: listeners[i].fn.call(listeners[i].context); break;
case 2: listeners[i].fn.call(listeners[i].context, a1); break;
case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
default:
if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
args[j - 1] = arguments[j];
}
listeners[i].fn.apply(listeners[i].context, args);
}
}
}
return true;
};
/**
* Add a listener for a given event.
*
* @param {(String|Symbol)} event The event name.
* @param {Function} fn The listener function.
* @param {*} [context=this] The context to invoke the listener with.
* @returns {EventEmitter} `this`.
* @public
*/
EventEmitter.prototype.on = function on(event, fn, context) {
return addListener(this, event, fn, context, false);
};
/**
* Add a one-time listener for a given event.
*
* @param {(String|Symbol)} event The event name.
* @param {Function} fn The listener function.
* @param {*} [context=this] The context to invoke the listener with.
* @returns {EventEmitter} `this`.
* @public
*/
EventEmitter.prototype.once = function once(event, fn, context) {
return addListener(this, event, fn, context, true);
};
/**
* Remove the listeners of a given event.
*
* @param {(String|Symbol)} event The event name.
* @param {Function} fn Only remove the listeners that match this function.
* @param {*} context Only remove the listeners that have this context.
* @param {Boolean} once Only remove one-time listeners.
* @returns {EventEmitter} `this`.
* @public
*/
EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
var evt = prefix ? prefix + event : event;
if (!this._events[evt]) return this;
if (!fn) {
clearEvent(this, evt);
return this;
}
var listeners = this._events[evt];
if (listeners.fn) {
if (
listeners.fn === fn &&
(!once || listeners.once) &&
(!context || listeners.context === context)
) {
clearEvent(this, evt);
}
} else {
for (var i = 0, events = [], length = listeners.length; i < length; i++) {
if (
listeners[i].fn !== fn ||
(once && !listeners[i].once) ||
(context && listeners[i].context !== context)
) {
events.push(listeners[i]);
}
}
//
// Reset the array, or remove it completely if we have no more listeners.
//
if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
else clearEvent(this, evt);
}
return this;
};
/**
* Remove all listeners, or those of the specified event.
*
* @param {(String|Symbol)} [event] The event name.
* @returns {EventEmitter} `this`.
* @public
*/
EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
var evt;
if (event) {
evt = prefix ? prefix + event : event;
if (this._events[evt]) clearEvent(this, evt);
} else {
this._events = new Events();
this._eventsCount = 0;
}
return this;
};
//
// Alias methods names because people roll like that.
//
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
EventEmitter.prototype.addListener = EventEmitter.prototype.on;
//
// Expose the prefix.
//
EventEmitter.prefixed = prefix;
//
// Allow `EventEmitter` to be imported as module namespace.
//
EventEmitter.EventEmitter = EventEmitter;
//
// Expose the module.
//
if (true) {
module.exports = EventEmitter;
}
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function isString(value) {
return typeof value === 'string';
}
exports.default = isString;
//# sourceMappingURL=is-string.js.map
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function isObject(value) {
return ((value !== null) && (typeof value === 'object'));
}
exports.default = isObject;
//# sourceMappingURL=is-object.js.map
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, '__esModule', {
value: true,
});
exports.print = print;
var _visitor = __webpack_require__(8);
var _blockString = __webpack_require__(12);
var _printString = __webpack_require__(13);
/**
* Converts an AST into a string, using one set of reasonable
* formatting rules.
*/
function print(ast) {
return (0, _visitor.visit)(ast, printDocASTReducer);
}
const MAX_LINE_LENGTH = 80;
const printDocASTReducer = {
Name: {
leave: (node) => node.value,
},
Variable: {
leave: (node) => '$' + node.name,
},
// Document
Document: {
leave: (node) => join(node.definitions, '\n\n'),
},
OperationDefinition: {
leave(node) {
const varDefs = wrap('(', join(node.variableDefinitions, ', '), ')');
const prefix = join(
[
node.operation,
join([node.name, varDefs]),
join(node.directives, ' '),
],
' ',
); // Anonymous queries with no directives or variable definitions can use
// the query short form.
return (prefix === 'query' ? '' : prefix + ' ') + node.selectionSet;
},
},
VariableDefinition: {
leave: ({ variable, type, defaultValue, directives }) =>
variable +
': ' +
type +
wrap(' = ', defaultValue) +
wrap(' ', join(directives, ' ')),
},
SelectionSet: {
leave: ({ selections }) => block(selections),
},
Field: {
leave({ alias, name, arguments: args, directives, selectionSet }) {
const prefix = wrap('', alias, ': ') + name;
let argsLine = prefix + wrap('(', join(args, ', '), ')');
if (argsLine.length > MAX_LINE_LENGTH) {
argsLine = prefix + wrap('(\n', indent(join(args, '\n')), '\n)');
}
return join([argsLine, join(directives, ' '), selectionSet], ' ');
},
},
Argument: {
leave: ({ name, value }) => name + ': ' + value,
},
// Fragments
FragmentSpread: {
leave: ({ name, directives }) =>
'...' + name + wrap(' ', join(directives, ' ')),
},
InlineFragment: {
leave: ({ typeCondition, directives, selectionSet }) =>
join(
[
'...',
wrap('on ', typeCondition),
join(directives, ' '),
selectionSet,
],
' ',
),
},
FragmentDefinition: {
leave: (
{ name, typeCondition, variableDefinitions, directives, selectionSet }, // Note: fragment variable definitions are experimental and may be changed
) =>
// or removed in the future.
`fragment ${name}${wrap('(', join(variableDefinitions, ', '), ')')} ` +
`on ${typeCondition} ${wrap('', join(directives, ' '), ' ')}` +
selectionSet,
},
// Value
IntValue: {
leave: ({ value }) => value,
},
FloatValue: {
leave: ({ value }) => value,
},
StringValue: {
leave: ({ value, block: isBlockString }) =>
isBlockString
? (0, _blockString.printBlockString)(value)
: (0, _printString.printString)(value),
},
BooleanValue: {
leave: ({ value }) => (value ? 'true' : 'false'),
},
NullValue: {
leave: () => 'null',
},
EnumValue: {
leave: ({ value }) => value,
},
ListValue: {
leave: ({ values }) => '[' + join(values, ', ') + ']',
},
ObjectValue: {
leave: ({ fields }) => '{' + join(fields, ', ') + '}',
},
ObjectField: {
leave: ({ name, value }) => name + ': ' + value,
},
// Directive
Directive: {
leave: ({ name, arguments: args }) =>
'@' + name + wrap('(', join(args, ', '), ')'),
},
// Type
NamedType: {
leave: ({ name }) => name,
},
ListType: {
leave: ({ type }) => '[' + type + ']',
},
NonNullType: {
leave: ({ type }) => type + '!',
},
// Type System Definitions
SchemaDefinition: {
leave: ({ description, directives, operationTypes }) =>
wrap('', description, '\n') +
join(['schema', join(directives, ' '), block(operationTypes)], ' '),
},
OperationTypeDefinition: {
leave: ({ operation, type }) => operation + ': ' + type,
},
ScalarTypeDefinition: {
leave: ({ description, name, directives }) =>
wrap('', description, '\n') +
join(['scalar', name, join(directives, ' ')], ' '),
},
ObjectTypeDefinition: {
leave: ({ description, name, interfaces, directives, fields }) =>
wrap('', description, '\n') +
join(
[
'type',
name,
wrap('implements ', join(interfaces, ' & ')),
join(directives, ' '),
block(fields),
],
' ',
),
},
FieldDefinition: {
leave: ({ description, name, arguments: args, type, directives }) =>
wrap('', description, '\n') +
name +
(hasMultilineItems(args)
? wrap('(\n', indent(join(args, '\n')), '\n)')
: wrap('(', join(args, ', '), ')')) +
': ' +
type +
wrap(' ', join(directives, ' ')),
},
InputValueDefinition: {
leave: ({ description, name, type, defaultValue, directives }) =>
wrap('', description, '\n') +
join(
[name + ': ' + type, wrap('= ', defaultValue), join(directives, ' ')],
' ',
),
},
InterfaceTypeDefinition: {
leave: ({ description, name, interfaces, directives, fields }) =>
wrap('', description, '\n') +
join(
[
'interface',
name,
wrap('implements ', join(interfaces, ' & ')),
join(directives, ' '),
block(fields),
],
' ',
),
},
UnionTypeDefinition: {
leave: ({ description, name, directives, types }) =>
wrap('', description, '\n') +
join(
['union', name, join(directives, ' '), wrap('= ', join(types, ' | '))],
' ',
),
},
EnumTypeDefinition: {
leave: ({ description, name, directives, values }) =>
wrap('', description, '\n') +
join(['enum', name, join(directives, ' '), block(values)], ' '),
},
EnumValueDefinition: {
leave: ({ description, name, directives }) =>
wrap('', description, '\n') + join([name, join(directives, ' ')], ' '),
},
InputObjectTypeDefinition: {
leave: ({ description, name, directives, fields }) =>
wrap('', description, '\n') +
join(['input', name, join(directives, ' '), block(fields)], ' '),
},
DirectiveDefinition: {
leave: ({ description, name, arguments: args, repeatable, locations }) =>
wrap('', description, '\n') +
'directive @' +
name +
(hasMultilineItems(args)
? wrap('(\n', indent(join(args, '\n')), '\n)')
: wrap('(', join(args, ', '), ')')) +
(repeatable ? ' repeatable' : '') +
' on ' +
join(locations, ' | '),
},
SchemaExtension: {
leave: ({ directives, operationTypes }) =>
join(
['extend schema', join(directives, ' '), block(operationTypes)],
' ',
),
},
ScalarTypeExtension: {
leave: ({ name, directives }) =>
join(['extend scalar', name, join(directives, ' ')], ' '),
},
ObjectTypeExtension: {
leave: ({ name, interfaces, directives, fields }) =>
join(
[
'extend type',
name,
wrap('implements ', join(interfaces, ' & ')),
join(directives, ' '),
block(fields),
],
' ',
),
},
InterfaceTypeExtension: {
leave: ({ name, interfaces, directives, fields }) =>
join(
[
'extend interface',
name,
wrap('implements ', join(interfaces, ' & ')),
join(directives, ' '),
block(fields),
],
' ',
),
},
UnionTypeExtension: {
leave: ({ name, directives, types }) =>
join(
[
'extend union',
name,
join(directives, ' '),
wrap('= ', join(types, ' | ')),
],
' ',
),
},
EnumTypeExtension: {
leave: ({ name, directives, values }) =>
join(['extend enum', name, join(directives, ' '), block(values)], ' '),
},
InputObjectTypeExtension: {
leave: ({ name, directiv