@ecopages/core 0.2.0-alpha.23 → 0.2.0-alpha.24

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 (515) hide show
  1. package/package.json +93 -226
  2. package/src/adapters/abstract/application-adapter.test.ts +172 -0
  3. package/src/adapters/abstract/application-adapter.ts +379 -0
  4. package/src/adapters/abstract/router-adapter.ts +30 -0
  5. package/src/adapters/abstract/server-adapter.ts +79 -0
  6. package/src/adapters/bun/client-bridge.ts +62 -0
  7. package/src/adapters/bun/create-app.ts +180 -0
  8. package/src/adapters/bun/hmr-manager.test.ts +267 -0
  9. package/src/adapters/bun/hmr-manager.ts +406 -0
  10. package/src/adapters/bun/index.ts +2 -0
  11. package/src/adapters/bun/server-adapter.ts +500 -0
  12. package/src/adapters/bun/server-lifecycle.ts +124 -0
  13. package/src/adapters/create-app.test.ts +10 -0
  14. package/src/adapters/create-app.ts +91 -0
  15. package/src/adapters/index.ts +2 -0
  16. package/src/adapters/node/create-app.test.ts +53 -0
  17. package/src/adapters/node/create-app.ts +183 -0
  18. package/src/adapters/node/node-client-bridge.test.ts +198 -0
  19. package/src/adapters/node/node-client-bridge.ts +79 -0
  20. package/src/adapters/node/node-hmr-manager.test.ts +322 -0
  21. package/src/adapters/node/node-hmr-manager.ts +378 -0
  22. package/src/adapters/node/server-adapter.ts +502 -0
  23. package/src/adapters/node/static-content-server.test.ts +60 -0
  24. package/src/adapters/node/static-content-server.ts +239 -0
  25. package/src/adapters/shared/api-response.test.ts +97 -0
  26. package/src/adapters/shared/api-response.ts +104 -0
  27. package/src/adapters/shared/application-adapter.ts +199 -0
  28. package/src/adapters/shared/define-api-handler.ts +66 -0
  29. package/src/adapters/shared/explicit-static-route-matcher.test.ts +381 -0
  30. package/src/adapters/shared/explicit-static-route-matcher.ts +140 -0
  31. package/src/adapters/shared/file-route-middleware-pipeline.test.ts +90 -0
  32. package/src/adapters/shared/file-route-middleware-pipeline.ts +127 -0
  33. package/src/adapters/shared/fs-server-response-factory.test.ts +187 -0
  34. package/src/adapters/shared/fs-server-response-factory.ts +118 -0
  35. package/src/adapters/shared/fs-server-response-matcher.test.ts +285 -0
  36. package/src/adapters/shared/fs-server-response-matcher.ts +189 -0
  37. package/src/adapters/shared/hmr-entrypoint-registrar.ts +149 -0
  38. package/src/adapters/shared/hmr-html-response.ts +52 -0
  39. package/src/adapters/shared/hmr-manager.contract.test.ts +232 -0
  40. package/src/adapters/shared/hmr-manager.dispatch.test.ts +220 -0
  41. package/src/adapters/shared/render-context.test.ts +150 -0
  42. package/src/adapters/shared/render-context.ts +123 -0
  43. package/src/adapters/shared/runtime-bootstrap.ts +79 -0
  44. package/src/adapters/shared/server-adapter.test.ts +77 -0
  45. package/src/adapters/shared/server-adapter.ts +493 -0
  46. package/src/adapters/shared/server-route-handler.test.ts +110 -0
  47. package/src/adapters/shared/server-route-handler.ts +153 -0
  48. package/src/adapters/shared/server-static-builder.test.ts +338 -0
  49. package/src/adapters/shared/server-static-builder.ts +170 -0
  50. package/src/build/build-adapter-serialization.test.ts +281 -0
  51. package/src/build/build-adapter.test.ts +1240 -0
  52. package/src/build/build-adapter.ts +1012 -0
  53. package/src/build/build-manifest.ts +54 -0
  54. package/src/build/build-types.ts +83 -0
  55. package/src/build/dev-build-coordinator.ts +220 -0
  56. package/src/build/esbuild-build-adapter.ts +660 -0
  57. package/src/build/runtime-build-executor.test.ts +81 -0
  58. package/src/build/runtime-build-executor.ts +40 -0
  59. package/src/build/runtime-specifier-alias-plugin.test.ts +67 -0
  60. package/src/build/runtime-specifier-alias-plugin.ts +62 -0
  61. package/src/build/runtime-specifier-aliases.ts +135 -0
  62. package/src/config/config-builder.test.ts +443 -0
  63. package/src/config/config-builder.ts +742 -0
  64. package/src/config/config-builder.typecheck.test.ts +96 -0
  65. package/src/config/{constants.d.ts → constants.ts} +22 -13
  66. package/src/dev/sc-server.ts +143 -0
  67. package/src/eco/eco.browser.test.ts +43 -0
  68. package/src/eco/eco.browser.ts +118 -0
  69. package/src/eco/eco.test.ts +654 -0
  70. package/src/eco/eco.ts +205 -0
  71. package/src/eco/eco.types.ts +221 -0
  72. package/src/eco/eco.utils.test.ts +219 -0
  73. package/src/eco/eco.utils.ts +5 -0
  74. package/src/eco/global-injector-map.test.ts +42 -0
  75. package/src/eco/global-injector-map.ts +112 -0
  76. package/src/eco/lazy-injector-map.test.ts +66 -0
  77. package/src/eco/lazy-injector-map.ts +120 -0
  78. package/src/eco/module-dependencies.test.ts +30 -0
  79. package/src/eco/module-dependencies.ts +75 -0
  80. package/src/errors/http-error.test.ts +134 -0
  81. package/src/errors/http-error.ts +72 -0
  82. package/src/errors/{index.d.ts → index.ts} +2 -2
  83. package/src/errors/locals-access-error.ts +7 -0
  84. package/src/global/app-logger.ts +4 -0
  85. package/src/global/utils.test.ts +12 -0
  86. package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-HMR-Server-Integration-should-have-HMR-script-injected-in-page-1.png +0 -0
  87. package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-HMR-Server-Integration-should-load-fixture-app-page-1.png +0 -0
  88. package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-WebSocket-Connection-should-connect-to-correct-HMR-endpoint-1.png +0 -0
  89. package/src/hmr/client/hmr-runtime.ts +160 -0
  90. package/src/hmr/hmr-strategy.test.ts +124 -0
  91. package/src/hmr/hmr-strategy.ts +177 -0
  92. package/src/hmr/hmr.postcss.test.e2e.ts +41 -0
  93. package/src/hmr/hmr.test.e2e.ts +66 -0
  94. package/src/hmr/strategies/default-hmr-strategy.ts +60 -0
  95. package/src/hmr/strategies/js-hmr-strategy.test.ts +335 -0
  96. package/src/hmr/strategies/js-hmr-strategy.ts +320 -0
  97. package/src/index.browser.ts +3 -0
  98. package/src/index.ts +15 -0
  99. package/src/integrations/ghtml/ghtml-renderer.test.ts +253 -0
  100. package/src/integrations/ghtml/ghtml-renderer.ts +97 -0
  101. package/src/integrations/ghtml/ghtml.constants.ts +1 -0
  102. package/src/integrations/ghtml/ghtml.plugin.ts +28 -0
  103. package/src/plugins/alias-resolver-plugin.test.ts +41 -0
  104. package/src/plugins/alias-resolver-plugin.ts +63 -0
  105. package/src/plugins/eco-component-meta-plugin.test.ts +406 -0
  106. package/src/plugins/eco-component-meta-plugin.ts +495 -0
  107. package/src/plugins/foreign-jsx-override-plugin.test.ts +65 -0
  108. package/src/plugins/foreign-jsx-override-plugin.ts +67 -0
  109. package/src/plugins/integration-plugin.test.ts +156 -0
  110. package/src/plugins/integration-plugin.ts +311 -0
  111. package/src/plugins/processor.test.ts +148 -0
  112. package/src/plugins/processor.ts +240 -0
  113. package/src/plugins/{runtime-capability.d.ts → runtime-capability.ts} +8 -3
  114. package/src/plugins/source-transform.test.ts +82 -0
  115. package/src/plugins/source-transform.ts +123 -0
  116. package/src/route-renderer/orchestration/boundary-planning.service.ts +146 -0
  117. package/src/route-renderer/orchestration/component-render-context.ts +318 -0
  118. package/src/route-renderer/orchestration/integration-renderer.test.ts +2088 -0
  119. package/src/route-renderer/orchestration/integration-renderer.ts +1285 -0
  120. package/src/route-renderer/orchestration/page-packaging.service.test.ts +76 -0
  121. package/src/route-renderer/orchestration/page-packaging.service.ts +85 -0
  122. package/src/route-renderer/orchestration/processed-asset-dedupe.ts +25 -0
  123. package/src/route-renderer/orchestration/queued-boundary-runtime.service.test.ts +319 -0
  124. package/src/route-renderer/orchestration/queued-boundary-runtime.service.ts +289 -0
  125. package/src/route-renderer/orchestration/render-execution.service.test.ts +196 -0
  126. package/src/route-renderer/orchestration/render-execution.service.ts +182 -0
  127. package/src/route-renderer/orchestration/render-output.utils.ts +302 -0
  128. package/src/route-renderer/orchestration/render-preparation.service.test.ts +569 -0
  129. package/src/route-renderer/orchestration/render-preparation.service.ts +508 -0
  130. package/src/route-renderer/orchestration/route-shell-composer.service.ts +162 -0
  131. package/src/route-renderer/orchestration/template-serialization.test.ts +110 -0
  132. package/src/route-renderer/orchestration/template-serialization.ts +117 -0
  133. package/src/route-renderer/page-loading/component-dependency-collection.ts +196 -0
  134. package/src/route-renderer/page-loading/declared-asset-collection.ts +156 -0
  135. package/src/route-renderer/page-loading/dependency-resolver.test.ts +665 -0
  136. package/src/route-renderer/page-loading/dependency-resolver.ts +150 -0
  137. package/src/route-renderer/page-loading/ecopages-virtual-imports.ts +75 -0
  138. package/src/route-renderer/page-loading/lazy-entry-collection.ts +167 -0
  139. package/src/route-renderer/page-loading/lazy-trigger-planning.ts +74 -0
  140. package/src/route-renderer/page-loading/module-declaration-aggregation.ts +60 -0
  141. package/src/route-renderer/page-loading/module-declaration-scripts.ts +16 -0
  142. package/src/route-renderer/page-loading/page-dependency-bundling.ts +205 -0
  143. package/src/route-renderer/page-loading/page-module-loader.test.ts +183 -0
  144. package/src/route-renderer/page-loading/page-module-loader.ts +184 -0
  145. package/src/route-renderer/route-renderer.ts +136 -0
  146. package/src/router/client/link-intent.test.browser.ts +51 -0
  147. package/src/router/client/link-intent.ts +92 -0
  148. package/src/router/client/navigation-coordinator.test.ts +237 -0
  149. package/src/router/client/navigation-coordinator.ts +453 -0
  150. package/src/router/server/fs-router-scanner.test.ts +83 -0
  151. package/src/router/server/fs-router-scanner.ts +224 -0
  152. package/src/router/server/fs-router.test.ts +214 -0
  153. package/src/router/server/fs-router.ts +122 -0
  154. package/src/services/assets/asset-processing-service/asset-dependency-keys.ts +66 -0
  155. package/src/services/assets/asset-processing-service/asset-processing.service.test.ts +476 -0
  156. package/src/services/assets/asset-processing-service/asset-processing.service.ts +345 -0
  157. package/src/services/assets/asset-processing-service/asset.factory.test.ts +63 -0
  158. package/src/services/assets/asset-processing-service/asset.factory.ts +105 -0
  159. package/src/services/assets/asset-processing-service/assets.types.ts +125 -0
  160. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.test.ts +74 -0
  161. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.ts +96 -0
  162. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.test.ts +67 -0
  163. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.ts +78 -0
  164. package/src/services/assets/asset-processing-service/grouped-content-bundles.ts +104 -0
  165. package/src/services/assets/asset-processing-service/index.ts +5 -0
  166. package/src/services/assets/asset-processing-service/{processor.interface.d.ts → processor.interface.ts} +10 -5
  167. package/src/services/assets/asset-processing-service/processor.registry.ts +18 -0
  168. package/src/services/assets/asset-processing-service/processors/base/base-processor.test.ts +59 -0
  169. package/src/services/assets/asset-processing-service/processors/base/base-processor.ts +83 -0
  170. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.ts +174 -0
  171. package/src/services/assets/asset-processing-service/processors/index.ts +5 -0
  172. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.test.ts +192 -0
  173. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.ts +134 -0
  174. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.test.ts +326 -0
  175. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.ts +110 -0
  176. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.test.ts +227 -0
  177. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.ts +87 -0
  178. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.test.ts +261 -0
  179. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.ts +71 -0
  180. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.ts +81 -0
  181. package/src/services/assets/asset-processing-service/ungrouped-dependency-processing.ts +65 -0
  182. package/src/services/assets/browser-bundle.service.test.ts +66 -0
  183. package/src/services/assets/browser-bundle.service.ts +109 -0
  184. package/src/services/cache/cache.types.ts +126 -0
  185. package/src/services/cache/index.ts +18 -0
  186. package/src/services/cache/memory-cache-store.test.ts +225 -0
  187. package/src/services/cache/memory-cache-store.ts +130 -0
  188. package/src/services/cache/page-cache-service.test.ts +175 -0
  189. package/src/services/cache/page-cache-service.ts +202 -0
  190. package/src/services/cache/page-request-cache-coordinator.service.test.ts +79 -0
  191. package/src/services/cache/page-request-cache-coordinator.service.ts +131 -0
  192. package/src/services/html/html-rewriter-provider.service.test.ts +183 -0
  193. package/src/services/html/html-rewriter-provider.service.ts +104 -0
  194. package/src/services/html/html-transformer.service.test.ts +479 -0
  195. package/src/services/html/html-transformer.service.ts +275 -0
  196. package/src/services/invalidation/development-invalidation.service.test.ts +87 -0
  197. package/src/services/invalidation/development-invalidation.service.ts +262 -0
  198. package/src/services/module-loading/app-module-loader.service.ts +9 -0
  199. package/src/services/module-loading/app-server-module-transpiler.service.test.ts +130 -0
  200. package/src/services/module-loading/app-server-module-transpiler.service.ts +143 -0
  201. package/src/services/module-loading/host-module-loader-registry.ts +15 -0
  202. package/src/services/module-loading/{module-loading-types.d.ts → module-loading-types.ts} +1 -0
  203. package/src/services/module-loading/node-bootstrap-plugin.test.ts +335 -0
  204. package/src/services/module-loading/node-bootstrap-plugin.ts +297 -0
  205. package/src/services/module-loading/page-module-import.service.test.ts +504 -0
  206. package/src/services/module-loading/page-module-import.service.ts +252 -0
  207. package/src/services/module-loading/server-module-transpiler.service.test.ts +243 -0
  208. package/src/services/module-loading/server-module-transpiler.service.ts +104 -0
  209. package/src/services/module-loading/source-module-support.ts +19 -0
  210. package/src/services/runtime-state/dev-graph.service.ts +217 -0
  211. package/src/services/runtime-state/entrypoint-dependency-graph.service.ts +136 -0
  212. package/src/services/runtime-state/runtime-specifier-registry.service.ts +96 -0
  213. package/src/services/runtime-state/server-invalidation-state.service.ts +68 -0
  214. package/src/services/validation/schema-validation-service.test.ts +223 -0
  215. package/src/services/validation/schema-validation-service.ts +204 -0
  216. package/src/services/validation/{standard-schema.types.d.ts → standard-schema.types.ts} +20 -17
  217. package/src/static-site-generator/static-site-generator.test.ts +316 -0
  218. package/src/static-site-generator/static-site-generator.ts +462 -0
  219. package/src/types/internal-types.ts +242 -0
  220. package/src/types/public-types.ts +1443 -0
  221. package/src/utils/deep-merge.test.ts +114 -0
  222. package/src/utils/deep-merge.ts +47 -0
  223. package/src/utils/hash.ts +5 -0
  224. package/src/utils/html-escaping.ts +9 -0
  225. package/src/utils/invariant.test.ts +22 -0
  226. package/src/utils/invariant.ts +15 -0
  227. package/src/utils/locals-utils.ts +37 -0
  228. package/src/utils/parse-cli-args.test.ts +69 -0
  229. package/src/utils/parse-cli-args.ts +105 -0
  230. package/src/utils/path-utils.module.ts +14 -0
  231. package/src/utils/path-utils.test.ts +15 -0
  232. package/src/utils/resolve-work-dir.ts +45 -0
  233. package/src/utils/runtime.ts +44 -0
  234. package/src/utils/server-utils.module.ts +67 -0
  235. package/src/utils/server-utils.test.ts +38 -0
  236. package/src/watchers/project-watcher.integration.test.ts +337 -0
  237. package/src/watchers/project-watcher.test-helpers.ts +41 -0
  238. package/src/watchers/project-watcher.test.ts +768 -0
  239. package/src/watchers/project-watcher.ts +357 -0
  240. package/CHANGELOG.md +0 -51
  241. package/src/adapters/abstract/application-adapter.d.ts +0 -194
  242. package/src/adapters/abstract/application-adapter.js +0 -121
  243. package/src/adapters/abstract/router-adapter.d.ts +0 -26
  244. package/src/adapters/abstract/router-adapter.js +0 -5
  245. package/src/adapters/abstract/server-adapter.d.ts +0 -69
  246. package/src/adapters/abstract/server-adapter.js +0 -15
  247. package/src/adapters/bun/client-bridge.d.ts +0 -34
  248. package/src/adapters/bun/client-bridge.js +0 -48
  249. package/src/adapters/bun/create-app.d.ts +0 -52
  250. package/src/adapters/bun/create-app.js +0 -116
  251. package/src/adapters/bun/hmr-manager.d.ts +0 -143
  252. package/src/adapters/bun/hmr-manager.js +0 -333
  253. package/src/adapters/bun/index.d.ts +0 -2
  254. package/src/adapters/bun/index.js +0 -8
  255. package/src/adapters/bun/server-adapter.d.ts +0 -155
  256. package/src/adapters/bun/server-adapter.js +0 -374
  257. package/src/adapters/bun/server-lifecycle.d.ts +0 -63
  258. package/src/adapters/bun/server-lifecycle.js +0 -92
  259. package/src/adapters/create-app.d.ts +0 -20
  260. package/src/adapters/create-app.js +0 -66
  261. package/src/adapters/index.d.ts +0 -2
  262. package/src/adapters/index.js +0 -8
  263. package/src/adapters/node/create-app.d.ts +0 -18
  264. package/src/adapters/node/create-app.js +0 -149
  265. package/src/adapters/node/node-client-bridge.d.ts +0 -26
  266. package/src/adapters/node/node-client-bridge.js +0 -66
  267. package/src/adapters/node/node-hmr-manager.d.ts +0 -133
  268. package/src/adapters/node/node-hmr-manager.js +0 -311
  269. package/src/adapters/node/server-adapter.d.ts +0 -161
  270. package/src/adapters/node/server-adapter.js +0 -359
  271. package/src/adapters/node/static-content-server.d.ts +0 -60
  272. package/src/adapters/node/static-content-server.js +0 -194
  273. package/src/adapters/shared/api-response.d.ts +0 -52
  274. package/src/adapters/shared/api-response.js +0 -96
  275. package/src/adapters/shared/application-adapter.d.ts +0 -18
  276. package/src/adapters/shared/application-adapter.js +0 -90
  277. package/src/adapters/shared/define-api-handler.d.ts +0 -25
  278. package/src/adapters/shared/define-api-handler.js +0 -15
  279. package/src/adapters/shared/explicit-static-route-matcher.d.ts +0 -38
  280. package/src/adapters/shared/explicit-static-route-matcher.js +0 -103
  281. package/src/adapters/shared/file-route-middleware-pipeline.d.ts +0 -65
  282. package/src/adapters/shared/file-route-middleware-pipeline.js +0 -99
  283. package/src/adapters/shared/fs-server-response-factory.d.ts +0 -19
  284. package/src/adapters/shared/fs-server-response-factory.js +0 -97
  285. package/src/adapters/shared/fs-server-response-matcher.d.ts +0 -67
  286. package/src/adapters/shared/fs-server-response-matcher.js +0 -147
  287. package/src/adapters/shared/hmr-entrypoint-registrar.d.ts +0 -55
  288. package/src/adapters/shared/hmr-entrypoint-registrar.js +0 -87
  289. package/src/adapters/shared/hmr-html-response.d.ts +0 -22
  290. package/src/adapters/shared/hmr-html-response.js +0 -32
  291. package/src/adapters/shared/render-context.d.ts +0 -15
  292. package/src/adapters/shared/render-context.js +0 -72
  293. package/src/adapters/shared/runtime-bootstrap.d.ts +0 -38
  294. package/src/adapters/shared/runtime-bootstrap.js +0 -43
  295. package/src/adapters/shared/server-adapter.d.ts +0 -97
  296. package/src/adapters/shared/server-adapter.js +0 -390
  297. package/src/adapters/shared/server-route-handler.d.ts +0 -89
  298. package/src/adapters/shared/server-route-handler.js +0 -111
  299. package/src/adapters/shared/server-static-builder.d.ts +0 -70
  300. package/src/adapters/shared/server-static-builder.js +0 -100
  301. package/src/build/build-adapter.d.ts +0 -239
  302. package/src/build/build-adapter.js +0 -642
  303. package/src/build/build-manifest.d.ts +0 -27
  304. package/src/build/build-manifest.js +0 -30
  305. package/src/build/build-types.d.ts +0 -57
  306. package/src/build/build-types.js +0 -0
  307. package/src/build/dev-build-coordinator.d.ts +0 -72
  308. package/src/build/dev-build-coordinator.js +0 -154
  309. package/src/build/esbuild-build-adapter.d.ts +0 -78
  310. package/src/build/esbuild-build-adapter.js +0 -505
  311. package/src/build/runtime-build-executor.d.ts +0 -14
  312. package/src/build/runtime-build-executor.js +0 -22
  313. package/src/build/runtime-specifier-alias-plugin.d.ts +0 -15
  314. package/src/build/runtime-specifier-alias-plugin.js +0 -35
  315. package/src/build/runtime-specifier-aliases.d.ts +0 -5
  316. package/src/build/runtime-specifier-aliases.js +0 -95
  317. package/src/config/config-builder.d.ts +0 -252
  318. package/src/config/config-builder.js +0 -603
  319. package/src/config/constants.js +0 -25
  320. package/src/dev/sc-server.d.ts +0 -30
  321. package/src/dev/sc-server.js +0 -111
  322. package/src/eco/eco.browser.d.ts +0 -2
  323. package/src/eco/eco.browser.js +0 -83
  324. package/src/eco/eco.d.ts +0 -9
  325. package/src/eco/eco.js +0 -85
  326. package/src/eco/eco.types.d.ts +0 -178
  327. package/src/eco/eco.types.js +0 -0
  328. package/src/eco/eco.utils.d.ts +0 -1
  329. package/src/eco/eco.utils.js +0 -10
  330. package/src/eco/global-injector-map.d.ts +0 -16
  331. package/src/eco/global-injector-map.js +0 -80
  332. package/src/eco/lazy-injector-map.d.ts +0 -8
  333. package/src/eco/lazy-injector-map.js +0 -70
  334. package/src/eco/module-dependencies.d.ts +0 -18
  335. package/src/eco/module-dependencies.js +0 -49
  336. package/src/errors/http-error.d.ts +0 -31
  337. package/src/errors/http-error.js +0 -50
  338. package/src/errors/index.js +0 -4
  339. package/src/errors/locals-access-error.d.ts +0 -4
  340. package/src/errors/locals-access-error.js +0 -9
  341. package/src/global/app-logger.d.ts +0 -2
  342. package/src/global/app-logger.js +0 -6
  343. package/src/hmr/client/hmr-runtime.d.ts +0 -5
  344. package/src/hmr/client/hmr-runtime.js +0 -109
  345. package/src/hmr/hmr-strategy.d.ts +0 -162
  346. package/src/hmr/hmr-strategy.js +0 -44
  347. package/src/hmr/hmr.postcss.test.e2e.d.ts +0 -1
  348. package/src/hmr/hmr.postcss.test.e2e.js +0 -31
  349. package/src/hmr/hmr.test.e2e.d.ts +0 -1
  350. package/src/hmr/hmr.test.e2e.js +0 -43
  351. package/src/hmr/strategies/default-hmr-strategy.d.ts +0 -43
  352. package/src/hmr/strategies/default-hmr-strategy.js +0 -34
  353. package/src/hmr/strategies/js-hmr-strategy.d.ts +0 -139
  354. package/src/hmr/strategies/js-hmr-strategy.js +0 -178
  355. package/src/index.browser.d.ts +0 -3
  356. package/src/index.browser.js +0 -4
  357. package/src/index.d.ts +0 -6
  358. package/src/index.js +0 -21
  359. package/src/integrations/ghtml/ghtml-renderer.d.ts +0 -20
  360. package/src/integrations/ghtml/ghtml-renderer.js +0 -63
  361. package/src/integrations/ghtml/ghtml.constants.d.ts +0 -1
  362. package/src/integrations/ghtml/ghtml.constants.js +0 -4
  363. package/src/integrations/ghtml/ghtml.plugin.d.ts +0 -16
  364. package/src/integrations/ghtml/ghtml.plugin.js +0 -20
  365. package/src/plugins/alias-resolver-plugin.d.ts +0 -2
  366. package/src/plugins/alias-resolver-plugin.js +0 -53
  367. package/src/plugins/eco-component-meta-plugin.d.ts +0 -108
  368. package/src/plugins/eco-component-meta-plugin.js +0 -163
  369. package/src/plugins/foreign-jsx-override-plugin.d.ts +0 -31
  370. package/src/plugins/foreign-jsx-override-plugin.js +0 -35
  371. package/src/plugins/integration-plugin.d.ts +0 -219
  372. package/src/plugins/integration-plugin.js +0 -196
  373. package/src/plugins/processor.d.ts +0 -95
  374. package/src/plugins/processor.js +0 -136
  375. package/src/plugins/runtime-capability.js +0 -0
  376. package/src/plugins/source-transform.d.ts +0 -46
  377. package/src/plugins/source-transform.js +0 -71
  378. package/src/route-renderer/orchestration/boundary-planning.service.d.ts +0 -25
  379. package/src/route-renderer/orchestration/boundary-planning.service.js +0 -97
  380. package/src/route-renderer/orchestration/component-render-context.d.ts +0 -83
  381. package/src/route-renderer/orchestration/component-render-context.js +0 -147
  382. package/src/route-renderer/orchestration/integration-renderer.d.ts +0 -554
  383. package/src/route-renderer/orchestration/integration-renderer.js +0 -957
  384. package/src/route-renderer/orchestration/queued-boundary-runtime.service.d.ts +0 -89
  385. package/src/route-renderer/orchestration/queued-boundary-runtime.service.js +0 -155
  386. package/src/route-renderer/orchestration/render-execution.service.d.ts +0 -43
  387. package/src/route-renderer/orchestration/render-execution.service.js +0 -106
  388. package/src/route-renderer/orchestration/render-output.utils.d.ts +0 -46
  389. package/src/route-renderer/orchestration/render-output.utils.js +0 -65
  390. package/src/route-renderer/orchestration/render-preparation.service.d.ts +0 -120
  391. package/src/route-renderer/orchestration/render-preparation.service.js +0 -341
  392. package/src/route-renderer/orchestration/route-shell-composer.service.d.ts +0 -50
  393. package/src/route-renderer/orchestration/route-shell-composer.service.js +0 -81
  394. package/src/route-renderer/orchestration/template-serialization.d.ts +0 -38
  395. package/src/route-renderer/orchestration/template-serialization.js +0 -45
  396. package/src/route-renderer/page-loading/dependency-resolver.d.ts +0 -35
  397. package/src/route-renderer/page-loading/dependency-resolver.js +0 -444
  398. package/src/route-renderer/page-loading/page-module-loader.d.ts +0 -90
  399. package/src/route-renderer/page-loading/page-module-loader.js +0 -127
  400. package/src/route-renderer/route-renderer.d.ts +0 -67
  401. package/src/route-renderer/route-renderer.js +0 -103
  402. package/src/router/client/link-intent.js +0 -34
  403. package/src/router/client/link-intent.test.browser.d.ts +0 -1
  404. package/src/router/client/link-intent.test.browser.js +0 -43
  405. package/src/router/client/navigation-coordinator.d.ts +0 -149
  406. package/src/router/client/navigation-coordinator.js +0 -215
  407. package/src/router/server/fs-router-scanner.d.ts +0 -41
  408. package/src/router/server/fs-router-scanner.js +0 -161
  409. package/src/router/server/fs-router.d.ts +0 -26
  410. package/src/router/server/fs-router.js +0 -100
  411. package/src/services/assets/asset-processing-service/asset-processing.service.d.ts +0 -120
  412. package/src/services/assets/asset-processing-service/asset-processing.service.js +0 -331
  413. package/src/services/assets/asset-processing-service/asset.factory.d.ts +0 -17
  414. package/src/services/assets/asset-processing-service/asset.factory.js +0 -82
  415. package/src/services/assets/asset-processing-service/assets.types.d.ts +0 -89
  416. package/src/services/assets/asset-processing-service/assets.types.js +0 -0
  417. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.d.ts +0 -55
  418. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +0 -48
  419. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.d.ts +0 -20
  420. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.js +0 -41
  421. package/src/services/assets/asset-processing-service/index.d.ts +0 -5
  422. package/src/services/assets/asset-processing-service/index.js +0 -5
  423. package/src/services/assets/asset-processing-service/processor.interface.js +0 -6
  424. package/src/services/assets/asset-processing-service/processor.registry.d.ts +0 -8
  425. package/src/services/assets/asset-processing-service/processor.registry.js +0 -15
  426. package/src/services/assets/asset-processing-service/processors/base/base-processor.d.ts +0 -24
  427. package/src/services/assets/asset-processing-service/processors/base/base-processor.js +0 -64
  428. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.d.ts +0 -17
  429. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.js +0 -72
  430. package/src/services/assets/asset-processing-service/processors/index.d.ts +0 -5
  431. package/src/services/assets/asset-processing-service/processors/index.js +0 -5
  432. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.d.ts +0 -5
  433. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.js +0 -57
  434. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.d.ts +0 -9
  435. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +0 -88
  436. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.d.ts +0 -7
  437. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +0 -75
  438. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.d.ts +0 -5
  439. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +0 -25
  440. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.d.ts +0 -9
  441. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +0 -66
  442. package/src/services/assets/browser-bundle.service.d.ts +0 -32
  443. package/src/services/assets/browser-bundle.service.js +0 -33
  444. package/src/services/cache/cache.types.d.ts +0 -107
  445. package/src/services/cache/cache.types.js +0 -0
  446. package/src/services/cache/index.d.ts +0 -7
  447. package/src/services/cache/index.js +0 -7
  448. package/src/services/cache/memory-cache-store.d.ts +0 -42
  449. package/src/services/cache/memory-cache-store.js +0 -98
  450. package/src/services/cache/page-cache-service.d.ts +0 -70
  451. package/src/services/cache/page-cache-service.js +0 -152
  452. package/src/services/cache/page-request-cache-coordinator.service.d.ts +0 -75
  453. package/src/services/cache/page-request-cache-coordinator.service.js +0 -109
  454. package/src/services/html/html-rewriter-provider.service.d.ts +0 -37
  455. package/src/services/html/html-rewriter-provider.service.js +0 -68
  456. package/src/services/html/html-transformer.service.d.ts +0 -77
  457. package/src/services/html/html-transformer.service.js +0 -215
  458. package/src/services/invalidation/development-invalidation.service.d.ts +0 -74
  459. package/src/services/invalidation/development-invalidation.service.js +0 -190
  460. package/src/services/module-loading/app-module-loader.service.d.ts +0 -28
  461. package/src/services/module-loading/app-module-loader.service.js +0 -35
  462. package/src/services/module-loading/app-server-module-transpiler.service.d.ts +0 -24
  463. package/src/services/module-loading/app-server-module-transpiler.service.js +0 -109
  464. package/src/services/module-loading/host-module-loader-registry.d.ts +0 -4
  465. package/src/services/module-loading/host-module-loader-registry.js +0 -15
  466. package/src/services/module-loading/module-loading-types.js +0 -0
  467. package/src/services/module-loading/node-bootstrap-plugin.d.ts +0 -42
  468. package/src/services/module-loading/node-bootstrap-plugin.js +0 -204
  469. package/src/services/module-loading/page-module-import.service.d.ts +0 -76
  470. package/src/services/module-loading/page-module-import.service.js +0 -173
  471. package/src/services/module-loading/server-module-transpiler.service.d.ts +0 -72
  472. package/src/services/module-loading/server-module-transpiler.service.js +0 -64
  473. package/src/services/runtime-state/dev-graph.service.d.ts +0 -118
  474. package/src/services/runtime-state/dev-graph.service.js +0 -162
  475. package/src/services/runtime-state/entrypoint-dependency-graph.service.d.ts +0 -41
  476. package/src/services/runtime-state/entrypoint-dependency-graph.service.js +0 -85
  477. package/src/services/runtime-state/runtime-specifier-registry.service.d.ts +0 -69
  478. package/src/services/runtime-state/runtime-specifier-registry.service.js +0 -37
  479. package/src/services/runtime-state/server-invalidation-state.service.d.ts +0 -26
  480. package/src/services/runtime-state/server-invalidation-state.service.js +0 -35
  481. package/src/services/validation/schema-validation-service.d.ts +0 -122
  482. package/src/services/validation/schema-validation-service.js +0 -101
  483. package/src/services/validation/standard-schema.types.js +0 -0
  484. package/src/static-site-generator/static-site-generator.d.ts +0 -104
  485. package/src/static-site-generator/static-site-generator.js +0 -338
  486. package/src/types/internal-types.d.ts +0 -231
  487. package/src/types/internal-types.js +0 -0
  488. package/src/types/public-types.d.ts +0 -1219
  489. package/src/types/public-types.js +0 -0
  490. package/src/utils/deep-merge.d.ts +0 -14
  491. package/src/utils/deep-merge.js +0 -32
  492. package/src/utils/hash.d.ts +0 -1
  493. package/src/utils/hash.js +0 -7
  494. package/src/utils/html-escaping.d.ts +0 -7
  495. package/src/utils/html-escaping.js +0 -6
  496. package/src/utils/html.js +0 -4
  497. package/src/utils/invariant.d.ts +0 -5
  498. package/src/utils/invariant.js +0 -11
  499. package/src/utils/locals-utils.d.ts +0 -15
  500. package/src/utils/locals-utils.js +0 -24
  501. package/src/utils/parse-cli-args.d.ts +0 -27
  502. package/src/utils/parse-cli-args.js +0 -62
  503. package/src/utils/path-utils.module.d.ts +0 -5
  504. package/src/utils/path-utils.module.js +0 -14
  505. package/src/utils/resolve-work-dir.d.ts +0 -11
  506. package/src/utils/resolve-work-dir.js +0 -31
  507. package/src/utils/runtime.d.ts +0 -11
  508. package/src/utils/runtime.js +0 -40
  509. package/src/utils/server-utils.module.d.ts +0 -19
  510. package/src/utils/server-utils.module.js +0 -56
  511. package/src/watchers/project-watcher.d.ts +0 -136
  512. package/src/watchers/project-watcher.js +0 -275
  513. package/src/watchers/project-watcher.test-helpers.d.ts +0 -4
  514. package/src/watchers/project-watcher.test-helpers.js +0 -52
  515. /package/src/utils/{html.d.ts → html.ts} +0 -0
