import { dotnet } from "./_framework/dotnet.js";
+import * as runtime from "./_framework/dotnet.runtime.js";
-async function fetchBinary(uri) {
- return new Uint8Array(await (await fetch(uri)).arrayBuffer());
+async function fetchBinary(url) {
+ return (await fetch(url, { cache: "no-cache" })).arrayBuffer();
+}
+
+function fetchWasm(url) {
+ return {
+ response: fetch(url, { cache: "no-cache" }),
+ url,
+ name: url.substring(url.lastIndexOf("/") + 1)
+ };
}
const assets = [
{
name: "dotnet.native.js",
+ // demo dynamic import
+ moduleExports: import("./_framework/dotnet.native.js"),
behavior: "js-module-native"
},
- {
- name: "dotnet.js",
- behavior: "js-module-dotnet"
- },
{
name: "dotnet.runtime.js",
+ // demo static import
+ moduleExports: runtime,
behavior: "js-module-runtime"
},
{
name: "dotnet.native.wasm",
+ // demo pending download promise
+ pendingDownload: fetchWasm("./_framework/dotnet.native.wasm"),
behavior: "dotnetwasm"
},
{
},
{
name: "Wasm.Browser.Config.Sample.wasm",
- buffer: await fetchBinary("./_framework/Wasm.Browser.Config.Sample.wasm"),
+ // demo buffer promise
+ buffer: fetchBinary("./_framework/Wasm.Browser.Config.Sample.wasm"),
behavior: "assembly"
},
{
* If provided, runtime doesn't have to fetch the data.
* Runtime would set the buffer to null after instantiation to free the memory.
*/
- buffer?: ArrayBuffer;
+ buffer?: ArrayBuffer | Promise<ArrayBuffer>;
+ /**
+ * If provided, runtime doesn't have to import it's JavaScript modules.
+ * This will not work for multi-threaded runtime.
+ */
+ moduleExports?: any | Promise<any>;
/**
* It's metadata + fetch-like Promise<Response>
* If provided, the runtime doesn't have to initiate the download. It would just await the response.
const asset = await downloadPromise;
if (asset.buffer) {
if (!skipInstantiateByAssetTypes[asset.behavior]) {
- mono_assert(asset.buffer && typeof asset.buffer === "object", "asset buffer must be array or buffer like");
+ mono_assert(asset.buffer && typeof asset.buffer === "object", "asset buffer must be array-like or buffer-like or promise of these");
mono_assert(typeof asset.resolvedUrl === "string", "resolvedUrl must be string");
const url = asset.resolvedUrl!;
- const data = new Uint8Array(asset.buffer!);
+ const buffer = await asset.buffer;
+ const data = new Uint8Array(buffer);
cleanupAsset(asset);
// wait till after onRuntimeInitialized and after memory snapshot is loaded or skipped
return asset.pendingDownloadInternal.response;
}
if (asset.buffer) {
- const buffer = asset.buffer;
+ const buffer = await asset.buffer;
if (!asset.resolvedUrl) {
asset.resolvedUrl = "undefined://" + asset.name;
}
asset.pendingDownloadInternal = null as any; // GC
asset.pendingDownload = null as any; // GC
asset.buffer = null as any; // GC
+ asset.moduleExports = null as any; // GC
}
function fileName(name: string) {
: createEmscriptenMain();
}
+// in the future we can use feature detection to load different flavors
function importModules() {
const jsModuleRuntimeAsset = resolve_single_asset_path("js-module-runtime");
const jsModuleNativeAsset = resolve_single_asset_path("js-module-native");
- mono_log_debug(`Attempting to import '${jsModuleRuntimeAsset.resolvedUrl}' for ${jsModuleRuntimeAsset.name}`);
- mono_log_debug(`Attempting to import '${jsModuleNativeAsset.resolvedUrl}' for ${jsModuleNativeAsset.name}`);
- return [
- // keep js module names dynamic by using config, in the future we can use feature detection to load different flavors
- import(/* webpackIgnore: true */jsModuleRuntimeAsset.resolvedUrl!),
- import(/* webpackIgnore: true */jsModuleNativeAsset.resolvedUrl!),
- ];
+
+ let jsModuleRuntimePromise: Promise<RuntimeModuleExportsInternal>;
+ let jsModuleNativePromise: Promise<NativeModuleExportsInternal>;
+
+ if (typeof jsModuleRuntimeAsset.moduleExports === "object") {
+ jsModuleRuntimePromise = jsModuleRuntimeAsset.moduleExports;
+ } else {
+ mono_log_debug(`Attempting to import '${jsModuleRuntimeAsset.resolvedUrl}' for ${jsModuleRuntimeAsset.name}`);
+ jsModuleRuntimePromise = import(/* webpackIgnore: true */jsModuleRuntimeAsset.resolvedUrl!);
+ }
+
+ if (typeof jsModuleNativeAsset.moduleExports === "object") {
+ jsModuleNativePromise = jsModuleNativeAsset.moduleExports;
+ } else {
+ mono_log_debug(`Attempting to import '${jsModuleNativeAsset.resolvedUrl}' for ${jsModuleNativeAsset.name}`);
+ jsModuleNativePromise = import(/* webpackIgnore: true */jsModuleNativeAsset.resolvedUrl!);
+ }
+
+ return [jsModuleRuntimePromise, jsModuleNativePromise];
}
async function initializeModules(es6Modules: [RuntimeModuleExportsInternal, NativeModuleExportsInternal]) {
assetToLoad.pendingDownloadInternal = null as any; // GC
assetToLoad.pendingDownload = null as any; // GC
assetToLoad.buffer = null as any; // GC
+ assetToLoad.moduleExports = null as any; // GC
mono_log_debug("instantiate_wasm_module done");
* If provided, runtime doesn't have to fetch the data.
* Runtime would set the buffer to null after instantiation to free the memory.
*/
- buffer?: ArrayBuffer
+ buffer?: ArrayBuffer | Promise<ArrayBuffer>,
+
+ /**
+ * If provided, runtime doesn't have to import it's JavaScript modules.
+ * This will not work for multi-threaded runtime.
+ */
+ moduleExports?: any | Promise<any>,
+
/**
* It's metadata + fetch-like Promise<Response>
* If provided, the runtime doesn't have to initiate the download. It would just await the response.