import type { CreateExpressContextOptions } from "@trpc/server/adapters/express" import type { CreateWSSContextFnOptions } from "@trpc/server/adapters/ws" import { Context, Effect, Layer, Runtime } from "effect" import { createTRCPErrorMapper } from "./createTRCPErrorMapper" import { TRPCContextTransactionEnum, type TRPCContext, type TRPCContextTransaction } from "./TRPCContext" export interface TRPCContextCreatorService { readonly createContext: (transaction: TRPCContextTransaction) => TRPCContext readonly createExpressContext: (context: CreateExpressContextOptions) => TRPCContext readonly createWebSocketContext: (context: CreateWSSContextFnOptions) => TRPCContext } export class TRPCUnknownContextCreator extends Context.Tag("@thilalib/TRPC/TRPCContextCreator") >() {} export const make = () => { class TRPCContextCreator extends Context.Tag("@thilalib/TRPC/TRPCContextCreator") >() {} const TRPCContextCreatorLive = Layer.effect(TRPCContextCreator, Effect.gen(function*() { const runtime = yield* Effect.runtime() const mapErrors = yield* createTRCPErrorMapper const run = ( effect: Effect.Effect, options?: { readonly signal?: AbortSignal }, ) => Runtime.runPromise(runtime)( effect.pipe(mapErrors), options, ) const fork = ( effect: Effect.Effect, options?: Runtime.RunForkOptions, ) => Runtime.runFork(runtime)( effect.pipe(mapErrors), options, ) const createContext = (transaction: TRPCContextTransaction) => ({ runtime, run, fork, transaction, }) const createExpressContext = (context: CreateExpressContextOptions) => createContext(TRPCContextTransactionEnum.Express(context)) const createWebSocketContext = (context: CreateWSSContextFnOptions) => createContext(TRPCContextTransactionEnum.WebSocket(context)) return { createContext, createExpressContext, createWebSocketContext } })) return { TRPCContextCreator, TRPCContextCreatorLive } }