From 79de973830a80a1115e5f652afd5a9e39a5133ad Mon Sep 17 00:00:00 2001 From: Alessandro Pignotti Date: Wed, 9 Oct 2024 21:16:12 +0200 Subject: [PATCH] Cheerpx docs update review (#137) Co-authored-by: Ana Gabriela Reyna Co-authored-by: Hongge Cui <124056750+Honggeiry@users.noreply.github.com> --- .../docs/11-guides/File-System-support.md | 45 +++++++++++++++-- sites/cheerpx/src/content/docs/20-faq.md | 48 ++++++++++++------- 2 files changed, 70 insertions(+), 23 deletions(-) diff --git a/sites/cheerpx/src/content/docs/11-guides/File-System-support.md b/sites/cheerpx/src/content/docs/11-guides/File-System-support.md index 18a648f5..9f42266d 100644 --- a/sites/cheerpx/src/content/docs/11-guides/File-System-support.md +++ b/sites/cheerpx/src/content/docs/11-guides/File-System-support.md @@ -28,7 +28,7 @@ To create a WebDevice, use the `CheerpX.WebDevice.create()` method: const webDevice = await CheerpX.WebDevice.create("path/to/local/directory"); const cx = await CheerpX.Linux.create({ - mounts: [{ type: "dir", path: "/web", dev: webDevice }], + mounts: [ ... , { type: "dir", path: "/web", dev: webDevice }], }); ``` @@ -58,15 +58,50 @@ Create an IDBDevice using the `CheerpX.IDBDevice.create()` method: const idbDevice = await CheerpX.IDBDevice.create("dbName"); const cx = await CheerpX.Linux.create({ - mounts: [{ type: "dir", path: "/files", dev: idbDevice }], + mounts: [ ... , { type: "dir", path: "/files", dev: idbDevice }], }); ``` This setup creates a virtual filesystem at `/files` that is backed by IndexedDB. +### Reading Files from JavaScript + +You can read files from an `IDBDevice` in JavaScript using the `readFileAsBlob` method: + +```javascript +await idbDevice.readFileAsBlob("/filename"); +``` + +### `idbDevice.readFileAsBlob` + +`CheerpX.IDBDevice` provides a method to read back files as JavaScript accessible data. + +```js +await idbDevice.readFileAsBlob(filename: string): Promise +``` + +**Parameters**: + +- **filename**: A string representing the path to the file within the device, starting with a `/` (e.g., "/filename"). Do not include the mount point. + +**Returns**: + +The method returns a Promise that resolves to a standard JavaScript Blob object. + +Example: + +```js +const idbDevice = await CheerpX.IDBDevice.create("files"); +// Use CheerpX to write something to the device +const outputBlob = await dataDevice.readFileAsBlob("/filename"); +``` + +> [!note] Note +> The `readFileAsBlob` API returns a standard JavaScript Blob object. You can convert it to a string if needed, but you can also convert it to an `ArrayBuffer` or to a URL via `URL.createObjectURL`. + ## DataDevice -DataDevice is an in-memory filesystem useful for temporary data storage or passing data from JavaScript to the CheerpX environment. +`DataDevice` is an in-memory filesystem useful for temporary data storage or passing data from JavaScript to the CheerpX environment. ### Usage @@ -76,7 +111,7 @@ Create a DataDevice using the `CheerpX.DataDevice.create()` method: const dataDevice = await CheerpX.DataDevice.create(); const cx = await CheerpX.Linux.create({ - mounts: [{ type: "dir", path: "/temp", dev: dataDevice }], + mounts: [ ... , { type: "dir", path: "/data", dev: dataDevice }], }); ``` @@ -98,7 +133,7 @@ await dataDevice.writeFile(filename: string, contents: string | Uint8Array): Pro **Parameters**: -- **filename**: A string representing the absolute path to the file, starting with a `/` (e.g., "/filename"). +- **filename**: A string representing the path to the file within the device, starting with a `/` (e.g., "/filename"). Do not include the mount point. - **contents**: The data to write to the file. Can be either a string or a Uint8Array. **Returns**: diff --git a/sites/cheerpx/src/content/docs/20-faq.md b/sites/cheerpx/src/content/docs/20-faq.md index af432548..f061be95 100644 --- a/sites/cheerpx/src/content/docs/20-faq.md +++ b/sites/cheerpx/src/content/docs/20-faq.md @@ -10,30 +10,42 @@ Currently, CheerpX doesn't directly support capturing stdout from running progra You can redirect the output of a program to a file and then read that file from JavaScript. Here's how: -1. Run your program using `bash -c`, redirecting stdout to a file: +1. Make sure to mount an IDBDevice for a writable and JavaScript accessible file storage + +``` +const filesDevice = await CheerpX.IDBDevice.create("files"); +const cx = await CheerpX.Linux.create({ + mounts: [ + // This example assumes using `overlayDevice` as the root, please adapt accordingly to your needs + { type: "ext2", path: "/", dev: overlayDevice }, + { type: "dir", path: "/files", dev: filesDevice }, + ], + }); +``` + +2. Run your program using `bash -c`, redirecting stdout to a file: ```js -await cx.run(["bash", "-c", "your_executable > output.txt"]); +await cx.run("/bin/bash", [ + "-c", + "echo 'Output to capture' > /files/output.txt", +]); ``` -2. After the program finishes, read the contents of the file using JavaScript: +3. After the program finishes, read the contents of the file using JavaScript: ```javascript -const output = await cx.readFile("output.txt"); -console.log(output); +const outputBlob = await filesDevice.readFileAsBlob("/output.txt"); +console.log(await outputBlob.text()); ``` ### Limitation This method has a significant limitation: it doesn't provide streaming output. The entire program needs to finish execution before you can read the output file. This means you won't see real-time output, and for long-running programs, you'll have to wait until completion to see any results. -## Why can't CheerpX find files in my device? - -When using WebDevice, keep in mind: +## Why can't CheerpX find files in my `WebDevice` backend? -1. WebDevice uses absolute paths from the root of the mounted directory. -2. Do not include the first slash `/` of the path. -3. The path is relative to the root of the mounted WebDevice, not the current working directory. +We know from experience that the interaction between mount points and `WebDevice` can be confusing for some users. The best solution to identify why a file can't be found is to use the _**Network**_ tab to see the final URLs that CheerpX is trying to access. With this information you should be able to fix the incorrect paths. ### Debugging Path Issues @@ -45,13 +57,13 @@ Use browser's DevTools: 4. Look for 404 (Not Found) errors. 5. Check the full URL of these 404 requests to see the exact path CheerpX is trying to access. -## Why can't I execute files directly from a DataDevice? +## Can I use third-party origins with `WebDevice`? -DataDevice in CheerpX is write-only. This means you can write data to it, but you cannot execute files directly from it. To execute files that are in a DataDevice, you need to first copy the files to a writable filesystem, such as an IDB (IndexedDB) or ext2 filesystem. +Yes, `WebDevice` can handle third-party origins as paths, but it's important to consider the implications of Cross-Origin Resource Sharing (CORS) when doing so. To ensure smooth functioning, the server hosting these third-party resources must have the appropriate CORS headers configured. If the CORS settings are not properly arranged, browsers will block these requests, which will lead to files being inaccessible in CheerpX. -## Can I use third-party origins with WebDevice? +## Why can't I execute files directly from a `DataDevice`? -Yes, WebDevice can handle third-party origins as paths, but it's important to consider the implications of Cross-Origin Resource Sharing (CORS) when doing so. To ensure smooth functioning, the server hosting these third-party resources must have the appropriate CORS headers configured. If the CORS settings are not properly arranged, browsers might block these requests to third-party resources, which can lead to files being inaccessible in CheerpX. +`DataDevice` in CheerpX does not have full support for Linux mode bits, and in particular it lacks the _**executable**_ bit. This means you can write data to it, but you cannot execute files directly from it. To execute files that are in a DataDevice, you need to first copy the files to a filesystem with complete support for mode bits, such as IDB (IndexedDB) or Ext2. ## Why can't CheerpX do what v86 does in terms of disk access and networking? @@ -59,12 +71,12 @@ CheerpX's architecture and use case differ significantly from v86, which affects ### Disk Access -CheerpX is powered by an extremely sophisticated JIT engine, which allows it to support large disk images (up to 2GB at the time). This means we cannot simply download the entire disk image before starting execution, as v86 might do for smaller images. Instead, CheerpX uses a chunk-based, on-demand downloading system. +CheerpX is designed to support large scale applications and complete Operating Systems, to achieve those objectives to support large disk images (up to 2GB at the time). This means we cannot simply download the entire disk image before starting execution, as v86 might do for smaller images. Instead, CheerpX uses a chunk-based, on-demand downloading system. -We acknowledge that some users may experience slower disk access. Our team is actively investigating these issues and working on optimizations to enhance performance across all use cases. +Our cloud disk backend is based on WebSocket and distributed across a global CDN, which should provides low latency disk access to users everywhere in the world. We are aware that some users in mainland China might experience slower disk access at the moment due to local networking constraints. ### Networking -While v86 might use an open proxy to the internet, this approach is not feasible for CheerpX due to its scale of use. An open proxy can pose significant security risks when used at scale. +While v86 might use an open proxy to the internet, this approach is not feasible for CheerpX due to its scale of use. An open proxy can pose significant security and abuse risks when used at scale. Instead, CheerpX supports Tailscale-based networking, which can accommodate many use cases. It's important to note that developers using CheerpX are responsible for implementing appropriate security measures and preventing potential abuse.