@farm.js/core 0.1.0-beta.3 → 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 (192) 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-5QH4IKY3.mjs → chunk-3U3ZUQAQ.mjs} +2 -2
  30. package/dist/{chunk-6WXJ54TC.mjs → chunk-65A7QIKI.mjs} +5 -5
  31. package/dist/{chunk-6WXJ54TC.mjs.map → chunk-65A7QIKI.mjs.map} +1 -1
  32. package/dist/{chunk-OHC6VCDI.mjs → chunk-AJWRO5WE.mjs} +521 -42
  33. package/dist/chunk-AJWRO5WE.mjs.map +1 -0
  34. package/dist/chunk-ALCLXXTY.mjs +187 -0
  35. package/dist/chunk-ALCLXXTY.mjs.map +1 -0
  36. package/dist/{chunk-XJSHJN4M.mjs → chunk-AOBXKNS5.mjs} +593 -49
  37. package/dist/chunk-AOBXKNS5.mjs.map +1 -0
  38. package/dist/{chunk-CSU4KJJF.mjs → chunk-C2ROET2V.mjs} +2 -2
  39. package/dist/{chunk-BIOIOWXZ.mjs → chunk-HNIQFZKB.mjs} +2 -2
  40. package/dist/{chunk-G5I34UA6.mjs → chunk-JDEOUK5V.mjs} +4 -4
  41. package/dist/{chunk-T543TMFY.mjs → chunk-NM3CRAAL.mjs} +3 -2
  42. package/dist/chunk-NM3CRAAL.mjs.map +1 -0
  43. package/dist/{chunk-LWMGIEJA.mjs → chunk-PFE6GMNE.mjs} +47 -37
  44. package/dist/chunk-PFE6GMNE.mjs.map +1 -0
  45. package/dist/{chunk-6VS6CKAV.mjs → chunk-QM746KUO.mjs} +8 -1
  46. package/dist/chunk-QM746KUO.mjs.map +1 -0
  47. package/dist/{chunk-SHRJG6OG.mjs → chunk-RBRLLZL5.mjs} +18 -3
  48. package/dist/chunk-RBRLLZL5.mjs.map +1 -0
  49. package/dist/{chunk-MH6FKW2I.mjs → chunk-SADGIRS2.mjs} +3 -3
  50. package/dist/{chunk-NRRFGX45.mjs → chunk-TQAEEJB4.mjs} +3 -3
  51. package/dist/{chunk-45LKHSHJ.mjs → chunk-UB5UOSHB.mjs} +24 -12
  52. package/dist/chunk-UB5UOSHB.mjs.map +1 -0
  53. package/dist/chunk-V3XURYJO.mjs +756 -0
  54. package/dist/chunk-V3XURYJO.mjs.map +1 -0
  55. package/dist/{chunk-5FW6PQ3J.mjs → chunk-VVKWFZAH.mjs} +41 -16
  56. package/dist/chunk-VVKWFZAH.mjs.map +1 -0
  57. package/dist/{chunk-HZYXGV4K.mjs → chunk-VY2UYN5R.mjs} +24 -4
  58. package/dist/chunk-VY2UYN5R.mjs.map +1 -0
  59. package/dist/{chunk-C33RALN7.mjs → chunk-W2CRQFF6.mjs} +79 -15
  60. package/dist/chunk-W2CRQFF6.mjs.map +1 -0
  61. package/dist/{chunk-JNYVN7YP.mjs → chunk-W4UIVMVI.mjs} +2 -2
  62. package/dist/{chunk-JNYVN7YP.mjs.map → chunk-W4UIVMVI.mjs.map} +1 -1
  63. package/dist/{chunk-LG3YINQN.mjs → chunk-Z5CQMP54.mjs} +3 -3
  64. package/dist/{client-DiViK9yK.d.mts → client-BT1mFQas.d.mts} +23 -4
  65. package/dist/{client-DpEBJbts.d.ts → client-Nn0q4eO4.d.ts} +23 -4
  66. package/dist/{client-plugins-CTnsZz_A.d.ts → client-plugins-Cw4qUGsw.d.ts} +6 -0
  67. package/dist/{client-plugins-Cnr0D3kk.d.mts → client-plugins-DQQ1adXM.d.mts} +6 -0
  68. package/dist/client-plugins.d.mts +2 -1
  69. package/dist/client-plugins.d.ts +2 -1
  70. package/dist/client.cjs +665 -82
  71. package/dist/client.cjs.map +1 -1
  72. package/dist/client.d.mts +70 -4
  73. package/dist/client.d.ts +70 -4
  74. package/dist/client.mjs +10 -7
  75. package/dist/config.d.mts +2 -1
  76. package/dist/config.d.ts +2 -1
  77. package/dist/{devtools-HE4FTUDN.mjs → devtools-LVC3VB5P.mjs} +4 -4
  78. package/dist/docs.cjs +11 -1
  79. package/dist/docs.cjs.map +1 -1
  80. package/dist/docs.mjs +4 -4
  81. package/dist/index.cjs +2112 -197
  82. package/dist/index.cjs.map +1 -1
  83. package/dist/index.d.mts +12 -11
  84. package/dist/index.d.ts +12 -11
  85. package/dist/index.mjs +49 -21
  86. package/dist/index.mjs.map +1 -1
  87. package/dist/integrations.d.mts +2 -1
  88. package/dist/integrations.d.ts +2 -1
  89. package/dist/internal/build-runtime.cjs +1455 -90
  90. package/dist/internal/build-runtime.cjs.map +1 -1
  91. package/dist/internal/build-runtime.d.mts +4 -3
  92. package/dist/internal/build-runtime.d.ts +4 -3
  93. package/dist/internal/build-runtime.mjs +15 -14
  94. package/dist/internal/config-runtime.cjs +12 -1
  95. package/dist/internal/config-runtime.cjs.map +1 -1
  96. package/dist/internal/config-runtime.d.mts +3 -2
  97. package/dist/internal/config-runtime.d.ts +3 -2
  98. package/dist/internal/config-runtime.mjs +3 -3
  99. package/dist/internal/production-runtime.cjs +282 -6
  100. package/dist/internal/production-runtime.cjs.map +1 -1
  101. package/dist/internal/production-runtime.d.mts +4 -4
  102. package/dist/internal/production-runtime.d.ts +4 -4
  103. package/dist/internal/production-runtime.mjs +4 -2
  104. package/dist/{metadata-eoVmHoyv.d.ts → metadata-BAPg_Nmo.d.ts} +1 -1
  105. package/dist/{metadata-Dp8AdvsB.d.mts → metadata-_6i9oFG3.d.mts} +1 -1
  106. package/dist/middleware.d.mts +4 -3
  107. package/dist/middleware.d.ts +4 -3
  108. package/dist/navigation.cjs +40 -15
  109. package/dist/navigation.cjs.map +1 -1
  110. package/dist/navigation.mjs +2 -2
  111. package/dist/plugin.cjs +913 -53
  112. package/dist/plugin.cjs.map +1 -1
  113. package/dist/plugin.d.mts +2 -1
  114. package/dist/plugin.d.ts +2 -1
  115. package/dist/plugin.mjs +11 -10
  116. package/dist/{production-runtime-BqTnUTai.d.ts → production-runtime-BoJDc5mc.d.ts} +1 -1
  117. package/dist/{production-runtime-DtDdG9fc.d.mts → production-runtime-DPfgMV9Y.d.mts} +1 -1
  118. package/dist/routes.cjs +276 -6
  119. package/dist/routes.cjs.map +1 -1
  120. package/dist/routes.d.mts +1 -1
  121. package/dist/routes.d.ts +1 -1
  122. package/dist/routes.mjs +3 -3
  123. package/dist/{runtime-C1B7pSGT.d.mts → runtime-9nQjVM7X.d.mts} +8 -9
  124. package/dist/{runtime-CdPHt0bv.d.ts → runtime-DgeS2skB.d.ts} +8 -9
  125. package/dist/server-action-security.cjs +28 -10
  126. package/dist/server-action-security.cjs.map +1 -1
  127. package/dist/server-action-security.d.mts +2 -1
  128. package/dist/server-action-security.d.ts +2 -1
  129. package/dist/server-action-security.mjs +2 -2
  130. package/dist/server-fn-client.d.mts +1 -0
  131. package/dist/server-fn-client.d.ts +1 -0
  132. package/dist/server-fn.cjs +785 -3
  133. package/dist/server-fn.cjs.map +1 -1
  134. package/dist/server-fn.d.mts +10 -1
  135. package/dist/server-fn.d.ts +10 -1
  136. package/dist/server-fn.mjs +6 -3
  137. package/dist/server-plugins.d.mts +3 -2
  138. package/dist/server-plugins.d.ts +3 -2
  139. package/dist/server-query-client.cjs +278 -7
  140. package/dist/server-query-client.cjs.map +1 -1
  141. package/dist/server-query-client.mjs +4 -4
  142. package/dist/server-query.cjs +381 -10
  143. package/dist/server-query.cjs.map +1 -1
  144. package/dist/server-query.mjs +5 -5
  145. package/dist/server.cjs +1086 -76
  146. package/dist/server.cjs.map +1 -1
  147. package/dist/server.d.mts +8 -7
  148. package/dist/server.d.ts +8 -7
  149. package/dist/server.mjs +31 -16
  150. package/dist/server.mjs.map +1 -1
  151. package/dist/testing.cjs +341 -20
  152. package/dist/testing.cjs.map +1 -1
  153. package/dist/testing.d.mts +3 -2
  154. package/dist/testing.d.ts +3 -2
  155. package/dist/testing.mjs +7 -6
  156. package/dist/testing.mjs.map +1 -1
  157. package/dist/transport-BmbGTXA5.d.mts +49 -0
  158. package/dist/transport-BmbGTXA5.d.ts +49 -0
  159. package/dist/{utils-8USa5BiY.d.mts → utils-CHXlMDkg.d.mts} +1 -1
  160. package/dist/{utils-DKJb6K6G.d.ts → utils-Drsyz1Vj.d.ts} +1 -1
  161. package/dist/version.cjs +1 -1
  162. package/dist/version.cjs.map +1 -1
  163. package/dist/version.mjs +1 -1
  164. package/dist/vite.cjs +914 -54
  165. package/dist/vite.cjs.map +1 -1
  166. package/dist/vite.d.mts +2 -1
  167. package/dist/vite.d.ts +2 -1
  168. package/dist/vite.mjs +11 -10
  169. package/package.json +1 -1
  170. package/types/api.d.ts +44 -0
  171. package/types/client.d.ts +85 -4
  172. package/dist/chunk-45LKHSHJ.mjs.map +0 -1
  173. package/dist/chunk-5FW6PQ3J.mjs.map +0 -1
  174. package/dist/chunk-6VS6CKAV.mjs.map +0 -1
  175. package/dist/chunk-C33RALN7.mjs.map +0 -1
  176. package/dist/chunk-GZWT6VI5.mjs +0 -382
  177. package/dist/chunk-GZWT6VI5.mjs.map +0 -1
  178. package/dist/chunk-HZYXGV4K.mjs.map +0 -1
  179. package/dist/chunk-LWMGIEJA.mjs.map +0 -1
  180. package/dist/chunk-OHC6VCDI.mjs.map +0 -1
  181. package/dist/chunk-SHRJG6OG.mjs.map +0 -1
  182. package/dist/chunk-T543TMFY.mjs.map +0 -1
  183. package/dist/chunk-XJSHJN4M.mjs.map +0 -1
  184. package/dist/chunk-XUBZ7JI4.mjs.map +0 -1
  185. /package/dist/{chunk-5QH4IKY3.mjs.map → chunk-3U3ZUQAQ.mjs.map} +0 -0
  186. /package/dist/{chunk-CSU4KJJF.mjs.map → chunk-C2ROET2V.mjs.map} +0 -0
  187. /package/dist/{chunk-BIOIOWXZ.mjs.map → chunk-HNIQFZKB.mjs.map} +0 -0
  188. /package/dist/{chunk-G5I34UA6.mjs.map → chunk-JDEOUK5V.mjs.map} +0 -0
  189. /package/dist/{chunk-MH6FKW2I.mjs.map → chunk-SADGIRS2.mjs.map} +0 -0
  190. /package/dist/{chunk-NRRFGX45.mjs.map → chunk-TQAEEJB4.mjs.map} +0 -0
  191. /package/dist/{chunk-LG3YINQN.mjs.map → chunk-Z5CQMP54.mjs.map} +0 -0
  192. /package/dist/{devtools-HE4FTUDN.mjs.map → devtools-LVC3VB5P.mjs.map} +0 -0
