@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
@@ -17,7 +17,7 @@ import type { ServerInvalidationState } from '../services/runtime-state/server-i
17
17
  import type { ServerModuleTranspiler } from '../services/module-loading/server-module-transpiler.service.js';
18
18
  import type { RouteModuleBuildCache } from '../services/module-loading/route-module-build-cache.store.js';
19
19
  /** Integration hook for registered `dependencies.scripts` entrypoint changes in dev. */
20
- export type RegisteredScriptEntrypointChangeHandler = (filePath: string) => void | Promise<void>;
20
+ export type RegisteredScriptEntrypointChangeHandler = (filePath: string) => void | boolean | Promise<void | boolean>;
21
21
  export interface RobotsPreference {
22
22
  /**
23
23
  * The user agent
@@ -187,8 +187,24 @@ export type EcoPagesAppConfig = {
187
187
  devClientOwner?: 'core' | 'host';
188
188
  /** Integration hooks run when a registered `dependencies.scripts` entrypoint changes. */
189
189
  registeredScriptEntrypointChangeHandlers?: RegisteredScriptEntrypointChangeHandler[];
190
- /** @deprecated Prefer {@link devClientOwner}: `'host'`. */
191
- delegateBrowserReloadToHost?: boolean;
190
+ };
191
+ /**
192
+ * Development-only in-browser toolbar configuration.
193
+ */
194
+ devToolbar?: {
195
+ /**
196
+ * Whether the dev toolbar is enabled during watch mode.
197
+ *
198
+ * @default true when `package` is configured
199
+ */
200
+ enabled?: boolean;
201
+ /**
202
+ * Client package resolved from the application project and bundled to
203
+ * `/_dev_toolbar.js` during watch mode.
204
+ *
205
+ * @example '@ecopages/dev-toolbar'
206
+ */
207
+ package?: string;
192
208
  };
193
209
  /**
194
210
  * Experimental features.
@@ -0,0 +1 @@
1
+ export {};
@@ -1,15 +1,14 @@
1
1
  import type { Readable } from 'node:stream';
2
2
  import type { ApiResponseBuilder } from '../adapters/shared/http/api-response.js';
3
- import type { BuildExecutor } from '../build/build-adapter.js';
4
3
  import type { ForeignChildRuntime } from '../route-renderer/orchestration/foreign-child/component-render-context.js';
5
4
  import type { EcoPageComponent } from '../eco/eco.types.js';
6
5
  import type { EcoPagesAppConfig } from './internal-types.js';
7
6
  import type { HmrStrategy } from '../hmr/hmr-strategy.js';
8
- import type { BrowserBundleExecutor } from '../services/assets/browser-bundle.service.js';
9
7
  import type { AssetDefinition, ProcessedAsset } from '../services/assets/asset-processing-service/assets.types.js';
10
8
  import type { CacheStats, CacheStrategy } from '../services/cache/cache.types.js';
11
9
  import type { InteractionEventsString as ScriptsInjectorInteractionEventsString } from '@ecopages/scripts-injector/types';
12
10
  import type { EntrypointDependencyGraph } from '../services/runtime-state/entrypoint-dependency-graph.service.js';
11
+ import type { DevTransformBundleContributor } from '../dev/transform-server/types.js';
13
12
  export type { EcoPagesAppConfig } from './internal-types.js';
14
13
  export type { EcoPageComponent } from '../eco/eco.types.js';
15
14
  export type { ProcessedAsset } from '../services/assets/asset-processing-service/assets.types.js';
@@ -163,17 +162,14 @@ export interface CacheInvalidator {
163
162
  }
164
163
  /**
165
164
  * Context interface for HMR strategies.
166
- * Provides access to watched files, registered bare-specifier mappings, and build configuration.
165
+ * Provides access to registered entrypoints and build configuration.
167
166
  */
