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

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/server-adapter.d.ts +90 -22
  13. package/src/adapters/bun/server-adapter.js +266 -84
  14. package/src/adapters/bun/static-preview-host.js +25 -20
  15. package/src/adapters/create-app.d.ts +13 -11
  16. package/src/adapters/create-app.js +2 -51
  17. package/src/adapters/index.d.ts +1 -1
  18. package/src/adapters/index.js +1 -2
  19. package/src/adapters/node/create-app.d.ts +5 -1
  20. package/src/adapters/node/create-app.js +51 -12
  21. package/src/adapters/node/node-client-bridge.d.ts +1 -0
  22. package/src/adapters/node/node-client-bridge.js +3 -0
  23. package/src/adapters/node/server-adapter-dependencies.js +4 -0
  24. package/src/adapters/node/server-adapter.d.ts +62 -20
  25. package/src/adapters/node/server-adapter.js +160 -131
  26. package/src/adapters/node/static-content-server.d.ts +1 -0
  27. package/src/adapters/node/static-content-server.js +10 -2
  28. package/src/adapters/node/static-preview-host.js +27 -12
  29. package/src/adapters/shared/bun-user-websocket-lifecycle.d.ts +22 -0
  30. package/src/adapters/shared/bun-user-websocket-lifecycle.js +96 -0
  31. package/src/adapters/shared/copy-runtime-public-dir.d.ts +6 -0
  32. package/src/adapters/shared/copy-runtime-public-dir.js +24 -0
  33. package/src/adapters/shared/fs-server-response-matcher.d.ts +2 -0
  34. package/src/adapters/shared/fs-server-response-matcher.js +40 -18
  35. package/src/adapters/shared/hmr-entrypoint-registrar.d.ts +21 -30
  36. package/src/adapters/shared/hmr-entrypoint-registrar.js +49 -54
  37. package/src/adapters/shared/hmr-html-response.d.ts +1 -1
  38. package/src/adapters/shared/hmr-html-response.js +4 -1
  39. package/src/adapters/shared/node-http-websocket-upgrades.d.ts +21 -0
  40. package/src/adapters/shared/node-http-websocket-upgrades.js +100 -0
  41. package/src/adapters/shared/port-manager.d.ts +116 -0
  42. package/src/adapters/shared/port-manager.js +196 -0
  43. package/src/adapters/shared/runtime-app-bootstrap.d.ts +2 -1
  44. package/src/adapters/shared/runtime-app-bootstrap.js +3 -6
  45. package/src/adapters/shared/runtime-server-lifecycle.d.ts +46 -0
  46. package/src/adapters/shared/runtime-server-lifecycle.js +50 -0
  47. package/src/adapters/shared/server-adapter.d.ts +2 -1
  48. package/src/adapters/shared/server-adapter.js +13 -6
  49. package/src/adapters/shared/server-route-handler.d.ts +4 -1
  50. package/src/adapters/shared/server-route-handler.js +5 -2
  51. package/src/adapters/shared/server-static-builder.d.ts +23 -32
  52. package/src/adapters/shared/server-static-builder.js +100 -73
  53. package/src/adapters/shared/shared-hmr-manager.d.ts +45 -11
  54. package/src/adapters/shared/shared-hmr-manager.js +204 -58
  55. package/src/adapters/shared/static-preview-host.d.ts +5 -0
  56. package/src/adapters/shared/websocket-lifecycle.d.ts +24 -0
  57. package/src/adapters/shared/websocket-lifecycle.js +55 -0
  58. package/src/build/README.md +77 -14
  59. package/src/build/app-build-manifest-runtime.d.ts +9 -0
  60. package/src/build/app-build-manifest-runtime.js +87 -0
  61. package/src/build/build-adapter.d.ts +17 -319
  62. package/src/build/build-adapter.js +28 -94
  63. package/src/build/build-contracts.d.ts +97 -0
  64. package/src/build/build-contracts.js +0 -0
  65. package/src/build/build-input-fingerprint.d.ts +28 -0
  66. package/src/build/build-input-fingerprint.js +31 -0
  67. package/src/build/build-profile-options.d.ts +7 -0
  68. package/src/build/build-profile-options.js +37 -0
  69. package/src/build/build-runtime.d.ts +24 -0
  70. package/src/build/build-runtime.js +65 -0
  71. package/src/build/deduping-build-executor.d.ts +28 -0
  72. package/src/build/deduping-build-executor.js +56 -0
  73. package/src/build/jsx-ownership-plugins.d.ts +24 -0
  74. package/src/build/jsx-ownership-plugins.js +41 -0
  75. package/src/build/pages-unified-graph-build.d.ts +31 -0
  76. package/src/build/pages-unified-graph-build.js +206 -0
  77. package/src/build/parallel-build-executor.d.ts +21 -0
  78. package/src/build/parallel-build-executor.js +52 -0
  79. package/src/build/production-build-cache.d.ts +20 -0
  80. package/src/build/production-build-cache.js +63 -0
  81. package/src/build/rolldown-adapter-helpers.d.ts +3 -6
  82. package/src/build/rolldown-adapter-helpers.js +71 -6
  83. package/src/build/rolldown-build-adapter.d.ts +2 -6
  84. package/src/build/rolldown-build-adapter.js +3 -3
  85. package/src/build/rolldown-build-invocation-metrics.d.ts +12 -0
  86. package/src/build/rolldown-build-invocation-metrics.js +43 -0
  87. package/src/build/rolldown-plugin-bridge.d.ts +15 -1
  88. package/src/build/rolldown-plugin-bridge.js +20 -5
  89. package/src/build/rolldown-source-transform-pass.d.ts +15 -0
  90. package/src/build/rolldown-source-transform-pass.js +58 -0
  91. package/src/build/runtime-build-executor.d.ts +8 -15
  92. package/src/build/runtime-build-executor.js +12 -15
  93. package/src/build/runtime-build-output-normalizer.d.ts +7 -0
  94. package/src/build/runtime-build-output-normalizer.js +94 -2
  95. package/src/build/server-entry-build-cache.d.ts +44 -0
  96. package/src/build/server-entry-build-cache.js +161 -0
  97. package/src/client/navigation-scripts/classification.d.ts +16 -0
  98. package/src/client/navigation-scripts/classification.js +41 -0
  99. package/src/client/navigation-scripts/index.d.ts +3 -0
  100. package/src/client/navigation-scripts/index.js +23 -0
  101. package/src/client/navigation-scripts/navigation-scripts.test.browser.js +65 -0
  102. package/src/client/navigation-scripts/registry.d.ts +11 -0
  103. package/src/client/navigation-scripts/registry.js +12 -0
  104. package/src/client/navigation-scripts/rerun-queue.d.ts +37 -0
  105. package/src/client/navigation-scripts/rerun-queue.js +73 -0
  106. package/src/client/scroll.d.ts +17 -0
  107. package/src/client/scroll.js +25 -0
  108. package/src/client/scroll.test.browser.js +37 -0
  109. package/src/client/view-transitions.d.ts +16 -0
  110. package/src/client/view-transitions.js +63 -0
  111. package/src/config/config-builder.d.ts +12 -7
  112. package/src/config/config-builder.js +12 -9
  113. package/src/dev/client-bridge-registry.d.ts +5 -0
  114. package/src/dev/client-bridge-registry.js +15 -0
  115. package/src/dev/dev-client-ownership.d.ts +7 -0
  116. package/src/dev/dev-client-ownership.js +6 -0
  117. package/src/dev/hmr-manager-registry.d.ts +8 -0
  118. package/src/dev/hmr-manager-registry.js +15 -0
  119. package/src/dev/host-runtime.d.ts +3 -0
  120. package/src/dev/host-runtime.js +7 -0
  121. package/src/dev/runtime-server-started-message.d.ts +2 -0
  122. package/src/dev/runtime-server-started-message.js +6 -0
  123. package/src/eco/README.md +11 -0
  124. package/src/eco/eco-declared-component.d.ts +14 -0
  125. package/src/eco/eco-declared-component.js +16 -0
  126. package/src/eco/eco.browser.js +5 -6
  127. package/src/eco/eco.js +5 -6
  128. package/src/eco/eco.types.d.ts +2 -2
  129. package/src/eco/page-layout-normalization.d.ts +21 -0
  130. package/src/eco/page-layout-normalization.js +59 -0
  131. package/src/errors/index.d.ts +1 -0
  132. package/src/errors/index.js +7 -1
  133. package/src/errors/undeclared-component-dependency-error.d.ts +11 -0
  134. package/src/errors/undeclared-component-dependency-error.js +17 -0
  135. package/src/hmr/client/hmr-runtime.js +5 -2
  136. package/src/hmr/hmr-entrypoint-output.d.ts +43 -0
  137. package/src/hmr/hmr-entrypoint-output.js +53 -0
  138. package/src/hmr/hmr-strategy.d.ts +15 -0
  139. package/src/hmr/hmr-strategy.js +19 -0
  140. package/src/hmr/strategies/js-hmr-strategy.d.ts +3 -5
  141. package/src/hmr/strategies/js-hmr-strategy.js +67 -19
  142. package/src/hmr/strategies/server-rendered-template-hmr-strategy.d.ts +17 -0
  143. package/src/hmr/strategies/server-rendered-template-hmr-strategy.js +29 -0
  144. package/src/integrations/ghtml/ghtml-renderer.d.ts +2 -6
  145. package/src/integrations/ghtml/ghtml-renderer.js +2 -51
  146. package/src/integrations/ghtml/ghtml.plugin.d.ts +3 -16
  147. package/src/integrations/ghtml/ghtml.plugin.js +7 -14
  148. package/src/plugins/define-integration.d.ts +26 -0
  149. package/src/plugins/define-integration.js +19 -0
  150. package/src/plugins/eco-component-meta-plugin.js +5 -8
  151. package/src/plugins/foreign-jsx-override-plugin.js +4 -6
  152. package/src/plugins/integration-plugin.d.ts +19 -9
  153. package/src/plugins/integration-plugin.js +7 -4
  154. package/src/plugins/jsx-import-source.utils.d.ts +8 -0
  155. package/src/plugins/jsx-import-source.utils.js +26 -0
  156. package/src/plugins/processor.d.ts +19 -4
  157. package/src/plugins/processor.js +22 -4
  158. package/src/plugins/source-transform.d.ts +31 -0
  159. package/src/plugins/source-transform.js +23 -1
  160. package/src/route-renderer/GRAPH.md +8 -8
  161. package/src/route-renderer/README.md +30 -28
  162. package/src/route-renderer/orchestration/component-graph-collectors.d.ts +10 -0
  163. package/src/route-renderer/orchestration/component-graph-collectors.js +143 -0
  164. package/src/route-renderer/orchestration/component-graph.d.ts +36 -0
  165. package/src/route-renderer/orchestration/component-graph.js +98 -0
  166. package/src/route-renderer/orchestration/component-render-context.d.ts +3 -10
  167. package/src/route-renderer/orchestration/component-render-context.js +3 -1
  168. package/src/route-renderer/orchestration/declared-ownership-graph.d.ts +1 -18
  169. package/src/route-renderer/orchestration/declared-ownership-graph.js +5 -31
  170. package/src/route-renderer/orchestration/document-shell-render.service.d.ts +90 -0
  171. package/src/route-renderer/orchestration/document-shell-render.service.js +120 -0
  172. package/src/route-renderer/orchestration/foreign-subtree-execution.service.d.ts +59 -29
  173. package/src/route-renderer/orchestration/foreign-subtree-execution.service.js +164 -35
  174. package/src/route-renderer/orchestration/global-injector-assets.service.d.ts +7 -0
  175. package/src/route-renderer/orchestration/global-injector-assets.service.js +32 -0
  176. package/src/route-renderer/orchestration/integration-renderer.d.ts +18 -54
  177. package/src/route-renderer/orchestration/integration-renderer.js +113 -195
  178. package/src/route-renderer/orchestration/integration-route-render-adapter.d.ts +38 -0
  179. package/src/route-renderer/orchestration/integration-route-render-adapter.js +27 -0
  180. package/src/route-renderer/orchestration/layout-shell-props.service.d.ts +20 -0
  181. package/src/route-renderer/orchestration/layout-shell-props.service.js +31 -0
  182. package/src/route-renderer/orchestration/ownership-validation.service.d.ts +5 -0
  183. package/src/route-renderer/orchestration/ownership-validation.service.js +29 -1
  184. package/src/route-renderer/orchestration/page-browser-graph-contribution.loader.d.ts +9 -0
  185. package/src/route-renderer/orchestration/page-browser-graph-contribution.loader.js +7 -0
  186. package/src/route-renderer/orchestration/page-browser-graph.service.d.ts +25 -0
  187. package/src/route-renderer/orchestration/page-browser-graph.service.js +174 -0
  188. package/src/route-renderer/orchestration/render-output.utils.d.ts +2 -0
  189. package/src/route-renderer/orchestration/render-output.utils.js +4 -0
  190. package/src/route-renderer/orchestration/route-html-finalization.service.d.ts +17 -0
  191. package/src/route-renderer/orchestration/route-html-finalization.service.js +26 -0
  192. package/src/route-renderer/orchestration/route-prepared-options.builder.d.ts +26 -0
  193. package/src/route-renderer/orchestration/route-prepared-options.builder.js +54 -0
  194. package/src/route-renderer/orchestration/route-prepared-options.utils.d.ts +4 -0
  195. package/src/route-renderer/orchestration/route-prepared-options.utils.js +33 -0
  196. package/src/route-renderer/orchestration/route-render-orchestrator.d.ts +8 -39
  197. package/src/route-renderer/orchestration/route-render-orchestrator.js +53 -461
  198. package/src/route-renderer/orchestration/string-markup-renderer.d.ts +14 -0
  199. package/src/route-renderer/orchestration/string-markup-renderer.js +55 -0
  200. package/src/route-renderer/page-loading/component-dependency-collection.js +5 -2
  201. package/src/router/client/link-intent.d.ts +11 -21
  202. package/src/router/client/link-intent.js +10 -0
  203. package/src/router/client/link-intent.test.browser.js +12 -1
  204. package/src/router/client/link-navigation-policy.d.ts +45 -0
  205. package/src/router/client/link-navigation-policy.js +101 -0
  206. package/src/router/client/link-navigation-policy.test.browser.d.ts +1 -0
  207. package/src/router/client/link-navigation-policy.test.browser.js +92 -0
  208. package/src/router/client/navigation-coordinator.d.ts +1 -1
  209. package/src/router/client/navigation-coordinator.js +12 -2
  210. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.d.ts +1 -0
  211. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +1 -0
  212. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.d.ts +4 -2
  213. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.js +27 -7
  214. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.d.ts +0 -1
  215. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +18 -15
  216. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +17 -3
  217. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.d.ts +0 -3
  218. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +2 -31
  219. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.d.ts +0 -3
  220. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +2 -30
  221. package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.d.ts +2 -0
  222. package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.js +43 -0
  223. package/src/services/assets/browser-bundle.service.d.ts +3 -1
  224. package/src/services/assets/browser-bundle.service.js +17 -5
  225. package/src/services/html/html-transformer.service.d.ts +1 -1
  226. package/src/services/html/html-transformer.service.js +4 -4
  227. package/src/services/invalidation/development-invalidation.service.d.ts +20 -2
  228. package/src/services/invalidation/development-invalidation.service.js +56 -2
  229. package/src/services/module-loading/README.md +49 -0
  230. package/src/services/module-loading/app-server-module-transpiler.service.js +5 -17
  231. package/src/services/module-loading/page-module-import.service.d.ts +5 -1
  232. package/src/services/module-loading/page-module-import.service.js +96 -45
  233. package/src/services/module-loading/route-module-build-cache-registry.d.ts +24 -0
  234. package/src/services/module-loading/route-module-build-cache-registry.js +37 -0
  235. package/src/services/module-loading/route-module-build-cache.d.ts +4 -0
  236. package/src/services/module-loading/route-module-build-cache.js +38 -0
  237. package/src/services/module-loading/route-module-build-cache.store.d.ts +57 -0
  238. package/src/services/module-loading/route-module-build-cache.store.js +207 -0
  239. package/src/services/module-loading/route-module-build-manifest.d.ts +61 -0
  240. package/src/services/module-loading/route-module-build-manifest.js +116 -0
  241. package/src/services/module-loading/route-module-dependency-hasher.d.ts +81 -0
  242. package/src/services/module-loading/route-module-dependency-hasher.js +122 -0
  243. package/src/services/module-loading/server-module-transpiler.service.js +1 -1
  244. package/src/static-site-generator/README.md +33 -0
  245. package/src/static-site-generator/static-build-invalidation.d.ts +10 -0
  246. package/src/static-site-generator/static-build-invalidation.js +59 -0
  247. package/src/static-site-generator/static-export-context.d.ts +22 -0
  248. package/src/static-site-generator/static-export-context.js +0 -0
  249. package/src/static-site-generator/static-site-generator.d.ts +17 -20
  250. package/src/static-site-generator/static-site-generator.js +188 -85
  251. package/src/types/internal-types.d.ts +16 -9
  252. package/src/types/public-types.d.ts +144 -40
  253. package/src/utils/parse-cli-args.d.ts +2 -0
  254. package/src/utils/parse-cli-args.js +6 -0
  255. package/src/utils/server-utils.module.d.ts +3 -2
  256. package/src/utils/server-utils.module.js +5 -6
  257. package/src/utils/static-file-extensions.d.ts +12 -0
  258. package/src/utils/static-file-extensions.js +48 -0
  259. package/src/watchers/project-watcher-ignore.d.ts +11 -0
  260. package/src/watchers/project-watcher-ignore.js +16 -0
  261. package/src/watchers/project-watcher.d.ts +26 -3
  262. package/src/watchers/project-watcher.js +132 -30
  263. package/src/watchers/project-watcher.test-helpers.js +5 -5
  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,53 +1,66 @@
