Skip to content

Commit 6284b44

Browse files
committed
Pass environment as SSR component payload for standalone mode
1 parent 163e87c commit 6284b44

File tree

7 files changed

+54
-10
lines changed

7 files changed

+54
-10
lines changed

src/Components/Endpoints/src/DependencyInjection/RazorComponentsServiceCollectionExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ public static IRazorComponentsBuilder AddRazorComponents(this IServiceCollection
7171
services.TryAddScoped<AuthenticationStateProvider, ServerAuthenticationStateProvider>();
7272
services.AddSupplyValueFromQueryProvider();
7373
services.TryAddCascadingValue(sp => sp.GetRequiredService<EndpointHtmlRenderer>().HttpContext);
74+
services.TryAddScoped<WebAssemblyEnvironmentEmitter>();
7475

7576
services.TryAddScoped<ResourceCollectionProvider>();
7677

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Microsoft.Extensions.Hosting;
5+
6+
namespace Microsoft.AspNetCore.Components.Endpoints;
7+
8+
internal class WebAssemblyEnvironmentEmitter(IHostEnvironment hostEnvironment)
9+
{
10+
private bool wasEmittedAlready;
11+
12+
public string? GetEnvironmentOnce()
13+
{
14+
if (wasEmittedAlready)
15+
{
16+
return null;
17+
}
18+
19+
wasEmittedAlready = true;
20+
return hostEnvironment.EnvironmentName;
21+
}
22+
}

src/Components/Endpoints/src/Rendering/SSRRenderModeBoundary.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,8 @@ public ComponentMarker ToMarker(HttpContext httpContext, int sequence, object? c
165165
var marker = RenderMode switch
166166
{
167167
InteractiveServerRenderMode server => ComponentMarker.Create(ComponentMarker.ServerMarkerType, server.Prerender, _markerKey),
168-
InteractiveWebAssemblyRenderMode webAssembly => ComponentMarker.Create(ComponentMarker.WebAssemblyMarkerType, webAssembly.Prerender, _markerKey),
169-
InteractiveAutoRenderMode auto => ComponentMarker.Create(ComponentMarker.AutoMarkerType, auto.Prerender, _markerKey),
168+
InteractiveWebAssemblyRenderMode webAssembly => ComponentMarker.Create(ComponentMarker.WebAssemblyMarkerType, webAssembly.Prerender, _markerKey, GetEnvironmentOnce(httpContext)),
169+
InteractiveAutoRenderMode auto => ComponentMarker.Create(ComponentMarker.AutoMarkerType, auto.Prerender, _markerKey, GetEnvironmentOnce(httpContext)),
170170
_ => throw new UnreachableException($"Unknown render mode {RenderMode.GetType().FullName}"),
171171
};
172172

@@ -188,6 +188,9 @@ public ComponentMarker ToMarker(HttpContext httpContext, int sequence, object? c
188188
return marker;
189189
}
190190

191+
private static string? GetEnvironmentOnce(HttpContext httpContext)
192+
=> httpContext.RequestServices.GetRequiredService<WebAssemblyEnvironmentEmitter>().GetEnvironmentOnce();
193+
191194
private ComponentMarkerKey GenerateMarkerKey(int sequence, object? componentKey)
192195
{
193196
var componentTypeNameHash = _componentTypeNameHashCache.GetOrAdd(_componentType, TypeNameHash.Compute);

src/Components/Web.JS/src/Boot.WebAssembly.Common.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,23 +68,23 @@ export function setWebAssemblyOptions(initializersReady: Promise<Partial<WebAsse
6868
}
6969
}
7070

71-
export function startWebAssembly(components: RootComponentManager<WebAssemblyComponentDescriptor>): Promise<void> {
71+
export function startWebAssembly(components: RootComponentManager<WebAssemblyComponentDescriptor>, environment: string | undefined): Promise<void> {
7272
if (startPromise !== undefined) {
7373
throw new Error('Blazor WebAssembly has already started.');
7474
}
7575

76-
startPromise = new Promise(startCore.bind(null, components));
76+
startPromise = new Promise(startCore.bind(null, components, environment));
7777

7878
return startPromise;
7979
}
8080

81-
async function startCore(components: RootComponentManager<WebAssemblyComponentDescriptor>, resolve, _) {
81+
async function startCore(components: RootComponentManager<WebAssemblyComponentDescriptor>, environment: string | undefined, resolve, _) {
8282
if (inAuthRedirectIframe()) {
8383
// eslint-disable-next-line @typescript-eslint/no-empty-function
8484
await new Promise(() => { }); // See inAuthRedirectIframe for explanation
8585
}
8686

87-
const platformLoadPromise = loadWebAssemblyPlatformIfNotStarted();
87+
const platformLoadPromise = loadWebAssemblyPlatformIfNotStarted(environment);
8888

8989
addDispatchEventMiddleware((browserRendererId, eventHandlerId, continuation) => {
9090
// It's extremely unusual, but an event can be raised while we're in the middle of synchronously applying a
@@ -206,10 +206,13 @@ export function waitForBootConfigLoaded(): Promise<MonoConfig> {
206206
return bootConfigPromise;
207207
}
208208

209-
export function loadWebAssemblyPlatformIfNotStarted(): Promise<void> {
209+
export function loadWebAssemblyPlatformIfNotStarted(environment: string | undefined): Promise<void> {
210210
platformLoadPromise ??= (async () => {
211211
await initializersPromise;
212212
const finalOptions = options ?? {};
213+
if (!finalOptions.environment) {
214+
finalOptions.environment = environment;
215+
}
213216
const existingConfig = options?.configureRuntime;
214217
finalOptions.configureRuntime = (config) => {
215218
existingConfig?.(config);

src/Components/Web.JS/src/Boot.WebAssembly.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,20 @@ async function boot(options?: Partial<WebAssemblyStartOptions>): Promise<void> {
2424

2525
JSEventRegistry.create(Blazor);
2626
const webAssemblyComponents = discoverComponents(document, 'webassembly') as WebAssemblyComponentDescriptor[];
27+
2728
const components = new InitialRootComponentsList(webAssemblyComponents);
28-
await startWebAssembly(components);
29+
await startWebAssembly(components, findEnvironment(webAssemblyComponents));
30+
}
31+
32+
function findEnvironment(webAssemblyComponents: WebAssemblyComponentDescriptor[]): string | undefined {
33+
for (let index = 0; index < webAssemblyComponents.length; index++) {
34+
const component = webAssemblyComponents[index];
35+
if (component.environment) {
36+
return component.environment;
37+
}
38+
}
39+
40+
return undefined;
2941
}
3042

3143
Blazor.start = boot;

src/Components/Web.JS/src/Services/ComponentDescriptorDiscovery.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ type ServerComponentMarker = {
355355

356356
type WebAssemblyComponentMarker = {
357357
type: 'webassembly';
358+
environment: string | undefined;
358359
} & WebAssemblyMarkerData;
359360

360361
type AutoComponentMarker = {

src/Components/Web.JS/src/Services/WebRootComponentManager.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ export class WebRootComponentManager implements DescriptorHandler, RootComponent
132132

133133
setWaitForRootComponents();
134134

135-
const loadWebAssemblyPromise = loadWebAssemblyPlatformIfNotStarted();
135+
// MF TODO: Pass the environment
136+
const loadWebAssemblyPromise = loadWebAssemblyPlatformIfNotStarted(undefined);
136137
const bootConfig = await waitForBootConfigLoaded();
137138

138139
if (maxParallelDownloadsOverride !== undefined) {
@@ -182,7 +183,8 @@ export class WebRootComponentManager implements DescriptorHandler, RootComponent
182183
this.startLoadingWebAssemblyIfNotStarted();
183184

184185
if (!hasStartedWebAssembly()) {
185-
await startWebAssembly(this);
186+
// MF TODO: Pass the environment
187+
await startWebAssembly(this, undefined);
186188
}
187189
}
188190

0 commit comments

Comments
 (0)