diff options
| author | Adam <[email protected]> | 2026-02-12 15:15:27 -0600 |
|---|---|---|
| committer | Adam <[email protected]> | 2026-02-12 15:15:34 -0600 |
| commit | 548608b7ad1252af3181201ef764b16c05d0b786 (patch) | |
| tree | e33c2f8c5a7f30fbb2a7f068010ee98c13656491 /packages/app/src/utils | |
| parent | 4e0f509e7b7d84395a541bdfa658f6c98f588221 (diff) | |
| download | opencode-548608b7ad1252af3181201ef764b16c05d0b786.tar.gz opencode-548608b7ad1252af3181201ef764b16c05d0b786.zip | |
fix(app): terminal pty isolation
Diffstat (limited to 'packages/app/src/utils')
| -rw-r--r-- | packages/app/src/utils/terminal-writer.test.ts | 33 | ||||
| -rw-r--r-- | packages/app/src/utils/terminal-writer.ts | 27 |
2 files changed, 60 insertions, 0 deletions
diff --git a/packages/app/src/utils/terminal-writer.test.ts b/packages/app/src/utils/terminal-writer.test.ts new file mode 100644 index 000000000..d48dd4f4e --- /dev/null +++ b/packages/app/src/utils/terminal-writer.test.ts @@ -0,0 +1,33 @@ +import { describe, expect, test } from "bun:test" +import { terminalWriter } from "./terminal-writer" + +describe("terminalWriter", () => { + test("buffers and flushes once per schedule", () => { + const calls: string[] = [] + const scheduled: VoidFunction[] = [] + const writer = terminalWriter( + (data) => calls.push(data), + (flush) => scheduled.push(flush), + ) + + writer.push("a") + writer.push("b") + writer.push("c") + + expect(calls).toEqual([]) + expect(scheduled).toHaveLength(1) + + scheduled[0]?.() + expect(calls).toEqual(["abc"]) + }) + + test("flush is a no-op when empty", () => { + const calls: string[] = [] + const writer = terminalWriter( + (data) => calls.push(data), + (flush) => flush(), + ) + writer.flush() + expect(calls).toEqual([]) + }) +}) diff --git a/packages/app/src/utils/terminal-writer.ts b/packages/app/src/utils/terminal-writer.ts new file mode 100644 index 000000000..b6caff789 --- /dev/null +++ b/packages/app/src/utils/terminal-writer.ts @@ -0,0 +1,27 @@ +export function terminalWriter( + write: (data: string) => void, + schedule: (flush: VoidFunction) => void = queueMicrotask, +) { + let chunks: string[] | undefined + let scheduled = false + + const flush = () => { + scheduled = false + const items = chunks + if (!items?.length) return + chunks = undefined + write(items.join("")) + } + + const push = (data: string) => { + if (!data) return + if (chunks) chunks.push(data) + else chunks = [data] + + if (scheduled) return + scheduled = true + schedule(flush) + } + + return { push, flush } +} |
