trpc-bun-adapter
Advanced tools
Comparing version 1.1.0 to 1.1.1
@@ -1,45 +0,3 @@ | ||
import * as bun from 'bun'; | ||
import { Server, ServerWebSocket, WebSocketHandler, ServeOptions } from 'bun'; | ||
import { AnyRouter, inferRouterContext } from '@trpc/server'; | ||
import { HTTPBaseHandlerOptions, BaseHandlerOptions } from '@trpc/server/http'; | ||
import { TRPCClientOutgoingMessage } from '@trpc/server/rpc'; | ||
type CreateBunContextOptions = { | ||
req: Request; | ||
}; | ||
type BunHttpHandlerOptions<TRouter extends AnyRouter> = HTTPBaseHandlerOptions<TRouter, Request> & { | ||
endpoint?: string; | ||
createContext?: (opts: CreateBunContextOptions) => inferRouterContext<TRouter> | Promise<inferRouterContext<TRouter>>; | ||
}; | ||
declare function createBunHttpHandler<TRouter extends AnyRouter>(opts: BunHttpHandlerOptions<TRouter> & { | ||
emitWsUpgrades?: boolean; | ||
}): (request: Request, server: Server) => Response | Promise<Response> | undefined; | ||
type BunWSAdapterOptions<TRouter extends AnyRouter> = BaseHandlerOptions<TRouter, Request> & { | ||
createContext?: (params: { | ||
req: Request; | ||
client: ServerWebSocket<BunWSClientCtx>; | ||
}) => Promise<unknown> | unknown; | ||
}; | ||
type BunWSClientCtx = { | ||
req: Request; | ||
handleRequest: (msg: TRPCClientOutgoingMessage) => Promise<void>; | ||
unsubscribe(): void; | ||
}; | ||
declare function createBunWSHandler<TRouter extends AnyRouter>(opts: BunWSAdapterOptions<TRouter>): WebSocketHandler<BunWSClientCtx>; | ||
type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>; | ||
declare function createBunServeHandler<TRouter extends AnyRouter>(opts: BunHttpHandlerOptions<TRouter>, serveOptions?: Optional<ServeOptions, "fetch">): { | ||
fetch(req: Request, server: Server): Promise<Response | undefined>; | ||
websocket: bun.WebSocketHandler<BunWSClientCtx>; | ||
error?: ((this: Server, request: bun.Errorlike) => Response | Promise<Response> | Promise<undefined> | undefined) | undefined; | ||
id?: string | null | undefined; | ||
port?: string | number | undefined; | ||
reusePort?: boolean | undefined; | ||
hostname?: string | undefined; | ||
unix?: undefined; | ||
maxRequestBodySize?: number | undefined; | ||
development?: boolean | undefined; | ||
}; | ||
export { type BunHttpHandlerOptions, type BunWSAdapterOptions, type BunWSClientCtx, type CreateBunContextOptions, createBunHttpHandler, createBunServeHandler, createBunWSHandler }; | ||
export * from "./createBunHttpHandler"; | ||
export * from "./createBunWSHandler"; | ||
export * from "./createBunServeHandler"; |
@@ -7,14 +7,20 @@ "use strict"; | ||
var __export = (target, all) => { | ||
for (var name in all) | ||
__defProp(target, name, { get: all[name], enumerable: true }); | ||
for (var name in all) | ||
__defProp(target, name, { get: all[name], enumerable: true }); | ||
}; | ||
var __copyProps = (to, from, except, desc) => { | ||
if (from && typeof from === "object" || typeof from === "function") { | ||
for (let key of __getOwnPropNames(from)) | ||
if (!__hasOwnProp.call(to, key) && key !== except) | ||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
} | ||
return to; | ||
if ((from && typeof from === "object") || typeof from === "function") { | ||
for (let key of __getOwnPropNames(from)) | ||
if (!__hasOwnProp.call(to, key) && key !== except) | ||
__defProp(to, key, { | ||
get: () => from[key], | ||
enumerable: | ||
!(desc = __getOwnPropDesc(from, key)) || | ||
desc.enumerable, | ||
}); | ||
} | ||
return to; | ||
}; | ||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
var __toCommonJS = (mod) => | ||
__copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
@@ -24,5 +30,5 @@ // src/index.ts | ||
__export(src_exports, { | ||
createBunHttpHandler: () => createBunHttpHandler, | ||
createBunServeHandler: () => createBunServeHandler, | ||
createBunWSHandler: () => createBunWSHandler | ||
createBunHttpHandler: () => createBunHttpHandler, | ||
createBunServeHandler: () => createBunServeHandler, | ||
createBunWSHandler: () => createBunWSHandler, | ||
}); | ||
@@ -34,16 +40,20 @@ module.exports = __toCommonJS(src_exports); | ||
function createBunHttpHandler(opts) { | ||
return (request, server) => { | ||
const url = new URL(request.url); | ||
if (opts.endpoint && !url.pathname.startsWith(opts.endpoint)) { | ||
return; | ||
} | ||
if (opts.emitWsUpgrades && server.upgrade(request, { data: { req: request } })) { | ||
return new Response(null, { status: 101 }); | ||
} | ||
return (0, import_fetch.fetchRequestHandler)({ | ||
endpoint: opts.endpoint ?? "", | ||
...opts, | ||
req: request | ||
}); | ||
}; | ||
return (request, server) => { | ||
const url = new URL(request.url); | ||
if (opts.endpoint && !url.pathname.startsWith(opts.endpoint)) { | ||
return; | ||
} | ||
if ( | ||
opts.emitWsUpgrades && | ||
server.upgrade(request, { data: { req: request } }) | ||
) { | ||
return new Response(null, { status: 101 }); | ||
} | ||
return (0, import_fetch.fetchRequestHandler)({ | ||
endpoint: opts.endpoint ?? "", | ||
router: opts.router, | ||
req: request, | ||
createContext: opts.createContext, | ||
}); | ||
}; | ||
} | ||
@@ -56,223 +66,230 @@ | ||
function createBunWSHandler(opts) { | ||
const { router, createContext } = opts; | ||
const respond = (client, untransformedJSON) => { | ||
client.send( | ||
JSON.stringify( | ||
(0, import_server.transformTRPCResponse)( | ||
opts.router._def._config, | ||
untransformedJSON | ||
) | ||
) | ||
); | ||
}; | ||
return { | ||
async open(client) { | ||
const { req } = client.data; | ||
const clientSubscriptions = /* @__PURE__ */ new Map(); | ||
const ctxPromise = createContext?.({ req, client }); | ||
let ctx = void 0; | ||
await (async () => { | ||
try { | ||
ctx = await ctxPromise; | ||
} catch (cause) { | ||
const error = (0, import_server.getTRPCErrorFromUnknown)(cause); | ||
opts.onError?.({ | ||
error, | ||
path: void 0, | ||
type: "unknown", | ||
ctx, | ||
req, | ||
input: void 0 | ||
}); | ||
respond(client, { | ||
id: null, | ||
error: (0, import_server.getErrorShape)({ | ||
config: router._def._config, | ||
error, | ||
type: "unknown", | ||
path: void 0, | ||
input: void 0, | ||
ctx | ||
}) | ||
}); | ||
setImmediate(() => client.close()); | ||
} | ||
})(); | ||
const stopSubscription = (subscription, { | ||
id, | ||
jsonrpc | ||
}) => { | ||
subscription.unsubscribe(); | ||
respond(client, { | ||
id, | ||
jsonrpc, | ||
result: { | ||
type: "stopped" | ||
} | ||
}); | ||
}; | ||
client.data.handleRequest = async (msg) => { | ||
const { id, jsonrpc } = msg; | ||
if (id === null) { | ||
throw new import_server.TRPCError({ | ||
code: "BAD_REQUEST", | ||
message: "`id` is required" | ||
}); | ||
} | ||
if (msg.method === "subscription.stop") { | ||
const sub = clientSubscriptions.get(id); | ||
if (sub) { | ||
stopSubscription(sub, { id, jsonrpc }); | ||
} | ||
clientSubscriptions.delete(id); | ||
return; | ||
} | ||
const { path, input } = msg.params; | ||
const type = msg.method; | ||
try { | ||
await ctxPromise; | ||
const result = await (0, import_server.callProcedure)({ | ||
procedures: router._def.procedures, | ||
path, | ||
input, | ||
getRawInput: () => Promise.resolve(input), | ||
ctx, | ||
type | ||
}); | ||
if (type === "subscription") { | ||
if (!(0, import_observable.isObservable)(result)) { | ||
throw new import_server.TRPCError({ | ||
message: `Subscription ${path} did not return an observable`, | ||
code: "INTERNAL_SERVER_ERROR" | ||
}); | ||
} | ||
} else { | ||
respond(client, { | ||
id, | ||
jsonrpc, | ||
result: { | ||
type: "data", | ||
data: result | ||
} | ||
}); | ||
return; | ||
} | ||
const observable = result; | ||
const sub = observable.subscribe({ | ||
next(data) { | ||
respond(client, { | ||
id, | ||
jsonrpc, | ||
result: { | ||
type: "data", | ||
data | ||
const { router, createContext } = opts; | ||
const respond = (client, untransformedJSON) => { | ||
client.send( | ||
JSON.stringify( | ||
(0, import_server.transformTRPCResponse)( | ||
opts.router._def._config, | ||
untransformedJSON, | ||
), | ||
), | ||
); | ||
}; | ||
return { | ||
async open(client) { | ||
const { req } = client.data; | ||
const clientSubscriptions = /* @__PURE__ */ new Map(); | ||
const ctxPromise = createContext?.({ req, client }); | ||
let ctx = void 0; | ||
await (async () => { | ||
try { | ||
ctx = await ctxPromise; | ||
} catch (cause) { | ||
const error = (0, import_server.getTRPCErrorFromUnknown)( | ||
cause, | ||
); | ||
opts.onError?.({ | ||
error, | ||
path: void 0, | ||
type: "unknown", | ||
ctx, | ||
req, | ||
input: void 0, | ||
}); | ||
respond(client, { | ||
id: null, | ||
error: (0, import_server.getErrorShape)({ | ||
config: router._def._config, | ||
error, | ||
type: "unknown", | ||
path: void 0, | ||
input: void 0, | ||
ctx, | ||
}), | ||
}); | ||
setImmediate(() => client.close()); | ||
} | ||
}); | ||
}, | ||
error(err) { | ||
const error = (0, import_server.getTRPCErrorFromUnknown)(err); | ||
opts.onError?.({ | ||
error, | ||
path, | ||
type, | ||
ctx, | ||
req, | ||
input | ||
}); | ||
respond(client, { | ||
id, | ||
jsonrpc, | ||
error: (0, import_server.getErrorShape)({ | ||
config: router._def._config, | ||
error, | ||
type, | ||
path, | ||
input, | ||
ctx | ||
}) | ||
}); | ||
}, | ||
complete() { | ||
respond(client, { | ||
id, | ||
jsonrpc, | ||
result: { | ||
type: "stopped" | ||
})(); | ||
const stopSubscription = (subscription, { id, jsonrpc }) => { | ||
subscription.unsubscribe(); | ||
respond(client, { | ||
id, | ||
jsonrpc, | ||
result: { | ||
type: "stopped", | ||
}, | ||
}); | ||
}; | ||
client.data.handleRequest = async (msg) => { | ||
const { id, jsonrpc } = msg; | ||
if (id === null) { | ||
throw new import_server.TRPCError({ | ||
code: "BAD_REQUEST", | ||
message: "`id` is required", | ||
}); | ||
} | ||
}); | ||
if (msg.method === "subscription.stop") { | ||
const sub = clientSubscriptions.get(id); | ||
if (sub) { | ||
stopSubscription(sub, { id, jsonrpc }); | ||
} | ||
clientSubscriptions.delete(id); | ||
return; | ||
} | ||
const { path, input } = msg.params; | ||
const type = msg.method; | ||
try { | ||
await ctxPromise; | ||
const result = await (0, import_server.callProcedure)({ | ||
procedures: router._def.procedures, | ||
path, | ||
input, | ||
getRawInput: () => Promise.resolve(input), | ||
ctx, | ||
type, | ||
}); | ||
if (type === "subscription") { | ||
if (!(0, import_observable.isObservable)(result)) { | ||
throw new import_server.TRPCError({ | ||
message: `Subscription ${path} did not return an observable`, | ||
code: "INTERNAL_SERVER_ERROR", | ||
}); | ||
} | ||
} else { | ||
respond(client, { | ||
id, | ||
jsonrpc, | ||
result: { | ||
type: "data", | ||
data: result, | ||
}, | ||
}); | ||
return; | ||
} | ||
const observable = result; | ||
const sub = observable.subscribe({ | ||
next(data) { | ||
respond(client, { | ||
id, | ||
jsonrpc, | ||
result: { | ||
type: "data", | ||
data, | ||
}, | ||
}); | ||
}, | ||
error(err) { | ||
const error = (0, | ||
import_server.getTRPCErrorFromUnknown)(err); | ||
opts.onError?.({ | ||
error, | ||
path, | ||
type, | ||
ctx, | ||
req, | ||
input, | ||
}); | ||
respond(client, { | ||
id, | ||
jsonrpc, | ||
error: (0, import_server.getErrorShape)({ | ||
config: router._def._config, | ||
error, | ||
type, | ||
path, | ||
input, | ||
ctx, | ||
}), | ||
}); | ||
}, | ||
complete() { | ||
respond(client, { | ||
id, | ||
jsonrpc, | ||
result: { | ||
type: "stopped", | ||
}, | ||
}); | ||
}, | ||
}); | ||
if (client.readyState !== WebSocket.OPEN) { | ||
sub.unsubscribe(); | ||
return; | ||
} | ||
if (clientSubscriptions.has(id)) { | ||
stopSubscription(sub, { id, jsonrpc }); | ||
throw new import_server.TRPCError({ | ||
message: `Duplicate id ${id}`, | ||
code: "BAD_REQUEST", | ||
}); | ||
} | ||
clientSubscriptions.set(id, sub); | ||
respond(client, { | ||
id, | ||
jsonrpc, | ||
result: { | ||
type: "started", | ||
}, | ||
}); | ||
} catch (cause) { | ||
const error = (0, import_server.getTRPCErrorFromUnknown)( | ||
cause, | ||
); | ||
opts.onError?.({ error, path, type, ctx, req, input }); | ||
respond(client, { | ||
id, | ||
jsonrpc, | ||
error: (0, import_server.getErrorShape)({ | ||
config: router._def._config, | ||
error, | ||
type, | ||
path, | ||
input, | ||
ctx, | ||
}), | ||
}); | ||
} | ||
}; | ||
client.data.unsubscribe = () => { | ||
for (const sub of clientSubscriptions.values()) { | ||
sub.unsubscribe(); | ||
} | ||
clientSubscriptions.clear(); | ||
}; | ||
}, | ||
async close(client) { | ||
client.data.unsubscribe?.(); | ||
}, | ||
async message(client, message) { | ||
try { | ||
const msgJSON = JSON.parse(message.toString()); | ||
const msgs = Array.isArray(msgJSON) ? msgJSON : [msgJSON]; | ||
const promises = msgs | ||
.map((raw) => | ||
(0, import_rpc.parseTRPCMessage)( | ||
raw, | ||
router._def._config.transformer, | ||
), | ||
) | ||
.map(client.data.handleRequest); | ||
await Promise.all(promises); | ||
} catch (cause) { | ||
const error = new import_server.TRPCError({ | ||
code: "PARSE_ERROR", | ||
cause, | ||
}); | ||
respond(client, { | ||
id: null, | ||
error: (0, import_server.getErrorShape)({ | ||
config: router._def._config, | ||
error, | ||
type: "unknown", | ||
path: void 0, | ||
input: void 0, | ||
ctx: void 0, | ||
}), | ||
}); | ||
} | ||
}); | ||
if (client.readyState !== WebSocket.OPEN) { | ||
sub.unsubscribe(); | ||
return; | ||
} | ||
if (clientSubscriptions.has(id)) { | ||
stopSubscription(sub, { id, jsonrpc }); | ||
throw new import_server.TRPCError({ | ||
message: `Duplicate id ${id}`, | ||
code: "BAD_REQUEST" | ||
}); | ||
} | ||
clientSubscriptions.set(id, sub); | ||
respond(client, { | ||
id, | ||
jsonrpc, | ||
result: { | ||
type: "started" | ||
} | ||
}); | ||
} catch (cause) { | ||
const error = (0, import_server.getTRPCErrorFromUnknown)(cause); | ||
opts.onError?.({ error, path, type, ctx, req, input }); | ||
respond(client, { | ||
id, | ||
jsonrpc, | ||
error: (0, import_server.getErrorShape)({ | ||
config: router._def._config, | ||
error, | ||
type, | ||
path, | ||
input, | ||
ctx | ||
}) | ||
}); | ||
} | ||
}; | ||
client.data.unsubscribe = () => { | ||
for (const sub of clientSubscriptions.values()) { | ||
sub.unsubscribe(); | ||
} | ||
clientSubscriptions.clear(); | ||
}; | ||
}, | ||
async close(client) { | ||
client.data.unsubscribe?.(); | ||
}, | ||
async message(client, message) { | ||
try { | ||
const msgJSON = JSON.parse(message.toString()); | ||
const msgs = Array.isArray(msgJSON) ? msgJSON : [msgJSON]; | ||
const promises = msgs.map( | ||
(raw) => (0, import_rpc.parseTRPCMessage)(raw, router._def._config.transformer) | ||
).map(client.data.handleRequest); | ||
await Promise.all(promises); | ||
} catch (cause) { | ||
const error = new import_server.TRPCError({ | ||
code: "PARSE_ERROR", | ||
cause | ||
}); | ||
respond(client, { | ||
id: null, | ||
error: (0, import_server.getErrorShape)({ | ||
config: router._def._config, | ||
error, | ||
type: "unknown", | ||
path: void 0, | ||
input: void 0, | ||
ctx: void 0 | ||
}) | ||
}); | ||
} | ||
} | ||
}; | ||
}, | ||
}; | ||
} | ||
@@ -282,25 +299,26 @@ | ||
function createBunServeHandler(opts, serveOptions) { | ||
const trpcHandler = createBunHttpHandler({ | ||
...opts, | ||
emitWsUpgrades: true | ||
}); | ||
return { | ||
...serveOptions, | ||
async fetch(req, server) { | ||
const trpcReponse = trpcHandler(req, server); | ||
if (trpcReponse) { | ||
return trpcReponse; | ||
} | ||
return serveOptions?.fetch?.call(server, req, server); | ||
}, | ||
websocket: createBunWSHandler(opts) | ||
}; | ||
const trpcHandler = createBunHttpHandler({ | ||
...opts, | ||
emitWsUpgrades: true, | ||
}); | ||
return { | ||
...serveOptions, | ||
async fetch(req, server) { | ||
const trpcReponse = trpcHandler(req, server); | ||
if (trpcReponse) { | ||
return trpcReponse; | ||
} | ||
return serveOptions?.fetch?.call(server, req, server); | ||
}, | ||
websocket: createBunWSHandler(opts), | ||
}; | ||
} | ||
// Annotate the CommonJS export names for ESM import in node: | ||
0 && (module.exports = { | ||
createBunHttpHandler, | ||
createBunServeHandler, | ||
createBunWSHandler | ||
}); | ||
0 && | ||
(module.exports = { | ||
createBunHttpHandler, | ||
createBunServeHandler, | ||
createBunWSHandler, | ||
}); | ||
/* istanbul ignore next -- @preserve */ | ||
//# sourceMappingURL=index.js.map | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "trpc-bun-adapter", | ||
"version": "1.1.0", | ||
"description": "TRPC adapter for bun js runtime", | ||
"main": "dist/index.js", | ||
"module": "dist/index.mjs", | ||
"types": "dist/index.d.ts", | ||
"scripts": { | ||
"test": "bun test", | ||
"fmt": "bunx @biomejs/biome format --write .", | ||
"build": "npx tsup src/index.ts --format cjs,esm --dts --clean --sourcemap" | ||
}, | ||
"keywords": [ | ||
"bun", | ||
"trpc", | ||
"adapter", | ||
"websocket" | ||
], | ||
"repository": { | ||
"url": "git+https://github.com/cah4a/trpc-bun-adapter.git" | ||
}, | ||
"bugs": "https://github.com/cah4a/trpc-bun-adapter/issues", | ||
"author": "Sancha <cah4o3@gmail.com>", | ||
"license": "MIT", | ||
"devDependencies": { | ||
"@trpc/server": "next", | ||
"bun-types": "^1.0.20", | ||
"tsup": "^8.0.1", | ||
"typescript": "^5.3.3" | ||
}, | ||
"peerDependencies": { | ||
"@trpc/server": "^11.0.0-next-beta.228" | ||
} | ||
"name": "trpc-bun-adapter", | ||
"version": "1.1.1", | ||
"description": "TRPC adapter for bun js runtime", | ||
"main": "dist/index.js", | ||
"module": "dist/index.mjs", | ||
"types": "dist/index.d.ts", | ||
"files": [ | ||
"dist", | ||
"src", | ||
"package.json", | ||
"LICENSE.txt", | ||
"README.md", | ||
"tsconfig.json" | ||
], | ||
"scripts": { | ||
"test": "bun test", | ||
"fmt": "bunx @biomejs/biome format --write .", | ||
"build": "npx tsup src/index.ts --format cjs,esm --dts --clean --sourcemap" | ||
}, | ||
"keywords": ["bun", "trpc", "adapter", "websocket"], | ||
"repository": { | ||
"url": "git+https://github.com/cah4a/trpc-bun-adapter.git" | ||
}, | ||
"bugs": "https://github.com/cah4a/trpc-bun-adapter/issues", | ||
"author": "Sancha <cah4o3@gmail.com>", | ||
"license": "MIT", | ||
"devDependencies": { | ||
"@trpc/server": "next", | ||
"bun-types": "^1.1.17", | ||
"tsup": "^8.0.1", | ||
"typescript": "^5.5.2" | ||
}, | ||
"peerDependencies": { | ||
"@trpc/server": "^11.0.0-next-beta.228" | ||
} | ||
} |
@@ -45,2 +45,6 @@ # tRPC Bun Adapter | ||
## Example | ||
for a full example, see the [example](./example/) directory. | ||
## API Reference | ||
@@ -84,3 +88,3 @@ | ||
fetch(request, server) { | ||
// will be fired if it's not a TRPC request | ||
// will be executed if it's not a TRPC request | ||
return new Response("Hello world"); | ||
@@ -93,2 +97,22 @@ }, | ||
To add response headers like Cross-origin resource sharing (CORS) use `responseMeta` option: | ||
```ts | ||
Bun.serve( | ||
createBunServeHandler({ | ||
router: appRouter, | ||
responseMeta(opts) { | ||
return { | ||
status: 200, | ||
headers: { | ||
"Access-Control-Allow-Origin": "*", | ||
"Access-Control-Allow-Methods": "GET, POST, OPTIONS", | ||
"Access-Control-Allow-Headers": "Content-Type, Authorization" | ||
} | ||
}; | ||
} | ||
} | ||
) | ||
); | ||
``` | ||
### createBunHttpHandler | ||
@@ -95,0 +119,0 @@ |
import { Server } from "bun"; | ||
import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; | ||
import type { AnyRouter, inferRouterContext } from "@trpc/server"; | ||
import type { HTTPBaseHandlerOptions } from "@trpc/server/http"; | ||
import type { | ||
FetchHandlerRequestOptions, | ||
FetchCreateContextFnOptions, | ||
} from "@trpc/server/adapters/fetch"; | ||
export type CreateBunContextOptions = { req: Request }; | ||
export type CreateBunContextOptions = FetchCreateContextFnOptions; | ||
export type BunHttpHandlerOptions<TRouter extends AnyRouter> = | ||
HTTPBaseHandlerOptions<TRouter, Request> & { | ||
FetchHandlerRequestOptions<TRouter> & { | ||
endpoint?: string; | ||
@@ -34,7 +37,7 @@ createContext?: ( | ||
return fetchRequestHandler({ | ||
endpoint: opts.endpoint ?? "", | ||
...opts, | ||
req: request, | ||
endpoint: opts.endpoint ?? "", | ||
}); | ||
}; | ||
} |
import type { ServeOptions, Server } from "bun"; | ||
import { createBunWSHandler } from "./createBunWSHandler"; | ||
import { BunWSAdapterOptions, createBunWSHandler } from "./createBunWSHandler"; | ||
import { | ||
@@ -12,3 +12,3 @@ BunHttpHandlerOptions, | ||
export function createBunServeHandler<TRouter extends AnyRouter>( | ||
opts: BunHttpHandlerOptions<TRouter>, | ||
opts: BunHttpHandlerOptions<TRouter> & BunWSAdapterOptions<TRouter>, | ||
serveOptions?: Optional<ServeOptions, "fetch">, | ||
@@ -15,0 +15,0 @@ ) { |
@@ -11,3 +11,3 @@ import { ServerWebSocket, WebSocketHandler } from "bun"; | ||
callProcedure, | ||
getErrorShape, | ||
getErrorShape, | ||
transformTRPCResponse, | ||
@@ -19,13 +19,22 @@ getTRPCErrorFromUnknown, | ||
import { isObservable, Unsubscribable } from "@trpc/server/observable"; | ||
import type { BaseHandlerOptions } from "@trpc/server/http"; | ||
import type { BaseHandlerOptions } from "@trpc/server/src/@trpc/server/http"; | ||
import type { CreateContextCallback } from "@trpc/server/src/@trpc/server"; | ||
import type { MaybePromise } from "@trpc/server/src/unstable-core-do-not-import"; | ||
import type { NodeHTTPCreateContextFnOptions } from "@trpc/server/src/adapters/node-http"; | ||
export type CreateBunWSSContextFnOptions = Omit< | ||
NodeHTTPCreateContextFnOptions<Request, ServerWebSocket<BunWSClientCtx>>, | ||
"info" | ||
>; | ||
export type BunWSAdapterOptions<TRouter extends AnyRouter> = BaseHandlerOptions< | ||
TRouter, | ||
Request | ||
> & { | ||
createContext?: (params: { | ||
req: Request; | ||
client: ServerWebSocket<BunWSClientCtx>; | ||
}) => Promise<unknown> | unknown; | ||
}; | ||
> & | ||
CreateContextCallback< | ||
inferRouterContext<TRouter>, | ||
( | ||
opts: CreateBunWSSContextFnOptions, | ||
) => MaybePromise<inferRouterContext<TRouter>> | ||
>; | ||
@@ -65,3 +74,6 @@ export type BunWSClientCtx = { | ||
const ctxPromise = createContext?.({ req, client }); | ||
const ctxPromise = createContext?.({ | ||
req, | ||
res: client, | ||
}); | ||
let ctx: inferRouterContext<TRouter> | undefined = undefined; | ||
@@ -68,0 +80,0 @@ await (async () => { |
{ | ||
"compilerOptions": { | ||
"declaration": true, | ||
"baseUrl": "src", | ||
"target": "esnext", | ||
"allowJs": true, | ||
"skipLibCheck": true, | ||
"strict": true, | ||
"forceConsistentCasingInFileNames": true, | ||
"emitDecoratorMetadata": true, | ||
"emitDeclarationOnly": true, | ||
"outDir": "dist", | ||
"experimentalDecorators": true, | ||
"esModuleInterop": true, | ||
"module": "esnext", | ||
"moduleResolution": "node", | ||
"resolveJsonModule": true, | ||
"isolatedModules": true, | ||
"jsx": "preserve", | ||
"types": ["bun-types"] | ||
}, | ||
"include": ["src/index.ts"] | ||
"compilerOptions": { | ||
"declaration": true, | ||
"baseUrl": "src", | ||
"target": "esnext", | ||
"allowJs": true, | ||
"skipLibCheck": true, | ||
"strict": true, | ||
"forceConsistentCasingInFileNames": true, | ||
"emitDecoratorMetadata": true, | ||
"emitDeclarationOnly": true, | ||
"outDir": "dist", | ||
"experimentalDecorators": true, | ||
"esModuleInterop": true, | ||
"module": "esnext", | ||
"moduleResolution": "node", | ||
"resolveJsonModule": true, | ||
"isolatedModules": true, | ||
"jsx": "preserve", | ||
"types": ["bun-types"] | ||
}, | ||
"include": ["src/index.ts"] | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
91308
1313
228