Skip to content
59 changes: 57 additions & 2 deletions src/Components/Web.JS/@types/dotnet/dotnet.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,14 @@ type MonoConfig = {
* initial number of workers to add to the emscripten pthread pool
*/
pthreadPoolSize?: number;
/**
* 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;
/**
* application environment
*/
applicationEnvironment?: string;
};
interface ResourceRequest {
name: string;
Expand Down Expand Up @@ -180,8 +188,10 @@ type DotnetModuleConfig = {
disableDotnet6Compatibility?: boolean;
config?: MonoConfig;
configSrc?: string;
onConfigLoaded?: (config: MonoConfig) => void | Promise<void>;
onConfigLoaded?: (config: MonoConfig & BootJsonData) => 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;
Expand Down Expand Up @@ -274,4 +284,49 @@ declare global {
declare const dotnet: ModuleAPI["dotnet"];
declare const exit: ModuleAPI["exit"];

export { AssetEntry, CreateDotnetRuntimeType, DotnetModuleConfig, EmscriptenModule, IMemoryView, ModuleAPI, MonoConfig, ResourceRequest, RuntimeAPI, createDotnetRuntime as default, dotnet, exit };
interface BootJsonData {
readonly entryAssembly: string;
readonly resources: ResourceGroups;
/** Gets a value that determines if this boot config was produced from a non-published build (i.e. dotnet build or dotnet run) */
readonly debugBuild: boolean;
readonly linkerEnabled: boolean;
readonly cacheBootResources: boolean;
readonly config: string[];
readonly icuDataMode: ICUDataMode;
readonly startupMemoryCache: boolean | undefined;
readonly runtimeOptions: string[] | undefined;

// These properties are tacked on, and not found in the boot.json file
modifiableAssemblies: string | null;
aspnetCoreBrowserTools: string | null;
}

type BootJsonDataExtension = { [extensionName: string]: ResourceList };

interface ResourceGroups {
readonly assembly: ResourceList;
readonly lazyAssembly: ResourceList;
readonly pdb?: ResourceList;
readonly runtime: ResourceList;
readonly satelliteResources?: { [cultureName: string]: ResourceList };
readonly libraryInitializers?: ResourceList,
readonly extensions?: BootJsonDataExtension
readonly runtimeAssets: ExtendedResourceList;
}

type ResourceList = { [name: string]: string };
type ExtendedResourceList = {
[name: string]: {
hash: string,
behavior: string
}
};

declare const enum ICUDataMode {
Sharded,
All,
Invariant,
Custom
}

export { AssetEntry, CreateDotnetRuntimeType, DotnetModuleConfig, EmscriptenModule, IMemoryView, ModuleAPI, MonoConfig, ResourceRequest, RuntimeAPI, BootJsonData, ICUDataMode, createDotnetRuntime as default, dotnet, exit };
56 changes: 8 additions & 48 deletions src/Components/Web.JS/src/Boot.WebAssembly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,14 @@ import { DotNet } from '@microsoft/dotnet-js-interop';
import { Blazor } from './GlobalExports';
import * as Environment from './Environment';
import { Module, BINDING, monoPlatform } from './Platform/Mono/MonoPlatform';
import { renderBatch, getRendererer, attachRootComponentToElement, attachRootComponentToLogicalElement } from './Rendering/Renderer';
import { renderBatch, getRendererer } from './Rendering/Renderer';
import { SharedMemoryRenderBatch } from './Rendering/RenderBatch/SharedMemoryRenderBatch';
import { shouldAutoStart } from './BootCommon';
import { WebAssemblyResourceLoader } from './Platform/WebAssemblyResourceLoader';
import { WebAssemblyConfigLoader } from './Platform/WebAssemblyConfigLoader';
import { BootConfigResult } from './Platform/BootConfig';
import { Pointer } from './Platform/Platform';
import { WebAssemblyStartOptions } from './Platform/WebAssemblyStartOptions';
import { WebAssemblyComponentAttacher } from './Platform/WebAssemblyComponentAttacher';
import { discoverComponents, discoverPersistedState, WebAssemblyComponentDescriptor } from './Services/ComponentDescriptorDiscovery';
import { setDispatchEventMiddleware } from './Rendering/WebRendererInteropMethods';
import { fetchAndInvokeInitializers } from './JSInitializers/JSInitializers.WebAssembly';
import { JSInitializer } from './JSInitializers/JSInitializers';

let started = false;

Expand All @@ -30,7 +26,7 @@ async function boot(options?: Partial<WebAssemblyStartOptions>): Promise<void> {

if (inAuthRedirectIframe()) {
// eslint-disable-next-line @typescript-eslint/no-empty-function
await new Promise(() => {}); // See inAuthRedirectIframe for explanation
await new Promise(() => { }); // See inAuthRedirectIframe for explanation
}

setDispatchEventMiddleware((browserRendererId, eventHandlerId, continuation) => {
Expand Down Expand Up @@ -93,48 +89,12 @@ async function boot(options?: Partial<WebAssemblyStartOptions>): Promise<void> {
Blazor._internal.navigationManager.endLocationChanging(callId, shouldContinueNavigation);
});

const candidateOptions = options ?? {};

// Get the custom environment setting and blazorBootJson loader if defined
const environment = candidateOptions.environment;

// Fetch the resources and prepare the Mono runtime
const bootConfigPromise = BootConfigResult.initAsync(candidateOptions.loadBootResource, environment);

// Leverage the time while we are loading boot.config.json from the network to discover any potentially registered component on
// the document.
const discoveredComponents = discoverComponents(document, 'webassembly') as WebAssemblyComponentDescriptor[];
const componentAttacher = new WebAssemblyComponentAttacher(discoveredComponents);
Blazor._internal.registeredComponents = {
getRegisteredComponentsCount: () => componentAttacher.getCount(),
getId: (index) => componentAttacher.getId(index),
getAssembly: (id) => componentAttacher.getAssembly(id),
getTypeName: (id) => componentAttacher.getTypeName(id),
getParameterDefinitions: (id) => componentAttacher.getParameterDefinitions(id) || '',
getParameterValues: (id) => componentAttacher.getParameterValues(id) || '',
};

Blazor._internal.getPersistedState = () => discoverPersistedState(document) || '';

Blazor._internal.attachRootComponentToElement = (selector, componentId, rendererId: any) => {
const element = componentAttacher.resolveRegisteredElement(selector);
if (!element) {
attachRootComponentToElement(selector, componentId, rendererId);
} else {
attachRootComponentToLogicalElement(rendererId, element, componentId, false);
}
};

const bootConfigResult: BootConfigResult = await bootConfigPromise;
const jsInitializer = await fetchAndInvokeInitializers(bootConfigResult.bootConfig, candidateOptions);

const [resourceLoader] = await Promise.all([
WebAssemblyResourceLoader.initAsync(bootConfigResult.bootConfig, candidateOptions || {}),
WebAssemblyConfigLoader.initAsync(bootConfigResult, candidateOptions || {}),
]);

let resourceLoader: WebAssemblyResourceLoader;
let jsInitializer: JSInitializer;
try {
await platform.start(resourceLoader);
const api = await platform.start(options ?? {});
resourceLoader = api.resourceLoader;
jsInitializer = api.jsInitializer;
} catch (ex) {
throw new Error(`Failed to start platform. Reason: ${ex}`);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

import { BootJsonData } from '../Platform/BootConfig';
import { BootJsonData } from 'dotnet';
import { WebAssemblyStartOptions } from '../Platform/WebAssemblyStartOptions';
import { JSInitializer } from './JSInitializers';

export async function fetchAndInvokeInitializers(bootConfig: BootJsonData, options: Partial<WebAssemblyStartOptions>) : Promise<JSInitializer> {
export async function fetchAndInvokeInitializers(bootConfig: BootJsonData, options: Partial<WebAssemblyStartOptions>): Promise<JSInitializer> {
const initializers = bootConfig.resources.libraryInitializers;
const jsInitializer = new JSInitializer();
if (initializers) {
Expand Down
90 changes: 0 additions & 90 deletions src/Components/Web.JS/src/Platform/BootConfig.ts

This file was deleted.

Loading