@farm.js/core 0.1.51-beta.3 → 0.1.60

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 (320) hide show
  1. package/dist/{agent-mcp-handler-7JSKGSOW.mjs → agent-mcp-handler-7QMX2LUY.mjs} +7 -7
  2. package/dist/agent-mcp-handler-OV4WRFBL.cjs +18 -0
  3. package/dist/{agent-mcp.d-BJKChOrO.d.mts → agent-mcp.d-C-2S9bnP.d.mts} +1 -1
  4. package/dist/{agent-mcp.d-BAR9njbJ.d.ts → agent-mcp.d-SIoCUP1I.d.ts} +1 -1
  5. package/dist/agent-runtime.cjs +5 -5
  6. package/dist/agent-runtime.d.mts +2 -2
  7. package/dist/agent-runtime.d.ts +2 -2
  8. package/dist/agent-runtime.mjs +4 -4
  9. package/dist/{analyzer-OTPEWH5W.mjs → analyzer-22BEYV7S.mjs} +116 -13
  10. package/dist/{analyzer-TSQXZCZN.cjs → analyzer-LCSI3NSH.cjs} +123 -20
  11. package/dist/api/client.cjs +5 -4
  12. package/dist/api/client.d.mts +1 -1
  13. package/dist/api/client.d.ts +1 -1
  14. package/dist/api/client.mjs +3 -2
  15. package/dist/api/client.native.cjs +45 -0
  16. package/dist/api/client.native.d.mts +23 -0
  17. package/dist/api/client.native.d.ts +23 -0
  18. package/dist/api/client.native.mjs +45 -0
  19. package/dist/api/route-manager.cjs +7 -7
  20. package/dist/api/route-manager.d.mts +4 -4
  21. package/dist/api/route-manager.d.ts +4 -4
  22. package/dist/api/route-manager.mjs +6 -6
  23. package/dist/api/runtime.cjs +5 -5
  24. package/dist/api/runtime.d.mts +3 -3
  25. package/dist/api/runtime.d.ts +3 -3
  26. package/dist/api/runtime.mjs +4 -4
  27. package/dist/{api-client.d-CeA6tNA6.d.mts → api-client.d-BNLXNCXJ.d.mts} +1 -1
  28. package/dist/{api-client.d-BWcqZciH.d.ts → api-client.d-ddQBNGtu.d.ts} +1 -1
  29. package/dist/api.cjs +11 -11
  30. package/dist/api.d.mts +5 -5
  31. package/dist/api.d.ts +5 -5
  32. package/dist/api.mjs +10 -10
  33. package/dist/{app-manifest.d-DEQNnNhV.d.mts → app-manifest.d-DrSAHskY.d.mts} +1 -1
  34. package/dist/{app-manifest.d-BLFbaqx8.d.ts → app-manifest.d-Tb3CJpL4.d.ts} +1 -1
  35. package/dist/app-markdown.cjs +7 -7
  36. package/dist/app-markdown.d.mts +3 -3
  37. package/dist/app-markdown.d.ts +3 -3
  38. package/dist/app-markdown.mjs +6 -6
  39. package/dist/{app.d-CNPaUYaa.d.ts → app.d-CmWlYpZJ.d.ts} +9 -4
  40. package/dist/{app.d-CT7xDkj2.d.mts → app.d-D6QQM_kk.d.mts} +9 -4
  41. package/dist/{chunk-SN5VSO3Q.mjs → chunk-25T5VXOE.mjs} +7 -9
  42. package/dist/{chunk-OAMUSC7H.cjs → chunk-2FRLSDBT.cjs} +1 -1
  43. package/dist/{chunk-LM2YOGDK.mjs → chunk-2I6PUKWJ.mjs} +1 -1
  44. package/dist/{chunk-ZD2VKAUI.mjs → chunk-2KTYMMWT.mjs} +1 -1
  45. package/dist/{chunk-B5BBTPJQ.cjs → chunk-2OF5RPVU.cjs} +14 -14
  46. package/dist/{chunk-UQF3OJVE.mjs → chunk-37PYUEK5.mjs} +173 -29
  47. package/dist/{chunk-VSLM6BHX.cjs → chunk-3OJNNCDL.cjs} +9 -9
  48. package/dist/{chunk-X3JNB2TB.mjs → chunk-3PX4AIXO.mjs} +36 -5
  49. package/dist/{chunk-UQHIWZZ6.cjs → chunk-3TL3AH25.cjs} +12 -6
  50. package/dist/chunk-3YMLUNL2.cjs +251 -0
  51. package/dist/chunk-4JTQPOKO.cjs +137 -0
  52. package/dist/{chunk-7MD37P5V.cjs → chunk-4P23B7DU.cjs} +5 -5
  53. package/dist/{chunk-3BLEXUGE.mjs → chunk-55U5QIXQ.mjs} +1 -1
  54. package/dist/{chunk-TWHXBMLJ.cjs → chunk-5JNUYGNF.cjs} +4 -4
  55. package/dist/{chunk-53SACYBY.cjs → chunk-6BJJYOFL.cjs} +7 -7
  56. package/dist/chunk-6UUH4N4J.mjs +251 -0
  57. package/dist/{chunk-2NHOYYUT.mjs → chunk-7H45IJWO.mjs} +2 -2
  58. package/dist/{chunk-NN3MOPSI.mjs → chunk-A2MN5PQJ.mjs} +7 -7
  59. package/dist/{chunk-KY32FWK7.mjs → chunk-BHJAYPYU.mjs} +2 -2
  60. package/dist/{chunk-VAHBCI6X.mjs → chunk-BQWBHWEW.mjs} +26 -1
  61. package/dist/{chunk-KJMWAUKE.mjs → chunk-C7GJDVN4.mjs} +1 -1
  62. package/dist/{chunk-OYNNA4DD.cjs → chunk-CBKRS3M4.cjs} +9 -9
  63. package/dist/{chunk-I2DQGS56.cjs → chunk-CBOEJ5Z4.cjs} +39 -41
  64. package/dist/{chunk-UJL4JOXV.cjs → chunk-CI4UNQHO.cjs} +2 -2
  65. package/dist/{chunk-S5AQ7CAC.cjs → chunk-CNNBFGL5.cjs} +39 -14
  66. package/dist/chunk-D2X5MUF5.cjs +1457 -0
  67. package/dist/{chunk-LEIXUFJN.cjs → chunk-D4MRNBVF.cjs} +10 -9
  68. package/dist/{chunk-2KVDHNQS.mjs → chunk-D7LTCK3U.mjs} +2 -2
  69. package/dist/{chunk-4SEHMBL4.cjs → chunk-DPJ66FSI.cjs} +22 -22
  70. package/dist/{chunk-FFE2EMF7.cjs → chunk-DZPR2W6U.cjs} +5 -5
  71. package/dist/{chunk-3Z63X45F.mjs → chunk-E72UD6ME.mjs} +1 -1
  72. package/dist/{chunk-XXXRRVY6.mjs → chunk-EGVC4LIG.mjs} +5 -5
  73. package/dist/{chunk-72NBDVWQ.mjs → chunk-EXUONJYV.mjs} +3 -3
  74. package/dist/{chunk-VS7EHLLW.mjs → chunk-EZ34EHQP.mjs} +1 -1
  75. package/dist/{chunk-5FXPJIOT.mjs → chunk-F6Y7ZAPQ.mjs} +2 -2
  76. package/dist/{chunk-LMFJCXDD.mjs → chunk-FN5UEC7I.mjs} +1 -1
  77. package/dist/{chunk-3SMXQNFD.mjs → chunk-FORSVMEJ.mjs} +2 -2
  78. package/dist/{chunk-R4PHCZ3G.mjs → chunk-HPWB57PZ.mjs} +1 -1
  79. package/dist/{chunk-Y2G5SJFB.mjs → chunk-IFHPDLIS.mjs} +1 -1
  80. package/dist/{chunk-3XQ57EFI.cjs → chunk-IFXSBJPN.cjs} +16 -16
  81. package/dist/{chunk-3WSIYBMG.mjs → chunk-ILMTRGBG.mjs} +279 -48
  82. package/dist/{chunk-HLWOWZFX.cjs → chunk-JBK7UJOI.cjs} +14 -11
  83. package/dist/chunk-JI5D7MXY.mjs +137 -0
  84. package/dist/{chunk-QXJADAQB.cjs → chunk-JIBEFLQ7.cjs} +6 -2
  85. package/dist/{chunk-LZ4SB57H.mjs → chunk-JPIUGDK4.mjs} +1 -1
  86. package/dist/{chunk-Y3N5BFRJ.mjs → chunk-JSDV2NUN.mjs} +1 -1
  87. package/dist/{chunk-IRSS4HS4.mjs → chunk-K3RU5MOR.mjs} +1 -1
  88. package/dist/chunk-KPOMS5RO.cjs +237 -0
  89. package/dist/{chunk-YAJTD3ZG.mjs → chunk-KVW2M6PI.mjs} +1 -1
  90. package/dist/{chunk-5IONBVJY.cjs → chunk-LB3DPQP6.cjs} +22 -22
  91. package/dist/{chunk-CZ35L6PL.mjs → chunk-LJVNMGE3.mjs} +10 -4
  92. package/dist/{chunk-X2AMN2WV.cjs → chunk-LQNW3ABP.cjs} +10 -10
  93. package/dist/{chunk-6ONBZGVH.cjs → chunk-LRB5OVRT.cjs} +3 -3
  94. package/dist/{chunk-D7UQC4O6.cjs → chunk-LT4VAF5Z.cjs} +2 -2
  95. package/dist/{chunk-F6TLUMH7.mjs → chunk-M53MIIXY.mjs} +1 -1
  96. package/dist/{chunk-H33PJEXN.cjs → chunk-MEQN6DDA.cjs} +5 -5
  97. package/dist/{chunk-XLRLSTJ6.cjs → chunk-MGKW5XZE.cjs} +7 -7
  98. package/dist/{chunk-B3GZAQSC.cjs → chunk-MHLNWRCJ.cjs} +3 -3
  99. package/dist/{chunk-5ENW27SL.mjs → chunk-MMK4MZUN.mjs} +1 -1
  100. package/dist/{chunk-WGUHDWT5.cjs → chunk-MTWXOEI4.cjs} +527 -366
  101. package/dist/chunk-NHD7BAKD.mjs +1457 -0
  102. package/dist/{chunk-KLNFJDFM.cjs → chunk-NQJDO7K7.cjs} +31 -31
  103. package/dist/{chunk-TSFMFPRU.cjs → chunk-O27PLNQZ.cjs} +10 -10
  104. package/dist/{chunk-PIHKO25G.mjs → chunk-OM7WILES.mjs} +1 -1
  105. package/dist/{chunk-YUEYBL35.mjs → chunk-PCXIJKPM.mjs} +8 -8
  106. package/dist/{chunk-IWFV5ZED.cjs → chunk-PMJSG4JS.cjs} +1 -1
  107. package/dist/{chunk-B3GM5I6N.cjs → chunk-PRFNLQSP.cjs} +4 -4
  108. package/dist/{chunk-46KXZBOG.cjs → chunk-QAS7KE7J.cjs} +7 -7
  109. package/dist/chunk-QGOZLGVP.mjs +0 -0
  110. package/dist/{chunk-VQJYGZNX.cjs → chunk-QMNWKQL4.cjs} +1 -1
  111. package/dist/{chunk-XB24LZWI.cjs → chunk-QRX4JRBO.cjs} +3 -3
  112. package/dist/{chunk-LNM57D3H.cjs → chunk-R53QDV6T.cjs} +4 -4
  113. package/dist/{chunk-SUV6YO4Q.cjs → chunk-RAWWCDCT.cjs} +5 -5
  114. package/dist/{chunk-LJDIFIJ2.mjs → chunk-RPUJHJHE.mjs} +4 -4
  115. package/dist/{chunk-G2KTRMWA.mjs → chunk-RSEAX5MW.mjs} +4 -0
  116. package/dist/chunk-SJRCWF4Z.mjs +237 -0
  117. package/dist/{chunk-4353ZRE5.mjs → chunk-SX7EECTS.mjs} +8 -5
  118. package/dist/{chunk-LDNSSHEG.mjs → chunk-T4TBK5NY.mjs} +2 -2
  119. package/dist/{chunk-NOTSHVRN.mjs → chunk-T7I62A4C.mjs} +293 -132
  120. package/dist/{chunk-E36C43IX.cjs → chunk-U4BJKNIR.cjs} +6 -6
  121. package/dist/{chunk-4CGOMZP3.cjs → chunk-UDJY2ZGY.cjs} +487 -256
  122. package/dist/{chunk-SHS6KXOZ.mjs → chunk-UR25Z5Z6.mjs} +1 -1
  123. package/dist/{chunk-TQMI6BYO.cjs → chunk-UYSTTPYJ.cjs} +1262 -936
  124. package/dist/{chunk-E5DXF5GE.mjs → chunk-UZZ6IEQP.mjs} +3 -3
  125. package/dist/{chunk-EKJYE4Y7.cjs → chunk-VGG74PSU.cjs} +25 -25
  126. package/dist/{chunk-GAO7MS5O.mjs → chunk-VPTWKOCY.mjs} +19 -19
  127. package/dist/{chunk-UN6N623E.mjs → chunk-VQJHT2ND.mjs} +2 -2
  128. package/dist/{chunk-SJ23LJ3N.cjs → chunk-VVTJTMGQ.cjs} +3 -3
  129. package/dist/{chunk-KHXAJ2KA.cjs → chunk-W2RZ73IU.cjs} +12 -12
  130. package/dist/{chunk-JWI5PUO2.mjs → chunk-W2ZXMMHA.mjs} +2 -1
  131. package/dist/{chunk-BLD5GVCG.mjs → chunk-W6QLRQ3V.mjs} +1 -1
  132. package/dist/{chunk-AV26KHTG.mjs → chunk-X2CZTWQA.mjs} +2 -2
  133. package/dist/chunk-XPIPMWY3.cjs +1 -0
  134. package/dist/{chunk-JXEPLIXD.cjs → chunk-XTG73QZA.cjs} +183 -39
  135. package/dist/{chunk-XPMC4E2G.cjs → chunk-XVSBALOY.cjs} +3 -3
  136. package/dist/{chunk-XYL4HSVC.cjs → chunk-YI6FKTTN.cjs} +38 -7
  137. package/dist/{chunk-LPDKG6RA.mjs → chunk-YSXTNSXS.mjs} +1 -1
  138. package/dist/{chunk-EHB77D5U.cjs → chunk-ZDAEHG2O.cjs} +3 -3
  139. package/dist/{chunk-3TLKUBXG.mjs → chunk-ZFUKPWFC.mjs} +912 -586
  140. package/dist/{chunk-4TKAIO2F.mjs → chunk-ZMHAFH4R.mjs} +8 -8
  141. package/dist/{chunk-ZOWNWHK6.cjs → chunk-ZNH6NR3H.cjs} +2 -2
  142. package/dist/{chunk-PFV2KPDZ.cjs → chunk-ZOYKJBP5.cjs} +3 -3
  143. package/dist/{chunk-CECUDGXQ.cjs → chunk-ZP32GNJQ.cjs} +13 -13
  144. package/dist/{chunk-MRNDAJEV.mjs → chunk-ZZ2QKCKW.mjs} +1 -1
  145. package/dist/{client-plugins.d-DllmH8eM.d.mts → client-plugins.d-CgQQ-EAv.d.mts} +10 -2
  146. package/dist/{client-plugins.d-n3iWY1EJ.d.ts → client-plugins.d-vXrbcfJ1.d.ts} +10 -2
  147. package/dist/client-plugins.d.mts +2 -2
  148. package/dist/client-plugins.d.ts +2 -2
  149. package/dist/client.cjs +9 -9
  150. package/dist/client.d.mts +9 -9
  151. package/dist/client.d.ts +9 -9
  152. package/dist/client.mjs +9 -9
  153. package/dist/{config.d-DqKaCr1r.d.ts → config.d-DqZkLwef.d.mts} +139 -1
  154. package/dist/{config.d-DqKaCr1r.d.mts → config.d-DqZkLwef.d.ts} +139 -1
  155. package/dist/config.d.mts +2 -2
  156. package/dist/config.d.ts +2 -2
  157. package/dist/cron.cjs +3 -3
  158. package/dist/cron.d.mts +10 -0
  159. package/dist/cron.d.ts +10 -0
  160. package/dist/cron.mjs +2 -2
  161. package/dist/desktop.d.mts +3 -3
  162. package/dist/desktop.d.ts +3 -3
  163. package/dist/{devtools-UESYARTF.mjs → devtools-KQZ6SRCJ.mjs} +16 -16
  164. package/dist/{devtools-TO6TAO32.cjs → devtools-UF6JYHUN.cjs} +18 -18
  165. package/dist/docs.cjs +19 -19
  166. package/dist/docs.d.mts +3 -3
  167. package/dist/docs.d.ts +3 -3
  168. package/dist/docs.mjs +18 -18
  169. package/dist/index.cjs +96 -96
  170. package/dist/{index.d-BXsAXm1U.d.ts → index.d-DlCELfhf.d.ts} +1 -1
  171. package/dist/{index.d-BL7KKiwa.d.mts → index.d-Dmfb7Kb_.d.mts} +1 -1
  172. package/dist/index.d.mts +18 -18
  173. package/dist/index.d.ts +18 -18
  174. package/dist/index.mjs +139 -139
  175. package/dist/integrations.cjs +5 -5
  176. package/dist/integrations.d.mts +2 -2
  177. package/dist/integrations.d.ts +2 -2
  178. package/dist/integrations.mjs +4 -4
  179. package/dist/internal/app-markdown-runtime.cjs +6 -6
  180. package/dist/internal/app-markdown-runtime.d.mts +3 -3
  181. package/dist/internal/app-markdown-runtime.d.ts +3 -3
  182. package/dist/internal/app-markdown-runtime.mjs +5 -5
  183. package/dist/internal/build-runtime.cjs +50 -50
  184. package/dist/internal/build-runtime.d.mts +4 -4
  185. package/dist/internal/build-runtime.d.ts +4 -4
  186. package/dist/internal/build-runtime.mjs +49 -49
  187. package/dist/internal/cli-runtime.cjs +28 -28
  188. package/dist/internal/cli-runtime.mjs +28 -28
  189. package/dist/internal/client-error-overlay.cjs +4 -4
  190. package/dist/internal/client-error-overlay.mjs +1 -1
  191. package/dist/internal/client-runtime.cjs +20 -15
  192. package/dist/internal/client-runtime.d.mts +5 -5
  193. package/dist/internal/client-runtime.d.ts +5 -5
  194. package/dist/internal/client-runtime.mjs +8 -3
  195. package/dist/internal/compression-runtime.d.mts +2 -2
  196. package/dist/internal/compression-runtime.d.ts +2 -2
  197. package/dist/internal/config-runtime.cjs +18 -18
  198. package/dist/internal/config-runtime.d.mts +94 -6
  199. package/dist/internal/config-runtime.d.ts +94 -6
  200. package/dist/internal/config-runtime.mjs +17 -17
  201. package/dist/internal/infra-analytics-runtime.cjs +11 -11
  202. package/dist/internal/infra-analytics-runtime.mjs +9 -9
  203. package/dist/internal/islands-boot.cjs +211 -0
  204. package/dist/internal/islands-boot.d.mts +8 -0
  205. package/dist/internal/islands-boot.d.ts +8 -0
  206. package/dist/internal/islands-boot.mjs +211 -0
  207. package/dist/internal/product-telemetry-runtime.cjs +2 -2
  208. package/dist/internal/product-telemetry-runtime.mjs +1 -1
  209. package/dist/internal/production-runtime.cjs +37 -101
  210. package/dist/internal/production-runtime.d.mts +17 -11
  211. package/dist/internal/production-runtime.d.ts +17 -11
  212. package/dist/internal/production-runtime.mjs +47 -111
  213. package/dist/markdown.cjs +5 -5
  214. package/dist/markdown.d.mts +2 -2
  215. package/dist/markdown.d.ts +2 -2
  216. package/dist/markdown.mjs +4 -4
  217. package/dist/middleware.cjs +10 -10
  218. package/dist/middleware.d.mts +4 -4
  219. package/dist/middleware.d.ts +4 -4
  220. package/dist/middleware.mjs +9 -9
  221. package/dist/mobile.d.mts +27 -5
  222. package/dist/mobile.d.ts +27 -5
  223. package/dist/modules-VHD7BELU.mjs +13 -0
  224. package/dist/modules-WT5D3AWY.cjs +13 -0
  225. package/dist/native-specs-BD7HOTMJ.mjs +15 -0
  226. package/dist/native-specs-IQQRJOOW.cjs +15 -0
  227. package/dist/native-tree-6G5O53O3.cjs +27 -0
  228. package/dist/{native-tree-EBPDFTRW.mjs → native-tree-VWNW2MQ2.mjs} +10 -8
  229. package/dist/native.cjs +87 -0
  230. package/dist/native.d.mts +72 -0
  231. package/dist/native.d.ts +72 -0
  232. package/dist/native.mjs +87 -0
  233. package/dist/{navigation-delegate.d-C76gXTmO.d.mts → navigation-delegate.d-CnOTWOyi.d.mts} +1 -1
  234. package/dist/{navigation-delegate.d-DIyDslxt.d.ts → navigation-delegate.d-JXx40JzR.d.ts} +1 -1
  235. package/dist/navigation.cjs +5 -5
  236. package/dist/navigation.d.mts +5 -5
  237. package/dist/navigation.d.ts +5 -5
  238. package/dist/navigation.mjs +4 -4
  239. package/dist/{nitro-R444AF3O.mjs → nitro-FLN6DRGJ.mjs} +7 -7
  240. package/dist/{nitro-CK7M4RMY.cjs → nitro-HXAZZQKY.cjs} +12 -12
  241. package/dist/plugin.cjs +42 -42
  242. package/dist/plugin.d.mts +4 -4
  243. package/dist/plugin.d.ts +4 -4
  244. package/dist/plugin.mjs +41 -41
  245. package/dist/port-C6GBH4C6.cjs +419 -0
  246. package/dist/port-WOOQ3V56.mjs +419 -0
  247. package/dist/{production-runtime.d-CDHztggO.d.mts → production-runtime.d-CP5s6RuY.d.mts} +1 -1
  248. package/dist/{production-runtime.d-tyaGdbk6.d.ts → production-runtime.d-N-cE3pmy.d.ts} +1 -1
  249. package/dist/{programmatic-routes-client.d-XfmIrCK1.d.ts → programmatic-routes-client.d-CLG2N1yH.d.ts} +2 -2
  250. package/dist/{programmatic-routes-client.d-aAWiDd64.d.mts → programmatic-routes-client.d-CPbNqtIi.d.mts} +2 -2
  251. package/dist/query/client.cjs +6 -6
  252. package/dist/query/client.mjs +2 -2
  253. package/dist/{render-plan.d-Dr5WRjoV.d.ts → render-plan.d-B9lAP3uX.d.ts} +1 -1
  254. package/dist/{render-plan.d-Diwybxo8.d.mts → render-plan.d-DZ-qjjdG.d.mts} +1 -1
  255. package/dist/renderer/react/server.cjs +2 -2
  256. package/dist/renderer/react/server.mjs +3 -3
  257. package/dist/renderer-client.cjs +6 -6
  258. package/dist/renderer-client.d.mts +5 -5
  259. package/dist/renderer-client.d.ts +5 -5
  260. package/dist/renderer-client.mjs +2 -2
  261. package/dist/{request.d-D01fRn--.d.ts → request.d-BiicaNxb.d.ts} +1 -1
  262. package/dist/{request.d-Dd3AFR79.d.mts → request.d-DV0oeUit.d.mts} +1 -1
  263. package/dist/request.d.mts +3 -3
  264. package/dist/request.d.ts +3 -3
  265. package/dist/{route-rendering.d-BQ53lJ_D.d.mts → route-rendering.d-BrIKA51A.d.mts} +1 -1
  266. package/dist/{route-rendering.d-Bhx4QoJt.d.ts → route-rendering.d-Iss0C7GR.d.ts} +1 -1
  267. package/dist/{router.d-DQ3k7EYn.d.ts → router.d-DjGn_al7.d.ts} +1 -1
  268. package/dist/{router.d-Bi23a6Xc.d.mts → router.d-mNTbOGV_.d.mts} +1 -1
  269. package/dist/{routes.d-C7jMJFvP.d.ts → routes.d-BKSjHuH9.d.ts} +25 -2
  270. package/dist/{routes.d-BgTd7vI4.d.mts → routes.d-qd8Qf4LG.d.mts} +25 -2
  271. package/dist/routes.d.mts +2 -2
  272. package/dist/routes.d.ts +2 -2
  273. package/dist/{rsc-pipeline-OCZIT5OF.cjs → rsc-pipeline-SVLBTY7H.cjs} +21 -21
  274. package/dist/{rsc-pipeline-K3ER3Q4N.mjs → rsc-pipeline-WBLBDQXA.mjs} +20 -20
  275. package/dist/{runtime-DKNSIH7V.cjs → runtime-DGUOWSMF.cjs} +293 -41
  276. package/dist/{runtime-MKYDEUZT.mjs → runtime-HFZTVNFF.mjs} +283 -31
  277. package/dist/{runtime.d-B2Js6qZ2.d.mts → runtime.d-BNVbojF1.d.mts} +1 -1
  278. package/dist/{runtime.d-BL-CGwoi.d.ts → runtime.d-Bm_4hP5T.d.ts} +1 -1
  279. package/dist/{schema-dev-notice-F6QYSOAI.mjs → schema-dev-notice-JMXEQWIQ.mjs} +3 -3
  280. package/dist/{schema-dev-notice-UU7DMZEU.cjs → schema-dev-notice-PLBFDTOF.cjs} +6 -6
  281. package/dist/server-fn-client.d.mts +1 -1
  282. package/dist/server-fn-client.d.ts +1 -1
  283. package/dist/server-plugins.cjs +1 -1
  284. package/dist/server-plugins.d.mts +3 -3
  285. package/dist/server-plugins.d.ts +3 -3
  286. package/dist/server-plugins.mjs +1 -1
  287. package/dist/server.cjs +81 -81
  288. package/dist/server.d.mts +11 -11
  289. package/dist/server.d.ts +11 -11
  290. package/dist/server.mjs +64 -64
  291. package/dist/session-2Q72D4QV.cjs +23 -0
  292. package/dist/{session-IGEDQ5PY.mjs → session-QZXZOPR2.mjs} +2 -2
  293. package/dist/shell-render.d-CG6bPiiA.d.mts +41 -0
  294. package/dist/shell-render.d-CG6bPiiA.d.ts +41 -0
  295. package/dist/{spa-router.d-DqZ6Lfs0.d.ts → spa-router.d-DAtnNoBe.d.ts} +11 -2
  296. package/dist/{spa-router.d-B2rIFGs0.d.mts → spa-router.d-DHDoXxDE.d.mts} +11 -2
  297. package/dist/testing.cjs +7 -7
  298. package/dist/testing.d.mts +2 -2
  299. package/dist/testing.d.ts +2 -2
  300. package/dist/testing.mjs +6 -6
  301. package/dist/{utils.d-Bv2MPeLR.d.ts → utils.d-DwZ-KLSB.d.ts} +7 -1
  302. package/dist/{utils.d-fqXe8lNc.d.mts → utils.d-uKZcKJk4.d.mts} +7 -1
  303. package/dist/version.cjs +2 -2
  304. package/dist/version.mjs +1 -1
  305. package/dist/vite.cjs +42 -42
  306. package/dist/vite.d.mts +10 -5
  307. package/dist/vite.d.ts +10 -5
  308. package/dist/vite.mjs +41 -41
  309. package/dist/workflows.cjs +3 -3
  310. package/dist/workflows.mjs +2 -2
  311. package/package.json +17 -3
  312. package/dist/agent-mcp-handler-YE4AGWHN.cjs +0 -18
  313. package/dist/chunk-MIGFX2FN.mjs +0 -758
  314. package/dist/chunk-P6MHI5O2.cjs +0 -758
  315. package/dist/native-tree-MMZS7S6W.cjs +0 -25
  316. package/dist/session-AAU7RNRO.cjs +0 -23
  317. package/dist/{chunk-7FVVQEVL.cjs → chunk-4BS3HSY7.cjs} +2 -2
  318. package/dist/{chunk-N7JQXQAV.cjs → chunk-5OJVKXFV.cjs} +2 -2
  319. package/dist/{chunk-WSDKXV4E.mjs → chunk-72KABRWN.mjs} +4 -4
  320. package/dist/{chunk-C3BOESDW.mjs → chunk-B4CWYGCG.mjs} +3 -3
