@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
package/dist/vite.cjs CHANGED
@@ -31,6 +31,255 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
31
31
  ));
32
32
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
33
33
 
34
+ // src/utils/runtime-env.ts
35
+ function getFarmRuntimeBindings() {
36
+ const runtimeBindings = globalThis.__env__;
37
+ return runtimeBindings && typeof runtimeBindings === "object" ? runtimeBindings : void 0;
38
+ }
39
+ function readFarmEnvironmentValue(name2) {
40
+ const runtimeValue = getFarmRuntimeBindings()?.[name2];
41
+ if (typeof runtimeValue === "string") return runtimeValue;
42
+ return typeof process !== "undefined" ? process.env?.[name2] : void 0;
43
+ }
44
+ function isFarmDeployedRuntime() {
45
+ if (getFarmRuntimeBindings()) return true;
46
+ return readFarmEnvironmentValue("NODE_ENV") === "production";
47
+ }
48
+ var init_runtime_env = __esm({
49
+ "src/utils/runtime-env.ts"() {
50
+ "use strict";
51
+ __name(getFarmRuntimeBindings, "getFarmRuntimeBindings");
52
+ __name(readFarmEnvironmentValue, "readFarmEnvironmentValue");
53
+ __name(isFarmDeployedRuntime, "isFarmDeployedRuntime");
54
+ }
55
+ });
56
+
57
+ // src/env.ts
58
+ function createBundledEnv(env2, source = getProcessEnv()) {
59
+ const resolved = normalizeResolvedEnv(env2 ?? {});
60
+ const server = {};
61
+ const runtime3 = {};
62
+ for (const [key, value] of Object.entries(resolved.server)) {
63
+ const raw = source[key];
64
+ const type = getRuntimeEnvType(value);
65
+ if (raw !== void 0 && isSameEnvValue(coerceRuntimeEnvValue(raw, type), value)) {
66
+ runtime3[key] = type;
67
+ } else {
68
+ server[key] = value;
69
+ }
70
+ }
71
+ return {
72
+ server,
73
+ public: resolved.public,
74
+ ...Object.keys(runtime3).length > 0 ? { runtime: { server: runtime3 } } : {}
75
+ };
76
+ }
77
+ function createEnvProxy(scope) {
78
+ return new Proxy(
79
+ {},
80
+ {
81
+ get(_target, property) {
82
+ if (typeof property === "symbol") {
83
+ return void 0;
84
+ }
85
+ const env2 = getEnvScope(scope);
86
+ return scope === "server" ? readServerEnvKey(env2, property) : env2[property];
87
+ },
88
+ ownKeys() {
89
+ return Reflect.ownKeys(getEnvScope(scope));
90
+ },
91
+ getOwnPropertyDescriptor(_target, property) {
92
+ const env2 = getEnvScope(scope);
93
+ if (!(property in env2)) {
94
+ return void 0;
95
+ }
96
+ return {
97
+ enumerable: true,
98
+ configurable: true,
99
+ value: env2[property]
100
+ };
101
+ },
102
+ has(_target, property) {
103
+ return property in getEnvScope(scope);
104
+ }
105
+ }
106
+ );
107
+ }
108
+ function getEnvScope(scope) {
109
+ const env2 = getCurrentEnv();
110
+ if (scope === "server") {
111
+ assertServerEnvAccess();
112
+ readRuntimeServerEnv(env2);
113
+ }
114
+ return env2[scope] || {};
115
+ }
116
+ function readServerEnvKey(server, key) {
117
+ const value = server[key];
118
+ if (value === void 0) {
119
+ const state = getCurrentEnv()[FARM_ENV_RUNTIME_SYMBOL];
120
+ if (state && key in state.pending && !state.warned.has(key)) {
121
+ state.warned.add(key);
122
+ console.warn(
123
+ `[Farm] Server env "${key}" was set when this app was built but is not set where the server runs, so it reads as undefined. Farm reads server env at runtime and does not store it in the build output; set "${key}" in the server's environment.`
124
+ );
125
+ }
126
+ }
127
+ return value;
128
+ }
129
+ function readRuntimeServerEnv(env2) {
130
+ const state = env2[FARM_ENV_RUNTIME_SYMBOL];
131
+ if (!state) return;
132
+ for (const [key, type] of Object.entries(state.pending)) {
133
+ const raw = readFarmEnvironmentValue(key);
134
+ if (raw === void 0) continue;
135
+ env2.server[key] = coerceRuntimeEnvValue(raw, type);
136
+ delete state.pending[key];
137
+ }
138
+ }
139
+ function getRuntimeEnvType(value) {
140
+ if (typeof value === "number") return "number";
141
+ if (typeof value === "boolean") return "boolean";
142
+ if (value !== null && typeof value === "object" && !(value instanceof Date)) return "json";
143
+ return "string";
144
+ }
145
+ function coerceRuntimeEnvValue(raw, type) {
146
+ if (type === "number") {
147
+ const value = Number(raw);
148
+ return raw.trim() !== "" && Number.isFinite(value) ? value : raw;
149
+ }
150
+ if (type === "boolean") {
151
+ if (/^(true|1)$/i.test(raw.trim())) return true;
152
+ if (/^(false|0|)$/i.test(raw.trim())) return false;
153
+ return raw;
154
+ }
155
+ if (type === "json") {
156
+ try {
157
+ return JSON.parse(raw);
158
+ } catch {
159
+ return raw;
160
+ }
161
+ }
162
+ return raw;
163
+ }
164
+ function isSameEnvValue(left, right) {
165
+ if (Object.is(left, right)) return true;
166
+ if (Array.isArray(left) || Array.isArray(right)) {
167
+ return Array.isArray(left) && Array.isArray(right) && left.length === right.length && left.every((item, index) => isSameEnvValue(item, right[index]));
168
+ }
169
+ if (!isPlainObject(left) || !isPlainObject(right)) return false;
170
+ const keys = Object.keys(left);
171
+ return keys.length === Object.keys(right).length && keys.every(
172
+ (key) => Object.prototype.hasOwnProperty.call(right, key) && isSameEnvValue(left[key], right[key])
173
+ );
174
+ }
175
+ function isPlainObject(value) {
176
+ if (!value || typeof value !== "object") return false;
177
+ const prototype = Object.getPrototypeOf(value);
178
+ return prototype === Object.prototype || prototype === null;
179
+ }
180
+ function prepareEnv(env2) {
181
+ const normalized = normalizeResolvedEnv(env2);
182
+ const runtime3 = env2.runtime?.server;
183
+ if (!isRecord(runtime3) || Object.keys(runtime3).length === 0) return normalized;
184
+ const prepared = { server: { ...normalized.server }, public: normalized.public };
185
+ Object.defineProperty(prepared, FARM_ENV_RUNTIME_SYMBOL, {
186
+ value: {
187
+ pending: { ...runtime3 },
188
+ warned: /* @__PURE__ */ new Set()
189
+ },
190
+ enumerable: false
191
+ });
192
+ return prepared;
193
+ }
194
+ function assertServerEnvAccess() {
195
+ if (typeof window !== "undefined") {
196
+ throw new Error("Farm server env is not available in the browser. Use publicEnv.");
197
+ }
198
+ }
199
+ function getInitialEnv() {
200
+ const injectedEnv = getInjectedEnv();
201
+ if (injectedEnv) {
202
+ return injectedEnv;
203
+ }
204
+ if (typeof window === "undefined" && farmEnvGlobal[FARM_ENV_SYMBOL]) {
205
+ return normalizeResolvedEnv(farmEnvGlobal[FARM_ENV_SYMBOL]);
206
+ }
207
+ return {
208
+ server: {},
209
+ public: getInjectedPublicEnv()
210
+ };
211
+ }
212
+ function getCurrentEnv() {
213
+ if (typeof window === "undefined" && farmEnvGlobal[FARM_ENV_SYMBOL]) {
214
+ return farmEnvGlobal[FARM_ENV_SYMBOL];
215
+ }
216
+ return currentEnv;
217
+ }
218
+ function getInjectedEnv() {
219
+ try {
220
+ if (typeof __FARM_ENV__ !== "undefined" && __FARM_ENV__) {
221
+ return prepareEnv(__FARM_ENV__);
222
+ }
223
+ } catch {
224
+ }
225
+ return null;
226
+ }
227
+ function getInjectedPublicEnv() {
228
+ try {
229
+ if (typeof __FARM_PUBLIC_ENV__ !== "undefined" && __FARM_PUBLIC_ENV__) {
230
+ return __FARM_PUBLIC_ENV__;
231
+ }
232
+ } catch {
233
+ }
234
+ return {};
235
+ }
236
+ function normalizeResolvedEnv(env2) {
237
+ return {
238
+ server: isRecord(env2.server) ? env2.server : {},
239
+ public: isRecord(env2.public) ? env2.public : {}
240
+ };
241
+ }
242
+ function isRecord(value) {
243
+ return !!value && typeof value === "object" && !Array.isArray(value);
244
+ }
245
+ function getProcessEnv() {
246
+ if (typeof process !== "undefined" && process.env) {
247
+ return process.env;
248
+ }
249
+ return {};
250
+ }
251
+ var FARM_ENV_SYMBOL, FARM_ENV_RUNTIME_SYMBOL, farmEnvGlobal, currentEnv, env, publicEnv;
252
+ var init_env = __esm({
253
+ "src/env.ts"() {
254
+ "use strict";
255
+ init_runtime_env();
256
+ FARM_ENV_SYMBOL = /* @__PURE__ */ Symbol.for("farm.env");
257
+ FARM_ENV_RUNTIME_SYMBOL = /* @__PURE__ */ Symbol.for("farm.env.runtime");
258
+ farmEnvGlobal = globalThis;
259
+ currentEnv = getInitialEnv();
260
+ __name(createBundledEnv, "createBundledEnv");
261
+ env = createEnvProxy("server");
262
+ publicEnv = createEnvProxy("public");
263
+ __name(createEnvProxy, "createEnvProxy");
264
+ __name(getEnvScope, "getEnvScope");
265
+ __name(readServerEnvKey, "readServerEnvKey");
266
+ __name(readRuntimeServerEnv, "readRuntimeServerEnv");
267
+ __name(getRuntimeEnvType, "getRuntimeEnvType");
268
+ __name(coerceRuntimeEnvValue, "coerceRuntimeEnvValue");
269
+ __name(isSameEnvValue, "isSameEnvValue");
270
+ __name(isPlainObject, "isPlainObject");
271
+ __name(prepareEnv, "prepareEnv");
272
+ __name(assertServerEnvAccess, "assertServerEnvAccess");
273
+ __name(getInitialEnv, "getInitialEnv");
274
+ __name(getCurrentEnv, "getCurrentEnv");
275
+ __name(getInjectedEnv, "getInjectedEnv");
276
+ __name(getInjectedPublicEnv, "getInjectedPublicEnv");
277
+ __name(normalizeResolvedEnv, "normalizeResolvedEnv");
278
+ __name(isRecord, "isRecord");
279
+ __name(getProcessEnv, "getProcessEnv");
280
+ }
281
+ });
282
+
34
283
  // src/app-markdown-config.ts
