@farm.js/core 0.1.42 → 0.1.44

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 (243) hide show
  1. package/dist/{agent-mcp-ssVy_tea.d.mts → agent-mcp-CWI-awqd.d.mts} +1 -1
  2. package/dist/{agent-mcp-SSD6L3VZ.d.ts → agent-mcp-EnzWYv_X.d.ts} +1 -1
  3. package/dist/agent-runtime.cjs +3 -2
  4. package/dist/agent-runtime.d.mts +1 -1
  5. package/dist/agent-runtime.d.ts +1 -1
  6. package/dist/agent-runtime.mjs +2 -1
  7. package/dist/api/route-manager.d.mts +3 -3
  8. package/dist/api/route-manager.d.ts +3 -3
  9. package/dist/api/runtime.d.mts +2 -2
  10. package/dist/api/runtime.d.ts +2 -2
  11. package/dist/api.cjs +2 -2
  12. package/dist/api.d.mts +8 -3
  13. package/dist/api.d.ts +8 -3
  14. package/dist/api.mjs +1 -1
  15. package/dist/{app-KjFzdCqy.d.ts → app-CAN_2Cqo.d.ts} +8 -4
  16. package/dist/{app-1h3lVT4a.d.mts → app-DG3dE8v5.d.mts} +8 -4
  17. package/dist/{app-manifest-D3RkVNuS.d.mts → app-manifest-8x5VjZ0L.d.mts} +1 -1
  18. package/dist/{app-manifest-DaW8-tvX.d.ts → app-manifest-DazjgQya.d.ts} +1 -1
  19. package/dist/app-markdown.d.mts +2 -2
  20. package/dist/app-markdown.d.ts +2 -2
  21. package/dist/{chunk-ECKF2BAM.cjs → chunk-2GVF3C2F.cjs} +255 -42
  22. package/dist/{chunk-TUL355PH.mjs → chunk-2MKTHHEU.mjs} +136 -161
  23. package/dist/chunk-2NXO5SBY.mjs +57 -0
  24. package/dist/{chunk-AX7S67YV.mjs → chunk-37VKVISD.mjs} +9 -173
  25. package/dist/chunk-3BROEWFY.cjs +39 -0
  26. package/dist/chunk-3SAWHWDH.cjs +186 -0
  27. package/dist/{chunk-AHFRQMRX.cjs → chunk-3YJMBQ27.cjs} +1 -1
  28. package/dist/{chunk-6PKXK4TY.mjs → chunk-53ZV6K65.mjs} +1 -1
  29. package/dist/{chunk-JG3MEQUH.cjs → chunk-5GBL2LKD.cjs} +430 -217
  30. package/dist/{chunk-LYIZHJTK.cjs → chunk-5LPHJZSI.cjs} +14 -14
  31. package/dist/chunk-5NIWBWDD.mjs +97 -0
  32. package/dist/{chunk-NRDBW4MP.mjs → chunk-7IQQIPRZ.mjs} +10 -0
  33. package/dist/{chunk-TCJ4A4A2.cjs → chunk-AI3WVJNP.cjs} +324 -350
  34. package/dist/chunk-APDGOKKE.cjs +148 -0
  35. package/dist/chunk-AZBSVLRM.cjs +132 -0
  36. package/dist/{chunk-RHGK2JEN.cjs → chunk-B6XAA7V6.cjs} +18 -182
  37. package/dist/chunk-CEDPEDNW.cjs +98 -0
  38. package/dist/{chunk-WSOBCAYO.cjs → chunk-CW6SNEN2.cjs} +25 -25
  39. package/dist/chunk-D5RFPV2H.mjs +148 -0
  40. package/dist/chunk-E22SWCXB.cjs +144 -0
  41. package/dist/{chunk-375K2ZVU.mjs → chunk-ERA5RP3L.mjs} +263 -50
  42. package/dist/{chunk-724JLMS4.mjs → chunk-F646BZ4Y.mjs} +4 -2
  43. package/dist/{chunk-C5KVWHIH.cjs → chunk-G2Z5DGMS.cjs} +5 -3
  44. package/dist/{chunk-ZATTDMBW.cjs → chunk-GA6JM4L6.cjs} +279 -376
  45. package/dist/chunk-GZWHCWLB.mjs +186 -0
  46. package/dist/{chunk-24SP5TGU.mjs → chunk-H4LXPWI2.mjs} +2 -2
  47. package/dist/chunk-H7BLEEAE.cjs +57 -0
  48. package/dist/chunk-IOMVXBLZ.mjs +144 -0
  49. package/dist/{chunk-BD3D7EZV.cjs → chunk-IXFOBGLQ.cjs} +9 -3
  50. package/dist/{chunk-JIYYX7WU.mjs → chunk-JVXW76I7.mjs} +2 -2
  51. package/dist/{chunk-MHN4UR5U.cjs → chunk-KFZZFZ7J.cjs} +7 -7
  52. package/dist/{chunk-BXJ5HJTJ.cjs → chunk-LPE3ED4R.cjs} +17 -13
  53. package/dist/chunk-LRJRXXQZ.cjs +109 -0
  54. package/dist/{chunk-HCSVR4YZ.mjs → chunk-M3BXTWJM.mjs} +18 -0
  55. package/dist/{chunk-2JZHQDUY.mjs → chunk-OYZGFRPA.mjs} +1 -1
  56. package/dist/{chunk-JR4QCLJY.cjs → chunk-PDU4P2IC.cjs} +19 -1
  57. package/dist/chunk-PJEHUSHA.mjs +229 -0
  58. package/dist/{chunk-QTEJGB5A.mjs → chunk-QGFKXYC7.mjs} +80 -177
  59. package/dist/chunk-QGH2RQVF.mjs +132 -0
  60. package/dist/{chunk-YWMZUGIS.mjs → chunk-R3ZFQJEF.mjs} +247 -34
  61. package/dist/{chunk-U2UC7UGP.mjs → chunk-R4J2UOV4.mjs} +1 -1
  62. package/dist/chunk-S34OBRMZ.mjs +109 -0
  63. package/dist/{chunk-TS4JHGUJ.mjs → chunk-S3ZEMCE6.mjs} +9 -3
  64. package/dist/{chunk-WWFTAUFG.cjs → chunk-SBH2JLLF.cjs} +12 -2
  65. package/dist/{chunk-YSLWRWWP.cjs → chunk-SKK6UF5P.cjs} +200 -46
  66. package/dist/{chunk-ZS6HDNOM.cjs → chunk-T44ECMEP.cjs} +6 -6
  67. package/dist/{chunk-OFZUJMCU.mjs → chunk-WPJQN64R.mjs} +195 -41
  68. package/dist/{chunk-NU25TRIO.mjs → chunk-WWYXIECF.mjs} +12 -8
  69. package/dist/{chunk-7YHSD3Z6.cjs → chunk-XPSGGECF.cjs} +85 -31
  70. package/dist/chunk-XUGFRFD2.mjs +39 -0
  71. package/dist/{chunk-IVQY6UTY.mjs → chunk-XUHIRBXY.mjs} +1 -1
  72. package/dist/{chunk-PIZXONIS.mjs → chunk-YFLBG2W3.mjs} +56 -2
  73. package/dist/chunk-YKUEJ3MG.cjs +229 -0
  74. package/dist/{chunk-QKZMB7LY.cjs → chunk-YN2QEMMO.cjs} +2 -2
  75. package/dist/{client-plugins-DIem0I0W.d.ts → client-plugins-BGS0wqzc.d.ts} +36 -16
  76. package/dist/{client-plugins-C9Py_50W.d.mts → client-plugins-nQ0tYt4l.d.mts} +36 -16
  77. package/dist/client-plugins.d.mts +1 -1
  78. package/dist/client-plugins.d.ts +1 -1
  79. package/dist/client.cjs +4 -3
  80. package/dist/client.d.mts +5 -5
  81. package/dist/client.d.ts +5 -5
  82. package/dist/client.mjs +3 -2
  83. package/dist/config.d.mts +1 -1
  84. package/dist/config.d.ts +1 -1
  85. package/dist/{devtools-2RY3EKHL.cjs → devtools-5Q7VRKVH.cjs} +6 -5
  86. package/dist/{devtools-Q3LBNUJ7.mjs → devtools-LJ4IGYGW.mjs} +5 -4
  87. package/dist/docs.cjs +7 -6
  88. package/dist/docs.d.mts +2 -2
  89. package/dist/docs.d.ts +2 -2
  90. package/dist/docs.mjs +6 -5
  91. package/dist/index-Cy26isrh.d.ts +48 -0
  92. package/dist/index-y1jgR74U.d.mts +48 -0
  93. package/dist/index.cjs +44 -25
  94. package/dist/index.d.mts +15 -15
  95. package/dist/index.d.ts +15 -15
  96. package/dist/index.mjs +51 -32
  97. package/dist/integrations.cjs +5 -3
  98. package/dist/integrations.d.mts +1 -1
  99. package/dist/integrations.d.ts +1 -1
  100. package/dist/integrations.mjs +6 -4
  101. package/dist/internal/app-markdown-runtime.d.mts +2 -2
  102. package/dist/internal/app-markdown-runtime.d.ts +2 -2
  103. package/dist/internal/build-runtime.cjs +30 -15
  104. package/dist/internal/build-runtime.d.mts +12 -16
  105. package/dist/internal/build-runtime.d.ts +12 -16
  106. package/dist/internal/build-runtime.mjs +29 -14
  107. package/dist/internal/cli-runtime.cjs +24 -11
  108. package/dist/internal/cli-runtime.mjs +24 -11
  109. package/dist/internal/client-error-overlay.cjs +4 -4
  110. package/dist/internal/client-error-overlay.mjs +1 -1
  111. package/dist/internal/client-runtime.cjs +5 -1
  112. package/dist/internal/client-runtime.d.mts +1 -0
  113. package/dist/internal/client-runtime.d.ts +1 -0
  114. package/dist/internal/client-runtime.mjs +4 -0
  115. package/dist/internal/compression-runtime.d.mts +1 -1
  116. package/dist/internal/compression-runtime.d.ts +1 -1
  117. package/dist/internal/config-runtime.cjs +6 -5
  118. package/dist/internal/config-runtime.d.mts +2 -2
  119. package/dist/internal/config-runtime.d.ts +2 -2
  120. package/dist/internal/config-runtime.mjs +5 -4
  121. package/dist/internal/form-actions-client.cjs +18 -0
  122. package/dist/internal/form-actions-client.d.mts +5 -0
  123. package/dist/internal/form-actions-client.d.ts +5 -0
  124. package/dist/internal/form-actions-client.mjs +18 -0
  125. package/dist/internal/form-actions.cjs +18 -0
  126. package/dist/internal/form-actions.d.mts +14 -0
  127. package/dist/internal/form-actions.d.ts +14 -0
  128. package/dist/internal/form-actions.mjs +18 -0
  129. package/dist/internal/island-codec.cjs +22 -0
  130. package/dist/internal/island-codec.d.mts +29 -0
  131. package/dist/internal/island-codec.d.ts +29 -0
  132. package/dist/internal/island-codec.mjs +22 -0
  133. package/dist/internal/island-value-store.cjs +13 -0
  134. package/dist/internal/island-value-store.d.mts +6 -0
  135. package/dist/internal/island-value-store.d.ts +6 -0
  136. package/dist/internal/island-value-store.mjs +13 -0
  137. package/dist/internal/islands-runtime.cjs +77 -0
  138. package/dist/internal/islands-runtime.d.mts +57 -0
  139. package/dist/internal/islands-runtime.d.ts +57 -0
  140. package/dist/internal/islands-runtime.mjs +77 -0
  141. package/dist/internal/islands-server.cjs +19 -0
  142. package/dist/internal/islands-server.d.mts +3 -0
  143. package/dist/internal/islands-server.d.ts +3 -0
  144. package/dist/internal/islands-server.mjs +19 -0
  145. package/dist/internal/islx-client.cjs +5 -0
  146. package/dist/internal/islx-client.d.mts +2 -0
  147. package/dist/internal/islx-client.d.ts +2 -0
  148. package/dist/internal/islx-client.mjs +3 -0
  149. package/dist/internal/islx-react.cjs +4 -0
  150. package/dist/internal/islx-react.d.mts +1 -0
  151. package/dist/internal/islx-react.d.ts +1 -0
  152. package/dist/internal/islx-react.mjs +2 -0
  153. package/dist/internal/islx-server.cjs +5 -0
  154. package/dist/internal/islx-server.d.mts +2 -0
  155. package/dist/internal/islx-server.d.ts +2 -0
  156. package/dist/internal/islx-server.mjs +3 -0
  157. package/dist/internal/isolated-boundary.cjs +4 -3
  158. package/dist/internal/isolated-boundary.d.mts +13 -1
  159. package/dist/internal/isolated-boundary.d.ts +13 -1
  160. package/dist/internal/isolated-boundary.mjs +3 -2
  161. package/dist/internal/product-telemetry-runtime.cjs +2 -2
  162. package/dist/internal/product-telemetry-runtime.mjs +1 -1
  163. package/dist/internal/production-runtime.cjs +24 -13
  164. package/dist/internal/production-runtime.d.mts +20 -10
  165. package/dist/internal/production-runtime.d.ts +20 -10
  166. package/dist/internal/production-runtime.mjs +24 -13
  167. package/dist/internal/server-tree.cjs +6 -3
  168. package/dist/internal/server-tree.d.mts +25 -2
  169. package/dist/internal/server-tree.d.ts +25 -2
  170. package/dist/internal/server-tree.mjs +7 -4
  171. package/dist/island-value-protocol-BRayRghM.d.mts +12 -0
  172. package/dist/island-value-protocol-BRayRghM.d.ts +12 -0
  173. package/dist/markdown.d.mts +1 -1
  174. package/dist/markdown.d.ts +1 -1
  175. package/dist/middleware.d.mts +3 -3
  176. package/dist/middleware.d.ts +3 -3
  177. package/dist/navigation.cjs +5 -4
  178. package/dist/navigation.d.mts +4 -4
  179. package/dist/navigation.d.ts +4 -4
  180. package/dist/navigation.mjs +4 -3
  181. package/dist/og.d.mts +5 -0
  182. package/dist/og.d.ts +5 -0
  183. package/dist/plugin.cjs +19 -12
  184. package/dist/plugin.d.mts +3 -3
  185. package/dist/plugin.d.ts +3 -3
  186. package/dist/plugin.mjs +18 -11
  187. package/dist/{production-runtime-bjjWq-DA.d.ts → production-runtime-BVMDgHrA.d.ts} +1 -1
  188. package/dist/{production-runtime-CHFKIgpW.d.mts → production-runtime-ClFA_1KQ.d.mts} +1 -1
  189. package/dist/query/client.cjs +6 -5
  190. package/dist/query/client.mjs +2 -1
  191. package/dist/{render-plan-DOHg6wdO.d.mts → render-plan-CoSovy_O.d.mts} +4 -2
  192. package/dist/{render-plan-B2UndB4x.d.ts → render-plan-y2DefWf8.d.ts} +4 -2
  193. package/dist/renderer/react/server.cjs +7 -6
  194. package/dist/renderer/react/server.d.mts +3 -1
  195. package/dist/renderer/react/server.d.ts +3 -1
  196. package/dist/renderer/react/server.mjs +5 -4
  197. package/dist/renderer-client.cjs +5 -4
  198. package/dist/renderer-client.d.mts +3 -3
  199. package/dist/renderer-client.d.ts +3 -3
  200. package/dist/renderer-client.mjs +2 -1
  201. package/dist/renderer.d.mts +3 -1
  202. package/dist/renderer.d.ts +3 -1
  203. package/dist/{request-DVNXRQrI.d.ts → request-aG5Wovm5.d.ts} +1 -1
  204. package/dist/{request-DQcGfdgQ.d.mts → request-cNM09Q7e.d.mts} +1 -1
  205. package/dist/request.d.mts +2 -2
  206. package/dist/request.d.ts +2 -2
  207. package/dist/{route-rendering-B_6fj-GG.d.ts → route-rendering-B3uQmCWX.d.ts} +1 -1
  208. package/dist/{route-rendering-CEX4mFn-.d.mts → route-rendering-EyInfsjI.d.mts} +1 -1
  209. package/dist/{router-CHEMHm1P.d.ts → router-DNUf-Bg1.d.ts} +1 -1
  210. package/dist/{router-CKHPBKXX.d.mts → router-Devibh4r.d.mts} +1 -1
  211. package/dist/routes.d.mts +1 -1
  212. package/dist/routes.d.ts +1 -1
  213. package/dist/rsc-pipeline-4ZJ6GUVQ.cjs +78 -0
  214. package/dist/rsc-pipeline-KK6GFDET.mjs +78 -0
  215. package/dist/{runtime-jj8TKNsy.d.mts → runtime-9KZb8AI5.d.mts} +1 -1
  216. package/dist/{runtime-Br2ZDTAv.d.ts → runtime-CLr9P5kn.d.ts} +1 -1
  217. package/dist/{schema-dev-notice-5JPE67AI.cjs → schema-dev-notice-77ZL23PL.cjs} +4 -4
  218. package/dist/{schema-dev-notice-WLPZ6WKU.mjs → schema-dev-notice-BLXOS6U2.mjs} +2 -2
  219. package/dist/server-plugins.d.mts +2 -2
  220. package/dist/server-plugins.d.ts +2 -2
  221. package/dist/server.cjs +57 -38
  222. package/dist/server.d.mts +15 -10
  223. package/dist/server.d.ts +15 -10
  224. package/dist/server.mjs +37 -18
  225. package/dist/{spa-router-BEvS9Erj.d.mts → spa-router-BIxh4IY-.d.mts} +8 -3
  226. package/dist/{spa-router-DmCuH5B7.d.ts → spa-router-Ds6R_oe-.d.ts} +8 -3
  227. package/dist/{ssg-57v6cZcW.d.mts → ssg-ByrOVYdM.d.mts} +2 -2
  228. package/dist/{ssg-gT093ETk.d.ts → ssg-XnMHCyEc.d.ts} +2 -2
  229. package/dist/testing.d.mts +1 -1
  230. package/dist/testing.d.ts +1 -1
  231. package/dist/{utils-CCTKvR-P.d.ts → utils-BN70ueSN.d.ts} +1 -1
  232. package/dist/{utils-raHHQVyL.d.mts → utils-BrjR5xRs.d.mts} +1 -1
  233. package/dist/version.cjs +2 -2
  234. package/dist/version.mjs +1 -1
  235. package/dist/vite.cjs +19 -12
  236. package/dist/vite.d.mts +6 -4
  237. package/dist/vite.d.ts +6 -4
  238. package/dist/vite.mjs +18 -11
  239. package/package.json +53 -1
  240. package/dist/{chunk-35WS7P2V.mjs → chunk-26CXZR6L.mjs} +3 -3
  241. package/dist/{chunk-QEILRWVV.cjs → chunk-3XEMGDBF.cjs} +2 -2
  242. package/dist/{chunk-BPOTSHDO.cjs → chunk-IOAUK4OI.cjs} +2 -2
  243. package/dist/{chunk-BYR3RQPB.mjs → chunk-T76H22WI.mjs} +4 -4
