@ecopages/core 0.2.0-beta.31 → 0.2.0-beta.33

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.
Files changed (343) hide show
  1. package/README.md +1 -0
  2. package/package.json +90 -3
  3. package/src/adapters/abstract/application-adapter.d.ts +0 -8
  4. package/src/adapters/abstract/application-adapter.js +252 -261
  5. package/src/adapters/abstract/router-adapter.js +12 -4
  6. package/src/adapters/abstract/segment-path-matcher.js +132 -134
  7. package/src/adapters/abstract/server-adapter.js +22 -14
  8. package/src/adapters/abstract/ws-pattern-matcher.js +24 -26
  9. package/src/adapters/bun/bun-user-websocket-lifecycle.js +83 -86
  10. package/src/adapters/bun/client-bridge.js +51 -50
  11. package/src/adapters/bun/create-app.js +171 -161
  12. package/src/adapters/bun/hmr-manager.js +62 -57
  13. package/src/adapters/bun/index.js +2 -31
  14. package/src/adapters/bun/runtime-host.js +61 -54
  15. package/src/adapters/bun/server-adapter.d.ts +0 -1
  16. package/src/adapters/bun/server-adapter.js +561 -561
  17. package/src/adapters/bun/static-preview-host.js +43 -46
  18. package/src/adapters/create-app.js +11 -14
  19. package/src/adapters/index.js +2 -30
  20. package/src/adapters/node/create-app.js +123 -129
  21. package/src/adapters/node/http-request-bridge.js +147 -106
  22. package/src/adapters/node/node-client-bridge.js +62 -64
  23. package/src/adapters/node/node-hmr-manager.js +58 -48
  24. package/src/adapters/node/runtime-host.js +96 -89
  25. package/src/adapters/node/server-adapter-dependencies.js +18 -21
  26. package/src/adapters/node/server-adapter.d.ts +0 -1
  27. package/src/adapters/node/server-adapter.js +347 -326
  28. package/src/adapters/node/static-content-server.js +172 -191
  29. package/src/adapters/node/static-preview-host.js +87 -78
  30. package/src/adapters/shared/hmr/dev-transform-entrypoint-registry.d.ts +16 -0
  31. package/src/adapters/shared/hmr/dev-transform-entrypoint-registry.js +32 -0
  32. package/src/adapters/shared/hmr/hmr-html-response.js +46 -32
  33. package/src/adapters/shared/hmr/shared-hmr-manager.d.ts +29 -38
  34. package/src/adapters/shared/hmr/shared-hmr-manager.js +439 -425
  35. package/src/adapters/shared/http/api-request-pipeline.js +122 -119
  36. package/src/adapters/shared/http/api-response.js +77 -77
  37. package/src/adapters/shared/http/create-body-response.js +22 -19
  38. package/src/adapters/shared/http/define-api-handler.js +41 -55
  39. package/src/adapters/shared/http/explicit-static-render-preparation.js +26 -23
  40. package/src/adapters/shared/http/explicit-static-route-matcher.js +55 -62
  41. package/src/adapters/shared/http/file-route-middleware-pipeline.js +81 -75
  42. package/src/adapters/shared/http/fs-server-response-factory.js +101 -96
  43. package/src/adapters/shared/http/fs-server-response-matcher.js +239 -257
  44. package/src/adapters/shared/http/run-middleware-chain.js +15 -15
  45. package/src/adapters/shared/runtime/application-adapter.js +72 -87
  46. package/src/adapters/shared/runtime/copy-runtime-public-dir.js +25 -22
  47. package/src/adapters/shared/runtime/port-manager.js +207 -177
  48. package/src/adapters/shared/runtime/render-context.js +94 -79
  49. package/src/adapters/shared/runtime/runtime-app-bootstrap.js +33 -38
  50. package/src/adapters/shared/runtime/runtime-host.js +1 -0
  51. package/src/adapters/shared/runtime/runtime-server-lifecycle.d.ts +2 -3
  52. package/src/adapters/shared/runtime/runtime-server-lifecycle.js +65 -51
  53. package/src/adapters/shared/runtime/server-adapter.d.ts +1 -0
  54. package/src/adapters/shared/runtime/server-adapter.js +233 -217
  55. package/src/adapters/shared/runtime/server-route-handler.js +74 -70
  56. package/src/adapters/shared/runtime/server-static-builder.js +165 -184
  57. package/src/adapters/shared/runtime/static-preview-host.js +1 -0
  58. package/src/adapters/shared/ws/node-http-websocket-upgrades.js +97 -88
  59. package/src/adapters/shared/ws/websocket-lifecycle.js +57 -50
  60. package/src/build/README.md +52 -1
  61. package/src/build/app-build-manifest-runtime.js +129 -108
  62. package/src/build/browser/browser-runtime-manifest.js +47 -50
  63. package/src/build/browser/browser-runtime-plugin-helpers.js +32 -12
  64. package/src/build/browser/browser-runtime-plugin.js +206 -160
  65. package/src/build/browser/jsx-ownership-plugins.js +51 -37
  66. package/src/build/browser/lit-static-render-worker-context.js +3 -5
  67. package/src/build/build-adapter.js +276 -139
  68. package/src/build/cache/build-input-fingerprint.js +28 -26
  69. package/src/build/cache/cache-constants.js +4 -6
  70. package/src/build/cache/cache-keys.js +64 -56
  71. package/src/build/cache/pages-unified-graph-build.js +179 -178
  72. package/src/build/cache/production-build-cache.js +47 -54
  73. package/src/build/cache/server-entry-build-cache.js +134 -146
  74. package/src/build/contracts/build-contracts.d.ts +4 -4
  75. package/src/build/contracts/build-contracts.js +1 -0
  76. package/src/build/contracts/build-manifest.js +58 -43
  77. package/src/build/contracts/build-types.js +1 -0
  78. package/src/build/rolldown/rolldown-adapter-helpers.d.ts +9 -0
  79. package/src/build/rolldown/rolldown-adapter-helpers.js +405 -298
  80. package/src/build/rolldown/rolldown-build-adapter.js +53 -61
  81. package/src/build/rolldown/rolldown-build-invocation-metrics.js +31 -35
  82. package/src/build/rolldown/rolldown-plugin-bridge.js +264 -194
  83. package/src/build/rolldown/rolldown-source-transform-pass.js +59 -50
  84. package/src/build/rolldown/runtime-build-output-normalizer.js +227 -175
  85. package/src/build/rolldown/server-side-css-shim-plugin.js +54 -31
  86. package/src/build/runtime/build-profile-options.js +36 -36
  87. package/src/build/runtime/build-request-identity.js +70 -45
  88. package/src/build/runtime/build-request-policy.js +80 -42
  89. package/src/build/runtime/build-runtime.js +64 -54
  90. package/src/build/runtime/deduping-build-executor.js +38 -32
  91. package/src/build/runtime/parallel-build-executor.js +58 -50
  92. package/src/build/runtime/serialized-build-executor.js +78 -62
  93. package/src/cache/index.js +6 -6
  94. package/src/cache/module-parse-cache.js +99 -68
  95. package/src/client/navigation-scripts/classification.js +45 -37
  96. package/src/client/navigation-scripts/index.js +3 -23
  97. package/src/client/navigation-scripts/navigation-scripts.test.browser.js +58 -62
  98. package/src/client/navigation-scripts/registry.js +15 -11
  99. package/src/client/navigation-scripts/rerun-queue.js +81 -64
  100. package/src/client/scroll.js +32 -24
  101. package/src/client/scroll.test.browser.js +27 -33
  102. package/src/client/view-transitions.js +68 -55
  103. package/src/config/config-builder.d.ts +8 -0
  104. package/src/config/config-builder.js +637 -642
  105. package/src/config/constants.js +44 -24
  106. package/src/declarations.d.ts +1 -0
  107. package/src/dev/README.md +24 -0
  108. package/src/dev/client-bridge-registry.js +7 -12
  109. package/src/dev/dev-client-ownership.js +7 -5
  110. package/src/dev/hmr-manager-registry.js +7 -12
  111. package/src/dev/host-runtime.js +25 -30
  112. package/src/dev/runtime-server-started-message.js +2 -5
  113. package/src/dev/sc-server.js +106 -103
  114. package/src/dev/transform-server/dev-transform-bundler.d.ts +24 -0
  115. package/src/dev/transform-server/dev-transform-bundler.js +79 -0
  116. package/src/dev/transform-server/dev-transform-externalize-plugin.d.ts +12 -0
  117. package/src/dev/transform-server/dev-transform-externalize-plugin.js +29 -0
  118. package/src/dev/transform-server/dev-transform-import-rewriter.d.ts +16 -0
  119. package/src/dev/transform-server/dev-transform-import-rewriter.js +110 -0
  120. package/src/dev/transform-server/dev-transform-module-kind.d.ts +13 -0
  121. package/src/dev/transform-server/dev-transform-module-kind.js +17 -0
  122. package/src/dev/transform-server/dev-transform-runtime-specifiers.d.ts +5 -0
  123. package/src/dev/transform-server/dev-transform-runtime-specifiers.js +16 -0
  124. package/src/dev/transform-server/dev-transform-server.d.ts +41 -0
  125. package/src/dev/transform-server/dev-transform-server.js +191 -0
  126. package/src/dev/transform-server/dev-transform-url.d.ts +13 -0
  127. package/src/dev/transform-server/dev-transform-url.js +58 -0
  128. package/src/dev/transform-server/dev-transform-vendor-registry.d.ts +27 -0
  129. package/src/dev/transform-server/dev-transform-vendor-registry.js +145 -0
  130. package/src/dev/transform-server/index.d.ts +6 -0
  131. package/src/dev/transform-server/index.js +4 -0
  132. package/src/dev/transform-server/types.d.ts +15 -0
  133. package/src/dev/transform-server/types.js +1 -0
  134. package/src/dev-toolbar/README.md +51 -0
  135. package/src/dev-toolbar/define-dev-tool.d.ts +21 -0
  136. package/src/dev-toolbar/define-dev-tool.js +9 -0
  137. package/src/dev-toolbar/dev-toolbar-config.d.ts +25 -0
  138. package/src/dev-toolbar/dev-toolbar-config.js +19 -0
  139. package/src/dev-toolbar/dev-toolbar-host.d.ts +49 -0
  140. package/src/dev-toolbar/dev-toolbar-host.js +117 -0
  141. package/src/dev-toolbar/dev-toolbar-html-response.d.ts +11 -0
  142. package/src/dev-toolbar/dev-toolbar-html-response.js +14 -0
  143. package/src/dev-toolbar/dev-toolbar-manifest.d.ts +15 -0
  144. package/src/dev-toolbar/dev-toolbar-manifest.js +52 -0
  145. package/src/dev-toolbar/dev-toolbar-package.d.ts +31 -0
  146. package/src/dev-toolbar/dev-toolbar-package.js +72 -0
  147. package/src/dev-toolbar/dev-toolbar-runtime-paths.d.ts +10 -0
  148. package/src/dev-toolbar/dev-toolbar-runtime-paths.js +13 -0
  149. package/src/diagnostics/request-build-dedupe.js +34 -28
  150. package/src/diagnostics/startup-trace.d.ts +10 -1
  151. package/src/diagnostics/startup-trace.js +269 -241
  152. package/src/eco/README.md +6 -0
  153. package/src/eco/eco-declared-component.js +19 -14
  154. package/src/eco/eco.browser.js +56 -69
  155. package/src/eco/eco.js +156 -96
  156. package/src/eco/eco.types.js +5 -0
  157. package/src/eco/eco.utils.js +1 -10
  158. package/src/eco/global-injector-map.js +55 -41
  159. package/src/eco/lazy-injector-map.js +90 -60
  160. package/src/eco/module-dependencies.js +52 -44
  161. package/src/eco/page-layout-normalization.js +59 -49
  162. package/src/errors/http-error.js +50 -49
  163. package/src/errors/index.js +3 -12
  164. package/src/errors/locals-access-error.js +5 -8
  165. package/src/errors/undeclared-component-dependency-error.js +15 -15
  166. package/src/global/app-logger.js +3 -6
  167. package/src/hmr/README.md +10 -0
  168. package/src/hmr/client/hmr-runtime.js +117 -113
  169. package/src/hmr/client/module-update.d.ts +13 -0
  170. package/src/hmr/client/module-update.js +39 -0
  171. package/src/hmr/hmr-asset-paths.d.ts +14 -0
  172. package/src/hmr/hmr-asset-paths.js +22 -0
  173. package/src/hmr/hmr-entrypoint-output.d.ts +11 -39
  174. package/src/hmr/hmr-entrypoint-output.js +28 -54
  175. package/src/hmr/hmr-file-change-prep.js +13 -16
  176. package/src/hmr/hmr-registered-entrypoints-context.d.ts +7 -0
  177. package/src/hmr/hmr-registered-entrypoints-context.js +1 -0
  178. package/src/hmr/hmr-runtime-paths.d.ts +10 -0
  179. package/src/hmr/hmr-runtime-paths.js +13 -0
  180. package/src/hmr/hmr-strategy.d.ts +5 -11
  181. package/src/hmr/hmr-strategy.js +113 -61
  182. package/src/hmr/strategies/default-hmr-strategy.js +55 -33
  183. package/src/hmr/strategies/js-hmr-strategy.d.ts +6 -95
  184. package/src/hmr/strategies/js-hmr-strategy.js +104 -217
  185. package/src/hmr/strategies/server-rendered-template-hmr-strategy.js +33 -27
  186. package/src/index.browser.js +1 -4
  187. package/src/index.d.ts +1 -0
  188. package/src/index.js +6 -47
  189. package/src/integrations/ghtml/ghtml-renderer.js +12 -7
  190. package/src/integrations/ghtml/ghtml.constants.js +1 -4
  191. package/src/integrations/ghtml/ghtml.plugin.js +9 -12
  192. package/src/islands/README.md +25 -0
  193. package/src/islands/island-host.d.ts +37 -0
  194. package/src/islands/island-host.js +55 -0
  195. package/src/plugins/alias-resolver-cache.js +114 -97
  196. package/src/plugins/alias-resolver-plugin.js +33 -47
  197. package/src/plugins/define-integration.js +18 -17
  198. package/src/plugins/eco-component-meta-plugin.js +387 -145
  199. package/src/plugins/foreign-jsx-override-plugin.js +49 -35
  200. package/src/plugins/integration-plugin.js +212 -203
  201. package/src/plugins/jsx-import-source.utils.js +16 -21
  202. package/src/plugins/processor.js +159 -149
  203. package/src/plugins/runtime-capability.js +1 -0
  204. package/src/plugins/source-transform.js +109 -79
  205. package/src/plugins/tsconfig-import-resolver.d.ts +17 -0
  206. package/src/plugins/tsconfig-import-resolver.js +218 -142
  207. package/src/route-renderer/README.md +12 -1
  208. package/src/route-renderer/orchestration/document-shell/document-shell-render.service.js +143 -136
  209. package/src/route-renderer/orchestration/document-shell/layout-shell-props.service.js +33 -27
  210. package/src/route-renderer/orchestration/foreign-child/component-render-context.js +173 -126
  211. package/src/route-renderer/orchestration/foreign-child/foreign-child-output.utils.js +165 -154
  212. package/src/route-renderer/orchestration/foreign-child/foreign-subtree-execution.service.js +329 -341
  213. package/src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.js +33 -32
  214. package/src/route-renderer/orchestration/integration-renderer.d.ts +1 -0
  215. package/src/route-renderer/orchestration/integration-renderer.js +731 -750
  216. package/src/route-renderer/orchestration/integration-renderer.test-fixtures.js +168 -172
  217. package/src/route-renderer/orchestration/ownership-graph/component-graph-collectors.js +119 -131
  218. package/src/route-renderer/orchestration/ownership-graph/component-graph.js +82 -91
  219. package/src/route-renderer/orchestration/ownership-graph/ownership-validation.service.js +82 -76
  220. package/src/route-renderer/orchestration/page-browser-graph/global-injector-assets.service.js +29 -31
  221. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-contribution.loader.js +10 -6
  222. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.js +31 -28
  223. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-session.d.ts +3 -0
  224. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-session.js +430 -413
  225. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph.service.js +191 -212
  226. package/src/route-renderer/orchestration/page-browser-graph/processed-asset-dedupe.js +20 -24
  227. package/src/route-renderer/orchestration/route-pipeline/integration-route-render-adapter.d.ts +4 -0
  228. package/src/route-renderer/orchestration/route-pipeline/integration-route-render-adapter.js +24 -24
  229. package/src/route-renderer/orchestration/route-pipeline/marker-artifact.utils.js +22 -24
  230. package/src/route-renderer/orchestration/route-pipeline/robots-meta.contribution.js +41 -34
  231. package/src/route-renderer/orchestration/route-pipeline/route-html-finalization.service.d.ts +5 -0
  232. package/src/route-renderer/orchestration/route-pipeline/route-html-finalization.service.js +42 -22
  233. package/src/route-renderer/orchestration/route-pipeline/route-prepared-options.builder.js +50 -48
  234. package/src/route-renderer/orchestration/route-pipeline/route-prepared-options.utils.js +29 -32
  235. package/src/route-renderer/orchestration/route-pipeline/route-render-orchestrator.js +150 -156
  236. package/src/route-renderer/orchestration/string-markup-renderer.js +48 -51
  237. package/src/route-renderer/page-loading/component-dependency-collection.js +120 -124
  238. package/src/route-renderer/page-loading/declared-asset-collection.js +66 -94
  239. package/src/route-renderer/page-loading/dependency-resolver.js +101 -104
  240. package/src/route-renderer/page-loading/ecopages-virtual-imports.js +68 -54
  241. package/src/route-renderer/page-loading/lazy-entry-collection.js +75 -98
  242. package/src/route-renderer/page-loading/lazy-trigger-planning.js +46 -36
  243. package/src/route-renderer/page-loading/module-declaration-aggregation.js +38 -31
  244. package/src/route-renderer/page-loading/module-declaration-scripts.js +10 -15
  245. package/src/route-renderer/page-loading/page-dependency-bundling.js +156 -113
  246. package/src/route-renderer/page-loading/page-module-loader.js +130 -124
  247. package/src/route-renderer/route-renderer.js +74 -76
  248. package/src/router/README.md +23 -0
  249. package/src/router/client/link-intent.js +55 -39
  250. package/src/router/client/link-intent.test.browser.js +49 -49
  251. package/src/router/client/link-navigation-policy.js +114 -93
  252. package/src/router/client/link-navigation-policy.test.browser.js +70 -80
  253. package/src/router/client/navigation-coordinator.js +235 -211
  254. package/src/router/client/navigation-lifecycle.d.ts +55 -0
  255. package/src/router/client/navigation-lifecycle.js +50 -0
  256. package/src/router/client/navigation-lifecycle.test.browser.d.ts +1 -0
  257. package/src/router/client/navigation-lifecycle.test.browser.js +118 -0
  258. package/src/router/server/route-registry.js +237 -242
  259. package/src/services/assets/asset-processing-service/asset-dependency-keys.js +64 -53
  260. package/src/services/assets/asset-processing-service/asset-processing.service.js +287 -303
  261. package/src/services/assets/asset-processing-service/asset.factory.js +78 -81
  262. package/src/services/assets/asset-processing-service/assets.types.js +1 -0
  263. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +57 -46
  264. package/src/services/assets/asset-processing-service/browser-runtime-entry-resolution.js +106 -69
  265. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.js +53 -53
  266. package/src/services/assets/asset-processing-service/finalize-processed-asset.js +4 -6
  267. package/src/services/assets/asset-processing-service/grouped-content-bundles.js +79 -80
  268. package/src/services/assets/asset-processing-service/index.js +8 -8
  269. package/src/services/assets/asset-processing-service/inline-content-script-body.js +22 -16
  270. package/src/services/assets/asset-processing-service/materialize-content-script-asset.js +21 -17
  271. package/src/services/assets/asset-processing-service/page-package.js +70 -72
  272. package/src/services/assets/asset-processing-service/processor.interface.js +7 -5
  273. package/src/services/assets/asset-processing-service/processor.registry.js +11 -14
  274. package/src/services/assets/asset-processing-service/processors/base/base-processor.js +59 -62
  275. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.js +102 -117
  276. package/src/services/assets/asset-processing-service/processors/index.js +5 -5
  277. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.js +110 -115
  278. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +95 -97
  279. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +136 -135
  280. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +27 -29
  281. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +34 -40
  282. package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.js +36 -35
  283. package/src/services/assets/asset-processing-service/resolve-integration-plugin.js +14 -16
  284. package/src/services/assets/asset-processing-service/ungrouped-dependency-processing.js +27 -39
  285. package/src/services/assets/browser-bundle.service.js +52 -47
  286. package/src/services/cache/cache.types.js +5 -0
  287. package/src/services/cache/index.js +6 -7
  288. package/src/services/cache/memory-cache-store.js +101 -89
  289. package/src/services/cache/page-cache-service.js +156 -145
  290. package/src/services/cache/page-request-cache-coordinator.service.js +102 -102
  291. package/src/services/html/html-rewriter-provider.service.js +61 -61
  292. package/src/services/html/html-transformer.service.js +249 -266
  293. package/src/services/invalidation/development-invalidation.service.js +252 -241
  294. package/src/services/module-loading/app-module-loader.service.js +1 -0
  295. package/src/services/module-loading/app-server-module-transpiler.service.js +107 -101
  296. package/src/services/module-loading/host-module-loader-registry.js +6 -11
  297. package/src/services/module-loading/module-loading-types.js +1 -0
  298. package/src/services/module-loading/page-module-import.service.js +235 -243
  299. package/src/services/module-loading/route-module-build-cache-registry.js +47 -33
  300. package/src/services/module-loading/route-module-build-cache.js +3 -38
  301. package/src/services/module-loading/route-module-build-cache.store.js +195 -200
  302. package/src/services/module-loading/route-module-build-manifest.js +61 -74
  303. package/src/services/module-loading/route-module-dependency-hasher.js +136 -110
  304. package/src/services/module-loading/server-module-transpiler.service.js +68 -62
  305. package/src/services/module-loading/source-module-support.js +15 -7
  306. package/src/services/runtime-state/dev-graph.service.js +165 -157
  307. package/src/services/runtime-state/entrypoint-dependency-graph.service.js +85 -76
  308. package/src/services/runtime-state/server-invalidation-state.service.js +38 -30
  309. package/src/services/validation/schema-validation-service.js +157 -95
  310. package/src/services/validation/standard-schema.types.js +1 -0
  311. package/src/services/validation/validate-standard-schema.js +13 -13
  312. package/src/static-site-generator/production-page-browser-graph-prebuild.js +35 -19
  313. package/src/static-site-generator/sitemap-routes.js +33 -28
  314. package/src/static-site-generator/sitemap.js +38 -29
  315. package/src/static-site-generator/static-build-invalidation.js +34 -56
  316. package/src/static-site-generator/static-export-context.js +1 -0
  317. package/src/static-site-generator/static-site-generator.js +517 -553
  318. package/src/types/internal-types.d.ts +19 -3
  319. package/src/types/internal-types.js +1 -0
  320. package/src/types/public-types.d.ts +16 -46
  321. package/src/types/public-types.js +1 -0
  322. package/src/utils/deep-merge.js +39 -26
  323. package/src/utils/ecopages-route-info.js +27 -23
  324. package/src/utils/hash.js +3 -6
  325. package/src/utils/html-escaping.js +21 -8
  326. package/src/utils/html.js +1 -4
  327. package/src/utils/invariant.js +11 -10
  328. package/src/utils/locals-utils.js +32 -22
  329. package/src/utils/parse-cli-args.js +73 -65
  330. package/src/utils/path-pattern.js +38 -23
  331. package/src/utils/path-utils.module.js +8 -11
  332. package/src/utils/resolve-entry-file.js +70 -38
  333. package/src/utils/resolve-work-dir.js +23 -27
  334. package/src/utils/runtime.js +24 -33
  335. package/src/utils/server-utils.module.js +60 -52
  336. package/src/utils/static-file-extensions.js +52 -46
  337. package/src/watchers/project-watcher-ignore.js +16 -15
  338. package/src/watchers/project-watcher.js +385 -366
  339. package/src/watchers/project-watcher.test-helpers.js +45 -50
  340. package/src/adapters/shared/hmr/hmr-entrypoint-registrar.d.ts +0 -56
  341. package/src/adapters/shared/hmr/hmr-entrypoint-registrar.js +0 -106
  342. package/src/build/cache/dev-browser-script-cache.d.ts +0 -34
  343. package/src/build/cache/dev-browser-script-cache.js +0 -90