35
284
  function resolveMdxConfig(config) {
36
285
  return {
@@ -152,8 +401,16 @@ async function createMarkdownMirrorResponse(options) {
152
401
  if (!hasMarkdownExtension) {
153
402
  headersOut.set("Vary", "Accept");
154
403
  }
404
+ for (const token of pageResponse.headers.get("vary")?.split(",") ?? []) {
405
+ const name2 = token.trim();
406
+ if (name2 && name2.toLowerCase() !== "accept") appendHeaderToken(headersOut, "Vary", name2);
407
+ }
408
+ const pageCacheControl = pageResponse.headers.get("cache-control");
155
409
  const cache = target.route?.cache ?? options.config?.cache ?? false;
156
- headersOut.set("Cache-Control", createMarkdownCacheHeader(cache));
410
+ headersOut.set(
411
+ "Cache-Control",
412
+ pageCacheControl && isPrivateCacheControl(pageCacheControl) ? pageCacheControl : createMarkdownCacheHeader(cache)
413
+ );
157
414
  return new Response(options.request.method === "HEAD" ? null : markdown, {
158
415
  status: pageResponse.status,
159
416
  headers: headersOut
@@ -304,6 +561,17 @@ function isFarmMarkdownMirrorExposed(config, pathname) {
304
561
  function matchesFarmMarkdownRoutePattern(pattern, pathname) {
305
562
  return routeMatches(pattern, pathname);
306
563
  }
564
+ function appendHeaderToken(headers, name2, token) {
565
+ const current = headers.get(name2);
566
+ if (!current) {
567
+ headers.set(name2, token);
568
+ return;
569
+ }
570
+ const tokens = current.split(",").map((value) => value.trim().toLowerCase());
571
+ if (!tokens.includes(token.toLowerCase())) {
572
+ headers.set(name2, `${current}, ${token}`);
573
+ }
574
+ }
307
575
  function findExposedMarkdownRoute(config, pathname) {
308
576
  if (config.expose === true) {
309
577
  return null;
@@ -335,6 +603,12 @@ function isHtmlResponse(response) {
335
603
  const contentType = response.headers.get("content-type") ?? "";
336
604
  return contentType.includes("text/html");
337
605
  }
606
+ function isPrivateCacheControl(value) {
607
+ return value.split(",").some((directive) => {
608
+ const name2 = directive.split("=", 1)[0].trim().toLowerCase();
609
+ return name2 === "private" || name2 === "no-store";
610
+ });
611
+ }
338
612
  function createMarkdownCacheHeader(cache) {
339
613
  if (cache === false || cache <= 0) {
340
614
  return "no-store";
@@ -487,9 +761,11 @@ var init_markdown = __esm({
487
761
  __name(getFarmMarkdownAlternatePath, "getFarmMarkdownAlternatePath");
488
762
  __name(isFarmMarkdownMirrorExposed, "isFarmMarkdownMirrorExposed");
489
763
  __name(matchesFarmMarkdownRoutePattern, "matchesFarmMarkdownRoutePattern");
764
+ __name(appendHeaderToken, "appendHeaderToken");
490
765
  __name(findExposedMarkdownRoute, "findExposedMarkdownRoute");
491
766
  __name(routeMatches, "routeMatches");
492
767
  __name(isHtmlResponse, "isHtmlResponse");
768
+ __name(isPrivateCacheControl, "isPrivateCacheControl");
493
769
  __name(createMarkdownCacheHeader, "createMarkdownCacheHeader");
494
770
  __name(extractHtmlTitle, "extractHtmlTitle");
495
771
  __name(extractHtmlBody, "extractHtmlBody");
@@ -1193,29 +1469,6 @@ var init_secret_compare = __esm({
1193
1469
  }
1194
1470
  });
1195
1471
 
1196
- // src/utils/runtime-env.ts
1197
- function getFarmRuntimeBindings() {
1198
- const runtimeBindings = globalThis.__env__;
1199
- return runtimeBindings && typeof runtimeBindings === "object" ? runtimeBindings : void 0;
1200
- }
1201
- function readFarmEnvironmentValue(name2) {
1202
- const runtimeValue = getFarmRuntimeBindings()?.[name2];
1203
- if (typeof runtimeValue === "string") return runtimeValue;
1204
- return typeof process !== "undefined" ? process.env?.[name2] : void 0;
1205
- }
1206
- function isFarmDeployedRuntime() {
1207
- if (getFarmRuntimeBindings()) return true;
1208
- return readFarmEnvironmentValue("NODE_ENV") === "production";
1209
- }
1210
- var init_runtime_env = __esm({
1211
- "src/utils/runtime-env.ts"() {
1212
- "use strict";
1213
- __name(getFarmRuntimeBindings, "getFarmRuntimeBindings");
1214
- __name(readFarmEnvironmentValue, "readFarmEnvironmentValue");
1215
- __name(isFarmDeployedRuntime, "isFarmDeployedRuntime");
1216
- }
1217
- });
1218
-
1219
1472
  // src/utils/decode.ts
1220
1473
  function decodeRouteSegment(segment) {
1221
1474
  try {
@@ -4470,7 +4723,7 @@ function mergeFarmLayerConfig(base, override) {
4470
4723
  output[key] = mergeConfigListResolvers(output[key], value);
4471
4724
  continue;
4472
4725
  }
4473
- if (isPlainObject(output[key]) && isPlainObject(value)) {
4726
+ if (isPlainObject2(output[key]) && isPlainObject2(value)) {
4474
4727
  output[key] = mergePlainObjects(output[key], value);
4475
4728
  continue;
4476
4729
  }
@@ -4482,7 +4735,7 @@ function mergePlainObjects(base, override) {
4482
4735
  const output = { ...base };
4483
4736
  for (const [key, value] of Object.entries(override)) {
4484
4737
  if (value === void 0) continue;
4485
- output[key] = isPlainObject(output[key]) && isPlainObject(value) ? mergePlainObjects(output[key], value) : value;
4738
+ output[key] = isPlainObject2(output[key]) && isPlainObject2(value) ? mergePlainObjects(output[key], value) : value;
4486
4739
  }
4487
4740
  return output;
4488
4741
  }
@@ -4497,7 +4750,7 @@ function toArray(value) {
4497
4750
  if (value === void 0 || value === null) return [];
4498
4751
  return Array.isArray(value) ? value : [value];
4499
4752
  }
4500
- function isPlainObject(value) {
4753
+ function isPlainObject2(value) {
4501
4754
  if (!value || typeof value !== "object" || Array.isArray(value)) return false;
4502
4755
  const prototype = Object.getPrototypeOf(value);
4503
4756
  return prototype === Object.prototype || prototype === null;
@@ -4574,7 +4827,7 @@ var init_layers = __esm({
4574
4827
  __name(mergeConfigListResolvers, "mergeConfigListResolvers");
4575
4828
  __name(resolveConfigList, "resolveConfigList");
4576
4829
  __name(toArray, "toArray");
4577
- __name(isPlainObject, "isPlainObject");
4830
+ __name(isPlainObject2, "isPlainObject");
4578
4831
  __name(isPathLayerSource, "isPathLayerSource");
4579
4832
  __name(normalizeRealPath, "normalizeRealPath");
4580
4833
  }
@@ -5359,6 +5612,8 @@ var init_cache = __esm({
5359
5612
  constructor(config = {}) {
5360
5613
  this.entries = /* @__PURE__ */ new Map();
5361
5614
  this.inflight = /* @__PURE__ */ new Map();
5615
+ /** Local entries by tag, so tag counts and pruning never scan unrelated entries. */
5616
+ this.entriesByTag = /* @__PURE__ */ new Map();
5362
5617
  this.invalidatedTagVersions = /* @__PURE__ */ new Map();
5363
5618
  this.activeGenerations = /* @__PURE__ */ new Set();
5364
5619
  this.version = 0;
@@ -5377,6 +5632,7 @@ var init_cache = __esm({
5377
5632
  configure(config = {}) {
5378
5633
  this.generation++;
5379
5634
  this.entries.clear();
5635
+ this.entriesByTag.clear();
5380
5636
  this.inflight.clear();
5381
5637
  this.invalidatedTagVersions.clear();
5382
5638
  this.activeGenerations.clear();
@@ -5543,14 +5799,12 @@ var init_cache = __esm({
5543
5799
  return entry;
5544
5800
  }
5545
5801
  delete(key) {
5546
- const deleted = this.entries.delete(key);
5547
- if (deleted) this.pruneInvalidatedTagVersions();
5802
+ const deleted = this.deleteLocalEntry(key);
5548
5803
  emitFarmEvent({ type: "cache.delete", key, deleted });
5549
5804
  return deleted;
5550
5805
  }
5551
5806
  async deleteAsync(key) {
5552
- const deleted = this.entries.delete(key);
5553
- if (deleted) this.pruneInvalidatedTagVersions();
5807
+ const deleted = this.deleteLocalEntry(key);
5554
5808
  if (this.adapter) {
5555
5809
  await this.adapter.delete(this.createAdapterKey(key));
5556
5810
  }
@@ -5561,6 +5815,7 @@ var init_cache = __esm({
5561
5815
  const count = this.entries.size;
5562
5816
  this.generation++;
5563
5817
  this.entries.clear();
5818
+ this.entriesByTag.clear();
5564
5819
  this.inflight.clear();
5565
5820
  this.invalidatedTagVersions.clear();
5566
5821
  this.activeGenerations.clear();
@@ -5646,23 +5901,32 @@ var init_cache = __esm({
5646
5901
  return cached.value;
5647
5902
  }
5648
5903
  const inflight = this.inflight.get(key);
5649
- if (inflight) {
5904
+ if (inflight && !this.wasInvalidatedSince(inflight.tags, inflight.startVersion)) {
5650
5905
  emitFarmEvent({ type: "cache.dedupe", key });
5651
- return inflight;
5906
+ return inflight.promise;
5652
5907
  }
5653
5908
  const tags = Array.from(normalizeCacheOptionsTags(options));
5654
5909
  const generation = this.generation;
5910
+ const startVersion = this.version;
5655
5911
  const promise = this.fillCacheEntry(key, producer, options, tags, generation).catch((error) => {
5656
5912
  emitFarmEvent({ type: "cache.error", key, operation: "set", error });
5657
5913
  throw error;
5658
5914
  }).finally(() => {
5659
- if (this.inflight.get(key) === promise) {
5915
+ if (this.inflight.get(key)?.promise === promise) {
5660
5916
  this.inflight.delete(key);
5661
5917
  }
5662
5918
  });
5663
- this.inflight.set(key, promise);
5919
+ this.inflight.set(key, { promise, tags, startVersion });
5664
5920
  return promise;
5665
5921
  }
5922
+ /** A fill that started before one of its tags was invalidated cannot satisfy later readers. */
5923
+ wasInvalidatedSince(tags, version2) {
5924
+ for (const tag of tags) {
5925
+ const invalidatedVersion = this.invalidatedTagVersions.get(tag);
5926
+ if (invalidatedVersion !== void 0 && invalidatedVersion > version2) return true;
5927
+ }
5928
+ return false;
5929
+ }
5666
5930
  async fillCacheEntry(key, producer, options, tags, generation) {
5667
5931
  const adapter = this.adapter;
5668
5932
  const namespace = this.namespace;
@@ -5703,7 +5967,7 @@ var init_cache = __esm({
5703
5967
  return value;
5704
5968
  } finally {
5705
5969
  this.activeGenerations.delete(activeGeneration);
5706
- this.pruneInvalidatedTagVersions();
5970
+ this.pruneInvalidatedTagVersions(activeGeneration.tags);
5707
5971
  if (leaseToken && adapter?.releaseLease) {
5708
5972
  try {
5709
5973
  await adapter.releaseLease(leaseKey, leaseToken);
@@ -5748,18 +6012,9 @@ var init_cache = __esm({
5748
6012
  }
5749
6013
  return void 0;
5750
6014
  }
5751
- countEntriesForTag(tag) {
5752
- let count = 0;
5753
- for (const entry of this.entries.values()) {
5754
- if (entry.tags.has(tag)) {
5755
- count++;
5756
- }
5757
- }
5758
- return count;
5759
- }
5760
6015
  countEntriesForTags(tags) {
5761
6016
  let count = 0;
5762
- for (const entry of this.entries.values()) {
6017
+ for (const entry of this.entriesByTag.get(tags[0]) ?? []) {
5763
6018
  if (tags.every((tag) => entry.tags.has(tag))) {
5764
6019
  count++;
5765
6020
  }
@@ -5767,10 +6022,10 @@ var init_cache = __esm({
5767
6022
  return count;
5768
6023
  }
5769
6024
  invalidateTag(normalizedTag) {
5770
- const count = this.countEntriesForTag(normalizedTag);
6025
+ const count = this.entriesByTag.get(normalizedTag)?.size ?? 0;
5771
6026
  this.invalidatedTagVersions.delete(normalizedTag);
5772
6027
  this.invalidatedTagVersions.set(normalizedTag, ++this.version);
5773
- this.pruneInvalidatedTagVersions();
6028
+ this.pruneInvalidatedTagVersions([normalizedTag]);
5774
6029
  return count;
5775
6030
  }
5776
6031
  toPublicEntry(entry) {
@@ -5800,19 +6055,51 @@ var init_cache = __esm({
5800
6055
  this.entries.set(key, entry);
5801
6056
  }
5802
6057
  storeLocalEntry(entry) {
5803
- this.entries.delete(entry.key);
6058
+ const removed = [];
6059
+ const replaced = this.detachLocalEntry(entry.key);
6060
+ if (replaced) removed.push(replaced);
5804
6061
  this.entries.set(entry.key, entry);
6062
+ for (const tag of entry.tags) {
6063
+ let tagged = this.entriesByTag.get(tag);
6064
+ if (!tagged) this.entriesByTag.set(tag, tagged = /* @__PURE__ */ new Set());
6065
+ tagged.add(entry);
6066
+ }
5805
6067
  while (this.entries.size > this.maxEntries) {
5806
6068
  const oldestKey = this.entries.keys().next().value;
5807
6069
  if (oldestKey === void 0) break;
5808
- this.entries.delete(oldestKey);
6070
+ removed.push(this.detachLocalEntry(oldestKey));
5809
6071
  }
5810
- this.pruneInvalidatedTagVersions();
6072
+ for (const removedEntry of removed) this.pruneInvalidatedTagVersions(removedEntry.tags);
6073
+ }
6074
+ deleteLocalEntry(key) {
6075
+ const entry = this.detachLocalEntry(key);
6076
+ if (!entry) return false;
6077
+ this.pruneInvalidatedTagVersions(entry.tags);
6078
+ return true;
5811
6079
  }
5812
- pruneInvalidatedTagVersions() {
5813
- tags: for (const [tag, invalidatedVersion] of this.invalidatedTagVersions) {
5814
- for (const entry of this.entries.values()) {
5815
- if (entry.tags.has(tag) && entry.createdVersion < invalidatedVersion) continue tags;
6080
+ detachLocalEntry(key) {
6081
+ const entry = this.entries.get(key);
6082
+ if (!entry) return void 0;
6083
+ this.entries.delete(key);
6084
+ for (const tag of entry.tags) {
6085
+ const tagged = this.entriesByTag.get(tag);
6086
+ if (!tagged) continue;
6087
+ tagged.delete(entry);
6088
+ if (tagged.size === 0) this.entriesByTag.delete(tag);
6089
+ }
6090
+ return entry;
6091
+ }
6092
+ /**
6093
+ * Drop invalidation versions that no local entry or active fill can be stale against.
6094
+ * Callers pass only the tags whose dependents just changed, so the cost is bounded by
6095
+ * the entries sharing those tags rather than by the whole cache.
6096
+ */
6097
+ pruneInvalidatedTagVersions(tags) {
6098
+ tags: for (const tag of tags) {
6099
+ const invalidatedVersion = this.invalidatedTagVersions.get(tag);
6100
+ if (invalidatedVersion === void 0) continue;
6101
+ for (const entry of this.entriesByTag.get(tag) ?? []) {
6102
+ if (entry.createdVersion < invalidatedVersion) continue tags;
5816
6103
  }
5817
6104
  for (const generation of this.activeGenerations) {
5818
6105
  if (generation.tags.has(tag) && generation.createdVersion < invalidatedVersion)
@@ -6207,6 +6494,7 @@ function createProgrammaticPageComponent(route, rendererRuntime) {
6207
6494
  }
6208
6495
  return rendererRuntime.createElement(...args);
6209
6496
  }, "createElement");
6497
+ const markFunctionComponent = /* @__PURE__ */ __name((component) => rendererRuntime?.markFunctionComponent?.(component) ?? component, "markFunctionComponent");
6210
6498
  const Component = route.component;
6211
6499
  if (route.pending) {
6212
6500
  const PendingComponent = route.pending;
@@ -6228,7 +6516,9 @@ function createProgrammaticPageComponent(route, rendererRuntime) {
6228
6516
  throw error;
6229
6517
  }
6230
6518
  }, "FarmProgrammaticPageContent");
6231
- const PageContent = FarmProgrammaticPageContent2;
6519
+ const PageContent = markFunctionComponent(
6520
+ FarmProgrammaticPageContent2
6521
+ );
6232
6522
  const FarmProgrammaticPage = /* @__PURE__ */ __name(function FarmProgrammaticPage2(props) {
6233
6523
  return createElement2(
6234
6524
  rendererRuntime.Suspense,
@@ -6238,7 +6528,7 @@ function createProgrammaticPageComponent(route, rendererRuntime) {
6238
6528
  createElement2(PageContent, props)
6239
6529
  );
6240
6530
  }, "FarmProgrammaticPage");
6241
- return FarmProgrammaticPage;
6531
+ return markFunctionComponent(FarmProgrammaticPage);
6242
6532
  }
6243
6533
  const FarmProgrammaticPageContent = /* @__PURE__ */ __name(async function FarmProgrammaticPageContent2(props) {
6244
6534
  try {
@@ -6257,7 +6547,7 @@ function createProgrammaticPageComponent(route, rendererRuntime) {
6257
6547
  throw error;
6258
6548
  }
6259
6549
  }, "FarmProgrammaticPageContent");
6260
- return FarmProgrammaticPageContent;
6550
+ return markFunctionComponent(FarmProgrammaticPageContent);
6261
6551
  }
6262
6552
  function readProgrammaticRouteProps(route, props, resources) {
6263
6553
  if (isProgrammaticRoutePropsResolved(props)) {
@@ -8942,7 +9232,7 @@ function serializeFarmLlmsTxt(value) {
8942
9232
  return value.endsWith("\n") ? value : `${value}
8943
9233
  `;
8944
9234
  }
8945
- if (!isRecord2(value)) {
9235
+ if (!isRecord3(value)) {
8946
9236
  throw new TypeError("llms.ts must return llms.txt text, an llms.txt object, or a Response");
8947
9237
  }
8948
9238
  const title = requireText(value.title, "llms.ts must return a non-empty title");
@@ -8955,7 +9245,7 @@ function serializeFarmLlmsTxt(value) {
8955
9245
  if (summary?.trim()) blocks.push(`> ${toSingleLine(summary)}`);
8956
9246
  if (details?.trim()) blocks.push(details.trim());
8957
9247
  for (const [sectionIndex, section] of (value.sections ?? []).entries()) {
8958
- if (!isRecord2(section)) {
9248
+ if (!isRecord3(section)) {
8959
9249
  throw new TypeError(`llms.ts section ${sectionIndex} must be an object`);
8960
9250
  }
8961
9251
  const sectionTitle = requireText(
@@ -8967,7 +9257,7 @@ function serializeFarmLlmsTxt(value) {
8967
9257
  }
8968
9258
  const links = section.links.map((link, linkIndex) => {
8969
9259
  const where = `llms.ts section "${sectionTitle}" link ${linkIndex}`;
8970
- if (!isRecord2(link)) throw new TypeError(`${where} must be an object`);
9260
+ if (!isRecord3(link)) throw new TypeError(`${where} must be an object`);
8971
9261
  const linkTitle = requireText(link.title, `${where} must include a non-empty title`);
8972
9262
  const url = requireText(link.url, `${where} must include a non-empty url`);
8973
9263
  const description = optionalText(link.description, `${where} description must be a string`);
@@ -9053,10 +9343,10 @@ async function mapWithConcurrency(items, limit, run) {
9053
9343
  return results;
9054
9344
  }
9055
9345
  function readMetadataTitle(metadata) {
9056
- if (!isRecord2(metadata)) return void 0;
9346
+ if (!isRecord3(metadata)) return void 0;
9057
9347
  const { title } = metadata;
9058
9348
  if (typeof title === "string") return title.trim() || void 0;
9059
- if (isRecord2(title)) {
9349
+ if (isRecord3(title)) {
9060
9350
  for (const key of ["absolute", "default"]) {
9061
9351
  const value = title[key];
9062
9352
  if (typeof value === "string" && value.trim()) return value.trim();
@@ -9065,7 +9355,7 @@ function readMetadataTitle(metadata) {
9065
9355
  return void 0;
9066
9356
  }
9067
9357
  function readMetadataString(metadata, key) {
9068
- if (!isRecord2(metadata)) return void 0;
9358
+ if (!isRecord3(metadata)) return void 0;
9069
9359
  const value = metadata[key];
9070
9360
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
9071
9361
  }
@@ -9097,7 +9387,7 @@ function optionalText(value, message) {
9097
9387
  if (typeof value !== "string") throw new TypeError(message);
9098
9388
  return value;
9099
9389
  }
9100
- function isRecord2(value) {
9390
+ function isRecord3(value) {
9101
9391
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
9102
9392
  }
9103
9393
  var init_llms_txt = __esm({
@@ -9123,7 +9413,7 @@ var init_llms_txt = __esm({
9123
9413
  __name(escapeLinkUrl, "escapeLinkUrl");
9124
9414
  __name(requireText, "requireText");
9125
9415
  __name(optionalText, "optionalText");
9126
- __name(isRecord2, "isRecord");
9416
+ __name(isRecord3, "isRecord");
9127
9417
  }
9128
9418
  });
9129
9419
 
@@ -10346,116 +10636,6 @@ var init_config3 = __esm({
10346
10636
  }
10347
10637
  });
10348
10638
 
10349
- // src/env.ts
10350
- function createEnvProxy(scope) {
10351
- return new Proxy(
10352
- {},
10353
- {
10354
- get(_target, property) {
10355
- if (typeof property === "symbol") {
10356
- return void 0;
10357
- }
10358
- const env2 = getEnvScope(scope);
10359
- return env2[property];
10360
- },
10361
- ownKeys() {
10362
- return Reflect.ownKeys(getEnvScope(scope));
10363
- },
10364
- getOwnPropertyDescriptor(_target, property) {
10365
- const env2 = getEnvScope(scope);
10366
- if (!(property in env2)) {
10367
- return void 0;
10368
- }
10369
- return {
10370
- enumerable: true,
10371
- configurable: true,
10372
- value: env2[property]
10373
- };
10374
- },
10375
- has(_target, property) {
10376
- return property in getEnvScope(scope);
10377
- }
10378
- }
10379
- );
10380
- }
10381
- function getEnvScope(scope) {
10382
- if (scope === "server") {
10383
- assertServerEnvAccess();
10384
- }
10385
- return getCurrentEnv()[scope] || {};
10386
- }
10387
- function assertServerEnvAccess() {
10388
- if (typeof window !== "undefined") {
10389
- throw new Error("Farm server env is not available in the browser. Use publicEnv.");
10390
- }
10391
- }
10392
- function getInitialEnv() {
10393
- const injectedEnv = getInjectedEnv();
10394
- if (injectedEnv) {
10395
- return injectedEnv;
10396
- }
10397
- if (typeof window === "undefined" && farmEnvGlobal[FARM_ENV_SYMBOL]) {
10398
- return normalizeResolvedEnv(farmEnvGlobal[FARM_ENV_SYMBOL]);
10399
- }
10400
- return {
10401
- server: {},
10402
- public: getInjectedPublicEnv()
10403
- };
10404
- }
10405
- function getCurrentEnv() {
10406
- if (typeof window === "undefined" && farmEnvGlobal[FARM_ENV_SYMBOL]) {
10407
- return farmEnvGlobal[FARM_ENV_SYMBOL];
10408
- }
10409
- return currentEnv;
10410
- }
10411
- function getInjectedEnv() {
10412
- try {
10413
- if (typeof __FARM_ENV__ !== "undefined" && __FARM_ENV__) {
10414
- return normalizeResolvedEnv(__FARM_ENV__);
10415
- }
10416
- } catch {
10417
- }
10418
- return null;
10419
- }
10420
- function getInjectedPublicEnv() {
10421
- try {
10422
- if (typeof __FARM_PUBLIC_ENV__ !== "undefined" && __FARM_PUBLIC_ENV__) {
10423
- return __FARM_PUBLIC_ENV__;
10424
- }
10425
- } catch {
10426
- }
10427
- return {};
10428
- }
10429
- function normalizeResolvedEnv(env2) {
10430
- return {
10431
- server: isRecord4(env2.server) ? env2.server : {},
10432
- public: isRecord4(env2.public) ? env2.public : {}
10433
- };
10434
- }
10435
- function isRecord4(value) {
10436
- return !!value && typeof value === "object" && !Array.isArray(value);
10437
- }
10438
- var FARM_ENV_SYMBOL, farmEnvGlobal, currentEnv, env, publicEnv;
10439
- var init_env = __esm({
10440
- "src/env.ts"() {
10441
- "use strict";
10442
- FARM_ENV_SYMBOL = /* @__PURE__ */ Symbol.for("farm.env");
10443
- farmEnvGlobal = globalThis;
10444
- currentEnv = getInitialEnv();
10445
- env = createEnvProxy("server");
10446
- publicEnv = createEnvProxy("public");
10447
- __name(createEnvProxy, "createEnvProxy");
10448
- __name(getEnvScope, "getEnvScope");
10449
- __name(assertServerEnvAccess, "assertServerEnvAccess");
10450
- __name(getInitialEnv, "getInitialEnv");
10451
- __name(getCurrentEnv, "getCurrentEnv");
10452
- __name(getInjectedEnv, "getInjectedEnv");
10453
- __name(getInjectedPublicEnv, "getInjectedPublicEnv");
10454
- __name(normalizeResolvedEnv, "normalizeResolvedEnv");
10455
- __name(isRecord4, "isRecord");
10456
- }
10457
- });
10458
-
10459
10639
  // src/plugin-dependencies.ts
10460
10640
  function pluginShortName(name2) {
10461
10641
  return name2.slice(Math.max(name2.lastIndexOf(":"), name2.lastIndexOf("/")) + 1);
@@ -13465,6 +13645,7 @@ function createFarmDocsHandler(docs, options) {
13465
13645
  if (!isFarmDocsRequest(docs, request2)) return null;
13466
13646
  const page2 = loadPage(contentDir, docs, request2);
13467
13647
  if (!page2) return null;
13648
+ const negotiatesAccept = !requestUrl.pathname.endsWith(".md");
13468
13649
  if (shouldReturnMarkdown(request2)) {
13469
13650
  const origin = new URL(request2.url).origin;
13470
13651
  return omitFarmDocsHeadBody(
@@ -13479,7 +13660,8 @@ function createFarmDocsHandler(docs, options) {
13479
13660
  status: 200,
13480
13661
  headers: {
13481
13662
  "Content-Type": "text/markdown; charset=utf-8",
13482
- "Cache-Control": "public, max-age=60"
13663
+ "Cache-Control": "public, max-age=60",
13664
+ ...negotiatesAccept ? { Vary: "Accept" } : {}
13483
13665
  }
13484
13666
  }
13485
13667
  )
@@ -13509,6 +13691,7 @@ function createFarmDocsHandler(docs, options) {
13509
13691
  headers: {
13510
13692
  "Content-Type": "text/html; charset=utf-8",
13511
13693
  "Cache-Control": "public, s-maxage=60, stale-while-revalidate=300",
13694
+ Vary: "Accept",
13512
13695
  ...fontPreloadHeader ? { Link: fontPreloadHeader } : {}
13513
13696
  }
13514
13697
  }
@@ -17453,6 +17636,7 @@ __export(vite_exports, {
17453
17636
  withFarmRequestTracing: () => withFarmRequestTracing
17454
17637
  });
17455
17638
  module.exports = __toCommonJS(vite_exports);
17639
+ init_env();
17456
17640
 
17457
17641
  // src/app.ts
17458
17642
  init_app_markdown_config();
@@ -19467,7 +19651,7 @@ function resolveImportedModule(importerPath, specifier, root) {
19467
19651
  return { path: resolveImportedModuleSourcePath(importerPath, specifier, root), local: true };
19468
19652
  }
19469
19653
  const aliased = resolveProjectAliasSourcePath(specifier, root);
19470
- if (aliased !== void 0) return { path: aliased, local: true };
19654
+ if (aliased) return { path: aliased, local: true };
19471
19655
  return { path: resolvePackageModuleSourcePath(importerPath, specifier, root), local: false };
19472
19656
  }
19473
19657
  __name(resolveImportedModule, "resolveImportedModule");
@@ -19483,11 +19667,12 @@ function resolveProjectAliasSourcePath(specifier, root) {
19483
19667
  if (!match || alias.prefix.length > match.alias.prefix.length) match = { alias, captured };
19484
19668
  }
19485
19669
  if (!match) return void 0;
19486
- return resolveSourceCandidate(
19670
+ const resolved = resolveSourceCandidate(
19487
19671
  match.alias.targets.map(
19488
19672
  (target) => import_path4.default.normalize(match.alias.wildcard ? target.replace("*", match.captured) : target)
19489
19673
  )
19490
19674
  );
19675
+ return resolved && /\.d\.[cm]?ts$/.test(resolved) ? null : resolved;
19491
19676
  }
19492
19677
  __name(resolveProjectAliasSourcePath, "resolveProjectAliasSourcePath");
19493
19678
  function matchProjectImportAlias(alias, specifier) {
@@ -19894,6 +20079,7 @@ __name(readAltText, "readAltText");
19894
20079
  // src/routing/route-manager.ts
19895
20080
  init_route_runtime();
19896
20081
  init_routing();
20082
+ init_base_path();
19897
20083
 
19898
20084
  // src/redirect-query.ts
19899
20085
  function appendFarmRedirectQuery(destination, search) {
@@ -20970,7 +21156,7 @@ var _RouteManager = class _RouteManager {
20970
21156
  }
20971
21157
  toRoutePathname(pathname) {
20972
21158
  const i18n = this.getI18nConfig();
20973
- return i18n ? stripFarmLocaleFromPathname(pathname, i18n) : pathname;
21159
+ return i18n ? stripFarmLocaleFromPathname(pathname, i18n) : stripFarmBasePath(pathname, this.config.basePath);
20974
21160
  }
20975
21161
  localizeRedirectDestination(destination, locale) {
20976
21162
  if (!locale || !destination.startsWith("/") || destination.startsWith("//")) {
@@ -21470,11 +21656,11 @@ function mergeMetadata(base, next) {
21470
21656
  __name(mergeMetadata, "mergeMetadata");
21471
21657
  function mergeMetadataTitle(base, next) {
21472
21658
  if (next === void 0) return base;
21473
- const parentTemplate = isRecord(base) ? normalizeContent(base.template) : void 0;
21659
+ const parentTemplate = isRecord2(base) ? normalizeContent(base.template) : void 0;
21474
21660
  if (typeof next === "string") {
21475
21661
  return parentTemplate ? applyTitleTemplate(parentTemplate, next) : next;
21476
21662
  }
21477
- if (!isRecord(next)) return next;
21663
+ if (!isRecord2(next)) return next;
21478
21664
  const defaultTitle = normalizeContent(next.default) ?? resolveMetadataTitle(base);
21479
21665
  return {
21480
21666
  ...next,
@@ -21525,8 +21711,8 @@ __name(addMetadataImageReference, "addMetadataImageReference");
21525
21711
  var MARKDOWN_MIME_TYPE = "text/markdown";
21526
21712
  function addMetadataMarkdownAlternate(metadata, href) {
21527
21713
  if (!href) return metadata;
21528
- const alternates = isRecord(metadata.alternates) ? metadata.alternates : {};
21529
- const types = isRecord(alternates.types) ? alternates.types : {};
21714
+ const alternates = isRecord2(metadata.alternates) ? metadata.alternates : {};
21715
+ const types = isRecord2(alternates.types) ? alternates.types : {};
21530
21716
  if (Object.keys(types).some((type) => type.toLowerCase() === MARKDOWN_MIME_TYPE)) {
21531
21717
  return metadata;
21532
21718
  }
@@ -21559,26 +21745,26 @@ function renderMetadataHead(metadata, options = {}) {
21559
21745
  appendMetaName(tags, "creator", resolvedMetadata.creator);
21560
21746
  appendMetaName(tags, "publisher", resolvedMetadata.publisher);
21561
21747
  appendMetaName(tags, "robots", normalizeRobots(resolvedMetadata.robots));
21562
- if (isRecord(resolvedMetadata.robots)) {
21748
+ if (isRecord2(resolvedMetadata.robots)) {
21563
21749
  appendMetaName(tags, "googlebot", normalizeRobots(resolvedMetadata.robots.googleBot));
21564
21750
  }
21565
21751
  const alternates = resolvedMetadata.alternates;
21566
- const explicitCanonical = isRecord(alternates) ? alternates.canonical : void 0;
21752
+ const explicitCanonical = isRecord2(alternates) ? alternates.canonical : void 0;
21567
21753
  const canonicalHref = explicitCanonical != null ? resolveMetadataUrl(explicitCanonical, metadataBase) : options.pathname ? resolveMetadataUrl(sanitizeSelfCanonicalPathname(options.pathname), metadataBase) : void 0;
21568
21754
  if (canonicalHref) {
21569
21755
  appendLink(tags, "canonical", canonicalHref);
21570
21756
  }
21571
- if (isRecord(alternates) && isRecord(alternates.languages)) {
21757
+ if (isRecord2(alternates) && isRecord2(alternates.languages)) {
21572
21758
  for (const [language, href] of Object.entries(alternates.languages)) {
21573
21759
  appendLink(tags, "alternate", resolveMetadataUrl(href, metadataBase), {
21574
21760
  hreflang: language
21575
21761
  });
21576
21762
  }
21577
21763
  }
21578
- if (isRecord(alternates) && isRecord(alternates.types)) {
21764
+ if (isRecord2(alternates) && isRecord2(alternates.types)) {
21579
21765
  for (const [type, value] of Object.entries(alternates.types)) {
21580
21766
  for (const entry of normalizeArray(value)) {
21581
- const link = isRecord(entry) ? entry : { url: entry };
21767
+ const link = isRecord2(entry) ? entry : { url: entry };
21582
21768
  appendLink(tags, "alternate", resolveMetadataUrl(link.url, metadataBase), {
21583
21769
  type,
21584
21770
  title: link.title
@@ -21602,14 +21788,14 @@ function renderMetadataHead(metadata, options = {}) {
21602
21788
  const jsonLdConfig = options.jsonLd === true ? {} : options.jsonLd;
21603
21789
  const jsonLdScript = renderFarmAgentJsonLd(jsonLdConfig, {
21604
21790
  metadataBase,
21605
- siteName: isRecord(resolvedMetadata.openGraph) ? normalizeContent(resolvedMetadata.openGraph.siteName) : void 0,
21791
+ siteName: isRecord2(resolvedMetadata.openGraph) ? normalizeContent(resolvedMetadata.openGraph.siteName) : void 0,
21606
21792
  title: explicitTitle,
21607
21793
  description: normalizeContent(resolvedMetadata.description)
21608
21794
  });
21609
21795
  if (jsonLdScript) tags.push(jsonLdScript);
21610
21796
  }
21611
21797
  for (const entry of normalizeArray(resolvedMetadata.jsonLd)) {
21612
- if (!isRecord(entry)) continue;
21798
+ if (!isRecord2(entry)) continue;
21613
21799
  tags.push(
21614
21800
  `<script type="application/ld+json" ${FARM_METADATA_ATTRIBUTE}>${serializeJsonLd(entry)}</script>`
21615
21801
  );
@@ -21624,7 +21810,7 @@ function renderMetadataHead(metadata, options = {}) {
21624
21810
  }
21625
21811
  __name(renderMetadataHead, "renderMetadataHead");
21626
21812
  function mergeNestedMetadata(base, next) {
21627
- if (isRecord(base) && isRecord(next)) {
21813
+ if (isRecord2(base) && isRecord2(next)) {
21628
21814
  return {
21629
21815
  ...base,
21630
21816
  ...next
@@ -21634,7 +21820,7 @@ function mergeNestedMetadata(base, next) {
21634
21820
  }
21635
21821
  __name(mergeNestedMetadata, "mergeNestedMetadata");
21636
21822
  function appendOpenGraph(tags, openGraph, metadataBase) {
21637
- if (!isRecord(openGraph)) return;
21823
+ if (!isRecord2(openGraph)) return;
21638
21824
  appendMetaProperty(tags, "og:title", openGraph.title);
21639
21825
  appendMetaProperty(tags, "og:description", openGraph.description);
21640
21826
  appendMetaProperty(tags, "og:url", resolveMetadataUrl(openGraph.url, metadataBase));
@@ -21666,7 +21852,7 @@ function appendOpenGraph(tags, openGraph, metadataBase) {
21666
21852
  }
21667
21853
  __name(appendOpenGraph, "appendOpenGraph");
21668
21854
  function appendTwitter(tags, twitter, metadataBase) {
21669
- if (!isRecord(twitter)) return;
21855
+ if (!isRecord2(twitter)) return;
21670
21856
  appendMetaName(tags, "twitter:card", twitter.card);
21671
21857
  appendMetaName(tags, "twitter:site", twitter.site);
21672
21858
  appendMetaName(tags, "twitter:creator", twitter.creator);
@@ -21679,7 +21865,7 @@ function appendTwitter(tags, twitter, metadataBase) {
21679
21865
  }
21680
21866
  __name(appendTwitter, "appendTwitter");
21681
21867
  function appendNamedMetaRecord(tags, record) {
21682
- if (!isRecord(record)) return;
21868
+ if (!isRecord2(record)) return;
21683
21869
  for (const [name2, value] of Object.entries(record)) {
21684
21870
  for (const content of normalizeArray(value)) {
21685
21871
  appendMetaName(tags, name2, content, true);
@@ -21694,7 +21880,7 @@ function appendIcons(tags, icons, metadataBase) {
21694
21880
  appendLink(tags, "icon", resolveMetadataUrl(icons, metadataBase));
21695
21881
  return tags.length > initialTagCount2;
21696
21882
  }
21697
- if (!isRecord(icons)) return false;
21883
+ if (!isRecord2(icons)) return false;
21698
21884
  const initialTagCount = tags.length;
21699
21885
  appendIconList(tags, "icon", icons.icon, metadataBase);
21700
21886
  appendIconList(tags, "shortcut icon", icons.shortcut, metadataBase);
@@ -21709,7 +21895,7 @@ function appendIconList(tags, rel, value, metadataBase) {
21709
21895
  appendLink(tags, rel, resolveMetadataUrl(icon2, metadataBase));
21710
21896
  continue;
21711
21897
  }
21712
- if (!isRecord(icon2)) continue;
21898
+ if (!isRecord2(icon2)) continue;
21713
21899
  appendLink(tags, rel, resolveMetadataUrl(icon2.url, metadataBase), {
21714
21900
  sizes: icon2.sizes,
21715
21901
  type: icon2.type
@@ -21740,7 +21926,7 @@ var VERIFICATION_META_NAMES = [
21740
21926
  ["yandex", "yandex-verification"]
21741
21927
  ];
21742
21928
  function appendVerification(tags, verification) {
21743
- if (!isRecord(verification)) return;
21929
+ if (!isRecord2(verification)) return;
21744
21930
  for (const [key, name2] of VERIFICATION_META_NAMES) {
21745
21931
  for (const token of normalizeArray(verification[key])) {
21746
21932
  appendMetaName(tags, name2, token);
@@ -21766,7 +21952,7 @@ function normalizeMetadataImages(value, metadataBase) {
21766
21952
  if (typeof item === "string") {
21767
21953
  return { url: resolveMetadataUrl(item, metadataBase) || item };
21768
21954
  }
21769
- if (!isRecord(item)) return null;
21955
+ if (!isRecord2(item)) return null;
21770
21956
  const rawUrl = item.url || item.src;
21771
21957
  const url = resolveMetadataUrl(rawUrl, metadataBase);
21772
21958
  if (!url) return null;
@@ -21791,7 +21977,7 @@ function hasMetadataImages(value) {
21791
21977
  __name(hasMetadataImages, "hasMetadataImages");
21792
21978
  function resolveMetadataTitle(title) {
21793
21979
  if (typeof title === "string") return title;
21794
- if (isRecord(title)) {
21980
+ if (isRecord2(title)) {
21795
21981
  return normalizeContent(title.default);
21796
21982
  }
21797
21983
  return void 0;
@@ -21811,7 +21997,7 @@ var ROBOTS_VALUES = [
21811
21997
  ];
21812
21998
  function normalizeRobots(robots) {
21813
21999
  if (typeof robots === "string") return robots;
21814
- if (!isRecord(robots)) return void 0;
22000
+ if (!isRecord2(robots)) return void 0;
21815
22001
  const values = [];
21816
22002
  if (typeof robots.index === "boolean") values.push(robots.index ? "index" : "noindex");
21817
22003
  if (typeof robots.follow === "boolean") values.push(robots.follow ? "follow" : "nofollow");
@@ -21872,10 +22058,10 @@ function normalizeContent(value) {
21872
22058
  return void 0;
21873
22059
  }
21874
22060
  __name(normalizeContent, "normalizeContent");
21875
- function isRecord(value) {
22061
+ function isRecord2(value) {
21876
22062
  return !!value && typeof value === "object" && !Array.isArray(value);
21877
22063
  }
21878
- __name(isRecord, "isRecord");
22064
+ __name(isRecord2, "isRecord");
21879
22065
  function escapeText(value) {
21880
22066
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
21881
22067
  }
@@ -22159,7 +22345,7 @@ async function readFarmI18nCatalogs(config) {
22159
22345
  }
22160
22346
  __name(readFarmI18nCatalogs, "readFarmI18nCatalogs");
22161
22347
  function flattenFarmI18nCatalog(input, source = "i18n catalog") {
22162
- if (!isPlainObject2(input)) {
22348
+ if (!isPlainObject3(input)) {
22163
22349
  throw new Error(`${source} must contain a JSON object at its root.`);
22164
22350
  }
22165
22351
  const output = {};
@@ -22173,7 +22359,7 @@ function flattenFarmI18nCatalog(input, source = "i18n catalog") {
22173
22359
  output[key] = value;
22174
22360
  return;
22175
22361
  }
22176
- if (!isPlainObject2(value)) {
22362
+ if (!isPlainObject3(value)) {
22177
22363
  const key = segments.join(".") || "<root>";
22178
22364
  throw new Error(`${source} message "${key}" must be a string or nested object.`);
22179
22365
  }
@@ -22273,10 +22459,10 @@ function sameSignature(expected, actual) {
22273
22459
  return JSON.stringify(expectedEntries) === JSON.stringify(actualEntries);
22274
22460
  }
22275
22461
  __name(sameSignature, "sameSignature");
22276
- function isPlainObject2(value) {
22462
+ function isPlainObject3(value) {
22277
22463
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
22278
22464
  }
22279
- __name(isPlainObject2, "isPlainObject");
22465
+ __name(isPlainObject3, "isPlainObject");
22280
22466
  function messageOf(error) {
22281
22467
  return error instanceof Error ? error.message : String(error);
22282
22468
  }
@@ -23919,10 +24105,10 @@ function isResponse2(value) {
23919
24105
  ));
23920
24106
  }
23921
24107
  __name(isResponse2, "isResponse");
23922
- function isRecord3(value) {
24108
+ function isRecord4(value) {
23923
24109
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
23924
24110
  }
23925
- __name(isRecord3, "isRecord");
24111
+ __name(isRecord4, "isRecord");
23926
24112
  function resolveCacheControl2(revalidate) {
23927
24113
  if (revalidate === false) {
23928
24114
  return "public, max-age=31536000, immutable";
@@ -23942,7 +24128,7 @@ function serializeSitemap(value) {
23942
24128
  throw new TypeError("sitemap.ts must return an array or a Response");
23943
24129
  }
23944
24130
  const entries = value.map((candidate, index) => {
23945
- if (!isRecord3(candidate) || typeof candidate.url !== "string" || !candidate.url) {
24131
+ if (!isRecord4(candidate) || typeof candidate.url !== "string" || !candidate.url) {
23946
24132
  throw new TypeError(`sitemap.ts entry ${index} must include a non-empty url`);
23947
24133
  }
23948
24134
  return candidate;
@@ -23984,7 +24170,7 @@ function toArray2(value) {
23984
24170
  }
23985
24171
  __name(toArray2, "toArray");
23986
24172
  function serializeRobots(value) {
23987
- if (!isRecord3(value)) {
24173
+ if (!isRecord4(value)) {
23988
24174
  throw new TypeError("robots.ts must return a robots object or a Response");
23989
24175
  }
23990
24176
  const robots = value;
@@ -23993,7 +24179,7 @@ function serializeRobots(value) {
23993
24179
  throw new TypeError("robots.ts must return at least one rule");
23994
24180
  }
23995
24181
  const sections = rules.map((rule, index) => {
23996
- if (!isRecord3(rule)) {
24182
+ if (!isRecord4(rule)) {
23997
24183
  throw new TypeError(`robots.ts rule ${index} must be an object`);
23998
24184
  }
23999
24185
  const userAgents = toArray2(rule.userAgent).filter(
@@ -24017,7 +24203,7 @@ function serializeRobots(value) {
24017
24203
  }
24018
24204
  __name(serializeRobots, "serializeRobots");
24019
24205
  function serializeManifest(value) {
24020
- if (!isRecord3(value)) {
24206
+ if (!isRecord4(value)) {
24021
24207
  throw new TypeError("manifest.ts must return a manifest object or a Response");
24022
24208
  }
24023
24209
  return `${JSON.stringify(value, null, 2)}
@@ -25079,7 +25265,7 @@ _setFarmThemeServerSnapshotResolver(() => {
25079
25265
  });
25080
25266
 
25081
25267
  // package.json
25082
- var version = "0.1.15";
25268
+ var version = "0.1.17";
25083
25269
 
25084
25270
  // src/version.ts
25085
25271
  var FARM_VERSION = version;
@@ -25369,7 +25555,7 @@ function createPPRRefreshScript() {
25369
25555
  __name(createPPRRefreshScript, "createPPRRefreshScript");
25370
25556
  function createPreHydrationClickQueueScript() {
25371
25557
  const selector = JSON.stringify(FARM_ISLAND_REPLAYABLE_SELECTOR);
25372
- return `<script>(function(){if(window.__FARM_PREHYDRATION_CLICK_QUEUE__)return;var queue=[];window.__FARM_PREHYDRATION_CLICK_QUEUE__=queue;window.__FARM_HYDRATED__=false;document.documentElement.dataset.farmHydrated="false";function isModified(event){return !!(event.metaKey||event.altKey||event.ctrlKey||event.shiftKey)}function inHydrated(node){return !!(node&&node.closest&&node.closest('[data-farm-island-hydrated="true"]'))}function closestQueuedTarget(target){while(target&&target!==document.documentElement){if(target.matches&&target.matches(${selector}))return target;target=target.parentElement}return null}function announce(target,kind){document.dispatchEvent(new CustomEvent("farm:island-interaction",{detail:{target:target,kind:kind||null}}))}function hold(event,target,kind){if(queue.some(function(item){return item.target===target}))return;queue.push({target:target,kind:kind,createdAt:Date.now()});announce(target,kind);event.preventDefault();event.stopImmediatePropagation()}document.addEventListener("click",function(event){if(window.__FARM_HYDRATED__)return;if(event.defaultPrevented||event.button!==0||isModified(event))return;var target=closestQueuedTarget(event.target);if(!target||target.closest&&target.closest("a[href]")||inHydrated(target))return;hold(event,target,"click")},true);document.addEventListener("submit",function(event){if(window.__FARM_HYDRATED__)return;if(event.defaultPrevented)return;var form=event.target;if(!form||form.nodeName!=="FORM"||inHydrated(form))return;hold(event,form,"submit")},true);function observe(event){if(window.__FARM_HYDRATED__)return;var target=event.target;if(!(target&&target.closest)||inHydrated(target))return;announce(target,null)}document.addEventListener("pointerdown",observe,true);document.addEventListener("focusin",observe,true);})();</script>`;
25558
+ return `<script>(function(){if(window.__FARM_PREHYDRATION_CLICK_QUEUE__)return;var queue=[];window.__FARM_PREHYDRATION_CLICK_QUEUE__=queue;window.__FARM_HYDRATED__=false;document.documentElement.dataset.farmHydrated="false";function isModified(event){return !!(event.metaKey||event.altKey||event.ctrlKey||event.shiftKey)}function inHydrated(node){return !!(node&&node.closest&&node.closest('[data-farm-island-hydrated="true"]'))}function closestQueuedTarget(target){while(target&&target!==document.documentElement){if(target.matches&&target.matches(${selector}))return target;target=target.parentElement}return null}function announce(target,kind){document.dispatchEvent(new CustomEvent("farm:island-interaction",{detail:{target:target,kind:kind||null}}))}function hold(event,target,kind){if(!queue.some(function(item){return item.target===target})){queue.push({target:target,kind:kind,createdAt:Date.now()});announce(target,kind)}event.preventDefault();event.stopImmediatePropagation()}document.addEventListener("click",function(event){if(window.__FARM_HYDRATED__)return;if(event.defaultPrevented||event.button!==0||isModified(event))return;var target=closestQueuedTarget(event.target);if(!target||target.closest&&target.closest("a[href]")||inHydrated(target))return;hold(event,target,"click")},true);document.addEventListener("submit",function(event){if(window.__FARM_HYDRATED__)return;if(event.defaultPrevented)return;var form=event.target;if(!form||form.nodeName!=="FORM"||inHydrated(form))return;hold(event,form,"submit")},true);function observe(event){if(window.__FARM_HYDRATED__)return;var target=event.target;if(!(target&&target.closest)||inHydrated(target))return;announce(target,null)}document.addEventListener("pointerdown",observe,true);document.addEventListener("focusin",observe,true);})();</script>`;
25373
25559
  }
25374
25560
  __name(createPreHydrationClickQueueScript, "createPreHydrationClickQueueScript");
25375
25561
  function createDocumentFooter(options) {
@@ -28729,7 +28915,7 @@ function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
28729
28915
  wrappedHandler
28730
28916
  );
28731
28917
  endpoint.__path = path39 || void 0;
28732
- endpoint.__method = options.method || "GET";
28918
+ endpoint.__method = options.method || (path39 ? "GET" : void 0);
28733
28919
  endpoint.__autoPath = !path39;
28734
28920
  endpoint.__handler = wrappedHandler;
28735
28921
  endpoint.__farmInvoke = (ctx) => runEndpointMiddleware(middleware, ctx, handler, error, options.invalidates);
@@ -30317,7 +30503,7 @@ function parseColonParam(segment) {
30317
30503
  };
30318
30504
  }
30319
30505
  __name(parseColonParam, "parseColonParam");
30320
- function compilePathPattern(pattern) {
30506
+ function compilePathPattern(pattern, trailingSlash = false) {
30321
30507
  const params = [];
30322
30508
  const segments = pattern.split("/").filter(Boolean);
30323
30509
  if (segments.length === 0) {
@@ -30353,11 +30539,18 @@ function compilePathPattern(pattern) {
30353
30539
  });
30354
30540
  return {
30355
30541
  kind: "path",
30356
- regex: new RegExp(`^${parts.join("")}$`),
30542
+ regex: new RegExp(`^${parts.join("")}${trailingSlash ? "/?" : ""}$`),
30357
30543
  params
30358
30544
  };
30359
30545
  }
30360
30546
  __name(compilePathPattern, "compilePathPattern");
30547
+ function compileMatcherPattern(pattern) {
30548
+ if (typeof pattern === "string" && pattern !== "*" && !pattern.endsWith("(.*)")) {
30549
+ return compilePathPattern(pattern, true);
30550
+ }
30551
+ return compilePattern(pattern);
30552
+ }
30553
+ __name(compileMatcherPattern, "compileMatcherPattern");
30361
30554
  function compilePattern(pattern) {
30362
30555
  if (pattern instanceof RegExp) {
30363
30556
  return { kind: "regexp", regex: pattern };
@@ -30377,7 +30570,7 @@ __name(compilePattern, "compilePattern");
30377
30570
  function compileMiddlewareConfig(config) {
30378
30571
  const compiled = {
30379
30572
  matcher: config.matcher ? toMatcherList(config.matcher).map(
30380
- (matcher) => typeof matcher === "function" ? matcher : compilePattern(matcher)
30573
+ (matcher) => typeof matcher === "function" ? matcher : compileMatcherPattern(matcher)
30381
30574
  ) : void 0,
30382
30575
  exclude: config.exclude?.map(compilePattern)
30383
30576
  };
@@ -31643,6 +31836,7 @@ __name(collectLegacyTypeArtifacts, "collectLegacyTypeArtifacts");
31643
31836
  // src/vite.ts
31644
31837
  init_routes_shared();
31645
31838
  init_markdown();
31839
+ init_base_path();
31646
31840
  init_llms_txt();
31647
31841
  init_agent_crawlers();
31648
31842
  init_response();
@@ -33092,7 +33286,7 @@ function getEnvDefines(config, configEnv) {
33092
33286
  )
33093
33287
  };
33094
33288
  if (configEnv?.isSsrBuild) {
33095
- defines.__FARM_ENV__ = JSON.stringify(getFullEnvDefine(config));
33289
+ defines.__FARM_ENV__ = JSON.stringify(createBundledEnv(getFullEnvDefine(config)));
33096
33290
  }
33097
33291
  return defines;
33098
33292
  }
@@ -33369,8 +33563,8 @@ function farmPlugin(options = {}, initialPluginManager) {
33369
33563
  }, "emitPluginError");
33370
33564
  farmApp = new FarmApp(
33371
33565
  {
33372
- root: server.config.root,
33373
- ...options
33566
+ ...options,
33567
+ root: resolveDevelopmentRoot(options.root, server.config.root)
33374
33568
  },
33375
33569
  server
33376
33570
  );
@@ -33957,7 +34151,8 @@ window.__FARM_MANIFEST__ = ${inlineValue({
33957
34151
  () => middlewareManager.execute(req, res)
33958
34152
  );
33959
34153
  }, "runAppMiddlewareForContentRoute");
33960
- if (openAPIManager && options.openapi?.specRoute && requestPathname === options.openapi.specRoute) {
34154
+ const openAPIRequestPathname = openAPIManager ? stripFarmBasePath(requestPathname, farmConfig.basePath) : requestPathname;
34155
+ if (openAPIManager && options.openapi?.specRoute && openAPIRequestPathname === options.openapi.specRoute) {
33961
34156
  if (await runAppMiddlewareForContentRoute()) return;
33962
34157
  if (requestMethod !== "GET" && requestMethod !== "HEAD") {
33963
34158
  res.statusCode = 405;
@@ -33974,7 +34169,7 @@ window.__FARM_MANIFEST__ = ${inlineValue({
33974
34169
  res.end(requestMethod === "HEAD" ? void 0 : body);
33975
34170
  return;
33976
34171
  }
33977
- if (openAPIManager && requestPathname === options.openapi?.route) {
34172
+ if (openAPIManager && openAPIRequestPathname === options.openapi?.route) {
33978
34173
  if (await runAppMiddlewareForContentRoute()) return;
33979
34174
  const docsHandler = openAPIManager.getDocsRouteHandler(parsedRequestUrl.origin);
33980
34175
  return docsHandler(req, res);
@@ -34452,6 +34647,21 @@ window.__FARM_MANIFEST__ = ${inlineValue({
34452
34647
  headers: request2.headers,
34453
34648
  signal: request2.signal
34454
34649
  });
34650
+ let middlewareMap = /* @__PURE__ */ new Map();
34651
+ let middlewareContext = /* @__PURE__ */ new Map();
34652
+ if (middlewareManager?.hasMiddleware()) {
34653
+ const targetNodeRequest = createPageDataMiddlewareRequest(req, targetRequestUrl);
34654
+ const handled = await runFarmMiddlewareWithNavigation(
34655
+ farmApp.getServerRenderer(),
34656
+ targetRequest,
34657
+ targetNodeRequest,
34658
+ res,
34659
+ () => middlewareManager.execute(targetNodeRequest, res)
34660
+ );
34661
+ if (handled) return;
34662
+ middlewareMap = targetNodeRequest.__FARM_MIDDLEWARE_DATA__ ?? middlewareMap;
34663
+ middlewareContext = targetNodeRequest.__FARM_MIDDLEWARE_CONTEXT__ ?? middlewareContext;
34664
+ }
34455
34665
  await farmApp.getServerRenderer().runWithRequestContext(targetRequest, async () => {
34456
34666
  const routeManager3 = farmApp.getRouteManager();
34457
34667
  if (pm) {
@@ -34525,7 +34735,8 @@ window.__FARM_MANIFEST__ = ${inlineValue({
34525
34735
  {
34526
34736
  params,
34527
34737
  searchParams: Promise.resolve(searchParams),
34528
- path: targetUrl.pathname
34738
+ path: targetUrl.pathname,
34739
+ middleware: middlewareMap.size > 0 ? { data: middlewareMap } : void 0
34529
34740
  },
34530
34741
  routeContext
34531
34742
  ),
@@ -34613,27 +34824,34 @@ window.__FARM_MANIFEST__ = ${inlineValue({
34613
34824
  parseFarmLayoutChainHeader(request2.headers.get("x-farm-layout-chain")),
34614
34825
  destinationLayoutPatterns
34615
34826
  );
34616
- const fragmentHtml = await farmApp.getServerRenderer().renderNavigationFragment({
34617
- PageComponent: routeModule.default,
34618
- LoadingComponent: loadingModule?.default,
34619
- pageProps: routeProps,
34620
- params,
34621
- layouts: layouts.map((layout2, index) => ({
34622
- pattern: layout2.pattern,
34623
- module: layoutModules[index]
34624
- })),
34625
- layoutStartIndex,
34626
- slots: routeSlots.map((slot) => ({
34627
- name: slot.name,
34628
- ownerPattern: slot.ownerPattern,
34629
- containerId: slot.containerId,
34630
- module: slot.renderModule,
34631
- props: slot.props
34632
- })),
34633
- pageShouldHydrate: shouldHydrate,
34634
- layoutShouldHydrate: shouldHydrateLayout,
34635
- islandStrategy: hydrationIslandStrategy
34636
- });
34827
+ const renderer = farmApp.getServerRenderer();
34828
+ const fragmentHtml = await _runWithMiddlewareData(
34829
+ middlewareMap,
34830
+ () => _runWithMiddlewareContext(
34831
+ middlewareContext,
34832
+ () => renderer.renderNavigationFragment({
34833
+ PageComponent: routeModule.default,
34834
+ LoadingComponent: loadingModule?.default,
34835
+ pageProps: routeProps,
34836
+ params,
34837
+ layouts: layouts.map((layout2, index) => ({
34838
+ pattern: layout2.pattern,
34839
+ module: layoutModules[index]
34840
+ })),
34841
+ layoutStartIndex,
34842
+ slots: routeSlots.map((slot) => ({
34843
+ name: slot.name,
34844
+ ownerPattern: slot.ownerPattern,
34845
+ containerId: slot.containerId,
34846
+ module: slot.renderModule,
34847
+ props: slot.props
34848
+ })),
34849
+ pageShouldHydrate: shouldHydrate,
34850
+ layoutShouldHydrate: shouldHydrateLayout,
34851
+ islandStrategy: hydrationIslandStrategy
34852
+ })
34853
+ )
34854
+ );
34637
34855
  const pageData = {
34638
34856
  props: {
34639
34857
  params: routeProps.params,
@@ -34643,7 +34861,9 @@ window.__FARM_MANIFEST__ = ${inlineValue({
34643
34861
  ...routeProps.__farmCanonicalPath ? {
34644
34862
  __farmCanonicalPath: routeProps.__farmCanonicalPath
34645
34863
  } : {},
34646
- ...routeProps.__farmRoutePropsResolved ? { __farmRoutePropsResolved: true } : {}
34864
+ ...routeProps.__farmRoutePropsResolved ? { __farmRoutePropsResolved: true } : {},
34865
+ // The same serialized shape a full load embeds in __FARM_PROPS__.
34866
+ ...middlewareMap.size > 0 ? { middleware: { data: Object.fromEntries(middlewareMap) } } : {}
34647
34867
  },
34648
34868
  canonicalPath: routeProps.__farmCanonicalPath,
34649
34869
  modulePath: toUrlPath(route.modulePath),
@@ -35393,6 +35613,26 @@ function runFarmMiddlewareWithNavigation(renderer, middlewareRequest, req, res,
35393
35613
  });
35394
35614
  }
35395
35615
  __name(runFarmMiddlewareWithNavigation, "runFarmMiddlewareWithNavigation");
35616
+ function createPageDataMiddlewareRequest(req, target) {
35617
+ const targetNodeRequest = Object.create(req);
35618
+ targetNodeRequest.url = `${target.pathname}${target.search}`;
35619
+ targetNodeRequest.originalUrl = targetNodeRequest.url;
35620
+ targetNodeRequest.method = "GET";
35621
+ return targetNodeRequest;
35622
+ }
35623
+ __name(createPageDataMiddlewareRequest, "createPageDataMiddlewareRequest");
35624
+ function resolveDevelopmentRoot(farmRoot, viteRoot) {
35625
+ if (!farmRoot) return viteRoot;
35626
+ if (path38.resolve(farmRoot) === path38.resolve(viteRoot)) return farmRoot;
35627
+ try {
35628
+ if (fs14.realpathSync(farmRoot) === fs14.realpathSync(viteRoot)) {
35629
+ return path38.resolve(viteRoot);
35630
+ }
35631
+ } catch {
35632
+ }
35633
+ return farmRoot;
35634
+ }
35635
+ __name(resolveDevelopmentRoot, "resolveDevelopmentRoot");
35396
35636
  function isFarmClientVirtualId(id) {
35397
35637
  const pathname = id.split("?", 1)[0];
35398
35638
  return pathname === "/@farm/client" || pathname === "/@farm/client.js";
@@ -35408,16 +35648,18 @@ function generateProgrammaticRouteModule(moduleId, root, renderer = REACT_RENDER
35408
35648
  return generateProgrammaticApiRouteModule(parsed.routePath, routeFile);
35409
35649
  }
35410
35650
  return `
35411
- import {
35412
- createElement as __farmCreateElement,
35413
- Suspense as __farmSuspense,
35414
- } from ${JSON.stringify(renderer.server)};
35651
+ import * as __farmRendererRuntime from ${JSON.stringify(renderer.server)};
35415
35652
  import {
35416
35653
  createLayoutModuleFromProgrammaticLayout as __farmCreateLayoutRouteModule,
35417
35654
  createRouteModuleFromProgrammaticPage as __farmCreatePageRouteModule,
35418
35655
  } from "@farm.js/core/routes";
35419
35656
  import * as __farmRoutesModule from ${JSON.stringify(routeFile)};
35420
35657
 
35658
+ const __farmCreateElement = __farmRendererRuntime.createElement;
35659
+ const __farmSuspense = __farmRendererRuntime.Suspense;
35660
+ // Optional hook: only renderers that need it export markFunctionComponent.
35661
+ const __farmMarkFunctionComponent = Reflect.get(__farmRendererRuntime, "markFunctionComponent");
35662
+
35421
35663
  const __farmIsRouteDefinition = (value) => (
35422
35664
  value &&
35423
35665
  typeof value === "object" &&
@@ -35471,6 +35713,7 @@ const __farmRouteModule = __farmRoute.kind === "layout"
35471
35713
  : __farmCreatePageRouteModule(__farmRoute, {
35472
35714
  createElement: __farmCreateElement,
35473
35715
  Suspense: __farmSuspense,
35716
+ markFunctionComponent: __farmMarkFunctionComponent,
35474
35717
  });
35475
35718
 
35476
35719
  export const metadata = __farmRouteModule.metadata;
@@ -37080,6 +37323,11 @@ async function hydrate() {
37080
37323
  pendingPageHydrationController = hydrationController;
37081
37324
  await hydrateFarmIsolatedClientBoundaries(rootContainer, hydrationController.signal);
37082
37325
  if (hydrationController.signal.aborted) return;
37326
+ // The rest of the document is static server HTML with nothing to hydrate, so
37327
+ // stop holding its clicks and submits once the load-strategy islands are live.
37328
+ // Deferred islands capture their own interactions, and held targets outside an
37329
+ // island are not replayed into DOM no client code owns.
37330
+ markFarmHydrated();
37083
37331
  return;
37084
37332
  }` : ""}
37085
37333
  if (!shouldHydrate) {