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

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 (433) hide show
  1. package/README.md +38 -9
  2. package/package.json +241 -30
  3. package/src/adapters/README.md +6 -2
  4. package/src/adapters/abstract/application-adapter.d.ts +123 -6
  5. package/src/adapters/abstract/application-adapter.js +151 -1
  6. package/src/adapters/abstract/segment-path-matcher.d.ts +6 -0
  7. package/src/adapters/abstract/segment-path-matcher.js +149 -0
  8. package/src/adapters/abstract/server-adapter.d.ts +16 -2
  9. package/src/adapters/abstract/ws-pattern-matcher.d.ts +12 -0
  10. package/src/adapters/abstract/ws-pattern-matcher.js +30 -0
  11. package/src/adapters/bun/bun-user-websocket-lifecycle.d.ts +22 -0
  12. package/src/adapters/bun/bun-user-websocket-lifecycle.js +96 -0
  13. package/src/adapters/bun/client-bridge.d.ts +1 -0
  14. package/src/adapters/bun/client-bridge.js +3 -0
  15. package/src/adapters/bun/create-app.d.ts +9 -6
  16. package/src/adapters/bun/create-app.js +76 -45
  17. package/src/adapters/bun/hmr-manager.d.ts +1 -1
  18. package/src/adapters/bun/hmr-manager.js +1 -1
  19. package/src/adapters/bun/index.d.ts +1 -1
  20. package/src/adapters/bun/index.js +25 -2
  21. package/src/adapters/bun/runtime-host.d.ts +1 -1
  22. package/src/adapters/bun/runtime-host.js +1 -1
  23. package/src/adapters/bun/server-adapter.d.ts +92 -41
  24. package/src/adapters/bun/server-adapter.js +256 -117
  25. package/src/adapters/bun/static-preview-host.d.ts +1 -1
  26. package/src/adapters/bun/static-preview-host.js +25 -20
  27. package/src/adapters/create-app.d.ts +13 -11
  28. package/src/adapters/create-app.js +2 -51
  29. package/src/adapters/index.d.ts +2 -2
  30. package/src/adapters/index.js +26 -4
  31. package/src/adapters/node/create-app.d.ts +8 -3
  32. package/src/adapters/node/create-app.js +61 -13
  33. package/src/adapters/node/node-client-bridge.d.ts +1 -0
  34. package/src/adapters/node/node-client-bridge.js +3 -0
  35. package/src/adapters/node/node-hmr-manager.d.ts +1 -1
  36. package/src/adapters/node/node-hmr-manager.js +1 -1
  37. package/src/adapters/node/runtime-host.d.ts +1 -1
  38. package/src/adapters/node/runtime-host.js +1 -1
  39. package/src/adapters/node/server-adapter-dependencies.js +4 -0
  40. package/src/adapters/node/server-adapter.d.ts +64 -23
  41. package/src/adapters/node/server-adapter.js +169 -142
  42. package/src/adapters/node/static-content-server.d.ts +1 -0
  43. package/src/adapters/node/static-content-server.js +10 -2
  44. package/src/adapters/node/static-preview-host.d.ts +1 -1
  45. package/src/adapters/node/static-preview-host.js +27 -12
  46. package/src/adapters/shared/{hmr-entrypoint-registrar.d.ts → hmr/hmr-entrypoint-registrar.d.ts} +31 -30
  47. package/src/adapters/shared/hmr/hmr-entrypoint-registrar.js +106 -0
  48. package/src/adapters/shared/{hmr-html-response.d.ts → hmr/hmr-html-response.d.ts} +2 -2
  49. package/src/adapters/shared/{hmr-html-response.js → hmr/hmr-html-response.js} +4 -1
  50. package/src/adapters/shared/hmr/shared-hmr-manager.d.ts +101 -0
  51. package/src/adapters/shared/hmr/shared-hmr-manager.js +432 -0
  52. package/src/adapters/shared/http/api-request-pipeline.d.ts +23 -0
  53. package/src/adapters/shared/http/api-request-pipeline.js +129 -0
  54. package/src/adapters/shared/{api-response.d.ts → http/api-response.d.ts} +1 -1
  55. package/src/adapters/shared/{api-response.js → http/api-response.js} +6 -23
  56. package/src/adapters/shared/http/create-body-response.d.ts +12 -0
  57. package/src/adapters/shared/http/create-body-response.js +23 -0
  58. package/src/adapters/shared/http/define-api-handler.d.ts +90 -0
  59. package/src/adapters/shared/http/define-api-handler.js +63 -0
  60. package/src/adapters/shared/{explicit-static-render-preparation.d.ts → http/explicit-static-render-preparation.d.ts} +3 -3
  61. package/src/adapters/shared/{explicit-static-route-matcher.d.ts → http/explicit-static-route-matcher.d.ts} +3 -9
  62. package/src/adapters/shared/{explicit-static-route-matcher.js → http/explicit-static-route-matcher.js} +3 -38
  63. package/src/adapters/shared/{file-route-middleware-pipeline.d.ts → http/file-route-middleware-pipeline.d.ts} +2 -2
  64. package/src/adapters/shared/{file-route-middleware-pipeline.js → http/file-route-middleware-pipeline.js} +10 -22
  65. package/src/adapters/shared/{fs-server-response-factory.d.ts → http/fs-server-response-factory.d.ts} +7 -2
  66. package/src/adapters/shared/{fs-server-response-factory.js → http/fs-server-response-factory.js} +22 -2
  67. package/src/adapters/shared/{fs-server-response-matcher.d.ts → http/fs-server-response-matcher.d.ts} +25 -5
  68. package/src/adapters/shared/{fs-server-response-matcher.js → http/fs-server-response-matcher.js} +109 -27
  69. package/src/adapters/shared/http/run-middleware-chain.d.ts +5 -0
  70. package/src/adapters/shared/http/run-middleware-chain.js +17 -0
  71. package/src/adapters/shared/{application-adapter.d.ts → runtime/application-adapter.d.ts} +2 -2
  72. package/src/adapters/shared/{application-adapter.js → runtime/application-adapter.js} +1 -1
  73. package/src/adapters/shared/runtime/copy-runtime-public-dir.d.ts +6 -0
  74. package/src/adapters/shared/runtime/copy-runtime-public-dir.js +24 -0
  75. package/src/adapters/shared/runtime/port-manager.d.ts +116 -0
  76. package/src/adapters/shared/runtime/port-manager.js +196 -0
  77. package/src/adapters/shared/{render-context.d.ts → runtime/render-context.d.ts} +2 -2
  78. package/src/adapters/shared/{render-context.js → runtime/render-context.js} +8 -17
  79. package/src/adapters/shared/{runtime-app-bootstrap.d.ts → runtime/runtime-app-bootstrap.d.ts} +4 -3
  80. package/src/adapters/shared/{runtime-app-bootstrap.js → runtime/runtime-app-bootstrap.js} +4 -7
  81. package/src/adapters/shared/runtime/runtime-server-lifecycle.d.ts +46 -0
  82. package/src/adapters/shared/runtime/runtime-server-lifecycle.js +57 -0
  83. package/src/adapters/shared/{server-adapter.d.ts → runtime/server-adapter.d.ts} +23 -49
  84. package/src/adapters/shared/runtime/server-adapter.js +226 -0
  85. package/src/adapters/shared/{server-route-handler.d.ts → runtime/server-route-handler.d.ts} +6 -33
  86. package/src/adapters/shared/{server-route-handler.js → runtime/server-route-handler.js} +5 -43
  87. package/src/adapters/shared/{server-static-builder.d.ts → runtime/server-static-builder.d.ts} +27 -35
  88. package/src/adapters/shared/runtime/server-static-builder.js +191 -0
  89. package/src/adapters/shared/{static-preview-host.d.ts → runtime/static-preview-host.d.ts} +6 -1
  90. package/src/adapters/shared/ws/node-http-websocket-upgrades.d.ts +21 -0
  91. package/src/adapters/shared/ws/node-http-websocket-upgrades.js +100 -0
  92. package/src/adapters/shared/ws/websocket-lifecycle.d.ts +24 -0
  93. package/src/adapters/shared/ws/websocket-lifecycle.js +55 -0
  94. package/src/build/README.md +140 -31
  95. package/src/build/app-build-manifest-runtime.d.ts +39 -0
  96. package/src/build/app-build-manifest-runtime.js +124 -0
  97. package/src/build/{browser-runtime-plugin.d.ts → browser/browser-runtime-plugin.d.ts} +1 -1
  98. package/src/build/{browser-runtime-plugin.js → browser/browser-runtime-plugin.js} +1 -1
  99. package/src/build/browser/jsx-ownership-plugins.d.ts +24 -0
  100. package/src/build/browser/jsx-ownership-plugins.js +41 -0
  101. package/src/build/browser/lit-static-render-worker-context.d.ts +2 -0
  102. package/src/build/browser/lit-static-render-worker-context.js +6 -0
  103. package/src/build/build-adapter.d.ts +29 -334
  104. package/src/build/build-adapter.js +32 -133
  105. package/src/build/cache/build-input-fingerprint.d.ts +28 -0
  106. package/src/build/cache/build-input-fingerprint.js +31 -0
  107. package/src/build/cache/cache-constants.d.ts +4 -0
  108. package/src/build/cache/cache-constants.js +6 -0
  109. package/src/build/cache/cache-keys.d.ts +22 -0
  110. package/src/build/cache/cache-keys.js +63 -0
  111. package/src/build/cache/dev-browser-script-cache.d.ts +34 -0
  112. package/src/build/cache/dev-browser-script-cache.js +90 -0
  113. package/src/build/cache/pages-unified-graph-build.d.ts +31 -0
  114. package/src/build/cache/pages-unified-graph-build.js +198 -0
  115. package/src/build/cache/production-build-cache.d.ts +20 -0
  116. package/src/build/cache/production-build-cache.js +63 -0
  117. package/src/build/cache/server-entry-build-cache.d.ts +43 -0
  118. package/src/build/cache/server-entry-build-cache.js +165 -0
  119. package/src/build/contracts/build-contracts.d.ts +96 -0
  120. package/src/build/contracts/build-manifest.d.ts +90 -0
  121. package/src/build/{build-manifest.js → contracts/build-manifest.js} +2 -2
  122. package/src/build/contracts/build-types.js +0 -0
  123. package/src/build/{rolldown-adapter-helpers.d.ts → rolldown/rolldown-adapter-helpers.d.ts} +23 -9
  124. package/src/build/{rolldown-adapter-helpers.js → rolldown/rolldown-adapter-helpers.js} +99 -13
  125. package/src/build/{rolldown-build-adapter.d.ts → rolldown/rolldown-build-adapter.d.ts} +3 -7
  126. package/src/build/{rolldown-build-adapter.js → rolldown/rolldown-build-adapter.js} +3 -3
  127. package/src/build/rolldown/rolldown-build-invocation-metrics.d.ts +12 -0
  128. package/src/build/rolldown/rolldown-build-invocation-metrics.js +43 -0
  129. package/src/build/{rolldown-plugin-bridge.d.ts → rolldown/rolldown-plugin-bridge.d.ts} +16 -2
  130. package/src/build/{rolldown-plugin-bridge.js → rolldown/rolldown-plugin-bridge.js} +21 -6
  131. package/src/build/rolldown/rolldown-source-transform-pass.d.ts +15 -0
  132. package/src/build/rolldown/rolldown-source-transform-pass.js +61 -0
  133. package/src/build/rolldown/runtime-build-output-normalizer.d.ts +10 -0
  134. package/src/build/rolldown/runtime-build-output-normalizer.js +201 -0
  135. package/src/build/runtime/build-profile-options.d.ts +7 -0
  136. package/src/build/runtime/build-profile-options.js +37 -0
  137. package/src/build/runtime/build-request-identity.d.ts +17 -0
  138. package/src/build/runtime/build-request-identity.js +54 -0
  139. package/src/build/runtime/build-request-policy.d.ts +59 -0
  140. package/src/build/runtime/build-request-policy.js +46 -0
  141. package/src/build/runtime/build-runtime.d.ts +28 -0
  142. package/src/build/runtime/build-runtime.js +65 -0
  143. package/src/build/runtime/deduping-build-executor.d.ts +21 -0
  144. package/src/build/runtime/deduping-build-executor.js +34 -0
  145. package/src/build/runtime/parallel-build-executor.d.ts +21 -0
  146. package/src/build/runtime/parallel-build-executor.js +52 -0
  147. package/src/build/{serialized-build-executor.d.ts → runtime/serialized-build-executor.d.ts} +1 -1
  148. package/src/client/navigation-scripts/classification.d.ts +16 -0
  149. package/src/client/navigation-scripts/classification.js +41 -0
  150. package/src/client/navigation-scripts/index.d.ts +3 -0
  151. package/src/client/navigation-scripts/index.js +23 -0
  152. package/src/client/navigation-scripts/navigation-scripts.test.browser.js +65 -0
  153. package/src/client/navigation-scripts/registry.d.ts +11 -0
  154. package/src/client/navigation-scripts/registry.js +12 -0
  155. package/src/client/navigation-scripts/rerun-queue.d.ts +37 -0
  156. package/src/client/navigation-scripts/rerun-queue.js +73 -0
  157. package/src/client/scroll.d.ts +17 -0
  158. package/src/client/scroll.js +25 -0
  159. package/src/client/scroll.test.browser.js +37 -0
  160. package/src/client/view-transitions.d.ts +16 -0
  161. package/src/client/view-transitions.js +63 -0
  162. package/src/config/config-builder.d.ts +25 -10
  163. package/src/config/config-builder.js +53 -11
  164. package/src/config/constants.d.ts +1 -0
  165. package/src/config/constants.js +2 -1
  166. package/src/dev/client-bridge-registry.d.ts +5 -0
  167. package/src/dev/client-bridge-registry.js +15 -0
  168. package/src/dev/dev-client-ownership.d.ts +7 -0
  169. package/src/dev/dev-client-ownership.js +6 -0
  170. package/src/dev/hmr-manager-registry.d.ts +8 -0
  171. package/src/dev/hmr-manager-registry.js +15 -0
  172. package/src/dev/host-runtime.d.ts +3 -0
  173. package/src/dev/host-runtime.js +7 -0
  174. package/src/dev/runtime-server-started-message.d.ts +2 -0
  175. package/src/dev/runtime-server-started-message.js +6 -0
  176. package/src/diagnostics/request-build-dedupe.d.ts +18 -0
  177. package/src/diagnostics/request-build-dedupe.js +33 -0
  178. package/src/diagnostics/startup-trace.d.ts +72 -0
  179. package/src/diagnostics/startup-trace.js +253 -0
  180. package/src/eco/README.md +11 -0
  181. package/src/eco/eco-declared-component.d.ts +14 -0
  182. package/src/eco/eco-declared-component.js +16 -0
  183. package/src/eco/eco.browser.js +5 -6
  184. package/src/eco/eco.js +7 -8
  185. package/src/eco/eco.types.d.ts +14 -3
  186. package/src/eco/eco.utils.d.ts +1 -1
  187. package/src/eco/eco.utils.js +1 -1
  188. package/src/eco/page-layout-normalization.d.ts +21 -0
  189. package/src/eco/page-layout-normalization.js +59 -0
  190. package/src/env.d.ts +2 -0
  191. package/src/errors/index.d.ts +1 -0
  192. package/src/errors/index.js +7 -1
  193. package/src/errors/undeclared-component-dependency-error.d.ts +11 -0
  194. package/src/errors/undeclared-component-dependency-error.js +17 -0
  195. package/src/hmr/client/hmr-runtime.js +7 -4
  196. package/src/hmr/hmr-entrypoint-output.d.ts +49 -0
  197. package/src/hmr/hmr-entrypoint-output.js +60 -0
  198. package/src/hmr/hmr-file-change-prep.d.ts +10 -0
  199. package/src/hmr/hmr-file-change-prep.js +17 -0
  200. package/src/hmr/hmr-strategy.d.ts +15 -0
  201. package/src/hmr/hmr-strategy.js +19 -0
  202. package/src/hmr/strategies/js-hmr-strategy.d.ts +3 -5
  203. package/src/hmr/strategies/js-hmr-strategy.js +72 -19
  204. package/src/hmr/strategies/server-rendered-template-hmr-strategy.d.ts +17 -0
  205. package/src/hmr/strategies/server-rendered-template-hmr-strategy.js +29 -0
  206. package/src/index.d.ts +2 -1
  207. package/src/index.js +28 -2
  208. package/src/integrations/ghtml/ghtml-renderer.d.ts +2 -6
  209. package/src/integrations/ghtml/ghtml-renderer.js +2 -51
  210. package/src/integrations/ghtml/ghtml.plugin.d.ts +3 -16
  211. package/src/integrations/ghtml/ghtml.plugin.js +7 -14
  212. package/src/plugins/alias-resolver-cache.d.ts +6 -9
  213. package/src/plugins/alias-resolver-plugin.d.ts +3 -3
  214. package/src/plugins/alias-resolver-plugin.js +38 -51
  215. package/src/plugins/define-integration.d.ts +26 -0
  216. package/src/plugins/define-integration.js +19 -0
  217. package/src/plugins/eco-component-meta-plugin.d.ts +1 -1
  218. package/src/plugins/eco-component-meta-plugin.js +5 -8
  219. package/src/plugins/foreign-jsx-override-plugin.d.ts +1 -1
  220. package/src/plugins/foreign-jsx-override-plugin.js +4 -6
  221. package/src/plugins/integration-plugin.d.ts +43 -14
  222. package/src/plugins/integration-plugin.js +18 -5
  223. package/src/plugins/jsx-import-source.utils.d.ts +8 -0
  224. package/src/plugins/jsx-import-source.utils.js +26 -0
  225. package/src/plugins/processor.d.ts +61 -12
  226. package/src/plugins/processor.js +24 -5
  227. package/src/plugins/source-transform.d.ts +32 -1
  228. package/src/plugins/source-transform.js +23 -1
  229. package/src/plugins/tsconfig-import-resolver.d.ts +18 -0
  230. package/src/plugins/tsconfig-import-resolver.js +159 -0
  231. package/src/route-renderer/GRAPH.md +26 -32
  232. package/src/route-renderer/README.md +38 -31
  233. package/src/route-renderer/orchestration/document-shell/document-shell-render.service.d.ts +107 -0
  234. package/src/route-renderer/orchestration/document-shell/document-shell-render.service.js +148 -0
  235. package/src/route-renderer/orchestration/document-shell/layout-shell-props.service.d.ts +20 -0
  236. package/src/route-renderer/orchestration/document-shell/layout-shell-props.service.js +31 -0
  237. package/src/route-renderer/orchestration/{component-render-context.d.ts → foreign-child/component-render-context.d.ts} +8 -15
  238. package/src/route-renderer/orchestration/{component-render-context.js → foreign-child/component-render-context.js} +4 -2
  239. package/src/route-renderer/orchestration/{render-output.utils.d.ts → foreign-child/foreign-child-output.utils.d.ts} +17 -7
  240. package/src/route-renderer/orchestration/{render-output.utils.js → foreign-child/foreign-child-output.utils.js} +35 -26
  241. package/src/route-renderer/orchestration/{foreign-subtree-execution.service.d.ts → foreign-child/foreign-subtree-execution.service.d.ts} +64 -34
  242. package/src/route-renderer/orchestration/{foreign-subtree-execution.service.js → foreign-child/foreign-subtree-execution.service.js} +170 -37
  243. package/src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.d.ts +19 -0
  244. package/src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.js +35 -0
  245. package/src/route-renderer/orchestration/integration-renderer.d.ts +24 -143
  246. package/src/route-renderer/orchestration/integration-renderer.js +163 -402
  247. package/src/route-renderer/orchestration/integration-renderer.test-fixtures.d.ts +75 -0
  248. package/src/route-renderer/orchestration/integration-renderer.test-fixtures.js +177 -0
  249. package/src/route-renderer/orchestration/ownership-graph/component-graph-collectors.d.ts +10 -0
  250. package/src/route-renderer/orchestration/ownership-graph/component-graph-collectors.js +143 -0
  251. package/src/route-renderer/orchestration/ownership-graph/component-graph.d.ts +34 -0
  252. package/src/route-renderer/orchestration/ownership-graph/component-graph.js +96 -0
  253. package/src/route-renderer/orchestration/{ownership-validation.service.d.ts → ownership-graph/ownership-validation.service.d.ts} +7 -2
  254. package/src/route-renderer/orchestration/{ownership-validation.service.js → ownership-graph/ownership-validation.service.js} +30 -3
  255. package/src/route-renderer/orchestration/page-browser-graph/global-injector-assets.service.d.ts +7 -0
  256. package/src/route-renderer/orchestration/page-browser-graph/global-injector-assets.service.js +32 -0
  257. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-contribution.loader.d.ts +9 -0
  258. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-contribution.loader.js +7 -0
  259. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.d.ts +12 -0
  260. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.js +29 -0
  261. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-session.d.ts +106 -0
  262. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-session.js +436 -0
  263. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph.service.d.ts +31 -0
  264. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph.service.js +229 -0
  265. package/src/route-renderer/orchestration/{processed-asset-dedupe.d.ts → page-browser-graph/processed-asset-dedupe.d.ts} +1 -1
  266. package/src/route-renderer/orchestration/route-pipeline/integration-route-render-adapter.d.ts +31 -0
  267. package/src/route-renderer/orchestration/route-pipeline/integration-route-render-adapter.js +25 -0
  268. package/src/route-renderer/orchestration/route-pipeline/marker-artifact.utils.d.ts +6 -0
  269. package/src/route-renderer/orchestration/route-pipeline/marker-artifact.utils.js +27 -0
  270. package/src/route-renderer/orchestration/route-pipeline/robots-meta.contribution.d.ts +15 -0
  271. package/src/route-renderer/orchestration/route-pipeline/robots-meta.contribution.js +36 -0
  272. package/src/route-renderer/orchestration/route-pipeline/route-html-finalization.service.d.ts +20 -0
  273. package/src/route-renderer/orchestration/route-pipeline/route-html-finalization.service.js +24 -0
  274. package/src/route-renderer/orchestration/route-pipeline/route-prepared-options.builder.d.ts +25 -0
  275. package/src/route-renderer/orchestration/route-pipeline/route-prepared-options.builder.js +49 -0
  276. package/src/route-renderer/orchestration/route-pipeline/route-prepared-options.utils.d.ts +4 -0
  277. package/src/route-renderer/orchestration/route-pipeline/route-prepared-options.utils.js +33 -0
  278. package/src/route-renderer/orchestration/{route-render-orchestrator.d.ts → route-pipeline/route-render-orchestrator.d.ts} +13 -53
  279. package/src/route-renderer/orchestration/route-pipeline/route-render-orchestrator.js +162 -0
  280. package/src/route-renderer/orchestration/string-markup-renderer.d.ts +14 -0
  281. package/src/route-renderer/orchestration/string-markup-renderer.js +55 -0
  282. package/src/route-renderer/page-loading/component-dependency-collection.js +5 -2
  283. package/src/route-renderer/page-loading/ecopages-virtual-imports.d.ts +6 -0
  284. package/src/route-renderer/page-loading/ecopages-virtual-imports.js +7 -2
  285. package/src/route-renderer/page-loading/module-declaration-aggregation.js +4 -0
  286. package/src/router/client/link-intent.d.ts +11 -21
  287. package/src/router/client/link-intent.js +10 -0
  288. package/src/router/client/link-intent.test.browser.js +12 -1
  289. package/src/router/client/link-navigation-policy.d.ts +45 -0
  290. package/src/router/client/link-navigation-policy.js +101 -0
  291. package/src/router/client/link-navigation-policy.test.browser.d.ts +1 -0
  292. package/src/router/client/link-navigation-policy.test.browser.js +92 -0
  293. package/src/router/client/navigation-coordinator.d.ts +1 -1
  294. package/src/router/client/navigation-coordinator.js +12 -2
  295. package/src/services/assets/asset-processing-service/asset-dependency-keys.d.ts +13 -0
  296. package/src/services/assets/asset-processing-service/asset-dependency-keys.js +3 -0
  297. package/src/services/assets/asset-processing-service/asset-processing.service.d.ts +6 -1
  298. package/src/services/assets/asset-processing-service/asset-processing.service.js +44 -5
  299. package/src/services/assets/asset-processing-service/assets.types.d.ts +1 -1
  300. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.d.ts +2 -1
  301. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +1 -0
  302. package/src/services/assets/asset-processing-service/browser-runtime-entry-resolution.d.ts +52 -0
  303. package/src/services/assets/asset-processing-service/browser-runtime-entry-resolution.js +78 -0
  304. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.d.ts +4 -2
  305. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.js +28 -13
  306. package/src/services/assets/asset-processing-service/finalize-processed-asset.d.ts +3 -0
  307. package/src/services/assets/asset-processing-service/finalize-processed-asset.js +7 -0
  308. package/src/services/assets/asset-processing-service/grouped-content-bundles.d.ts +2 -1
  309. package/src/services/assets/asset-processing-service/grouped-content-bundles.js +38 -12
  310. package/src/services/assets/asset-processing-service/index.d.ts +2 -0
  311. package/src/services/assets/asset-processing-service/index.js +2 -0
  312. package/src/services/assets/asset-processing-service/inline-content-script-body.d.ts +11 -0
  313. package/src/services/assets/asset-processing-service/inline-content-script-body.js +17 -0
  314. package/src/services/assets/asset-processing-service/materialize-content-script-asset.d.ts +9 -0
  315. package/src/services/assets/asset-processing-service/materialize-content-script-asset.js +18 -0
  316. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.d.ts +0 -2
  317. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.js +2 -15
  318. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.d.ts +8 -0
  319. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.js +73 -68
  320. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.d.ts +0 -1
  321. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +18 -15
  322. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +17 -3
  323. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.d.ts +0 -3
  324. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +2 -31
  325. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.d.ts +0 -3
  326. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +2 -30
  327. package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.d.ts +2 -0
  328. package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.js +43 -0
  329. package/src/services/assets/asset-processing-service/resolve-integration-plugin.d.ts +4 -0
  330. package/src/services/assets/asset-processing-service/resolve-integration-plugin.js +17 -0
  331. package/src/services/assets/asset-processing-service/ungrouped-dependency-processing.d.ts +0 -1
  332. package/src/services/assets/asset-processing-service/ungrouped-dependency-processing.js +5 -10
  333. package/src/services/assets/browser-bundle.service.d.ts +28 -30
  334. package/src/services/assets/browser-bundle.service.js +28 -19
  335. package/src/services/html/html-transformer.service.d.ts +1 -1
  336. package/src/services/html/html-transformer.service.js +5 -5
  337. package/src/services/invalidation/development-invalidation.service.d.ts +25 -2
  338. package/src/services/invalidation/development-invalidation.service.js +64 -11
  339. package/src/services/module-loading/README.md +49 -0
  340. package/src/services/module-loading/app-server-module-transpiler.service.d.ts +8 -0
  341. package/src/services/module-loading/app-server-module-transpiler.service.js +3 -21
  342. package/src/services/module-loading/page-module-import.service.d.ts +6 -2
  343. package/src/services/module-loading/page-module-import.service.js +110 -47
  344. package/src/services/module-loading/route-module-build-cache-registry.d.ts +24 -0
  345. package/src/services/module-loading/route-module-build-cache-registry.js +37 -0
  346. package/src/services/module-loading/route-module-build-cache.d.ts +4 -0
  347. package/src/services/module-loading/route-module-build-cache.js +38 -0
  348. package/src/services/module-loading/route-module-build-cache.store.d.ts +57 -0
  349. package/src/services/module-loading/route-module-build-cache.store.js +207 -0
  350. package/src/services/module-loading/route-module-build-manifest.d.ts +54 -0
  351. package/src/services/module-loading/route-module-build-manifest.js +85 -0
  352. package/src/services/module-loading/route-module-dependency-hasher.d.ts +81 -0
  353. package/src/services/module-loading/route-module-dependency-hasher.js +122 -0
  354. package/src/services/module-loading/server-module-transpiler.service.d.ts +1 -1
  355. package/src/services/module-loading/server-module-transpiler.service.js +1 -1
  356. package/src/services/validation/schema-validation-service.d.ts +1 -4
  357. package/src/services/validation/schema-validation-service.js +12 -13
  358. package/src/services/validation/standard-schema.types.d.ts +9 -62
  359. package/src/services/validation/validate-standard-schema.d.ts +7 -0
  360. package/src/services/validation/validate-standard-schema.js +14 -0
  361. package/src/static-site-generator/README.md +41 -0
  362. package/src/static-site-generator/production-page-browser-graph-prebuild.d.ts +28 -0
  363. package/src/static-site-generator/production-page-browser-graph-prebuild.js +22 -0
  364. package/src/static-site-generator/sitemap-routes.d.ts +14 -0
  365. package/src/static-site-generator/sitemap-routes.js +31 -0
  366. package/src/static-site-generator/sitemap.d.ts +15 -0
  367. package/src/static-site-generator/sitemap.js +33 -0
  368. package/src/static-site-generator/static-build-invalidation.d.ts +10 -0
  369. package/src/static-site-generator/static-build-invalidation.js +59 -0
  370. package/src/static-site-generator/static-export-context.d.ts +30 -0
  371. package/src/static-site-generator/static-export-context.js +0 -0
  372. package/src/static-site-generator/static-site-generator.d.ts +43 -25
  373. package/src/static-site-generator/static-site-generator.js +381 -106
  374. package/src/types/internal-types.d.ts +39 -13
  375. package/src/types/public-types.d.ts +289 -52
  376. package/src/utils/ecopages-route-info.d.ts +26 -0
  377. package/src/utils/ecopages-route-info.js +26 -0
  378. package/src/utils/html-escaping.d.ts +7 -0
  379. package/src/utils/html-escaping.js +5 -1
  380. package/src/utils/parse-cli-args.d.ts +2 -0
  381. package/src/utils/parse-cli-args.js +6 -0
  382. package/src/utils/path-pattern.d.ts +23 -0
  383. package/src/utils/path-pattern.js +27 -0
  384. package/src/utils/server-utils.module.d.ts +3 -2
  385. package/src/utils/server-utils.module.js +5 -6
  386. package/src/utils/static-file-extensions.d.ts +12 -0
  387. package/src/utils/static-file-extensions.js +48 -0
  388. package/src/watchers/project-watcher-ignore.d.ts +11 -0
  389. package/src/watchers/project-watcher-ignore.js +16 -0
  390. package/src/watchers/project-watcher.d.ts +29 -6
  391. package/src/watchers/project-watcher.js +146 -34
  392. package/src/watchers/project-watcher.test-helpers.js +5 -5
  393. package/src/adapters/shared/define-api-handler.d.ts +0 -25
  394. package/src/adapters/shared/define-api-handler.js +0 -15
  395. package/src/adapters/shared/hmr-entrypoint-registrar.js +0 -87
  396. package/src/adapters/shared/server-adapter.js +0 -436
  397. package/src/adapters/shared/server-static-builder.js +0 -162
  398. package/src/adapters/shared/shared-hmr-manager.d.ts +0 -59
  399. package/src/adapters/shared/shared-hmr-manager.js +0 -241
  400. package/src/build/build-manifest.d.ts +0 -33
  401. package/src/build/rolldown-dev-build-adapter.d.ts +0 -82
  402. package/src/build/rolldown-dev-build-adapter.js +0 -166
  403. package/src/build/runtime-build-executor.d.ts +0 -21
  404. package/src/build/runtime-build-executor.js +0 -19
  405. package/src/build/runtime-build-output-normalizer.d.ts +0 -3
  406. package/src/build/runtime-build-output-normalizer.js +0 -111
  407. package/src/hmr/hmr.postcss.test.e2e.js +0 -31
  408. package/src/hmr/hmr.test.e2e.js +0 -43
  409. package/src/route-renderer/orchestration/declared-ownership-graph.d.ts +0 -18
  410. package/src/route-renderer/orchestration/declared-ownership-graph.js +0 -34
  411. package/src/route-renderer/orchestration/ownership-planning.service.d.ts +0 -24
  412. package/src/route-renderer/orchestration/ownership-planning.service.js +0 -63
  413. package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.d.ts +0 -91
  414. package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.js +0 -170
  415. package/src/route-renderer/orchestration/route-render-orchestrator.js +0 -577
  416. package/src/route-renderer/orchestration/template-serialization.d.ts +0 -38
  417. package/src/route-renderer/orchestration/template-serialization.js +0 -45
  418. /package/src/adapters/shared/{explicit-static-render-preparation.js → http/explicit-static-render-preparation.js} +0 -0
  419. /package/src/adapters/shared/{runtime-host.d.ts → runtime/runtime-host.d.ts} +0 -0
  420. /package/src/adapters/shared/{runtime-host.js → runtime/runtime-host.js} +0 -0
  421. /package/src/adapters/shared/{static-preview-host.js → runtime/static-preview-host.js} +0 -0
  422. /package/src/build/{browser-runtime-manifest.d.ts → browser/browser-runtime-manifest.d.ts} +0 -0
  423. /package/src/build/{browser-runtime-manifest.js → browser/browser-runtime-manifest.js} +0 -0
  424. /package/src/build/{browser-runtime-plugin-helpers.d.ts → browser/browser-runtime-plugin-helpers.d.ts} +0 -0
  425. /package/src/build/{browser-runtime-plugin-helpers.js → browser/browser-runtime-plugin-helpers.js} +0 -0
  426. /package/src/build/{build-types.js → contracts/build-contracts.js} +0 -0
  427. /package/src/build/{build-types.d.ts → contracts/build-types.d.ts} +0 -0
  428. /package/src/build/{server-side-css-shim-plugin.d.ts → rolldown/server-side-css-shim-plugin.d.ts} +0 -0
  429. /package/src/build/{server-side-css-shim-plugin.js → rolldown/server-side-css-shim-plugin.js} +0 -0
  430. /package/src/build/{serialized-build-executor.js → runtime/serialized-build-executor.js} +0 -0
  431. /package/src/{hmr/hmr.postcss.test.e2e.d.ts → client/navigation-scripts/navigation-scripts.test.browser.d.ts} +0 -0
  432. /package/src/{hmr/hmr.test.e2e.d.ts → client/scroll.test.browser.d.ts} +0 -0
  433. /package/src/route-renderer/orchestration/{processed-asset-dedupe.js → page-browser-graph/processed-asset-dedupe.js} +0 -0
