@farm.js/core 0.1.16 → 0.1.17

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 (180) hide show
  1. package/dist/agent-runtime.d.mts +3 -3
  2. package/dist/agent-runtime.d.ts +3 -3
  3. package/dist/api/client.cjs +62 -28
  4. package/dist/api/client.d.mts +3 -3
  5. package/dist/api/client.d.ts +3 -3
  6. package/dist/api/client.mjs +3 -3
  7. package/dist/api/route-manager.cjs +69 -32
  8. package/dist/api/route-manager.d.mts +3 -3
  9. package/dist/api/route-manager.d.ts +3 -3
  10. package/dist/api/route-manager.mjs +5 -5
  11. package/dist/api/runtime.cjs +65 -29
  12. package/dist/api/runtime.d.mts +3 -3
  13. package/dist/api/runtime.d.ts +3 -3
  14. package/dist/api/runtime.mjs +6 -3
  15. package/dist/{api-client-B-n3pm_Q.d.mts → api-client-Cx54IR5g.d.mts} +2 -2
  16. package/dist/{api-client-C0_NZEBl.d.ts → api-client-DykpaKcY.d.ts} +2 -2
  17. package/dist/api.cjs +106 -33
  18. package/dist/api.d.mts +5 -5
  19. package/dist/api.d.ts +5 -5
  20. package/dist/api.mjs +8 -8
  21. package/dist/{app-AyjEsCBq.d.ts → app-BHY_10Lm.d.ts} +3 -3
  22. package/dist/{app-CYPHeOo_.d.mts → app-BMk0do23.d.mts} +3 -3
  23. package/dist/app-markdown.d.mts +4 -4
  24. package/dist/app-markdown.d.ts +4 -4
  25. package/dist/app-markdown.mjs +3 -3
  26. package/dist/cache.cjs +62 -28
  27. package/dist/cache.d.mts +11 -1
  28. package/dist/cache.d.ts +11 -1
  29. package/dist/cache.mjs +1 -1
  30. package/dist/{chunk-7HDZYYS4.mjs → chunk-4OOBRCJX.mjs} +27 -5
  31. package/dist/{chunk-NHHKW2T6.mjs → chunk-56DAX2BE.mjs} +170 -52
  32. package/dist/{chunk-B76DT5Y6.mjs → chunk-57J3Y7Y3.mjs} +1 -1
  33. package/dist/{chunk-MOQNHLTS.mjs → chunk-5QOEPUYE.mjs} +5 -2
  34. package/dist/{chunk-HKLRP3BN.mjs → chunk-5SPPCN5J.mjs} +1 -1
  35. package/dist/{chunk-LUC2FAGW.mjs → chunk-6VQIKZZO.mjs} +1 -1
  36. package/dist/{chunk-7ZWL7XOU.mjs → chunk-76DG3LF3.mjs} +1 -1
  37. package/dist/{chunk-EWDK36MM.mjs → chunk-A72YEUZ3.mjs} +1 -1
  38. package/dist/{chunk-ZHOIQC6U.mjs → chunk-ATERBVHQ.mjs} +2 -2
  39. package/dist/{chunk-27JNCYEK.mjs → chunk-EN7WTEAY.mjs} +2 -2
  40. package/dist/{chunk-IGO2HEV7.mjs → chunk-F6SJAKFJ.mjs} +62 -28
  41. package/dist/{chunk-GSDIZACQ.mjs → chunk-FG5H2VCJ.mjs} +2 -2
  42. package/dist/{chunk-LZK5CXDW.mjs → chunk-KLSSO6YD.mjs} +2 -2
  43. package/dist/{chunk-KUO3GBPK.mjs → chunk-L6V3P73N.mjs} +1 -1
  44. package/dist/{chunk-TYVVIQ5M.mjs → chunk-MVIWBEJF.mjs} +32 -25
  45. package/dist/{chunk-KTGFMHET.mjs → chunk-N6UROPT7.mjs} +1 -1
  46. package/dist/{chunk-NDD2YVGU.mjs → chunk-NRVGEI5I.mjs} +10 -3
  47. package/dist/{chunk-IXTEENRS.mjs → chunk-QGVJVSNX.mjs} +5 -5
  48. package/dist/{chunk-6SCB2MXB.mjs → chunk-SXHV42UQ.mjs} +16 -1
  49. package/dist/{chunk-OWTIOHON.mjs → chunk-SYGGPS4A.mjs} +2 -2
  50. package/dist/{chunk-NC333MFA.mjs → chunk-TSWW5BVH.mjs} +7 -4
  51. package/dist/{chunk-LK6FGAQR.mjs → chunk-UDBJCUPA.mjs} +7 -4
  52. package/dist/{chunk-NUD6XBMO.mjs → chunk-UTBVHYS3.mjs} +2 -2
  53. package/dist/{chunk-76MNRHTS.mjs → chunk-UUYF3CHN.mjs} +2 -2
  54. package/dist/{chunk-VVTREAG5.mjs → chunk-WD4YXVLV.mjs} +11 -3
  55. package/dist/{chunk-UQZPTIML.mjs → chunk-WD5PNSOB.mjs} +2 -2
  56. package/dist/{chunk-DPZUDPVJ.mjs → chunk-XP777LRD.mjs} +1 -1
  57. package/dist/{chunk-KATQ6I56.mjs → chunk-XWAYMDLB.mjs} +1 -1
  58. package/dist/{chunk-IL5RWYK7.mjs → chunk-YD4J4XCI.mjs} +1 -1
  59. package/dist/{chunk-Q3MDL7TM.mjs → chunk-ZCNJKLA2.mjs} +30 -11
  60. package/dist/{client-plugins-CqVtZi5X.d.ts → client-plugins-C089bQhN.d.ts} +2 -2
  61. package/dist/{client-plugins-CIPRtSsW.d.mts → client-plugins-JXXmZliS.d.mts} +2 -2
  62. package/dist/client-plugins.d.mts +3 -3
  63. package/dist/client-plugins.d.ts +3 -3
  64. package/dist/client.cjs +62 -28
  65. package/dist/client.d.mts +8 -8
  66. package/dist/client.d.ts +8 -8
  67. package/dist/client.mjs +6 -6
  68. package/dist/config.d.mts +3 -3
  69. package/dist/config.d.ts +3 -3
  70. package/dist/cron.mjs +2 -2
  71. package/dist/{devtools-IU7LKZOH.mjs → devtools-UFVTMQX5.mjs} +7 -7
  72. package/dist/docs.cjs +18 -10
  73. package/dist/docs.mjs +9 -9
  74. package/dist/{endpoint-kSAxE52R.d.ts → endpoint-1zA994xL.d.ts} +1 -1
  75. package/dist/{endpoint-Bu3XgeMK.d.mts → endpoint-DAc96i93.d.mts} +1 -1
  76. package/dist/env.cjs +39 -5
  77. package/dist/env.d.mts +5 -3
  78. package/dist/env.d.ts +5 -3
  79. package/dist/env.mjs +2 -1
  80. package/dist/index.cjs +311 -93
  81. package/dist/index.d.mts +14 -14
  82. package/dist/index.d.ts +14 -14
  83. package/dist/index.mjs +34 -34
  84. package/dist/integrations.d.mts +3 -3
  85. package/dist/integrations.d.ts +3 -3
  86. package/dist/internal/app-markdown-runtime.d.mts +3 -3
  87. package/dist/internal/app-markdown-runtime.d.ts +3 -3
  88. package/dist/internal/app-markdown-runtime.mjs +2 -2
  89. package/dist/internal/build-runtime.cjs +342 -121
  90. package/dist/internal/build-runtime.d.mts +5 -5
  91. package/dist/internal/build-runtime.d.ts +5 -5
  92. package/dist/internal/build-runtime.mjs +23 -23
  93. package/dist/internal/cli-runtime.cjs +77 -31
  94. package/dist/internal/cli-runtime.mjs +13 -13
  95. package/dist/internal/client-error-overlay.cjs +1 -1
  96. package/dist/internal/client-error-overlay.mjs +1 -1
  97. package/dist/internal/compression-runtime.d.mts +3 -3
  98. package/dist/internal/compression-runtime.d.ts +3 -3
  99. package/dist/internal/config-runtime.cjs +14 -2
  100. package/dist/internal/config-runtime.d.mts +4 -4
  101. package/dist/internal/config-runtime.d.ts +4 -4
  102. package/dist/internal/config-runtime.mjs +7 -7
  103. package/dist/internal/product-telemetry-runtime.cjs +1 -1
  104. package/dist/internal/product-telemetry-runtime.mjs +1 -1
  105. package/dist/internal/production-runtime.cjs +101 -41
  106. package/dist/internal/production-runtime.d.mts +9 -9
  107. package/dist/internal/production-runtime.d.ts +9 -9
  108. package/dist/internal/production-runtime.mjs +6 -6
  109. package/dist/markdown.cjs +16 -1
  110. package/dist/markdown.mjs +1 -1
  111. package/dist/{metadata-8g__AMPM.d.ts → metadata-BcNJP4fq.d.ts} +1 -1
  112. package/dist/{metadata-OMX6wFNf.d.mts → metadata-C1Z9vLbb.d.mts} +1 -1
  113. package/dist/middleware.cjs +10 -3
  114. package/dist/middleware.d.mts +5 -5
  115. package/dist/middleware.d.ts +5 -5
  116. package/dist/middleware.mjs +4 -4
  117. package/dist/{nitro-3N4ZXRYM.mjs → nitro-CVZ36JM5.mjs} +4 -4
  118. package/dist/plugin.cjs +256 -105
  119. package/dist/plugin.d.mts +3 -3
  120. package/dist/plugin.d.ts +3 -3
  121. package/dist/plugin.mjs +19 -19
  122. package/dist/{production-runtime-W3M0eNDV.d.mts → production-runtime-jcrTlRTb.d.mts} +1 -1
  123. package/dist/{production-runtime-BJh7o6Cr.d.ts → production-runtime-oKmC0WU-.d.ts} +1 -1
  124. package/dist/{render-plan-io7pvDNc.d.mts → render-plan-BLIfc4jt.d.mts} +1 -1
  125. package/dist/{render-plan-Be4ZGTJP.d.ts → render-plan-DOB9cV-h.d.ts} +1 -1
  126. package/dist/renderer-client.cjs +62 -28
  127. package/dist/renderer-client.d.mts +5 -5
  128. package/dist/renderer-client.d.ts +5 -5
  129. package/dist/renderer-client.mjs +3 -3
  130. package/dist/{request-DZkHYQ89.d.mts → request-Cr53NRHr.d.mts} +1 -1
  131. package/dist/{request-G8JhKr4F.d.ts → request-Dt2gNuQD.d.ts} +1 -1
  132. package/dist/request.d.mts +4 -4
  133. package/dist/request.d.ts +4 -4
  134. package/dist/{route-C_eLaFTZ.d.mts → route-B0XrsrFk.d.mts} +1 -1
  135. package/dist/{route-BxNJT447.d.ts → route-DOEpbyWZ.d.ts} +1 -1
  136. package/dist/{route-rendering-BcLLPJgN.d.ts → route-rendering-CWYd8Mv1.d.ts} +1 -1
  137. package/dist/{route-rendering-CbAKr1TY.d.mts → route-rendering-CeFBEAoZ.d.mts} +1 -1
  138. package/dist/routes.cjs +68 -31
  139. package/dist/routes.d.mts +4 -4
  140. package/dist/routes.d.ts +4 -4
  141. package/dist/routes.mjs +2 -2
  142. package/dist/server-fn-client.d.mts +3 -3
  143. package/dist/server-fn-client.d.ts +3 -3
  144. package/dist/server-fn.cjs +72 -30
  145. package/dist/server-fn.d.mts +1 -1
  146. package/dist/server-fn.d.ts +1 -1
  147. package/dist/server-fn.mjs +2 -2
  148. package/dist/server-plugins.d.mts +4 -4
  149. package/dist/server-plugins.d.ts +4 -4
  150. package/dist/server-query-client.cjs +62 -28
  151. package/dist/server-query-client.d.mts +1 -1
  152. package/dist/server-query-client.d.ts +1 -1
  153. package/dist/server-query-client.mjs +4 -4
  154. package/dist/server-query.cjs +72 -30
  155. package/dist/server-query.d.mts +1 -1
  156. package/dist/server-query.d.ts +1 -1
  157. package/dist/server-query.mjs +3 -3
  158. package/dist/server.cjs +239 -80
  159. package/dist/server.d.mts +9 -9
  160. package/dist/server.d.ts +9 -9
  161. package/dist/server.mjs +22 -22
  162. package/dist/{spa-router-BcS_4nqm.d.mts → spa-router-CQWiYGxS.d.mts} +2 -2
  163. package/dist/{spa-router-BzFBUJkn.d.ts → spa-router-Wjiw-8hB.d.ts} +2 -2
  164. package/dist/testing.cjs +73 -32
  165. package/dist/testing.d.mts +3 -3
  166. package/dist/testing.d.ts +3 -3
  167. package/dist/testing.mjs +11 -7
  168. package/dist/{utils-C4yrAhNc.d.ts → utils-B0XJmG_b.d.ts} +1 -1
  169. package/dist/{utils-5kQP1mFR.d.mts → utils-uUxF0K0P.d.mts} +1 -1
  170. package/dist/version.cjs +1 -1
  171. package/dist/version.mjs +1 -1
  172. package/dist/vite.cjs +260 -109
  173. package/dist/vite.d.mts +3 -3
  174. package/dist/vite.d.ts +3 -3
  175. package/dist/vite.mjs +19 -19
  176. package/dist/workflows.mjs +2 -2
  177. package/package.json +2 -2
  178. package/dist/{chunk-VO5SCWF5.mjs → chunk-BNGS6KJ6.mjs} +0 -0
  179. package/dist/{chunk-MUUZJLCI.mjs → chunk-EGJDUF4Q.mjs} +3 -3
  180. package/dist/{chunk-4L7SZOHZ.mjs → chunk-YHOCRI4H.mjs} +3 -3
