@ecopages/core 0.2.0-beta.4 → 0.2.0-beta.40

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 (611) hide show
  1. package/README.md +40 -9
  2. package/package.json +371 -33
  3. package/src/adapters/README.md +6 -2
  4. package/src/adapters/abstract/application-adapter.d.ts +115 -6
  5. package/src/adapters/abstract/application-adapter.js +261 -120
  6. package/src/adapters/abstract/router-adapter.js +12 -4
  7. package/src/adapters/abstract/segment-path-matcher.d.ts +6 -0
  8. package/src/adapters/abstract/segment-path-matcher.js +147 -0
  9. package/src/adapters/abstract/server-adapter.d.ts +16 -2
  10. package/src/adapters/abstract/server-adapter.js +22 -14
  11. package/src/adapters/abstract/ws-pattern-matcher.d.ts +12 -0
  12. package/src/adapters/abstract/ws-pattern-matcher.js +28 -0
  13. package/src/adapters/bun/bun-user-websocket-lifecycle.d.ts +22 -0
  14. package/src/adapters/bun/bun-user-websocket-lifecycle.js +93 -0
  15. package/src/adapters/bun/client-bridge.d.ts +1 -0
  16. package/src/adapters/bun/client-bridge.js +51 -47
  17. package/src/adapters/bun/create-app.d.ts +9 -6
  18. package/src/adapters/bun/create-app.js +171 -130
  19. package/src/adapters/bun/hmr-manager.d.ts +1 -1
  20. package/src/adapters/bun/hmr-manager.js +62 -57
  21. package/src/adapters/bun/index.d.ts +1 -1
  22. package/src/adapters/bun/index.js +2 -8
  23. package/src/adapters/bun/runtime-host.d.ts +1 -1
  24. package/src/adapters/bun/runtime-host.js +61 -54
  25. package/src/adapters/bun/server-adapter.d.ts +91 -41
  26. package/src/adapters/bun/server-adapter.js +566 -426
  27. package/src/adapters/bun/static-preview-host.d.ts +1 -1
  28. package/src/adapters/bun/static-preview-host.js +43 -41
  29. package/src/adapters/create-app.d.ts +13 -11
  30. package/src/adapters/create-app.js +11 -63
  31. package/src/adapters/index.d.ts +2 -2
  32. package/src/adapters/index.js +2 -8
  33. package/src/adapters/node/create-app.d.ts +8 -3
  34. package/src/adapters/node/create-app.js +126 -84
  35. package/src/adapters/node/http-request-bridge.js +147 -106
  36. package/src/adapters/node/node-client-bridge.d.ts +1 -0
  37. package/src/adapters/node/node-client-bridge.js +62 -61
  38. package/src/adapters/node/node-hmr-manager.d.ts +1 -1
  39. package/src/adapters/node/node-hmr-manager.js +58 -48
  40. package/src/adapters/node/runtime-host.d.ts +1 -1
  41. package/src/adapters/node/runtime-host.js +96 -89
  42. package/src/adapters/node/server-adapter-dependencies.js +18 -17
  43. package/src/adapters/node/server-adapter.d.ts +63 -23
  44. package/src/adapters/node/server-adapter.js +346 -297
  45. package/src/adapters/node/static-content-server.d.ts +1 -0
  46. package/src/adapters/node/static-content-server.js +172 -183
  47. package/src/adapters/node/static-preview-host.d.ts +1 -1
  48. package/src/adapters/node/static-preview-host.js +88 -64
  49. package/src/adapters/shared/hmr/dev-transform-entrypoint-registry.d.ts +16 -0
  50. package/src/adapters/shared/hmr/dev-transform-entrypoint-registry.js +32 -0
  51. package/src/adapters/shared/{hmr-html-response.d.ts → hmr/hmr-html-response.d.ts} +2 -2
  52. package/src/adapters/shared/hmr/hmr-html-response.js +50 -0
  53. package/src/adapters/shared/hmr/shared-hmr-manager.d.ts +92 -0
  54. package/src/adapters/shared/hmr/shared-hmr-manager.js +446 -0
  55. package/src/adapters/shared/http/api-request-pipeline.d.ts +23 -0
  56. package/src/adapters/shared/http/api-request-pipeline.js +132 -0
  57. package/src/adapters/shared/{api-response.d.ts → http/api-response.d.ts} +1 -1
  58. package/src/adapters/shared/http/api-response.js +79 -0
  59. package/src/adapters/shared/http/create-body-response.d.ts +12 -0
  60. package/src/adapters/shared/http/create-body-response.js +26 -0
  61. package/src/adapters/shared/http/define-api-handler.d.ts +90 -0
  62. package/src/adapters/shared/http/define-api-handler.js +49 -0
  63. package/src/adapters/shared/{explicit-static-render-preparation.d.ts → http/explicit-static-render-preparation.d.ts} +3 -3
  64. package/src/adapters/shared/http/explicit-static-render-preparation.js +29 -0
  65. package/src/adapters/shared/{explicit-static-route-matcher.d.ts → http/explicit-static-route-matcher.d.ts} +3 -9
  66. package/src/adapters/shared/http/explicit-static-route-matcher.js +59 -0
  67. package/src/adapters/shared/{file-route-middleware-pipeline.d.ts → http/file-route-middleware-pipeline.d.ts} +2 -2
  68. package/src/adapters/shared/http/file-route-middleware-pipeline.js +84 -0
  69. package/src/adapters/shared/{fs-server-response-factory.d.ts → http/fs-server-response-factory.d.ts} +7 -2
  70. package/src/adapters/shared/http/fs-server-response-factory.js +106 -0
  71. package/src/adapters/shared/{fs-server-response-matcher.d.ts → http/fs-server-response-matcher.d.ts} +25 -5
  72. package/src/adapters/shared/http/fs-server-response-matcher.js +258 -0
  73. package/src/adapters/shared/http/run-middleware-chain.d.ts +5 -0
  74. package/src/adapters/shared/http/run-middleware-chain.js +17 -0
  75. package/src/adapters/shared/{application-adapter.d.ts → runtime/application-adapter.d.ts} +2 -2
  76. package/src/adapters/shared/runtime/application-adapter.js +75 -0
  77. package/src/adapters/shared/runtime/collect-dev-prewarm-plan.d.ts +11 -0
  78. package/src/adapters/shared/runtime/collect-dev-prewarm-plan.js +29 -0
  79. package/src/adapters/shared/runtime/copy-runtime-public-dir.d.ts +6 -0
  80. package/src/adapters/shared/runtime/copy-runtime-public-dir.js +27 -0
  81. package/src/adapters/shared/runtime/dev-static-route-prewarm.d.ts +16 -0
  82. package/src/adapters/shared/runtime/dev-static-route-prewarm.js +66 -0
  83. package/src/adapters/shared/runtime/port-manager.d.ts +116 -0
  84. package/src/adapters/shared/runtime/port-manager.js +226 -0
  85. package/src/adapters/shared/{render-context.d.ts → runtime/render-context.d.ts} +2 -2
  86. package/src/adapters/shared/runtime/render-context.js +99 -0
  87. package/src/adapters/shared/{runtime-app-bootstrap.d.ts → runtime/runtime-app-bootstrap.d.ts} +4 -3
  88. package/src/adapters/shared/runtime/runtime-app-bootstrap.js +38 -0
  89. package/src/adapters/shared/runtime/runtime-server-lifecycle.d.ts +45 -0
  90. package/src/adapters/shared/runtime/runtime-server-lifecycle.js +71 -0
  91. package/src/adapters/shared/{server-adapter.d.ts → runtime/server-adapter.d.ts} +31 -50
  92. package/src/adapters/shared/runtime/server-adapter.js +301 -0
  93. package/src/adapters/shared/{server-route-handler.d.ts → runtime/server-route-handler.d.ts} +6 -33
  94. package/src/adapters/shared/runtime/server-route-handler.js +77 -0
  95. package/src/adapters/shared/{server-static-builder.d.ts → runtime/server-static-builder.d.ts} +27 -35
  96. package/src/adapters/shared/runtime/server-static-builder.js +172 -0
  97. package/src/adapters/shared/{static-preview-host.d.ts → runtime/static-preview-host.d.ts} +6 -1
  98. package/src/adapters/shared/ws/node-http-websocket-upgrades.d.ts +21 -0
  99. package/src/adapters/shared/ws/node-http-websocket-upgrades.js +109 -0
  100. package/src/adapters/shared/ws/websocket-lifecycle.d.ts +24 -0
  101. package/src/adapters/shared/ws/websocket-lifecycle.js +62 -0
  102. package/src/build/README.md +191 -31
  103. package/src/build/app-build-manifest-runtime.d.ts +39 -0
  104. package/src/build/app-build-manifest-runtime.js +145 -0
  105. package/src/build/browser/browser-runtime-manifest.js +58 -0
  106. package/src/build/browser/browser-runtime-plugin-helpers.js +34 -0
  107. package/src/build/{browser-runtime-plugin.d.ts → browser/browser-runtime-plugin.d.ts} +1 -1
  108. package/src/build/browser/browser-runtime-plugin.js +216 -0
  109. package/src/build/browser/jsx-ownership-plugins.d.ts +24 -0
  110. package/src/build/browser/jsx-ownership-plugins.js +55 -0
  111. package/src/build/browser/lit-static-render-worker-context.d.ts +2 -0
  112. package/src/build/browser/lit-static-render-worker-context.js +4 -0
  113. package/src/build/build-adapter.d.ts +29 -334
  114. package/src/build/build-adapter.js +273 -237
  115. package/src/build/cache/build-input-fingerprint.d.ts +28 -0
  116. package/src/build/cache/build-input-fingerprint.js +33 -0
  117. package/src/build/cache/cache-constants.d.ts +4 -0
  118. package/src/build/cache/cache-constants.js +4 -0
  119. package/src/build/cache/cache-keys.d.ts +22 -0
  120. package/src/build/cache/cache-keys.js +71 -0
  121. package/src/build/cache/pages-unified-graph-build.d.ts +31 -0
  122. package/src/build/cache/pages-unified-graph-build.js +199 -0
  123. package/src/build/cache/production-build-cache.d.ts +21 -0
  124. package/src/build/cache/production-build-cache.js +56 -0
  125. package/src/build/cache/server-entry-build-cache.d.ts +43 -0
  126. package/src/build/cache/server-entry-build-cache.js +153 -0
  127. package/src/build/contracts/build-contracts.d.ts +96 -0
  128. package/src/build/contracts/build-contracts.js +1 -0
  129. package/src/build/contracts/build-manifest.d.ts +90 -0
  130. package/src/build/contracts/build-manifest.js +64 -0
  131. package/src/build/contracts/build-types.js +1 -0
  132. package/src/build/contracts/content-virtual-modules.d.ts +12 -0
  133. package/src/build/contracts/content-virtual-modules.js +29 -0
  134. package/src/build/{rolldown-adapter-helpers.d.ts → rolldown/rolldown-adapter-helpers.d.ts} +32 -9
  135. package/src/build/rolldown/rolldown-adapter-helpers.js +458 -0
  136. package/src/build/{rolldown-build-adapter.d.ts → rolldown/rolldown-build-adapter.d.ts} +3 -7
  137. package/src/build/rolldown/rolldown-build-adapter.js +57 -0
  138. package/src/build/rolldown/rolldown-build-invocation-metrics.d.ts +12 -0
  139. package/src/build/rolldown/rolldown-build-invocation-metrics.js +39 -0
  140. package/src/build/{rolldown-plugin-bridge.d.ts → rolldown/rolldown-plugin-bridge.d.ts} +16 -2
  141. package/src/build/rolldown/rolldown-plugin-bridge.js +284 -0
  142. package/src/build/rolldown/rolldown-source-transform-pass.d.ts +15 -0
  143. package/src/build/rolldown/rolldown-source-transform-pass.js +70 -0
  144. package/src/build/rolldown/runtime-build-output-normalizer.d.ts +10 -0
  145. package/src/build/rolldown/runtime-build-output-normalizer.js +253 -0
  146. package/src/build/rolldown/server-side-css-shim-plugin.js +58 -0
  147. package/src/build/runtime/build-profile-options.d.ts +7 -0
  148. package/src/build/runtime/build-profile-options.js +37 -0
  149. package/src/build/runtime/build-request-identity.d.ts +17 -0
  150. package/src/build/runtime/build-request-identity.js +79 -0
  151. package/src/build/runtime/build-request-policy.d.ts +58 -0
  152. package/src/build/runtime/build-request-policy.js +84 -0
  153. package/src/build/runtime/build-runtime.d.ts +28 -0
  154. package/src/build/runtime/build-runtime.js +75 -0
  155. package/src/build/runtime/deduping-build-executor.d.ts +21 -0
  156. package/src/build/runtime/deduping-build-executor.js +40 -0
  157. package/src/build/runtime/parallel-build-executor.d.ts +21 -0
  158. package/src/build/runtime/parallel-build-executor.js +60 -0
  159. package/src/build/{serialized-build-executor.d.ts → runtime/serialized-build-executor.d.ts} +1 -1
  160. package/src/build/runtime/serialized-build-executor.js +79 -0
  161. package/src/cache/index.d.ts +2 -1
  162. package/src/cache/index.js +7 -6
  163. package/src/cache/module-parse-cache.d.ts +5 -0
  164. package/src/cache/module-parse-cache.js +122 -67
  165. package/src/cache/module-transform-profiler.d.ts +8 -0
  166. package/src/cache/module-transform-profiler.js +8 -0
  167. package/src/client/navigation-scripts/classification.d.ts +16 -0
  168. package/src/client/navigation-scripts/classification.js +49 -0
  169. package/src/client/navigation-scripts/index.d.ts +3 -0
  170. package/src/client/navigation-scripts/index.js +3 -0
  171. package/src/client/navigation-scripts/navigation-scripts.test.browser.d.ts +1 -0
  172. package/src/client/navigation-scripts/navigation-scripts.test.browser.js +61 -0
  173. package/src/client/navigation-scripts/registry.d.ts +11 -0
  174. package/src/client/navigation-scripts/registry.js +16 -0
  175. package/src/client/navigation-scripts/rerun-queue.d.ts +37 -0
  176. package/src/client/navigation-scripts/rerun-queue.js +90 -0
  177. package/src/client/scroll.d.ts +17 -0
  178. package/src/client/scroll.js +33 -0
  179. package/src/client/scroll.test.browser.d.ts +1 -0
  180. package/src/client/scroll.test.browser.js +31 -0
  181. package/src/client/view-transitions.d.ts +32 -0
  182. package/src/client/view-transitions.js +120 -0
  183. package/src/client/view-transitions.test.browser.d.ts +1 -0
  184. package/src/client/view-transitions.test.browser.js +56 -0
  185. package/src/config/config-builder.d.ts +40 -10
  186. package/src/config/config-builder.js +647 -600
  187. package/src/config/constants.d.ts +1 -0
  188. package/src/config/constants.js +44 -23
  189. package/src/declarations.d.ts +1 -0
  190. package/src/dev/README.md +24 -0
  191. package/src/dev/client-bridge-registry.d.ts +5 -0
  192. package/src/dev/client-bridge-registry.js +10 -0
  193. package/src/dev/dev-client-ownership.d.ts +7 -0
  194. package/src/dev/dev-client-ownership.js +8 -0
  195. package/src/dev/hmr-manager-registry.d.ts +8 -0
  196. package/src/dev/hmr-manager-registry.js +10 -0
  197. package/src/dev/host-runtime.d.ts +3 -0
  198. package/src/dev/host-runtime.js +25 -23
  199. package/src/dev/runtime-server-started-message.d.ts +2 -0
  200. package/src/dev/runtime-server-started-message.js +3 -0
  201. package/src/dev/sc-server.js +106 -103
  202. package/src/dev/transform-server/dev-transform-bundler.d.ts +24 -0
  203. package/src/dev/transform-server/dev-transform-bundler.js +79 -0
  204. package/src/dev/transform-server/dev-transform-externalize-plugin.d.ts +12 -0
  205. package/src/dev/transform-server/dev-transform-externalize-plugin.js +29 -0
  206. package/src/dev/transform-server/dev-transform-import-rewriter.d.ts +16 -0
  207. package/src/dev/transform-server/dev-transform-import-rewriter.js +126 -0
  208. package/src/dev/transform-server/dev-transform-module-kind.d.ts +13 -0
  209. package/src/dev/transform-server/dev-transform-module-kind.js +17 -0
  210. package/src/dev/transform-server/dev-transform-runtime-specifiers.d.ts +5 -0
  211. package/src/dev/transform-server/dev-transform-runtime-specifiers.js +16 -0
  212. package/src/dev/transform-server/dev-transform-server.d.ts +41 -0
  213. package/src/dev/transform-server/dev-transform-server.js +191 -0
  214. package/src/dev/transform-server/dev-transform-url.d.ts +13 -0
  215. package/src/dev/transform-server/dev-transform-url.js +58 -0
  216. package/src/dev/transform-server/dev-transform-vendor-registry.d.ts +28 -0
  217. package/src/dev/transform-server/dev-transform-vendor-registry.js +158 -0
  218. package/src/dev/transform-server/index.d.ts +6 -0
  219. package/src/dev/transform-server/index.js +4 -0
  220. package/src/dev/transform-server/types.d.ts +15 -0
  221. package/src/dev/transform-server/types.js +1 -0
  222. package/src/dev-toolbar/README.md +52 -0
  223. package/src/dev-toolbar/define-dev-tool.d.ts +21 -0
  224. package/src/dev-toolbar/define-dev-tool.js +9 -0
  225. package/src/dev-toolbar/dev-toolbar-config.d.ts +25 -0
  226. package/src/dev-toolbar/dev-toolbar-config.js +19 -0
  227. package/src/dev-toolbar/dev-toolbar-host.d.ts +49 -0
  228. package/src/dev-toolbar/dev-toolbar-host.js +117 -0
  229. package/src/dev-toolbar/dev-toolbar-html-response.d.ts +11 -0
  230. package/src/dev-toolbar/dev-toolbar-html-response.js +14 -0
  231. package/src/dev-toolbar/dev-toolbar-manifest-contract.d.ts +22 -0
  232. package/src/dev-toolbar/dev-toolbar-manifest-contract.js +2 -0
  233. package/src/dev-toolbar/dev-toolbar-manifest.d.ts +15 -0
  234. package/src/dev-toolbar/dev-toolbar-manifest.js +52 -0
  235. package/src/dev-toolbar/dev-toolbar-package.d.ts +34 -0
  236. package/src/dev-toolbar/dev-toolbar-package.js +78 -0
  237. package/src/dev-toolbar/dev-toolbar-runtime-paths.d.ts +10 -0
  238. package/src/dev-toolbar/dev-toolbar-runtime-paths.js +13 -0
  239. package/src/diagnostics/request-build-dedupe.d.ts +18 -0
  240. package/src/diagnostics/request-build-dedupe.js +39 -0
  241. package/src/diagnostics/request-pipeline-metrics.d.ts +38 -0
  242. package/src/diagnostics/request-pipeline-metrics.js +121 -0
  243. package/src/diagnostics/startup-trace.d.ts +81 -0
  244. package/src/diagnostics/startup-trace.js +281 -0
  245. package/src/eco/README.md +17 -0
  246. package/src/eco/component-identity.d.ts +13 -0
  247. package/src/eco/component-identity.js +18 -0
  248. package/src/eco/eco-declared-component.d.ts +15 -0
  249. package/src/eco/eco-declared-component.js +23 -0
  250. package/src/eco/eco.browser.js +63 -70
  251. package/src/eco/eco.js +163 -97
  252. package/src/eco/eco.types.d.ts +47 -8
  253. package/src/eco/eco.types.js +5 -0
  254. package/src/eco/eco.utils.d.ts +1 -1
  255. package/src/eco/eco.utils.js +1 -10
  256. package/src/eco/global-injector-map.js +55 -41
  257. package/src/eco/lazy-injector-map.js +90 -60
  258. package/src/eco/module-dependencies.js +52 -44
  259. package/src/eco/page-layout-normalization.d.ts +21 -0
  260. package/src/eco/page-layout-normalization.js +69 -0
  261. package/src/env.d.ts +2 -0
  262. package/src/errors/http-error.d.ts +8 -0
  263. package/src/errors/http-error.js +66 -49
  264. package/src/errors/index.d.ts +1 -0
  265. package/src/errors/index.js +3 -6
  266. package/src/errors/locals-access-error.js +5 -8
  267. package/src/errors/undeclared-component-dependency-error.d.ts +11 -0
  268. package/src/errors/undeclared-component-dependency-error.js +17 -0
  269. package/src/global/app-logger.js +3 -6
  270. package/src/hmr/README.md +21 -0
  271. package/src/hmr/client/hmr-runtime.js +119 -110
  272. package/src/hmr/client/module-update.d.ts +13 -0
  273. package/src/hmr/client/module-update.js +39 -0
  274. package/src/hmr/hmr-asset-paths.d.ts +14 -0
  275. package/src/hmr/hmr-asset-paths.js +22 -0
  276. package/src/hmr/hmr-entrypoint-output.d.ts +21 -0
  277. package/src/hmr/hmr-entrypoint-output.js +34 -0
  278. package/src/hmr/hmr-file-change-prep.d.ts +10 -0
  279. package/src/hmr/hmr-file-change-prep.js +14 -0
  280. package/src/hmr/hmr-registered-entrypoints-context.d.ts +7 -0
  281. package/src/hmr/hmr-registered-entrypoints-context.js +1 -0
  282. package/src/hmr/hmr-runtime-paths.d.ts +10 -0
  283. package/src/hmr/hmr-runtime-paths.js +13 -0
  284. package/src/hmr/hmr-strategy.d.ts +9 -0
  285. package/src/hmr/hmr-strategy.js +113 -42
  286. package/src/hmr/strategies/default-hmr-strategy.js +55 -33
  287. package/src/hmr/strategies/js-hmr-strategy.d.ts +6 -97
  288. package/src/hmr/strategies/js-hmr-strategy.js +107 -167
  289. package/src/hmr/strategies/server-rendered-template-hmr-strategy.d.ts +17 -0
  290. package/src/hmr/strategies/server-rendered-template-hmr-strategy.js +35 -0
  291. package/src/index.browser.d.ts +1 -0
  292. package/src/index.browser.js +2 -4
  293. package/src/index.d.ts +4 -1
  294. package/src/index.js +7 -21
  295. package/src/integrations/ghtml/ghtml-renderer.d.ts +2 -6
  296. package/src/integrations/ghtml/ghtml-renderer.js +12 -56
  297. package/src/integrations/ghtml/ghtml.constants.js +1 -4
  298. package/src/integrations/ghtml/ghtml.plugin.d.ts +3 -16
  299. package/src/integrations/ghtml/ghtml.plugin.js +10 -20
  300. package/src/islands/README.md +25 -0
  301. package/src/islands/island-host.d.ts +37 -0
  302. package/src/islands/island-host.js +55 -0
  303. package/src/plugins/README.md +2 -1
  304. package/src/plugins/alias-resolver-cache.d.ts +6 -9
  305. package/src/plugins/alias-resolver-cache.js +114 -97
  306. package/src/plugins/alias-resolver-plugin.d.ts +3 -3
  307. package/src/plugins/alias-resolver-plugin.js +35 -62
  308. package/src/plugins/define-integration.d.ts +26 -0
  309. package/src/plugins/define-integration.js +20 -0
  310. package/src/plugins/eco-component-meta-plugin.d.ts +6 -102
  311. package/src/plugins/eco-component-meta-plugin.js +120 -162
  312. package/src/plugins/foreign-jsx-override-plugin.d.ts +1 -1
  313. package/src/plugins/foreign-jsx-override-plugin.js +49 -37
  314. package/src/plugins/integration-plugin.d.ts +43 -14
  315. package/src/plugins/integration-plugin.js +212 -190
  316. package/src/plugins/jsx-import-source.utils.d.ts +8 -0
  317. package/src/plugins/jsx-import-source.utils.js +21 -0
  318. package/src/plugins/processor.d.ts +71 -12
  319. package/src/plugins/processor.js +168 -130
  320. package/src/plugins/runtime-capability.js +1 -0
  321. package/src/plugins/source-transform.d.ts +32 -1
  322. package/src/plugins/source-transform.js +112 -60
  323. package/src/plugins/tsconfig-import-resolver.d.ts +35 -0
  324. package/src/plugins/tsconfig-import-resolver.js +235 -0
  325. package/src/route-renderer/GRAPH.md +26 -32
  326. package/src/route-renderer/README.md +54 -33
  327. package/src/route-renderer/orchestration/document-shell/document-shell-render.service.d.ts +107 -0
  328. package/src/route-renderer/orchestration/document-shell/document-shell-render.service.js +155 -0
  329. package/src/route-renderer/orchestration/document-shell/layout-shell-props.service.d.ts +20 -0
  330. package/src/route-renderer/orchestration/document-shell/layout-shell-props.service.js +37 -0
  331. package/src/route-renderer/orchestration/{component-render-context.d.ts → foreign-child/component-render-context.d.ts} +8 -15
  332. package/src/route-renderer/orchestration/foreign-child/component-render-context.js +196 -0
  333. package/src/route-renderer/orchestration/{render-output.utils.d.ts → foreign-child/foreign-child-output.utils.d.ts} +17 -7
  334. package/src/route-renderer/orchestration/foreign-child/foreign-child-output.utils.js +191 -0
  335. package/src/route-renderer/orchestration/{foreign-subtree-execution.service.d.ts → foreign-child/foreign-subtree-execution.service.d.ts} +64 -34
  336. package/src/route-renderer/orchestration/foreign-child/foreign-subtree-execution.service.js +354 -0
  337. package/src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.d.ts +19 -0
  338. package/src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.js +36 -0
  339. package/src/route-renderer/orchestration/integration-renderer.d.ts +41 -151
  340. package/src/route-renderer/orchestration/integration-renderer.js +798 -988
  341. package/src/route-renderer/orchestration/integration-renderer.test-fixtures.d.ts +75 -0
  342. package/src/route-renderer/orchestration/integration-renderer.test-fixtures.js +173 -0
  343. package/src/route-renderer/orchestration/ownership-graph/component-graph-collectors.d.ts +10 -0
  344. package/src/route-renderer/orchestration/ownership-graph/component-graph-collectors.js +132 -0
  345. package/src/route-renderer/orchestration/ownership-graph/component-graph.d.ts +34 -0
  346. package/src/route-renderer/orchestration/ownership-graph/component-graph.js +89 -0
  347. package/src/route-renderer/orchestration/{ownership-validation.service.d.ts → ownership-graph/ownership-validation.service.d.ts} +6 -2
  348. package/src/route-renderer/orchestration/ownership-graph/ownership-validation.service.js +77 -0
  349. package/src/route-renderer/orchestration/page-browser-graph/global-injector-assets.service.d.ts +7 -0
  350. package/src/route-renderer/orchestration/page-browser-graph/global-injector-assets.service.js +30 -0
  351. package/src/route-renderer/orchestration/page-browser-graph/grouped-graph-build-plan.d.ts +15 -0
  352. package/src/route-renderer/orchestration/page-browser-graph/grouped-graph-build-plan.js +9 -0
  353. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-contribution.merge.d.ts +5 -0
  354. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-contribution.merge.js +30 -0
  355. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.d.ts +12 -0
  356. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.js +32 -0
  357. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-session.d.ts +126 -0
  358. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-session.js +542 -0
  359. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph.service.d.ts +47 -0
  360. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph.service.js +232 -0
  361. package/src/route-renderer/orchestration/{processed-asset-dedupe.d.ts → page-browser-graph/processed-asset-dedupe.d.ts} +1 -1
  362. package/src/route-renderer/orchestration/page-browser-graph/processed-asset-dedupe.js +23 -0
  363. package/src/route-renderer/orchestration/page-browser-graph/route-instance-key.d.ts +29 -0
  364. package/src/route-renderer/orchestration/page-browser-graph/route-instance-key.js +54 -0
  365. package/src/route-renderer/orchestration/route-pipeline/integration-route-render-adapter.d.ts +38 -0
  366. package/src/route-renderer/orchestration/route-pipeline/integration-route-render-adapter.js +26 -0
  367. package/src/route-renderer/orchestration/route-pipeline/marker-artifact.utils.d.ts +6 -0
  368. package/src/route-renderer/orchestration/route-pipeline/marker-artifact.utils.js +25 -0
  369. package/src/route-renderer/orchestration/route-pipeline/robots-meta.contribution.d.ts +15 -0
  370. package/src/route-renderer/orchestration/route-pipeline/robots-meta.contribution.js +43 -0
  371. package/src/route-renderer/orchestration/route-pipeline/route-html-finalization.service.d.ts +25 -0
  372. package/src/route-renderer/orchestration/route-pipeline/route-html-finalization.service.js +44 -0
  373. package/src/route-renderer/orchestration/route-pipeline/route-prepared-options.builder.d.ts +26 -0
  374. package/src/route-renderer/orchestration/route-pipeline/route-prepared-options.builder.js +49 -0
  375. package/src/route-renderer/orchestration/route-pipeline/route-prepared-options.utils.d.ts +4 -0
  376. package/src/route-renderer/orchestration/route-pipeline/route-prepared-options.utils.js +30 -0
  377. package/src/route-renderer/orchestration/{route-render-orchestrator.d.ts → route-pipeline/route-render-orchestrator.d.ts} +24 -54
  378. package/src/route-renderer/orchestration/route-pipeline/route-render-orchestrator.js +215 -0
  379. package/src/route-renderer/orchestration/string-markup-renderer.d.ts +14 -0
  380. package/src/route-renderer/orchestration/string-markup-renderer.js +52 -0
  381. package/src/route-renderer/page-loading/component-dependency-collection.js +121 -121
  382. package/src/route-renderer/page-loading/declared-asset-collection.js +66 -94
  383. package/src/route-renderer/page-loading/dependency-resolver.js +101 -104
  384. package/src/route-renderer/page-loading/ecopages-virtual-imports.d.ts +1 -0
  385. package/src/route-renderer/page-loading/ecopages-virtual-imports.js +64 -51
  386. package/src/route-renderer/page-loading/file-scoped-dependency-components.d.ts +42 -0
  387. package/src/route-renderer/page-loading/file-scoped-dependency-components.js +94 -0
  388. package/src/route-renderer/page-loading/lazy-entry-collection.js +75 -98
  389. package/src/route-renderer/page-loading/lazy-trigger-planning.js +47 -36
  390. package/src/route-renderer/page-loading/module-declaration-aggregation.js +39 -28
  391. package/src/route-renderer/page-loading/module-declaration-scripts.js +10 -15
  392. package/src/route-renderer/page-loading/page-dependency-bundling.js +156 -113
  393. package/src/route-renderer/page-loading/page-module-loader.d.ts +2 -1
  394. package/src/route-renderer/page-loading/page-module-loader.js +136 -124
  395. package/src/route-renderer/page-loading/resolved-page-dependencies.d.ts +12 -0
  396. package/src/route-renderer/page-loading/resolved-page-dependencies.js +38 -0
  397. package/src/route-renderer/route-renderer.js +74 -76
  398. package/src/router/README.md +31 -0
  399. package/src/router/client/link-intent.d.ts +11 -21
  400. package/src/router/client/link-intent.js +56 -30
  401. package/src/router/client/link-intent.test.browser.js +50 -39
  402. package/src/router/client/link-navigation-policy.d.ts +45 -0
  403. package/src/router/client/link-navigation-policy.js +122 -0
  404. package/src/router/client/link-navigation-policy.test.browser.d.ts +1 -0
  405. package/src/router/client/link-navigation-policy.test.browser.js +82 -0
  406. package/src/router/client/navigation-coordinator.d.ts +1 -1
  407. package/src/router/client/navigation-coordinator.js +235 -201
  408. package/src/router/client/navigation-lifecycle.d.ts +55 -0
  409. package/src/router/client/navigation-lifecycle.js +50 -0
  410. package/src/router/client/navigation-lifecycle.test.browser.d.ts +1 -0
  411. package/src/router/client/navigation-lifecycle.test.browser.js +118 -0
  412. package/src/router/server/route-registry.js +237 -242
  413. package/src/services/README.md +5 -0
  414. package/src/services/assets/asset-processing-service/asset-dependency-keys.d.ts +13 -0
  415. package/src/services/assets/asset-processing-service/asset-dependency-keys.js +64 -50
  416. package/src/services/assets/asset-processing-service/asset-processing.service.d.ts +7 -1
  417. package/src/services/assets/asset-processing-service/asset-processing.service.js +308 -268
  418. package/src/services/assets/asset-processing-service/asset.factory.js +78 -81
  419. package/src/services/assets/asset-processing-service/assets.types.d.ts +1 -1
  420. package/src/services/assets/asset-processing-service/assets.types.js +1 -0
  421. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.d.ts +2 -1
  422. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +57 -45
  423. package/src/services/assets/asset-processing-service/browser-runtime-entry-resolution.d.ts +52 -0
  424. package/src/services/assets/asset-processing-service/browser-runtime-entry-resolution.js +115 -0
  425. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.d.ts +4 -2
  426. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.js +53 -38
  427. package/src/services/assets/asset-processing-service/finalize-processed-asset.d.ts +3 -0
  428. package/src/services/assets/asset-processing-service/finalize-processed-asset.js +5 -0
  429. package/src/services/assets/asset-processing-service/grouped-content-bundles.d.ts +2 -1
  430. package/src/services/assets/asset-processing-service/grouped-content-bundles.js +85 -60
  431. package/src/services/assets/asset-processing-service/index.d.ts +2 -0
  432. package/src/services/assets/asset-processing-service/index.js +8 -6
  433. package/src/services/assets/asset-processing-service/inline-content-script-body.d.ts +11 -0
  434. package/src/services/assets/asset-processing-service/inline-content-script-body.js +23 -0
  435. package/src/services/assets/asset-processing-service/materialize-content-script-asset.d.ts +9 -0
  436. package/src/services/assets/asset-processing-service/materialize-content-script-asset.js +22 -0
  437. package/src/services/assets/asset-processing-service/page-package.js +70 -72
  438. package/src/services/assets/asset-processing-service/processor.interface.js +7 -5
  439. package/src/services/assets/asset-processing-service/processor.registry.js +11 -14
  440. package/src/services/assets/asset-processing-service/processors/base/base-processor.js +59 -62
  441. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.d.ts +0 -2
  442. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.js +102 -130
  443. package/src/services/assets/asset-processing-service/processors/index.js +5 -5
  444. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.d.ts +8 -0
  445. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.js +111 -111
  446. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.d.ts +0 -1
  447. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +95 -94
  448. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +136 -121
  449. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.d.ts +0 -3
  450. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +26 -57
  451. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.d.ts +0 -3
  452. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +33 -67
  453. package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.d.ts +2 -0
  454. package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.js +44 -0
  455. package/src/services/assets/asset-processing-service/resolve-integration-plugin.d.ts +4 -0
  456. package/src/services/assets/asset-processing-service/resolve-integration-plugin.js +15 -0
  457. package/src/services/assets/asset-processing-service/ungrouped-dependency-processing.d.ts +0 -1
  458. package/src/services/assets/asset-processing-service/ungrouped-dependency-processing.js +27 -44
  459. package/src/services/assets/browser-bundle.service.d.ts +28 -30
  460. package/src/services/assets/browser-bundle.service.js +54 -40
  461. package/src/services/cache/cache.types.d.ts +4 -2
  462. package/src/services/cache/cache.types.js +5 -0
  463. package/src/services/cache/html-page-cache-dependency-index.d.ts +34 -0
  464. package/src/services/cache/html-page-cache-dependency-index.js +88 -0
  465. package/src/services/cache/index.d.ts +2 -0
  466. package/src/services/cache/index.js +8 -7
  467. package/src/services/cache/memory-cache-store.js +101 -89
  468. package/src/services/cache/page-cache-service.d.ts +31 -1
  469. package/src/services/cache/page-cache-service.js +237 -150
  470. package/src/services/cache/page-request-cache-coordinator.service.js +106 -102
  471. package/src/services/html/html-rewriter-provider.service.js +61 -61
  472. package/src/services/html/html-transformer.service.d.ts +1 -1
  473. package/src/services/html/html-transformer.service.js +249 -266
  474. package/src/services/invalidation/development-invalidation.service.d.ts +25 -2
  475. package/src/services/invalidation/development-invalidation.service.js +239 -175
  476. package/src/services/module-loading/README.md +52 -0
  477. package/src/services/module-loading/app-module-loader.service.js +1 -0
  478. package/src/services/module-loading/app-server-module-transpiler.service.d.ts +8 -0
  479. package/src/services/module-loading/app-server-module-transpiler.service.js +103 -118
  480. package/src/services/module-loading/collection-server-module-build.service.d.ts +19 -0
  481. package/src/services/module-loading/collection-server-module-build.service.js +83 -0
  482. package/src/services/module-loading/host-module-loader-registry.js +6 -11
  483. package/src/services/module-loading/module-loading-types.js +1 -0
  484. package/src/services/module-loading/page-module-import.service.d.ts +11 -13
  485. package/src/services/module-loading/page-module-import.service.js +222 -184
  486. package/src/services/module-loading/route-module-build-cache-registry.d.ts +24 -0
  487. package/src/services/module-loading/route-module-build-cache-registry.js +51 -0
  488. package/src/services/module-loading/route-module-build-cache.d.ts +4 -0
  489. package/src/services/module-loading/route-module-build-cache.js +3 -0
  490. package/src/services/module-loading/route-module-build-cache.store.d.ts +57 -0
  491. package/src/services/module-loading/route-module-build-cache.store.js +202 -0
  492. package/src/services/module-loading/route-module-build-manifest.d.ts +57 -0
  493. package/src/services/module-loading/route-module-build-manifest.js +60 -0
  494. package/src/services/module-loading/route-module-dependency-hasher.d.ts +81 -0
  495. package/src/services/module-loading/route-module-dependency-hasher.js +148 -0
  496. package/src/services/module-loading/server-module-transpiler.service.d.ts +1 -3
  497. package/src/services/module-loading/server-module-transpiler.service.js +65 -62
  498. package/src/services/module-loading/source-module-support.js +15 -7
  499. package/src/services/runtime-state/dev-graph.service.js +165 -157
  500. package/src/services/runtime-state/entrypoint-dependency-graph.service.js +85 -76
  501. package/src/services/runtime-state/server-invalidation-state.service.js +38 -30
  502. package/src/services/validation/schema-validation-service.d.ts +1 -4
  503. package/src/services/validation/schema-validation-service.js +156 -95
  504. package/src/services/validation/standard-schema.types.d.ts +9 -62
  505. package/src/services/validation/standard-schema.types.js +1 -0
  506. package/src/services/validation/validate-standard-schema.d.ts +7 -0
  507. package/src/services/validation/validate-standard-schema.js +14 -0
  508. package/src/static-site-generator/README.md +41 -0
  509. package/src/static-site-generator/production-page-browser-graph-prebuild.d.ts +32 -0
  510. package/src/static-site-generator/production-page-browser-graph-prebuild.js +57 -0
  511. package/src/static-site-generator/sitemap-routes.d.ts +14 -0
  512. package/src/static-site-generator/sitemap-routes.js +36 -0
  513. package/src/static-site-generator/sitemap.d.ts +15 -0
  514. package/src/static-site-generator/sitemap.js +42 -0
  515. package/src/static-site-generator/static-build-invalidation.d.ts +10 -0
  516. package/src/static-site-generator/static-build-invalidation.js +37 -0
  517. package/src/static-site-generator/static-export-context.d.ts +30 -0
  518. package/src/static-site-generator/static-export-context.js +1 -0
  519. package/src/static-site-generator/static-site-generator.d.ts +43 -25
  520. package/src/static-site-generator/static-site-generator.js +536 -294
  521. package/src/types/internal-types.d.ts +59 -13
  522. package/src/types/internal-types.js +1 -0
  523. package/src/types/public-types.d.ts +310 -95
  524. package/src/types/public-types.js +1 -0
  525. package/src/utils/deep-merge.js +39 -26
  526. package/src/utils/ecopages-route-info.d.ts +26 -0
  527. package/src/utils/ecopages-route-info.js +30 -0
  528. package/src/utils/hash.js +3 -6
  529. package/src/utils/html-escaping.d.ts +7 -0
  530. package/src/utils/html-escaping.js +22 -5
  531. package/src/utils/html.js +1 -4
  532. package/src/utils/invariant.js +11 -10
  533. package/src/utils/locals-utils.js +32 -22
  534. package/src/utils/parse-cli-args.d.ts +2 -0
  535. package/src/utils/parse-cli-args.js +73 -59
  536. package/src/utils/path-pattern.d.ts +23 -0
  537. package/src/utils/path-pattern.js +42 -0
  538. package/src/utils/path-utils.module.js +8 -11
  539. package/src/utils/resolve-entry-file.js +70 -38
  540. package/src/utils/resolve-work-dir.js +23 -27
  541. package/src/utils/runtime.js +24 -33
  542. package/src/utils/server-utils.module.d.ts +3 -2
  543. package/src/utils/server-utils.module.js +60 -53
  544. package/src/utils/static-file-extensions.d.ts +12 -0
  545. package/src/utils/static-file-extensions.js +54 -0
  546. package/src/watchers/project-watcher-ignore.d.ts +11 -0
  547. package/src/watchers/project-watcher-ignore.js +17 -0
  548. package/src/watchers/project-watcher.d.ts +29 -6
  549. package/src/watchers/project-watcher.js +402 -257
  550. package/src/watchers/project-watcher.test-helpers.js +45 -50
  551. package/src/adapters/shared/api-response.js +0 -96
  552. package/src/adapters/shared/application-adapter.js +0 -90
  553. package/src/adapters/shared/define-api-handler.d.ts +0 -25
  554. package/src/adapters/shared/define-api-handler.js +0 -15
  555. package/src/adapters/shared/explicit-static-render-preparation.js +0 -26
  556. package/src/adapters/shared/explicit-static-route-matcher.js +0 -101
  557. package/src/adapters/shared/file-route-middleware-pipeline.js +0 -90
  558. package/src/adapters/shared/fs-server-response-factory.js +0 -81
  559. package/src/adapters/shared/fs-server-response-matcher.js +0 -186
  560. package/src/adapters/shared/hmr-entrypoint-registrar.d.ts +0 -55
  561. package/src/adapters/shared/hmr-entrypoint-registrar.js +0 -87
  562. package/src/adapters/shared/hmr-html-response.js +0 -33
  563. package/src/adapters/shared/render-context.js +0 -93
  564. package/src/adapters/shared/runtime-app-bootstrap.js +0 -46
  565. package/src/adapters/shared/runtime-host.js +0 -0
  566. package/src/adapters/shared/server-adapter.js +0 -436
  567. package/src/adapters/shared/server-route-handler.js +0 -111
  568. package/src/adapters/shared/server-static-builder.js +0 -162
  569. package/src/adapters/shared/shared-hmr-manager.d.ts +0 -59
  570. package/src/adapters/shared/shared-hmr-manager.js +0 -241
  571. package/src/adapters/shared/static-preview-host.js +0 -0
  572. package/src/build/browser-runtime-manifest.js +0 -61
  573. package/src/build/browser-runtime-plugin-helpers.js +0 -14
  574. package/src/build/browser-runtime-plugin.js +0 -173
  575. package/src/build/build-manifest.d.ts +0 -33
  576. package/src/build/build-manifest.js +0 -49
  577. package/src/build/build-types.js +0 -0
  578. package/src/build/rolldown-adapter-helpers.js +0 -265
  579. package/src/build/rolldown-build-adapter.js +0 -65
  580. package/src/build/rolldown-dev-build-adapter.d.ts +0 -82
  581. package/src/build/rolldown-dev-build-adapter.js +0 -166
  582. package/src/build/rolldown-plugin-bridge.js +0 -199
  583. package/src/build/runtime-build-executor.d.ts +0 -21
  584. package/src/build/runtime-build-executor.js +0 -19
  585. package/src/build/runtime-build-output-normalizer.d.ts +0 -3
  586. package/src/build/runtime-build-output-normalizer.js +0 -111
  587. package/src/build/serialized-build-executor.js +0 -63
  588. package/src/build/server-side-css-shim-plugin.js +0 -35
  589. package/src/hmr/hmr.postcss.test.e2e.js +0 -31
  590. package/src/hmr/hmr.test.e2e.js +0 -43
  591. package/src/route-renderer/orchestration/component-render-context.js +0 -147
  592. package/src/route-renderer/orchestration/declared-ownership-graph.d.ts +0 -18
  593. package/src/route-renderer/orchestration/declared-ownership-graph.js +0 -34
  594. package/src/route-renderer/orchestration/foreign-subtree-execution.service.js +0 -233
  595. package/src/route-renderer/orchestration/ownership-planning.service.d.ts +0 -24
  596. package/src/route-renderer/orchestration/ownership-planning.service.js +0 -63
  597. package/src/route-renderer/orchestration/ownership-validation.service.js +0 -53
  598. package/src/route-renderer/orchestration/processed-asset-dedupe.js +0 -27
  599. package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.d.ts +0 -91
  600. package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.js +0 -170
  601. package/src/route-renderer/orchestration/render-output.utils.js +0 -171
  602. package/src/route-renderer/orchestration/route-render-orchestrator.js +0 -577
  603. package/src/route-renderer/orchestration/template-serialization.d.ts +0 -38
  604. package/src/route-renderer/orchestration/template-serialization.js +0 -45
  605. /package/src/adapters/shared/{runtime-host.d.ts → runtime/runtime-host.d.ts} +0 -0
  606. /package/src/{hmr/hmr.postcss.test.e2e.d.ts → adapters/shared/runtime/runtime-host.js} +0 -0
  607. /package/src/{hmr/hmr.test.e2e.d.ts → adapters/shared/runtime/static-preview-host.js} +0 -0
  608. /package/src/build/{browser-runtime-manifest.d.ts → browser/browser-runtime-manifest.d.ts} +0 -0
  609. /package/src/build/{browser-runtime-plugin-helpers.d.ts → browser/browser-runtime-plugin-helpers.d.ts} +0 -0
  610. /package/src/build/{build-types.d.ts → contracts/build-types.d.ts} +0 -0
  611. /package/src/build/{server-side-css-shim-plugin.d.ts → rolldown/server-side-css-shim-plugin.d.ts} +0 -0
