MCPcopy Create free account
hub / github.com/Noumena-Network/code / constructor

Method constructor

src/ink/ink.tsx:203–317  ·  view source on GitHub ↗
(private readonly options: Options)

Source from the content-addressed store, hash-verified

201 y: number;
202 } | null = null;
203 constructor(private readonly options: Options) {
204 autoBind(this);
205 this.exitPromise = new Promise((resolve, reject) => {
206 this.resolveExitPromise = resolve;
207 this.rejectExitPromise = reject;
208 });
209 if (this.options.patchConsole) {
210 this.restoreConsole = this.patchConsole();
211 this.restoreStderr = this.patchStderr();
212 }
213 this.terminal = {
214 stdout: options.stdout,
215 stderr: options.stderr
216 };
217 this.terminalColumns = options.stdout.columns || 80;
218 this.terminalRows = options.stdout.rows || 24;
219 this.altScreenParkPatch = makeAltScreenParkPatch(this.terminalRows);
220 this.stylePool = new StylePool();
221 this.charPool = new CharPool();
222 this.hyperlinkPool = new HyperlinkPool();
223 this.frontFrame = emptyFrame(this.terminalRows, this.terminalColumns, this.stylePool, this.charPool, this.hyperlinkPool);
224 this.backFrame = emptyFrame(this.terminalRows, this.terminalColumns, this.stylePool, this.charPool, this.hyperlinkPool);
225 this.logicalFrontFrame = this.frontFrame;
226 this.logicalBackFrame = this.backFrame;
227 this.log = new LogUpdate({
228 isTTY: options.stdout.isTTY as boolean | undefined || false,
229 stylePool: this.stylePool
230 });
231
232 // scheduleRender is called from the reconciler's resetAfterCommit, which
233 // runs BEFORE React's layout phase (ref attach + useLayoutEffect). Any
234 // state set in layout effects — notably the cursorDeclaration from
235 // useDeclaredCursor — would lag one commit behind if we rendered
236 // synchronously. Deferring to a microtask runs onRender after layout
237 // effects have committed, so the native cursor tracks the caret without
238 // a one-keystroke lag. Same event-loop tick, so throughput is unchanged.
239 // Test env uses onImmediateRender (direct onRender, no throttle) so
240 // existing synchronous lastFrame() tests are unaffected.
241 const deferredRender = (): void => {
242 const queuedAt = performance.now();
243 queueMicrotask(() => {
244 // If a direct caller (forceRedraw, pause, resume, drainTimer, etc.)
245 // already ran onRender after this microtask was queued, skip the
246 // redundant scheduled render.
247 if (this.lastRenderAt >= queuedAt) return;
248 this.onRender();
249 });
250 };
251 this.scheduleRender = throttle(deferredRender, FRAME_INTERVAL_MS, {
252 leading: true,
253 trailing: true
254 });
255
256 // Ignore last render after unmounting a tree to prevent empty output before exit
257 this.isUnmounted = false;
258
259 // Unmount when process exits
260 this.unsubscribeExit = onExit(this.unmount, {

Callers

nothing calls this directly

Calls 11

patchConsoleMethod · 0.95
patchStderrMethod · 0.95
makeAltScreenParkPatchFunction · 0.85
emptyFrameFunction · 0.85
createRendererFunction · 0.85
recordYogaMsFunction · 0.85
getYogaCountersFunction · 0.85
dispatchDiscreteMethod · 0.80
onExitFunction · 0.50
setWidthMethod · 0.45
calculateLayoutMethod · 0.45

Tested by

no test coverage detected