1
1
  import path from "node:path";
2
2
  import { fileSystem } from "@ecopages/file-system";
3
3
  import { DEFAULT_ECOPAGES_HOSTNAME, DEFAULT_ECOPAGES_PORT } from "../../config/constants.js";
4
- import { StaticContentServer } from "../../dev/sc-server.js";
5
4
  import { appLogger } from "../../global/app-logger.js";
6
- import { getAppBuildAdapter } from "../../build/build-adapter.js";
7
- import { resolveEntryFile, SERVER_BUNDLE_DIR, SERVER_BUNDLE_FILENAME } from "../../utils/resolve-entry-file.js";
5
+ import { build, getAppBuildAdapter, setupAppRuntimePlugins } from "../../build/build-adapter.js";
6
+ import { attachHmrToIntegrations } from "./runtime-server-lifecycle.js";
7
+ import { resolveBuildProfileOptions } from "../../build/build-profile-options.js";
8
+ import {
9
+ getServerBundleOutputPaths,
10
+ lookupServerEntryBuildCache,
11
+ recordServerEntryBuildCache,
12
+ writeServerBundleDeployManifest
13
+ } from "../../build/server-entry-build-cache.js";
14
+ import { getInstalledServerEntryBuildExecutor } from "../../build/runtime-build-executor.js";
15
+ import {
16
+ clearProductionBuildCaches,
17
+ shouldResetStaticExportDirectory
18
+ } from "../../static-site-generator/static-build-invalidation.js";
19
+ import { resolveEntryFile, SERVER_BUNDLE_FILENAME } from "../../utils/resolve-entry-file.js";
8
20
  class ServerStaticBuilder {
9
21
  appConfig;
10
22
  staticSiteGenerator;
11
23
  serveOptions;
12
- apiHandlers;
24
+ runtimeOrigin;
25
+ needsServerBundle;
13
26
  logger;
14
- previewServerFactory;
15
27
  entryFile;
28
+ hmrManager;
29
+ onRuntimePlugin;
16
30
  constructor({
17
31
  appConfig,
18
32
  staticSiteGenerator,
19
33
  serveOptions,
20
- apiHandlers,
34
+ runtimeOrigin,
35
+ needsServerBundle,
21
36
  logger,
22
- previewServerFactory,
23
- entryFile
37
+ entryFile,
38
+ hmrManager,
39
+ onRuntimePlugin
24
40
  }) {
25
41
  this.appConfig = appConfig;
26
42
  this.staticSiteGenerator = staticSiteGenerator;
27
43
  this.serveOptions = serveOptions;
28
- this.apiHandlers = apiHandlers ?? [];
44
+ this.runtimeOrigin = runtimeOrigin;
45
+ this.needsServerBundle = needsServerBundle ?? false;
29
46
  this.logger = logger ?? appLogger;
30
- this.previewServerFactory = previewServerFactory ?? StaticContentServer;
31
47
  this.entryFile = resolveEntryFile({ entryFile });
48
+ this.hmrManager = hmrManager;
49
+ this.onRuntimePlugin = onRuntimePlugin;
32
50
  }
33
- warnApiHandlersUnavailableInStaticMode() {
34
- if (this.apiHandlers.length === 0) {
35
- return;
51
+ prepareExportDirectory(force) {
52
+ if (force) {
53
+ clearProductionBuildCaches(this.appConfig);
36
54
  }
37
- const uniqueHandlers = Array.from(
38
- new Set(this.apiHandlers.map((handler) => `${handler.method} ${handler.path}`))
39
- );
40
- const visibleHandlers = uniqueHandlers.slice(0, 5).join(", ");
41
- const remainingCount = uniqueHandlers.length - Math.min(uniqueHandlers.length, 5);
42
- const summary = remainingCount > 0 ? `${visibleHandlers}, +${remainingCount} more` : visibleHandlers;
43
- this.logger.warn(
44
- "Registered API endpoints are not available in static build or preview modes because no server runtime is started. They are excluded from the generated output.\n",
45
- `\u27A4 ${summary}`
46
- );
47
- }
48
- prepareExportDirectory() {
49
55
  const exportDir = this.appConfig.absolutePaths?.distDir ?? path.join(this.appConfig.rootDir, this.appConfig.distDir);
50
- fileSystem.ensureDir(exportDir, true);
56
+ const shouldCleanDist = shouldResetStaticExportDirectory(this.appConfig, force);
57
+ fileSystem.ensureDir(exportDir, shouldCleanDist);
58
+ if (shouldCleanDist) {
59
+ this.appConfig.runtime = {
60
+ ...this.appConfig.runtime ?? {},
61
+ runtimeAssetsPrepared: false
62
+ };
63
+ }
51
64
  const srcPublicDir = path.join(
52
65
  this.appConfig.rootDir,
53
66
  this.appConfig.srcDir ?? "src",
@@ -56,39 +69,42 @@ class ServerStaticBuilder {
56
69
  if (fileSystem.exists(srcPublicDir)) {
57
70
  fileSystem.copyDir(srcPublicDir, exportDir);
58
71
  }
72
+ return !shouldCleanDist;
59
73
  }
60
74
  async refreshRuntimeAssets() {
61
- for (const processor of this.appConfig.processors.values()) {
62
- await processor.setup();
63
- }
64
- for (const integration of this.appConfig.integrations) {
65
- await integration.setup();
75
+ appLogger.debugTime("refreshRuntimeAssets");
76
+ try {
77
+ await setupAppRuntimePlugins({
78
+ appConfig: this.appConfig,
79
+ runtimeOrigin: this.runtimeOrigin,
80
+ onRuntimePlugin: this.onRuntimePlugin
81
+ });
82
+ if (this.hmrManager?.isEnabled()) {
83
+ attachHmrToIntegrations(this.appConfig, this.hmrManager);
84
+ }
85
+ } finally {
86
+ appLogger.debugTimeEnd("refreshRuntimeAssets");
66
87
  }
67
88
  }
68
89
  /**
69
90
  * Bundles the server entry file for production use.
70
91
  *
71
92
  * @remarks
72
- * When the project has API endpoints, the entry file must be bundled
73
- * into a single JS file so the production server can start without
74
- * on-the-fly TypeScript transpilation. The bundle is output to
75
- * `dist/{SERVER_BUNDLE_DIR}/{SERVER_BUNDLE_FILENAME}` and used by
76
- * `ecopages start` in production.
93
+ * Only invoked when the app requires a runtime server (API handlers,
94
+ * websocket handlers, etc.). Static-only apps skip this step entirely.
95
+ * Incremental builds may skip Rolldown when the `.eco/.server-entry`
96
+ * cache is still valid.
77
97
  *
78
98
  * Package imports remain external so native addons and runtime-owned
79
99
  * dependencies continue to load through the app's installed
80
100
  * `node_modules` tree. Only the app entry graph is bundled.
81
101
  *
82
- * Skips silently when no API endpoints are registered (static-only site).
83
102
  * Throws if the build adapter is unavailable, is owned by a host
84
103
  * runtime, or bundling fails.
85
104
  *
86
105
  * @throws If the build adapter is unavailable, is host-owned, or bundling fails.
87
106
  */
88
- async bundleServerEntry() {
89
- if (this.apiHandlers.length === 0) {
90
- return;
91
- }
107
+ async bundleServerEntry(options) {
92
108
  const buildAdapter = getAppBuildAdapter(this.appConfig);
93
109
  if (buildAdapter.ownership === "vite-host") {
94
110
  throw new Error(
@@ -101,60 +117,71 @@ class ServerStaticBuilder {
101
117
  `Cannot bundle server entry: file "${this.entryFile}" not found in "${this.appConfig.rootDir}".`
102
118
  );
103
119
  }
104
- const distDir = this.appConfig.absolutePaths?.distDir ?? path.join(this.appConfig.rootDir, this.appConfig.distDir);
105
- const serverOutdir = path.join(distDir, SERVER_BUNDLE_DIR);
106
- this.logger.info("Bundling server entry file...");
107
- const result = await buildAdapter.build({
108
- entrypoints: [entryPath],
109
- outdir: serverOutdir,
110
- naming: SERVER_BUNDLE_FILENAME,
111
- target: "node",
112
- format: "esm",
113
- sourcemap: "hidden",
114
- externalPackages: true,
115
- root: this.appConfig.rootDir
120
+ const { serverOutdir, serverEntryPath } = getServerBundleOutputPaths(this.appConfig);
121
+ const cached = lookupServerEntryBuildCache({
122
+ appConfig: this.appConfig,
123
+ entryPath,
124
+ force: options?.force
116
125
  });
126
+ if (cached) {
127
+ const hasBundle = cached.outputPaths.some(
128
+ (outputPath) => path.resolve(outputPath) === path.resolve(serverEntryPath) && fileSystem.exists(outputPath)
129
+ );
130
+ if (hasBundle) {
131
+ this.logger.info("Reusing cached server entry bundle");
132
+ writeServerBundleDeployManifest(this.appConfig, serverEntryPath);
133
+ return;
134
+ }
135
+ }
136
+ this.logger.info("Bundling server entry file...");
137
+ const buildOptions = {
138
+ ...resolveBuildProfileOptions("server-entry", this.appConfig, {
139
+ entrypoints: [entryPath],
140
+ outdir: serverOutdir,
141
+ naming: SERVER_BUNDLE_FILENAME,
142
+ sourcemap: "hidden"
143
+ }),
144
+ entrypoints: [entryPath]
145
+ };
146
+ const result = await build(buildOptions, getInstalledServerEntryBuildExecutor(this.appConfig));
117
147
  if (!result.success) {
118
148
  const errorMessages = result.logs.map((log) => log.message).join("\n");
119
149
  throw new Error(`Failed to bundle server entry file:
120
150
  ${errorMessages}`);
121
151
  }
152
+ const outputPaths = result.outputs.length > 0 ? result.outputs.map((output) => output.path) : fileSystem.exists(serverEntryPath) ? [serverEntryPath] : [];
153
+ recordServerEntryBuildCache({
154
+ appConfig: this.appConfig,
155
+ entryPath,
156
+ buildResult: result,
157
+ outputPaths
158
+ });
159
+ writeServerBundleDeployManifest(this.appConfig, serverEntryPath);
122
160
  this.logger.info("Server entry file bundled successfully");
123
161
  }
124
162
  /**
125
163
  * Generates a static build of the site for deployment.
126
- * @param options.preview - If true, starts a preview server after build
127
164
  * @param dependencies.router - The initialized router
128
165
  * @param dependencies.routeRendererFactory - The route renderer factory
129
166
  * @param dependencies.staticRoutes - Explicit static routes registered via app.static()
130
167
  */
131
168
  async build(options, dependencies) {
132
- const { preview = false, baseUrl: explicitBaseUrl } = options ?? {};
169
+ const { baseUrl: explicitBaseUrl, force = false } = options ?? {};
133
170
  const baseUrl = explicitBaseUrl ?? `http://${this.serveOptions.hostname || DEFAULT_ECOPAGES_HOSTNAME}:${this.serveOptions.port || DEFAULT_ECOPAGES_PORT}`;
134
- this.warnApiHandlersUnavailableInStaticMode();
135
- this.prepareExportDirectory();
171
+ const preserveExportDirectory = this.prepareExportDirectory(force);
136
172
  await this.refreshRuntimeAssets();
137
- await this.bundleServerEntry();
173
+ if (this.needsServerBundle) {
174
+ await this.bundleServerEntry({ force });
175
+ }
138
176
  await this.staticSiteGenerator.run({
139
177
  router: dependencies.router,
140
178
  baseUrl,
141
179
  routeRendererFactory: dependencies.routeRendererFactory,
142
- staticRoutes: dependencies.staticRoutes
180
+ staticRoutes: dependencies.staticRoutes,
181
+ force,
182
+ preserveExportDirectory
143
183
  });
144
- if (!preview) {
145
- this.logger.info("Build completed");
146
- return;
147
- }
148
- const previewPort = this.serveOptions.port || DEFAULT_ECOPAGES_PORT;
149
- const { server } = this.previewServerFactory.createServer({
150
- appConfig: this.appConfig,
151
- options: { port: Number(previewPort) }
152
- });
153
- if (server?.port) {
154
- this.logger.info(`Preview running at http://localhost:${server.port}`);
155
- } else {
156
- this.logger.error("Failed to start preview server");
157
- }
184
+ this.logger.info("Build completed");
158
185
  }
159
186
  }
160
187
  export {
@@ -1,7 +1,8 @@
1
1
  import fs from 'node:fs';
2
+ import { type ResolvedHmrEntrypoint } from '../../hmr/hmr-entrypoint-output.js';
2
3
  import type { DefaultHmrContext, EcoPagesAppConfig, IHmrManager, IClientBridge } from '../../types/internal-types.js';
3
- import type { EcoBuildPlugin } from '../../build/build-types.js';
4
4
  import { type HmrStrategy } from '../../hmr/hmr-strategy.js';
5
+ import { DevelopmentInvalidationService } from '../../services/invalidation/development-invalidation.service.js';
5
6
  import type { ClientBridgeEvent } from '../../types/public-types.js';
6
7
  import { HmrEntrypointRegistrar } from './hmr-entrypoint-registrar.js';
7
8
  import { BrowserBundleService } from '../../services/assets/browser-bundle.service.js';
@@ -13,23 +14,22 @@ type HandleFileChangeOptions = {
13
14
  type SharedHmrManagerParams = {
14
15
  appConfig: EcoPagesAppConfig;
15
16
  bridge: IClientBridge;
16
- registrationTimeoutMs?: number;
17
17
  };
18
18
  export declare abstract class SharedHmrManager implements IHmrManager {
19
19
  readonly appConfig: EcoPagesAppConfig;
20
20
  protected readonly bridge: IClientBridge;
21
21
  protected watchers: Map<string, fs.FSWatcher>;
22
- protected watchedFiles: Map<string, string>;
23
- protected entrypointRegistrations: Map<string, Promise<string>>;
24
22
  protected distDir: string;
25
- protected plugins: EcoBuildPlugin[];
26
23
  protected enabled: boolean;
27
24
  protected strategies: HmrStrategy[];
28
25
  protected readonly entrypointRegistrar: HmrEntrypointRegistrar;
29
26
  protected readonly browserBundleService: BrowserBundleService;
27
+ protected readonly invalidationService: DevelopmentInvalidationService;
30
28
  protected readonly entrypointDependencyGraph: EntrypointDependencyGraph;
31
29
  protected readonly serverModuleTranspiler: ServerModuleTranspiler;
32
- constructor({ appConfig, bridge, registrationTimeoutMs }: SharedHmrManagerParams);
30
+ private runtimeBuildPromise;
31
+ private runtimeReady;
32
+ constructor({ appConfig, bridge }: SharedHmrManagerParams);
33
33
  protected abstract createEntrypointDependencyGraph(existingEntrypointDependencyGraph: EntrypointDependencyGraph): EntrypointDependencyGraph;
34
34
  protected shouldSkipMissingFileChange(_filePath: string): boolean;
35
35
  protected onRuntimeBundleFailure(error: unknown): void;
@@ -37,23 +37,57 @@ export declare abstract class SharedHmrManager implements IHmrManager {
37
37
  protected shouldJsStrategyProcessEntrypoint(entrypointPath: string): boolean;
38
38
  protected initializeStrategies(): void;
39
39
  registerStrategy(strategy: HmrStrategy): void;
40
- setPlugins(plugins: EcoBuildPlugin[]): void;
41
40
  setEnabled(enabled: boolean): void;
42
41
  isEnabled(): boolean;
42
+ isRuntimeReady(): boolean;
43
+ /**
44
+ * Builds the browser HMR runtime once per manager session and reuses the in-flight build for concurrent callers.
45
+ */
46
+ ensureRuntimeReady(): Promise<boolean>;
43
47
  buildRuntime(): Promise<void>;
44
48
  getRuntimePath(): string;
49
+ private buildRuntimeInternal;
45
50
  broadcast(event: ClientBridgeEvent): void;
46
51
  handleFileChange(filePath: string, options?: HandleFileChangeOptions): Promise<void>;
52
+ private getStrategiesByPriority;
53
+ private selectChangeStrategy;
54
+ private selectEntrypointEmitter;
55
+ protected createUnownedEntrypointError(entrypointPath: string): Error;
56
+ /**
57
+ * Materializes one integration-owned page entrypoint during cold registration.
58
+ *
59
+ * @remarks
60
+ * Registration uses {@link HmrStrategy.canEmitEntrypoint} / {@link HmrStrategy.emitEntrypoint},
61
+ * not {@link HmrStrategy.matches} / {@link HmrStrategy.process}. File-change handling stays
62
+ * on `handleFileChange()`.
63
+ */
64
+ emitIntegrationEntrypoint(entrypointPath: string, outputPath: string): Promise<void>;
65
+ /**
66
+ * Runs server invalidation and integration hooks before rebuilding a registered script entrypoint.
67
+ *
68
+ * @remarks
69
+ * Browser-only `*.script.ts` entrypoints skip server module invalidation and bypass-cache
70
+ * import; only integration change handlers and the downstream strategy rebuild run.
71
+ */
72
+ private prepareRegisteredScriptChange;
47
73
  getOutputUrl(entrypointPath: string): string | undefined;
74
+ /**
75
+ * Returns the emitted HMR script output when the entrypoint is already registered
76
+ * and its browser bundle exists on disk.
77
+ *
78
+ * @remarks
79
+ * Disk artifacts alone are not enough: a fresh dev session must still register
80
+ * the entrypoint so file watchers can rebuild it on change.
81
+ */
82
+ getResolvedScriptOutput(entrypointPath: string): ResolvedHmrEntrypoint | undefined;
48
83
  getWatchedFiles(): Map<string, string>;
49
84
  getDistDir(): string;
50
- getPlugins(): EcoBuildPlugin[];
51
85
  getDefaultContext(): DefaultHmrContext;
86
+ stop(): void;
52
87
  protected clearFailedEntrypointRegistration(entrypointPath: string): void;
53
88
  registerEntrypoint(entrypointPath: string): Promise<string>;
54
- registerScriptEntrypoint(entrypointPath: string): Promise<string>;
55
- protected emitStrictEntrypoint(entrypointPath: string): Promise<void>;
89
+ registerScriptEntrypoint(entrypointPath: string): Promise<ResolvedHmrEntrypoint>;
56
90
  protected emitScriptEntrypoint(entrypointPath: string, outputPath: string): Promise<void>;
57
- stop(): void;
91
+ [Symbol.dispose](): void;
58
92
  }
59
93
  export {};