@ecopages/core 0.2.0-beta.2 → 0.2.0-beta.20

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 (273) hide show
  1. package/README.md +1 -1
  2. package/package.json +163 -3
  3. package/src/adapters/abstract/application-adapter.d.ts +104 -5
  4. package/src/adapters/abstract/application-adapter.js +125 -1
  5. package/src/adapters/abstract/server-adapter.d.ts +6 -2
  6. package/src/adapters/abstract/ws-pattern-matcher.d.ts +60 -0
  7. package/src/adapters/abstract/ws-pattern-matcher.js +61 -0
  8. package/src/adapters/bun/client-bridge.d.ts +1 -0
  9. package/src/adapters/bun/client-bridge.js +3 -0
  10. package/src/adapters/bun/create-app.d.ts +6 -4
  11. package/src/adapters/bun/create-app.js +65 -43
  12. package/src/adapters/bun/hmr-manager.d.ts +2 -1
  13. package/src/adapters/bun/hmr-manager.js +2 -2
  14. package/src/adapters/bun/server-adapter.d.ts +90 -22
  15. package/src/adapters/bun/server-adapter.js +265 -84
  16. package/src/adapters/bun/static-preview-host.js +25 -20
  17. package/src/adapters/create-app.d.ts +13 -11
  18. package/src/adapters/create-app.js +2 -51
  19. package/src/adapters/index.d.ts +1 -1
  20. package/src/adapters/index.js +1 -2
  21. package/src/adapters/node/create-app.d.ts +5 -1
  22. package/src/adapters/node/create-app.js +51 -12
  23. package/src/adapters/node/node-client-bridge.d.ts +1 -0
  24. package/src/adapters/node/node-client-bridge.js +3 -0
  25. package/src/adapters/node/node-hmr-manager.d.ts +2 -1
  26. package/src/adapters/node/node-hmr-manager.js +2 -2
  27. package/src/adapters/node/server-adapter-dependencies.js +4 -0
  28. package/src/adapters/node/server-adapter.d.ts +62 -20
  29. package/src/adapters/node/server-adapter.js +161 -131
  30. package/src/adapters/node/static-content-server.d.ts +1 -0
  31. package/src/adapters/node/static-content-server.js +10 -2
  32. package/src/adapters/node/static-preview-host.js +27 -12
  33. package/src/adapters/shared/bun-user-websocket-lifecycle.d.ts +22 -0
  34. package/src/adapters/shared/bun-user-websocket-lifecycle.js +96 -0
  35. package/src/adapters/shared/copy-runtime-public-dir.d.ts +6 -0
  36. package/src/adapters/shared/copy-runtime-public-dir.js +24 -0
  37. package/src/adapters/shared/fs-server-response-matcher.d.ts +2 -0
  38. package/src/adapters/shared/fs-server-response-matcher.js +40 -18
  39. package/src/adapters/shared/hmr-entrypoint-registrar.d.ts +0 -2
  40. package/src/adapters/shared/hmr-entrypoint-registrar.js +3 -26
  41. package/src/adapters/shared/hmr-html-response.d.ts +1 -1
  42. package/src/adapters/shared/hmr-html-response.js +4 -1
  43. package/src/adapters/shared/node-http-websocket-upgrades.d.ts +21 -0
  44. package/src/adapters/shared/node-http-websocket-upgrades.js +100 -0
  45. package/src/adapters/shared/port-manager.d.ts +116 -0
  46. package/src/adapters/shared/port-manager.js +196 -0
  47. package/src/adapters/shared/runtime-app-bootstrap.d.ts +2 -1
  48. package/src/adapters/shared/runtime-app-bootstrap.js +3 -6
  49. package/src/adapters/shared/runtime-server-lifecycle.d.ts +38 -0
  50. package/src/adapters/shared/runtime-server-lifecycle.js +43 -0
  51. package/src/adapters/shared/server-adapter.d.ts +2 -1
  52. package/src/adapters/shared/server-adapter.js +13 -6
  53. package/src/adapters/shared/server-route-handler.d.ts +4 -1
  54. package/src/adapters/shared/server-route-handler.js +5 -2
  55. package/src/adapters/shared/server-static-builder.d.ts +23 -32
  56. package/src/adapters/shared/server-static-builder.js +97 -73
  57. package/src/adapters/shared/shared-hmr-manager.d.ts +28 -0
  58. package/src/adapters/shared/shared-hmr-manager.js +119 -9
  59. package/src/adapters/shared/static-preview-host.d.ts +5 -0
  60. package/src/adapters/shared/websocket-lifecycle.d.ts +24 -0
  61. package/src/adapters/shared/websocket-lifecycle.js +55 -0
  62. package/src/build/README.md +77 -14
  63. package/src/build/app-build-manifest-runtime.d.ts +10 -0
  64. package/src/build/app-build-manifest-runtime.js +90 -0
  65. package/src/build/build-adapter.d.ts +17 -319
  66. package/src/build/build-adapter.js +28 -94
  67. package/src/build/build-contracts.d.ts +97 -0
  68. package/src/build/build-contracts.js +0 -0
  69. package/src/build/build-input-fingerprint.d.ts +28 -0
  70. package/src/build/build-input-fingerprint.js +31 -0
  71. package/src/build/build-profile-options.d.ts +7 -0
  72. package/src/build/build-profile-options.js +37 -0
  73. package/src/build/build-runtime.d.ts +24 -0
  74. package/src/build/build-runtime.js +65 -0
  75. package/src/build/deduping-build-executor.d.ts +28 -0
  76. package/src/build/deduping-build-executor.js +56 -0
  77. package/src/build/jsx-ownership-plugins.d.ts +24 -0
  78. package/src/build/jsx-ownership-plugins.js +41 -0
  79. package/src/build/pages-unified-graph-build.d.ts +31 -0
  80. package/src/build/pages-unified-graph-build.js +206 -0
  81. package/src/build/parallel-build-executor.d.ts +21 -0
  82. package/src/build/parallel-build-executor.js +52 -0
  83. package/src/build/production-build-cache.d.ts +20 -0
  84. package/src/build/production-build-cache.js +63 -0
  85. package/src/build/rolldown-adapter-helpers.d.ts +3 -6
  86. package/src/build/rolldown-adapter-helpers.js +71 -6
  87. package/src/build/rolldown-build-adapter.d.ts +2 -6
  88. package/src/build/rolldown-build-adapter.js +3 -3
  89. package/src/build/rolldown-build-invocation-metrics.d.ts +12 -0
  90. package/src/build/rolldown-build-invocation-metrics.js +43 -0
  91. package/src/build/rolldown-plugin-bridge.d.ts +15 -1
  92. package/src/build/rolldown-plugin-bridge.js +20 -5
  93. package/src/build/rolldown-source-transform-pass.d.ts +15 -0
  94. package/src/build/rolldown-source-transform-pass.js +58 -0
  95. package/src/build/runtime-build-executor.d.ts +8 -15
  96. package/src/build/runtime-build-executor.js +12 -15
  97. package/src/build/runtime-build-output-normalizer.d.ts +7 -0
  98. package/src/build/runtime-build-output-normalizer.js +94 -2
  99. package/src/build/server-entry-build-cache.d.ts +44 -0
  100. package/src/build/server-entry-build-cache.js +161 -0
  101. package/src/client/navigation-scripts/classification.d.ts +16 -0
  102. package/src/client/navigation-scripts/classification.js +41 -0
  103. package/src/client/navigation-scripts/index.d.ts +3 -0
  104. package/src/client/navigation-scripts/index.js +23 -0
  105. package/src/client/navigation-scripts/navigation-scripts.test.browser.js +65 -0
  106. package/src/client/navigation-scripts/registry.d.ts +11 -0
  107. package/src/client/navigation-scripts/registry.js +12 -0
  108. package/src/client/navigation-scripts/rerun-queue.d.ts +37 -0
  109. package/src/client/navigation-scripts/rerun-queue.js +73 -0
  110. package/src/client/scroll.d.ts +17 -0
  111. package/src/client/scroll.js +25 -0
  112. package/src/client/scroll.test.browser.js +37 -0
  113. package/src/client/view-transitions.d.ts +16 -0
  114. package/src/client/view-transitions.js +63 -0
  115. package/src/config/config-builder.d.ts +12 -7
  116. package/src/config/config-builder.js +12 -9
  117. package/src/dev/client-bridge-registry.d.ts +5 -0
  118. package/src/dev/client-bridge-registry.js +15 -0
  119. package/src/dev/dev-client-ownership.d.ts +7 -0
  120. package/src/dev/dev-client-ownership.js +6 -0
  121. package/src/dev/hmr-manager-registry.d.ts +8 -0
  122. package/src/dev/hmr-manager-registry.js +15 -0
  123. package/src/dev/host-runtime.d.ts +3 -0
  124. package/src/dev/host-runtime.js +7 -0
  125. package/src/dev/runtime-server-started-message.d.ts +2 -0
  126. package/src/dev/runtime-server-started-message.js +6 -0
  127. package/src/eco/README.md +11 -0
  128. package/src/eco/eco-declared-component.d.ts +14 -0
  129. package/src/eco/eco-declared-component.js +16 -0
  130. package/src/eco/eco.browser.js +5 -6
  131. package/src/eco/eco.js +5 -6
  132. package/src/eco/eco.types.d.ts +2 -2
  133. package/src/eco/page-layout-normalization.d.ts +21 -0
  134. package/src/eco/page-layout-normalization.js +59 -0
  135. package/src/errors/index.d.ts +1 -0
  136. package/src/errors/index.js +7 -1
  137. package/src/errors/undeclared-component-dependency-error.d.ts +11 -0
  138. package/src/errors/undeclared-component-dependency-error.js +17 -0
  139. package/src/hmr/client/hmr-runtime.js +5 -2
  140. package/src/hmr/hmr-entrypoint-output.d.ts +28 -0
  141. package/src/hmr/hmr-entrypoint-output.js +58 -0
  142. package/src/hmr/strategies/js-hmr-strategy.d.ts +3 -0
  143. package/src/hmr/strategies/js-hmr-strategy.js +68 -18
  144. package/src/hmr/strategies/server-rendered-template-hmr-strategy.d.ts +17 -0
  145. package/src/hmr/strategies/server-rendered-template-hmr-strategy.js +29 -0
  146. package/src/integrations/ghtml/ghtml-renderer.d.ts +2 -6
  147. package/src/integrations/ghtml/ghtml-renderer.js +2 -51
  148. package/src/integrations/ghtml/ghtml.plugin.d.ts +3 -16
  149. package/src/integrations/ghtml/ghtml.plugin.js +7 -14
  150. package/src/plugins/define-integration.d.ts +26 -0
  151. package/src/plugins/define-integration.js +19 -0
  152. package/src/plugins/eco-component-meta-plugin.js +5 -8
  153. package/src/plugins/foreign-jsx-override-plugin.js +4 -6
  154. package/src/plugins/integration-plugin.d.ts +19 -9
  155. package/src/plugins/integration-plugin.js +7 -4
  156. package/src/plugins/jsx-import-source.utils.d.ts +8 -0
  157. package/src/plugins/jsx-import-source.utils.js +26 -0
  158. package/src/plugins/processor.d.ts +19 -4
  159. package/src/plugins/processor.js +22 -4
  160. package/src/plugins/source-transform.d.ts +31 -0
  161. package/src/plugins/source-transform.js +23 -1
  162. package/src/route-renderer/GRAPH.md +8 -8
  163. package/src/route-renderer/README.md +30 -28
  164. package/src/route-renderer/orchestration/component-graph-collectors.d.ts +10 -0
  165. package/src/route-renderer/orchestration/component-graph-collectors.js +143 -0
  166. package/src/route-renderer/orchestration/component-graph.d.ts +36 -0
  167. package/src/route-renderer/orchestration/component-graph.js +98 -0
  168. package/src/route-renderer/orchestration/component-render-context.d.ts +3 -10
  169. package/src/route-renderer/orchestration/component-render-context.js +3 -1
  170. package/src/route-renderer/orchestration/declared-ownership-graph.d.ts +1 -18
  171. package/src/route-renderer/orchestration/declared-ownership-graph.js +5 -31
  172. package/src/route-renderer/orchestration/document-shell-render.service.d.ts +90 -0
  173. package/src/route-renderer/orchestration/document-shell-render.service.js +120 -0
  174. package/src/route-renderer/orchestration/foreign-subtree-execution.service.d.ts +59 -29
  175. package/src/route-renderer/orchestration/foreign-subtree-execution.service.js +164 -35
  176. package/src/route-renderer/orchestration/global-injector-assets.service.d.ts +7 -0
  177. package/src/route-renderer/orchestration/global-injector-assets.service.js +32 -0
  178. package/src/route-renderer/orchestration/integration-renderer.d.ts +18 -54
  179. package/src/route-renderer/orchestration/integration-renderer.js +113 -195
  180. package/src/route-renderer/orchestration/integration-route-render-adapter.d.ts +38 -0
  181. package/src/route-renderer/orchestration/integration-route-render-adapter.js +27 -0
  182. package/src/route-renderer/orchestration/layout-shell-props.service.d.ts +20 -0
  183. package/src/route-renderer/orchestration/layout-shell-props.service.js +31 -0
  184. package/src/route-renderer/orchestration/ownership-validation.service.d.ts +5 -0
  185. package/src/route-renderer/orchestration/ownership-validation.service.js +29 -1
  186. package/src/route-renderer/orchestration/page-browser-graph-contribution.loader.d.ts +9 -0
  187. package/src/route-renderer/orchestration/page-browser-graph-contribution.loader.js +7 -0
  188. package/src/route-renderer/orchestration/page-browser-graph.service.d.ts +25 -0
  189. package/src/route-renderer/orchestration/page-browser-graph.service.js +174 -0
  190. package/src/route-renderer/orchestration/render-output.utils.d.ts +2 -0
  191. package/src/route-renderer/orchestration/render-output.utils.js +4 -0
  192. package/src/route-renderer/orchestration/route-html-finalization.service.d.ts +17 -0
  193. package/src/route-renderer/orchestration/route-html-finalization.service.js +26 -0
  194. package/src/route-renderer/orchestration/route-prepared-options.builder.d.ts +26 -0
  195. package/src/route-renderer/orchestration/route-prepared-options.builder.js +54 -0
  196. package/src/route-renderer/orchestration/route-prepared-options.utils.d.ts +4 -0
  197. package/src/route-renderer/orchestration/route-prepared-options.utils.js +33 -0
  198. package/src/route-renderer/orchestration/route-render-orchestrator.d.ts +8 -39
  199. package/src/route-renderer/orchestration/route-render-orchestrator.js +53 -461
  200. package/src/route-renderer/orchestration/string-markup-renderer.d.ts +14 -0
  201. package/src/route-renderer/orchestration/string-markup-renderer.js +55 -0
  202. package/src/route-renderer/page-loading/component-dependency-collection.js +5 -2
  203. package/src/router/client/link-intent.d.ts +11 -21
  204. package/src/router/client/link-intent.js +10 -0
  205. package/src/router/client/link-intent.test.browser.js +12 -1
  206. package/src/router/client/link-navigation-policy.d.ts +45 -0
  207. package/src/router/client/link-navigation-policy.js +101 -0
  208. package/src/router/client/link-navigation-policy.test.browser.d.ts +1 -0
  209. package/src/router/client/link-navigation-policy.test.browser.js +92 -0
  210. package/src/router/client/navigation-coordinator.d.ts +1 -1
  211. package/src/router/client/navigation-coordinator.js +12 -2
  212. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.d.ts +1 -0
  213. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +1 -0
  214. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.d.ts +4 -2
  215. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.js +27 -7
  216. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +36 -14
  217. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +17 -3
  218. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.d.ts +0 -3
  219. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +2 -31
  220. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.d.ts +0 -3
  221. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +2 -30
  222. package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.d.ts +2 -0
  223. package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.js +43 -0
  224. package/src/services/assets/browser-bundle.service.d.ts +3 -1
  225. package/src/services/assets/browser-bundle.service.js +17 -5
  226. package/src/services/html/html-transformer.service.d.ts +1 -1
  227. package/src/services/html/html-transformer.service.js +4 -4
  228. package/src/services/invalidation/development-invalidation.service.d.ts +20 -2
  229. package/src/services/invalidation/development-invalidation.service.js +56 -2
  230. package/src/services/module-loading/README.md +49 -0
  231. package/src/services/module-loading/app-server-module-transpiler.service.js +5 -17
  232. package/src/services/module-loading/page-module-import.service.d.ts +5 -1
  233. package/src/services/module-loading/page-module-import.service.js +97 -45
  234. package/src/services/module-loading/route-module-build-cache-registry.d.ts +24 -0
  235. package/src/services/module-loading/route-module-build-cache-registry.js +37 -0
  236. package/src/services/module-loading/route-module-build-cache.d.ts +4 -0
  237. package/src/services/module-loading/route-module-build-cache.js +38 -0
  238. package/src/services/module-loading/route-module-build-cache.store.d.ts +57 -0
  239. package/src/services/module-loading/route-module-build-cache.store.js +207 -0
  240. package/src/services/module-loading/route-module-build-manifest.d.ts +61 -0
  241. package/src/services/module-loading/route-module-build-manifest.js +116 -0
  242. package/src/services/module-loading/route-module-dependency-hasher.d.ts +81 -0
  243. package/src/services/module-loading/route-module-dependency-hasher.js +121 -0
  244. package/src/services/module-loading/server-module-transpiler.service.js +1 -1
  245. package/src/static-site-generator/README.md +33 -0
  246. package/src/static-site-generator/static-build-invalidation.d.ts +10 -0
  247. package/src/static-site-generator/static-build-invalidation.js +59 -0
  248. package/src/static-site-generator/static-export-context.d.ts +22 -0
  249. package/src/static-site-generator/static-export-context.js +0 -0
  250. package/src/static-site-generator/static-site-generator.d.ts +17 -20
  251. package/src/static-site-generator/static-site-generator.js +188 -85
  252. package/src/types/internal-types.d.ts +16 -9
  253. package/src/types/public-types.d.ts +138 -26
  254. package/src/utils/parse-cli-args.d.ts +2 -0
  255. package/src/utils/parse-cli-args.js +6 -0
  256. package/src/utils/server-utils.module.d.ts +3 -2
  257. package/src/utils/server-utils.module.js +5 -6
  258. package/src/utils/static-file-extensions.d.ts +12 -0
  259. package/src/utils/static-file-extensions.js +48 -0
  260. package/src/watchers/project-watcher-ignore.d.ts +11 -0
  261. package/src/watchers/project-watcher-ignore.js +16 -0
  262. package/src/watchers/project-watcher.d.ts +25 -2
  263. package/src/watchers/project-watcher.js +130 -23
  264. package/src/build/rolldown-dev-build-adapter.d.ts +0 -82
  265. package/src/build/rolldown-dev-build-adapter.js +0 -166
  266. package/src/hmr/hmr.postcss.test.e2e.js +0 -31
  267. package/src/hmr/hmr.test.e2e.js +0 -43
  268. package/src/route-renderer/orchestration/ownership-planning.service.d.ts +0 -24
  269. package/src/route-renderer/orchestration/ownership-planning.service.js +0 -63
  270. package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.d.ts +0 -91
  271. package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.js +0 -170
  272. /package/src/{hmr/hmr.postcss.test.e2e.d.ts → client/navigation-scripts/navigation-scripts.test.browser.d.ts} +0 -0
  273. /package/src/{hmr/hmr.test.e2e.d.ts → client/scroll.test.browser.d.ts} +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";
