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

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 (343) hide show
  1. package/README.md +1 -0
  2. package/package.json +90 -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/README.md +23 -0
  249. package/src/router/client/link-intent.js +55 -39
  250. package/src/router/client/link-intent.test.browser.js +49 -49
  251. package/src/router/client/link-navigation-policy.js +114 -93
  252. package/src/router/client/link-navigation-policy.test.browser.js +70 -80
  253. package/src/router/client/navigation-coordinator.js +235 -211
  254. package/src/router/client/navigation-lifecycle.d.ts +55 -0
  255. package/src/router/client/navigation-lifecycle.js +50 -0
  256. package/src/router/client/navigation-lifecycle.test.browser.d.ts +1 -0
  257. package/src/router/client/navigation-lifecycle.test.browser.js +118 -0
  258. package/src/router/server/route-registry.js +237 -242
  259. package/src/services/assets/asset-processing-service/asset-dependency-keys.js +64 -53
  260. package/src/services/assets/asset-processing-service/asset-processing.service.js +287 -303
  261. package/src/services/assets/asset-processing-service/asset.factory.js +78 -81
  262. package/src/services/assets/asset-processing-service/assets.types.js +1 -0
  263. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +57 -46
  264. package/src/services/assets/asset-processing-service/browser-runtime-entry-resolution.js +106 -69
  265. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.js +53 -53
  266. package/src/services/assets/asset-processing-service/finalize-processed-asset.js +4 -6
  267. package/src/services/assets/asset-processing-service/grouped-content-bundles.js +79 -80
  268. package/src/services/assets/asset-processing-service/index.js +8 -8
  269. package/src/services/assets/asset-processing-service/inline-content-script-body.js +22 -16
  270. package/src/services/assets/asset-processing-service/materialize-content-script-asset.js +21 -17
  271. package/src/services/assets/asset-processing-service/page-package.js +70 -72
  272. package/src/services/assets/asset-processing-service/processor.interface.js +7 -5
  273. package/src/services/assets/asset-processing-service/processor.registry.js +11 -14
  274. package/src/services/assets/asset-processing-service/processors/base/base-processor.js +59 -62
  275. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.js +102 -117
  276. package/src/services/assets/asset-processing-service/processors/index.js +5 -5
  277. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.js +110 -115
  278. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +95 -97
  279. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +136 -135
  280. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +27 -29
  281. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +34 -40
  282. package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.js +36 -35
  283. package/src/services/assets/asset-processing-service/resolve-integration-plugin.js +14 -16
  284. package/src/services/assets/asset-processing-service/ungrouped-dependency-processing.js +27 -39
  285. package/src/services/assets/browser-bundle.service.js +52 -47
  286. package/src/services/cache/cache.types.js +5 -0
  287. package/src/services/cache/index.js +6 -7
  288. package/src/services/cache/memory-cache-store.js +101 -89
  289. package/src/services/cache/page-cache-service.js +156 -145
  290. package/src/services/cache/page-request-cache-coordinator.service.js +102 -102
  291. package/src/services/html/html-rewriter-provider.service.js +61 -61
  292. package/src/services/html/html-transformer.service.js +249 -266
  293. package/src/services/invalidation/development-invalidation.service.js +252 -241
  294. package/src/services/module-loading/app-module-loader.service.js +1 -0
  295. package/src/services/module-loading/app-server-module-transpiler.service.js +107 -101
  296. package/src/services/module-loading/host-module-loader-registry.js +6 -11
  297. package/src/services/module-loading/module-loading-types.js +1 -0
  298. package/src/services/module-loading/page-module-import.service.js +235 -243
  299. package/src/services/module-loading/route-module-build-cache-registry.js +47 -33
  300. package/src/services/module-loading/route-module-build-cache.js +3 -38
  301. package/src/services/module-loading/route-module-build-cache.store.js +195 -200
  302. package/src/services/module-loading/route-module-build-manifest.js +61 -74
  303. package/src/services/module-loading/route-module-dependency-hasher.js +136 -110
  304. package/src/services/module-loading/server-module-transpiler.service.js +68 -62
  305. package/src/services/module-loading/source-module-support.js +15 -7
  306. package/src/services/runtime-state/dev-graph.service.js +165 -157
  307. package/src/services/runtime-state/entrypoint-dependency-graph.service.js +85 -76
  308. package/src/services/runtime-state/server-invalidation-state.service.js +38 -30
  309. package/src/services/validation/schema-validation-service.js +157 -95
  310. package/src/services/validation/standard-schema.types.js +1 -0
  311. package/src/services/validation/validate-standard-schema.js +13 -13
  312. package/src/static-site-generator/production-page-browser-graph-prebuild.js +35 -19
  313. package/src/static-site-generator/sitemap-routes.js +33 -28
  314. package/src/static-site-generator/sitemap.js +38 -29
  315. package/src/static-site-generator/static-build-invalidation.js +34 -56
  316. package/src/static-site-generator/static-export-context.js +1 -0
  317. package/src/static-site-generator/static-site-generator.js +517 -553
  318. package/src/types/internal-types.d.ts +19 -3
  319. package/src/types/internal-types.js +1 -0
  320. package/src/types/public-types.d.ts +16 -46
  321. package/src/types/public-types.js +1 -0
  322. package/src/utils/deep-merge.js +39 -26
  323. package/src/utils/ecopages-route-info.js +27 -23
  324. package/src/utils/hash.js +3 -6
  325. package/src/utils/html-escaping.js +21 -8
  326. package/src/utils/html.js +1 -4
  327. package/src/utils/invariant.js +11 -10
  328. package/src/utils/locals-utils.js +32 -22
  329. package/src/utils/parse-cli-args.js +73 -65
  330. package/src/utils/path-pattern.js +38 -23
  331. package/src/utils/path-utils.module.js +8 -11
  332. package/src/utils/resolve-entry-file.js +70 -38
  333. package/src/utils/resolve-work-dir.js +23 -27
  334. package/src/utils/runtime.js +24 -33
  335. package/src/utils/server-utils.module.js +60 -52
  336. package/src/utils/static-file-extensions.js +52 -46
  337. package/src/watchers/project-watcher-ignore.js +16 -15
  338. package/src/watchers/project-watcher.js +385 -366
  339. package/src/watchers/project-watcher.test-helpers.js +45 -50
  340. package/src/adapters/shared/hmr/hmr-entrypoint-registrar.d.ts +0 -56
  341. package/src/adapters/shared/hmr/hmr-entrypoint-registrar.js +0 -106
  342. package/src/build/cache/dev-browser-script-cache.d.ts +0 -34
  343. package/src/build/cache/dev-browser-script-cache.js +0 -90
