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

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 (338) hide show
  1. package/README.md +1 -0
  2. package/package.json +82 -3
  3. package/src/adapters/abstract/application-adapter.d.ts +0 -8
  4. package/src/adapters/abstract/application-adapter.js +252 -261
  5. package/src/adapters/abstract/router-adapter.js +12 -4
  6. package/src/adapters/abstract/segment-path-matcher.js +132 -134
  7. package/src/adapters/abstract/server-adapter.js +22 -14
  8. package/src/adapters/abstract/ws-pattern-matcher.js +24 -26
  9. package/src/adapters/bun/bun-user-websocket-lifecycle.js +83 -86
  10. package/src/adapters/bun/client-bridge.js +51 -50
  11. package/src/adapters/bun/create-app.js +171 -161
  12. package/src/adapters/bun/hmr-manager.js +62 -57
  13. package/src/adapters/bun/index.js +2 -31
  14. package/src/adapters/bun/runtime-host.js +61 -54
  15. package/src/adapters/bun/server-adapter.d.ts +0 -1
  16. package/src/adapters/bun/server-adapter.js +561 -561
  17. package/src/adapters/bun/static-preview-host.js +43 -46
  18. package/src/adapters/create-app.js +11 -14
  19. package/src/adapters/index.js +2 -30
  20. package/src/adapters/node/create-app.js +123 -129
  21. package/src/adapters/node/http-request-bridge.js +147 -106
  22. package/src/adapters/node/node-client-bridge.js +62 -64
  23. package/src/adapters/node/node-hmr-manager.js +58 -48
  24. package/src/adapters/node/runtime-host.js +96 -89
  25. package/src/adapters/node/server-adapter-dependencies.js +18 -21
  26. package/src/adapters/node/server-adapter.d.ts +0 -1
  27. package/src/adapters/node/server-adapter.js +347 -326
  28. package/src/adapters/node/static-content-server.js +172 -191
  29. package/src/adapters/node/static-preview-host.js +87 -78
  30. package/src/adapters/shared/hmr/dev-transform-entrypoint-registry.d.ts +16 -0
  31. package/src/adapters/shared/hmr/dev-transform-entrypoint-registry.js +32 -0
  32. package/src/adapters/shared/hmr/hmr-html-response.js +46 -32
  33. package/src/adapters/shared/hmr/shared-hmr-manager.d.ts +29 -38
  34. package/src/adapters/shared/hmr/shared-hmr-manager.js +439 -425
  35. package/src/adapters/shared/http/api-request-pipeline.js +122 -119
  36. package/src/adapters/shared/http/api-response.js +77 -77
  37. package/src/adapters/shared/http/create-body-response.js +22 -19
  38. package/src/adapters/shared/http/define-api-handler.js +41 -55
  39. package/src/adapters/shared/http/explicit-static-render-preparation.js +26 -23
  40. package/src/adapters/shared/http/explicit-static-route-matcher.js +55 -62
  41. package/src/adapters/shared/http/file-route-middleware-pipeline.js +81 -75
  42. package/src/adapters/shared/http/fs-server-response-factory.js +101 -96
  43. package/src/adapters/shared/http/fs-server-response-matcher.js +239 -257
  44. package/src/adapters/shared/http/run-middleware-chain.js +15 -15
  45. package/src/adapters/shared/runtime/application-adapter.js +72 -87
  46. package/src/adapters/shared/runtime/copy-runtime-public-dir.js +25 -22
  47. package/src/adapters/shared/runtime/port-manager.js +207 -177
  48. package/src/adapters/shared/runtime/render-context.js +94 -79
  49. package/src/adapters/shared/runtime/runtime-app-bootstrap.js +33 -38
  50. package/src/adapters/shared/runtime/runtime-host.js +1 -0
  51. package/src/adapters/shared/runtime/runtime-server-lifecycle.d.ts +2 -3
  52. package/src/adapters/shared/runtime/runtime-server-lifecycle.js +65 -51
  53. package/src/adapters/shared/runtime/server-adapter.d.ts +1 -0
  54. package/src/adapters/shared/runtime/server-adapter.js +233 -217
  55. package/src/adapters/shared/runtime/server-route-handler.js +74 -70
  56. package/src/adapters/shared/runtime/server-static-builder.js +165 -184
  57. package/src/adapters/shared/runtime/static-preview-host.js +1 -0
  58. package/src/adapters/shared/ws/node-http-websocket-upgrades.js +97 -88
  59. package/src/adapters/shared/ws/websocket-lifecycle.js +57 -50
  60. package/src/build/README.md +52 -1
  61. package/src/build/app-build-manifest-runtime.js +129 -108
  62. package/src/build/browser/browser-runtime-manifest.js +47 -50
  63. package/src/build/browser/browser-runtime-plugin-helpers.js +32 -12
  64. package/src/build/browser/browser-runtime-plugin.js +206 -160
  65. package/src/build/browser/jsx-ownership-plugins.js +51 -37
  66. package/src/build/browser/lit-static-render-worker-context.js +3 -5
  67. package/src/build/build-adapter.js +276 -139
  68. package/src/build/cache/build-input-fingerprint.js +28 -26
  69. package/src/build/cache/cache-constants.js +4 -6
  70. package/src/build/cache/cache-keys.js +64 -56
  71. package/src/build/cache/pages-unified-graph-build.js +179 -178
  72. package/src/build/cache/production-build-cache.js +47 -54
  73. package/src/build/cache/server-entry-build-cache.js +134 -146
  74. package/src/build/contracts/build-contracts.d.ts +4 -4
  75. package/src/build/contracts/build-contracts.js +1 -0
  76. package/src/build/contracts/build-manifest.js +58 -43
  77. package/src/build/contracts/build-types.js +1 -0
  78. package/src/build/rolldown/rolldown-adapter-helpers.d.ts +9 -0
  79. package/src/build/rolldown/rolldown-adapter-helpers.js +405 -298
  80. package/src/build/rolldown/rolldown-build-adapter.js +53 -61
  81. package/src/build/rolldown/rolldown-build-invocation-metrics.js +31 -35
  82. package/src/build/rolldown/rolldown-plugin-bridge.js +264 -194
  83. package/src/build/rolldown/rolldown-source-transform-pass.js +59 -50
  84. package/src/build/rolldown/runtime-build-output-normalizer.js +227 -175
  85. package/src/build/rolldown/server-side-css-shim-plugin.js +54 -31
  86. package/src/build/runtime/build-profile-options.js +36 -36
  87. package/src/build/runtime/build-request-identity.js +70 -45
  88. package/src/build/runtime/build-request-policy.js +80 -42
  89. package/src/build/runtime/build-runtime.js +64 -54
  90. package/src/build/runtime/deduping-build-executor.js +38 -32
  91. package/src/build/runtime/parallel-build-executor.js +58 -50
  92. package/src/build/runtime/serialized-build-executor.js +78 -62
  93. package/src/cache/index.js +6 -6
  94. package/src/cache/module-parse-cache.js +99 -68
  95. package/src/client/navigation-scripts/classification.js +45 -37
  96. package/src/client/navigation-scripts/index.js +3 -23
  97. package/src/client/navigation-scripts/navigation-scripts.test.browser.js +58 -62
  98. package/src/client/navigation-scripts/registry.js +15 -11
  99. package/src/client/navigation-scripts/rerun-queue.js +81 -64
  100. package/src/client/scroll.js +32 -24
  101. package/src/client/scroll.test.browser.js +27 -33
  102. package/src/client/view-transitions.js +68 -55
  103. package/src/config/config-builder.d.ts +8 -0
  104. package/src/config/config-builder.js +637 -642
  105. package/src/config/constants.js +44 -24
  106. package/src/declarations.d.ts +1 -0
  107. package/src/dev/README.md +24 -0
  108. package/src/dev/client-bridge-registry.js +7 -12
  109. package/src/dev/dev-client-ownership.js +7 -5
  110. package/src/dev/hmr-manager-registry.js +7 -12
  111. package/src/dev/host-runtime.js +25 -30
  112. package/src/dev/runtime-server-started-message.js +2 -5
  113. package/src/dev/sc-server.js +106 -103
  114. package/src/dev/transform-server/dev-transform-bundler.d.ts +24 -0
  115. package/src/dev/transform-server/dev-transform-bundler.js +79 -0
  116. package/src/dev/transform-server/dev-transform-externalize-plugin.d.ts +12 -0
  117. package/src/dev/transform-server/dev-transform-externalize-plugin.js +29 -0
  118. package/src/dev/transform-server/dev-transform-import-rewriter.d.ts +16 -0
  119. package/src/dev/transform-server/dev-transform-import-rewriter.js +110 -0
  120. package/src/dev/transform-server/dev-transform-module-kind.d.ts +13 -0
  121. package/src/dev/transform-server/dev-transform-module-kind.js +17 -0
  122. package/src/dev/transform-server/dev-transform-runtime-specifiers.d.ts +5 -0
  123. package/src/dev/transform-server/dev-transform-runtime-specifiers.js +16 -0
  124. package/src/dev/transform-server/dev-transform-server.d.ts +41 -0
  125. package/src/dev/transform-server/dev-transform-server.js +191 -0
  126. package/src/dev/transform-server/dev-transform-url.d.ts +13 -0
  127. package/src/dev/transform-server/dev-transform-url.js +58 -0
  128. package/src/dev/transform-server/dev-transform-vendor-registry.d.ts +27 -0
  129. package/src/dev/transform-server/dev-transform-vendor-registry.js +145 -0
  130. package/src/dev/transform-server/index.d.ts +6 -0
  131. package/src/dev/transform-server/index.js +4 -0
  132. package/src/dev/transform-server/types.d.ts +15 -0
  133. package/src/dev/transform-server/types.js +1 -0
  134. package/src/dev-toolbar/README.md +51 -0
  135. package/src/dev-toolbar/define-dev-tool.d.ts +21 -0
  136. package/src/dev-toolbar/define-dev-tool.js +9 -0
  137. package/src/dev-toolbar/dev-toolbar-config.d.ts +25 -0
  138. package/src/dev-toolbar/dev-toolbar-config.js +19 -0
  139. package/src/dev-toolbar/dev-toolbar-host.d.ts +49 -0
  140. package/src/dev-toolbar/dev-toolbar-host.js +117 -0
  141. package/src/dev-toolbar/dev-toolbar-html-response.d.ts +11 -0
  142. package/src/dev-toolbar/dev-toolbar-html-response.js +14 -0
  143. package/src/dev-toolbar/dev-toolbar-manifest.d.ts +15 -0
  144. package/src/dev-toolbar/dev-toolbar-manifest.js +52 -0
  145. package/src/dev-toolbar/dev-toolbar-package.d.ts +31 -0
  146. package/src/dev-toolbar/dev-toolbar-package.js +72 -0
  147. package/src/dev-toolbar/dev-toolbar-runtime-paths.d.ts +10 -0
  148. package/src/dev-toolbar/dev-toolbar-runtime-paths.js +13 -0
  149. package/src/diagnostics/request-build-dedupe.js +34 -28
  150. package/src/diagnostics/startup-trace.d.ts +10 -1
  151. package/src/diagnostics/startup-trace.js +269 -241
  152. package/src/eco/README.md +6 -0
  153. package/src/eco/eco-declared-component.js +19 -14
  154. package/src/eco/eco.browser.js +56 -69
  155. package/src/eco/eco.js +156 -96
  156. package/src/eco/eco.types.js +5 -0
  157. package/src/eco/eco.utils.js +1 -10
  158. package/src/eco/global-injector-map.js +55 -41
  159. package/src/eco/lazy-injector-map.js +90 -60
  160. package/src/eco/module-dependencies.js +52 -44
  161. package/src/eco/page-layout-normalization.js +59 -49
  162. package/src/errors/http-error.js +50 -49
  163. package/src/errors/index.js +3 -12
  164. package/src/errors/locals-access-error.js +5 -8
  165. package/src/errors/undeclared-component-dependency-error.js +15 -15
  166. package/src/global/app-logger.js +3 -6
  167. package/src/hmr/README.md +10 -0
  168. package/src/hmr/client/hmr-runtime.js +117 -113
  169. package/src/hmr/client/module-update.d.ts +13 -0
  170. package/src/hmr/client/module-update.js +39 -0
  171. package/src/hmr/hmr-asset-paths.d.ts +14 -0
  172. package/src/hmr/hmr-asset-paths.js +22 -0
  173. package/src/hmr/hmr-entrypoint-output.d.ts +11 -39
  174. package/src/hmr/hmr-entrypoint-output.js +28 -54
  175. package/src/hmr/hmr-file-change-prep.js +13 -16
  176. package/src/hmr/hmr-registered-entrypoints-context.d.ts +7 -0
  177. package/src/hmr/hmr-registered-entrypoints-context.js +1 -0
  178. package/src/hmr/hmr-runtime-paths.d.ts +10 -0
  179. package/src/hmr/hmr-runtime-paths.js +13 -0
  180. package/src/hmr/hmr-strategy.d.ts +5 -11
  181. package/src/hmr/hmr-strategy.js +113 -61
  182. package/src/hmr/strategies/default-hmr-strategy.js +55 -33
  183. package/src/hmr/strategies/js-hmr-strategy.d.ts +6 -95
  184. package/src/hmr/strategies/js-hmr-strategy.js +104 -217
  185. package/src/hmr/strategies/server-rendered-template-hmr-strategy.js +33 -27
  186. package/src/index.browser.js +1 -4
  187. package/src/index.d.ts +1 -0
  188. package/src/index.js +6 -47
  189. package/src/integrations/ghtml/ghtml-renderer.js +12 -7
  190. package/src/integrations/ghtml/ghtml.constants.js +1 -4
  191. package/src/integrations/ghtml/ghtml.plugin.js +9 -12
  192. package/src/islands/README.md +25 -0
  193. package/src/islands/island-host.d.ts +37 -0
  194. package/src/islands/island-host.js +55 -0
  195. package/src/plugins/alias-resolver-cache.js +114 -97
  196. package/src/plugins/alias-resolver-plugin.js +33 -47
  197. package/src/plugins/define-integration.js +18 -17
  198. package/src/plugins/eco-component-meta-plugin.js +387 -145
  199. package/src/plugins/foreign-jsx-override-plugin.js +49 -35
  200. package/src/plugins/integration-plugin.js +212 -203
  201. package/src/plugins/jsx-import-source.utils.js +16 -21
  202. package/src/plugins/processor.js +159 -149
  203. package/src/plugins/runtime-capability.js +1 -0
  204. package/src/plugins/source-transform.js +109 -79
  205. package/src/plugins/tsconfig-import-resolver.d.ts +17 -0
  206. package/src/plugins/tsconfig-import-resolver.js +218 -142
  207. package/src/route-renderer/README.md +12 -1
  208. package/src/route-renderer/orchestration/document-shell/document-shell-render.service.js +143 -136
  209. package/src/route-renderer/orchestration/document-shell/layout-shell-props.service.js +33 -27
  210. package/src/route-renderer/orchestration/foreign-child/component-render-context.js +173 -126
  211. package/src/route-renderer/orchestration/foreign-child/foreign-child-output.utils.js +165 -154
  212. package/src/route-renderer/orchestration/foreign-child/foreign-subtree-execution.service.js +329 -341
  213. package/src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.js +33 -32
  214. package/src/route-renderer/orchestration/integration-renderer.d.ts +1 -0
  215. package/src/route-renderer/orchestration/integration-renderer.js +731 -750
  216. package/src/route-renderer/orchestration/integration-renderer.test-fixtures.js +168 -172
  217. package/src/route-renderer/orchestration/ownership-graph/component-graph-collectors.js +119 -131
  218. package/src/route-renderer/orchestration/ownership-graph/component-graph.js +82 -91
  219. package/src/route-renderer/orchestration/ownership-graph/ownership-validation.service.js +82 -76
  220. package/src/route-renderer/orchestration/page-browser-graph/global-injector-assets.service.js +29 -31
  221. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-contribution.loader.js +10 -6
  222. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.js +31 -28
  223. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-session.d.ts +3 -0
  224. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-session.js +430 -413
  225. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph.service.js +191 -212
  226. package/src/route-renderer/orchestration/page-browser-graph/processed-asset-dedupe.js +20 -24
  227. package/src/route-renderer/orchestration/route-pipeline/integration-route-render-adapter.d.ts +4 -0
  228. package/src/route-renderer/orchestration/route-pipeline/integration-route-render-adapter.js +24 -24
  229. package/src/route-renderer/orchestration/route-pipeline/marker-artifact.utils.js +22 -24
  230. package/src/route-renderer/orchestration/route-pipeline/robots-meta.contribution.js +41 -34
  231. package/src/route-renderer/orchestration/route-pipeline/route-html-finalization.service.d.ts +5 -0
  232. package/src/route-renderer/orchestration/route-pipeline/route-html-finalization.service.js +42 -22
  233. package/src/route-renderer/orchestration/route-pipeline/route-prepared-options.builder.js +50 -48
  234. package/src/route-renderer/orchestration/route-pipeline/route-prepared-options.utils.js +29 -32
  235. package/src/route-renderer/orchestration/route-pipeline/route-render-orchestrator.js +150 -156
  236. package/src/route-renderer/orchestration/string-markup-renderer.js +48 -51
  237. package/src/route-renderer/page-loading/component-dependency-collection.js +120 -124
  238. package/src/route-renderer/page-loading/declared-asset-collection.js +66 -94
  239. package/src/route-renderer/page-loading/dependency-resolver.js +101 -104
  240. package/src/route-renderer/page-loading/ecopages-virtual-imports.js +68 -54
  241. package/src/route-renderer/page-loading/lazy-entry-collection.js +75 -98
  242. package/src/route-renderer/page-loading/lazy-trigger-planning.js +46 -36
  243. package/src/route-renderer/page-loading/module-declaration-aggregation.js +38 -31
  244. package/src/route-renderer/page-loading/module-declaration-scripts.js +10 -15
  245. package/src/route-renderer/page-loading/page-dependency-bundling.js +156 -113
  246. package/src/route-renderer/page-loading/page-module-loader.js +130 -124
  247. package/src/route-renderer/route-renderer.js +74 -76
  248. package/src/router/client/link-intent.js +55 -39
  249. package/src/router/client/link-intent.test.browser.js +49 -49
  250. package/src/router/client/link-navigation-policy.js +114 -93
  251. package/src/router/client/link-navigation-policy.test.browser.js +70 -80
  252. package/src/router/client/navigation-coordinator.js +235 -211
  253. package/src/router/server/route-registry.js +237 -242
  254. package/src/services/assets/asset-processing-service/asset-dependency-keys.js +64 -53
  255. package/src/services/assets/asset-processing-service/asset-processing.service.js +287 -303
  256. package/src/services/assets/asset-processing-service/asset.factory.js +78 -81
  257. package/src/services/assets/asset-processing-service/assets.types.js +1 -0
  258. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +57 -46
  259. package/src/services/assets/asset-processing-service/browser-runtime-entry-resolution.js +106 -69
  260. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.js +53 -53
  261. package/src/services/assets/asset-processing-service/finalize-processed-asset.js +4 -6
  262. package/src/services/assets/asset-processing-service/grouped-content-bundles.js +79 -80
  263. package/src/services/assets/asset-processing-service/index.js +8 -8
  264. package/src/services/assets/asset-processing-service/inline-content-script-body.js +22 -16
  265. package/src/services/assets/asset-processing-service/materialize-content-script-asset.js +21 -17
  266. package/src/services/assets/asset-processing-service/page-package.js +70 -72
  267. package/src/services/assets/asset-processing-service/processor.interface.js +7 -5
  268. package/src/services/assets/asset-processing-service/processor.registry.js +11 -14
  269. package/src/services/assets/asset-processing-service/processors/base/base-processor.js +59 -62
  270. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.js +102 -117
  271. package/src/services/assets/asset-processing-service/processors/index.js +5 -5
  272. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.js +110 -115
  273. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +95 -97
  274. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +136 -135
  275. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +27 -29
  276. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +34 -40
  277. package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.js +36 -35
  278. package/src/services/assets/asset-processing-service/resolve-integration-plugin.js +14 -16
  279. package/src/services/assets/asset-processing-service/ungrouped-dependency-processing.js +27 -39
  280. package/src/services/assets/browser-bundle.service.js +52 -47
  281. package/src/services/cache/cache.types.js +5 -0
  282. package/src/services/cache/index.js +6 -7
  283. package/src/services/cache/memory-cache-store.js +101 -89
  284. package/src/services/cache/page-cache-service.js +156 -145
  285. package/src/services/cache/page-request-cache-coordinator.service.js +102 -102
  286. package/src/services/html/html-rewriter-provider.service.js +61 -61
  287. package/src/services/html/html-transformer.service.js +249 -266
  288. package/src/services/invalidation/development-invalidation.service.js +252 -241
  289. package/src/services/module-loading/app-module-loader.service.js +1 -0
  290. package/src/services/module-loading/app-server-module-transpiler.service.js +107 -101
  291. package/src/services/module-loading/host-module-loader-registry.js +6 -11
  292. package/src/services/module-loading/module-loading-types.js +1 -0
  293. package/src/services/module-loading/page-module-import.service.js +235 -243
  294. package/src/services/module-loading/route-module-build-cache-registry.js +47 -33
  295. package/src/services/module-loading/route-module-build-cache.js +3 -38
  296. package/src/services/module-loading/route-module-build-cache.store.js +195 -200
  297. package/src/services/module-loading/route-module-build-manifest.js +61 -74
  298. package/src/services/module-loading/route-module-dependency-hasher.js +136 -110
  299. package/src/services/module-loading/server-module-transpiler.service.js +68 -62
  300. package/src/services/module-loading/source-module-support.js +15 -7
  301. package/src/services/runtime-state/dev-graph.service.js +165 -157
  302. package/src/services/runtime-state/entrypoint-dependency-graph.service.js +85 -76
  303. package/src/services/runtime-state/server-invalidation-state.service.js +38 -30
  304. package/src/services/validation/schema-validation-service.js +157 -95
  305. package/src/services/validation/standard-schema.types.js +1 -0
  306. package/src/services/validation/validate-standard-schema.js +13 -13
  307. package/src/static-site-generator/production-page-browser-graph-prebuild.js +35 -19
  308. package/src/static-site-generator/sitemap-routes.js +33 -28
  309. package/src/static-site-generator/sitemap.js +38 -29
  310. package/src/static-site-generator/static-build-invalidation.js +34 -56
  311. package/src/static-site-generator/static-export-context.js +1 -0
  312. package/src/static-site-generator/static-site-generator.js +517 -553
  313. package/src/types/internal-types.d.ts +19 -3
  314. package/src/types/internal-types.js +1 -0
  315. package/src/types/public-types.d.ts +16 -46
  316. package/src/types/public-types.js +1 -0
  317. package/src/utils/deep-merge.js +39 -26
  318. package/src/utils/ecopages-route-info.js +27 -23
  319. package/src/utils/hash.js +3 -6
  320. package/src/utils/html-escaping.js +21 -8
  321. package/src/utils/html.js +1 -4
  322. package/src/utils/invariant.js +11 -10
  323. package/src/utils/locals-utils.js +32 -22
  324. package/src/utils/parse-cli-args.js +73 -65
  325. package/src/utils/path-pattern.js +38 -23
  326. package/src/utils/path-utils.module.js +8 -11
  327. package/src/utils/resolve-entry-file.js +70 -38
  328. package/src/utils/resolve-work-dir.js +23 -27
  329. package/src/utils/runtime.js +24 -33
  330. package/src/utils/server-utils.module.js +60 -52
  331. package/src/utils/static-file-extensions.js +52 -46
  332. package/src/watchers/project-watcher-ignore.js +16 -15
  333. package/src/watchers/project-watcher.js +385 -366
  334. package/src/watchers/project-watcher.test-helpers.js +45 -50
  335. package/src/adapters/shared/hmr/hmr-entrypoint-registrar.d.ts +0 -56
  336. package/src/adapters/shared/hmr/hmr-entrypoint-registrar.js +0 -106
  337. package/src/build/cache/dev-browser-script-cache.d.ts +0 -34
  338. package/src/build/cache/dev-browser-script-cache.js +0 -90
