@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,24 +1,30 @@
1
1
  import path from "node:path";
2
2
  import { DEFAULT_ECOPAGES_HOSTNAME, DEFAULT_ECOPAGES_PORT } from "../../config/constants.js";
3
- import { RESOLVED_ASSETS_DIR } from "../../config/constants.js";
4
3
  import { appLogger } from "../../global/app-logger.js";
5
4
  import { HttpError } from "../../errors/http-error.js";
6
5
  import { createRequire } from "../../utils/locals-utils.js";
6
+ import { findWebSocketRoute } from "../abstract/ws-pattern-matcher.js";
7
7
  import { fileSystem } from "@ecopages/file-system";
8
- import { getAppBrowserBuildPlugins, setupAppRuntimePlugins } from "../../build/build-adapter.js";
9
- import { installAppRuntimeBuildExecutor } from "../../build/runtime-build-executor.js";
8
+ import { setupAppRuntimePlugins } from "../../build/build-adapter.js";
9
+ import { installBuildRuntime } from "../../build/runtime/build-runtime.js";
10
10
  import { StaticSiteGenerator } from "../../static-site-generator/static-site-generator.js";
11
11
  import { ProjectWatcher } from "../../watchers/project-watcher.js";
12
- import { SharedServerAdapter } from "../shared/server-adapter.js";
13
- import { ApiResponseBuilder } from "../shared/api-response.js";
14
- import { ServerStaticBuilder } from "../shared/server-static-builder.js";
12
+ import { SharedServerAdapter } from "../shared/runtime/server-adapter.js";
13
+ import { ApiResponseBuilder } from "../shared/http/api-response.js";
14
+ import { ServerStaticBuilder } from "../shared/runtime/server-static-builder.js";
15
+ import { attachNodeHttpWebSocketUpgrades } from "../shared/ws/node-http-websocket-upgrades.js";
16
+ import { createBunUserWebSocketLifecycle } from "./bun-user-websocket-lifecycle.js";
17
+ import { createEcopagesSocket } from "../shared/ws/websocket-lifecycle.js";
18
+ import { resolveServeRuntimeOrigin } from "../shared/runtime/runtime-app-bootstrap.js";
15
19
  import {
16
- injectHmrRuntimeIntoHtmlResponse,
17
- isHtmlResponse,
18
- shouldInjectHmrHtmlResponse
19
- } from "../shared/hmr-html-response.js";
20
- import { resolveServeRuntimeOrigin } from "../shared/runtime-app-bootstrap.js";
20
+ attachHmrToIntegrations,
21
+ disposeDevResources,
22
+ prepareRuntimePublicDir,
23
+ startConfiguredIntegrationRuntimePrewarm
24
+ } from "../shared/runtime/runtime-server-lifecycle.js";
21
25
  import { ClientBridge } from "./client-bridge.js";
26
+ import { setAppDevClientBridge } from "../../dev/client-bridge-registry.js";
27
+ import { setAppHmrManager } from "../../dev/hmr-manager-registry.js";
22
28
  import { HmrManager } from "./hmr-manager.js";
23
29
  import { BunStaticPreviewHost } from "./static-preview-host.js";