@@ -5,7 +5,7 @@ import {
5
5
  collectSSGPages,
6
6
  matchSSGPage,
7
7
  resolveRouteRenderingConfigFromFile
8
- } from "./chunk-CZ35L6PL.mjs";
8
+ } from "./chunk-LJVNMGE3.mjs";
9
9
  import {
10
10
  classifyFarmDocumentPrefix,
11
11
  composeFarmFullDocument,
@@ -24,16 +24,21 @@ import {
24
24
  getFarmServerTreeLayoutPatterns,
25
25
  getRouteDirectoryDepth,
26
26
  getRouteGroupScope,
27
+ getSharedLayoutPrefixLength,
27
28
  isInRouteGroupScope,
28
29
  openFarmStreamedDocument,
30
+ parseFarmLayoutChainHeader,
29
31
  removeFarmDocumentTitles,
30
32
  renderFarmLocaleAlternateLinks,
31
33
  resolveDefaultErrorStatus,
32
34
  routeBoundaryCoversDirectory
33
- } from "./chunk-YUEYBL35.mjs";
35
+ } from "./chunk-PCXIJKPM.mjs";
36
+ import {
37
+ handleFarmFormActionRequest
38
+ } from "./chunk-Z5A6CNV2.mjs";
34
39
  import {
35
40
  listFarmMCPLlmsTxtLinks
36
- } from "./chunk-4TKAIO2F.mjs";
41
+ } from "./chunk-ZMHAFH4R.mjs";
37
42
  import {
38
43
  FARM_DEFAULT_MCP_PATH,
39
44
  collectFarmDefaultMCPPages,
@@ -41,7 +46,7 @@ import {
41
46
  farmConfigMountsMCP,
42
47
  isFarmDefaultMCPPathname,
43
48
  resolveFarmDefaultMCPServer
44
- } from "./chunk-E5DXF5GE.mjs";
49
+ } from "./chunk-UZZ6IEQP.mjs";
45
50
  import {
46
51
  createFarmMetadataImageResponse
47
52
  } from "./chunk-OZK2DS44.mjs";
@@ -49,9 +54,6 @@ import {
49
54
  installFarmIslandValues,
50
55
  uninstallFarmIslandValues
51
56
  } from "./chunk-A4PWGL46.mjs";
52
- import {
53
- handleFarmFormActionRequest
54
- } from "./chunk-Z5A6CNV2.mjs";
55
57
  import {
56
58
  FARM_ISLAND_REPLAYABLE_SELECTOR,
57
59
  isFarmIslandStrategy
@@ -61,17 +63,6 @@ import {
61
63
  mergeProgrammaticClientRoutes,
62
64
  resolveProgrammaticClientRoutes
63
65
  } from "./chunk-ZQ5BDNKW.mjs";
64
- import {
65
- createFarmMarkdownRouteModuleFromFile,
66
- loadFarmMdxComponents
67
- } from "./chunk-3BLEXUGE.mjs";
68
- import {
69
- isFarmMarkdownPageFile
70
- } from "./chunk-3Z63X45F.mjs";
71
- import {
72
- _setDefaultFarmThemeConfig,
73
- getTheme
74
- } from "./chunk-EMDGXYUD.mjs";
75
66
  import {
76
67
  isSecretDocsConfigKey
77
68
  } from "./chunk-EJCVG25Z.mjs";
@@ -105,14 +96,7 @@ import {
105
96
  resolveFarmAgentCrawlers,
106
97
  resolveFarmAgentSitemap,
107
98
  resolveFarmPerformanceConfig
108
- } from "./chunk-LDNSSHEG.mjs";
109
- import {
110
- collectFarmLlmsTxtPages,
111
- createFarmDefaultLlmsTxt,
112
- createFarmLlmsMarkdownReader,
113
- renderFarmLlmsFullTxt,
114
- resolveFarmLlmsTxtConfig
115
- } from "./chunk-YAJTD3ZG.mjs";
99
+ } from "./chunk-T4TBK5NY.mjs";
116
100
  import {
117
101
  createFarmCspNonce,
118
102
  createFarmCspNonceRewriter,
@@ -122,37 +106,55 @@ import {
122
106
  stampFarmCspNonce
123
107
  } from "./chunk-22W4FNTG.mjs";
124
108
  import {
125
- resolveFarmImageConfig
126
- } from "./chunk-2NGZFOKG.mjs";
109
+ collectFarmLlmsTxtPages,
110
+ createFarmDefaultLlmsTxt,
111
+ createFarmLlmsMarkdownReader,
112
+ renderFarmLlmsFullTxt,
113
+ resolveFarmLlmsTxtConfig
114
+ } from "./chunk-KVW2M6PI.mjs";
127
115
  import {
128
116
  getFarmAppDirectories,
129
117
  getFarmSourceRoots
130
118
  } from "./chunk-52Y3C3HG.mjs";
119
+ import {
120
+ resolveFarmImageConfig
121
+ } from "./chunk-2NGZFOKG.mjs";
122
+ import {
123
+ createFarmMarkdownRouteModuleFromFile,
124
+ loadFarmMdxComponents
125
+ } from "./chunk-55U5QIXQ.mjs";
126
+ import {
127
+ isFarmMarkdownPageFile
128
+ } from "./chunk-E72UD6ME.mjs";
131
129
  import {
132
130
  resolveFarmMdxComponentsModulePath,
133
131
  resolveMdxConfig
134
132
  } from "./chunk-UIJOLBUL.mjs";
133
+ import {
134
+ FARM_MARKDOWN_CONTENT_TYPE,
135
+ FARM_MARKDOWN_PAGE_CHECK_HEADER,
136
+ _isFarmMarkdownPageCheck,
137
+ createFarmMarkdownErrorBody,
138
+ farmRequestWantsMarkdown,
139
+ getFarmMarkdownAlternatePath,
140
+ resolveMarkdownConfig
141
+ } from "./chunk-YSXTNSXS.mjs";
135
142
  import {
136
143
  resolveWorkflowsConfig
137
- } from "./chunk-LZ4SB57H.mjs";
144
+ } from "./chunk-JPIUGDK4.mjs";
138
145
  import {
139
146
  resolveCronConfig
140
- } from "./chunk-X3JNB2TB.mjs";
147
+ } from "./chunk-3PX4AIXO.mjs";
141
148
  import {
142
149
  resolveServerActionsConfig
143
150
  } from "./chunk-FSQMN2MQ.mjs";
