wasm-idle 1.0.0 → 1.0.4
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 +46 -5
- package/dist/index.d.ts +1 -0
- package/dist/playground/applicationAssets.js +4 -1
- package/dist/playground/assetBridge.d.ts +6 -5
- package/dist/playground/assetBridge.js +85 -9
- package/dist/playground/assets.d.ts +7 -0
- package/dist/playground/assets.js +11 -0
- package/dist/playground/clang.js +10 -3
- package/dist/playground/clangAssetIntegrity.d.ts +26 -0
- package/dist/playground/clangAssetIntegrity.js +10 -3
- package/dist/playground/clangStreamingPolicy.d.ts +6 -0
- package/dist/playground/clangStreamingPolicy.js +7 -0
- package/dist/playground/dotnet.js +2 -1
- package/dist/playground/index.d.ts +2 -1
- package/dist/playground/index.js +2 -2
- package/dist/playground/java.js +8 -2
- package/dist/playground/loadingProgress.js +2 -1
- package/dist/playground/ruby.js +52 -30
- package/dist/playground/rubyAssets.d.ts +4 -4
- package/dist/playground/rubyAssets.js +10 -3
- package/dist/playground/sandbox.d.ts +4 -0
- package/dist/playground/staticRuntimeModuleVersion.d.ts +1 -1
- package/dist/playground/staticRuntimeModuleVersion.js +1 -1
- package/dist/playground/typescript.js +18 -5
- package/dist/playground/wasmDotnetVersion.d.ts +1 -1
- package/dist/playground/wasmDotnetVersion.js +1 -1
- package/dist/playground/wasmGoVersion.d.ts +1 -1
- package/dist/playground/wasmGoVersion.js +1 -1
- package/dist/playground/wasmRustVersion.d.ts +66 -12
- package/dist/playground/wasmRustVersion.js +71 -11
- package/dist/playground/wasmTypeScriptVersion.d.ts +7 -3
- package/dist/playground/wasmTypeScriptVersion.js +7 -3
- package/dist/playground/worker/assets.js +34 -7
- package/dist/playground/worker/boundedAssetResponse.d.ts +14 -0
- package/dist/playground/worker/boundedAssetResponse.js +148 -0
- package/dist/playground/worker/clang.js +21 -4
- package/dist/playground/worker/clangStreaming.d.ts +3 -0
- package/dist/playground/worker/clangStreaming.js +41 -0
- package/dist/playground/worker/dotnet.js +2 -0
- package/dist/playground/worker/java.js +55 -20
- package/dist/playground/worker/javaStreaming.d.ts +9 -0
- package/dist/playground/worker/javaStreaming.js +99 -0
- package/dist/playground/worker/php.js +52 -12
- package/dist/playground/worker/python.js +37 -9
- package/dist/playground/worker/ruby.js +207 -56
- package/package.json +9 -7
package/README.md
CHANGED
|
@@ -221,9 +221,9 @@ when they exist.
|
|
|
221
221
|
| Language / IDs | Package/version base | Execution defaults / flags | Customization |
|
|
222
222
|
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
223
223
|
| C3<br>`C3` | wasm-llvm/c3-browser: C3 0.8.3 / LLVM 22.1.8 | Verified c3c and builtin LLD compile real C3 in a fresh browser Worker; UTF-8 env.readByte/env.writeByte ABI and exported main; std::io and WASI unavailable | `runtimeAssets.c3.baseUrl`, `stdin`, `activePath`, `workspaceFiles`; fixed compiler flags and bounded Wasm memories |
|
|
224
|
-
| C<br>`C` | @wasm-idle/llvm-core@1.0.
|
|
225
|
-
| C++<br>`CPP` | @wasm-idle/llvm-core@1.0.
|
|
226
|
-
| Objective-C<br>`OBJC` | GNUstep libobjc2 v2.3 assets from the `wasm-llvm` producer + @wasm-idle/llvm-core@1.0.
|
|
224
|
+
| C<br>`C` | @wasm-idle/llvm-core@1.0.3 / Clang 22.1.8 WASI sysroot from the `wasm-llvm` producer | `clang` for `wasm32-wasi`; default `-std=gnu11`; LLDB mode compiles untouched source with embedded DWARF at `-g -O0` and runs it in WAMR; normal runs still use the browser WASI host; supports `stdin` and `programArgs` | `runtimeAssets.clang.baseUrl`/`loader` or `rootUrl`; `compileArgs`, `programArgs`, `cVersion`, `activePath`, `workspaceFiles`, `debugMode`, `breakpoints`, `pauseOnEntry` |
|
|
225
|
+
| C++<br>`CPP` | @wasm-idle/llvm-core@1.0.3 / Clang 22.1.8 WASI sysroot from the `wasm-llvm` producer | `clang++` for `wasm32-wasi`; default `-std=gnu++20`; LLDB mode compiles untouched source with embedded DWARF at `-g -O0` and runs it in WAMR; normal runs still use the browser WASI host; supports `stdin` and `programArgs` | `runtimeAssets.clang.baseUrl`/`loader` or `rootUrl`; `compileArgs`, `programArgs`, `cppVersion`, `activePath`, `workspaceFiles`, `debugMode`, `breakpoints`, `pauseOnEntry` |
|
|
226
|
+
| Objective-C<br>`OBJC` | GNUstep libobjc2 v2.3 assets from the `wasm-llvm` producer + @wasm-idle/llvm-core@1.0.3 | `clang -x objective-c -fobjc-runtime=gnustep-2.0 -fblocks` for `wasm32-wasi`; links `libobjc.a`, `libgnustep-base.a`, and `libffi.a` when Foundation is imported; Foundation headers are inlined from `foundation-headers.json`; includes a constructor wrapper for Objective-C class registration; auto-compiles `.m`/`.mm`/`.c` workspace files; trace debug instruments active source and uses wasm-idle controls; supports `stdin` and `programArgs`; large Objective-C assets may be served as gzip-only `.gz` files through the service worker or worker fallback | `runtimeAssets.objectivec.baseUrl`/`libobjcUrl`/`headersUrl`/`libgnustepBaseUrl`/`libgnustepBaseObjectUrl`/`foundationHeadersUrl`/`libffiUrl` or `PUBLIC_WASM_OBJECTIVEC_*`; `runtimeAssets.clang.baseUrl`/`loader` for the clang toolchain; `activePath`, `workspaceFiles`, `compileArgs`, `debug`, `breakpoints`, `pauseOnEntry` |
|
|
227
227
|
| Python<br>`PYTHON3` | static ESM `static/pyodide/pyodide.mjs` / pyodide@0.29.3 | loads `pyodide.mjs`, `pyodide.asm.js`, `pyodide.asm.wasm`, and `python_stdlib.zip` from the configured static asset tree on demand; supports `stdin`, workspace files, and trace debugging | `runtimeAssets.python.baseUrl`/`loader` or `rootUrl`; `stdin`, `activePath`, `workspaceFiles`, `debug`, `breakpoints`, `pauseOnEntry`, `debugPath` |
|
|
228
228
|
| Java<br>`JAVA` | @wasm-idle/runtime-teavm@0.0.0 / TeaVM compiler assets | `compiler.wasm` compiles Java to browser WASM/JS; supports `stdin` and `programArgs` | `runtimeAssets.java.baseUrl`/`loader` or `rootUrl` |
|
|
229
229
|
| Rust<br>`RUST` | wasm-rust@0.1.0 / rust-1.99.0-browser-integrated-v1 + integrated LLVM/LLD 22.1.8 from the `wasm-llvm` producer; exact rustc/LLVM provenance is recorded for LLDB compatibility | browser host `wasm32-wasip1-threads`; default target `wasm32-wasip1`, selectable `wasm32-wasip1`, `wasm32-wasip2`, `wasm32-wasip3`; LLDB mode is currently limited to `wasm32-wasip1` and emits embedded DWARF with `-C debuginfo=2 -C opt-level=0`; normal Preview 1/2/3 execution remains unchanged; supports `stdin` and `programArgs` | `runtimeAssets.rust.compilerUrl`, `runtimeAssets.rust.debugModuleUrl`, or `PUBLIC_WASM_RUST_COMPILER_URL`; `rootUrl`, `rustTargetTriple`, `programArgs`, `debugMode`; compiler requests accept `edition`, `crateType`, `extendedTimeout`, `log`, and `onProgress`; runtime manifest controls compiler memory, timeout, and shared workspace size |
|
|
@@ -261,8 +261,8 @@ when they exist.
|
|
|
261
261
|
| Ruby<br>`RUBY` | receipt-pinned `static/wasm-ruby` profile produced from @ruby/3.4-wasm-wasi@2.9.3-2.9.4 + @ruby/wasm-wasi@2.9.3-2.9.4 | host-verifies the manifest, canonical stored module and gzip bytes, and logical WASM before transferring three owned buffers to a no-fetch CRuby 3.4 worker; supports `stdin`, `programArgs`, and workspace files | `rootUrl` mirrors reuse the bundled profile; explicit `runtimeAssets.ruby` overrides require one complete profile and same-origin canonical paths; URL-only `PUBLIC_WASM_RUBY_*` overrides fail closed; `stdin`, `programArgs`, `workspaceFiles` |
|
|
262
262
|
| Haskell<br>`HASKELL` | ghc-in-browser / GHC 9.14.0.20251031 WASI rootfs | loads `dyld.mjs`, `rootfs.tar.zst`, `bsdtar.wasm`; `compileArgs` become GHC args, otherwise legacy `args` become GHC args | `runtimeAssets.haskell.moduleUrl`/`rootfsUrl`/`bsdtarUrl`; `mainSoPath`, `searchDirs`, `activePath`, `workspaceFiles` |
|
|
263
263
|
| LFortran<br>`LFORTRAN` | receipt-pinned `wasm-llvm/producer/lfortran-browser` artifacts in `static/wasm-lfortran` | real LFortran 0.65.0-97-gab867a23 LLVM evaluator compiles and executes Emscripten side modules in a fresh Worker; shared-ring stdin supports delayed READ and EOF; experimental Fortran feature coverage | `runtimeAssets.lfortran.baseUrl` relocates the reviewed bundle; `stdin`, `activePath`, workspace data/include files, cancellation and execution limits; no program arguments or multi-file module build orchestration |
|
|
264
|
-
| Fortran<br>`FORTRAN` | Netlib f2c 2022-09-09 + `@cowasm/f2c 1.0.0` libf2c + @wasm-idle/llvm-core@1.0.
|
|
265
|
-
| COBOL<br>`COBOL` | GnuCOBOL 3.2 + GMP 6.3.0 assets from the `wasm-llvm` producer + @wasm-idle/llvm-core@1.0.
|
|
264
|
+
| Fortran<br>`FORTRAN` | Netlib f2c 2022-09-09 + `@cowasm/f2c 1.0.0` libf2c + @wasm-idle/llvm-core@1.0.3 | runs `f2c.wasm` in WASI, compiles generated C with the llvm-core Clang host, links `libf2c.a`, then executes the resulting WASI module with `stdin` and `programArgs` | `runtimeAssets.fortran.baseUrl`/`f2cWasmUrl`/`libf2cUrl`/`f2cHeaderUrl`/`analyzerUrl` or `PUBLIC_WASM_FORTRAN_*`; `runtimeAssets.clang.baseUrl`/`loader` for the C backend; `activePath`, `workspaceFiles`, `compileArgs` |
|
|
265
|
+
| COBOL<br>`COBOL` | GnuCOBOL 3.2 + GMP 6.3.0 assets from the `wasm-llvm` producer + @wasm-idle/llvm-core@1.0.3 | native gzip delivery for the frontend Wasm and filesystem tar assets; translates free-format COBOL with the real GnuCOBOL `cobc` frontend, compiles the generated C with the llvm-core Clang host, links libcob/GMP, and executes the resulting WASI module with `stdin` and `programArgs` | `runtimeAssets.cobol.baseUrl` or `PUBLIC_WASM_COBOL_BASE_URL`; `runtimeAssets.clang.baseUrl`/`loader` for the C backend; `activePath`, `workspaceFiles`, `compileArgs` |
|
|
266
266
|
| R<br>`R` | versioned static `static/webr/<hash>/webr.js` / webr@0.6.0 | loads the browser ESM entry `webr.js` and its WebR runtime files from the configured static asset tree on demand; supports `stdin`, `programArgs`, and workspace files | `runtimeAssets.r.baseUrl` or `PUBLIC_WASM_R_BASE_URL`; `stdin`, `programArgs`, `activePath`, `workspaceFiles` |
|
|
267
267
|
| Octave<br>`OCTAVE` | Octave 10.3.0 (octave-10.3.0-pl5321h996e327_3.tar.bz2) | Octave CLI Emscripten worker; supports `stdin` and `programArgs` | `runtimeAssets.octave.baseUrl`/`workerUrl`/`manifestUrl` or `PUBLIC_WASM_OCTAVE_*` |
|
|
268
268
|
| DuckDB<br>`DUCKDB` | static ESM `static/wasm-duckdb/runtime.mjs` produced from @duckdb/duckdb-wasm@1.33.1-dev45.0 | selects the best DuckDB-Wasm MVP/EH bundle on demand and creates a fresh in-memory database per run; `stdin` is registered as `stdin.txt` and `/dev/stdin` rather than terminal stdin | `runtimeAssets.duckdb.moduleUrl` or `PUBLIC_WASM_DUCKDB_MODULE_URL` or `rootUrl`; `stdin`, `activePath`, `workspaceFiles` |
|
|
@@ -552,6 +552,11 @@ from GitHub without WAF credentials. Update the snapshot URL and all changed rec
|
|
|
552
552
|
do not replace a receipt with bytes from a mutable deployment URL. Receipt failures report both
|
|
553
553
|
expected and actual byte counts and SHA-256 digests.
|
|
554
554
|
|
|
555
|
+
The slim Clang snapshot is retained on `artifacts/slim-clang-20260927`. Keep that branch while
|
|
556
|
+
the manifest references its commit; the snapshot preserves the pinned OCaml inputs and replaces
|
|
557
|
+
only Clang delivery files and their build receipt. Updating this download source does not deploy
|
|
558
|
+
GitHub Pages.
|
|
559
|
+
|
|
555
560
|
OCaml preparation keeps these verified download inputs in a separate receipt-keyed cache,
|
|
556
561
|
compiles the tracked TypeScript browser adapter with the producer's locked compiler, and syncs
|
|
557
562
|
that adapter together with the verified native bundle. The sync derives the final
|
|
@@ -849,6 +854,11 @@ Verified static runtimes such as Janet and Julia intentionally omit URL-only exa
|
|
|
849
854
|
field declared by that runtime's asset config, including the matching `workerReceipt`. Partial
|
|
850
855
|
trust bundles fail closed instead of borrowing receipts from bundled executable bytes.
|
|
851
856
|
|
|
857
|
+
The bundled C/C++ app uses receipt-pinned Clang language sysroots: C initially downloads only the
|
|
858
|
+
C base, while C++ or a mixed/opaque-language build loads the C++ add-on before compiling or linking.
|
|
859
|
+
Custom Clang loaders retain the original full sysroot path unless their host explicitly provides
|
|
860
|
+
and verifies a matching profile pair.
|
|
861
|
+
|
|
852
862
|
Python custom loaders receive file names under the Pyodide asset root and can serve both core assets and package files. TeaVM custom loaders receive file names under the TeaVM asset root. Clang custom loaders receive `bin/memfs.wasm.gz`, `bin/clang.wasm.gz`, `bin/lld.wasm.gz`, and `bin/sysroot.tar.gz`; COBOL loaders receive `cobc.wasm.gz`, `rootfs.tar.gz`, and `c-sysroot.tar.gz`. The shared loader pipes these gzip response bodies through native `DecompressionStream`. Legacy external manifests that still reference ZIP assets remain supported through the dynamically loaded `fflate` compatibility path. Zig custom loaders receive `zig_small.wasm` and `std.tar.gz`; an explicitly configured legacy `std.zip` URL remains compatible. Clangd custom loaders receive `clangd.js` and `clangd.wasm.gz`, with the worker decompressing the gzip payload before instantiation. Rust expects a logical, profile-pinned graph entry URL whose sibling inert storage exactly matches the generated receipts; it does not import that HTTP entry directly. C#, F#, and VB.NET expect a browser-loadable `wasm-dotnet` module with its language-specific static .NET `browser-wasm` runtime assets. Compressed TeaVM runtime assets are no longer unpacked inside the library; provide the final file URL or handle decompression in your own loader.
|
|
853
863
|
|
|
854
864
|
To reuse the same runtime asset configuration for both `<Terminal>` and direct `playground(...)`
|
|
@@ -881,3 +891,34 @@ Compiler assets produced by [`wasm-llvm`](https://github.com/seo-rii/wasm-llvm)
|
|
|
881
891
|
external static hosting and loaded by `@wasm-idle/llvm-core`. Also powered by Pyodide, TeaVM, `wasm-rust`,
|
|
882
892
|
`wasm-dotnet`, `wasm-of-js-of-ocaml`, `wasm-typescript`, `wasm-lisp`,
|
|
883
893
|
`wasm-wat`, `wasm-lua`, `wasm-zig`, CBQN, Janet, AtomVM/Popcorn, and `ghc-in-browser`.
|
|
894
|
+
|
|
895
|
+
### Ruby split standard library
|
|
896
|
+
|
|
897
|
+
The bundled Ruby runtime also provides a verified `ruby.splitStdlib: true` profile. It compiles the genuine Ruby core Wasm while fetching the complete standard library and bundled gems as a separate read-only filesystem pack. The web demo selects this profile; library consumers retain the embedded-stdlib profile unless they opt in. Custom trust profiles continue to use the embedded path.
|
|
898
|
+
|
|
899
|
+
The pack contains the same locked upstream files, not an import-based subset. Each execution gets fresh filesystem descriptors and directories. Both the host and worker verify fixed byte lengths and SHA-256 receipts before activation. Compiler payload size decreases, but total network transfer is not necessarily smaller.
|
|
900
|
+
|
|
901
|
+
`node scripts/sync-runtime.mjs wasm-ruby` regenerates both profiles from the pinned producer inputs. `node scripts/sync-wasm-ruby-split.mjs --verify` additionally checks split-profile freshness without replacing published files.
|
|
902
|
+
|
|
903
|
+
### Optional idle runtime prewarming
|
|
904
|
+
|
|
905
|
+
`createPlaygroundBinding(assets, { prewarm: true })` enables explicit
|
|
906
|
+
`binding.prewarm(language)` requests. The default is **false**: constructing a
|
|
907
|
+
binding or selecting a language in an embedding does not start network requests.
|
|
908
|
+
The first-party web demo opts in and exposes a **Prewarm** checkbox.
|
|
909
|
+
|
|
910
|
+
```ts
|
|
911
|
+
const binding = createPlaygroundBinding(assets, { prewarm: true });
|
|
912
|
+
void binding.prewarm('JAVA'); // idle priority; runtime only, never executes source
|
|
913
|
+
const sandbox = await binding.load('JAVA'); // claims the same prepared sandbox
|
|
914
|
+
await binding.setPrewarmEnabled?.(false); // cancels unclaimed preparation only
|
|
915
|
+
await binding.dispose?.();
|
|
916
|
+
```
|
|
917
|
+
|
|
918
|
+
Only one unclaimed runtime is retained per binding. Selecting another language
|
|
919
|
+
cancels that speculative work. A foreground load starts queued preparation
|
|
920
|
+
immediately and owns the result; subsequent toggles cannot terminate it.
|
|
921
|
+
Speculative failures are discarded so ordinary loading can retry. Prewarming
|
|
922
|
+
skips server-side rendering, hidden documents, save-data mode and 2G connections.
|
|
923
|
+
All normal runtime integrity, startup timeout and execution-limit checks remain
|
|
924
|
+
in place. This does not compile user source or preload every language at once.
|
package/dist/index.d.ts
CHANGED
|
@@ -6,3 +6,4 @@ export type { DebugCommand, DebugFrame, DebugSessionEvent, DebugVariable, Termin
|
|
|
6
6
|
export type { CompilerDiagnostic, SandboxExecutionOptions } from './playground/options';
|
|
7
7
|
export type { PlaygroundRuntimeAssets, RuntimeAssetConfig, RuntimeAssetLoadRequest, RuntimeAssetLoader, RuntimeAssetLoaderResult } from './playground/assets';
|
|
8
8
|
export type { BoundSandbox, PlaygroundBinding, PlaygroundTerminalProps, SandboxProgress, SandboxRuntimeAssets } from './playground/sandbox';
|
|
9
|
+
export type { PlaygroundBindingOptions } from "@wasm-idle/core";
|
|
@@ -55,6 +55,7 @@ export function createApplicationRuntimeAssets(rootUrl) {
|
|
|
55
55
|
const asset = createApplicationAssetResolver(normalizedRootUrl);
|
|
56
56
|
return {
|
|
57
57
|
rootUrl: normalizedRootUrl,
|
|
58
|
+
clang: { bundledLanguageSysroots: true },
|
|
58
59
|
assemblyscript: {
|
|
59
60
|
moduleUrl: asset('wasm-assemblyscript/runtime.mjs', STATIC_RUNTIME_MODULE_VERSION)
|
|
60
61
|
},
|
|
@@ -62,7 +63,7 @@ export function createApplicationRuntimeAssets(rootUrl) {
|
|
|
62
63
|
moduleUrl: asset('wasm-duckdb/runtime.mjs', STATIC_RUNTIME_MODULE_VERSION)
|
|
63
64
|
},
|
|
64
65
|
php: {
|
|
65
|
-
moduleUrl: asset('wasm-php/
|
|
66
|
+
moduleUrl: asset('wasm-php/startup.mjs', STATIC_RUNTIME_MODULE_VERSION)
|
|
66
67
|
},
|
|
67
68
|
rust: {
|
|
68
69
|
compilerUrl: `${asset('wasm-rust/index.js', WASM_RUST_ASSET_VERSION)}&rustManifestBytes=${WASM_RUST_RUNTIME_PROFILE.manifestReceipt.bytes}&rustManifestSha256=${WASM_RUST_RUNTIME_PROFILE.manifestReceipt.sha256}`,
|
|
@@ -209,6 +210,7 @@ export function createApplicationRuntimeAssets(rootUrl) {
|
|
|
209
210
|
},
|
|
210
211
|
typescript: {
|
|
211
212
|
moduleUrl: asset('wasm-typescript/index.js', WASM_TYPESCRIPT_ASSET_VERSION),
|
|
213
|
+
javascriptModuleUrl: asset('wasm-typescript/javascript.js', WASM_TYPESCRIPT_ASSET_VERSION),
|
|
212
214
|
libUrl: asset('lsp/typescript-libs.json.gz', WASM_TYPESCRIPT_ASSET_VERSION)
|
|
213
215
|
},
|
|
214
216
|
wat: {
|
|
@@ -228,6 +230,7 @@ export function createApplicationRuntimeAssets(rootUrl) {
|
|
|
228
230
|
manifestFingerprint: WASM_LISP_ASSET_VERSION
|
|
229
231
|
},
|
|
230
232
|
ruby: {
|
|
233
|
+
splitStdlib: true,
|
|
231
234
|
baseUrl: asset('wasm-ruby/'),
|
|
232
235
|
manifestUrl: asset(`wasm-ruby/${RUBY_RUNTIME_MANIFEST_PATH}`, RUBY_RUNTIME_BUNDLE.profile.manifestFingerprint),
|
|
233
236
|
moduleUrl: asset(`wasm-ruby/${RUBY_RUNTIME_MODULE_STORAGE_PATH}`, RUBY_RUNTIME_BUNDLE.profile.moduleJavaScriptReceipt.sha256),
|
|
@@ -5,16 +5,17 @@ export declare class WorkerAssetBridge {
|
|
|
5
5
|
private worker;
|
|
6
6
|
private readonly runtime;
|
|
7
7
|
private config;
|
|
8
|
-
private
|
|
9
|
-
private
|
|
8
|
+
private progress;
|
|
9
|
+
private expectedAssets;
|
|
10
|
+
private languageSysroots;
|
|
10
11
|
private pythonPackageAssets;
|
|
11
12
|
private generation;
|
|
12
13
|
private state;
|
|
13
14
|
private readonly activeLoads;
|
|
14
15
|
private maxAssetBytes;
|
|
15
|
-
constructor(worker: Worker, runtime: RuntimeAssetRuntime, config: ResolvedRuntimeAssetConfig, progress?: ProgressLike, maxAssetBytes?: number);
|
|
16
|
-
matches(config: ResolvedRuntimeAssetConfig, maxAssetBytes?: number): boolean;
|
|
17
|
-
rebind(worker: Worker, config: ResolvedRuntimeAssetConfig, progress?: ProgressLike, maxAssetBytes?: number): void;
|
|
16
|
+
constructor(worker: Worker, runtime: RuntimeAssetRuntime, config: ResolvedRuntimeAssetConfig, progress?: ProgressLike, maxAssetBytes?: number, languageSysroots?: boolean);
|
|
17
|
+
matches(config: ResolvedRuntimeAssetConfig, maxAssetBytes?: number, languageSysroots?: boolean): boolean;
|
|
18
|
+
rebind(worker: Worker, config: ResolvedRuntimeAssetConfig, progress?: ProgressLike, maxAssetBytes?: number, languageSysroots?: boolean): void;
|
|
18
19
|
dispose(): void;
|
|
19
20
|
resetProgress(progress?: ProgressLike): void;
|
|
20
21
|
private configuredReceiptByteLimit;
|
|
@@ -2,6 +2,8 @@ import { RUNTIME_LOAD_ASSETS } from './assets';
|
|
|
2
2
|
import { ProtocolError, verifyRuntimeAssetIntegrity, verifyRuntimeAssetPair } from '@wasm-idle/core';
|
|
3
3
|
import { decompressGzip } from '@wasm-idle/llvm-core';
|
|
4
4
|
import { readPythonPackageAssets } from './pythonPackageLock';
|
|
5
|
+
import { BUNDLED_CLANG_LANGUAGE_SYSROOT_PROFILES } from './clangAssetIntegrity';
|
|
6
|
+
import { shouldStreamBundledClang } from './clangStreamingPolicy';
|
|
5
7
|
const encoder = new TextEncoder();
|
|
6
8
|
const DEFAULT_STREAM_BUFFER_BYTES = 64 * 1024;
|
|
7
9
|
const MAX_RUNTIME_ASSET_BYTES = 128 * 1024 * 1024;
|
|
@@ -181,7 +183,18 @@ const transferBuffer = (bytes, transferOwnership = false) => {
|
|
|
181
183
|
? transferableBuffer
|
|
182
184
|
: Uint8Array.from(canonicalBytes).buffer;
|
|
183
185
|
};
|
|
184
|
-
const
|
|
186
|
+
const cSysrootAsset = BUNDLED_CLANG_LANGUAGE_SYSROOT_PROFILES.c.asset;
|
|
187
|
+
const cppAddonAsset = BUNDLED_CLANG_LANGUAGE_SYSROOT_PROFILES.cppAddon.asset;
|
|
188
|
+
const fullSysrootAsset = 'bin/sysroot.tar.gz';
|
|
189
|
+
const canUseClangLanguageSysroots = (runtime, config, requested) => runtime === 'clang' && requested && config.useAssetBridge && shouldStreamBundledClang(config);
|
|
190
|
+
const expectedAssetsForRuntime = (runtime, languageSysroots = false) => {
|
|
191
|
+
const assets = new Set(RUNTIME_LOAD_ASSETS[runtime]);
|
|
192
|
+
if (runtime === 'clang' && languageSysroots) {
|
|
193
|
+
assets.add(cSysrootAsset);
|
|
194
|
+
assets.add(cppAddonAsset);
|
|
195
|
+
}
|
|
196
|
+
return assets;
|
|
197
|
+
};
|
|
185
198
|
const integrityKey = (config) => JSON.stringify(Object.entries(config.integrity || {})
|
|
186
199
|
.sort(([left], [right]) => left.localeCompare(right))
|
|
187
200
|
.map(([asset, entry]) => [
|
|
@@ -199,19 +212,29 @@ const integrityKey = (config) => JSON.stringify(Object.entries(config.integrity
|
|
|
199
212
|
const allowedBaseUrlsKey = (config) => JSON.stringify([...(config.allowedBaseUrls || [])].sort());
|
|
200
213
|
class RuntimeLoadProgress {
|
|
201
214
|
samples = new Map();
|
|
215
|
+
optionalSamples = new Map();
|
|
202
216
|
expectedAssets;
|
|
217
|
+
optionalAssets;
|
|
203
218
|
phaseId;
|
|
204
219
|
progress;
|
|
205
220
|
lockedTotal;
|
|
206
221
|
measurementInvalid = false;
|
|
207
|
-
constructor(runtime) {
|
|
222
|
+
constructor(runtime, languageSysroots = false) {
|
|
208
223
|
this.expectedAssets = expectedAssetsForRuntime(runtime);
|
|
224
|
+
this.optionalAssets = new Set();
|
|
225
|
+
if (runtime === 'clang' && languageSysroots) {
|
|
226
|
+
this.expectedAssets.delete(fullSysrootAsset);
|
|
227
|
+
this.expectedAssets.add(cSysrootAsset);
|
|
228
|
+
this.optionalAssets.add(fullSysrootAsset);
|
|
229
|
+
this.optionalAssets.add(cppAddonAsset);
|
|
230
|
+
}
|
|
209
231
|
this.phaseId = `${runtime}:runtime-assets`;
|
|
210
232
|
this.reset();
|
|
211
233
|
}
|
|
212
234
|
reset(progress) {
|
|
213
235
|
this.progress = progress;
|
|
214
236
|
this.samples.clear();
|
|
237
|
+
this.optionalSamples.clear();
|
|
215
238
|
this.lockedTotal = undefined;
|
|
216
239
|
this.measurementInvalid = false;
|
|
217
240
|
for (const asset of this.expectedAssets)
|
|
@@ -219,8 +242,53 @@ class RuntimeLoadProgress {
|
|
|
219
242
|
this.emit();
|
|
220
243
|
}
|
|
221
244
|
update(asset, loaded, total) {
|
|
222
|
-
if (!this.expectedAssets.has(asset))
|
|
245
|
+
if (!this.expectedAssets.has(asset)) {
|
|
246
|
+
if (this.optionalAssets.has(asset) && this.progress) {
|
|
247
|
+
const previous = this.optionalSamples.get(asset) || { loaded: 0 };
|
|
248
|
+
// A completed optional transfer may receive a duplicate or an unrelated
|
|
249
|
+
// worker-side progress sample. Keep its final measurement terminal;
|
|
250
|
+
// a subsequent unmeasured activity would turn 100% back into 99%.
|
|
251
|
+
if (previous.total !== undefined && previous.loaded === previous.total)
|
|
252
|
+
return;
|
|
253
|
+
const nextLoaded = Math.max(previous.loaded, loaded);
|
|
254
|
+
const nextTotal = total ?? previous.total;
|
|
255
|
+
const valid = Number.isSafeInteger(loaded) &&
|
|
256
|
+
loaded >= 0 &&
|
|
257
|
+
(total === undefined ||
|
|
258
|
+
(Number.isSafeInteger(total) &&
|
|
259
|
+
total > 0 &&
|
|
260
|
+
(previous.total === undefined || previous.total === total))) &&
|
|
261
|
+
(nextTotal === undefined || nextLoaded <= nextTotal);
|
|
262
|
+
if (valid) {
|
|
263
|
+
this.optionalSamples.set(asset, {
|
|
264
|
+
loaded: nextLoaded,
|
|
265
|
+
...(nextTotal === undefined ? {} : { total: nextTotal })
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
const label = `Downloading ${asset}`;
|
|
269
|
+
if (this.progress.report) {
|
|
270
|
+
this.progress.report({
|
|
271
|
+
kind: 'activity',
|
|
272
|
+
phase: 'downloading',
|
|
273
|
+
phaseId: `${this.phaseId}:${asset}`,
|
|
274
|
+
label,
|
|
275
|
+
...(valid && nextTotal !== undefined
|
|
276
|
+
? {
|
|
277
|
+
measurement: {
|
|
278
|
+
kind: 'bytes',
|
|
279
|
+
completed: nextLoaded,
|
|
280
|
+
total: nextTotal
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
: {})
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
this.progress.set?.(valid && nextTotal !== undefined ? nextLoaded / nextTotal : 0, label);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
223
290
|
return;
|
|
291
|
+
}
|
|
224
292
|
if (!Number.isSafeInteger(loaded) || loaded < 0) {
|
|
225
293
|
this.measurementInvalid = true;
|
|
226
294
|
this.emit();
|
|
@@ -309,22 +377,26 @@ export class WorkerAssetBridge {
|
|
|
309
377
|
config;
|
|
310
378
|
progress;
|
|
311
379
|
expectedAssets;
|
|
380
|
+
languageSysroots;
|
|
312
381
|
pythonPackageAssets = new Set();
|
|
313
382
|
generation = 0;
|
|
314
383
|
state = 'active';
|
|
315
384
|
activeLoads = new Set();
|
|
316
385
|
maxAssetBytes;
|
|
317
|
-
constructor(worker, runtime, config, progress, maxAssetBytes = MAX_RUNTIME_ASSET_BYTES) {
|
|
386
|
+
constructor(worker, runtime, config, progress, maxAssetBytes = MAX_RUNTIME_ASSET_BYTES, languageSysroots = false) {
|
|
318
387
|
this.worker = worker;
|
|
319
388
|
this.runtime = runtime;
|
|
320
389
|
this.config = config;
|
|
321
390
|
this.maxAssetBytes = requireBridgeMaxAssetBytes(maxAssetBytes);
|
|
322
|
-
this.
|
|
323
|
-
this.
|
|
391
|
+
this.languageSysroots = canUseClangLanguageSysroots(runtime, config, languageSysroots);
|
|
392
|
+
this.progress = new RuntimeLoadProgress(runtime, this.languageSysroots);
|
|
393
|
+
this.expectedAssets = expectedAssetsForRuntime(runtime, this.languageSysroots);
|
|
324
394
|
this.progress.reset(progress);
|
|
325
395
|
}
|
|
326
|
-
matches(config, maxAssetBytes = this.maxAssetBytes) {
|
|
396
|
+
matches(config, maxAssetBytes = this.maxAssetBytes, languageSysroots = this.languageSysroots) {
|
|
327
397
|
return (this.state === 'active' &&
|
|
398
|
+
this.languageSysroots ===
|
|
399
|
+
canUseClangLanguageSysroots(this.runtime, config, languageSysroots) &&
|
|
328
400
|
this.maxAssetBytes === requireBridgeMaxAssetBytes(maxAssetBytes) &&
|
|
329
401
|
this.config.baseUrl === config.baseUrl &&
|
|
330
402
|
this.config.loader === config.loader &&
|
|
@@ -332,7 +404,7 @@ export class WorkerAssetBridge {
|
|
|
332
404
|
allowedBaseUrlsKey(this.config) === allowedBaseUrlsKey(config) &&
|
|
333
405
|
this.config.useAssetBridge === config.useAssetBridge);
|
|
334
406
|
}
|
|
335
|
-
rebind(worker, config, progress, maxAssetBytes = this.maxAssetBytes) {
|
|
407
|
+
rebind(worker, config, progress, maxAssetBytes = this.maxAssetBytes, languageSysroots = this.languageSysroots) {
|
|
336
408
|
if (this.state === 'disposed') {
|
|
337
409
|
throw new Error('Cannot rebind a disposed worker asset bridge');
|
|
338
410
|
}
|
|
@@ -340,7 +412,8 @@ export class WorkerAssetBridge {
|
|
|
340
412
|
throw new Error('Cannot rebind a worker asset bridge while another rebind is active');
|
|
341
413
|
}
|
|
342
414
|
const nextMaxAssetBytes = requireBridgeMaxAssetBytes(maxAssetBytes);
|
|
343
|
-
const
|
|
415
|
+
const nextLanguageSysroots = canUseClangLanguageSysroots(this.runtime, config, languageSysroots);
|
|
416
|
+
const preservePythonPackageAssets = this.matches(config, nextMaxAssetBytes, nextLanguageSysroots);
|
|
344
417
|
this.state = 'rebinding';
|
|
345
418
|
const generation = ++this.generation;
|
|
346
419
|
this.progress.reset();
|
|
@@ -354,6 +427,9 @@ export class WorkerAssetBridge {
|
|
|
354
427
|
this.worker = worker;
|
|
355
428
|
this.config = config;
|
|
356
429
|
this.maxAssetBytes = nextMaxAssetBytes;
|
|
430
|
+
this.languageSysroots = nextLanguageSysroots;
|
|
431
|
+
this.expectedAssets = expectedAssetsForRuntime(this.runtime, nextLanguageSysroots);
|
|
432
|
+
this.progress = new RuntimeLoadProgress(this.runtime, nextLanguageSysroots);
|
|
357
433
|
this.progress.reset(progress);
|
|
358
434
|
if (this.state !== 'rebinding' || this.generation !== generation) {
|
|
359
435
|
throw new Error('Cannot rebind a disposed worker asset bridge');
|
|
@@ -30,6 +30,8 @@ export interface RuntimeAssetConfig {
|
|
|
30
30
|
loaderKey?: string;
|
|
31
31
|
integrity?: RuntimeAssetIntegrityMap;
|
|
32
32
|
allowedBaseUrls?: string[];
|
|
33
|
+
/** Opt in to the pinned C/C++ sysroot split only for the built-in Clang asset profile. */
|
|
34
|
+
bundledLanguageSysroots?: boolean;
|
|
33
35
|
}
|
|
34
36
|
export interface RustRuntimeAssetConfig {
|
|
35
37
|
compilerUrl?: string;
|
|
@@ -89,6 +91,8 @@ export interface ErlangRuntimeAssetConfig {
|
|
|
89
91
|
}
|
|
90
92
|
export interface TypeScriptRuntimeAssetConfig {
|
|
91
93
|
moduleUrl?: string;
|
|
94
|
+
/** Optional official JavaScript-only bundle; must match its generated receipt. */
|
|
95
|
+
javascriptModuleUrl?: string;
|
|
92
96
|
libUrl?: string;
|
|
93
97
|
}
|
|
94
98
|
export interface WatRuntimeAssetConfig {
|
|
@@ -142,6 +146,8 @@ export interface ResolvedLispRuntimeAssetConfig {
|
|
|
142
146
|
manifestFingerprint: string;
|
|
143
147
|
}
|
|
144
148
|
export interface RubyRuntimeAssetConfig {
|
|
149
|
+
/** Keep full stdlib compatibility, but load its data separately from the core Wasm. */
|
|
150
|
+
splitStdlib?: boolean;
|
|
145
151
|
baseUrl?: string;
|
|
146
152
|
manifestUrl?: string;
|
|
147
153
|
moduleUrl?: string;
|
|
@@ -159,6 +165,7 @@ export interface RubyRuntimeAssetConfig {
|
|
|
159
165
|
wasmReceipt?: RuntimeAssetIntegrityEntry;
|
|
160
166
|
}
|
|
161
167
|
export interface ResolvedRubyRuntimeAssetConfig {
|
|
168
|
+
splitStdlib?: boolean;
|
|
162
169
|
baseUrl: string;
|
|
163
170
|
manifestUrl: string;
|
|
164
171
|
moduleUrl: string;
|
|
@@ -765,6 +765,7 @@ function snapshotRubyRuntimeAssetConfig(options) {
|
|
|
765
765
|
const snapshot = {};
|
|
766
766
|
for (const key of RUBY_RUNTIME_CONFIG_KEYS)
|
|
767
767
|
snapshot[key] = source[key];
|
|
768
|
+
snapshot.splitStdlib = source.splitStdlib;
|
|
768
769
|
return Object.freeze(snapshot);
|
|
769
770
|
}
|
|
770
771
|
function resolveRubyBaseUrlFromSnapshot(options, configured, currentUrl = '') {
|
|
@@ -784,6 +785,10 @@ export function resolveRubyBaseUrl(options, currentUrl = '') {
|
|
|
784
785
|
}
|
|
785
786
|
export function resolveRubyRuntimeAssetConfig(options, currentUrl = '') {
|
|
786
787
|
const configured = snapshotRubyRuntimeAssetConfig(options);
|
|
788
|
+
if (configured?.splitStdlib !== undefined && typeof configured.splitStdlib !== 'boolean')
|
|
789
|
+
throw new RuntimeConfigurationError('Ruby splitStdlib must be a boolean', {
|
|
790
|
+
runtimeId: 'RUBY'
|
|
791
|
+
});
|
|
787
792
|
const publicModuleUrl = (publicEnv.PUBLIC_WASM_RUBY_MODULE_URL || '').trim();
|
|
788
793
|
const publicWasmUrl = (publicEnv.PUBLIC_WASM_RUBY_WASM_URL || '').trim();
|
|
789
794
|
const usesCustomTrustBoundary = Boolean((configured && RUBY_RUNTIME_CONFIG_KEYS.some((key) => configured[key] !== undefined)) ||
|
|
@@ -810,6 +815,10 @@ export function resolveRubyRuntimeAssetConfig(options, currentUrl = '') {
|
|
|
810
815
|
catch (cause) {
|
|
811
816
|
throw new RuntimeConfigurationError('Ruby runtime custom assets require one complete profile and receipt bundle.', { cause, runtimeId: 'RUBY' });
|
|
812
817
|
}
|
|
818
|
+
if (configured?.splitStdlib &&
|
|
819
|
+
JSON.stringify(preflightProfile) !==
|
|
820
|
+
JSON.stringify(snapshotRubyRuntimePreflightProfile(RUBY_RUNTIME_BUNDLE.profile)))
|
|
821
|
+
throw new RuntimeConfigurationError('Ruby split stdlib is supported only for the bundled profile', { runtimeId: 'RUBY' });
|
|
813
822
|
const baseUrl = resolveRubyBaseUrlFromSnapshot(options, configured, currentUrl);
|
|
814
823
|
const resolvePinnedUrl = (configuredUrl, path, pin) => {
|
|
815
824
|
const sentinelOrigin = 'https://wasm-idle.invalid';
|
|
@@ -845,11 +854,13 @@ export function resolveRubyRuntimeAssetConfig(options, currentUrl = '') {
|
|
|
845
854
|
const moduleUrl = resolvePinnedUrl(configured?.moduleUrl || publicModuleUrl, RUBY_RUNTIME_MODULE_STORAGE_PATH, preflightProfile.moduleJavaScriptReceipt.sha256);
|
|
846
855
|
const wasmUrl = resolvePinnedUrl(configured?.wasmUrl || publicWasmUrl, RUBY_RUNTIME_WASM_STORAGE_PATH, preflightProfile.wasmReceipt.sha256);
|
|
847
856
|
return {
|
|
857
|
+
...(configured?.splitStdlib === true ? { splitStdlib: true } : {}),
|
|
848
858
|
baseUrl,
|
|
849
859
|
manifestUrl,
|
|
850
860
|
moduleUrl,
|
|
851
861
|
wasmUrl,
|
|
852
862
|
preflightKey: JSON.stringify({
|
|
863
|
+
...(configured?.splitStdlib === true ? { splitStdlib: true } : {}),
|
|
853
864
|
baseUrl,
|
|
854
865
|
manifestUrl,
|
|
855
866
|
moduleUrl,
|
package/dist/playground/clang.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { shouldStreamBundledClang } from './clangStreamingPolicy';
|
|
1
2
|
import { WorkerAssetBridge } from './assetBridge';
|
|
2
3
|
import { resolveDebugRuntimeUrls, resolveRuntimeAssetConfig } from './assets';
|
|
3
4
|
import { LldbSandboxSession } from './lldbSession';
|
|
@@ -88,9 +89,13 @@ class Clang {
|
|
|
88
89
|
this.debugRuntimeBaseUrl = debugRuntime.baseUrl;
|
|
89
90
|
this.debugManifestUrl = debugRuntime.manifestUrl;
|
|
90
91
|
this.debugManifestReceipt = debugRuntime.manifestReceipt;
|
|
92
|
+
const bundledAssets = shouldStreamBundledClang(assetConfig);
|
|
93
|
+
const languageSysrootProfiles = bundledAssets &&
|
|
94
|
+
typeof runtimeAssets !== 'string' &&
|
|
95
|
+
runtimeAssets.clang?.bundledLanguageSysroots === true;
|
|
91
96
|
const needsWorkerReset = !this.worker ||
|
|
92
97
|
!this.assetBridge ||
|
|
93
|
-
!this.assetBridge.matches(assetConfig, limits.maxAssetBytes);
|
|
98
|
+
!this.assetBridge.matches(assetConfig, limits.maxAssetBytes, languageSysrootProfiles);
|
|
94
99
|
if (needsWorkerReset && this.worker) {
|
|
95
100
|
this.workerSession.reset();
|
|
96
101
|
}
|
|
@@ -102,7 +107,7 @@ class Clang {
|
|
|
102
107
|
if (!this.workerSession.attach(worker, operation))
|
|
103
108
|
return;
|
|
104
109
|
this.worker = worker;
|
|
105
|
-
this.assetBridge = new WorkerAssetBridge(this.worker, 'clang', assetConfig, progress, limits.maxAssetBytes);
|
|
110
|
+
this.assetBridge = new WorkerAssetBridge(this.worker, 'clang', assetConfig, progress, limits.maxAssetBytes, languageSysrootProfiles);
|
|
106
111
|
this.worker.onmessage = (event) => {
|
|
107
112
|
if (!this.workerSession.isActive(operation))
|
|
108
113
|
return;
|
|
@@ -116,6 +121,8 @@ class Clang {
|
|
|
116
121
|
};
|
|
117
122
|
this.worker.postMessage({
|
|
118
123
|
load: true,
|
|
124
|
+
verifiedStreaming: bundledAssets,
|
|
125
|
+
languageSysrootProfiles,
|
|
119
126
|
log,
|
|
120
127
|
code,
|
|
121
128
|
args,
|
|
@@ -128,7 +135,7 @@ class Clang {
|
|
|
128
135
|
});
|
|
129
136
|
}
|
|
130
137
|
else {
|
|
131
|
-
this.assetBridge?.rebind(this.worker, assetConfig, progress, limits.maxAssetBytes);
|
|
138
|
+
this.assetBridge?.rebind(this.worker, assetConfig, progress, limits.maxAssetBytes, languageSysrootProfiles);
|
|
132
139
|
this.worker.postMessage({ log });
|
|
133
140
|
resolve();
|
|
134
141
|
}
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
export declare const BUNDLED_CLANG_LANGUAGE_SYSROOT_PROFILES: Readonly<{
|
|
2
|
+
c: Readonly<{
|
|
3
|
+
asset: "bin/c-sysroot.tar.gz";
|
|
4
|
+
}>;
|
|
5
|
+
cppAddon: Readonly<{
|
|
6
|
+
asset: "bin/cpp-addon.tar.gz";
|
|
7
|
+
}>;
|
|
8
|
+
}>;
|
|
1
9
|
export declare const BUNDLED_CLANG_ASSET_INTEGRITY: Readonly<{
|
|
2
10
|
'runtime-manifest.v1.json': Readonly<{
|
|
3
11
|
bytes: number;
|
|
@@ -29,4 +37,22 @@ export declare const BUNDLED_CLANG_ASSET_INTEGRITY: Readonly<{
|
|
|
29
37
|
uncompressedBytes: number;
|
|
30
38
|
uncompressedSha256: string;
|
|
31
39
|
}>;
|
|
40
|
+
'bin/c-sysroot.tar.gz': Readonly<{
|
|
41
|
+
bytes: number;
|
|
42
|
+
sha256: string;
|
|
43
|
+
uncompressedBytes: number;
|
|
44
|
+
uncompressedSha256: string;
|
|
45
|
+
}>;
|
|
46
|
+
'bin/cpp-addon.tar.gz': Readonly<{
|
|
47
|
+
bytes: number;
|
|
48
|
+
sha256: string;
|
|
49
|
+
uncompressedBytes: number;
|
|
50
|
+
uncompressedSha256: string;
|
|
51
|
+
}>;
|
|
52
|
+
'language-sysroots.v1.json': Readonly<{
|
|
53
|
+
bytes: number;
|
|
54
|
+
sha256: string;
|
|
55
|
+
uncompressedBytes: number;
|
|
56
|
+
uncompressedSha256: string;
|
|
57
|
+
}>;
|
|
32
58
|
}>;
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
const integrityEntry = (bytes, sha256, uncompressedBytes = bytes, uncompressedSha256 = sha256) => Object.freeze({ bytes, sha256, uncompressedBytes, uncompressedSha256 });
|
|
2
|
+
export const BUNDLED_CLANG_LANGUAGE_SYSROOT_PROFILES = Object.freeze({
|
|
3
|
+
c: Object.freeze({ asset: 'bin/c-sysroot.tar.gz' }),
|
|
4
|
+
cppAddon: Object.freeze({ asset: 'bin/cpp-addon.tar.gz' })
|
|
5
|
+
});
|
|
2
6
|
export const BUNDLED_CLANG_ASSET_INTEGRITY = Object.freeze({
|
|
3
7
|
'runtime-manifest.v1.json': integrityEntry(876, '1420808d0391ff2d8a2fdf2a9f6bbce8f728e06b1ed1651029ed80b226101444'),
|
|
4
8
|
'bin/memfs.wasm.gz': integrityEntry(18_974, 'd86f141eacd58a93511fbfb7c4e81d498eb7106a8a57df1bea7d33df3ce1f403', 345_442, '2c72ee42bd9430029dda8c6bafc9f37143f6fe88d5f1ea950a70259ab748bcfe'),
|
|
5
|
-
'bin/clang.wasm.gz': integrityEntry(
|
|
6
|
-
'bin/lld.wasm.gz': integrityEntry(
|
|
7
|
-
'bin/sysroot.tar.gz': integrityEntry(
|
|
9
|
+
'bin/clang.wasm.gz': integrityEntry(13_121_917, '8dc032057fbeb41e4a9986dfc54b2336c17532033dee172eb0095eba9c5fbe75', 35_658_969, 'd92ef06cdd3fea88acf384db15a6f2a344790c05bcba8e9f13f5b75b36ad4a99'),
|
|
10
|
+
'bin/lld.wasm.gz': integrityEntry(6_417_339, '495813efde8f354c38483749cdface7a7d9e23c8411da45a6f5f80030159eb11', 16_171_013, '34d39bc410c098e7e09933b61cc8e28699447af9a28abf4544d71b6e9cad1f9d'),
|
|
11
|
+
'bin/sysroot.tar.gz': integrityEntry(5_059_493, 'c0ef46e903492383a3c7069bfd4aed0e764e8df988f92bb81eb96bea50bf2c00', 19_312_640, 'e122f1acec0642d62d8976101c542aaa5346460df6eae5a3f8efb594ff32f5ae'),
|
|
12
|
+
'bin/c-sysroot.tar.gz': integrityEntry(1_216_797, 'fb3e1cdacac3eceddcfe2e57cbbf78e593ec2a298f01acb61c06e4b9d24fbbee', 3_736_064, '720c620e459025e918747768b9f5f1aef7b48c6df1b34c1a31fb2e5b1b7a213e'),
|
|
13
|
+
'bin/cpp-addon.tar.gz': integrityEntry(3_840_608, '47e9946c5aaeb3b35a1d42d6a80eae8987c596f4f858b207e492c00d8680af9e', 15_572_992, '7d61b724d377dc4e5670725055fb2884ebc8153d697e05093992004d5859310d'),
|
|
14
|
+
'language-sysroots.v1.json': integrityEntry(175_348, 'd69acbdb636009dc5b2243f13f1580264f64a34362f0af67c9cd661388b565d0')
|
|
8
15
|
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { BUNDLED_CLANG_ASSET_INTEGRITY } from './clangAssetIntegrity';
|
|
2
|
+
/** A custom loader or custom trust profile must keep using the asset bridge. */
|
|
3
|
+
export function shouldStreamBundledClang(config) {
|
|
4
|
+
return (!config.loader &&
|
|
5
|
+
config.allowedBaseUrls === undefined &&
|
|
6
|
+
config.integrity === BUNDLED_CLANG_ASSET_INTEGRITY);
|
|
7
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { BoundSandbox, PlaygroundBinding, Sandbox, SandboxRuntimeAssets } from './sandbox';
|
|
2
|
+
import { type PlaygroundBindingOptions } from '@wasm-idle/core';
|
|
2
3
|
export declare const supportedLanguages: ("C" | "CPP" | "OBJC" | "D" | "TINYGO" | "RUBY" | "PERL" | "TCL" | "AWK" | "PASCAL" | "JANET" | "JULIA" | "NIM" | "BASH" | "BQN" | "CLOJURESCRIPT" | "FORTH" | "J" | "PROLOG" | "C3" | "PYTHON3" | "JAVA" | "RUST" | "GO" | "CSHARP" | "FSHARP" | "VBNET" | "ELIXIR" | "ERLANG" | "GLEAM" | "FORTRAN" | "LFORTRAN" | "COBOL" | "OCAML" | "JAVASCRIPT" | "TYPESCRIPT" | "ASSEMBLYSCRIPT" | "WAT" | "WASM" | "LUA" | "ZIG" | "LISP" | "HASKELL" | "R" | "OCTAVE" | "DUCKDB" | "SQLITE" | "PHP")[];
|
|
3
|
-
export declare function createPlaygroundBinding(runtimeAssets: SandboxRuntimeAssets): PlaygroundBinding;
|
|
4
|
+
export declare function createPlaygroundBinding(runtimeAssets: SandboxRuntimeAssets, options?: PlaygroundBindingOptions): PlaygroundBinding;
|
|
4
5
|
declare function playground(language: string): Promise<Sandbox>;
|
|
5
6
|
declare function playground(language: string, runtimeAssets: SandboxRuntimeAssets): Promise<BoundSandbox>;
|
|
6
7
|
export default playground;
|
package/dist/playground/index.js
CHANGED
|
@@ -350,8 +350,8 @@ for (const languageId of supportedLanguageIds) {
|
|
|
350
350
|
}
|
|
351
351
|
}
|
|
352
352
|
export const supportedLanguages = [...supportedLanguageIds];
|
|
353
|
-
export function createPlaygroundBinding(runtimeAssets) {
|
|
354
|
-
return createCorePlaygroundBinding(runtimeAssets, playground);
|
|
353
|
+
export function createPlaygroundBinding(runtimeAssets, options = {}) {
|
|
354
|
+
return createCorePlaygroundBinding(runtimeAssets, playground, options);
|
|
355
355
|
}
|
|
356
356
|
async function playground(language, runtimeAssets) {
|
|
357
357
|
const normalizedLanguage = normalizeLanguageId(language);
|
package/dist/playground/java.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolveSandboxExecutionArgs } from './options';
|
|
2
2
|
import { WorkerAssetBridge } from './assetBridge';
|
|
3
3
|
import { resolveRuntimeAssetConfig } from './assets';
|
|
4
|
-
import { AssetTooLargeError, BusyError, CancelledError, DEFAULT_WORKSPACE_LIMITS, DiagnosticLimitError, OutputLimitError, RuntimeConfigurationError, TEAVM_RUNTIME_ASSET_NAMES, TimeoutError, resolveExecutionLimits, validateExecutionWorkspace } from '@wasm-idle/core';
|
|
4
|
+
import { AssetTooLargeError, BusyError, CancelledError, DEFAULT_WORKSPACE_LIMITS, DiagnosticLimitError, OutputLimitError, RuntimeConfigurationError, TEAVM_RUNTIME_ASSET_NAMES, TEAVM_RUNTIME_ASSET_RECEIPTS, TimeoutError, resolveExecutionLimits, validateExecutionWorkspace } from '@wasm-idle/core';
|
|
5
5
|
import { resolveJavaSourceIdentity } from './javaSource';
|
|
6
6
|
import { flushBufferedEof, flushQueuedStdin, resetBufferedStdin } from './stdinBuffer';
|
|
7
7
|
import { createWasmIdleSharedBuffer } from './sharedBuffer';
|
|
@@ -447,7 +447,13 @@ class Java {
|
|
|
447
447
|
load: true,
|
|
448
448
|
assets: {
|
|
449
449
|
baseUrl: assetConfig.baseUrl,
|
|
450
|
-
useAssetBridge: assetConfig.useAssetBridge
|
|
450
|
+
useAssetBridge: assetConfig.useAssetBridge,
|
|
451
|
+
maxAssetBytes: limits.maxAssetBytes,
|
|
452
|
+
streamCompiler: !assetConfig.loader && TEAVM_RUNTIME_ASSET_NAMES.every((asset) => {
|
|
453
|
+
const receipt = assetConfig.integrity?.[asset];
|
|
454
|
+
const expected = TEAVM_RUNTIME_ASSET_RECEIPTS[asset];
|
|
455
|
+
return typeof receipt === 'object' && receipt.bytes === expected.bytes && receipt.sha256 === expected.sha256;
|
|
456
|
+
})
|
|
451
457
|
}
|
|
452
458
|
});
|
|
453
459
|
}
|