graphql-ws
Version:
Coherent, zero-dependency, lazy, simple, GraphQL over WebSocket Protocol compliant server and client
2 lines (1 loc) • 5.29 kB
JavaScript
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).graphqlWs={})}(this,(function(e){"use strict";const n="graphql-transport-ws",t=Object.prototype.hasOwnProperty;function o(e){return"object"==typeof e&&null!==e}function r(e,n){return t.call(e,n)}function a(e,n){return t.call(e,n)&&o(e[n])}function i(e,n){return t.call(e,n)&&"string"==typeof e[n]}var s;function c(n){if(o(n)){if(!i(n,"type"))return!1;switch(n.type){case e.MessageType.ConnectionInit:case e.MessageType.ConnectionAck:return!r(n,"payload")||void 0===n.payload||o(n.payload);case e.MessageType.Subscribe:return i(n,"id")&&a(n,"payload")&&(!r(n.payload,"operationName")||void 0===n.payload.operationName||null===n.payload.operationName||"string"==typeof n.payload.operationName)&&i(n.payload,"query")&&(!r(n.payload,"variables")||void 0===n.payload.variables||null===n.payload.variables||a(n.payload,"variables"));case e.MessageType.Next:return i(n,"id")&&a(n,"payload");case e.MessageType.Error:return i(n,"id")&&(t=n.payload,Array.isArray(t)&&t.length>0&&t.every((e=>"message"in e)));case e.MessageType.Complete:return i(n,"id");default:return!1}}var t;return!1}function l(e){if(c(e))return e;if("string"!=typeof e)throw new Error("Message not parsable");const n=JSON.parse(e);if(!c(n))throw new Error("Invalid message");return n}function d(e){if(!c(e))throw new Error("Cannot stringify invalid message");return JSON.stringify(e)}function u(e){return o(e)&&"code"in e&&"reason"in e}e.MessageType=void 0,(s=e.MessageType||(e.MessageType={})).ConnectionInit="connection_init",s.ConnectionAck="connection_ack",s.Subscribe="subscribe",s.Next="next",s.Error="error",s.Complete="complete",e.GRAPHQL_TRANSPORT_WS_PROTOCOL=n,e.createClient=function(t){const{url:o,connectionParams:r,lazy:a=!0,onNonLazyError:i=console.error,keepAlive:s=0,retryAttempts:c=5,retryWait:p=async function(e){let n=1e3;for(let t=0;t<e;t++)n*=2;await new Promise((e=>setTimeout(e,n+Math.floor(2700*Math.random()+300))))},isFatalConnectionProblem:y=(e=>!u(e)),on:f,webSocketImpl:g,generateID:m=function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(e=>{const n=16*Math.random()|0;return("x"==e?n:3&n|8).toString(16)}))}}=t;let w;if(g){if(!("function"==typeof(x=g)&&"constructor"in x&&"CLOSED"in x&&"CLOSING"in x&&"CONNECTING"in x&&"OPEN"in x))throw new Error("Invalid WebSocket implementation provided");w=g}else"undefined"!=typeof WebSocket?w=WebSocket:"undefined"!=typeof global?w=global.WebSocket||global.MozWebSocket:"undefined"!=typeof window&&(w=window.WebSocket||window.MozWebSocket);var x;if(!w)throw new Error("WebSocket implementation missing");const b=w,v=(()=>{const e={connecting:(null==f?void 0:f.connecting)?[f.connecting]:[],connected:(null==f?void 0:f.connected)?[f.connected]:[],closed:(null==f?void 0:f.closed)?[f.closed]:[]};return{on(n,t){const o=e[n];return o.push(t),()=>{o.splice(o.indexOf(t),1)}},emit(n,...t){for(const o of e[n])o(...t)}}})();let h,M,T,E=0,S=!1,C=0,N=!1;async function O(){E++;const t=await(null!=h?h:h=new Promise(((t,a)=>(async()=>{S&&(await p(C),C++),v.emit("connecting");const i=new b(o,n);i.onclose=e=>{h=void 0,v.emit("closed",e),a(e)},i.onopen=async()=>{try{i.send(d({type:e.MessageType.ConnectionInit,payload:"function"==typeof r?await r():r}))}catch(e){i.close(4400,e instanceof Error?e.message:new Error(e).message)}},i.onmessage=({data:n})=>{i.onmessage=null;try{const o=l(n);if(o.type!==e.MessageType.ConnectionAck)throw new Error(`First message cannot be of type ${o.type}`);v.emit("connected",i,o.payload),C=0,t(i)}catch(e){i.close(4400,e instanceof Error?e.message:new Error(e).message)}}})())));let a=()=>{};const i=new Promise((e=>a=e));return[t,a,Promise.race([i.then((()=>{if(0==--E){const e=()=>t.close(1e3,"Normal Closure");isFinite(s)&&s>0?setTimeout((()=>{E||t.readyState!==b.OPEN||e()}),s):e()}})),new Promise(((e,n)=>t.addEventListener("close",n,{once:!0})))])]}function P(e){if(u(e)&&[1002,1011,4400,4401,4409,4429].includes(e.code))throw e;if(N||u(e)&&1e3===e.code)return!1;if(!c||C>=c)throw e;if(y(e))throw e;return S=!0,!0}return a||(async()=>{for(;;)try{const[,,e]=await O();return void await e}catch(e){try{if(!P(e))return null==i?void 0:i(e)}catch(n){return null==i?void 0:i(e)}}})(),{on:v.on,subscribe(n,t){const o=m();let r=!1;const a={current:()=>{r=!0}};function i({data:n}){const i=function(e){return e!==M&&(T=l(e),M=e),T}(n);switch(i.type){case e.MessageType.Next:return void(i.id===o&&t.next(i.payload));case e.MessageType.Error:return void(i.id===o&&(r=!0,t.error(i.payload),a.current()));case e.MessageType.Complete:return void(i.id===o&&(r=!0,a.current()))}}return(async()=>{for(;;)try{const[t,s,c]=await O();return r?s():(t.addEventListener("message",i),t.send(d({id:o,type:e.MessageType.Subscribe,payload:n})),a.current=()=>{r||t.readyState!==b.OPEN||t.send(d({id:o,type:e.MessageType.Complete})),s()},await c,void t.removeEventListener("message",i))}catch(e){if(!P(e))return}})().catch(t.error).then(t.complete),()=>a.current()},async dispose(){if(N=!0,h){(await h).close(1e3,"Normal Closure")}}}},e.isMessage=c,e.parseMessage=l,e.stringifyMessage=d,Object.defineProperty(e,"__esModule",{value:!0})}));