8
+ import { setupAppRuntimePlugins } from "../../build/build-adapter.js";
9
9
  import { installAppRuntimeBuildExecutor } from "../../build/runtime-build-executor.js";
10
10
  import { StaticSiteGenerator } from "../../static-site-generator/static-site-generator.js";
11
11
  import { ProjectWatcher } from "../../watchers/project-watcher.js";
12
12
  import { SharedServerAdapter } from "../shared/server-adapter.js";
13
13
  import { ApiResponseBuilder } from "../shared/api-response.js";
14
14
  import { ServerStaticBuilder } from "../shared/server-static-builder.js";
15
- import {
16
- injectHmrRuntimeIntoHtmlResponse,
17
- isHtmlResponse,
18
- shouldInjectHmrHtmlResponse
19
- } from "../shared/hmr-html-response.js";
15
+ import { attachNodeHttpWebSocketUpgrades } from "../shared/node-http-websocket-upgrades.js";
16
+ import { createBunUserWebSocketLifecycle } from "../shared/bun-user-websocket-lifecycle.js";
17
+ import { createEcopagesSocket } from "../shared/websocket-lifecycle.js";
20
18
  import { resolveServeRuntimeOrigin } from "../shared/runtime-app-bootstrap.js";
19
+ import {
20
+ disposeDevResources,
21
+ maybeInjectAdapterHmrHtmlResponse,
22
+ prepareRuntimePublicDir,
23
+ wireIntegrationHmrManagers
24
+ } from "../shared/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,18 +104,38 @@ 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
+ }
129
+ }
130
+ /**
131
+ * Wires user WebSocket routes onto a Node HTTP server used by host integrations.
132
+ */
133
+ attachUserWebSocketUpgrades(server, options) {
134
+ attachNodeHttpWebSocketUpgrades(server, {
135
+ runtimeOrigin: this.runtimeOrigin,
136
+ websocketHandlers: this.websocketHandlers,
137
+ passthroughUnmatched: options?.passthroughUnmatched
138
+ });
61
139
  }
