{"version":3,"file":"ws-C7ZOJJeA.mjs","names":["callTRPCProcedure"],"sources":["../src/adapters/wsEncoder.ts","../src/adapters/ws.ts"],"sourcesContent":["/**\n * Encoder for WebSocket wire format.\n * Encodes outgoing messages and decodes incoming messages.\n *\n * @example\n * ```ts\n * const customEncoder: Encoder = {\n *   encode: (data) => myFormat.stringify(data),\n *   decode: (data) => myFormat.parse(data),\n * };\n * ```\n */\nexport interface Encoder {\n  /** Encode data for transmission over the wire */\n  encode(data: unknown): string | Uint8Array<ArrayBuffer>;\n  /** Decode data received from the wire */\n  decode(data: string | ArrayBuffer | Uint8Array): unknown;\n}\n\n/**\n * Default JSON encoder - used when no encoder is specified.\n * This maintains backwards compatibility with existing behavior.\n */\nexport const jsonEncoder: Encoder = {\n  encode: (data) => JSON.stringify(data),\n  decode: (data) => {\n    if (typeof data !== 'string') {\n      throw new Error(\n        'jsonEncoder received binary data. JSON uses text frames. ' +\n          'Use a binary encoder for binary data.',\n      );\n    }\n    return JSON.parse(data);\n  },\n};\n","import type { IncomingMessage } from 'http';\nimport type ws from 'ws';\nimport type {\n  AnyRouter,\n  CreateContextCallback,\n  inferRouterContext,\n} from '../@trpc/server';\nimport {\n  callTRPCProcedure,\n  getErrorShape,\n  getTRPCErrorFromUnknown,\n  transformTRPCResponse,\n  TRPCError,\n} from '../@trpc/server';\nimport type { TRPCRequestInfo } from '../@trpc/server/http';\nimport { type BaseHandlerOptions } from '../@trpc/server/http';\nimport { parseTRPCMessage } from '../@trpc/server/rpc';\n// @trpc/server/rpc\nimport type {\n  TRPCClientOutgoingMessage,\n  TRPCConnectionParamsMessage,\n  TRPCReconnectNotification,\n  TRPCResponseMessage,\n  TRPCResultMessage,\n} from '../@trpc/server/rpc';\nimport { parseConnectionParamsFromUnknown } from '../http';\nimport { isObservable, observableToAsyncIterable } from '../observable';\n// eslint-disable-next-line no-restricted-imports\nimport {\n  isAsyncIterable,\n  isObject,\n  isTrackedEnvelope,\n  run,\n  type MaybePromise,\n} from '../unstable-core-do-not-import';\n// eslint-disable-next-line no-restricted-imports\nimport type { Result } from '../unstable-core-do-not-import';\n// eslint-disable-next-line no-restricted-imports\nimport { iteratorResource } from '../unstable-core-do-not-import/stream/utils/asyncIterable';\nimport { Unpromise } from '../vendor/unpromise';\nimport { createURL, type NodeHTTPCreateContextFnOptions } from './node-http';\nimport type { Encoder } from './wsEncoder';\nimport { jsonEncoder } from './wsEncoder';\n\n/**\n * Importing ws causes a build error\n * @see https://github.com/trpc/trpc/pull/5279\n */\nconst WEBSOCKET_OPEN = 1; /* ws.WebSocket.OPEN */\n\n/**\n * @public\n */\nexport type CreateWSSContextFnOptions = NodeHTTPCreateContextFnOptions<\n  IncomingMessage,\n  ws.WebSocket\n>;\n\n/**\n * @public\n */\nexport type CreateWSSContextFn<TRouter extends AnyRouter> = (\n  opts: CreateWSSContextFnOptions,\n) => MaybePromise<inferRouterContext<TRouter>>;\n\nexport type WSConnectionHandlerOptions<TRouter extends AnyRouter> =\n  BaseHandlerOptions<TRouter, IncomingMessage> &\n    CreateContextCallback<\n      inferRouterContext<TRouter>,\n      CreateWSSContextFn<TRouter>\n    >;\n\n/**\n * Web socket server handler\n */\nexport type WSSHandlerOptions<TRouter extends AnyRouter> =\n  WSConnectionHandlerOptions<TRouter> & {\n    wss: ws.WebSocketServer;\n    prefix?: string;\n    keepAlive?: {\n      /**\n       * Enable heartbeat messages\n       * @default false\n       */\n      enabled: boolean;\n      /**\n       * Heartbeat interval in milliseconds\n       * @default 30_000\n       */\n      pingMs?: number;\n      /**\n       * Terminate the WebSocket if no pong is received after this many milliseconds\n       * @default 5_000\n       */\n      pongWaitMs?: number;\n    };\n    /**\n     * Disable responding to ping messages from the client\n     * **Not recommended** - this is mainly used for testing\n     * @default false\n     */\n    dangerouslyDisablePong?: boolean;\n    /**\n     * Custom encoder for wire encoding (e.g. custom binary formats)\n     * @default jsonEncoder\n     */\n    experimental_encoder?: Encoder;\n  };\n\nexport function getWSConnectionHandler<TRouter extends AnyRouter>(\n  opts: WSSHandlerOptions<TRouter>,\n) {\n  const { createContext, router } = opts;\n  const { transformer } = router._def._config;\n  const encoder = opts.experimental_encoder ?? jsonEncoder;\n\n  return (client: ws.WebSocket, req: IncomingMessage) => {\n    type Context = inferRouterContext<TRouter>;\n    type ContextResult = Result<Context>;\n\n    const clientSubscriptions = new Map<number | string, AbortController>();\n    const abortController = new AbortController();\n\n    if (opts.keepAlive?.enabled) {\n      const { pingMs, pongWaitMs } = opts.keepAlive;\n      handleKeepAlive(client, pingMs, pongWaitMs);\n    }\n\n    function respond(untransformedJSON: TRPCResponseMessage) {\n      client.send(\n        encoder.encode(\n          transformTRPCResponse(router._def._config, untransformedJSON),\n        ),\n      );\n    }\n\n    async function createCtxPromise(\n      getConnectionParams: () => TRPCRequestInfo['connectionParams'],\n    ): Promise<ContextResult> {\n      try {\n        return await run(async (): Promise<ContextResult> => {\n          ctx = await createContext?.({\n            req,\n            res: client,\n            info: {\n              connectionParams: getConnectionParams(),\n              calls: [],\n              isBatchCall: false,\n              accept: null,\n              type: 'unknown',\n              signal: abortController.signal,\n              url: null,\n            },\n          });\n\n          return {\n            ok: true,\n            value: ctx,\n          };\n        });\n      } catch (cause) {\n        const error = getTRPCErrorFromUnknown(cause);\n        opts.onError?.({\n          error,\n          path: undefined,\n          type: 'unknown',\n          ctx,\n          req,\n          input: undefined,\n        });\n        respond({\n          id: null,\n          error: getErrorShape({\n            config: router._def._config,\n            error,\n            type: 'unknown',\n            path: undefined,\n            input: undefined,\n            ctx,\n          }),\n        });\n\n        // close in next tick\n        (globalThis.setImmediate ?? globalThis.setTimeout)(() => {\n          client.close();\n        });\n        return {\n          ok: false,\n          error,\n        };\n      }\n    }\n\n    let ctx: Context | undefined = undefined;\n\n    /**\n     * promise for initializing the context\n     *\n     * - the context promise will be created immediately on connection if no connectionParams are expected\n     * - if connection params are expected, they will be created once received\n     */\n    let ctxPromise =\n      createURL(req).searchParams.get('connectionParams') === '1'\n        ? null\n        : createCtxPromise(() => null);\n\n    function handleRequest(msg: TRPCClientOutgoingMessage, batchIndex: number) {\n      const { id, jsonrpc } = msg;\n\n      if (id === null) {\n        const error = getTRPCErrorFromUnknown(\n          new TRPCError({\n            code: 'PARSE_ERROR',\n            message: '`id` is required',\n          }),\n        );\n        opts.onError?.({\n          error,\n          path: undefined,\n          type: 'unknown',\n          ctx,\n          req,\n          input: undefined,\n        });\n        respond({\n          id,\n          jsonrpc,\n          error: getErrorShape({\n            config: router._def._config,\n            error,\n            type: 'unknown',\n            path: undefined,\n            input: undefined,\n            ctx,\n          }),\n        });\n        return;\n      }\n      if (msg.method === 'subscription.stop') {\n        clientSubscriptions.get(id)?.abort();\n        return;\n      }\n      const { path, lastEventId } = msg.params;\n      let { input } = msg.params;\n      const type = msg.method;\n\n      if (lastEventId !== undefined) {\n        if (isObject(input)) {\n          input = {\n            ...input,\n            lastEventId: lastEventId,\n          };\n        } else {\n          input ??= {\n            lastEventId: lastEventId,\n          };\n        }\n      }\n      run(async () => {\n        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n        const res = await ctxPromise!; // asserts context has been set\n        if (!res.ok) {\n          throw res.error;\n        }\n\n        const abortController = new AbortController();\n        const result = await callTRPCProcedure({\n          router,\n          path,\n          getRawInput: async () => input,\n          ctx,\n          type,\n          signal: abortController.signal,\n          batchIndex,\n        });\n\n        const isIterableResult =\n          isAsyncIterable(result) || isObservable(result);\n\n        if (type !== 'subscription') {\n          if (isIterableResult) {\n            throw new TRPCError({\n              code: 'UNSUPPORTED_MEDIA_TYPE',\n              message: `Cannot return an async iterable or observable from a ${type} procedure with WebSockets`,\n            });\n          }\n          // send the value as data if the method is not a subscription\n          respond({\n            id,\n            jsonrpc,\n            result: {\n              type: 'data',\n              data: result,\n            },\n          });\n          return;\n        }\n\n        if (!isIterableResult) {\n          throw new TRPCError({\n            message: `Subscription ${path} did not return an observable or a AsyncGenerator`,\n            code: 'INTERNAL_SERVER_ERROR',\n          });\n        }\n\n        /* istanbul ignore next -- @preserve */\n        if (client.readyState !== WEBSOCKET_OPEN) {\n          // if the client got disconnected whilst initializing the subscription\n          // no need to send stopped message if the client is disconnected\n\n          return;\n        }\n\n        /* istanbul ignore next -- @preserve */\n        if (clientSubscriptions.has(id)) {\n          // duplicate request ids for client\n\n          throw new TRPCError({\n            message: `Duplicate id ${id}`,\n            code: 'BAD_REQUEST',\n          });\n        }\n\n        const iterable = isObservable(result)\n          ? observableToAsyncIterable(result, abortController.signal)\n          : result;\n\n        run(async () => {\n          await using iterator = iteratorResource(iterable);\n\n          const abortPromise = new Promise<'abort'>((resolve) => {\n            abortController.signal.onabort = () => resolve('abort');\n          });\n          // We need those declarations outside the loop for garbage collection reasons. If they\n          // were declared inside, they would not be freed until the next value is present.\n          let next:\n            | null\n            | TRPCError\n            | Awaited<\n                typeof abortPromise | ReturnType<(typeof iterator)['next']>\n              >;\n          let result: null | TRPCResultMessage<unknown>['result'];\n\n          while (true) {\n            next = await Unpromise.race([\n              iterator.next().catch(getTRPCErrorFromUnknown),\n              abortPromise,\n            ]);\n\n            if (next === 'abort') {\n              await iterator.return?.();\n              break;\n            }\n            if (next instanceof Error) {\n              const error = getTRPCErrorFromUnknown(next);\n              opts.onError?.({ error, path, type, ctx, req, input });\n              respond({\n                id,\n                jsonrpc,\n                error: getErrorShape({\n                  config: router._def._config,\n                  error,\n                  type,\n                  path,\n                  input,\n                  ctx,\n                }),\n              });\n              break;\n            }\n            if (next.done) {\n              break;\n            }\n\n            result = {\n              type: 'data',\n              data: next.value,\n            };\n\n            if (isTrackedEnvelope(next.value)) {\n              const [id, data] = next.value;\n              result.id = id;\n              result.data = {\n                id,\n                data,\n              };\n            }\n\n            respond({\n              id,\n              jsonrpc,\n              result,\n            });\n\n            // free up references for garbage collection\n            next = null;\n            result = null;\n          }\n\n          respond({\n            id,\n            jsonrpc,\n            result: {\n              type: 'stopped',\n            },\n          });\n          clientSubscriptions.delete(id);\n        }).catch((cause) => {\n          clientSubscriptions.delete(id);\n          const error = getTRPCErrorFromUnknown(cause);\n          opts.onError?.({ error, path, type, ctx, req, input });\n          respond({\n            id,\n            jsonrpc,\n            error: getErrorShape({\n              config: router._def._config,\n              error,\n              type,\n              path,\n              input,\n              ctx,\n            }),\n          });\n          abortController.abort();\n        });\n        clientSubscriptions.set(id, abortController);\n\n        respond({\n          id,\n          jsonrpc,\n          result: {\n            type: 'started',\n          },\n        });\n      }).catch((cause) => {\n        // procedure threw an error\n        const error = getTRPCErrorFromUnknown(cause);\n        opts.onError?.({ error, path, type, ctx, req, input });\n        respond({\n          id,\n          jsonrpc,\n          error: getErrorShape({\n            config: router._def._config,\n            error,\n            type,\n            path,\n            input,\n            ctx,\n          }),\n        });\n      });\n    }\n    client.on('message', (rawData, isBinary) => {\n      // Handle PING/PONG as text regardless of encoder\n      if (!isBinary) {\n        // eslint-disable-next-line @typescript-eslint/no-base-to-string\n        const msgStr = rawData.toString();\n        if (msgStr === 'PONG') {\n          return;\n        }\n        if (msgStr === 'PING') {\n          if (!opts.dangerouslyDisablePong) {\n            client.send('PONG');\n          }\n          return;\n        }\n      }\n\n      // Convert rawData to a format our encoder accepts\n      // ws gives us Buffer for both text and binary frames\n      if (!Buffer.isBuffer(rawData)) {\n        const error = new TRPCError({\n          code: 'UNPROCESSABLE_CONTENT',\n          message: 'Unexpected WebSocket message format',\n        });\n        respond({\n          id: null,\n          error: getErrorShape({\n            config: router._def._config,\n            error,\n            type: 'unknown',\n            path: undefined,\n            input: undefined,\n            ctx,\n          }),\n        });\n        return;\n      }\n      const data: string | Uint8Array = isBinary\n        ? rawData\n        : rawData.toString('utf8');\n\n      if (!ctxPromise) {\n        // If the ctxPromise wasn't created immediately, we're expecting the first message to be a TRPCConnectionParamsMessage\n        ctxPromise = createCtxPromise(() => {\n          let msg;\n          try {\n            msg = encoder.decode(data) as TRPCConnectionParamsMessage;\n\n            if (!isObject(msg)) {\n              throw new Error('Message was not an object');\n            }\n          } catch (cause) {\n            throw new TRPCError({\n              code: 'PARSE_ERROR',\n              message: `Malformed TRPCConnectionParamsMessage`,\n              cause,\n            });\n          }\n\n          const connectionParams = parseConnectionParamsFromUnknown(msg.data);\n\n          return connectionParams;\n        });\n        return;\n      }\n\n      const parsedMsgs = run(() => {\n        try {\n          const msgJSON: unknown = encoder.decode(data);\n          const msgs: unknown[] = Array.isArray(msgJSON) ? msgJSON : [msgJSON];\n\n          return msgs.map((raw) => parseTRPCMessage(raw, transformer));\n        } catch (cause) {\n          const error = new TRPCError({\n            code: 'PARSE_ERROR',\n            cause,\n          });\n\n          respond({\n            id: null,\n            error: getErrorShape({\n              config: router._def._config,\n              error,\n              type: 'unknown',\n              path: undefined,\n              input: undefined,\n              ctx,\n            }),\n          });\n\n          return [];\n        }\n      });\n\n      parsedMsgs.map((msg, index) => handleRequest(msg, index));\n    });\n\n    // WebSocket errors should be handled, as otherwise unhandled exceptions will crash Node.js.\n    // This line was introduced after the following error brought down production systems:\n    // \"RangeError: Invalid WebSocket frame: RSV2 and RSV3 must be clear\"\n    // Here is the relevant discussion: https://github.com/websockets/ws/issues/1354#issuecomment-774616962\n    client.on('error', (cause) => {\n      opts.onError?.({\n        ctx,\n        error: getTRPCErrorFromUnknown(cause),\n        input: undefined,\n        path: undefined,\n        type: 'unknown',\n        req,\n      });\n    });\n\n    client.once('close', () => {\n      for (const sub of clientSubscriptions.values()) {\n        sub.abort();\n      }\n      clientSubscriptions.clear();\n      abortController.abort();\n    });\n  };\n}\n\n/**\n * Handle WebSocket keep-alive messages\n */\nexport function handleKeepAlive(\n  client: ws.WebSocket,\n  pingMs = 30_000,\n  pongWaitMs = 5_000,\n) {\n  let timeout: NodeJS.Timeout | undefined = undefined;\n  let ping: NodeJS.Timeout | undefined = undefined;\n\n  const schedulePing = () => {\n    const scheduleTimeout = () => {\n      timeout = setTimeout(() => {\n        client.terminate();\n      }, pongWaitMs);\n    };\n    ping = setTimeout(() => {\n      client.send('PING');\n\n      scheduleTimeout();\n    }, pingMs);\n  };\n\n  const onMessage = () => {\n    clearTimeout(ping);\n    clearTimeout(timeout);\n\n    schedulePing();\n  };\n\n  client.on('message', onMessage);\n\n  client.on('close', () => {\n    clearTimeout(ping);\n    clearTimeout(timeout);\n  });\n\n  schedulePing();\n}\n\nexport function applyWSSHandler<TRouter extends AnyRouter>(\n  opts: WSSHandlerOptions<TRouter>,\n) {\n  const encoder = opts.experimental_encoder ?? jsonEncoder;\n  const onConnection = getWSConnectionHandler(opts);\n  opts.wss.on('connection', (client, req) => {\n    if (opts.prefix && !req.url?.startsWith(opts.prefix)) {\n      return;\n    }\n\n    onConnection(client, req);\n  });\n\n  return {\n    broadcastReconnectNotification: () => {\n      const response: TRPCReconnectNotification = {\n        id: null,\n        method: 'reconnect',\n      };\n      const data = encoder.encode(response);\n      for (const client of opts.wss.clients) {\n        if (client.readyState === WEBSOCKET_OPEN) {\n          client.send(data);\n        }\n      }\n    },\n  };\n}\n\nexport type { Encoder } from './wsEncoder';\nexport { jsonEncoder } from './wsEncoder';\n"],"mappings":"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"}