Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/libraries/sendtohelix-browser.targets
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@
<_XUnitTraitArg Condition="'$(TestUsingWorkloads)' == 'true'">-notrait category=no-workload</_XUnitTraitArg>
<_XUnitTraitArg Condition="'$(TestUsingWorkloads)' != 'true'">-trait category=no-workload</_XUnitTraitArg>
<_XUnitTraitArg Condition="'$(WasmFingerprintAssets)' == 'false'">$(_XUnitTraitArg) -trait category=no-fingerprinting</_XUnitTraitArg>
<_XUnitTraitArg Condition="'$(WasmBundlerFriendlyBootConfig)' == 'true'">$(_XUnitTraitArg) -trait category=bundler-friendly</_XUnitTraitArg>
</PropertyGroup>

<PropertyGroup>
Expand Down
5 changes: 3 additions & 2 deletions src/libraries/sendtohelix-wasm.targets
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<WorkItemPrefix Condition="'$(TestUsingWorkloads)' != 'true'">NoWorkload-</WorkItemPrefix>
<WorkItemPrefix Condition="'$(WasmEnableWebcil)' == 'false'">NoWebcil-</WorkItemPrefix>
<WorkItemPrefix Condition="'$(WasmFingerprintAssets)' == 'false'">NoFingerprint-</WorkItemPrefix>
<WorkItemPrefix Condition="'$(WasmBundlerFriendlyBootConfig)' == 'true'">JavascriptBundler-</WorkItemPrefix>
<WorkItemPrefix Condition="'$(WasmEnableThreads)' != 'true'">$(WorkItemPrefix)ST-</WorkItemPrefix>
<WorkItemPrefix Condition="'$(WasmEnableThreads)' == 'true'">$(WorkItemPrefix)MT-</WorkItemPrefix>
</PropertyGroup>
Expand Down Expand Up @@ -50,15 +51,15 @@

<!-- for testing with workloads, we use separate items -->
<ItemGroup>
<HelixWorkItem Include="@(BuildWasmApps_PerJobList->'$(WorkItemPrefix)%(Identity)')" Condition="'$(TestUsingWorkloads)' == 'true' and '$(WasmFingerprintAssets)' == 'true'">
<HelixWorkItem Include="@(BuildWasmApps_PerJobList->'$(WorkItemPrefix)%(Identity)')" Condition="'$(TestUsingWorkloads)' == 'true' and '$(WasmFingerprintAssets)' == 'true' and '$(WasmBundlerFriendlyBootConfig)' == 'false'">
<PayloadArchive>$(_BuildWasmAppsPayloadArchive)</PayloadArchive>
<PreCommands Condition="'$(OS)' == 'Windows_NT'">set &quot;HELIX_XUNIT_ARGS=-class %(Identity)&quot;</PreCommands>
<PreCommands Condition="'$(OS)' != 'Windows_NT'">export &quot;HELIX_XUNIT_ARGS=-class %(Identity)&quot;</PreCommands>
<Command>$(HelixCommand)</Command>
<Timeout>$(_workItemTimeout)</Timeout>
</HelixWorkItem>

<HelixWorkItem Include="$(WorkItemPrefix)Wasm.Build.Tests" Condition="'$(TestUsingWorkloads)' != 'true' or '$(WasmFingerprintAssets)' != 'true'">
<HelixWorkItem Include="$(WorkItemPrefix)Wasm.Build.Tests" Condition="'$(TestUsingWorkloads)' != 'true' or '$(WasmFingerprintAssets)' != 'true' or '$(WasmBundlerFriendlyBootConfig)' != 'false'">
<PayloadArchive>$(_BuildWasmAppsPayloadArchive)</PayloadArchive>
<Command>$(HelixCommand)</Command>
<Timeout>$(_workItemTimeout)</Timeout>
Expand Down
19 changes: 18 additions & 1 deletion src/libraries/sendtohelix.proj
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,12 @@
<_TestUsingWorkloadsValues Include="true;false" />
<_TestUsingWebcilValues Include="true;false" Condition="'$(TargetOS)' == 'browser'" />
<_TestUsingFingerprintingValues Include="true;false" Condition="'$(TargetOS)' == 'browser'" />
<_TestUsingJavascriptBundlerValues Include="true;false" Condition="'$(TargetOS)' == 'browser'" />