@@ -1,351 +1,458 @@
1
- import { builtinModules, createRequire } from "node:module";
2
- import { readFileSync } from "node:fs";
3
- import path from "node:path";
4
- import { isBarePackageImportSpecifier } from "../../plugins/tsconfig-import-resolver.js";
5
- import {
6
- collectBrowserRuntimeImportRewriteMap,
7
- rewriteBrowserRuntimeImports
8
- } from "../browser/browser-runtime-plugin.js";
9
- import { createServerSideCssShimPlugin } from "./server-side-css-shim-plugin.js";
10
- import { createRolldownPluginBridge } from "./rolldown-plugin-bridge.js";
11
- import {
12
- isDeclaredAppPackageImport,
13
- isWorkspacePackageImport,
14
- normalizeNodeRuntimeBuildOutputs
15
- } from "./runtime-build-output-normalizer.js";
16
- const corePackageRequire = createRequire(new URL("../../../package.json", import.meta.url));
1
+ /**
2
+ * Shared helpers for the Rolldown-backed build adapters.
3
+ *
4
+ * @remarks
5
+ * The standard {@link RolldownBuildAdapter} uses these helpers for
6
+ * BuildOptions → Rolldown mapping, dependency-graph extraction, and the
7
+ * post-build rewriting pipeline.
8
+ *
9
+ * @module
10
+ */
11
+ import { builtinModules, createRequire } from 'node:module';
12
+ import { readFileSync } from 'node:fs';
13
+ import path from 'node:path';
14
+ import { isBarePackageImportSpecifier } from '../../plugins/tsconfig-import-resolver.js';
15
+ import { collectBrowserRuntimeImportRewriteMap, rewriteBrowserRuntimeImports, } from '../browser/browser-runtime-plugin.js';
16
+ import { createServerSideCssShimPlugin } from './server-side-css-shim-plugin.js';
17
+ import { createRolldownPluginBridge } from './rolldown-plugin-bridge.js';
18
+ import { isDeclaredAppPackageImport, isWorkspacePackageImport, normalizeNodeRuntimeBuildOutputs, } from './runtime-build-output-normalizer.js';
19
+ const corePackageRequire = createRequire(new URL('../../../package.json', import.meta.url));
17
20
  const nodeBuiltinSpecifiers = new Set(builtinModules);
18
21
  let corePackageNames;
22
+ /**
23
+ * Returns the set of packages declared as direct dependencies in core's own
24
+ * `package.json` (all dependency fields combined).
25
+ *
26
+ * @remarks
27
+ * Result is cached for the lifetime of the process. This is safe because
28
+ * core's own package.json does not change at runtime.
29
+ */
19
30
  function getCorePackageNames() {
20
- if (corePackageNames) {
31
+ if (corePackageNames) {
32
+ return corePackageNames;
33
+ }
34
+ const packageJsonPath = new URL('../../../package.json', import.meta.url);
35
+ corePackageNames = new Set();
36
+ try {
37
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
38
+ for (const field of ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']) {
39
+ const entries = packageJson[field];
40
+ if (!entries || typeof entries !== 'object') {
41
+ continue;
42
+ }
43
+ for (const name of Object.keys(entries)) {
44
+ corePackageNames.add(name);
45
+ }
46
+ }
47
+ }
48
+ catch {
49
+ // Return empty set on read/parse failure; packages will be bundled.
50
+ }
21
51
  return corePackageNames;
22
- }
23
- const packageJsonPath = new URL("../../../package.json", import.meta.url);
24
- corePackageNames = /* @__PURE__ */ new Set();
25
- try {
26
- const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
27
- for (const field of ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"]) {
28
- const entries = packageJson[field];
29
- if (!entries || typeof entries !== "object") {
30
- continue;
31
- }
32
- for (const name of Object.keys(entries)) {
33
- corePackageNames.add(name);
34
- }
35
- }
36
- } catch {
37
- }
38
- return corePackageNames;
39
52
  }
