import { type Instance, render } from "ink"; import { FullScreenBox } from "./FullScreenBox.js"; type InkRender = typeof render; type WithFullScreen = (...args: Parameters) => { instance: Instance; start: () => Promise; waitUntilExit: () => Promise; }; export async function enterAlternateBuffer() { await write("\x1b[?1049h"); // enter alternate buffer } export async function exitAlternateBuffer() { await write("\x1b[?1049l"); // exit alternate buffer } export async function write(content: string) { return new Promise((resolve, reject) => { process.stdout.write(content, (error) => { if (error) reject(error); else resolve(); }); }); } async function cleanUpOnExit(instance: Instance) { await instance.waitUntilExit(); restoreStdin(); await exitAlternateBuffer(); } function restoreStdin() { let { stdin } = process; if (!stdin.isTTY) { return; } if (typeof stdin.setRawMode === "function") { stdin.setRawMode(false); } stdin.pause(); } export const withFullScreen: WithFullScreen = (node, options) => { const instance = render(null, options); const exitPromise = cleanUpOnExit(instance); function waitUntilExit() { return exitPromise; } return { instance: instance, start: async () => { await enterAlternateBuffer(); instance.rerender({node}); }, waitUntilExit, }; };