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.
Files changed (46) hide show
  1. package/README.md +46 -5
  2. package/dist/index.d.ts +1 -0
  3. package/dist/playground/applicationAssets.js +4 -1
  4. package/dist/playground/assetBridge.d.ts +6 -5
  5. package/dist/playground/assetBridge.js +85 -9
  6. package/dist/playground/assets.d.ts +7 -0
  7. package/dist/playground/assets.js +11 -0
  8. package/dist/playground/clang.js +10 -3
  9. package/dist/playground/clangAssetIntegrity.d.ts +26 -0
  10. package/dist/playground/clangAssetIntegrity.js +10 -3
  11. package/dist/playground/clangStreamingPolicy.d.ts +6 -0
  12. package/dist/playground/clangStreamingPolicy.js +7 -0
  13. package/dist/playground/dotnet.js +2 -1
  14. package/dist/playground/index.d.ts +2 -1
  15. package/dist/playground/index.js +2 -2
  16. package/dist/playground/java.js +8 -2
  17. package/dist/playground/loadingProgress.js +2 -1
  18. package/dist/playground/ruby.js +52 -30
  19. package/dist/playground/rubyAssets.d.ts +4 -4
  20. package/dist/playground/rubyAssets.js +10 -3
  21. package/dist/playground/sandbox.d.ts +4 -0
  22. package/dist/playground/staticRuntimeModuleVersion.d.ts +1 -1
  23. package/dist/playground/staticRuntimeModuleVersion.js +1 -1
  24. package/dist/playground/typescript.js +18 -5
  25. package/dist/playground/wasmDotnetVersion.d.ts +1 -1
  26. package/dist/playground/wasmDotnetVersion.js +1 -1
  27. package/dist/playground/wasmGoVersion.d.ts +1 -1
  28. package/dist/playground/wasmGoVersion.js +1 -1
  29. package/dist/playground/wasmRustVersion.d.ts +66 -12
  30. package/dist/playground/wasmRustVersion.js +71 -11
  31. package/dist/playground/wasmTypeScriptVersion.d.ts +7 -3
  32. package/dist/playground/wasmTypeScriptVersion.js +7 -3
  33. package/dist/playground/worker/assets.js +34 -7
  34. package/dist/playground/worker/boundedAssetResponse.d.ts +14 -0
  35. package/dist/playground/worker/boundedAssetResponse.js +148 -0
  36. package/dist/playground/worker/clang.js +21 -4
  37. package/dist/playground/worker/clangStreaming.d.ts +3 -0
  38. package/dist/playground/worker/clangStreaming.js +41 -0
  39. package/dist/playground/worker/dotnet.js +2 -0
  40. package/dist/playground/worker/java.js +55 -20
  41. package/dist/playground/worker/javaStreaming.d.ts +9 -0
  42. package/dist/playground/worker/javaStreaming.js +99 -0
  43. package/dist/playground/worker/php.js +52 -12
  44. package/dist/playground/worker/python.js +37 -9
  45. package/dist/playground/worker/ruby.js +207 -56
  46. 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.0 / 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.0 / 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.0 | `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` |
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.0 | 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.0 | 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` |
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/runtime.mjs', STATIC_RUNTIME_MODULE_VERSION)
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 readonly progress;
9
- private readonly expectedAssets;
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 expectedAssetsForRuntime = (runtime) => new Set(RUNTIME_LOAD_ASSETS[runtime]);
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.progress = new RuntimeLoadProgress(runtime);
323
- this.expectedAssets = expectedAssetsForRuntime(runtime);
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 preservePythonPackageAssets = this.matches(config, nextMaxAssetBytes);
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,
@@ -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(15_721_977, 'b1174438d9a67b7ff11e623541b9a0572c024a9e798084b9b021dd9da2da0874', 44_159_206, '60747a8272f337195c961fb7b7140f0789360267845016f1abb026f056aad083'),
6
- 'bin/lld.wasm.gz': integrityEntry(7_837_837, 'f842a9b5df3c6d326f0260bfd313c11c2e22bc8b8ae0387deede9a4af55779cd', 20_795_796, '14f08c475b24ef45313cab7a086693525955c2c000b833faaaf48ad35b2521f8'),
7
- 'bin/sysroot.tar.gz': integrityEntry(5_059_892, '68437624a81c465b93895615e7afd3f235ff256de17dc1927b124e783614e3e4', 19_312_640, '963478e663d6ee2a3ae418ce7427f4535fb59831bb933f95938ccb2253cbb388')
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,6 @@
1
+ /** A custom loader or custom trust profile must keep using the asset bridge. */
2
+ export declare function shouldStreamBundledClang(config: {
3
+ loader?: unknown;
4
+ integrity?: unknown;
5
+ allowedBaseUrls?: readonly string[];
6
+ }): boolean;
@@ -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
+ }
@@ -443,7 +443,8 @@ class Dotnet {
443
443
  };
444
444
  worker.postMessage({
445
445
  load: true,
446
- moduleUrl: nextModuleUrl
446
+ moduleUrl: nextModuleUrl,
447
+ language: this.compileLanguage
447
448
  });
448
449
  }
449
450
  else {
@@ -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;
@@ -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);
@@ -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
  }