@@ -11,13 +11,13 @@ import {
11
11
  import {
12
12
  generateNativeMCPPluginSource,
13
13
  layoutsCanCoverSamePage
14
- } from "./chunk-IVQY6UTY.mjs";
14
+ } from "./chunk-XUHIRBXY.mjs";
15
15
  import {
16
16
  assertFarmDocsAdapterServesNoGuardedPages,
17
17
  compileFarmDocsAdapterEdgeManifest,
18
18
  createFarmDocsAPIHandler,
19
19
  hasFarmDocsRuntimeAdapter
20
- } from "./chunk-2JZHQDUY.mjs";
20
+ } from "./chunk-OYZGFRPA.mjs";
21
21
  import {
22
22
  FARM_DOCS_LAST_MODIFIED_MANIFEST,
23
23
  createFarmDocsHandler,
@@ -45,7 +45,7 @@ import {
45
45
  getDeployTargetForPreset,
46
46
  hasCustomFarmRouteContext,
47
47
  resolveDeployOutputPath
48
- } from "./chunk-NU25TRIO.mjs";
48
+ } from "./chunk-WWYXIECF.mjs";
49
49
  import {
50
50
  resolveFarmInstrumentationFile
51
51
  } from "./chunk-ZZSRYEYU.mjs";
@@ -72,7 +72,6 @@ import {
72
72
  getClientModuleHydrationPlan,
73
73
  getClientModuleMetadata,
74
74
  getFarmClientHydrationPlanOptions,
75
- loadTailwindVitePlugin,
76
75
  mergeFarmFontCss,
77
76
  mergeFarmProductionViteConfig,
78
77
  mergeFarmViteConfig,
@@ -83,15 +82,18 @@ import {
83
82
  resolveFarmIsolatedClientHydrationMode,
84
83
  resolveFarmNotFoundComponentPath,
85
84
  usesFarmServerTree
86
- } from "./chunk-QTEJGB5A.mjs";
85
+ } from "./chunk-QGFKXYC7.mjs";
87
86
  import {
88
87
  PluginManager
89
88
  } from "./chunk-FGH3ZXTP.mjs";