@@ -1,36 +1,43 @@
1
- import { escapeHtmlAttribute } from "../../../utils/html-escaping.js";
2
- function buildRobotsMetaContribution(metadata) {
3
- const content = formatRobotsMetaContent(metadata.robots);
4
- if (!content) {
5
- return void 0;
6
- }
7
- return {
8
- placement: "head-append",
9
- html: `<meta name="robots" content="${escapeHtmlAttribute(content)}">`
10
- };
1
+ import { escapeHtmlAttribute } from '../../../utils/html-escaping.js';
2
+ /**
3
+ * Builds a head contribution for non-default `metadata.robots` values.
4
+ *
5
+ * @remarks
6
+ * When `robots` is omitted or matches the default `index,follow` behaviour,
7
+ * no tag is emitted (Next.js parity). Otherwise a single
8
+ * `<meta name="robots" content="...">` contribution is returned.
9
+ */
10
+ export function buildRobotsMetaContribution(metadata) {
11
+ const content = formatRobotsMetaContent(metadata.robots);
12
+ if (!content) {
13
+ return undefined;
14
+ }
15
+ return {
16
+ placement: 'head-append',
17
+ html: `<meta name="robots" content="${escapeHtmlAttribute(content)}">`,
18
+ };
11
19
  }
12
- function formatRobotsMetaContent(robots) {
13
- if (!robots) {
14
- return void 0;
15
- }
16
- const index = robots.index !== false;
17
- const follow = robots.follow !== false;
18
- const directives = [];
19
- if (!index) {
20
- directives.push("noindex");
21
- }
22
- if (!follow) {
23
- directives.push("nofollow");
24
- }
25
- if (robots.nocache) {
26
- directives.push("nocache");
27
- }
28
- if (directives.length === 0) {
29
- return void 0;
30
- }
31
- return directives.join(", ");
20
+ /**
21
+ * Formats robots directives for a meta tag, or `undefined` when defaults apply.
22
+ */
23
+ export function formatRobotsMetaContent(robots) {
24
+ if (!robots) {
25
+ return undefined;
26
+ }
27
+ const index = robots.index !== false;
28
+ const follow = robots.follow !== false;
29
+ const directives = [];
30
+ if (!index) {
31
+ directives.push('noindex');
32
+ }
33
+ if (!follow) {
34
+ directives.push('nofollow');
35
+ }
36
+ if (robots.nocache) {
37
+ directives.push('nocache');
38
+ }
39
+ if (directives.length === 0) {
40
+ return undefined;
41
+ }
42
+ return directives.join(', ');
32
43
  }
33
- export {
34
- buildRobotsMetaContribution,
35
- formatRobotsMetaContent
36
- };
@@ -1,7 +1,12 @@
1
1
  import type { HtmlDocumentContribution } from '../../../services/html/html-transformer.service.js';
2
2
  import type { IntegrationRendererRenderOptions } from '../../../types/public-types.js';
3
3
  import type { RouteHtmlFinalization } from './route-render-orchestrator.js';
4
+ import type { EcoPagesAppConfig } from '../../../types/internal-types.js';
4
5
  export type RouteHtmlFinalizationContext<C> = {
6
+ appConfig: EcoPagesAppConfig;
7
+ watch: boolean;
8
+ hostOwnsDevClient?: boolean;
9
+ integrationName: string;
5
10
  renderOptions: IntegrationRendererRenderOptions<C>;
6
11
  getDocumentAttributes: (renderOptions: IntegrationRendererRenderOptions<C>) => Record<string, string> | undefined;
7
12
  getHtmlDocumentContributions: (options: {
@@ -1,24 +1,44 @@
1
- import { buildRobotsMetaContribution } from "./robots-meta.contribution.js";
2
- function buildRouteHtmlFinalization(context) {
3
- const { renderOptions } = context;
4
- const documentAttributes = context.getDocumentAttributes(renderOptions);
5
- const integrationContributions = context.getHtmlDocumentContributions({ renderOptions, partial: false }) ?? [];
6
- const robotsContribution = buildRobotsMetaContribution(renderOptions.metadata ?? {});
7
- const htmlContributions = robotsContribution ? [robotsContribution, ...integrationContributions] : integrationContributions;
8
- const hasStructuralFinalization = documentAttributes && Object.keys(documentAttributes).length > 0;
9
- if (!hasStructuralFinalization && htmlContributions.length === 0) {
10
- return {};
11
- }
12
- return {
13
- htmlContributions,
14
- finalizeHtml: (html) => {
15
- if (!documentAttributes || Object.keys(documentAttributes).length === 0) {
16
- return html;
17
- }
18
- return context.applyAttributesToHtmlElement(html, documentAttributes);
1
+ import { buildRobotsMetaContribution } from './robots-meta.contribution.js';
2
+ import { DevToolbarHost } from '../../../dev-toolbar/dev-toolbar-host.js';
3
+ /**
4
+ * Builds the structural HTML finalization plan for one prepared route render.
5
+ *
6
+ * @remarks
7
+ * Merges core robots meta contributions with integration-owned document
8
+ * contributions so page-level `metadata.robots` works across templates.
9
+ */
10
+ export function buildRouteHtmlFinalization(context) {
11
+ const { renderOptions } = context;
12
+ const documentAttributes = context.getDocumentAttributes(renderOptions);
13
+ const integrationContributions = context.getHtmlDocumentContributions({ renderOptions, partial: false }) ?? [];
14
+ const robotsContribution = buildRobotsMetaContribution(renderOptions.metadata ?? {});
15
+ const devToolbarContribution = buildDevToolbarManifestContribution(context);
16
+ const htmlContributions = [
17
+ ...(robotsContribution ? [robotsContribution] : []),
18
+ ...(devToolbarContribution ? [devToolbarContribution] : []),
19
+ ...integrationContributions,
20
+ ];
21
+ const hasStructuralFinalization = documentAttributes && Object.keys(documentAttributes).length > 0;
22
+ if (!hasStructuralFinalization && htmlContributions.length === 0) {
23
+ return {};
19
24
  }
20
- };
25
+ return {
26
+ htmlContributions,
27
+ finalizeHtml: (html) => {
28
+ if (!documentAttributes || Object.keys(documentAttributes).length === 0) {
29
+ return html;
30
+ }
31
+ return context.applyAttributesToHtmlElement(html, documentAttributes);
32
+ },
33
+ };
34
+ }
35
+ function buildDevToolbarManifestContribution(context) {
36
+ return DevToolbarHost.forApp(context.appConfig, {
37
+ watch: context.watch,
38
+ hostOwnsDevClient: context.hostOwnsDevClient,
39
+ }).buildRouteManifestContribution({
40
+ routeFile: context.renderOptions.file,
41
+ integrationName: context.integrationName,
42
+ pagePackage: context.renderOptions.pagePackage,
43
+ });
21
44
  }
22
- export {
23
- buildRouteHtmlFinalization
24
- };
@@ -1,49 +1,51 @@
1
- import { createPagePackage } from "../../../services/assets/asset-processing-service/index.js";
2
- import { dedupeProcessedAssets } from "../page-browser-graph/processed-asset-dedupe.js";
3
- import { createPageLocalsProxy } from "./route-prepared-options.utils.js";
4
- function buildPreparedRenderOptions(input) {
5
- const { routeOptions, resolvedInputs, resolvedDependencies, allDependencies, pageBrowserGraph, appConfig } = input;
6
- const { Page, HtmlTemplate, Layouts, Layout, layoutEntries, props, metadata, integrationSpecificProps } = resolvedInputs;
7
- const dedupedDependencies = dedupeProcessedAssets(allDependencies);
8
- const pagePackage = createPagePackage(dedupedDependencies, { pageBrowserGraph });
9
- const resolvedProps = {
10
- ...props,
11
- ...routeOptions.props ?? {}
12
- };
13
- const pageProps = {
14
- ...resolvedProps,
15
- params: routeOptions.params || {},
16
- query: routeOptions.query || {}
17
- };
18
- const cacheStrategy = Page.cache;
19
- const defaultCacheStrategy = appConfig.cache?.defaultStrategy ?? "static";
20
- const effectiveCacheStrategy = cacheStrategy ?? defaultCacheStrategy;
21
- const localsAvailable = effectiveCacheStrategy === "dynamic" && routeOptions.locals !== void 0;
22
- const pageLocals = localsAvailable ? routeOptions.locals : createPageLocalsProxy(routeOptions.file);
23
- const locals = localsAvailable ? routeOptions.locals : void 0;
24
- const preparedOptions = {
25
- ...routeOptions,
26
- resolvedDependencies,
27
- pagePackage,
28
- HtmlTemplate,
29
- Layouts,
30
- Layout,
31
- layoutEntries,
32
- props: resolvedProps,
33
- Page,
34
- metadata,
35
- params: routeOptions.params || {},
36
- query: routeOptions.query || {},
37
- pageProps,
38
- locals,
39
- pageLocals,
40
- cacheStrategy
41
- };
42
- return {
43
- ...integrationSpecificProps,
44
- ...preparedOptions
45
- };
1
+ import { createPagePackage } from '../../../services/assets/asset-processing-service/index.js';
2
+ import { dedupeProcessedAssets } from '../page-browser-graph/processed-asset-dedupe.js';
3
+ import { createPageLocalsProxy } from './route-prepared-options.utils.js';
4
+ /**
5
+ * Assembles the final integration render options after route prep dependencies resolve.
6
+ */
7
+ export function buildPreparedRenderOptions(input) {
8
+ const { routeOptions, resolvedInputs, resolvedDependencies, allDependencies, pageBrowserGraph, appConfig } = input;
9
+ const { Page, HtmlTemplate, Layouts, Layout, layoutEntries, props, metadata, integrationSpecificProps } = resolvedInputs;
10
+ const dedupedDependencies = dedupeProcessedAssets(allDependencies);
11
+ const pagePackage = createPagePackage(dedupedDependencies, { pageBrowserGraph });
12
+ const resolvedProps = {
13
+ ...props,
14
+ ...(routeOptions.props ?? {}),
15
+ };
16
+ const pageProps = {
17
+ ...resolvedProps,
18
+ params: routeOptions.params || {},
19
+ query: routeOptions.query || {},
20
+ };
21
+ const cacheStrategy = Page.cache;
22
+ const defaultCacheStrategy = appConfig.cache?.defaultStrategy ?? 'static';
23
+ const effectiveCacheStrategy = cacheStrategy ?? defaultCacheStrategy;
24
+ const localsAvailable = effectiveCacheStrategy === 'dynamic' && routeOptions.locals !== undefined;
25
+ const pageLocals = localsAvailable
26
+ ? routeOptions.locals
27
+ : createPageLocalsProxy(routeOptions.file);
28
+ const locals = localsAvailable ? routeOptions.locals : undefined;
29
+ const preparedOptions = {
30
+ ...routeOptions,
31
+ resolvedDependencies,
32
+ pagePackage,
33
+ HtmlTemplate: HtmlTemplate,
34
+ Layouts,
35
+ Layout,
36
+ layoutEntries,
37
+ props: resolvedProps,
38
+ Page: Page,
39
+ metadata,
40
+ params: routeOptions.params || {},
41
+ query: routeOptions.query || {},
42
+ pageProps,
43
+ locals,
44
+ pageLocals,
45
+ cacheStrategy,
46
+ };
47
+ return {
48
+ ...integrationSpecificProps,
49
+ ...preparedOptions,
50
+ };
46
51
  }
47
- export {
48
- buildPreparedRenderOptions
49
- };
@@ -1,33 +1,30 @@
1
- import { LocalsAccessError } from "../../../errors/locals-access-error.js";
2
- function createPageLocalsProxy(filePath) {
3
- const errorMessage = `[ecopages] Request locals are only available during request-time rendering with cache: 'dynamic'. Page: ${filePath}. If you meant to use locals here, set cache: 'dynamic' and provide locals from route middleware/handlers.`;
4
- return new Proxy(
5
- {},
6
- {
7
- get: () => {
8
- throw new LocalsAccessError(errorMessage);
9
- },
10
- set: () => {
11
- throw new LocalsAccessError(errorMessage);
12
- },
13
- has: () => {
14
- throw new LocalsAccessError(errorMessage);
15
- },
16
- ownKeys: () => {
17
- throw new LocalsAccessError(errorMessage);
18
- },
19
- deleteProperty: () => {
20
- throw new LocalsAccessError(errorMessage);
21
- },
22
- defineProperty: () => {
23
- throw new LocalsAccessError(errorMessage);
24
- },
25
- getOwnPropertyDescriptor: () => {
26
- throw new LocalsAccessError(errorMessage);
27
- }
28
- }
29
- );
1
+ import { LocalsAccessError } from '../../../errors/locals-access-error.js';
2
+ /**
3
+ * Proxy that throws when dynamic route locals are accessed on non-dynamic pages.
4
+ */
5
+ export function createPageLocalsProxy(filePath) {
6
+ const errorMessage = `[ecopages] Request locals are only available during request-time rendering with cache: 'dynamic'. Page: ${filePath}. If you meant to use locals here, set cache: 'dynamic' and provide locals from route middleware/handlers.`;
7
+ return new Proxy({}, {
8
+ get: () => {
9
+ throw new LocalsAccessError(errorMessage);
10
+ },
11
+ set: () => {
12
+ throw new LocalsAccessError(errorMessage);
13
+ },
14
+ has: () => {
15
+ throw new LocalsAccessError(errorMessage);
16
+ },
17
+ ownKeys: () => {
18
+ throw new LocalsAccessError(errorMessage);
19
+ },
20
+ deleteProperty: () => {
21
+ throw new LocalsAccessError(errorMessage);
22
+ },
23
+ defineProperty: () => {
24
+ throw new LocalsAccessError(errorMessage);
25
+ },
26
+ getOwnPropertyDescriptor: () => {
27
+ throw new LocalsAccessError(errorMessage);
28
+ },
29
+ });
30
30
  }
31
- export {
32
- createPageLocalsProxy
33
- };
@@ -1,162 +1,156 @@
1
- import { inspectUnresolvedMarkerArtifactHtml } from "./marker-artifact.utils.js";
2
- import {
3
- OwnershipValidationService,
4
- throwIfOwnershipInvalid
5
- } from "../ownership-graph/ownership-validation.service.js";
6
- import {
7
- buildEagerSsrLazyAssetsFromGraph,
8
- collectResolvedLazyTriggersFromGraph,
9
- collectUsedIntegrationDependenciesFromGraph
10
- } from "../ownership-graph/component-graph-collectors.js";
11
- import { buildGlobalInjectorAssets } from "../page-browser-graph/global-injector-assets.service.js";
12
- import { PageBrowserGraphService } from "../page-browser-graph/page-browser-graph.service.js";
13
- import { buildPreparedRenderOptions } from "./route-prepared-options.builder.js";
14
- class RouteRenderOrchestrator {
15
- appConfig;
16
- assetProcessingService;
17
- ownershipValidationService;
18
- pageBrowserGraphService;
19
- constructor(appConfig, assetProcessingService, dependencies = {}) {
20
- this.appConfig = appConfig;
21
- this.assetProcessingService = assetProcessingService;
22
- this.ownershipValidationService = dependencies.ownershipValidationService ?? new OwnershipValidationService(appConfig);
23
- this.pageBrowserGraphService = dependencies.pageBrowserGraphService ?? new PageBrowserGraphService(appConfig, assetProcessingService);
24
- }
25
- /**
26
- * Builds normalized route render options before the integration render runs.
27
- *
28
- * This preparation step validates route-root ownership, resolves page data,
29
- * collects processed assets, and produces the page package consumed by downstream
30
- * HTML transformation.
31
- */
32
- async prepareRenderOptions(routeOptions, adapter) {
33
- const resolvedInputs = await adapter.resolveRouteRenderInputs(routeOptions);
34
- const { Page, HtmlTemplate, Layouts } = resolvedInputs;
35
- const validationErrors = this.ownershipValidationService.validate({
36
- currentIntegrationName: adapter.name,
37
- roots: [
38
- { component: HtmlTemplate, source: "html-template" },
39
- ...Layouts.map((layout) => ({ component: layout, source: "layout" })),
40
- { component: Page, source: "page" }
41
- ]
42
- });
43
- throwIfOwnershipInvalid(validationErrors);
44
- const componentsToResolve = [HtmlTemplate, ...Layouts, Page];
45
- const [{ resolvedDependencies }, pageBrowserGraph] = await Promise.all([
46
- adapter.resolveRouteDependencies({
47
- components: componentsToResolve
48
- }),
49
- this.pageBrowserGraphService.resolvePageBrowserGraph({
50
- routeFile: routeOptions.file,
51
- integrationName: adapter.name,
52
- collectContribution: async (routeFile) => await adapter.collectPageBrowserGraphContribution(routeFile)
53
- })
54
- ]);
55
- const allDependencies = [
56
- ...resolvedDependencies,
57
- ...collectUsedIntegrationDependenciesFromGraph(this.appConfig, componentsToResolve, adapter.name)
58
- ];
59
- const triggers = collectResolvedLazyTriggersFromGraph(componentsToResolve, adapter.name);
60
- const [globalAssets, eagerSsrLazyAssets] = await Promise.all([
61
- triggers.length > 0 ? buildGlobalInjectorAssets(this.appConfig, this.assetProcessingService, triggers, adapter.name) : Promise.resolve([]),
62
- buildEagerSsrLazyAssetsFromGraph(this.assetProcessingService, componentsToResolve, adapter.name)
63
- ]);
64
- allDependencies.push(...globalAssets, ...eagerSsrLazyAssets);
65
- return buildPreparedRenderOptions({
66
- routeOptions,
67
- resolvedInputs,
68
- resolvedDependencies,
69
- allDependencies,
70
- pageBrowserGraph,
71
- appConfig: this.appConfig
72
- });
73
- }
74
- async resolveDeclaredPageBrowserGraph(input) {
75
- return await this.pageBrowserGraphService.resolvePageBrowserGraph(input);
76
- }
77
- /**
78
- * Captures one route render body as HTML while preserving a replayable body value.
79
- */
80
- async captureHtmlRender(render) {
81
- const renderedBody = await render();
82
- const capturedRender = await this.captureRenderedBody(renderedBody);
83
- return {
84
- body: capturedRender.body,
85
- html: capturedRender.html
86
- };
87
- }
88
- /**
89
- * Executes the full route-render flow and returns the final body plus cache strategy.
90
- */
91
- async execute(options, adapter) {
92
- const renderOptions = await this.prepareRenderOptions(options, adapter);
93
- return this.executePrepared(renderOptions, adapter);
94
- }
95
- /**
96
- * Executes the route-render finalization path for already prepared render options.
97
- */
98
- async executePrepared(renderOptions, adapter) {
99
- const renderExecution = await this.captureHtmlRender(async () => adapter.renderRouteBody(renderOptions));
100
- const unresolvedArtifactInspection = inspectUnresolvedMarkerArtifactHtml(renderExecution.html);
101
- const htmlFinalization = adapter.getRouteHtmlFinalization(renderOptions);
102
- const hasUnresolvedMarkerHtml = unresolvedArtifactInspection.hasUnresolvedMarkerArtifacts;
103
- if (hasUnresolvedMarkerHtml) {
104
- throw new Error(
105
- "[ecopages] Route render returned unresolved eco-marker artifact HTML. Full-route unresolved-marker fallback has been removed; resolve mixed foreign children inside renderComponentWithForeignChildren()."
106
- );
1
+ import { inspectUnresolvedMarkerArtifactHtml } from './marker-artifact.utils.js';
2
+ import { OwnershipValidationService, throwIfOwnershipInvalid, } from '../ownership-graph/ownership-validation.service.js';
3
+ import { buildEagerSsrLazyAssetsFromGraph, collectResolvedLazyTriggersFromGraph, collectUsedIntegrationDependenciesFromGraph, } from '../ownership-graph/component-graph-collectors.js';
4
+ import { buildGlobalInjectorAssets } from '../page-browser-graph/global-injector-assets.service.js';
5
+ import { PageBrowserGraphService } from '../page-browser-graph/page-browser-graph.service.js';
6
+ import { buildPreparedRenderOptions } from './route-prepared-options.builder.js';
7
+ /**
8
+ * Owns one route render from normalized module loading through final HTML output.
9
+ *
10
+ * This orchestrator keeps route rendering as one app-scoped unit while still
11
+ * delegating integration-specific behavior through the adapter seam. It owns
12
+ * route-root validation, dependency aggregation, page package creation, and the
13
+ * final HTML/body handling that happens after the integration render returns.
14
+ */
15
+ export class RouteRenderOrchestrator {
16
+ appConfig;
17
+ assetProcessingService;
18
+ ownershipValidationService;
19
+ pageBrowserGraphService;
20
+ constructor(appConfig, assetProcessingService, dependencies = {}) {
21
+ this.appConfig = appConfig;
22
+ this.assetProcessingService = assetProcessingService;
23
+ this.ownershipValidationService =
24
+ dependencies.ownershipValidationService ?? new OwnershipValidationService(appConfig);
25
+ this.pageBrowserGraphService =
26
+ dependencies.pageBrowserGraphService ?? new PageBrowserGraphService(appConfig, assetProcessingService);
107
27
  }
108
- const canReuseCapturedBody = !hasUnresolvedMarkerHtml && htmlFinalization.finalizeHtml === void 0;
109
- if (canReuseCapturedBody) {
110
- const body2 = await adapter.transformRouteResponse(
111
- new Response(renderExecution.body, {
112
- headers: {
113
- "Content-Type": "text/html"
114
- }
115
- }),
116
- htmlFinalization.htmlContributions,
117
- renderOptions.pagePackage
118
- );
119
- return {
120
- body: body2,
121
- cacheStrategy: renderOptions.cacheStrategy
122
- };
28
+ /**
29
+ * Builds normalized route render options before the integration render runs.
30
+ *
31
+ * This preparation step validates route-root ownership, resolves page data,
32
+ * collects processed assets, and produces the page package consumed by downstream
33
+ * HTML transformation.
34
+ */
35
+ async prepareRenderOptions(routeOptions, adapter) {
36
+ const resolvedInputs = await adapter.resolveRouteRenderInputs(routeOptions);
37
+ const { Page, HtmlTemplate, Layouts } = resolvedInputs;
38
+ const validationErrors = this.ownershipValidationService.validate({
39
+ currentIntegrationName: adapter.name,
40
+ roots: [
41
+ { component: HtmlTemplate, source: 'html-template' },
42
+ ...Layouts.map((layout) => ({ component: layout, source: 'layout' })),
43
+ { component: Page, source: 'page' },
44
+ ],
45
+ });
46
+ throwIfOwnershipInvalid(validationErrors);
47
+ const componentsToResolve = [HtmlTemplate, ...Layouts, Page];
48
+ const [{ resolvedDependencies }, pageBrowserGraph] = await Promise.all([
49
+ adapter.resolveRouteDependencies({
50
+ components: componentsToResolve,
51
+ }),
52
+ this.pageBrowserGraphService.resolvePageBrowserGraph({
53
+ routeFile: routeOptions.file,
54
+ integrationName: adapter.name,
55
+ collectContribution: async (routeFile) => await adapter.collectPageBrowserGraphContribution(routeFile),
56
+ }),
57
+ ]);
58
+ const allDependencies = [
59
+ ...resolvedDependencies,
60
+ ...collectUsedIntegrationDependenciesFromGraph(this.appConfig, componentsToResolve, adapter.name),
61
+ ];
62
+ const triggers = collectResolvedLazyTriggersFromGraph(componentsToResolve, adapter.name);
63
+ const [globalAssets, eagerSsrLazyAssets] = await Promise.all([
64
+ triggers.length > 0
65
+ ? buildGlobalInjectorAssets(this.appConfig, this.assetProcessingService, triggers, adapter.name)
66
+ : Promise.resolve([]),
67
+ buildEagerSsrLazyAssetsFromGraph(this.assetProcessingService, componentsToResolve, adapter.name),
68
+ ]);
69
+ allDependencies.push(...globalAssets, ...eagerSsrLazyAssets);
70
+ return buildPreparedRenderOptions({
71
+ routeOptions,
72
+ resolvedInputs,
73
+ resolvedDependencies,
74
+ allDependencies,
75
+ pageBrowserGraph,
76
+ appConfig: this.appConfig,
77
+ });
123
78
  }
124
- const finalization = htmlFinalization.finalizeHtml ? htmlFinalization.finalizeHtml(unresolvedArtifactInspection.normalizedHtml) : unresolvedArtifactInspection.normalizedHtml;
125
- const body = await adapter.transformRouteResponse(
126
- new Response(finalization, {
127
- headers: {
128
- "Content-Type": "text/html"
79
+ async resolveDeclaredPageBrowserGraph(input) {
80
+ return await this.pageBrowserGraphService.resolvePageBrowserGraph(input);
81
+ }
82
+ /**
83
+ * Captures one route render body as HTML while preserving a replayable body value.
84
+ */
85
+ async captureHtmlRender(render) {
86
+ const renderedBody = await render();
87
+ const capturedRender = await this.captureRenderedBody(renderedBody);
88
+ return {
89
+ body: capturedRender.body,
90
+ html: capturedRender.html,
91
+ };
92
+ }
93
+ /**
94
+ * Executes the full route-render flow and returns the final body plus cache strategy.
95
+ */
96
+ async execute(options, adapter) {
97
+ const renderOptions = await this.prepareRenderOptions(options, adapter);
98
+ return this.executePrepared(renderOptions, adapter);
99
+ }
100
+ /**
101
+ * Executes the route-render finalization path for already prepared render options.
102
+ */
103
+ async executePrepared(renderOptions, adapter) {
104
+ const renderExecution = await this.captureHtmlRender(async () => adapter.renderRouteBody(renderOptions));
105
+ const unresolvedArtifactInspection = inspectUnresolvedMarkerArtifactHtml(renderExecution.html);
106
+ const htmlFinalization = adapter.getRouteHtmlFinalization(renderOptions);
107
+ const hasUnresolvedMarkerHtml = unresolvedArtifactInspection.hasUnresolvedMarkerArtifacts;
108
+ if (hasUnresolvedMarkerHtml) {
109
+ throw new Error('[ecopages] Route render returned unresolved eco-marker artifact HTML. Full-route unresolved-marker fallback has been removed; resolve mixed foreign children inside renderComponentWithForeignChildren().');
129
110
  }
130
- }),
131
- htmlFinalization.htmlContributions,
132
- renderOptions.pagePackage
133
- );
134
- return {
135
- body,
136
- cacheStrategy: renderOptions.cacheStrategy
137
- };
138
- }
139
- async captureRenderedBody(body) {
140
- const response = new Response(body);
141
- if (typeof body === "string") {
142
- return {
143
- body,
144
- html: await response.text()
145
- };
111
+ const canReuseCapturedBody = !hasUnresolvedMarkerHtml && htmlFinalization.finalizeHtml === undefined;
112
+ if (canReuseCapturedBody) {
113
+ const body = await adapter.transformRouteResponse(new Response(renderExecution.body, {
114
+ headers: {
115
+ 'Content-Type': 'text/html',
116
+ },
117
+ }), htmlFinalization.htmlContributions, renderOptions.pagePackage);
118
+ return {
119
+ body,
120
+ cacheStrategy: renderOptions.cacheStrategy,
121
+ };
122
+ }
123
+ const finalization = htmlFinalization.finalizeHtml
124
+ ? htmlFinalization.finalizeHtml(unresolvedArtifactInspection.normalizedHtml)
125
+ : unresolvedArtifactInspection.normalizedHtml;
126
+ const body = await adapter.transformRouteResponse(new Response(finalization, {
127
+ headers: {
128
+ 'Content-Type': 'text/html',
129
+ },
130
+ }), htmlFinalization.htmlContributions, renderOptions.pagePackage);
131
+ return {
132
+ body,
133
+ cacheStrategy: renderOptions.cacheStrategy,
134
+ };
146
135
  }
147
- if (!response.body) {
148
- return {
149
- body,
150
- html: await response.text()
151
- };
136
+ async captureRenderedBody(body) {
137
+ const response = new Response(body);
138
+ if (typeof body === 'string') {
139
+ return {
140
+ body,
141
+ html: await response.text(),
142
+ };
143
+ }
144
+ if (!response.body) {
145
+ return {
146
+ body,
147
+ html: await response.text(),
148
+ };
149
+ }
150
+ const [capturedBody, replayBody] = response.body.tee();
151
+ return {
152
+ body: replayBody,
153
+ html: await new Response(capturedBody).text(),
154
+ };
152
155
  }
153
- const [capturedBody, replayBody] = response.body.tee();
154
- return {
155
- body: replayBody,
156
- html: await new Response(capturedBody).text()
157
- };
158
- }
159
156
  }
160
- export {
161
- RouteRenderOrchestrator
162
- };