@@ -1,23 +1,26 @@
1
- import { createServer } from "node:http";
1
+ import {} from "node:http";
2
2
  import path from "node:path";
3
3
  import { fileSystem } from "@ecopages/file-system";
4
- import { getAppBrowserBuildPlugins, setupAppRuntimePlugins } from "../../build/build-adapter.js";
5
- import { installAppRuntimeBuildExecutor } from "../../build/runtime-build-executor.js";
6
- import { RESOLVED_ASSETS_DIR } from "../../config/constants.js";
4
+ import { setupAppRuntimePlugins } from "../../build/build-adapter.js";
5
+ import { installBuildRuntime } from "../../build/runtime/build-runtime.js";
7
6
  import { appLogger } from "../../global/app-logger.js";
8
7
  import { NodeClientBridge } from "./node-client-bridge.js";
9
8
  import { NodeHmrManager } from "./node-hmr-manager.js";
10
9
  import { ProjectWatcher } from "../../watchers/project-watcher.js";
10
+ import {
11
+ attachNodeHttpWebSocketUpgrades
12
+ } from "../shared/ws/node-http-websocket-upgrades.js";
11
13
  import { StaticSiteGenerator } from "../../static-site-generator/static-site-generator.js";
12
- import { SharedServerAdapter } from "../shared/server-adapter.js";
13
- import { ServerStaticBuilder } from "../shared/server-static-builder.js";
14
+ import { SharedServerAdapter } from "../shared/runtime/server-adapter.js";
15
+ import { ServerStaticBuilder } from "../shared/runtime/server-static-builder.js";
14
16
  import { DEFAULT_ECOPAGES_HOSTNAME, DEFAULT_ECOPAGES_PORT } from "../../config/constants.js";
