@ecopages/core 0.2.0-alpha.26 → 0.2.0-alpha.27

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 (550) hide show
  1. package/README.md +63 -7
  2. package/package.json +73 -249
  3. package/src/adapters/abstract/application-adapter.test.ts +172 -0
  4. package/src/adapters/abstract/application-adapter.ts +379 -0
  5. package/src/adapters/abstract/router-adapter.ts +30 -0
  6. package/src/adapters/abstract/server-adapter.ts +79 -0
  7. package/src/adapters/bun/client-bridge.ts +62 -0
  8. package/src/adapters/bun/create-app.ts +232 -0
  9. package/src/adapters/bun/hmr-manager.test.ts +265 -0
  10. package/src/adapters/bun/hmr-manager.ts +383 -0
  11. package/src/adapters/bun/index.ts +2 -0
  12. package/src/adapters/bun/server-adapter.ts +526 -0
  13. package/src/adapters/bun/server-lifecycle.ts +124 -0
  14. package/src/adapters/create-app.test.ts +10 -0
  15. package/src/adapters/create-app.ts +91 -0
  16. package/src/adapters/index.ts +2 -0
  17. package/src/adapters/node/create-app.test.ts +53 -0
  18. package/src/adapters/node/create-app.ts +183 -0
  19. package/src/adapters/node/node-client-bridge.test.ts +198 -0
  20. package/src/adapters/node/node-client-bridge.ts +79 -0
  21. package/src/adapters/node/node-hmr-manager.test.ts +320 -0
  22. package/src/adapters/node/node-hmr-manager.ts +355 -0
  23. package/src/adapters/node/server-adapter.ts +502 -0
  24. package/src/adapters/node/static-content-server.test.ts +60 -0
  25. package/src/adapters/node/static-content-server.ts +239 -0
  26. package/src/adapters/shared/api-response.test.ts +97 -0
  27. package/src/adapters/shared/api-response.ts +104 -0
  28. package/src/adapters/shared/application-adapter.ts +199 -0
  29. package/src/adapters/shared/define-api-handler.ts +66 -0
  30. package/src/adapters/shared/explicit-static-render-preparation.ts +58 -0
  31. package/src/adapters/shared/explicit-static-route-matcher.test.ts +381 -0
  32. package/src/adapters/shared/explicit-static-route-matcher.ts +131 -0
  33. package/src/adapters/shared/file-route-middleware-pipeline.test.ts +85 -0
  34. package/src/adapters/shared/file-route-middleware-pipeline.ts +118 -0
  35. package/src/adapters/shared/fs-server-response-factory.test.ts +176 -0
  36. package/src/adapters/shared/fs-server-response-factory.ts +96 -0
  37. package/src/adapters/shared/fs-server-response-matcher.test.ts +311 -0
  38. package/src/adapters/shared/fs-server-response-matcher.ts +240 -0
  39. package/src/adapters/shared/hmr-entrypoint-registrar.ts +149 -0
  40. package/src/adapters/shared/hmr-html-response.ts +52 -0
  41. package/src/adapters/shared/hmr-manager.contract.test.ts +228 -0
  42. package/src/adapters/shared/hmr-manager.dispatch.test.ts +220 -0
  43. package/src/adapters/shared/render-context.test.ts +150 -0
  44. package/src/adapters/shared/render-context.ts +123 -0
  45. package/src/adapters/shared/runtime-bootstrap.ts +79 -0
  46. package/src/adapters/shared/server-adapter.test.ts +130 -0
  47. package/src/adapters/shared/server-adapter.ts +562 -0
  48. package/src/adapters/shared/server-route-handler.test.ts +111 -0
  49. package/src/adapters/shared/server-route-handler.ts +153 -0
  50. package/src/adapters/shared/server-static-builder.test.ts +338 -0
  51. package/src/adapters/shared/server-static-builder.ts +170 -0
  52. package/src/build/build-adapter-serialization.test.ts +281 -0
  53. package/src/build/build-adapter.test.ts +1240 -0
  54. package/src/build/build-adapter.ts +1012 -0
  55. package/src/build/build-manifest.ts +54 -0
  56. package/src/build/build-types.ts +83 -0
  57. package/src/build/dev-build-coordinator.ts +220 -0
  58. package/src/build/esbuild-build-adapter.ts +660 -0
  59. package/src/build/runtime-build-executor.test.ts +81 -0
  60. package/src/build/runtime-build-executor.ts +40 -0
  61. package/src/build/runtime-specifier-alias-plugin.test.ts +67 -0
  62. package/src/build/runtime-specifier-alias-plugin.ts +62 -0
  63. package/src/build/runtime-specifier-aliases.ts +135 -0
  64. package/src/config/README.md +1 -1
  65. package/src/config/config-builder.test.ts +442 -0
  66. package/src/config/config-builder.ts +737 -0
  67. package/src/config/config-builder.typecheck.test.ts +96 -0
  68. package/src/config/{constants.d.ts → constants.ts} +22 -13
  69. package/src/dev/host-runtime.ts +34 -0
  70. package/src/dev/sc-server.ts +143 -0
  71. package/src/eco/eco.browser.test.ts +43 -0
  72. package/src/eco/eco.browser.ts +118 -0
  73. package/src/eco/eco.test.ts +654 -0
  74. package/src/eco/eco.ts +205 -0
  75. package/src/eco/eco.types.ts +221 -0
  76. package/src/eco/eco.utils.test.ts +219 -0
  77. package/src/eco/eco.utils.ts +5 -0
  78. package/src/eco/global-injector-map.test.ts +42 -0
  79. package/src/eco/global-injector-map.ts +112 -0
  80. package/src/eco/lazy-injector-map.test.ts +66 -0
  81. package/src/eco/lazy-injector-map.ts +120 -0
  82. package/src/eco/module-dependencies.test.ts +30 -0
  83. package/src/eco/module-dependencies.ts +75 -0
  84. package/src/errors/http-error.test.ts +134 -0
  85. package/src/errors/http-error.ts +72 -0
  86. package/src/errors/index.ts +3 -0
  87. package/src/errors/locals-access-error.ts +7 -0
  88. package/src/global/app-logger.ts +4 -0
  89. package/src/global/utils.test.ts +12 -0
  90. 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
  91. package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-HMR-Server-Integration-should-load-fixture-app-page-1.png +0 -0
  92. package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-WebSocket-Connection-should-connect-to-correct-HMR-endpoint-1.png +0 -0
  93. package/src/hmr/client/hmr-runtime.ts +162 -0
  94. package/src/hmr/hmr-strategy.test.ts +124 -0
  95. package/src/hmr/hmr-strategy.ts +177 -0
  96. package/src/hmr/hmr.postcss.test.e2e.ts +41 -0
  97. package/src/hmr/hmr.test.e2e.ts +66 -0
  98. package/src/hmr/strategies/default-hmr-strategy.ts +60 -0
  99. package/src/hmr/strategies/js-hmr-strategy.test.ts +334 -0
  100. package/src/hmr/strategies/js-hmr-strategy.ts +314 -0
  101. package/src/index.browser.ts +3 -0
  102. package/src/index.ts +15 -0
  103. package/src/integrations/ghtml/ghtml-renderer.test.ts +253 -0
  104. package/src/integrations/ghtml/ghtml-renderer.ts +87 -0
  105. package/src/integrations/ghtml/ghtml.constants.ts +1 -0
  106. package/src/integrations/ghtml/ghtml.plugin.ts +28 -0
  107. package/src/plugins/alias-resolver-plugin.test.ts +41 -0
  108. package/src/plugins/alias-resolver-plugin.ts +63 -0
  109. package/src/plugins/eco-component-meta-plugin.test.ts +406 -0
  110. package/src/plugins/eco-component-meta-plugin.ts +494 -0
  111. package/src/plugins/foreign-jsx-override-plugin.test.ts +65 -0
  112. package/src/plugins/foreign-jsx-override-plugin.ts +67 -0
  113. package/src/plugins/integration-plugin.test.ts +151 -0
  114. package/src/plugins/integration-plugin.ts +323 -0
  115. package/src/plugins/processor.test.ts +148 -0
  116. package/src/plugins/processor.ts +257 -0
  117. package/src/plugins/{runtime-capability.d.ts → runtime-capability.ts} +8 -3
  118. package/src/plugins/source-transform.test.ts +82 -0
  119. package/src/plugins/source-transform.ts +123 -0
  120. package/src/route-renderer/GRAPH.md +81 -289
  121. package/src/route-renderer/README.md +67 -105
  122. package/src/route-renderer/orchestration/component-render-context.ts +325 -0
  123. package/src/route-renderer/orchestration/declared-ownership-graph.ts +62 -0
  124. package/src/route-renderer/orchestration/foreign-subtree-execution.service.ts +383 -0
  125. package/src/route-renderer/orchestration/integration-renderer.test.ts +2085 -0
  126. package/src/route-renderer/orchestration/integration-renderer.ts +1244 -0
  127. package/src/route-renderer/orchestration/ownership-planning.service.ts +97 -0
  128. package/src/route-renderer/orchestration/ownership-validation.service.ts +76 -0
  129. package/src/route-renderer/orchestration/processed-asset-dedupe.ts +25 -0
  130. package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.test.ts +324 -0
  131. package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.ts +294 -0
  132. package/src/route-renderer/orchestration/render-output.utils.ts +310 -0
  133. package/src/route-renderer/orchestration/route-render-orchestrator.prepare-render-options.test.ts +644 -0
  134. package/src/route-renderer/orchestration/route-render-orchestrator.test.ts +265 -0
  135. package/src/route-renderer/orchestration/route-render-orchestrator.ts +592 -0
  136. package/src/route-renderer/orchestration/template-serialization.test.ts +110 -0
  137. package/src/route-renderer/orchestration/template-serialization.ts +117 -0
  138. package/src/route-renderer/page-loading/component-dependency-collection.ts +202 -0
  139. package/src/route-renderer/page-loading/declared-asset-collection.ts +153 -0
  140. package/src/route-renderer/page-loading/dependency-resolver.test.ts +761 -0
  141. package/src/route-renderer/page-loading/dependency-resolver.ts +144 -0
  142. package/src/route-renderer/page-loading/ecopages-virtual-imports.ts +75 -0
  143. package/src/route-renderer/page-loading/lazy-entry-collection.ts +167 -0
  144. package/src/route-renderer/page-loading/lazy-trigger-planning.ts +74 -0
  145. package/src/route-renderer/page-loading/module-declaration-aggregation.ts +60 -0
  146. package/src/route-renderer/page-loading/module-declaration-scripts.ts +16 -0
  147. package/src/route-renderer/page-loading/page-dependency-bundling.ts +244 -0
  148. package/src/route-renderer/page-loading/page-module-loader.test.ts +183 -0
  149. package/src/route-renderer/page-loading/page-module-loader.ts +184 -0
  150. package/src/route-renderer/route-renderer.ts +133 -0
  151. package/src/router/README.md +16 -19
  152. package/src/router/client/link-intent.test.browser.ts +51 -0
  153. package/src/router/client/link-intent.ts +92 -0
  154. package/src/router/client/navigation-coordinator.test.ts +237 -0
  155. package/src/router/client/navigation-coordinator.ts +453 -0
  156. package/src/router/server/route-registry.test.ts +176 -0
  157. package/src/router/server/route-registry.ts +382 -0
  158. package/src/services/README.md +1 -2
  159. package/src/services/assets/asset-processing-service/asset-dependency-keys.ts +66 -0
  160. package/src/services/assets/asset-processing-service/asset-processing.service.test.ts +473 -0
  161. package/src/services/assets/asset-processing-service/asset-processing.service.ts +344 -0
  162. package/src/services/assets/asset-processing-service/asset.factory.test.ts +63 -0
  163. package/src/services/assets/asset-processing-service/asset.factory.ts +105 -0
  164. package/src/services/assets/asset-processing-service/assets.types.ts +128 -0
  165. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.test.ts +74 -0
  166. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.ts +96 -0
  167. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.test.ts +67 -0
  168. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.ts +78 -0
  169. package/src/services/assets/asset-processing-service/grouped-content-bundles.ts +104 -0
  170. package/src/services/assets/asset-processing-service/index.ts +6 -0
  171. package/src/services/assets/asset-processing-service/page-package.test.ts +100 -0
  172. package/src/services/assets/asset-processing-service/page-package.ts +93 -0
  173. package/src/services/assets/asset-processing-service/{processor.interface.d.ts → processor.interface.ts} +10 -5
  174. package/src/services/assets/asset-processing-service/processor.registry.ts +18 -0
  175. package/src/services/assets/asset-processing-service/processors/base/base-processor.test.ts +59 -0
  176. package/src/services/assets/asset-processing-service/processors/base/base-processor.ts +83 -0
  177. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.ts +173 -0
  178. package/src/services/assets/asset-processing-service/processors/index.ts +5 -0
  179. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.test.ts +195 -0
  180. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.ts +137 -0
  181. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.test.ts +326 -0
  182. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.ts +116 -0
  183. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.test.ts +227 -0
  184. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.ts +89 -0
  185. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.test.ts +261 -0
  186. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.ts +72 -0
  187. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.ts +83 -0
  188. package/src/services/assets/asset-processing-service/ungrouped-dependency-processing.ts +65 -0
  189. package/src/services/assets/browser-bundle.service.test.ts +66 -0
  190. package/src/services/assets/browser-bundle.service.ts +109 -0
  191. package/src/services/cache/cache.types.ts +126 -0
  192. package/src/services/cache/index.ts +18 -0
  193. package/src/services/cache/memory-cache-store.test.ts +225 -0
  194. package/src/services/cache/memory-cache-store.ts +130 -0
  195. package/src/services/cache/page-cache-service.test.ts +175 -0
  196. package/src/services/cache/page-cache-service.ts +202 -0
  197. package/src/services/cache/page-request-cache-coordinator.service.test.ts +79 -0
  198. package/src/services/cache/page-request-cache-coordinator.service.ts +131 -0
  199. package/src/services/html/html-rewriter-provider.service.test.ts +183 -0
  200. package/src/services/html/html-rewriter-provider.service.ts +104 -0
  201. package/src/services/html/html-transformer.service.test.ts +476 -0
  202. package/src/services/html/html-transformer.service.ts +275 -0
  203. package/src/services/invalidation/development-invalidation.service.test.ts +87 -0
  204. package/src/services/invalidation/development-invalidation.service.ts +262 -0
  205. package/src/services/module-loading/app-module-loader.service.ts +9 -0
  206. package/src/services/module-loading/app-server-module-transpiler.service.test.ts +130 -0
  207. package/src/services/module-loading/app-server-module-transpiler.service.ts +141 -0
  208. package/src/services/module-loading/host-module-loader-registry.ts +15 -0
  209. package/src/services/module-loading/{module-loading-types.d.ts → module-loading-types.ts} +1 -0
  210. package/src/services/module-loading/node-bootstrap-plugin.test.ts +335 -0
  211. package/src/services/module-loading/node-bootstrap-plugin.ts +311 -0
  212. package/src/services/module-loading/page-module-import.service.test.ts +504 -0
  213. package/src/services/module-loading/page-module-import.service.ts +251 -0
  214. package/src/services/module-loading/server-module-transpiler.service.test.ts +243 -0
  215. package/src/services/module-loading/server-module-transpiler.service.ts +104 -0
  216. package/src/services/module-loading/source-module-support.ts +19 -0
  217. package/src/services/runtime-state/dev-graph.service.ts +217 -0
  218. package/src/services/runtime-state/entrypoint-dependency-graph.service.ts +136 -0
  219. package/src/services/runtime-state/server-invalidation-state.service.ts +68 -0
  220. package/src/services/validation/schema-validation-service.test.ts +223 -0
  221. package/src/services/validation/schema-validation-service.ts +204 -0
  222. package/src/services/validation/{standard-schema.types.d.ts → standard-schema.types.ts} +20 -17
  223. package/src/static-site-generator/static-site-generator.test.ts +408 -0
  224. package/src/static-site-generator/static-site-generator.ts +445 -0
  225. package/src/types/internal-types.ts +243 -0
  226. package/src/types/public-types.ts +1459 -0
  227. package/src/utils/deep-merge.test.ts +114 -0
  228. package/src/utils/deep-merge.ts +47 -0
  229. package/src/utils/hash.ts +5 -0
  230. package/src/utils/html-escaping.ts +9 -0
  231. package/src/utils/invariant.test.ts +22 -0
  232. package/src/utils/invariant.ts +15 -0
  233. package/src/utils/locals-utils.ts +37 -0
  234. package/src/utils/parse-cli-args.test.ts +69 -0
  235. package/src/utils/parse-cli-args.ts +105 -0
  236. package/src/utils/path-utils.module.ts +14 -0
  237. package/src/utils/path-utils.test.ts +15 -0
  238. package/src/utils/resolve-work-dir.ts +45 -0
  239. package/src/utils/runtime.ts +44 -0
  240. package/src/utils/server-utils.module.ts +67 -0
  241. package/src/utils/server-utils.test.ts +38 -0
  242. package/src/watchers/project-watcher.integration.test.ts +337 -0
  243. package/src/watchers/project-watcher.test-helpers.ts +42 -0
  244. package/src/watchers/project-watcher.test.ts +768 -0
  245. package/src/watchers/project-watcher.ts +357 -0
  246. package/CHANGELOG.md +0 -66
  247. package/src/adapters/abstract/application-adapter.d.ts +0 -194
  248. package/src/adapters/abstract/application-adapter.js +0 -121
  249. package/src/adapters/abstract/router-adapter.d.ts +0 -26
  250. package/src/adapters/abstract/router-adapter.js +0 -5
  251. package/src/adapters/abstract/server-adapter.d.ts +0 -69
  252. package/src/adapters/abstract/server-adapter.js +0 -15
  253. package/src/adapters/bun/client-bridge.d.ts +0 -34
  254. package/src/adapters/bun/client-bridge.js +0 -48
  255. package/src/adapters/bun/create-app.d.ts +0 -52
  256. package/src/adapters/bun/create-app.js +0 -116
  257. package/src/adapters/bun/hmr-manager.d.ts +0 -143
  258. package/src/adapters/bun/hmr-manager.js +0 -333
  259. package/src/adapters/bun/index.d.ts +0 -2
  260. package/src/adapters/bun/index.js +0 -8
  261. package/src/adapters/bun/server-adapter.d.ts +0 -155
  262. package/src/adapters/bun/server-adapter.js +0 -374
  263. package/src/adapters/bun/server-lifecycle.d.ts +0 -63
  264. package/src/adapters/bun/server-lifecycle.js +0 -92
  265. package/src/adapters/create-app.d.ts +0 -20
  266. package/src/adapters/create-app.js +0 -66
  267. package/src/adapters/index.d.ts +0 -2
  268. package/src/adapters/index.js +0 -8
  269. package/src/adapters/node/create-app.d.ts +0 -18
  270. package/src/adapters/node/create-app.js +0 -149
  271. package/src/adapters/node/node-client-bridge.d.ts +0 -26
  272. package/src/adapters/node/node-client-bridge.js +0 -66
  273. package/src/adapters/node/node-hmr-manager.d.ts +0 -133
  274. package/src/adapters/node/node-hmr-manager.js +0 -311
  275. package/src/adapters/node/server-adapter.d.ts +0 -162
  276. package/src/adapters/node/server-adapter.js +0 -368
  277. package/src/adapters/node/static-content-server.d.ts +0 -60
  278. package/src/adapters/node/static-content-server.js +0 -194
  279. package/src/adapters/shared/api-response.d.ts +0 -52
  280. package/src/adapters/shared/api-response.js +0 -96
  281. package/src/adapters/shared/application-adapter.d.ts +0 -18
  282. package/src/adapters/shared/application-adapter.js +0 -90
  283. package/src/adapters/shared/define-api-handler.d.ts +0 -25
  284. package/src/adapters/shared/define-api-handler.js +0 -15
  285. package/src/adapters/shared/explicit-static-route-matcher.d.ts +0 -38
  286. package/src/adapters/shared/explicit-static-route-matcher.js +0 -103
  287. package/src/adapters/shared/file-route-middleware-pipeline.d.ts +0 -65
  288. package/src/adapters/shared/file-route-middleware-pipeline.js +0 -99
  289. package/src/adapters/shared/fs-server-response-factory.d.ts +0 -19
  290. package/src/adapters/shared/fs-server-response-factory.js +0 -97
  291. package/src/adapters/shared/fs-server-response-matcher.d.ts +0 -67
  292. package/src/adapters/shared/fs-server-response-matcher.js +0 -147
  293. package/src/adapters/shared/hmr-entrypoint-registrar.d.ts +0 -55
  294. package/src/adapters/shared/hmr-entrypoint-registrar.js +0 -87
  295. package/src/adapters/shared/hmr-html-response.d.ts +0 -22
  296. package/src/adapters/shared/hmr-html-response.js +0 -32
  297. package/src/adapters/shared/render-context.d.ts +0 -15
  298. package/src/adapters/shared/render-context.js +0 -72
  299. package/src/adapters/shared/runtime-bootstrap.d.ts +0 -38
  300. package/src/adapters/shared/runtime-bootstrap.js +0 -43
  301. package/src/adapters/shared/server-adapter.d.ts +0 -97
  302. package/src/adapters/shared/server-adapter.js +0 -390
  303. package/src/adapters/shared/server-route-handler.d.ts +0 -89
  304. package/src/adapters/shared/server-route-handler.js +0 -111
  305. package/src/adapters/shared/server-static-builder.d.ts +0 -71
  306. package/src/adapters/shared/server-static-builder.js +0 -100
  307. package/src/build/build-adapter.d.ts +0 -239
  308. package/src/build/build-adapter.js +0 -642
  309. package/src/build/build-manifest.d.ts +0 -27
  310. package/src/build/build-manifest.js +0 -30
  311. package/src/build/build-types.d.ts +0 -57
  312. package/src/build/build-types.js +0 -0
  313. package/src/build/dev-build-coordinator.d.ts +0 -72
  314. package/src/build/dev-build-coordinator.js +0 -154
  315. package/src/build/esbuild-build-adapter.d.ts +0 -78
  316. package/src/build/esbuild-build-adapter.js +0 -505
  317. package/src/build/runtime-build-executor.d.ts +0 -14
  318. package/src/build/runtime-build-executor.js +0 -22
  319. package/src/build/runtime-specifier-alias-plugin.d.ts +0 -15
  320. package/src/build/runtime-specifier-alias-plugin.js +0 -35
  321. package/src/build/runtime-specifier-aliases.d.ts +0 -5
  322. package/src/build/runtime-specifier-aliases.js +0 -95
  323. package/src/config/config-builder.d.ts +0 -252
  324. package/src/config/config-builder.js +0 -603
  325. package/src/config/constants.js +0 -25
  326. package/src/dev/sc-server.d.ts +0 -30
  327. package/src/dev/sc-server.js +0 -111
  328. package/src/eco/eco.browser.d.ts +0 -2
  329. package/src/eco/eco.browser.js +0 -83
  330. package/src/eco/eco.d.ts +0 -9
  331. package/src/eco/eco.js +0 -85
  332. package/src/eco/eco.types.d.ts +0 -178
  333. package/src/eco/eco.types.js +0 -0
  334. package/src/eco/eco.utils.d.ts +0 -1
  335. package/src/eco/eco.utils.js +0 -10
  336. package/src/eco/global-injector-map.d.ts +0 -16
  337. package/src/eco/global-injector-map.js +0 -80
  338. package/src/eco/lazy-injector-map.d.ts +0 -8
  339. package/src/eco/lazy-injector-map.js +0 -70
  340. package/src/eco/module-dependencies.d.ts +0 -18
  341. package/src/eco/module-dependencies.js +0 -49
  342. package/src/errors/http-error.d.ts +0 -31
  343. package/src/errors/http-error.js +0 -50
  344. package/src/errors/index.d.ts +0 -2
  345. package/src/errors/index.js +0 -4
  346. package/src/errors/locals-access-error.d.ts +0 -4
  347. package/src/errors/locals-access-error.js +0 -9
  348. package/src/global/app-logger.d.ts +0 -2
  349. package/src/global/app-logger.js +0 -6
  350. package/src/hmr/client/hmr-runtime.d.ts +0 -5
  351. package/src/hmr/client/hmr-runtime.js +0 -117
  352. package/src/hmr/hmr-strategy.d.ts +0 -162
  353. package/src/hmr/hmr-strategy.js +0 -44
  354. package/src/hmr/hmr.postcss.test.e2e.d.ts +0 -1
  355. package/src/hmr/hmr.postcss.test.e2e.js +0 -31
  356. package/src/hmr/hmr.test.e2e.d.ts +0 -1
  357. package/src/hmr/hmr.test.e2e.js +0 -43
  358. package/src/hmr/strategies/default-hmr-strategy.d.ts +0 -43
  359. package/src/hmr/strategies/default-hmr-strategy.js +0 -34
  360. package/src/hmr/strategies/js-hmr-strategy.d.ts +0 -139
  361. package/src/hmr/strategies/js-hmr-strategy.js +0 -178
  362. package/src/index.browser.d.ts +0 -3
  363. package/src/index.browser.js +0 -4
  364. package/src/index.d.ts +0 -6
  365. package/src/index.js +0 -21
  366. package/src/integrations/ghtml/ghtml-renderer.d.ts +0 -20
  367. package/src/integrations/ghtml/ghtml-renderer.js +0 -63
  368. package/src/integrations/ghtml/ghtml.constants.d.ts +0 -1
  369. package/src/integrations/ghtml/ghtml.constants.js +0 -4
  370. package/src/integrations/ghtml/ghtml.plugin.d.ts +0 -16
  371. package/src/integrations/ghtml/ghtml.plugin.js +0 -20
  372. package/src/plugins/alias-resolver-plugin.d.ts +0 -2
  373. package/src/plugins/alias-resolver-plugin.js +0 -53
  374. package/src/plugins/eco-component-meta-plugin.d.ts +0 -108
  375. package/src/plugins/eco-component-meta-plugin.js +0 -163
  376. package/src/plugins/foreign-jsx-override-plugin.d.ts +0 -31
  377. package/src/plugins/foreign-jsx-override-plugin.js +0 -35
  378. package/src/plugins/integration-plugin.d.ts +0 -219
  379. package/src/plugins/integration-plugin.js +0 -196
  380. package/src/plugins/processor.d.ts +0 -95
  381. package/src/plugins/processor.js +0 -136
  382. package/src/plugins/runtime-capability.js +0 -0
  383. package/src/plugins/source-transform.d.ts +0 -46
  384. package/src/plugins/source-transform.js +0 -71
  385. package/src/route-renderer/orchestration/boundary-planning.service.d.ts +0 -25
  386. package/src/route-renderer/orchestration/boundary-planning.service.js +0 -97
  387. package/src/route-renderer/orchestration/component-render-context.d.ts +0 -83
  388. package/src/route-renderer/orchestration/component-render-context.js +0 -147
  389. package/src/route-renderer/orchestration/integration-renderer.d.ts +0 -556
  390. package/src/route-renderer/orchestration/integration-renderer.js +0 -932
  391. package/src/route-renderer/orchestration/page-packaging.service.d.ts +0 -16
  392. package/src/route-renderer/orchestration/page-packaging.service.js +0 -66
  393. package/src/route-renderer/orchestration/processed-asset-dedupe.d.ts +0 -2
  394. package/src/route-renderer/orchestration/processed-asset-dedupe.js +0 -23
  395. package/src/route-renderer/orchestration/queued-boundary-runtime.service.d.ts +0 -89
  396. package/src/route-renderer/orchestration/queued-boundary-runtime.service.js +0 -155
  397. package/src/route-renderer/orchestration/render-execution.service.d.ts +0 -43
  398. package/src/route-renderer/orchestration/render-execution.service.js +0 -106
  399. package/src/route-renderer/orchestration/render-output.utils.d.ts +0 -66
  400. package/src/route-renderer/orchestration/render-output.utils.js +0 -171
  401. package/src/route-renderer/orchestration/render-preparation.service.d.ts +0 -120
  402. package/src/route-renderer/orchestration/render-preparation.service.js +0 -364
  403. package/src/route-renderer/orchestration/route-shell-composer.service.d.ts +0 -50
  404. package/src/route-renderer/orchestration/route-shell-composer.service.js +0 -81
  405. package/src/route-renderer/orchestration/template-serialization.d.ts +0 -38
  406. package/src/route-renderer/orchestration/template-serialization.js +0 -45
  407. package/src/route-renderer/page-loading/component-dependency-collection.d.ts +0 -37
  408. package/src/route-renderer/page-loading/component-dependency-collection.js +0 -125
  409. package/src/route-renderer/page-loading/declared-asset-collection.d.ts +0 -24
  410. package/src/route-renderer/page-loading/declared-asset-collection.js +0 -106
  411. package/src/route-renderer/page-loading/dependency-resolver.d.ts +0 -35
  412. package/src/route-renderer/page-loading/dependency-resolver.js +0 -117
  413. package/src/route-renderer/page-loading/ecopages-virtual-imports.d.ts +0 -11
  414. package/src/route-renderer/page-loading/ecopages-virtual-imports.js +0 -57
  415. package/src/route-renderer/page-loading/lazy-entry-collection.d.ts +0 -45
  416. package/src/route-renderer/page-loading/lazy-entry-collection.js +0 -105
  417. package/src/route-renderer/page-loading/lazy-trigger-planning.d.ts +0 -19
  418. package/src/route-renderer/page-loading/lazy-trigger-planning.js +0 -40
  419. package/src/route-renderer/page-loading/module-declaration-aggregation.d.ts +0 -5
  420. package/src/route-renderer/page-loading/module-declaration-aggregation.js +0 -33
  421. package/src/route-renderer/page-loading/module-declaration-scripts.d.ts +0 -3
  422. package/src/route-renderer/page-loading/module-declaration-scripts.js +0 -18
  423. package/src/route-renderer/page-loading/page-dependency-bundling.d.ts +0 -13
  424. package/src/route-renderer/page-loading/page-dependency-bundling.js +0 -115
  425. package/src/route-renderer/page-loading/page-module-loader.d.ts +0 -90
  426. package/src/route-renderer/page-loading/page-module-loader.js +0 -127
  427. package/src/route-renderer/route-renderer.d.ts +0 -67
  428. package/src/route-renderer/route-renderer.js +0 -103
  429. package/src/router/client/link-intent.js +0 -34
  430. package/src/router/client/link-intent.test.browser.d.ts +0 -1
  431. package/src/router/client/link-intent.test.browser.js +0 -43
  432. package/src/router/client/navigation-coordinator.d.ts +0 -169
  433. package/src/router/client/navigation-coordinator.js +0 -215
  434. package/src/router/server/fs-router-scanner.d.ts +0 -41
  435. package/src/router/server/fs-router-scanner.js +0 -161
  436. package/src/router/server/fs-router.d.ts +0 -26
  437. package/src/router/server/fs-router.js +0 -100
  438. package/src/services/assets/asset-processing-service/asset-dependency-keys.d.ts +0 -3
  439. package/src/services/assets/asset-processing-service/asset-dependency-keys.js +0 -56
  440. package/src/services/assets/asset-processing-service/asset-processing.service.d.ts +0 -103
  441. package/src/services/assets/asset-processing-service/asset-processing.service.js +0 -285
  442. package/src/services/assets/asset-processing-service/asset.factory.d.ts +0 -17
  443. package/src/services/assets/asset-processing-service/asset.factory.js +0 -82
  444. package/src/services/assets/asset-processing-service/assets.types.d.ts +0 -100
  445. package/src/services/assets/asset-processing-service/assets.types.js +0 -0
  446. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.d.ts +0 -55
  447. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +0 -49
  448. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.d.ts +0 -20
  449. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.js +0 -41
  450. package/src/services/assets/asset-processing-service/grouped-content-bundles.d.ts +0 -30
  451. package/src/services/assets/asset-processing-service/grouped-content-bundles.js +0 -65
  452. package/src/services/assets/asset-processing-service/index.d.ts +0 -5
  453. package/src/services/assets/asset-processing-service/index.js +0 -5
  454. package/src/services/assets/asset-processing-service/processor.interface.js +0 -6
  455. package/src/services/assets/asset-processing-service/processor.registry.d.ts +0 -8
  456. package/src/services/assets/asset-processing-service/processor.registry.js +0 -15
  457. package/src/services/assets/asset-processing-service/processors/base/base-processor.d.ts +0 -24
  458. package/src/services/assets/asset-processing-service/processors/base/base-processor.js +0 -65
  459. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.d.ts +0 -22
  460. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.js +0 -136
  461. package/src/services/assets/asset-processing-service/processors/index.d.ts +0 -5
  462. package/src/services/assets/asset-processing-service/processors/index.js +0 -5
  463. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.d.ts +0 -6
  464. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.js +0 -116
  465. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.d.ts +0 -9
  466. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +0 -91
  467. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.d.ts +0 -7
  468. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +0 -77
  469. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.d.ts +0 -8
  470. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +0 -58
  471. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.d.ts +0 -9
  472. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +0 -67
  473. package/src/services/assets/asset-processing-service/ungrouped-dependency-processing.d.ts +0 -18
  474. package/src/services/assets/asset-processing-service/ungrouped-dependency-processing.js +0 -45
  475. package/src/services/assets/browser-bundle.service.d.ts +0 -73
  476. package/src/services/assets/browser-bundle.service.js +0 -41
  477. package/src/services/cache/cache.types.d.ts +0 -107
  478. package/src/services/cache/cache.types.js +0 -0
  479. package/src/services/cache/index.d.ts +0 -7
  480. package/src/services/cache/index.js +0 -7
  481. package/src/services/cache/memory-cache-store.d.ts +0 -42
  482. package/src/services/cache/memory-cache-store.js +0 -98
  483. package/src/services/cache/page-cache-service.d.ts +0 -70
  484. package/src/services/cache/page-cache-service.js +0 -152
  485. package/src/services/cache/page-request-cache-coordinator.service.d.ts +0 -75
  486. package/src/services/cache/page-request-cache-coordinator.service.js +0 -109
  487. package/src/services/html/html-rewriter-provider.service.d.ts +0 -37
  488. package/src/services/html/html-rewriter-provider.service.js +0 -68
  489. package/src/services/html/html-transformer.service.d.ts +0 -87
  490. package/src/services/html/html-transformer.service.js +0 -216
  491. package/src/services/invalidation/development-invalidation.service.d.ts +0 -74
  492. package/src/services/invalidation/development-invalidation.service.js +0 -190
  493. package/src/services/module-loading/app-module-loader.service.d.ts +0 -7
  494. package/src/services/module-loading/app-module-loader.service.js +0 -0
  495. package/src/services/module-loading/app-server-module-transpiler.service.d.ts +0 -24
  496. package/src/services/module-loading/app-server-module-transpiler.service.js +0 -115
  497. package/src/services/module-loading/host-module-loader-registry.d.ts +0 -4
  498. package/src/services/module-loading/host-module-loader-registry.js +0 -15
  499. package/src/services/module-loading/module-loading-types.js +0 -0
  500. package/src/services/module-loading/node-bootstrap-plugin.d.ts +0 -42
  501. package/src/services/module-loading/node-bootstrap-plugin.js +0 -204
  502. package/src/services/module-loading/page-module-import.service.d.ts +0 -76
  503. package/src/services/module-loading/page-module-import.service.js +0 -170
  504. package/src/services/module-loading/server-module-transpiler.service.d.ts +0 -63
  505. package/src/services/module-loading/server-module-transpiler.service.js +0 -64
  506. package/src/services/module-loading/source-module-support.d.ts +0 -5
  507. package/src/services/module-loading/source-module-support.js +0 -8
  508. package/src/services/runtime-state/dev-graph.service.d.ts +0 -118
  509. package/src/services/runtime-state/dev-graph.service.js +0 -162
  510. package/src/services/runtime-state/entrypoint-dependency-graph.service.d.ts +0 -41
  511. package/src/services/runtime-state/entrypoint-dependency-graph.service.js +0 -85
  512. package/src/services/runtime-state/runtime-specifier-registry.service.d.ts +0 -69
  513. package/src/services/runtime-state/runtime-specifier-registry.service.js +0 -37
  514. package/src/services/runtime-state/server-invalidation-state.service.d.ts +0 -26
  515. package/src/services/runtime-state/server-invalidation-state.service.js +0 -35
  516. package/src/services/validation/schema-validation-service.d.ts +0 -122
  517. package/src/services/validation/schema-validation-service.js +0 -101
  518. package/src/services/validation/standard-schema.types.js +0 -0
  519. package/src/static-site-generator/static-site-generator.d.ts +0 -105
  520. package/src/static-site-generator/static-site-generator.js +0 -349
  521. package/src/types/internal-types.d.ts +0 -231
  522. package/src/types/internal-types.js +0 -0
  523. package/src/types/public-types.d.ts +0 -1257
  524. package/src/types/public-types.js +0 -0
  525. package/src/utils/deep-merge.d.ts +0 -14
  526. package/src/utils/deep-merge.js +0 -32
  527. package/src/utils/hash.d.ts +0 -1
  528. package/src/utils/hash.js +0 -7
  529. package/src/utils/html-escaping.d.ts +0 -7
  530. package/src/utils/html-escaping.js +0 -6
  531. package/src/utils/html.js +0 -4
  532. package/src/utils/invariant.d.ts +0 -5
  533. package/src/utils/invariant.js +0 -11
  534. package/src/utils/locals-utils.d.ts +0 -15
  535. package/src/utils/locals-utils.js +0 -24
  536. package/src/utils/parse-cli-args.d.ts +0 -27
  537. package/src/utils/parse-cli-args.js +0 -62
  538. package/src/utils/path-utils.module.d.ts +0 -5
  539. package/src/utils/path-utils.module.js +0 -14
  540. package/src/utils/resolve-work-dir.d.ts +0 -11
  541. package/src/utils/resolve-work-dir.js +0 -31
  542. package/src/utils/runtime.d.ts +0 -11
  543. package/src/utils/runtime.js +0 -40
  544. package/src/utils/server-utils.module.d.ts +0 -19
  545. package/src/utils/server-utils.module.js +0 -56
  546. package/src/watchers/project-watcher.d.ts +0 -136
  547. package/src/watchers/project-watcher.js +0 -275
  548. package/src/watchers/project-watcher.test-helpers.d.ts +0 -4
  549. package/src/watchers/project-watcher.test-helpers.js +0 -52
  550. /package/src/utils/{html.d.ts → html.ts} +0 -0
