@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,118 +1,159 @@
1
- import { Readable } from "node:stream";
2
- import { pipeline } from "node:stream/promises";
3
- class NodeClientAbortError extends Error {
4
- /**
5
- * Creates the canonical Node transport abort error used across request-body
6
- * reads and response-body writes.
7
- */
8
- constructor() {
9
- super("Client closed the request");
10
- this.name = "ClientAbortError";
11
- }
1
+ import { Readable } from 'node:stream';
2
+ import { pipeline } from 'node:stream/promises';
3
+ /**
4
+ * Signals that the remote client closed the HTTP exchange before the Node
5
+ * adapter finished reading or writing the body.
6
+ *
7
+ * @remarks
8
+ * This error represents a transport-level disconnect, not an application
9
+ * failure. Higher layers may safely suppress logging for this error when the
10
+ * client socket is already gone and no meaningful response can still be sent.
11
+ */
12
+ export class NodeClientAbortError extends Error {
13
+ /**
14
+ * Creates the canonical Node transport abort error used across request-body
15
+ * reads and response-body writes.
16
+ */
17
+ constructor() {
18
+ super('Client closed the request');
19
+ this.name = 'ClientAbortError';
20
+ }
12
21
  }
22
+ /**
23
+ * Returns whether a Node stream error code corresponds to a normal client-side
24
+ * disconnect rather than a server fault.
25
+ *
26
+ * @remarks
27
+ * The allowlist is intentionally narrow. Only socket and stream shutdown codes
28
+ * that are expected after browser aborts or navigation churn are treated as
29
+ * suppressible client disconnects.
30
+ */
13
31
  function isNodeClientDisconnectCode(code) {
14
- return [
15
- "ECONNRESET",
16
- "EPIPE",
17
- "ERR_STREAM_DESTROYED",
18
- "ERR_STREAM_PREMATURE_CLOSE",
19
- "ERR_STREAM_UNABLE_TO_PIPE"
20
- ].includes(code ?? "");
32
+ return [
33
+ 'ECONNRESET',
34
+ 'EPIPE',
35
+ 'ERR_STREAM_DESTROYED',
36
+ 'ERR_STREAM_PREMATURE_CLOSE',
37
+ 'ERR_STREAM_UNABLE_TO_PIPE',
38
+ ].includes(code ?? '');
21
39
  }
22
- function isNodeClientAbortError(error) {
23
- return error instanceof NodeClientAbortError;
40
+ /**
41
+ * Type guard for the canonical client-abort error used by the Node adapter.
42
+ *
43
+ * @remarks
44
+ * Runtime hosts use this guard before logging so only explicitly classified
45
+ * client disconnects are muted. All other failures continue through the normal
46
+ * error-reporting path.
47
+ */
48
+ export function isNodeClientAbortError(error) {
49
+ return error instanceof NodeClientAbortError;
24
50
  }
51
+ /**
52
+ * Normalizes low-level Node socket and stream shutdown errors into the shared
53
+ * `NodeClientAbortError` abstraction used by the adapter stack.
54
+ *
55
+ * @remarks
56
+ * This normalization exists at the transport boundary because Node exposes
57
+ * several host-specific error codes for the same underlying event: the client
58
+ * disappeared before the response stream finished. Converting them here keeps
59
+ * the rest of the adapter stack independent from those Node-specific details.
60
+ */
25
61
  function toNodeClientAbortError(error) {
26
- if (error instanceof NodeClientAbortError) {
27
- return error;
28
- }
29
- if (typeof error === "object" && error !== null && "code" in error) {
30
- const code = typeof error.code === "string" ? error.code : void 0;
31
- if (isNodeClientDisconnectCode(code)) {
32
- return new NodeClientAbortError();
62
+ if (error instanceof NodeClientAbortError) {
63
+ return error;
33
64
  }
34
- }
35
- return null;
36
- }
37
- class NodeHttpRequestBridge {
38
- /**
39
- * Converts one incoming Node request into the Web `Request` shape consumed by
40
- * the shared server adapter.
41
- *
42
- * @remarks
43
- * Non-GET/HEAD requests retain streaming semantics via a `ReadableStream` so
44
- * large request bodies do not need to be buffered before route handling begins.
45
- */
46
- createWebRequest(req, runtimeOrigin) {
47
- const url = new URL(req.url ?? "/", runtimeOrigin);
48
- const headers = new Headers();
49
- for (const [key, value] of Object.entries(req.headers)) {
50
- if (Array.isArray(value)) {
51
- for (const item of value) {
52
- headers.append(key, item);
65
+ if (typeof error === 'object' && error !== null && 'code' in error) {
66
+ const code = typeof error.code === 'string' ? error.code : undefined;
67
+ if (isNodeClientDisconnectCode(code)) {
68
+ return new NodeClientAbortError();
53
69
  }
54
- continue;
55
- }
56
- if (value !== void 0) {
57
- headers.set(key, value);
58
- }
59
70
  }
60
- const method = (req.method ?? "GET").toUpperCase();
61
- const requestInit = {
62
- method,
63
- headers
64
- };
65
- if (method !== "GET" && method !== "HEAD") {
66
- const body = new ReadableStream({
67
- start(controller) {
68
- req.on("data", (chunk) => controller.enqueue(chunk));
69
- req.once("end", () => controller.close());
70
- req.once("aborted", () => {
71
- controller.error(new NodeClientAbortError());
72
- });
73
- req.once("error", (err) => {
74
- const isClientAbort = err.code === "ECONNRESET";
75
- controller.error(isClientAbort ? new NodeClientAbortError() : err);
76
- });
77
- },
78
- cancel() {
79
- req.destroy();
71
+ return null;
72
+ }
73
+ /**
74
+ * Bridges Node's `IncomingMessage` / `ServerResponse` pair to the Web
75
+ * `Request` / `Response` contract used by the shared routing pipeline.
76
+ *
77
+ * @remarks
78
+ * This class is the Node transport boundary. It owns the translation of request
79
+ * headers and bodies into Web primitives and the reverse translation of Web
80
+ * responses back onto Node streams, including client-abort normalization.
81
+ */
82
+ export class NodeHttpRequestBridge {
83
+ /**
84
+ * Converts one incoming Node request into the Web `Request` shape consumed by
85
+ * the shared server adapter.
86
+ *
87
+ * @remarks
88
+ * Non-GET/HEAD requests retain streaming semantics via a `ReadableStream` so
89
+ * large request bodies do not need to be buffered before route handling begins.
90
+ */
91
+ createWebRequest(req, runtimeOrigin) {
92
+ const url = new URL(req.url ?? '/', runtimeOrigin);
93
+ const headers = new Headers();
94
+ for (const [key, value] of Object.entries(req.headers)) {
95
+ if (Array.isArray(value)) {
96
+ for (const item of value) {
97
+ headers.append(key, item);
98
+ }
99
+ continue;
100
+ }
101
+ if (value !== undefined) {
102
+ headers.set(key, value);
103
+ }
80
104
  }
81
- });
82
- requestInit.body = body;
83
- requestInit.duplex = "half";
84
- }
85
- return new Request(url, requestInit);
86
- }
87
- /**
88
- * Sends a Web `Response` through Node's `ServerResponse` without buffering the
89
- * full body in memory first.
90
- *
91
- * @remarks
92
- * Streaming responses matter for large payloads and long-lived transports such
93
- * as server-sent events. The bridge therefore forwards the `ReadableStream`
94
- * directly into the Node writable response instead of materializing an
95
- * intermediate `ArrayBuffer`.
96
- */
97
- async sendNodeResponse(res, response) {
98
- res.statusCode = response.status;
99
- response.headers.forEach((value, key) => {
100
- res.setHeader(key, value);
101
- });
102
- if (!response.body) {
103
- res.end();
104
- return;
105
+ const method = (req.method ?? 'GET').toUpperCase();
106
+ const requestInit = {
107
+ method,
108
+ headers,
109
+ };
110
+ if (method !== 'GET' && method !== 'HEAD') {
111
+ const body = new ReadableStream({
112
+ start(controller) {
113
+ req.on('data', (chunk) => controller.enqueue(chunk));
114
+ req.once('end', () => controller.close());
115
+ req.once('aborted', () => {
116
+ controller.error(new NodeClientAbortError());
117
+ });
118
+ req.once('error', (err) => {
119
+ const isClientAbort = err.code === 'ECONNRESET';
120
+ controller.error(isClientAbort ? new NodeClientAbortError() : err);
121
+ });
122
+ },
123
+ cancel() {
124
+ req.destroy();
125
+ },
126
+ });
127
+ requestInit.body = body;
128
+ requestInit.duplex = 'half';
129
+ }
130
+ return new Request(url, requestInit);
105
131
  }
106
- const responseBody = response.body;
107
- try {
108
- await pipeline(Readable.fromWeb(responseBody), res);
109
- } catch (error) {
110
- throw toNodeClientAbortError(error) ?? error;
132
+ /**
133
+ * Sends a Web `Response` through Node's `ServerResponse` without buffering the
134
+ * full body in memory first.
135
+ *
136
+ * @remarks
137
+ * Streaming responses matter for large payloads and long-lived transports such
138
+ * as server-sent events. The bridge therefore forwards the `ReadableStream`
139
+ * directly into the Node writable response instead of materializing an
140
+ * intermediate `ArrayBuffer`.
141
+ */
142
+ async sendNodeResponse(res, response) {
143
+ res.statusCode = response.status;
144
+ response.headers.forEach((value, key) => {
145
+ res.setHeader(key, value);
146
+ });
147
+ if (!response.body) {
148
+ res.end();
149
+ return;
150
+ }
151
+ const responseBody = response.body;
152
+ try {
153
+ await pipeline(Readable.fromWeb(responseBody), res);
154
+ }
155
+ catch (error) {
156
+ throw toNodeClientAbortError(error) ?? error;
157
+ }
111
158
  }
112
- }
113
159
  }
114
- export {
115
- NodeClientAbortError,
116
- NodeHttpRequestBridge,
117
- isNodeClientAbortError
118
- };
@@ -1,69 +1,67 @@
1
- const HEARTBEAT_INTERVAL_MS = 3e4;
2
- class NodeClientBridge {
3
- subscribers = /* @__PURE__ */ new Set();
4
- heartbeatTimer = null;
5
- constructor() {
6
- this.heartbeatTimer = setInterval(() => this.sweep(), HEARTBEAT_INTERVAL_MS);
7
- this.heartbeatTimer.unref?.();
8
- }
9
- /**
10
- * Pings all open subscribers and removes any that are no longer in OPEN state.
11
- * This prevents a slow memory leak caused by zombie connections that never
12
- * send a close event (e.g. abruptly killed browsers, orphaned tabs, network drops).
13
- */
14
- sweep() {
15
- for (const ws of this.subscribers) {
16
- if (ws.readyState !== 1) {
1
+ const HEARTBEAT_INTERVAL_MS = 30_000;
2
+ export class NodeClientBridge {
3
+ subscribers = new Set();
4
+ heartbeatTimer = null;
5
+ constructor() {
6
+ this.heartbeatTimer = setInterval(() => this.sweep(), HEARTBEAT_INTERVAL_MS);
7
+ /* Allow the process to exit even if the timer is still active */
8
+ this.heartbeatTimer.unref?.();
9
+ }
10
+ /**
11
+ * Pings all open subscribers and removes any that are no longer in OPEN state.
12
+ * This prevents a slow memory leak caused by zombie connections that never
13
+ * send a close event (e.g. abruptly killed browsers, orphaned tabs, network drops).
14
+ */
15
+ sweep() {
16
+ for (const ws of this.subscribers) {
17
+ if (ws.readyState !== 1 /* OPEN */) {
18
+ this.subscribers.delete(ws);
19
+ continue;
20
+ }
21
+ ws.ping();
22
+ }
23
+ }
24
+ subscribe(ws) {
25
+ this.subscribers.add(ws);
26
+ }
27
+ unsubscribe(ws) {
17
28
  this.subscribers.delete(ws);
18
- continue;
19
- }
20
- ws.ping();
21
29
  }
22
- }
23
- subscribe(ws) {
24
- this.subscribers.add(ws);
25
- }
26
- unsubscribe(ws) {
27
- this.subscribers.delete(ws);
28
- }
29
- broadcast(event) {
30
- const payload = JSON.stringify(event);
31
- for (const ws of this.subscribers) {
32
- if (ws.readyState === 1) {
33
- ws.send(payload);
34
- }
30
+ broadcast(event) {
31
+ const payload = JSON.stringify(event);
32
+ for (const ws of this.subscribers) {
33
+ if (ws.readyState === 1) {
34
+ ws.send(payload);
35
+ }
36
+ }
37
+ }
38
+ reload() {
39
+ this.broadcast({ type: 'reload' });
40
+ }
41
+ cssUpdate(path) {
42
+ this.broadcast({ type: 'css-update', path, timestamp: Date.now() });
43
+ }
44
+ update(path) {
45
+ this.broadcast({ type: 'update', path, timestamp: Date.now() });
46
+ }
47
+ error(message) {
48
+ this.broadcast({ type: 'error', message });
49
+ }
50
+ get subscriberCount() {
51
+ return this.subscribers.size;
52
+ }
53
+ /**
54
+ * Stops the heartbeat timer and clears all subscribers.
55
+ * Call this when the dev server is shutting down.
56
+ */
57
+ destroy() {
58
+ if (this.heartbeatTimer !== null) {
59
+ clearInterval(this.heartbeatTimer);
60
+ this.heartbeatTimer = null;
61
+ }
62
+ this.subscribers.clear();
35
63
  }
36
- }
37
- reload() {
38
- this.broadcast({ type: "reload" });
39
- }
40
- cssUpdate(path) {
41
- this.broadcast({ type: "css-update", path, timestamp: Date.now() });
42
- }
43
- update(path) {
44
- this.broadcast({ type: "update", path, timestamp: Date.now() });
45
- }
46
- error(message) {
47
- this.broadcast({ type: "error", message });
48
- }
49
- get subscriberCount() {
50
- return this.subscribers.size;
51
- }
52
- /**
53
- * Stops the heartbeat timer and clears all subscribers.
54
- * Call this when the dev server is shutting down.
55
- */
56
- destroy() {
57
- if (this.heartbeatTimer !== null) {
58
- clearInterval(this.heartbeatTimer);
59
- this.heartbeatTimer = null;
64
+ [Symbol.dispose]() {
65
+ this.destroy();
60
66
  }
61
- this.subscribers.clear();
62
- }
63
- [Symbol.dispose]() {
64
- this.destroy();
65
- }
66
67
  }
67
- export {
68
- NodeClientBridge
69
- };
@@ -1,49 +1,59 @@
1
- import { appLogger } from "../../global/app-logger.js";
2
- import {
3
- InMemoryEntrypointDependencyGraph
4
- } from "../../services/runtime-state/entrypoint-dependency-graph.service.js";
5
- import { SharedHmrManager } from "../shared/hmr/shared-hmr-manager.js";
6
- class NodeHmrManager extends SharedHmrManager {
7
- /**
8
- * Creates the Node HMR manager over the shared coordination pipeline.
9
- *
10
- * @remarks
11
- * Unlike Bun, Node keeps websocket subscription wiring in the server adapter,
12
- * so this manager only specializes the shared manager where runtime behavior
13
- * actually differs: dependency-graph storage, missing-file tolerance, and how
14
- * runtime bundle failures disable HMR.
15
- */
16
- constructor({ appConfig, bridge }) {
17
- super({ appConfig, bridge });
18
- }
19
- /**
20
- * Reuses the shared in-memory dependency graph when the app already has one and
21
- * otherwise creates the default Node development graph.
22
- */
23
- createEntrypointDependencyGraph(existingEntrypointDependencyGraph) {
24
- return existingEntrypointDependencyGraph instanceof InMemoryEntrypointDependencyGraph ? existingEntrypointDependencyGraph : new InMemoryEntrypointDependencyGraph();
25
- }
26
- /**
27
- * Tells the shared HMR manager to ignore missing-file events during Node watch
28
- * mode.
29
- *
30
- * @remarks
31
- * Node file watching can briefly report remove-and-recreate sequences while a
32
- * file is being rewritten. Treating those transient gaps as fatal would disable
33
- * otherwise healthy development sessions.
34
- */
35
- shouldSkipMissingFileChange(_filePath) {
36
- return true;
37
- }
38
- /**
39
- * Disables HMR after a runtime bundle failure so the Node dev server can keep
40
- * serving requests without repeatedly emitting broken updates.
41
- */
42
- onRuntimeBundleFailure(error) {
43
- this.enabled = false;
44
- appLogger.error("[HMR] Failed to build runtime script; continuing with HMR disabled.", error);
45
- }
1
+ import { appLogger } from '../../global/app-logger.js';
2
+ import { InMemoryEntrypointDependencyGraph, } from '../../services/runtime-state/entrypoint-dependency-graph.service.js';
3
+ import { SharedHmrManager } from '../shared/hmr/shared-hmr-manager.js';
4
+ /**
5
+ * Node development HMR manager.
6
+ *
7
+ * @remarks
8
+ * This manager owns three separate concerns:
9
+ * - runtime websocket event fanout
10
+ * - entrypoint registration and dedupe
11
+ * - strategy coordination for rebuilds and invalidation
12
+ *
13
+ * The strict page-entrypoint contract lives here: `registerEntrypoint()` is
14
+ * reserved for integration-owned page bundles, while generic script assets must
15
+ * go through `registerScriptEntrypoint()`.
16
+ */
17
+ export class NodeHmrManager extends SharedHmrManager {
18
+ /**
19
+ * Creates the Node HMR manager over the shared coordination pipeline.
20
+ *
21
+ * @remarks
22
+ * Unlike Bun, Node keeps websocket subscription wiring in the server adapter,
23
+ * so this manager only specializes the shared manager where runtime behavior
24
+ * actually differs: dependency-graph storage, missing-file tolerance, and how
25
+ * runtime bundle failures disable HMR.
26
+ */
27
+ constructor({ appConfig, bridge }) {
28
+ super({ appConfig, bridge });
29
+ }
30
+ /**
31
+ * Reuses the shared in-memory dependency graph when the app already has one and
32
+ * otherwise creates the default Node development graph.
33
+ */
34
+ createEntrypointDependencyGraph(existingEntrypointDependencyGraph) {
35
+ return existingEntrypointDependencyGraph instanceof InMemoryEntrypointDependencyGraph
36
+ ? existingEntrypointDependencyGraph
37
+ : new InMemoryEntrypointDependencyGraph();
38
+ }
39
+ /**
40
+ * Tells the shared HMR manager to ignore missing-file events during Node watch
41
+ * mode.
42
+ *
43
+ * @remarks
44
+ * Node file watching can briefly report remove-and-recreate sequences while a
45
+ * file is being rewritten. Treating those transient gaps as fatal would disable
46
+ * otherwise healthy development sessions.
47
+ */
48
+ shouldSkipMissingFileChange(_filePath) {
49
+ return true;
50
+ }
51
+ /**
52
+ * Disables HMR after a runtime bundle failure so the Node dev server can keep
53
+ * serving requests without repeatedly emitting broken updates.
54
+ */
55
+ onRuntimeBundleFailure(error) {
56
+ this.enabled = false;
57
+ appLogger.error('[HMR] Failed to build runtime script; continuing with HMR disabled.', error);
58
+ }
46
59
  }
47
- export {
48
- NodeHmrManager
49
- };