webtty 1.6.0 → 1.7.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.
@@ -1,3 +1,3 @@
1
- import{FitAddon as L,init as M,Terminal as y}from"/dist/ghostty-web.js";var B=new RegExp("\x1B\\[(\\d*) q","g");function W(j,G){let Q=j.options.cursorStyle,P=j.options.cursorBlink;B.lastIndex=0;let K=B.exec(G);while(K!==null){let J=K[1]===""?0:Number(K[1]);if(!Number.isNaN(J)&&J>=0&&J<=6)j.options.cursorStyle=J===0||J===1||J===2?"block":J===3||J===4?"underline":"bar",j.options.cursorBlink=J===0||J===1||J===3||J===5;K=B.exec(G)}if((j.options.cursorStyle!==Q||j.options.cursorBlink!==P)&&j.renderer&&j.wasmTerm)j.renderer.render(j.wasmTerm,!0,j.viewportY)}var O=window.location.pathname.split("/s/")[1]??"main",N=await fetch("/api/config").then((j)=>j.json());document.title=`${O} | webtty`;await M();var z=new y({cols:N.cols,rows:N.rows,cursorStyle:N.cursorStyle,cursorBlink:N.cursorStyleBlink,fontSize:N.fontSize,fontFamily:N.fontFamily,scrollback:Math.ceil(N.scrollback/80),theme:N.theme}),_=new L;z.loadAddon(_);var $=document.getElementById("terminal");await z.open($);_.fit();_.observeResize();var U=window.location.protocol==="https:"?"wss:":"ws:",H;function q(){let j=`${U}//${window.location.host}/ws/${O}?cols=${z.cols}&rows=${z.rows}`;H=new WebSocket(j);let G="\x1B[2m",Q="\x1B[1;33m",P="\x1B[3m",K="\x1B[0m",J=`${G}[${K} ${Q}webtty${K} ${G}]${K}`,V=(X)=>`\r
2
- ${J} ${G}${P}${X}${K}\r
3
- `;H.onopen=()=>{H.send(JSON.stringify({type:"resize",cols:z.cols,rows:z.rows}))},H.onmessage=(X)=>{W(z,X.data),z.write(X.data)},H.onclose=(X)=>{if(X.code===4001){z.write(V("Session removed.")),setTimeout(()=>window.close(),500);return}if(X.code===1001){z.write(V("Server stopped.")),setTimeout(()=>window.close(),500);return}z.write(V("Connection lost. Reconnecting in 2s...")),setTimeout(q,2000)},H.onerror=()=>{z.write(V("WebSocket error."))}}q();var Z=0,Y=0;z.attachCustomWheelEventHandler((j)=>{if(!z.hasMouseTracking())return!1;let G=z.renderer?.getMetrics();if(!G)return!1;let Q=j.deltaY<0?-1:1;if(Q!==Y)Z=0,Y=Q;Z+=N.mouseScrollSpeed;let P=Math.trunc(Z);if(P===0)return!0;Z-=P;let K=j.target.getBoundingClientRect(),J=Math.max(1,Math.floor((j.clientX-K.left)/G.width)+1),V=Math.max(1,Math.floor((j.clientY-K.top)/G.height)+1),x=`\x1B[<${Q<0?64:65};${J};${V}M`;if(H&&H.readyState===WebSocket.OPEN)for(let F=0;F<P;F++)H.send(x);return!0});$.addEventListener("keydown",(j)=>{let G=j.key.toLowerCase(),Q=new Set([...j.shiftKey?["shift"]:[],...j.ctrlKey?["ctrl"]:[],...j.altKey?["alt"]:[],...j.metaKey?["meta"]:[]]),P=N.keyboardBindings.find((K)=>{if(K.key.toLowerCase()!==G)return!1;let J=new Set((Array.isArray(K.mods)?K.mods:[]).map((V)=>V.toLowerCase()));if(J.size!==Q.size)return!1;for(let V of J)if(!Q.has(V))return!1;return!0});if(!P)return;if(j.preventDefault(),j.stopPropagation(),P.chars&&H.readyState===WebSocket.OPEN)H.send(P.chars)},{capture:!0});z.onData((j)=>{if(H&&H.readyState===WebSocket.OPEN)H.send(j)});z.onResize(({cols:j,rows:G})=>{if(H&&H.readyState===WebSocket.OPEN)H.send(JSON.stringify({type:"resize",cols:j,rows:G}))});window.addEventListener("resize",()=>{_.fit()});if(N.copyOnSelect)z.onSelectionChange(()=>{let j=z.getSelection();if(!j)return;navigator.clipboard.writeText(j).catch(()=>{})});if(N.rightClickBehavior==="copyPaste")$.addEventListener("contextmenu",(j)=>{let G=z.getSelection();if(!G)return;j.preventDefault(),navigator.clipboard.writeText(G).catch(()=>{}),z.clearSelection()});$.addEventListener("paste",(j)=>{let G=j.clipboardData;if(!G)return;if(G.getData("text/plain"))return;if(j.preventDefault(),j.stopImmediatePropagation(),H&&H.readyState===WebSocket.OPEN)H.send("\x16")},{capture:!0});
1
+ import{FitAddon as k,init as F,Terminal as T}from"/dist/ghostty-web.js";var Y=new RegExp("\x1B\\[(\\d*) q","g");function L(j,H){let P=j.options.cursorStyle,Z=j.options.cursorBlink;Y.lastIndex=0;let Q=Y.exec(H);while(Q!==null){let N=Q[1]===""?0:Number(Q[1]);if(!Number.isNaN(N)&&N>=0&&N<=6)j.options.cursorStyle=N===0||N===1||N===2?"block":N===3||N===4?"underline":"bar",j.options.cursorBlink=N===0||N===1||N===3||N===5;Q=Y.exec(H)}if((j.options.cursorStyle!==P||j.options.cursorBlink!==Z)&&j.renderer&&j.wasmTerm)j.renderer.render(j.wasmTerm,!0,j.viewportY)}var G=window.location.pathname.split("/s/")[1]??"main",V=await fetch("/api/config").then((j)=>j.json());document.title=`${G} | webtty`;await F();var J=new T({cols:V.cols,rows:V.rows,cursorStyle:V.cursorStyle,cursorBlink:V.cursorStyleBlink,fontSize:V.fontSize,fontFamily:V.fontFamily,scrollback:Math.ceil(V.scrollback/80),theme:V.theme}),O=new k;J.loadAddon(O);var X=document.getElementById("terminal");if(V.theme?.background)X.style.background=V.theme.background;await J.open(X);function q(){X.style.padding="0",O.fit();let j=X.querySelector("canvas");if(!j)return;let H=Math.max(0,X.clientWidth-j.offsetWidth),P=Math.max(0,X.clientHeight-j.offsetHeight);X.style.paddingLeft=`${Math.floor(H/2)}px`,X.style.paddingRight=`${Math.ceil(H/2)}px`,X.style.paddingTop=`${Math.floor(P/2)}px`,X.style.paddingBottom=`${Math.ceil(P/2)}px`}q();new ResizeObserver(()=>q()).observe(X,{box:"border-box"});var C=window.location.protocol==="https:"?"wss:":"ws:",K;function y(){let j=`${C}//${window.location.host}/ws/${G}?cols=${J.cols}&rows=${J.rows}`;K=new WebSocket(j);let H="\x1B[2m",P="\x1B[1;33m",Z="\x1B[3m",Q="\x1B[0m",N=`${H}[${Q} ${P}webtty${Q} ${H}]${Q}`,_=($)=>`\r
2
+ ${N} ${H}${Z}${$}${Q}\r
3
+ `;K.onopen=()=>{K.send(JSON.stringify({type:"resize",cols:J.cols,rows:J.rows}))},K.onmessage=($)=>{L(J,$.data),J.write($.data)},K.onclose=($)=>{if($.code===4001){J.write(_("Session removed.")),setTimeout(()=>window.close(),500);return}if($.code===1001){J.write(_("Server stopped.")),setTimeout(()=>window.close(),500);return}J.write(_("Connection lost. Reconnecting in 2s...")),setTimeout(y,2000)},K.onerror=()=>{J.write(_("WebSocket error."))}}y();var W=0,M=0;J.attachCustomWheelEventHandler((j)=>{if(!J.hasMouseTracking())return!1;let H=J.renderer?.getMetrics();if(!H)return!1;let P=j.deltaY<0?-1:1;if(P!==M)W=0,M=P;W+=V.mouseScrollSpeed;let Z=Math.trunc(W);if(Z===0)return!0;W-=Z;let Q=j.target.getBoundingClientRect(),N=Math.max(1,Math.floor((j.clientX-Q.left)/H.width)+1),_=Math.max(1,Math.floor((j.clientY-Q.top)/H.height)+1),U=`\x1B[<${P<0?64:65};${N};${_}M`;if(K&&K.readyState===WebSocket.OPEN)for(let x=0;x<Z;x++)K.send(U);return!0});X.addEventListener("keydown",(j)=>{let H=j.key.toLowerCase(),P=new Set([...j.shiftKey?["shift"]:[],...j.ctrlKey?["ctrl"]:[],...j.altKey?["alt"]:[],...j.metaKey?["meta"]:[]]),Z=V.keyboardBindings.find((Q)=>{if(Q.key.toLowerCase()!==H)return!1;let N=new Set((Array.isArray(Q.mods)?Q.mods:[]).map((_)=>_.toLowerCase()));if(N.size!==P.size)return!1;for(let _ of N)if(!P.has(_))return!1;return!0});if(!Z)return;if(j.preventDefault(),j.stopPropagation(),Z.chars&&K.readyState===WebSocket.OPEN)K.send(Z.chars)},{capture:!0});var B=Math.min(32,Math.max(6,V.fontSize));window.addEventListener("keydown",(j)=>{if(!j.ctrlKey&&!j.metaKey)return;let H=j.code==="Equal"||j.code==="NumpadAdd",P=j.code==="Minus"&&!j.shiftKey||j.code==="NumpadSubtract",Z=j.code==="Digit0"&&!j.shiftKey||j.code==="Numpad0";if(!H&&!P&&!Z)return;if(j.preventDefault(),j.stopPropagation(),H)B=Math.min(32,B+1);else if(P)B=Math.max(6,B-1);else B=Math.min(32,Math.max(6,V.fontSize));J.options.fontSize=B,q()},{capture:!0});J.onData((j)=>{if(K&&K.readyState===WebSocket.OPEN)K.send(j)});J.onResize(({cols:j,rows:H})=>{if(K&&K.readyState===WebSocket.OPEN)K.send(JSON.stringify({type:"resize",cols:j,rows:H}))});if(V.copyOnSelect)J.onSelectionChange(()=>{let j=J.getSelection();if(!j)return;navigator.clipboard.writeText(j).catch(()=>{})});if(V.rightClickBehavior==="copyPaste")X.addEventListener("contextmenu",(j)=>{let H=J.getSelection();if(!H)return;j.preventDefault(),navigator.clipboard.writeText(H).catch(()=>{}),J.clearSelection()});X.addEventListener("paste",(j)=>{let H=j.clipboardData;if(!H)return;if(H.getData("text/plain"))return;if(j.preventDefault(),j.stopImmediatePropagation(),K&&K.readyState===WebSocket.OPEN)K.send("\x16")},{capture:!0});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webtty",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "Web TTY for running CLI/TUI applications in a browser tab, across platforms",
5
5
  "license": "MIT",
6
6
  "bin": {