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

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 (254) hide show
  1. package/README.md +1 -1
  2. package/dist/agent-runtime.d.mts +2 -1
  3. package/dist/agent-runtime.d.ts +2 -1
  4. package/dist/api/route-manager.cjs +410 -15
  5. package/dist/api/route-manager.cjs.map +1 -1
  6. package/dist/api/route-manager.d.mts +4 -2
  7. package/dist/api/route-manager.d.ts +4 -2
  8. package/dist/api/route-manager.mjs +9 -8
  9. package/dist/api/runtime.cjs +748 -9
  10. package/dist/api/runtime.cjs.map +1 -1
  11. package/dist/api/runtime.d.mts +3 -16
  12. package/dist/api/runtime.d.ts +3 -16
  13. package/dist/api/runtime.mjs +8 -1
  14. package/dist/api.cjs +1243 -342
  15. package/dist/api.cjs.map +1 -1
  16. package/dist/api.d.mts +5 -147
  17. package/dist/api.d.ts +5 -147
  18. package/dist/api.mjs +51 -21
  19. package/dist/{app-CFRNJXP1.d.ts → app-BjN-da13.d.ts} +38 -3
  20. package/dist/{app-BiX4qb-d.d.mts → app-CakAr8Be.d.mts} +38 -3
  21. package/dist/app-markdown.cjs +1 -1
  22. package/dist/app-markdown.cjs.map +1 -1
  23. package/dist/app-markdown.d.mts +2 -1
  24. package/dist/app-markdown.d.ts +2 -1
  25. package/dist/app-markdown.mjs +1 -1
  26. package/dist/cache.cjs +414 -12
  27. package/dist/cache.cjs.map +1 -1
  28. package/dist/cache.d.mts +120 -6
  29. package/dist/cache.d.ts +120 -6
  30. package/dist/cache.mjs +11 -3
  31. package/dist/{chunk-Y7A27276.mjs → chunk-2CUKEMVR.mjs} +349 -15
  32. package/dist/chunk-2CUKEMVR.mjs.map +1 -0
  33. package/dist/{chunk-QF4PHCMA.mjs → chunk-2ED5Q2GH.mjs} +3 -3
  34. package/dist/chunk-2ED5Q2GH.mjs.map +1 -0
  35. package/dist/{chunk-GZP5W4K3.mjs → chunk-32W4QEJP.mjs} +1 -1
  36. package/dist/chunk-32W4QEJP.mjs.map +1 -0
  37. package/dist/{chunk-TRORP7E4.mjs → chunk-3U3ZUQAQ.mjs} +2 -2
  38. package/dist/{chunk-25D7G34K.mjs → chunk-65A7QIKI.mjs} +5 -5
  39. package/dist/{chunk-25D7G34K.mjs.map → chunk-65A7QIKI.mjs.map} +1 -1
  40. package/dist/{chunk-G3B5BRDY.mjs → chunk-AJWRO5WE.mjs} +539 -61
  41. package/dist/chunk-AJWRO5WE.mjs.map +1 -0
  42. package/dist/chunk-ALCLXXTY.mjs +187 -0
  43. package/dist/chunk-ALCLXXTY.mjs.map +1 -0
  44. package/dist/{chunk-CHFHNEMO.mjs → chunk-AOBXKNS5.mjs} +627 -84
  45. package/dist/chunk-AOBXKNS5.mjs.map +1 -0
  46. package/dist/{chunk-B6N4ZB2H.mjs → chunk-C2ROET2V.mjs} +3 -3
  47. package/dist/{chunk-JN3UU635.mjs → chunk-EJ7T4TPB.mjs} +2 -2
  48. package/dist/chunk-EJ7T4TPB.mjs.map +1 -0
  49. package/dist/{chunk-ZJQNATYV.mjs → chunk-FRPWCMMG.mjs} +3 -3
  50. package/dist/chunk-FRPWCMMG.mjs.map +1 -0
  51. package/dist/{chunk-QM6VV26B.mjs → chunk-GQVGIUSN.mjs} +3 -3
  52. package/dist/{chunk-QM6VV26B.mjs.map → chunk-GQVGIUSN.mjs.map} +1 -1
  53. package/dist/{chunk-UREJA4GZ.mjs → chunk-GXASWWJU.mjs} +1 -1
  54. package/dist/{chunk-UREJA4GZ.mjs.map → chunk-GXASWWJU.mjs.map} +1 -1
  55. package/dist/{chunk-3QJO55ZF.mjs → chunk-HNIQFZKB.mjs} +5 -3
  56. package/dist/{chunk-3QJO55ZF.mjs.map → chunk-HNIQFZKB.mjs.map} +1 -1
  57. package/dist/{chunk-PRNYWD7K.mjs → chunk-JDEOUK5V.mjs} +67 -239
  58. package/dist/chunk-JDEOUK5V.mjs.map +1 -0
  59. package/dist/{chunk-O3HADRW6.mjs → chunk-MIUW47JX.mjs} +2 -2
  60. package/dist/{chunk-O3HADRW6.mjs.map → chunk-MIUW47JX.mjs.map} +1 -1
  61. package/dist/{chunk-UHE2TTLK.mjs → chunk-NM3CRAAL.mjs} +9 -8
  62. package/dist/chunk-NM3CRAAL.mjs.map +1 -0
  63. package/dist/chunk-PFE6GMNE.mjs +603 -0
  64. package/dist/chunk-PFE6GMNE.mjs.map +1 -0
  65. package/dist/{chunk-S2XHZS7W.mjs → chunk-QGQX7SFC.mjs} +2 -2
  66. package/dist/chunk-QGQX7SFC.mjs.map +1 -0
  67. package/dist/{chunk-RKI6TN3A.mjs → chunk-QM746KUO.mjs} +9 -2
  68. package/dist/chunk-QM746KUO.mjs.map +1 -0
  69. package/dist/chunk-RBRLLZL5.mjs +81 -0
  70. package/dist/chunk-RBRLLZL5.mjs.map +1 -0
  71. package/dist/{chunk-HXP3ZSPC.mjs → chunk-SADGIRS2.mjs} +3 -3
  72. package/dist/{chunk-6XDUHOEM.mjs → chunk-TQAEEJB4.mjs} +3 -3
  73. package/dist/{chunk-AGS7UJ52.mjs → chunk-UB5UOSHB.mjs} +24 -12
  74. package/dist/chunk-UB5UOSHB.mjs.map +1 -0
  75. package/dist/{chunk-SXZTEK3V.mjs → chunk-UXUAWNO5.mjs} +2 -2
  76. package/dist/chunk-V3XURYJO.mjs +756 -0
  77. package/dist/chunk-V3XURYJO.mjs.map +1 -0
  78. package/dist/{chunk-TU4YJICB.mjs → chunk-VVKWFZAH.mjs} +41 -16
  79. package/dist/chunk-VVKWFZAH.mjs.map +1 -0
  80. package/dist/{chunk-JLWMCADZ.mjs → chunk-VY2UYN5R.mjs} +24 -4
  81. package/dist/chunk-VY2UYN5R.mjs.map +1 -0
  82. package/dist/{chunk-QFQRHRZS.mjs → chunk-W2CRQFF6.mjs} +151 -23
  83. package/dist/chunk-W2CRQFF6.mjs.map +1 -0
  84. package/dist/chunk-W4UIVMVI.mjs +10 -0
  85. package/dist/chunk-W4UIVMVI.mjs.map +1 -0
  86. package/dist/{chunk-Y2OJJD7R.mjs → chunk-XIVV5IWN.mjs} +7 -9
  87. package/dist/chunk-XIVV5IWN.mjs.map +1 -0
  88. package/dist/{chunk-OYXO65LI.mjs → chunk-YW7OBE6Q.mjs} +4 -4
  89. package/dist/chunk-YW7OBE6Q.mjs.map +1 -0
  90. package/dist/{chunk-YHU7SS6L.mjs → chunk-Z5CQMP54.mjs} +11 -11
  91. package/dist/{chunk-SOU3Q3ZA.mjs → chunk-ZZ57EH5Z.mjs} +1 -1
  92. package/dist/chunk-ZZ57EH5Z.mjs.map +1 -0
  93. package/dist/{client-D_yUjVhe.d.mts → client-BT1mFQas.d.mts} +55 -10
  94. package/dist/{client-Dkc03WP8.d.ts → client-Nn0q4eO4.d.ts} +55 -10
  95. package/dist/{client-plugins-BZnpeTGA.d.ts → client-plugins-Cw4qUGsw.d.ts} +7 -0
  96. package/dist/{client-plugins-g4bzuCmo.d.mts → client-plugins-DQQ1adXM.d.mts} +7 -0
  97. package/dist/client-plugins.d.mts +2 -1
  98. package/dist/client-plugins.d.ts +2 -1
  99. package/dist/client.cjs +922 -91
  100. package/dist/client.cjs.map +1 -1
  101. package/dist/client.d.mts +121 -3
  102. package/dist/client.d.ts +121 -3
  103. package/dist/client.mjs +23 -16
  104. package/dist/config.d.mts +2 -1
  105. package/dist/config.d.ts +2 -1
  106. package/dist/cron.cjs.map +1 -1
  107. package/dist/cron.mjs +1 -1
  108. package/dist/{devtools-AE4RVXCM.mjs → devtools-LVC3VB5P.mjs} +10 -10
  109. package/dist/{devtools-client-6WPY2AQU.mjs → devtools-client-3XRTBND5.mjs} +2 -11
  110. package/dist/devtools-client-3XRTBND5.mjs.map +1 -0
  111. package/dist/docs.cjs +14 -2
  112. package/dist/docs.cjs.map +1 -1
  113. package/dist/docs.mjs +10 -10
  114. package/dist/i18n/server.cjs +2 -2
  115. package/dist/i18n/server.cjs.map +1 -1
  116. package/dist/i18n/server.mjs +1 -1
  117. package/dist/index.cjs +2852 -463
  118. package/dist/index.cjs.map +1 -1
  119. package/dist/index.d.mts +13 -12
  120. package/dist/index.d.ts +13 -12
  121. package/dist/index.mjs +152 -109
  122. package/dist/index.mjs.map +1 -1
  123. package/dist/integrations.d.mts +2 -1
  124. package/dist/integrations.d.ts +2 -1
  125. package/dist/internal/build-runtime.cjs +1616 -149
  126. package/dist/internal/build-runtime.cjs.map +1 -1
  127. package/dist/internal/build-runtime.d.mts +4 -3
  128. package/dist/internal/build-runtime.d.ts +4 -3
  129. package/dist/internal/build-runtime.mjs +27 -25
  130. package/dist/internal/client-runtime.cjs.map +1 -1
  131. package/dist/internal/client-runtime.mjs +1 -1
  132. package/dist/internal/config-runtime.cjs +13 -2
  133. package/dist/internal/config-runtime.cjs.map +1 -1
  134. package/dist/internal/config-runtime.d.mts +3 -2
  135. package/dist/internal/config-runtime.d.ts +3 -2
  136. package/dist/internal/config-runtime.mjs +9 -9
  137. package/dist/internal/production-runtime.cjs +285 -9
  138. package/dist/internal/production-runtime.cjs.map +1 -1
  139. package/dist/internal/production-runtime.d.mts +4 -4
  140. package/dist/internal/production-runtime.d.ts +4 -4
  141. package/dist/internal/production-runtime.mjs +10 -8
  142. package/dist/{metadata-DAXRaOHx.d.ts → metadata-BAPg_Nmo.d.ts} +1 -1
  143. package/dist/{metadata-C9NZxMDW.d.mts → metadata-_6i9oFG3.d.mts} +1 -1
  144. package/dist/middleware.cjs +2 -2
  145. package/dist/middleware.cjs.map +1 -1
  146. package/dist/middleware.d.mts +4 -3
  147. package/dist/middleware.d.ts +4 -3
  148. package/dist/middleware.mjs +3 -3
  149. package/dist/navigation.cjs +40 -15
  150. package/dist/navigation.cjs.map +1 -1
  151. package/dist/navigation.mjs +3 -3
  152. package/dist/{nitro-KME62MWG.mjs → nitro-QO5LV6QK.mjs} +11 -13
  153. package/dist/{nitro-KME62MWG.mjs.map → nitro-QO5LV6QK.mjs.map} +1 -1
  154. package/dist/plugin.cjs +1032 -92
  155. package/dist/plugin.cjs.map +1 -1
  156. package/dist/plugin.d.mts +2 -1
  157. package/dist/plugin.d.ts +2 -1
  158. package/dist/plugin.mjs +23 -21
  159. package/dist/{production-runtime-DRkCHUvJ.d.ts → production-runtime-BoJDc5mc.d.ts} +1 -1
  160. package/dist/{production-runtime-flrjp_nC.d.mts → production-runtime-DPfgMV9Y.d.mts} +1 -1
  161. package/dist/routes.cjs +276 -6
  162. package/dist/routes.cjs.map +1 -1
  163. package/dist/routes.d.mts +1 -1
  164. package/dist/routes.d.ts +1 -1
  165. package/dist/routes.mjs +4 -4
  166. package/dist/runtime-9nQjVM7X.d.mts +206 -0
  167. package/dist/runtime-DgeS2skB.d.ts +206 -0
  168. package/dist/server-action-security.cjs +28 -10
  169. package/dist/server-action-security.cjs.map +1 -1
  170. package/dist/server-action-security.d.mts +2 -1
  171. package/dist/server-action-security.d.ts +2 -1
  172. package/dist/server-action-security.mjs +2 -2
  173. package/dist/server-fn-client.cjs.map +1 -1
  174. package/dist/server-fn-client.d.mts +1 -0
  175. package/dist/server-fn-client.d.ts +1 -0
  176. package/dist/server-fn-client.mjs +1 -1
  177. package/dist/server-fn.cjs +785 -3
  178. package/dist/server-fn.cjs.map +1 -1
  179. package/dist/server-fn.d.mts +10 -1
  180. package/dist/server-fn.d.ts +10 -1
  181. package/dist/server-fn.mjs +6 -3
  182. package/dist/server-plugins.d.mts +3 -2
  183. package/dist/server-plugins.d.ts +3 -2
  184. package/dist/server-query-client.cjs +278 -7
  185. package/dist/server-query-client.cjs.map +1 -1
  186. package/dist/server-query-client.mjs +4 -4
  187. package/dist/server-query.cjs +381 -10
  188. package/dist/server-query.cjs.map +1 -1
  189. package/dist/server-query.mjs +5 -5
  190. package/dist/server.cjs +1233 -118
  191. package/dist/server.cjs.map +1 -1
  192. package/dist/server.d.mts +8 -7
  193. package/dist/server.d.ts +8 -7
  194. package/dist/server.mjs +53 -33
  195. package/dist/server.mjs.map +1 -1
  196. package/dist/testing.cjs +436 -25
  197. package/dist/testing.cjs.map +1 -1
  198. package/dist/testing.d.mts +4 -3
  199. package/dist/testing.d.ts +4 -3
  200. package/dist/testing.mjs +19 -18
  201. package/dist/testing.mjs.map +1 -1
  202. package/dist/transport-BmbGTXA5.d.mts +49 -0
  203. package/dist/transport-BmbGTXA5.d.ts +49 -0
  204. package/dist/{utils-DOXXivjL.d.mts → utils-CHXlMDkg.d.mts} +1 -1
  205. package/dist/{utils-DA1yo54_.d.ts → utils-Drsyz1Vj.d.ts} +1 -1
  206. package/dist/version.cjs +36 -0
  207. package/dist/version.cjs.map +1 -0
  208. package/dist/version.d.mts +3 -0
  209. package/dist/version.d.ts +3 -0
  210. package/dist/version.mjs +8 -0
  211. package/dist/version.mjs.map +1 -0
  212. package/dist/vite.cjs +1039 -93
  213. package/dist/vite.cjs.map +1 -1
  214. package/dist/vite.d.mts +2 -1
  215. package/dist/vite.d.ts +2 -1
  216. package/dist/vite.mjs +23 -21
  217. package/dist/workflows.cjs +6 -8
  218. package/dist/workflows.cjs.map +1 -1
  219. package/dist/workflows.mjs +1 -1
  220. package/package.json +12 -5
  221. package/types/api.d.ts +44 -0
  222. package/types/client.d.ts +220 -16
  223. package/dist/chunk-4PTK6KT4.mjs +0 -364
  224. package/dist/chunk-4PTK6KT4.mjs.map +0 -1
  225. package/dist/chunk-AGS7UJ52.mjs.map +0 -1
  226. package/dist/chunk-CHFHNEMO.mjs.map +0 -1
  227. package/dist/chunk-EVGBEZDF.mjs +0 -215
  228. package/dist/chunk-EVGBEZDF.mjs.map +0 -1
  229. package/dist/chunk-G3B5BRDY.mjs.map +0 -1
  230. package/dist/chunk-GZP5W4K3.mjs.map +0 -1
  231. package/dist/chunk-JLWMCADZ.mjs.map +0 -1
  232. package/dist/chunk-JN3UU635.mjs.map +0 -1
  233. package/dist/chunk-OYXO65LI.mjs.map +0 -1
  234. package/dist/chunk-PRNYWD7K.mjs.map +0 -1
  235. package/dist/chunk-QF4PHCMA.mjs.map +0 -1
  236. package/dist/chunk-QFQRHRZS.mjs.map +0 -1
  237. package/dist/chunk-RKI6TN3A.mjs.map +0 -1
  238. package/dist/chunk-S2XHZS7W.mjs.map +0 -1
  239. package/dist/chunk-SOU3Q3ZA.mjs.map +0 -1
  240. package/dist/chunk-TU4YJICB.mjs.map +0 -1
  241. package/dist/chunk-TXCFGOHW.mjs +0 -42
  242. package/dist/chunk-TXCFGOHW.mjs.map +0 -1
  243. package/dist/chunk-UHE2TTLK.mjs.map +0 -1
  244. package/dist/chunk-Y2OJJD7R.mjs.map +0 -1
  245. package/dist/chunk-Y7A27276.mjs.map +0 -1
  246. package/dist/chunk-ZJQNATYV.mjs.map +0 -1
  247. package/dist/devtools-client-6WPY2AQU.mjs.map +0 -1
  248. /package/dist/{chunk-TRORP7E4.mjs.map → chunk-3U3ZUQAQ.mjs.map} +0 -0
  249. /package/dist/{chunk-B6N4ZB2H.mjs.map → chunk-C2ROET2V.mjs.map} +0 -0
  250. /package/dist/{chunk-HXP3ZSPC.mjs.map → chunk-SADGIRS2.mjs.map} +0 -0
  251. /package/dist/{chunk-6XDUHOEM.mjs.map → chunk-TQAEEJB4.mjs.map} +0 -0
  252. /package/dist/{chunk-SXZTEK3V.mjs.map → chunk-UXUAWNO5.mjs.map} +0 -0
  253. /package/dist/{chunk-YHU7SS6L.mjs.map → chunk-Z5CQMP54.mjs.map} +0 -0
  254. /package/dist/{devtools-AE4RVXCM.mjs.map → devtools-LVC3VB5P.mjs.map} +0 -0
