| 83 | onFrame?: (event: FrameEvent) => void; |
| 84 | }; |
| 85 | export default class Ink { |
| 86 | private readonly log: LogUpdate; |
| 87 | private readonly terminal: Terminal; |
| 88 | private scheduleRender: (() => void) & { |
| 89 | cancel?: () => void; |
| 90 | }; |
| 91 | // Ignore last render after unmounting a tree to prevent empty output before exit |
| 92 | private isUnmounted = false; |
| 93 | private isPaused = false; |
| 94 | private readonly container: FiberRoot; |
| 95 | private rootNode: dom.DOMElement; |
| 96 | readonly focusManager: FocusManager; |
| 97 | private renderer: Renderer; |
| 98 | private readonly stylePool: StylePool; |
| 99 | private charPool: CharPool; |
| 100 | private hyperlinkPool: HyperlinkPool; |
| 101 | private exitPromise: Promise<void>; |
| 102 | private restoreConsole?: () => void; |
| 103 | private restoreStderr?: () => void; |
| 104 | private readonly unsubscribeTTYHandlers?: () => void; |
| 105 | private terminalColumns: number; |
| 106 | private terminalRows: number; |
| 107 | private currentNode: ReactNode = null; |
| 108 | private frontFrame: Frame; |
| 109 | private backFrame: Frame; |
| 110 | private logicalFrontFrame: Frame; |
| 111 | private logicalBackFrame: Frame; |
| 112 | private lastPoolResetTime = performance.now(); |
| 113 | private drainTimer: ReturnType<typeof setTimeout> | null = null; |
| 114 | private lastYogaCounters: { |
| 115 | ms: number; |
| 116 | visited: number; |
| 117 | measured: number; |
| 118 | cacheHits: number; |
| 119 | live: number; |
| 120 | } = { |
| 121 | ms: 0, |
| 122 | visited: 0, |
| 123 | measured: 0, |
| 124 | cacheHits: 0, |
| 125 | live: 0 |
| 126 | }; |
| 127 | // Timestamp of the most recent onRender() call (direct or scheduled). |
| 128 | // Used in the deferredRender microtask to skip stale renders that were |
| 129 | // superseded by a direct caller (e.g. forceRedraw) before the microtask ran. |
| 130 | private lastRenderAt = 0; |
| 131 | private altScreenParkPatch: Readonly<{ |
| 132 | type: 'stdout'; |
| 133 | content: string; |
| 134 | }>; |
| 135 | // Text selection state (alt-screen only). Owned here so the overlay |
| 136 | // pass in onRender can read it and App.tsx can update it from mouse |
| 137 | // events. Public so instances.get() callers can access. |
| 138 | readonly selection: SelectionState = createSelectionState(); |
| 139 | // Search highlight query (alt-screen only). Setter below triggers |
| 140 | // scheduleRender; applySearchHighlight in onRender inverts matching cells. |
| 141 | private searchHighlightQuery = ''; |
| 142 | // Position-based highlight. VML scans positions ONCE (via |
nothing calls this directly
no test coverage detected