From 60acd0089fdba03777e31dc05cad268271666423 Mon Sep 17 00:00:00 2001 From: Nicholas Bollweg Date: Sat, 10 Jul 2021 17:57:01 -0400 Subject: [PATCH] Expose Module.FS (#1692) --- Makefile | 5 +---- docs/project/changelog.md | 3 +++ src/js/api.js | 17 +++++++++++++++++ src/js/module.js | 5 +++++ src/js/package-lock.json | 6 ++++++ src/js/package.json | 11 ++++++++++- src/js/test/filesystem.test.js | 15 +++++++++++++++ src/js/tsconfig.json | 13 +++++++++++++ 8 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 src/js/test/filesystem.test.js create mode 100644 src/js/tsconfig.json diff --git a/Makefile b/Makefile index f9fa75e44..95a36c820 100644 --- a/Makefile +++ b/Makefile @@ -87,10 +87,7 @@ node_modules/.installed : src/js/package.json touch node_modules/.installed build/pyodide.js: src/js/*.js src/js/pyproxy.gen.js node_modules/.installed - npx typescript src/js/pyodide.js \ - --lib ES2018 --allowJs \ - --declaration --emitDeclarationOnly \ - --outDir build + npx typescript --project src/js npx rollup -c src/js/rollup.config.js src/js/pyproxy.gen.js : src/core/pyproxy.* src/core/*.h diff --git a/docs/project/changelog.md b/docs/project/changelog.md index 58eedf5b7..bf5239bda 100644 --- a/docs/project/changelog.md +++ b/docs/project/changelog.md @@ -47,6 +47,9 @@ substitutions: - {{ Enhancement }} Pyodide can experimentally be used in Node.js {pr}`1689` +- {{ Enhancement }} Pyodide now exposes the emscripten `FS` module as `fileSystem`, + allowing for direct manipulation of the in-memory filesystem {pr}`1692` + ## Standard library - The following standard library modules are now available as standalone packages diff --git a/src/js/api.js b/src/js/api.js index 0e7aad9f8..40f3c9cc5 100644 --- a/src/js/api.js +++ b/src/js/api.js @@ -7,6 +7,7 @@ export { loadPackage, loadedPackages, isPyProxy }; * @typedef {import('./pyproxy.gen').Py2JsResult} Py2JsResult * @typedef {import('./pyproxy.gen').PyProxy} PyProxy * @typedef {import('./pyproxy.gen').TypedArray} TypedArray + * @typedef {import('emscripten')} Emscripten */ /** @@ -329,8 +330,23 @@ setInterruptBuffer = Module.setInterruptBuffer; export { setInterruptBuffer }; export function makePublicAPI() { + /** + * An alias to the `Emscripten File System API + * `_. + * + * This provides a wide range of POSIX-`like` file/device operations, including + * `mount + * `_ + * which can be used to extend the in-memory filesystem with features like `persistence + * `_. + * + * @type {FS} The Emscripten File System API. + */ + const fileSystem = Module.FS; + let namespace = { globals, + fileSystem, pyodide_py, version, loadPackage, @@ -348,6 +364,7 @@ export function makePublicAPI() { PythonError, PyBuffer, }; + namespace._module = Module; // @private Module.public_api = namespace; return namespace; diff --git a/src/js/module.js b/src/js/module.js index f09d6e1e3..ad15e02ce 100644 --- a/src/js/module.js +++ b/src/js/module.js @@ -1,3 +1,8 @@ +/** + * The Emscripten Module. + * + * @private @type {import('emscripten').Module} + */ export let Module = {}; Module.noImageDecoding = true; Module.noAudioDecoding = true; diff --git a/src/js/package-lock.json b/src/js/package-lock.json index 29f8600a2..8c859656e 100644 --- a/src/js/package-lock.json +++ b/src/js/package-lock.json @@ -129,6 +129,12 @@ "defer-to-connect": "^1.0.1" } }, + "@types/emscripten": { + "version": "1.39.5", + "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.39.5.tgz", + "integrity": "sha512-DIOOg+POSrYl+OlNRHQuIEqCd8DCtynG57H862UCce16nXJX7J8eWxNGgOcf8Eyge8zXeSs27mz1UcFu8L/L7g==", + "dev": true + }, "@types/eslint": { "version": "7.2.14", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.14.tgz", diff --git a/src/js/package.json b/src/js/package.json index 1e4e3e73b..e37cac238 100644 --- a/src/js/package.json +++ b/src/js/package.json @@ -8,12 +8,21 @@ "rollup-plugin-terser": "^7.0.2", "tsd": "^0.15.1", "typescript": "^4.2.4", - "mocha": "^9.0.2" + "mocha": "^9.0.2", + "@types/emscripten": "^1.39.5" }, "type": "module", "scripts": { "test": "mocha --timeout 15000" }, + "tsd": { + "compilerOptions": { + "lib": [ + "ES2018", + "DOM" + ] + } + }, "dependencies": { "node-fetch": "^2.6.1" } diff --git a/src/js/test/filesystem.test.js b/src/js/test/filesystem.test.js new file mode 100644 index 000000000..68b60a42e --- /dev/null +++ b/src/js/test/filesystem.test.js @@ -0,0 +1,15 @@ +import assert from "assert"; +import { loadPyodide } from "../pyodide.js"; + +describe("fileSystem", () => { + let pyodide; + it("loadPyodide", async () => { + pyodide = await loadPyodide({ indexURL: "../../build/" }); + }); + const exists = () => { + return pyodide.runPython("import os; os.path.exists('/tmp/js-test')"); + }; + it("no dir", async () => assert.equal(exists(), false)); + it("mkdir", async () => pyodide.fileSystem.mkdir("/tmp/js-test")); + it("made dir", async () => assert.equal(exists(), true)); +}); diff --git a/src/js/tsconfig.json b/src/js/tsconfig.json new file mode 100644 index 000000000..9ada2a2bb --- /dev/null +++ b/src/js/tsconfig.json @@ -0,0 +1,13 @@ +{ + "$schema": "http://json.schemastore.org/tsconfig", + "compilerOptions": { + "allowJs": true, + "declaration": true, + "emitDeclarationOnly": true, + "lib": ["ES2018", "DOM"], + "outDir": "../../build", + "rootDir": "." + }, + "include": ["./*.js"], + "exclude": ["rollup.config.js"] +}