Skip to content

Commit 0b0a98b

Browse files
committed
Cleanups and Blazor server implementation
1 parent 309e8b1 commit 0b0a98b

11 files changed

+99
-12
lines changed

src/Components/Server/src/Builder/ComponentEndpointConventionBuilder.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ public sealed class ComponentEndpointConventionBuilder : IHubEndpointConventionB
1212
{
1313
private readonly IEndpointConventionBuilder _hubEndpoint;
1414
private readonly IEndpointConventionBuilder _disconnectEndpoint;
15+
private readonly IEndpointConventionBuilder _jsInitializersEndpoint;
1516

16-
internal ComponentEndpointConventionBuilder(IEndpointConventionBuilder hubEndpoint, IEndpointConventionBuilder disconnectEndpoint)
17+
internal ComponentEndpointConventionBuilder(IEndpointConventionBuilder hubEndpoint, IEndpointConventionBuilder disconnectEndpoint, IEndpointConventionBuilder jsInitializersEndpoint)
1718
{
1819
_hubEndpoint = hubEndpoint;
1920
_disconnectEndpoint = disconnectEndpoint;
21+
_jsInitializersEndpoint = jsInitializersEndpoint;
2022
}
2123

2224
/// <summary>
@@ -27,6 +29,7 @@ public void Add(Action<EndpointBuilder> convention)
2729
{
2830
_hubEndpoint.Add(convention);
2931
_disconnectEndpoint.Add(convention);
32+
_jsInitializersEndpoint.Add(convention);
3033
}
3134
}
3235
}

src/Components/Server/src/Builder/ComponentEndpointRouteBuilderExtensions.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33

44
using System;
55
using Microsoft.AspNetCore.Components.Server;
6+
using Microsoft.AspNetCore.Hosting;
67
using Microsoft.AspNetCore.Http.Connections;
78
using Microsoft.AspNetCore.Routing;
89
using Microsoft.AspNetCore.SignalR;
10+
using Microsoft.Extensions.DependencyInjection;
11+
using Microsoft.Extensions.Hosting;
912

1013
namespace Microsoft.AspNetCore.Builder
1114
{
@@ -110,7 +113,12 @@ public static ComponentEndpointConventionBuilder MapBlazorHub(
110113
endpoints.CreateApplicationBuilder().UseMiddleware<CircuitDisconnectMiddleware>().Build())
111114
.WithDisplayName("Blazor disconnect");
112115

113-
return new ComponentEndpointConventionBuilder(hubEndpoint, disconnectEndpoint);
116+
var jsInitializersEndpoint = endpoints.Map(
117+
(path.EndsWith('/') ? path : path + "/") + "initializers/",
118+
endpoints.CreateApplicationBuilder().UseMiddleware<CircuitJavaScriptInitializationMiddleware>().Build())
119+
.WithDisplayName("Blazor initializers");
120+
121+
return new ComponentEndpointConventionBuilder(hubEndpoint, disconnectEndpoint, jsInitializersEndpoint);
114122
}
115123
}
116124
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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.AspNetCore.Components.Server;
5+
using Microsoft.AspNetCore.Http;
6+
using Microsoft.Extensions.Options;
7+
8+
namespace Microsoft.AspNetCore.Builder
9+
{
10+
internal class CircuitJavaScriptInitializationMiddleware
11+
{
12+
private readonly IList<string> _initializers;
13+
14+
public CircuitJavaScriptInitializationMiddleware(IOptions<CircuitOptions> options)
15+
{
16+
_initializers = options.Value.JavaScriptInitializers;
17+
}
18+
19+
public async Task InvokeAsync(HttpContext context)
20+
{
21+
await context.Response.WriteAsJsonAsync(_initializers);
22+
}
23+
}
24+
}

src/Components/Server/src/CircuitOptions.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
using System;
5-
using Microsoft.AspNetCore.Components.Web;
4+
using Microsoft.Extensions.Hosting;
65

76
namespace Microsoft.AspNetCore.Components.Server
87
{
@@ -82,5 +81,11 @@ public sealed class CircuitOptions
8281
/// Gets options for root components within the circuit.
8382
/// </summary>
8483
public CircuitRootComponentOptions RootComponents { get; } = new CircuitRootComponentOptions();
84+
85+
/// <summary>
86+
/// Gets the list of JavaScript initializers used by Blazor server. By default this list gets populated by
87+
/// the <c><see cref="IHostEnvironment.ApplicationName"/>.modules.json</c> manifest file in the web root if present.
88+
/// </summary>
89+
public IList<string> JavaScriptInitializers { get; } = new List<string>();
8590
}
8691
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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 System.Text.Json;
5+
using Microsoft.AspNetCore.Hosting;
6+
using Microsoft.Extensions.Options;
7+
8+
namespace Microsoft.AspNetCore.Components.Server.Circuits
9+
{
10+
internal class CircuitOptionsJavaScriptInitializersConfiguration : IConfigureOptions<CircuitOptions>
11+
{
12+
private readonly IWebHostEnvironment _environment;
13+
14+
public CircuitOptionsJavaScriptInitializersConfiguration(IWebHostEnvironment environment)
15+
{
16+
_environment = environment;
17+
}
18+
19+
public void Configure(CircuitOptions options)
20+
{
21+
var file = _environment.WebRootFileProvider.GetFileInfo($"{_environment.ApplicationName}.modules.json");
22+
if (file.Exists)
23+
{
24+
var initializers = JsonSerializer.Deserialize<string[]>(file.CreateReadStream());
25+
for (var i = 0; i < initializers.Length; i++)
26+
{
27+
var initializer = initializers[i];
28+
options.JavaScriptInitializers.Add(initializer);
29+
}
30+
}
31+
}
32+
}
33+
}

