bolt.diy/app/lib/stores/terminal.ts

54 lines
1.7 KiB
TypeScript
Raw Normal View History

import type { WebContainer, WebContainerProcess } from '@webcontainer/api';
import { atom, type WritableAtom } from 'nanostores';
import type { ITerminal } from '~/types/terminal';
2024-11-08 16:17:31 +00:00
import { newBoltShellProcess, newShellProcess } from '~/utils/shell';
import { coloredText } from '~/utils/terminal';
export class TerminalStore {
#webcontainer: Promise<WebContainer>;
#terminals: Array<{ terminal: ITerminal; process: WebContainerProcess }> = [];
2024-11-21 21:05:35 +00:00
#boltTerminal = newBoltShellProcess();
2024-11-08 16:17:31 +00:00
showTerminal: WritableAtom<boolean> = import.meta.hot?.data.showTerminal ?? atom(true);
constructor(webcontainerPromise: Promise<WebContainer>) {
this.#webcontainer = webcontainerPromise;
if (import.meta.hot) {
import.meta.hot.data.showTerminal = this.showTerminal;
}
}
2024-11-08 16:17:31 +00:00
get boltTerminal() {
return this.#boltTerminal;
}
toggleTerminal(value?: boolean) {
this.showTerminal.set(value !== undefined ? value : !this.showTerminal.get());
}
2024-11-08 16:17:31 +00:00
async attachBoltTerminal(terminal: ITerminal) {
try {
2024-11-21 21:05:35 +00:00
const wc = await this.#webcontainer;
await this.#boltTerminal.init(wc, terminal);
2024-11-08 16:17:31 +00:00
} catch (error: any) {
terminal.write(coloredText.red('Failed to spawn bolt shell\n\n') + error.message);
return;
}
}
async attachTerminal(terminal: ITerminal) {
try {
const shellProcess = await newShellProcess(await this.#webcontainer, terminal);
this.#terminals.push({ terminal, process: shellProcess });
} catch (error: any) {
terminal.write(coloredText.red('Failed to spawn shell\n\n') + error.message);
return;
}
}
onTerminalResize(cols: number, rows: number) {
for (const { process } of this.#terminals) {
process.resize({ cols, rows });
}
}
}