UNPKG

@graphql-mesh/transport-ws

Version:
103 lines (100 loc) 3.35 kB
import { process } from '@graphql-mesh/cross-helpers'; import { getInterpolatedHeadersFactory } from '@graphql-mesh/string-interpolation'; import { makeAsyncDisposable, isDisposable, dispose } from '@graphql-mesh/utils'; import { buildGraphQLWSExecutor } from '@graphql-tools/executor-graphql-ws'; function switchProtocols(url) { if (url.startsWith("https://")) { return url.replace("https://", "wss://"); } if (url.startsWith("http://")) { return url.replace("http://", "ws://"); } return url; } var index = { getSubgraphExecutor({ transportEntry, log: rootLog }, onClient) { const wsExecutorMap = /* @__PURE__ */ new Map(); if (!transportEntry.location) { throw new Error( "WS Transport: location is required in the transport entry" ); } const wsUrl = switchProtocols(transportEntry.location); const connectionParamsFactory = transportEntry.options?.connectionParams ? getInterpolatedHeadersFactory(transportEntry.options.connectionParams) : void 0; const headersFactory = transportEntry.headers ? getInterpolatedHeadersFactory( Object.fromEntries(transportEntry.headers) ) : void 0; const mergedExecutor = function mergedExecutor2(execReq) { const connectionParams = connectionParamsFactory?.({ env: process.env, root: execReq.rootValue, context: execReq.context, info: execReq.info }); const headers = headersFactory?.({ env: process.env, root: execReq.rootValue, context: execReq.context, info: execReq.info }); const hash = JSON.stringify({ wsUrl, connectionParams, headers }); let wsExecutor = wsExecutorMap.get(hash); if (!wsExecutor) { const log = rootLog.child({ executor: "GraphQL WS", wsUrl, connectionParams, headers }); wsExecutor = buildGraphQLWSExecutor({ headers, url: wsUrl, lazy: true, lazyCloseTimeout: 3e3, ...transportEntry.options, connectionParams, on: { connecting(isRetry) { log.debug({ isRetry }, "connecting"); }, opened(socket) { log.debug({ socket }, "opened"); }, connected(socket, payload) { log.debug({ socket, payload }, "connected"); }, ping(received, payload) { log.debug({ received, payload }, "ping"); }, pong(received, payload) { log.debug({ received, payload }, "pong"); }, message(message) { log.debug({ message }, "message"); }, closed(event) { log.debug({ event }, "closed"); wsExecutorMap.delete(hash); }, error(error) { log.debug({ error }, "error"); } }, onClient }); wsExecutorMap.set(hash, wsExecutor); } return wsExecutor(execReq); }; return makeAsyncDisposable( mergedExecutor, () => Promise.all( Array.from(wsExecutorMap.values()).map( (executor) => isDisposable(executor) && dispose(executor) ) ).then(() => { }) ); } }; export { index as default };