restty 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.
Files changed (44) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +101 -0
  3. package/dist/app/atlas-builder.d.ts +81 -0
  4. package/dist/app/index.d.ts +3 -0
  5. package/dist/app/types.d.ts +133 -0
  6. package/dist/fonts/index.d.ts +4 -0
  7. package/dist/fonts/manager.d.ts +21 -0
  8. package/dist/fonts/nerd-constraints.d.ts +23 -0
  9. package/dist/fonts/nerd-ranges.d.ts +2 -0
  10. package/dist/fonts/types.d.ts +40 -0
  11. package/dist/grid/grid.d.ts +22 -0
  12. package/dist/grid/index.d.ts +2 -0
  13. package/dist/grid/types.d.ts +24 -0
  14. package/dist/ime/ime.d.ts +14 -0
  15. package/dist/ime/index.d.ts +2 -0
  16. package/dist/ime/types.d.ts +10 -0
  17. package/dist/index.d.ts +16 -0
  18. package/dist/index.js +30821 -0
  19. package/dist/input/index.d.ts +6 -0
  20. package/dist/input/keymap.d.ts +24 -0
  21. package/dist/input/mouse.d.ts +38 -0
  22. package/dist/input/output.d.ts +53 -0
  23. package/dist/input/types.d.ts +159 -0
  24. package/dist/pty/index.d.ts +2 -0
  25. package/dist/pty/pty.d.ts +8 -0
  26. package/dist/pty/types.d.ts +36 -0
  27. package/dist/renderer/box-drawing-map.d.ts +1 -0
  28. package/dist/renderer/index.d.ts +5 -0
  29. package/dist/renderer/shaders.d.ts +7 -0
  30. package/dist/renderer/shapes.d.ts +40 -0
  31. package/dist/renderer/types.d.ts +80 -0
  32. package/dist/renderer/webgpu.d.ts +19 -0
  33. package/dist/restty-input.d.ts +1 -0
  34. package/dist/selection/index.d.ts +2 -0
  35. package/dist/selection/selection.d.ts +13 -0
  36. package/dist/selection/types.d.ts +14 -0
  37. package/dist/theme/builtin-themes.d.ts +3 -0
  38. package/dist/theme/catalog.d.ts +7 -0
  39. package/dist/theme/ghostty.d.ts +23 -0
  40. package/dist/theme/index.d.ts +2 -0
  41. package/dist/wasm/embedded.d.ts +1 -0
  42. package/dist/wasm/index.d.ts +1 -0
  43. package/dist/wasm/runtime.d.ts +155 -0
  44. package/package.json +55 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Wiedy Mi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # restty
