未验证 提交 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 @@
// The .NET Foundation licenses this file to you under the MIT license.
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 { mono_wasm_raise_debug_event, mono_wasm_runtime_ready } from "./debug";
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 {
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) {
const bytes = new Uint8Array(blob);
if (ctx.tracing)
......@@ -143,47 +180,6 @@ function _apply_configuration_from_args(args: MonoConfig) {
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) {
const moduleExt = Module as EmscriptenModuleMono;
......@@ -316,7 +312,7 @@ export async function mono_load_runtime_and_bcl_args(args: MonoConfig): Promise<
_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> => {
//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<
}
// 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)
return false;
......@@ -456,20 +452,10 @@ export async function mono_wasm_load_config(configFilePath: string): Promise<voi
const module = Module;
module.addRunDependency(configFilePath);
try {
let config = null;
// NOTE: when we add nodejs make sure to include the nodejs fetch package
if (ENVIRONMENT_IS_WEB) {
const configRaw = await fetch(configFilePath);
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);
}
const configRaw = await _fetch_asset(configFilePath);
const config = await configRaw.json();
runtimeHelpers.config = config;
config.environment_variables = config.environment_variables || {};
config.assets = config.assets || [];
......
......@@ -59,8 +59,8 @@ declare interface EmscriptenModule {
setValue(ptr: VoidPtr, 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;
UTF8ToString(arg: CharPtr): string;
UTF8ArrayToString(str: TypedArray, heap: number[] | number, outIdx: number, maxBytesToWrite?: number): string;
UTF8ToString(ptr: CharPtr, maxBytesToRead?: number): string;
UTF8ArrayToString(u8Array: Uint8Array, idx?: number, maxBytesToRead?: number): 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;
removeRunDependency(id: string): void;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册