diff --git a/packages/opencode/src/cli/cmd/tui/context/sdk.tsx b/packages/opencode/src/cli/cmd/tui/context/sdk.tsx index fa3b1c633..401a53ab4 100644 --- a/packages/opencode/src/cli/cmd/tui/context/sdk.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/sdk.tsx @@ -1,7 +1,8 @@ import { createOpencodeClient, type Event } from "@opencode-ai/sdk" import { createSimpleContext } from "./helper" import { createGlobalEmitter } from "@solid-primitives/event-bus" -import { batch, onCleanup } from "solid-js" +import { batch, onCleanup, onMount } from "solid-js" +import { iife } from "@/util/iife" export const { use: useSDK, provider: SDKProvider } = createSimpleContext({ name: "SDK", @@ -16,43 +17,49 @@ export const { use: useSDK, provider: SDKProvider } = createSimpleContext({ [key in Event["type"]]: Extract }>() - sdk.event.subscribe().then(async (events) => { - let queue: Event[] = [] - let timer: Timer | undefined - let last = 0 - - const flush = () => { - if (queue.length === 0) return - const events = queue - queue = [] - timer = undefined - last = Date.now() - // Batch all event emissions so all store updates result in a single render - batch(() => { - for (const event of events) { - emitter.emit(event.type, event) - } + onMount(async () => { + while (true) { + if (abort.signal.aborted) break + const events = await sdk.event.subscribe({ + signal: abort.signal, }) - } + let queue: Event[] = [] + let timer: Timer | undefined + let last = 0 - for await (const event of events.stream) { - queue.push(event) - const elapsed = Date.now() - last - - if (timer) continue - // If we just flushed recently (within 16ms), batch this with future events - // Otherwise, process immediately to avoid latency - if (elapsed < 16) { - timer = setTimeout(flush, 16) - continue + const flush = () => { + if (queue.length === 0) return + const events = queue + queue = [] + timer = undefined + last = Date.now() + // Batch all event emissions so all store updates result in a single render + batch(() => { + for (const event of events) { + emitter.emit(event.type, event) + } + }) } - flush() - } - // Flush any remaining events - if (timer) clearTimeout(timer) - if (queue.length > 0) { - flush() + for await (const event of events.stream) { + queue.push(event) + const elapsed = Date.now() - last + + if (timer) continue + // If we just flushed recently (within 16ms), batch this with future events + // Otherwise, process immediately to avoid latency + if (elapsed < 16) { + timer = setTimeout(flush, 16) + continue + } + flush() + } + + // Flush any remaining events + if (timer) clearTimeout(timer) + if (queue.length > 0) { + flush() + } } })