@ecopages/core 0.2.0-alpha.8 → 0.2.1-beta.0
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 +79 -28
- package/package.json +94 -116
- package/src/adapters/README.md +2 -2
- package/src/adapters/abstract/application-adapter.d.ts +28 -2
- package/src/adapters/abstract/application-adapter.js +14 -2
- package/src/adapters/abstract/router-adapter.d.ts +1 -1
- package/src/adapters/abstract/server-adapter.d.ts +2 -2
- package/src/adapters/bun/client-bridge.d.ts +1 -1
- package/src/adapters/bun/create-app.d.ts +12 -12
- package/src/adapters/bun/create-app.js +64 -41
- package/src/adapters/bun/hmr-manager.d.ts +19 -115
- package/src/adapters/bun/hmr-manager.js +25 -301
- package/src/adapters/bun/index.d.ts +1 -1
- package/src/adapters/bun/index.js +2 -2
- package/src/adapters/bun/runtime-host.d.ts +52 -0
- package/src/adapters/bun/runtime-host.js +56 -0
- package/src/adapters/bun/server-adapter.d.ts +100 -32
- package/src/adapters/bun/server-adapter.js +142 -65
- package/src/adapters/bun/static-preview-host.d.ts +28 -0
- package/src/adapters/bun/static-preview-host.js +45 -0
- package/src/{create-app.d.ts → adapters/create-app.d.ts} +9 -6
- package/src/{create-app.js → adapters/create-app.js} +4 -4
- package/src/adapters/index.d.ts +1 -5
- package/src/adapters/index.js +1 -7
- package/src/adapters/node/create-app.d.ts +15 -12
- package/src/adapters/node/create-app.js +34 -85
- package/src/adapters/node/http-request-bridge.d.ts +57 -0
- package/src/adapters/node/http-request-bridge.js +118 -0
- package/src/adapters/node/node-client-bridge.d.ts +1 -1
- package/src/adapters/node/node-hmr-manager.d.ts +22 -103
- package/src/adapters/node/node-hmr-manager.js +26 -289
- package/src/adapters/node/runtime-host.d.ts +57 -0
- package/src/adapters/node/runtime-host.js +92 -0
- package/src/adapters/node/server-adapter-dependencies.d.ts +19 -0
- package/src/adapters/node/server-adapter-dependencies.js +18 -0
- package/src/adapters/node/server-adapter.d.ts +19 -42
- package/src/adapters/node/server-adapter.js +94 -139
- package/src/adapters/node/static-content-server.d.ts +1 -1
- package/src/adapters/node/static-content-server.js +1 -1
- package/src/adapters/node/static-preview-host.d.ts +55 -0
- package/src/adapters/node/static-preview-host.js +68 -0
- package/src/adapters/shared/application-adapter.d.ts +1 -1
- package/src/adapters/shared/define-api-handler.d.ts +1 -1
- package/src/adapters/shared/explicit-static-render-preparation.d.ts +25 -0
- package/src/adapters/shared/explicit-static-render-preparation.js +26 -0
- package/src/adapters/shared/explicit-static-route-matcher.d.ts +7 -4
- package/src/adapters/shared/explicit-static-route-matcher.js +14 -16
- package/src/adapters/shared/file-route-middleware-pipeline.d.ts +7 -10
- package/src/adapters/shared/file-route-middleware-pipeline.js +2 -11
- package/src/adapters/shared/fs-server-response-factory.d.ts +14 -10
- package/src/adapters/shared/fs-server-response-factory.js +11 -27
- package/src/adapters/shared/fs-server-response-matcher.d.ts +18 -18
- package/src/adapters/shared/fs-server-response-matcher.js +72 -46
- package/src/adapters/shared/hmr-entrypoint-registrar.js +1 -1
- package/src/adapters/shared/hmr-html-response.d.ts +1 -1
- package/src/adapters/shared/hmr-html-response.js +4 -3
- package/src/adapters/shared/render-context.d.ts +5 -3
- package/src/adapters/shared/render-context.js +24 -1
- package/src/adapters/shared/runtime-app-bootstrap.d.ts +26 -0
- package/src/adapters/shared/runtime-app-bootstrap.js +46 -0
- package/src/adapters/shared/runtime-host.d.ts +12 -0
- package/src/adapters/shared/server-adapter.d.ts +22 -11
- package/src/adapters/shared/server-adapter.js +183 -133
- package/src/adapters/shared/server-route-handler.d.ts +5 -5
- package/src/adapters/shared/server-route-handler.js +4 -4
- package/src/adapters/shared/server-static-builder.d.ts +8 -7
- package/src/adapters/shared/server-static-builder.js +6 -5
- package/src/adapters/shared/shared-hmr-manager.d.ts +59 -0
- package/src/adapters/shared/shared-hmr-manager.js +241 -0
- package/src/adapters/shared/static-preview-host.d.ts +10 -0
- package/src/build/README.md +57 -67
- package/src/build/browser-runtime-manifest.d.ts +31 -0
- package/src/build/browser-runtime-manifest.js +61 -0
- package/src/build/browser-runtime-plugin-helpers.d.ts +26 -0
- package/src/build/browser-runtime-plugin-helpers.js +14 -0
- package/src/build/browser-runtime-plugin.d.ts +78 -0
- package/src/build/browser-runtime-plugin.js +173 -0
- package/src/build/build-adapter.d.ts +384 -63
- package/src/build/build-adapter.js +129 -54
- package/src/build/build-manifest.d.ts +6 -0
- package/src/build/build-manifest.js +21 -2
- package/src/build/build-types.d.ts +2 -2
- package/src/build/rolldown-adapter-helpers.d.ts +58 -0
- package/src/build/rolldown-adapter-helpers.js +265 -0
- package/src/build/rolldown-build-adapter.d.ts +28 -0
- package/src/build/rolldown-build-adapter.js +65 -0
- package/src/build/rolldown-dev-build-adapter.d.ts +82 -0
- package/src/build/rolldown-dev-build-adapter.js +166 -0
- package/src/build/rolldown-plugin-bridge.d.ts +59 -0
- package/src/build/rolldown-plugin-bridge.js +199 -0
- package/src/build/runtime-build-executor.d.ts +15 -7
- package/src/build/runtime-build-executor.js +8 -9
- package/src/build/runtime-build-output-normalizer.d.ts +3 -0
- package/src/build/runtime-build-output-normalizer.js +111 -0
- package/src/build/serialized-build-executor.d.ts +64 -0
- package/src/build/serialized-build-executor.js +63 -0
- package/src/build/server-side-css-shim-plugin.d.ts +41 -0
- package/src/build/server-side-css-shim-plugin.js +35 -0
- package/src/cache/index.d.ts +6 -0
- package/src/cache/index.js +6 -0
- package/src/cache/module-parse-cache.d.ts +65 -0
- package/src/cache/module-parse-cache.js +75 -0
- package/src/config/README.md +5 -2
- package/src/config/config-builder.d.ts +41 -13
- package/src/config/config-builder.js +62 -24
- package/src/declarations.d.ts +1 -1
- package/src/dev/host-runtime.d.ts +10 -0
- package/src/dev/host-runtime.js +24 -0
- package/src/dev/sc-server.d.ts +1 -1
- package/src/dev/sc-server.js +1 -1
- package/src/eco/eco.browser.d.ts +2 -0
- package/src/eco/eco.browser.js +88 -0
- package/src/eco/eco.js +50 -45
- package/src/eco/eco.types.d.ts +60 -8
- package/src/eco/eco.utils.d.ts +1 -40
- package/src/eco/eco.utils.js +5 -35
- package/src/eco/global-injector-map.d.ts +3 -3
- package/src/eco/global-injector-map.js +2 -2
- package/src/eco/lazy-injector-map.d.ts +2 -2
- package/src/errors/index.d.ts +1 -0
- package/src/errors/index.js +3 -1
- package/src/hmr/client/hmr-runtime.js +9 -1
- package/src/hmr/hmr-strategy.d.ts +16 -13
- package/src/hmr/hmr-strategy.js +22 -7
- package/src/hmr/strategies/default-hmr-strategy.d.ts +2 -2
- package/src/hmr/strategies/default-hmr-strategy.js +1 -1
- package/src/hmr/strategies/js-hmr-strategy.d.ts +4 -9
- package/src/hmr/strategies/js-hmr-strategy.js +5 -10
- package/src/index.browser.d.ts +2 -2
- package/src/index.browser.js +1 -1
- package/src/index.d.ts +3 -2
- package/src/index.js +15 -4
- package/src/integrations/ghtml/ghtml-renderer.d.ts +2 -1
- package/src/integrations/ghtml/ghtml-renderer.js +24 -29
- package/src/integrations/ghtml/ghtml.constants.d.ts +1 -0
- package/src/integrations/ghtml/ghtml.constants.js +4 -0
- package/src/integrations/ghtml/ghtml.plugin.d.ts +2 -6
- package/src/integrations/ghtml/ghtml.plugin.js +3 -4
- package/src/plugins/README.md +1 -0
- package/src/plugins/alias-resolver-cache.d.ts +68 -0
- package/src/plugins/alias-resolver-cache.js +106 -0
- package/src/plugins/alias-resolver-plugin.d.ts +5 -1
- package/src/plugins/alias-resolver-plugin.js +19 -7
- package/src/plugins/eco-component-meta-plugin.d.ts +12 -1
- package/src/plugins/eco-component-meta-plugin.js +43 -25
- package/src/plugins/foreign-jsx-override-plugin.d.ts +33 -0
- package/src/plugins/foreign-jsx-override-plugin.js +41 -0
- package/src/plugins/integration-plugin.d.ts +136 -42
- package/src/plugins/integration-plugin.js +99 -31
- package/src/plugins/processor.d.ts +4 -2
- package/src/plugins/processor.js +8 -3
- package/src/plugins/source-transform.d.ts +46 -0
- package/src/plugins/source-transform.js +71 -0
- package/src/route-renderer/GRAPH.md +80 -318
- package/src/route-renderer/README.md +74 -78
- package/src/route-renderer/orchestration/component-render-context.d.ts +97 -0
- package/src/route-renderer/orchestration/component-render-context.js +147 -0
- package/src/route-renderer/orchestration/declared-ownership-graph.d.ts +18 -0
- package/src/route-renderer/orchestration/declared-ownership-graph.js +34 -0
- package/src/route-renderer/orchestration/foreign-subtree-execution.service.d.ts +110 -0
- package/src/route-renderer/orchestration/foreign-subtree-execution.service.js +233 -0
- package/src/route-renderer/orchestration/integration-renderer.d.ts +290 -128
- package/src/route-renderer/orchestration/integration-renderer.js +660 -258
- package/src/route-renderer/orchestration/ownership-planning.service.d.ts +24 -0
- package/src/route-renderer/orchestration/ownership-planning.service.js +63 -0
- package/src/route-renderer/orchestration/ownership-validation.service.d.ts +29 -0
- package/src/route-renderer/orchestration/ownership-validation.service.js +53 -0
- package/src/route-renderer/orchestration/processed-asset-dedupe.d.ts +3 -0
- package/src/route-renderer/orchestration/processed-asset-dedupe.js +27 -0
- package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.d.ts +91 -0
- package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.js +170 -0
- package/src/route-renderer/orchestration/render-output.utils.d.ts +66 -0
- package/src/route-renderer/orchestration/render-output.utils.js +171 -0
- package/src/route-renderer/orchestration/route-render-orchestrator.d.ts +156 -0
- package/src/route-renderer/orchestration/route-render-orchestrator.js +577 -0
- package/src/route-renderer/orchestration/template-serialization.d.ts +38 -0
- package/src/route-renderer/orchestration/template-serialization.js +45 -0
- package/src/route-renderer/page-loading/component-dependency-collection.d.ts +37 -0
- package/src/route-renderer/page-loading/component-dependency-collection.js +132 -0
- package/src/route-renderer/page-loading/declared-asset-collection.d.ts +24 -0
- package/src/route-renderer/page-loading/declared-asset-collection.js +106 -0
- package/src/route-renderer/page-loading/dependency-resolver.d.ts +2 -2
- package/src/route-renderer/page-loading/dependency-resolver.js +27 -354
- package/src/route-renderer/page-loading/ecopages-virtual-imports.d.ts +11 -0
- package/src/route-renderer/page-loading/ecopages-virtual-imports.js +57 -0
- package/src/route-renderer/page-loading/lazy-entry-collection.d.ts +45 -0
- package/src/route-renderer/page-loading/lazy-entry-collection.js +105 -0
- package/src/route-renderer/page-loading/lazy-trigger-planning.d.ts +19 -0
- package/src/route-renderer/page-loading/lazy-trigger-planning.js +40 -0
- package/src/route-renderer/page-loading/module-declaration-aggregation.d.ts +5 -0
- package/src/route-renderer/page-loading/module-declaration-aggregation.js +33 -0
- package/src/route-renderer/page-loading/module-declaration-scripts.d.ts +3 -0
- package/src/route-renderer/page-loading/module-declaration-scripts.js +18 -0
- package/src/route-renderer/page-loading/page-dependency-bundling.d.ts +13 -0
- package/src/route-renderer/page-loading/page-dependency-bundling.js +137 -0
- package/src/route-renderer/page-loading/page-module-loader.d.ts +7 -4
- package/src/route-renderer/page-loading/page-module-loader.js +8 -5
- package/src/route-renderer/route-renderer.d.ts +31 -23
- package/src/route-renderer/route-renderer.js +17 -24
- package/src/router/README.md +76 -8
- package/src/router/client/navigation-coordinator.d.ts +20 -0
- package/src/router/client/navigation-coordinator.js +2 -2
- package/src/router/server/route-registry.d.ts +78 -0
- package/src/router/server/route-registry.js +262 -0
- package/src/services/README.md +1 -2
- package/src/services/assets/asset-processing-service/asset-dependency-keys.d.ts +3 -0
- package/src/services/assets/asset-processing-service/asset-dependency-keys.js +56 -0
- package/src/services/assets/asset-processing-service/asset-processing.service.d.ts +3 -20
- package/src/services/assets/asset-processing-service/asset-processing.service.js +52 -98
- package/src/services/assets/asset-processing-service/asset.factory.d.ts +1 -1
- package/src/services/assets/asset-processing-service/asset.factory.js +2 -2
- package/src/services/assets/asset-processing-service/assets.types.d.ts +14 -0
- package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.d.ts +2 -0
- package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +1 -0
- package/src/services/assets/asset-processing-service/grouped-content-bundles.d.ts +30 -0
- package/src/services/assets/asset-processing-service/grouped-content-bundles.js +65 -0
- package/src/services/assets/asset-processing-service/index.d.ts +6 -5
- package/src/services/assets/asset-processing-service/index.js +6 -5
- package/src/services/assets/asset-processing-service/page-package.d.ts +6 -0
- package/src/services/assets/asset-processing-service/page-package.js +80 -0
- package/src/services/assets/asset-processing-service/processor.interface.d.ts +2 -2
- package/src/services/assets/asset-processing-service/processor.registry.d.ts +2 -2
- package/src/services/assets/asset-processing-service/processors/base/base-processor.d.ts +1 -1
- package/src/services/assets/asset-processing-service/processors/base/base-processor.js +3 -2
- package/src/services/assets/asset-processing-service/processors/base/base-script-processor.d.ts +10 -5
- package/src/services/assets/asset-processing-service/processors/base/base-script-processor.js +69 -5
- package/src/services/assets/asset-processing-service/processors/index.d.ts +5 -5
- package/src/services/assets/asset-processing-service/processors/index.js +5 -5
- package/src/services/assets/asset-processing-service/processors/script/content-script.processor.d.ts +3 -2
- package/src/services/assets/asset-processing-service/processors/script/content-script.processor.js +66 -3
- package/src/services/assets/asset-processing-service/processors/script/file-script.processor.d.ts +4 -3
- package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +27 -6
- package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.d.ts +38 -3
- package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +57 -6
- package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.d.ts +5 -2
- package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +39 -5
- package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.d.ts +2 -2
- package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +5 -2
- package/src/services/assets/asset-processing-service/ungrouped-dependency-processing.d.ts +18 -0
- package/src/services/assets/asset-processing-service/ungrouped-dependency-processing.js +45 -0
- package/src/services/assets/browser-bundle.service.d.ts +44 -3
- package/src/services/assets/browser-bundle.service.js +15 -7
- package/src/services/html/html-rewriter-provider.service.d.ts +3 -0
- package/src/services/html/html-rewriter-provider.service.js +4 -1
- package/src/services/html/html-transformer.service.d.ts +22 -3
- package/src/services/html/html-transformer.service.js +101 -35
- package/src/services/invalidation/development-invalidation.service.d.ts +1 -1
- package/src/services/invalidation/development-invalidation.service.js +1 -0
- package/src/services/module-loading/app-module-loader.service.d.ts +7 -0
- package/src/services/module-loading/app-module-loader.service.js +0 -0
- package/src/services/module-loading/app-server-module-transpiler.service.d.ts +9 -1
- package/src/services/module-loading/app-server-module-transpiler.service.js +102 -6
- package/src/services/module-loading/host-module-loader-registry.d.ts +4 -0
- package/src/services/module-loading/host-module-loader-registry.js +15 -0
- package/src/services/module-loading/module-loading-types.d.ts +2 -0
- package/src/services/module-loading/module-loading-types.js +0 -0
- package/src/services/module-loading/page-module-import.service.d.ts +32 -8
- package/src/services/module-loading/page-module-import.service.js +83 -22
- package/src/services/module-loading/server-module-transpiler.service.d.ts +8 -14
- package/src/services/module-loading/server-module-transpiler.service.js +5 -2
- package/src/services/module-loading/source-module-support.d.ts +5 -0
- package/src/services/module-loading/source-module-support.js +8 -0
- package/src/services/runtime-state/dev-graph.service.d.ts +6 -6
- package/src/services/runtime-state/dev-graph.service.js +10 -10
- package/src/services/runtime-state/entrypoint-dependency-graph.service.d.ts +1 -1
- package/src/services/runtime-state/server-invalidation-state.service.d.ts +1 -1
- package/src/static-site-generator/static-site-generator.d.ts +23 -28
- package/src/static-site-generator/static-site-generator.js +119 -156
- package/src/{internal-types.d.ts → types/internal-types.d.ts} +34 -23
- package/src/types/internal-types.js +0 -0
- package/src/{public-types.d.ts → types/public-types.d.ts} +195 -37
- package/src/types/public-types.js +0 -0
- package/src/utils/html-escaping.d.ts +7 -0
- package/src/utils/html-escaping.js +6 -0
- package/src/utils/locals-utils.d.ts +1 -1
- package/src/utils/parse-cli-args.d.ts +4 -1
- package/src/utils/parse-cli-args.js +16 -1
- package/src/utils/resolve-work-dir.js +1 -1
- package/src/watchers/project-watcher.d.ts +4 -4
- package/src/watchers/project-watcher.js +35 -41
- package/src/watchers/project-watcher.test-helpers.d.ts +2 -2
- package/src/watchers/project-watcher.test-helpers.js +5 -5
- package/CHANGELOG.md +0 -31
- package/src/adapters/abstract/application-adapter.ts +0 -337
- package/src/adapters/abstract/router-adapter.ts +0 -30
- package/src/adapters/abstract/server-adapter.ts +0 -79
- package/src/adapters/bun/client-bridge.ts +0 -62
- package/src/adapters/bun/create-app.ts +0 -189
- package/src/adapters/bun/hmr-manager.ts +0 -409
- package/src/adapters/bun/index.ts +0 -2
- package/src/adapters/bun/server-adapter.ts +0 -499
- package/src/adapters/bun/server-lifecycle.d.ts +0 -63
- package/src/adapters/bun/server-lifecycle.js +0 -92
- package/src/adapters/bun/server-lifecycle.ts +0 -124
- package/src/adapters/index.ts +0 -6
- package/src/adapters/node/bootstrap-dependency-resolver.d.ts +0 -44
- package/src/adapters/node/bootstrap-dependency-resolver.js +0 -172
- package/src/adapters/node/bootstrap-dependency-resolver.ts +0 -301
- package/src/adapters/node/create-app.ts +0 -179
- package/src/adapters/node/index.d.ts +0 -6
- package/src/adapters/node/index.js +0 -11
- package/src/adapters/node/index.ts +0 -16
- package/src/adapters/node/node-client-bridge.ts +0 -79
- package/src/adapters/node/node-hmr-manager.ts +0 -381
- package/src/adapters/node/runtime-adapter.d.ts +0 -46
- package/src/adapters/node/runtime-adapter.js +0 -306
- package/src/adapters/node/runtime-adapter.ts +0 -439
- package/src/adapters/node/server-adapter.ts +0 -488
- package/src/adapters/node/static-content-server.ts +0 -239
- package/src/adapters/node/write-runtime-manifest.d.ts +0 -26
- package/src/adapters/node/write-runtime-manifest.js +0 -12
- package/src/adapters/node/write-runtime-manifest.ts +0 -38
- package/src/adapters/shared/api-response.ts +0 -104
- package/src/adapters/shared/application-adapter.ts +0 -199
- package/src/adapters/shared/define-api-handler.ts +0 -66
- package/src/adapters/shared/explicit-static-route-matcher.ts +0 -140
- package/src/adapters/shared/file-route-middleware-pipeline.ts +0 -127
- package/src/adapters/shared/fs-server-response-factory.ts +0 -118
- package/src/adapters/shared/fs-server-response-matcher.ts +0 -205
- package/src/adapters/shared/hmr-entrypoint-registrar.ts +0 -149
- package/src/adapters/shared/hmr-html-response.ts +0 -52
- package/src/adapters/shared/render-context.ts +0 -120
- package/src/adapters/shared/runtime-bootstrap.d.ts +0 -38
- package/src/adapters/shared/runtime-bootstrap.js +0 -43
- package/src/adapters/shared/runtime-bootstrap.ts +0 -79
- package/src/adapters/shared/server-adapter.ts +0 -489
- package/src/adapters/shared/server-route-handler.ts +0 -153
- package/src/adapters/shared/server-static-builder.ts +0 -166
- package/src/build/build-adapter.ts +0 -361
- package/src/build/build-manifest.ts +0 -54
- package/src/build/build-types.ts +0 -83
- package/src/build/dev-build-coordinator.d.ts +0 -74
- package/src/build/dev-build-coordinator.js +0 -161
- package/src/build/dev-build-coordinator.ts +0 -221
- package/src/build/esbuild-build-adapter.d.ts +0 -72
- package/src/build/esbuild-build-adapter.js +0 -422
- package/src/build/esbuild-build-adapter.ts +0 -559
- package/src/build/runtime-build-executor.ts +0 -34
- package/src/build/runtime-specifier-alias-plugin.d.ts +0 -15
- package/src/build/runtime-specifier-alias-plugin.js +0 -31
- package/src/build/runtime-specifier-alias-plugin.ts +0 -58
- package/src/config/config-builder.ts +0 -706
- package/src/constants.ts +0 -54
- package/src/create-app.ts +0 -87
- package/src/dev/sc-server.ts +0 -143
- package/src/eco/component-render-context.d.ts +0 -105
- package/src/eco/component-render-context.js +0 -87
- package/src/eco/component-render-context.ts +0 -224
- package/src/eco/eco.ts +0 -242
- package/src/eco/eco.types.ts +0 -221
- package/src/eco/eco.utils.ts +0 -89
- package/src/eco/global-injector-map.ts +0 -112
- package/src/eco/lazy-injector-map.ts +0 -120
- package/src/eco/module-dependencies.ts +0 -75
- package/src/errors/http-error.ts +0 -72
- package/src/errors/index.ts +0 -2
- package/src/errors/locals-access-error.ts +0 -7
- package/src/global/app-logger.ts +0 -4
- package/src/hmr/client/hmr-runtime.ts +0 -152
- package/src/hmr/hmr-strategy.ts +0 -172
- package/src/hmr/hmr.postcss.test.e2e.ts +0 -41
- package/src/hmr/hmr.test.e2e.ts +0 -66
- package/src/hmr/strategies/default-hmr-strategy.ts +0 -60
- package/src/hmr/strategies/js-hmr-strategy.ts +0 -320
- package/src/index.browser.ts +0 -3
- package/src/index.ts +0 -5
- package/src/integrations/ghtml/ghtml-renderer.ts +0 -96
- package/src/integrations/ghtml/ghtml.plugin.ts +0 -32
- package/src/internal-types.ts +0 -232
- package/src/plugins/alias-resolver-plugin.ts +0 -63
- package/src/plugins/eco-component-meta-plugin.ts +0 -481
- package/src/plugins/integration-plugin.ts +0 -226
- package/src/plugins/processor.ts +0 -240
- package/src/plugins/runtime-capability.ts +0 -14
- package/src/public-types.ts +0 -1317
- package/src/route-renderer/component-graph/component-graph-executor.d.ts +0 -32
- package/src/route-renderer/component-graph/component-graph-executor.js +0 -31
- package/src/route-renderer/component-graph/component-graph-executor.ts +0 -84
- package/src/route-renderer/component-graph/component-graph.d.ts +0 -42
- package/src/route-renderer/component-graph/component-graph.js +0 -72
- package/src/route-renderer/component-graph/component-graph.ts +0 -159
- package/src/route-renderer/component-graph/component-marker.d.ts +0 -52
- package/src/route-renderer/component-graph/component-marker.js +0 -46
- package/src/route-renderer/component-graph/component-marker.ts +0 -117
- package/src/route-renderer/component-graph/component-reference.d.ts +0 -10
- package/src/route-renderer/component-graph/component-reference.js +0 -19
- package/src/route-renderer/component-graph/component-reference.ts +0 -29
- package/src/route-renderer/component-graph/marker-graph-resolver.d.ts +0 -77
- package/src/route-renderer/component-graph/marker-graph-resolver.js +0 -95
- package/src/route-renderer/component-graph/marker-graph-resolver.ts +0 -155
- package/src/route-renderer/orchestration/integration-renderer.ts +0 -790
- package/src/route-renderer/orchestration/render-execution.service.d.ts +0 -103
- package/src/route-renderer/orchestration/render-execution.service.js +0 -121
- package/src/route-renderer/orchestration/render-execution.service.ts +0 -230
- package/src/route-renderer/orchestration/render-preparation.service.d.ts +0 -121
- package/src/route-renderer/orchestration/render-preparation.service.js +0 -332
- package/src/route-renderer/orchestration/render-preparation.service.ts +0 -476
- package/src/route-renderer/page-loading/dependency-resolver.ts +0 -612
- package/src/route-renderer/page-loading/page-module-loader.ts +0 -181
- package/src/route-renderer/route-renderer.ts +0 -115
- package/src/router/client/link-intent.test.browser.ts +0 -51
- package/src/router/client/link-intent.ts +0 -92
- package/src/router/client/navigation-coordinator.ts +0 -433
- package/src/router/server/fs-router-scanner.d.ts +0 -41
- package/src/router/server/fs-router-scanner.js +0 -156
- package/src/router/server/fs-router-scanner.ts +0 -219
- package/src/router/server/fs-router.d.ts +0 -26
- package/src/router/server/fs-router.js +0 -100
- package/src/router/server/fs-router.ts +0 -122
- package/src/services/assets/asset-processing-service/asset-processing.service.ts +0 -401
- package/src/services/assets/asset-processing-service/asset.factory.ts +0 -105
- package/src/services/assets/asset-processing-service/assets.types.ts +0 -113
- package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.ts +0 -95
- package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.ts +0 -78
- package/src/services/assets/asset-processing-service/index.ts +0 -5
- package/src/services/assets/asset-processing-service/processor.interface.ts +0 -27
- package/src/services/assets/asset-processing-service/processor.registry.ts +0 -18
- package/src/services/assets/asset-processing-service/processors/base/base-processor.ts +0 -82
- package/src/services/assets/asset-processing-service/processors/base/base-script-processor.ts +0 -95
- package/src/services/assets/asset-processing-service/processors/index.ts +0 -5
- package/src/services/assets/asset-processing-service/processors/script/content-script.processor.ts +0 -66
- package/src/services/assets/asset-processing-service/processors/script/file-script.processor.ts +0 -88
- package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.ts +0 -85
- package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.ts +0 -27
- package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.ts +0 -80
- package/src/services/assets/browser-bundle.service.ts +0 -53
- package/src/services/cache/cache.types.ts +0 -126
- package/src/services/cache/index.ts +0 -18
- package/src/services/cache/memory-cache-store.ts +0 -130
- package/src/services/cache/page-cache-service.ts +0 -202
- package/src/services/cache/page-request-cache-coordinator.service.ts +0 -131
- package/src/services/html/html-rewriter-provider.service.ts +0 -103
- package/src/services/html/html-transformer.service.ts +0 -279
- package/src/services/invalidation/development-invalidation.service.ts +0 -261
- package/src/services/module-loading/app-server-module-transpiler.service.ts +0 -52
- package/src/services/module-loading/page-module-import.service.ts +0 -200
- package/src/services/module-loading/server-loader.service.d.ts +0 -96
- package/src/services/module-loading/server-loader.service.js +0 -32
- package/src/services/module-loading/server-loader.service.ts +0 -130
- package/src/services/module-loading/server-module-transpiler.service.ts +0 -105
- package/src/services/runtime-manifest/node-runtime-manifest.service.d.ts +0 -35
- package/src/services/runtime-manifest/node-runtime-manifest.service.js +0 -60
- package/src/services/runtime-manifest/node-runtime-manifest.service.ts +0 -101
- package/src/services/runtime-state/dev-graph.service.ts +0 -217
- package/src/services/runtime-state/entrypoint-dependency-graph.service.ts +0 -136
- package/src/services/runtime-state/runtime-specifier-registry.service.d.ts +0 -69
- package/src/services/runtime-state/runtime-specifier-registry.service.js +0 -37
- package/src/services/runtime-state/runtime-specifier-registry.service.ts +0 -96
- package/src/services/runtime-state/server-invalidation-state.service.ts +0 -68
- package/src/services/validation/schema-validation-service.ts +0 -204
- package/src/services/validation/standard-schema.types.ts +0 -68
- package/src/static-site-generator/static-site-generator.ts +0 -462
- package/src/utils/css.d.ts +0 -1
- package/src/utils/css.js +0 -7
- package/src/utils/css.ts +0 -5
- package/src/utils/deep-merge.ts +0 -47
- package/src/utils/hash.ts +0 -5
- package/src/utils/html.ts +0 -1
- package/src/utils/invariant.ts +0 -15
- package/src/utils/locals-utils.ts +0 -37
- package/src/utils/parse-cli-args.ts +0 -83
- package/src/utils/path-utils.module.ts +0 -14
- package/src/utils/resolve-work-dir.ts +0 -45
- package/src/utils/runtime.ts +0 -44
- package/src/utils/server-utils.module.ts +0 -67
- package/src/watchers/project-watcher.test-helpers.ts +0 -41
- package/src/watchers/project-watcher.ts +0 -363
- /package/src/{internal-types.js → adapters/shared/runtime-host.js} +0 -0
- /package/src/{public-types.js → adapters/shared/static-preview-host.js} +0 -0
- /package/src/{constants.d.ts → config/constants.d.ts} +0 -0
- /package/src/{constants.js → config/constants.js} +0 -0
|
@@ -1,42 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
|
+
createPagePackage
|
|
2
3
|
} from "../../services/assets/asset-processing-service/index.js";
|
|
3
4
|
import { HtmlTransformerService } from "../../services/html/html-transformer.service.js";
|
|
4
5
|
import { invariant } from "../../utils/invariant.js";
|
|
5
6
|
import { HttpError } from "../../errors/http-error.js";
|
|
6
|
-
import { LocalsAccessError } from "../../errors/locals-access-error.js";
|
|
7
7
|
import { DependencyResolverService } from "../page-loading/dependency-resolver.js";
|
|
8
8
|
import { PageModuleLoaderService } from "../page-loading/page-module-loader.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
throw new LocalsAccessError(errorMessage);
|
|
22
|
-
},
|
|
23
|
-
has: () => {
|
|
24
|
-
throw new LocalsAccessError(errorMessage);
|
|
25
|
-
},
|
|
26
|
-
ownKeys: () => {
|
|
27
|
-
throw new LocalsAccessError(errorMessage);
|
|
28
|
-
},
|
|
29
|
-
deleteProperty: () => {
|
|
30
|
-
throw new LocalsAccessError(errorMessage);
|
|
31
|
-
},
|
|
32
|
-
defineProperty: () => {
|
|
33
|
-
throw new LocalsAccessError(errorMessage);
|
|
34
|
-
},
|
|
35
|
-
getOwnPropertyDescriptor: () => {
|
|
36
|
-
throw new LocalsAccessError(errorMessage);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
);
|
|
9
|
+
import { OwnershipValidationService } from "./ownership-validation.service.js";
|
|
10
|
+
import {
|
|
11
|
+
RouteRenderOrchestrator
|
|
12
|
+
} from "./route-render-orchestrator.js";
|
|
13
|
+
import { normalizeUnresolvedMarkerArtifactHtml } from "./render-output.utils.js";
|
|
14
|
+
import {
|
|
15
|
+
ForeignSubtreeExecutionService
|
|
16
|
+
} from "./foreign-subtree-execution.service.js";
|
|
17
|
+
import {} from "./queued-foreign-subtree-resolution.service.js";
|
|
18
|
+
import { buildProcessedAssetDedupeKey } from "./processed-asset-dedupe.js";
|
|
19
|
+
function isMarkupNodeLike(value) {
|
|
20
|
+
return typeof value === "object" && value !== null && "nodeType" in value && typeof value.nodeType === "number" && "outerHTML" in value && typeof value.outerHTML === "string";
|
|
40
21
|
}
|
|
41
22
|
class IntegrationRenderer {
|
|
42
23
|
appConfig;
|
|
@@ -44,13 +25,103 @@ class IntegrationRenderer {
|
|
|
44
25
|
htmlTransformer;
|
|
45
26
|
hmrManager;
|
|
46
27
|
resolvedIntegrationDependencies = [];
|
|
28
|
+
rendererModules;
|
|
47
29
|
runtimeOrigin;
|
|
48
30
|
dependencyResolverService;
|
|
49
31
|
pageModuleLoaderService;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
renderExecutionService;
|
|
32
|
+
routeRenderOrchestrator;
|
|
33
|
+
foreignSubtreeExecutionService = new ForeignSubtreeExecutionService();
|
|
53
34
|
DOC_TYPE = "<!DOCTYPE html>";
|
|
35
|
+
/**
|
|
36
|
+
* Loads one route module through the owning renderer's import path.
|
|
37
|
+
*
|
|
38
|
+
* Request-time infrastructure may need page metadata such as cache strategy or
|
|
39
|
+
* middleware before full rendering starts. Exposing this narrow entrypoint lets
|
|
40
|
+
* those callers reuse integration-specific import setup instead of bypassing it
|
|
41
|
+
* with raw transpiler access.
|
|
42
|
+
*/
|
|
43
|
+
async loadPageModule(file, options) {
|
|
44
|
+
return this.importPageFile(file, options);
|
|
45
|
+
}
|
|
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
|
+
getRendererModuleValue(key) {
|
|
93
|
+
if (!this.rendererModules || typeof this.rendererModules !== "object") {
|
|
94
|
+
return void 0;
|
|
95
|
+
}
|
|
96
|
+
return this.rendererModules[key];
|
|
97
|
+
}
|
|
98
|
+
getRendererModuleString(key) {
|
|
99
|
+
const value = this.getRendererModuleValue(key);
|
|
100
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
101
|
+
}
|
|
102
|
+
getRendererBootstrapDependencies(partial = false) {
|
|
103
|
+
if (partial) {
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
106
|
+
const islandClientModuleId = this.getRendererModuleString("islandClientModuleId");
|
|
107
|
+
if (!islandClientModuleId) {
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
return [
|
|
111
|
+
{
|
|
112
|
+
attributes: {
|
|
113
|
+
crossorigin: "anonymous",
|
|
114
|
+
"data-ecopages-runtime": "islands",
|
|
115
|
+
type: "module"
|
|
116
|
+
},
|
|
117
|
+
content: `import ${JSON.stringify(islandClientModuleId)};`,
|
|
118
|
+
inline: true,
|
|
119
|
+
kind: "script",
|
|
120
|
+
packageRole: "keep-separate",
|
|
121
|
+
position: "body"
|
|
122
|
+
}
|
|
123
|
+
];
|
|
124
|
+
}
|
|
54
125
|
setHmrManager(hmrManager) {
|
|
55
126
|
this.hmrManager = hmrManager;
|
|
56
127
|
if (this.assetProcessingService) {
|
|
@@ -106,25 +177,312 @@ class IntegrationRenderer {
|
|
|
106
177
|
const resolvedDependencies = this.htmlTransformer.dedupeProcessedAssets(
|
|
107
178
|
await this.resolveDependencies(componentsToResolve)
|
|
108
179
|
);
|
|
109
|
-
this.htmlTransformer.
|
|
180
|
+
this.htmlTransformer.setPagePackage(createPagePackage(resolvedDependencies));
|
|
110
181
|
return resolvedDependencies;
|
|
111
182
|
}
|
|
183
|
+
async resolvePageBrowserGraphForFile(filePath) {
|
|
184
|
+
return await this.routeRenderOrchestrator.resolveDeclaredPageBrowserGraph({
|
|
185
|
+
routeFile: filePath,
|
|
186
|
+
integrationName: this.name,
|
|
187
|
+
collectContribution: async (routeFile) => {
|
|
188
|
+
const pageModule = await this.importPageFile(routeFile);
|
|
189
|
+
return await this.collectPageBrowserGraphContribution({ file: routeFile, pageModule });
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
mergePageBrowserGraphIntoPagePackage(pageBrowserGraph) {
|
|
194
|
+
if (!pageBrowserGraph) {
|
|
195
|
+
return void 0;
|
|
196
|
+
}
|
|
197
|
+
const currentPagePackage = this.htmlTransformer.getPagePackage();
|
|
198
|
+
const mergedPageBrowserGraph = currentPagePackage?.pageBrowserGraph ? {
|
|
199
|
+
entryAssets: this.htmlTransformer.dedupeProcessedAssets([
|
|
200
|
+
...currentPagePackage.pageBrowserGraph.entryAssets,
|
|
201
|
+
...pageBrowserGraph.entryAssets
|
|
202
|
+
]),
|
|
203
|
+
chunkAssets: this.htmlTransformer.dedupeProcessedAssets([
|
|
204
|
+
...currentPagePackage.pageBrowserGraph.chunkAssets,
|
|
205
|
+
...pageBrowserGraph.chunkAssets
|
|
206
|
+
])
|
|
207
|
+
} : pageBrowserGraph;
|
|
208
|
+
const pageBrowserGraphAssetKeys = new Set(
|
|
209
|
+
[...mergedPageBrowserGraph.entryAssets, ...mergedPageBrowserGraph.chunkAssets].map(
|
|
210
|
+
(asset) => buildProcessedAssetDedupeKey(asset)
|
|
211
|
+
)
|
|
212
|
+
);
|
|
213
|
+
const baseAssets = currentPagePackage ? currentPagePackage.assets.filter(
|
|
214
|
+
(asset) => !pageBrowserGraphAssetKeys.has(buildProcessedAssetDedupeKey(asset))
|
|
215
|
+
) : this.htmlTransformer.getProcessedDependencies();
|
|
216
|
+
this.htmlTransformer.setPagePackage(
|
|
217
|
+
createPagePackage(this.htmlTransformer.dedupeProcessedAssets(baseAssets), {
|
|
218
|
+
pageBrowserGraph: mergedPageBrowserGraph
|
|
219
|
+
})
|
|
220
|
+
);
|
|
221
|
+
return mergedPageBrowserGraph;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Merges component-scoped assets into the active HTML transformer state.
|
|
225
|
+
*
|
|
226
|
+
* Explicit page, layout, and document shell composition can produce assets at
|
|
227
|
+
* each foreign subtree. This helper deduplicates those groups and folds them back into
|
|
228
|
+
* the transformer so downstream HTML finalization sees one canonical asset set.
|
|
229
|
+
*
|
|
230
|
+
* @param assetGroups - Optional groups of processed assets to merge.
|
|
231
|
+
* @returns The deduplicated asset subset contributed by this merge operation.
|
|
232
|
+
*/
|
|
233
|
+
appendProcessedDependencies(...assetGroups) {
|
|
234
|
+
const nextDependencies = this.htmlTransformer.dedupeProcessedAssets(
|
|
235
|
+
assetGroups.flatMap((assets) => assets ?? [])
|
|
236
|
+
);
|
|
237
|
+
if (nextDependencies.length === 0) {
|
|
238
|
+
return nextDependencies;
|
|
239
|
+
}
|
|
240
|
+
const mergedDependencies = this.htmlTransformer.dedupeProcessedAssets([
|
|
241
|
+
...this.htmlTransformer.getProcessedDependencies(),
|
|
242
|
+
...nextDependencies
|
|
243
|
+
]);
|
|
244
|
+
const currentPageBrowserGraph = this.htmlTransformer.getPagePackage()?.pageBrowserGraph;
|
|
245
|
+
this.htmlTransformer.setPagePackage(
|
|
246
|
+
createPagePackage(mergedDependencies, {
|
|
247
|
+
pageBrowserGraph: currentPageBrowserGraph
|
|
248
|
+
})
|
|
249
|
+
);
|
|
250
|
+
return nextDependencies;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Resolves metadata for explicit view rendering.
|
|
254
|
+
*
|
|
255
|
+
* When a view declares a `metadata()` function, that contract owns the final
|
|
256
|
+
* metadata for the explicit render. Otherwise the app-level default metadata is
|
|
257
|
+
* reused so explicit routes and page-module routes share the same fallback.
|
|
258
|
+
*
|
|
259
|
+
* @param view - View component being rendered.
|
|
260
|
+
* @param props - Props passed to the view.
|
|
261
|
+
* @returns Resolved metadata for the final document shell.
|
|
262
|
+
*/
|
|
263
|
+
async resolveViewMetadata(view, props) {
|
|
264
|
+
return view.metadata ? await view.metadata({
|
|
265
|
+
params: {},
|
|
266
|
+
query: {},
|
|
267
|
+
props,
|
|
268
|
+
appConfig: this.appConfig
|
|
269
|
+
}) : this.appConfig.defaultMetadata;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Renders one explicit view response in partial mode.
|
|
273
|
+
*
|
|
274
|
+
* Same-integration views can optionally stream or render inline via the caller's
|
|
275
|
+
* `renderInline()` hook. Once a view may cross integration boundaries, this
|
|
276
|
+
* helper routes the render through `renderComponentWithForeignChildren()` instead so mixed
|
|
277
|
+
* shells can reuse the execution-scoped renderer cache and resolve nested
|
|
278
|
+
* foreign ownership before the partial response is returned.
|
|
279
|
+
*
|
|
280
|
+
* @param input - View render options for the partial response.
|
|
281
|
+
* @returns HTML response for the partial render.
|
|
282
|
+
*/
|
|
283
|
+
async renderPartialViewResponse(input) {
|
|
284
|
+
if (input.renderInline && !this.hasForeignChildDescendants(input.view)) {
|
|
285
|
+
return this.createHtmlResponse(await input.renderInline(), input.ctx);
|
|
286
|
+
}
|
|
287
|
+
const rendererCache = /* @__PURE__ */ new Map();
|
|
288
|
+
const viewRender = await this.renderComponentWithForeignChildren({
|
|
289
|
+
component: input.view,
|
|
290
|
+
props: input.props ?? {},
|
|
291
|
+
integrationContext: { rendererCache }
|
|
292
|
+
});
|
|
293
|
+
const html = input.transformHtml ? input.transformHtml(viewRender.html) : viewRender.html;
|
|
294
|
+
return this.createHtmlResponse(html, input.ctx);
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Renders an explicit view through optional layout and document shells.
|
|
298
|
+
*
|
|
299
|
+
* This helper is the shared explicit-route path for string-oriented and mixed
|
|
300
|
+
* integrations. It prepares view dependencies, resolves metadata, and composes
|
|
301
|
+
* view, layout, and html template boundaries with one execution-scoped renderer
|
|
302
|
+
* cache so repeated foreign shell delegation can reuse initialized renderers
|
|
303
|
+
* during the same render flow.
|
|
304
|
+
*
|
|
305
|
+
* @param input - View, props, and optional layout metadata for the render.
|
|
306
|
+
* @returns HTML response for the explicit view render.
|
|
307
|
+
*/
|
|
308
|
+
async renderViewWithDocumentShell(input) {
|
|
309
|
+
const normalizedProps = input.props ?? {};
|
|
310
|
+
if (input.ctx.partial) {
|
|
311
|
+
return this.renderPartialViewResponse(input);
|
|
312
|
+
}
|
|
313
|
+
await this.prepareViewDependencies(input.view, input.layout);
|
|
314
|
+
const HtmlTemplate = await this.getHtmlTemplate();
|
|
315
|
+
const metadata = await this.resolveViewMetadata(input.view, input.props);
|
|
316
|
+
const { documentHtml } = await this.composeDocumentShell({
|
|
317
|
+
primaryComponent: input.view,
|
|
318
|
+
primaryProps: normalizedProps,
|
|
319
|
+
layout: input.layout ? {
|
|
320
|
+
component: input.layout,
|
|
321
|
+
props: {}
|
|
322
|
+
} : void 0,
|
|
323
|
+
htmlTemplate: HtmlTemplate,
|
|
324
|
+
documentProps: {
|
|
325
|
+
metadata,
|
|
326
|
+
pageProps: normalizedProps
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
const html = await this.finalizeResolvedHtml({
|
|
330
|
+
html: `${this.DOC_TYPE}${documentHtml}`,
|
|
331
|
+
partial: false
|
|
332
|
+
});
|
|
333
|
+
return this.createHtmlResponse(html, input.ctx);
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Renders a route page through optional layout and document shells.
|
|
337
|
+
*
|
|
338
|
+
* Route rendering and explicit view rendering now share the same renderer-owned
|
|
339
|
+
* shell composition model. This helper composes page, layout, and html template
|
|
340
|
+
* renders while threading one execution-scoped renderer cache through every
|
|
341
|
+
* delegated foreign subtree so foreign shell ownership remains stable and renderer
|
|
342
|
+
* initialization is reused inside the current request.
|
|
343
|
+
*
|
|
344
|
+
* @param input - Page, layout, document, and metadata inputs for the route render.
|
|
345
|
+
* @returns Final serialized document HTML including the doctype prefix.
|
|
346
|
+
*/
|
|
347
|
+
async renderPageWithDocumentShell(input) {
|
|
348
|
+
const { documentHtml: composedDocumentHtml } = await this.composeDocumentShell({
|
|
349
|
+
primaryComponent: input.page.component,
|
|
350
|
+
primaryProps: input.page.props,
|
|
351
|
+
layout: input.layout,
|
|
352
|
+
htmlTemplate: input.htmlTemplate,
|
|
353
|
+
documentProps: {
|
|
354
|
+
metadata: input.metadata,
|
|
355
|
+
pageProps: input.pageProps,
|
|
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
|
+
};
|
|
385
|
+
}
|
|
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
|
+
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;
|
|
401
|
+
if (input.children !== void 0 && serializedChildren === void 0) {
|
|
402
|
+
const componentFile = input.component.config?.__eco?.file ?? "unknown component";
|
|
403
|
+
const childTag = Object.prototype.toString.call(input.children);
|
|
404
|
+
throw new TypeError(
|
|
405
|
+
`[ecopages] ${this.name} renderer expected serialized children for ${componentFile}, received ${childTag}.`
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
const props = serializedChildren === void 0 ? input.props : { ...input.props, children: serializedChildren };
|
|
409
|
+
const content = await component(props);
|
|
410
|
+
const html = String(content);
|
|
411
|
+
const assets = input.component.config?.dependencies && typeof this.assetProcessingService?.processDependencies === "function" ? await this.processComponentDependencies([input.component]) : void 0;
|
|
412
|
+
return {
|
|
413
|
+
html,
|
|
414
|
+
canAttachAttributes: true,
|
|
415
|
+
rootTag: this.getRootTagName(html),
|
|
416
|
+
integrationName: this.name,
|
|
417
|
+
assets
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
getForeignSubtreeTokenPrefix() {
|
|
421
|
+
return `__${this.name}_foreign_subtree__`;
|
|
422
|
+
}
|
|
423
|
+
getForeignSubtreeResolutionContextKey() {
|
|
424
|
+
return `__${this.name}_foreign_subtree_runtime__`;
|
|
425
|
+
}
|
|
426
|
+
createQueuedForeignSubtreeExecutionRuntime(options) {
|
|
427
|
+
return this.foreignSubtreeExecutionService.createQueuedRuntime({
|
|
428
|
+
renderInput: options.renderInput,
|
|
429
|
+
rendererCache: options.rendererCache,
|
|
430
|
+
runtimeContextKey: options.runtimeContextKey ?? this.getForeignSubtreeResolutionContextKey(),
|
|
431
|
+
tokenPrefix: options.tokenPrefix ?? this.getForeignSubtreeTokenPrefix(),
|
|
432
|
+
createRuntimeContext: options.createRuntimeContext
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
getQueuedForeignSubtreeResolutionContext(input) {
|
|
436
|
+
return this.foreignSubtreeExecutionService.getQueuedRuntimeContext(
|
|
437
|
+
input,
|
|
438
|
+
this.getForeignSubtreeResolutionContextKey()
|
|
439
|
+
);
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Renders a string-first component, then resolves any queued foreign
|
|
443
|
+
* boundaries before returning final component HTML.
|
|
444
|
+
*/
|
|
445
|
+
async renderStringComponentWithQueuedForeignSubtrees(input, component) {
|
|
446
|
+
const componentRender = await this.renderStringComponentWithSerializedChildren(input, component);
|
|
447
|
+
const queuedForeignSubtreeResolution = await this.foreignSubtreeExecutionService.resolveStringQueuedHtml({
|
|
448
|
+
currentIntegrationName: this.name,
|
|
449
|
+
renderInput: input,
|
|
450
|
+
html: componentRender.html,
|
|
451
|
+
runtimeContextKey: this.getForeignSubtreeResolutionContextKey(),
|
|
452
|
+
queueLabel: "String",
|
|
453
|
+
getOwningRenderer: (integrationName, rendererCache) => this.getIntegrationRendererForName(integrationName, rendererCache),
|
|
454
|
+
applyAttributesToFirstElement: (html, attributes) => this.htmlTransformer.applyAttributesToFirstElement(html, attributes),
|
|
455
|
+
dedupeProcessedAssets: (assets) => this.htmlTransformer.dedupeProcessedAssets(assets)
|
|
456
|
+
});
|
|
457
|
+
const mergedAssets = this.htmlTransformer.dedupeProcessedAssets([
|
|
458
|
+
...componentRender.assets ?? [],
|
|
459
|
+
...queuedForeignSubtreeResolution.assets
|
|
460
|
+
]);
|
|
461
|
+
return {
|
|
462
|
+
...componentRender,
|
|
463
|
+
html: queuedForeignSubtreeResolution.html,
|
|
464
|
+
rootTag: this.getRootTagName(queuedForeignSubtreeResolution.html),
|
|
465
|
+
assets: mergedAssets.length > 0 ? mergedAssets : void 0
|
|
466
|
+
};
|
|
467
|
+
}
|
|
112
468
|
constructor({
|
|
113
469
|
appConfig,
|
|
114
470
|
assetProcessingService,
|
|
115
471
|
resolvedIntegrationDependencies,
|
|
472
|
+
rendererModules,
|
|
116
473
|
runtimeOrigin
|
|
117
474
|
}) {
|
|
118
475
|
this.appConfig = appConfig;
|
|
119
476
|
this.assetProcessingService = assetProcessingService;
|
|
120
477
|
this.htmlTransformer = new HtmlTransformerService();
|
|
121
478
|
this.resolvedIntegrationDependencies = resolvedIntegrationDependencies || [];
|
|
479
|
+
this.rendererModules = rendererModules ?? appConfig.runtime?.rendererModuleContext;
|
|
122
480
|
this.runtimeOrigin = runtimeOrigin;
|
|
123
481
|
this.dependencyResolverService = new DependencyResolverService(appConfig, assetProcessingService);
|
|
124
482
|
this.pageModuleLoaderService = new PageModuleLoaderService(appConfig, runtimeOrigin);
|
|
125
|
-
this.
|
|
126
|
-
|
|
127
|
-
|
|
483
|
+
this.routeRenderOrchestrator = new RouteRenderOrchestrator(appConfig, assetProcessingService, {
|
|
484
|
+
ownershipValidationService: new OwnershipValidationService(appConfig)
|
|
485
|
+
});
|
|
128
486
|
}
|
|
129
487
|
/**
|
|
130
488
|
* Returns the HTML path from the provided file path.
|
|
@@ -150,41 +508,22 @@ class IntegrationRenderer {
|
|
|
150
508
|
* @returns The HTML template component.
|
|
151
509
|
*/
|
|
152
510
|
async getHtmlTemplate() {
|
|
153
|
-
const
|
|
511
|
+
const htmlTemplatePath = this.getRendererModuleString("htmlTemplateModulePath") ?? this.appConfig.absolutePaths.htmlTemplatePath;
|
|
154
512
|
try {
|
|
155
|
-
const { default: HtmlTemplate } = await this.importPageFile(
|
|
513
|
+
const { default: HtmlTemplate } = await this.importPageFile(htmlTemplatePath);
|
|
156
514
|
return HtmlTemplate;
|
|
157
515
|
} catch (error) {
|
|
158
516
|
invariant(false, `Error importing HtmlTemplate: ${error}`);
|
|
159
517
|
}
|
|
160
518
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
* It calls the provided getStaticProps function with the given options.
|
|
164
|
-
*
|
|
165
|
-
* @param getStaticProps - The function to get static props.
|
|
166
|
-
* @param options - The options to pass to the getStaticProps function.
|
|
167
|
-
* @returns The static props and metadata.
|
|
168
|
-
*/
|
|
169
|
-
async getStaticProps(getStaticProps, options) {
|
|
170
|
-
return this.pageModuleLoaderService.getStaticPropsForPage({
|
|
171
|
-
getStaticProps,
|
|
172
|
-
params: options?.params
|
|
173
|
-
});
|
|
519
|
+
usesIntegrationPageImporter(_file) {
|
|
520
|
+
return false;
|
|
174
521
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
* @param context - The context to pass to the getMetadata function.
|
|
181
|
-
* @returns The metadata properties.
|
|
182
|
-
*/
|
|
183
|
-
async getMetadataProps(getMetadata, { props, params, query }) {
|
|
184
|
-
return this.pageModuleLoaderService.getMetadataPropsForPage({
|
|
185
|
-
getMetadata,
|
|
186
|
-
context: { props, params, query }
|
|
187
|
-
});
|
|
522
|
+
async importIntegrationPageFile(_file, _options) {
|
|
523
|
+
invariant(false, "Integration page importer must be implemented when enabled");
|
|
524
|
+
}
|
|
525
|
+
normalizeImportedPageFile(_file, pageModule) {
|
|
526
|
+
return pageModule;
|
|
188
527
|
}
|
|
189
528
|
/**
|
|
190
529
|
* Imports the page file from the specified path.
|
|
@@ -193,8 +532,16 @@ class IntegrationRenderer {
|
|
|
193
532
|
* @param file - The file path to import.
|
|
194
533
|
* @returns The imported module.
|
|
195
534
|
*/
|
|
196
|
-
async importPageFile(file) {
|
|
197
|
-
|
|
535
|
+
async importPageFile(file, options) {
|
|
536
|
+
const bypassCache = options?.bypassCache ?? (typeof Bun !== "undefined" && process.env.NODE_ENV === "development");
|
|
537
|
+
const pageModule = this.usesIntegrationPageImporter(file) ? await this.importIntegrationPageFile(file, {
|
|
538
|
+
bypassCache,
|
|
539
|
+
cacheScope: options?.cacheScope
|
|
540
|
+
}) : await this.pageModuleLoaderService.importPageFile(file, {
|
|
541
|
+
bypassCache,
|
|
542
|
+
cacheScope: options?.cacheScope
|
|
543
|
+
});
|
|
544
|
+
return this.normalizeImportedPageFile(file, pageModule);
|
|
198
545
|
}
|
|
199
546
|
/**
|
|
200
547
|
* Resolves the dependency path based on the component directory.
|
|
@@ -266,6 +613,103 @@ class IntegrationRenderer {
|
|
|
266
613
|
async processComponentDependencies(components) {
|
|
267
614
|
return this.dependencyResolverService.processComponentDependencies(components, this.name);
|
|
268
615
|
}
|
|
616
|
+
/**
|
|
617
|
+
* Builds the internal route-render adapter consumed by `RouteRenderOrchestrator`.
|
|
618
|
+
*
|
|
619
|
+
* The route orchestrator needs a narrow orchestration contract, but those hooks should
|
|
620
|
+
* not become public API on the renderer base class. Keeping the adapter object
|
|
621
|
+
* local to the execution path lets the orchestrator depend on one explicit seam while
|
|
622
|
+
* subclasses continue to override protected renderer behavior directly.
|
|
623
|
+
*/
|
|
624
|
+
createRouteRenderOrchestratorAdapter() {
|
|
625
|
+
return {
|
|
626
|
+
name: this.name,
|
|
627
|
+
resolveRouteRenderInputs: (routeOptions) => this.resolveRouteRenderInputs(routeOptions),
|
|
628
|
+
resolveRouteDependencies: (input) => this.resolveRouteDependencies(input),
|
|
629
|
+
collectPageBrowserGraphContribution: async (routeFile) => {
|
|
630
|
+
const pageModule = await this.importPageFile(routeFile);
|
|
631
|
+
return await this.collectPageBrowserGraphContribution({ file: routeFile, pageModule });
|
|
632
|
+
},
|
|
633
|
+
resolveRoutePageComponentRender: (input) => this.resolveRoutePageComponentRender(input),
|
|
634
|
+
renderRouteBody: (renderOptions) => this.renderRouteBody(renderOptions),
|
|
635
|
+
getRouteHtmlFinalization: (renderOptions) => this.getRouteHtmlFinalization(renderOptions),
|
|
636
|
+
transformRouteResponse: (response, htmlContributions) => this.transformRouteResponse(response, htmlContributions)
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
async resolveRouteRenderInputs(routeOptions) {
|
|
640
|
+
const pageModule = await this.pageModuleLoaderService.resolvePageModule({
|
|
641
|
+
file: routeOptions.file,
|
|
642
|
+
importPageFileFn: (targetFile) => this.importPageFile(targetFile)
|
|
643
|
+
});
|
|
644
|
+
const { Page, integrationSpecificProps } = pageModule;
|
|
645
|
+
const HtmlTemplate = await this.getHtmlTemplate();
|
|
646
|
+
const Layout = Page.config?.layout;
|
|
647
|
+
const { props, metadata } = await this.pageModuleLoaderService.resolvePageData({
|
|
648
|
+
pageModule,
|
|
649
|
+
routeOptions
|
|
650
|
+
});
|
|
651
|
+
return {
|
|
652
|
+
Page,
|
|
653
|
+
HtmlTemplate,
|
|
654
|
+
Layout,
|
|
655
|
+
props,
|
|
656
|
+
metadata,
|
|
657
|
+
integrationSpecificProps
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
async resolveRouteDependencies(input) {
|
|
661
|
+
return {
|
|
662
|
+
resolvedDependencies: await this.resolveDependencies(input.components)
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
async resolveRoutePageComponentRender(input) {
|
|
666
|
+
if (!this.shouldRenderPageComponent({ Page: input.Page, Layout: input.Layout, options: input.routeOptions })) {
|
|
667
|
+
return void 0;
|
|
668
|
+
}
|
|
669
|
+
return this.renderComponentWithForeignChildren({
|
|
670
|
+
component: input.Page,
|
|
671
|
+
props: {
|
|
672
|
+
...input.props,
|
|
673
|
+
params: input.routeOptions.params || {},
|
|
674
|
+
query: input.routeOptions.query || {}
|
|
675
|
+
},
|
|
676
|
+
integrationContext: {
|
|
677
|
+
componentInstanceId: "eco-page-root"
|
|
678
|
+
}
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
async renderRouteBody(renderOptions) {
|
|
682
|
+
return this.render(renderOptions);
|
|
683
|
+
}
|
|
684
|
+
getRouteHtmlFinalization(renderOptions) {
|
|
685
|
+
const componentRootAttributes = renderOptions.componentRender?.canAttachAttributes && renderOptions.componentRender.rootAttributes && Object.keys(renderOptions.componentRender.rootAttributes).length > 0 ? renderOptions.componentRender.rootAttributes : void 0;
|
|
686
|
+
const documentAttributes = this.getDocumentAttributes(renderOptions);
|
|
687
|
+
const htmlContributions = this.getHtmlDocumentContributions({ renderOptions, partial: false });
|
|
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 {
|
|
693
|
+
htmlContributions,
|
|
694
|
+
finalizeHtml: (html) => {
|
|
695
|
+
let renderedHtml = html;
|
|
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);
|
|
711
|
+
return transformedResponse.body ?? await transformedResponse.text();
|
|
712
|
+
}
|
|
269
713
|
/**
|
|
270
714
|
* Prepares the render options for the integration renderer.
|
|
271
715
|
* It imports the page file, collects dependencies, and prepares the render options.
|
|
@@ -273,26 +717,11 @@ class IntegrationRenderer {
|
|
|
273
717
|
* @param options - The route renderer options.
|
|
274
718
|
* @returns The prepared render options.
|
|
275
719
|
*/
|
|
276
|
-
async prepareRenderOptions(options) {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
resolveDependencies: (components) => this.resolveDependencies(components),
|
|
282
|
-
buildRouteRenderAssets: (file) => this.buildRouteRenderAssets(file),
|
|
283
|
-
shouldRenderPageComponent: (input) => this.shouldRenderPageComponent(input),
|
|
284
|
-
renderPageComponent: ({ component, props }) => this.renderComponent({
|
|
285
|
-
component,
|
|
286
|
-
props,
|
|
287
|
-
integrationContext: {
|
|
288
|
-
componentInstanceId: "eco-page-root"
|
|
289
|
-
}
|
|
290
|
-
}),
|
|
291
|
-
getComponentRenderBoundaryContext: () => this.getComponentRenderBoundaryContext(),
|
|
292
|
-
setProcessedDependencies: (dependencies) => this.htmlTransformer.setProcessedDependencies(dependencies),
|
|
293
|
-
dedupeProcessedAssets: (assets) => this.htmlTransformer.dedupeProcessedAssets(assets),
|
|
294
|
-
createPageLocalsProxy: (filePath) => createLocalsProxy(filePath)
|
|
295
|
-
});
|
|
720
|
+
async prepareRenderOptions(options, adapter = this.createRouteRenderOrchestratorAdapter()) {
|
|
721
|
+
const renderOptions = await this.routeRenderOrchestrator.prepareRenderOptions(options, adapter);
|
|
722
|
+
invariant(renderOptions.pagePackage !== void 0, "Expected render preparation to produce a page package");
|
|
723
|
+
this.htmlTransformer.setPagePackage(renderOptions.pagePackage);
|
|
724
|
+
return renderOptions;
|
|
296
725
|
}
|
|
297
726
|
/**
|
|
298
727
|
* Controls whether the page root should be rendered through `renderComponent()`
|
|
@@ -305,34 +734,15 @@ class IntegrationRenderer {
|
|
|
305
734
|
shouldRenderPageComponent(_input) {
|
|
306
735
|
return true;
|
|
307
736
|
}
|
|
308
|
-
/**
|
|
309
|
-
* Resolves the page module and normalizes exports.
|
|
310
|
-
*/
|
|
311
|
-
async resolvePageModule(file) {
|
|
312
|
-
return this.pageModuleLoaderService.resolvePageModule({
|
|
313
|
-
file,
|
|
314
|
-
importPageFileFn: (targetFile) => this.importPageFile(targetFile)
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* Resolves static props and metadata for the page.
|
|
319
|
-
*/
|
|
320
|
-
async resolvePageData(pageModule, options) {
|
|
321
|
-
return this.pageModuleLoaderService.resolvePageData({
|
|
322
|
-
pageModule,
|
|
323
|
-
routeOptions: options
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
737
|
/**
|
|
327
738
|
* Executes the integration renderer with the provided options.
|
|
328
739
|
*
|
|
329
740
|
* Execution flow:
|
|
330
741
|
* 1. Build normalized render options (`prepareRenderOptions`).
|
|
331
|
-
* 2. Render
|
|
332
|
-
* 3.
|
|
333
|
-
* 4.
|
|
334
|
-
* 5.
|
|
335
|
-
* 6. Run HTML transformer with final dependency set.
|
|
742
|
+
* 2. Render the route body once.
|
|
743
|
+
* 3. Reject unresolved route-level eco-marker artifacts.
|
|
744
|
+
* 4. Optionally apply root attributes for page/component root boundaries.
|
|
745
|
+
* 5. Run HTML transformer with final dependency set.
|
|
336
746
|
*
|
|
337
747
|
* Stream-safety note: the first render result is normalized to a string once,
|
|
338
748
|
* then the pipeline continues with that immutable HTML value to avoid disturbed
|
|
@@ -342,84 +752,39 @@ class IntegrationRenderer {
|
|
|
342
752
|
* @returns Rendered route body plus effective cache strategy.
|
|
343
753
|
*/
|
|
344
754
|
async execute(options) {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
getComponentRenderBoundaryContext: () => this.getComponentRenderBoundaryContext(),
|
|
349
|
-
resolveMarkerGraphHtml: (input) => this.resolveMarkerGraphHtml({
|
|
350
|
-
html: input.html,
|
|
351
|
-
componentsToResolve: input.componentsToResolve,
|
|
352
|
-
graphContext: input.graphContext
|
|
353
|
-
}),
|
|
354
|
-
getDocumentAttributes: (renderOptions) => this.getDocumentAttributes(renderOptions),
|
|
355
|
-
dedupeProcessedAssets: (assets) => this.htmlTransformer.dedupeProcessedAssets(assets),
|
|
356
|
-
getProcessedDependencies: () => this.htmlTransformer.getProcessedDependencies(),
|
|
357
|
-
setProcessedDependencies: (dependencies) => this.htmlTransformer.setProcessedDependencies(dependencies),
|
|
358
|
-
applyAttributesToHtmlElement: (html, attributes) => this.htmlTransformer.applyAttributesToHtmlElement(html, attributes),
|
|
359
|
-
applyAttributesToFirstBodyElement: (html, attributes) => this.htmlTransformer.applyAttributesToFirstBodyElement(html, attributes),
|
|
360
|
-
transformHtml: async (html) => {
|
|
361
|
-
const response = await this.htmlTransformer.transform(
|
|
362
|
-
new Response(html, {
|
|
363
|
-
headers: {
|
|
364
|
-
"Content-Type": "text/html"
|
|
365
|
-
}
|
|
366
|
-
})
|
|
367
|
-
);
|
|
368
|
-
return response.body;
|
|
369
|
-
}
|
|
370
|
-
});
|
|
755
|
+
const adapter = this.createRouteRenderOrchestratorAdapter();
|
|
756
|
+
const renderOptions = await this.prepareRenderOptions(options, adapter);
|
|
757
|
+
return this.routeRenderOrchestrator.executePrepared(renderOptions, adapter);
|
|
371
758
|
}
|
|
372
759
|
/**
|
|
373
|
-
*
|
|
374
|
-
* for deferred marker resolution.
|
|
760
|
+
* Finalizes already-resolved HTML for explicit renderer-owned paths.
|
|
375
761
|
*
|
|
376
|
-
* This
|
|
377
|
-
*
|
|
378
|
-
*
|
|
379
|
-
*/
|
|
380
|
-
async captureHtmlRender(render) {
|
|
381
|
-
return this.renderExecutionService.captureHtmlRender(
|
|
382
|
-
this.name,
|
|
383
|
-
this.getComponentRenderBoundaryContext(),
|
|
384
|
-
render
|
|
385
|
-
);
|
|
386
|
-
}
|
|
387
|
-
/**
|
|
388
|
-
* Finalizes previously captured HTML by resolving deferred markers, merging
|
|
389
|
-
* any emitted assets, stamping optional attributes, and optionally running the
|
|
390
|
-
* HTML transformer for full-document flows.
|
|
762
|
+
* This keeps document and root-attribute stamping plus HTML transformation
|
|
763
|
+
* available after a renderer has completed nested foreign-subtree resolution without
|
|
764
|
+
* routing back through shared route execution.
|
|
391
765
|
*/
|
|
392
|
-
async
|
|
393
|
-
const
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
{
|
|
403
|
-
resolveMarkerGraphHtml: (input) => this.resolveMarkerGraphHtml({
|
|
404
|
-
html: input.html,
|
|
405
|
-
componentsToResolve: input.componentsToResolve,
|
|
406
|
-
graphContext: input.graphContext
|
|
407
|
-
}),
|
|
408
|
-
dedupeProcessedAssets: (assets) => this.htmlTransformer.dedupeProcessedAssets(assets),
|
|
409
|
-
getProcessedDependencies: () => this.htmlTransformer.getProcessedDependencies(),
|
|
410
|
-
setProcessedDependencies: (dependencies) => this.htmlTransformer.setProcessedDependencies(dependencies),
|
|
411
|
-
applyAttributesToHtmlElement: (html, attributes) => this.htmlTransformer.applyAttributesToHtmlElement(html, attributes),
|
|
412
|
-
applyAttributesToFirstBodyElement: (html, attributes) => this.htmlTransformer.applyAttributesToFirstBodyElement(html, attributes)
|
|
413
|
-
}
|
|
414
|
-
);
|
|
766
|
+
async finalizeResolvedHtml(options) {
|
|
767
|
+
const rendererBootstrapDependencies = this.getRendererBootstrapDependencies(options.partial);
|
|
768
|
+
this.appendProcessedDependencies(rendererBootstrapDependencies);
|
|
769
|
+
let html = options.html;
|
|
770
|
+
if (options.componentRootAttributes && Object.keys(options.componentRootAttributes).length > 0) {
|
|
771
|
+
html = this.htmlTransformer.applyAttributesToFirstBodyElement(html, options.componentRootAttributes);
|
|
772
|
+
}
|
|
773
|
+
if (options.documentAttributes && Object.keys(options.documentAttributes).length > 0) {
|
|
774
|
+
html = this.htmlTransformer.applyAttributesToHtmlElement(html, options.documentAttributes);
|
|
775
|
+
}
|
|
415
776
|
const shouldTransform = options.transformHtml ?? !options.partial;
|
|
416
777
|
if (!shouldTransform) {
|
|
417
|
-
return
|
|
778
|
+
return html;
|
|
418
779
|
}
|
|
780
|
+
const htmlContributions = options.htmlContributions ?? this.getHtmlDocumentContributions({
|
|
781
|
+
partial: options.partial
|
|
782
|
+
});
|
|
419
783
|
const transformedResponse = await this.htmlTransformer.transform(
|
|
420
|
-
new Response(
|
|
784
|
+
new Response(html, {
|
|
421
785
|
headers: { "Content-Type": "text/html" }
|
|
422
|
-
})
|
|
786
|
+
}),
|
|
787
|
+
htmlContributions
|
|
423
788
|
);
|
|
424
789
|
return await transformedResponse.text();
|
|
425
790
|
}
|
|
@@ -433,37 +798,16 @@ class IntegrationRenderer {
|
|
|
433
798
|
return void 0;
|
|
434
799
|
}
|
|
435
800
|
/**
|
|
436
|
-
*
|
|
437
|
-
*
|
|
438
|
-
*
|
|
439
|
-
*
|
|
440
|
-
*
|
|
441
|
-
*
|
|
442
|
-
*
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
* - resolve component definition by `componentRef`
|
|
447
|
-
* - resolve serialized props by `propsRef`
|
|
448
|
-
* - stitch resolved child HTML when `slotRef` is present
|
|
449
|
-
* - dispatch to target integration `renderComponent`
|
|
450
|
-
* - collect produced assets and apply root attributes when attachable
|
|
451
|
-
*
|
|
452
|
-
* @param options.html HTML that may still contain marker tokens.
|
|
453
|
-
* @param options.componentsToResolve Component set used to build component ref registry.
|
|
454
|
-
* @param options.graphContext Props/slot linkage captured during render.
|
|
455
|
-
* @returns Resolved HTML plus any component-scoped assets produced while resolving nodes.
|
|
456
|
-
* @throws Error when marker component refs or props refs cannot be resolved.
|
|
457
|
-
*/
|
|
458
|
-
async resolveMarkerGraphHtml(options) {
|
|
459
|
-
const integrationRendererCache = /* @__PURE__ */ new Map();
|
|
460
|
-
return this.markerGraphResolver.resolve({
|
|
461
|
-
html: options.html,
|
|
462
|
-
componentsToResolve: options.componentsToResolve,
|
|
463
|
-
graphContext: options.graphContext,
|
|
464
|
-
resolveRenderer: (integrationName) => this.getIntegrationRendererForName(integrationName, integrationRendererCache),
|
|
465
|
-
applyAttributesToFirstElement: (html, attributes) => this.htmlTransformer.applyAttributesToFirstElement(html, attributes)
|
|
466
|
-
});
|
|
801
|
+
* Returns declarative HTML fragments that core should inject into the final document.
|
|
802
|
+
*
|
|
803
|
+
* @remarks
|
|
804
|
+
* Integrations may contribute document markup here, but core retains ownership
|
|
805
|
+
* of the final HTML rewrite pipeline and placement semantics. This is the
|
|
806
|
+
* supported document-markup extension point for integrations instead of custom
|
|
807
|
+
* response finalization logic.
|
|
808
|
+
*/
|
|
809
|
+
getHtmlDocumentContributions(_options) {
|
|
810
|
+
return void 0;
|
|
467
811
|
}
|
|
468
812
|
/**
|
|
469
813
|
* Returns a renderer instance for a given integration name.
|
|
@@ -486,26 +830,100 @@ class IntegrationRenderer {
|
|
|
486
830
|
const integrationPlugin = this.appConfig.integrations.find(
|
|
487
831
|
(integration) => integration.name === integrationName
|
|
488
832
|
);
|
|
489
|
-
invariant(!!integrationPlugin, `[ecopages] Integration not found for
|
|
490
|
-
const renderer = integrationPlugin.initializeRenderer(
|
|
833
|
+
invariant(!!integrationPlugin, `[ecopages] Integration not found for foreign owner: ${integrationName}`);
|
|
834
|
+
const renderer = integrationPlugin.initializeRenderer({
|
|
835
|
+
rendererModules: this.appConfig.runtime?.rendererModuleContext
|
|
836
|
+
});
|
|
491
837
|
cache.set(integrationName, renderer);
|
|
492
838
|
return renderer;
|
|
493
839
|
}
|
|
840
|
+
/**
|
|
841
|
+
* Renders one component under this integration's foreign-child runtime and resolves
|
|
842
|
+
* any nested foreign children captured during that render.
|
|
843
|
+
*
|
|
844
|
+
* Without this wrapper, a component tree with foreign-owned descendants would
|
|
845
|
+
* render them with no active foreign-child runtime, which bypasses the owning
|
|
846
|
+
* renderer's nested foreign-child handoff.
|
|
847
|
+
*/
|
|
848
|
+
async renderComponentWithForeignChildren(input) {
|
|
849
|
+
return await this.foreignSubtreeExecutionService.executeComponentRender({
|
|
850
|
+
currentIntegrationName: this.name,
|
|
851
|
+
input,
|
|
852
|
+
renderComponent: (renderInput) => this.renderComponent(renderInput),
|
|
853
|
+
normalizeComponentRenderOutput: (result) => this.normalizeComponentRenderOutput(result),
|
|
854
|
+
hasForeignChildDescendants: (component) => this.hasForeignChildDescendants(component),
|
|
855
|
+
createForeignChildRuntime: ({ renderInput, rendererCache }) => this.createForeignChildRuntime({
|
|
856
|
+
renderInput,
|
|
857
|
+
rendererCache
|
|
858
|
+
}),
|
|
859
|
+
getOwningRenderer: (integrationName, rendererCache) => this.getIntegrationRendererForName(integrationName, rendererCache)
|
|
860
|
+
});
|
|
861
|
+
}
|
|
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
|
+
normalizeComponentRenderOutput(result) {
|
|
879
|
+
const normalizedHtml = this.normalizeUnresolvedMarkerArtifactHtml(result.html);
|
|
880
|
+
return normalizedHtml === result.html ? result : {
|
|
881
|
+
...result,
|
|
882
|
+
html: normalizedHtml
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
normalizeUnresolvedMarkerArtifactHtml(html) {
|
|
886
|
+
return normalizeUnresolvedMarkerArtifactHtml(html);
|
|
887
|
+
}
|
|
888
|
+
/**
|
|
889
|
+
* Returns whether the component dependency tree crosses into another
|
|
890
|
+
* integration.
|
|
891
|
+
*
|
|
892
|
+
* This keeps foreign-child runtime setup narrow: same-integration trees can render
|
|
893
|
+
* directly without paying the queue orchestration cost.
|
|
894
|
+
*/
|
|
895
|
+
hasForeignChildDescendants(component) {
|
|
896
|
+
const stack = [component];
|
|
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;
|
|
911
|
+
}
|
|
494
912
|
/**
|
|
495
913
|
* Render a single component and return structured output for orchestration paths.
|
|
496
914
|
*
|
|
497
915
|
* Default behavior delegates to `renderToResponse` in partial mode and wraps
|
|
498
916
|
* the resulting HTML into the `ComponentRenderResult` contract.
|
|
499
917
|
*
|
|
500
|
-
* In
|
|
501
|
-
* already-resolved deferred
|
|
918
|
+
* In foreign-subtree resolution, this method is the integration-owned step that turns an
|
|
919
|
+
* already-resolved deferred foreign subtree into concrete HTML, assets, and optional
|
|
502
920
|
* root attributes.
|
|
503
921
|
*
|
|
504
922
|
* Integrations can override this for richer behavior (asset emission,
|
|
505
923
|
* root attributes, integration-specific hydration metadata).
|
|
506
924
|
*
|
|
507
925
|
* @param input Component render request.
|
|
508
|
-
* @returns Structured render result used by
|
|
926
|
+
* @returns Structured render result used by component/page orchestration.
|
|
509
927
|
*/
|
|
510
928
|
async renderComponent(input) {
|
|
511
929
|
const response = await this.renderToResponse(
|
|
@@ -528,60 +946,44 @@ class IntegrationRenderer {
|
|
|
528
946
|
* @returns Root tag name when present; otherwise `undefined`.
|
|
529
947
|
*/
|
|
530
948
|
getRootTagName(html) {
|
|
531
|
-
const rootTag = html.match(
|
|
949
|
+
const rootTag = html.match(/^(?:\s|<!--[\s\S]*?-->)*<([a-zA-Z][a-zA-Z0-9:-]*)\b/);
|
|
532
950
|
return rootTag?.[1];
|
|
533
951
|
}
|
|
534
952
|
/**
|
|
535
|
-
*
|
|
536
|
-
*
|
|
953
|
+
* Collects declarative Page Browser Graph contributions for one Page.
|
|
954
|
+
*
|
|
955
|
+
* @remarks
|
|
956
|
+
* Integrations may describe page-scoped browser requirements here, while core
|
|
957
|
+
* retains ownership of dependency processing and final graph assembly. This is
|
|
958
|
+
* the supported page-browser extension point for integrations.
|
|
537
959
|
*
|
|
538
|
-
* @param
|
|
539
|
-
* @returns
|
|
960
|
+
* @param context - The route file path and already imported page module.
|
|
961
|
+
* @returns Declarative dependencies or pre-resolved assets for the Page.
|
|
540
962
|
*/
|
|
541
|
-
|
|
963
|
+
async collectPageBrowserGraphContribution(_context) {
|
|
542
964
|
return void 0;
|
|
543
965
|
}
|
|
544
966
|
/**
|
|
545
|
-
*
|
|
546
|
-
*
|
|
967
|
+
* Creates the per-render foreign-child runtime adopted by the shared component
|
|
968
|
+
* render context.
|
|
547
969
|
*
|
|
548
|
-
*
|
|
549
|
-
*
|
|
550
|
-
*
|
|
551
|
-
*
|
|
970
|
+
* The default runtime queues delegated foreign subtrees inside the owning
|
|
971
|
+
* renderer so string and markup renderers do not need to re-declare the same
|
|
972
|
+
* handoff boilerplate. Override only when a renderer needs custom runtime
|
|
973
|
+
* context or a different foreign-child execution strategy.
|
|
552
974
|
*/
|
|
553
|
-
|
|
554
|
-
return {
|
|
555
|
-
|
|
556
|
-
|
|
975
|
+
createForeignChildRuntime(options) {
|
|
976
|
+
return this.createQueuedForeignSubtreeExecutionRuntime({
|
|
977
|
+
renderInput: options.renderInput,
|
|
978
|
+
rendererCache: options.rendererCache
|
|
979
|
+
});
|
|
557
980
|
}
|
|
558
981
|
/**
|
|
559
|
-
*
|
|
560
|
-
*
|
|
561
|
-
*
|
|
562
|
-
* Boundaries targeting the current integration always render inline. Cross-
|
|
563
|
-
* integration boundaries delegate the decision to the target integration's
|
|
564
|
-
* `shouldDeferComponentBoundary()` policy.
|
|
565
|
-
*
|
|
566
|
-
* @param input Boundary metadata for the active render pass.
|
|
567
|
-
* @returns `true` when the boundary should emit a marker; otherwise `false`.
|
|
982
|
+
* Creates an explicit fail-fast runtime for tests or renderers that do not
|
|
983
|
+
* support cross-integration foreign-child execution.
|
|
568
984
|
*/
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
return false;
|
|
572
|
-
}
|
|
573
|
-
const targetIntegration = this.appConfig.integrations.find(
|
|
574
|
-
(integration) => integration.name === input.targetIntegration
|
|
575
|
-
);
|
|
576
|
-
invariant(
|
|
577
|
-
!!targetIntegration,
|
|
578
|
-
`[ecopages] Integration not found for component boundary: ${input.targetIntegration}`
|
|
579
|
-
);
|
|
580
|
-
return targetIntegration.shouldDeferComponentBoundary({
|
|
581
|
-
currentIntegration: input.currentIntegration,
|
|
582
|
-
targetIntegration: input.targetIntegration,
|
|
583
|
-
component: input.component
|
|
584
|
-
});
|
|
985
|
+
createFailFastForeignChildRuntime() {
|
|
986
|
+
return this.foreignSubtreeExecutionService.createFailFastRuntime(this.name);
|
|
585
987
|
}
|
|
586
988
|
}
|
|
587
989
|
export {
|