UNPKG

trpc-bun-adapter

Version:

TRPC adapter for bun js runtime

1 lines 25 kB
{"version":3,"sources":["../src/createBunHttpHandler.ts","../src/createBunWSHandler.ts","../src/createBunServeHandler.ts"],"sourcesContent":["import type { AnyRouter, inferRouterContext } from \"@trpc/server\";\nimport { fetchRequestHandler } from \"@trpc/server/adapters/fetch\";\nimport type {\n FetchCreateContextFnOptions,\n FetchHandlerRequestOptions,\n} from \"@trpc/server/adapters/fetch\";\nimport type { Server } from \"bun\";\n\nexport type CreateBunContextOptions = FetchCreateContextFnOptions;\n\nexport type BunHttpHandlerOptions<TRouter extends AnyRouter> = Omit<\n FetchHandlerRequestOptions<TRouter>,\n \"req\"\n> & {\n endpoint?: string;\n createContext?: (\n opts: CreateBunContextOptions,\n ) => inferRouterContext<TRouter> | Promise<inferRouterContext<TRouter>>;\n};\n\nexport function createBunHttpHandler<TRouter extends AnyRouter>(\n opts: BunHttpHandlerOptions<TRouter> & { emitWsUpgrades?: boolean },\n) {\n return (request: Request, server: Server) => {\n const url = new URL(request.url);\n\n if (opts.endpoint && !url.pathname.startsWith(opts.endpoint)) {\n return;\n }\n\n if (\n opts.emitWsUpgrades &&\n server.upgrade(request, { data: { req: request } })\n ) {\n return new Response(null, { status: 101 });\n }\n\n return fetchRequestHandler({\n createContext: () => ({}) as never,\n ...opts,\n req: request,\n endpoint: opts.endpoint ?? \"\",\n });\n };\n}\n","import {\n TRPCError,\n callTRPCProcedure,\n getErrorShape,\n getTRPCErrorFromUnknown,\n type inferRouterContext,\n isTrackedEnvelope,\n transformTRPCResponse,\n} from \"@trpc/server\";\nimport type { AnyRouter } from \"@trpc/server\";\nimport { parseConnectionParamsFromUnknown } from \"@trpc/server/http\";\nimport type { TRPCRequestInfo } from \"@trpc/server/http\";\nimport {\n isObservable,\n observableToAsyncIterable,\n} from \"@trpc/server/observable\";\nimport {\n type TRPCClientOutgoingMessage,\n type TRPCResponseMessage,\n type TRPCResultMessage,\n parseTRPCMessage,\n} from \"@trpc/server/rpc\";\nimport type { CreateContextCallback } from \"@trpc/server/src/@trpc/server\";\nimport type { BaseHandlerOptions } from \"@trpc/server/src/@trpc/server/http\";\nimport type { TRPCConnectionParamsMessage } from \"@trpc/server/src/@trpc/server/rpc\";\nimport type { NodeHTTPCreateContextFnOptions } from \"@trpc/server/src/adapters/node-http\";\nimport type { MaybePromise } from \"@trpc/server/src/unstable-core-do-not-import\";\nimport type { ServerWebSocket, WebSocketHandler } from \"bun\";\n\nexport type CreateBunWSSContextFnOptions<TRouter extends AnyRouter> =\n NodeHTTPCreateContextFnOptions<\n Request,\n ServerWebSocket<BunWSClientCtx<TRouter>>\n >;\n\nexport type BunWSAdapterOptions<TRouter extends AnyRouter> = BaseHandlerOptions<\n // @ts-expect-error: I don't know why this AnyRouter differs the one exported from @trpc/server\n TRouter,\n Request\n> &\n CreateContextCallback<\n inferRouterContext<TRouter>,\n (\n opts: CreateBunWSSContextFnOptions<TRouter>,\n ) => MaybePromise<inferRouterContext<TRouter>>\n >;\n\nexport type BunWSClientCtx<TRouter extends AnyRouter> = {\n req: Request;\n abortController: AbortController;\n abortControllers: Map<string | number, AbortController>;\n ctx:\n | Promise<inferRouterContext<TRouter>>\n | ((\n params: TRPCRequestInfo[\"connectionParams\"],\n ) => Promise<inferRouterContext<TRouter>>);\n};\n\nexport function createBunWSHandler<TRouter extends AnyRouter>(\n opts: BunWSAdapterOptions<TRouter>,\n): WebSocketHandler<BunWSClientCtx<TRouter>> {\n const { router, createContext } = opts;\n\n const respond = (\n client: ServerWebSocket<unknown>,\n untransformedJSON: TRPCResponseMessage,\n ) => {\n client.send(\n JSON.stringify(\n transformTRPCResponse(\n opts.router._def._config,\n untransformedJSON,\n ),\n ),\n );\n };\n\n async function createClientCtx(\n client: ServerWebSocket<BunWSClientCtx<inferRouterContext<TRouter>>>,\n url: URL,\n connectionParams: TRPCRequestInfo[\"connectionParams\"],\n ) {\n const ctxPromise = createContext?.({\n req: client.data.req,\n res: client,\n info: {\n url,\n connectionParams,\n calls: [],\n isBatchCall: false,\n accept: null,\n type: \"unknown\",\n signal: client.data.abortController.signal,\n },\n });\n\n try {\n return await ctxPromise;\n } catch (cause) {\n const error = getTRPCErrorFromUnknown(cause);\n opts.onError?.({\n error,\n path: undefined,\n type: \"unknown\",\n ctx: undefined,\n req: client.data.req,\n input: undefined,\n });\n respond(client, {\n id: null,\n error: getErrorShape({\n config: router._def._config,\n error,\n type: \"unknown\",\n path: undefined,\n input: undefined,\n ctx: undefined,\n }),\n });\n }\n }\n\n async function handleRequest(\n client: ServerWebSocket<BunWSClientCtx<inferRouterContext<TRouter>>>,\n msg: TRPCClientOutgoingMessage,\n ) {\n if (!msg.id) {\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: \"`id` is required\",\n });\n }\n\n if (msg.method === \"subscription.stop\") {\n client.data.abortControllers.get(msg.id)?.abort();\n client.data.abortControllers.delete(msg.id);\n return;\n }\n\n const { id, method, jsonrpc } = msg;\n const type = method;\n const { path, lastEventId } = msg.params;\n const req = client.data.req;\n const clientAbortControllers = client.data.abortControllers;\n let { input } = msg.params;\n const ctx = await client.data.ctx;\n\n try {\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\n if (clientAbortControllers.has(id)) {\n // duplicate request ids for client\n throw new TRPCError({\n message: `Duplicate id ${id}`,\n code: \"BAD_REQUEST\",\n });\n }\n\n const abortController = new AbortController();\n const result = await callTRPCProcedure({\n router,\n path,\n getRawInput: () => Promise.resolve(input),\n ctx,\n type,\n signal: abortController.signal,\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(client, {\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 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 return;\n }\n\n const iterable = isObservable(result)\n ? observableToAsyncIterable(result, abortController.signal)\n : result;\n\n const iterator: AsyncIterator<unknown> =\n iterable[Symbol.asyncIterator]();\n\n const abortPromise = new Promise<\"abort\">((resolve) => {\n abortController.signal.onabort = () => resolve(\"abort\");\n });\n\n clientAbortControllers.set(id, abortController);\n run(async () => {\n while (true) {\n const next = await Promise.race([\n iterator.next().catch(getTRPCErrorFromUnknown),\n abortPromise,\n ]);\n\n if (next === \"abort\") {\n await iterator.return?.();\n break;\n }\n\n if (next instanceof Error) {\n const error = getTRPCErrorFromUnknown(next);\n opts.onError?.({\n error,\n path,\n type,\n ctx,\n req,\n input,\n });\n respond(client, {\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\n if (next.done) {\n break;\n }\n\n const result: TRPCResultMessage<unknown>[\"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(client, {\n id,\n jsonrpc,\n result,\n });\n }\n\n await iterator.return?.();\n respond(client, {\n id,\n jsonrpc,\n result: {\n type: \"stopped\",\n },\n });\n })\n .catch((cause) => {\n const error = getTRPCErrorFromUnknown(cause);\n opts.onError?.({ error, path, type, ctx, req, input });\n respond(client, {\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 .finally(() => {\n clientAbortControllers.delete(id);\n });\n\n respond(client, {\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(client, {\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\n return {\n open(client) {\n client.data.abortController = new AbortController();\n client.data.abortControllers = new Map();\n\n const url = createURL(client);\n client.data.ctx = createClientCtx.bind(null, client, url);\n\n const connectionParams =\n url.searchParams.get(\"connectionParams\") === \"1\";\n\n if (!connectionParams) {\n client.data.ctx = client.data.ctx(null);\n }\n },\n\n async close(client) {\n client.data.abortController.abort();\n await Promise.all(\n Array.from(client.data.abortControllers.values(), (ctrl) =>\n ctrl.abort(),\n ),\n );\n },\n\n async message(client, message) {\n const msgStr = message.toString();\n\n if (msgStr === \"PONG\") {\n return;\n }\n\n if (msgStr === \"PING\") {\n client.send(\"PONG\");\n return;\n }\n\n try {\n const msgJSON: unknown = JSON.parse(msgStr);\n const msgs: unknown[] = Array.isArray(msgJSON)\n ? msgJSON\n : [msgJSON];\n\n if (client.data.ctx instanceof Function) {\n const msg = msgs.shift() as TRPCConnectionParamsMessage;\n client.data.ctx = client.data.ctx(\n parseConnectionParamsFromUnknown(msg.data),\n );\n }\n\n const promises = [];\n\n for (const raw of msgs) {\n const msg = parseTRPCMessage(\n raw,\n router._def._config.transformer,\n );\n promises.push(handleRequest(client, msg));\n }\n\n await Promise.all(promises);\n } catch (cause) {\n const error = new TRPCError({\n code: \"PARSE_ERROR\",\n cause,\n });\n\n respond(client, {\n id: null,\n error: getErrorShape({\n config: router._def._config,\n error,\n type: \"unknown\",\n path: undefined,\n input: undefined,\n ctx: undefined,\n }),\n });\n }\n },\n };\n}\n\n// util functions of @trpc/server that are not exported, unfortunately\nfunction isAsyncIterable<TValue>(\n value: unknown,\n): value is AsyncIterable<TValue> {\n return isObject(value) && Symbol.asyncIterator in value;\n}\n\nfunction run<TValue>(fn: () => TValue): TValue {\n return fn();\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return !!value && !Array.isArray(value) && typeof value === \"object\";\n}\n\nfunction createURL(client: ServerWebSocket<BunWSClientCtx<AnyRouter>>): URL {\n try {\n const req = client.data.req;\n\n const protocol =\n client && \"encrypted\" in client && client.encrypted\n ? \"https:\"\n : \"http:\";\n\n const host = req.headers.get(\"host\") ?? \"localhost\";\n return new URL(req.url, `${protocol}//${host}`);\n } catch (cause) {\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: \"Invalid URL\",\n cause,\n });\n }\n}\n","import type { AnyRouter } from \"@trpc/server\";\nimport type { ServeOptions, Server } from \"bun\";\nimport {\n type BunHttpHandlerOptions,\n createBunHttpHandler,\n} from \"./createBunHttpHandler\";\nimport {\n type BunWSAdapterOptions,\n createBunWSHandler,\n} from \"./createBunWSHandler\";\n\ntype Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;\n\nexport function createBunServeHandler<TRouter extends AnyRouter>(\n opts: BunHttpHandlerOptions<TRouter> & BunWSAdapterOptions<TRouter>,\n serveOptions?: Optional<ServeOptions, \"fetch\">,\n) {\n const trpcHandler = createBunHttpHandler({\n ...opts,\n emitWsUpgrades: true,\n });\n\n return {\n ...serveOptions,\n async fetch(req: Request, server: Server) {\n const trpcResponse = trpcHandler(req, server);\n\n if (trpcResponse) {\n return trpcResponse;\n }\n\n return serveOptions?.fetch?.call(server, req, server);\n },\n websocket: createBunWSHandler(opts),\n };\n}\n"],"mappings":"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","names":["result","id"]}