@dkkoval/tui-preview 0.1.1 → 0.2.1
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/README.md +24 -16
- package/dist/TuiPreview.js +91 -68
- package/dist/core/ghostty-vt.wasm +0 -0
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +2 -2
- package/dist/core/libghostty.d.ts +86 -0
- package/dist/core/libghostty.js +678 -0
- package/dist/core/normalize.d.ts +0 -1
- package/dist/core/normalize.js +20 -67
- package/dist/core/wasi.d.ts +8 -2
- package/dist/core/wasi.js +131 -22
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -363
- package/dist/types.d.ts +8 -26
- package/package.json +9 -11
- package/dist/__vite-browser-external-2447137e-BcPniuRQ.cjs +0 -1
- package/dist/__vite-browser-external-2447137e-DYxpcVy9.js +0 -4
- package/dist/core/ghostty.d.ts +0 -2
- package/dist/core/ghostty.js +0 -11
- package/dist/ghostty-web-BfBVpf8G.js +0 -2962
- package/dist/ghostty-web-DkOZu5AZ.cjs +0 -13
- package/dist/index.cjs +0 -1
- package/dist/wasi.d.ts +0 -1
- package/dist/wasi.js +0 -2
package/dist/index.js
CHANGED
|
@@ -1,363 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var k = (e, t, n) => $(e, typeof t != "symbol" ? t + "" : t, n);
|
|
4
|
-
import { jsxs as D, jsx as L } from "react/jsx-runtime";
|
|
5
|
-
import { useMemo as Y, useRef as M, useState as R, useEffect as T } from "react";
|
|
6
|
-
let p = null;
|
|
7
|
-
function q() {
|
|
8
|
-
return p || (p = import("./ghostty-web-BfBVpf8G.js").then(async (e) => (await e.init(), e))), p;
|
|
9
|
-
}
|
|
10
|
-
const S = { cols: 80, rows: 24 }, P = {}, Z = [];
|
|
11
|
-
function J(e) {
|
|
12
|
-
return "wasm" in e;
|
|
13
|
-
}
|
|
14
|
-
function I(e) {
|
|
15
|
-
const t = e ?? Z;
|
|
16
|
-
return typeof t == "function" ? t : () => t;
|
|
17
|
-
}
|
|
18
|
-
function K(e) {
|
|
19
|
-
return e.cols !== void 0 || e.rows !== void 0 ? {
|
|
20
|
-
fit: "none",
|
|
21
|
-
size: {
|
|
22
|
-
cols: Math.max(1, e.cols ?? S.cols),
|
|
23
|
-
rows: Math.max(1, e.rows ?? S.rows)
|
|
24
|
-
}
|
|
25
|
-
} : { fit: "container", size: S };
|
|
26
|
-
}
|
|
27
|
-
let W = !1;
|
|
28
|
-
function X(e) {
|
|
29
|
-
!e || W || (W = !0, console.warn(
|
|
30
|
-
"[tui-preview] Legacy props (`app`, `args`, `cols`, `rows`, `fontSize`, `fontFamily`, `theme`) are deprecated. Use `wasm`, `argv`, `fit`, `size`, and `terminal`."
|
|
31
|
-
));
|
|
32
|
-
}
|
|
33
|
-
function tt(e) {
|
|
34
|
-
var i, s, r, o, c, u, a, h, m;
|
|
35
|
-
if (J(e)) {
|
|
36
|
-
const v = e.fit ?? (e.size ? "none" : "container"), w = v === "none" ? {
|
|
37
|
-
cols: Math.max(1, ((i = e.size) == null ? void 0 : i.cols) ?? S.cols),
|
|
38
|
-
rows: Math.max(1, ((s = e.size) == null ? void 0 : s.rows) ?? S.rows)
|
|
39
|
-
} : {
|
|
40
|
-
cols: Math.max(1, ((r = e.size) == null ? void 0 : r.cols) ?? S.cols),
|
|
41
|
-
rows: Math.max(1, ((o = e.size) == null ? void 0 : o.rows) ?? S.rows)
|
|
42
|
-
}, y = e.mode ?? "terminal";
|
|
43
|
-
return {
|
|
44
|
-
wasm: e.wasm,
|
|
45
|
-
env: e.env ?? P,
|
|
46
|
-
interactive: y === "static" ? !1 : e.interactive ?? !0,
|
|
47
|
-
mode: y,
|
|
48
|
-
fit: v,
|
|
49
|
-
size: w,
|
|
50
|
-
terminal: {
|
|
51
|
-
fontSize: ((c = e.terminal) == null ? void 0 : c.fontSize) ?? 14,
|
|
52
|
-
fontFamily: ((u = e.terminal) == null ? void 0 : u.fontFamily) ?? "monospace",
|
|
53
|
-
cursorBlink: ((a = e.terminal) == null ? void 0 : a.cursorBlink) ?? !0,
|
|
54
|
-
convertEol: ((h = e.terminal) == null ? void 0 : h.convertEol) ?? !0,
|
|
55
|
-
theme: (m = e.terminal) == null ? void 0 : m.theme
|
|
56
|
-
},
|
|
57
|
-
resolveArgv: I(e.argv),
|
|
58
|
-
onExit: e.onExit,
|
|
59
|
-
onError: e.onError,
|
|
60
|
-
onStatusChange: e.onStatusChange,
|
|
61
|
-
usedLegacyProps: !1
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
const { fit: t, size: n } = K(e);
|
|
65
|
-
return {
|
|
66
|
-
wasm: e.app,
|
|
67
|
-
env: e.env ?? P,
|
|
68
|
-
interactive: e.interactive ?? !0,
|
|
69
|
-
mode: "terminal",
|
|
70
|
-
fit: t,
|
|
71
|
-
size: n,
|
|
72
|
-
terminal: {
|
|
73
|
-
fontSize: e.fontSize ?? 14,
|
|
74
|
-
fontFamily: e.fontFamily ?? "monospace",
|
|
75
|
-
cursorBlink: !0,
|
|
76
|
-
convertEol: !0,
|
|
77
|
-
theme: e.theme
|
|
78
|
-
},
|
|
79
|
-
resolveArgv: I(e.args),
|
|
80
|
-
onExit: e.onExit,
|
|
81
|
-
onError: e.onError,
|
|
82
|
-
onStatusChange: e.onStatusChange,
|
|
83
|
-
usedLegacyProps: !0
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
const d = 0, et = 6, x = 8, nt = 0, O = 1, rt = 2;
|
|
87
|
-
class it {
|
|
88
|
-
constructor(t) {
|
|
89
|
-
k(this, "inputQueue", []);
|
|
90
|
-
k(this, "memory");
|
|
91
|
-
this.opts = t;
|
|
92
|
-
}
|
|
93
|
-
/** Push keyboard data from the terminal into the app's stdin */
|
|
94
|
-
pushInput(t) {
|
|
95
|
-
const n = typeof t == "string" ? new TextEncoder().encode(t) : t;
|
|
96
|
-
this.inputQueue.push(n);
|
|
97
|
-
}
|
|
98
|
-
/** Attach the WASM instance's memory after instantiation */
|
|
99
|
-
attachMemory(t) {
|
|
100
|
-
this.memory = t;
|
|
101
|
-
}
|
|
102
|
-
view() {
|
|
103
|
-
return new DataView(this.memory.buffer);
|
|
104
|
-
}
|
|
105
|
-
u8() {
|
|
106
|
-
return new Uint8Array(this.memory.buffer);
|
|
107
|
-
}
|
|
108
|
-
// ── WASI imports object ────────────────────────────────────────────────
|
|
109
|
-
get imports() {
|
|
110
|
-
return {
|
|
111
|
-
args_sizes_get: (t, n) => {
|
|
112
|
-
const { args: i } = this.opts, s = new TextEncoder(), r = i.reduce((o, c) => o + s.encode(c).length + 1, 0);
|
|
113
|
-
return this.view().setUint32(t, i.length, !0), this.view().setUint32(n, r, !0), d;
|
|
114
|
-
},
|
|
115
|
-
args_get: (t, n) => {
|
|
116
|
-
const i = new TextEncoder(), s = this.u8(), r = this.view();
|
|
117
|
-
let o = n;
|
|
118
|
-
return this.opts.args.forEach((c, u) => {
|
|
119
|
-
const a = i.encode(c);
|
|
120
|
-
s.set(a, o), s[o + a.length] = 0, r.setUint32(t + u * 4, o, !0), o += a.length + 1;
|
|
121
|
-
}), d;
|
|
122
|
-
},
|
|
123
|
-
environ_sizes_get: (t, n) => {
|
|
124
|
-
const i = this.envEntries(), s = new TextEncoder(), r = i.reduce((o, c) => o + s.encode(c).length + 1, 0);
|
|
125
|
-
return this.view().setUint32(t, i.length, !0), this.view().setUint32(n, r, !0), d;
|
|
126
|
-
},
|
|
127
|
-
environ_get: (t, n) => {
|
|
128
|
-
const i = new TextEncoder(), s = this.u8(), r = this.view();
|
|
129
|
-
let o = n;
|
|
130
|
-
return this.envEntries().forEach((c, u) => {
|
|
131
|
-
const a = i.encode(c);
|
|
132
|
-
s.set(a, o), s[o + a.length] = 0, r.setUint32(t + u * 4, o, !0), o += a.length + 1;
|
|
133
|
-
}), d;
|
|
134
|
-
},
|
|
135
|
-
fd_write: (t, n, i, s) => {
|
|
136
|
-
if (t !== O && t !== rt) return x;
|
|
137
|
-
const r = this.view(), o = this.u8();
|
|
138
|
-
let c = 0;
|
|
139
|
-
const u = [];
|
|
140
|
-
for (let m = 0; m < i; m++) {
|
|
141
|
-
const v = r.getUint32(n + m * 8, !0), w = r.getUint32(n + m * 8 + 4, !0);
|
|
142
|
-
u.push(o.slice(v, v + w)), c += w;
|
|
143
|
-
}
|
|
144
|
-
const a = new Uint8Array(c);
|
|
145
|
-
let h = 0;
|
|
146
|
-
for (const m of u)
|
|
147
|
-
a.set(m, h), h += m.length;
|
|
148
|
-
return t === O ? this.opts.stdout(a) : this.opts.stderr(a), r.setUint32(s, c, !0), d;
|
|
149
|
-
},
|
|
150
|
-
fd_read: (t, n, i, s) => {
|
|
151
|
-
if (t !== nt) return x;
|
|
152
|
-
const r = this.inputQueue.shift();
|
|
153
|
-
if (!r) return et;
|
|
154
|
-
const o = this.view(), c = this.u8();
|
|
155
|
-
let u = 0;
|
|
156
|
-
for (let a = 0; a < i && u < r.length; a++) {
|
|
157
|
-
const h = o.getUint32(n + a * 8, !0), m = o.getUint32(n + a * 8 + 4, !0), v = Math.min(m, r.length - u);
|
|
158
|
-
c.set(r.subarray(u, u + v), h), u += v;
|
|
159
|
-
}
|
|
160
|
-
return o.setUint32(s, u, !0), d;
|
|
161
|
-
},
|
|
162
|
-
poll_oneoff: (t, n, i, s) => {
|
|
163
|
-
const r = this.view();
|
|
164
|
-
let o = 0;
|
|
165
|
-
for (let c = 0; c < i; c++) {
|
|
166
|
-
const u = t + c * 48, a = r.getUint8(u + 8);
|
|
167
|
-
if (a === 0 && this.inputQueue.length > 0) {
|
|
168
|
-
const h = n + o * 32;
|
|
169
|
-
r.setBigUint64(h, r.getBigUint64(u, !0), !0), r.setUint16(h + 8, 0, !0), r.setUint8(h + 10, a), o++;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
return r.setUint32(s, o, !0), d;
|
|
173
|
-
},
|
|
174
|
-
proc_exit: (t) => {
|
|
175
|
-
throw this.opts.onExit(t), new Q(t);
|
|
176
|
-
},
|
|
177
|
-
random_get: (t, n) => (crypto.getRandomValues(new Uint8Array(this.memory.buffer, t, n)), d),
|
|
178
|
-
// Stubs for calls TUI apps may make but we don't need to implement.
|
|
179
|
-
fd_close: () => d,
|
|
180
|
-
fd_seek: () => d,
|
|
181
|
-
fd_fdstat_get: (t, n) => (this.view().setUint8(n, t <= 2 ? 2 : 0), d),
|
|
182
|
-
fd_prestat_get: () => x,
|
|
183
|
-
fd_prestat_dir_name: () => x,
|
|
184
|
-
path_open: () => x,
|
|
185
|
-
sched_yield: () => d,
|
|
186
|
-
clock_time_get: (t, n, i) => {
|
|
187
|
-
const s = BigInt(Date.now()) * 1000000n;
|
|
188
|
-
return this.view().setBigUint64(i, s, !0), d;
|
|
189
|
-
}
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
envEntries() {
|
|
193
|
-
const t = {
|
|
194
|
-
TERM: "xterm-256color",
|
|
195
|
-
COLORTERM: "truecolor",
|
|
196
|
-
...this.opts.env
|
|
197
|
-
};
|
|
198
|
-
return Object.entries(t).map(([n, i]) => `${n}=${i}`);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
class Q extends Error {
|
|
202
|
-
constructor(t) {
|
|
203
|
-
super(`WASI exit: ${t}`), this.code = t;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
const N = /* @__PURE__ */ new Map();
|
|
207
|
-
async function ot(e, t) {
|
|
208
|
-
const n = e.toString();
|
|
209
|
-
let i = N.get(n);
|
|
210
|
-
if (!i) {
|
|
211
|
-
const u = await (await fetch(e)).arrayBuffer();
|
|
212
|
-
i = await WebAssembly.compile(u), N.set(n, i);
|
|
213
|
-
}
|
|
214
|
-
const s = {
|
|
215
|
-
wasi_snapshot_preview1: t.imports
|
|
216
|
-
}, r = await WebAssembly.instantiate(i, s);
|
|
217
|
-
t.attachMemory(r.exports.memory);
|
|
218
|
-
const o = r.exports._start;
|
|
219
|
-
if (!o) throw new Error("WASM module has no _start export");
|
|
220
|
-
return {
|
|
221
|
-
run: async () => {
|
|
222
|
-
try {
|
|
223
|
-
o();
|
|
224
|
-
} catch (c) {
|
|
225
|
-
if (!(c instanceof Q)) throw c;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
function ut(e) {
|
|
231
|
-
var v;
|
|
232
|
-
const t = Y(() => tt(e), [e]), n = M(null), i = M(null), s = M(null), [r, o] = R("loading"), [c, u] = R(""), a = M(null), [h, m] = R(t.size);
|
|
233
|
-
return T(() => {
|
|
234
|
-
X(t.usedLegacyProps);
|
|
235
|
-
}, [t.usedLegacyProps]), T(() => {
|
|
236
|
-
m(t.size);
|
|
237
|
-
}, [t.fit, t.size.cols, t.size.rows]), T(() => {
|
|
238
|
-
if (t.fit !== "container" || !n.current) return;
|
|
239
|
-
const w = new ResizeObserver(([y]) => {
|
|
240
|
-
var z, b;
|
|
241
|
-
const { width: _, height: E } = y.contentRect;
|
|
242
|
-
if (_ > 0 && E > 0) {
|
|
243
|
-
const f = ((z = a.current) == null ? void 0 : z.w) ?? t.terminal.fontSize * 0.6, l = ((b = a.current) == null ? void 0 : b.h) ?? t.terminal.fontSize * 1.2;
|
|
244
|
-
m({
|
|
245
|
-
cols: Math.max(1, Math.floor(_ / f)),
|
|
246
|
-
rows: Math.max(1, Math.floor(E / l))
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
});
|
|
250
|
-
return w.observe(n.current), () => w.disconnect();
|
|
251
|
-
}, [t.fit, t.terminal.fontSize]), T(() => {
|
|
252
|
-
if (!h || !i.current) return;
|
|
253
|
-
let w = !1;
|
|
254
|
-
const y = i.current, _ = h, E = (f) => {
|
|
255
|
-
var l;
|
|
256
|
-
o(f), (l = t.onStatusChange) == null || l.call(t, f);
|
|
257
|
-
}, z = (f) => {
|
|
258
|
-
var l;
|
|
259
|
-
E("error"), u(f instanceof Error ? f.message : String(f)), (l = t.onError) == null || l.call(t, f);
|
|
260
|
-
};
|
|
261
|
-
E("loading"), u("");
|
|
262
|
-
async function b() {
|
|
263
|
-
try {
|
|
264
|
-
const f = await q();
|
|
265
|
-
if (w) return;
|
|
266
|
-
y.innerHTML = "";
|
|
267
|
-
const l = new f.Terminal({
|
|
268
|
-
cols: _.cols,
|
|
269
|
-
rows: _.rows,
|
|
270
|
-
fontSize: t.terminal.fontSize,
|
|
271
|
-
fontFamily: t.terminal.fontFamily,
|
|
272
|
-
theme: t.terminal.theme,
|
|
273
|
-
disableStdin: !t.interactive,
|
|
274
|
-
cursorBlink: t.terminal.cursorBlink,
|
|
275
|
-
convertEol: t.terminal.convertEol
|
|
276
|
-
});
|
|
277
|
-
s.current = l, l.open(y), t.mode === "static" && l.write("\x1B[?25l");
|
|
278
|
-
let A = l.cols, U = l.rows;
|
|
279
|
-
if (t.fit === "container") {
|
|
280
|
-
const g = new f.FitAddon();
|
|
281
|
-
l.loadAddon(g), g.fit(), A = l.cols, U = l.rows, n.current && A > 0 && U > 0 && (a.current = {
|
|
282
|
-
w: n.current.clientWidth / A,
|
|
283
|
-
h: n.current.clientHeight / U
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
const V = t.resolveArgv({ cols: A, rows: U }), F = new TextDecoder(), B = new it({
|
|
287
|
-
args: [t.wasm.toString(), ...V],
|
|
288
|
-
env: t.env,
|
|
289
|
-
stdout: (g) => l.write(F.decode(g)),
|
|
290
|
-
stderr: (g) => l.write(F.decode(g)),
|
|
291
|
-
onExit: (g) => {
|
|
292
|
-
var C;
|
|
293
|
-
w || (E("exited"), (C = t.onExit) == null || C.call(t, g));
|
|
294
|
-
}
|
|
295
|
-
});
|
|
296
|
-
t.interactive && l.onData((g) => B.pushInput(g));
|
|
297
|
-
const G = await ot(t.wasm, B);
|
|
298
|
-
if (w) return;
|
|
299
|
-
E("running"), queueMicrotask(() => {
|
|
300
|
-
w || G.run().catch((g) => {
|
|
301
|
-
w || z(g);
|
|
302
|
-
});
|
|
303
|
-
});
|
|
304
|
-
} catch (f) {
|
|
305
|
-
w || z(f);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
return b(), () => {
|
|
309
|
-
var f;
|
|
310
|
-
w = !0, (f = s.current) == null || f.dispose(), s.current = null;
|
|
311
|
-
};
|
|
312
|
-
}, [
|
|
313
|
-
t.mode,
|
|
314
|
-
h,
|
|
315
|
-
t.wasm,
|
|
316
|
-
t.resolveArgv,
|
|
317
|
-
t.env,
|
|
318
|
-
t.fit,
|
|
319
|
-
t.interactive,
|
|
320
|
-
t.onExit,
|
|
321
|
-
t.onError,
|
|
322
|
-
t.onStatusChange,
|
|
323
|
-
t.terminal.fontSize,
|
|
324
|
-
t.terminal.fontFamily,
|
|
325
|
-
t.terminal.theme,
|
|
326
|
-
t.terminal.cursorBlink,
|
|
327
|
-
t.terminal.convertEol
|
|
328
|
-
]), /* @__PURE__ */ D(
|
|
329
|
-
"div",
|
|
330
|
-
{
|
|
331
|
-
ref: n,
|
|
332
|
-
className: e.className,
|
|
333
|
-
style: {
|
|
334
|
-
position: "relative",
|
|
335
|
-
display: "inline-block",
|
|
336
|
-
background: ((v = t.terminal.theme) == null ? void 0 : v.background) ?? "#1a1b26",
|
|
337
|
-
borderRadius: 6,
|
|
338
|
-
overflow: "hidden",
|
|
339
|
-
...e.style
|
|
340
|
-
},
|
|
341
|
-
children: [
|
|
342
|
-
/* @__PURE__ */ L("div", { ref: i, style: { display: r === "error" ? "none" : void 0 } }),
|
|
343
|
-
r === "loading" && /* @__PURE__ */ L("div", { style: j, children: "Loading…" }),
|
|
344
|
-
r === "error" && /* @__PURE__ */ D("div", { style: { ...j, color: "#f7768e" }, children: [
|
|
345
|
-
"Error: ",
|
|
346
|
-
c
|
|
347
|
-
] })
|
|
348
|
-
]
|
|
349
|
-
}
|
|
350
|
-
);
|
|
351
|
-
}
|
|
352
|
-
const j = {
|
|
353
|
-
padding: "1rem",
|
|
354
|
-
fontFamily: "monospace",
|
|
355
|
-
fontSize: 14,
|
|
356
|
-
color: "#a9b1d6"
|
|
357
|
-
};
|
|
358
|
-
export {
|
|
359
|
-
ut as TuiPreview,
|
|
360
|
-
it as WasiBridge,
|
|
361
|
-
Q as WasiExitError,
|
|
362
|
-
ot as instantiateApp
|
|
363
|
-
};
|
|
1
|
+
export { TuiPreview } from "./TuiPreview.js";
|
|
2
|
+
export { WasiBridge, WasiExitError, instantiateApp } from "./core/wasi.js";
|
package/dist/types.d.ts
CHANGED
|
@@ -4,17 +4,17 @@ export interface TuiRuntimeSize {
|
|
|
4
4
|
}
|
|
5
5
|
export type TuiArgv = string[] | ((size: TuiRuntimeSize) => string[]);
|
|
6
6
|
export type TuiFitMode = "container" | "none";
|
|
7
|
-
export type TuiRenderMode = "
|
|
7
|
+
export type TuiRenderMode = "interactive" | "static";
|
|
8
8
|
export type TuiPreviewStatus = "loading" | "running" | "exited" | "error";
|
|
9
9
|
export interface TuiTerminalOptions {
|
|
10
10
|
/** Font size in pixels. Default: 14 */
|
|
11
11
|
fontSize?: number;
|
|
12
12
|
/** CSS font family. Default: monospace */
|
|
13
13
|
fontFamily?: string;
|
|
14
|
-
/**
|
|
14
|
+
/** Terminal color theme overrides */
|
|
15
15
|
theme?: Partial<GhosttyTheme>;
|
|
16
|
-
/**
|
|
17
|
-
|
|
16
|
+
/** URL to libghostty-vt wasm. Default: "/ghostty-vt.wasm" */
|
|
17
|
+
wasmUrl?: string | URL;
|
|
18
18
|
/** Convert LF to CRLF. Default: true */
|
|
19
19
|
convertEol?: boolean;
|
|
20
20
|
}
|
|
@@ -37,12 +37,7 @@ export interface TuiPreviewModernProps extends TuiPreviewCommonProps {
|
|
|
37
37
|
wasm: string | URL;
|
|
38
38
|
/** CLI argv (without argv[0]), static or size-aware */
|
|
39
39
|
argv?: TuiArgv;
|
|
40
|
-
/**
|
|
41
|
-
* Render mode.
|
|
42
|
-
* - `"terminal"` (default): full ghostty-web terminal, supports interactive apps.
|
|
43
|
-
* - `"static"`: runs the app once, captures stdout, renders ANSI output as HTML.
|
|
44
|
-
* No cursor, no input. Ideal for non-interactive previews in docs.
|
|
45
|
-
*/
|
|
40
|
+
/** Render mode. Default: "interactive" */
|
|
46
41
|
mode?: TuiRenderMode;
|
|
47
42
|
/** "container" auto-fit or "none" fixed size. Default: "container" */
|
|
48
43
|
fit?: TuiFitMode;
|
|
@@ -51,20 +46,7 @@ export interface TuiPreviewModernProps extends TuiPreviewCommonProps {
|
|
|
51
46
|
/** Terminal renderer options */
|
|
52
47
|
terminal?: TuiTerminalOptions;
|
|
53
48
|
}
|
|
54
|
-
|
|
55
|
-
* Legacy API retained for backwards compatibility.
|
|
56
|
-
* Prefer `TuiPreviewModernProps`.
|
|
57
|
-
*/
|
|
58
|
-
export interface TuiPreviewLegacyProps extends TuiPreviewCommonProps {
|
|
59
|
-
app: string | URL;
|
|
60
|
-
args?: TuiArgv;
|
|
61
|
-
cols?: number;
|
|
62
|
-
rows?: number;
|
|
63
|
-
fontSize?: number;
|
|
64
|
-
fontFamily?: string;
|
|
65
|
-
theme?: Partial<GhosttyTheme>;
|
|
66
|
-
}
|
|
67
|
-
export type TuiPreviewProps = TuiPreviewModernProps | TuiPreviewLegacyProps;
|
|
49
|
+
export type TuiPreviewProps = TuiPreviewModernProps;
|
|
68
50
|
export interface GhosttyTheme {
|
|
69
51
|
background: string;
|
|
70
52
|
foreground: string;
|
|
@@ -102,12 +84,12 @@ export interface ResolvedTuiPreviewOptions {
|
|
|
102
84
|
mode: TuiRenderMode;
|
|
103
85
|
fit: TuiFitMode;
|
|
104
86
|
size: TuiRuntimeSize;
|
|
105
|
-
terminal: Required<Omit<TuiTerminalOptions, "theme">> & {
|
|
87
|
+
terminal: Required<Omit<TuiTerminalOptions, "theme" | "wasmUrl">> & {
|
|
106
88
|
theme?: Partial<GhosttyTheme>;
|
|
89
|
+
wasmUrl?: string | URL;
|
|
107
90
|
};
|
|
108
91
|
resolveArgv: (size: TuiRuntimeSize) => string[];
|
|
109
92
|
onExit?: (code: number) => void;
|
|
110
93
|
onError?: (error: unknown) => void;
|
|
111
94
|
onStatusChange?: (status: TuiPreviewStatus) => void;
|
|
112
|
-
usedLegacyProps: boolean;
|
|
113
95
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dkkoval/tui-preview",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "React component for embedding interactive TUI apps via
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "React component for embedding interactive TUI apps via libghostty",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/dmk/tui-preview"
|
|
@@ -13,14 +13,12 @@
|
|
|
13
13
|
"type": "module",
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"sideEffects": false,
|
|
16
|
-
"main": "./dist/index.cjs",
|
|
17
16
|
"module": "./dist/index.js",
|
|
18
17
|
"types": "./dist/index.d.ts",
|
|
19
18
|
"exports": {
|
|
20
19
|
".": {
|
|
21
20
|
"types": "./dist/index.d.ts",
|
|
22
|
-
"import": "./dist/index.js"
|
|
23
|
-
"require": "./dist/index.cjs"
|
|
21
|
+
"import": "./dist/index.js"
|
|
24
22
|
},
|
|
25
23
|
"./core": {
|
|
26
24
|
"types": "./dist/core/index.d.ts",
|
|
@@ -32,20 +30,20 @@
|
|
|
32
30
|
],
|
|
33
31
|
"scripts": {
|
|
34
32
|
"clean": "rm -rf dist dist-example",
|
|
33
|
+
"build:ghostty-wasm": "./scripts/build-libghostty-wasm.sh",
|
|
35
34
|
"dev": "vite example",
|
|
35
|
+
"build:examples": "./scripts/build-examples-wasm.sh",
|
|
36
36
|
"build": "vite build",
|
|
37
|
-
"build:lib": "tsc -p tsconfig.json
|
|
37
|
+
"build:lib": "tsc -p tsconfig.json",
|
|
38
|
+
"prepack": "tsc -p tsconfig.json && ./scripts/build-libghostty-wasm.sh dist/core/ghostty-vt.wasm",
|
|
38
39
|
"typecheck": "tsc --noEmit",
|
|
39
|
-
"test": "
|
|
40
|
-
"check": "
|
|
40
|
+
"test": "tsc -p tsconfig.json && node --test tests/*.test.mjs",
|
|
41
|
+
"check": "tsc --noEmit && tsc -p tsconfig.json && node --test tests/*.test.mjs"
|
|
41
42
|
},
|
|
42
43
|
"peerDependencies": {
|
|
43
44
|
"react": ">=18",
|
|
44
45
|
"react-dom": ">=18"
|
|
45
46
|
},
|
|
46
|
-
"dependencies": {
|
|
47
|
-
"ghostty-web": "^0.4.0"
|
|
48
|
-
},
|
|
49
47
|
"devDependencies": {
|
|
50
48
|
"@types/react": "^18",
|
|
51
49
|
"@types/react-dom": "^18",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e={};exports.default=e;
|
package/dist/core/ghostty.d.ts
DELETED
package/dist/core/ghostty.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
let ghosttyReady = null;
|
|
2
|
-
/** Load ghostty-web lazily to avoid SSR issues in host apps. */
|
|
3
|
-
export function loadGhostty() {
|
|
4
|
-
if (!ghosttyReady) {
|
|
5
|
-
ghosttyReady = import("ghostty-web").then(async (mod) => {
|
|
6
|
-
await mod.init();
|
|
7
|
-
return mod;
|
|
8
|
-
});
|
|
9
|
-
}
|
|
10
|
-
return ghosttyReady;
|
|
11
|
-
}
|