refactor(simulation): unify UI state polling
This commit is contained in:
parent
c4ccc9cbd1
commit
ba42a0a7c3
4 changed files with 10 additions and 16 deletions
|
|
@ -47,7 +47,7 @@ function hit(renderer: CliRenderer, renderable: Renderable) {
|
|||
/**
|
||||
* Builds the harness the simulation server drives.
|
||||
*
|
||||
* When the renderer is the fake simulation renderer, its TestRendererSetup
|
||||
* When the renderer is the headless simulation renderer, its TestRendererSetup
|
||||
* provides the supported testing APIs. For the visible terminal renderer the
|
||||
* harness falls back to `requestRender` + `idle` and reading the private
|
||||
* `currentRenderBuffer`.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { createTestRenderer, type TestRendererSetup } from "@opentui/core/testin
|
|||
const setups = new WeakMap<CliRenderer, TestRendererSetup>()
|
||||
|
||||
/**
|
||||
* Creates the fake simulation renderer: a real CliRenderer backed by an
|
||||
* Creates the headless simulation renderer: a real CliRenderer backed by an
|
||||
* in-memory screen buffer instead of a terminal. The TestRendererSetup is
|
||||
* kept module-side (keyed by renderer) so the harness can use the supported
|
||||
* testing APIs without app code carrying it around.
|
||||
|
|
|
|||
|
|
@ -15,21 +15,16 @@ function parseRequest(input: string | Buffer) {
|
|||
return SimulationProtocol.JsonRpc.decodeRequest(JSON.parse(typeof input === "string" ? input : input.toString()))
|
||||
}
|
||||
|
||||
async function handle(harness: Harness, request: SimulationProtocol.JsonRpc.Request) {
|
||||
async function handle(harness: Harness, request: SimulationProtocol.JsonRpc.Request, headless: boolean) {
|
||||
switch (request.method) {
|
||||
case "ui.state": {
|
||||
if (headless) await harness.renderOnce()
|
||||
const result = SimulationActions.state(harness)
|
||||
SimulationTrace.add("ui.state", { elements: result.elements.length, actions: result.actions.length })
|
||||
return result
|
||||
}
|
||||
case "ui.action":
|
||||
return SimulationActions.execute(harness, actionParam(request.params))
|
||||
case "ui.render": {
|
||||
await harness.renderOnce()
|
||||
const result = SimulationActions.state(harness)
|
||||
SimulationTrace.add("ui.render", { elements: result.elements.length, actions: result.actions.length })
|
||||
return result
|
||||
}
|
||||
case "trace.list":
|
||||
return { records: SimulationTrace.list() }
|
||||
case "trace.clear":
|
||||
|
|
@ -41,7 +36,7 @@ async function handle(harness: Harness, request: SimulationProtocol.JsonRpc.Requ
|
|||
throw new Error(`Unknown simulation method: ${request.method}`)
|
||||
}
|
||||
|
||||
export function start(harness: Harness, endpoint: string): Server {
|
||||
export function start(harness: Harness, endpoint: string, headless: boolean): Server {
|
||||
const url = new URL(endpoint)
|
||||
const server = Bun.serve<{ readonly drive: true }>({
|
||||
hostname: url.hostname,
|
||||
|
|
@ -61,7 +56,7 @@ export function start(harness: Harness, endpoint: string): Server {
|
|||
let request: SimulationProtocol.JsonRpc.Request | undefined
|
||||
try {
|
||||
request = parseRequest(message)
|
||||
const result = await handle(harness, request)
|
||||
const result = await handle(harness, request, headless)
|
||||
const next = SimulationProtocol.JsonRpc.success(request.id, result)
|
||||
if (next) socket.send(JSON.stringify(next))
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -7,19 +7,18 @@ import { SimulationServer } from "./server"
|
|||
/**
|
||||
* Drive-mode renderer entry point.
|
||||
*
|
||||
* Creates the renderer (fake when OPENCODE_DRIVE_RENDERER=fake, the normal
|
||||
* 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 renderer =
|
||||
process.env.OPENCODE_DRIVE_RENDERER === "fake"
|
||||
? await SimulationRenderer.create(options)
|
||||
: await createCliRenderer(options)
|
||||
const headless = process.env.OPENCODE_DRIVE_RENDERER === "headless"
|
||||
const renderer = headless ? await SimulationRenderer.create(options) : await createCliRenderer(options)
|
||||
const server = SimulationServer.start(
|
||||
SimulationActions.createHarness(renderer),
|
||||
DriveManifest.resolve().endpoints.ui,
|
||||
headless,
|
||||
)
|
||||
process.stderr.write(`opencode drive ui websocket: ${server.url}\n`)
|
||||
renderer.once("destroy", () => server.stop())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue