@farm.js/core 0.1.0-beta.1 → 0.1.0-beta.11

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 (310) hide show
  1. package/README.md +1 -1
  2. package/dist/agent-runtime.d.mts +3 -2
  3. package/dist/agent-runtime.d.ts +3 -2
  4. package/dist/api/route-manager.cjs +410 -15
  5. package/dist/api/route-manager.cjs.map +1 -1
  6. package/dist/api/route-manager.d.mts +7 -5
  7. package/dist/api/route-manager.d.ts +7 -5
  8. package/dist/api/route-manager.mjs +9 -8
  9. package/dist/api/runtime.cjs +748 -9
  10. package/dist/api/runtime.cjs.map +1 -1
  11. package/dist/api/runtime.d.mts +3 -16
  12. package/dist/api/runtime.d.ts +3 -16
  13. package/dist/api/runtime.mjs +8 -1
  14. package/dist/api.cjs +1243 -342
  15. package/dist/api.cjs.map +1 -1
  16. package/dist/api.d.mts +8 -150
  17. package/dist/api.d.ts +8 -150
  18. package/dist/api.mjs +51 -21
  19. package/dist/{app-BiX4qb-d.d.mts → app-BNE2FoZ4.d.mts} +42 -5
  20. package/dist/{app-CFRNJXP1.d.ts → app-DRGUmJ3s.d.ts} +42 -5
  21. package/dist/app-markdown.cjs +32 -8
  22. package/dist/app-markdown.cjs.map +1 -1
  23. package/dist/app-markdown.d.mts +3 -2
  24. package/dist/app-markdown.d.ts +3 -2
  25. package/dist/app-markdown.mjs +2 -1
  26. package/dist/cache.cjs +414 -12
  27. package/dist/cache.cjs.map +1 -1
  28. package/dist/cache.d.mts +120 -6
  29. package/dist/cache.d.ts +120 -6
  30. package/dist/cache.mjs +11 -3
  31. package/dist/{chunk-QF4PHCMA.mjs → chunk-2ED5Q2GH.mjs} +3 -3
  32. package/dist/chunk-2ED5Q2GH.mjs.map +1 -0
  33. package/dist/{chunk-GZP5W4K3.mjs → chunk-32W4QEJP.mjs} +1 -1
  34. package/dist/chunk-32W4QEJP.mjs.map +1 -0
  35. package/dist/{chunk-G3B5BRDY.mjs → chunk-4677KXB7.mjs} +646 -86
  36. package/dist/chunk-4677KXB7.mjs.map +1 -0
  37. package/dist/{chunk-3QJO55ZF.mjs → chunk-4LND3PXF.mjs} +30 -38
  38. package/dist/chunk-4LND3PXF.mjs.map +1 -0
  39. package/dist/chunk-5EVQFRL2.mjs +10 -0
  40. package/dist/chunk-5EVQFRL2.mjs.map +1 -0
  41. package/dist/{chunk-25D7G34K.mjs → chunk-65A7QIKI.mjs} +5 -5
  42. package/dist/{chunk-25D7G34K.mjs.map → chunk-65A7QIKI.mjs.map} +1 -1
  43. package/dist/{chunk-CHFHNEMO.mjs → chunk-77BOAQHI.mjs} +1972 -188
  44. package/dist/chunk-77BOAQHI.mjs.map +1 -0
  45. package/dist/{chunk-LLC7BNXW.mjs → chunk-7FBJLMQH.mjs} +73 -10
  46. package/dist/chunk-7FBJLMQH.mjs.map +1 -0
  47. package/dist/{chunk-TRORP7E4.mjs → chunk-7N62DNSO.mjs} +2 -2
  48. package/dist/chunk-ALCLXXTY.mjs +187 -0
  49. package/dist/chunk-ALCLXXTY.mjs.map +1 -0
  50. package/dist/chunk-AW6I64AP.mjs +25 -0
  51. package/dist/chunk-AW6I64AP.mjs.map +1 -0
  52. package/dist/{chunk-B6N4ZB2H.mjs → chunk-C2ROET2V.mjs} +3 -3
  53. package/dist/{chunk-BHG3LVHH.mjs → chunk-CGIXMLSY.mjs} +15 -7
  54. package/dist/chunk-CGIXMLSY.mjs.map +1 -0
  55. package/dist/{chunk-C3DLZMBU.mjs → chunk-DJSGLHCN.mjs} +2 -2
  56. package/dist/{chunk-JN3UU635.mjs → chunk-EJ7T4TPB.mjs} +2 -2
  57. package/dist/chunk-EJ7T4TPB.mjs.map +1 -0
  58. package/dist/{chunk-ZJQNATYV.mjs → chunk-FRPWCMMG.mjs} +3 -3
  59. package/dist/chunk-FRPWCMMG.mjs.map +1 -0
  60. package/dist/{chunk-QM6VV26B.mjs → chunk-GQVGIUSN.mjs} +3 -3
  61. package/dist/{chunk-QM6VV26B.mjs.map → chunk-GQVGIUSN.mjs.map} +1 -1
  62. package/dist/{chunk-UREJA4GZ.mjs → chunk-GXASWWJU.mjs} +1 -1
  63. package/dist/{chunk-UREJA4GZ.mjs.map → chunk-GXASWWJU.mjs.map} +1 -1
  64. package/dist/chunk-I4CUBGVF.mjs +93 -0
  65. package/dist/chunk-I4CUBGVF.mjs.map +1 -0
  66. package/dist/{chunk-HXP3ZSPC.mjs → chunk-J5YWQVI5.mjs} +4 -4
  67. package/dist/chunk-J5YWQVI5.mjs.map +1 -0
  68. package/dist/{chunk-PRNYWD7K.mjs → chunk-JDEOUK5V.mjs} +67 -239
  69. package/dist/chunk-JDEOUK5V.mjs.map +1 -0
  70. package/dist/{chunk-UHE2TTLK.mjs → chunk-K5ZTUF22.mjs} +34 -17
  71. package/dist/chunk-K5ZTUF22.mjs.map +1 -0
  72. package/dist/{chunk-O3HADRW6.mjs → chunk-MIUW47JX.mjs} +2 -2
  73. package/dist/{chunk-O3HADRW6.mjs.map → chunk-MIUW47JX.mjs.map} +1 -1
  74. package/dist/chunk-PFE6GMNE.mjs +603 -0
  75. package/dist/chunk-PFE6GMNE.mjs.map +1 -0
  76. package/dist/{chunk-RKI6TN3A.mjs → chunk-QM746KUO.mjs} +9 -2
  77. package/dist/chunk-QM746KUO.mjs.map +1 -0
  78. package/dist/{chunk-TU4YJICB.mjs → chunk-QTZZ2ISQ.mjs} +41 -16
  79. package/dist/chunk-QTZZ2ISQ.mjs.map +1 -0
  80. package/dist/chunk-RBRLLZL5.mjs +81 -0
  81. package/dist/chunk-RBRLLZL5.mjs.map +1 -0
  82. package/dist/{chunk-RSKVYESE.mjs → chunk-RQ633A5I.mjs} +1 -1
  83. package/dist/chunk-RQ633A5I.mjs.map +1 -0
  84. package/dist/{chunk-6XDUHOEM.mjs → chunk-TQAEEJB4.mjs} +3 -3
  85. package/dist/{chunk-AGS7UJ52.mjs → chunk-UB5UOSHB.mjs} +24 -12
  86. package/dist/chunk-UB5UOSHB.mjs.map +1 -0
  87. package/dist/{chunk-SXZTEK3V.mjs → chunk-UXUAWNO5.mjs} +2 -2
  88. package/dist/chunk-V3XURYJO.mjs +756 -0
  89. package/dist/chunk-V3XURYJO.mjs.map +1 -0
  90. package/dist/{chunk-JLWMCADZ.mjs → chunk-VY2UYN5R.mjs} +24 -4
  91. package/dist/chunk-VY2UYN5R.mjs.map +1 -0
  92. package/dist/{chunk-QFQRHRZS.mjs → chunk-W2CRQFF6.mjs} +151 -23
  93. package/dist/chunk-W2CRQFF6.mjs.map +1 -0
  94. package/dist/{chunk-Y7A27276.mjs → chunk-WDU6QXNK.mjs} +349 -15
  95. package/dist/chunk-WDU6QXNK.mjs.map +1 -0
  96. package/dist/{chunk-Y2OJJD7R.mjs → chunk-XIVV5IWN.mjs} +7 -9
  97. package/dist/chunk-XIVV5IWN.mjs.map +1 -0
  98. package/dist/{chunk-OYXO65LI.mjs → chunk-YW7OBE6Q.mjs} +4 -4
  99. package/dist/chunk-YW7OBE6Q.mjs.map +1 -0
  100. package/dist/{chunk-YHU7SS6L.mjs → chunk-Z5CQMP54.mjs} +11 -11
  101. package/dist/{chunk-S2XHZS7W.mjs → chunk-ZVWA4ZQ3.mjs} +18 -9
  102. package/dist/chunk-ZVWA4ZQ3.mjs.map +1 -0
  103. package/dist/{chunk-SOU3Q3ZA.mjs → chunk-ZZ57EH5Z.mjs} +1 -1
  104. package/dist/chunk-ZZ57EH5Z.mjs.map +1 -0
  105. package/dist/{client-D_yUjVhe.d.mts → client-BT1mFQas.d.mts} +55 -10
  106. package/dist/{client-Dkc03WP8.d.ts → client-Nn0q4eO4.d.ts} +55 -10
  107. package/dist/{client-plugins-BZnpeTGA.d.ts → client-plugins-Bc5jHcNr.d.ts} +85 -6
  108. package/dist/{client-plugins-g4bzuCmo.d.mts → client-plugins-jsk-ZLzJ.d.mts} +85 -6
  109. package/dist/client-plugins.d.mts +3 -2
  110. package/dist/client-plugins.d.ts +3 -2
  111. package/dist/client.cjs +922 -91
  112. package/dist/client.cjs.map +1 -1
  113. package/dist/client.d.mts +124 -6
  114. package/dist/client.d.ts +124 -6
  115. package/dist/client.mjs +23 -16
  116. package/dist/config.d.mts +3 -2
  117. package/dist/config.d.ts +3 -2
  118. package/dist/cron.cjs.map +1 -1
  119. package/dist/cron.mjs +1 -1
  120. package/dist/{devtools-AE4RVXCM.mjs → devtools-A22KUJZT.mjs} +13 -12
  121. package/dist/{devtools-AE4RVXCM.mjs.map → devtools-A22KUJZT.mjs.map} +1 -1
  122. package/dist/{devtools-client-6WPY2AQU.mjs → devtools-client-3XRTBND5.mjs} +2 -11
  123. package/dist/devtools-client-3XRTBND5.mjs.map +1 -0
  124. package/dist/docs.cjs +65 -58
  125. package/dist/docs.cjs.map +1 -1
  126. package/dist/docs.mjs +13 -12
  127. package/dist/env-types.cjs +14 -5
  128. package/dist/env-types.cjs.map +1 -1
  129. package/dist/env-types.d.mts +2 -1
  130. package/dist/env-types.d.ts +2 -1
  131. package/dist/env-types.mjs +3 -1
  132. package/dist/env.cjs.map +1 -1
  133. package/dist/env.d.mts +1 -1
  134. package/dist/env.d.ts +1 -1
  135. package/dist/env.mjs +1 -1
  136. package/dist/font.cjs +47 -0
  137. package/dist/font.cjs.map +1 -0
  138. package/dist/font.d.mts +70 -0
  139. package/dist/font.d.ts +70 -0
  140. package/dist/font.mjs +10 -0
  141. package/dist/font.mjs.map +1 -0
  142. package/dist/i18n/client.d.mts +2 -2
  143. package/dist/i18n/client.d.ts +2 -2
  144. package/dist/i18n/index.d.mts +3 -3
  145. package/dist/i18n/index.d.ts +3 -3
  146. package/dist/i18n/server.cjs +2 -2
  147. package/dist/i18n/server.cjs.map +1 -1
  148. package/dist/i18n/server.d.mts +5 -5
  149. package/dist/i18n/server.d.ts +5 -5
  150. package/dist/i18n/server.mjs +1 -1
  151. package/dist/index.cjs +5016 -1108
  152. package/dist/index.cjs.map +1 -1
  153. package/dist/index.d.mts +23 -19
  154. package/dist/index.d.ts +23 -19
  155. package/dist/index.mjs +177 -121
  156. package/dist/index.mjs.map +1 -1
  157. package/dist/integrations.d.mts +3 -2
  158. package/dist/integrations.d.ts +3 -2
  159. package/dist/internal/build-runtime.cjs +3504 -581
  160. package/dist/internal/build-runtime.cjs.map +1 -1
  161. package/dist/internal/build-runtime.d.mts +5 -4
  162. package/dist/internal/build-runtime.d.ts +5 -4
  163. package/dist/internal/build-runtime.mjs +32 -29
  164. package/dist/internal/client-runtime.cjs.map +1 -1
  165. package/dist/internal/client-runtime.mjs +1 -1
  166. package/dist/internal/config-runtime.cjs +148 -41
  167. package/dist/internal/config-runtime.cjs.map +1 -1
  168. package/dist/internal/config-runtime.d.mts +4 -3
  169. package/dist/internal/config-runtime.d.ts +4 -3
  170. package/dist/internal/config-runtime.mjs +12 -11
  171. package/dist/internal/production-runtime.cjs +300 -9
  172. package/dist/internal/production-runtime.cjs.map +1 -1
  173. package/dist/internal/production-runtime.d.mts +10 -8
  174. package/dist/internal/production-runtime.d.ts +10 -8
  175. package/dist/internal/production-runtime.mjs +27 -9
  176. package/dist/internal/production-runtime.mjs.map +1 -1
  177. package/dist/markdown.cjs +73 -8
  178. package/dist/markdown.cjs.map +1 -1
  179. package/dist/markdown.d.mts +19 -2
  180. package/dist/markdown.d.ts +19 -2
  181. package/dist/markdown.mjs +5 -1
  182. package/dist/{metadata-C9NZxMDW.d.mts → metadata-7ffpT3jr.d.mts} +1 -1
  183. package/dist/{metadata-DAXRaOHx.d.ts → metadata-JHn-8eht.d.ts} +1 -1
  184. package/dist/middleware.cjs +2 -2
  185. package/dist/middleware.cjs.map +1 -1
  186. package/dist/middleware.d.mts +5 -4
  187. package/dist/middleware.d.ts +5 -4
  188. package/dist/middleware.mjs +3 -3
  189. package/dist/navigation.cjs +40 -15
  190. package/dist/navigation.cjs.map +1 -1
  191. package/dist/navigation.mjs +3 -3
  192. package/dist/{nitro-KME62MWG.mjs → nitro-QO5LV6QK.mjs} +11 -13
  193. package/dist/{nitro-KME62MWG.mjs.map → nitro-QO5LV6QK.mjs.map} +1 -1
  194. package/dist/plugin.cjs +2854 -590
  195. package/dist/plugin.cjs.map +1 -1
  196. package/dist/plugin.d.mts +3 -2
  197. package/dist/plugin.d.ts +3 -2
  198. package/dist/plugin.mjs +28 -25
  199. package/dist/{production-runtime-DRkCHUvJ.d.ts → production-runtime-9KG7GuvW.d.ts} +2 -2
  200. package/dist/{production-runtime-flrjp_nC.d.mts → production-runtime-B-fweKts.d.mts} +2 -2
  201. package/dist/{request-BrFBuc8G.d.mts → request-Dsq4kGW0.d.mts} +1 -1
  202. package/dist/{request-BslSZIRz.d.ts → request-udtobOLv.d.ts} +1 -1
  203. package/dist/request.d.mts +2 -2
  204. package/dist/request.d.ts +2 -2
  205. package/dist/{resolver-DlOPpjkB.d.mts → resolver-DJqjLMg_.d.mts} +1 -1
  206. package/dist/{resolver-C6iecsDV.d.ts → resolver-IH4RmPEl.d.ts} +1 -1
  207. package/dist/routes.cjs +276 -6
  208. package/dist/routes.cjs.map +1 -1
  209. package/dist/routes.d.mts +2 -2
  210. package/dist/routes.d.ts +2 -2
  211. package/dist/routes.mjs +4 -4
  212. package/dist/runtime-9nQjVM7X.d.mts +206 -0
  213. package/dist/{runtime-DeAAZ6gO.d.mts → runtime-Cxpq6xZN.d.mts} +2 -2
  214. package/dist/runtime-DgeS2skB.d.ts +206 -0
  215. package/dist/{runtime-B6GvwDS1.d.ts → runtime-bv63eUiO.d.ts} +2 -2
  216. package/dist/server-action-security.cjs +28 -10
  217. package/dist/server-action-security.cjs.map +1 -1
  218. package/dist/server-action-security.d.mts +2 -1
  219. package/dist/server-action-security.d.ts +2 -1
  220. package/dist/server-action-security.mjs +2 -2
  221. package/dist/server-fn-client.cjs.map +1 -1
  222. package/dist/server-fn-client.d.mts +1 -0
  223. package/dist/server-fn-client.d.ts +1 -0
  224. package/dist/server-fn-client.mjs +1 -1
  225. package/dist/server-fn.cjs +785 -3
  226. package/dist/server-fn.cjs.map +1 -1
  227. package/dist/server-fn.d.mts +10 -1
  228. package/dist/server-fn.d.ts +10 -1
  229. package/dist/server-fn.mjs +6 -3
  230. package/dist/server-plugins.d.mts +4 -3
  231. package/dist/server-plugins.d.ts +4 -3
  232. package/dist/server-query-client.cjs +279 -8
  233. package/dist/server-query-client.cjs.map +1 -1
  234. package/dist/server-query-client.mjs +4 -4
  235. package/dist/server-query.cjs +381 -10
  236. package/dist/server-query.cjs.map +1 -1
  237. package/dist/server-query.mjs +5 -5
  238. package/dist/server.cjs +3319 -841
  239. package/dist/server.cjs.map +1 -1
  240. package/dist/server.d.mts +12 -11
  241. package/dist/server.d.ts +12 -11
  242. package/dist/server.mjs +57 -36
  243. package/dist/server.mjs.map +1 -1
  244. package/dist/testing.cjs +436 -25
  245. package/dist/testing.cjs.map +1 -1
  246. package/dist/testing.d.mts +5 -4
  247. package/dist/testing.d.ts +5 -4
  248. package/dist/testing.mjs +19 -18
  249. package/dist/testing.mjs.map +1 -1
  250. package/dist/transport-BmbGTXA5.d.mts +49 -0
  251. package/dist/transport-BmbGTXA5.d.ts +49 -0
  252. package/dist/{types-BH1lhg5G.d.ts → types-BMxWr97v.d.mts} +2 -2
  253. package/dist/{types-BH1lhg5G.d.mts → types-BMxWr97v.d.ts} +2 -2
  254. package/dist/{utils-DA1yo54_.d.ts → utils-CA0z0c-2.d.ts} +1 -1
  255. package/dist/{utils-DOXXivjL.d.mts → utils-mYVkSOt2.d.mts} +1 -1
  256. package/dist/version.cjs +36 -0
  257. package/dist/version.cjs.map +1 -0
  258. package/dist/version.d.mts +3 -0
  259. package/dist/version.d.ts +3 -0
  260. package/dist/version.mjs +8 -0
  261. package/dist/version.mjs.map +1 -0
  262. package/dist/vite.cjs +2938 -668
  263. package/dist/vite.cjs.map +1 -1
  264. package/dist/vite.d.mts +3 -2
  265. package/dist/vite.d.ts +3 -2
  266. package/dist/vite.mjs +26 -23
  267. package/dist/workflows.cjs +6 -8
  268. package/dist/workflows.cjs.map +1 -1
  269. package/dist/workflows.mjs +1 -1
  270. package/package.json +22 -6
  271. package/types/api.d.ts +44 -0
  272. package/types/client.d.ts +221 -17
  273. package/types/image.d.ts +4 -0
  274. package/types/images.d.ts +59 -0
  275. package/dist/chunk-3QJO55ZF.mjs.map +0 -1
  276. package/dist/chunk-4PTK6KT4.mjs +0 -364
  277. package/dist/chunk-4PTK6KT4.mjs.map +0 -1
  278. package/dist/chunk-AGS7UJ52.mjs.map +0 -1
  279. package/dist/chunk-BHG3LVHH.mjs.map +0 -1
  280. package/dist/chunk-CHFHNEMO.mjs.map +0 -1
  281. package/dist/chunk-EVGBEZDF.mjs +0 -215
  282. package/dist/chunk-EVGBEZDF.mjs.map +0 -1
  283. package/dist/chunk-G3B5BRDY.mjs.map +0 -1
  284. package/dist/chunk-GZP5W4K3.mjs.map +0 -1
  285. package/dist/chunk-HXP3ZSPC.mjs.map +0 -1
  286. package/dist/chunk-JLWMCADZ.mjs.map +0 -1
  287. package/dist/chunk-JN3UU635.mjs.map +0 -1
  288. package/dist/chunk-LLC7BNXW.mjs.map +0 -1
  289. package/dist/chunk-OYXO65LI.mjs.map +0 -1
  290. package/dist/chunk-PRNYWD7K.mjs.map +0 -1
  291. package/dist/chunk-QF4PHCMA.mjs.map +0 -1
  292. package/dist/chunk-QFQRHRZS.mjs.map +0 -1
  293. package/dist/chunk-RKI6TN3A.mjs.map +0 -1
  294. package/dist/chunk-RSKVYESE.mjs.map +0 -1
  295. package/dist/chunk-S2XHZS7W.mjs.map +0 -1
  296. package/dist/chunk-SOU3Q3ZA.mjs.map +0 -1
  297. package/dist/chunk-TU4YJICB.mjs.map +0 -1
  298. package/dist/chunk-TXCFGOHW.mjs +0 -42
  299. package/dist/chunk-TXCFGOHW.mjs.map +0 -1
  300. package/dist/chunk-UHE2TTLK.mjs.map +0 -1
  301. package/dist/chunk-Y2OJJD7R.mjs.map +0 -1
  302. package/dist/chunk-Y7A27276.mjs.map +0 -1
  303. package/dist/chunk-ZJQNATYV.mjs.map +0 -1
  304. package/dist/devtools-client-6WPY2AQU.mjs.map +0 -1
  305. /package/dist/{chunk-TRORP7E4.mjs.map → chunk-7N62DNSO.mjs.map} +0 -0
  306. /package/dist/{chunk-B6N4ZB2H.mjs.map → chunk-C2ROET2V.mjs.map} +0 -0
  307. /package/dist/{chunk-C3DLZMBU.mjs.map → chunk-DJSGLHCN.mjs.map} +0 -0
  308. /package/dist/{chunk-6XDUHOEM.mjs.map → chunk-TQAEEJB4.mjs.map} +0 -0
  309. /package/dist/{chunk-SXZTEK3V.mjs.map → chunk-UXUAWNO5.mjs.map} +0 -0
  310. /package/dist/{chunk-YHU7SS6L.mjs.map → chunk-Z5CQMP54.mjs.map} +0 -0
