@ecopages/core 0.2.0-alpha.25 → 0.2.0-alpha.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -7
- package/package.json +4 -47
- package/src/adapters/bun/create-app.ts +54 -2
- package/src/adapters/bun/hmr-manager.test.ts +0 -2
- package/src/adapters/bun/hmr-manager.ts +1 -24
- package/src/adapters/bun/server-adapter.ts +30 -4
- package/src/adapters/node/node-hmr-manager.test.ts +0 -2
- package/src/adapters/node/node-hmr-manager.ts +2 -25
- package/src/adapters/shared/explicit-static-render-preparation.ts +58 -0
- package/src/adapters/shared/explicit-static-route-matcher.test.ts +6 -6
- package/src/adapters/shared/explicit-static-route-matcher.ts +22 -31
- package/src/adapters/shared/file-route-middleware-pipeline.test.ts +5 -10
- package/src/adapters/shared/file-route-middleware-pipeline.ts +8 -17
- package/src/adapters/shared/fs-server-response-factory.test.ts +32 -43
- package/src/adapters/shared/fs-server-response-factory.ts +15 -37
- package/src/adapters/shared/fs-server-response-matcher.test.ts +65 -39
- package/src/adapters/shared/fs-server-response-matcher.ts +94 -43
- package/src/adapters/shared/hmr-manager.contract.test.ts +0 -4
- package/src/adapters/shared/render-context.ts +3 -3
- package/src/adapters/shared/server-adapter.test.ts +53 -0
- package/src/adapters/shared/server-adapter.ts +228 -159
- package/src/adapters/shared/server-route-handler.test.ts +6 -5
- package/src/adapters/shared/server-route-handler.ts +4 -4
- package/src/adapters/shared/server-static-builder.test.ts +4 -4
- package/src/adapters/shared/server-static-builder.ts +4 -4
- package/src/config/README.md +1 -1
- package/src/config/config-builder.test.ts +0 -1
- package/src/config/config-builder.ts +2 -7
- package/src/dev/host-runtime.ts +34 -0
- package/src/eco/eco.browser.test.ts +2 -2
- package/src/eco/eco.browser.ts +2 -2
- package/src/eco/eco.test.ts +6 -6
- package/src/eco/eco.ts +12 -12
- package/src/eco/eco.types.ts +3 -3
- package/src/errors/index.ts +1 -0
- package/src/hmr/client/hmr-runtime.ts +4 -2
- package/src/hmr/strategies/js-hmr-strategy.test.ts +0 -1
- package/src/hmr/strategies/js-hmr-strategy.ts +0 -6
- package/src/integrations/ghtml/ghtml-renderer.test.ts +7 -7
- package/src/integrations/ghtml/ghtml-renderer.ts +1 -11
- package/src/plugins/eco-component-meta-plugin.ts +0 -1
- package/src/plugins/integration-plugin.test.ts +9 -14
- package/src/plugins/integration-plugin.ts +34 -22
- package/src/plugins/processor.ts +17 -0
- package/src/route-renderer/GRAPH.md +81 -289
- package/src/route-renderer/README.md +67 -105
- package/src/route-renderer/orchestration/component-render-context.ts +45 -38
- package/src/route-renderer/orchestration/declared-ownership-graph.ts +62 -0
- package/src/route-renderer/orchestration/foreign-subtree-execution.service.ts +383 -0
- package/src/route-renderer/orchestration/integration-renderer.test.ts +118 -121
- package/src/route-renderer/orchestration/integration-renderer.ts +362 -403
- package/src/route-renderer/orchestration/ownership-planning.service.ts +97 -0
- package/src/route-renderer/orchestration/ownership-validation.service.ts +76 -0
- package/src/route-renderer/orchestration/processed-asset-dedupe.ts +1 -1
- package/src/route-renderer/orchestration/{queued-boundary-runtime.service.test.ts → queued-foreign-subtree-resolution.service.test.ts} +76 -71
- package/src/route-renderer/orchestration/{queued-boundary-runtime.service.ts → queued-foreign-subtree-resolution.service.ts} +68 -63
- package/src/route-renderer/orchestration/render-output.utils.ts +21 -13
- package/src/route-renderer/orchestration/{render-preparation.service.test.ts → route-render-orchestrator.prepare-render-options.test.ts} +160 -85
- package/src/route-renderer/orchestration/route-render-orchestrator.test.ts +265 -0
- package/src/route-renderer/orchestration/{render-preparation.service.ts → route-render-orchestrator.ts} +244 -160
- package/src/route-renderer/page-loading/component-dependency-collection.ts +9 -3
- package/src/route-renderer/page-loading/declared-asset-collection.ts +2 -5
- package/src/route-renderer/page-loading/dependency-resolver.test.ts +107 -11
- package/src/route-renderer/page-loading/dependency-resolver.ts +6 -12
- package/src/route-renderer/page-loading/ecopages-virtual-imports.ts +1 -1
- package/src/route-renderer/page-loading/lazy-entry-collection.ts +1 -1
- package/src/route-renderer/page-loading/lazy-trigger-planning.ts +1 -1
- package/src/route-renderer/page-loading/module-declaration-aggregation.ts +1 -1
- package/src/route-renderer/page-loading/module-declaration-scripts.ts +1 -1
- package/src/route-renderer/page-loading/page-dependency-bundling.ts +105 -66
- package/src/route-renderer/route-renderer.ts +28 -31
- package/src/router/README.md +16 -19
- package/src/router/server/route-registry.test.ts +176 -0
- package/src/router/server/route-registry.ts +382 -0
- package/src/services/README.md +1 -2
- package/src/services/assets/asset-processing-service/asset-dependency-keys.ts +1 -1
- package/src/services/assets/asset-processing-service/asset-processing.service.test.ts +1 -4
- package/src/services/assets/asset-processing-service/asset-processing.service.ts +1 -2
- package/src/services/assets/asset-processing-service/assets.types.ts +3 -0
- package/src/services/assets/asset-processing-service/grouped-content-bundles.ts +1 -1
- package/src/services/assets/asset-processing-service/index.ts +1 -0
- package/src/{route-renderer/orchestration/page-packaging.service.test.ts → services/assets/asset-processing-service/page-package.test.ts} +38 -14
- package/src/services/assets/asset-processing-service/page-package.ts +93 -0
- package/src/services/assets/asset-processing-service/processors/base/base-script-processor.ts +4 -5
- package/src/services/assets/asset-processing-service/processors/script/content-script.processor.test.ts +13 -10
- package/src/services/assets/asset-processing-service/processors/script/content-script.processor.ts +3 -0
- package/src/services/assets/asset-processing-service/processors/script/file-script.processor.ts +6 -0
- package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.ts +2 -0
- package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.ts +1 -0
- package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.ts +2 -0
- package/src/services/assets/asset-processing-service/ungrouped-dependency-processing.ts +1 -1
- package/src/services/html/html-transformer.service.test.ts +1 -4
- package/src/services/module-loading/app-server-module-transpiler.service.ts +1 -3
- package/src/services/module-loading/node-bootstrap-plugin.ts +17 -3
- package/src/services/module-loading/page-module-import.service.ts +0 -1
- package/src/services/module-loading/source-module-support.ts +1 -1
- package/src/static-site-generator/static-site-generator.test.ts +124 -32
- package/src/static-site-generator/static-site-generator.ts +168 -185
- package/src/types/internal-types.ts +13 -12
- package/src/types/public-types.ts +55 -39
- package/src/watchers/project-watcher.test-helpers.ts +4 -3
- package/src/route-renderer/orchestration/boundary-planning.service.ts +0 -146
- package/src/route-renderer/orchestration/page-packaging.service.ts +0 -85
- package/src/route-renderer/orchestration/render-execution.service.test.ts +0 -196
- package/src/route-renderer/orchestration/render-execution.service.ts +0 -182
- package/src/route-renderer/orchestration/route-shell-composer.service.ts +0 -162
- package/src/router/server/fs-router-scanner.test.ts +0 -83
- package/src/router/server/fs-router-scanner.ts +0 -224
- package/src/router/server/fs-router.test.ts +0 -214
- package/src/router/server/fs-router.ts +0 -122
- package/src/services/runtime-state/runtime-specifier-registry.service.ts +0 -96
|
@@ -1,38 +1,16 @@
|
|
|
1
1
|
# Rendering Logic Graph
|
|
2
2
|
|
|
3
|
-
This document maps the
|
|
3
|
+
This document maps the rendering logic in core using the ownership, foreign-child, and foreign-subtree model.
|
|
4
4
|
|
|
5
5
|
## Design Principles
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- Rendering entry points stay separate, but they converge on the same integration renderer contracts.
|
|
8
|
+
- Integration selection happens outside the renderer. Once selected, the integration renderer owns the render pipeline.
|
|
9
|
+
- Ownership is preparation-time metadata. Runtime handoff still happens inside renderer-owned foreign-child interception.
|
|
10
|
+
- Route-level fallback resolution is gone. Unresolved `<eco-marker>` artifacts are now a failure signal.
|
|
11
|
+
- Asset emission converges into one final HTML transformation step.
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
Request-time page rendering, explicit view rendering, and static generation all eventually depend on the same integration renderer behavior.
|
|
11
|
-
- **Integration choice should remain a boundary concern.**
|
|
12
|
-
Adapters and route matchers decide which renderer to use; once selected, the integration renderer owns the page render pipeline.
|
|
13
|
-
- **Data resolution should happen before HTML transformation.**
|
|
14
|
-
Static props, metadata, dependency processing, and route assets are all upstream of final HTML injection.
|
|
15
|
-
- **Deferred boundary orchestration should stay renderer-owned.**
|
|
16
|
-
The initial integration render is responsible for handing foreign boundaries back to their owning renderer before final route HTML is returned.
|
|
17
|
-
- **Foreign boundary ownership is renderer-defined behavior.**
|
|
18
|
-
If a renderer cannot resolve a foreign boundary inside its own runtime, route execution now treats any leftover unresolved boundary artifact HTML as an error instead of attempting any route-level fallback.
|
|
19
|
-
- **Caching policy is authoritative at the page layer.**
|
|
20
|
-
Middleware, locals, and response reuse all depend on the effective page cache strategy.
|
|
21
|
-
- **Asset emission should converge into one injection stage.**
|
|
22
|
-
Route-level assets, integration assets, page-root component assets, and renderer-owned boundary assets all end up in the HTML transformer.
|
|
23
|
-
|
|
24
|
-
## Entry Points
|
|
25
|
-
|
|
26
|
-
There are three main rendering entry points:
|
|
27
|
-
|
|
28
|
-
1. **Runtime request rendering**
|
|
29
|
-
- handled through the server adapters and file-system route matching
|
|
30
|
-
2. **Explicit rendering APIs**
|
|
31
|
-
- handled through `renderToResponse()` and route-handler render context helpers
|
|
32
|
-
3. **Static site generation**
|
|
33
|
-
- handled through explicit route generation and route renderer reuse at build time
|
|
34
|
-
|
|
35
|
-
## 1) Runtime Request Flow (Bun and Node)
|
|
13
|
+
## 1) Runtime Request Flow
|
|
36
14
|
|
|
37
15
|
```mermaid
|
|
38
16
|
flowchart TD
|
|
@@ -51,303 +29,117 @@ flowchart TD
|
|
|
51
29
|
K --> L[RouteRenderer createRoute]
|
|
52
30
|
L --> M[IntegrationRenderer execute]
|
|
53
31
|
M --> N[response body and cache strategy]
|
|
54
|
-
|
|
55
|
-
J --> O{Static asset request?}
|
|
56
|
-
O -- Yes --> P[FileSystemServerResponseFactory createFileResponse]
|
|
57
|
-
O -- No --> Q[FileSystemServerResponseFactory createCustomNotFoundResponse]
|
|
58
|
-
Q --> R[routeRendererFactory createRenderer for 404 template]
|
|
59
|
-
R --> S[RouteRenderer createRoute]
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
## 2) FS Route Rendering + Middleware + Cache
|
|
63
|
-
|
|
64
|
-
This is the most operationally important runtime path because it is where middleware, locals, and cache behavior are coordinated.
|
|
65
|
-
|
|
66
|
-
```mermaid
|
|
67
|
-
flowchart TD
|
|
68
|
-
A[FileSystemResponseMatcher handleMatch] --> B[PageModuleImportService importModule]
|
|
69
|
-
B --> C[read Page cache and Page middleware]
|
|
70
|
-
C --> D[FileRouteMiddlewarePipeline assertValidConfiguration]
|
|
71
|
-
D --> E{Middleware exists?}
|
|
72
|
-
|
|
73
|
-
E -- Yes --> F{cache dynamic?}
|
|
74
|
-
F -- No --> G[throw LocalsAccessError]
|
|
75
|
-
F -- Yes --> H[FileRouteMiddlewarePipeline createContext]
|
|
76
|
-
H --> I[FileRouteMiddlewarePipeline run]
|
|
77
|
-
|
|
78
|
-
E -- No --> J[renderResponse]
|
|
79
|
-
I --> J
|
|
80
|
-
|
|
81
|
-
J --> K[PageRequestCacheCoordinator render]
|
|
82
|
-
K --> L{cache disabled OR dynamic page?}
|
|
83
|
-
L -- Yes --> M[renderFn directly]
|
|
84
|
-
L -- No --> N[PageCacheService getOrCreate]
|
|
85
|
-
|
|
86
|
-
M --> O[routeRenderer createRoute]
|
|
87
|
-
N --> O
|
|
88
|
-
O --> P[PageRequestCacheCoordinator bodyToString]
|
|
89
|
-
P --> Q[html and strategy]
|
|
90
|
-
Q --> R[createCachedResponse with cache headers]
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
## 3) RouteRendererFactory Selection Logic
|
|
94
|
-
|
|
95
|
-
This is a small but important boundary. It centralizes integration selection and renderer reuse, which helps keep adapter code thin.
|
|
96
|
-
|
|
97
|
-
```mermaid
|
|
98
|
-
flowchart TD
|
|
99
|
-
A[createRenderer filePath] --> B[getRouteRendererEngine filePath]
|
|
100
|
-
B --> C[getIntegrationPlugin by template extension]
|
|
101
|
-
C --> D{renderer cached by integration name?}
|
|
102
|
-
D -- Yes --> E[Reuse renderer]
|
|
103
|
-
D -- No --> F[integrationPlugin.initializeRenderer]
|
|
104
|
-
F --> G[Cache renderer]
|
|
105
|
-
E --> H[RouteRenderer]
|
|
106
|
-
G --> H
|
|
107
|
-
|
|
108
|
-
I[getRendererByIntegration integrationName] --> J{plugin exists?}
|
|
109
|
-
J -- No --> K[return null]
|
|
110
|
-
J -- Yes --> L{renderer cached?}
|
|
111
|
-
L -- Yes --> M[Reuse renderer]
|
|
112
|
-
L -- No --> N[initializeRenderer + cache]
|
|
113
32
|
```
|
|
114
33
|
|
|
115
|
-
##
|
|
34
|
+
## 2) Route Render Flow
|
|
116
35
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
### 4.1 Render preparation via `RenderPreparationService`
|
|
36
|
+
`IntegrationRenderer.execute()` delegates shared route orchestration to `RouteRenderFlow`.
|
|
120
37
|
|
|
121
38
|
```mermaid
|
|
122
39
|
flowchart TD
|
|
123
|
-
A[IntegrationRenderer
|
|
40
|
+
A[IntegrationRenderer.execute] --> B[RouteRenderFlow.prepareRenderOptions]
|
|
124
41
|
B --> C[resolvePageModule]
|
|
125
|
-
C --> D[
|
|
126
|
-
D --> E[
|
|
127
|
-
E --> F
|
|
128
|
-
F
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
I -->
|
|
133
|
-
J -->
|
|
134
|
-
K
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
```mermaid
|
|
147
|
-
flowchart TD
|
|
148
|
-
A[IntegrationRenderer execute] --> B[RenderExecutionService execute]
|
|
149
|
-
B --> C[prepareRenderOptions]
|
|
150
|
-
C --> D[runWithComponentRenderContext then render]
|
|
151
|
-
D --> E[normalize response body to renderedHtml]
|
|
152
|
-
E --> F{contains unresolved boundary artifact html?}
|
|
153
|
-
F -- Yes --> G[throw unresolved boundary error]
|
|
154
|
-
F -- No --> H{root attributes attachable?}
|
|
155
|
-
H -- Yes --> I[HtmlTransformerService applyAttributesToFirstBodyElement]
|
|
156
|
-
H -- No --> J[leave html unchanged]
|
|
157
|
-
I --> K[htmlTransformer transform]
|
|
158
|
-
J --> K
|
|
159
|
-
K --> L[return body stream and cache strategy]
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### 4.3 Render preparation responsibilities
|
|
163
|
-
|
|
164
|
-
```mermaid
|
|
165
|
-
flowchart LR
|
|
166
|
-
A[Page module loader] --> B[static props]
|
|
167
|
-
B --> C[metadata]
|
|
168
|
-
C --> D[page props and locals]
|
|
169
|
-
|
|
170
|
-
E[dependency resolver] --> F[component assets]
|
|
171
|
-
F --> G[integration assets]
|
|
172
|
-
G --> H[route assets]
|
|
173
|
-
H --> I[global injector assets]
|
|
174
|
-
|
|
175
|
-
D --> J[prepared render options]
|
|
176
|
-
I --> J
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
### 4.4 Service boundary map
|
|
180
|
-
|
|
181
|
-
```mermaid
|
|
182
|
-
flowchart LR
|
|
183
|
-
A[IntegrationRenderer] --> B[RenderPreparationService]
|
|
184
|
-
A --> C[RenderExecutionService]
|
|
185
|
-
A --> D[QueuedBoundaryRuntimeService]
|
|
186
|
-
A --> F[PageModuleLoaderService]
|
|
187
|
-
A --> G[DependencyResolverService]
|
|
188
|
-
A --> H[HtmlTransformerService]
|
|
189
|
-
|
|
190
|
-
B --> F
|
|
191
|
-
B --> G
|
|
192
|
-
B --> H
|
|
193
|
-
C --> H
|
|
194
|
-
D --> H
|
|
42
|
+
C --> D[ownershipValidationService.validate]
|
|
43
|
+
D --> E[resolvePageData]
|
|
44
|
+
E --> F[ownershipPlanningService.buildPlan]
|
|
45
|
+
F --> G[resolveDependencies]
|
|
46
|
+
G --> H[buildPageBrowserGraph]
|
|
47
|
+
H --> I{shouldRenderPageComponent?}
|
|
48
|
+
I -- Yes --> J[renderPageComponent]
|
|
49
|
+
I -- No --> K[skip page-root render]
|
|
50
|
+
J --> L[merge component assets]
|
|
51
|
+
K --> L
|
|
52
|
+
L --> M[collect injector and eager SSR lazy assets]
|
|
53
|
+
M --> N[build pagePackage and prepared render options]
|
|
54
|
+
N --> O[callbacks.render]
|
|
55
|
+
O --> P[capture rendered body as html]
|
|
56
|
+
P --> Q[inspect unresolved marker artifacts]
|
|
57
|
+
Q --> R{unresolved eco-marker remains?}
|
|
58
|
+
R -- Yes --> S[throw unresolved artifact error]
|
|
59
|
+
R -- No --> T[stamp root or document attributes when needed]
|
|
60
|
+
T --> U[htmlTransformer transform]
|
|
61
|
+
U --> V[final body and cache strategy]
|
|
195
62
|
```
|
|
196
63
|
|
|
197
|
-
##
|
|
198
|
-
|
|
199
|
-
This part is architecturally interesting because boundaries can still emit temporary transport tokens, but renderer-owned runtimes are now responsible for resolving foreign descendants before final route HTML is returned.
|
|
200
|
-
|
|
201
|
-
If this feels complex, the simplest mental model is:
|
|
202
|
-
|
|
203
|
-
- first pass: render everything that can be rendered safely right now
|
|
204
|
-
- when a renderer supports mixed boundaries, hand foreign descendants back to the owning renderer inside that renderer's runtime
|
|
205
|
-
- if literal `<eco-marker>` boundary artifact HTML survives to route finalization, treat it as a failure instead of attempting any route-level fallback
|
|
206
|
-
- final pass: merge emitted assets and perform the normal HTML transformation
|
|
207
|
-
|
|
208
|
-
In the current implementation, renderer-owned runtimes use internal boundary tokens for queued nested handoff. Literal `<eco-marker>` markup remains only as a route-level failure signal when unresolved boundary artifacts escape renderer-owned resolution.
|
|
209
|
-
|
|
210
|
-
Important clarification: not every integration automatically goes through this stage. Boundary queueing is conditional.
|
|
211
|
-
|
|
212
|
-
- If a render pass stays inside one integration, rendering continues directly to post-processing and HTML transformation.
|
|
213
|
-
- If a renderer can resolve foreign descendants inline, the boundary runtime returns resolved HTML immediately.
|
|
214
|
-
- If a renderer needs token-based nested handoff, it queues renderer-owned transport tokens and resolves them before returning final HTML.
|
|
215
|
-
|
|
216
|
-
### Why this exists
|
|
217
|
-
|
|
218
|
-
Renderer-owned boundary queueing exists because some component boundaries cannot always be rendered eagerly inside the current integration pass.
|
|
64
|
+
## 3) Mixed-Integration Render Model
|
|
219
65
|
|
|
220
|
-
|
|
66
|
+
The renderer-level mental model is:
|
|
221
67
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
- the child render may emit its own assets or root attributes that must be merged back into the final document
|
|
226
|
-
|
|
227
|
-
So the first pass either returns resolved renderer-owned output immediately or emits a renderer-local transport token that is resolved before the enclosing renderer returns its final HTML.
|
|
228
|
-
|
|
229
|
-
Another way to say it:
|
|
230
|
-
|
|
231
|
-
- a boundary token says "this subtree belongs to another renderer, but the current renderer still owns the overall render pass"
|
|
232
|
-
- the token stores just enough information to make that later renderer-owned handoff deterministic
|
|
233
|
-
- the queue exists so nested foreign boundaries resolve from leaves to parents while preserving child insertion order and emitted assets
|
|
234
|
-
|
|
235
|
-
### 5.1 Boundary interception in `eco.component` factory
|
|
236
|
-
|
|
237
|
-
The key rule here today is: boundaries are resolved by the owning renderer, not by a shared core fallback. During an active component render pass, `eco.component` asks the current render boundary context whether the next boundary should render inline or be resolved by a foreign renderer runtime.
|
|
238
|
-
|
|
239
|
-
For the current built-in integrations, this is how non-owning renderers hand foreign subtrees back to the owning runtime without relying on a shared core fallback.
|
|
68
|
+
1. declared dependencies describe ownership
|
|
69
|
+
2. active render context intercepts foreign children
|
|
70
|
+
3. the owning renderer returns a foreign subtree
|
|
240
71
|
|
|
241
72
|
```mermaid
|
|
242
73
|
flowchart TD
|
|
243
|
-
A[eco
|
|
244
|
-
B --> C[
|
|
245
|
-
C --> D{
|
|
246
|
-
D --
|
|
247
|
-
D --
|
|
74
|
+
A[eco.component render] --> B[getComponentRenderContext]
|
|
75
|
+
B --> C[foreignChildRuntime interceptForeignChildSync]
|
|
76
|
+
C --> D{same integration?}
|
|
77
|
+
D -- Yes --> E[render inline]
|
|
78
|
+
D -- No --> F[delegate to owning renderer]
|
|
79
|
+
F --> G[owning renderer renderComponentWithForeignChildren]
|
|
80
|
+
G --> H[owning renderer renderForeignSubtree when payload form is needed]
|
|
81
|
+
H --> I[resolved html plus assets and attachment policy]
|
|
248
82
|
```
|
|
249
83
|
|
|
250
|
-
|
|
84
|
+
## 4) Queued Foreign-Subtree Resolution
|
|
251
85
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
This means boundary tokens are no longer a general component-boundary contract. Core only resolves queued boundary payloads that already belong to a renderer-owned string boundary workflow.
|
|
86
|
+
Some renderers cannot hand off foreign children inline. Those renderers can use the queue service during one render pass.
|
|
255
87
|
|
|
256
88
|
```mermaid
|
|
257
89
|
flowchart TD
|
|
258
|
-
A[
|
|
259
|
-
B --> C[
|
|
260
|
-
|
|
261
|
-
D --> E[
|
|
262
|
-
E --> F[
|
|
263
|
-
F --> G[
|
|
264
|
-
G --> H[
|
|
265
|
-
H --> I[
|
|
90
|
+
A[current renderer encounters foreign child] --> B{can resolve inline?}
|
|
91
|
+
B -- Yes --> C[return resolved renderer-owned output]
|
|
92
|
+
B -- No --> D[queue foreign-subtree token]
|
|
93
|
+
D --> E[finish current render pass]
|
|
94
|
+
E --> F[QueuedForeignSubtreeResolutionService resolveQueuedHtml]
|
|
95
|
+
F --> G[resolve nested queued tokens first]
|
|
96
|
+
G --> H[dispatch foreign subtree to owning renderer]
|
|
97
|
+
H --> I[merge emitted assets and root attributes]
|
|
98
|
+
I --> J[replace token in html]
|
|
266
99
|
```
|
|
267
100
|
|
|
268
|
-
##
|
|
101
|
+
## 5) Explicit Rendering Paths
|
|
269
102
|
|
|
270
|
-
These paths
|
|
103
|
+
These paths bypass most filesystem routing, but they still converge on the same renderer contracts.
|
|
271
104
|
|
|
272
105
|
```mermaid
|
|
273
106
|
flowchart TD
|
|
274
107
|
A[ExplicitStaticRouteMatcher handleMatch] --> B[route loader returns view]
|
|
275
|
-
B --> C[
|
|
276
|
-
C --> D[
|
|
277
|
-
D --> E[optional view.staticProps]
|
|
278
|
-
E --> F[renderer renderToResponse]
|
|
279
|
-
|
|
280
|
-
G[createRenderContext render or renderPartial] --> H[get renderer from integrations list]
|
|
281
|
-
H --> I[merge props + locals]
|
|
282
|
-
I --> J[renderer renderToResponse]
|
|
283
|
-
|
|
284
|
-
K[StaticSiteGenerator explicit routes] --> L[getRendererByIntegration]
|
|
285
|
-
L --> M[optional staticPaths and staticProps]
|
|
286
|
-
M --> N[renderer renderToResponse]
|
|
287
|
-
N --> O[write html to dist]
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
## 7) Current Concrete Integration in core
|
|
108
|
+
B --> C[get renderer by integration]
|
|
109
|
+
C --> D[renderer renderToResponse]
|
|
291
110
|
|
|
292
|
-
|
|
111
|
+
E[render context render or renderPartial] --> F[get renderer from integrations list]
|
|
112
|
+
F --> G[renderer renderToResponse]
|
|
293
113
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
B --> C{Layout exists?}
|
|
298
|
-
C -- Yes --> D[Layout wraps page content]
|
|
299
|
-
C -- No --> E[use page content]
|
|
300
|
-
D --> F[HtmlTemplate metadata + children + pageProps]
|
|
301
|
-
E --> F
|
|
302
|
-
F --> G[prepend DOCTYPE]
|
|
303
|
-
|
|
304
|
-
H[GhtmlRenderer renderToResponse] --> I{partial?}
|
|
305
|
-
I -- Yes --> J[return component html only]
|
|
306
|
-
I -- No --> K[resolve Layout and HtmlTemplate and metadata]
|
|
307
|
-
K --> L[prepend DOCTYPE]
|
|
308
|
-
J --> M[createHtmlResponse]
|
|
309
|
-
L --> M
|
|
114
|
+
H[StaticSiteGenerator explicit routes] --> I[get renderer by integration]
|
|
115
|
+
I --> J[renderer renderToResponse]
|
|
116
|
+
J --> K[write html to dist]
|
|
310
117
|
```
|
|
311
118
|
|
|
312
|
-
##
|
|
119
|
+
## 6) Reading Order
|
|
313
120
|
|
|
314
|
-
|
|
121
|
+
The most useful reading order is:
|
|
315
122
|
|
|
316
|
-
1. `
|
|
317
|
-
2. `
|
|
318
|
-
3. `
|
|
319
|
-
4. `
|
|
320
|
-
5. `
|
|
321
|
-
6. `
|
|
322
|
-
7. `
|
|
323
|
-
8. `
|
|
324
|
-
9. `
|
|
325
|
-
10. `
|
|
326
|
-
11. `page-module-loader.ts`
|
|
327
|
-
12. `dependency-resolver.ts`
|
|
328
|
-
13. `eco.ts`
|
|
329
|
-
14. `component-render-context.ts`
|
|
123
|
+
1. `route-renderer.ts`
|
|
124
|
+
2. `orchestration/route-render-flow.ts`
|
|
125
|
+
3. `orchestration/integration-renderer.ts`
|
|
126
|
+
4. `orchestration/ownership-validation.service.ts`
|
|
127
|
+
5. `orchestration/ownership-planning.service.ts`
|
|
128
|
+
6. `orchestration/component-render-context.ts`
|
|
129
|
+
7. `orchestration/queued-foreign-subtree-resolution.service.ts`
|
|
130
|
+
8. `page-loading/page-module-loader.ts`
|
|
131
|
+
9. `page-loading/dependency-resolver.ts`
|
|
132
|
+
10. `eco/eco.ts`
|
|
330
133
|
|
|
331
|
-
##
|
|
134
|
+
## 7) Key Files
|
|
332
135
|
|
|
333
|
-
- `packages/core/src/adapters/shared/server-adapter.ts`
|
|
334
|
-
- `packages/core/src/adapters/shared/server-route-handler.ts`
|
|
335
|
-
- `packages/core/src/adapters/shared/fs-server-response-matcher.ts`
|
|
336
|
-
- `packages/core/src/adapters/shared/file-route-middleware-pipeline.ts`
|
|
337
|
-
- `packages/core/src/adapters/shared/fs-server-response-factory.ts`
|
|
338
|
-
- `packages/core/src/adapters/shared/explicit-static-route-matcher.ts`
|
|
339
|
-
- `packages/core/src/adapters/shared/render-context.ts`
|
|
340
136
|
- `packages/core/src/route-renderer/route-renderer.ts`
|
|
137
|
+
- `packages/core/src/route-renderer/orchestration/route-render-flow.ts`
|
|
341
138
|
- `packages/core/src/route-renderer/orchestration/integration-renderer.ts`
|
|
342
|
-
- `packages/core/src/route-renderer/orchestration/
|
|
343
|
-
- `packages/core/src/route-renderer/orchestration/
|
|
344
|
-
- `packages/core/src/route-renderer/orchestration/
|
|
139
|
+
- `packages/core/src/route-renderer/orchestration/ownership-validation.service.ts`
|
|
140
|
+
- `packages/core/src/route-renderer/orchestration/ownership-planning.service.ts`
|
|
141
|
+
- `packages/core/src/route-renderer/orchestration/component-render-context.ts`
|
|
142
|
+
- `packages/core/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.ts`
|
|
345
143
|
- `packages/core/src/route-renderer/page-loading/page-module-loader.ts`
|
|
346
144
|
- `packages/core/src/route-renderer/page-loading/dependency-resolver.ts`
|
|
347
|
-
- `packages/core/src/services/module-loading/page-module-import.service.ts`
|
|
348
|
-
- `packages/core/src/services/cache/page-request-cache-coordinator.service.ts`
|
|
349
|
-
- `packages/core/src/eco/component-render-context.ts`
|
|
350
145
|
- `packages/core/src/eco/eco.ts`
|
|
351
|
-
- `packages/core/src/services/html-transformer.service.ts`
|
|
352
|
-
- `packages/core/src/services/cache/page-cache-service.ts`
|
|
353
|
-
- `packages/core/src/integrations/ghtml/ghtml-renderer.ts`
|