未验证 提交 2b1f420c 编写于 作者: L Larry Ewing 提交者: GitHub

[wasm] Rework fetch (#61639)

* Unify some code and load mono-config.json using our _fetch_asset
上级 9a9a4f34
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license. // The .NET Foundation licenses this file to you under the MIT license.
import { INTERNAL, Module, MONO, runtimeHelpers } from "./modules"; import { INTERNAL, Module, MONO, runtimeHelpers } from "./modules";
import { AllAssetEntryTypes, AssetEntry, CharPtr, CharPtrNull, EmscriptenModuleMono, GlobalizationMode, MonoConfig, TypedArray, VoidPtr, wasm_type_symbol } from "./types"; import { AllAssetEntryTypes, AssetEntry, CharPtr, CharPtrNull, EmscriptenModuleMono, GlobalizationMode, MonoConfig, VoidPtr, wasm_type_symbol } from "./types";
import cwraps from "./cwraps"; import cwraps from "./cwraps";
import { mono_wasm_raise_debug_event, mono_wasm_runtime_ready } from "./debug"; import { mono_wasm_raise_debug_event, mono_wasm_runtime_ready } from "./debug";
import { mono_wasm_globalization_init, mono_wasm_load_icu_data } from "./icu"; import { mono_wasm_globalization_init, mono_wasm_load_icu_data } from "./icu";
...@@ -56,6 +56,43 @@ export function mono_wasm_set_runtime_options(options: string[]): void { ...@@ -56,6 +56,43 @@ export function mono_wasm_set_runtime_options(options: string[]): void {
cwraps.mono_wasm_parse_runtime_options(options.length, argv); cwraps.mono_wasm_parse_runtime_options(options.length, argv);
} }
async function _fetch_asset(url: string): Promise<Response> {
try {
if (typeof (fetch) === "function") {
return fetch(url, { credentials: "same-origin" });
}
else if (ENVIRONMENT_IS_NODE) {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const fs = require("fs");
const arrayBuffer = await fs.promises.readFile(url);
return <Response><any> {
ok: true,
url,
arrayBuffer: () => arrayBuffer,
json: () => JSON.parse(arrayBuffer)
};
}
else if (typeof (read) === "function") {
const arrayBuffer = new Uint8Array(read(url, "binary"));
return <Response><any> {
ok: true,
url,
arrayBuffer: () => arrayBuffer,
json: () => JSON.parse(Module.UTF8ArrayToString(arrayBuffer, 0, arrayBuffer.length))
};
}
}
catch (e: any) {
return <Response><any> {
ok: false,
url,
arrayBuffer: () => { throw e; },
json: () => { throw e; }
};
}
throw new Error("No fetch implementation available");
}
function _handle_fetched_asset(ctx: MonoInitContext, asset: AssetEntry, url: string, blob: ArrayBuffer) { function _handle_fetched_asset(ctx: MonoInitContext, asset: AssetEntry, url: string, blob: ArrayBuffer) {
const bytes = new Uint8Array(blob); const bytes = new Uint8Array(blob);
if (ctx.tracing) if (ctx.tracing)
...@@ -143,47 +180,6 @@ function _apply_configuration_from_args(args: MonoConfig) { ...@@ -143,47 +180,6 @@ function _apply_configuration_from_args(args: MonoConfig) {
mono_wasm_init_coverage_profiler(args.coverage_profiler_options); mono_wasm_init_coverage_profiler(args.coverage_profiler_options);
} }
function _get_fetch_implementation(args: MonoConfig): (asset: string) => Promise<Response> {
if (typeof (args.fetch_file_cb) === "function")
return args.fetch_file_cb;
if (typeof (fetch) === "function") {
return function (asset) {
return fetch(asset, { credentials: "same-origin" });
};
} else if (ENVIRONMENT_IS_NODE || typeof (read) === "function") {
return async function (asset) {
let data: any = null;
let err: any = null;
try {
if (ENVIRONMENT_IS_NODE) {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const fs = require("fs");
data = await fs.promises.readFile(asset);
}
else {
data = read(asset, "binary");
}
}
catch (exc) {
data = null;
err = exc;
}
const res: any = {
ok: !!data,
url: asset,
arrayBuffer: async function () {
if (err) throw err;
return new Uint8Array(data);
}
};
return <Response>res;
};
} else {
throw new Error("No fetch_file_cb was provided and this environment does not expose 'fetch'.");
}
}
function _finalize_startup(args: MonoConfig, ctx: MonoInitContext) { function _finalize_startup(args: MonoConfig, ctx: MonoInitContext) {
const moduleExt = Module as EmscriptenModuleMono; const moduleExt = Module as EmscriptenModuleMono;
...@@ -316,7 +312,7 @@ export async function mono_load_runtime_and_bcl_args(args: MonoConfig): Promise< ...@@ -316,7 +312,7 @@ export async function mono_load_runtime_and_bcl_args(args: MonoConfig): Promise<
_apply_configuration_from_args(args); _apply_configuration_from_args(args);
const local_fetch = _get_fetch_implementation(args); const local_fetch = typeof (args.fetch_file_cb) === "function" ? args.fetch_file_cb : _fetch_asset;
const load_asset = async (asset: AllAssetEntryTypes): Promise<void> => { const load_asset = async (asset: AllAssetEntryTypes): Promise<void> => {
//TODO we could do module.addRunDependency(asset.name) and delay emscripten run() after all assets are loaded //TODO we could do module.addRunDependency(asset.name) and delay emscripten run() after all assets are loaded
...@@ -392,7 +388,7 @@ export async function mono_load_runtime_and_bcl_args(args: MonoConfig): Promise< ...@@ -392,7 +388,7 @@ export async function mono_load_runtime_and_bcl_args(args: MonoConfig): Promise<
} }
// used from Blazor // used from Blazor
export function mono_wasm_load_data_archive(data: TypedArray, prefix: string): boolean { export function mono_wasm_load_data_archive(data: Uint8Array, prefix: string): boolean {
if (data.length < 8) if (data.length < 8)
return false; return false;
...@@ -456,20 +452,10 @@ export async function mono_wasm_load_config(configFilePath: string): Promise<voi ...@@ -456,20 +452,10 @@ export async function mono_wasm_load_config(configFilePath: string): Promise<voi
const module = Module; const module = Module;
module.addRunDependency(configFilePath); module.addRunDependency(configFilePath);
try { try {
let config = null;
// NOTE: when we add nodejs make sure to include the nodejs fetch package // NOTE: when we add nodejs make sure to include the nodejs fetch package
if (ENVIRONMENT_IS_WEB) { const configRaw = await _fetch_asset(configFilePath);
const configRaw = await fetch(configFilePath); const config = await configRaw.json();
config = await configRaw.json();
} else if (ENVIRONMENT_IS_NODE) {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const fs = require("fs");
const json = await fs.promises.readFile(configFilePath);
config = JSON.parse(json);
} else { // shell or worker
const json = read(configFilePath);// read is a v8 debugger command
config = JSON.parse(json);
}
runtimeHelpers.config = config; runtimeHelpers.config = config;
config.environment_variables = config.environment_variables || {}; config.environment_variables = config.environment_variables || {};
config.assets = config.assets || []; config.assets = config.assets || [];
......
...@@ -59,8 +59,8 @@ declare interface EmscriptenModule { ...@@ -59,8 +59,8 @@ declare interface EmscriptenModule {
setValue(ptr: VoidPtr, value: number, type: string, noSafe?: number | boolean): void; setValue(ptr: VoidPtr, value: number, type: string, noSafe?: number | boolean): void;
setValue(ptr: Int32Ptr, value: number, type: string, noSafe?: number | boolean): void; setValue(ptr: Int32Ptr, value: number, type: string, noSafe?: number | boolean): void;
getValue(ptr: number, type: string, noSafe?: number | boolean): number; getValue(ptr: number, type: string, noSafe?: number | boolean): number;
UTF8ToString(arg: CharPtr): string; UTF8ToString(ptr: CharPtr, maxBytesToRead?: number): string;
UTF8ArrayToString(str: TypedArray, heap: number[] | number, outIdx: number, maxBytesToWrite?: number): string; UTF8ArrayToString(u8Array: Uint8Array, idx?: number, maxBytesToRead?: number): string;
FS_createPath(parent: string, path: string, canRead?: boolean, canWrite?: boolean): string; FS_createPath(parent: string, path: string, canRead?: boolean, canWrite?: boolean): string;
FS_createDataFile(parent: string, name: string, data: TypedArray, canRead: boolean, canWrite: boolean, canOwn?: boolean): string; FS_createDataFile(parent: string, name: string, data: TypedArray, canRead: boolean, canWrite: boolean, canOwn?: boolean): string;
removeRunDependency(id: string): void; removeRunDependency(id: string): void;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册