151
+ import {
152
+ _setDefaultFarmThemeConfig,
153
+ getTheme
154
+ } from "./chunk-EMDGXYUD.mjs";
144
155
  import {
145
156
  resolveFarmThemeConfig
146
157
  } from "./chunk-YWPNIYUP.mjs";
147
- import {
148
- FARM_MARKDOWN_CONTENT_TYPE,
149
- FARM_MARKDOWN_PAGE_CHECK_HEADER,
150
- _isFarmMarkdownPageCheck,
151
- createFarmMarkdownErrorBody,
152
- farmRequestWantsMarkdown,
153
- getFarmMarkdownAlternatePath,
154
- resolveMarkdownConfig
155
- } from "./chunk-LPDKG6RA.mjs";
156
158
  import {
157
159
  initStorage
158
160
  } from "./chunk-TJVUTGED.mjs";
@@ -164,11 +166,11 @@ import {
164
166
  getIntegrationProviders,
165
167
  getRegisteredIntegrationAPIManifest,
166
168
  isFarmIntegrationProviderComponentReference
167
- } from "./chunk-Y2G5SJFB.mjs";
169
+ } from "./chunk-IFHPDLIS.mjs";
168
170
  import {
169
171
  createRouteSlotContainerId,
170
172
  parseRouteSlotFile
171
- } from "./chunk-IRSS4HS4.mjs";
173
+ } from "./chunk-K3RU5MOR.mjs";
172
174
  import {
173
175
  _clearCurrentMiddlewareContext,
174
176
  _clearCurrentMiddlewareData,
@@ -230,7 +232,7 @@ import {
230
232
  splitRoutePath,
231
233
  toRootRelativeUrlPath,
232
234
  toViteModuleId
233
- } from "./chunk-Y3N5BFRJ.mjs";
235
+ } from "./chunk-JSDV2NUN.mjs";
234
236
  import {
235
237
  createFarmSearchParams,
236
238
  searchParamsToObject
@@ -242,6 +244,9 @@ import {
242
244
  import {
243
245
  sendWebResponse
244
246
  } from "./chunk-CO6UYM2D.mjs";
247
+ import {
248
+ resolveFarmAPIServerBasePath
249
+ } from "./chunk-2I6PUKWJ.mjs";
245
250
  import {
246
251
  matchesFarmIfNoneMatch,
247
252
  resolveFarmServerConfig
@@ -249,19 +254,16 @@ import {
249
254
  import {
250
255
  getRequestContextSnapshot
251
256
  } from "./chunk-D2LCAV6L.mjs";
252
- import {
253
- resolveFarmAPIServerBasePath
254
- } from "./chunk-LM2YOGDK.mjs";
255
257
  import {
256
258
  FARM_VERSION
257
- } from "./chunk-R4PHCZ3G.mjs";
259
+ } from "./chunk-HPWB57PZ.mjs";
258
260
  import {
259
261
  resolveFarmTrailingSlashRedirect,
260
262
  setFarmTrailingSlashPreference
261
263
  } from "./chunk-RFKTJTWZ.mjs";
262
264
  import {
263
265
  normalizeFarmAPIConfig
264
- } from "./chunk-BLD5GVCG.mjs";
266
+ } from "./chunk-W6QLRQ3V.mjs";
265
267
  import {
266
268
  createFarmLocaleCookie,
267
269
  getFarmLocaleVaryHeaders
@@ -932,6 +934,41 @@ function resolveOwnerSourcePath(resolvedPath, root) {
932
934
  }
933
935
  return current;
934
936
  }
937
+ function collectFarmRenderedClientModules(modulePath, root) {
938
+ const resolvedPath = resolveOwnerSourcePath(resolveModuleSourcePath(modulePath, root), root);
939
+ if (!resolvedPath) return null;
940
+ if (hasUseClientDirective(readIfExists(resolvedPath))) return [resolvedPath];
941
+ const collected = collectIsolatedClientBoundaries(resolvedPath, root, {
942
+ allowDynamicCardinality: true,
943
+ allowElementProps: true
944
+ });
945
+ if (collected.fallbackReason || collected.costGuardExceeded) return null;
946
+ return collected.boundaries.map((boundary) => boundary.modulePath);
947
+ }
948
+ var SERVER_MODULE_SOURCE = /\.[cm]?[jt]sx?$/;
949
+ var STYLESHEET_SOURCE = /\.(?:css|scss|sass|less|styl|stylus|pcss|postcss)$/;
950
+ function collectFarmServerStylesheets(modulePaths, root) {
951
+ const stylesheets = /* @__PURE__ */ new Set();
952
+ const visited = /* @__PURE__ */ new Set();
953
+ const visit = (file) => {
954
+ if (visited.has(file) || !SERVER_MODULE_SOURCE.test(file)) return;
955
+ visited.add(file);
956
+ const content = readIfExists(file);
957
+ if (!content || hasUseClientDirective(content)) return;
958
+ for (const specifier of getImportSpecifiers(content)) {
959
+ if (specifier.includes("?")) continue;
960
+ const imported = resolveImportedModule(file, specifier, root);
961
+ if (!imported.path) continue;
962
+ if (STYLESHEET_SOURCE.test(imported.path)) stylesheets.add(imported.path);
963
+ else if (imported.local) visit(imported.path);
964
+ }
965
+ };
966
+ for (const modulePath of modulePaths) {
967
+ const resolved = resolveOwnerSourcePath(resolveModuleSourcePath(modulePath, root), root);
968
+ if (resolved) visit(resolved);
969
+ }
970
+ return [...stylesheets];
971
+ }
935
972
  function getClientModuleMetadata(modulePath, root) {
936
973
  const resolvedPath = resolveModuleSourcePath(modulePath, root);
937
974
  return inspectClientModuleMetadata(resolvedPath, root, /* @__PURE__ */ new Set(), true);
@@ -946,7 +983,8 @@ function getClientModuleHydrationPlan(modulePath, root, mode = "off", options =
946
983
  if (!resolvedPath || owner.isClientComponent || owner.hasHydrateExport) return plan;
947
984
  const layout = collectIsolatedClientBoundaries(resolvedPath, root, {
948
985
  allowDynamicCardinality: true,
949
- allowElementProps: true
986
+ allowElementProps: true,
987
+ staticPackageLeaves: true
950
988
  });
951
989
  const routeWide = {
952
990
  ...plan,
@@ -964,7 +1002,16 @@ function getClientModuleHydrationPlan(modulePath, root, mode = "off", options =
964
1002
  islandsError: layout.fallbackHint ? `${layout.fallbackReason}. ${layout.fallbackHint}` : layout.fallbackReason
965
1003
  };
966
1004
  }
967
- return { ...routeWide, serverTreeLayout: true, isolatedBoundaries: layout.boundaries };
1005
+ const staticPackages = layout.staticPackages.length > 0 ? { staticPackageBoundaries: layout.staticPackages } : {};
1006
+ if (layout.boundaries.length === 0) {
1007
+ return { ...routeWide, shouldHydrate: false, islandStrategy: null, ...staticPackages };
1008
+ }
1009
+ return {
1010
+ ...routeWide,
1011
+ serverTreeLayout: true,
1012
+ isolatedBoundaries: layout.boundaries,
1013
+ ...staticPackages
1014
+ };
968
1015
  }
969
1016
  function planClientModuleHydration(modulePath, root, mode, options) {
970
1017
  const metadata = getClientModuleMetadata(modulePath, root);
@@ -995,7 +1042,8 @@ function planClientModuleHydration(modulePath, root, mode, options) {
995
1042
  const inspection = collectIsolatedClientBoundaries(resolvedPath, root, {
996
1043
  allowDynamicCardinality: asyncOwner,
997
1044
  allowElementProps: asyncOwner,
998
- staticPackageBoundaries: asyncOwner
1045
+ staticPackageBoundaries: asyncOwner,
1046
+ staticPackageLeaves: options.serverTreeLayouts === true && options.asyncOwnerIslands === true
999
1047
  });
1000
1048
  if (inspection.fallbackReason && asyncOwner && options.serverOwners === true) {
1001
1049
  return {
@@ -1039,9 +1087,9 @@ function planClientModuleHydration(modulePath, root, mode, options) {
1039
1087
  if (asyncOwner) {
1040
1088
  delete plan.suppressedAsyncHydration;
1041
1089
  plan.asyncOwnerIslands = true;
1042
- if (inspection.staticPackages.length > 0)
1043
- plan.staticPackageBoundaries = inspection.staticPackages;
1044
1090
  }
1091
+ if (inspection.staticPackages.length > 0)
1092
+ plan.staticPackageBoundaries = inspection.staticPackages;
1045
1093
  return plan;
1046
1094
  }
1047
1095
  function usesFarmServerTree(plan) {
@@ -1104,10 +1152,10 @@ function restoreRouteWideHydration(metadata, fallbackReason) {
1104
1152
  metadata.fallbackReason = fallbackReason;
1105
1153
  }
1106
1154
  }
1107
- function enforceFarmIsolatedHydrationRouteBudget(layouts, routes, layoutAppliesToRoute) {
1155
+ function enforceFarmIsolatedHydrationRouteBudget(layouts, routes, layoutAppliesToRoute, options = {}) {
1108
1156
  const boundaryLimit = isolatedHydrationBoundaryLimit();
1109
1157
  const sortedLayouts = [...layouts].sort((left, right) => left.depth - right.depth);
1110
- for (const route of routes) {
1158
+ for (const route of options.serverOwners ? [] : routes) {
1111
1159
  if (route.metadata.mode !== "enabled") continue;
1112
1160
  const applicableLayouts = sortedLayouts.filter(
1113
1161
  (layout) => layoutAppliesToRoute(layout.pattern, route.pattern)
@@ -1414,6 +1462,25 @@ function passesElementValuedProps(content, localBindings) {
1414
1462
  }
1415
1463
  return false;
1416
1464
  }
1465
+ function rendersOnlyLeafElements(content, localBindings) {
1466
+ if (!content) return false;
1467
+ const names = new Set(localBindings);
1468
+ const tokens = tokenizeModuleSource(content);
1469
+ for (let index = 0; index < tokens.length - 1; index++) {
1470
+ if (tokens[index].value !== "<" || !names.has(tokens[index + 1].value)) continue;
1471
+ let braceDepth = 0;
1472
+ let cursor = index + 2;
1473
+ for (; cursor < tokens.length; cursor++) {
1474
+ const value = tokens[cursor].value;
1475
+ if (value === "{") braceDepth++;
1476
+ else if (value === "}") braceDepth--;
1477
+ else if (value === "<" && braceDepth > 0) return false;
1478
+ else if (value === ">" && braceDepth === 0) break;
1479
+ }
1480
+ if (cursor >= tokens.length || tokens[cursor - 1]?.value !== "/") return false;
1481
+ }
1482
+ return true;
1483
+ }
1417
1484
  function hasDynamicJsxCardinality(content, localBindings) {
1418
1485
  if (!content || localBindings.length === 0) return false;
1419
1486
  const clientBindings = new Set(localBindings);
@@ -1492,7 +1559,7 @@ function collectIsolatedClientBoundaries(ownerPath, root, options = {}) {
1492
1559
  if (!imported.local) {
1493
1560
  const packageMetadata = inspectPackageClientBoundary(importedPath, root, /* @__PURE__ */ new Set());
1494
1561
  if (packageMetadata.shouldHydrate) {
1495
- if (options.staticPackageBoundaries) {
1562
+ if (options.staticPackageBoundaries || options.staticPackageLeaves && rendersOnlyLeafElements(content, importedBindings.get(specifier) ?? [])) {
1496
1563
  staticPackages.add(specifier);
1497
1564
  continue;
1498
1565
  }
@@ -2472,7 +2539,7 @@ var RouteManager = class {
2472
2539
  for (const { entry, metadata } of [...layoutEntries, ...routeEntries]) {
2473
2540
  if (isFarmMarkdownPageFile(entry.modulePath) || !metadata.staticPackageBoundaries) continue;
2474
2541
  logger.info(
2475
- `[Farm.js] ${entry.pattern} is async, so it renders client components from ${metadata.staticPackageBoundaries.join(", ")} as static HTML: package client components cannot be isolated yet.`
2542
+ `[Farm.js] ${entry.pattern} renders client components from ${metadata.staticPackageBoundaries.join(", ")} as static HTML: package client components cannot be isolated yet.`
2476
2543
  );
2477
2544
  }
2478
2545
  enforceFarmIsolatedHydrationRouteBudget(
@@ -2486,7 +2553,8 @@ var RouteManager = class {
2486
2553
  depth: getRouteDirectoryDepth(getRouteEntryDirectory(entry)),
2487
2554
  metadata
2488
2555
  })),
2489
- routeBoundaryCoversDirectory
2556
+ routeBoundaryCoversDirectory,
2557
+ { serverOwners: islandsMode }
2490
2558
  );
2491
2559
  for (const { entry, metadata } of [...layoutEntries, ...routeEntries]) {
2492
2560
  if (!metadata.costGuardExceeded) continue;
@@ -3309,17 +3377,18 @@ function resolveDevGlobalStylesheetHref(root, srcDir = "src") {
3309
3377
  }
3310
3378
  var STYLE_EXTENSIONS = /\.(css|scss|sass|less|styl|stylus)(?:$|\?)/;
3311
3379
  var ALREADY_LINKED = "/src/app/globals.css";
3312
- function collectDevStylesheetUrls(modules, alreadyLinked = ALREADY_LINKED) {
3380
+ function collectDevStylesheetUrls(modules, alreadyLinked = ALREADY_LINKED, options = {}) {
3313
3381
  const seen = /* @__PURE__ */ new Set();
3314
3382
  for (const mod of modules) {
3315
3383
  const id = mod.id ?? mod.file ?? "";
3316
3384
  if (!STYLE_EXTENSIONS.test(id)) continue;
3317
- if (id.includes(".module.")) continue;
3385
+ const cssModule = id.includes(".module.");
3386
+ if (cssModule && !options.cssModules) continue;
3318
3387
  const url = mod.url;
3319
3388
  if (!url || !url.startsWith("/")) continue;
3320
3389
  const bare = url.split("?")[0];
3321
3390
  if (bare === alreadyLinked) continue;
3322
- seen.add(bare);
3391
+ seen.add(cssModule ? `${bare}?direct` : bare);
3323
3392
  }
3324
3393
  return [...seen].sort();
3325
3394
  }
@@ -4423,101 +4492,498 @@ function resolveProviderModule(moduleId, root) {
4423
4492
  return toViteModuleId(path7.resolve(root, moduleId), root);
4424
4493
  }
4425
4494
 
4426
- // src/server/renderer.ts
4427
- import * as fs6 from "fs";
4428
- import * as https from "https";
4429
- import { isIP } from "net";
4430
- import * as path10 from "path";
4431
- import * as tls from "tls";
4432
- import { Readable, Writable } from "stream";
4433
-
4434
- // src/not-found.ts
4495
+ // src/island-inference.ts
4435
4496
  import fs4 from "fs";
4436
4497
  import path8 from "path";
4437
- function resolveFarmNotFoundComponentPath(config, appDirs) {
4438
- const extensions = getFarmRendererComponentExtensions(config.renderer);
4439
- const configuredPath = config.notFound?.component?.trim();
4440
- if (configuredPath) {
4441
- const componentPath = path8.isAbsolute(configuredPath) ? path8.normalize(configuredPath) : path8.resolve(config.root, configuredPath);
4442
- if (!extensions.some((extension) => componentPath.endsWith(extension))) {
4443
- throw new Error(
4444
- `notFound.component must use one of the configured renderer extensions: ${extensions.join(", ")}`
4445
- );
4498
+ import { inferStrategy } from "@farm.js/islx/compiler";
4499
+ import { parseAst } from "rolldown/parseAst";
4500
+ var PARSE_LANGS = /* @__PURE__ */ new Map([
4501
+ [".tsx", "tsx"],
4502
+ [".ts", "ts"],
4503
+ [".jsx", "jsx"],
4504
+ [".js", "jsx"],
4505
+ [".mjs", "js"]
4506
+ ]);
4507
+ function parseFarmIslandSource(file, code) {
4508
+ const lang = PARSE_LANGS.get(path8.extname(file));
4509
+ if (!lang) throw new Error(`${path8.basename(file)} is not a script module`);
4510
+ return parseAst(code, { lang });
4511
+ }
4512
+ function modifiedAt(file) {
4513
+ try {
4514
+ return fs4.statSync(file).mtimeMs;
4515
+ } catch {
4516
+ return -1;
4517
+ }
4518
+ }
4519
+ var inferences = /* @__PURE__ */ new Map();
4520
+ function inferFarmIslandStrategy(filePath, root) {
4521
+ const file = path8.resolve(filePath);
4522
+ const cached = inferences.get(file);
4523
+ if (cached && cached.stamps.every(([read, stamp]) => modifiedAt(read) === stamp)) {
4524
+ return cached.result;
4525
+ }
4526
+ let code;
4527
+ try {
4528
+ code = fs4.readFileSync(file, "utf8");
4529
+ } catch {
4530
+ return { strategy: null, files: [file], reason: `${path8.basename(file)} could not be read` };
4531
+ }
4532
+ const result = inferStrategy(file, code, {
4533
+ parse: parseFarmIslandSource,
4534
+ resolve: (specifier, importer) => {
4535
+ const resolved = resolveImportedModule(importer, specifier, root);
4536
+ return resolved.local ? resolved.path : null;
4446
4537
  }
4447
- if (!fs4.existsSync(componentPath) || !fs4.statSync(componentPath).isFile()) {
4448
- throw new Error(`notFound.component was not found: ${componentPath}`);
4538
+ });
4539
+ inferences.set(file, {
4540
+ stamps: result.files.map((read) => [read, modifiedAt(read)]),
4541
+ result
4542
+ });
4543
+ return result;
4544
+ }
4545
+ function inferFarmRouteRootStrategy(owners, root) {
4546
+ const files = [];
4547
+ const modules = [];
4548
+ for (const owner of owners) {
4549
+ const rendered = collectFarmRenderedClientModules(owner, root);
4550
+ if (!rendered) {
4551
+ return {
4552
+ strategy: null,
4553
+ files,
4554
+ reason: `${path8.basename(owner)}: its client components could not be listed`
4555
+ };
4449
4556
  }
4450
- return componentPath;
4557
+ modules.push(...rendered);
4451
4558
  }
4452
- let discoveredPath = null;
4453
- for (const appDir of appDirs) {
4454
- for (const extension of extensions) {
4455
- const candidate = path8.join(appDir, `not-found${extension}`);
4456
- if (fs4.existsSync(candidate) && fs4.statSync(candidate).isFile()) {
4457
- discoveredPath = candidate;
4458
- break;
4459
- }
4559
+ for (const module of modules) {
4560
+ let source = null;
4561
+ try {
4562
+ source = fs4.readFileSync(module, "utf8");
4563
+ } catch {
4460
4564
  }
4565
+ if (getIslandStrategyExport(source) !== null) return { strategy: null, files, declared: true };
4461
4566
  }
4462
- return discoveredPath;
4463
- }
4464
-
4465
- // src/components/not-found-styles.ts
4466
- var DEFAULT_NOT_FOUND_STYLES = `
4467
- body {
4468
- margin: 0;
4469
- }
4470
-
4471
- .farm-default-not-found {
4472
- --farm-not-found-bg: #fafafa;
4473
- --farm-not-found-fg: #171717;
4474
- --farm-not-found-muted: #737373;
4475
- --farm-not-found-line: rgba(0, 0, 0, 0.16);
4476
- --farm-not-found-button-fg: #ffffff;
4477
- min-height: 100vh;
4478
- min-height: 100svh;
4479
- display: grid;
4480
- place-items: center;
4481
- padding: 24px;
4482
- color: var(--farm-not-found-fg);
4483
- background: var(--farm-not-found-bg);
4484
- font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
4485
- color-scheme: light;
4567
+ for (const module of modules) {
4568
+ const result = inferFarmIslandStrategy(module, root);
4569
+ files.push(...result.files);
4570
+ if (!result.strategy) return { strategy: null, files, reason: result.reason };
4571
+ }
4572
+ return { strategy: "interaction", files };
4486
4573
  }
4487
-
4488
- .farm-default-not-found,
4489
- .farm-default-not-found * {
4490
- box-sizing: border-box;
4574
+ function resolveFarmRouteRootStrategy(route, page, layouts, root, islandsMode) {
4575
+ const directory = route.directory ?? route.pattern;
4576
+ const onRoute = layouts.filter(
4577
+ (layout) => routeBoundaryCoversDirectory(layout.pattern, directory)
4578
+ );
4579
+ const declared = [
4580
+ ...page.islandStrategy ? [page.islandStrategy] : [],
4581
+ ...onRoute.flatMap(
4582
+ (layout) => (layout.shouldHydrate || layout.hasIsolatedClientBoundaries) && layout.islandStrategy ? [layout.islandStrategy] : []
4583
+ )
4584
+ ];
4585
+ const combined = declared.every((strategy) => strategy === declared[0]) ? declared[0] ?? "load" : "load";
4586
+ const layoutHydrates = onRoute.some((layout) => layout.shouldHydrate);
4587
+ if (!islandsMode || !page.shouldHydrate && !layoutHydrates) return combined;
4588
+ const owners = [
4589
+ route.modulePath,
4590
+ ...layoutHydrates ? onRoute.map((layout) => layout.modulePath) : []
4591
+ ];
4592
+ const inference = inferFarmRouteRootStrategy(owners, root);
4593
+ if (inference.declared) return combined;
4594
+ return inference.strategy ?? "load";
4491
4595
  }
4492
4596
 
4493
- .farm-default-not-found__content {
4494
- width: min(100%, 280px);
4495
- display: flex;
4496
- flex-direction: column;
4497
- align-items: center;
4597
+ // src/client-plugin-build.ts
4598
+ import fs5 from "fs";
4599
+ import path9 from "path";
4600
+ var CLIENT_KEYS = [
4601
+ "public",
4602
+ "setup",
4603
+ "hydration",
4604
+ "navigation",
4605
+ "error",
4606
+ "performance",
4607
+ "close"
4608
+ ];
4609
+ var HYDRATION_KEYS = ["before", "after"];
4610
+ var NAVIGATION_KEYS = ["before", "loaded", "resolved", "rendered", "error"];
4611
+ var MOBILE_SHELL_CLIENT_IMPORT = 'import { farmMobileShellClient as __farmMobileShellClient } from "@farm.js/core/internal/client-runtime";';
4612
+ var MOBILE_SHELL_CLIENT_REGISTRATION = ` {
4613
+ name: "farm:mobile-shell",
4614
+ enforce: "pre",
4615
+ definition: __farmMobileShellClient,
4616
+ }`;
4617
+ var APP_CLIENT_EXTENSIONS = ["ts", "tsx", "js", "jsx", "mts", "mjs"];
4618
+ function resolveFarmAppClientEntry(root = process.cwd(), srcDir = "src") {
4619
+ const sourceRoot = path9.resolve(root, srcDir);
4620
+ for (const extension of APP_CLIENT_EXTENSIONS) {
4621
+ const candidate = path9.join(sourceRoot, `client.${extension}`);
4622
+ if (fs5.existsSync(candidate) && fs5.statSync(candidate).isFile()) return candidate;
4623
+ }
4624
+ return void 0;
4498
4625
  }
4499
-
4500
- .farm-default-not-found__code {
4501
- margin: 0;
4502
- color: var(--farm-not-found-fg);
4503
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
4504
- font-size: clamp(88px, 20vw, 140px);
4505
- font-weight: 800;
4506
- line-height: 0.75;
4507
- letter-spacing: -0.1em;
4508
- transform: translateX(-3px);
4626
+ function resolveFarmClientPlugins(plugins, _root) {
4627
+ if (!plugins?.length) return [];
4628
+ return plugins.flatMap((plugin) => {
4629
+ if (!plugin.client) return [];
4630
+ assertClientLifecycle(plugin.client, plugin.name);
4631
+ assertPublicData(plugin.client.public, plugin.name);
4632
+ return [
4633
+ {
4634
+ name: plugin.name,
4635
+ version: plugin.version,
4636
+ enforce: plugin.enforce,
4637
+ definition: plugin.client,
4638
+ publicData: plugin.client.public
4639
+ }
4640
+ ];
4641
+ });
4509
4642
  }
4510
-
4511
- @supports (-webkit-text-stroke: 1px currentColor) {
4512
- .farm-default-not-found__code {
4513
- color: var(--farm-not-found-bg);
4514
- -webkit-text-stroke: 2px var(--farm-not-found-fg);
4515
- text-shadow: 5px 5px 0 var(--farm-not-found-fg);
4643
+ function generateFarmClientPluginEntryCode(plugins, root, srcDir = "src", appPublicData, platform = resolveFarmPlatform()) {
4644
+ const resolved = resolveFarmClientPlugins(plugins, root);
4645
+ const appClientEntry = root ? resolveFarmAppClientEntry(root, srcDir) : void 0;
4646
+ const appImport = appClientEntry ? `import farmAppClientDefinition from ${JSON.stringify(appClientEntry.replace(/\\/g, "/"))};` : "";
4647
+ const mobileShell = platform === "mobile";
4648
+ const imports = mobileShell ? [MOBILE_SHELL_CLIENT_IMPORT, appImport].filter(Boolean).join("\n") : appImport;
4649
+ const serializedPlugins = mobileShell ? [MOBILE_SHELL_CLIENT_REGISTRATION] : [];
4650
+ serializedPlugins.push(
4651
+ ...resolved.map(
4652
+ (plugin) => ` {
4653
+ name: ${JSON.stringify(plugin.name)},
4654
+ version: ${serializeOptionalString(plugin.version)},
4655
+ enforce: ${serializeOptionalString(plugin.enforce)},
4656
+ definition: ${serializeClientLifecycle(plugin.definition, plugin.name)},
4657
+ public: ${serializePublicData(plugin.publicData)},
4658
+ }`
4659
+ )
4660
+ );
4661
+ if (appClientEntry) {
4662
+ assertPublicData(appPublicData, "farm:app-client");
4663
+ serializedPlugins.push(` {
4664
+ name: "farm:app-client",
4665
+ enforce: "post",
4666
+ definition: farmAppClientDefinition,
4667
+ public: ${serializePublicData(appPublicData)},
4668
+ }`);
4516
4669
  }
4670
+ const registrations = `[
4671
+ ${serializedPlugins.join(",\n")}
4672
+ ]`;
4673
+ return { imports, registrations, plugins: resolved };
4517
4674
  }
4518
-
4519
- .farm-default-not-found__description {
4520
- width: 100%;
4675
+ function assertClientLifecycle(client, pluginName) {
4676
+ assertLifecycleObject(client, pluginName, "client", CLIENT_KEYS);
4677
+ assertHook(client.setup, pluginName, "client.setup");
4678
+ assertHook(client.error, pluginName, "client.error");
4679
+ assertHook(client.performance, pluginName, "client.performance");
4680
+ assertHook(client.close, pluginName, "client.close");
4681
+ if (client.hydration !== void 0) {
4682
+ assertLifecycleObject(client.hydration, pluginName, "client.hydration", HYDRATION_KEYS);
4683
+ assertHook(client.hydration.before, pluginName, "client.hydration.before");
4684
+ assertHook(client.hydration.after, pluginName, "client.hydration.after");
4685
+ }
4686
+ if (client.navigation !== void 0) {
4687
+ assertLifecycleObject(client.navigation, pluginName, "client.navigation", NAVIGATION_KEYS);
4688
+ for (const key of NAVIGATION_KEYS) {
4689
+ assertHook(client.navigation[key], pluginName, `client.navigation.${key}`);
4690
+ }
4691
+ }
4692
+ }
4693
+ function assertLifecycleObject(value, pluginName, location, allowedKeys) {
4694
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
4695
+ throw new TypeError(`Client plugin "${pluginName}" ${location} must be an object`);
4696
+ }
4697
+ const prototype = Object.getPrototypeOf(value);
4698
+ if (prototype !== Object.prototype && prototype !== null) {
4699
+ throw new TypeError(`Client plugin "${pluginName}" ${location} must be a plain object`);
4700
+ }
4701
+ for (const key of Reflect.ownKeys(value)) {
4702
+ if (typeof key === "symbol") {
4703
+ throw new TypeError(`Client plugin "${pluginName}" ${location} cannot contain symbol keys`);
4704
+ }
4705
+ if (!allowedKeys.includes(key)) {
4706
+ throw new TypeError(`Client plugin "${pluginName}" has an unknown ${location}.${key} option`);
4707
+ }
4708
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
4709
+ if (!descriptor?.enumerable) {
4710
+ throw new TypeError(`Client plugin "${pluginName}" ${location}.${key} must be enumerable`);
4711
+ }
4712
+ if (!("value" in descriptor)) {
4713
+ throw new TypeError(`Client plugin "${pluginName}" ${location}.${key} cannot be an accessor`);
4714
+ }
4715
+ }
4716
+ }
4717
+ function assertHook(value, pluginName, location) {
4718
+ if (value === void 0) return;
4719
+ if (typeof value !== "function") {
4720
+ throw new TypeError(`Client plugin "${pluginName}" ${location} must be a function`);
4721
+ }
4722
+ functionSource(value, pluginName, location);
4723
+ }
4724
+ function serializeClientLifecycle(definition, pluginName) {
4725
+ const fields = [];
4726
+ pushHook(fields, "setup", definition.setup, pluginName, "client.setup", 2);
4727
+ pushHookGroup(fields, "hydration", definition.hydration, HYDRATION_KEYS, pluginName, 2);
4728
+ pushHookGroup(fields, "navigation", definition.navigation, NAVIGATION_KEYS, pluginName, 2);
4729
+ pushHook(fields, "error", definition.error, pluginName, "client.error", 2);
4730
+ pushHook(fields, "performance", definition.performance, pluginName, "client.performance", 2);
4731
+ pushHook(fields, "close", definition.close, pluginName, "client.close", 2);
4732
+ return fields.length ? `{
4733
+ ${fields.join(",\n")}
4734
+ }` : "{}";
4735
+ }
4736
+ function pushHookGroup(fields, groupName, group, keys, pluginName, indent) {
4737
+ if (!group) return;
4738
+ const hooks = [];
4739
+ for (const key of keys) {
4740
+ pushHook(hooks, key, group[key], pluginName, `client.${groupName}.${key}`, indent + 2);
4741
+ }
4742
+ fields.push(
4743
+ `${" ".repeat(indent)}${JSON.stringify(groupName)}: {
4744
+ ${hooks.join(",\n")}
4745
+ ${" ".repeat(indent)}}`
4746
+ );
4747
+ }
4748
+ function pushHook(fields, key, hook, pluginName, location, indent) {
4749
+ if (hook === void 0) return;
4750
+ fields.push(
4751
+ `${" ".repeat(indent)}${JSON.stringify(key)}: ${functionSource(hook, pluginName, location)}`
4752
+ );
4753
+ }
4754
+ function functionSource(value, pluginName, location) {
4755
+ if (typeof value !== "function") {
4756
+ throw new TypeError(`Client plugin "${pluginName}" ${location} must be a function`);
4757
+ }
4758
+ const source = Function.prototype.toString.call(value).trim();
4759
+ if (!source || source.includes("[native code]")) {
4760
+ throw new TypeError(
4761
+ `Client plugin "${pluginName}" ${location} must be authored inline and cannot be native or bound`
4762
+ );
4763
+ }
4764
+ if (/^(?:async\s+)?function(?:\s*\*)?(?:\s+|\()/.test(source)) {
4765
+ return `(${source})`;
4766
+ }
4767
+ const method = source.match(/^(async\s+)?(\*\s*)?[$A-Z_a-z][$\w]*\s*(\([\s\S]*)$/);
4768
+ if (method) {
4769
+ const asyncPrefix = method[1] ?? "";
4770
+ const generator = method[2] ? "*" : "";
4771
+ return `(${asyncPrefix}function${generator}${method[3]})`;
4772
+ }
4773
+ if (source.includes("=>")) return `(${source})`;
4774
+ throw new TypeError(
4775
+ `Client plugin "${pluginName}" ${location} must use a function, method, or arrow function`
4776
+ );
4777
+ }
4778
+ function assertPublicData(value, pluginName) {
4779
+ if (value === void 0) return;
4780
+ const seen = /* @__PURE__ */ new WeakSet();
4781
+ const visit = (current, pathSegments) => {
4782
+ if (current === null || typeof current === "string" || typeof current === "boolean") {
4783
+ return;
4784
+ }
4785
+ if (typeof current === "number") {
4786
+ if (Number.isFinite(current)) return;
4787
+ throwPublicDataError(pluginName, pathSegments, "must be a finite number");
4788
+ }
4789
+ if (typeof current !== "object") {
4790
+ throwPublicDataError(pluginName, pathSegments, `cannot contain ${typeof current} values`);
4791
+ }
4792
+ if (seen.has(current)) {
4793
+ throwPublicDataError(pluginName, pathSegments, "cannot contain circular references");
4794
+ }
4795
+ seen.add(current);
4796
+ if (Array.isArray(current)) {
4797
+ for (let index = 0; index < current.length; index += 1) {
4798
+ if (!Object.prototype.hasOwnProperty.call(current, index)) {
4799
+ throwPublicDataError(
4800
+ pluginName,
4801
+ [...pathSegments, String(index)],
4802
+ "cannot contain sparse array slots"
4803
+ );
4804
+ }
4805
+ visit(current[index], [...pathSegments, String(index)]);
4806
+ }
4807
+ for (const key of Reflect.ownKeys(current)) {
4808
+ if (key === "length" || typeof key === "string" && isArrayIndex(key)) continue;
4809
+ throwPublicDataError(
4810
+ pluginName,
4811
+ pathSegments,
4812
+ typeof key === "symbol" ? "cannot contain symbol keys" : `cannot contain non-index array property ${key}`
4813
+ );
4814
+ }
4815
+ seen.delete(current);
4816
+ return;
4817
+ }
4818
+ const prototype = Object.getPrototypeOf(current);
4819
+ if (prototype !== Object.prototype && prototype !== null) {
4820
+ throwPublicDataError(pluginName, pathSegments, "must contain only plain objects and arrays");
4821
+ }
4822
+ for (const key of Reflect.ownKeys(current)) {
4823
+ if (typeof key === "symbol") {
4824
+ throwPublicDataError(pluginName, pathSegments, "cannot contain symbol keys");
4825
+ }
4826
+ const descriptor = Object.getOwnPropertyDescriptor(current, key);
4827
+ if (!descriptor?.enumerable) {
4828
+ throwPublicDataError(
4829
+ pluginName,
4830
+ [...pathSegments, key],
4831
+ "cannot contain non-enumerable properties"
4832
+ );
4833
+ }
4834
+ if (!("value" in descriptor)) {
4835
+ throwPublicDataError(
4836
+ pluginName,
4837
+ [...pathSegments, key],
4838
+ "cannot contain accessor properties"
4839
+ );
4840
+ }
4841
+ visit(descriptor.value, [...pathSegments, key]);
4842
+ }
4843
+ seen.delete(current);
4844
+ };
4845
+ visit(value, []);
4846
+ }
4847
+ function throwPublicDataError(pluginName, pathSegments, message) {
4848
+ const location = pathSegments.length ? ` at client.public.${pathSegments.join(".")}` : "";
4849
+ throw new TypeError(`Client plugin "${pluginName}"${location} ${message}`);
4850
+ }
4851
+ function serializePublicData(value) {
4852
+ if (value === void 0) return "undefined";
4853
+ return `JSON.parse(${JSON.stringify(JSON.stringify(value))})`;
4854
+ }
4855
+ function serializeOptionalString(value) {
4856
+ return value === void 0 ? "undefined" : JSON.stringify(value);
4857
+ }
4858
+ function isArrayIndex(key) {
4859
+ const value = Number(key);
4860
+ return Number.isInteger(value) && value >= 0 && value < 4294967295 && String(value) === key;
4861
+ }
4862
+
4863
+ // src/server/renderer.ts
4864
+ import * as fs8 from "fs";
4865
+ import * as https from "https";
4866
+ import { isIP } from "net";
4867
+ import * as path12 from "path";
4868
+ import * as tls from "tls";
4869
+ import { Readable, Writable } from "stream";
4870
+
4871
+ // src/not-found.ts
4872
+ import fs6 from "fs";
4873
+ import path10 from "path";
4874
+ function resolveFarmNotFoundComponentPath(config, appDirs) {
4875
+ const extensions = getFarmRendererComponentExtensions(config.renderer);
4876
+ const configuredPath = config.notFound?.component?.trim();
4877
+ if (configuredPath) {
4878
+ const componentPath = path10.isAbsolute(configuredPath) ? path10.normalize(configuredPath) : path10.resolve(config.root, configuredPath);
4879
+ if (!extensions.some((extension) => componentPath.endsWith(extension))) {
4880
+ throw new Error(
4881
+ `notFound.component must use one of the configured renderer extensions: ${extensions.join(", ")}`
4882
+ );
4883
+ }
4884
+ if (!fs6.existsSync(componentPath) || !fs6.statSync(componentPath).isFile()) {
4885
+ throw new Error(`notFound.component was not found: ${componentPath}`);
4886
+ }
4887
+ return componentPath;
4888
+ }
4889
+ let discoveredPath = null;
4890
+ for (const appDir of appDirs) {
4891
+ for (const extension of extensions) {
4892
+ const candidate = path10.join(appDir, `not-found${extension}`);
4893
+ if (fs6.existsSync(candidate) && fs6.statSync(candidate).isFile()) {
4894
+ discoveredPath = candidate;
4895
+ break;
4896
+ }
4897
+ }
4898
+ }
4899
+ return discoveredPath;
4900
+ }
4901
+
4902
+ // src/navigation/segment-navigation.ts
4903
+ function getFarmLayoutKey(pattern, params) {
4904
+ return pattern.replace(
4905
+ /\[\[?\.\.\.([^\]]+)\]?\]|\[([^\]]+)\]/g,
4906
+ (_match, rest, name) => {
4907
+ const value = params ? params[rest || name] : void 0;
4908
+ if (Array.isArray(value)) return value.map(encodeURIComponent).join("/");
4909
+ return value === void 0 ? "" : encodeURIComponent(String(value));
4910
+ }
4911
+ );
4912
+ }
4913
+ function countFarmKeptLayouts(layoutsHeader, layouts, params) {
4914
+ const chain = parseFarmLayoutChainHeader(layoutsHeader ?? null);
4915
+ if (chain.length === 0) return 0;
4916
+ const keys = layouts.map((layout) => getFarmLayoutKey(layout.pattern, params));
4917
+ if (chain[0] === keys[0]) return getSharedLayoutPrefixLength(chain, keys);
4918
+ return keys.length > 1 ? 1 + getSharedLayoutPrefixLength(chain, keys.slice(1)) : 0;
4919
+ }
4920
+ function createFarmFlushToken() {
4921
+ const bytes = new Uint8Array(16);
4922
+ globalThis.crypto.getRandomValues(bytes);
4923
+ let token = "";
4924
+ for (const byte of bytes) token += byte.toString(16).padStart(2, "0");
4925
+ return token;
4926
+ }
4927
+ function farmFlushMarker(token) {
4928
+ return `<!--farm-flush:${token}-->`;
4929
+ }
4930
+
4931
+ // src/components/not-found-styles.ts
4932
+ var DEFAULT_NOT_FOUND_STYLES = `
4933
+ body {
4934
+ margin: 0;
4935
+ }
4936
+
4937
+ .farm-default-not-found {
4938
+ --farm-not-found-bg: #fafafa;
4939
+ --farm-not-found-fg: #171717;
4940
+ --farm-not-found-muted: #737373;
4941
+ --farm-not-found-line: rgba(0, 0, 0, 0.16);
4942
+ --farm-not-found-button-fg: #ffffff;
4943
+ min-height: 100vh;
4944
+ min-height: 100svh;
4945
+ display: grid;
4946
+ place-items: center;
4947
+ padding: 24px;
4948
+ color: var(--farm-not-found-fg);
4949
+ background: var(--farm-not-found-bg);
4950
+ font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
4951
+ color-scheme: light;
4952
+ }
4953
+
4954
+ .farm-default-not-found,
4955
+ .farm-default-not-found * {
4956
+ box-sizing: border-box;
4957
+ }
4958
+
4959
+ .farm-default-not-found__content {
4960
+ width: min(100%, 280px);
4961
+ display: flex;
4962
+ flex-direction: column;
4963
+ align-items: center;
4964
+ }
4965
+
4966
+ .farm-default-not-found__code {
4967
+ margin: 0;
4968
+ color: var(--farm-not-found-fg);
4969
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
4970
+ font-size: clamp(88px, 20vw, 140px);
4971
+ font-weight: 800;
4972
+ line-height: 0.75;
4973
+ letter-spacing: -0.1em;
4974
+ transform: translateX(-3px);
4975
+ }
4976
+
4977
+ @supports (-webkit-text-stroke: 1px currentColor) {
4978
+ .farm-default-not-found__code {
4979
+ color: var(--farm-not-found-bg);
4980
+ -webkit-text-stroke: 2px var(--farm-not-found-fg);
4981
+ text-shadow: 5px 5px 0 var(--farm-not-found-fg);
4982
+ }
4983
+ }
4984
+
4985
+ .farm-default-not-found__description {
4986
+ width: 100%;
4521
4987
  display: flex;
4522
4988
  align-items: center;
4523
4989
  gap: 12px;
@@ -4620,8 +5086,8 @@ body {
4620
5086
  import { pathToFileURL as pathToFileURL2 } from "url";
4621
5087
 
4622
5088
  // src/server/error-diagnostics.ts
4623
- import * as fs5 from "fs";
4624
- import * as path9 from "path";
5089
+ import * as fs7 from "fs";
5090
+ import * as path11 from "path";
4625
5091
  import { fileURLToPath as fileURLToPath2 } from "url";
4626
5092
  var SECRET_VALUE_PATTERN = /\b(api[_-]?key|access[_-]?token|auth[_-]?token|client[_-]?secret|secret[_-]?key|token|password|secret)\s*[:=]\s*([^\s,;]+)/gi;
4627
5093
  var BEARER_PATTERN = /\b(Bearer\s+)[A-Za-z0-9._~+/=-]+/gi;
@@ -4629,8 +5095,8 @@ function redactErrorText(value) {
4629
5095
  return value.replace(BEARER_PATTERN, "$1[REDACTED]").replace(SECRET_VALUE_PATTERN, "$1=[REDACTED]");
4630
5096
  }
4631
5097
  function isPathInsideRoot(root, filePath) {
4632
- const relative3 = path9.relative(root, filePath);
4633
- return relative3 === "" || !relative3.startsWith("..") && !path9.isAbsolute(relative3);
5098
+ const relative3 = path11.relative(root, filePath);
5099
+ return relative3 === "" || !relative3.startsWith("..") && !path11.isAbsolute(relative3);
4634
5100
  }
4635
5101
  function normalizeStackPath(value) {
4636
5102
  const withoutQuery = value.replace(/[?#].*$/, "");
@@ -4647,13 +5113,13 @@ function findStackLocation(stack, root) {
4647
5113
  );
4648
5114
  if (!match) continue;
4649
5115
  const candidate = normalizeStackPath(match[1]);
4650
- if (!candidate || candidate.includes(`${path9.sep}node_modules${path9.sep}`)) continue;
4651
- const absolutePath = path9.resolve(candidate);
4652
- if (!isPathInsideRoot(root, absolutePath) || !fs5.existsSync(absolutePath)) continue;
4653
- const relativePath = path9.relative(root, absolutePath).split(path9.sep).join("/");
5116
+ if (!candidate || candidate.includes(`${path11.sep}node_modules${path11.sep}`)) continue;
5117
+ const absolutePath = path11.resolve(candidate);
5118
+ if (!isPathInsideRoot(root, absolutePath) || !fs7.existsSync(absolutePath)) continue;
5119
+ const relativePath = path11.relative(root, absolutePath).split(path11.sep).join("/");
4654
5120
  return {
4655
5121
  absolutePath,
4656
- displayPath: relativePath || path9.basename(absolutePath),
5122
+ displayPath: relativePath || path11.basename(absolutePath),
4657
5123
  line: Number(match[2]),
4658
5124
  column: Number(match[3])
4659
5125
  };
@@ -4662,7 +5128,7 @@ function findStackLocation(stack, root) {
4662
5128
  }
4663
5129
  function createSourceFrame(location) {
4664
5130
  try {
4665
- const sourceLines = fs5.readFileSync(location.absolutePath, "utf8").split(/\r?\n/);
5131
+ const sourceLines = fs7.readFileSync(location.absolutePath, "utf8").split(/\r?\n/);
4666
5132
  if (location.line < 1 || location.line > sourceLines.length) return void 0;
4667
5133
  const start = Math.max(1, location.line - 2);
4668
5134
  const end = Math.min(sourceLines.length, location.line + 2);
@@ -4685,13 +5151,13 @@ function createSourceFrame(location) {
4685
5151
  }
4686
5152
  }
4687
5153
  function sanitizeStack(stack, root) {
4688
- const normalizedRoot = path9.resolve(root);
5154
+ const normalizedRoot = path11.resolve(root);
4689
5155
  return redactErrorText(stack).split(normalizedRoot).join("<project>").replace(/<project>[^\s)]*/g, (segment) => segment.split("\\").join("/")).split("\n").filter((line, index) => index === 0 || !line.includes("node:internal")).slice(0, 14).join("\n");
4690
5156
  }
4691
5157
  function createDefaultErrorDiagnostics(error, root) {
4692
5158
  const normalizedError = error instanceof Error ? error : new Error(typeof error === "string" ? error : "Unknown server rendering error");
4693
5159
  const rawStack = normalizedError.stack || `${normalizedError.name}: ${normalizedError.message}`;
4694
- const location = findStackLocation(rawStack, path9.resolve(root));
5160
+ const location = findStackLocation(rawStack, path11.resolve(root));
4695
5161
  return {
4696
5162
  name: redactErrorText(normalizedError.name || "Error"),
4697
5163
  message: redactErrorText(normalizedError.message || "Unknown server rendering error"),
@@ -4700,6 +5166,13 @@ function createDefaultErrorDiagnostics(error, root) {
4700
5166
  };
4701
5167
  }
4702
5168
 
5169
+ // src/islands-client-boot.ts
5170
+ function canBootFarmIslandsClient(config) {
5171
+ const docs = config.docs;
5172
+ const docsEnabled = docs === true || typeof docs === "object" && docs !== null && docs.enabled !== false;
5173
+ return resolveFarmServerComponentsMode(config.experimental?.serverComponents) === "islands" && !docsEnabled && resolveFarmClientPlugins(config.plugins, config.root).length === 0 && !resolveFarmAppClientEntry(config.root, config.srcDir || "src");
5174
+ }
5175
+
4703
5176
  // src/server/renderer.ts
4704
5177
  var islands;
4705
5178
  function withFarmIslandsRenders(runtime, islandsRuntime) {
@@ -4806,6 +5279,10 @@ function appendResponseHeader(res, name, value) {
4806
5279
  res.setHeader(name, [String(current), value]);
4807
5280
  }
4808
5281
  }
5282
+ function requestHeader(req, name) {
5283
+ const value = req.headers?.[name];
5284
+ return Array.isArray(value) ? value[0] : value;
5285
+ }
4809
5286
  function appendResponseVary(res, value) {
4810
5287
  const current = res.getHeader("Vary");
4811
5288
  const values = new Set(
@@ -4832,6 +5309,10 @@ function rendererRenderOptions() {
4832
5309
  return nonce ? { nonce } : void 0;
4833
5310
  }
4834
5311
  var FARM_DEV_EARLY_CLIENT_SCRIPT = `<script type="module" async src="/@farm/client.js"></script>`;
5312
+ function createFarmDevBootScript(root, strategy) {
5313
+ const rootAttributes = root ? ` data-farm-root="${root}" data-farm-root-strategy="${escapeHtmlAttribute2(strategy ?? "load")}"` : "";
5314
+ return `<script type="module" async src="/@farm/client-boot.js" data-farm-runtime="/@farm/client.js"${rootAttributes}></script>`;
5315
+ }
4835
5316
  function createDocumentFooter(options) {
4836
5317
  return `${options.closeRoot === false ? "" : "</div>"}
4837
5318
  ${options.suspenseRevealFallback}
@@ -4945,7 +5426,7 @@ function createRouteStateProps(input) {
4945
5426
  function readAppPackageIdentity(root) {
4946
5427
  try {
4947
5428
  return JSON.parse(
4948
- fs6.readFileSync(path10.join(root || process.cwd(), "package.json"), "utf8")
5429
+ fs8.readFileSync(path12.join(root || process.cwd(), "package.json"), "utf8")
4949
5430
  );
4950
5431
  } catch {
4951
5432
  return {};
@@ -5057,7 +5538,8 @@ var ServerRenderer = class {
5057
5538
  if (!graph) return [];
5058
5539
  return collectDevStylesheetUrls(
5059
5540
  graph.idToModuleMap.values(),
5060
- this.devGlobalStylesheetHref() ?? void 0
5541
+ this.devGlobalStylesheetHref() ?? void 0,
5542
+ { cssModules: this.islandValues() }
5061
5543
  );
5062
5544
  }
5063
5545
  collectDevStyleLinks() {
@@ -5065,12 +5547,19 @@ var ServerRenderer = class {
5065
5547
  (href) => `<link rel="stylesheet" href="${escapeHtmlAttribute2(href)}">`
5066
5548
  );
5067
5549
  }
5068
- createLayoutBoundary(pattern, layoutElement) {
5550
+ /**
5551
+ * A layout's boundary. Islands mode keys it (the pattern with its params, as the production
5552
+ * server does), so a navigation can name the layouts the browser shows; a layout the browser
5553
+ * keeps is sent as its boundary alone (`kept`).
5554
+ */
5555
+ createLayoutBoundary(pattern, layoutElement, segment) {
5069
5556
  return this.rendererRuntime.createElement(
5070
5557
  "div",
5071
5558
  {
5072
5559
  "data-farm-layout-boundary": "true",
5073
5560
  "data-farm-layout-pattern": pattern,
5561
+ ...segment ? { "data-farm-layout-key": segment.key } : {},
5562
+ ...segment?.kept ? { "data-farm-layout-kept": "true" } : {},
5074
5563
  style: { display: "contents" }
5075
5564
  },
5076
5565
  layoutElement
@@ -5244,10 +5733,10 @@ var ServerRenderer = class {
5244
5733
  * Load SSG manifest from build output
5245
5734
  */
5246
5735
  loadSSGManifest() {
5247
- const manifestPath = path10.join(this.config.root, this.config.outDir, "__ssg_manifest.json");
5736
+ const manifestPath = path12.join(this.config.root, this.config.outDir, "__ssg_manifest.json");
5248
5737
  let content;
5249
5738
  try {
5250
- content = fs6.readFileSync(manifestPath, "utf-8");
5739
+ content = fs8.readFileSync(manifestPath, "utf-8");
5251
5740
  } catch (error) {
5252
5741
  if (error.code === "ENOENT") {
5253
5742
  return;
@@ -5466,10 +5955,10 @@ var ServerRenderer = class {
5466
5955
  return true;
5467
5956
  }
5468
5957
  try {
5469
- const htmlPath = page.urlPath === "/" ? path10.join(this.config.root, this.config.outDir, "client", "index.html") : path10.join(this.config.root, this.config.outDir, "client", page.urlPath + ".html");
5470
- if (fs6.existsSync(htmlPath)) {
5471
- const stat = fs6.statSync(htmlPath);
5472
- const html = fs6.readFileSync(htmlPath, "utf-8");
5958
+ const htmlPath = page.urlPath === "/" ? path12.join(this.config.root, this.config.outDir, "client", "index.html") : path12.join(this.config.root, this.config.outDir, "client", page.urlPath + ".html");
5959
+ if (fs8.existsSync(htmlPath)) {
5960
+ const stat = fs8.statSync(htmlPath);
5961
+ const html = fs8.readFileSync(htmlPath, "utf-8");
5473
5962
  await this.cacheSSGPage(page, html, {
5474
5963
  document: true,
5475
5964
  createdAt: stat.mtimeMs
@@ -5719,7 +6208,10 @@ var ServerRenderer = class {
5719
6208
  { experimentalPPR: this.config.experimental?.ppr === true }
5720
6209
  );
5721
6210
  const pprBypassReason = renderingConfig.ppr ? this.getPPRShellBypassReason(req, middlewareMap, middlewareContext, pluginExposedContext) : void 0;
5722
- const canCachePPRShell = renderingConfig.ppr && !pprBypassReason;
6211
+ const islandsNavigationRequest = Boolean(
6212
+ islands && this.islandValues() && (requestHeader(req, "f-layouts") || requestHeader(req, "f-stream"))
6213
+ );
6214
+ const canCachePPRShell = renderingConfig.ppr && !pprBypassReason && !islandsNavigationRequest;
5723
6215
  const pprI18nSnapshot = canCachePPRShell ? getFarmI18nClientSnapshot() : void 0;
5724
6216
  const pprShellOptions = canCachePPRShell ? {
5725
6217
  pathname,
@@ -5893,9 +6385,19 @@ var ServerRenderer = class {
5893
6385
  (metadata) => metadata.shouldHydrate && metadata.islandStrategy ? [metadata.islandStrategy] : []
5894
6386
  )
5895
6387
  ];
5896
- const hydrationIslandStrategy = hydrationStrategies.every(
5897
- (strategy) => strategy === hydrationStrategies[0]
5898
- ) ? hydrationStrategies[0] ?? "load" : "load";
6388
+ const hydrationIslandStrategy = this.islandValues() ? resolveFarmRouteRootStrategy(
6389
+ route,
6390
+ { shouldHydrate, islandStrategy: moduleMetadata.islandStrategy ?? null },
6391
+ layouts.map((layout, index) => ({
6392
+ pattern: layout.pattern,
6393
+ modulePath: layout.modulePath,
6394
+ shouldHydrate: layoutHydrationMetadata[index]?.shouldHydrate === true,
6395
+ hasIsolatedClientBoundaries: layoutHydrationMetadata[index]?.hasIsolatedClientBoundaries === true,
6396
+ islandStrategy: layoutHydrationMetadata[index]?.islandStrategy ?? null
6397
+ })),
6398
+ this.config.root || process.cwd(),
6399
+ true
6400
+ ) : hydrationStrategies.every((strategy) => strategy === hydrationStrategies[0]) ? hydrationStrategies[0] ?? "load" : "load";
5899
6401
  const hasHydratableRouteSlots = renderedRouteSlots.some(
5900
6402
  (slot) => slot.isClientComponent || slot.shouldHydrate
5901
6403
  );
@@ -5992,11 +6494,22 @@ var ServerRenderer = class {
5992
6494
  layoutShouldHydrate: shouldHydrateLayout,
5993
6495
  islandStrategy: hydrationIslandStrategy
5994
6496
  });
6497
+ const islandsSegments = Boolean(islands && this.islandValues());
6498
+ const keptLayoutCount = islandsSegments && !renderingConfig.ssg && !shouldHydrateLayout && renderedRouteSlots.length === 0 ? countFarmKeptLayouts(requestHeader(req, "f-layouts"), layouts, params) : 0;
6499
+ const keptLayouts = keptLayoutCount > 1 ? keptLayoutCount : 0;
5995
6500
  let wrappedElement = pageElement;
5996
6501
  for (let i = layoutModules.length - 1; i >= 0; i--) {
5997
6502
  const layoutModule = layoutModules[i];
5998
6503
  const layoutEntry = layouts[i];
5999
6504
  const LayoutComponent = layoutModule.default;
6505
+ const segment = islandsSegments && !shouldHydrateLayout ? { key: getFarmLayoutKey(layoutEntry.pattern, params) } : void 0;
6506
+ if (LayoutComponent && i > 0 && i < keptLayouts) {
6507
+ wrappedElement = this.createLayoutBoundary(layoutEntry.pattern, wrappedElement, {
6508
+ key: segment.key,
6509
+ kept: true
6510
+ });
6511
+ continue;
6512
+ }
6000
6513
  const slotProps = {};
6001
6514
  for (const slot of renderedRouteSlots) {
6002
6515
  if ((slot.ownerDirectory ?? slot.ownerPattern) !== layoutEntry.pattern) continue;
@@ -6026,7 +6539,11 @@ var ServerRenderer = class {
6026
6539
  params,
6027
6540
  ...slotProps
6028
6541
  });
6029
- wrappedElement = this.createLayoutBoundary(layoutEntry.pattern, wrappedElement);
6542
+ wrappedElement = this.createLayoutBoundary(
6543
+ layoutEntry.pattern,
6544
+ wrappedElement,
6545
+ segment
6546
+ );
6030
6547
  }
6031
6548
  if (shouldHydrateLayout) {
6032
6549
  wrappedElement = this.wrapClientGraph(wrappedElement);
@@ -6204,11 +6721,11 @@ var ServerRenderer = class {
6204
6721
  if (isFarmIntegrationProviderComponentReference(provider.component)) {
6205
6722
  providerSourceModule = provider.component.module;
6206
6723
  const providerModuleId = provider.component.module.startsWith(".") ? toViteModuleId(
6207
- path10.resolve(this.config.root, provider.component.module),
6724
+ path12.resolve(this.config.root, provider.component.module),
6208
6725
  this.config.root
6209
6726
  ) : provider.component.module;
6210
6727
  const providerModule = this.viteServer ? await loadFarmDevModule(this.viteServer, providerModuleId) : await importRuntimeModule(
6211
- provider.component.module.startsWith(".") ? pathToFileURL2(path10.resolve(this.config.root, provider.component.module)).href : provider.component.module
6728
+ provider.component.module.startsWith(".") ? pathToFileURL2(path12.resolve(this.config.root, provider.component.module)).href : provider.component.module
6212
6729
  );
6213
6730
  ProviderComponent = providerModule[provider.component.export || "default"];
6214
6731
  } else if (typeof provider.component === "function") {
@@ -6475,7 +6992,7 @@ var ServerRenderer = class {
6475
6992
  logger.warn(`Could not read metadata for ${pattern} in sitemap.xml: ${error}`);
6476
6993
  return void 0;
6477
6994
  }),
6478
- fs6.promises.stat(route.modulePath).catch(() => void 0)
6995
+ fs8.promises.stat(route.modulePath).catch(() => void 0)
6479
6996
  ]);
6480
6997
  return { pattern, module, lastModified: stat?.mtime.toISOString() };
6481
6998
  })
@@ -6541,7 +7058,7 @@ var ServerRenderer = class {
6541
7058
  const server = this.getDefaultMCPServer();
6542
7059
  const request2 = getCurrentRequestOrNull() ?? createWebRequestFromFarmRequest(req, { trustProxy: this.config.server?.trustProxy });
6543
7060
  try {
6544
- const { handleFarmDefaultMCPRequest } = await import("./agent-mcp-handler-7JSKGSOW.mjs");
7061
+ const { handleFarmDefaultMCPRequest } = await import("./agent-mcp-handler-7QMX2LUY.mjs");
6545
7062
  const origin = new URL(request2.url).origin;
6546
7063
  const response = await handleFarmDefaultMCPRequest(request2, {
6547
7064
  server,
@@ -6726,7 +7243,7 @@ var ServerRenderer = class {
6726
7243
  res.end();
6727
7244
  return;
6728
7245
  }
6729
- res.write(await fs6.promises.readFile(image.modulePath));
7246
+ res.write(await fs8.promises.readFile(image.modulePath));
6730
7247
  res.end();
6731
7248
  }
6732
7249
  async renderRouteErrorBoundary(req, res, options) {
@@ -7048,6 +7565,18 @@ window.__FARM_I18N__ = ${getFarmI18nClientSnapshot() ? serializeInlineValue(getF
7048
7565
  for (const [key, value] of Object.entries(options.responseHeaders || {})) {
7049
7566
  res.setHeader(key, value);
7050
7567
  }
7568
+ const islandsMode = Boolean(islands && this.islandValues());
7569
+ const flushToken = islandsMode && requestHeader(req, "f-stream") === "flush" ? createFarmFlushToken() : "";
7570
+ const flushMarker = flushToken ? Buffer.from(farmFlushMarker(flushToken)) : void 0;
7571
+ if (islandsMode) {
7572
+ for (const name of ["F-Values", "F-Layouts", "F-Render", "F-Stream"]) {
7573
+ appendResponseVary(res, name);
7574
+ }
7575
+ if (requestHeader(req, "f-layouts") || flushToken) {
7576
+ res.setHeader("Cache-Control", "private, no-store");
7577
+ }
7578
+ if (flushToken) res.setHeader("F-Flush", flushToken);
7579
+ }
7051
7580
  const htmlParts = [];
7052
7581
  const findStaticShellBoundary = this.rendererRuntime.findStaticShellBoundary;
7053
7582
  const staticShellParts = options.captureStaticShell && findStaticShellBoundary ? [] : void 0;
@@ -7143,7 +7672,11 @@ window.__FARM_MANIFEST__ = ${JSON.stringify(clientManifest)};
7143
7672
  window.__FARM_INTEGRATION_API_MANIFEST__ = ${JSON.stringify(getRegisteredIntegrationAPIManifest())};
7144
7673
  window.__FARM_I18N__ = ${getFarmI18nClientSnapshot() ? serializeInlineValue(getFarmI18nClientSnapshot()) : "null"};
7145
7674
  </script>`;
7146
- const hydrationClickQueueScript = isClientComponent || req.__FARM_SHOULD_HYDRATE__ === true || req.__FARM_HAS_HYDRATABLE_ROUTE_SLOTS__ === true ? createPreHydrationClickQueueScript() : "";
7675
+ const islandsOnlyPage = this.islandValues() && req.__FARM_PAGE_SHOULD_HYDRATE__ !== true && req.__FARM_LAYOUT_SHOULD_HYDRATE__ !== true && req.__FARM_HAS_HYDRATABLE_ROUTE_SLOTS__ !== true;
7676
+ const rootStrategy = req.__FARM_ISLAND_STRATEGY__;
7677
+ const waitingRoot = this.islandValues() && !islandsOnlyPage && req.__FARM_HAS_HYDRATABLE_ROUTE_SLOTS__ !== true && rootStrategy !== void 0 && rootStrategy !== "load" ? req.__FARM_LAYOUT_SHOULD_HYDRATE__ === true ? "root" : "__farm_page__" : null;
7678
+ const bootClient = (islandsOnlyPage || waitingRoot !== null) && !staticShellParts && canBootFarmIslandsClient(this.config);
7679
+ const hydrationClickQueueScript = !islandsOnlyPage && !bootClient && (isClientComponent || req.__FARM_SHOULD_HYDRATE__ === true || req.__FARM_HAS_HYDRATABLE_ROUTE_SLOTS__ === true) ? createPreHydrationClickQueueScript() : "";
7147
7680
  const {
7148
7681
  title,
7149
7682
  tags: metaTags,
@@ -7174,6 +7707,7 @@ window.__FARM_I18N__ = ${getFarmI18nClientSnapshot() ? serializeInlineValue(getF
7174
7707
  const filterDocumentHTML = (html) => cspNonce ? filterFarmCspNonces(html, cspNonce) : html;
7175
7708
  const createLateNavigationRecovery = (navigationError) => this.createLateNavigationRecoveryHTML(req, navigationError);
7176
7709
  const earlyClient = this.islandValues();
7710
+ const earlyClientScript = bootClient ? createFarmDevBootScript(waitingRoot, rootStrategy) : FARM_DEV_EARLY_CLIENT_SCRIPT;
7177
7711
  const { pipe, abort } = renderToPipeableStream(streamRoot, {
7178
7712
  nonce: cspNonce,
7179
7713
  onShellReady() {
@@ -7212,7 +7746,7 @@ window.__FARM_I18N__ = ${getFarmI18nClientSnapshot() ? serializeInlineValue(getF
7212
7746
  ${hydrationClickQueueScript}
7213
7747
  </head>
7214
7748
  <body class="">${earlyClient ? `
7215
- ${FARM_DEV_EARLY_CLIENT_SCRIPT}` : ""}
7749
+ ${earlyClientScript}` : ""}
7216
7750
  <div id="root">`;
7217
7751
  const securedShell = streamDocument ? "" : stampDocumentHTML(shell);
7218
7752
  if (securedShell) {
@@ -7224,7 +7758,7 @@ window.__FARM_I18N__ = ${getFarmI18nClientSnapshot() ? serializeInlineValue(getF
7224
7758
  html: document.html.replace(
7225
7759
  /<body\b[^>]*>/i,
7226
7760
  (open) => `${open}
7227
- ${stampDocumentHTML(FARM_DEV_EARLY_CLIENT_SCRIPT)}`
7761
+ ${stampDocumentHTML(earlyClientScript)}`
7228
7762
  )
7229
7763
  } : document;
7230
7764
  const documentTransform = streamDocument ? createFarmStreamedDocumentTransform(
@@ -7297,6 +7831,14 @@ window.__FARM_I18N__ = ${getFarmI18nClientSnapshot() ? serializeInlineValue(getF
7297
7831
  };
7298
7832
  const writableStream = new Writable({
7299
7833
  write(chunk, encoding, callback) {
7834
+ if (flushMarker && chunk === flushMarker) {
7835
+ const marker = documentTransform ? documentTransform.write(flushMarker.toString()) : flushMarker;
7836
+ res.write(marker, () => {
7837
+ if (typeof res.flush === "function") res.flush();
7838
+ callback();
7839
+ });
7840
+ return;
7841
+ }
7300
7842
  if (firstChunk && process.env.FARM_VERBOSE) {
7301
7843
  console.log(`[FARM STREAM] first pipe chunk at ${Date.now() - streamStartTime}ms`);
7302
7844
  firstChunk = false;
@@ -7392,6 +7934,7 @@ window.__FARM_I18N__ = ${getFarmI18nClientSnapshot() ? serializeInlineValue(getF
7392
7934
  if (typeof res.flush === "function") {
7393
7935
  res.flush();
7394
7936
  }
7937
+ if (flushMarker) writableStream.flush = () => writableStream.write(flushMarker);
7395
7938
  pipe(writableStream);
7396
7939
  },
7397
7940
  onShellError(error) {
@@ -7521,13 +8064,13 @@ window.__FARM_I18N__ = ${getFarmI18nClientSnapshot() ? serializeInlineValue(getF
7521
8064
  res.end(createFarmMarkdownErrorBody(404, pathname, this.config.basePath || "/"));
7522
8065
  return;
7523
8066
  }
7524
- const appDir = path10.join(this.config.root, this.config.srcDir, "app");
8067
+ const appDir = path12.join(this.config.root, this.config.srcDir, "app");
7525
8068
  const notFoundExtensions = getFarmRendererComponentExtensions(this.config.renderer);
7526
8069
  let layoutModule = null;
7527
8070
  try {
7528
8071
  for (const ext of notFoundExtensions) {
7529
- const layoutPath = path10.join(appDir, `layout${ext}`);
7530
- if (fs6.existsSync(layoutPath)) {
8072
+ const layoutPath = path12.join(appDir, `layout${ext}`);
8073
+ if (fs8.existsSync(layoutPath)) {
7531
8074
  layoutModule = await this.routeManager.loadLayoutModule(layoutPath);
7532
8075
  break;
7533
8076
  }
@@ -7740,7 +8283,7 @@ ${clientScript}
7740
8283
  };
7741
8284
 
7742
8285
  // src/app.ts
7743
- import path11 from "path";
8286
+ import path13 from "path";
7744
8287
  var defaultDocsConfig = {
7745
8288
  enabled: false,
7746
8289
  entry: "/docs",
@@ -7880,7 +8423,7 @@ var FarmApp = class {
7880
8423
  }
7881
8424
  const componentExtensions = getFarmRendererComponentExtensions(this.config.renderer);
7882
8425
  const rootLayoutPaths = appDirs.flatMap(
7883
- (appDir) => componentExtensions.map((extension) => path11.join(appDir, `layout${extension}`))
8426
+ (appDir) => componentExtensions.map((extension) => path13.join(appDir, `layout${extension}`))
7884
8427
  );
7885
8428
  const hasRootLayout = await Promise.all(rootLayoutPaths.map((p) => fileExists(p))).then(
7886
8429
  (results) => results.some(Boolean)
@@ -7944,13 +8487,13 @@ function resolveFarmImageServerRuntime(images, preset) {
7944
8487
  }
7945
8488
 
7946
8489
  // src/app-manifest-packages.ts
7947
- import fs7 from "fs";
7948
- import path12 from "path";
8490
+ import fs9 from "fs";
8491
+ import path14 from "path";
7949
8492
  var FARM_PACKAGE = /^@(?:farm\.js|farming-labs)\/[a-z0-9._-]+$/;
7950
8493
  function resolveFarmAppPackages(root) {
7951
8494
  let manifest;
7952
8495
  try {
7953
- manifest = JSON.parse(fs7.readFileSync(path12.join(root, "package.json"), "utf8"));
8496
+ manifest = JSON.parse(fs9.readFileSync(path14.join(root, "package.json"), "utf8"));
7954
8497
  } catch {
7955
8498
  return {};
7956
8499
  }
@@ -7965,13 +8508,13 @@ function resolveFarmAppPackages(root) {
7965
8508
  for (let dir = root; ; ) {
7966
8509
  try {
7967
8510
  const { version } = JSON.parse(
7968
- fs7.readFileSync(path12.join(dir, "node_modules", name, "package.json"), "utf8")
8511
+ fs9.readFileSync(path14.join(dir, "node_modules", name, "package.json"), "utf8")
7969
8512
  );
7970
8513
  if (typeof version === "string" && /^[0-9A-Za-z.+-]{1,64}$/.test(version))
7971
8514
  versions[name] = version;
7972
8515
  break;
7973
8516
  } catch {
7974
- const parent = path12.dirname(dir);
8517
+ const parent = path14.dirname(dir);
7975
8518
  if (parent === dir) break;
7976
8519
  dir = parent;
7977
8520
  }
@@ -7981,9 +8524,9 @@ function resolveFarmAppPackages(root) {
7981
8524
  }
7982
8525
 
7983
8526
  // src/app-manifest-webmcp.ts
7984
- import fs8 from "fs";
8527
+ import fs10 from "fs";
7985
8528
  import { createRequire as createRequire2 } from "module";
7986
- import path13 from "path";
8529
+ import path15 from "path";
7987
8530
  import { globSync } from "tinyglobby";
7988
8531
  var WEBMCP_CLIENT = "@farm.js/webmcp/client";
7989
8532
  var DEFINERS = /* @__PURE__ */ new Set(["defineWebMCPTool", "registerWebMCPTool", "registerWebMCPTools"]);
@@ -8001,7 +8544,7 @@ var LANGS = {
8001
8544
  cjs: "jsx",
8002
8545
  jsx: "jsx"
8003
8546
  };
8004
- var parseAst;
8547
+ var parseAst2;
8005
8548
  function staticValue(node) {
8006
8549
  if (!node) return NOT_STATIC;
8007
8550
  switch (node.type) {
@@ -8034,406 +8577,140 @@ function staticValue(node) {
8034
8577
  object[key] = value;
8035
8578
  }
8036
8579
  return object;
8037
- }
8038
- case "TSAsExpression":
8039
- case "TSSatisfiesExpression":
8040
- case "TSNonNullExpression":
8041
- case "ParenthesizedExpression":
8042
- return staticValue(node.expression);
8043
- default:
8044
- return NOT_STATIC;
8045
- }
8046
- }
8047
- function property(object, name) {
8048
- return object.properties.find(
8049
- (entry) => entry.type === "Property" && !entry.computed && (entry.key.name === name || entry.key.value === name)
8050
- )?.value;
8051
- }
8052
- function toolFromObject(object) {
8053
- const name = staticValue(property(object, "name"));
8054
- if (typeof name !== "string" || !/^[A-Za-z0-9_.-]{1,128}$/.test(name)) return null;
8055
- const text = (key) => {
8056
- const value = staticValue(property(object, key));
8057
- return typeof value === "string" && value.length <= 2e3 ? value : void 0;
8058
- };
8059
- const annotations = staticValue(property(object, "annotations"));
8060
- const hints = annotations && typeof annotations === "object" && !Array.isArray(annotations) ? Object.fromEntries(
8061
- HINTS.filter(
8062
- (hint) => typeof annotations[hint] === "boolean"
8063
- ).map((hint) => [hint, annotations[hint]])
8064
- ) : {};
8065
- const schemaNode = property(object, "inputSchema");
8066
- const schema = staticValue(schemaNode);
8067
- const literal = schema !== NOT_STATIC && schema !== null && typeof schema === "object" && !Array.isArray(schema) && Buffer.byteLength(JSON.stringify(schema)) <= MAX_SCHEMA_BYTES;
8068
- const title = text("title");
8069
- const description = text("description");
8070
- return {
8071
- name,
8072
- ...title ? { title } : {},
8073
- ...description ? { description } : {},
8074
- ...hints,
8075
- ...literal ? { inputSchema: schema } : {},
8076
- inputSchemaSource: literal ? "literal" : schemaNode ? "computed" : "none"
8077
- };
8078
- }
8079
- function findFarmWebMCPTools(code, filename = "module.tsx") {
8080
- if (!code.includes(WEBMCP_CLIENT)) return [];
8081
- const lang = LANGS[path13.extname(filename).slice(1)] ?? "tsx";
8082
- parseAst ?? (parseAst = createRequire2(typeof __filename === "string" ? __filename : import.meta.url)(
8083
- "rolldown/parseAst"
8084
- ).parseAst);
8085
- let program;
8086
- try {
8087
- program = parseAst(code, { lang });
8088
- } catch {
8089
- return [];
8090
- }
8091
- const locals = /* @__PURE__ */ new Map();
8092
- for (const statement of program.body) {
8093
- if (statement.type !== "ImportDeclaration" || statement.source.value !== WEBMCP_CLIENT)
8094
- continue;
8095
- for (const specifier of statement.specifiers) {
8096
- const imported = specifier.imported?.name ?? specifier.imported?.value;
8097
- if (specifier.type === "ImportSpecifier" && DEFINERS.has(imported))
8098
- locals.set(specifier.local.name, imported);
8099
- }
8100
- }
8101
- if (!locals.size) return [];
8102
- const found = [];
8103
- const visit = (node) => {
8104
- if (!node || typeof node !== "object") return;
8105
- if (Array.isArray(node)) return node.forEach(visit);
8106
- const current = node;
8107
- if (current.type === "CallExpression" && current.callee.type === "Identifier") {
8108
- const definer = locals.get(current.callee.name);
8109
- const [argument] = current.arguments;
8110
- if (definer && argument) {
8111
- const objects = definer === "registerWebMCPTools" ? argument.type === "ArrayExpression" ? argument.elements.filter(
8112
- (element) => element?.type === "ObjectExpression"
8113
- ) : [] : argument.type === "ObjectExpression" ? [argument] : [];
8114
- for (const object of objects) {
8115
- const tool = toolFromObject(object);
8116
- if (tool) found.push({ start: object.start, tool });
8117
- }
8118
- }
8119
- }
8120
- for (const [key, value] of Object.entries(current))
8121
- if (key !== "type" && value && typeof value === "object") visit(value);
8122
- };
8123
- visit(program.body);
8124
- return found.sort((a, b) => a.start - b.start).map(({ tool }) => tool);
8125
- }
8126
- var cache = /* @__PURE__ */ new Map();
8127
- function collectFarmWebMCPTools(root, srcDir = "src") {
8128
- const base = path13.resolve(root, srcDir);
8129
- let files;
8130
- try {
8131
- files = globSync("**/*.{ts,tsx,js,jsx,mts,mjs,cts,cjs}", {
8132
- cwd: base,
8133
- absolute: true,
8134
- expandDirectories: false,
8135
- ignore: ["**/node_modules/**", "**/*.d.ts", "**/*.{test,spec}.*", "**/__tests__/**"]
8136
- });
8137
- } catch {
8138
- return [];
8139
- }
8140
- const seen = /* @__PURE__ */ new Set();
8141
- const tools = [];
8142
- for (const file of files.sort()) {
8143
- let mtimeMs;
8144
- try {
8145
- mtimeMs = fs8.statSync(file).mtimeMs;
8146
- } catch {
8147
- continue;
8148
- }
8149
- let entry = cache.get(file);
8150
- if (!entry || entry.mtimeMs !== mtimeMs) {
8151
- let code = "";
8152
- try {
8153
- code = fs8.readFileSync(file, "utf8");
8154
- } catch {
8155
- }
8156
- entry = { mtimeMs, tools: findFarmWebMCPTools(code, file) };
8157
- cache.set(file, entry);
8158
- }
8159
- for (const tool of entry.tools) {
8160
- if (seen.has(tool.name) || tools.length >= MAX_TOOLS) continue;
8161
- seen.add(tool.name);
8162
- tools.push(tool);
8163
- }
8164
- }
8165
- return tools;
8166
- }
8167
-
8168
- // src/client-plugin-build.ts
8169
- import fs9 from "fs";
8170
- import path14 from "path";
8171
- var CLIENT_KEYS = [
8172
- "public",
8173
- "setup",
8174
- "hydration",
8175
- "navigation",
8176
- "error",
8177
- "performance",
8178
- "close"
8179
- ];
8180
- var HYDRATION_KEYS = ["before", "after"];
8181
- var NAVIGATION_KEYS = ["before", "loaded", "resolved", "rendered", "error"];
8182
- var MOBILE_SHELL_CLIENT_IMPORT = 'import { farmMobileShellClient as __farmMobileShellClient } from "@farm.js/core/internal/client-runtime";';
8183
- var MOBILE_SHELL_CLIENT_REGISTRATION = ` {
8184
- name: "farm:mobile-shell",
8185
- enforce: "pre",
8186
- definition: __farmMobileShellClient,
8187
- }`;
8188
- var APP_CLIENT_EXTENSIONS = ["ts", "tsx", "js", "jsx", "mts", "mjs"];
8189
- function resolveFarmAppClientEntry(root = process.cwd(), srcDir = "src") {
8190
- const sourceRoot = path14.resolve(root, srcDir);
8191
- for (const extension of APP_CLIENT_EXTENSIONS) {
8192
- const candidate = path14.join(sourceRoot, `client.${extension}`);
8193
- if (fs9.existsSync(candidate) && fs9.statSync(candidate).isFile()) return candidate;
8194
- }
8195
- return void 0;
8196
- }
8197
- function resolveFarmClientPlugins(plugins, _root) {
8198
- if (!plugins?.length) return [];
8199
- return plugins.flatMap((plugin) => {
8200
- if (!plugin.client) return [];
8201
- assertClientLifecycle(plugin.client, plugin.name);
8202
- assertPublicData(plugin.client.public, plugin.name);
8203
- return [
8204
- {
8205
- name: plugin.name,
8206
- version: plugin.version,
8207
- enforce: plugin.enforce,
8208
- definition: plugin.client,
8209
- publicData: plugin.client.public
8210
- }
8211
- ];
8212
- });
8213
- }
8214
- function generateFarmClientPluginEntryCode(plugins, root, srcDir = "src", appPublicData, platform = resolveFarmPlatform()) {
8215
- const resolved = resolveFarmClientPlugins(plugins, root);
8216
- const appClientEntry = root ? resolveFarmAppClientEntry(root, srcDir) : void 0;
8217
- const appImport = appClientEntry ? `import farmAppClientDefinition from ${JSON.stringify(appClientEntry.replace(/\\/g, "/"))};` : "";
8218
- const mobileShell = platform === "mobile";
8219
- const imports = mobileShell ? [MOBILE_SHELL_CLIENT_IMPORT, appImport].filter(Boolean).join("\n") : appImport;
8220
- const serializedPlugins = mobileShell ? [MOBILE_SHELL_CLIENT_REGISTRATION] : [];
8221
- serializedPlugins.push(
8222
- ...resolved.map(
8223
- (plugin) => ` {
8224
- name: ${JSON.stringify(plugin.name)},
8225
- version: ${serializeOptionalString(plugin.version)},
8226
- enforce: ${serializeOptionalString(plugin.enforce)},
8227
- definition: ${serializeClientLifecycle(plugin.definition, plugin.name)},
8228
- public: ${serializePublicData(plugin.publicData)},
8229
- }`
8230
- )
8231
- );
8232
- if (appClientEntry) {
8233
- assertPublicData(appPublicData, "farm:app-client");
8234
- serializedPlugins.push(` {
8235
- name: "farm:app-client",
8236
- enforce: "post",
8237
- definition: farmAppClientDefinition,
8238
- public: ${serializePublicData(appPublicData)},
8239
- }`);
8240
- }
8241
- const registrations = `[
8242
- ${serializedPlugins.join(",\n")}
8243
- ]`;
8244
- return { imports, registrations, plugins: resolved };
8245
- }
8246
- function assertClientLifecycle(client, pluginName) {
8247
- assertLifecycleObject(client, pluginName, "client", CLIENT_KEYS);
8248
- assertHook(client.setup, pluginName, "client.setup");
8249
- assertHook(client.error, pluginName, "client.error");
8250
- assertHook(client.performance, pluginName, "client.performance");
8251
- assertHook(client.close, pluginName, "client.close");
8252
- if (client.hydration !== void 0) {
8253
- assertLifecycleObject(client.hydration, pluginName, "client.hydration", HYDRATION_KEYS);
8254
- assertHook(client.hydration.before, pluginName, "client.hydration.before");
8255
- assertHook(client.hydration.after, pluginName, "client.hydration.after");
8256
- }
8257
- if (client.navigation !== void 0) {
8258
- assertLifecycleObject(client.navigation, pluginName, "client.navigation", NAVIGATION_KEYS);
8259
- for (const key of NAVIGATION_KEYS) {
8260
- assertHook(client.navigation[key], pluginName, `client.navigation.${key}`);
8261
- }
8262
- }
8263
- }
8264
- function assertLifecycleObject(value, pluginName, location, allowedKeys) {
8265
- if (!value || typeof value !== "object" || Array.isArray(value)) {
8266
- throw new TypeError(`Client plugin "${pluginName}" ${location} must be an object`);
8267
- }
8268
- const prototype = Object.getPrototypeOf(value);
8269
- if (prototype !== Object.prototype && prototype !== null) {
8270
- throw new TypeError(`Client plugin "${pluginName}" ${location} must be a plain object`);
8271
- }
8272
- for (const key of Reflect.ownKeys(value)) {
8273
- if (typeof key === "symbol") {
8274
- throw new TypeError(`Client plugin "${pluginName}" ${location} cannot contain symbol keys`);
8275
- }
8276
- if (!allowedKeys.includes(key)) {
8277
- throw new TypeError(`Client plugin "${pluginName}" has an unknown ${location}.${key} option`);
8278
- }
8279
- const descriptor = Object.getOwnPropertyDescriptor(value, key);
8280
- if (!descriptor?.enumerable) {
8281
- throw new TypeError(`Client plugin "${pluginName}" ${location}.${key} must be enumerable`);
8282
- }
8283
- if (!("value" in descriptor)) {
8284
- throw new TypeError(`Client plugin "${pluginName}" ${location}.${key} cannot be an accessor`);
8285
- }
8286
- }
8287
- }
8288
- function assertHook(value, pluginName, location) {
8289
- if (value === void 0) return;
8290
- if (typeof value !== "function") {
8291
- throw new TypeError(`Client plugin "${pluginName}" ${location} must be a function`);
8580
+ }
8581
+ case "TSAsExpression":
8582
+ case "TSSatisfiesExpression":
8583
+ case "TSNonNullExpression":
8584
+ case "ParenthesizedExpression":
8585
+ return staticValue(node.expression);
8586
+ default:
8587
+ return NOT_STATIC;
8292
8588
  }
8293
- functionSource(value, pluginName, location);
8294
- }
8295
- function serializeClientLifecycle(definition, pluginName) {
8296
- const fields = [];
8297
- pushHook(fields, "setup", definition.setup, pluginName, "client.setup", 2);
8298
- pushHookGroup(fields, "hydration", definition.hydration, HYDRATION_KEYS, pluginName, 2);
8299
- pushHookGroup(fields, "navigation", definition.navigation, NAVIGATION_KEYS, pluginName, 2);
8300
- pushHook(fields, "error", definition.error, pluginName, "client.error", 2);
8301
- pushHook(fields, "performance", definition.performance, pluginName, "client.performance", 2);
8302
- pushHook(fields, "close", definition.close, pluginName, "client.close", 2);
8303
- return fields.length ? `{
8304
- ${fields.join(",\n")}
8305
- }` : "{}";
8306
8589
  }
8307
- function pushHookGroup(fields, groupName, group, keys, pluginName, indent) {
8308
- if (!group) return;
8309
- const hooks = [];
8310
- for (const key of keys) {
8311
- pushHook(hooks, key, group[key], pluginName, `client.${groupName}.${key}`, indent + 2);
8312
- }
8313
- fields.push(
8314
- `${" ".repeat(indent)}${JSON.stringify(groupName)}: {
8315
- ${hooks.join(",\n")}
8316
- ${" ".repeat(indent)}}`
8317
- );
8590
+ function property(object, name) {
8591
+ return object.properties.find(
8592
+ (entry) => entry.type === "Property" && !entry.computed && (entry.key.name === name || entry.key.value === name)
8593
+ )?.value;
8318
8594
  }
8319
- function pushHook(fields, key, hook, pluginName, location, indent) {
8320
- if (hook === void 0) return;
8321
- fields.push(
8322
- `${" ".repeat(indent)}${JSON.stringify(key)}: ${functionSource(hook, pluginName, location)}`
8323
- );
8595
+ function toolFromObject(object) {
8596
+ const name = staticValue(property(object, "name"));
8597
+ if (typeof name !== "string" || !/^[A-Za-z0-9_.-]{1,128}$/.test(name)) return null;
8598
+ const text = (key) => {
8599
+ const value = staticValue(property(object, key));
8600
+ return typeof value === "string" && value.length <= 2e3 ? value : void 0;
8601
+ };
8602
+ const annotations = staticValue(property(object, "annotations"));
8603
+ const hints = annotations && typeof annotations === "object" && !Array.isArray(annotations) ? Object.fromEntries(
8604
+ HINTS.filter(
8605
+ (hint) => typeof annotations[hint] === "boolean"
8606
+ ).map((hint) => [hint, annotations[hint]])
8607
+ ) : {};
8608
+ const schemaNode = property(object, "inputSchema");
8609
+ const schema = staticValue(schemaNode);
8610
+ const literal = schema !== NOT_STATIC && schema !== null && typeof schema === "object" && !Array.isArray(schema) && Buffer.byteLength(JSON.stringify(schema)) <= MAX_SCHEMA_BYTES;
8611
+ const title = text("title");
8612
+ const description = text("description");
8613
+ return {
8614
+ name,
8615
+ ...title ? { title } : {},
8616
+ ...description ? { description } : {},
8617
+ ...hints,
8618
+ ...literal ? { inputSchema: schema } : {},
8619
+ inputSchemaSource: literal ? "literal" : schemaNode ? "computed" : "none"
8620
+ };
8324
8621
  }
8325
- function functionSource(value, pluginName, location) {
8326
- if (typeof value !== "function") {
8327
- throw new TypeError(`Client plugin "${pluginName}" ${location} must be a function`);
8328
- }
8329
- const source = Function.prototype.toString.call(value).trim();
8330
- if (!source || source.includes("[native code]")) {
8331
- throw new TypeError(
8332
- `Client plugin "${pluginName}" ${location} must be authored inline and cannot be native or bound`
8333
- );
8334
- }
8335
- if (/^(?:async\s+)?function(?:\s*\*)?(?:\s+|\()/.test(source)) {
8336
- return `(${source})`;
8337
- }
8338
- const method = source.match(/^(async\s+)?(\*\s*)?[$A-Z_a-z][$\w]*\s*(\([\s\S]*)$/);
8339
- if (method) {
8340
- const asyncPrefix = method[1] ?? "";
8341
- const generator = method[2] ? "*" : "";
8342
- return `(${asyncPrefix}function${generator}${method[3]})`;
8622
+ function findFarmWebMCPTools(code, filename = "module.tsx") {
8623
+ if (!code.includes(WEBMCP_CLIENT)) return [];
8624
+ const lang = LANGS[path15.extname(filename).slice(1)] ?? "tsx";
8625
+ parseAst2 ?? (parseAst2 = createRequire2(typeof __filename === "string" ? __filename : import.meta.url)(
8626
+ "rolldown/parseAst"
8627
+ ).parseAst);
8628
+ let program;
8629
+ try {
8630
+ program = parseAst2(code, { lang });
8631
+ } catch {
8632
+ return [];
8343
8633
  }
8344
- if (source.includes("=>")) return `(${source})`;
8345
- throw new TypeError(
8346
- `Client plugin "${pluginName}" ${location} must use a function, method, or arrow function`
8347
- );
8348
- }
8349
- function assertPublicData(value, pluginName) {
8350
- if (value === void 0) return;
8351
- const seen = /* @__PURE__ */ new WeakSet();
8352
- const visit = (current, pathSegments) => {
8353
- if (current === null || typeof current === "string" || typeof current === "boolean") {
8354
- return;
8355
- }
8356
- if (typeof current === "number") {
8357
- if (Number.isFinite(current)) return;
8358
- throwPublicDataError(pluginName, pathSegments, "must be a finite number");
8359
- }
8360
- if (typeof current !== "object") {
8361
- throwPublicDataError(pluginName, pathSegments, `cannot contain ${typeof current} values`);
8362
- }
8363
- if (seen.has(current)) {
8364
- throwPublicDataError(pluginName, pathSegments, "cannot contain circular references");
8634
+ const locals = /* @__PURE__ */ new Map();
8635
+ for (const statement of program.body) {
8636
+ if (statement.type !== "ImportDeclaration" || statement.source.value !== WEBMCP_CLIENT)
8637
+ continue;
8638
+ for (const specifier of statement.specifiers) {
8639
+ const imported = specifier.imported?.name ?? specifier.imported?.value;
8640
+ if (specifier.type === "ImportSpecifier" && DEFINERS.has(imported))
8641
+ locals.set(specifier.local.name, imported);
8365
8642
  }
8366
- seen.add(current);
8367
- if (Array.isArray(current)) {
8368
- for (let index = 0; index < current.length; index += 1) {
8369
- if (!Object.prototype.hasOwnProperty.call(current, index)) {
8370
- throwPublicDataError(
8371
- pluginName,
8372
- [...pathSegments, String(index)],
8373
- "cannot contain sparse array slots"
8374
- );
8643
+ }
8644
+ if (!locals.size) return [];
8645
+ const found = [];
8646
+ const visit = (node) => {
8647
+ if (!node || typeof node !== "object") return;
8648
+ if (Array.isArray(node)) return node.forEach(visit);
8649
+ const current = node;
8650
+ if (current.type === "CallExpression" && current.callee.type === "Identifier") {
8651
+ const definer = locals.get(current.callee.name);
8652
+ const [argument] = current.arguments;
8653
+ if (definer && argument) {
8654
+ const objects = definer === "registerWebMCPTools" ? argument.type === "ArrayExpression" ? argument.elements.filter(
8655
+ (element) => element?.type === "ObjectExpression"
8656
+ ) : [] : argument.type === "ObjectExpression" ? [argument] : [];
8657
+ for (const object of objects) {
8658
+ const tool = toolFromObject(object);
8659
+ if (tool) found.push({ start: object.start, tool });
8375
8660
  }
8376
- visit(current[index], [...pathSegments, String(index)]);
8377
- }
8378
- for (const key of Reflect.ownKeys(current)) {
8379
- if (key === "length" || typeof key === "string" && isArrayIndex(key)) continue;
8380
- throwPublicDataError(
8381
- pluginName,
8382
- pathSegments,
8383
- typeof key === "symbol" ? "cannot contain symbol keys" : `cannot contain non-index array property ${key}`
8384
- );
8385
8661
  }
8386
- seen.delete(current);
8387
- return;
8388
8662
  }
8389
- const prototype = Object.getPrototypeOf(current);
8390
- if (prototype !== Object.prototype && prototype !== null) {
8391
- throwPublicDataError(pluginName, pathSegments, "must contain only plain objects and arrays");
8663
+ for (const [key, value] of Object.entries(current))
8664
+ if (key !== "type" && value && typeof value === "object") visit(value);
8665
+ };
8666
+ visit(program.body);
8667
+ return found.sort((a, b) => a.start - b.start).map(({ tool }) => tool);
8668
+ }
8669
+ var cache = /* @__PURE__ */ new Map();
8670
+ function collectFarmWebMCPTools(root, srcDir = "src") {
8671
+ const base = path15.resolve(root, srcDir);
8672
+ let files;
8673
+ try {
8674
+ files = globSync("**/*.{ts,tsx,js,jsx,mts,mjs,cts,cjs}", {
8675
+ cwd: base,
8676
+ absolute: true,
8677
+ expandDirectories: false,
8678
+ ignore: ["**/node_modules/**", "**/*.d.ts", "**/*.{test,spec}.*", "**/__tests__/**"]
8679
+ });
8680
+ } catch {
8681
+ return [];
8682
+ }
8683
+ const seen = /* @__PURE__ */ new Set();
8684
+ const tools = [];
8685
+ for (const file of files.sort()) {
8686
+ let mtimeMs;
8687
+ try {
8688
+ mtimeMs = fs10.statSync(file).mtimeMs;
8689
+ } catch {
8690
+ continue;
8392
8691
  }
8393
- for (const key of Reflect.ownKeys(current)) {
8394
- if (typeof key === "symbol") {
8395
- throwPublicDataError(pluginName, pathSegments, "cannot contain symbol keys");
8396
- }
8397
- const descriptor = Object.getOwnPropertyDescriptor(current, key);
8398
- if (!descriptor?.enumerable) {
8399
- throwPublicDataError(
8400
- pluginName,
8401
- [...pathSegments, key],
8402
- "cannot contain non-enumerable properties"
8403
- );
8404
- }
8405
- if (!("value" in descriptor)) {
8406
- throwPublicDataError(
8407
- pluginName,
8408
- [...pathSegments, key],
8409
- "cannot contain accessor properties"
8410
- );
8692
+ let entry = cache.get(file);
8693
+ if (!entry || entry.mtimeMs !== mtimeMs) {
8694
+ let code = "";
8695
+ try {
8696
+ code = fs10.readFileSync(file, "utf8");
8697
+ } catch {
8411
8698
  }
8412
- visit(descriptor.value, [...pathSegments, key]);
8699
+ entry = { mtimeMs, tools: findFarmWebMCPTools(code, file) };
8700
+ cache.set(file, entry);
8413
8701
  }
8414
- seen.delete(current);
8415
- };
8416
- visit(value, []);
8417
- }
8418
- function throwPublicDataError(pluginName, pathSegments, message) {
8419
- const location = pathSegments.length ? ` at client.public.${pathSegments.join(".")}` : "";
8420
- throw new TypeError(`Client plugin "${pluginName}"${location} ${message}`);
8421
- }
8422
- function serializePublicData(value) {
8423
- if (value === void 0) return "undefined";
8424
- return `JSON.parse(${JSON.stringify(JSON.stringify(value))})`;
8425
- }
8426
- function serializeOptionalString(value) {
8427
- return value === void 0 ? "undefined" : JSON.stringify(value);
8428
- }
8429
- function isArrayIndex(key) {
8430
- const value = Number(key);
8431
- return Number.isInteger(value) && value >= 0 && value < 4294967295 && String(value) === key;
8702
+ for (const tool of entry.tools) {
8703
+ if (seen.has(tool.name) || tools.length >= MAX_TOOLS) continue;
8704
+ seen.add(tool.name);
8705
+ tools.push(tool);
8706
+ }
8707
+ }
8708
+ return tools;
8432
8709
  }
8433
8710
 
8434
8711
  // src/client-cache-persistence-build.ts
8435
- import fs10 from "fs";
8436
- import path15 from "path";
8712
+ import fs11 from "fs";
8713
+ import path16 from "path";
8437
8714
  var ADAPTER_EXTENSIONS = ["ts", "tsx", "js", "jsx", "mts", "mjs"];
8438
8715
  function resolveFarmClientCacheAdapterEntry(root, cache2) {
8439
8716
  const client = cache2?.client;
@@ -8444,7 +8721,7 @@ function resolveFarmClientCacheAdapterEntry(root, cache2) {
8444
8721
  'cache.client.adapter must be a module path string, for example "./src/cache-adapter".'
8445
8722
  );
8446
8723
  }
8447
- const resolved = path15.resolve(root, adapter);
8724
+ const resolved = path16.resolve(root, adapter);
8448
8725
  const found = resolveAdapterFile(resolved);
8449
8726
  if (!found) {
8450
8727
  throw new Error(
@@ -8457,10 +8734,10 @@ function resolveFarmClientCacheAdapterEntry(root, cache2) {
8457
8734
  return { importPath: found.replace(/\\/g, "/"), options };
8458
8735
  }
8459
8736
  function resolveAdapterFile(resolved) {
8460
- if (fs10.existsSync(resolved) && fs10.statSync(resolved).isFile()) return resolved;
8737
+ if (fs11.existsSync(resolved) && fs11.statSync(resolved).isFile()) return resolved;
8461
8738
  for (const extension of ADAPTER_EXTENSIONS) {
8462
8739
  const candidate = `${resolved}.${extension}`;
8463
- if (fs10.existsSync(candidate) && fs10.statSync(candidate).isFile()) return candidate;
8740
+ if (fs11.existsSync(candidate) && fs11.statSync(candidate).isFile()) return candidate;
8464
8741
  }
8465
8742
  return void 0;
8466
8743
  }
@@ -8623,11 +8900,55 @@ async function buildFarmTreeLayouts(layouts, params, source, options) {
8623
8900
  }
8624
8901
  `;
8625
8902
 
8903
+ // src/client/navigation-stream-client.ts
8904
+ var FARM_NAVIGATION_STREAM_READER_SOURCE = `// Reads a streamed navigation (F-Stream) up to the end of React's shell. \`next\` then resolves
8905
+ // with each later flush as it ends, and null at the end; a document without a marker is all shell.
8906
+ // The marker carries the random token the server sent in the F-Flush header, so page content
8907
+ // cannot forge a boundary; a response without a valid token is all shell.
8908
+ async function readFarmNavigationStream(body, flushToken) {
8909
+ const reader = body.getReader();
8910
+ const decoder = new TextDecoder();
8911
+ const marker = typeof flushToken === "string" && /^[0-9a-f]{32}$/.test(flushToken)
8912
+ ? "<!--farm-flush:" + flushToken + "-->"
8913
+ : "";
8914
+ let text = "";
8915
+ let done = false;
8916
+ const next = async function() {
8917
+ for (;;) {
8918
+ const at = marker ? text.indexOf(marker) : -1;
8919
+ if (at !== -1) {
8920
+ const flush = text.slice(0, at);
8921
+ text = text.slice(at + marker.length);
8922
+ return flush;
8923
+ }
8924
+ if (done) {
8925
+ const flush = text;
8926
+ text = "";
8927
+ return flush ? flush : null;
8928
+ }
8929
+ const result = await reader.read();
8930
+ if (result.done) {
8931
+ done = true;
8932
+ text += decoder.decode();
8933
+ } else {
8934
+ text += decoder.decode(result.value, { stream: true });
8935
+ }
8936
+ }
8937
+ };
8938
+ const shell = await next();
8939
+ if (done && !text) return { shell: shell || "" };
8940
+ return {
8941
+ shell: shell,
8942
+ next: next,
8943
+ cancel: function() { reader.cancel().catch(function() {}); },
8944
+ };
8945
+ }`;
8946
+
8626
8947
  // src/docs/client-config.ts
8627
8948
  import { realpathSync as realpathSync2 } from "fs";
8628
8949
  import { createRequire as createRequire3 } from "module";
8629
- import path16 from "path";
8630
- var parseAst2;
8950
+ import path17 from "path";
8951
+ var parseAst3;
8631
8952
  function propertyKeyName(property2) {
8632
8953
  if (property2.computed) return void 0;
8633
8954
  const key = property2.key;
@@ -8636,11 +8957,11 @@ function propertyKeyName(property2) {
8636
8957
  return void 0;
8637
8958
  }
8638
8959
  function redactFarmDocsClientConfig(code, filename) {
8639
- parseAst2 ?? (parseAst2 = createRequire3(typeof __filename === "string" ? __filename : import.meta.url)(
8960
+ parseAst3 ?? (parseAst3 = createRequire3(typeof __filename === "string" ? __filename : import.meta.url)(
8640
8961
  "rolldown/parseAst"
8641
8962
  ).parseAst);
8642
- const extension = path16.extname(filename);
8643
- const program = parseAst2(code, {
8963
+ const extension = path17.extname(filename);
8964
+ const program = parseAst3(code, {
8644
8965
  lang: extension === ".tsx" || extension === ".jsx" ? "tsx" : "ts"
8645
8966
  });
8646
8967
  const edits = [];
@@ -8701,7 +9022,7 @@ function farmDocsClientConfigPlugin(configModule) {
8701
9022
  }
8702
9023
 
8703
9024
  // src/server/vite-config.ts
8704
- import path17 from "path";
9025
+ import path18 from "path";
8705
9026
  var FARM_CLIENT_ENTRY_PATTERN = "**/{page,layout,loading,error,not-found,default}.{js,jsx,ts,tsx}";
8706
9027
  var FARM_CLIENT_OPTIMIZE_DEPS_INCLUDE = [
8707
9028
  "react",
@@ -8728,9 +9049,9 @@ function getFarmClientOptimizeDepsInclude(renderer) {
8728
9049
  );
8729
9050
  }
8730
9051
  function createFarmClientOptimizeDepsEntries(projectRoot, appDirectories) {
8731
- const resolvedProjectRoot = path17.resolve(projectRoot);
9052
+ const resolvedProjectRoot = path18.resolve(projectRoot);
8732
9053
  return appDirectories.map((appDirectory) => {
8733
- const relativeAppDirectory = path17.relative(resolvedProjectRoot, path17.resolve(appDirectory)).replace(/\\/g, "/");
9054
+ const relativeAppDirectory = path18.relative(resolvedProjectRoot, path18.resolve(appDirectory)).replace(/\\/g, "/");
8734
9055
  const prefix = relativeAppDirectory || ".";
8735
9056
  return `${prefix}/${FARM_CLIENT_ENTRY_PATTERN}`;
8736
9057
  });
@@ -8752,7 +9073,7 @@ function createFarmClientOptimizeDepsConfig(entries, renderer) {
8752
9073
  }
8753
9074
  function createFarmSourceAlias(projectRoot, srcDir = "src") {
8754
9075
  return {
8755
- "@": path17.resolve(projectRoot, srcDir)
9076
+ "@": path18.resolve(projectRoot, srcDir)
8756
9077
  };
8757
9078
  }
8758
9079
  function mergeNoExternal(farmValue, userValue) {
@@ -8909,6 +9230,7 @@ export {
8909
9230
  hasUseClientDirective,
8910
9231
  getIslandStrategyExport,
8911
9232
  stripUseClientDirective,
9233
+ collectFarmServerStylesheets,
8912
9234
  getClientModuleMetadata,
8913
9235
  getClientModuleHydrationPlan,
8914
9236
  usesFarmServerTree,
@@ -8923,6 +9245,10 @@ export {
8923
9245
  DEFAULT_NOT_FOUND_STYLES,
8924
9246
  generateFarmIntegrationProviderClientCode,
8925
9247
  generateFarmIntegrationProviderServerModules,
9248
+ inferFarmIslandStrategy,
9249
+ resolveFarmRouteRootStrategy,
9250
+ generateFarmClientPluginEntryCode,
9251
+ canBootFarmIslandsClient,
8926
9252
  ServerRenderer,
8927
9253
  FarmApp,
8928
9254
  createFarmApp,
@@ -8931,11 +9257,11 @@ export {
8931
9257
  resolveFarmImageServerRuntime,
8932
9258
  resolveFarmAppPackages,
8933
9259
  collectFarmWebMCPTools,
8934
- generateFarmClientPluginEntryCode,
8935
9260
  resolveFarmClientCacheAdapterEntry,
8936
9261
  generateClientCachePersistenceCode,
8937
9262
  FARM_LAYOUT_ELEMENT_CLIENT_SOURCE,
8938
9263
  FARM_SERVER_TREE_LAYOUT_CLIENT_SOURCE,
9264
+ FARM_NAVIGATION_STREAM_READER_SOURCE,
8939
9265
  redactFarmDocsClientConfig,
8940
9266
  isFarmDocsClientConfigModule,
8941
9267
  farmDocsClientConfigPlugin,