@@ -5,7 +5,7 @@ import {
5
5
  addMetadataImageReference,
6
6
  mergeMetadata,
7
7
  renderMetadataHead
8
- } from "./chunk-ZJQNATYV.mjs";
8
+ } from "./chunk-FRPWCMMG.mjs";
9
9
  import {
10
10
  farmEnvironmentFunctionsPlugin
11
11
  } from "./chunk-V6WE6JSZ.mjs";
@@ -18,6 +18,11 @@ import {
18
18
  import {
19
19
  writeFileIfChanged
20
20
  } from "./chunk-USWZZUEH.mjs";
21
+ import {
22
+ getFarmRedirectError,
23
+ isFarmNotFoundError,
24
+ isFarmRedirectError
25
+ } from "./chunk-7HO6AEOP.mjs";
21
26
  import {
22
27
  getFarmAppDirectories,
23
28
  getFarmLayerAliases,
@@ -30,11 +35,14 @@ import {
30
35
  } from "./chunk-7MABZJIM.mjs";
31
36
  import {
32
37
  normalizeRouteRules
33
- } from "./chunk-OYXO65LI.mjs";
38
+ } from "./chunk-YW7OBE6Q.mjs";
34
39
  import {
35
40
  getPublicFarmImageConfig,
36
41
  resolveFarmImageConfig
37
42
  } from "./chunk-GY2STC2S.mjs";
43
+ import {
44
+ resolveServerActionsConfig
45
+ } from "./chunk-UB5UOSHB.mjs";
38
46
  import {
39
47
  createMarkdownMirrorResponse,
40
48
  resolveMarkdownConfig
@@ -45,16 +53,13 @@ import {
45
53
  isFarmMarkdownPageFile,
46
54
  loadFarmMdxComponents,
47
55
  resolveMdxConfig
48
- } from "./chunk-S2XHZS7W.mjs";
56
+ } from "./chunk-QGQX7SFC.mjs";
49
57
  import {
50
58
  resolveWorkflowsConfig
51
- } from "./chunk-Y2OJJD7R.mjs";
59
+ } from "./chunk-XIVV5IWN.mjs";
52
60
  import {
53
61
  resolveCronConfig
54
- } from "./chunk-UREJA4GZ.mjs";
55
- import {
56
- resolveServerActionsConfig
57
- } from "./chunk-AGS7UJ52.mjs";
62
+ } from "./chunk-GXASWWJU.mjs";
58
63
  import {
59
64
  dispatchIntegrationRequest,
60
65
  getIntegrationDocumentNavigationMatchers,
@@ -63,14 +68,9 @@ import {
63
68
  getRequestContextSnapshot,
64
69
  matchIntegrationRoute
65
70
  } from "./chunk-K4667E2Q.mjs";
66
- import {
67
- getFarmRedirectError,
68
- isFarmNotFoundError,
69
- isFarmRedirectError
70
- } from "./chunk-7HO6AEOP.mjs";
71
71
  import {
72
72
  MiddlewareManager
73
- } from "./chunk-O3HADRW6.mjs";
73
+ } from "./chunk-MIUW47JX.mjs";
74
74
  import {
75
75
  _clearCurrentMiddlewareContext,
76
76
  _clearCurrentMiddlewareData,
@@ -91,14 +91,14 @@ import {
91
91
  discoverProgrammaticRoutePaths,
92
92
  findProgrammaticRouteFiles,
93
93
  loadProgrammaticRouteManifests
94
- } from "./chunk-YHU7SS6L.mjs";
94
+ } from "./chunk-Z5CQMP54.mjs";
95
95
  import {
96
96
  _runWithFarmI18nRequest,
97
97
  _setDefaultFarmI18nRuntime,
98
98
  createFarmI18nRuntime,
99
99
  getFarmI18nClientSnapshot,
100
100
  readFarmI18nCatalogs
101
- } from "./chunk-QF4PHCMA.mjs";
101
+ } from "./chunk-2ED5Q2GH.mjs";
102
102
  import {
103
103
  createFarmLocaleCookie,
104
104
  getFarmLocaleVaryHeaders
@@ -106,19 +106,6 @@ import {
106
106
  import {
107
107
  resolveFarmI18nConfig
108
108
  } from "./chunk-FQYDHKKU.mjs";
109
- import {
110
- fileExists,
111
- globFiles,
112
- logger,
113
- matchRoute,
114
- parseRoutePath,
115
- resolveAppPath,
116
- toViteModuleId
117
- } from "./chunk-J4FNJ5IU.mjs";
118
- import {
119
- _runWithCurrentRequest,
120
- createWebRequestFromFarmRequest
121
- } from "./chunk-RHIFZZUI.mjs";
122
109
  import {
123
110
  createLayoutModuleFromProgrammaticLayout,
124
111
  createProgrammaticRouteModuleId,
@@ -128,7 +115,7 @@ import {
128
115
  parseProgrammaticRouteModuleId,
129
116
  parseProgrammaticRoutePath,
130
117
  scanProgrammaticPagePaths
131
- } from "./chunk-B6N4ZB2H.mjs";
118
+ } from "./chunk-C2ROET2V.mjs";
132
119
  import {
133
120
  resolveFarmRouteContext,
134
121
  withFarmRouteContext
@@ -139,7 +126,23 @@ import {
139
126
  normalizeFarmRouteRuntimeConfig,
140
127
  resolveFarmRouteRuleRuntimeConfig,
141
128
  resolveFarmRouteRuntimeConfig
142
- } from "./chunk-QM6VV26B.mjs";
129
+ } from "./chunk-GQVGIUSN.mjs";
130
+ import {
131
+ fileExists,
132
+ globFiles,
133
+ logger,
134
+ matchRoute,
135
+ parseRoutePath,
136
+ resolveAppPath,
137
+ toViteModuleId
138
+ } from "./chunk-J4FNJ5IU.mjs";
139
+ import {
140
+ _runWithCurrentRequest,
141
+ createWebRequestFromFarmRequest
142
+ } from "./chunk-RHIFZZUI.mjs";
143
+ import {
144
+ FARM_VERSION
145
+ } from "./chunk-W4UIVMVI.mjs";
143
146
  import {
144
147
  FARM_DEPLOYMENT_ID_HEADER,
145
148
  createFarmDeploymentCookie,
@@ -158,10 +161,11 @@ import {
158
161
  stripFarmLocaleFromPathname
159
162
  } from "./chunk-44ZCFSKE.mjs";
160
163
  import {
164
+ configureFarmCache,
161
165
  createFarmCacheKey,
162
166
  getFarmDataCache,
163
167
  normalizeRevalidatePath
164
- } from "./chunk-4PTK6KT4.mjs";
168
+ } from "./chunk-V3XURYJO.mjs";
165
169
  import {
166
170
  configureFarmObservability,
167
171
  emitFarmEvent
@@ -775,6 +779,76 @@ async function readAltText(filePath) {
775
779
  }
776
780
  __name(readAltText, "readAltText");
777
781
 
782
+ // src/routing/route-slots.ts
783
+ var SLOT_SEGMENT = /^@([A-Za-z][A-Za-z0-9_-]*)$/;
784
+ function parseRouteSlotFile(filePath) {
785
+ const normalized = filePath.replace(/\\/g, "/");
786
+ const parts = normalized.split("/").filter(Boolean);
787
+ const fileName = parts.at(-1) ?? "";
788
+ const baseName = fileName.replace(/\.(tsx?|jsx?)$/, "");
789
+ if (baseName !== "page" && baseName !== "default") return null;
790
+ const slotIndex = parts.findIndex((part) => SLOT_SEGMENT.test(part));
791
+ if (slotIndex < 0) return null;
792
+ if (parts.slice(slotIndex + 1, -1).some((part) => SLOT_SEGMENT.test(part))) {
793
+ throw new Error(`Nested route slots are not supported in "${filePath}"`);
794
+ }
795
+ const slotMatch = parts[slotIndex].match(SLOT_SEGMENT);
796
+ const name = slotMatch?.[1];
797
+ if (!name) return null;
798
+ const ownerParts = parts.slice(0, slotIndex);
799
+ const contentParts = parts.slice(slotIndex + 1, -1);
800
+ const marker = parseInterceptionMarker(contentParts[0]);
801
+ let targetBase = ownerParts;
802
+ let targetParts = contentParts;
803
+ if (marker) {
804
+ targetBase = marker.root === true ? [] : ownerParts.slice(0, Math.max(0, ownerParts.length - marker.up));
805
+ targetParts = [...marker.remainder ? [marker.remainder] : [], ...contentParts.slice(1)];
806
+ }
807
+ const ownerFile = [...ownerParts, "layout.tsx"].join("/");
808
+ const routeFile = [
809
+ ...baseName === "default" ? ownerParts : targetBase,
810
+ ...baseName === "default" ? [] : targetParts,
811
+ "page.tsx"
812
+ ].join("/");
813
+ return {
814
+ name,
815
+ ownerRoute: parseRoutePath(ownerFile || "layout.tsx"),
816
+ route: parseRoutePath(routeFile || "page.tsx"),
817
+ interception: marker !== null,
818
+ fallback: baseName === "default"
819
+ };
820
+ }
821
+ __name(parseRouteSlotFile, "parseRouteSlotFile");
822
+ function createRouteSlotContainerId(name, ownerPattern) {
823
+ const owner = ownerPattern === "/" ? "root" : ownerPattern.replace(/^\//, "").replace(/[^A-Za-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
824
+ return `__farm_slot_${name}_${owner || "root"}__`;
825
+ }
826
+ __name(createRouteSlotContainerId, "createRouteSlotContainerId");
827
+ function parseInterceptionMarker(segment) {
828
+ if (!segment) return null;
829
+ if (segment.startsWith("(...)")) {
830
+ return {
831
+ up: 0,
832
+ root: true,
833
+ remainder: segment.slice(5)
834
+ };
835
+ }
836
+ if (segment.startsWith("(.)")) {
837
+ return {
838
+ up: 0,
839
+ remainder: segment.slice(3)
840
+ };
841
+ }
842
+ let remainder = segment;
843
+ let up = 0;
844
+ while (remainder.startsWith("(..)")) {
845
+ up += 1;
846
+ remainder = remainder.slice(4);
847
+ }
848
+ return up > 0 ? { up, remainder } : null;
849
+ }
850
+ __name(parseInterceptionMarker, "parseInterceptionMarker");
851
+
778
852
  // src/routing/route-manager.ts
779
853
  function routeSpecificity(entry) {
780
854
  return entry.route.segments.reduce((score, segment) => {
@@ -788,6 +862,7 @@ var _RouteManager = class _RouteManager {
788
862
  constructor(config, viteServer) {
789
863
  this.routes = /* @__PURE__ */ new Map();
790
864
  this.layouts = /* @__PURE__ */ new Map();
865
+ this.routeSlots = /* @__PURE__ */ new Map();
791
866
  this.loadings = /* @__PURE__ */ new Map();
792
867
  this.errors = /* @__PURE__ */ new Map();
793
868
  this.metadataImages = /* @__PURE__ */ new Map();
@@ -803,6 +878,7 @@ var _RouteManager = class _RouteManager {
803
878
  async discoverRoutes() {
804
879
  this.routes.clear();
805
880
  this.layouts.clear();
881
+ this.routeSlots.clear();
806
882
  this.loadings.clear();
807
883
  this.errors.clear();
808
884
  this.metadataImages.clear();
@@ -813,6 +889,13 @@ var _RouteManager = class _RouteManager {
813
889
  await this.discoverFileRoutes(source);
814
890
  await this.discoverProgrammaticRoutes(source);
815
891
  }
892
+ for (const slot of this.routeSlots.values()) {
893
+ if (slot.interception && !this.routes.has(slot.pattern)) {
894
+ throw new Error(
895
+ `Intercepting route slot "${slot.name}" targets "${slot.pattern}", but no canonical page exists for that URL`
896
+ );
897
+ }
898
+ }
816
899
  this.routes = new Map(
817
900
  Array.from(this.routes.entries()).sort(
818
901
  ([, left], [, right]) => routeSpecificity(right) - routeSpecificity(left)
@@ -828,7 +911,7 @@ var _RouteManager = class _RouteManager {
828
911
  /**
829
912
  * Find matching route for a given URL path
830
913
  */
831
- matchRoute(pathname) {
914
+ matchRoute(pathname, options = {}) {
832
915
  const routePathname = this.toRoutePathname(pathname);
833
916
  const normalizedPath = routePathname === "/" ? "/" : routePathname.replace(/\/$/, "");
834
917
  let matchedRoute = null;
@@ -842,10 +925,12 @@ var _RouteManager = class _RouteManager {
842
925
  }
843
926
  }
844
927
  const layouts = this.findMatchingLayouts(normalizedPath);
928
+ const slots = this.findMatchingRouteSlots(normalizedPath, options.interceptFrom);
845
929
  return {
846
930
  route: matchedRoute,
847
931
  params,
848
- layouts
932
+ layouts,
933
+ slots
849
934
  };
850
935
  }
851
936
  /**
@@ -860,6 +945,9 @@ var _RouteManager = class _RouteManager {
860
945
  getLayouts() {
861
946
  return new Map(this.layouts);
862
947
  }
948
+ getRouteSlots() {
949
+ return new Map(this.routeSlots);
950
+ }
863
951
  /** Resolve route rules, inherited layouts, and the page export in precedence order. */
864
952
  async resolveRouteRuntimeConfig(pattern) {
865
953
  const routeEntry = this.routes.get(pattern);
@@ -1018,7 +1106,22 @@ var _RouteManager = class _RouteManager {
1018
1106
  pattern: entry.pattern,
1019
1107
  modulePath: toUrlPath(entry.modulePath)
1020
1108
  }));
1021
- return { routes, layouts };
1109
+ const slots = Array.from(this.routeSlots.values()).map((entry) => {
1110
+ const metadata = getClientModuleMetadata(entry.modulePath, projectRoot);
1111
+ return {
1112
+ name: entry.name,
1113
+ ownerPattern: entry.ownerPattern,
1114
+ pattern: entry.pattern,
1115
+ modulePath: toUrlPath(entry.modulePath),
1116
+ containerId: entry.containerId,
1117
+ interception: entry.interception,
1118
+ fallback: entry.fallback,
1119
+ shouldHydrate: metadata.shouldHydrate,
1120
+ isClientComponent: metadata.isClientComponent,
1121
+ segments: entry.route.segments
1122
+ };
1123
+ });
1124
+ return { routes, layouts, slots };
1022
1125
  }
1023
1126
  /**
1024
1127
  * Load a route module dynamically
@@ -1095,6 +1198,7 @@ var _RouteManager = class _RouteManager {
1095
1198
  async discoverFileRoutes(source) {
1096
1199
  const appDir = resolveAppPath(source.root, source.srcDir, "app");
1097
1200
  const pageFiles = await safeGlobFiles("**/page.{ts,tsx,js,jsx,md,mdx}", appDir);
1201
+ const slotDefaultFiles = await safeGlobFiles("**/@*/**/default.{ts,tsx,js,jsx}", appDir);
1098
1202
  const layoutFiles = await safeGlobFiles("**/layout.{ts,tsx,js,jsx}", appDir);
1099
1203
  const loadingFiles = await safeGlobFiles("**/loading.{ts,tsx,js,jsx}", appDir);
1100
1204
  const errorFiles = await safeGlobFiles("**/error.{ts,tsx,js,jsx}", appDir);
@@ -1103,7 +1207,7 @@ var _RouteManager = class _RouteManager {
1103
1207
  appDir
1104
1208
  );
1105
1209
  for (const [kind, files, target] of [
1106
- ["page", pageFiles, this.routes],
1210
+ ["page", pageFiles.filter((file) => parseRouteSlotFile(file) === null), this.routes],
1107
1211
  ["layout", layoutFiles, this.layouts],
1108
1212
  ["loading", loadingFiles, this.loadings],
1109
1213
  ["error", errorFiles, this.errors]
@@ -1127,6 +1231,32 @@ var _RouteManager = class _RouteManager {
1127
1231
  });
1128
1232
  }
1129
1233
  }
1234
+ for (const file of [...pageFiles, ...slotDefaultFiles]) {
1235
+ const slot = parseRouteSlotFile(file);
1236
+ if (!slot) continue;
1237
+ const modulePath = path3.join(appDir, file);
1238
+ const pattern = this.createRoutePattern(slot.route);
1239
+ const ownerPattern = this.createRoutePattern(slot.ownerRoute);
1240
+ const key = `${ownerPattern}:${slot.name}:${slot.interception ? "intercept" : "slot"}:${slot.fallback ? "default" : pattern}`;
1241
+ const existing = this.routeSlots.get(key);
1242
+ if (existing?.sourceRoot === source.root) {
1243
+ throw new Error(
1244
+ `Duplicate route slot "${slot.name}" for "${pattern}". Found both ${existing.modulePath} and ${modulePath}.`
1245
+ );
1246
+ }
1247
+ this.routeSlots.set(key, {
1248
+ route: slot.route,
1249
+ modulePath,
1250
+ pattern,
1251
+ source: "file",
1252
+ sourceRoot: source.root,
1253
+ name: slot.name,
1254
+ ownerPattern,
1255
+ interception: slot.interception,
1256
+ fallback: slot.fallback,
1257
+ containerId: createRouteSlotContainerId(slot.name, ownerPattern)
1258
+ });
1259
+ }
1130
1260
  for (const file of metadataImageFiles) {
1131
1261
  const fileBase = path3.basename(file, path3.extname(file));
1132
1262
  const kind = fileBase === "twitter-image" ? "twitter" : "opengraph";
@@ -1252,6 +1382,71 @@ var _RouteManager = class _RouteManager {
1252
1382
  }
1253
1383
  return matchingLayouts;
1254
1384
  }
1385
+ findMatchingRouteSlots(pathname, interceptFrom) {
1386
+ const groups = /* @__PURE__ */ new Map();
1387
+ for (const entry of this.routeSlots.values()) {
1388
+ if (!this.matchesRoutePrefix(pathname, entry.ownerPattern)) continue;
1389
+ const key = `${entry.ownerPattern}:${entry.name}`;
1390
+ const entries = groups.get(key) ?? [];
1391
+ entries.push(entry);
1392
+ groups.set(key, entries);
1393
+ }
1394
+ const normalizedFrom = interceptFrom ? this.toRoutePathname(new URL(interceptFrom, "http://farm.local").pathname) : void 0;
1395
+ const matches = [];
1396
+ for (const entries of groups.values()) {
1397
+ const candidates = entries.filter((entry) => !entry.fallback).filter(
1398
+ (entry) => !entry.interception || normalizedFrom !== void 0 && this.matchesRoutePrefix(normalizedFrom, entry.ownerPattern)
1399
+ ).map((entry) => ({
1400
+ entry,
1401
+ match: matchRoute(pathname, entry.route.segments)
1402
+ })).filter((candidate) => candidate.match.matches).sort((left, right) => {
1403
+ if (left.entry.interception !== right.entry.interception) {
1404
+ return left.entry.interception ? -1 : 1;
1405
+ }
1406
+ return routeSpecificity(right.entry) - routeSpecificity(left.entry);
1407
+ });
1408
+ const selected = candidates[0];
1409
+ if (selected) {
1410
+ matches.push({
1411
+ name: selected.entry.name,
1412
+ ownerPattern: selected.entry.ownerPattern,
1413
+ containerId: selected.entry.containerId,
1414
+ interception: selected.entry.interception,
1415
+ fallback: false,
1416
+ route: selected.entry,
1417
+ params: selected.match.params
1418
+ });
1419
+ continue;
1420
+ }
1421
+ const fallback = entries.find((entry) => entry.fallback);
1422
+ if (fallback) {
1423
+ matches.push({
1424
+ name: fallback.name,
1425
+ ownerPattern: fallback.ownerPattern,
1426
+ containerId: fallback.containerId,
1427
+ interception: false,
1428
+ fallback: true,
1429
+ route: fallback,
1430
+ params: {}
1431
+ });
1432
+ }
1433
+ }
1434
+ return matches.sort((left, right) => {
1435
+ const ownerDifference = left.route.route.segments.length - right.route.route.segments.length;
1436
+ return ownerDifference || left.name.localeCompare(right.name);
1437
+ });
1438
+ }
1439
+ matchesRoutePrefix(pathname, pattern) {
1440
+ if (pattern === "/") return true;
1441
+ const patternSegments = parseRoutePath(`${pattern}/page.tsx`).segments;
1442
+ const pathSegments = pathname.split("/").filter(Boolean);
1443
+ if (patternSegments.length > pathSegments.length) return false;
1444
+ for (let index = 0; index < patternSegments.length; index++) {
1445
+ const segment = patternSegments[index];
1446
+ if (!segment.isDynamic && segment.segment !== pathSegments[index]) return false;
1447
+ }
1448
+ return true;
1449
+ }
1255
1450
  findNearestBoundary(pathname, boundaries) {
1256
1451
  const normalizedPath = pathname === "/" ? "/" : pathname.replace(/\/$/, "");
1257
1452
  const pathSegments = normalizedPath.split("/").filter(Boolean);
@@ -1656,7 +1851,9 @@ var _ServerRenderer = class _ServerRenderer {
1656
1851
  async runWithRequestContext(request, fn) {
1657
1852
  return _runWithCurrentRequest(
1658
1853
  request,
1659
- () => this.i18nRuntime?.config.enabled ? _runWithFarmI18nRequest(this.i18nRuntime, request, fn, { redirect: false }) : fn()
1854
+ () => this.i18nRuntime?.config.enabled ? _runWithFarmI18nRequest(this.i18nRuntime, request, fn, {
1855
+ redirect: false
1856
+ }) : fn()
1660
1857
  );
1661
1858
  }
1662
1859
  async resolveRouteContext(input) {
@@ -1679,11 +1876,11 @@ var _ServerRenderer = class _ServerRenderer {
1679
1876
  /**
1680
1877
  * Check if a path should be served from SSG cache
1681
1878
  */
1682
- shouldServeSSG(pathname) {
1879
+ async shouldServeSSG(pathname) {
1683
1880
  const ssgPage = matchSSGPage(pathname, this.ssgManifest);
1684
1881
  if (!ssgPage) return null;
1685
- const cached = this.getCachedSSGPage(pathname);
1686
- if (cached && this.dataCache.isStale(cached)) {
1882
+ const cached = await this.getCachedSSGPage(pathname);
1883
+ if (cached && await this.dataCache.isStaleAsync(cached)) {
1687
1884
  this.regenerateSSGPage(ssgPage);
1688
1885
  }
1689
1886
  return ssgPage;
@@ -1695,12 +1892,12 @@ var _ServerRenderer = class _ServerRenderer {
1695
1892
  return createFarmCacheKey(["ppr", normalizeRevalidatePath(pathname), search]);
1696
1893
  }
1697
1894
  getCachedSSGPage(urlPath) {
1698
- return this.dataCache.getEntry(this.getSSGCacheKey(urlPath), {
1895
+ return this.dataCache.getEntryAsync(this.getSSGCacheKey(urlPath), {
1699
1896
  allowStale: true
1700
1897
  });
1701
1898
  }
1702
- cacheSSGPage(page, html, options) {
1703
- this.dataCache.set(
1899
+ async cacheSSGPage(page, html, options) {
1900
+ await this.dataCache.setAsync(
1704
1901
  this.getSSGCacheKey(page.urlPath),
1705
1902
  { html, document: options.document },
1706
1903
  {
@@ -1712,11 +1909,11 @@ var _ServerRenderer = class _ServerRenderer {
1712
1909
  );
1713
1910
  }
1714
1911
  getCachedPPRShell(pathname, search) {
1715
- return this.dataCache.getEntry(this.getPPRCacheKey(pathname, search));
1912
+ return this.dataCache.getEntryAsync(this.getPPRCacheKey(pathname, search));
1716
1913
  }
1717
- cachePPRShell(options, html) {
1914
+ async cachePPRShell(options, html) {
1718
1915
  const key = this.getPPRCacheKey(options.pathname, options.search);
1719
- this.dataCache.set(
1916
+ await this.dataCache.setAsync(
1720
1917
  key,
1721
1918
  { html },
1722
1919
  {
@@ -1814,7 +2011,7 @@ var _ServerRenderer = class _ServerRenderer {
1814
2011
  }
1815
2012
  const { renderToString } = await import("react-dom/server");
1816
2013
  const html = renderToString(await this.wrapWithIntegrationProviders(pageElement));
1817
- this.cacheSSGPage(page, html, { document: false });
2014
+ await this.cacheSSGPage(page, html, { document: false });
1818
2015
  logger.info(`ISR: Regenerated ${page.urlPath}`);
1819
2016
  } catch (error) {
1820
2017
  logger.error(`ISR regeneration failed for ${page.urlPath}: ${error}`);
@@ -1828,7 +2025,7 @@ var _ServerRenderer = class _ServerRenderer {
1828
2025
  * Serve a pre-rendered SSG page
1829
2026
  */
1830
2027
  async serveSSGPage(req, res, page) {
1831
- const cached = this.getCachedSSGPage(page.urlPath);
2028
+ const cached = await this.getCachedSSGPage(page.urlPath);
1832
2029
  if (cached) {
1833
2030
  res.setHeader("Content-Type", "text/html; charset=utf-8");
1834
2031
  res.setHeader("X-Farm-SSG", "cached");
@@ -1846,9 +2043,12 @@ var _ServerRenderer = class _ServerRenderer {
1846
2043
  if (fs2.existsSync(htmlPath)) {
1847
2044
  const stat = fs2.statSync(htmlPath);
1848
2045
  const html = fs2.readFileSync(htmlPath, "utf-8");
1849
- this.cacheSSGPage(page, html, { document: true, createdAt: stat.mtimeMs });
1850
- const fileCacheEntry = this.getCachedSSGPage(page.urlPath);
1851
- if (fileCacheEntry && this.dataCache.isStale(fileCacheEntry)) {
2046
+ await this.cacheSSGPage(page, html, {
2047
+ document: true,
2048
+ createdAt: stat.mtimeMs
2049
+ });
2050
+ const fileCacheEntry = await this.getCachedSSGPage(page.urlPath);
2051
+ if (fileCacheEntry && await this.dataCache.isStaleAsync(fileCacheEntry)) {
1852
2052
  this.regenerateSSGPage(page);
1853
2053
  }
1854
2054
  res.setHeader("Content-Type", "text/html; charset=utf-8");
@@ -1894,6 +2094,7 @@ var _ServerRenderer = class _ServerRenderer {
1894
2094
  let pathname = "/";
1895
2095
  let params = {};
1896
2096
  let layouts = [];
2097
+ let routeSlots = [];
1897
2098
  let searchParamsObject = {};
1898
2099
  let middlewareMap = /* @__PURE__ */ new Map();
1899
2100
  let middlewareContext = /* @__PURE__ */ new Map();
@@ -1926,7 +2127,7 @@ var _ServerRenderer = class _ServerRenderer {
1926
2127
  }
1927
2128
  this.applyDeploymentHeaders(req, res);
1928
2129
  if (process.env.NODE_ENV === "production") {
1929
- const ssgPage = this.shouldServeSSG(pathname);
2130
+ const ssgPage = await this.shouldServeSSG(pathname);
1930
2131
  if (ssgPage) {
1931
2132
  const served = await this.serveSSGPage(req, res, ssgPage);
1932
2133
  if (served) {
@@ -1939,6 +2140,7 @@ var _ServerRenderer = class _ServerRenderer {
1939
2140
  const route = match.route;
1940
2141
  params = match.params;
1941
2142
  layouts = match.layouts;
2143
+ routeSlots = match.slots ?? [];
1942
2144
  if (!route) {
1943
2145
  emitFarmEvent({ type: "route.notFound", pathname });
1944
2146
  await this.render404(req, res);
@@ -1955,7 +2157,9 @@ var _ServerRenderer = class _ServerRenderer {
1955
2157
  errorBoundaryEntry = this.routeManager.getMatchingError(pathname);
1956
2158
  middlewareMap = toMiddlewareMap(req.__FARM_MIDDLEWARE_DATA__);
1957
2159
  middlewareContext = toMiddlewareMap(req.__FARM_MIDDLEWARE_CONTEXT__);
1958
- pluginExposedContext = getRequestContextSnapshot(req, { exposedOnly: true });
2160
+ pluginExposedContext = getRequestContextSnapshot(req, {
2161
+ exposedOnly: true
2162
+ });
1959
2163
  const currentRequest = createWebRequestFromFarmRequest(req);
1960
2164
  const routeContext = await this.resolveRouteContext({
1961
2165
  request: currentRequest,
@@ -2019,8 +2223,16 @@ var _ServerRenderer = class _ServerRenderer {
2019
2223
  revalidate: renderingConfig.revalidate
2020
2224
  } : void 0;
2021
2225
  if (renderingConfig.ppr && pprBypassReason) {
2022
- emitFarmEvent({ type: "ppr.shell.bypass", route: pathname, reason: pprBypassReason });
2023
- emitFarmEvent({ type: "cache.bypass", route: pathname, reason: pprBypassReason });
2226
+ emitFarmEvent({
2227
+ type: "ppr.shell.bypass",
2228
+ route: pathname,
2229
+ reason: pprBypassReason
2230
+ });
2231
+ emitFarmEvent({
2232
+ type: "cache.bypass",
2233
+ route: pathname,
2234
+ reason: pprBypassReason
2235
+ });
2024
2236
  if (pprBypassReason === "refresh") {
2025
2237
  pprRefreshRoute = pathname;
2026
2238
  emitFarmEvent({ type: "ppr.refresh.start", route: pathname });
@@ -2028,14 +2240,22 @@ var _ServerRenderer = class _ServerRenderer {
2028
2240
  }
2029
2241
  if (pprShellOptions) {
2030
2242
  const pprCacheKey = this.getPPRCacheKey(pathname, url.search);
2031
- const cachedPPRShell = this.getCachedPPRShell(pathname, url.search);
2243
+ const cachedPPRShell = await this.getCachedPPRShell(pathname, url.search);
2032
2244
  if (cachedPPRShell) {
2033
- emitFarmEvent({ type: "ppr.shell.hit", route: pathname, key: pprCacheKey });
2245
+ emitFarmEvent({
2246
+ type: "ppr.shell.hit",
2247
+ route: pathname,
2248
+ key: pprCacheKey
2249
+ });
2034
2250
  this.serveCachedPPRShell(res, cachedPPRShell.value, renderingConfig.revalidate);
2035
2251
  completeRender(res.statusCode || 200, pathname);
2036
2252
  return;
2037
2253
  }
2038
- emitFarmEvent({ type: "ppr.shell.miss", route: pathname, key: pprCacheKey });
2254
+ emitFarmEvent({
2255
+ type: "ppr.shell.miss",
2256
+ route: pathname,
2257
+ key: pprCacheKey
2258
+ });
2039
2259
  }
2040
2260
  let LoadingFallbackComponent = null;
2041
2261
  if (loadingBoundaryEntry) {
@@ -2059,14 +2279,77 @@ var _ServerRenderer = class _ServerRenderer {
2059
2279
  );
2060
2280
  const moduleMetadata = routeManifestEntry || getClientModuleMetadata(route.modulePath, this.config.root);
2061
2281
  const isClientComponent = moduleMetadata.isClientComponent;
2282
+ const renderedRouteSlots = await Promise.all(
2283
+ routeSlots.map(async (slot) => {
2284
+ const slotModule = await this.routeManager.loadRouteModule(slot.route.modulePath);
2285
+ if (!slotModule.default) {
2286
+ throw new Error(
2287
+ `Route slot "${slot.name}" module ${slot.route.modulePath} does not export a default component`
2288
+ );
2289
+ }
2290
+ const slotContext = await this.resolveRouteContext({
2291
+ request: currentRequest,
2292
+ rawRequest: req,
2293
+ params: slot.params,
2294
+ search: searchParamsObject,
2295
+ path: pathname
2296
+ });
2297
+ const rawSlotProps = withFarmRouteContext(
2298
+ {
2299
+ params: slot.params,
2300
+ searchParams: Promise.resolve(searchParamsObject),
2301
+ path: pathname,
2302
+ middleware: middlewareMap.size > 0 ? { data: middlewareMap } : void 0,
2303
+ context: pluginExposedContext.size > 0 ? { data: pluginExposedContext } : void 0
2304
+ },
2305
+ slotContext
2306
+ );
2307
+ const slotProps = await parseRouteModuleProps(slotModule, {
2308
+ props: rawSlotProps,
2309
+ search: searchParamsObject,
2310
+ routePath: slot.route.pattern
2311
+ });
2312
+ const metadata = getClientModuleMetadata(slot.route.modulePath, this.config.root);
2313
+ return {
2314
+ ...slot,
2315
+ module: slotModule,
2316
+ props: slotProps,
2317
+ isClientComponent: metadata.isClientComponent,
2318
+ shouldHydrate: metadata.shouldHydrate
2319
+ };
2320
+ })
2321
+ );
2062
2322
  const shouldHydrate = moduleMetadata.shouldHydrate;
2323
+ const hasHydratableRouteSlots = renderedRouteSlots.some(
2324
+ (slot) => slot.isClientComponent || slot.shouldHydrate
2325
+ );
2063
2326
  req.__FARM_PAGE_PATH__ = route.modulePath;
2064
2327
  req.__FARM_ROUTE__ = pathname;
2065
2328
  req.__FARM_IS_CLIENT_COMPONENT__ = isClientComponent;
2066
2329
  req.__FARM_SHOULD_HYDRATE__ = shouldHydrate;
2330
+ req.__FARM_HAS_HYDRATABLE_ROUTE_SLOTS__ = hasHydratableRouteSlots;
2067
2331
  req.__FARM_LOADING_MODULE_PATH__ = loadingBoundaryEntry?.modulePath ? loadingBoundaryEntry.modulePath.substring(
2068
2332
  loadingBoundaryEntry.modulePath.indexOf("/src/app/")
2069
2333
  ) : null;
2334
+ req.__FARM_ROUTE_SLOTS__ = renderedRouteSlots.map((slot) => ({
2335
+ name: slot.name,
2336
+ ownerPattern: slot.ownerPattern,
2337
+ containerId: slot.containerId,
2338
+ interception: slot.interception,
2339
+ fallback: slot.fallback,
2340
+ modulePath: slot.route.modulePath,
2341
+ isClientComponent: slot.isClientComponent,
2342
+ shouldHydrate: slot.shouldHydrate,
2343
+ props: {
2344
+ params: slot.props.params,
2345
+ search: slot.props.search,
2346
+ searchParams: slot.props.search,
2347
+ ..."data" in slot.props ? { data: slot.props.data } : {},
2348
+ ...slot.props.__farmCanonicalPath ? { __farmCanonicalPath: slot.props.__farmCanonicalPath } : {},
2349
+ ...slot.props.__farmRoutePropsResolved ? { __farmRoutePropsResolved: true } : {},
2350
+ path: pathname
2351
+ }
2352
+ }));
2070
2353
  req.__FARM_PROPS__ = {
2071
2354
  params: pageProps.params,
2072
2355
  search: pageProps.search,
@@ -2126,12 +2409,32 @@ var _ServerRenderer = class _ServerRenderer {
2126
2409
  let wrappedElement = pageElement;
2127
2410
  for (let i = layoutModules.length - 1; i >= 0; i--) {
2128
2411
  const layoutModule = layoutModules[i];
2412
+ const layoutEntry = layouts[i];
2129
2413
  const LayoutComponent = layoutModule.default;
2414
+ const slotProps = {};
2415
+ for (const slot of renderedRouteSlots) {
2416
+ if (slot.ownerPattern !== layoutEntry.pattern) continue;
2417
+ let slotElement = React.createElement(
2418
+ slot.module.default,
2419
+ slot.props
2420
+ );
2421
+ slotElement = React.createElement(
2422
+ "div",
2423
+ {
2424
+ id: slot.containerId,
2425
+ "data-farm-route-slot": slot.name,
2426
+ "data-farm-slot-owner": slot.ownerPattern
2427
+ },
2428
+ slotElement
2429
+ );
2430
+ slotProps[slot.name] = slotElement;
2431
+ }
2130
2432
  wrappedElement = React.createElement(
2131
2433
  LayoutComponent,
2132
2434
  {
2133
2435
  children: wrappedElement,
2134
- params
2436
+ params,
2437
+ ...slotProps
2135
2438
  }
2136
2439
  );
2137
2440
  }
@@ -2168,7 +2471,10 @@ var _ServerRenderer = class _ServerRenderer {
2168
2471
  routeManifest,
2169
2472
  captureStaticShell: Boolean(pprShellOptions),
2170
2473
  observabilityRoute: pathname,
2171
- onSuspenseHoleDetected: pprShellOptions ? () => emitFarmEvent({ type: "ppr.suspense.holeDetected", route: pathname }) : void 0,
2474
+ onSuspenseHoleDetected: pprShellOptions ? () => emitFarmEvent({
2475
+ type: "ppr.suspense.holeDetected",
2476
+ route: pathname
2477
+ }) : void 0,
2172
2478
  onComplete: pprShellOptions && req.method !== "HEAD" ? (html) => this.cachePPRShell(pprShellOptions, html) : void 0
2173
2479
  }
2174
2480
  );
@@ -2216,7 +2522,11 @@ var _ServerRenderer = class _ServerRenderer {
2216
2522
  }
2217
2523
  emitFarmEvent({ type: "render.error", route: pathname, error });
2218
2524
  if (pprRefreshRoute) {
2219
- emitFarmEvent({ type: "ppr.refresh.error", route: pprRefreshRoute, error });
2525
+ emitFarmEvent({
2526
+ type: "ppr.refresh.error",
2527
+ route: pprRefreshRoute,
2528
+ error
2529
+ });
2220
2530
  }
2221
2531
  logger.error(`Error rendering page: ${error}`);
2222
2532
  if (res.headersSent || res.writableEnded) {
@@ -2269,7 +2579,9 @@ var _ServerRenderer = class _ServerRenderer {
2269
2579
  if (typeof layoutModule.generateMetadata === "function") {
2270
2580
  metadata = mergeMetadata(
2271
2581
  metadata,
2272
- await layoutModule.generateMetadata({ params: options.pageProps.params })
2582
+ await layoutModule.generateMetadata({
2583
+ params: options.pageProps.params
2584
+ })
2273
2585
  );
2274
2586
  }
2275
2587
  }
@@ -2500,7 +2812,13 @@ var _ServerRenderer = class _ServerRenderer {
2500
2812
  clientEntry: "/@farm/client.js",
2501
2813
  routes: {},
2502
2814
  layouts: {},
2503
- sharedAssets: [{ tag: "link", attrs: { rel: "stylesheet", href: "/src/app/globals.css" } }]
2815
+ slots: [],
2816
+ sharedAssets: [
2817
+ {
2818
+ tag: "link",
2819
+ attrs: { rel: "stylesheet", href: "/src/app/globals.css" }
2820
+ }
2821
+ ]
2504
2822
  };
2505
2823
  for (const routeEntry of manifest.routes) {
2506
2824
  clientManifest.routes[routeEntry.pattern] = {
@@ -2522,9 +2840,26 @@ var _ServerRenderer = class _ServerRenderer {
2522
2840
  assets: []
2523
2841
  };
2524
2842
  }
2525
- const deferredProps = prepareDeferredData(req.__FARM_PROPS__ || {});
2843
+ for (const slotEntry of manifest.slots ?? []) {
2844
+ clientManifest.slots.push({
2845
+ ...slotEntry,
2846
+ preloads: [slotEntry.modulePath],
2847
+ assets: []
2848
+ });
2849
+ }
2850
+ const routeSlotPayload = (req.__FARM_ROUTE_SLOTS__ || []).map(
2851
+ (slot) => ({
2852
+ ...slot,
2853
+ modulePath: typeof slot.modulePath === "string" && slot.modulePath.startsWith(this.config.root) ? slot.modulePath.slice(this.config.root.length) : slot.modulePath
2854
+ })
2855
+ );
2856
+ const deferredProps = prepareDeferredData({
2857
+ page: req.__FARM_PROPS__ || {},
2858
+ slots: routeSlotPayload
2859
+ });
2526
2860
  const propsScript = `<script>
2527
- window.__FARM_PROPS__ = ${serializeInlineValue(deferredProps.data)};
2861
+ window.__FARM_PROPS__ = ${serializeInlineValue(deferredProps.data.page)};
2862
+ window.__FARM_ROUTE_SLOTS__ = ${serializeInlineValue(deferredProps.data.slots)};
2528
2863
  window.__FARM_DEPLOYMENT_ID__ = ${serializeInlineValue(deploymentId)};
2529
2864
  window.__FARM_PATH__ = ${JSON.stringify(req.__FARM_ROUTE__ || req.url || "/")};
2530
2865
  window.__FARM_IS_CLIENT__ = ${JSON.stringify(isClientComponent)};
@@ -2537,7 +2872,7 @@ window.__FARM_MANIFEST__ = ${JSON.stringify(clientManifest)};
2537
2872
  window.__FARM_INTEGRATION_API_MANIFEST__ = ${JSON.stringify(getRegisteredIntegrationAPIManifest())};
2538
2873
  ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue(getFarmI18nClientSnapshot())};` : ""}
2539
2874
  </script>`;
2540
- const hydrationClickQueueScript = isClientComponent || req.__FARM_SHOULD_HYDRATE__ === true ? createPreHydrationClickQueueScript() : "";
2875
+ const hydrationClickQueueScript = isClientComponent || req.__FARM_SHOULD_HYDRATE__ === true || req.__FARM_HAS_HYDRATABLE_ROUTE_SLOTS__ === true ? createPreHydrationClickQueueScript() : "";
2541
2876
  const {
2542
2877
  title,
2543
2878
  tags: metaTags,
@@ -2648,7 +2983,11 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue(g
2648
2983
  didError = true;
2649
2984
  if (!isFarmRedirectError(error) && !isFarmNotFoundError(error)) {
2650
2985
  logger.error(`SSR shell error: ${error}`);
2651
- emitFarmEvent({ type: "render.error", route: observabilityRoute, error });
2986
+ emitFarmEvent({
2987
+ type: "render.error",
2988
+ route: observabilityRoute,
2989
+ error
2990
+ });
2652
2991
  }
2653
2992
  if (clearMiddlewareData) {
2654
2993
  clearMiddlewareData();
@@ -2659,7 +2998,11 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue(g
2659
2998
  didError = true;
2660
2999
  if (!isFarmRedirectError(error) && !isFarmNotFoundError(error)) {
2661
3000
  logger.error(`SSR streaming error: ${error}`);
2662
- emitFarmEvent({ type: "render.error", route: observabilityRoute, error });
3001
+ emitFarmEvent({
3002
+ type: "render.error",
3003
+ route: observabilityRoute,
3004
+ error
3005
+ });
2663
3006
  }
2664
3007
  }
2665
3008
  });
@@ -2826,17 +3169,14 @@ var _FarmApp = class _FarmApp {
2826
3169
  _setDefaultFarmI18nRuntime(this.i18nRuntime);
2827
3170
  this.viteServer = viteServer;
2828
3171
  this.routeManager = new RouteManager(this.config, viteServer);
2829
- this.serverRenderer = new ServerRenderer(
2830
- this.config,
2831
- this.routeManager,
2832
- this.i18nRuntime
2833
- );
3172
+ this.serverRenderer = new ServerRenderer(this.config, this.routeManager, this.i18nRuntime);
2834
3173
  }
2835
3174
  async initialize() {
2836
3175
  if (process.env.FARM_VERBOSE) {
2837
3176
  logger.info("Initializing Farm.js application...");
2838
3177
  }
2839
3178
  await initStorage(this.config.storage);
3179
+ await configureFarmCache(this.config.cache);
2840
3180
  await this.i18nRuntime.initialize();
2841
3181
  await this.verifyAppStructure();
2842
3182
  await this.routeManager.discoverRoutes();
@@ -2868,6 +3208,7 @@ var _FarmApp = class _FarmApp {
2868
3208
  preset: config.preset ?? "node-server",
2869
3209
  deploy: config.deploy || {},
2870
3210
  storage: config.storage || {},
3211
+ cache: config.cache || {},
2871
3212
  integrations: config.integrations || {},
2872
3213
  plugins: config.plugins || [],
2873
3214
  migrations: config.migrations || { commands: [] },
@@ -3340,6 +3681,7 @@ async function generateRouteTypes(options) {
3340
3681
  absolute: false
3341
3682
  });
3342
3683
  for (const file of pageFiles) {
3684
+ if (parseRouteSlotFile(file)) continue;
3343
3685
  const route = parseRoutePath(file);
3344
3686
  if (route.type === "page") {
3345
3687
  const pattern = createRoutePattern(route);
@@ -3666,7 +4008,7 @@ function loadFarmWorkflowsDevRuntime() {
3666
4008
  }
3667
4009
  __name(loadFarmWorkflowsDevRuntime, "loadFarmWorkflowsDevRuntime");
3668
4010
  function loadFarmDevtoolsSnapshotRuntime() {
3669
- return import("./devtools-AE4RVXCM.mjs");
4011
+ return import("./devtools-LVC3VB5P.mjs");
3670
4012
  }
3671
4013
  __name(loadFarmDevtoolsSnapshotRuntime, "loadFarmDevtoolsSnapshotRuntime");
3672
4014
  function loadFarmDevtoolsUIRuntime() {
@@ -3674,7 +4016,7 @@ function loadFarmDevtoolsUIRuntime() {
3674
4016
  }
3675
4017
  __name(loadFarmDevtoolsUIRuntime, "loadFarmDevtoolsUIRuntime");
3676
4018
  function loadFarmDevtoolsClientRuntime() {
3677
- return import("./devtools-client-6WPY2AQU.mjs");
4019
+ return import("./devtools-client-3XRTBND5.mjs");
3678
4020
  }
3679
4021
  __name(loadFarmDevtoolsClientRuntime, "loadFarmDevtoolsClientRuntime");
3680
4022
  function farmI18nClientBridgePlugin() {
@@ -3829,7 +4171,7 @@ function isResolvedEnvScope(value) {
3829
4171
  }
3830
4172
  __name(isResolvedEnvScope, "isResolvedEnvScope");
3831
4173
  function isPotentialProgrammaticRouteSourceFile(normalizedFile, srcDirSlug) {
3832
- return normalizedFile.startsWith(`${srcDirSlug}/`) && /\.(ts|tsx|js|jsx)$/.test(normalizedFile) && !/\.d\.ts$/.test(normalizedFile) && !normalizedFile.endsWith("/farm-routes.d.ts") && !normalizedFile.endsWith("/farm-env.d.ts") && !normalizedFile.endsWith("/lib/api.generated.ts");
4174
+ return normalizedFile.startsWith(`${srcDirSlug}/`) && /\.(ts|tsx|js|jsx)$/.test(normalizedFile) && !normalizedFile.endsWith(".d.ts") && !normalizedFile.endsWith("/farm-routes.d.ts") && !normalizedFile.endsWith("/farm-env.d.ts") && !normalizedFile.endsWith("/lib/api.generated.ts");
3833
4175
  }
3834
4176
  __name(isPotentialProgrammaticRouteSourceFile, "isPotentialProgrammaticRouteSourceFile");
3835
4177
  function fileContainsProgrammaticPageRoute(file) {
@@ -4072,7 +4414,7 @@ function farmPlugin(options = {}, initialPluginManager) {
4072
4414
  }, "isProgrammaticRouteSourceFile");
4073
4415
  const isAppRuntimeFile = /* @__PURE__ */ __name((file) => {
4074
4416
  const normalized = file.replace(/\\/g, "/");
4075
- return appDirSlugs.some((appDir) => normalized.startsWith(`${appDir}/`)) && /\/(?:page|layout|loading|error|middleware|route)\.(?:ts|tsx|js|jsx|md|mdx)$|\/(?:opengraph-image|twitter-image)(?:\.(?:ts|tsx|js|jsx|png|jpg|jpeg|gif|webp)|\.alt\.txt)$/.test(
4417
+ return appDirSlugs.some((appDir) => normalized.startsWith(`${appDir}/`)) && /\/(?:page|default|layout|loading|error|middleware|route)\.(?:ts|tsx|js|jsx|md|mdx)$|\/(?:opengraph-image|twitter-image)(?:\.(?:ts|tsx|js|jsx|png|jpg|jpeg|gif|webp)|\.alt\.txt)$/.test(
4076
4418
  normalized
4077
4419
  );
4078
4420
  }, "isAppRuntimeFile");
@@ -4763,7 +5105,10 @@ function farmPlugin(options = {}, initialPluginManager) {
4763
5105
  method: req.method || "GET"
4764
5106
  });
4765
5107
  }
4766
- const match = routeManager3.matchRoute(targetPath);
5108
+ const interceptFromHeader = request.headers.get("x-farm-intercept-from") || void 0;
5109
+ const match = routeManager3.matchRoute(targetRequestUrl.pathname, {
5110
+ interceptFrom: interceptFromHeader
5111
+ });
4767
5112
  if (pm) {
4768
5113
  await pm.runHookParallel("afterRouteMatch", {
4769
5114
  pathname: targetPath,
@@ -4779,7 +5124,7 @@ function farmPlugin(options = {}, initialPluginManager) {
4779
5124
  res.end(JSON.stringify({ error: "Route not found" }));
4780
5125
  return;
4781
5126
  }
4782
- const { route, params, layouts } = match;
5127
+ const { route, params, layouts, slots } = match;
4783
5128
  if (!route) {
4784
5129
  res.statusCode = 404;
4785
5130
  res.setHeader("Content-Type", "application/json");
@@ -4834,6 +5179,54 @@ function farmPlugin(options = {}, initialPluginManager) {
4834
5179
  search: searchParams,
4835
5180
  routePath: route.pattern
4836
5181
  });
5182
+ const routeSlots = await Promise.all(
5183
+ slots.map(async (slot) => {
5184
+ const slotModule = await routeManager3.loadRouteModule(slot.route.modulePath);
5185
+ const slotMetadata = getClientModuleMetadata(
5186
+ slot.route.modulePath,
5187
+ server.config.root
5188
+ );
5189
+ const slotContext = await resolveFarmRouteContext(farmApp.getConfig(), {
5190
+ request,
5191
+ params: slot.params,
5192
+ search: searchParams,
5193
+ path: targetUrl.pathname
5194
+ });
5195
+ const slotProps = await parseRouteModuleProps2(slotModule, {
5196
+ props: withFarmRouteContext(
5197
+ {
5198
+ params: slot.params,
5199
+ searchParams: Promise.resolve(searchParams),
5200
+ path: targetUrl.pathname
5201
+ },
5202
+ slotContext
5203
+ ),
5204
+ search: searchParams,
5205
+ routePath: slot.route.pattern
5206
+ });
5207
+ return {
5208
+ name: slot.name,
5209
+ ownerPattern: slot.ownerPattern,
5210
+ containerId: slot.containerId,
5211
+ interception: slot.interception,
5212
+ fallback: slot.fallback,
5213
+ modulePath: slot.route.modulePath,
5214
+ isClientComponent: slotMetadata.isClientComponent,
5215
+ shouldHydrate: slotMetadata.shouldHydrate,
5216
+ props: {
5217
+ params: slotProps.params,
5218
+ search: slotProps.search,
5219
+ searchParams: slotProps.search,
5220
+ ..."data" in slotProps ? { data: slotProps.data } : {},
5221
+ ...slotProps.__farmCanonicalPath ? {
5222
+ __farmCanonicalPath: slotProps.__farmCanonicalPath
5223
+ } : {},
5224
+ ...slotProps.__farmRoutePropsResolved ? { __farmRoutePropsResolved: true } : {},
5225
+ path: targetUrl.pathname
5226
+ }
5227
+ };
5228
+ })
5229
+ );
4837
5230
  const projectRoot = server.config.root;
4838
5231
  const toUrlPath = /* @__PURE__ */ __name((absolutePath) => {
4839
5232
  if (absolutePath.startsWith(projectRoot)) {
@@ -4854,13 +5247,21 @@ function farmPlugin(options = {}, initialPluginManager) {
4854
5247
  },
4855
5248
  canonicalPath: routeProps.__farmCanonicalPath,
4856
5249
  modulePath: toUrlPath(route.modulePath),
4857
- isClientComponent,
4858
- shouldHydrate,
5250
+ isClientComponent: routeSlots.length > 0 ? false : isClientComponent,
5251
+ shouldHydrate: shouldHydrate || routeSlots.some((slot) => slot.isClientComponent || slot.shouldHydrate),
4859
5252
  metadata: {
4860
5253
  title: mergedMetadata.title,
4861
5254
  description: mergedMetadata.description
4862
5255
  },
4863
5256
  layoutModules: layouts.map((l) => toUrlPath(l.modulePath)),
5257
+ routeSlots: routeSlots.map((slot) => ({
5258
+ ...slot,
5259
+ modulePath: toUrlPath(slot.modulePath)
5260
+ })),
5261
+ interception: routeSlots.some((slot) => slot.interception) ? {
5262
+ from: interceptFromHeader,
5263
+ slots: routeSlots.filter((slot) => slot.interception).map((slot) => slot.name)
5264
+ } : void 0,
4864
5265
  i18n: getFarmI18nClientSnapshot()
4865
5266
  };
4866
5267
  await sendWebResponse(
@@ -5196,6 +5597,7 @@ function farmPlugin(options = {}, initialPluginManager) {
5196
5597
  export const getManifest = () => ({
5197
5598
  routes: {},
5198
5599
  layouts: {},
5600
+ slots: [],
5199
5601
  clientEntry: "/@farm/client.js",
5200
5602
  sharedAssets: []
5201
5603
  });
@@ -5206,6 +5608,7 @@ export const getManifest = () => ({
5206
5608
  clientEntry: "/@farm/client.js",
5207
5609
  routes: {},
5208
5610
  layouts: {},
5611
+ slots: [],
5209
5612
  sharedAssets: [
5210
5613
  {
5211
5614
  tag: "link",
@@ -5235,6 +5638,13 @@ export const getManifest = () => ({
5235
5638
  assets: []
5236
5639
  };
5237
5640
  }
5641
+ for (const slot of manifest.slots) {
5642
+ fullManifest.slots.push({
5643
+ ...slot,
5644
+ preloads: [slot.modulePath],
5645
+ assets: []
5646
+ });
5647
+ }
5238
5648
  return `
5239
5649
  // Auto-generated manifest for SPA navigation (TanStack Start pattern)
5240
5650
  // This manifest is inlined in the server bundle - no file on disk
@@ -5877,7 +6287,7 @@ window.__FARM_WRAP_PROVIDERS__ = wrapWithIntegrationProviders;
5877
6287
 
5878
6288
  // Get manifest from window (inlined by server in HTML)
5879
6289
  // Fallback to empty manifest if not available yet
5880
- const getManifest = () => window.__FARM_MANIFEST__ || { routes: {}, layouts: {}, clientEntry: '', sharedAssets: [] };
6290
+ const getManifest = () => window.__FARM_MANIFEST__ || { routes: {}, layouts: {}, slots: [], clientEntry: '', sharedAssets: [] };
5881
6291
 
5882
6292
  // ====== CLIENT-SIDE ROUTE MATCHING ======
5883
6293
  // Matches URL to route using manifest (no server request!)
@@ -6216,6 +6626,9 @@ let LayoutComponent = null;
6216
6626
 
6217
6627
  // Track if we've taken over rendering from SSR
6218
6628
  let hasClientTakenOver = false;
6629
+ const routeSlotRoots = new Map();
6630
+ const routeSlotDefinitions = new Map();
6631
+ let activeRouteInterception = null;
6219
6632
 
6220
6633
  function normalizeServerProps(rawProps) {
6221
6634
  const props = rawProps && typeof rawProps === 'object' ? { ...rawProps } : {};
@@ -6228,6 +6641,123 @@ function normalizeServerProps(rawProps) {
6228
6641
  return props;
6229
6642
  }
6230
6643
 
6644
+ function getRouteSlotKey(slot) {
6645
+ return slot.ownerPattern + ':' + slot.name;
6646
+ }
6647
+
6648
+ async function renderRouteSlot(slot, mode = 'render') {
6649
+ const container = document.getElementById(slot.containerId);
6650
+ if (!container || !slot.modulePath) return false;
6651
+ if (mode === 'intercept' && !slot.isClientComponent && !slot.shouldHydrate) {
6652
+ return false;
6653
+ }
6654
+
6655
+ let slotModule = pageModuleCache.get(slot.modulePath);
6656
+ if (!slotModule) {
6657
+ slotModule = await import(/* @vite-ignore */ slot.modulePath);
6658
+ pageModuleCache.set(slot.modulePath, slotModule);
6659
+ }
6660
+ const SlotComponent = slotModule?.default;
6661
+ if (!SlotComponent) return false;
6662
+
6663
+ const props = reviveDeferredData(
6664
+ normalizeServerProps(slot.props || {}),
6665
+ window.__FARM_DEFERRED_DATA__ || {},
6666
+ );
6667
+ const element = wrapWithIntegrationProviders(
6668
+ React.createElement(SlotComponent, props),
6669
+ );
6670
+ const key = getRouteSlotKey(slot);
6671
+ const existingRoot = routeSlotRoots.get(key);
6672
+
6673
+ if (mode === 'hydrate') {
6674
+ if (existingRoot) return true;
6675
+ const root = hydrateRoot(container, element);
6676
+ routeSlotRoots.set(key, root);
6677
+ } else {
6678
+ if (existingRoot) {
6679
+ try { existingRoot.unmount(); } catch (error) {}
6680
+ }
6681
+ const root = createRoot(container);
6682
+ root.render(element);
6683
+ routeSlotRoots.set(key, root);
6684
+ }
6685
+
6686
+ routeSlotDefinitions.set(key, slot);
6687
+ return true;
6688
+ }
6689
+
6690
+ async function hydrateInitialRouteSlots() {
6691
+ const slots = Array.isArray(window.__FARM_ROUTE_SLOTS__)
6692
+ ? window.__FARM_ROUTE_SLOTS__
6693
+ : [];
6694
+ let hydrated = false;
6695
+
6696
+ for (const slot of slots) {
6697
+ routeSlotDefinitions.set(getRouteSlotKey(slot), slot);
6698
+ if (!slot.isClientComponent && !slot.shouldHydrate) continue;
6699
+ try {
6700
+ hydrated = (await renderRouteSlot(slot, 'hydrate')) || hydrated;
6701
+ } catch (error) {
6702
+ console.warn('[Farm.js] Could not hydrate route slot:', slot.name, error);
6703
+ }
6704
+ }
6705
+
6706
+ return hydrated;
6707
+ }
6708
+
6709
+ async function renderRouteInterception(pageData) {
6710
+ const slots = Array.isArray(pageData.routeSlots)
6711
+ ? pageData.routeSlots.filter((slot) => slot.interception)
6712
+ : [];
6713
+ if (!pageData.interception || slots.length === 0) return false;
6714
+
6715
+ const previous = new Map();
6716
+ for (const slot of slots) {
6717
+ const key = getRouteSlotKey(slot);
6718
+ previous.set(key, routeSlotDefinitions.get(key) || null);
6719
+ if (!(await renderRouteSlot(slot, 'intercept'))) {
6720
+ return false;
6721
+ }
6722
+ }
6723
+
6724
+ activeRouteInterception = {
6725
+ from: pageData.interception.from,
6726
+ slots,
6727
+ previous,
6728
+ };
6729
+ return true;
6730
+ }
6731
+
6732
+ async function clearRouteInterception(destination) {
6733
+ if (!activeRouteInterception) return false;
6734
+ const active = activeRouteInterception;
6735
+ activeRouteInterception = null;
6736
+
6737
+ for (const slot of active.slots) {
6738
+ const key = getRouteSlotKey(slot);
6739
+ const root = routeSlotRoots.get(key);
6740
+ if (root) {
6741
+ try { root.unmount(); } catch (error) {}
6742
+ routeSlotRoots.delete(key);
6743
+ }
6744
+
6745
+ const previous = active.previous.get(key);
6746
+ if (previous && (previous.isClientComponent || previous.shouldHydrate)) {
6747
+ await renderRouteSlot(previous, 'render');
6748
+ } else {
6749
+ const container = document.getElementById(slot.containerId);
6750
+ if (container) container.replaceChildren();
6751
+ if (previous) routeSlotDefinitions.set(key, previous);
6752
+ else routeSlotDefinitions.delete(key);
6753
+ }
6754
+ }
6755
+
6756
+ if (!active.from) return false;
6757
+ const background = new URL(active.from, window.location.origin);
6758
+ return destination === background.pathname + background.search;
6759
+ }
6760
+
6231
6761
  function applyCanonicalPathFromProps(props) {
6232
6762
  const canonicalPath = props && typeof props.__farmCanonicalPath === 'string'
6233
6763
  ? props.__farmCanonicalPath
@@ -6462,6 +6992,17 @@ async function tryHydrateImportedPage(
6462
6992
  async function renderPage(pageData) {
6463
6993
  const container = document.getElementById('root');
6464
6994
  if (!container) return;
6995
+ const destination = window.location.pathname + window.location.search;
6996
+
6997
+ if (pageData.interception) {
6998
+ if (await renderRouteInterception(pageData)) return;
6999
+ window.location.assign(destination);
7000
+ return;
7001
+ }
7002
+
7003
+ if (await clearRouteInterception(destination)) {
7004
+ return;
7005
+ }
6465
7006
 
6466
7007
  const route = {
6467
7008
  modulePath: pageData.modulePath,
@@ -6690,7 +7231,9 @@ async function hydrate() {
6690
7231
  window.__FARM_SHOULD_HYDRATE__ === true ||
6691
7232
  isClientComponent ||
6692
7233
  await moduleLooksClient(modulePath);
7234
+ const hydratedSlots = await hydrateInitialRouteSlots();
6693
7235
  if (!shouldHydrate) {
7236
+ if (hydratedSlots) replayPreHydrationClicks();
6694
7237
  console.log('[Farm.js] Server component - SPA router ready')
6695
7238
  return
6696
7239
  }
@@ -6955,7 +7498,7 @@ async function defineConfig(config = {}) {
6955
7498
  const isExposed = hostConfig === true || hostConfig === "0.0.0.0";
6956
7499
  console.log("");
6957
7500
  console.log(
6958
- ` ${pc.bold(pc.green("Farm.js"))} ${pc.dim("v1.0.0")} ${pc.dim(`ready in ${elapsed}ms`)}`
7501
+ ` ${pc.bold(pc.green("Farm.js"))} ${pc.dim(`v${FARM_VERSION}`)} ${pc.dim(`ready in ${elapsed}ms`)}`
6959
7502
  );
6960
7503
  console.log("");
6961
7504
  console.log(
@@ -7085,4 +7628,4 @@ export {
7085
7628
  farmPlugin,
7086
7629
  defineConfig
7087
7630
  };
7088
- //# sourceMappingURL=chunk-CHFHNEMO.mjs.map
7631
+ //# sourceMappingURL=chunk-AOBXKNS5.mjs.map