@@ -9,7 +9,7 @@ import {
9
9
  FARM_DOCS_LAST_MODIFIED_MANIFEST,
10
10
  createFarmDocsLastModifiedManifest,
11
11
  getFarmDocsRouteTypeEntries
12
- } from "./chunk-3QJO55ZF.mjs";
12
+ } from "./chunk-4LND3PXF.mjs";
13
13
  import {
14
14
  generateFarmDocsSearchClientRuntime,
15
15
  isFarmDocsSearchEnabled,
@@ -17,55 +17,54 @@ import {
17
17
  } from "./chunk-V7RBCSDJ.mjs";
18
18
  import {
19
19
  mergeFarmViteConfig
20
- } from "./chunk-RKI6TN3A.mjs";
20
+ } from "./chunk-QM746KUO.mjs";
21
21
  import {
22
22
  hasCustomFarmRouteContext,
23
23
  resolveDeployOutputPath
24
- } from "./chunk-UHE2TTLK.mjs";
24
+ } from "./chunk-K5ZTUF22.mjs";
25
25
  import {
26
26
  PluginManager
27
- } from "./chunk-C3DLZMBU.mjs";
27
+ } from "./chunk-DJSGLHCN.mjs";
28
28
  import {
29
29
  createFarmApp,
30
+ farmFontImportsPlugin,
30
31
  generateFarmClientPluginEntryCode,
31
32
  generateFarmTypeArtifacts,
32
33
  getClientModuleMetadata,
34
+ mergeFarmFontCss,
33
35
  resolveRouteRenderingConfigFromFile
34
- } from "./chunk-CHFHNEMO.mjs";
36
+ } from "./chunk-77BOAQHI.mjs";
35
37
  import {
36
38
  farmEnvironmentFunctionsPlugin
37
39
  } from "./chunk-V6WE6JSZ.mjs";
