@farm.js/core 0.1.0-beta.3 → 0.1.0-beta.5

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 (193) hide show
  1. package/dist/agent-runtime.d.mts +2 -1
  2. package/dist/agent-runtime.d.ts +2 -1
  3. package/dist/api/route-manager.cjs +313 -10
  4. package/dist/api/route-manager.cjs.map +1 -1
  5. package/dist/api/route-manager.d.mts +3 -2
  6. package/dist/api/route-manager.d.ts +3 -2
  7. package/dist/api/route-manager.mjs +6 -5
  8. package/dist/api/runtime.cjs +313 -10
  9. package/dist/api/runtime.cjs.map +1 -1
  10. package/dist/api/runtime.d.mts +2 -1
  11. package/dist/api/runtime.d.ts +2 -1
  12. package/dist/api/runtime.mjs +4 -3
  13. package/dist/api.cjs +642 -57
  14. package/dist/api.cjs.map +1 -1
  15. package/dist/api.d.mts +3 -2
  16. package/dist/api.d.ts +3 -2
  17. package/dist/api.mjs +29 -9
  18. package/dist/{app-DOKxo-LH.d.ts → app-BjN-da13.d.ts} +38 -3
  19. package/dist/{app-BB3Iu3xh.d.mts → app-CakAr8Be.d.mts} +38 -3
  20. package/dist/app-markdown.d.mts +2 -1
  21. package/dist/app-markdown.d.ts +2 -1
  22. package/dist/cache.cjs +395 -12
  23. package/dist/cache.cjs.map +1 -1
  24. package/dist/cache.d.mts +100 -6
  25. package/dist/cache.d.ts +100 -6
  26. package/dist/cache.mjs +8 -2
  27. package/dist/{chunk-XUBZ7JI4.mjs → chunk-2CUKEMVR.mjs} +187 -16
  28. package/dist/chunk-2CUKEMVR.mjs.map +1 -0
  29. package/dist/{chunk-OHC6VCDI.mjs → chunk-2NHCNRF6.mjs} +521 -42
  30. package/dist/chunk-2NHCNRF6.mjs.map +1 -0
  31. package/dist/{chunk-6WXJ54TC.mjs → chunk-65A7QIKI.mjs} +5 -5
  32. package/dist/{chunk-6WXJ54TC.mjs.map → chunk-65A7QIKI.mjs.map} +1 -1
  33. package/dist/{chunk-5QH4IKY3.mjs → chunk-7N62DNSO.mjs} +2 -2
  34. package/dist/{chunk-XJSHJN4M.mjs → chunk-A2LUXHD2.mjs} +593 -49
  35. package/dist/chunk-A2LUXHD2.mjs.map +1 -0
  36. package/dist/chunk-ALCLXXTY.mjs +187 -0
  37. package/dist/chunk-ALCLXXTY.mjs.map +1 -0
  38. package/dist/{chunk-CSU4KJJF.mjs → chunk-C2ROET2V.mjs} +2 -2
  39. package/dist/{chunk-JNYVN7YP.mjs → chunk-EEABSBKK.mjs} +2 -2
  40. package/dist/{chunk-JNYVN7YP.mjs.map → chunk-EEABSBKK.mjs.map} +1 -1
  41. package/dist/{chunk-BIOIOWXZ.mjs → chunk-HNIQFZKB.mjs} +2 -2
  42. package/dist/{chunk-MH6FKW2I.mjs → chunk-J5YWQVI5.mjs} +4 -4
  43. package/dist/chunk-J5YWQVI5.mjs.map +1 -0
  44. package/dist/{chunk-G5I34UA6.mjs → chunk-JDEOUK5V.mjs} +4 -4
  45. package/dist/{chunk-T543TMFY.mjs → chunk-NM3CRAAL.mjs} +3 -2
  46. package/dist/chunk-NM3CRAAL.mjs.map +1 -0
  47. package/dist/{chunk-LWMGIEJA.mjs → chunk-PFE6GMNE.mjs} +47 -37
  48. package/dist/chunk-PFE6GMNE.mjs.map +1 -0
  49. package/dist/{chunk-6VS6CKAV.mjs → chunk-QM746KUO.mjs} +8 -1
  50. package/dist/chunk-QM746KUO.mjs.map +1 -0
  51. package/dist/{chunk-5FW6PQ3J.mjs → chunk-QTZZ2ISQ.mjs} +41 -16
  52. package/dist/chunk-QTZZ2ISQ.mjs.map +1 -0
  53. package/dist/{chunk-SHRJG6OG.mjs → chunk-RBRLLZL5.mjs} +18 -3
  54. package/dist/chunk-RBRLLZL5.mjs.map +1 -0
  55. package/dist/{chunk-NRRFGX45.mjs → chunk-TQAEEJB4.mjs} +3 -3
  56. package/dist/{chunk-45LKHSHJ.mjs → chunk-UB5UOSHB.mjs} +24 -12
  57. package/dist/chunk-UB5UOSHB.mjs.map +1 -0
  58. package/dist/chunk-V3XURYJO.mjs +756 -0
  59. package/dist/chunk-V3XURYJO.mjs.map +1 -0
  60. package/dist/{chunk-HZYXGV4K.mjs → chunk-VY2UYN5R.mjs} +24 -4
  61. package/dist/chunk-VY2UYN5R.mjs.map +1 -0
  62. package/dist/{chunk-C33RALN7.mjs → chunk-W2CRQFF6.mjs} +79 -15
  63. package/dist/chunk-W2CRQFF6.mjs.map +1 -0
  64. package/dist/{chunk-LG3YINQN.mjs → chunk-Z5CQMP54.mjs} +3 -3
  65. package/dist/{client-DiViK9yK.d.mts → client-BT1mFQas.d.mts} +23 -4
  66. package/dist/{client-DpEBJbts.d.ts → client-Nn0q4eO4.d.ts} +23 -4
  67. package/dist/{client-plugins-CTnsZz_A.d.ts → client-plugins-Cw4qUGsw.d.ts} +6 -0
  68. package/dist/{client-plugins-Cnr0D3kk.d.mts → client-plugins-DQQ1adXM.d.mts} +6 -0
  69. package/dist/client-plugins.d.mts +2 -1
  70. package/dist/client-plugins.d.ts +2 -1
  71. package/dist/client.cjs +665 -82
  72. package/dist/client.cjs.map +1 -1
  73. package/dist/client.d.mts +71 -5
  74. package/dist/client.d.ts +71 -5
  75. package/dist/client.mjs +10 -7
  76. package/dist/config.d.mts +2 -1
  77. package/dist/config.d.ts +2 -1
  78. package/dist/{devtools-HE4FTUDN.mjs → devtools-LVC3VB5P.mjs} +4 -4
  79. package/dist/docs.cjs +11 -1
  80. package/dist/docs.cjs.map +1 -1
  81. package/dist/docs.mjs +4 -4
  82. package/dist/index.cjs +2113 -198
  83. package/dist/index.cjs.map +1 -1
  84. package/dist/index.d.mts +16 -16
  85. package/dist/index.d.ts +16 -16
  86. package/dist/index.mjs +49 -21
  87. package/dist/index.mjs.map +1 -1
  88. package/dist/integrations.d.mts +2 -1
  89. package/dist/integrations.d.ts +2 -1
  90. package/dist/internal/build-runtime.cjs +1455 -90
  91. package/dist/internal/build-runtime.cjs.map +1 -1
  92. package/dist/internal/build-runtime.d.mts +4 -3
  93. package/dist/internal/build-runtime.d.ts +4 -3
  94. package/dist/internal/build-runtime.mjs +15 -14
  95. package/dist/internal/config-runtime.cjs +12 -1
  96. package/dist/internal/config-runtime.cjs.map +1 -1
  97. package/dist/internal/config-runtime.d.mts +3 -2
  98. package/dist/internal/config-runtime.d.ts +3 -2
  99. package/dist/internal/config-runtime.mjs +3 -3
  100. package/dist/internal/production-runtime.cjs +282 -6
  101. package/dist/internal/production-runtime.cjs.map +1 -1
  102. package/dist/internal/production-runtime.d.mts +4 -4
  103. package/dist/internal/production-runtime.d.ts +4 -4
  104. package/dist/internal/production-runtime.mjs +4 -2
  105. package/dist/{metadata-eoVmHoyv.d.ts → metadata-BAPg_Nmo.d.ts} +1 -1
  106. package/dist/{metadata-Dp8AdvsB.d.mts → metadata-_6i9oFG3.d.mts} +1 -1
  107. package/dist/middleware.d.mts +4 -3
  108. package/dist/middleware.d.ts +4 -3
  109. package/dist/navigation.cjs +40 -15
  110. package/dist/navigation.cjs.map +1 -1
  111. package/dist/navigation.mjs +2 -2
  112. package/dist/plugin.cjs +913 -53
  113. package/dist/plugin.cjs.map +1 -1
  114. package/dist/plugin.d.mts +2 -1
  115. package/dist/plugin.d.ts +2 -1
  116. package/dist/plugin.mjs +11 -10
  117. package/dist/{production-runtime-BqTnUTai.d.ts → production-runtime-BoJDc5mc.d.ts} +1 -1
  118. package/dist/{production-runtime-DtDdG9fc.d.mts → production-runtime-DPfgMV9Y.d.mts} +1 -1
  119. package/dist/routes.cjs +276 -6
  120. package/dist/routes.cjs.map +1 -1
  121. package/dist/routes.d.mts +1 -1
  122. package/dist/routes.d.ts +1 -1
  123. package/dist/routes.mjs +3 -3
  124. package/dist/{runtime-C1B7pSGT.d.mts → runtime-9nQjVM7X.d.mts} +8 -9
  125. package/dist/{runtime-CdPHt0bv.d.ts → runtime-DgeS2skB.d.ts} +8 -9
  126. package/dist/server-action-security.cjs +28 -10
  127. package/dist/server-action-security.cjs.map +1 -1
  128. package/dist/server-action-security.d.mts +2 -1
  129. package/dist/server-action-security.d.ts +2 -1
  130. package/dist/server-action-security.mjs +2 -2
  131. package/dist/server-fn-client.d.mts +1 -0
  132. package/dist/server-fn-client.d.ts +1 -0
  133. package/dist/server-fn.cjs +785 -3
  134. package/dist/server-fn.cjs.map +1 -1
  135. package/dist/server-fn.d.mts +10 -1
  136. package/dist/server-fn.d.ts +10 -1
  137. package/dist/server-fn.mjs +6 -3
  138. package/dist/server-plugins.d.mts +3 -2
  139. package/dist/server-plugins.d.ts +3 -2
  140. package/dist/server-query-client.cjs +279 -8
  141. package/dist/server-query-client.cjs.map +1 -1
  142. package/dist/server-query-client.mjs +4 -4
  143. package/dist/server-query.cjs +381 -10
  144. package/dist/server-query.cjs.map +1 -1
  145. package/dist/server-query.mjs +5 -5
  146. package/dist/server.cjs +1086 -76
  147. package/dist/server.cjs.map +1 -1
  148. package/dist/server.d.mts +8 -7
  149. package/dist/server.d.ts +8 -7
  150. package/dist/server.mjs +31 -16
  151. package/dist/server.mjs.map +1 -1
  152. package/dist/testing.cjs +341 -20
  153. package/dist/testing.cjs.map +1 -1
  154. package/dist/testing.d.mts +3 -2
  155. package/dist/testing.d.ts +3 -2
  156. package/dist/testing.mjs +7 -6
  157. package/dist/testing.mjs.map +1 -1
  158. package/dist/transport-BmbGTXA5.d.mts +49 -0
  159. package/dist/transport-BmbGTXA5.d.ts +49 -0
  160. package/dist/{utils-8USa5BiY.d.mts → utils-CHXlMDkg.d.mts} +1 -1
  161. package/dist/{utils-DKJb6K6G.d.ts → utils-Drsyz1Vj.d.ts} +1 -1
  162. package/dist/version.cjs +1 -1
  163. package/dist/version.cjs.map +1 -1
  164. package/dist/version.mjs +1 -1
  165. package/dist/vite.cjs +914 -54
  166. package/dist/vite.cjs.map +1 -1
  167. package/dist/vite.d.mts +2 -1
  168. package/dist/vite.d.ts +2 -1
  169. package/dist/vite.mjs +11 -10
  170. package/package.json +1 -1
  171. package/types/api.d.ts +44 -0
  172. package/types/client.d.ts +85 -4
  173. package/dist/chunk-45LKHSHJ.mjs.map +0 -1
  174. package/dist/chunk-5FW6PQ3J.mjs.map +0 -1
  175. package/dist/chunk-6VS6CKAV.mjs.map +0 -1
  176. package/dist/chunk-C33RALN7.mjs.map +0 -1
  177. package/dist/chunk-GZWT6VI5.mjs +0 -382
  178. package/dist/chunk-GZWT6VI5.mjs.map +0 -1
  179. package/dist/chunk-HZYXGV4K.mjs.map +0 -1
  180. package/dist/chunk-LWMGIEJA.mjs.map +0 -1
  181. package/dist/chunk-MH6FKW2I.mjs.map +0 -1
  182. package/dist/chunk-OHC6VCDI.mjs.map +0 -1
  183. package/dist/chunk-SHRJG6OG.mjs.map +0 -1
  184. package/dist/chunk-T543TMFY.mjs.map +0 -1
  185. package/dist/chunk-XJSHJN4M.mjs.map +0 -1
  186. package/dist/chunk-XUBZ7JI4.mjs.map +0 -1
  187. /package/dist/{chunk-5QH4IKY3.mjs.map → chunk-7N62DNSO.mjs.map} +0 -0
  188. /package/dist/{chunk-CSU4KJJF.mjs.map → chunk-C2ROET2V.mjs.map} +0 -0
  189. /package/dist/{chunk-BIOIOWXZ.mjs.map → chunk-HNIQFZKB.mjs.map} +0 -0
  190. /package/dist/{chunk-G5I34UA6.mjs.map → chunk-JDEOUK5V.mjs.map} +0 -0
  191. /package/dist/{chunk-NRRFGX45.mjs.map → chunk-TQAEEJB4.mjs.map} +0 -0
  192. /package/dist/{chunk-LG3YINQN.mjs.map → chunk-Z5CQMP54.mjs.map} +0 -0
  193. /package/dist/{devtools-HE4FTUDN.mjs.map → devtools-LVC3VB5P.mjs.map} +0 -0
