import { Terminal } from "@xterm/xterm"; import { FitAddon } from "@xterm/addon-fit"; class MyTerminalElement extends HTMLElement { #terminal; #fitAddon; #command = ""; static #prompt = "$>"; constructor() { super(); this.#terminal = new Terminal({ cursorBlink: true, }); this.#fitAddon = new FitAddon(); this.#terminal.loadAddon(this.#fitAddon); } connectedCallback() { this.#terminal.open(this); this.#fitAddon.fit(); this.#terminal.writeln("Hello from xterm.js"); this.#terminal.write(MyTerminalElement.#prompt); this.#terminal.onData(async data => { if (data === '\r') { await this.handleCommand(); this.#terminal.write("\r\n"); this.#terminal.write(MyTerminalElement.#prompt); this.#command = ""; } else { this.#terminal.write(data); this.#command += data; } }); } async handleCommand() { const [command, ...args] = this.#command.split(" "); if (command.length === 0) { return; } const response = await fetch(`/command/${command}`); this.#terminal.write("\r\n"); this.#terminal.write(await response.text()); } } customElements.define("my-terminal", MyTerminalElement);