24
30
  class BunServerAdapter extends SharedServerAdapter {
@@ -29,7 +35,59 @@ class BunServerAdapter extends SharedServerAdapter {
29
35
  hmrManager;
30
36
  initializationPromise = null;
31
37
  fullyInitialized = false;
38
+ projectWatcher = null;
39
+ adapterDisposed = false;
40
+ deferRuntimeAssetSetup;
41
+ allowPortFallback;
32
42
  previewHost;
43
+ /**
44
+ * Reference to the application-level WebSocket handlers map.
45
+ *
46
+ * @remarks
47
+ * This is a reference to the map owned by `AbstractApplicationAdapter`,
48
+ * passed in via the constructor. The Bun adapter reads from it to wire
49
+ * WebSocket upgrades for user-registered patterns.
50
+ */
51
+ websocketHandlers = /* @__PURE__ */ new Map();
52
+ registerBunRuntimePlugin(plugin) {
53
+ Bun.plugin(plugin);
54
+ }
55
+ adaptBunWebSocket(ws, kind, params, search, context) {
56
+ return createEcopagesSocket(
57
+ {
58
+ send: (data) => ws.send(data),
59
+ close: (code, reason) => ws.close(code, reason)
60
+ },
61
+ { kind, params, search, context }
62
+ );
63
+ }
64
+ /**
65
+ * Resolves the per-connection context for a Bun user connection.
66
+ *
67
+ * @remarks
68
+ * `context()` is invoked exactly once per accepted connection. Its
69
+ * resolved value is shared by all subsequent lifecycle hooks. If
70
+ * `context()` throws, the connection is closed immediately with code
71
+ * 1011 (server error) and the error is logged.
72
+ *
73
+ * @param request - The original upgrade request (best-effort reconstructed)
74
+ * @param handler - The registered handler
75
+ * @param kind - The registered route pattern
76
+ * @param params - Dynamic path parameters
77
+ * @param search - Query string parameters
78
+ * @returns The resolved per-connection context
79
+ */
80
+ async resolveBunContext(request, handler, kind, params, search) {
81
+ if (!handler.context) {
82
+ return void 0;
83
+ }
84
+ try {
85
+ return await handler.context({ request, kind, params, search });
86
+ } catch (error) {
87
+ appLogger.error(`[WS:${kind}] context() failed; closing connection.`, error);
88
+ throw error;
89
+ }
90
+ }
33
91
  /**
34
92
  * Creates a Bun server adapter with already-resolved runtime collaborators.
35
93
  *
@@ -46,74 +104,64 @@ class BunServerAdapter extends SharedServerAdapter {
46
104
  apiHandlers,
47
105
  staticRoutes,
48
106
  errorHandler,
107
+ websocketHandlers,
49
108
  options,
109
+ hostOwnsDevClient,
110
+ deferRuntimeAssetSetup,
111
+ allowPortFallback,
50
112
  hmrManager,
51
113
  bridge,
52
114
  previewHost
53
115
  }) {
54
116
  super({ appConfig, runtimeOrigin, serveOptions, options });
117
+ this.deferRuntimeAssetSetup = deferRuntimeAssetSetup === true;
118
+ this.allowPortFallback = allowPortFallback !== false;
55
119
  this.apiHandlers = apiHandlers || [];
56
120
  this.staticRoutes = staticRoutes || [];
57
121
  this.errorHandler = errorHandler;
58
122
  this.bridge = bridge;
59
123
  this.hmrManager = hmrManager;
60
124
  this.previewHost = previewHost;
125
+ this.hostOwnsDevClient = hostOwnsDevClient === true;
126
+ if (websocketHandlers) {
127
+ this.websocketHandlers = websocketHandlers;
128
+ }
61
129
  }
62
130
  /**
63
- * Returns whether adapter-level HTML responses still need HMR runtime injection.
64
- *
65
- * @remarks
66
- * Filesystem-routed pages are wrapped later in the shared route layer. This
67
- * adapter-level check exists for explicit API handlers that return HTML and
68
- * would otherwise bypass the route wrapper entirely.
69
- */
70
- shouldInjectHmrScript() {
71
- return shouldInjectHmrHtmlResponse(this.options?.watch === true, this.hmrManager);
72
- }
73
- /**
74
- * Delegates the HTML-response test to the shared response helper used by both
75
- * adapters.
76
- */
77
- isHtmlResponse(response) {
78
- return isHtmlResponse(response);
79
- }
80
- /**
81
- * Injects HMR script into HTML responses in development mode.
82
- * Ensures explicit API handlers that return HTML get auto-reload capability.
131
+ * Wires user WebSocket routes onto a Node HTTP server used by host integrations.
83
132
  */
84
- async maybeInjectHmrScript(response) {
85
- if (this.shouldInjectHmrScript() && this.isHtmlResponse(response)) {
86
- return injectHmrRuntimeIntoHtmlResponse(response);
87
- }
88
- return response;
133
+ attachUserWebSocketUpgrades(server, options) {
134
+ attachNodeHttpWebSocketUpgrades(server, {
135
+ runtimeOrigin: this.runtimeOrigin,
136
+ websocketHandlers: this.websocketHandlers,
137
+ passthroughUnmatched: options?.passthroughUnmatched
138
+ });
89
139
  }
90
140
  /**
91
141
  * Initializes the server adapter's core runtime components.
92
142
  */
93
143
  async initialize() {
94
- installAppRuntimeBuildExecutor(this.appConfig);
144
+ installBuildRuntime(this.appConfig);
95
145
  this.staticSiteGenerator = new StaticSiteGenerator({ appConfig: this.appConfig });
96
- await this.hmrManager.buildRuntime();
97
- this.prepareRuntimePublicDir();
146
+ prepareRuntimePublicDir(this.appConfig);
98
147
  const staticBuilderOptions = {
99
148
  appConfig: this.appConfig,
100
149
  staticSiteGenerator: this.staticSiteGenerator,
101
150
  serveOptions: this.serveOptions,
102
- apiHandlers: this.apiHandlers
151
+ runtimeOrigin: this.runtimeOrigin,
152
+ needsServerBundle: this.apiHandlers.length > 0 || this.websocketHandlers.size > 0,
153
+ hmrManager: this.hmrManager,
154
+ onRuntimePlugin: (plugin) => {
155
+ this.registerBunRuntimePlugin(plugin);
156
+ }
103
157
  };
104
158
  this.staticBuilder = new ServerStaticBuilder(staticBuilderOptions);
105
- await this.initializeRuntimePlugins({ watch: this.options?.watch });
106
- }
107
- /**
108
- * Copies the source `public` directory into the runtime output and ensures the
109
- * HMR assets directory exists before any runtime bundles are emitted.
110
- */
111
- prepareRuntimePublicDir() {
112
- const srcPublicDir = path.join(this.appConfig.rootDir, this.appConfig.srcDir, this.appConfig.publicDir);
113
- if (fileSystem.exists(srcPublicDir)) {
114
- fileSystem.copyDir(srcPublicDir, path.join(this.appConfig.rootDir, this.appConfig.distDir));
159
+ if (!this.deferRuntimeAssetSetup) {
160
+ await this.initializeRuntimePlugins({ watch: this.options?.watch });
161
+ }
162
+ if (this.options?.watch) {
163
+ await this.hmrManager.ensureRuntimeReady();
115
164
  }
116
- fileSystem.ensureDir(path.join(this.appConfig.absolutePaths.distDir, RESOLVED_ASSETS_DIR));
117
165
  }
118
166
  /**
119
167
  * Registers runtime plugins and propagates the final HMR manager into each
@@ -130,15 +178,12 @@ class BunServerAdapter extends SharedServerAdapter {
130
178
  await setupAppRuntimePlugins({
131
179
  appConfig: this.appConfig,
132
180
  runtimeOrigin: this.runtimeOrigin,
133
- hmrManager: this.hmrManager,
134
181
  onRuntimePlugin: (plugin) => {
135
- Bun.plugin(plugin);
182
+ this.registerBunRuntimePlugin(plugin);
136
183
  }
137
184
  });
138
- const browserBuildPlugins = getAppBrowserBuildPlugins(this.appConfig);
139
- this.hmrManager.setPlugins(browserBuildPlugins);
140
- for (const integration of this.appConfig.integrations) {
141
- integration.setHmrManager(this.hmrManager);
185
+ if (options?.watch) {
186
+ attachHmrToIntegrations(this.appConfig, this.hmrManager);
142
187
  }
143
188
  } catch (error) {
144
189
  appLogger.error(`Failed to initialize plugins: ${error instanceof Error ? error.message : String(error)}`);
@@ -173,70 +218,109 @@ class BunServerAdapter extends SharedServerAdapter {
173
218
  config: this.appConfig,
174
219
  refreshRouterRoutesCallback: this.refreshRouterRoutes.bind(this),
175
220
  hmrManager: this.hmrManager,
176
- bridge: this.bridge
221
+ bridge: this.bridge,
222
+ hostOwnsDevClient: this.hostOwnsDevClient
177
223
  });
224
+ this.projectWatcher = watcher;
178
225
  await watcher.createWatcherSubscription();
179
226
  }
180
227
  /**
181
228
  * Builds the `Bun.serve()` options for the current adapter state.
182
229
  *
183
230
  * @remarks
184
- * The HMR-enabled variant wraps the base fetch handler so one Bun server can
185
- * serve normal requests, accept HMR websocket upgrades, and expose the HMR
186
- * runtime asset without splitting responsibility across separate listeners.
231
+ * When HMR is enabled the websocket dispatcher merges HMR and user handlers,
232
+ * routing by the `kind` field embedded in socket data at upgrade time.
233
+ * This prevents user-registered websocket handlers from being silently overwritten
234
+ * by the HMR handler in development mode.
235
+ *
236
+ * User WebSocket paths are intercepted in the fetch handler via the pattern matcher.
237
+ * The upgrade happens implicitly — no manual GET route registration needed.
187
238
  */
188
239
  getServerOptions({ enableHmr = false } = {}) {
189
240
  appLogger.debug(`[BunServerAdapter] getServerOptions called with enableHmr: ${enableHmr}`);
190
241
  const serverOptions = this.buildServerSettings();
242
+ const hasUserWs = this.websocketHandlers.size > 0;
243
+ if (!enableHmr && !hasUserWs) {
244
+ return serverOptions;
245
+ }
246
+ const userLifecycle = this.createBunUserLifecycle();
191
247
  if (enableHmr) {
192
- const originalFetch = serverOptions.fetch;
193
- const hmrHandler = this.hmrManager.getWebSocketHandler();
194
- const hmrManager = this.hmrManager;
195
248
  serverOptions.development = true;
196
- serverOptions.websocket = hmrHandler;
197
- serverOptions.fetch = async function(request, _server) {
198
- const url = new URL(request.url);
199
- appLogger.debug(`[HMR] Request: ${url.pathname}`);
200
- if (url.pathname === "/_hmr") {
201
- const success = this.upgrade(request, {
202
- data: void 0
203
- });
204
- if (success) return;
205
- return new Response("WebSocket upgrade failed", { status: 400 });
206
- }
207
- if (url.pathname === "/_hmr_runtime.js") {
208
- appLogger.debug(`[HMR] Serving runtime from ${hmrManager.getRuntimePath()}`);
209
- return new Response(fileSystem.readFileAsBuffer(hmrManager.getRuntimePath()), {
210
- headers: { "Content-Type": "application/javascript" }
211
- });
212
- }
213
- let response;
214
- if (originalFetch) {
215
- const res = await originalFetch.call(this, request, this);
216
- response = res instanceof Response ? res : new Response("Not Found", { status: 404 });
217
- } else {
218
- response = new Response("Not Found", { status: 404 });
219
- }
220
- return response;
221
- };
249
+ serverOptions.websocket = this.createHmrAwareWebSocketHandler(userLifecycle);
250
+ } else {
251
+ serverOptions.websocket = userLifecycle;
222
252
  }
253
+ serverOptions.fetch = this.wrapFetchWithWebSocketUpgrades(serverOptions.fetch, {
254
+ serveHmrEndpoints: enableHmr
255
+ });
223
256
  return serverOptions;
224
257
  }
258
+ createBunUserLifecycle() {
259
+ return createBunUserWebSocketLifecycle({
260
+ runtimeOrigin: this.runtimeOrigin,
261
+ userHandlers: this.websocketHandlers,
262
+ resolveContext: this.resolveBunContext.bind(this),
263
+ adaptSocket: (ws, kind, params, search, context) => this.adaptBunWebSocket(ws, kind, params, search, context)
264
+ });
265
+ }
225
266
  /**
226
- * Helper method to retrieve and parse the request body.
227
- * Handles JSON and plain text content types.
228
- * For FormData (multipart/form-data, x-www-form-urlencoded), use ctx.request.formData() directly.
229
- * Returns undefined for unsupported content types.
267
+ * @remarks
268
+ * HMR and user sockets share one Bun `websocket` handler. Upgrade tags HMR
269
+ * connections with `kind: '__hmr__'`; everything else routes to the user lifecycle.
230
270
  */
231
- async retrieveBodyFromRequest(request) {
232
- const contentType = request.headers.get("Content-Type") || "";
233
- if (contentType.includes("application/json")) {
234
- return await request.json();
235
- }
236
- if (contentType.includes("text/plain")) {
237
- return await request.text();
238
- }
239
- return void 0;
271
+ createHmrAwareWebSocketHandler(userLifecycle) {
272
+ const hmrHandler = this.hmrManager.getWebSocketHandler();
273
+ const isHmrSocket = (ws) => (ws.data?.kind ?? "__hmr__") === "__hmr__";
274
+ return {
275
+ open(ws) {
276
+ if (isHmrSocket(ws)) return void hmrHandler.open?.(ws);
277
+ userLifecycle.open(ws);
278
+ },
279
+ message(ws, msg) {
280
+ if (isHmrSocket(ws)) return void hmrHandler.message?.(ws, msg);
281
+ userLifecycle.message(ws, msg);
282
+ },
283
+ close(ws, code, reason) {
284
+ if (isHmrSocket(ws)) return void hmrHandler.close?.(ws, code, reason);
285
+ userLifecycle.close(ws, code, reason);
286
+ },
287
+ error(ws, error) {
288
+ if (isHmrSocket(ws)) return void appLogger.error("[HMR] WebSocket error:", error);
289
+ userLifecycle.error(ws, error);
290
+ }
291
+ };
292
+ }
293
+ /**
294
+ * @remarks
295
+ * When `serveHmrEndpoints` is set, `/_hmr` is checked before user websocket
296
+ * patterns so HMR upgrades are never captured by app routes. Runtime assets are
297
+ * served by `SharedServerAdapter.handleSharedRequest` via `tryHandleAssetRequest`.
298
+ * Production mode with only user handlers skips the HMR branch entirely.
299
+ */
300
+ wrapFetchWithWebSocketUpgrades(originalFetch, { serveHmrEndpoints }) {
301
+ const matchRoute = (pathname) => findWebSocketRoute(this.websocketHandlers, pathname);
302
+ return async function(request, server) {
303
+ const url = new URL(request.url);
304
+ if (serveHmrEndpoints) {
305
+ if (url.pathname === "/_hmr") {
306
+ const success = this.upgrade(request, { data: { kind: "__hmr__", params: {}, search: {} } });
307
+ return success ? void 0 : new Response("WebSocket upgrade failed", { status: 400 });
308
+ }
309
+ }
310
+ const wsMatch = matchRoute(url.pathname);
311
+ if (wsMatch && request.headers.get("upgrade")?.toLowerCase() === "websocket") {
312
+ const search = Object.fromEntries(url.searchParams.entries());
313
+ const success = this.upgrade(request, {
314
+ data: { kind: wsMatch.kind, params: wsMatch.params, search, upgradeUrl: request.url }
315
+ });
316
+ return success ? void 0 : new Response("WebSocket upgrade failed", { status: 400 });
317
+ }
318
+ if (!originalFetch) {
319
+ return new Response("Not Found", { status: 404 });
320
+ }
321
+ const res = await originalFetch.call(this, request, server);
322
+ return res instanceof Response ? res : new Response("Not Found", { status: 404 });
323
+ };
240
324
  }
241
325
  /**
242
326
  * Composes the base Bun server settings that all runtime modes build from.
@@ -306,9 +390,9 @@ class BunServerAdapter extends SharedServerAdapter {
306
390
  hmrManager: this.hmrManager
307
391
  });
308
392
  }
309
- const buildRuntimeOrigin = this.serverInstance ? `http://${this.serverInstance.hostname || DEFAULT_ECOPAGES_HOSTNAME}:${this.serverInstance.port || DEFAULT_ECOPAGES_PORT}` : void 0;
393
+ const buildRuntimeOrigin = resolveServeRuntimeOrigin(this.serveOptions);
310
394
  await this.staticBuilder.build(
311
- { ...options, preview: false, baseUrl: buildRuntimeOrigin },
395
+ { baseUrl: buildRuntimeOrigin, force: options?.force },
312
396
  {
313
397
  router: this.router,
314
398
  routeRendererFactory: this.routeRendererFactory,
@@ -316,19 +400,42 @@ class BunServerAdapter extends SharedServerAdapter {
316
400
  }
317
401
  );
318
402
  if (!options?.preview) {
319
- return;
403
+ return void 0;
404
+ }
405
+ return this.startPreviewServer();
406
+ }
407
+ /**
408
+ * Serves an existing static export without running SSG. Used by e2e preview
409
+ * launchers after a shared prewarm build.
410
+ */
411
+ async servePreviewOnly() {
412
+ if (!this.fullyInitialized) {
413
+ await this.initializeSharedRouteHandling({
414
+ staticRoutes: this.staticRoutes,
415
+ hmrManager: this.hmrManager
416
+ });
320
417
  }
418
+ const distPath = path.join(this.appConfig.rootDir, this.appConfig.distDir);
419
+ if (!fileSystem.exists(distPath)) {
420
+ throw new Error(
421
+ `Cannot serve preview without building first: dist directory "${this.appConfig.distDir}" not found in "${this.appConfig.rootDir}".`
422
+ );
423
+ }
424
+ return this.startPreviewServer();
425
+ }
426
+ async startPreviewServer() {
321
427
  const previewHostname = this.serveOptions.hostname || DEFAULT_ECOPAGES_HOSTNAME;
322
428
  const previewPort = Number(this.serveOptions.port || DEFAULT_ECOPAGES_PORT);
323
429
  const activePreviewPort = await this.previewHost.start({
324
430
  appConfig: this.appConfig,
325
431
  hostname: String(previewHostname),
326
- port: previewPort
432
+ port: previewPort,
433
+ allowPortFallback: this.allowPortFallback
327
434
  });
328
- if (activePreviewPort) {
329
- appLogger.info(`Preview running at http://${previewHostname}:${activePreviewPort}`);
330
- return;
435
+ if (!activePreviewPort) {
436
+ return void 0;
331
437
  }
438
+ return `http://${previewHostname}:${activePreviewPort}`;
332
439
  }
333
440
  /**
334
441
  * Initializes the server with dynamic routes after server creation.
@@ -362,6 +469,13 @@ class BunServerAdapter extends SharedServerAdapter {
362
469
  staticRoutes: this.staticRoutes,
363
470
  hmrManager: this.hmrManager
364
471
  });
472
+ if (this.options?.watch) {
473
+ await this.hmrManager.ensureRuntimeReady();
474
+ startConfiguredIntegrationRuntimePrewarm({
475
+ appConfig: this.appConfig,
476
+ runtimeOrigin: this.runtimeOrigin
477
+ });
478
+ }
365
479
  this.fullyInitialized = true;
366
480
  if (this.options?.watch) await this.watch();
367
481
  if (server && typeof server.reload === "function") {
@@ -379,19 +493,42 @@ class BunServerAdapter extends SharedServerAdapter {
379
493
  return {
380
494
  getServerOptions: this.getServerOptions.bind(this),
381
495
  buildStatic: this.buildStatic.bind(this),
496
+ servePreviewOnly: this.servePreviewOnly.bind(this),
382
497
  completeInitialization: this.completeInitialization.bind(this),
383
- handleRequest: this.handleRequest.bind(this)
498
+ handleRequest: this.handleRequest.bind(this),
499
+ attachUserWebSocketUpgrades: this.attachUserWebSocketUpgrades.bind(this),
500
+ listStaticGenerationRoutes: (input) => this.router.listStaticGenerationRoutes(input),
501
+ dispose: this.dispose.bind(this)
384
502
  };
385
503
  }
504
+ /**
505
+ * Releases dev-time resources owned by the adapter.
506
+ *
507
+ * @remarks
508
+ * Safe to call multiple times. Does not stop the bound Bun server — callers
509
+ * should shut down transport through the runtime host before disposing.
510
+ */
511
+ async dispose() {
512
+ if (this.adapterDisposed) {
513
+ return;
514
+ }
515
+ this.adapterDisposed = true;
516
+ await disposeDevResources({
517
+ projectWatcher: this.projectWatcher,
518
+ appConfig: this.appConfig,
519
+ hmrManager: this.hmrManager,
520
+ bridge: this.bridge,
521
+ previewHost: this.previewHost
522
+ });
523
+ this.projectWatcher = null;
524
+ }
386
525
  /**
387
526
  * Handles HTTP requests by passing them securely to the shared core router adapter.
388
527
  *
389
528
  * @remarks
390
- * Filesystem page responses are wrapped by `ServerRouteHandler`. This
391
- * adapter-level pass only covers HTML returned by explicit API handlers,
392
- * which bypass that route-layer wrapper and would otherwise miss the
393
- * dev HMR runtime — so the HMR script injection happens here, after
394
- * the shared handler runs.
529
+ * HMR HTML injection for API and page responses is owned by
530
+ * `SharedServerAdapter.handleSharedRequest`. This method only maps the
531
+ * request into the shared pipeline.
395
532
  */
396
533
  async handleRequest(request) {
397
534
  const response = await this.handleSharedRequest(request, {
@@ -400,7 +537,7 @@ class BunServerAdapter extends SharedServerAdapter {
400
537
  serverInstance: this.serverInstance,
401
538
  hmrManager: this.hmrManager
402
539
  });
403
- return await this.maybeInjectHmrScript(response);
540
+ return response;
404
541
  }
405
542
  /**
406
543
  * Ensures server initialization completes before request handling.
@@ -434,6 +571,8 @@ async function createBunServerAdapter(params) {
434
571
  const runtimeOrigin = params.runtimeOrigin ?? resolveServeRuntimeOrigin(params.serveOptions);
435
572
  const bridge = params.bridge ?? new ClientBridge();
436
573
  const hmrManager = params.hmrManager ?? new HmrManager({ appConfig: params.appConfig, bridge });
574
+ setAppDevClientBridge(params.appConfig, bridge);
575
+ setAppHmrManager(params.appConfig, hmrManager);
437
576
  const previewHost = params.previewHost ?? new BunStaticPreviewHost();
438
577
  const adapter = new BunServerAdapter({
439
578
  ...params,
@@ -1,5 +1,5 @@
1
1
  import type { EcoPagesAppConfig } from '../../types/internal-types.js';
2
- import type { StaticPreviewHost, StaticPreviewHostStartOptions } from '../shared/static-preview-host.js';
2
+ import type { StaticPreviewHost, StaticPreviewHostStartOptions } from '../shared/runtime/static-preview-host.js';
3
3
  type BunStaticPreviewServer = {
4
4
  server: {
5
5
  port?: number;
@@ -1,5 +1,6 @@
1
1
  import { StaticContentServer } from "../../dev/sc-server.js";
2
2
  import { appLogger } from "../../global/app-logger.js";
3
+ import { PortManager } from "../shared/runtime/port-manager.js";
3
4
  class BunStaticPreviewHost {
4
5
  constructor(previewServerFactory = StaticContentServer, logger = appLogger) {
5
6
  this.previewServerFactory = previewServerFactory;
@@ -10,30 +11,34 @@ class BunStaticPreviewHost {
10
11
  previewServer = null;
11
12
  async start(options) {
12
13
  await this.stop();
13
- await new Promise((resolve) => setTimeout(resolve, 100));
14
- for (let attempt = 0; attempt < 20; attempt += 1) {
15
- try {
16
- this.previewServer = this.previewServerFactory.createServer({
14
+ let previewServer = null;
15
+ const portManager = new PortManager({
16
+ startOnPort: async (port) => {
17
+ const candidate = this.previewServerFactory.createServer({
17
18
  appConfig: options.appConfig,
18
- options: { port: options.port }
19
+ options: { port }
19
20
  });
20
- const previewPort = this.previewServer.server?.port;
21
- if (previewPort) {
22
- return previewPort;
21
+ const boundPort = candidate.server?.port ?? null;
22
+ if (!boundPort) {
23
+ candidate.stop();
24
+ return null;
23
25
  }
24
- break;
25
- } catch (error) {
26
- const errorMessage = error instanceof Error ? error.message : String(error);
27
- const errorCode = typeof error === "object" && error !== null && "code" in error ? String(error.code) : void 0;
28
- const isPortReleaseRace = errorCode === "EADDRINUSE" || errorMessage.includes("EADDRINUSE");
29
- if (!isPortReleaseRace || attempt === 19) {
30
- throw error;
31
- }
32
- await new Promise((resolve) => setTimeout(resolve, 100));
33
- }
26
+ previewServer = candidate;
27
+ return boundPort;
28
+ },
29
+ warn: (message) => appLogger.warn(message)
30
+ });
31
+ const previewPort = await portManager.bind({
32
+ preferredPort: options.port,
33
+ allowPortFallback: options.allowPortFallback === true
34
+ });
35
+ if (!previewPort) {
36
+ this.previewServer = null;
37
+ this.logger.error("Failed to start preview server");
38
+ return null;
34
39
  }
35
- this.logger.error("Failed to start preview server");
36
- return null;
40
+ this.previewServer = previewServer;
41
+ return previewPort;
37
42
  }
38
43
  async stop() {
39
44
  this.previewServer?.stop();
@@ -1,20 +1,22 @@
1
1
  import type { EcoPagesAppConfig } from '../types/internal-types.js';
2
2
  import { AbstractApplicationAdapter } from './abstract/application-adapter.js';
3
3
  import type { ApplicationAdapterOptions } from './abstract/application-adapter.js';
4
- import { SharedApplicationAdapter } from './shared/application-adapter.js';
4
+ export type { OnAppStartCallback, AppStartInfo, StartCallback, ListenCallback, ApplicationListeningCallback, ApplicationListeningInfo, } from './abstract/application-adapter.js';
5
+ export type EcopagesRuntimeAdapter = 'auto' | 'node' | 'bun';
5
6
  export interface EcopagesAppOptions extends ApplicationAdapterOptions {
6
7
  appConfig: EcoPagesAppConfig;
8
+ /**
9
+ * Selects the runtime adapter used by the universal `createApp()` entrypoint.
10
+ *
11
+ * @default 'auto'
12
+ *
13
+ * @remarks
14
+ * This is separate from `runtime`, which configures embedded host behavior.
15
+ * Use `auto` to select Bun when the current process exposes `globalThis.Bun`
16
+ * and Node otherwise.
17
+ */
18
+ adapter?: EcopagesRuntimeAdapter;
7
19
  serverOptions?: Record<string, any>;
8
20
  }
9
21
  export type UniversalEcopagesApp = AbstractApplicationAdapter<EcopagesAppOptions, unknown, Request>;
10
22
  export declare function createApp<WebSocketData = undefined>(options: EcopagesAppOptions): Promise<UniversalEcopagesApp>;
11
- export declare class EcopagesApp extends SharedApplicationAdapter<EcopagesAppOptions, unknown, Request> {
12
- private readonly appOptions;
13
- private runtimeApp;
14
- private runtimeAppPromise;
15
- constructor(options: EcopagesAppOptions);
16
- private getRuntimeApp;
17
- protected initializeServerAdapter(): Promise<UniversalEcopagesApp>;
18
- start(): Promise<unknown>;
19
- fetch(request: Request): Promise<Response>;
20
- }