import { type ReactNode } from "react"; import { type ReadStream, type WriteStream } from "../types/io.js"; import { Tinky, type RenderMetrics } from "./tinky.js"; import { type IncrementalRenderingConfig, type IncrementalRenderingOption } from "./incremental-rendering.js"; export type { IncrementalRenderingConfig, IncrementalRenderingOption }; /** * Options for the render function. */ export interface RenderOptions { /** * Output stream where the app will be rendered. * * @defaultValue process.stdout */ stdout?: WriteStream; /** * Input stream where the app will listen for input. * * @defaultValue process.stdin */ stdin?: ReadStream; /** * Error stream. * * @defaultValue process.stderr */ stderr?: WriteStream; /** * If true, each update will be rendered as separate output, without * replacing. * * @defaultValue false */ debug?: boolean; /** * Configure whether Tinky should listen for Ctrl+C keyboard input and exit. * This is needed in raw mode, where Ctrl+C is ignored by default. * * @defaultValue true */ exitOnCtrlC?: boolean; /** * Patch console methods to ensure console output doesn't mix with Tinky's. * * @defaultValue true */ patchConsole?: boolean; /** * runs the given callback after each render and re-render. * * @param metrics - Performance metrics of the render. */ onRender?: (metrics: RenderMetrics) => void; /** * Enable screen reader support. * * @defaultValue process.env['TINKY_SCREEN_READER'] === 'true' */ isScreenReaderEnabled?: boolean; /** * Maximum frames per second for render updates. * Controls how frequently UI can update to prevent excessive re-rendering. * Higher values allow more frequent updates but may impact performance. * * @defaultValue 30 */ maxFps?: number; /** * Configure incremental rendering mode. * * - `true`: Enables run-diff incremental rendering. * - `false` or omitted: Disables incremental rendering. * - Object mode: * - `{ enabled: false }` disables incremental rendering. * - `{ strategy: "line" }` enables line-diff incremental rendering. * - `{ strategy: "run" }` (or omitted strategy) enables run-diff rendering. * * Runtime notes: * - In `run` strategy, terminal writes are skipped entirely when frames are unchanged. * - In `debug` mode, Tinky always writes full frames. * - In screen-reader mode, Tinky uses the screen-reader output path. * - In CI mode, Tinky avoids cursor-diff updates. * * @defaultValue false */ incrementalRendering?: IncrementalRenderingOption; /** * Environment variables. * * @defaultValue process.env */ env?: Record; } /** * Interface for the Tinky instance returned by render. */ export interface Instance { /** * Replace the previous root node with a new one or update props of current * root. * * @param node - The new React node to render. */ rerender: Tinky["render"]; /** * Manually unmount the whole Tinky app. * * @param error - Optional error or exit code. */ unmount: Tinky["unmount"]; /** * Returns a promise that resolves when the app is unmounted. * * @returns A promise that resolves when the app is unmounted. */ waitUntilExit: Tinky["waitUntilExit"]; /** * Cleanup the instance from the instances map. */ cleanup: () => void; /** * Clear output. */ clear: () => void; } /** * Mount a component and render the output. * * @param node - The React component to render. * @param options - Render options or the stdout stream. * @returns The Tinky instance. * * @example * ```tsx * import { render, Text } from 'tinky'; * * render(Hello World); * ``` * * @example * ```tsx * import { render, Text } from 'tinky'; * * const {unmount} = render(Hello World); * * setTimeout(() => { * unmount(); * }, 1000); * ``` */ export declare const render: (node: ReactNode, options?: RenderOptions) => Instance;