@dkkoval/tui-preview 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 +78 -0
- package/dist/TuiPreview.d.ts +2 -0
- package/dist/TuiPreview.js +257 -0
- package/dist/__vite-browser-external-2447137e-BcPniuRQ.cjs +1 -0
- package/dist/__vite-browser-external-2447137e-DYxpcVy9.js +4 -0
- package/dist/core/ansi.d.ts +15 -0
- package/dist/core/ansi.js +181 -0
- package/dist/core/ghostty.d.ts +2 -0
- package/dist/core/ghostty.js +11 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.js +4 -0
- package/dist/core/normalize.d.ts +3 -0
- package/dist/core/normalize.js +89 -0
- package/dist/core/wasi.d.ts +34 -0
- package/dist/core/wasi.js +218 -0
- package/dist/ghostty-web-BfBVpf8G.js +2962 -0
- package/dist/ghostty-web-DkOZu5AZ.cjs +13 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +515 -0
- package/dist/types.d.ts +113 -0
- package/dist/types.js +1 -0
- package/dist/wasi.d.ts +1 -0
- package/dist/wasi.js +2 -0
- package/package.json +51 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var K=Object.defineProperty;var X=(t,e,n)=>e in t?K(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var W=(t,e,n)=>X(t,typeof e!="symbol"?e+"":e,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const M=require("react/jsx-runtime"),b=require("react"),j=["#000000","#cd0000","#00cd00","#cdcd00","#0000ee","#cd00cd","#00cdcd","#e5e5e5","#7f7f7f","#ff0000","#00ff00","#ffff00","#5c5cff","#ff00ff","#00ffff","#ffffff"];function Q(t){if(t<16)return j[t];if(t<232){const n=t-16,o=Math.floor(n/36),a=Math.floor(n%36/6),r=n%6,i=c=>c===0?0:c*40+55;return`rgb(${i(o)},${i(a)},${i(r)})`}const e=(t-232)*10+8;return`rgb(${e},${e},${e})`}function V(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function ee(t){let e=null,n=null,o=!1,a=!1,r=!1;const i=[];let c="",u="";function h(){const s=[];return e&&s.push(`color:${e}`),n&&s.push(`background-color:${n}`),o&&s.push("font-weight:bold"),a&&s.push("font-style:italic"),r&&s.push("text-decoration:underline"),s.join(";")}function m(){c&&(i.push(u?`<span style="${u}">${V(c)}</span>`:V(c)),c="")}function v(s){m();let f=0;for(;f<s.length;){const l=s[f];l===0?(e=null,n=null,o=!1,a=!1,r=!1):l===1?o=!0:l===22?o=!1:l===3?a=!0:l===23?a=!1:l===4?r=!0:l===24?r=!1:l>=30&&l<=37?e=j[l-30]:l===38?s[f+1]===2&&f+4<s.length?(e=`rgb(${s[f+2]},${s[f+3]},${s[f+4]})`,f+=4):s[f+1]===5&&f+2<s.length&&(e=Q(s[f+2]),f+=2):l===39?e=null:l>=40&&l<=47?n=j[l-40]:l===48?s[f+1]===2&&f+4<s.length?(n=`rgb(${s[f+2]},${s[f+3]},${s[f+4]})`,f+=4):s[f+1]===5&&f+2<s.length&&(n=Q(s[f+2]),f+=2):l===49?n=null:l>=90&&l<=97?e=j[l-82]:l>=100&&l<=107&&(n=j[l-92]),f++}u=h()}let d=0;for(;d<t.length;){const s=t[d];if(s==="\x1B"&&d+1<t.length&&t[d+1]==="["){const f=d+2;let l=f;for(;l<t.length&&(t.charCodeAt(l)<64||t.charCodeAt(l)>126);)l++;if(l<t.length){if(t[l]==="m"){const F=t.slice(f,l),I=F?F.split(";").map(y=>parseInt(y,10)||0):[0];v(I)}d=l+1}else d++}else if(s==="\r")d++;else{const f=h();f!==u&&(m(),u=f),c+=s,d++}}return m(),i.join("")}let p=null;function te(){return p||(p=Promise.resolve().then(()=>require("./ghostty-web-DkOZu5AZ.cjs")).then(async t=>(await t.init(),t))),p}const k={cols:80,rows:24},G={},ne=[];function re(t){return"wasm"in t}function Y(t){const e=t??ne;return typeof e=="function"?e:()=>e}function ie(t){return t.cols!==void 0||t.rows!==void 0?{fit:"none",size:{cols:Math.max(1,t.cols??k.cols),rows:Math.max(1,t.rows??k.rows)}}:{fit:"container",size:k}}let Z=!1;function se(t){!t||Z||(Z=!0,console.warn("[tui-preview] Legacy props (`app`, `args`, `cols`, `rows`, `fontSize`, `fontFamily`, `theme`) are deprecated. Use `wasm`, `argv`, `fit`, `size`, and `terminal`."))}function oe(t){var o,a,r,i,c,u,h,m,v;if(re(t)){const d=t.fit??(t.size?"none":"container"),s=d==="none"?{cols:Math.max(1,((o=t.size)==null?void 0:o.cols)??k.cols),rows:Math.max(1,((a=t.size)==null?void 0:a.rows)??k.rows)}:{cols:Math.max(1,((r=t.size)==null?void 0:r.cols)??k.cols),rows:Math.max(1,((i=t.size)==null?void 0:i.rows)??k.rows)};return{wasm:t.wasm,env:t.env??G,interactive:t.interactive??!0,mode:t.mode??"terminal",fit:d,size:s,terminal:{fontSize:((c=t.terminal)==null?void 0:c.fontSize)??14,fontFamily:((u=t.terminal)==null?void 0:u.fontFamily)??"monospace",cursorBlink:((h=t.terminal)==null?void 0:h.cursorBlink)??!0,convertEol:((m=t.terminal)==null?void 0:m.convertEol)??!0,theme:(v=t.terminal)==null?void 0:v.theme},resolveArgv:Y(t.argv),onExit:t.onExit,onError:t.onError,onStatusChange:t.onStatusChange,usedLegacyProps:!1}}const{fit:e,size:n}=ie(t);return{wasm:t.app,env:t.env??G,interactive:t.interactive??!0,mode:"terminal",fit:e,size:n,terminal:{fontSize:t.fontSize??14,fontFamily:t.fontFamily??"monospace",cursorBlink:!0,convertEol:!0,theme:t.theme},resolveArgv:Y(t.args),onExit:t.onExit,onError:t.onError,onStatusChange:t.onStatusChange,usedLegacyProps:!0}}const z=0,ce=6,P=8,le=0,J=1,ae=2;class N{constructor(e){W(this,"inputQueue",[]);W(this,"memory");this.opts=e}pushInput(e){const n=typeof e=="string"?new TextEncoder().encode(e):e;this.inputQueue.push(n)}attachMemory(e){this.memory=e}view(){return new DataView(this.memory.buffer)}u8(){return new Uint8Array(this.memory.buffer)}get imports(){return{args_sizes_get:(e,n)=>{const{args:o}=this.opts,a=new TextEncoder,r=o.reduce((i,c)=>i+a.encode(c).length+1,0);return this.view().setUint32(e,o.length,!0),this.view().setUint32(n,r,!0),z},args_get:(e,n)=>{const o=new TextEncoder,a=this.u8(),r=this.view();let i=n;return this.opts.args.forEach((c,u)=>{const h=o.encode(c);a.set(h,i),a[i+h.length]=0,r.setUint32(e+u*4,i,!0),i+=h.length+1}),z},environ_sizes_get:(e,n)=>{const o=this.envEntries(),a=new TextEncoder,r=o.reduce((i,c)=>i+a.encode(c).length+1,0);return this.view().setUint32(e,o.length,!0),this.view().setUint32(n,r,!0),z},environ_get:(e,n)=>{const o=new TextEncoder,a=this.u8(),r=this.view();let i=n;return this.envEntries().forEach((c,u)=>{const h=o.encode(c);a.set(h,i),a[i+h.length]=0,r.setUint32(e+u*4,i,!0),i+=h.length+1}),z},fd_write:(e,n,o,a)=>{if(e!==J&&e!==ae)return P;const r=this.view(),i=this.u8();let c=0;const u=[];for(let v=0;v<o;v++){const d=r.getUint32(n+v*8,!0),s=r.getUint32(n+v*8+4,!0);u.push(i.slice(d,d+s)),c+=s}const h=new Uint8Array(c);let m=0;for(const v of u)h.set(v,m),m+=v.length;return e===J?this.opts.stdout(h):this.opts.stderr(h),r.setUint32(a,c,!0),z},fd_read:(e,n,o,a)=>{if(e!==le)return P;const r=this.inputQueue.shift();if(!r)return ce;const i=this.view(),c=this.u8();let u=0;for(let h=0;h<o&&u<r.length;h++){const m=i.getUint32(n+h*8,!0),v=i.getUint32(n+h*8+4,!0),d=Math.min(v,r.length-u);c.set(r.subarray(u,u+d),m),u+=d}return i.setUint32(a,u,!0),z},poll_oneoff:(e,n,o,a)=>{const r=this.view();let i=0;for(let c=0;c<o;c++){const u=e+c*48,h=r.getUint8(u+8);if(h===0&&this.inputQueue.length>0){const m=n+i*32;r.setBigUint64(m,r.getBigUint64(u,!0),!0),r.setUint16(m+8,0,!0),r.setUint8(m+10,h),i++}}return r.setUint32(a,i,!0),z},proc_exit:e=>{throw this.opts.onExit(e),new H(e)},random_get:(e,n)=>(crypto.getRandomValues(new Uint8Array(this.memory.buffer,e,n)),z),fd_close:()=>z,fd_seek:()=>z,fd_fdstat_get:(e,n)=>(this.view().setUint8(n,e<=2?2:0),z),fd_prestat_get:()=>P,fd_prestat_dir_name:()=>P,path_open:()=>P,sched_yield:()=>z,clock_time_get:(e,n,o)=>{const a=BigInt(Date.now())*1000000n;return this.view().setBigUint64(o,a,!0),z}}}envEntries(){const e={TERM:"xterm-256color",COLORTERM:"truecolor",...this.opts.env};return Object.entries(e).map(([n,o])=>`${n}=${o}`)}}class H extends Error{constructor(e){super(`WASI exit: ${e}`),this.code=e}}async function O(t,e){const o=await(await fetch(t)).arrayBuffer(),a=await WebAssembly.compile(o),r={wasi_snapshot_preview1:e.imports},i=await WebAssembly.instantiate(a,r);e.attachMemory(i.exports.memory);const c=i.exports._start;if(!c)throw new Error("WASM module has no _start export");return{run:async()=>{try{c()}catch(u){if(!(u instanceof H))throw u}}}}function ue(t){var F,I;const e=b.useMemo(()=>oe(t),[t]),n=b.useRef(null),o=b.useRef(null),a=b.useRef(null),[r,i]=b.useState("loading"),[c,u]=b.useState(""),h=b.useRef(null),[m,v]=b.useState(e.size),[d,s]=b.useState(null);b.useEffect(()=>{se(e.usedLegacyProps)},[e.usedLegacyProps]),b.useEffect(()=>{e.mode==="terminal"&&v(e.size)},[e.mode,e.fit,e.size.cols,e.size.rows]),b.useEffect(()=>{if(e.mode!=="terminal"||e.fit!=="container"||!n.current)return;const y=new ResizeObserver(([_])=>{var E,A;const{width:T,height:x}=_.contentRect;if(T>0&&x>0){const w=((E=h.current)==null?void 0:E.w)??e.terminal.fontSize*.6,g=((A=h.current)==null?void 0:A.h)??e.terminal.fontSize*1.2;v({cols:Math.max(1,Math.floor(T/w)),rows:Math.max(1,Math.floor(x/g))})}});return y.observe(n.current),()=>y.disconnect()},[e.mode,e.fit,e.terminal.fontSize]),b.useEffect(()=>{if(e.mode!=="terminal"||!m||!o.current)return;let y=!1;const _=o.current,T=m,x=w=>{var g;i(w),(g=e.onStatusChange)==null||g.call(e,w)},E=w=>{var g;x("error"),u(w instanceof Error?w.message:String(w)),(g=e.onError)==null||g.call(e,w)};x("loading"),u("");async function A(){try{const w=await te();if(y)return;_.innerHTML="";const g=new w.Terminal({cols:T.cols,rows:T.rows,fontSize:e.terminal.fontSize,fontFamily:e.terminal.fontFamily,theme:e.terminal.theme,disableStdin:!e.interactive,cursorBlink:e.terminal.cursorBlink,convertEol:e.terminal.convertEol});a.current=g,g.open(_);let U=g.cols,R=g.rows;if(e.fit==="container"){const S=new w.FitAddon;g.loadAddon(S),S.fit(),U=g.cols,R=g.rows,n.current&&U>0&&R>0&&(h.current={w:n.current.clientWidth/U,h:n.current.clientHeight/R})}const D=e.resolveArgv({cols:U,rows:R}),B=new TextDecoder,C=new N({args:[e.wasm.toString(),...D],env:e.env,stdout:S=>g.write(B.decode(S)),stderr:S=>g.write(B.decode(S)),onExit:S=>{var q;y||(x("exited"),(q=e.onExit)==null||q.call(e,S))}});e.interactive&&g.onData(S=>C.pushInput(S));const $=await O(e.wasm,C);if(y)return;x("running"),queueMicrotask(()=>{y||$.run().catch(S=>{y||E(S)})})}catch(w){y||E(w)}}return A(),()=>{var w;y=!0,(w=a.current)==null||w.dispose(),a.current=null}},[e.mode,m,e.wasm,e.resolveArgv,e.env,e.fit,e.interactive,e.onExit,e.onError,e.onStatusChange,e.terminal.fontSize,e.terminal.fontFamily,e.terminal.theme,e.terminal.cursorBlink,e.terminal.convertEol]),b.useEffect(()=>{if(e.mode!=="static")return;let y=!1;const _=x=>{var E;i(x),(E=e.onStatusChange)==null||E.call(e,x)};_("loading"),u(""),s(null);async function T(){var x;try{const E=new TextDecoder,A=[],w=new N({args:[e.wasm.toString(),...e.resolveArgv(e.size)],env:e.env,stdout:U=>A.push(new Uint8Array(U)),stderr:()=>{},onExit:U=>{var R;if(!y){const D=A.reduce(($,S)=>$+S.length,0),B=new Uint8Array(D);let C=0;for(const $ of A)B.set($,C),C+=$.length;s(ee(E.decode(B))),_("exited"),(R=e.onExit)==null||R.call(e,U)}}}),g=await O(e.wasm,w);if(y)return;_("running"),await g.run()}catch(E){y||(_("error"),u(E instanceof Error?E.message:String(E)),(x=e.onError)==null||x.call(e,E))}}return T(),()=>{y=!0}},[e.mode,e.wasm,e.resolveArgv,e.env,e.size.cols,e.size.rows,e.onExit,e.onError,e.onStatusChange]);const f=((F=e.terminal.theme)==null?void 0:F.background)??"#1a1b26",l=((I=e.terminal.theme)==null?void 0:I.foreground)??"#a9b1d6";return e.mode==="static"?M.jsxs("div",{className:t.className,style:{position:"relative",background:f,borderRadius:6,overflow:"hidden",...t.style},children:[r==="loading"&&M.jsx("div",{style:L,children:"Loading…"}),r==="error"&&M.jsxs("div",{style:{...L,color:"#f7768e"},children:["Error: ",c]}),d!==null&&M.jsx("pre",{style:{margin:0,padding:"0.5em",fontFamily:e.terminal.fontFamily,fontSize:e.terminal.fontSize,color:l,lineHeight:1.2,background:"transparent",overflow:"auto"},dangerouslySetInnerHTML:{__html:d}})]}):M.jsxs("div",{ref:n,className:t.className,style:{position:"relative",display:"inline-block",background:f,borderRadius:6,overflow:"hidden",...t.style},children:[M.jsx("div",{ref:o,style:{display:r==="error"?"none":void 0}}),r==="loading"&&M.jsx("div",{style:L,children:"Loading…"}),r==="error"&&M.jsxs("div",{style:{...L,color:"#f7768e"},children:["Error: ",c]})]})}const L={padding:"1rem",fontFamily:"monospace",fontSize:14,color:"#a9b1d6"};exports.TuiPreview=ue;exports.WasiBridge=N;exports.WasiExitError=H;exports.instantiateApp=O;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { TuiPreview } from "./TuiPreview.js";
|
|
2
|
+
export type { GhosttyTheme, ResolvedTuiPreviewOptions, TuiArgv, TuiFitMode, TuiRenderMode, TuiPreviewCommonProps, TuiPreviewLegacyProps, TuiPreviewModernProps, TuiPreviewProps, TuiPreviewStatus, TuiRuntimeSize, TuiTerminalOptions, WasiOptions, } from "./types.js";
|
|
3
|
+
export { WasiBridge, WasiExitError, instantiateApp } from "./wasi.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
var te = Object.defineProperty;
|
|
2
|
+
var ne = (t, e, n) => e in t ? te(t, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : t[e] = n;
|
|
3
|
+
var O = (t, e, n) => ne(t, typeof e != "symbol" ? e + "" : e, n);
|
|
4
|
+
import { jsxs as D, jsx as p } from "react/jsx-runtime";
|
|
5
|
+
import { useMemo as re, useRef as P, useState as W, useEffect as C } from "react";
|
|
6
|
+
const I = [
|
|
7
|
+
"#000000",
|
|
8
|
+
"#cd0000",
|
|
9
|
+
"#00cd00",
|
|
10
|
+
"#cdcd00",
|
|
11
|
+
"#0000ee",
|
|
12
|
+
"#cd00cd",
|
|
13
|
+
"#00cdcd",
|
|
14
|
+
"#e5e5e5",
|
|
15
|
+
"#7f7f7f",
|
|
16
|
+
"#ff0000",
|
|
17
|
+
"#00ff00",
|
|
18
|
+
"#ffff00",
|
|
19
|
+
"#5c5cff",
|
|
20
|
+
"#ff00ff",
|
|
21
|
+
"#00ffff",
|
|
22
|
+
"#ffffff"
|
|
23
|
+
];
|
|
24
|
+
function V(t) {
|
|
25
|
+
if (t < 16) return I[t];
|
|
26
|
+
if (t < 232) {
|
|
27
|
+
const n = t - 16, s = Math.floor(n / 36), a = Math.floor(n % 36 / 6), r = n % 6, i = (c) => c === 0 ? 0 : c * 40 + 55;
|
|
28
|
+
return `rgb(${i(s)},${i(a)},${i(r)})`;
|
|
29
|
+
}
|
|
30
|
+
const e = (t - 232) * 10 + 8;
|
|
31
|
+
return `rgb(${e},${e},${e})`;
|
|
32
|
+
}
|
|
33
|
+
function q(t) {
|
|
34
|
+
return t.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
35
|
+
}
|
|
36
|
+
function ie(t) {
|
|
37
|
+
let e = null, n = null, s = !1, a = !1, r = !1;
|
|
38
|
+
const i = [];
|
|
39
|
+
let c = "", u = "";
|
|
40
|
+
function h() {
|
|
41
|
+
const o = [];
|
|
42
|
+
return e && o.push(`color:${e}`), n && o.push(`background-color:${n}`), s && o.push("font-weight:bold"), a && o.push("font-style:italic"), r && o.push("text-decoration:underline"), o.join(";");
|
|
43
|
+
}
|
|
44
|
+
function m() {
|
|
45
|
+
c && (i.push(u ? `<span style="${u}">${q(c)}</span>` : q(c)), c = "");
|
|
46
|
+
}
|
|
47
|
+
function v(o) {
|
|
48
|
+
m();
|
|
49
|
+
let f = 0;
|
|
50
|
+
for (; f < o.length; ) {
|
|
51
|
+
const l = o[f];
|
|
52
|
+
l === 0 ? (e = null, n = null, s = !1, a = !1, r = !1) : l === 1 ? s = !0 : l === 22 ? s = !1 : l === 3 ? a = !0 : l === 23 ? a = !1 : l === 4 ? r = !0 : l === 24 ? r = !1 : l >= 30 && l <= 37 ? e = I[l - 30] : l === 38 ? o[f + 1] === 2 && f + 4 < o.length ? (e = `rgb(${o[f + 2]},${o[f + 3]},${o[f + 4]})`, f += 4) : o[f + 1] === 5 && f + 2 < o.length && (e = V(o[f + 2]), f += 2) : l === 39 ? e = null : l >= 40 && l <= 47 ? n = I[l - 40] : l === 48 ? o[f + 1] === 2 && f + 4 < o.length ? (n = `rgb(${o[f + 2]},${o[f + 3]},${o[f + 4]})`, f += 4) : o[f + 1] === 5 && f + 2 < o.length && (n = V(o[f + 2]), f += 2) : l === 49 ? n = null : l >= 90 && l <= 97 ? e = I[l - 82] : l >= 100 && l <= 107 && (n = I[l - 92]), f++;
|
|
53
|
+
}
|
|
54
|
+
u = h();
|
|
55
|
+
}
|
|
56
|
+
let d = 0;
|
|
57
|
+
for (; d < t.length; ) {
|
|
58
|
+
const o = t[d];
|
|
59
|
+
if (o === "\x1B" && d + 1 < t.length && t[d + 1] === "[") {
|
|
60
|
+
const f = d + 2;
|
|
61
|
+
let l = f;
|
|
62
|
+
for (; l < t.length && (t.charCodeAt(l) < 64 || t.charCodeAt(l) > 126); )
|
|
63
|
+
l++;
|
|
64
|
+
if (l < t.length) {
|
|
65
|
+
if (t[l] === "m") {
|
|
66
|
+
const $ = t.slice(f, l), L = $ ? $.split(";").map((y) => parseInt(y, 10) || 0) : [0];
|
|
67
|
+
v(L);
|
|
68
|
+
}
|
|
69
|
+
d = l + 1;
|
|
70
|
+
} else
|
|
71
|
+
d++;
|
|
72
|
+
} else if (o === "\r")
|
|
73
|
+
d++;
|
|
74
|
+
else {
|
|
75
|
+
const f = h();
|
|
76
|
+
f !== u && (m(), u = f), c += o, d++;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return m(), i.join("");
|
|
80
|
+
}
|
|
81
|
+
let j = null;
|
|
82
|
+
function oe() {
|
|
83
|
+
return j || (j = import("./ghostty-web-BfBVpf8G.js").then(async (t) => (await t.init(), t))), j;
|
|
84
|
+
}
|
|
85
|
+
const T = { cols: 80, rows: 24 }, G = {}, se = [];
|
|
86
|
+
function ce(t) {
|
|
87
|
+
return "wasm" in t;
|
|
88
|
+
}
|
|
89
|
+
function Y(t) {
|
|
90
|
+
const e = t ?? se;
|
|
91
|
+
return typeof e == "function" ? e : () => e;
|
|
92
|
+
}
|
|
93
|
+
function le(t) {
|
|
94
|
+
return t.cols !== void 0 || t.rows !== void 0 ? {
|
|
95
|
+
fit: "none",
|
|
96
|
+
size: {
|
|
97
|
+
cols: Math.max(1, t.cols ?? T.cols),
|
|
98
|
+
rows: Math.max(1, t.rows ?? T.rows)
|
|
99
|
+
}
|
|
100
|
+
} : { fit: "container", size: T };
|
|
101
|
+
}
|
|
102
|
+
let Z = !1;
|
|
103
|
+
function ae(t) {
|
|
104
|
+
!t || Z || (Z = !0, console.warn(
|
|
105
|
+
"[tui-preview] Legacy props (`app`, `args`, `cols`, `rows`, `fontSize`, `fontFamily`, `theme`) are deprecated. Use `wasm`, `argv`, `fit`, `size`, and `terminal`."
|
|
106
|
+
));
|
|
107
|
+
}
|
|
108
|
+
function ue(t) {
|
|
109
|
+
var s, a, r, i, c, u, h, m, v;
|
|
110
|
+
if (ce(t)) {
|
|
111
|
+
const d = t.fit ?? (t.size ? "none" : "container"), o = d === "none" ? {
|
|
112
|
+
cols: Math.max(1, ((s = t.size) == null ? void 0 : s.cols) ?? T.cols),
|
|
113
|
+
rows: Math.max(1, ((a = t.size) == null ? void 0 : a.rows) ?? T.rows)
|
|
114
|
+
} : {
|
|
115
|
+
cols: Math.max(1, ((r = t.size) == null ? void 0 : r.cols) ?? T.cols),
|
|
116
|
+
rows: Math.max(1, ((i = t.size) == null ? void 0 : i.rows) ?? T.rows)
|
|
117
|
+
};
|
|
118
|
+
return {
|
|
119
|
+
wasm: t.wasm,
|
|
120
|
+
env: t.env ?? G,
|
|
121
|
+
interactive: t.interactive ?? !0,
|
|
122
|
+
mode: t.mode ?? "terminal",
|
|
123
|
+
fit: d,
|
|
124
|
+
size: o,
|
|
125
|
+
terminal: {
|
|
126
|
+
fontSize: ((c = t.terminal) == null ? void 0 : c.fontSize) ?? 14,
|
|
127
|
+
fontFamily: ((u = t.terminal) == null ? void 0 : u.fontFamily) ?? "monospace",
|
|
128
|
+
cursorBlink: ((h = t.terminal) == null ? void 0 : h.cursorBlink) ?? !0,
|
|
129
|
+
convertEol: ((m = t.terminal) == null ? void 0 : m.convertEol) ?? !0,
|
|
130
|
+
theme: (v = t.terminal) == null ? void 0 : v.theme
|
|
131
|
+
},
|
|
132
|
+
resolveArgv: Y(t.argv),
|
|
133
|
+
onExit: t.onExit,
|
|
134
|
+
onError: t.onError,
|
|
135
|
+
onStatusChange: t.onStatusChange,
|
|
136
|
+
usedLegacyProps: !1
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
const { fit: e, size: n } = le(t);
|
|
140
|
+
return {
|
|
141
|
+
wasm: t.app,
|
|
142
|
+
env: t.env ?? G,
|
|
143
|
+
interactive: t.interactive ?? !0,
|
|
144
|
+
mode: "terminal",
|
|
145
|
+
fit: e,
|
|
146
|
+
size: n,
|
|
147
|
+
terminal: {
|
|
148
|
+
fontSize: t.fontSize ?? 14,
|
|
149
|
+
fontFamily: t.fontFamily ?? "monospace",
|
|
150
|
+
cursorBlink: !0,
|
|
151
|
+
convertEol: !0,
|
|
152
|
+
theme: t.theme
|
|
153
|
+
},
|
|
154
|
+
resolveArgv: Y(t.args),
|
|
155
|
+
onExit: t.onExit,
|
|
156
|
+
onError: t.onError,
|
|
157
|
+
onStatusChange: t.onStatusChange,
|
|
158
|
+
usedLegacyProps: !0
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
const z = 0, fe = 6, B = 8, he = 0, J = 1, de = 2;
|
|
162
|
+
class K {
|
|
163
|
+
constructor(e) {
|
|
164
|
+
O(this, "inputQueue", []);
|
|
165
|
+
O(this, "memory");
|
|
166
|
+
this.opts = e;
|
|
167
|
+
}
|
|
168
|
+
/** Push keyboard data from the terminal into the app's stdin */
|
|
169
|
+
pushInput(e) {
|
|
170
|
+
const n = typeof e == "string" ? new TextEncoder().encode(e) : e;
|
|
171
|
+
this.inputQueue.push(n);
|
|
172
|
+
}
|
|
173
|
+
/** Attach the WASM instance's memory after instantiation */
|
|
174
|
+
attachMemory(e) {
|
|
175
|
+
this.memory = e;
|
|
176
|
+
}
|
|
177
|
+
view() {
|
|
178
|
+
return new DataView(this.memory.buffer);
|
|
179
|
+
}
|
|
180
|
+
u8() {
|
|
181
|
+
return new Uint8Array(this.memory.buffer);
|
|
182
|
+
}
|
|
183
|
+
// ── WASI imports object ────────────────────────────────────────────────
|
|
184
|
+
get imports() {
|
|
185
|
+
return {
|
|
186
|
+
args_sizes_get: (e, n) => {
|
|
187
|
+
const { args: s } = this.opts, a = new TextEncoder(), r = s.reduce((i, c) => i + a.encode(c).length + 1, 0);
|
|
188
|
+
return this.view().setUint32(e, s.length, !0), this.view().setUint32(n, r, !0), z;
|
|
189
|
+
},
|
|
190
|
+
args_get: (e, n) => {
|
|
191
|
+
const s = new TextEncoder(), a = this.u8(), r = this.view();
|
|
192
|
+
let i = n;
|
|
193
|
+
return this.opts.args.forEach((c, u) => {
|
|
194
|
+
const h = s.encode(c);
|
|
195
|
+
a.set(h, i), a[i + h.length] = 0, r.setUint32(e + u * 4, i, !0), i += h.length + 1;
|
|
196
|
+
}), z;
|
|
197
|
+
},
|
|
198
|
+
environ_sizes_get: (e, n) => {
|
|
199
|
+
const s = this.envEntries(), a = new TextEncoder(), r = s.reduce((i, c) => i + a.encode(c).length + 1, 0);
|
|
200
|
+
return this.view().setUint32(e, s.length, !0), this.view().setUint32(n, r, !0), z;
|
|
201
|
+
},
|
|
202
|
+
environ_get: (e, n) => {
|
|
203
|
+
const s = new TextEncoder(), a = this.u8(), r = this.view();
|
|
204
|
+
let i = n;
|
|
205
|
+
return this.envEntries().forEach((c, u) => {
|
|
206
|
+
const h = s.encode(c);
|
|
207
|
+
a.set(h, i), a[i + h.length] = 0, r.setUint32(e + u * 4, i, !0), i += h.length + 1;
|
|
208
|
+
}), z;
|
|
209
|
+
},
|
|
210
|
+
fd_write: (e, n, s, a) => {
|
|
211
|
+
if (e !== J && e !== de) return B;
|
|
212
|
+
const r = this.view(), i = this.u8();
|
|
213
|
+
let c = 0;
|
|
214
|
+
const u = [];
|
|
215
|
+
for (let v = 0; v < s; v++) {
|
|
216
|
+
const d = r.getUint32(n + v * 8, !0), o = r.getUint32(n + v * 8 + 4, !0);
|
|
217
|
+
u.push(i.slice(d, d + o)), c += o;
|
|
218
|
+
}
|
|
219
|
+
const h = new Uint8Array(c);
|
|
220
|
+
let m = 0;
|
|
221
|
+
for (const v of u)
|
|
222
|
+
h.set(v, m), m += v.length;
|
|
223
|
+
return e === J ? this.opts.stdout(h) : this.opts.stderr(h), r.setUint32(a, c, !0), z;
|
|
224
|
+
},
|
|
225
|
+
fd_read: (e, n, s, a) => {
|
|
226
|
+
if (e !== he) return B;
|
|
227
|
+
const r = this.inputQueue.shift();
|
|
228
|
+
if (!r) return fe;
|
|
229
|
+
const i = this.view(), c = this.u8();
|
|
230
|
+
let u = 0;
|
|
231
|
+
for (let h = 0; h < s && u < r.length; h++) {
|
|
232
|
+
const m = i.getUint32(n + h * 8, !0), v = i.getUint32(n + h * 8 + 4, !0), d = Math.min(v, r.length - u);
|
|
233
|
+
c.set(r.subarray(u, u + d), m), u += d;
|
|
234
|
+
}
|
|
235
|
+
return i.setUint32(a, u, !0), z;
|
|
236
|
+
},
|
|
237
|
+
poll_oneoff: (e, n, s, a) => {
|
|
238
|
+
const r = this.view();
|
|
239
|
+
let i = 0;
|
|
240
|
+
for (let c = 0; c < s; c++) {
|
|
241
|
+
const u = e + c * 48, h = r.getUint8(u + 8);
|
|
242
|
+
if (h === 0 && this.inputQueue.length > 0) {
|
|
243
|
+
const m = n + i * 32;
|
|
244
|
+
r.setBigUint64(m, r.getBigUint64(u, !0), !0), r.setUint16(m + 8, 0, !0), r.setUint8(m + 10, h), i++;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return r.setUint32(a, i, !0), z;
|
|
248
|
+
},
|
|
249
|
+
proc_exit: (e) => {
|
|
250
|
+
throw this.opts.onExit(e), new ee(e);
|
|
251
|
+
},
|
|
252
|
+
random_get: (e, n) => (crypto.getRandomValues(new Uint8Array(this.memory.buffer, e, n)), z),
|
|
253
|
+
// Stubs for calls TUI apps may make but we don't need to implement.
|
|
254
|
+
fd_close: () => z,
|
|
255
|
+
fd_seek: () => z,
|
|
256
|
+
fd_fdstat_get: (e, n) => (this.view().setUint8(n, e <= 2 ? 2 : 0), z),
|
|
257
|
+
fd_prestat_get: () => B,
|
|
258
|
+
fd_prestat_dir_name: () => B,
|
|
259
|
+
path_open: () => B,
|
|
260
|
+
sched_yield: () => z,
|
|
261
|
+
clock_time_get: (e, n, s) => {
|
|
262
|
+
const a = BigInt(Date.now()) * 1000000n;
|
|
263
|
+
return this.view().setBigUint64(s, a, !0), z;
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
envEntries() {
|
|
268
|
+
const e = {
|
|
269
|
+
TERM: "xterm-256color",
|
|
270
|
+
COLORTERM: "truecolor",
|
|
271
|
+
...this.opts.env
|
|
272
|
+
};
|
|
273
|
+
return Object.entries(e).map(([n, s]) => `${n}=${s}`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
class ee extends Error {
|
|
277
|
+
constructor(e) {
|
|
278
|
+
super(`WASI exit: ${e}`), this.code = e;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
async function X(t, e) {
|
|
282
|
+
const s = await (await fetch(t)).arrayBuffer(), a = await WebAssembly.compile(s), r = {
|
|
283
|
+
wasi_snapshot_preview1: e.imports
|
|
284
|
+
}, i = await WebAssembly.instantiate(a, r);
|
|
285
|
+
e.attachMemory(i.exports.memory);
|
|
286
|
+
const c = i.exports._start;
|
|
287
|
+
if (!c) throw new Error("WASM module has no _start export");
|
|
288
|
+
return {
|
|
289
|
+
run: async () => {
|
|
290
|
+
try {
|
|
291
|
+
c();
|
|
292
|
+
} catch (u) {
|
|
293
|
+
if (!(u instanceof ee)) throw u;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
function ve(t) {
|
|
299
|
+
var $, L;
|
|
300
|
+
const e = re(() => ue(t), [t]), n = P(null), s = P(null), a = P(null), [r, i] = W("loading"), [c, u] = W(""), h = P(null), [m, v] = W(e.size), [d, o] = W(null);
|
|
301
|
+
C(() => {
|
|
302
|
+
ae(e.usedLegacyProps);
|
|
303
|
+
}, [e.usedLegacyProps]), C(() => {
|
|
304
|
+
e.mode === "terminal" && v(e.size);
|
|
305
|
+
}, [e.mode, e.fit, e.size.cols, e.size.rows]), C(() => {
|
|
306
|
+
if (e.mode !== "terminal" || e.fit !== "container" || !n.current) return;
|
|
307
|
+
const y = new ResizeObserver(([_]) => {
|
|
308
|
+
var E, x;
|
|
309
|
+
const { width: U, height: b } = _.contentRect;
|
|
310
|
+
if (U > 0 && b > 0) {
|
|
311
|
+
const w = ((E = h.current) == null ? void 0 : E.w) ?? e.terminal.fontSize * 0.6, g = ((x = h.current) == null ? void 0 : x.h) ?? e.terminal.fontSize * 1.2;
|
|
312
|
+
v({
|
|
313
|
+
cols: Math.max(1, Math.floor(U / w)),
|
|
314
|
+
rows: Math.max(1, Math.floor(b / g))
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
return y.observe(n.current), () => y.disconnect();
|
|
319
|
+
}, [e.mode, e.fit, e.terminal.fontSize]), C(() => {
|
|
320
|
+
if (e.mode !== "terminal" || !m || !s.current) return;
|
|
321
|
+
let y = !1;
|
|
322
|
+
const _ = s.current, U = m, b = (w) => {
|
|
323
|
+
var g;
|
|
324
|
+
i(w), (g = e.onStatusChange) == null || g.call(e, w);
|
|
325
|
+
}, E = (w) => {
|
|
326
|
+
var g;
|
|
327
|
+
b("error"), u(w instanceof Error ? w.message : String(w)), (g = e.onError) == null || g.call(e, w);
|
|
328
|
+
};
|
|
329
|
+
b("loading"), u("");
|
|
330
|
+
async function x() {
|
|
331
|
+
try {
|
|
332
|
+
const w = await oe();
|
|
333
|
+
if (y) return;
|
|
334
|
+
_.innerHTML = "";
|
|
335
|
+
const g = new w.Terminal({
|
|
336
|
+
cols: U.cols,
|
|
337
|
+
rows: U.rows,
|
|
338
|
+
fontSize: e.terminal.fontSize,
|
|
339
|
+
fontFamily: e.terminal.fontFamily,
|
|
340
|
+
theme: e.terminal.theme,
|
|
341
|
+
disableStdin: !e.interactive,
|
|
342
|
+
cursorBlink: e.terminal.cursorBlink,
|
|
343
|
+
convertEol: e.terminal.convertEol
|
|
344
|
+
});
|
|
345
|
+
a.current = g, g.open(_);
|
|
346
|
+
let A = g.cols, M = g.rows;
|
|
347
|
+
if (e.fit === "container") {
|
|
348
|
+
const S = new w.FitAddon();
|
|
349
|
+
g.loadAddon(S), S.fit(), A = g.cols, M = g.rows, n.current && A > 0 && M > 0 && (h.current = {
|
|
350
|
+
w: n.current.clientWidth / A,
|
|
351
|
+
h: n.current.clientHeight / M
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
const H = e.resolveArgv({ cols: A, rows: M }), R = new TextDecoder(), F = new K({
|
|
355
|
+
args: [e.wasm.toString(), ...H],
|
|
356
|
+
env: e.env,
|
|
357
|
+
stdout: (S) => g.write(R.decode(S)),
|
|
358
|
+
stderr: (S) => g.write(R.decode(S)),
|
|
359
|
+
onExit: (S) => {
|
|
360
|
+
var Q;
|
|
361
|
+
y || (b("exited"), (Q = e.onExit) == null || Q.call(e, S));
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
e.interactive && g.onData((S) => F.pushInput(S));
|
|
365
|
+
const k = await X(e.wasm, F);
|
|
366
|
+
if (y) return;
|
|
367
|
+
b("running"), queueMicrotask(() => {
|
|
368
|
+
y || k.run().catch((S) => {
|
|
369
|
+
y || E(S);
|
|
370
|
+
});
|
|
371
|
+
});
|
|
372
|
+
} catch (w) {
|
|
373
|
+
y || E(w);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return x(), () => {
|
|
377
|
+
var w;
|
|
378
|
+
y = !0, (w = a.current) == null || w.dispose(), a.current = null;
|
|
379
|
+
};
|
|
380
|
+
}, [
|
|
381
|
+
e.mode,
|
|
382
|
+
m,
|
|
383
|
+
e.wasm,
|
|
384
|
+
e.resolveArgv,
|
|
385
|
+
e.env,
|
|
386
|
+
e.fit,
|
|
387
|
+
e.interactive,
|
|
388
|
+
e.onExit,
|
|
389
|
+
e.onError,
|
|
390
|
+
e.onStatusChange,
|
|
391
|
+
e.terminal.fontSize,
|
|
392
|
+
e.terminal.fontFamily,
|
|
393
|
+
e.terminal.theme,
|
|
394
|
+
e.terminal.cursorBlink,
|
|
395
|
+
e.terminal.convertEol
|
|
396
|
+
]), C(() => {
|
|
397
|
+
if (e.mode !== "static") return;
|
|
398
|
+
let y = !1;
|
|
399
|
+
const _ = (b) => {
|
|
400
|
+
var E;
|
|
401
|
+
i(b), (E = e.onStatusChange) == null || E.call(e, b);
|
|
402
|
+
};
|
|
403
|
+
_("loading"), u(""), o(null);
|
|
404
|
+
async function U() {
|
|
405
|
+
var b;
|
|
406
|
+
try {
|
|
407
|
+
const E = new TextDecoder(), x = [], w = new K({
|
|
408
|
+
args: [e.wasm.toString(), ...e.resolveArgv(e.size)],
|
|
409
|
+
env: e.env,
|
|
410
|
+
stdout: (A) => x.push(new Uint8Array(A)),
|
|
411
|
+
stderr: () => {
|
|
412
|
+
},
|
|
413
|
+
onExit: (A) => {
|
|
414
|
+
var M;
|
|
415
|
+
if (!y) {
|
|
416
|
+
const H = x.reduce((k, S) => k + S.length, 0), R = new Uint8Array(H);
|
|
417
|
+
let F = 0;
|
|
418
|
+
for (const k of x)
|
|
419
|
+
R.set(k, F), F += k.length;
|
|
420
|
+
o(ie(E.decode(R))), _("exited"), (M = e.onExit) == null || M.call(e, A);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}), g = await X(e.wasm, w);
|
|
424
|
+
if (y) return;
|
|
425
|
+
_("running"), await g.run();
|
|
426
|
+
} catch (E) {
|
|
427
|
+
y || (_("error"), u(E instanceof Error ? E.message : String(E)), (b = e.onError) == null || b.call(e, E));
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
return U(), () => {
|
|
431
|
+
y = !0;
|
|
432
|
+
};
|
|
433
|
+
}, [
|
|
434
|
+
e.mode,
|
|
435
|
+
e.wasm,
|
|
436
|
+
e.resolveArgv,
|
|
437
|
+
e.env,
|
|
438
|
+
e.size.cols,
|
|
439
|
+
e.size.rows,
|
|
440
|
+
e.onExit,
|
|
441
|
+
e.onError,
|
|
442
|
+
e.onStatusChange
|
|
443
|
+
]);
|
|
444
|
+
const f = (($ = e.terminal.theme) == null ? void 0 : $.background) ?? "#1a1b26", l = ((L = e.terminal.theme) == null ? void 0 : L.foreground) ?? "#a9b1d6";
|
|
445
|
+
return e.mode === "static" ? /* @__PURE__ */ D(
|
|
446
|
+
"div",
|
|
447
|
+
{
|
|
448
|
+
className: t.className,
|
|
449
|
+
style: {
|
|
450
|
+
position: "relative",
|
|
451
|
+
background: f,
|
|
452
|
+
borderRadius: 6,
|
|
453
|
+
overflow: "hidden",
|
|
454
|
+
...t.style
|
|
455
|
+
},
|
|
456
|
+
children: [
|
|
457
|
+
r === "loading" && /* @__PURE__ */ p("div", { style: N, children: "Loading…" }),
|
|
458
|
+
r === "error" && /* @__PURE__ */ D("div", { style: { ...N, color: "#f7768e" }, children: [
|
|
459
|
+
"Error: ",
|
|
460
|
+
c
|
|
461
|
+
] }),
|
|
462
|
+
d !== null && /* @__PURE__ */ p(
|
|
463
|
+
"pre",
|
|
464
|
+
{
|
|
465
|
+
style: {
|
|
466
|
+
margin: 0,
|
|
467
|
+
padding: "0.5em",
|
|
468
|
+
fontFamily: e.terminal.fontFamily,
|
|
469
|
+
fontSize: e.terminal.fontSize,
|
|
470
|
+
color: l,
|
|
471
|
+
lineHeight: 1.2,
|
|
472
|
+
background: "transparent",
|
|
473
|
+
overflow: "auto"
|
|
474
|
+
},
|
|
475
|
+
dangerouslySetInnerHTML: { __html: d }
|
|
476
|
+
}
|
|
477
|
+
)
|
|
478
|
+
]
|
|
479
|
+
}
|
|
480
|
+
) : /* @__PURE__ */ D(
|
|
481
|
+
"div",
|
|
482
|
+
{
|
|
483
|
+
ref: n,
|
|
484
|
+
className: t.className,
|
|
485
|
+
style: {
|
|
486
|
+
position: "relative",
|
|
487
|
+
display: "inline-block",
|
|
488
|
+
background: f,
|
|
489
|
+
borderRadius: 6,
|
|
490
|
+
overflow: "hidden",
|
|
491
|
+
...t.style
|
|
492
|
+
},
|
|
493
|
+
children: [
|
|
494
|
+
/* @__PURE__ */ p("div", { ref: s, style: { display: r === "error" ? "none" : void 0 } }),
|
|
495
|
+
r === "loading" && /* @__PURE__ */ p("div", { style: N, children: "Loading…" }),
|
|
496
|
+
r === "error" && /* @__PURE__ */ D("div", { style: { ...N, color: "#f7768e" }, children: [
|
|
497
|
+
"Error: ",
|
|
498
|
+
c
|
|
499
|
+
] })
|
|
500
|
+
]
|
|
501
|
+
}
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
const N = {
|
|
505
|
+
padding: "1rem",
|
|
506
|
+
fontFamily: "monospace",
|
|
507
|
+
fontSize: 14,
|
|
508
|
+
color: "#a9b1d6"
|
|
509
|
+
};
|
|
510
|
+
export {
|
|
511
|
+
ve as TuiPreview,
|
|
512
|
+
K as WasiBridge,
|
|
513
|
+
ee as WasiExitError,
|
|
514
|
+
X as instantiateApp
|
|
515
|
+
};
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
export interface TuiRuntimeSize {
|
|
2
|
+
cols: number;
|
|
3
|
+
rows: number;
|
|
4
|
+
}
|
|
5
|
+
export type TuiArgv = string[] | ((size: TuiRuntimeSize) => string[]);
|
|
6
|
+
export type TuiFitMode = "container" | "none";
|
|
7
|
+
export type TuiRenderMode = "terminal" | "static";
|
|
8
|
+
export type TuiPreviewStatus = "loading" | "running" | "exited" | "error";
|
|
9
|
+
export interface TuiTerminalOptions {
|
|
10
|
+
/** Font size in pixels. Default: 14 */
|
|
11
|
+
fontSize?: number;
|
|
12
|
+
/** CSS font family. Default: monospace */
|
|
13
|
+
fontFamily?: string;
|
|
14
|
+
/** ghostty-web theme overrides */
|
|
15
|
+
theme?: Partial<GhosttyTheme>;
|
|
16
|
+
/** Cursor blinking. Default: true */
|
|
17
|
+
cursorBlink?: boolean;
|
|
18
|
+
/** Convert LF to CRLF. Default: true */
|
|
19
|
+
convertEol?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface TuiPreviewCommonProps {
|
|
22
|
+
/** Environment variables (TERM, COLORTERM are set automatically) */
|
|
23
|
+
env?: Record<string, string>;
|
|
24
|
+
/** Whether the user can type into the terminal. Default: true */
|
|
25
|
+
interactive?: boolean;
|
|
26
|
+
/** Called when the app exits */
|
|
27
|
+
onExit?: (code: number) => void;
|
|
28
|
+
/** Called on runtime errors */
|
|
29
|
+
onError?: (error: unknown) => void;
|
|
30
|
+
/** Called whenever status changes */
|
|
31
|
+
onStatusChange?: (status: TuiPreviewStatus) => void;
|
|
32
|
+
className?: string;
|
|
33
|
+
style?: React.CSSProperties;
|
|
34
|
+
}
|
|
35
|
+
export interface TuiPreviewModernProps extends TuiPreviewCommonProps {
|
|
36
|
+
/** URL or path to a wasm32-wasi binary */
|
|
37
|
+
wasm: string | URL;
|
|
38
|
+
/** CLI argv (without argv[0]), static or size-aware */
|
|
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
|
+
*/
|
|
46
|
+
mode?: TuiRenderMode;
|
|
47
|
+
/** "container" auto-fit or "none" fixed size. Default: "container" */
|
|
48
|
+
fit?: TuiFitMode;
|
|
49
|
+
/** Fixed size (fit="none") or initial fallback (fit="container") */
|
|
50
|
+
size?: TuiRuntimeSize;
|
|
51
|
+
/** Terminal renderer options */
|
|
52
|
+
terminal?: TuiTerminalOptions;
|
|
53
|
+
}
|
|
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;
|
|
68
|
+
export interface GhosttyTheme {
|
|
69
|
+
background: string;
|
|
70
|
+
foreground: string;
|
|
71
|
+
cursor: string;
|
|
72
|
+
selectionBackground: string;
|
|
73
|
+
selectionForeground: string;
|
|
74
|
+
black: string;
|
|
75
|
+
red: string;
|
|
76
|
+
green: string;
|
|
77
|
+
yellow: string;
|
|
78
|
+
blue: string;
|
|
79
|
+
magenta: string;
|
|
80
|
+
cyan: string;
|
|
81
|
+
white: string;
|
|
82
|
+
brightBlack: string;
|
|
83
|
+
brightRed: string;
|
|
84
|
+
brightGreen: string;
|
|
85
|
+
brightYellow: string;
|
|
86
|
+
brightBlue: string;
|
|
87
|
+
brightMagenta: string;
|
|
88
|
+
brightCyan: string;
|
|
89
|
+
brightWhite: string;
|
|
90
|
+
}
|
|
91
|
+
export interface WasiOptions {
|
|
92
|
+
args: string[];
|
|
93
|
+
env: Record<string, string>;
|
|
94
|
+
stdout: (data: Uint8Array) => void;
|
|
95
|
+
stderr: (data: Uint8Array) => void;
|
|
96
|
+
onExit: (code: number) => void;
|
|
97
|
+
}
|
|
98
|
+
export interface ResolvedTuiPreviewOptions {
|
|
99
|
+
wasm: string | URL;
|
|
100
|
+
env: Record<string, string>;
|
|
101
|
+
interactive: boolean;
|
|
102
|
+
mode: TuiRenderMode;
|
|
103
|
+
fit: TuiFitMode;
|
|
104
|
+
size: TuiRuntimeSize;
|
|
105
|
+
terminal: Required<Omit<TuiTerminalOptions, "theme">> & {
|
|
106
|
+
theme?: Partial<GhosttyTheme>;
|
|
107
|
+
};
|
|
108
|
+
resolveArgv: (size: TuiRuntimeSize) => string[];
|
|
109
|
+
onExit?: (code: number) => void;
|
|
110
|
+
onError?: (error: unknown) => void;
|
|
111
|
+
onStatusChange?: (status: TuiPreviewStatus) => void;
|
|
112
|
+
usedLegacyProps: boolean;
|
|
113
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/wasi.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { WasiBridge, WasiExitError, instantiateApp } from "./core/wasi.js";
|
package/dist/wasi.js
ADDED