@dkkoval/tui-preview 0.1.0 → 0.2.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/README.md +24 -16
- package/dist/TuiPreview.js +64 -145
- package/dist/core/index.d.ts +2 -3
- package/dist/core/index.js +2 -3
- 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 -66
- package/dist/core/wasi.d.ts +1 -1
- package/dist/core/wasi.js +26 -6
- package/dist/ghostty-vt.wasm +0 -0
- package/dist/index.cjs +2 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +645 -411
- package/dist/types.d.ts +8 -26
- package/package.json +14 -7
- package/dist/__vite-browser-external-2447137e-BcPniuRQ.cjs +0 -1
- package/dist/__vite-browser-external-2447137e-DYxpcVy9.js +0 -4
- package/dist/core/ansi.d.ts +0 -15
- package/dist/core/ansi.js +0 -181
- 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/wasi.d.ts +0 -1
- package/dist/wasi.js +0 -2
package/dist/core/normalize.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
const DEFAULT_SIZE = { cols: 80, rows: 24 };
|
|
2
2
|
const EMPTY_ENV = {};
|
|
3
3
|
const EMPTY_ARGV = [];
|
|
4
|
-
function
|
|
5
|
-
|
|
4
|
+
function normalizeMode(mode) {
|
|
5
|
+
if (mode === "static") {
|
|
6
|
+
return "static";
|
|
7
|
+
}
|
|
8
|
+
return "interactive";
|
|
6
9
|
}
|
|
7
10
|
function resolveArgvInput(argv) {
|
|
8
11
|
const value = argv ?? EMPTY_ARGV;
|
|
@@ -11,79 +14,30 @@ function resolveArgvInput(argv) {
|
|
|
11
14
|
}
|
|
12
15
|
return () => value;
|
|
13
16
|
}
|
|
14
|
-
function resolveLegacySize(props) {
|
|
15
|
-
const hasExplicitSize = props.cols !== undefined || props.rows !== undefined;
|
|
16
|
-
if (!hasExplicitSize) {
|
|
17
|
-
return { fit: "container", size: DEFAULT_SIZE };
|
|
18
|
-
}
|
|
19
|
-
return {
|
|
20
|
-
fit: "none",
|
|
21
|
-
size: {
|
|
22
|
-
cols: Math.max(1, props.cols ?? DEFAULT_SIZE.cols),
|
|
23
|
-
rows: Math.max(1, props.rows ?? DEFAULT_SIZE.rows),
|
|
24
|
-
},
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
let warnedLegacyProps = false;
|
|
28
|
-
export function warnLegacyPropsOnce(usedLegacyProps) {
|
|
29
|
-
if (!usedLegacyProps || warnedLegacyProps)
|
|
30
|
-
return;
|
|
31
|
-
warnedLegacyProps = true;
|
|
32
|
-
console.warn("[tui-preview] Legacy props (`app`, `args`, `cols`, `rows`, `fontSize`, `fontFamily`, `theme`) are deprecated. " +
|
|
33
|
-
"Use `wasm`, `argv`, `fit`, `size`, and `terminal`.");
|
|
34
|
-
}
|
|
35
17
|
export function resolveTuiPreviewProps(props) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
: {
|
|
44
|
-
cols: Math.max(1, props.size?.cols ?? DEFAULT_SIZE.cols),
|
|
45
|
-
rows: Math.max(1, props.size?.rows ?? DEFAULT_SIZE.rows),
|
|
46
|
-
};
|
|
47
|
-
return {
|
|
48
|
-
wasm: props.wasm,
|
|
49
|
-
env: props.env ?? EMPTY_ENV,
|
|
50
|
-
interactive: props.interactive ?? true,
|
|
51
|
-
mode: (props.mode ?? "terminal"),
|
|
52
|
-
fit,
|
|
53
|
-
size,
|
|
54
|
-
terminal: {
|
|
55
|
-
fontSize: props.terminal?.fontSize ?? 14,
|
|
56
|
-
fontFamily: props.terminal?.fontFamily ?? "monospace",
|
|
57
|
-
cursorBlink: props.terminal?.cursorBlink ?? true,
|
|
58
|
-
convertEol: props.terminal?.convertEol ?? true,
|
|
59
|
-
theme: props.terminal?.theme,
|
|
60
|
-
},
|
|
61
|
-
resolveArgv: resolveArgvInput(props.argv),
|
|
62
|
-
onExit: props.onExit,
|
|
63
|
-
onError: props.onError,
|
|
64
|
-
onStatusChange: props.onStatusChange,
|
|
65
|
-
usedLegacyProps: false,
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
const { fit, size } = resolveLegacySize(props);
|
|
18
|
+
const fit = props.fit ?? (props.size ? "none" : "container");
|
|
19
|
+
const size = {
|
|
20
|
+
cols: Math.max(1, props.size?.cols ?? DEFAULT_SIZE.cols),
|
|
21
|
+
rows: Math.max(1, props.size?.rows ?? DEFAULT_SIZE.rows),
|
|
22
|
+
};
|
|
23
|
+
const mode = normalizeMode(props.mode);
|
|
69
24
|
return {
|
|
70
|
-
wasm: props.
|
|
25
|
+
wasm: props.wasm,
|
|
71
26
|
env: props.env ?? EMPTY_ENV,
|
|
72
|
-
interactive: props.interactive ?? true,
|
|
73
|
-
mode
|
|
27
|
+
interactive: mode === "static" ? false : (props.interactive ?? true),
|
|
28
|
+
mode,
|
|
74
29
|
fit,
|
|
75
30
|
size,
|
|
76
31
|
terminal: {
|
|
77
|
-
fontSize: props.fontSize ?? 14,
|
|
78
|
-
fontFamily: props.fontFamily ?? "monospace",
|
|
79
|
-
|
|
80
|
-
convertEol: true,
|
|
81
|
-
theme: props.theme,
|
|
32
|
+
fontSize: props.terminal?.fontSize ?? 14,
|
|
33
|
+
fontFamily: props.terminal?.fontFamily ?? "monospace",
|
|
34
|
+
wasmUrl: props.terminal?.wasmUrl,
|
|
35
|
+
convertEol: props.terminal?.convertEol ?? true,
|
|
36
|
+
theme: props.terminal?.theme,
|
|
82
37
|
},
|
|
83
|
-
resolveArgv: resolveArgvInput(props.
|
|
38
|
+
resolveArgv: resolveArgvInput(props.argv),
|
|
84
39
|
onExit: props.onExit,
|
|
85
40
|
onError: props.onError,
|
|
86
41
|
onStatusChange: props.onStatusChange,
|
|
87
|
-
usedLegacyProps: true,
|
|
88
42
|
};
|
|
89
43
|
}
|
package/dist/core/wasi.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* WASI bridge — connects a wasm32-wasi TUI app to a
|
|
2
|
+
* WASI bridge — connects a wasm32-wasi TUI app to a terminal surface.
|
|
3
3
|
*
|
|
4
4
|
* Implements a minimal WASI preview1 surface sufficient for interactive TUI apps:
|
|
5
5
|
* - fd_write (stdout/stderr → terminal)
|
package/dist/core/wasi.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* WASI bridge — connects a wasm32-wasi TUI app to a
|
|
2
|
+
* WASI bridge — connects a wasm32-wasi TUI app to a terminal surface.
|
|
3
3
|
*
|
|
4
4
|
* Implements a minimal WASI preview1 surface sufficient for interactive TUI apps:
|
|
5
5
|
* - fd_write (stdout/stderr → terminal)
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
const WASI_ESUCCESS = 0;
|
|
13
13
|
const WASI_EAGAIN = 6;
|
|
14
14
|
const WASI_BADF = 8;
|
|
15
|
+
const WASI_EVENTTYPE_FD_READ = 1;
|
|
15
16
|
const STDIN_FD = 0;
|
|
16
17
|
const STDOUT_FD = 1;
|
|
17
18
|
const STDERR_FD = 2;
|
|
@@ -115,7 +116,7 @@ export class WasiBridge {
|
|
|
115
116
|
fd_read: (fd, iovsPtr, iovsLen, nreadPtr) => {
|
|
116
117
|
if (fd !== STDIN_FD)
|
|
117
118
|
return WASI_BADF;
|
|
118
|
-
const chunk = this.inputQueue
|
|
119
|
+
const chunk = this.inputQueue[0];
|
|
119
120
|
if (!chunk)
|
|
120
121
|
return WASI_EAGAIN;
|
|
121
122
|
const view = this.view();
|
|
@@ -128,6 +129,12 @@ export class WasiBridge {
|
|
|
128
129
|
u8.set(chunk.subarray(nread, nread + toCopy), ptr);
|
|
129
130
|
nread += toCopy;
|
|
130
131
|
}
|
|
132
|
+
if (nread >= chunk.length) {
|
|
133
|
+
this.inputQueue.shift();
|
|
134
|
+
}
|
|
135
|
+
else if (nread > 0) {
|
|
136
|
+
this.inputQueue[0] = chunk.subarray(nread);
|
|
137
|
+
}
|
|
131
138
|
view.setUint32(nreadPtr, nread, true);
|
|
132
139
|
return WASI_ESUCCESS;
|
|
133
140
|
},
|
|
@@ -137,7 +144,7 @@ export class WasiBridge {
|
|
|
137
144
|
for (let i = 0; i < nsubscriptions; i++) {
|
|
138
145
|
const subPtr = inPtr + i * 48;
|
|
139
146
|
const type = view.getUint8(subPtr + 8);
|
|
140
|
-
if (type ===
|
|
147
|
+
if (type === WASI_EVENTTYPE_FD_READ && this.inputQueue.length > 0) {
|
|
141
148
|
const evPtr = outPtr + nevents * 32;
|
|
142
149
|
view.setBigUint64(evPtr, view.getBigUint64(subPtr, true), true);
|
|
143
150
|
view.setUint16(evPtr + 8, 0, true);
|
|
@@ -191,11 +198,24 @@ export class WasiExitError extends Error {
|
|
|
191
198
|
this.code = code;
|
|
192
199
|
}
|
|
193
200
|
}
|
|
201
|
+
/** Compiled module cache — keyed by URL string, persists for the page lifetime. */
|
|
202
|
+
const moduleCache = new Map();
|
|
194
203
|
/** Load and instantiate a WASM TUI app with a WasiBridge */
|
|
195
204
|
export async function instantiateApp(source, bridge) {
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
205
|
+
const key = source.toString();
|
|
206
|
+
let module = moduleCache.get(key);
|
|
207
|
+
if (!module) {
|
|
208
|
+
const response = await fetch(source);
|
|
209
|
+
if (!response.ok) {
|
|
210
|
+
throw new Error(`Failed to load app wasm: ${response.status} ${response.statusText}`);
|
|
211
|
+
}
|
|
212
|
+
const bytes = await response.arrayBuffer();
|
|
213
|
+
if (bytes.byteLength === 0) {
|
|
214
|
+
throw new Error("App wasm is empty.");
|
|
215
|
+
}
|
|
216
|
+
module = await WebAssembly.compile(bytes);
|
|
217
|
+
moduleCache.set(key, module);
|
|
218
|
+
}
|
|
199
219
|
const importObject = {
|
|
200
220
|
wasi_snapshot_preview1: bridge.imports,
|
|
201
221
|
};
|
|
Binary file
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1,2 @@
|
|
|
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;
|
|
1
|
+
"use strict";var st=Object.defineProperty;var it=(e,t,n)=>t in e?st(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var B=(e,t,n)=>it(e,typeof t!="symbol"?t+"":t,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const L=require("react/jsx-runtime"),U=require("react"),F=16,M=80,Z="/ghostty-vt.wasm",ot=1,at=2,ct=4,W=8,O=16,lt=32,$=64,H=128,ht=["black","red","green","yellow","blue","magenta","cyan","white","brightBlack","brightRed","brightGreen","brightYellow","brightBlue","brightMagenta","brightCyan","brightWhite"],ut={background:"#1a1b26",foreground:"#a9b1d6",cursor:"#c0caf5",selectionBackground:"#33467c",selectionForeground:"#c0caf5",black:"#15161e",red:"#f7768e",green:"#9ece6a",yellow:"#e0af68",blue:"#7aa2f7",magenta:"#bb9af7",cyan:"#7dcfff",white:"#a9b1d6",brightBlack:"#414868",brightRed:"#f7768e",brightGreen:"#9ece6a",brightYellow:"#e0af68",brightBlue:"#7aa2f7",brightMagenta:"#bb9af7",brightCyan:"#7dcfff",brightWhite:"#c0caf5"};class ft{constructor(t,n){this.wasm=t,this.abi=n}createTerminal(t,n,r){const o=this.wasm.ghostty_wasm_alloc_u8_array(this.abi.terminalConfigSize);if(!o)throw new Error("Failed to allocate terminal config.");try{const i=new DataView(this.wasm.memory.buffer);let s=o;i.setUint32(s,1e4,!0),s+=4,i.setUint32(s,D(r.foreground),!0),s+=4,i.setUint32(s,D(r.background),!0),s+=4,i.setUint32(s,D(r.cursor),!0),s+=4;for(const c of ht)i.setUint32(s,D(r[c]),!0),s+=4;const a=this.wasm.ghostty_terminal_new_with_config(t,n,o);if(!a)throw new Error("Failed to create libghostty terminal.");return new wt(this.wasm,a,t,n,this.abi.cellSize)}finally{this.wasm.ghostty_wasm_free_u8_array(o,this.abi.terminalConfigSize)}}}class wt{constructor(t,n,r,o,i){B(this,"viewportPtr",0);B(this,"viewportLen",0);this.wasm=t,this.handle=n,this.cols=r,this.rows=o,this.cellSize=i}write(t){const n=typeof t=="string"?new TextEncoder().encode(t):t;if(n.length===0)return;const r=this.wasm.ghostty_wasm_alloc_u8_array(n.length);if(!r)throw new Error("Failed to allocate libghostty write buffer.");try{new Uint8Array(this.wasm.memory.buffer).set(n,r),this.wasm.ghostty_terminal_write(this.handle,r,n.length)}finally{this.wasm.ghostty_wasm_free_u8_array(r,n.length)}}resize(t,n){t===this.cols&&n===this.rows||(this.cols=t,this.rows=n,this.wasm.ghostty_terminal_resize(this.handle,t,n),this.releaseViewport())}hasResponse(){return this.wasm.ghostty_terminal_has_response(this.handle)}isDirty(){return this.wasm.ghostty_render_state_update(this.handle)!==0}readResponse(t=4096){const n=this.wasm.ghostty_wasm_alloc_u8_array(t);if(!n)throw new Error("Failed to allocate libghostty response buffer.");try{const r=this.wasm.ghostty_terminal_read_response(this.handle,n,t);if(r<=0)return null;const o=new Uint8Array(this.wasm.memory.buffer,n,r);return new TextDecoder().decode(o)}finally{this.wasm.ghostty_wasm_free_u8_array(n,t)}}getViewportData(){const t=this.wasm.ghostty_render_state_get_cols(this.handle),n=this.wasm.ghostty_render_state_get_rows(this.handle);this.cols=t,this.rows=n;const r=Math.max(1,t*n*this.cellSize);if((r>this.viewportLen||this.viewportPtr===0)&&(this.releaseViewport(),this.viewportPtr=this.wasm.ghostty_wasm_alloc_u8_array(r),this.viewportLen=r,!this.viewportPtr))throw new Error("Failed to allocate libghostty viewport buffer.");const o=this.wasm.ghostty_render_state_get_viewport(this.handle,this.viewportPtr,this.viewportLen),i=new Uint8Array(o);if(o>0){const s=new Uint8Array(this.wasm.memory.buffer,this.viewportPtr,o);i.set(s)}return this.wasm.ghostty_render_state_mark_clean(this.handle),{cols:t,rows:n,buffer:i}}dispose(){this.releaseViewport(),this.wasm.ghostty_terminal_free(this.handle)}releaseViewport(){this.viewportPtr!==0&&(this.wasm.ghostty_wasm_free_u8_array(this.viewportPtr,this.viewportLen),this.viewportPtr=0,this.viewportLen=0)}}class mt{constructor(t,n,r,o,i,s){B(this,"ctx");B(this,"dpr");B(this,"metrics");this.canvas=t,this.cols=n,this.rows=r,this.fontSize=o,this.fontFamily=i,this.theme=s;const a=t.getContext("2d");if(!a)throw new Error("Failed to create 2D canvas context.");this.ctx=a,this.dpr=window.devicePixelRatio||1,this.metrics=this.measureFont(),this.resizeCanvas(n,r)}get cellSize(){return{w:this.metrics.width,h:this.metrics.height}}render(t){(t.cols!==this.cols||t.rows!==this.rows)&&(this.cols=t.cols,this.rows=t.rows,this.resizeCanvas(t.cols,t.rows));const{cols:n,rows:r,buffer:o}=t,i=new DataView(o.buffer,o.byteOffset,o.byteLength),s=this.ctx,a=this.metrics.width,c=this.metrics.height;s.fillStyle=this.theme.background,s.fillRect(0,0,n*a,r*c);for(let l=0;l<r;l++)for(let u=0;u<n;u++){const h=(l*n+u)*F,f=i.getUint8(h+11);if(f===0)continue;const w=i.getUint8(h+10),b=R(i,h+4),y=R(i,h+7),_=x(w,O),g=x(w,W)?P(b):this.theme.foreground,d=x(w,$)?P(y):this.theme.background;(_||x(w,$))&&(s.fillStyle=_?g:d,s.fillRect(u*a,l*c,f*a,c))}for(let l=0;l<r;l++)for(let u=0;u<n;u++){const h=(l*n+u)*F,f=i.getUint8(h+11);if(f===0)continue;const w=i.getUint8(h+10);if(x(w,lt))continue;const b=i.getUint32(h,!0);if(b===0)continue;const y=x(w,O),_=R(i,h+4),g=R(i,h+7),d=x(w,W)?P(_):this.theme.foreground,m=x(w,$)?P(g):this.theme.background;s.fillStyle=y?m:d;let p="";x(w,at)&&(p+="italic "),x(w,ot)&&(p+="bold "),s.font=`${p}${this.fontSize}px ${this.fontFamily}`,x(w,H)&&(s.globalAlpha=.5);const E=bt(b);if(s.fillText(E,u*a,l*c+this.metrics.baseline),x(w,H)&&(s.globalAlpha=1),x(w,ct)){const v=l*c+this.metrics.baseline+2;s.strokeStyle=s.fillStyle,s.lineWidth=1,s.beginPath(),s.moveTo(u*a,v),s.lineTo(u*a+f*a,v),s.stroke()}}}dispose(){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height)}measureFont(){this.ctx.font=`${this.fontSize}px ${this.fontFamily}`;const t=this.ctx.measureText("M"),n=Math.ceil(t.width),r=t.actualBoundingBoxAscent||this.fontSize*.8,o=t.actualBoundingBoxDescent||this.fontSize*.2;return{width:n,height:Math.ceil(r+o)+2,baseline:Math.ceil(r)+1}}resizeCanvas(t,n){const r=t*this.metrics.width,o=n*this.metrics.height;this.canvas.width=Math.max(1,Math.floor(r*this.dpr)),this.canvas.height=Math.max(1,Math.floor(o*this.dpr)),this.canvas.style.width=`${r}px`,this.canvas.style.height=`${o}px`,this.ctx.setTransform(this.dpr,0,0,this.dpr,0,0),this.ctx.textBaseline="alphabetic",this.ctx.textAlign="left"}}function J(e,t){const r=document.createElement("canvas").getContext("2d");if(!r)return{w:Math.ceil(e*.6),h:Math.ceil(e*1.2)};r.font=`${e}px ${t}`;const o=r.measureText("M"),i=Math.ceil(o.width),s=o.actualBoundingBoxAscent||e*.8,a=o.actualBoundingBoxDescent||e*.2;return{w:i,h:Math.ceil(s+a)+2}}const K=new Map;function dt(e=Z){const t=e.toString(),n=K.get(t);if(n)return n;const r=(async()=>{const o=await fetch(e);if(!o.ok)throw new Error(`Failed to load libghostty wasm: ${o.status} ${o.statusText}`);const i=await o.arrayBuffer();if(i.byteLength===0)throw new Error("libghostty wasm is empty.");const s=await WebAssembly.compile(i),c=(await WebAssembly.instantiate(s,{env:{log:()=>{}}})).exports;if(!c.memory||!c.ghostty_terminal_new||!c.ghostty_render_state_get_viewport)throw new Error("Invalid libghostty wasm exports.");return yt(c),new ft(c,{cellSize:F,terminalConfigSize:M})})();return K.set(t,r),r}async function gt(e){var _,g;const t=await dt(e.wasmUrl??Z),n={...ut,...e.theme};let r,o;const i=J(e.fontSize,e.fontFamily);e.widthPx!=null&&e.heightPx!=null?(r=Math.max(1,Math.floor(e.widthPx/i.w)),o=Math.max(1,Math.floor(e.heightPx/i.h))):(r=e.cols??80,o=e.rows??24),e.container.innerHTML="";const s=document.createElement("canvas");s.style.display="block",s.style.outline="none",s.tabIndex=e.interactive?0:-1,e.container.appendChild(s);const a=t.createTerminal(r,o,n),c=new mt(s,r,o,e.fontSize,e.fontFamily,n);e.showCursor||a.write("\x1B[?25l"),c.render(a.getViewportData());const l=((_=window.requestAnimationFrame)==null?void 0:_.bind(window))??(d=>window.setTimeout(d,16)),u=((g=window.cancelAnimationFrame)==null?void 0:g.bind(window))??window.clearTimeout.bind(window);let h=null,f=!1;const w=()=>{h=null,!(f||!a.isDirty())&&c.render(a.getViewportData())},b=()=>{h!==null||f||(h=l(w))},y=e.interactive?pt(s,d=>{var m;return(m=e.onInput)==null?void 0:m.call(e,d)}):()=>{};return{cols:r,rows:o,cellSize:c.cellSize,write(d){if(f)return;const m=e.convertEol?_t(d):d;a.write(m),b()},drainResponses(){if(f)return[];const d=[];for(;a.hasResponse();){const m=a.readResponse();if(!m)break;d.push(m)}return d},dispose(){f=!0,h!==null&&(u(h),h=null),y(),c.dispose(),a.dispose(),s.parentElement===e.container&&e.container.removeChild(s)}}}function yt(e){const t=e.ghostty_wasm_alloc_u8_array(M);if(!t)throw new Error("Failed to allocate ABI probe config buffer.");let n=0,r=0,o=0,i=0;const s=1122867,a=4478310,[c,l,u]=j(s),[h,f,w]=j(a);try{new Uint8Array(e.memory.buffer,t,M).fill(0);const b=new DataView(e.memory.buffer,t,M);if(b.setUint32(0,16,!0),b.setUint32(4,s,!0),b.setUint32(8,a,!0),b.setUint32(12,7833753,!0),n=e.ghostty_terminal_new_with_config(2,1,t),!n)throw new Error("Failed to create ABI probe terminal.");const y=new TextEncoder().encode("\x1B[7mX");if(o=y.length,r=e.ghostty_wasm_alloc_u8_array(o),!r)throw new Error("Failed to allocate ABI probe write buffer.");if(new Uint8Array(e.memory.buffer,r,o).set(y),e.ghostty_terminal_write(n,r,o),i=e.ghostty_wasm_alloc_u8_array(F),!i)throw new Error("Failed to allocate ABI probe viewport buffer.");const _=e.ghostty_render_state_get_viewport(n,i,F);if(_!==F)throw new Error(`Incompatible libghostty ABI: expected cell size ${F}, got ${_}.`);const g=new DataView(e.memory.buffer,i,F),d=g.getUint8(10),m=x(d,W),p=x(d,$),E=g.getUint8(4)===c&&g.getUint8(5)===l&&g.getUint8(6)===u,v=g.getUint8(7)===h&&g.getUint8(8)===f&&g.getUint8(9)===w;if(!m||!p||!E||!v)throw new Error("Incompatible libghostty ABI: terminal config layout mismatch.")}finally{i&&e.ghostty_wasm_free_u8_array(i,F),r&&o>0&&e.ghostty_wasm_free_u8_array(r,o),n&&e.ghostty_terminal_free(n),e.ghostty_wasm_free_u8_array(t,M)}}function _t(e){return e.replace(/\r?\n/g,`\r
|
|
2
|
+
`)}function D(e){if(e.startsWith("#")){let i=e.slice(1);i.length===3&&(i=`${i[0]}${i[0]}${i[1]}${i[1]}${i[2]}${i[2]}`);const s=Number.parseInt(i,16);return Number.isNaN(s)?0:s}const t=e.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);if(!t)return 0;const n=Number.parseInt(t[1],10),r=Number.parseInt(t[2],10),o=Number.parseInt(t[3],10);return n<<16|r<<8|o}function j(e){return[e>>16&255,e>>8&255,e&255]}function R(e,t){return{r:e.getUint8(t),g:e.getUint8(t+1),b:e.getUint8(t+2)}}function x(e,t){return(e&t)!==0}function P(e){return`rgb(${e.r}, ${e.g}, ${e.b})`}function bt(e){try{return String.fromCodePoint(e)}catch{return" "}}function pt(e,t){const n=()=>e.focus(),r=i=>{var a;const s=(a=i.clipboardData)==null?void 0:a.getData("text");s&&(i.preventDefault(),t(s))},o=i=>{const s=Et(i);s&&(i.preventDefault(),t(s))};return e.addEventListener("mousedown",n),e.addEventListener("paste",r),e.addEventListener("keydown",o),()=>{e.removeEventListener("mousedown",n),e.removeEventListener("paste",r),e.removeEventListener("keydown",o)}}function Et(e){if(e.isComposing||e.metaKey)return null;let t=null;switch(e.key){case"Enter":t="\r";break;case"Backspace":t="";break;case"Tab":t=e.shiftKey?"\x1B[Z":" ";break;case"Escape":t="\x1B";break;case"ArrowUp":t="\x1B[A";break;case"ArrowDown":t="\x1B[B";break;case"ArrowRight":t="\x1B[C";break;case"ArrowLeft":t="\x1B[D";break;case"Home":t="\x1B[H";break;case"End":t="\x1B[F";break;case"Delete":t="\x1B[3~";break;case"PageUp":t="\x1B[5~";break;case"PageDown":t="\x1B[6~";break}return!t&&e.ctrlKey&&(t=vt(e.key)),!t&&e.key.length===1&&!e.ctrlKey&&(t=e.key),t?e.altKey&&!t.startsWith("\x1B")?`\x1B${t}`:t:null}function vt(e){if(e.length!==1)return null;const t=e.toUpperCase();if(t>="A"&&t<="Z")return String.fromCharCode(t.charCodeAt(0)-64);switch(e){case"@":case" ":return"\0";case"[":return"\x1B";case"\\":return"";case"]":return"";case"^":return"";case"_":return"";default:return null}}const Y={cols:80,rows:24},xt={},At=[];function St(e){return e==="static"?"static":"interactive"}function Ut(e){const t=e??At;return typeof t=="function"?t:()=>t}function Ft(e){var o,i,s,a,c,l,u;const t=e.fit??(e.size?"none":"container"),n={cols:Math.max(1,((o=e.size)==null?void 0:o.cols)??Y.cols),rows:Math.max(1,((i=e.size)==null?void 0:i.rows)??Y.rows)},r=St(e.mode);return{wasm:e.wasm,env:e.env??xt,interactive:r==="static"?!1:e.interactive??!0,mode:r,fit:t,size:n,terminal:{fontSize:((s=e.terminal)==null?void 0:s.fontSize)??14,fontFamily:((a=e.terminal)==null?void 0:a.fontFamily)??"monospace",wasmUrl:(c=e.terminal)==null?void 0:c.wasmUrl,convertEol:((l=e.terminal)==null?void 0:l.convertEol)??!0,theme:(u=e.terminal)==null?void 0:u.theme},resolveArgv:Ut(e.argv),onExit:e.onExit,onError:e.onError,onStatusChange:e.onStatusChange}}const A=0,Bt=6,C=8,Tt=1,Ct=0,q=1,Mt=2;class tt{constructor(t){B(this,"inputQueue",[]);B(this,"memory");this.opts=t}pushInput(t){const n=typeof t=="string"?new TextEncoder().encode(t):t;this.inputQueue.push(n)}attachMemory(t){this.memory=t}view(){return new DataView(this.memory.buffer)}u8(){return new Uint8Array(this.memory.buffer)}get imports(){return{args_sizes_get:(t,n)=>{const{args:r}=this.opts,o=new TextEncoder,i=r.reduce((s,a)=>s+o.encode(a).length+1,0);return this.view().setUint32(t,r.length,!0),this.view().setUint32(n,i,!0),A},args_get:(t,n)=>{const r=new TextEncoder,o=this.u8(),i=this.view();let s=n;return this.opts.args.forEach((a,c)=>{const l=r.encode(a);o.set(l,s),o[s+l.length]=0,i.setUint32(t+c*4,s,!0),s+=l.length+1}),A},environ_sizes_get:(t,n)=>{const r=this.envEntries(),o=new TextEncoder,i=r.reduce((s,a)=>s+o.encode(a).length+1,0);return this.view().setUint32(t,r.length,!0),this.view().setUint32(n,i,!0),A},environ_get:(t,n)=>{const r=new TextEncoder,o=this.u8(),i=this.view();let s=n;return this.envEntries().forEach((a,c)=>{const l=r.encode(a);o.set(l,s),o[s+l.length]=0,i.setUint32(t+c*4,s,!0),s+=l.length+1}),A},fd_write:(t,n,r,o)=>{if(t!==q&&t!==Mt)return C;const i=this.view(),s=this.u8();let a=0;const c=[];for(let h=0;h<r;h++){const f=i.getUint32(n+h*8,!0),w=i.getUint32(n+h*8+4,!0);c.push(s.slice(f,f+w)),a+=w}const l=new Uint8Array(a);let u=0;for(const h of c)l.set(h,u),u+=h.length;return t===q?this.opts.stdout(l):this.opts.stderr(l),i.setUint32(o,a,!0),A},fd_read:(t,n,r,o)=>{if(t!==Ct)return C;const i=this.inputQueue[0];if(!i)return Bt;const s=this.view(),a=this.u8();let c=0;for(let l=0;l<r&&c<i.length;l++){const u=s.getUint32(n+l*8,!0),h=s.getUint32(n+l*8+4,!0),f=Math.min(h,i.length-c);a.set(i.subarray(c,c+f),u),c+=f}return c>=i.length?this.inputQueue.shift():c>0&&(this.inputQueue[0]=i.subarray(c)),s.setUint32(o,c,!0),A},poll_oneoff:(t,n,r,o)=>{const i=this.view();let s=0;for(let a=0;a<r;a++){const c=t+a*48,l=i.getUint8(c+8);if(l===Tt&&this.inputQueue.length>0){const u=n+s*32;i.setBigUint64(u,i.getBigUint64(c,!0),!0),i.setUint16(u+8,0,!0),i.setUint8(u+10,l),s++}}return i.setUint32(o,s,!0),A},proc_exit:t=>{throw this.opts.onExit(t),new N(t)},random_get:(t,n)=>(crypto.getRandomValues(new Uint8Array(this.memory.buffer,t,n)),A),fd_close:()=>A,fd_seek:()=>A,fd_fdstat_get:(t,n)=>(this.view().setUint8(n,t<=2?2:0),A),fd_prestat_get:()=>C,fd_prestat_dir_name:()=>C,path_open:()=>C,sched_yield:()=>A,clock_time_get:(t,n,r)=>{const o=BigInt(Date.now())*1000000n;return this.view().setBigUint64(r,o,!0),A}}}envEntries(){const t={TERM:"xterm-256color",COLORTERM:"truecolor",...this.opts.env};return Object.entries(t).map(([n,r])=>`${n}=${r}`)}}class N extends Error{constructor(t){super(`WASI exit: ${t}`),this.code=t}}const Q=new Map;async function et(e,t){const n=e.toString();let r=Q.get(n);if(!r){const a=await fetch(e);if(!a.ok)throw new Error(`Failed to load app wasm: ${a.status} ${a.statusText}`);const c=await a.arrayBuffer();if(c.byteLength===0)throw new Error("App wasm is empty.");r=await WebAssembly.compile(c),Q.set(n,r)}const o={wasi_snapshot_preview1:t.imports},i=await WebAssembly.instantiate(r,o);t.attachMemory(i.exports.memory);const s=i.exports._start;if(!s)throw new Error("WASM module has no _start export");return{run:async()=>{try{s()}catch(a){if(!(a instanceof N))throw a}}}}function kt(e){var h;const t=U.useMemo(()=>Ft(e),[e]),n=U.useRef(null),r=U.useRef(null),[o,i]=U.useState("loading"),[s,a]=U.useState(""),c=U.useRef(null),[l,u]=U.useState(t.fit==="container"?null:t.size);return U.useEffect(()=>{u(t.fit==="container"?null:t.size)},[t.fit,t.size.cols,t.size.rows]),U.useEffect(()=>{if(t.fit!=="container"||!n.current)return;const f=n.current,w=J(t.terminal.fontSize,t.terminal.fontFamily),b=(g,d)=>{var k,I;const m=((k=c.current)==null?void 0:k.w)??w.w,p=((I=c.current)==null?void 0:I.h)??w.h,E=Math.max(1,Math.floor(g/m)),v=Math.max(1,Math.floor(d/p));u(T=>T&&T.cols===E&&T.rows===v?T:{cols:E,rows:v})},y=f.getBoundingClientRect();y.width>0&&y.height>0&&b(y.width,y.height);const _=new ResizeObserver(([g])=>{const{width:d,height:m}=g.contentRect;d>0&&m>0&&b(d,m)});return _.observe(f),()=>_.disconnect()},[t.fit,t.terminal.fontSize,t.terminal.fontFamily]),U.useEffect(()=>{if(!l||!r.current)return;let f=!1,w=null;const b=r.current,y=l,_=m=>{var p;i(m),(p=t.onStatusChange)==null||p.call(t,m)},g=m=>{var p;_("error"),a(m instanceof Error?m.message:String(m)),(p=t.onError)==null||p.call(t,m)};_("loading"),a("");async function d(){try{let m=y.cols,p=y.rows,E=null;const v=await gt({container:b,cols:y.cols,rows:y.rows,fontSize:t.terminal.fontSize,fontFamily:t.terminal.fontFamily,theme:t.terminal.theme,convertEol:t.terminal.convertEol,interactive:t.mode!=="static"&&t.interactive,showCursor:t.mode!=="static",wasmUrl:t.terminal.wasmUrl,onInput:S=>E==null?void 0:E.pushInput(S)});if(f){v.dispose();return}w=()=>v.dispose(),m=v.cols,p=v.rows,c.current=v.cellSize;const k=t.resolveArgv({cols:m,rows:p}),I=new TextDecoder,T=new TextDecoder,G=(S,z)=>{const V=z.decode(S,{stream:!0});V&&v.write(V);for(const rt of v.drainResponses())E==null||E.pushInput(rt)};E=new tt({args:[t.wasm.toString(),...k],env:t.env,stdout:S=>G(S,I),stderr:S=>G(S,T),onExit:S=>{var z;f||(_("exited"),(z=t.onExit)==null||z.call(t,S))}});const nt=await et(t.wasm,E);if(f)return;_("running"),queueMicrotask(()=>{f||nt.run().catch(S=>{f||g(S)})})}catch(m){f||g(m)}}return d(),()=>{f=!0,w==null||w(),w=null}},[t.mode,l,t.wasm,t.resolveArgv,t.env,t.fit,t.interactive,t.onExit,t.onError,t.onStatusChange,t.terminal.fontSize,t.terminal.fontFamily,t.terminal.theme,t.terminal.wasmUrl,t.terminal.convertEol]),L.jsxs("div",{ref:n,className:e.className,style:{position:"relative",display:t.fit==="container"?"block":"inline-block",background:((h=t.terminal.theme)==null?void 0:h.background)??"#1a1b26",borderRadius:6,overflow:"hidden",...e.style},children:[L.jsx("div",{ref:r,style:{display:o==="error"?"none":void 0}}),o==="loading"&&L.jsx("div",{style:X,children:"Loading…"}),o==="error"&&L.jsxs("div",{style:{...X,color:"#f7768e"},children:["Error: ",s]})]})}const X={padding:"1rem",fontFamily:"monospace",fontSize:14,color:"#a9b1d6"};exports.TuiPreview=kt;exports.WasiBridge=tt;exports.WasiExitError=N;exports.instantiateApp=et;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { TuiPreview } from "./TuiPreview.js";
|
|
2
|
-
export type { GhosttyTheme, ResolvedTuiPreviewOptions, TuiArgv, TuiFitMode, TuiRenderMode, TuiPreviewCommonProps,
|
|
3
|
-
export { WasiBridge, WasiExitError, instantiateApp } from "./wasi.js";
|
|
2
|
+
export type { GhosttyTheme, ResolvedTuiPreviewOptions, TuiArgv, TuiFitMode, TuiRenderMode, TuiPreviewCommonProps, TuiPreviewModernProps, TuiPreviewProps, TuiPreviewStatus, TuiRuntimeSize, TuiTerminalOptions, WasiOptions, } from "./types.js";
|
|
3
|
+
export { WasiBridge, WasiExitError, instantiateApp } from "./core/wasi.js";
|