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));