@ecopages/core 0.2.0-beta.4 → 0.2.0-beta.40

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 (611) hide show
  1. package/README.md +40 -9
  2. package/package.json +371 -33
  3. package/src/adapters/README.md +6 -2
  4. package/src/adapters/abstract/application-adapter.d.ts +115 -6
  5. package/src/adapters/abstract/application-adapter.js +261 -120
  6. package/src/adapters/abstract/router-adapter.js +12 -4
  7. package/src/adapters/abstract/segment-path-matcher.d.ts +6 -0
  8. package/src/adapters/abstract/segment-path-matcher.js +147 -0
  9. package/src/adapters/abstract/server-adapter.d.ts +16 -2
  10. package/src/adapters/abstract/server-adapter.js +22 -14
  11. package/src/adapters/abstract/ws-pattern-matcher.d.ts +12 -0
  12. package/src/adapters/abstract/ws-pattern-matcher.js +28 -0
  13. package/src/adapters/bun/bun-user-websocket-lifecycle.d.ts +22 -0
  14. package/src/adapters/bun/bun-user-websocket-lifecycle.js +93 -0
  15. package/src/adapters/bun/client-bridge.d.ts +1 -0
  16. package/src/adapters/bun/client-bridge.js +51 -47
  17. package/src/adapters/bun/create-app.d.ts +9 -6
  18. package/src/adapters/bun/create-app.js +171 -130
  19. package/src/adapters/bun/hmr-manager.d.ts +1 -1
  20. package/src/adapters/bun/hmr-manager.js +62 -57
  21. package/src/adapters/bun/index.d.ts +1 -1
  22. package/src/adapters/bun/index.js +2 -8
  23. package/src/adapters/bun/runtime-host.d.ts +1 -1
  24. package/src/adapters/bun/runtime-host.js +61 -54
  25. package/src/adapters/bun/server-adapter.d.ts +91 -41
  26. package/src/adapters/bun/server-adapter.js +566 -426
  27. package/src/adapters/bun/static-preview-host.d.ts +1 -1
  28. package/src/adapters/bun/static-preview-host.js +43 -41
  29. package/src/adapters/create-app.d.ts +13 -11
  30. package/src/adapters/create-app.js +11 -63
  31. package/src/adapters/index.d.ts +2 -2
  32. package/src/adapters/index.js +2 -8
  33. package/src/adapters/node/create-app.d.ts +8 -3
  34. package/src/adapters/node/create-app.js +126 -84
  35. package/src/adapters/node/http-request-bridge.js +147 -106
  36. package/src/adapters/node/node-client-bridge.d.ts +1 -0
  37. package/src/adapters/node/node-client-bridge.js +62 -61
  38. package/src/adapters/node/node-hmr-manager.d.ts +1 -1
  39. package/src/adapters/node/node-hmr-manager.js +58 -48
  40. package/src/adapters/node/runtime-host.d.ts +1 -1
  41. package/src/adapters/node/runtime-host.js +96 -89
  42. package/src/adapters/node/server-adapter-dependencies.js +18 -17
  43. package/src/adapters/node/server-adapter.d.ts +63 -23
  44. package/src/adapters/node/server-adapter.js +346 -297
  45. package/src/adapters/node/static-content-server.d.ts +1 -0
  46. package/src/adapters/node/static-content-server.js +172 -183
  47. package/src/adapters/node/static-preview-host.d.ts +1 -1
  48. package/src/adapters/node/static-preview-host.js +88 -64
  49. package/src/adapters/shared/hmr/dev-transform-entrypoint-registry.d.ts +16 -0
  50. package/src/adapters/shared/hmr/dev-transform-entrypoint-registry.js +32 -0
  51. package/src/adapters/shared/{hmr-html-response.d.ts → hmr/hmr-html-response.d.ts} +2 -2
  52. package/src/adapters/shared/hmr/hmr-html-response.js +50 -0
  53. package/src/adapters/shared/hmr/shared-hmr-manager.d.ts +92 -0
  54. package/src/adapters/shared/hmr/shared-hmr-manager.js +446 -0
  55. package/src/adapters/shared/http/api-request-pipeline.d.ts +23 -0
  56. package/src/adapters/shared/http/api-request-pipeline.js +132 -0
  57. package/src/adapters/shared/{api-response.d.ts → http/api-response.d.ts} +1 -1
  58. package/src/adapters/shared/http/api-response.js +79 -0
  59. package/src/adapters/shared/http/create-body-response.d.ts +12 -0
  60. package/src/adapters/shared/http/create-body-response.js +26 -0
  61. package/src/adapters/shared/http/define-api-handler.d.ts +90 -0
  62. package/src/adapters/shared/http/define-api-handler.js +49 -0
  63. package/src/adapters/shared/{explicit-static-render-preparation.d.ts → http/explicit-static-render-preparation.d.ts} +3 -3
  64. package/src/adapters/shared/http/explicit-static-render-preparation.js +29 -0
  65. package/src/adapters/shared/{explicit-static-route-matcher.d.ts → http/explicit-static-route-matcher.d.ts} +3 -9
  66. package/src/adapters/shared/http/explicit-static-route-matcher.js +59 -0
  67. package/src/adapters/shared/{file-route-middleware-pipeline.d.ts → http/file-route-middleware-pipeline.d.ts} +2 -2
  68. package/src/adapters/shared/http/file-route-middleware-pipeline.js +84 -0
  69. package/src/adapters/shared/{fs-server-response-factory.d.ts → http/fs-server-response-factory.d.ts} +7 -2
  70. package/src/adapters/shared/http/fs-server-response-factory.js +106 -0
  71. package/src/adapters/shared/{fs-server-response-matcher.d.ts → http/fs-server-response-matcher.d.ts} +25 -5
  72. package/src/adapters/shared/http/fs-server-response-matcher.js +258 -0
  73. package/src/adapters/shared/http/run-middleware-chain.d.ts +5 -0
  74. package/src/adapters/shared/http/run-middleware-chain.js +17 -0
  75. package/src/adapters/shared/{application-adapter.d.ts → runtime/application-adapter.d.ts} +2 -2
  76. package/src/adapters/shared/runtime/application-adapter.js +75 -0
  77. package/src/adapters/shared/runtime/collect-dev-prewarm-plan.d.ts +11 -0
  78. package/src/adapters/shared/runtime/collect-dev-prewarm-plan.js +29 -0
  79. package/src/adapters/shared/runtime/copy-runtime-public-dir.d.ts +6 -0
  80. package/src/adapters/shared/runtime/copy-runtime-public-dir.js +27 -0
  81. package/src/adapters/shared/runtime/dev-static-route-prewarm.d.ts +16 -0
  82. package/src/adapters/shared/runtime/dev-static-route-prewarm.js +66 -0
  83. package/src/adapters/shared/runtime/port-manager.d.ts +116 -0
  84. package/src/adapters/shared/runtime/port-manager.js +226 -0
  85. package/src/adapters/shared/{render-context.d.ts → runtime/render-context.d.ts} +2 -2
  86. package/src/adapters/shared/runtime/render-context.js +99 -0
  87. package/src/adapters/shared/{runtime-app-bootstrap.d.ts → runtime/runtime-app-bootstrap.d.ts} +4 -3
  88. package/src/adapters/shared/runtime/runtime-app-bootstrap.js +38 -0
  89. package/src/adapters/shared/runtime/runtime-server-lifecycle.d.ts +45 -0
  90. package/src/adapters/shared/runtime/runtime-server-lifecycle.js +71 -0
  91. package/src/adapters/shared/{server-adapter.d.ts → runtime/server-adapter.d.ts} +31 -50
  92. package/src/adapters/shared/runtime/server-adapter.js +301 -0
  93. package/src/adapters/shared/{server-route-handler.d.ts → runtime/server-route-handler.d.ts} +6 -33
  94. package/src/adapters/shared/runtime/server-route-handler.js +77 -0
  95. package/src/adapters/shared/{server-static-builder.d.ts → runtime/server-static-builder.d.ts} +27 -35
  96. package/src/adapters/shared/runtime/server-static-builder.js +172 -0
  97. package/src/adapters/shared/{static-preview-host.d.ts → runtime/static-preview-host.d.ts} +6 -1
  98. package/src/adapters/shared/ws/node-http-websocket-upgrades.d.ts +21 -0
  99. package/src/adapters/shared/ws/node-http-websocket-upgrades.js +109 -0
  100. package/src/adapters/shared/ws/websocket-lifecycle.d.ts +24 -0
  101. package/src/adapters/shared/ws/websocket-lifecycle.js +62 -0
  102. package/src/build/README.md +191 -31
  103. package/src/build/app-build-manifest-runtime.d.ts +39 -0
  104. package/src/build/app-build-manifest-runtime.js +145 -0
  105. package/src/build/browser/browser-runtime-manifest.js +58 -0
  106. package/src/build/browser/browser-runtime-plugin-helpers.js +34 -0
  107. package/src/build/{browser-runtime-plugin.d.ts → browser/browser-runtime-plugin.d.ts} +1 -1
  108. package/src/build/browser/browser-runtime-plugin.js +216 -0
  109. package/src/build/browser/jsx-ownership-plugins.d.ts +24 -0
  110. package/src/build/browser/jsx-ownership-plugins.js +55 -0
  111. package/src/build/browser/lit-static-render-worker-context.d.ts +2 -0
  112. package/src/build/browser/lit-static-render-worker-context.js +4 -0
  113. package/src/build/build-adapter.d.ts +29 -334
  114. package/src/build/build-adapter.js +273 -237
  115. package/src/build/cache/build-input-fingerprint.d.ts +28 -0
  116. package/src/build/cache/build-input-fingerprint.js +33 -0
  117. package/src/build/cache/cache-constants.d.ts +4 -0
  118. package/src/build/cache/cache-constants.js +4 -0
  119. package/src/build/cache/cache-keys.d.ts +22 -0
  120. package/src/build/cache/cache-keys.js +71 -0
  121. package/src/build/cache/pages-unified-graph-build.d.ts +31 -0
  122. package/src/build/cache/pages-unified-graph-build.js +199 -0
  123. package/src/build/cache/production-build-cache.d.ts +21 -0
  124. package/src/build/cache/production-build-cache.js +56 -0
  125. package/src/build/cache/server-entry-build-cache.d.ts +43 -0
  126. package/src/build/cache/server-entry-build-cache.js +153 -0
  127. package/src/build/contracts/build-contracts.d.ts +96 -0
  128. package/src/build/contracts/build-contracts.js +1 -0
  129. package/src/build/contracts/build-manifest.d.ts +90 -0
  130. package/src/build/contracts/build-manifest.js +64 -0
  131. package/src/build/contracts/build-types.js +1 -0
  132. package/src/build/contracts/content-virtual-modules.d.ts +12 -0
  133. package/src/build/contracts/content-virtual-modules.js +29 -0
  134. package/src/build/{rolldown-adapter-helpers.d.ts → rolldown/rolldown-adapter-helpers.d.ts} +32 -9
  135. package/src/build/rolldown/rolldown-adapter-helpers.js +458 -0
  136. package/src/build/{rolldown-build-adapter.d.ts → rolldown/rolldown-build-adapter.d.ts} +3 -7
  137. package/src/build/rolldown/rolldown-build-adapter.js +57 -0
  138. package/src/build/rolldown/rolldown-build-invocation-metrics.d.ts +12 -0
  139. package/src/build/rolldown/rolldown-build-invocation-metrics.js +39 -0
  140. package/src/build/{rolldown-plugin-bridge.d.ts → rolldown/rolldown-plugin-bridge.d.ts} +16 -2
  141. package/src/build/rolldown/rolldown-plugin-bridge.js +284 -0
  142. package/src/build/rolldown/rolldown-source-transform-pass.d.ts +15 -0
  143. package/src/build/rolldown/rolldown-source-transform-pass.js +70 -0
  144. package/src/build/rolldown/runtime-build-output-normalizer.d.ts +10 -0
  145. package/src/build/rolldown/runtime-build-output-normalizer.js +253 -0
  146. package/src/build/rolldown/server-side-css-shim-plugin.js +58 -0
  147. package/src/build/runtime/build-profile-options.d.ts +7 -0
  148. package/src/build/runtime/build-profile-options.js +37 -0
  149. package/src/build/runtime/build-request-identity.d.ts +17 -0
  150. package/src/build/runtime/build-request-identity.js +79 -0
  151. package/src/build/runtime/build-request-policy.d.ts +58 -0
  152. package/src/build/runtime/build-request-policy.js +84 -0
  153. package/src/build/runtime/build-runtime.d.ts +28 -0
  154. package/src/build/runtime/build-runtime.js +75 -0
  155. package/src/build/runtime/deduping-build-executor.d.ts +21 -0
  156. package/src/build/runtime/deduping-build-executor.js +40 -0
  157. package/src/build/runtime/parallel-build-executor.d.ts +21 -0
  158. package/src/build/runtime/parallel-build-executor.js +60 -0
  159. package/src/build/{serialized-build-executor.d.ts → runtime/serialized-build-executor.d.ts} +1 -1
  160. package/src/build/runtime/serialized-build-executor.js +79 -0
  161. package/src/cache/index.d.ts +2 -1
  162. package/src/cache/index.js +7 -6
  163. package/src/cache/module-parse-cache.d.ts +5 -0
  164. package/src/cache/module-parse-cache.js +122 -67
  165. package/src/cache/module-transform-profiler.d.ts +8 -0
  166. package/src/cache/module-transform-profiler.js +8 -0
  167. package/src/client/navigation-scripts/classification.d.ts +16 -0
  168. package/src/client/navigation-scripts/classification.js +49 -0
  169. package/src/client/navigation-scripts/index.d.ts +3 -0
  170. package/src/client/navigation-scripts/index.js +3 -0
  171. package/src/client/navigation-scripts/navigation-scripts.test.browser.d.ts +1 -0
  172. package/src/client/navigation-scripts/navigation-scripts.test.browser.js +61 -0
  173. package/src/client/navigation-scripts/registry.d.ts +11 -0
  174. package/src/client/navigation-scripts/registry.js +16 -0
  175. package/src/client/navigation-scripts/rerun-queue.d.ts +37 -0
  176. package/src/client/navigation-scripts/rerun-queue.js +90 -0
  177. package/src/client/scroll.d.ts +17 -0
  178. package/src/client/scroll.js +33 -0
  179. package/src/client/scroll.test.browser.d.ts +1 -0
  180. package/src/client/scroll.test.browser.js +31 -0
  181. package/src/client/view-transitions.d.ts +32 -0
  182. package/src/client/view-transitions.js +120 -0
  183. package/src/client/view-transitions.test.browser.d.ts +1 -0
  184. package/src/client/view-transitions.test.browser.js +56 -0
  185. package/src/config/config-builder.d.ts +40 -10
  186. package/src/config/config-builder.js +647 -600
  187. package/src/config/constants.d.ts +1 -0
  188. package/src/config/constants.js +44 -23
  189. package/src/declarations.d.ts +1 -0
  190. package/src/dev/README.md +24 -0
  191. package/src/dev/client-bridge-registry.d.ts +5 -0
  192. package/src/dev/client-bridge-registry.js +10 -0
  193. package/src/dev/dev-client-ownership.d.ts +7 -0
  194. package/src/dev/dev-client-ownership.js +8 -0
  195. package/src/dev/hmr-manager-registry.d.ts +8 -0
  196. package/src/dev/hmr-manager-registry.js +10 -0
  197. package/src/dev/host-runtime.d.ts +3 -0
  198. package/src/dev/host-runtime.js +25 -23
  199. package/src/dev/runtime-server-started-message.d.ts +2 -0
  200. package/src/dev/runtime-server-started-message.js +3 -0
  201. package/src/dev/sc-server.js +106 -103
  202. package/src/dev/transform-server/dev-transform-bundler.d.ts +24 -0
  203. package/src/dev/transform-server/dev-transform-bundler.js +79 -0
  204. package/src/dev/transform-server/dev-transform-externalize-plugin.d.ts +12 -0
  205. package/src/dev/transform-server/dev-transform-externalize-plugin.js +29 -0
  206. package/src/dev/transform-server/dev-transform-import-rewriter.d.ts +16 -0
  207. package/src/dev/transform-server/dev-transform-import-rewriter.js +126 -0
  208. package/src/dev/transform-server/dev-transform-module-kind.d.ts +13 -0
  209. package/src/dev/transform-server/dev-transform-module-kind.js +17 -0
  210. package/src/dev/transform-server/dev-transform-runtime-specifiers.d.ts +5 -0
  211. package/src/dev/transform-server/dev-transform-runtime-specifiers.js +16 -0
  212. package/src/dev/transform-server/dev-transform-server.d.ts +41 -0
  213. package/src/dev/transform-server/dev-transform-server.js +191 -0
  214. package/src/dev/transform-server/dev-transform-url.d.ts +13 -0
  215. package/src/dev/transform-server/dev-transform-url.js +58 -0
  216. package/src/dev/transform-server/dev-transform-vendor-registry.d.ts +28 -0
  217. package/src/dev/transform-server/dev-transform-vendor-registry.js +158 -0
  218. package/src/dev/transform-server/index.d.ts +6 -0
  219. package/src/dev/transform-server/index.js +4 -0
  220. package/src/dev/transform-server/types.d.ts +15 -0
  221. package/src/dev/transform-server/types.js +1 -0
  222. package/src/dev-toolbar/README.md +52 -0
  223. package/src/dev-toolbar/define-dev-tool.d.ts +21 -0
  224. package/src/dev-toolbar/define-dev-tool.js +9 -0
  225. package/src/dev-toolbar/dev-toolbar-config.d.ts +25 -0
  226. package/src/dev-toolbar/dev-toolbar-config.js +19 -0
  227. package/src/dev-toolbar/dev-toolbar-host.d.ts +49 -0
  228. package/src/dev-toolbar/dev-toolbar-host.js +117 -0
  229. package/src/dev-toolbar/dev-toolbar-html-response.d.ts +11 -0
  230. package/src/dev-toolbar/dev-toolbar-html-response.js +14 -0
  231. package/src/dev-toolbar/dev-toolbar-manifest-contract.d.ts +22 -0
  232. package/src/dev-toolbar/dev-toolbar-manifest-contract.js +2 -0
  233. package/src/dev-toolbar/dev-toolbar-manifest.d.ts +15 -0
  234. package/src/dev-toolbar/dev-toolbar-manifest.js +52 -0
  235. package/src/dev-toolbar/dev-toolbar-package.d.ts +34 -0
  236. package/src/dev-toolbar/dev-toolbar-package.js +78 -0
  237. package/src/dev-toolbar/dev-toolbar-runtime-paths.d.ts +10 -0
  238. package/src/dev-toolbar/dev-toolbar-runtime-paths.js +13 -0
  239. package/src/diagnostics/request-build-dedupe.d.ts +18 -0
  240. package/src/diagnostics/request-build-dedupe.js +39 -0
  241. package/src/diagnostics/request-pipeline-metrics.d.ts +38 -0
  242. package/src/diagnostics/request-pipeline-metrics.js +121 -0
  243. package/src/diagnostics/startup-trace.d.ts +81 -0
  244. package/src/diagnostics/startup-trace.js +281 -0
  245. package/src/eco/README.md +17 -0
  246. package/src/eco/component-identity.d.ts +13 -0
  247. package/src/eco/component-identity.js +18 -0
  248. package/src/eco/eco-declared-component.d.ts +15 -0
  249. package/src/eco/eco-declared-component.js +23 -0
  250. package/src/eco/eco.browser.js +63 -70
  251. package/src/eco/eco.js +163 -97
  252. package/src/eco/eco.types.d.ts +47 -8
  253. package/src/eco/eco.types.js +5 -0
  254. package/src/eco/eco.utils.d.ts +1 -1
  255. package/src/eco/eco.utils.js +1 -10
  256. package/src/eco/global-injector-map.js +55 -41
  257. package/src/eco/lazy-injector-map.js +90 -60
  258. package/src/eco/module-dependencies.js +52 -44
  259. package/src/eco/page-layout-normalization.d.ts +21 -0
  260. package/src/eco/page-layout-normalization.js +69 -0
  261. package/src/env.d.ts +2 -0
  262. package/src/errors/http-error.d.ts +8 -0
  263. package/src/errors/http-error.js +66 -49
  264. package/src/errors/index.d.ts +1 -0
  265. package/src/errors/index.js +3 -6
  266. package/src/errors/locals-access-error.js +5 -8
  267. package/src/errors/undeclared-component-dependency-error.d.ts +11 -0
  268. package/src/errors/undeclared-component-dependency-error.js +17 -0
  269. package/src/global/app-logger.js +3 -6
  270. package/src/hmr/README.md +21 -0
  271. package/src/hmr/client/hmr-runtime.js +119 -110
  272. package/src/hmr/client/module-update.d.ts +13 -0
  273. package/src/hmr/client/module-update.js +39 -0
  274. package/src/hmr/hmr-asset-paths.d.ts +14 -0
  275. package/src/hmr/hmr-asset-paths.js +22 -0
  276. package/src/hmr/hmr-entrypoint-output.d.ts +21 -0
  277. package/src/hmr/hmr-entrypoint-output.js +34 -0
  278. package/src/hmr/hmr-file-change-prep.d.ts +10 -0
  279. package/src/hmr/hmr-file-change-prep.js +14 -0
  280. package/src/hmr/hmr-registered-entrypoints-context.d.ts +7 -0
  281. package/src/hmr/hmr-registered-entrypoints-context.js +1 -0
  282. package/src/hmr/hmr-runtime-paths.d.ts +10 -0
  283. package/src/hmr/hmr-runtime-paths.js +13 -0
  284. package/src/hmr/hmr-strategy.d.ts +9 -0
  285. package/src/hmr/hmr-strategy.js +113 -42
  286. package/src/hmr/strategies/default-hmr-strategy.js +55 -33
  287. package/src/hmr/strategies/js-hmr-strategy.d.ts +6 -97
  288. package/src/hmr/strategies/js-hmr-strategy.js +107 -167
  289. package/src/hmr/strategies/server-rendered-template-hmr-strategy.d.ts +17 -0
  290. package/src/hmr/strategies/server-rendered-template-hmr-strategy.js +35 -0
  291. package/src/index.browser.d.ts +1 -0
  292. package/src/index.browser.js +2 -4
  293. package/src/index.d.ts +4 -1
  294. package/src/index.js +7 -21
  295. package/src/integrations/ghtml/ghtml-renderer.d.ts +2 -6
  296. package/src/integrations/ghtml/ghtml-renderer.js +12 -56
  297. package/src/integrations/ghtml/ghtml.constants.js +1 -4
  298. package/src/integrations/ghtml/ghtml.plugin.d.ts +3 -16
  299. package/src/integrations/ghtml/ghtml.plugin.js +10 -20
  300. package/src/islands/README.md +25 -0
  301. package/src/islands/island-host.d.ts +37 -0
  302. package/src/islands/island-host.js +55 -0
  303. package/src/plugins/README.md +2 -1
  304. package/src/plugins/alias-resolver-cache.d.ts +6 -9
  305. package/src/plugins/alias-resolver-cache.js +114 -97
  306. package/src/plugins/alias-resolver-plugin.d.ts +3 -3
  307. package/src/plugins/alias-resolver-plugin.js +35 -62
  308. package/src/plugins/define-integration.d.ts +26 -0
  309. package/src/plugins/define-integration.js +20 -0
  310. package/src/plugins/eco-component-meta-plugin.d.ts +6 -102
  311. package/src/plugins/eco-component-meta-plugin.js +120 -162
  312. package/src/plugins/foreign-jsx-override-plugin.d.ts +1 -1
  313. package/src/plugins/foreign-jsx-override-plugin.js +49 -37
  314. package/src/plugins/integration-plugin.d.ts +43 -14
  315. package/src/plugins/integration-plugin.js +212 -190
  316. package/src/plugins/jsx-import-source.utils.d.ts +8 -0
  317. package/src/plugins/jsx-import-source.utils.js +21 -0
  318. package/src/plugins/processor.d.ts +71 -12
  319. package/src/plugins/processor.js +168 -130
  320. package/src/plugins/runtime-capability.js +1 -0
  321. package/src/plugins/source-transform.d.ts +32 -1
  322. package/src/plugins/source-transform.js +112 -60
  323. package/src/plugins/tsconfig-import-resolver.d.ts +35 -0
  324. package/src/plugins/tsconfig-import-resolver.js +235 -0
  325. package/src/route-renderer/GRAPH.md +26 -32
  326. package/src/route-renderer/README.md +54 -33
  327. package/src/route-renderer/orchestration/document-shell/document-shell-render.service.d.ts +107 -0
  328. package/src/route-renderer/orchestration/document-shell/document-shell-render.service.js +155 -0
  329. package/src/route-renderer/orchestration/document-shell/layout-shell-props.service.d.ts +20 -0
  330. package/src/route-renderer/orchestration/document-shell/layout-shell-props.service.js +37 -0
  331. package/src/route-renderer/orchestration/{component-render-context.d.ts → foreign-child/component-render-context.d.ts} +8 -15
  332. package/src/route-renderer/orchestration/foreign-child/component-render-context.js +196 -0
  333. package/src/route-renderer/orchestration/{render-output.utils.d.ts → foreign-child/foreign-child-output.utils.d.ts} +17 -7
  334. package/src/route-renderer/orchestration/foreign-child/foreign-child-output.utils.js +191 -0
  335. package/src/route-renderer/orchestration/{foreign-subtree-execution.service.d.ts → foreign-child/foreign-subtree-execution.service.d.ts} +64 -34
  336. package/src/route-renderer/orchestration/foreign-child/foreign-subtree-execution.service.js +354 -0
  337. package/src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.d.ts +19 -0
  338. package/src/route-renderer/orchestration/foreign-child/owning-renderer-resolution.js +36 -0
  339. package/src/route-renderer/orchestration/integration-renderer.d.ts +41 -151
  340. package/src/route-renderer/orchestration/integration-renderer.js +798 -988
  341. package/src/route-renderer/orchestration/integration-renderer.test-fixtures.d.ts +75 -0
  342. package/src/route-renderer/orchestration/integration-renderer.test-fixtures.js +173 -0
  343. package/src/route-renderer/orchestration/ownership-graph/component-graph-collectors.d.ts +10 -0
  344. package/src/route-renderer/orchestration/ownership-graph/component-graph-collectors.js +132 -0
  345. package/src/route-renderer/orchestration/ownership-graph/component-graph.d.ts +34 -0
  346. package/src/route-renderer/orchestration/ownership-graph/component-graph.js +89 -0
  347. package/src/route-renderer/orchestration/{ownership-validation.service.d.ts → ownership-graph/ownership-validation.service.d.ts} +6 -2
  348. package/src/route-renderer/orchestration/ownership-graph/ownership-validation.service.js +77 -0
  349. package/src/route-renderer/orchestration/page-browser-graph/global-injector-assets.service.d.ts +7 -0
  350. package/src/route-renderer/orchestration/page-browser-graph/global-injector-assets.service.js +30 -0
  351. package/src/route-renderer/orchestration/page-browser-graph/grouped-graph-build-plan.d.ts +15 -0
  352. package/src/route-renderer/orchestration/page-browser-graph/grouped-graph-build-plan.js +9 -0
  353. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-contribution.merge.d.ts +5 -0
  354. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-contribution.merge.js +30 -0
  355. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.d.ts +12 -0
  356. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-merge.utils.js +32 -0
  357. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-session.d.ts +126 -0
  358. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph-session.js +542 -0
  359. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph.service.d.ts +47 -0
  360. package/src/route-renderer/orchestration/page-browser-graph/page-browser-graph.service.js +232 -0
  361. package/src/route-renderer/orchestration/{processed-asset-dedupe.d.ts → page-browser-graph/processed-asset-dedupe.d.ts} +1 -1
  362. package/src/route-renderer/orchestration/page-browser-graph/processed-asset-dedupe.js +23 -0
  363. package/src/route-renderer/orchestration/page-browser-graph/route-instance-key.d.ts +29 -0
  364. package/src/route-renderer/orchestration/page-browser-graph/route-instance-key.js +54 -0
  365. package/src/route-renderer/orchestration/route-pipeline/integration-route-render-adapter.d.ts +38 -0
  366. package/src/route-renderer/orchestration/route-pipeline/integration-route-render-adapter.js +26 -0
  367. package/src/route-renderer/orchestration/route-pipeline/marker-artifact.utils.d.ts +6 -0
  368. package/src/route-renderer/orchestration/route-pipeline/marker-artifact.utils.js +25 -0
  369. package/src/route-renderer/orchestration/route-pipeline/robots-meta.contribution.d.ts +15 -0
  370. package/src/route-renderer/orchestration/route-pipeline/robots-meta.contribution.js +43 -0
  371. package/src/route-renderer/orchestration/route-pipeline/route-html-finalization.service.d.ts +25 -0
  372. package/src/route-renderer/orchestration/route-pipeline/route-html-finalization.service.js +44 -0
  373. package/src/route-renderer/orchestration/route-pipeline/route-prepared-options.builder.d.ts +26 -0
  374. package/src/route-renderer/orchestration/route-pipeline/route-prepared-options.builder.js +49 -0
  375. package/src/route-renderer/orchestration/route-pipeline/route-prepared-options.utils.d.ts +4 -0
  376. package/src/route-renderer/orchestration/route-pipeline/route-prepared-options.utils.js +30 -0
  377. package/src/route-renderer/orchestration/{route-render-orchestrator.d.ts → route-pipeline/route-render-orchestrator.d.ts} +24 -54
  378. package/src/route-renderer/orchestration/route-pipeline/route-render-orchestrator.js +215 -0
  379. package/src/route-renderer/orchestration/string-markup-renderer.d.ts +14 -0
  380. package/src/route-renderer/orchestration/string-markup-renderer.js +52 -0
  381. package/src/route-renderer/page-loading/component-dependency-collection.js +121 -121
  382. package/src/route-renderer/page-loading/declared-asset-collection.js +66 -94
  383. package/src/route-renderer/page-loading/dependency-resolver.js +101 -104
  384. package/src/route-renderer/page-loading/ecopages-virtual-imports.d.ts +1 -0
  385. package/src/route-renderer/page-loading/ecopages-virtual-imports.js +64 -51
  386. package/src/route-renderer/page-loading/file-scoped-dependency-components.d.ts +42 -0
  387. package/src/route-renderer/page-loading/file-scoped-dependency-components.js +94 -0
  388. package/src/route-renderer/page-loading/lazy-entry-collection.js +75 -98
  389. package/src/route-renderer/page-loading/lazy-trigger-planning.js +47 -36
  390. package/src/route-renderer/page-loading/module-declaration-aggregation.js +39 -28
  391. package/src/route-renderer/page-loading/module-declaration-scripts.js +10 -15
  392. package/src/route-renderer/page-loading/page-dependency-bundling.js +156 -113
  393. package/src/route-renderer/page-loading/page-module-loader.d.ts +2 -1
  394. package/src/route-renderer/page-loading/page-module-loader.js +136 -124
  395. package/src/route-renderer/page-loading/resolved-page-dependencies.d.ts +12 -0
  396. package/src/route-renderer/page-loading/resolved-page-dependencies.js +38 -0
  397. package/src/route-renderer/route-renderer.js +74 -76
  398. package/src/router/README.md +31 -0
  399. package/src/router/client/link-intent.d.ts +11 -21
  400. package/src/router/client/link-intent.js +56 -30
  401. package/src/router/client/link-intent.test.browser.js +50 -39
  402. package/src/router/client/link-navigation-policy.d.ts +45 -0
  403. package/src/router/client/link-navigation-policy.js +122 -0
  404. package/src/router/client/link-navigation-policy.test.browser.d.ts +1 -0
  405. package/src/router/client/link-navigation-policy.test.browser.js +82 -0
  406. package/src/router/client/navigation-coordinator.d.ts +1 -1
  407. package/src/router/client/navigation-coordinator.js +235 -201
  408. package/src/router/client/navigation-lifecycle.d.ts +55 -0
  409. package/src/router/client/navigation-lifecycle.js +50 -0
  410. package/src/router/client/navigation-lifecycle.test.browser.d.ts +1 -0
  411. package/src/router/client/navigation-lifecycle.test.browser.js +118 -0
  412. package/src/router/server/route-registry.js +237 -242
  413. package/src/services/README.md +5 -0
  414. package/src/services/assets/asset-processing-service/asset-dependency-keys.d.ts +13 -0
  415. package/src/services/assets/asset-processing-service/asset-dependency-keys.js +64 -50
  416. package/src/services/assets/asset-processing-service/asset-processing.service.d.ts +7 -1
  417. package/src/services/assets/asset-processing-service/asset-processing.service.js +308 -268
  418. package/src/services/assets/asset-processing-service/asset.factory.js +78 -81
  419. package/src/services/assets/asset-processing-service/assets.types.d.ts +1 -1
  420. package/src/services/assets/asset-processing-service/assets.types.js +1 -0
  421. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.d.ts +2 -1
  422. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +57 -45
  423. package/src/services/assets/asset-processing-service/browser-runtime-entry-resolution.d.ts +52 -0
  424. package/src/services/assets/asset-processing-service/browser-runtime-entry-resolution.js +115 -0
  425. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.d.ts +4 -2
  426. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.js +53 -38
  427. package/src/services/assets/asset-processing-service/finalize-processed-asset.d.ts +3 -0
  428. package/src/services/assets/asset-processing-service/finalize-processed-asset.js +5 -0
  429. package/src/services/assets/asset-processing-service/grouped-content-bundles.d.ts +2 -1
  430. package/src/services/assets/asset-processing-service/grouped-content-bundles.js +85 -60
  431. package/src/services/assets/asset-processing-service/index.d.ts +2 -0
  432. package/src/services/assets/asset-processing-service/index.js +8 -6
  433. package/src/services/assets/asset-processing-service/inline-content-script-body.d.ts +11 -0
  434. package/src/services/assets/asset-processing-service/inline-content-script-body.js +23 -0
  435. package/src/services/assets/asset-processing-service/materialize-content-script-asset.d.ts +9 -0
  436. package/src/services/assets/asset-processing-service/materialize-content-script-asset.js +22 -0
  437. package/src/services/assets/asset-processing-service/page-package.js +70 -72
  438. package/src/services/assets/asset-processing-service/processor.interface.js +7 -5
  439. package/src/services/assets/asset-processing-service/processor.registry.js +11 -14
  440. package/src/services/assets/asset-processing-service/processors/base/base-processor.js +59 -62
  441. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.d.ts +0 -2
  442. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.js +102 -130
  443. package/src/services/assets/asset-processing-service/processors/index.js +5 -5
  444. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.d.ts +8 -0
  445. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.js +111 -111
  446. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.d.ts +0 -1
  447. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +95 -94
  448. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +136 -121
  449. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.d.ts +0 -3
  450. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +26 -57
  451. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.d.ts +0 -3
  452. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +33 -67
  453. package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.d.ts +2 -0
  454. package/src/services/assets/asset-processing-service/processors/stylesheet/stylesheet-processor-pipeline.js +44 -0
  455. package/src/services/assets/asset-processing-service/resolve-integration-plugin.d.ts +4 -0
  456. package/src/services/assets/asset-processing-service/resolve-integration-plugin.js +15 -0
  457. package/src/services/assets/asset-processing-service/ungrouped-dependency-processing.d.ts +0 -1
  458. package/src/services/assets/asset-processing-service/ungrouped-dependency-processing.js +27 -44
  459. package/src/services/assets/browser-bundle.service.d.ts +28 -30
  460. package/src/services/assets/browser-bundle.service.js +54 -40
  461. package/src/services/cache/cache.types.d.ts +4 -2
  462. package/src/services/cache/cache.types.js +5 -0
  463. package/src/services/cache/html-page-cache-dependency-index.d.ts +34 -0
  464. package/src/services/cache/html-page-cache-dependency-index.js +88 -0
  465. package/src/services/cache/index.d.ts +2 -0
  466. package/src/services/cache/index.js +8 -7
  467. package/src/services/cache/memory-cache-store.js +101 -89
  468. package/src/services/cache/page-cache-service.d.ts +31 -1
  469. package/src/services/cache/page-cache-service.js +237 -150
  470. package/src/services/cache/page-request-cache-coordinator.service.js +106 -102
  471. package/src/services/html/html-rewriter-provider.service.js +61 -61
  472. package/src/services/html/html-transformer.service.d.ts +1 -1
  473. package/src/services/html/html-transformer.service.js +249 -266
  474. package/src/services/invalidation/development-invalidation.service.d.ts +25 -2
  475. package/src/services/invalidation/development-invalidation.service.js +239 -175
  476. package/src/services/module-loading/README.md +52 -0
  477. package/src/services/module-loading/app-module-loader.service.js +1 -0
  478. package/src/services/module-loading/app-server-module-transpiler.service.d.ts +8 -0
  479. package/src/services/module-loading/app-server-module-transpiler.service.js +103 -118
  480. package/src/services/module-loading/collection-server-module-build.service.d.ts +19 -0
  481. package/src/services/module-loading/collection-server-module-build.service.js +83 -0
  482. package/src/services/module-loading/host-module-loader-registry.js +6 -11
  483. package/src/services/module-loading/module-loading-types.js +1 -0
  484. package/src/services/module-loading/page-module-import.service.d.ts +11 -13
  485. package/src/services/module-loading/page-module-import.service.js +222 -184
  486. package/src/services/module-loading/route-module-build-cache-registry.d.ts +24 -0
  487. package/src/services/module-loading/route-module-build-cache-registry.js +51 -0
  488. package/src/services/module-loading/route-module-build-cache.d.ts +4 -0
  489. package/src/services/module-loading/route-module-build-cache.js +3 -0
  490. package/src/services/module-loading/route-module-build-cache.store.d.ts +57 -0
  491. package/src/services/module-loading/route-module-build-cache.store.js +202 -0
  492. package/src/services/module-loading/route-module-build-manifest.d.ts +57 -0
  493. package/src/services/module-loading/route-module-build-manifest.js +60 -0
  494. package/src/services/module-loading/route-module-dependency-hasher.d.ts +81 -0
  495. package/src/services/module-loading/route-module-dependency-hasher.js +148 -0
  496. package/src/services/module-loading/server-module-transpiler.service.d.ts +1 -3
  497. package/src/services/module-loading/server-module-transpiler.service.js +65 -62
  498. package/src/services/module-loading/source-module-support.js +15 -7
  499. package/src/services/runtime-state/dev-graph.service.js +165 -157
  500. package/src/services/runtime-state/entrypoint-dependency-graph.service.js +85 -76
  501. package/src/services/runtime-state/server-invalidation-state.service.js +38 -30
  502. package/src/services/validation/schema-validation-service.d.ts +1 -4
  503. package/src/services/validation/schema-validation-service.js +156 -95
  504. package/src/services/validation/standard-schema.types.d.ts +9 -62
  505. package/src/services/validation/standard-schema.types.js +1 -0
  506. package/src/services/validation/validate-standard-schema.d.ts +7 -0
  507. package/src/services/validation/validate-standard-schema.js +14 -0
  508. package/src/static-site-generator/README.md +41 -0
  509. package/src/static-site-generator/production-page-browser-graph-prebuild.d.ts +32 -0
  510. package/src/static-site-generator/production-page-browser-graph-prebuild.js +57 -0
  511. package/src/static-site-generator/sitemap-routes.d.ts +14 -0
  512. package/src/static-site-generator/sitemap-routes.js +36 -0
  513. package/src/static-site-generator/sitemap.d.ts +15 -0
  514. package/src/static-site-generator/sitemap.js +42 -0
  515. package/src/static-site-generator/static-build-invalidation.d.ts +10 -0
  516. package/src/static-site-generator/static-build-invalidation.js +37 -0
  517. package/src/static-site-generator/static-export-context.d.ts +30 -0
  518. package/src/static-site-generator/static-export-context.js +1 -0
  519. package/src/static-site-generator/static-site-generator.d.ts +43 -25
  520. package/src/static-site-generator/static-site-generator.js +536 -294
  521. package/src/types/internal-types.d.ts +59 -13
  522. package/src/types/internal-types.js +1 -0
  523. package/src/types/public-types.d.ts +310 -95
  524. package/src/types/public-types.js +1 -0
  525. package/src/utils/deep-merge.js +39 -26
  526. package/src/utils/ecopages-route-info.d.ts +26 -0
  527. package/src/utils/ecopages-route-info.js +30 -0
  528. package/src/utils/hash.js +3 -6
  529. package/src/utils/html-escaping.d.ts +7 -0
  530. package/src/utils/html-escaping.js +22 -5
  531. package/src/utils/html.js +1 -4
  532. package/src/utils/invariant.js +11 -10
  533. package/src/utils/locals-utils.js +32 -22
  534. package/src/utils/parse-cli-args.d.ts +2 -0
  535. package/src/utils/parse-cli-args.js +73 -59
  536. package/src/utils/path-pattern.d.ts +23 -0
  537. package/src/utils/path-pattern.js +42 -0
  538. package/src/utils/path-utils.module.js +8 -11
  539. package/src/utils/resolve-entry-file.js +70 -38
  540. package/src/utils/resolve-work-dir.js +23 -27
  541. package/src/utils/runtime.js +24 -33
  542. package/src/utils/server-utils.module.d.ts +3 -2
  543. package/src/utils/server-utils.module.js +60 -53
  544. package/src/utils/static-file-extensions.d.ts +12 -0
  545. package/src/utils/static-file-extensions.js +54 -0
  546. package/src/watchers/project-watcher-ignore.d.ts +11 -0
  547. package/src/watchers/project-watcher-ignore.js +17 -0
  548. package/src/watchers/project-watcher.d.ts +29 -6
  549. package/src/watchers/project-watcher.js +402 -257
  550. package/src/watchers/project-watcher.test-helpers.js +45 -50
  551. package/src/adapters/shared/api-response.js +0 -96
  552. package/src/adapters/shared/application-adapter.js +0 -90
  553. package/src/adapters/shared/define-api-handler.d.ts +0 -25
  554. package/src/adapters/shared/define-api-handler.js +0 -15
  555. package/src/adapters/shared/explicit-static-render-preparation.js +0 -26
  556. package/src/adapters/shared/explicit-static-route-matcher.js +0 -101
  557. package/src/adapters/shared/file-route-middleware-pipeline.js +0 -90
  558. package/src/adapters/shared/fs-server-response-factory.js +0 -81
  559. package/src/adapters/shared/fs-server-response-matcher.js +0 -186
  560. package/src/adapters/shared/hmr-entrypoint-registrar.d.ts +0 -55
  561. package/src/adapters/shared/hmr-entrypoint-registrar.js +0 -87
  562. package/src/adapters/shared/hmr-html-response.js +0 -33
  563. package/src/adapters/shared/render-context.js +0 -93
  564. package/src/adapters/shared/runtime-app-bootstrap.js +0 -46
  565. package/src/adapters/shared/runtime-host.js +0 -0
  566. package/src/adapters/shared/server-adapter.js +0 -436
  567. package/src/adapters/shared/server-route-handler.js +0 -111
  568. package/src/adapters/shared/server-static-builder.js +0 -162
  569. package/src/adapters/shared/shared-hmr-manager.d.ts +0 -59
  570. package/src/adapters/shared/shared-hmr-manager.js +0 -241
  571. package/src/adapters/shared/static-preview-host.js +0 -0
  572. package/src/build/browser-runtime-manifest.js +0 -61
  573. package/src/build/browser-runtime-plugin-helpers.js +0 -14
  574. package/src/build/browser-runtime-plugin.js +0 -173
  575. package/src/build/build-manifest.d.ts +0 -33
  576. package/src/build/build-manifest.js +0 -49
  577. package/src/build/build-types.js +0 -0
  578. package/src/build/rolldown-adapter-helpers.js +0 -265
  579. package/src/build/rolldown-build-adapter.js +0 -65
  580. package/src/build/rolldown-dev-build-adapter.d.ts +0 -82
  581. package/src/build/rolldown-dev-build-adapter.js +0 -166
  582. package/src/build/rolldown-plugin-bridge.js +0 -199
  583. package/src/build/runtime-build-executor.d.ts +0 -21
  584. package/src/build/runtime-build-executor.js +0 -19
  585. package/src/build/runtime-build-output-normalizer.d.ts +0 -3
  586. package/src/build/runtime-build-output-normalizer.js +0 -111
  587. package/src/build/serialized-build-executor.js +0 -63
  588. package/src/build/server-side-css-shim-plugin.js +0 -35
  589. package/src/hmr/hmr.postcss.test.e2e.js +0 -31
  590. package/src/hmr/hmr.test.e2e.js +0 -43
  591. package/src/route-renderer/orchestration/component-render-context.js +0 -147
  592. package/src/route-renderer/orchestration/declared-ownership-graph.d.ts +0 -18
  593. package/src/route-renderer/orchestration/declared-ownership-graph.js +0 -34
  594. package/src/route-renderer/orchestration/foreign-subtree-execution.service.js +0 -233
  595. package/src/route-renderer/orchestration/ownership-planning.service.d.ts +0 -24
  596. package/src/route-renderer/orchestration/ownership-planning.service.js +0 -63
  597. package/src/route-renderer/orchestration/ownership-validation.service.js +0 -53
  598. package/src/route-renderer/orchestration/processed-asset-dedupe.js +0 -27
  599. package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.d.ts +0 -91
  600. package/src/route-renderer/orchestration/queued-foreign-subtree-resolution.service.js +0 -170
  601. package/src/route-renderer/orchestration/render-output.utils.js +0 -171
  602. package/src/route-renderer/orchestration/route-render-orchestrator.js +0 -577
  603. package/src/route-renderer/orchestration/template-serialization.d.ts +0 -38
  604. package/src/route-renderer/orchestration/template-serialization.js +0 -45
  605. /package/src/adapters/shared/{runtime-host.d.ts → runtime/runtime-host.d.ts} +0 -0
  606. /package/src/{hmr/hmr.postcss.test.e2e.d.ts → adapters/shared/runtime/runtime-host.js} +0 -0
  607. /package/src/{hmr/hmr.test.e2e.d.ts → adapters/shared/runtime/static-preview-host.js} +0 -0
  608. /package/src/build/{browser-runtime-manifest.d.ts → browser/browser-runtime-manifest.d.ts} +0 -0
  609. /package/src/build/{browser-runtime-plugin-helpers.d.ts → browser/browser-runtime-plugin-helpers.d.ts} +0 -0
  610. /package/src/build/{build-types.d.ts → contracts/build-types.d.ts} +0 -0
  611. /package/src/build/{server-side-css-shim-plugin.d.ts → rolldown/server-side-css-shim-plugin.d.ts} +0 -0
