summaryrefslogtreecommitdiffhomepage
path: root/packages
diff options
context:
space:
mode:
authorDax Raad <[email protected]>2025-11-25 21:32:56 -0500
committerDax Raad <[email protected]>2025-11-25 21:32:56 -0500
commit50c40a8d99bb4bcce4b978eaf9a9bd38101336fa (patch)
treecb223f3f436187a3e8aab549403112a433ea991d /packages
parent4114c8715c65bf55c7c1d81daf87b6d3639968e3 (diff)
downloadopencode-50c40a8d99bb4bcce4b978eaf9a9bd38101336fa.tar.gz
opencode-50c40a8d99bb4bcce4b978eaf9a9bd38101336fa.zip
tui: fix event subscription cleanup in SDK context
Diffstat (limited to 'packages')
-rw-r--r--packages/opencode/src/cli/cmd/tui/context/sdk.tsx73
1 files changed, 40 insertions, 33 deletions
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<Event, { type: key }>
}>()
- 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
+
+ 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)
+ }
+ })
+ }
- for await (const event of events.stream) {
- queue.push(event)
- const elapsed = Date.now() - last
+ 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
+ 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()
- }
- // Flush any remaining events
- if (timer) clearTimeout(timer)
- if (queue.length > 0) {
- flush()
+ // Flush any remaining events
+ if (timer) clearTimeout(timer)
+ if (queue.length > 0) {
+ flush()
+ }
}
})