@@ -6,151 +6,113 @@ This folder contains the core rendering orchestration for Ecopages.
6
6
 
7
7
  The route renderer layer is responsible for:
8
8
 
9
- - Selecting the correct integration renderer for a route.
10
- - Loading page modules and resolving static data/metadata.
11
- - Resolving and processing component dependencies.
12
- - Applying full orchestration.
13
- - Emitting final HTML body output plus metadata/cache strategy.
9
+ - selecting the correct integration renderer for a route
10
+ - loading page modules and resolving static data or metadata
11
+ - resolving component dependencies and page browser assets
12
+ - coordinating mixed-integration rendering
13
+ - emitting final HTML plus cache strategy
14
14
 
15
- ## Main Components
15
+ ## Core Concepts
16
16
 
17
- ### `route-renderer.ts`
17
+ The architecture is organized around three distinct concepts:
18
18
 
19
- - `RouteRendererFactory` chooses integration renderers based on route file extension.
20
- - `RouteRenderer` delegates route execution to the selected integration renderer.
19
+ - `ownership`: preparation-time metadata that describes which integration owns each declared component edge
20
+ - `foreign child`: a component encountered during render whose owning integration differs from the current integration
21
+ - `foreign subtree`: the resolved HTML, assets, and root-attachment metadata returned by the owning renderer for that foreign child
21
22
 
