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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (338) hide show
  1. package/README.md +1 -0
  2. package/package.json +82 -3
  3. package/src/adapters/abstract/application-adapter.d.ts +0 -8
  4. package/src/adapters/abstract/application-adapter.js +252 -261
  5. package/src/adapters/abstract/router-adapter.js +12 -4
  6. package/src/adapters/abstract/segment-path-matcher.js +132 -134
  7. package/src/adapters/abstract/server-adapter.js +22 -14
  8. package/src/adapters/abstract/ws-pattern-matcher.js +24 -26
  9. package/src/adapters/bun/bun-user-websocket-lifecycle.js +83 -86
  10. package/src/adapters/bun/client-bridge.js +51 -50
  11. package/src/adapters/bun/create-app.js +171 -161
  12. package/src/adapters/bun/hmr-manager.js +62 -57
  13. package/src/adapters/bun/index.js +2 -31
  14. package/src/adapters/bun/runtime-host.js +61 -54
  15. package/src/adapters/bun/server-adapter.d.ts +0 -1
  16. package/src/adapters/bun/server-adapter.js +561 -561
  17. package/src/adapters/bun/static-preview-host.js +43 -46
  18. package/src/adapters/create-app.js +11 -14
  19. package/src/adapters/index.js +2 -30
  20. package/src/adapters/node/create-app.js +123 -129
  21. package/src/adapters/node/http-request-bridge.js +147 -106
  22. package/src/adapters/node/node-client-bridge.js +62 -64
  23. package/src/adapters/node/node-hmr-manager.js +58 -48
  24. package/src/adapters/node/runtime-host.js +96 -89
  25. package/src/adapters/node/server-adapter-dependencies.js +18 -21
  26. package/src/adapters/node/server-adapter.d.ts +0 -1
  27. package/src/adapters/node/server-adapter.js +347 -326
  28. package/src/adapters/node/static-content-server.js +172 -191
  29. package/src/adapters/node/static-preview-host.js +87 -78
  30. package/src/adapters/shared/hmr/dev-transform-entrypoint-registry.d.ts +16 -0
  31. package/src/adapters/shared/hmr/dev-transform-entrypoint-registry.js +32 -0
  32. package/src/adapters/shared/hmr/hmr-html-response.js +46 -32
  33. package/src/adapters/shared/hmr/shared-hmr-manager.d.ts +29 -38
  34. package/src/adapters/shared/hmr/shared-hmr-manager.js +439 -425
  35. package/src/adapters/shared/http/api-request-pipeline.js +122 -119
  36. package/src/adapters/shared/http/api-response.js +77 -77
  37. package/src/adapters/shared/http/create-body-response.js +22 -19
  38. package/src/adapters/shared/http/define-api-handler.js +41 -55
  39. package/src/adapters/shared/http/explicit-static-render-preparation.js +26 -23
  40. package/src/adapters/shared/http/explicit-static-route-matcher.js +55 -62
  41. package/src/adapters/shared/http/file-route-middleware-pipeline.js +81 -75
  42. package/src/adapters/shared/http/fs-server-response-factory.js +101 -96
  43. package/src/adapters/shared/http/fs-server-response-matcher.js +239 -257
  44. package/src/adapters/shared/http/run-middleware-chain.js +15 -15
  45. package/src/adapters/shared/runtime/application-adapter.js +72 -87
  46. package/src/adapters/shared/runtime/copy-runtime-public-dir.js +25 -22
  47. package/src/adapters/shared/runtime/port-manager.js +207 -177
  48. package/src/adapters/shared/runtime/render-context.js +94 -79
  49. package/src/adapters/shared/runtime/runtime-app-bootstrap.js +33 -38
  50. package/src/adapters/shared/runtime/runtime-host.js +1 -0
  51. package/src/adapters/shared/runtime/runtime-server-lifecycle.d.ts +2 -3
  52. package/src/adapters/shared/runtime/runtime-server-lifecycle.js +65 -51
  53. package/src/adapters/shared/runtime/server-adapter.d.ts +1 -0
  54. package/src/adapters/shared/runtime/server-adapter.js +233 -217
  55. package/src/adapters/shared/runtime/server-route-handler.js +74 -70
  56. package/src/adapters/shared/runtime/server-static-builder.js +165 -184
  57. package/src/adapters/shared/runtime/static-preview-host.js +1 -0
  58. package/src/adapters/shared/ws/node-http-websocket-upgrades.js +97 -88
  59. package/src/adapters/shared/ws/websocket-lifecycle.js +57 -50
  60. package/src/build/README.md +52 -1
  61. package/src/build/app-build-manifest-runtime.js +129 -108
  62. package/src/build/browser/browser-runtime-manifest.js +47 -50
  63. package/src/build/browser/browser-runtime-plugin-helpers.js +32 -12
  64. package/src/build/browser/browser-runtime-plugin.js +206 -160
  65. package/src/build/browser/jsx-ownership-plugins.js +51 -37
  66. package/src/build/browser/lit-static-render-worker-context.js +3 -5
  67. package/src/build/build-adapter.js +276 -139
  68. package/src/build/cache/build-input-fingerprint.js +28 -26
  69. package/src/build/cache/cache-constants.js +4 -6
  70. package/src/build/cache/cache-keys.js +64 -56
  71. package/src/build/cache/pages-unified-graph-build.js +179 -178
  72. package/src/build/cache/production-build-cache.js +47 -54
  73. package/src/build/cache/server-entry-build-cache.js +134 -146
  74. package/src/build/contracts/build-contracts.d.ts +4 -4
  75. package/src/build/contracts/build-contracts.js +1 -0
  76. package/src/build/contracts/build-manifest.js +58 -43
  77. package/src/build/contracts/build-types.js +1 -0
  78. package/src/build/rolldown/rolldown-adapter-helpers.d.ts +9 -0
  79. package/src/build/rolldown/rolldown-adapter-helpers.js +405 -298
  80. package/src/build/rolldown/rolldown-build-adapter.js +53 -61
  81. package/src/build/rolldown/rolldown-build-invocation-metrics.js +31 -35
  82. package/src/build/rolldown/rolldown-plugin-bridge.js +264 -194
  83. package/src/build/rolldown/rolldown-source-transform-pass.js +59 -50
  84. package/src/build/rolldown/runtime-build-output-normalizer.js +227 -175
  85. package/src/build/rolldown/server-side-css-shim-plugin.js +54 -31
  86. package/src/build/runtime/build-profile-options.js +36 -36
  87. package/src/build/runtime/build-request-identity.js +70 -45
  88. package/src/build/runtime/build-request-policy.js +80 -42
  89. package/src/build/runtime/build-runtime.js +64 -54
  90. package/src/build/runtime/deduping-build-executor.js +38 -32
  91. package/src/build/runtime/parallel-build-executor.js +58 -50
  92. package/src/build/runtime/serialized-build-executor.js +78 -62
  93. package/src/cache/index.js +6 -6
  94. package/src/cache/module-parse-cache.js +99 -68
  95. package/src/client/navigation-scripts/classification.js +45 -37
  96. package/src/client/navigation-scripts/index.js +3 -23
  97. package/src/client/navigation-scripts/navigation-scripts.test.browser.js +58 -62
  98. package/src/client/navigation-scripts/registry.js +15 -11
  99. package/src/client/navigation-scripts/rerun-queue.js +81 -64
  100. package/src/client/scroll.js +32 -24
  101. package/src/client/scroll.test.browser.js +27 -33
  102. package/src/client/view-transitions.js +68 -55
  103. package/src/config/config-builder.d.ts +8 -0
  104. package/src/config/config-builder.js +637 -642
  105. package/src/config/constants.js +44 -24
  106. package/src/declarations.d.ts +1 -0
  107. package/src/dev/README.md +24 -0
  108. package/src/dev/client-bridge-registry.js +7 -12
  109. package/src/dev/dev-client-ownership.js +7 -5
  110. package/src/dev/hmr-manager-registry.js +7 -12
  111. package/src/dev/host-runtime.js +25 -30
  112. package/src/dev/runtime-server-started-message.js +2 -5
  113. package/src/dev/sc-server.js +106 -103
  114. package/src/dev/transform-server/dev-transform-bundler.d.ts +24 -0
  115. package/src/dev/transform-server/dev-transform-bundler.js +79 -0
  116. package/src/dev/transform-server/dev-transform-externalize-plugin.d.ts +12 -0
  117. package/src/dev/transform-server/dev-transform-externalize-plugin.js +29 -0
  118. package/src/dev/transform-server/dev-transform-import-rewriter.d.ts +16 -0
  119. package/src/dev/transform-server/dev-transform-import-rewriter.js +110 -0
  120. package/src/dev/transform-server/dev-transform-module-kind.d.ts +13 -0
  121. package/src/dev/transform-server/dev-transform-module-kind.js +17 -0
  122. package/src/dev/transform-server/dev-transform-runtime-specifiers.d.ts +5 -0
  123. package/src/dev/transform-server/dev-transform-runtime-specifiers.js +16 -0
  124. package/src/dev/transform-server/dev-transform-server.d.ts +41 -0
  125. package/src/dev/transform-server/dev-transform-server.js +191 -0
  126. package/src/dev/transform-server/dev-transform-url.d.ts +13 -0
  127. package/src/dev/transform-server/dev-transform-url.js +58 -0
  128. package/src/dev/transform-server/dev-transform-vendor-registry.d.ts +27 -0
  129. package/src/dev/transform-server/dev-transform-vendor-registry.js +145 -0
  130. package/src/dev/transform-server/index.d.ts +6 -0
  131. package/src/dev/transform-server/index.js +4 -0
  132. package/src/dev/transform-server/types.d.ts +15 -0
  133. package/src/dev/transform-server/types.js +1 -0
  134. package/src/dev-toolbar/README.md +51 -0
  135. package/src/dev-toolbar/define-dev-tool.d.ts +21 -0
  136. package/src/dev-toolbar/define-dev-tool.js +9 -0
  137. package/src/dev-toolbar/dev-toolbar-config.d.ts +25 -0
  138. package/src/dev-toolbar/dev-toolbar-config.js +19 -0
  139. package/src/dev-toolbar/dev-toolbar-host.d.ts +49 -0
  140. package/src/dev-toolbar/dev-toolbar-host.js +117 -0
  141. package/src/dev-toolbar/dev-toolbar-html-response.d.ts +11 -0
  142. package/src/dev-toolbar/dev-toolbar-html-response.js +14 -0
  143. package/src/dev-toolbar/dev-toolbar-manifest.d.ts +15 -0
  144. package/src/dev-toolbar/dev-toolbar-manifest.js +52 -0
  145. package/src/dev-toolbar/dev-toolbar-package.d.ts +31 -0
  146. package/src/dev-toolbar/dev-toolbar-package.js +72 -0
  147. package/src/dev-toolbar/dev-toolbar-runtime-paths.d.ts +10 -0
  148. package/src/dev-toolbar/dev-toolbar-runtime-paths.js +13 -0
  149. package/src/diagnostics/request-build-dedupe.js +34 -28
  150. package/src/diagnostics/startup-trace.d.ts +10 -1
  151. package/src/diagnostics/startup-trace.js +269 -241
  152. package/src/eco/README.md +6 -0
  153. package/src/eco/eco-declared-component.js +19 -14
  154. package/src/eco/eco.browser.js +56 -69
  155. package/src/eco/eco.js +156 -96
  156. package/src/eco/eco.types.js +5 -0
  157. package/src/eco/eco.utils.js +1 -10
  158. package/src/eco/global-injector-map.js +55 -41
  159. package/src/eco/lazy-injector-map.js +90 -60
  160. package/src/eco/module-dependencies.js +52 -44
  161. package/src/eco/page-layout-normalization.js +59 -49
  162. package/src/errors/http-error.js +50 -49
  163. package/src/errors/index.js +3 -12
  164. package/src/errors/locals-access-error.js +5 -8
  165. package/src/errors/undeclared-component-dependency-error.js +15 -15
  166. package/src/global/app-logger.js +3 -6
  167. package/src/hmr/README.md +10 -0
  168. package/src/hmr/client/hmr-runtime.js +117 -113
  169. package/src/hmr/client/module-update.d.ts +13 -0
  170. package/src/hmr/client/module-update.js +39 -0
  171. package/src/hmr/hmr-asset-paths.d.ts +14 -0
  172. package/src/hmr/hmr-asset-paths.js +22 -0
  173. package/src/hmr/hmr-entrypoint-output.d.ts +11 -39
  174. package/src/hmr/hmr-entrypoint-output.js +28 -54
  175. package/src/hmr/hmr-file-change-prep.js +13 -16
  176. package/src/hmr/hmr-registered-entrypoints-context.d.ts +7 -0
  177. package/src/hmr/hmr-registered-entrypoints-context.js +1 -0
  178. package/src/hmr/hmr-runtime-paths.d.ts +10 -0
  179. package/src/hmr/hmr-runtime-paths.js +13 -0
  180. package/src/hmr/hmr-strategy.d.ts +5 -11
  181. package/src/hmr/hmr-strategy.js +113 -61
  182. package/src/hmr/strategies/default-hmr-strategy.js +55 -33
  183. package/src/hmr/strategies/js-hmr-strategy.d.ts +6 -95
  184. package/src/hmr/strategies/js-hmr-strategy.js +104 -217
  185. package/src/hmr/strategies/server-rendered-template-hmr-strategy.js +33 -27
  186. package/src/index.browser.js +1 -4
  187. package/src/index.d.ts +1 -0
  188. package/src/index.js +6 -47
  189. package/src/integrations/ghtml/ghtml-renderer.js +12 -7
  190. package/src/integrations/ghtml/ghtml.constants.js +1 -4
  191. package/src/integrations/ghtml/ghtml.plugin.js +9 -12
  192. package/src/islands/README.md +25 -0
  193. package/src/islands/island-host.d.ts +37 -0
  194. package/src/islands/island-host.js +55 -0
  195. package/src/plugins/alias-resolver-cache.js +114 -97
  196. package/src/plugins/alias-resolver-plugin.js +33 -47
  197. package/src/plugins/define-integration.js +18 -17
  198. package/src/plugins/eco-component-meta-plugin.js +387 -145
  199. package/src/plugins/foreign-jsx-override-plugin.js +49 -35
  200. package/src/plugins/integration-plugin.js +212 -203
  201. package/src/plugins/jsx-import-source.utils.js +16 -21
  202. package/src/plugins/processor.js +159 -149
  203. package/src/plugins/runtime-capability.js +1 -0
  204. package/src/plugins/source-transform.js +109 -79
  205. package/src/plugins/tsconfig-import-resolver.d.ts +17 -0
  206. package/src/plugins/tsconfig-import-resolver.js +218 -142
  207. package/src/route-renderer/README.md +12 -1
  208. package/src/route-renderer/orchestration/document-shell/document-shell-render.service.js +143 -136
  209. package/src/route-renderer/orchestration/document-shell/layout-shell-props.service.js +33 -27
  210. package/src/route-renderer/orchestration/foreign-child/component-render-context.js +173 -126
  211. package/src/route-renderer/orchestration/foreign-child/foreign-child-output.utils.js +165 -154
  212. package/src/route-renderer/orchestration/foreign-child/foreign-subtree-execution.service.js +329 -341
  213. package/src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.js +33 -32
  214. package/src/route-renderer/orchestration/integration-renderer.d.ts +1 -0
  215. package/src/route-renderer/orchestration/integration-renderer.js +731 -750
  216. package/src/route-renderer/orchestration/integration-renderer.test-fixtures.js +168 -172
  217. package/src/route-renderer/orchestration/ownership-graph/component-graph-collectors.js +119 -131
  218. package/src/route-renderer/orchestration/ownership-graph/component-graph.js +82 -91
  219. package/src/route-renderer/orchestration/ownership-graph/ownership-validation.service.js +82 -76
  220. package/src/route-renderer/orchestration/page-browser-graph/global-injector-assets.service.js +29 -31
  221. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-contribution.loader.js +10 -6
  222. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.js +31 -28
  223. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-session.d.ts +3 -0
  224. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-session.js +430 -413
  225. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph.service.js +191 -212
  226. package/src/route-renderer/orchestration/page-browser-graph/processed-asset-dedupe.js +20 -24
  227. package/src/route-renderer/orchestration/route-pipeline/integration-route-render-adapter.d.ts +4 -0
  228. package/src/route-renderer/orchestration/route-pipeline/integration-route-render-adapter.js +24 -24
  229. package/src/route-renderer/orchestration/route-pipeline/marker-artifact.utils.js +22 -24
  230. package/src/route-renderer/orchestration/route-pipeline/robots-meta.contribution.js +41 -34
  231. package/src/route-renderer/orchestration/route-pipeline/route-html-finalization.service.d.ts +5 -0
  232. package/src/route-renderer/orchestration/route-pipeline/route-html-finalization.service.js +42 -22
  233. package/src/route-renderer/orchestration/route-pipeline/route-prepared-options.builder.js +50 -48
  234. package/src/route-renderer/orchestration/route-pipeline/route-prepared-options.utils.js +29 -32
  235. package/src/route-renderer/orchestration/route-pipeline/route-render-orchestrator.js +150 -156
  236. package/src/route-renderer/orchestration/string-markup-renderer.js +48 -51
  237. package/src/route-renderer/page-loading/component-dependency-collection.js +120 -124
  238. package/src/route-renderer/page-loading/declared-asset-collection.js +66 -94
  239. package/src/route-renderer/page-loading/dependency-resolver.js +101 -104
  240. package/src/route-renderer/page-loading/ecopages-virtual-imports.js +68 -54
  241. package/src/route-renderer/page-loading/lazy-entry-collection.js +75 -98
  242. package/src/route-renderer/page-loading/lazy-trigger-planning.js +46 -36
  243. package/src/route-renderer/page-loading/module-declaration-aggregation.js +38 -31
  244. package/src/route-renderer/page-loading/module-declaration-scripts.js +10 -15
  245. package/src/route-renderer/page-loading/page-dependency-bundling.js +156 -113
  246. package/src/route-renderer/page-loading/page-module-loader.js +130 -124
  247. package/src/route-renderer/route-renderer.js +74 -76
  248. package/src/router/client/link-intent.js +55 -39
  249. package/src/router/client/link-intent.test.browser.js +49 -49
  250. package/src/router/client/link-navigation-policy.js +114 -93
  251. package/src/router/client/link-navigation-policy.test.browser.js +70 -80
  252. package/src/router/client/navigation-coordinator.js +235 -211
  253. package/src/router/server/route-registry.js +237 -242
  254. package/src/services/assets/asset-processing-service/asset-dependency-keys.js +64 -53
  255. package/src/services/assets/asset-processing-service/asset-processing.service.js +287 -303
  256. package/src/services/assets/asset-processing-service/asset.factory.js +78 -81
  257. package/src/services/assets/asset-processing-service/assets.types.js +1 -0
  258. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +57 -46
  259. package/src/services/assets/asset-processing-service/browser-runtime-entry-resolution.js +106 -69
  260. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.js +53 -53
  261. package/src/services/assets/asset-processing-service/finalize-processed-asset.js +4 -6
  262. package/src/services/assets/asset-processing-service/grouped-content-bundles.js +79 -80
  263. package/src/services/assets/asset-processing-service/index.js +8 -8
  264. package/src/services/assets/asset-processing-service/inline-content-script-body.js +22 -16
  265. package/src/services/assets/asset-processing-service/materialize-content-script-asset.js +21 -17
  266. package/src/services/assets/asset-processing-service/page-package.js +70 -72
  267. package/src/services/assets/asset-processing-service/processor.interface.js +7 -5
  268. package/src/services/assets/asset-processing-service/processor.registry.js +11 -14
  269. package/src/services/assets/asset-processing-service/processors/base/base-processor.js +59 -62
  270. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.js +102 -117
  271. package/src/services/assets/asset-processing-service/processors/index.js +5 -5
  272. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.js +110 -115
  273. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +95 -97
  274. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +136 -135
  275. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +27 -29
  276. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +34 -40
  277. package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.js +36 -35
  278. package/src/services/assets/asset-processing-service/resolve-integration-plugin.js +14 -16
  279. package/src/services/assets/asset-processing-service/ungrouped-dependency-processing.js +27 -39
  280. package/src/services/assets/browser-bundle.service.js +52 -47
  281. package/src/services/cache/cache.types.js +5 -0
  282. package/src/services/cache/index.js +6 -7
  283. package/src/services/cache/memory-cache-store.js +101 -89
  284. package/src/services/cache/page-cache-service.js +156 -145
  285. package/src/services/cache/page-request-cache-coordinator.service.js +102 -102
  286. package/src/services/html/html-rewriter-provider.service.js +61 -61
  287. package/src/services/html/html-transformer.service.js +249 -266
  288. package/src/services/invalidation/development-invalidation.service.js +252 -241
  289. package/src/services/module-loading/app-module-loader.service.js +1 -0
  290. package/src/services/module-loading/app-server-module-transpiler.service.js +107 -101
  291. package/src/services/module-loading/host-module-loader-registry.js +6 -11
  292. package/src/services/module-loading/module-loading-types.js +1 -0
  293. package/src/services/module-loading/page-module-import.service.js +235 -243
  294. package/src/services/module-loading/route-module-build-cache-registry.js +47 -33
  295. package/src/services/module-loading/route-module-build-cache.js +3 -38
  296. package/src/services/module-loading/route-module-build-cache.store.js +195 -200
  297. package/src/services/module-loading/route-module-build-manifest.js +61 -74
  298. package/src/services/module-loading/route-module-dependency-hasher.js +136 -110
  299. package/src/services/module-loading/server-module-transpiler.service.js +68 -62
  300. package/src/services/module-loading/source-module-support.js +15 -7
  301. package/src/services/runtime-state/dev-graph.service.js +165 -157
  302. package/src/services/runtime-state/entrypoint-dependency-graph.service.js +85 -76
  303. package/src/services/runtime-state/server-invalidation-state.service.js +38 -30
  304. package/src/services/validation/schema-validation-service.js +157 -95
  305. package/src/services/validation/standard-schema.types.js +1 -0
  306. package/src/services/validation/validate-standard-schema.js +13 -13
  307. package/src/static-site-generator/production-page-browser-graph-prebuild.js +35 -19
  308. package/src/static-site-generator/sitemap-routes.js +33 -28
  309. package/src/static-site-generator/sitemap.js +38 -29
  310. package/src/static-site-generator/static-build-invalidation.js +34 -56
  311. package/src/static-site-generator/static-export-context.js +1 -0
  312. package/src/static-site-generator/static-site-generator.js +517 -553
  313. package/src/types/internal-types.d.ts +19 -3
  314. package/src/types/internal-types.js +1 -0
  315. package/src/types/public-types.d.ts +16 -46
  316. package/src/types/public-types.js +1 -0
  317. package/src/utils/deep-merge.js +39 -26
  318. package/src/utils/ecopages-route-info.js +27 -23
  319. package/src/utils/hash.js +3 -6
  320. package/src/utils/html-escaping.js +21 -8
  321. package/src/utils/html.js +1 -4
  322. package/src/utils/invariant.js +11 -10
  323. package/src/utils/locals-utils.js +32 -22
  324. package/src/utils/parse-cli-args.js +73 -65
  325. package/src/utils/path-pattern.js +38 -23
  326. package/src/utils/path-utils.module.js +8 -11
  327. package/src/utils/resolve-entry-file.js +70 -38
  328. package/src/utils/resolve-work-dir.js +23 -27
  329. package/src/utils/runtime.js +24 -33
  330. package/src/utils/server-utils.module.js +60 -52
  331. package/src/utils/static-file-extensions.js +52 -46
  332. package/src/watchers/project-watcher-ignore.js +16 -15
  333. package/src/watchers/project-watcher.js +385 -366
  334. package/src/watchers/project-watcher.test-helpers.js +45 -50
  335. package/src/adapters/shared/hmr/hmr-entrypoint-registrar.d.ts +0 -56
  336. package/src/adapters/shared/hmr/hmr-entrypoint-registrar.js +0 -106
  337. package/src/build/cache/dev-browser-script-cache.d.ts +0 -34
  338. package/src/build/cache/dev-browser-script-cache.js +0 -90