@@ -0,0 +1,335 @@
1
+ import { describe, expect, it, beforeAll, afterAll } from 'vitest';
2
+ import { JsHmrStrategy, type JsHmrContext } from './js-hmr-strategy';
3
+ import { HmrStrategyType } from '../hmr-strategy';
4
+ import { InMemoryDevGraphService, NoopDevGraphService } from '../../services/runtime-state/dev-graph.service.ts';
5
+ import fs from 'node:fs';
6
+ import path from 'node:path';
7
+ import os from 'node:os';
8
+
9
+ const TMP_DIR = path.join(os.tmpdir(), 'js-hmr-strategy-test');
10
+ const SRC_DIR = path.join(TMP_DIR, 'src');
11
+
12
+ function createMockContext(overrides: Partial<JsHmrContext> = {}): JsHmrContext {
13
+ return {
14
+ getWatchedFiles: () => new Map(),
15
+ getSpecifierMap: () => new Map(),
16
+ getEntrypointDependencyGraph: () => new NoopDevGraphService(),
17
+ getDistDir: () => TMP_DIR,
18
+ getPlugins: () => [],
19
+ getSrcDir: () => SRC_DIR,
20
+ getPagesDir: () => path.join(SRC_DIR, 'pages'),
21
+ getLayoutsDir: () => path.join(SRC_DIR, 'layouts'),
22
+ getTemplateExtensions: () => ['.tsx'],
23
+ getBrowserBundleService: () => ({
24
+ bundle: async () => ({ success: true, logs: [], outputs: [] }),
25
+ }),
26
+ ...overrides,
27
+ };
28
+ }
29
+
30
+ describe('JsHmrStrategy', () => {
31
+ beforeAll(() => {
32
+ fs.mkdirSync(SRC_DIR, { recursive: true });
33
+ });
34
+
35
+ afterAll(() => {
36
+ fs.rmSync(TMP_DIR, { recursive: true, force: true });
37
+ });
38
+
39
+ describe('type', () => {
40
+ it('has SCRIPT type', () => {
41
+ const context = createMockContext();
42
+ const strategy = new JsHmrStrategy(context);
43
+ expect(strategy.type).toBe(HmrStrategyType.SCRIPT);
44
+ });
45
+
46
+ it('has default priority of 25', () => {
47
+ const context = createMockContext();
48
+ const strategy = new JsHmrStrategy(context);
49
+ expect(strategy.priority).toBe(25);
50
+ });
51
+ });
52
+
53
+ describe('matches', () => {
54
+ it('returns false when no watched files are registered', () => {
55
+ const context = createMockContext({
56
+ getWatchedFiles: () => new Map(),
57
+ });
58
+ const strategy = new JsHmrStrategy(context);
59
+
60
+ expect(strategy.matches(path.join(SRC_DIR, 'app.ts'))).toBe(false);
61
+ });
62
+
63
+ it('returns false for unrelated .ts files when dependency graph support is available', () => {
64
+ const devGraphService = new InMemoryDevGraphService();
65
+ const context = createMockContext({
66
+ getWatchedFiles: () => new Map([[path.join(SRC_DIR, 'entry.ts'), '/output.js']]),
67
+ getEntrypointDependencyGraph: () => devGraphService,
68
+ });
69
+ const strategy = new JsHmrStrategy(context);
70
+
71
+ expect(strategy.matches(path.join(SRC_DIR, 'component.ts'))).toBe(false);
72
+ });
73
+
74
+ it('returns true for dependency-connected .tsx files in src directory', () => {
75
+ const changedFile = path.join(SRC_DIR, 'component.tsx');
76
+ const devGraphService = new InMemoryDevGraphService();
77
+ devGraphService.setEntrypointDependencies(path.join(SRC_DIR, 'entry.ts'), [changedFile]);
78
+ const context = createMockContext({
79
+ getWatchedFiles: () => new Map([[path.join(SRC_DIR, 'entry.ts'), '/output.js']]),
80
+ getEntrypointDependencyGraph: () => devGraphService,
81
+ });
82
+ const strategy = new JsHmrStrategy(context);
83
+
84
+ expect(strategy.matches(changedFile)).toBe(true);
85
+ });
86
+
87
+ it('returns true for registered entrypoints even without dependency graph hits', () => {
88
+ const entrypoint = path.join(SRC_DIR, 'entry.tsx');
89
+ const devGraphService = new InMemoryDevGraphService();
90
+ const context = createMockContext({
91
+ getWatchedFiles: () => new Map([[entrypoint, '/output.js']]),
92
+ getEntrypointDependencyGraph: () => devGraphService,
93
+ });
94
+ const strategy = new JsHmrStrategy(context);
95
+
96
+ expect(strategy.matches(entrypoint)).toBe(true);
97
+ });
98
+
99
+ it('returns true for .js files in src directory', () => {
100
+ const context = createMockContext({
101
+ getWatchedFiles: () => new Map([[path.join(SRC_DIR, 'entry.ts'), '/output.js']]),
102
+ });
103
+ const strategy = new JsHmrStrategy(context);
104
+
105
+ expect(strategy.matches(path.join(SRC_DIR, 'utils.js'))).toBe(true);
106
+ });
107
+
108
+ it('returns true for .jsx files in src directory', () => {
109
+ const context = createMockContext({
110
+ getWatchedFiles: () => new Map([[path.join(SRC_DIR, 'entry.ts'), '/output.js']]),
111
+ });
112
+ const strategy = new JsHmrStrategy(context);
113
+
114
+ expect(strategy.matches(path.join(SRC_DIR, 'component.jsx'))).toBe(true);
115
+ });
116
+
117
+ it('returns false for .css files', () => {
118
+ const context = createMockContext({
119
+ getWatchedFiles: () => new Map([[path.join(SRC_DIR, 'entry.ts'), '/output.js']]),
120
+ });
121
+ const strategy = new JsHmrStrategy(context);
122
+
123
+ expect(strategy.matches(path.join(SRC_DIR, 'styles.css'))).toBe(false);
124
+ });
125
+
126
+ it('returns false for files outside src directory', () => {
127
+ const context = createMockContext({
128
+ getWatchedFiles: () => new Map([[path.join(SRC_DIR, 'entry.ts'), '/output.js']]),
129
+ });
130
+ const strategy = new JsHmrStrategy(context);
131
+
132
+ expect(strategy.matches('/other/path/file.ts')).toBe(false);
133
+ });
134
+
135
+ it('returns false for integration-owned route template files', () => {
136
+ const pagesDir = path.join(SRC_DIR, 'pages');
137
+ const context = createMockContext({
138
+ getWatchedFiles: () => new Map([[path.join(SRC_DIR, 'entry.ts'), '/output.js']]),
139
+ getPagesDir: () => pagesDir,
140
+ getTemplateExtensions: () => ['.kita.tsx', '.react.tsx'],
141
+ });
142
+ const strategy = new JsHmrStrategy(context);
143
+
144
+ expect(strategy.matches(path.join(pagesDir, 'index.kita.tsx'))).toBe(false);
145
+ expect(strategy.matches(path.join(pagesDir, 'home.react.tsx'))).toBe(false);
146
+ });
147
+
148
+ it('returns false for non-extension matches', () => {
149
+ const context = createMockContext({
150
+ getWatchedFiles: () => new Map([[path.join(SRC_DIR, 'entry.ts'), '/output.js']]),
151
+ });
152
+ const strategy = new JsHmrStrategy(context);
153
+
154
+ expect(strategy.matches(path.join(SRC_DIR, 'data.json'))).toBe(false);
155
+ expect(strategy.matches(path.join(SRC_DIR, 'readme.md'))).toBe(false);
156
+ });
157
+ });
158
+
159
+ describe('process', () => {
160
+ it('returns none when no watched files are registered', async () => {
161
+ const context = createMockContext({
162
+ getWatchedFiles: () => new Map(),
163
+ });
164
+ const strategy = new JsHmrStrategy(context);
165
+
166
+ const action = await strategy.process(path.join(SRC_DIR, 'app.ts'));
167
+
168
+ expect(action.type).toBe('none');
169
+ });
170
+
171
+ it('rebuilds only dependency-connected entrypoints when graph hit exists', async () => {
172
+ const entryA = path.join(SRC_DIR, 'entry-a.ts');
173
+ const entryB = path.join(SRC_DIR, 'entry-b.ts');
174
+ const depA = path.join(SRC_DIR, 'shared-a.ts');
175
+ const setEntrypointDependenciesCalls: Array<{ entrypointPath: string; dependencies: string[] }> = [];
176
+ let batchedEntrypoints: string[] = [];
177
+ const devGraphService = new InMemoryDevGraphService();
178
+ devGraphService.setEntrypointDependencies(entryA, [depA]);
179
+ devGraphService.setEntrypointDependencies(entryB, [entryB]);
180
+
181
+ const context = createMockContext({
182
+ getWatchedFiles: () =>
183
+ new Map([
184
+ [entryA, '/_hmr/entry-a.js'],
185
+ [entryB, '/_hmr/entry-b.js'],
186
+ ]),
187
+ getEntrypointDependencyGraph: () => ({
188
+ supportsSelectiveInvalidation: () => devGraphService.supportsSelectiveInvalidation(),
189
+ getDependencyEntrypoints: (filePath: string) => devGraphService.getDependencyEntrypoints(filePath),
190
+ setEntrypointDependencies: (entrypointPath: string, dependencies: string[]) => {
191
+ setEntrypointDependenciesCalls.push({ entrypointPath, dependencies });
192
+ devGraphService.setEntrypointDependencies(entrypointPath, dependencies);
193
+ },
194
+ clearEntrypointDependencies: (entrypointPath: string) =>
195
+ devGraphService.clearEntrypointDependencies(entrypointPath),
196
+ reset: () => devGraphService.reset(),
197
+ }),
198
+ });
199
+
200
+ const strategy = new JsHmrStrategy(context) as unknown as {
201
+ process: (filePath: string) => Promise<{ type: string; events?: unknown[] }>;
202
+ [key: string]: unknown;
203
+ };
204
+
205
+ strategy.bundleEntrypoints = async (entrypoints: string[]) => {
206
+ batchedEntrypoints = entrypoints;
207
+ const dependencies = new Map<string, string[]>();
208
+ for (const ep of entrypoints) {
209
+ dependencies.set(path.resolve(ep), [ep, depA]);
210
+ }
211
+ return { success: true, dependencies };
212
+ };
213
+
214
+ strategy.processOutput = async () => {
215
+ return { success: true, requiresReload: false };
216
+ };
217
+
218
+ const action = await strategy.process(depA);
219
+
220
+ expect(batchedEntrypoints).toEqual([entryA]);
221
+ expect(setEntrypointDependenciesCalls).toEqual([{ entrypointPath: entryA, dependencies: [entryA, depA] }]);
222
+ expect(action).toEqual({
223
+ type: 'broadcast',
224
+ events: [
225
+ {
226
+ type: 'update',
227
+ path: '/_hmr/entry-a.js',
228
+ timestamp: expect.any(Number),
229
+ },
230
+ ],
231
+ });
232
+ });
233
+
234
+ it('falls back to rebuilding all watched entrypoints when graph has no hit', async () => {
235
+ const entryA = path.join(SRC_DIR, 'entry-a.ts');
236
+ const entryB = path.join(SRC_DIR, 'entry-b.ts');
237
+ const changedFile = path.join(SRC_DIR, 'new-shared.ts');
238
+ let batchedEntrypoints: string[] = [];
239
+
240
+ const context = createMockContext({
241
+ getWatchedFiles: () =>
242
+ new Map([
243
+ [entryA, '/_hmr/entry-a.js'],
244
+ [entryB, '/_hmr/entry-b.js'],
245
+ ]),
246
+ getEntrypointDependencyGraph: () => new NoopDevGraphService(),
247
+ });
248
+
249
+ const strategy = new JsHmrStrategy(context) as unknown as {
250
+ process: (filePath: string) => Promise<{ type: string; events?: unknown[] }>;
251
+ [key: string]: unknown;
252
+ };
253
+
254
+ strategy.bundleEntrypoints = async (entrypoints: string[]) => {
255
+ batchedEntrypoints = entrypoints;
256
+ const dependencies = new Map<string, string[]>();
257
+ for (const ep of entrypoints) {
258
+ dependencies.set(path.resolve(ep), [ep]);
259
+ }
260
+ return { success: true, dependencies };
261
+ };
262
+
263
+ strategy.processOutput = async () => {
264
+ return { success: true, requiresReload: false };
265
+ };
266
+
267
+ const action = await strategy.process(changedFile);
268
+
269
+ expect(batchedEntrypoints).toEqual([entryA, entryB]);
270
+ expect(action).toEqual({
271
+ type: 'broadcast',
272
+ events: [
273
+ {
274
+ type: 'update',
275
+ path: '/_hmr/entry-a.js',
276
+ timestamp: expect.any(Number),
277
+ },
278
+ {
279
+ type: 'update',
280
+ path: '/_hmr/entry-b.js',
281
+ timestamp: expect.any(Number),
282
+ },
283
+ ],
284
+ });
285
+ });
286
+
287
+ it('skips watched entrypoints owned by higher-priority integration strategies', async () => {
288
+ const reactEntrypoint = path.join(SRC_DIR, 'react-page.tsx');
289
+ const scriptEntrypoint = path.join(SRC_DIR, 'widget.script.ts');
290
+ const changedFile = path.join(SRC_DIR, 'shared.ts');
291
+ let batchedEntrypoints: string[] = [];
292
+ const devGraphService = new InMemoryDevGraphService();
293
+ devGraphService.setEntrypointDependencies(reactEntrypoint, [changedFile]);
294
+ devGraphService.setEntrypointDependencies(scriptEntrypoint, [changedFile]);
295
+
296
+ const context = createMockContext({
297
+ getWatchedFiles: () =>
298
+ new Map([
299
+ [reactEntrypoint, '/_hmr/react-page.js'],
300
+ [scriptEntrypoint, '/_hmr/widget.script.js'],
301
+ ]),
302
+ getEntrypointDependencyGraph: () => devGraphService,
303
+ shouldProcessEntrypoint: (entrypointPath: string) => entrypointPath !== reactEntrypoint,
304
+ });
305
+
306
+ const strategy = new JsHmrStrategy(context) as unknown as {
307
+ process: (filePath: string) => Promise<{ type: string; events?: unknown[] }>;
308
+ [key: string]: unknown;
309
+ };
310
+
311
+ strategy.bundleEntrypoints = async (entrypoints: string[]) => {
312
+ batchedEntrypoints = entrypoints;
313
+ return { success: true, dependencies: new Map([[path.resolve(scriptEntrypoint), [scriptEntrypoint]]]) };
314
+ };
315
+
316
+ strategy.processOutput = async () => {
317
+ return { success: true, requiresReload: false };
318
+ };
319
+
320
+ const action = await strategy.process(changedFile);
321
+
322
+ expect(batchedEntrypoints).toEqual([scriptEntrypoint]);
323
+ expect(action).toEqual({
324
+ type: 'broadcast',
325
+ events: [
326
+ {
327
+ type: 'update',
328
+ path: '/_hmr/widget.script.js',
329
+ timestamp: expect.any(Number),
330
+ },
331
+ ],
332
+ });
333
+ });
334
+ });
335
+ });
@@ -0,0 +1,320 @@
1
+ /**
2
+ * JavaScript HMR Strategy
3
+ *
4
+ * Handles hot module replacement for JavaScript and TypeScript entrypoints.
5
+ * Bundles files, inspects the emitted output, and decides whether the browser
6
+ * can hot-accept the change or must reload.
7
+ *
8
+ * @module
9
+ */
10
+
11
+ import path from 'node:path';
12
+ import { fileSystem } from '@ecopages/file-system';
13
+ import { HmrStrategy, HmrStrategyType, type HmrAction } from '../hmr-strategy.ts';
14
+ import { appLogger } from '../../global/app-logger.ts';
15
+ import type { EcoBuildPlugin } from '../../build/build-types.ts';
16
+ import type { BrowserBundleExecutor } from '../../services/assets/browser-bundle.service.ts';
17
+ import type { EntrypointDependencyGraph } from '../../services/runtime-state/entrypoint-dependency-graph.service.ts';
18
+
19
+ /**
20
+ * Context interface providing access to HmrManager state.
21
+ * Required for JsHmrStrategy to access registered entrypoints and configuration.
22
+ */
23
+ export interface JsHmrContext {
24
+ /**
25
+ * Map of registered entrypoints to their output URLs.
26
+ */
27
+ getWatchedFiles(): Map<string, string>;
28
+
29
+ /**
30
+ * Map of bare specifiers to vendor URLs for import resolution.
31
+ */
32
+ getSpecifierMap(): Map<string, string>;
33
+
34
+ getEntrypointDependencyGraph(): EntrypointDependencyGraph;
35
+
36
+ /**
37
+ * Directory where HMR bundles are written.
38
+ */
39
+ getDistDir(): string;
40
+
41
+ /**
42
+ * Build plugins to use during bundling.
43
+ */
44
+ getPlugins(): EcoBuildPlugin[];
45
+
46
+ /**
47
+ * Absolute path to the source directory.
48
+ */
49
+ getSrcDir(): string;
50
+
51
+ /**
52
+ * Absolute path to the pages directory.
53
+ */
54
+ getPagesDir(): string;
55
+
56
+ /**
57
+ * Absolute path to the layouts directory.
58
+ */
59
+ getLayoutsDir(): string;
60
+
61
+ /**
62
+ * All configured route-template extensions across integrations.
63
+ */
64
+ getTemplateExtensions(): string[];
65
+
66
+ /**
67
+ * Browser bundler used to rebuild changed entrypoints.
68
+ */
69
+ getBrowserBundleService(): BrowserBundleExecutor;
70
+
71
+ /**
72
+ * Returns whether a watched entrypoint should be rebuilt by the generic JS strategy.
73
+ *
74
+ * @remarks
75
+ * Integrations with higher-priority HMR strategies can use this to keep the
76
+ * generic JS strategy from overwriting their emitted entrypoints when a shared
77
+ * dependency changes.
78
+ */
79
+ shouldProcessEntrypoint?(entrypointPath: string): boolean;
80
+ }
81
+
82
+ /**
83
+ * Strategy for handling JavaScript/TypeScript file changes with hot reloading.
84
+ *
85
+ * The processing steps are:
86
+ * 1. Check if any entrypoints are registered
87
+ * 2. Rebuild impacted entrypoints, or all watched entrypoints when no runtime
88
+ * dependency graph is available
89
+ * 3. Emit rebuilt entrypoint bundles for browser delivery
90
+ * 4. Inject generic HMR boilerplate
91
+ * 5. Broadcast update events for each rebuilt entrypoint
92
+ *
93
+ * @remarks
94
+ * Node can provide dependency-graph metadata, so this strategy can rebuild only
95
+ * the entrypoints impacted by a changed dependency. Runtimes that do not expose
96
+ * that metadata intentionally keep the rebuild-all fallback.
97
+ *
98
+ * @see https://bun.sh/docs/runtime/transpiler
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * const context = {
103
+ * getWatchedFiles: () => watchedFilesMap,
104
+ * getSpecifierMap: () => specifierMap,
105
+ * getDistDir: () => '/path/to/dist/_hmr',
106
+ * getPlugins: () => [],
107
+ * getSrcDir: () => '/path/to/src'
108
+ * };
109
+ * const strategy = new JsHmrStrategy(context);
110
+ * ```
111
+ */
112
+ export class JsHmrStrategy extends HmrStrategy {
113
+ readonly type = HmrStrategyType.SCRIPT;
114
+ private context: JsHmrContext;
115
+
116
+ constructor(context: JsHmrContext) {
117
+ super();
118
+ this.context = context;
119
+ }
120
+
121
+ /**
122
+ * Determines if the file is a JS/TS file that could affect registered entrypoints.
123
+ *
124
+ * Matches if:
125
+ * 1. There are registered entrypoints to rebuild
126
+ * 2. The changed file is a JS/TS file in the src directory
127
+ *
128
+ * @param filePath - Absolute path to the changed file
129
+ * @returns True if this file should trigger entrypoint rebuilds
130
+ */
131
+ matches(filePath: string): boolean {
132
+ const watchedFiles = this.context.getWatchedFiles();
133
+ const isJsTs = /\.(ts|tsx|js|jsx)$/.test(filePath);
134
+ const isInSrc = filePath.startsWith(this.context.getSrcDir());
135
+ const isRouteTemplate =
136
+ filePath.startsWith(this.context.getPagesDir()) || filePath.startsWith(this.context.getLayoutsDir());
137
+ const isIntegrationTemplate =
138
+ isRouteTemplate && this.context.getTemplateExtensions().some((extension) => filePath.endsWith(extension));
139
+
140
+ if (watchedFiles.size === 0) {
141
+ return false;
142
+ }
143
+
144
+ if (!isJsTs || !isInSrc) {
145
+ return false;
146
+ }
147
+
148
+ if (isIntegrationTemplate) {
149
+ return false;
150
+ }
151
+
152
+ if (watchedFiles.has(filePath)) {
153
+ return true;
154
+ }
155
+
156
+ const entrypointDependencyGraph = this.context.getEntrypointDependencyGraph();
157
+ if (entrypointDependencyGraph.supportsSelectiveInvalidation()) {
158
+ return entrypointDependencyGraph.getDependencyEntrypoints(filePath).size > 0;
159
+ }
160
+
161
+ return true;
162
+ }
163
+
164
+ /**
165
+ * Processes a file change by rebuilding affected entrypoints.
166
+ *
167
+ * @param filePath - Absolute path to the changed file
168
+ *
169
+ * @remarks
170
+ * If runtime-specific dependency graph hooks are unavailable, this strategy
171
+ * falls back to rebuilding all watched entrypoints.
172
+ * When multiple entrypoints are impacted they are bundled in a single esbuild
173
+ * invocation to share AST parsing and chunk deduplication.
174
+ * @returns Action to broadcast update events
175
+ */
176
+ async process(filePath: string): Promise<HmrAction> {
177
+ appLogger.debug(`[JsHmrStrategy] Processing ${filePath}`);
178
+ const watchedFiles = this.context.getWatchedFiles();
179
+
180
+ if (watchedFiles.size === 0) {
181
+ appLogger.debug(`[JsHmrStrategy] No watched files to rebuild`);
182
+ return { type: 'none' };
183
+ }
184
+
185
+ const dependencyHits = this.context.getEntrypointDependencyGraph().getDependencyEntrypoints(filePath);
186
+ const hasDependencyHit = dependencyHits.size > 0;
187
+ const impactedEntrypoints = hasDependencyHit
188
+ ? Array.from(dependencyHits).filter((entrypoint) => watchedFiles.has(entrypoint))
189
+ : Array.from(watchedFiles.keys());
190
+ const buildableEntrypoints = impactedEntrypoints.filter(
191
+ (entrypoint) => this.context.shouldProcessEntrypoint?.(entrypoint) ?? true,
192
+ );
193
+
194
+ if (!hasDependencyHit) {
195
+ appLogger.debug('[JsHmrStrategy] Dependency graph miss, rebuilding all watched entrypoints');
196
+ }
197
+
198
+ if (buildableEntrypoints.length === 0) {
199
+ return { type: 'none' };
200
+ }
201
+
202
+ const buildResult = await this.bundleEntrypoints(buildableEntrypoints);
203
+
204
+ if (!buildResult.success) {
205
+ return { type: 'none' };
206
+ }
207
+
208
+ const updates: string[] = [];
209
+ let reloadRequired = false;
210
+
211
+ for (const entrypoint of buildableEntrypoints) {
212
+ const outputUrl = watchedFiles.get(entrypoint);
213
+ if (!outputUrl) continue;
214
+
215
+ if (buildResult.dependencies) {
216
+ const entrypointDeps = buildResult.dependencies.get(path.resolve(entrypoint)) ?? [];
217
+ this.context.getEntrypointDependencyGraph().setEntrypointDependencies(entrypoint, entrypointDeps);
218
+ }
219
+
220
+ const srcDir = this.context.getSrcDir();
221
+ const relativePath = path.relative(srcDir, entrypoint);
222
+ const relativePathJs = relativePath.replace(/\.(tsx?|jsx?|mdx?)$/, '.js');
223
+ const outputPath = path.join(this.context.getDistDir(), relativePathJs);
224
+
225
+ const result = await this.processOutput(outputPath, outputUrl);
226
+ if (result.success) {
227
+ updates.push(outputUrl);
228
+ if (result.requiresReload) {
229
+ reloadRequired = true;
230
+ }
231
+ }
232
+ }
233
+
234
+ if (updates.length > 0) {
235
+ if (reloadRequired) {
236
+ appLogger.debug(`[JsHmrStrategy] Full reload required (no HMR accept found)`);
237
+ return {
238
+ type: 'broadcast',
239
+ events: [{ type: 'reload' }],
240
+ };
241
+ }
242
+
243
+ return {
244
+ type: 'broadcast',
245
+ events: updates.map((p) => ({
246
+ type: 'update',
247
+ path: p,
248
+ timestamp: Date.now(),
249
+ })),
250
+ };
251
+ }
252
+
253
+ return { type: 'none' };
254
+ }
255
+
256
+ /**
257
+ * Bundles one or more entrypoints in a single esbuild invocation.
258
+ * Uses the source directory as the output base so that the directory structure
259
+ * is preserved under the HMR dist folder.
260
+ */
261
+ private async bundleEntrypoints(
262
+ entrypoints: string[],
263
+ ): Promise<{ success: boolean; dependencies?: Map<string, string[]> }> {
264
+ try {
265
+ const result = await this.context.getBrowserBundleService().bundle({
266
+ profile: 'hmr-entrypoint',
267
+ entrypoints,
268
+ outdir: this.context.getDistDir(),
269
+ outbase: this.context.getSrcDir(),
270
+ naming: '[dir]/[name]',
271
+ plugins: this.context.getPlugins(),
272
+ minify: false,
273
+ });
274
+
275
+ if (!result.success) {
276
+ appLogger.error('[JsHmrStrategy] Batched build failed:', result.logs);
277
+ return { success: false };
278
+ }
279
+
280
+ const dependencies = new Map<string, string[]>();
281
+ if (result.dependencyGraph?.entrypoints) {
282
+ for (const [entrypoint, deps] of Object.entries(result.dependencyGraph.entrypoints)) {
283
+ dependencies.set(path.resolve(entrypoint), deps);
284
+ }
285
+ }
286
+
287
+ return { success: true, dependencies };
288
+ } catch (error) {
289
+ appLogger.error('[JsHmrStrategy] Error in batched build:', error as Error);
290
+ return { success: false };
291
+ }
292
+ }
293
+
294
+ /**
295
+ * Processes bundled output and determines whether the browser can hot-accept
296
+ * the update or must fall back to a full reload.
297
+ *
298
+ * @param filepath - Path to the bundled output file
299
+ * @param url - URL path for the bundled file
300
+ * @returns True if processing was successful and update should be broadcast
301
+ */
302
+ private async processOutput(filepath: string, url: string): Promise<{ success: boolean; requiresReload: boolean }> {
303
+ try {
304
+ const code = await fileSystem.readFile(filepath);
305
+
306
+ if (code.includes('/* [ecopages] hmr */')) {
307
+ // Legacy safety: previously processed bundles already carry the marker.
308
+ return { success: true, requiresReload: !code.includes('import.meta.hot.accept') };
309
+ }
310
+
311
+ appLogger.debug(`[JsHmrStrategy] Processed ${url}`);
312
+
313
+ const hasHmrAccept = code.includes('import.meta.hot.accept');
314
+ return { success: true, requiresReload: !hasHmrAccept };
315
+ } catch (error) {
316
+ appLogger.error(`[JsHmrStrategy] Error processing output for ${url}:`, error as Error);
317
+ return { success: false, requiresReload: false };
318
+ }
319
+ }
320
+ }
@@ -0,0 +1,3 @@
1
+ export type * from './types/public-types.ts';
2
+ export type * from './eco/eco.types.ts';
3
+ export { eco } from './eco/eco.browser.ts';
package/src/index.ts ADDED
@@ -0,0 +1,15 @@
1
+ export type * from './types/public-types.ts';
2
+ export type * from './eco/eco.types.ts';
3
+ export { eco } from './eco/eco.ts';
4
+ export { defineApiHandler, defineGroupHandler, type GroupHandler } from './adapters/shared/define-api-handler.ts';
5
+ export {
6
+ createEcoBuildPluginFromSourceTransform,
7
+ createVitePluginsFromAppSourceTransforms,
8
+ getAppSourceTransforms,
9
+ createVitePluginFromSourceTransform,
10
+ normalizeTransformId,
11
+ type EcoSourceTransform,
12
+ type EcoSourceTransformResult,
13
+ type EcoViteCompatiblePlugin,
14
+ } from './plugins/source-transform.ts';
15
+ export { createEcoComponentMetaTransform } from './plugins/eco-component-meta-plugin.ts';