168
167
  export interface DefaultHmrContext {
169
168
  /**
170
- * Map of registered entrypoints to their output URLs.
169
+ * Map of registered entrypoint source paths to their dev-transform output URLs.
171
170
  */
172
171
  getWatchedFiles(): Map<string, string>;
173
- /**
174
- * Directory where HMR bundles are written.
175
- */
176
- getDistDir(): string;
172
+ getRegisteredEntrypoints(): ReadonlyMap<string, ResolvedHmrEntrypoint>;
177
173
  /**
178
174
  * Absolute path to the source directory.
179
175
  */
@@ -188,14 +184,6 @@ export interface DefaultHmrContext {
188
184
  * Used by plugins to identify page files for transformation.
189
185
  */
190
186
  getPagesDir(): string;
191
- /**
192
- * Build executor owned by the active app/runtime.
193
- */
194
- getBuildExecutor(): BuildExecutor;
195
- /**
196
- * Browser bundler owned by the active app/runtime.
197
- */
198
- getBrowserBundleService(): BrowserBundleExecutor;
199
187
  /**
200
188
  * Server-side module loader owned by the active app/runtime.
201
189
  */
@@ -204,14 +192,6 @@ export interface DefaultHmrContext {
204
192
  * Entrypoint dependency graph for selective HMR invalidation.
205
193
  */
206
194
  getEntrypointDependencyGraph(): EntrypointDependencyGraph;
207
- /**
208
- * Registers an already-materialized HMR entrypoint without rebuilding it.
209
- *
210
- * @remarks
211
- * Cold dev batches seed the registrar after grouped builds so the first SSR
212
- * resolves the artifact from disk instead of triggering a rebuild.
213
- */
214
- seedResolvedEntrypoint(resolved: ResolvedHmrEntrypoint): void;
215
195
  }
216
196
  /**
217
197
  * Represents an event broadcast to connected clients via the ClientBridge.
@@ -262,13 +242,11 @@ export interface IClientBridge {
262
242
  error(message: string): void;
263
243
  subscriberCount: number;
264
244
  }
265
- /**
266
- * Verified HMR entrypoint artifact produced by registration.
267
- */
268
245
  export interface ResolvedHmrEntrypoint {
269
246
  sourcePath: string;
270
247
  outputPath: string;
271
248
  outputUrl: string;
249
+ role: 'page' | 'script';
272
250
  }
273
251
  /**
274
252
  * Interface for the HMR Manager.
@@ -276,21 +254,17 @@ export interface ResolvedHmrEntrypoint {
276
254
  */
277
255
  export interface IHmrManager {
278
256
  /**
279
- * Registers an integration-owned client entrypoint to be built and watched.
257
+ * Registers a client entrypoint for dev-transform delivery and HMR watching.
280
258
  *
281
259
  * @remarks
282
- * This path is strict: the owning integration must emit the expected `_hmr`
283
- * bundle. Missing output is treated as a development pipeline failure.
260
+ * Returns a stable `/assets/__eco_dev__/…` URL immediately; the module is
261
+ * transpiled on the first browser request (per-file ESM, not a page bundle).
284
262
  */
285
263
  registerEntrypoint(entrypointPath: string): Promise<string>;
286
264
  /**
287
- * Registers a generic script asset entrypoint to be built and watched.
288
- *
289
- * @remarks
290
- * This path exists for non-page script assets that are not owned by a
291
- * framework integration. Unlike `registerEntrypoint()`, it may use the generic
292
- * script bundling path.
265
+ * Registers an integration contributor that supplies per-module transform plugins.
293
266
  */
267
+ registerDevTransformContributor(contributor: DevTransformBundleContributor): void;
294
268
  registerScriptEntrypoint(entrypointPath: string): Promise<ResolvedHmrEntrypoint>;
295
269
  /**
296
270
  * Registers a custom HMR strategy.
@@ -320,22 +294,18 @@ export interface IHmrManager {
320
294
  * Returns an existing emitted HMR script artifact without registering it.
321
295
  */
322
296
  getResolvedScriptOutput?(entrypointPath: string): ResolvedHmrEntrypoint | undefined;
323
- /**
324
- * Registers an already-materialized HMR entrypoint without rebuilding it.
325
- *
326
- * @remarks
327
- * Cold dev batches seed the registrar after grouped builds so the first SSR
328
- * resolves the artifact from disk instead of triggering a rebuild.
329
- */
330
- seedResolvedEntrypoint?(resolved: ResolvedHmrEntrypoint): void;
331
297
  /**
332
298
  * Gets the map of watched files.
333
299
  */
334
300
  getWatchedFiles(): Map<string, string>;
335
301
  /**
336
- * Gets the HMR dist directory.
302
+ * Gets registered dev-transform entrypoints keyed by resolved source path.
303
+ */
304
+ getRegisteredEntrypoints(): ReadonlyMap<string, ResolvedHmrEntrypoint>;
305
+ /**
306
+ * Gets the on-disk work directory for the bundled HMR client runtime.
337
307
  */
338
- getDistDir(): string;
308
+ getRuntimeWorkDir(): string;
339
309
  /**
340
310
  * Returns the on-disk path to the bundled HMR runtime script.
341
311
  */
@@ -0,0 +1 @@
1
+ export {};
@@ -1,32 +1,45 @@
1
+ /**
2
+ * This module contains a simple utility function to merge two objects deeply
3
+ * @module
4
+ */
1
5
  function isObject(item) {
2
- return item && typeof item === "object" && !Array.isArray(item);
6
+ return item && typeof item === 'object' && !Array.isArray(item);
3
7
  }
4
8
  function isArray(item) {
5
- return Array.isArray(item);
9
+ return Array.isArray(item);
6
10
  }
7
- function deepMerge(target, source) {
8
- if (isArray(target) && isArray(source)) {
9
- return [...target, ...source];
10
- }
11
- if (!isObject(target) || !isObject(source)) {
12
- return source;
13
- }
14
- const output = Object.assign({}, target);
15
- for (const key in source) {
16
- if (isObject(source[key])) {
17
- if (!target[key]) {
18
- Object.assign(output, { [key]: source[key] });
19
- } else {
20
- output[key] = deepMerge(target[key], source[key]);
21
- }
22
- } else if (isArray(source[key])) {
23
- output[key] = [...target[key] || [], ...source[key]];
24
- } else if (source[key] !== void 0) {
25
- Object.assign(output, { [key]: source[key] });
11
+ /**
12
+ * Deeply merges two objects or arrays
13
+ * @function deepMerge
14
+ * @template T - Type of target object
15
+ * @template U - Type of source object
16
+ * @param target - The target object to merge into
17
+ * @param source - The source object to merge from
18
+ * @returns A new object with merged properties
19
+ */
20
+ export function deepMerge(target, source) {
21
+ if (isArray(target) && isArray(source)) {
22
+ return [...target, ...source];
26
23
  }
27
- }
28
- return output;
24
+ if (!isObject(target) || !isObject(source)) {
25
+ return source;
26
+ }
27
+ const output = Object.assign({}, target);
28
+ for (const key in source) {
29
+ if (isObject(source[key])) {
30
+ if (!target[key]) {
31
+ Object.assign(output, { [key]: source[key] });
32
+ }
33
+ else {
34
+ output[key] = deepMerge(target[key], source[key]);
35
+ }
36
+ }
37
+ else if (isArray(source[key])) {
38
+ output[key] = [...(target[key] || []), ...source[key]];
39
+ }
40
+ else if (source[key] !== undefined) {
41
+ Object.assign(output, { [key]: source[key] });
42
+ }
43
+ }
44
+ return output;
29
45
  }
30
- export {
31
- deepMerge
32
- };
@@ -1,26 +1,30 @@
1
- import { normalizePathname } from "./path-pattern.js";
2
- function toEcopagesRouteInfo(route) {
3
- return {
4
- pathname: normalizePathname(route.pathname),
5
- params: normalizeRouteParams(route.params)
6
- };
1
+ import { normalizePathname } from './path-pattern.js';
2
+ /**
3
+ * Maps a static-generation or registry route into the public slim route shape.
4
+ */
5
+ export function toEcopagesRouteInfo(route) {
6
+ return {
7
+ pathname: normalizePathname(route.pathname),
8
+ params: normalizeRouteParams(route.params),
9
+ };
7
10
  }
8
- function normalizeRouteParams(params) {
9
- const normalized = {};
10
- for (const [key, value] of Object.entries(params)) {
11
- normalized[key] = Array.isArray(value) ? value.join("/") : value;
12
- }
13
- return normalized;
11
+ /**
12
+ * Flattens string | string[] route params into string values for public APIs.
13
+ */
14
+ export function normalizeRouteParams(params) {
15
+ const normalized = {};
16
+ for (const [key, value] of Object.entries(params)) {
17
+ normalized[key] = Array.isArray(value) ? value.join('/') : value;
18
+ }
19
+ return normalized;
14
20
  }
15
- async function resolveAppStartRoutes(input) {
16
- if (!input.listStaticGenerationRoutes) {
17
- return [];
18
- }
19
- const routes = await input.listStaticGenerationRoutes({ runtimeOrigin: input.runtimeOrigin });
20
- return routes.map(toEcopagesRouteInfo);
21
+ /**
22
+ * Resolves {@link EcopagesRouteInfo} entries for app-start and similar consumers.
23
+ */
24
+ export async function resolveAppStartRoutes(input) {
25
+ if (!input.listStaticGenerationRoutes) {
26
+ return [];
27
+ }
28
+ const routes = await input.listStaticGenerationRoutes({ runtimeOrigin: input.runtimeOrigin });
29
+ return routes.map(toEcopagesRouteInfo);
21
30
  }
22
- export {
23
- normalizeRouteParams,
24
- resolveAppStartRoutes,
25
- toEcopagesRouteInfo
26
- };
package/src/utils/hash.js CHANGED
@@ -1,7 +1,4 @@
1
- import { runtimeHash } from "./runtime.js";
2
- const rapidhash = (content) => {
3
- return runtimeHash(content);
4
- };
5
- export {
6
- rapidhash
1
+ import { runtimeHash } from './runtime.js';
2
+ export const rapidhash = (content) => {
3
+ return runtimeHash(content);
7
4
  };
@@ -1,10 +1,23 @@
1
- function escapeHtmlAttribute(value) {
2
- return value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
1
+ /**
2
+ * Escapes a string for safe use inside a double-quoted HTML attribute value.
3
+ *
4
+ * @param value Raw attribute value.
5
+ * @returns Escaped attribute-safe string.
6
+ */
7
+ export function escapeHtmlAttribute(value) {
8
+ return value.replaceAll('&', '&amp;').replaceAll('"', '&quot;').replaceAll('<', '&lt;').replaceAll('>', '&gt;');
3
9
  }
4
- function escapeXmlText(value) {
5
- return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&apos;");
10
+ /**
11
+ * Escapes a string for safe use as XML text content (e.g. `<loc>` values).
12
+ *
13
+ * @param value Raw text node value.
14
+ * @returns Escaped XML-safe string.
15
+ */
16
+ export function escapeXmlText(value) {
17
+ return value
18
+ .replaceAll('&', '&amp;')
19
+ .replaceAll('<', '&lt;')
20
+ .replaceAll('>', '&gt;')
21
+ .replaceAll('"', '&quot;')
22
+ .replaceAll("'", '&apos;');
6
23
  }
7
- export {
8
- escapeHtmlAttribute,
9
- escapeXmlText
10
- };
package/src/utils/html.js CHANGED
@@ -1,4 +1 @@
1
- import { html } from "ghtml";
2
- export {
3
- html
4
- };
1
+ export { html } from 'ghtml';
@@ -1,11 +1,12 @@
1
- const prefix = "[ecopages]";
2
- function invariant(condition, message) {
3
- if (condition) {
4
- return;
5
- }
6
- const value = message ? `${prefix} ${message}` : `${prefix} An error occurred`;
7
- throw new Error(value);
1
+ /**
2
+ * This module contains a simple utility invariant function that throws an error if the condition is not met
3
+ * @module
4
+ */
5
+ const prefix = '[ecopages]';
6
+ export function invariant(condition, message) {
7
+ if (condition) {
8
+ return;
9
+ }
10
+ const value = message ? `${prefix} ${message}` : `${prefix} An error occurred`;
11
+ throw new Error(value);
8
12
  }
9
- export {
10
- invariant
11
- };
@@ -1,24 +1,34 @@
1
- function createRequire(getLocals) {
2
- return (keyOrKeys, onMissing) => {
3
- const locals = getLocals();
4
- if (Array.isArray(keyOrKeys)) {
5
- const result = {};
6
- for (const key of keyOrKeys) {
7
- const value2 = locals[key];
8
- if (value2 === void 0 || value2 === null) {
9
- throw onMissing();
1
+ /**
2
+ * Creates a require function for validating and retrieving request locals.
3
+ * Supports both single key access and multiple keys with type safety.
4
+ *
5
+ * @param getLocals - Function that returns the current locals object
6
+ * @returns A require function that throws the onMissing response if keys are not found
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * const require = createRequire(() => context.locals);
11
+ * const userId = require('userId', () => new Response('Unauthorized', { status: 401 }));
12
+ * ```
13
+ */
14
+ export function createRequire(getLocals) {
15
+ return (keyOrKeys, onMissing) => {
16
+ const locals = getLocals();
17
+ if (Array.isArray(keyOrKeys)) {
18
+ const result = {};
19
+ for (const key of keyOrKeys) {
20
+ const value = locals[key];
21
+ if (value === undefined || value === null) {
22
+ throw onMissing();
23
+ }
24
+ result[key] = value;
25
+ }
26
+ return result;
10
27
  }
11
- result[key] = value2;
12
- }
13
- return result;
14
- }
15
- const value = locals[keyOrKeys];
16
- if (value === void 0 || value === null) {
17
- throw onMissing();
18
- }
19
- return value;
20
- };
28
+ const value = locals[keyOrKeys];
29
+ if (value === undefined || value === null) {
30
+ throw onMissing();
31
+ }
32
+ return value;
33
+ };
21
34
  }
22
- export {
23
- createRequire
24
- };
@@ -1,68 +1,76 @@
1
- import { parseArgs } from "node:util";
2
- import { getRuntimeArgv } from "./runtime.js";
1
+ import { parseArgs } from 'node:util';
2
+ import { getRuntimeArgv } from './runtime.js';
3
3
  function getEmbeddedRuntimeCommandOptions() {
4
- const isDevelopment = process.env.NODE_ENV === "development";
5
- return {
6
- preview: false,
7
- build: false,
8
- start: !isDevelopment,
9
- dev: isDevelopment,
10
- force: false,
11
- serveOnly: false,
12
- port: void 0,
13
- hostname: void 0,
14
- reactFastRefresh: void 0
15
- };
4
+ const isDevelopment = process.env.NODE_ENV === 'development';
5
+ return {
6
+ preview: false,
7
+ build: false,
8
+ start: !isDevelopment,
9
+ dev: isDevelopment,
10
+ force: false,
11
+ serveOnly: false,
12
+ port: undefined,
13
+ hostname: undefined,
14
+ reactFastRefresh: undefined,
15
+ };
16
16
  }
17
- const ECOPAGES_BIN_FILES = ["ecopages.ts", "ecopages.js", "cli.js"];
18
- const ECOPAGES_AVAILABLE_COMMANDS = ["dev", "build", "start", "preview"];
19
- function parseCliArgs(options = {}) {
20
- if (options.embeddedRuntime || process.env.ECOPAGES_INTERNAL_EMBEDDED_RUNTIME === "true") {
21
- return getEmbeddedRuntimeCommandOptions();
22
- }
23
- const runtimeArgv = getRuntimeArgv();
24
- const { values } = parseArgs({
25
- args: runtimeArgv,
26
- options: {
27
- dev: { type: "boolean" },
28
- preview: { type: "boolean" },
29
- build: { type: "boolean" },
30
- force: { type: "boolean" },
31
- "serve-only": { type: "boolean" },
32
- port: { type: "string" },
33
- hostname: { type: "string" },
34
- "react-fast-refresh": { type: "boolean" }
35
- },
36
- allowPositionals: true
37
- });
38
- let command = "";
39
- const ecopagesIndex = runtimeArgv.findIndex((arg) => ECOPAGES_BIN_FILES.some((filename) => arg.endsWith(filename)));
40
- const isAvailableCommand = ecopagesIndex !== -1;
41
- if (isAvailableCommand) {
42
- command = ecopagesIndex < runtimeArgv.length - 1 && ECOPAGES_AVAILABLE_COMMANDS.some((cmd) => {
43
- return runtimeArgv[ecopagesIndex + 1] === cmd;
44
- }) ? runtimeArgv[ecopagesIndex + 1] : "start";
45
- }
46
- const isStartCommand = command === "start" || !values.dev && !values.build && !values.preview;
47
- const isDevCommand = command === "dev" || !!values.dev;
48
- const isBuildCommand = command === "build" || !!values.build;
49
- const isPreviewCommand = command === "preview" || !!values.preview;
50
- const parsedCommandOptions = {
51
- preview: isPreviewCommand,
52
- build: isBuildCommand,
53
- start: isStartCommand,
54
- dev: isDevCommand,
55
- force: !!values.force,
56
- serveOnly: !!values["serve-only"] || process.env.ECOPAGES_PREVIEW_SERVE_ONLY === "true",
57
- port: values.port ? Number(values.port) : void 0,
58
- hostname: values.hostname,
59
- reactFastRefresh: values["react-fast-refresh"]
60
- };
61
- if (!process.env.NODE_ENV) {
62
- process.env.NODE_ENV = isDevCommand ? "development" : "production";
63
- }
64
- return parsedCommandOptions;
17
+ const ECOPAGES_BIN_FILES = ['ecopages.ts', 'ecopages.js', 'cli.js'];
18
+ const ECOPAGES_AVAILABLE_COMMANDS = ['dev', 'build', 'start', 'preview'];
19
+ /**
20
+ * Parses command line arguments for the server.
21
+ * It returns {@link ReturnParseCliArgs}
22
+ */
23
+ export function parseCliArgs(options = {}) {
24
+ if (options.embeddedRuntime || process.env.ECOPAGES_INTERNAL_EMBEDDED_RUNTIME === 'true') {
25
+ return getEmbeddedRuntimeCommandOptions();
26
+ }
27
+ const runtimeArgv = getRuntimeArgv();
28
+ const { values } = parseArgs({
29
+ args: runtimeArgv,
30
+ options: {
31
+ dev: { type: 'boolean' },
32
+ preview: { type: 'boolean' },
33
+ build: { type: 'boolean' },
34
+ force: { type: 'boolean' },
35
+ 'serve-only': { type: 'boolean' },
36
+ port: { type: 'string' },
37
+ hostname: { type: 'string' },
38
+ 'react-fast-refresh': { type: 'boolean' },
39
+ },
40
+ allowPositionals: true,
41
+ });
42
+ let command = '';
43
+ const ecopagesIndex = runtimeArgv.findIndex((arg) => ECOPAGES_BIN_FILES.some((filename) => arg.endsWith(filename)));
44
+ const isAvailableCommand = ecopagesIndex !== -1;
45
+ if (isAvailableCommand) {
46
+ command =
47
+ ecopagesIndex < runtimeArgv.length - 1 &&
48
+ ECOPAGES_AVAILABLE_COMMANDS.some((cmd) => {
49
+ return runtimeArgv[ecopagesIndex + 1] === cmd;
50
+ })
51
+ ? runtimeArgv[ecopagesIndex + 1]
52
+ : 'start';
53
+ }
54
+ const isStartCommand = command === 'start' || (!values.dev && !values.build && !values.preview);
55
+ const isDevCommand = command === 'dev' || !!values.dev;
56
+ const isBuildCommand = command === 'build' || !!values.build;
57
+ const isPreviewCommand = command === 'preview' || !!values.preview;
58
+ const parsedCommandOptions = {
59
+ preview: isPreviewCommand,
60
+ build: isBuildCommand,
61
+ start: isStartCommand,
62
+ dev: isDevCommand,
63
+ force: !!values.force,
64
+ serveOnly: !!values['serve-only'] || process.env.ECOPAGES_PREVIEW_SERVE_ONLY === 'true',
65
+ port: values.port ? Number(values.port) : undefined,
66
+ hostname: values.hostname,
67
+ reactFastRefresh: values['react-fast-refresh'],
68
+ };
69
+ if (isDevCommand) {
70
+ process.env.NODE_ENV ??= 'development';
71
+ }
72
+ else {
73
+ process.env.NODE_ENV = 'production';
74
+ }
75
+ return parsedCommandOptions;
65
76
  }
66
- export {
67
- parseCliArgs
68
- };
@@ -1,27 +1,42 @@
1
- function normalizePathname(pathname) {
2
- if (!pathname || pathname === "/") {
3
- return "/";
4
- }
5
- const withLeadingSlash = pathname.startsWith("/") ? pathname : `/${pathname}`;
6
- return withLeadingSlash.replace(/\/+$/, "") || "/";
1
+ /**
2
+ * Normalizes a URL pathname for matching and sitemap location building.
3
+ *
4
+ * @remarks
5
+ * Ensures a leading slash and strips trailing slashes except for `/`.
6
+ */
7
+ export function normalizePathname(pathname) {
8
+ if (!pathname || pathname === '/') {
9
+ return '/';
10
+ }
11
+ const withLeadingSlash = pathname.startsWith('/') ? pathname : `/${pathname}`;
12
+ return withLeadingSlash.replace(/\/+$/, '') || '/';
7
13
  }
8
- function matchPathPattern(pathname, pattern) {
9
- const normalizedPath = normalizePathname(pathname);
10
- const normalizedPattern = pattern.trim();
11
- if (normalizedPattern.endsWith("/**")) {
12
- const prefix = normalizePathname(normalizedPattern.slice(0, -3));
13
- if (prefix === "/") {
14
- return true;
14
+ /**
15
+ * Matches a pathname against a small set of supported patterns.
16
+ *
17
+ * @remarks
18
+ * Supported forms:
19
+ * - exact: `/admin`
20
+ * - prefix wildcard: `/admin/**` (matches `/admin` and descendants)
21
+ * - trailing `**` only as a full segment after `/`
22
+ *
23
+ * This is not a full glob engine. Unsupported patterns are treated as exact matches.
24
+ */
25
+ export function matchPathPattern(pathname, pattern) {
26
+ const normalizedPath = normalizePathname(pathname);
27
+ const normalizedPattern = pattern.trim();
28
+ if (normalizedPattern.endsWith('/**')) {
29
+ const prefix = normalizePathname(normalizedPattern.slice(0, -3));
30
+ if (prefix === '/') {
31
+ return true;
32
+ }
33
+ return normalizedPath === prefix || normalizedPath.startsWith(`${prefix}/`);
15
34
  }
16
- return normalizedPath === prefix || normalizedPath.startsWith(`${prefix}/`);
17
- }
18
- return normalizedPath === normalizePathname(normalizedPattern);
35
+ return normalizedPath === normalizePathname(normalizedPattern);
19
36
  }
20
- function matchesAnyPathPattern(pathname, patterns) {
21
- return patterns.some((pattern) => matchPathPattern(pathname, pattern));
37
+ /**
38
+ * Returns true when the pathname matches any of the patterns.
39
+ */
40
+ export function matchesAnyPathPattern(pathname, patterns) {
41
+ return patterns.some((pattern) => matchPathPattern(pathname, pattern));
22
42
  }
23
- export {
24
- matchPathPattern,
25
- matchesAnyPathPattern,
26
- normalizePathname
27
- };