22
- ### `orchestration/`
23
+ These concepts intentionally live in different places:
23
24
 
24
- Framework-owned orchestration services and renderer base class:
25
+ - `ownership-planning.service.ts` builds `ownershipPlan`
26
+ - `ownership-validation.service.ts` validates declared foreign ownership up front
27
+ - `component-render-context.ts` intercepts foreign children during active component render
28
+ - `queued-foreign-subtree-resolution.service.ts` resolves queued foreign subtrees for renderers that cannot hand them off inline
29
+ - `integration-renderer.ts` owns renderer-to-renderer delegation and shared shell composition
30
+ - `route-render-flow.ts` owns route preparation, final response capture, and unresolved artifact enforcement
25
31
 
26
- - `integration-renderer.ts`: abstract base class that coordinates end-to-end route rendering.
27
- - `render-preparation.service.ts`: page module/data/dependency preparation before render.
28
- - `render-execution.service.ts`: render capture, unresolved boundary artifact enforcement, and finalization.
29
- - `route-shell-composer.service.ts`: shared page/view/layout/html-template shell composition used by multiple integrations.
30
- - `queued-boundary-runtime.service.ts`: shared queued foreign-boundary runtime used directly by renderer-owned helpers, including string-first renderers.
32
+ ## Main Files
31
33
 
