@farm.js/core 0.1.0-beta.96 → 0.1.0-beta.97

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 (311) hide show
  1. package/dist/after.cjs +1 -1
  2. package/dist/after.mjs +1 -1
  3. package/dist/agent-runtime.d.mts +3 -2
  4. package/dist/agent-runtime.d.ts +3 -2
  5. package/dist/api/route-manager.cjs +43 -4
  6. package/dist/api/route-manager.d.mts +4 -3
  7. package/dist/api/route-manager.d.ts +4 -3
  8. package/dist/api/route-manager.mjs +6 -6
  9. package/dist/api/runtime.cjs +43 -4
  10. package/dist/api/runtime.d.mts +1 -1
  11. package/dist/api/runtime.d.ts +1 -1
  12. package/dist/api/runtime.mjs +4 -4
  13. package/dist/api.cjs +239 -70
  14. package/dist/api.d.mts +7 -6
  15. package/dist/api.d.ts +7 -6
  16. package/dist/api.mjs +17 -11
  17. package/dist/{app-CIIEvA4r.d.ts → app-CIOx3LvY.d.ts} +4 -4
  18. package/dist/{app-O4AEC1OH.d.mts → app-DBd6437H.d.mts} +4 -4
  19. package/dist/app-markdown.d.mts +4 -3
  20. package/dist/app-markdown.d.ts +4 -3
  21. package/dist/cache.cjs +42 -4
  22. package/dist/cache.d.mts +68 -1
  23. package/dist/cache.d.ts +68 -1
  24. package/dist/cache.mjs +3 -3
  25. package/dist/{chunk-AXVJCMVF.mjs → chunk-2HDOV47R.mjs} +3 -3
  26. package/dist/chunk-2HDOV47R.mjs.map +1 -0
  27. package/dist/{chunk-RBRLLZL5.mjs → chunk-34IAPZBG.mjs} +16 -3
  28. package/dist/chunk-34IAPZBG.mjs.map +1 -0
  29. package/dist/{chunk-VV24CC42.mjs → chunk-35NPLKQJ.mjs} +2 -2
  30. package/dist/{chunk-MM46HTX6.mjs → chunk-3TWQERDE.mjs} +4 -3
  31. package/dist/chunk-3TWQERDE.mjs.map +1 -0
  32. package/dist/{chunk-RWYRFCLG.mjs → chunk-4X57GXQA.mjs} +2 -2
  33. package/dist/{chunk-3I55IGXU.mjs → chunk-52BR7LTX.mjs} +14 -15
  34. package/dist/chunk-52BR7LTX.mjs.map +1 -0
  35. package/dist/{chunk-RAGSHKDC.mjs → chunk-6EJHNHH4.mjs} +38 -3
  36. package/dist/chunk-6EJHNHH4.mjs.map +1 -0
  37. package/dist/{chunk-ZFNK77WN.mjs → chunk-6JNGOC37.mjs} +2 -2
  38. package/dist/{after.cjs.map → chunk-6JNGOC37.mjs.map} +1 -1
  39. package/dist/{chunk-MOW47IF5.mjs → chunk-6UYVU46O.mjs} +2 -2
  40. package/dist/{chunk-7MABZJIM.mjs → chunk-7PYVLJ4J.mjs} +1 -1
  41. package/dist/chunk-7PYVLJ4J.mjs.map +1 -0
  42. package/dist/{chunk-54XSGLKT.mjs → chunk-D7F7YZ7L.mjs} +93 -67
  43. package/dist/chunk-D7F7YZ7L.mjs.map +1 -0
  44. package/dist/{chunk-SCFX4UTD.mjs → chunk-EHTUKVSW.mjs} +1 -1
  45. package/dist/chunk-EHTUKVSW.mjs.map +1 -0
  46. package/dist/{chunk-LZTGDH3H.mjs → chunk-EPDIF432.mjs} +424 -10
  47. package/dist/chunk-EPDIF432.mjs.map +1 -0
  48. package/dist/{chunk-GZHKWHCH.mjs → chunk-FP5Q67FO.mjs} +167 -96
  49. package/dist/chunk-FP5Q67FO.mjs.map +1 -0
  50. package/dist/{chunk-HHZAOTQD.mjs → chunk-GJ7W6LNK.mjs} +7 -6
  51. package/dist/chunk-GJ7W6LNK.mjs.map +1 -0
  52. package/dist/{chunk-RLGUZ3HS.mjs → chunk-I3OOUWO5.mjs} +3 -3
  53. package/dist/{chunk-LKKMI7JG.mjs → chunk-IZBX2TEU.mjs} +153 -68
  54. package/dist/chunk-IZBX2TEU.mjs.map +1 -0
  55. package/dist/{chunk-74QPONAN.mjs → chunk-J3MPQ4MQ.mjs} +2 -2
  56. package/dist/{chunk-74QPONAN.mjs.map → chunk-J3MPQ4MQ.mjs.map} +1 -1
  57. package/dist/{chunk-ODJGAWDH.mjs → chunk-JV7JUD7Q.mjs} +4 -4
  58. package/dist/{chunk-Q3OX763A.mjs → chunk-LXDASSTE.mjs} +2 -2
  59. package/dist/{chunk-ZRBCBOEX.mjs → chunk-N2FY2QZ7.mjs} +28 -3
  60. package/dist/chunk-N2FY2QZ7.mjs.map +1 -0
  61. package/dist/{chunk-MRVJCLYQ.mjs → chunk-PSQ7N4XP.mjs} +4 -2
  62. package/dist/chunk-PSQ7N4XP.mjs.map +1 -0
  63. package/dist/{chunk-HVG3HLQZ.mjs → chunk-Q7WGOOAI.mjs} +3 -3
  64. package/dist/{chunk-WTYAPO5I.mjs → chunk-RCNWMEBT.mjs} +3 -2
  65. package/dist/{chunk-WTYAPO5I.mjs.map → chunk-RCNWMEBT.mjs.map} +1 -1
  66. package/dist/{chunk-3INDBMUU.mjs → chunk-TGDIACZT.mjs} +2 -2
  67. package/dist/{chunk-WB75GIX2.mjs → chunk-TQTB33JS.mjs} +14 -3
  68. package/dist/chunk-TQTB33JS.mjs.map +1 -0
  69. package/dist/{chunk-WMAYETRD.mjs → chunk-TT3E2JOF.mjs} +3 -3
  70. package/dist/{chunk-FVAM43KI.mjs → chunk-UMUWR5XA.mjs} +2 -2
  71. package/dist/{chunk-VOUJW4FL.mjs → chunk-WD2EBM3I.mjs} +70 -15
  72. package/dist/chunk-WD2EBM3I.mjs.map +1 -0
  73. package/dist/{chunk-ZPG6SNHH.mjs → chunk-WMJGA32P.mjs} +47 -5
  74. package/dist/chunk-WMJGA32P.mjs.map +1 -0
  75. package/dist/{chunk-TKQCJMY7.mjs → chunk-X4SFHKFH.mjs} +7 -4
  76. package/dist/{chunk-TKQCJMY7.mjs.map → chunk-X4SFHKFH.mjs.map} +1 -1
  77. package/dist/{chunk-Q7GPJZCO.mjs → chunk-YIBV77KZ.mjs} +26 -7
  78. package/dist/chunk-YIBV77KZ.mjs.map +1 -0
  79. package/dist/client/lifecycle.mjs +2 -2
  80. package/dist/{client-mcMC334J.d.mts → client-DWoLZ3QU.d.mts} +52 -5
  81. package/dist/{client-d5ONQ-Pd.d.ts → client-DuQuQC1h.d.ts} +52 -5
  82. package/dist/client-cache-BMxuFqwH.d.ts +18 -0
  83. package/dist/client-cache-CCK-fCe0.d.mts +18 -0
  84. package/dist/{client-plugins-BvClItiL.d.mts → client-plugins-B6-07YmP.d.mts} +52 -99
  85. package/dist/{client-plugins-B9Sq-iMg.d.ts → client-plugins-By6MVUX-.d.ts} +52 -99
  86. package/dist/client-plugins.cjs +1 -1
  87. package/dist/client-plugins.d.mts +3 -2
  88. package/dist/client-plugins.d.ts +3 -2
  89. package/dist/client-plugins.mjs +2 -2
  90. package/dist/client.cjs +757 -104
  91. package/dist/client.d.mts +124 -16
  92. package/dist/client.d.ts +124 -16
  93. package/dist/client.mjs +28 -14
  94. package/dist/config.d.mts +3 -2
  95. package/dist/config.d.ts +3 -2
  96. package/dist/{devtools-S52RRRMN.mjs → devtools-XWZX6CCL.mjs} +5 -5
  97. package/dist/{devtools-client-EOVDBPOI.mjs → devtools-client-Z7QQA3Q2.mjs} +2 -2
  98. package/dist/{devtools-ui-NJKFORTG.mjs → devtools-ui-2HG5M4EL.mjs} +3 -1
  99. package/dist/devtools-ui-2HG5M4EL.mjs.map +1 -0
  100. package/dist/docs.cjs +24 -5
  101. package/dist/docs.mjs +5 -5
  102. package/dist/i18n/server.cjs +13 -2
  103. package/dist/i18n/server.d.mts +2 -2
  104. package/dist/i18n/server.d.ts +2 -2
  105. package/dist/i18n/server.mjs +1 -1
  106. package/dist/index.cjs +1578 -772
  107. package/dist/index.d.mts +28 -20
  108. package/dist/index.d.ts +28 -20
  109. package/dist/index.mjs +53 -33
  110. package/dist/index.mjs.map +1 -1
  111. package/dist/integration-api-BT024nuJ.d.mts +97 -0
  112. package/dist/integration-api-BT024nuJ.d.ts +97 -0
  113. package/dist/integrations.d.mts +3 -2
  114. package/dist/integrations.d.ts +3 -2
  115. package/dist/internal/build-runtime.cjs +710 -532
  116. package/dist/internal/build-runtime.d.mts +5 -4
  117. package/dist/internal/build-runtime.d.ts +5 -4
  118. package/dist/internal/build-runtime.mjs +15 -15
  119. package/dist/internal/client-runtime.cjs +1 -1
  120. package/dist/internal/client-runtime.mjs +2 -2
  121. package/dist/internal/config-runtime.cjs +4 -1
  122. package/dist/internal/config-runtime.d.mts +4 -3
  123. package/dist/internal/config-runtime.d.ts +4 -3
  124. package/dist/internal/config-runtime.mjs +4 -4
  125. package/dist/internal/product-telemetry-runtime.cjs +1 -1
  126. package/dist/internal/product-telemetry-runtime.mjs +1 -1
  127. package/dist/internal/production-runtime.cjs +29 -3
  128. package/dist/internal/production-runtime.d.mts +8 -7
  129. package/dist/internal/production-runtime.d.ts +8 -7
  130. package/dist/internal/production-runtime.mjs +5 -5
  131. package/dist/{metadata-route-yV4U6X8h.d.ts → metadata-route-8_V3UonT.d.ts} +1 -1
  132. package/dist/{metadata-route-p4K1l92V.d.mts → metadata-route-CWP_HjGU.d.mts} +1 -1
  133. package/dist/middleware.cjs +28 -2
  134. package/dist/middleware.d.mts +5 -4
  135. package/dist/middleware.d.ts +5 -4
  136. package/dist/middleware.mjs +4 -4
  137. package/dist/navigation.cjs +3 -1
  138. package/dist/navigation.mjs +3 -3
  139. package/dist/observability.cjs +27 -2
  140. package/dist/observability.mjs +1 -1
  141. package/dist/plugin.cjs +474 -334
  142. package/dist/plugin.d.mts +3 -2
  143. package/dist/plugin.d.ts +3 -2
  144. package/dist/plugin.mjs +12 -12
  145. package/dist/{production-runtime-IkB0Qj4i.d.mts → production-runtime-BGRH1dKG.d.mts} +1 -1
  146. package/dist/{production-runtime-0JTch4_d.d.ts → production-runtime-CdmzsDax.d.ts} +1 -1
  147. package/dist/query/client.cjs +11 -3
  148. package/dist/query/client.mjs +12 -4
  149. package/dist/query/client.mjs.map +1 -1
  150. package/dist/{render-plan-Dc8CjNI7.d.ts → render-plan-0GeHiGVZ.d.ts} +1 -1
  151. package/dist/{render-plan-CU31j-Jk.d.mts → render-plan-DLxJYAA5.d.mts} +1 -1
  152. package/dist/renderer-client.cjs +140 -26
  153. package/dist/renderer-client.d.mts +7 -6
  154. package/dist/renderer-client.d.ts +7 -6
  155. package/dist/renderer-client.mjs +16 -19
  156. package/dist/renderer-client.mjs.map +1 -1
  157. package/dist/{request-BXa1KY8i.d.mts → request-BCNXSXLh.d.mts} +1 -1
  158. package/dist/{request-CUUBujZt.d.ts → request-BstWbZ6O.d.ts} +1 -1
  159. package/dist/request.d.mts +4 -3
  160. package/dist/request.d.ts +4 -3
  161. package/dist/{route-Y8lfz1wF.d.ts → route-4pd-EVtw.d.ts} +45 -50
  162. package/dist/{route-Cq3aObmj.d.mts → route-CvEr4Uc9.d.mts} +45 -50
  163. package/dist/routes.cjs +27 -2
  164. package/dist/routes.d.mts +3 -2
  165. package/dist/routes.d.ts +3 -2
  166. package/dist/routes.mjs +4 -4
  167. package/dist/{runtime-j1S3sDTh.d.ts → runtime-BgDQzBiu.d.ts} +1 -0
  168. package/dist/{runtime-DDwvDtS4.d.mts → runtime-CV2UCV-5.d.mts} +1 -0
  169. package/dist/server-action-security.mjs +2 -2
  170. package/dist/server-fn-client.cjs +34 -2
  171. package/dist/server-fn-client.d.mts +6 -0
  172. package/dist/server-fn-client.d.ts +6 -0
  173. package/dist/server-fn-client.mjs +1 -1
  174. package/dist/server-fn.cjs +42 -4
  175. package/dist/server-fn.mjs +5 -5
  176. package/dist/server-plugins.d.mts +4 -3
  177. package/dist/server-plugins.d.ts +4 -3
  178. package/dist/server-query-client.cjs +146 -27
  179. package/dist/server-query-client.d.mts +3 -3
  180. package/dist/server-query-client.d.ts +3 -3
  181. package/dist/server-query-client.mjs +7 -7
  182. package/dist/{server-query-runtime-3zAj77yv.d.ts → server-query-runtime-DXRNhX_3.d.ts} +2 -0
  183. package/dist/{server-query-runtime-B50KAcj5.d.mts → server-query-runtime-aP52iuL5.d.mts} +2 -0
  184. package/dist/server-query.cjs +44 -5
  185. package/dist/server-query.d.mts +4 -0
  186. package/dist/server-query.d.ts +4 -0
  187. package/dist/server-query.mjs +7 -7
  188. package/dist/server.cjs +499 -355
  189. package/dist/server.d.mts +11 -10
  190. package/dist/server.d.ts +11 -10
  191. package/dist/server.mjs +16 -16
  192. package/dist/{spa-router-CyLkwst6.d.mts → spa-router-BeyAVSc6.d.mts} +1 -1
  193. package/dist/{spa-router-BkqGXaV_.d.ts → spa-router-COgu4txb.d.ts} +1 -1
  194. package/dist/testing.cjs +27 -2
  195. package/dist/testing.d.mts +3 -2
  196. package/dist/testing.d.ts +3 -2
  197. package/dist/testing.mjs +8 -8
  198. package/dist/{utils-NKR6SoNv.d.mts → utils-DL2VwDQl.d.mts} +1 -1
  199. package/dist/{utils-B2OHrb9F.d.ts → utils-DkU2c_1B.d.ts} +1 -1
  200. package/dist/version.cjs +1 -1
  201. package/dist/version.mjs +1 -1
  202. package/dist/vite.cjs +482 -338
  203. package/dist/vite.d.mts +3 -2
  204. package/dist/vite.d.ts +3 -2
  205. package/dist/vite.mjs +16 -12
  206. package/package.json +17 -17
  207. package/types/client.d.ts +87 -1
  208. package/dist/agent-runtime.cjs.map +0 -1
  209. package/dist/api/route-manager.cjs.map +0 -1
  210. package/dist/api/runtime.cjs.map +0 -1
  211. package/dist/api.cjs.map +0 -1
  212. package/dist/app-markdown.cjs.map +0 -1
  213. package/dist/cache.cjs.map +0 -1
  214. package/dist/chunk-3I55IGXU.mjs.map +0 -1
  215. package/dist/chunk-54XSGLKT.mjs.map +0 -1
  216. package/dist/chunk-7MABZJIM.mjs.map +0 -1
  217. package/dist/chunk-AXVJCMVF.mjs.map +0 -1
  218. package/dist/chunk-GZHKWHCH.mjs.map +0 -1
  219. package/dist/chunk-HHZAOTQD.mjs.map +0 -1
  220. package/dist/chunk-LKKMI7JG.mjs.map +0 -1
  221. package/dist/chunk-LZTGDH3H.mjs.map +0 -1
  222. package/dist/chunk-MM46HTX6.mjs.map +0 -1
  223. package/dist/chunk-MRVJCLYQ.mjs.map +0 -1
  224. package/dist/chunk-Q7GPJZCO.mjs.map +0 -1
  225. package/dist/chunk-RAGSHKDC.mjs.map +0 -1
  226. package/dist/chunk-RBRLLZL5.mjs.map +0 -1
  227. package/dist/chunk-SCFX4UTD.mjs.map +0 -1
  228. package/dist/chunk-VOUJW4FL.mjs.map +0 -1
  229. package/dist/chunk-WB75GIX2.mjs.map +0 -1
  230. package/dist/chunk-ZFNK77WN.mjs.map +0 -1
  231. package/dist/chunk-ZPG6SNHH.mjs.map +0 -1
  232. package/dist/chunk-ZRBCBOEX.mjs.map +0 -1
  233. package/dist/client/lifecycle.cjs.map +0 -1
  234. package/dist/client-cache-CopR_MaI.d.mts +0 -6
  235. package/dist/client-cache-Djy_TlE8.d.ts +0 -6
  236. package/dist/client-plugins.cjs.map +0 -1
  237. package/dist/client.cjs.map +0 -1
  238. package/dist/config.cjs.map +0 -1
  239. package/dist/cron.cjs.map +0 -1
  240. package/dist/deferred.cjs.map +0 -1
  241. package/dist/deployment.cjs.map +0 -1
  242. package/dist/devtools-ui-NJKFORTG.mjs.map +0 -1
  243. package/dist/docs.cjs.map +0 -1
  244. package/dist/env-types.cjs.map +0 -1
  245. package/dist/env.cjs.map +0 -1
  246. package/dist/environment/vite.cjs.map +0 -1
  247. package/dist/environment.cjs.map +0 -1
  248. package/dist/font.cjs.map +0 -1
  249. package/dist/headers.cjs.map +0 -1
  250. package/dist/i18n/client.cjs.map +0 -1
  251. package/dist/i18n/index.cjs.map +0 -1
  252. package/dist/i18n/server.cjs.map +0 -1
  253. package/dist/image/server.cjs.map +0 -1
  254. package/dist/image/sharp.cjs.map +0 -1
  255. package/dist/image.cjs.map +0 -1
  256. package/dist/index.cjs.map +0 -1
  257. package/dist/instrumentation.cjs.map +0 -1
  258. package/dist/integrations.cjs.map +0 -1
  259. package/dist/internal/build-runtime.cjs.map +0 -1
  260. package/dist/internal/client-runtime.cjs.map +0 -1
  261. package/dist/internal/config-runtime.cjs.map +0 -1
  262. package/dist/internal/isolated-boundary.cjs.map +0 -1
  263. package/dist/internal/metadata-image-runtime.cjs.map +0 -1
  264. package/dist/internal/product-telemetry-runtime.cjs.map +0 -1
  265. package/dist/internal/production-node-env.cjs.map +0 -1
  266. package/dist/internal/production-runtime.cjs.map +0 -1
  267. package/dist/markdown.cjs.map +0 -1
  268. package/dist/middleware.cjs.map +0 -1
  269. package/dist/navigation.cjs.map +0 -1
  270. package/dist/observability.cjs.map +0 -1
  271. package/dist/plugin.cjs.map +0 -1
  272. package/dist/query/client.cjs.map +0 -1
  273. package/dist/query/index.cjs.map +0 -1
  274. package/dist/query/parsers.cjs.map +0 -1
  275. package/dist/query/server.cjs.map +0 -1
  276. package/dist/renderer/react/client.cjs.map +0 -1
  277. package/dist/renderer/react/server.cjs.map +0 -1
  278. package/dist/renderer/react/vite.cjs.map +0 -1
  279. package/dist/renderer-client.cjs.map +0 -1
  280. package/dist/renderer.cjs.map +0 -1
  281. package/dist/request.cjs.map +0 -1
  282. package/dist/router.cjs.map +0 -1
  283. package/dist/routes.cjs.map +0 -1
  284. package/dist/server-action-security.cjs.map +0 -1
  285. package/dist/server-fn-client.cjs.map +0 -1
  286. package/dist/server-fn.cjs.map +0 -1
  287. package/dist/server-plugins.cjs.map +0 -1
  288. package/dist/server-query-client.cjs.map +0 -1
  289. package/dist/server-query.cjs.map +0 -1
  290. package/dist/server.cjs.map +0 -1
  291. package/dist/storage.cjs.map +0 -1
  292. package/dist/testing.cjs.map +0 -1
  293. package/dist/theme/client.cjs.map +0 -1
  294. package/dist/theme/index.cjs.map +0 -1
  295. package/dist/theme/runtime.cjs.map +0 -1
  296. package/dist/theme/server.cjs.map +0 -1
  297. package/dist/version.cjs.map +0 -1
  298. package/dist/vite.cjs.map +0 -1
  299. package/dist/workflows.cjs.map +0 -1
  300. /package/dist/{chunk-VV24CC42.mjs.map → chunk-35NPLKQJ.mjs.map} +0 -0
  301. /package/dist/{chunk-RWYRFCLG.mjs.map → chunk-4X57GXQA.mjs.map} +0 -0
  302. /package/dist/{chunk-MOW47IF5.mjs.map → chunk-6UYVU46O.mjs.map} +0 -0
  303. /package/dist/{chunk-RLGUZ3HS.mjs.map → chunk-I3OOUWO5.mjs.map} +0 -0
  304. /package/dist/{chunk-ODJGAWDH.mjs.map → chunk-JV7JUD7Q.mjs.map} +0 -0
  305. /package/dist/{chunk-Q3OX763A.mjs.map → chunk-LXDASSTE.mjs.map} +0 -0
  306. /package/dist/{chunk-HVG3HLQZ.mjs.map → chunk-Q7WGOOAI.mjs.map} +0 -0
  307. /package/dist/{chunk-3INDBMUU.mjs.map → chunk-TGDIACZT.mjs.map} +0 -0
  308. /package/dist/{chunk-WMAYETRD.mjs.map → chunk-TT3E2JOF.mjs.map} +0 -0
  309. /package/dist/{chunk-FVAM43KI.mjs.map → chunk-UMUWR5XA.mjs.map} +0 -0
  310. /package/dist/{devtools-S52RRRMN.mjs.map → devtools-XWZX6CCL.mjs.map} +0 -0
  311. /package/dist/{devtools-client-EOVDBPOI.mjs.map → devtools-client-Z7QQA3Q2.mjs.map} +0 -0
package/dist/client.cjs CHANGED
@@ -32,12 +32,15 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
32
32
  var client_exports = {};
33
33
  __export(client_exports, {
34
34
  APIClientError: () => APIClientError,
35
+ FARM_CACHE_INVALIDATION_CHANNEL: () => FARM_CACHE_INVALIDATION_CHANNEL,
36
+ FARM_CLIENT_CACHE_PERSIST_VERSION: () => FARM_CLIENT_CACHE_PERSIST_VERSION,
35
37
  FarmClientPluginManager: () => FarmClientPluginManager,
36
38
  FetcherInputError: () => FetcherInputError,
37
39
  IntegrationClientError: () => IntegrationClientError,
38
40
  Link: () => Link,
39
41
  SPARouter: () => SPARouter,
40
42
  api: () => api,
43
+ clearPersistedCache: () => clearPersistedCache,
41
44
  createAPIClient: () => createAPIClient,
42
45
  createApiClients: () => createApiClients,
43
46
  createClientPluginManager: () => createClientPluginManager,
@@ -48,13 +51,16 @@ __export(client_exports, {
48
51
  createIntegrations: () => createIntegrations,
49
52
  createServerAPIClient: () => createServerAPIClient,
50
53
  createStore: () => createStore,
54
+ defineClientCacheAdapter: () => defineClientCacheAdapter,
51
55
  defineIntegrationAPI: () => defineIntegrationAPI,
52
56
  defineIntegrationAPIOperation: () => defineIntegrationAPIOperation,
57
+ enableCrossTabCacheInvalidation: () => enableCrossTabCacheInvalidation,
53
58
  endpoint: () => endpoint,
54
59
  fetchServerQuery: () => fetchServerQuery,
55
60
  getIntegrationAPIManifest: () => getIntegrationAPIManifest,
56
61
  getRouter: () => getRouter2,
57
62
  getTheme: () => getTheme,
63
+ initPersistedClientCache: () => initPersistedClientCache,
58
64
  installChunkErrorRecovery: () => installChunkErrorRecovery,
59
65
  integrationClients: () => integrationClients,
60
66
  integrationsClient: () => integrationsClient,
@@ -67,6 +73,7 @@ __export(client_exports, {
67
73
  readPageState: () => readPageState,
68
74
  replaceState: () => replaceState,
69
75
  setTheme: () => setTheme,
76
+ storageClientCacheAdapter: () => storageClientCacheAdapter,
70
77
  toggleTheme: () => toggleTheme,
71
78
  useAction: () => useAction,
72
79
  useBlocker: () => useBlocker,
@@ -224,10 +231,10 @@ __name(createClientCancellation, "createClientCancellation");
224
231
  function notifyClientObserver(observer, args, label = "Client lifecycle") {
225
232
  if (!observer) return;
226
233
  const report = /* @__PURE__ */ __name((error) => {
227
- const reportError = globalThis.reportError;
228
- if (typeof reportError === "function") {
234
+ const reportError2 = globalThis.reportError;
235
+ if (typeof reportError2 === "function") {
229
236
  try {
230
- reportError.call(globalThis, error);
237
+ reportError2.call(globalThis, error);
231
238
  return;
232
239
  } catch {
233
240
  }
@@ -1218,7 +1225,13 @@ function recordFarmEventTrace(event) {
1218
1225
  activeSpan.addEvent(event.type, toEventAttributes(event), event.timestamp);
1219
1226
  }
1220
1227
  const error = event.type === "request.error" ? void 0 : getEventError(event);
1221
- if (error !== void 0) recordSpanError(activeSpan, error);
1228
+ if (error !== void 0) {
1229
+ if (event.type === "render.error") {
1230
+ recordSpanException(activeSpan, error);
1231
+ } else {
1232
+ recordSpanError(activeSpan, error);
1233
+ }
1234
+ }
1222
1235
  }
1223
1236
  const completedTraceContext = recordCompletedEventSpan(event, activeContext);
1224
1237
  return traceContext ?? completedTraceContext;
@@ -1315,12 +1328,26 @@ function getCompletedSpanDescriptor(event) {
1315
1328
  }
1316
1329
  }
1317
1330
  __name(getCompletedSpanDescriptor, "getCompletedSpanDescriptor");
1331
+ function hashFarmCacheKey(value) {
1332
+ let hash = 2166136261;
1333
+ for (let index = 0; index < value.length; index++) {
1334
+ hash ^= value.charCodeAt(index);
1335
+ hash = Math.imul(hash, 16777619);
1336
+ }
1337
+ return (hash >>> 0).toString(16).padStart(8, "0");
1338
+ }
1339
+ __name(hashFarmCacheKey, "hashFarmCacheKey");
1318
1340
  function toEventAttributes(event) {
1319
1341
  const attributes = {};
1342
+ const redactKey = typeof event.type === "string" && event.type.startsWith("cache.");
1320
1343
  for (const [key, value] of Object.entries(event)) {
1321
1344
  if (key === "timestamp" || key === "level" || key === "error" || key === "traceId" || key === "spanId" || key === "traceSampled" || value === void 0) {
1322
1345
  continue;
1323
1346
  }
1347
+ if (redactKey && key === "key" && typeof value === "string") {
1348
+ attributes["farm.key_hash"] = hashFarmCacheKey(value);
1349
+ continue;
1350
+ }
1324
1351
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
1325
1352
  attributes[`farm.${key}`] = value;
1326
1353
  } else if (Array.isArray(value)) {
@@ -1340,9 +1367,14 @@ function getEventError(event) {
1340
1367
  return "error" in event ? event.error : void 0;
1341
1368
  }
1342
1369
  __name(getEventError, "getEventError");
1343
- function recordSpanError(span, error) {
1370
+ function recordSpanException(span, error) {
1344
1371
  const normalized = error instanceof Error ? error : new Error(String(error));
1345
1372
  span.recordException(normalized);
1373
+ return normalized;
1374
+ }
1375
+ __name(recordSpanException, "recordSpanException");
1376
+ function recordSpanError(span, error) {
1377
+ const normalized = recordSpanException(span, error);
1346
1378
  span.setStatus({ code: import_api.SpanStatusCode.ERROR, message: normalized.message });
1347
1379
  }
1348
1380
  __name(recordSpanError, "recordSpanError");
@@ -1502,10 +1534,19 @@ function getFarmCacheInvalidationState() {
1502
1534
  });
1503
1535
  }
1504
1536
  __name(getFarmCacheInvalidationState, "getFarmCacheInvalidationState");
1537
+ function warnFarmCacheListenerError(scope, error) {
1538
+ const detail = error instanceof Error ? error.stack ?? error.message : String(error);
1539
+ console.warn(`[farm:cache] ${scope} listener failed: ${detail}`);
1540
+ }
1541
+ __name(warnFarmCacheListenerError, "warnFarmCacheListenerError");
1505
1542
  function notifyFarmCacheInvalidation(key) {
1506
1543
  if (typeof key !== "string" || key.length === 0) return;
1507
1544
  for (const listener of getFarmCacheInvalidationState().listeners) {
1508
- listener(key);
1545
+ try {
1546
+ listener(key);
1547
+ } catch (error) {
1548
+ warnFarmCacheListenerError("invalidation", error);
1549
+ }
1509
1550
  }
1510
1551
  }
1511
1552
  __name(notifyFarmCacheInvalidation, "notifyFarmCacheInvalidation");
@@ -1518,6 +1559,14 @@ function applyFarmCacheInvalidations(keys) {
1518
1559
  }
1519
1560
  }
1520
1561
  __name(applyFarmCacheInvalidations, "applyFarmCacheInvalidations");
1562
+ function encodeFarmCacheInvalidations(keys) {
1563
+ const normalized = Array.from(
1564
+ new Set(keys.filter((key) => typeof key === "string" && key.length > 0))
1565
+ );
1566
+ if (normalized.length === 0) return null;
1567
+ return encodeURIComponent(JSON.stringify(normalized));
1568
+ }
1569
+ __name(encodeFarmCacheInvalidations, "encodeFarmCacheInvalidations");
1521
1570
  function decodeFarmCacheInvalidations(value) {
1522
1571
  if (!value) return [];
1523
1572
  try {
@@ -2237,6 +2286,7 @@ function subscribeWeakCache(reference) {
2237
2286
  return dispose;
2238
2287
  }
2239
2288
  __name(subscribeWeakCache, "subscribeWeakCache");
2289
+ var DEFAULT_GC_SWEEP_INTERVAL_MS = 3e4;
2240
2290
  var _FarmClientDataCache = class _FarmClientDataCache {
2241
2291
  constructor(options = {}) {
2242
2292
  this.entries = /* @__PURE__ */ new Map();
@@ -2244,6 +2294,7 @@ var _FarmClientDataCache = class _FarmClientDataCache {
2244
2294
  this.invalidatedAt = /* @__PURE__ */ new Map();
2245
2295
  this.listeners = /* @__PURE__ */ new Map();
2246
2296
  this.inflight = /* @__PURE__ */ new Map();
2297
+ this.gcSweepIntervalMs = options.gcSweepIntervalMs ?? DEFAULT_GC_SWEEP_INTERVAL_MS;
2247
2298
  if (options.subscribeToInvalidation !== false) {
2248
2299
  if (typeof WeakRef === "function") {
2249
2300
  const reference = new WeakRef(this);
@@ -2260,6 +2311,10 @@ var _FarmClientDataCache = class _FarmClientDataCache {
2260
2311
  get size() {
2261
2312
  return this.entries.size;
2262
2313
  }
2314
+ /** @internal Attach or detach the persistence engine's observation sink. */
2315
+ attachPersistence(sink) {
2316
+ this.persistence = sink;
2317
+ }
2263
2318
  resolveKey(key) {
2264
2319
  let resolved = key;
2265
2320
  const seen = /* @__PURE__ */ new Set();
@@ -2275,6 +2330,7 @@ var _FarmClientDataCache = class _FarmClientDataCache {
2275
2330
  if (!entry) return void 0;
2276
2331
  if (entry.gcAt !== void 0 && now2 >= entry.gcAt) {
2277
2332
  this.entries.delete(resolved);
2333
+ this.persistence?.onDelete(resolved);
2278
2334
  this.emit(resolved);
2279
2335
  return void 0;
2280
2336
  }
@@ -2288,6 +2344,8 @@ var _FarmClientDataCache = class _FarmClientDataCache {
2288
2344
  this.invalidatedAt.delete(resolved);
2289
2345
  }
2290
2346
  this.entries.set(resolved, nextEntry);
2347
+ if (nextEntry.gcAt !== void 0) this.scheduleGcSweep();
2348
+ this.persistence?.onSet(resolved, nextEntry);
2291
2349
  this.emit(resolved);
2292
2350
  return this;
2293
2351
  }
@@ -2295,6 +2353,7 @@ var _FarmClientDataCache = class _FarmClientDataCache {
2295
2353
  const resolved = this.resolveKey(key);
2296
2354
  const deleted = this.entries.delete(resolved);
2297
2355
  this.inflight.delete(resolved);
2356
+ if (deleted) this.persistence?.onDelete(resolved);
2298
2357
  this.emit(resolved);
2299
2358
  return deleted;
2300
2359
  }
@@ -2304,11 +2363,16 @@ var _FarmClientDataCache = class _FarmClientDataCache {
2304
2363
  this.aliases.clear();
2305
2364
  this.invalidatedAt.clear();
2306
2365
  this.inflight.clear();
2366
+ this.persistence?.onClear();
2307
2367
  for (const key of keys) this.emit(key);
2308
2368
  }
2309
2369
  dispose() {
2310
2370
  this.unsubscribeInvalidation?.();
2311
2371
  this.unsubscribeInvalidation = void 0;
2372
+ if (this.gcTimer !== void 0) {
2373
+ clearTimeout(this.gcTimer);
2374
+ this.gcTimer = void 0;
2375
+ }
2312
2376
  this.clear();
2313
2377
  }
2314
2378
  isStale(key, now2 = Date.now()) {
@@ -2337,8 +2401,9 @@ var _FarmClientDataCache = class _FarmClientDataCache {
2337
2401
  const resolvedInvalidatedAt = this.invalidatedAt.get(resolved);
2338
2402
  if (aliasEntry && !this.entries.has(resolved)) {
2339
2403
  this.entries.set(resolved, aliasEntry);
2404
+ this.persistence?.onSet(resolved, aliasEntry);
2340
2405
  }
2341
- this.entries.delete(alias);
2406
+ if (this.entries.delete(alias)) this.persistence?.onDelete(alias);
2342
2407
  this.invalidatedAt.delete(alias);
2343
2408
  const invalidatedAt = [aliasInvalidatedAt, resolvedInvalidatedAt].reduce(
2344
2409
  (latest, value) => value === void 0 ? latest : latest === void 0 ? value : Math.max(latest, value),
@@ -2378,7 +2443,9 @@ var _FarmClientDataCache = class _FarmClientDataCache {
2378
2443
  listeners2.add(listener);
2379
2444
  return () => {
2380
2445
  listeners2.delete(listener);
2381
- if (listeners2.size === 0) this.listeners.delete(key);
2446
+ if (listeners2.size === 0 && this.listeners.get(key) === listeners2) {
2447
+ this.listeners.delete(key);
2448
+ }
2382
2449
  };
2383
2450
  }
2384
2451
  getInflight(key) {
@@ -2390,6 +2457,30 @@ var _FarmClientDataCache = class _FarmClientDataCache {
2390
2457
  deleteInflight(key) {
2391
2458
  this.inflight.delete(this.resolveKey(key));
2392
2459
  }
2460
+ scheduleGcSweep() {
2461
+ if (this.gcSweepIntervalMs === false || this.gcTimer !== void 0) return;
2462
+ const timer = setTimeout(() => {
2463
+ this.gcTimer = void 0;
2464
+ this.sweepExpiredEntries();
2465
+ }, this.gcSweepIntervalMs);
2466
+ timer.unref?.();
2467
+ this.gcTimer = timer;
2468
+ }
2469
+ sweepExpiredEntries(now2 = Date.now()) {
2470
+ const watched = /* @__PURE__ */ new Set();
2471
+ for (const key of this.listeners.keys()) watched.add(this.resolveKey(key));
2472
+ let remaining = false;
2473
+ for (const [key, entry] of this.entries) {
2474
+ if (entry.gcAt === void 0) continue;
2475
+ if (now2 < entry.gcAt || entry.fetching || this.inflight.has(key) || watched.has(key)) {
2476
+ remaining = true;
2477
+ continue;
2478
+ }
2479
+ this.entries.delete(key);
2480
+ this.persistence?.onDelete(key);
2481
+ }
2482
+ if (remaining) this.scheduleGcSweep();
2483
+ }
2393
2484
  emit(key, event) {
2394
2485
  this.notifyListeners(key, event);
2395
2486
  for (const [alias, target] of this.aliases) {
@@ -3027,70 +3118,6 @@ function createAPIClientRuntime(options = {}, transport) {
3027
3118
  let scopedRequestState;
3028
3119
  const routeMeta = transport?.routeMeta ?? /* @__PURE__ */ new WeakMap();
3029
3120
  let requestCounter = 0;
3030
- const applyOptimisticLayer = /* @__PURE__ */ __name((entry, layer) => {
3031
- let data = entry?.data;
3032
- for (const updater of layer.updaters) data = updater(data);
3033
- return {
3034
- data,
3035
- updatedAt: layer.updatedAt,
3036
- staleAt: entry?.staleAt ?? layer.staleAt,
3037
- gcAt: entry?.gcAt ?? layer.gcAt,
3038
- invalidatedAt: entry?.invalidatedAt,
3039
- [API_CACHE_REFETCH]: entry?.[API_CACHE_REFETCH]
3040
- };
3041
- }, "applyOptimisticLayer");
3042
- const storeOptimisticEntry = /* @__PURE__ */ __name((cacheState, key, stack, entry) => {
3043
- if (!entry) {
3044
- cacheState.delete(key);
3045
- stack.renderedEntry = void 0;
3046
- return;
3047
- }
3048
- cacheState.set(key, entry);
3049
- if (stack.invalidatedAt !== void 0) {
3050
- cacheState.invalidate(key, stack.invalidatedAt);
3051
- }
3052
- stack.renderedEntry = cacheState.get(key);
3053
- }, "storeOptimisticEntry");
3054
- const reconcileOptimisticInvalidation = /* @__PURE__ */ __name((cacheState, key, stack) => {
3055
- const current = cacheState.get(key);
3056
- const rendered = stack.renderedEntry;
3057
- if (current === rendered) return true;
3058
- if (!current || !rendered || current.data !== rendered.data || current.updatedAt !== rendered.updatedAt || current.gcAt !== rendered.gcAt || current.status !== rendered.status || current.error !== rendered.error || current.fetching !== rendered.fetching || current.staleAt !== 0 || current.invalidatedAt === void 0) {
3059
- return false;
3060
- }
3061
- stack.invalidatedAt = current.invalidatedAt;
3062
- stack.renderedEntry = current;
3063
- return true;
3064
- }, "reconcileOptimisticInvalidation");
3065
- const renderOptimisticStack = /* @__PURE__ */ __name((cacheState, key, stack) => {
3066
- let entry = stack.entry ? { ...stack.entry } : void 0;
3067
- for (const layer of stack.layers) entry = applyOptimisticLayer(entry, layer);
3068
- storeOptimisticEntry(cacheState, key, stack, entry);
3069
- }, "renderOptimisticStack");
3070
- const settleOptimisticUpdates = /* @__PURE__ */ __name((cacheState, optimisticState, snapshots, outcome) => {
3071
- const settledKeys = [];
3072
- for (const snapshot of snapshots) {
3073
- const stack = optimisticState.get(snapshot.key);
3074
- if (stack !== snapshot.stack) continue;
3075
- if (!reconcileOptimisticInvalidation(cacheState, snapshot.key, stack)) {
3076
- optimisticState.delete(snapshot.key);
3077
- continue;
3078
- }
3079
- if (outcome === "rollback") {
3080
- stack.layers = stack.layers.filter((layer) => layer !== snapshot.layer);
3081
- } else {
3082
- snapshot.layer.committed = true;
3083
- if (outcome === "invalidate") stack.invalidatedAt = Date.now();
3084
- }
3085
- while (stack.layers[0]?.committed) {
3086
- stack.entry = applyOptimisticLayer(stack.entry, stack.layers.shift());
3087
- }
3088
- renderOptimisticStack(cacheState, snapshot.key, stack);
3089
- if (stack.layers.length === 0) optimisticState.delete(snapshot.key);
3090
- settledKeys.push(snapshot.key);
3091
- }
3092
- return settledKeys;
3093
- }, "settleOptimisticUpdates");
3094
3121
  const fetchClient = /* @__PURE__ */ __name(async (path, requestOptions, defaultHeaders, cancellation) => {
3095
3122
  const url = resolveFarmAPIRequestURL(path, baseURL);
3096
3123
  const method = String(requestOptions.method || "GET").toUpperCase();
@@ -3467,6 +3494,7 @@ function createAPIClientRuntime(options = {}, transport) {
3467
3494
  staleAt: updatedAt + staleTime,
3468
3495
  gcAt: getGcAt(updatedAt, cacheOptions?.gcTime),
3469
3496
  invalidatedAt: void 0,
3497
+ persist: cacheOptions?.persist === true ? true : void 0,
3470
3498
  [API_CACHE_REFETCH]: createCacheRefetch(
3471
3499
  request,
3472
3500
  path,
@@ -3814,6 +3842,151 @@ function getOptimisticState(cache) {
3814
3842
  return state;
3815
3843
  }
3816
3844
  __name(getOptimisticState, "getOptimisticState");
3845
+ function applyOptimisticLayer(entry, layer) {
3846
+ let data = entry?.data;
3847
+ for (const updater of layer.updaters) data = updater(data);
3848
+ return {
3849
+ data,
3850
+ updatedAt: layer.updatedAt,
3851
+ staleAt: entry?.staleAt ?? layer.staleAt,
3852
+ gcAt: entry?.gcAt ?? layer.gcAt,
3853
+ invalidatedAt: entry?.invalidatedAt,
3854
+ [API_CACHE_REFETCH]: entry?.[API_CACHE_REFETCH]
3855
+ };
3856
+ }
3857
+ __name(applyOptimisticLayer, "applyOptimisticLayer");
3858
+ function storeOptimisticEntry(cacheState, key, stack, entry) {
3859
+ if (!entry) {
3860
+ cacheState.delete(key);
3861
+ stack.renderedEntry = void 0;
3862
+ return;
3863
+ }
3864
+ cacheState.set(key, entry);
3865
+ if (stack.invalidatedAt !== void 0) {
3866
+ cacheState.invalidate(key, stack.invalidatedAt);
3867
+ }
3868
+ stack.renderedEntry = cacheState.get(key);
3869
+ }
3870
+ __name(storeOptimisticEntry, "storeOptimisticEntry");
3871
+ function reconcileOptimisticInvalidation(cacheState, key, stack) {
3872
+ const current = cacheState.get(key);
3873
+ const rendered = stack.renderedEntry;
3874
+ if (current === rendered) return true;
3875
+ if (!current || !rendered || current.data !== rendered.data || current.updatedAt !== rendered.updatedAt || current.gcAt !== rendered.gcAt || current.status !== rendered.status || current.error !== rendered.error || current.fetching !== rendered.fetching || current.staleAt !== 0 || current.invalidatedAt === void 0) {
3876
+ return false;
3877
+ }
3878
+ stack.invalidatedAt = current.invalidatedAt;
3879
+ stack.renderedEntry = current;
3880
+ return true;
3881
+ }
3882
+ __name(reconcileOptimisticInvalidation, "reconcileOptimisticInvalidation");
3883
+ function renderOptimisticStack(cacheState, key, stack) {
3884
+ let entry = stack.entry ? { ...stack.entry } : void 0;
3885
+ for (const layer of stack.layers) entry = applyOptimisticLayer(entry, layer);
3886
+ storeOptimisticEntry(cacheState, key, stack, entry);
3887
+ }
3888
+ __name(renderOptimisticStack, "renderOptimisticStack");
3889
+ function settleOptimisticUpdates(cacheState, optimisticState, snapshots, outcome) {
3890
+ const settledKeys = [];
3891
+ for (const snapshot of snapshots) {
3892
+ const stack = optimisticState.get(snapshot.key);
3893
+ if (stack !== snapshot.stack) continue;
3894
+ if (!reconcileOptimisticInvalidation(cacheState, snapshot.key, stack)) {
3895
+ optimisticState.delete(snapshot.key);
3896
+ continue;
3897
+ }
3898
+ if (outcome === "rollback") {
3899
+ stack.layers = stack.layers.filter((layer) => layer !== snapshot.layer);
3900
+ } else {
3901
+ snapshot.layer.committed = true;
3902
+ if (outcome === "invalidate") stack.invalidatedAt = Date.now();
3903
+ }
3904
+ while (stack.layers[0]?.committed) {
3905
+ stack.entry = applyOptimisticLayer(stack.entry, stack.layers.shift());
3906
+ }
3907
+ renderOptimisticStack(cacheState, snapshot.key, stack);
3908
+ if (stack.layers.length === 0) optimisticState.delete(snapshot.key);
3909
+ settledKeys.push(snapshot.key);
3910
+ }
3911
+ return settledKeys;
3912
+ }
3913
+ __name(settleOptimisticUpdates, "settleOptimisticUpdates");
3914
+ function applyServerFnOptimisticUpdates(updates, now2 = Date.now()) {
3915
+ const cacheState = getFarmClientDataCache();
3916
+ const optimisticState = getOptimisticState(cacheState);
3917
+ const snapshots = /* @__PURE__ */ new Map();
3918
+ for (const update of updates) {
3919
+ if (update.length !== 2) continue;
3920
+ const [target, updater] = update;
3921
+ if (typeof updater !== "function") continue;
3922
+ const targetKey = typeof target === "string" || Array.isArray(target) ? normalizeFarmClientCacheKey(target) : null;
3923
+ if (!targetKey) continue;
3924
+ const targetEntry = getValidCacheEntry(cacheState, targetKey, now2);
3925
+ const currentEntry = cacheState.get(targetKey);
3926
+ let stack = optimisticState.get(targetKey);
3927
+ if (stack && !reconcileOptimisticInvalidation(cacheState, targetKey, stack)) {
3928
+ stack = void 0;
3929
+ }
3930
+ if (!stack) {
3931
+ stack = {
3932
+ entry: targetEntry ? { ...targetEntry } : void 0,
3933
+ layers: [],
3934
+ renderedEntry: currentEntry
3935
+ };
3936
+ optimisticState.set(targetKey, stack);
3937
+ }
3938
+ let snapshot = snapshots.get(targetKey);
3939
+ if (!snapshot) {
3940
+ const previousEntry = stack.layers.length === 0 ? stack.entry : stack.renderedEntry;
3941
+ const layer = {
3942
+ updaters: [],
3943
+ updatedAt: now2,
3944
+ // A server function has no cache policy of its own; preserve the
3945
+ // target read's freshness metadata when it exists.
3946
+ staleAt: targetEntry?.staleAt ?? now2,
3947
+ gcAt: targetEntry?.gcAt
3948
+ };
3949
+ stack.layers.push(layer);
3950
+ snapshot = { key: targetKey, stack, layer };
3951
+ snapshots.set(targetKey, snapshot);
3952
+ snapshot.layer.updaters.push(updater);
3953
+ const nextEntry2 = applyOptimisticLayer(previousEntry, {
3954
+ ...snapshot.layer,
3955
+ updaters: [updater]
3956
+ });
3957
+ storeOptimisticEntry(cacheState, targetKey, stack, nextEntry2);
3958
+ continue;
3959
+ }
3960
+ snapshot.layer.updaters.push(updater);
3961
+ const nextEntry = applyOptimisticLayer(stack.renderedEntry, {
3962
+ ...snapshot.layer,
3963
+ updaters: [updater]
3964
+ });
3965
+ storeOptimisticEntry(cacheState, targetKey, stack, nextEntry);
3966
+ }
3967
+ return Array.from(snapshots.values());
3968
+ }
3969
+ __name(applyServerFnOptimisticUpdates, "applyServerFnOptimisticUpdates");
3970
+ function settleServerFnOptimisticUpdates(snapshots, outcome) {
3971
+ if (snapshots.length === 0) return;
3972
+ const cacheState = getFarmClientDataCache();
3973
+ settleOptimisticUpdates(cacheState, getOptimisticState(cacheState), snapshots, outcome);
3974
+ }
3975
+ __name(settleServerFnOptimisticUpdates, "settleServerFnOptimisticUpdates");
3976
+ function resolveServerFnInvalidateTargets(invalidate) {
3977
+ const targets = Array.isArray(invalidate) ? invalidate : invalidate.targets;
3978
+ const keys = [];
3979
+ for (const target of targets) {
3980
+ if (typeof target === "string" || Array.isArray(target)) {
3981
+ if (Array.isArray(target) && typeof target[0] === "function") continue;
3982
+ keys.push(normalizeFarmClientCacheKey(target));
3983
+ } else if (target && typeof target === "object" && "key" in target) {
3984
+ keys.push(normalizeFarmClientCacheKey(target.key));
3985
+ }
3986
+ }
3987
+ return keys;
3988
+ }
3989
+ __name(resolveServerFnInvalidateTargets, "resolveServerFnInvalidateTargets");
3817
3990
  function buildCacheKey(method, path, input, baseURL, defaultHeaders) {
3818
3991
  const keyInput = input && typeof input === "object" ? {
3819
3992
  query: input.query,
@@ -3992,6 +4165,42 @@ __name(readEndpointErrorEnvelope, "readEndpointErrorEnvelope");
3992
4165
 
3993
4166
  // src/mutation-client.ts
3994
4167
  var import_react = require("react");
4168
+
4169
+ // src/client-network-status.ts
4170
+ function isNavigatorOnline() {
4171
+ if (typeof navigator === "undefined" || typeof navigator.onLine !== "boolean") return true;
4172
+ return navigator.onLine;
4173
+ }
4174
+ __name(isNavigatorOnline, "isNavigatorOnline");
4175
+ function subscribeOnline(listener) {
4176
+ if (typeof window === "undefined") return () => {
4177
+ };
4178
+ window.addEventListener("online", listener);
4179
+ return () => window.removeEventListener("online", listener);
4180
+ }
4181
+ __name(subscribeOnline, "subscribeOnline");
4182
+
4183
+ // src/mutation-retry.ts
4184
+ async function invokeMutationWithRetry(invoke, retry, shouldContinue) {
4185
+ const maxRetries = Math.max(0, retry?.count ?? 0);
4186
+ let attempt = 0;
4187
+ while (true) {
4188
+ try {
4189
+ return await invoke();
4190
+ } catch (error) {
4191
+ if (attempt >= maxRetries || !shouldContinue()) throw error;
4192
+ attempt += 1;
4193
+ const delay2 = typeof retry?.delay === "function" ? retry.delay(attempt) : retry?.delay ?? 0;
4194
+ if (delay2 > 0) {
4195
+ await new Promise((resolve) => setTimeout(resolve, delay2));
4196
+ if (!shouldContinue()) throw error;
4197
+ }
4198
+ }
4199
+ }
4200
+ }
4201
+ __name(invokeMutationWithRetry, "invokeMutationWithRetry");
4202
+
4203
+ // src/mutation-client.ts
3995
4204
  function useMutation(target, options = {}) {
3996
4205
  return useMutationLifecycle(target, options).mutation;
3997
4206
  }
@@ -4004,12 +4213,14 @@ function useMutationLifecycle(target, options = {}) {
4004
4213
  const lastResetIdRef = (0, import_react.useRef)(0);
4005
4214
  const initialState = {
4006
4215
  pendingCount: 0,
4216
+ pausedCount: 0,
4007
4217
  status: "idle",
4008
4218
  data: initialData,
4009
4219
  error: null,
4010
4220
  variables: void 0
4011
4221
  };
4012
4222
  const stateRef = (0, import_react.useRef)(initialState);
4223
+ const resetWakersRef = (0, import_react.useRef)(/* @__PURE__ */ new Set());
4013
4224
  const [state, setState] = (0, import_react.useState)(initialState);
4014
4225
  optionsRef.current = options;
4015
4226
  targetRef.current = target;
@@ -4021,6 +4232,31 @@ function useMutationLifecycle(target, options = {}) {
4021
4232
  },
4022
4233
  []
4023
4234
  );
4235
+ const waitForReconnect = (0, import_react.useCallback)(
4236
+ async (requestId) => {
4237
+ while (!isNavigatorOnline()) {
4238
+ if (requestId < lastResetIdRef.current) return;
4239
+ setMutationState((current) => ({ ...current, pausedCount: current.pausedCount + 1 }));
4240
+ try {
4241
+ await new Promise((resolve) => {
4242
+ const wake = /* @__PURE__ */ __name(() => {
4243
+ unsubscribe();
4244
+ resetWakersRef.current.delete(wake);
4245
+ resolve();
4246
+ }, "wake");
4247
+ const unsubscribe = subscribeOnline(wake);
4248
+ resetWakersRef.current.add(wake);
4249
+ });
4250
+ } finally {
4251
+ setMutationState((current) => ({
4252
+ ...current,
4253
+ pausedCount: Math.max(0, current.pausedCount - 1)
4254
+ }));
4255
+ }
4256
+ }
4257
+ },
4258
+ [setMutationState]
4259
+ );
4024
4260
  const mutatePreparedAsync = (0, import_react.useCallback)(
4025
4261
  async (prepare) => {
4026
4262
  const requestId = ++requestIdRef.current;
@@ -4043,17 +4279,49 @@ function useMutationLifecycle(target, options = {}) {
4043
4279
  if (requestId !== requestIdRef.current) return { ...current, pendingCount };
4044
4280
  return {
4045
4281
  pendingCount,
4282
+ pausedCount: current.pausedCount,
4046
4283
  status: "pending",
4047
4284
  data: hasOptimisticData ? optimisticData : currentOptions.resetOnMutate === false ? current.data : null,
4048
4285
  error: null,
4049
4286
  variables
4050
4287
  };
4051
4288
  });
4289
+ const mutationTarget = targetRef.current;
4290
+ const isAPITarget = isAPIRouteRef(mutationTarget);
4291
+ const sharedOptimistic = !preparationFailed && !isAPITarget ? currentOptions.request?.optimistic : void 0;
4292
+ const sharedSnapshots = sharedOptimistic?.update?.length ? applyServerFnOptimisticUpdates(sharedOptimistic.update) : [];
4052
4293
  try {
4053
4294
  if (preparationFailed) throw preparationError;
4054
- const mutationTarget = targetRef.current;
4055
- const rawResult = isAPIRouteRef(mutationTarget) ? await mutationTarget(variables, currentOptions.request) : await mutationTarget(variables);
4056
- const data = unwrapMutationResult(rawResult, isAPIRouteRef(mutationTarget));
4295
+ let data;
4296
+ while (true) {
4297
+ if (currentOptions.networkMode === "online") {
4298
+ await waitForReconnect(requestId);
4299
+ if (requestId < lastResetIdRef.current) {
4300
+ throw new Error("Mutation reset while waiting for reconnection");
4301
+ }
4302
+ }
4303
+ try {
4304
+ const rawResult = isAPITarget ? await mutationTarget(variables, currentOptions.request) : await invokeMutationWithRetry(
4305
+ () => targetRef.current(variables),
4306
+ currentOptions.request?.retry,
4307
+ // A reset disowns this submission; stop scheduling retries then.
4308
+ () => requestId >= lastResetIdRef.current
4309
+ );
4310
+ data = unwrapMutationResult(rawResult, isAPITarget);
4311
+ break;
4312
+ } catch (cause) {
4313
+ if (currentOptions.networkMode === "online" && !isNavigatorOnline() && requestId >= lastResetIdRef.current) {
4314
+ continue;
4315
+ }
4316
+ throw cause;
4317
+ }
4318
+ }
4319
+ settleServerFnOptimisticUpdates(sharedSnapshots, "commit");
4320
+ if (!isAPITarget && currentOptions.request?.invalidate) {
4321
+ for (const key of resolveServerFnInvalidateTargets(currentOptions.request.invalidate)) {
4322
+ notifyFarmCacheInvalidation(key);
4323
+ }
4324
+ }
4057
4325
  const isLatestRequest = requestId === requestIdRef.current;
4058
4326
  setMutationState((current) => {
4059
4327
  if (requestId < lastResetIdRef.current) return current;
@@ -4066,6 +4334,7 @@ function useMutationLifecycle(target, options = {}) {
4066
4334
  }
4067
4335
  return {
4068
4336
  pendingCount,
4337
+ pausedCount: current.pausedCount,
4069
4338
  status: "success",
4070
4339
  data,
4071
4340
  error: null,
@@ -4084,6 +4353,10 @@ function useMutationLifecycle(target, options = {}) {
4084
4353
  }
4085
4354
  return data;
4086
4355
  } catch (cause) {
4356
+ settleServerFnOptimisticUpdates(
4357
+ sharedSnapshots,
4358
+ sharedOptimistic?.rollbackOnError ? "rollback" : "invalidate"
4359
+ );
4087
4360
  const error = normalizeMutationError(cause);
4088
4361
  const isLatestRequest = requestId === requestIdRef.current;
4089
4362
  setMutationState((current) => {
@@ -4097,6 +4370,7 @@ function useMutationLifecycle(target, options = {}) {
4097
4370
  }
4098
4371
  return {
4099
4372
  pendingCount,
4373
+ pausedCount: current.pausedCount,
4100
4374
  status: "error",
4101
4375
  data: hasOptimisticData && currentOptions.rollbackOnError ? previousData : currentOptions.resetOnMutate === false ? current.data : null,
4102
4376
  error,
@@ -4116,7 +4390,7 @@ function useMutationLifecycle(target, options = {}) {
4116
4390
  throw error;
4117
4391
  }
4118
4392
  },
4119
- [setMutationState]
4393
+ [setMutationState, waitForReconnect]
4120
4394
  );
4121
4395
  const mutateAsync = (0, import_react.useCallback)(
4122
4396
  (variables) => mutatePreparedAsync(() => variables),
@@ -4133,15 +4407,20 @@ function useMutationLifecycle(target, options = {}) {
4133
4407
  lastResetIdRef.current = ++requestIdRef.current;
4134
4408
  setMutationState({
4135
4409
  pendingCount: 0,
4410
+ pausedCount: 0,
4136
4411
  status: "idle",
4137
4412
  data: optionsRef.current.initialData ?? null,
4138
4413
  error: null,
4139
4414
  variables: void 0
4140
4415
  });
4416
+ const wakers = Array.from(resetWakersRef.current);
4417
+ resetWakersRef.current.clear();
4418
+ for (const wake of wakers) wake();
4141
4419
  }, [setMutationState]);
4142
4420
  const mutation = (0, import_react.useMemo)(
4143
4421
  () => ({
4144
4422
  pending: state.pendingCount > 0,
4423
+ paused: state.pausedCount > 0,
4145
4424
  status: state.status,
4146
4425
  data: state.data,
4147
4426
  error: state.error,
@@ -4156,6 +4435,7 @@ function useMutationLifecycle(target, options = {}) {
4156
4435
  reset,
4157
4436
  state.data,
4158
4437
  state.error,
4438
+ state.pausedCount,
4159
4439
  state.pendingCount,
4160
4440
  state.status,
4161
4441
  state.variables
@@ -4275,6 +4555,7 @@ function useFetcher(target, options = {}) {
4275
4555
  state: mutation.pending ? "submitting" : "idle",
4276
4556
  status: mutation.status,
4277
4557
  pending: mutation.pending,
4558
+ paused: mutation.paused,
4278
4559
  data: mutation.data,
4279
4560
  error: mutation.error,
4280
4561
  variables: mutation.variables,
@@ -4289,6 +4570,7 @@ function useFetcher(target, options = {}) {
4289
4570
  formData,
4290
4571
  mutation.data,
4291
4572
  mutation.error,
4573
+ mutation.paused,
4292
4574
  mutation.pending,
4293
4575
  mutation.status,
4294
4576
  mutation.variables,
@@ -4307,9 +4589,18 @@ function mapFetcherFormData(target, formData, options) {
4307
4589
  if (!isAPIRouteRef(target)) {
4308
4590
  return formData;
4309
4591
  }
4310
- const values = formDataToObject(formData);
4311
4592
  const method = getAPIRouteRefMetadata(target)?.method;
4312
- return method === "GET" || method === "HEAD" ? { query: values } : { body: values };
4593
+ const query = method === "GET" || method === "HEAD";
4594
+ const encoding = context2.submitter?.getAttribute("formenctype") ?? context2.form?.enctype;
4595
+ if (!query && (encoding?.toLowerCase() === "multipart/form-data" || Array.from(formData.values()).some((value) => typeof value !== "string"))) {
4596
+ const body = new FormData();
4597
+ for (const [key, value] of formData) {
4598
+ if (!isUnsafeFormKey(key)) body.append(key, value);
4599
+ }
4600
+ return { body };
4601
+ }
4602
+ const values = formDataToObject(formData);
4603
+ return query ? { query: values } : { body: values };
4313
4604
  }
4314
4605
  __name(mapFetcherFormData, "mapFetcherFormData");
4315
4606
  function resolveFetcherFormAction(target, metadata) {
@@ -4321,7 +4612,7 @@ __name(resolveFetcherFormAction, "resolveFetcherFormAction");
4321
4612
  function formDataToObject(formData) {
4322
4613
  const output = /* @__PURE__ */ Object.create(null);
4323
4614
  for (const [key, value] of formData.entries()) {
4324
- if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
4615
+ if (isUnsafeFormKey(key)) continue;
4325
4616
  const current = output[key];
4326
4617
  if (current === void 0) {
4327
4618
  output[key] = value;
@@ -4334,6 +4625,10 @@ function formDataToObject(formData) {
4334
4625
  return output;
4335
4626
  }
4336
4627
  __name(formDataToObject, "formDataToObject");
4628
+ function isUnsafeFormKey(key) {
4629
+ return key === "__proto__" || key === "constructor" || key === "prototype";
4630
+ }
4631
+ __name(isUnsafeFormKey, "isUnsafeFormKey");
4337
4632
  function createSubmitterFormData(form, submitter) {
4338
4633
  try {
4339
4634
  return new FormData(form, submitter);
@@ -4415,7 +4710,12 @@ function useServerFn(serverFn, options = {}) {
4415
4710
  };
4416
4711
  });
4417
4712
  try {
4418
- const result = await serverFn(input);
4713
+ const result = await invokeMutationWithRetry(
4714
+ () => serverFn(input),
4715
+ options.retry,
4716
+ // A reset disowns this submission; stop scheduling retries then.
4717
+ () => requestId >= lastResetIdRef.current
4718
+ );
4419
4719
  const isLatestRequest = requestId === requestIdRef.current;
4420
4720
  setActionState((current) => {
4421
4721
  if (requestId < lastResetIdRef.current) return current;
@@ -4472,7 +4772,14 @@ function useServerFn(serverFn, options = {}) {
4472
4772
  throw error;
4473
4773
  }
4474
4774
  },
4475
- [options.optimistic, options.rollbackOnError, resetOnSubmit, serverFn, setActionState]
4775
+ [
4776
+ options.optimistic,
4777
+ options.retry,
4778
+ options.rollbackOnError,
4779
+ resetOnSubmit,
4780
+ serverFn,
4781
+ setActionState
4782
+ ]
4476
4783
  );
4477
4784
  const formAction = (0, import_react3.useCallback)(
4478
4785
  async (formData) => {
@@ -4574,6 +4881,21 @@ __name(isFormData3, "isFormData");
4574
4881
  // src/server-query-client.ts
4575
4882
  var import_react4 = require("react");
4576
4883
 
4884
+ // src/client-revalidation.ts
4885
+ function attachRevalidationListeners(refresh, options = {}) {
4886
+ if (typeof window === "undefined") return () => {
4887
+ };
4888
+ const onFocus = options.refetchOnWindowFocus === false ? void 0 : refresh;
4889
+ const onOnline = options.refetchOnReconnect === false ? void 0 : refresh;
4890
+ if (onFocus) window.addEventListener("focus", onFocus);
4891
+ if (onOnline) window.addEventListener("online", onOnline);
4892
+ return () => {
4893
+ if (onFocus) window.removeEventListener("focus", onFocus);
4894
+ if (onOnline) window.removeEventListener("online", onOnline);
4895
+ };
4896
+ }
4897
+ __name(attachRevalidationListeners, "attachRevalidationListeners");
4898
+
4577
4899
  // src/server-query-runtime.ts
4578
4900
  var FARM_SERVER_QUERY_CLIENT_STATE = /* @__PURE__ */ Symbol.for("farm.serverQueryClientState");
4579
4901
  var serverQueryClientGlobal = globalThis;
@@ -4581,9 +4903,30 @@ var serverQueryClientState = serverQueryClientGlobal[FARM_SERVER_QUERY_CLIENT_ST
4581
4903
  functionIds: /* @__PURE__ */ new WeakMap(),
4582
4904
  nextFunctionId: 0,
4583
4905
  active: [],
4584
- latestOwners: /* @__PURE__ */ new Map()
4906
+ latestOwners: /* @__PURE__ */ new Map(),
4907
+ owners: /* @__PURE__ */ new Set()
4585
4908
  });
4586
4909
  serverQueryClientState.latestOwners ?? (serverQueryClientState.latestOwners = /* @__PURE__ */ new Map());
4910
+ serverQueryClientState.owners ?? (serverQueryClientState.owners = /* @__PURE__ */ new Set());
4911
+ function isServerQueryOwnerSuperseded(owner, key) {
4912
+ const cache = getFarmClientDataCache();
4913
+ const resolved = cache.resolveKey(key);
4914
+ for (const superseded of owner.supersededKeys ?? []) {
4915
+ if (cache.resolveKey(superseded) === resolved) return true;
4916
+ }
4917
+ return false;
4918
+ }
4919
+ __name(isServerQueryOwnerSuperseded, "isServerQueryOwnerSuperseded");
4920
+ function claimServerQueryKey(owner, key) {
4921
+ if (isServerQueryOwnerSuperseded(owner, key)) return false;
4922
+ const resolved = getFarmClientDataCache().resolveKey(key);
4923
+ for (const older of serverQueryClientState.owners) {
4924
+ if (older === owner) break;
4925
+ older.supersededKeys.add(resolved);
4926
+ }
4927
+ return true;
4928
+ }
4929
+ __name(claimServerQueryKey, "claimServerQueryKey");
4587
4930
  var RAW_SERVER_QUERY_SYMBOL = /* @__PURE__ */ Symbol.for("farm.server-query");
4588
4931
  function assertNotRawServerQueryInBrowser(query) {
4589
4932
  if (typeof window === "undefined" || typeof document === "undefined") return;
@@ -4597,6 +4940,10 @@ function assertNotRawServerQueryInBrowser(query) {
4597
4940
  );
4598
4941
  }
4599
4942
  __name(assertNotRawServerQueryInBrowser, "assertNotRawServerQueryInBrowser");
4943
+ function isCurrentServerQueryOwner(provisionalKey, owner) {
4944
+ return serverQueryClientState.latestOwners.get(provisionalKey) === owner && !isServerQueryOwnerSuperseded(owner, provisionalKey);
4945
+ }
4946
+ __name(isCurrentServerQueryOwner, "isCurrentServerQueryOwner");
4600
4947
  function createServerQueryCallKey(query, input) {
4601
4948
  let id = serverQueryClientState.functionIds.get(query);
4602
4949
  if (!id) {
@@ -4612,12 +4959,14 @@ async function fetchServerQuery(query, input, options = {}) {
4612
4959
  const entry = cache.get(provisionalKey);
4613
4960
  const stale = cache.isStale(provisionalKey);
4614
4961
  const inflight = cache.getInflight(provisionalKey);
4615
- if (inflight && !options.force) return inflight;
4616
- if (!options.force && entry && !stale && entry.status !== "error") return entry.data;
4617
- if (!options.force && entry && stale && entry.status !== "pending" && entry.status !== "error" && (options.swr ?? true)) {
4618
- void executeServerQuery(query, input, provisionalKey, options).catch(() => void 0);
4962
+ if (!options.force && entry && stale && (entry.status !== "pending" || entry.updatedAt !== 0) && entry.status !== "error" && (options.swr ?? true)) {
4963
+ if (!inflight) {
4964
+ void executeServerQuery(query, input, provisionalKey, options).catch(() => void 0);
4965
+ }
4619
4966
  return entry.data;
4620
4967
  }
4968
+ if (inflight && !options.force) return inflight;
4969
+ if (!options.force && entry && !stale && entry.status !== "error") return entry.data;
4621
4970
  return executeServerQuery(query, input, provisionalKey, options);
4622
4971
  }
4623
4972
  __name(fetchServerQuery, "fetchServerQuery");
@@ -4630,8 +4979,13 @@ async function executeServerQuery(query, input, provisionalKey, options) {
4630
4979
  const cache = getFarmClientDataCache();
4631
4980
  const inflight = cache.getInflight(provisionalKey);
4632
4981
  if (inflight && !options.force) return inflight;
4633
- const owner = { invalidations: trackFarmClientCacheInvalidations(cache) };
4982
+ const owner = {
4983
+ invalidations: trackFarmClientCacheInvalidations(cache),
4984
+ supersededKeys: /* @__PURE__ */ new Set()
4985
+ };
4634
4986
  serverQueryClientState.latestOwners.set(provisionalKey, owner);
4987
+ serverQueryClientState.owners.add(owner);
4988
+ claimServerQueryKey(owner, provisionalKey);
4635
4989
  const previous = cache.get(provisionalKey);
4636
4990
  cache.set(provisionalKey, {
4637
4991
  data: previous?.data,
@@ -4656,7 +5010,7 @@ async function executeServerQuery(query, input, provisionalKey, options) {
4656
5010
  }
4657
5011
  const data = await pending;
4658
5012
  const transported = cache.get(provisionalKey);
4659
- if (serverQueryClientState.latestOwners.get(provisionalKey) === owner && (!transported || transported.fetching)) {
5013
+ if (isCurrentServerQueryOwner(provisionalKey, owner) && (!transported || transported.fetching)) {
4660
5014
  const updatedAt = Date.now();
4661
5015
  cache.set(provisionalKey, {
4662
5016
  data,
@@ -4670,7 +5024,7 @@ async function executeServerQuery(query, input, provisionalKey, options) {
4670
5024
  return data;
4671
5025
  } catch (cause) {
4672
5026
  const error = normalizeServerQueryError(cause);
4673
- if (serverQueryClientState.latestOwners.get(provisionalKey) === owner) {
5027
+ if (isCurrentServerQueryOwner(provisionalKey, owner)) {
4674
5028
  const current = cache.get(provisionalKey);
4675
5029
  cache.set(provisionalKey, {
4676
5030
  data: current?.data,
@@ -4685,8 +5039,10 @@ async function executeServerQuery(query, input, provisionalKey, options) {
4685
5039
  }
4686
5040
  throw error;
4687
5041
  } finally {
4688
- const invalidated = serverQueryClientState.latestOwners.get(provisionalKey) === owner && owner.invalidations.has(provisionalKey);
5042
+ const invalidated = isCurrentServerQueryOwner(provisionalKey, owner) && owner.invalidations.has(provisionalKey);
4689
5043
  owner.invalidations.dispose();
5044
+ serverQueryClientState.owners.delete(owner);
5045
+ owner.supersededKeys.clear();
4690
5046
  if (cache.getInflight(provisionalKey) === promise) {
4691
5047
  cache.deleteInflight(provisionalKey);
4692
5048
  }
@@ -4752,18 +5108,16 @@ function useServerQuery(query, input, options = {}) {
4752
5108
  }
4753
5109
  }, [cache, entry, key, options.enabled, run]);
4754
5110
  (0, import_react4.useEffect)(() => {
4755
- if (options.enabled === false || typeof window === "undefined") return;
4756
- const refreshIfStale = /* @__PURE__ */ __name(() => {
4757
- if (cache.isStale(key)) void run().catch(() => void 0);
4758
- }, "refreshIfStale");
4759
- const onFocus = options.refetchOnWindowFocus === false ? void 0 : refreshIfStale;
4760
- const onOnline = options.refetchOnReconnect === false ? void 0 : refreshIfStale;
4761
- if (onFocus) window.addEventListener("focus", onFocus);
4762
- if (onOnline) window.addEventListener("online", onOnline);
4763
- return () => {
4764
- if (onFocus) window.removeEventListener("focus", onFocus);
4765
- if (onOnline) window.removeEventListener("online", onOnline);
4766
- };
5111
+ if (options.enabled === false) return;
5112
+ return attachRevalidationListeners(
5113
+ () => {
5114
+ if (cache.isStale(key)) void run().catch(() => void 0);
5115
+ },
5116
+ {
5117
+ refetchOnWindowFocus: options.refetchOnWindowFocus,
5118
+ refetchOnReconnect: options.refetchOnReconnect
5119
+ }
5120
+ );
4767
5121
  }, [cache, key, options.enabled, options.refetchOnReconnect, options.refetchOnWindowFocus, run]);
4768
5122
  const status = entry?.status ?? (entry ? "success" : "idle");
4769
5123
  const fetching = entry?.fetching ?? false;
@@ -4779,6 +5133,296 @@ function useServerQuery(query, input, options = {}) {
4779
5133
  }
4780
5134
  __name(useServerQuery, "useServerQuery");
4781
5135
 
5136
+ // src/cache-invalidation-broadcast.ts
5137
+ var FARM_CACHE_INVALIDATION_CHANNEL = "farm:cache-invalidation";
5138
+ var activeBridge;
5139
+ function enableCrossTabCacheInvalidation(options = {}) {
5140
+ if (typeof BroadcastChannel !== "function") return () => {
5141
+ };
5142
+ const channelName = options.channelName ?? FARM_CACHE_INVALIDATION_CHANNEL;
5143
+ if (activeBridge) {
5144
+ if (activeBridge.channelName !== channelName) {
5145
+ throw new Error(
5146
+ `Cross-tab cache invalidation is already enabled on channel "${activeBridge.channelName}".`
5147
+ );
5148
+ }
5149
+ activeBridge.refCount += 1;
5150
+ } else {
5151
+ activeBridge = createBridge(channelName);
5152
+ }
5153
+ let disposed = false;
5154
+ return () => {
5155
+ if (disposed || !activeBridge) return;
5156
+ disposed = true;
5157
+ activeBridge.refCount -= 1;
5158
+ if (activeBridge.refCount === 0) {
5159
+ activeBridge.teardown();
5160
+ activeBridge = void 0;
5161
+ }
5162
+ };
5163
+ }
5164
+ __name(enableCrossTabCacheInvalidation, "enableCrossTabCacheInvalidation");
5165
+ function createBridge(channelName) {
5166
+ const channel = new BroadcastChannel(channelName);
5167
+ let applyingRemote = false;
5168
+ let pending = [];
5169
+ let flushScheduled = false;
5170
+ let closed = false;
5171
+ const flush = /* @__PURE__ */ __name(() => {
5172
+ flushScheduled = false;
5173
+ if (closed || pending.length === 0) return;
5174
+ const encoded = encodeFarmCacheInvalidations(pending);
5175
+ pending = [];
5176
+ if (encoded !== null) channel.postMessage(encoded);
5177
+ }, "flush");
5178
+ const unsubscribe = subscribeFarmCacheInvalidation((key) => {
5179
+ if (applyingRemote || closed) return;
5180
+ pending.push(key);
5181
+ if (!flushScheduled) {
5182
+ flushScheduled = true;
5183
+ queueMicrotask(flush);
5184
+ }
5185
+ });
5186
+ channel.onmessage = (event) => {
5187
+ const keys = decodeFarmCacheInvalidations(
5188
+ typeof event.data === "string" ? event.data : void 0
5189
+ );
5190
+ if (keys.length === 0) return;
5191
+ applyingRemote = true;
5192
+ try {
5193
+ for (const key of keys) notifyFarmCacheInvalidation(key);
5194
+ } finally {
5195
+ applyingRemote = false;
5196
+ }
5197
+ };
5198
+ return {
5199
+ channelName,
5200
+ refCount: 1,
5201
+ teardown() {
5202
+ closed = true;
5203
+ pending = [];
5204
+ unsubscribe();
5205
+ channel.onmessage = null;
5206
+ channel.close();
5207
+ }
5208
+ };
5209
+ }
5210
+ __name(createBridge, "createBridge");
5211
+
5212
+ // src/client-cache-persistence.ts
5213
+ var FARM_CLIENT_CACHE_PERSIST_VERSION = "1";
5214
+ function defineClientCacheAdapter(adapter) {
5215
+ for (const method of ["keys", "get", "set", "delete", "clear"]) {
5216
+ if (typeof adapter?.[method] !== "function") {
5217
+ throw new TypeError(
5218
+ `defineClientCacheAdapter expects a "${method}" method. Implement keys/get/set/delete/clear over your storage.`
5219
+ );
5220
+ }
5221
+ }
5222
+ return adapter;
5223
+ }
5224
+ __name(defineClientCacheAdapter, "defineClientCacheAdapter");
5225
+ function storageClientCacheAdapter(storage, options = {}) {
5226
+ if (!storage || typeof storage.getItem !== "function" || typeof storage.setItem !== "function" || typeof storage.removeItem !== "function") {
5227
+ throw new TypeError("storageClientCacheAdapter expects a compatible key-value client.");
5228
+ }
5229
+ const base = options.base ?? "farm-client-cache";
5230
+ const entryKey = /* @__PURE__ */ __name((key) => `${base}:${key}`, "entryKey");
5231
+ const enumerate = storage.getKeys?.bind(storage) ?? storage.keys?.bind(storage);
5232
+ return {
5233
+ async keys() {
5234
+ if (!enumerate) return [];
5235
+ const keys = await enumerate(base);
5236
+ const prefix = `${base}:`;
5237
+ return keys.filter((key) => key.startsWith(prefix)).map((key) => key.slice(prefix.length));
5238
+ },
5239
+ async get(key) {
5240
+ return await storage.getItem(entryKey(key)) ?? null;
5241
+ },
5242
+ async set(key, entry) {
5243
+ await storage.setItem(entryKey(key), entry);
5244
+ },
5245
+ async delete(key) {
5246
+ await storage.removeItem(entryKey(key));
5247
+ },
5248
+ async clear() {
5249
+ if (storage.clear) {
5250
+ await storage.clear(base);
5251
+ return;
5252
+ }
5253
+ if (!enumerate) return;
5254
+ const prefix = `${base}:`;
5255
+ for (const key of await enumerate(base)) {
5256
+ if (key.startsWith(prefix)) await storage.removeItem(key);
5257
+ }
5258
+ }
5259
+ };
5260
+ }
5261
+ __name(storageClientCacheAdapter, "storageClientCacheAdapter");
5262
+ var activeEngine;
5263
+ function reportPersistenceFailure(error) {
5264
+ const report = typeof reportError === "function" ? reportError : console.error;
5265
+ if (error instanceof Error) {
5266
+ report(error);
5267
+ return;
5268
+ }
5269
+ const normalized = new Error("Client cache persistence failed");
5270
+ normalized.cause = error;
5271
+ report(normalized);
5272
+ }
5273
+ __name(reportPersistenceFailure, "reportPersistenceFailure");
5274
+ function disableEngine(engine, error) {
5275
+ if (engine.disabled) return;
5276
+ engine.disabled = true;
5277
+ engine.pendingSets.clear();
5278
+ engine.pendingDeletes.clear();
5279
+ if (engine.flushTimer !== void 0) {
5280
+ clearTimeout(engine.flushTimer);
5281
+ engine.flushTimer = void 0;
5282
+ }
5283
+ reportPersistenceFailure(error);
5284
+ }
5285
+ __name(disableEngine, "disableEngine");
5286
+ function scheduleFlush(engine) {
5287
+ if (engine.disabled || engine.flushTimer !== void 0) return;
5288
+ const timer = setTimeout(() => {
5289
+ engine.flushTimer = void 0;
5290
+ void flushEngine(engine);
5291
+ }, engine.flushDelayMs);
5292
+ timer.unref?.();
5293
+ engine.flushTimer = timer;
5294
+ }
5295
+ __name(scheduleFlush, "scheduleFlush");
5296
+ async function flushEngine(engine) {
5297
+ if (engine.disabled) return;
5298
+ const sets = Array.from(engine.pendingSets.entries());
5299
+ const deletes = Array.from(engine.pendingDeletes);
5300
+ engine.pendingSets.clear();
5301
+ engine.pendingDeletes.clear();
5302
+ try {
5303
+ if (sets.length > 0) {
5304
+ if (engine.adapter.setMany) await engine.adapter.setMany(sets);
5305
+ else for (const [key, entry] of sets) await engine.adapter.set(key, entry);
5306
+ }
5307
+ for (const key of deletes) await engine.adapter.delete(key);
5308
+ } catch (error) {
5309
+ disableEngine(engine, error);
5310
+ }
5311
+ }
5312
+ __name(flushEngine, "flushEngine");
5313
+ async function hydrateEngine(engine) {
5314
+ const now2 = Date.now();
5315
+ const keys = await engine.adapter.keys();
5316
+ if (keys.length === 0) return;
5317
+ const persisted = engine.adapter.getMany ? await engine.adapter.getMany(keys) : await Promise.all(keys.map((key) => engine.adapter.get(key)));
5318
+ engine.hydrating = true;
5319
+ try {
5320
+ for (let index = 0; index < keys.length; index += 1) {
5321
+ const key = keys[index];
5322
+ const entry = persisted[index];
5323
+ if (engine.disabled) return;
5324
+ if (!entry || entry.version !== engine.version || entry.gcAt !== void 0 && now2 >= entry.gcAt) {
5325
+ engine.pendingDeletes.add(key);
5326
+ continue;
5327
+ }
5328
+ if (engine.cache.get(key, now2)) continue;
5329
+ engine.cache.set(key, {
5330
+ data: entry.data,
5331
+ updatedAt: entry.updatedAt,
5332
+ staleAt: 0,
5333
+ gcAt: entry.gcAt,
5334
+ status: "success",
5335
+ error: null,
5336
+ persist: true
5337
+ });
5338
+ }
5339
+ } finally {
5340
+ engine.hydrating = false;
5341
+ }
5342
+ if (engine.pendingDeletes.size > 0) scheduleFlush(engine);
5343
+ }
5344
+ __name(hydrateEngine, "hydrateEngine");
5345
+ function createSink(engine) {
5346
+ return {
5347
+ onSet(key, entry) {
5348
+ if (engine.disabled || engine.hydrating) return;
5349
+ if (!entry.persist || entry.fetching || entry.error || entry.status === "pending") return;
5350
+ if (engine.persistKey && !engine.persistKey(key)) return;
5351
+ engine.pendingDeletes.delete(key);
5352
+ engine.pendingSets.set(key, {
5353
+ data: entry.data,
5354
+ updatedAt: entry.updatedAt,
5355
+ staleAt: entry.staleAt,
5356
+ gcAt: entry.gcAt,
5357
+ version: engine.version
5358
+ });
5359
+ scheduleFlush(engine);
5360
+ },
5361
+ onDelete(key) {
5362
+ if (engine.disabled) return;
5363
+ engine.pendingSets.delete(key);
5364
+ engine.pendingDeletes.add(key);
5365
+ scheduleFlush(engine);
5366
+ },
5367
+ onClear() {
5368
+ if (engine.disabled) return;
5369
+ engine.pendingSets.clear();
5370
+ engine.pendingDeletes.clear();
5371
+ void engine.adapter.clear().catch((error) => disableEngine(engine, error));
5372
+ }
5373
+ };
5374
+ }
5375
+ __name(createSink, "createSink");
5376
+ function initPersistedClientCache(adapter, options = {}) {
5377
+ defineClientCacheAdapter(adapter);
5378
+ disposePersistedClientCache();
5379
+ const engine = {
5380
+ adapter,
5381
+ cache: getFarmClientDataCache(),
5382
+ version: options.version ? `${FARM_CLIENT_CACHE_PERSIST_VERSION}:${options.version}` : FARM_CLIENT_CACHE_PERSIST_VERSION,
5383
+ persistKey: options.persistKey,
5384
+ flushDelayMs: options.flushDelayMs ?? 300,
5385
+ pendingSets: /* @__PURE__ */ new Map(),
5386
+ pendingDeletes: /* @__PURE__ */ new Set(),
5387
+ flushTimer: void 0,
5388
+ hydrating: false,
5389
+ disabled: false
5390
+ };
5391
+ activeEngine = engine;
5392
+ engine.cache.attachPersistence(createSink(engine));
5393
+ void hydrateEngine(engine).catch((error) => disableEngine(engine, error));
5394
+ return () => {
5395
+ if (activeEngine !== engine) return;
5396
+ disposePersistedClientCache();
5397
+ };
5398
+ }
5399
+ __name(initPersistedClientCache, "initPersistedClientCache");
5400
+ function disposePersistedClientCache() {
5401
+ const engine = activeEngine;
5402
+ if (!engine) return;
5403
+ activeEngine = void 0;
5404
+ engine.cache.attachPersistence(void 0);
5405
+ if (engine.flushTimer !== void 0) {
5406
+ clearTimeout(engine.flushTimer);
5407
+ engine.flushTimer = void 0;
5408
+ }
5409
+ engine.pendingSets.clear();
5410
+ engine.pendingDeletes.clear();
5411
+ }
5412
+ __name(disposePersistedClientCache, "disposePersistedClientCache");
5413
+ async function clearPersistedCache() {
5414
+ const engine = activeEngine;
5415
+ if (!engine) return;
5416
+ engine.pendingSets.clear();
5417
+ engine.pendingDeletes.clear();
5418
+ try {
5419
+ await engine.adapter.clear();
5420
+ } catch (error) {
5421
+ disableEngine(engine, error);
5422
+ }
5423
+ }
5424
+ __name(clearPersistedCache, "clearPersistedCache");
5425
+
4782
5426
  // src/integration-api.ts
4783
5427
  function defineIntegrationAPIOperation(operation2) {
4784
5428
  return {
@@ -6860,7 +7504,9 @@ var _SPARouter = class _SPARouter {
6860
7504
  if (this.onNavigate) {
6861
7505
  await this.onNavigate(pageData);
6862
7506
  }
6863
- if (this.options.scrollRestoration) {
7507
+ if (window.location.hash) {
7508
+ getHashTargetElement(window.location.hash)?.scrollIntoView();
7509
+ } else if (this.options.scrollRestoration) {
6864
7510
  this.restoreScrollPosition(window.location.pathname + window.location.search);
6865
7511
  }
6866
7512
  if (clientNavigation) {
@@ -7949,7 +8595,7 @@ body {
7949
8595
  `;
7950
8596
 
7951
8597
  // package.json
7952
- var version = "0.1.0-beta.96";
8598
+ var version = "0.1.0-beta.97";
7953
8599
 
7954
8600
  // src/version.ts
7955
8601
  var FARM_VERSION = version;
@@ -9250,12 +9896,15 @@ __name(isObject, "isObject");
9250
9896
  // Annotate the CommonJS export names for ESM import in node:
9251
9897
  0 && (module.exports = {
9252
9898
  APIClientError,
9899
+ FARM_CACHE_INVALIDATION_CHANNEL,
9900
+ FARM_CLIENT_CACHE_PERSIST_VERSION,
9253
9901
  FarmClientPluginManager,
9254
9902
  FetcherInputError,
9255
9903
  IntegrationClientError,
9256
9904
  Link,
9257
9905
  SPARouter,
9258
9906
  api,
9907
+ clearPersistedCache,
9259
9908
  createAPIClient,
9260
9909
  createApiClients,
9261
9910
  createClientPluginManager,
@@ -9266,13 +9915,16 @@ __name(isObject, "isObject");
9266
9915
  createIntegrations,
9267
9916
  createServerAPIClient,
9268
9917
  createStore,
9918
+ defineClientCacheAdapter,
9269
9919
  defineIntegrationAPI,
9270
9920
  defineIntegrationAPIOperation,
9921
+ enableCrossTabCacheInvalidation,
9271
9922
  endpoint,
9272
9923
  fetchServerQuery,
9273
9924
  getIntegrationAPIManifest,
9274
9925
  getRouter,
9275
9926
  getTheme,
9927
+ initPersistedClientCache,
9276
9928
  installChunkErrorRecovery,
9277
9929
  integrationClients,
9278
9930
  integrationsClient,
@@ -9285,6 +9937,7 @@ __name(isObject, "isObject");
9285
9937
  readPageState,
9286
9938
  replaceState,
9287
9939
  setTheme,
9940
+ storageClientCacheAdapter,
9288
9941
  toggleTheme,
9289
9942
  useAction,
9290
9943
  useBlocker,