89
+ import {
90
+ loadTailwindVitePlugin
91
+ } from "./chunk-S34OBRMZ.mjs";
90
92
  import {
91
93
  generateFarmTypeArtifacts,
92
94
  readRouteRenderingDirectiveFromFile,
93
95
  resolveRouteRenderingConfigFromFile
94
- } from "./chunk-35WS7P2V.mjs";
96
+ } from "./chunk-26CXZR6L.mjs";
95
97
  import {
96
98
  FARM_API_CATALOG_PATH,
97
99
  FARM_APP_MANIFEST_LEGACY_PATH,
@@ -107,15 +109,15 @@ import {
107
109
  resolveFarmAppManifestInput,
108
110
  routeBoundaryCoversDirectory,
109
111
  stripRouteGroups
110
- } from "./chunk-PIZXONIS.mjs";
112
+ } from "./chunk-YFLBG2W3.mjs";
113
+ import {
114
+ farmPluginMayAffectRuntimePath
115
+ } from "./chunk-Y5RG6B7S.mjs";
111
116
  import {
112
117
  FARM_DEFAULT_MCP_PATH,
113
118
  createFarmDefaultMCPServer,
114
119
  farmConfigMountsMCP
115
120
  } from "./chunk-4ZZNPK25.mjs";
116
- import {
117
- farmPluginMayAffectRuntimePath
118
- } from "./chunk-Y5RG6B7S.mjs";
119
121
  import {
120
122
  isFarmPreviewDeploymentEnvironment
121
123
  } from "./chunk-BOYNDCZL.mjs";
@@ -130,6 +132,9 @@ import {
130
132
  resolveFarmDocsFontAssets,
131
133
  toFarmDocsPublicFontAssets
132
134
  } from "./chunk-TVGP4BBZ.mjs";
135
+ import {
136
+ resolveFarmServerComponentsMode
137
+ } from "./chunk-M3BXTWJM.mjs";
133
138
  import {
134
139
  routeRulesToNitroRouteRules
135
140
  } from "./chunk-GHFS7RUB.mjs";
@@ -155,6 +160,9 @@ import {
155
160
  mergeScheduledTasks,
156
161
  prepareFarmCronForNitro
157
162
  } from "./chunk-YHOCRI4H.mjs";
163
+ import {
164
+ resolveServerActionsConfig
165
+ } from "./chunk-WMHG64DA.mjs";
158
166
  import {
159
167
  createBundledEnv
160
168
  } from "./chunk-4OOBRCJX.mjs";
@@ -176,10 +184,12 @@ import {
176
184
  _collectFarmStorageModules
177
185
  } from "./chunk-JGHCKIRI.mjs";
178
186
  import {
179
- FARM_INTEGRATION_API_BASE_PATH_KEY,
180
187
  getFarmIntegrationPluginServerRuntime,
181
188
  getIntegrationProviders
182
- } from "./chunk-AX7S67YV.mjs";
189
+ } from "./chunk-37VKVISD.mjs";
190
+ import {
191
+ FARM_INTEGRATION_API_BASE_PATH_KEY
192
+ } from "./chunk-GZWHCWLB.mjs";
183
193
  import {
184
194
  appendMiddlewareDirectory,
185
195
  appendMiddlewareRoutePath,
@@ -214,7 +224,7 @@ import {
214
224
  } from "./chunk-BTHHUD7Q.mjs";
215
225
  import {
216
226
  FARM_VERSION
217
- } from "./chunk-U2UC7UGP.mjs";
227
+ } from "./chunk-R4J2UOV4.mjs";
218
228
  import {
219
229
  getFarmPresetRuntime
220
230
  } from "./chunk-2A3EQHXX.mjs";