@@ -2,10 +2,11 @@ import { ViteDevServer } from 'vite';
2
2
  import { F as FarmRouteRuntimeConfig } from '../route-runtime-DoOHzCAD.mjs';
3
3
  import '../types-BH1lhg5G.mjs';
4
4
  import { F as FarmI18nRuntime } from '../runtime-DeAAZ6gO.mjs';
5
- import { A as APIRouteMatch } from '../runtime-C1B7pSGT.mjs';
6
- export { c as APIRouteParamValue, b as APIRouteParams, i as invokeAPIRouteEndpoint, a as isWebResponse, m as matchAPIRoute, n as normalizeRouteResponse } from '../runtime-C1B7pSGT.mjs';
5
+ import { A as APIRouteMatch } from '../runtime-9nQjVM7X.mjs';
6
+ export { c as APIRouteParamValue, b as APIRouteParams, i as invokeAPIRouteEndpoint, a as isWebResponse, m as matchAPIRoute, n as normalizeRouteResponse } from '../runtime-9nQjVM7X.mjs';
7
7
  import '../resolver-DlOPpjkB.mjs';
8
8
  import '../cache.mjs';
9
+ import '../transport-BmbGTXA5.mjs';
9
10
 
10
11
  interface APIRoute extends FarmRouteRuntimeConfig {
11
12
  path: string;
@@ -2,10 +2,11 @@ import { ViteDevServer } from 'vite';
2
2
  import { F as FarmRouteRuntimeConfig } from '../route-runtime-DoOHzCAD.js';
3
3
  import '../types-BH1lhg5G.js';
4
4
  import { F as FarmI18nRuntime } from '../runtime-B6GvwDS1.js';
5
- import { A as APIRouteMatch } from '../runtime-CdPHt0bv.js';
6
- export { c as APIRouteParamValue, b as APIRouteParams, i as invokeAPIRouteEndpoint, a as isWebResponse, m as matchAPIRoute, n as normalizeRouteResponse } from '../runtime-CdPHt0bv.js';
5
+ import { A as APIRouteMatch } from '../runtime-DgeS2skB.js';
6
+ export { c as APIRouteParamValue, b as APIRouteParams, i as invokeAPIRouteEndpoint, a as isWebResponse, m as matchAPIRoute, n as normalizeRouteResponse } from '../runtime-DgeS2skB.js';
7
7
  import '../resolver-C6iecsDV.js';
8
8
  import '../cache.js';
9
+ import '../transport-BmbGTXA5.js';
9
10
 
10
11
  interface APIRoute extends FarmRouteRuntimeConfig {
11
12
  path: string;
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  APIRouteManager,
3
3
  API_ROUTE_METHODS
4
- } from "../chunk-LG3YINQN.mjs";
4
+ } from "../chunk-Z5CQMP54.mjs";
5
5
  import "../chunk-2ED5Q2GH.mjs";