40
+ import {
41
+ routeRulesToNitroRouteRules
42
+ } from "./chunk-YW7OBE6Q.mjs";
38
43
  import {
39
44
  getFarmAppDirectories
40
45
  } from "./chunk-74YTBPTY.mjs";
41
- import {
42
- routeRulesToNitroRouteRules
43
- } from "./chunk-OYXO65LI.mjs";
44
46
  import {
45
47
  isFarmMarkdownPageFile
46
- } from "./chunk-S2XHZS7W.mjs";
48
+ } from "./chunk-ZVWA4ZQ3.mjs";
47
49
  import {
48
50
  applyFarmWorkflowVercelCrons,
49
51
  prepareFarmWorkflowsForNitro
50
- } from "./chunk-Y2OJJD7R.mjs";
52
+ } from "./chunk-XIVV5IWN.mjs";
51
53
  import {
52
54
  applyFarmCronVercelCrons,
53
55
  createFarmCronCloudflareConfig,
54
56
  mergeScheduledTasks,
55
57
  prepareFarmCronForNitro
56
- } from "./chunk-UREJA4GZ.mjs";
58
+ } from "./chunk-GXASWWJU.mjs";
57
59
  import {
58
60
  getFarmIntegrationPluginServerRuntime
59
61
  } from "./chunk-K4667E2Q.mjs";
60
62
  import {
61
63
  APIRouteManager
62
- } from "./chunk-YHU7SS6L.mjs";
64
+ } from "./chunk-Z5CQMP54.mjs";
63
65
  import {
64
66
  readFarmI18nCatalogs
65
- } from "./chunk-QF4PHCMA.mjs";
66
- import {
67
- logger
68
- } from "./chunk-J4FNJ5IU.mjs";
67
+ } from "./chunk-2ED5Q2GH.mjs";
69
68
  import {
70
69
  createFarmRouteRuntimeKey,
71
70
  getFarmRouteRuntimeConfig,
@@ -74,7 +73,10 @@ import {
74
73
  normalizeFarmRouteRuntimeConfig,
75
74
  resolveFarmRouteRuleRuntimeConfig,
76
75
  resolveFarmRouteRuntimeConfig
77
- } from "./chunk-QM6VV26B.mjs";
76
+ } from "./chunk-GQVGIUSN.mjs";
77
+ import {
78
+ logger
79
+ } from "./chunk-J4FNJ5IU.mjs";
78
80
  import {
79
81
  __name
80
82
  } from "./chunk-CGILA3WO.mjs";
