Created
June 12, 2025 04:34
-
-
Save coder0107git/bc1a421ce88933ef67658d9787066fc6 to your computer and use it in GitHub Desktop.
A small wrapper for writing files to the java-writable portion of the CheerpJ filesystem.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://cjrtnc.leaningtech.com/3_20250514_1341/loader.js"></script> | |
<script type="module"> | |
import { fileOpen } from "https://cdn.jsdelivr.net/npm/[email protected]/+esm"; | |
class CheerpJFs { | |
// This probably should be static | |
#textEncoder = new TextEncoder(); | |
#java; | |
#lib; | |
constructor(cheerpjLib) { | |
const lib = cheerpjLib; | |
this.#lib = cheerpjLib; | |
this.#java = new Promise(async (resolve) => { | |
const Files = await lib.java.nio.file.Files; | |
const Paths = await lib.java.nio.file.Paths; | |
resolve({ Files, Paths }); | |
}); | |
} | |
// Handles errors that might be java errors | |
async #errorHandler(e) { | |
try { | |
const lib = this.#lib; | |
const JavaError = await lib.java.lang.Throwable; | |
if(e instanceof JavaError) { | |
return new Error(await e.toString()); | |
} | |
} catch (_) {} | |
if(e instanceof Error) { | |
return e; | |
} | |
return new Error(e); | |
} | |
/** | |
* @param {Object} options | |
* @param {string} options.path - The absolute path to the file. | |
* @param {string | Int8Array} options.contents - The contents of the file. | |
* @param {boolean} [options.ensureDirectoryExists=true] - If parent directories should be created if they don't exist before creating the file. | |
* | |
* @returns {string} | |
*/ | |
async writeFile(options = {}) { | |
// To avoid modification of an object we don't own. | |
options = Object.assign({}, options); | |
if(typeof options.path !== "string") { | |
throw new Error("File path is required"); | |
} | |
if(typeof options.contents === "string") { | |
options.contents = new Int8Array( | |
this.#textEncoder.encode(options.contents) | |
); | |
} | |
if(options.contents instanceof Int8Array !== true) { | |
throw new Error("File contents are required. Contents must be either a string or an Int8Array."); | |
} | |
const { | |
path, | |
contents: fileContents, | |
ensureDirectoryExists, | |
throwErrors, | |
} = { | |
ensureDirectoryExists: true, | |
throwErrors: true, | |
...options, | |
}; | |
try { | |
const { Files, Paths } = await this.#java; | |
const filePath = await Paths.get(path); | |
if(ensureDirectoryExists) { | |
const parentDir = await filePath.getParent(); | |
await Files.createDirectories(parentDir); | |
} | |
const fileStream = await Files.newOutputStream(filePath); | |
// Int8Array -> byte[] | |
await fileStream.write(fileContents); | |
// TODO: Is flushing needed? | |
await fileStream.flush(); | |
await fileStream.close(); | |
return true; | |
} catch(e) { | |
throw await this.#errorHandler(e); | |
} | |
} | |
} | |
console.log(-1) | |
await cheerpjInit({ | |
version: 11, | |
}); | |
console.log(0) | |
const lib = await cheerpjRunLibrary(""); | |
console.log(1) | |
try { | |
alert("Click on page a lot for 3 seconds"); | |
await new Promise(r => setTimeout(r, 2000)); | |
const file = await fileOpen([ | |
{ | |
description: "Any file", | |
id: "open-file", | |
}, | |
]); | |
const fileBuffer = await file.arrayBuffer(); | |
console.log(2); | |
const fs = new CheerpJFs(lib); | |
console.log(3); | |
await fs.writeFile({ | |
path: `/files/js/${file.name}`, | |
contents: new Int8Array(fileBuffer), | |
}); | |
console.log(4); | |
// Make sure the file exists | |
const fileBlob = await cjFileBlob(`/files/js/${file.name}`); | |
console.log(`Size: ${JSON.stringify(fileBlob.size)}, Type: ${JSON.stringify(fileBlob.type)}`) | |
} catch(e) { | |
debugger; | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment