import { Exit, flow, ManagedRuntime } from "effect" import { Effect, Layer, Logger } from "effect-app" import { CauseException } from "effect-app/client/errors" import { type Context } from "effect-app/Context" export const makeAppRuntime = Effect.fnUntraced(function*(layer: Layer.Layer) { const l = layer.pipe( Layer.provide(Logger.layer([Logger.consolePretty()])) ) as Layer.Layer const mrt = ManagedRuntime.make(l) yield* mrt.contextEffect return Object.assign(mrt, { [Symbol.dispose]() { return Effect.runSync(mrt.disposeEffect) }, [Symbol.asyncDispose]() { return mrt.dispose() } }) // as we initialise here, there is no more error left. }) export function initializeSync(layer: Layer.Layer) { const runtime = Effect.runSync(makeAppRuntime(layer)) return runtime } export function initializeAsync(layer: Layer.Layer) { return Effect .runPromise(makeAppRuntime(layer)) } // we wrap into CauseException because we want to keep the full cause of the failure. export const makeRunPromise = (services: Context) => flow(Effect.runPromiseExitWith(services), (_) => _.then( Exit.match({ onFailure: (cause) => Promise.reject(new CauseException(cause, "runPromise")), onSuccess: (value) => Promise.resolve(value) }) )) export const makeRunSync = (services: Context) => flow( Effect.runSyncExitWith(services), Exit.match({ onFailure: (cause) => { throw new CauseException(cause, "runSync") }, onSuccess: (value) => value }) )