UNPKG

subscriptions-transport-ws

Version:
108 lines 4.64 kB
"use strict"; var websocket = require('websocket'); var W3CWebSocket = websocket['w3cwebsocket']; var messageTypes_1 = require('./messageTypes'); var lodash_1 = require('lodash'); var Client = (function () { function Client(url) { var _this = this; this.client = new W3CWebSocket(url, 'graphql-subscriptions'); this.subscriptionHandlers = {}; this.maxId = 0; this.client.onmessage = function (message) { var parsedMessage; try { parsedMessage = JSON.parse(message.data); } catch (e) { throw new Error('Message must be JSON-parseable.'); } var subId = parsedMessage.id; if (!_this.subscriptionHandlers[subId]) { _this.unsubscribe(subId); return; } switch (parsedMessage.type) { case messageTypes_1.SUBSCRIPTION_SUCCESS: _this.subscriptionHandlers[subId](null, null); break; case messageTypes_1.SUBSCRIPTION_FAIL: if (_this.subscriptionHandlers[subId]) { _this.subscriptionHandlers[subId](parsedMessage.errors, null); } delete _this.subscriptionHandlers[subId]; break; case messageTypes_1.SUBSCRIPTION_DATA: if (parsedMessage.payload.data && !parsedMessage.payload.errors) { _this.subscriptionHandlers[subId](null, parsedMessage.payload.data); } else { _this.subscriptionHandlers[subId](parsedMessage.payload.errors, null); } break; default: throw new Error('Invalid message type - must be of type `subscription_start` or `subscription_data`.'); } }; } Client.prototype.subscribe = function (options, handler) { var query = options.query, variables = options.variables, operationName = options.operationName; if (!query || !variables || !operationName) { throw new Error('Must provide `query`, `variables`, and `operationName` to subscribe.'); } if (!handler) { throw new Error('Must provide `handler` to subscribe.'); } if (!lodash_1.isString(query) || !lodash_1.isString(operationName) || !lodash_1.isObject(variables)) { throw new Error('Incorrect option types to subscribe. `subscription` must be a string,' + '`operationName` must be a string, and `variables` must be an object.'); } switch (this.client.readyState) { case this.client.OPEN: var subId = this.generateSubscriptionId(); var message = Object.assign(options, { type: messageTypes_1.SUBSCRIPTION_START, id: subId }); this.sendMessage(message); this.subscriptionHandlers[subId] = handler; return subId; case this.client.CONNECTING: throw new Error('Client is still connecting to websocket.'); case this.client.CLOSING: throw new Error('Client websocket connection is closing.'); case this.client.CLOSED: throw new Error('Client is not connected to a websocket.'); default: throw new Error('Client is not connected to a websocket.'); } }; Client.prototype.unsubscribe = function (id) { delete this.subscriptionHandlers[id]; if (this.client.readyState === this.client.OPEN) { var message = { id: id, type: messageTypes_1.SUBSCRIPTION_END }; this.sendMessage(message); } }; Client.prototype.unsubscribeAll = function () { var _this = this; Object.keys(this.subscriptionHandlers).forEach(function (subId) { _this.unsubscribe(subId); }); }; Client.prototype.sendMessage = function (message) { if (this.client.readyState === this.client.OPEN) { this.client.send(JSON.stringify(message)); } else { throw new Error('Cannot send message. WebSocket connection is not open'); } }; Client.prototype.generateSubscriptionId = function () { var id = this.maxId; this.maxId += 1; return id; }; return Client; }()); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Client; ; //# sourceMappingURL=client.js.map