refactor(simulation): scope Drive lifecycle with Effect (#36908)
This commit is contained in:
parent
a149a61a89
commit
947566f611
30 changed files with 1313 additions and 600 deletions
|
|
@ -1,32 +1,27 @@
|
|||
import { createCliRenderer, type CliRenderer, type CliRendererConfig } from "@opentui/core"
|
||||
import { createCliRenderer, type CliRendererConfig } from "@opentui/core"
|
||||
import { Config, Effect } from "effect"
|
||||
import { DriveManifest } from "../manifest"
|
||||
import { SimulationActions } from "./actions"
|
||||
import { SimulationRenderer } from "./renderer"
|
||||
import { SimulationServer } from "./server"
|
||||
|
||||
/**
|
||||
* Drive-mode renderer entry point.
|
||||
*
|
||||
* Creates the renderer (headless when OPENCODE_DRIVE_RENDERER=headless, the normal
|
||||
* visible renderer otherwise) and starts the UI control
|
||||
* server against it. The server stops when the renderer is destroyed, so the
|
||||
* caller only manages the renderer lifecycle.
|
||||
*/
|
||||
export async function create(options: CliRendererConfig): Promise<CliRenderer> {
|
||||
const headless = process.env.OPENCODE_DRIVE_RENDERER === "headless"
|
||||
const manifest = DriveManifest.resolve()
|
||||
/** Drive-mode renderer and control-server acquisition. */
|
||||
export const create = Effect.fn("Drive.create")(function* (options: CliRendererConfig) {
|
||||
const headless = (yield* Config.string("OPENCODE_DRIVE_RENDERER").pipe(Config.withDefault("visible"))) === "headless"
|
||||
const manifest = yield* DriveManifest.resolve()
|
||||
const renderer = headless
|
||||
? await SimulationRenderer.create(options, manifest.recording?.timeline, manifest.viewport)
|
||||
: await createCliRenderer(options)
|
||||
? yield* SimulationRenderer.create(options, manifest.recording?.timeline, manifest.viewport)
|
||||
: yield* Effect.acquireRelease(
|
||||
Effect.tryPromise(() => createCliRenderer(options)),
|
||||
(renderer) =>
|
||||
Effect.sync(() => {
|
||||
if (!renderer.isDestroyed) renderer.destroy()
|
||||
}),
|
||||
)
|
||||
if (!headless && manifest.viewport) renderer.resize(manifest.viewport.cols, manifest.viewport.rows)
|
||||
const server = SimulationServer.start(
|
||||
SimulationActions.createHarness(renderer),
|
||||
manifest.endpoints.ui,
|
||||
headless && manifest.recording ? () => SimulationRenderer.finish(renderer) : undefined,
|
||||
)
|
||||
process.stderr.write(`opencode drive ui websocket: ${server.url}\n`)
|
||||
renderer.once("destroy", () => server.stop())
|
||||
const server = yield* SimulationServer.start(SimulationActions.createHarness(renderer), manifest.endpoints.ui)
|
||||
yield* Effect.sync(() => process.stderr.write(`opencode drive ui websocket: ${server.url}\n`))
|
||||
return renderer
|
||||
}
|
||||
})
|
||||
|
||||
export * as Drive from "./simulation"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue