@ecopages/core 0.2.0-alpha.5 → 0.2.0-alpha.7

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 (418) hide show
  1. package/README.md +213 -12
  2. package/package.json +100 -188
  3. package/src/adapters/README.md +39 -0
  4. package/src/adapters/bun/hmr-manager.test.ts +267 -0
  5. package/src/adapters/bun/hmr-manager.ts +180 -47
  6. package/src/adapters/bun/index.ts +1 -2
  7. package/src/adapters/bun/server-adapter.ts +41 -34
  8. package/src/adapters/bun/server-lifecycle.ts +40 -70
  9. package/src/adapters/index.ts +1 -1
  10. package/src/adapters/node/bootstrap-dependency-resolver.test.ts +282 -0
  11. package/src/adapters/node/bootstrap-dependency-resolver.ts +301 -0
  12. package/src/adapters/node/index.ts +7 -0
  13. package/src/adapters/node/node-client-bridge.test.ts +198 -0
  14. package/src/adapters/node/node-hmr-manager.test.ts +322 -0
  15. package/src/adapters/node/node-hmr-manager.ts +207 -97
  16. package/src/adapters/node/runtime-adapter.test.ts +868 -0
  17. package/src/adapters/node/runtime-adapter.ts +439 -0
  18. package/src/adapters/node/server-adapter.ts +31 -104
  19. package/src/adapters/node/static-content-server.test.ts +60 -0
  20. package/src/adapters/node/static-content-server.ts +36 -0
  21. package/src/adapters/node/write-runtime-manifest.ts +38 -0
  22. package/src/adapters/shared/api-response.test.ts +97 -0
  23. package/src/{define-api-handler.ts → adapters/shared/define-api-handler.ts} +1 -1
  24. package/src/adapters/shared/explicit-static-route-matcher.test.ts +381 -0
  25. package/src/adapters/shared/explicit-static-route-matcher.ts +7 -1
  26. package/src/adapters/shared/file-route-middleware-pipeline.test.ts +90 -0
  27. package/src/adapters/shared/file-route-middleware-pipeline.ts +6 -2
  28. package/src/adapters/shared/fs-server-response-factory.test.ts +187 -0
  29. package/src/adapters/shared/fs-server-response-matcher.test.ts +286 -0
  30. package/src/adapters/shared/fs-server-response-matcher.ts +17 -10
  31. package/src/adapters/shared/hmr-entrypoint-registrar.ts +149 -0
  32. package/src/adapters/shared/hmr-html-response.ts +52 -0
  33. package/src/adapters/shared/hmr-manager.contract.test.ts +196 -0
  34. package/src/adapters/shared/hmr-manager.dispatch.test.ts +220 -0
  35. package/src/adapters/shared/render-context.test.ts +146 -0
  36. package/src/adapters/shared/render-context.ts +21 -6
  37. package/src/adapters/shared/runtime-bootstrap.ts +79 -0
  38. package/src/adapters/shared/server-adapter.test.ts +77 -0
  39. package/src/adapters/shared/server-adapter.ts +51 -4
  40. package/src/adapters/shared/server-route-handler.test.ts +110 -0
  41. package/src/adapters/shared/server-route-handler.ts +5 -18
  42. package/src/adapters/shared/server-static-builder.test.ts +316 -0
  43. package/src/adapters/shared/server-static-builder.ts +92 -8
  44. package/src/build/README.md +101 -0
  45. package/src/build/build-adapter-serialization.test.ts +268 -0
  46. package/src/build/build-adapter.test.ts +815 -0
  47. package/src/build/build-adapter.ts +234 -6
  48. package/src/build/build-manifest.ts +54 -0
  49. package/src/build/dev-build-coordinator.ts +221 -0
  50. package/src/build/esbuild-build-adapter.ts +132 -84
  51. package/src/build/runtime-build-executor.ts +34 -0
  52. package/src/build/runtime-specifier-alias-plugin.test.ts +43 -0
  53. package/src/build/runtime-specifier-alias-plugin.ts +58 -0
  54. package/src/config/README.md +33 -0
  55. package/src/config/config-builder.test.ts +410 -0
  56. package/src/config/config-builder.ts +281 -49
  57. package/src/constants.ts +15 -0
  58. package/src/declarations.d.ts +18 -13
  59. package/src/eco/README.md +70 -16
  60. package/src/eco/component-render-context.ts +39 -17
  61. package/src/eco/eco.test.ts +678 -0
  62. package/src/eco/eco.ts +29 -8
  63. package/src/eco/eco.types.ts +20 -1
  64. package/src/eco/eco.utils.test.ts +124 -0
  65. package/src/eco/global-injector-map.test.ts +42 -0
  66. package/src/eco/lazy-injector-map.test.ts +66 -0
  67. package/src/eco/module-dependencies.test.ts +30 -0
  68. package/src/errors/http-error.test.ts +134 -0
  69. package/src/global/utils.test.ts +12 -0
  70. package/src/hmr/README.md +26 -0
  71. package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-HMR-Server-Integration-should-have-HMR-script-injected-in-page-1.png +0 -0
  72. package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-HMR-Server-Integration-should-load-fixture-app-page-1.png +0 -0
  73. package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-WebSocket-Connection-should-connect-to-correct-HMR-endpoint-1.png +0 -0
  74. package/src/hmr/client/hmr-runtime.ts +38 -7
  75. package/src/hmr/hmr-strategy.test.ts +124 -0
  76. package/src/hmr/hmr.postcss.test.e2e.ts +41 -0
  77. package/src/hmr/hmr.test.e2e.ts +29 -38
  78. package/src/hmr/strategies/js-hmr-strategy.test.ts +335 -0
  79. package/src/hmr/strategies/js-hmr-strategy.ts +71 -78
  80. package/src/index.ts +1 -1
  81. package/src/integrations/ghtml/ghtml-renderer.test.ts +63 -0
  82. package/src/integrations/ghtml/ghtml-renderer.ts +4 -1
  83. package/src/internal-types.ts +39 -19
  84. package/src/plugins/README.md +34 -0
  85. package/src/plugins/alias-resolver-plugin.test.ts +41 -0
  86. package/src/plugins/alias-resolver-plugin.ts +21 -3
  87. package/src/plugins/eco-component-meta-plugin.test.ts +380 -0
  88. package/src/plugins/eco-component-meta-plugin.ts +10 -3
  89. package/src/plugins/integration-plugin.test.ts +111 -0
  90. package/src/plugins/integration-plugin.ts +45 -3
  91. package/src/plugins/processor.test.ts +148 -0
  92. package/src/plugins/processor.ts +22 -2
  93. package/src/plugins/runtime-capability.ts +14 -0
  94. package/src/public-types.ts +73 -11
  95. package/src/route-renderer/GRAPH.md +16 -20
  96. package/src/route-renderer/README.md +8 -21
  97. package/src/route-renderer/component-graph/component-graph-executor.test.ts +41 -0
  98. package/src/route-renderer/component-graph/component-graph.test.ts +63 -0
  99. package/src/route-renderer/component-graph/component-marker.test.ts +73 -0
  100. package/src/route-renderer/component-graph/component-reference.ts +29 -0
  101. package/src/route-renderer/component-graph/marker-graph-resolver.test.ts +135 -0
  102. package/src/route-renderer/{marker-graph-resolver.ts → component-graph/marker-graph-resolver.ts} +11 -9
  103. package/src/route-renderer/orchestration/integration-renderer.test.ts +936 -0
  104. package/src/route-renderer/{integration-renderer.ts → orchestration/integration-renderer.ts} +113 -19
  105. package/src/route-renderer/orchestration/render-execution.service.test.ts +97 -0
  106. package/src/route-renderer/{render-execution.service.ts → orchestration/render-execution.service.ts} +109 -37
  107. package/src/route-renderer/orchestration/render-preparation.service.test.ts +235 -0
  108. package/src/route-renderer/{render-preparation.service.ts → orchestration/render-preparation.service.ts} +127 -9
  109. package/src/route-renderer/page-loading/dependency-resolver.test.ts +345 -0
  110. package/src/route-renderer/{dependency-resolver.ts → page-loading/dependency-resolver.ts} +28 -12
  111. package/src/route-renderer/page-loading/page-module-loader.test.ts +96 -0
  112. package/src/route-renderer/{page-module-loader.ts → page-loading/page-module-loader.ts} +49 -21
  113. package/src/route-renderer/route-renderer.ts +36 -1
  114. package/src/router/README.md +26 -0
  115. package/src/router/client/link-intent.d.ts +53 -0
  116. package/src/router/client/link-intent.test.browser.ts +51 -0
  117. package/src/router/client/link-intent.ts +92 -0
  118. package/src/router/client/navigation-coordinator.test.ts +237 -0
  119. package/src/router/client/navigation-coordinator.ts +433 -0
  120. package/src/router/server/fs-router-scanner.test.ts +83 -0
  121. package/src/router/{fs-router-scanner.ts → server/fs-router-scanner.ts} +12 -10
  122. package/src/router/server/fs-router.test.ts +214 -0
  123. package/src/router/{fs-router.ts → server/fs-router.ts} +2 -2
  124. package/src/services/README.md +29 -0
  125. package/src/services/assets/asset-processing-service/asset-processing.service.test.ts +385 -0
  126. package/src/services/{asset-processing-service → assets/asset-processing-service}/asset-processing.service.ts +101 -6
  127. package/src/services/assets/asset-processing-service/asset.factory.test.ts +63 -0
  128. package/src/services/{asset-processing-service → assets/asset-processing-service}/asset.factory.ts +2 -2
  129. package/src/services/{asset-processing-service → assets/asset-processing-service}/assets.types.ts +2 -1
  130. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.test.ts +72 -0
  131. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.ts +95 -0
  132. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.test.ts +67 -0
  133. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.ts +78 -0
  134. package/src/services/{asset-processing-service → assets/asset-processing-service}/index.ts +2 -0
  135. package/src/services/{asset-processing-service → assets/asset-processing-service}/processor.interface.ts +1 -1
  136. package/src/services/assets/asset-processing-service/processors/base/base-processor.test.ts +59 -0
  137. package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/base/base-processor.ts +11 -5
  138. package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/base/base-script-processor.ts +17 -27
  139. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.test.ts +286 -0
  140. package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/script/file-script.processor.ts +3 -3
  141. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.test.ts +227 -0
  142. package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/script/node-module-script.processor.ts +5 -4
  143. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.test.ts +199 -0
  144. package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/stylesheet/file-stylesheet.processor.ts +4 -1
  145. package/src/services/assets/browser-bundle.service.test.ts +36 -0
  146. package/src/services/assets/browser-bundle.service.ts +53 -0
  147. package/src/services/cache/index.ts +3 -3
  148. package/src/services/cache/memory-cache-store.test.ts +225 -0
  149. package/src/services/cache/memory-cache-store.ts +1 -1
  150. package/src/services/cache/page-cache-service.test.ts +175 -0
  151. package/src/services/cache/page-cache-service.ts +3 -3
  152. package/src/services/cache/page-request-cache-coordinator.service.test.ts +79 -0
  153. package/src/services/{page-request-cache-coordinator.service.ts → cache/page-request-cache-coordinator.service.ts} +9 -6
  154. package/src/services/html/html-rewriter-provider.service.test.ts +183 -0
  155. package/src/services/html/html-rewriter-provider.service.ts +103 -0
  156. package/src/services/html/html-transformer.service.test.ts +378 -0
  157. package/src/services/html/html-transformer.service.ts +279 -0
  158. package/src/services/invalidation/development-invalidation.service.test.ts +77 -0
  159. package/src/services/invalidation/development-invalidation.service.ts +261 -0
  160. package/src/services/module-loading/app-server-module-transpiler.service.ts +52 -0
  161. package/src/services/module-loading/page-module-import.service.test.ts +253 -0
  162. package/src/services/module-loading/page-module-import.service.ts +200 -0
  163. package/src/services/module-loading/server-loader.service.test.ts +161 -0
  164. package/src/services/module-loading/server-loader.service.ts +130 -0
  165. package/src/services/module-loading/server-module-transpiler.service.test.ts +115 -0
  166. package/src/services/module-loading/server-module-transpiler.service.ts +105 -0
  167. package/src/services/runtime-manifest/node-runtime-manifest.service.test.ts +95 -0
  168. package/src/services/runtime-manifest/node-runtime-manifest.service.ts +101 -0
  169. package/src/services/runtime-state/dev-graph.service.ts +217 -0
  170. package/src/services/runtime-state/entrypoint-dependency-graph.service.ts +136 -0
  171. package/src/services/runtime-state/runtime-specifier-registry.service.ts +96 -0
  172. package/src/services/runtime-state/server-invalidation-state.service.ts +68 -0
  173. package/src/services/validation/schema-validation-service.test.ts +223 -0
  174. package/src/services/{schema-validation-service.ts → validation/schema-validation-service.ts} +1 -1
  175. package/src/static-site-generator/README.md +26 -0
  176. package/src/static-site-generator/static-site-generator.test.ts +307 -0
  177. package/src/static-site-generator/static-site-generator.ts +109 -6
  178. package/src/utils/deep-merge.test.ts +114 -0
  179. package/src/utils/invariant.test.ts +22 -0
  180. package/src/utils/path-utils.test.ts +15 -0
  181. package/src/utils/resolve-work-dir.ts +45 -0
  182. package/src/utils/server-utils.test.ts +38 -0
  183. package/src/watchers/project-watcher.integration.test.ts +337 -0
  184. package/src/watchers/project-watcher.test-helpers.ts +1 -0
  185. package/src/watchers/project-watcher.test.ts +678 -0
  186. package/src/watchers/project-watcher.ts +49 -50
  187. package/CHANGELOG.md +0 -94
  188. package/src/adapters/abstract/application-adapter.d.ts +0 -168
  189. package/src/adapters/abstract/application-adapter.js +0 -109
  190. package/src/adapters/abstract/router-adapter.d.ts +0 -26
  191. package/src/adapters/abstract/router-adapter.js +0 -5
  192. package/src/adapters/abstract/server-adapter.d.ts +0 -69
  193. package/src/adapters/abstract/server-adapter.js +0 -15
  194. package/src/adapters/bun/client-bridge.d.ts +0 -34
  195. package/src/adapters/bun/client-bridge.js +0 -48
  196. package/src/adapters/bun/create-app.d.ts +0 -60
  197. package/src/adapters/bun/create-app.js +0 -117
  198. package/src/adapters/bun/define-api-handler.d.ts +0 -61
  199. package/src/adapters/bun/define-api-handler.js +0 -15
  200. package/src/adapters/bun/define-api-handler.ts +0 -114
  201. package/src/adapters/bun/hmr-manager.d.ts +0 -79
  202. package/src/adapters/bun/hmr-manager.js +0 -222
  203. package/src/adapters/bun/index.d.ts +0 -3
  204. package/src/adapters/bun/index.js +0 -8
  205. package/src/adapters/bun/server-adapter.d.ts +0 -155
  206. package/src/adapters/bun/server-adapter.js +0 -368
  207. package/src/adapters/bun/server-lifecycle.d.ts +0 -52
  208. package/src/adapters/bun/server-lifecycle.js +0 -120
  209. package/src/adapters/index.d.ts +0 -6
  210. package/src/adapters/index.js +0 -14
  211. package/src/adapters/node/create-app.d.ts +0 -21
  212. package/src/adapters/node/create-app.js +0 -143
  213. package/src/adapters/node/index.d.ts +0 -4
  214. package/src/adapters/node/index.js +0 -8
  215. package/src/adapters/node/node-client-bridge.d.ts +0 -26
  216. package/src/adapters/node/node-client-bridge.js +0 -66
  217. package/src/adapters/node/node-hmr-manager.d.ts +0 -62
  218. package/src/adapters/node/node-hmr-manager.js +0 -221
  219. package/src/adapters/node/server-adapter.d.ts +0 -190
  220. package/src/adapters/node/server-adapter.js +0 -420
  221. package/src/adapters/node/static-content-server.d.ts +0 -24
  222. package/src/adapters/node/static-content-server.js +0 -166
  223. package/src/adapters/shared/api-response.d.ts +0 -52
  224. package/src/adapters/shared/api-response.js +0 -96
  225. package/src/adapters/shared/application-adapter.d.ts +0 -18
  226. package/src/adapters/shared/application-adapter.js +0 -90
  227. package/src/adapters/shared/explicit-static-route-matcher.d.ts +0 -38
  228. package/src/adapters/shared/explicit-static-route-matcher.js +0 -100
  229. package/src/adapters/shared/file-route-middleware-pipeline.d.ts +0 -65
  230. package/src/adapters/shared/file-route-middleware-pipeline.js +0 -98
  231. package/src/adapters/shared/fs-server-response-factory.d.ts +0 -19
  232. package/src/adapters/shared/fs-server-response-factory.js +0 -97
  233. package/src/adapters/shared/fs-server-response-matcher.d.ts +0 -71
  234. package/src/adapters/shared/fs-server-response-matcher.js +0 -155
  235. package/src/adapters/shared/render-context.d.ts +0 -14
  236. package/src/adapters/shared/render-context.js +0 -69
  237. package/src/adapters/shared/server-adapter.d.ts +0 -87
  238. package/src/adapters/shared/server-adapter.js +0 -353
  239. package/src/adapters/shared/server-route-handler.d.ts +0 -89
  240. package/src/adapters/shared/server-route-handler.js +0 -120
  241. package/src/adapters/shared/server-static-builder.d.ts +0 -38
  242. package/src/adapters/shared/server-static-builder.js +0 -46
  243. package/src/build/build-adapter.d.ts +0 -75
  244. package/src/build/build-adapter.js +0 -54
  245. package/src/build/build-types.d.ts +0 -57
  246. package/src/build/build-types.js +0 -0
  247. package/src/build/esbuild-build-adapter.d.ts +0 -69
  248. package/src/build/esbuild-build-adapter.js +0 -391
  249. package/src/config/config-builder.d.ts +0 -227
  250. package/src/config/config-builder.js +0 -392
  251. package/src/constants.d.ts +0 -32
  252. package/src/constants.js +0 -21
  253. package/src/create-app.d.ts +0 -17
  254. package/src/create-app.js +0 -66
  255. package/src/define-api-handler.d.ts +0 -25
  256. package/src/define-api-handler.js +0 -15
  257. package/src/dev/sc-server.d.ts +0 -30
  258. package/src/dev/sc-server.js +0 -111
  259. package/src/eco/component-render-context.d.ts +0 -105
  260. package/src/eco/component-render-context.js +0 -77
  261. package/src/eco/eco.d.ts +0 -9
  262. package/src/eco/eco.js +0 -110
  263. package/src/eco/eco.types.d.ts +0 -170
  264. package/src/eco/eco.types.js +0 -0
  265. package/src/eco/eco.utils.d.ts +0 -40
  266. package/src/eco/eco.utils.js +0 -40
  267. package/src/eco/global-injector-map.d.ts +0 -16
  268. package/src/eco/global-injector-map.js +0 -80
  269. package/src/eco/lazy-injector-map.d.ts +0 -8
  270. package/src/eco/lazy-injector-map.js +0 -70
  271. package/src/eco/module-dependencies.d.ts +0 -18
  272. package/src/eco/module-dependencies.js +0 -49
  273. package/src/errors/http-error.d.ts +0 -31
  274. package/src/errors/http-error.js +0 -50
  275. package/src/errors/index.d.ts +0 -2
  276. package/src/errors/index.js +0 -4
  277. package/src/errors/locals-access-error.d.ts +0 -4
  278. package/src/errors/locals-access-error.js +0 -9
  279. package/src/global/app-logger.d.ts +0 -2
  280. package/src/global/app-logger.js +0 -6
  281. package/src/hmr/client/hmr-runtime.d.ts +0 -10
  282. package/src/hmr/client/hmr-runtime.js +0 -86
  283. package/src/hmr/hmr-strategy.d.ts +0 -159
  284. package/src/hmr/hmr-strategy.js +0 -29
  285. package/src/hmr/hmr.test.e2e.d.ts +0 -1
  286. package/src/hmr/hmr.test.e2e.js +0 -50
  287. package/src/hmr/strategies/default-hmr-strategy.d.ts +0 -43
  288. package/src/hmr/strategies/default-hmr-strategy.js +0 -34
  289. package/src/hmr/strategies/js-hmr-strategy.d.ts +0 -136
  290. package/src/hmr/strategies/js-hmr-strategy.js +0 -192
  291. package/src/index.browser.d.ts +0 -3
  292. package/src/index.browser.js +0 -4
  293. package/src/index.d.ts +0 -5
  294. package/src/index.js +0 -10
  295. package/src/integrations/ghtml/ghtml-renderer.d.ts +0 -15
  296. package/src/integrations/ghtml/ghtml-renderer.js +0 -60
  297. package/src/integrations/ghtml/ghtml.plugin.d.ts +0 -20
  298. package/src/integrations/ghtml/ghtml.plugin.js +0 -21
  299. package/src/internal-types.d.ts +0 -200
  300. package/src/internal-types.js +0 -0
  301. package/src/plugins/alias-resolver-plugin.d.ts +0 -2
  302. package/src/plugins/alias-resolver-plugin.js +0 -39
  303. package/src/plugins/eco-component-meta-plugin.d.ts +0 -95
  304. package/src/plugins/eco-component-meta-plugin.js +0 -157
  305. package/src/plugins/integration-plugin.d.ts +0 -102
  306. package/src/plugins/integration-plugin.js +0 -100
  307. package/src/plugins/processor.d.ts +0 -82
  308. package/src/plugins/processor.js +0 -122
  309. package/src/public-types.d.ts +0 -1094
  310. package/src/public-types.js +0 -0
  311. package/src/route-renderer/component-graph-executor.d.ts +0 -32
  312. package/src/route-renderer/component-graph-executor.js +0 -31
  313. package/src/route-renderer/component-graph.d.ts +0 -42
  314. package/src/route-renderer/component-graph.js +0 -72
  315. package/src/route-renderer/component-marker.d.ts +0 -52
  316. package/src/route-renderer/component-marker.js +0 -46
  317. package/src/route-renderer/dependency-resolver.d.ts +0 -24
  318. package/src/route-renderer/dependency-resolver.js +0 -428
  319. package/src/route-renderer/html-post-processing.service.d.ts +0 -40
  320. package/src/route-renderer/html-post-processing.service.js +0 -86
  321. package/src/route-renderer/html-post-processing.service.ts +0 -103
  322. package/src/route-renderer/integration-renderer.d.ts +0 -339
  323. package/src/route-renderer/integration-renderer.js +0 -526
  324. package/src/route-renderer/marker-graph-resolver.d.ts +0 -76
  325. package/src/route-renderer/marker-graph-resolver.js +0 -93
  326. package/src/route-renderer/page-module-loader.d.ts +0 -61
  327. package/src/route-renderer/page-module-loader.js +0 -102
  328. package/src/route-renderer/render-execution.service.d.ts +0 -69
  329. package/src/route-renderer/render-execution.service.js +0 -91
  330. package/src/route-renderer/render-preparation.service.d.ts +0 -112
  331. package/src/route-renderer/render-preparation.service.js +0 -243
  332. package/src/route-renderer/route-renderer.d.ts +0 -26
  333. package/src/route-renderer/route-renderer.js +0 -68
  334. package/src/router/fs-router-scanner.d.ts +0 -41
  335. package/src/router/fs-router-scanner.js +0 -155
  336. package/src/router/fs-router.d.ts +0 -26
  337. package/src/router/fs-router.js +0 -100
  338. package/src/services/asset-processing-service/asset-processing.service.d.ts +0 -41
  339. package/src/services/asset-processing-service/asset-processing.service.js +0 -250
  340. package/src/services/asset-processing-service/asset.factory.d.ts +0 -17
  341. package/src/services/asset-processing-service/asset.factory.js +0 -82
  342. package/src/services/asset-processing-service/assets.types.d.ts +0 -88
  343. package/src/services/asset-processing-service/assets.types.js +0 -0
  344. package/src/services/asset-processing-service/index.d.ts +0 -3
  345. package/src/services/asset-processing-service/index.js +0 -3
  346. package/src/services/asset-processing-service/processor.interface.d.ts +0 -22
  347. package/src/services/asset-processing-service/processor.interface.js +0 -6
  348. package/src/services/asset-processing-service/processor.registry.d.ts +0 -8
  349. package/src/services/asset-processing-service/processor.registry.js +0 -15
  350. package/src/services/asset-processing-service/processors/base/base-processor.d.ts +0 -24
  351. package/src/services/asset-processing-service/processors/base/base-processor.js +0 -59
  352. package/src/services/asset-processing-service/processors/base/base-script-processor.d.ts +0 -16
  353. package/src/services/asset-processing-service/processors/base/base-script-processor.js +0 -80
  354. package/src/services/asset-processing-service/processors/index.d.ts +0 -5
  355. package/src/services/asset-processing-service/processors/index.js +0 -5
  356. package/src/services/asset-processing-service/processors/script/content-script.processor.d.ts +0 -5
  357. package/src/services/asset-processing-service/processors/script/content-script.processor.js +0 -57
  358. package/src/services/asset-processing-service/processors/script/file-script.processor.d.ts +0 -8
  359. package/src/services/asset-processing-service/processors/script/file-script.processor.js +0 -76
  360. package/src/services/asset-processing-service/processors/script/node-module-script.processor.d.ts +0 -7
  361. package/src/services/asset-processing-service/processors/script/node-module-script.processor.js +0 -74
  362. package/src/services/asset-processing-service/processors/stylesheet/content-stylesheet.processor.d.ts +0 -5
  363. package/src/services/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +0 -25
  364. package/src/services/asset-processing-service/processors/stylesheet/file-stylesheet.processor.d.ts +0 -9
  365. package/src/services/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +0 -63
  366. package/src/services/cache/cache.types.d.ts +0 -107
  367. package/src/services/cache/cache.types.js +0 -0
  368. package/src/services/cache/index.d.ts +0 -7
  369. package/src/services/cache/index.js +0 -7
  370. package/src/services/cache/memory-cache-store.d.ts +0 -42
  371. package/src/services/cache/memory-cache-store.js +0 -98
  372. package/src/services/cache/page-cache-service.d.ts +0 -70
  373. package/src/services/cache/page-cache-service.js +0 -152
  374. package/src/services/html-transformer.service.d.ts +0 -50
  375. package/src/services/html-transformer.service.js +0 -163
  376. package/src/services/html-transformer.service.ts +0 -217
  377. package/src/services/page-module-import.service.d.ts +0 -37
  378. package/src/services/page-module-import.service.js +0 -88
  379. package/src/services/page-module-import.service.ts +0 -129
  380. package/src/services/page-request-cache-coordinator.service.d.ts +0 -75
  381. package/src/services/page-request-cache-coordinator.service.js +0 -107
  382. package/src/services/schema-validation-service.d.ts +0 -122
  383. package/src/services/schema-validation-service.js +0 -101
  384. package/src/services/validation/standard-schema.types.d.ts +0 -65
  385. package/src/services/validation/standard-schema.types.js +0 -0
  386. package/src/static-site-generator/static-site-generator.d.ts +0 -57
  387. package/src/static-site-generator/static-site-generator.js +0 -272
  388. package/src/utils/css.d.ts +0 -1
  389. package/src/utils/css.js +0 -7
  390. package/src/utils/deep-merge.d.ts +0 -14
  391. package/src/utils/deep-merge.js +0 -32
  392. package/src/utils/hash.d.ts +0 -1
  393. package/src/utils/hash.js +0 -7
  394. package/src/utils/html.d.ts +0 -1
  395. package/src/utils/html.js +0 -4
  396. package/src/utils/invariant.d.ts +0 -5
  397. package/src/utils/invariant.js +0 -11
  398. package/src/utils/locals-utils.d.ts +0 -15
  399. package/src/utils/locals-utils.js +0 -24
  400. package/src/utils/parse-cli-args.d.ts +0 -24
  401. package/src/utils/parse-cli-args.js +0 -47
  402. package/src/utils/path-utils.module.d.ts +0 -5
  403. package/src/utils/path-utils.module.js +0 -14
  404. package/src/utils/runtime.d.ts +0 -11
  405. package/src/utils/runtime.js +0 -40
  406. package/src/utils/server-utils.module.d.ts +0 -19
  407. package/src/utils/server-utils.module.js +0 -56
  408. package/src/watchers/project-watcher.d.ts +0 -132
  409. package/src/watchers/project-watcher.js +0 -281
  410. package/src/watchers/project-watcher.test-helpers.d.ts +0 -4
  411. package/src/watchers/project-watcher.test-helpers.js +0 -51
  412. /package/src/route-renderer/{component-graph-executor.ts → component-graph/component-graph-executor.ts} +0 -0
  413. /package/src/route-renderer/{component-graph.ts → component-graph/component-graph.ts} +0 -0
  414. /package/src/route-renderer/{component-marker.ts → component-graph/component-marker.ts} +0 -0
  415. /package/src/services/{asset-processing-service → assets/asset-processing-service}/processor.registry.ts +0 -0
  416. /package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/index.ts +0 -0
  417. /package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/script/content-script.processor.ts +0 -0
  418. /package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/stylesheet/content-stylesheet.processor.ts +0 -0