6
6
  import "../chunk-GN72QAIH.mjs";
7
7
  import "../chunk-FQYDHKKU.mjs";
8
- import "../chunk-CSU4KJJF.mjs";
8
+ import "../chunk-C2ROET2V.mjs";
9
9
  import "../chunk-QKVUNGAH.mjs";
10
10
  import "../chunk-GQVGIUSN.mjs";
11
11
  import "../chunk-J4FNJ5IU.mjs";
@@ -14,13 +14,14 @@ import {
14
14
  isWebResponse,
15
15
  matchAPIRoute,
16
16
  normalizeRouteResponse
17
- } from "../chunk-LWMGIEJA.mjs";
17
+ } from "../chunk-PFE6GMNE.mjs";
18
18
  import "../chunk-RHIFZZUI.mjs";
19
19
  import "../chunk-LM2YNO4U.mjs";
20
20
  import "../chunk-44ZCFSKE.mjs";
21
- import "../chunk-GZWT6VI5.mjs";
21
+ import "../chunk-ALCLXXTY.mjs";
22
+ import "../chunk-V3XURYJO.mjs";
22
23
  import "../chunk-WZ5QFROO.mjs";
23
- import "../chunk-SHRJG6OG.mjs";
24
+ import "../chunk-RBRLLZL5.mjs";
24
25
  import "../chunk-7ZY5AIJO.mjs";
