| 67 | * `Command.make(...)` won't touch any handler bodies. |
| 68 | */ |
| 69 | export const effectCmd = <Args, A>(opts: EffectCmdOpts<Args, A>) => |
| 70 | cmd<{}, Args>({ |
| 71 | command: opts.command, |
| 72 | aliases: opts.aliases, |
| 73 | describe: opts.describe, |
| 74 | builder: opts.builder as never, |
| 75 | async handler(rawArgs) { |
| 76 | const { AppRuntime } = await import("@/effect/app-runtime") |
| 77 | // yargs typing wraps Args in ArgumentsCamelCase<WithDoubleDash<...>>; cast at the boundary. |
| 78 | const args = rawArgs as unknown as WithDoubleDash<Args> |
| 79 | const useInstance = typeof opts.instance === "function" ? opts.instance(args) : opts.instance !== false |
| 80 | if (!useInstance) { |
| 81 | await AppRuntime.runPromise(opts.handler(args)) |
| 82 | return |
| 83 | } |
| 84 | const { InstanceStore } = await import("@/project/instance-store") |
| 85 | const { InstanceRef } = await import("@/effect/instance-ref") |
| 86 | const directory = opts.directory?.(args) ?? process.cwd() |
| 87 | const { store, ctx } = await AppRuntime.runPromise( |
| 88 | InstanceStore.Service.use((store) => store.load({ directory }).pipe(Effect.map((ctx) => ({ store, ctx })))), |
| 89 | ) |
| 90 | try { |
| 91 | await AppRuntime.runPromise(opts.handler(args).pipe(Effect.provideService(InstanceRef, ctx))) |
| 92 | } finally { |
| 93 | await AppRuntime.runPromise(store.dispose(ctx)) |
| 94 | } |
| 95 | }, |
| 96 | }) |