@@ -151,7 +151,8 @@ var FARM_CACHE_INVALIDATION_STATE = /* @__PURE__ */ Symbol.for("farm.cacheInvali
151
151
  var globalState = globalThis;
152
152
  function getFarmCacheInvalidationState() {
153
153
  return globalState[FARM_CACHE_INVALIDATION_STATE] ?? (globalState[FARM_CACHE_INVALIDATION_STATE] = {
154
- listeners: /* @__PURE__ */ new Set()
154
+ listeners: /* @__PURE__ */ new Set(),
155
+ taskListeners: /* @__PURE__ */ new Set()
155
156
  });
156
157
  }
157
158
  __name(getFarmCacheInvalidationState, "getFarmCacheInvalidationState");
@@ -164,11 +165,51 @@ __name(subscribeFarmCacheInvalidation, "subscribeFarmCacheInvalidation");
164
165
 
165
166
  // src/cache.ts
166
167
  var _FarmDataCache = class _FarmDataCache {
167
- constructor() {
168
+ constructor(config = {}) {
168
169
  this.entries = /* @__PURE__ */ new Map();
169
170
  this.inflight = /* @__PURE__ */ new Map();
170
171
  this.invalidatedTagVersions = /* @__PURE__ */ new Map();
171
172
  this.version = 0;
173
+ this.namespace = "farm";
174
+ this.local = true;
175
+ this.lease = {
176
+ enabled: true,
177
+ ttlMs: 1e4,
178
+ waitTimeoutMs: 1e4,
179
+ pollIntervalMs: 25
180
+ };
181
+ this.configure(config);
182
+ }
183
+ configure(config = {}) {
184
+ this.adapter = config.adapter;
185
+ this.namespace = normalizeCacheNamespace(config.namespace || "farm");
186
+ this.local = !config.adapter;
187
+ this.lease = config.lease === false ? { ...this.lease, enabled: false } : {
188
+ enabled: true,
189
+ ttlMs: normalizePositiveDuration(config.lease?.ttlMs, 1e4, "cache.lease.ttlMs"),
190
+ waitTimeoutMs: normalizePositiveDuration(
191
+ config.lease?.waitTimeoutMs,
192
+ 1e4,
193
+ "cache.lease.waitTimeoutMs"
194
+ ),
195
+ pollIntervalMs: normalizePositiveDuration(
196
+ config.lease?.pollIntervalMs,
197
+ 25,
198
+ "cache.lease.pollIntervalMs"
199
+ )
200
+ };
201
+ if (!this.local) {
202
+ this.entries.clear();
203
+ this.inflight.clear();
204
+ this.invalidatedTagVersions.clear();
205
+ this.version = 0;
206
+ }
207
+ }
208
+ get adapterName() {
209
+ return this.adapter?.name || (this.adapter ? "custom" : "memory");
210
+ }
211
+ get hasAdapter() {
212
+ return this.adapter !== void 0;
172
213
  }
173
214
  get size() {
174
215
  return this.entries.size;
@@ -204,6 +245,45 @@ var _FarmDataCache = class _FarmDataCache {
204
245
  });
205
246
  return this.toPublicEntry(entry);
206
247
  }
248
+ async getEntryAsync(key, options = {}) {
249
+ if (this.local) {
250
+ const localEntry = this.getEntry(key, options);
251
+ if (localEntry) return localEntry;
252
+ }
253
+ if (!this.adapter) {
254
+ return this.local ? void 0 : this.getEntry(key, options);
255
+ }
256
+ const entry = await this.adapter.get(this.createAdapterKey(key));
257
+ if (!entry) {
258
+ emitFarmEvent({ type: "cache.miss", key });
259
+ return void 0;
260
+ }
261
+ assertFarmCacheEntry(entry, key);
262
+ const stale = await this.isAdapterEntryStale(entry, options.now);
263
+ if (stale) {
264
+ emitFarmEvent({
265
+ type: "cache.stale",
266
+ key,
267
+ tags: [...entry.tags],
268
+ revalidate: entry.revalidate
269
+ });
270
+ if (!options.allowStale) {
271
+ emitFarmEvent({ type: "cache.miss", key, reason: "stale" });
272
+ return void 0;
273
+ }
274
+ }
275
+ emitFarmEvent({
276
+ type: "cache.hit",
277
+ key,
278
+ tags: [...entry.tags],
279
+ revalidate: entry.revalidate,
280
+ stale
281
+ });
282
+ if (this.local && !stale) {
283
+ this.hydrateLocalEntry(entry);
284
+ }
285
+ return { ...entry, key };
286
+ }
207
287
  set(key, value, options = {}) {
208
288
  const tags = /* @__PURE__ */ new Set();
209
289
  for (const tag of options.tags ?? []) {
@@ -216,6 +296,7 @@ var _FarmDataCache = class _FarmDataCache {
216
296
  key,
217
297
  value,
218
298
  tags,
299
+ tagVersions: void 0,
219
300
  createdAt: options.createdAt ?? Date.now(),
220
301
  createdVersion: ++this.version,
221
302
  revalidate: normalizeRevalidate(options.revalidate)
@@ -229,11 +310,45 @@ var _FarmDataCache = class _FarmDataCache {
229
310
  });
230
311
  return this.toPublicEntry(entry);
231
312
  }
313
+ async setAsync(key, value, options = {}, tagVersions) {
314
+ const tags = normalizeCacheOptionsTags(options);
315
+ const capturedVersions = tagVersions ?? await this.getAdapterTagVersions(Array.from(tags.values()));
316
+ const entry = {
317
+ key,
318
+ value,
319
+ tags: Array.from(tags),
320
+ tagVersions: capturedVersions,
321
+ createdAt: options.createdAt ?? Date.now(),
322
+ createdVersion: ++this.version,
323
+ revalidate: normalizeRevalidate(options.revalidate)
324
+ };
325
+ if (this.local) {
326
+ this.hydrateLocalEntry(entry);
327
+ }
328
+ if (this.adapter) {
329
+ await this.adapter.set(this.createAdapterKey(key), entry);
330
+ }
331
+ emitFarmEvent({
332
+ type: "cache.set",
333
+ key,
334
+ tags: [...entry.tags],
335
+ revalidate: entry.revalidate
336
+ });
337
+ return entry;
338
+ }
232
339
  delete(key) {
233
340
  const deleted = this.entries.delete(key);
234
341
  emitFarmEvent({ type: "cache.delete", key, deleted });
235
342
  return deleted;
236
343
  }
344
+ async deleteAsync(key) {
345
+ const deleted = this.entries.delete(key);
346
+ if (this.adapter) {
347
+ await this.adapter.delete(this.createAdapterKey(key));
348
+ }
349
+ emitFarmEvent({ type: "cache.delete", key, deleted: this.adapter ? true : deleted });
350
+ return this.adapter ? true : deleted;
351
+ }
237
352
  clear() {
238
353
  const count = this.entries.size;
239
354
  this.entries.clear();
@@ -242,6 +357,10 @@ var _FarmDataCache = class _FarmDataCache {
242
357
  this.version = 0;
243
358
  emitFarmEvent({ type: "cache.clear", count });
244
359
  }
360
+ async clearAsync() {
361
+ this.clear();
362
+ await this.adapter?.clear?.();
363
+ }
245
364
  isStale(entry, now = Date.now()) {
246
365
  if (typeof entry.revalidate === "number" && entry.revalidate > 0 && now - entry.createdAt >= entry.revalidate * 1e3) {
247
366
  return true;
@@ -254,6 +373,12 @@ var _FarmDataCache = class _FarmDataCache {
254
373
  }
255
374
  return false;
256
375
  }
376
+ async isStaleAsync(entry, now = Date.now()) {
377
+ if (this.adapter) {
378
+ return this.isAdapterEntryStale(entry, now);
379
+ }
380
+ return this.isStale(entry, now);
381
+ }
257
382
  revalidateTag(tag, options = {}) {
258
383
  const normalized = normalizeCacheTag(tag);
259
384
  const count = this.invalidateTag(normalized);
@@ -262,6 +387,15 @@ var _FarmDataCache = class _FarmDataCache {
262
387
  );
263
388
  return count;
264
389
  }
390
+ async revalidateTagAsync(tag, options = {}) {
391
+ const normalized = normalizeCacheTag(tag);
392
+ const count = this.invalidateTag(normalized);
393
+ await this.adapter?.invalidateTags?.([this.createAdapterTag(normalized)]);
394
+ emitFarmEvent(
395
+ options.source === "updateTag" ? { type: "cache.updateTag", tag: normalized, count } : { type: "cache.revalidateTag", tag: normalized, profile: options.profile, count }
396
+ );
397
+ return count;
398
+ }
265
399
  revalidatePath(routePath) {
266
400
  const normalizedPath = normalizeRevalidatePath(routePath);
267
401
  const pathTag = createPathCacheTag(normalizedPath);
@@ -278,8 +412,25 @@ var _FarmDataCache = class _FarmDataCache {
278
412
  }
279
413
  return count;
280
414
  }
415
+ async revalidatePathAsync(routePath) {
416
+ const normalizedPath = normalizeRevalidatePath(routePath);
417
+ const pathTag = createPathCacheTag(normalizedPath);
418
+ const pprCount = this.countEntriesForTags([pathTag, "ppr"]);
419
+ const count = this.invalidateTag(pathTag);
420
+ await this.adapter?.invalidateTags?.([this.createAdapterTag(pathTag)]);
421
+ emitFarmEvent({ type: "cache.revalidatePath", path: normalizedPath, count });
422
+ if (pprCount > 0) {
423
+ emitFarmEvent({
424
+ type: "ppr.shell.invalidated",
425
+ route: normalizedPath,
426
+ reason: "revalidatePath",
427
+ count: pprCount
428
+ });
429
+ }
430
+ return count;
431
+ }
281
432
  async getOrSet(key, producer, options = {}) {
282
- const cached = this.getEntry(key);
433
+ const cached = await this.getEntryAsync(key);
283
434
  if (cached) {
284
435
  return cached.value;
285
436
  }
@@ -288,10 +439,8 @@ var _FarmDataCache = class _FarmDataCache {
288
439
  emitFarmEvent({ type: "cache.dedupe", key });
289
440
  return inflight;
290
441
  }
291
- const promise = Promise.resolve().then(producer).then((value) => {
292
- this.set(key, value, options);
293
- return value;
294
- }).catch((error) => {
442
+ const tags = Array.from(normalizeCacheOptionsTags(options));
443
+ const promise = this.fillCacheEntry(key, producer, options, tags).catch((error) => {
295
444
  emitFarmEvent({ type: "cache.error", key, operation: "set", error });
296
445
  throw error;
297
446
  }).finally(() => {
@@ -300,6 +449,40 @@ var _FarmDataCache = class _FarmDataCache {
300
449
  this.inflight.set(key, promise);
301
450
  return promise;
302
451
  }
452
+ async fillCacheEntry(key, producer, options, tags) {
453
+ const leaseKey = `${this.namespace}:lease:${key}`;
454
+ let leaseToken;
455
+ if (this.adapter?.acquireLease && this.adapter.releaseLease && this.lease.enabled) {
456
+ leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);
457
+ if (!leaseToken) {
458
+ const shared = await this.waitForAdapterEntry(key);
459
+ if (shared) {
460
+ emitFarmEvent({ type: "cache.dedupe", key });
461
+ return shared.value;
462
+ }
463
+ leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);
464
+ }
465
+ }
466
+ try {
467
+ const initialTagVersions = await this.getAdapterTagVersions(tags);
468
+ const value = await producer();
469
+ await this.setAsync(key, value, options, initialTagVersions);
470
+ return value;
471
+ } finally {
472
+ if (leaseToken && this.adapter?.releaseLease) {
473
+ await this.adapter.releaseLease(leaseKey, leaseToken);
474
+ }
475
+ }
476
+ }
477
+ async waitForAdapterEntry(key) {
478
+ const deadline = Date.now() + this.lease.waitTimeoutMs;
479
+ while (Date.now() < deadline) {
480
+ await delay(this.lease.pollIntervalMs);
481
+ const entry = await this.getEntryAsync(key);
482
+ if (entry) return entry;
483
+ }
484
+ return void 0;
485
+ }
303
486
  countEntriesForTag(tag) {
304
487
  let count = 0;
305
488
  for (const entry of this.entries.values()) {
@@ -327,11 +510,53 @@ var _FarmDataCache = class _FarmDataCache {
327
510
  key: entry.key,
328
511
  value: entry.value,
329
512
  tags: Array.from(entry.tags),
513
+ tagVersions: entry.tagVersions,
330
514
  createdAt: entry.createdAt,
331
515
  createdVersion: entry.createdVersion,
332
516
  revalidate: entry.revalidate
333
517
  };
334
518
  }
519
+ hydrateLocalEntry(entry) {
520
+ this.entries.set(entry.key, {
521
+ key: entry.key,
522
+ value: entry.value,
523
+ tags: new Set(entry.tags.map(normalizeCacheTag)),
524
+ tagVersions: entry.tagVersions,
525
+ createdAt: entry.createdAt,
526
+ createdVersion: entry.createdVersion ?? ++this.version,
527
+ revalidate: normalizeRevalidate(entry.revalidate)
528
+ });
529
+ }
530
+ createAdapterKey(key) {
531
+ return `${this.namespace}:entry:${key}`;
532
+ }
533
+ createAdapterTag(tag) {
534
+ return `${this.namespace}:tag:${tag}`;
535
+ }
536
+ async getAdapterTagVersions(tags) {
537
+ if (!this.adapter?.getTagVersions || tags.length === 0) return {};
538
+ const normalized = tags.map(normalizeCacheTag);
539
+ const physicalTags = normalized.map((tag) => this.createAdapterTag(tag));
540
+ const versions = await this.adapter.getTagVersions(physicalTags);
541
+ return Object.fromEntries(
542
+ normalized.map((tag, index) => [
543
+ tag,
544
+ normalizeAdapterVersion(versions[physicalTags[index]])
545
+ ])
546
+ );
547
+ }
548
+ async isAdapterEntryStale(entry, now = Date.now()) {
549
+ if (typeof entry.revalidate === "number" && entry.revalidate > 0 && now - entry.createdAt >= entry.revalidate * 1e3) {
550
+ return true;
551
+ }
552
+ const currentVersions = await this.getAdapterTagVersions(entry.tags);
553
+ for (const tag of entry.tags) {
554
+ if (normalizeAdapterVersion(currentVersions[tag]) > normalizeAdapterVersion(entry.tagVersions?.[tag])) {
555
+ return true;
556
+ }
557
+ }
558
+ return false;
559
+ }
335
560
  };
336
561
  __name(_FarmDataCache, "FarmDataCache");
337
562
  var FarmDataCache = _FarmDataCache;
@@ -392,6 +617,52 @@ function normalizeCacheTag(tag) {
392
617
  return normalized;
393
618
  }
394
619
  __name(normalizeCacheTag, "normalizeCacheTag");
620
+ function normalizeCacheNamespace(namespace) {
621
+ if (typeof namespace !== "string") {
622
+ throw new TypeError("Cache namespace must be a string.");
623
+ }
624
+ const normalized = namespace.trim().replace(/:+$/g, "");
625
+ if (!normalized) {
626
+ throw new Error("Cache namespace cannot be empty.");
627
+ }
628
+ return normalized;
629
+ }
630
+ __name(normalizeCacheNamespace, "normalizeCacheNamespace");
631
+ function normalizeAdapterVersion(value) {
632
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
633
+ }
634
+ __name(normalizeAdapterVersion, "normalizeAdapterVersion");
635
+ function normalizePositiveDuration(value, fallback, name) {
636
+ if (value === void 0) return fallback;
637
+ if (!Number.isFinite(value) || value <= 0) {
638
+ throw new TypeError(`${name} must be a positive number of milliseconds.`);
639
+ }
640
+ return Math.floor(value);
641
+ }
642
+ __name(normalizePositiveDuration, "normalizePositiveDuration");
643
+ function delay(ms) {
644
+ return new Promise((resolve) => setTimeout(resolve, ms));
645
+ }
646
+ __name(delay, "delay");
647
+ function normalizeCacheOptionsTags(options) {
648
+ const tags = /* @__PURE__ */ new Set();
649
+ for (const tag of options.tags ?? []) {
650
+ tags.add(normalizeCacheTag(tag));
651
+ }
652
+ for (const routePath of options.paths ?? []) {
653
+ tags.add(createPathCacheTag(routePath));
654
+ }
655
+ return tags;
656
+ }
657
+ __name(normalizeCacheOptionsTags, "normalizeCacheOptionsTags");
658
+ function assertFarmCacheEntry(entry, expectedKey) {
659
+ if (!entry || typeof entry !== "object" || entry.key !== expectedKey || !Array.isArray(entry.tags) || typeof entry.createdAt !== "number") {
660
+ throw new TypeError(
661
+ `Cache adapter returned an invalid entry for ${JSON.stringify(expectedKey)}.`
662
+ );
663
+ }
664
+ }
665
+ __name(assertFarmCacheEntry, "assertFarmCacheEntry");
395
666
  function getFunctionCacheIdentity(fn) {
396
667
  if (fn.name) {
397
668
  return `name:${fn.name}`;