Conversation
…will be able to customize HTML rendering
…an vary its output based on this
…nent to a readonly struct
…treaming components
…for blazor.server.js
We used to serve sourcemaps when working on this repo. Not sure when that got broken.
…g render batch (to avoid duplicated HTML)
…treaming output into SectionOutlet This automatically deals with HeadOutlet as a special case
…gh it actually is already (transitively). This did not affect CLI builds.
…ly.Authentication needs to be rebuilt
It was so inconvenient not being able to just reload the existing browser tab
… issues with launching browser.
| }); | ||
| app.UseStaticFiles(options); | ||
|
|
||
| var blazorEndpoint = endpoints.Map("/_framework/blazor.web.js", app.Build()) |
There was a problem hiding this comment.
How do we feel about this being just blazor.js and leaving the other more specialized flavors with a suffix.
| var blazorEndpoint = endpoints.Map("/_framework/blazor.web.js", app.Build()) | ||
| .WithDisplayName("Blazor web static files"); | ||
|
|
||
| blazorEndpoint.Add((builder) => ((RouteEndpointBuilder)builder).Order = int.MinValue); |
There was a problem hiding this comment.
Just -1 is ok here, FYI.
It's ok to give a way to override the endpoint as long as it doesn't happen by accident.
| return GetOrCreateDataSource<TRootComponent>(endpoints).DefaultBuilder; | ||
| } | ||
|
|
||
| private static void AddBlazorWebJsEndpoint(IEndpointRouteBuilder endpoints) |
There was a problem hiding this comment.
We should add these endpoints to the data source, but ideally, we just make these files static web assets, and they get placed on your project. (not asking to do anything, just pointing it out).
| var bufSizeRequired = count * Marshal.SizeOf<ComponentIdAndDepth>(); | ||
| var componentIdsInDepthOrder = bufSizeRequired < 1024 | ||
| ? MemoryMarshal.Cast<byte, ComponentIdAndDepth>(stackalloc byte[bufSizeRequired]) | ||
| : new ComponentIdAndDepth[count]; |
| for (var i = 0; i < count; i++) | ||
| { | ||
| var componentId = renderBatch.UpdatedComponents.Array[i].ComponentId; | ||
| componentIdsInDepthOrder[i] = new(componentId, GetComponentDepth(componentId)); |
There was a problem hiding this comment.
Is it worth keeping the depth inside the EndpointComponentState to avoid this look-up?
| function findStreamingMarkers(componentIdAsString: string): { startMarker: Comment, endMarker: Comment } | null { | ||
| // Find start marker | ||
| const expectedStartText = `bl:${componentIdAsString}`; | ||
| const iterator = document.createNodeIterator(document, NodeFilter.SHOW_COMMENT); | ||
| let startMarker: Comment | null = null; | ||
| while (startMarker = iterator.nextNode() as Comment | null) { | ||
| if (startMarker.textContent === expectedStartText) { | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| if (!startMarker) { | ||
| return null; | ||
| } | ||
|
|
||
| // Find end marker | ||
| const expectedEndText = `/bl:${componentIdAsString}`; | ||
| let endMarker: Comment | null = null; | ||
| while (endMarker = iterator.nextNode() as Comment | null) { | ||
| if (endMarker.textContent === expectedEndText) { | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| return endMarker ? { startMarker, endMarker } : null; | ||
| } |
There was a problem hiding this comment.
If this is inside a template, are there any reasons why we can't just wrap every update inside an element and just iterate over a flat list of children? (without needing to find marker comments)
|
|
||
| namespace Microsoft.AspNetCore.Components.E2ETests.ServerExecutionTests; | ||
|
|
||
| public class StreamingRenderingTest : ServerTestBase<BasicTestAppServerSiteFixture<RazorComponentEndpointsStartup>> |
There was a problem hiding this comment.
I think we have code to handle redirects, could we add an E2E test to make sure that works?
Make the streaming SSR really work and update the UI properly.
@MackinnonBuck If you get a chance to review this that would be super helpful! I'm sorry it's such a big PR - I'm trying to get it in before I'm off for a few days. Once again there's a lot of refactoring and nudging layers around within the new Endpoints code to make this fit in neatly.
Also quite a bit of new stuff here is just infrastructure for serving
blazor.web.jsand for a new E2E test app.The other major reason why there are so many changes here is this: since this involves setting up a whole new area of E2E tests, I fixed some longstanding quality-of-life issues for people working on the E2E tests here.
Components.TestServerby renaming its directory to match the project name.Components.TestServerso that, when you launch it manually, it uses deterministic port numbers instead of randomizing on every launch. Now you can just reload your existing browser tab :)M.A.C.WebAssembly.Authorization. Previously it was stuck always thinking that project needed to be rebuilt, causing a whole chain of extra projects to get rebuilt every time you tried to restart the E2E tests, even though those other projects hadn't changed.