graphql-ws
Advanced tools
Comparing version 2.0.0 to 2.0.1
@@ -0,1 +1,8 @@ | ||
## [2.0.1](https://github.com/enisdenjo/graphql-ws/compare/v2.0.0...v2.0.1) (2020-12-03) | ||
### Bug Fixes | ||
* **client:** Close event's `wasClean` is not necessary ([2c65f0e](https://github.com/enisdenjo/graphql-ws/commit/2c65f0ee91a6372a9c2935183d9be0be50f40663)), closes [#81](https://github.com/enisdenjo/graphql-ws/issues/81) | ||
# [2.0.0](https://github.com/enisdenjo/graphql-ws/compare/v1.14.0...v2.0.0) (2020-11-20) | ||
@@ -2,0 +9,0 @@ |
@@ -235,3 +235,3 @@ "use strict"; | ||
// throw non `CloseEvent`s immediately, something else is wrong | ||
if (!isCloseEvent(errOrCloseEvent)) { | ||
if (!isLikeCloseEvent(errOrCloseEvent)) { | ||
throw errOrCloseEvent; | ||
@@ -391,4 +391,4 @@ } | ||
exports.createClient = createClient; | ||
function isCloseEvent(val) { | ||
return utils_1.isObject(val) && 'code' in val && 'reason' in val && 'wasClean' in val; | ||
function isLikeCloseEvent(val) { | ||
return utils_1.isObject(val) && 'code' in val && 'reason' in val; | ||
} | ||
@@ -395,0 +395,0 @@ function isWebSocket(val) { |
{ | ||
"name": "graphql-ws", | ||
"version": "2.0.0", | ||
"version": "2.0.1", | ||
"description": "Coherent, zero-dependency, lazy, simple, GraphQL over WebSocket Protocol compliant server and client", | ||
@@ -54,31 +54,31 @@ "keywords": [ | ||
"devDependencies": { | ||
"@babel/core": "^7.12.3", | ||
"@babel/core": "^7.12.9", | ||
"@babel/plugin-proposal-class-properties": "^7.12.1", | ||
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1", | ||
"@babel/plugin-proposal-object-rest-spread": "^7.12.1", | ||
"@babel/plugin-proposal-optional-chaining": "^7.12.1", | ||
"@babel/preset-env": "^7.12.1", | ||
"@babel/preset-typescript": "^7.12.1", | ||
"@rollup/plugin-typescript": "^6.1.0", | ||
"@babel/plugin-proposal-optional-chaining": "^7.12.7", | ||
"@babel/preset-env": "^7.12.7", | ||
"@babel/preset-typescript": "^7.12.7", | ||
"@rollup/plugin-typescript": "^8.0.0", | ||
"@semantic-release/changelog": "^5.0.1", | ||
"@semantic-release/git": "^9.0.0", | ||
"@types/jest": "^26.0.15", | ||
"@types/jest": "^26.0.16", | ||
"@types/ws": "^7.4.0", | ||
"@typescript-eslint/eslint-plugin": "^4.7.0", | ||
"@typescript-eslint/parser": "^4.7.0", | ||
"@typescript-eslint/eslint-plugin": "^4.9.0", | ||
"@typescript-eslint/parser": "^4.9.0", | ||
"babel-jest": "^26.6.3", | ||
"eslint": "^7.13.0", | ||
"eslint": "^7.14.0", | ||
"eslint-config-prettier": "^6.15.0", | ||
"eslint-plugin-prettier": "^3.1.4", | ||
"eslint-plugin-prettier": "^3.2.0", | ||
"graphql": "^15.4.0", | ||
"jest": "^26.6.3", | ||
"prettier": "^2.1.2", | ||
"rollup": "^2.33.1", | ||
"prettier": "^2.2.1", | ||
"rollup": "^2.34.1", | ||
"rollup-plugin-terser": "^7.0.2", | ||
"semantic-release": "^17.2.2", | ||
"semantic-release": "^17.3.0", | ||
"typedoc": "^0.19.2", | ||
"typedoc-plugin-markdown": "^3.0.11", | ||
"typescript": "^4.0.5", | ||
"typescript": "^4.1.2", | ||
"ws": "^7.4.0" | ||
} | ||
} |
138
README.md
@@ -85,3 +85,3 @@ <div align="center"> | ||
```ts | ||
import { createClient } from 'graphql-ws/lib/use/ws'; | ||
import { createClient } from 'graphql-ws'; | ||
@@ -140,3 +140,3 @@ const client = createClient({ | ||
```ts | ||
import { createClient, SubscribePayload } from 'graphql-ws/lib/use/ws'; | ||
import { createClient, SubscribePayload } from 'graphql-ws'; | ||
@@ -178,3 +178,3 @@ const client = createClient({ | ||
```ts | ||
import { createClient, SubscribePayload } from 'graphql-ws/lib/use/ws'; | ||
import { createClient, SubscribePayload } from 'graphql-ws'; | ||
@@ -290,3 +290,3 @@ const client = createClient({ | ||
} from 'relay-runtime'; | ||
import { createClient } from 'graphql-ws/lib/use/ws'; | ||
import { createClient } from 'graphql-ws'; | ||
@@ -356,3 +356,3 @@ const subscriptionsClient = createClient({ | ||
import { createClient, defaultExchanges, subscriptionExchange } from 'urql'; | ||
import { createClient as createWSClient } from 'graphql-ws/lib/use/ws'; | ||
import { createClient as createWSClient } from 'graphql-ws'; | ||
@@ -391,3 +391,3 @@ const wsClient = createWSClient({ | ||
import { print, GraphQLError } from 'graphql'; | ||
import { createClient, ClientOptions, Client } from 'graphql-ws/lib/use/ws'; | ||
import { createClient, ClientOptions, Client } from 'graphql-ws'; | ||
@@ -533,15 +533,21 @@ class WebSocketLink extends ApolloLink { | ||
wsServer.on('connection', (socket, request) => { | ||
// a new socket opened, let graphql-ws take over | ||
const closed = server.opened( | ||
{ | ||
protocol: socket.protocol, | ||
protocol: socket.protocol, // will be validated | ||
send: (data) => | ||
new Promise((resolve, reject) => { | ||
socket.send(data, (err) => (err ? reject(err) : resolve())); | ||
}), | ||
close: (code, reason) => socket.close(code, reason), | ||
}), // control your data flow by timing the promise resole | ||
close: (code, reason) => socket.close(code, reason), // there are protocol standard closures | ||
onMessage: (cb) => | ||
socket.on('message', async (event) => { | ||
try { | ||
// wait for the the operation to complete | ||
// - if query/mutation, waits for result | ||
// - if subscription, waits for complete | ||
await cb(event.toString()); | ||
} catch (err) { | ||
// all errors that could be thrown during the | ||
// execution of operations, will be caught here | ||
socket.close(1011, err.message); | ||
@@ -551,10 +557,8 @@ } | ||
}, | ||
// pass values to the `extra` field in the context | ||
{ socket, request }, | ||
); | ||
socket.once('close', () => { | ||
if (pongWait) clearTimeout(pongWait); | ||
if (pingInterval) clearInterval(pingInterval); | ||
closed(); | ||
}); | ||
// notify server that the socket closed | ||
socket.once('close', () => closed()); | ||
}); | ||
@@ -565,2 +569,103 @@ ``` | ||
<details id="ws-auth-handling"> | ||
<summary><a href="#ws-auth-handling">🔗</a> Server usage with <a href="https://github.com/websockets/ws">ws</a> and custom auth handling</summary> | ||
```ts | ||
// check extended implementation at `{ useServer } from 'graphql-ws/lib/use/ws'` | ||
import http from 'http'; | ||
import ws from 'ws'; // yarn add ws | ||
import { makeServer } from '../index'; | ||
import { execute, subscribe } from 'graphql'; | ||
import { schema } from 'my-graphql-schema'; | ||
import { validate } from 'my-auth'; | ||
// extra in the context | ||
interface Extra { | ||
readonly request: http.IncomingMessage; | ||
} | ||
// your custom auth | ||
class Forbidden extends Error {} | ||
function handleAuth(request: http.IncomingMessage) { | ||
// do your auth on every subscription connect | ||
const good = validate(request.headers['authorization']); | ||
// or const { iDontApprove } = session(request.cookies); | ||
if (!good) { | ||
// throw a custom error to be handled | ||
throw new Forbidden(':('); | ||
} | ||
} | ||
// make | ||
const server = makeServer<Extra>({ | ||
schema, | ||
execute, | ||
subscribe, | ||
onConnect: async (ctx) => { | ||
// do your auth on every connect | ||
await handleAuth(ctx.extra.request); | ||
}, | ||
onSubscribe: async (ctx) => { | ||
// or maybe on every subscribe | ||
await handleAuth(ctx.extra.request); | ||
}, | ||
onNext: async (ctx) => { | ||
// haha why not on every result emission? | ||
await handleAuth(ctx.extra.request); | ||
}, | ||
}); | ||
// create websocket server | ||
const wsServer = new ws.Server({ | ||
server, | ||
path: '/graphql', | ||
}); | ||
// implement | ||
wsServer.on('connection', (socket, request) => { | ||
// you may even reject the connection without ever reaching the lib | ||
// return socket.close(4403, 'Forbidden'); | ||
// pass the connection to graphql-ws | ||
const closed = server.opened( | ||
{ | ||
protocol: socket.protocol, // will be validated | ||
send: (data) => | ||
new Promise((resolve, reject) => { | ||
// control your data flow by timing the promise resolve | ||
socket.send(data, (err) => (err ? reject(err) : resolve())); | ||
}), | ||
close: (code, reason) => socket.close(code, reason), // for standard closures | ||
onMessage: (cb) => { | ||
socket.on('message', async (event) => { | ||
try { | ||
// wait for the the operation to complete | ||
// - if init message, waits for connect | ||
// - if query/mutation, waits for result | ||
// - if subscription, waits for complete | ||
await cb(event.toString()); | ||
} catch (err) { | ||
// all errors that could be thrown during the | ||
// execution of operations, will be caught here | ||
if (err instanceof Forbidden) { | ||
// your magic | ||
} else { | ||
socket.close(1011, err.message); | ||
} | ||
} | ||
}); | ||
}, | ||
}, | ||
// pass request to the extra | ||
{ request }, | ||
); | ||
// notify server that the socket closed | ||
socket.once('close', () => closed()); | ||
}); | ||
``` | ||
</details> | ||
<details id="express"> | ||
@@ -704,3 +809,4 @@ <summary><a href="#express">🔗</a> <a href="https://github.com/websockets/ws">ws</a> server usage with <a href="https://github.com/graphql/express-graphql">Express GraphQL</a></summary> | ||
import { execute, subscribe } from 'graphql'; | ||
import { useServer, createClient } from 'graphql-ws/lib/use/ws'; | ||
import { createClient } from 'graphql-ws'; | ||
import { useServer } from 'graphql-ws/lib/use/ws'; | ||
import { schema } from 'my-graphql-schema'; | ||
@@ -870,3 +976,3 @@ | ||
import { createClient } from 'graphql-ws/lib/use/ws'; | ||
import { createClient } from 'graphql-ws'; | ||
@@ -873,0 +979,0 @@ const client = createClient({ |
@@ -346,3 +346,3 @@ (function (global, factory) { | ||
// throw non `CloseEvent`s immediately, something else is wrong | ||
if (!isCloseEvent(errOrCloseEvent)) { | ||
if (!isLikeCloseEvent(errOrCloseEvent)) { | ||
throw errOrCloseEvent; | ||
@@ -501,4 +501,4 @@ } | ||
} | ||
function isCloseEvent(val) { | ||
return isObject(val) && 'code' in val && 'reason' in val && 'wasClean' in val; | ||
function isLikeCloseEvent(val) { | ||
return isObject(val) && 'code' in val && 'reason' in val; | ||
} | ||
@@ -505,0 +505,0 @@ function isWebSocket(val) { |
@@ -1,1 +0,1 @@ | ||
!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";const t=Object.prototype.hasOwnProperty;function n(e){return"object"==typeof e&&null!==e}function o(e,n){return t.call(e,n)}function r(e,o){return t.call(e,o)&&n(e[o])}function c(e,n){return t.call(e,n)&&"string"==typeof e[n]}var i;function s(e){if(n(e)){if(!c(e,"type"))return!1;switch(e.type){case i.ConnectionInit:case i.ConnectionAck:return!o(e,"payload")||void 0===e.payload||n(e.payload);case i.Subscribe:return c(e,"id")&&r(e,"payload")&&(!o(e.payload,"operationName")||void 0===e.payload.operationName||null===e.payload.operationName||"string"==typeof e.payload.operationName)&&c(e.payload,"query")&&(!o(e.payload,"variables")||void 0===e.payload.variables||null===e.payload.variables||r(e.payload,"variables"));case i.Next:return c(e,"id")&&r(e,"payload");case i.Error:return c(e,"id")&&(t=e.payload,Array.isArray(t)&&t.length>0&&t.every((e=>"message"in e)));case i.Complete:return c(e,"id");default:return!1}}var t;return!1}function a(e){if(s(e))return e;if("string"!=typeof e)throw new Error("Message not parsable");const t=JSON.parse(e);if(!s(t))throw new Error("Invalid message");return t}function l(e){if(!s(e))throw new Error("Cannot stringify invalid message");return JSON.stringify(e)}!function(e){e.ConnectionInit="connection_init",e.ConnectionAck="connection_ack",e.Subscribe="subscribe",e.Next="next",e.Error="error",e.Complete="complete"}(i||(i={})),e.createClient=function(e){const{url:t,connectionParams:o,lazy:r=!0,keepAlive:c=0,retryAttempts:s=5,retryTimeout:u=3e3,on:d,webSocketImpl:f,generateID:p=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)}))}}=e;let y;if(f){if(!("function"==typeof(m=f)&&"constructor"in m&&"CLOSED"in m&&"CLOSING"in m&&"CONNECTING"in m&&"OPEN"in m))throw new Error("Invalid WebSocket implementation provided");y=f}else"undefined"!=typeof WebSocket?y=WebSocket:"undefined"!=typeof global?y=global.WebSocket||global.MozWebSocket:"undefined"!=typeof window&&(y=window.WebSocket||window.MozWebSocket);var m;if(!y)throw new Error("WebSocket implementation missing");const w=y,b=(()=>{const e={connecting:(null==d?void 0:d.connecting)?[d.connecting]:[],connected:(null==d?void 0:d.connected)?[d.connected]:[],closed:(null==d?void 0:d.closed)?[d.closed]:[]};return{on(t,n){const o=e[t];return o.push(n),()=>{o.splice(o.indexOf(n),1)}},emit(t,...n){for(const o of e[t])o(...n)},reset(){Object.keys(e).forEach((t=>{e[t]=[]}))}}})();let g,k,x={socket:null,acknowledged:!1,locks:0,tries:0};async function v(e,n=0){if(n>10)throw new Error("Kept trying to connect but the socket never settled.");if(x.socket)switch(x.socket.readyState){case w.OPEN:return x.acknowledged?h(x.socket,e):(await new Promise((e=>setTimeout(e,300))),v(e,n+1));case w.CONNECTING:return await new Promise((e=>setTimeout(e,300))),v(e,n+1);case w.CLOSED:break;case w.CLOSING:return await new Promise((e=>setTimeout(e,300))),v(e,n+1);default:throw new Error("Impossible ready state "+x.socket.readyState)}const r=new w(t,"graphql-transport-ws");return x=Object.assign(Object.assign({},x),{acknowledged:!1,socket:r,tries:x.tries+1}),b.emit("connecting"),await new Promise(((t,n)=>{let c=!1;e.current=()=>c=!0;const s=setTimeout((()=>{r.close(3408,"Waited 5 seconds but socket connect never settled")}),5e3);r.onclose=e=>(r.onclose=null,clearTimeout(s),x=Object.assign(Object.assign({},x),{acknowledged:!1,socket:null}),b.emit("closed",e),n(e)),r.onmessage=e=>{if(r.onmessage=null,c)r.close(3499,"Client cancelled the socket before connecting");else try{const n=a(e.data);if(n.type!==i.ConnectionAck)throw new Error("First message cannot be of type "+n.type);return clearTimeout(s),x=Object.assign(Object.assign({},x),{acknowledged:!0,socket:r,tries:0}),b.emit("connected",r,n.payload),t()}catch(e){r.close(4400,e instanceof Error?e.message:new Error(e).message)}},r.onopen=()=>{r.onopen=null,c?r.close(3499,"Client cancelled the socket before connecting"):(async()=>{try{r.send(l({type:i.ConnectionInit,payload:"function"==typeof o?await o():o}))}catch(e){r.close(4400,e instanceof Error?e.message:new Error(e).message)}})()}})),h(r,e)}async function h(e,t){return[e,n=>new Promise(((o,r)=>{if(e.readyState===w.CLOSED)return r(new Error("Socket has already been closed"));function i(n){return t.current=null,x.locks--,e.removeEventListener("close",i),r(n)}x.locks++,e.addEventListener("close",i),t.current=()=>(t.current=null,null==n||n(),x.locks--,x.locks||(c>0&&isFinite(c)?setTimeout((()=>{!x.locks&&e.OPEN&&e.close(1e3,"Normal Closure")}),c):e.close(1e3,"Normal Closure")),e.removeEventListener("close",i),o())}))]}function E(e){if(!function(e){return n(e)&&"code"in e&&"reason"in e&&"wasClean"in e}(e))throw e;if([1002,1011,4400,4401,4409,4429].includes(e.code))throw e;if(1e3===e.code)return!1;if(3499===e.code)return!1;if(!s||x.tries>s)throw e;return!0}return r||(async()=>{for(;;)try{const[,e]=await v({current:null});return void await e()}catch(e){if(!E(e))return;await new Promise((e=>setTimeout(e,u)))}})(),{on:b.on,subscribe(e,t){const n=p();let o=!1;const r={current:null},c=({data:e})=>{const c=function(e){return e!==g&&(k=a(e),g=e),k}(e);switch(c.type){case i.Next:return void(c.id===n&&t.next(c.payload));case i.Error:return void(c.id===n&&(t.error(c.payload),r.current()));case i.Complete:return void(c.id===n&&(o=!0,r.current()))}};return(async()=>{for(;;)try{const[t,s]=await v(r);return t.addEventListener("message",c),t.send(l({id:n,type:i.Subscribe,payload:e})),await s((()=>{o||t.send(l({id:n,type:i.Complete}))})),void t.removeEventListener("message",c)}catch(e){if(!E(e))return;await new Promise((e=>setTimeout(e,u)))}})().catch(t.error).then(t.complete),()=>{var e;null===(e=r.current)||void 0===e||e.call(r)}},dispose(){var e;null===(e=x.socket)||void 0===e||e.close(1e3,"Normal Closure"),b.reset()}}},Object.defineProperty(e,"__esModule",{value:!0})})); | ||
!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";const t=Object.prototype.hasOwnProperty;function n(e){return"object"==typeof e&&null!==e}function o(e,n){return t.call(e,n)}function r(e,o){return t.call(e,o)&&n(e[o])}function c(e,n){return t.call(e,n)&&"string"==typeof e[n]}var i;function s(e){if(n(e)){if(!c(e,"type"))return!1;switch(e.type){case i.ConnectionInit:case i.ConnectionAck:return!o(e,"payload")||void 0===e.payload||n(e.payload);case i.Subscribe:return c(e,"id")&&r(e,"payload")&&(!o(e.payload,"operationName")||void 0===e.payload.operationName||null===e.payload.operationName||"string"==typeof e.payload.operationName)&&c(e.payload,"query")&&(!o(e.payload,"variables")||void 0===e.payload.variables||null===e.payload.variables||r(e.payload,"variables"));case i.Next:return c(e,"id")&&r(e,"payload");case i.Error:return c(e,"id")&&(t=e.payload,Array.isArray(t)&&t.length>0&&t.every((e=>"message"in e)));case i.Complete:return c(e,"id");default:return!1}}var t;return!1}function a(e){if(s(e))return e;if("string"!=typeof e)throw new Error("Message not parsable");const t=JSON.parse(e);if(!s(t))throw new Error("Invalid message");return t}function l(e){if(!s(e))throw new Error("Cannot stringify invalid message");return JSON.stringify(e)}!function(e){e.ConnectionInit="connection_init",e.ConnectionAck="connection_ack",e.Subscribe="subscribe",e.Next="next",e.Error="error",e.Complete="complete"}(i||(i={})),e.createClient=function(e){const{url:t,connectionParams:o,lazy:r=!0,keepAlive:c=0,retryAttempts:s=5,retryTimeout:u=3e3,on:d,webSocketImpl:f,generateID:p=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)}))}}=e;let y;if(f){if(!("function"==typeof(m=f)&&"constructor"in m&&"CLOSED"in m&&"CLOSING"in m&&"CONNECTING"in m&&"OPEN"in m))throw new Error("Invalid WebSocket implementation provided");y=f}else"undefined"!=typeof WebSocket?y=WebSocket:"undefined"!=typeof global?y=global.WebSocket||global.MozWebSocket:"undefined"!=typeof window&&(y=window.WebSocket||window.MozWebSocket);var m;if(!y)throw new Error("WebSocket implementation missing");const w=y,b=(()=>{const e={connecting:(null==d?void 0:d.connecting)?[d.connecting]:[],connected:(null==d?void 0:d.connected)?[d.connected]:[],closed:(null==d?void 0:d.closed)?[d.closed]:[]};return{on(t,n){const o=e[t];return o.push(n),()=>{o.splice(o.indexOf(n),1)}},emit(t,...n){for(const o of e[t])o(...n)},reset(){Object.keys(e).forEach((t=>{e[t]=[]}))}}})();let g,k,x={socket:null,acknowledged:!1,locks:0,tries:0};async function v(e,n=0){if(n>10)throw new Error("Kept trying to connect but the socket never settled.");if(x.socket)switch(x.socket.readyState){case w.OPEN:return x.acknowledged?h(x.socket,e):(await new Promise((e=>setTimeout(e,300))),v(e,n+1));case w.CONNECTING:return await new Promise((e=>setTimeout(e,300))),v(e,n+1);case w.CLOSED:break;case w.CLOSING:return await new Promise((e=>setTimeout(e,300))),v(e,n+1);default:throw new Error(`Impossible ready state ${x.socket.readyState}`)}const r=new w(t,"graphql-transport-ws");return x=Object.assign(Object.assign({},x),{acknowledged:!1,socket:r,tries:x.tries+1}),b.emit("connecting"),await new Promise(((t,n)=>{let c=!1;e.current=()=>c=!0;const s=setTimeout((()=>{r.close(3408,"Waited 5 seconds but socket connect never settled")}),5e3);r.onclose=e=>(r.onclose=null,clearTimeout(s),x=Object.assign(Object.assign({},x),{acknowledged:!1,socket:null}),b.emit("closed",e),n(e)),r.onmessage=e=>{if(r.onmessage=null,c)r.close(3499,"Client cancelled the socket before connecting");else try{const n=a(e.data);if(n.type!==i.ConnectionAck)throw new Error(`First message cannot be of type ${n.type}`);return clearTimeout(s),x=Object.assign(Object.assign({},x),{acknowledged:!0,socket:r,tries:0}),b.emit("connected",r,n.payload),t()}catch(e){r.close(4400,e instanceof Error?e.message:new Error(e).message)}},r.onopen=()=>{r.onopen=null,c?r.close(3499,"Client cancelled the socket before connecting"):(async()=>{try{r.send(l({type:i.ConnectionInit,payload:"function"==typeof o?await o():o}))}catch(e){r.close(4400,e instanceof Error?e.message:new Error(e).message)}})()}})),h(r,e)}async function h(e,t){return[e,n=>new Promise(((o,r)=>{if(e.readyState===w.CLOSED)return r(new Error("Socket has already been closed"));function i(n){return t.current=null,x.locks--,e.removeEventListener("close",i),r(n)}x.locks++,e.addEventListener("close",i),t.current=()=>(t.current=null,null==n||n(),x.locks--,x.locks||(c>0&&isFinite(c)?setTimeout((()=>{!x.locks&&e.OPEN&&e.close(1e3,"Normal Closure")}),c):e.close(1e3,"Normal Closure")),e.removeEventListener("close",i),o())}))]}function E(e){if(!function(e){return n(e)&&"code"in e&&"reason"in e}(e))throw e;if([1002,1011,4400,4401,4409,4429].includes(e.code))throw e;if(1e3===e.code)return!1;if(3499===e.code)return!1;if(!s||x.tries>s)throw e;return!0}return r||(async()=>{for(;;)try{const[,e]=await v({current:null});return void await e()}catch(e){if(!E(e))return;await new Promise((e=>setTimeout(e,u)))}})(),{on:b.on,subscribe(e,t){const n=p();let o=!1;const r={current:null},c=({data:e})=>{const c=function(e){return e!==g&&(k=a(e),g=e),k}(e);switch(c.type){case i.Next:return void(c.id===n&&t.next(c.payload));case i.Error:return void(c.id===n&&(t.error(c.payload),r.current()));case i.Complete:return void(c.id===n&&(o=!0,r.current()))}};return(async()=>{for(;;)try{const[t,s]=await v(r);return t.addEventListener("message",c),t.send(l({id:n,type:i.Subscribe,payload:e})),await s((()=>{o||t.send(l({id:n,type:i.Complete}))})),void t.removeEventListener("message",c)}catch(e){if(!E(e))return;await new Promise((e=>setTimeout(e,u)))}})().catch(t.error).then(t.complete),()=>{var e;null===(e=r.current)||void 0===e||e.call(r)}},dispose(){var e;null===(e=x.socket)||void 0===e||e.close(1e3,"Normal Closure"),b.reset()}}},Object.defineProperty(e,"__esModule",{value:!0})})); |
Sorry, the diff of this file is not supported yet
157220
1007