|
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[] = []; |
|
|
|
|
|
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') { |
|
|
|
isInteractive = true; |
|
|
|
jshReady.resolve(); |
|
} |
|
} |
|
|
|
terminal.write(data); |
|
}, |
|
}), |
|
); |
|
|
|
terminal.onData((data) => { |
|
if (isInteractive) { |
|
input.write(data); |
|
} |
|
}); |
|
|
|
await jshReady.promise; |
|
|
|
return process; |
|
} |
|
|