import { useRenderer } from "@opentui/solid" import { createSimpleContext } from "./helper" import { FormatError, FormatUnknownError } from "@/cli/error" import { win32FlushInputBuffer } from "../win32" type Exit = ((reason?: unknown) => Promise) & { message: { set: (value?: string) => () => void clear: () => void get: () => string | undefined } } export const { use: useExit, provider: ExitProvider } = createSimpleContext({ name: "Exit", init: (input: { onBeforeExit?: () => Promise; onExit?: () => Promise }) => { const renderer = useRenderer() let message: string | undefined let task: Promise | undefined const store = { set: (value?: string) => { const prev = message message = value return () => { message = prev } }, clear: () => { message = undefined }, get: () => message, } const exit: Exit = Object.assign( (reason?: unknown) => { if (task) return task task = (async () => { await input.onBeforeExit?.() // Reset window title before destroying renderer renderer.setTerminalTitle("") renderer.destroy() win32FlushInputBuffer() if (reason) { const formatted = FormatError(reason) ?? FormatUnknownError(reason) if (formatted) { process.stderr.write(formatted + "\n") } } const text = store.get() if (text) process.stdout.write(text + "\n") await input.onExit?.() })() return task }, { message: store, }, ) process.on("SIGHUP", () => exit()) return exit }, })