( prompt: Prompt<Value, Config>, config: Config, options?: RenderOptions, )
| 7 | import { interpretTerminalOutput } from './terminal.ts'; |
| 8 | |
| 9 | export async function render<Value, const Config>( |
| 10 | prompt: Prompt<Value, Config>, |
| 11 | config: Config, |
| 12 | options?: RenderOptions, |
| 13 | ): Promise<{ |
| 14 | answer: Promise<Value>; |
| 15 | input: MuteStream; |
| 16 | events: { |
| 17 | keypress: ( |
| 18 | key: string | { name?: string; ctrl?: boolean; meta?: boolean; shift?: boolean }, |
| 19 | ) => void; |
| 20 | type: (text: string) => void; |
| 21 | }; |
| 22 | getScreen: ({ raw }?: { raw?: boolean }) => string; |
| 23 | getFullOutput: ({ raw }?: { raw?: boolean }) => Promise<string>; |
| 24 | nextRender: () => Promise<void>; |
| 25 | }> { |
| 26 | const input = new MuteStream(); |
| 27 | input.unmute(); |
| 28 | |
| 29 | const output = new BufferedStream(); |
| 30 | const firstRender = new Promise<void>((resolve) => output.once('render', resolve)); |
| 31 | |
| 32 | const answer = prompt(config, { ...options, input, output }); |
| 33 | |
| 34 | // The first render is synchronous. If our BufferedStream received a write, we're ready. |
| 35 | if (output.writeCount === 0) { |
| 36 | // Our BufferedStream didn't receive a write yet. This happens when the prompt |
| 37 | // errored before rendering. Race against the answer promise to handle that case. |
| 38 | await Promise.race([firstRender, answer.catch(() => {})]); |
| 39 | } |
| 40 | |
| 41 | const events = { |
| 42 | keypress( |
| 43 | key: |
| 44 | | string |
| 45 | | { |
| 46 | name?: string; |
| 47 | ctrl?: boolean; |
| 48 | meta?: boolean; |
| 49 | shift?: boolean; |
| 50 | }, |
| 51 | ) { |
| 52 | if (typeof key === 'string') { |
| 53 | input.emit('keypress', null, { name: key }); |
| 54 | } else { |
| 55 | input.emit('keypress', null, key); |
| 56 | } |
| 57 | }, |
| 58 | type(text: string) { |
| 59 | input.write(text); |
| 60 | for (const char of text) { |
| 61 | input.emit('keypress', null, { name: char }); |
| 62 | } |
| 63 | }, |
| 64 | }; |
| 65 | |
| 66 | let rendersConsumed = output.writeCount; |
no test coverage detected