Context transaction

This commit is contained in:
Julien Valverdé
2024-07-14 03:11:44 +02:00
parent 50b525cfd2
commit 69d9ffb3e0
6 changed files with 41 additions and 30 deletions

View File

@@ -3,6 +3,7 @@ import { Effect, Layer } from "effect"
import { rpcHTTPRoot } from "../config" import { rpcHTTPRoot } from "../config"
import { ExpressApp } from "../http/ExpressApp" import { ExpressApp } from "../http/ExpressApp"
import { TRPCContextCreator } from "../trpc/TRPCContextCreator" import { TRPCContextCreator } from "../trpc/TRPCContextCreator"
import { contextCreatorExpressAdapter } from "../trpc/adapters"
import { RPCRouter } from "./RPCRouter" import { RPCRouter } from "./RPCRouter"
@@ -13,7 +14,7 @@ export module RPCRoute {
app.use(yield* rpcHTTPRoot, app.use(yield* rpcHTTPRoot,
createExpressMiddleware({ createExpressMiddleware({
router: yield* RPCRouter, router: yield* RPCRouter,
createContext: yield* TRPCContextCreator, createContext: contextCreatorExpressAdapter(yield* TRPCContextCreator),
}), }),
) )
})) }))

View File

@@ -2,6 +2,7 @@ import { applyWSSHandler } from "@trpc/server/adapters/ws"
import { Effect, Layer } from "effect" import { Effect, Layer } from "effect"
import { WebSocketServer } from "../http/WebSocketServer" import { WebSocketServer } from "../http/WebSocketServer"
import { TRPCContextCreator } from "../trpc/TRPCContextCreator" import { TRPCContextCreator } from "../trpc/TRPCContextCreator"
import { contextCreatorWSSAdapter } from "../trpc/adapters"
import { RPCRouter } from "./RPCRouter" import { RPCRouter } from "./RPCRouter"
@@ -11,7 +12,7 @@ export module RPCWebSocketHandler {
return applyWSSHandler({ return applyWSSHandler({
wss: yield* WebSocketServer, wss: yield* WebSocketServer,
router: yield* RPCRouter, router: yield* RPCRouter,
createContext: yield* TRPCContextCreator, createContext: contextCreatorWSSAdapter(yield* TRPCContextCreator),
}) })
}), }),

View File

@@ -1,14 +1,13 @@
import type { TRPCError } from "@trpc/server" import type { TRPCError } from "@trpc/server"
import { Data, type Effect, type Runtime } from "effect" import { Data, type Effect, type Runtime } from "effect"
import type { RuntimeFiber } from "effect/Fiber" import type { RuntimeFiber } from "effect/Fiber"
import type { Request } from "express" import express from "express"
import type { IncomingMessage } from "node:http" import type { IncomingMessage } from "node:http"
import { WebSocket } from "ws"
import type { Services } from "../Services" import type { Services } from "../Services"
export interface TRPCContext { export interface TRPCContext {
req: TRPCContextRequest
runtime: Runtime.Runtime<Services> runtime: Runtime.Runtime<Services>
run: <A, E>( run: <A, E>(
@@ -20,12 +19,21 @@ export interface TRPCContext {
effect: Effect.Effect<A, E, Services>, effect: Effect.Effect<A, E, Services>,
options?: Runtime.RunForkOptions, options?: Runtime.RunForkOptions,
) => RuntimeFiber<A, TRPCError> ) => RuntimeFiber<A, TRPCError>
transaction: TRPCContextTransaction
} }
export type TRPCContextRequest = Data.TaggedEnum<{ export type TRPCContextTransaction = Data.TaggedEnum<{
Express: { readonly req: Request } Express: {
WebSocket: { readonly req: IncomingMessage } readonly req: express.Request
readonly res: express.Response
}
WebSocket: {
readonly req: IncomingMessage
readonly res: WebSocket
}
}> }>
export const TRPCContextRequestEnum = Data.taggedEnum<TRPCContextRequest>() export const TRPCContextTransactionEnum = Data.taggedEnum<TRPCContextTransaction>()

View File

@@ -1,19 +1,14 @@
import { TRPCError } from "@trpc/server" import { TRPCError } from "@trpc/server"
import type { CreateExpressContextOptions } from "@trpc/server/adapters/express"
import type { CreateWSSContextFnOptions } from "@trpc/server/adapters/ws"
import { Context, Effect, Layer, Runtime } from "effect" import { Context, Effect, Layer, Runtime } from "effect"
import type { Services } from "../Services" import type { Services } from "../Services"
import type { TRPCContext } from "./TRPCContext" import type { TRPCContext, TRPCContextTransaction } from "./TRPCContext"
/** /**
* Provides a function that instantiates a fresh context for each tRPC procedure call * Provides a function that instantiates a fresh context for each tRPC procedure call
*/ */
export class TRPCContextCreator extends Context.Tag("TRPCContextCreator")<TRPCContextCreator, export class TRPCContextCreator extends Context.Tag("TRPCContextCreator")<TRPCContextCreator,
(opts: (transaction: TRPCContextTransaction) => TRPCContext
| CreateExpressContextOptions
| CreateWSSContextFnOptions
) => TRPCContext
>() {} >() {}
export module TRPCContextCreator { export module TRPCContextCreator {
@@ -36,12 +31,11 @@ export module TRPCContextCreator {
options, options,
) )
return ({ req }) => ({ return transaction => ({
runtime, runtime,
run, run,
fork, fork,
transaction,
}) })
})) }))
} }

View File

@@ -0,0 +1,18 @@
import { type CreateExpressContextOptions } from "@trpc/server/adapters/express"
import type { CreateWSSContextFnOptions } from "@trpc/server/adapters/ws"
import type { Context } from "effect"
import { TRPCContextTransactionEnum } from "./TRPCContext"
import { TRPCContextCreator } from "./TRPCContextCreator"
export const contextCreatorExpressAdapter = (
createContext: Context.Tag.Service<typeof TRPCContextCreator>
) =>
(opts: CreateExpressContextOptions) =>
createContext(TRPCContextTransactionEnum.Express(opts))
export const contextCreatorWSSAdapter = (
createContext: Context.Tag.Service<typeof TRPCContextCreator>
) =>
(opts: CreateWSSContextFnOptions) =>
createContext(TRPCContextTransactionEnum.WebSocket(opts))

View File

@@ -1,11 +0,0 @@
import type { AnyRouter } from "@trpc/server"
import { createExpressMiddleware } from "@trpc/server/adapters/express"
import type { NodeHTTPHandlerOptions } from "@trpc/server/adapters/node-http"
import express from "express"
export const createExpressHandler = <TRouter extends AnyRouter>(
opts: NodeHTTPHandlerOptions<TRouter, express.Request, express.Response>,
) => {
const t = createExpressMiddleware(opts)
}