mirror of
https://github.com/stackblitz/bolt.new
synced 2024-11-27 14:32:46 +00:00
52 lines
1.2 KiB
TypeScript
52 lines
1.2 KiB
TypeScript
import type { WebContainer } from '@webcontainer/api';
|
|
import type { ITerminal } from '~/types/terminal';
|
|
import { withResolvers } from './promises';
|
|
|
|
export async function newShellProcess(webcontainer: WebContainer, terminal: ITerminal) {
|
|
const args: string[] = [];
|
|
|
|
// we spawn a JSH process with a fallback cols and rows in case the process is not attached yet to a visible terminal
|
|
const process = await webcontainer.spawn('/bin/jsh', ['--osc', ...args], {
|
|
terminal: {
|
|
cols: terminal.cols ?? 80,
|
|
rows: terminal.rows ?? 15,
|
|
},
|
|
});
|
|
|
|
const input = process.input.getWriter();
|
|
const output = process.output;
|
|
|
|
const jshReady = withResolvers<void>();
|
|
|
|
let isInteractive = false;
|
|
|
|
output.pipeTo(
|
|
new WritableStream({
|
|
write(data) {
|
|
if (!isInteractive) {
|
|
const [, osc] = data.match(/\x1b\]654;([^\x07]+)\x07/) || [];
|
|
|
|
if (osc === 'interactive') {
|
|
// wait until we see the interactive OSC
|
|
isInteractive = true;
|
|
|
|
jshReady.resolve();
|
|
}
|
|
}
|
|
|
|
terminal.write(data);
|
|
},
|
|
}),
|
|
);
|
|
|
|
terminal.onData((data) => {
|
|
if (isInteractive) {
|
|
input.write(data);
|
|
}
|
|
});
|
|
|
|
await jshReady.promise;
|
|
|
|
return process;
|
|
}
|