@@ -4,7 +4,7 @@
4
4
  * @module
5
5
  */
6
6
 
7
- import type { EcoPagesAppConfig, IHmrManager } from '../internal-types.ts';
7
+ import type { EcoPagesAppConfig, IHmrManager } from '../../internal-types.ts';
8
8
  import type {
9
9
  ComponentRenderInput,
10
10
  ComponentRenderResult,
@@ -23,19 +23,35 @@ import type {
23
23
  RouteRendererBody,
24
24
  RouteRendererOptions,
25
25
  RouteRenderResult,
26
- } from '../public-types.ts';
27
- import { type AssetProcessingService, type ProcessedAsset } from '../services/asset-processing-service/index.ts';
28
- import { HtmlTransformerService } from '../services/html-transformer.service.ts';
29
- import { invariant } from '../utils/invariant.ts';
30
- import { HttpError } from '../errors/http-error.ts';
31
- import { LocalsAccessError } from '../errors/locals-access-error.ts';
32
- import { DependencyResolverService } from './dependency-resolver.ts';
33
- import { HtmlPostProcessingService } from './html-post-processing.service.ts';
34
- import { PageModuleLoaderService } from './page-module-loader.ts';
35
- import { MarkerGraphResolver } from './marker-graph-resolver.ts';
26
+ } from '../../public-types.ts';
27
+ import {
28
+ type AssetProcessingService,
29
+ type ProcessedAsset,
30
+ } from '../../services/assets/asset-processing-service/index.ts';
31
+ import { HtmlTransformerService } from '../../services/html/html-transformer.service.ts';
32
+ import { invariant } from '../../utils/invariant.ts';
33
+ import { HttpError } from '../../errors/http-error.ts';
34
+ import { LocalsAccessError } from '../../errors/locals-access-error.ts';
35
+ import { DependencyResolverService } from '../page-loading/dependency-resolver.ts';
36
+ import { PageModuleLoaderService } from '../page-loading/page-module-loader.ts';
37
+ import { MarkerGraphResolver } from '../component-graph/marker-graph-resolver.ts';
36
38
  import { RenderExecutionService, type RenderExecutionGraphContext } from './render-execution.service.ts';