32
- It also provides:
34
+ ### `route-renderer.ts`
33
35
 
34
- - `renderToResponse()` contract for explicit-route rendering.
35
- - `renderComponent()` contract for component-level orchestration and artifact reporting.
36
- - deferred boundary resolution for nested cross-integration component boundaries.
36
+ - `RouteRendererFactory` chooses integration renderers from route files
37
+ - `RouteRenderer` delegates execution to the selected renderer
37
38
 
38
- ### Boundary Tokens
39
+ ### `orchestration/`
39
40
 
40
- Renderer-owned runtimes may emit internal boundary tokens while they resolve foreign descendants before returning final HTML. If literal `<eco-marker ...></eco-marker>` markup survives to route finalization, it is treated as an unresolved boundary artifact rather than a normal transport mechanism.
41
+ - `route-render-flow.ts`: one route render from page-module loading through final HTML output
42
+ - `integration-renderer.ts`: abstract base class for route rendering, explicit view rendering, and foreign-child delegation
43
+ - `ownership-planning.service.ts`: declared ownership graph construction
44
+ - `ownership-validation.service.ts`: up-front ownership validation for route roots and declared descendants
45
+ - `component-render-context.ts`: active render context used by `eco.component()` to intercept foreign children
46
+ - `queued-foreign-subtree-resolution.service.ts`: queue resolution for renderers that need token-based foreign-subtree handoff
47
+ - `render-output.utils.ts`: unresolved artifact normalization and marker inspection
41
48
 