@@ -1,80 +1,78 @@
1
- import { invariant } from "../utils/invariant.js";
2
- import { PathUtils } from "../utils/path-utils.module.js";
3
- class RouteRendererFactory {
4
- appConfig;
5
- runtimeOrigin;
6
- rendererModules;
7
- rendererCache = /* @__PURE__ */ new Map();
8
- /**
9
- * Creates the route-renderer factory for one app/runtime instance.
10
- */
11
- constructor({
12
- appConfig,
13
- rendererModules,
14
- runtimeOrigin
15
- }) {
16
- this.appConfig = appConfig;
17
- this.rendererModules = rendererModules;
18
- this.runtimeOrigin = runtimeOrigin;
19
- }
20
- /**
21
- * Returns a route renderer for the supplied route file.
22
- */
23
- getPageRenderer(filePath) {
24
- const integrationRenderer = this.getRouteRendererEngine(filePath);
25
- invariant(!!integrationRenderer, `No integration renderer found for file: ${filePath}`);
26
- return integrationRenderer;
27
- }
28
- /**
29
- * Returns a renderer for an explicit view integration.
30
- */
31
- getExplicitViewRenderer(integrationName) {
32
- const integrationPlugin = this.appConfig.integrations.find((plugin) => plugin.name === integrationName);
33
- if (!integrationPlugin) {
34
- return null;
1
+ import { invariant } from '../utils/invariant.js';
2
+ import { PathUtils } from '../utils/path-utils.module.js';
3
+ /**
4
+ * Selects and caches integration renderers for route files and explicit views.
5
+ *
6
+ * @remarks
7
+ * The factory owns the policy that maps a route file or explicit integration
8
+ * name to one initialized integration renderer. Renderer instances are cached by
9
+ * integration name so repeated requests do not rebuild renderer state.
10
+ */
11
+ export class RouteRendererFactory {
12
+ appConfig;
13
+ runtimeOrigin;
14
+ rendererModules;
15
+ rendererCache = new Map();
16
+ /**
17
+ * Creates the route-renderer factory for one app/runtime instance.
18
+ */
19
+ constructor({ appConfig, rendererModules, runtimeOrigin, }) {
20
+ this.appConfig = appConfig;
21
+ this.rendererModules = rendererModules;
22
+ this.runtimeOrigin = runtimeOrigin;
35
23
  }
36
- const cached = this.rendererCache.get(integrationName);
37
- if (cached) {
38
- return cached;
24
+ /**
25
+ * Returns a route renderer for the supplied route file.
26
+ */
27
+ getPageRenderer(filePath) {
28
+ const integrationRenderer = this.getRouteRendererEngine(filePath);
29
+ invariant(!!integrationRenderer, `No integration renderer found for file: ${filePath}`);
30
+ return integrationRenderer;
39
31
  }
40
- const renderer = integrationPlugin.initializeRenderer({
41
- rendererModules: this.rendererModules
42
- });
43
- this.rendererCache.set(integrationName, renderer);
44
- return renderer;
45
- }
46
- /**
47
- * Resolves the integration plugin that owns a given route file.
48
- */
49
- getIntegrationPlugin(filePath) {
50
- const templateExtension = PathUtils.getEcoTemplateExtension(filePath);
51
- const isIntegrationPlugin = (plugin) => {
52
- return plugin.extensions.some((extension) => templateExtension === extension);
53
- };
54
- const integrationPlugin = this.appConfig.integrations.find(isIntegrationPlugin);
55
- invariant(
56
- !!integrationPlugin,
57
- `No integration plugin found for template extension: ${templateExtension}, file: ${filePath}`
58
- );
59
- return integrationPlugin;
60
- }
61
- /**
62
- * Returns the cached renderer engine for the file's owning integration,
63
- * creating it on first use.
64
- */
65
- getRouteRendererEngine(filePath) {
66
- const integrationPlugin = this.getIntegrationPlugin(filePath);
67
- const cached = this.rendererCache.get(integrationPlugin.name);
68
- if (cached) {
69
- return cached;
32
+ /**
33
+ * Returns a renderer for an explicit view integration.
34
+ */
35
+ getExplicitViewRenderer(integrationName) {
36
+ const integrationPlugin = this.appConfig.integrations.find((plugin) => plugin.name === integrationName);
37
+ if (!integrationPlugin) {
38
+ return null;
39
+ }
40
+ const cached = this.rendererCache.get(integrationName);
41
+ if (cached) {
42
+ return cached;
43
+ }
44
+ const renderer = integrationPlugin.initializeRenderer({
45
+ rendererModules: this.rendererModules,
46
+ });
47
+ this.rendererCache.set(integrationName, renderer);
48
+ return renderer;
49
+ }
50
+ /**
51
+ * Resolves the integration plugin that owns a given route file.
52
+ */
53
+ getIntegrationPlugin(filePath) {
54
+ const templateExtension = PathUtils.getEcoTemplateExtension(filePath);
55
+ const isIntegrationPlugin = (plugin) => {
56
+ return plugin.extensions.some((extension) => templateExtension === extension);
57
+ };
58
+ const integrationPlugin = this.appConfig.integrations.find(isIntegrationPlugin);
59
+ invariant(!!integrationPlugin, `No integration plugin found for template extension: ${templateExtension}, file: ${filePath}`);
60
+ return integrationPlugin;
61
+ }
62
+ /**
63
+ * Returns the cached renderer engine for the file's owning integration,
64
+ * creating it on first use.
65
+ */
66
+ getRouteRendererEngine(filePath) {
67
+ const integrationPlugin = this.getIntegrationPlugin(filePath);
68
+ const cached = this.rendererCache.get(integrationPlugin.name);
69
+ if (cached) {
70
+ return cached;
71
+ }
72
+ const renderer = integrationPlugin.initializeRenderer({
73
+ rendererModules: this.rendererModules,
74
+ });
75
+ this.rendererCache.set(integrationPlugin.name, renderer);
76
+ return renderer;
70
77
  }
71
- const renderer = integrationPlugin.initializeRenderer({
72
- rendererModules: this.rendererModules
73
- });
74
- this.rendererCache.set(integrationPlugin.name, renderer);
75
- return renderer;
76
- }
77
78
  }
78
- export {
79
- RouteRendererFactory
80
- };
@@ -22,6 +22,7 @@ router/
22
22
  │ └── route-registry.ts # Owns template routes, request matching, static expansion, and reload
23
23
  └── client/ # Browser-side navigation coordination
24
24
  ├── navigation-coordinator.ts # Singleton runtime coordinator
25
+ ├── navigation-lifecycle.ts # Shared document lifecycle events
25
26
  └── link-intent.ts # Shared anchor detection and intent recovery helpers
26
27
  ```
27
28
 
@@ -59,6 +60,14 @@ Match priority:
59
60
 
60
61
  ## `client/`
61
62
 
63
+ ### View transitions (`@ecopages/core/client/view-transitions`)
64
+
65
+ Shared helpers used by `@ecopages/browser-router` and `@ecopages/react-router`:
66
+
67
+ - `applyViewTransitionNames` / `clearViewTransitionNames` — named `data-view-transition` morph / fade styles (`eco-vt-dynamic-styles`).
68
+ - `ensureRootViewTransitionStyles` — persisted CSS (`eco-vt-root-styles`, `data-eco-persist`) with `html { view-transition-name: none }` when VT is enabled.
69
+ - `documentHasNamedViewTransitions` / `navigationHasNamedViewTransitions` — gate `startViewTransition` to pages with `data-view-transition` markup.
70
+
62
71
  ### Navigation Coordinator (`navigation-coordinator.ts`)
63
72
 
64
73
  A singleton browser-side runtime stored on `window.__ECO_PAGES__.navigation`.
@@ -79,6 +88,28 @@ The coordinator is framework-agnostic. Browser runtimes (e.g. `browser-router`,
79
88
  - **Reload** — `reloadCurrentPage` delegates to whichever runtime currently owns the document.
80
89
  - **Events** — `subscribe` lets runtimes react to `owner-change` and `registration-change` events.
81
90
 
91
+ ### Navigation Lifecycle (`navigation-lifecycle.ts`)
92
+
93
+ Shared document lifecycle events emitted by browser runtimes after a client navigation commits.
94
+
95
+ Access it with:
96
+
97
+ ```ts
98
+ import {
99
+ completeNavigationLifecycle,
100
+ dispatchBeforeSwap,
101
+ type EcoNavigationEvent,
102
+ } from '@ecopages/core/router/navigation-lifecycle';
103
+ ```
104
+
105
+ `browser-router` and `react-router` call these helpers around their own commit implementations. Use `completeNavigationLifecycle` for the paired post-commit signals. Listeners use the DOM contract:
106
+
107
+ - `eco:before-swap` — pre-commit hook with `newDocument` and `reload()`
108
+ - `eco:after-swap` — post-commit signal after the runtime has applied the new page
109
+ - `eco:page-load` — scheduled on the next animation frame after `eco:after-swap`
110
+
111
+ This is separate from coordinator `subscribe()` events, which track runtime ownership rather than page lifecycle.
112
+
82
113
  ### Link Intent (`link-intent.ts`)
83
114
 
84
115
  Shared helpers for locating anchors and recovering stale navigation intent.
@@ -15,8 +15,8 @@
15
15
  * Timestamped navigation intent captured from pointer or hover activity.
16
16
  */
17
17
  export type EcoPendingNavigationIntent = {
18
- href: string;
19
- timestamp: number;
18
+ href: string;
19
+ timestamp: number;
20
20
  };
21
21
  /**
22
22
  * Finds the nearest matching anchor within an event's composed path.
@@ -28,26 +28,16 @@ export type EcoPendingNavigationIntent = {
28
28
  * @param linkSelector - Selector that identifies navigable anchors.
29
29
  * @returns The matched anchor element, or `null` when no matching anchor exists.
30
30
  */
31
- export declare function getAnchorFromNavigationEvent(
32
- event: MouseEvent | PointerEvent,
33
- linkSelector: string,
34
- ): HTMLAnchorElement | null;
31
+ export declare function getAnchorFromNavigationEvent(event: MouseEvent | PointerEvent, linkSelector: string): HTMLAnchorElement | null;
32
+ /**
33
+ * Returns whether an href targets a static asset that should use a full document load.
34
+ */
35
+ export declare function isStaticAssetHref(href: string): boolean;
35
36
  /**
36
37
  * Resolves a previously captured intent while a navigation is still in flight.
37
38
  *
38
- * Pending intents expire quickly because they are only meant to bridge the gap
39
- * between pointer or hover capture and the later click event when the DOM or
40
- * active runtime changes during a rapid navigation sequence.
41
- *
42
- * @param intent - Previously captured pointer or hover intent.
43
- * @param hasInFlightNavigation - Whether a router navigation is still active.
44
- * @param now - Current monotonic timestamp, usually from `performance.now()`.
45
- * @param maxAgeMs - Maximum allowed age for the recovered intent.
46
- * @returns The intended href when still valid, otherwise `null`.
39
+ * @remarks
40
+ * Pending intents expire quickly because they bridge pointer or hover capture
41
+ * and the later click when the DOM changes during a rapid navigation sequence.
47
42
  */
48
- export declare function recoverPendingNavigationHref(
49
- intent: EcoPendingNavigationIntent | null,
50
- hasInFlightNavigation: boolean,
51
- now: number,
52
- maxAgeMs?: number,
53
- ): string | null;
43
+ export declare function recoverPendingNavigationHref(intent: EcoPendingNavigationIntent | null, hasInFlightNavigation: boolean, now: number, maxAgeMs?: number): string | null;
@@ -1,34 +1,60 @@
1
- function getAnchorFromNavigationEvent(event, linkSelector) {
2
- const eventTarget = event.target;
3
- if (eventTarget instanceof HTMLAnchorElement && eventTarget.matches(linkSelector)) {
4
- return eventTarget;
5
- }
6
- if (eventTarget instanceof Element) {
7
- const closestAnchor = eventTarget.closest(linkSelector);
8
- if (closestAnchor instanceof HTMLAnchorElement) {
9
- return closestAnchor;
1
+ import { hasKnownStaticExtension } from '../../utils/static-file-extensions.js';
2
+ /**
3
+ * Finds the nearest matching anchor within an event's composed path.
4
+ *
5
+ * This works across Shadow DOM boundaries, which is required for delegated
6
+ * navigation handling when links are rendered inside custom elements.
7
+ *
8
+ * @param event - Pointer or mouse event being inspected.
9
+ * @param linkSelector - Selector that identifies navigable anchors.
10
+ * @returns The matched anchor element, or `null` when no matching anchor exists.
11
+ */
12
+ export function getAnchorFromNavigationEvent(event, linkSelector) {
13
+ const eventTarget = event.target;
14
+ if (eventTarget instanceof HTMLAnchorElement && eventTarget.matches(linkSelector)) {
15
+ return eventTarget;
10
16
  }
11
- }
12
- if (eventTarget instanceof Text) {
13
- const parentAnchor = eventTarget.parentElement?.closest(linkSelector);
14
- if (parentAnchor instanceof HTMLAnchorElement) {
15
- return parentAnchor;
17
+ if (eventTarget instanceof Element) {
18
+ const closestAnchor = eventTarget.closest(linkSelector);
19
+ if (closestAnchor instanceof HTMLAnchorElement) {
20
+ return closestAnchor;
21
+ }
22
+ }
23
+ if (eventTarget instanceof Text) {
24
+ const parentAnchor = eventTarget.parentElement?.closest(linkSelector);
25
+ if (parentAnchor instanceof HTMLAnchorElement) {
26
+ return parentAnchor;
27
+ }
28
+ }
29
+ return event
30
+ .composedPath()
31
+ .find((target) => target instanceof HTMLAnchorElement && target.matches(linkSelector));
32
+ }
33
+ /**
34
+ * Returns whether an href targets a static asset that should use a full document load.
35
+ */
36
+ export function isStaticAssetHref(href) {
37
+ try {
38
+ const url = new URL(href, 'http://localhost');
39
+ return hasKnownStaticExtension(url.pathname);
40
+ }
41
+ catch {
42
+ return false;
16
43
  }
17
- }
18
- return event.composedPath().find(
19
- (target) => target instanceof HTMLAnchorElement && target.matches(linkSelector)
20
- );
21
44
  }
22
- function recoverPendingNavigationHref(intent, hasInFlightNavigation, now, maxAgeMs = 1e3) {
23
- if (!intent || !hasInFlightNavigation) {
24
- return null;
25
- }
26
- if (now - intent.timestamp > maxAgeMs) {
27
- return null;
28
- }
29
- return intent.href;
45
+ /**
46
+ * Resolves a previously captured intent while a navigation is still in flight.
47
+ *
48
+ * @remarks
49
+ * Pending intents expire quickly because they bridge pointer or hover capture
50
+ * and the later click when the DOM changes during a rapid navigation sequence.
51
+ */
52
+ export function recoverPendingNavigationHref(intent, hasInFlightNavigation, now, maxAgeMs = 1000) {
53
+ if (!intent || !hasInFlightNavigation) {
54
+ return null;
55
+ }
56
+ if (now - intent.timestamp > maxAgeMs) {
57
+ return null;
58
+ }
59
+ return intent.href;
30
60
  }
31
- export {
32
- getAnchorFromNavigationEvent,
33
- recoverPendingNavigationHref
34
- };
@@ -1,43 +1,54 @@
1
- import { describe, expect, it } from "vitest";
2
- import { getAnchorFromNavigationEvent, recoverPendingNavigationHref } from "./link-intent.js";
3
- describe("getAnchorFromNavigationEvent", () => {
4
- it("returns the anchor when the event target is a text node inside it", () => {
5
- const anchor = document.createElement("a");
6
- anchor.href = "/fast";
7
- anchor.setAttribute("data-eco-link", "true");
8
- const textNode = document.createTextNode("fast-link");
9
- anchor.append(textNode);
10
- document.body.append(anchor);
11
- const event = new MouseEvent("click", { bubbles: true, cancelable: true, composed: true });
12
- Object.defineProperty(event, "target", {
13
- configurable: true,
14
- value: textNode
1
+ import { describe, expect, it } from 'vitest';
2
+ import { getAnchorFromNavigationEvent, isStaticAssetHref, recoverPendingNavigationHref } from './link-intent.js';
3
+ describe('getAnchorFromNavigationEvent', () => {
4
+ it('returns the anchor when the event target is a text node inside it', () => {
5
+ const anchor = document.createElement('a');
6
+ anchor.href = '/fast';
7
+ anchor.setAttribute('data-eco-link', 'true');
8
+ const textNode = document.createTextNode('fast-link');
9
+ anchor.append(textNode);
10
+ document.body.append(anchor);
11
+ const event = new MouseEvent('click', { bubbles: true, cancelable: true, composed: true });
12
+ Object.defineProperty(event, 'target', {
13
+ configurable: true,
14
+ value: textNode,
15
+ });
16
+ expect(getAnchorFromNavigationEvent(event, 'a[data-eco-link]')).toBe(anchor);
15
17
  });
16
- expect(getAnchorFromNavigationEvent(event, "a[data-eco-link]")).toBe(anchor);
17
- });
18
- it("returns the closest matching anchor for nested element targets", () => {
19
- const anchor = document.createElement("a");
20
- anchor.href = "/fast";
21
- anchor.setAttribute("data-eco-link", "true");
22
- const span = document.createElement("span");
23
- span.textContent = "fast-link";
24
- anchor.append(span);
25
- document.body.append(anchor);
26
- const event = new MouseEvent("click", { bubbles: true, cancelable: true, composed: true });
27
- Object.defineProperty(event, "target", {
28
- configurable: true,
29
- value: span
18
+ it('returns the closest matching anchor for nested element targets', () => {
19
+ const anchor = document.createElement('a');
20
+ anchor.href = '/fast';
21
+ anchor.setAttribute('data-eco-link', 'true');
22
+ const span = document.createElement('span');
23
+ span.textContent = 'fast-link';
24
+ anchor.append(span);
25
+ document.body.append(anchor);
26
+ const event = new MouseEvent('click', { bubbles: true, cancelable: true, composed: true });
27
+ Object.defineProperty(event, 'target', {
28
+ configurable: true,
29
+ value: span,
30
+ });
31
+ expect(getAnchorFromNavigationEvent(event, 'a[data-eco-link]')).toBe(anchor);
30
32
  });
31
- expect(getAnchorFromNavigationEvent(event, "a[data-eco-link]")).toBe(anchor);
32
- });
33
33
  });
34
- describe("recoverPendingNavigationHref", () => {
35
- it("returns null for stale or missing pending intent state", () => {
36
- expect(recoverPendingNavigationHref(null, true, 10)).toBeNull();
37
- expect(recoverPendingNavigationHref({ href: "/fast", timestamp: 0 }, false, 10)).toBeNull();
38
- expect(recoverPendingNavigationHref({ href: "/fast", timestamp: 0 }, true, 2e3, 1e3)).toBeNull();
39
- });
40
- it("returns the captured href while a navigation is still in flight", () => {
41
- expect(recoverPendingNavigationHref({ href: "/fast", timestamp: 10 }, true, 20, 1e3)).toBe("/fast");
42
- });
34
+ describe('isStaticAssetHref', () => {
35
+ it('returns true for known static asset paths', () => {
36
+ expect(isStaticAssetHref('/skill.txt')).toBe(true);
37
+ expect(isStaticAssetHref('/skill/reference/full-stack.md')).toBe(true);
38
+ expect(isStaticAssetHref('/assets/logo.png')).toBe(true);
39
+ });
40
+ it('returns false for application routes', () => {
41
+ expect(isStaticAssetHref('/docs/getting-started/introduction')).toBe(false);
42
+ expect(isStaticAssetHref('/')).toBe(false);
43
+ });
44
+ });
45
+ describe('recoverPendingNavigationHref', () => {
46
+ it('returns null for stale or missing pending intent state', () => {
47
+ expect(recoverPendingNavigationHref(null, true, 10)).toBeNull();
48
+ expect(recoverPendingNavigationHref({ href: '/fast', timestamp: 0 }, false, 10)).toBeNull();
49
+ expect(recoverPendingNavigationHref({ href: '/fast', timestamp: 0 }, true, 2000, 1000)).toBeNull();
50
+ });
51
+ it('returns the captured href while a navigation is still in flight', () => {
52
+ expect(recoverPendingNavigationHref({ href: '/fast', timestamp: 10 }, true, 20, 1000)).toBe('/fast');
53
+ });
43
54
  });
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Canonical link interception, prefetch eligibility, and HTML fetch guards.
3
+ * @module
4
+ */
5
+ export type LinkNavigationPolicyOptions = {
6
+ /** Attribute that forces a full document reload instead of SPA navigation. */
7
+ reloadAttribute?: string;
8
+ /** Attribute that opts a link out of prefetch. */
9
+ noPrefetchAttribute?: string;
10
+ };
11
+ export type LinkNavigationDecision = {
12
+ shouldIntercept: true;
13
+ href: string;
14
+ } | {
15
+ shouldIntercept: false;
16
+ reason: 'modified-click' | 'non-left-click' | 'external-target' | 'explicit-reload' | 'download' | 'no-prefetch' | 'invalid-href' | 'cross-origin' | 'static-asset' | 'same-page-hash';
17
+ };
18
+ /**
19
+ * Returns whether an href only adds a hash fragment on the current page.
20
+ */
21
+ export declare function isSamePageHashNavigationHref(href: string): boolean;
22
+ /**
23
+ * Decides whether a pointer or click on an anchor should be handled as SPA navigation.
24
+ */
25
+ export declare function getLinkNavigationDecision(event: MouseEvent | PointerEvent, link: HTMLAnchorElement, options: LinkNavigationPolicyOptions): LinkNavigationDecision;
26
+ /**
27
+ * Returns the href when SPA navigation should intercept the click, otherwise `null`.
28
+ */
29
+ export declare function getNavigableHrefFromClick(event: MouseEvent | PointerEvent, link: HTMLAnchorElement, options: LinkNavigationPolicyOptions): string | null;
30
+ /**
31
+ * Returns whether a link is eligible for hover or viewport prefetch.
32
+ */
33
+ export declare function shouldPrefetchLink(link: HTMLAnchorElement, options: LinkNavigationPolicyOptions): boolean;
34
+ /**
35
+ * @remarks
36
+ * Prefetch and SPA fetches request HTML. Only explicit `text/html` and
37
+ * `application/xhtml+xml` responses are accepted; missing or asset types are rejected.
38
+ */
39
+ export declare function isHtmlPageResponse(response: Response): boolean;
40
+ /**
41
+ * @remarks
42
+ * Servers should send `text/html`. When the type is missing or the runtime
43
+ * defaults to `text/plain` (common in tests), a document-shaped body is accepted.
44
+ */
45
+ export declare function assertHtmlPageResponse(response: Response): Promise<void>;
@@ -0,0 +1,122 @@
1
+ import { isStaticAssetHref } from './link-intent.js';
2
+ /**
3
+ * Shared anchor/href checks for navigation interception and prefetch eligibility.
4
+ */
5
+ function getLinkIneligibilityReason(link, options) {
6
+ if (options.noPrefetchAttribute && link.hasAttribute(options.noPrefetchAttribute)) {
7
+ return 'no-prefetch';
8
+ }
9
+ if (options.reloadAttribute && link.hasAttribute(options.reloadAttribute)) {
10
+ return 'explicit-reload';
11
+ }
12
+ if (link.hasAttribute('download')) {
13
+ return 'download';
14
+ }
15
+ const href = link.getAttribute('href');
16
+ if (!href || href.startsWith('#') || href.startsWith('javascript:')) {
17
+ return 'invalid-href';
18
+ }
19
+ const url = new URL(href, window.location.origin);
20
+ if (url.origin !== window.location.origin) {
21
+ return 'cross-origin';
22
+ }
23
+ if (isStaticAssetHref(href)) {
24
+ return 'static-asset';
25
+ }
26
+ return null;
27
+ }
28
+ /**
29
+ * Returns whether an href only adds a hash fragment on the current page.
30
+ */
31
+ export function isSamePageHashNavigationHref(href) {
32
+ if (!href) {
33
+ return false;
34
+ }
35
+ const currentUrl = new URL(window.location.href);
36
+ const targetUrl = new URL(href, currentUrl);
37
+ return (targetUrl.origin === currentUrl.origin &&
38
+ targetUrl.hash.length > 0 &&
39
+ targetUrl.pathname === currentUrl.pathname &&
40
+ targetUrl.search === currentUrl.search);
41
+ }
42
+ /**
43
+ * Decides whether a pointer or click on an anchor should be handled as SPA navigation.
44
+ */
45
+ export function getLinkNavigationDecision(event, link, options) {
46
+ if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
47
+ return { shouldIntercept: false, reason: 'modified-click' };
48
+ }
49
+ if (event.button !== 0) {
50
+ return { shouldIntercept: false, reason: 'non-left-click' };
51
+ }
52
+ const target = link.getAttribute('target');
53
+ if (target && target !== '_self') {
54
+ return { shouldIntercept: false, reason: 'external-target' };
55
+ }
56
+ const ineligibility = getLinkIneligibilityReason(link, options);
57
+ if (ineligibility) {
58
+ return { shouldIntercept: false, reason: ineligibility };
59
+ }
60
+ const href = link.getAttribute('href');
61
+ if (isSamePageHashNavigationHref(href)) {
62
+ return { shouldIntercept: false, reason: 'same-page-hash' };
63
+ }
64
+ return { shouldIntercept: true, href };
65
+ }
66
+ /**
67
+ * Returns the href when SPA navigation should intercept the click, otherwise `null`.
68
+ */
69
+ export function getNavigableHrefFromClick(event, link, options) {
70
+ const decision = getLinkNavigationDecision(event, link, options);
71
+ return decision.shouldIntercept ? decision.href : null;
72
+ }
73
+ /**
74
+ * Returns whether a link is eligible for hover or viewport prefetch.
75
+ */
76
+ export function shouldPrefetchLink(link, options) {
77
+ if (getLinkIneligibilityReason(link, options)) {
78
+ return false;
79
+ }
80
+ const href = link.getAttribute('href');
81
+ try {
82
+ const url = new URL(href, window.location.origin);
83
+ const currentPath = window.location.pathname + window.location.search;
84
+ const targetPath = url.pathname + url.search;
85
+ return currentPath !== targetPath;
86
+ }
87
+ catch {
88
+ return false;
89
+ }
90
+ }
91
+ /**
92
+ * @remarks
93
+ * Prefetch and SPA fetches request HTML. Only explicit `text/html` and
94
+ * `application/xhtml+xml` responses are accepted; missing or asset types are rejected.
95
+ */
96
+ export function isHtmlPageResponse(response) {
97
+ const contentType = response.headers.get('Content-Type');
98
+ if (!contentType) {
99
+ return false;
100
+ }
101
+ const normalized = contentType.split(';')[0]?.trim().toLowerCase() ?? '';
102
+ return normalized === 'text/html' || normalized === 'application/xhtml+xml';
103
+ }
104
+ /**
105
+ * @remarks
106
+ * Servers should send `text/html`. When the type is missing or the runtime
107
+ * defaults to `text/plain` (common in tests), a document-shaped body is accepted.
108
+ */
109
+ export async function assertHtmlPageResponse(response) {
110
+ if (isHtmlPageResponse(response)) {
111
+ return;
112
+ }
113
+ const contentType = response.headers.get('Content-Type');
114
+ const normalized = contentType?.split(';')[0]?.trim().toLowerCase() ?? '';
115
+ if (normalized === 'text/plain' || normalized === '') {
116
+ const sample = (await response.clone().text()).trimStart();
117
+ if (sample.startsWith('<')) {
118
+ return;
119
+ }
120
+ }
121
+ throw new Error(`Expected HTML page response, received ${contentType ?? 'unknown content type'}`);
122
+ }