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

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,240 @@
1
+ import path from 'node:path';
2
+ import { fileSystem } from '@ecopages/file-system';
3
+ import type { EcoBuildPlugin } from '../build/build-types.ts';
4
+ import type { EcoPagesAppConfig, IClientBridge } from '../types/internal-types.ts';
5
+ import type { AssetDefinition } from '../services/assets/asset-processing-service/assets.types.ts';
6
+ import { DEFAULT_ECOPAGES_WORK_DIR } from '../config/constants.ts';
7
+ import { GENERATED_BASE_PATHS } from '../config/constants.ts';
8
+ import type { RuntimeCapabilityDeclaration } from './runtime-capability.ts';
9
+
10
+ export type { RuntimeCapabilityDeclaration, RuntimeCapabilityTag } from './runtime-capability.ts';
11
+
12
+ export const PROCESSOR_ERRORS = {
13
+ CACHE_DIRECTORY_NOT_SET: 'Cache directory not set in context',
14
+ } as const;
15
+
16
+ function resolveGeneratedPath(
17
+ type: keyof typeof GENERATED_BASE_PATHS,
18
+ options: { root: string; module: string; subPath?: string },
19
+ ): string {
20
+ const { root, module, subPath } = options;
21
+ const parts = [root, GENERATED_BASE_PATHS[type], module, subPath].filter(Boolean);
22
+ return path.join(...(parts as string[]));
23
+ }
24
+
25
+ export interface ProcessorWatchContext {
26
+ path: string;
27
+ bridge: IClientBridge;
28
+ }
29
+
30
+ export interface ProcessorWatchConfig {
31
+ paths: string[];
32
+ extensions?: string[];
33
+ onCreate?: (ctx: ProcessorWatchContext) => Promise<void>;
34
+ onChange?: (ctx: ProcessorWatchContext) => Promise<void>;
35
+ onDelete?: (ctx: ProcessorWatchContext) => Promise<void>;
36
+ onError?: (error: Error) => void;
37
+ }
38
+
39
+ export type ProcessorAssetKind = 'script' | 'stylesheet' | 'image';
40
+ export type ProcessorExtensionPattern = string;
41
+
42
+ export interface ProcessorAssetCapability {
43
+ kind: ProcessorAssetKind;
44
+ /**
45
+ * Supported patterns:
46
+ * - `*` (all extensions)
47
+ * - `.css` or `css`
48
+ * - `*.css`
49
+ * - `*.{css,scss,sass}`
50
+ *
51
+ * Pattern matching is case-insensitive and trims surrounding spaces,
52
+ * including grouped values (e.g. `*.{ CSS, ScSs }`).
53
+ */
54
+ extensions?: ProcessorExtensionPattern[];
55
+ }
56
+
57
+ export interface ProcessorConfig<TOptions = Record<string, unknown>> {
58
+ name: string;
59
+ description?: string;
60
+ options?: TOptions;
61
+ watch?: ProcessorWatchConfig;
62
+ capabilities?: ProcessorAssetCapability[];
63
+ runtimeCapability?: RuntimeCapabilityDeclaration;
64
+ }
65
+ export interface ProcessorContext {
66
+ config: EcoPagesAppConfig;
67
+ rootDir: string;
68
+ srcDir: string;
69
+ distDir: string;
70
+ cache?: string;
71
+ }
72
+
73
+ /**
74
+ * Interface for processor build plugins
75
+ * This is used to pass plugins to the build process directly from the processor
76
+ * For instance it can become very handy when dealing with virtual modules that needs to be recognized by the bundler
77
+ * i.e. @ecopages/image-processor
78
+ */
79
+ export abstract class Processor<TOptions = Record<string, unknown>> {
80
+ readonly name: string;
81
+ protected dependencies: AssetDefinition[] = [];
82
+ protected context?: ProcessorContext;
83
+ protected options?: TOptions;
84
+ protected watchConfig?: ProcessorWatchConfig;
85
+ protected capabilities: ProcessorAssetCapability[] = [];
86
+ readonly runtimeCapability?: RuntimeCapabilityDeclaration;
87
+
88
+ /** Plugins that are only used during the build process */
89
+ abstract buildPlugins?: EcoBuildPlugin[];
90
+
91
+ /** Plugins that are used during runtime for file processing */
92
+ abstract plugins?: EcoBuildPlugin[];
93
+
94
+ constructor(config: ProcessorConfig<TOptions>) {
95
+ this.name = config.name;
96
+ this.options = config.options;
97
+ this.watchConfig = config.watch;
98
+ this.capabilities = config.capabilities ?? [];
99
+ this.runtimeCapability = config.runtimeCapability;
100
+ }
101
+
102
+ setContext(appConfig: EcoPagesAppConfig): void {
103
+ const workDir =
104
+ appConfig.absolutePaths.workDir ??
105
+ path.join(appConfig.rootDir, appConfig.workDir ?? DEFAULT_ECOPAGES_WORK_DIR);
106
+ const cachePath = resolveGeneratedPath('cache', {
107
+ root: workDir,
108
+ module: this.name,
109
+ });
110
+
111
+ fileSystem.ensureDir(cachePath);
112
+
113
+ this.context = {
114
+ config: appConfig,
115
+ rootDir: appConfig.rootDir,
116
+ srcDir: appConfig.absolutePaths.srcDir,
117
+ distDir: appConfig.absolutePaths.distDir,
118
+ cache: cachePath,
119
+ };
120
+ }
121
+
122
+ /**
123
+ * Prepares build-facing processor contributions before config finalization.
124
+ *
125
+ * @remarks
126
+ * Override this when a processor must compute runtime/build plugins or other
127
+ * manifest-owned state before startup. Runtime-only work such as cache
128
+ * warming or watcher registration should stay in `setup()`.
129
+ */
130
+ async prepareBuildContributions(): Promise<void> {}
131
+
132
+ abstract setup(): Promise<void>;
133
+ abstract teardown(): Promise<void>;
134
+ abstract process(input: unknown, filePath?: string): Promise<unknown>;
135
+
136
+ protected getCachePath(key: string): string {
137
+ return `${this.context?.cache}/${key}`;
138
+ }
139
+
140
+ protected async readCache<T>(key: string): Promise<T | null> {
141
+ const cachePath = this.getCachePath(key);
142
+ try {
143
+ const data = await fileSystem.readFile(cachePath);
144
+ return JSON.parse(data) as T;
145
+ } catch {
146
+ return null;
147
+ }
148
+ }
149
+
150
+ protected async writeCache<T>(key: string, data: T): Promise<void> {
151
+ if (!this.context?.cache) {
152
+ throw new Error(PROCESSOR_ERRORS.CACHE_DIRECTORY_NOT_SET);
153
+ }
154
+
155
+ const cachePath = this.getCachePath(key);
156
+ fileSystem.write(cachePath, JSON.stringify(data, null, 2));
157
+ }
158
+
159
+ getWatchConfig(): ProcessorWatchConfig | undefined {
160
+ return this.watchConfig;
161
+ }
162
+
163
+ getDependencies(): AssetDefinition[] {
164
+ return this.dependencies;
165
+ }
166
+
167
+ getName(): string {
168
+ return this.name;
169
+ }
170
+
171
+ getAssetCapabilities(): ProcessorAssetCapability[] {
172
+ return this.capabilities;
173
+ }
174
+
175
+ matchesFileFilter(_filepath: string): boolean {
176
+ return true;
177
+ }
178
+
179
+ canProcessAsset(kind: ProcessorAssetKind, filepath?: string): boolean {
180
+ const capabilities = this.getAssetCapabilities();
181
+ if (capabilities.length === 0) {
182
+ return false;
183
+ }
184
+
185
+ const matchingKind = capabilities.filter((capability) => capability.kind === kind);
186
+ if (matchingKind.length === 0) {
187
+ return false;
188
+ }
189
+
190
+ if (!filepath) {
191
+ return true;
192
+ }
193
+
194
+ return matchingKind.some((capability) => this.matchesCapabilityExtensions(filepath, capability.extensions));
195
+ }
196
+
197
+ private matchesCapabilityExtensions(filepath: string, extensions?: ProcessorExtensionPattern[]): boolean {
198
+ if (!extensions || extensions.length === 0) {
199
+ return true;
200
+ }
201
+
202
+ const normalizedExt = path.extname(filepath).toLowerCase();
203
+
204
+ return extensions.some((rawPattern) => {
205
+ const pattern = this.normalizeExtensionPattern(rawPattern);
206
+ if (!pattern) {
207
+ return false;
208
+ }
209
+
210
+ if (pattern === '*') {
211
+ return true;
212
+ }
213
+
214
+ const groupedMatch = pattern.match(/^\*\.\{(.+)\}$/);
215
+ if (groupedMatch) {
216
+ const groupItems = groupedMatch[1]
217
+ .split(',')
218
+ .map((item) => this.normalizeExtensionPattern(item))
219
+ .filter(Boolean);
220
+
221
+ return groupItems.some((item) => normalizedExt === item || normalizedExt === `.${item}`);
222
+ }
223
+
224
+ if (pattern.startsWith('*')) {
225
+ const suffix = pattern.slice(1);
226
+ return normalizedExt.endsWith(suffix);
227
+ }
228
+
229
+ if (pattern.startsWith('.')) {
230
+ return normalizedExt === pattern;
231
+ }
232
+
233
+ return normalizedExt === `.${pattern}`;
234
+ });
235
+ }
236
+
237
+ private normalizeExtensionPattern(rawPattern: string): string {
238
+ return rawPattern.trim().toLowerCase();
239
+ }
240
+ }
@@ -1,9 +1,14 @@
1
- export type RuntimeCapabilityTag = 'bun-only' | 'node-compatible' | 'requires-native-bun-api' | 'requires-node-builtins';
1
+ export type RuntimeCapabilityTag =
2
+ | 'bun-only'
3
+ | 'node-compatible'
4
+ | 'requires-native-bun-api'
5
+ | 'requires-node-builtins';
6
+
2
7
  /**
3
8
  * Declares the runtime assumptions a plugin makes so config finalization can
4
9
  * reject incompatible startup environments before bootstrapping the app.
5
10
  */