@@ -1,268 +1,250 @@
1
- import path from "node:path";
2
- import { appLogger } from "../../../global/app-logger.js";
3
- import { PageRequestCacheCoordinator } from "../../../services/cache/page-request-cache-coordinator.service.js";
4
- import { ServerUtils } from "../../../utils/server-utils.module.js";
5
- import { FileRouteMiddlewarePipeline } from "./file-route-middleware-pipeline.js";
6
- import { LocalsAccessError } from "../../../errors/locals-access-error.js";
7
- import { isDevelopmentRuntime } from "../../../utils/runtime.js";
8
- class FileSystemResponseMatcher {
9
- appConfig;
10
- assetPrefix;
11
- router;
12
- routeRendererFactory;
13
- fileSystemResponseFactory;
14
- pageRequestCacheCoordinator;
15
- fileRouteMiddlewarePipeline;
16
- constructor({
17
- appConfig,
18
- assetPrefix,
19
- router,
20
- routeRendererFactory,
21
- fileSystemResponseFactory,
22
- cacheService = null,
23
- defaultCacheStrategy = "static"
24
- }) {
25
- this.appConfig = appConfig;
26
- this.assetPrefix = assetPrefix;
27
- this.router = router;
28
- this.routeRendererFactory = routeRendererFactory;
29
- this.fileSystemResponseFactory = fileSystemResponseFactory;
30
- this.pageRequestCacheCoordinator = new PageRequestCacheCoordinator(cacheService, defaultCacheStrategy);
31
- this.fileRouteMiddlewarePipeline = new FileRouteMiddlewarePipeline(cacheService);
32
- }
33
- /**
34
- * Resolves unmatched paths either as static asset requests or as the custom
35
- * not-found page.
36
- * @param requestUrl Incoming pathname.
37
- * @returns Static file response or rendered 404 response.
38
- */
39
- async handleNoMatch(requestUrl) {
40
- const isStaticFileRequest = ServerUtils.hasKnownStaticExtension(requestUrl);
41
- if (!isStaticFileRequest) {
42
- return this.renderCustomNotFoundResponseOrServerError(requestUrl);
1
+ import path from 'node:path';
2
+ import { appLogger } from '../../../global/app-logger.js';
3
+ import { PageRequestCacheCoordinator } from '../../../services/cache/page-request-cache-coordinator.service.js';
4
+ import { ServerUtils } from '../../../utils/server-utils.module.js';
5
+ import { FileRouteMiddlewarePipeline } from './file-route-middleware-pipeline.js';
6
+ import { LocalsAccessError } from '../../../errors/locals-access-error.js';
7
+ import { isDevelopmentRuntime } from '../../../utils/runtime.js';
8
+ /**
9
+ * Matches file-system routes to rendered HTML responses.
10
+ *
11
+ * This render pipeline coordinates page module inspection, request-local policy,
12
+ * renderer invocation, middleware execution, cache integration, and fallback
13
+ * error translation.
14
+ */
15
+ export class FileSystemResponseMatcher {
16
+ appConfig;
17
+ assetPrefix;
18
+ router;
19
+ routeRendererFactory;
20
+ fileSystemResponseFactory;
21
+ pageRequestCacheCoordinator;
22
+ fileRouteMiddlewarePipeline;
23
+ constructor({ appConfig, assetPrefix, router, routeRendererFactory, fileSystemResponseFactory, cacheService = null, defaultCacheStrategy = 'static', }) {
24
+ this.appConfig = appConfig;
25
+ this.assetPrefix = assetPrefix;
26
+ this.router = router;
27
+ this.routeRendererFactory = routeRendererFactory;
28
+ this.fileSystemResponseFactory = fileSystemResponseFactory;
29
+ this.pageRequestCacheCoordinator = new PageRequestCacheCoordinator(cacheService, defaultCacheStrategy);
30
+ this.fileRouteMiddlewarePipeline = new FileRouteMiddlewarePipeline(cacheService);
43
31
  }
44
- const relativeUrl = requestUrl.startsWith("/") ? requestUrl.slice(1) : requestUrl;
45
- const filePath = path.join(this.assetPrefix, relativeUrl);
46
- const contentType = ServerUtils.getContentType(filePath);
47
- const response = await this.fileSystemResponseFactory.createFileResponse(filePath, contentType);
48
- return response ?? this.renderCustomNotFoundResponseOrServerError(requestUrl);
49
- }
50
- /**
51
- * Handles a matched file-system page route.
52
- *
53
- * The method inspects page metadata needed for request-time execution,
54
- * prepares the renderer invocation, validates middleware/cache constraints,
55
- * and delegates caching plus middleware execution to dedicated collaborators.
56
- *
57
- * @param match Router match result.
58
- * @param request Optional incoming request. A synthetic GET request is created when omitted.
59
- * @returns Final response for the matched route.
60
- */
61
- async handleMatch(match, request) {
62
- try {
63
- const executionPlan = await this.createExecutionPlan(match, request);
64
- this.fileRouteMiddlewarePipeline.assertValidConfiguration({
65
- middleware: executionPlan.pageMiddleware,
66
- pageCacheStrategy: executionPlan.pageCacheStrategy,
67
- filePath: executionPlan.pageFilePath
68
- });
69
- const routeRenderer = this.routeRendererFactory.getPageRenderer(executionPlan.pageFilePath);
70
- const middlewareContext = this.fileRouteMiddlewarePipeline.createContext({
71
- request: executionPlan.request,
72
- params: match.params,
73
- locals: executionPlan.localsStore
74
- });
75
- const renderFn = async () => {
76
- const result = await routeRenderer.execute({
77
- file: executionPlan.pageFilePath,
78
- params: match.params,
79
- query: match.query,
80
- locals: executionPlan.localsForRender
32
+ /**
33
+ * Resolves unmatched paths either as static asset requests or as the custom
34
+ * not-found page.
35
+ * @param requestUrl Incoming pathname.
36
+ * @returns Static file response or rendered 404 response.
37
+ */
38
+ async handleNoMatch(requestUrl) {
39
+ const isStaticFileRequest = ServerUtils.hasKnownStaticExtension(requestUrl);
40
+ if (!isStaticFileRequest) {
41
+ return this.renderCustomNotFoundResponseOrServerError(requestUrl);
42
+ }
43
+ const relativeUrl = requestUrl.startsWith('/') ? requestUrl.slice(1) : requestUrl;
44
+ const filePath = path.join(this.assetPrefix, relativeUrl);
45
+ const contentType = ServerUtils.getContentType(filePath);
46
+ const response = await this.fileSystemResponseFactory.createFileResponse(filePath, contentType);
47
+ return response ?? this.renderCustomNotFoundResponseOrServerError(requestUrl);
48
+ }
49
+ /**
50
+ * Handles a matched file-system page route.
51
+ *
52
+ * The method inspects page metadata needed for request-time execution,
53
+ * prepares the renderer invocation, validates middleware/cache constraints,
54
+ * and delegates caching plus middleware execution to dedicated collaborators.
55
+ *
56
+ * @param match Router match result.
57
+ * @param request Optional incoming request. A synthetic GET request is created when omitted.
58
+ * @returns Final response for the matched route.
59
+ */
60
+ async handleMatch(match, request) {
61
+ try {
62
+ const executionPlan = await this.createExecutionPlan(match, request);
63
+ this.fileRouteMiddlewarePipeline.assertValidConfiguration({
64
+ middleware: executionPlan.pageMiddleware,
65
+ pageCacheStrategy: executionPlan.pageCacheStrategy,
66
+ filePath: executionPlan.pageFilePath,
67
+ });
68
+ const routeRenderer = this.routeRendererFactory.getPageRenderer(executionPlan.pageFilePath);
69
+ const middlewareContext = this.fileRouteMiddlewarePipeline.createContext({
70
+ request: executionPlan.request,
71
+ params: match.params,
72
+ locals: executionPlan.localsStore,
73
+ });
74
+ const renderFn = async () => {
75
+ const result = await routeRenderer.execute({
76
+ file: executionPlan.pageFilePath,
77
+ params: match.params,
78
+ query: match.query,
79
+ locals: executionPlan.localsForRender,
80
+ });
81
+ const html = await this.pageRequestCacheCoordinator.bodyToString(result.body);
82
+ const strategy = result.cacheStrategy ?? this.pageRequestCacheCoordinator.getDefaultCacheStrategy();
83
+ return { html, strategy };
84
+ };
85
+ const renderResponse = async () => {
86
+ return this.pageRequestCacheCoordinator.render({
87
+ cacheKey: executionPlan.cacheKey,
88
+ pageCacheStrategy: executionPlan.pageCacheStrategy,
89
+ renderFn,
90
+ });
91
+ };
92
+ return await this.fileRouteMiddlewarePipeline.run({
93
+ middleware: executionPlan.pageMiddleware,
94
+ context: middlewareContext,
95
+ renderResponse,
96
+ });
97
+ }
98
+ catch (error) {
99
+ if (error instanceof Response) {
100
+ return error;
101
+ }
102
+ if (error instanceof LocalsAccessError) {
103
+ return await this.createInternalServerErrorResponse(error.message, match.requestedPathname, error);
104
+ }
105
+ return await this.createInternalServerErrorResponse(error instanceof Error ? error.message : 'Internal Server Error', match.requestedPathname, error);
106
+ }
107
+ }
108
+ /**
109
+ * Renders the app-owned custom 404 page, falling back to the default text 404
110
+ * when the page template cannot be resolved.
111
+ */
112
+ async renderCustomNotFoundResponse() {
113
+ return this.renderCustomErrorPageResponse({
114
+ templatePath: this.appConfig.absolutePaths.error404TemplatePath,
115
+ label: '404',
116
+ createDefaultResponse: () => this.fileSystemResponseFactory.createDefaultNotFoundResponse(),
117
+ createHtmlResponse: (body) => this.fileSystemResponseFactory.createHtmlNotFoundResponse(body),
81
118
  });
82
- const html = await this.pageRequestCacheCoordinator.bodyToString(result.body);
83
- const strategy = result.cacheStrategy ?? this.pageRequestCacheCoordinator.getDefaultCacheStrategy();
84
- return { html, strategy };
85
- };
86
- const renderResponse = async () => {
87
- return this.pageRequestCacheCoordinator.render({
88
- cacheKey: executionPlan.cacheKey,
89
- pageCacheStrategy: executionPlan.pageCacheStrategy,
90
- renderFn
119
+ }
120
+ /**
121
+ * Renders the app-owned custom 500 page, falling back to the default text 500
122
+ * when the page template cannot be resolved.
123
+ */
124
+ async renderCustomServerErrorResponse(error) {
125
+ return this.renderCustomErrorPageResponse({
126
+ templatePath: this.appConfig.absolutePaths.error500TemplatePath,
127
+ label: '500',
128
+ props: this.buildServerErrorPageProps(error),
129
+ createDefaultResponse: () => this.fileSystemResponseFactory.createDefaultServerErrorResponse(),
130
+ createHtmlResponse: (body) => this.fileSystemResponseFactory.createHtmlServerErrorResponse(body),
91
131
  });
92
- };
93
- return await this.fileRouteMiddlewarePipeline.run({
94
- middleware: executionPlan.pageMiddleware,
95
- context: middlewareContext,
96
- renderResponse
97
- });
98
- } catch (error) {
99
- if (error instanceof Response) {
100
- return error;
101
- }
102
- if (error instanceof LocalsAccessError) {
103
- return await this.createInternalServerErrorResponse(error.message, match.requestedPathname, error);
104
- }
105
- return await this.createInternalServerErrorResponse(
106
- error instanceof Error ? error.message : "Internal Server Error",
107
- match.requestedPathname,
108
- error
109
- );
110
132
  }
111
- }
112
- /**
113
- * Renders the app-owned custom 404 page, falling back to the default text 404
114
- * when the page template cannot be resolved.
115
- */
116
- async renderCustomNotFoundResponse() {
117
- return this.renderCustomErrorPageResponse({
118
- templatePath: this.appConfig.absolutePaths.error404TemplatePath,
119
- label: "404",
120
- createDefaultResponse: () => this.fileSystemResponseFactory.createDefaultNotFoundResponse(),
121
- createHtmlResponse: (body) => this.fileSystemResponseFactory.createHtmlNotFoundResponse(body)
122
- });
123
- }
124
- /**
125
- * Renders the app-owned custom 500 page, falling back to the default text 500
126
- * when the page template cannot be resolved.
127
- */
128
- async renderCustomServerErrorResponse(error) {
129
- return this.renderCustomErrorPageResponse({
130
- templatePath: this.appConfig.absolutePaths.error500TemplatePath,
131
- label: "500",
132
- props: this.buildServerErrorPageProps(error),
133
- createDefaultResponse: () => this.fileSystemResponseFactory.createDefaultServerErrorResponse(),
134
- createHtmlResponse: (body) => this.fileSystemResponseFactory.createHtmlServerErrorResponse(body)
135
- });
136
- }
137
- /**
138
- * Builds development-only error details for the custom 500 page.
139
- * @remarks Production omits these fields so stacks are not serialized into HTML.
140
- */
141
- buildServerErrorPageProps(error) {
142
- if (!isDevelopmentRuntime()) {
143
- return void 0;
133
+ /**
134
+ * Builds development-only error details for the custom 500 page.
135
+ * @remarks Production omits these fields so stacks are not serialized into HTML.
136
+ */
137
+ buildServerErrorPageProps(error) {
138
+ if (!isDevelopmentRuntime()) {
139
+ return undefined;
140
+ }
141
+ if (error instanceof Error) {
142
+ return {
143
+ message: error.message,
144
+ stack: error.stack,
145
+ };
146
+ }
147
+ return {
148
+ message: String(error),
149
+ };
144
150
  }
145
- if (error instanceof Error) {
146
- return {
147
- message: error.message,
148
- stack: error.stack
149
- };
151
+ async renderCustomErrorPageResponse({ templatePath, label, props, createDefaultResponse, createHtmlResponse, }) {
152
+ let routeRenderer;
153
+ try {
154
+ routeRenderer = this.routeRendererFactory.getPageRenderer(templatePath);
155
+ }
156
+ catch {
157
+ appLogger.debug(`Custom ${label} template not found, falling back to default ${label} response`, templatePath);
158
+ return createDefaultResponse();
159
+ }
160
+ const result = await routeRenderer.execute({
161
+ file: templatePath,
162
+ props,
163
+ });
164
+ return createHtmlResponse(result.body);
165
+ }
166
+ async renderCustomNotFoundResponseOrServerError(pathname) {
167
+ try {
168
+ return await this.renderCustomNotFoundResponse();
169
+ }
170
+ catch (error) {
171
+ if (error instanceof Response) {
172
+ return error;
173
+ }
174
+ return await this.createInternalServerErrorResponse(error instanceof Error ? error.message : 'Internal Server Error', pathname, error);
175
+ }
150
176
  }
151
- return {
152
- message: String(error)
153
- };
154
- }
155
- async renderCustomErrorPageResponse({
156
- templatePath,
157
- label,
158
- props,
159
- createDefaultResponse,
160
- createHtmlResponse
161
- }) {
162
- let routeRenderer;
163
- try {
164
- routeRenderer = this.routeRendererFactory.getPageRenderer(templatePath);
165
- } catch {
166
- appLogger.debug(
167
- `Custom ${label} template not found, falling back to default ${label} response`,
168
- templatePath
169
- );
170
- return createDefaultResponse();
177
+ /**
178
+ * Logs the original render failure, then tries the custom 500 page once.
179
+ * @remarks Any failure while rendering the custom 500 page falls back to the
180
+ * default plain-text response and never re-enters the custom page path.
181
+ * In development the thrown error's `message` and `stack` are passed into the
182
+ * custom 500 page props.
183
+ */
184
+ async createInternalServerErrorResponse(message, pathname, error) {
185
+ if (isDevelopmentRuntime() || appLogger.isDebugEnabled()) {
186
+ appLogger.error(`[FileSystemResponseMatcher] ${message} at ${pathname}`, error);
187
+ }
188
+ else {
189
+ appLogger.error(`[FileSystemResponseMatcher] Render error at ${pathname}`, error);
190
+ }
191
+ try {
192
+ return await this.renderCustomServerErrorResponse(error);
193
+ }
194
+ catch (serverErrorPageError) {
195
+ if (serverErrorPageError instanceof Response) {
196
+ return serverErrorPageError;
197
+ }
198
+ appLogger.error(`[FileSystemResponseMatcher] Custom 500 template failed at ${pathname}`, serverErrorPageError);
199
+ return this.fileSystemResponseFactory.createDefaultServerErrorResponse();
200
+ }
171
201
  }
172
- const result = await routeRenderer.execute({
173
- file: templatePath,
174
- props
175
- });
176
- return createHtmlResponse(result.body);
177
- }
178
- async renderCustomNotFoundResponseOrServerError(pathname) {
179
- try {
180
- return await this.renderCustomNotFoundResponse();
181
- } catch (error) {
182
- if (error instanceof Response) {
183
- return error;
184
- }
185
- return await this.createInternalServerErrorResponse(
186
- error instanceof Error ? error.message : "Internal Server Error",
187
- pathname,
188
- error
189
- );
202
+ async createExecutionPlan(match, request) {
203
+ const cacheKey = this.pageRequestCacheCoordinator.buildCacheKey({
204
+ pathname: match.requestedPathname,
205
+ query: match.query,
206
+ });
207
+ const resolvedRequest = request ??
208
+ new Request(new URL(cacheKey, this.router.origin).toString(), {
209
+ method: 'GET',
210
+ });
211
+ const localsStore = {};
212
+ const pageFilePath = match.templateRoute.filePath;
213
+ const pageModule = await this.importPageModule(pageFilePath);
214
+ const Page = pageModule?.default;
215
+ const pageMiddleware = (Page?.middleware ?? []);
216
+ const pageCacheStrategy = Page?.cache ?? this.pageRequestCacheCoordinator.getDefaultCacheStrategy();
217
+ return {
218
+ cacheKey,
219
+ request: resolvedRequest,
220
+ pageFilePath,
221
+ pageMiddleware,
222
+ pageCacheStrategy,
223
+ localsStore,
224
+ localsForRender: pageCacheStrategy === 'dynamic' ? localsStore : undefined,
225
+ };
190
226
  }
191
- }
192
- /**
193
- * Logs the original render failure, then tries the custom 500 page once.
194
- * @remarks Any failure while rendering the custom 500 page falls back to the
195
- * default plain-text response and never re-enters the custom page path.
196
- * In development the thrown error's `message` and `stack` are passed into the
197
- * custom 500 page props.
198
- */
199
- async createInternalServerErrorResponse(message, pathname, error) {
200
- if (isDevelopmentRuntime() || appLogger.isDebugEnabled()) {
201
- appLogger.error(`[FileSystemResponseMatcher] ${message} at ${pathname}`, error);
202
- } else {
203
- appLogger.error(`[FileSystemResponseMatcher] Render error at ${pathname}`, error);
227
+ /**
228
+ * Loads the matched page module for request-time inspection.
229
+ *
230
+ * The matcher needs access to page-level metadata such as `cache` and
231
+ * `middleware` before full rendering starts, so it asks the owning route
232
+ * renderer to load the page module. That preserves integration-specific page
233
+ * import setup for request-time inspection as well as for full rendering.
234
+ *
235
+ * @param filePath Absolute page module path.
236
+ * @returns Imported page module.
237
+ */
238
+ async importPageModule(filePath) {
239
+ const routeRenderer = this.routeRendererFactory.getPageRenderer(filePath);
240
+ return routeRenderer.loadPageModule(filePath, {
241
+ cacheScope: 'request-metadata',
242
+ });
204
243
  }
205
- try {
206
- return await this.renderCustomServerErrorResponse(error);
207
- } catch (serverErrorPageError) {
208
- if (serverErrorPageError instanceof Response) {
209
- return serverErrorPageError;
210
- }
211
- appLogger.error(
212
- `[FileSystemResponseMatcher] Custom 500 template failed at ${pathname}`,
213
- serverErrorPageError
214
- );
215
- return this.fileSystemResponseFactory.createDefaultServerErrorResponse();
244
+ /**
245
+ * Get the underlying cache service for external invalidation.
246
+ */
247
+ getCacheService() {
248
+ return this.pageRequestCacheCoordinator.getCacheService();
216
249
  }
217
- }
218
- async createExecutionPlan(match, request) {
219
- const cacheKey = this.pageRequestCacheCoordinator.buildCacheKey({
220
- pathname: match.requestedPathname,
221
- query: match.query
222
- });
223
- const resolvedRequest = request ?? new Request(new URL(cacheKey, this.router.origin).toString(), {
224
- method: "GET"
225
- });
226
- const localsStore = {};
227
- const pageFilePath = match.templateRoute.filePath;
228
- const pageModule = await this.importPageModule(pageFilePath);
229
- const Page = pageModule?.default;
230
- const pageMiddleware = Page?.middleware ?? [];
231
- const pageCacheStrategy = Page?.cache ?? this.pageRequestCacheCoordinator.getDefaultCacheStrategy();
232
- return {
233
- cacheKey,
234
- request: resolvedRequest,
235
- pageFilePath,
236
- pageMiddleware,
237
- pageCacheStrategy,
238
- localsStore,
239
- localsForRender: pageCacheStrategy === "dynamic" ? localsStore : void 0
240
- };
241
- }
242
- /**
243
- * Loads the matched page module for request-time inspection.
244
- *
245
- * The matcher needs access to page-level metadata such as `cache` and
246
- * `middleware` before full rendering starts, so it asks the owning route
247
- * renderer to load the page module. That preserves integration-specific page
248
- * import setup for request-time inspection as well as for full rendering.
249
- *
250
- * @param filePath Absolute page module path.
251
- * @returns Imported page module.
252
- */
253
- async importPageModule(filePath) {
254
- const routeRenderer = this.routeRendererFactory.getPageRenderer(filePath);
255
- return routeRenderer.loadPageModule(filePath, {
256
- cacheScope: "request-metadata"
257
- });
258
- }
259
- /**
260
- * Get the underlying cache service for external invalidation.
261
- */
262
- getCacheService() {
263
- return this.pageRequestCacheCoordinator.getCacheService();
264
- }
265
250
  }
266
- export {
267
- FileSystemResponseMatcher
268
- };
@@ -1,17 +1,17 @@
1
- async function runMiddlewareChain(middleware, context, terminal) {
2
- if (middleware.length === 0) {
3
- return terminal();
4
- }
5
- let index = 0;
6
- const executeNext = async () => {
7
- if (index < middleware.length) {
8
- const current = middleware[index++];
9
- return await current(context, executeNext);
1
+ /**
2
+ * Runs an onion middleware chain and invokes the terminal handler when the chain completes.
3
+ */
4
+ export async function runMiddlewareChain(middleware, context, terminal) {
5
+ if (middleware.length === 0) {
6
+ return terminal();
10
7
  }
11
- return terminal();
12
- };
13
- return executeNext();
8
+ let index = 0;
9
+ const executeNext = async () => {
10
+ if (index < middleware.length) {
11
+ const current = middleware[index++];
12
+ return await current(context, executeNext);
13
+ }
14
+ return terminal();
15
+ };
16
+ return executeNext();
14
17
  }
15
- export {
16
- runMiddlewareChain
17
- };