40
53
  function isCoreDeclaredPackageImport(specifier) {
41
- const name = specifier.startsWith("@") ? specifier.split("/").slice(0, 2).join("/") : specifier.split("/")[0] ?? specifier;
42
- return getCorePackageNames().has(name);
54
+ const name = specifier.startsWith('@')
55
+ ? specifier.split('/').slice(0, 2).join('/')
56
+ : (specifier.split('/')[0] ?? specifier);
57
+ return getCorePackageNames().has(name);
43
58
  }
44
- function transpileProfileToOptions(profile) {
45
- switch (profile) {
46
- case "browser-script":
47
- case "hmr-runtime":
48
- case "hmr-entrypoint":
49
- return {
50
- target: "browser",
51
- format: "esm",
52
- sourcemap: "none"
53
- };
54
- }
59
+ export function transpileProfileToOptions(profile) {
60
+ switch (profile) {
61
+ case 'browser-script':
62
+ case 'hmr-runtime':
63
+ case 'hmr-entrypoint':
64
+ return {
65
+ target: 'browser',
66
+ format: 'esm',
67
+ sourcemap: 'none',
68
+ };
69
+ }
55
70
  }
56
71
  function isPackageImport(id, contextRoot) {
57
- return isBarePackageImportSpecifier(id, contextRoot);
72
+ return isBarePackageImportSpecifier(id, contextRoot);
58
73
  }
59
74
  function tryResolveModule(id, resolver) {
60
- try {
61
- return resolver.resolve(id);
62
- } catch {
63
- return void 0;
64
- }
75
+ try {
76
+ return resolver.resolve(id);
77
+ }
78
+ catch {
79
+ return undefined;
80
+ }
65
81
  }
66
82
  function getAppRootRequire(cache, contextRoot) {
67
- const cacheKey = path.resolve(contextRoot);
68
- let req = cache.get(cacheKey);
69
- if (!req) {
70
- req = createRequire(path.join(cacheKey, "package.json"));
71
- cache.set(cacheKey, req);
72
- }
73
- return req;
83
+ const cacheKey = path.resolve(contextRoot);
84
+ let req = cache.get(cacheKey);
85
+ if (!req) {
86
+ req = createRequire(path.join(cacheKey, 'package.json'));
87
+ cache.set(cacheKey, req);
88
+ }
89
+ return req;
74
90
  }
91
+ /**
92
+ * Determines whether a package import should be bundled into the output
93
+ * rather than left as an external bare specifier.
94
+ *
95
+ * @remarks
96
+ * Resolution is evaluated in three tiers:
97
+ *
98
+ * 1. **Workspace packages** (`workspace:` protocol) — always bundled; they
99
+ * are source-only and cannot be resolved by Node.js at runtime.
100
+ * 2. **App-declared packages** — bundled only when their resolved entry is a
101
+ * TypeScript or JSX file (source packages); pre-compiled packages are left
102
+ * external so the app's own resolver handles them at runtime.
103
+ * 3. **Everything else** (undeclared transitives) — split into two sub-cases:
104
+ * - A **direct dependency of core** that resolves to a compiled JS file
105
+ * (e.g. `oxc-parser`, `rolldown`, `ws`): externalized so the
106
+ * `runtime-build-output-normalizer` can rewrite the import to an
107
+ * absolute `file://` URL after the build. "Direct" means declared in
108
+ * core's own `package.json`; transitives that merely *resolve through*
109
+ * core's `require` are excluded.
110
+ * - **Everything else** (true transitives like `lexical`, `@lexical/react`):
111
+ * bundled unconditionally. pnpm strict hoisting means these packages
112
+ * are unreachable as bare specifiers from output directories such as
113
+ * `.eco/`, `.server-route-modules/`, or `dist/.server/`.
114
+ *
115
+ * @param id - The package specifier (e.g., `@scope/pkg/subpath`).
116
+ * @param contextRoot - The root directory of the app being built.
117
+ * @param appRootRequireCache - Cache of `require` instances per context root.
118
+ * @returns `true` if the import should be bundled, `false` to externalize.
119
+ */
75
120
  function shouldBundlePackageImport(id, contextRoot, appRootRequireCache) {
76
- if (isWorkspacePackageImport(id, contextRoot)) {
121
+ if (isWorkspacePackageImport(id, contextRoot)) {
122
+ return true;
123
+ }
124
+ if (isDeclaredAppPackageImport(id, contextRoot)) {
125
+ const appRootRequire = getAppRootRequire(appRootRequireCache, contextRoot);
126
+ const appResolvedPath = tryResolveModule(id, appRootRequire);
127
+ return Boolean(appResolvedPath && /\.(?:[cm]?ts|tsx|jsx)$/u.test(appResolvedPath));
128
+ }
129
+ if (isCoreDeclaredPackageImport(id)) {
130
+ const coreResolvedPath = tryResolveModule(id, corePackageRequire);
131
+ if (coreResolvedPath && !/\.(?:[cm]?ts|tsx|jsx)$/u.test(coreResolvedPath)) {
132
+ return false;
133
+ }
134
+ }
77
135
  return true;
78
- }
79
- if (isDeclaredAppPackageImport(id, contextRoot)) {
80
- const appRootRequire = getAppRootRequire(appRootRequireCache, contextRoot);
81
- const appResolvedPath = tryResolveModule(id, appRootRequire);
82
- return Boolean(appResolvedPath && /\.(?:[cm]?ts|tsx|jsx)$/u.test(appResolvedPath));
83
- }
84
- if (isCoreDeclaredPackageImport(id)) {
85
- const coreResolvedPath = tryResolveModule(id, corePackageRequire);
86
- if (coreResolvedPath && !/\.(?:[cm]?ts|tsx|jsx)$/u.test(coreResolvedPath)) {
87
- return false;
88
- }
89
- }
90
- return true;
91
136
  }
92
137
  function createExternalMatcher(options, appRootRequireCache) {
93
- const explicitExternals = new Set(options.external ?? []);
94
- const externalPackages = options.externalPackages === true;
95
- const contextRoot = options.root ? path.resolve(options.root) : process.cwd();
96
- return (id) => {
97
- if (explicitExternals.has(id)) {
98
- return true;
99
- }
100
- if (!externalPackages || !isPackageImport(id, contextRoot)) {
101
- return false;
102
- }
103
- return !shouldBundlePackageImport(id, contextRoot, appRootRequireCache);
104
- };
138
+ const explicitExternals = new Set(options.external ?? []);
139
+ const externalPackages = options.externalPackages === true;
140
+ const contextRoot = options.root ? path.resolve(options.root) : process.cwd();
141
+ return (id) => {
142
+ if (explicitExternals.has(id)) {
143
+ return true;
144
+ }
145
+ if (!externalPackages || !isPackageImport(id, contextRoot)) {
146
+ return false;
147
+ }
148
+ return !shouldBundlePackageImport(id, contextRoot, appRootRequireCache);
149
+ };
105
150
  }
106
151
  function isNodeBuiltinSpecifier(id) {
107
- return id.startsWith("node:") || nodeBuiltinSpecifiers.has(id);
152
+ return id.startsWith('node:') || nodeBuiltinSpecifiers.has(id);
108
153
  }
109
- function createNodeBuiltinExternalPlugin() {
110
- return {
111
- name: "ecopages-node-builtin-external",
112
- resolveId(id) {
113
- return isNodeBuiltinSpecifier(id) ? { id, external: true } : null;
114
- }
115
- };
154
+ /**
155
+ * Resolves Node builtins as external before Rolldown falls back to file resolution.
156
+ *
157
+ * @remarks
158
+ * Rolldown documents two first-class externalization points: its `external`
159
+ * option is checked before resolution, and a plugin `resolveId` hook can return
160
+ * `{ id, external: true }`. Core uses the latter to keep Node-builtin ownership
161
+ * explicit in the Node-target plugin pipeline.
162
+ *
163
+ * The hook runs before Rolldown's internal filesystem resolver, leaving imports
164
+ * such as `node:fs` intact for the Node runtime. It is installed only for
165
+ * Node-target builds, so browser bundles still surface accidental Node builtin
166
+ * imports as resolver failures.
167
+ *
168
+ * See {@link https://rolldown.rs/in-depth/external-modules | Rolldown external modules}.
169
+ */
170
+ export function createNodeBuiltinExternalPlugin() {
171
+ return {
172
+ name: 'ecopages-node-builtin-external',
173
+ resolveId(id) {
174
+ return isNodeBuiltinSpecifier(id) ? { id, external: true } : null;
175
+ },
176
+ };
177
+ }
178
+ /**
179
+ * Rejects Node builtins in browser-target builds before Rolldown externalizes them.
180
+ *
181
+ * @remarks
182
+ * With `platform: 'browser'`, Rolldown leaves `node:*` imports in the output as
183
+ * bare specifiers. This plugin fails the build instead so server-only graphs
184
+ * cannot reach the browser as silent CORS errors.
185
+ */
186
+ export function createBrowserNodeBuiltinGuardPlugin() {
187
+ return {
188
+ name: 'ecopages-browser-node-builtin-guard',
189
+ resolveId(id, importer) {
190
+ if (!isNodeBuiltinSpecifier(id)) {
191
+ return null;
192
+ }
193
+ const from = importer ? ` (imported from ${importer})` : '';
194
+ throw new Error(`[browser-build] Node builtin "${id}" cannot be bundled for the browser${from}. ` +
195
+ `Check package "browser" exports and the client-graph boundary for the importer.`);
196
+ },
197
+ };
116
198
  }
117
199
  function mapRolldownFormat(value) {
118
- switch (value) {
119
- case "cjs":
120
- return "cjs";
121
- case "iife":
122
- return "iife";
123
- default:
124
- return "esm";
125
- }
200
+ switch (value) {
201
+ case 'cjs':
202
+ return 'cjs';
203
+ case 'iife':
204
+ return 'iife';
205
+ default:
206
+ return 'esm';
207
+ }
126
208
  }
127
209
  function mapRolldownPlatform(value) {
128
- if (value === "browser") return "browser";
129
- if (value === "node") return "node";
130
- if (value && /^(?:es\d+|chrome\d+|edge\d+|firefox\d+|safari\d+|hermes|deno\d+|ios\d+)$/.test(value)) {
131
- return "node";
132
- }
133
- return "neutral";
210
+ if (value === 'browser')
211
+ return 'browser';
212
+ if (value === 'node')
213
+ return 'node';
214
+ if (value && /^(?:es\d+|chrome\d+|edge\d+|firefox\d+|safari\d+|hermes|deno\d+|ios\d+)$/.test(value)) {
215
+ return 'node';
216
+ }
217
+ return 'neutral';
134
218
  }
135
219
  function mapRolldownSourcemap(value) {
136
- switch (value) {
137
- case "none":
138
- return false;
139
- case "inline":
140
- return "inline";
141
- case "external":
142
- case "linked":
143
- return "hidden";
144
- default:
145
- return true;
146
- }
220
+ switch (value) {
221
+ case 'none':
222
+ return false;
223
+ case 'inline':
224
+ return 'inline';
225
+ case 'external':
226
+ case 'linked':
227
+ return 'hidden';
228
+ default:
229
+ return true;
230
+ }
147
231
  }
148
232
  function mapRolldownJsx(jsx) {
149
- const { factory, fragment, ...rest } = jsx;
150
- const out = { ...rest };
151
- if (factory !== void 0) {
152
- out.pragma = factory;
153
- }
154
- if (fragment !== void 0) {
155
- out.pragmaFrag = fragment;
156
- }
157
- return out;
233
+ const { factory, fragment, ...rest } = jsx;
234
+ const out = { ...rest };
235
+ if (factory !== undefined) {
236
+ out.pragma = factory;
237
+ }
238
+ if (fragment !== undefined) {
239
+ out.pragmaFrag = fragment;
240
+ }
241
+ return out;
158
242
  }
159
243
  function toEntryFileNamesPattern(value) {
160
- if (!value) {
161
- return void 0;
162
- }
163
- const literal = !/\[[^\]]+\]/u.test(value);
164
- const stripped = value.replaceAll(/\.?\[ext\]/g, "");
165
- if (stripped.length === 0) {
166
- return void 0;
167
- }
168
- return { pattern: stripped, literal };
244
+ if (!value) {
245
+ return undefined;
246
+ }
247
+ const literal = !/\[[^\]]+\]/u.test(value);
248
+ const stripped = value.replaceAll(/\.?\[ext\]/g, '');
249
+ if (stripped.length === 0) {
250
+ return undefined;
251
+ }
252
+ return { pattern: stripped, literal };
169
253
  }