@@ -299,8 +301,8 @@ function compareRuntimeRoutes(left, right) {
299
301
  __name(compareRuntimeRoutes, "compareRuntimeRoutes");
300
302
  function getPatternSpecificity(pattern) {
301
303
  return normalizePattern(pattern).split("/").filter(Boolean).reduce((score, segment) => {
302
- if (segment === "**" || /^\[\[\.\.\./.test(segment)) return score + 1;
303
- if (segment === "*" || /^\[\.\.\./.test(segment)) return score + 10;
304
+ if (segment === "**" || segment.startsWith("[[...")) return score + 1;
305
+ if (segment === "*" || segment.startsWith("[...")) return score + 10;
304
306
  if (/^\[.+\]$/.test(segment)) return score + 50;
305
307
  return score + 100;
306
308
  }, 0);
@@ -743,12 +745,28 @@ async function buildUniversal(config, routeManager, apiRouteManager, serverRende
743
745
  const routeRuntimeManifestResultPromise = Promise.allSettled([routeRuntimeManifestPromise]);
744
746
  const pageRoutes = [];
745
747
  for (const [pattern, entry] of routeManager.getRoutes()) {
748
+ const markdownSourcePath = entry.markdownSourcePath || (isFarmMarkdownPageFile(entry.modulePath) ? entry.modulePath : void 0);
746
749
  pageRoutes.push({
747
750
  pattern,
748
751
  modulePath: entry.modulePath,
749
- ...isFarmMarkdownPageFile(entry.modulePath) ? { source: readFileSync(entry.modulePath, "utf8") } : {}
752
+ ...markdownSourcePath ? {
753
+ source: readFileSync(markdownSourcePath, "utf8"),
754
+ markdownSourcePath
755
+ } : {}
750
756
  });
751
757
  }
758
+ const routeSlots = Array.from(
759
+ routeManager.getRouteSlots().values(),
760
+ (entry) => ({
761
+ name: entry.name,
762
+ ownerPattern: entry.ownerPattern,
763
+ pattern: entry.pattern,
764
+ modulePath: entry.modulePath,
765
+ containerId: entry.containerId,
766
+ interception: entry.interception,
767
+ fallback: entry.fallback
768
+ })
769
+ );
752
770
  logger.info(`\u{1F4CB} Found ${pageRoutes.length} page routes`);
753
771
  const fs = await import("fs/promises");
754
772
  const layoutRoutes = [];
@@ -792,7 +810,16 @@ async function buildUniversal(config, routeManager, apiRouteManager, serverRende
792
810
  logger.info("\u{1F4E6} Building client and SSR bundles in parallel...");
793
811
  const [clientBuildResult, ssrBuildResult] = await Promise.allSettled([
794
812
  // Client build (to disk)
795
- buildClient(productionVite, config, root, srcDir, clientOutputDir, pageRoutes, layoutRoutes),
813
+ buildClient(
814
+ productionVite,
815
+ config,
816
+ root,
817
+ srcDir,
818
+ clientOutputDir,
819
+ pageRoutes,
820
+ layoutRoutes,
821
+ routeSlots
822
+ ),
796
823
  // SSR build (in memory)
797
824
  buildSSRInMemory(
798
825
  productionVite,
@@ -803,7 +830,8 @@ async function buildUniversal(config, routeManager, apiRouteManager, serverRende
803
830
  serverRenderer,
804
831
  preset,
805
832
  pageRoutes,
806
- layoutRoutes
833
+ layoutRoutes,
834
+ routeSlots
807
835
  )
808
836
  ]);
809
837
  const [routeRuntimeManifestResult] = await routeRuntimeManifestResultPromise;
@@ -823,7 +851,8 @@ async function buildUniversal(config, routeManager, apiRouteManager, serverRende
823
851
  srcDir,
824
852
  clientOutputDir,
825
853
  pageRoutes,
826
- layoutRoutes
854
+ layoutRoutes,
855
+ routeSlots
827
856
  );
828
857
  }
829
858
  const ssrResult = ssrBuildResult.value;
@@ -878,12 +907,41 @@ async function writeSSRAssetsToClient(bundle, outputDir) {
878
907
  const fs = await import("fs/promises");
879
908
  for (const [fileName, output] of Object.entries(bundle)) {
880
909
  if (output.type !== "asset") continue;
910
+ if (fileName === "farm-fonts.css") {
911
+ await mergeBuiltFontCss(outputDir, output.source);
912
+ continue;
913
+ }
881
914
  const filePath = path3.join(outputDir, fileName);
882
915
  await fs.mkdir(path3.dirname(filePath), { recursive: true });
883
916
  await fs.writeFile(filePath, output.source);
884
917
  }
885
918
  }
886
919
  __name(writeSSRAssetsToClient, "writeSSRAssetsToClient");
920
+ async function mergeBuiltFontCss(outputDir, fontCssSource) {
921
+ const fs = await import("fs/promises");
922
+ const fontCssPath = path3.join(outputDir, "farm-fonts.css");
923
+ let fontCss = fontCssSource;
924
+ if (fontCss === void 0) {
925
+ try {
926
+ fontCss = await fs.readFile(fontCssPath);
927
+ } catch {
928
+ return;
929
+ }
930
+ }
931
+ const clientCssPath = path3.join(outputDir, "farm-client.css");
932
+ let clientCss = "";
933
+ try {
934
+ clientCss = await fs.readFile(clientCssPath, "utf8");
935
+ } catch {
936
+ }
937
+ const normalizedFontCss = typeof fontCss === "string" ? fontCss : Buffer.from(fontCss).toString("utf8");
938
+ await fs.writeFile(clientCssPath, mergeFarmFontCss(clientCss, normalizedFontCss));
939
+ try {
940
+ await fs.rm(fontCssPath, { force: true });
941
+ } catch {
942
+ }
943
+ }
944
+ __name(mergeBuiltFontCss, "mergeBuiltFontCss");
887
945
  var _IncompleteClientBuildOutputError = class _IncompleteClientBuildOutputError extends Error {
888
946
  constructor(detail) {
889
947
  super(`Farm client build produced incomplete output: ${detail}`);
@@ -926,7 +984,7 @@ async function validateClientBuildOutput(root, srcDir, outputDir) {
926
984
  }
927
985
  }
928
986
  __name(validateClientBuildOutput, "validateClientBuildOutput");
929
- async function buildClient(productionVite, config, root, srcDir, outputDir, pageRoutes, layoutRoutes = []) {
987
+ async function buildClient(productionVite, config, root, srcDir, outputDir, pageRoutes, layoutRoutes = [], routeSlots = []) {
930
988
  const viteBuild = productionVite.build;
931
989
  const { farmPlugin } = await import("./vite.mjs");
932
990
  const { PluginManager: PluginManager2 } = await import("./plugin.mjs");
@@ -953,8 +1011,16 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
953
1011
  logger.warn(`\u26A0\uFE0F Could not inspect route file ${route.modulePath}: ${error}`);
954
1012
  }
955
1013
  }
1014
+ const clientRouteSlots = routeSlots.filter((slot) => {
1015
+ try {
1016
+ return getClientModuleMetadata(slot.modulePath, root).shouldHydrate;
1017
+ } catch (error) {
1018
+ logger.warn(`\u26A0\uFE0F Could not inspect route slot ${slot.modulePath}: ${error}`);
1019
+ return false;
1020
+ }
1021
+ });
956
1022
  logger.info(
957
- `\u{1F4F1} Total hydratable routes detected: ${clientPages.length} out of ${pageRoutes.length} pages`
1023
+ `\u{1F4F1} Total hydratable routes detected: ${clientPages.length} pages and ${clientRouteSlots.length} slots`
958
1024
  );
959
1025
  const clientEntryRoot = path3.join(root, ".farm", "tmp");
960
1026
  await fs.mkdir(clientEntryRoot, { recursive: true });
@@ -963,6 +1029,7 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
963
1029
  const clientHydrationCode = generateClientHydrationEntry(
964
1030
  clientPages,
965
1031
  layoutRoutes,
1032
+ clientRouteSlots,
966
1033
  root,
967
1034
  srcDir,
968
1035
  isFarmDocsSearchEnabled(config.docs),
@@ -1089,7 +1156,8 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
1089
1156
  'export { Link } from "@farm.js/core/client";',
1090
1157
  'export { useRouter } from "@farm.js/core/client";',
1091
1158
  'export { usePathname, useSearchParams } from "@farm.js/core/navigation";',
1092
- 'export { createAPIClient } from "@farm.js/core/client";'
1159
+ 'export { createAPIClient } from "@farm.js/core/client";',
1160
+ 'export { localFont, remoteFont } from "@farm.js/core/font";'
1093
1161
  ].join("\n");
1094
1162
  }
1095
1163
  return null;
@@ -1116,6 +1184,7 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
1116
1184
  ]
1117
1185
  }
1118
1186
  });
1187
+ await mergeBuiltFontCss(outputDir);
1119
1188
  await validateClientBuildOutput(root, srcDir, outputDir);
1120
1189
  } finally {
1121
1190
  try {
@@ -1295,7 +1364,7 @@ function generateUniversalRouterStateProperties() {
1295
1364
  `.trim();
1296
1365
  }
1297
1366
  __name(generateUniversalRouterStateProperties, "generateUniversalRouterStateProperties");
1298
- function generateClientHydrationEntry(clientPages, layoutRoutes, root, srcDir, docsSearchEnabled, docsSearchModuleId, i18nConfig = {
1367
+ function generateClientHydrationEntry(clientPages, layoutRoutes, clientRouteSlots, root, srcDir, docsSearchEnabled, docsSearchModuleId, i18nConfig = {
1299
1368
  enabled: false,
1300
1369
  locales: ["en"],
1301
1370
  defaultLocale: "en",
@@ -1363,7 +1432,7 @@ function isFarmLocaleDocumentChange() {
1363
1432
  return false;
1364
1433
  }
1365
1434
  `;
1366
- if (clientPages.length === 0) {
1435
+ if (clientPages.length === 0 && clientRouteSlots.length === 0) {
1367
1436
  return `
1368
1437
  // Farm.js Client Runtime (no client components)
1369
1438
  ${cssImport}
@@ -1613,11 +1682,25 @@ document.addEventListener("click", function(e) {
1613
1682
  }
1614
1683
  const imports = [];
1615
1684
  const routeEntries = [];
1685
+ const routeSlotEntries = [];
1616
1686
  clientPages.forEach((page, index) => {
1617
1687
  const importPath = toImportPath(page.modulePath);
1618
1688
  imports.push(`import Page${index} from "${importPath}";`);
1619
1689
  routeEntries.push(` { pattern: ${JSON.stringify(page.pattern)}, Component: Page${index} }`);
1620
1690
  });
1691
+ clientRouteSlots.forEach((slot, index) => {
1692
+ const importPath = toImportPath(slot.modulePath);
1693
+ imports.push(`import RouteSlot${index} from "${importPath}";`);
1694
+ routeSlotEntries.push(` {
1695
+ name: ${JSON.stringify(slot.name)},
1696
+ ownerPattern: ${JSON.stringify(slot.ownerPattern)},
1697
+ pattern: ${JSON.stringify(slot.pattern)},
1698
+ containerId: ${JSON.stringify(slot.containerId)},
1699
+ interception: ${JSON.stringify(slot.interception)},
1700
+ fallback: ${JSON.stringify(slot.fallback)},
1701
+ Component: RouteSlot${index},
1702
+ }`);
1703
+ });
1621
1704
  return `
1622
1705
  // Farm.js Client Runtime - SPA with Hydration
1623
1706
  ${cssImport}
@@ -1639,6 +1722,10 @@ const clientRoutes = [
1639
1722
  ${routeEntries.join(",\n")}
1640
1723
  ];
1641
1724
 
1725
+ const clientRouteSlots = [
1726
+ ${routeSlotEntries.join(",\n")}
1727
+ ];
1728
+
1642
1729
  // Layout routes for wrapping client components
1643
1730
  const layoutRoutes = [
1644
1731
  ${layoutRegistrations.join(",\n")}
@@ -1693,6 +1780,146 @@ function matchRoute(pathname) {
1693
1780
  return null;
1694
1781
  }
1695
1782
 
1783
+ function matchesRoutePrefix(pathname, pattern) {
1784
+ if (pattern === "/") return true;
1785
+ const pathSegments = getFarmRoutePathname(pathname).split("/").filter(Boolean);
1786
+ const patternSegments = pattern.split("/").filter(Boolean);
1787
+ if (patternSegments.length > pathSegments.length) return false;
1788
+ const candidate = "/" + pathSegments.slice(0, patternSegments.length).join("/");
1789
+ return matchFarmRoute(pattern, candidate) !== null;
1790
+ }
1791
+
1792
+ function matchInterceptedRouteSlot(pathname, from) {
1793
+ for (const slot of clientRouteSlots) {
1794
+ if (!slot.interception || !matchesRoutePrefix(from, slot.ownerPattern)) continue;
1795
+ const params = matchFarmRoute(slot.pattern, getFarmRoutePathname(pathname));
1796
+ if (params !== null) return { slot: slot, params: params };
1797
+ }
1798
+ return null;
1799
+ }
1800
+
1801
+ function routeSlotKey(slot) {
1802
+ return slot.ownerPattern + ":" + slot.name;
1803
+ }
1804
+
1805
+ function findClientRouteSlot(slot) {
1806
+ return clientRouteSlots.find(function(candidate) {
1807
+ return candidate.name === slot.name &&
1808
+ candidate.ownerPattern === slot.ownerPattern &&
1809
+ candidate.pattern === slot.pattern &&
1810
+ candidate.interception === slot.interception &&
1811
+ candidate.fallback === slot.fallback;
1812
+ });
1813
+ }
1814
+
1815
+ function readRouteSlotPayload(doc) {
1816
+ const script = doc.getElementById("__farm_route_slots_data__");
1817
+ if (!script?.textContent) return [];
1818
+ try {
1819
+ const parsed = JSON.parse(script.textContent);
1820
+ return Array.isArray(parsed) ? parsed : [];
1821
+ } catch {
1822
+ return [];
1823
+ }
1824
+ }
1825
+
1826
+ const routeSlotRoots = new Map();
1827
+ let activeRouteInterception = null;
1828
+
1829
+ function resetRouteSlotRoots() {
1830
+ for (const root of routeSlotRoots.values()) {
1831
+ try { root.unmount(); } catch {}
1832
+ }
1833
+ routeSlotRoots.clear();
1834
+ activeRouteInterception = null;
1835
+ }
1836
+
1837
+ function renderClientRouteSlot(slot, registration, mode) {
1838
+ const container = document.getElementById(slot.containerId);
1839
+ if (!container || !registration?.Component) return false;
1840
+ const key = routeSlotKey(slot);
1841
+ const existingRoot = routeSlotRoots.get(key);
1842
+ const props = slot.props && typeof slot.props === "object" ? slot.props : {};
1843
+ const element = React.createElement(registration.Component, props);
1844
+
1845
+ if (mode === "hydrate") {
1846
+ if (existingRoot) return true;
1847
+ const root = hydrateRoot(container, element);
1848
+ routeSlotRoots.set(key, root);
1849
+ return true;
1850
+ }
1851
+
1852
+ if (existingRoot) {
1853
+ try { existingRoot.unmount(); } catch {}
1854
+ routeSlotRoots.delete(key);
1855
+ } else {
1856
+ container.replaceChildren();
1857
+ }
1858
+ const root = createRoot(container);
1859
+ root.render(element);
1860
+ routeSlotRoots.set(key, root);
1861
+ return true;
1862
+ }
1863
+
1864
+ function hydrateInitialRouteSlots() {
1865
+ const slots = Array.isArray(window.__FARM_ROUTE_SLOTS__)
1866
+ ? window.__FARM_ROUTE_SLOTS__
1867
+ : [];
1868
+ for (const slot of slots) {
1869
+ const registration = findClientRouteSlot(slot);
1870
+ if (!registration) continue;
1871
+ try {
1872
+ renderClientRouteSlot(slot, registration, "hydrate");
1873
+ } catch (error) {
1874
+ console.warn("[Farm.js] Could not hydrate route slot:", slot.name, error);
1875
+ }
1876
+ }
1877
+ }
1878
+
1879
+ function renderRouteInterception(slot, registration, from) {
1880
+ const container = document.getElementById(slot.containerId);
1881
+ if (!container) return false;
1882
+ const key = routeSlotKey(slot);
1883
+ const previousSlot = (window.__FARM_ROUTE_SLOTS__ || []).find(function(candidate) {
1884
+ return routeSlotKey(candidate) === key;
1885
+ }) || null;
1886
+ const previousHtml = container.innerHTML;
1887
+
1888
+ if (!renderClientRouteSlot(slot, registration, "render")) return false;
1889
+ activeRouteInterception = {
1890
+ from: from,
1891
+ key: key,
1892
+ slot: slot,
1893
+ previousSlot: previousSlot,
1894
+ previousHtml: previousHtml,
1895
+ };
1896
+ return true;
1897
+ }
1898
+
1899
+ function clearRouteInterception(destination) {
1900
+ if (!activeRouteInterception) return false;
1901
+ const active = activeRouteInterception;
1902
+ activeRouteInterception = null;
1903
+ const root = routeSlotRoots.get(active.key);
1904
+ if (root) {
1905
+ try { root.unmount(); } catch {}
1906
+ routeSlotRoots.delete(active.key);
1907
+ }
1908
+ const container = document.getElementById(active.slot.containerId);
1909
+ if (container) {
1910
+ container.innerHTML = active.previousHtml;
1911
+ if (active.previousSlot) {
1912
+ const registration = findClientRouteSlot(active.previousSlot);
1913
+ if (registration) {
1914
+ try {
1915
+ renderClientRouteSlot(active.previousSlot, registration, "hydrate");
1916
+ } catch {}
1917
+ }
1918
+ }
1919
+ }
1920
+ return destination === active.from;
1921
+ }
1922
+
1696
1923
  // State
1697
1924
  let reactRoot = null;
1698
1925
  let currentPathname = null;
@@ -1711,12 +1938,17 @@ function resetReactRoot() {
1711
1938
  async function hydrate() {
1712
1939
  const pathname = window.location.pathname;
1713
1940
  const matched = matchRoute(pathname);
1714
-
1941
+ hydrateInitialRouteSlots();
1942
+
1715
1943
  if (!matched) {
1716
1944
  return;
1717
1945
  }
1718
1946
 
1719
- const container = document.getElementById("root");
1947
+ const hasRouteSlots =
1948
+ Array.isArray(window.__FARM_ROUTE_SLOTS__) && window.__FARM_ROUTE_SLOTS__.length > 0;
1949
+ const container =
1950
+ (hasRouteSlots ? document.getElementById("__farm_page__") : null) ||
1951
+ document.getElementById("root");
1720
1952
  if (!container) {
1721
1953
  console.error("[Farm.js] No root element found");
1722
1954
  return;
@@ -1730,7 +1962,9 @@ async function hydrate() {
1730
1962
 
1731
1963
  // Create page element and wrap with layouts
1732
1964
  const pageElement = React.createElement(Component, props);
1733
- const wrappedElement = wrapWithLayouts(pageElement, pathname, params);
1965
+ const wrappedElement = hasRouteSlots
1966
+ ? pageElement
1967
+ : wrapWithLayouts(pageElement, pathname, params);
1734
1968
 
1735
1969
  const shouldHydrate = !isHydrated && Boolean(container.innerHTML.trim());
1736
1970
  const hydrationSession = await farmClientRuntime.beginHydration({
@@ -1795,6 +2029,57 @@ ${generateUniversalRouterStateProperties()}
1795
2029
  : undefined,
1796
2030
  });
1797
2031
 
2032
+ if (activeRouteInterception && clearRouteInterception(to)) {
2033
+ await farmClientRuntime.markNavigationLoaded(clientNavigation, {
2034
+ routeSlots: "restored",
2035
+ });
2036
+ await farmClientRuntime.resolveNavigation(clientNavigation);
2037
+ void farmClientRuntime.scheduleNavigationRendered(clientNavigation);
2038
+ this.currentPath = to;
2039
+ this.finishNavigation();
2040
+ return;
2041
+ }
2042
+ if (activeRouteInterception) {
2043
+ clearRouteInterception(to);
2044
+ }
2045
+
2046
+ const intercepted = matchInterceptedRouteSlot(pathname, from);
2047
+ if (intercepted) {
2048
+ const html = await this.fetchPage(to, from);
2049
+ const doc = new DOMParser().parseFromString(html, "text/html");
2050
+ const slotPayload = readRouteSlotPayload(doc);
2051
+ const selectedSlot = slotPayload.find(function(slot) {
2052
+ return slot.interception &&
2053
+ slot.name === intercepted.slot.name &&
2054
+ slot.ownerPattern === intercepted.slot.ownerPattern;
2055
+ });
2056
+
2057
+ if (
2058
+ selectedSlot &&
2059
+ renderRouteInterception(selectedSlot, intercepted.slot, from)
2060
+ ) {
2061
+ await farmClientRuntime.markNavigationLoaded(clientNavigation, {
2062
+ route: intercepted.slot.pattern,
2063
+ params: intercepted.params,
2064
+ });
2065
+ const historyState = createHistoryState(
2066
+ to,
2067
+ options.state,
2068
+ window.history.state,
2069
+ );
2070
+ if (action === "replace") {
2071
+ window.history.replaceState(historyState, "", url);
2072
+ } else if (action !== "pop") {
2073
+ window.history.pushState(historyState, "", url);
2074
+ }
2075
+ await farmClientRuntime.resolveNavigation(clientNavigation);
2076
+ void farmClientRuntime.scheduleNavigationRendered(clientNavigation);
2077
+ this.currentPath = to;
2078
+ this.finishNavigation();
2079
+ return;
2080
+ }
2081
+ }
2082
+
1798
2083
  if (matched) {
1799
2084
  const Component = matched.route.Component;
1800
2085
  const params = matched.params;
@@ -1871,21 +2156,28 @@ ${generateUniversalRouterStateProperties()}
1871
2156
  }
1872
2157
  },
1873
2158
 
1874
- fetchPage: async function(url) {
1875
- const cached = this.prefetchCache.get(url);
2159
+ fetchPage: async function(url, interceptFrom) {
2160
+ const cacheKey = interceptFrom ? url + "\\nintercept:" + interceptFrom : url;
2161
+ const cached = this.prefetchCache.get(cacheKey);
1876
2162
  if (cached) return cached;
1877
2163
 
1878
2164
  const response = await fetch(url, {
1879
- headers: { "Accept": "text/html" }
2165
+ headers: {
2166
+ "Accept": "text/html",
2167
+ ...(interceptFrom ? { "X-Farm-Intercept-From": interceptFrom } : {}),
2168
+ }
1880
2169
  });
1881
2170
  if (!response.ok) throw new Error("Failed to fetch page");
1882
- return response.text();
2171
+ const html = await response.text();
2172
+ this.prefetchCache.set(cacheKey, html);
2173
+ return html;
1883
2174
  },
1884
2175
 
1885
2176
  swapContent: function(html, targetPath) {
1886
2177
  const parser = new DOMParser();
1887
2178
  const doc = parser.parseFromString(html, "text/html");
1888
2179
  if (isFarmLocaleDocumentChange(doc)) return false;
2180
+ const nextRouteSlots = readRouteSlotPayload(doc);
1889
2181
 
1890
2182
  // Update title
1891
2183
  const newTitle = doc.querySelector("title");
@@ -1910,7 +2202,10 @@ ${generateUniversalRouterStateProperties()}
1910
2202
  const currentRoot = document.getElementById("root");
1911
2203
  if (!newRoot || !currentRoot) return this.swapDocument(doc);
1912
2204
  resetReactRoot();
2205
+ resetRouteSlotRoots();
1913
2206
  currentRoot.innerHTML = newRoot.innerHTML;
2207
+ window.__FARM_ROUTE_SLOTS__ = nextRouteSlots;
2208
+ hydrateInitialRouteSlots();
1914
2209
 
1915
2210
  // Check if new page has a client component
1916
2211
  const targetUrl = new URL(targetPath || window.location.href, window.location.origin);
@@ -1922,13 +2217,15 @@ ${generateUniversalRouterStateProperties()}
1922
2217
  const params = matched.params;
1923
2218
  const searchParams = Object.fromEntries(targetUrl.searchParams);
1924
2219
  const props = { params: params, searchParams: Promise.resolve(searchParams) };
1925
-
1926
- if (!reactRoot) {
1927
- reactRoot = createRoot(currentRoot);
1928
- }
1929
2220
  const pageElement = React.createElement(Component, props);
1930
- const wrappedElement = wrapWithLayouts(pageElement, newPathname, params);
1931
- reactRoot.render(wrappedElement);
2221
+ const hasRouteSlots = nextRouteSlots.length > 0;
2222
+ const pageContainer =
2223
+ (hasRouteSlots ? document.getElementById("__farm_page__") : null) || currentRoot;
2224
+ const wrappedElement = hasRouteSlots
2225
+ ? pageElement
2226
+ : wrapWithLayouts(pageElement, newPathname, params);
2227
+ reactRoot = hydrateRoot(pageContainer, wrappedElement);
2228
+ isHydrated = true;
1932
2229
  }
1933
2230
  return true;
1934
2231
  },
@@ -1937,6 +2234,7 @@ ${generateUniversalRouterStateProperties()}
1937
2234
  if (!doc.documentElement || !doc.body) return false;
1938
2235
 
1939
2236
  resetReactRoot();
2237
+ resetRouteSlotRoots();
1940
2238
 
1941
2239
  Array.from(document.documentElement.attributes).forEach(function(attr) {
1942
2240
  if (!doc.documentElement.hasAttribute(attr.name)) {
@@ -1970,10 +2268,12 @@ ${generateUniversalRouterStateProperties()}
1970
2268
  if (url.origin !== window.location.origin) return;
1971
2269
 
1972
2270
  const pathname = url.pathname + url.search;
1973
- if (this.prefetchCache.has(pathname)) return;
2271
+ const interceptFrom = this.currentPath;
2272
+ const cacheKey = pathname + "\\nintercept:" + interceptFrom;
2273
+ if (this.prefetchCache.has(cacheKey)) return;
1974
2274
 
1975
- this.fetchPage(pathname)
1976
- .then(function(html) { spaRouter.prefetchCache.set(pathname, html); })
2275
+ this.fetchPage(pathname, interceptFrom)
2276
+ .then(function(html) { spaRouter.prefetchCache.set(cacheKey, html); })
1977
2277
  .catch(function() {});
1978
2278
  },
1979
2279
 
@@ -2064,7 +2364,7 @@ if (isFarmDocsSearchPage()) {
2064
2364
  `.trim();
2065
2365
  }
2066
2366
  __name(generateClientHydrationEntry, "generateClientHydrationEntry");
2067
- async function buildSSRInMemory(productionVite, config, root, routeManager, apiRouteManager, serverRenderer, preset, collectedPageRoutes, collectedLayoutRoutes) {
2367
+ async function buildSSRInMemory(productionVite, config, root, routeManager, apiRouteManager, serverRenderer, preset, collectedPageRoutes, collectedLayoutRoutes, collectedRouteSlots) {
2068
2368
  const viteBuild = productionVite.build;
2069
2369
  const { farmPlugin } = await import("./vite.mjs");
2070
2370
  const { PluginManager: PluginManager2 } = await import("./plugin.mjs");
@@ -2097,6 +2397,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
2097
2397
  let ssrEntryFile;
2098
2398
  const pageRoutes = collectedPageRoutes.map((route) => ({ ...route }));
2099
2399
  const layoutRoutes = collectedLayoutRoutes.map((route) => ({ ...route }));
2400
+ const routeSlots = collectedRouteSlots.map((slot) => ({ ...slot }));
2100
2401
  const metadataImageRoutes = [];
2101
2402
  for (const entry of routeManager.getMetadataImages().values()) {
2102
2403
  if (entry.sourceType === "static") {
@@ -2197,6 +2498,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
2197
2498
  apiRoutes,
2198
2499
  pageRoutes,
2199
2500
  layoutRoutes,
2501
+ routeSlots,
2200
2502
  errorRoutes,
2201
2503
  metadataImageRoutes,
2202
2504
  middlewareRoutes,
@@ -2283,14 +2585,11 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
2283
2585
  ".prisma/client",
2284
2586
  ".prisma/client/default"
2285
2587
  ],
2286
- // Don't externalize these - bundle them into the SSR output
2287
- // Keep this list minimal for faster builds
2288
- noExternal: [
2289
- "@farm.js/core",
2290
- "@farm.js/core/image",
2291
- "better-call",
2292
- ...preset === "cloudflare-module" ? [] : ["react", "react-dom", "react-dom/server"]
2293
- ]
2588
+ // Node deployments must bundle application dependencies with Farm's
2589
+ // React runtime. Leaving a React component package external can make it
2590
+ // resolve a second React instance at runtime and break hooks during SSR.
2591
+ // Native and build-only packages above remain explicitly external.
2592
+ noExternal: preset === "cloudflare-module" ? ["@farm.js/core", "@farm.js/core/image", "better-call"] : true
2294
2593
  },
2295
2594
  define: {
2296
2595
  __FARM_ENV__: JSON.stringify(config.env || { server: {}, public: {} }),
@@ -2367,10 +2666,14 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
2367
2666
  }
2368
2667
  }
2369
2668
  }
2370
- return { bundle: ssrBundle, entryFile: ssrEntryFile, configuredHeaderRoutes };
2669
+ return {
2670
+ bundle: ssrBundle,
2671
+ entryFile: ssrEntryFile,
2672
+ configuredHeaderRoutes
2673
+ };
2371
2674
  }
2372
2675
  __name(buildSSRInMemory, "buildSSRInMemory");
2373
- function generateVirtualEntryCode(apiRoutes, pageRoutes, layoutRoutes, errorRoutes, metadataImageRoutes, middlewareRoutes, redirectRoutes, configuredRewriteRoutes, configuredHeaderRoutes, notFoundPath, config, configModulePath, hasServerRuntimeIntegrations, hasRuntimeIntegrationConfig, hasConfiguredRuntimePlugins, preset, i18nCatalogs) {
2676
+ function generateVirtualEntryCode(apiRoutes, pageRoutes, layoutRoutes, routeSlots, errorRoutes, metadataImageRoutes, middlewareRoutes, redirectRoutes, configuredRewriteRoutes, configuredHeaderRoutes, notFoundPath, config, configModulePath, hasServerRuntimeIntegrations, hasRuntimeIntegrationConfig, hasConfiguredRuntimePlugins, preset, i18nCatalogs) {
2374
2677
  const hasPluginRuntime = hasRuntimeIntegrationConfig || hasConfiguredRuntimePlugins;
2375
2678
  const hasMiddlewareRuntime = middlewareRoutes.length > 0 || hasFarmMiddlewareConfig(config.middleware);
2376
2679
  const farmDocsBaseConfig = config.docs?.enabled ? { ...config.docs, config: void 0 } : void 0;
@@ -2388,15 +2691,13 @@ function generateVirtualEntryCode(apiRoutes, pageRoutes, layoutRoutes, errorRout
2388
2691
  });
2389
2692
  const pageImports = [];
2390
2693
  const pageRegistrations = [];
2391
- const hasMarkdownPages = pageRoutes.some(
2392
- (route) => route.source !== void 0 || isFarmMarkdownPageFile(route.modulePath)
2393
- );
2694
+ const hasMarkdownPages = pageRoutes.some((route) => route.source !== void 0);
2394
2695
  const orderedPageRoutes = pageRoutes.map((route, index) => ({ route, index })).sort(
2395
2696
  (left, right) => routePatternSpecificity(right.route.pattern) - routePatternSpecificity(left.route.pattern) || left.index - right.index
2396
2697
  ).map(({ route }) => route);
2397
2698
  orderedPageRoutes.forEach((route, index) => {
2398
2699
  const varName = `pageRoute${index}`;
2399
- if (route.source !== void 0 || isFarmMarkdownPageFile(route.modulePath)) {
2700
+ if (isFarmMarkdownPageFile(route.modulePath)) {
2400
2701
  pageRegistrations.push(`
2401
2702
  {
2402
2703
  pattern: ${JSON.stringify(route.pattern)},
@@ -2408,16 +2709,22 @@ function generateVirtualEntryCode(apiRoutes, pageRoutes, layoutRoutes, errorRout
2408
2709
  }),
2409
2710
  markdownSource: {
2410
2711
  source: ${JSON.stringify(route.source ?? "")},
2411
- filePath: ${JSON.stringify(route.modulePath)},
2712
+ filePath: ${JSON.stringify(route.markdownSourcePath ?? route.modulePath)},
2412
2713
  },
2413
2714
  }`);
2414
2715
  return;
2415
2716
  }
2416
2717
  pageImports.push(`import * as ${varName} from "${route.modulePath}";`);
2718
+ const shouldHydrate = getClientModuleMetadata(route.modulePath, config.root).shouldHydrate;
2417
2719
  pageRegistrations.push(`
2418
2720
  {
2419
2721
  pattern: ${JSON.stringify(route.pattern)},
2420
2722
  module: ${varName},
2723
+ shouldHydrate: ${JSON.stringify(shouldHydrate)},
2724
+ ${route.source !== void 0 ? `markdownSource: {
2725
+ source: ${JSON.stringify(route.source)},
2726
+ filePath: ${JSON.stringify(route.markdownSourcePath)},
2727
+ },` : ""}
2421
2728
  }`);
2422
2729
  });
2423
2730
  const layoutImports = [];
@@ -2431,6 +2738,22 @@ function generateVirtualEntryCode(apiRoutes, pageRoutes, layoutRoutes, errorRout
2431
2738
  module: ${varName},
2432
2739
  }`);
2433
2740
  });
2741
+ const routeSlotImports = [];
2742
+ const routeSlotRegistrations = [];
2743
+ routeSlots.forEach((slot, index) => {
2744
+ const varName = `routeSlot${index}`;
2745
+ routeSlotImports.push(`import * as ${varName} from "${slot.modulePath}";`);
2746
+ routeSlotRegistrations.push(`
2747
+ {
2748
+ name: ${JSON.stringify(slot.name)},
2749
+ ownerPattern: ${JSON.stringify(slot.ownerPattern)},
2750
+ pattern: ${JSON.stringify(slot.pattern)},
2751
+ containerId: ${JSON.stringify(slot.containerId)},
2752
+ interception: ${JSON.stringify(slot.interception)},
2753
+ fallback: ${JSON.stringify(slot.fallback)},
2754
+ module: ${varName},
2755
+ }`);
2756
+ });
2434
2757
  const errorImports = [];
2435
2758
  const errorRegistrations = [];
2436
2759
  errorRoutes.forEach((errorRoute, index) => {
@@ -2480,7 +2803,9 @@ function generateVirtualEntryCode(apiRoutes, pageRoutes, layoutRoutes, errorRout
2480
2803
  _runWithMiddlewareContext,
2481
2804
  _runWithMiddlewareData,
2482
2805
  addMetadataImageReference,
2806
+ appendFarmLinkHeader,
2483
2807
  applyProductionMiddlewareHeaders,
2808
+ configureFarmCache,
2484
2809
  configureFarmObservability,
2485
2810
  createFarmCacheKey,
2486
2811
  createFarmLocaleCookie,
@@ -2506,7 +2831,7 @@ function generateVirtualEntryCode(apiRoutes, pageRoutes, layoutRoutes, errorRout
2506
2831
  const docsRuntimeImport = config.docs?.enabled ? `import { existsSync as farmDocsExistsSync } from "node:fs";
2507
2832
  import { dirname as farmDocsDirname, join as farmDocsJoin } from "node:path";
2508
2833
  import { fileURLToPath as farmDocsFileURLToPath } from "node:url";` : "";
2509
- const markdownHandlerImport = config.md?.enabled ? `import { createMarkdownMirrorResponse } from "@farm.js/core/markdown";` : "";
2834
+ const markdownHandlerImport = config.md?.enabled ? `import { applyMarkdownNegotiationHeaders, createMarkdownMirrorResponse } from "@farm.js/core/markdown";` : "";
2510
2835
  const appMarkdownImport = hasMarkdownPages ? `import { createFarmMarkdownRouteModule, createFarmMarkdownSourceResponse } from "@farm.js/core/app-markdown";` : "const createFarmMarkdownSourceResponse = null;";
2511
2836
  const mdxComponentsPath = typeof config.mdx?.components === "string" ? path3.isAbsolute(config.mdx.components) ? config.mdx.components : path3.join(config.root, config.mdx.components) : null;
2512
2837
  const mdxComponentsImport = mdxComponentsPath ? `import * as FarmMdxComponentsModule from "${mdxComponentsPath.replace(/\\/g, "/")}";` : "";
@@ -2583,6 +2908,7 @@ async function handleAPIRequest(request) {
2583
2908
  ${apiImports.join("\n")}
2584
2909
  ${pageImports.join("\n")}
2585
2910
  ${layoutImports.join("\n")}
2911
+ ${routeSlotImports.join("\n")}
2586
2912
  ${errorImports.join("\n")}
2587
2913
  ${metadataImageImports.join("\n")}
2588
2914
  ${middlewareImports.join("\n")}
@@ -2599,6 +2925,7 @@ ${mdxComponentsImport}
2599
2925
  ${integrationImports}
2600
2926
  ${imageRuntimeImport}
2601
2927
  ${imageNodeRuntimeImport}
2928
+ import { farmFontPreloadHeader } from "virtual:farm-font-runtime";
2602
2929
  import * as React from "react";
2603
2930
  import * as ReactDOMServer from "react-dom/server";
2604
2931
 
@@ -2660,6 +2987,7 @@ const farmObservabilityConfig = farmUserConfig?.observability ?? ${JSON.stringif
2660
2987
  config.observability ?? false
2661
2988
  )};
2662
2989
  configureFarmObservability(farmObservabilityConfig);
2990
+ configureFarmCache(farmResolvedRuntimeConfig.cache);
2663
2991
  const farmI18nConfig = ${JSON.stringify(config.i18n)};
2664
2992
  const farmI18nRuntime = ${config.i18n.enabled ? `createFarmI18nRuntime(farmI18nConfig, ${JSON.stringify(i18nCatalogs)})` : "null"};
2665
2993
  ${config.i18n.enabled ? "_setDefaultFarmI18nRuntime(farmI18nRuntime);" : ""}
@@ -2717,6 +3045,9 @@ for (const route of pageRoutes) {
2717
3045
  const layoutRoutes = [${layoutRegistrations.join(",")}
2718
3046
  ];
2719
3047
 
3048
+ const routeSlots = [${routeSlotRegistrations.join(",")}
3049
+ ];
3050
+
2720
3051
  // Route-level error boundaries bundled at build time.
2721
3052
  const errorRoutes = [${errorRegistrations.join(",")}
2722
3053
  ];
@@ -2751,18 +3082,23 @@ function serializeFarmInlineValue(value) {
2751
3082
  .replace(/\\u2029/g, "\\\\u2029");
2752
3083
  }
2753
3084
 
2754
- function renderFarmClientBootstrapScript(canonicalPath) {
3085
+ function renderFarmClientBootstrapScript(canonicalPath, selectedRouteSlots, pageProps) {
2755
3086
  const integrationManifest = ${hasRuntimeIntegrationConfig ? "getRegisteredIntegrationAPIManifest()" : "{}"};
2756
- let source = 'window.__FARM_INTEGRATION_API_MANIFEST__=' +
3087
+ const serializedRouteSlots = serializeFarmInlineValue(selectedRouteSlots || []);
3088
+ const serializedPageProps = serializeFarmInlineValue(pageProps || {});
3089
+ let source = 'window.__FARM_PROPS__=' + serializedPageProps +
3090
+ ';window.__FARM_INTEGRATION_API_MANIFEST__=' +
2757
3091
  serializeFarmInlineValue(integrationManifest) +
2758
- ';';
3092
+ ';window.__FARM_ROUTE_SLOTS__=' + serializedRouteSlots + ';';
2759
3093
  if (typeof canonicalPath === "string" && canonicalPath.startsWith("/")) {
2760
3094
  const serializedPath = serializeFarmInlineValue(canonicalPath);
2761
3095
  source += 'if(location.pathname+location.search!==' + serializedPath + '){' +
2762
3096
  'history.replaceState(Object.assign({},history.state||{},{path:' + serializedPath + '}),"",' +
2763
3097
  serializedPath + ');}';
2764
3098
  }
2765
- return '<script>' + source + '</script>';
3099
+ return '<script id="__farm_route_slots_data__" type="application/json">' +
3100
+ serializedRouteSlots +
3101
+ '</script><script>' + source + '</script>';
2766
3102
  }
2767
3103
 
2768
3104
  function escapeFarmHtmlAttribute(value) {
@@ -3447,9 +3783,14 @@ function applyConfiguredResponseHeaders(response, pathname) {
3447
3783
  for (const headerRoute of configuredHeaderRoutes) {
3448
3784
  if (!matchRuntimePathPattern(headerRoute.source, pathname)) continue;
3449
3785
  for (const header of headerRoute.headers) {
3450
- if ((headers || response.headers).get(header.key) === header.value) continue;
3786
+ const currentValue = (headers || response.headers).get(header.key);
3787
+ if (currentValue === header.value) continue;
3451
3788
  if (!headers) headers = new Headers(response.headers);
3452
- headers.set(header.key, header.value);
3789
+ if (header.key.toLowerCase() === "link") {
3790
+ appendFarmLinkHeader(headers, header.value);
3791
+ } else {
3792
+ headers.set(header.key, header.value);
3793
+ }
3453
3794
  }
3454
3795
  }
3455
3796
 
@@ -3512,6 +3853,79 @@ function matchPageRoute(pathname) {
3512
3853
  return null;
3513
3854
  }
3514
3855
 
3856
+ function matchesRoutePrefix(pathname, pattern) {
3857
+ if (pattern === "/") return true;
3858
+ const pathSegments = normalizeRuntimePath(pathname).split("/").filter(Boolean);
3859
+ const patternSegments = normalizeRuntimePath(pattern).split("/").filter(Boolean);
3860
+ if (patternSegments.length > pathSegments.length) return false;
3861
+ const candidate = "/" + pathSegments.slice(0, patternSegments.length).join("/");
3862
+ return matchRuntimePathPattern(pattern, candidate) !== null;
3863
+ }
3864
+
3865
+ function routeSlotSpecificity(slot) {
3866
+ return slot.pattern.split("/").reduce(function(score, segment) {
3867
+ if (!segment) return score;
3868
+ if (segment.startsWith("[[...")) return score + 1;
3869
+ if (segment.startsWith("[...")) return score + 2;
3870
+ if (segment.startsWith("[")) return score + 3;
3871
+ return score + 10;
3872
+ }, 0);
3873
+ }
3874
+
3875
+ function matchRouteSlots(pathname, interceptFrom) {
3876
+ const groups = new Map();
3877
+ for (const slot of routeSlots) {
3878
+ if (!matchesRoutePrefix(pathname, slot.ownerPattern)) continue;
3879
+ const key = slot.ownerPattern + ":" + slot.name;
3880
+ const entries = groups.get(key) || [];
3881
+ entries.push(slot);
3882
+ groups.set(key, entries);
3883
+ }
3884
+
3885
+ const normalizedFrom =
3886
+ typeof interceptFrom === "string" && interceptFrom.startsWith("/")
3887
+ ? new URL(interceptFrom, "http://farm.local").pathname
3888
+ : null;
3889
+ const matches = [];
3890
+
3891
+ for (const entries of groups.values()) {
3892
+ const candidates = entries
3893
+ .filter(function(entry) { return !entry.fallback; })
3894
+ .filter(function(entry) {
3895
+ return !entry.interception ||
3896
+ (normalizedFrom && matchesRoutePrefix(normalizedFrom, entry.ownerPattern));
3897
+ })
3898
+ .map(function(entry) {
3899
+ return {
3900
+ entry: entry,
3901
+ params: matchRuntimePathPattern(entry.pattern, pathname),
3902
+ };
3903
+ })
3904
+ .filter(function(candidate) { return candidate.params !== null; })
3905
+ .sort(function(left, right) {
3906
+ if (left.entry.interception !== right.entry.interception) {
3907
+ return left.entry.interception ? -1 : 1;
3908
+ }
3909
+ return routeSlotSpecificity(right.entry) - routeSlotSpecificity(left.entry);
3910
+ });
3911
+
3912
+ if (candidates[0]) {
3913
+ matches.push({ ...candidates[0].entry, params: candidates[0].params });
3914
+ continue;
3915
+ }
3916
+
3917
+ const fallback = entries.find(function(entry) { return entry.fallback; });
3918
+ if (fallback) matches.push({ ...fallback, params: {} });
3919
+ }
3920
+
3921
+ return matches.sort(function(left, right) {
3922
+ const ownerDepth =
3923
+ left.ownerPattern.split("/").filter(Boolean).length -
3924
+ right.ownerPattern.split("/").filter(Boolean).length;
3925
+ return ownerDepth || left.name.localeCompare(right.name);
3926
+ });
3927
+ }
3928
+
3515
3929
  function hasLocalRequestRoute(request, routePathname) {
3516
3930
  const pathname = new URL(request.url).pathname;
3517
3931
  if (matchLocalAPIRequest(request) || matchLocalIntegrationRequest(request)) {
@@ -3662,6 +4076,7 @@ function getPPRShellBypassReason(request, middlewareData, middlewareContext) {
3662
4076
  if (method !== "GET" && method !== "HEAD") return "method";
3663
4077
  if (request.headers.get("cookie")) return "cookie";
3664
4078
  if (request.headers.get("authorization")) return "authorization";
4079
+ if (request.headers.get("x-farm-intercept-from")) return "route-interception";
3665
4080
  if (request.headers.get("x-farm-ppr-refresh")) return "refresh";
3666
4081
  if (hasConfiguredRouteContext) return "route-context";
3667
4082
  if (middlewareData?.size) return "middleware-data";
@@ -3715,8 +4130,8 @@ function getRouteSharedCacheControl(routeModule, pprCanCache) {
3715
4130
  return "public, s-maxage=" + revalidate + ", stale-while-revalidate=300";
3716
4131
  }
3717
4132
 
3718
- function getCachedPPRShell(cacheKey) {
3719
- const entry = pprShellCache.getEntry(cacheKey);
4133
+ async function getCachedPPRShell(cacheKey) {
4134
+ const entry = await pprShellCache.getEntryAsync(cacheKey);
3720
4135
  if (!entry) {
3721
4136
  return null;
3722
4137
  }
@@ -3728,7 +4143,7 @@ function getCachedPPRShell(cacheKey) {
3728
4143
  * Main request handler - created at runtime with bundled routes
3729
4144
  */
3730
4145
  async function handleFarmRequest(request) {
3731
- ${config.i18n.enabled ? `return _runWithFarmI18nRequest(
4146
+ const response = await ${config.i18n.enabled ? `_runWithFarmI18nRequest(
3732
4147
  farmI18nRuntime,
3733
4148
  request,
3734
4149
  async function(farmLocaleResolution) {
@@ -3747,7 +4162,15 @@ async function handleFarmRequest(request) {
3747
4162
  const response = await handleFarmRequestInContext(request, farmLocaleResolution);
3748
4163
  return applyFarmI18nResponse(response, farmLocaleResolution);
3749
4164
  }
3750
- );` : "return handleFarmRequestInContext(request, null);"}
4165
+ )` : "handleFarmRequestInContext(request, null)"};
4166
+ ${config.md?.enabled ? `const pathname = getFarmRoutePathname(new URL(request.url).pathname);
4167
+ if (matchPageRoute(pathname)) {
4168
+ return applyMarkdownNegotiationHeaders(response, {
4169
+ config: farmMarkdownConfig,
4170
+ pathname,
4171
+ });
4172
+ }` : ""}
4173
+ return response;
3751
4174
  }
3752
4175
 
3753
4176
  async function handleFarmRequestInContext(
@@ -3931,7 +4354,7 @@ async function handleFarmRequestInContext(
3931
4354
  }
3932
4355
  }
3933
4356
  if (pprCacheKey) {
3934
- const cachedPPRShell = getCachedPPRShell(pprCacheKey);
4357
+ const cachedPPRShell = await getCachedPPRShell(pprCacheKey);
3935
4358
  if (cachedPPRShell) {
3936
4359
  emitFarmEvent({ type: "ppr.shell.hit", route: pathname, key: pprCacheKey });
3937
4360
  emitFarmEvent({
@@ -3945,6 +4368,7 @@ async function handleFarmRequestInContext(
3945
4368
  status: 200,
3946
4369
  headers: {
3947
4370
  "Content-Type": "text/html; charset=utf-8",
4371
+ ...(farmFontPreloadHeader ? { "Link": farmFontPreloadHeader } : {}),
3948
4372
  ...getPPRHeaders("hit", pprConfig),
3949
4373
  },
3950
4374
  }), middlewareHeaders);
@@ -3959,6 +4383,10 @@ async function handleFarmRequestInContext(
3959
4383
 
3960
4384
  // Get applicable layouts for this page
3961
4385
  const applicableLayouts = getApplicableLayouts(routePathname);
4386
+ const selectedRouteSlots = matchRouteSlots(
4387
+ routePathname,
4388
+ request.headers.get("x-farm-intercept-from"),
4389
+ );
3962
4390
 
3963
4391
  if (PageComponent) {
3964
4392
  // Parse search params - make it a resolved Promise for async components
@@ -4046,6 +4474,100 @@ async function handleFarmRequestInContext(
4046
4474
  throw routeStateError;
4047
4475
  }
4048
4476
  }
4477
+
4478
+ const renderedRouteSlots = await Promise.all(
4479
+ selectedRouteSlots.map(async function(slot) {
4480
+ const slotContext = hasConfiguredRouteContext
4481
+ ? await resolveFarmRouteContext(farmResolvedRuntimeConfig, {
4482
+ request,
4483
+ params: slot.params,
4484
+ search: searchParamsObj,
4485
+ path: pathname,
4486
+ })
4487
+ : undefined;
4488
+ const rawSlotProps = withFarmRouteContext(
4489
+ {
4490
+ params: slot.params,
4491
+ searchParams: Promise.resolve(searchParamsObj),
4492
+ path: pathname,
4493
+ ...(middlewareData?.size ? { middleware: { data: middlewareData } } : {}),
4494
+ },
4495
+ slotContext,
4496
+ );
4497
+ if (slot.module.__farmResolveRouteProps && slotContext !== undefined) {
4498
+ Object.defineProperty(rawSlotProps, "context", {
4499
+ value: slotContext,
4500
+ enumerable: true,
4501
+ configurable: true,
4502
+ });
4503
+ }
4504
+
4505
+ const slotSchemas = slot.module.__farmRouteParsesProps
4506
+ ? {}
4507
+ : slot.module.__farmRouteSchemas || {};
4508
+ let slotProps = slot.module.__farmResolveRouteProps
4509
+ ? await slot.module.__farmResolveRouteProps(rawSlotProps)
4510
+ : {
4511
+ ...rawSlotProps,
4512
+ params: slotSchemas.params?.parse
4513
+ ? slotSchemas.params.parse(slot.params)
4514
+ : slot.params,
4515
+ search: slotSchemas.search?.parse
4516
+ ? slotSchemas.search.parse(searchParamsObj)
4517
+ : searchParamsObj,
4518
+ searchParams: Promise.resolve(
4519
+ slotSchemas.search?.parse
4520
+ ? slotSchemas.search.parse(searchParamsObj)
4521
+ : searchParamsObj,
4522
+ ),
4523
+ };
4524
+ if (
4525
+ slot.module.__farmResolveRouteProps &&
4526
+ slotContext !== undefined &&
4527
+ slotProps.context === slotContext
4528
+ ) {
4529
+ const { context: _slotContext, ...renderSlotProps } = slotProps;
4530
+ slotProps = renderSlotProps;
4531
+ }
4532
+
4533
+ return { ...slot, props: slotProps };
4534
+ }),
4535
+ );
4536
+ const clientMiddleware = middlewareData?.size
4537
+ ? { data: Object.fromEntries(middlewareData) }
4538
+ : undefined;
4539
+ const clientPageProps = {
4540
+ params: pageProps.params,
4541
+ search: pageProps.search ?? searchParamsObj,
4542
+ searchParams: pageProps.search ?? searchParamsObj,
4543
+ ...("data" in pageProps ? { data: pageProps.data } : {}),
4544
+ ...(pageProps.__farmCanonicalPath
4545
+ ? { __farmCanonicalPath: pageProps.__farmCanonicalPath }
4546
+ : {}),
4547
+ ...(pageProps.__farmRoutePropsResolved
4548
+ ? { __farmRoutePropsResolved: true }
4549
+ : {}),
4550
+ path: pathname,
4551
+ ...(clientMiddleware ? { middleware: clientMiddleware } : {}),
4552
+ };
4553
+ const routeSlotPayload = renderedRouteSlots.map(function(slot) {
4554
+ return {
4555
+ name: slot.name,
4556
+ ownerPattern: slot.ownerPattern,
4557
+ pattern: slot.pattern,
4558
+ containerId: slot.containerId,
4559
+ interception: slot.interception,
4560
+ fallback: slot.fallback,
4561
+ props: {
4562
+ params: slot.props.params,
4563
+ search: slot.props.search || searchParamsObj,
4564
+ searchParams: slot.props.search || searchParamsObj,
4565
+ ...("data" in slot.props ? { data: slot.props.data } : {}),
4566
+ path: pathname,
4567
+ ...(clientMiddleware ? { middleware: clientMiddleware } : {}),
4568
+ },
4569
+ };
4570
+ });
4049
4571
 
4050
4572
  const renderPageElement = async () => {
4051
4573
  // First, render the page content
@@ -4073,6 +4595,14 @@ async function handleFarmRequestInContext(
4073
4595
  pageElement = React.createElement(PageComponent, pageProps);
4074
4596
  }
4075
4597
 
4598
+ if (route.shouldHydrate && renderedRouteSlots.length > 0) {
4599
+ pageElement = React.createElement(
4600
+ "div",
4601
+ { id: "__farm_page__", "data-farm-client": "true" },
4602
+ pageElement,
4603
+ );
4604
+ }
4605
+
4076
4606
  // Wrap with layouts (from innermost to outermost)
4077
4607
  // Layouts are sorted by depth (root first), so we process in reverse
4078
4608
  let wrappedElement = pageElement;
@@ -4080,9 +4610,23 @@ async function handleFarmRequestInContext(
4080
4610
  const layout = applicableLayouts[i];
4081
4611
  const LayoutComponent = layout.module.default;
4082
4612
  if (LayoutComponent) {
4613
+ const slotProps = {};
4614
+ for (const slot of renderedRouteSlots) {
4615
+ if (slot.ownerPattern !== layout.pattern) continue;
4616
+ slotProps[slot.name] = React.createElement(
4617
+ "div",
4618
+ {
4619
+ id: slot.containerId,
4620
+ "data-farm-route-slot": slot.name,
4621
+ "data-farm-slot-owner": slot.ownerPattern,
4622
+ },
4623
+ React.createElement(slot.module.default, slot.props),
4624
+ );
4625
+ }
4083
4626
  wrappedElement = React.createElement(LayoutComponent, {
4084
4627
  children: wrappedElement,
4085
4628
  params,
4629
+ ...slotProps,
4086
4630
  });
4087
4631
  }
4088
4632
  }
@@ -4134,6 +4678,7 @@ async function handleFarmRequestInContext(
4134
4678
  );
4135
4679
  const hasRequestScopedRender = Boolean(
4136
4680
  pageStatus >= 400 ||
4681
+ request.headers.get("x-farm-intercept-from") ||
4137
4682
  hasPrivateRequestHeaders ||
4138
4683
  hasConfiguredRouteContext ||
4139
4684
  middlewareData?.size ||
@@ -4145,6 +4690,7 @@ async function handleFarmRequestInContext(
4145
4690
  "Cache-Control": renderedPage.stream || hasRequestScopedRender || !sharedCacheControl
4146
4691
  ? "private, no-store"
4147
4692
  : sharedCacheControl,
4693
+ ...(farmFontPreloadHeader ? { "Link": farmFontPreloadHeader } : {}),
4148
4694
  ...(pprConfig.enabled ? getPPRHeaders(pprCanCache ? "miss" : "bypass", pprConfig) : {}),
4149
4695
  };
4150
4696
  const farmI18nSnapshot = getFarmI18nSnapshot();
@@ -4173,7 +4719,11 @@ async function handleFarmRequestInContext(
4173
4719
  ' <link rel="modulepreload" href="/farm-client.js">\\n' +
4174
4720
  '</head>\\n<body>\\n <div id="root">';
4175
4721
  const streamSuffix = '</div>\\n' +
4176
- ' ' + renderFarmClientBootstrapScript(pageProps.__farmCanonicalPath) + '\\n' +
4722
+ ' ' + renderFarmClientBootstrapScript(
4723
+ pageProps.__farmCanonicalPath,
4724
+ routeSlotPayload,
4725
+ clientPageProps
4726
+ ) + '\\n' +
4177
4727
  ' <script type="module" src="/farm-client.js"></script>\\n' +
4178
4728
  '</body>\\n</html>';
4179
4729
  const streamedDocument = createFarmDocumentStream(
@@ -4230,7 +4780,11 @@ async function handleFarmRequestInContext(
4230
4780
  // Inject client script before closing body tag
4231
4781
  .replace(
4232
4782
  /<\\/body>/i,
4233
- ' ' + renderFarmClientBootstrapScript(pageProps.__farmCanonicalPath) + '\\n' +
4783
+ ' ' + renderFarmClientBootstrapScript(
4784
+ pageProps.__farmCanonicalPath,
4785
+ routeSlotPayload,
4786
+ clientPageProps
4787
+ ) + '\\n' +
4234
4788
  ' <script type="module" src="/farm-client.js"></script>\\n</body>',
4235
4789
  );
4236
4790
 
@@ -4251,7 +4805,7 @@ async function handleFarmRequestInContext(
4251
4805
  </head>
4252
4806
  <body>
4253
4807
  <div id="root">\${html}</div>
4254
- \${renderFarmClientBootstrapScript(pageProps.__farmCanonicalPath)}
4808
+ \${renderFarmClientBootstrapScript(pageProps.__farmCanonicalPath, routeSlotPayload, clientPageProps)}
4255
4809
  <script type="module" src="/farm-client.js"></script>
4256
4810
  </body>
4257
4811
  </html>\`;
@@ -4259,7 +4813,7 @@ async function handleFarmRequestInContext(
4259
4813
  fullHtml = applyFarmI18nDocument(fullHtml, pathname, farmI18nSnapshot);
4260
4814
 
4261
4815
  if (pageStatus === 200 && pprCacheKey && request.method.toUpperCase() !== "HEAD") {
4262
- pprShellCache.set(
4816
+ await pprShellCache.setAsync(
4263
4817
  pprCacheKey,
4264
4818
  { html: fullHtml },
4265
4819
  {
@@ -4876,9 +5430,8 @@ async function buildNitroUniversal(config, routeManager, apiRouteManager, server
4876
5430
  const nitroEntryPath = path3.join(ssrOutputDir, "nitro-entry.mjs");
4877
5431
  const nitroEntryCode = `
4878
5432
  // Farm.js Nitro Entry
4879
- // This file imports h3 and the SSR handler, wrapping it for Nitro
5433
+ // This file adapts Farm's Web fetch handler to Nitro's event handler contract.
4880
5434
 
4881
- import { defineEventHandler } from 'h3'
4882
5435
  import handler from './${ssrEntryFile}'
4883
5436
 
4884
5437
  function mergeVaryHeaders(target, source) {
@@ -4916,8 +5469,8 @@ function createResponseFinishedHook(event) {
4916
5469
  }
4917
5470
  }
4918
5471
 
4919
- // Export the wrapped handler for Nitro
4920
- export default defineEventHandler(async (event) => {
5472
+ // Export the event handler for Nitro
5473
+ export default async function farmNitroEventHandler(event) {
4921
5474
  const response = await handler.fetch(event.req, {
4922
5475
  waitUntil: (promise) => event.waitUntil(promise),
4923
5476
  onResponseFinished: createResponseFinishedHook(event),
@@ -4928,7 +5481,7 @@ export default defineEventHandler(async (event) => {
4928
5481
  const farmVary = response.headers.get('Vary')
4929
5482
  if (farmVary) mergeVaryHeaders(event.res.headers, farmVary)
4930
5483
  return response
4931
- })
5484
+ }
4932
5485
  `.trim();
4933
5486
  await fs.writeFile(nitroEntryPath, nitroEntryCode);
4934
5487
  const prebuiltSSRPlugin = createExternalSSRBundlePlugin(
@@ -5346,8 +5899,8 @@ async function copySharpRuntime(config, root, nitroFuncDir, fs) {
5346
5899
  await fs.mkdir(path3.dirname(targetDir), { recursive: true });
5347
5900
  const packageRequire = createRequire(packageJsonPath);
5348
5901
  const dependencies = {
5349
- ...packageJson.dependencies || {},
5350
- ...packageJson.optionalDependencies || {}
5902
+ ...packageJson.dependencies,
5903
+ ...packageJson.optionalDependencies
5351
5904
  };
5352
5905
  await Promise.all([
5353
5906
  fs.cp(packageDir, targetDir, {
@@ -5571,7 +6124,14 @@ async function createProjectModuleServer(createViteServer, config, root) {
5571
6124
  plugins: []
5572
6125
  }
5573
6126
  },
5574
- plugins: [farmEnvironmentFunctionsPlugin()],
6127
+ plugins: [
6128
+ farmFontImportsPlugin({
6129
+ root,
6130
+ basePath: config.basePath,
6131
+ publicDir: config.publicDir
6132
+ }),
6133
+ farmEnvironmentFunctionsPlugin()
6134
+ ],
5575
6135
  server: {
5576
6136
  middlewareMode: true,
5577
6137
  hmr: false
@@ -5667,7 +6227,7 @@ async function buildSSR(viteBuild, config, root, srcDir, outputDir) {
5667
6227
  __name(buildSSR, "buildSSR");
5668
6228
  async function buildNitro(config, routeManager, apiRouteManager, serverRenderer, preset, root, distDir, pluginManager) {
5669
6229
  const [{ createNitroConfig }, { createNitro, build: nitroBuild }] = await Promise.all([
5670
- import("./nitro-KME62MWG.mjs"),
6230
+ import("./nitro-QO5LV6QK.mjs"),
5671
6231
  import("nitro")
5672
6232
  ]);
5673
6233
  let nitroConfig = await createNitroConfig(
@@ -5760,4 +6320,4 @@ __name(buildNitro, "buildNitro");
5760
6320
  export {
5761
6321
  build
5762
6322
  };
5763
- //# sourceMappingURL=chunk-G3B5BRDY.mjs.map
6323
+ //# sourceMappingURL=chunk-4677KXB7.mjs.map