37
39
  import { RenderPreparationService } from './render-preparation.service.ts';
38
- import type { BoundaryRenderDecisionInput, ComponentRenderBoundaryContext } from '../eco/component-render-context.ts';
40
+ import type {
41
+ BoundaryRenderDecisionInput,
42
+ ComponentRenderBoundaryContext,
43
+ } from '../../eco/component-render-context.ts';
44
+
45
+ export interface FinalizeCapturedHtmlRenderOptions {
46
+ html: string;
47
+ componentsToResolve: EcoComponent[];
48
+ graphContext: RenderExecutionGraphContext;
49
+ partial?: boolean;
50
+ componentRootAttributes?: Record<string, string>;
51
+ documentAttributes?: Record<string, string>;
52
+ mergeAssets?: boolean;
53
+ transformHtml?: boolean;
54
+ }
39
55
 
40
56
  /**
41
57
  * Creates a Proxy that throws LocalsAccessError on any property access.
@@ -103,7 +119,6 @@ export abstract class IntegrationRenderer<C = EcoPagesElement> {
103
119
  protected pageModuleLoaderService: PageModuleLoaderService;
104
120
  protected markerGraphResolver: MarkerGraphResolver;
105
121
  protected renderPreparationService: RenderPreparationService;
106
- protected htmlPostProcessingService: HtmlPostProcessingService;
107
122
  protected renderExecutionService: RenderExecutionService;
108
123
 
109
124
  protected DOC_TYPE = '<!DOCTYPE html>';
@@ -164,7 +179,7 @@ export abstract class IntegrationRenderer<C = EcoPagesElement> {
164
179
  protected async prepareViewDependencies(view: EcoComponent, layout?: EcoComponent): Promise<ProcessedAsset[]> {
165
180
  const HtmlTemplate = await this.getHtmlTemplate();
166
181
  const componentsToResolve = layout ? [HtmlTemplate, layout, view] : [HtmlTemplate, view];
167
- const resolvedDependencies = this.htmlPostProcessingService.dedupeProcessedAssets(
182
+ const resolvedDependencies = this.htmlTransformer.dedupeProcessedAssets(
168
183
  await this.resolveDependencies(componentsToResolve),
169
184
  );
170
185
  this.htmlTransformer.setProcessedDependencies(resolvedDependencies);
@@ -191,7 +206,6 @@ export abstract class IntegrationRenderer<C = EcoPagesElement> {
191
206
  this.pageModuleLoaderService = new PageModuleLoaderService(appConfig, runtimeOrigin);
192
207
  this.markerGraphResolver = new MarkerGraphResolver();
193
208
  this.renderPreparationService = new RenderPreparationService(appConfig, assetProcessingService);
194
- this.htmlPostProcessingService = new HtmlPostProcessingService();
195
209
  this.renderExecutionService = new RenderExecutionService();
196
210
  }
197
211
 
@@ -394,7 +408,7 @@ export abstract class IntegrationRenderer<C = EcoPagesElement> {
394
408
  }),
395
409
  getComponentRenderBoundaryContext: () => this.getComponentRenderBoundaryContext(),
396
410
  setProcessedDependencies: (dependencies) => this.htmlTransformer.setProcessedDependencies(dependencies),
397
- dedupeProcessedAssets: (assets) => this.htmlPostProcessingService.dedupeProcessedAssets(assets),
411
+ dedupeProcessedAssets: (assets) => this.htmlTransformer.dedupeProcessedAssets(assets),
398
412
  createPageLocalsProxy: (filePath) =>
399
413
  createLocalsProxy(filePath) as unknown as RouteRendererOptions['locals'],
400
414
  });
@@ -480,11 +494,14 @@ export abstract class IntegrationRenderer<C = EcoPagesElement> {
480
494
  componentsToResolve: input.componentsToResolve,
481
495
  graphContext: input.graphContext,
482
496
  }),
483
- dedupeProcessedAssets: (assets) => this.htmlPostProcessingService.dedupeProcessedAssets(assets),
497
+ getDocumentAttributes: (renderOptions) => this.getDocumentAttributes(renderOptions),
498
+ dedupeProcessedAssets: (assets) => this.htmlTransformer.dedupeProcessedAssets(assets),
484
499
  getProcessedDependencies: () => this.htmlTransformer.getProcessedDependencies(),
485
500
  setProcessedDependencies: (dependencies) => this.htmlTransformer.setProcessedDependencies(dependencies),
501
+ applyAttributesToHtmlElement: (html, attributes) =>
502
+ this.htmlTransformer.applyAttributesToHtmlElement(html, attributes),
486
503
  applyAttributesToFirstBodyElement: (html, attributes) =>
487
- this.htmlPostProcessingService.applyAttributesToFirstBodyElement(html, attributes),
504
+ this.htmlTransformer.applyAttributesToFirstBodyElement(html, attributes),
488
505
  transformHtml: async (html) => {
489
506
  const response = await this.htmlTransformer.transform(
490
507
  new Response(html, {
@@ -498,6 +515,83 @@ export abstract class IntegrationRenderer<C = EcoPagesElement> {
498
515
  });
499
516
  }
500
517
 
518
+ /**
519
+ * Captures a render pass as immutable HTML along with the graph context needed
520
+ * for deferred marker resolution.
521
+ *
522
+ * This is the shared entry point for direct `renderToResponse()` flows that
523
+ * need the same component graph capture semantics as route execution without
524
+ * going through `prepareRenderOptions()`.
525
+ */
526
+ protected async captureHtmlRender(render: () => Promise<RouteRendererBody>): Promise<{
527
+ html: string;
528
+ graphContext: RenderExecutionGraphContext;
529
+ }> {
530
+ return this.renderExecutionService.captureHtmlRender(
531
+ this.name,
532
+ this.getComponentRenderBoundaryContext(),
533
+ render,
534
+ );
535
+ }
536
+
537
+ /**
538
+ * Finalizes previously captured HTML by resolving deferred markers, merging
539
+ * any emitted assets, stamping optional attributes, and optionally running the
540
+ * HTML transformer for full-document flows.
541
+ */
542
+ protected async finalizeCapturedHtmlRender(options: FinalizeCapturedHtmlRenderOptions): Promise<string> {
543
+ const finalization = await this.renderExecutionService.finalizeHtmlRender(
544
+ {
545
+ html: options.html,
546
+ graphContext: options.graphContext,
547
+ componentsToResolve: options.componentsToResolve,
548
+ componentRootAttributes: options.componentRootAttributes,
549
+ documentAttributes: options.documentAttributes,
550
+ mergeAssets: options.mergeAssets ?? !options.partial,
551
+ },
552
+ {
553
+ resolveMarkerGraphHtml: (input) =>
554
+ this.resolveMarkerGraphHtml({
555
+ html: input.html,
556
+ componentsToResolve: input.componentsToResolve,
557
+ graphContext: input.graphContext,
558
+ }),
559
+ dedupeProcessedAssets: (assets) => this.htmlTransformer.dedupeProcessedAssets(assets),
560
+ getProcessedDependencies: () => this.htmlTransformer.getProcessedDependencies(),
561
+ setProcessedDependencies: (dependencies) => this.htmlTransformer.setProcessedDependencies(dependencies),
562
+ applyAttributesToHtmlElement: (html, attributes) =>
563
+ this.htmlTransformer.applyAttributesToHtmlElement(html, attributes),
564
+ applyAttributesToFirstBodyElement: (html, attributes) =>
565
+ this.htmlTransformer.applyAttributesToFirstBodyElement(html, attributes),
566
+ },
567
+ );
568
+
569
+ const shouldTransform = options.transformHtml ?? !options.partial;
570
+ if (!shouldTransform) {
571
+ return finalization.html;
572
+ }
573
+
574
+ const transformedResponse = await this.htmlTransformer.transform(
575
+ new Response(finalization.html, {
576
+ headers: { 'Content-Type': 'text/html' },
577
+ }),
578
+ );
579
+
580
+ return await transformedResponse.text();
581
+ }
582
+
583
+ /**
584
+ * Returns document-level attributes to stamp onto the rendered `<html>` tag.
585
+ *
586
+ * Integrations can override this to expose explicit document ownership or
587
+ * other runtime coordination markers without relying on script sniffing.
588
+ */
589
+ protected getDocumentAttributes(
590
+ _renderOptions: IntegrationRendererRenderOptions<C>,
591
+ ): Record<string, string> | undefined {
592
+ return undefined;
593
+ }
594
+
501
595
  /**
502
596
  * Resolves all `eco-marker` placeholders in rendered HTML using integration
503
597
  * dispatch and bottom-up graph execution.
@@ -534,7 +628,7 @@ export abstract class IntegrationRenderer<C = EcoPagesElement> {
534
628
  resolveRenderer: (integrationName) =>
535
629
  this.getIntegrationRendererForName(integrationName, integrationRendererCache),
536
630
  applyAttributesToFirstElement: (html, attributes) =>
537
- this.htmlPostProcessingService.applyAttributesToFirstElement(html, attributes),
631
+ this.htmlTransformer.applyAttributesToFirstElement(html, attributes),
538
632
  });
539
633
  }
540
634
 
@@ -0,0 +1,97 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+ import { getComponentRenderContext } from '../../eco/component-render-context.ts';
3
+ import type { EcoComponent, IntegrationRendererRenderOptions, RouteRendererOptions } from '../../public-types.ts';
4
+ import type { ProcessedAsset } from '../../services/assets/asset-processing-service/index.ts';
5
+ import { createComponentMarker } from '../component-graph/component-marker.ts';
6
+ import { RenderExecutionService } from './render-execution.service.ts';
7
+
8
+ describe('RenderExecutionService', () => {
9
+ it('should execute render flow, merge graph context, resolve markers, and apply root attributes', async () => {
10
+ const service = new RenderExecutionService();
11
+ const HtmlTemplate = (() => '<html></html>') as EcoComponent<Record<string, unknown>>;
12
+ const Page = (() => '<main>Page</main>') as EcoComponent<Record<string, unknown>>;
13
+ const asset = { kind: 'script', srcUrl: '/assets/nested.js', position: 'head' } as ProcessedAsset;
14
+ const setProcessedDependencies = vi.fn();
15
+ const dedupeProcessedAssets = vi.fn((assets: ProcessedAsset[]) => {
16
+ const seen = new Set<string>();
17
+ return assets.filter((entry) => {
18
+ const key = `${entry.kind}:${entry.srcUrl ?? ''}:${entry.position ?? ''}`;
19
+ if (seen.has(key)) {
20
+ return false;
21
+ }
22
+ seen.add(key);
23
+ return true;
24
+ });
25
+ });
26
+ const resolveMarkerGraphHtml = vi.fn(async (input) => {
27
+ expect(input.componentsToResolve).toEqual([HtmlTemplate, Page]);
28
+ expect(input.graphContext.propsByRef).toEqual({
29
+ captured: { count: 1 },
30
+ explicit: { count: 2 },
31
+ });
32
+
33
+ return {
34
+ html: '<html><body><main>Resolved</main></body></html>',
35
+ assets: [asset, asset],
36
+ };
37
+ });
38
+
39
+ const result = await service.execute(
40
+ {
41
+ file: '/app/pages/index.tsx',
42
+ params: {},
43
+ query: {},
44
+ } as unknown as RouteRendererOptions,
45
+ 'ghtml',
46
+ {
47
+ prepareRenderOptions: async () =>
48
+ ({
49
+ HtmlTemplate,
50
+ Page,
51
+ cacheStrategy: { revalidate: 60 },
52
+ componentRender: {
53
+ canAttachAttributes: true,
54
+ rootAttributes: { 'data-eco-component-id': 'eco-page-root' },
55
+ },
56
+ componentGraphContext: {
57
+ propsByRef: {
58
+ explicit: { count: 2 },
59
+ },
60
+ },
61
+ }) as unknown as IntegrationRendererRenderOptions<unknown>,
62
+ render: async () => {
63
+ const context = getComponentRenderContext();
64
+ if (context) {
65
+ context.propsByRef.captured = { count: 1 };
66
+ }
67
+ return `<html><body>${createComponentMarker({
68
+ nodeId: 'n_1',
69
+ integration: 'react',
70
+ componentRef: 'nested-component',
71
+ propsRef: 'captured',
72
+ })}</body></html>`;
73
+ },
74
+ getComponentRenderBoundaryContext: () => ({
75
+ decideBoundaryRender: () => 'inline',
76
+ }),
77
+ getDocumentAttributes: () => ({ 'data-eco-document-owner': 'react-router' }),
78
+ resolveMarkerGraphHtml,
79
+ dedupeProcessedAssets,
80
+ getProcessedDependencies: () => [asset],
81
+ setProcessedDependencies,
82
+ applyAttributesToHtmlElement: (html, attributes) =>
83
+ html.replace('<html', `<html data-eco-document-owner="${attributes['data-eco-document-owner']}"`),
84
+ applyAttributesToFirstBodyElement: (html, attributes) =>
85
+ html.replace('<main', `<main data-eco-component-id="${attributes['data-eco-component-id']}"`),
86
+ transformHtml: async (html) => html,
87
+ },
88
+ );
89
+
90
+ expect(result.cacheStrategy).toEqual({ revalidate: 60 });
91
+ expect(result.body).toContain('<html data-eco-document-owner="react-router"><body>');
92
+ expect(result.body).toContain('<main data-eco-component-id="eco-page-root">Resolved</main>');
93
+ expect(setProcessedDependencies).toHaveBeenCalledWith([asset]);
94
+ expect(dedupeProcessedAssets).toHaveBeenCalled();
95
+ expect(resolveMarkerGraphHtml).toHaveBeenCalledTimes(1);
96
+ });
97
+ });
@@ -1,17 +1,16 @@
1
1
  import {
2
2
  runWithComponentRenderContext,
3
3
  type ComponentRenderBoundaryContext,
4
- type ComponentGraphContext as CapturedComponentGraphContext,
5
- } from '../eco/component-render-context.ts';
4
+ } from '../../eco/component-render-context.ts';
6
5
  import type {
7
6
  EcoComponent,
8
7
  IntegrationRendererRenderOptions,
9
8
  RouteRendererBody,
10
9
  RouteRendererOptions,
11
10
  RouteRenderResult,
12
- } from '../public-types.ts';
13
- import type { ProcessedAsset } from '../services/asset-processing-service/index.ts';
14
- import type { MarkerGraphContext } from './marker-graph-resolver.ts';
11
+ } from '../../public-types.ts';
12
+ import type { ProcessedAsset } from '../../services/assets/asset-processing-service/index.ts';
13
+ import type { MarkerGraphContext } from '../component-graph/marker-graph-resolver.ts';
15
14
 
16
15
  /**
17
16
  * Serializable graph context merged from render-time captured references and
@@ -22,10 +21,25 @@ export type RenderExecutionGraphContext = {
22
21
  slotChildrenByRef?: MarkerGraphContext['slotChildrenByRef'];
23
22
  };
24
23
 
24
+ export interface CapturedHtmlRenderResult {
25
+ html: string;
26
+ graphContext: RenderExecutionGraphContext;
27
+ }
28
+
29
+ export interface FinalizeHtmlRenderOptions {
30
+ html: string;
31
+ graphContext: RenderExecutionGraphContext;
32
+ componentsToResolve: EcoComponent[];
33
+ componentRootAttributes?: Record<string, string>;
34
+ documentAttributes?: Record<string, string>;
35
+ mergeAssets?: boolean;
36
+ }
37
+
25
38
  export interface RenderExecutionCallbacks<C> {
26
39
  prepareRenderOptions(options: RouteRendererOptions): Promise<IntegrationRendererRenderOptions<C>>;
27
40
  render(renderOptions: IntegrationRendererRenderOptions<C>): Promise<RouteRendererBody>;
28
41
  getComponentRenderBoundaryContext(): ComponentRenderBoundaryContext;
42
+ getDocumentAttributes(renderOptions: IntegrationRendererRenderOptions<C>): Record<string, string> | undefined;
29
43
  resolveMarkerGraphHtml(input: {
30
44
  html: string;
31
45
  componentsToResolve: EcoComponent[];
@@ -34,10 +48,24 @@ export interface RenderExecutionCallbacks<C> {
34
48
  dedupeProcessedAssets(assets: ProcessedAsset[]): ProcessedAsset[];
35
49
  getProcessedDependencies(): ProcessedAsset[];
36
50
  setProcessedDependencies(dependencies: ProcessedAsset[]): void;
51
+ applyAttributesToHtmlElement(html: string, attributes: Record<string, string>): string;
37
52
  applyAttributesToFirstBodyElement(html: string, attributes: Record<string, string>): string;
38
53
  transformHtml(html: string): Promise<RouteRendererBody>;
39
54
  }
40
55
 
56
+ export interface FinalizeHtmlRenderCallbacks {
57
+ resolveMarkerGraphHtml(input: {
58
+ html: string;
59
+ componentsToResolve: EcoComponent[];
60
+ graphContext: RenderExecutionGraphContext;
61
+ }): Promise<{ html: string; assets: ProcessedAsset[] }>;
62
+ dedupeProcessedAssets(assets: ProcessedAsset[]): ProcessedAsset[];
63
+ getProcessedDependencies(): ProcessedAsset[];
64
+ setProcessedDependencies(dependencies: ProcessedAsset[]): void;
65
+ applyAttributesToHtmlElement(html: string, attributes: Record<string, string>): string;
66
+ applyAttributesToFirstBodyElement(html: string, attributes: Record<string, string>): string;
67
+ }
68
+
41
69
  /**
42
70
  * Executes the main post-preparation rendering flow for integration renderers.
43
71
  *
@@ -47,6 +75,25 @@ export interface RenderExecutionCallbacks<C> {
47
75
  * transformation into a response body stream.
48
76
  */