@@ -1,55 +1,62 @@
1
- import { appLogger } from "../../../global/app-logger.js";
1
+ import { appLogger } from '../../../global/app-logger.js';
2
2
  function sendOutgoingMessage(transport, message) {
3
- if (typeof message === "string") {
4
- transport.send(message);
5
- } else if (message instanceof Blob) {
6
- void message.arrayBuffer().then((buffer) => transport.send(new Uint8Array(buffer)));
7
- } else if (message instanceof ArrayBuffer) {
8
- transport.send(new Uint8Array(message));
9
- } else if (ArrayBuffer.isView(message)) {
10
- transport.send(new Uint8Array(message.buffer, message.byteOffset, message.byteLength));
11
- } else {
12
- transport.send(message);
13
- }
3
+ if (typeof message === 'string') {
4
+ transport.send(message);
5
+ }
6
+ else if (message instanceof Blob) {
7
+ void message.arrayBuffer().then((buffer) => transport.send(new Uint8Array(buffer)));
8
+ }
9
+ else if (message instanceof ArrayBuffer) {
10
+ transport.send(new Uint8Array(message));
11
+ }
12
+ else if (ArrayBuffer.isView(message)) {
13
+ transport.send(new Uint8Array(message.buffer, message.byteOffset, message.byteLength));
14
+ }
15
+ else {
16
+ transport.send(message);
17
+ }
14
18
  }
