@ecopages/core 0.2.0-beta.27 → 0.2.0-beta.28
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 +1 -1
- package/package.json +42 -26
- package/src/eco/eco.js +2 -2
- package/src/eco/eco.utils.d.ts +1 -1
- package/src/eco/eco.utils.js +1 -1
- package/src/hmr/client/hmr-runtime.js +1 -1
- package/src/hmr/hmr-file-change-prep.d.ts +1 -1
- package/src/hmr/hmr-file-change-prep.js +1 -1
- package/src/plugins/processor.d.ts +8 -0
- package/src/route-renderer/GRAPH.md +11 -11
- package/src/route-renderer/README.md +11 -6
- package/src/route-renderer/orchestration/{document-shell-render.service.d.ts → document-shell/document-shell-render.service.d.ts} +19 -2
- package/src/route-renderer/orchestration/{document-shell-render.service.js → document-shell/document-shell-render.service.js} +28 -0
- package/src/route-renderer/orchestration/{layout-shell-props.service.d.ts → document-shell/layout-shell-props.service.d.ts} +1 -1
- package/src/route-renderer/orchestration/{component-render-context.d.ts → foreign-child/component-render-context.d.ts} +1 -1
- package/src/route-renderer/orchestration/{component-render-context.js → foreign-child/component-render-context.js} +1 -1
- package/src/route-renderer/orchestration/{render-output.utils.d.ts → foreign-child/foreign-child-output.utils.d.ts} +1 -7
- package/src/route-renderer/orchestration/{render-output.utils.js → foreign-child/foreign-child-output.utils.js} +1 -26
- package/src/route-renderer/orchestration/{foreign-subtree-execution.service.d.ts → foreign-child/foreign-subtree-execution.service.d.ts} +5 -5
- package/src/route-renderer/orchestration/{foreign-subtree-execution.service.js → foreign-child/foreign-subtree-execution.service.js} +2 -2
- package/src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.d.ts +19 -0
- package/src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.js +35 -0
- package/src/route-renderer/orchestration/integration-renderer.d.ts +4 -46
- package/src/route-renderer/orchestration/integration-renderer.js +53 -157
- package/src/route-renderer/orchestration/integration-renderer.test-fixtures.d.ts +75 -0
- package/src/route-renderer/orchestration/integration-renderer.test-fixtures.js +177 -0
- package/src/route-renderer/orchestration/{component-graph-collectors.d.ts → ownership-graph/component-graph-collectors.d.ts} +4 -4
- package/src/route-renderer/orchestration/{component-graph-collectors.js → ownership-graph/component-graph-collectors.js} +1 -1
- package/src/route-renderer/orchestration/{component-graph.d.ts → ownership-graph/component-graph.d.ts} +1 -3
- package/src/route-renderer/orchestration/{component-graph.js → ownership-graph/component-graph.js} +0 -2
- package/src/route-renderer/orchestration/{ownership-validation.service.d.ts → ownership-graph/ownership-validation.service.d.ts} +2 -2
- package/src/route-renderer/orchestration/{ownership-validation.service.js → ownership-graph/ownership-validation.service.js} +3 -4
- package/src/route-renderer/orchestration/{global-injector-assets.service.d.ts → page-browser-graph/global-injector-assets.service.d.ts} +3 -3
- package/src/route-renderer/orchestration/{global-injector-assets.service.js → page-browser-graph/global-injector-assets.service.js} +2 -2
- package/src/route-renderer/orchestration/{page-browser-graph-contribution.loader.d.ts → page-browser-graph/page-browser-graph-contribution.loader.d.ts} +1 -1
- package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.d.ts +12 -0
- package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.js +29 -0
- package/src/route-renderer/orchestration/{page-browser-graph-session.d.ts → page-browser-graph/page-browser-graph-session.d.ts} +3 -3
- package/src/route-renderer/orchestration/{page-browser-graph-session.js → page-browser-graph/page-browser-graph-session.js} +1 -1
- package/src/route-renderer/orchestration/{page-browser-graph.service.d.ts → page-browser-graph/page-browser-graph.service.d.ts} +3 -3
- package/src/route-renderer/orchestration/{page-browser-graph.service.js → page-browser-graph/page-browser-graph.service.js} +3 -3
- package/src/route-renderer/orchestration/{processed-asset-dedupe.d.ts → page-browser-graph/processed-asset-dedupe.d.ts} +1 -1
- package/src/route-renderer/orchestration/{integration-route-render-adapter.d.ts → route-pipeline/integration-route-render-adapter.d.ts} +3 -3
- package/src/route-renderer/orchestration/{integration-route-render-adapter.js → route-pipeline/integration-route-render-adapter.js} +1 -1
- package/src/route-renderer/orchestration/route-pipeline/marker-artifact.utils.d.ts +6 -0
- package/src/route-renderer/orchestration/route-pipeline/marker-artifact.utils.js +27 -0
- package/src/route-renderer/orchestration/{route-html-finalization.service.d.ts → route-pipeline/route-html-finalization.service.d.ts} +2 -2
- package/src/route-renderer/orchestration/{route-prepared-options.builder.d.ts → route-pipeline/route-prepared-options.builder.d.ts} +3 -3
- package/src/route-renderer/orchestration/{route-prepared-options.builder.js → route-pipeline/route-prepared-options.builder.js} +2 -2
- package/src/route-renderer/orchestration/{route-prepared-options.utils.js → route-pipeline/route-prepared-options.utils.js} +1 -1
- package/src/route-renderer/orchestration/{route-render-orchestrator.d.ts → route-pipeline/route-render-orchestrator.d.ts} +6 -6
- package/src/route-renderer/orchestration/{route-render-orchestrator.js → route-pipeline/route-render-orchestrator.js} +8 -5
- package/src/route-renderer/orchestration/string-markup-renderer.js +1 -1
- package/src/services/html/html-transformer.service.js +1 -1
- package/src/services/invalidation/development-invalidation.service.d.ts +5 -0
- package/src/services/invalidation/development-invalidation.service.js +8 -9
- package/src/static-site-generator/production-page-browser-graph-prebuild.js +1 -1
- package/src/types/internal-types.d.ts +1 -1
- package/src/types/public-types.d.ts +1 -1
- package/src/watchers/project-watcher.d.ts +3 -3
- package/src/watchers/project-watcher.js +4 -4
- package/src/route-renderer/orchestration/declared-ownership-graph.d.ts +0 -1
- package/src/route-renderer/orchestration/declared-ownership-graph.js +0 -8
- package/src/route-renderer/orchestration/template-serialization.d.ts +0 -38
- package/src/route-renderer/orchestration/template-serialization.js +0 -45
- /package/src/route-renderer/orchestration/{layout-shell-props.service.js → document-shell/layout-shell-props.service.js} +0 -0
- /package/src/route-renderer/orchestration/{page-browser-graph-contribution.loader.js → page-browser-graph/page-browser-graph-contribution.loader.js} +0 -0
- /package/src/route-renderer/orchestration/{processed-asset-dedupe.js → page-browser-graph/processed-asset-dedupe.js} +0 -0
- /package/src/route-renderer/orchestration/{route-html-finalization.service.js → route-pipeline/route-html-finalization.service.js} +0 -0
- /package/src/route-renderer/orchestration/{route-prepared-options.utils.d.ts → route-pipeline/route-prepared-options.utils.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -267,7 +267,7 @@ Use these entrypoints when implementing integrations, processors, or source tran
|
|
|
267
267
|
- `@ecopages/core/plugins/integration-plugin`
|
|
268
268
|
- `@ecopages/core/plugins/processor`
|
|
269
269
|
- `@ecopages/core/plugins/source-transform`
|
|
270
|
-
- `@ecopages/core/route-renderer/integration-renderer`
|
|
270
|
+
- `@ecopages/core/route-renderer/orchestration/integration-renderer`
|
|
271
271
|
- `@ecopages/core/services/asset-processing-service`
|
|
272
272
|
- `@ecopages/core/hmr/hmr-strategy`
|
|
273
273
|
- `@ecopages/core/integrations/ghtml`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ecopages/core",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.28",
|
|
4
4
|
"description": "Core package for Ecopages",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ecopages",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"directory": "packages/core"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@ecopages/file-system": "0.2.0-beta.
|
|
20
|
+
"@ecopages/file-system": "0.2.0-beta.28",
|
|
21
21
|
"@ecopages/logger": "^0.2.3",
|
|
22
22
|
"@ecopages/scripts-injector": "^0.1.5",
|
|
23
23
|
"@oxc-project/runtime": "0.134.0",
|
|
@@ -44,11 +44,11 @@
|
|
|
44
44
|
"types": "./src/adapters/create-app.d.ts",
|
|
45
45
|
"default": "./src/adapters/create-app.js"
|
|
46
46
|
},
|
|
47
|
-
"./route-renderer/integration-renderer": {
|
|
47
|
+
"./route-renderer/orchestration/integration-renderer": {
|
|
48
48
|
"types": "./src/route-renderer/orchestration/integration-renderer.d.ts",
|
|
49
49
|
"default": "./src/route-renderer/orchestration/integration-renderer.js"
|
|
50
50
|
},
|
|
51
|
-
"./route-renderer/string-markup-renderer": {
|
|
51
|
+
"./route-renderer/orchestration/string-markup-renderer": {
|
|
52
52
|
"types": "./src/route-renderer/orchestration/string-markup-renderer.d.ts",
|
|
53
53
|
"default": "./src/route-renderer/orchestration/string-markup-renderer.js"
|
|
54
54
|
},
|
|
@@ -56,18 +56,26 @@
|
|
|
56
56
|
"types": "./src/route-renderer/route-renderer.d.ts",
|
|
57
57
|
"default": "./src/route-renderer/route-renderer.js"
|
|
58
58
|
},
|
|
59
|
-
"./route-renderer/component-render-context": {
|
|
60
|
-
"import": "./src/route-renderer/orchestration/component-render-context.js",
|
|
61
|
-
"types": "./src/route-renderer/orchestration/component-render-context.d.ts",
|
|
62
|
-
"default": "./src/route-renderer/orchestration/component-render-context.js"
|
|
59
|
+
"./route-renderer/orchestration/foreign-child/component-render-context": {
|
|
60
|
+
"import": "./src/route-renderer/orchestration/foreign-child/component-render-context.js",
|
|
61
|
+
"types": "./src/route-renderer/orchestration/foreign-child/component-render-context.d.ts",
|
|
62
|
+
"default": "./src/route-renderer/orchestration/foreign-child/component-render-context.js"
|
|
63
63
|
},
|
|
64
|
-
"./route-renderer/orchestration/foreign-subtree-execution.service": {
|
|
65
|
-
"types": "./src/route-renderer/orchestration/foreign-subtree-execution.service.d.ts",
|
|
66
|
-
"default": "./src/route-renderer/orchestration/foreign-subtree-execution.service.js"
|
|
64
|
+
"./route-renderer/orchestration/foreign-child/foreign-subtree-execution.service": {
|
|
65
|
+
"types": "./src/route-renderer/orchestration/foreign-child/foreign-subtree-execution.service.d.ts",
|
|
66
|
+
"default": "./src/route-renderer/orchestration/foreign-child/foreign-subtree-execution.service.js"
|
|
67
67
|
},
|
|
68
|
-
"./route-renderer/orchestration/document-shell-render.service": {
|
|
69
|
-
"types": "./src/route-renderer/orchestration/document-shell-render.service.d.ts",
|
|
70
|
-
"default": "./src/route-renderer/orchestration/document-shell-render.service.js"
|
|
68
|
+
"./route-renderer/orchestration/document-shell/document-shell-render.service": {
|
|
69
|
+
"types": "./src/route-renderer/orchestration/document-shell/document-shell-render.service.d.ts",
|
|
70
|
+
"default": "./src/route-renderer/orchestration/document-shell/document-shell-render.service.js"
|
|
71
|
+
},
|
|
72
|
+
"./route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils": {
|
|
73
|
+
"types": "./src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.d.ts",
|
|
74
|
+
"default": "./src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.js"
|
|
75
|
+
},
|
|
76
|
+
"./route-renderer/orchestration/foreign-child/owning-renderer-resolution": {
|
|
77
|
+
"types": "./src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.d.ts",
|
|
78
|
+
"default": "./src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.js"
|
|
71
79
|
},
|
|
72
80
|
"./router/navigation-coordinator": {
|
|
73
81
|
"types": "./src/router/client/navigation-coordinator.d.ts",
|
|
@@ -269,11 +277,11 @@
|
|
|
269
277
|
"types": "./src/adapters/create-app.d.ts",
|
|
270
278
|
"default": "./src/adapters/create-app.js"
|
|
271
279
|
},
|
|
272
|
-
"./route-renderer/integration-renderer.ts": {
|
|
280
|
+
"./route-renderer/orchestration/integration-renderer.ts": {
|
|
273
281
|
"types": "./src/route-renderer/orchestration/integration-renderer.d.ts",
|
|
274
282
|
"default": "./src/route-renderer/orchestration/integration-renderer.js"
|
|
275
283
|
},
|
|
276
|
-
"./route-renderer/string-markup-renderer.ts": {
|
|
284
|
+
"./route-renderer/orchestration/string-markup-renderer.ts": {
|
|
277
285
|
"types": "./src/route-renderer/orchestration/string-markup-renderer.d.ts",
|
|
278
286
|
"default": "./src/route-renderer/orchestration/string-markup-renderer.js"
|
|
279
287
|
},
|
|
@@ -281,18 +289,26 @@
|
|
|
281
289
|
"types": "./src/route-renderer/route-renderer.d.ts",
|
|
282
290
|
"default": "./src/route-renderer/route-renderer.js"
|
|
283
291
|
},
|
|
284
|
-
"./route-renderer/component-render-context.ts": {
|
|
285
|
-
"import": "./src/route-renderer/orchestration/component-render-context.js",
|
|
286
|
-
"types": "./src/route-renderer/orchestration/component-render-context.d.ts",
|
|
287
|
-
"default": "./src/route-renderer/orchestration/component-render-context.js"
|
|
292
|
+
"./route-renderer/orchestration/foreign-child/component-render-context.ts": {
|
|
293
|
+
"import": "./src/route-renderer/orchestration/foreign-child/component-render-context.js",
|
|
294
|
+
"types": "./src/route-renderer/orchestration/foreign-child/component-render-context.d.ts",
|
|
295
|
+
"default": "./src/route-renderer/orchestration/foreign-child/component-render-context.js"
|
|
296
|
+
},
|
|
297
|
+
"./route-renderer/orchestration/foreign-child/foreign-subtree-execution.service.ts": {
|
|
298
|
+
"types": "./src/route-renderer/orchestration/foreign-child/foreign-subtree-execution.service.d.ts",
|
|
299
|
+
"default": "./src/route-renderer/orchestration/foreign-child/foreign-subtree-execution.service.js"
|
|
300
|
+
},
|
|
301
|
+
"./route-renderer/orchestration/document-shell/document-shell-render.service.ts": {
|
|
302
|
+
"types": "./src/route-renderer/orchestration/document-shell/document-shell-render.service.d.ts",
|
|
303
|
+
"default": "./src/route-renderer/orchestration/document-shell/document-shell-render.service.js"
|
|
288
304
|
},
|
|
289
|
-
"./route-renderer/orchestration/
|
|
290
|
-
"types": "./src/route-renderer/orchestration/
|
|
291
|
-
"default": "./src/route-renderer/orchestration/
|
|
305
|
+
"./route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.ts": {
|
|
306
|
+
"types": "./src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.d.ts",
|
|
307
|
+
"default": "./src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.js"
|
|
292
308
|
},
|
|
293
|
-
"./route-renderer/orchestration/
|
|
294
|
-
"types": "./src/route-renderer/orchestration/
|
|
295
|
-
"default": "./src/route-renderer/orchestration/
|
|
309
|
+
"./route-renderer/orchestration/foreign-child/owning-renderer-resolution.ts": {
|
|
310
|
+
"types": "./src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.d.ts",
|
|
311
|
+
"default": "./src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.js"
|
|
296
312
|
},
|
|
297
313
|
"./router/navigation-coordinator.ts": {
|
|
298
314
|
"types": "./src/router/client/navigation-coordinator.d.ts",
|
package/src/eco/eco.js
CHANGED
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
finalizeComponentRender,
|
|
3
3
|
getComponentRenderContext,
|
|
4
4
|
interceptForeignChild
|
|
5
|
-
} from "../route-renderer/orchestration/component-render-context.js";
|
|
6
|
-
import { isThenable } from "../route-renderer/orchestration/
|
|
5
|
+
} from "../route-renderer/orchestration/foreign-child/component-render-context.js";
|
|
6
|
+
import { isThenable } from "../route-renderer/orchestration/foreign-child/foreign-child-output.utils.js";
|
|
7
7
|
import { applyPageLayoutConfig, mergeLayoutDependencies, normalizePageLayouts } from "./page-layout-normalization.js";
|
|
8
8
|
function createComponentFactory(options) {
|
|
9
9
|
const integrationName = options.integration ?? options.__eco?.integration;
|
package/src/eco/eco.utils.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { addTriggerAttribute, isThenable, wrapWithScriptsInjector, } from '../route-renderer/orchestration/
|
|
1
|
+
export { addTriggerAttribute, isThenable, wrapWithScriptsInjector, } from '../route-renderer/orchestration/foreign-child/foreign-child-output.utils.js';
|
package/src/eco/eco.utils.js
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
addTriggerAttribute,
|
|
3
3
|
isThenable,
|
|
4
4
|
wrapWithScriptsInjector
|
|
5
|
-
} from "../route-renderer/orchestration/
|
|
5
|
+
} from "../route-renderer/orchestration/foreign-child/foreign-child-output.utils.js";
|
|
6
6
|
export {
|
|
7
7
|
addTriggerAttribute,
|
|
8
8
|
isThenable,
|
|
@@ -88,7 +88,7 @@ import { getEcoNavigationRuntime } from "../../router/client/navigation-coordina
|
|
|
88
88
|
}
|
|
89
89
|
await new Promise((resolve) => {
|
|
90
90
|
const startedAt = performance.now();
|
|
91
|
-
const timeoutMs =
|
|
91
|
+
const timeoutMs = 5e3;
|
|
92
92
|
const poll = () => {
|
|
93
93
|
if (!navigationRuntime.hasPendingNavigationTransaction()) {
|
|
94
94
|
resolve();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EcoPagesAppConfig } from '../types/internal-types.js';
|
|
2
|
-
import { type AffectedGraphIdentity } from '../route-renderer/orchestration/page-browser-graph-session.js';
|
|
2
|
+
import { type AffectedGraphIdentity } from '../route-renderer/orchestration/page-browser-graph/page-browser-graph-session.js';
|
|
3
3
|
export type HmrFileChangePreparation = {
|
|
4
4
|
affectedGraphIdentities: AffectedGraphIdentity[];
|
|
5
5
|
invalidatedGraphCount: number;
|
|
@@ -2,7 +2,7 @@ import path from "node:path";
|
|
|
2
2
|
import {
|
|
3
3
|
getAffectedPageBrowserGraphIdentities,
|
|
4
4
|
invalidatePageBrowserGraphSession
|
|
5
|
-
} from "../route-renderer/orchestration/page-browser-graph-session.js";
|
|
5
|
+
} from "../route-renderer/orchestration/page-browser-graph/page-browser-graph-session.js";
|
|
6
6
|
function prepareHmrFileChange(appConfig, filePath) {
|
|
7
7
|
const resolvedFilePath = path.resolve(filePath);
|
|
8
8
|
const affectedGraphIdentities = getAffectedPageBrowserGraphIdentities(appConfig, resolvedFilePath);
|
|
@@ -19,6 +19,14 @@ export interface ProcessorWatchContext {
|
|
|
19
19
|
}
|
|
20
20
|
export interface ProcessorWatchConfig {
|
|
21
21
|
paths: string[];
|
|
22
|
+
/**
|
|
23
|
+
* File extensions that trigger watch callbacks (`onCreate`, `onChange`, `onDelete`).
|
|
24
|
+
*
|
|
25
|
+
* @remarks
|
|
26
|
+
* Watch extensions drive notifications only. They do not declare asset ownership.
|
|
27
|
+
* Ownership requires {@link ProcessorConfig.capabilities} and controls whether dev
|
|
28
|
+
* invalidation skips server modules and HMR for processor-handled assets.
|
|
29
|
+
*/
|
|
22
30
|
extensions?: string[];
|
|
23
31
|
onCreate?: (ctx: ProcessorWatchContext) => Promise<void>;
|
|
24
32
|
onChange?: (ctx: ProcessorWatchContext) => Promise<void>;
|
|
@@ -85,7 +85,7 @@ flowchart TD
|
|
|
85
85
|
B -- Yes --> C[return resolved renderer-owned output]
|
|
86
86
|
B -- No --> D[queue foreign-subtree token]
|
|
87
87
|
D --> E[finish current render pass]
|
|
88
|
-
E --> F[
|
|
88
|
+
E --> F[ForeignSubtreeExecutionService resolveQueuedHtml]
|
|
89
89
|
F --> G[resolve nested queued tokens first]
|
|
90
90
|
G --> H[dispatch foreign subtree to owning renderer]
|
|
91
91
|
H --> I[merge emitted assets and root attributes]
|
|
@@ -115,12 +115,12 @@ flowchart TD
|
|
|
115
115
|
The most useful reading order is:
|
|
116
116
|
|
|
117
117
|
1. `route-renderer.ts`
|
|
118
|
-
2. `orchestration/route-render-orchestrator.ts`
|
|
118
|
+
2. `orchestration/route-pipeline/route-render-orchestrator.ts`
|
|
119
119
|
3. `orchestration/integration-renderer.ts`
|
|
120
|
-
4. `orchestration/ownership-validation.service.ts`
|
|
121
|
-
5. `orchestration/component-graph.ts`
|
|
122
|
-
6. `orchestration/component-render-context.ts`
|
|
123
|
-
7. `orchestration/foreign-subtree-execution.service.ts`
|
|
120
|
+
4. `orchestration/ownership-graph/ownership-validation.service.ts`
|
|
121
|
+
5. `orchestration/ownership-graph/component-graph.ts`
|
|
122
|
+
6. `orchestration/foreign-child/component-render-context.ts`
|
|
123
|
+
7. `orchestration/foreign-child/foreign-subtree-execution.service.ts`
|
|
124
124
|
8. `page-loading/page-module-loader.ts`
|
|
125
125
|
9. `page-loading/dependency-resolver.ts`
|
|
126
126
|
10. `eco/eco.ts`
|
|
@@ -128,12 +128,12 @@ The most useful reading order is:
|
|
|
128
128
|
## 7) Key Files
|
|
129
129
|
|
|
130
130
|
- `packages/core/src/route-renderer/route-renderer.ts`
|
|
131
|
-
- `packages/core/src/route-renderer/orchestration/route-render-orchestrator.ts`
|
|
131
|
+
- `packages/core/src/route-renderer/orchestration/route-pipeline/route-render-orchestrator.ts`
|
|
132
132
|
- `packages/core/src/route-renderer/orchestration/integration-renderer.ts`
|
|
133
|
-
- `packages/core/src/route-renderer/orchestration/ownership-validation.service.ts`
|
|
134
|
-
- `packages/core/src/route-renderer/orchestration/component-graph.ts`
|
|
135
|
-
- `packages/core/src/route-renderer/orchestration/component-render-context.ts`
|
|
136
|
-
- `packages/core/src/route-renderer/orchestration/foreign-subtree-execution.service.ts`
|
|
133
|
+
- `packages/core/src/route-renderer/orchestration/ownership-graph/ownership-validation.service.ts`
|
|
134
|
+
- `packages/core/src/route-renderer/orchestration/ownership-graph/component-graph.ts`
|
|
135
|
+
- `packages/core/src/route-renderer/orchestration/foreign-child/component-render-context.ts`
|
|
136
|
+
- `packages/core/src/route-renderer/orchestration/foreign-child/foreign-subtree-execution.service.ts`
|
|
137
137
|
- `packages/core/src/route-renderer/page-loading/page-module-loader.ts`
|
|
138
138
|
- `packages/core/src/route-renderer/page-loading/dependency-resolver.ts`
|
|
139
139
|
- `packages/core/src/eco/eco.ts`
|
|
@@ -50,13 +50,18 @@ See [`../build/README.md`](../build/README.md) for the JSX ownership helper spli
|
|
|
50
50
|
|
|
51
51
|
### `orchestration/`
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
Root renderer classes:
|
|
54
|
+
|
|
54
55
|
- `integration-renderer.ts`: abstract base class for route rendering, explicit view rendering, and foreign-child delegation
|
|
55
|
-
- `
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
- `
|
|
56
|
+
- `string-markup-renderer.ts`: shared base for string-markup integrations
|
|
57
|
+
|
|
58
|
+
Domain folders:
|
|
59
|
+
|
|
60
|
+
- `ownership-graph/`: component graph walk/collect and up-front ownership validation
|
|
61
|
+
- `foreign-child/`: active render context, foreign-subtree execution, deferred template serialization
|
|
62
|
+
- `document-shell/`: shared page/layout/html shell composition and attribute stamping helpers
|
|
63
|
+
- `route-pipeline/`: route preparation, final HTML capture, marker-artifact enforcement
|
|
64
|
+
- `page-browser-graph/`: browser asset graph build, session cache, and injector assets
|
|
60
65
|
|
|
61
66
|
### `page-loading/`
|
|
62
67
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { BaseIntegrationContext, ComponentRenderInput, ComponentRenderResult, EcoComponent, PageMetadataProps } from '
|
|
2
|
-
import type { ProcessedAsset } from '
|
|
1
|
+
import type { BaseIntegrationContext, ComponentRenderInput, ComponentRenderResult, EcoComponent, PageMetadataProps } from '../../../types/public-types.js';
|
|
2
|
+
import type { ProcessedAsset } from '../../../services/assets/asset-processing-service/index.js';
|
|
3
|
+
import { HtmlTransformerService, type HtmlDocumentContribution } from '../../../services/html/html-transformer.service.js';
|
|
3
4
|
export type DocumentShellLayoutInput = {
|
|
4
5
|
component: EcoComponent;
|
|
5
6
|
props?: Record<string, unknown>;
|
|
@@ -88,3 +89,19 @@ export declare function applyDocumentShellAttributeStamping(html: string, stampi
|
|
|
88
89
|
* Builds the final serialized document HTML for one route page render.
|
|
89
90
|
*/
|
|
90
91
|
export declare function renderPageDocumentShell(dependencies: DocumentShellRenderDependencies, input: DocumentShellPageRenderInput, docType: string): Promise<string>;
|
|
92
|
+
/**
|
|
93
|
+
* Finalizes already-resolved HTML for explicit renderer-owned paths.
|
|
94
|
+
*
|
|
95
|
+
* @remarks
|
|
96
|
+
* Callers append renderer bootstrap dependencies before invoking this helper.
|
|
97
|
+
* Stamps document/root attributes and runs HTML transformation after nested
|
|
98
|
+
* foreign-subtree resolution without routing back through shared route execution.
|
|
99
|
+
*/
|
|
100
|
+
export declare function finalizeDocumentShellHtml(htmlTransformer: HtmlTransformerService, options: {
|
|
101
|
+
html: string;
|
|
102
|
+
partial?: boolean;
|
|
103
|
+
componentRootAttributes?: Record<string, string>;
|
|
104
|
+
documentAttributes?: Record<string, string>;
|
|
105
|
+
transformHtml?: boolean;
|
|
106
|
+
htmlContributions?: HtmlDocumentContribution[];
|
|
107
|
+
}): Promise<string>;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
HtmlTransformerService
|
|
3
|
+
} from "../../../services/html/html-transformer.service.js";
|
|
1
4
|
function resolveDocumentShellLayouts(input) {
|
|
2
5
|
if (input.layouts && input.layouts.length > 0) {
|
|
3
6
|
return input.layouts;
|
|
@@ -112,9 +115,34 @@ async function renderPageDocumentShell(dependencies, input, docType) {
|
|
|
112
115
|
const documentHtml = input.transformDocumentHtml ? input.transformDocumentHtml(composedDocumentHtml) : composedDocumentHtml;
|
|
113
116
|
return `${docType}${documentHtml}`;
|
|
114
117
|
}
|
|
118
|
+
async function finalizeDocumentShellHtml(htmlTransformer, options) {
|
|
119
|
+
const html = applyDocumentShellAttributeStamping(
|
|
120
|
+
options.html,
|
|
121
|
+
{
|
|
122
|
+
applyAttributesToFirstBodyElement: (nextHtml, attributes) => htmlTransformer.applyAttributesToFirstBodyElement(nextHtml, attributes),
|
|
123
|
+
applyAttributesToHtmlElement: (nextHtml, attributes) => htmlTransformer.applyAttributesToHtmlElement(nextHtml, attributes)
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
componentRootAttributes: options.componentRootAttributes,
|
|
127
|
+
documentAttributes: options.documentAttributes
|
|
128
|
+
}
|
|
129
|
+
);
|
|
130
|
+
const shouldTransform = options.transformHtml ?? !options.partial;
|
|
131
|
+
if (!shouldTransform) {
|
|
132
|
+
return html;
|
|
133
|
+
}
|
|
134
|
+
const transformedResponse = await htmlTransformer.transform(
|
|
135
|
+
new Response(html, {
|
|
136
|
+
headers: { "Content-Type": "text/html" }
|
|
137
|
+
}),
|
|
138
|
+
options.htmlContributions
|
|
139
|
+
);
|
|
140
|
+
return await transformedResponse.text();
|
|
141
|
+
}
|
|
115
142
|
export {
|
|
116
143
|
applyDocumentShellAttributeStamping,
|
|
117
144
|
composeDocumentShell,
|
|
118
145
|
composeSequentialLayoutChildren,
|
|
146
|
+
finalizeDocumentShellHtml,
|
|
119
147
|
renderPageDocumentShell
|
|
120
148
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EcoPageLayoutEntry, LayoutPropsContext } from '
|
|
1
|
+
import type { EcoPageLayoutEntry, LayoutPropsContext } from '../../../types/public-types.js';
|
|
2
2
|
export type LayoutShellPropsContext = LayoutPropsContext & {
|
|
3
3
|
pageProps?: Record<string, unknown>;
|
|
4
4
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { addTriggerAttribute, isThenable, wrapWithScriptsInjector } from "./
|
|
1
|
+
import { addTriggerAttribute, isThenable, wrapWithScriptsInjector } from "./foreign-child-output.utils.js";
|
|
2
2
|
class ComponentRenderOutputRuntime {
|
|
3
3
|
finalizeComponentRender(component, content) {
|
|
4
4
|
const lazyTriggers = component.config?._resolvedLazyTriggers;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EcoComponent } from '
|
|
1
|
+
import type { EcoComponent } from '../../../types/public-types.js';
|
|
2
2
|
type ResolvedLazyScriptGroups = Readonly<NonNullable<EcoComponent['config']>['_resolvedLazyScripts']>;
|
|
3
3
|
type TemplateContentShape = {
|
|
4
4
|
strings: readonly string[];
|
|
@@ -73,10 +73,4 @@ export declare function wrapWithScriptsInjector(content: string, lazyGroups: Res
|
|
|
73
73
|
export declare function wrapWithScriptsInjector<T extends TemplateContentShape>(content: T, lazyGroups: ResolvedLazyScriptGroups): T | string;
|
|
74
74
|
export declare function wrapWithScriptsInjector<T extends MarkupNodeLikeShape>(content: T, lazyGroups: ResolvedLazyScriptGroups): T;
|
|
75
75
|
export declare function wrapWithScriptsInjector(content: unknown, lazyGroups: ResolvedLazyScriptGroups): string | TemplateContentShape | MarkupNodeLikeShape;
|
|
76
|
-
export declare function decodeHtmlEntities(value: string): string;
|
|
77
|
-
export declare function normalizeUnresolvedMarkerArtifactHtml(html: string): string;
|
|
78
|
-
export declare function inspectUnresolvedMarkerArtifactHtml(html: string): {
|
|
79
|
-
hasUnresolvedMarkerArtifacts: boolean;
|
|
80
|
-
normalizedHtml: string;
|
|
81
|
-
};
|
|
82
76
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildInjectorMapScript } from "
|
|
1
|
+
import { buildInjectorMapScript } from "../../../eco/lazy-injector-map.js";
|
|
2
2
|
function cloneTemplateStrings(strings, firstString) {
|
|
3
3
|
const nextStrings = [...strings];
|
|
4
4
|
nextStrings[0] = firstString;
|
|
@@ -170,36 +170,11 @@ function wrapWithScriptsInjector(content, lazyGroups) {
|
|
|
170
170
|
}
|
|
171
171
|
return wrapWithScriptsInjectorMarkup(String(content), injectorMapScript);
|
|
172
172
|
}
|
|
173
|
-
function decodeHtmlEntities(value) {
|
|
174
|
-
let decoded = value;
|
|
175
|
-
let previous;
|
|
176
|
-
do {
|
|
177
|
-
previous = decoded;
|
|
178
|
-
decoded = decoded.replaceAll(""", '"').replaceAll("'", "'").replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">").replaceAll("&", "&");
|
|
179
|
-
} while (decoded !== previous);
|
|
180
|
-
return decoded;
|
|
181
|
-
}
|
|
182
|
-
function normalizeUnresolvedMarkerArtifactHtml(html) {
|
|
183
|
-
return html.replace(
|
|
184
|
-
/&(?:amp;)?lt;eco-marker\b[\s\S]*?&(?:amp;)?gt;&(?:amp;)?lt;\/eco-marker&(?:amp;)?gt;/g,
|
|
185
|
-
(marker) => decodeHtmlEntities(marker)
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
function inspectUnresolvedMarkerArtifactHtml(html) {
|
|
189
|
-
const normalizedHtml = normalizeUnresolvedMarkerArtifactHtml(html);
|
|
190
|
-
return {
|
|
191
|
-
normalizedHtml,
|
|
192
|
-
hasUnresolvedMarkerArtifacts: normalizedHtml.includes("<eco-marker")
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
173
|
export {
|
|
196
174
|
addTriggerAttribute,
|
|
197
175
|
assertForeignChildrenNotOpaque,
|
|
198
|
-
decodeHtmlEntities,
|
|
199
|
-
inspectUnresolvedMarkerArtifactHtml,
|
|
200
176
|
isMarkupNodeLike,
|
|
201
177
|
isOpaqueForeignChildValue,
|
|
202
178
|
isThenable,
|
|
203
|
-
normalizeUnresolvedMarkerArtifactHtml,
|
|
204
179
|
wrapWithScriptsInjector
|
|
205
180
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ProcessedAsset } from '
|
|
2
|
-
import type { BaseIntegrationContext, ComponentRenderInput, ComponentRenderResult, EcoComponent, ForeignSubtreeRenderPayload } from '
|
|
1
|
+
import type { ProcessedAsset } from '../../../services/assets/asset-processing-service/index.js';
|
|
2
|
+
import type { BaseIntegrationContext, ComponentRenderInput, ComponentRenderResult, EcoComponent, ForeignSubtreeRenderPayload } from '../../../types/public-types.js';
|
|
3
3
|
import { type ForeignChildRuntime } from './component-render-context.js';
|
|
4
4
|
export type QueuedForeignChildDecisionInput = {
|
|
5
5
|
currentIntegration: string;
|
|
@@ -46,7 +46,7 @@ export interface ForeignSubtreeExecutionRenderOptions {
|
|
|
46
46
|
renderInput: ComponentRenderInput;
|
|
47
47
|
rendererCache: Map<string, ForeignSubtreeExecutionOwningRenderer>;
|
|
48
48
|
}): ForeignChildRuntime;
|
|
49
|
-
getOwningRenderer(integrationName: string, rendererCache: Map<string, ForeignSubtreeExecutionOwningRenderer>): ForeignSubtreeExecutionOwningRenderer
|
|
49
|
+
getOwningRenderer(integrationName: string, rendererCache: Map<string, ForeignSubtreeExecutionOwningRenderer>): Promise<ForeignSubtreeExecutionOwningRenderer>;
|
|
50
50
|
}
|
|
51
51
|
export interface ForeignSubtreeQueuedRuntimeOptions<TContext extends QueuedForeignSubtreeResolutionContext> {
|
|
52
52
|
renderInput: ComponentRenderInput;
|
|
@@ -61,7 +61,7 @@ export interface ForeignSubtreeStringQueuedHtmlOptions {
|
|
|
61
61
|
html: string;
|
|
62
62
|
runtimeContextKey: string;
|
|
63
63
|
queueLabel: string;
|
|
64
|
-
getOwningRenderer(integrationName: string, rendererCache: Map<string, ForeignSubtreeExecutionOwningRenderer>): ForeignSubtreeExecutionOwningRenderer
|
|
64
|
+
getOwningRenderer(integrationName: string, rendererCache: Map<string, ForeignSubtreeExecutionOwningRenderer>): Promise<ForeignSubtreeExecutionOwningRenderer>;
|
|
65
65
|
applyAttributesToFirstElement(html: string, attributes: Record<string, string>): string;
|
|
66
66
|
dedupeProcessedAssets(assets: ProcessedAsset[]): ProcessedAsset[];
|
|
67
67
|
}
|
|
@@ -75,7 +75,7 @@ export interface ForeignSubtreeQueuedHtmlOptions<TContext extends QueuedForeignS
|
|
|
75
75
|
children?: unknown;
|
|
76
76
|
html?: string;
|
|
77
77
|
}>;
|
|
78
|
-
getOwningRenderer(integrationName: string, rendererCache: Map<string, ForeignSubtreeExecutionOwningRenderer>): ForeignSubtreeExecutionOwningRenderer
|
|
78
|
+
getOwningRenderer(integrationName: string, rendererCache: Map<string, ForeignSubtreeExecutionOwningRenderer>): Promise<ForeignSubtreeExecutionOwningRenderer>;
|
|
79
79
|
applyAttributesToFirstElement(html: string, attributes: Record<string, string>): string;
|
|
80
80
|
dedupeProcessedAssets(assets: ProcessedAsset[]): ProcessedAsset[];
|
|
81
81
|
}
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
getComponentRenderContext,
|
|
3
3
|
runWithComponentRenderContext
|
|
4
4
|
} from "./component-render-context.js";
|
|
5
|
-
import { assertForeignChildrenNotOpaque, isMarkupNodeLike } from "./
|
|
5
|
+
import { assertForeignChildrenNotOpaque, isMarkupNodeLike } from "./foreign-child-output.utils.js";
|
|
6
6
|
function toForeignSubtreeRenderPayload(result) {
|
|
7
7
|
return {
|
|
8
8
|
html: result.html,
|
|
@@ -313,7 +313,7 @@ class ForeignSubtreeExecutionService {
|
|
|
313
313
|
if (!foreignOwnerIntegrationName) {
|
|
314
314
|
return void 0;
|
|
315
315
|
}
|
|
316
|
-
const owningRenderer = options.getOwningRenderer(foreignOwnerIntegrationName, options.rendererCache);
|
|
316
|
+
const owningRenderer = await options.getOwningRenderer(foreignOwnerIntegrationName, options.rendererCache);
|
|
317
317
|
if (owningRenderer.name === options.currentIntegrationName) {
|
|
318
318
|
return void 0;
|
|
319
319
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { EcoPagesAppConfig } from '../../../types/internal-types.js';
|
|
2
|
+
import type { ForeignSubtreeExecutionOwningRenderer } from './foreign-subtree-execution.service.js';
|
|
3
|
+
export type OwningRendererResolutionInput = {
|
|
4
|
+
appConfig: EcoPagesAppConfig;
|
|
5
|
+
runtimeOrigin: string;
|
|
6
|
+
currentIntegrationName: string;
|
|
7
|
+
currentRenderer: ForeignSubtreeExecutionOwningRenderer;
|
|
8
|
+
integrationName: string;
|
|
9
|
+
cache: Map<string, ForeignSubtreeExecutionOwningRenderer>;
|
|
10
|
+
};
|
|
11
|
+
export declare function getForeignSubtreeTokenPrefix(integrationName: string): string;
|
|
12
|
+
export declare function getForeignSubtreeResolutionContextKey(integrationName: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Resolves an owning integration renderer for a foreign-child handoff.
|
|
15
|
+
*
|
|
16
|
+
* Reuses the execution-scoped cache, activates the target runtime when needed,
|
|
17
|
+
* and initializes the plugin renderer once per integration name.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveOwningIntegrationRenderer(input: OwningRendererResolutionInput): Promise<ForeignSubtreeExecutionOwningRenderer>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ensureIntegrationRuntimeReady } from "../../../build/app-build-manifest-runtime.js";
|
|
2
|
+
import { invariant } from "../../../utils/invariant.js";
|
|
3
|
+
function getForeignSubtreeTokenPrefix(integrationName) {
|
|
4
|
+
return `__${integrationName}_foreign_subtree__`;
|
|
5
|
+
}
|
|
6
|
+
function getForeignSubtreeResolutionContextKey(integrationName) {
|
|
7
|
+
return `__${integrationName}_foreign_subtree_runtime__`;
|
|
8
|
+
}
|
|
9
|
+
async function resolveOwningIntegrationRenderer(input) {
|
|
10
|
+
const { integrationName, cache } = input;
|
|
11
|
+
if (cache.has(integrationName)) {
|
|
12
|
+
return cache.get(integrationName);
|
|
13
|
+
}
|
|
14
|
+
if (integrationName === input.currentIntegrationName) {
|
|
15
|
+
cache.set(integrationName, input.currentRenderer);
|
|
16
|
+
return input.currentRenderer;
|
|
17
|
+
}
|
|
18
|
+
await ensureIntegrationRuntimeReady({
|
|
19
|
+
appConfig: input.appConfig,
|
|
20
|
+
integrationName,
|
|
21
|
+
runtimeOrigin: input.runtimeOrigin
|
|
22
|
+
});
|
|
23
|
+
const integrationPlugin = input.appConfig.integrations.find((integration) => integration.name === integrationName);
|
|
24
|
+
invariant(!!integrationPlugin, `[ecopages] Integration not found for foreign owner: ${integrationName}`);
|
|
25
|
+
const renderer = integrationPlugin.initializeRenderer({
|
|
26
|
+
rendererModules: input.appConfig.runtime?.rendererModuleContext
|
|
27
|
+
});
|
|
28
|
+
cache.set(integrationName, renderer);
|
|
29
|
+
return renderer;
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
getForeignSubtreeResolutionContextKey,
|
|
33
|
+
getForeignSubtreeTokenPrefix,
|
|
34
|
+
resolveOwningIntegrationRenderer
|
|
35
|
+
};
|