49
77
  export class RenderExecutionService {
78
+ async captureHtmlRender(
79
+ currentIntegrationName: string,
80
+ boundaryContext: ComponentRenderBoundaryContext,
81
+ render: () => Promise<RouteRendererBody>,
82
+ ): Promise<CapturedHtmlRenderResult> {
83
+ const renderExecution = await runWithComponentRenderContext(
84
+ {
85
+ currentIntegration: currentIntegrationName,
86
+ boundaryContext,
87
+ },
88
+ render,
89
+ );
90
+
91
+ return {
92
+ html: await new Response(renderExecution.value as BodyInit).text(),
93
+ graphContext: renderExecution.graphContext,
94
+ };
95
+ }
96
+
50
97
  /**
51
98
  * Executes one integration render pass and returns the final route render
52
99
  * result.
@@ -68,15 +115,12 @@ export class RenderExecutionService {
68
115
  renderOptions.componentRender.rootAttributes &&
69
116
  Object.keys(renderOptions.componentRender.rootAttributes).length > 0;
70
117
 
71
- const renderExecution = await runWithComponentRenderContext(
72
- {
73
- currentIntegration: currentIntegrationName,
74
- boundaryContext: callbacks.getComponentRenderBoundaryContext(),
75
- },
118
+ const renderExecution = await this.captureHtmlRender(
119
+ currentIntegrationName,
120
+ callbacks.getComponentRenderBoundaryContext(),
76
121
  async () => callbacks.render(renderOptions),
77
122
  );
78
123
 
79
- let renderedHtml = await new Response(renderExecution.value as BodyInit).text();
80
124
  const componentGraphContext = this.mergeGraphContext(
81
125
  renderExecution.graphContext,
82
126
  (
@@ -85,32 +129,21 @@ export class RenderExecutionService {
85
129
  }
86
130
  ).componentGraphContext,
87
131
  );
88
-
89
- if (renderedHtml.includes('<eco-marker')) {
90
- const markerResolution = await callbacks.resolveMarkerGraphHtml({
91
- html: renderedHtml,
92
- componentsToResolve: this.getComponentsToResolve(renderOptions),
132
+ const finalization = await this.finalizeHtmlRender(
133
+ {
134
+ html: renderExecution.html,
93
135
  graphContext: componentGraphContext,
94
- });
95
- renderedHtml = markerResolution.html;
96
-
97
- if (markerResolution.assets.length > 0) {
98
- const mergedDependencies = callbacks.dedupeProcessedAssets([
99
- ...callbacks.getProcessedDependencies(),
100
- ...markerResolution.assets,
101
- ]);
102
- callbacks.setProcessedDependencies(mergedDependencies);
103
- }
104
- }
105
-
106
- if (shouldApplyComponentRootAttributes) {
107
- renderedHtml = callbacks.applyAttributesToFirstBodyElement(
108
- renderedHtml,
109
- renderOptions.componentRender?.rootAttributes as Record<string, string>,
110
- );
111
- }
136
+ componentsToResolve: this.getComponentsToResolve(renderOptions),
137
+ componentRootAttributes: shouldApplyComponentRootAttributes
138
+ ? (renderOptions.componentRender?.rootAttributes as Record<string, string>)
139
+ : undefined,
140
+ documentAttributes: callbacks.getDocumentAttributes(renderOptions),
141
+ mergeAssets: true,
142
+ },
143
+ callbacks,
144
+ );
112
145
 
113
- const body = await callbacks.transformHtml(renderedHtml);
146
+ const body = await callbacks.transformHtml(finalization.html);
114
147
 
115
148
  return {
116
149
  body,
@@ -126,8 +159,8 @@ export class RenderExecutionService {
126
159
  * @param explicitGraphContext Optional page-module graph metadata.
127
160
  * @returns Merged graph context used during marker resolution.
128
161
  */
129
- private mergeGraphContext(
130
- capturedGraphContext: CapturedComponentGraphContext,
162
+ mergeGraphContext(
163
+ capturedGraphContext: RenderExecutionGraphContext,
131
164
  explicitGraphContext?: RenderExecutionGraphContext,
132
165
  ): RenderExecutionGraphContext {
133
166
  return {
@@ -142,6 +175,45 @@ export class RenderExecutionService {
142
175
  };
143
176
  }
144
177
 
178
+ async finalizeHtmlRender(
179
+ options: FinalizeHtmlRenderOptions,
180
+ callbacks: FinalizeHtmlRenderCallbacks,
181
+ ): Promise<{ html: string; assets: ProcessedAsset[] }> {
182
+ let renderedHtml = options.html;
183
+ let markerAssets: ProcessedAsset[] = [];
184
+
185
+ if (renderedHtml.includes('<eco-marker')) {
186
+ const markerResolution = await callbacks.resolveMarkerGraphHtml({
187
+ html: renderedHtml,
188
+ componentsToResolve: options.componentsToResolve,
189
+ graphContext: options.graphContext,
190
+ });
191
+ renderedHtml = markerResolution.html;
192
+ markerAssets = markerResolution.assets;
193
+
194
+ if (options.mergeAssets !== false && markerResolution.assets.length > 0) {
195
+ const mergedDependencies = callbacks.dedupeProcessedAssets([
196
+ ...callbacks.getProcessedDependencies(),
197
+ ...markerResolution.assets,
198
+ ]);
199
+ callbacks.setProcessedDependencies(mergedDependencies);
200
+ }
201
+ }
202
+
203
+ if (options.componentRootAttributes && Object.keys(options.componentRootAttributes).length > 0) {
204
+ renderedHtml = callbacks.applyAttributesToFirstBodyElement(renderedHtml, options.componentRootAttributes);
205
+ }
206
+
207
+ if (options.documentAttributes && Object.keys(options.documentAttributes).length > 0) {
208
+ renderedHtml = callbacks.applyAttributesToHtmlElement(renderedHtml, options.documentAttributes);
209
+ }
210
+
211
+ return {
212
+ html: renderedHtml,
213
+ assets: markerAssets,
214
+ };
215
+ }
216
+
145
217
  /**
146
218
  * Returns the component set that participates in marker graph resolution for a
147
219
  * render pass.