<!-- now make the cartesian product of true and false values for two categories -->
<_TestUsingCrossProductValuesTemp Include="@(_TestUsingWorkloadsValues)">
<Workloads>%(_TestUsingWorkloadsValues.Identity)</Workloads>
<BundlerFriendly>false</BundlerFriendly>
</_TestUsingCrossProductValuesTemp>
<_TestUsingCrossProductValuesTemp2 Include="@(_TestUsingCrossProductValuesTemp)">
<Webcil>%(_TestUsingWebcilValues.Identity)</Webcil>
Expand All @@ -102,9 +104,24 @@

<!-- There no tests without fingerprinting and without workloads -->
<_TestUsingCrossProductValues Remove="@(_TestUsingCrossProductValues)" Condition="'%(_TestUsingCrossProductValues.Workloads)' == 'false' and '%(_TestUsingCrossProductValues.Fingerprinting)' == 'false'" />

<!-- Add combination for JavascriptBundler friendliness -->
<_TestUsingCrossProductValues Include="JavaScriptBundlerFriendly">
<Workloads>true</Workloads>
<Webcil>true</Webcil>
<Fingerprinting>true</Fingerprinting>
<BundlerFriendly>true</BundlerFriendly>
</_TestUsingCrossProductValues>

<_BuildWasmAppsProjectsToBuild Include="$(PerScenarioProjectFile)">
<AdditionalProperties>$(_PropertiesToPass);Scenario=BuildWasmApps;TestArchiveRuntimeFile=$(TestArchiveRuntimeFile);TestUsingWorkloads=%(_TestUsingCrossProductValues.Workloads);WasmEnableWebcil=%(_TestUsingCrossProductValues.Webcil);WasmFingerprintAssets=%(_TestUsingCrossProductValues.Fingerprinting)</AdditionalProperties>
<AdditionalProperties>
$(_PropertiesToPass);Scenario=BuildWasmApps;
TestArchiveRuntimeFile=$(TestArchiveRuntimeFile);
TestUsingWorkloads=%(_TestUsingCrossProductValues.Workloads);
WasmEnableWebcil=%(_TestUsingCrossProductValues.Webcil);
WasmFingerprintAssets=%(_TestUsingCrossProductValues.Fingerprinting);
WasmBundlerFriendlyBootConfig=%(_TestUsingCrossProductValues.BundlerFriendly)
</AdditionalProperties>
<AdditionalProperties Condition="'$(NeedsToBuildWasmAppsOnHelix)' != ''">%(_BuildWasmAppsProjectsToBuild.AdditionalProperties);NeedsToBuildWasmAppsOnHelix=$(NeedsToBuildWasmAppsOnHelix)</AdditionalProperties>
</_BuildWasmAppsProjectsToBuild>
</ItemGroup>
Expand Down
3 changes: 2 additions & 1 deletion src/libraries/sendtohelixhelp.proj
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@
<HelixCommandPrefixEnvVarItem Condition="'$(TestUsingWorkloads)' == 'true'" Include="TEST_USING_WORKLOADS=true" />
<HelixCommandPrefixEnvVarItem Condition="'$(WasmEnableWebcil)' == 'false'" Include="WASM_ENABLE_WEBCIL=false" />
<HelixCommandPrefixEnvVarItem Condition="'$(WasmFingerprintAssets)' == 'false'" Include="WASM_FINGERPRINT_ASSETS=false" />
<HelixCommandPrefixEnvVarItem Condition="'$(WasmBundlerFriendlyBootConfig)' == 'true'" Include="WASM_BUNDLER_FRIENDLY_BOOT_CONFIG=true" />
<HelixCommandPrefixEnvVarItem Condition="'$(WorkloadsTestPreviousVersions)' == 'true'" Include="WORKLOADS_TEST_PREVIOUS_VERSIONS=true" />
</ItemGroup>

Expand Down Expand Up @@ -348,7 +349,7 @@
<Target Name="PrintHelixQueues">
<Message Importance="High" Text="Using Queues: $(HelixTargetQueues)" />
<Message Condition="'$(Scenario)' == 'BuildWasmApps'" Importance="High"
Text="Scenario: $(Scenario), TestUsingWorkloads: $(TestUsingWorkloads), WasmEnableWebcil: $(WasmEnableWebcil), WasmFingerprintAssets: $(WasmFingerprintAssets)" />
Text="Scenario: $(Scenario), TestUsingWorkloads: $(TestUsingWorkloads), WasmEnableWebcil: $(WasmEnableWebcil), WasmFingerprintAssets: $(WasmFingerprintAssets), WasmBundlerFriendlyBootConfig: $(WasmBundlerFriendlyBootConfig)" />
</Target>