15
17
  import {
16
- injectHmrRuntimeIntoHtmlResponse,
17
- isHtmlResponse,
18
- shouldInjectHmrHtmlResponse
19
- } from "../shared/hmr-html-response.js";
20
- import { resolveServeRuntimeOrigin } from "../shared/runtime-app-bootstrap.js";
18
+ attachHmrToIntegrations,
19
+ disposeDevResources,
20
+ prepareRuntimePublicDir,
21
+ startConfiguredIntegrationRuntimePrewarm
22
+ } from "../shared/runtime/runtime-server-lifecycle.js";
23
+ import { resolveServeRuntimeOrigin } from "../shared/runtime/runtime-app-bootstrap.js";
21
24
  import { NodeClientAbortError, NodeHttpRequestBridge } from "./http-request-bridge.js";
22
25
  import { NodeStaticPreviewHost } from "./static-preview-host.js";
23
26
  import { DefaultNodeServerDevRuntimeFactory } from "./server-adapter-dependencies.js";
@@ -29,29 +32,66 @@ class NodeServerAdapter extends SharedServerAdapter {
29
32
  errorHandler;
30
33
  bridge = null;
31
34
  hmrManager = null;
35
+ projectWatcher = null;
36
+ adapterDisposed = false;
37
+ deferRuntimeAssetSetup;
38
+ allowPortFallback;
32
39
  previewHost;
33
40
  requestBridge;
34
41
  devRuntimeFactory;
35
- shouldInjectHmrScript() {
36
- return shouldInjectHmrHtmlResponse(this.options?.watch === true, this.hmrManager ?? void 0);
37
- }
38
- isHtmlResponse(response) {
39
- return isHtmlResponse(response);
42
+ /**
43
+ * Reference to the application-level WebSocket handlers map.
44
+ *
45
+ * @remarks
46
+ * This is a reference to the map owned by `AbstractApplicationAdapter`,
47
+ * passed in via the constructor. The Node adapter reads from it to wire
48
+ * WebSocket upgrades for user-registered patterns.
49
+ */
50
+ websocketHandlers = /* @__PURE__ */ new Map();
51
+ /**
52
+ * Wires user WebSocket routes onto a foreign Node HTTP server.
53
+ *
54
+ * Host integrations such as the Vite plugin call this so `app.websocket()`
55
+ * handlers work while HTTP is still served by the host dev server.
56
+ */
57
+ attachUserWebSocketUpgrades(server, options) {
58
+ attachNodeHttpWebSocketUpgrades(server, {
59
+ runtimeOrigin: this.runtimeOrigin,
60
+ websocketHandlers: this.websocketHandlers,
61
+ passthroughUnmatched: options?.passthroughUnmatched
62
+ });
40
63
  }
41
- async maybeInjectHmrScript(response) {
42
- if (this.shouldInjectHmrScript() && this.isHtmlResponse(response)) {
43
- return injectHmrRuntimeIntoHtmlResponse(response);
44
- }
45
- return response;
64
+ wireUserWebSocketUpgrades(server, preflight) {
65
+ attachNodeHttpWebSocketUpgrades(server, {
66
+ runtimeOrigin: this.runtimeOrigin,
67
+ websocketHandlers: this.websocketHandlers,
68
+ passthroughUnmatched: false,
69
+ preflight
70
+ });
46
71
  }
72
+ /**
73
+ * @remarks
74
+ * `previewHost`, `requestBridge`, and `devRuntimeFactory` are optional on the
75
+ * public {@link NodeServerAdapterParams} so factory callers can omit them, but
76
+ * they are mandatory by the time the concrete adapter is constructed —
77
+ * {@link createNodeServerAdapter} fills in Node-specific defaults first. The
78
+ * constructor signature makes that invariant explicit instead of relying on
79
+ * non-null assertions.
80
+ */
47
81
  constructor(options) {
48
82
  super(options);
83
+ this.deferRuntimeAssetSetup = options.deferRuntimeAssetSetup === true;
84
+ this.allowPortFallback = options.allowPortFallback !== false;
49
85
  this.apiHandlers = options.apiHandlers || [];
50
86
  this.staticRoutes = options.staticRoutes || [];
51
87
  this.errorHandler = options.errorHandler;
52
88
  this.previewHost = options.previewHost;
53
89
  this.requestBridge = options.requestBridge;
54
90
  this.devRuntimeFactory = options.devRuntimeFactory;
91
+ if (options.websocketHandlers) {
92
+ this.websocketHandlers = options.websocketHandlers;
93
+ }
94
+ this.hostOwnsDevClient = options.hostOwnsDevClient === true;
55
95
  }
56
96
  /**
57
97
  * Prepares the adapter for use.
@@ -67,13 +107,14 @@ class NodeServerAdapter extends SharedServerAdapter {
67
107
  * processors during their `setup()` calls.
68
108
  */
69
109
  async initialize() {
70
- installAppRuntimeBuildExecutor(this.appConfig);
71
- this.prepareRuntimePublicDir();
72
- await setupAppRuntimePlugins({
73
- appConfig: this.appConfig,
74
- runtimeOrigin: this.runtimeOrigin,
75
- hmrManager: this.hmrManager ?? void 0
76
- });
110
+ installBuildRuntime(this.appConfig);
111
+ prepareRuntimePublicDir(this.appConfig);
112
+ if (!this.deferRuntimeAssetSetup) {
113
+ await setupAppRuntimePlugins({
114
+ appConfig: this.appConfig,
115
+ runtimeOrigin: this.runtimeOrigin
116
+ });
117
+ }
77
118
  await this.initializeSharedRouteHandling({
78
119
  staticRoutes: this.staticRoutes,
79
120
  hmrManager: this.hmrManager ?? void 0
@@ -83,17 +124,12 @@ class NodeServerAdapter extends SharedServerAdapter {
83
124
  appConfig: this.appConfig,
84
125
  staticSiteGenerator: this.staticSiteGenerator,
85
126
  serveOptions: this.serveOptions,
86
- apiHandlers: this.apiHandlers
127
+ runtimeOrigin: this.runtimeOrigin,
128
+ needsServerBundle: this.apiHandlers.length > 0 || this.websocketHandlers.size > 0,
129
+ hmrManager: this.hmrManager ?? void 0
87
130
  });
88
131
  this.initialized = true;
89
132
  }
90
- prepareRuntimePublicDir() {
91
- const srcPublicDir = path.join(this.appConfig.rootDir, this.appConfig.srcDir, this.appConfig.publicDir);
92
- if (fileSystem.exists(srcPublicDir)) {
93
- fileSystem.copyDir(srcPublicDir, path.join(this.appConfig.rootDir, this.appConfig.distDir));
94
- }
95
- fileSystem.ensureDir(path.join(this.appConfig.absolutePaths.distDir, RESOLVED_ASSETS_DIR));
96
- }
97
133
  getServerOptions() {
98
134
  return {
99
135
  ...this.serveOptions
@@ -103,106 +139,85 @@ class NodeServerAdapter extends SharedServerAdapter {
103
139
  if (!this.initialized) {
104
140
  await this.initialize();
105
141
  }
106
- const buildServer = await this.startBuildRuntimeServer();
107
- const buildRuntimeOrigin = this.getListeningServerOrigin(buildServer);
108
- try {
109
- await this.staticBuilder.build(
110
- { preview: false, baseUrl: buildRuntimeOrigin },
111
- {
112
- router: this.router,
113
- routeRendererFactory: this.routeRendererFactory,
114
- staticRoutes: this.staticRoutes
115
- }
116
- );
117
- } finally {
118
- await this.stopBuildRuntimeServer(buildServer);
119
- }
120
- if (!options?.preview) {
121
- return;
122
- }
123
- await this.previewHost.start({
124
- appConfig: this.appConfig,
125
- hostname: String(this.serveOptions.hostname || DEFAULT_ECOPAGES_HOSTNAME),
126
- port: Number(this.serveOptions.port || DEFAULT_ECOPAGES_PORT)
127
- });
128
- const previewHostname = this.serveOptions.hostname || DEFAULT_ECOPAGES_HOSTNAME;
129
- const previewPort = this.serveOptions.port || DEFAULT_ECOPAGES_PORT;
130
- appLogger.info(`Preview running at http://${previewHostname}:${previewPort}`);
131
- }
132
- async startBuildRuntimeServer() {
133
- const hostname = String(this.serveOptions.hostname || DEFAULT_ECOPAGES_HOSTNAME);
134
- const port = 0;
135
- const server = createServer(async (req, res) => {
136
- try {
137
- const webRequest = this.requestBridge.createWebRequest(req, this.runtimeOrigin);
138
- const response = await this.handleRequest(webRequest);
139
- await this.requestBridge.sendNodeResponse(res, response);
140
- } catch (error) {
141
- if (error instanceof NodeClientAbortError) {
142
- return;
143
- }
144
- appLogger.error("Node static build runtime request failed", error);
145
- res.statusCode = 500;
146
- res.end("Internal Server Error");
142
+ const baseUrl = resolveServeRuntimeOrigin(this.serveOptions);
143
+ await this.staticBuilder.build(
144
+ { baseUrl, force: options?.force },
145
+ {
146
+ router: this.router,
147
+ routeRendererFactory: this.routeRendererFactory,
148
+ staticRoutes: this.staticRoutes
147
149
  }
148
- });
149
- await new Promise((resolve, reject) => {
150
- server.once("error", reject);
151
- server.listen(port, hostname, () => {
152
- server.off("error", reject);
153
- resolve();
154
- });
155
- });
156
- this.serverInstance = server;
157
- appLogger.info(`Server running at ${this.getListeningServerOrigin(server)}`);
158
- return server;
159
- }
160
- getListeningServerOrigin(server) {
161
- const address = server.address();
162
- const hostname = String(this.serveOptions.hostname || DEFAULT_ECOPAGES_HOSTNAME);
163
- if (!address || typeof address === "string") {
164
- throw new Error("Build runtime server did not expose a numeric listening port");
150
+ );
151
+ if (!options?.preview) {
152
+ return void 0;
165
153
  }
166
- return `http://${hostname}:${address.port}`;
154
+ return this.startPreviewServer();
167
155
  }
168
156
  /**
169
- * Gracefully shuts down the ephemeral build runtime server.
170
- *
171
- * `closeAllConnections()` is called *before* `close()` because `server.close()`
172
- * only stops accepting new connections — it waits for existing keep-alive
173
- * connections to finish naturally, which can stall the build indefinitely.
174
- * `closeAllConnections()` force-closes any lingering sockets immediately so
175
- * the `close()` callback fires promptly.
176
- *
177
- * The `NodeClientBridge` heartbeat is also destroyed here so its `setInterval`
178
- * does not prevent the Node.js process from exiting cleanly after the build.
157
+ * Serves an existing static export without running SSG. Used by e2e preview
158
+ * launchers after a shared prewarm build.
179
159
  */
180
- async stopBuildRuntimeServer(server) {
181
- await new Promise((resolve, reject) => {
182
- server.close((error) => {
183
- if (error) {
184
- reject(error);
185
- return;
186
- }
187
- resolve();
188
- });
189
- server.closeAllConnections();
160
+ async servePreviewOnly() {
161
+ if (!this.initialized) {
162
+ await this.initialize();
163
+ }
164
+ const distPath = path.join(this.appConfig.rootDir, this.appConfig.distDir);
165
+ if (!fileSystem.exists(distPath)) {
166
+ throw new Error(
167
+ `Cannot serve preview without building first: dist directory "${this.appConfig.distDir}" not found in "${this.appConfig.rootDir}".`
168
+ );
169
+ }
170
+ return this.startPreviewServer();
171
+ }
172
+ async startPreviewServer() {
173
+ const activePreviewPort = await this.previewHost.start({
174
+ appConfig: this.appConfig,
175
+ hostname: String(this.serveOptions.hostname || DEFAULT_ECOPAGES_HOSTNAME),
176
+ port: Number(this.serveOptions.port || DEFAULT_ECOPAGES_PORT),
177
+ allowPortFallback: this.allowPortFallback
190
178
  });
191
- if (this.serverInstance === server) {
192
- this.serverInstance = null;
179
+ if (!activePreviewPort) {
180
+ return void 0;
193
181
  }
194
- this.bridge?.destroy();
195
- this.bridge = null;
182
+ const previewHostname = this.serveOptions.hostname || DEFAULT_ECOPAGES_HOSTNAME;
183
+ return `http://${previewHostname}:${activePreviewPort}`;
196
184
  }
197
185
  async createAdapter() {
198
186
  await this.initialize();
199
187
  return {
200
188
  getServerOptions: this.getServerOptions.bind(this),
201
189
  buildStatic: this.buildStatic.bind(this),
190
+ servePreviewOnly: this.servePreviewOnly.bind(this),
202
191
  completeInitialization: this.completeInitialization.bind(this),
203
- handleRequest: this.handleRequest.bind(this)
192
+ handleRequest: this.handleRequest.bind(this),
193
+ attachUserWebSocketUpgrades: this.attachUserWebSocketUpgrades.bind(this),
194
+ listStaticGenerationRoutes: (input) => this.router.listStaticGenerationRoutes(input),
195
+ dispose: this.dispose.bind(this)
204
196
  };
205
197
  }
198
+ /**
199
+ * Releases dev-time resources owned by the adapter.
200
+ *
201
+ * @remarks
202
+ * Safe to call multiple times. Does not stop the bound HTTP server — callers
203
+ * should shut down transport through the runtime host before disposing.
204
+ */
205
+ async dispose() {
206
+ if (this.adapterDisposed) {
207
+ return;
208
+ }
209
+ this.adapterDisposed = true;
210
+ await disposeDevResources({
211
+ projectWatcher: this.projectWatcher,
212
+ appConfig: this.appConfig,
213
+ hmrManager: this.hmrManager,
214
+ bridge: this.bridge,
215
+ previewHost: this.previewHost
216
+ });
217
+ this.projectWatcher = null;
218
+ this.hmrManager = null;
219
+ this.bridge = null;
220
+ }
206
221
  /**
207
222
  * Handles a single incoming Web `Request` and returns a Web `Response`.
208
223
  *
@@ -221,9 +236,9 @@ class NodeServerAdapter extends SharedServerAdapter {
221
236
  apiHandlers: this.apiHandlers,
222
237
  errorHandler: this.errorHandler,
223
238
  serverInstance: this.serverInstance,
224
- hmrManager: this.hmrManager
239
+ hmrManager: this.hmrManager ?? void 0
225
240
  });
226
- return await this.maybeInjectHmrScript(response);
241
+ return response;
227
242
  } catch (error) {
228
243
  if (error instanceof NodeClientAbortError) {
229
244
  return new Response(null, { status: 499 });
@@ -244,46 +259,58 @@ class NodeServerAdapter extends SharedServerAdapter {
244
259
  * - Shared watcher bootstrapping listens for route-level file changes and
245
260
  * refreshes the router and response handlers when pages are added or removed.
246
261
  *
247
- * WebSocket upgrade requests that do not target `/_hmr` are rejected with an
262
+ * WebSocket upgrade requests that do not match a known path are rejected with an
248
263
  * immediate socket destroy to prevent unhandled upgrade leaks.
249
264
  */
250
265
  async completeInitialization(server) {
251
266
  this.serverInstance = server;
267
+ const hasUserWs = this.websocketHandlers.size > 0;
252
268
  if (this.options?.watch) {
253
269
  const devRuntime = this.devRuntimeFactory.create({ appConfig: this.appConfig });
254
270
  const wss = devRuntime.websocketServer;
255
271
  this.bridge = devRuntime.bridge;
256
272
  this.hmrManager = devRuntime.hmrManager;
257
273
  this.hmrManager.setEnabled(true);
258
- await this.hmrManager.buildRuntime();
259
- server.on("upgrade", (req, socket, head) => {
274
+ await this.hmrManager.ensureRuntimeReady();
275
+ const hmrPreflight = (req, socket, head) => {
260
276
  const url = new URL(req.url ?? "/", this.runtimeOrigin);
261
- if (url.pathname === "/_hmr") {
262
- wss.handleUpgrade(req, socket, head, (ws) => {
263
- this.bridge.subscribe(ws);
264
- ws.on("close", () => this.bridge.unsubscribe(ws));
265
- ws.on("error", (err) => appLogger.error("[HMR] WebSocket error:", err));
266
- });
267
- } else {
268
- socket.destroy();
269
- }
270
- });
271
- const browserBuildPlugins = getAppBrowserBuildPlugins(this.appConfig);
272
- this.hmrManager.setPlugins(browserBuildPlugins);
273
- for (const integration of this.appConfig.integrations) {
274
- integration.setHmrManager(this.hmrManager);
277
+ if (url.pathname !== "/_hmr") return false;
278
+ wss.handleUpgrade(req, socket, head, (ws) => {
279
+ this.bridge.subscribe(ws);
280
+ ws.on("close", () => this.bridge.unsubscribe(ws));
281
+ ws.on("error", (err) => appLogger.error("[HMR] WebSocket error:", err));
282
+ });
283
+ return true;
284
+ };
285
+ if (hasUserWs) {
286
+ this.wireUserWebSocketUpgrades(server, hmrPreflight);
287
+ } else {
288
+ server.on("upgrade", (req, socket, head) => {
289
+ if (!hmrPreflight(req, socket, head)) {
290
+ socket.destroy();
291
+ }
292
+ });
275
293
  }
294
+ attachHmrToIntegrations(this.appConfig, this.hmrManager);
295
+ startConfiguredIntegrationRuntimePrewarm({
296
+ appConfig: this.appConfig,
297
+ runtimeOrigin: this.runtimeOrigin
298
+ });
276
299
  this.configureSharedResponseHandlers(this.staticRoutes, this.hmrManager);
277
300
  const watcher = new ProjectWatcher({
278
301
  config: this.appConfig,
279
302
  refreshRouterRoutesCallback: this.createSharedWatchRefreshCallback({
280
303
  staticRoutes: this.staticRoutes,
281
- hmrManager: this.hmrManager
304
+ hmrManager: this.hmrManager ?? void 0
282
305
  }),
283
- hmrManager: this.hmrManager,
284
- bridge: this.bridge
306
+ hmrManager: this.hmrManager ?? void 0,
307
+ bridge: this.bridge,
308
+ hostOwnsDevClient: this.hostOwnsDevClient
285
309
  });
310
+ this.projectWatcher = watcher;
286
311
  await watcher.createWatcherSubscription();
312
+ } else if (hasUserWs) {
313
+ this.wireUserWebSocketUpgrades(server);
287
314
  }
288
315
  appLogger.debug("Node server adapter initialization completed", {
289
316
  apiHandlers: this.apiHandlers.length,
@@ -56,5 +56,6 @@ export declare class NodeStaticContentServer {
56
56
  * Stops the static preview server and optionally closes active connections.
57
57
  */
58
58
  stop(force?: boolean): Promise<void>;
59
+ [Symbol.asyncDispose](): Promise<void>;
59
60
  }
60
61
  export {};
@@ -161,8 +161,13 @@ class NodeStaticContentServer {
161
161
  this.server = createServer(this.handleRequest.bind(this));
162
162
  const hostname = this.options.hostname ?? DEFAULT_ECOPAGES_HOSTNAME;
163
163
  const port = this.options.port ?? DEFAULT_ECOPAGES_PORT;
164
- await new Promise((resolve) => {
165
- this.server.listen(port, hostname, () => resolve());
164
+ await new Promise((resolve, reject) => {
165
+ const activeServer = this.server;
166
+ activeServer.once("error", reject);
167
+ activeServer.listen(port, hostname, () => {
168
+ activeServer.off("error", reject);
169
+ resolve();
170
+ });
166
171
  });
167
172
  return this.server;
168
173
  }
@@ -188,6 +193,9 @@ class NodeStaticContentServer {
188
193
  }
189
194
  });
190
195
  }
196
+ async [Symbol.asyncDispose]() {
197
+ await this.stop();
198
+ }
191
199
  }
192
200
  export {
193
201
  NodeStaticContentServer
@@ -1,6 +1,6 @@
1
1
  import type { AddressInfo } from 'node:net';
2
2
  import type { EcoPagesAppConfig } from '../../types/internal-types.js';
3
- import type { StaticPreviewHost, StaticPreviewHostStartOptions } from '../shared/static-preview-host.js';
3
+ import type { StaticPreviewHost, StaticPreviewHostStartOptions } from '../shared/runtime/static-preview-host.js';
4
4
  type NodeStaticPreviewServer = {
5
5
  start(): Promise<{
6
6
  address(): AddressInfo | string | null;
@@ -1,3 +1,5 @@
1
+ import { appLogger } from "../../global/app-logger.js";
2
+ import { PortManager } from "../shared/runtime/port-manager.js";
1
3
  import { NodeStaticContentServer } from "./static-content-server.js";
2
4
  class NodeStaticPreviewHost {
3
5
  /**
@@ -20,20 +22,33 @@ class NodeStaticPreviewHost {
20
22
  */
21
23
  async start(options) {
22
24
  await this.stop();
23
- const previewServer = new this.previewServerFactory({
24
- appConfig: options.appConfig,
25
- options: {
26
- hostname: options.hostname,
27
- port: options.port
28
- }
25
+ const portManager = new PortManager({
26
+ startOnPort: async (port) => {
27
+ const previewServer = new this.previewServerFactory({
28
+ appConfig: options.appConfig,
29
+ options: {
30
+ hostname: options.hostname,
31
+ port
32
+ }
33
+ });
34
+ const server = await previewServer.start();
35
+ this.previewServer = previewServer;
36
+ const address = server.address();
37
+ if (address && typeof address === "object") {
38
+ return address.port;
39
+ }
40
+ return port;
41
+ },
42
+ warn: (message) => appLogger.warn(message)
43
+ });
44
+ const previewPort = await portManager.bind({
45
+ preferredPort: options.port,
46
+ allowPortFallback: options.allowPortFallback === true
29
47
  });
30
- const server = await previewServer.start();
31
- this.previewServer = previewServer;
32
- const address = server.address();
33
- if (address && typeof address === "object") {
34
- return address.port;
48
+ if (!previewPort) {
49
+ this.previewServer = null;
35
50
  }
36
- return options.port;
51
+ return previewPort;
37
52
  }
38
53
  /**
39
54
  * Stops the active preview server and coalesces overlapping stop requests onto
@@ -1,20 +1,4 @@
1
- /**
2
- * Shared runtime state used while registering HMR-owned entrypoints.
3
- */
4
- export interface HmrEntrypointRegistrarOptions {
5
- /** Absolute source directory used to derive the emitted HMR path. */
6
- srcDir: string;
7
- /** Absolute distribution directory where HMR outputs are written. */
8
- distDir: string;
9
- /** In-flight registrations keyed by normalized absolute entrypoint path. */
10
- entrypointRegistrations: Map<string, Promise<string>>;
11
- /** Stable entrypoint-to-output mapping retained once an entrypoint is registered. */
12
- watchedFiles: Map<string, string>;
13
- /** Runtime-specific cleanup invoked when an entrypoint registration fails. */
14
- clearFailedRegistration?: (entrypointPath: string) => void;
15
- /** Development-only guardrail for integrations that never finish producing output. */
16
- registrationTimeoutMs: number;
17
- }
1
+ import { type ResolvedHmrEntrypoint } from '../../../hmr/hmr-entrypoint-output.js';
18
2
  /**
19
3
  * Runtime-specific hooks required to materialize a single HMR entrypoint.
20
4
  */
@@ -28,28 +12,45 @@ export interface HmrEntrypointRegistrationOptions {
28
12
  */
29
13
  getMissingOutputError(entrypointPath: string, outputPath: string): Error;
30
14
  }
15
+ export interface HmrEntrypointRegistrarOptions {
16
+ /** Absolute source directory used to derive the emitted HMR path. */
17
+ srcDir: string;
18
+ /** Absolute distribution directory where HMR outputs are written. */
19
+ distDir: string;
20
+ /** Runtime-specific cleanup invoked when an entrypoint registration fails. */
21
+ clearFailedRegistration?: (entrypointPath: string) => void;
22
+ }
31
23
  /**
32
24
  * Coordinates the shared HMR entrypoint registration lifecycle for both Node and Bun managers.
33
25
  *
34
- * The registrar owns the cross-runtime policy: normalize entrypoint identities, dedupe concurrent
35
- * registrations, derive the emitted `_hmr` output path, clear stale output before rebuilding, and
36
- * apply the development timeout that prevents unresolved registrations from hanging navigation.
37
- * Runtime-specific managers remain responsible for the actual emit step and any cleanup outside
38
- * this shared registration flow.
26
+ * @remarks
27
+ * The registrar owns in-flight deduplication and the registered entrypoint table.
28
+ * A source path is committed only after emit succeeds and the expected output exists on disk.
39
29
  */
40
30
  export declare class HmrEntrypointRegistrar {
41
31
  private readonly options;
32
+ private readonly inFlight;
33
+ private readonly registered;
42
34
  constructor(options: HmrEntrypointRegistrarOptions);
35
+ getRegistered(): ReadonlyMap<string, ResolvedHmrEntrypoint>;
36
+ getWatchedFiles(): Map<string, string>;
37
+ clearRegistration(entrypointPath: string): void;
38
+ /**
39
+ * Registers an already-materialized HMR entrypoint without running the emit hook.
40
+ *
41
+ * @remarks
42
+ * Cold dev batches build entrypoints in grouped Rolldown passes and then seed
43
+ * the registrar so the first SSR can resolve the artifact without rebuilding.
44
+ * The source path is committed verbatim so `getResolvedScriptOutput()` and the
45
+ * file watcher see it as a regular watched entrypoint.
46
+ */
47
+ seedResolvedEntrypoint(resolved: ResolvedHmrEntrypoint): void;
48
+ clearAll(): void;
43
49
  /**
44
- * Registers a single source entrypoint and returns the browser URL for its emitted HMR module.
50
+ * Registers a single source entrypoint and returns its verified HMR artifact.
45
51
  *
46
- * Concurrent requests for the same normalized entrypoint share the same in-flight promise so the
47
- * integration only builds once per registration cycle.
52
+ * Concurrent requests for the same normalized entrypoint share the same in-flight promise.
48
53
  */
49
- registerEntrypoint(entrypointPath: string, registrationOptions: HmrEntrypointRegistrationOptions): Promise<string>;
54
+ registerEntrypoint(entrypointPath: string, registrationOptions: HmrEntrypointRegistrationOptions): Promise<ResolvedHmrEntrypoint>;
50
55
  private registerEntrypointInternal;
51
- private awaitEntrypointRegistration;
52
- private getEntrypointOutput;
53
- private removeStaleEntrypointOutput;
54
- private encodeDynamicSegments;
55
56
  }