15
- function createEcopagesSocket(transport, meta) {
16
- return {
17
- kind: meta.kind,
18
- params: meta.params,
19
- search: meta.search,
20
- context: meta.context,
21
- send: (message) => sendOutgoingMessage(transport, message),
22
- sendStream: async (stream) => {
23
- const reader = stream.getReader();
24
- try {
25
- while (true) {
26
- const { value, done } = await reader.read();
27
- if (done) break;
28
- if (value) transport.send(value);
29
- }
30
- } finally {
31
- reader.releaseLock();
32
- }
33
- },
34
- close: (code, reason) => transport.close(code, reason)
35
- };
19
+ /**
20
+ * @remarks
21
+ * Bun and Node adapters previously duplicated outgoing-message dispatch and
22
+ * stream forwarding; this is the shared implementation both transports delegate to.
23
+ */
24
+ export function createEcopagesSocket(transport, meta) {
25
+ return {
26
+ kind: meta.kind,
27
+ params: meta.params,
28
+ search: meta.search,
29
+ context: meta.context,
30
+ send: (message) => sendOutgoingMessage(transport, message),
31
+ sendStream: async (stream) => {
32
+ const reader = stream.getReader();
33
+ try {
34
+ while (true) {
35
+ const { value, done } = await reader.read();
36
+ if (done)
37
+ break;
38
+ if (value)
39
+ transport.send(value);
40
+ }
41
+ }
42
+ finally {
43
+ reader.releaseLock();
44
+ }
45
+ },
46
+ close: (code, reason) => transport.close(code, reason),
47
+ };
36
48
  }
37
- function toWebSocketCloseInfo(code, reason) {
38
- return {
39
- code,
40
- reason,
41
- wasClean: code === 1e3 || code === 1001
42
- };
49
+ export function toWebSocketCloseInfo(code, reason) {
50
+ return {
51
+ code,
52
+ reason,
53
+ wasClean: code === 1000 || code === 1001,
54
+ };
43
55
  }
44
- function invokeWebSocketHandlerHook(kind, hookName, result) {
45
- if (result instanceof Promise) {
46
- result.catch((error) => {
47
- appLogger.error(`[WS:${kind}] ${hookName} failed:`, error);
48
- });
49
- }
56
+ export function invokeWebSocketHandlerHook(kind, hookName, result) {
57
+ if (result instanceof Promise) {
58
+ result.catch((error) => {
59
+ appLogger.error(`[WS:${kind}] ${hookName} failed:`, error);
60
+ });
61
+ }
50
62
  }
51
- export {
52
- createEcopagesSocket,
53
- invokeWebSocketHandlerHook,
54
- toWebSocketCloseInfo
55
- };
@@ -2,6 +2,23 @@
2
2
 
3
3
  The build layer is the bundler contract for Ecopages. One bundled adapter is the default; one host-owned boundary marker covers the Vite-host path.
4
4
 
5
+ ## Contents
6
+
7
+ - [Mental Model](#mental-model)
8
+ - [Files](#files)
9
+ - [Default Flow](#default-flow)
10
+ - [App build manifest](#app-build-manifest)
11
+ - [Vite-Host Boundary](#vite-host-boundary)
12
+ - [Plugin Authoring](#plugin-authoring)
13
+ - [BuildOptions Caveats](#buildoptions-caveats)
14
+ - [Dev / watch path](#dev--watch-path)
15
+ - [Metrics](#metrics)
16
+ - [Production build caches](#production-build-caches)
17
+ - [Unified pages graph](#unified-pages-graph)
18
+ - [JSX Ownership Plugins](#jsx-ownership-plugins)
19
+ - [Rolldown operator notes](#rolldown-operator-notes)
20
+ - [Testing Strategy](#testing-strategy)
21
+
5
22
  ## Mental Model
6
23
 
7
24
  Three concentric shapes, plus profile executors and request policy:
@@ -122,7 +139,7 @@ App-manifest plugins keep canonical registration order and cannot be silently re
122
139
 
123
140
  `BuildOptions` is modeled on the bundler's options shape. Most fields map cleanly. The exceptions:
124
141
 
125
- - `splitting` — accepted but currently ignored. The bundler splits by default. The per-chunk naming is fixed to `[name]-[hash]`. If you need to disable splitting or rename chunks, the adapter will need a new option.
142
+ - `splitting` — when `false` with a single entrypoint, maps to Rolldown `codeSplitting: false` so dynamic imports stay in one file. Multi-entrypoint builds ignore `splitting: false` because Rolldown cannot inline across multiple inputs.
126
143
  - `bundle` — accepted but ignored. The bundler always bundles.
127
144
  - `outbase` — accepted but ignored. The adapter derives the base from `options.root` directly.
128
145
 
@@ -188,6 +205,40 @@ Mixed-integration apps need explicit `@jsxImportSource` handling in two differen
188
205
 
189
206
  `foreign-jsx-override-plugin.ts` is the shared implementation. Prefer the helpers above instead of calling it directly from integrations.
190
207
 
208
+ ## Rolldown operator notes
209
+
210
+ Ecopages bundles with Rolldown across Node, Bun, and browser targets. Vite-hosted apps use `ViteHostBuildAdapter` as a boundary marker; the host runs its own pipeline.
211
+
212
+ ### Plugin hook filters
213
+
214
+ Rolldown evaluates plugin hooks on the Rust side and only calls JavaScript when the filter matches. Hooks without filters run for every module through Rust→JS FFI, causing **3–4× slowdown** with multiple plugins.
215
+
216
+ ```typescript
217
+ // BAD — called for every module
218
+ resolveId(source, importer) { /* ... */ }
219
+
220
+ // GOOD — skipped unless the filter matches
221
+ resolveId: {
222
+ filter: { id: /\.tsx?$/ },
223
+ handler(source, importer) { /* ... */ },
224
+ }
225
+ ```
226
+
227
+ If patterns are dynamic (populated during `buildStart`), Rolldown cannot use filters because they are read at registration time. Consolidate dynamic plugins into a **single** Rolldown plugin to minimize FFI calls. See [rolldown.rs/reference/plugin-hooks](https://rolldown.rs/reference/plugin-hooks).
228
+
229
+ ### Consolidate plugins
230
+
231
+ Each Rolldown plugin adds FFI overhead per module per hook. Ecopages merges all `EcoBuildPlugin` instances into one Rolldown plugin in `rolldown-plugin-bridge.ts` with JavaScript-side routing.
232
+
233
+ ### Benchmarks
234
+
235
+ Kitchen-sink benchmarks (`ECOPAGES_BENCH=1 pnpm vitest bench`) show Rolldown winning 15/18 scenarios versus esbuild, with a **1.21×** geometric mean speedup. Largest wins: React page rebuilds (1.56×), production single page (1.49×), Lit (1.52×), Ecopages-JSX (1.47×). Three scenarios regressed (KitaJS postcss, dynamic route, no-op rebuild); route-module disk cache and fingerprinted production caches reduce repeated work on warm paths.
236
+
237
+ ### Native MagicString and CSS shim
238
+
239
+ - `experimental.nativeMagicString: true` enables Rust-native string manipulation for faster transforms.
240
+ - Server-side builds use `createServerSideCssShimPlugin()` to turn `.css` imports into empty ESM modules. Skipped for browser builds.
241
+
191
242
  ## Testing Strategy
192
243
 
193
244
  - `rolldown/rolldown-build-adapter.test.ts` covers the adapter's `build`, `resolve`, `getTranspileOptions`, and dependency-graph extraction end-to-end.
@@ -1,124 +1,145 @@
1
- import { mergeBrowserRuntimeManifests } from "./browser/browser-runtime-manifest.js";
2
- import { appLogger } from "../global/app-logger.js";
3
- import { startupTrace } from "../diagnostics/startup-trace.js";
4
- import { isLitStaticRenderWorkerThread } from "./browser/lit-static-render-worker-context.js";
1
+ import { mergeBrowserRuntimeManifests } from './browser/browser-runtime-manifest.js';
2
+ import { appLogger } from '../global/app-logger.js';
3
+ import { startupTrace } from '../diagnostics/startup-trace.js';
4
+ import { isLitStaticRenderWorkerThread } from './browser/lit-static-render-worker-context.js';
5
5
  function patchAppRuntime(appConfig, patch) {
6
- appConfig.runtime = {
7
- ...appConfig.runtime ?? {},
8
- ...patch
9
- };
6
+ appConfig.runtime = {
7
+ ...(appConfig.runtime ?? {}),
8
+ ...patch,
9
+ };
10
10
  }
11
11
  function registerRuntimePlugins(appConfig, onRuntimePlugin) {
12
- for (const loader of appConfig.loaders.values()) {
13
- onRuntimePlugin?.(loader);
14
- }
15
- for (const processor of appConfig.processors.values()) {
16
- if (processor.plugins) {
17
- for (const plugin of processor.plugins) {
18
- onRuntimePlugin?.(plugin);
19
- }
12
+ for (const loader of appConfig.loaders.values()) {
13
+ onRuntimePlugin?.(loader);
20
14
  }
21
- }
22
- for (const integration of appConfig.integrations) {
23
- for (const plugin of integration.plugins) {
24
- onRuntimePlugin?.(plugin);
15
+ for (const processor of appConfig.processors.values()) {
16
+ if (processor.plugins) {
17
+ for (const plugin of processor.plugins) {
18
+ onRuntimePlugin?.(plugin);
19
+ }
20
+ }
21
+ }
22
+ for (const integration of appConfig.integrations) {
23
+ for (const plugin of integration.plugins) {
24
+ onRuntimePlugin?.(plugin);
25
+ }
25
26
  }
26
- }
27
27
  }
28
- async function collectConfiguredAppBuildManifestContributions(appConfig) {
29
- const runtimePlugins = [];
30
- const browserBundlePlugins = [];
31
- const browserRuntimeManifests = [];
32
- for (const processor of appConfig.processors.values()) {
33
- await processor.prepareBuildContributions();
34
- if (processor.plugins) {
35
- runtimePlugins.push(...processor.plugins);
28
+ /**
29
+ * Collects integration and processor contributions before the app build manifest is sealed.
30
+ *
31
+ * @remarks
32
+ * Called from {@link ConfigBuilder.build} via {@link updateAppBuildManifest}. Walks
33
+ * processors first, then integrations, invoking {@link Processor.prepareBuildContributions}
34
+ * and {@link IntegrationPlugin.prepareBuildContributions} so dynamic plugin lists can be
35
+ * materialized before sealing.
36
+ *
37
+ * Maps contributor getters to manifest buckets:
38
+ * - `processor.plugins` / `integration.plugins` → `runtimePlugins`
39
+ * - `processor.buildPlugins` / `integration.browserBuildPlugins` → `browserBundlePlugins`
40
+ * - `integration.browserRuntimeManifest` → merged `browserRuntimeManifest`
41
+ *
42
+ * Loaders are not collected here; {@link createConfiguredAppBuildManifest} always takes
43
+ * them from `appConfig.loaders`.
44
+ */
45
+ export async function collectConfiguredAppBuildManifestContributions(appConfig) {
46
+ const runtimePlugins = [];
47
+ const browserBundlePlugins = [];
48
+ const browserRuntimeManifests = [];
49
+ for (const processor of appConfig.processors.values()) {
50
+ await processor.prepareBuildContributions();
51
+ if (processor.plugins) {
52
+ runtimePlugins.push(...processor.plugins);
53
+ }
54
+ if (processor.buildPlugins) {
55
+ browserBundlePlugins.push(...processor.buildPlugins);
56
+ }
36
57
  }
37
- if (processor.buildPlugins) {
38
- browserBundlePlugins.push(...processor.buildPlugins);
58
+ for (const integration of appConfig.integrations) {
59
+ integration.setConfig(appConfig);
60
+ await integration.prepareBuildContributions();
61
+ runtimePlugins.push(...(integration.plugins ?? []));
62
+ browserBundlePlugins.push(...(integration.browserBuildPlugins ?? []));
63
+ browserRuntimeManifests.push(integration.browserRuntimeManifest);
39
64
  }
40
- }
41
- for (const integration of appConfig.integrations) {
42
- integration.setConfig(appConfig);
43
- await integration.prepareBuildContributions();
44
- runtimePlugins.push(...integration.plugins ?? []);
45
- browserBundlePlugins.push(...integration.browserBuildPlugins ?? []);
46
- browserRuntimeManifests.push(integration.browserRuntimeManifest);
47
- }
48
- return {
49
- runtimePlugins,
50
- browserBundlePlugins,
51
- browserRuntimeManifest: mergeBrowserRuntimeManifests(...browserRuntimeManifests)
52
- };
65
+ return {
66
+ runtimePlugins,
67
+ browserBundlePlugins,
68
+ browserRuntimeManifest: mergeBrowserRuntimeManifests(...browserRuntimeManifests),
69
+ };
53
70
  }
54
- async function setupAppRuntimePlugins(options) {
55
- startupTrace.markPhaseStart("setupAppRuntimePlugins");
56
- if (options.appConfig.runtime?.runtimeAssetsPrepared) {
57
- appLogger.debug("Skipped setupAppRuntimePlugins: runtime assets already prepared");
58
- registerRuntimePlugins(options.appConfig, options.onRuntimePlugin);
59
- startupTrace.markPhaseEnd("setupAppRuntimePlugins");
60
- return;
61
- }
62
- if (isLitStaticRenderWorkerThread()) {
63
- appLogger.debug("Lit static-render worker: skipping processor setup (main thread already prepared artifacts)");
64
- }
65
- appLogger.debugTime("setupAppRuntimePlugins");
66
- try {
67
- if (options.onRuntimePlugin) {
68
- patchAppRuntime(options.appConfig, { onRuntimePlugin: options.onRuntimePlugin });
71
+ export async function setupAppRuntimePlugins(options) {
72
+ startupTrace.markPhaseStart('setupAppRuntimePlugins');
73
+ if (options.appConfig.runtime?.runtimeAssetsPrepared) {
74
+ appLogger.debug('Skipped setupAppRuntimePlugins: runtime assets already prepared');
75
+ registerRuntimePlugins(options.appConfig, options.onRuntimePlugin);
76
+ startupTrace.markPhaseEnd('setupAppRuntimePlugins');
77
+ return;
69
78
  }
70
- for (const loader of options.appConfig.loaders.values()) {
71
- options.onRuntimePlugin?.(loader);
79
+ if (isLitStaticRenderWorkerThread()) {
80
+ appLogger.debug('Lit static-render worker: skipping processor setup (main thread already prepared artifacts)');
72
81
  }
73
- const skipProcessorSetup = isLitStaticRenderWorkerThread();
74
- for (const processor of options.appConfig.processors.values()) {
75
- if (!skipProcessorSetup) {
76
- await processor.setup();
77
- }
78
- if (processor.plugins) {
79
- for (const plugin of processor.plugins) {
80
- options.onRuntimePlugin?.(plugin);
82
+ appLogger.debugTime('setupAppRuntimePlugins');
83
+ try {
84
+ if (options.onRuntimePlugin) {
85
+ patchAppRuntime(options.appConfig, { onRuntimePlugin: options.onRuntimePlugin });
86
+ }
87
+ for (const loader of options.appConfig.loaders.values()) {
88
+ options.onRuntimePlugin?.(loader);
81
89
  }
82
- }
90
+ const skipProcessorSetup = isLitStaticRenderWorkerThread();
91
+ for (const processor of options.appConfig.processors.values()) {
92
+ if (!skipProcessorSetup) {
93
+ await processor.setup();
94
+ }
95
+ if (processor.plugins) {
96
+ for (const plugin of processor.plugins) {
97
+ options.onRuntimePlugin?.(plugin);
98
+ }
99
+ }
100
+ }
101
+ patchAppRuntime(options.appConfig, { runtimeAssetsPrepared: true });
102
+ }
103
+ finally {
104
+ appLogger.debugTimeEnd('setupAppRuntimePlugins');
105
+ startupTrace.markPhaseEnd('setupAppRuntimePlugins');
83
106
  }
84
- patchAppRuntime(options.appConfig, { runtimeAssetsPrepared: true });
85
- } finally {
86
- appLogger.debugTimeEnd("setupAppRuntimePlugins");
87
- startupTrace.markPhaseEnd("setupAppRuntimePlugins");
88
- }
89
107
  }
90
- async function ensureIntegrationRuntimeReady(options) {
91
- const runtime = options.appConfig.runtime ?? {};
92
- options.appConfig.runtime = runtime;
93
- runtime.integrationActivations ??= /* @__PURE__ */ new Map();
94
- const existing = runtime.integrationActivations.get(options.integrationName);
95
- if (existing) {
96
- await existing;
97
- return;
98
- }
99
- const integration = options.appConfig.integrations.find((plugin) => plugin.name === options.integrationName);
100
- if (!integration) {
101
- return;
102
- }
103
- const activation = (async () => {
104
- integration.setConfig(options.appConfig);
105
- integration.setRuntimeOrigin(options.runtimeOrigin);
106
- await integration.setup();
107
- const onRuntimePlugin = options.onRuntimePlugin ?? options.appConfig.runtime?.onRuntimePlugin;
108
- for (const plugin of integration.plugins ?? []) {
109
- onRuntimePlugin?.(plugin);
108
+ /**
109
+ * Activates one integration's runtime setup on first use.
110
+ *
111
+ * @remarks
112
+ * Concurrent callers share a single in-flight promise per integration name.
113
+ * Failed activations are evicted so a later caller can retry.
114
+ */
115
+ export async function ensureIntegrationRuntimeReady(options) {
116
+ const runtime = options.appConfig.runtime ?? {};
117
+ options.appConfig.runtime = runtime;
118
+ runtime.integrationActivations ??= new Map();
119
+ const existing = runtime.integrationActivations.get(options.integrationName);
120
+ if (existing) {
121
+ await existing;
122
+ return;
123
+ }
124
+ const integration = options.appConfig.integrations.find((plugin) => plugin.name === options.integrationName);
125
+ if (!integration) {
126
+ return;
127
+ }
128
+ const activation = (async () => {
129
+ integration.setConfig(options.appConfig);
130
+ integration.setRuntimeOrigin(options.runtimeOrigin);
131
+ await integration.setup();
132
+ const onRuntimePlugin = options.onRuntimePlugin ?? options.appConfig.runtime?.onRuntimePlugin;
133
+ for (const plugin of integration.plugins ?? []) {
134
+ onRuntimePlugin?.(plugin);
135
+ }
136
+ })();
137
+ runtime.integrationActivations.set(options.integrationName, activation);
138
+ try {
139
+ await activation;
140
+ }
141
+ catch (error) {
142
+ runtime.integrationActivations.delete(options.integrationName);
143
+ throw error;
110
144
  }
111
- })();
112
- runtime.integrationActivations.set(options.integrationName, activation);
113
- try {
114
- await activation;
115
- } catch (error) {
116
- runtime.integrationActivations.delete(options.integrationName);
117
- throw error;
118
- }
119
145
  }
120
- export {
121
- collectConfiguredAppBuildManifestContributions,
122
- ensureIntegrationRuntimeReady,
123
- setupAppRuntimePlugins
124
- };
@@ -1,61 +1,58 @@
1
- class BrowserRuntimeManifestConflictError extends Error {
2
- specifier;
3
- existing;
4
- incoming;
5
- constructor(specifier, existing, incoming) {
6
- super(
7
- `Browser runtime asset conflict for ${specifier}: ${existing.owner} maps to ${existing.publicPath}, ${incoming.owner} maps to ${incoming.publicPath}`
8
- );
9
- this.name = "BrowserRuntimeManifestConflictError";
10
- this.specifier = specifier;
11
- this.existing = existing;
12
- this.incoming = incoming;
13
- }
1
+ export class BrowserRuntimeManifestConflictError extends Error {
2
+ specifier;
3
+ existing;
4
+ incoming;
5
+ constructor(specifier, existing, incoming) {
6
+ super(`Browser runtime asset conflict for ${specifier}: ${existing.owner} maps to ${existing.publicPath}, ` +
7
+ `${incoming.owner} maps to ${incoming.publicPath}`);
8
+ this.name = 'BrowserRuntimeManifestConflictError';
9
+ this.specifier = specifier;
10
+ this.existing = existing;
11
+ this.incoming = incoming;
12
+ }
14
13
  }
15
14
  function normalizeDeclaration(declaration) {
16
- return {
17
- ...declaration,
18
- externals: declaration.externals ?? []
19
- };
15
+ return {
16
+ ...declaration,
17
+ externals: declaration.externals ?? [],
18
+ };
20
19
  }
21
20
  function hasCompatibleRuntimeAsset(existing, incoming) {
22
- return existing.owner === incoming.owner && existing.importPath === incoming.importPath && existing.publicPath === incoming.publicPath && existing.mode === incoming.mode && arrayEquals(existing.externals, incoming.externals);
21
+ return (existing.owner === incoming.owner &&
22
+ existing.importPath === incoming.importPath &&
23
+ existing.publicPath === incoming.publicPath &&
24
+ existing.mode === incoming.mode &&
25
+ arrayEquals(existing.externals, incoming.externals));
23
26
  }
24
27
  function arrayEquals(left, right) {
25
- if (left.length !== right.length) {
26
- return false;
27
- }
28
- return left.every((value, index) => value === right[index]);
28
+ if (left.length !== right.length) {
29
+ return false;
30
+ }
31
+ return left.every((value, index) => value === right[index]);
29
32
  }
30
- function createBrowserRuntimeManifest(declarations = []) {
31
- const assets = [];
32
- const bySpecifier = /* @__PURE__ */ new Map();
33
- for (const declaration of declarations) {
34
- const asset = normalizeDeclaration(declaration);
35
- const existing = bySpecifier.get(asset.specifier);
36
- if (existing) {
37
- if (!hasCompatibleRuntimeAsset(existing, asset)) {
38
- throw new BrowserRuntimeManifestConflictError(asset.specifier, existing, asset);
39
- }
40
- continue;
33
+ export function createBrowserRuntimeManifest(declarations = []) {
34
+ const assets = [];
35
+ const bySpecifier = new Map();
36
+ for (const declaration of declarations) {
37
+ const asset = normalizeDeclaration(declaration);
38
+ const existing = bySpecifier.get(asset.specifier);
39
+ if (existing) {
40
+ if (!hasCompatibleRuntimeAsset(existing, asset)) {
41
+ throw new BrowserRuntimeManifestConflictError(asset.specifier, existing, asset);
42
+ }
43
+ continue;
44
+ }
45
+ assets.push(asset);
46
+ bySpecifier.set(asset.specifier, asset);
41
47
  }
42
- assets.push(asset);
43
- bySpecifier.set(asset.specifier, asset);
44
- }
45
- return {
46
- assets,
47
- bySpecifier
48
- };
48
+ return {
49
+ assets,
50
+ bySpecifier,
51
+ };
49
52
  }
50
- function mergeBrowserRuntimeManifests(...manifests) {
51
- return createBrowserRuntimeManifest(manifests.flatMap((manifest) => manifest?.assets ?? []));
53
+ export function mergeBrowserRuntimeManifests(...manifests) {
54
+ return createBrowserRuntimeManifest(manifests.flatMap((manifest) => manifest?.assets ?? []));
52
55
  }
53
- function getBrowserRuntimeSpecifierMap(manifest) {
54
- return new Map(manifest.assets.map((asset) => [asset.specifier, asset.publicPath]));
56
+ export function getBrowserRuntimeSpecifierMap(manifest) {
57
+ return new Map(manifest.assets.map((asset) => [asset.specifier, asset.publicPath]));
55
58
  }
56
- export {
57
- BrowserRuntimeManifestConflictError,
58
- createBrowserRuntimeManifest,
59
- getBrowserRuntimeSpecifierMap,
60
- mergeBrowserRuntimeManifests
61
- };
@@ -1,14 +1,34 @@
1
- function escapeRegExp(value) {
2
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1
+ /**
2
+ * Shared helpers for the browser-runtime plugin.
3
+ *
4
+ * @remarks
5
+ * `createBrowserRuntimePlugin` needs to:
6
+ *
7
+ * 1. Escape each specifier for inclusion in a regex filter.
8
+ * 2. Build a `RegExp` whose alternation matches any of those specifiers.
9
+ *
10
+ * These utilities are extracted here so the plugin does not duplicate
11
+ * the same code path.
12
+ */
13
+ /**
14
+ * Escapes a literal specifier for inclusion in a regular expression.
15
+ *
16
+ * Only the regex metacharacters are escaped: `. * + ? ^ $ { } ( ) | [ ] \`
17
+ */
18
+ export function escapeRegExp(value) {
19
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
3
20
  }
4
- function buildSpecifierFilter(specifierMap) {
5
- if (specifierMap.size === 0) {
6
- return null;
7
- }
8
- const alternation = Array.from(specifierMap.keys()).map(escapeRegExp).join("|");
9
- return new RegExp(`^(${alternation})$`);
21
+ /**
22
+ * Builds a `RegExp` whose alternation matches any of the keys in
23
+ * `specifierMap`.
24
+ *
25
+ * Returns `null` for an empty map so callers can short-circuit and
26
+ * avoid registering a no-op `onResolve` / `onLoad` filter.
27
+ */
28
+ export function buildSpecifierFilter(specifierMap) {
29
+ if (specifierMap.size === 0) {
30
+ return null;
31
+ }
32
+ const alternation = Array.from(specifierMap.keys()).map(escapeRegExp).join('|');
33
+ return new RegExp(`^(${alternation})$`);
10
34
  }
11
- export {
12
- buildSpecifierFilter,
13
- escapeRegExp
14
- };