subscriptions-transport-ws
Version:
A websocket transport for GraphQL subscriptions
1,443 lines (1,334 loc) • 71.3 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 = 1);
/******/ })
/************************************************************************/
/******/ ([
/* 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";
/* WEBPACK VAR INJECTION */(function(global) {
var __assign = (this && this.__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;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
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) : new P(function (resolve) { resolve(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 };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
var _global = typeof global !== 'undefined' ? global : (typeof window !== 'undefined' ? window : {});
var NativeWebSocket = _global.WebSocket || _global.MozWebSocket;
var Backoff = __webpack_require__(2);
var eventemitter3_1 = __webpack_require__(3);
var is_string_1 = __webpack_require__(4);
var is_object_1 = __webpack_require__(5);
var printer_1 = __webpack_require__(6);
var getOperationAST_1 = __webpack_require__(9);
var symbol_observable_1 = __webpack_require__(11);
var protocol_1 = __webpack_require__(14);
var defaults_1 = __webpack_require__(15);
var message_types_1 = __webpack_require__(16);
var SubscriptionClient = (function () {
function SubscriptionClient(url, options, webSocketImpl) {
var _a = (options || {}), _b = _a.connectionCallback, connectionCallback = _b === void 0 ? undefined : _b, _c = _a.connectionParams, connectionParams = _c === void 0 ? {} : _c, _d = _a.timeout, timeout = _d === void 0 ? defaults_1.WS_TIMEOUT : _d, _e = _a.reconnect, reconnect = _e === void 0 ? false : _e, _f = _a.reconnectionAttempts, reconnectionAttempts = _f === void 0 ? Infinity : _f, _g = _a.lazy, lazy = _g === void 0 ? false : _g, _h = _a.inactivityTimeout, inactivityTimeout = _h === void 0 ? 0 : _h;
this.wsImpl = webSocketImpl || NativeWebSocket;
if (!this.wsImpl) {
throw new Error('Unable to find native implementation, or alternative implementation for WebSocket!');
}
this.connectionCallback = connectionCallback;
this.url = url;
this.operations = {};
this.nextOperationId = 0;
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);
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: true,
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 = 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(_this.middlewares.slice(), _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 = 1000;
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 ((!is_string_1.default(query) && !getOperationAST_1.getOperationAST(query, operationName)) ||
(operationName && !is_string_1.default(operationName)) ||
(variables && !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({}, payload, { query: typeof payload.query === 'string' ? payload.query : 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: " + 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 _this = this;
this.client = new this.wsImpl(this.url, protocol_1.GRAPHQL_WS);
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);
};
};
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: " + 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');
this.reconnecting = false;
this.backoff.reset();
this.maxConnectTimeGenerator.reset();
if (this.connectionCallback) {
this.connectionCallback();
}
break;
case message_types_1.default.GQL_COMPLETE:
this.operations[opId].handler(null, null);
delete this.operations[opId];
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({}, 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)))
/***/ }),
/* 2 */
/***/ (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;
};
/***/ }),
/* 3 */
/***/ (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;
}
/***/ }),
/* 4 */
/***/ (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
/***/ }),
/* 5 */
/***/ (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
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.print = print;
var _visitor = __webpack_require__(7);
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* Converts an AST into a string, using one set of reasonable
* formatting rules.
*/
function print(ast) {
return (0, _visitor.visit)(ast, {
leave: printDocASTReducer
});
}
var printDocASTReducer = {
Name: function Name(node) {
return node.value;
},
Variable: function Variable(node) {
return '$' + node.name;
},
// Document
Document: function Document(node) {
return join(node.definitions, '\n\n') + '\n';
},
OperationDefinition: function OperationDefinition(node) {
var op = node.operation;
var name = node.name;
var varDefs = wrap('(', join(node.variableDefinitions, ', '), ')');
var directives = join(node.directives, ' ');
var selectionSet = node.selectionSet; // Anonymous queries with no directives or variable definitions can use
// the query short form.
return !name && !directives && !varDefs && op === 'query' ? selectionSet : join([op, join([name, varDefs]), directives, selectionSet], ' ');
},
VariableDefinition: function VariableDefinition(_ref) {
var variable = _ref.variable,
type = _ref.type,
defaultValue = _ref.defaultValue,
directives = _ref.directives;
return variable + ': ' + type + wrap(' = ', defaultValue) + wrap(' ', join(directives, ' '));
},
SelectionSet: function SelectionSet(_ref2) {
var selections = _ref2.selections;
return block(selections);
},
Field: function Field(_ref3) {
var alias = _ref3.alias,
name = _ref3.name,
args = _ref3.arguments,
directives = _ref3.directives,
selectionSet = _ref3.selectionSet;
return join([wrap('', alias, ': ') + name + wrap('(', join(args, ', '), ')'), join(directives, ' '), selectionSet], ' ');
},
Argument: function Argument(_ref4) {
var name = _ref4.name,
value = _ref4.value;
return name + ': ' + value;
},
// Fragments
FragmentSpread: function FragmentSpread(_ref5) {
var name = _ref5.name,
directives = _ref5.directives;
return '...' + name + wrap(' ', join(directives, ' '));
},
InlineFragment: function InlineFragment(_ref6) {
var typeCondition = _ref6.typeCondition,
directives = _ref6.directives,
selectionSet = _ref6.selectionSet;
return join(['...', wrap('on ', typeCondition), join(directives, ' '), selectionSet], ' ');
},
FragmentDefinition: function FragmentDefinition(_ref7) {
var name = _ref7.name,
typeCondition = _ref7.typeCondition,
variableDefinitions = _ref7.variableDefinitions,
directives = _ref7.directives,
selectionSet = _ref7.selectionSet;
return (// Note: fragment variable definitions are experimental and may be changed
// or removed in the future.
"fragment ".concat(name).concat(wrap('(', join(variableDefinitions, ', '), ')'), " ") + "on ".concat(typeCondition, " ").concat(wrap('', join(directives, ' '), ' ')) + selectionSet
);
},
// Value
IntValue: function IntValue(_ref8) {
var value = _ref8.value;
return value;
},
FloatValue: function FloatValue(_ref9) {
var value = _ref9.value;
return value;
},
StringValue: function StringValue(_ref10, key) {
var value = _ref10.value,
isBlockString = _ref10.block;
return isBlockString ? printBlockString(value, key === 'description') : JSON.stringify(value);
},
BooleanValue: function BooleanValue(_ref11) {
var value = _ref11.value;
return value ? 'true' : 'false';
},
NullValue: function NullValue() {
return 'null';
},
EnumValue: function EnumValue(_ref12) {
var value = _ref12.value;
return value;
},
ListValue: function ListValue(_ref13) {
var values = _ref13.values;
return '[' + join(values, ', ') + ']';
},
ObjectValue: function ObjectValue(_ref14) {
var fields = _ref14.fields;
return '{' + join(fields, ', ') + '}';
},
ObjectField: function ObjectField(_ref15) {
var name = _ref15.name,
value = _ref15.value;
return name + ': ' + value;
},
// Directive
Directive: function Directive(_ref16) {
var name = _ref16.name,
args = _ref16.arguments;
return '@' + name + wrap('(', join(args, ', '), ')');
},
// Type
NamedType: function NamedType(_ref17) {
var name = _ref17.name;
return name;
},
ListType: function ListType(_ref18) {
var type = _ref18.type;
return '[' + type + ']';
},
NonNullType: function NonNullType(_ref19) {
var type = _ref19.type;
return type + '!';
},
// Type System Definitions
SchemaDefinition: function SchemaDefinition(_ref20) {
var directives = _ref20.directives,
operationTypes = _ref20.operationTypes;
return join(['schema', join(directives, ' '), block(operationTypes)], ' ');
},
OperationTypeDefinition: function OperationTypeDefinition(_ref21) {
var operation = _ref21.operation,
type = _ref21.type;
return operation + ': ' + type;
},
ScalarTypeDefinition: addDescription(function (_ref22) {
var name = _ref22.name,
directives = _ref22.directives;
return join(['scalar', name, join(directives, ' ')], ' ');
}),
ObjectTypeDefinition: addDescription(function (_ref23) {
var name = _ref23.name,
interfaces = _ref23.interfaces,
directives = _ref23.directives,
fields = _ref23.fields;
return join(['type', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' ');
}),
FieldDefinition: addDescription(function (_ref24) {
var name = _ref24.name,
args = _ref24.arguments,
type = _ref24.type,
directives = _ref24.directives;
return name + (args.every(function (arg) {
return arg.indexOf('\n') === -1;
}) ? wrap('(', join(args, ', '), ')') : wrap('(\n', indent(join(args, '\n')), '\n)')) + ': ' + type + wrap(' ', join(directives, ' '));
}),
InputValueDefinition: addDescription(function (_ref25) {
var name = _ref25.name,
type = _ref25.type,
defaultValue = _ref25.defaultValue,
directives = _ref25.directives;
return join([name + ': ' + type, wrap('= ', defaultValue), join(directives, ' ')], ' ');
}),
InterfaceTypeDefinition: addDescription(function (_ref26) {
var name = _ref26.name,
directives = _ref26.directives,
fields = _ref26.fields;
return join(['interface', name, join(directives, ' '), block(fields)], ' ');
}),
UnionTypeDefinition: addDescription(function (_ref27) {
var name = _ref27.name,
directives = _ref27.directives,
types = _ref27.types;
return join(['union', name, join(directives, ' '), types && types.length !== 0 ? '= ' + join(types, ' | ') : ''], ' ');
}),
EnumTypeDefinition: addDescription(function (_ref28) {
var name = _ref28.name,
directives = _ref28.directives,
values = _ref28.values;
return join(['enum', name, join(directives, ' '), block(values)], ' ');
}),
EnumValueDefinition: addDescription(function (_ref29) {
var name = _ref29.name,
directives = _ref29.directives;
return join([name, join(directives, ' ')], ' ');
}),
InputObjectTypeDefinition: addDescription(function (_ref30) {
var name = _ref30.name,
directives = _ref30.directives,
fields = _ref30.fields;
return join(['input', name, join(directives, ' '), block(fields)], ' ');
}),
DirectiveDefinition: addDescription(function (_ref31) {
var name = _ref31.name,
args = _ref31.arguments,
locations = _ref31.locations;
return 'directive @' + name + (args.every(function (arg) {
return arg.indexOf('\n') === -1;
}) ? wrap('(', join(args, ', '), ')') : wrap('(\n', indent(join(args, '\n')), '\n)')) + ' on ' + join(locations, ' | ');
}),
SchemaExtension: function SchemaExtension(_ref32) {
var directives = _ref32.directives,
operationTypes = _ref32.operationTypes;
return join(['extend schema', join(directives, ' '), block(operationTypes)], ' ');
},
ScalarTypeExtension: function ScalarTypeExtension(_ref33) {
var name = _ref33.name,
directives = _ref33.directives;
return join(['extend scalar', name, join(directives, ' ')], ' ');
},
ObjectTypeExtension: function ObjectTypeExtension(_ref34) {
var name = _ref34.name,
interfaces = _ref34.interfaces,
directives = _ref34.directives,
fields = _ref34.fields;
return join(['extend type', name, wrap('implements ', join(interfaces, ' & ')), join(directives, ' '), block(fields)], ' ');
},
InterfaceTypeExtension: function InterfaceTypeExtension(_ref35) {
var name = _ref35.name,
directives = _ref35.directives,
fields = _ref35.fields;
return join(['extend interface', name, join(directives, ' '), block(fields)], ' ');
},
UnionTypeExtension: function UnionTypeExtension(_ref36) {
var name = _ref36.name,
directives = _ref36.directives,
types = _ref36.types;
return join(['extend union', name, join(directives, ' '), types && types.length !== 0 ? '= ' + join(types, ' | ') : ''], ' ');
},
EnumTypeExtension: function EnumTypeExtension(_ref37) {
var name = _ref37.name,
directives = _ref37.directives,
values = _ref37.values;
return join(['extend enum', name, join(directives, ' '), block(values)], ' ');
},
InputObjectTypeExtension: function InputObjectTypeExtension(_ref38) {
var name = _ref38.name,
directives = _ref38.directives,
fields = _ref38.fields;
return join(['extend input', name, join(directives, ' '), block(fields)], ' ');
}
};
function addDescription(cb) {
return function (node) {
return join([node.description, cb(node)], '\n');
};
}
/**
* Given maybeArray, print an empty string if it is null or empty, otherwise
* print all items together separated by separator if provided
*/
function join(maybeArray, separator) {
return maybeArray ? maybeArray.filter(function (x) {
return x;
}).join(separator || '') : '';
}
/**
* Given array, print each item on its own line, wrapped in an
* indented "{ }" block.
*/
function block(array) {
return array && array.length !== 0 ? '{\n' + indent(join(array, '\n')) + '\n}' : '';
}
/**
* If maybeString is not null or empty, then wrap with start and end, otherwise
* print an empty string.
*/
function wrap(start, maybeString, end) {
return maybeString ? start + maybeString + (end || '') : '';
}
function indent(maybeString) {
return maybeString && ' ' + maybeString.replace(/\n/g, '\n ');
}
/**
* Print a block string in the indented block form by adding a leading and
* trailing blank line. However, if a block string starts with whitespace and is
* a single-line, adding a leading blank line would strip that whitespace.
*/
function printBlockString(value, isDescription) {
var escaped = value.replace(/"""/g, '\\"""');
return (value[0] === ' ' || value[0] === '\t') && value.indexOf('\n') === -1 ? "\"\"\"".concat(escaped.replace(/"$/, '"\n'), "\"\"\"") : "\"\"\"\n".concat(isDescription ? escaped : indent(escaped), "\n\"\"\"");
}
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.visit = visit;
exports.visitInParallel = visitInParallel;
exports.visitWithTypeInfo = visitWithTypeInfo;
exports.getVisitFn = getVisitFn;
exports.BREAK = exports.QueryDocumentKeys = void 0;
var _inspect = _interopRequireDefault(__webpack_require__(8));
function _interopRequireDefault(obj)