@ecopages/core 0.2.0-alpha.26 → 0.2.0-alpha.27

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 (550) hide show
  1. package/README.md +63 -7
  2. package/package.json +73 -249
  3. package/src/adapters/abstract/application-adapter.test.ts +172 -0
  4. package/src/adapters/abstract/application-adapter.ts +379 -0
  5. package/src/adapters/abstract/router-adapter.ts +30 -0
  6. package/src/adapters/abstract/server-adapter.ts +79 -0
  7. package/src/adapters/bun/client-bridge.ts +62 -0
  8. package/src/adapters/bun/create-app.ts +232 -0
  9. package/src/adapters/bun/hmr-manager.test.ts +265 -0
  10. package/src/adapters/bun/hmr-manager.ts +383 -0
  11. package/src/adapters/bun/index.ts +2 -0
  12. package/src/adapters/bun/server-adapter.ts +526 -0
  13. package/src/adapters/bun/server-lifecycle.ts +124 -0
  14. package/src/adapters/create-app.test.ts +10 -0
  15. package/src/adapters/create-app.ts +91 -0
  16. package/src/adapters/index.ts +2 -0
  17. package/src/adapters/node/create-app.test.ts +53 -0
  18. package/src/adapters/node/create-app.ts +183 -0
  19. package/src/adapters/node/node-client-bridge.test.ts +198 -0
  20. package/src/adapters/node/node-client-bridge.ts +79 -0
  21. package/src/adapters/node/node-hmr-manager.test.ts +320 -0
  22. package/src/adapters/node/node-hmr-manager.ts +355 -0
  23. package/src/adapters/node/server-adapter.ts +502 -0
  24. package/src/adapters/node/static-content-server.test.ts +60 -0
  25. package/src/adapters/node/static-content-server.ts +239 -0
  26. package/src/adapters/shared/api-response.test.ts +97 -0
  27. package/src/adapters/shared/api-response.ts +104 -0
  28. package/src/adapters/shared/application-adapter.ts +199 -0
  29. package/src/adapters/shared/define-api-handler.ts +66 -0
  30. package/src/adapters/shared/explicit-static-render-preparation.ts +58 -0
  31. package/src/adapters/shared/explicit-static-route-matcher.test.ts +381 -0
  32. package/src/adapters/shared/explicit-static-route-matcher.ts +131 -0
  33. package/src/adapters/shared/file-route-middleware-pipeline.test.ts +85 -0
  34. package/src/adapters/shared/file-route-middleware-pipeline.ts +118 -0
  35. package/src/adapters/shared/fs-server-response-factory.test.ts +176 -0
  36. package/src/adapters/shared/fs-server-response-factory.ts +96 -0
  37. package/src/adapters/shared/fs-server-response-matcher.test.ts +311 -0
  38. package/src/adapters/shared/fs-server-response-matcher.ts +240 -0
  39. package/src/adapters/shared/hmr-entrypoint-registrar.ts +149 -0
  40. package/src/adapters/shared/hmr-html-response.ts +52 -0
  41. package/src/adapters/shared/hmr-manager.contract.test.ts +228 -0
  42. package/src/adapters/shared/hmr-manager.dispatch.test.ts +220 -0
  43. package/src/adapters/shared/render-context.test.ts +150 -0
  44. package/src/adapters/shared/render-context.ts +123 -0
  45. package/src/adapters/shared/runtime-bootstrap.ts +79 -0
  46. package/src/adapters/shared/server-adapter.test.ts +130 -0
  47. package/src/adapters/shared/server-adapter.ts +562 -0
  48. package/src/adapters/shared/server-route-handler.test.ts +111 -0
  49. package/src/adapters/shared/server-route-handler.ts +153 -0
  50. package/src/adapters/shared/server-static-builder.test.ts +338 -0
  51. package/src/adapters/shared/server-static-builder.ts +170 -0
  52. package/src/build/build-adapter-serialization.test.ts +281 -0
  53. package/src/build/build-adapter.test.ts +1240 -0
  54. package/src/build/build-adapter.ts +1012 -0
  55. package/src/build/build-manifest.ts +54 -0
  56. package/src/build/build-types.ts +83 -0
  57. package/src/build/dev-build-coordinator.ts +220 -0
  58. package/src/build/esbuild-build-adapter.ts +660 -0
  59. package/src/build/runtime-build-executor.test.ts +81 -0
  60. package/src/build/runtime-build-executor.ts +40 -0
  61. package/src/build/runtime-specifier-alias-plugin.test.ts +67 -0
  62. package/src/build/runtime-specifier-alias-plugin.ts +62 -0
  63. package/src/build/runtime-specifier-aliases.ts +135 -0
  64. package/src/config/README.md +1 -1
  65. package/src/config/config-builder.test.ts +442 -0
  66. package/src/config/config-builder.ts +737 -0
  67. package/src/config/config-builder.typecheck.test.ts +96 -0
  68. package/src/config/{constants.d.ts → constants.ts} +22 -13
  69. package/src/dev/host-runtime.ts +34 -0
  70. package/src/dev/sc-server.ts +143 -0
  71. package/src/eco/eco.browser.test.ts +43 -0
  72. package/src/eco/eco.browser.ts +118 -0
  73. package/src/eco/eco.test.ts +654 -0
  74. package/src/eco/eco.ts +205 -0
  75. package/src/eco/eco.types.ts +221 -0
  76. package/src/eco/eco.utils.test.ts +219 -0
  77. package/src/eco/eco.utils.ts +5 -0
  78. package/src/eco/global-injector-map.test.ts +42 -0
  79. package/src/eco/global-injector-map.ts +112 -0
  80. package/src/eco/lazy-injector-map.test.ts +66 -0
  81. package/src/eco/lazy-injector-map.ts +120 -0
  82. package/src/eco/module-dependencies.test.ts +30 -0
  83. package/src/eco/module-dependencies.ts +75 -0
  84. package/src/errors/http-error.test.ts +134 -0
  85. package/src/errors/http-error.ts +72 -0
  86. package/src/errors/index.ts +3 -0
  87. package/src/errors/locals-access-error.ts +7 -0
  88. package/src/global/app-logger.ts +4 -0
  89. package/src/global/utils.test.ts +12 -0
  90. 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
  91. package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-HMR-Server-Integration-should-load-fixture-app-page-1.png +0 -0
  92. package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-WebSocket-Connection-should-connect-to-correct-HMR-endpoint-1.png +0 -0
  93. package/src/hmr/client/hmr-runtime.ts +162 -0
  94. package/src/hmr/hmr-strategy.test.ts +124 -0
  95. package/src/hmr/hmr-strategy.ts +177 -0
  96. package/src/hmr/hmr.postcss.test.e2e.ts +41 -0
  97. package/src/hmr/hmr.test.e2e.ts +66 -0
  98. package/src/hmr/strategies/default-hmr-strategy.ts +60 -0
  99. package/src/hmr/strategies/js-hmr-strategy.test.ts +334 -0
  100. package/src/hmr/strategies/js-hmr-strategy.ts +314 -0
  101. package/src/index.browser.ts +3 -0
  102. package/src/index.ts +15 -0
  103. package/src/integrations/ghtml/ghtml-renderer.test.ts +253 -0
  104. package/src/integrations/ghtml/ghtml-renderer.ts +87 -0
  105. package/src/integrations/ghtml/ghtml.constants.ts +1 -0
  106. package/src/integrations/ghtml/ghtml.plugin.ts +28 -0
  107. package/src/plugins/alias-resolver-plugin.test.ts +41 -0
  108. package/src/plugins/alias-resolver-plugin.ts +63 -0
  109. package/src/plugins/eco-component-meta-plugin.test.ts +406 -0
  110. package/src/plugins/eco-component-meta-plugin.ts +494 -0
  111. package/src/plugins/foreign-jsx-override-plugin.test.ts +65 -0
  112. package/src/plugins/foreign-jsx-override-plugin.ts +67 -0
  113. package/src/plugins/integration-plugin.test.ts +151 -0
  114. package/src/plugins/integration-plugin.ts +323 -0
  115. package/src/plugins/processor.test.ts +148 -0
  116. package/src/plugins/processor.ts +257 -0
  117. package/src/plugins/{runtime-capability.d.ts → runtime-capability.ts} +8 -3
  118. package/src/plugins/source-transform.test.ts +82 -0
  119. package/src/plugins/source-transform.ts +123 -0
  120. package/src/route-renderer/GRAPH.md +81 -289
  121. package/src/route-renderer/README.md +67 -105
  122. package/src/route-renderer/orchestration/component-render-context.ts +325 -0
  123. package/src/route-renderer/orchestration/declared-ownership-graph.ts +62 -0
  124. package/src/route-renderer/orchestration/foreign-subtree-execution.service.ts +383 -0
  125. package/src/route-renderer/orchestration/integration-renderer.test.ts +2085 -0
  126. package/src/route-renderer/orchestration/integration-renderer.ts +1244 -0
  127. package/src/route-renderer/orchestration/ownership-planning.service.ts +97 -0
  128. package/src/route-renderer/orchestration/ownership-validation.service.ts +76 -0
  129. package/src/route-renderer/orchestration/processed-asset-dedupe.ts +25 -0
  130. package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.test.ts +324 -0
  131. package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.ts +294 -0
  132. package/src/route-renderer/orchestration/render-output.utils.ts +310 -0
  133. package/src/route-renderer/orchestration/route-render-orchestrator.prepare-render-options.test.ts +644 -0
  134. package/src/route-renderer/orchestration/route-render-orchestrator.test.ts +265 -0
  135. package/src/route-renderer/orchestration/route-render-orchestrator.ts +592 -0
  136. package/src/route-renderer/orchestration/template-serialization.test.ts +110 -0
  137. package/src/route-renderer/orchestration/template-serialization.ts +117 -0
  138. package/src/route-renderer/page-loading/component-dependency-collection.ts +202 -0
  139. package/src/route-renderer/page-loading/declared-asset-collection.ts +153 -0
  140. package/src/route-renderer/page-loading/dependency-resolver.test.ts +761 -0
  141. package/src/route-renderer/page-loading/dependency-resolver.ts +144 -0
  142. package/src/route-renderer/page-loading/ecopages-virtual-imports.ts +75 -0
  143. package/src/route-renderer/page-loading/lazy-entry-collection.ts +167 -0
  144. package/src/route-renderer/page-loading/lazy-trigger-planning.ts +74 -0
  145. package/src/route-renderer/page-loading/module-declaration-aggregation.ts +60 -0
  146. package/src/route-renderer/page-loading/module-declaration-scripts.ts +16 -0
  147. package/src/route-renderer/page-loading/page-dependency-bundling.ts +244 -0
  148. package/src/route-renderer/page-loading/page-module-loader.test.ts +183 -0
  149. package/src/route-renderer/page-loading/page-module-loader.ts +184 -0
  150. package/src/route-renderer/route-renderer.ts +133 -0
  151. package/src/router/README.md +16 -19
  152. package/src/router/client/link-intent.test.browser.ts +51 -0
  153. package/src/router/client/link-intent.ts +92 -0
  154. package/src/router/client/navigation-coordinator.test.ts +237 -0
  155. package/src/router/client/navigation-coordinator.ts +453 -0
  156. package/src/router/server/route-registry.test.ts +176 -0
  157. package/src/router/server/route-registry.ts +382 -0
  158. package/src/services/README.md +1 -2
  159. package/src/services/assets/asset-processing-service/asset-dependency-keys.ts +66 -0
  160. package/src/services/assets/asset-processing-service/asset-processing.service.test.ts +473 -0
  161. package/src/services/assets/asset-processing-service/asset-processing.service.ts +344 -0
  162. package/src/services/assets/asset-processing-service/asset.factory.test.ts +63 -0
  163. package/src/services/assets/asset-processing-service/asset.factory.ts +105 -0
  164. package/src/services/assets/asset-processing-service/assets.types.ts +128 -0
  165. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.test.ts +74 -0
  166. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.ts +96 -0
  167. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.test.ts +67 -0
  168. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.ts +78 -0
  169. package/src/services/assets/asset-processing-service/grouped-content-bundles.ts +104 -0
  170. package/src/services/assets/asset-processing-service/index.ts +6 -0
  171. package/src/services/assets/asset-processing-service/page-package.test.ts +100 -0
  172. package/src/services/assets/asset-processing-service/page-package.ts +93 -0
  173. package/src/services/assets/asset-processing-service/{processor.interface.d.ts → processor.interface.ts} +10 -5
  174. package/src/services/assets/asset-processing-service/processor.registry.ts +18 -0
  175. package/src/services/assets/asset-processing-service/processors/base/base-processor.test.ts +59 -0
  176. package/src/services/assets/asset-processing-service/processors/base/base-processor.ts +83 -0
  177. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.ts +173 -0
  178. package/src/services/assets/asset-processing-service/processors/index.ts +5 -0
  179. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.test.ts +195 -0
  180. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.ts +137 -0
  181. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.test.ts +326 -0
  182. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.ts +116 -0
  183. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.test.ts +227 -0
  184. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.ts +89 -0
  185. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.test.ts +261 -0
  186. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.ts +72 -0
  187. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.ts +83 -0
  188. package/src/services/assets/asset-processing-service/ungrouped-dependency-processing.ts +65 -0
  189. package/src/services/assets/browser-bundle.service.test.ts +66 -0
  190. package/src/services/assets/browser-bundle.service.ts +109 -0
  191. package/src/services/cache/cache.types.ts +126 -0
  192. package/src/services/cache/index.ts +18 -0
  193. package/src/services/cache/memory-cache-store.test.ts +225 -0
  194. package/src/services/cache/memory-cache-store.ts +130 -0
  195. package/src/services/cache/page-cache-service.test.ts +175 -0
  196. package/src/services/cache/page-cache-service.ts +202 -0
  197. package/src/services/cache/page-request-cache-coordinator.service.test.ts +79 -0
  198. package/src/services/cache/page-request-cache-coordinator.service.ts +131 -0
  199. package/src/services/html/html-rewriter-provider.service.test.ts +183 -0
  200. package/src/services/html/html-rewriter-provider.service.ts +104 -0
  201. package/src/services/html/html-transformer.service.test.ts +476 -0
  202. package/src/services/html/html-transformer.service.ts +275 -0
  203. package/src/services/invalidation/development-invalidation.service.test.ts +87 -0
  204. package/src/services/invalidation/development-invalidation.service.ts +262 -0
  205. package/src/services/module-loading/app-module-loader.service.ts +9 -0
  206. package/src/services/module-loading/app-server-module-transpiler.service.test.ts +130 -0
  207. package/src/services/module-loading/app-server-module-transpiler.service.ts +141 -0
  208. package/src/services/module-loading/host-module-loader-registry.ts +15 -0
  209. package/src/services/module-loading/{module-loading-types.d.ts → module-loading-types.ts} +1 -0
  210. package/src/services/module-loading/node-bootstrap-plugin.test.ts +335 -0
  211. package/src/services/module-loading/node-bootstrap-plugin.ts +311 -0
  212. package/src/services/module-loading/page-module-import.service.test.ts +504 -0
  213. package/src/services/module-loading/page-module-import.service.ts +251 -0
  214. package/src/services/module-loading/server-module-transpiler.service.test.ts +243 -0
  215. package/src/services/module-loading/server-module-transpiler.service.ts +104 -0
  216. package/src/services/module-loading/source-module-support.ts +19 -0
  217. package/src/services/runtime-state/dev-graph.service.ts +217 -0
  218. package/src/services/runtime-state/entrypoint-dependency-graph.service.ts +136 -0
  219. package/src/services/runtime-state/server-invalidation-state.service.ts +68 -0
  220. package/src/services/validation/schema-validation-service.test.ts +223 -0
  221. package/src/services/validation/schema-validation-service.ts +204 -0
  222. package/src/services/validation/{standard-schema.types.d.ts → standard-schema.types.ts} +20 -17
  223. package/src/static-site-generator/static-site-generator.test.ts +408 -0
  224. package/src/static-site-generator/static-site-generator.ts +445 -0
  225. package/src/types/internal-types.ts +243 -0
  226. package/src/types/public-types.ts +1459 -0
  227. package/src/utils/deep-merge.test.ts +114 -0
  228. package/src/utils/deep-merge.ts +47 -0
  229. package/src/utils/hash.ts +5 -0
  230. package/src/utils/html-escaping.ts +9 -0
  231. package/src/utils/invariant.test.ts +22 -0
  232. package/src/utils/invariant.ts +15 -0
  233. package/src/utils/locals-utils.ts +37 -0
  234. package/src/utils/parse-cli-args.test.ts +69 -0
  235. package/src/utils/parse-cli-args.ts +105 -0
  236. package/src/utils/path-utils.module.ts +14 -0
  237. package/src/utils/path-utils.test.ts +15 -0
  238. package/src/utils/resolve-work-dir.ts +45 -0
  239. package/src/utils/runtime.ts +44 -0
  240. package/src/utils/server-utils.module.ts +67 -0
  241. package/src/utils/server-utils.test.ts +38 -0
  242. package/src/watchers/project-watcher.integration.test.ts +337 -0
  243. package/src/watchers/project-watcher.test-helpers.ts +42 -0
  244. package/src/watchers/project-watcher.test.ts +768 -0
  245. package/src/watchers/project-watcher.ts +357 -0
  246. package/CHANGELOG.md +0 -66
  247. package/src/adapters/abstract/application-adapter.d.ts +0 -194
  248. package/src/adapters/abstract/application-adapter.js +0 -121
  249. package/src/adapters/abstract/router-adapter.d.ts +0 -26
  250. package/src/adapters/abstract/router-adapter.js +0 -5
  251. package/src/adapters/abstract/server-adapter.d.ts +0 -69
  252. package/src/adapters/abstract/server-adapter.js +0 -15
  253. package/src/adapters/bun/client-bridge.d.ts +0 -34
  254. package/src/adapters/bun/client-bridge.js +0 -48
  255. package/src/adapters/bun/create-app.d.ts +0 -52
  256. package/src/adapters/bun/create-app.js +0 -116
  257. package/src/adapters/bun/hmr-manager.d.ts +0 -143
  258. package/src/adapters/bun/hmr-manager.js +0 -333
  259. package/src/adapters/bun/index.d.ts +0 -2
  260. package/src/adapters/bun/index.js +0 -8
  261. package/src/adapters/bun/server-adapter.d.ts +0 -155
  262. package/src/adapters/bun/server-adapter.js +0 -374
  263. package/src/adapters/bun/server-lifecycle.d.ts +0 -63
  264. package/src/adapters/bun/server-lifecycle.js +0 -92
  265. package/src/adapters/create-app.d.ts +0 -20
  266. package/src/adapters/create-app.js +0 -66
  267. package/src/adapters/index.d.ts +0 -2
  268. package/src/adapters/index.js +0 -8
  269. package/src/adapters/node/create-app.d.ts +0 -18
  270. package/src/adapters/node/create-app.js +0 -149
  271. package/src/adapters/node/node-client-bridge.d.ts +0 -26
  272. package/src/adapters/node/node-client-bridge.js +0 -66
  273. package/src/adapters/node/node-hmr-manager.d.ts +0 -133
  274. package/src/adapters/node/node-hmr-manager.js +0 -311
  275. package/src/adapters/node/server-adapter.d.ts +0 -162
  276. package/src/adapters/node/server-adapter.js +0 -368
  277. package/src/adapters/node/static-content-server.d.ts +0 -60
  278. package/src/adapters/node/static-content-server.js +0 -194
  279. package/src/adapters/shared/api-response.d.ts +0 -52
  280. package/src/adapters/shared/api-response.js +0 -96
  281. package/src/adapters/shared/application-adapter.d.ts +0 -18
  282. package/src/adapters/shared/application-adapter.js +0 -90
  283. package/src/adapters/shared/define-api-handler.d.ts +0 -25
  284. package/src/adapters/shared/define-api-handler.js +0 -15
  285. package/src/adapters/shared/explicit-static-route-matcher.d.ts +0 -38
  286. package/src/adapters/shared/explicit-static-route-matcher.js +0 -103
  287. package/src/adapters/shared/file-route-middleware-pipeline.d.ts +0 -65
  288. package/src/adapters/shared/file-route-middleware-pipeline.js +0 -99
  289. package/src/adapters/shared/fs-server-response-factory.d.ts +0 -19
  290. package/src/adapters/shared/fs-server-response-factory.js +0 -97
  291. package/src/adapters/shared/fs-server-response-matcher.d.ts +0 -67
  292. package/src/adapters/shared/fs-server-response-matcher.js +0 -147
  293. package/src/adapters/shared/hmr-entrypoint-registrar.d.ts +0 -55
  294. package/src/adapters/shared/hmr-entrypoint-registrar.js +0 -87
  295. package/src/adapters/shared/hmr-html-response.d.ts +0 -22
  296. package/src/adapters/shared/hmr-html-response.js +0 -32
  297. package/src/adapters/shared/render-context.d.ts +0 -15
  298. package/src/adapters/shared/render-context.js +0 -72
  299. package/src/adapters/shared/runtime-bootstrap.d.ts +0 -38
  300. package/src/adapters/shared/runtime-bootstrap.js +0 -43
  301. package/src/adapters/shared/server-adapter.d.ts +0 -97
  302. package/src/adapters/shared/server-adapter.js +0 -390
  303. package/src/adapters/shared/server-route-handler.d.ts +0 -89
  304. package/src/adapters/shared/server-route-handler.js +0 -111
  305. package/src/adapters/shared/server-static-builder.d.ts +0 -71
  306. package/src/adapters/shared/server-static-builder.js +0 -100
  307. package/src/build/build-adapter.d.ts +0 -239
  308. package/src/build/build-adapter.js +0 -642
  309. package/src/build/build-manifest.d.ts +0 -27
  310. package/src/build/build-manifest.js +0 -30
  311. package/src/build/build-types.d.ts +0 -57
  312. package/src/build/build-types.js +0 -0
  313. package/src/build/dev-build-coordinator.d.ts +0 -72
  314. package/src/build/dev-build-coordinator.js +0 -154
  315. package/src/build/esbuild-build-adapter.d.ts +0 -78
  316. package/src/build/esbuild-build-adapter.js +0 -505
  317. package/src/build/runtime-build-executor.d.ts +0 -14
  318. package/src/build/runtime-build-executor.js +0 -22
  319. package/src/build/runtime-specifier-alias-plugin.d.ts +0 -15
  320. package/src/build/runtime-specifier-alias-plugin.js +0 -35
  321. package/src/build/runtime-specifier-aliases.d.ts +0 -5
  322. package/src/build/runtime-specifier-aliases.js +0 -95
  323. package/src/config/config-builder.d.ts +0 -252
  324. package/src/config/config-builder.js +0 -603
  325. package/src/config/constants.js +0 -25
  326. package/src/dev/sc-server.d.ts +0 -30
  327. package/src/dev/sc-server.js +0 -111
  328. package/src/eco/eco.browser.d.ts +0 -2
  329. package/src/eco/eco.browser.js +0 -83
  330. package/src/eco/eco.d.ts +0 -9
  331. package/src/eco/eco.js +0 -85
  332. package/src/eco/eco.types.d.ts +0 -178
  333. package/src/eco/eco.types.js +0 -0
  334. package/src/eco/eco.utils.d.ts +0 -1
  335. package/src/eco/eco.utils.js +0 -10
  336. package/src/eco/global-injector-map.d.ts +0 -16
  337. package/src/eco/global-injector-map.js +0 -80
  338. package/src/eco/lazy-injector-map.d.ts +0 -8
  339. package/src/eco/lazy-injector-map.js +0 -70
  340. package/src/eco/module-dependencies.d.ts +0 -18
  341. package/src/eco/module-dependencies.js +0 -49
  342. package/src/errors/http-error.d.ts +0 -31
  343. package/src/errors/http-error.js +0 -50
  344. package/src/errors/index.d.ts +0 -2
  345. package/src/errors/index.js +0 -4
  346. package/src/errors/locals-access-error.d.ts +0 -4
  347. package/src/errors/locals-access-error.js +0 -9
  348. package/src/global/app-logger.d.ts +0 -2
  349. package/src/global/app-logger.js +0 -6
  350. package/src/hmr/client/hmr-runtime.d.ts +0 -5
  351. package/src/hmr/client/hmr-runtime.js +0 -117
  352. package/src/hmr/hmr-strategy.d.ts +0 -162
  353. package/src/hmr/hmr-strategy.js +0 -44
  354. package/src/hmr/hmr.postcss.test.e2e.d.ts +0 -1
  355. package/src/hmr/hmr.postcss.test.e2e.js +0 -31
  356. package/src/hmr/hmr.test.e2e.d.ts +0 -1
  357. package/src/hmr/hmr.test.e2e.js +0 -43
  358. package/src/hmr/strategies/default-hmr-strategy.d.ts +0 -43
  359. package/src/hmr/strategies/default-hmr-strategy.js +0 -34
  360. package/src/hmr/strategies/js-hmr-strategy.d.ts +0 -139
  361. package/src/hmr/strategies/js-hmr-strategy.js +0 -178
  362. package/src/index.browser.d.ts +0 -3
  363. package/src/index.browser.js +0 -4
  364. package/src/index.d.ts +0 -6
  365. package/src/index.js +0 -21
  366. package/src/integrations/ghtml/ghtml-renderer.d.ts +0 -20
  367. package/src/integrations/ghtml/ghtml-renderer.js +0 -63
  368. package/src/integrations/ghtml/ghtml.constants.d.ts +0 -1
  369. package/src/integrations/ghtml/ghtml.constants.js +0 -4
  370. package/src/integrations/ghtml/ghtml.plugin.d.ts +0 -16
  371. package/src/integrations/ghtml/ghtml.plugin.js +0 -20
  372. package/src/plugins/alias-resolver-plugin.d.ts +0 -2
  373. package/src/plugins/alias-resolver-plugin.js +0 -53
  374. package/src/plugins/eco-component-meta-plugin.d.ts +0 -108
  375. package/src/plugins/eco-component-meta-plugin.js +0 -163
  376. package/src/plugins/foreign-jsx-override-plugin.d.ts +0 -31
  377. package/src/plugins/foreign-jsx-override-plugin.js +0 -35
  378. package/src/plugins/integration-plugin.d.ts +0 -219
  379. package/src/plugins/integration-plugin.js +0 -196
  380. package/src/plugins/processor.d.ts +0 -95
  381. package/src/plugins/processor.js +0 -136
  382. package/src/plugins/runtime-capability.js +0 -0
  383. package/src/plugins/source-transform.d.ts +0 -46
  384. package/src/plugins/source-transform.js +0 -71
  385. package/src/route-renderer/orchestration/boundary-planning.service.d.ts +0 -25
  386. package/src/route-renderer/orchestration/boundary-planning.service.js +0 -97
  387. package/src/route-renderer/orchestration/component-render-context.d.ts +0 -83
  388. package/src/route-renderer/orchestration/component-render-context.js +0 -147
  389. package/src/route-renderer/orchestration/integration-renderer.d.ts +0 -556
  390. package/src/route-renderer/orchestration/integration-renderer.js +0 -932
  391. package/src/route-renderer/orchestration/page-packaging.service.d.ts +0 -16
  392. package/src/route-renderer/orchestration/page-packaging.service.js +0 -66
  393. package/src/route-renderer/orchestration/processed-asset-dedupe.d.ts +0 -2
  394. package/src/route-renderer/orchestration/processed-asset-dedupe.js +0 -23
  395. package/src/route-renderer/orchestration/queued-boundary-runtime.service.d.ts +0 -89
  396. package/src/route-renderer/orchestration/queued-boundary-runtime.service.js +0 -155
  397. package/src/route-renderer/orchestration/render-execution.service.d.ts +0 -43
  398. package/src/route-renderer/orchestration/render-execution.service.js +0 -106
  399. package/src/route-renderer/orchestration/render-output.utils.d.ts +0 -66
  400. package/src/route-renderer/orchestration/render-output.utils.js +0 -171
  401. package/src/route-renderer/orchestration/render-preparation.service.d.ts +0 -120
  402. package/src/route-renderer/orchestration/render-preparation.service.js +0 -364
  403. package/src/route-renderer/orchestration/route-shell-composer.service.d.ts +0 -50
  404. package/src/route-renderer/orchestration/route-shell-composer.service.js +0 -81
  405. package/src/route-renderer/orchestration/template-serialization.d.ts +0 -38
  406. package/src/route-renderer/orchestration/template-serialization.js +0 -45
  407. package/src/route-renderer/page-loading/component-dependency-collection.d.ts +0 -37
  408. package/src/route-renderer/page-loading/component-dependency-collection.js +0 -125
  409. package/src/route-renderer/page-loading/declared-asset-collection.d.ts +0 -24
  410. package/src/route-renderer/page-loading/declared-asset-collection.js +0 -106
  411. package/src/route-renderer/page-loading/dependency-resolver.d.ts +0 -35
  412. package/src/route-renderer/page-loading/dependency-resolver.js +0 -117
  413. package/src/route-renderer/page-loading/ecopages-virtual-imports.d.ts +0 -11
  414. package/src/route-renderer/page-loading/ecopages-virtual-imports.js +0 -57
  415. package/src/route-renderer/page-loading/lazy-entry-collection.d.ts +0 -45
  416. package/src/route-renderer/page-loading/lazy-entry-collection.js +0 -105
  417. package/src/route-renderer/page-loading/lazy-trigger-planning.d.ts +0 -19
  418. package/src/route-renderer/page-loading/lazy-trigger-planning.js +0 -40
  419. package/src/route-renderer/page-loading/module-declaration-aggregation.d.ts +0 -5
  420. package/src/route-renderer/page-loading/module-declaration-aggregation.js +0 -33
  421. package/src/route-renderer/page-loading/module-declaration-scripts.d.ts +0 -3
  422. package/src/route-renderer/page-loading/module-declaration-scripts.js +0 -18
  423. package/src/route-renderer/page-loading/page-dependency-bundling.d.ts +0 -13
  424. package/src/route-renderer/page-loading/page-dependency-bundling.js +0 -115
  425. package/src/route-renderer/page-loading/page-module-loader.d.ts +0 -90
  426. package/src/route-renderer/page-loading/page-module-loader.js +0 -127
  427. package/src/route-renderer/route-renderer.d.ts +0 -67
  428. package/src/route-renderer/route-renderer.js +0 -103
  429. package/src/router/client/link-intent.js +0 -34
  430. package/src/router/client/link-intent.test.browser.d.ts +0 -1
  431. package/src/router/client/link-intent.test.browser.js +0 -43
  432. package/src/router/client/navigation-coordinator.d.ts +0 -169
  433. package/src/router/client/navigation-coordinator.js +0 -215
  434. package/src/router/server/fs-router-scanner.d.ts +0 -41
  435. package/src/router/server/fs-router-scanner.js +0 -161
  436. package/src/router/server/fs-router.d.ts +0 -26
  437. package/src/router/server/fs-router.js +0 -100
  438. package/src/services/assets/asset-processing-service/asset-dependency-keys.d.ts +0 -3
  439. package/src/services/assets/asset-processing-service/asset-dependency-keys.js +0 -56
  440. package/src/services/assets/asset-processing-service/asset-processing.service.d.ts +0 -103
  441. package/src/services/assets/asset-processing-service/asset-processing.service.js +0 -285
  442. package/src/services/assets/asset-processing-service/asset.factory.d.ts +0 -17
  443. package/src/services/assets/asset-processing-service/asset.factory.js +0 -82
  444. package/src/services/assets/asset-processing-service/assets.types.d.ts +0 -100
  445. package/src/services/assets/asset-processing-service/assets.types.js +0 -0
  446. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.d.ts +0 -55
  447. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +0 -49
  448. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.d.ts +0 -20
  449. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.js +0 -41
  450. package/src/services/assets/asset-processing-service/grouped-content-bundles.d.ts +0 -30
  451. package/src/services/assets/asset-processing-service/grouped-content-bundles.js +0 -65
  452. package/src/services/assets/asset-processing-service/index.d.ts +0 -5
  453. package/src/services/assets/asset-processing-service/index.js +0 -5
  454. package/src/services/assets/asset-processing-service/processor.interface.js +0 -6
  455. package/src/services/assets/asset-processing-service/processor.registry.d.ts +0 -8
  456. package/src/services/assets/asset-processing-service/processor.registry.js +0 -15
  457. package/src/services/assets/asset-processing-service/processors/base/base-processor.d.ts +0 -24
  458. package/src/services/assets/asset-processing-service/processors/base/base-processor.js +0 -65
  459. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.d.ts +0 -22
  460. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.js +0 -136
  461. package/src/services/assets/asset-processing-service/processors/index.d.ts +0 -5
  462. package/src/services/assets/asset-processing-service/processors/index.js +0 -5
  463. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.d.ts +0 -6
  464. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.js +0 -116
  465. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.d.ts +0 -9
  466. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +0 -91
  467. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.d.ts +0 -7
  468. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +0 -77
  469. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.d.ts +0 -8
  470. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +0 -58
  471. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.d.ts +0 -9
  472. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +0 -67
  473. package/src/services/assets/asset-processing-service/ungrouped-dependency-processing.d.ts +0 -18
  474. package/src/services/assets/asset-processing-service/ungrouped-dependency-processing.js +0 -45
  475. package/src/services/assets/browser-bundle.service.d.ts +0 -73
  476. package/src/services/assets/browser-bundle.service.js +0 -41
  477. package/src/services/cache/cache.types.d.ts +0 -107
  478. package/src/services/cache/cache.types.js +0 -0
  479. package/src/services/cache/index.d.ts +0 -7
  480. package/src/services/cache/index.js +0 -7
  481. package/src/services/cache/memory-cache-store.d.ts +0 -42
  482. package/src/services/cache/memory-cache-store.js +0 -98
  483. package/src/services/cache/page-cache-service.d.ts +0 -70
  484. package/src/services/cache/page-cache-service.js +0 -152
  485. package/src/services/cache/page-request-cache-coordinator.service.d.ts +0 -75
  486. package/src/services/cache/page-request-cache-coordinator.service.js +0 -109
  487. package/src/services/html/html-rewriter-provider.service.d.ts +0 -37
  488. package/src/services/html/html-rewriter-provider.service.js +0 -68
  489. package/src/services/html/html-transformer.service.d.ts +0 -87
  490. package/src/services/html/html-transformer.service.js +0 -216
  491. package/src/services/invalidation/development-invalidation.service.d.ts +0 -74
  492. package/src/services/invalidation/development-invalidation.service.js +0 -190
  493. package/src/services/module-loading/app-module-loader.service.d.ts +0 -7
  494. package/src/services/module-loading/app-module-loader.service.js +0 -0
  495. package/src/services/module-loading/app-server-module-transpiler.service.d.ts +0 -24
  496. package/src/services/module-loading/app-server-module-transpiler.service.js +0 -115
  497. package/src/services/module-loading/host-module-loader-registry.d.ts +0 -4
  498. package/src/services/module-loading/host-module-loader-registry.js +0 -15
  499. package/src/services/module-loading/module-loading-types.js +0 -0
  500. package/src/services/module-loading/node-bootstrap-plugin.d.ts +0 -42
  501. package/src/services/module-loading/node-bootstrap-plugin.js +0 -204
  502. package/src/services/module-loading/page-module-import.service.d.ts +0 -76
  503. package/src/services/module-loading/page-module-import.service.js +0 -170
  504. package/src/services/module-loading/server-module-transpiler.service.d.ts +0 -63
  505. package/src/services/module-loading/server-module-transpiler.service.js +0 -64
  506. package/src/services/module-loading/source-module-support.d.ts +0 -5
  507. package/src/services/module-loading/source-module-support.js +0 -8
  508. package/src/services/runtime-state/dev-graph.service.d.ts +0 -118
  509. package/src/services/runtime-state/dev-graph.service.js +0 -162
  510. package/src/services/runtime-state/entrypoint-dependency-graph.service.d.ts +0 -41
  511. package/src/services/runtime-state/entrypoint-dependency-graph.service.js +0 -85
  512. package/src/services/runtime-state/runtime-specifier-registry.service.d.ts +0 -69
  513. package/src/services/runtime-state/runtime-specifier-registry.service.js +0 -37
  514. package/src/services/runtime-state/server-invalidation-state.service.d.ts +0 -26
  515. package/src/services/runtime-state/server-invalidation-state.service.js +0 -35
  516. package/src/services/validation/schema-validation-service.d.ts +0 -122
  517. package/src/services/validation/schema-validation-service.js +0 -101
  518. package/src/services/validation/standard-schema.types.js +0 -0
  519. package/src/static-site-generator/static-site-generator.d.ts +0 -105
  520. package/src/static-site-generator/static-site-generator.js +0 -349
  521. package/src/types/internal-types.d.ts +0 -231
  522. package/src/types/internal-types.js +0 -0
  523. package/src/types/public-types.d.ts +0 -1257
  524. package/src/types/public-types.js +0 -0
  525. package/src/utils/deep-merge.d.ts +0 -14
  526. package/src/utils/deep-merge.js +0 -32
  527. package/src/utils/hash.d.ts +0 -1
  528. package/src/utils/hash.js +0 -7
  529. package/src/utils/html-escaping.d.ts +0 -7
  530. package/src/utils/html-escaping.js +0 -6
  531. package/src/utils/html.js +0 -4
  532. package/src/utils/invariant.d.ts +0 -5
  533. package/src/utils/invariant.js +0 -11
  534. package/src/utils/locals-utils.d.ts +0 -15
  535. package/src/utils/locals-utils.js +0 -24
  536. package/src/utils/parse-cli-args.d.ts +0 -27
  537. package/src/utils/parse-cli-args.js +0 -62
  538. package/src/utils/path-utils.module.d.ts +0 -5
  539. package/src/utils/path-utils.module.js +0 -14
  540. package/src/utils/resolve-work-dir.d.ts +0 -11
  541. package/src/utils/resolve-work-dir.js +0 -31
  542. package/src/utils/runtime.d.ts +0 -11
  543. package/src/utils/runtime.js +0 -40
  544. package/src/utils/server-utils.module.d.ts +0 -19
  545. package/src/utils/server-utils.module.js +0 -56
  546. package/src/watchers/project-watcher.d.ts +0 -136
  547. package/src/watchers/project-watcher.js +0 -275
  548. package/src/watchers/project-watcher.test-helpers.d.ts +0 -4
  549. package/src/watchers/project-watcher.test-helpers.js +0 -52
  550. /package/src/utils/{html.d.ts → html.ts} +0 -0