170
254
  function getJavaScriptOutExtension(options, literal) {
171
- if (literal) {
172
- return void 0;
173
- }
174
- if (options.target === "browser") {
175
- return ".js";
176
- }
177
- if (options.format === "cjs") {
178
- return ".cjs";
179
- }
180
- return ".mjs";
255
+ if (literal) {
256
+ return undefined;
257
+ }
258
+ if (options.target === 'browser') {
259
+ return '.js';
260
+ }
261
+ if (options.format === 'cjs') {
262
+ return '.cjs';
263
+ }
264
+ return '.mjs';
181
265
  }
182
266
  function normalizeOutputPath(outputPath, outdir) {
183
- return path.isAbsolute(outputPath) ? path.normalize(outputPath) : path.normalize(path.join(outdir, outputPath));
267
+ return path.isAbsolute(outputPath) ? path.normalize(outputPath) : path.normalize(path.join(outdir, outputPath));
184
268
  }
185
269
  function normalizeModulePath(modulePath, contextRoot) {
186
- return path.isAbsolute(modulePath) ? path.normalize(modulePath) : path.normalize(path.resolve(contextRoot, modulePath));
270
+ return path.isAbsolute(modulePath)
271
+ ? path.normalize(modulePath)
272
+ : path.normalize(path.resolve(contextRoot, modulePath));
187
273
  }
