@ecopages/core 0.2.0-alpha.7 → 0.2.0-alpha.9

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 (354) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/package.json +212 -92
  3. package/src/adapters/abstract/application-adapter.d.ts +168 -0
  4. package/src/adapters/abstract/application-adapter.js +109 -0
  5. package/src/adapters/abstract/router-adapter.d.ts +26 -0
  6. package/src/adapters/abstract/router-adapter.js +5 -0
  7. package/src/adapters/abstract/server-adapter.d.ts +69 -0
  8. package/src/adapters/abstract/server-adapter.js +15 -0
  9. package/src/adapters/bun/client-bridge.d.ts +34 -0
  10. package/src/adapters/bun/client-bridge.js +48 -0
  11. package/src/adapters/bun/create-app.d.ts +60 -0
  12. package/src/adapters/bun/create-app.js +117 -0
  13. package/src/adapters/bun/hmr-manager.d.ts +143 -0
  14. package/src/adapters/bun/hmr-manager.js +334 -0
  15. package/src/adapters/bun/index.d.ts +2 -0
  16. package/src/adapters/bun/index.js +8 -0
  17. package/src/adapters/bun/server-adapter.d.ts +155 -0
  18. package/src/adapters/bun/server-adapter.js +373 -0
  19. package/src/adapters/bun/server-lifecycle.d.ts +63 -0
  20. package/src/adapters/bun/server-lifecycle.js +92 -0
  21. package/src/adapters/index.d.ts +6 -0
  22. package/src/adapters/index.js +14 -0
  23. package/src/adapters/node/bootstrap-dependency-resolver.d.ts +44 -0
  24. package/src/adapters/node/bootstrap-dependency-resolver.js +172 -0
  25. package/src/adapters/node/create-app.d.ts +21 -0
  26. package/src/adapters/node/create-app.js +143 -0
  27. package/src/adapters/node/index.d.ts +6 -0
  28. package/src/adapters/node/index.js +11 -0
  29. package/src/adapters/node/node-client-bridge.d.ts +26 -0
  30. package/src/adapters/node/node-client-bridge.js +66 -0
  31. package/src/adapters/node/node-hmr-manager.d.ts +133 -0
  32. package/src/adapters/node/node-hmr-manager.js +312 -0
  33. package/src/adapters/node/runtime-adapter.d.ts +46 -0
  34. package/src/adapters/node/runtime-adapter.js +306 -0
  35. package/src/adapters/node/server-adapter.d.ts +161 -0
  36. package/src/adapters/node/server-adapter.js +358 -0
  37. package/src/adapters/node/static-content-server.d.ts +60 -0
  38. package/src/adapters/node/static-content-server.js +194 -0
  39. package/src/adapters/node/write-runtime-manifest.d.ts +26 -0
  40. package/src/adapters/node/write-runtime-manifest.js +12 -0
  41. package/src/adapters/shared/api-response.d.ts +52 -0
  42. package/src/adapters/shared/api-response.js +96 -0
  43. package/src/adapters/shared/application-adapter.d.ts +18 -0
  44. package/src/adapters/shared/application-adapter.js +90 -0
  45. package/src/adapters/shared/define-api-handler.d.ts +25 -0
  46. package/src/adapters/shared/define-api-handler.js +15 -0
  47. package/src/adapters/shared/explicit-static-route-matcher.d.ts +38 -0
  48. package/src/adapters/shared/explicit-static-route-matcher.js +103 -0
  49. package/src/adapters/shared/file-route-middleware-pipeline.d.ts +65 -0
  50. package/src/adapters/shared/file-route-middleware-pipeline.js +99 -0
  51. package/src/adapters/shared/fs-server-response-factory.d.ts +19 -0
  52. package/src/adapters/shared/fs-server-response-factory.js +97 -0
  53. package/src/adapters/shared/fs-server-response-matcher.d.ts +75 -0
  54. package/src/adapters/shared/fs-server-response-matcher.js +160 -0
  55. package/src/adapters/shared/hmr-entrypoint-registrar.d.ts +55 -0
  56. package/src/adapters/shared/hmr-entrypoint-registrar.js +87 -0
  57. package/src/adapters/shared/hmr-html-response.d.ts +22 -0
  58. package/src/adapters/shared/hmr-html-response.js +32 -0
  59. package/src/adapters/shared/render-context.d.ts +14 -0
  60. package/src/adapters/shared/render-context.js +70 -0
  61. package/src/adapters/shared/runtime-bootstrap.d.ts +38 -0
  62. package/src/adapters/shared/runtime-bootstrap.js +43 -0
  63. package/src/adapters/shared/server-adapter.d.ts +97 -0
  64. package/src/adapters/shared/server-adapter.js +386 -0
  65. package/src/adapters/shared/server-route-handler.d.ts +89 -0
  66. package/src/adapters/shared/server-route-handler.js +111 -0
  67. package/src/adapters/shared/server-static-builder.d.ts +70 -0
  68. package/src/adapters/shared/server-static-builder.js +99 -0
  69. package/src/build/build-adapter.d.ts +186 -0
  70. package/src/build/build-adapter.js +168 -0
  71. package/src/build/build-manifest.d.ts +27 -0
  72. package/src/build/build-manifest.js +30 -0
  73. package/src/build/build-types.d.ts +57 -0
  74. package/src/build/build-types.js +0 -0
  75. package/src/build/dev-build-coordinator.d.ts +74 -0
  76. package/src/build/dev-build-coordinator.js +161 -0
  77. package/src/build/esbuild-build-adapter.d.ts +72 -0
  78. package/src/build/esbuild-build-adapter.js +422 -0
  79. package/src/build/runtime-build-executor.d.ts +13 -0
  80. package/src/build/runtime-build-executor.js +20 -0
  81. package/src/build/runtime-specifier-alias-plugin.d.ts +15 -0
  82. package/src/build/runtime-specifier-alias-plugin.js +31 -0
  83. package/src/config/config-builder.d.ts +238 -0
  84. package/src/config/config-builder.js +565 -0
  85. package/src/constants.d.ts +45 -0
  86. package/src/constants.js +25 -0
  87. package/src/create-app.d.ts +17 -0
  88. package/src/create-app.js +66 -0
  89. package/src/dev/sc-server.d.ts +30 -0
  90. package/src/dev/sc-server.js +111 -0
  91. package/src/eco/component-render-context.d.ts +105 -0
  92. package/src/eco/component-render-context.js +87 -0
  93. package/src/eco/eco.d.ts +9 -0
  94. package/src/eco/eco.js +114 -0
  95. package/src/eco/eco.types.d.ts +178 -0
  96. package/src/eco/eco.types.js +0 -0
  97. package/src/eco/eco.utils.d.ts +40 -0
  98. package/src/eco/eco.utils.js +40 -0
  99. package/src/eco/global-injector-map.d.ts +16 -0
  100. package/src/eco/global-injector-map.js +80 -0
  101. package/src/eco/lazy-injector-map.d.ts +8 -0
  102. package/src/eco/lazy-injector-map.js +70 -0
  103. package/src/eco/module-dependencies.d.ts +18 -0
  104. package/src/eco/module-dependencies.js +49 -0
  105. package/src/errors/http-error.d.ts +31 -0
  106. package/src/errors/http-error.js +50 -0
  107. package/src/errors/index.d.ts +2 -0
  108. package/src/errors/index.js +4 -0
  109. package/src/errors/locals-access-error.d.ts +4 -0
  110. package/src/errors/locals-access-error.js +9 -0
  111. package/src/global/app-logger.d.ts +2 -0
  112. package/src/global/app-logger.js +6 -0
  113. package/src/hmr/client/hmr-runtime.d.ts +5 -0
  114. package/src/hmr/client/hmr-runtime.js +109 -0
  115. package/src/hmr/hmr-strategy.d.ts +159 -0
  116. package/src/hmr/hmr-strategy.js +29 -0
  117. package/src/hmr/hmr.postcss.test.e2e.d.ts +1 -0
  118. package/src/hmr/hmr.postcss.test.e2e.js +31 -0
  119. package/src/hmr/hmr.test.e2e.d.ts +1 -0
  120. package/src/hmr/hmr.test.e2e.js +43 -0
  121. package/src/hmr/strategies/default-hmr-strategy.d.ts +43 -0
  122. package/src/hmr/strategies/default-hmr-strategy.js +34 -0
  123. package/src/hmr/strategies/js-hmr-strategy.d.ts +139 -0
  124. package/src/hmr/strategies/js-hmr-strategy.js +178 -0
  125. package/src/index.browser.d.ts +3 -0
  126. package/src/index.browser.js +4 -0
  127. package/src/index.d.ts +5 -0
  128. package/src/index.js +10 -0
  129. package/src/integrations/ghtml/ghtml-renderer.d.ts +15 -0
  130. package/src/integrations/ghtml/ghtml-renderer.js +62 -0
  131. package/src/integrations/ghtml/ghtml.plugin.d.ts +20 -0
  132. package/src/integrations/ghtml/ghtml.plugin.js +21 -0
  133. package/src/internal-types.d.ts +221 -0
  134. package/src/internal-types.js +0 -0
  135. package/src/plugins/alias-resolver-plugin.d.ts +2 -0
  136. package/src/plugins/alias-resolver-plugin.js +53 -0
  137. package/src/plugins/eco-component-meta-plugin.d.ts +97 -0
  138. package/src/plugins/eco-component-meta-plugin.js +157 -0
  139. package/src/plugins/integration-plugin.d.ts +136 -0
  140. package/src/plugins/integration-plugin.js +133 -0
  141. package/src/plugins/processor.d.ts +95 -0
  142. package/src/plugins/processor.js +136 -0
  143. package/src/plugins/runtime-capability.d.ts +9 -0
  144. package/src/plugins/runtime-capability.js +0 -0
  145. package/src/public-types.d.ts +1149 -0
  146. package/src/public-types.js +0 -0
  147. package/src/route-renderer/component-graph/component-graph-executor.d.ts +32 -0
  148. package/src/route-renderer/component-graph/component-graph-executor.js +31 -0
  149. package/src/route-renderer/component-graph/component-graph.d.ts +42 -0
  150. package/src/route-renderer/component-graph/component-graph.js +72 -0
  151. package/src/route-renderer/component-graph/component-marker.d.ts +52 -0
  152. package/src/route-renderer/component-graph/component-marker.js +46 -0
  153. package/src/route-renderer/component-graph/component-reference.d.ts +10 -0
  154. package/src/route-renderer/component-graph/component-reference.js +19 -0
  155. package/src/route-renderer/component-graph/marker-graph-resolver.d.ts +77 -0
  156. package/src/route-renderer/component-graph/marker-graph-resolver.js +95 -0
  157. package/src/route-renderer/orchestration/integration-renderer.d.ts +372 -0
  158. package/src/route-renderer/orchestration/integration-renderer.js +589 -0
  159. package/src/route-renderer/orchestration/render-execution.service.d.ts +103 -0
  160. package/src/route-renderer/orchestration/render-execution.service.js +121 -0
  161. package/src/route-renderer/orchestration/render-preparation.service.d.ts +121 -0
  162. package/src/route-renderer/orchestration/render-preparation.service.js +332 -0
  163. package/src/route-renderer/page-loading/dependency-resolver.d.ts +35 -0
  164. package/src/route-renderer/page-loading/dependency-resolver.js +442 -0
  165. package/src/route-renderer/page-loading/page-module-loader.d.ts +87 -0
  166. package/src/route-renderer/page-loading/page-module-loader.js +124 -0
  167. package/src/route-renderer/route-renderer.d.ts +61 -0
  168. package/src/route-renderer/route-renderer.js +87 -0
  169. package/src/router/client/link-intent.js +34 -0
  170. package/src/router/client/link-intent.test.browser.d.ts +1 -0
  171. package/src/router/client/link-intent.test.browser.js +43 -0
  172. package/src/router/client/navigation-coordinator.d.ts +149 -0
  173. package/src/router/client/navigation-coordinator.js +215 -0
  174. package/src/router/server/fs-router-scanner.d.ts +41 -0
  175. package/src/router/server/fs-router-scanner.js +156 -0
  176. package/src/router/server/fs-router.d.ts +26 -0
  177. package/src/router/server/fs-router.js +100 -0
  178. package/src/services/assets/asset-processing-service/asset-processing.service.d.ts +120 -0
  179. package/src/services/assets/asset-processing-service/asset-processing.service.js +331 -0
  180. package/src/services/assets/asset-processing-service/asset.factory.d.ts +17 -0
  181. package/src/services/assets/asset-processing-service/asset.factory.js +82 -0
  182. package/src/services/assets/asset-processing-service/assets.types.d.ts +89 -0
  183. package/src/services/assets/asset-processing-service/assets.types.js +0 -0
  184. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.d.ts +55 -0
  185. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +48 -0
  186. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.d.ts +20 -0
  187. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.js +41 -0
  188. package/src/services/assets/asset-processing-service/index.d.ts +5 -0
  189. package/src/services/assets/asset-processing-service/index.js +5 -0
  190. package/src/services/assets/asset-processing-service/processor.interface.d.ts +22 -0
  191. package/src/services/assets/asset-processing-service/processor.interface.js +6 -0
  192. package/src/services/assets/asset-processing-service/processor.registry.d.ts +8 -0
  193. package/src/services/assets/asset-processing-service/processor.registry.js +15 -0
  194. package/src/services/assets/asset-processing-service/processors/base/base-processor.d.ts +24 -0
  195. package/src/services/assets/asset-processing-service/processors/base/base-processor.js +64 -0
  196. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.d.ts +17 -0
  197. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.js +72 -0
  198. package/src/services/assets/asset-processing-service/processors/index.d.ts +5 -0
  199. package/src/services/assets/asset-processing-service/processors/index.js +5 -0
  200. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.d.ts +5 -0
  201. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.js +57 -0
  202. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.d.ts +8 -0
  203. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +76 -0
  204. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.d.ts +7 -0
  205. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +75 -0
  206. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.d.ts +5 -0
  207. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +25 -0
  208. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.d.ts +9 -0
  209. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +66 -0
  210. package/src/services/assets/browser-bundle.service.d.ts +32 -0
  211. package/src/services/assets/browser-bundle.service.js +33 -0
  212. package/src/services/cache/cache.types.d.ts +107 -0
  213. package/src/services/cache/cache.types.js +0 -0
  214. package/src/services/cache/index.d.ts +7 -0
  215. package/src/services/cache/index.js +7 -0
  216. package/src/services/cache/memory-cache-store.d.ts +42 -0
  217. package/src/services/cache/memory-cache-store.js +98 -0
  218. package/src/services/cache/page-cache-service.d.ts +70 -0
  219. package/src/services/cache/page-cache-service.js +152 -0
  220. package/src/services/cache/page-request-cache-coordinator.service.d.ts +75 -0
  221. package/src/services/cache/page-request-cache-coordinator.service.js +109 -0
  222. package/src/services/html/html-rewriter-provider.service.d.ts +37 -0
  223. package/src/services/html/html-rewriter-provider.service.js +65 -0
  224. package/src/services/html/html-transformer.service.d.ts +77 -0
  225. package/src/services/html/html-transformer.service.js +221 -0
  226. package/src/services/invalidation/development-invalidation.service.d.ts +74 -0
  227. package/src/services/invalidation/development-invalidation.service.js +189 -0
  228. package/src/services/module-loading/app-server-module-transpiler.service.d.ts +16 -0
  229. package/src/services/module-loading/app-server-module-transpiler.service.js +34 -0
  230. package/src/services/module-loading/page-module-import.service.d.ts +71 -0
  231. package/src/services/module-loading/page-module-import.service.js +132 -0
  232. package/src/services/module-loading/server-loader.service.d.ts +96 -0
  233. package/src/services/module-loading/server-loader.service.js +32 -0
  234. package/src/services/module-loading/server-module-transpiler.service.d.ts +69 -0
  235. package/src/services/module-loading/server-module-transpiler.service.js +61 -0
  236. package/src/services/runtime-manifest/node-runtime-manifest.service.d.ts +35 -0
  237. package/src/services/runtime-manifest/node-runtime-manifest.service.js +60 -0
  238. package/src/services/runtime-state/dev-graph.service.d.ts +118 -0
  239. package/src/services/runtime-state/dev-graph.service.js +162 -0
  240. package/src/services/runtime-state/entrypoint-dependency-graph.service.d.ts +41 -0
  241. package/src/services/runtime-state/entrypoint-dependency-graph.service.js +85 -0
  242. package/src/services/runtime-state/runtime-specifier-registry.service.d.ts +69 -0
  243. package/src/services/runtime-state/runtime-specifier-registry.service.js +37 -0
  244. package/src/services/runtime-state/server-invalidation-state.service.d.ts +26 -0
  245. package/src/services/runtime-state/server-invalidation-state.service.js +35 -0
  246. package/src/services/validation/schema-validation-service.d.ts +122 -0
  247. package/src/services/validation/schema-validation-service.js +101 -0
  248. package/src/services/validation/standard-schema.types.d.ts +65 -0
  249. package/src/services/validation/standard-schema.types.js +0 -0
  250. package/src/static-site-generator/static-site-generator.d.ts +109 -0
  251. package/src/static-site-generator/static-site-generator.js +353 -0
  252. package/src/utils/css.d.ts +1 -0
  253. package/src/utils/css.js +7 -0
  254. package/src/utils/deep-merge.d.ts +14 -0
  255. package/src/utils/deep-merge.js +32 -0
  256. package/src/utils/hash.d.ts +1 -0
  257. package/src/utils/hash.js +7 -0
  258. package/src/utils/html.d.ts +1 -0
  259. package/src/utils/html.js +4 -0
  260. package/src/utils/invariant.d.ts +5 -0
  261. package/src/utils/invariant.js +11 -0
  262. package/src/utils/locals-utils.d.ts +15 -0
  263. package/src/utils/locals-utils.js +24 -0
  264. package/src/utils/parse-cli-args.d.ts +24 -0
  265. package/src/utils/parse-cli-args.js +47 -0
  266. package/src/utils/path-utils.module.d.ts +5 -0
  267. package/src/utils/path-utils.module.js +14 -0
  268. package/src/utils/resolve-work-dir.d.ts +11 -0
  269. package/src/utils/resolve-work-dir.js +31 -0
  270. package/src/utils/runtime.d.ts +11 -0
  271. package/src/utils/runtime.js +40 -0
  272. package/src/utils/server-utils.module.d.ts +19 -0
  273. package/src/utils/server-utils.module.js +56 -0
  274. package/src/watchers/project-watcher.d.ts +136 -0
  275. package/src/watchers/project-watcher.js +281 -0
  276. package/src/watchers/project-watcher.test-helpers.d.ts +4 -0
  277. package/src/watchers/project-watcher.test-helpers.js +52 -0
  278. package/src/adapters/bun/hmr-manager.test.ts +0 -267
  279. package/src/adapters/node/bootstrap-dependency-resolver.test.ts +0 -282
  280. package/src/adapters/node/node-client-bridge.test.ts +0 -198
  281. package/src/adapters/node/node-hmr-manager.test.ts +0 -322
  282. package/src/adapters/node/runtime-adapter.test.ts +0 -868
  283. package/src/adapters/node/static-content-server.test.ts +0 -60
  284. package/src/adapters/shared/api-response.test.ts +0 -97
  285. package/src/adapters/shared/explicit-static-route-matcher.test.ts +0 -381
  286. package/src/adapters/shared/file-route-middleware-pipeline.test.ts +0 -90
  287. package/src/adapters/shared/fs-server-response-factory.test.ts +0 -187
  288. package/src/adapters/shared/fs-server-response-matcher.test.ts +0 -286
  289. package/src/adapters/shared/hmr-manager.contract.test.ts +0 -196
  290. package/src/adapters/shared/hmr-manager.dispatch.test.ts +0 -220
  291. package/src/adapters/shared/render-context.test.ts +0 -146
  292. package/src/adapters/shared/server-adapter.test.ts +0 -77
  293. package/src/adapters/shared/server-route-handler.test.ts +0 -110
  294. package/src/adapters/shared/server-static-builder.test.ts +0 -316
  295. package/src/build/build-adapter-serialization.test.ts +0 -268
  296. package/src/build/build-adapter.test.ts +0 -815
  297. package/src/build/runtime-specifier-alias-plugin.test.ts +0 -43
  298. package/src/config/config-builder.test.ts +0 -410
  299. package/src/eco/eco.test.ts +0 -678
  300. package/src/eco/eco.utils.test.ts +0 -124
  301. package/src/eco/global-injector-map.test.ts +0 -42
  302. package/src/eco/lazy-injector-map.test.ts +0 -66
  303. package/src/eco/module-dependencies.test.ts +0 -30
  304. package/src/errors/http-error.test.ts +0 -134
  305. package/src/global/utils.test.ts +0 -12
  306. 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
  307. package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-HMR-Server-Integration-should-load-fixture-app-page-1.png +0 -0
  308. package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-WebSocket-Connection-should-connect-to-correct-HMR-endpoint-1.png +0 -0
  309. package/src/hmr/hmr-strategy.test.ts +0 -124
  310. package/src/hmr/strategies/js-hmr-strategy.test.ts +0 -335
  311. package/src/integrations/ghtml/ghtml-renderer.test.ts +0 -63
  312. package/src/plugins/alias-resolver-plugin.test.ts +0 -41
  313. package/src/plugins/eco-component-meta-plugin.test.ts +0 -380
  314. package/src/plugins/integration-plugin.test.ts +0 -111
  315. package/src/plugins/processor.test.ts +0 -148
  316. package/src/route-renderer/component-graph/component-graph-executor.test.ts +0 -41
  317. package/src/route-renderer/component-graph/component-graph.test.ts +0 -63
  318. package/src/route-renderer/component-graph/component-marker.test.ts +0 -73
  319. package/src/route-renderer/component-graph/marker-graph-resolver.test.ts +0 -135
  320. package/src/route-renderer/orchestration/integration-renderer.test.ts +0 -936
  321. package/src/route-renderer/orchestration/render-execution.service.test.ts +0 -97
  322. package/src/route-renderer/orchestration/render-preparation.service.test.ts +0 -235
  323. package/src/route-renderer/page-loading/dependency-resolver.test.ts +0 -345
  324. package/src/route-renderer/page-loading/page-module-loader.test.ts +0 -96
  325. package/src/router/client/navigation-coordinator.test.ts +0 -237
  326. package/src/router/server/fs-router-scanner.test.ts +0 -83
  327. package/src/router/server/fs-router.test.ts +0 -214
  328. package/src/services/assets/asset-processing-service/asset-processing.service.test.ts +0 -385
  329. package/src/services/assets/asset-processing-service/asset.factory.test.ts +0 -63
  330. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.test.ts +0 -72
  331. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.test.ts +0 -67
  332. package/src/services/assets/asset-processing-service/processors/base/base-processor.test.ts +0 -59
  333. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.test.ts +0 -286
  334. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.test.ts +0 -227
  335. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.test.ts +0 -199
  336. package/src/services/assets/browser-bundle.service.test.ts +0 -36
  337. package/src/services/cache/memory-cache-store.test.ts +0 -225
  338. package/src/services/cache/page-cache-service.test.ts +0 -175
  339. package/src/services/cache/page-request-cache-coordinator.service.test.ts +0 -79
  340. package/src/services/html/html-rewriter-provider.service.test.ts +0 -183
  341. package/src/services/html/html-transformer.service.test.ts +0 -378
  342. package/src/services/invalidation/development-invalidation.service.test.ts +0 -77
  343. package/src/services/module-loading/page-module-import.service.test.ts +0 -253
  344. package/src/services/module-loading/server-loader.service.test.ts +0 -161
  345. package/src/services/module-loading/server-module-transpiler.service.test.ts +0 -115
  346. package/src/services/runtime-manifest/node-runtime-manifest.service.test.ts +0 -95
  347. package/src/services/validation/schema-validation-service.test.ts +0 -223
  348. package/src/static-site-generator/static-site-generator.test.ts +0 -307
  349. package/src/utils/deep-merge.test.ts +0 -114
  350. package/src/utils/invariant.test.ts +0 -22
  351. package/src/utils/path-utils.test.ts +0 -15
  352. package/src/utils/server-utils.test.ts +0 -38
  353. package/src/watchers/project-watcher.integration.test.ts +0 -337
  354. package/src/watchers/project-watcher.test.ts +0 -678
