@ecopages/core 0.2.0-beta.2 → 0.2.0-beta.21
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 +163 -3
- package/src/adapters/abstract/application-adapter.d.ts +104 -5
- package/src/adapters/abstract/application-adapter.js +125 -1
- package/src/adapters/abstract/server-adapter.d.ts +6 -2
- package/src/adapters/abstract/ws-pattern-matcher.d.ts +60 -0
- package/src/adapters/abstract/ws-pattern-matcher.js +61 -0
- package/src/adapters/bun/client-bridge.d.ts +1 -0
- package/src/adapters/bun/client-bridge.js +3 -0
- package/src/adapters/bun/create-app.d.ts +6 -4
- package/src/adapters/bun/create-app.js +65 -43
- package/src/adapters/bun/server-adapter.d.ts +90 -22
- package/src/adapters/bun/server-adapter.js +266 -84
- package/src/adapters/bun/static-preview-host.js +25 -20
- package/src/adapters/create-app.d.ts +13 -11
- package/src/adapters/create-app.js +2 -51
- package/src/adapters/index.d.ts +1 -1
- package/src/adapters/index.js +1 -2
- package/src/adapters/node/create-app.d.ts +5 -1
- package/src/adapters/node/create-app.js +51 -12
- package/src/adapters/node/node-client-bridge.d.ts +1 -0
- package/src/adapters/node/node-client-bridge.js +3 -0
- package/src/adapters/node/server-adapter-dependencies.js +4 -0
- package/src/adapters/node/server-adapter.d.ts +62 -20
- package/src/adapters/node/server-adapter.js +160 -131
- package/src/adapters/node/static-content-server.d.ts +1 -0
- package/src/adapters/node/static-content-server.js +10 -2
- package/src/adapters/node/static-preview-host.js +27 -12
- package/src/adapters/shared/bun-user-websocket-lifecycle.d.ts +22 -0
- package/src/adapters/shared/bun-user-websocket-lifecycle.js +96 -0
- package/src/adapters/shared/copy-runtime-public-dir.d.ts +6 -0
- package/src/adapters/shared/copy-runtime-public-dir.js +24 -0
- package/src/adapters/shared/fs-server-response-matcher.d.ts +2 -0
- package/src/adapters/shared/fs-server-response-matcher.js +40 -18
- package/src/adapters/shared/hmr-entrypoint-registrar.d.ts +21 -30
- package/src/adapters/shared/hmr-entrypoint-registrar.js +49 -54
- package/src/adapters/shared/hmr-html-response.d.ts +1 -1
- package/src/adapters/shared/hmr-html-response.js +4 -1
- package/src/adapters/shared/node-http-websocket-upgrades.d.ts +21 -0
- package/src/adapters/shared/node-http-websocket-upgrades.js +100 -0
- package/src/adapters/shared/port-manager.d.ts +116 -0
- package/src/adapters/shared/port-manager.js +196 -0
- package/src/adapters/shared/runtime-app-bootstrap.d.ts +2 -1
- package/src/adapters/shared/runtime-app-bootstrap.js +3 -6
- package/src/adapters/shared/runtime-server-lifecycle.d.ts +46 -0
- package/src/adapters/shared/runtime-server-lifecycle.js +50 -0
- package/src/adapters/shared/server-adapter.d.ts +2 -1
- package/src/adapters/shared/server-adapter.js +13 -6
- package/src/adapters/shared/server-route-handler.d.ts +4 -1
- package/src/adapters/shared/server-route-handler.js +5 -2
- package/src/adapters/shared/server-static-builder.d.ts +23 -32
- package/src/adapters/shared/server-static-builder.js +100 -73
- package/src/adapters/shared/shared-hmr-manager.d.ts +45 -11
- package/src/adapters/shared/shared-hmr-manager.js +204 -58
- package/src/adapters/shared/static-preview-host.d.ts +5 -0
- package/src/adapters/shared/websocket-lifecycle.d.ts +24 -0
- package/src/adapters/shared/websocket-lifecycle.js +55 -0
- package/src/build/README.md +77 -14
- package/src/build/app-build-manifest-runtime.d.ts +9 -0
- package/src/build/app-build-manifest-runtime.js +87 -0
- package/src/build/build-adapter.d.ts +17 -319
- package/src/build/build-adapter.js +28 -94
- package/src/build/build-contracts.d.ts +97 -0
- package/src/build/build-contracts.js +0 -0
- package/src/build/build-input-fingerprint.d.ts +28 -0
- package/src/build/build-input-fingerprint.js +31 -0
- package/src/build/build-profile-options.d.ts +7 -0
- package/src/build/build-profile-options.js +37 -0
- package/src/build/build-runtime.d.ts +24 -0
- package/src/build/build-runtime.js +65 -0
- package/src/build/deduping-build-executor.d.ts +28 -0
- package/src/build/deduping-build-executor.js +56 -0
- package/src/build/jsx-ownership-plugins.d.ts +24 -0
- package/src/build/jsx-ownership-plugins.js +41 -0
- package/src/build/pages-unified-graph-build.d.ts +31 -0
- package/src/build/pages-unified-graph-build.js +206 -0
- package/src/build/parallel-build-executor.d.ts +21 -0
- package/src/build/parallel-build-executor.js +52 -0
- package/src/build/production-build-cache.d.ts +20 -0
- package/src/build/production-build-cache.js +63 -0
- package/src/build/rolldown-adapter-helpers.d.ts +3 -6
- package/src/build/rolldown-adapter-helpers.js +71 -6
- package/src/build/rolldown-build-adapter.d.ts +2 -6
- package/src/build/rolldown-build-adapter.js +3 -3
- package/src/build/rolldown-build-invocation-metrics.d.ts +12 -0
- package/src/build/rolldown-build-invocation-metrics.js +43 -0
- package/src/build/rolldown-plugin-bridge.d.ts +15 -1
- package/src/build/rolldown-plugin-bridge.js +20 -5
- package/src/build/rolldown-source-transform-pass.d.ts +15 -0
- package/src/build/rolldown-source-transform-pass.js +58 -0
- package/src/build/runtime-build-executor.d.ts +8 -15
- package/src/build/runtime-build-executor.js +12 -15
- package/src/build/runtime-build-output-normalizer.d.ts +7 -0
- package/src/build/runtime-build-output-normalizer.js +94 -2
- package/src/build/server-entry-build-cache.d.ts +44 -0
- package/src/build/server-entry-build-cache.js +161 -0
- package/src/client/navigation-scripts/classification.d.ts +16 -0
- package/src/client/navigation-scripts/classification.js +41 -0
- package/src/client/navigation-scripts/index.d.ts +3 -0
- package/src/client/navigation-scripts/index.js +23 -0
- package/src/client/navigation-scripts/navigation-scripts.test.browser.js +65 -0
- package/src/client/navigation-scripts/registry.d.ts +11 -0
- package/src/client/navigation-scripts/registry.js +12 -0
- package/src/client/navigation-scripts/rerun-queue.d.ts +37 -0
- package/src/client/navigation-scripts/rerun-queue.js +73 -0
- package/src/client/scroll.d.ts +17 -0
- package/src/client/scroll.js +25 -0
- package/src/client/scroll.test.browser.js +37 -0
- package/src/client/view-transitions.d.ts +16 -0
- package/src/client/view-transitions.js +63 -0
- package/src/config/config-builder.d.ts +12 -7
- package/src/config/config-builder.js +12 -9
- package/src/dev/client-bridge-registry.d.ts +5 -0
- package/src/dev/client-bridge-registry.js +15 -0
- package/src/dev/dev-client-ownership.d.ts +7 -0
- package/src/dev/dev-client-ownership.js +6 -0
- package/src/dev/hmr-manager-registry.d.ts +8 -0
- package/src/dev/hmr-manager-registry.js +15 -0
- package/src/dev/host-runtime.d.ts +3 -0
- package/src/dev/host-runtime.js +7 -0
- package/src/dev/runtime-server-started-message.d.ts +2 -0
- package/src/dev/runtime-server-started-message.js +6 -0
- package/src/eco/README.md +11 -0
- package/src/eco/eco-declared-component.d.ts +14 -0
- package/src/eco/eco-declared-component.js +16 -0
- package/src/eco/eco.browser.js +5 -6
- package/src/eco/eco.js +5 -6
- package/src/eco/eco.types.d.ts +2 -2
- package/src/eco/page-layout-normalization.d.ts +21 -0
- package/src/eco/page-layout-normalization.js +59 -0
- package/src/errors/index.d.ts +1 -0
- package/src/errors/index.js +7 -1
- package/src/errors/undeclared-component-dependency-error.d.ts +11 -0
- package/src/errors/undeclared-component-dependency-error.js +17 -0
- package/src/hmr/client/hmr-runtime.js +5 -2
- package/src/hmr/hmr-entrypoint-output.d.ts +43 -0
- package/src/hmr/hmr-entrypoint-output.js +53 -0
- package/src/hmr/hmr-strategy.d.ts +15 -0
- package/src/hmr/hmr-strategy.js +19 -0
- package/src/hmr/strategies/js-hmr-strategy.d.ts +3 -5
- package/src/hmr/strategies/js-hmr-strategy.js +67 -19
- package/src/hmr/strategies/server-rendered-template-hmr-strategy.d.ts +17 -0
- package/src/hmr/strategies/server-rendered-template-hmr-strategy.js +29 -0
- package/src/integrations/ghtml/ghtml-renderer.d.ts +2 -6
- package/src/integrations/ghtml/ghtml-renderer.js +2 -51
- package/src/integrations/ghtml/ghtml.plugin.d.ts +3 -16
- package/src/integrations/ghtml/ghtml.plugin.js +7 -14
- package/src/plugins/define-integration.d.ts +26 -0
- package/src/plugins/define-integration.js +19 -0
- package/src/plugins/eco-component-meta-plugin.js +5 -8
- package/src/plugins/foreign-jsx-override-plugin.js +4 -6
- package/src/plugins/integration-plugin.d.ts +19 -9
- package/src/plugins/integration-plugin.js +7 -4
- package/src/plugins/jsx-import-source.utils.d.ts +8 -0
- package/src/plugins/jsx-import-source.utils.js +26 -0
- package/src/plugins/processor.d.ts +19 -4
- package/src/plugins/processor.js +22 -4
- package/src/plugins/source-transform.d.ts +31 -0
- package/src/plugins/source-transform.js +23 -1
- package/src/route-renderer/GRAPH.md +8 -8
- package/src/route-renderer/README.md +30 -28
- package/src/route-renderer/orchestration/component-graph-collectors.d.ts +10 -0
- package/src/route-renderer/orchestration/component-graph-collectors.js +143 -0
- package/src/route-renderer/orchestration/component-graph.d.ts +36 -0
- package/src/route-renderer/orchestration/component-graph.js +98 -0
- package/src/route-renderer/orchestration/component-render-context.d.ts +3 -10
- package/src/route-renderer/orchestration/component-render-context.js +3 -1
- package/src/route-renderer/orchestration/declared-ownership-graph.d.ts +1 -18
- package/src/route-renderer/orchestration/declared-ownership-graph.js +5 -31
- package/src/route-renderer/orchestration/document-shell-render.service.d.ts +90 -0
- package/src/route-renderer/orchestration/document-shell-render.service.js +120 -0
- package/src/route-renderer/orchestration/foreign-subtree-execution.service.d.ts +59 -29
- package/src/route-renderer/orchestration/foreign-subtree-execution.service.js +164 -35
- package/src/route-renderer/orchestration/global-injector-assets.service.d.ts +7 -0
- package/src/route-renderer/orchestration/global-injector-assets.service.js +32 -0
- package/src/route-renderer/orchestration/integration-renderer.d.ts +18 -54
- package/src/route-renderer/orchestration/integration-renderer.js +113 -195
- package/src/route-renderer/orchestration/integration-route-render-adapter.d.ts +38 -0
- package/src/route-renderer/orchestration/integration-route-render-adapter.js +27 -0
- package/src/route-renderer/orchestration/layout-shell-props.service.d.ts +20 -0
- package/src/route-renderer/orchestration/layout-shell-props.service.js +31 -0
- package/src/route-renderer/orchestration/ownership-validation.service.d.ts +5 -0
- package/src/route-renderer/orchestration/ownership-validation.service.js +29 -1
- package/src/route-renderer/orchestration/page-browser-graph-contribution.loader.d.ts +9 -0
- package/src/route-renderer/orchestration/page-browser-graph-contribution.loader.js +7 -0
- package/src/route-renderer/orchestration/page-browser-graph.service.d.ts +25 -0
- package/src/route-renderer/orchestration/page-browser-graph.service.js +174 -0
- package/src/route-renderer/orchestration/render-output.utils.d.ts +2 -0
- package/src/route-renderer/orchestration/render-output.utils.js +4 -0
- package/src/route-renderer/orchestration/route-html-finalization.service.d.ts +17 -0
- package/src/route-renderer/orchestration/route-html-finalization.service.js +26 -0
- package/src/route-renderer/orchestration/route-prepared-options.builder.d.ts +26 -0
- package/src/route-renderer/orchestration/route-prepared-options.builder.js +54 -0
- package/src/route-renderer/orchestration/route-prepared-options.utils.d.ts +4 -0
- package/src/route-renderer/orchestration/route-prepared-options.utils.js +33 -0
- package/src/route-renderer/orchestration/route-render-orchestrator.d.ts +8 -39
- package/src/route-renderer/orchestration/route-render-orchestrator.js +53 -461
- package/src/route-renderer/orchestration/string-markup-renderer.d.ts +14 -0
- package/src/route-renderer/orchestration/string-markup-renderer.js +55 -0
- package/src/route-renderer/page-loading/component-dependency-collection.js +5 -2
- package/src/router/client/link-intent.d.ts +11 -21
- package/src/router/client/link-intent.js +10 -0
- package/src/router/client/link-intent.test.browser.js +12 -1
- package/src/router/client/link-navigation-policy.d.ts +45 -0
- package/src/router/client/link-navigation-policy.js +101 -0
- package/src/router/client/link-navigation-policy.test.browser.d.ts +1 -0
- package/src/router/client/link-navigation-policy.test.browser.js +92 -0
- package/src/router/client/navigation-coordinator.d.ts +1 -1
- package/src/router/client/navigation-coordinator.js +12 -2
- package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.d.ts +1 -0
- package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +1 -0
- package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.d.ts +4 -2
- package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.js +27 -7
- package/src/services/assets/asset-processing-service/processors/script/file-script.processor.d.ts +0 -1
- package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +18 -15
- package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +17 -3
- package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.d.ts +0 -3
- package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +2 -31
- package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.d.ts +0 -3
- package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +2 -30
- package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.d.ts +2 -0
- package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.js +43 -0
- package/src/services/assets/browser-bundle.service.d.ts +3 -1
- package/src/services/assets/browser-bundle.service.js +17 -5
- package/src/services/html/html-transformer.service.d.ts +1 -1
- package/src/services/html/html-transformer.service.js +4 -4
- package/src/services/invalidation/development-invalidation.service.d.ts +20 -2
- package/src/services/invalidation/development-invalidation.service.js +56 -2
- package/src/services/module-loading/README.md +49 -0
- package/src/services/module-loading/app-server-module-transpiler.service.js +5 -17
- package/src/services/module-loading/page-module-import.service.d.ts +5 -1
- package/src/services/module-loading/page-module-import.service.js +96 -45
- package/src/services/module-loading/route-module-build-cache-registry.d.ts +24 -0
- package/src/services/module-loading/route-module-build-cache-registry.js +37 -0
- package/src/services/module-loading/route-module-build-cache.d.ts +4 -0
- package/src/services/module-loading/route-module-build-cache.js +38 -0
- package/src/services/module-loading/route-module-build-cache.store.d.ts +57 -0
- package/src/services/module-loading/route-module-build-cache.store.js +207 -0
- package/src/services/module-loading/route-module-build-manifest.d.ts +61 -0
- package/src/services/module-loading/route-module-build-manifest.js +116 -0
- package/src/services/module-loading/route-module-dependency-hasher.d.ts +81 -0
- package/src/services/module-loading/route-module-dependency-hasher.js +122 -0
- package/src/services/module-loading/server-module-transpiler.service.js +1 -1
- package/src/static-site-generator/README.md +33 -0
- package/src/static-site-generator/static-build-invalidation.d.ts +10 -0
- package/src/static-site-generator/static-build-invalidation.js +59 -0
- package/src/static-site-generator/static-export-context.d.ts +22 -0
- package/src/static-site-generator/static-export-context.js +0 -0
- package/src/static-site-generator/static-site-generator.d.ts +17 -20
- package/src/static-site-generator/static-site-generator.js +188 -85
- package/src/types/internal-types.d.ts +16 -9
- package/src/types/public-types.d.ts +144 -40
- package/src/utils/parse-cli-args.d.ts +2 -0
- package/src/utils/parse-cli-args.js +6 -0
- package/src/utils/server-utils.module.d.ts +3 -2
- package/src/utils/server-utils.module.js +5 -6
- package/src/utils/static-file-extensions.d.ts +12 -0
- package/src/utils/static-file-extensions.js +48 -0
- package/src/watchers/project-watcher-ignore.d.ts +11 -0
- package/src/watchers/project-watcher-ignore.js +16 -0
- package/src/watchers/project-watcher.d.ts +26 -3
- package/src/watchers/project-watcher.js +132 -30
- package/src/watchers/project-watcher.test-helpers.js +5 -5
- package/src/build/rolldown-dev-build-adapter.d.ts +0 -82
- package/src/build/rolldown-dev-build-adapter.js +0 -166
- package/src/hmr/hmr.postcss.test.e2e.js +0 -31
- package/src/hmr/hmr.test.e2e.js +0 -43
- package/src/route-renderer/orchestration/ownership-planning.service.d.ts +0 -24
- package/src/route-renderer/orchestration/ownership-planning.service.js +0 -63
- package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.d.ts +0 -91
- package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.js +0 -170
- /package/src/{hmr/hmr.postcss.test.e2e.d.ts → client/navigation-scripts/navigation-scripts.test.browser.d.ts} +0 -0
- /package/src/{hmr/hmr.test.e2e.d.ts → client/scroll.test.browser.d.ts} +0 -0
|
@@ -4,17 +4,16 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
import type { EcoPagesAppConfig, IHmrManager } from '../../types/internal-types.js';
|
|
7
|
-
import type { ComponentRenderInput, ComponentRenderResult,
|
|
7
|
+
import type { ComponentRenderInput, ComponentRenderResult, EcoComponent, EcoComponentDependencies, EcoPageFile, EcoPagesElement, BaseIntegrationContext, HtmlTemplateProps, IntegrationRendererRenderOptions, PageBrowserGraphContribution, PageBrowserGraphContributionContext, PageBrowserGraphResult, PageMetadataProps, PagePackageResult, RouteRendererBody, RouteRendererOptions, RouteRenderResult } from '../../types/public-types.js';
|
|
8
8
|
import { type AssetProcessingService, type ProcessedAsset } from '../../services/assets/asset-processing-service/index.js';
|
|
9
9
|
import { HtmlTransformerService } from '../../services/html/html-transformer.service.js';
|
|
10
10
|
import type { HtmlDocumentContribution } from '../../services/html/html-transformer.service.js';
|
|
11
11
|
import { HttpError } from '../../errors/http-error.js';
|
|
12
12
|
import { DependencyResolverService } from '../page-loading/dependency-resolver.js';
|
|
13
13
|
import { PageModuleLoaderService } from '../page-loading/page-module-loader.js';
|
|
14
|
-
import {
|
|
14
|
+
import { RouteRenderOrchestrator, type RouteRenderOrchestratorAdapter, type RouteRenderOrchestratorResolvedInputs } from './route-render-orchestrator.js';
|
|
15
15
|
import type { ForeignChildRuntime } from './component-render-context.js';
|
|
16
|
-
import { ForeignSubtreeExecutionService, type ForeignSubtreeExecutionOwningRenderer } from './foreign-subtree-execution.service.js';
|
|
17
|
-
import { type QueuedForeignSubtreeResolutionContext } from './queued-foreign-subtree-resolution.service.js';
|
|
16
|
+
import { ForeignSubtreeExecutionService, type ForeignSubtreeExecutionOwningRenderer, type ForeignSubtreeQueuedHtmlOptions, type QueuedForeignSubtreeResolutionContext } from './foreign-subtree-execution.service.js';
|
|
18
17
|
/**
|
|
19
18
|
* Controls how one route module is loaded outside the normal render path.
|
|
20
19
|
*
|
|
@@ -59,7 +58,15 @@ export declare abstract class IntegrationRenderer<C = EcoPagesElement> {
|
|
|
59
58
|
protected pageModuleLoaderService: PageModuleLoaderService;
|
|
60
59
|
protected routeRenderOrchestrator: RouteRenderOrchestrator;
|
|
61
60
|
protected readonly foreignSubtreeExecutionService: ForeignSubtreeExecutionService;
|
|
61
|
+
/**
|
|
62
|
+
* Serializes route and view renders that mutate `htmlTransformer` state.
|
|
63
|
+
*
|
|
64
|
+
* Integration renderers are cached per integration, so concurrent static builds
|
|
65
|
+
* and overlapping SSR requests must not share one transformer page package.
|
|
66
|
+
*/
|
|
67
|
+
private renderExclusiveChain;
|
|
62
68
|
protected DOC_TYPE: string;
|
|
69
|
+
private runRenderExclusive;
|
|
63
70
|
/**
|
|
64
71
|
* Loads one route module through the owning renderer's import path.
|
|
65
72
|
*
|
|
@@ -69,34 +76,6 @@ export declare abstract class IntegrationRenderer<C = EcoPagesElement> {
|
|
|
69
76
|
* with raw transpiler access.
|
|
70
77
|
*/
|
|
71
78
|
loadPageModule(file: string, options?: RouteModuleLoadOptions): Promise<EcoPageFile>;
|
|
72
|
-
/**
|
|
73
|
-
* Reads the execution-scoped owning-renderer cache from one render input.
|
|
74
|
-
*
|
|
75
|
-
* Shared page/layout/document shell helpers pass one cache through
|
|
76
|
-
* `integrationContext` so repeated delegation to the same foreign integration
|
|
77
|
-
* can reuse a single initialized renderer instance during one render flow.
|
|
78
|
-
* The cache is deliberately scoped to the current render execution rather than
|
|
79
|
-
* stored on the renderer, which avoids leaking mutable integration state across
|
|
80
|
-
* requests while still preventing redundant renderer initialization.
|
|
81
|
-
*
|
|
82
|
-
* @param integrationContext - Optional render context carried with one render input.
|
|
83
|
-
* @returns The current execution cache when present.
|
|
84
|
-
*/
|
|
85
|
-
private getOwningRendererCache;
|
|
86
|
-
private getForeignOwnerIntegrationName;
|
|
87
|
-
/**
|
|
88
|
-
* Attaches an execution-scoped owning-renderer cache to one render input.
|
|
89
|
-
*
|
|
90
|
-
* Foreign-owned page, layout, or document shells may delegate several times in
|
|
91
|
-
* the same render flow. Threading the cache through `integrationContext`
|
|
92
|
-
* preserves renderer reuse without changing the public render input contract.
|
|
93
|
-
* Existing integration-specific context is preserved and augmented.
|
|
94
|
-
*
|
|
95
|
-
* @param input - Original render input.
|
|
96
|
-
* @param rendererCache - Execution-scoped renderer cache to propagate.
|
|
97
|
-
* @returns Render input augmented with the shared renderer cache.
|
|
98
|
-
*/
|
|
99
|
-
private withOwningRendererCache;
|
|
100
79
|
protected getRendererModuleValue(key: string): unknown;
|
|
101
80
|
protected getRendererModuleString(key: string): string | undefined;
|
|
102
81
|
protected getRendererBootstrapDependencies(partial?: boolean): ProcessedAsset[];
|
|
@@ -219,20 +198,6 @@ export declare abstract class IntegrationRenderer<C = EcoPagesElement> {
|
|
|
219
198
|
documentProps?: Record<string, unknown>;
|
|
220
199
|
transformDocumentHtml?: (html: string) => string;
|
|
221
200
|
}): Promise<string>;
|
|
222
|
-
private composeDocumentShell;
|
|
223
|
-
/**
|
|
224
|
-
* Renders one string-first component with serialized children and collects its assets.
|
|
225
|
-
*
|
|
226
|
-
* String-oriented integrations frequently share the same component contract:
|
|
227
|
-
* pass serialized children through props, coerce the render result to HTML, and
|
|
228
|
-
* attach any component-scoped dependencies. This helper centralizes that flow
|
|
229
|
-
* so integrations can opt into shared orchestration without repeating the same
|
|
230
|
-
* string-render boilerplate.
|
|
231
|
-
*
|
|
232
|
-
* @param input - Component render input.
|
|
233
|
-
* @param component - String-oriented component implementation to execute.
|
|
234
|
-
* @returns Structured component render result for orchestration paths.
|
|
235
|
-
*/
|
|
236
201
|
protected renderStringComponentWithSerializedChildren(input: ComponentRenderInput, component: (props: Record<string, unknown>) => Promise<EcoPagesElement> | EcoPagesElement): Promise<ComponentRenderResult>;
|
|
237
202
|
protected getForeignSubtreeTokenPrefix(): string;
|
|
238
203
|
protected getForeignSubtreeResolutionContextKey(): string;
|
|
@@ -244,6 +209,10 @@ export declare abstract class IntegrationRenderer<C = EcoPagesElement> {
|
|
|
244
209
|
createRuntimeContext?: (integrationContext: BaseIntegrationContext & Record<string, unknown>, rendererCache: Map<string, unknown>) => TContext;
|
|
245
210
|
}): ForeignChildRuntime;
|
|
246
211
|
protected getQueuedForeignSubtreeResolutionContext<TContext extends QueuedForeignSubtreeResolutionContext>(input: ComponentRenderInput): TContext | undefined;
|
|
212
|
+
protected resolveQueuedForeignSubtreeHtml<TContext extends QueuedForeignSubtreeResolutionContext>(html: string, runtimeContext: TContext | undefined, renderQueuedChildren: ForeignSubtreeQueuedHtmlOptions<TContext>['renderQueuedChildren'], queueLabel?: string): Promise<{
|
|
213
|
+
assets: ProcessedAsset[];
|
|
214
|
+
html: string;
|
|
215
|
+
}>;
|
|
247
216
|
/**
|
|
248
217
|
* Renders a string-first component, then resolves any queued foreign
|
|
249
218
|
* boundaries before returning final component HTML.
|
|
@@ -350,8 +319,7 @@ export declare abstract class IntegrationRenderer<C = EcoPagesElement> {
|
|
|
350
319
|
routeOptions: RouteRendererOptions;
|
|
351
320
|
}): Promise<ComponentRenderResult | undefined>;
|
|
352
321
|
protected renderRouteBody(renderOptions: IntegrationRendererRenderOptions<C>): Promise<RouteRendererBody>;
|
|
353
|
-
protected
|
|
354
|
-
protected transformRouteResponse(response: Response, htmlContributions?: HtmlDocumentContribution[]): Promise<RouteRendererBody>;
|
|
322
|
+
protected transformRouteResponse(response: Response, htmlContributions?: HtmlDocumentContribution[], pagePackage?: PagePackageResult): Promise<RouteRendererBody>;
|
|
355
323
|
/**
|
|
356
324
|
* Prepares the render options for the integration renderer.
|
|
357
325
|
* It imports the page file, collects dependencies, and prepares the render options.
|
|
@@ -413,6 +381,8 @@ export declare abstract class IntegrationRenderer<C = EcoPagesElement> {
|
|
|
413
381
|
* other runtime coordination markers without relying on script sniffing.
|
|
414
382
|
*/
|
|
415
383
|
protected getDocumentAttributes(_renderOptions: IntegrationRendererRenderOptions<C>): Record<string, string> | undefined;
|
|
384
|
+
protected applyAttributesToFirstBodyElement(html: string, attributes: Record<string, string>): string;
|
|
385
|
+
protected applyAttributesToHtmlElement(html: string, attributes: Record<string, string>): string;
|
|
416
386
|
/**
|
|
417
387
|
* Returns declarative HTML fragments that core should inject into the final document.
|
|
418
388
|
*
|
|
@@ -451,12 +421,6 @@ export declare abstract class IntegrationRenderer<C = EcoPagesElement> {
|
|
|
451
421
|
* renderer's nested foreign-child handoff.
|
|
452
422
|
*/
|
|
453
423
|
renderComponentWithForeignChildren(input: ComponentRenderInput): Promise<ComponentRenderResult>;
|
|
454
|
-
/**
|
|
455
|
-
* Compatibility foreign-subtree contract that exposes a narrower payload shape for
|
|
456
|
-
* future route-composition work while preserving the current
|
|
457
|
-
* `renderComponentWithForeignChildren()` runtime semantics.
|
|
458
|
-
*/
|
|
459
|
-
renderForeignSubtree(input: ComponentRenderInput): Promise<ForeignSubtreeRenderPayload>;
|
|
460
424
|
private normalizeComponentRenderOutput;
|
|
461
425
|
protected normalizeUnresolvedMarkerArtifactHtml(html: string): string;
|
|
462
426
|
/**
|
|
@@ -7,18 +7,23 @@ import { HttpError } from "../../errors/http-error.js";
|
|
|
7
7
|
import { DependencyResolverService } from "../page-loading/dependency-resolver.js";
|
|
8
8
|
import { PageModuleLoaderService } from "../page-loading/page-module-loader.js";
|
|
9
9
|
import { OwnershipValidationService } from "./ownership-validation.service.js";
|
|
10
|
+
import { hasForeignChildDescendantsInGraph } from "./component-graph-collectors.js";
|
|
10
11
|
import {
|
|
11
12
|
RouteRenderOrchestrator
|
|
12
13
|
} from "./route-render-orchestrator.js";
|
|
13
|
-
import {
|
|
14
|
+
import { createIntegrationRouteRenderAdapter } from "./integration-route-render-adapter.js";
|
|
15
|
+
import { loadPageBrowserGraphContribution } from "./page-browser-graph-contribution.loader.js";
|
|
16
|
+
import { normalizeUnresolvedMarkerArtifactHtml, isMarkupNodeLike } from "./render-output.utils.js";
|
|
14
17
|
import {
|
|
15
18
|
ForeignSubtreeExecutionService
|
|
16
19
|
} from "./foreign-subtree-execution.service.js";
|
|
17
|
-
import {} from "./queued-foreign-subtree-resolution.service.js";
|
|
18
20
|
import { buildProcessedAssetDedupeKey } from "./processed-asset-dedupe.js";
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
import {
|
|
22
|
+
applyDocumentShellAttributeStamping,
|
|
23
|
+
composeDocumentShell,
|
|
24
|
+
renderPageDocumentShell
|
|
25
|
+
} from "./document-shell-render.service.js";
|
|
26
|
+
import { resolveInnermostPageLayout, resolvePageLayoutComponents } from "./layout-shell-props.service.js";
|
|
22
27
|
class IntegrationRenderer {
|
|
23
28
|
appConfig;
|
|
24
29
|
assetProcessingService;
|
|
@@ -31,7 +36,22 @@ class IntegrationRenderer {
|
|
|
31
36
|
pageModuleLoaderService;
|
|
32
37
|
routeRenderOrchestrator;
|
|
33
38
|
foreignSubtreeExecutionService = new ForeignSubtreeExecutionService();
|
|
39
|
+
/**
|
|
40
|
+
* Serializes route and view renders that mutate `htmlTransformer` state.
|
|
41
|
+
*
|
|
42
|
+
* Integration renderers are cached per integration, so concurrent static builds
|
|
43
|
+
* and overlapping SSR requests must not share one transformer page package.
|
|
44
|
+
*/
|
|
45
|
+
renderExclusiveChain = Promise.resolve();
|
|
34
46
|
DOC_TYPE = "<!DOCTYPE html>";
|
|
47
|
+
runRenderExclusive(operation) {
|
|
48
|
+
const run = this.renderExclusiveChain.then(operation, operation);
|
|
49
|
+
this.renderExclusiveChain = run.then(
|
|
50
|
+
() => void 0,
|
|
51
|
+
() => void 0
|
|
52
|
+
);
|
|
53
|
+
return run;
|
|
54
|
+
}
|
|
35
55
|
/**
|
|
36
56
|
* Loads one route module through the owning renderer's import path.
|
|
37
57
|
*
|
|
@@ -43,52 +63,6 @@ class IntegrationRenderer {
|
|
|
43
63
|
async loadPageModule(file, options) {
|
|
44
64
|
return this.importPageFile(file, options);
|
|
45
65
|
}
|
|
46
|
-
/**
|
|
47
|
-
* Reads the execution-scoped owning-renderer cache from one render input.
|
|
48
|
-
*
|
|
49
|
-
* Shared page/layout/document shell helpers pass one cache through
|
|
50
|
-
* `integrationContext` so repeated delegation to the same foreign integration
|
|
51
|
-
* can reuse a single initialized renderer instance during one render flow.
|
|
52
|
-
* The cache is deliberately scoped to the current render execution rather than
|
|
53
|
-
* stored on the renderer, which avoids leaking mutable integration state across
|
|
54
|
-
* requests while still preventing redundant renderer initialization.
|
|
55
|
-
*
|
|
56
|
-
* @param integrationContext - Optional render context carried with one render input.
|
|
57
|
-
* @returns The current execution cache when present.
|
|
58
|
-
*/
|
|
59
|
-
getOwningRendererCache(integrationContext) {
|
|
60
|
-
if (integrationContext?.rendererCache instanceof Map) {
|
|
61
|
-
return integrationContext.rendererCache;
|
|
62
|
-
}
|
|
63
|
-
return void 0;
|
|
64
|
-
}
|
|
65
|
-
getForeignOwnerIntegrationName(component) {
|
|
66
|
-
const integrationName = component.config?.integration ?? component.config?.__eco?.integration;
|
|
67
|
-
if (!integrationName || integrationName === this.name) {
|
|
68
|
-
return void 0;
|
|
69
|
-
}
|
|
70
|
-
return this.appConfig.integrations.some((integration) => integration.name === integrationName) ? integrationName : void 0;
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Attaches an execution-scoped owning-renderer cache to one render input.
|
|
74
|
-
*
|
|
75
|
-
* Foreign-owned page, layout, or document shells may delegate several times in
|
|
76
|
-
* the same render flow. Threading the cache through `integrationContext`
|
|
77
|
-
* preserves renderer reuse without changing the public render input contract.
|
|
78
|
-
* Existing integration-specific context is preserved and augmented.
|
|
79
|
-
*
|
|
80
|
-
* @param input - Original render input.
|
|
81
|
-
* @param rendererCache - Execution-scoped renderer cache to propagate.
|
|
82
|
-
* @returns Render input augmented with the shared renderer cache.
|
|
83
|
-
*/
|
|
84
|
-
withOwningRendererCache(input, rendererCache) {
|
|
85
|
-
const integrationContext = input.integrationContext;
|
|
86
|
-
const sharedRendererCache = rendererCache;
|
|
87
|
-
return {
|
|
88
|
-
...input,
|
|
89
|
-
integrationContext: integrationContext ? { ...integrationContext, rendererCache: sharedRendererCache } : { rendererCache: sharedRendererCache }
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
66
|
getRendererModuleValue(key) {
|
|
93
67
|
if (!this.rendererModules || typeof this.rendererModules !== "object") {
|
|
94
68
|
return void 0;
|
|
@@ -184,10 +158,11 @@ class IntegrationRenderer {
|
|
|
184
158
|
return await this.routeRenderOrchestrator.resolveDeclaredPageBrowserGraph({
|
|
185
159
|
routeFile: filePath,
|
|
186
160
|
integrationName: this.name,
|
|
187
|
-
collectContribution:
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
161
|
+
collectContribution: (routeFile) => loadPageBrowserGraphContribution(
|
|
162
|
+
routeFile,
|
|
163
|
+
(targetFile) => this.importPageFile(targetFile),
|
|
164
|
+
(context) => this.collectPageBrowserGraphContribution(context)
|
|
165
|
+
)
|
|
191
166
|
});
|
|
192
167
|
}
|
|
193
168
|
mergePageBrowserGraphIntoPagePackage(pageBrowserGraph) {
|
|
@@ -313,19 +288,25 @@ class IntegrationRenderer {
|
|
|
313
288
|
await this.prepareViewDependencies(input.view, input.layout);
|
|
314
289
|
const HtmlTemplate = await this.getHtmlTemplate();
|
|
315
290
|
const metadata = await this.resolveViewMetadata(input.view, input.props);
|
|
316
|
-
const { documentHtml } = await
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
291
|
+
const { documentHtml } = await composeDocumentShell(
|
|
292
|
+
{
|
|
293
|
+
renderComponentWithForeignChildren: (renderInput) => this.renderComponentWithForeignChildren(renderInput),
|
|
294
|
+
appendProcessedDependencies: (...assetGroups) => this.appendProcessedDependencies(...assetGroups)
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
primaryComponent: input.view,
|
|
298
|
+
primaryProps: normalizedProps,
|
|
299
|
+
layout: input.layout ? {
|
|
300
|
+
component: input.layout,
|
|
301
|
+
props: {}
|
|
302
|
+
} : void 0,
|
|
303
|
+
htmlTemplate: HtmlTemplate,
|
|
304
|
+
documentProps: {
|
|
305
|
+
metadata,
|
|
306
|
+
pageProps: normalizedProps
|
|
307
|
+
}
|
|
327
308
|
}
|
|
328
|
-
|
|
309
|
+
);
|
|
329
310
|
const html = await this.finalizeResolvedHtml({
|
|
330
311
|
html: `${this.DOC_TYPE}${documentHtml}`,
|
|
331
312
|
partial: false
|
|
@@ -345,59 +326,17 @@ class IntegrationRenderer {
|
|
|
345
326
|
* @returns Final serialized document HTML including the doctype prefix.
|
|
346
327
|
*/
|
|
347
328
|
async renderPageWithDocumentShell(input) {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
...input.documentProps ?? {}
|
|
357
|
-
}
|
|
358
|
-
});
|
|
359
|
-
const documentHtml = input.transformDocumentHtml ? input.transformDocumentHtml(composedDocumentHtml) : composedDocumentHtml;
|
|
360
|
-
return `${this.DOC_TYPE}${documentHtml}`;
|
|
361
|
-
}
|
|
362
|
-
async composeDocumentShell(input) {
|
|
363
|
-
const rendererCache = /* @__PURE__ */ new Map();
|
|
364
|
-
const primaryRender = await this.renderComponentWithForeignChildren({
|
|
365
|
-
component: input.primaryComponent,
|
|
366
|
-
props: input.primaryProps,
|
|
367
|
-
integrationContext: { rendererCache }
|
|
368
|
-
});
|
|
369
|
-
const layoutRender = input.layout ? await this.renderComponentWithForeignChildren({
|
|
370
|
-
component: input.layout.component,
|
|
371
|
-
props: input.layout.props ?? {},
|
|
372
|
-
children: primaryRender.html,
|
|
373
|
-
integrationContext: { rendererCache }
|
|
374
|
-
}) : void 0;
|
|
375
|
-
const documentRender = await this.renderComponentWithForeignChildren({
|
|
376
|
-
component: input.htmlTemplate,
|
|
377
|
-
props: input.documentProps,
|
|
378
|
-
children: layoutRender?.html ?? primaryRender.html,
|
|
379
|
-
integrationContext: { rendererCache }
|
|
380
|
-
});
|
|
381
|
-
this.appendProcessedDependencies(primaryRender.assets, layoutRender?.assets, documentRender.assets);
|
|
382
|
-
return {
|
|
383
|
-
documentHtml: documentRender.html
|
|
384
|
-
};
|
|
329
|
+
return renderPageDocumentShell(
|
|
330
|
+
{
|
|
331
|
+
renderComponentWithForeignChildren: (renderInput) => this.renderComponentWithForeignChildren(renderInput),
|
|
332
|
+
appendProcessedDependencies: (...assetGroups) => this.appendProcessedDependencies(...assetGroups)
|
|
333
|
+
},
|
|
334
|
+
input,
|
|
335
|
+
this.DOC_TYPE
|
|
336
|
+
);
|
|
385
337
|
}
|
|
386
|
-
/**
|
|
387
|
-
* Renders one string-first component with serialized children and collects its assets.
|
|
388
|
-
*
|
|
389
|
-
* String-oriented integrations frequently share the same component contract:
|
|
390
|
-
* pass serialized children through props, coerce the render result to HTML, and
|
|
391
|
-
* attach any component-scoped dependencies. This helper centralizes that flow
|
|
392
|
-
* so integrations can opt into shared orchestration without repeating the same
|
|
393
|
-
* string-render boilerplate.
|
|
394
|
-
*
|
|
395
|
-
* @param input - Component render input.
|
|
396
|
-
* @param component - String-oriented component implementation to execute.
|
|
397
|
-
* @returns Structured component render result for orchestration paths.
|
|
398
|
-
*/
|
|
399
338
|
async renderStringComponentWithSerializedChildren(input, component) {
|
|
400
|
-
const serializedChildren = input.children === void 0 ? void 0 : typeof input.children === "string" ? input.children : isMarkupNodeLike(input.children) ? input.children.outerHTML : void 0;
|
|
339
|
+
const serializedChildren = input.children === void 0 ? void 0 : typeof input.children === "string" ? input.children : isMarkupNodeLike(input.children) && typeof input.children.outerHTML === "string" ? input.children.outerHTML : void 0;
|
|
401
340
|
if (input.children !== void 0 && serializedChildren === void 0) {
|
|
402
341
|
const componentFile = input.component.config?.__eco?.file ?? "unknown component";
|
|
403
342
|
const childTag = Object.prototype.toString.call(input.children);
|
|
@@ -438,6 +377,18 @@ class IntegrationRenderer {
|
|
|
438
377
|
this.getForeignSubtreeResolutionContextKey()
|
|
439
378
|
);
|
|
440
379
|
}
|
|
380
|
+
async resolveQueuedForeignSubtreeHtml(html, runtimeContext, renderQueuedChildren, queueLabel = this.name) {
|
|
381
|
+
return this.foreignSubtreeExecutionService.resolveQueuedHtml({
|
|
382
|
+
currentIntegrationName: this.name,
|
|
383
|
+
html,
|
|
384
|
+
runtimeContext,
|
|
385
|
+
queueLabel,
|
|
386
|
+
getOwningRenderer: (integrationName, rendererCache) => this.getIntegrationRendererForName(integrationName, rendererCache),
|
|
387
|
+
applyAttributesToFirstElement: (resolvedHtml, attributes) => this.htmlTransformer.applyAttributesToFirstElement(resolvedHtml, attributes),
|
|
388
|
+
dedupeProcessedAssets: (assets) => this.htmlTransformer.dedupeProcessedAssets(assets),
|
|
389
|
+
renderQueuedChildren
|
|
390
|
+
});
|
|
391
|
+
}
|
|
441
392
|
/**
|
|
442
393
|
* Renders a string-first component, then resolves any queued foreign
|
|
443
394
|
* boundaries before returning final component HTML.
|
|
@@ -533,7 +484,7 @@ class IntegrationRenderer {
|
|
|
533
484
|
* @returns The imported module.
|
|
534
485
|
*/
|
|
535
486
|
async importPageFile(file, options) {
|
|
536
|
-
const bypassCache = options?.bypassCache ??
|
|
487
|
+
const bypassCache = options?.bypassCache ?? false;
|
|
537
488
|
const pageModule = this.usesIntegrationPageImporter(file) ? await this.importIntegrationPageFile(file, {
|
|
538
489
|
bypassCache,
|
|
539
490
|
cacheScope: options?.cacheScope
|
|
@@ -622,19 +573,20 @@ class IntegrationRenderer {
|
|
|
622
573
|
* subclasses continue to override protected renderer behavior directly.
|
|
623
574
|
*/
|
|
624
575
|
createRouteRenderOrchestratorAdapter() {
|
|
625
|
-
return {
|
|
576
|
+
return createIntegrationRouteRenderAdapter({
|
|
626
577
|
name: this.name,
|
|
627
578
|
resolveRouteRenderInputs: (routeOptions) => this.resolveRouteRenderInputs(routeOptions),
|
|
628
579
|
resolveRouteDependencies: (input) => this.resolveRouteDependencies(input),
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
return await this.collectPageBrowserGraphContribution({ file: routeFile, pageModule });
|
|
632
|
-
},
|
|
580
|
+
importPageFile: (file) => this.importPageFile(file),
|
|
581
|
+
collectPageBrowserGraphContribution: (context) => this.collectPageBrowserGraphContribution(context),
|
|
633
582
|
resolveRoutePageComponentRender: (input) => this.resolveRoutePageComponentRender(input),
|
|
634
583
|
renderRouteBody: (renderOptions) => this.renderRouteBody(renderOptions),
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
584
|
+
getDocumentAttributes: (renderOptions) => this.getDocumentAttributes(renderOptions),
|
|
585
|
+
getHtmlDocumentContributions: (options) => this.getHtmlDocumentContributions(options),
|
|
586
|
+
applyAttributesToFirstBodyElement: (html, attributes) => this.applyAttributesToFirstBodyElement(html, attributes),
|
|
587
|
+
applyAttributesToHtmlElement: (html, attributes) => this.applyAttributesToHtmlElement(html, attributes),
|
|
588
|
+
transformRouteResponse: (response, htmlContributions, pagePackage) => this.transformRouteResponse(response, htmlContributions, pagePackage)
|
|
589
|
+
});
|
|
638
590
|
}
|
|
639
591
|
async resolveRouteRenderInputs(routeOptions) {
|
|
640
592
|
const pageModule = await this.pageModuleLoaderService.resolvePageModule({
|
|
@@ -643,7 +595,8 @@ class IntegrationRenderer {
|
|
|
643
595
|
});
|
|
644
596
|
const { Page, integrationSpecificProps } = pageModule;
|
|
645
597
|
const HtmlTemplate = await this.getHtmlTemplate();
|
|
646
|
-
const
|
|
598
|
+
const Layouts = resolvePageLayoutComponents(Page.config?.layouts);
|
|
599
|
+
const Layout = resolveInnermostPageLayout(Layouts);
|
|
647
600
|
const { props, metadata } = await this.pageModuleLoaderService.resolvePageData({
|
|
648
601
|
pageModule,
|
|
649
602
|
routeOptions
|
|
@@ -651,7 +604,9 @@ class IntegrationRenderer {
|
|
|
651
604
|
return {
|
|
652
605
|
Page,
|
|
653
606
|
HtmlTemplate,
|
|
607
|
+
Layouts,
|
|
654
608
|
Layout,
|
|
609
|
+
layoutEntries: Page.config?.layoutEntries,
|
|
655
610
|
props,
|
|
656
611
|
metadata,
|
|
657
612
|
integrationSpecificProps
|
|
@@ -681,33 +636,13 @@ class IntegrationRenderer {
|
|
|
681
636
|
async renderRouteBody(renderOptions) {
|
|
682
637
|
return this.render(renderOptions);
|
|
683
638
|
}
|
|
684
|
-
|
|
685
|
-
const
|
|
686
|
-
const
|
|
687
|
-
|
|
688
|
-
const hasStructuralFinalization = componentRootAttributes && Object.keys(componentRootAttributes).length > 0 || documentAttributes && Object.keys(documentAttributes).length > 0;
|
|
689
|
-
if (!hasStructuralFinalization && (!htmlContributions || htmlContributions.length === 0)) {
|
|
690
|
-
return {};
|
|
691
|
-
}
|
|
692
|
-
return {
|
|
639
|
+
async transformRouteResponse(response, htmlContributions, pagePackage) {
|
|
640
|
+
const resolvedPagePackage = this.htmlTransformer.getPagePackage() ?? pagePackage;
|
|
641
|
+
const transformedResponse = await this.htmlTransformer.transform(
|
|
642
|
+
response,
|
|
693
643
|
htmlContributions,
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
if (componentRootAttributes) {
|
|
697
|
-
renderedHtml = this.htmlTransformer.applyAttributesToFirstBodyElement(
|
|
698
|
-
renderedHtml,
|
|
699
|
-
componentRootAttributes
|
|
700
|
-
);
|
|
701
|
-
}
|
|
702
|
-
if (documentAttributes) {
|
|
703
|
-
renderedHtml = this.htmlTransformer.applyAttributesToHtmlElement(renderedHtml, documentAttributes);
|
|
704
|
-
}
|
|
705
|
-
return renderedHtml;
|
|
706
|
-
}
|
|
707
|
-
};
|
|
708
|
-
}
|
|
709
|
-
async transformRouteResponse(response, htmlContributions) {
|
|
710
|
-
const transformedResponse = await this.htmlTransformer.transform(response, htmlContributions);
|
|
644
|
+
resolvedPagePackage
|
|
645
|
+
);
|
|
711
646
|
return transformedResponse.body ?? await transformedResponse.text();
|
|
712
647
|
}
|
|
713
648
|
/**
|
|
@@ -752,9 +687,12 @@ class IntegrationRenderer {
|
|
|
752
687
|
* @returns Rendered route body plus effective cache strategy.
|
|
753
688
|
*/
|
|
754
689
|
async execute(options) {
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
690
|
+
return this.runRenderExclusive(async () => {
|
|
691
|
+
this.htmlTransformer.setProcessedDependencies([]);
|
|
692
|
+
const adapter = this.createRouteRenderOrchestratorAdapter();
|
|
693
|
+
const renderOptions = await this.prepareRenderOptions(options, adapter);
|
|
694
|
+
return this.routeRenderOrchestrator.executePrepared(renderOptions, adapter);
|
|
695
|
+
});
|
|
758
696
|
}
|
|
759
697
|
/**
|
|
760
698
|
* Finalizes already-resolved HTML for explicit renderer-owned paths.
|
|
@@ -766,13 +704,17 @@ class IntegrationRenderer {
|
|
|
766
704
|
async finalizeResolvedHtml(options) {
|
|
767
705
|
const rendererBootstrapDependencies = this.getRendererBootstrapDependencies(options.partial);
|
|
768
706
|
this.appendProcessedDependencies(rendererBootstrapDependencies);
|
|
769
|
-
let html =
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
707
|
+
let html = applyDocumentShellAttributeStamping(
|
|
708
|
+
options.html,
|
|
709
|
+
{
|
|
710
|
+
applyAttributesToFirstBodyElement: (nextHtml, attributes) => this.htmlTransformer.applyAttributesToFirstBodyElement(nextHtml, attributes),
|
|
711
|
+
applyAttributesToHtmlElement: (nextHtml, attributes) => this.htmlTransformer.applyAttributesToHtmlElement(nextHtml, attributes)
|
|
712
|
+
},
|
|
713
|
+
{
|
|
714
|
+
componentRootAttributes: options.componentRootAttributes,
|
|
715
|
+
documentAttributes: options.documentAttributes
|
|
716
|
+
}
|
|
717
|
+
);
|
|
776
718
|
const shouldTransform = options.transformHtml ?? !options.partial;
|
|
777
719
|
if (!shouldTransform) {
|
|
778
720
|
return html;
|
|
@@ -797,6 +739,12 @@ class IntegrationRenderer {
|
|
|
797
739
|
getDocumentAttributes(_renderOptions) {
|
|
798
740
|
return void 0;
|
|
799
741
|
}
|
|
742
|
+
applyAttributesToFirstBodyElement(html, attributes) {
|
|
743
|
+
return this.htmlTransformer.applyAttributesToFirstBodyElement(html, attributes);
|
|
744
|
+
}
|
|
745
|
+
applyAttributesToHtmlElement(html, attributes) {
|
|
746
|
+
return this.htmlTransformer.applyAttributesToHtmlElement(html, attributes);
|
|
747
|
+
}
|
|
800
748
|
/**
|
|
801
749
|
* Returns declarative HTML fragments that core should inject into the final document.
|
|
802
750
|
*
|
|
@@ -859,22 +807,6 @@ class IntegrationRenderer {
|
|
|
859
807
|
getOwningRenderer: (integrationName, rendererCache) => this.getIntegrationRendererForName(integrationName, rendererCache)
|
|
860
808
|
});
|
|
861
809
|
}
|
|
862
|
-
/**
|
|
863
|
-
* Compatibility foreign-subtree contract that exposes a narrower payload shape for
|
|
864
|
-
* future route-composition work while preserving the current
|
|
865
|
-
* `renderComponentWithForeignChildren()` runtime semantics.
|
|
866
|
-
*/
|
|
867
|
-
async renderForeignSubtree(input) {
|
|
868
|
-
const result = await this.renderComponentWithForeignChildren(input);
|
|
869
|
-
return {
|
|
870
|
-
html: result.html,
|
|
871
|
-
assets: result.assets ?? [],
|
|
872
|
-
rootTag: result.rootTag,
|
|
873
|
-
rootAttributes: result.rootAttributes,
|
|
874
|
-
attachmentPolicy: result.canAttachAttributes ? { kind: "first-element" } : { kind: "none" },
|
|
875
|
-
integrationName: result.integrationName
|
|
876
|
-
};
|
|
877
|
-
}
|
|
878
810
|
normalizeComponentRenderOutput(result) {
|
|
879
811
|
const normalizedHtml = this.normalizeUnresolvedMarkerArtifactHtml(result.html);
|
|
880
812
|
return normalizedHtml === result.html ? result : {
|
|
@@ -893,21 +825,7 @@ class IntegrationRenderer {
|
|
|
893
825
|
* directly without paying the queue orchestration cost.
|
|
894
826
|
*/
|
|
895
827
|
hasForeignChildDescendants(component) {
|
|
896
|
-
|
|
897
|
-
const seen = /* @__PURE__ */ new Set();
|
|
898
|
-
while (stack.length > 0) {
|
|
899
|
-
const current = stack.pop();
|
|
900
|
-
if (!current || seen.has(current)) {
|
|
901
|
-
continue;
|
|
902
|
-
}
|
|
903
|
-
seen.add(current);
|
|
904
|
-
const integrationName = current.config?.integration ?? current.config?.__eco?.integration;
|
|
905
|
-
if (integrationName && integrationName !== this.name) {
|
|
906
|
-
return true;
|
|
907
|
-
}
|
|
908
|
-
stack.push(...current.config?.dependencies?.components ?? []);
|
|
909
|
-
}
|
|
910
|
-
return false;
|
|
828
|
+
return hasForeignChildDescendantsInGraph(component, this.name);
|
|
911
829
|
}
|
|
912
830
|
/**
|
|
913
831
|
* Render a single component and return structured output for orchestration paths.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ProcessedAsset } from '../../services/assets/asset-processing-service/index.js';
|
|
2
|
+
import type { HtmlDocumentContribution } from '../../services/html/html-transformer.service.js';
|
|
3
|
+
import type { ComponentRenderResult, EcoComponent, EcoPageFile, IntegrationRendererRenderOptions, PageBrowserGraphContribution, PageBrowserGraphContributionContext, PagePackageResult, RouteRendererBody, RouteRendererOptions } from '../../types/public-types.js';
|
|
4
|
+
import type { RouteHtmlFinalization, RouteRenderOrchestratorAdapter, RouteRenderOrchestratorResolvedInputs } from './route-render-orchestrator.js';
|
|
5
|
+
/**
|
|
6
|
+
* Host surface required to build the orchestrator adapter for one integration renderer.
|
|
7
|
+
*/
|
|
8
|
+
export type IntegrationRouteRenderAdapterHost<C> = {
|
|
9
|
+
readonly name: string;
|
|
10
|
+
resolveRouteRenderInputs(routeOptions: RouteRendererOptions): Promise<RouteRenderOrchestratorResolvedInputs>;
|
|
11
|
+
resolveRouteDependencies(input: {
|
|
12
|
+
components: (EcoComponent | Partial<EcoComponent>)[];
|
|
13
|
+
}): Promise<{
|
|
14
|
+
resolvedDependencies: ProcessedAsset[];
|
|
15
|
+
}>;
|
|
16
|
+
importPageFile(file: string): Promise<EcoPageFile>;
|
|
17
|
+
collectPageBrowserGraphContribution(context: PageBrowserGraphContributionContext): Promise<PageBrowserGraphContribution | undefined>;
|
|
18
|
+
resolveRoutePageComponentRender(input: {
|
|
19
|
+
Page: EcoComponent;
|
|
20
|
+
Layout?: EcoComponent;
|
|
21
|
+
props: Record<string, unknown>;
|
|
22
|
+
routeOptions: RouteRendererOptions;
|
|
23
|
+
}): Promise<ComponentRenderResult | undefined>;
|
|
24
|
+
renderRouteBody(renderOptions: IntegrationRendererRenderOptions<C>): Promise<RouteRendererBody>;
|
|
25
|
+
getDocumentAttributes(renderOptions: IntegrationRendererRenderOptions<C>): Record<string, string> | undefined;
|
|
26
|
+
getHtmlDocumentContributions(options: {
|
|
27
|
+
renderOptions: IntegrationRendererRenderOptions<C>;
|
|
28
|
+
partial: boolean;
|
|
29
|
+
}): HtmlDocumentContribution[] | undefined;
|
|
30
|
+
applyAttributesToFirstBodyElement(html: string, attributes: Record<string, string>): string;
|
|
31
|
+
applyAttributesToHtmlElement(html: string, attributes: Record<string, string>): string;
|
|
32
|
+
transformRouteResponse(response: Response, htmlContributions?: HtmlDocumentContribution[], pagePackage?: PagePackageResult): Promise<RouteRendererBody>;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Builds the internal route-render adapter consumed by `RouteRenderOrchestrator`.
|
|
36
|
+
*/
|
|
37
|
+
export declare function createIntegrationRouteRenderAdapter<C>(host: IntegrationRouteRenderAdapterHost<C>): RouteRenderOrchestratorAdapter<C>;
|
|
38
|
+
export type { RouteHtmlFinalization };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { loadPageBrowserGraphContribution } from "./page-browser-graph-contribution.loader.js";
|
|
2
|
+
import { buildRouteHtmlFinalization } from "./route-html-finalization.service.js";
|
|
3
|
+
function createIntegrationRouteRenderAdapter(host) {
|
|
4
|
+
return {
|
|
5
|
+
name: host.name,
|
|
6
|
+
resolveRouteRenderInputs: (routeOptions) => host.resolveRouteRenderInputs(routeOptions),
|
|
7
|
+
resolveRouteDependencies: (input) => host.resolveRouteDependencies(input),
|
|
8
|
+
collectPageBrowserGraphContribution: (routeFile) => loadPageBrowserGraphContribution(
|
|
9
|
+
routeFile,
|
|
10
|
+
(file) => host.importPageFile(file),
|
|
11
|
+
(context) => host.collectPageBrowserGraphContribution(context)
|
|
12
|
+
),
|
|
13
|
+
resolveRoutePageComponentRender: (input) => host.resolveRoutePageComponentRender(input),
|
|
14
|
+
renderRouteBody: (renderOptions) => host.renderRouteBody(renderOptions),
|
|
15
|
+
getRouteHtmlFinalization: (renderOptions) => buildRouteHtmlFinalization({
|
|
16
|
+
renderOptions,
|
|
17
|
+
getDocumentAttributes: (options) => host.getDocumentAttributes(options),
|
|
18
|
+
getHtmlDocumentContributions: (options) => host.getHtmlDocumentContributions(options),
|
|
19
|
+
applyAttributesToFirstBodyElement: (html, attributes) => host.applyAttributesToFirstBodyElement(html, attributes),
|
|
20
|
+
applyAttributesToHtmlElement: (html, attributes) => host.applyAttributesToHtmlElement(html, attributes)
|
|
21
|
+
}),
|
|
22
|
+
transformRouteResponse: (response, htmlContributions, pagePackage) => host.transformRouteResponse(response, htmlContributions, pagePackage)
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export {
|
|
26
|
+
createIntegrationRouteRenderAdapter
|
|
27
|
+
};
|