@@ -8,7 +8,7 @@ const { file } = Astro.props;
88---
99
1010<web-container name ={ file } >
11- <div data-content ><slot /></div >
11+ <pre data-content ><code >< slot /></code ></ pre >
1212 <Terminal />
1313</web-container>
1414
@@ -17,16 +17,23 @@ const { file } = Astro.props;
1717 import { WebContainer } from "@webcontainer/api";
1818 let host: WebContainer;
1919
20- host = await WebContainer.boot();
20+ host = await WebContainer.boot({ workdirName: 'demo' } );
2121 const snapshotResponse = await fetch(`/docs/snapshot`);
2222 const snapshot = await snapshotResponse.arrayBuffer();
2323 await host.mount(snapshot, { mountPoint: "/" });
2424
2525 customElements.define(
2626 "web-container",
2727 class extends HTMLElement {
28+ get dir() {
29+ return `${this.name}/`
30+ }
31+ get file() {
32+ return `${this.dir}index.js`;
33+ }
2834 get fileContent() {
29- return this.querySelector("[data-content]")!.textContent;
35+ const text = this.querySelector("[data-content]")!.textContent;
36+ return `import { intro, outro } from "@clack/prompts";console.clear();intro("\\x1b[46m\\x1b[30m ${this.name} \\x1b[0m");\n${text};process.on('exit', () => console.log('EOF'));`;
3037 }
3138 get name() {
3239 return this.getAttribute("name")!;
@@ -35,47 +42,52 @@ const { file } = Astro.props;
3542 return (this.querySelector("docs-terminal") as any)?.instance;
3643 }
3744 async connectedCallback() {
38- await host.fs.mkdir(`/examples/${ this.name}` , { recursive: true });
45+ await host.fs.mkdir(this.dir , { recursive: true });
3946 await host.fs.writeFile(
40- `/examples/${ this.name}/index.js` ,
47+ this.file ,
4148 this.fileContent,
4249 { encoding: "utf-8" }
4350 );
4451 await this.render();
4552 }
4653
4754 async render() {
48- const { terminal } = this;
55+ const { terminal, name, render } = this;
4956 terminal?.reset();
5057 const main = async () => {
51- const jshReady = Promise.withResolvers();
52- let process;
53- let isJSHReady = false;
54-
5558 // we set an infinite loop so that when the user runs the `exit` command, we restart
5659 while (true) {
57- process = await host.spawn("jsh", {
60+ const jsh = Promise.withResolvers();
61+ let isJSHReady = false;
62+ const process = await host.spawn("jsh", {
63+ cwd: name,
5864 terminal: { rows: terminal?.rows!, cols: terminal?.cols! },
5965 });
6066 process.output.pipeTo(
6167 new WritableStream({
6268 write(data) {
6369 if (data.includes("❯") && !isJSHReady) {
6470 isJSHReady = true;
65- jshReady.resolve(undefined);
71+ jsh.resolve(undefined);
72+ }
73+ if (data.includes("❯") || data.includes('~/demo')) {
74+ return;
75+ }
76+ if (data.includes("EOF")) {
77+ process.kill();
78+ render();
79+ return;
6680 }
6781 terminal?.write(data);
68- },
82+ }
6983 })
7084 );
71- const shellWriter = process.input.getWriter();
72- await jshReady.promise;
73- await shellWriter.write(
74- `cd examples/${this.name} && clear && node index.js\n`
75- );
85+ const shell = process.input.getWriter();
86+ await jsh.promise;
87+ await shell.write(`node index.js\n`);
7688 // write the terminal input to the process
7789 const terminalWriter = terminal?.onData((data) => {
78- shellWriter .write(data);
90+ shell .write(data);
7991 });
8092 // wait for the process to finish
8193 await process.exit;
0 commit comments