New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

graphql-ws

Package Overview
Dependencies
Maintainers
1
Versions
163
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

graphql-ws - npm Package Compare versions

Comparing version

to
6.0.0-alpha-2f8a0db0dbf18c4bcf4572a2dfa5935024b27f8b

dist/client.cjs

115

package.json
{
"name": "graphql-ws",
"version": "5.16.2",
"version": "6.0.0-alpha-2f8a0db0dbf18c4bcf4572a2dfa5935024b27f8b",
"description": "Coherent, zero-dependency, lazy, simple, GraphQL over WebSocket Protocol compliant server and client",
"type": "module",
"repository": {

@@ -14,48 +15,41 @@ "type": "git",

"engines": {
"node": ">=10"
"node": ">=20"
},
"main": "lib/index.js",
"module": "lib/index.mjs",
"main": "dist/index.js",
"exports": {
".": {
"types": "./lib/index.d.ts",
"require": "./lib/index.js",
"import": "./lib/index.mjs",
"browser": "./umd/graphql-ws.js"
"types": "./dist/index.d.ts",
"require": "./dist/index.cjs",
"import": "./dist/index.js",
"browser": "./dist/client.js"
},
"./lib/use/ws": {
"types": "./lib/use/ws.d.ts",
"require": "./lib/use/ws.js",
"import": "./lib/use/ws.mjs"
"./use/ws": {
"types": "./dist/use/ws.d.ts",
"require": "./dist/use/ws.cjs",
"import": "./dist/use/ws.js"
},
"./lib/use/uWebSockets": {
"types": "./lib/use/uWebSockets.d.ts",
"require": "./lib/use/uWebSockets.js",
"import": "./lib/use/uWebSockets.mjs"
"./use/uWebSockets": {
"types": "./dist/use/uWebSockets.d.ts",
"require": "./dist/use/uWebSockets.cjs",
"import": "./dist/use/uWebSockets.js"
},
"./lib/use/@fastify/websocket": {
"types": "./lib/use/@fastify/websocket.d.ts",
"require": "./lib/use/@fastify/websocket.js",
"import": "./lib/use/@fastify/websocket.mjs"
"./use/@fastify/websocket": {
"types": "./dist/use/@fastify/websocket.d.ts",
"require": "./dist/use/@fastify/websocket.cjs",
"import": "./dist/use/@fastify/websocket.js"
},
"./lib/use/fastify-websocket": {
"types": "./lib/use/fastify-websocket.d.ts",
"require": "./lib/use/fastify-websocket.js",
"import": "./lib/use/fastify-websocket.mjs"
"./use/bun": {
"types": "./dist/use/bun.d.ts",
"require": "./dist/use/bun.cjs",
"import": "./dist/use/bun.js"
},
"./lib/use/bun": {
"bun": "./lib/use/bun.mjs",
"types": "./lib/use/bun.d.ts",
"require": "./lib/use/bun.js",
"import": "./lib/use/bun.mjs"
"./use/deno": {
"types": "./dist/use/deno.d.ts",
"require": "./dist/use/deno.cjs",
"import": "./dist/use/deno.js"
},
"./lib/use/deno": {
"types": "./lib/use/deno.d.ts",
"require": "./lib/use/deno.js",
"import": "./lib/use/deno.mjs"
},
"./package.json": "./package.json"
},
"browser": "umd/graphql-ws.js",
"types": "lib/index.d.ts",
"browser": "./dist/client.js",
"types": "./dist/index.d.ts",
"sideEffects": [

@@ -67,3 +61,3 @@ "umd/*"

"PROTOCOL.md",
"lib",
"dist",
"umd",

@@ -88,18 +82,13 @@ "README.md"

"scripts": {
"build": "yarn build:esm && yarn build:cjs && yarn build:umd && yarn postbuild",
"build:cjs": "tsc -b tsconfig.cjs.json",
"build:esm": "tsc -b tsconfig.esm.json && node scripts/esm-post-process.mjs",
"build:umd": "rollup --bundleConfigAsCjs --config rollup.config.ts --configPlugin typescript && gzip umd/graphql-ws.min.js -c > umd/graphql-ws.min.js.gz",
"changeset": "changeset",
"check:format": "prettier --check .",
"check:lint": "eslint 'src'",
"check:type": "tsc --noEmit",
"format": "yarn check:format --write",
"gendocs": "typedoc --options typedoc.js src/ && node scripts/post-gendocs.mjs",
"postbuild": "node scripts/fix-declaration-directives.mjs",
"check:types": "tsc --noEmit",
"test": "vitest",
"release": "yarn build && yarn changeset publish"
"build": "pkgroll --clean-dist && rollup -c rollup.config.js && gzip umd/graphql-ws.min.js -c > umd/graphql-ws.min.js.gz",
"prepack": "yarn build",
"gendocs": "typedoc --options typedoc.js src/ && node scripts/post-gendocs.js"
},
"peerDependencies": {
"graphql": ">=0.11 <=16"
"graphql": "^15.9.0 || ^16.9.0"
},

@@ -109,32 +98,24 @@ "devDependencies": {

"@changesets/cli": "^2.27.11",
"@fastify/websocket": "^9.0.0",
"@fastify/websocket": "^11.0.1",
"@ianvs/prettier-plugin-sort-imports": "^4.4.0",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^11.1.6",
"@types/eslint": "^8.56.10",
"@tsconfig/strictest": "^2.0.5",
"@types/glob": "^8.1.0",
"@types/ws": "^8.5.10",
"@typescript-eslint/eslint-plugin": "^7.7.0",
"@typescript-eslint/parser": "^7.7.0",
"@types/ws": "^8.5.13",
"bun-types": "^1.1.4",
"eslint": "^8.57.0",
"fastify": "^4.26.2",
"fastify-websocket": "4.2.2",
"fastify": "^5.2.1",
"glob": "^10.3.12",
"graphql": "^16.8.1",
"graphql": "^16.9.0",
"jsdom": "^25.0.1",
"pkgroll": "patch:pkgroll@npm%3A2.6.1#~/.yarn/patches/pkgroll-npm-2.6.1-193e78e84e.patch",
"prettier": "^3.4.2",
"prettier-plugin-sh": "^0.14.0",
"replacestream": "^4.0.3",
"rollup": "^4.14.3",
"subscriptions-transport-ws": "^0.11.0",
"tslib": "^2.6.2",
"typedoc": "^0.25.13",
"typedoc-plugin-markdown": "^3.17.1",
"typescript": "^5.4.5",
"uWebSockets.js": "uNetworking/uWebSockets.js#v20.43.0",
"rollup": "^4.30.1",
"typedoc": "^0.27.6",
"typedoc-plugin-markdown": "^4.4.1",
"typescript": "^5.7.3",
"uWebSockets.js": "uNetworking/uWebSockets.js#v20.51.0",
"vitest": "^2.1.8",
"ws": "8.12.0",
"ws7": "npm:ws@^7.5.9"
"ws": "^8.18.0"
}
}
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.graphqlWs = {}));
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.graphqlWs = {}));
})(this, (function (exports) { 'use strict';
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
function __await(v) {
return this instanceof __await ? (this.v = v, this) : new __await(v);
function extendedTypeof(val) {
if (val === null) {
return "null";
}
function __asyncGenerator(thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var g = generator.apply(thisArg, _arguments || []), i, q = [];
return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
function fulfill(value) { resume("next", value); }
function reject(value) { resume("throw", value); }
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
if (Array.isArray(val)) {
return "array";
}
return typeof val;
}
function isObject(val) {
return extendedTypeof(val) === "object";
}
function areGraphQLErrors(obj) {
return Array.isArray(obj) && // must be at least one error
obj.length > 0 && // error has at least a message
obj.every((ob) => "message" in ob);
}
function limitCloseReason(reason, whenTooLong) {
return reason.length < 124 ? reason : whenTooLong;
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
/** @private */
function extendedTypeof(val) {
if (val === null) {
return 'null';
}
if (Array.isArray(val)) {
return 'array';
}
return typeof val;
const GRAPHQL_TRANSPORT_WS_PROTOCOL = "graphql-transport-ws";
const DEPRECATED_GRAPHQL_WS_PROTOCOL = "graphql-ws";
var CloseCode = /* @__PURE__ */ ((CloseCode2) => {
CloseCode2[CloseCode2["InternalServerError"] = 4500] = "InternalServerError";
CloseCode2[CloseCode2["InternalClientError"] = 4005] = "InternalClientError";
CloseCode2[CloseCode2["BadRequest"] = 4400] = "BadRequest";
CloseCode2[CloseCode2["BadResponse"] = 4004] = "BadResponse";
CloseCode2[CloseCode2["Unauthorized"] = 4401] = "Unauthorized";
CloseCode2[CloseCode2["Forbidden"] = 4403] = "Forbidden";
CloseCode2[CloseCode2["SubprotocolNotAcceptable"] = 4406] = "SubprotocolNotAcceptable";
CloseCode2[CloseCode2["ConnectionInitialisationTimeout"] = 4408] = "ConnectionInitialisationTimeout";
CloseCode2[CloseCode2["ConnectionAcknowledgementTimeout"] = 4504] = "ConnectionAcknowledgementTimeout";
CloseCode2[CloseCode2["SubscriberAlreadyExists"] = 4409] = "SubscriberAlreadyExists";
CloseCode2[CloseCode2["TooManyInitialisationRequests"] = 4429] = "TooManyInitialisationRequests";
return CloseCode2;
})(CloseCode || {});
var MessageType = /* @__PURE__ */ ((MessageType2) => {
MessageType2["ConnectionInit"] = "connection_init";
MessageType2["ConnectionAck"] = "connection_ack";
MessageType2["Ping"] = "ping";
MessageType2["Pong"] = "pong";
MessageType2["Subscribe"] = "subscribe";
MessageType2["Next"] = "next";
MessageType2["Error"] = "error";
MessageType2["Complete"] = "complete";
return MessageType2;
})(MessageType || {});
function validateMessage(val) {
if (!isObject(val)) {
throw new Error(
`Message is expected to be an object, but got ${extendedTypeof(val)}`
);
}
/** @private */
function isObject(val) {
return extendedTypeof(val) === 'object';
if (!val.type) {
throw new Error(`Message is missing the 'type' property`);
}
/** @private */
function areGraphQLErrors(obj) {
return (Array.isArray(obj) &&
// must be at least one error
obj.length > 0 &&
// error has at least a message
obj.every((ob) => 'message' in ob));
if (typeof val.type !== "string") {
throw new Error(
`Message is expects the 'type' property to be a string, but got ${extendedTypeof(
val.type
)}`
);
}
/**
* Limits the WebSocket close event reason to not exceed a length of one frame.
* Reference: https://datatracker.ietf.org/doc/html/rfc6455#section-5.2.
*
* @private
*/
function limitCloseReason(reason, whenTooLong) {
return reason.length < 124 ? reason : whenTooLong;
}
/**
*
* common
*
*/
/**
* The WebSocket sub-protocol used for the [GraphQL over WebSocket Protocol](https://github.com/graphql/graphql-over-http/blob/main/rfcs/GraphQLOverWebSocket.md).
*
* @category Common
*/
const GRAPHQL_TRANSPORT_WS_PROTOCOL = 'graphql-transport-ws';
/**
* The deprecated subprotocol used by [subscriptions-transport-ws](https://github.com/apollographql/subscriptions-transport-ws).
*
* @private
*/
const DEPRECATED_GRAPHQL_WS_PROTOCOL = 'graphql-ws';
/**
* `graphql-ws` expected and standard close codes of the [GraphQL over WebSocket Protocol](https://github.com/graphql/graphql-over-http/blob/main/rfcs/GraphQLOverWebSocket.md).
*
* @category Common
*/
exports.CloseCode = void 0;
(function (CloseCode) {
CloseCode[CloseCode["InternalServerError"] = 4500] = "InternalServerError";
CloseCode[CloseCode["InternalClientError"] = 4005] = "InternalClientError";
CloseCode[CloseCode["BadRequest"] = 4400] = "BadRequest";
CloseCode[CloseCode["BadResponse"] = 4004] = "BadResponse";
/** Tried subscribing before connect ack */
CloseCode[CloseCode["Unauthorized"] = 4401] = "Unauthorized";
CloseCode[CloseCode["Forbidden"] = 4403] = "Forbidden";
CloseCode[CloseCode["SubprotocolNotAcceptable"] = 4406] = "SubprotocolNotAcceptable";
CloseCode[CloseCode["ConnectionInitialisationTimeout"] = 4408] = "ConnectionInitialisationTimeout";
CloseCode[CloseCode["ConnectionAcknowledgementTimeout"] = 4504] = "ConnectionAcknowledgementTimeout";
/** Subscriber distinction is very important */
CloseCode[CloseCode["SubscriberAlreadyExists"] = 4409] = "SubscriberAlreadyExists";
CloseCode[CloseCode["TooManyInitialisationRequests"] = 4429] = "TooManyInitialisationRequests";
})(exports.CloseCode || (exports.CloseCode = {}));
/**
* Types of messages allowed to be sent by the client/server over the WS protocol.
*
* @category Common
*/
exports.MessageType = void 0;
(function (MessageType) {
MessageType["ConnectionInit"] = "connection_init";
MessageType["ConnectionAck"] = "connection_ack";
MessageType["Ping"] = "ping";
MessageType["Pong"] = "pong";
MessageType["Subscribe"] = "subscribe";
MessageType["Next"] = "next";
MessageType["Error"] = "error";
MessageType["Complete"] = "complete";
})(exports.MessageType || (exports.MessageType = {}));
/**
* Validates the message against the GraphQL over WebSocket Protocol.
*
* Invalid messages will throw descriptive errors.
*
* @category Common
*/
function validateMessage(val) {
if (!isObject(val)) {
throw new Error(`Message is expected to be an object, but got ${extendedTypeof(val)}`);
switch (val.type) {
case "connection_init" /* ConnectionInit */:
case "connection_ack" /* ConnectionAck */:
case "ping" /* Ping */:
case "pong" /* Pong */: {
if (val.payload != null && !isObject(val.payload)) {
throw new Error(
`"${val.type}" message expects the 'payload' property to be an object or nullish or missing, but got "${val.payload}"`
);
}
if (!val.type) {
throw new Error(`Message is missing the 'type' property`);
break;
}
case "subscribe" /* Subscribe */: {
if (typeof val.id !== "string") {
throw new Error(
`"${val.type}" message expects the 'id' property to be a string, but got ${extendedTypeof(
val.id
)}`
);
}
if (typeof val.type !== 'string') {
throw new Error(`Message is expects the 'type' property to be a string, but got ${extendedTypeof(val.type)}`);
if (!val.id) {
throw new Error(
`"${val.type}" message requires a non-empty 'id' property`
);
}
switch (val.type) {
case exports.MessageType.ConnectionInit:
case exports.MessageType.ConnectionAck:
case exports.MessageType.Ping:
case exports.MessageType.Pong: {
if (val.payload != null && !isObject(val.payload)) {
throw new Error(`"${val.type}" message expects the 'payload' property to be an object or nullish or missing, but got "${val.payload}"`);
}
break;
}
case exports.MessageType.Subscribe: {
if (typeof val.id !== 'string') {
throw new Error(`"${val.type}" message expects the 'id' property to be a string, but got ${extendedTypeof(val.id)}`);
}
if (!val.id) {
throw new Error(`"${val.type}" message requires a non-empty 'id' property`);
}
if (!isObject(val.payload)) {
throw new Error(`"${val.type}" message expects the 'payload' property to be an object, but got ${extendedTypeof(val.payload)}`);
}
if (typeof val.payload.query !== 'string') {
throw new Error(`"${val.type}" message payload expects the 'query' property to be a string, but got ${extendedTypeof(val.payload.query)}`);
}
if (val.payload.variables != null && !isObject(val.payload.variables)) {
throw new Error(`"${val.type}" message payload expects the 'variables' property to be a an object or nullish or missing, but got ${extendedTypeof(val.payload.variables)}`);
}
if (val.payload.operationName != null &&
extendedTypeof(val.payload.operationName) !== 'string') {
throw new Error(`"${val.type}" message payload expects the 'operationName' property to be a string or nullish or missing, but got ${extendedTypeof(val.payload.operationName)}`);
}
if (val.payload.extensions != null && !isObject(val.payload.extensions)) {
throw new Error(`"${val.type}" message payload expects the 'extensions' property to be a an object or nullish or missing, but got ${extendedTypeof(val.payload.extensions)}`);
}
break;
}
case exports.MessageType.Next: {
if (typeof val.id !== 'string') {
throw new Error(`"${val.type}" message expects the 'id' property to be a string, but got ${extendedTypeof(val.id)}`);
}
if (!val.id) {
throw new Error(`"${val.type}" message requires a non-empty 'id' property`);
}
if (!isObject(val.payload)) {
throw new Error(`"${val.type}" message expects the 'payload' property to be an object, but got ${extendedTypeof(val.payload)}`);
}
break;
}
case exports.MessageType.Error: {
if (typeof val.id !== 'string') {
throw new Error(`"${val.type}" message expects the 'id' property to be a string, but got ${extendedTypeof(val.id)}`);
}
if (!val.id) {
throw new Error(`"${val.type}" message requires a non-empty 'id' property`);
}
if (!areGraphQLErrors(val.payload)) {
throw new Error(`"${val.type}" message expects the 'payload' property to be an array of GraphQL errors, but got ${JSON.stringify(val.payload)}`);
}
break;
}
case exports.MessageType.Complete: {
if (typeof val.id !== 'string') {
throw new Error(`"${val.type}" message expects the 'id' property to be a string, but got ${extendedTypeof(val.id)}`);
}
if (!val.id) {
throw new Error(`"${val.type}" message requires a non-empty 'id' property`);
}
break;
}
default:
throw new Error(`Invalid message 'type' property "${val.type}"`);
if (!isObject(val.payload)) {
throw new Error(
`"${val.type}" message expects the 'payload' property to be an object, but got ${extendedTypeof(
val.payload
)}`
);
}
return val;
}
/**
* Checks if the provided value is a valid GraphQL over WebSocket message.
*
* @deprecated Use `validateMessage` instead.
*
* @category Common
*/
function isMessage(val) {
try {
validateMessage(val);
return true;
if (typeof val.payload.query !== "string") {
throw new Error(
`"${val.type}" message payload expects the 'query' property to be a string, but got ${extendedTypeof(
val.payload.query
)}`
);
}
catch (_a) {
return false;
if (val.payload.variables != null && !isObject(val.payload.variables)) {
throw new Error(
`"${val.type}" message payload expects the 'variables' property to be a an object or nullish or missing, but got ${extendedTypeof(
val.payload.variables
)}`
);
}
}
/**
* Parses the raw websocket message data to a valid message.
*
* @category Common
*/
function parseMessage(data, reviver) {
return validateMessage(typeof data === 'string' ? JSON.parse(data, reviver) : data);
}
/**
* Stringifies a valid message ready to be sent through the socket.
*
* @category Common
*/
function stringifyMessage(msg, replacer) {
validateMessage(msg);
return JSON.stringify(msg, replacer);
}
/**
*
* client
*
*/
/**
* Creates a disposable GraphQL over WebSocket client.
*
* @category Client
*/
function createClient(options) {
const { url, connectionParams, lazy = true, onNonLazyError = console.error, lazyCloseTimeout: lazyCloseTimeoutMs = 0, keepAlive = 0, disablePong, connectionAckWaitTimeout = 0, retryAttempts = 5, retryWait = async function randomisedExponentialBackoff(retries) {
let retryDelay = 1000; // start with 1s delay
for (let i = 0; i < retries; i++) {
retryDelay *= 2;
}
await new Promise((resolve) => setTimeout(resolve, retryDelay +
// add random timeout from 300ms to 3s
Math.floor(Math.random() * (3000 - 300) + 300)));
}, shouldRetry = isLikeCloseEvent, isFatalConnectionProblem, on, webSocketImpl,
/**
* Generates a v4 UUID to be used as the ID using `Math`
* as the random number generator. Supply your own generator
* in case you need more uniqueness.
*
* Reference: https://gist.github.com/jed/982883
*/
generateID = function generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
const r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
}, jsonMessageReplacer: replacer, jsonMessageReviver: reviver, } = options;
let ws;
if (webSocketImpl) {
if (!isWebSocket(webSocketImpl)) {
throw new Error('Invalid WebSocket implementation provided');
}
ws = webSocketImpl;
if (val.payload.operationName != null && extendedTypeof(val.payload.operationName) !== "string") {
throw new Error(
`"${val.type}" message payload expects the 'operationName' property to be a string or nullish or missing, but got ${extendedTypeof(
val.payload.operationName
)}`
);
}
else if (typeof WebSocket !== 'undefined') {
ws = WebSocket;
if (val.payload.extensions != null && !isObject(val.payload.extensions)) {
throw new Error(
`"${val.type}" message payload expects the 'extensions' property to be a an object or nullish or missing, but got ${extendedTypeof(
val.payload.extensions
)}`
);
}
else if (typeof global !== 'undefined') {
ws =
global.WebSocket ||
// @ts-expect-error: Support more browsers
global.MozWebSocket;
break;
}
case "next" /* Next */: {
if (typeof val.id !== "string") {
throw new Error(
`"${val.type}" message expects the 'id' property to be a string, but got ${extendedTypeof(
val.id
)}`
);
}
else if (typeof window !== 'undefined') {
ws =
window.WebSocket ||
// @ts-expect-error: Support more browsers
window.MozWebSocket;
if (!val.id) {
throw new Error(
`"${val.type}" message requires a non-empty 'id' property`
);
}
if (!ws)
throw new Error("WebSocket implementation missing; on Node you can `import WebSocket from 'ws';` and pass `webSocketImpl: WebSocket` to `createClient`");
const WebSocketImpl = ws;
// websocket status emitter, subscriptions are handled differently
const emitter = (() => {
const message = (() => {
const listeners = {};
return {
on(id, listener) {
listeners[id] = listener;
return () => {
delete listeners[id];
};
},
emit(message) {
var _a;
if ('id' in message)
(_a = listeners[message.id]) === null || _a === undefined ? undefined : _a.call(listeners, message);
},
};
})();
const listeners = {
connecting: (on === null || on === undefined ? undefined : on.connecting) ? [on.connecting] : [],
opened: (on === null || on === undefined ? undefined : on.opened) ? [on.opened] : [],
connected: (on === null || on === undefined ? undefined : on.connected) ? [on.connected] : [],
ping: (on === null || on === undefined ? undefined : on.ping) ? [on.ping] : [],
pong: (on === null || on === undefined ? undefined : on.pong) ? [on.pong] : [],
message: (on === null || on === undefined ? undefined : on.message) ? [message.emit, on.message] : [message.emit],
closed: (on === null || on === undefined ? undefined : on.closed) ? [on.closed] : [],
error: (on === null || on === undefined ? undefined : on.error) ? [on.error] : [],
};
return {
onMessage: message.on,
on(event, listener) {
const l = listeners[event];
l.push(listener);
return () => {
l.splice(l.indexOf(listener), 1);
};
},
emit(event, ...args) {
// we copy the listeners so that unlistens dont "pull the rug under our feet"
for (const listener of [...listeners[event]]) {
// @ts-expect-error: The args should fit
listener(...args);
}
},
};
})();
// invokes the callback either when an error or closed event is emitted,
// first one that gets called prevails, other emissions are ignored
function errorOrClosed(cb) {
const listening = [
// errors are fatal and more critical than close events, throw them first
emitter.on('error', (err) => {
listening.forEach((unlisten) => unlisten());
cb(err);
}),
// closes can be graceful and not fatal, throw them second (if error didnt throw)
emitter.on('closed', (event) => {
listening.forEach((unlisten) => unlisten());
cb(event);
}),
];
if (!isObject(val.payload)) {
throw new Error(
`"${val.type}" message expects the 'payload' property to be an object, but got ${extendedTypeof(
val.payload
)}`
);
}
let connecting, locks = 0, lazyCloseTimeout, retrying = false, retries = 0, disposed = false;
async function connect() {
// clear the lazy close timeout immediatelly so that close gets debounced
// see: https://github.com/enisdenjo/graphql-ws/issues/388
clearTimeout(lazyCloseTimeout);
const [socket, throwOnClose] = await (connecting !== null && connecting !== undefined ? connecting : (connecting = new Promise((connected, denied) => (async () => {
if (retrying) {
await retryWait(retries);
// subscriptions might complete while waiting for retry
if (!locks) {
connecting = undefined;
return denied({ code: 1000, reason: 'All Subscriptions Gone' });
}
retries++;
}
emitter.emit('connecting', retrying);
const socket = new WebSocketImpl(typeof url === 'function' ? await url() : url, GRAPHQL_TRANSPORT_WS_PROTOCOL);
let connectionAckTimeout, queuedPing;
function enqueuePing() {
if (isFinite(keepAlive) && keepAlive > 0) {
clearTimeout(queuedPing); // in case where a pong was received before a ping (this is valid behaviour)
queuedPing = setTimeout(() => {
if (socket.readyState === WebSocketImpl.OPEN) {
socket.send(stringifyMessage({ type: exports.MessageType.Ping }));
emitter.emit('ping', false, undefined);
}
}, keepAlive);
}
}
errorOrClosed((errOrEvent) => {
connecting = undefined;
clearTimeout(connectionAckTimeout);
clearTimeout(queuedPing);
denied(errOrEvent);
if (errOrEvent instanceof TerminatedCloseEvent) {
socket.close(4499, 'Terminated'); // close event is artificial and emitted manually, see `Client.terminate()` below
socket.onerror = null;
socket.onclose = null;
}
});
socket.onerror = (err) => emitter.emit('error', err);
socket.onclose = (event) => emitter.emit('closed', event);
socket.onopen = async () => {
try {
emitter.emit('opened', socket);
const payload = typeof connectionParams === 'function'
? await connectionParams()
: connectionParams;
// connectionParams might take too long causing the server to kick off the client
// the necessary error/close event is already reported - simply stop execution
if (socket.readyState !== WebSocketImpl.OPEN)
return;
socket.send(stringifyMessage(payload
? {
type: exports.MessageType.ConnectionInit,
payload,
}
: {
type: exports.MessageType.ConnectionInit,
// payload is completely absent if not provided
}, replacer));
if (isFinite(connectionAckWaitTimeout) &&
connectionAckWaitTimeout > 0) {
connectionAckTimeout = setTimeout(() => {
socket.close(exports.CloseCode.ConnectionAcknowledgementTimeout, 'Connection acknowledgement timeout');
}, connectionAckWaitTimeout);
}
enqueuePing(); // enqueue ping (noop if disabled)
}
catch (err) {
emitter.emit('error', err);
socket.close(exports.CloseCode.InternalClientError, limitCloseReason(err instanceof Error ? err.message : new Error(err).message, 'Internal client error'));
}
};
let acknowledged = false;
socket.onmessage = ({ data }) => {
try {
const message = parseMessage(data, reviver);
emitter.emit('message', message);
if (message.type === 'ping' || message.type === 'pong') {
emitter.emit(message.type, true, message.payload); // received
if (message.type === 'pong') {
enqueuePing(); // enqueue next ping (noop if disabled)
}
else if (!disablePong) {
// respond with pong on ping
socket.send(stringifyMessage(message.payload
? {
type: exports.MessageType.Pong,
payload: message.payload,
}
: {
type: exports.MessageType.Pong,
// payload is completely absent if not provided
}));
emitter.emit('pong', false, message.payload);
}
return; // ping and pongs can be received whenever
}
if (acknowledged)
return; // already connected and acknowledged
if (message.type !== exports.MessageType.ConnectionAck)
throw new Error(`First message cannot be of type ${message.type}`);
clearTimeout(connectionAckTimeout);
acknowledged = true;
emitter.emit('connected', socket, message.payload, retrying); // connected = socket opened + acknowledged
retrying = false; // future lazy connects are not retries
retries = 0; // reset the retries on connect
connected([
socket,
new Promise((_, reject) => errorOrClosed(reject)),
]);
}
catch (err) {
socket.onmessage = null; // stop reading messages as soon as reading breaks once
emitter.emit('error', err);
socket.close(exports.CloseCode.BadResponse, limitCloseReason(err instanceof Error ? err.message : new Error(err).message, 'Bad response'));
}
};
})())));
// if the provided socket is in a closing state, wait for the throw on close
if (socket.readyState === WebSocketImpl.CLOSING)
await throwOnClose;
let release = () => {
// releases this connection
};
const released = new Promise((resolve) => (release = resolve));
return [
socket,
release,
Promise.race([
// wait for
released.then(() => {
if (!locks) {
// and if no more locks are present, complete the connection
const complete = () => socket.close(1000, 'Normal Closure');
if (isFinite(lazyCloseTimeoutMs) && lazyCloseTimeoutMs > 0) {
// if the keepalive is set, allow for the specified calmdown time and
// then complete if the socket is still open.
lazyCloseTimeout = setTimeout(() => {
if (socket.readyState === WebSocketImpl.OPEN)
complete();
}, lazyCloseTimeoutMs);
}
else {
// otherwise complete immediately
complete();
}
}
}),
// or
throwOnClose,
]),
];
break;
}
case "error" /* Error */: {
if (typeof val.id !== "string") {
throw new Error(
`"${val.type}" message expects the 'id' property to be a string, but got ${extendedTypeof(
val.id
)}`
);
}
/**
* Checks the `connect` problem and evaluates if the client should retry.
*/
function shouldRetryConnectOrThrow(errOrCloseEvent) {
// some close codes are worth reporting immediately
if (isLikeCloseEvent(errOrCloseEvent) &&
(isFatalInternalCloseCode(errOrCloseEvent.code) ||
[
exports.CloseCode.InternalServerError,
exports.CloseCode.InternalClientError,
exports.CloseCode.BadRequest,
exports.CloseCode.BadResponse,
exports.CloseCode.Unauthorized,
// CloseCode.Forbidden, might grant access out after retry
exports.CloseCode.SubprotocolNotAcceptable,
// CloseCode.ConnectionInitialisationTimeout, might not time out after retry
// CloseCode.ConnectionAcknowledgementTimeout, might not time out after retry
exports.CloseCode.SubscriberAlreadyExists,
exports.CloseCode.TooManyInitialisationRequests,
// 4499, // Terminated, probably because the socket froze, we want to retry
].includes(errOrCloseEvent.code)))
throw errOrCloseEvent;
// client was disposed, no retries should proceed regardless
if (disposed)
return false;
// normal closure (possibly all subscriptions have completed)
// if no locks were acquired in the meantime, shouldnt try again
if (isLikeCloseEvent(errOrCloseEvent) && errOrCloseEvent.code === 1000)
return locks > 0;
// retries are not allowed or we tried to many times, report error
if (!retryAttempts || retries >= retryAttempts)
throw errOrCloseEvent;
// throw non-retryable connection problems
if (!shouldRetry(errOrCloseEvent))
throw errOrCloseEvent;
// @deprecated throw fatal connection problems immediately
if (isFatalConnectionProblem === null || isFatalConnectionProblem === undefined ? undefined : isFatalConnectionProblem(errOrCloseEvent))
throw errOrCloseEvent;
// looks good, start retrying
return (retrying = true);
if (!val.id) {
throw new Error(
`"${val.type}" message requires a non-empty 'id' property`
);
}
// in non-lazy (hot?) mode always hold one connection lock to persist the socket
if (!lazy) {
(async () => {
locks++;
for (;;) {
try {
const [, , throwOnClose] = await connect();
await throwOnClose; // will always throw because releaser is not used
}
catch (errOrCloseEvent) {
try {
if (!shouldRetryConnectOrThrow(errOrCloseEvent))
return;
}
catch (errOrCloseEvent) {
// report thrown error, no further retries
return onNonLazyError === null || onNonLazyError === undefined ? undefined : onNonLazyError(errOrCloseEvent);
}
}
}
})();
if (!areGraphQLErrors(val.payload)) {
throw new Error(
`"${val.type}" message expects the 'payload' property to be an array of GraphQL errors, but got ${JSON.stringify(
val.payload
)}`
);
}
function subscribe(payload, sink) {
const id = generateID(payload);
let done = false, errored = false, releaser = () => {
// for handling completions before connect
locks--;
done = true;
};
(async () => {
locks++;
for (;;) {
try {
const [socket, release, waitForReleaseOrThrowOnClose] = await connect();
// if done while waiting for connect, release the connection lock right away
if (done)
return release();
const unlisten = emitter.onMessage(id, (message) => {
switch (message.type) {
case exports.MessageType.Next: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- payload will fit type
sink.next(message.payload);
return;
}
case exports.MessageType.Error: {
(errored = true), (done = true);
sink.error(message.payload);
releaser();
return;
}
case exports.MessageType.Complete: {
done = true;
releaser(); // release completes the sink
return;
}
}
});
socket.send(stringifyMessage({
id,
type: exports.MessageType.Subscribe,
payload,
}, replacer));
releaser = () => {
if (!done && socket.readyState === WebSocketImpl.OPEN)
// if not completed already and socket is open, send complete message to server on release
socket.send(stringifyMessage({
id,
type: exports.MessageType.Complete,
}, replacer));
locks--;
done = true;
release();
};
// either the releaser will be called, connection completed and
// the promise resolved or the socket closed and the promise rejected.
// whatever happens though, we want to stop listening for messages
await waitForReleaseOrThrowOnClose.finally(unlisten);
return; // completed, shouldnt try again
}
catch (errOrCloseEvent) {
if (!shouldRetryConnectOrThrow(errOrCloseEvent))
return;
}
}
})()
.then(() => {
// delivering either an error or a complete terminates the sequence
if (!errored)
sink.complete();
}) // resolves on release or normal closure
.catch((err) => {
sink.error(err);
}); // rejects on close events and errors
break;
}
case "complete" /* Complete */: {
if (typeof val.id !== "string") {
throw new Error(
`"${val.type}" message expects the 'id' property to be a string, but got ${extendedTypeof(
val.id
)}`
);
}
if (!val.id) {
throw new Error(
`"${val.type}" message requires a non-empty 'id' property`
);
}
break;
}
default:
throw new Error(`Invalid message 'type' property "${val.type}"`);
}
return val;
}
function isMessage(val) {
try {
validateMessage(val);
return true;
} catch {
return false;
}
}
function parseMessage(data, reviver) {
return validateMessage(
typeof data === "string" ? JSON.parse(data, reviver) : data
);
}
function stringifyMessage(msg, replacer) {
validateMessage(msg);
return JSON.stringify(msg, replacer);
}
function createClient(options) {
const {
url,
connectionParams,
lazy = true,
onNonLazyError = console.error,
lazyCloseTimeout: lazyCloseTimeoutMs = 0,
keepAlive = 0,
disablePong,
connectionAckWaitTimeout = 0,
retryAttempts = 5,
retryWait = async function randomisedExponentialBackoff(retries2) {
let retryDelay = 1e3;
for (let i = 0; i < retries2; i++) {
retryDelay *= 2;
}
await new Promise(
(resolve) => setTimeout(
resolve,
retryDelay + // add random timeout from 300ms to 3s
Math.floor(Math.random() * (3e3 - 300) + 300)
)
);
},
shouldRetry = isLikeCloseEvent,
isFatalConnectionProblem,
on,
webSocketImpl,
/**
* Generates a v4 UUID to be used as the ID using `Math`
* as the random number generator. Supply your own generator
* in case you need more uniqueness.
*
* Reference: https://gist.github.com/jed/982883
*/
generateID = function generateUUID() {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
const r = Math.random() * 16 | 0, v = c == "x" ? r : r & 3 | 8;
return v.toString(16);
});
},
jsonMessageReplacer: replacer,
jsonMessageReviver: reviver
} = options;
let ws;
if (webSocketImpl) {
if (!isWebSocket(webSocketImpl)) {
throw new Error("Invalid WebSocket implementation provided");
}
ws = webSocketImpl;
} else if (typeof WebSocket !== "undefined") {
ws = WebSocket;
} else if (typeof global !== "undefined") {
ws = global.WebSocket || // @ts-expect-error: Support more browsers
global.MozWebSocket;
} else if (typeof window !== "undefined") {
ws = window.WebSocket || // @ts-expect-error: Support more browsers
window.MozWebSocket;
}
if (!ws)
throw new Error(
"WebSocket implementation missing; on Node you can `import WebSocket from 'ws';` and pass `webSocketImpl: WebSocket` to `createClient`"
);
const WebSocketImpl = ws;
const emitter = (() => {
const message = /* @__PURE__ */ (() => {
const listeners2 = {};
return {
on(id, listener) {
listeners2[id] = listener;
return () => {
// dispose only of active subscriptions
if (!done)
releaser();
delete listeners2[id];
};
},
emit(message2) {
if ("id" in message2) listeners2[message2.id]?.(message2);
}
};
})();
const listeners = {
connecting: on?.connecting ? [on.connecting] : [],
opened: on?.opened ? [on.opened] : [],
connected: on?.connected ? [on.connected] : [],
ping: on?.ping ? [on.ping] : [],
pong: on?.pong ? [on.pong] : [],
message: on?.message ? [message.emit, on.message] : [message.emit],
closed: on?.closed ? [on.closed] : [],
error: on?.error ? [on.error] : []
};
return {
onMessage: message.on,
on(event, listener) {
const l = listeners[event];
l.push(listener);
return () => {
l.splice(l.indexOf(listener), 1);
};
},
emit(event, ...args) {
for (const listener of [...listeners[event]]) {
listener(...args);
}
}
return {
on: emitter.on,
subscribe,
iterate(request) {
const pending = [];
const deferred = {
done: false,
error: null,
resolve: () => {
// noop
},
};
const dispose = subscribe(request, {
next(val) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- payload will fit type
pending.push(val);
deferred.resolve();
},
error(err) {
deferred.done = true;
deferred.error = err;
deferred.resolve();
},
complete() {
deferred.done = true;
deferred.resolve();
},
});
const iterator = (function iterator() {
return __asyncGenerator(this, arguments, function* iterator_1() {
for (;;) {
if (!pending.length) {
// only wait if there are no pending messages available
yield __await(new Promise((resolve) => (deferred.resolve = resolve)));
}
// first flush
while (pending.length) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
yield yield __await(pending.shift());
}
// then error
if (deferred.error) {
throw deferred.error;
}
// or complete
if (deferred.done) {
return yield __await(undefined);
}
}
});
})();
iterator.throw = async (err) => {
if (!deferred.done) {
deferred.done = true;
deferred.error = err;
deferred.resolve();
}
return { done: true, value: undefined };
};
iterator.return = async () => {
dispose();
return { done: true, value: undefined };
};
return iterator;
},
async dispose() {
disposed = true;
if (connecting) {
// if there is a connection, close it
const [socket] = await connecting;
socket.close(1000, 'Normal Closure');
};
})();
function errorOrClosed(cb) {
const listening = [
// errors are fatal and more critical than close events, throw them first
emitter.on("error", (err) => {
listening.forEach((unlisten) => unlisten());
cb(err);
}),
// closes can be graceful and not fatal, throw them second (if error didnt throw)
emitter.on("closed", (event) => {
listening.forEach((unlisten) => unlisten());
cb(event);
})
];
}
let connecting, locks = 0, lazyCloseTimeout, retrying = false, retries = 0, disposed = false;
async function connect() {
clearTimeout(lazyCloseTimeout);
const [socket, throwOnClose] = await (connecting ?? (connecting = new Promise(
(connected, denied) => (async () => {
if (retrying) {
await retryWait(retries);
if (!locks) {
connecting = undefined;
return denied({ code: 1e3, reason: "All Subscriptions Gone" });
}
retries++;
}
emitter.emit("connecting", retrying);
const socket2 = new WebSocketImpl(
typeof url === "function" ? await url() : url,
GRAPHQL_TRANSPORT_WS_PROTOCOL
);
let connectionAckTimeout, queuedPing;
function enqueuePing() {
if (isFinite(keepAlive) && keepAlive > 0) {
clearTimeout(queuedPing);
queuedPing = setTimeout(() => {
if (socket2.readyState === WebSocketImpl.OPEN) {
socket2.send(stringifyMessage({ type: MessageType.Ping }));
emitter.emit("ping", false, undefined);
}
},
terminate() {
if (connecting) {
// only if there is a connection
emitter.emit('closed', new TerminatedCloseEvent());
}, keepAlive);
}
}
errorOrClosed((errOrEvent) => {
connecting = undefined;
clearTimeout(connectionAckTimeout);
clearTimeout(queuedPing);
denied(errOrEvent);
if (errOrEvent instanceof TerminatedCloseEvent) {
socket2.close(4499, "Terminated");
socket2.onerror = null;
socket2.onclose = null;
}
});
socket2.onerror = (err) => emitter.emit("error", err);
socket2.onclose = (event) => emitter.emit("closed", event);
socket2.onopen = async () => {
try {
emitter.emit("opened", socket2);
const payload = typeof connectionParams === "function" ? await connectionParams() : connectionParams;
if (socket2.readyState !== WebSocketImpl.OPEN) return;
socket2.send(
stringifyMessage(
payload ? {
type: MessageType.ConnectionInit,
payload
} : {
type: MessageType.ConnectionInit
// payload is completely absent if not provided
},
replacer
)
);
if (isFinite(connectionAckWaitTimeout) && connectionAckWaitTimeout > 0) {
connectionAckTimeout = setTimeout(() => {
socket2.close(
CloseCode.ConnectionAcknowledgementTimeout,
"Connection acknowledgement timeout"
);
}, connectionAckWaitTimeout);
}
enqueuePing();
} catch (err) {
emitter.emit("error", err);
socket2.close(
CloseCode.InternalClientError,
limitCloseReason(
err instanceof Error ? err.message : String(err),
"Internal client error"
)
);
}
};
let acknowledged = false;
socket2.onmessage = ({ data }) => {
try {
const message = parseMessage(data, reviver);
emitter.emit("message", message);
if (message.type === "ping" || message.type === "pong") {
emitter.emit(message.type, true, message.payload);
if (message.type === "pong") {
enqueuePing();
} else if (!disablePong) {
socket2.send(
stringifyMessage(
message.payload ? {
type: MessageType.Pong,
payload: message.payload
} : {
type: MessageType.Pong
// payload is completely absent if not provided
}
)
);
emitter.emit("pong", false, message.payload);
}
},
};
return;
}
if (acknowledged) return;
if (message.type !== MessageType.ConnectionAck)
throw new Error(
`First message cannot be of type ${message.type}`
);
clearTimeout(connectionAckTimeout);
acknowledged = true;
emitter.emit("connected", socket2, message.payload, retrying);
retrying = false;
retries = 0;
connected([
socket2,
new Promise((_, reject) => errorOrClosed(reject))
]);
} catch (err) {
socket2.onmessage = null;
emitter.emit("error", err);
socket2.close(
CloseCode.BadResponse,
limitCloseReason(
err instanceof Error ? err.message : String(err),
"Bad response"
)
);
}
};
})()
)));
if (socket.readyState === WebSocketImpl.CLOSING) await throwOnClose;
let release = () => {
};
const released = new Promise((resolve) => release = resolve);
return [
socket,
release,
Promise.race([
// wait for
released.then(() => {
if (!locks) {
const complete = () => socket.close(1e3, "Normal Closure");
if (isFinite(lazyCloseTimeoutMs) && lazyCloseTimeoutMs > 0) {
lazyCloseTimeout = setTimeout(() => {
if (socket.readyState === WebSocketImpl.OPEN) complete();
}, lazyCloseTimeoutMs);
} else {
complete();
}
}
}),
// or
throwOnClose
])
];
}
/**
* A synthetic close event `4499: Terminated` is issued to the current to immediately
* close the connection without waiting for the one coming from `WebSocket.onclose`.
*
* Terminating is not considered fatal and a connection retry will occur as expected.
*
* Useful in cases where the WebSocket is stuck and not emitting any events;
* can happen on iOS Safari, see: https://github.com/enisdenjo/graphql-ws/discussions/290.
*/
class TerminatedCloseEvent extends Error {
constructor() {
super(...arguments);
this.name = 'TerminatedCloseEvent';
this.message = '4499: Terminated';
this.code = 4499;
this.reason = 'Terminated';
this.wasClean = false;
function shouldRetryConnectOrThrow(errOrCloseEvent) {
if (isLikeCloseEvent(errOrCloseEvent) && (isFatalInternalCloseCode(errOrCloseEvent.code) || [
CloseCode.InternalServerError,
CloseCode.InternalClientError,
CloseCode.BadRequest,
CloseCode.BadResponse,
CloseCode.Unauthorized,
// CloseCode.Forbidden, might grant access out after retry
CloseCode.SubprotocolNotAcceptable,
// CloseCode.ConnectionInitialisationTimeout, might not time out after retry
// CloseCode.ConnectionAcknowledgementTimeout, might not time out after retry
CloseCode.SubscriberAlreadyExists,
CloseCode.TooManyInitialisationRequests
// 4499, // Terminated, probably because the socket froze, we want to retry
].includes(errOrCloseEvent.code)))
throw errOrCloseEvent;
if (disposed) return false;
if (isLikeCloseEvent(errOrCloseEvent) && errOrCloseEvent.code === 1e3)
return locks > 0;
if (!retryAttempts || retries >= retryAttempts) throw errOrCloseEvent;
if (!shouldRetry(errOrCloseEvent)) throw errOrCloseEvent;
if (isFatalConnectionProblem?.(errOrCloseEvent)) throw errOrCloseEvent;
return retrying = true;
}
if (!lazy) {
(async () => {
locks++;
for (; ; ) {
try {
const [, , throwOnClose] = await connect();
await throwOnClose;
} catch (errOrCloseEvent) {
try {
if (!shouldRetryConnectOrThrow(errOrCloseEvent)) return;
} catch (errOrCloseEvent2) {
return onNonLazyError?.(errOrCloseEvent2);
}
}
}
})();
}
function isLikeCloseEvent(val) {
return isObject(val) && 'code' in val && 'reason' in val;
function subscribe(payload, sink) {
const id = generateID(payload);
let done = false, errored = false, releaser = () => {
locks--;
done = true;
};
(async () => {
locks++;
for (; ; ) {
try {
const [socket, release, waitForReleaseOrThrowOnClose] = await connect();
if (done) return release();
const unlisten = emitter.onMessage(id, (message) => {
switch (message.type) {
case MessageType.Next: {
sink.next(message.payload);
return;
}
case MessageType.Error: {
errored = true, done = true;
sink.error(message.payload);
releaser();
return;
}
case MessageType.Complete: {
done = true;
releaser();
return;
}
}
});
socket.send(
stringifyMessage(
{
id,
type: MessageType.Subscribe,
payload
},
replacer
)
);
releaser = () => {
if (!done && socket.readyState === WebSocketImpl.OPEN)
socket.send(
stringifyMessage(
{
id,
type: MessageType.Complete
},
replacer
)
);
locks--;
done = true;
release();
};
await waitForReleaseOrThrowOnClose.finally(unlisten);
return;
} catch (errOrCloseEvent) {
if (!shouldRetryConnectOrThrow(errOrCloseEvent)) return;
}
}
})().then(() => {
if (!errored) sink.complete();
}).catch((err) => {
sink.error(err);
});
return () => {
if (!done) releaser();
};
}
function isFatalInternalCloseCode(code) {
if ([
1000, // Normal Closure is not an erroneous close code
1001, // Going Away
1006, // Abnormal Closure
1005, // No Status Received
1012, // Service Restart
1013, // Try Again Later
1014, // Bad Gateway
].includes(code))
return false;
// all other internal errors are fatal
return code >= 1000 && code <= 1999;
}
function isWebSocket(val) {
return (typeof val === 'function' &&
'constructor' in val &&
'CLOSED' in val &&
'CLOSING' in val &&
'CONNECTING' in val &&
'OPEN' in val);
}
return {
on: emitter.on,
subscribe,
iterate(request) {
const pending = [];
const deferred = {
done: false,
error: null,
resolve: () => {
}
};
const dispose = subscribe(request, {
next(val) {
pending.push(val);
deferred.resolve();
},
error(err) {
deferred.done = true;
deferred.error = err;
deferred.resolve();
},
complete() {
deferred.done = true;
deferred.resolve();
}
});
const iterator = async function* iterator2() {
for (; ; ) {
if (!pending.length) {
await new Promise((resolve) => deferred.resolve = resolve);
}
while (pending.length) {
yield pending.shift();
}
if (deferred.error) {
throw deferred.error;
}
if (deferred.done) {
return;
}
}
}();
iterator.throw = async (err) => {
if (!deferred.done) {
deferred.done = true;
deferred.error = err;
deferred.resolve();
}
return { done: true, value: undefined };
};
iterator.return = async () => {
dispose();
return { done: true, value: undefined };
};
return iterator;
},
async dispose() {
disposed = true;
if (connecting) {
const [socket] = await connecting;
socket.close(1e3, "Normal Closure");
}
},
terminate() {
if (connecting) {
emitter.emit("closed", new TerminatedCloseEvent());
}
}
};
}
class TerminatedCloseEvent extends Error {
name = "TerminatedCloseEvent";
message = "4499: Terminated";
code = 4499;
reason = "Terminated";
wasClean = false;
}
function isLikeCloseEvent(val) {
return isObject(val) && "code" in val && "reason" in val;
}
function isFatalInternalCloseCode(code) {
if ([
1e3,
// Normal Closure is not an erroneous close code
1001,
// Going Away
1006,
// Abnormal Closure
1005,
// No Status Received
1012,
// Service Restart
1013,
// Try Again Later
1014
// Bad Gateway
].includes(code))
return false;
return code >= 1e3 && code <= 1999;
}
function isWebSocket(val) {
return typeof val === "function" && "constructor" in val && "CLOSED" in val && "CLOSING" in val && "CONNECTING" in val && "OPEN" in val;
}
exports.DEPRECATED_GRAPHQL_WS_PROTOCOL = DEPRECATED_GRAPHQL_WS_PROTOCOL;
exports.GRAPHQL_TRANSPORT_WS_PROTOCOL = GRAPHQL_TRANSPORT_WS_PROTOCOL;
exports.TerminatedCloseEvent = TerminatedCloseEvent;
exports.createClient = createClient;
exports.isMessage = isMessage;
exports.parseMessage = parseMessage;
exports.stringifyMessage = stringifyMessage;
exports.validateMessage = validateMessage;
exports.CloseCode = CloseCode;
exports.DEPRECATED_GRAPHQL_WS_PROTOCOL = DEPRECATED_GRAPHQL_WS_PROTOCOL;
exports.GRAPHQL_TRANSPORT_WS_PROTOCOL = GRAPHQL_TRANSPORT_WS_PROTOCOL;
exports.MessageType = MessageType;
exports.TerminatedCloseEvent = TerminatedCloseEvent;
exports.createClient = createClient;
exports.isMessage = isMessage;
exports.parseMessage = parseMessage;
exports.stringifyMessage = stringifyMessage;
exports.validateMessage = validateMessage;
}));

@@ -1,1 +0,1 @@

!function(e,o){"object"==typeof exports&&"undefined"!=typeof module?o(exports):"function"==typeof define&&define.amd?define(["exports"],o):o((e="undefined"!=typeof globalThis?globalThis:e||self).graphqlWs={})}(this,(function(e){"use strict";function o(e){return this instanceof o?(this.v=e,this):new o(e)}function t(e,t,r){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var n,s=r.apply(e,t||[]),i=[];return n=Object.create(("function"==typeof AsyncIterator?AsyncIterator:Object).prototype),a("next"),a("throw"),a("return",(function(e){return function(o){return Promise.resolve(o).then(e,p)}})),n[Symbol.asyncIterator]=function(){return this},n;function a(e,o){s[e]&&(n[e]=function(o){return new Promise((function(t,r){i.push([e,o,t,r])>1||c(e,o)}))},o&&(n[e]=o(n[e])))}function c(e,t){try{(r=s[e](t)).value instanceof o?Promise.resolve(r.value.v).then(l,p):d(i[0][2],r)}catch(e){d(i[0][3],e)}var r}function l(e){c("next",e)}function p(e){c("throw",e)}function d(e,o){e(o),i.shift(),i.length&&c(i[0][0],i[0][1])}}function r(e){return null===e?"null":Array.isArray(e)?"array":typeof e}function n(e){return"object"===r(e)}function s(e,o){return e.length<124?e:o}"function"==typeof SuppressedError&&SuppressedError;const i="graphql-transport-ws";var a,c;function l(o){if(!n(o))throw new Error(`Message is expected to be an object, but got ${r(o)}`);if(!o.type)throw new Error("Message is missing the 'type' property");if("string"!=typeof o.type)throw new Error(`Message is expects the 'type' property to be a string, but got ${r(o.type)}`);switch(o.type){case e.MessageType.ConnectionInit:case e.MessageType.ConnectionAck:case e.MessageType.Ping:case e.MessageType.Pong:if(null!=o.payload&&!n(o.payload))throw new Error(`"${o.type}" message expects the 'payload' property to be an object or nullish or missing, but got "${o.payload}"`);break;case e.MessageType.Subscribe:if("string"!=typeof o.id)throw new Error(`"${o.type}" message expects the 'id' property to be a string, but got ${r(o.id)}`);if(!o.id)throw new Error(`"${o.type}" message requires a non-empty 'id' property`);if(!n(o.payload))throw new Error(`"${o.type}" message expects the 'payload' property to be an object, but got ${r(o.payload)}`);if("string"!=typeof o.payload.query)throw new Error(`"${o.type}" message payload expects the 'query' property to be a string, but got ${r(o.payload.query)}`);if(null!=o.payload.variables&&!n(o.payload.variables))throw new Error(`"${o.type}" message payload expects the 'variables' property to be a an object or nullish or missing, but got ${r(o.payload.variables)}`);if(null!=o.payload.operationName&&"string"!==r(o.payload.operationName))throw new Error(`"${o.type}" message payload expects the 'operationName' property to be a string or nullish or missing, but got ${r(o.payload.operationName)}`);if(null!=o.payload.extensions&&!n(o.payload.extensions))throw new Error(`"${o.type}" message payload expects the 'extensions' property to be a an object or nullish or missing, but got ${r(o.payload.extensions)}`);break;case e.MessageType.Next:if("string"!=typeof o.id)throw new Error(`"${o.type}" message expects the 'id' property to be a string, but got ${r(o.id)}`);if(!o.id)throw new Error(`"${o.type}" message requires a non-empty 'id' property`);if(!n(o.payload))throw new Error(`"${o.type}" message expects the 'payload' property to be an object, but got ${r(o.payload)}`);break;case e.MessageType.Error:if("string"!=typeof o.id)throw new Error(`"${o.type}" message expects the 'id' property to be a string, but got ${r(o.id)}`);if(!o.id)throw new Error(`"${o.type}" message requires a non-empty 'id' property`);if(t=o.payload,!(Array.isArray(t)&&t.length>0&&t.every((e=>"message"in e))))throw new Error(`"${o.type}" message expects the 'payload' property to be an array of GraphQL errors, but got ${JSON.stringify(o.payload)}`);break;case e.MessageType.Complete:if("string"!=typeof o.id)throw new Error(`"${o.type}" message expects the 'id' property to be a string, but got ${r(o.id)}`);if(!o.id)throw new Error(`"${o.type}" message requires a non-empty 'id' property`);break;default:throw new Error(`Invalid message 'type' property "${o.type}"`)}var t;return o}function p(e,o){return l("string"==typeof e?JSON.parse(e,o):e)}function d(e,o){return l(e),JSON.stringify(e,o)}e.CloseCode=void 0,(a=e.CloseCode||(e.CloseCode={}))[a.InternalServerError=4500]="InternalServerError",a[a.InternalClientError=4005]="InternalClientError",a[a.BadRequest=4400]="BadRequest",a[a.BadResponse=4004]="BadResponse",a[a.Unauthorized=4401]="Unauthorized",a[a.Forbidden=4403]="Forbidden",a[a.SubprotocolNotAcceptable=4406]="SubprotocolNotAcceptable",a[a.ConnectionInitialisationTimeout=4408]="ConnectionInitialisationTimeout",a[a.ConnectionAcknowledgementTimeout=4504]="ConnectionAcknowledgementTimeout",a[a.SubscriberAlreadyExists=4409]="SubscriberAlreadyExists",a[a.TooManyInitialisationRequests=4429]="TooManyInitialisationRequests",e.MessageType=void 0,(c=e.MessageType||(e.MessageType={})).ConnectionInit="connection_init",c.ConnectionAck="connection_ack",c.Ping="ping",c.Pong="pong",c.Subscribe="subscribe",c.Next="next",c.Error="error",c.Complete="complete";class y extends Error{constructor(){super(...arguments),this.name="TerminatedCloseEvent",this.message="4499: Terminated",this.code=4499,this.reason="Terminated",this.wasClean=!1}}function u(e){return n(e)&&"code"in e&&"reason"in e}e.DEPRECATED_GRAPHQL_WS_PROTOCOL="graphql-ws",e.GRAPHQL_TRANSPORT_WS_PROTOCOL=i,e.TerminatedCloseEvent=y,e.createClient=function(r){const{url:n,connectionParams:a,lazy:c=!0,onNonLazyError:l=console.error,lazyCloseTimeout:g=0,keepAlive:f=0,disablePong:m,connectionAckWaitTimeout:h=0,retryAttempts:w=5,retryWait:b=async function(e){let o=1e3;for(let t=0;t<e;t++)o*=2;await new Promise((e=>setTimeout(e,o+Math.floor(2700*Math.random()+300))))},shouldRetry:x=u,isFatalConnectionProblem:C,on:v,webSocketImpl:E,generateID:T=function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(e=>{const o=16*Math.random()|0;return("x"==e?o:3&o|8).toString(16)}))},jsonMessageReplacer:S,jsonMessageReviver:M}=r;let $;if(E){if(!("function"==typeof(I=E)&&"constructor"in I&&"CLOSED"in I&&"CLOSING"in I&&"CONNECTING"in I&&"OPEN"in I))throw new Error("Invalid WebSocket implementation provided");$=E}else"undefined"!=typeof WebSocket?$=WebSocket:"undefined"!=typeof global?$=global.WebSocket||global.MozWebSocket:"undefined"!=typeof window&&($=window.WebSocket||window.MozWebSocket);var I;if(!$)throw new Error("WebSocket implementation missing; on Node you can `import WebSocket from 'ws';` and pass `webSocketImpl: WebSocket` to `createClient`");const P=$,N=(()=>{const e=(()=>{const e={};return{on:(o,t)=>(e[o]=t,()=>{delete e[o]}),emit(o){var t;"id"in o&&(null===(t=e[o.id])||void 0===t||t.call(e,o))}}})(),o={connecting:(null==v?void 0:v.connecting)?[v.connecting]:[],opened:(null==v?void 0:v.opened)?[v.opened]:[],connected:(null==v?void 0:v.connected)?[v.connected]:[],ping:(null==v?void 0:v.ping)?[v.ping]:[],pong:(null==v?void 0:v.pong)?[v.pong]:[],message:(null==v?void 0:v.message)?[e.emit,v.message]:[e.emit],closed:(null==v?void 0:v.closed)?[v.closed]:[],error:(null==v?void 0:v.error)?[v.error]:[]};return{onMessage:e.on,on(e,t){const r=o[e];return r.push(t),()=>{r.splice(r.indexOf(t),1)}},emit(e,...t){for(const r of[...o[e]])r(...t)}}})();function k(e){const o=[N.on("error",(t=>{o.forEach((e=>e())),e(t)})),N.on("closed",(t=>{o.forEach((e=>e())),e(t)}))]}let A,O,R=0,q=!1,W=0,j=!1;async function L(){clearTimeout(O);const[o,t]=await(null!=A?A:A=new Promise(((o,t)=>(async()=>{if(q){if(await b(W),!R)return A=void 0,t({code:1e3,reason:"All Subscriptions Gone"});W++}N.emit("connecting",q);const r=new P("function"==typeof n?await n():n,i);let c,l;function u(){isFinite(f)&&f>0&&(clearTimeout(l),l=setTimeout((()=>{r.readyState===P.OPEN&&(r.send(d({type:e.MessageType.Ping})),N.emit("ping",!1,void 0))}),f))}k((e=>{A=void 0,clearTimeout(c),clearTimeout(l),t(e),e instanceof y&&(r.close(4499,"Terminated"),r.onerror=null,r.onclose=null)})),r.onerror=e=>N.emit("error",e),r.onclose=e=>N.emit("closed",e),r.onopen=async()=>{try{N.emit("opened",r);const o="function"==typeof a?await a():a;if(r.readyState!==P.OPEN)return;r.send(d(o?{type:e.MessageType.ConnectionInit,payload:o}:{type:e.MessageType.ConnectionInit},S)),isFinite(h)&&h>0&&(c=setTimeout((()=>{r.close(e.CloseCode.ConnectionAcknowledgementTimeout,"Connection acknowledgement timeout")}),h)),u()}catch(o){N.emit("error",o),r.close(e.CloseCode.InternalClientError,s(o instanceof Error?o.message:new Error(o).message,"Internal client error"))}};let g=!1;r.onmessage=({data:t})=>{try{const n=p(t,M);if(N.emit("message",n),"ping"===n.type||"pong"===n.type)return N.emit(n.type,!0,n.payload),void("pong"===n.type?u():m||(r.send(d(n.payload?{type:e.MessageType.Pong,payload:n.payload}:{type:e.MessageType.Pong})),N.emit("pong",!1,n.payload)));if(g)return;if(n.type!==e.MessageType.ConnectionAck)throw new Error(`First message cannot be of type ${n.type}`);clearTimeout(c),g=!0,N.emit("connected",r,n.payload,q),q=!1,W=0,o([r,new Promise(((e,o)=>k(o)))])}catch(o){r.onmessage=null,N.emit("error",o),r.close(e.CloseCode.BadResponse,s(o instanceof Error?o.message:new Error(o).message,"Bad response"))}}})())));o.readyState===P.CLOSING&&await t;let r=()=>{};const c=new Promise((e=>r=e));return[o,r,Promise.race([c.then((()=>{if(!R){const e=()=>o.close(1e3,"Normal Closure");isFinite(g)&&g>0?O=setTimeout((()=>{o.readyState===P.OPEN&&e()}),g):e()}})),t])]}function z(o){if(u(o)&&(t=o.code,![1e3,1001,1006,1005,1012,1013,1014].includes(t)&&t>=1e3&&t<=1999||[e.CloseCode.InternalServerError,e.CloseCode.InternalClientError,e.CloseCode.BadRequest,e.CloseCode.BadResponse,e.CloseCode.Unauthorized,e.CloseCode.SubprotocolNotAcceptable,e.CloseCode.SubscriberAlreadyExists,e.CloseCode.TooManyInitialisationRequests].includes(o.code)))throw o;var t;if(j)return!1;if(u(o)&&1e3===o.code)return R>0;if(!w||W>=w)throw o;if(!x(o))throw o;if(null==C?void 0:C(o))throw o;return q=!0}function B(o,t){const r=T(o);let n=!1,s=!1,i=()=>{R--,n=!0};return(async()=>{for(R++;;)try{const[a,c,l]=await L();if(n)return c();const p=N.onMessage(r,(o=>{switch(o.type){case e.MessageType.Next:return void t.next(o.payload);case e.MessageType.Error:return s=!0,n=!0,t.error(o.payload),void i();case e.MessageType.Complete:return n=!0,void i()}}));return a.send(d({id:r,type:e.MessageType.Subscribe,payload:o},S)),i=()=>{n||a.readyState!==P.OPEN||a.send(d({id:r,type:e.MessageType.Complete},S)),R--,n=!0,c()},void await l.finally(p)}catch(e){if(!z(e))return}})().then((()=>{s||t.complete()})).catch((e=>{t.error(e)})),()=>{n||i()}}return c||(async()=>{for(R++;;)try{const[,,e]=await L();await e}catch(e){try{if(!z(e))return}catch(e){return null==l?void 0:l(e)}}})(),{on:N.on,subscribe:B,iterate(e){const r=[],n={done:!1,error:null,resolve:()=>{}},s=B(e,{next(e){r.push(e),n.resolve()},error(e){n.done=!0,n.error=e,n.resolve()},complete(){n.done=!0,n.resolve()}}),i=function(){return t(this,arguments,(function*(){for(;;){for(r.length||(yield o(new Promise((e=>n.resolve=e))));r.length;)yield yield o(r.shift());if(n.error)throw n.error;if(n.done)return yield o(void 0)}}))}();return i.throw=async e=>(n.done||(n.done=!0,n.error=e,n.resolve()),{done:!0,value:void 0}),i.return=async()=>(s(),{done:!0,value:void 0}),i},async dispose(){if(j=!0,A){const[e]=await A;e.close(1e3,"Normal Closure")}},terminate(){A&&N.emit("closed",new y)}}},e.isMessage=function(e){try{return l(e),!0}catch(e){return!1}},e.parseMessage=p,e.stringifyMessage=d,e.validateMessage=l}));
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).graphqlWs={})}(this,(function(e){"use strict";function t(e){return null===e?"null":Array.isArray(e)?"array":typeof e}function o(e){return"object"===t(e)}function r(e,t){return e.length<124?e:t}const n="graphql-transport-ws";var i=(e=>(e[e.InternalServerError=4500]="InternalServerError",e[e.InternalClientError=4005]="InternalClientError",e[e.BadRequest=4400]="BadRequest",e[e.BadResponse=4004]="BadResponse",e[e.Unauthorized=4401]="Unauthorized",e[e.Forbidden=4403]="Forbidden",e[e.SubprotocolNotAcceptable=4406]="SubprotocolNotAcceptable",e[e.ConnectionInitialisationTimeout=4408]="ConnectionInitialisationTimeout",e[e.ConnectionAcknowledgementTimeout=4504]="ConnectionAcknowledgementTimeout",e[e.SubscriberAlreadyExists=4409]="SubscriberAlreadyExists",e[e.TooManyInitialisationRequests=4429]="TooManyInitialisationRequests",e))(i||{}),a=(e=>(e.ConnectionInit="connection_init",e.ConnectionAck="connection_ack",e.Ping="ping",e.Pong="pong",e.Subscribe="subscribe",e.Next="next",e.Error="error",e.Complete="complete",e))(a||{});function s(e){if(!o(e))throw new Error(`Message is expected to be an object, but got ${t(e)}`);if(!e.type)throw new Error("Message is missing the 'type' property");if("string"!=typeof e.type)throw new Error(`Message is expects the 'type' property to be a string, but got ${t(e.type)}`);switch(e.type){case"connection_init":case"connection_ack":case"ping":case"pong":if(null!=e.payload&&!o(e.payload))throw new Error(`"${e.type}" message expects the 'payload' property to be an object or nullish or missing, but got "${e.payload}"`);break;case"subscribe":if("string"!=typeof e.id)throw new Error(`"${e.type}" message expects the 'id' property to be a string, but got ${t(e.id)}`);if(!e.id)throw new Error(`"${e.type}" message requires a non-empty 'id' property`);if(!o(e.payload))throw new Error(`"${e.type}" message expects the 'payload' property to be an object, but got ${t(e.payload)}`);if("string"!=typeof e.payload.query)throw new Error(`"${e.type}" message payload expects the 'query' property to be a string, but got ${t(e.payload.query)}`);if(null!=e.payload.variables&&!o(e.payload.variables))throw new Error(`"${e.type}" message payload expects the 'variables' property to be a an object or nullish or missing, but got ${t(e.payload.variables)}`);if(null!=e.payload.operationName&&"string"!==t(e.payload.operationName))throw new Error(`"${e.type}" message payload expects the 'operationName' property to be a string or nullish or missing, but got ${t(e.payload.operationName)}`);if(null!=e.payload.extensions&&!o(e.payload.extensions))throw new Error(`"${e.type}" message payload expects the 'extensions' property to be a an object or nullish or missing, but got ${t(e.payload.extensions)}`);break;case"next":if("string"!=typeof e.id)throw new Error(`"${e.type}" message expects the 'id' property to be a string, but got ${t(e.id)}`);if(!e.id)throw new Error(`"${e.type}" message requires a non-empty 'id' property`);if(!o(e.payload))throw new Error(`"${e.type}" message expects the 'payload' property to be an object, but got ${t(e.payload)}`);break;case"error":if("string"!=typeof e.id)throw new Error(`"${e.type}" message expects the 'id' property to be a string, but got ${t(e.id)}`);if(!e.id)throw new Error(`"${e.type}" message requires a non-empty 'id' property`);if(r=e.payload,!(Array.isArray(r)&&r.length>0&&r.every((e=>"message"in e))))throw new Error(`"${e.type}" message expects the 'payload' property to be an array of GraphQL errors, but got ${JSON.stringify(e.payload)}`);break;case"complete":if("string"!=typeof e.id)throw new Error(`"${e.type}" message expects the 'id' property to be a string, but got ${t(e.id)}`);if(!e.id)throw new Error(`"${e.type}" message requires a non-empty 'id' property`);break;default:throw new Error(`Invalid message 'type' property "${e.type}"`)}var r;return e}function c(e,t){return s("string"==typeof e?JSON.parse(e,t):e)}function p(e,t){return s(e),JSON.stringify(e,t)}class l extends Error{name="TerminatedCloseEvent";message="4499: Terminated";code=4499;reason="Terminated";wasClean=!1}function d(e){return o(e)&&"code"in e&&"reason"in e}e.CloseCode=i,e.DEPRECATED_GRAPHQL_WS_PROTOCOL="graphql-ws",e.GRAPHQL_TRANSPORT_WS_PROTOCOL=n,e.MessageType=a,e.TerminatedCloseEvent=l,e.createClient=function(e){const{url:t,connectionParams:o,lazy:s=!0,onNonLazyError:y=console.error,lazyCloseTimeout:u=0,keepAlive:g=0,disablePong:m,connectionAckWaitTimeout:f=0,retryAttempts:b=5,retryWait:w=async function(e){let t=1e3;for(let o=0;o<e;o++)t*=2;await new Promise((e=>setTimeout(e,t+Math.floor(2700*Math.random()+300))))},shouldRetry:h=d,isFatalConnectionProblem:x,on:E,webSocketImpl:S,generateID:v=function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(e=>{const t=16*Math.random()|0;return("x"==e?t:3&t|8).toString(16)}))},jsonMessageReplacer:C,jsonMessageReviver:T}=e;let $;if(S){if(!("function"==typeof(k=S)&&"constructor"in k&&"CLOSED"in k&&"CLOSING"in k&&"CONNECTING"in k&&"OPEN"in k))throw new Error("Invalid WebSocket implementation provided");$=S}else"undefined"!=typeof WebSocket?$=WebSocket:"undefined"!=typeof global?$=global.WebSocket||global.MozWebSocket:"undefined"!=typeof window&&($=window.WebSocket||window.MozWebSocket);var k;if(!$)throw new Error("WebSocket implementation missing; on Node you can `import WebSocket from 'ws';` and pass `webSocketImpl: WebSocket` to `createClient`");const N=$,P=(()=>{const e=(()=>{const e={};return{on:(t,o)=>(e[t]=o,()=>{delete e[t]}),emit(t){"id"in t&&e[t.id]?.(t)}}})(),t={connecting:E?.connecting?[E.connecting]:[],opened:E?.opened?[E.opened]:[],connected:E?.connected?[E.connected]:[],ping:E?.ping?[E.ping]:[],pong:E?.pong?[E.pong]:[],message:E?.message?[e.emit,E.message]:[e.emit],closed:E?.closed?[E.closed]:[],error:E?.error?[E.error]:[]};return{onMessage:e.on,on(e,o){const r=t[e];return r.push(o),()=>{r.splice(r.indexOf(o),1)}},emit(e,...o){for(const r of[...t[e]])r(...o)}}})();function I(e){const t=[P.on("error",(o=>{t.forEach((e=>e())),e(o)})),P.on("closed",(o=>{t.forEach((e=>e())),e(o)}))]}let A,M,O=0,R=!1,q=0,W=!1;async function j(){clearTimeout(M);const[e,s]=await(A??(A=new Promise(((e,s)=>(async()=>{if(R){if(await w(q),!O)return A=void 0,s({code:1e3,reason:"All Subscriptions Gone"});q++}P.emit("connecting",R);const d=new N("function"==typeof t?await t():t,n);let y,u;function b(){isFinite(g)&&g>0&&(clearTimeout(u),u=setTimeout((()=>{d.readyState===N.OPEN&&(d.send(p({type:a.Ping})),P.emit("ping",!1,void 0))}),g))}I((e=>{A=void 0,clearTimeout(y),clearTimeout(u),s(e),e instanceof l&&(d.close(4499,"Terminated"),d.onerror=null,d.onclose=null)})),d.onerror=e=>P.emit("error",e),d.onclose=e=>P.emit("closed",e),d.onopen=async()=>{try{P.emit("opened",d);const e="function"==typeof o?await o():o;if(d.readyState!==N.OPEN)return;d.send(p(e?{type:a.ConnectionInit,payload:e}:{type:a.ConnectionInit},C)),isFinite(f)&&f>0&&(y=setTimeout((()=>{d.close(i.ConnectionAcknowledgementTimeout,"Connection acknowledgement timeout")}),f)),b()}catch(e){P.emit("error",e),d.close(i.InternalClientError,r(e instanceof Error?e.message:String(e),"Internal client error"))}};let h=!1;d.onmessage=({data:t})=>{try{const o=c(t,T);if(P.emit("message",o),"ping"===o.type||"pong"===o.type)return P.emit(o.type,!0,o.payload),void("pong"===o.type?b():m||(d.send(p(o.payload?{type:a.Pong,payload:o.payload}:{type:a.Pong})),P.emit("pong",!1,o.payload)));if(h)return;if(o.type!==a.ConnectionAck)throw new Error(`First message cannot be of type ${o.type}`);clearTimeout(y),h=!0,P.emit("connected",d,o.payload,R),R=!1,q=0,e([d,new Promise(((e,t)=>I(t)))])}catch(e){d.onmessage=null,P.emit("error",e),d.close(i.BadResponse,r(e instanceof Error?e.message:String(e),"Bad response"))}}})()))));e.readyState===N.CLOSING&&await s;let d=()=>{};const y=new Promise((e=>d=e));return[e,d,Promise.race([y.then((()=>{if(!O){const t=()=>e.close(1e3,"Normal Closure");isFinite(u)&&u>0?M=setTimeout((()=>{e.readyState===N.OPEN&&t()}),u):t()}})),s])]}function _(e){if(d(e)&&(t=e.code,![1e3,1001,1006,1005,1012,1013,1014].includes(t)&&t>=1e3&&t<=1999||[i.InternalServerError,i.InternalClientError,i.BadRequest,i.BadResponse,i.Unauthorized,i.SubprotocolNotAcceptable,i.SubscriberAlreadyExists,i.TooManyInitialisationRequests].includes(e.code)))throw e;var t;if(W)return!1;if(d(e)&&1e3===e.code)return O>0;if(!b||q>=b)throw e;if(!h(e))throw e;if(x?.(e))throw e;return R=!0}function L(e,t){const o=v(e);let r=!1,n=!1,i=()=>{O--,r=!0};return(async()=>{for(O++;;)try{const[s,c,l]=await j();if(r)return c();const d=P.onMessage(o,(e=>{switch(e.type){case a.Next:return void t.next(e.payload);case a.Error:return n=!0,r=!0,t.error(e.payload),void i();case a.Complete:return r=!0,void i()}}));return s.send(p({id:o,type:a.Subscribe,payload:e},C)),i=()=>{r||s.readyState!==N.OPEN||s.send(p({id:o,type:a.Complete},C)),O--,r=!0,c()},void await l.finally(d)}catch(e){if(!_(e))return}})().then((()=>{n||t.complete()})).catch((e=>{t.error(e)})),()=>{r||i()}}return s||(async()=>{for(O++;;)try{const[,,e]=await j();await e}catch(e){try{if(!_(e))return}catch(e){return y?.(e)}}})(),{on:P.on,subscribe:L,iterate(e){const t=[],o={done:!1,error:null,resolve:()=>{}},r=L(e,{next(e){t.push(e),o.resolve()},error(e){o.done=!0,o.error=e,o.resolve()},complete(){o.done=!0,o.resolve()}}),n=async function*(){for(;;){for(t.length||await new Promise((e=>o.resolve=e));t.length;)yield t.shift();if(o.error)throw o.error;if(o.done)return}}();return n.throw=async e=>(o.done||(o.done=!0,o.error=e,o.resolve()),{done:!0,value:void 0}),n.return=async()=>(r(),{done:!0,value:void 0}),n},async dispose(){if(W=!0,A){const[e]=await A;e.close(1e3,"Normal Closure")}},terminate(){A&&P.emit("closed",new l)}}},e.isMessage=function(e){try{return s(e),!0}catch{return!1}},e.parseMessage=c,e.stringifyMessage=p,e.validateMessage=s}));

Sorry, the diff of this file is not supported yet