import { Effect, Schema } from "effect"; import { ApiErrorResponseSchema } from "@local-studio/agent-runtime/api-contract"; const errorMessage = (body: unknown, fallback: string): string => { const decoded = Schema.decodeUnknownOption(ApiErrorResponseSchema)(body); return decoded._tag === "Some" ? decoded.value.error : fallback; }; export async function requestJson( url: string, decode: (input: unknown) => T, init?: RequestInit, fallback = "Request failed", ): Promise { const response = await fetch(url, init); const body: unknown = await response.json().catch(() => null); if (!response.ok) throw new Error(errorMessage(body, `${fallback} (${response.status})`)); return decode(body); } export const requestDecodedEffect = ( url: string, decode: (input: unknown) => T, init?: RequestInit, fallback?: string, ): Effect.Effect => Effect.tryPromise({ try: () => requestJson(url, decode, init, fallback), catch: (error) => (error instanceof Error ? error : new Error(String(error))), }); export const requestJsonEffect = ( url: string, schema: Schema.ConstraintDecoder, init?: RequestInit, fallback?: string, ): Effect.Effect => requestDecodedEffect(url, Schema.decodeUnknownSync(schema), init, fallback);