62
140
  /**
63
141
  * Returns whether adapter-level HTML responses still need HMR runtime injection.
@@ -67,25 +145,12 @@ class BunServerAdapter extends SharedServerAdapter {
67
145
  * adapter-level check exists for explicit API handlers that return HTML and
68
146
  * would otherwise bypass the route wrapper entirely.
69
147
  */
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.
83
- */
84
148
  async maybeInjectHmrScript(response) {
85
- if (this.shouldInjectHmrScript() && this.isHtmlResponse(response)) {
86
- return injectHmrRuntimeIntoHtmlResponse(response);
87
- }
88
- return response;
149
+ return maybeInjectAdapterHmrHtmlResponse(response, {
150
+ watch: this.options?.watch === true,
151
+ hmrManager: this.hmrManager,
152
+ hostOwnsDevClient: this.hostOwnsDevClient
153
+ });
89
154
  }
90
155
  /**
91
156
  * Initializes the server adapter's core runtime components.
@@ -93,27 +158,25 @@ class BunServerAdapter extends SharedServerAdapter {
93
158
  async initialize() {
94
159
  installAppRuntimeBuildExecutor(this.appConfig);
95
160
  this.staticSiteGenerator = new StaticSiteGenerator({ appConfig: this.appConfig });
96
- await this.hmrManager.buildRuntime();
97
- this.prepareRuntimePublicDir();
161
+ prepareRuntimePublicDir(this.appConfig);
98
162
  const staticBuilderOptions = {
99
163
  appConfig: this.appConfig,
100
164
  staticSiteGenerator: this.staticSiteGenerator,
101
165
  serveOptions: this.serveOptions,
102
- apiHandlers: this.apiHandlers
166
+ runtimeOrigin: this.runtimeOrigin,
167
+ needsServerBundle: this.apiHandlers.length > 0 || this.websocketHandlers.size > 0,
168
+ hmrManager: this.hmrManager,
169
+ onRuntimePlugin: (plugin) => {
170
+ this.registerBunRuntimePlugin(plugin);
171
+ }
103
172
  };
104
173
  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));
174
+ if (!this.deferRuntimeAssetSetup) {
175
+ await this.initializeRuntimePlugins({ watch: this.options?.watch });
176
+ }
177
+ if (this.options?.watch) {
178
+ await this.hmrManager.ensureRuntimeReady();
115
179
  }
116
- fileSystem.ensureDir(path.join(this.appConfig.absolutePaths.distDir, RESOLVED_ASSETS_DIR));
117
180
  }
118
181
  /**
119
182
  * Registers runtime plugins and propagates the final HMR manager into each
@@ -132,14 +195,10 @@ class BunServerAdapter extends SharedServerAdapter {
132
195
  runtimeOrigin: this.runtimeOrigin,
133
196
  hmrManager: this.hmrManager,
134
197
  onRuntimePlugin: (plugin) => {
135
- Bun.plugin(plugin);
198
+ this.registerBunRuntimePlugin(plugin);
136
199
  }
137
200
  });
138
- const browserBuildPlugins = getAppBrowserBuildPlugins(this.appConfig);
139
- this.hmrManager.setPlugins(browserBuildPlugins);
140
- for (const integration of this.appConfig.integrations) {
141
- integration.setHmrManager(this.hmrManager);
142
- }
201
+ wireIntegrationHmrManagers(this.appConfig, this.hmrManager);
143
202
  } catch (error) {
144
203
  appLogger.error(`Failed to initialize plugins: ${error instanceof Error ? error.message : String(error)}`);
145
204
  throw error;
@@ -173,54 +232,124 @@ class BunServerAdapter extends SharedServerAdapter {
173
232
  config: this.appConfig,
174
233
  refreshRouterRoutesCallback: this.refreshRouterRoutes.bind(this),
175
234
  hmrManager: this.hmrManager,
176
- bridge: this.bridge
235
+ bridge: this.bridge,
236
+ hostOwnsDevClient: this.hostOwnsDevClient
177
237
  });
238
+ this.projectWatcher = watcher;
178
239
  await watcher.createWatcherSubscription();
179
240
  }
180
241
  /**
181
242
  * Builds the `Bun.serve()` options for the current adapter state.
182
243
  *
183
244
  * @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.
245
+ * When HMR is enabled the websocket dispatcher merges HMR and user handlers,
246
+ * routing by the `kind` field embedded in socket data at upgrade time.
247
+ * This prevents user-registered websocket handlers from being silently overwritten
248
+ * by the HMR handler in development mode.
249
+ *
250
+ * User WebSocket paths are intercepted in the fetch handler via the pattern matcher.
251
+ * The upgrade happens implicitly — no manual GET route registration needed.
187
252
  */
