Skip to content

Commit 2346e99

Browse files
authored
feat!: use .net 10 runtime config (#194)
1 parent db6204f commit 2346e99

6 files changed

Lines changed: 199 additions & 104 deletions

File tree

src/cs/Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project>
22

33
<PropertyGroup>
4-
<Version>0.8.0-alpha.45</Version>
4+
<Version>0.8.0-alpha.46</Version>
55
<Authors>Elringus</Authors>
66
<PackageTags>javascript typescript ts js wasm node deno bun interop codegen</PackageTags>
77
<PackageProjectUrl>https://bootsharp.com</PackageProjectUrl>

src/js/scripts/compile-test.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
cd test/cs
2+
rm -rf Test/bin Test/obj Test.Types/bin Test.Types/obj
23
dotnet restore --no-cache --force-evaluate
34
dotnet publish -p BootsharpName=embedded -p BootsharpEmbedBinaries=true -c Debug
5+
rm -rf Test/bin/Debug Test/obj Test.Types/bin Test.Types/obj
46
dotnet publish -p BootsharpName=sideload -p BootsharpEmbedBinaries=false -c Debug

src/js/src/config.ts

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { RuntimeConfig, AssetEntry, AssetBehaviors, getRuntime, getNative, getMain } from "./modules";
1+
import { RuntimeConfig, RuntimeWasm, RuntimeModule, RuntimeAssembly, getRuntime, getNative } from "./modules";
22
import { BinaryResource, BootResources } from "./resources";
33
import { decodeBase64 } from "./decoder";
44

@@ -7,39 +7,43 @@ import { decodeBase64 } from "./decoder";
77
* @param root When specified, assumes boot resources are side-loaded from the specified root. */
88
export async function buildConfig(resources: BootResources, root?: string): Promise<RuntimeConfig> {
99
const embed = root == null;
10-
const assets: AssetEntry[] = await Promise.all([
10+
const mt = !embed && (await import("./dotnet.g")).mt;
11+
const [wasm, native, runtime, assemblies] = await Promise.all([
1112
resolveWasm(),
12-
resolveModule("dotnet.js", "js-module-dotnet", embed ? getMain : undefined),
13-
resolveModule("dotnet.native.js", "js-module-native", embed ? getNative : undefined),
14-
resolveModule("dotnet.runtime.js", "js-module-runtime", embed ? getRuntime : undefined),
15-
...resources.assemblies.map(resolveAssembly)
13+
resolveModule("dotnet.native.js", embed ? getNative : undefined),
14+
resolveModule("dotnet.runtime.js", embed ? getRuntime : undefined),
15+
Promise.all(resources.assemblies.map(resolveAssembly))
1616
]);
17-
const mt = !embed && (await import("./dotnet.g")).mt;
18-
if (mt) assets.push(await resolveModule("dotnet.native.worker.mjs", "js-module-threads"));
19-
return { assets, mainAssemblyName: resources.entryAssemblyName };
17+
return {
18+
resources: {
19+
wasmNative: [wasm],
20+
jsModuleNative: [native],
21+
jsModuleRuntime: [runtime],
22+
jsModuleWorker: mt ? [await resolveModule("dotnet.native.worker.mjs")] : undefined,
23+
assembly: assemblies
24+
},
25+
mainAssemblyName: resources.entryAssemblyName
26+
};
2027

21-
async function resolveWasm(): Promise<AssetEntry> {
28+
async function resolveWasm(): Promise<RuntimeWasm> {
2229
return {
2330
name: resources.wasm.name,
24-
buffer: await resolveBuffer(resources.wasm),
25-
behavior: "dotnetwasm"
31+
buffer: await resolveBuffer(resources.wasm)
2632
};
2733
}
2834

29-
async function resolveModule(name: string, behavior: AssetBehaviors,
30-
embed?: () => Promise<unknown>): Promise<AssetEntry> {
35+
async function resolveModule(name: string, embed?: () => Promise<unknown>): Promise<RuntimeModule> {
3136
return {
3237
name,
33-
moduleExports: embed ? await embed() : undefined,
34-
behavior
38+
moduleExports: embed ? await embed() : undefined
3539
};
3640
}
3741

38-
async function resolveAssembly(res: BinaryResource): Promise<AssetEntry> {
42+
async function resolveAssembly(res: BinaryResource): Promise<RuntimeAssembly> {
3943
return {
4044
name: res.name,
41-
buffer: await resolveBuffer(res),
42-
behavior: "assembly"
45+
virtualPath: res.name,
46+
buffer: await resolveBuffer(res)
4347
};
4448
}
4549

src/js/src/dotnet.g.d.ts

Lines changed: 144 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
export const embedded = false;
33
export const mt = false;
44

5-
// Types: https://github.com/dotnet/runtime/blob/v9.0.0/src/mono/browser/runtime/dotnet.d.ts
5+
// Types: https://github.com/dotnet/runtime/blob/release/10.0/src/mono/browser/runtime/dotnet.d.ts
66

77
declare interface NativePointer {
88
__brandNativePointer: "NativePointer";
@@ -57,11 +57,11 @@ declare type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Arra
5757
interface DotnetHostBuilder {
5858
/**
5959
* @param config default values for the runtime configuration. It will be merged with the default values.
60-
* Note that if you provide resources and don't provide custom configSrc URL, the blazor.boot.json will be downloaded and applied by default.
60+
* Note that if you provide resources and don't provide custom configSrc URL, the dotnet.boot.js will be downloaded and applied by default.
6161
*/
6262
withConfig(config: MonoConfig): DotnetHostBuilder;
6363
/**
64-
* @param configSrc URL to the configuration file. ./blazor.boot.json is a default config file location.
64+
* @param configSrc URL to the configuration file. ./dotnet.boot.js is a default config file location.
6565
*/
6666
withConfigSrc(configSrc: string): DotnetHostBuilder;
6767
/**
@@ -165,14 +165,6 @@ type MonoConfig = {
165165
* debugLevel < 0 enables debugging and disables debug logging.
166166
*/
167167
debugLevel?: number;
168-
/**
169-
* Gets a value that determines whether to enable caching of the 'resources' inside a CacheStorage instance within the browser.
170-
*/
171-
cacheBootResources?: boolean;
172-
/**
173-
* Delay of the purge of the cached resources in milliseconds. Default is 10000 (10 seconds).
174-
*/
175-
cachedResourcesPurgeDelay?: number;
176168
/**
177169
* Configures use of the `integrity` directive for fetching assets
178170
*/
@@ -191,6 +183,16 @@ type MonoConfig = {
191183
environmentVariables?: {
192184
[i: string]: string;
193185
};
186+
/**
187+
* Subset of runtimeconfig.json
188+
*/
189+
runtimeConfig?: {
190+
runtimeOptions?: {
191+
configProperties?: {
192+
[i: string]: string | number | boolean;
193+
};
194+
};
195+
};
194196
/**
195197
* initial number of workers to add to the emscripten pthread pool
196198
*/
@@ -217,10 +219,7 @@ type MonoConfig = {
217219
* Gets the application culture. This is a name specified in the BCP 47 format. See https://tools.ietf.org/html/bcp47
218220
*/
219221
applicationCulture?: string;
220-
/**
221-
* definition of assets to load along with the runtime.
222-
*/
223-
resources?: ResourceGroups;
222+
resources?: Assets;
224223
/**
225224
* appsettings files to load to VFS
226225
*/
@@ -244,36 +243,90 @@ type MonoConfig = {
244243
type ResourceExtensions = {
245244
[extensionName: string]: ResourceList;
246245
};
247-
interface ResourceGroups {
246+
interface Assets {
248247
hash?: string;
249-
fingerprinting?: {
250-
[name: string]: string;
251-
};
252-
coreAssembly?: ResourceList;
253-
assembly?: ResourceList;
254-
lazyAssembly?: ResourceList;
255-
corePdb?: ResourceList;
256-
pdb?: ResourceList;
257-
jsModuleWorker?: ResourceList;
258-
jsModuleGlobalization?: ResourceList;
259-
jsModuleNative: ResourceList;
260-
jsModuleRuntime: ResourceList;
261-
wasmSymbols?: ResourceList;
262-
wasmNative: ResourceList;
263-
icu?: ResourceList;
248+
coreAssembly?: AssemblyAsset[];
249+
assembly?: AssemblyAsset[];
250+
lazyAssembly?: AssemblyAsset[];
251+
corePdb?: PdbAsset[];
252+
pdb?: PdbAsset[];
253+
jsModuleWorker?: JsAsset[];
254+
jsModuleDiagnostics?: JsAsset[];
255+
jsModuleNative: JsAsset[];
256+
jsModuleRuntime: JsAsset[];
257+
wasmSymbols?: SymbolsAsset[];
258+
wasmNative: WasmAsset[];
259+
icu?: IcuAsset[];
264260
satelliteResources?: {
265-
[cultureName: string]: ResourceList;
261+
[cultureName: string]: AssemblyAsset[];
266262
};
267-
modulesAfterConfigLoaded?: ResourceList;
268-
modulesAfterRuntimeReady?: ResourceList;
263+
modulesAfterConfigLoaded?: JsAsset[];
264+
modulesAfterRuntimeReady?: JsAsset[];
269265
extensions?: ResourceExtensions;
270-
coreVfs?: {
271-
[virtualPath: string]: ResourceList;
272-
};
273-
vfs?: {
274-
[virtualPath: string]: ResourceList;
275-
};
266+
coreVfs?: VfsAsset[];
267+
vfs?: VfsAsset[];
276268
}
269+
type Asset = {
270+
/**
271+
* this should be absolute url to the asset
272+
*/
273+
resolvedUrl?: string;
274+
/**
275+
* If true, the runtime startup would not fail if the asset download was not successful.
276+
*/
277+
isOptional?: boolean;
278+
/**
279+
* If provided, runtime doesn't have to fetch the data.
280+
* Runtime would set the buffer to null after instantiation to free the memory.
281+
*/
282+
buffer?: ArrayBuffer | Promise<ArrayBuffer>;
283+
/**
284+
* It's metadata + fetch-like Promise<Response>
285+
* If provided, the runtime doesn't have to initiate the download. It would just await the response.
286+
*/
287+
pendingDownload?: LoadingResource;
288+
};
289+
type WasmAsset = Asset & {
290+
name: string;
291+
hash?: string | null | "";
292+
cache?: RequestCache;
293+
};
294+
type AssemblyAsset = Asset & {
295+
virtualPath: string;
296+
name: string;
297+
hash?: string | null | "";
298+
cache?: RequestCache;
299+
};
300+
type PdbAsset = Asset & {
301+
virtualPath: string;
302+
name: string;
303+
hash?: string | null | "";
304+
cache?: RequestCache;
305+
};
306+
type JsAsset = Asset & {
307+
/**
308+
* If provided, runtime doesn't have to import it's JavaScript modules.
309+
* This will not work for multi-threaded runtime.
310+
*/
311+
moduleExports?: any | Promise<any>;
312+
name?: string;
313+
};
314+
type SymbolsAsset = Asset & {
315+
name: string;
316+
cache?: RequestCache;
317+
};
318+
type VfsAsset = Asset & {
319+
virtualPath: string;
320+
name: string;
321+
hash?: string | null | "";
322+
cache?: RequestCache;
323+
};
324+
type IcuAsset = Asset & {
325+
virtualPath: string;
326+
name: string;
327+
hash?: string | null | "";
328+
cache?: RequestCache;
329+
};
277330
/**
278331
* A "key" is name of the file, a "value" is optional hash for integrity check.
279332
*/
@@ -291,7 +344,10 @@ type ResourceList = {
291344
* @returns A URI string or a Response promise to override the loading process, or null/undefined to allow the default loading behavior.
292345
* When returned string is not qualified with `./` or absolute URL, it will be resolved against the application base URI.
293346
*/
294-
type LoadBootResourceCallback = (type: WebAssemblyBootResourceType, name: string, defaultUri: string, integrity: string, behavior: AssetBehaviors) => string | Promise<Response> | null | undefined;
347+
type LoadBootResourceCallback = (type: WebAssemblyBootResourceType, name: string, defaultUri: string, integrity: string, behavior: AssetBehaviors) => string | Promise<Response> | Promise<BootModule> | null | undefined;
348+
type BootModule = {
349+
config: MonoConfig;
350+
};
295351
interface LoadingResource {
296352
name: string;
297353
url: string;
@@ -359,6 +415,10 @@ type SingleAssetBehaviors =
359415
* The javascript module for threads.
360416
*/
361417
| "js-module-threads"
418+
/**
419+
* The javascript module for diagnostic server and client.
420+
*/
421+
| "js-module-diagnostics"
362422
/**
363423
* The javascript module for runtime.
364424
*/
@@ -368,21 +428,13 @@ type SingleAssetBehaviors =
368428
*/
369429
| "js-module-native"
370430
/**
371-
* The javascript module for hybrid globalization.
372-
*/
373-
| "js-module-globalization"
374-
/**
375-
* Typically blazor.boot.json
431+
* Typically dotnet.boot.js
376432
*/
377433
| "manifest"
378434
/**
379435
* The debugging symbols
380436
*/
381-
| "symbols"
382-
/**
383-
* Load segmentation rules file for Hybrid Globalization.
384-
*/
385-
| "segmentation-rules";
437+
| "symbols";
386438
type AssetBehaviors = SingleAssetBehaviors |
387439
/**
388440
* Load asset as a managed resource assembly.
@@ -428,11 +480,7 @@ declare const enum GlobalizationMode {
428480
/**
429481
* Use user defined icu file.
430482
*/
431-
Custom = "custom",
432-
/**
433-
* Operate in hybrid globalization mode with small ICU files, using native platform functions.
434-
*/
435-
Hybrid = "hybrid"
483+
Custom = "custom"
436484
}
437485
type DotnetModuleConfig = {
438486
config?: MonoConfig;
@@ -443,7 +491,7 @@ type DotnetModuleConfig = {
443491
imports?: any;
444492
exports?: string[];
445493
} & Partial<EmscriptenModule>;
446-
type APIType = {
494+
type RunAPIType = {
447495
/**
448496
* Runs the Main() method of the application.
449497
* Note: this will keep the .NET runtime alive and the APIs will be available for further calls.
@@ -493,6 +541,8 @@ type APIType = {
493541
* You can register the scripts using MonoConfig.resources.modulesAfterConfigLoaded and MonoConfig.resources.modulesAfterRuntimeReady.
494542
*/
495543
invokeLibraryInitializers: (functionName: string, args: any[]) => Promise<void>;
544+
};
545+
type MemoryAPIType = {
496546
/**
497547
* Writes to the WASM linear memory
498548
*/
@@ -634,6 +684,43 @@ type APIType = {
634684
*/
635685
localHeapViewF64: () => Float64Array;
636686
};
687+
type DiagnosticsAPIType = {
688+
/**
689+
* creates diagnostic trace file. Default is 60 seconds.
690+
* It could be opened in PerfView or Visual Studio as is.
691+
*/
692+
collectCpuSamples: (options?: DiagnosticCommandOptions) => Promise<Uint8Array[]>;
693+
/**
694+
* creates diagnostic trace file. Default is 60 seconds.
695+
* It could be opened in PerfView or Visual Studio as is.
696+
* It could be summarized by `dotnet-trace report xxx.nettrace topN -n 10`
697+
*/
698+
collectMetrics: (options?: DiagnosticCommandOptions) => Promise<Uint8Array[]>;
699+
/**
700+
* creates diagnostic trace file.
701+
* It could be opened in PerfView as is.
702+
* It could be converted for Visual Studio using `dotnet-gcdump convert`.
703+
*/
704+
collectGcDump: (options?: DiagnosticCommandOptions) => Promise<Uint8Array[]>;
705+
/**
706+
* changes DOTNET_DiagnosticPorts and makes a new connection to WebSocket on that URL.
707+
*/
708+
connectDSRouter(url: string): void;
709+
};
710+
type DiagnosticCommandProviderV2 = {
711+
keywords: [number, number];
712+
logLevel: number;
713+
provider_name: string;
714+
arguments: string | null;
715+
};
716+
type DiagnosticCommandOptions = {
717+
durationSeconds?: number;
718+
intervalSeconds?: number;
719+
skipDownload?: boolean;
720+
circularBufferMB?: number;
721+
extraProviders?: DiagnosticCommandProviderV2[];
722+
};
723+
type APIType = RunAPIType & MemoryAPIType & DiagnosticsAPIType;
637724
type RuntimeAPI = {
638725
INTERNAL: any;
639726
Module: EmscriptenModule;

0 commit comments

Comments
 (0)