42
49
  ### `page-loading/`
43
50
 
44
- Service for loading page modules and deriving page data:
45
-
46
- - `importPageFile()` runtime-aware loading.
47
- - `resolvePageModule()` normalizes exports and statics.
48
- - `resolvePageData()` resolves static props then metadata.
49
-
50
- Builds processed assets from component dependency declarations:
51
+ - `page-module-loader.ts`: imports page modules and normalizes page exports
52
+ - `dependency-resolver.ts`: resolves component dependencies and browser-facing assets
51
53
 
52
- - Scripts/styles/components/modules.
53
- - Lazy dependency grouping and trigger derivation.
54
- - Default global injector behavior with optional legacy scripts-injector compatibility.
54
+ ## Render Flow
55
55
 
56
- ## Rendering Behavior
56
+ The route-render contract is:
57
57
 
58
- Default behavior:
59
-
60
- - renderer-owned component-boundary orchestration + component render artifacts.
61
- - global lazy trigger map + global injector bootstrap.
62
-
63
- ## Mixed Renderer Mental Model
64
-
65
- The current mixed-renderer contract has four phases:
66
-
67
- 1. `render-preparation.service.ts` builds the route inputs and a conservative `boundaryPlan` from declared component dependencies.
68
- 2. The selected integration renderer owns page, layout, document-shell, and explicit-view composition for that route.
69
- 3. `route-shell-composer.service.ts` applies the shared page/view/layout/html-template composition flow while calling back into the owning renderer for each boundary render.
70
- 4. Renderer-owned boundary runtimes resolve foreign nested components through the owning renderer and exchange a compatibility `renderBoundary()` payload with explicit attachment-policy semantics.
71
- 5. `render-execution.service.ts` finalizes the response and fails if unresolved boundary artifact HTML survives the renderer-owned resolution pass.
58
+ 1. `RouteRendererFactory` selects the owning integration renderer.
59
+ 2. `IntegrationRenderer.execute()` delegates preparation and finalization to `RouteRenderFlow`.
60
+ 3. `RouteRenderFlow.prepareRenderOptions()` loads the page module, validates ownership, builds `ownershipPlan`, resolves page data, resolves dependencies, and builds the page browser graph.
61
+ 4. The integration renderer performs page, layout, and document-shell rendering. When it encounters a foreign child, it delegates that child back to the owning renderer.
62
+ 5. If a renderer needs queued handoff, it emits internal foreign-subtree tokens and resolves them before returning final HTML.
63
+ 6. `RouteRenderFlow.execute()` captures the final body, rejects unresolved `<eco-marker>` artifacts, stamps root or document attributes when needed, and runs the HTML transformer.
72
64
 