188
253
  getServerOptions({ enableHmr = false } = {}) {
189
254
  appLogger.debug(`[BunServerAdapter] getServerOptions called with enableHmr: ${enableHmr}`);
190
255
  const serverOptions = this.buildServerSettings();
256
+ const hasUserWs = this.websocketHandlers.size > 0;
257
+ if (!enableHmr && !hasUserWs) {
258
+ return serverOptions;
259
+ }
260
+ const userLifecycle = this.createBunUserLifecycle();
191
261
  if (enableHmr) {
192
- const originalFetch = serverOptions.fetch;
193
- const hmrHandler = this.hmrManager.getWebSocketHandler();
194
- const hmrManager = this.hmrManager;
195
262
  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}`);
263
+ serverOptions.websocket = this.createHmrAwareWebSocketHandler(userLifecycle);
264
+ } else {
265
+ serverOptions.websocket = userLifecycle;
266
+ }
267
+ serverOptions.fetch = this.wrapFetchWithWebSocketUpgrades(serverOptions.fetch, {
268
+ serveHmrEndpoints: enableHmr
269
+ });
270
+ return serverOptions;
271
+ }
272
+ createBunUserLifecycle() {
273
+ return createBunUserWebSocketLifecycle({
274
+ runtimeOrigin: this.runtimeOrigin,
275
+ userHandlers: this.websocketHandlers,
276
+ resolveContext: this.resolveBunContext.bind(this),
277
+ adaptSocket: (ws, kind, params, search, context) => this.adaptBunWebSocket(ws, kind, params, search, context)
278
+ });
279
+ }
280
+ /**
281
+ * @remarks
282
+ * HMR and user sockets share one Bun `websocket` handler. Upgrade tags HMR
283
+ * connections with `kind: '__hmr__'`; everything else routes to the user lifecycle.
284
+ */
285
+ createHmrAwareWebSocketHandler(userLifecycle) {
286
+ const hmrHandler = this.hmrManager.getWebSocketHandler();
287
+ const isHmrSocket = (ws) => (ws.data?.kind ?? "__hmr__") === "__hmr__";
288
+ return {
289
+ open(ws) {
290
+ if (isHmrSocket(ws)) return void hmrHandler.open?.(ws);
291
+ userLifecycle.open(ws);
292
+ },
293
+ message(ws, msg) {
294
+ if (isHmrSocket(ws)) return void hmrHandler.message?.(ws, msg);
295
+ userLifecycle.message(ws, msg);
296
+ },
297
+ close(ws, code, reason) {
298
+ if (isHmrSocket(ws)) return void hmrHandler.close?.(ws, code, reason);
299
+ userLifecycle.close(ws, code, reason);
300
+ },
301
+ error(ws, error) {
302
+ if (isHmrSocket(ws)) return void appLogger.error("[HMR] WebSocket error:", error);
303
+ userLifecycle.error(ws, error);
304
+ }
305
+ };
306
+ }
307
+ /**
308
+ * @remarks
309
+ * When `serveHmrEndpoints` is set, `/_hmr` and `/_hmr_runtime.js` are checked
310
+ * before user websocket patterns so HMR upgrades are never captured by app routes.
311
+ * Production mode with only user handlers skips the HMR branch entirely.
312
+ */
313
+ wrapFetchWithWebSocketUpgrades(originalFetch, { serveHmrEndpoints }) {
314
+ const matchRoute = (pathname) => findWebSocketRoute(this.websocketHandlers, pathname);
315
+ const hmrManager = this.hmrManager;
316
+ const waitForInit = this.waitForInitialization.bind(this);
317
+ return async function(request, server) {
318
+ const url = new URL(request.url);
319
+ if (serveHmrEndpoints) {
200
320
  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 });
321
+ const success = this.upgrade(request, { data: { kind: "__hmr__", params: {}, search: {} } });
322
+ return success ? void 0 : new Response("WebSocket upgrade failed", { status: 400 });
206
323
  }
207
324
  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 });
325
+ await waitForInit();
326
+ const runtimeReady = await hmrManager.ensureRuntimeReady();
327
+ const runtimePath = hmrManager.getRuntimePath();
328
+ if (runtimeReady && fileSystem.exists(runtimePath)) {
329
+ return new Response(fileSystem.readFileAsBuffer(runtimePath), {
330
+ headers: { "Content-Type": "application/javascript" }
331
+ });
332
+ }
333
+ appLogger.warn(
334
+ `[HMR] Runtime script not found at ${runtimePath}; the HMR runtime build likely failed during startup.`
335
+ );
336
+ return new Response("Not Found", { status: 404 });
219
337
  }
220
- return response;
221
- };
222
- }
223
- return serverOptions;
338
+ }
339
+ const wsMatch = matchRoute(url.pathname);
340
+ if (wsMatch && request.headers.get("upgrade")?.toLowerCase() === "websocket") {
341
+ const search = Object.fromEntries(url.searchParams.entries());
342
+ const success = this.upgrade(request, {
343
+ data: { kind: wsMatch.kind, params: wsMatch.params, search, upgradeUrl: request.url }
344
+ });
345
+ return success ? void 0 : new Response("WebSocket upgrade failed", { status: 400 });
346
+ }
347
+ if (!originalFetch) {
348
+ return new Response("Not Found", { status: 404 });
349
+ }
350
+ const res = await originalFetch.call(this, request, server);
351
+ return res instanceof Response ? res : new Response("Not Found", { status: 404 });
352
+ };
224
353
  }
225
354
  /**
226
355
  * Helper method to retrieve and parse the request body.
@@ -306,9 +435,9 @@ class BunServerAdapter extends SharedServerAdapter {
306
435
  hmrManager: this.hmrManager
307
436
  });
308
437
  }
309
- const buildRuntimeOrigin = this.serverInstance ? `http://${this.serverInstance.hostname || DEFAULT_ECOPAGES_HOSTNAME}:${this.serverInstance.port || DEFAULT_ECOPAGES_PORT}` : void 0;
438
+ const buildRuntimeOrigin = resolveServeRuntimeOrigin(this.serveOptions);
310
439
  await this.staticBuilder.build(
311
- { ...options, preview: false, baseUrl: buildRuntimeOrigin },
440
+ { baseUrl: buildRuntimeOrigin, force: options?.force },
312
441
  {
313
442
  router: this.router,
314
443
  routeRendererFactory: this.routeRendererFactory,
@@ -316,19 +445,42 @@ class BunServerAdapter extends SharedServerAdapter {
316
445
  }
317
446
  );
318
447
  if (!options?.preview) {
319
- return;
448
+ return void 0;
449
+ }
450
+ return this.startPreviewServer();
451
+ }
452
+ /**
453
+ * Serves an existing static export without running SSG. Used by e2e preview
454
+ * launchers after a shared prewarm build.
455
+ */
456
+ async servePreviewOnly() {
457
+ if (!this.fullyInitialized) {
458
+ await this.initializeSharedRouteHandling({
459
+ staticRoutes: this.staticRoutes,
460
+ hmrManager: this.hmrManager
461
+ });
462
+ }
463
+ const distPath = path.join(this.appConfig.rootDir, this.appConfig.distDir);
464
+ if (!fileSystem.exists(distPath)) {
465
+ throw new Error(
466
+ `Cannot serve preview without building first: dist directory "${this.appConfig.distDir}" not found in "${this.appConfig.rootDir}".`
467
+ );
320
468
  }
469
+ return this.startPreviewServer();
470
+ }
471
+ async startPreviewServer() {
321
472
  const previewHostname = this.serveOptions.hostname || DEFAULT_ECOPAGES_HOSTNAME;
322
473
  const previewPort = Number(this.serveOptions.port || DEFAULT_ECOPAGES_PORT);
323
474
  const activePreviewPort = await this.previewHost.start({
324
475
  appConfig: this.appConfig,
325
476
  hostname: String(previewHostname),
326
- port: previewPort
477
+ port: previewPort,
478
+ allowPortFallback: this.allowPortFallback
327
479
  });
328
- if (activePreviewPort) {
329
- appLogger.info(`Preview running at http://${previewHostname}:${activePreviewPort}`);
330
- return;
480
+ if (!activePreviewPort) {
481
+ return void 0;
331
482
  }
483
+ return `http://${previewHostname}:${activePreviewPort}`;
332
484
  }
333
485
  /**
334
486
  * Initializes the server with dynamic routes after server creation.
@@ -362,6 +514,9 @@ class BunServerAdapter extends SharedServerAdapter {
362
514
  staticRoutes: this.staticRoutes,
363
515
  hmrManager: this.hmrManager
364
516
  });
517
+ if (this.options?.watch) {
518
+ await this.hmrManager.ensureRuntimeReady();
519
+ }
365
520
  this.fullyInitialized = true;
366
521
  if (this.options?.watch) await this.watch();
367
522
  if (server && typeof server.reload === "function") {
@@ -379,10 +534,34 @@ class BunServerAdapter extends SharedServerAdapter {
379
534
  return {
380
535
  getServerOptions: this.getServerOptions.bind(this),
381
536
  buildStatic: this.buildStatic.bind(this),
537
+ servePreviewOnly: this.servePreviewOnly.bind(this),
382
538
  completeInitialization: this.completeInitialization.bind(this),
383
- handleRequest: this.handleRequest.bind(this)
539
+ handleRequest: this.handleRequest.bind(this),
540
+ attachUserWebSocketUpgrades: this.attachUserWebSocketUpgrades.bind(this),
541
+ dispose: this.dispose.bind(this)
384
542
  };
385
543
  }
544
+ /**
545
+ * Releases dev-time resources owned by the adapter.
546
+ *
547
+ * @remarks
548
+ * Safe to call multiple times. Does not stop the bound Bun server — callers
549
+ * should shut down transport through the runtime host before disposing.
550
+ */
551
+ async dispose() {
552
+ if (this.adapterDisposed) {
553
+ return;
554
+ }
555
+ this.adapterDisposed = true;
556
+ await disposeDevResources({
557
+ projectWatcher: this.projectWatcher,
558
+ appConfig: this.appConfig,
559
+ hmrManager: this.hmrManager,
560
+ bridge: this.bridge,
561
+ previewHost: this.previewHost
562
+ });
563
+ this.projectWatcher = null;
564
+ }
386
565
  /**
387
566
  * Handles HTTP requests by passing them securely to the shared core router adapter.
388
567
  *
@@ -434,6 +613,8 @@ async function createBunServerAdapter(params) {
434
613
  const runtimeOrigin = params.runtimeOrigin ?? resolveServeRuntimeOrigin(params.serveOptions);
435
614
  const bridge = params.bridge ?? new ClientBridge();
436
615
  const hmrManager = params.hmrManager ?? new HmrManager({ appConfig: params.appConfig, bridge });
616
+ setAppDevClientBridge(params.appConfig, bridge);
617
+ setAppHmrManager(params.appConfig, hmrManager);
437
618
  const previewHost = params.previewHost ?? new BunStaticPreviewHost();
438
619
  const adapter = new BunServerAdapter({
439
620
  ...params,
@@ -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/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
- }
@@ -1,10 +1,10 @@
1
1
  import { AbstractApplicationAdapter } from "./abstract/application-adapter.js";
2
- import { SharedApplicationAdapter } from "./shared/application-adapter.js";
3
2
  import { createApp as createBunApp } from "./bun/create-app.js";
4
3
  import { createNodeApp } from "./node/create-app.js";
5
4
  async function createRuntimeApp(options) {
5
+ const adapter = options.adapter ?? "auto";
6
6
  const bun = globalThis.Bun;
7
- if (bun) {
7
+ if (adapter === "bun" || adapter === "auto" && bun) {
8
8
  return await createBunApp(options);
9
9
  }
10
10
  return await createNodeApp(options);
@@ -12,55 +12,6 @@ async function createRuntimeApp(options) {
12
12
  async function createApp(options) {
13
13
  return createRuntimeApp(options);
14
14
  }
15
- class EcopagesApp extends SharedApplicationAdapter {
16
- appOptions;
17
- runtimeApp = null;
18
- runtimeAppPromise = null;
19
- constructor(options) {
20
- super(options);
21
- this.appOptions = options;
22
- }
23
- async getRuntimeApp() {
24
- if (this.runtimeApp) {
25
- return this.runtimeApp;
26
- }
27
- if (!this.runtimeAppPromise) {
28
- this.runtimeAppPromise = createRuntimeApp({
29
- ...this.appOptions,
30
- clearOutput: false
31
- }).then((app) => {
32
- for (const handler of this.apiHandlers) {
33
- app.add(handler);
34
- }
35
- for (const route of this.staticRoutes) {
36
- app.static(route.path, route.loader);
37
- }
38
- if (this.errorHandler) {
39
- app.onError(this.errorHandler);
40
- }
41
- this.runtimeApp = app;
42
- return app;
43
- });
44
- }
45
- return this.runtimeAppPromise;
46
- }
47
- async initializeServerAdapter() {
48
- return this.getRuntimeApp();
49
- }
50
- async start() {
51
- const runtimeApp = await this.getRuntimeApp();
52
- return runtimeApp.start();
53
- }
54
- async fetch(request) {
55
- const runtimeApp = await this.getRuntimeApp();
56
- const candidate = runtimeApp;
57
- if (!candidate.fetch) {
58
- throw new Error("The selected runtime adapter does not expose fetch()");
59
- }
60
- return candidate.fetch(request);
61
- }
62
- }
63
15
  export {
64
- EcopagesApp,
65
16
  createApp
66
17
  };
@@ -1,2 +1,2 @@
1
- export { EcopagesApp, createApp } from './create-app.js';
1
+ export { createApp } from './create-app.js';
2
2
  export { defineApiHandler, defineGroupHandler, type GroupHandler } from './shared/define-api-handler.js';
@@ -1,7 +1,6 @@
1
- import { EcopagesApp, createApp } from "./create-app.js";
1
+ import { createApp } from "./create-app.js";
2
2
  import { defineApiHandler, defineGroupHandler } from "./shared/define-api-handler.js";
3
3
  export {
4
- EcopagesApp,
5
4
  createApp,
6
5
  defineApiHandler,
7
6
  defineGroupHandler