<Target Name="PrintBuildTargetFramework">
Expand Down
103 changes: 74 additions & 29 deletions src/mono/browser/runtime/dotnet.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,7 @@ type MonoConfig = {
* Gets the application culture. This is a name specified in the BCP 47 format. See https://tools.ietf.org/html/bcp47
*/
applicationCulture?: string;
/**
* definition of assets to load along with the runtime.
*/
resources?: ResourceGroups;
resources?: Assets;
/**
* appsettings files to load to VFS
*/
Expand All @@ -247,36 +244,84 @@ type MonoConfig = {
type ResourceExtensions = {
[extensionName: string]: ResourceList;
};
interface ResourceGroups {
interface Assets {
hash?: string;
fingerprinting?: {
[name: string]: string;
};
coreAssembly?: ResourceList;
assembly?: ResourceList;
lazyAssembly?: ResourceList;
corePdb?: ResourceList;
pdb?: ResourceList;
jsModuleWorker?: ResourceList;
jsModuleDiagnostics?: ResourceList;
jsModuleNative: ResourceList;
jsModuleRuntime: ResourceList;
wasmSymbols?: ResourceList;
wasmNative: ResourceList;
icu?: ResourceList;
coreAssembly?: AssemblyAsset[];
assembly?: AssemblyAsset[];
lazyAssembly?: AssemblyAsset[];
corePdb?: PdbAsset[];
pdb?: PdbAsset[];
jsModuleWorker?: JsAsset[];
jsModuleDiagnostics?: JsAsset[];
jsModuleNative: JsAsset[];
jsModuleRuntime: JsAsset[];
wasmSymbols?: SymbolsAsset[];
wasmNative: WasmAsset[];
icu?: IcuAsset[];
satelliteResources?: {
[cultureName: string]: ResourceList;
[cultureName: string]: AssemblyAsset[];
};
modulesAfterConfigLoaded?: ResourceList;
modulesAfterRuntimeReady?: ResourceList;
modulesAfterConfigLoaded?: JsAsset[];
modulesAfterRuntimeReady?: JsAsset[];
extensions?: ResourceExtensions;
coreVfs?: {
[virtualPath: string]: ResourceList;
};
vfs?: {
[virtualPath: string]: ResourceList;
};
coreVfs?: VfsAsset[];
vfs?: VfsAsset[];
}
type Asset = {
/**
* this should be absolute url to the asset
*/
resolvedUrl?: string;
/**
* If true, the runtime startup would not fail if the asset download was not successful.
*/
isOptional?: boolean;
/**
* 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 | Promise<ArrayBuffer>;
/**
* It's metadata + fetch-like Promise<Response>
* If provided, the runtime doesn't have to initiate the download. It would just await the response.
*/
pendingDownload?: LoadingResource;
};
type WasmAsset = Asset & {
name: string;
hash?: string | null | "";
};
type AssemblyAsset = Asset & {
virtualPath: string;
name: string;
hash?: string | null | "";
};
type PdbAsset = Asset & {
virtualPath: string;
name: string;
hash?: string | null | "";
};
type JsAsset = Asset & {
/**
* If provided, runtime doesn't have to import it's JavaScript modules.
* This will not work for multi-threaded runtime.
*/
moduleExports?: any | Promise<any>;
name?: string;
};
type SymbolsAsset = Asset & {
name: string;
};
type VfsAsset = Asset & {
virtualPath: string;
name: string;
hash?: string | null | "";
};
type IcuAsset = Asset & {
virtualPath: string;
name: string;
hash?: string | null | "";
};
/**
* A "key" is name of the file, a "value" is optional hash for integrity check.
*/
Expand Down
64 changes: 23 additions & 41 deletions src/mono/browser/runtime/lazyLoading.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

import { loaderHelpers } from "./globals";
import { load_lazy_assembly } from "./managed-exports";
import { AssetEntry } from "./types";
import { type AssemblyAsset, type PdbAsset } from "./types";
import { type AssetEntryInternal } from "./types/internal";

export async function loadLazyAssembly (assemblyNameToLoad: string): Promise<boolean> {
const resources = loaderHelpers.config.resources!;
Expand All @@ -20,50 +21,35 @@ export async function loadLazyAssembly (assemblyNameToLoad: string): Promise<boo

const assemblyNameToLoadDll = assemblyNameWithoutExtension + ".dll";
const assemblyNameToLoadWasm = assemblyNameWithoutExtension + ".wasm";
if (loaderHelpers.config.resources!.fingerprinting) {
const map = loaderHelpers.config.resources!.fingerprinting;
for (const fingerprintedName in map) {
const nonFingerprintedName = map[fingerprintedName];
if (nonFingerprintedName == assemblyNameToLoadDll || nonFingerprintedName == assemblyNameToLoadWasm) {
assemblyNameToLoad = fingerprintedName;
break;
}
}
}

if (!lazyAssemblies[assemblyNameToLoad]) {
if (lazyAssemblies[assemblyNameToLoadDll]) {
assemblyNameToLoad = assemblyNameToLoadDll;
} else if (lazyAssemblies[assemblyNameToLoadWasm]) {
assemblyNameToLoad = assemblyNameToLoadWasm;
} else {
throw new Error(`${assemblyNameToLoad} must be marked with 'BlazorWebAssemblyLazyLoad' item group in your project file to allow lazy-loading.`);
let dllAsset: (AssemblyAsset & AssetEntryInternal) | null = null;
for (let i = 0; i < lazyAssemblies.length; i++) {
const asset = lazyAssemblies[i];
if (asset.virtualPath === assemblyNameToLoadDll || asset.virtualPath === assemblyNameToLoadWasm) {
dllAsset = asset as AssemblyAsset & AssetEntryInternal;
dllAsset.behavior = "assembly";
break;
}
}

const dllAsset: AssetEntry = {
name: assemblyNameToLoad,
hash: lazyAssemblies[assemblyNameToLoad],
behavior: "assembly",
};
if (dllAsset == null) {
throw new Error(`${assemblyNameToLoad} must be marked with 'BlazorWebAssemblyLazyLoad' item group in your project file to allow lazy-loading.`);
}

if (loaderHelpers.loadedAssemblies.includes(assemblyNameToLoad)) {
if (loaderHelpers.loadedAssemblies.includes(dllAsset.name)) {
return false;
}

let pdbNameToLoad = assemblyNameWithoutExtension + ".pdb";
const pdbNameToLoad = assemblyNameWithoutExtension + ".pdb";
let shouldLoadPdb = false;
let pdbAsset: (PdbAsset & AssetEntryInternal) | null = null;
if (loaderHelpers.config.debugLevel != 0 && loaderHelpers.isDebuggingSupported()) {
shouldLoadPdb = Object.prototype.hasOwnProperty.call(lazyAssemblies, pdbNameToLoad);
if (loaderHelpers.config.resources!.fingerprinting) {
const map = loaderHelpers.config.resources!.fingerprinting;
for (const fingerprintedName in map) {
const nonFingerprintedName = map[fingerprintedName];
if (nonFingerprintedName == pdbNameToLoad) {
pdbNameToLoad = fingerprintedName;
shouldLoadPdb = true;
break;
}
for (let i = 0; i < lazyAssemblies.length; i++) {
if (lazyAssemblies[i].virtualPath === pdbNameToLoad) {
shouldLoadPdb = true;
pdbAsset = lazyAssemblies[i] as PdbAsset & AssetEntryInternal;
pdbAsset.behavior = "pdb";
break;
}
}
}
Expand All @@ -73,12 +59,8 @@ export async function loadLazyAssembly (assemblyNameToLoad: string): Promise<boo
let dll = null;
let pdb = null;
if (shouldLoadPdb) {
const pdbBytesPromise = lazyAssemblies[pdbNameToLoad]
? loaderHelpers.retrieve_asset_download({
name: pdbNameToLoad,
hash: lazyAssemblies[pdbNameToLoad],
behavior: "pdb"
})
const pdbBytesPromise = pdbAsset != null
? loaderHelpers.retrieve_asset_download(pdbAsset)
: Promise.resolve(null);

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