import type { Context, Handler, MiddlewareHandler, Next, TypedResponse } from "hono"; import { Cause, Exit, type Effect } from "effect"; import type { AppContextService } from "../app-context"; import type { ControllerRuntime } from "../core/effect-runtime"; export type ControllerEffect = Effect.Effect; export type ControllerEnvironment = { Variables: { controllerRuntime: ControllerRuntime; }; }; export const controllerRuntimeMiddleware = (runtime: ControllerRuntime): MiddlewareHandler => (context, next) => { context.set("controllerRuntime", runtime); return next(); }; const runControllerEffect = ( runtime: ControllerRuntime, effect: ControllerEffect, ): Promise => runtime.runPromiseExit(effect).then((exit) => { if (Exit.isSuccess(exit)) return exit.value; const failure = Cause.findErrorOption(exit.cause); if (failure._tag === "Some") throw failure.value; throw Cause.squash(exit.cause); }); export const effectHandler = >( handler: (context: Context) => ControllerEffect, ): Handler> => (context) => runControllerEffect(context.get("controllerRuntime"), handler(context)); export const effectMiddleware = ( handler: ( context: Context, next: Next, ) => ControllerEffect, ): MiddlewareHandler => (context, next) => runControllerEffect(context.get("controllerRuntime"), handler(context, next));