@@ -0,0 +1,761 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+ import { join } from 'node:path';
3
+ import { tmpdir } from 'node:os';
4
+ import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
5
+ import { DEPENDENCY_ERRORS, DependencyResolverService } from './dependency-resolver.ts';
6
+ import type { EcoPagesAppConfig } from '../../types/internal-types.ts';
7
+ import type {
8
+ AssetDefinition,
9
+ AssetProcessingService,
10
+ ProcessedAsset,
11
+ ContentScriptAsset,
12
+ InlineContentScriptAsset,
13
+ } from '../../services/assets/asset-processing-service/index.ts';
14
+ import type { EcoComponent } from '../../types/public-types.ts';
15
+
16
+ describe('DependencyResolverService', () => {
17
+ const appConfig = {
18
+ srcDir: '/app',
19
+ } as EcoPagesAppConfig;
20
+
21
+ it('should resolve dependency and lazy script paths', () => {
22
+ const assetProcessingService = {
23
+ processDependencies: vi.fn(async () => []),
24
+ } as unknown as AssetProcessingService;
25
+ const service = new DependencyResolverService(appConfig, assetProcessingService);
26
+
27
+ expect(service.resolveDependencyPath('/app/components/card', './style.css')).toBe(
28
+ '/app/components/card/style.css',
29
+ );
30
+ expect(service.resolveLazyScripts('/app/components/card', ['./client.ts', './widget.tsx'])).toBe(
31
+ '/assets/components/card/client.js,/assets/components/card/widget.js',
32
+ );
33
+ });
34
+
35
+ it('should emit module dependencies as content scripts and resolve lazy triggers by default', async () => {
36
+ let capturedDeps: AssetDefinition[] = [];
37
+ const assetProcessingService = {
38
+ processDependencies: vi.fn(async (deps: AssetDefinition[]) => {
39
+ capturedDeps = deps;
40
+ return [
41
+ {
42
+ kind: 'script',
43
+ filepath: '/app/components/table/table.client.ts',
44
+ srcUrl: '/assets/components/table/table.client.js',
45
+ },
46
+ ] as ProcessedAsset[];
47
+ }),
48
+ } as unknown as AssetProcessingService;
49
+ const service = new DependencyResolverService(appConfig, assetProcessingService);
50
+
51
+ const component = ((_) => '<table></table>') as EcoComponent<Record<string, unknown>>;
52
+ component.config = {
53
+ __eco: {
54
+ id: 'table',
55
+ integration: 'react',
56
+ file: '/app/components/table/table.tsx',
57
+ },
58
+ dependencies: {
59
+ modules: ['react-aria-components{Table,Button}', './client-utils'],
60
+ scripts: [{ src: './table.client.ts', lazy: { 'on:interaction': 'click' } }],
61
+ },
62
+ };
63
+
64
+ await service.processComponentDependencies([component], 'react');
65
+
66
+ const contentScripts = capturedDeps.filter(
67
+ (dep): dep is ContentScriptAsset => dep.kind === 'script' && dep.source === 'content',
68
+ );
69
+
70
+ expect(
71
+ contentScripts.some((script) =>
72
+ script.content.includes("export { Button, Table } from 'react-aria-components';"),
73
+ ),
74
+ ).toBe(true);
75
+ expect(contentScripts.some((script) => script.content.includes("export * from './client-utils';"))).toBe(true);
76
+ expect(contentScripts.every((script) => /^module-[a-f0-9]+$/.test(script.name ?? ''))).toBe(true);
77
+
78
+ const hasInjector = capturedDeps.some(
79
+ (dep) =>
80
+ dep.kind === 'script' &&
81
+ dep.source === 'node-module' &&
82
+ dep.importPath === '@ecopages/scripts-injector',
83
+ );
84
+ expect(hasInjector).toBe(false);
85
+
86
+ expect(component.config._resolvedLazyScripts).toBeUndefined();
87
+ expect(component.config._resolvedLazyTriggers).toHaveLength(1);
88
+ expect(component.config._resolvedLazyTriggers?.[0]?.rules).toEqual([
89
+ {
90
+ 'on:interaction': {
91
+ value: 'click',
92
+ scripts: ['/assets/components/table/table.client.js'],
93
+ },
94
+ },
95
+ ]);
96
+ });
97
+
98
+ it('should canonicalize generated module script content across different import orders', async () => {
99
+ const captureModuleScriptContent = async (modules: string[]) => {
100
+ let capturedDeps: AssetDefinition[] = [];
101
+ const assetProcessingService = {
102
+ processDependencies: vi.fn(async (deps: AssetDefinition[]) => {
103
+ capturedDeps = deps;
104
+ return [] as ProcessedAsset[];
105
+ }),
106
+ } as unknown as AssetProcessingService;
107
+
108
+ const service = new DependencyResolverService(appConfig, assetProcessingService);
109
+ const component = ((_) => '<div></div>') as EcoComponent<Record<string, unknown>>;
110
+ component.config = {
111
+ __eco: {
112
+ id: 'module-order',
113
+ integration: 'react',
114
+ file: '/app/components/module-order/component.tsx',
115
+ },
116
+ dependencies: {
117
+ modules,
118
+ },
119
+ };
120
+
121
+ await service.processComponentDependencies([component], 'react');
122
+
123
+ return capturedDeps
124
+ .filter((dep): dep is ContentScriptAsset => dep.kind === 'script' && dep.source === 'content')
125
+ .map((dep) => dep.content)
126
+ .find((content) => content.includes("from 'react-aria-components';"));
127
+ };
128
+
129
+ const firstContent = await captureModuleScriptContent(['react-aria-components{Table,Button}']);
130
+ const secondContent = await captureModuleScriptContent(['react-aria-components{Button,Table}']);
131
+
132
+ expect(firstContent).toBe("export { Button, Table } from 'react-aria-components';");
133
+ expect(secondContent).toBe(firstContent);
134
+ });
135
+
136
+ it('should detect ecopages virtual imports via parser', async () => {
137
+ const tempDir = mkdtempSync(join(tmpdir(), 'ecopages-dependency-resolver-'));
138
+ const componentFile = join(tempDir, 'component.tsx');
139
+
140
+ writeFileSync(
141
+ componentFile,
142
+ "import { heroImage as imageAsset } from 'ecopages:images';\nexport const ok = imageAsset.src;\n",
143
+ 'utf-8',
144
+ );
145
+
146
+ let capturedDeps: AssetDefinition[] = [];
147
+ const assetProcessingService = {
148
+ processDependencies: vi.fn(async (deps: AssetDefinition[]) => {
149
+ capturedDeps = deps;
150
+ return [] as ProcessedAsset[];
151
+ }),
152
+ } as unknown as AssetProcessingService;
153
+
154
+ const service = new DependencyResolverService(appConfig, assetProcessingService);
155
+ const component = ((_) => '<div></div>') as EcoComponent<Record<string, unknown>>;
156
+ component.config = {
157
+ __eco: {
158
+ id: 'component',
159
+ integration: 'react',
160
+ file: componentFile,
161
+ },
162
+ };
163
+
164
+ try {
165
+ await service.processComponentDependencies([component], 'react');
166
+
167
+ const contentScripts = capturedDeps.filter(
168
+ (dep): dep is ContentScriptAsset => dep.kind === 'script' && dep.source === 'content',
169
+ );
170
+
171
+ expect(contentScripts.some((script) => script.content.includes("from 'ecopages:images';"))).toBe(true);
172
+ } finally {
173
+ rmSync(tempDir, { recursive: true, force: true });
174
+ }
175
+ });
176
+
177
+ it('should keep ecopages-jsx page and lazy dependency bundles separate', async () => {
178
+ const tempDir = mkdtempSync(join(tmpdir(), 'ecopages-jsx-script-dedupe-'));
179
+ const componentFile = join(tempDir, 'component.tsx');
180
+ const widgetScript = join(tempDir, 'widget.script.ts');
181
+ const siblingScript = join(tempDir, 'other.ts');
182
+ const lazyScript = join(tempDir, 'lazy.ts');
183
+
184
+ writeFileSync(componentFile, "import './widget.script';\nexport const Component = () => null;\n", 'utf-8');
185
+ writeFileSync(widgetScript, 'export const widget = true;\n', 'utf-8');
186
+ writeFileSync(siblingScript, 'export const other = true;\n', 'utf-8');
187
+ writeFileSync(lazyScript, 'export const lazy = true;\n', 'utf-8');
188
+
189
+ let capturedDeps: AssetDefinition[] = [];
190
+ const assetProcessingService = {
191
+ processDependencies: vi.fn(async (deps: AssetDefinition[]) => {
192
+ capturedDeps = deps;
193
+ return [] as ProcessedAsset[];
194
+ }),
195
+ } as unknown as AssetProcessingService;
196
+
197
+ const service = new DependencyResolverService(appConfig, assetProcessingService);
198
+ const component = ((_) => '<div></div>') as EcoComponent<Record<string, unknown>>;
199
+ component.config = {
200
+ __eco: {
201
+ id: 'imported-script',
202
+ integration: 'ecopages-jsx',
203
+ file: componentFile,
204
+ },
205
+ dependencies: {
206
+ scripts: [
207
+ './widget.script.ts',
208
+ './other.ts',
209
+ { src: './lazy.ts', lazy: { 'on:interaction': 'click' } },
210
+ ],
211
+ },
212
+ };
213
+
214
+ try {
215
+ await service.processComponentDependencies([component], 'ecopages-jsx');
216
+
217
+ const fileScripts = capturedDeps.filter(
218
+ (dep): dep is Extract<AssetDefinition, { kind: 'script'; source: 'file' }> =>
219
+ dep.kind === 'script' && dep.source === 'file',
220
+ );
221
+ const contentScripts = capturedDeps.filter(
222
+ (dep): dep is Extract<AssetDefinition, { kind: 'script'; source: 'content' }> =>
223
+ dep.kind === 'script' && dep.source === 'content',
224
+ );
225
+
226
+ expect(fileScripts).toEqual([
227
+ expect.objectContaining({
228
+ filepath: widgetScript,
229
+ }),
230
+ expect.objectContaining({
231
+ filepath: siblingScript,
232
+ }),
233
+ ]);
234
+
235
+ expect(contentScripts).toHaveLength(1);
236
+
237
+ const lazyEntry = contentScripts.find((dep) => dep.excludeFromHtml === true);
238
+
239
+ expect(lazyEntry).toEqual(
240
+ expect.objectContaining({
241
+ content: `import ${JSON.stringify(lazyScript)};`,
242
+ excludeFromHtml: true,
243
+ bundleOptions: {
244
+ splitting: false,
245
+ },
246
+ }),
247
+ );
248
+
249
+ expect(lazyEntry?.groupedBundle).toBeUndefined();
250
+ } finally {
251
+ rmSync(tempDir, { recursive: true, force: true });
252
+ }
253
+ });
254
+
255
+ it('should not promote SSR-imported lazy ecopages-jsx scripts into the page bundle', async () => {
256
+ const tempDir = mkdtempSync(join(tmpdir(), 'ecopages-jsx-lazy-imported-script-'));
257
+ const componentFile = join(tempDir, 'component.tsx');
258
+ const lazyScript = join(tempDir, 'theme-toggle.script.ts');
259
+
260
+ writeFileSync(
261
+ componentFile,
262
+ "import './theme-toggle.script';\nexport const Component = () => null;\n",
263
+ 'utf-8',
264
+ );
265
+ writeFileSync(lazyScript, 'export const themeToggle = true;\n', 'utf-8');
266
+
267
+ let capturedDeps: AssetDefinition[] = [];
268
+ const assetProcessingService = {
269
+ processDependencies: vi.fn(async (deps: AssetDefinition[]) => {
270
+ capturedDeps = deps;
271
+ return [] as ProcessedAsset[];
272
+ }),
273
+ } as unknown as AssetProcessingService;
274
+
275
+ const service = new DependencyResolverService(appConfig, assetProcessingService);
276
+ const component = ((_) => '<div></div>') as EcoComponent<Record<string, unknown>>;
277
+ component.config = {
278
+ __eco: {
279
+ id: 'imported-lazy-script',
280
+ integration: 'ecopages-jsx',
281
+ file: componentFile,
282
+ },
283
+ dependencies: {
284
+ scripts: [{ src: './theme-toggle.script.ts', lazy: { 'on:interaction': 'click' } }],
285
+ },
286
+ };
287
+
288
+ try {
289
+ await service.processComponentDependencies([component], 'ecopages-jsx');
290
+
291
+ const contentScripts = capturedDeps.filter(
292
+ (dep): dep is Extract<AssetDefinition, { kind: 'script'; source: 'content' }> =>
293
+ dep.kind === 'script' && dep.source === 'content',
294
+ );
295
+
296
+ expect(contentScripts).toHaveLength(1);
297
+ expect(contentScripts[0]).toEqual(
298
+ expect.objectContaining({
299
+ content: `import ${JSON.stringify(lazyScript)};`,
300
+ excludeFromHtml: true,
301
+ }),
302
+ );
303
+ expect(contentScripts[0]?.packageRole).toBeUndefined();
304
+ } finally {
305
+ rmSync(tempDir, { recursive: true, force: true });
306
+ }
307
+ });
308
+
309
+ it('should ignore ecopages-jsx SSR imports that are not declared in dependencies', async () => {
310
+ const tempDir = mkdtempSync(join(tmpdir(), 'ecopages-jsx-undeclared-import-'));
311
+ const componentFile = join(tempDir, 'component.tsx');
312
+ const declaredScript = join(tempDir, 'declared.ts');
313
+
314
+ writeFileSync(
315
+ componentFile,
316
+ "import './theme-toggle.script';\nimport './not-declared.script';\nexport const Component = () => null;\n",
317
+ 'utf-8',
318
+ );
319
+ writeFileSync(declaredScript, 'export const declared = true;\n', 'utf-8');
320
+
321
+ let capturedDeps: AssetDefinition[] = [];
322
+ const assetProcessingService = {
323
+ processDependencies: vi.fn(async (deps: AssetDefinition[]) => {
324
+ capturedDeps = deps;
325
+ return [] as ProcessedAsset[];
326
+ }),
327
+ } as unknown as AssetProcessingService;
328
+
329
+ const service = new DependencyResolverService(appConfig, assetProcessingService);
330
+ const component = ((_) => '<div></div>') as EcoComponent<Record<string, unknown>>;
331
+ component.config = {
332
+ __eco: {
333
+ id: 'undeclared-import',
334
+ integration: 'ecopages-jsx',
335
+ file: componentFile,
336
+ },
337
+ dependencies: {
338
+ scripts: ['./declared.ts'],
339
+ },
340
+ };
341
+
342
+ try {
343
+ await service.processComponentDependencies([component], 'ecopages-jsx');
344
+
345
+ const fileScripts = capturedDeps.filter(
346
+ (dep): dep is Extract<AssetDefinition, { kind: 'script'; source: 'file' }> =>
347
+ dep.kind === 'script' && dep.source === 'file',
348
+ );
349
+
350
+ expect(fileScripts).toHaveLength(1);
351
+ expect(fileScripts[0]?.filepath).toBe(declaredScript);
352
+ } finally {
353
+ rmSync(tempDir, { recursive: true, force: true });
354
+ }
355
+ });
356
+
357
+ it('should pass entry attributes and support inline stylesheet content', async () => {
358
+ let capturedDeps: AssetDefinition[] = [];
359
+ const assetProcessingService = {
360
+ processDependencies: vi.fn(async (deps: AssetDefinition[]) => {
361
+ capturedDeps = deps;
362
+ return [] as ProcessedAsset[];
363
+ }),
364
+ } as unknown as AssetProcessingService;
365
+
366
+ const service = new DependencyResolverService(appConfig, assetProcessingService);
367
+ const component = ((_) => '<div></div>') as EcoComponent<Record<string, unknown>>;
368
+ component.config = {
369
+ __eco: {
370
+ id: 'attrs-inline',
371
+ integration: 'react',
372
+ file: '/app/components/attrs-inline/component.tsx',
373
+ },
374
+ dependencies: {
375
+ scripts: [
376
+ {
377
+ src: './client.ts',
378
+ attributes: {
379
+ async: '',
380
+ 'data-script-id': 'main-client',
381
+ },
382
+ },
383
+ ],
384
+ stylesheets: [
385
+ {
386
+ src: './styles.css',
387
+ attributes: {
388
+ media: 'print',
389
+ },
390
+ },
391
+ {
392
+ content: 'body { background: red; }',
393
+ attributes: {
394
+ media: 'screen',
395
+ },
396
+ },
397
+ ],
398
+ },
399
+ };
400
+
401
+ await service.processComponentDependencies([component], 'react');
402
+
403
+ expect(
404
+ capturedDeps.some((dep) => {
405
+ if (dep.kind !== 'script' || dep.source !== 'file') return false;
406
+ return (
407
+ dep.filepath === '/app/components/attrs-inline/client.ts' &&
408
+ dep.attributes?.type === 'module' &&
409
+ dep.attributes?.defer === '' &&
410
+ dep.attributes?.async === '' &&
411
+ dep.attributes?.['data-script-id'] === 'main-client'
412
+ );
413
+ }),
414
+ ).toBe(true);
415
+
416
+ expect(
417
+ capturedDeps.some((dep) => {
418
+ if (dep.kind !== 'stylesheet' || dep.source !== 'file') return false;
419
+ return (
420
+ dep.filepath === '/app/components/attrs-inline/styles.css' &&
421
+ dep.attributes?.rel === 'stylesheet' &&
422
+ dep.attributes?.media === 'print'
423
+ );
424
+ }),
425
+ ).toBe(true);
426
+
427
+ expect(
428
+ capturedDeps.some((dep) => {
429
+ if (dep.kind !== 'stylesheet' || dep.source !== 'content') return false;
430
+ return dep.content === 'body { background: red; }' && dep.attributes?.media === 'screen';
431
+ }),
432
+ ).toBe(true);
433
+ });
434
+
435
+ it('should collapse bundleable page stylesheets and scripts into page-owned assets', async () => {
436
+ const previousNodeEnv = process.env.NODE_ENV;
437
+ process.env.NODE_ENV = 'production';
438
+ const tempDir = mkdtempSync(join(tmpdir(), 'ecopages-page-bundle-'));
439
+ const componentFile = join(tempDir, 'component.tsx');
440
+ const stylesheetA = join(tempDir, 'first.css');
441
+ const stylesheetB = join(tempDir, 'second.css');
442
+ const scriptA = join(tempDir, 'first.ts');
443
+ const scriptB = join(tempDir, 'second.ts');
444
+
445
+ writeFileSync(componentFile, 'export const Component = () => null;', 'utf-8');
446
+ writeFileSync(stylesheetA, '.first { color: red; }', 'utf-8');
447
+ writeFileSync(stylesheetB, '.second { color: blue; }', 'utf-8');
448
+ writeFileSync(scriptA, 'export const first = true;', 'utf-8');
449
+ writeFileSync(scriptB, 'export const second = true;', 'utf-8');
450
+
451
+ let capturedDeps: AssetDefinition[] = [];
452
+ const assetProcessingService = {
453
+ processDependencies: vi.fn(async (deps: AssetDefinition[]) => {
454
+ capturedDeps = deps;
455
+ return [] as ProcessedAsset[];
456
+ }),
457
+ } as unknown as AssetProcessingService;
458
+
459
+ const bundleAppConfig = {
460
+ ...appConfig,
461
+ rootDir: tempDir,
462
+ absolutePaths: {
463
+ srcDir: tempDir,
464
+ distDir: join(tempDir, '.eco/public'),
465
+ },
466
+ } as EcoPagesAppConfig;
467
+
468
+ const service = new DependencyResolverService(bundleAppConfig, assetProcessingService);
469
+ const component = ((_) => '<div></div>') as EcoComponent<Record<string, unknown>>;
470
+ component.config = {
471
+ __eco: {
472
+ id: 'page-bundle',
473
+ integration: 'react',
474
+ file: componentFile,
475
+ },
476
+ dependencies: {
477
+ stylesheets: ['./first.css', './second.css'],
478
+ scripts: ['./first.ts', './second.ts'],
479
+ },
480
+ };
481
+
482
+ try {
483
+ await service.processComponentDependencies([component], 'react');
484
+
485
+ expect(capturedDeps).toEqual([
486
+ expect.objectContaining({
487
+ kind: 'stylesheet',
488
+ source: 'content',
489
+ packageRole: 'page-style',
490
+ content: '.first { color: red; }\n.second { color: blue; }',
491
+ bundledSourceFilepaths: [stylesheetA, stylesheetB],
492
+ }),
493
+ expect.objectContaining({
494
+ kind: 'script',
495
+ source: 'content',
496
+ packageRole: 'page-script',
497
+ content: `import ${JSON.stringify(scriptA)};\nimport ${JSON.stringify(scriptB)};`,
498
+ bundledSourceFilepaths: [scriptA, scriptB],
499
+ }),
500
+ ]);
501
+ } finally {
502
+ process.env.NODE_ENV = previousNodeEnv;
503
+ rmSync(tempDir, { recursive: true, force: true });
504
+ }
505
+ });
506
+
507
+ it('should keep bundleable page stylesheets and scripts as file assets during development', async () => {
508
+ const previousNodeEnv = process.env.NODE_ENV;
509
+ process.env.NODE_ENV = 'development';
510
+ const tempDir = mkdtempSync(join(tmpdir(), 'ecopages-page-style-dev-'));
511
+ const componentFile = join(tempDir, 'component.tsx');
512
+ const stylesheetA = join(tempDir, 'first.css');
513
+ const stylesheetB = join(tempDir, 'second.css');
514
+ const scriptA = join(tempDir, 'first.ts');
515
+ const scriptB = join(tempDir, 'second.ts');
516
+
517
+ writeFileSync(componentFile, 'export const Component = () => null;', 'utf-8');
518
+ writeFileSync(stylesheetA, '.first { color: red; }', 'utf-8');
519
+ writeFileSync(stylesheetB, '.second { color: blue; }', 'utf-8');
520
+ writeFileSync(scriptA, 'export const first = true;', 'utf-8');
521
+ writeFileSync(scriptB, 'export const second = true;', 'utf-8');
522
+
523
+ let capturedDeps: AssetDefinition[] = [];
524
+ const assetProcessingService = {
525
+ processDependencies: vi.fn(async (deps: AssetDefinition[]) => {
526
+ capturedDeps = deps;
527
+ return [] as ProcessedAsset[];
528
+ }),
529
+ } as unknown as AssetProcessingService;
530
+
531
+ const bundleAppConfig = {
532
+ ...appConfig,
533
+ rootDir: tempDir,
534
+ absolutePaths: {
535
+ srcDir: tempDir,
536
+ distDir: join(tempDir, '.eco/public'),
537
+ },
538
+ } as EcoPagesAppConfig;
539
+
540
+ const service = new DependencyResolverService(bundleAppConfig, assetProcessingService);
541
+ const component = ((_) => '<div></div>') as EcoComponent<Record<string, unknown>>;
542
+ component.config = {
543
+ __eco: {
544
+ id: 'page-style-dev',
545
+ integration: 'react',
546
+ file: componentFile,
547
+ },
548
+ dependencies: {
549
+ stylesheets: ['./first.css', './second.css'],
550
+ scripts: ['./first.ts', './second.ts'],
551
+ },
552
+ };
553
+
554
+ try {
555
+ await service.processComponentDependencies([component], 'react');
556
+
557
+ expect(capturedDeps).toEqual([
558
+ expect.objectContaining({
559
+ kind: 'stylesheet',
560
+ source: 'file',
561
+ filepath: stylesheetA,
562
+ }),
563
+ expect.objectContaining({
564
+ kind: 'stylesheet',
565
+ source: 'file',
566
+ filepath: stylesheetB,
567
+ }),
568
+ expect.objectContaining({
569
+ kind: 'script',
570
+ source: 'file',
571
+ filepath: scriptA,
572
+ }),
573
+ expect.objectContaining({
574
+ kind: 'script',
575
+ source: 'file',
576
+ filepath: scriptB,
577
+ }),
578
+ ]);
579
+ } finally {
580
+ process.env.NODE_ENV = previousNodeEnv;
581
+ rmSync(tempDir, { recursive: true, force: true });
582
+ }
583
+ });
584
+
585
+ it('should reject lazy script entry without src or content', async () => {
586
+ const assetProcessingService = {
587
+ processDependencies: vi.fn(async () => [] as ProcessedAsset[]),
588
+ } as unknown as AssetProcessingService;
589
+
590
+ const service = new DependencyResolverService(appConfig, assetProcessingService);
591
+ const component = ((_) => '<div></div>') as EcoComponent<Record<string, unknown>>;
592
+ component.config = {
593
+ __eco: {
594
+ id: 'invalid-lazy-entry',
595
+ integration: 'react',
596
+ file: '/app/components/invalid-lazy-entry/component.tsx',
597
+ },
598
+ dependencies: {
599
+ scripts: [
600
+ {
601
+ lazy: { 'on:idle': true },
602
+ },
603
+ ],
604
+ },
605
+ };
606
+
607
+ await expect(service.processComponentDependencies([component], 'react')).rejects.toThrow(
608
+ DEPENDENCY_ERRORS.LAZY_SCRIPT_MISSING_SRC,
609
+ );
610
+ });
611
+
612
+ it('should resolve lazy triggers by group, including lazy content entries', async () => {
613
+ const assetProcessingService = {
614
+ processDependencies: vi.fn(async (deps: AssetDefinition[]) => {
615
+ return deps.map((dep, index) => {
616
+ const lazyKey = dep.attributes?.['data-eco-lazy-key'];
617
+ const hasContent = dep.source === 'content' && typeof (dep as any).content === 'string';
618
+ const isLazyScript = dep.kind === 'script' && Boolean(lazyKey);
619
+ const srcUrl = isLazyScript
620
+ ? hasContent
621
+ ? `/assets/lazy/content-${index}.js`
622
+ : `/assets/lazy/file-${index}.js`
623
+ : undefined;
624
+
625
+ return {
626
+ kind: dep.kind ?? 'script',
627
+ filepath: (dep as Record<string, any>).filepath,
628
+ attributes: dep.attributes,
629
+ srcUrl,
630
+ } as ProcessedAsset;
631
+ });
632
+ }),
633
+ } as unknown as AssetProcessingService;
634
+
635
+ const service = new DependencyResolverService(appConfig, assetProcessingService);
636
+ const component = ((_) => '<div></div>') as EcoComponent<Record<string, unknown>>;
637
+ component.config = {
638
+ __eco: {
639
+ id: 'multi-lazy-groups',
640
+ integration: 'lit',
641
+ file: '/app/components/multi-lazy-groups/component.tsx',
642
+ },
643
+ dependencies: {
644
+ scripts: [
645
+ { src: './idle.ts', lazy: { 'on:idle': true } },
646
+ { content: 'console.log("visible")', lazy: { 'on:visible': '0.25' } },
647
+ ],
648
+ },
649
+ };
650
+
651
+ await service.processComponentDependencies([component], 'lit');
652
+
653
+ expect(component.config._resolvedLazyScripts).toBeUndefined();
654
+ expect(component.config._resolvedLazyTriggers).toHaveLength(1);
655
+
656
+ const rules = component.config._resolvedLazyTriggers?.[0]?.rules ?? [];
657
+ const idleRule = rules.find((rule) => 'on:idle' in rule);
658
+ const visibleRule = rules.find((rule) => 'on:visible' in rule);
659
+
660
+ expect(idleRule && 'on:idle' in idleRule ? idleRule['on:idle'].scripts[0] : undefined).toMatch(
661
+ /^\/assets\/lazy\/file-\d+\.js$/,
662
+ );
663
+ expect(visibleRule && 'on:visible' in visibleRule ? visibleRule['on:visible'].scripts[0] : undefined).toMatch(
664
+ /^\/assets\/lazy\/content-\d+\.js$/,
665
+ );
666
+ });
667
+
668
+ it('should emit object-form content scripts as inline non-bundled assets', async () => {
669
+ let capturedDeps: AssetDefinition[] = [];
670
+ const assetProcessingService = {
671
+ processDependencies: vi.fn(async (deps: AssetDefinition[]) => {
672
+ capturedDeps = deps;
673
+ return [] as ProcessedAsset[];
674
+ }),
675
+ } as unknown as AssetProcessingService;
676
+
677
+ const service = new DependencyResolverService(appConfig, assetProcessingService);
678
+ const component = ((_) => '<div></div>') as EcoComponent<Record<string, unknown>>;
679
+ component.config = {
680
+ __eco: {
681
+ id: 'html-shell',
682
+ integration: 'react',
683
+ file: '/app/includes/html.tsx',
684
+ },
685
+ dependencies: {
686
+ scripts: [
687
+ {
688
+ content: '(function(){document.documentElement.dataset.theme="light";})()',
689
+ attributes: { 'data-eco-script': 'theme' },
690
+ },
691
+ {
692
+ content: '(function(){document.getElementById("banner").style.display="block";})()',
693
+ attributes: { 'data-eco-script': 'announcement' },
694
+ },
695
+ ],
696
+ },
697
+ };
698
+
699
+ await service.processComponentDependencies([component], 'react');
700
+
701
+ const inlineScripts = capturedDeps.filter(
702
+ (dep): dep is InlineContentScriptAsset =>
703
+ dep.kind === 'script' && dep.source === 'content' && (dep as InlineContentScriptAsset).inline === true,
704
+ );
705
+
706
+ expect(inlineScripts).toHaveLength(2);
707
+ expect(inlineScripts.every((s) => s.bundle === false)).toBe(true);
708
+ expect(inlineScripts.every((s) => s.position === 'head')).toBe(true);
709
+ expect(inlineScripts[0].attributes?.['data-eco-script']).toBe('theme');
710
+ expect(inlineScripts[1].attributes?.['data-eco-script']).toBe('announcement');
711
+ expect(inlineScripts[0].content).toContain('theme');
712
+ expect(inlineScripts[1].content).toContain('banner');
713
+ });
714
+
715
+ it('should ignore undefined component entries when collecting nested dependencies', async () => {
716
+ let capturedDeps: AssetDefinition[] = [];
717
+ const assetProcessingService = {
718
+ processDependencies: vi.fn(async (deps: AssetDefinition[]) => {
719
+ capturedDeps = deps;
720
+ return [] as ProcessedAsset[];
721
+ }),
722
+ } as unknown as AssetProcessingService;
723
+
724
+ const service = new DependencyResolverService(appConfig, assetProcessingService);
725
+ const nestedComponent = ((_) => '<button></button>') as EcoComponent<Record<string, unknown>>;
726
+ nestedComponent.config = {
727
+ __eco: {
728
+ id: 'theme-toggle',
729
+ integration: 'react',
730
+ file: '/app/components/theme-toggle.tsx',
731
+ },
732
+ dependencies: {
733
+ scripts: ['./theme-toggle.client.ts'],
734
+ },
735
+ };
736
+
737
+ const component = ((_) => '<div></div>') as EcoComponent<Record<string, unknown>>;
738
+ component.config = {
739
+ __eco: {
740
+ id: 'page',
741
+ integration: 'kitajs',
742
+ file: '/app/views/page.tsx',
743
+ },
744
+ dependencies: {
745
+ components: [undefined, nestedComponent] as unknown as EcoComponent[],
746
+ },
747
+ };
748
+
749
+ await expect(
750
+ service.processComponentDependencies([undefined as unknown as EcoComponent, component], 'kitajs'),
751
+ ).resolves.toEqual([]);
752
+
753
+ expect(capturedDeps).toEqual([
754
+ expect.objectContaining({
755
+ kind: 'script',
756
+ source: 'file',
757
+ filepath: '/app/components/theme-toggle.client.ts',
758
+ }),
759
+ ]);
760
+ });
761
+ });