73
65
  Important:
74
66
 
75
- - Renderer-owned deferral is intentional. Ecopages does not run a route-level fallback resolver after render completion.
76
- - Boundary ownership is planned from declared component dependency metadata, not inferred purely from rendered HTML.
77
- - Same-integration children do not have to pass through one universal string-only transport. Each renderer keeps its own child transport rules for same-integration trees.
67
+ - route-level fallback resolution is gone; unresolved artifacts are now a hard failure
68
+ - ownership is declared from component metadata, not inferred from final HTML
69
+ - same-integration children stay renderer-local and do not need to pass through a universal transport
78
70
 
79
71
  ## Declared Foreign Child Contract
80
72
 
81
- Mixed-integration component configs must declare every possible foreign child in `config.dependencies.components`. The planning pass uses those declarations to describe ownership transitions and surface invalid or unknown foreign owners before render execution.
82
-
83
- Current behavior:
73
+ Mixed-integration component configs must declare every possible foreign child in `config.dependencies.components`.
84
74
 
85
- - Missing or unknown ownership is recorded on the route `boundaryPlan` as validation errors.
86
- - Renderer-owned runtime discovery still resolves actual foreign descendants during render.
87
- - If unresolved boundary artifact HTML reaches route finalization, Ecopages throws instead of attempting a route-level recovery pass.
75
+ That declaration is used for two things:
88
76
 
89
- Global injector lifecycle notes:
77
+ - `OwnershipValidationService` surfaces missing metadata or unknown integrations before render execution
78
+ - `OwnershipPlanningService` records the expected ownership shape in `ownershipPlan`
90
79
 
91
- - The bootstrap remains active across client-side navigations.
92
- - On `eco:after-swap`, it prunes stale `ecopages/global-injector-map` scripts and calls `refresh()` so newly swapped `data-eco-trigger` elements can bind their lazy rules.
93
- - It must not call injector `cleanup()` on every swap, because that permanently disables future refresh work for the current runtime instance.
80
+ At runtime, renderers still discover actual foreign children through the active component render context.
94
81
 
95
- ## Boundary Payload Contract
82
+ ## Foreign Subtree Contract
96
83
 
97
- The compatibility boundary API is `renderBoundary()`. Today it wraps the existing `renderComponentBoundary()` behavior and returns a narrower payload:
84
+ `renderForeignSubtree()` is the compatibility contract for renderer-to-renderer handoff. It returns:
98
85
 
99
86
  - `html`
100
87
  - `assets`
101
88
  - `rootTag`
102
- - `integrationName`
103
89
  - optional `rootAttributes`
104
90
  - `attachmentPolicy`
105
-
106
- `renderComponent()` still returns `ComponentRenderResult` internally, including `canAttachAttributes`, because renderer-local implementations have not been collapsed into one universal boundary primitive.
107
-
108
- Base orchestration uses the compatibility payload to:
109
-
110
- - keep queued foreign-boundary resolution renderer-owned
111
- - apply root attributes only when `attachmentPolicy.kind === 'first-element'`
112
- - preserve asset bubbling through the normal dependency pipeline
113
-
114
- The lower-level `ComponentRenderResult` currently includes:
115
-
116
- - `html`
117
- - `canAttachAttributes`
118
- - `rootTag`
119
91
  - `integrationName`
120
- - optional `rootAttributes`
121
- - optional `assets`
122
-
123
- When rendered output still contains unresolved boundary artifact HTML:
124
92
 
125
- - route execution now fails fast instead of attempting any route-level unresolved-boundary fallback.
126
- - renderer-owned boundary runtimes are responsible for resolving foreign nested components before final route HTML is returned.
93
+ `renderComponentWithForeignChildren()` is the higher-level renderer entrypoint. It is responsible for:
127
94
 
128
- This enables island-style hydration assets (for example React/Lit/Kita integration outputs) to be emitted through the normal dependency injection pipeline.
95
+ - reusing the execution-scoped owning-renderer cache
96
+ - deciding whether the current component can stay local
97
+ - creating a foreign-child runtime when nested foreign ownership must be resolved
98
+ - normalizing unresolved artifact HTML before the render leaves the renderer
129
99
 
130
- ## React Island Boundary Notes
100
+ ## Queue Model
131
101
 
132
- - React component-level islands are emitted without synthetic wrapper elements.
133
- - The React integration attaches `data-eco-component-id` on the component's own SSR root element when a single root is available.
134
- - Island client bootstrap mounts with `createRoot()` into that root boundary.
135
- - The emitted hydration bootstrap also listens for `eco:after-swap` so islands hydrate correctly when their SSR markup appears after client-side navigation.
136
- - React hydration bootstraps are emitted with `data-eco-rerun` and stable `data-eco-script-id` metadata so head-script reconciliation can safely re-execute them when needed.
137
- - This keeps authored DOM shape stable for global layout/style selectors while preserving per-island runtime isolation.
102
+ Not every integration needs queue-based handoff.
138
103
 
139
- ## Output Pipeline (High-Level)
104
+ - If a renderer can resolve a foreign child inline, it returns resolved output immediately.
105
+ - If it cannot, it may emit internal foreign-subtree tokens and resolve them before returning final HTML.
106
+ - The queue service is only for renderer-owned transport inside one render pass. It is not a general route-level fallback mechanism.
140
107
 
141
- 1. Factory selects integration renderer.
142
- 2. Integration renderer prepares render options.
143
- 3. Dependencies are resolved and processed.
144
- 4. Orchestration assets/artifacts are merged.
145
- 5. Integration renderer generates HTML body.
146
- 6. HTML transformer injects head/body dependencies.
147
- 7. Route result returns body + metadata + cache strategy.
108
+ ## React Island Notes
148
109
 