@@ -232,6 +242,9 @@ import {
232
242
  import path10 from "path";
233
243
  import { existsSync as existsSync3 } from "fs";
234
244
 
245
+ // src/nitro/universal-build.ts
246
+ import { randomBytes } from "crypto";
247
+
235
248
  // src/nitro/client-css-href.ts
236
249
  import path from "path";
237
250
  var FARM_CLIENT_CSS_HREF_PLACEHOLDER = "/__farm_client_css_href__";
@@ -1998,7 +2011,7 @@ async function validateClientBuildOutput(root, srcDir, outputDir) {
1998
2011
  }
1999
2012
  __name(validateClientBuildOutput, "validateClientBuildOutput");
2000
2013
  function getCachedClientModuleHydrationPlan(modulePath, root, mode, cache, options = {}) {
2001
- const key = `${path9.resolve(root)}\0${mode}\0${options.asyncOwnerIslands === true}\0${path9.resolve(modulePath)}`;
2014
+ const key = `${path9.resolve(root)}\0${mode}\0${options.asyncOwnerIslands === true}\0${options.serverOwners === true}\0${path9.resolve(modulePath)}`;
2002
2015
  let plan = cache.get(key);
2003
2016
  if (!plan) {
2004
2017
  plan = getClientModuleHydrationPlan(modulePath, root, mode, options);
@@ -2025,7 +2038,7 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
2025
2038
  const unsupportedIntegrationProvider = integrationProviders.find(
2026
2039
  (provider) => provider.supportsIsolatedHydration !== true
2027
2040
  );
2028
- if (config.experimental?.isolatedClientHydration === "enabled" && config.experimental?.serverComponents !== true && unsupportedIntegrationProvider) {
2041
+ if (config.experimental?.isolatedClientHydration === "enabled" && resolveFarmServerComponentsMode(config.experimental?.serverComponents) !== "rsc" && unsupportedIntegrationProvider) {
2029
2042
  logger.warn(
2030
2043
  `[Farm.js] isolated hydration kept route-wide because integration provider "${unsupportedIntegrationProvider.name}" does not declare supportsIsolatedHydration: true.`
2031
2044
  );
@@ -2033,7 +2046,7 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
2033
2046
  const isolatedMode = resolveFarmIsolatedClientHydrationMode(
2034
2047
  config.experimental?.isolatedClientHydration,
2035
2048
  {
2036
- serverComponents: config.experimental?.serverComponents === true,
2049
+ serverComponents: resolveFarmServerComponentsMode(config.experimental?.serverComponents) === "rsc",
2037
2050
  hasUnsupportedIntegrationProvider: Boolean(unsupportedIntegrationProvider)
2038
2051
  }
2039
2052
  );
@@ -2041,6 +2054,10 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
2041
2054
  config.renderer,
2042
2055
  Boolean(unsupportedIntegrationProvider)
2043
2056
  );
2057
+ const pagePlanOptions = {
2058
+ ...planOptions,
2059
+ serverOwners: resolveFarmServerComponentsMode(config.experimental?.serverComponents) === "islands"
2060
+ };
2044
2061
  const clientLayouts = layoutRoutes.map((layout) => {
2045
2062
  try {
2046
2063
  const metadata = getCachedClientModuleHydrationPlan(
@@ -2108,7 +2125,7 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
2108
2125
  root,
2109
2126
  isolatedMode,
2110
2127
  hydrationPlanCache,
2111
- planOptions
2128
+ pagePlanOptions
2112
2129
  )
2113
2130
  }));
2114
2131
  enforceFarmIsolatedHydrationRouteBudget(
@@ -2259,7 +2276,8 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
2259
2276
  getIntegrationProviders(config.integrations),
2260
2277
  config.basePath,
2261
2278
  generateClientCachePersistenceCode(resolveFarmClientCacheAdapterEntry(root, config.cache)),
2262
- adapterOwnsDocsRuntime ? getFarmDocsAdapterConfigModule(config.docs) : void 0
2279
+ adapterOwnsDocsRuntime ? getFarmDocsAdapterConfigModule(config.docs) : void 0,
2280
+ resolveFarmServerComponentsMode(config.experimental?.serverComponents) === "islands"
2263
2281
  );
2264
2282
  await fs4.writeFile(clientEntryPath, clientHydrationCode);
2265
2283
  const hasScopedPostcssConfig = hasProjectPostcssConfig(root);
@@ -2974,13 +2992,17 @@ function generateUniversalRouterStateProperties() {
2974
2992
 
2975
2993
  clearPrefetchedPath: function(url) {
2976
2994
  const interceptionPrefix = url + "\\nintercept:";
2995
+ const partialPrefix = url + "\\npartial:";
2996
+ const matches = function(key) {
2997
+ return key === url || key.startsWith(interceptionPrefix) || key.startsWith(partialPrefix);
2998
+ };
2977
2999
  for (const key of this.prefetchCache.keys()) {
2978
- if (key === url || key.startsWith(interceptionPrefix)) {
3000
+ if (matches(key)) {
2979
3001
  this.prefetchCache.delete(key);
2980
3002
  }
2981
3003
  }
2982
3004
  for (const [key, pending] of this.pendingPrefetches) {
2983
- if (key === url || key.startsWith(interceptionPrefix)) {
3005
+ if (matches(key)) {
2984
3006
  pending.valid = false;
2985
3007
  this.pendingPrefetches.delete(key);
2986
3008
  }
@@ -2994,9 +3016,18 @@ function generateUniversalRouterStateProperties() {
2994
3016
  this.pendingPrefetches.clear();
2995
3017
  },
2996
3018
 
2997
- fetchPrefetchedDocument: async function(url, interceptFrom, fresh, recover, signal, cacheResult = true) {
3019
+ // Islands mode: a partial response (layouts kept, or only the page's payload) suits the page
3020
+ // that asked for it, so the cache keys it by what that page told the server.
3021
+ prefetchRequest: function(url, interceptFrom, layoutChain = true) {
3022
+ const base = interceptFrom ? url + "\\nintercept:" + interceptFrom : url;
3023
+ const partial = layoutChain && this.partialNavigationHeaders ? this.partialNavigationHeaders() : {};
3024
+ const identity = Object.keys(partial).length ? JSON.stringify(partial) : "";
3025
+ return { cacheKey: identity ? base + "\\npartial:" + identity : base, headers: partial };
3026
+ },
3027
+
3028
+ fetchPrefetchedDocument: async function(url, interceptFrom, fresh, recover, signal, cacheResult = true, layoutChain = true) {
2998
3029
  signal?.throwIfAborted();
2999
- const cacheKey = interceptFrom ? url + "\\nintercept:" + interceptFrom : url;
3030
+ const { cacheKey, headers: partialHeaders } = this.prefetchRequest(url, interceptFrom, layoutChain);
3000
3031
  if (fresh) this.clearPrefetchedPath(url);
3001
3032
  const cached = fresh ? undefined : this.readFreshPrefetch(cacheKey);
3002
3033
  if (cached !== undefined) return cached;
@@ -3028,6 +3059,10 @@ function generateUniversalRouterStateProperties() {
3028
3059
  const response = await fetchFarmNavigationDocument(url, {
3029
3060
  "Accept": "text/html",
3030
3061
  ...(interceptFrom ? { "X-Farm-Intercept-From": interceptFrom } : {}),
3062
+ // Islands mode: the server leaves out island values this browser holds, and the
3063
+ // layouts it shows.
3064
+ ...getFarmIslandValueHeaders(),
3065
+ ...partialHeaders,
3031
3066
  }, recover, signal);
3032
3067
  if (!response.ok) throw new Error("Failed to fetch page");
3033
3068
  const html = await response.text();
@@ -3185,6 +3220,25 @@ function generateUniversalRouterStateProperties() {
3185
3220
  `.trim();
3186
3221
  }
3187
3222
  __name(generateUniversalRouterStateProperties, "generateUniversalRouterStateProperties");
3223
+ var FARM_SEGMENT_NAVIGATION_SERVER_RUNTIME = `
3224
+ function getFarmLayoutKey(pattern, params) {
3225
+ return pattern.replace(/\\[\\[?\\.\\.\\.([^\\]]+)\\]?\\]|\\[([^\\]]+)\\]/g, function(match, rest, name) {
3226
+ const value = params ? params[rest || name] : undefined;
3227
+ if (Array.isArray(value)) return value.map(encodeURIComponent).join("/");
3228
+ return value === undefined ? "" : encodeURIComponent(String(value));
3229
+ });
3230
+ }
3231
+
3232
+ function countFarmKeptLayouts(request, layouts, params) {
3233
+ const chain = parseFarmLayoutChainHeader(request.headers.get("f-layouts"));
3234
+ if (chain.length === 0) return 0;
3235
+ const keys = layouts.map(function(layout) { return getFarmLayoutKey(layout.pattern, params); });
3236
+ if (chain[0] === keys[0]) return getSharedLayoutPrefixLength(chain, keys);
3237
+ // A root layout that renders the document itself leaves no boundary in the page, so the
3238
+ // browser's chain starts at the next layout.
3239
+ return keys.length > 1 ? 1 + getSharedLayoutPrefixLength(chain, keys.slice(1)) : 0;
3240
+ }
3241
+ `;
3188
3242
  function generateClientHydrationEntry(clientPages, layoutRoutes, clientRouteSlots, root, srcDir, docsSearchEnabled, docsSearchModuleId, docsEntryPath, docsAdapterReact, i18nConfig = {
3189
3243
  enabled: false,
3190
3244
  basePath: "/",
@@ -3203,7 +3257,7 @@ function generateClientHydrationEntry(clientPages, layoutRoutes, clientRouteSlot
3203
3257
  secure: false
3204
3258
  },
3205
3259
  direction: {}
3206
- }, plugins = [], renderer = REACT_RENDERER, publicRuntimeConfig = void 0, trailingSlash = false, integrationProviders = [], basePath = "/", clientCachePersistence = { imports: "", init: "" }, docsConfigModule) {
3260
+ }, plugins = [], renderer = REACT_RENDERER, publicRuntimeConfig = void 0, trailingSlash = false, integrationProviders = [], basePath = "/", clientCachePersistence = { imports: "", init: "" }, docsConfigModule, islandValues = false) {
3207
3261
  const toImportPath = /* @__PURE__ */ __name((targetPath) => targetPath.replace(/\\/g, "/"), "toImportPath");
3208
3262
  const clientPluginEntry = generateFarmClientPluginEntryCode(
3209
3263
  plugins,
@@ -3292,7 +3346,7 @@ function isFarmDocsPath() {
3292
3346
  // Farm.js Client Runtime (no client components)
3293
3347
  ${cssImport}
3294
3348
  ${layoutImports}
3295
- import { createClientCancellation, createClientPluginManager, getHashTargetElement, installChunkErrorRecovery, isFarmBlockedNavigationURL, isFarmExternalNavigationURL, reconcileFarmDocumentHead, setFarmBasePath, setFarmTrailingSlashPreference, stripFarmBasePath } from "@farm.js/core/internal/client-runtime";
3349
+ import { createClientCancellation, createClientPluginManager, getFarmIslandValueHeaders, getHashTargetElement, installChunkErrorRecovery, isFarmBlockedNavigationURL, isFarmExternalNavigationURL, reconcileFarmDocumentHead, setFarmBasePath, setFarmTrailingSlashPreference, stripFarmBasePath } from "@farm.js/core/internal/client-runtime";
3296
3350
  import { createFarmDeploymentMismatchError, createFarmDeploymentRequestHeaders, isFarmDeploymentMismatchResponse } from "@farm.js/core/deployment";
3297
3351
  ${clientPluginEntry.imports}
3298
3352
  ${clientCachePersistence.imports}
@@ -3591,7 +3645,7 @@ document.addEventListener("click", function(e) {
3591
3645
  });
3592
3646
  const isolatedHydrationEnabled = isolatedBoundaryModules.size > 0;
3593
3647
  const serverTreeEnabled = isolatedHydrationEnabled && clientPages.some((page) => page.serverTree);
3594
- const isolatedHydrationImport = isolatedHydrationEnabled ? `import { createFarmIsolatedHydrationRuntime, createFarmServerPageBoundary, wrapFarmIsolatedClientGraph } from "@farm.js/core/internal/isolated-boundary";${serverTreeEnabled ? '\nimport { createFarmServerTreeElement } from "@farm.js/core/internal/server-tree";' : ""}` : "";
3648
+ const isolatedHydrationImport = isolatedHydrationEnabled ? `${islandValues ? 'import { createFarmIsolatedHydrationRuntime, createFarmServerPageBoundary, wrapFarmIsolatedClientGraph, createFarmServerTreeElement } from "@farm.js/core/internal/islands-runtime";' : 'import { createFarmIsolatedHydrationRuntime, createFarmServerPageBoundary, wrapFarmIsolatedClientGraph } from "@farm.js/core/internal/isolated-boundary";'}${serverTreeEnabled && !islandValues ? '\nimport { createFarmServerTreeElement } from "@farm.js/core/internal/server-tree";' : ""}` : "";
3595
3649
  const isolatedHydrationRuntime = isolatedHydrationEnabled ? `const farmIsolatedBoundaryLoaders = {
3596
3650
  ${Array.from(isolatedBoundaryModules.entries()).map(
3597
3651
  ([reference, modulePath]) => ` ${JSON.stringify(reference)}: () => import(${JSON.stringify(modulePath)}),`
@@ -3657,7 +3711,7 @@ ${layoutImports}
3657
3711
  ${rendererClientImports}
3658
3712
  ${isolatedHydrationImport}
3659
3713
  ${providerClientCode.imports}
3660
- import { createClientCancellation, createClientPluginManager, getHashTargetElement, installChunkErrorRecovery, isFarmBlockedNavigationURL, isFarmExternalNavigationURL, reconcileFarmDocumentHead, scheduleFarmIslandHydration, searchParamsToObject, setFarmBasePath, setFarmTrailingSlashPreference, stripFarmBasePath } from "@farm.js/core/internal/client-runtime";
3714
+ import { createClientCancellation, createClientPluginManager, getFarmIslandValueHeaders, getHashTargetElement, installChunkErrorRecovery, isFarmBlockedNavigationURL, isFarmExternalNavigationURL, reconcileFarmDocumentHead, scheduleFarmIslandHydration, searchParamsToObject, setFarmBasePath, setFarmTrailingSlashPreference, stripFarmBasePath } from "@farm.js/core/internal/client-runtime";
3661
3715
  import { createFarmDeploymentMismatchError, createFarmDeploymentRequestHeaders, isFarmDeploymentMismatchResponse } from "@farm.js/core/deployment";
3662
3716
  import { createFarmRouter, isFarmRouteActive, matchFarmRoute } from "@farm.js/core/router";
3663
3717
  ${clientPluginEntry.imports}
@@ -3834,6 +3888,10 @@ async function createMatchedHydrationRoute(matched, pathname, searchParams, serv
3834
3888
  const serverPage = document.getElementById("__farm_page__");
3835
3889
  const pageSource = typeof serverHtml === "string" ? serverHtml : serverPage;
3836
3890
  const serverTree = pageSource ? await createFarmServerTreePageElement(pageSource, pathname) : null;
3891
+ // A payload-only page (islands mode) has no HTML to fall back to: fetch the whole document.
3892
+ if (!serverTree && typeof serverHtml === "string" && serverHtml.includes('<script type="f/tree" partial')) {
3893
+ return null;
3894
+ }
3837
3895
  pageElement = serverTree
3838
3896
  ? createLayoutPageBoundary(matched.route, serverTree)
3839
3897
  : createLayoutPageBoundary(
@@ -4161,7 +4219,7 @@ async function hydrate() {
4161
4219
  });
4162
4220
  ${isolatedHydrationEnabled ? `const isolatedHydration =
4163
4221
  !hasHydratableLayout(pathname) &&
4164
- document.querySelector('farm-client-boundary[data-farm-client-boundary]')
4222
+ document.querySelector('f-island[src]')
4165
4223
  ? hydrateFarmIsolatedClientBoundaries(document, hydrationController.signal)
4166
4224
  : Promise.resolve();
4167
4225
  await Promise.all([pageHydration, isolatedHydration]);` : "await pageHydration;"}
@@ -4172,20 +4230,41 @@ async function hydrate() {
4172
4230
  }
4173
4231
  }
4174
4232
 
4233
+ // A layout boundary is the same layout when its key matches: islands mode keys it by pattern and
4234
+ // params, so a layout whose params change renders again. Other modes compare patterns.
4235
+ function getLayoutIdentity(boundary) {
4236
+ return boundary.getAttribute("data-farm-layout-key") || boundary.getAttribute("data-farm-layout-pattern");
4237
+ }
4238
+
4175
4239
  function findLayoutBoundary(root, pattern) {
4176
4240
  const boundaries = root?.querySelectorAll?.('[data-farm-layout-boundary="true"]') || [];
4177
4241
  for (const boundary of boundaries) {
4178
- if (boundary.getAttribute("data-farm-layout-pattern") === pattern) return boundary;
4242
+ if (getLayoutIdentity(boundary) === pattern) return boundary;
4179
4243
  }
4180
4244
  return null;
4181
4245
  }
4182
4246
 
4183
4247
  function getLayoutPatterns(root) {
4184
4248
  return Array.from(root?.querySelectorAll?.('[data-farm-layout-boundary="true"]') || [])
4185
- .map(function(element) { return element.getAttribute("data-farm-layout-pattern"); })
4249
+ .map(getLayoutIdentity)
4186
4250
  .filter(Boolean);
4187
4251
  }
4188
4252
 
4253
+ ${islandValues ? `// A segment response leaves out the layouts the browser said it shows. It fits this page only if
4254
+ // the page still shows each of them, at the same depth.
4255
+ function fitsSegmentResponse(currentRoot, nextRoot) {
4256
+ const nextBoundaries = Array.from(nextRoot.querySelectorAll('[data-farm-layout-boundary="true"]'));
4257
+ const lastKept = nextBoundaries.map(function(boundary) {
4258
+ return boundary.getAttribute("data-farm-layout-kept") === "true";
4259
+ }).lastIndexOf(true);
4260
+ if (lastKept === -1) return true;
4261
+ const current = getLayoutPatterns(currentRoot);
4262
+ for (let index = 0; index <= lastKept; index++) {
4263
+ if (current[index] !== getLayoutIdentity(nextBoundaries[index])) return false;
4264
+ }
4265
+ return true;
4266
+ }` : ""}
4267
+
4189
4268
  function activateNavigationScripts(root) {
4190
4269
  for (const script of Array.from(root?.querySelectorAll?.("script") || [])) {
4191
4270
  const freshScript = document.createElement("script");
@@ -4197,7 +4276,7 @@ function activateNavigationScripts(root) {
4197
4276
  }
4198
4277
  }
4199
4278
 
4200
- function replaceSharedLayoutBoundary(currentRoot, nextRoot) {
4279
+ function replaceSharedLayoutBoundary(currentRoot, nextRoot, refresh = false) {
4201
4280
  const currentPatterns = getLayoutPatterns(currentRoot);
4202
4281
  const nextPatterns = getLayoutPatterns(nextRoot);
4203
4282
  let sharedCount = 0;
@@ -4218,7 +4297,9 @@ function replaceSharedLayoutBoundary(currentRoot, nextRoot) {
4218
4297
  : nextRoot.querySelector("#__farm_page__");
4219
4298
 
4220
4299
  if (!currentTarget || !nextTarget) return false;
4221
- ${isolatedHydrationEnabled ? "disposeFarmIsolatedClientBoundaries(currentTarget);" : ""}
4300
+ ${isolatedHydrationEnabled ? `${islandValues ? `// A refresh keeps the islands still on the page, with their state and new props.
4301
+ if (refresh) farmIsolatedHydrationRuntime.carryOver(currentTarget, nextTarget);
4302
+ ` : ""}disposeFarmIsolatedClientBoundaries(currentTarget);` : ""}
4222
4303
  currentTarget.replaceWith(nextTarget);
4223
4304
  activateNavigationScripts(nextTarget);
4224
4305
  if (nextTreeRoot && nextTreeRoot !== nextTarget) nextTreeRoot.remove();
@@ -4239,7 +4320,17 @@ function replaceSharedLayoutBoundary(currentRoot, nextRoot) {
4239
4320
  const spaRouter = {
4240
4321
  ${generateUniversalRouterStateProperties()}
4241
4322
  prefetchCache: new Map(),
4242
-
4323
+ ${islandValues ? ` // Islands mode: navigations name the layouts on screen, and say when this page renders the
4324
+ // next one in its own React root; the server leaves out what the browser keeps or rebuilds.
4325
+ partialNavigationHeaders: function() {
4326
+ const root = document.getElementById("root") || document.body;
4327
+ const layouts = getLayoutPatterns(root);
4328
+ return {
4329
+ ...(layouts.length ? { "F-Layouts": JSON.stringify(layouts) } : {}),
4330
+ ...(reactRoot && reactRootContainer === root ? { "F-Render": "tree" } : {}),
4331
+ };
4332
+ },
4333
+ ` : ""}
4243
4334
  navigate: async function(href, options = {}) {
4244
4335
  const url = new URL(href, window.location.href);
4245
4336
  if (isFarmBlockedNavigationURL(url)) return;
@@ -4294,6 +4385,8 @@ ${generateUniversalRouterStateProperties()}
4294
4385
  cancelPendingPageHydration();
4295
4386
  this.saveScrollPosition(window.location.pathname + window.location.search);
4296
4387
  const navigation = this.startNavigation(from, url, action);
4388
+ // A refresh keeps the islands still on the page (islands mode).
4389
+ navigation.refresh = options.refresh === true;
4297
4390
  let clientNavigation;
4298
4391
 
4299
4392
  try {
@@ -4396,26 +4489,48 @@ ${generateUniversalRouterStateProperties()}
4396
4489
  this.currentPath = to;
4397
4490
  });
4398
4491
  } else {
4492
+ // A refresh renders every layout again; other navigations keep the ones on screen.
4399
4493
  const html = await this.fetchPage(
4400
4494
  url.pathname + url.search,
4401
4495
  undefined,
4402
4496
  options.refresh === true,
4403
4497
  true,
4404
4498
  navigation.controller.signal,
4499
+ options.refresh !== true,
4405
4500
  );
4406
4501
  if (!this.isCurrentNavigation(navigation, clientNavigation)) return;
4407
4502
  await farmClientRuntime.markNavigationLoaded(clientNavigation, html);
4408
4503
  if (!this.isCurrentNavigation(navigation, clientNavigation)) return;
4409
4504
  await this.runViewTransition(options.viewTransition, async () => {
4410
4505
  if (!this.isCurrentNavigation(navigation, clientNavigation)) return;
4411
- const swapped = await this.swapContent(
4506
+ let swapped = await this.swapContent(
4412
4507
  html,
4413
4508
  url.pathname + url.search,
4414
4509
  navigation,
4415
4510
  clientNavigation,
4416
4511
  );
4417
4512
  if (!this.isCurrentNavigation(navigation, clientNavigation)) return;
4418
- if (!swapped) {
4513
+ if (swapped === "segment-mismatch") {
4514
+ // The page changed since this segment was requested (a prefetch, a later
4515
+ // navigation): fetch the whole document instead.
4516
+ const documentHtml = await this.fetchPage(
4517
+ url.pathname + url.search,
4518
+ undefined,
4519
+ true,
4520
+ true,
4521
+ navigation.controller.signal,
4522
+ false,
4523
+ );
4524
+ if (!this.isCurrentNavigation(navigation, clientNavigation)) return;
4525
+ swapped = await this.swapContent(
4526
+ documentHtml,
4527
+ url.pathname + url.search,
4528
+ navigation,
4529
+ clientNavigation,
4530
+ );
4531
+ if (!this.isCurrentNavigation(navigation, clientNavigation)) return;
4532
+ }
4533
+ if (!swapped || swapped === "segment-mismatch") {
4419
4534
  throw new Error("Farm could not swap the target document");
4420
4535
  }
4421
4536
  this.writeHistoryEntry(action, url.pathname + url.search, options.state, url);
@@ -4465,8 +4580,8 @@ ${generateUniversalRouterStateProperties()}
4465
4580
  });
4466
4581
  },
4467
4582
 
4468
- fetchPage: async function(url, interceptFrom, fresh = false, recover = true, signal) {
4469
- return this.fetchPrefetchedDocument(url, interceptFrom, fresh, recover, signal);
4583
+ fetchPage: async function(url, interceptFrom, fresh = false, recover = true, signal, layoutChain = true) {
4584
+ return this.fetchPrefetchedDocument(url, interceptFrom, fresh, recover, signal, true, layoutChain);
4470
4585
  },
4471
4586
 
4472
4587
  swapContent: async function(html, targetPath, navigation, clientNavigation) {
@@ -4487,6 +4602,14 @@ ${generateUniversalRouterStateProperties()}
4487
4602
  // whole document (and remounting every isolated client boundary).
4488
4603
  const newRoot = doc.getElementById("root") || doc.body;
4489
4604
  const currentRoot = document.getElementById("root") || document.body;
4605
+ ${islandValues ? `const isSegment = Boolean(newRoot?.querySelector('[data-farm-layout-kept="true"]'));
4606
+ // A segment needs this page's kept layouts in place, outside a React-owned root.
4607
+ if (
4608
+ isSegment &&
4609
+ (!currentRoot || reactRootContainer === currentRoot || !fitsSegmentResponse(currentRoot, newRoot))
4610
+ ) {
4611
+ return "segment-mismatch";
4612
+ }` : ""}
4490
4613
  if (!newRoot || !currentRoot) {
4491
4614
  if (!isNavigationCurrent()) return false;
4492
4615
  return this.swapDocument(doc);
@@ -4517,13 +4640,16 @@ ${generateUniversalRouterStateProperties()}
4517
4640
  }
4518
4641
  }
4519
4642
 
4643
+ ${islandValues ? `// A payload-only page renders only in a React root that rebuilds it.
4644
+ if (nextPage?.querySelector('script[type="f/tree"][partial]')) return "segment-mismatch";` : ""}
4520
4645
  const rootWasReactOwned = reactRootContainer === currentRoot;
4521
4646
  resetReactRoot();
4522
4647
  resetRouteSlotRoots();
4523
4648
  const replacedSharedBoundary = rootWasReactOwned
4524
4649
  ? null
4525
- : replaceSharedLayoutBoundary(currentRoot, newRoot);
4650
+ : replaceSharedLayoutBoundary(currentRoot, newRoot, navigation?.refresh === true);
4526
4651
  let isolatedHydrationScope = replacedSharedBoundary || currentRoot;
4652
+ ${islandValues ? 'if (!replacedSharedBoundary && isSegment) return "segment-mismatch";' : ""}
4527
4653
  if (!replacedSharedBoundary) {
4528
4654
  ${isolatedHydrationEnabled ? "disposeFarmIsolatedClientBoundaries(currentRoot);" : ""}
4529
4655
  currentRoot.innerHTML = newRoot.innerHTML;
@@ -4606,7 +4732,7 @@ ${generateUniversalRouterStateProperties()}
4606
4732
  // navigation (double fetch per prefetched link) and sent
4607
4733
  // X-Farm-Intercept-From, which bypasses the shared cache server-side.
4608
4734
  const pathname = url.pathname + url.search;
4609
- if (this.readFreshPrefetch(pathname) !== undefined) return;
4735
+ if (this.readFreshPrefetch(this.prefetchRequest(pathname).cacheKey) !== undefined) return;
4610
4736
 
4611
4737
  return this.fetchPage(pathname, undefined, false, false)
4612
4738
  .catch(function(error) {
@@ -5478,6 +5604,7 @@ ReactDOMServer.configureApp(__farmAppSetup);`;
5478
5604
  }
5479
5605
  __name(generateFarmRendererAppSetupServerCode, "generateFarmRendererAppSetupServerCode");
5480
5606
  function generateVirtualEntryCode(apiRoutes, pageRoutes, layoutRoutes, routeSlots, errorRoutes, metadataImageRoutes, applicationMetadataRoutes, middlewareRoutes, redirectRoutes, configuredRewriteRoutes, configuredHeaderRoutes, openAPIReference, notFoundPath, instrumentationPath, config, farmDocsPrecompiledManifest, configModulePath, hasServerRuntimeIntegrations, hasRuntimeIntegrationConfig, hasConfiguredRuntimePlugins, hasServerRuntimePlugins, preset, i18nCatalogs, isolatedClientBoundaryModules, hydrationPlanCache) {
5607
+ const farmIslandsMode = resolveFarmServerComponentsMode(config.experimental?.serverComponents) === "islands";
5481
5608
  const hasCompressionRuntime = config.compress && resolveFarmInstrumentationRuntime(preset) === "nodejs";
5482
5609
  const servesAgentRobotsTxt = Boolean(config.agent?.crawlers?.enabled) && !applicationMetadataRoutes.some(
5483
5610
  (metadata) => metadata.kind === "robots" && metadata.pattern === "/"
@@ -5501,7 +5628,7 @@ function generateVirtualEntryCode(apiRoutes, pageRoutes, layoutRoutes, routeSlot
5501
5628
  );
5502
5629
  const hasReactSyncRender = isReactRenderer(config.renderer);
5503
5630
  const rendererServerImports = isReactRenderer(config.renderer) ? `import * as React from "react";
5504
- import * as ReactDOMServer from "react-dom/server";${hasIsolatedClientGraphRuntime ? '\nimport { isolateFarmServerPageGraph, wrapFarmIsolatedClientGraph } from "@farm.js/core/internal/isolated-boundary";\nimport { renderFarmServerTreePage } from "@farm.js/core/internal/server-tree";' : ""}` : `import React, * as ReactDOMServer from ${JSON.stringify(config.renderer.server)};${generateFarmRendererAppSetupServerCode(config)}`;
5631
+ import * as ReactDOMServer from "react-dom/server";${hasIsolatedClientGraphRuntime ? farmIslandsMode ? '\nimport { isolateFarmServerPageGraph, wrapFarmIsolatedClientGraph, renderFarmServerTreePage } from "@farm.js/core/internal/islands-runtime";' : '\nimport { isolateFarmServerPageGraph, wrapFarmIsolatedClientGraph } from "@farm.js/core/internal/isolated-boundary";\nimport { renderFarmServerTreePage } from "@farm.js/core/internal/server-tree";' : ""}` : `import React, * as ReactDOMServer from ${JSON.stringify(config.renderer.server)};${generateFarmRendererAppSetupServerCode(config)}`;
5505
5632
  const routeClientGraphServerRuntime = hasIsolatedClientGraphRuntime ? `function wrapFarmRouteClientGraph(element) {
5506
5633
  return wrapFarmIsolatedClientGraph(React, element);
5507
5634
  }
@@ -5514,13 +5641,16 @@ function isolateFarmRouteServerPage(element) {
5514
5641
 
5515
5642
  // An async page below a hydrating layout renders as a serialized tree the browser rebuilds in
5516
5643
  // the layout's React root, so its client components read the layout's context.
5517
- function renderFarmRouteServerTree(element) {
5518
- return renderFarmServerTreePage(React, element, { isolate: isolateFarmRouteServerPage });
5644
+ function renderFarmRouteServerTree(element, extra) {
5645
+ return renderFarmServerTreePage(React, element, {
5646
+ isolate: isolateFarmRouteServerPage,${farmIslandsMode ? "\n values: true," : ""}
5647
+ ...extra,
5648
+ });
5519
5649
  }` : `function wrapFarmRouteClientGraph(element) { return element; }
5520
5650
 
5521
5651
  function isolateFarmRouteServerPage(element) { return element; }
5522
5652
 
5523
- function renderFarmRouteServerTree(element) { return element; }`;
5653
+ function renderFarmRouteServerTree(element, extra) { return element; }`;
5524
5654
  const hasGeneratedMetadataImages = metadataImageRoutes.some(
5525
5655
  (image) => image.sourceType === "module"
5526
5656
  );
@@ -5558,7 +5688,7 @@ function renderFarmRouteServerTree(element) { return element; }`;
5558
5688
  const isolatedHydrationMode = resolveFarmIsolatedClientHydrationMode(
5559
5689
  config.experimental?.isolatedClientHydration,
5560
5690
  {
5561
- serverComponents: config.experimental?.serverComponents === true,
5691
+ serverComponents: resolveFarmServerComponentsMode(config.experimental?.serverComponents) === "rsc",
5562
5692
  hasUnsupportedIntegrationProvider: Boolean(unsupportedIntegrationProvider)
5563
5693
  }
5564
5694
  );
@@ -5566,6 +5696,10 @@ function renderFarmRouteServerTree(element) { return element; }`;
5566
5696
  config.renderer,
5567
5697
  Boolean(unsupportedIntegrationProvider)
5568
5698
  );
5699
+ const pageHydrationPlanOptions = {
5700
+ ...hydrationPlanOptions,
5701
+ serverOwners: resolveFarmServerComponentsMode(config.experimental?.serverComponents) === "islands"
5702
+ };
5569
5703
  const layoutHydrationPlans = layoutRoutes.map((layout) => ({
5570
5704
  ...layout,
5571
5705
  hydration: getCachedClientModuleHydrationPlan(
@@ -5590,7 +5724,7 @@ function renderFarmRouteServerTree(element) { return element; }`;
5590
5724
  config.root,
5591
5725
  isolatedHydrationMode,
5592
5726
  hydrationPlanCache,
5593
- hydrationPlanOptions
5727
+ pageHydrationPlanOptions
5594
5728
  )
5595
5729
  ])
5596
5730
  );
@@ -5876,7 +6010,14 @@ function renderFarmRouteServerTree(element) { return element; }`;
5876
6010
  withFarmRouteContext,
5877
6011
  createLateNotFoundRecovery,
5878
6012
  createLateRedirectRecovery,${hasFarmServerStorageConfig(config.storage) ? "\n _registerFarmStorageModules,\n disposeFarmStorage,\n initFarmStorage," : ""}
5879
- } from "@farm.js/core/internal/production-runtime";`;
6013
+ } from "@farm.js/core/internal/production-runtime";${farmIslandsMode ? `
6014
+ import { getSharedLayoutPrefixLength, handleFarmFormActionRequest, ignoreFarmHeldValues, installFarmIslandValues, parseFarmLayoutChainHeader } from "@farm.js/core/internal/production-runtime";
6015
+ import { installFarmIslandsServer } from "@farm.js/core/internal/islands-server";
6016
+ installFarmIslandsServer();
6017
+ const farmFormActionsConfig = ${JSON.stringify(resolveServerActionsConfig(config.serverActions))};
6018
+ installFarmIslandValues();
6019
+ ${islandsActionKeyCode()}
6020
+ ${FARM_SEGMENT_NAVIGATION_SERVER_RUNTIME}` : ""}`;
5880
6021
  const productionSiteTelemetryImport = config.telemetry ? `import { createFarmProductionSiteReporter } from "@farm.js/core/internal/product-telemetry-runtime";` : "";
5881
6022
  const metadataImageRuntimeImport = hasGeneratedMetadataImages ? `import { createFarmMetadataImageResponse } from "@farm.js/core/internal/metadata-image-runtime";` : "";
5882
6023
  const pluginRuntimeImport = hasPluginRuntime ? `import { PluginManager } from "@farm.js/core/plugin";` : "";
@@ -7029,7 +7170,7 @@ const farmClientEntryPreloadTags = farmClientModulePreloads
7029
7170
  : "";
7030
7171
  // The client modules a document's markup loads: its islands' boundaries and the
7031
7172
  // client references of its server tree.
7032
- const FARM_CLIENT_MODULE_REFERENCE_PATTERN = /data-farm-client-boundary="([^"]+)"|"r":"(\\/[^"]+)"/g;
7173
+ const FARM_CLIENT_MODULE_REFERENCE_PATTERN = /<f-island src="([^"]+)"|"r":"(\\/[^"]+)"/g;
7033
7174
 
7034
7175
  function renderFarmClientModulePreload(index) {
7035
7176
  return '\\n <link rel="modulepreload" href="/' +
@@ -8601,6 +8742,11 @@ ${hasServerRuntimeIntegrations ? `
8601
8742
  // Handle page routes (SSR)
8602
8743
  emitFarmEvent({ type: "render.start", route: pathname, pathname });
8603
8744
  const matchedRoute = matchPageRoute(routePathname);
8745
+ ${farmIslandsMode ? `// Islands mode: a form or client component posting a server action to this page.
8746
+ if (matchedRoute && request.method === "POST") {
8747
+ const actionResponse = await handleFarmFormActionRequest(request, farmFormActionsConfig);
8748
+ if (actionResponse) return applyProductionMiddlewareHeaders(actionResponse, middlewareHeaders);
8749
+ }` : ""}
8604
8750
  if (matchedRoute) {
8605
8751
  const trailingSlashLocation = resolveFarmTrailingSlashRedirect(
8606
8752
  url,
@@ -8619,6 +8765,21 @@ ${hasServerRuntimeIntegrations ? `
8619
8765
  emitFarmEvent({ type: "route.matched", pathname, route: route.pattern, params });
8620
8766
 
8621
8767
  try {
8768
+ ${farmIslandsMode ? `// Islands mode: the layouts the navigating browser keeps, decided before the shell cache
8769
+ // so a PPR route caches each segment under its own key. A static page, a layout that
8770
+ // hydrates as a root, or a route slot always renders whole.
8771
+ const farmSegmentLayouts = getApplicableLayouts(
8772
+ routePathname,
8773
+ route.directory || route.pattern,
8774
+ );
8775
+ const farmKeptLayoutCount =
8776
+ resolveRouteRenderingView(route).ssg ||
8777
+ farmSegmentLayouts.some((layout) => layout.shouldHydrate === true) ||
8778
+ matchRouteSlots(routePathname, request.headers.get("x-farm-intercept-from")).length > 0
8779
+ ? 0
8780
+ : countFarmKeptLayouts(request, farmSegmentLayouts, params);
8781
+ // The root layout always renders, so keeping one layout keeps nothing.
8782
+ const farmKeptLayouts = farmKeptLayoutCount > 1 ? farmKeptLayoutCount : 0;` : `const farmKeptLayouts = 0;`}
8622
8783
  const pprConfig = resolvePPRConfig(route);
8623
8784
  const pprBypassReason = pprConfig.enabled
8624
8785
  ? getPPRShellBypassReason(request, middlewareData, middlewareContext)
@@ -8631,7 +8792,7 @@ ${hasServerRuntimeIntegrations ? `
8631
8792
  farmLocaleResolution && farmI18nConfig.routing !== "none"
8632
8793
  ? resolveFarmI18nAlternateOrigin(request)
8633
8794
  : ""
8634
- )
8795
+ ) + (farmKeptLayouts ? ":segment:" + farmKeptLayouts : "")
8635
8796
  : null;
8636
8797
  if (pprConfig.enabled && pprBypassReason) {
8637
8798
  emitFarmEvent({ type: "ppr.shell.bypass", route: pathname, reason: pprBypassReason });
@@ -8658,6 +8819,10 @@ ${hasServerRuntimeIntegrations ? `
8658
8819
  "x-farm-preload-buffered": getFarmBufferedPreloadMarker(cachedPPRShell),
8659
8820
  ...(farmFontPreloadHeader ? { "Link": farmFontPreloadHeader } : {}),
8660
8821
  ...getPPRHeaders("hit", pprConfig),
8822
+ // A segment is one navigation's answer, never a CDN entry: some CDNs ignore Vary.
8823
+ ...(farmKeptLayouts
8824
+ ? { "Cache-Control": "private, no-store", "Vary": "F-Layouts" }
8825
+ : {}),
8661
8826
  },
8662
8827
  }), middlewareHeaders), cachedPPRShell);
8663
8828
  }
@@ -8884,6 +9049,21 @@ ${hasServerRuntimeIntegrations ? `
8884
9049
  };
8885
9050
  });
8886
9051
 
9052
+ ${farmIslandsMode ? `// Islands mode: a route a shared cache may store (a PPR shell, a static page) renders
9053
+ // whole for every request, so a cache hit stays a hit. Other routes leave out what the
9054
+ // navigating browser keeps: the layouts it shows and the values it holds.
9055
+ const farmSharedCacheableRoute = Boolean(getRouteSharedCacheControl(route, pprCanCache));
9056
+ if (farmSharedCacheableRoute) ignoreFarmHeldValues();
9057
+ const farmLayoutKeyOf = getFarmLayoutKey;
9058
+ // A navigation the browser renders in its layout's React root rebuilds a server-tree page
9059
+ // from its payload, so the page's rendered HTML would go unused.
9060
+ const farmPayloadOnlyNavigation =
9061
+ !farmSharedCacheableRoute &&
9062
+ shouldHydrateLayout &&
9063
+ route.serverTree === true &&
9064
+ !route.shouldHydrate &&
9065
+ request.headers.get("f-render") === "tree";` : `const farmLayoutKeyOf = null;
9066
+ const farmPayloadOnlyNavigation = false;`}
8887
9067
  const renderPageElement = async () => {
8888
9068
  // First, render the page content
8889
9069
  let pageElement;
@@ -8910,7 +9090,10 @@ ${hasServerRuntimeIntegrations ? `
8910
9090
  pageElement = wrapFarmRouteClientGraph(pageElement);
8911
9091
  } else if (shouldHydrateLayout && !route.shouldHydrate) {
8912
9092
  pageElement = route.serverTree
8913
- ? await renderFarmRouteServerTree(pageElement)
9093
+ ? await renderFarmRouteServerTree(
9094
+ pageElement,
9095
+ farmPayloadOnlyNavigation ? { payloadOnly: true } : undefined,
9096
+ )
8914
9097
  : isolateFarmRouteServerPage(pageElement);
8915
9098
  }
8916
9099
 
@@ -8935,6 +9118,22 @@ ${hasServerRuntimeIntegrations ? `
8935
9118
  for (let i = applicableLayouts.length - 1; i >= 0; i--) {
8936
9119
  const layout = applicableLayouts[i];
8937
9120
  const LayoutComponent = layout.module.default;
9121
+ // Islands mode: a layout the browser keeps sends only its boundary, so the client
9122
+ // knows where the rest goes. The root layout always renders: it may own the document.
9123
+ if (LayoutComponent && i > 0 && i < farmKeptLayouts) {
9124
+ wrappedElement = React.createElement(
9125
+ "div",
9126
+ {
9127
+ "data-farm-layout-boundary": "true",
9128
+ "data-farm-layout-pattern": layout.pattern,
9129
+ "data-farm-layout-key": farmLayoutKeyOf(layout.pattern, params),
9130
+ "data-farm-layout-kept": "true",
9131
+ style: { display: "contents" },
9132
+ },
9133
+ wrappedElement,
9134
+ );
9135
+ continue;
9136
+ }
8938
9137
  if (LayoutComponent) {
8939
9138
  const slotProps = {};
8940
9139
  for (const slot of renderedRouteSlots) {
@@ -8961,6 +9160,9 @@ ${hasServerRuntimeIntegrations ? `
8961
9160
  {
8962
9161
  "data-farm-layout-boundary": "true",
8963
9162
  "data-farm-layout-pattern": layout.pattern,
9163
+ "data-farm-layout-key": farmLayoutKeyOf
9164
+ ? farmLayoutKeyOf(layout.pattern, params)
9165
+ : undefined,
8964
9166
  style: { display: "contents" },
8965
9167
  },
8966
9168
  wrappedElement,
@@ -9071,7 +9273,7 @@ ${hasServerRuntimeIntegrations ? `
9071
9273
  farmLocaleResolution,
9072
9274
  );
9073
9275
  const hasRequestScopedRender = Boolean(
9074
- pageStatus >= 400 ||
9276
+ pageStatus >= 400 ||${farmIslandsMode ? "\n farmKeptLayouts > 0 ||\n farmPayloadOnlyNavigation ||" : ""}
9075
9277
  renderReadRequest ||
9076
9278
  request.headers.get("x-farm-intercept-from") ||
9077
9279
  hasPrivateRequestHeaders ||
@@ -9091,7 +9293,12 @@ ${hasServerRuntimeIntegrations ? `
9091
9293
  if (renderedPage.stream || hasRequestScopedRender || !sharedCacheControl) {
9092
9294
  responseHeaders["Cache-Control"] = "private, no-store";
9093
9295
  }
9094
- const farmI18nSnapshot = getFarmI18nSnapshot();
9296
+ const farmI18nSnapshot = getFarmI18nSnapshot();${farmIslandsMode ? `
9297
+ // Islands mode: a navigation that names the values it holds, or the layouts it shows,
9298
+ // gets HTML without them.
9299
+ responseHeaders["Vary"] = farmSharedCacheableRoute
9300
+ ? "F-Layouts"
9301
+ : "F-Values, F-Layouts, F-Render";` : ""}
9095
9302
  let html = renderedPage.html;
9096
9303
 
9097
9304
  // Check if the layout already rendered a full HTML document
@@ -11003,6 +11210,12 @@ async function copyPrismaClientForVercel(root, nitroFuncDir, fs4) {
11003
11210
  await writeNitroOutputPackage(nitroFuncDir, functionPackage, fs4);
11004
11211
  }
11005
11212
  __name(copyPrismaClientForVercel, "copyPrismaClientForVercel");
11213
+ function islandsActionKeyCode() {
11214
+ const key = randomBytes(32).toString("base64url");
11215
+ return `import { setBuildDefaults as __farmIslxBuildDefaults } from "@farm.js/core/internal/islx-server";
11216
+ __farmIslxBuildDefaults({ key: ${JSON.stringify(key)} });`;
11217
+ }
11218
+ __name(islandsActionKeyCode, "islandsActionKeyCode");
11006
11219
 
11007
11220
  // src/build/project-module-runner.ts
11008
11221
  async function createFarmProjectModuleSsrEnvironment() {