wasm-idle 0.7.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +760 -81
- package/dist/index.d.ts +4 -9
- package/dist/index.js +2 -4
- package/dist/playground/applicationAssets.d.ts +4 -0
- package/dist/playground/applicationAssets.js +277 -0
- package/dist/playground/assemblyscript.d.ts +41 -0
- package/dist/playground/assemblyscript.js +630 -0
- package/dist/playground/assetBridge.d.ts +18 -7
- package/dist/playground/assetBridge.js +824 -100
- package/dist/playground/assets.d.ts +813 -19
- package/dist/playground/assets.js +2096 -156
- package/dist/playground/awk.d.ts +5 -0
- package/dist/playground/awk.js +60 -0
- package/dist/playground/bash.d.ts +53 -0
- package/dist/playground/bash.js +1096 -0
- package/dist/playground/bashWorkerProtocol.d.ts +88 -0
- package/dist/playground/bashWorkerProtocol.js +135 -0
- package/dist/playground/bqn.d.ts +5 -0
- package/dist/playground/bqn.js +57 -0
- package/dist/playground/bqnPreflight.d.ts +26 -0
- package/dist/playground/bqnPreflight.js +399 -0
- package/dist/playground/c3.d.ts +15 -0
- package/dist/playground/c3.js +154 -0
- package/dist/playground/clang.d.ts +35 -19
- package/dist/playground/clang.js +241 -52
- package/dist/playground/clangAssetIntegrity.d.ts +32 -0
- package/dist/playground/clangAssetIntegrity.js +8 -0
- package/dist/playground/clojurescript.d.ts +5 -0
- package/dist/playground/clojurescript.js +59 -0
- package/dist/playground/clojurescriptPreflight.d.ts +26 -0
- package/dist/playground/clojurescriptPreflight.js +383 -0
- package/dist/playground/cobol.d.ts +46 -0
- package/dist/playground/cobol.js +703 -0
- package/dist/playground/d.d.ts +47 -0
- package/dist/playground/d.js +644 -0
- package/dist/playground/dOuterAssets.d.ts +16 -0
- package/dist/playground/dOuterAssets.js +163 -0
- package/dist/playground/dotnet.d.ts +99 -0
- package/dist/playground/dotnet.js +1131 -0
- package/dist/playground/duckdb.d.ts +36 -0
- package/dist/playground/duckdb.js +542 -0
- package/dist/playground/elixir.d.ts +18 -10
- package/dist/playground/elixir.js +630 -96
- package/dist/playground/elixirAssets.d.ts +6 -0
- package/dist/playground/elixirAssets.js +33 -0
- package/dist/playground/executionObservation.d.ts +22 -0
- package/dist/playground/executionObservation.js +65 -0
- package/dist/playground/forth.d.ts +5 -0
- package/dist/playground/forth.js +53 -0
- package/dist/playground/forthPreflight.d.ts +24 -0
- package/dist/playground/forthPreflight.js +198 -0
- package/dist/playground/fortran.d.ts +47 -0
- package/dist/playground/fortran.js +651 -0
- package/dist/playground/fortranAssets.d.ts +6 -0
- package/dist/playground/fortranAssets.js +27 -0
- package/dist/playground/gleam.d.ts +6 -0
- package/dist/playground/gleam.js +33 -0
- package/dist/playground/go.d.ts +17 -11
- package/dist/playground/go.js +376 -72
- package/dist/playground/goDebugInstrumentation.d.ts +1 -0
- package/dist/playground/goDebugInstrumentation.js +229 -0
- package/dist/playground/haskell.d.ts +44 -0
- package/dist/playground/haskell.js +678 -0
- package/dist/playground/haskellAssets.d.ts +24 -0
- package/dist/playground/haskellAssets.js +93 -0
- package/dist/playground/index.d.ts +1 -1
- package/dist/playground/index.js +360 -111
- package/dist/playground/j.d.ts +5 -0
- package/dist/playground/j.js +60 -0
- package/dist/playground/jPreflight.d.ts +26 -0
- package/dist/playground/jPreflight.js +372 -0
- package/dist/playground/janet.d.ts +5 -0
- package/dist/playground/janet.js +64 -0
- package/dist/playground/java.d.ts +24 -10
- package/dist/playground/java.js +706 -84
- package/dist/playground/javaSource.d.ts +5 -0
- package/dist/playground/javaSource.js +16 -0
- package/dist/playground/javaStdin.d.ts +1 -1
- package/dist/playground/javaStdin.js +13 -4
- package/dist/playground/julia.d.ts +5 -0
- package/dist/playground/julia.js +64 -0
- package/dist/playground/lfortran.d.ts +8 -0
- package/dist/playground/lfortran.js +30 -0
- package/dist/playground/lfortranAssets.d.ts +21 -0
- package/dist/playground/lfortranAssets.js +118 -0
- package/dist/playground/lisp.d.ts +45 -0
- package/dist/playground/lisp.js +640 -0
- package/dist/playground/lispAssets.d.ts +9 -0
- package/dist/playground/lispAssets.js +74 -0
- package/dist/playground/lldbManifest.d.ts +3 -0
- package/dist/playground/lldbManifest.js +155 -0
- package/dist/playground/lldbSession.d.ts +115 -0
- package/dist/playground/lldbSession.js +1347 -0
- package/dist/playground/loadingProgress.d.ts +16 -0
- package/dist/playground/loadingProgress.js +166 -0
- package/dist/playground/lua.d.ts +44 -0
- package/dist/playground/lua.js +630 -0
- package/dist/playground/nim.d.ts +5 -0
- package/dist/playground/nim.js +76 -0
- package/dist/playground/objectivec.d.ts +39 -0
- package/dist/playground/objectivec.js +288 -0
- package/dist/playground/ocaml.d.ts +28 -10
- package/dist/playground/ocaml.js +815 -253
- package/dist/playground/octave.d.ts +43 -0
- package/dist/playground/octave.js +783 -0
- package/dist/playground/options.d.ts +19 -40
- package/dist/playground/options.js +2 -1
- package/dist/playground/pascal.d.ts +5 -0
- package/dist/playground/pascal.js +60 -0
- package/dist/playground/perl.d.ts +5 -0
- package/dist/playground/perl.js +61 -0
- package/dist/playground/php.d.ts +44 -0
- package/dist/playground/php.js +665 -0
- package/dist/playground/prolog.d.ts +6 -0
- package/dist/playground/prolog.js +75 -0
- package/dist/playground/python.d.ts +20 -14
- package/dist/playground/python.js +445 -101
- package/dist/playground/pythonPackageLock.d.ts +6 -0
- package/dist/playground/pythonPackageLock.js +56 -0
- package/dist/playground/r.d.ts +44 -0
- package/dist/playground/r.js +637 -0
- package/dist/playground/ruby.d.ts +46 -0
- package/dist/playground/ruby.js +732 -0
- package/dist/playground/rubyAssets.d.ts +23 -0
- package/dist/playground/rubyAssets.js +68 -0
- package/dist/playground/rubyTestPreflight.d.ts +2 -0
- package/dist/playground/rubyTestPreflight.js +18 -0
- package/dist/playground/runtimeModule.d.ts +1 -0
- package/dist/playground/runtimeModule.js +5 -0
- package/dist/playground/rust.d.ts +44 -13
- package/dist/playground/rust.js +714 -76
- package/dist/playground/rustExecutableGraph.d.ts +85 -0
- package/dist/playground/rustExecutableGraph.js +946 -0
- package/dist/playground/rustWorkerLimits.d.ts +17 -0
- package/dist/playground/rustWorkerLimits.js +34 -0
- package/dist/playground/sandbox.d.ts +16 -10
- package/dist/playground/sharedBuffer.d.ts +6 -0
- package/dist/playground/sharedBuffer.js +12 -0
- package/dist/playground/sqlite.d.ts +38 -0
- package/dist/playground/sqlite.js +550 -0
- package/dist/playground/staticRuntimeModuleVersion.d.ts +1 -0
- package/dist/playground/staticRuntimeModuleVersion.js +2 -0
- package/dist/playground/staticRuntimePreflight.d.ts +13 -0
- package/dist/playground/staticRuntimePreflight.js +231 -0
- package/dist/playground/staticRuntimePreflightExecute.d.ts +8 -0
- package/dist/playground/staticRuntimePreflightExecute.js +66 -0
- package/dist/playground/staticRuntimePreflightProtocol.d.ts +68 -0
- package/dist/playground/staticRuntimePreflightProtocol.js +339 -0
- package/dist/playground/staticStdinRing.d.ts +45 -0
- package/dist/playground/staticStdinRing.js +158 -0
- package/dist/playground/staticWorkerRuntime.d.ts +154 -0
- package/dist/playground/staticWorkerRuntime.js +1917 -0
- package/dist/playground/stdinBuffer.d.ts +9 -7
- package/dist/playground/stdinBuffer.js +9 -18
- package/dist/playground/swift.d.ts +5 -0
- package/dist/playground/swift.js +17 -0
- package/dist/playground/tcl.d.ts +5 -0
- package/dist/playground/tcl.js +62 -0
- package/dist/playground/teavmConfig.d.ts +1 -1
- package/dist/playground/teavmConfig.js +2 -2
- package/dist/playground/tinygo.d.ts +48 -18
- package/dist/playground/tinygo.js +1202 -329
- package/dist/playground/tinygoExecutableGraph.d.ts +44 -0
- package/dist/playground/tinygoExecutableGraph.js +449 -0
- package/dist/playground/typescript.d.ts +55 -0
- package/dist/playground/typescript.js +924 -0
- package/dist/playground/wasm.d.ts +43 -0
- package/dist/playground/wasm.js +608 -0
- package/dist/playground/wasmAwkVersion.d.ts +59 -0
- package/dist/playground/wasmAwkVersion.js +31 -0
- package/dist/playground/wasmBashVersion.d.ts +63 -0
- package/dist/playground/wasmBashVersion.js +36 -0
- package/dist/playground/wasmBqnVersion.d.ts +24 -0
- package/dist/playground/wasmBqnVersion.js +24 -0
- package/dist/playground/wasmC3Version.d.ts +20 -0
- package/dist/playground/wasmC3Version.js +21 -0
- package/dist/playground/wasmClojureScriptVersion.d.ts +21 -0
- package/dist/playground/wasmClojureScriptVersion.js +21 -0
- package/dist/playground/wasmDIntegrity.d.ts +15 -0
- package/dist/playground/wasmDIntegrity.js +15 -0
- package/dist/playground/wasmDVersion.d.ts +1 -0
- package/dist/playground/wasmDVersion.js +1 -0
- package/dist/playground/wasmDebugVersion.d.ts +6 -0
- package/dist/playground/wasmDebugVersion.js +6 -0
- package/dist/playground/wasmDotnetVersion.d.ts +1 -0
- package/dist/playground/wasmDotnetVersion.js +1 -0
- package/dist/playground/wasmElixirVersion.d.ts +21 -1
- package/dist/playground/wasmElixirVersion.js +21 -1
- package/dist/playground/wasmForthVersion.d.ts +18 -0
- package/dist/playground/wasmForthVersion.js +18 -0
- package/dist/playground/wasmFortranExecutionAssets.d.ts +15 -0
- package/dist/playground/wasmFortranExecutionAssets.js +15 -0
- package/dist/playground/wasmFortranVersion.d.ts +1 -0
- package/dist/playground/wasmFortranVersion.js +1 -0
- package/dist/playground/wasmGleamVersion.d.ts +5 -0
- package/dist/playground/wasmGleamVersion.js +5 -0
- package/dist/playground/wasmGoVersion.d.ts +1 -1
- package/dist/playground/wasmGoVersion.js +1 -1
- package/dist/playground/wasmHaskellVersion.d.ts +1 -0
- package/dist/playground/wasmHaskellVersion.js +1 -0
- package/dist/playground/wasmJVersion.d.ts +24 -0
- package/dist/playground/wasmJVersion.js +24 -0
- package/dist/playground/wasmJanetVersion.d.ts +53 -0
- package/dist/playground/wasmJanetVersion.js +30 -0
- package/dist/playground/wasmJuliaVersion.d.ts +71 -0
- package/dist/playground/wasmJuliaVersion.js +39 -0
- package/dist/playground/wasmLfortranVersion.d.ts +28 -0
- package/dist/playground/wasmLfortranVersion.js +29 -0
- package/dist/playground/wasmLispVersion.d.ts +1 -0
- package/dist/playground/wasmLispVersion.js +1 -0
- package/dist/playground/wasmLuaVersion.d.ts +1 -0
- package/dist/playground/wasmLuaVersion.js +1 -0
- package/dist/playground/wasmNimVersion.d.ts +125 -0
- package/dist/playground/wasmNimVersion.js +66 -0
- package/dist/playground/wasmObjectiveCVersion.d.ts +27 -0
- package/dist/playground/wasmObjectiveCVersion.js +27 -0
- package/dist/playground/wasmOcamlVersion.d.ts +12 -1
- package/dist/playground/wasmOcamlVersion.js +12 -1
- package/dist/playground/wasmOctaveVersion.d.ts +1 -0
- package/dist/playground/wasmOctaveVersion.js +1 -0
- package/dist/playground/wasmPascalVersion.d.ts +61 -0
- package/dist/playground/wasmPascalVersion.js +34 -0
- package/dist/playground/wasmPerlVersion.d.ts +71 -0
- package/dist/playground/wasmPerlVersion.js +39 -0
- package/dist/playground/wasmPrologVersion.d.ts +31 -0
- package/dist/playground/wasmPrologVersion.js +31 -0
- package/dist/playground/wasmRVersion.d.ts +1 -0
- package/dist/playground/wasmRVersion.js +1 -0
- package/dist/playground/wasmRustVersion.d.ts +1306 -1
- package/dist/playground/wasmRustVersion.js +1458 -1
- package/dist/playground/wasmSwiftVersion.d.ts +1 -0
- package/dist/playground/wasmSwiftVersion.js +1 -0
- package/dist/playground/wasmTclVersion.d.ts +85 -0
- package/dist/playground/wasmTclVersion.js +46 -0
- package/dist/playground/wasmTinyGoVersion.d.ts +98 -1
- package/dist/playground/wasmTinyGoVersion.js +107 -1
- package/dist/playground/wasmTypeScriptVersion.d.ts +5 -0
- package/dist/playground/wasmTypeScriptVersion.js +5 -0
- package/dist/playground/wasmWatVersion.d.ts +1 -0
- package/dist/playground/wasmWatVersion.js +1 -0
- package/dist/playground/wasmZigVersion.d.ts +13 -0
- package/dist/playground/wasmZigVersion.js +13 -0
- package/dist/playground/wat.d.ts +44 -0
- package/dist/playground/wat.js +622 -0
- package/dist/playground/worker/assemblyscript.js +339 -0
- package/dist/playground/worker/assets.d.ts +7 -0
- package/dist/playground/worker/assets.js +288 -39
- package/dist/playground/worker/bash.js +338 -0
- package/dist/playground/worker/bashNestedBootstrap.d.ts +6 -0
- package/dist/playground/worker/bashNestedBootstrap.js +59 -0
- package/dist/playground/worker/bashRuntime.d.ts +89 -0
- package/dist/playground/worker/bashRuntime.js +982 -0
- package/dist/playground/worker/clang.js +92 -13
- package/dist/playground/worker/cobol.js +107 -0
- package/dist/playground/worker/d.js +199 -0
- package/dist/playground/worker/dotnet.js +141 -0
- package/dist/playground/worker/duckdb.d.ts +1 -0
- package/dist/playground/worker/duckdb.js +136 -0
- package/dist/playground/worker/elixir.js +307 -41
- package/dist/playground/worker/fortran.d.ts +1 -0
- package/dist/playground/worker/fortran.js +295 -0
- package/dist/playground/worker/go.js +246 -40
- package/dist/playground/worker/haskell.d.ts +7 -0
- package/dist/playground/worker/haskell.js +465 -0
- package/dist/playground/worker/java.js +59 -20
- package/dist/playground/worker/lisp.d.ts +1 -0
- package/dist/playground/worker/lisp.js +195 -0
- package/dist/playground/worker/lua.d.ts +1 -0
- package/dist/playground/worker/lua.js +163 -0
- package/dist/playground/worker/objectivec.d.ts +1 -0
- package/dist/playground/worker/objectivec.js +10 -0
- package/dist/playground/worker/ocaml.js +206 -58
- package/dist/playground/worker/php.d.ts +1 -0
- package/dist/playground/worker/php.js +261 -0
- package/dist/playground/worker/python.js +201 -44
- package/dist/playground/worker/r.d.ts +1 -0
- package/dist/playground/worker/r.js +192 -0
- package/dist/playground/worker/ruby.d.ts +1 -0
- package/dist/playground/worker/ruby.js +248 -0
- package/dist/playground/worker/runtimeAssetFetch.d.ts +15 -0
- package/dist/playground/worker/runtimeAssetFetch.js +375 -0
- package/dist/playground/worker/rust.js +546 -20
- package/dist/playground/worker/sqlite.d.ts +1 -0
- package/dist/playground/worker/sqlite.js +112 -0
- package/dist/playground/worker/staticRuntimePreflight.d.ts +1 -0
- package/dist/playground/worker/staticRuntimePreflight.js +56 -0
- package/dist/playground/worker/tinygo.js +34 -9
- package/dist/playground/worker/typescript.d.ts +1 -0
- package/dist/playground/worker/typescript.js +251 -0
- package/dist/playground/worker/wasm.d.ts +1 -0
- package/dist/playground/worker/wasm.js +273 -0
- package/dist/playground/worker/wat.d.ts +1 -0
- package/dist/playground/worker/wat.js +188 -0
- package/dist/playground/worker/zig.d.ts +8 -0
- package/dist/playground/worker/zig.js +578 -0
- package/dist/playground/workerProgress.d.ts +15 -0
- package/dist/playground/workerProgress.js +72 -0
- package/dist/playground/workerSession.d.ts +28 -0
- package/dist/playground/workerSession.js +164 -0
- package/dist/playground/zig.d.ts +46 -0
- package/dist/playground/zig.js +690 -0
- package/dist/playground/zigAssets.d.ts +6 -0
- package/dist/playground/zigAssets.js +49 -0
- package/package.json +234 -105
- package/dist/clang/app.d.ts +0 -75
- package/dist/clang/app.js +0 -744
- package/dist/clang/apply.d.ts +0 -2
- package/dist/clang/apply.js +0 -11
- package/dist/clang/color.d.ts +0 -3
- package/dist/clang/color.js +0 -3
- package/dist/clang/encode.d.ts +0 -4
- package/dist/clang/encode.js +0 -20
- package/dist/clang/error.d.ts +0 -14
- package/dist/clang/error.js +0 -27
- package/dist/clang/gccCompat.d.ts +0 -15
- package/dist/clang/gccCompat.js +0 -767
- package/dist/clang/index.d.ts +0 -85
- package/dist/clang/index.js +0 -1077
- package/dist/clang/memory/index.d.ts +0 -4
- package/dist/clang/memory/index.js +0 -4
- package/dist/clang/memory/memFs.d.ts +0 -35
- package/dist/clang/memory/memFs.js +0 -132
- package/dist/clang/memory/memory.d.ts +0 -22
- package/dist/clang/memory/memory.js +0 -73
- package/dist/clang/memory/tar.d.ts +0 -2
- package/dist/clang/memory/tar.js +0 -59
- package/dist/clang/url.d.ts +0 -4
- package/dist/clang/url.js +0 -5
- package/dist/clang/wasm.d.ts +0 -4
- package/dist/clang/wasm.js +0 -50
- package/dist/clangd/config.d.ts +0 -18
- package/dist/clangd/config.js +0 -14
- package/dist/clangd/jsonStream.d.ts +0 -9
- package/dist/clangd/jsonStream.js +0 -48
- package/dist/clangd/session.d.ts +0 -18
- package/dist/clangd/session.js +0 -112
- package/dist/clangd/worker.js +0 -131
- package/dist/debug/controller.svelte.d.ts +0 -43
- package/dist/debug/controller.svelte.js +0 -268
- package/dist/debug/editor/index.d.ts +0 -2
- package/dist/debug/editor/index.js +0 -1
- package/dist/debug/editor/monaco.d.ts +0 -26
- package/dist/debug/editor/monaco.js +0 -128
- package/dist/debug/expression.d.ts +0 -26
- package/dist/debug/expression.js +0 -547
- package/dist/debug/index.d.ts +0 -8
- package/dist/debug/index.js +0 -5
- package/dist/debug/language/cpp.d.ts +0 -2
- package/dist/debug/language/cpp.js +0 -7
- package/dist/debug/language/index.d.ts +0 -3
- package/dist/debug/language/index.js +0 -2
- package/dist/debug/language/python.d.ts +0 -2
- package/dist/debug/language/python.js +0 -14
- package/dist/debug/language/types.d.ts +0 -6
- package/dist/debug/locals.d.ts +0 -2
- package/dist/debug/locals.js +0 -8
- package/dist/lsp/cpp/server.d.ts +0 -2
- package/dist/lsp/cpp/server.js +0 -68
- package/dist/lsp/index.d.ts +0 -5
- package/dist/lsp/index.js +0 -4
- package/dist/lsp/python/main.worker.js +0 -92
- package/dist/lsp/python/package/arcturus_python_lsp/__init__.py +0 -3
- package/dist/lsp/python/package/arcturus_python_lsp/server.py +0 -462
- package/dist/lsp/python/server.d.ts +0 -2
- package/dist/lsp/python/server.js +0 -54
- package/dist/lsp/registry.d.ts +0 -2
- package/dist/lsp/registry.js +0 -12
- package/dist/lsp/runtime.d.ts +0 -5
- package/dist/lsp/runtime.js +0 -31
- package/dist/lsp/types.d.ts +0 -17
- package/dist/terminal/Terminal.svelte +0 -422
- package/dist/terminal/Terminal.svelte.d.ts +0 -26
- package/dist/terminal/index.d.ts +0 -7
- package/dist/terminal/index.js +0 -5
- package/dist/terminal/plugin/index.d.ts +0 -9
- package/dist/terminal/plugin/index.js +0 -19
- package/dist/terminal/theme.d.ts +0 -49
- package/dist/terminal/theme.js +0 -49
- package/dist/terminal/types.d.ts +0 -18
- package/dist/utils/vscodeJsonrpcBrowser.d.ts +0 -5
- package/dist/utils/vscodeJsonrpcBrowser.js +0 -4
- /package/dist/{clangd/worker.d.ts → playground/worker/assemblyscript.d.ts} +0 -0
- /package/dist/{debug/language/types.js → playground/worker/bash.d.ts} +0 -0
- /package/dist/{lsp/python/main.worker.d.ts → playground/worker/cobol.d.ts} +0 -0
- /package/dist/{lsp/types.js → playground/worker/d.d.ts} +0 -0
- /package/dist/{terminal/types.js → playground/worker/dotnet.d.ts} +0 -0
|
@@ -1,46 +1,306 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RUNTIME_LOAD_ASSETS } from './assets';
|
|
2
|
+
import { ProtocolError, verifyRuntimeAssetIntegrity, verifyRuntimeAssetPair } from '@wasm-idle/core';
|
|
3
|
+
import { decompressGzip } from '@wasm-idle/llvm-core';
|
|
4
|
+
import { readPythonPackageAssets } from './pythonPackageLock';
|
|
2
5
|
const encoder = new TextEncoder();
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
const DEFAULT_STREAM_BUFFER_BYTES = 64 * 1024;
|
|
7
|
+
const MAX_RUNTIME_ASSET_BYTES = 128 * 1024 * 1024;
|
|
8
|
+
const typedArrayPrototype = Object.getPrototypeOf(Uint8Array.prototype);
|
|
9
|
+
const typedArrayTagGetter = Object.getOwnPropertyDescriptor(typedArrayPrototype, Symbol.toStringTag)?.get;
|
|
10
|
+
const typedArrayBufferGetter = Object.getOwnPropertyDescriptor(typedArrayPrototype, 'buffer')?.get;
|
|
11
|
+
const typedArrayByteLengthGetter = Object.getOwnPropertyDescriptor(typedArrayPrototype, 'byteLength')?.get;
|
|
12
|
+
const typedArrayByteOffsetGetter = Object.getOwnPropertyDescriptor(typedArrayPrototype, 'byteOffset')?.get;
|
|
13
|
+
const arrayBufferByteLengthGetter = Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, 'byteLength')?.get;
|
|
14
|
+
const blobSizeGetter = Object.getOwnPropertyDescriptor(Blob.prototype, 'size')?.get;
|
|
15
|
+
const blobTypeGetter = Object.getOwnPropertyDescriptor(Blob.prototype, 'type')?.get;
|
|
16
|
+
const runtimeAssetSizeError = (asset, maxBytes = MAX_RUNTIME_ASSET_BYTES) => new Error(`Runtime asset ${asset} exceeds the ${maxBytes} byte limit`);
|
|
17
|
+
const requireRuntimeAssetSize = (asset, byteLength, maxBytes = MAX_RUNTIME_ASSET_BYTES) => {
|
|
18
|
+
if (!Number.isSafeInteger(byteLength) || byteLength < 0) {
|
|
19
|
+
throw new Error(`Runtime asset ${asset} has an invalid byte length`);
|
|
20
|
+
}
|
|
21
|
+
if (byteLength > maxBytes)
|
|
22
|
+
throw runtimeAssetSizeError(asset, maxBytes);
|
|
23
|
+
};
|
|
24
|
+
const canonicalUint8Array = (value) => {
|
|
25
|
+
if (!typedArrayTagGetter ||
|
|
26
|
+
!typedArrayBufferGetter ||
|
|
27
|
+
!typedArrayByteLengthGetter ||
|
|
28
|
+
!typedArrayByteOffsetGetter) {
|
|
29
|
+
throw new Error('Uint8Array intrinsic accessors are unavailable');
|
|
30
|
+
}
|
|
31
|
+
if (Reflect.apply(typedArrayTagGetter, value, []) !== 'Uint8Array') {
|
|
32
|
+
throw new TypeError('Runtime asset byte data must be a Uint8Array');
|
|
33
|
+
}
|
|
34
|
+
const buffer = Reflect.apply(typedArrayBufferGetter, value, []);
|
|
35
|
+
const byteLength = Reflect.apply(typedArrayByteLengthGetter, value, []);
|
|
36
|
+
const byteOffset = Reflect.apply(typedArrayByteOffsetGetter, value, []);
|
|
37
|
+
return new Uint8Array(buffer, byteOffset, byteLength);
|
|
38
|
+
};
|
|
39
|
+
const detachedRuntimeAssetBytesError = (asset) => new Error(`Runtime asset ${asset} byte data is detached or invalid`);
|
|
40
|
+
const tryCanonicalUint8Array = (value, asset) => {
|
|
41
|
+
if (!typedArrayTagGetter)
|
|
42
|
+
throw new Error('Uint8Array intrinsic accessors are unavailable');
|
|
43
|
+
let tag;
|
|
44
|
+
try {
|
|
45
|
+
tag = Reflect.apply(typedArrayTagGetter, value, []);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
if (tag !== 'Uint8Array')
|
|
51
|
+
return undefined;
|
|
52
|
+
try {
|
|
53
|
+
return canonicalUint8Array(value);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
throw detachedRuntimeAssetBytesError(asset);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const tryArrayBufferByteLength = (value) => {
|
|
60
|
+
if (!arrayBufferByteLengthGetter)
|
|
61
|
+
return undefined;
|
|
62
|
+
try {
|
|
63
|
+
return Reflect.apply(arrayBufferByteLengthGetter, value, []);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const snapshotArrayBufferBytes = (value, asset, maxBytes) => {
|
|
70
|
+
const byteLength = tryArrayBufferByteLength(value);
|
|
71
|
+
if (byteLength === undefined)
|
|
72
|
+
return undefined;
|
|
73
|
+
requireRuntimeAssetSize(asset, byteLength, maxBytes);
|
|
74
|
+
try {
|
|
75
|
+
return Uint8Array.from(new Uint8Array(value));
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
throw detachedRuntimeAssetBytesError(asset);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
const snapshotLoaderBytes = (value, asset, maxBytes) => {
|
|
82
|
+
const bytes = tryCanonicalUint8Array(value, asset);
|
|
83
|
+
if (!bytes)
|
|
84
|
+
return snapshotArrayBufferBytes(value, asset, maxBytes);
|
|
85
|
+
requireRuntimeAssetSize(asset, bytes.byteLength, maxBytes);
|
|
86
|
+
return Uint8Array.from(bytes);
|
|
87
|
+
};
|
|
88
|
+
const snapshotMaterializedArrayBuffer = (value, asset, maxBytes) => {
|
|
89
|
+
const bytes = snapshotArrayBufferBytes(value, asset, maxBytes);
|
|
90
|
+
if (!bytes) {
|
|
91
|
+
throw new Error(`Runtime asset ${asset} materialization did not return an ArrayBuffer`);
|
|
92
|
+
}
|
|
93
|
+
return bytes;
|
|
94
|
+
};
|
|
95
|
+
const tryCanonicalBlob = (value) => {
|
|
96
|
+
if (!blobSizeGetter || !blobTypeGetter)
|
|
97
|
+
return undefined;
|
|
98
|
+
try {
|
|
99
|
+
return {
|
|
100
|
+
blob: value,
|
|
101
|
+
size: Reflect.apply(blobSizeGetter, value, []),
|
|
102
|
+
type: Reflect.apply(blobTypeGetter, value, [])
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
export const boundedUtf8ByteLength = (value, maxBytes = MAX_RUNTIME_ASSET_BYTES) => {
|
|
110
|
+
let byteLength = 0;
|
|
111
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
112
|
+
const codeUnit = value.charCodeAt(index);
|
|
113
|
+
if (codeUnit <= 0x7f) {
|
|
114
|
+
byteLength += 1;
|
|
115
|
+
}
|
|
116
|
+
else if (codeUnit <= 0x7ff) {
|
|
117
|
+
byteLength += 2;
|
|
118
|
+
}
|
|
119
|
+
else if (codeUnit >= 0xd800 &&
|
|
120
|
+
codeUnit <= 0xdbff &&
|
|
121
|
+
index + 1 < value.length &&
|
|
122
|
+
value.charCodeAt(index + 1) >= 0xdc00 &&
|
|
123
|
+
value.charCodeAt(index + 1) <= 0xdfff) {
|
|
124
|
+
byteLength += 4;
|
|
125
|
+
index += 1;
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
byteLength += 3;
|
|
129
|
+
}
|
|
130
|
+
if (byteLength > maxBytes)
|
|
131
|
+
return byteLength;
|
|
132
|
+
}
|
|
133
|
+
return byteLength;
|
|
134
|
+
};
|
|
135
|
+
const runtimeAssetAbortReason = (signal) => signal.reason ?? new DOMException('Runtime asset load aborted', 'AbortError');
|
|
136
|
+
const requireBridgeMaxAssetBytes = (value) => {
|
|
137
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
138
|
+
throw new TypeError('Worker asset bridge maxAssetBytes must be a positive safe integer');
|
|
139
|
+
}
|
|
140
|
+
return value;
|
|
141
|
+
};
|
|
142
|
+
const cancelResponseBody = (response, reason) => {
|
|
143
|
+
try {
|
|
144
|
+
void Promise.resolve(response.body?.cancel(reason)).catch(() => undefined);
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// Preserve the asset failure that caused cancellation.
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
const readAbortableArrayBuffer = async (source, signal) => {
|
|
151
|
+
if (signal.aborted)
|
|
152
|
+
throw runtimeAssetAbortReason(signal);
|
|
153
|
+
let cancelOnAbort;
|
|
154
|
+
const aborted = new Promise((_resolve, reject) => {
|
|
155
|
+
cancelOnAbort = () => reject(runtimeAssetAbortReason(signal));
|
|
156
|
+
signal.addEventListener('abort', cancelOnAbort, { once: true });
|
|
157
|
+
});
|
|
158
|
+
try {
|
|
159
|
+
const materialized = source.arrayBuffer();
|
|
160
|
+
const bytes = await Promise.race([materialized, aborted]);
|
|
161
|
+
if (signal.aborted)
|
|
162
|
+
throw runtimeAssetAbortReason(signal);
|
|
163
|
+
return bytes;
|
|
164
|
+
}
|
|
165
|
+
finally {
|
|
166
|
+
if (cancelOnAbort)
|
|
167
|
+
signal.removeEventListener('abort', cancelOnAbort);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
const transferBuffer = (bytes, transferOwnership = false) => {
|
|
171
|
+
const canonicalBytes = canonicalUint8Array(bytes);
|
|
172
|
+
const buffer = canonicalBytes.buffer;
|
|
173
|
+
const transferableBuffer = buffer instanceof ArrayBuffer ? buffer : undefined;
|
|
174
|
+
const transferableByteLength = transferableBuffer && arrayBufferByteLengthGetter
|
|
175
|
+
? Reflect.apply(arrayBufferByteLengthGetter, transferableBuffer, [])
|
|
176
|
+
: undefined;
|
|
177
|
+
return transferOwnership &&
|
|
178
|
+
transferableBuffer &&
|
|
179
|
+
canonicalBytes.byteOffset === 0 &&
|
|
180
|
+
canonicalBytes.byteLength === transferableByteLength
|
|
181
|
+
? transferableBuffer
|
|
182
|
+
: Uint8Array.from(canonicalBytes).buffer;
|
|
183
|
+
};
|
|
184
|
+
const expectedAssetsForRuntime = (runtime) => new Set(RUNTIME_LOAD_ASSETS[runtime]);
|
|
185
|
+
const integrityKey = (config) => JSON.stringify(Object.entries(config.integrity || {})
|
|
186
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
187
|
+
.map(([asset, entry]) => [
|
|
188
|
+
asset,
|
|
189
|
+
typeof entry === 'string'
|
|
190
|
+
? entry
|
|
191
|
+
: {
|
|
192
|
+
sha256: entry.sha256,
|
|
193
|
+
bytes: entry.bytes,
|
|
194
|
+
mediaType: entry.mediaType,
|
|
195
|
+
uncompressedSha256: entry.uncompressedSha256,
|
|
196
|
+
uncompressedBytes: entry.uncompressedBytes
|
|
197
|
+
}
|
|
198
|
+
]));
|
|
199
|
+
const allowedBaseUrlsKey = (config) => JSON.stringify([...(config.allowedBaseUrls || [])].sort());
|
|
13
200
|
class RuntimeLoadProgress {
|
|
14
|
-
|
|
201
|
+
samples = new Map();
|
|
15
202
|
expectedAssets;
|
|
203
|
+
phaseId;
|
|
16
204
|
progress;
|
|
205
|
+
lockedTotal;
|
|
206
|
+
measurementInvalid = false;
|
|
17
207
|
constructor(runtime) {
|
|
18
208
|
this.expectedAssets = expectedAssetsForRuntime(runtime);
|
|
209
|
+
this.phaseId = `${runtime}:runtime-assets`;
|
|
19
210
|
this.reset();
|
|
20
211
|
}
|
|
21
212
|
reset(progress) {
|
|
22
213
|
this.progress = progress;
|
|
23
|
-
this.
|
|
214
|
+
this.samples.clear();
|
|
215
|
+
this.lockedTotal = undefined;
|
|
216
|
+
this.measurementInvalid = false;
|
|
24
217
|
for (const asset of this.expectedAssets)
|
|
25
|
-
this.
|
|
218
|
+
this.samples.set(asset, { loaded: 0 });
|
|
26
219
|
this.emit();
|
|
27
220
|
}
|
|
28
221
|
update(asset, loaded, total) {
|
|
29
222
|
if (!this.expectedAssets.has(asset))
|
|
30
223
|
return;
|
|
31
|
-
|
|
32
|
-
|
|
224
|
+
if (!Number.isSafeInteger(loaded) || loaded < 0) {
|
|
225
|
+
this.measurementInvalid = true;
|
|
226
|
+
this.emit();
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
const previous = this.samples.get(asset) || { loaded: 0 };
|
|
230
|
+
let nextTotal = previous.total;
|
|
231
|
+
if (total !== undefined) {
|
|
232
|
+
if (!Number.isSafeInteger(total) || total <= 0) {
|
|
233
|
+
this.measurementInvalid = true;
|
|
234
|
+
}
|
|
235
|
+
else if (previous.total !== undefined && previous.total !== total) {
|
|
236
|
+
this.measurementInvalid = true;
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
nextTotal = total;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
const nextLoaded = Math.max(previous.loaded, loaded);
|
|
243
|
+
if (nextTotal !== undefined && nextLoaded > nextTotal) {
|
|
244
|
+
this.measurementInvalid = true;
|
|
245
|
+
}
|
|
246
|
+
this.samples.set(asset, {
|
|
247
|
+
loaded: nextLoaded,
|
|
248
|
+
...(nextTotal === undefined ? {} : { total: nextTotal })
|
|
249
|
+
});
|
|
33
250
|
this.emit();
|
|
34
251
|
}
|
|
252
|
+
activity(phase, asset) {
|
|
253
|
+
if (!this.progress)
|
|
254
|
+
return;
|
|
255
|
+
const action = phase === 'decompressing' ? 'Decompressing' : 'Verifying';
|
|
256
|
+
const label = `${action} ${asset}`;
|
|
257
|
+
if (this.progress.report) {
|
|
258
|
+
this.progress.report({
|
|
259
|
+
kind: 'activity',
|
|
260
|
+
phase,
|
|
261
|
+
phaseId: `${this.phaseId}:${asset}`,
|
|
262
|
+
label
|
|
263
|
+
});
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
this.progress.set?.(0, label);
|
|
267
|
+
}
|
|
35
268
|
emit() {
|
|
36
269
|
if (!this.progress)
|
|
37
270
|
return;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
let
|
|
41
|
-
for (const
|
|
42
|
-
total
|
|
43
|
-
|
|
271
|
+
let completedBytes = 0;
|
|
272
|
+
let totalBytes = 0;
|
|
273
|
+
let allTotalsKnown = this.samples.size > 0;
|
|
274
|
+
for (const sample of this.samples.values()) {
|
|
275
|
+
if (sample.total === undefined) {
|
|
276
|
+
allTotalsKnown = false;
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
completedBytes += sample.loaded;
|
|
280
|
+
totalBytes += sample.total;
|
|
281
|
+
}
|
|
282
|
+
if (!Number.isSafeInteger(completedBytes) || !Number.isSafeInteger(totalBytes)) {
|
|
283
|
+
this.measurementInvalid = true;
|
|
284
|
+
}
|
|
285
|
+
if (allTotalsKnown && this.lockedTotal === undefined)
|
|
286
|
+
this.lockedTotal = totalBytes;
|
|
287
|
+
if (this.lockedTotal !== undefined && this.lockedTotal !== totalBytes) {
|
|
288
|
+
this.measurementInvalid = true;
|
|
289
|
+
}
|
|
290
|
+
const measurement = allTotalsKnown && !this.measurementInvalid && totalBytes > 0
|
|
291
|
+
? { kind: 'bytes', completed: completedBytes, total: totalBytes }
|
|
292
|
+
: undefined;
|
|
293
|
+
if (this.progress.report) {
|
|
294
|
+
this.progress.report({
|
|
295
|
+
kind: 'activity',
|
|
296
|
+
phase: 'downloading',
|
|
297
|
+
phaseId: this.phaseId,
|
|
298
|
+
label: 'Downloading runtime assets',
|
|
299
|
+
...(measurement ? { measurement } : {})
|
|
300
|
+
});
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
this.progress.set?.(measurement ? measurement.completed / measurement.total : 0);
|
|
44
304
|
}
|
|
45
305
|
}
|
|
46
306
|
export class WorkerAssetBridge {
|
|
@@ -48,44 +308,190 @@ export class WorkerAssetBridge {
|
|
|
48
308
|
runtime;
|
|
49
309
|
config;
|
|
50
310
|
progress;
|
|
51
|
-
|
|
311
|
+
expectedAssets;
|
|
312
|
+
pythonPackageAssets = new Set();
|
|
313
|
+
generation = 0;
|
|
314
|
+
state = 'active';
|
|
315
|
+
activeLoads = new Set();
|
|
316
|
+
maxAssetBytes;
|
|
317
|
+
constructor(worker, runtime, config, progress, maxAssetBytes = MAX_RUNTIME_ASSET_BYTES) {
|
|
52
318
|
this.worker = worker;
|
|
53
319
|
this.runtime = runtime;
|
|
54
320
|
this.config = config;
|
|
321
|
+
this.maxAssetBytes = requireBridgeMaxAssetBytes(maxAssetBytes);
|
|
55
322
|
this.progress = new RuntimeLoadProgress(runtime);
|
|
323
|
+
this.expectedAssets = expectedAssetsForRuntime(runtime);
|
|
56
324
|
this.progress.reset(progress);
|
|
57
325
|
}
|
|
58
|
-
matches(config) {
|
|
59
|
-
return (this.
|
|
326
|
+
matches(config, maxAssetBytes = this.maxAssetBytes) {
|
|
327
|
+
return (this.state === 'active' &&
|
|
328
|
+
this.maxAssetBytes === requireBridgeMaxAssetBytes(maxAssetBytes) &&
|
|
329
|
+
this.config.baseUrl === config.baseUrl &&
|
|
60
330
|
this.config.loader === config.loader &&
|
|
331
|
+
integrityKey(this.config) === integrityKey(config) &&
|
|
332
|
+
allowedBaseUrlsKey(this.config) === allowedBaseUrlsKey(config) &&
|
|
61
333
|
this.config.useAssetBridge === config.useAssetBridge);
|
|
62
334
|
}
|
|
63
|
-
rebind(worker, config, progress) {
|
|
64
|
-
this.
|
|
65
|
-
|
|
66
|
-
|
|
335
|
+
rebind(worker, config, progress, maxAssetBytes = this.maxAssetBytes) {
|
|
336
|
+
if (this.state === 'disposed') {
|
|
337
|
+
throw new Error('Cannot rebind a disposed worker asset bridge');
|
|
338
|
+
}
|
|
339
|
+
if (this.state === 'rebinding') {
|
|
340
|
+
throw new Error('Cannot rebind a worker asset bridge while another rebind is active');
|
|
341
|
+
}
|
|
342
|
+
const nextMaxAssetBytes = requireBridgeMaxAssetBytes(maxAssetBytes);
|
|
343
|
+
const preservePythonPackageAssets = this.matches(config, nextMaxAssetBytes);
|
|
344
|
+
this.state = 'rebinding';
|
|
345
|
+
const generation = ++this.generation;
|
|
346
|
+
this.progress.reset();
|
|
347
|
+
try {
|
|
348
|
+
this.abortActiveLoads();
|
|
349
|
+
if (!preservePythonPackageAssets)
|
|
350
|
+
this.pythonPackageAssets.clear();
|
|
351
|
+
if (this.state !== 'rebinding' || this.generation !== generation) {
|
|
352
|
+
throw new Error('Cannot rebind a disposed worker asset bridge');
|
|
353
|
+
}
|
|
354
|
+
this.worker = worker;
|
|
355
|
+
this.config = config;
|
|
356
|
+
this.maxAssetBytes = nextMaxAssetBytes;
|
|
357
|
+
this.progress.reset(progress);
|
|
358
|
+
if (this.state !== 'rebinding' || this.generation !== generation) {
|
|
359
|
+
throw new Error('Cannot rebind a disposed worker asset bridge');
|
|
360
|
+
}
|
|
361
|
+
this.state = 'active';
|
|
362
|
+
}
|
|
363
|
+
catch (error) {
|
|
364
|
+
if (this.state === 'rebinding' && this.generation === generation)
|
|
365
|
+
this.dispose();
|
|
366
|
+
throw error;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
dispose() {
|
|
370
|
+
if (this.state === 'disposed')
|
|
371
|
+
return;
|
|
372
|
+
this.state = 'disposed';
|
|
373
|
+
this.generation += 1;
|
|
374
|
+
this.progress.reset();
|
|
375
|
+
this.pythonPackageAssets.clear();
|
|
376
|
+
this.abortActiveLoads();
|
|
67
377
|
}
|
|
68
378
|
resetProgress(progress) {
|
|
379
|
+
if (this.state !== 'active')
|
|
380
|
+
return;
|
|
69
381
|
this.progress.reset(progress);
|
|
70
382
|
}
|
|
383
|
+
configuredReceiptByteLimit(asset, value) {
|
|
384
|
+
if (value === undefined)
|
|
385
|
+
return undefined;
|
|
386
|
+
if (!Number.isSafeInteger(value) || value < 0) {
|
|
387
|
+
throw new ProtocolError(`Runtime asset ${asset} has an invalid integrity byte count`, {
|
|
388
|
+
phase: 'asset',
|
|
389
|
+
runtimeId: this.runtime
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
const byteLimit = value;
|
|
393
|
+
if (byteLimit > this.maxAssetBytes) {
|
|
394
|
+
throw runtimeAssetSizeError(asset, this.maxAssetBytes);
|
|
395
|
+
}
|
|
396
|
+
return byteLimit;
|
|
397
|
+
}
|
|
398
|
+
runtimeAssetByteLimit(asset) {
|
|
399
|
+
const configured = this.config.integrity?.[asset];
|
|
400
|
+
if (!configured || typeof configured === 'string')
|
|
401
|
+
return this.maxAssetBytes;
|
|
402
|
+
return (this.configuredReceiptByteLimit(asset, configured.uncompressedBytes ?? configured.bytes) ?? this.maxAssetBytes);
|
|
403
|
+
}
|
|
404
|
+
sourceAssetByteLimit(asset) {
|
|
405
|
+
const configured = this.config.integrity?.[asset];
|
|
406
|
+
if (!configured || typeof configured === 'string')
|
|
407
|
+
return this.maxAssetBytes;
|
|
408
|
+
const paired = configured.uncompressedBytes !== undefined ||
|
|
409
|
+
configured.uncompressedSha256 !== undefined;
|
|
410
|
+
if (asset.endsWith('.gz')) {
|
|
411
|
+
if (!paired)
|
|
412
|
+
return this.maxAssetBytes;
|
|
413
|
+
const deliveryLimit = this.configuredReceiptByteLimit(asset, configured.bytes);
|
|
414
|
+
const runtimeLimit = this.configuredReceiptByteLimit(asset, configured.uncompressedBytes);
|
|
415
|
+
return deliveryLimit !== undefined || runtimeLimit !== undefined
|
|
416
|
+
? Math.max(deliveryLimit ?? 0, runtimeLimit ?? 0)
|
|
417
|
+
: this.maxAssetBytes;
|
|
418
|
+
}
|
|
419
|
+
const deliveryLimit = this.configuredReceiptByteLimit(asset, configured.bytes);
|
|
420
|
+
const runtimeLimit = this.configuredReceiptByteLimit(asset, configured.uncompressedBytes);
|
|
421
|
+
return deliveryLimit !== undefined || runtimeLimit !== undefined
|
|
422
|
+
? Math.max(deliveryLimit ?? 0, runtimeLimit ?? 0)
|
|
423
|
+
: this.maxAssetBytes;
|
|
424
|
+
}
|
|
71
425
|
handleMessage(event) {
|
|
72
426
|
const assetRequest = event.data?.assetRequest;
|
|
73
427
|
if (assetRequest) {
|
|
74
|
-
|
|
428
|
+
if (this.state === 'active')
|
|
429
|
+
void this.respond(assetRequest);
|
|
75
430
|
return true;
|
|
76
431
|
}
|
|
77
432
|
const assetProgress = event.data?.assetProgress;
|
|
78
433
|
if (assetProgress) {
|
|
79
|
-
this.
|
|
434
|
+
if (this.state === 'active') {
|
|
435
|
+
this.progress.update(assetProgress.asset, assetProgress.loaded, assetProgress.total);
|
|
436
|
+
}
|
|
80
437
|
return true;
|
|
81
438
|
}
|
|
82
439
|
return false;
|
|
83
440
|
}
|
|
84
441
|
async respond(request) {
|
|
442
|
+
if (this.state !== 'active')
|
|
443
|
+
return;
|
|
444
|
+
const worker = this.worker;
|
|
445
|
+
const generation = this.generation;
|
|
446
|
+
const controller = new AbortController();
|
|
447
|
+
this.activeLoads.add(controller);
|
|
85
448
|
try {
|
|
86
|
-
const loaded = await this.loadAsset(request.asset);
|
|
87
|
-
const
|
|
88
|
-
this.
|
|
449
|
+
const loaded = await this.loadAsset(request.asset, controller.signal);
|
|
450
|
+
const deliveryBytes = canonicalUint8Array(loaded.bytes);
|
|
451
|
+
const sourceAssetByteLimit = this.sourceAssetByteLimit(request.asset);
|
|
452
|
+
const runtimeAssetByteLimit = this.runtimeAssetByteLimit(request.asset);
|
|
453
|
+
requireRuntimeAssetSize(request.asset, deliveryBytes.byteLength, sourceAssetByteLimit);
|
|
454
|
+
let normalizedRuntimeBytes;
|
|
455
|
+
if (request.asset.endsWith('.gz')) {
|
|
456
|
+
this.progress.activity('decompressing', request.asset);
|
|
457
|
+
normalizedRuntimeBytes = await decompressGzip(deliveryBytes, request.asset, runtimeAssetByteLimit, controller.signal);
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
460
|
+
normalizedRuntimeBytes = deliveryBytes;
|
|
461
|
+
}
|
|
462
|
+
const runtimeBytes = canonicalUint8Array(normalizedRuntimeBytes);
|
|
463
|
+
requireRuntimeAssetSize(request.asset, runtimeBytes.byteLength, runtimeAssetByteLimit);
|
|
464
|
+
const httpDecodedGzip = (loaded.contentEncoding || '')
|
|
465
|
+
.toLowerCase()
|
|
466
|
+
.split(',')
|
|
467
|
+
.map((encoding) => encoding.trim())
|
|
468
|
+
.includes('gzip');
|
|
469
|
+
if (controller.signal.aborted || generation !== this.generation)
|
|
470
|
+
return;
|
|
471
|
+
let cancelOnAbort;
|
|
472
|
+
const aborted = new Promise((_resolve, reject) => {
|
|
473
|
+
cancelOnAbort = () => reject(runtimeAssetAbortReason(controller.signal));
|
|
474
|
+
controller.signal.addEventListener('abort', cancelOnAbort, { once: true });
|
|
475
|
+
});
|
|
476
|
+
try {
|
|
477
|
+
if (this.config.integrity?.[request.asset]) {
|
|
478
|
+
this.progress.activity('verifying', request.asset);
|
|
479
|
+
}
|
|
480
|
+
const verification = this.verifyIntegrity(request.asset, deliveryBytes, runtimeBytes, loaded.mimeType, !httpDecodedGzip);
|
|
481
|
+
await Promise.race([verification, aborted]);
|
|
482
|
+
}
|
|
483
|
+
finally {
|
|
484
|
+
if (cancelOnAbort) {
|
|
485
|
+
controller.signal.removeEventListener('abort', cancelOnAbort);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
if (controller.signal.aborted || generation !== this.generation)
|
|
489
|
+
return;
|
|
490
|
+
if (this.runtime === 'python' && request.asset === 'pyodide-lock.json') {
|
|
491
|
+
this.pythonPackageAssets = readPythonPackageAssets(runtimeBytes);
|
|
492
|
+
}
|
|
493
|
+
const buffer = transferBuffer(runtimeBytes, normalizedRuntimeBytes === deliveryBytes ? loaded.transferOwnership : true);
|
|
494
|
+
worker.postMessage({
|
|
89
495
|
assetResponse: {
|
|
90
496
|
id: request.id,
|
|
91
497
|
ok: true,
|
|
@@ -95,104 +501,422 @@ export class WorkerAssetBridge {
|
|
|
95
501
|
}, [buffer]);
|
|
96
502
|
}
|
|
97
503
|
catch (error) {
|
|
98
|
-
this.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
504
|
+
if (controller.signal.aborted || generation !== this.generation)
|
|
505
|
+
return;
|
|
506
|
+
try {
|
|
507
|
+
worker.postMessage({
|
|
508
|
+
assetResponse: {
|
|
509
|
+
id: request.id,
|
|
510
|
+
ok: false,
|
|
511
|
+
error: error instanceof Error ? error.message : String(error)
|
|
512
|
+
}
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
catch {
|
|
516
|
+
// The worker may already be terminated. There is no remaining response channel.
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
finally {
|
|
520
|
+
this.activeLoads.delete(controller);
|
|
105
521
|
}
|
|
106
522
|
}
|
|
107
|
-
async loadAsset(asset) {
|
|
108
|
-
|
|
523
|
+
async loadAsset(asset, signal) {
|
|
524
|
+
if (!this.expectedAssets.has(asset) && !this.pythonPackageAssets.has(asset)) {
|
|
525
|
+
throw new Error(`Unexpected ${this.runtime} runtime asset: ${asset}`);
|
|
526
|
+
}
|
|
527
|
+
if (this.config.integrity && !Object.hasOwn(this.config.integrity, asset)) {
|
|
528
|
+
throw new Error(`Runtime asset ${asset} is missing integrity metadata`);
|
|
529
|
+
}
|
|
530
|
+
if (signal.aborted) {
|
|
531
|
+
throw runtimeAssetAbortReason(signal);
|
|
532
|
+
}
|
|
533
|
+
const sourceAssetByteLimit = this.sourceAssetByteLimit(asset);
|
|
534
|
+
this.runtimeAssetByteLimit(asset);
|
|
535
|
+
const reportProgress = (loaded, total) => {
|
|
536
|
+
if (!signal.aborted)
|
|
537
|
+
this.progress.update(asset, loaded, total);
|
|
538
|
+
};
|
|
109
539
|
if (this.config.loader) {
|
|
110
|
-
const
|
|
540
|
+
const pendingResult = Promise.resolve(this.config.loader({
|
|
111
541
|
runtime: this.runtime,
|
|
112
542
|
asset,
|
|
113
|
-
reportProgress
|
|
114
|
-
|
|
543
|
+
reportProgress,
|
|
544
|
+
signal
|
|
545
|
+
}));
|
|
546
|
+
const result = await new Promise((resolve, reject) => {
|
|
547
|
+
let settled = false;
|
|
548
|
+
const onAbort = () => {
|
|
549
|
+
if (settled)
|
|
550
|
+
return;
|
|
551
|
+
settled = true;
|
|
552
|
+
signal.removeEventListener('abort', onAbort);
|
|
553
|
+
reject(runtimeAssetAbortReason(signal));
|
|
554
|
+
};
|
|
555
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
556
|
+
void pendingResult.then((value) => {
|
|
557
|
+
if (settled)
|
|
558
|
+
return;
|
|
559
|
+
settled = true;
|
|
560
|
+
signal.removeEventListener('abort', onAbort);
|
|
561
|
+
resolve(value);
|
|
562
|
+
}, (error) => {
|
|
563
|
+
if (settled)
|
|
564
|
+
return;
|
|
565
|
+
settled = true;
|
|
566
|
+
signal.removeEventListener('abort', onAbort);
|
|
567
|
+
reject(error);
|
|
568
|
+
});
|
|
569
|
+
if (signal.aborted)
|
|
570
|
+
onAbort();
|
|
571
|
+
});
|
|
572
|
+
if (signal.aborted) {
|
|
573
|
+
throw runtimeAssetAbortReason(signal);
|
|
574
|
+
}
|
|
575
|
+
const loaded = await this.normalizeLoaderResult(result, asset, signal, sourceAssetByteLimit);
|
|
576
|
+
if (signal.aborted) {
|
|
577
|
+
throw runtimeAssetAbortReason(signal);
|
|
578
|
+
}
|
|
115
579
|
if (loaded)
|
|
116
580
|
return loaded;
|
|
117
581
|
}
|
|
118
|
-
return await this.fetchAsset(
|
|
582
|
+
return await this.fetchAsset(asset, asset, signal, sourceAssetByteLimit);
|
|
119
583
|
}
|
|
120
|
-
async
|
|
584
|
+
async verifyIntegrity(asset, deliveryBytes, runtimeBytes, mimeType, hasDeliveryBytes = true) {
|
|
585
|
+
const configured = this.config.integrity?.[asset];
|
|
586
|
+
if (!configured)
|
|
587
|
+
return;
|
|
588
|
+
const expected = typeof configured === 'string' ? { sha256: configured } : configured;
|
|
589
|
+
if (expected.uncompressedSha256 !== undefined || expected.uncompressedBytes !== undefined) {
|
|
590
|
+
if (hasDeliveryBytes) {
|
|
591
|
+
await verifyRuntimeAssetPair({
|
|
592
|
+
asset,
|
|
593
|
+
compressed: deliveryBytes,
|
|
594
|
+
uncompressed: runtimeBytes,
|
|
595
|
+
expected,
|
|
596
|
+
mimeType
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
else {
|
|
600
|
+
await verifyRuntimeAssetIntegrity({
|
|
601
|
+
asset,
|
|
602
|
+
bytes: runtimeBytes,
|
|
603
|
+
expected,
|
|
604
|
+
stage: 'uncompressed',
|
|
605
|
+
mimeType
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
await verifyRuntimeAssetIntegrity({
|
|
611
|
+
asset,
|
|
612
|
+
bytes: runtimeBytes,
|
|
613
|
+
expected: {
|
|
614
|
+
...expected,
|
|
615
|
+
uncompressedSha256: expected.sha256,
|
|
616
|
+
uncompressedBytes: expected.bytes ?? runtimeBytes.byteLength
|
|
617
|
+
},
|
|
618
|
+
stage: 'uncompressed',
|
|
619
|
+
mimeType
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
async normalizeLoaderResult(result, asset, signal, maxAssetBytes) {
|
|
121
623
|
if (!result)
|
|
122
624
|
return null;
|
|
123
625
|
if (typeof result === 'string' || result instanceof URL) {
|
|
124
|
-
return await this.fetchAsset(String(result), asset);
|
|
125
|
-
}
|
|
126
|
-
if (result instanceof ArrayBuffer) {
|
|
127
|
-
const bytes = new Uint8Array(result);
|
|
128
|
-
this.progress.update(asset, bytes.byteLength, bytes.byteLength);
|
|
129
|
-
return { bytes };
|
|
626
|
+
return await this.fetchAsset(String(result), asset, signal, maxAssetBytes);
|
|
130
627
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
628
|
+
const directBytes = snapshotLoaderBytes(result, asset, maxAssetBytes);
|
|
629
|
+
if (directBytes) {
|
|
630
|
+
this.progress.update(asset, directBytes.byteLength, directBytes.byteLength);
|
|
631
|
+
return { bytes: directBytes, transferOwnership: true };
|
|
134
632
|
}
|
|
135
|
-
|
|
136
|
-
|
|
633
|
+
const directBlob = tryCanonicalBlob(result);
|
|
634
|
+
const wrappedBlob = typeof result === 'object' && result !== null && 'data' in result
|
|
635
|
+
? {
|
|
636
|
+
value: tryCanonicalBlob(result.data),
|
|
637
|
+
mimeType: result.mimeType
|
|
638
|
+
}
|
|
639
|
+
: undefined;
|
|
640
|
+
const loaderBlob = directBlob
|
|
641
|
+
? { ...directBlob, mimeType: directBlob.type || undefined }
|
|
642
|
+
: wrappedBlob?.value
|
|
643
|
+
? {
|
|
644
|
+
...wrappedBlob.value,
|
|
645
|
+
mimeType: wrappedBlob.mimeType || wrappedBlob.value.type || undefined
|
|
646
|
+
}
|
|
647
|
+
: undefined;
|
|
648
|
+
if (loaderBlob) {
|
|
649
|
+
const { blob, size, mimeType } = loaderBlob;
|
|
650
|
+
requireRuntimeAssetSize(asset, size, maxAssetBytes);
|
|
651
|
+
const source = await readAbortableArrayBuffer(blob, signal);
|
|
652
|
+
const bytes = snapshotMaterializedArrayBuffer(source, asset, maxAssetBytes);
|
|
137
653
|
this.progress.update(asset, bytes.byteLength, bytes.byteLength);
|
|
138
|
-
return { bytes, mimeType:
|
|
654
|
+
return { bytes, mimeType, transferOwnership: true };
|
|
139
655
|
}
|
|
140
656
|
if ('url' in result && result.url) {
|
|
141
|
-
return await this.fetchAsset(String(result.url), asset);
|
|
657
|
+
return await this.fetchAsset(String(result.url), asset, signal, maxAssetBytes);
|
|
142
658
|
}
|
|
143
659
|
if ('data' in result) {
|
|
144
660
|
if (typeof result.data === 'string') {
|
|
145
|
-
|
|
661
|
+
requireRuntimeAssetSize(asset, boundedUtf8ByteLength(result.data, maxAssetBytes), maxAssetBytes);
|
|
662
|
+
const bytes = canonicalUint8Array(encoder.encode(result.data));
|
|
663
|
+
requireRuntimeAssetSize(asset, bytes.byteLength, maxAssetBytes);
|
|
146
664
|
this.progress.update(asset, bytes.byteLength, bytes.byteLength);
|
|
147
|
-
return { bytes, mimeType: result.mimeType };
|
|
665
|
+
return { bytes, mimeType: result.mimeType, transferOwnership: true };
|
|
148
666
|
}
|
|
149
|
-
|
|
150
|
-
|
|
667
|
+
const bytes = snapshotLoaderBytes(result.data, asset, maxAssetBytes);
|
|
668
|
+
if (bytes) {
|
|
151
669
|
this.progress.update(asset, bytes.byteLength, bytes.byteLength);
|
|
152
|
-
return {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
670
|
+
return {
|
|
671
|
+
bytes,
|
|
672
|
+
mimeType: result.mimeType,
|
|
673
|
+
transferOwnership: true
|
|
674
|
+
};
|
|
157
675
|
}
|
|
158
|
-
const bytes = new Uint8Array(await result.data.arrayBuffer());
|
|
159
|
-
this.progress.update(asset, bytes.byteLength, bytes.byteLength);
|
|
160
|
-
return { bytes, mimeType: result.mimeType || result.data.type || undefined };
|
|
161
676
|
}
|
|
162
677
|
return null;
|
|
163
678
|
}
|
|
164
|
-
async fetchAsset(url, asset) {
|
|
165
|
-
const
|
|
166
|
-
if (
|
|
167
|
-
throw
|
|
168
|
-
const
|
|
679
|
+
async fetchAsset(url, asset, signal, maxAssetBytes = this.sourceAssetByteLimit(asset)) {
|
|
680
|
+
const requestUrl = this.requireAllowedAssetUrl(asset, url);
|
|
681
|
+
if (signal.aborted)
|
|
682
|
+
throw runtimeAssetAbortReason(signal);
|
|
683
|
+
const pendingResponse = Promise.resolve(fetch(requestUrl.href, {
|
|
684
|
+
signal,
|
|
685
|
+
credentials: 'omit',
|
|
686
|
+
redirect: 'error',
|
|
687
|
+
referrerPolicy: 'no-referrer'
|
|
688
|
+
}));
|
|
689
|
+
const response = await new Promise((resolve, reject) => {
|
|
690
|
+
let settled = false;
|
|
691
|
+
const onAbort = () => {
|
|
692
|
+
if (settled)
|
|
693
|
+
return;
|
|
694
|
+
settled = true;
|
|
695
|
+
signal.removeEventListener('abort', onAbort);
|
|
696
|
+
reject(runtimeAssetAbortReason(signal));
|
|
697
|
+
};
|
|
698
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
699
|
+
void pendingResponse.then((candidate) => {
|
|
700
|
+
if (settled) {
|
|
701
|
+
const reason = runtimeAssetAbortReason(signal);
|
|
702
|
+
cancelResponseBody(candidate, reason);
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
settled = true;
|
|
706
|
+
signal.removeEventListener('abort', onAbort);
|
|
707
|
+
resolve(candidate);
|
|
708
|
+
}, (error) => {
|
|
709
|
+
if (settled)
|
|
710
|
+
return;
|
|
711
|
+
settled = true;
|
|
712
|
+
signal.removeEventListener('abort', onAbort);
|
|
713
|
+
reject(error);
|
|
714
|
+
});
|
|
715
|
+
if (signal.aborted)
|
|
716
|
+
onAbort();
|
|
717
|
+
});
|
|
718
|
+
if (signal.aborted) {
|
|
719
|
+
const reason = runtimeAssetAbortReason(signal);
|
|
720
|
+
cancelResponseBody(response, reason);
|
|
721
|
+
throw reason;
|
|
722
|
+
}
|
|
723
|
+
if (response.url) {
|
|
724
|
+
let finalResponseUrl;
|
|
725
|
+
try {
|
|
726
|
+
finalResponseUrl = new URL(response.url).href;
|
|
727
|
+
}
|
|
728
|
+
catch {
|
|
729
|
+
const error = new Error(`Runtime asset ${asset} final response URL does not match the requested asset`);
|
|
730
|
+
cancelResponseBody(response, error);
|
|
731
|
+
throw error;
|
|
732
|
+
}
|
|
733
|
+
if (response.redirected || finalResponseUrl !== requestUrl.href) {
|
|
734
|
+
const error = new Error(`Runtime asset ${asset} final response URL does not match the requested asset`);
|
|
735
|
+
cancelResponseBody(response, error);
|
|
736
|
+
throw error;
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
if (!response.ok) {
|
|
740
|
+
const error = new Error(`Failed to load ${asset}: ${response.status}`);
|
|
741
|
+
cancelResponseBody(response, error);
|
|
742
|
+
throw error;
|
|
743
|
+
}
|
|
744
|
+
const originalContentLength = response.headers.get('x-wasm-idle-original-content-length');
|
|
745
|
+
const contentLengthHeader = originalContentLength !== null
|
|
746
|
+
? 'x-wasm-idle-original-content-length'
|
|
747
|
+
: 'content-length';
|
|
748
|
+
const rawContentLength = originalContentLength ?? response.headers.get('content-length');
|
|
749
|
+
let contentLength;
|
|
750
|
+
if (rawContentLength !== null) {
|
|
751
|
+
const normalizedContentLength = rawContentLength.trim();
|
|
752
|
+
const parsedContentLength = Number(normalizedContentLength);
|
|
753
|
+
if (!/^\d+$/u.test(normalizedContentLength) ||
|
|
754
|
+
!Number.isSafeInteger(parsedContentLength)) {
|
|
755
|
+
const error = new ProtocolError(`Runtime asset ${asset} has an invalid ${contentLengthHeader}`, { phase: 'asset', runtimeId: this.runtime });
|
|
756
|
+
cancelResponseBody(response, error);
|
|
757
|
+
throw error;
|
|
758
|
+
}
|
|
759
|
+
contentLength = parsedContentLength;
|
|
760
|
+
}
|
|
761
|
+
if (contentLength !== undefined && contentLength > maxAssetBytes) {
|
|
762
|
+
const error = runtimeAssetSizeError(asset, maxAssetBytes);
|
|
763
|
+
cancelResponseBody(response, error);
|
|
764
|
+
throw error;
|
|
765
|
+
}
|
|
169
766
|
const mimeType = response.headers.get('content-type') || undefined;
|
|
767
|
+
const contentEncoding = response.headers.get('content-encoding') || undefined;
|
|
170
768
|
if (!response.body) {
|
|
171
|
-
const bytes =
|
|
769
|
+
const bytes = snapshotMaterializedArrayBuffer(await readAbortableArrayBuffer(response, signal), asset, maxAssetBytes);
|
|
172
770
|
this.progress.update(asset, bytes.byteLength, contentLength ?? bytes.byteLength);
|
|
173
|
-
return { bytes, mimeType };
|
|
771
|
+
return { bytes, contentEncoding, mimeType, transferOwnership: true };
|
|
174
772
|
}
|
|
175
773
|
const reader = response.body.getReader();
|
|
774
|
+
let readerCancelled = false;
|
|
775
|
+
if (signal.aborted) {
|
|
776
|
+
const reason = runtimeAssetAbortReason(signal);
|
|
777
|
+
readerCancelled = true;
|
|
778
|
+
try {
|
|
779
|
+
void reader.cancel(reason).catch(() => undefined);
|
|
780
|
+
}
|
|
781
|
+
catch { }
|
|
782
|
+
try {
|
|
783
|
+
reader.releaseLock();
|
|
784
|
+
}
|
|
785
|
+
catch { }
|
|
786
|
+
throw reason;
|
|
787
|
+
}
|
|
788
|
+
let cancelOnAbort;
|
|
789
|
+
const aborted = new Promise((_resolve, reject) => {
|
|
790
|
+
cancelOnAbort = () => {
|
|
791
|
+
const reason = runtimeAssetAbortReason(signal);
|
|
792
|
+
if (!readerCancelled) {
|
|
793
|
+
readerCancelled = true;
|
|
794
|
+
try {
|
|
795
|
+
void reader.cancel(reason).catch(() => undefined);
|
|
796
|
+
}
|
|
797
|
+
catch { }
|
|
798
|
+
}
|
|
799
|
+
reject(reason);
|
|
800
|
+
};
|
|
801
|
+
signal.addEventListener('abort', cancelOnAbort, { once: true });
|
|
802
|
+
});
|
|
176
803
|
let receivedLength = 0;
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
804
|
+
let bytes = new Uint8Array(Math.min(maxAssetBytes, contentLength || DEFAULT_STREAM_BUFFER_BYTES));
|
|
805
|
+
let loadedAsset;
|
|
806
|
+
let releaseError;
|
|
807
|
+
try {
|
|
808
|
+
while (true) {
|
|
809
|
+
if (signal.aborted)
|
|
810
|
+
throw runtimeAssetAbortReason(signal);
|
|
811
|
+
const pendingRead = reader.read();
|
|
812
|
+
const { done, value } = await Promise.race([pendingRead, aborted]);
|
|
813
|
+
if (signal.aborted)
|
|
814
|
+
throw runtimeAssetAbortReason(signal);
|
|
815
|
+
if (done)
|
|
816
|
+
break;
|
|
817
|
+
if (!value)
|
|
818
|
+
continue;
|
|
819
|
+
const chunk = canonicalUint8Array(value);
|
|
820
|
+
const nextLength = receivedLength + chunk.byteLength;
|
|
821
|
+
if (nextLength > maxAssetBytes) {
|
|
822
|
+
const error = runtimeAssetSizeError(asset, maxAssetBytes);
|
|
823
|
+
readerCancelled = true;
|
|
824
|
+
try {
|
|
825
|
+
void reader.cancel(error).catch(() => undefined);
|
|
826
|
+
}
|
|
827
|
+
catch { }
|
|
828
|
+
throw error;
|
|
829
|
+
}
|
|
830
|
+
if (nextLength > bytes.byteLength) {
|
|
831
|
+
const nextCapacity = Math.min(maxAssetBytes, Math.max(nextLength, bytes.byteLength * 2));
|
|
832
|
+
const grown = new Uint8Array(nextCapacity);
|
|
833
|
+
grown.set(bytes.subarray(0, receivedLength));
|
|
834
|
+
bytes = grown;
|
|
835
|
+
}
|
|
836
|
+
bytes.set(chunk, receivedLength);
|
|
837
|
+
receivedLength = nextLength;
|
|
838
|
+
this.progress.update(asset, receivedLength, contentLength);
|
|
839
|
+
}
|
|
840
|
+
if (receivedLength !== bytes.byteLength)
|
|
841
|
+
bytes = bytes.slice(0, receivedLength);
|
|
842
|
+
this.progress.update(asset, receivedLength, contentLength ?? receivedLength);
|
|
843
|
+
loadedAsset = { bytes, contentEncoding, mimeType, transferOwnership: true };
|
|
844
|
+
}
|
|
845
|
+
catch (error) {
|
|
846
|
+
if (signal.aborted) {
|
|
847
|
+
const reason = runtimeAssetAbortReason(signal);
|
|
848
|
+
if (!readerCancelled) {
|
|
849
|
+
readerCancelled = true;
|
|
850
|
+
try {
|
|
851
|
+
void reader.cancel(reason).catch(() => undefined);
|
|
852
|
+
}
|
|
853
|
+
catch { }
|
|
854
|
+
}
|
|
855
|
+
throw reason;
|
|
856
|
+
}
|
|
857
|
+
if (!readerCancelled) {
|
|
858
|
+
readerCancelled = true;
|
|
859
|
+
try {
|
|
860
|
+
void reader.cancel(error).catch(() => undefined);
|
|
861
|
+
}
|
|
862
|
+
catch { }
|
|
863
|
+
}
|
|
864
|
+
throw error;
|
|
865
|
+
}
|
|
866
|
+
finally {
|
|
867
|
+
if (cancelOnAbort)
|
|
868
|
+
signal.removeEventListener('abort', cancelOnAbort);
|
|
869
|
+
try {
|
|
870
|
+
reader.releaseLock();
|
|
871
|
+
}
|
|
872
|
+
catch (error) {
|
|
873
|
+
if (!signal.aborted)
|
|
874
|
+
releaseError = error;
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
if (releaseError)
|
|
878
|
+
throw releaseError;
|
|
879
|
+
return loadedAsset;
|
|
880
|
+
}
|
|
881
|
+
requireAllowedAssetUrl(asset, value) {
|
|
882
|
+
let url;
|
|
883
|
+
try {
|
|
884
|
+
url = new URL(value, this.config.baseUrl);
|
|
885
|
+
}
|
|
886
|
+
catch {
|
|
887
|
+
throw new Error(`Runtime asset ${asset} has an invalid URL`);
|
|
888
|
+
}
|
|
889
|
+
if (url.protocol !== 'https:' && url.protocol !== 'http:') {
|
|
890
|
+
throw new Error(`Runtime asset ${asset} uses an unsupported URL scheme: ${url.protocol}`);
|
|
891
|
+
}
|
|
892
|
+
if (url.username || url.password) {
|
|
893
|
+
throw new Error(`Runtime asset ${asset} URL must not include credentials`);
|
|
894
|
+
}
|
|
895
|
+
if (url.hash) {
|
|
896
|
+
throw new Error(`Runtime asset ${asset} URL must not include a fragment`);
|
|
897
|
+
}
|
|
898
|
+
const allowed = [this.config.baseUrl, ...(this.config.allowedBaseUrls || [])].some((baseUrl) => {
|
|
899
|
+
let base;
|
|
900
|
+
try {
|
|
901
|
+
base = new URL(baseUrl, url);
|
|
902
|
+
}
|
|
903
|
+
catch {
|
|
904
|
+
return false;
|
|
905
|
+
}
|
|
906
|
+
if (base.protocol !== 'https:' && base.protocol !== 'http:')
|
|
907
|
+
return false;
|
|
908
|
+
const basePath = base.pathname.endsWith('/') ? base.pathname : `${base.pathname}/`;
|
|
909
|
+
return url.origin === base.origin && url.pathname.startsWith(basePath);
|
|
910
|
+
});
|
|
911
|
+
if (!allowed) {
|
|
912
|
+
throw new Error(`Runtime asset ${asset} URL is outside the allowed asset bases`);
|
|
913
|
+
}
|
|
914
|
+
return url;
|
|
915
|
+
}
|
|
916
|
+
abortActiveLoads() {
|
|
917
|
+
const controllers = [...this.activeLoads];
|
|
918
|
+
this.activeLoads.clear();
|
|
919
|
+
for (const controller of controllers)
|
|
920
|
+
controller.abort();
|
|
197
921
|
}
|
|
198
922
|
}
|