wasm-idle 1.0.6 → 1.0.7
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 +18 -5
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/playground/assetBridge.d.ts +6 -1
- package/dist/playground/assetBridge.js +70 -4
- package/dist/playground/assets.d.ts +9 -1
- package/dist/playground/assets.js +29 -5
- package/dist/playground/awk.js +1 -0
- package/dist/playground/bash.d.ts +1 -0
- package/dist/playground/bash.js +7 -1
- package/dist/playground/bqn.js +1 -0
- package/dist/playground/bqnPreflight.d.ts +2 -1
- package/dist/playground/bqnPreflight.js +1 -0
- package/dist/playground/c3.js +1 -0
- package/dist/playground/cachedClang.js +15 -8
- package/dist/playground/clang.d.ts +1 -0
- package/dist/playground/clang.js +8 -1
- package/dist/playground/clojurescript.js +1 -0
- package/dist/playground/clojurescriptPreflight.d.ts +2 -1
- package/dist/playground/clojurescriptPreflight.js +1 -0
- package/dist/playground/elixir.js +4 -1
- package/dist/playground/forth.js +1 -0
- package/dist/playground/forthPreflight.d.ts +2 -1
- package/dist/playground/forthPreflight.js +1 -0
- package/dist/playground/fortran.js +7 -1
- package/dist/playground/haskell.js +4 -1
- package/dist/playground/haskellAssets.d.ts +2 -1
- package/dist/playground/haskellAssets.js +8 -8
- package/dist/playground/index.d.ts +1 -1
- package/dist/playground/index.js +2 -2
- package/dist/playground/j.js +1 -0
- package/dist/playground/jPreflight.d.ts +2 -1
- package/dist/playground/jPreflight.js +1 -0
- package/dist/playground/janet.js +1 -0
- package/dist/playground/java.js +20 -8
- package/dist/playground/julia.js +1 -0
- package/dist/playground/lfortranAssets.d.ts +2 -1
- package/dist/playground/lfortranAssets.js +1 -0
- package/dist/playground/lisp.js +4 -1
- package/dist/playground/lispAssets.d.ts +2 -1
- package/dist/playground/lispAssets.js +10 -0
- package/dist/playground/lldbManifest.d.ts +2 -2
- package/dist/playground/lldbManifest.js +17 -3
- package/dist/playground/lldbSession.d.ts +1 -0
- package/dist/playground/lldbSession.js +2 -1
- package/dist/playground/nim.js +1 -0
- package/dist/playground/ocaml.d.ts +1 -0
- package/dist/playground/ocaml.js +12 -1
- package/dist/playground/options.d.ts +2 -0
- package/dist/playground/pascal.js +1 -0
- package/dist/playground/perl.js +1 -0
- package/dist/playground/prolog.js +1 -0
- package/dist/playground/python.js +3 -1
- package/dist/playground/runtimeSession.d.ts +2 -1
- package/dist/playground/runtimeSession.js +2 -2
- package/dist/playground/rust.d.ts +1 -0
- package/dist/playground/rust.js +11 -1
- package/dist/playground/rustExecutableGraph.d.ts +1 -0
- package/dist/playground/rustExecutableGraph.js +1 -0
- package/dist/playground/staticRuntimePreflight.d.ts +2 -1
- package/dist/playground/staticRuntimePreflight.js +4 -2
- package/dist/playground/staticRuntimePreflightExecute.js +1 -0
- package/dist/playground/staticRuntimePreflightProtocol.d.ts +2 -1
- package/dist/playground/staticWorkerRuntime.d.ts +3 -1
- package/dist/playground/staticWorkerRuntime.js +44 -3
- package/dist/playground/tcl.js +1 -0
- package/dist/playground/tinygo.d.ts +2 -0
- package/dist/playground/tinygo.js +57 -3
- package/dist/playground/tinygoExecutableGraph.d.ts +4 -1
- package/dist/playground/tinygoExecutableGraph.js +59 -7
- package/dist/playground/typescript.js +4 -1
- package/dist/playground/wasmGoVersion.d.ts +1 -1
- package/dist/playground/wasmGoVersion.js +1 -1
- package/dist/playground/wasmOcamlVersion.d.ts +2 -2
- package/dist/playground/wasmOcamlVersion.js +1 -1
- package/dist/playground/wasmRustVersion.d.ts +90 -24
- package/dist/playground/wasmRustVersion.js +98 -23
- package/dist/playground/wasmTinyGoVersion.d.ts +40 -29
- package/dist/playground/wasmTinyGoVersion.js +43 -31
- package/dist/playground/worker/clang.js +1 -5
- package/dist/playground/worker/elixir.js +10 -8
- package/dist/playground/worker/fortran.js +4 -7
- package/dist/playground/worker/haskell.js +2 -0
- package/dist/playground/worker/lisp.js +2 -0
- package/dist/playground/worker/ocaml.js +13 -1
- package/dist/playground/worker/runtimeAssetFetch.d.ts +11 -1
- package/dist/playground/worker/runtimeAssetFetch.js +64 -1
- package/dist/playground/worker/rust.js +9 -2
- package/dist/playground/worker/staticRuntimePreflight.js +2 -0
- package/dist/playground/worker/typescript.js +4 -1
- package/dist/playground/worker/zig.js +7 -4
- package/dist/playground/zig.js +4 -1
- package/package.json +10 -7
package/README.md
CHANGED
|
@@ -15,6 +15,10 @@ Compiler source pins, patches, and reproducible asset builds live in
|
|
|
15
15
|
[`seo-rii/wasm-llvm`](https://github.com/seo-rii/wasm-llvm); wasm-idle loads the generated
|
|
16
16
|
artifacts from external URLs instead of embedding them in npm packages.
|
|
17
17
|
|
|
18
|
+
Verified downloads can be retained across reloads using a version-pinned, capacity-bounded
|
|
19
|
+
CacheStorage/IndexedDB cache. See [persistent asset cache configuration and coverage](docs/runtime-asset-cache.md)
|
|
20
|
+
for global/per-call opt-out, cleanup and prefetch APIs.
|
|
21
|
+
|
|
18
22
|
## Language support policy
|
|
19
23
|
|
|
20
24
|
wasm-idle language support must run user code through the real language implementation in the
|
|
@@ -221,9 +225,9 @@ when they exist.
|
|
|
221
225
|
| Language / IDs | Package/version base | Execution defaults / flags | Customization |
|
|
222
226
|
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
223
227
|
| 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.
|
|
228
|
+
| C<br>`C` | @wasm-idle/llvm-core@1.0.7 / 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` |
|
|
229
|
+
| C++<br>`CPP` | @wasm-idle/llvm-core@1.0.7 / 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` |
|
|
230
|
+
| Objective-C<br>`OBJC` | GNUstep libobjc2 v2.3 assets from the `wasm-llvm` producer + @wasm-idle/llvm-core@1.0.7 | `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
231
|
| 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
232
|
| 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
233
|
| 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 +265,8 @@ when they exist.
|
|
|
261
265
|
| 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
266
|
| 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
267
|
| 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.
|
|
268
|
+
| Fortran<br>`FORTRAN` | Netlib f2c 2022-09-09 + `@cowasm/f2c 1.0.0` libf2c + @wasm-idle/llvm-core@1.0.7 | 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` |
|
|
269
|
+
| COBOL<br>`COBOL` | GnuCOBOL 3.2 + GMP 6.3.0 assets from the `wasm-llvm` producer + @wasm-idle/llvm-core@1.0.7 | 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
270
|
| 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
271
|
| 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
272
|
| 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` |
|
|
@@ -323,6 +327,15 @@ toolchains can be consumed from pinned external runtime repositories:
|
|
|
323
327
|
normal runtime workspace packages. `tools/dool` contains the Docker judge backend for Elixir and
|
|
324
328
|
the other server-side language runners.
|
|
325
329
|
|
|
330
|
+
Deployment builds retain both legacy `.gz` and canonical `.gz.bin` URLs by default.
|
|
331
|
+
After building and compressing the page, `pnpm run compact:build-runtimes` reports
|
|
332
|
+
byte-identical duplicates without changing files. Add `--drop-legacy-aliases` to
|
|
333
|
+
remove those duplicate files and add compatibility routing to the generated service
|
|
334
|
+
worker. This only preserves legacy URLs in service-worker-controlled requests:
|
|
335
|
+
external SDKs and uncontrolled first requests to the removed `.gz` URLs need to
|
|
336
|
+
migrate to `.gz.bin` or use server aliases. Opt in only after that migration. Source
|
|
337
|
+
assets and producer receipts stay intact; rerun compaction after each page build.
|
|
338
|
+
|
|
326
339
|
Useful workspace commands:
|
|
327
340
|
|
|
328
341
|
```bash
|
package/dist/index.d.ts
CHANGED
|
@@ -2,10 +2,11 @@ import playground, { createPlaygroundBinding } from './playground';
|
|
|
2
2
|
export default playground;
|
|
3
3
|
export { createPlaygroundBinding, playground };
|
|
4
4
|
export { createRuntimeSession } from './playground/runtimeSession';
|
|
5
|
+
export { configureRuntimeAssetCache, createRuntimeAssetCacheBackend, fetchPinnedRuntimeAsset, prefetchRuntimeAssets, resolveRuntimeAssetLockEntry, type PrefetchRuntimeAssetsOptions, type PrefetchRuntimeAssetsResult, type RuntimeAssetCacheStats, type RuntimeAssetCacheBackend, type RuntimeAssetCacheBackendIdentity, type PinnedRuntimeAssetRequest, getRuntimeAssetCacheOptions, getRuntimeAssetCacheStats, clearRuntimeAssetCache, pruneRuntimeAssetCache, requestRuntimeAssetCachePersistence, type RuntimeAssetCacheOptions } from '@wasm-idle/core';
|
|
5
6
|
export type { PlaygroundRuntimeSession } from './playground/runtimeSession';
|
|
6
7
|
export { isSharedArrayBufferAvailable, requireSharedArrayBuffer } from './playground/sharedBuffer';
|
|
7
8
|
export type { DebugCommand, DebugFrame, DebugSessionEvent, DebugVariable, TerminalControl } from '@wasm-idle/core';
|
|
8
9
|
export type { CompilerDiagnostic, SandboxExecutionOptions } from './playground/options';
|
|
9
10
|
export type { PlaygroundRuntimeAssets, RuntimeAssetConfig, RuntimeAssetLoadRequest, RuntimeAssetLoader, RuntimeAssetLoaderResult } from './playground/assets';
|
|
10
11
|
export type { BoundSandbox, PlaygroundBinding, PlaygroundTerminalProps, SandboxProgress, SandboxRuntimeAssets } from './playground/sandbox';
|
|
11
|
-
export type { PlaygroundBindingOptions } from
|
|
12
|
+
export type { PlaygroundBindingOptions } from '@wasm-idle/core';
|
package/dist/index.js
CHANGED
|
@@ -2,4 +2,5 @@ import playground, { createPlaygroundBinding } from './playground';
|
|
|
2
2
|
export default playground;
|
|
3
3
|
export { createPlaygroundBinding, playground };
|
|
4
4
|
export { createRuntimeSession } from './playground/runtimeSession';
|
|
5
|
+
export { configureRuntimeAssetCache, createRuntimeAssetCacheBackend, fetchPinnedRuntimeAsset, prefetchRuntimeAssets, resolveRuntimeAssetLockEntry, getRuntimeAssetCacheOptions, getRuntimeAssetCacheStats, clearRuntimeAssetCache, pruneRuntimeAssetCache, requestRuntimeAssetCachePersistence } from '@wasm-idle/core';
|
|
5
6
|
export { isSharedArrayBufferAvailable, requireSharedArrayBuffer } from './playground/sharedBuffer';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ResolvedRuntimeAssetConfig, type RuntimeAssetRuntime } from './assets';
|
|
2
|
-
import { type ProgressLike } from '@wasm-idle/core';
|
|
2
|
+
import { type RuntimeAssetCacheOptions, type ResolvedRuntimeAssetCacheOptions, type ProgressLike } from '@wasm-idle/core';
|
|
3
3
|
import { RuntimeAssetCache } from './runtimeAssetCache';
|
|
4
4
|
export declare const boundedUtf8ByteLength: (value: string, maxBytes?: number) => number;
|
|
5
5
|
export declare class WorkerAssetBridge {
|
|
@@ -7,6 +7,8 @@ export declare class WorkerAssetBridge {
|
|
|
7
7
|
private worker;
|
|
8
8
|
private readonly runtime;
|
|
9
9
|
private config;
|
|
10
|
+
private persistentCacheBaseline;
|
|
11
|
+
private readonly persistentCacheBySignal;
|
|
10
12
|
private progress;
|
|
11
13
|
private expectedAssets;
|
|
12
14
|
private languageSysroots;
|
|
@@ -17,6 +19,8 @@ export declare class WorkerAssetBridge {
|
|
|
17
19
|
private maxAssetBytes;
|
|
18
20
|
constructor(worker: Worker, runtime: RuntimeAssetRuntime, config: ResolvedRuntimeAssetConfig, progress?: ProgressLike, maxAssetBytes?: number, languageSysroots?: boolean, cache?: RuntimeAssetCache | undefined);
|
|
19
21
|
matches(config: ResolvedRuntimeAssetConfig, maxAssetBytes?: number, languageSysroots?: boolean): boolean;
|
|
22
|
+
/** Apply one execution's policy without changing the configuration established by load(). */
|
|
23
|
+
setExecutionPersistentCache(override?: RuntimeAssetCacheOptions): ResolvedRuntimeAssetCacheOptions;
|
|
20
24
|
rebind(worker: Worker, config: ResolvedRuntimeAssetConfig, progress?: ProgressLike, maxAssetBytes?: number, languageSysroots?: boolean): void;
|
|
21
25
|
dispose(): void;
|
|
22
26
|
resetProgress(progress?: ProgressLike): void;
|
|
@@ -31,6 +35,7 @@ export declare class WorkerAssetBridge {
|
|
|
31
35
|
private verifyIntegrity;
|
|
32
36
|
private normalizeLoaderResult;
|
|
33
37
|
private fetchAsset;
|
|
38
|
+
private fetchAssetFromNetwork;
|
|
34
39
|
private requireAllowedAssetUrl;
|
|
35
40
|
private abortActiveLoads;
|
|
36
41
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RUNTIME_LOAD_ASSETS } from './assets';
|
|
2
|
-
import { ProtocolError, verifyRuntimeAssetIntegrity, verifyRuntimeAssetPair } from '@wasm-idle/core';
|
|
2
|
+
import { ProtocolError, verifyRuntimeAssetIntegrity, verifyRuntimeAssetPair, readPersistentRuntimeAsset, writePersistentRuntimeAsset, resolveRuntimeAssetLockEntry, resolveRuntimeAssetCacheOptions } from '@wasm-idle/core';
|
|
3
3
|
import { decompressGzip } from '@wasm-idle/llvm-core';
|
|
4
4
|
import { readPythonPackageAssets } from './pythonPackageLock';
|
|
5
5
|
import { BUNDLED_CLANG_LANGUAGE_SYSROOT_PROFILES } from './clangAssetIntegrity';
|
|
@@ -379,6 +379,8 @@ export class WorkerAssetBridge {
|
|
|
379
379
|
worker;
|
|
380
380
|
runtime;
|
|
381
381
|
config;
|
|
382
|
+
persistentCacheBaseline;
|
|
383
|
+
persistentCacheBySignal = new WeakMap();
|
|
382
384
|
progress;
|
|
383
385
|
expectedAssets;
|
|
384
386
|
languageSysroots;
|
|
@@ -391,7 +393,8 @@ export class WorkerAssetBridge {
|
|
|
391
393
|
this.cache = cache;
|
|
392
394
|
this.worker = worker;
|
|
393
395
|
this.runtime = runtime;
|
|
394
|
-
this.
|
|
396
|
+
this.persistentCacheBaseline = resolveRuntimeAssetCacheOptions(config.persistentCache);
|
|
397
|
+
this.config = { ...config, persistentCache: this.persistentCacheBaseline };
|
|
395
398
|
this.maxAssetBytes = requireBridgeMaxAssetBytes(maxAssetBytes);
|
|
396
399
|
this.languageSysroots = canUseClangLanguageSysroots(runtime, config, languageSysroots);
|
|
397
400
|
this.progress = new RuntimeLoadProgress(runtime, this.languageSysroots);
|
|
@@ -407,7 +410,17 @@ export class WorkerAssetBridge {
|
|
|
407
410
|
this.config.loader === config.loader &&
|
|
408
411
|
integrityKey(this.config) === integrityKey(config) &&
|
|
409
412
|
allowedBaseUrlsKey(this.config) === allowedBaseUrlsKey(config) &&
|
|
410
|
-
this.config.useAssetBridge === config.useAssetBridge
|
|
413
|
+
this.config.useAssetBridge === config.useAssetBridge &&
|
|
414
|
+
JSON.stringify(this.persistentCacheBaseline) ===
|
|
415
|
+
JSON.stringify(resolveRuntimeAssetCacheOptions(config.persistentCache)));
|
|
416
|
+
}
|
|
417
|
+
/** Apply one execution's policy without changing the configuration established by load(). */
|
|
418
|
+
setExecutionPersistentCache(override) {
|
|
419
|
+
if (this.state !== 'active')
|
|
420
|
+
throw new Error('Cannot configure an inactive worker asset bridge');
|
|
421
|
+
const cache = resolveRuntimeAssetCacheOptions(this.persistentCacheBaseline, override);
|
|
422
|
+
this.config = { ...this.config, persistentCache: cache };
|
|
423
|
+
return cache;
|
|
411
424
|
}
|
|
412
425
|
rebind(worker, config, progress, maxAssetBytes = this.maxAssetBytes, languageSysroots = this.languageSysroots) {
|
|
413
426
|
if (this.state === 'disposed') {
|
|
@@ -430,7 +443,8 @@ export class WorkerAssetBridge {
|
|
|
430
443
|
throw new Error('Cannot rebind a disposed worker asset bridge');
|
|
431
444
|
}
|
|
432
445
|
this.worker = worker;
|
|
433
|
-
this.
|
|
446
|
+
this.persistentCacheBaseline = resolveRuntimeAssetCacheOptions(config.persistentCache);
|
|
447
|
+
this.config = { ...config, persistentCache: this.persistentCacheBaseline };
|
|
434
448
|
this.maxAssetBytes = nextMaxAssetBytes;
|
|
435
449
|
this.languageSysroots = nextLanguageSysroots;
|
|
436
450
|
this.expectedAssets = expectedAssetsForRuntime(this.runtime, nextLanguageSysroots);
|
|
@@ -525,6 +539,7 @@ export class WorkerAssetBridge {
|
|
|
525
539
|
const worker = this.worker;
|
|
526
540
|
const generation = this.generation;
|
|
527
541
|
const controller = new AbortController();
|
|
542
|
+
this.persistentCacheBySignal.set(controller.signal, resolveRuntimeAssetCacheOptions(this.config.persistentCache));
|
|
528
543
|
this.activeLoads.add(controller);
|
|
529
544
|
try {
|
|
530
545
|
this.validateAssetRequest(request.asset);
|
|
@@ -555,6 +570,7 @@ export class WorkerAssetBridge {
|
|
|
555
570
|
const receipt = BUNDLED_CLANG_ASSET_INTEGRITY[request.asset];
|
|
556
571
|
module = await compileVerifiedWasmAsset(new URL(request.asset, this.config.baseUrl).href, receipt, {
|
|
557
572
|
fetch: globalThis.fetch.bind(globalThis),
|
|
573
|
+
persistentCache: this.persistentCacheBySignal.get(controller.signal),
|
|
558
574
|
maxAssetBytes: this.maxAssetBytes,
|
|
559
575
|
signal: controller.signal,
|
|
560
576
|
onProgress: (loaded, total) => this.progress.update(request.asset, loaded, total)
|
|
@@ -831,6 +847,56 @@ export class WorkerAssetBridge {
|
|
|
831
847
|
return null;
|
|
832
848
|
}
|
|
833
849
|
async fetchAsset(url, asset, signal, maxAssetBytes = this.sourceAssetByteLimit(asset)) {
|
|
850
|
+
const requestUrl = this.requireAllowedAssetUrl(asset, url);
|
|
851
|
+
const persistentCache = this.persistentCacheBySignal.get(signal) ?? this.config.persistentCache;
|
|
852
|
+
const configured = this.config.integrity?.[asset];
|
|
853
|
+
const expected = typeof configured === 'string' ? { sha256: configured } : configured;
|
|
854
|
+
const lock = this.config.assetPrefix
|
|
855
|
+
? resolveRuntimeAssetLockEntry(requestUrl, {
|
|
856
|
+
assetRoot: this.config.baseUrl,
|
|
857
|
+
assetPrefix: this.config.assetPrefix
|
|
858
|
+
})
|
|
859
|
+
: undefined;
|
|
860
|
+
// Existing .gz receipts without a pair describe logical bytes, not stored gzip bytes.
|
|
861
|
+
const receipt = expected && (!asset.endsWith('.gz') || expected.uncompressedSha256) ? expected : lock;
|
|
862
|
+
const identity = receipt
|
|
863
|
+
? {
|
|
864
|
+
url: requestUrl.href,
|
|
865
|
+
sha256: receipt.sha256,
|
|
866
|
+
bytes: receipt.bytes,
|
|
867
|
+
validationKey: JSON.stringify([
|
|
868
|
+
'bridge-v1',
|
|
869
|
+
this.config.baseUrl,
|
|
870
|
+
allowedBaseUrlsKey(this.config),
|
|
871
|
+
maxAssetBytes
|
|
872
|
+
])
|
|
873
|
+
}
|
|
874
|
+
: undefined;
|
|
875
|
+
if (identity && (identity.bytes === undefined || identity.bytes <= maxAssetBytes)) {
|
|
876
|
+
const bytes = await readPersistentRuntimeAsset({
|
|
877
|
+
identity,
|
|
878
|
+
cache: persistentCache,
|
|
879
|
+
signal
|
|
880
|
+
});
|
|
881
|
+
if (bytes) {
|
|
882
|
+
requireRuntimeAssetSize(asset, bytes.byteLength, maxAssetBytes);
|
|
883
|
+
this.progress.update(asset, bytes.byteLength, bytes.byteLength);
|
|
884
|
+
return { bytes, mimeType: receipt?.mediaType, transferOwnership: true };
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
const loaded = await this.fetchAssetFromNetwork(url, asset, signal, maxAssetBytes);
|
|
888
|
+
if (identity && !loaded.contentEncoding) {
|
|
889
|
+
// Only checksum-matching bytes are published. Existing runtime validation still runs.
|
|
890
|
+
await writePersistentRuntimeAsset({
|
|
891
|
+
identity,
|
|
892
|
+
cache: persistentCache,
|
|
893
|
+
signal,
|
|
894
|
+
bytes: loaded.bytes
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
return loaded;
|
|
898
|
+
}
|
|
899
|
+
async fetchAssetFromNetwork(url, asset, signal, maxAssetBytes = this.sourceAssetByteLimit(asset)) {
|
|
834
900
|
const requestUrl = this.requireAllowedAssetUrl(asset, url);
|
|
835
901
|
if (signal.aborted)
|
|
836
902
|
throw runtimeAssetAbortReason(signal);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type RuntimeAssetCacheOptions } from '@wasm-idle/core';
|
|
1
2
|
import { type DOuterAssetReceipts } from './dOuterAssets';
|
|
2
3
|
import type { ElixirRuntimeAssetReceipts } from './elixirAssets';
|
|
3
4
|
import { type FortranExecutionAssetReceipts } from './fortranAssets';
|
|
@@ -25,6 +26,7 @@ export type RuntimeAssetLoader = (request: RuntimeAssetLoadRequest) => RuntimeAs
|
|
|
25
26
|
export type RuntimeAssetIntegrityEntry = CoreRuntimeAssetIntegrityEntry;
|
|
26
27
|
export type RuntimeAssetIntegrityMap = Record<string, string | RuntimeAssetIntegrityEntry>;
|
|
27
28
|
export interface RuntimeAssetConfig {
|
|
29
|
+
persistentCache?: import('@wasm-idle/core').RuntimeAssetCacheOptions;
|
|
28
30
|
baseUrl?: string;
|
|
29
31
|
loader?: RuntimeAssetLoader;
|
|
30
32
|
loaderKey?: string;
|
|
@@ -139,11 +141,14 @@ export interface LispRuntimeAssetConfig {
|
|
|
139
141
|
moduleUrl?: string;
|
|
140
142
|
manifestUrl?: string;
|
|
141
143
|
manifestFingerprint?: string;
|
|
144
|
+
/** Optional raw JSON byte receipt; distinct from the canonical manifest fingerprint. */
|
|
145
|
+
manifestReceipt?: RuntimeAssetIntegrityEntry;
|
|
142
146
|
}
|
|
143
147
|
export interface ResolvedLispRuntimeAssetConfig {
|
|
144
148
|
moduleUrl: string;
|
|
145
149
|
manifestUrl: string;
|
|
146
150
|
manifestFingerprint: string;
|
|
151
|
+
manifestReceipt?: RuntimeAssetIntegrityEntry;
|
|
147
152
|
}
|
|
148
153
|
export interface RubyRuntimeAssetConfig {
|
|
149
154
|
/** Keep full stdlib compatibility, but load its data separately from the core Wasm. */
|
|
@@ -563,6 +568,9 @@ export interface TinyGoRuntimeAssetLoaderRequest {
|
|
|
563
568
|
export type TinyGoRuntimeAssetLoaderResult = RuntimeAssetDataResult | RuntimeAssetUrlResult | string | URL | ArrayBuffer | Uint8Array | Blob | null | undefined;
|
|
564
569
|
export type TinyGoRuntimeAssetLoader = (request: TinyGoRuntimeAssetLoaderRequest) => TinyGoRuntimeAssetLoaderResult | Promise<TinyGoRuntimeAssetLoaderResult>;
|
|
565
570
|
export interface ResolvedRuntimeAssetConfig {
|
|
571
|
+
persistentCache?: import('@wasm-idle/core').RuntimeAssetCacheOptions;
|
|
572
|
+
/** Built-in lock prefix; custom loaders use only explicitly supplied receipts. */
|
|
573
|
+
assetPrefix?: string;
|
|
566
574
|
baseUrl: string;
|
|
567
575
|
loader?: RuntimeAssetLoader;
|
|
568
576
|
integrity?: RuntimeAssetIntegrityMap;
|
|
@@ -607,7 +615,7 @@ export declare const RUNTIME_LOAD_ASSETS: {
|
|
|
607
615
|
clang: readonly ["runtime-manifest.v1.json", "bin/memfs.wasm.gz", "bin/clang.wasm.gz", "bin/lld.wasm.gz", "bin/sysroot.tar.gz"];
|
|
608
616
|
clangd: readonly ["clangd.js", "clangd.wasm.gz"];
|
|
609
617
|
};
|
|
610
|
-
export declare function resolveRuntimeAssetConfig(runtime: RuntimeAssetRuntime, options: string | PlaygroundRuntimeAssets | undefined, currentUrl?: string): ResolvedRuntimeAssetConfig;
|
|
618
|
+
export declare function resolveRuntimeAssetConfig(runtime: RuntimeAssetRuntime, options: string | PlaygroundRuntimeAssets | undefined, currentUrl?: string, callCache?: RuntimeAssetCacheOptions): ResolvedRuntimeAssetConfig;
|
|
611
619
|
export declare function resolveRustCompilerUrl(options: string | PlaygroundRuntimeAssets | undefined, currentUrl?: string): string;
|
|
612
620
|
export declare function resolveDebugRuntimeUrls(options: string | PlaygroundRuntimeAssets | undefined, currentUrl?: string): {
|
|
613
621
|
baseUrl: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { env as dynamicPublicEnv } from '$env/dynamic/public';
|
|
2
|
+
import { resolveRuntimeAssetCacheOptions, resolveRuntimeAssetLockEntry } from '@wasm-idle/core';
|
|
2
3
|
import { BUNDLED_CLANG_ASSET_INTEGRITY } from './clangAssetIntegrity';
|
|
3
4
|
import { snapshotDOuterAssetConfig } from './dOuterAssets';
|
|
4
5
|
import { snapshotFortranExecutionAssetReceipts } from './fortranAssets';
|
|
@@ -100,7 +101,21 @@ const RUNTIME_ASSET_FOLDERS = {
|
|
|
100
101
|
const resolveRuntimeRootBaseUrl = (config, rootUrl = '', currentUrl = '') => config.resolveRootBaseUrl?.(rootUrl, currentUrl) ||
|
|
101
102
|
resolveFolderRuntimeBaseUrl(config.folder, rootUrl, currentUrl);
|
|
102
103
|
const resolveRuntimeConfiguredBaseUrl = (config, baseUrl, currentUrl = '') => config.resolveConfiguredBaseUrl?.(baseUrl, currentUrl) || normalizeBaseUrl(baseUrl, currentUrl);
|
|
103
|
-
export function resolveRuntimeAssetConfig(runtime, options, currentUrl = '') {
|
|
104
|
+
export function resolveRuntimeAssetConfig(runtime, options, currentUrl = '', callCache) {
|
|
105
|
+
const config = resolveRuntimeAssetConfigWithoutCache(runtime, options, currentUrl);
|
|
106
|
+
const runtimeConfig = typeof options === 'object' ? options?.[runtime] : undefined;
|
|
107
|
+
const persistentCache = resolveRuntimeAssetCacheOptions(typeof options === 'object' ? options?.persistentCache : undefined, runtimeConfig?.persistentCache, callCache);
|
|
108
|
+
const assetPrefix = !config.loader && !runtimeConfig?.baseUrl
|
|
109
|
+
? RUNTIME_ASSET_FOLDERS[runtime].folder
|
|
110
|
+
: undefined;
|
|
111
|
+
return {
|
|
112
|
+
...config,
|
|
113
|
+
persistentCache,
|
|
114
|
+
assetPrefix,
|
|
115
|
+
useAssetBridge: config.useAssetBridge || (persistentCache.enabled && !!assetPrefix)
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function resolveRuntimeAssetConfigWithoutCache(runtime, options, currentUrl = '') {
|
|
104
119
|
const runtimeFolder = RUNTIME_ASSET_FOLDERS[runtime];
|
|
105
120
|
if (typeof options === 'string') {
|
|
106
121
|
const integrity = resolveRuntimeAssetIntegrity(runtime, undefined);
|
|
@@ -733,12 +748,21 @@ export function resolveLispRuntimeAssetConfig(options, currentUrl = '') {
|
|
|
733
748
|
const configuredFingerprint = configured?.manifestFingerprint?.trim() ||
|
|
734
749
|
(publicEnv.PUBLIC_WASM_LISP_MANIFEST_FINGERPRINT || '').trim();
|
|
735
750
|
const usesBundledRoot = !configuredModuleUrl && !publicModuleUrl && rootUrl !== undefined;
|
|
751
|
+
const manifestUrl = configuredManifestUrl
|
|
752
|
+
? resolveConfiguredUrl(configuredManifestUrl, currentUrl)
|
|
753
|
+
: deriveLispManifestUrl(moduleUrl, currentUrl);
|
|
754
|
+
const manifestReceipt = configured?.manifestReceipt ??
|
|
755
|
+
(usesBundledRoot && !configuredManifestUrl && !configuredFingerprint
|
|
756
|
+
? resolveRuntimeAssetLockEntry(manifestUrl, {
|
|
757
|
+
assetRoot: new URL('./', new URL(moduleUrl, currentUrl || 'http://localhost/')),
|
|
758
|
+
assetPrefix: 'wasm-lisp'
|
|
759
|
+
})
|
|
760
|
+
: undefined);
|
|
736
761
|
return {
|
|
737
762
|
moduleUrl,
|
|
738
|
-
manifestUrl
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
manifestFingerprint: configuredFingerprint || (usesBundledRoot ? WASM_LISP_ASSET_VERSION : '')
|
|
763
|
+
manifestUrl,
|
|
764
|
+
manifestFingerprint: configuredFingerprint || (usesBundledRoot ? WASM_LISP_ASSET_VERSION : ''),
|
|
765
|
+
...(manifestReceipt ? { manifestReceipt: Object.freeze({ ...manifestReceipt }) } : {})
|
|
742
766
|
};
|
|
743
767
|
}
|
|
744
768
|
const RUBY_RUNTIME_CONFIG_KEYS = [
|
package/dist/playground/awk.js
CHANGED
|
@@ -40,6 +40,7 @@ class Awk extends StaticWorkerRuntimeSandbox {
|
|
|
40
40
|
manifestUrl: resolved.manifestUrl,
|
|
41
41
|
profile,
|
|
42
42
|
limits: context.limits,
|
|
43
|
+
persistentCache: context.persistentCache,
|
|
43
44
|
signal: context.signal,
|
|
44
45
|
reportProgress(progress) {
|
|
45
46
|
loadedByAsset.set(progress.assetKey, progress.loadedBytes);
|
package/dist/playground/bash.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolveBashRuntimeAssetConfig } from './assets';
|
|
2
2
|
import { BASH_WORKER_PROTOCOL_VERSION, isBashWorkerToHostMessage } from './bashWorkerProtocol';
|
|
3
3
|
import { reportWorkerProgress } from './workerProgress';
|
|
4
|
-
import { AssetTooLargeError, AssetIntegrityError, AssetNotFoundError, BusyError, CancelledError, CompileError, DEFAULT_WORKSPACE_LIMITS, DiagnosticLimitError, OutputLimitError, ProtocolError, ResourceLimitError, RuntimeConfigurationError, RuntimeExecutionError, TimeoutError, UnsupportedBrowserFeatureError, UnsupportedLanguageError, WasmIdleError, WorkerStartupError, preflightBashRuntimeAssets, resolveExecutionLimits, validateExecutionWorkspace } from '@wasm-idle/core';
|
|
4
|
+
import { AssetTooLargeError, AssetIntegrityError, AssetNotFoundError, BusyError, CancelledError, CompileError, DEFAULT_WORKSPACE_LIMITS, DiagnosticLimitError, OutputLimitError, ProtocolError, ResourceLimitError, RuntimeConfigurationError, RuntimeExecutionError, TimeoutError, UnsupportedBrowserFeatureError, UnsupportedLanguageError, WasmIdleError, WorkerStartupError, preflightBashRuntimeAssets, resolveExecutionLimits, resolveRuntimeAssetCacheOptions, validateExecutionWorkspace } from '@wasm-idle/core';
|
|
5
5
|
const MAX_TIMER_DELAY_MS = 2_147_483_647;
|
|
6
6
|
const textEncoder = new TextEncoder();
|
|
7
7
|
const abortReason = (signal, phase) => signal.reason !== undefined
|
|
@@ -29,6 +29,7 @@ class Bash {
|
|
|
29
29
|
activeOperation = null;
|
|
30
30
|
readyWorker = null;
|
|
31
31
|
loadedConfig = null;
|
|
32
|
+
persistentCache;
|
|
32
33
|
requestUid = 0;
|
|
33
34
|
sessionUid = 0;
|
|
34
35
|
disposed = false;
|
|
@@ -85,6 +86,9 @@ class Bash {
|
|
|
85
86
|
const currentUrl = typeof window !== 'undefined' ? window.location.href : '';
|
|
86
87
|
const resolved = resolveBashRuntimeAssetConfig(runtimeAssets, currentUrl);
|
|
87
88
|
this.requireActive(operation);
|
|
89
|
+
this.persistentCache =
|
|
90
|
+
typeof runtimeAssets === 'string' ? undefined : runtimeAssets.persistentCache;
|
|
91
|
+
operation.persistentCache = resolveRuntimeAssetCacheOptions(this.persistentCache, options.persistentCache);
|
|
88
92
|
const config = {
|
|
89
93
|
...resolved,
|
|
90
94
|
identity: createBashConfigIdentity(resolved.preflightKey, limits),
|
|
@@ -165,6 +169,7 @@ class Bash {
|
|
|
165
169
|
this.requireActive(operation);
|
|
166
170
|
if (signal?.aborted)
|
|
167
171
|
throw abortReason(signal, operation.stage);
|
|
172
|
+
operation.persistentCache = resolveRuntimeAssetCacheOptions(this.persistentCache, options.persistentCache);
|
|
168
173
|
const limits = resolveExecutionLimits(options.limits);
|
|
169
174
|
this.requireActive(operation);
|
|
170
175
|
if (!this.readyWorker) {
|
|
@@ -481,6 +486,7 @@ class Bash {
|
|
|
481
486
|
webcUrl: config.webcUrl,
|
|
482
487
|
profile: config.preflightProfile,
|
|
483
488
|
limits: config.limits,
|
|
489
|
+
persistentCache: operation.persistentCache,
|
|
484
490
|
signal: preflightController.signal,
|
|
485
491
|
reportProgress: ({ assetKey, loadedBytes }) => {
|
|
486
492
|
loadedByAsset.set(assetKey, loadedBytes);
|
package/dist/playground/bqn.js
CHANGED
|
@@ -35,6 +35,7 @@ class Bqn extends StaticWorkerRuntimeSandbox {
|
|
|
35
35
|
manifestUrl: urls.manifestUrl || '',
|
|
36
36
|
profile,
|
|
37
37
|
limits: context.limits,
|
|
38
|
+
persistentCache: context.persistentCache,
|
|
38
39
|
signal: context.signal,
|
|
39
40
|
reportProgress(progress) {
|
|
40
41
|
if (progress.kind === 'asset') {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BqnRuntimePreflightProfile } from './assets';
|
|
2
|
-
import { type ExecutionLimits, type RuntimeAssetPreflightProgress } from '@wasm-idle/core';
|
|
2
|
+
import { type ExecutionLimits, type RuntimeAssetCacheOptions, type RuntimeAssetPreflightProgress } from '@wasm-idle/core';
|
|
3
3
|
export declare const BQN_PREFLIGHT_PROTOCOL: "wasm-idle-bqn-preflight";
|
|
4
4
|
export declare const BQN_PREFLIGHT_PROTOCOL_VERSION: 1;
|
|
5
5
|
export declare const BQN_PREFLIGHT_RUNTIME_ID: "BQN";
|
|
@@ -8,6 +8,7 @@ export interface BqnRuntimePreflightRequest {
|
|
|
8
8
|
readonly manifestUrl: string;
|
|
9
9
|
readonly profile: BqnRuntimePreflightProfile;
|
|
10
10
|
readonly limits?: Partial<ExecutionLimits>;
|
|
11
|
+
readonly persistentCache?: RuntimeAssetCacheOptions;
|
|
11
12
|
readonly signal?: AbortSignal;
|
|
12
13
|
readonly fetch?: typeof globalThis.fetch;
|
|
13
14
|
readonly reportProgress?: (progress: RuntimeAssetPreflightProgress) => void;
|
package/dist/playground/c3.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { resolveExecutionLimits } from '@wasm-idle/core';
|
|
1
|
+
import { resolveExecutionLimits, resolveRuntimeAssetCacheOptions } from '@wasm-idle/core';
|
|
2
2
|
import { resolveRuntimeAssetConfig } from './assets';
|
|
3
3
|
import { WorkerAssetBridge } from './assetBridge';
|
|
4
4
|
import { shouldStreamBundledClang } from './clangStreamingPolicy';
|
|
@@ -69,7 +69,7 @@ export function createCachedClangSandbox(legacy, language, runtimeCache, cache =
|
|
|
69
69
|
cancelWorker?.(new Error('Process terminated'));
|
|
70
70
|
resetInput();
|
|
71
71
|
}
|
|
72
|
-
async function workerOperation(factory, message, token, progress, compileLimit = 0, signal) {
|
|
72
|
+
async function workerOperation(factory, message, token, progress, compileLimit = 0, signal, executionAssetConfig = assetConfig) {
|
|
73
73
|
const worker = await factory();
|
|
74
74
|
if (token !== generation || signal?.aborted) {
|
|
75
75
|
worker.terminate();
|
|
@@ -79,7 +79,7 @@ export function createCachedClangSandbox(legacy, language, runtimeCache, cache =
|
|
|
79
79
|
let bridge;
|
|
80
80
|
try {
|
|
81
81
|
if (compileLimit)
|
|
82
|
-
bridge = new WorkerAssetBridge(worker, 'clang',
|
|
82
|
+
bridge = new WorkerAssetBridge(worker, 'clang', executionAssetConfig, progress, compileLimit, languageSysroots, runtimeCache);
|
|
83
83
|
}
|
|
84
84
|
catch (error) {
|
|
85
85
|
worker.terminate();
|
|
@@ -172,7 +172,7 @@ export function createCachedClangSandbox(legacy, language, runtimeCache, cache =
|
|
|
172
172
|
throw new Error('C/C++ sandbox was disposed');
|
|
173
173
|
loadedAssets = assets;
|
|
174
174
|
const config = typeof assets === 'object' ? assets : undefined;
|
|
175
|
-
assetConfig = resolveRuntimeAssetConfig('clang', assets, globalThis.location?.href || 'http://localhost/');
|
|
175
|
+
assetConfig = resolveRuntimeAssetConfig('clang', assets, globalThis.location?.href || 'http://localhost/', options.persistentCache);
|
|
176
176
|
const debugMode = options.debugMode || (options.debug ? 'trace' : 'none');
|
|
177
177
|
const cacheEligible = debugMode === 'none' &&
|
|
178
178
|
shouldStreamBundledClang(assetConfig) &&
|
|
@@ -194,16 +194,23 @@ export function createCachedClangSandbox(legacy, language, runtimeCache, cache =
|
|
|
194
194
|
async run(code, prepare, log = true, progress, args = [], options = {}) {
|
|
195
195
|
if (disposed)
|
|
196
196
|
throw new Error('C/C++ sandbox was disposed');
|
|
197
|
+
if (running)
|
|
198
|
+
throw new Error('C/C++ sandbox is already running');
|
|
197
199
|
if (cached &&
|
|
198
200
|
((options.debugMode || (options.debug ? 'trace' : 'none')) !== 'none' ||
|
|
199
201
|
(options.stdin !== undefined && typeof options.stdin !== 'string') ||
|
|
200
202
|
options.workspaceFiles?.some((file) => typeof file.content !== 'string'))) {
|
|
201
|
-
await overrides.load(loadedAssets, code, log, args,
|
|
203
|
+
await overrides.load(loadedAssets, code, log, args, {
|
|
204
|
+
...options,
|
|
205
|
+
persistentCache: assetConfig.persistentCache
|
|
206
|
+
}, progress);
|
|
202
207
|
}
|
|
203
208
|
if (!cached)
|
|
204
209
|
return legacy.run(code, prepare, log, progress, args, options);
|
|
205
|
-
|
|
206
|
-
|
|
210
|
+
const executionAssetConfig = {
|
|
211
|
+
...assetConfig,
|
|
212
|
+
persistentCache: resolveRuntimeAssetCacheOptions(assetConfig.persistentCache, options.persistentCache)
|
|
213
|
+
};
|
|
207
214
|
options.signal?.throwIfAborted();
|
|
208
215
|
const token = ++generation;
|
|
209
216
|
// Reactive UI arrays/records are Proxies and cannot cross postMessage.
|
|
@@ -246,7 +253,7 @@ export function createCachedClangSandbox(legacy, language, runtimeCache, cache =
|
|
|
246
253
|
useAssetBridge: assetConfig.useAssetBridge,
|
|
247
254
|
useModuleBridge: true
|
|
248
255
|
}
|
|
249
|
-
}, token, progress, limit, options.signal);
|
|
256
|
+
}, token, progress, limit, options.signal, executionAssetConfig);
|
|
250
257
|
if (token !== generation)
|
|
251
258
|
throw new Error('Process terminated');
|
|
252
259
|
cache.set(key, artifact);
|
|
@@ -27,6 +27,7 @@ declare class Clang implements Sandbox {
|
|
|
27
27
|
debugRuntimeBaseUrl: string;
|
|
28
28
|
debugManifestUrl: string;
|
|
29
29
|
debugManifestReceipt?: Readonly<RuntimeAssetIntegrityEntry>;
|
|
30
|
+
private persistentCache?;
|
|
30
31
|
private lldbSession?;
|
|
31
32
|
private runtimeAssetCache;
|
|
32
33
|
private ownsRuntimeAssetCache;
|
package/dist/playground/clang.js
CHANGED
|
@@ -39,6 +39,7 @@ class Clang {
|
|
|
39
39
|
debugRuntimeBaseUrl = '';
|
|
40
40
|
debugManifestUrl = '';
|
|
41
41
|
debugManifestReceipt;
|
|
42
|
+
persistentCache;
|
|
42
43
|
lldbSession;
|
|
43
44
|
runtimeAssetCache = new RuntimeAssetCache();
|
|
44
45
|
ownsRuntimeAssetCache = true;
|
|
@@ -91,9 +92,10 @@ class Clang {
|
|
|
91
92
|
this.pendingInput = [];
|
|
92
93
|
this.waitingForInput = false;
|
|
93
94
|
this.pendingEof = false;
|
|
94
|
-
const assetConfig = resolveRuntimeAssetConfig('clang', runtimeAssets, typeof window !== 'undefined' ? window.location.href : '');
|
|
95
|
+
const assetConfig = resolveRuntimeAssetConfig('clang', runtimeAssets, typeof window !== 'undefined' ? window.location.href : '', options.persistentCache);
|
|
95
96
|
const debugRuntime = resolveDebugRuntimeUrls(runtimeAssets, typeof window !== 'undefined' ? window.location.href : '');
|
|
96
97
|
this.debugRuntimeBaseUrl = debugRuntime.baseUrl;
|
|
98
|
+
this.persistentCache = assetConfig.persistentCache;
|
|
97
99
|
this.debugManifestUrl = debugRuntime.manifestUrl;
|
|
98
100
|
this.debugManifestReceipt = debugRuntime.manifestReceipt;
|
|
99
101
|
const bundledAssets = shouldStreamBundledClang(assetConfig);
|
|
@@ -191,6 +193,10 @@ class Clang {
|
|
|
191
193
|
if (!this.worker)
|
|
192
194
|
return reject('Worker not loaded');
|
|
193
195
|
const operation = this.workerSession.beginRun(this.worker, reject);
|
|
196
|
+
const persistentCacheOverride = options.persistentCache;
|
|
197
|
+
if (!this.workerSession.isActive(operation))
|
|
198
|
+
return;
|
|
199
|
+
const persistentCache = this.assetBridge?.setExecutionPersistentCache(persistentCacheOverride);
|
|
194
200
|
const { compileArgs, programArgs } = resolveSandboxExecutionArgs(this.language, args, options);
|
|
195
201
|
const sourcePath = normalizeLldbSourcePath(options.debugPath || options.activePath, this.language === 'C' ? 'main.c' : 'main.cc');
|
|
196
202
|
this.lldbBreakpoints.clear();
|
|
@@ -228,6 +234,7 @@ class Clang {
|
|
|
228
234
|
if (lldbArtifact) {
|
|
229
235
|
const compilerWorker = this.worker;
|
|
230
236
|
const lldbSession = new LldbSandboxSession({
|
|
237
|
+
persistentCache: persistentCache ?? this.persistentCache,
|
|
231
238
|
manifestUrl: this.debugManifestUrl,
|
|
232
239
|
manifestReceipt: this.debugManifestReceipt,
|
|
233
240
|
runtimeBaseUrl: this.debugRuntimeBaseUrl,
|
|
@@ -35,6 +35,7 @@ class ClojureScript extends StaticWorkerRuntimeSandbox {
|
|
|
35
35
|
manifestUrl: urls.manifestUrl || '',
|
|
36
36
|
profile,
|
|
37
37
|
limits: context.limits,
|
|
38
|
+
persistentCache: context.persistentCache,
|
|
38
39
|
signal: context.signal,
|
|
39
40
|
reportProgress(progress) {
|
|
40
41
|
if (progress.kind === 'asset') {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ClojureScriptRuntimePreflightProfile } from './assets';
|
|
2
|
-
import { type ExecutionLimits, type RuntimeAssetPreflightProgress } from '@wasm-idle/core';
|
|
2
|
+
import { type ExecutionLimits, type RuntimeAssetCacheOptions, type RuntimeAssetPreflightProgress } from '@wasm-idle/core';
|
|
3
3
|
export declare const CLOJURESCRIPT_PREFLIGHT_PROTOCOL: "wasm-idle-clojurescript-preflight";
|
|
4
4
|
export declare const CLOJURESCRIPT_PREFLIGHT_PROTOCOL_VERSION: 1;
|
|
5
5
|
export declare const CLOJURESCRIPT_PREFLIGHT_RUNTIME_ID: "CLOJURESCRIPT";
|
|
@@ -8,6 +8,7 @@ export interface ClojureScriptRuntimePreflightRequest {
|
|
|
8
8
|
readonly manifestUrl: string;
|
|
9
9
|
readonly profile: ClojureScriptRuntimePreflightProfile;
|
|
10
10
|
readonly limits?: Partial<ExecutionLimits>;
|
|
11
|
+
readonly persistentCache?: RuntimeAssetCacheOptions;
|
|
11
12
|
readonly signal?: AbortSignal;
|
|
12
13
|
readonly fetch?: typeof globalThis.fetch;
|
|
13
14
|
readonly reportProgress?: (progress: RuntimeAssetPreflightProgress) => void;
|