From 0b0a8be022bb1e7d244f1b7b891986ed01af0ff4 Mon Sep 17 00:00:00 2001 From: Cheng Shao Date: Fri, 15 Nov 2024 00:11:15 +0000 Subject: [PATCH] frontend: add html/js logic of pandoc playground --- .github/workflows/build.yml | 6 ++- frontend/index.html | 92 +++++++++++++++++++++++++++++++++++++ frontend/index.js | 62 +++++++++++++++++++++++++ 3 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 frontend/index.html create mode 100644 frontend/index.js diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 312d20a..7668f58 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,6 +35,9 @@ jobs: ~/.ghc-wasm/add_to_github_path.sh popd + - name: checkout + uses: actions/checkout@v4 + - name: checkout uses: actions/checkout@v4 with: @@ -57,10 +60,11 @@ jobs: wasm32-wasi-cabal build pandoc-cli popd - - name: wasm-opt + - name: dist run: | mkdir dist wasm-opt --low-memory-unused --converge --gufa --flatten --rereloop -Oz $(find pandoc -type f -name pandoc.wasm) -o dist/pandoc.wasm + cp frontend/*.html frontend/*.js dist - name: test run: | diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000..d47461d --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,92 @@ + + + + + + pandoc-wasm playground + + + +
+ + +
+
+ +
+ + + diff --git a/frontend/index.js b/frontend/index.js new file mode 100644 index 0000000..4d7928a --- /dev/null +++ b/frontend/index.js @@ -0,0 +1,62 @@ +import { + WASI, + OpenFile, + File, + ConsoleStdout, +} from "https://cdn.jsdelivr.net/npm/@bjorn3/browser_wasi_shim@0.3.0/dist/index.js"; + +const mod = await WebAssembly.compileStreaming(fetch("./pandoc.wasm")); + +const instance_promise_pool_size = 8; + +const instance_promise_pool = []; + +function instance_promise_pool_fill() { + if (instance_promise_pool.length < instance_promise_pool_size) { + for ( + let i = instance_promise_pool.length; + i < instance_promise_pool_size; + ++i + ) { + const args = []; + const env = []; + const stdin_file = new File(new Uint8Array(), { readonly: true }); + const stdout_file = new File(new Uint8Array(), { readonly: false }); + const fds = [ + new OpenFile(stdin_file), + new OpenFile(stdout_file), + ConsoleStdout.lineBuffered((msg) => + console.warn(`[WASI stderr] ${msg}`) + ), + ]; + const options = { debug: false }; + const wasi = new WASI(args, env, fds, options); + instance_promise_pool.push( + WebAssembly.instantiate(mod, { + wasi_snapshot_preview1: wasi.wasiImport, + }).then((instance) => ({ instance, wasi, stdin_file, stdout_file })) + ); + } + } +} + +instance_promise_pool_fill(); + +const instances = (async function* () { + while (true) { + yield await instance_promise_pool.shift(); + instance_promise_pool_fill(); + } +})(); + +export async function run_pandoc(args, stdin_str) { + const { instance, wasi, stdin_file, stdout_file } = (await instances.next()) + .value; + wasi.args = ["pandoc.wasm", ...args]; + stdin_file.data = new TextEncoder().encode(stdin_str); + const ec = wasi.start(instance); + if (ec !== 0) { + throw new Error(`Non-zero exit code ${ec}`); + } + return new TextDecoder("utf-8", { fatal: true }).decode(stdout_file.data); +}