@@ -1,868 +0,0 @@
1
- import fs from 'node:fs';
2
- import { tmpdir } from 'node:os';
3
- import path from 'node:path';
4
- import assert from 'node:assert/strict';
5
- import { test, vi } from 'vitest';
6
- import { assertNodeRuntimeManifest, createNodeRuntimeAdapter } from './runtime-adapter.ts';
7
- import { TranspilerServerLoader } from '../../services/module-loading/server-loader.service.ts';
8
-
9
- test('assertNodeRuntimeManifest accepts the current runtime manifest shape', () => {
10
- const manifest = assertNodeRuntimeManifest({
11
- runtime: 'node',
12
- appRootDir: '/repo',
13
- sourceRootDir: '/repo/src',
14
- distDir: '/repo/dist',
15
- modulePaths: {
16
- config: '/repo/eco.config.ts',
17
- entry: '/repo/app.ts',
18
- },
19
- });
20
-
21
- assert.equal(manifest.modulePaths.entry, '/repo/app.ts');
22
- });
23
-
24
- test('node runtime adapter loads the config module and app entry through core-owned services', async () => {
25
- const workspaceRoot = process.cwd();
26
- const projectDir = fs.mkdtempSync(path.join(workspaceRoot, '.tmp-node-runtime-adapter-'));
27
- const marker = globalThis as typeof globalThis & {
28
- __ecoNodeRuntimeLoaded?: {
29
- rootDir: string;
30
- };
31
- };
32
-
33
- try {
34
- fs.mkdirSync(path.join(projectDir, 'src'), { recursive: true });
35
- fs.writeFileSync(
36
- path.join(projectDir, 'eco.config.ts'),
37
- [
38
- `const rootDir = ${JSON.stringify(projectDir)};`,
39
- 'const config = {',
40
- "\tbaseUrl: 'http://localhost:3000',",
41
- '\trootDir,',
42
- "\tsrcDir: 'src',",
43
- "\tpublicDir: 'public',",
44
- "\tpagesDir: 'pages',",
45
- "\tincludesDir: 'includes',",
46
- "\tlayoutsDir: 'layouts',",
47
- "\tdistDir: 'dist',",
48
- '\ttemplatesExt: [],',
49
- "\tcomponentsDir: 'components',",
50
- "\trobotsTxt: { preferences: { '*': [] } },",
51
- '\tadditionalWatchPaths: [],',
52
- "\tdefaultMetadata: { title: 'Test', description: 'Test' },",
53
- '\tintegrations: [],',
54
- '\tintegrationsDependencies: [],',
55
- '\tabsolutePaths: {',
56
- '\t\tconfig: `${rootDir}/eco.config.ts`,',
57
- '\t\tcomponentsDir: `${rootDir}/src/components`,',
58
- '\t\tdistDir: `${rootDir}/dist`,',
59
- '\t\tincludesDir: `${rootDir}/src/includes`,',
60
- '\t\tlayoutsDir: `${rootDir}/src/layouts`,',
61
- '\t\tpagesDir: `${rootDir}/src/pages`,',
62
- '\t\tprojectDir: rootDir,',
63
- '\t\tpublicDir: `${rootDir}/public`,',
64
- '\t\tsrcDir: `${rootDir}/src`,',
65
- '\t\thtmlTemplatePath: `${rootDir}/src/index.html`,',
66
- '\t\terror404TemplatePath: `${rootDir}/src/404.html`,',
67
- '\t},',
68
- '\tprocessors: new Map(),',
69
- '\tloaders: new Map(),',
70
- '};',
71
- 'export default config;',
72
- ].join('\n'),
73
- 'utf8',
74
- );
75
- fs.writeFileSync(
76
- path.join(projectDir, 'app.ts'),
77
- [
78
- "import appConfig from './eco.config';",
79
- 'const runtimeMarker = globalThis as typeof globalThis & { __ecoNodeRuntimeLoaded?: { rootDir: string } };',
80
- 'runtimeMarker.__ecoNodeRuntimeLoaded = {',
81
- '\trootDir: appConfig.rootDir,',
82
- '};',
83
- ].join('\n'),
84
- 'utf8',
85
- );
86
-
87
- const adapter = createNodeRuntimeAdapter();
88
- const manifest = assertNodeRuntimeManifest({
89
- runtime: 'node',
90
- appRootDir: projectDir,
91
- sourceRootDir: path.join(projectDir, 'src'),
92
- distDir: path.join(projectDir, 'dist'),
93
- modulePaths: {
94
- config: path.join(projectDir, 'eco.config.ts'),
95
- entry: path.join(projectDir, 'app.ts'),
96
- },
97
- });
98
-
99
- const session = await adapter.start({
100
- manifest,
101
- workingDirectory: projectDir,
102
- cliArgs: ['app.ts', '--dev'],
103
- });
104
-
105
- const loadedAppRuntime = await session.loadApp();
106
-
107
- assert.equal(loadedAppRuntime.entryModulePath, path.join(projectDir, 'app.ts'));
108
- assert.equal(loadedAppRuntime.appConfig.rootDir, projectDir);
109
- assert.equal(typeof loadedAppRuntime.entryModule, 'object');
110
- assert.deepEqual(marker.__ecoNodeRuntimeLoaded, {
111
- rootDir: projectDir,
112
- });
113
- await assert.doesNotReject(() => session.invalidate(['/repo/src/pages/index.tsx']));
114
- await assert.doesNotReject(() => session.dispose());
115
- } finally {
116
- delete marker.__ecoNodeRuntimeLoaded;
117
- fs.rmSync(projectDir, { recursive: true, force: true });
118
- }
119
- });
120
-
121
- test('node runtime adapter fails on real bootstrap problems instead of the placeholder message', async () => {
122
- const adapter = createNodeRuntimeAdapter();
123
- const manifest = assertNodeRuntimeManifest({
124
- runtime: 'node',
125
- appRootDir: '/repo',
126
- sourceRootDir: '/repo/src',
127
- distDir: '/repo/dist',
128
- modulePaths: {
129
- config: '/repo/eco.config.ts',
130
- entry: '/repo/app.ts',
131
- },
132
- });
133
-
134
- const session = await adapter.start({
135
- manifest,
136
- workingDirectory: '/repo',
137
- cliArgs: ['app.ts', '--dev'],
138
- });
139
-
140
- await assert.rejects(
141
- () => session.loadApp(),
142
- /Failed to transpile Ecopages config module|No transpiled output generated for Ecopages config module|Error hashing file:/,
143
- );
144
- });
145
-
146
- test('node runtime adapter routes config and entry bootstrap imports through the explicit server-loader boundary', async () => {
147
- const loadConfig = vi.spyOn(TranspilerServerLoader.prototype, 'loadConfig');
148
- const loadApp = vi.spyOn(TranspilerServerLoader.prototype, 'loadApp');
149
- const reboundContexts: Array<{ rootDir: string }> = [];
150
- const rebindAppContext = vi.spyOn(TranspilerServerLoader.prototype, 'rebindAppContext');
151
- const projectDir = '/repo';
152
-
153
- loadConfig.mockImplementationOnce(async () => {
154
- return {
155
- rootDir: projectDir,
156
- absolutePaths: {
157
- config: path.join(projectDir, 'eco.config.ts'),
158
- srcDir: path.join(projectDir, 'src'),
159
- distDir: path.join(projectDir, 'dist'),
160
- },
161
- loaders: new Map(),
162
- runtime: {},
163
- };
164
- });
165
- loadApp.mockImplementationOnce(async () => ({}));
166
- rebindAppContext.mockImplementation((context) => {
167
- reboundContexts.push({ rootDir: context.rootDir });
168
- });
169
-
170
- try {
171
- const adapter = createNodeRuntimeAdapter();
172
- const manifest = assertNodeRuntimeManifest({
173
- runtime: 'node',
174
- appRootDir: projectDir,
175
- sourceRootDir: path.join(projectDir, 'src'),
176
- distDir: path.join(projectDir, 'dist'),
177
- modulePaths: {
178
- config: path.join(projectDir, 'eco.config.ts'),
179
- entry: path.join(projectDir, 'app.ts'),
180
- },
181
- });
182
-
183
- const session = await adapter.start({
184
- manifest,
185
- workingDirectory: projectDir,
186
- cliArgs: ['app.ts', '--dev'],
187
- });
188
-
189
- const loadedAppRuntime = await session.loadApp();
190
- assert.equal(loadConfig.mock.calls.length, 1);
191
- assert.equal(loadApp.mock.calls.length, 1);
192
- assert.deepEqual(reboundContexts, [{ rootDir: projectDir }]);
193
- assert.equal(loadedAppRuntime.entryModulePath, path.join(projectDir, 'app.ts'));
194
- assert.equal(loadedAppRuntime.appConfig.rootDir, projectDir);
195
- assert.equal(typeof loadedAppRuntime.entryModule, 'object');
196
- } finally {
197
- loadConfig.mockRestore();
198
- loadApp.mockRestore();
199
- rebindAppContext.mockRestore();
200
- }
201
- });
202
-
203
- test('node runtime adapter caches the loaded runtime until invalidation requests a fresh app load', async () => {
204
- const projectDir = '/repo';
205
- const loadConfig = vi.spyOn(TranspilerServerLoader.prototype, 'loadConfig');
206
- const loadApp = vi.spyOn(TranspilerServerLoader.prototype, 'loadApp');
207
- const invalidate = vi.spyOn(TranspilerServerLoader.prototype, 'invalidate');
208
- let appLoadCount = 0;
209
-
210
- loadConfig.mockImplementationOnce(async () => {
211
- return {
212
- rootDir: projectDir,
213
- absolutePaths: {
214
- config: path.join(projectDir, 'eco.config.ts'),
215
- srcDir: path.join(projectDir, 'src'),
216
- distDir: path.join(projectDir, 'dist'),
217
- publicDir: path.join(projectDir, 'public'),
218
- includesDir: path.join(projectDir, 'src', 'includes'),
219
- pagesDir: path.join(projectDir, 'src', 'pages'),
220
- },
221
- additionalWatchPaths: [],
222
- templatesExt: [],
223
- processors: new Map(),
224
- loaders: new Map(),
225
- runtime: {},
226
- };
227
- });
228
- loadApp.mockImplementation(async () => ({ loadNumber: ++appLoadCount }));
229
-
230
- try {
231
- const adapter = createNodeRuntimeAdapter();
232
- const manifest = assertNodeRuntimeManifest({
233
- runtime: 'node',
234
- appRootDir: projectDir,
235
- sourceRootDir: path.join(projectDir, 'src'),
236
- distDir: path.join(projectDir, 'dist'),
237
- modulePaths: {
238
- config: path.join(projectDir, 'eco.config.ts'),
239
- entry: path.join(projectDir, 'app.ts'),
240
- },
241
- });
242
-
243
- const session = await adapter.start({
244
- manifest,
245
- workingDirectory: projectDir,
246
- cliArgs: ['app.ts', '--dev'],
247
- });
248
-
249
- const firstRuntime = await session.loadApp();
250
- const secondRuntime = await session.loadApp();
251
-
252
- assert.strictEqual(secondRuntime, firstRuntime);
253
- assert.equal(loadConfig.mock.calls.length, 1);
254
- assert.equal(loadApp.mock.calls.length, 1);
255
-
256
- await session.invalidate([path.join(projectDir, 'src', 'pages', 'index.tsx')]);
257
-
258
- const thirdRuntime = await session.loadApp();
259
-
260
- assert.notStrictEqual(thirdRuntime, firstRuntime);
261
- assert.equal(loadConfig.mock.calls.length, 1);
262
- assert.equal(loadApp.mock.calls.length, 2);
263
- assert.deepEqual(invalidate.mock.calls[0]?.[0], [path.join(projectDir, 'src', 'pages', 'index.tsx')]);
264
- } finally {
265
- loadConfig.mockRestore();
266
- loadApp.mockRestore();
267
- invalidate.mockRestore();
268
- }
269
- });
270
-
271
- test('node runtime adapter bootstraps an app entry that imports core runtime code plus a local config module', async () => {
272
- const workspaceRoot = process.cwd();
273
- const projectDir = fs.mkdtempSync(path.join(workspaceRoot, '.tmp-node-runtime-adapter-entry-'));
274
- const marker = globalThis as typeof globalThis & {
275
- __ecoNodeRuntimeEntryBootstrap?: {
276
- hasCreateApp: boolean;
277
- rootDir: string;
278
- };
279
- };
280
-
281
- try {
282
- fs.mkdirSync(path.join(projectDir, 'src'), { recursive: true });
283
- fs.writeFileSync(
284
- path.join(projectDir, 'eco.config.ts'),
285
- [
286
- `const rootDir = ${JSON.stringify(projectDir)};`,
287
- 'const config = {',
288
- "\tbaseUrl: 'http://localhost:3000',",
289
- '\trootDir,',
290
- "\tsrcDir: 'src',",
291
- "\tpublicDir: 'public',",
292
- "\tpagesDir: 'pages',",
293
- "\tincludesDir: 'includes',",
294
- "\tlayoutsDir: 'layouts',",
295
- "\tdistDir: 'dist',",
296
- '\ttemplatesExt: [],',
297
- "\tcomponentsDir: 'components',",
298
- "\trobotsTxt: { preferences: { '*': [] } },",
299
- '\tadditionalWatchPaths: [],',
300
- "\tdefaultMetadata: { title: 'Test', description: 'Test' },",
301
- '\tintegrations: [],',
302
- '\tintegrationsDependencies: [],',
303
- '\tabsolutePaths: {',
304
- '\t\tconfig: `${rootDir}/eco.config.ts`,',
305
- '\t\tcomponentsDir: `${rootDir}/src/components`,',
306
- '\t\tdistDir: `${rootDir}/dist`,',
307
- '\t\tincludesDir: `${rootDir}/src/includes`,',
308
- '\t\tlayoutsDir: `${rootDir}/src/layouts`,',
309
- '\t\tpagesDir: `${rootDir}/src/pages`,',
310
- '\t\tprojectDir: rootDir,',
311
- '\t\tpublicDir: `${rootDir}/public`,',
312
- '\t\tsrcDir: `${rootDir}/src`,',
313
- '\t\thtmlTemplatePath: `${rootDir}/src/index.html`,',
314
- '\t\terror404TemplatePath: `${rootDir}/src/404.html`,',
315
- '\t},',
316
- '\tprocessors: new Map(),',
317
- '\tloaders: new Map(),',
318
- '};',
319
- 'export default config;',
320
- ].join('\n'),
321
- 'utf8',
322
- );
323
- fs.writeFileSync(
324
- path.join(projectDir, 'app.ts'),
325
- [
326
- "import { createApp } from '@ecopages/core';",
327
- "import appConfig from './eco.config';",
328
- 'const runtimeMarker = globalThis as typeof globalThis & { __ecoNodeRuntimeEntryBootstrap?: { hasCreateApp: boolean; rootDir: string } };',
329
- 'runtimeMarker.__ecoNodeRuntimeEntryBootstrap = {',
330
- '\thasCreateApp: typeof createApp === "function",',
331
- '\trootDir: appConfig.rootDir,',
332
- '};',
333
- ].join('\n'),
334
- 'utf8',
335
- );
336
-
337
- const adapter = createNodeRuntimeAdapter();
338
- const manifest = assertNodeRuntimeManifest({
339
- runtime: 'node',
340
- appRootDir: projectDir,
341
- sourceRootDir: path.join(projectDir, 'src'),
342
- distDir: path.join(projectDir, 'dist'),
343
- modulePaths: {
344
- config: path.join(projectDir, 'eco.config.ts'),
345
- entry: path.join(projectDir, 'app.ts'),
346
- },
347
- });
348
-
349
- const session = await adapter.start({
350
- manifest,
351
- workingDirectory: projectDir,
352
- cliArgs: ['app.ts', '--dev'],
353
- });
354
-
355
- await session.loadApp();
356
-
357
- assert.deepEqual(marker.__ecoNodeRuntimeEntryBootstrap, {
358
- hasCreateApp: true,
359
- rootDir: projectDir,
360
- });
361
- await assert.doesNotReject(() => session.dispose());
362
- } finally {
363
- delete marker.__ecoNodeRuntimeEntryBootstrap;
364
- fs.rmSync(projectDir, { recursive: true, force: true });
365
- }
366
- });
367
-
368
- test('node runtime adapter preserves config import.meta.dirname semantics during bootstrap transpilation', async () => {
369
- const workspaceRoot = process.cwd();
370
- const projectDir = fs.mkdtempSync(path.join(workspaceRoot, '.tmp-node-runtime-adapter-import-meta-'));
371
- const marker = globalThis as typeof globalThis & {
372
- __ecoNodeRuntimeImportMeta?: {
373
- rootDir: string;
374
- htmlTemplatePath: string;
375
- };
376
- };
377
-
378
- try {
379
- fs.mkdirSync(path.join(projectDir, 'src', 'includes'), { recursive: true });
380
- fs.writeFileSync(path.join(projectDir, 'src', 'includes', 'html.kita.tsx'), 'export default {};\n', 'utf8');
381
- fs.writeFileSync(
382
- path.join(projectDir, 'eco.config.ts'),
383
- [
384
- 'const rootDir = import.meta.dirname;',
385
- 'const config = {',
386
- "\tbaseUrl: 'http://localhost:3000',",
387
- '\trootDir,',
388
- "\tsrcDir: 'src',",
389
- "\tpublicDir: 'public',",
390
- "\tpagesDir: 'pages',",
391
- "\tincludesDir: 'includes',",
392
- "\tlayoutsDir: 'layouts',",
393
- "\tdistDir: 'dist',",
394
- "\ttemplatesExt: ['.kita.tsx'],",
395
- "\tcomponentsDir: 'components',",
396
- "\trobotsTxt: { preferences: { '*': [] } },",
397
- '\tadditionalWatchPaths: [],',
398
- "\tdefaultMetadata: { title: 'Test', description: 'Test' },",
399
- '\tintegrations: [],',
400
- '\tintegrationsDependencies: [],',
401
- '\tabsolutePaths: {',
402
- '\t\tconfig: `${rootDir}/eco.config.ts`,',
403
- '\t\tcomponentsDir: `${rootDir}/src/components`,',
404
- '\t\tdistDir: `${rootDir}/dist`,',
405
- '\t\tincludesDir: `${rootDir}/src/includes`,',
406
- '\t\tlayoutsDir: `${rootDir}/src/layouts`,',
407
- '\t\tpagesDir: `${rootDir}/src/pages`,',
408
- '\t\tprojectDir: rootDir,',
409
- '\t\tpublicDir: `${rootDir}/public`,',
410
- '\t\tsrcDir: `${rootDir}/src`,',
411
- '\t\thtmlTemplatePath: `${rootDir}/src/includes/html.kita.tsx`,',
412
- '\t\terror404TemplatePath: `${rootDir}/src/pages/404.kita.tsx`,',
413
- '},',
414
- '\tprocessors: new Map(),',
415
- '\tloaders: new Map(),',
416
- '};',
417
- 'export default config;',
418
- ].join('\n'),
419
- 'utf8',
420
- );
421
- fs.writeFileSync(
422
- path.join(projectDir, 'app.ts'),
423
- [
424
- "import appConfig from './eco.config';",
425
- 'const runtimeMarker = globalThis as typeof globalThis & { __ecoNodeRuntimeImportMeta?: { rootDir: string; htmlTemplatePath: string } };',
426
- 'runtimeMarker.__ecoNodeRuntimeImportMeta = {',
427
- '\trootDir: appConfig.rootDir,',
428
- '\thtmlTemplatePath: appConfig.absolutePaths.htmlTemplatePath,',
429
- '};',
430
- ].join('\n'),
431
- 'utf8',
432
- );
433
-
434
- const adapter = createNodeRuntimeAdapter();
435
- const manifest = assertNodeRuntimeManifest({
436
- runtime: 'node',
437
- appRootDir: projectDir,
438
- sourceRootDir: path.join(projectDir, 'src'),
439
- distDir: path.join(projectDir, 'dist'),
440
- modulePaths: {
441
- config: path.join(projectDir, 'eco.config.ts'),
442
- entry: path.join(projectDir, 'app.ts'),
443
- },
444
- });
445
-
446
- const session = await adapter.start({
447
- manifest,
448
- workingDirectory: projectDir,
449
- cliArgs: ['app.ts', '--dev'],
450
- });
451
-
452
- const loadedAppRuntime = await session.loadApp();
453
-
454
- assert.equal(loadedAppRuntime.appConfig.rootDir, projectDir);
455
- assert.equal(
456
- loadedAppRuntime.appConfig.absolutePaths.htmlTemplatePath,
457
- path.join(projectDir, 'src', 'includes', 'html.kita.tsx'),
458
- );
459
- assert.deepEqual(marker.__ecoNodeRuntimeImportMeta, {
460
- rootDir: projectDir,
461
- htmlTemplatePath: path.join(projectDir, 'src', 'includes', 'html.kita.tsx'),
462
- });
463
- await assert.doesNotReject(() => session.dispose());
464
- } finally {
465
- delete marker.__ecoNodeRuntimeImportMeta;
466
- fs.rmSync(projectDir, { recursive: true, force: true });
467
- }
468
- });
469
-
470
- test('node runtime adapter preserves layout metadata for explicit ctx.render routes', async () => {
471
- const workspaceRoot = process.cwd();
472
- const projectDir = fs.mkdtempSync(path.join(tmpdir(), 'ecopages-node-runtime-adapter-explicit-render-'));
473
- const runtimeMarker = globalThis as typeof globalThis & {
474
- __ecoNodeRuntimeExplicitRender?: {
475
- explicitHasLayout?: boolean;
476
- latestHasLayout?: boolean;
477
- };
478
- };
479
-
480
- try {
481
- const workspaceNodeModulesDir = path.join(workspaceRoot, 'node_modules');
482
- fs.mkdirSync(path.join(projectDir, 'src', 'includes'), { recursive: true });
483
- fs.mkdirSync(path.join(projectDir, 'src', 'layouts'), { recursive: true });
484
- fs.mkdirSync(path.join(projectDir, 'src', 'views'), { recursive: true });
485
- fs.writeFileSync(
486
- path.join(projectDir, 'tsconfig.json'),
487
- JSON.stringify(
488
- {
489
- compilerOptions: {
490
- baseUrl: '.',
491
- jsx: 'react-jsx',
492
- jsxImportSource: '@kitajs/html',
493
- module: 'ESNext',
494
- moduleResolution: 'Bundler',
495
- },
496
- },
497
- null,
498
- 2,
499
- ),
500
- 'utf8',
501
- );
502
- if (fs.existsSync(workspaceNodeModulesDir)) {
503
- fs.symlinkSync(workspaceNodeModulesDir, path.join(projectDir, 'node_modules'), 'dir');
504
- }
505
- fs.writeFileSync(
506
- path.join(projectDir, 'eco.config.ts'),
507
- [
508
- "import { ConfigBuilder } from '@ecopages/core/config-builder';",
509
- "import { kitajsPlugin } from '@ecopages/kitajs';",
510
- `const appRoot = ${JSON.stringify(projectDir)};`,
511
- 'const config = await new ConfigBuilder()',
512
- '\t.setRootDir(appRoot)',
513
- "\t.setBaseUrl('http://localhost:3000')",
514
- '\t.setIntegrations([kitajsPlugin()])',
515
- '\t.build();',
516
- 'export default config;',
517
- ].join('\n'),
518
- 'utf8',
519
- );
520
- fs.writeFileSync(
521
- path.join(projectDir, 'src', 'includes', 'html.kita.tsx'),
522
- [
523
- "import { eco } from '@ecopages/core';",
524
- 'export default eco.html({',
525
- '\trender: ({ children }) => <html><body>{children}</body></html>,',
526
- '});',
527
- ].join('\n'),
528
- 'utf8',
529
- );
530
- fs.writeFileSync(
531
- path.join(projectDir, 'src', 'layouts', 'base-layout.kita.tsx'),
532
- [
533
- "import { eco } from '@ecopages/core';",
534
- 'export const BaseLayout = eco.layout({',
535
- '\trender: ({ children }) => <main data-layout="base-layout">{children}</main>,',
536
- '});',
537
- ].join('\n'),
538
- 'utf8',
539
- );
540
- fs.writeFileSync(
541
- path.join(projectDir, 'src', 'views', 'explicit-view.kita.tsx'),
542
- [
543
- "import { eco } from '@ecopages/core';",
544
- "import { BaseLayout } from '../layouts/base-layout.kita';",
545
- 'export default eco.page({',
546
- '\tdependencies: {',
547
- '\t\tcomponents: [BaseLayout],',
548
- '\t},',
549
- "\tintegration: 'kitajs',",
550
- '\tlayout: BaseLayout,',
551
- '\trender: () => <section data-view="explicit">Explicit route body</section>,',
552
- '});',
553
- ].join('\n'),
554
- 'utf8',
555
- );
556
- fs.writeFileSync(
557
- path.join(projectDir, 'src', 'views', 'latest-view.kita.tsx'),
558
- [
559
- "import { eco } from '@ecopages/core';",
560
- "import { BaseLayout } from '../layouts/base-layout.kita';",
561
- 'type LatestViewProps = {',
562
- '\tname: string;',
563
- '};',
564
- 'export default eco.page<LatestViewProps>({',
565
- '\tdependencies: {',
566
- '\t\tcomponents: [BaseLayout],',
567
- '\t},',
568
- "\tintegration: 'kitajs',",
569
- '\tlayout: BaseLayout,',
570
- '\trender: ({ name }) => <section data-view="latest">Latest route for {name}</section>,',
571
- '});',
572
- ].join('\n'),
573
- 'utf8',
574
- );
575
- fs.writeFileSync(
576
- path.join(projectDir, 'app.ts'),
577
- [
578
- "import { createApp } from '@ecopages/core';",
579
- "import appConfig from './eco.config';",
580
- 'const app = await createApp({ appConfig });',
581
- 'const runtimeMarker = globalThis as typeof globalThis & {',
582
- '\t__ecoNodeRuntimeExplicitRender?: {',
583
- '\t\texplicitHasLayout?: boolean;',
584
- '\t\tlatestHasLayout?: boolean;',
585
- '\t};',
586
- '};',
587
- "app.get('/explicit', async (ctx) => {",
588
- "\tconst { default: ExplicitView } = await import('./src/views/explicit-view.kita');",
589
- '\truntimeMarker.__ecoNodeRuntimeExplicitRender = {',
590
- '\t\t...runtimeMarker.__ecoNodeRuntimeExplicitRender,',
591
- '\t\texplicitHasLayout: Boolean(ExplicitView.config?.layout),',
592
- '\t};',
593
- '\treturn ctx.render(ExplicitView, {});',
594
- '});',
595
- "app.get('/latest', async (ctx) => {",
596
- "\tconst { default: LatestView } = await import('./src/views/latest-view.kita');",
597
- '\truntimeMarker.__ecoNodeRuntimeExplicitRender = {',
598
- '\t\t...runtimeMarker.__ecoNodeRuntimeExplicitRender,',
599
- '\t\tlatestHasLayout: Boolean(LatestView.config?.layout),',
600
- '\t};',
601
- "\treturn ctx.render(LatestView, { name: 'node-thin-host' });",
602
- '});',
603
- 'export default app;',
604
- ].join('\n'),
605
- 'utf8',
606
- );
607
-
608
- const adapter = createNodeRuntimeAdapter();
609
- const manifest = assertNodeRuntimeManifest({
610
- runtime: 'node',
611
- appRootDir: projectDir,
612
- sourceRootDir: path.join(projectDir, 'src'),
613
- distDir: path.join(projectDir, 'dist'),
614
- modulePaths: {
615
- config: path.join(projectDir, 'eco.config.ts'),
616
- entry: path.join(projectDir, 'app.ts'),
617
- },
618
- });
619
-
620
- const session = await adapter.start({
621
- manifest,
622
- workingDirectory: projectDir,
623
- cliArgs: ['app.ts', '--dev'],
624
- });
625
- const loadedAppRuntime = await session.loadApp();
626
- const runtimeApp = loadedAppRuntime.entryModule as {
627
- default?: {
628
- fetch(request: Request): Promise<Response>;
629
- };
630
- };
631
- assert.ok(runtimeApp.default);
632
-
633
- const explicitResponse = await runtimeApp.default.fetch(new Request('http://localhost:3000/explicit'));
634
- const latestResponse = await runtimeApp.default.fetch(new Request('http://localhost:3000/latest'));
635
- const explicitHtml = await explicitResponse.text();
636
- const latestHtml = await latestResponse.text();
637
-
638
- assert.equal(runtimeMarker.__ecoNodeRuntimeExplicitRender?.explicitHasLayout, true);
639
- assert.equal(runtimeMarker.__ecoNodeRuntimeExplicitRender?.latestHasLayout, true);
640
- assert.match(explicitHtml, /data-layout="base-layout"/);
641
- assert.match(explicitHtml, /data-view="explicit"/);
642
- assert.match(latestHtml, /data-layout="base-layout"/);
643
- assert.match(latestHtml, /data-view="latest"/);
644
-
645
- await assert.doesNotReject(() => session.dispose());
646
- } finally {
647
- delete runtimeMarker.__ecoNodeRuntimeExplicitRender;
648
- fs.rmSync(projectDir, { recursive: true, force: true });
649
- }
650
- });
651
-
652
- test('node runtime adapter preserves explicit-route view metadata before renderer recovery', async () => {
653
- const workspaceRoot = process.cwd();
654
- const projectDir = fs.mkdtempSync(path.join(tmpdir(), 'ecopages-node-runtime-adapter-direct-view-metadata-'));
655
- let session: Awaited<ReturnType<ReturnType<typeof createNodeRuntimeAdapter>['start']>> | undefined;
656
-
657
- try {
658
- const workspaceNodeModulesDir = path.join(workspaceRoot, 'node_modules');
659
- fs.mkdirSync(path.join(projectDir, 'src', 'components'), { recursive: true });
660
- fs.mkdirSync(path.join(projectDir, 'src', 'data'), { recursive: true });
661
- fs.mkdirSync(path.join(projectDir, 'src', 'includes'), { recursive: true });
662
- fs.mkdirSync(path.join(projectDir, 'src', 'layouts', 'base-layout'), { recursive: true });
663
- fs.mkdirSync(path.join(projectDir, 'src', 'views'), { recursive: true });
664
- if (fs.existsSync(workspaceNodeModulesDir)) {
665
- fs.symlinkSync(workspaceNodeModulesDir, path.join(projectDir, 'node_modules'), 'dir');
666
- }
667
- fs.writeFileSync(
668
- path.join(projectDir, 'tsconfig.json'),
669
- JSON.stringify(
670
- {
671
- compilerOptions: {
672
- baseUrl: '.',
673
- jsx: 'react-jsx',
674
- jsxImportSource: '@kitajs/html',
675
- module: 'ESNext',
676
- moduleResolution: 'Bundler',
677
- paths: {
678
- '@/*': ['./src/*'],
679
- },
680
- },
681
- },
682
- null,
683
- 2,
684
- ),
685
- 'utf8',
686
- );
687
- fs.writeFileSync(
688
- path.join(projectDir, 'eco.config.ts'),
689
- [
690
- "import { ConfigBuilder } from '@ecopages/core/config-builder';",
691
- "import { kitajsPlugin } from '@ecopages/kitajs';",
692
- `const appRoot = ${JSON.stringify(projectDir)};`,
693
- 'const config = await new ConfigBuilder()',
694
- '\t.setRootDir(appRoot)',
695
- "\t.setBaseUrl('http://localhost:3000')",
696
- '\t.setIntegrations([kitajsPlugin()])',
697
- '\t.build();',
698
- 'export default config;',
699
- ].join('\n'),
700
- 'utf8',
701
- );
702
- fs.writeFileSync(
703
- path.join(projectDir, 'src', 'components', 'theme-toggle.react.tsx'),
704
- [
705
- '/** @jsxImportSource react */',
706
- "import { eco } from '@ecopages/core';",
707
- "import type { JSX } from 'react';",
708
- 'export const ThemeToggleReact = eco.component<{}, JSX.Element>({',
709
- "\tintegration: 'react',",
710
- '\trender: () => <button type="button">Toggle theme</button>,',
711
- '});',
712
- ].join('\n'),
713
- 'utf8',
714
- );
715
- fs.writeFileSync(
716
- path.join(projectDir, 'src', 'data', 'primary-links.ts'),
717
- [
718
- 'export function getPrimaryLinkTestId(href: string): string {',
719
- "\treturn `primary-link-${href.replace(/^\\//, '').replace(/\\//g, '-') || 'home'}`;",
720
- '}',
721
- "export const kitchenSinkShell = { eyebrow: 'Kitchen sink', title: 'Explicit route metadata' } as const;",
722
- "export const primaryLinks = [{ href: '/', label: 'Overview' }] as const;",
723
- ].join('\n'),
724
- 'utf8',
725
- );
726
- fs.writeFileSync(
727
- path.join(projectDir, 'src', 'includes', 'html.kita.tsx'),
728
- [
729
- "import { eco } from '@ecopages/core';",
730
- 'export default eco.html({',
731
- '\trender: ({ children }) => <html><body>{children}</body></html>,',
732
- '});',
733
- ].join('\n'),
734
- 'utf8',
735
- );
736
- fs.writeFileSync(
737
- path.join(projectDir, 'src', 'layouts', 'base-layout', 'base-layout.kita.tsx'),
738
- [
739
- "import { eco } from '@ecopages/core';",
740
- "import { ThemeToggleReact } from '../../components/theme-toggle.react';",
741
- "import { getPrimaryLinkTestId, kitchenSinkShell, primaryLinks } from '@/data/primary-links';",
742
- 'export const BaseLayout = eco.layout({',
743
- '\tdependencies: {',
744
- '\t\tcomponents: [ThemeToggleReact],',
745
- '\t},',
746
- '\trender: ({ children }) => (',
747
- '\t\t<div>',
748
- '\t\t\t<header>',
749
- '\t\t\t\t<p>{kitchenSinkShell.eyebrow}</p>',
750
- '\t\t\t\t<h1>{kitchenSinkShell.title}</h1>',
751
- '\t\t\t\t<nav>',
752
- '\t\t\t\t\t{primaryLinks.map((link) => (',
753
- '\t\t\t\t\t\t<a href={link.href} data-testid={getPrimaryLinkTestId(link.href)}>{link.label}</a>',
754
- '\t\t\t\t\t))}',
755
- '\t\t\t\t</nav>',
756
- '\t\t\t\t{/* @ts-expect-error - jsx mismatch */}',
757
- '\t\t\t\t<ThemeToggleReact />',
758
- '\t\t\t</header>',
759
- '\t\t\t<main data-layout="base-layout">{children}</main>',
760
- '\t\t</div>',
761
- '\t),',
762
- '});',
763
- ].join('\n'),
764
- 'utf8',
765
- );
766
- fs.writeFileSync(
767
- path.join(projectDir, 'src', 'layouts', 'base-layout', 'index.ts'),
768
- "export * from './base-layout.kita';\n",
769
- 'utf8',
770
- );
771
- fs.writeFileSync(
772
- path.join(projectDir, 'src', 'views', 'latest-view.kita.tsx'),
773
- [
774
- "import { eco } from '@ecopages/core';",
775
- "import { BaseLayout } from '@/layouts/base-layout';",
776
- 'export default eco.page({',
777
- '\tdependencies: {',
778
- '\t\tcomponents: [BaseLayout],',
779
- '\t},',
780
- "\tintegration: 'kitajs',",
781
- '\tlayout: BaseLayout,',
782
- '\trender: () => <section data-view="latest">Latest route body</section>,',
783
- '});',
784
- ].join('\n'),
785
- 'utf8',
786
- );
787
- fs.writeFileSync(
788
- path.join(projectDir, 'app.ts'),
789
- [
790
- "import { createApp } from '@ecopages/core';",
791
- "import appConfig from './eco.config';",
792
- 'const app = await createApp({ appConfig });',
793
- "app.get('/metadata', async (ctx) => {",
794
- "\tconst { default: LatestView } = await import('./src/views/latest-view.kita');",
795
- '\tconst initialComponentDependencies = LatestView.config?.dependencies?.components;',
796
- '\tconst initialMetadata = {',
797
- '\t\thasLayout: Boolean(LatestView.config?.layout),',
798
- '\t\thasEcoFile: Boolean(LatestView.config?.__eco?.file),',
799
- '\t\tcomponentDependencyCount:',
800
- '\t\t\tArray.isArray(initialComponentDependencies) ? initialComponentDependencies.length : 0,',
801
- '\t\tallComponentDependenciesDefined:',
802
- '\t\t\tArray.isArray(initialComponentDependencies) &&',
803
- '\t\t\tinitialComponentDependencies.every((component) => Boolean(component)),',
804
- '\t};',
805
- "\tconst barrelModule = await import('./src/layouts/base-layout');",
806
- "\tconst directLayoutModule = await import('./src/layouts/base-layout/base-layout.kita');",
807
- '\treturn ctx.json({',
808
- '\t\tbarrelHasLayoutExport: Boolean(barrelModule.BaseLayout),',
809
- '\t\tdirectHasLayoutExport: Boolean(directLayoutModule.BaseLayout),',
810
- '\t\t...initialMetadata,',
811
- '\t});',
812
- '});',
813
- 'export default app;',
814
- ].join('\n'),
815
- 'utf8',
816
- );
817
-
818
- const adapter = createNodeRuntimeAdapter();
819
- const manifest = assertNodeRuntimeManifest({
820
- runtime: 'node',
821
- appRootDir: projectDir,
822
- sourceRootDir: path.join(projectDir, 'src'),
823
- distDir: path.join(projectDir, 'dist'),
824
- modulePaths: {
825
- config: path.join(projectDir, 'eco.config.ts'),
826
- entry: path.join(projectDir, 'app.ts'),
827
- },
828
- });
829
-
830
- session = await adapter.start({
831
- manifest,
832
- workingDirectory: projectDir,
833
- cliArgs: ['app.ts', '--dev'],
834
- });
835
- const loadedAppRuntime = await session.loadApp();
836
- const runtimeApp = loadedAppRuntime.entryModule as {
837
- default?: {
838
- fetch(request: Request): Promise<Response>;
839
- };
840
- };
841
- assert.ok(runtimeApp.default);
842
-
843
- const metadataResponse = await runtimeApp.default.fetch(new Request('http://localhost:3000/metadata'));
844
- const metadata = (await metadataResponse.json()) as {
845
- barrelHasLayoutExport: boolean;
846
- directHasLayoutExport: boolean;
847
- hasLayout: boolean;
848
- hasEcoFile: boolean;
849
- componentDependencyCount: number;
850
- allComponentDependenciesDefined: boolean;
851
- };
852
-
853
- assert.deepEqual(metadata, {
854
- barrelHasLayoutExport: true,
855
- directHasLayoutExport: true,
856
- hasEcoFile: true,
857
- hasLayout: true,
858
- componentDependencyCount: 2,
859
- allComponentDependenciesDefined: true,
860
- });
861
- } finally {
862
- if (session) {
863
- const activeSession = session;
864
- await assert.doesNotReject(() => activeSession.dispose());
865
- }
866
- fs.rmSync(projectDir, { recursive: true, force: true });
867
- }
868
- }, 15000);