src/Components/Server/src/ComponentHub.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using Microsoft.AspNetCore.Http;
1313
using Microsoft.AspNetCore.SignalR;
1414
using Microsoft.Extensions.Logging;
15+
using Microsoft.Extensions.Options;
1516

1617
namespace Microsoft.AspNetCore.Components.Server
1718
{

src/Components/Server/src/DependencyInjection/ComponentServiceCollectionExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ public static IServerSideBlazorBuilder AddServerSideBlazor(this IServiceCollecti
8383
services.AddScoped<AuthenticationStateProvider, ServerAuthenticationStateProvider>();
8484

8585
services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<CircuitOptions>, CircuitOptionsJSInteropDetailedErrorsConfiguration>());
86+
services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<CircuitOptions>, CircuitOptionsJavaScriptInitializersConfiguration>());
8687

8788
if (configure != null)
8889
{

src/Components/Server/src/PublicAPI.Unshipped.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#nullable enable
2+
Microsoft.AspNetCore.Components.Server.CircuitOptions.JavaScriptInitializers.get -> System.Collections.Generic.IList<string!>!
23
Microsoft.AspNetCore.Components.Server.CircuitOptions.RootComponents.get -> Microsoft.AspNetCore.Components.Server.CircuitRootComponentOptions!
34
Microsoft.AspNetCore.Components.Server.CircuitRootComponentOptions
45
Microsoft.AspNetCore.Components.Server.CircuitRootComponentOptions.CircuitRootComponentOptions() -> void

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { DefaultReconnectionHandler } from './Platform/Circuits/DefaultReconnect
1414
import { attachRootComponentToLogicalElement } from './Rendering/Renderer';
1515
import { discoverComponents, discoverPersistedState, ServerComponentDescriptor } from './Services/ComponentDescriptorDiscovery';
1616
import { sendJSDataStream } from './Platform/Circuits/CircuitStreamingInterop';
17+
import { JSInitializers } from './JSInitializers';
1718

1819
let renderingFailed = false;
1920
let started = false;
@@ -26,6 +27,15 @@ async function boot(userOptions?: Partial<CircuitStartOptions>): Promise<void> {
2627

2728
// Establish options to be used
2829
const options = resolveOptions(userOptions);
30+
const jsInitializersResponse = await fetch('_blazor/initializers', {
31+
method: 'GET',
32+
credentials: 'include',
33+
cache: 'no-cache'
34+
});
35+
36+
const initializers: string[] = await jsInitializersResponse.json();
37+
const afterStartedCallbacks = await JSInitializers.invokeInitializersAsync(initializers, [options]);
38+
2939
const logger = new ConsoleLogger(options.logLevel);
3040
Blazor.defaultReconnectionHandler = new DefaultReconnectionHandler(logger);
3141

@@ -36,7 +46,6 @@ async function boot(userOptions?: Partial<CircuitStartOptions>): Promise<void> {
3646
const appState = discoverPersistedState(document);
3747
const circuit = new CircuitDescriptor(components, appState || '');
3848

39-
4049
const initialConnection = await initializeConnection(options, logger, circuit);
4150
const circuitStarted = await circuit.startCircuit(initialConnection);
4251
if (!circuitStarted) {
@@ -58,6 +67,8 @@ async function boot(userOptions?: Partial<CircuitStartOptions>): Promise<void> {
5867

5968
options.reconnectionHandler!.onConnectionUp();
6069

70+
Promise.all(afterStartedCallbacks.map(c => c(Blazor)));
71+
6172
return true;
6273
};
6374

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ import { shouldAutoStart } from './BootCommon';
99
import { setEventDispatcher } from './Rendering/Events/EventDispatcher';
1010
import { WebAssemblyResourceLoader } from './Platform/WebAssemblyResourceLoader';
1111
import { WebAssemblyConfigLoader } from './Platform/WebAssemblyConfigLoader';
12-
import { BootConfigResult, BootJsonData, BootJsonDataExtension } from './Platform/BootConfig';
12+
import { BootConfigResult } from './Platform/BootConfig';
1313
import { Pointer, System_Array, System_Boolean, System_Byte, System_Int, System_Object, System_String } from './Platform/Platform';
1414
import { WebAssemblyStartOptions } from './Platform/WebAssemblyStartOptions';
1515
import { WebAssemblyComponentAttacher } from './Platform/WebAssemblyComponentAttacher';
1616
import { discoverComponents, discoverPersistedState, WebAssemblyComponentDescriptor } from './Services/ComponentDescriptorDiscovery';
17-
import { AfterBlazorStartedCallback, WebAssemblyJSInitializers } from './Platform/Initialization/WebAssemblyJSInitializers';
17+
import { AfterBlazorStartedCallback, JSInitializers } from './JSInitializers';
1818

1919
declare var Module: EmscriptenModule;
2020
let started = false;
@@ -123,7 +123,7 @@ async function boot(options?: Partial<WebAssemblyStartOptions>): Promise<void> {
123123
let afterBlazorStartedCallbacks: AfterBlazorStartedCallback[] = [];
124124
if (bootConfigResult.bootConfig.libraryInitializers) {
125125
const initializerFiles = bootConfigResult.bootConfig.libraryInitializers;
126-
afterBlazorStartedCallbacks = await WebAssemblyJSInitializers.invokeInitializersAsync(
126+
afterBlazorStartedCallbacks = await JSInitializers.invokeInitializersAsync(
127127
Object.keys(initializerFiles),
128128
[candidateOptions, bootConfigResult.bootConfig.extensions]);
129129
}

0 commit comments

Comments
 (0)