@@ -433,6 +433,8 @@ var _FarmDataCache = class _FarmDataCache {
433
433
  constructor(config = {}) {
434
434
  this.entries = /* @__PURE__ */ new Map();
435
435
  this.inflight = /* @__PURE__ */ new Map();
436
+ /** Local entries by tag, so tag counts and pruning never scan unrelated entries. */
437
+ this.entriesByTag = /* @__PURE__ */ new Map();
436
438
  this.invalidatedTagVersions = /* @__PURE__ */ new Map();
437
439
  this.activeGenerations = /* @__PURE__ */ new Set();
438
440
  this.version = 0;
@@ -451,6 +453,7 @@ var _FarmDataCache = class _FarmDataCache {
451
453
  configure(config = {}) {
452
454
  this.generation++;
453
455
  this.entries.clear();
456
+ this.entriesByTag.clear();
454
457
  this.inflight.clear();
455
458
  this.invalidatedTagVersions.clear();
456
459
  this.activeGenerations.clear();
@@ -617,14 +620,12 @@ var _FarmDataCache = class _FarmDataCache {
617
620
  return entry;
618
621
  }
619
622
  delete(key) {
620
- const deleted = this.entries.delete(key);
621
- if (deleted) this.pruneInvalidatedTagVersions();
623
+ const deleted = this.deleteLocalEntry(key);
622
624
  emitFarmEvent({ type: "cache.delete", key, deleted });
623
625
  return deleted;
624
626
  }
625
627
  async deleteAsync(key) {
626
- const deleted = this.entries.delete(key);
627
- if (deleted) this.pruneInvalidatedTagVersions();
628
+ const deleted = this.deleteLocalEntry(key);
628
629
  if (this.adapter) {
629
630
  await this.adapter.delete(this.createAdapterKey(key));
630
631
  }
@@ -635,6 +636,7 @@ var _FarmDataCache = class _FarmDataCache {
635
636
  const count = this.entries.size;
636
637
  this.generation++;
637
638
  this.entries.clear();
639
+ this.entriesByTag.clear();
638
640
  this.inflight.clear();
639
641
  this.invalidatedTagVersions.clear();
640
642
  this.activeGenerations.clear();
@@ -720,23 +722,32 @@ var _FarmDataCache = class _FarmDataCache {
720
722
  return cached.value;
721
723
  }
722
724
  const inflight = this.inflight.get(key);
723
- if (inflight) {
725
+ if (inflight && !this.wasInvalidatedSince(inflight.tags, inflight.startVersion)) {
724
726
  emitFarmEvent({ type: "cache.dedupe", key });
725
- return inflight;
727
+ return inflight.promise;
726
728
  }
727
729
  const tags = Array.from(normalizeCacheOptionsTags(options));
728
730
  const generation = this.generation;
731
+ const startVersion = this.version;
729
732
  const promise = this.fillCacheEntry(key, producer, options, tags, generation).catch((error) => {
730
733
  emitFarmEvent({ type: "cache.error", key, operation: "set", error });
731
734
  throw error;
732
735
  }).finally(() => {
733
- if (this.inflight.get(key) === promise) {
736
+ if (this.inflight.get(key)?.promise === promise) {
734
737
  this.inflight.delete(key);
735
738
  }
736
739
  });
737
- this.inflight.set(key, promise);
740
+ this.inflight.set(key, { promise, tags, startVersion });
738
741
  return promise;
739
742
  }
743
+ /** A fill that started before one of its tags was invalidated cannot satisfy later readers. */
744
+ wasInvalidatedSince(tags, version) {
745
+ for (const tag of tags) {
746
+ const invalidatedVersion = this.invalidatedTagVersions.get(tag);
747
+ if (invalidatedVersion !== void 0 && invalidatedVersion > version) return true;
748
+ }
749
+ return false;
750
+ }
740
751
  async fillCacheEntry(key, producer, options, tags, generation) {
741
752
  const adapter = this.adapter;
742
753
  const namespace = this.namespace;
@@ -777,7 +788,7 @@ var _FarmDataCache = class _FarmDataCache {
777
788
  return value;
778
789
  } finally {
779
790
  this.activeGenerations.delete(activeGeneration);
780
- this.pruneInvalidatedTagVersions();
791
+ this.pruneInvalidatedTagVersions(activeGeneration.tags);
781
792
  if (leaseToken && adapter?.releaseLease) {
782
793
  try {
783
794
  await adapter.releaseLease(leaseKey, leaseToken);
@@ -822,18 +833,9 @@ var _FarmDataCache = class _FarmDataCache {
822
833
  }
823
834
  return void 0;
824
835
  }
825
- countEntriesForTag(tag) {
826
- let count = 0;
827
- for (const entry of this.entries.values()) {
828
- if (entry.tags.has(tag)) {
829
- count++;
830
- }
831
- }
832
- return count;
833
- }
834
836
  countEntriesForTags(tags) {
835
837
  let count = 0;
836
- for (const entry of this.entries.values()) {
838
+ for (const entry of this.entriesByTag.get(tags[0]) ?? []) {
837
839
  if (tags.every((tag) => entry.tags.has(tag))) {
838
840
  count++;
839
841
  }
@@ -841,10 +843,10 @@ var _FarmDataCache = class _FarmDataCache {
841
843
  return count;
842
844
  }
843
845
  invalidateTag(normalizedTag) {
844
- const count = this.countEntriesForTag(normalizedTag);
846
+ const count = this.entriesByTag.get(normalizedTag)?.size ?? 0;
845
847
  this.invalidatedTagVersions.delete(normalizedTag);
846
848
  this.invalidatedTagVersions.set(normalizedTag, ++this.version);
847
- this.pruneInvalidatedTagVersions();
849
+ this.pruneInvalidatedTagVersions([normalizedTag]);
848
850
  return count;
849
851
  }
850
852
  toPublicEntry(entry) {
@@ -874,19 +876,51 @@ var _FarmDataCache = class _FarmDataCache {
874
876
  this.entries.set(key, entry);
875
877
  }
876
878
  storeLocalEntry(entry) {
877
- this.entries.delete(entry.key);
879
+ const removed = [];
880
+ const replaced = this.detachLocalEntry(entry.key);
881
+ if (replaced) removed.push(replaced);
878
882
  this.entries.set(entry.key, entry);
883
+ for (const tag of entry.tags) {
884
+ let tagged = this.entriesByTag.get(tag);
885
+ if (!tagged) this.entriesByTag.set(tag, tagged = /* @__PURE__ */ new Set());
886
+ tagged.add(entry);
887
+ }
879
888
  while (this.entries.size > this.maxEntries) {
880
889
  const oldestKey = this.entries.keys().next().value;
881
890
  if (oldestKey === void 0) break;
882
- this.entries.delete(oldestKey);
891
+ removed.push(this.detachLocalEntry(oldestKey));
883
892
  }
884
- this.pruneInvalidatedTagVersions();
893
+ for (const removedEntry of removed) this.pruneInvalidatedTagVersions(removedEntry.tags);
885
894
  }
886
- pruneInvalidatedTagVersions() {
887
- tags: for (const [tag, invalidatedVersion] of this.invalidatedTagVersions) {
888
- for (const entry of this.entries.values()) {
889
- if (entry.tags.has(tag) && entry.createdVersion < invalidatedVersion) continue tags;
895
+ deleteLocalEntry(key) {
896
+ const entry = this.detachLocalEntry(key);
897
+ if (!entry) return false;
898
+ this.pruneInvalidatedTagVersions(entry.tags);
899
+ return true;
900
+ }
901
+ detachLocalEntry(key) {
902
+ const entry = this.entries.get(key);
903
+ if (!entry) return void 0;
904
+ this.entries.delete(key);
905
+ for (const tag of entry.tags) {
906
+ const tagged = this.entriesByTag.get(tag);
907
+ if (!tagged) continue;
908
+ tagged.delete(entry);
909
+ if (tagged.size === 0) this.entriesByTag.delete(tag);
910
+ }
911
+ return entry;
912
+ }
913
+ /**
914
+ * Drop invalidation versions that no local entry or active fill can be stale against.
915
+ * Callers pass only the tags whose dependents just changed, so the cost is bounded by
916
+ * the entries sharing those tags rather than by the whole cache.
917
+ */
918
+ pruneInvalidatedTagVersions(tags) {
919
+ tags: for (const tag of tags) {
920
+ const invalidatedVersion = this.invalidatedTagVersions.get(tag);
921
+ if (invalidatedVersion === void 0) continue;
922
+ for (const entry of this.entriesByTag.get(tag) ?? []) {
923
+ if (entry.createdVersion < invalidatedVersion) continue tags;
890
924
  }
891
925
  for (const generation of this.activeGenerations) {
892
926
  if (generation.tags.has(tag) && generation.createdVersion < invalidatedVersion)
@@ -5,7 +5,7 @@ export { F as FarmServerQueryActionInvocation, b as beginFarmServerQueryAction,
5
5
  import './cache.mjs';
6
6
  import './server-fn.mjs';
7
7
  import './server-fn-error-DDh14a0V.mjs';
8
- import './endpoint-Bu3XgeMK.mjs';
8
+ import './endpoint-DAc96i93.mjs';
9
9
 
10
10
  type UseServerQueryOptions = ServerQueryFetchOptions & {
11
11
  enabled?: boolean;
@@ -5,7 +5,7 @@ export { F as FarmServerQueryActionInvocation, b as beginFarmServerQueryAction,
5
5
  import './cache.js';
6
6
  import './server-fn.js';
7
7
  import './server-fn-error-DDh14a0V.js';
8
- import './endpoint-kSAxE52R.js';
8
+ import './endpoint-1zA994xL.js';
9
9
 
10
10
  type UseServerQueryOptions = ServerQueryFetchOptions & {
11
11
  enabled?: boolean;
@@ -1,17 +1,17 @@
1
1
  "use client";
2
2
  import {
3
3
  useServerQuery
4
- } from "./chunk-GSDIZACQ.mjs";
4
+ } from "./chunk-FG5H2VCJ.mjs";
5
5
  import {
6
6
  beginFarmServerQueryAction,
7
7
  completeFarmServerQueryAction,
8
8
  fetchServerQuery,
9
9
  prefetchServerQuery,
10
10
  shouldApplyFarmServerQueryActionResult
11
- } from "./chunk-76MNRHTS.mjs";
12
- import "./chunk-HKLRP3BN.mjs";
11
+ } from "./chunk-UUYF3CHN.mjs";
12
+ import "./chunk-5SPPCN5J.mjs";
13
13
  import "./chunk-KGB5UXJJ.mjs";
14
- import "./chunk-IGO2HEV7.mjs";
14
+ import "./chunk-F6SJAKFJ.mjs";
15
15
  import "./chunk-4SIYUGRY.mjs";
16
16
  import "./chunk-C4NCTZLM.mjs";
17
17
  import "./chunk-FUZEBRP3.mjs";
@@ -459,6 +459,8 @@ var _FarmDataCache = class _FarmDataCache {
459
459
  constructor(config = {}) {
460
460
  this.entries = /* @__PURE__ */ new Map();
461
461
  this.inflight = /* @__PURE__ */ new Map();
462
+ /** Local entries by tag, so tag counts and pruning never scan unrelated entries. */
463
+ this.entriesByTag = /* @__PURE__ */ new Map();
462
464
  this.invalidatedTagVersions = /* @__PURE__ */ new Map();
463
465
  this.activeGenerations = /* @__PURE__ */ new Set();
464
466
  this.version = 0;
@@ -477,6 +479,7 @@ var _FarmDataCache = class _FarmDataCache {
477
479
  configure(config = {}) {
478
480
  this.generation++;
479
481
  this.entries.clear();
482
+ this.entriesByTag.clear();
480
483
  this.inflight.clear();
481
484
  this.invalidatedTagVersions.clear();
482
485
  this.activeGenerations.clear();
@@ -643,14 +646,12 @@ var _FarmDataCache = class _FarmDataCache {
643
646
  return entry;
644
647
  }
645
648
  delete(key) {
646
- const deleted = this.entries.delete(key);
647
- if (deleted) this.pruneInvalidatedTagVersions();
649
+ const deleted = this.deleteLocalEntry(key);
648
650
  emitFarmEvent({ type: "cache.delete", key, deleted });
649
651
  return deleted;
650
652
  }
651
653
  async deleteAsync(key) {
652
- const deleted = this.entries.delete(key);
653
- if (deleted) this.pruneInvalidatedTagVersions();
654
+ const deleted = this.deleteLocalEntry(key);
654
655
  if (this.adapter) {
655
656
  await this.adapter.delete(this.createAdapterKey(key));
656
657
  }
@@ -661,6 +662,7 @@ var _FarmDataCache = class _FarmDataCache {
661
662
  const count = this.entries.size;
662
663
  this.generation++;
663
664
  this.entries.clear();
665
+ this.entriesByTag.clear();
664
666
  this.inflight.clear();
665
667
  this.invalidatedTagVersions.clear();
666
668
  this.activeGenerations.clear();
@@ -746,23 +748,32 @@ var _FarmDataCache = class _FarmDataCache {
746
748
  return cached.value;
747
749
  }
748
750
  const inflight = this.inflight.get(key);
749
- if (inflight) {
751
+ if (inflight && !this.wasInvalidatedSince(inflight.tags, inflight.startVersion)) {
750
752
  emitFarmEvent({ type: "cache.dedupe", key });
751
- return inflight;
753
+ return inflight.promise;
752
754
  }
753
755
  const tags = Array.from(normalizeCacheOptionsTags(options));
754
756
  const generation = this.generation;
757
+ const startVersion = this.version;
755
758
  const promise = this.fillCacheEntry(key, producer, options, tags, generation).catch((error) => {
756
759
  emitFarmEvent({ type: "cache.error", key, operation: "set", error });
757
760
  throw error;
758
761
  }).finally(() => {
759
- if (this.inflight.get(key) === promise) {
762
+ if (this.inflight.get(key)?.promise === promise) {
760
763
  this.inflight.delete(key);
761
764
  }
762
765
  });
763
- this.inflight.set(key, promise);
766
+ this.inflight.set(key, { promise, tags, startVersion });
764
767
  return promise;
765
768
  }
769
+ /** A fill that started before one of its tags was invalidated cannot satisfy later readers. */
770
+ wasInvalidatedSince(tags, version) {
771
+ for (const tag of tags) {
772
+ const invalidatedVersion = this.invalidatedTagVersions.get(tag);
773
+ if (invalidatedVersion !== void 0 && invalidatedVersion > version) return true;
774
+ }
775
+ return false;
776
+ }
766
777
  async fillCacheEntry(key, producer, options, tags, generation) {
767
778
  const adapter = this.adapter;
768
779
  const namespace = this.namespace;
@@ -803,7 +814,7 @@ var _FarmDataCache = class _FarmDataCache {
803
814
  return value;
804
815
  } finally {
805
816
  this.activeGenerations.delete(activeGeneration);
806
- this.pruneInvalidatedTagVersions();
817
+ this.pruneInvalidatedTagVersions(activeGeneration.tags);
807
818
  if (leaseToken && adapter?.releaseLease) {
808
819
  try {
809
820
  await adapter.releaseLease(leaseKey, leaseToken);
@@ -848,18 +859,9 @@ var _FarmDataCache = class _FarmDataCache {
848
859
  }
849
860
  return void 0;
850
861
  }
851
- countEntriesForTag(tag) {
852
- let count = 0;
853
- for (const entry of this.entries.values()) {
854
- if (entry.tags.has(tag)) {
855
- count++;
856
- }
857
- }
858
- return count;
859
- }
860
862
  countEntriesForTags(tags) {
861
863
  let count = 0;
862
- for (const entry of this.entries.values()) {
864
+ for (const entry of this.entriesByTag.get(tags[0]) ?? []) {
863
865
  if (tags.every((tag) => entry.tags.has(tag))) {
864
866
  count++;
865
867
  }
@@ -867,10 +869,10 @@ var _FarmDataCache = class _FarmDataCache {
867
869
  return count;
868
870
  }
869
871
  invalidateTag(normalizedTag) {
870
- const count = this.countEntriesForTag(normalizedTag);
872
+ const count = this.entriesByTag.get(normalizedTag)?.size ?? 0;
871
873
  this.invalidatedTagVersions.delete(normalizedTag);
872
874
  this.invalidatedTagVersions.set(normalizedTag, ++this.version);
873
- this.pruneInvalidatedTagVersions();
875
+ this.pruneInvalidatedTagVersions([normalizedTag]);
874
876
  return count;
875
877
  }
876
878
  toPublicEntry(entry) {
@@ -900,19 +902,51 @@ var _FarmDataCache = class _FarmDataCache {
900
902
  this.entries.set(key, entry);
901
903
  }
902
904
  storeLocalEntry(entry) {
903
- this.entries.delete(entry.key);
905
+ const removed = [];
906
+ const replaced = this.detachLocalEntry(entry.key);
907
+ if (replaced) removed.push(replaced);
904
908
  this.entries.set(entry.key, entry);
909
+ for (const tag of entry.tags) {
910
+ let tagged = this.entriesByTag.get(tag);
911
+ if (!tagged) this.entriesByTag.set(tag, tagged = /* @__PURE__ */ new Set());
912
+ tagged.add(entry);
913
+ }
905
914
  while (this.entries.size > this.maxEntries) {
906
915
  const oldestKey = this.entries.keys().next().value;
907
916
  if (oldestKey === void 0) break;
908
- this.entries.delete(oldestKey);
917
+ removed.push(this.detachLocalEntry(oldestKey));
918
+ }
919
+ for (const removedEntry of removed) this.pruneInvalidatedTagVersions(removedEntry.tags);
920
+ }
921
+ deleteLocalEntry(key) {
922
+ const entry = this.detachLocalEntry(key);
923
+ if (!entry) return false;
924
+ this.pruneInvalidatedTagVersions(entry.tags);
925
+ return true;
926
+ }
927
+ detachLocalEntry(key) {
928
+ const entry = this.entries.get(key);
929
+ if (!entry) return void 0;
930
+ this.entries.delete(key);
931
+ for (const tag of entry.tags) {
932
+ const tagged = this.entriesByTag.get(tag);
933
+ if (!tagged) continue;
934
+ tagged.delete(entry);
935
+ if (tagged.size === 0) this.entriesByTag.delete(tag);
909
936
  }
910
- this.pruneInvalidatedTagVersions();
937
+ return entry;
911
938
  }
912
- pruneInvalidatedTagVersions() {
913
- tags: for (const [tag, invalidatedVersion] of this.invalidatedTagVersions) {
914
- for (const entry of this.entries.values()) {
915
- if (entry.tags.has(tag) && entry.createdVersion < invalidatedVersion) continue tags;
939
+ /**
940
+ * Drop invalidation versions that no local entry or active fill can be stale against.
941
+ * Callers pass only the tags whose dependents just changed, so the cost is bounded by
942
+ * the entries sharing those tags rather than by the whole cache.
943
+ */
944
+ pruneInvalidatedTagVersions(tags) {
945
+ tags: for (const tag of tags) {
946
+ const invalidatedVersion = this.invalidatedTagVersions.get(tag);
947
+ if (invalidatedVersion === void 0) continue;
948
+ for (const entry of this.entriesByTag.get(tag) ?? []) {
949
+ if (entry.createdVersion < invalidatedVersion) continue tags;
916
950
  }
917
951
  for (const generation of this.activeGenerations) {
918
952
  if (generation.tags.has(tag) && generation.createdVersion < invalidatedVersion)
@@ -1395,7 +1429,7 @@ function createServerFn(options) {
1395
1429
  try {
1396
1430
  input = await _parseServerFnSchema(options.input, rawInput, "input");
1397
1431
  } catch (cause) {
1398
- throw labelInputErrors ? new ServerFnInputError(cause) : cause;
1432
+ throw labelInputErrors && isSchemaValidationFailure(cause) ? new ServerFnInputError(cause) : cause;
1399
1433
  }
1400
1434
  const executionContext = getServerActionExecutionContext();
1401
1435
  const request = executionContext?.request ?? _resolveCurrentRequest();
@@ -1615,9 +1649,17 @@ async function _parseServerFnSchema(schema, value, contract, owner = "createServ
1615
1649
  throw new TypeError(`${owner} ${contract} must provide parse, parseAsync, or safeParse`);
1616
1650
  }
1617
1651
  __name(_parseServerFnSchema, "_parseServerFnSchema");
1652
+ var schemaValidationFailures = /* @__PURE__ */ new WeakSet();
1653
+ function isSchemaValidationFailure(error) {
1654
+ if (!error || typeof error !== "object") return false;
1655
+ return schemaValidationFailures.has(error) || Array.isArray(error.issues);
1656
+ }
1657
+ __name(isSchemaValidationFailure, "isSchemaValidationFailure");
1618
1658
  function unwrapSafeParseResult(result) {
1619
1659
  if (result && typeof result === "object" && "success" in result && result.success === false) {
1620
- throw result.error;
1660
+ const error = result.error;
1661
+ if (error && typeof error === "object") schemaValidationFailures.add(error);
1662
+ throw error;
1621
1663
  }
1622
1664
  if (result && typeof result === "object" && "success" in result && result.success === true) {
1623
1665
  return result.data;
@@ -1,7 +1,7 @@
1
1
  import { RouteDataCacheKey } from './cache.mjs';
2
2
  import { ServerFnContext, ServerFnSchema, AnyServerFnMiddleware, InferServerFnSchemaOutput, ServerFnMiddlewareContext, ServerFnMCPMetadata, ServerFnHandler, InferServerFnSchemaInput } from './server-fn.mjs';
3
3
  import './server-fn-error-DDh14a0V.mjs';
4
- import './endpoint-Bu3XgeMK.mjs';
4
+ import './endpoint-DAc96i93.mjs';
5
5
 
6
6
  type MaybePromise<T> = T | Promise<T>;
7
7
  type ServerQueryStaleTime = number | false | `${number}${"ms" | "s" | "m" | "h"}`;
@@ -1,7 +1,7 @@
1
1
  import { RouteDataCacheKey } from './cache.js';
2
2
  import { ServerFnContext, ServerFnSchema, AnyServerFnMiddleware, InferServerFnSchemaOutput, ServerFnMiddlewareContext, ServerFnMCPMetadata, ServerFnHandler, InferServerFnSchemaInput } from './server-fn.js';
3
3
  import './server-fn-error-DDh14a0V.js';
4
- import './endpoint-kSAxE52R.js';
4
+ import './endpoint-1zA994xL.js';
5
5
 
6
6
  type MaybePromise<T> = T | Promise<T>;
7
7
  type ServerQueryStaleTime = number | false | `${number}${"ms" | "s" | "m" | "h"}`;
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  FARM_SERVER_QUERY_SYMBOL,
3
3
  createServerQuery
4
- } from "./chunk-UQZPTIML.mjs";
5
- import "./chunk-VVTREAG5.mjs";
4
+ } from "./chunk-WD5PNSOB.mjs";
5
+ import "./chunk-WD4YXVLV.mjs";
6
6
  import "./chunk-KGB5UXJJ.mjs";
7
7
  import "./chunk-QCFFHV5H.mjs";
8
8
  import "./chunk-FP2INE7H.mjs";
9
9
  import "./chunk-XF7Q24PF.mjs";
10
- import "./chunk-IGO2HEV7.mjs";
10
+ import "./chunk-F6SJAKFJ.mjs";
11
11
  import "./chunk-4SIYUGRY.mjs";
12
12
  import "./chunk-C4NCTZLM.mjs";
13
13
  import "./chunk-FUZEBRP3.mjs";