25
26
  import "../chunk-CGILA3WO.mjs";
26
27
  export {
@@ -206,11 +206,51 @@ __name(formatError, "formatError");
206
206
 
207
207
  // src/cache.ts
208
208
  var _FarmDataCache = class _FarmDataCache {
209
- constructor() {
209
+ constructor(config = {}) {
210
210
  this.entries = /* @__PURE__ */ new Map();
211
211
  this.inflight = /* @__PURE__ */ new Map();
212
212
  this.invalidatedTagVersions = /* @__PURE__ */ new Map();
213
213
  this.version = 0;
214
+ this.namespace = "farm";
215
+ this.local = true;
216
+ this.lease = {
217
+ enabled: true,
218
+ ttlMs: 1e4,
219
+ waitTimeoutMs: 1e4,
220
+ pollIntervalMs: 25
221
+ };
222
+ this.configure(config);
223
+ }
224
+ configure(config = {}) {
225
+ this.adapter = config.adapter;
226
+ this.namespace = normalizeCacheNamespace(config.namespace || "farm");
227
+ this.local = !config.adapter;
228
+ this.lease = config.lease === false ? { ...this.lease, enabled: false } : {
229
+ enabled: true,
230
+ ttlMs: normalizePositiveDuration(config.lease?.ttlMs, 1e4, "cache.lease.ttlMs"),
231
+ waitTimeoutMs: normalizePositiveDuration(
232
+ config.lease?.waitTimeoutMs,
233
+ 1e4,
234
+ "cache.lease.waitTimeoutMs"
235
+ ),
236
+ pollIntervalMs: normalizePositiveDuration(
237
+ config.lease?.pollIntervalMs,
238
+ 25,
239
+ "cache.lease.pollIntervalMs"
240
+ )
241
+ };
242
+ if (!this.local) {
243
+ this.entries.clear();
244
+ this.inflight.clear();
245
+ this.invalidatedTagVersions.clear();
246
+ this.version = 0;
247
+ }
248
+ }
249
+ get adapterName() {
250
+ return this.adapter?.name || (this.adapter ? "custom" : "memory");
251
+ }
252
+ get hasAdapter() {
253
+ return this.adapter !== void 0;
214
254
  }
215
255
  get size() {
216
256
  return this.entries.size;
@@ -246,6 +286,45 @@ var _FarmDataCache = class _FarmDataCache {
246
286
  });
247
287
  return this.toPublicEntry(entry);
248
288
  }
289
+ async getEntryAsync(key, options = {}) {
290
+ if (this.local) {
291
+ const localEntry = this.getEntry(key, options);
292
+ if (localEntry) return localEntry;
293
+ }
294
+ if (!this.adapter) {
295
+ return this.local ? void 0 : this.getEntry(key, options);
296
+ }
297
+ const entry = await this.adapter.get(this.createAdapterKey(key));
298
+ if (!entry) {
299
+ emitFarmEvent({ type: "cache.miss", key });
300
+ return void 0;
301
+ }
302
+ assertFarmCacheEntry(entry, key);
303
+ const stale = await this.isAdapterEntryStale(entry, options.now);
304
+ if (stale) {
305
+ emitFarmEvent({
306
+ type: "cache.stale",
307
+ key,
308
+ tags: [...entry.tags],
309
+ revalidate: entry.revalidate
310
+ });
311
+ if (!options.allowStale) {
312
+ emitFarmEvent({ type: "cache.miss", key, reason: "stale" });
313
+ return void 0;
314
+ }
315
+ }
316
+ emitFarmEvent({
317
+ type: "cache.hit",
318
+ key,
319
+ tags: [...entry.tags],
320
+ revalidate: entry.revalidate,
321
+ stale
322
+ });
323
+ if (this.local && !stale) {
324
+ this.hydrateLocalEntry(entry);
325
+ }
326
+ return { ...entry, key };
327
+ }
249
328
  set(key, value, options = {}) {
250
329
  const tags = /* @__PURE__ */ new Set();
251
330
  for (const tag of options.tags ?? []) {
@@ -258,6 +337,7 @@ var _FarmDataCache = class _FarmDataCache {
258
337
  key,
259
338
  value,
260
339
  tags,
340
+ tagVersions: void 0,
261
341
  createdAt: options.createdAt ?? Date.now(),
262
342
  createdVersion: ++this.version,
263
343
  revalidate: normalizeRevalidate(options.revalidate)
@@ -271,11 +351,45 @@ var _FarmDataCache = class _FarmDataCache {
271
351
  });
272
352
  return this.toPublicEntry(entry);
273
353
  }
354
+ async setAsync(key, value, options = {}, tagVersions) {
355
+ const tags = normalizeCacheOptionsTags(options);
356
+ const capturedVersions = tagVersions ?? await this.getAdapterTagVersions(Array.from(tags.values()));
357
+ const entry = {
358
+ key,
359
+ value,
360
+ tags: Array.from(tags),
361
+ tagVersions: capturedVersions,
362
+ createdAt: options.createdAt ?? Date.now(),
363
+ createdVersion: ++this.version,
364
+ revalidate: normalizeRevalidate(options.revalidate)
365
+ };
366
+ if (this.local) {
367
+ this.hydrateLocalEntry(entry);
368
+ }
369
+ if (this.adapter) {
370
+ await this.adapter.set(this.createAdapterKey(key), entry);
371
+ }
372
+ emitFarmEvent({
373
+ type: "cache.set",
374
+ key,
375
+ tags: [...entry.tags],
376
+ revalidate: entry.revalidate
377
+ });
378
+ return entry;
379
+ }
274
380
  delete(key) {
275
381
  const deleted = this.entries.delete(key);
276
382
  emitFarmEvent({ type: "cache.delete", key, deleted });
277
383
  return deleted;
278
384
  }
385
+ async deleteAsync(key) {
386
+ const deleted = this.entries.delete(key);
387
+ if (this.adapter) {
388
+ await this.adapter.delete(this.createAdapterKey(key));
389
+ }
390
+ emitFarmEvent({ type: "cache.delete", key, deleted: this.adapter ? true : deleted });
391
+ return this.adapter ? true : deleted;
392
+ }
279
393
  clear() {
280
394
  const count = this.entries.size;
281
395
  this.entries.clear();
@@ -284,6 +398,10 @@ var _FarmDataCache = class _FarmDataCache {
284
398
  this.version = 0;
285
399
  emitFarmEvent({ type: "cache.clear", count });
286
400
  }
401
+ async clearAsync() {
402
+ this.clear();
403
+ await this.adapter?.clear?.();
404
+ }
287
405
  isStale(entry, now = Date.now()) {
288
406
  if (typeof entry.revalidate === "number" && entry.revalidate > 0 && now - entry.createdAt >= entry.revalidate * 1e3) {
289
407
  return true;
@@ -296,6 +414,12 @@ var _FarmDataCache = class _FarmDataCache {
296
414
  }
297
415
  return false;
298
416
  }
417
+ async isStaleAsync(entry, now = Date.now()) {
418
+ if (this.adapter) {
419
+ return this.isAdapterEntryStale(entry, now);
420
+ }
421
+ return this.isStale(entry, now);
422
+ }
299
423
  revalidateTag(tag, options = {}) {
300
424
  const normalized = normalizeCacheTag(tag);
301
425
  const count = this.invalidateTag(normalized);
@@ -304,6 +428,15 @@ var _FarmDataCache = class _FarmDataCache {
304
428
  );
305
429
  return count;
306
430
  }
431
+ async revalidateTagAsync(tag, options = {}) {
432
+ const normalized = normalizeCacheTag(tag);
433
+ const count = this.invalidateTag(normalized);
434
+ await this.adapter?.invalidateTags?.([this.createAdapterTag(normalized)]);
435
+ emitFarmEvent(
436
+ options.source === "updateTag" ? { type: "cache.updateTag", tag: normalized, count } : { type: "cache.revalidateTag", tag: normalized, profile: options.profile, count }
437
+ );
438
+ return count;
439
+ }
307
440
  revalidatePath(routePath) {
308
441
  const normalizedPath = normalizeRevalidatePath(routePath);
309
442
  const pathTag = createPathCacheTag(normalizedPath);
@@ -320,8 +453,25 @@ var _FarmDataCache = class _FarmDataCache {
320
453
  }
321
454
  return count;
322
455
  }
456
+ async revalidatePathAsync(routePath) {
457
+ const normalizedPath = normalizeRevalidatePath(routePath);
458
+ const pathTag = createPathCacheTag(normalizedPath);
459
+ const pprCount = this.countEntriesForTags([pathTag, "ppr"]);
460
+ const count = this.invalidateTag(pathTag);
461
+ await this.adapter?.invalidateTags?.([this.createAdapterTag(pathTag)]);
462
+ emitFarmEvent({ type: "cache.revalidatePath", path: normalizedPath, count });
463
+ if (pprCount > 0) {
464
+ emitFarmEvent({
465
+ type: "ppr.shell.invalidated",
466
+ route: normalizedPath,
467
+ reason: "revalidatePath",
468
+ count: pprCount
469
+ });
470
+ }
471
+ return count;
472
+ }
323
473
  async getOrSet(key, producer, options = {}) {
324
- const cached = this.getEntry(key);
474
+ const cached = await this.getEntryAsync(key);
325
475
  if (cached) {
326
476
  return cached.value;
327
477
  }
@@ -330,10 +480,8 @@ var _FarmDataCache = class _FarmDataCache {
330
480
  emitFarmEvent({ type: "cache.dedupe", key });
331
481
  return inflight;
332
482
  }
333
- const promise = Promise.resolve().then(producer).then((value) => {
334
- this.set(key, value, options);
335
- return value;
336
- }).catch((error) => {
483
+ const tags = Array.from(normalizeCacheOptionsTags(options));
484
+ const promise = this.fillCacheEntry(key, producer, options, tags).catch((error) => {
337
485
  emitFarmEvent({ type: "cache.error", key, operation: "set", error });
338
486
  throw error;
339
487
  }).finally(() => {
@@ -342,6 +490,40 @@ var _FarmDataCache = class _FarmDataCache {
342
490
  this.inflight.set(key, promise);
343
491
  return promise;
344
492
  }
493
+ async fillCacheEntry(key, producer, options, tags) {
494
+ const leaseKey = `${this.namespace}:lease:${key}`;
495
+ let leaseToken;
496
+ if (this.adapter?.acquireLease && this.adapter.releaseLease && this.lease.enabled) {
497
+ leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);
498
+ if (!leaseToken) {
499
+ const shared = await this.waitForAdapterEntry(key);
500
+ if (shared) {
501
+ emitFarmEvent({ type: "cache.dedupe", key });
502
+ return shared.value;
503
+ }
504
+ leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);
505
+ }
506
+ }
507
+ try {
508
+ const initialTagVersions = await this.getAdapterTagVersions(tags);
509
+ const value = await producer();
510
+ await this.setAsync(key, value, options, initialTagVersions);
511
+ return value;
512
+ } finally {
513
+ if (leaseToken && this.adapter?.releaseLease) {
514
+ await this.adapter.releaseLease(leaseKey, leaseToken);
515
+ }
516
+ }
517
+ }
518
+ async waitForAdapterEntry(key) {
519
+ const deadline = Date.now() + this.lease.waitTimeoutMs;
520
+ while (Date.now() < deadline) {
521
+ await delay(this.lease.pollIntervalMs);
522
+ const entry = await this.getEntryAsync(key);
523
+ if (entry) return entry;
524
+ }
525
+ return void 0;
526
+ }
345
527
  countEntriesForTag(tag) {
346
528
  let count = 0;
347
529
  for (const entry of this.entries.values()) {
@@ -369,11 +551,53 @@ var _FarmDataCache = class _FarmDataCache {
369
551
  key: entry.key,
370
552
  value: entry.value,
371
553
  tags: Array.from(entry.tags),
554
+ tagVersions: entry.tagVersions,
372
555
  createdAt: entry.createdAt,
373
556
  createdVersion: entry.createdVersion,
374
557
  revalidate: entry.revalidate
375
558
  };
376
559
  }
560
+ hydrateLocalEntry(entry) {
561
+ this.entries.set(entry.key, {
562
+ key: entry.key,
563
+ value: entry.value,
564
+ tags: new Set(entry.tags.map(normalizeCacheTag)),
565
+ tagVersions: entry.tagVersions,
566
+ createdAt: entry.createdAt,
567
+ createdVersion: entry.createdVersion ?? ++this.version,
568
+ revalidate: normalizeRevalidate(entry.revalidate)
569
+ });
570
+ }
571
+ createAdapterKey(key) {
572
+ return `${this.namespace}:entry:${key}`;
573
+ }
574
+ createAdapterTag(tag) {
575
+ return `${this.namespace}:tag:${tag}`;
576
+ }
577
+ async getAdapterTagVersions(tags) {
578
+ if (!this.adapter?.getTagVersions || tags.length === 0) return {};
579
+ const normalized = tags.map(normalizeCacheTag);
580
+ const physicalTags = normalized.map((tag) => this.createAdapterTag(tag));
581
+ const versions = await this.adapter.getTagVersions(physicalTags);
582
+ return Object.fromEntries(
583
+ normalized.map((tag, index) => [
584
+ tag,
585
+ normalizeAdapterVersion(versions[physicalTags[index]])
586
+ ])
587
+ );
588
+ }
589
+ async isAdapterEntryStale(entry, now = Date.now()) {
590
+ if (typeof entry.revalidate === "number" && entry.revalidate > 0 && now - entry.createdAt >= entry.revalidate * 1e3) {
591
+ return true;
592
+ }
593
+ const currentVersions = await this.getAdapterTagVersions(entry.tags);
594
+ for (const tag of entry.tags) {
595
+ if (normalizeAdapterVersion(currentVersions[tag]) > normalizeAdapterVersion(entry.tagVersions?.[tag])) {
596
+ return true;
597
+ }
598
+ }
599
+ return false;
600
+ }
377
601
  };
378
602
  __name(_FarmDataCache, "FarmDataCache");
379
603
  var FarmDataCache = _FarmDataCache;
@@ -428,6 +652,52 @@ function normalizeCacheTag(tag) {
428
652
  return normalized;
429
653
  }
430
654
  __name(normalizeCacheTag, "normalizeCacheTag");
655
+ function normalizeCacheNamespace(namespace) {
656
+ if (typeof namespace !== "string") {
657
+ throw new TypeError("Cache namespace must be a string.");
658
+ }
659
+ const normalized = namespace.trim().replace(/:+$/g, "");
660
+ if (!normalized) {
661
+ throw new Error("Cache namespace cannot be empty.");
662
+ }
663
+ return normalized;
664
+ }
665
+ __name(normalizeCacheNamespace, "normalizeCacheNamespace");
666
+ function normalizeAdapterVersion(value) {
667
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
668
+ }
669
+ __name(normalizeAdapterVersion, "normalizeAdapterVersion");
670
+ function normalizePositiveDuration(value, fallback, name) {
671
+ if (value === void 0) return fallback;
672
+ if (!Number.isFinite(value) || value <= 0) {
673
+ throw new TypeError(`${name} must be a positive number of milliseconds.`);
674
+ }
675
+ return Math.floor(value);
676
+ }
677
+ __name(normalizePositiveDuration, "normalizePositiveDuration");
678
+ function delay(ms) {
679
+ return new Promise((resolve) => setTimeout(resolve, ms));
680
+ }
681
+ __name(delay, "delay");
682
+ function normalizeCacheOptionsTags(options) {
683
+ const tags = /* @__PURE__ */ new Set();
684
+ for (const tag of options.tags ?? []) {
685
+ tags.add(normalizeCacheTag(tag));
686
+ }
687
+ for (const routePath of options.paths ?? []) {
688
+ tags.add(createPathCacheTag(routePath));
689
+ }
690
+ return tags;
691
+ }
692
+ __name(normalizeCacheOptionsTags, "normalizeCacheOptionsTags");
693
+ function assertFarmCacheEntry(entry, expectedKey) {
694
+ if (!entry || typeof entry !== "object" || entry.key !== expectedKey || !Array.isArray(entry.tags) || typeof entry.createdAt !== "number") {
695
+ throw new TypeError(
696
+ `Cache adapter returned an invalid entry for ${JSON.stringify(expectedKey)}.`
697
+ );
698
+ }
699
+ }
700
+ __name(assertFarmCacheEntry, "assertFarmCacheEntry");
431
701
 
432
702
  // src/api/endpoint.ts
433
703
  var _EndpointFailure = class _EndpointFailure extends Error {
@@ -492,7 +762,7 @@ async function invokeAPIRouteEndpointInContext(endpoint, request, params) {
492
762
  });
493
763
  let body = void 0;
494
764
  if (request.method.toUpperCase() !== "GET" && request.method.toUpperCase() !== "HEAD") {
495
- body = await readJSONBody(request);
765
+ body = await readRequestBody(request);
496
766
  }
497
767
  const headers = Object.fromEntries(request.headers.entries());
498
768
  const types = endpoint.__types || {};
@@ -596,17 +866,50 @@ function isFarmContextHandler(endpoint) {
596
866
  return firstParameter === "ctx" || firstParameter === "context" || firstParameter.startsWith("{");
597
867
  }
598
868
  __name(isFarmContextHandler, "isFarmContextHandler");
599
- async function readJSONBody(request) {
869
+ async function readRequestBody(request) {
870
+ const contentType = request.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
600
871
  try {
872
+ if (contentType === "multipart/form-data") {
873
+ return formDataToObject(await request.clone().formData());
874
+ }
601
875
  const text = await request.clone().text();
602
- if (text) {
876
+ if (!text) return void 0;
877
+ if (contentType === "application/x-www-form-urlencoded") {
878
+ return searchParamsToObject(new URLSearchParams(text));
879
+ }
880
+ if (contentType === "application/json" || contentType?.endsWith("+json")) {
603
881
  return JSON.parse(text);
604
882
  }
883
+ return JSON.parse(text);
605
884
  } catch {
606
885
  }
607
886
  return void 0;
608
887
  }
609
- __name(readJSONBody, "readJSONBody");
888
+ __name(readRequestBody, "readRequestBody");
889
+ function formDataToObject(formData) {
890
+ return entriesToObject(formData.entries());
891
+ }
892
+ __name(formDataToObject, "formDataToObject");
893
+ function searchParamsToObject(searchParams) {
894
+ return entriesToObject(searchParams.entries());
895
+ }
896
+ __name(searchParamsToObject, "searchParamsToObject");
897
+ function entriesToObject(entries) {
898
+ const output = /* @__PURE__ */ Object.create(null);
899
+ for (const [key, value] of entries) {
900
+ if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
901
+ const current = output[key];
902
+ if (current === void 0) {
903
+ output[key] = value;
904
+ } else if (Array.isArray(current)) {
905
+ current.push(value);
906
+ } else {
907
+ output[key] = [current, value];
908
+ }
909
+ }
910
+ return output;
911
+ }
912
+ __name(entriesToObject, "entriesToObject");
610
913
  function validateInput(schema, value, error) {
611
914
  if (!schema || typeof schema.parse !== "function") {
612
915
  return value;