Skip to content

Commit

Permalink
[browser] Clean-up typescript code imported from Blazor (#89435)
Browse files Browse the repository at this point in the history
  • Loading branch information
maraf authored Jul 29, 2023
1 parent 8be0ec5 commit 7a9ff69
Show file tree
Hide file tree
Showing 28 changed files with 1,084 additions and 1,118 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -372,8 +372,8 @@ Copyright (c) .NET Foundation. All rights reserved.
RuntimeOptions="$(_BlazorWebAssemblyRuntimeOptions)"
Extensions="@(WasmBootConfigExtension)"
TargetFrameworkVersion="$(TargetFrameworkVersion)"
LibraryInitializerOnRuntimeConfigLoaded="@(WasmLibraryInitializerOnRuntimeConfigLoaded)"
LibraryInitializerOnRuntimeReady="@(WasmLibraryInitializerOnRuntimeReady)" />
ModuleAfterConfigLoaded="@(WasmModuleAfterConfigLoaded)"
ModuleAfterRuntimeReady="@(WasmModuleAfterRuntimeReady)" />

<ItemGroup>
<FileWrites Include="$(_WasmBuildBootJsonPath)" />
Expand Down Expand Up @@ -563,8 +563,8 @@ Copyright (c) .NET Foundation. All rights reserved.
RuntimeOptions="$(_BlazorWebAssemblyRuntimeOptions)"
Extensions="@(WasmBootConfigExtension)"
TargetFrameworkVersion="$(TargetFrameworkVersion)"
LibraryInitializerOnRuntimeConfigLoaded="@(WasmLibraryInitializerOnRuntimeConfigLoaded)"
LibraryInitializerOnRuntimeReady="@(WasmLibraryInitializerOnRuntimeReady)" />
ModuleAfterConfigLoaded="@(WasmModuleAfterConfigLoaded)"
ModuleAfterRuntimeReady="@(WasmModuleAfterRuntimeReady)" />

<ItemGroup>
<FileWrites Include="$(IntermediateOutputPath)blazor.publish.boot.json" />
Expand Down
10 changes: 8 additions & 2 deletions src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -390,15 +390,21 @@ public void AssertBootJson(AssertBundleOptionsBase options)
Assert.True(File.Exists(bootJsonPath), $"Expected to find {bootJsonPath}");

BootJsonData bootJson = ParseBootData(bootJsonPath);
var bootJsonEntries = bootJson.resources.runtime.Keys.Where(k => k.StartsWith("dotnet.", StringComparison.Ordinal)).ToArray();
var bootJsonEntries = bootJson.resources.jsModuleNative.Keys
.Union(bootJson.resources.jsModuleRuntime.Keys)
.Union(bootJson.resources.jsModuleWorker?.Keys ?? Enumerable.Empty<string>())
.Union(bootJson.resources.jsSymbols?.Keys ?? Enumerable.Empty<string>())
.Union(bootJson.resources.wasmNative.Keys)
.ToArray();

var expectedEntries = new SortedDictionary<string, Action<string>>();
IReadOnlySet<string> expected = GetDotNetFilesExpectedSet(options);

var knownSet = GetAllKnownDotnetFilesToFingerprintMap(options);
foreach (string expectedFilename in expected)
{
if (Path.GetExtension(expectedFilename) == ".map")
// FIXME: Find a systematic solution for skipping dotnet.js from boot json check
if (expectedFilename == "dotnet.js" || Path.GetExtension(expectedFilename) == ".map")
continue;

bool expectFingerprint = knownSet[expectedFilename];
Expand Down
101 changes: 48 additions & 53 deletions src/mono/wasm/runtime/dotnet.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,6 @@ interface DotnetHostBuilder {
run(): Promise<number>;
}
type MonoConfig = {
/**
* The subfolder containing managed assemblies and pdbs. This is relative to dotnet.js script.
*/
assemblyRootFolder?: string;
/**
* A list of assets to load along with the runtime.
*/
assets?: AssetEntry[];
/**
* Additional search locations for assets.
*/
Expand Down Expand Up @@ -133,6 +125,10 @@ type MonoConfig = {
* debugLevel < 0 enables debugging and disables debug logging.
*/
debugLevel?: number;
/**
* Gets a value that determines whether to enable caching of the 'resources' inside a CacheStorage instance within the browser.
*/
cacheBootResources?: boolean;
/**
* Enables diagnostic log messages during startup
*/
Expand All @@ -151,10 +147,6 @@ type MonoConfig = {
* If true, the snapshot of runtime's memory will be stored in the browser and used for faster startup next time. Default is false.
*/
startupMemoryCache?: boolean;
/**
* hash of assets
*/
assetsHash?: string;
/**
* application environment
*/
Expand All @@ -167,6 +159,10 @@ type MonoConfig = {
* definition of assets to load along with the runtime.
*/
resources?: ResourceGroups;
/**
* appsettings files to load to VFS
*/
appsettings?: string[];
/**
* config extensions declared in MSBuild items @(WasmBootConfigExtension)
*/
Expand All @@ -178,26 +174,31 @@ type ResourceExtensions = {
[extensionName: string]: ResourceList;
};
interface ResourceGroups {
readonly hash?: string;
readonly assembly?: ResourceList;
readonly lazyAssembly?: ResourceList;
readonly pdb?: ResourceList;
readonly runtime?: ResourceList;
readonly satelliteResources?: {
hash?: string;
assembly?: ResourceList;
lazyAssembly?: ResourceList;
pdb?: ResourceList;
jsModuleWorker?: ResourceList;
jsModuleNative: ResourceList;
jsModuleRuntime: ResourceList;
jsSymbols?: ResourceList;
wasmNative: ResourceList;
icu?: ResourceList;
satelliteResources?: {
[cultureName: string]: ResourceList;
};
readonly libraryInitializers?: ResourceList;
readonly libraryStartupModules?: {
readonly onRuntimeConfigLoaded?: ResourceList;
readonly onRuntimeReady?: ResourceList;
};
readonly extensions?: ResourceExtensions;
readonly vfs?: {
modulesAfterConfigLoaded?: ResourceList;
modulesAfterRuntimeReady?: ResourceList;
extensions?: ResourceExtensions;
vfs?: {
[virtualPath: string]: ResourceList;
};
}
/**
* A "key" is name of the file, a "value" is optional hash for integrity check.
*/
type ResourceList = {
[name: string]: string;
[name: string]: string | null | "";
};
/**
* Overrides the built-in boot resource loading mechanism so that boot resources can be fetched
Expand All @@ -208,12 +209,12 @@ type ResourceList = {
* @param integrity The integrity string representing the expected content in the response.
* @returns A URI string or a Response promise to override the loading process, or null/undefined to allow the default loading behavior.
*/
type LoadBootResourceCallback = (type: WebAssemblyBootResourceType, name: string, defaultUri: string, integrity: string) => string | Promise<Response> | null | undefined;
type LoadBootResourceCallback = (type: AssetBehaviors | "manifest", name: string, defaultUri: string, integrity: string) => string | Promise<Response> | null | undefined;
interface ResourceRequest {
name: string;
behavior: AssetBehaviours;
behavior: AssetBehaviors;
resolvedUrl?: string;
hash?: string;
hash?: string | null | "";
}
interface LoadingResource {
name: string;
Expand Down Expand Up @@ -248,7 +249,24 @@ interface AssetEntry extends ResourceRequest {
*/
pendingDownload?: LoadingResource;
}
type AssetBehaviours =
type SingleAssetBehaviors =
/**
* The binary of the dotnet runtime.
*/
"dotnetwasm"
/**
* The javascript module for threads.
*/
| "js-module-threads"
/**
* The javascript module for threads.
*/
| "js-module-runtime"
/**
* The javascript module for threads.
*/
| "js-module-native";
type AssetBehaviors = SingleAssetBehaviors |
/**
* Load asset as a managed resource assembly.
*/
Expand All @@ -273,26 +291,6 @@ type AssetBehaviours =
* Load asset into the virtual filesystem (for fopen, File.Open, etc).
*/
| "vfs"
/**
* The binary of the dotnet runtime.
*/
| "dotnetwasm"
/**
* The javascript module for threads.
*/
| "js-module-threads"
/**
* The javascript module for threads.
*/
| "js-module-runtime"
/**
* The javascript module for threads.
*/
| "js-module-dotnet"
/**
* The javascript module for threads.
*/
| "js-module-native"
/**
* The javascript module that came from nuget package .
*/
Expand Down Expand Up @@ -330,10 +328,8 @@ type DotnetModuleConfig = {
onConfigLoaded?: (config: MonoConfig) => void | Promise<void>;
onDotnetReady?: () => void | Promise<void>;
onDownloadResourceProgress?: (resourcesLoaded: number, totalResources: number) => void;
getApplicationEnvironment?: (bootConfigResponse: Response) => string | null;
imports?: any;
exports?: string[];
downloadResource?: (request: ResourceRequest) => LoadingResource | undefined;
} & Partial<EmscriptenModule>;
type APIType = {
runMain: (mainAssemblyName: string, args: string[]) => Promise<number>;
Expand Down Expand Up @@ -400,7 +396,6 @@ type ModuleAPI = {
exit: (code: number, reason?: any) => void;
};
type CreateDotnetRuntimeType = (moduleFactory: DotnetModuleConfig | ((api: RuntimeAPI) => DotnetModuleConfig)) => Promise<RuntimeAPI>;
type WebAssemblyBootResourceType = "assembly" | "pdb" | "dotnetjs" | "dotnetwasm" | "globalization" | "manifest" | "configuration";

interface IDisposable {
dispose(): void;
Expand Down
34 changes: 22 additions & 12 deletions src/mono/wasm/runtime/lazyLoading.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,50 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

import { INTERNAL, loaderHelpers, runtimeHelpers } from "./globals";
import type { WebAssemblyResourceLoader } from "./loader/blazor/WebAssemblyResourceLoader";
import { loaderHelpers, runtimeHelpers } from "./globals";
import { AssetEntry } from "./types";

export async function loadLazyAssembly(assemblyNameToLoad: string): Promise<boolean> {
const resourceLoader: WebAssemblyResourceLoader = INTERNAL.resourceLoader;
const resources = resourceLoader.bootConfig.resources;
const resources = loaderHelpers.config.resources!;
const lazyAssemblies = resources.lazyAssembly;
if (!lazyAssemblies) {
throw new Error("No assemblies have been marked as lazy-loadable. Use the 'BlazorWebAssemblyLazyLoad' item group in your project file to enable lazy loading an assembly.");
}

const assemblyMarkedAsLazy = Object.prototype.hasOwnProperty.call(lazyAssemblies, assemblyNameToLoad);
if (!assemblyMarkedAsLazy) {
if (!lazyAssemblies[assemblyNameToLoad]) {
throw new Error(`${assemblyNameToLoad} must be marked with 'BlazorWebAssemblyLazyLoad' item group in your project file to allow lazy-loading.`);
}

const dllAsset: AssetEntry = {
name: assemblyNameToLoad,
hash: lazyAssemblies[assemblyNameToLoad],
behavior: "assembly",
};

if (loaderHelpers.loadedAssemblies.some(f => f.includes(assemblyNameToLoad))) {
return false;
}

const dllNameToLoad = assemblyNameToLoad;
const pdbNameToLoad = changeExtension(assemblyNameToLoad, ".pdb");
const shouldLoadPdb = loaderHelpers.hasDebuggingEnabled(resourceLoader.bootConfig) && resources.pdb && Object.prototype.hasOwnProperty.call(lazyAssemblies, pdbNameToLoad);
const pdbNameToLoad = changeExtension(dllAsset.name, ".pdb");
const shouldLoadPdb = loaderHelpers.hasDebuggingEnabled(loaderHelpers.config) && Object.prototype.hasOwnProperty.call(lazyAssemblies, pdbNameToLoad);

const dllBytesPromise = resourceLoader.loadResource(dllNameToLoad, loaderHelpers.locateFile(dllNameToLoad), lazyAssemblies[dllNameToLoad], "assembly").response.then(response => response.arrayBuffer());
const dllBytesPromise = loaderHelpers.retrieve_asset_download(dllAsset);

let dll = null;
let pdb = null;
if (shouldLoadPdb) {
const pdbBytesPromise = await resourceLoader.loadResource(pdbNameToLoad, loaderHelpers.locateFile(pdbNameToLoad), lazyAssemblies[pdbNameToLoad], "pdb").response.then(response => response.arrayBuffer());
const pdbBytesPromise = lazyAssemblies[pdbNameToLoad]
? loaderHelpers.retrieve_asset_download({
name: pdbNameToLoad,
hash: lazyAssemblies[pdbNameToLoad],
behavior: "pdb"
})
: Promise.resolve(null);

const [dllBytes, pdbBytes] = await Promise.all([dllBytesPromise, pdbBytesPromise]);

dll = new Uint8Array(dllBytes);
pdb = new Uint8Array(pdbBytes);
pdb = pdbBytes ? new Uint8Array(pdbBytes) : null;
} else {
const dllBytes = await dllBytesPromise;
dll = new Uint8Array(dllBytes);
Expand Down
Loading

0 comments on commit 7a9ff69

Please sign in to comment.