@@ -1,316 +1,558 @@
1
- import path from "node:path";
2
- import { appLogger } from "../global/app-logger.js";
3
- import { fileSystem } from "@ecopages/file-system";
4
- import { PathUtils } from "../utils/path-utils.module.js";
5
- import { prepareExplicitStaticRender } from "../adapters/shared/explicit-static-render-preparation.js";
6
- const STATIC_SITE_GENERATOR_ERRORS = {
7
- ROUTE_RENDERER_FACTORY_REQUIRED: "RouteRendererFactory is required for render strategy",
8
- unsupportedBodyType: (bodyType) => `Unsupported body type for static generation: ${bodyType}`,
9
- missingIntegration: (routePath) => `View at ${routePath} is missing __eco.integration. Ensure it's defined with eco.page().`,
10
- noRendererForIntegration: (integrationName) => `No renderer found for integration: ${integrationName}`,
11
- dynamicRouteRequiresStaticPaths: (routePath) => `Dynamic route ${routePath} requires staticPaths to be defined on the view.`
1
+ import path from 'node:path';
2
+ import { availableParallelism } from 'node:os';
3
+ import { appLogger } from '../global/app-logger.js';
4
+ import { fileSystem } from '@ecopages/file-system';
5
+ import { prepareExplicitStaticRender } from '../adapters/shared/http/explicit-static-render-preparation.js';
6
+ import { createRouteModuleStaticRenderCacheContext } from './static-build-invalidation.js';
7
+ import { getServerModuleBuildCacheOutdir, getSharedRouteModuleBuildCache, } from '../services/module-loading/route-module-build-cache-registry.js';
8
+ import { ensurePagesUnifiedGraphBuilt, shouldBuildPagesUnifiedGraph, } from '../build/cache/pages-unified-graph-build.js';
9
+ import { clearProductionPageBrowserGraphSession, prebuildProductionPageBrowserGraphs, shouldPrebuildProductionPageBrowserGraphs, } from './production-page-browser-graph-prebuild.js';
10
+ import { PageModuleLoaderService } from '../route-renderer/page-loading/page-module-loader.js';
11
+ import { renderSitemap } from './sitemap.js';
12
+ import { resolveSitemapLocations } from './sitemap-routes.js';
13
+ import { toEcopagesRouteInfo } from '../utils/ecopages-route-info.js';
14
+ import { normalizePathname } from '../utils/path-pattern.js';
15
+ export const STATIC_SITE_GENERATOR_ERRORS = {
16
+ ROUTE_RENDERER_FACTORY_REQUIRED: 'RouteRendererFactory is required for render strategy',
17
+ unsupportedBodyType: (bodyType) => `Unsupported body type for static generation: ${bodyType}`,
18
+ missingIntegration: (routePath) => `View at ${routePath} is missing component identity integration. Ensure it's defined with eco.page().`,
19
+ noRendererForIntegration: (integrationName) => `No renderer found for integration: ${integrationName}`,
20
+ dynamicRouteRequiresStaticPaths: (routePath) => `Dynamic route ${routePath} requires staticPaths to be defined on the view.`,
12
21
  };
13
- class StaticSiteGenerator {
14
- appConfig;
15
- /**
16
- * Creates the static-site generator for one app config.
17
- */
18
- constructor({ appConfig }) {
19
- this.appConfig = appConfig;
20
- }
21
- getExportDir() {
22
- return this.appConfig.absolutePaths?.distDir ?? path.join(this.appConfig.rootDir, this.appConfig.distDir);
23
- }
24
- /**
25
- * Logs the standardized warning emitted when a dynamic-cache page is skipped.
26
- */
27
- warnDynamicPageSkipped(filePath) {
28
- appLogger.warn(
29
- "Pages with cache: 'dynamic' are not supported in static generation or preview, so they will be skipped\n",
30
- `\u27A4 ${filePath}`
31
- );
32
- }
33
- /**
34
- * Determines whether one filesystem-discovered page should be excluded from
35
- * static generation.
36
- */
37
- async shouldSkipStaticPageFile(filePath, routeRendererFactory) {
38
- const module = await routeRendererFactory.getPageRenderer(filePath).loadPageModule(filePath, {
39
- cacheScope: "static-page-probe"
22
+ function resolveStaticPageConcurrency() {
23
+ return Math.max(1, availableParallelism() - 1);
24
+ }
25
+ async function runWithConcurrency(items, concurrency, worker) {
26
+ if (items.length === 0) {
27
+ return;
28
+ }
29
+ const limit = Math.max(1, concurrency);
30
+ let nextIndex = 0;
31
+ const runners = Array.from({ length: Math.min(limit, items.length) }, async () => {
32
+ while (nextIndex < items.length) {
33
+ const currentIndex = nextIndex++;
34
+ await worker(items[currentIndex]);
35
+ }
40
36
  });
41
- if (module.default?.cache !== "dynamic") {
42
- return false;
37
+ await Promise.all(runners);
38
+ }
39
+ /**
40
+ * Generates static output files from the finalized app config and route graph.
41
+ *
42
+ * @remarks
43
+ * This class intentionally reuses the same routing, renderer, and server-module
44
+ * loading seams used by runtime rendering. Static generation should be a build
45
+ * loop over the normal app model, not a parallel rendering stack with different
46
+ * semantics.
47
+ */
48
+ export class StaticSiteGenerator {
49
+ appConfig;
50
+ routeModuleBuildCacheOverride;
51
+ staticRenderCacheContext;
52
+ forceFullStaticGeneration = false;
53
+ pageModuleLoader;
54
+ /**
55
+ * Creates the static-site generator for one app config.
56
+ */
57
+ constructor({ appConfig, routeModuleBuildCache, }) {
58
+ this.appConfig = appConfig;
59
+ this.routeModuleBuildCacheOverride = routeModuleBuildCache;
60
+ this.staticRenderCacheContext = createRouteModuleStaticRenderCacheContext(appConfig);
43
61
  }
44
- this.warnDynamicPageSkipped(filePath);
45
- return true;
46
- }
47
- /**
48
- * Determines whether one explicit static route view should be excluded from
49
- * static generation.
50
- */
51
- shouldSkipStaticView(routePath, view) {
52
- if (view.cache !== "dynamic") {
53
- return false;
62
+ getRouteModuleBuildCache() {
63
+ return (this.routeModuleBuildCacheOverride ??
64
+ getSharedRouteModuleBuildCache(getServerModuleBuildCacheOutdir(this.appConfig), this.appConfig));
54
65
  }
55
- this.warnDynamicPageSkipped(routePath);
56
- return true;
57
- }
58
- /**
59
- * Writes the robots.txt file declared by the app config.
60
- */
61
- generateRobotsTxt() {
62
- let data = "";
63
- const preferences = this.appConfig.robotsTxt.preferences;
64
- for (const userAgent in preferences) {
65
- data += `user-agent: ${userAgent}
66
- `;
67
- for (const path2 of preferences[userAgent]) {
68
- data += `disallow: ${path2}
69
- `;
70
- }
71
- data += "\n";
66
+ getExportDir() {
67
+ return this.appConfig.absolutePaths?.distDir ?? path.join(this.appConfig.rootDir, this.appConfig.distDir);
72
68
  }
73
- fileSystem.ensureDir(this.getExportDir());
74
- fileSystem.write(path.join(this.getExportDir(), "robots.txt"), data);
75
- }
76
- /**
77
- * Returns whether the input path points at the root directory.
78
- */
79
- isRootDir(path2) {
80
- const slashes = path2.match(/\//g);
81
- return slashes && slashes.length === 1;
82
- }
83
- /**
84
- * Collects parent directories that must exist for the generated route set.
85
- */
86
- getDirectories(routes) {
87
- const directories = /* @__PURE__ */ new Set();
88
- for (const route of routes) {
89
- const path2 = route.startsWith("http") ? new URL(route).pathname : route;
90
- const segments = path2.split("/");
91
- if (segments.length > 2) {
92
- directories.add(segments.slice(0, segments.length - 1).join("/"));
93
- }
69
+ async shouldSkipStaticPageFile(filePath, routeRendererFactory) {
70
+ const pageModule = await routeRendererFactory.getPageRenderer(filePath).loadPageModule(filePath);
71
+ const Page = pageModule.default;
72
+ return Page.cache === 'dynamic';
94
73
  }
95
- return Array.from(directories);
96
- }
97
- writeStaticOutput(routePath, contents, directories = []) {
98
- const outputPath = this.getOutputPath(routePath, directories);
99
- fileSystem.ensureDir(path.dirname(outputPath));
100
- fileSystem.write(outputPath, contents);
101
- return outputPath;
102
- }
103
- getStaticBuildStrategy(filePath) {
104
- const ext = PathUtils.getEcoTemplateExtension(filePath);
105
- const integration = this.appConfig.integrations.find((plugin) => plugin.extensions.includes(ext));
106
- return integration?.staticBuildStep || "render";
107
- }
108
- async createFilesystemStaticContents(route, baseUrl, routeRendererFactory) {
109
- const {
110
- templateRoute: { filePath },
111
- params
112
- } = route;
113
- if (this.getStaticBuildStrategy(filePath) === "fetch") {
114
- const fetchUrl = this.resolveStaticFetchUrl(route.requestUrl, baseUrl);
115
- const response = await fetch(fetchUrl);
116
- if (!response.ok) {
117
- appLogger.error(`Failed to fetch ${fetchUrl}. Status: ${response.status}`);
118
- return null;
119
- }
120
- return response.text();
74
+ shouldSkipStaticView(_routePath, view) {
75
+ return view.cache === 'dynamic';
121
76
  }
122
- if (!routeRendererFactory) {
123
- throw new Error(STATIC_SITE_GENERATOR_ERRORS.ROUTE_RENDERER_FACTORY_REQUIRED);
77
+ /**
78
+ * Writes the robots.txt file declared by the app config.
79
+ */
80
+ generateRobotsTxt() {
81
+ let data = '';
82
+ const preferences = this.appConfig.robotsTxt.preferences;
83
+ for (const userAgent in preferences) {
84
+ data += `user-agent: ${userAgent}\n`;
85
+ for (const path of preferences[userAgent]) {
86
+ data += `disallow: ${path}\n`;
87
+ }
88
+ data += '\n';
89
+ }
90
+ fileSystem.ensureDir(this.getExportDir());
91
+ fileSystem.write(path.join(this.getExportDir(), 'robots.txt'), data);
124
92
  }
125
- if (await this.shouldSkipStaticPageFile(filePath, routeRendererFactory)) {
126
- return null;
93
+ /**
94
+ * Writes the configured sitemap file to the export directory.
95
+ */
96
+ generateSitemap(locations, sitemap) {
97
+ const fileName = sitemap.fileName ?? 'sitemap.xml';
98
+ fileSystem.ensureDir(this.getExportDir());
99
+ fileSystem.write(path.join(this.getExportDir(), fileName), renderSitemap(locations));
127
100
  }
128
- const renderer = routeRendererFactory.getPageRenderer(filePath);
129
- const result = await renderer.execute({
130
- file: filePath,
131
- params
132
- });
133
- const body = result.body;
134
- if (typeof body === "string" || Buffer.isBuffer(body)) {
135
- return body;
101
+ /**
102
+ * Returns whether the input path points at the root directory.
103
+ */
104
+ isRootDir(path) {
105
+ const slashes = path.match(/\//g);
106
+ return slashes && slashes.length === 1;
107
+ }
108
+ /**
109
+ * Collects parent directories that must exist for the generated route set.
110
+ */
111
+ getDirectories(routes) {
112
+ const directories = new Set();
113
+ for (const route of routes) {
114
+ const path = route.startsWith('http') ? new URL(route).pathname : route;
115
+ const segments = path.split('/');
116
+ if (segments.length > 2) {
117
+ directories.add(segments.slice(0, segments.length - 1).join('/'));
118
+ }
119
+ }
120
+ return Array.from(directories);
136
121
  }
137
- if (body instanceof ReadableStream) {
138
- return new Response(body).text();
122
+ writeStaticOutput(routePath, contents, directories = []) {
123
+ const outputPath = this.getOutputPath(routePath, directories);
124
+ fileSystem.ensureDir(path.dirname(outputPath));
125
+ fileSystem.write(outputPath, contents);
126
+ return outputPath;
139
127
  }
140
- throw new Error(STATIC_SITE_GENERATOR_ERRORS.unsupportedBodyType(typeof body));
141
- }
142
- /**
143
- * Generates static output for all filesystem-discovered routes.
144
- *
145
- * @remarks
146
- * Routes whose integrations opt into fetch-based static builds are rendered by
147
- * issuing a request against the running server origin. Render-strategy routes
148
- * go through the normal route renderer directly.
149
- */
150
- async generateStaticPages(router, baseUrl, routeRendererFactory) {
151
- const routes = await router.listStaticGenerationRoutes({ runtimeOrigin: baseUrl });
152
- appLogger.debug(
153
- "Static Pages",
154
- routes.map((route) => route.requestUrl)
155
- );
156
- const directories = this.getDirectories(routes.map((route) => route.requestUrl));
157
- for (const route of routes) {
158
- try {
159
- const contents = await this.createFilesystemStaticContents(route, baseUrl, routeRendererFactory);
128
+ async writeStaticPageArtifact(options) {
129
+ const directories = options.directories ?? this.getDirectories([options.pathname]);
130
+ const renderedOutputPath = this.getOutputPath(options.pathname, directories);
131
+ const routeModuleBuildCache = this.getRouteModuleBuildCache();
132
+ if (options.reuseRenderedOutput !== false &&
133
+ options.sourceFile &&
134
+ routeModuleBuildCache.canReuseStaticRender({
135
+ sourceFile: options.sourceFile,
136
+ pathname: options.pathname,
137
+ renderedOutputPath,
138
+ context: this.staticRenderCacheContext,
139
+ force: this.forceFullStaticGeneration,
140
+ })) {
141
+ options.activeStaticPathnames?.add(options.pathname);
142
+ await options.onSuccessfulExport?.();
143
+ appLogger.debug(`Skipped unchanged static page: ${options.debugLabel ?? options.pathname}`);
144
+ return;
145
+ }
146
+ const contents = await options.createContents();
160
147
  if (contents === null) {
161
- continue;
162
- }
163
- this.writeStaticOutput(route.pathname, contents, directories);
164
- } catch (error) {
165
- appLogger.error(
166
- `Error generating static page for ${route.requestUrl}:`,
167
- error instanceof Error ? error : String(error)
168
- );
169
- }
148
+ return;
149
+ }
150
+ const outputPath = this.writeStaticOutput(options.pathname, contents, directories);
151
+ options.activeStaticPathnames?.add(options.pathname);
152
+ if (options.sourceFile) {
153
+ try {
154
+ routeModuleBuildCache.recordStaticRender({
155
+ filePath: options.sourceFile,
156
+ pathname: options.pathname,
157
+ sourceHash: fileSystem.hash(options.sourceFile),
158
+ renderedOutputPath: outputPath,
159
+ context: this.staticRenderCacheContext,
160
+ });
161
+ }
162
+ catch (error) {
163
+ appLogger.debug(`Failed to record static render cache for ${options.pathname}`, error instanceof Error ? error.message : String(error));
164
+ }
165
+ }
166
+ await options.onSuccessfulExport?.();
170
167
  }
171
- }
172
- resolveStaticFetchUrl(route, baseUrl) {
173
- if (!route.startsWith("http://") && !route.startsWith("https://")) {
174
- return `${baseUrl}${route}`;
168
+ /**
169
+ * Marks a successfully exported pathname as sitemap-eligible when robots allow indexing.
170
+ *
171
+ * @remarks
172
+ * Fail-closed: metadata resolution errors omit the URL. `robots.index === false`
173
+ * also omits it. Eligibility is decided during generation, not by reloading modules
174
+ * after `afterStaticExport`.
175
+ */
176
+ async considerSitemapEligibility(input) {
177
+ if (!input.sitemapEligiblePathnames || !this.appConfig.sitemap?.enabled) {
178
+ return;
179
+ }
180
+ try {
181
+ const metadata = await input.resolveMetadata();
182
+ if (metadata.robots?.index === false) {
183
+ return;
184
+ }
185
+ input.sitemapEligiblePathnames.add(normalizePathname(input.pathname));
186
+ }
187
+ catch (error) {
188
+ appLogger.debug(`Sitemap eligibility skipped for ${input.pathname}; metadata resolution failed`, error instanceof Error ? error.message : String(error));
189
+ }
175
190
  }
176
- const targetUrl = new URL(route);
177
- const buildUrl = new URL(baseUrl);
178
- buildUrl.pathname = targetUrl.pathname;
179
- buildUrl.search = targetUrl.search;
180
- buildUrl.hash = targetUrl.hash;
181
- return buildUrl.href;
182
- }
183
- /**
184
- * Executes the full static-generation workflow for one app run.
185
- */
186
- async run({
187
- router,
188
- baseUrl,
189
- routeRendererFactory,
190
- staticRoutes
191
- }) {
192
- this.generateRobotsTxt();
193
- await this.generateStaticPages(router, baseUrl, routeRendererFactory);
194
- if (staticRoutes && staticRoutes.length > 0 && routeRendererFactory) {
195
- await this.generateExplicitStaticPages(staticRoutes, routeRendererFactory);
191
+ getPageModuleLoader(baseUrl) {
192
+ this.pageModuleLoader ??= new PageModuleLoaderService(this.appConfig, baseUrl);
193
+ return this.pageModuleLoader;
196
194
  }
197
- }
198
- /**
199
- * Generates static pages from explicit static routes registered via app.static().
200
- * These routes use eco.page views via loader functions for HMR support.
201
- */
202
- async generateExplicitStaticPages(staticRoutes, routeRendererFactory) {
203
- appLogger.debug(
204
- "Generating explicit static routes",
205
- staticRoutes.map((r) => r.path)
206
- );
207
- for (const route of staticRoutes) {
208
- try {
209
- const mod = await route.loader();
210
- const view = mod.default;
211
- if (this.shouldSkipStaticView(route.path, view)) {
212
- continue;
213
- }
214
- await this.generateExplicitStaticRoute(route.path, view, routeRendererFactory);
215
- } catch (error) {
216
- appLogger.error(
217
- `Error generating explicit static page for ${route.path}:`,
218
- error instanceof Error ? error : String(error)
219
- );
220
- }
195
+ async resolveFilesystemPageMetadata(input) {
196
+ const loader = this.getPageModuleLoader(input.baseUrl);
197
+ const pageModule = await loader.resolvePageModule({
198
+ file: input.filePath,
199
+ importPageFileFn: (file) => input.routeRendererFactory.getPageRenderer(file).loadPageModule(file),
200
+ });
201
+ const { metadata } = await loader.resolvePageData({
202
+ pageModule,
203
+ routeOptions: {
204
+ file: input.filePath,
205
+ params: input.params,
206
+ },
207
+ });
208
+ return metadata;
221
209
  }
222
- }
223
- async generateExplicitStaticRoute(routePath, view, routeRendererFactory) {
224
- const { renderer, routeEntries } = await this.planExplicitStaticRoute(routePath, view, routeRendererFactory);
225
- for (const { pathname, params } of routeEntries) {
226
- const contents = await this.createExplicitStaticContents(
227
- routePath,
228
- view,
229
- params,
230
- routeRendererFactory,
231
- renderer
232
- );
233
- const outputPath = this.writeStaticOutput(pathname, contents);
234
- appLogger.debug(`Generated static page: ${pathname} -> ${outputPath}`);
210
+ async resolveExplicitViewMetadata(input) {
211
+ if (!input.view.metadata) {
212
+ return this.appConfig.defaultMetadata;
213
+ }
214
+ const dynamicMetadata = await input.view.metadata({
215
+ params: input.params,
216
+ query: {},
217
+ props: input.props,
218
+ appConfig: this.appConfig,
219
+ });
220
+ return { ...this.appConfig.defaultMetadata, ...dynamicMetadata };
235
221
  }
236
- }
237
- async planExplicitStaticRoute(routePath, view, routeRendererFactory) {
238
- const { renderer } = await prepareExplicitStaticRender({
239
- routePath,
240
- view,
241
- params: {},
242
- appConfig: this.appConfig,
243
- runtimeOrigin: this.appConfig.baseUrl,
244
- routeRendererFactory,
245
- errors: STATIC_SITE_GENERATOR_ERRORS
246
- });
247
- return {
248
- renderer,
249
- routeEntries: await this.listExplicitStaticRouteEntries(routePath, view)
250
- };
251
- }
252
- async createExplicitStaticContents(routePath, view, params, routeRendererFactory, renderer) {
253
- const { props, view: renderableView } = await prepareExplicitStaticRender({
254
- routePath,
255
- view,
256
- params,
257
- appConfig: this.appConfig,
258
- runtimeOrigin: this.appConfig.baseUrl,
259
- routeRendererFactory,
260
- errors: STATIC_SITE_GENERATOR_ERRORS
261
- });
262
- const response = await renderer.renderToResponse(renderableView, props, {});
263
- return response.text();
264
- }
265
- async listExplicitStaticRouteEntries(routePath, view) {
266
- const isDynamic = routePath.includes(":") || routePath.includes("[");
267
- if (!isDynamic) {
268
- return [{ pathname: routePath, params: {} }];
222
+ pruneStaleStaticOutputs(activeStaticPathnames) {
223
+ const removedOutputPaths = this.getRouteModuleBuildCache().pruneStaleRenderedOutputs(activeStaticPathnames);
224
+ for (const outputPath of removedOutputPaths) {
225
+ const resolvedOutputPath = path.isAbsolute(outputPath) ? outputPath : path.resolve(outputPath);
226
+ if (fileSystem.exists(resolvedOutputPath)) {
227
+ fileSystem.remove(resolvedOutputPath);
228
+ appLogger.debug(`Removed stale static output: ${resolvedOutputPath}`);
229
+ }
230
+ }
269
231
  }
270
- if (!view.staticPaths) {
271
- throw new Error(STATIC_SITE_GENERATOR_ERRORS.dynamicRouteRequiresStaticPaths(routePath));
232
+ async createFilesystemStaticContents(input) {
233
+ const { route: { templateRoute: { filePath }, params, }, routeRendererFactory, skipped, } = input;
234
+ if (!routeRendererFactory) {
235
+ throw new Error(STATIC_SITE_GENERATOR_ERRORS.ROUTE_RENDERER_FACTORY_REQUIRED);
236
+ }
237
+ if (await this.shouldSkipStaticPageFile(filePath, routeRendererFactory)) {
238
+ skipped?.push(filePath);
239
+ return null;
240
+ }
241
+ const renderer = routeRendererFactory.getPageRenderer(filePath);
242
+ const result = await renderer.execute({
243
+ file: filePath,
244
+ params: params,
245
+ });
246
+ const body = result.body;
247
+ if (typeof body === 'string' || Buffer.isBuffer(body)) {
248
+ return body;
249
+ }
250
+ if (body instanceof ReadableStream) {
251
+ return new Response(body).text();
252
+ }
253
+ throw new Error(STATIC_SITE_GENERATOR_ERRORS.unsupportedBodyType(typeof body));
272
254
  }
273
- const { paths } = await view.staticPaths({
274
- appConfig: this.appConfig,
275
- runtimeOrigin: this.appConfig.baseUrl
276
- });
277
- return paths.map(({ params }) => ({
278
- pathname: this.resolveRoutePath(routePath, params),
279
- params
280
- }));
281
- }
282
- /**
283
- * Resolve a route path template with actual params.
284
- * Supports both :param and [param] syntax.
285
- */
286
- resolveRoutePath(routePath, params) {
287
- let resolved = routePath;
288
- for (const [key, value] of Object.entries(params)) {
289
- const paramValue = Array.isArray(value) ? value.join("/") : value;
290
- resolved = resolved.replace(`:${key}`, paramValue);
291
- resolved = resolved.replace(`[${key}]`, paramValue);
292
- resolved = resolved.replace(`[...${key}]`, paramValue);
255
+ /**
256
+ * Generates static output for all filesystem-discovered routes.
257
+ *
258
+ * @remarks
259
+ * Routes are rendered through the normal route renderer directly.
260
+ */
261
+ async generateStaticPages(input) {
262
+ const { router, baseUrl, routeRendererFactory, skipped, activeStaticPathnames, sitemapEligiblePathnames } = input;
263
+ const routes = input.preloadedRoutes ?? (await router.listStaticGenerationRoutes({ runtimeOrigin: baseUrl }));
264
+ appLogger.debug('Static Pages', routes.map((route) => route.requestUrl));
265
+ const directories = this.getDirectories(routes.map((route) => route.requestUrl));
266
+ await runWithConcurrency(routes, resolveStaticPageConcurrency(), async (route) => {
267
+ try {
268
+ await this.writeStaticPageArtifact({
269
+ pathname: route.pathname,
270
+ sourceFile: route.templateRoute.filePath,
271
+ directories,
272
+ debugLabel: route.requestUrl,
273
+ activeStaticPathnames,
274
+ onSuccessfulExport: () => this.considerSitemapEligibility({
275
+ pathname: route.pathname,
276
+ sitemapEligiblePathnames,
277
+ resolveMetadata: () => {
278
+ if (!routeRendererFactory) {
279
+ throw new Error(STATIC_SITE_GENERATOR_ERRORS.ROUTE_RENDERER_FACTORY_REQUIRED);
280
+ }
281
+ return this.resolveFilesystemPageMetadata({
282
+ filePath: route.templateRoute.filePath,
283
+ params: route.params,
284
+ baseUrl,
285
+ routeRendererFactory,
286
+ });
287
+ },
288
+ }),
289
+ createContents: () => this.createFilesystemStaticContents({
290
+ route,
291
+ baseUrl,
292
+ routeRendererFactory,
293
+ skipped,
294
+ }),
295
+ });
296
+ }
297
+ catch (error) {
298
+ appLogger.error(`Error generating static page for ${route.requestUrl}:`, error instanceof Error ? error : String(error));
299
+ }
300
+ });
301
+ }
302
+ createStaticExportContext(input) {
303
+ return {
304
+ appConfig: this.appConfig,
305
+ router: input.router,
306
+ baseUrl: input.baseUrl,
307
+ routeRendererFactory: input.routeRendererFactory,
308
+ staticRoutes: input.staticRoutes,
309
+ force: input.force,
310
+ preserveExportDirectory: input.preserveExportDirectory,
311
+ routes: input.routes,
312
+ };
293
313
  }
294
- return resolved;
295
- }
296
- /**
297
- * Get the output file path for a given route.
298
- */
299
- getOutputPath(routePath, directories = []) {
300
- let outputName;
301
- if (routePath === "/") {
302
- outputName = "index.html";
303
- } else if (directories.includes(routePath)) {
304
- outputName = `${routePath}/index.html`;
305
- } else if (routePath.endsWith("/")) {
306
- outputName = `${routePath}index.html`;
307
- } else {
308
- outputName = `${routePath}.html`;
314
+ async invokeStaticExportHook(hook, context) {
315
+ for (const integration of this.appConfig.integrations) {
316
+ const handler = integration[hook];
317
+ if (typeof handler === 'function') {
318
+ await handler.call(integration, context);
319
+ }
320
+ }
321
+ }
322
+ /**
323
+ * Executes the full static-generation workflow for one app run.
324
+ */
325
+ async run({ router, baseUrl, routeRendererFactory, staticRoutes, force = false, preserveExportDirectory = false, }) {
326
+ const skippedDynamicPages = [];
327
+ const activeStaticPathnames = new Set();
328
+ const sitemapEligiblePathnames = this.appConfig.sitemap?.enabled ? new Set() : undefined;
329
+ this.forceFullStaticGeneration = force;
330
+ this.staticRenderCacheContext = createRouteModuleStaticRenderCacheContext(this.appConfig);
331
+ this.pageModuleLoader = undefined;
332
+ if (!force) {
333
+ this.getRouteModuleBuildCache().ensureIncrementalStaticGenerationContext(this.staticRenderCacheContext);
334
+ }
335
+ if (shouldPrebuildProductionPageBrowserGraphs() && force) {
336
+ clearProductionPageBrowserGraphSession(this.appConfig);
337
+ }
338
+ const routes = await router.listStaticGenerationRoutes({ runtimeOrigin: baseUrl });
339
+ const exportRoutes = routes.map((route) => toEcopagesRouteInfo(route));
340
+ if (shouldBuildPagesUnifiedGraph()) {
341
+ await ensurePagesUnifiedGraphBuilt({
342
+ appConfig: this.appConfig,
343
+ entryPaths: routes.map((route) => route.templateRoute.filePath),
344
+ outdir: getServerModuleBuildCacheOutdir(this.appConfig),
345
+ force,
346
+ });
347
+ }
348
+ const staticExportContext = this.createStaticExportContext({
349
+ router,
350
+ baseUrl,
351
+ routeRendererFactory,
352
+ staticRoutes,
353
+ force,
354
+ preserveExportDirectory,
355
+ routes: exportRoutes,
356
+ });
357
+ await this.invokeStaticExportHook('beforeStaticExport', staticExportContext);
358
+ try {
359
+ if (shouldPrebuildProductionPageBrowserGraphs() && routeRendererFactory) {
360
+ await prebuildProductionPageBrowserGraphs(routes.map((route) => ({
361
+ routeFile: route.templateRoute.filePath,
362
+ params: route.params,
363
+ })), routeRendererFactory);
364
+ }
365
+ this.generateRobotsTxt();
366
+ await this.generateStaticPages({
367
+ router,
368
+ baseUrl,
369
+ routeRendererFactory,
370
+ skipped: skippedDynamicPages,
371
+ activeStaticPathnames,
372
+ preloadedRoutes: routes,
373
+ sitemapEligiblePathnames,
374
+ });
375
+ if (staticRoutes && staticRoutes.length > 0 && routeRendererFactory) {
376
+ await this.generateExplicitStaticPages({
377
+ staticRoutes,
378
+ routeRendererFactory,
379
+ skipped: skippedDynamicPages,
380
+ activeStaticPathnames,
381
+ sitemapEligiblePathnames,
382
+ });
383
+ }
384
+ if (preserveExportDirectory) {
385
+ this.pruneStaleStaticOutputs(activeStaticPathnames);
386
+ }
387
+ }
388
+ catch (error) {
389
+ if (shouldPrebuildProductionPageBrowserGraphs()) {
390
+ clearProductionPageBrowserGraphSession(this.appConfig);
391
+ }
392
+ throw error;
393
+ }
394
+ finally {
395
+ await this.invokeStaticExportHook('afterStaticExport', staticExportContext);
396
+ }
397
+ if (this.appConfig.sitemap?.enabled && sitemapEligiblePathnames) {
398
+ const locations = resolveSitemapLocations({
399
+ eligiblePathnames: [...sitemapEligiblePathnames],
400
+ sitemap: this.appConfig.sitemap,
401
+ baseUrl,
402
+ });
403
+ this.generateSitemap(locations, this.appConfig.sitemap);
404
+ }
405
+ if (skippedDynamicPages.length > 0) {
406
+ appLogger.debug(`Skipped ${skippedDynamicPages.length} page(s) with cache: 'dynamic' (not supported in static generation)`, skippedDynamicPages);
407
+ }
408
+ }
409
+ async generateExplicitStaticPages(input) {
410
+ appLogger.debug('Generating explicit static routes', input.staticRoutes.map((r) => r.path));
411
+ for (const route of input.staticRoutes) {
412
+ try {
413
+ const mod = await route.loader();
414
+ const view = mod.default;
415
+ if (this.shouldSkipStaticView(route.path, view)) {
416
+ input.skipped?.push(route.path);
417
+ continue;
418
+ }
419
+ await this.generateExplicitStaticRoute({
420
+ routePath: route.path,
421
+ view,
422
+ routeRendererFactory: input.routeRendererFactory,
423
+ activeStaticPathnames: input.activeStaticPathnames,
424
+ sitemapEligiblePathnames: input.sitemapEligiblePathnames,
425
+ });
426
+ }
427
+ catch (error) {
428
+ appLogger.error(`Error generating explicit static page for ${route.path}:`, error instanceof Error ? error : String(error));
429
+ }
430
+ }
431
+ }
432
+ resolveExplicitViewSourceFile(view) {
433
+ const sourceFile = view.config?.identity?.file;
434
+ if (!sourceFile) {
435
+ return undefined;
436
+ }
437
+ return path.isAbsolute(sourceFile) ? sourceFile : path.join(this.appConfig.rootDir, sourceFile);
438
+ }
439
+ async generateExplicitStaticRoute(input) {
440
+ const { routePath, view, routeRendererFactory, activeStaticPathnames, sitemapEligiblePathnames } = input;
441
+ const { renderer, routeEntries } = await this.planExplicitStaticRoute({
442
+ routePath,
443
+ view,
444
+ routeRendererFactory,
445
+ });
446
+ const sourceFile = this.resolveExplicitViewSourceFile(view);
447
+ for (const { pathname, params } of routeEntries) {
448
+ await this.writeStaticPageArtifact({
449
+ pathname,
450
+ sourceFile,
451
+ debugLabel: pathname,
452
+ activeStaticPathnames,
453
+ onSuccessfulExport: () => this.considerSitemapEligibility({
454
+ pathname,
455
+ sitemapEligiblePathnames,
456
+ resolveMetadata: async () => {
457
+ const { props } = await prepareExplicitStaticRender({
458
+ routePath,
459
+ view,
460
+ params,
461
+ appConfig: this.appConfig,
462
+ runtimeOrigin: this.appConfig.baseUrl,
463
+ routeRendererFactory,
464
+ errors: STATIC_SITE_GENERATOR_ERRORS,
465
+ });
466
+ return this.resolveExplicitViewMetadata({ view, params, props });
467
+ },
468
+ }),
469
+ createContents: () => this.createExplicitStaticContents({
470
+ routePath,
471
+ view,
472
+ params,
473
+ routeRendererFactory,
474
+ renderer,
475
+ }),
476
+ });
477
+ appLogger.debug(`Generated static page: ${pathname}`);
478
+ }
479
+ }
480
+ async planExplicitStaticRoute(input) {
481
+ const { renderer } = await prepareExplicitStaticRender({
482
+ routePath: input.routePath,
483
+ view: input.view,
484
+ params: {},
485
+ appConfig: this.appConfig,
486
+ runtimeOrigin: this.appConfig.baseUrl,
487
+ routeRendererFactory: input.routeRendererFactory,
488
+ errors: STATIC_SITE_GENERATOR_ERRORS,
489
+ });
490
+ return {
491
+ renderer,
492
+ routeEntries: await this.listExplicitStaticRouteEntries(input.routePath, input.view),
493
+ };
494
+ }
495
+ async createExplicitStaticContents(input) {
496
+ const { props, view: renderableView } = await prepareExplicitStaticRender({
497
+ routePath: input.routePath,
498
+ view: input.view,
499
+ params: input.params,
500
+ appConfig: this.appConfig,
501
+ runtimeOrigin: this.appConfig.baseUrl,
502
+ routeRendererFactory: input.routeRendererFactory,
503
+ errors: STATIC_SITE_GENERATOR_ERRORS,
504
+ });
505
+ const response = await input.renderer.renderToResponse(renderableView, props, {});
506
+ return response.text();
507
+ }
508
+ async listExplicitStaticRouteEntries(routePath, view) {
509
+ const isDynamic = routePath.includes(':') || routePath.includes('[');
510
+ if (!isDynamic) {
511
+ return [{ pathname: routePath, params: {} }];
512
+ }
513
+ if (!view.staticPaths) {
514
+ throw new Error(STATIC_SITE_GENERATOR_ERRORS.dynamicRouteRequiresStaticPaths(routePath));
515
+ }
516
+ const { paths } = await view.staticPaths({
517
+ appConfig: this.appConfig,
518
+ runtimeOrigin: this.appConfig.baseUrl,
519
+ });
520
+ return paths.map(({ params }) => ({
521
+ pathname: this.resolveRoutePath(routePath, params),
522
+ params,
523
+ }));
524
+ }
525
+ /**
526
+ * Resolve a route path template with actual params.
527
+ * Supports both :param and [param] syntax.
528
+ */
529
+ resolveRoutePath(routePath, params) {
530
+ let resolved = routePath;
531
+ for (const [key, value] of Object.entries(params)) {
532
+ const paramValue = Array.isArray(value) ? value.join('/') : value;
533
+ resolved = resolved.replace(`:${key}`, paramValue);
534
+ resolved = resolved.replace(`[${key}]`, paramValue);
535
+ resolved = resolved.replace(`[...${key}]`, paramValue);
536
+ }
537
+ return resolved;
538
+ }
539
+ /**
540
+ * Get the output file path for a given route.
541
+ */
542
+ getOutputPath(routePath, directories = []) {
543
+ let outputName;
544
+ if (routePath === '/') {
545
+ outputName = 'index.html';
546
+ }
547
+ else if (directories.includes(routePath)) {
548
+ outputName = `${routePath}/index.html`;
549
+ }
550
+ else if (routePath.endsWith('/')) {
551
+ outputName = `${routePath}index.html`;
552
+ }
553
+ else {
554
+ outputName = `${routePath}.html`;
555
+ }
556
+ return path.join(this.getExportDir(), outputName);
309
557
  }
310
- return path.join(this.getExportDir(), outputName);
311
- }
312
558
  }
313
- export {
314
- STATIC_SITE_GENERATOR_ERRORS,
315
- StaticSiteGenerator
316
- };