wasm-idle 0.7.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +760 -81
- package/dist/index.d.ts +4 -9
- package/dist/index.js +2 -4
- package/dist/playground/applicationAssets.d.ts +4 -0
- package/dist/playground/applicationAssets.js +277 -0
- package/dist/playground/assemblyscript.d.ts +41 -0
- package/dist/playground/assemblyscript.js +630 -0
- package/dist/playground/assetBridge.d.ts +18 -7
- package/dist/playground/assetBridge.js +824 -100
- package/dist/playground/assets.d.ts +813 -19
- package/dist/playground/assets.js +2096 -156
- package/dist/playground/awk.d.ts +5 -0
- package/dist/playground/awk.js +60 -0
- package/dist/playground/bash.d.ts +53 -0
- package/dist/playground/bash.js +1096 -0
- package/dist/playground/bashWorkerProtocol.d.ts +88 -0
- package/dist/playground/bashWorkerProtocol.js +135 -0
- package/dist/playground/bqn.d.ts +5 -0
- package/dist/playground/bqn.js +57 -0
- package/dist/playground/bqnPreflight.d.ts +26 -0
- package/dist/playground/bqnPreflight.js +399 -0
- package/dist/playground/c3.d.ts +15 -0
- package/dist/playground/c3.js +154 -0
- package/dist/playground/clang.d.ts +35 -19
- package/dist/playground/clang.js +241 -52
- package/dist/playground/clangAssetIntegrity.d.ts +32 -0
- package/dist/playground/clangAssetIntegrity.js +8 -0
- package/dist/playground/clojurescript.d.ts +5 -0
- package/dist/playground/clojurescript.js +59 -0
- package/dist/playground/clojurescriptPreflight.d.ts +26 -0
- package/dist/playground/clojurescriptPreflight.js +383 -0
- package/dist/playground/cobol.d.ts +46 -0
- package/dist/playground/cobol.js +703 -0
- package/dist/playground/d.d.ts +47 -0
- package/dist/playground/d.js +644 -0
- package/dist/playground/dOuterAssets.d.ts +16 -0
- package/dist/playground/dOuterAssets.js +163 -0
- package/dist/playground/dotnet.d.ts +99 -0
- package/dist/playground/dotnet.js +1131 -0
- package/dist/playground/duckdb.d.ts +36 -0
- package/dist/playground/duckdb.js +542 -0
- package/dist/playground/elixir.d.ts +18 -10
- package/dist/playground/elixir.js +630 -96
- package/dist/playground/elixirAssets.d.ts +6 -0
- package/dist/playground/elixirAssets.js +33 -0
- package/dist/playground/executionObservation.d.ts +22 -0
- package/dist/playground/executionObservation.js +65 -0
- package/dist/playground/forth.d.ts +5 -0
- package/dist/playground/forth.js +53 -0
- package/dist/playground/forthPreflight.d.ts +24 -0
- package/dist/playground/forthPreflight.js +198 -0
- package/dist/playground/fortran.d.ts +47 -0
- package/dist/playground/fortran.js +651 -0
- package/dist/playground/fortranAssets.d.ts +6 -0
- package/dist/playground/fortranAssets.js +27 -0
- package/dist/playground/gleam.d.ts +6 -0
- package/dist/playground/gleam.js +33 -0
- package/dist/playground/go.d.ts +17 -11
- package/dist/playground/go.js +376 -72
- package/dist/playground/goDebugInstrumentation.d.ts +1 -0
- package/dist/playground/goDebugInstrumentation.js +229 -0
- package/dist/playground/haskell.d.ts +44 -0
- package/dist/playground/haskell.js +678 -0
- package/dist/playground/haskellAssets.d.ts +24 -0
- package/dist/playground/haskellAssets.js +93 -0
- package/dist/playground/index.d.ts +1 -1
- package/dist/playground/index.js +360 -111
- package/dist/playground/j.d.ts +5 -0
- package/dist/playground/j.js +60 -0
- package/dist/playground/jPreflight.d.ts +26 -0
- package/dist/playground/jPreflight.js +372 -0
- package/dist/playground/janet.d.ts +5 -0
- package/dist/playground/janet.js +64 -0
- package/dist/playground/java.d.ts +24 -10
- package/dist/playground/java.js +706 -84
- package/dist/playground/javaSource.d.ts +5 -0
- package/dist/playground/javaSource.js +16 -0
- package/dist/playground/javaStdin.d.ts +1 -1
- package/dist/playground/javaStdin.js +13 -4
- package/dist/playground/julia.d.ts +5 -0
- package/dist/playground/julia.js +64 -0
- package/dist/playground/lfortran.d.ts +8 -0
- package/dist/playground/lfortran.js +30 -0
- package/dist/playground/lfortranAssets.d.ts +21 -0
- package/dist/playground/lfortranAssets.js +118 -0
- package/dist/playground/lisp.d.ts +45 -0
- package/dist/playground/lisp.js +640 -0
- package/dist/playground/lispAssets.d.ts +9 -0
- package/dist/playground/lispAssets.js +74 -0
- package/dist/playground/lldbManifest.d.ts +3 -0
- package/dist/playground/lldbManifest.js +155 -0
- package/dist/playground/lldbSession.d.ts +115 -0
- package/dist/playground/lldbSession.js +1347 -0
- package/dist/playground/loadingProgress.d.ts +16 -0
- package/dist/playground/loadingProgress.js +166 -0
- package/dist/playground/lua.d.ts +44 -0
- package/dist/playground/lua.js +630 -0
- package/dist/playground/nim.d.ts +5 -0
- package/dist/playground/nim.js +76 -0
- package/dist/playground/objectivec.d.ts +39 -0
- package/dist/playground/objectivec.js +288 -0
- package/dist/playground/ocaml.d.ts +28 -10
- package/dist/playground/ocaml.js +815 -253
- package/dist/playground/octave.d.ts +43 -0
- package/dist/playground/octave.js +783 -0
- package/dist/playground/options.d.ts +19 -40
- package/dist/playground/options.js +2 -1
- package/dist/playground/pascal.d.ts +5 -0
- package/dist/playground/pascal.js +60 -0
- package/dist/playground/perl.d.ts +5 -0
- package/dist/playground/perl.js +61 -0
- package/dist/playground/php.d.ts +44 -0
- package/dist/playground/php.js +665 -0
- package/dist/playground/prolog.d.ts +6 -0
- package/dist/playground/prolog.js +75 -0
- package/dist/playground/python.d.ts +20 -14
- package/dist/playground/python.js +445 -101
- package/dist/playground/pythonPackageLock.d.ts +6 -0
- package/dist/playground/pythonPackageLock.js +56 -0
- package/dist/playground/r.d.ts +44 -0
- package/dist/playground/r.js +637 -0
- package/dist/playground/ruby.d.ts +46 -0
- package/dist/playground/ruby.js +732 -0
- package/dist/playground/rubyAssets.d.ts +23 -0
- package/dist/playground/rubyAssets.js +68 -0
- package/dist/playground/rubyTestPreflight.d.ts +2 -0
- package/dist/playground/rubyTestPreflight.js +18 -0
- package/dist/playground/runtimeModule.d.ts +1 -0
- package/dist/playground/runtimeModule.js +5 -0
- package/dist/playground/rust.d.ts +44 -13
- package/dist/playground/rust.js +714 -76
- package/dist/playground/rustExecutableGraph.d.ts +85 -0
- package/dist/playground/rustExecutableGraph.js +946 -0
- package/dist/playground/rustWorkerLimits.d.ts +17 -0
- package/dist/playground/rustWorkerLimits.js +34 -0
- package/dist/playground/sandbox.d.ts +16 -10
- package/dist/playground/sharedBuffer.d.ts +6 -0
- package/dist/playground/sharedBuffer.js +12 -0
- package/dist/playground/sqlite.d.ts +38 -0
- package/dist/playground/sqlite.js +550 -0
- package/dist/playground/staticRuntimeModuleVersion.d.ts +1 -0
- package/dist/playground/staticRuntimeModuleVersion.js +2 -0
- package/dist/playground/staticRuntimePreflight.d.ts +13 -0
- package/dist/playground/staticRuntimePreflight.js +231 -0
- package/dist/playground/staticRuntimePreflightExecute.d.ts +8 -0
- package/dist/playground/staticRuntimePreflightExecute.js +66 -0
- package/dist/playground/staticRuntimePreflightProtocol.d.ts +68 -0
- package/dist/playground/staticRuntimePreflightProtocol.js +339 -0
- package/dist/playground/staticStdinRing.d.ts +45 -0
- package/dist/playground/staticStdinRing.js +158 -0
- package/dist/playground/staticWorkerRuntime.d.ts +154 -0
- package/dist/playground/staticWorkerRuntime.js +1917 -0
- package/dist/playground/stdinBuffer.d.ts +9 -7
- package/dist/playground/stdinBuffer.js +9 -18
- package/dist/playground/swift.d.ts +5 -0
- package/dist/playground/swift.js +17 -0
- package/dist/playground/tcl.d.ts +5 -0
- package/dist/playground/tcl.js +62 -0
- package/dist/playground/teavmConfig.d.ts +1 -1
- package/dist/playground/teavmConfig.js +2 -2
- package/dist/playground/tinygo.d.ts +48 -18
- package/dist/playground/tinygo.js +1202 -329
- package/dist/playground/tinygoExecutableGraph.d.ts +44 -0
- package/dist/playground/tinygoExecutableGraph.js +449 -0
- package/dist/playground/typescript.d.ts +55 -0
- package/dist/playground/typescript.js +924 -0
- package/dist/playground/wasm.d.ts +43 -0
- package/dist/playground/wasm.js +608 -0
- package/dist/playground/wasmAwkVersion.d.ts +59 -0
- package/dist/playground/wasmAwkVersion.js +31 -0
- package/dist/playground/wasmBashVersion.d.ts +63 -0
- package/dist/playground/wasmBashVersion.js +36 -0
- package/dist/playground/wasmBqnVersion.d.ts +24 -0
- package/dist/playground/wasmBqnVersion.js +24 -0
- package/dist/playground/wasmC3Version.d.ts +20 -0
- package/dist/playground/wasmC3Version.js +21 -0
- package/dist/playground/wasmClojureScriptVersion.d.ts +21 -0
- package/dist/playground/wasmClojureScriptVersion.js +21 -0
- package/dist/playground/wasmDIntegrity.d.ts +15 -0
- package/dist/playground/wasmDIntegrity.js +15 -0
- package/dist/playground/wasmDVersion.d.ts +1 -0
- package/dist/playground/wasmDVersion.js +1 -0
- package/dist/playground/wasmDebugVersion.d.ts +6 -0
- package/dist/playground/wasmDebugVersion.js +6 -0
- package/dist/playground/wasmDotnetVersion.d.ts +1 -0
- package/dist/playground/wasmDotnetVersion.js +1 -0
- package/dist/playground/wasmElixirVersion.d.ts +21 -1
- package/dist/playground/wasmElixirVersion.js +21 -1
- package/dist/playground/wasmForthVersion.d.ts +18 -0
- package/dist/playground/wasmForthVersion.js +18 -0
- package/dist/playground/wasmFortranExecutionAssets.d.ts +15 -0
- package/dist/playground/wasmFortranExecutionAssets.js +15 -0
- package/dist/playground/wasmFortranVersion.d.ts +1 -0
- package/dist/playground/wasmFortranVersion.js +1 -0
- package/dist/playground/wasmGleamVersion.d.ts +5 -0
- package/dist/playground/wasmGleamVersion.js +5 -0
- package/dist/playground/wasmGoVersion.d.ts +1 -1
- package/dist/playground/wasmGoVersion.js +1 -1
- package/dist/playground/wasmHaskellVersion.d.ts +1 -0
- package/dist/playground/wasmHaskellVersion.js +1 -0
- package/dist/playground/wasmJVersion.d.ts +24 -0
- package/dist/playground/wasmJVersion.js +24 -0
- package/dist/playground/wasmJanetVersion.d.ts +53 -0
- package/dist/playground/wasmJanetVersion.js +30 -0
- package/dist/playground/wasmJuliaVersion.d.ts +71 -0
- package/dist/playground/wasmJuliaVersion.js +39 -0
- package/dist/playground/wasmLfortranVersion.d.ts +28 -0
- package/dist/playground/wasmLfortranVersion.js +29 -0
- package/dist/playground/wasmLispVersion.d.ts +1 -0
- package/dist/playground/wasmLispVersion.js +1 -0
- package/dist/playground/wasmLuaVersion.d.ts +1 -0
- package/dist/playground/wasmLuaVersion.js +1 -0
- package/dist/playground/wasmNimVersion.d.ts +125 -0
- package/dist/playground/wasmNimVersion.js +66 -0
- package/dist/playground/wasmObjectiveCVersion.d.ts +27 -0
- package/dist/playground/wasmObjectiveCVersion.js +27 -0
- package/dist/playground/wasmOcamlVersion.d.ts +12 -1
- package/dist/playground/wasmOcamlVersion.js +12 -1
- package/dist/playground/wasmOctaveVersion.d.ts +1 -0
- package/dist/playground/wasmOctaveVersion.js +1 -0
- package/dist/playground/wasmPascalVersion.d.ts +61 -0
- package/dist/playground/wasmPascalVersion.js +34 -0
- package/dist/playground/wasmPerlVersion.d.ts +71 -0
- package/dist/playground/wasmPerlVersion.js +39 -0
- package/dist/playground/wasmPrologVersion.d.ts +31 -0
- package/dist/playground/wasmPrologVersion.js +31 -0
- package/dist/playground/wasmRVersion.d.ts +1 -0
- package/dist/playground/wasmRVersion.js +1 -0
- package/dist/playground/wasmRustVersion.d.ts +1306 -1
- package/dist/playground/wasmRustVersion.js +1458 -1
- package/dist/playground/wasmSwiftVersion.d.ts +1 -0
- package/dist/playground/wasmSwiftVersion.js +1 -0
- package/dist/playground/wasmTclVersion.d.ts +85 -0
- package/dist/playground/wasmTclVersion.js +46 -0
- package/dist/playground/wasmTinyGoVersion.d.ts +98 -1
- package/dist/playground/wasmTinyGoVersion.js +107 -1
- package/dist/playground/wasmTypeScriptVersion.d.ts +5 -0
- package/dist/playground/wasmTypeScriptVersion.js +5 -0
- package/dist/playground/wasmWatVersion.d.ts +1 -0
- package/dist/playground/wasmWatVersion.js +1 -0
- package/dist/playground/wasmZigVersion.d.ts +13 -0
- package/dist/playground/wasmZigVersion.js +13 -0
- package/dist/playground/wat.d.ts +44 -0
- package/dist/playground/wat.js +622 -0
- package/dist/playground/worker/assemblyscript.js +339 -0
- package/dist/playground/worker/assets.d.ts +7 -0
- package/dist/playground/worker/assets.js +288 -39
- package/dist/playground/worker/bash.js +338 -0
- package/dist/playground/worker/bashNestedBootstrap.d.ts +6 -0
- package/dist/playground/worker/bashNestedBootstrap.js +59 -0
- package/dist/playground/worker/bashRuntime.d.ts +89 -0
- package/dist/playground/worker/bashRuntime.js +982 -0
- package/dist/playground/worker/clang.js +92 -13
- package/dist/playground/worker/cobol.js +107 -0
- package/dist/playground/worker/d.js +199 -0
- package/dist/playground/worker/dotnet.js +141 -0
- package/dist/playground/worker/duckdb.d.ts +1 -0
- package/dist/playground/worker/duckdb.js +136 -0
- package/dist/playground/worker/elixir.js +307 -41
- package/dist/playground/worker/fortran.d.ts +1 -0
- package/dist/playground/worker/fortran.js +295 -0
- package/dist/playground/worker/go.js +246 -40
- package/dist/playground/worker/haskell.d.ts +7 -0
- package/dist/playground/worker/haskell.js +465 -0
- package/dist/playground/worker/java.js +59 -20
- package/dist/playground/worker/lisp.d.ts +1 -0
- package/dist/playground/worker/lisp.js +195 -0
- package/dist/playground/worker/lua.d.ts +1 -0
- package/dist/playground/worker/lua.js +163 -0
- package/dist/playground/worker/objectivec.d.ts +1 -0
- package/dist/playground/worker/objectivec.js +10 -0
- package/dist/playground/worker/ocaml.js +206 -58
- package/dist/playground/worker/php.d.ts +1 -0
- package/dist/playground/worker/php.js +261 -0
- package/dist/playground/worker/python.js +201 -44
- package/dist/playground/worker/r.d.ts +1 -0
- package/dist/playground/worker/r.js +192 -0
- package/dist/playground/worker/ruby.d.ts +1 -0
- package/dist/playground/worker/ruby.js +248 -0
- package/dist/playground/worker/runtimeAssetFetch.d.ts +15 -0
- package/dist/playground/worker/runtimeAssetFetch.js +375 -0
- package/dist/playground/worker/rust.js +546 -20
- package/dist/playground/worker/sqlite.d.ts +1 -0
- package/dist/playground/worker/sqlite.js +112 -0
- package/dist/playground/worker/staticRuntimePreflight.d.ts +1 -0
- package/dist/playground/worker/staticRuntimePreflight.js +56 -0
- package/dist/playground/worker/tinygo.js +34 -9
- package/dist/playground/worker/typescript.d.ts +1 -0
- package/dist/playground/worker/typescript.js +251 -0
- package/dist/playground/worker/wasm.d.ts +1 -0
- package/dist/playground/worker/wasm.js +273 -0
- package/dist/playground/worker/wat.d.ts +1 -0
- package/dist/playground/worker/wat.js +188 -0
- package/dist/playground/worker/zig.d.ts +8 -0
- package/dist/playground/worker/zig.js +578 -0
- package/dist/playground/workerProgress.d.ts +15 -0
- package/dist/playground/workerProgress.js +72 -0
- package/dist/playground/workerSession.d.ts +28 -0
- package/dist/playground/workerSession.js +164 -0
- package/dist/playground/zig.d.ts +46 -0
- package/dist/playground/zig.js +690 -0
- package/dist/playground/zigAssets.d.ts +6 -0
- package/dist/playground/zigAssets.js +49 -0
- package/package.json +234 -105
- package/dist/clang/app.d.ts +0 -75
- package/dist/clang/app.js +0 -744
- package/dist/clang/apply.d.ts +0 -2
- package/dist/clang/apply.js +0 -11
- package/dist/clang/color.d.ts +0 -3
- package/dist/clang/color.js +0 -3
- package/dist/clang/encode.d.ts +0 -4
- package/dist/clang/encode.js +0 -20
- package/dist/clang/error.d.ts +0 -14
- package/dist/clang/error.js +0 -27
- package/dist/clang/gccCompat.d.ts +0 -15
- package/dist/clang/gccCompat.js +0 -767
- package/dist/clang/index.d.ts +0 -85
- package/dist/clang/index.js +0 -1077
- package/dist/clang/memory/index.d.ts +0 -4
- package/dist/clang/memory/index.js +0 -4
- package/dist/clang/memory/memFs.d.ts +0 -35
- package/dist/clang/memory/memFs.js +0 -132
- package/dist/clang/memory/memory.d.ts +0 -22
- package/dist/clang/memory/memory.js +0 -73
- package/dist/clang/memory/tar.d.ts +0 -2
- package/dist/clang/memory/tar.js +0 -59
- package/dist/clang/url.d.ts +0 -4
- package/dist/clang/url.js +0 -5
- package/dist/clang/wasm.d.ts +0 -4
- package/dist/clang/wasm.js +0 -50
- package/dist/clangd/config.d.ts +0 -18
- package/dist/clangd/config.js +0 -14
- package/dist/clangd/jsonStream.d.ts +0 -9
- package/dist/clangd/jsonStream.js +0 -48
- package/dist/clangd/session.d.ts +0 -18
- package/dist/clangd/session.js +0 -112
- package/dist/clangd/worker.js +0 -131
- package/dist/debug/controller.svelte.d.ts +0 -43
- package/dist/debug/controller.svelte.js +0 -268
- package/dist/debug/editor/index.d.ts +0 -2
- package/dist/debug/editor/index.js +0 -1
- package/dist/debug/editor/monaco.d.ts +0 -26
- package/dist/debug/editor/monaco.js +0 -128
- package/dist/debug/expression.d.ts +0 -26
- package/dist/debug/expression.js +0 -547
- package/dist/debug/index.d.ts +0 -8
- package/dist/debug/index.js +0 -5
- package/dist/debug/language/cpp.d.ts +0 -2
- package/dist/debug/language/cpp.js +0 -7
- package/dist/debug/language/index.d.ts +0 -3
- package/dist/debug/language/index.js +0 -2
- package/dist/debug/language/python.d.ts +0 -2
- package/dist/debug/language/python.js +0 -14
- package/dist/debug/language/types.d.ts +0 -6
- package/dist/debug/locals.d.ts +0 -2
- package/dist/debug/locals.js +0 -8
- package/dist/lsp/cpp/server.d.ts +0 -2
- package/dist/lsp/cpp/server.js +0 -68
- package/dist/lsp/index.d.ts +0 -5
- package/dist/lsp/index.js +0 -4
- package/dist/lsp/python/main.worker.js +0 -92
- package/dist/lsp/python/package/arcturus_python_lsp/__init__.py +0 -3
- package/dist/lsp/python/package/arcturus_python_lsp/server.py +0 -462
- package/dist/lsp/python/server.d.ts +0 -2
- package/dist/lsp/python/server.js +0 -54
- package/dist/lsp/registry.d.ts +0 -2
- package/dist/lsp/registry.js +0 -12
- package/dist/lsp/runtime.d.ts +0 -5
- package/dist/lsp/runtime.js +0 -31
- package/dist/lsp/types.d.ts +0 -17
- package/dist/terminal/Terminal.svelte +0 -422
- package/dist/terminal/Terminal.svelte.d.ts +0 -26
- package/dist/terminal/index.d.ts +0 -7
- package/dist/terminal/index.js +0 -5
- package/dist/terminal/plugin/index.d.ts +0 -9
- package/dist/terminal/plugin/index.js +0 -19
- package/dist/terminal/theme.d.ts +0 -49
- package/dist/terminal/theme.js +0 -49
- package/dist/terminal/types.d.ts +0 -18
- package/dist/utils/vscodeJsonrpcBrowser.d.ts +0 -5
- package/dist/utils/vscodeJsonrpcBrowser.js +0 -4
- /package/dist/{clangd/worker.d.ts → playground/worker/assemblyscript.d.ts} +0 -0
- /package/dist/{debug/language/types.js → playground/worker/bash.d.ts} +0 -0
- /package/dist/{lsp/python/main.worker.d.ts → playground/worker/cobol.d.ts} +0 -0
- /package/dist/{lsp/types.js → playground/worker/d.d.ts} +0 -0
- /package/dist/{terminal/types.js → playground/worker/dotnet.d.ts} +0 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { importRuntimeModule } from '../runtimeModule';
|
|
2
|
+
const encoder = new TextEncoder();
|
|
3
|
+
let dbPromise = null;
|
|
4
|
+
let runtimeModuleUrl = '';
|
|
5
|
+
async function loadDuckDB(moduleUrl, log) {
|
|
6
|
+
if (!moduleUrl)
|
|
7
|
+
throw new Error('DuckDB runtime module URL is not configured.');
|
|
8
|
+
if (runtimeModuleUrl !== moduleUrl) {
|
|
9
|
+
runtimeModuleUrl = moduleUrl;
|
|
10
|
+
dbPromise = null;
|
|
11
|
+
}
|
|
12
|
+
if (dbPromise)
|
|
13
|
+
return await dbPromise;
|
|
14
|
+
dbPromise = (async () => {
|
|
15
|
+
const { duckdb, bundles } = await importRuntimeModule(moduleUrl);
|
|
16
|
+
const bundle = await duckdb.selectBundle(bundles);
|
|
17
|
+
if (!bundle.mainWorker) {
|
|
18
|
+
throw new Error('DuckDB selected bundle does not include a browser worker');
|
|
19
|
+
}
|
|
20
|
+
const worker = new Worker(bundle.mainWorker);
|
|
21
|
+
const db = new duckdb.AsyncDuckDB(log ? new duckdb.ConsoleLogger() : new duckdb.VoidLogger(), worker);
|
|
22
|
+
await db.instantiate(bundle.mainModule, bundle.pthreadWorker);
|
|
23
|
+
return db;
|
|
24
|
+
})();
|
|
25
|
+
return await dbPromise;
|
|
26
|
+
}
|
|
27
|
+
function stringifyCell(value) {
|
|
28
|
+
if (value == null)
|
|
29
|
+
return 'NULL';
|
|
30
|
+
if (value instanceof Uint8Array) {
|
|
31
|
+
return `x'${Array.from(value, (byte) => byte.toString(16).padStart(2, '0')).join('')}'`;
|
|
32
|
+
}
|
|
33
|
+
if (typeof value === 'bigint')
|
|
34
|
+
return value.toString();
|
|
35
|
+
return String(value);
|
|
36
|
+
}
|
|
37
|
+
function formatTable(table) {
|
|
38
|
+
if (!table.numCols)
|
|
39
|
+
return '';
|
|
40
|
+
const columns = table.schema.fields.map((field) => field.name);
|
|
41
|
+
const lines = [columns.join('\t')];
|
|
42
|
+
for (let rowIndex = 0; rowIndex < table.numRows; rowIndex += 1) {
|
|
43
|
+
const row = table.get(rowIndex);
|
|
44
|
+
lines.push(columns.map((column) => stringifyCell(row?.[column])).join('\t'));
|
|
45
|
+
}
|
|
46
|
+
return `${lines.join('\n')}\n`;
|
|
47
|
+
}
|
|
48
|
+
function normalizeWorkspacePath(path) {
|
|
49
|
+
return path
|
|
50
|
+
.replace(/^\/+/, '')
|
|
51
|
+
.split('/')
|
|
52
|
+
.filter((part) => part && part !== '.' && part !== '..' && !part.includes('\0'))
|
|
53
|
+
.join('/');
|
|
54
|
+
}
|
|
55
|
+
function isSqlPath(path) {
|
|
56
|
+
const normalized = path.toLowerCase();
|
|
57
|
+
return normalized.endsWith('.sql') || normalized.endsWith('.duckdb');
|
|
58
|
+
}
|
|
59
|
+
async function registerWorkspaceFiles(db, activePath, code, workspaceFiles, stdin) {
|
|
60
|
+
const setupSql = [];
|
|
61
|
+
const files = workspaceFiles.length
|
|
62
|
+
? workspaceFiles
|
|
63
|
+
: [{ path: activePath || 'main.duckdb', content: code }];
|
|
64
|
+
for (const file of files) {
|
|
65
|
+
if (!file || typeof file.path !== 'string' || typeof file.content !== 'string')
|
|
66
|
+
continue;
|
|
67
|
+
const normalizedPath = normalizeWorkspacePath(file.path);
|
|
68
|
+
if (!normalizedPath)
|
|
69
|
+
continue;
|
|
70
|
+
const content = normalizedPath === activePath ? code : file.content;
|
|
71
|
+
await db.registerFileText(normalizedPath, content);
|
|
72
|
+
if (isSqlPath(normalizedPath) && normalizedPath !== activePath) {
|
|
73
|
+
setupSql.push({ path: normalizedPath, content });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (typeof stdin === 'string') {
|
|
77
|
+
await db.registerFileText('stdin.txt', stdin);
|
|
78
|
+
await db.registerFileBuffer('/dev/stdin', encoder.encode(stdin));
|
|
79
|
+
}
|
|
80
|
+
return setupSql.sort((left, right) => left.path.localeCompare(right.path));
|
|
81
|
+
}
|
|
82
|
+
self.onmessage = async (event) => {
|
|
83
|
+
const { load, moduleUrl: nextModuleUrl, code, prepare, activePath = 'main.duckdb', workspaceFiles = [], stdin, log } = event.data;
|
|
84
|
+
try {
|
|
85
|
+
if (load) {
|
|
86
|
+
if (log) {
|
|
87
|
+
console.log('[wasm-idle:duckdb-worker] load');
|
|
88
|
+
}
|
|
89
|
+
await loadDuckDB(nextModuleUrl || runtimeModuleUrl, Boolean(log));
|
|
90
|
+
postMessage({ load: true });
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const db = await loadDuckDB(runtimeModuleUrl, Boolean(log));
|
|
94
|
+
if (prepare) {
|
|
95
|
+
postMessage({ results: true });
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
await db.reset();
|
|
99
|
+
const normalizedActivePath = normalizeWorkspacePath(activePath || 'main.duckdb');
|
|
100
|
+
const setupSql = await registerWorkspaceFiles(db, normalizedActivePath, code, workspaceFiles, stdin);
|
|
101
|
+
const connection = await db.connect();
|
|
102
|
+
try {
|
|
103
|
+
if (log) {
|
|
104
|
+
console.log(`[wasm-idle:duckdb-worker] exec start bytes=${code.length} activePath=${normalizedActivePath}`);
|
|
105
|
+
}
|
|
106
|
+
for (const setup of setupSql) {
|
|
107
|
+
await connection.query(setup.content);
|
|
108
|
+
}
|
|
109
|
+
postMessage({
|
|
110
|
+
progress: {
|
|
111
|
+
kind: 'ready',
|
|
112
|
+
state: 'running',
|
|
113
|
+
reason: 'started',
|
|
114
|
+
label: 'DuckDB query started'
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
const table = await connection.query(code);
|
|
118
|
+
const output = formatTable(table);
|
|
119
|
+
if (output)
|
|
120
|
+
postMessage({ output });
|
|
121
|
+
if (log) {
|
|
122
|
+
console.log('[wasm-idle:duckdb-worker] exec settled');
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
finally {
|
|
126
|
+
await connection.close().catch(() => { });
|
|
127
|
+
}
|
|
128
|
+
postMessage({ results: true });
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
if (log) {
|
|
132
|
+
console.error('[wasm-idle:duckdb-worker] failed', error);
|
|
133
|
+
}
|
|
134
|
+
postMessage({ error: error?.message || String(error) });
|
|
135
|
+
}
|
|
136
|
+
};
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { waitForBufferedStdin } from '../stdinBuffer';
|
|
2
|
+
import { ELIXIR_RUNTIME_ASSET_NAMES, snapshotElixirRuntimeAssetReceipts } from '../elixirAssets';
|
|
3
|
+
import { fetchRuntimeAssetBytes } from './runtimeAssetFetch';
|
|
4
|
+
import { verifyRuntimeAssetIntegrity } from '@wasm-idle/core';
|
|
2
5
|
const workerDocument = {
|
|
3
6
|
querySelectorAll() {
|
|
4
7
|
return [];
|
|
@@ -13,6 +16,7 @@ const workerHost = {
|
|
|
13
16
|
const popcornBrowserGlobal = ['globalThis', 'window'].join('.');
|
|
14
17
|
const popcornParentGlobal = [popcornBrowserGlobal, 'parent'].join('.');
|
|
15
18
|
const workerHostGlobal = 'globalThis.__wasmIdleElixirWorkerHost';
|
|
19
|
+
const MAX_ELIXIR_ASSET_BYTES = 128 * 1024 * 1024;
|
|
16
20
|
self.document = workerDocument;
|
|
17
21
|
globalThis.__wasmIdleElixirWorkerHost = workerHost;
|
|
18
22
|
class TrackedValue {
|
|
@@ -28,7 +32,9 @@ class TrackedValue {
|
|
|
28
32
|
}
|
|
29
33
|
globalThis.TrackedValue = TrackedValue;
|
|
30
34
|
let bundleUrl = '';
|
|
31
|
-
let
|
|
35
|
+
let bundleReceipts = null;
|
|
36
|
+
let bundleMaxAssetBytes = MAX_ELIXIR_ASSET_BYTES;
|
|
37
|
+
let loadedRuntimeIdentity = '';
|
|
32
38
|
let runtimePromise = null;
|
|
33
39
|
let stdinBufferElixir = null;
|
|
34
40
|
const elixirStdinCallNames = [
|
|
@@ -39,17 +45,39 @@ const elixirStdinCallNames = [
|
|
|
39
45
|
':io.get_line',
|
|
40
46
|
':io.get_chars'
|
|
41
47
|
];
|
|
48
|
+
const erlangStdinCallNames = ['io:get_line', 'io:get_chars'];
|
|
42
49
|
function resolveElixirRuntimeAssetUrl(assetName, bundleAssetUrl) {
|
|
43
50
|
const absoluteBundleUrl = new URL(bundleAssetUrl.startsWith('/') ? `http://localhost${bundleAssetUrl}` : bundleAssetUrl, globalThis.location?.href || 'http://localhost/');
|
|
44
|
-
|
|
51
|
+
const assetUrl = new URL(assetName, absoluteBundleUrl);
|
|
52
|
+
assetUrl.search = absoluteBundleUrl.search;
|
|
53
|
+
return assetUrl.toString();
|
|
45
54
|
}
|
|
46
|
-
|
|
55
|
+
function createAtomVmModuleBlob(moduleBytes) {
|
|
56
|
+
const copy = new Uint8Array(moduleBytes.byteLength);
|
|
57
|
+
copy.set(moduleBytes);
|
|
58
|
+
return new Blob([copy.buffer], { type: 'text/javascript' });
|
|
59
|
+
}
|
|
60
|
+
async function resolveAtomVmInitializer(moduleBytes) {
|
|
47
61
|
const injectedInitializer = globalThis.__wasmIdleAtomVmInit;
|
|
48
62
|
if (typeof injectedInitializer === 'function') {
|
|
49
63
|
return injectedInitializer;
|
|
50
64
|
}
|
|
51
|
-
|
|
52
|
-
|
|
65
|
+
if (typeof URL.createObjectURL !== 'function' || typeof URL.revokeObjectURL !== 'function') {
|
|
66
|
+
throw new Error('Elixir runtime requires Blob URL support');
|
|
67
|
+
}
|
|
68
|
+
const moduleUrl = URL.createObjectURL(createAtomVmModuleBlob(moduleBytes));
|
|
69
|
+
try {
|
|
70
|
+
const module = (await import(/* @vite-ignore */ moduleUrl));
|
|
71
|
+
return module.default;
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
try {
|
|
75
|
+
URL.revokeObjectURL(moduleUrl);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// Blob URL cleanup must not replace the verified module import outcome.
|
|
79
|
+
}
|
|
80
|
+
}
|
|
53
81
|
}
|
|
54
82
|
function skipQuotedLiteral(source, start) {
|
|
55
83
|
const heredoc = source.slice(start, start + 3);
|
|
@@ -268,7 +296,7 @@ function configureMessagingBridge(module) {
|
|
|
268
296
|
};
|
|
269
297
|
module.call = (process, args) => originalCall(process, module.serialize(args));
|
|
270
298
|
}
|
|
271
|
-
async function startVm(
|
|
299
|
+
async function startVm(assets, bundleAssetUrl, log) {
|
|
272
300
|
let resolveProcess = null;
|
|
273
301
|
const processPromise = new Promise((resolve, reject) => {
|
|
274
302
|
const timeout = setTimeout(() => {
|
|
@@ -281,10 +309,11 @@ async function startVm(avmBundle, bundleAssetUrl, log) {
|
|
|
281
309
|
resolve(process);
|
|
282
310
|
};
|
|
283
311
|
});
|
|
284
|
-
const atomVmModuleUrl = resolveElixirRuntimeAssetUrl('AtomVM.mjs', bundleAssetUrl);
|
|
285
312
|
const atomVmWasmUrl = resolveElixirRuntimeAssetUrl('AtomVM.wasm', bundleAssetUrl);
|
|
286
|
-
const initAtomVm = await resolveAtomVmInitializer(
|
|
313
|
+
const initAtomVm = await resolveAtomVmInitializer(assets['AtomVM.mjs']);
|
|
287
314
|
const module = (await initAtomVm({
|
|
315
|
+
mainScriptUrlOrBlob: createAtomVmModuleBlob(assets['AtomVM.mjs']),
|
|
316
|
+
wasmBinary: assets['AtomVM.wasm'],
|
|
288
317
|
locateFile(path) {
|
|
289
318
|
if (path === 'AtomVM.wasm') {
|
|
290
319
|
return atomVmWasmUrl;
|
|
@@ -294,7 +323,7 @@ async function startVm(avmBundle, bundleAssetUrl, log) {
|
|
|
294
323
|
preRun: [
|
|
295
324
|
({ FS }) => {
|
|
296
325
|
FS.mkdir('/data');
|
|
297
|
-
FS.writeFile('/data/bundle.avm',
|
|
326
|
+
FS.writeFile('/data/bundle.avm', new Int8Array(assets['bundle.avm']));
|
|
298
327
|
}
|
|
299
328
|
],
|
|
300
329
|
arguments: ['/data/bundle.avm'],
|
|
@@ -318,32 +347,93 @@ async function startVm(avmBundle, bundleAssetUrl, log) {
|
|
|
318
347
|
process: await processPromise
|
|
319
348
|
};
|
|
320
349
|
}
|
|
321
|
-
async function loadRuntime(nextBundleUrl, log) {
|
|
322
|
-
if (!nextBundleUrl) {
|
|
350
|
+
async function loadRuntime(nextBundleUrl, nextAssetReceipts, nextMaxAssetBytes, log) {
|
|
351
|
+
if (typeof nextBundleUrl !== 'string' || !nextBundleUrl.trim()) {
|
|
323
352
|
throw new Error('Elixir runtime is not configured. Set PUBLIC_WASM_ELIXIR_BUNDLE_URL or runtimeAssets.elixir.bundleUrl.');
|
|
324
353
|
}
|
|
325
|
-
|
|
326
|
-
|
|
354
|
+
let requestUrl;
|
|
355
|
+
try {
|
|
356
|
+
const locationOrigin = globalThis.location?.origin;
|
|
357
|
+
const locationHref = globalThis.location?.href;
|
|
358
|
+
const baseUrl = locationOrigin && locationOrigin !== 'null'
|
|
359
|
+
? `${locationOrigin}/`
|
|
360
|
+
: locationHref?.startsWith('blob:')
|
|
361
|
+
? locationHref.slice('blob:'.length)
|
|
362
|
+
: locationHref || 'http://localhost/';
|
|
363
|
+
requestUrl = new URL(nextBundleUrl.trim(), baseUrl);
|
|
327
364
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
365
|
+
catch {
|
|
366
|
+
throw new Error(`Elixir bundle URL is invalid: ${nextBundleUrl}`);
|
|
367
|
+
}
|
|
368
|
+
if (requestUrl.protocol !== 'http:' && requestUrl.protocol !== 'https:') {
|
|
369
|
+
throw new Error(`Elixir bundle URL must use HTTP(S): ${nextBundleUrl}`);
|
|
370
|
+
}
|
|
371
|
+
if (requestUrl.username || requestUrl.password) {
|
|
372
|
+
throw new Error(`Elixir bundle URL must not include credentials: ${nextBundleUrl}`);
|
|
373
|
+
}
|
|
374
|
+
if (requestUrl.hash) {
|
|
375
|
+
throw new Error(`Elixir bundle URL must not include a fragment: ${nextBundleUrl}`);
|
|
376
|
+
}
|
|
377
|
+
const configuredMaxAssetBytes = nextMaxAssetBytes ?? MAX_ELIXIR_ASSET_BYTES;
|
|
378
|
+
if (!Number.isSafeInteger(configuredMaxAssetBytes) || configuredMaxAssetBytes <= 0) {
|
|
379
|
+
throw new TypeError('Elixir runtime maxAssetBytes must be a positive safe integer');
|
|
380
|
+
}
|
|
381
|
+
const effectiveMaxAssetBytes = Math.min(MAX_ELIXIR_ASSET_BYTES, configuredMaxAssetBytes);
|
|
382
|
+
const receipts = snapshotElixirRuntimeAssetReceipts(nextAssetReceipts);
|
|
383
|
+
for (const asset of ELIXIR_RUNTIME_ASSET_NAMES) {
|
|
384
|
+
const actual = Math.max(receipts[asset].bytes, receipts[asset].uncompressedBytes);
|
|
385
|
+
if (actual > effectiveMaxAssetBytes) {
|
|
386
|
+
throw new Error(`Elixir runtime asset ${asset} exceeds the ${effectiveMaxAssetBytes} byte limit`);
|
|
332
387
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
388
|
+
}
|
|
389
|
+
const identity = JSON.stringify([requestUrl.href, receipts, configuredMaxAssetBytes]);
|
|
390
|
+
if (loadedRuntimeIdentity === identity && runtimePromise) {
|
|
391
|
+
return await runtimePromise;
|
|
392
|
+
}
|
|
393
|
+
if (log) {
|
|
394
|
+
console.log(`[wasm-idle:elixir-worker] load bundleUrl=${requestUrl.href}`);
|
|
395
|
+
}
|
|
396
|
+
const candidate = (async () => {
|
|
397
|
+
const loadedAssets = [];
|
|
398
|
+
for (const asset of ELIXIR_RUNTIME_ASSET_NAMES) {
|
|
399
|
+
const assetUrl = asset === 'bundle.avm'
|
|
400
|
+
? requestUrl.href
|
|
401
|
+
: resolveElixirRuntimeAssetUrl(asset, requestUrl.href);
|
|
402
|
+
const receipt = receipts[asset];
|
|
403
|
+
const bytes = await fetchRuntimeAssetBytes({
|
|
404
|
+
url: assetUrl,
|
|
405
|
+
label: `Elixir runtime asset ${asset}`,
|
|
406
|
+
maxAssetBytes: Math.min(receipt.uncompressedBytes, effectiveMaxAssetBytes)
|
|
407
|
+
});
|
|
408
|
+
await verifyRuntimeAssetIntegrity({
|
|
409
|
+
asset,
|
|
410
|
+
bytes,
|
|
411
|
+
expected: receipt,
|
|
412
|
+
stage: 'uncompressed',
|
|
413
|
+
runtimeId: 'ELIXIR'
|
|
414
|
+
});
|
|
415
|
+
loadedAssets.push([asset, bytes]);
|
|
416
|
+
}
|
|
417
|
+
const assets = Object.freeze(Object.fromEntries(loadedAssets));
|
|
418
|
+
return await startVm(assets, requestUrl.href, log);
|
|
340
419
|
})();
|
|
341
|
-
|
|
420
|
+
loadedRuntimeIdentity = identity;
|
|
421
|
+
runtimePromise = candidate;
|
|
422
|
+
try {
|
|
423
|
+
return await candidate;
|
|
424
|
+
}
|
|
425
|
+
catch (error) {
|
|
426
|
+
if (runtimePromise === candidate) {
|
|
427
|
+
runtimePromise = null;
|
|
428
|
+
loadedRuntimeIdentity = '';
|
|
429
|
+
}
|
|
430
|
+
throw error;
|
|
431
|
+
}
|
|
342
432
|
}
|
|
343
433
|
function normalizeCallError(module, error) {
|
|
344
434
|
if (error === 'noproc') {
|
|
345
435
|
runtimePromise = null;
|
|
346
|
-
|
|
436
|
+
loadedRuntimeIdentity = '';
|
|
347
437
|
return 'Elixir runtime process is unavailable';
|
|
348
438
|
}
|
|
349
439
|
if (typeof error === 'string') {
|
|
@@ -365,16 +455,30 @@ function normalizeCallError(module, error) {
|
|
|
365
455
|
return String(error);
|
|
366
456
|
}
|
|
367
457
|
}
|
|
458
|
+
function postExecutionReady(label) {
|
|
459
|
+
postMessage({
|
|
460
|
+
progress: { kind: 'ready', state: 'running', reason: 'started', label }
|
|
461
|
+
});
|
|
462
|
+
}
|
|
368
463
|
self.onmessage = async (event) => {
|
|
369
|
-
const { load, bundleUrl: nextBundleUrl, buffer, code, prepare, log = true } = event.data;
|
|
464
|
+
const { load, bundleUrl: nextBundleUrl, assetReceipts: nextAssetReceipts, maxAssetBytes: nextMaxAssetBytes, buffer, code, diagnose = false, prepare, stdin, language = 'ELIXIR', log = true } = event.data;
|
|
465
|
+
const evalLanguage = language === 'ERLANG' ? 'ERLANG' : 'ELIXIR';
|
|
370
466
|
try {
|
|
371
467
|
if (load) {
|
|
468
|
+
await loadRuntime(nextBundleUrl, nextAssetReceipts, nextMaxAssetBytes, log);
|
|
469
|
+
const configuredReceipts = snapshotElixirRuntimeAssetReceipts(nextAssetReceipts);
|
|
372
470
|
bundleUrl = nextBundleUrl;
|
|
373
|
-
|
|
471
|
+
bundleReceipts = configuredReceipts;
|
|
472
|
+
bundleMaxAssetBytes = nextMaxAssetBytes ?? MAX_ELIXIR_ASSET_BYTES;
|
|
374
473
|
postMessage({ load: true });
|
|
375
474
|
return;
|
|
376
475
|
}
|
|
377
|
-
if (
|
|
476
|
+
if (nextBundleUrl) {
|
|
477
|
+
bundleUrl = nextBundleUrl;
|
|
478
|
+
bundleReceipts = snapshotElixirRuntimeAssetReceipts(nextAssetReceipts);
|
|
479
|
+
bundleMaxAssetBytes = nextMaxAssetBytes ?? MAX_ELIXIR_ASSET_BYTES;
|
|
480
|
+
}
|
|
481
|
+
if (!bundleUrl || !bundleReceipts) {
|
|
378
482
|
throw new Error('Elixir runtime not loaded');
|
|
379
483
|
}
|
|
380
484
|
stdinBufferElixir = buffer ? new Int32Array(buffer) : null;
|
|
@@ -382,21 +486,22 @@ self.onmessage = async (event) => {
|
|
|
382
486
|
postMessage({ results: true });
|
|
383
487
|
return;
|
|
384
488
|
}
|
|
385
|
-
const runtime = await loadRuntime(bundleUrl, log);
|
|
489
|
+
const runtime = await loadRuntime(bundleUrl, bundleReceipts, bundleMaxAssetBytes, log);
|
|
386
490
|
if (!runtime.process) {
|
|
387
|
-
throw new Error('
|
|
491
|
+
throw new Error('Popcorn runtime did not expose a default process');
|
|
388
492
|
}
|
|
389
493
|
if (log) {
|
|
390
|
-
console.log(`[wasm-idle:elixir-worker] eval bytes=${code.length}`);
|
|
494
|
+
console.log(`[wasm-idle:elixir-worker] ${evalLanguage.toLowerCase()} eval bytes=${code.length}`);
|
|
391
495
|
}
|
|
392
496
|
let evalCode = code;
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
let
|
|
497
|
+
const currentStdinBuffer = stdinBufferElixir;
|
|
498
|
+
if (evalLanguage === 'ELIXIR' && currentStdinBuffer && /(?:\bIO\.|\:io\.)/.test(code)) {
|
|
499
|
+
let bufferedInput = typeof stdin === 'string' ? stdin : '';
|
|
500
|
+
let reachedEof = typeof stdin === 'string';
|
|
396
501
|
const pullStdinChunk = () => {
|
|
397
502
|
if (reachedEof)
|
|
398
503
|
return false;
|
|
399
|
-
const nextChunk = waitForBufferedStdin(
|
|
504
|
+
const nextChunk = waitForBufferedStdin(currentStdinBuffer, () => postMessage({ buffer: true }));
|
|
400
505
|
if (nextChunk === null) {
|
|
401
506
|
reachedEof = true;
|
|
402
507
|
return false;
|
|
@@ -448,11 +553,11 @@ self.onmessage = async (event) => {
|
|
|
448
553
|
return JSON.stringify(consumed);
|
|
449
554
|
};
|
|
450
555
|
const wrapWithDeviceEvaluation = (deviceArg, valueExpr) => deviceArg
|
|
451
|
-
? `((fn
|
|
556
|
+
? `((fn wasm_idle_device -> _ = wasm_idle_device; ${valueExpr} end).(${deviceArg}))`
|
|
452
557
|
: valueExpr;
|
|
453
558
|
const wrapWithPromptOutput = (promptArg, valueExpr, deviceArg) => deviceArg
|
|
454
|
-
? `((fn
|
|
455
|
-
: `((fn
|
|
559
|
+
? `((fn wasm_idle_device, wasm_idle_prompt -> _ = wasm_idle_device; IO.write(wasm_idle_prompt); ${valueExpr} end).(${deviceArg}, ${promptArg}))`
|
|
560
|
+
: `((fn wasm_idle_prompt -> IO.write(wasm_idle_prompt); ${valueExpr} end).(${promptArg}))`;
|
|
456
561
|
let rewritten = '';
|
|
457
562
|
let cursor = 0;
|
|
458
563
|
while (cursor < code.length) {
|
|
@@ -536,7 +641,8 @@ self.onmessage = async (event) => {
|
|
|
536
641
|
? wrapWithPromptOutput(args[1], readCountLiteral(count, ':eof'), args[0])
|
|
537
642
|
: wrapWithPromptOutput(args[0], readCountLiteral(count, ':eof'));
|
|
538
643
|
}
|
|
539
|
-
else if (callName === ':io.get_line' &&
|
|
644
|
+
else if (callName === ':io.get_line' &&
|
|
645
|
+
(args.length === 1 || args.length === 2)) {
|
|
540
646
|
replacement =
|
|
541
647
|
args.length === 2
|
|
542
648
|
? wrapWithPromptOutput(args[1], readLineLiteral(':eof'), args[0])
|
|
@@ -558,7 +664,167 @@ self.onmessage = async (event) => {
|
|
|
558
664
|
}
|
|
559
665
|
evalCode = rewritten;
|
|
560
666
|
}
|
|
561
|
-
|
|
667
|
+
if (evalLanguage === 'ERLANG' && currentStdinBuffer && /\bio:/.test(code)) {
|
|
668
|
+
let bufferedInput = typeof stdin === 'string' ? stdin : '';
|
|
669
|
+
let reachedEof = typeof stdin === 'string';
|
|
670
|
+
const pullStdinChunk = () => {
|
|
671
|
+
if (reachedEof)
|
|
672
|
+
return false;
|
|
673
|
+
const nextChunk = waitForBufferedStdin(currentStdinBuffer, () => postMessage({ buffer: true }));
|
|
674
|
+
if (nextChunk === null) {
|
|
675
|
+
reachedEof = true;
|
|
676
|
+
return false;
|
|
677
|
+
}
|
|
678
|
+
bufferedInput += nextChunk;
|
|
679
|
+
return true;
|
|
680
|
+
};
|
|
681
|
+
const readLineLiteral = () => {
|
|
682
|
+
while (true) {
|
|
683
|
+
const newlineIndex = bufferedInput.indexOf('\n');
|
|
684
|
+
if (newlineIndex !== -1) {
|
|
685
|
+
const line = bufferedInput.slice(0, newlineIndex + 1);
|
|
686
|
+
bufferedInput = bufferedInput.slice(newlineIndex + 1);
|
|
687
|
+
return JSON.stringify(line);
|
|
688
|
+
}
|
|
689
|
+
if (!pullStdinChunk()) {
|
|
690
|
+
if (!bufferedInput) {
|
|
691
|
+
return 'eof';
|
|
692
|
+
}
|
|
693
|
+
const remainder = bufferedInput;
|
|
694
|
+
bufferedInput = '';
|
|
695
|
+
return JSON.stringify(remainder);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
};
|
|
699
|
+
const readCountLiteral = (count) => {
|
|
700
|
+
if (count === 0) {
|
|
701
|
+
return JSON.stringify('');
|
|
702
|
+
}
|
|
703
|
+
while (bufferedInput.length < count && pullStdinChunk()) {
|
|
704
|
+
// Keep requesting chunks until the requested count or EOF is available.
|
|
705
|
+
}
|
|
706
|
+
if (!bufferedInput) {
|
|
707
|
+
return 'eof';
|
|
708
|
+
}
|
|
709
|
+
const consumed = bufferedInput.slice(0, Math.min(count, bufferedInput.length));
|
|
710
|
+
bufferedInput = bufferedInput.slice(consumed.length);
|
|
711
|
+
return JSON.stringify(consumed);
|
|
712
|
+
};
|
|
713
|
+
const wrapWithPromptOutput = (promptArg, valueExpr, deviceArg) => deviceArg
|
|
714
|
+
? `((fun(WasmIdleDevice, WasmIdlePrompt) -> _ = WasmIdleDevice, io:format("~s", [WasmIdlePrompt]), ${valueExpr} end)(${deviceArg}, ${promptArg}))`
|
|
715
|
+
: `((fun(WasmIdlePrompt) -> io:format("~s", [WasmIdlePrompt]), ${valueExpr} end)(${promptArg}))`;
|
|
716
|
+
let rewritten = '';
|
|
717
|
+
let cursor = 0;
|
|
718
|
+
while (cursor < code.length) {
|
|
719
|
+
const current = code[cursor];
|
|
720
|
+
if (current === '"' || current === "'") {
|
|
721
|
+
const nextCursor = skipQuotedLiteral(code, cursor);
|
|
722
|
+
rewritten += code.slice(cursor, nextCursor);
|
|
723
|
+
cursor = nextCursor;
|
|
724
|
+
continue;
|
|
725
|
+
}
|
|
726
|
+
if (current === '%') {
|
|
727
|
+
const newlineIndex = code.indexOf('\n', cursor);
|
|
728
|
+
if (newlineIndex === -1) {
|
|
729
|
+
rewritten += code.slice(cursor);
|
|
730
|
+
break;
|
|
731
|
+
}
|
|
732
|
+
rewritten += code.slice(cursor, newlineIndex + 1);
|
|
733
|
+
cursor = newlineIndex + 1;
|
|
734
|
+
continue;
|
|
735
|
+
}
|
|
736
|
+
const callName = erlangStdinCallNames.find((candidate) => {
|
|
737
|
+
if (!code.startsWith(candidate, cursor)) {
|
|
738
|
+
return false;
|
|
739
|
+
}
|
|
740
|
+
const previous = code[cursor - 1] || '';
|
|
741
|
+
return !/[A-Za-z0-9_:@]/.test(previous);
|
|
742
|
+
});
|
|
743
|
+
if (!callName) {
|
|
744
|
+
rewritten += current;
|
|
745
|
+
cursor += 1;
|
|
746
|
+
continue;
|
|
747
|
+
}
|
|
748
|
+
let openParenIndex = cursor + callName.length;
|
|
749
|
+
while (/\s/.test(code[openParenIndex] || '')) {
|
|
750
|
+
openParenIndex += 1;
|
|
751
|
+
}
|
|
752
|
+
if (code[openParenIndex] !== '(') {
|
|
753
|
+
rewritten += current;
|
|
754
|
+
cursor += 1;
|
|
755
|
+
continue;
|
|
756
|
+
}
|
|
757
|
+
const closeParenIndex = findClosingParen(code, openParenIndex);
|
|
758
|
+
if (closeParenIndex === -1) {
|
|
759
|
+
rewritten += code.slice(cursor);
|
|
760
|
+
break;
|
|
761
|
+
}
|
|
762
|
+
const originalCall = code.slice(cursor, closeParenIndex + 1);
|
|
763
|
+
const args = splitTopLevelArgs(code.slice(openParenIndex + 1, closeParenIndex));
|
|
764
|
+
let replacement = originalCall;
|
|
765
|
+
if (callName === 'io:get_line' && (args.length === 1 || args.length === 2)) {
|
|
766
|
+
replacement =
|
|
767
|
+
args.length === 2
|
|
768
|
+
? wrapWithPromptOutput(args[1], readLineLiteral(), args[0])
|
|
769
|
+
: wrapWithPromptOutput(args[0], readLineLiteral());
|
|
770
|
+
}
|
|
771
|
+
else if (callName === 'io:get_chars' &&
|
|
772
|
+
(args.length === 2 || args.length === 3)) {
|
|
773
|
+
const count = parseLiteralCount(args[args.length - 1]);
|
|
774
|
+
if (count === null) {
|
|
775
|
+
throw new Error('io:get_chars stdin bridge requires a literal non-negative count');
|
|
776
|
+
}
|
|
777
|
+
replacement =
|
|
778
|
+
args.length === 3
|
|
779
|
+
? wrapWithPromptOutput(args[1], readCountLiteral(count), args[0])
|
|
780
|
+
: wrapWithPromptOutput(args[0], readCountLiteral(count));
|
|
781
|
+
}
|
|
782
|
+
rewritten += replacement;
|
|
783
|
+
cursor = closeParenIndex + 1;
|
|
784
|
+
}
|
|
785
|
+
evalCode = rewritten;
|
|
786
|
+
}
|
|
787
|
+
let response;
|
|
788
|
+
if (evalLanguage === 'ERLANG') {
|
|
789
|
+
const moduleMatch = evalCode.match(/^\s*-module\(\s*([a-z][A-Za-z0-9_@]*|'(?:[^'\\]|\\.)+')\s*\)\s*\./m);
|
|
790
|
+
if (diagnose) {
|
|
791
|
+
if (moduleMatch) {
|
|
792
|
+
await runtime.module.call(runtime.process, ['eval_erlang_module', evalCode]);
|
|
793
|
+
}
|
|
794
|
+
else {
|
|
795
|
+
await runtime.module.call(runtime.process, [
|
|
796
|
+
'eval_erlang',
|
|
797
|
+
`{ok, WasmIdleTokens, _} = erl_scan:string(${JSON.stringify(code)}), erl_parse:parse_exprs(WasmIdleTokens).`
|
|
798
|
+
]);
|
|
799
|
+
}
|
|
800
|
+
postMessage({ results: true });
|
|
801
|
+
return;
|
|
802
|
+
}
|
|
803
|
+
if (moduleMatch) {
|
|
804
|
+
await runtime.module.call(runtime.process, ['eval_erlang_module', evalCode]);
|
|
805
|
+
postExecutionReady('Erlang program started');
|
|
806
|
+
response = await runtime.module.call(runtime.process, [
|
|
807
|
+
'eval_erlang',
|
|
808
|
+
`${moduleMatch[1]}:main().`
|
|
809
|
+
]);
|
|
810
|
+
}
|
|
811
|
+
else {
|
|
812
|
+
postExecutionReady('Erlang expression started');
|
|
813
|
+
response = await runtime.module.call(runtime.process, ['eval_erlang', evalCode]);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
else if (diagnose) {
|
|
817
|
+
await runtime.module.call(runtime.process, [
|
|
818
|
+
'eval_elixir',
|
|
819
|
+
`Code.string_to_quoted!(${JSON.stringify(code)})`
|
|
820
|
+
]);
|
|
821
|
+
postMessage({ results: true });
|
|
822
|
+
return;
|
|
823
|
+
}
|
|
824
|
+
else {
|
|
825
|
+
postExecutionReady('Elixir program started');
|
|
826
|
+
response = await runtime.module.call(runtime.process, ['eval_elixir', evalCode]);
|
|
827
|
+
}
|
|
562
828
|
const rendered = runtime.module.deserialize(response);
|
|
563
829
|
if (typeof rendered === 'string') {
|
|
564
830
|
postMessage({ results: rendered });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|