6
11
  export interface RuntimeCapabilityDeclaration {
7
- tags: RuntimeCapabilityTag[];
8
- minRuntimeVersion?: string;
12
+ tags: RuntimeCapabilityTag[];
13
+ minRuntimeVersion?: string;
9
14
  }
@@ -0,0 +1,82 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+ import { fileSystem } from '@ecopages/file-system';
3
+ import {
4
+ applySourceTransform,
5
+ createVitePluginsFromAppSourceTransforms,
6
+ createEcoBuildPluginFromSourceTransform,
7
+ getAppSourceTransforms,
8
+ createVitePluginFromSourceTransform,
9
+ normalizeTransformId,
10
+ type EcoSourceTransform,
11
+ } from './source-transform.ts';
12
+ import type { EcoPagesAppConfig } from '../types/internal-types.ts';
13
+
14
+ describe('source-transform', () => {
15
+ const transform: EcoSourceTransform = {
16
+ name: 'test-transform',
17
+ filter: /main\.tsx$/,
18
+ transform(code) {
19
+ return {
20
+ code: `/* injected */\n${code}`,
21
+ };
22
+ },
23
+ };
24
+
25
+ it('normalizes ids by stripping query and hash suffixes', () => {
26
+ expect(normalizeTransformId('/src/main.tsx?import')).toBe('/src/main.tsx');
27
+ expect(normalizeTransformId('/src/main.tsx#hash')).toBe('/src/main.tsx');
28
+ });
29
+
30
+ it('applies transforms against normalized ids', () => {
31
+ const result = applySourceTransform(transform, 'export const value = 1;', '/src/main.tsx?import');
32
+
33
+ expect(result).toEqual({
34
+ code: '/* injected */\nexport const value = 1;',
35
+ });
36
+ });
37
+
38
+ it('creates a Vite-compatible transform plugin', () => {
39
+ const vitePlugin = createVitePluginFromSourceTransform(transform);
40
+ const result = vitePlugin.transform('export const value = 1;', '/src/main.tsx?import');
41
+
42
+ expect(vitePlugin.name).toBe('test-transform');
43
+ expect(result).toEqual({
44
+ code: '/* injected */\nexport const value = 1;',
45
+ });
46
+ });
47
+
48
+ it('creates an Ecopages build plugin wrapper', async () => {
49
+ const buildPlugin = createEcoBuildPluginFromSourceTransform(transform);
50
+ let onLoadCallback: ((args: { path: string }) => unknown) | undefined;
51
+
52
+ buildPlugin.setup({
53
+ onLoad(_options: unknown, callback: unknown) {
54
+ onLoadCallback = callback as typeof onLoadCallback;
55
+ },
56
+ } as never);
57
+
58
+ const readSpy = vi.spyOn(fileSystem, 'readFileSync').mockReturnValue('export const value = 1;');
59
+
60
+ try {
61
+ const result = await onLoadCallback?.({ path: '/src/main.tsx?import' });
62
+
63
+ expect(result).toEqual({
64
+ contents: '/* injected */\nexport const value = 1;',
65
+ loader: 'tsx',
66
+ resolveDir: '/src',
67
+ });
68
+ } finally {
69
+ readSpy.mockRestore();
70
+ }
71
+ });
72
+
73
+ it('collects app-owned source transforms and adapts them to Vite plugins', () => {
74
+ const appConfig = {
75
+ sourceTransforms: new Map([[transform.name, transform]]),
76
+ } as EcoPagesAppConfig;
77
+
78
+ expect(getAppSourceTransforms(appConfig)).toEqual([transform]);
79
+ expect(createVitePluginsFromAppSourceTransforms(appConfig)).toHaveLength(1);
80
+ expect(createVitePluginsFromAppSourceTransforms(appConfig)[0].name).toBe('test-transform');
81
+ });
82
+ });
@@ -0,0 +1,123 @@
1
+ import path from 'node:path';
2
+ import { fileSystem } from '@ecopages/file-system';
3
+ import type { EcoBuildPlugin } from '../build/build-types.ts';
4
+ import type { EcoPagesAppConfig } from '../types/internal-types.ts';
5
+
6
+ export interface EcoSourceTransformResult {
7
+ code: string;
8
+ map?: unknown;
9
+ }
10
+
11
+ export interface EcoSourceTransform {
12
+ name: string;
13
+ filter: RegExp;
14
+ enforce?: 'pre' | 'post';
15
+ transform(code: string, id: string): EcoSourceTransformResult | string | undefined;
16
+ }
17
+
18
+ export interface EcoViteCompatiblePlugin {
19
+ name: string;
20
+ enforce?: 'pre' | 'post';
21
+ transform(code: string, id: string): EcoSourceTransformResult | string | undefined;
22
+ }
23
+
24
+ /**
25
+ * Normalizes bundler module ids so one transform can serve Ecopages loaders,
26
+ * Vite, and future bundler adapters.
27
+ */
28
+ export function normalizeTransformId(id: string): string {
29
+ const queryIndex = id.indexOf('?');
30
+ const hashIndex = id.indexOf('#');
31
+ const endIndex = [queryIndex, hashIndex].filter((index) => index >= 0).sort((left, right) => left - right)[0];
32
+
33
+ return endIndex === undefined ? id : id.slice(0, endIndex);
34
+ }
35
+
36
+ /**
37
+ * Applies one source transform if the normalized id matches its filter.
38
+ */
39
+ export function applySourceTransform(
40
+ transform: EcoSourceTransform,
41
+ code: string,
42
+ id: string,
43
+ ): EcoSourceTransformResult | string | undefined {
44
+ const normalizedId = normalizeTransformId(id);
45
+
46
+ if (!transform.filter.test(normalizedId)) {
47
+ return undefined;
48
+ }
49
+
50
+ return transform.transform(code, normalizedId);
51
+ }
52
+
53
+ function inferLoaderFromPath(filePath: string): 'ts' | 'tsx' | 'js' | 'jsx' {
54
+ const extension = path.extname(filePath).toLowerCase();
55
+
56
+ switch (extension) {
57
+ case '.ts':
58
+ return 'ts';
59
+ case '.tsx':
60
+ return 'tsx';
61
+ case '.jsx':
62
+ return 'jsx';
63
+ default:
64
+ return 'js';
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Adapts a source transform into the existing Ecopages build-plugin contract.
70
+ */
71
+ export function createEcoBuildPluginFromSourceTransform(transform: EcoSourceTransform): EcoBuildPlugin {
72
+ return {
73
+ name: transform.name,
74
+ setup(build) {
75
+ build.onLoad({ filter: transform.filter }, (args) => {
76
+ const filePath = normalizeTransformId(args.path);
77
+ const code = fileSystem.readFileSync(filePath);
78
+ const result = applySourceTransform(transform, code, filePath);
79
+
80
+ if (!result) {
81
+ return undefined;
82
+ }
83
+
84
+ return {
85
+ contents: typeof result === 'string' ? result : result.code,
86
+ loader: inferLoaderFromPath(filePath),
87
+ resolveDir: path.dirname(filePath),
88
+ };
89
+ });
90
+ },
91
+ };
92
+ }
93
+
94
+ /**
95
+ * Adapts a source transform into a Vite-compatible plugin object.
96
+ *
97
+ * @remarks
98
+ * This intentionally returns a plain object shape so core does not need a hard
99
+ * dependency on `vite` just to author transform primitives.
100
+ */
101
+ export function createVitePluginFromSourceTransform(transform: EcoSourceTransform): EcoViteCompatiblePlugin {
102
+ return {
103
+ name: transform.name,
104
+ enforce: transform.enforce,
105
+ transform(code, id) {
106
+ return applySourceTransform(transform, code, id);
107
+ },
108
+ };
109
+ }
110
+
111
+ /**
112
+ * Returns the app-owned source transforms in stable registration order.
113
+ */
114
+ export function getAppSourceTransforms(appConfig: EcoPagesAppConfig): EcoSourceTransform[] {
115
+ return Array.from(appConfig.sourceTransforms.values());
116
+ }
117
+
118
+ /**
119
+ * Adapts the app-owned source transforms into Vite-compatible plugin objects.
120
+ */
121
+ export function createVitePluginsFromAppSourceTransforms(appConfig: EcoPagesAppConfig): EcoViteCompatiblePlugin[] {
122
+ return getAppSourceTransforms(appConfig).map((transform) => createVitePluginFromSourceTransform(transform));
123
+ }
@@ -0,0 +1,146 @@
1
+ import type { EcoPagesAppConfig } from '../../types/internal-types.ts';
2
+ import type {
3
+ BoundaryPlan,
4
+ BoundaryPlanNode,
5
+ BoundaryPlanNodeSource,
6
+ BoundaryValidationError,
7
+ EcoComponent,
8
+ } from '../../types/public-types.ts';
9
+
10
+ type BoundaryPlanBuildInput = {
11
+ routeFile: string;
12
+ currentIntegrationName: string;
13
+ HtmlTemplate: EcoComponent;
14
+ Layout?: EcoComponent;
15
+ Page: EcoComponent;
16
+ };
17
+
18
+ type BoundaryPlanBuildEntry = {
19
+ component: EcoComponent;
20
+ source: Extract<BoundaryPlanNodeSource, 'page' | 'layout' | 'html-template'>;
21
+ };
22
+
23
+ /**
24
+ * Builds a declared ownership plan from the component dependency graph.
25
+ *
26
+ * The plan is intentionally conservative: it reflects declared component
27
+ * dependencies available during render preparation and records diagnostics for
28
+ * foreign ownership edges that cannot be validated against registered
29
+ * integrations or stable component metadata.
30
+ */
31
+ export class BoundaryPlanningService {
32
+ private readonly appConfig: EcoPagesAppConfig;
33
+ private nextSyntheticId = 0;
34
+
35
+ constructor(appConfig: EcoPagesAppConfig) {
36
+ this.appConfig = appConfig;
37
+ }
38
+
39
+ buildPlan(input: BoundaryPlanBuildInput): BoundaryPlan {
40
+ this.nextSyntheticId = 0;
41
+
42
+ const validationErrors: BoundaryValidationError[] = [];
43
+ const rendererNames = new Set<string>([input.currentIntegrationName]);
44
+ let foreignEdgeCount = 0;
45
+
46
+ const buildNode = (
47
+ component: EcoComponent,
48
+ source: Exclude<BoundaryPlanNodeSource, 'route'>,
49
+ parentIntegrationName: string,
50
+ lineage: Set<object>,
51
+ ): BoundaryPlanNode => {
52
+ const integrationName =
53
+ component.config?.integration ?? component.config?.__eco?.integration ?? parentIntegrationName;
54
+ const componentMeta = component.config?.__eco;
55
+ const isForeignToParent = integrationName !== parentIntegrationName;
56
+ const componentId = componentMeta?.id ?? componentMeta?.file ?? `${source}:${(this.nextSyntheticId += 1)}`;
57
+
58
+ rendererNames.add(integrationName);
59
+
60
+ if (isForeignToParent) {
61
+ foreignEdgeCount += 1;
62
+
63
+ if (!componentMeta) {
64
+ validationErrors.push({
65
+ code: 'MISSING_COMPONENT_METADATA',
66
+ message: `[ecopages] Foreign boundary "${componentId}" must provide stable __eco metadata so ownership diagnostics stay actionable. Declared dependencies must include all possible foreign children.`,
67
+ componentId,
68
+ integrationName,
69
+ });
70
+ }
71
+
72
+ if (!this.isRegisteredIntegration(integrationName, input.currentIntegrationName)) {
73
+ validationErrors.push({
74
+ code: 'UNKNOWN_INTEGRATION_OWNER',
75
+ message: `[ecopages] Foreign boundary "${componentId}" references unknown integration owner "${integrationName}". Declared dependencies must include all possible foreign children and those integrations must be registered.`,
76
+ componentId,
77
+ componentFile: componentMeta?.file,
78
+ integrationName,
79
+ });
80
+ }
81
+ }
82
+
83
+ const nextLineage = new Set(lineage);
84
+ nextLineage.add(component);
85
+ const children = (component.config?.dependencies?.components ?? []).flatMap((child) => {
86
+ if (!child || nextLineage.has(child)) {
87
+ return [];
88
+ }
89
+
90
+ return [buildNode(child, 'dependency', integrationName, nextLineage)];
91
+ });
92
+
93
+ return {
94
+ id: componentId,
95
+ source,
96
+ ownership: {
97
+ integrationName,
98
+ componentId,
99
+ componentFile: componentMeta?.file,
100
+ isPageEntry: source === 'page',
101
+ isForeignToParent,
102
+ },
103
+ children,
104
+ declaredDependenciesValid: true,
105
+ };
106
+ };
107
+
108
+ const roots: BoundaryPlanBuildEntry[] = [
109
+ { component: input.HtmlTemplate, source: 'html-template' },
110
+ ...(input.Layout ? [{ component: input.Layout, source: 'layout' as const }] : []),
111
+ { component: input.Page, source: 'page' },
112
+ ];
113
+
114
+ const root: BoundaryPlanNode = {
115
+ id: `route:${input.routeFile}`,
116
+ source: 'route',
117
+ ownership: {
118
+ integrationName: input.currentIntegrationName,
119
+ componentId: `route:${input.routeFile}`,
120
+ componentFile: input.routeFile,
121
+ isPageEntry: false,
122
+ isForeignToParent: false,
123
+ },
124
+ children: roots.map(({ component, source }) =>
125
+ buildNode(component, source, input.currentIntegrationName, new Set()),
126
+ ),
127
+ declaredDependenciesValid: validationErrors.length === 0,
128
+ };
129
+
130
+ return {
131
+ root,
132
+ rendererNames: Array.from(rendererNames),
133
+ foreignEdgeCount,
134
+ hasValidationErrors: validationErrors.length > 0,
135
+ validationErrors,
136
+ };
137
+ }
138
+
139
+ private isRegisteredIntegration(integrationName: string, currentIntegrationName: string): boolean {
140
+ if (integrationName === currentIntegrationName) {
141
+ return true;
142
+ }
143
+
144
+ return this.appConfig.integrations.some((integration) => integration.name === integrationName);
145
+ }
146
+ }