refactor(tui): centralize location state

This commit is contained in:
Dax Raad
2026-07-14 23:01:41 -04:00
parent ff3442ce34
commit 94a23b8537
19 changed files with 173 additions and 245 deletions
+7 -4
View File
@@ -5,10 +5,9 @@ import type { OpenCodeEvent } from "@opencode-ai/client"
import { SessionMessage } from "@opencode-ai/core/session/message"
import { EventV2 } from "@opencode-ai/core/event"
import { createEffect, onMount, type ParentProps } from "solid-js"
import { ProjectProvider } from "../../../src/context/project"
import { ClientProvider, useClient } from "../../../src/context/client"
import { DataProvider as DataProviderBase, useData } from "../../../src/context/data"
import { LocationProvider, useSetLocation } from "../../../src/context/location"
import { LocationProvider, useLocation } from "../../../src/context/location"
import { createSessionRows, type SessionRow } from "../../../src/routes/session/rows"
import { createApi, createEventStream, createFetch, directory, json } from "../../fixture/tui-client"
import { TestTuiContexts } from "../../fixture/tui-environment"
@@ -44,10 +43,14 @@ function DataProvider(props: ParentProps) {
)
}
function ProjectProvider(props: ParentProps) {
return props.children
}
function SyncLocation() {
const data = useData()
const setLocation = useSetLocation()
createEffect(() => setLocation(data.location.default()))
const location = useLocation()
createEffect(() => location.set(data.location.default()))
return null
}
+14 -25
View File
@@ -4,7 +4,6 @@ import type { OpenCodeClient, OpenCodeEvent } from "@opencode-ai/client"
import type { Service } from "@opencode-ai/client/effect"
import { testRender } from "@opentui/solid"
import { onMount } from "solid-js"
import { ProjectProvider, useProject } from "../../../src/context/project"
import { ClientProvider, useClient } from "../../../src/context/client"
import { useEvent } from "../../../src/context/event"
import { createApi, createEventStream, createFetch } from "../../fixture/tui-client"
@@ -61,7 +60,6 @@ async function mount(
const calls = createFetch(undefined, events)
const seen: OpenCodeEvent[] = []
const workspaces: Array<string | undefined> = []
let project!: ReturnType<typeof useProject>
let client!: ReturnType<typeof useClient>
let done!: () => void
const ready = new Promise<void>((resolve) => {
@@ -71,32 +69,27 @@ async function mount(
const app = await testRender(() => (
<TestTuiContexts log={log}>
<ClientProvider api={createApi(calls.fetch)} reconnect={reconnect}>
<ProjectProvider>
<Probe
onReady={async (ctx) => {
project = ctx.project
client = ctx.client
await project.sync()
done()
}}
seen={seen}
workspaces={workspaces}
/>
</ProjectProvider>
<Probe
onReady={(ctx) => {
client = ctx.client
done()
}}
seen={seen}
workspaces={workspaces}
/>
</ClientProvider>
</TestTuiContexts>
))
await ready
return { app, events, emit: events.emit, project, client, seen, workspaces }
return { app, events, emit: events.emit, client, seen, workspaces }
}
function Probe(props: {
seen: OpenCodeEvent[]
workspaces: Array<string | undefined>
onReady: (ctx: { project: ReturnType<typeof useProject>; client: ReturnType<typeof useClient> }) => void
onReady: (ctx: { client: ReturnType<typeof useClient> }) => void
}) {
const project = useProject()
const client = useClient()
const event = useEvent()
@@ -105,7 +98,7 @@ function Probe(props: {
props.seen.push(evt)
props.workspaces.push(workspace)
})
props.onReady({ project, client })
props.onReady({ client })
})
return <box />
@@ -161,10 +154,9 @@ describe("useEvent", () => {
})
test("delivers current project events regardless of active workspace", async () => {
const { app, emit, project, seen } = await mount()
const { app, emit, seen } = await mount()
try {
project.workspace.set("ws_a")
emit(event(vcs("ws"), { directory: "/tmp/other", project: projectID, workspace: "ws_b" }))
await wait(() => seen.length === 1)
@@ -176,10 +168,9 @@ describe("useEvent", () => {
})
test("delivers truly global events even when a workspace is active", async () => {
const { app, emit, project, seen } = await mount()
const { app, emit, seen } = await mount()
try {
project.workspace.set("ws_a")
emit(event(update("1.2.3"), { directory: "global" }))
await wait(() => seen.length === 1)
@@ -256,9 +247,7 @@ describe("useEvent", () => {
return new Response(
new ReadableStream({
start(controller) {
controller.enqueue(
encoder.encode('data: {"id":"evt_connected","type":"server.connected","data":{}}\n\n'),
)
controller.enqueue(encoder.encode('data: {"id":"evt_connected","type":"server.connected","data":{}}\n\n'))
controller.close()
},
}),