149
- ## Current Limits And Near-Term Work
110
+ - React islands are emitted without synthetic wrapper elements.
111
+ - The React integration attaches `data-eco-component-id` to the SSR root when a single root exists.
112
+ - The island bootstrap mounts with `createRoot()` into that SSR root.
113
+ - Hydration bootstraps listen for `eco:after-swap` so islands hydrate after client-side navigation.
150
114
 
151
- If you are reading this file to understand today's contract, you can stop at the output pipeline above. The items below describe areas still evolving rather than required behavior.
115
+ ## Current Limits
152
116
 
153
- - Deep multi-level mixed-integration trees now rely on renderer-owned boundary runtimes rather than a shared post-render graph resolver.
154
- - Each renderer still decides how to hand off foreign boundaries, so specialized runtimes remain appropriate where child serialization or hydration contracts differ.
155
- - `boundaryPlan` is currently preparation-time metadata and diagnostics. It does not yet drive a full route-composer execution model.
156
- - A narrow `RouteShellComposer` now owns shared shell composition, but a broader route composer that absorbs boundary ownership or execution flow is still deferred.
117
+ - `ownershipPlan` is still diagnostic and preparatory metadata; it does not yet drive a full route-composer execution model.
118
+ - Different integrations still own different foreign-child runtime strategies, which is intentional where child transport or hydration behavior differs.
@@ -0,0 +1,325 @@
1
+ import type { EcoComponent } from '../../types/public-types.ts';
2
+ import { addTriggerAttribute, isThenable, wrapWithScriptsInjector } from './render-output.utils.ts';
3
+
4
+ /**
5
+ * Result returned by a renderer-owned foreign-child runtime.
6
+ *
7
+ * `inline` keeps rendering inside the current integration. `resolved` returns a
8
+ * renderer-owned value immediately, which can be final HTML or a renderer-local
9
+ * transport token for later queue resolution.
10
+ */
11
+ export type ForeignChildInterceptionResult = { kind: 'inline' } | { kind: 'resolved'; value: unknown };
12
+
13
+ /**
14
+ * Foreign-child metadata passed into the active renderer-owned runtime.
15
+ */
16
+ export type ForeignChildInterceptionInput = {
17
+ currentIntegration: string;
18
+ targetIntegration?: string;
19
+ component: EcoComponent;
20
+ props: Record<string, unknown>;
21
+ };
22
+
23
+ /**
24
+ * Narrow renderer-owned foreign-child runtime injected into one active render
25
+ * context.
26
+ *
27
+ * Integrations implement this contract when foreign children must be handed
28
+ * off inside the renderer instead of being left for route-level reconciliation.
29
+ */
30
+ export interface ForeignChildRuntime {
31
+ /**
32
+ * Intercepts one foreign child during an active render.
33
+ *
34
+ * This runtime is typically installed by the Foreign Subtree execution module,
35
+ * which decides whether the child stays inline or leaves the current renderer.
36
+ */
37
+ interceptForeignChild?(
38
+ input: ForeignChildInterceptionInput,
39
+ ): ForeignChildInterceptionResult | Promise<ForeignChildInterceptionResult>;
40
+ interceptForeignChildSync?(input: ForeignChildInterceptionInput): ForeignChildInterceptionResult;
41
+ }
42
+
43
+ type ForeignChildRenderInput = {
44
+ component: EcoComponent;
45
+ props: Record<string, unknown>;
46
+ targetIntegration?: string;
47
+ };
48
+
49
+ /**
50
+ * Shared output finalization behavior used both inside and outside active render contexts.
51
+ *
52
+ * This stage is responsible only for lazy trigger or injector wrapping. Foreign-child
53
+ * interception stays in `ContextualComponentRenderRuntime`.
54
+ */
55
+ class ComponentRenderOutputRuntime {
56
+ finalizeComponentRender<T>(component: EcoComponent, content: T): T {
57
+ const lazyTriggers = component.config?._resolvedLazyTriggers;
58
+ if (lazyTriggers && lazyTriggers.length > 0) {
59
+ return this.addTriggerToContent(content, lazyTriggers[0].triggerId) as T;
60
+ }
61
+
62
+ const lazyGroups = component.config?._resolvedLazyScripts;
63
+ if (lazyGroups && lazyGroups.length > 0) {
64
+ return this.wrapContentWithScriptsInjector(content, lazyGroups) as T;
65
+ }
66
+
67
+ return content;
68
+ }
69
+
70
+ private addTriggerToContent(content: unknown, triggerId: string): unknown {
71
+ if (isThenable(content)) {
72
+ return content.then((resolvedContent) => addTriggerAttribute(resolvedContent, triggerId));
73
+ }
74
+
75
+ return addTriggerAttribute(content, triggerId);
76
+ }
77
+
78
+ private wrapContentWithScriptsInjector(
79
+ content: unknown,
80
+ lazyGroups: NonNullable<EcoComponent['config']>['_resolvedLazyScripts'],
81
+ ): unknown {
82
+ if (isThenable(content)) {
83
+ return content.then((resolvedContent) => wrapWithScriptsInjector(resolvedContent, lazyGroups));
84
+ }
85
+
86
+ return wrapWithScriptsInjector(content, lazyGroups);
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Render-context-aware runtime that delegates foreign-child interception.
92
+ */
93
+ class ContextualComponentRenderRuntime extends ComponentRenderOutputRuntime {
94
+ private readonly context: ComponentRenderContext;
95
+
96
+ constructor(context: ComponentRenderContext) {
97
+ super();
98
+ this.context = context;
99
+ }
100
+
101
+ private applyForeignChildInterceptionResult(result: ForeignChildInterceptionResult): unknown | undefined {
102
+ if (result.kind === 'resolved') {
103
+ return result.value;
104
+ }
105
+
106
+ return undefined;
107
+ }
108
+
109
+ /**
110
+ * Resolves one foreign-child interception through the active runtime.
111
+ *
112
+ * The runtime may choose inline rendering or immediate resolved output.
113
+ */
114
+ interceptForeignChild(input: ForeignChildRenderInput): Promise<unknown | undefined> | unknown | undefined {
115
+ const foreignChildRuntimeInput = {
116
+ currentIntegration: this.context.currentIntegration,
117
+ targetIntegration: input.targetIntegration,
118
+ component: input.component,
119
+ props: input.props,
120
+ } satisfies ForeignChildInterceptionInput;
121
+
122
+ const asyncInterception = this.context.foreignChildRuntime?.interceptForeignChild?.(foreignChildRuntimeInput);
123
+ if (asyncInterception !== undefined) {
124
+ if (isThenable<ForeignChildInterceptionResult>(asyncInterception)) {
125
+ return asyncInterception.then((result) => this.applyForeignChildInterceptionResult(result));
126
+ }
127
+
128
+ return this.applyForeignChildInterceptionResult(asyncInterception);
129
+ }
130
+
131
+ const syncInterception =
132
+ this.context.foreignChildRuntime?.interceptForeignChildSync?.(foreignChildRuntimeInput);
133
+ if (syncInterception === undefined) {
134
+ return undefined;
135
+ }
136
+
137
+ return this.applyForeignChildInterceptionResult(syncInterception);
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Per-render mutable state used while applying foreign-child interception and lazy
143
+ * output wrapping.
144
+ */
145
+ export type ComponentRenderContext = {
146
+ currentIntegration: string;
147
+ foreignChildRuntime?: ForeignChildRuntime;
148
+ interceptForeignChild(input: ForeignChildRenderInput): Promise<unknown | undefined> | unknown | undefined;
149
+ finalizeComponentRender<T>(component: EcoComponent, content: T): T;
150
+ };
151
+
152
+ /**
153
+ * Minimal adapter over async-local storage used by the render-context runtime.
154
+ *
155
+ * Keeping this interface tiny makes the fallback stack implementation and the
156
+ * Node `AsyncLocalStorage` implementation share the same calling code.
157
+ */
158
+ type ContextStorage = {
159
+ getStore(): ComponentRenderContext | undefined;
160
+ run<T>(store: ComponentRenderContext, callback: () => Promise<T>): Promise<T>;
161
+ };
162
+
163
+ /**
164
+ * Process-wide mutable state for component render contexts.
165
+ *
166
+ * Duplicate module instances can exist in development or mixed-runtime flows, so
167
+ * this state is attached to a shared global scope instead of module-local state.
168
+ */
169
+ type ComponentRenderContextState = {
170
+ contextStack: ComponentRenderContext[];
171
+ nodeContextStorage: ContextStorage | null;
172
+ nodeContextStorageLoader: Promise<ContextStorage | null> | null;
173
+ };
174
+
175
+ const GLOBAL_COMPONENT_RENDER_CONTEXT_STATE_KEY = '__ECOPAGES_COMPONENT_RENDER_CONTEXT_STATE__';
176
+
177
+ /**
178
+ * Chooses the widest shared global scope available for process-wide state.
179
+ *
180
+ * `process` is preferred when present so duplicate bundles or module instances in
181
+ * the same runtime still converge on one shared context registry.
182
+ */
183
+ function getSharedContextScope(): Record<string, unknown> {
184
+ const globalProcess = globalThis.process as (NodeJS.Process & Record<string, unknown>) | undefined;
185
+ if (globalProcess && typeof globalProcess === 'object') {
186
+ return globalProcess;
187
+ }
188
+
189
+ return globalThis as Record<string, unknown>;
190
+ }
191
+
192
+ /**
193
+ * Returns the singleton mutable state used by component render contexts.
194
+ */
195
+ function getComponentRenderContextState(): ComponentRenderContextState {
196
+ const sharedScope = getSharedContextScope() as typeof globalThis & {
197
+ __ECOPAGES_COMPONENT_RENDER_CONTEXT_STATE__?: ComponentRenderContextState;
198
+ };
199
+
200
+ sharedScope[GLOBAL_COMPONENT_RENDER_CONTEXT_STATE_KEY] ??= {
201
+ contextStack: [],
202
+ nodeContextStorage: null,
203
+ nodeContextStorageLoader: null,
204
+ };
205
+
206
+ return sharedScope[GLOBAL_COMPONENT_RENDER_CONTEXT_STATE_KEY];
207
+ }
208
+
209
+ /**
210
+ * Lazily initializes async context storage for Node runtimes.
211
+ *
212
+ * Falls back to in-memory stack mode when async_hooks is unavailable.
213
+ *
214
+ * @returns Async context storage when available; otherwise `null`.
215
+ */
216
+ async function getContextStorage(): Promise<ContextStorage | null> {
217
+ const state = getComponentRenderContextState();
218
+
219
+ if (state.nodeContextStorage) {
220
+ return state.nodeContextStorage;
221
+ }
222
+
223
+ if (state.nodeContextStorageLoader) {
224
+ return state.nodeContextStorageLoader;
225
+ }
226
+
227
+ state.nodeContextStorageLoader = import('node:async_hooks')
228
+ .then((module) => {
229
+ const storage = new module.AsyncLocalStorage<ComponentRenderContext>();
230
+ state.nodeContextStorage = {
231
+ getStore: () => storage.getStore(),
232
+ run: (store, callback) => storage.run(store, callback),
233
+ };
234
+ return state.nodeContextStorage;
235
+ })
236
+ .catch(() => {
237
+ state.nodeContextStorage = null;
238
+ return null;
239
+ })
240
+ .finally(() => {
241
+ state.nodeContextStorageLoader = null;
242
+ });
243
+
244
+ return state.nodeContextStorageLoader;
245
+ }
246
+
247
+ /**
248
+ * Returns the current component render context, if one is active.
249
+ *
250
+ * @returns Active render context or `undefined` outside render execution.
251
+ */
252
+ export function getComponentRenderContext(): ComponentRenderContext | undefined {
253
+ const state = getComponentRenderContextState();
254
+ return state.nodeContextStorage?.getStore() ?? state.contextStack[state.contextStack.length - 1];
255
+ }
256
+
257
+ const componentRenderOutputRuntime = new ComponentRenderOutputRuntime();
258
+
259
+ /**
260
+ * Runs foreign-child interception for one component render step.
261
+ *
262
+ * The active runtime may resolve the foreign child immediately or keep it inline.
263
+ */
264
+ export function interceptForeignChild(
265
+ input: ForeignChildRenderInput,
266
+ ): Promise<unknown | undefined> | unknown | undefined {
267
+ return getComponentRenderContext()?.interceptForeignChild(input);
268
+ }
269
+
270
+ /**
271
+ * Applies lazy trigger or injector wrapping to completed component output.
272
+ *
273
+ * This helper works both inside render-context execution and in fallback flows
274
+ * where no active context exists.
275
+ */
276
+ export function finalizeComponentRender<T>(component: EcoComponent, content: T): T {
277
+ const renderContext = getComponentRenderContext();
278
+ return (renderContext?.finalizeComponentRender(component, content) ??
279
+ componentRenderOutputRuntime.finalizeComponentRender(component, content)) as T;
280
+ }
281
+
282
+ /**
283
+ * Runs render work under a fresh component render context and returns the
284
+ * resulting value.
285
+ *
286
+ * @param input Execution metadata for current integration and foreign-child policy.
287
+ * @param render Async render function to execute inside the context.
288
+ * @returns Render result value.
289
+ */
290
+ export async function runWithComponentRenderContext<T>(
291
+ input: {
292
+ currentIntegration: string;
293
+ foreignChildRuntime?: ForeignChildRuntime;
294
+ },
295
+ render: () => Promise<T>,
296
+ ): Promise<{ value: T }> {
297
+ const context = {
298
+ currentIntegration: input.currentIntegration,
299
+ foreignChildRuntime: input.foreignChildRuntime,
300
+ } as ComponentRenderContext;
301
+ const runtime = new ContextualComponentRenderRuntime(context);
302
+ context.interceptForeignChild = (deferredInput: ForeignChildRenderInput) =>
303
+ runtime.interceptForeignChild(deferredInput);
304
+ context.finalizeComponentRender = <TContent>(component: EcoComponent, content: TContent) =>
305
+ runtime.finalizeComponentRender(component, content);
306
+
307
+ const storage = await getContextStorage();
308
+
309
+ let value: T;
310
+ if (storage) {
311
+ value = await storage.run(context, render);
312
+ } else {
313
+ const state = getComponentRenderContextState();
314
+ state.contextStack.push(context);
315
+ try {
316
+ value = await render();
317
+ } finally {
318
+ state.contextStack.pop();
319
+ }
320
+ }
321
+
322
+ return {
323
+ value,
324
+ };
325
+ }
@@ -0,0 +1,62 @@
1
+ import type { EcoComponent, OwnershipPlanNodeSource } from '../../types/public-types.ts';
2
+
3
+ export type DeclaredOwnershipRoot = {
4
+ component: EcoComponent;
5
+ source: Extract<OwnershipPlanNodeSource, 'page' | 'layout' | 'html-template'>;
6
+ };
7
+
8
+ export type DeclaredOwnershipNodeInput = {
9
+ component: EcoComponent;
10
+ source: Exclude<OwnershipPlanNodeSource, 'route'>;
11
+ parentIntegrationName: string;
12
+ integrationName: string;
13
+ componentId: string;
14
+ isForeignToParent: boolean;
15
+ };
16
+
17
+ export function mapDeclaredOwnershipGraph<T>(input: {
18
+ roots: DeclaredOwnershipRoot[];
19
+ currentIntegrationName: string;
20
+ mapNode: (node: DeclaredOwnershipNodeInput, children: T[]) => T;
21
+ }): T[] {
22
+ let nextSyntheticId = 0;
23
+
24
+ const mapComponent = (
25
+ component: EcoComponent,
26
+ source: Exclude<OwnershipPlanNodeSource, 'route'>,
27
+ parentIntegrationName: string,
28
+ lineage: Set<object>,
29
+ ): T => {
30
+ const integrationName =
31
+ component.config?.integration ?? component.config?.__eco?.integration ?? parentIntegrationName;
32
+ const componentMeta = component.config?.__eco;
33
+ const isForeignToParent = integrationName !== parentIntegrationName;
34
+ const componentId = componentMeta?.id ?? componentMeta?.file ?? `${source}:${(nextSyntheticId += 1)}`;
35
+
36
+ const nextLineage = new Set(lineage);
37
+ nextLineage.add(component);
38
+ const children = (component.config?.dependencies?.components ?? []).flatMap((child) => {
39
+ if (!child || nextLineage.has(child)) {
40
+ return [];
41
+ }
42
+
43
+ return [mapComponent(child, 'dependency', integrationName, nextLineage)];
44
+ });
45
+
46
+ return input.mapNode(
47
+ {
48
+ component,
49
+ source,
50
+ parentIntegrationName,
51
+ integrationName,
52
+ componentId,
53
+ isForeignToParent,
54
+ },
55
+ children,
56
+ );
57
+ };
58
+
59
+ return input.roots.map(({ component, source }) =>
60
+ mapComponent(component, source, input.currentIntegrationName, new Set()),
61
+ );
62
+ }