@farm.js/core 0.1.15 → 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 +5 -2
  2. package/dist/agent-runtime.d.ts +5 -2
  3. package/dist/api/client.cjs +62 -28
  4. package/dist/api/client.d.mts +3 -2
  5. package/dist/api/client.d.ts +3 -2
  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 +5 -2
  9. package/dist/api/route-manager.d.ts +5 -2
  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 -2
  13. package/dist/api/runtime.d.ts +3 -2
  14. package/dist/api/runtime.mjs +6 -3
  15. package/dist/{api-client-C8d7BZNp.d.mts → api-client-Cx54IR5g.d.mts} +2 -1
  16. package/dist/{api-client-BWrEbxfO.d.ts → api-client-DykpaKcY.d.ts} +2 -1
  17. package/dist/api.cjs +106 -33
  18. package/dist/api.d.mts +7 -4
  19. package/dist/api.d.ts +7 -4
  20. package/dist/api.mjs +8 -8
  21. package/dist/{app-wIYse61b.d.ts → app-BHY_10Lm.d.ts} +3 -3
  22. package/dist/{app-B3nVSjen.d.mts → app-BMk0do23.d.mts} +3 -3
  23. package/dist/app-markdown.d.mts +6 -3
  24. package/dist/app-markdown.d.ts +6 -3
  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-FOGLGRDS.mjs → chunk-4OOBRCJX.mjs} +122 -8
  31. package/dist/{chunk-JRF3C33L.mjs → chunk-56DAX2BE.mjs} +172 -53
  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-FBHGHMOA.mjs → chunk-MVIWBEJF.mjs} +37 -27
  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-GNTPTTLA.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-NJ47VORC.mjs → chunk-UTBVHYS3.mjs} +2 -2
  53. package/dist/{chunk-76MNRHTS.mjs → chunk-UUYF3CHN.mjs} +2 -2
  54. package/dist/{chunk-S3QW3BIS.mjs → chunk-WD4YXVLV.mjs} +99 -6
  55. package/dist/{chunk-W7IVHTOP.mjs → chunk-WD5PNSOB.mjs} +16 -3
  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-UE75PB52.mjs → chunk-YD4J4XCI.mjs} +1 -1
  59. package/dist/{chunk-Q3MDL7TM.mjs → chunk-ZCNJKLA2.mjs} +30 -11
  60. package/dist/{client-plugins-CslwYp3E.d.ts → client-plugins-C089bQhN.d.ts} +16 -4
  61. package/dist/{client-plugins-C1EgdoJM.d.mts → client-plugins-JXXmZliS.d.mts} +16 -4
  62. package/dist/client-plugins.d.mts +5 -2
  63. package/dist/client-plugins.d.ts +5 -2
  64. package/dist/client.cjs +62 -28
  65. package/dist/client.d.mts +8 -7
  66. package/dist/client.d.ts +8 -7
  67. package/dist/client.mjs +6 -6
  68. package/dist/config.d.mts +5 -2
  69. package/dist/config.d.ts +5 -2
  70. package/dist/cron.mjs +2 -2
  71. package/dist/{devtools-PCGEBRSC.mjs → devtools-UFVTMQX5.mjs} +7 -7
  72. package/dist/docs.cjs +83 -4
  73. package/dist/docs.mjs +9 -9
  74. package/dist/{route-CHBaW55F.d.ts → endpoint-1zA994xL.d.ts} +3 -128
  75. package/dist/{route-C6UClI1z.d.mts → endpoint-DAc96i93.d.mts} +3 -128
  76. package/dist/env.cjs +135 -8
  77. package/dist/env.d.mts +22 -2
  78. package/dist/env.d.ts +22 -2
  79. package/dist/env.mjs +4 -1
  80. package/dist/index.cjs +516 -105
  81. package/dist/index.d.mts +16 -15
  82. package/dist/index.d.ts +16 -15
  83. package/dist/index.mjs +46 -34
  84. package/dist/integrations.d.mts +5 -2
  85. package/dist/integrations.d.ts +5 -2
  86. package/dist/internal/app-markdown-runtime.d.mts +5 -2
  87. package/dist/internal/app-markdown-runtime.d.ts +5 -2
  88. package/dist/internal/app-markdown-runtime.mjs +2 -2
  89. package/dist/internal/build-runtime.cjs +600 -284
  90. package/dist/internal/build-runtime.d.mts +7 -4
  91. package/dist/internal/build-runtime.d.ts +7 -4
  92. package/dist/internal/build-runtime.mjs +23 -23
  93. package/dist/internal/cli-runtime.cjs +143 -33
  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 +5 -2
  98. package/dist/internal/compression-runtime.d.ts +5 -2
  99. package/dist/internal/config-runtime.cjs +80 -4
  100. package/dist/internal/config-runtime.d.mts +6 -3
  101. package/dist/internal/config-runtime.d.ts +6 -3
  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 +11 -8
  107. package/dist/internal/production-runtime.d.ts +11 -8
  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-BsUcOEXg.d.ts → metadata-BcNJP4fq.d.ts} +1 -1
  112. package/dist/{metadata-B1bxCPUY.d.mts → metadata-C1Z9vLbb.d.mts} +1 -1
  113. package/dist/middleware.cjs +10 -3
  114. package/dist/middleware.d.mts +7 -4
  115. package/dist/middleware.d.ts +7 -4
  116. package/dist/middleware.mjs +4 -4
  117. package/dist/{nitro-ICBP5APY.mjs → nitro-CVZ36JM5.mjs} +8 -5
  118. package/dist/plugin.cjs +358 -106
  119. package/dist/plugin.d.mts +5 -2
  120. package/dist/plugin.d.ts +5 -2
  121. package/dist/plugin.mjs +19 -19
  122. package/dist/{production-runtime-BDllolVh.d.mts → production-runtime-jcrTlRTb.d.mts} +1 -1
  123. package/dist/{production-runtime-CsNn2-zx.d.ts → production-runtime-oKmC0WU-.d.ts} +1 -1
  124. package/dist/{render-plan-CNUlzylR.d.mts → render-plan-BLIfc4jt.d.mts} +1 -1
  125. package/dist/{render-plan-EG4hNFjy.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 -4
  128. package/dist/renderer-client.d.ts +5 -4
  129. package/dist/renderer-client.mjs +3 -3
  130. package/dist/{request-Blh_f7Z3.d.mts → request-Cr53NRHr.d.mts} +1 -1
  131. package/dist/{request-DsVSQVfD.d.ts → request-Dt2gNuQD.d.ts} +1 -1
  132. package/dist/request.d.mts +6 -3
  133. package/dist/request.d.ts +6 -3
  134. package/dist/route-B0XrsrFk.d.mts +128 -0
  135. package/dist/route-DOEpbyWZ.d.ts +128 -0
  136. package/dist/{route-rendering-hUETRCbM.d.ts → route-rendering-CWYd8Mv1.d.ts} +1 -1
  137. package/dist/{route-rendering-LT4XSoQK.d.mts → route-rendering-CeFBEAoZ.d.mts} +1 -1
  138. package/dist/routes.cjs +68 -31
  139. package/dist/routes.d.mts +5 -3
  140. package/dist/routes.d.ts +5 -3
  141. package/dist/routes.mjs +2 -2
  142. package/dist/server-fn-client.d.mts +3 -2
  143. package/dist/server-fn-client.d.ts +3 -2
  144. package/dist/server-fn.cjs +212 -32
  145. package/dist/server-fn.d.mts +72 -1
  146. package/dist/server-fn.d.ts +72 -1
  147. package/dist/server-fn.mjs +13 -2
  148. package/dist/server-plugins.d.mts +6 -3
  149. package/dist/server-plugins.d.ts +6 -3
  150. package/dist/server-query-client.cjs +62 -28
  151. package/dist/server-query-client.d.mts +1 -0
  152. package/dist/server-query-client.d.ts +1 -0
  153. package/dist/server-query-client.mjs +4 -4
  154. package/dist/server-query.cjs +131 -32
  155. package/dist/server-query.d.mts +6 -1
  156. package/dist/server-query.d.ts +6 -1
  157. package/dist/server-query.mjs +4 -3
  158. package/dist/server.cjs +393 -84
  159. package/dist/server.d.mts +9 -8
  160. package/dist/server.d.ts +9 -8
  161. package/dist/server.mjs +22 -22
  162. package/dist/{spa-router-csKR9Ebj.d.mts → spa-router-CQWiYGxS.d.mts} +2 -2
  163. package/dist/{spa-router-Y_2FSJQK.d.ts → spa-router-Wjiw-8hB.d.ts} +2 -2
  164. package/dist/testing.cjs +73 -32
  165. package/dist/testing.d.mts +5 -3
  166. package/dist/testing.d.ts +5 -3
  167. package/dist/testing.mjs +11 -7
  168. package/dist/{utils-jISOE9SD.d.ts → utils-B0XJmG_b.d.ts} +1 -1
  169. package/dist/{utils-DR2wfZAn.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 +500 -252
  173. package/dist/vite.d.mts +5 -2
  174. package/dist/vite.d.ts +5 -2
  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
@@ -184,6 +184,8 @@ var _FarmDataCache = class _FarmDataCache {
184
184
  constructor(config = {}) {
185
185
  this.entries = /* @__PURE__ */ new Map();
186
186
  this.inflight = /* @__PURE__ */ new Map();
187
+ /** Local entries by tag, so tag counts and pruning never scan unrelated entries. */
188
+ this.entriesByTag = /* @__PURE__ */ new Map();
187
189
  this.invalidatedTagVersions = /* @__PURE__ */ new Map();
188
190
  this.activeGenerations = /* @__PURE__ */ new Set();
189
191
  this.version = 0;
@@ -202,6 +204,7 @@ var _FarmDataCache = class _FarmDataCache {
202
204
  configure(config = {}) {
203
205
  this.generation++;
204
206
  this.entries.clear();
207
+ this.entriesByTag.clear();
205
208
  this.inflight.clear();
206
209
  this.invalidatedTagVersions.clear();
207
210
  this.activeGenerations.clear();
@@ -368,14 +371,12 @@ var _FarmDataCache = class _FarmDataCache {
368
371
  return entry;
369
372
  }
370
373
  delete(key) {
371
- const deleted = this.entries.delete(key);
372
- if (deleted) this.pruneInvalidatedTagVersions();
374
+ const deleted = this.deleteLocalEntry(key);
373
375
  emitFarmEvent({ type: "cache.delete", key, deleted });
374
376
  return deleted;
375
377
  }
376
378
  async deleteAsync(key) {
377
- const deleted = this.entries.delete(key);
378
- if (deleted) this.pruneInvalidatedTagVersions();
379
+ const deleted = this.deleteLocalEntry(key);
379
380
  if (this.adapter) {
380
381
  await this.adapter.delete(this.createAdapterKey(key));
381
382
  }
@@ -386,6 +387,7 @@ var _FarmDataCache = class _FarmDataCache {
386
387
  const count = this.entries.size;
387
388
  this.generation++;
388
389
  this.entries.clear();
390
+ this.entriesByTag.clear();
389
391
  this.inflight.clear();
390
392
  this.invalidatedTagVersions.clear();
391
393
  this.activeGenerations.clear();
@@ -471,23 +473,32 @@ var _FarmDataCache = class _FarmDataCache {
471
473
  return cached.value;
472
474
  }
473
475
  const inflight = this.inflight.get(key);
474
- if (inflight) {
476
+ if (inflight && !this.wasInvalidatedSince(inflight.tags, inflight.startVersion)) {
475
477
  emitFarmEvent({ type: "cache.dedupe", key });
476
- return inflight;
478
+ return inflight.promise;
477
479
  }
478
480
  const tags = Array.from(normalizeCacheOptionsTags(options));
479
481
  const generation = this.generation;
482
+ const startVersion = this.version;
480
483
  const promise = this.fillCacheEntry(key, producer, options, tags, generation).catch((error) => {
481
484
  emitFarmEvent({ type: "cache.error", key, operation: "set", error });
482
485
  throw error;
483
486
  }).finally(() => {
484
- if (this.inflight.get(key) === promise) {
487
+ if (this.inflight.get(key)?.promise === promise) {
485
488
  this.inflight.delete(key);
486
489
  }
487
490
  });
488
- this.inflight.set(key, promise);
491
+ this.inflight.set(key, { promise, tags, startVersion });
489
492
  return promise;
490
493
  }
494
+ /** A fill that started before one of its tags was invalidated cannot satisfy later readers. */
495
+ wasInvalidatedSince(tags, version) {
496
+ for (const tag of tags) {
497
+ const invalidatedVersion = this.invalidatedTagVersions.get(tag);
498
+ if (invalidatedVersion !== void 0 && invalidatedVersion > version) return true;
499
+ }
500
+ return false;
501
+ }
491
502
  async fillCacheEntry(key, producer, options, tags, generation) {
492
503
  const adapter = this.adapter;
493
504
  const namespace = this.namespace;
@@ -528,7 +539,7 @@ var _FarmDataCache = class _FarmDataCache {
528
539
  return value;
529
540
  } finally {
530
541
  this.activeGenerations.delete(activeGeneration);
531
- this.pruneInvalidatedTagVersions();
542
+ this.pruneInvalidatedTagVersions(activeGeneration.tags);
532
543
  if (leaseToken && adapter?.releaseLease) {
533
544
  try {
534
545
  await adapter.releaseLease(leaseKey, leaseToken);
@@ -573,18 +584,9 @@ var _FarmDataCache = class _FarmDataCache {
573
584
  }
574
585
  return void 0;
575
586
  }
576
- countEntriesForTag(tag) {
577
- let count = 0;
578
- for (const entry of this.entries.values()) {
579
- if (entry.tags.has(tag)) {
580
- count++;
581
- }
582
- }
583
- return count;
584
- }
585
587
  countEntriesForTags(tags) {
586
588
  let count = 0;
587
- for (const entry of this.entries.values()) {
589
+ for (const entry of this.entriesByTag.get(tags[0]) ?? []) {
588
590
  if (tags.every((tag) => entry.tags.has(tag))) {
589
591
  count++;
590
592
  }
@@ -592,10 +594,10 @@ var _FarmDataCache = class _FarmDataCache {
592
594
  return count;
593
595
  }
594
596
  invalidateTag(normalizedTag) {
595
- const count = this.countEntriesForTag(normalizedTag);
597
+ const count = this.entriesByTag.get(normalizedTag)?.size ?? 0;
596
598
  this.invalidatedTagVersions.delete(normalizedTag);
597
599
  this.invalidatedTagVersions.set(normalizedTag, ++this.version);
598
- this.pruneInvalidatedTagVersions();
600
+ this.pruneInvalidatedTagVersions([normalizedTag]);
599
601
  return count;
600
602
  }
601
603
  toPublicEntry(entry) {
@@ -625,19 +627,51 @@ var _FarmDataCache = class _FarmDataCache {
625
627
  this.entries.set(key, entry);
626
628
  }
627
629
  storeLocalEntry(entry) {
628
- this.entries.delete(entry.key);
630
+ const removed = [];
631
+ const replaced = this.detachLocalEntry(entry.key);
632
+ if (replaced) removed.push(replaced);
629
633
  this.entries.set(entry.key, entry);
634
+ for (const tag of entry.tags) {
635
+ let tagged = this.entriesByTag.get(tag);
636
+ if (!tagged) this.entriesByTag.set(tag, tagged = /* @__PURE__ */ new Set());
637
+ tagged.add(entry);
638
+ }
630
639
  while (this.entries.size > this.maxEntries) {
631
640
  const oldestKey = this.entries.keys().next().value;
632
641
  if (oldestKey === void 0) break;
633
- this.entries.delete(oldestKey);
642
+ removed.push(this.detachLocalEntry(oldestKey));
634
643
  }
635
- this.pruneInvalidatedTagVersions();
644
+ for (const removedEntry of removed) this.pruneInvalidatedTagVersions(removedEntry.tags);
645
+ }
646
+ deleteLocalEntry(key) {
647
+ const entry = this.detachLocalEntry(key);
648
+ if (!entry) return false;
649
+ this.pruneInvalidatedTagVersions(entry.tags);
650
+ return true;
651
+ }
652
+ detachLocalEntry(key) {
653
+ const entry = this.entries.get(key);
654
+ if (!entry) return void 0;
655
+ this.entries.delete(key);
656
+ for (const tag of entry.tags) {
657
+ const tagged = this.entriesByTag.get(tag);
658
+ if (!tagged) continue;
659
+ tagged.delete(entry);
660
+ if (tagged.size === 0) this.entriesByTag.delete(tag);
661
+ }
662
+ return entry;
636
663
  }
637
- pruneInvalidatedTagVersions() {
638
- tags: for (const [tag, invalidatedVersion] of this.invalidatedTagVersions) {
639
- for (const entry of this.entries.values()) {
640
- if (entry.tags.has(tag) && entry.createdVersion < invalidatedVersion) continue tags;
664
+ /**
665
+ * Drop invalidation versions that no local entry or active fill can be stale against.
666
+ * Callers pass only the tags whose dependents just changed, so the cost is bounded by
667
+ * the entries sharing those tags rather than by the whole cache.
668
+ */
669
+ pruneInvalidatedTagVersions(tags) {
670
+ tags: for (const tag of tags) {
671
+ const invalidatedVersion = this.invalidatedTagVersions.get(tag);
672
+ if (invalidatedVersion === void 0) continue;
673
+ for (const entry of this.entriesByTag.get(tag) ?? []) {
674
+ if (entry.createdVersion < invalidatedVersion) continue tags;
641
675
  }
642
676
  for (const generation of this.activeGenerations) {
643
677
  if (generation.tags.has(tag) && generation.createdVersion < invalidatedVersion)
@@ -2,10 +2,10 @@ import {
2
2
  attachRevalidationListeners,
3
3
  createServerQueryCallKey,
4
4
  fetchServerQuery
5
- } from "./chunk-76MNRHTS.mjs";
5
+ } from "./chunk-UUYF3CHN.mjs";
6
6
  import {
7
7
  getFarmClientDataCache
8
- } from "./chunk-HKLRP3BN.mjs";
8
+ } from "./chunk-5SPPCN5J.mjs";
9
9
  import {
10
10
  __name
11
11
  } from "./chunk-LPEX4YW6.mjs";
@@ -7,7 +7,7 @@ import {
7
7
  isAPIRouteRef,
8
8
  resolveServerFnInvalidateTargets,
9
9
  settleServerFnOptimisticUpdates
10
- } from "./chunk-KUO3GBPK.mjs";
10
+ } from "./chunk-L6V3P73N.mjs";
11
11
  import {
12
12
  notifyClientObserver
13
13
  } from "./chunk-72AK62H5.mjs";
@@ -23,7 +23,7 @@ import {
23
23
  } from "./chunk-5HGR3W6O.mjs";
24
24
  import {
25
25
  getFarmClientDataCache
26
- } from "./chunk-HKLRP3BN.mjs";
26
+ } from "./chunk-5SPPCN5J.mjs";
27
27
  import {
28
28
  getFarmTrailingSlashPreference
29
29
  } from "./chunk-54UPOYFS.mjs";
@@ -7,7 +7,7 @@ import {
7
7
  FarmClientDataCache,
8
8
  getFarmClientDataCache,
9
9
  normalizeFarmClientCacheKey
10
- } from "./chunk-HKLRP3BN.mjs";
10
+ } from "./chunk-5SPPCN5J.mjs";
11
11
  import {
12
12
  createClientCancellation
13
13
  } from "./chunk-QVYLBY73.mjs";
@@ -7,7 +7,7 @@ import {
7
7
  import {
8
8
  compileFarmDocsAdapterEdgeManifest,
9
9
  createFarmDocsAPIHandler
10
- } from "./chunk-NJ47VORC.mjs";
10
+ } from "./chunk-UTBVHYS3.mjs";
11
11
  import {
12
12
  FARM_DOCS_LAST_MODIFIED_MANIFEST,
13
13
  createFarmDocsHandler,
@@ -17,7 +17,7 @@ import {
17
17
  loadFarmDocsPage,
18
18
  resolveFarmDocsContentDir,
19
19
  toFarmDocsMarkdownPage
20
- } from "./chunk-MOQNHLTS.mjs";
20
+ } from "./chunk-5QOEPUYE.mjs";
21
21
  import {
22
22
  generateFarmDocsSearchClientRuntime,
23
23
  isFarmDocsSearchEnabled,
@@ -31,7 +31,7 @@ import {
31
31
  getDeployTargetForPreset,
32
32
  hasCustomFarmRouteContext,
33
33
  resolveDeployOutputPath
34
- } from "./chunk-GNTPTTLA.mjs";
34
+ } from "./chunk-QGVJVSNX.mjs";
35
35
  import {
36
36
  resolveFarmInstrumentationFile
37
37
  } from "./chunk-F5D4XEAS.mjs";
@@ -59,17 +59,18 @@ import {
59
59
  getClientModuleMetadata,
60
60
  getFarmClientHydrationPlanOptions,
61
61
  mergeFarmFontCss,
62
+ mergeFarmProductionViteConfig,
62
63
  mergeFarmViteConfig,
63
64
  resolveFarmClientCacheAdapterEntry,
64
65
  resolveFarmIsolatedClientHydrationMode,
65
66
  resolveFarmNotFoundComponentPath
66
- } from "./chunk-JRF3C33L.mjs";
67
+ } from "./chunk-56DAX2BE.mjs";
67
68
  import {
68
69
  findRequestBoundSourceBlockers,
69
70
  generateFarmTypeArtifacts,
70
71
  parseRouteRenderingDirective,
71
72
  resolveRouteRenderingConfigFromFile
72
- } from "./chunk-27JNCYEK.mjs";
73
+ } from "./chunk-EN7WTEAY.mjs";
73
74
  import {
74
75
  isFarmPreviewDeploymentEnvironment
75
76
  } from "./chunk-BOYNDCZL.mjs";
@@ -96,16 +97,19 @@ import {
96
97
  } from "./chunk-OLYK7EAK.mjs";
97
98
  import {
98
99
  applyFarmCspHashesToHtml
99
- } from "./chunk-Q3MDL7TM.mjs";
100
+ } from "./chunk-ZCNJKLA2.mjs";
100
101
  import {
101
102
  applyFarmCronVercelCrons,
102
103
  createFarmCronCloudflareConfig,
103
104
  mergeScheduledTasks,
104
105
  prepareFarmCronForNitro
105
- } from "./chunk-4L7SZOHZ.mjs";
106
+ } from "./chunk-YHOCRI4H.mjs";
107
+ import {
108
+ createBundledEnv
109
+ } from "./chunk-4OOBRCJX.mjs";
106
110
  import {
107
111
  isFarmMarkdownPageFile
108
- } from "./chunk-LUC2FAGW.mjs";
112
+ } from "./chunk-6VQIKZZO.mjs";
109
113
  import {
110
114
  resolveFarmMdxComponentsModulePath,
111
115
  resolveMdxConfig
@@ -113,17 +117,17 @@ import {
113
117
  import {
114
118
  applyFarmWorkflowVercelCrons,
115
119
  prepareFarmWorkflowsForNitro
116
- } from "./chunk-MUUZJLCI.mjs";
120
+ } from "./chunk-EGJDUF4Q.mjs";
117
121
  import {
118
122
  getFarmIntegrationPluginServerRuntime,
119
123
  getIntegrationProviders
120
124
  } from "./chunk-JLCQGPXE.mjs";
121
125
  import {
122
126
  appendMiddlewareRoutePath
123
- } from "./chunk-B76DT5Y6.mjs";
127
+ } from "./chunk-57J3Y7Y3.mjs";
124
128
  import {
125
129
  APIRouteManager
126
- } from "./chunk-ZHOIQC6U.mjs";
130
+ } from "./chunk-ATERBVHQ.mjs";
127
131
  import {
128
132
  readFarmI18nCatalogs
129
133
  } from "./chunk-FV45CKBC.mjs";
@@ -2136,7 +2140,7 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
2136
2140
  }
2137
2141
  }
2138
2142
  try {
2139
- await viteBuild({
2143
+ const clientViteConfig = {
2140
2144
  root,
2141
2145
  // Vite otherwise falls back to <root>/public, silently dropping every
2142
2146
  // asset in a custom config.publicDir from the production client output.
@@ -2272,7 +2276,8 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
2272
2276
  "@farm.js/core/headers"
2273
2277
  ]
2274
2278
  }
2275
- });
2279
+ };
2280
+ await viteBuild(mergeFarmProductionViteConfig(clientViteConfig, config.vite));
2276
2281
  await mergeBuiltFontCss(outputDir);
2277
2282
  await validateClientBuildOutput(root, srcDir, outputDir);
2278
2283
  } finally {
@@ -4618,7 +4623,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
4618
4623
  "react-dom/server"
4619
4624
  ];
4620
4625
  try {
4621
- await viteBuild({
4626
+ const serverViteConfig = {
4622
4627
  root,
4623
4628
  build: {
4624
4629
  target: "esnext",
@@ -4709,7 +4714,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
4709
4714
  },
4710
4715
  define: {
4711
4716
  __FARM_API_BASE_URL__: JSON.stringify(config.api.baseURL),
4712
- __FARM_ENV__: JSON.stringify(config.env || { server: {}, public: {} }),
4717
+ __FARM_ENV__: JSON.stringify(createBundledEnv(config.env)),
4713
4718
  __FARM_PUBLIC_ENV__: JSON.stringify(config.env?.public || {})
4714
4719
  },
4715
4720
  plugins: [
@@ -4779,7 +4784,8 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
4779
4784
  // Route modules and the renderer adapter must share one runtime instance.
4780
4785
  dedupe: [...config.renderer.dedupe || []]
4781
4786
  }
4782
- });
4787
+ };
4788
+ await viteBuild(mergeFarmProductionViteConfig(serverViteConfig, config.vite));
4783
4789
  } finally {
4784
4790
  if (postcssConfigDir) {
4785
4791
  try {
@@ -6987,7 +6993,7 @@ function hasLocalRequestRoute(request, routePathname) {
6987
6993
  const pathname = new URL(request.url).pathname;
6988
6994
  if (
6989
6995
  farmOpenAPIReference &&
6990
- normalizeRuntimePath(pathname) === normalizeRuntimePath(farmOpenAPIReference.route)
6996
+ normalizeRuntimePath(stripFarmBasePath(pathname)) === normalizeRuntimePath(farmOpenAPIReference.route)
6991
6997
  ) {
6992
6998
  return true;
6993
6999
  }
@@ -7023,7 +7029,7 @@ function getFarmPluginRequestOptions(request) {
7023
7029
  const route = { pathname };
7024
7030
  if (
7025
7031
  farmOpenAPIReference &&
7026
- normalizeRuntimePath(pathname) === normalizeRuntimePath(farmOpenAPIReference.route)
7032
+ normalizeRuntimePath(stripFarmBasePath(pathname)) === normalizeRuntimePath(farmOpenAPIReference.route)
7027
7033
  ) {
7028
7034
  return {
7029
7035
  kind: "docs",
@@ -7352,9 +7358,10 @@ async function handleFarmRequest(request, adapterContext) {
7352
7358
  )` : "handleFarmRequestInContext(request, null, false, Date.now(), adapterContext, requestUrl)"};
7353
7359
  ${config.md?.enabled ? `const pathname = getFarmRoutePathname(requestUrl.pathname);
7354
7360
  if (matchPageRoute(pathname)) {
7361
+ // The Link header advertises the public .md URL, like the head alternate.
7355
7362
  return applyMarkdownNegotiationHeaders(response, {
7356
7363
  config: farmMarkdownConfig,
7357
- pathname,
7364
+ pathname: requestUrl.pathname,
7358
7365
  });
7359
7366
  }` : ""}
7360
7367
  return response;
@@ -7542,7 +7549,7 @@ async function handleFarmRequestInContext(
7542
7549
  if (
7543
7550
  farmOpenAPIReference &&
7544
7551
  farmOpenAPIReference.specRoute &&
7545
- normalizeRuntimePath(pathname) === normalizeRuntimePath(farmOpenAPIReference.specRoute)
7552
+ normalizeRuntimePath(stripFarmBasePath(pathname)) === normalizeRuntimePath(farmOpenAPIReference.specRoute)
7546
7553
  ) {
7547
7554
  const method = request.method.toUpperCase();
7548
7555
  const specResponse = method === "GET" || method === "HEAD"
@@ -7566,7 +7573,7 @@ async function handleFarmRequestInContext(
7566
7573
 
7567
7574
  if (
7568
7575
  farmOpenAPIReference &&
7569
- normalizeRuntimePath(pathname) === normalizeRuntimePath(farmOpenAPIReference.route)
7576
+ normalizeRuntimePath(stripFarmBasePath(pathname)) === normalizeRuntimePath(farmOpenAPIReference.route)
7570
7577
  ) {
7571
7578
  const method = request.method.toUpperCase();
7572
7579
  const response = method === "GET" || method === "HEAD"
@@ -8104,12 +8111,15 @@ async function handleFarmRequestInContext(
8104
8111
  const sharedCacheControl = getRouteSharedCacheControl(route, pprCanCache);
8105
8112
  const responseHeaders = {
8106
8113
  "Content-Type": "text/html; charset=utf-8",
8107
- "Cache-Control": renderedPage.stream || hasRequestScopedRender || !sharedCacheControl
8108
- ? "private, no-store"
8109
- : sharedCacheControl,
8114
+ "Cache-Control": sharedCacheControl,
8110
8115
  ...(farmFontPreloadHeader ? { "Link": farmFontPreloadHeader } : {}),
8111
8116
  ...(pprConfig.enabled ? getPPRHeaders(pprCanCache ? "miss" : "bypass", pprConfig) : {}),
8112
8117
  };
8118
+ // An error status or a request-scoped render is never shareable, even when
8119
+ // the PPR shell headers would otherwise grant a shared max-age.
8120
+ if (renderedPage.stream || hasRequestScopedRender || !sharedCacheControl) {
8121
+ responseHeaders["Cache-Control"] = "private, no-store";
8122
+ }
8113
8123
  const farmI18nSnapshot = getFarmI18nSnapshot();
8114
8124
  let html = renderedPage.html;
8115
8125
 
@@ -10115,7 +10125,7 @@ async function buildSSR(viteBuild, config, root, srcDir, outputDir) {
10115
10125
  },
10116
10126
  define: {
10117
10127
  __FARM_API_BASE_URL__: JSON.stringify(config.api.baseURL),
10118
- __FARM_ENV__: JSON.stringify(config.env || { server: {}, public: {} }),
10128
+ __FARM_ENV__: JSON.stringify(createBundledEnv(config.env)),
10119
10129
  __FARM_PUBLIC_ENV__: JSON.stringify(config.env?.public || {})
10120
10130
  },
10121
10131
  plugins: [
@@ -10138,7 +10148,7 @@ function resolveLegacyPageEntry(config, root, srcDir) {
10138
10148
  __name(resolveLegacyPageEntry, "resolveLegacyPageEntry");
10139
10149
  async function buildNitro(config, routeManager, apiRouteManager, serverRenderer, preset, root, distDir, pluginManager) {
10140
10150
  const [{ createNitroConfig }, { createNitro, build: nitroBuild }] = await Promise.all([
10141
- import("./nitro-ICBP5APY.mjs"),
10151
+ import("./nitro-CVZ36JM5.mjs"),
10142
10152
  import("nitro/builder")
10143
10153
  ]);
10144
10154
  let nitroConfig = await createNitroConfig(
@@ -10198,7 +10208,7 @@ async function buildNitro(config, routeManager, apiRouteManager, serverRenderer,
10198
10208
  farmRegistry.apiRouteManager = apiRouteManager;
10199
10209
  farmRegistry.routeManager = routeManager;
10200
10210
  farmRegistry.serverRenderer = serverRenderer;
10201
- farmRegistry.env = config.env || { server: {}, public: {} };
10211
+ farmRegistry.env = createBundledEnv(config.env);
10202
10212
  const routePaths = {};
10203
10213
  for (const [pattern, entry] of routeManager.getRoutes()) {
10204
10214
  const bundledPath = entry.modulePath.replace(/.*\/src\/app\//, "").replace(/\.(tsx?|jsx?)$/, ".js");
@@ -7,7 +7,7 @@ import {
7
7
  parseMiddlewareCookieHeader,
8
8
  serializeMiddlewareCookie,
9
9
  serializeMiddlewareCookieDeletion
10
- } from "./chunk-NDD2YVGU.mjs";
10
+ } from "./chunk-NRVGEI5I.mjs";
11
11
  import {
12
12
  emitFarmEvent
13
13
  } from "./chunk-FUZEBRP3.mjs";
@@ -278,7 +278,7 @@ function parseColonParam(segment) {
278
278
  };
279
279
  }
280
280
  __name(parseColonParam, "parseColonParam");
281
- function compilePathPattern(pattern) {
281
+ function compilePathPattern(pattern, trailingSlash = false) {
282
282
  const params = [];
283
283
  const segments = pattern.split("/").filter(Boolean);
284
284
  if (segments.length === 0) {
@@ -314,11 +314,18 @@ function compilePathPattern(pattern) {
314
314
  });
315
315
  return {
316
316
  kind: "path",
317
- regex: new RegExp(`^${parts.join("")}$`),
317
+ regex: new RegExp(`^${parts.join("")}${trailingSlash ? "/?" : ""}$`),
318
318
  params
319
319
  };
320
320
  }
321
321
  __name(compilePathPattern, "compilePathPattern");
322
+ function compileMatcherPattern(pattern) {
323
+ if (typeof pattern === "string" && pattern !== "*" && !pattern.endsWith("(.*)")) {
324
+ return compilePathPattern(pattern, true);
325
+ }
326
+ return compilePattern(pattern);
327
+ }
328
+ __name(compileMatcherPattern, "compileMatcherPattern");
322
329
  function compilePattern(pattern) {
323
330
  if (pattern instanceof RegExp) {
324
331
  return { kind: "regexp", regex: pattern };
@@ -338,7 +345,7 @@ __name(compilePattern, "compilePattern");
338
345
  function compileMiddlewareConfig(config) {
339
346
  const compiled = {
340
347
  matcher: config.matcher ? toMatcherList(config.matcher).map(
341
- (matcher) => typeof matcher === "function" ? matcher : compilePattern(matcher)
348
+ (matcher) => typeof matcher === "function" ? matcher : compileMatcherPattern(matcher)
342
349
  ) : void 0,
343
350
  exclude: config.exclude?.map(compilePattern)
344
351
  };
@@ -28,29 +28,29 @@ import {
28
28
  resolveFarmNoindexPreviews,
29
29
  resolveFarmPerformanceConfig,
30
30
  resolveFarmSecurityConfig
31
- } from "./chunk-Q3MDL7TM.mjs";
31
+ } from "./chunk-ZCNJKLA2.mjs";
32
32
  import {
33
33
  resolveFarmImageConfig
34
34
  } from "./chunk-G2KY33I6.mjs";
35
35
  import {
36
36
  resolveCronConfig
37
- } from "./chunk-4L7SZOHZ.mjs";
37
+ } from "./chunk-YHOCRI4H.mjs";
38
38
  import {
39
39
  resolveServerActionsConfig
40
40
  } from "./chunk-QCFFHV5H.mjs";
41
41
  import {
42
42
  resolveEnv,
43
43
  setEnv
44
- } from "./chunk-FOGLGRDS.mjs";
44
+ } from "./chunk-4OOBRCJX.mjs";
45
45
  import {
46
46
  resolveMdxConfig
47
47
  } from "./chunk-FA2W42OV.mjs";
48
48
  import {
49
49
  resolveMarkdownConfig
50
- } from "./chunk-6SCB2MXB.mjs";
50
+ } from "./chunk-SXHV42UQ.mjs";
51
51
  import {
52
52
  resolveWorkflowsConfig
53
- } from "./chunk-MUUZJLCI.mjs";
53
+ } from "./chunk-EGJDUF4Q.mjs";
54
54
  import {
55
55
  resolveFarmThemeConfig
56
56
  } from "./chunk-AELACLOB.mjs";
@@ -105,8 +105,16 @@ async function createMarkdownMirrorResponse(options) {
105
105
  if (!hasMarkdownExtension) {
106
106
  headersOut.set("Vary", "Accept");
107
107
  }
108
+ for (const token of pageResponse.headers.get("vary")?.split(",") ?? []) {
109
+ const name = token.trim();
110
+ if (name && name.toLowerCase() !== "accept") appendHeaderToken(headersOut, "Vary", name);
111
+ }
112
+ const pageCacheControl = pageResponse.headers.get("cache-control");
108
113
  const cache = target.route?.cache ?? options.config?.cache ?? false;
109
- headersOut.set("Cache-Control", createMarkdownCacheHeader(cache));
114
+ headersOut.set(
115
+ "Cache-Control",
116
+ pageCacheControl && isPrivateCacheControl(pageCacheControl) ? pageCacheControl : createMarkdownCacheHeader(cache)
117
+ );
110
118
  return new Response(options.request.method === "HEAD" ? null : markdown, {
111
119
  status: pageResponse.status,
112
120
  headers: headersOut
@@ -336,6 +344,13 @@ function isHtmlResponse(response) {
336
344
  return contentType.includes("text/html");
337
345
  }
338
346
  __name(isHtmlResponse, "isHtmlResponse");
347
+ function isPrivateCacheControl(value) {
348
+ return value.split(",").some((directive) => {
349
+ const name = directive.split("=", 1)[0].trim().toLowerCase();
350
+ return name === "private" || name === "no-store";
351
+ });
352
+ }
353
+ __name(isPrivateCacheControl, "isPrivateCacheControl");
339
354
  function createMarkdownCacheHeader(cache) {
340
355
  if (cache === false || cache <= 0) {
341
356
  return "no-store";
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-EMLAPBEM.mjs";
4
4
  import {
5
5
  applyFarmCacheInvalidationTargets
6
- } from "./chunk-IGO2HEV7.mjs";
6
+ } from "./chunk-F6SJAKFJ.mjs";
7
7
  import {
8
8
  assertBrowserStableRoutePath,
9
9
  assertUniqueRouteParameters,
@@ -77,7 +77,7 @@ function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
77
77
  wrappedHandler
78
78
  );
79
79
  endpoint.__path = path || void 0;
80
- endpoint.__method = options.method || "GET";
80
+ endpoint.__method = options.method || (path ? "GET" : void 0);
81
81
  endpoint.__autoPath = !path;
82
82
  endpoint.__handler = wrappedHandler;
83
83
  endpoint.__farmInvoke = (ctx) => runEndpointMiddleware(middleware, ctx, handler, error, options.invalidates);
@@ -12,7 +12,7 @@ import {
12
12
  createFarmCacheKey,
13
13
  createRouteDataCacheTag,
14
14
  getFarmDataCache
15
- } from "./chunk-IGO2HEV7.mjs";
15
+ } from "./chunk-F6SJAKFJ.mjs";
16
16
  import {
17
17
  __name
18
18
  } from "./chunk-LPEX4YW6.mjs";
@@ -355,6 +355,7 @@ function createProgrammaticPageComponent(route, rendererRuntime) {
355
355
  }
356
356
  return rendererRuntime.createElement(...args);
357
357
  }, "createElement");
358
+ const markFunctionComponent = /* @__PURE__ */ __name((component) => rendererRuntime?.markFunctionComponent?.(component) ?? component, "markFunctionComponent");
358
359
  const Component = route.component;
359
360
  if (route.pending) {
360
361
  const PendingComponent = route.pending;
@@ -376,7 +377,9 @@ function createProgrammaticPageComponent(route, rendererRuntime) {
376
377
  throw error;
377
378
  }
378
379
  }, "FarmProgrammaticPageContent");
379
- const PageContent = FarmProgrammaticPageContent2;
380
+ const PageContent = markFunctionComponent(
381
+ FarmProgrammaticPageContent2
382
+ );
380
383
  const FarmProgrammaticPage = /* @__PURE__ */ __name(function FarmProgrammaticPage2(props) {
381
384
  return createElement(
382
385
  rendererRuntime.Suspense,
@@ -386,7 +389,7 @@ function createProgrammaticPageComponent(route, rendererRuntime) {
386
389
  createElement(PageContent, props)
387
390
  );
388
391
  }, "FarmProgrammaticPage");
389
- return FarmProgrammaticPage;
392
+ return markFunctionComponent(FarmProgrammaticPage);
390
393
  }
391
394
  const FarmProgrammaticPageContent = /* @__PURE__ */ __name(async function FarmProgrammaticPageContent2(props) {
392
395
  try {
@@ -405,7 +408,7 @@ function createProgrammaticPageComponent(route, rendererRuntime) {
405
408
  throw error;
406
409
  }
407
410
  }, "FarmProgrammaticPageContent");
408
- return FarmProgrammaticPageContent;
411
+ return markFunctionComponent(FarmProgrammaticPageContent);
409
412
  }
410
413
  __name(createProgrammaticPageComponent, "createProgrammaticPageComponent");
411
414
  function readProgrammaticRouteProps(route, props, resources) {
@@ -6,10 +6,10 @@ import {
6
6
  } from "./chunk-IOEH4VWN.mjs";
7
7
  import {
8
8
  APIRouteConflictError
9
- } from "./chunk-ZHOIQC6U.mjs";
9
+ } from "./chunk-ATERBVHQ.mjs";
10
10
  import {
11
11
  findProgrammaticRouteFilesInDir
12
- } from "./chunk-VO5SCWF5.mjs";
12
+ } from "./chunk-BNGS6KJ6.mjs";
13
13
  import {
14
14
  isFarmAPIRouteFileName
15
15
  } from "./chunk-CU625VAY.mjs";
@@ -19,7 +19,7 @@ import {
19
19
  invokeAPIRouteEndpoint,
20
20
  matchAPIRouteAtBasePath,
21
21
  resolveAPIRouteEndpoint
22
- } from "./chunk-DPZUDPVJ.mjs";
22
+ } from "./chunk-XP777LRD.mjs";
23
23
  import {
24
24
  isProgrammaticRoutesFileName
25
25
  } from "./chunk-EA5K5BKU.mjs";
@@ -38,6 +38,9 @@ import {
38
38
  import {
39
39
  sendWebResponse
40
40
  } from "./chunk-Z2RZJZIZ.mjs";
41
+ import {
42
+ resolveFarmRequestURL
43
+ } from "./chunk-BSPQVJ4A.mjs";
41
44
  import {
42
45
  AmbiguousRouteError,
43
46
  assertUniqueRouteParameters,
@@ -395,7 +398,7 @@ function farmApiPlugin(options = {}) {
395
398
  if (currentPathname !== pathname && !matchAPIRouteAtBasePath(apiRoutesCache, currentPathname, basePath)) {
396
399
  return next();
397
400
  }
398
- const fullUrl = `http://${req.headers.host || "localhost:3000"}${currentUrl}`;
401
+ const fullUrl = resolveFarmRequestURL(req);
399
402
  const headers = new Headers();
400
403
  for (const [key, value] of Object.entries(req.headers)) {
401
404
  if (value) {