mirror of
https://github.com/anomalyco/opencode.git
synced 2026-04-25 15:24:58 +00:00
3.0 KiB
3.0 KiB
Route handler effectification
Practical reference for converting server route handlers in packages/opencode to a single AppRuntime.runPromise(Effect.gen(...)) body.
Goal
Route handlers should wrap their entire body in a single AppRuntime.runPromise(Effect.gen(...)) call, yielding services from context rather than calling facades one-by-one.
This eliminates multiple runPromise round-trips and lets handlers compose naturally.
// Before - one facade call per service
;async (c) => {
await SessionRunState.assertNotBusy(id)
await Session.removeMessage({ sessionID: id, messageID })
return c.json(true)
}
// After - one Effect.gen, yield services from context
;async (c) => {
await AppRuntime.runPromise(
Effect.gen(function* () {
const state = yield* SessionRunState.Service
const session = yield* Session.Service
yield* state.assertNotBusy(id)
yield* session.removeMessage({ sessionID: id, messageID })
}),
)
return c.json(true)
}
Rules
- Wrap the whole handler body in one
AppRuntime.runPromise(Effect.gen(...))call when the handler is service-heavy. - Yield services from context instead of calling async facades repeatedly.
- When independent service calls can run in parallel, use
Effect.all(..., { concurrency: "unbounded" }). - Prefer one composed Effect body over multiple separate
runPromise(...)calls in the same handler.
Current route files
Current instance route files live under src/server/instance, not server/routes.
The main migration targets are:
server/instance/session.ts— heaviest; still has many direct facade calls for Session, SessionPrompt, SessionRevert, SessionCompaction, SessionShare, SessionSummary, Agent, Busserver/instance/global.ts— still has direct facade calls for Config and instance lifecycle actionsserver/instance/provider.ts— still has direct facade calls for Config and Providerserver/instance/question.ts— partially converted; still worth tracking here until it consistently uses the composed styleserver/instance/pty.ts— still calls Pty facades directlyserver/instance/experimental.ts— mixed state; some handlers are already composed, others still use facades
Additional route files that still participate in the migration:
server/instance/index.ts— Vcs, Agent, Skill, LSP, Formatserver/instance/file.ts— Ripgrep, File, LSPserver/instance/mcp.ts— MCP facade-heavyserver/instance/permission.ts— Permissionserver/instance/workspace.ts— Workspaceserver/instance/tui.ts— Bus and Sessionserver/instance/middleware.ts— Session and Workspace lookups
Notes
- Some handlers already use
AppRuntime.runPromise(Effect.gen(...))in isolated places. Keep pushing those files toward one consistent style. - Route conversion is closely tied to facade removal. As services lose
makeRuntime-backed async exports, route handlers should switch to yielding the service directly.