188
- function extractDependencyGraph(chunks, contextRoot) {
189
- const entrypoints = {};
190
- for (const chunk of chunks) {
191
- if (!chunk.facadeModuleId) {
192
- continue;
193
- }
194
- const entrypointPath = normalizeModulePath(chunk.facadeModuleId, contextRoot);
195
- entrypoints[entrypointPath] = Array.from(
196
- /* @__PURE__ */ new Set([entrypointPath, ...chunk.moduleIds.map((id) => normalizeModulePath(id, contextRoot))])
197
- );
198
- }
199
- return { entrypoints };
274
+ export function extractDependencyGraph(chunks, contextRoot) {
275
+ const entrypoints = {};
276
+ for (const chunk of chunks) {
277
+ if (!chunk.facadeModuleId) {
278
+ continue;
279
+ }
280
+ const entrypointPath = normalizeModulePath(chunk.facadeModuleId, contextRoot);
281
+ entrypoints[entrypointPath] = Array.from(new Set([entrypointPath, ...chunk.moduleIds.map((id) => normalizeModulePath(id, contextRoot))]));
282
+ }
283
+ return { entrypoints };
200
284
  }
201
- function toBuildLogs(error) {
202
- if (error instanceof Error) {
203
- return [{ message: error.message }];
204
- }
205
- return [{ message: "Unknown build error" }];
285
+ export function toBuildLogs(error) {
286
+ if (error instanceof Error) {
287
+ return [{ message: error.message }];
288
+ }
289
+ return [{ message: 'Unknown build error' }];
206
290
  }
207
- function resolveRolldownOptions(options, contextRoot, outdir, appRootRequireCache) {
208
- const external = createExternalMatcher(options, appRootRequireCache);
209
- const transformOptions = {};
210
- if (options.define) {
211
- transformOptions.define = options.define;
212
- }
213
- if (options.jsx) {
214
- transformOptions.jsx = mapRolldownJsx(options.jsx);
215
- }
216
- if (options.target && /^(?:es|chrome|edge|firefox|safari|hermes|deno|ios)/.test(options.target)) {
217
- transformOptions.target = options.target;
218
- }
219
- const bundlePlugins = options.plugins ?? [];
220
- const sourceTransforms = options.target === "browser" ? options.sourceTransforms ?? [] : [];
221
- const appPlugins = createRolldownPluginBridge(bundlePlugins, contextRoot, sourceTransforms);
222
- const allPlugins = [
223
- ...mapRolldownPlatform(options.target) === "node" ? [createNodeBuiltinExternalPlugin()] : [],
224
- ...options.target !== "browser" ? [createServerSideCssShimPlugin()] : [],
225
- ...appPlugins
226
- ];
227
- const inputOptions = {
228
- input: options.entrypoints,
229
- cwd: contextRoot,
230
- external,
231
- platform: mapRolldownPlatform(options.target),
232
- transform: Object.keys(transformOptions).length > 0 ? transformOptions : void 0,
233
- resolve: options.conditions ? { conditionNames: options.conditions } : void 0,
234
- treeshake: typeof options.treeshaking === "boolean" ? options.treeshaking : true,
235
- ...process.env.ECOPAGES_PROFILE_BUILD === "1" ? {} : {
236
- checks: {
237
- pluginTimings: false
238
- }
239
- },
240
- experimental: {
241
- nativeMagicString: true
242
- },
243
- plugins: allPlugins
244
- };
245
- const entryFileNames = toEntryFileNamesPattern(options.naming);
246
- const jsExtension = getJavaScriptOutExtension(options, entryFileNames?.literal ?? false);
247
- const finalEntryFileNames = entryFileNames ? jsExtension ? `${entryFileNames.pattern}${jsExtension}` : entryFileNames.pattern : jsExtension ? `[name]${jsExtension}` : "[name]";
248
- const outputOptions = {
249
- dir: outdir,
250
- format: mapRolldownFormat(options.format),
251
- minify: !!options.minify,
252
- entryFileNames: finalEntryFileNames,
253
- chunkFileNames: "[name]-[hash].js",
254
- assetFileNames: "[name]-[hash][extname]",
255
- sourcemap: mapRolldownSourcemap(options.sourcemap)
256
- };
257
- return { inputOptions, outputOptions };
291
+ /**
292
+ * Translates a {@link BuildOptions} into Rolldown's `InputOptions` and
293
+ * `OutputOptions`. Always sets `experimental.nativeMagicString: true`
294
+ * and always consolidates eco plugins via the bridge.
295
+ */
296
+ export function resolveRolldownOptions(options, contextRoot, outdir, appRootRequireCache) {
297
+ const rolldownPlatform = mapRolldownPlatform(options.target);
298
+ const external = createExternalMatcher(options, appRootRequireCache);
299
+ const transformOptions = {};
300
+ if (options.define) {
301
+ transformOptions.define = options.define;
302
+ }
303
+ if (options.jsx) {
304
+ transformOptions.jsx = mapRolldownJsx(options.jsx);
305
+ }
306
+ if (options.target && /^(?:es|chrome|edge|firefox|safari|hermes|deno|ios)/.test(options.target)) {
307
+ transformOptions.target = options.target;
308
+ }
309
+ const bundlePlugins = options.plugins ?? [];
310
+ const sourceTransforms = options.target === 'browser' ? (options.sourceTransforms ?? []) : [];
311
+ const appPlugins = createRolldownPluginBridge(bundlePlugins, contextRoot, sourceTransforms);
312
+ const allPlugins = [
313
+ ...(rolldownPlatform === 'node' ? [createNodeBuiltinExternalPlugin()] : []),
314
+ ...(rolldownPlatform === 'browser' ? [createBrowserNodeBuiltinGuardPlugin()] : []),
315
+ ...(options.target !== 'browser' ? [createServerSideCssShimPlugin()] : []),
316
+ ...appPlugins,
317
+ ];
318
+ const inputOptions = {
319
+ input: options.entrypoints,
320
+ cwd: contextRoot,
321
+ external,
322
+ platform: mapRolldownPlatform(options.target),
323
+ transform: Object.keys(transformOptions).length > 0 ? transformOptions : undefined,
324
+ resolve: options.conditions ? { conditionNames: options.conditions } : undefined,
325
+ treeshake: typeof options.treeshaking === 'boolean' ? options.treeshaking : true,
326
+ ...(process.env.ECOPAGES_PROFILE_BUILD === '1'
327
+ ? {}
328
+ : {
329
+ checks: {
330
+ pluginTimings: false,
331
+ },
332
+ }),
333
+ experimental: {
334
+ nativeMagicString: true,
335
+ },
336
+ plugins: allPlugins,
337
+ };
338
+ const entryFileNames = toEntryFileNamesPattern(options.naming);
339
+ const jsExtension = getJavaScriptOutExtension(options, entryFileNames?.literal ?? false);
340
+ const finalEntryFileNames = entryFileNames
341
+ ? jsExtension
342
+ ? `${entryFileNames.pattern}${jsExtension}`
343
+ : entryFileNames.pattern
344
+ : jsExtension
345
+ ? `[name]${jsExtension}`
346
+ : '[name]';
347
+ const entrypointCount = Array.isArray(options.entrypoints)
348
+ ? options.entrypoints.length
349
+ : Object.keys(options.entrypoints).length;
350
+ const disableCodeSplitting = options.splitting === false && entrypointCount === 1;
351
+ const outputOptions = {
352
+ dir: outdir,
353
+ format: mapRolldownFormat(options.format),
354
+ minify: !!options.minify,
355
+ entryFileNames: finalEntryFileNames,
356
+ chunkFileNames: '[name]-[hash].js',
357
+ assetFileNames: '[name]-[hash][extname]',
358
+ sourcemap: mapRolldownSourcemap(options.sourcemap),
359
+ ...(disableCodeSplitting ? { codeSplitting: false } : {}),
360
+ };
361
+ return { inputOptions, outputOptions };
258
362
  }
259
- function rewriteBrowserRuntimeImportsInOutputs(result, contextRoot, plugins) {
260
- if (!result.success || result.outputs.length === 0) {
261
- return result;
262
- }
263
- const specifierMap = collectBrowserRuntimeImportRewriteMap(plugins);
264
- if (specifierMap.size === 0) {
363
+ /**
364
+ * Rewrites manifest-owned runtime specifiers in emitted JS output
365
+ * files. Skips work when the specifier map is empty or when a
366
+ * `(specifierMap, path, content)` tuple was already seen.
367
+ *
368
+ * The content cache is module-level and is keyed on a djb2 hash of
369
+ * the input bytes plus a sorted fingerprint of the specifier map. A
370
+ * manifest change correctly invalidates prior entries; different
371
+ * content of the same length does not collide.
372
+ */
373
+ export function rewriteBrowserRuntimeImportsInOutputs(result, contextRoot, plugins) {
374
+ if (!result.success || result.outputs.length === 0) {
375
+ return result;
376
+ }
377
+ const specifierMap = collectBrowserRuntimeImportRewriteMap(plugins);
378
+ if (specifierMap.size === 0) {
379
+ return result;
380
+ }
381
+ const moduleRequireFromContext = createRequire(path.join(contextRoot, 'package.json'));
382
+ const fs = moduleRequireFromContext('node:fs');
383
+ const cacheFingerprint = `${Array.from(specifierMap.entries()).sort().join('|')}`;
384
+ for (const output of result.outputs) {
385
+ if (!/\.(?:[cm]?js)$/u.test(output.path)) {
386
+ continue;
387
+ }
388
+ const code = fs.readFileSync(output.path, 'utf-8');
389
+ const contentKey = `${cacheFingerprint}::${output.path}::${djb2(code)}`;
390
+ if (rewriteCache.has(contentKey)) {
391
+ continue;
392
+ }
393
+ const rewritten = rewriteBrowserRuntimeImports(code, specifierMap, output.path);
394
+ if (rewritten !== code) {
395
+ fs.writeFileSync(output.path, rewritten);
396
+ }
397
+ rememberRewrite(contentKey);
398
+ }
265
399
  return result;
266
- }
267
- const moduleRequireFromContext = createRequire(path.join(contextRoot, "package.json"));
268
- const fs = moduleRequireFromContext("node:fs");
269
- const cacheFingerprint = `${Array.from(specifierMap.entries()).sort().join("|")}`;
270
- for (const output of result.outputs) {
271
- if (!/\.(?:[cm]?js)$/u.test(output.path)) {
272
- continue;
273
- }
274
- const code = fs.readFileSync(output.path, "utf-8");
275
- const contentKey = `${cacheFingerprint}::${output.path}::${djb2(code)}`;
276
- if (rewriteCache.has(contentKey)) {
277
- continue;
278
- }
279
- const rewritten = rewriteBrowserRuntimeImports(code, specifierMap, output.path);
280
- if (rewritten !== code) {
281
- fs.writeFileSync(output.path, rewritten);
282
- }
283
- rememberRewrite(contentKey);
284
- }
285
- return result;
286
400
  }
287
401
  const REWRITE_CACHE_MAX_ENTRIES = 2048;
288
- const rewriteCache = /* @__PURE__ */ new Set();
402
+ const rewriteCache = new Set();
403
+ /**
404
+ * @remarks
405
+ * Dev rebuilds hit the same output paths with stable specifier maps; memoizing
406
+ * skips re-reading and re-writing unchanged files. The cache is capped because
407
+ * a process-global set would otherwise grow for the lifetime of a watch session.
408
+ * Eviction uses insertion order as an approximate LRU.
409
+ */
289
410
  function rememberRewrite(contentKey) {
290
- rewriteCache.add(contentKey);
291
- if (rewriteCache.size > REWRITE_CACHE_MAX_ENTRIES) {
292
- const oldest = rewriteCache.values().next().value;
293
- if (oldest !== void 0) {
294
- rewriteCache.delete(oldest);
411
+ rewriteCache.add(contentKey);
412
+ if (rewriteCache.size > REWRITE_CACHE_MAX_ENTRIES) {
413
+ const oldest = rewriteCache.values().next().value;
414
+ if (oldest !== undefined) {
415
+ rewriteCache.delete(oldest);
416
+ }
295
417
  }
296
- }
297
418
  }
298
419
  function djb2(input) {
299
- let hash = 5381;
300
- for (let i = 0; i < input.length; i++) {
301
- hash = (hash << 5) + hash + input.charCodeAt(i) | 0;
302
- }
303
- return hash.toString(36);
420
+ let hash = 5381;
421
+ for (let i = 0; i < input.length; i++) {
422
+ hash = ((hash << 5) + hash + input.charCodeAt(i)) | 0;
423
+ }
424
+ return hash.toString(36);
304
425
  }
305
- function clearRewriteCacheForTests() {
306
- rewriteCache.clear();
426
+ /** Test-only: clears the rewriter content cache. */
427
+ export function clearRewriteCacheForTests() {
428
+ rewriteCache.clear();
307
429
  }
308
- function rewriteNodeRuntimeImportsInOutputs(result, contextRoot) {
309
- if (!result.success || result.outputs.length === 0) {
430
+ /** Normalizes node-runtime import paths in emitted outputs. */
431
+ export function rewriteNodeRuntimeImportsInOutputs(result, contextRoot) {
432
+ if (!result.success || result.outputs.length === 0) {
433
+ return result;
434
+ }
435
+ normalizeNodeRuntimeBuildOutputs(result.outputs.map((output) => output.path), contextRoot);
310
436
  return result;
311
- }
312
- normalizeNodeRuntimeBuildOutputs(
313
- result.outputs.map((output) => output.path),
314
- contextRoot
315
- );
316
- return result;
317
437
  }
318
- function buildResultFromRolldownOutput(output, outdir, contextRoot) {
319
- const outputs = output.output.map((entry) => ({
320
- path: normalizeOutputPath(entry.fileName, outdir)
321
- }));
322
- const entryChunks = output.output.filter((entry) => entry.type === "chunk" && entry.isEntry);
323
- const dependencyGraph = entryChunks.length > 0 ? extractDependencyGraph(entryChunks, contextRoot) : void 0;
324
- const entryOutputs = {};
325
- for (const chunk of entryChunks) {
326
- if (chunk.facadeModuleId) {
327
- entryOutputs[normalizeModulePath(chunk.facadeModuleId, contextRoot)] = normalizeOutputPath(
328
- chunk.fileName,
329
- outdir
330
- );
331
- }
332
- }
333
- return {
334
- success: true,
335
- logs: [],
336
- outputs,
337
- dependencyGraph,
338
- entryOutputs: entryChunks.length > 0 ? entryOutputs : void 0
339
- };
438
+ /** Maps a Rolldown `output` to a normalized {@link BuildResult}. */
439
+ export function buildResultFromRolldownOutput(output, outdir, contextRoot) {
440
+ const outputs = output.output.map((entry) => ({
441
+ path: normalizeOutputPath(entry.fileName, outdir),
442
+ }));
443
+ const entryChunks = output.output.filter((entry) => entry.type === 'chunk' && entry.isEntry);
444
+ const dependencyGraph = entryChunks.length > 0 ? extractDependencyGraph(entryChunks, contextRoot) : undefined;
445
+ const entryOutputs = {};
446
+ for (const chunk of entryChunks) {
447
+ if (chunk.facadeModuleId) {
448
+ entryOutputs[normalizeModulePath(chunk.facadeModuleId, contextRoot)] = normalizeOutputPath(chunk.fileName, outdir);
449
+ }
450
+ }
451
+ return {
452
+ success: true,
453
+ logs: [],
454
+ outputs,
455
+ dependencyGraph,
456
+ entryOutputs: entryChunks.length > 0 ? entryOutputs : undefined,
457
+ };
340
458
  }
341
- export {
342
- buildResultFromRolldownOutput,
343
- clearRewriteCacheForTests,
344
- createNodeBuiltinExternalPlugin,
345
- extractDependencyGraph,
346
- resolveRolldownOptions,
347
- rewriteBrowserRuntimeImportsInOutputs,
348
- rewriteNodeRuntimeImportsInOutputs,
349
- toBuildLogs,
350
- transpileProfileToOptions
351
- };