ink-native 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +389 -0
- package/dist/chunk-3NCUBVFY.js +124915 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +412 -0
- package/dist/index.d.ts +714 -0
- package/dist/index.js +26 -0
- package/fonts/Cozette.bdf +93671 -0
- package/native/fenster.dylib +0 -0
- package/native/fenster.h +443 -0
- package/native/fenster_bridge.c +149 -0
- package/package.json +71 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,714 @@
|
|
|
1
|
+
import { Readable, Writable } from 'node:stream';
|
|
2
|
+
import { EventEmitter } from 'node:events';
|
|
3
|
+
|
|
4
|
+
/** RGB color value */
|
|
5
|
+
interface Color {
|
|
6
|
+
r: number;
|
|
7
|
+
g: number;
|
|
8
|
+
b: number;
|
|
9
|
+
}
|
|
10
|
+
/** Types of draw commands */
|
|
11
|
+
type DrawCommandType = "text" | "clear_screen" | "clear_line" | "cursor_move" | "set_fg" | "set_bg" | "reset_style" | "set_bold" | "set_dim" | "set_italic" | "set_underline" | "set_strikethrough" | "set_reverse";
|
|
12
|
+
/** A single draw command from parsed ANSI output */
|
|
13
|
+
interface DrawCommand {
|
|
14
|
+
type: DrawCommandType;
|
|
15
|
+
text?: string;
|
|
16
|
+
row?: number;
|
|
17
|
+
col?: number;
|
|
18
|
+
color?: Color;
|
|
19
|
+
enabled?: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* ANSI Parser
|
|
24
|
+
*
|
|
25
|
+
* Parses terminal ANSI escape sequences and converts them to draw commands
|
|
26
|
+
* for rendering in a native framebuffer window.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* ANSI sequence parser
|
|
31
|
+
*
|
|
32
|
+
* Parses ANSI escape sequences from terminal output and produces
|
|
33
|
+
* draw commands for framebuffer rendering.
|
|
34
|
+
*/
|
|
35
|
+
declare class AnsiParser {
|
|
36
|
+
private cursorRow;
|
|
37
|
+
private cursorCol;
|
|
38
|
+
private fgColor;
|
|
39
|
+
private bgColor;
|
|
40
|
+
private bold;
|
|
41
|
+
/**
|
|
42
|
+
* Parse an ANSI string and return draw commands
|
|
43
|
+
*/
|
|
44
|
+
parse(input: string): DrawCommand[];
|
|
45
|
+
/**
|
|
46
|
+
* Process an escape sequence and emit draw commands
|
|
47
|
+
*/
|
|
48
|
+
private processEscapeSequence;
|
|
49
|
+
/**
|
|
50
|
+
* Process cursor position sequence
|
|
51
|
+
*/
|
|
52
|
+
private processCursorPosition;
|
|
53
|
+
/**
|
|
54
|
+
* Process erase display sequence
|
|
55
|
+
*/
|
|
56
|
+
private processEraseDisplay;
|
|
57
|
+
/**
|
|
58
|
+
* Process erase line sequence
|
|
59
|
+
*/
|
|
60
|
+
private processEraseLine;
|
|
61
|
+
/**
|
|
62
|
+
* Process SGR (Select Graphic Rendition) sequence
|
|
63
|
+
*/
|
|
64
|
+
private processSGR;
|
|
65
|
+
/**
|
|
66
|
+
* Parse extended color (256-color or 24-bit)
|
|
67
|
+
*/
|
|
68
|
+
private parseExtendedColor;
|
|
69
|
+
/**
|
|
70
|
+
* Reset all styles to default
|
|
71
|
+
*/
|
|
72
|
+
private resetStyle;
|
|
73
|
+
/**
|
|
74
|
+
* Get current cursor position
|
|
75
|
+
*/
|
|
76
|
+
getCursor(): {
|
|
77
|
+
row: number;
|
|
78
|
+
col: number;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Get current foreground color
|
|
82
|
+
*/
|
|
83
|
+
getFgColor(): Color;
|
|
84
|
+
/**
|
|
85
|
+
* Get current background color
|
|
86
|
+
*/
|
|
87
|
+
getBgColor(): Color;
|
|
88
|
+
/**
|
|
89
|
+
* Reset parser state
|
|
90
|
+
*/
|
|
91
|
+
reset(): void;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Bitmap Font Renderer
|
|
96
|
+
*
|
|
97
|
+
* Renders text using embedded Cozette bitmap font data directly into
|
|
98
|
+
* a Uint32Array framebuffer. Pure TypeScript -- no native dependencies,
|
|
99
|
+
* no caching needed (just bit tests and pixel writes).
|
|
100
|
+
*/
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Bitmap Font Renderer
|
|
104
|
+
*
|
|
105
|
+
* Blits bitmap font glyphs directly into a Uint32Array pixel buffer.
|
|
106
|
+
*/
|
|
107
|
+
declare class BitmapFontRenderer {
|
|
108
|
+
private fallbackGlyph;
|
|
109
|
+
/**
|
|
110
|
+
* Get the fixed character cell dimensions
|
|
111
|
+
*/
|
|
112
|
+
getCharDimensions(): {
|
|
113
|
+
width: number;
|
|
114
|
+
height: number;
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Check if a glyph is double-width based on its data length
|
|
118
|
+
*
|
|
119
|
+
* Wide glyphs have 2 bytes per row (26 bytes total) vs 1 byte (13 bytes).
|
|
120
|
+
*/
|
|
121
|
+
isWideGlyph(codepoint: number): boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Get the pixel width of a glyph
|
|
124
|
+
*/
|
|
125
|
+
getGlyphPixelWidth(codepoint: number): number;
|
|
126
|
+
/**
|
|
127
|
+
* Measure the total pixel width of a text string
|
|
128
|
+
*/
|
|
129
|
+
measureText(text: string): number;
|
|
130
|
+
/**
|
|
131
|
+
* Render a single character into the framebuffer
|
|
132
|
+
*/
|
|
133
|
+
renderChar(buf: Uint32Array, bufWidth: number, x: number, y: number, codepoint: number, fgColor: number, italic?: boolean): void;
|
|
134
|
+
/**
|
|
135
|
+
* Render a string of text into the framebuffer
|
|
136
|
+
*
|
|
137
|
+
* Returns the total pixel width rendered.
|
|
138
|
+
*/
|
|
139
|
+
renderText(buf: Uint32Array, bufWidth: number, x: number, y: number, text: string, fgColor: number, italic?: boolean): number;
|
|
140
|
+
/**
|
|
141
|
+
* Render a single character scaled via nearest-neighbor into the framebuffer
|
|
142
|
+
*
|
|
143
|
+
* Maps each destination pixel back to the source glyph bitmap using
|
|
144
|
+
* nearest-neighbor sampling. Preserves the crisp, pixelated look of
|
|
145
|
+
* bitmap fonts on HiDPI displays.
|
|
146
|
+
*/
|
|
147
|
+
renderCharScaled(buf: Uint32Array, bufWidth: number, bufHeight: number, x: number, y: number, codepoint: number, fgColor: number, destWidth: number, destHeight: number, italic?: boolean): void;
|
|
148
|
+
/**
|
|
149
|
+
* Render a string of text scaled via nearest-neighbor into the framebuffer
|
|
150
|
+
*
|
|
151
|
+
* Returns the total pixel width rendered.
|
|
152
|
+
*/
|
|
153
|
+
renderTextScaled(buf: Uint32Array, bufWidth: number, bufHeight: number, x: number, y: number, text: string, fgColor: number, scale: number, italic?: boolean): number;
|
|
154
|
+
/**
|
|
155
|
+
* Measure the total scaled pixel width of a text string
|
|
156
|
+
*/
|
|
157
|
+
measureTextScaled(text: string, scale: number): number;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** Opaque pointer type for fenster bridge handle */
|
|
161
|
+
type FensterPointer = unknown;
|
|
162
|
+
/** Key event from fenster key state diffing */
|
|
163
|
+
interface FensterKeyEvent {
|
|
164
|
+
/** Key index in fenster's keys[256] array (mostly ASCII) */
|
|
165
|
+
keyIndex: number;
|
|
166
|
+
/** Whether the key is pressed (true) or released (false) */
|
|
167
|
+
pressed: boolean;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Fenster FFI Bindings
|
|
172
|
+
*
|
|
173
|
+
* Provides fenster bindings for framebuffer-based window rendering
|
|
174
|
+
* using koffi for foreign function interface. No system dependencies
|
|
175
|
+
* required beyond the bundled native library.
|
|
176
|
+
*/
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Fenster API wrapper class
|
|
180
|
+
*
|
|
181
|
+
* Provides type-safe access to the fenster bridge functions for
|
|
182
|
+
* framebuffer-based window rendering.
|
|
183
|
+
*/
|
|
184
|
+
declare class Fenster {
|
|
185
|
+
private lib;
|
|
186
|
+
private _create;
|
|
187
|
+
private _open;
|
|
188
|
+
private _loop;
|
|
189
|
+
private _close;
|
|
190
|
+
private _copyBuf;
|
|
191
|
+
private _getKeys;
|
|
192
|
+
private _getMod;
|
|
193
|
+
private _getSize;
|
|
194
|
+
private _getResized;
|
|
195
|
+
private _getScale;
|
|
196
|
+
private _setScale;
|
|
197
|
+
constructor();
|
|
198
|
+
private bindFunctions;
|
|
199
|
+
/**
|
|
200
|
+
* Create a new fenster window (does not open it yet)
|
|
201
|
+
*/
|
|
202
|
+
create(title: string, width: number, height: number): FensterPointer;
|
|
203
|
+
/**
|
|
204
|
+
* Open the fenster window
|
|
205
|
+
*/
|
|
206
|
+
open(f: FensterPointer): void;
|
|
207
|
+
/**
|
|
208
|
+
* Process events and present the buffer
|
|
209
|
+
*
|
|
210
|
+
* Returns 0 on success, non-zero if window should close.
|
|
211
|
+
*/
|
|
212
|
+
loop(f: FensterPointer): number;
|
|
213
|
+
/**
|
|
214
|
+
* Close the fenster window and free resources
|
|
215
|
+
*/
|
|
216
|
+
close(f: FensterPointer): void;
|
|
217
|
+
/**
|
|
218
|
+
* Copy pixel data into fenster's native buffer
|
|
219
|
+
*
|
|
220
|
+
* Accepts a Buffer (e.g. a view over a Uint32Array) and memcpy's it
|
|
221
|
+
* into the native pixel buffer so the next `loop()` call presents it.
|
|
222
|
+
*/
|
|
223
|
+
copyBuf(f: FensterPointer, src: Buffer): void;
|
|
224
|
+
/**
|
|
225
|
+
* Get the keys state array
|
|
226
|
+
*
|
|
227
|
+
* 256 entries; each entry is 1 (pressed) or 0 (released).
|
|
228
|
+
*/
|
|
229
|
+
getKeys(f: FensterPointer): number[];
|
|
230
|
+
/**
|
|
231
|
+
* Get the current modifier bitmask
|
|
232
|
+
*
|
|
233
|
+
* Bits: ctrl=1, shift=2, alt=4, meta=8
|
|
234
|
+
*/
|
|
235
|
+
getMod(f: FensterPointer): number;
|
|
236
|
+
/**
|
|
237
|
+
* Check if the window was resized since the last call
|
|
238
|
+
*
|
|
239
|
+
* Returns the new dimensions if resized, or null if no resize occurred.
|
|
240
|
+
* Clears the resize flag on read.
|
|
241
|
+
*/
|
|
242
|
+
getResized(f: FensterPointer): {
|
|
243
|
+
width: number;
|
|
244
|
+
height: number;
|
|
245
|
+
} | null;
|
|
246
|
+
/**
|
|
247
|
+
* Get the backing scale factor (1.0 = normal, 2.0 = Retina)
|
|
248
|
+
*/
|
|
249
|
+
getScale(f: FensterPointer): number;
|
|
250
|
+
/**
|
|
251
|
+
* Override the backing scale factor
|
|
252
|
+
*
|
|
253
|
+
* Recomputes physical dimensions from logical size * scale.
|
|
254
|
+
*/
|
|
255
|
+
setScale(f: FensterPointer, scale: number): void;
|
|
256
|
+
/**
|
|
257
|
+
* Get the window size
|
|
258
|
+
*/
|
|
259
|
+
getSize(f: FensterPointer): {
|
|
260
|
+
width: number;
|
|
261
|
+
height: number;
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Get the Fenster API singleton
|
|
266
|
+
*/
|
|
267
|
+
declare const getFenster: () => Fenster;
|
|
268
|
+
/**
|
|
269
|
+
* Check if fenster is available without throwing
|
|
270
|
+
*/
|
|
271
|
+
declare const isFensterAvailable: () => boolean;
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Input Stream for Ink
|
|
275
|
+
*
|
|
276
|
+
* A Readable stream that provides keyboard input to Ink from native window events.
|
|
277
|
+
* Implements the TTY interface expected by Ink.
|
|
278
|
+
*/
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Input Stream
|
|
282
|
+
*
|
|
283
|
+
* Wraps native keyboard events in a Node.js Readable stream that Ink
|
|
284
|
+
* can use as stdin.
|
|
285
|
+
*/
|
|
286
|
+
declare class InputStream extends Readable {
|
|
287
|
+
/** TTY interface properties expected by Ink */
|
|
288
|
+
isTTY: boolean;
|
|
289
|
+
isRaw: boolean;
|
|
290
|
+
private buffer;
|
|
291
|
+
private waiting;
|
|
292
|
+
constructor();
|
|
293
|
+
/**
|
|
294
|
+
* Push a key sequence into the stream
|
|
295
|
+
*/
|
|
296
|
+
pushKey(sequence: string): void;
|
|
297
|
+
/**
|
|
298
|
+
* Implement Readable._read
|
|
299
|
+
*/
|
|
300
|
+
_read(): void;
|
|
301
|
+
/**
|
|
302
|
+
* Set raw mode (no-op, we're always raw)
|
|
303
|
+
*/
|
|
304
|
+
setRawMode(_mode: boolean): this;
|
|
305
|
+
/**
|
|
306
|
+
* Check if stream has buffered data
|
|
307
|
+
*/
|
|
308
|
+
hasData(): boolean;
|
|
309
|
+
/**
|
|
310
|
+
* Clear the input buffer
|
|
311
|
+
*/
|
|
312
|
+
clear(): void;
|
|
313
|
+
/**
|
|
314
|
+
* Close the stream
|
|
315
|
+
*/
|
|
316
|
+
close(): void;
|
|
317
|
+
/**
|
|
318
|
+
* Keep the event loop alive (no-op)
|
|
319
|
+
*/
|
|
320
|
+
ref(): this;
|
|
321
|
+
/**
|
|
322
|
+
* Allow event loop to exit (no-op)
|
|
323
|
+
*/
|
|
324
|
+
unref(): this;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* OutputStream Types
|
|
329
|
+
*/
|
|
330
|
+
/** Duck-typed interface for any UI renderer compatible with OutputStream */
|
|
331
|
+
interface UiRendererLike {
|
|
332
|
+
getDimensions(): {
|
|
333
|
+
columns: number;
|
|
334
|
+
rows: number;
|
|
335
|
+
};
|
|
336
|
+
processAnsi(text: string): void;
|
|
337
|
+
present(): void;
|
|
338
|
+
clear(): void;
|
|
339
|
+
getCursorPos(): {
|
|
340
|
+
x: number;
|
|
341
|
+
y: number;
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Output Stream for Ink
|
|
347
|
+
*
|
|
348
|
+
* A Writable stream that intercepts Ink's ANSI output and renders it
|
|
349
|
+
* to a native window.
|
|
350
|
+
*/
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Output Stream
|
|
354
|
+
*
|
|
355
|
+
* Wraps a UiRenderer in a Node.js Writable stream that Ink
|
|
356
|
+
* can use as stdout.
|
|
357
|
+
*/
|
|
358
|
+
declare class OutputStream extends Writable {
|
|
359
|
+
/** TTY interface property expected by Ink */
|
|
360
|
+
isTTY: boolean;
|
|
361
|
+
private uiRenderer;
|
|
362
|
+
constructor(uiRenderer: UiRendererLike);
|
|
363
|
+
/**
|
|
364
|
+
* Get terminal columns
|
|
365
|
+
*/
|
|
366
|
+
get columns(): number;
|
|
367
|
+
/**
|
|
368
|
+
* Get terminal rows
|
|
369
|
+
*/
|
|
370
|
+
get rows(): number;
|
|
371
|
+
/**
|
|
372
|
+
* Notify Ink of resize
|
|
373
|
+
*/
|
|
374
|
+
notifyResize(): void;
|
|
375
|
+
/**
|
|
376
|
+
* Implement Writable._write
|
|
377
|
+
*/
|
|
378
|
+
_write(chunk: Buffer | string, _encoding: BufferEncoding, callback: (error?: Error | null) => void): void;
|
|
379
|
+
/**
|
|
380
|
+
* Get the underlying renderer
|
|
381
|
+
*/
|
|
382
|
+
getRenderer(): UiRendererLike;
|
|
383
|
+
/**
|
|
384
|
+
* Clear the screen
|
|
385
|
+
*/
|
|
386
|
+
clear(): void;
|
|
387
|
+
/**
|
|
388
|
+
* Write a string directly (bypasses Writable buffering)
|
|
389
|
+
*/
|
|
390
|
+
writeSync(text: string): void;
|
|
391
|
+
/**
|
|
392
|
+
* Get cursor position
|
|
393
|
+
*/
|
|
394
|
+
getCursorPos(): {
|
|
395
|
+
x: number;
|
|
396
|
+
y: number;
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/** Options for creating a UiRenderer */
|
|
401
|
+
interface UiRendererOptions {
|
|
402
|
+
/** Window width in pixels (default 800) */
|
|
403
|
+
width?: number;
|
|
404
|
+
/** Window height in pixels (default 600) */
|
|
405
|
+
height?: number;
|
|
406
|
+
/** Window title (default "ink-native") */
|
|
407
|
+
title?: string;
|
|
408
|
+
/** Background color as RGB tuple [r, g, b] or hex string "#RRGGBB" */
|
|
409
|
+
backgroundColor?: [number, number, number] | string | undefined;
|
|
410
|
+
/** HiDPI scale factor override (number = override, null/undefined = auto-detect) */
|
|
411
|
+
scaleFactor?: number | null;
|
|
412
|
+
}
|
|
413
|
+
/** Direct access to the native framebuffer pixel buffer */
|
|
414
|
+
interface Framebuffer {
|
|
415
|
+
/** Pixel buffer in 0xAARRGGBB format (physical resolution) */
|
|
416
|
+
pixels: Uint32Array;
|
|
417
|
+
/** Physical width in pixels */
|
|
418
|
+
width: number;
|
|
419
|
+
/** Physical height in pixels */
|
|
420
|
+
height: number;
|
|
421
|
+
}
|
|
422
|
+
/** Result from processing native window events */
|
|
423
|
+
interface ProcessEventsResult {
|
|
424
|
+
/** Key events detected by diffing the keys array */
|
|
425
|
+
keyEvents: FensterKeyEvent[];
|
|
426
|
+
/** Current modifier bitmask */
|
|
427
|
+
mod: number;
|
|
428
|
+
/** Whether the window was resized this frame */
|
|
429
|
+
resized: boolean;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* UI Renderer
|
|
434
|
+
*
|
|
435
|
+
* Renders Ink UI to a native framebuffer window by parsing ANSI sequences
|
|
436
|
+
* and drawing bitmap font glyphs directly into a pixel buffer.
|
|
437
|
+
* No GPU, no textures -- pure TypeScript pixel manipulation.
|
|
438
|
+
*/
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Pack RGB color into fenster's 0xAARRGGBB pixel format
|
|
442
|
+
*/
|
|
443
|
+
declare const packColor: (r: number, g: number, b: number) => number;
|
|
444
|
+
/**
|
|
445
|
+
* UI Renderer
|
|
446
|
+
*
|
|
447
|
+
* Renders Ink UI to a native framebuffer by parsing ANSI sequences
|
|
448
|
+
* and drawing bitmap font glyphs. Uses a JS-side Uint32Array for
|
|
449
|
+
* rendering, then copies to the native buffer on present.
|
|
450
|
+
*/
|
|
451
|
+
declare class UiRenderer {
|
|
452
|
+
private fenster;
|
|
453
|
+
private fensterPtr;
|
|
454
|
+
private fontRenderer;
|
|
455
|
+
private ansiParser;
|
|
456
|
+
/** Logical window dimensions (in points) */
|
|
457
|
+
private windowWidth;
|
|
458
|
+
private windowHeight;
|
|
459
|
+
/** Physical framebuffer dimensions (in pixels) */
|
|
460
|
+
private physicalWidth;
|
|
461
|
+
private physicalHeight;
|
|
462
|
+
/** Backing scale factor */
|
|
463
|
+
private scaleFactor;
|
|
464
|
+
/** User-requested scale factor override (null = auto-detect) */
|
|
465
|
+
private userScaleFactor;
|
|
466
|
+
/** Scaled glyph dimensions (in physical pixels) */
|
|
467
|
+
private scaledGlyphWidth;
|
|
468
|
+
private scaledGlyphHeight;
|
|
469
|
+
private columns;
|
|
470
|
+
private rows;
|
|
471
|
+
/** JS-side framebuffer for rendering (at physical resolution) */
|
|
472
|
+
private framebuffer;
|
|
473
|
+
/** Previous key state for diff-based event detection */
|
|
474
|
+
private prevKeys;
|
|
475
|
+
private fgColor;
|
|
476
|
+
private bgColor;
|
|
477
|
+
private defaultBgColor;
|
|
478
|
+
private bold;
|
|
479
|
+
private dim;
|
|
480
|
+
private italic;
|
|
481
|
+
private underline;
|
|
482
|
+
private strikethrough;
|
|
483
|
+
private reverse;
|
|
484
|
+
private shouldQuit;
|
|
485
|
+
private pendingCommands;
|
|
486
|
+
constructor(options?: UiRendererOptions);
|
|
487
|
+
/**
|
|
488
|
+
* Copy JS framebuffer to native fenster buffer
|
|
489
|
+
*/
|
|
490
|
+
private copyToNativeBuffer;
|
|
491
|
+
/**
|
|
492
|
+
* Process ANSI output from Ink
|
|
493
|
+
*/
|
|
494
|
+
processAnsi(output: string): void;
|
|
495
|
+
/**
|
|
496
|
+
* Render pending commands and prepare for present
|
|
497
|
+
*/
|
|
498
|
+
present(): void;
|
|
499
|
+
/**
|
|
500
|
+
* Process fenster events and present the buffer to screen
|
|
501
|
+
*
|
|
502
|
+
* Calls fenster_loop (which presents the buffer + polls events),
|
|
503
|
+
* then diffs the keys array to detect press/release events.
|
|
504
|
+
*/
|
|
505
|
+
processEventsAndPresent(): ProcessEventsResult;
|
|
506
|
+
/**
|
|
507
|
+
* Handle window resize by updating dimensions and recreating the framebuffer
|
|
508
|
+
*
|
|
509
|
+
* Receives physical dimensions from getResized() and derives logical
|
|
510
|
+
* dimensions using the current scale factor.
|
|
511
|
+
*/
|
|
512
|
+
private handleResize;
|
|
513
|
+
/**
|
|
514
|
+
* Convert a fenster key event to a terminal escape sequence
|
|
515
|
+
*/
|
|
516
|
+
keyEventToSequence(event: FensterKeyEvent, mod: number): string | null;
|
|
517
|
+
/**
|
|
518
|
+
* Check if quit was requested
|
|
519
|
+
*/
|
|
520
|
+
shouldClose(): boolean;
|
|
521
|
+
/**
|
|
522
|
+
* Reset input state (no-op for fenster, modifier state is polled)
|
|
523
|
+
*/
|
|
524
|
+
resetInputState(): void;
|
|
525
|
+
/**
|
|
526
|
+
* Get the display refresh rate (fixed for fenster)
|
|
527
|
+
*/
|
|
528
|
+
getDisplayRefreshRate(): number;
|
|
529
|
+
/**
|
|
530
|
+
* Get terminal dimensions
|
|
531
|
+
*/
|
|
532
|
+
getDimensions(): {
|
|
533
|
+
columns: number;
|
|
534
|
+
rows: number;
|
|
535
|
+
};
|
|
536
|
+
/**
|
|
537
|
+
* Get direct access to the framebuffer pixel buffer.
|
|
538
|
+
*
|
|
539
|
+
* The returned `pixels` array is the same backing buffer used by the
|
|
540
|
+
* renderer, so writes are immediately visible on the next `present()` call.
|
|
541
|
+
* Pixel format is 0xAARRGGBB — use `packColor(r, g, b)` to create values.
|
|
542
|
+
*/
|
|
543
|
+
getFramebuffer(): Framebuffer;
|
|
544
|
+
/**
|
|
545
|
+
* Clear the entire screen
|
|
546
|
+
*/
|
|
547
|
+
clear(): void;
|
|
548
|
+
/**
|
|
549
|
+
* Get cursor position
|
|
550
|
+
*/
|
|
551
|
+
getCursorPos(): {
|
|
552
|
+
x: number;
|
|
553
|
+
y: number;
|
|
554
|
+
};
|
|
555
|
+
/**
|
|
556
|
+
* Execute a single draw command
|
|
557
|
+
*/
|
|
558
|
+
private executeCommand;
|
|
559
|
+
/**
|
|
560
|
+
* Render text at position (using scaled coordinates for physical resolution)
|
|
561
|
+
*/
|
|
562
|
+
private renderText;
|
|
563
|
+
/**
|
|
564
|
+
* Fill a rectangle in the framebuffer (physical pixel coordinates)
|
|
565
|
+
*/
|
|
566
|
+
private fillRect;
|
|
567
|
+
/**
|
|
568
|
+
* Clear a line from a specific position (scaled coordinates)
|
|
569
|
+
*/
|
|
570
|
+
private clearLine;
|
|
571
|
+
/**
|
|
572
|
+
* Clean up resources
|
|
573
|
+
*/
|
|
574
|
+
destroy(): void;
|
|
575
|
+
/**
|
|
576
|
+
* Reset state for reuse
|
|
577
|
+
*/
|
|
578
|
+
reset(): void;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
/**
|
|
582
|
+
* Options for creating streams
|
|
583
|
+
*/
|
|
584
|
+
interface StreamsOptions {
|
|
585
|
+
/** Window title */
|
|
586
|
+
title?: string;
|
|
587
|
+
/** Window width in pixels */
|
|
588
|
+
width?: number;
|
|
589
|
+
/** Window height in pixels */
|
|
590
|
+
height?: number;
|
|
591
|
+
/** Background color as RGB tuple [r, g, b] or hex string "#RRGGBB" */
|
|
592
|
+
backgroundColor?: [number, number, number] | string | undefined;
|
|
593
|
+
/** Force a specific frame rate instead of default 60fps */
|
|
594
|
+
frameRate?: number | undefined;
|
|
595
|
+
/** HiDPI scale factor override (number = override, null/undefined = auto-detect) */
|
|
596
|
+
scaleFactor?: number | null;
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Result of createStreams
|
|
600
|
+
*/
|
|
601
|
+
interface Streams {
|
|
602
|
+
/** Readable stream for keyboard input */
|
|
603
|
+
stdin: InputStream;
|
|
604
|
+
/** Writable stream for ANSI output */
|
|
605
|
+
stdout: OutputStream;
|
|
606
|
+
/** Window wrapper with events */
|
|
607
|
+
window: Window;
|
|
608
|
+
/** UI renderer (for advanced use) */
|
|
609
|
+
renderer: UiRenderer;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* Window and Streams for Ink
|
|
614
|
+
*
|
|
615
|
+
* Factory function to create stdin/stdout streams that render to a
|
|
616
|
+
* native framebuffer window.
|
|
617
|
+
*/
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* Window wrapper that emits events
|
|
621
|
+
*
|
|
622
|
+
* Manages the event loop, key event processing, and stream coordination
|
|
623
|
+
* for the native window backend.
|
|
624
|
+
*/
|
|
625
|
+
declare class Window extends EventEmitter {
|
|
626
|
+
private renderer;
|
|
627
|
+
private eventLoopHandle;
|
|
628
|
+
private inputStream;
|
|
629
|
+
private outputStream;
|
|
630
|
+
private closed;
|
|
631
|
+
private paused;
|
|
632
|
+
private currentFrameRate;
|
|
633
|
+
constructor(renderer: UiRenderer, inputStream: InputStream, outputStream: OutputStream, frameRate?: number);
|
|
634
|
+
/**
|
|
635
|
+
* Start the event loop
|
|
636
|
+
*/
|
|
637
|
+
private startEventLoop;
|
|
638
|
+
/**
|
|
639
|
+
* Run a single iteration of the event loop
|
|
640
|
+
*/
|
|
641
|
+
private runEventLoopIteration;
|
|
642
|
+
/**
|
|
643
|
+
* Get terminal dimensions
|
|
644
|
+
*/
|
|
645
|
+
getDimensions(): {
|
|
646
|
+
columns: number;
|
|
647
|
+
rows: number;
|
|
648
|
+
};
|
|
649
|
+
/**
|
|
650
|
+
* Clear the screen
|
|
651
|
+
*/
|
|
652
|
+
clear(): void;
|
|
653
|
+
/**
|
|
654
|
+
* Close the window
|
|
655
|
+
*/
|
|
656
|
+
close(): void;
|
|
657
|
+
/**
|
|
658
|
+
* Check if window is closed
|
|
659
|
+
*/
|
|
660
|
+
isClosed(): boolean;
|
|
661
|
+
/**
|
|
662
|
+
* Pause the Ink event loop so the caller can take over rendering.
|
|
663
|
+
*
|
|
664
|
+
* While paused, call `renderer.processEventsAndPresent()` manually
|
|
665
|
+
* in your own loop to poll events and present the framebuffer.
|
|
666
|
+
*/
|
|
667
|
+
pause(): void;
|
|
668
|
+
/**
|
|
669
|
+
* Resume the Ink event loop after pausing.
|
|
670
|
+
*/
|
|
671
|
+
resume(): void;
|
|
672
|
+
/**
|
|
673
|
+
* Check if the event loop is paused
|
|
674
|
+
*/
|
|
675
|
+
isPaused(): boolean;
|
|
676
|
+
/**
|
|
677
|
+
* Get the output stream
|
|
678
|
+
*/
|
|
679
|
+
getOutputStream(): OutputStream;
|
|
680
|
+
/**
|
|
681
|
+
* Get the current frame rate
|
|
682
|
+
*/
|
|
683
|
+
getFrameRate(): number;
|
|
684
|
+
}
|
|
685
|
+
/**
|
|
686
|
+
* Create streams for use with Ink
|
|
687
|
+
*
|
|
688
|
+
* Creates stdin/stdout streams backed by a native window.
|
|
689
|
+
*
|
|
690
|
+
* @example
|
|
691
|
+
* ```typescript
|
|
692
|
+
* import { render, Text, Box } from "ink";
|
|
693
|
+
* import { createStreams } from "ink-native";
|
|
694
|
+
*
|
|
695
|
+
* const App = () => (
|
|
696
|
+
* <Box flexDirection="column">
|
|
697
|
+
* <Text color="green">Hello from ink-native!</Text>
|
|
698
|
+
* </Box>
|
|
699
|
+
* );
|
|
700
|
+
*
|
|
701
|
+
* const { stdin, stdout, window } = createStreams({
|
|
702
|
+
* title: "My App",
|
|
703
|
+
* width: 800,
|
|
704
|
+
* height: 600,
|
|
705
|
+
* });
|
|
706
|
+
*
|
|
707
|
+
* render(<App />, { stdin, stdout });
|
|
708
|
+
*
|
|
709
|
+
* window.on("close", () => process.exit(0));
|
|
710
|
+
* ```
|
|
711
|
+
*/
|
|
712
|
+
declare const createStreams: (options?: StreamsOptions) => Streams;
|
|
713
|
+
|
|
714
|
+
export { AnsiParser, BitmapFontRenderer, type Color, type DrawCommand, Fenster, type FensterKeyEvent, type FensterPointer, type Framebuffer, InputStream, OutputStream, type ProcessEventsResult, type Streams, type StreamsOptions, UiRenderer, type UiRendererOptions, Window, createStreams, getFenster, isFensterAvailable, packColor };
|