Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

apollo-client-ws

Package Overview
Dependencies
Maintainers
1
Versions
54
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

apollo-client-ws - npm Package Compare versions

Comparing version 2.2.1 to 2.3.0

22

Gruntfile.js

@@ -47,7 +47,9 @@ /*

[ "babelify", {
presets: [ "es2015", "es2016", "es2017" ],
plugins: [ [ "transform-runtime", {
"polyfill": true,
"regenerator": false
} ] ]
presets: [
[ "@babel/preset-env", {
"targets": {
"browsers": "last 2 versions, not dead"
}
} ]
]
} ],

@@ -74,3 +76,11 @@ "browserify-shim",

[ "envify", { PLATFORM: "node" } ],
[ "babelify", { presets: [ "es2015", "es2016", "es2017" ] } ]
[ "babelify", {
presets: [
[ "@babel/preset-env", {
"targets": {
"node": "6.0"
}
} ]
]
} ]
],

@@ -77,0 +87,0 @@ plugin: [

@@ -28,532 +28,471 @@ /*

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 _apolloLink = _dereq_("apollo-link");
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 _ws = _interopRequireDefault(_dereq_("ws"));
var _apolloLink = _dereq_("apollo-link");
var _websocketFramed = _interopRequireDefault(_dereq_("websocket-framed"));
var _ws = _dereq_("ws");
var _printer = _dereq_("graphql/language/printer");
var _ws2 = _interopRequireDefault(_ws);
var _graphqlQueryCompress = _interopRequireDefault(_dereq_("graphql-query-compress"));
var _websocketFramed = _dereq_("websocket-framed");
var _latching = _interopRequireDefault(_dereq_("latching"));
var _websocketFramed2 = _interopRequireDefault(_websocketFramed);
var _eventemitter = _interopRequireDefault(_dereq_("eventemitter3"));
var _printer = _dereq_("graphql/language/printer");
var _ducky = _interopRequireDefault(_dereq_("ducky"));
var _graphqlQueryCompress = _dereq_("graphql-query-compress");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _graphqlQueryCompress2 = _interopRequireDefault(_graphqlQueryCompress);
/*
** Apollo-Client-WS -- GraphQL WebSocket Network Link for Apollo Client
** Copyright (c) 2017-2018 Ralf S. Engelschall <rse@engelschall.com>
**
** 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 _latching5 = _dereq_("latching");
/* external dependencies */
var _latching6 = _interopRequireDefault(_latching5);
/* Apollo Client Link Interface for WebSocket Communication */
class ApolloClientWS extends _apolloLink.ApolloLink {
constructor(...args) {
/* initialize ApolloLink base class */
super();
/* sanity check constructor arguments */
var _eventemitter = _dereq_("eventemitter3");
if (args.length === 2 && typeof args[0] === "string" && typeof args[1] === "object") this._args = {
uri: args[0],
opts: args[1]
};else if (args.length === 1 && typeof args[0] === "object") this._args = args[0];else throw new Error("invalid arguments to ApolloClientWS constructor (invalid number or type of arguments)");
if (this._args.uri === undefined) throw new Error("invalid arguments to ApolloClientWS constructor (missing URI)");
/* provide default values for options */
var _eventemitter2 = _interopRequireDefault(_eventemitter);
this._args.opts = Object.assign({
debug: 0,
protocols: [],
compress: false,
encoding: "json",
keepalive: 0,
reconnectattempts: -1,
reconnectdelay: 2 * 1000
}, this._args.opts);
/* validate options */
var _ducky = _dereq_("ducky");
let errors = [];
if (!_ducky.default.validate(this._args.opts, `{
debug: number,
protocols: [ string* ],
compress: boolean,
encoding: string,
keepalive: number,
reconnectattempts: number,
reconnectdelay: number
}`, errors)) throw new Error(`invalid options: ${errors.join("; ")}`);
/* initialize state variables */
var _ducky2 = _interopRequireDefault(_ducky);
this._ws = null;
this._wsf = null;
this._to = null;
this._tx = {};
/* provide hook latching sub-system */
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
this._latching = new _latching.default();
/* provide event emitter sub-system */
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
this._emitter = new _eventemitter.default();
}
/* ADDON: pass-through methods of latching sub-system */
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; } /*
** Apollo-Client-WS -- GraphQL WebSocket Network Link for Apollo Client
** Copyright (c) 2017-2018 Ralf S. Engelschall <rse@engelschall.com>
**
** 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.
*/
hook(...args) {
return this._latching.hook(...args);
}
/* external dependencies */
at(...args) {
return this._latching.at(...args);
}
latch(...args) {
return this._latching.latch(...args);
}
/* Apollo Client Link Interface for WebSocket Communication */
var ApolloClientWS = function (_ApolloLink) {
_inherits(ApolloClientWS, _ApolloLink);
unlatch(...args) {
return this._latching.unlatch(...args);
}
/* ADDON: pass-through methods of emitter sub-system */
function ApolloClientWS() {
_classCallCheck(this, ApolloClientWS);
/* sanity check constructor arguments */
var _this = _possibleConstructorReturn(this, (ApolloClientWS.__proto__ || Object.getPrototypeOf(ApolloClientWS)).call(this));
/* initialize ApolloLink base class */
emit(...args) {
return this._emitter.emit(...args);
}
once(...args) {
return this._emitter.once(...args);
}
if (arguments.length === 2 && typeof (arguments.length <= 0 ? undefined : arguments[0]) === "string" && _typeof(arguments.length <= 1 ? undefined : arguments[1]) === "object") _this._args = { uri: arguments.length <= 0 ? undefined : arguments[0], opts: arguments.length <= 1 ? undefined : arguments[1] };else if (arguments.length === 1 && _typeof(arguments.length <= 0 ? undefined : arguments[0]) === "object") _this._args = arguments.length <= 0 ? undefined : arguments[0];else throw new Error("invalid arguments to ApolloClientWS constructor (invalid number or type of arguments)");
if (_this._args.uri === undefined) throw new Error("invalid arguments to ApolloClientWS constructor (missing URI)");
on(...args) {
return this._emitter.on(...args);
}
/* provide default values for options */
_this._args.opts = Object.assign({
debug: 0,
protocols: [],
compress: false,
encoding: "json",
keepalive: 0,
reconnectattempts: -1,
reconnectdelay: 2 * 1000
}, _this._args.opts);
off(...args) {
return this._emitter.off(...args);
}
/* validate options */
var errors = [];
if (!_ducky2.default.validate(_this._args.opts, "{\n debug: number,\n protocols: [ string* ],\n compress: boolean,\n encoding: string,\n keepalive: number,\n reconnectattempts: number,\n reconnectdelay: number\n }", errors)) throw new Error("invalid options: " + errors.join("; "));
addListener(...args) {
return this._emitter.addListener(...args);
}
/* initialize state variables */
_this._ws = null;
_this._wsf = null;
_this._to = null;
_this._tx = {};
removeListener(...args) {
return this._emitter.removeListener(...args);
}
/* provide hook latching sub-system */
_this._latching = new _latching6.default();
removeAllListeners(...args) {
return this._emitter.removeAllListeners(...args);
}
/* provide event emitter sub-system */
_this._emitter = new _eventemitter2.default();
return _this;
}
listenerCount(...args) {
return this._emitter.listenerCount(...args);
}
/* ADDON: pass-through methods of latching sub-system */
listeners(...args) {
return this._emitter.listeners(...args);
}
eventNames(...args) {
return this._emitter.eventNames(...args);
}
/* ADDON: log a debug message */
_createClass(ApolloClientWS, [{
key: "hook",
value: function hook() {
var _latching;
return (_latching = this._latching).hook.apply(_latching, arguments);
}
}, {
key: "at",
value: function at() {
var _latching2;
log(level, msg) {
if (level <= this._args.opts.debug) {
let date = new Date().toISOString();
let log = `${date} DEBUG [${level}]: ${msg}`;
this.emit("debug", {
date,
level,
msg,
log
});
}
}
/* ADDON: connect to the peer */
return (_latching2 = this._latching).at.apply(_latching2, arguments);
}
}, {
key: "latch",
value: function latch() {
var _latching3;
return (_latching3 = this._latching).latch.apply(_latching3, arguments);
}
}, {
key: "unlatch",
value: function unlatch() {
var _latching4;
connect() {
const connectInternal = (attempt = 0) => {
return new Promise((resolve, reject) => {
this.emit("connect");
this.log(1, "connect: begin");
/* create a new WebSocket client */
return (_latching4 = this._latching).unlatch.apply(_latching4, arguments);
let ws;
if ("node" === "browser") ws = new _ws.default(this._args.uri, this._args.opts.protocols);else {
let opts = this.hook("connect:options", "pass", {});
ws = new _ws.default(this._args.uri, this._args.opts.protocols, opts);
}
/* configure binary transfer */
/* ADDON: pass-through methods of emitter sub-system */
ws.binaryType = "node" === "browser" ? "arraybuffer" : "nodebuffer";
/* create a new WebSocket-Framed wrapper */
}, {
key: "emit",
value: function emit() {
var _emitter;
let wsf = new _websocketFramed.default(ws, this._args.opts.encoding);
/* react (once) on error messages */
return (_emitter = this._emitter).emit.apply(_emitter, arguments);
}
}, {
key: "once",
value: function once() {
var _emitter2;
const onError = ev => {
if (this._ws !== null && this._ws._explicitDisconnect) return;
this.log(1, `connect: end (connection error: ${ev.message})`);
ws.removeEventListener("error", onError);
ws._errorOnConnect = true;
return (_emitter2 = this._emitter).once.apply(_emitter2, arguments);
}
}, {
key: "on",
value: function on() {
var _emitter3;
if (attempt < this._args.opts.reconnectattempts || this._args.opts.reconnectattempts === -1) {
this.log(2, "connection error: trigger new connect attempt " + `(in ${Math.trunc(this._args.opts.reconnectdelay / 1000)}s)`);
setTimeout(() => {
/* handle repeated connection attempts (subsequently) */
connectInternal(attempt + 1).then(() => resolve()).catch(err => reject(err));
}, this._args.opts.reconnectdelay);
} else reject(ev);
};
return (_emitter3 = this._emitter).on.apply(_emitter3, arguments);
}
}, {
key: "off",
value: function off() {
var _emitter4;
ws.addEventListener("error", onError);
/* react (once) on the connection opening */
return (_emitter4 = this._emitter).off.apply(_emitter4, arguments);
}
}, {
key: "addListener",
value: function addListener() {
var _emitter5;
const onOpen = () => {
this.log(1, "connect: end (connection open)");
ws.removeEventListener("open", onOpen);
this._ws = ws;
this._wsf = wsf;
return (_emitter5 = this._emitter).addListener.apply(_emitter5, arguments);
}
}, {
key: "removeListener",
value: function removeListener() {
var _emitter6;
if (this._args.opts.keepalive > 0) {
this.log(2, "connect: start auto-disconnect timer");
this._to = setTimeout(() => {
this.disconnect();
}, this._args.opts.keepalive);
}
return (_emitter6 = this._emitter).removeListener.apply(_emitter6, arguments);
}
}, {
key: "removeAllListeners",
value: function removeAllListeners() {
var _emitter7;
this.emit("open");
resolve();
};
return (_emitter7 = this._emitter).removeAllListeners.apply(_emitter7, arguments);
}
}, {
key: "listenerCount",
value: function listenerCount() {
var _emitter8;
ws.addEventListener("open", onOpen);
/* react (always) on received response messages */
return (_emitter8 = this._emitter).listenerCount.apply(_emitter8, arguments);
}
}, {
key: "listeners",
value: function listeners() {
var _emitter9;
const onMessage = ev => {
ev = this.hook("receive:message", "pass", ev);
let _ev$frame = ev.frame,
rid = _ev$frame.rid,
type = _ev$frame.type,
data = _ev$frame.data;
return (_emitter9 = this._emitter).listeners.apply(_emitter9, arguments);
}
}, {
key: "eventNames",
value: function eventNames() {
var _emitter10;
if (type === "GRAPHQL-RESPONSE" && typeof data === "object") {
/* is a valid GraphQL response */
this.log(3, `query: response (framed): ${JSON.stringify(ev.frame)}`);
return (_emitter10 = this._emitter).eventNames.apply(_emitter10, arguments);
}
if (this._tx[rid] !== undefined) {
if (_ducky.default.validate(data, "({ data: Object, errors?: [ Object* ] } | { data?: Object, errors: [ Object* ] })")) this._tx[rid](data);else this._tx[rid](null, "invalid GraphQL response object");
}
} else {
/* is a non-standard message */
this.log(2, `message received: ${JSON.stringify(ev.frame)}`);
this.emit("receive", ev.frame);
}
};
/* ADDON: log a debug message */
wsf.on("message", onMessage);
}, {
key: "log",
value: function log(level, msg) {
if (level <= this._args.opts.debug) {
var date = new Date().toISOString();
var log = date + " DEBUG [" + level + "]: " + msg;
this.emit("debug", { date: date, level: level, msg: msg, log: log });
}
}
const onSocketError = err => {
this.log(2, `WebSocket error: ${err}`);
/* not now, because of auto-reconnects we don't want to mention everything:
this.emit("error", `WebSocket error: ${err}`) */
};
/* ADDON: connect to the peer */
wsf.on("error", onSocketError);
/* react (once) on the connection closing */
}, {
key: "connect",
value: function connect() {
var _this2 = this;
const onClose = ev => {
if (this._ws !== null && this._ws._explicitDisconnect) return;
this.log(1, `connection closed (code: ${ev.code})`);
ws.removeEventListener("error", onError);
ws.removeEventListener("open", onOpen);
ws.removeEventListener("message", onMessage);
ws.removeEventListener("close", onClose);
if (this._to !== null) clearTimeout(this._to);
this._to = null;
this._ws = null;
this._wsf = null;
let errorOnConnect = ws._errorOnConnect;
delete ws._errorOnConnect;
this.emit("close");
var connectInternal = function connectInternal() {
var attempt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
if (!errorOnConnect && (ev.code > 1000 || this._args.opts.keepalive === 0)) {
this.log(2, "connection closed: trigger re-connect " + `(in ${this._args.opts.reconnectdelay / 1000}s)`);
setTimeout(() => {
this.connect().catch(err => void err);
}, this._args.opts.reconnectdelay);
}
};
return new Promise(function (resolve, reject) {
_this2.emit("connect");
_this2.log(1, "connect: begin");
ws.addEventListener("close", onClose);
});
};
/* handle subsequent connect calls */
/* create a new WebSocket client */
var ws = void 0;
if ("node" === "browser") ws = new _ws2.default(_this2._args.uri, _this2._args.opts.protocols);else {
var opts = _this2.hook("connect:options", "pass", {});
ws = new _ws2.default(_this2._args.uri, _this2._args.opts.protocols, opts);
}
/* configure binary transfer */
ws.binaryType = "node" === "browser" ? "arraybuffer" : "nodebuffer";
if (this._connectPromise) return Promise.resolve(this._connectPromise);else {
/* handle repeated connection attempts (initially) */
return this._connectPromise = connectInternal(0).then(() => {
delete this._connectPromise;
}, err => {
delete this._connectPromise;
throw err;
});
}
}
/* ADDON: disconnect from the peer */
/* create a new WebSocket-Framed wrapper */
var wsf = new _websocketFramed2.default(ws, _this2._args.opts.encoding);
/* react (once) on error messages */
var onError = function onError(ev) {
if (_this2._ws !== null && _this2._ws._explicitDisconnect) return;
_this2.log(1, "connect: end (connection error: " + ev.message + ")");
ws.removeEventListener("error", onError);
ws._errorOnConnect = true;
if (attempt < _this2._args.opts.reconnectattempts || _this2._args.opts.reconnectattempts === -1) {
_this2.log(2, "connection error: trigger new connect attempt " + ("(in " + Math.trunc(_this2._args.opts.reconnectdelay / 1000) + "s)"));
setTimeout(function () {
/* handle repeated connection attempts (subsequently) */
connectInternal(attempt + 1).then(function () {
return resolve();
}).catch(function (err) {
return reject(err);
});
}, _this2._args.opts.reconnectdelay);
} else reject(ev);
};
ws.addEventListener("error", onError);
disconnect() {
/* handle subsequent disconnect calls */
if (this._disconnectPromise) return Promise.resolve(this._disconnectPromise);else {
return this._disconnectPromise = new Promise((resolve, reject) => {
/* disconnect from the peer */
this.emit("disconnect");
this.log(1, "disconnect: begin");
/* react (once) on the connection opening */
var onOpen = function onOpen() {
_this2.log(1, "connect: end (connection open)");
ws.removeEventListener("open", onOpen);
_this2._ws = ws;
_this2._wsf = wsf;
if (_this2._args.opts.keepalive > 0) {
_this2.log(2, "connect: start auto-disconnect timer");
_this2._to = setTimeout(function () {
_this2.disconnect();
}, _this2._args.opts.keepalive);
}
_this2.emit("open");
resolve();
};
ws.addEventListener("open", onOpen);
if (this._ws !== null) {
this._ws._explicitDisconnect = true;
/* react (always) on received response messages */
var onMessage = function onMessage(ev) {
ev = _this2.hook("receive:message", "pass", ev);
var _ev$frame = ev.frame,
rid = _ev$frame.rid,
type = _ev$frame.type,
data = _ev$frame.data;
const onClose = ev => {
if (this._ws === null) return;
if (type === "GRAPHQL-RESPONSE" && (typeof data === "undefined" ? "undefined" : _typeof(data)) === "object") {
/* is a valid GraphQL response */
_this2.log(3, "query: response (framed): " + JSON.stringify(ev.frame));
if (_this2._tx[rid] !== undefined) {
if (_ducky2.default.validate(data, "({ data: Object, errors?: [ Object* ] } | { data?: Object, errors: [ Object* ] })")) _this2._tx[rid](data);else _this2._tx[rid](null, "invalid GraphQL response object");
}
} else {
/* is a non-standard message */
_this2.log(2, "message received: " + JSON.stringify(ev.frame));
_this2.emit("receive", ev.frame);
}
};
wsf.on("message", onMessage);
var onSocketError = function onSocketError(err) {
_this2.log(2, "WebSocket error: " + err);
/* not now, because of auto-reconnects we don't want to mention everything:
this.emit("error", `WebSocket error: ${err}`) */
};
wsf.on("error", onSocketError);
this._ws.removeEventListener("close", onClose);
/* react (once) on the connection closing */
var onClose = function onClose(ev) {
if (_this2._ws !== null && _this2._ws._explicitDisconnect) return;
_this2.log(1, "connection closed (code: " + ev.code + ")");
ws.removeEventListener("error", onError);
ws.removeEventListener("open", onOpen);
ws.removeEventListener("message", onMessage);
ws.removeEventListener("close", onClose);
if (_this2._to !== null) clearTimeout(_this2._to);
_this2._to = null;
_this2._ws = null;
_this2._wsf = null;
var errorOnConnect = ws._errorOnConnect;
delete ws._errorOnConnect;
_this2.emit("close");
if (!errorOnConnect && (ev.code > 1000 || _this2._args.opts.keepalive === 0)) {
_this2.log(2, "connection closed: trigger re-connect " + ("(in " + _this2._args.opts.reconnectdelay / 1000 + "s)"));
setTimeout(function () {
_this2.connect().catch(function (err) {
return void err;
});
}, _this2._args.opts.reconnectdelay);
}
};
ws.addEventListener("close", onClose);
});
};
/* handle subsequent connect calls */
if (this._connectPromise) return Promise.resolve(this._connectPromise);else {
/* handle repeated connection attempts (initially) */
return this._connectPromise = connectInternal(0).then(function () {
delete _this2._connectPromise;
}, function (err) {
delete _this2._connectPromise;throw err;
});
if (this._to !== null) {
clearTimeout(this._to);
this._to = null;
}
}
/* ADDON: disconnect from the peer */
this._ws = null;
this._wsf = null;
this.log(1, "disconnect: end");
this.emit("close");
resolve();
};
}, {
key: "disconnect",
value: function disconnect() {
var _this3 = this;
this._ws.addEventListener("close", onClose);
/* handle subsequent disconnect calls */
if (this._disconnectPromise) return Promise.resolve(this._disconnectPromise);else {
return this._disconnectPromise = new Promise(function (resolve, reject) {
/* disconnect from the peer */
_this3.emit("disconnect");
_this3.log(1, "disconnect: begin");
if (_this3._ws !== null) {
_this3._ws._explicitDisconnect = true;
var onClose = function onClose(ev) {
if (_this3._ws === null) return;
_this3._ws.removeEventListener("close", onClose);
if (_this3._to !== null) {
clearTimeout(_this3._to);
_this3._to = null;
}
_this3._ws = null;
_this3._wsf = null;
_this3.log(1, "disconnect: end");
_this3.emit("close");
resolve();
};
_this3._ws.addEventListener("close", onClose);
_this3._ws.close();
} else {
_this3.log(1, "disconnect: end (no-op)");
resolve();
}
}).then(function () {
delete _this3._disconnectPromise;
}, function () {
delete _this3._disconnectPromise;
});
}
this._ws.close();
} else {
this.log(1, "disconnect: end (no-op)");
resolve();
}
}).then(() => {
delete this._disconnectPromise;
}, () => {
delete this._disconnectPromise;
});
}
}
/* ADDON: send message to the peer */
/* ADDON: send message to the peer */
}, {
key: "send",
value: function send(type, data) {
var _this4 = this;
send(type, data) {
this.log(1, "send: begin");
this.emit("send", {
type,
data
});
return new Promise((resolve, reject) => {
if (this._ws === null) {
this.log(2, "send: on-the-fly connect");
this.connect().then(() => resolve()).catch(err => reject(err));
} else resolve();
}).then(() => {
/* await WebSocket ready-state OPEN */
return new Promise((resolve, reject) => {
const check = k => {
if (k <= 0) reject(new Error("failed to await WebSocket ready-state OPEN"));else if (this._ws.readyState === _ws.default.CLOSED) reject(new Error("failed to send to WebSocket, already in ready-state CLOSED"));else if (this._ws.readyState === _ws.default.CLOSING) reject(new Error("failed to send to WebSocket, already in ready-state CLOSING"));else if (this._ws.readyState === _ws.default.CONNECTING) setTimeout(() => check(k - 1), 100);else resolve();
};
this.log(1, "send: begin");
this.emit("send", { type: type, data: data });
return new Promise(function (resolve, reject) {
if (_this4._ws === null) {
_this4.log(2, "send: on-the-fly connect");
_this4.connect().then(function () {
return resolve();
}).catch(function (err) {
return reject(err);
});
} else resolve();
}).then(function () {
/* await WebSocket ready-state OPEN */
return new Promise(function (resolve, reject) {
var check = function check(k) {
if (k <= 0) reject(new Error("failed to await WebSocket ready-state OPEN"));else if (_this4._ws.readyState === _ws2.default.CLOSED) reject(new Error("failed to send to WebSocket, already in ready-state CLOSED"));else if (_this4._ws.readyState === _ws2.default.CLOSING) reject(new Error("failed to send to WebSocket, already in ready-state CLOSING"));else if (_this4._ws.readyState === _ws2.default.CONNECTING) setTimeout(function () {
return check(k - 1);
}, 100);else resolve();
};
check(100);
});
}).then(function () {
/* send the message */
var _wsf$send = _this4._wsf.send({ type: type, data: data }),
frame = _wsf$send.frame;
check(100);
});
}).then(() => {
/* send the message */
let _this$_wsf$send = this._wsf.send({
type,
data
}),
frame = _this$_wsf$send.frame;
_this4.log(2, "message sent: " + JSON.stringify(frame));
_this4.log(1, "send: end");
return frame;
});
}
this.log(2, `message sent: ${JSON.stringify(frame)}`);
this.log(1, "send: end");
return frame;
});
}
/* STANDARD: send request to the peer */
/* STANDARD: send request to the peer */
}, {
key: "request",
value: function request(operation) {
var _this5 = this;
request(operation) {
return new _apolloLink.Observable(observer => {
this.emit("request", operation);
this.log(1, "request: begin");
/* we here would have (but don't use):
const { operationName, extensions, variables, query } = operation */
return new _apolloLink.Observable(function (observer) {
_this5.emit("request", operation);
_this5.log(1, "request: begin");
/* we here would have (but don't use):
const { operationName, extensions, variables, query } = operation */
void new Promise(function (resolve, reject) {
/* optionally perform the deferred connect */
if (_this5._ws === null) {
_this5.log(2, "request: on-the-fly connect");
_this5.connect().then(function () {
return resolve();
}).catch(function (err) {
return reject(err);
});
} else resolve();
}).then(function () {
/* await WebSocket ready-state OPEN */
return new Promise(function (resolve, reject) {
var check = function check(k) {
if (k <= 0) reject(new Error("failed to await WebSocket ready-state OPEN"));else if (_this5._ws.readyState === _ws2.default.CLOSED) reject(new Error("failed to send to WebSocket, already in ready-state CLOSED"));else if (_this5._ws.readyState === _ws2.default.CLOSING) reject(new Error("failed to send to WebSocket, already in ready-state CLOSING"));else if (_this5._ws.readyState === _ws2.default.CONNECTING) setTimeout(function () {
return check(k - 1);
}, 100);else resolve();
};
check(100);
});
}).then(function () {
/* perform the request */
return new Promise(function (resolve, reject) {
/* prepare the request */
var request = Object.assign({}, operation);
request.query = (0, _printer.print)(request.query);
if (_this5._args.opts.compress === true) request.query = (0, _graphqlQueryCompress2.default)(request.query);
if (request.operationName === null) delete request.operationName;
if (Object.keys(request.variables).length === 0) delete request.variables;
if (Object.keys(request.extensions).length === 0) delete request.extensions;
request = _this5.hook("query:request", "pass", request);
void new Promise((resolve, reject) => {
/* optionally perform the deferred connect */
if (this._ws === null) {
this.log(2, "request: on-the-fly connect");
this.connect().then(() => resolve()).catch(err => reject(err));
} else resolve();
}).then(() => {
/* await WebSocket ready-state OPEN */
return new Promise((resolve, reject) => {
const check = k => {
if (k <= 0) reject(new Error("failed to await WebSocket ready-state OPEN"));else if (this._ws.readyState === _ws.default.CLOSED) reject(new Error("failed to send to WebSocket, already in ready-state CLOSED"));else if (this._ws.readyState === _ws.default.CLOSING) reject(new Error("failed to send to WebSocket, already in ready-state CLOSING"));else if (this._ws.readyState === _ws.default.CONNECTING) setTimeout(() => check(k - 1), 100);else resolve();
};
/* send the request */
_this5.log(2, "request: request: " + JSON.stringify(request));
check(100);
});
}).then(() => {
/* perform the request */
return new Promise((resolve, reject) => {
/* prepare the request */
let request = Object.assign({}, operation);
request.query = (0, _printer.print)(request.query);
if (this._args.opts.compress === true) request.query = (0, _graphqlQueryCompress.default)(request.query);
if (request.operationName === null) delete request.operationName;
if (Object.keys(request.variables).length === 0) delete request.variables;
if (Object.keys(request.extensions).length === 0) delete request.extensions;
request = this.hook("query:request", "pass", request);
/* send the request */
var _wsf$send2 = _this5._wsf.send({ type: "GRAPHQL-REQUEST", data: request }),
frame = _wsf$send2.frame;
this.log(2, `request: request: ${JSON.stringify(request)}`);
_this5.log(3, "request: request (framed): " + JSON.stringify(frame));
let _this$_wsf$send2 = this._wsf.send({
type: "GRAPHQL-REQUEST",
data: request
}),
frame = _this$_wsf$send2.frame;
/* queue request and await response or error */
var fid = frame.fid;
_this5._tx[fid] = function (response, error) {
delete _this5._tx[fid];
if (response) resolve(response);else reject(error);
};
});
}).then(function (response) {
/* optionally automatically disconnect connection after request */
if (_this5._args.opts.keepalive > 0) {
_this5.log(2, "request: (re)start auto-disconnect timer");
if (_this5._to !== null) clearTimeout(_this5._to);
_this5._to = setTimeout(function () {
_this5.disconnect();
}, _this5._args.opts.keepalive);
}
_this5.log(2, "request: response: " + JSON.stringify(response));
_this5.log(1, "request: end");
return response;
}).then(function (response) {
/* pass response to other Apollo Link instances */
operation.setContext({ response: response });
this.log(3, `request: request (framed): ${JSON.stringify(frame)}`);
/* queue request and await response or error */
/* pass response to caller */
observer.next(response);
observer.complete();
}).catch(function (err) {
/* pass error to caller */
observer.error(err);
});
return function () {
/* no-op: we cannot cancel the operation */
};
});
let fid = frame.fid;
this._tx[fid] = (response, error) => {
delete this._tx[fid];
if (response) resolve(response);else reject(error);
};
});
}).then(response => {
/* optionally automatically disconnect connection after request */
if (this._args.opts.keepalive > 0) {
this.log(2, "request: (re)start auto-disconnect timer");
if (this._to !== null) clearTimeout(this._to);
this._to = setTimeout(() => {
this.disconnect();
}, this._args.opts.keepalive);
}
}]);
return ApolloClientWS;
}(_apolloLink.ApolloLink);
this.log(2, `request: response: ${JSON.stringify(response)}`);
this.log(1, "request: end");
return response;
}).then(response => {
/* pass response to other Apollo Link instances */
operation.setContext({
response
});
/* pass response to caller */
observer.next(response);
observer.complete();
}).catch(err => {
/* pass error to caller */
observer.error(err);
});
return () => {
/* no-op: we cannot cancel the operation */
};
});
}
}
/* API export */

@@ -563,3 +502,3 @@

module.exports = {
ApolloClientWS: ApolloClientWS
ApolloClientWS
};

@@ -566,0 +505,0 @@

{
"name": "apollo-client-ws",
"version": "2.2.1",
"version": "2.3.0",
"description": "GraphQL WebSocket Network Interface for Apollo Client",

@@ -21,49 +21,46 @@ "keywords": [ "graphql", "websocket", "network", "interface", "transport", "apollo", "client" ],

"browserify-shim": {
"ws": "global:WebSocket"
"ws": "global:WebSocket"
},
"peerDependencies": {
"apollo-client": ">=2.1.0",
"apollo-link": ">=1.0.7"
"apollo-client": ">=2.1.0",
"apollo-link": ">=1.0.7"
},
"dependencies": {
"graphql": "0.13.2",
"graphql-query-compress": "1.0.11",
"websocket-framed": "1.0.23",
"eventemitter3": "3.1.0",
"latching": "1.0.1",
"es6-promise": "4.2.4",
"ducky": "2.6.11",
"ws": "6.0.0"
"graphql": "0.13.2",
"graphql-query-compress": "1.1.0",
"websocket-framed": "1.1.0",
"eventemitter3": "3.1.0",
"latching": "1.0.3",
"es6-promise": "4.2.4",
"ducky": "2.6.12",
"ws": "6.0.0"
},
"optionalDependencies": {
"utf-8-validate": "5.0.1",
"bufferutil": "4.0.0"
"utf-8-validate": "5.0.1",
"bufferutil": "4.0.0"
},
"devDependencies": {
"apollo-client": ">=2.1.0",
"apollo-link": ">=1.0.7",
"grunt": "1.0.3",
"grunt-cli": "1.2.0",
"grunt-contrib-clean": "1.1.0",
"grunt-eslint": "21.0.0",
"grunt-browserify": "5.3.0",
"browserify": "16.2.2",
"envify": "4.1.0",
"babelify": "8.0.0",
"babel-core": "6.26.3",
"babel-preset-es2015": "6.24.1",
"babel-preset-es2016": "6.24.1",
"babel-preset-es2017": "6.24.1",
"babel-plugin-transform-runtime": "6.23.0",
"uglifyify": "5.0.1",
"browserify-header": "0.9.4",
"browserify-derequire": "0.9.6",
"browserify-shim": "3.8.14",
"babel-eslint": "8.2.6",
"eslint": "5.2.0",
"eslint-config-standard": "11.0.0",
"eslint-plugin-standard": "3.1.0",
"eslint-plugin-promise": "3.8.0",
"eslint-plugin-import": "2.13.0",
"eslint-plugin-node": "7.0.1"
"apollo-client": ">=2.1.0",
"apollo-link": ">=1.0.7",
"grunt": "1.0.3",
"grunt-cli": "1.3.1",
"grunt-contrib-clean": "1.1.0",
"grunt-eslint": "21.0.0",
"grunt-browserify": "5.3.0",
"browserify": "16.2.2",
"envify": "4.1.0",
"babelify": "9.0.0",
"@babel/core": "7.0.0",
"@babel/preset-env": "7.0.0",
"uglifyify": "5.0.1",
"browserify-header": "0.9.4",
"browserify-derequire": "0.9.6",
"browserify-shim": "3.8.14",
"babel-eslint": "9.0.0",
"eslint": "5.5.0",
"eslint-config-standard": "12.0.0",
"eslint-plugin-standard": "4.0.0",
"eslint-plugin-promise": "4.0.0",
"eslint-plugin-import": "2.14.0",
"eslint-plugin-node": "7.0.1"
},

@@ -70,0 +67,0 @@ "scripts": {

@@ -14,7 +14,9 @@

[ "babelify", {
presets: [ "es2015", "es2016", "es2017" ],
plugins: [ [ "transform-runtime", {
"polyfill": true,
"regenerator": false
} ] ]
presets: [
[ "@babel/preset-env", {
"targets": {
"browsers": "last 2 versions, not dead"
}
} ]
]
} ]

@@ -21,0 +23,0 @@ ],

@@ -8,13 +8,13 @@ {

"graphql-tag": "2.9.2",
"graphql-tools": "3.0.5",
"hapi": "17.5.2",
"hapi-plugin-websocket": "2.0.11",
"graphql-tools": "3.1.1",
"hapi": "17.5.4",
"hapi-plugin-websocket": "2.0.13",
"boom": "7.2.0",
"apollo-client": "2.3.5",
"apollo-client": "2.4.1",
"apollo-client-ws": "file:../",
"apollo-cache-inmemory": "1.2.5"
"apollo-cache-inmemory": "1.2.9"
},
"devDependencies": {
"grunt": "1.0.3",
"grunt-cli": "1.2.0",
"grunt-cli": "1.3.1",
"grunt-contrib-clean": "1.1.0",

@@ -24,8 +24,5 @@ "grunt-eslint": "21.0.0",

"browserify": "16.2.2",
"babelify": "8.0.0",
"babel-core": "6.26.3",
"babel-preset-es2015": "6.24.1",
"babel-preset-es2016": "6.24.1",
"babel-preset-es2017": "6.24.1",
"babel-plugin-transform-runtime": "6.23.0",
"babelify": "9.0.0",
"@babel/core": "7.0.0",
"@babel/preset-env": "7.0.0",
"rimraf": "2.6.2"

@@ -32,0 +29,0 @@ },

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc