@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
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @farm.js/core
2
2
 
3
- Core Farm.js framework - A modern React meta-framework
3
+ Core Farm.js framework for modern integrated apps
4
4
 
5
5
  Farm.js is currently in beta.
6
6
 
@@ -1,5 +1,5 @@
1
1
  import { ChildProcess } from 'node:child_process';
2
- import { U as BundleResultPayload, V as FarmPlugin, W as FarmIntegration } from './client-plugins-g4bzuCmo.mjs';
2
+ import { U as BundleResultPayload, V as FarmPlugin, W as FarmIntegration } from './client-plugins-DQQ1adXM.mjs';
3
3
  import './plugin-BJDf43dc.mjs';
4
4
  import 'react';
5
5
  import 'http';
@@ -19,6 +19,7 @@ import './env.mjs';
19
19
  import './server-action-security.mjs';
20
20
  import './image-config-Duob7wER.mjs';
21
21
  import './types-BH1lhg5G.mjs';
22
+ import './cache.mjs';
22
23
  import './route-runtime-DoOHzCAD.mjs';
23
24
 
24
25
  interface FarmAgentRuntimeInstance {
@@ -1,5 +1,5 @@
1
1
  import { ChildProcess } from 'node:child_process';
2
- import { U as BundleResultPayload, V as FarmPlugin, W as FarmIntegration } from './client-plugins-BZnpeTGA.js';
2
+ import { U as BundleResultPayload, V as FarmPlugin, W as FarmIntegration } from './client-plugins-Cw4qUGsw.js';
3
3
  import './plugin-BJDf43dc.js';
4
4
  import 'react';
5
5
  import 'http';
@@ -19,6 +19,7 @@ import './env.js';
19
19
  import './server-action-security.js';
20
20
  import './image-config-Duob7wER.js';
21
21
  import './types-BH1lhg5G.js';
22
+ import './cache.js';
22
23
  import './route-runtime-DoOHzCAD.js';
23
24
 
24
25
  interface FarmAgentRuntimeInstance {
@@ -170,6 +170,29 @@ function formatError(error) {
170
170
  }
171
171
  __name(formatError, "formatError");
172
172
 
173
+ // src/cache-invalidation.ts
174
+ var FARM_CACHE_INVALIDATION_HEADER = "x-farm-cache-invalidations";
175
+ function encodeFarmCacheInvalidations(keys) {
176
+ const normalized = Array.from(
177
+ new Set(keys.filter((key) => typeof key === "string" && key.length > 0))
178
+ );
179
+ if (normalized.length === 0) return null;
180
+ return encodeURIComponent(JSON.stringify(normalized));
181
+ }
182
+ __name(encodeFarmCacheInvalidations, "encodeFarmCacheInvalidations");
183
+ function decodeFarmCacheInvalidations(value) {
184
+ if (!value) return [];
185
+ try {
186
+ const parsed = JSON.parse(decodeURIComponent(value));
187
+ return Array.isArray(parsed) ? Array.from(
188
+ new Set(parsed.filter((key) => typeof key === "string" && key.length > 0))
189
+ ) : [];
190
+ } catch {
191
+ return [];
192
+ }
193
+ }
194
+ __name(decodeFarmCacheInvalidations, "decodeFarmCacheInvalidations");
195
+
173
196
  // src/i18n/bridge.ts
174
197
  var FARM_I18N_SNAPSHOT_RESOLVER = /* @__PURE__ */ Symbol.for("farm.i18n.snapshotResolver");
175
198
  function _setFarmI18nSnapshotResolver(resolver) {
@@ -179,11 +202,51 @@ __name(_setFarmI18nSnapshotResolver, "_setFarmI18nSnapshotResolver");
179
202
 
180
203
  // src/cache.ts
181
204
  var _FarmDataCache = class _FarmDataCache {
182
- constructor() {
205
+ constructor(config = {}) {
183
206
  this.entries = /* @__PURE__ */ new Map();
184
207
  this.inflight = /* @__PURE__ */ new Map();
185
208
  this.invalidatedTagVersions = /* @__PURE__ */ new Map();
186
209
  this.version = 0;
210
+ this.namespace = "farm";
211
+ this.local = true;
212
+ this.lease = {
213
+ enabled: true,
214
+ ttlMs: 1e4,
215
+ waitTimeoutMs: 1e4,
216
+ pollIntervalMs: 25
217
+ };
218
+ this.configure(config);
219
+ }
220
+ configure(config = {}) {
221
+ this.adapter = config.adapter;
222
+ this.namespace = normalizeCacheNamespace(config.namespace || "farm");
223
+ this.local = !config.adapter;
224
+ this.lease = config.lease === false ? { ...this.lease, enabled: false } : {
225
+ enabled: true,
226
+ ttlMs: normalizePositiveDuration(config.lease?.ttlMs, 1e4, "cache.lease.ttlMs"),
227
+ waitTimeoutMs: normalizePositiveDuration(
228
+ config.lease?.waitTimeoutMs,
229
+ 1e4,
230
+ "cache.lease.waitTimeoutMs"
231
+ ),
232
+ pollIntervalMs: normalizePositiveDuration(
233
+ config.lease?.pollIntervalMs,
234
+ 25,
235
+ "cache.lease.pollIntervalMs"
236
+ )
237
+ };
238
+ if (!this.local) {
239
+ this.entries.clear();
240
+ this.inflight.clear();
241
+ this.invalidatedTagVersions.clear();
242
+ this.version = 0;
243
+ }
244
+ }
245
+ get adapterName() {
246
+ return this.adapter?.name || (this.adapter ? "custom" : "memory");
247
+ }
248
+ get hasAdapter() {
249
+ return this.adapter !== void 0;
187
250
  }
188
251
  get size() {
189
252
  return this.entries.size;
@@ -219,6 +282,45 @@ var _FarmDataCache = class _FarmDataCache {
219
282
  });
220
283
  return this.toPublicEntry(entry);
221
284
  }
285
+ async getEntryAsync(key, options = {}) {
286
+ if (this.local) {
287
+ const localEntry = this.getEntry(key, options);
288
+ if (localEntry) return localEntry;
289
+ }
290
+ if (!this.adapter) {
291
+ return this.local ? void 0 : this.getEntry(key, options);
292
+ }
293
+ const entry = await this.adapter.get(this.createAdapterKey(key));
294
+ if (!entry) {
295
+ emitFarmEvent({ type: "cache.miss", key });
296
+ return void 0;
297
+ }
298
+ assertFarmCacheEntry(entry, key);
299
+ const stale = await this.isAdapterEntryStale(entry, options.now);
300
+ if (stale) {
301
+ emitFarmEvent({
302
+ type: "cache.stale",
303
+ key,
304
+ tags: [...entry.tags],
305
+ revalidate: entry.revalidate
306
+ });
307
+ if (!options.allowStale) {
308
+ emitFarmEvent({ type: "cache.miss", key, reason: "stale" });
309
+ return void 0;
310
+ }
311
+ }
312
+ emitFarmEvent({
313
+ type: "cache.hit",
314
+ key,
315
+ tags: [...entry.tags],
316
+ revalidate: entry.revalidate,
317
+ stale
318
+ });
319
+ if (this.local && !stale) {
320
+ this.hydrateLocalEntry(entry);
321
+ }
322
+ return { ...entry, key };
323
+ }
222
324
  set(key, value, options = {}) {
223
325
  const tags = /* @__PURE__ */ new Set();
224
326
  for (const tag of options.tags ?? []) {
@@ -231,6 +333,7 @@ var _FarmDataCache = class _FarmDataCache {
231
333
  key,
232
334
  value,
233
335
  tags,
336
+ tagVersions: void 0,
234
337
  createdAt: options.createdAt ?? Date.now(),
235
338
  createdVersion: ++this.version,
236
339
  revalidate: normalizeRevalidate(options.revalidate)
@@ -244,11 +347,45 @@ var _FarmDataCache = class _FarmDataCache {
244
347
  });
245
348
  return this.toPublicEntry(entry);
246
349
  }
350
+ async setAsync(key, value, options = {}, tagVersions) {
351
+ const tags = normalizeCacheOptionsTags(options);
352
+ const capturedVersions = tagVersions ?? await this.getAdapterTagVersions(Array.from(tags.values()));
353
+ const entry = {
354
+ key,
355
+ value,
356
+ tags: Array.from(tags),
357
+ tagVersions: capturedVersions,
358
+ createdAt: options.createdAt ?? Date.now(),
359
+ createdVersion: ++this.version,
360
+ revalidate: normalizeRevalidate(options.revalidate)
361
+ };
362
+ if (this.local) {
363
+ this.hydrateLocalEntry(entry);
364
+ }
365
+ if (this.adapter) {
366
+ await this.adapter.set(this.createAdapterKey(key), entry);
367
+ }
368
+ emitFarmEvent({
369
+ type: "cache.set",
370
+ key,
371
+ tags: [...entry.tags],
372
+ revalidate: entry.revalidate
373
+ });
374
+ return entry;
375
+ }
247
376
  delete(key) {
248
377
  const deleted = this.entries.delete(key);
249
378
  emitFarmEvent({ type: "cache.delete", key, deleted });
250
379
  return deleted;
251
380
  }
381
+ async deleteAsync(key) {
382
+ const deleted = this.entries.delete(key);
383
+ if (this.adapter) {
384
+ await this.adapter.delete(this.createAdapterKey(key));
385
+ }
386
+ emitFarmEvent({ type: "cache.delete", key, deleted: this.adapter ? true : deleted });
387
+ return this.adapter ? true : deleted;
388
+ }
252
389
  clear() {
253
390
  const count = this.entries.size;
254
391
  this.entries.clear();
@@ -257,6 +394,10 @@ var _FarmDataCache = class _FarmDataCache {
257
394
  this.version = 0;
258
395
  emitFarmEvent({ type: "cache.clear", count });
259
396
  }
397
+ async clearAsync() {
398
+ this.clear();
399
+ await this.adapter?.clear?.();
400
+ }
260
401
  isStale(entry, now = Date.now()) {
261
402
  if (typeof entry.revalidate === "number" && entry.revalidate > 0 && now - entry.createdAt >= entry.revalidate * 1e3) {
262
403
  return true;
@@ -269,6 +410,12 @@ var _FarmDataCache = class _FarmDataCache {
269
410
  }
270
411
  return false;
271
412
  }
413
+ async isStaleAsync(entry, now = Date.now()) {
414
+ if (this.adapter) {
415
+ return this.isAdapterEntryStale(entry, now);
416
+ }
417
+ return this.isStale(entry, now);
418
+ }
272
419
  revalidateTag(tag, options = {}) {
273
420
  const normalized = normalizeCacheTag(tag);
274
421
  const count = this.invalidateTag(normalized);
@@ -277,6 +424,15 @@ var _FarmDataCache = class _FarmDataCache {
277
424
  );
278
425
  return count;
279
426
  }
427
+ async revalidateTagAsync(tag, options = {}) {
428
+ const normalized = normalizeCacheTag(tag);
429
+ const count = this.invalidateTag(normalized);
430
+ await this.adapter?.invalidateTags?.([this.createAdapterTag(normalized)]);
431
+ emitFarmEvent(
432
+ options.source === "updateTag" ? { type: "cache.updateTag", tag: normalized, count } : { type: "cache.revalidateTag", tag: normalized, profile: options.profile, count }
433
+ );
434
+ return count;
435
+ }
280
436
  revalidatePath(routePath) {
281
437
  const normalizedPath = normalizeRevalidatePath(routePath);
282
438
  const pathTag = createPathCacheTag(normalizedPath);
@@ -293,8 +449,25 @@ var _FarmDataCache = class _FarmDataCache {
293
449
  }
294
450
  return count;
295
451
  }
452
+ async revalidatePathAsync(routePath) {
453
+ const normalizedPath = normalizeRevalidatePath(routePath);
454
+ const pathTag = createPathCacheTag(normalizedPath);
455
+ const pprCount = this.countEntriesForTags([pathTag, "ppr"]);
456
+ const count = this.invalidateTag(pathTag);
457
+ await this.adapter?.invalidateTags?.([this.createAdapterTag(pathTag)]);
458
+ emitFarmEvent({ type: "cache.revalidatePath", path: normalizedPath, count });
459
+ if (pprCount > 0) {
460
+ emitFarmEvent({
461
+ type: "ppr.shell.invalidated",
462
+ route: normalizedPath,
463
+ reason: "revalidatePath",
464
+ count: pprCount
465
+ });
466
+ }
467
+ return count;
468
+ }
296
469
  async getOrSet(key, producer, options = {}) {
297
- const cached = this.getEntry(key);
470
+ const cached = await this.getEntryAsync(key);
298
471
  if (cached) {
299
472
  return cached.value;
300
473
  }
@@ -303,10 +476,8 @@ var _FarmDataCache = class _FarmDataCache {
303
476
  emitFarmEvent({ type: "cache.dedupe", key });
304
477
  return inflight;
305
478
  }
306
- const promise = Promise.resolve().then(producer).then((value) => {
307
- this.set(key, value, options);
308
- return value;
309
- }).catch((error) => {
479
+ const tags = Array.from(normalizeCacheOptionsTags(options));
480
+ const promise = this.fillCacheEntry(key, producer, options, tags).catch((error) => {
310
481
  emitFarmEvent({ type: "cache.error", key, operation: "set", error });
311
482
  throw error;
312
483
  }).finally(() => {
@@ -315,6 +486,40 @@ var _FarmDataCache = class _FarmDataCache {
315
486
  this.inflight.set(key, promise);
316
487
  return promise;
317
488
  }
489
+ async fillCacheEntry(key, producer, options, tags) {
490
+ const leaseKey = `${this.namespace}:lease:${key}`;
491
+ let leaseToken;
492
+ if (this.adapter?.acquireLease && this.adapter.releaseLease && this.lease.enabled) {
493
+ leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);
494
+ if (!leaseToken) {
495
+ const shared = await this.waitForAdapterEntry(key);
496
+ if (shared) {
497
+ emitFarmEvent({ type: "cache.dedupe", key });
498
+ return shared.value;
499
+ }
500
+ leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);
501
+ }
502
+ }
503
+ try {
504
+ const initialTagVersions = await this.getAdapterTagVersions(tags);
505
+ const value = await producer();
506
+ await this.setAsync(key, value, options, initialTagVersions);
507
+ return value;
508
+ } finally {
509
+ if (leaseToken && this.adapter?.releaseLease) {
510
+ await this.adapter.releaseLease(leaseKey, leaseToken);
511
+ }
512
+ }
513
+ }
514
+ async waitForAdapterEntry(key) {
515
+ const deadline = Date.now() + this.lease.waitTimeoutMs;
516
+ while (Date.now() < deadline) {
517
+ await delay(this.lease.pollIntervalMs);
518
+ const entry = await this.getEntryAsync(key);
519
+ if (entry) return entry;
520
+ }
521
+ return void 0;
522
+ }
318
523
  countEntriesForTag(tag) {
319
524
  let count = 0;
320
525
  for (const entry of this.entries.values()) {
@@ -342,11 +547,53 @@ var _FarmDataCache = class _FarmDataCache {
342
547
  key: entry.key,
343
548
  value: entry.value,
344
549
  tags: Array.from(entry.tags),
550
+ tagVersions: entry.tagVersions,
345
551
  createdAt: entry.createdAt,
346
552
  createdVersion: entry.createdVersion,
347
553
  revalidate: entry.revalidate
348
554
  };
349
555
  }
556
+ hydrateLocalEntry(entry) {
557
+ this.entries.set(entry.key, {
558
+ key: entry.key,
559
+ value: entry.value,
560
+ tags: new Set(entry.tags.map(normalizeCacheTag)),
561
+ tagVersions: entry.tagVersions,
562
+ createdAt: entry.createdAt,
563
+ createdVersion: entry.createdVersion ?? ++this.version,
564
+ revalidate: normalizeRevalidate(entry.revalidate)
565
+ });
566
+ }
567
+ createAdapterKey(key) {
568
+ return `${this.namespace}:entry:${key}`;
569
+ }
570
+ createAdapterTag(tag) {
571
+ return `${this.namespace}:tag:${tag}`;
572
+ }
573
+ async getAdapterTagVersions(tags) {
574
+ if (!this.adapter?.getTagVersions || tags.length === 0) return {};
575
+ const normalized = tags.map(normalizeCacheTag);
576
+ const physicalTags = normalized.map((tag) => this.createAdapterTag(tag));
577
+ const versions = await this.adapter.getTagVersions(physicalTags);
578
+ return Object.fromEntries(
579
+ normalized.map((tag, index) => [
580
+ tag,
581
+ normalizeAdapterVersion(versions[physicalTags[index]])
582
+ ])
583
+ );
584
+ }
585
+ async isAdapterEntryStale(entry, now = Date.now()) {
586
+ if (typeof entry.revalidate === "number" && entry.revalidate > 0 && now - entry.createdAt >= entry.revalidate * 1e3) {
587
+ return true;
588
+ }
589
+ const currentVersions = await this.getAdapterTagVersions(entry.tags);
590
+ for (const tag of entry.tags) {
591
+ if (normalizeAdapterVersion(currentVersions[tag]) > normalizeAdapterVersion(entry.tagVersions?.[tag])) {
592
+ return true;
593
+ }
594
+ }
595
+ return false;
596
+ }
350
597
  };
351
598
  __name(_FarmDataCache, "FarmDataCache");
352
599
  var FarmDataCache = _FarmDataCache;
@@ -401,6 +648,52 @@ function normalizeCacheTag(tag) {
401
648
  return normalized;
402
649
  }
403
650
  __name(normalizeCacheTag, "normalizeCacheTag");
651
+ function normalizeCacheNamespace(namespace) {
652
+ if (typeof namespace !== "string") {
653
+ throw new TypeError("Cache namespace must be a string.");
654
+ }
655
+ const normalized = namespace.trim().replace(/:+$/g, "");
656
+ if (!normalized) {
657
+ throw new Error("Cache namespace cannot be empty.");
658
+ }
659
+ return normalized;
660
+ }
661
+ __name(normalizeCacheNamespace, "normalizeCacheNamespace");
662
+ function normalizeAdapterVersion(value) {
663
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
664
+ }
665
+ __name(normalizeAdapterVersion, "normalizeAdapterVersion");
666
+ function normalizePositiveDuration(value, fallback, name) {
667
+ if (value === void 0) return fallback;
668
+ if (!Number.isFinite(value) || value <= 0) {
669
+ throw new TypeError(`${name} must be a positive number of milliseconds.`);
670
+ }
671
+ return Math.floor(value);
672
+ }
673
+ __name(normalizePositiveDuration, "normalizePositiveDuration");
674
+ function delay(ms) {
675
+ return new Promise((resolve) => setTimeout(resolve, ms));
676
+ }
677
+ __name(delay, "delay");
678
+ function normalizeCacheOptionsTags(options) {
679
+ const tags = /* @__PURE__ */ new Set();
680
+ for (const tag of options.tags ?? []) {
681
+ tags.add(normalizeCacheTag(tag));
682
+ }
683
+ for (const routePath of options.paths ?? []) {
684
+ tags.add(createPathCacheTag(routePath));
685
+ }
686
+ return tags;
687
+ }
688
+ __name(normalizeCacheOptionsTags, "normalizeCacheOptionsTags");
689
+ function assertFarmCacheEntry(entry, expectedKey) {
690
+ if (!entry || typeof entry !== "object" || entry.key !== expectedKey || !Array.isArray(entry.tags) || typeof entry.createdAt !== "number") {
691
+ throw new TypeError(
692
+ `Cache adapter returned an invalid entry for ${JSON.stringify(expectedKey)}.`
693
+ );
694
+ }
695
+ }
696
+ __name(assertFarmCacheEntry, "assertFarmCacheEntry");
404
697
 
405
698
  // src/route-runtime.ts
406
699
  function normalizeFarmRouteRuntimeConfig(value, source = "Route configuration") {
@@ -725,6 +1018,26 @@ async function _runWithCurrentRequest(request, fn) {
725
1018
  }
726
1019
  __name(_runWithCurrentRequest, "_runWithCurrentRequest");
727
1020
 
1021
+ // src/api/endpoint.ts
1022
+ var import_better_call = require("better-call");
1023
+ var _EndpointFailure = class _EndpointFailure extends Error {
1024
+ constructor(code, data, options) {
1025
+ super(options.message);
1026
+ this.name = "EndpointFailure";
1027
+ this.code = code;
1028
+ this.data = data;
1029
+ this.status = options.status;
1030
+ }
1031
+ };
1032
+ __name(_EndpointFailure, "EndpointFailure");
1033
+ var EndpointFailure = _EndpointFailure;
1034
+ function isEndpointFailure(value) {
1035
+ return value instanceof EndpointFailure;
1036
+ }
1037
+ __name(isEndpointFailure, "isEndpointFailure");
1038
+ var EMPTY_ENDPOINT_MIDDLEWARE = Object.freeze([]);
1039
+ var EMPTY_ENDPOINT_CONTEXT = Object.freeze(/* @__PURE__ */ Object.create(null));
1040
+
728
1041
  // src/api/runtime.ts
729
1042
  function matchAPIRoute(routes, pathname) {
730
1043
  const exactRoute = routes.get(pathname);
@@ -757,10 +1070,10 @@ __name(invokeAPIRouteEndpoint, "invokeAPIRouteEndpoint");
757
1070
  async function invokeAPIRouteEndpointInContext(endpoint, request, params) {
758
1071
  const farmHandler = endpoint.__handler || (isFarmContextHandler(endpoint) ? endpoint : null);
759
1072
  if (!farmHandler) {
760
- const result2 = await endpoint(request, {
1073
+ const result = await endpoint(request, {
761
1074
  params: Promise.resolve(params)
762
1075
  });
763
- return normalizeRouteResponse(result2);
1076
+ return normalizeRouteResponse(result);
764
1077
  }
765
1078
  const url = new URL(request.url);
766
1079
  const query = {};
@@ -769,7 +1082,7 @@ async function invokeAPIRouteEndpointInContext(endpoint, request, params) {
769
1082
  });
770
1083
  let body = void 0;
771
1084
  if (request.method.toUpperCase() !== "GET" && request.method.toUpperCase() !== "HEAD") {
772
- body = await readJSONBody(request);
1085
+ body = await readRequestBody(request);
773
1086
  }
774
1087
  const headers = Object.fromEntries(request.headers.entries());
775
1088
  const types = endpoint.__types || {};
@@ -785,15 +1098,30 @@ async function invokeAPIRouteEndpointInContext(endpoint, request, params) {
785
1098
  if (headersValidation instanceof Response) {
786
1099
  return headersValidation;
787
1100
  }
788
- const result = await farmHandler({
1101
+ const handlerContext = {
789
1102
  query: queryValidation,
790
1103
  body: bodyValidation,
791
1104
  headers: headersValidation,
792
1105
  request,
793
1106
  context: {},
794
1107
  params
795
- });
796
- return normalizeRouteResponse(result);
1108
+ };
1109
+ let execution;
1110
+ try {
1111
+ execution = typeof endpoint.__farmInvoke === "function" ? await endpoint.__farmInvoke(handlerContext) : {
1112
+ result: await farmHandler(handlerContext),
1113
+ context: handlerContext.context,
1114
+ handlerExecuted: true,
1115
+ invalidations: []
1116
+ };
1117
+ } catch (error) {
1118
+ if (isEndpointFailure(error)) {
1119
+ return createEndpointFailureResponse(error);
1120
+ }
1121
+ throw error;
1122
+ }
1123
+ const response = normalizeRouteResponse(execution.result);
1124
+ return attachEndpointInvalidations(response, execution.invalidations);
797
1125
  }
798
1126
  __name(invokeAPIRouteEndpointInContext, "invokeAPIRouteEndpointInContext");
799
1127
  function normalizeRouteResponse(result) {
@@ -813,6 +1141,40 @@ function isWebResponse(value) {
813
1141
  return value instanceof Response || typeof value === "object" && value !== null && "headers" in value && "status" in value && typeof value.arrayBuffer === "function";
814
1142
  }
815
1143
  __name(isWebResponse, "isWebResponse");
1144
+ function attachEndpointInvalidations(response, keys) {
1145
+ const existing = decodeFarmCacheInvalidations(
1146
+ response.headers.get(FARM_CACHE_INVALIDATION_HEADER)
1147
+ );
1148
+ const encoded = encodeFarmCacheInvalidations([...existing, ...keys]);
1149
+ if (!encoded) return response;
1150
+ const headers = new Headers(response.headers);
1151
+ headers.set(FARM_CACHE_INVALIDATION_HEADER, encoded);
1152
+ return new Response(response.body, {
1153
+ status: response.status,
1154
+ statusText: response.statusText,
1155
+ headers
1156
+ });
1157
+ }
1158
+ __name(attachEndpointInvalidations, "attachEndpointInvalidations");
1159
+ function createEndpointFailureResponse(failure) {
1160
+ return new Response(
1161
+ JSON.stringify({
1162
+ error: {
1163
+ code: failure.code,
1164
+ message: failure.message,
1165
+ data: failure.data
1166
+ }
1167
+ }),
1168
+ {
1169
+ status: failure.status,
1170
+ headers: {
1171
+ "cache-control": "no-store",
1172
+ "content-type": "application/json"
1173
+ }
1174
+ }
1175
+ );
1176
+ }
1177
+ __name(createEndpointFailureResponse, "createEndpointFailureResponse");
816
1178
  function isFarmContextHandler(endpoint) {
817
1179
  if (typeof endpoint !== "function") {
818
1180
  return false;
@@ -824,17 +1186,50 @@ function isFarmContextHandler(endpoint) {
824
1186
  return firstParameter === "ctx" || firstParameter === "context" || firstParameter.startsWith("{");
825
1187
  }
826
1188
  __name(isFarmContextHandler, "isFarmContextHandler");
827
- async function readJSONBody(request) {
1189
+ async function readRequestBody(request) {
1190
+ const contentType = request.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
828
1191
  try {
1192
+ if (contentType === "multipart/form-data") {
1193
+ return formDataToObject(await request.clone().formData());
1194
+ }
829
1195
  const text = await request.clone().text();
830
- if (text) {
1196
+ if (!text) return void 0;
1197
+ if (contentType === "application/x-www-form-urlencoded") {
1198
+ return searchParamsToObject(new URLSearchParams(text));
1199
+ }
1200
+ if (contentType === "application/json" || contentType?.endsWith("+json")) {
831
1201
  return JSON.parse(text);
832
1202
  }
1203
+ return JSON.parse(text);
833
1204
  } catch {
834
1205
  }
835
1206
  return void 0;
836
1207
  }
837
- __name(readJSONBody, "readJSONBody");
1208
+ __name(readRequestBody, "readRequestBody");
1209
+ function formDataToObject(formData) {
1210
+ return entriesToObject(formData.entries());
1211
+ }
1212
+ __name(formDataToObject, "formDataToObject");
1213
+ function searchParamsToObject(searchParams) {
1214
+ return entriesToObject(searchParams.entries());
1215
+ }
1216
+ __name(searchParamsToObject, "searchParamsToObject");
1217
+ function entriesToObject(entries) {
1218
+ const output = /* @__PURE__ */ Object.create(null);
1219
+ for (const [key, value] of entries) {
1220
+ if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
1221
+ const current = output[key];
1222
+ if (current === void 0) {
1223
+ output[key] = value;
1224
+ } else if (Array.isArray(current)) {
1225
+ current.push(value);
1226
+ } else {
1227
+ output[key] = [current, value];
1228
+ }
1229
+ }
1230
+ return output;
1231
+ }
1232
+ __name(entriesToObject, "entriesToObject");
838
1233
  function validateInput(schema, value, error) {
839
1234
  if (!schema || typeof schema.parse !== "function") {
840
1235
  return value;