2
+
3
+ ![CI](https://img.shields.io/badge/CI-GitHub%20Actions-2088FF?logo=githubactions&logoColor=white)
4
+ ![Bun](https://img.shields.io/badge/Bun-%3E%3D1.2.0-f9f1e1?logo=bun&logoColor=000)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
6
+
7
+ Experimental project: browser terminal rendering with a WASM terminal core, GPU rendering (WebGPU + WebGL2 fallback), and TypeScript text shaping.
8
+
9
+ restty combines a Zig/WASM VT engine, modern browser rendering pipelines, and a local playground + PTY server to iterate quickly on terminal behavior.
10
+
11
+ ## Why
12
+
13
+ - Build a browser terminal stack with explicit control over rendering and input.
14
+ - Keep terminal state logic in WASM while using TS/JS for browser integration.
15
+ - Validate behavior with focused tests (input mapping, UTF-8 handling, kitty graphics, glyph rendering).
16
+ - Iterate visually via a local playground without heavy framework overhead.
17
+
18
+ ## How it works
19
+
20
+ 1. PTY output bytes are fed into the WASM terminal core.
21
+ 2. WASM exposes render/cell state to the TypeScript runtime.
22
+ 3. Text shaping and glyph atlas generation happen in TS.
23
+ 4. Renderer draws frames via WebGPU (or WebGL2 fallback).
24
+ 5. Input (keyboard/mouse/IME) is encoded and sent back to PTY.
25
+
26
+ ## Documentation
27
+
28
+ - Start here: `docs/README.md`
29
+ - Initial goals and scope: `docs/goals.md`
30
+ - End-to-end runtime flow: `docs/how-it-works.md`
31
+ - Integration and usage: `docs/usage.md`
32
+ - Internal architecture notes: `docs/internals/`
33
+
34
+ ## Repository layout
35
+
36
+ - `src/` - Main library/runtime code (renderer, input, PTY bridge, app integration).
37
+ - `tests/` - Bun test suite.
38
+ - `playground/` - Browser playground app and local PTY websocket server.
39
+ - `playground/public/` - Playground static assets (fonts/wasm bundles).
40
+ - `assets/themes/` - Source-of-truth Ghostty theme files.
41
+ - `scripts/` - Setup helper scripts.
42
+ - `wasm/` - Zig source and build config for the WASM core.
43
+ - `docs/` - User docs, architecture notes, and development references.
44
+ - `reference/ghostty` - Upstream Ghostty reference (submodule).
45
+ - `reference/text-shaper` - Upstream text-shaper reference (submodule).
46
+
47
+ ## Requirements
48
+
49
+ - Bun `>=1.2.0`
50
+ - Git with submodule support
51
+ - Optional: Zig (if rebuilding WASM artifacts from source)
52
+
53
+ ## Quick start
54
+
55
+ ```bash
56
+ git submodule update --init --recursive
57
+ bun install
58
+ bun run build:themes
59
+ bun run build:assets
60
+ bun run playground
61
+ ```
62
+
63
+ Open `http://localhost:5173`.
64
+
65
+ ## Commands
66
+
67
+ ```bash
68
+ # Run all tests
69
+ bun run test
70
+
71
+ # Start PTY websocket server (default ws://localhost:8787/pty)
72
+ bun run pty
73
+
74
+ # Build playground/runtime bundles
75
+ bun run build:assets
76
+
77
+ # Regenerate embedded built-in theme catalog for the library
78
+ bun run build:themes
79
+
80
+ # Lint + format checks
81
+ bun run lint
82
+ bun run format:check
83
+
84
+ # Serve playground static files only
85
+ bun run playground:static
86
+ ```
87
+
88
+ ## Testing
89
+
90
+ Current suite covers:
91
+
92
+ - key/input encoding (`tests/input-keymap.test.ts`, `tests/input-kitty.test.ts`)
93
+ - PTY UTF-8 stream behavior (`tests/pty-utf8.test.ts`)
94
+ - output filtering and kitty graphics (`tests/output-filter.test.ts`, `tests/kitty-*.test.ts`)
95
+ - renderer/glyph checks (`tests/box-drawing.test.ts`, `tests/webgpu-glyph.test.ts`)
96
+
97
+ ## Notes
98
+
99
+ - `tests/webgpu-glyph.test.ts` can bootstrap polyfill artifacts via `scripts/setup-wgpu-polyfill.ts`.
100
+ - Built-in themes are embedded in `src/theme/builtin-themes.ts` (generated via `scripts/generate-builtin-themes.ts`).
101
+ - Some generated playground assets are intentionally committed for reproducible local runs.
@@ -0,0 +1,81 @@
1
+ export type GlyphConstraintMeta = {
2
+ cp: number;
3
+ constraintWidth: number;
4
+ variable?: boolean;
5
+ widths?: Set<number>;
6
+ };
7
+ export type AtlasConstraintContext = {
8
+ cellW: number;
9
+ cellH: number;
10
+ yPad: number;
11
+ baselineOffset: number;
12
+ baselineAdjust: number;
13
+ fontScale: number;
14
+ nerdMetrics: {
15
+ cellWidth: number;
16
+ cellHeight: number;
17
+ faceWidth: number;
18
+ faceHeight: number;
19
+ faceY: number;
20
+ iconHeight: number;
21
+ iconHeightSingle: number;
22
+ };
23
+ fontEntry: any;
24
+ };
25
+ type BuildAtlasDeps = {
26
+ fontScaleOverrides: Array<{
27
+ match: RegExp;
28
+ scale: number;
29
+ }>;
30
+ sizeMode: string;
31
+ isSymbolFont: (entry: any) => boolean;
32
+ fontScaleOverride: (entry: any, overrides: Array<{
33
+ match: RegExp;
34
+ scale: number;
35
+ }>) => number;
36
+ resolveGlyphPixelMode: (entry: any) => number;
37
+ atlasBitmapToRGBA: (atlas: any) => Uint8Array | null;
38
+ padAtlasRGBA: (rgba: Uint8Array, atlas: any, padding: number) => Uint8Array;
39
+ buildAtlas: (font: any, glyphIds: number[], options: any) => any;
40
+ buildGlyphAtlasWithConstraints: (options: any) => {
41
+ atlas: any;
42
+ constrainedGlyphWidths?: any;
43
+ } | null;
44
+ buildColorEmojiAtlasWithCanvas: (options: any) => {
45
+ atlas: any;
46
+ } | null;
47
+ rasterizeGlyph?: any;
48
+ rasterizeGlyphWithTransform?: any;
49
+ nerdConstraintSignature: (glyphMeta: Map<number, GlyphConstraintMeta> | undefined, constraintContext: AtlasConstraintContext | null | undefined) => string;
50
+ constants: {
51
+ atlasPadding: number;
52
+ symbolAtlasPadding: number;
53
+ symbolAtlasMaxSize: number;
54
+ defaultAtlasMaxSize: number;
55
+ pixelModeRgbaValue: number;
56
+ };
57
+ resolvePreferNearest: (params: {
58
+ fontIndex: number;
59
+ isSymbol: boolean;
60
+ atlasScale: number;
61
+ }) => boolean;
62
+ };
63
+ export type BuildFontAtlasParams = {
64
+ entry: any;
65
+ neededGlyphIds: Set<number>;
66
+ glyphMeta?: Map<number, GlyphConstraintMeta>;
67
+ fontSizePx: number;
68
+ atlasScale: number;
69
+ fontIndex: number;
70
+ constraintContext?: AtlasConstraintContext | null;
71
+ deps: BuildAtlasDeps;
72
+ };
73
+ export type BuildFontAtlasResult = {
74
+ rebuilt: boolean;
75
+ atlas: any | null;
76
+ rgba: Uint8Array | null;
77
+ colorGlyphs?: Set<number>;
78
+ preferNearest: boolean;
79
+ };
80
+ export declare function buildFontAtlasIfNeeded(params: BuildFontAtlasParams): BuildFontAtlasResult;
81
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { ResttyApp, ResttyAppOptions } from "./types";
2
+ export type { TextShaper, ResttyAppElements, ResttyAppCallbacks, FontSource, ResttyAppOptions, ResttyApp, } from "./types";
3
+ export declare function createResttyApp(options: ResttyAppOptions): ResttyApp;
@@ -0,0 +1,133 @@
1
+ import type { InputHandler } from "../input";
2
+ import type { GhosttyTheme } from "../theme";
3
+ export type TextShaper = {
4
+ Font: {
5
+ loadAsync: (buffer: ArrayBuffer) => Promise<any>;
6
+ collection?: (buffer: ArrayBuffer) => {
7
+ names: () => Array<{
8
+ index: number;
9
+ fullName?: string;
10
+ family?: string;
11
+ postScriptName?: string;
12
+ }>;
13
+ get: (index: number) => any;
14
+ } | null;
15
+ };
16
+ UnicodeBuffer: new () => {
17
+ addStr: (text: string) => void;
18
+ };
19
+ shape: (font: any, buffer: any) => any;
20
+ glyphBufferToShapedGlyphs: (glyphBuffer: any) => Array<{
21
+ glyphId: number;
22
+ xAdvance: number;
23
+ xOffset: number;
24
+ yOffset: number;
25
+ }>;
26
+ buildAtlas: (font: any, glyphIds: number[], options: any) => any;
27
+ atlasToRGBA: (atlas: any) => Uint8Array | null;
28
+ rasterizeGlyph?: (font: any, glyphId: number, fontSize: number, options?: any) => {
29
+ bitmap: any;
30
+ bearingX: number;
31
+ bearingY: number;
32
+ } | null;
33
+ rasterizeGlyphWithTransform?: (font: any, glyphId: number, fontSize: number, matrix: number[] | number[][], options?: any) => {
34
+ bitmap: any;
35
+ bearingX: number;
36
+ bearingY: number;
37
+ } | null;
38
+ PixelMode: {
39
+ Gray: any;
40
+ RGBA?: any;
41
+ };
42
+ };
43
+ export type ResttyAppElements = {
44
+ backendEl?: HTMLElement | null;
45
+ fpsEl?: HTMLElement | null;
46
+ dprEl?: HTMLElement | null;
47
+ sizeEl?: HTMLElement | null;
48
+ gridEl?: HTMLElement | null;
49
+ cellEl?: HTMLElement | null;
50
+ termSizeEl?: HTMLElement | null;
51
+ cursorPosEl?: HTMLElement | null;
52
+ inputDebugEl?: HTMLElement | null;
53
+ dbgEl?: HTMLElement | null;
54
+ ptyStatusEl?: HTMLElement | null;
55
+ mouseStatusEl?: HTMLElement | null;
56
+ termDebugEl?: HTMLElement | null;
57
+ logEl?: HTMLElement | null;
58
+ atlasInfoEl?: HTMLElement | null;
59
+ atlasCanvas?: HTMLCanvasElement | null;
60
+ };
61
+ export type ResttyAppCallbacks = {
62
+ onLog?: (line: string) => void;
63
+ onBackend?: (backend: string) => void;
64
+ onFps?: (fps: number) => void;
65
+ onDpr?: (dpr: number) => void;
66
+ onCanvasSize?: (width: number, height: number) => void;
67
+ onGridSize?: (cols: number, rows: number) => void;
68
+ onCellSize?: (cellW: number, cellH: number) => void;
69
+ onTermSize?: (cols: number, rows: number) => void;
70
+ onCursor?: (col: number, row: number) => void;
71
+ onDebug?: (text: string) => void;
72
+ onInputDebug?: (text: string) => void;
73
+ onPtyStatus?: (status: string) => void;
74
+ onMouseStatus?: (status: string) => void;
75
+ };
76
+ export type FontSource = {
77
+ name: string;
78
+ url?: string;
79
+ buffer?: ArrayBuffer;
80
+ matchers?: string[];
81
+ };
82
+ export type ResttyAppOptions = {
83
+ canvas: HTMLCanvasElement;
84
+ imeInput?: HTMLTextAreaElement | null;
85
+ textShaper: TextShaper;
86
+ elements?: ResttyAppElements;
87
+ callbacks?: ResttyAppCallbacks;
88
+ renderer?: "auto" | "webgpu" | "webgl2";
89
+ fontSize?: number;
90
+ assetBaseUrl?: string;
91
+ alphaBlending?: "native" | "linear" | "linear-corrected";
92
+ fontSources?: {
93
+ primary?: {
94
+ url?: string;
95
+ buffer?: ArrayBuffer;
96
+ matchers?: string[];
97
+ };
98
+ fallbacks?: FontSource[];
99
+ };
100
+ maxSymbolAtlasScale?: number;
101
+ fontScaleOverrides?: {
102
+ match: RegExp;
103
+ scale: number;
104
+ }[];
105
+ nerdIconScale?: number;
106
+ autoResize?: boolean;
107
+ attachWindowEvents?: boolean;
108
+ attachCanvasEvents?: boolean;
109
+ debugExpose?: boolean;
110
+ };
111
+ export type ResttyApp = {
112
+ init: () => Promise<void>;
113
+ destroy: () => void;
114
+ setRenderer: (value: "auto" | "webgpu" | "webgl2") => void;
115
+ setPaused: (value: boolean) => void;
116
+ togglePause: () => void;
117
+ setFontSize: (value: number) => void;
118
+ applyTheme: (theme: GhosttyTheme, sourceLabel?: string) => void;
119
+ resetTheme: () => void;
120
+ sendInput: (text: string, source?: string) => void;
121
+ sendKeyInput: (text: string, source?: string) => void;
122
+ clearScreen: () => void;
123
+ connectPty: (url: string) => void;
124
+ disconnectPty: () => void;
125
+ isPtyConnected: () => boolean;
126
+ setMouseMode: (value: string) => void;
127
+ getMouseStatus: () => ReturnType<InputHandler["getMouseStatus"]>;
128
+ copySelectionToClipboard: () => Promise<boolean>;
129
+ pasteFromClipboard: () => Promise<boolean>;
130
+ dumpAtlasForCodepoint: (cp: number) => void;
131
+ updateSize: (force?: boolean) => void;
132
+ getBackend: () => string;
133
+ };
@@ -0,0 +1,4 @@
1
+ export * from "./types";
2
+ export * from "./manager";
3
+ export * from "./nerd-ranges";
4
+ export * from "./nerd-constraints";
@@ -0,0 +1,21 @@
1
+ import type { FontEntry, FontManagerState, ShapedCluster, FallbackFontSource, FontScaleOverride } from "./types";
2
+ export declare function isSymbolFont(entry: FontEntry | null | undefined): boolean;
3
+ export declare function isNerdSymbolFont(entry: FontEntry | null | undefined): boolean;
4
+ export declare function isColorEmojiFont(entry: FontEntry | null | undefined): boolean;
5
+ export declare function fontMaxCellSpan(entry: FontEntry | null | undefined): number;
6
+ export declare function fontScaleOverride(entry: FontEntry | null | undefined, overrides?: FontScaleOverride[]): number;
7
+ export declare function fontRasterScale(entry: FontEntry | null | undefined, fontIndex: number, maxSymbolAtlasScale: number, overrides?: FontScaleOverride[]): number;
8
+ export declare function createFontEntry(font: any, label: string): FontEntry;
9
+ export declare function resetFontEntry(entry: FontEntry): void;
10
+ export declare function createFontManagerState(): FontManagerState;
11
+ export declare function fontHasGlyph(font: any, ch: string): boolean;
12
+ export declare function fontAdvanceUnits(entry: FontEntry, shapeClusterWithFont: (entry: FontEntry, text: string) => ShapedCluster): number;
13
+ export declare function glyphWidthUnits(entry: FontEntry, glyphId: number | undefined | null): number;
14
+ export declare function pickFontIndexForText(state: FontManagerState, text: string, expectedSpan: number, shapeClusterWithFont: (entry: FontEntry, text: string) => ShapedCluster): number;
15
+ export declare function tryFetchFontBuffer(url: string): Promise<ArrayBuffer | null>;
16
+ export declare function tryLocalFontBuffer(matchers: string[]): Promise<ArrayBuffer | null>;
17
+ export declare function loadPrimaryFontBuffer(localMatchers: string[], fallbackUrl: string, fallbackLocalMatchers: string[]): Promise<ArrayBuffer>;
18
+ export declare function loadFallbackFontBuffers(sources: FallbackFontSource[]): Promise<{
19
+ name: string;
20
+ buffer: ArrayBuffer;
21
+ }[]>;
@@ -0,0 +1,23 @@
1
+ export type NerdConstraint = {
2
+ size?: "none" | "fit" | "cover" | "fit_cover1" | "stretch";
3
+ align_horizontal?: "none" | "start" | "end" | "center" | "center1";
4
+ align_vertical?: "none" | "start" | "end" | "center" | "center1";
5
+ height?: "cell" | "icon";
6
+ pad_left?: number;
7
+ pad_right?: number;
8
+ pad_top?: number;
9
+ pad_bottom?: number;
10
+ relative_width?: number;
11
+ relative_height?: number;
12
+ relative_x?: number;
13
+ relative_y?: number;
14
+ max_xy_ratio?: number;
15
+ max_constraint_width?: number;
16
+ };
17
+ export type NerdConstraintRange = {
18
+ start: number;
19
+ end: number;
20
+ constraint: NerdConstraint;
21
+ };
22
+ export declare const NERD_CONSTRAINTS: NerdConstraintRange[];
23
+ export declare function getNerdConstraint(cp: number): NerdConstraint | null;
@@ -0,0 +1,2 @@
1
+ export declare const NERD_SYMBOL_RANGES: Array<[number, number]>;
2
+ export declare function isNerdSymbolCodepoint(cp: number): boolean;
@@ -0,0 +1,40 @@
1
+ export type FontEntry = {
2
+ font: any;
3
+ label: string;
4
+ glyphCache: Map<string, ShapedCluster>;
5
+ boundsCache: Map<number, number>;
6
+ colorGlyphTexts: Map<number, string>;
7
+ glyphIds: Set<number>;
8
+ atlas: any | null;
9
+ fontSizePx: number;
10
+ atlasScale: number;
11
+ advanceUnits: number;
12
+ constraintSignature?: string;
13
+ };
14
+ export type ShapedCluster = {
15
+ glyphs: ShapedGlyph[];
16
+ advance: number;
17
+ };
18
+ export type ShapedGlyph = {
19
+ glyphId: number;
20
+ xAdvance: number;
21
+ yAdvance: number;
22
+ xOffset: number;
23
+ yOffset: number;
24
+ };
25
+ export type FontManagerState = {
26
+ font: any | null;
27
+ fonts: FontEntry[];
28
+ fontSizePx: number;
29
+ sizeMode: "height" | "width" | "upem";
30
+ fontPickCache: Map<string, number>;
31
+ };
32
+ export type FallbackFontSource = {
33
+ name: string;
34
+ url: string;
35
+ matchers: string[];
36
+ };
37
+ export type FontScaleOverride = {
38
+ match: RegExp;
39
+ scale: number;
40
+ };
@@ -0,0 +1,22 @@
1
+ import type { CellMetrics, GridConfig, GridState } from "./types";
2
+ export type FontMetricsProvider = {
3
+ scaleForSize(sizePx: number, sizeMode: string): number;
4
+ glyphIdForChar(char: string): number | undefined | null;
5
+ advanceWidth(glyphId: number): number;
6
+ readonly ascender: number;
7
+ readonly descender?: number;
8
+ readonly height?: number;
9
+ readonly upem: number;
10
+ };
11
+ export type ShapeResult = {
12
+ advance: number;
13
+ };
14
+ export declare function fontHeightUnits(font: FontMetricsProvider): number;
15
+ export declare function computeCellMetrics(font: FontMetricsProvider, config: GridConfig, dpr: number, shapeCluster: (text: string) => ShapeResult): CellMetrics | null;
16
+ export declare function createGridState(): GridState;
17
+ export declare function updateGridState(state: GridState, metrics: CellMetrics, canvasWidth: number, canvasHeight: number): {
18
+ changed: boolean;
19
+ cols: number;
20
+ rows: number;
21
+ };
22
+ export declare function clamp(value: number, min: number, max: number): number;
@@ -0,0 +1,2 @@
1
+ export * from "./types";
2
+ export * from "./grid";
@@ -0,0 +1,24 @@
1
+ export type GridState = {
2
+ cols: number;
3
+ rows: number;
4
+ cellW: number;
5
+ cellH: number;
6
+ fontSizePx: number;
7
+ scale: number;
8
+ lineHeight: number;
9
+ baselineOffset: number;
10
+ yPad: number;
11
+ };
12
+ export type CellMetrics = {
13
+ cellW: number;
14
+ cellH: number;
15
+ fontSizePx: number;
16
+ scale: number;
17
+ lineHeight: number;
18
+ baselineOffset: number;
19
+ yPad: number;
20
+ };
21
+ export type GridConfig = {
22
+ fontSize: number;
23
+ sizeMode: "height" | "width" | "upem";
24
+ };
@@ -0,0 +1,14 @@
1
+ import type { ImeState, CursorPosition } from "./types";
2
+ export declare function createImeState(): ImeState;
3
+ export declare function setPreedit(state: ImeState, text: string, imeInput?: HTMLInputElement | null): void;
4
+ export declare function clearPreedit(state: ImeState, imeInput?: HTMLInputElement | null): void;
5
+ export declare function startComposition(state: ImeState, data: string, imeInput?: HTMLInputElement | null): void;
6
+ export declare function updateComposition(state: ImeState, data: string, imeInput?: HTMLInputElement | null): void;
7
+ export declare function endComposition(state: ImeState): string;
8
+ export declare function syncImeSelection(state: ImeState, imeInput: HTMLInputElement | null): void;
9
+ export declare function updateImePosition(imeInput: HTMLInputElement | null, cursor: CursorPosition | null, cellW: number, cellH: number, dpr: number, canvasRect: DOMRect): void;
10
+ export declare const PREEDIT_BG: readonly [0.16, 0.16, 0.2, 0.9];
11
+ export declare const PREEDIT_ACTIVE_BG: readonly [0.3, 0.32, 0.42, 0.95];
12
+ export declare const PREEDIT_FG: readonly [0.95, 0.95, 0.98, 1];
13
+ export declare const PREEDIT_UL: readonly [0.7, 0.7, 0.8, 0.9];
14
+ export declare const PREEDIT_CARET: readonly [0.95, 0.95, 0.98, 1];
@@ -0,0 +1,2 @@
1
+ export * from "./types";
2
+ export * from "./ime";
@@ -0,0 +1,10 @@
1
+ export type ImeState = {
2
+ composing: boolean;
3
+ preedit: string;
4
+ selectionStart: number;
5
+ selectionEnd: number;
6
+ };
7
+ export type CursorPosition = {
8
+ row: number;
9
+ col: number;
10
+ };
@@ -0,0 +1,16 @@
1
+ export { type Color, type RectData, type GlyphBox, type NerdMetrics, type WebGPUState, type WebGLState, type WebGLAtlasState, type AtlasState, type RendererState, type RendererConfig, type ResizeState, type ScrollbarState, BOX_STYLE_NONE, BOX_STYLE_LIGHT, BOX_STYLE_HEAVY, BOX_STYLE_DOUBLE, BOX_LINE_MAP, RECT_SHADER, GLYPH_SHADER, isPrivateUse, isSpaceCp, isBoxDrawing, isBlockElement, isLegacyComputing, isPowerline, isBraille, isGraphicsElement, isSymbolCp, applyAlpha, pushRect, pushRectSnapped, pushRectBox, drawBlockElement, drawBoxDrawing, drawBraille, drawPowerline, constrainGlyphBox, initWebGPU, initWebGL, ensureInstanceBuffer, ensureGLInstanceBuffer, configureContext, createResizeState, createScrollbarState, } from "./renderer";
2
+ export { type GridState, type CellMetrics, type GridConfig, type FontMetricsProvider, type ShapeResult, fontHeightUnits, computeCellMetrics, createGridState, updateGridState, clamp, } from "./grid";
3
+ export { type FontEntry, type FontManagerState, type ShapedCluster, type ShapedGlyph, type FallbackFontSource, type FontScaleOverride, type NerdConstraint, type NerdConstraintRange, isSymbolFont, isNerdSymbolFont, fontMaxCellSpan, fontScaleOverride, fontRasterScale, createFontEntry, resetFontEntry, createFontManagerState, fontHasGlyph, fontAdvanceUnits, glyphWidthUnits, pickFontIndexForText, tryFetchFontBuffer, tryLocalFontBuffer, loadPrimaryFontBuffer, loadFallbackFontBuffers, isNerdSymbolCodepoint, NERD_SYMBOL_RANGES, getNerdConstraint, NERD_CONSTRAINTS, } from "./fonts";
4
+ export { type SelectionState, type SelectionRange, type CellTextGetter, createSelectionState, clearSelection, startSelection, updateSelection, endSelection, selectionForRow, getSelectionText, normalizeSelectionCell, positionToCell, copyToClipboard, pasteFromClipboard, } from "./selection";
5
+ export type { CellPosition } from "./selection";
6
+ export { type ImeState, createImeState, setPreedit, clearPreedit, startComposition, updateComposition, endComposition, syncImeSelection, updateImePosition, PREEDIT_BG, PREEDIT_ACTIVE_BG, PREEDIT_FG, PREEDIT_UL, PREEDIT_CARET, } from "./ime";
7
+ export type { CursorPosition } from "./ime";
8
+ export { type PtyMessage, type PtyStatusMessage, type PtyErrorMessage, type PtyExitMessage, type PtyServerMessage, type PtyConnectionState, type PtyCallbacks, createPtyConnection, connectPty, disconnectPty, sendPtyInput, sendPtyResize, isPtyConnected, } from "./pty";
9
+ export { createInputHandler } from "./input";
10
+ export type { InputHandler, InputHandlerConfig, InputHandlerOptions, MouseMode, MouseStatus, } from "./input";
11
+ export { loadResttyWasm, ResttyWasm } from "./wasm";
12
+ export type { WasmAbi, WasmAbiKind, CursorInfo, RenderState, ResttyWasmExports, ResttyWasmOptions, } from "./wasm";
13
+ export { parseGhosttyTheme, parseGhosttyColor, colorToFloats, colorToRgbU32, listBuiltinThemeNames, isBuiltinThemeName, getBuiltinThemeSource, getBuiltinTheme, } from "./theme";
14
+ export type { GhosttyTheme, ThemeColor, ResttyBuiltinThemeName } from "./theme";
15
+ export { createResttyApp } from "./app";
16
+ export type { ResttyApp, ResttyAppOptions, ResttyAppElements, ResttyAppCallbacks, TextShaper, } from "./app";