@farm.js/core 0.1.0-beta.11 → 0.1.0-beta.14

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 (238) hide show
  1. package/dist/chunk-53MVSX3R.mjs +168 -0
  2. package/dist/chunk-53MVSX3R.mjs.map +1 -0
  3. package/dist/{chunk-AW6I64AP.mjs → chunk-6ZXIQSXE.mjs} +16 -1
  4. package/dist/chunk-6ZXIQSXE.mjs.map +1 -0
  5. package/dist/chunk-7ZVN3YZI.mjs +333 -0
  6. package/dist/chunk-7ZVN3YZI.mjs.map +1 -0
  7. package/dist/{chunk-5EVQFRL2.mjs → chunk-ARCGE2VT.mjs} +2 -2
  8. package/dist/chunk-ARCGE2VT.mjs.map +1 -0
  9. package/dist/{chunk-7N62DNSO.mjs → chunk-H3TE3LOV.mjs} +2 -2
  10. package/dist/{chunk-QTZZ2ISQ.mjs → chunk-KLA67WKG.mjs} +1 -1
  11. package/dist/chunk-KLA67WKG.mjs.map +1 -0
  12. package/dist/{chunk-K5ZTUF22.mjs → chunk-L2PE36GQ.mjs} +7 -3
  13. package/dist/chunk-L2PE36GQ.mjs.map +1 -0
  14. package/dist/{chunk-4LND3PXF.mjs → chunk-OPHK6OJN.mjs} +513 -48
  15. package/dist/chunk-OPHK6OJN.mjs.map +1 -0
  16. package/dist/{chunk-77BOAQHI.mjs → chunk-PNFQQSRA.mjs} +754 -156
  17. package/dist/chunk-PNFQQSRA.mjs.map +1 -0
  18. package/dist/chunk-USLFXFFH.mjs +46 -0
  19. package/dist/chunk-USLFXFFH.mjs.map +1 -0
  20. package/dist/{chunk-4677KXB7.mjs → chunk-VUL55IAX.mjs} +368 -103
  21. package/dist/chunk-VUL55IAX.mjs.map +1 -0
  22. package/dist/client.cjs.map +1 -1
  23. package/dist/client.mjs +1 -1
  24. package/dist/{devtools-A22KUJZT.mjs → devtools-GAZ7F3KL.mjs} +4 -3
  25. package/dist/{devtools-A22KUJZT.mjs.map → devtools-GAZ7F3KL.mjs.map} +1 -1
  26. package/dist/docs.cjs +622 -124
  27. package/dist/docs.cjs.map +1 -1
  28. package/dist/docs.mjs +5 -3
  29. package/dist/font.cjs +19 -2
  30. package/dist/font.cjs.map +1 -1
  31. package/dist/font.mjs +7 -3
  32. package/dist/index.cjs +2235 -689
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.mjs +27 -19
  35. package/dist/index.mjs.map +1 -1
  36. package/dist/internal/build-runtime.cjs +2062 -525
  37. package/dist/internal/build-runtime.cjs.map +1 -1
  38. package/dist/internal/build-runtime.mjs +13 -10
  39. package/dist/internal/client-runtime.cjs +169 -2
  40. package/dist/internal/client-runtime.cjs.map +1 -1
  41. package/dist/internal/client-runtime.mjs +170 -2
  42. package/dist/internal/client-runtime.mjs.map +1 -1
  43. package/dist/internal/config-runtime.cjs +22 -0
  44. package/dist/internal/config-runtime.cjs.map +1 -1
  45. package/dist/internal/config-runtime.mjs +3 -2
  46. package/dist/internal/metadata-image-runtime.cjs +199 -0
  47. package/dist/internal/metadata-image-runtime.cjs.map +1 -0
  48. package/dist/internal/metadata-image-runtime.mjs +8 -0
  49. package/dist/internal/metadata-image-runtime.mjs.map +1 -0
  50. package/dist/internal/production-runtime.cjs +310 -0
  51. package/dist/internal/production-runtime.cjs.map +1 -1
  52. package/dist/internal/production-runtime.mjs +10 -0
  53. package/dist/internal/production-runtime.mjs.map +1 -1
  54. package/dist/navigation.cjs.map +1 -1
  55. package/dist/navigation.mjs +2 -2
  56. package/dist/plugin.cjs +1550 -348
  57. package/dist/plugin.cjs.map +1 -1
  58. package/dist/plugin.mjs +9 -5
  59. package/dist/server.cjs +1663 -419
  60. package/dist/server.cjs.map +1 -1
  61. package/dist/server.mjs +17 -19
  62. package/dist/server.mjs.map +1 -1
  63. package/dist/version.cjs +1 -1
  64. package/dist/version.cjs.map +1 -1
  65. package/dist/version.mjs +1 -1
  66. package/dist/vite.cjs +1604 -358
  67. package/dist/vite.cjs.map +1 -1
  68. package/dist/vite.mjs +9 -5
  69. package/package.json +10 -1
  70. package/types/client.d.ts +115 -4
  71. package/dist/after.d.mts +0 -25
  72. package/dist/after.d.ts +0 -25
  73. package/dist/agent-runtime.d.mts +0 -94
  74. package/dist/agent-runtime.d.ts +0 -94
  75. package/dist/api/route-manager.d.mts +0 -66
  76. package/dist/api/route-manager.d.ts +0 -66
  77. package/dist/api/runtime.d.mts +0 -3
  78. package/dist/api/runtime.d.ts +0 -3
  79. package/dist/api.d.mts +0 -48
  80. package/dist/api.d.ts +0 -48
  81. package/dist/app-BNE2FoZ4.d.mts +0 -302
  82. package/dist/app-DRGUmJ3s.d.ts +0 -302
  83. package/dist/app-markdown.d.mts +0 -22
  84. package/dist/app-markdown.d.ts +0 -22
  85. package/dist/cache.d.mts +0 -192
  86. package/dist/cache.d.ts +0 -192
  87. package/dist/chunk-4677KXB7.mjs.map +0 -1
  88. package/dist/chunk-4LND3PXF.mjs.map +0 -1
  89. package/dist/chunk-5EVQFRL2.mjs.map +0 -1
  90. package/dist/chunk-77BOAQHI.mjs.map +0 -1
  91. package/dist/chunk-AW6I64AP.mjs.map +0 -1
  92. package/dist/chunk-K5ZTUF22.mjs.map +0 -1
  93. package/dist/chunk-QM746KUO.mjs +0 -56
  94. package/dist/chunk-QM746KUO.mjs.map +0 -1
  95. package/dist/chunk-QTZZ2ISQ.mjs.map +0 -1
  96. package/dist/client-BT1mFQas.d.mts +0 -447
  97. package/dist/client-Nn0q4eO4.d.ts +0 -447
  98. package/dist/client-cache-CIlyBlmx.d.ts +0 -6
  99. package/dist/client-cache-D-EZ7XVW.d.mts +0 -6
  100. package/dist/client-plugins-Bc5jHcNr.d.ts +0 -1927
  101. package/dist/client-plugins-jsk-ZLzJ.d.mts +0 -1927
  102. package/dist/client-plugins.d.mts +0 -22
  103. package/dist/client-plugins.d.ts +0 -22
  104. package/dist/client.d.mts +0 -447
  105. package/dist/client.d.ts +0 -447
  106. package/dist/config.d.mts +0 -29
  107. package/dist/config.d.ts +0 -29
  108. package/dist/cron.d.mts +0 -78
  109. package/dist/cron.d.ts +0 -78
  110. package/dist/deferred.d.mts +0 -42
  111. package/dist/deferred.d.ts +0 -42
  112. package/dist/deployment.d.mts +0 -34
  113. package/dist/deployment.d.ts +0 -34
  114. package/dist/docs.d.mts +0 -69
  115. package/dist/docs.d.ts +0 -69
  116. package/dist/env-types.d.mts +0 -12
  117. package/dist/env-types.d.ts +0 -12
  118. package/dist/env.d.mts +0 -45
  119. package/dist/env.d.ts +0 -45
  120. package/dist/environment/vite.d.mts +0 -22
  121. package/dist/environment/vite.d.ts +0 -22
  122. package/dist/environment.d.mts +0 -18
  123. package/dist/environment.d.ts +0 -18
  124. package/dist/font.d.mts +0 -70
  125. package/dist/font.d.ts +0 -70
  126. package/dist/headers.d.mts +0 -22
  127. package/dist/headers.d.ts +0 -22
  128. package/dist/i18n/client.d.mts +0 -32
  129. package/dist/i18n/client.d.ts +0 -32
  130. package/dist/i18n/index.d.mts +0 -20
  131. package/dist/i18n/index.d.ts +0 -20
  132. package/dist/i18n/server.d.mts +0 -30
  133. package/dist/i18n/server.d.ts +0 -30
  134. package/dist/image/server.d.mts +0 -37
  135. package/dist/image/server.d.ts +0 -37
  136. package/dist/image/sharp.d.mts +0 -7
  137. package/dist/image/sharp.d.ts +0 -7
  138. package/dist/image-config-Duob7wER.d.mts +0 -50
  139. package/dist/image-config-Duob7wER.d.ts +0 -50
  140. package/dist/image.d.mts +0 -39
  141. package/dist/image.d.ts +0 -39
  142. package/dist/index.d.mts +0 -455
  143. package/dist/index.d.ts +0 -455
  144. package/dist/integration-api-CHT2OKAf.d.mts +0 -93
  145. package/dist/integration-api-CHT2OKAf.d.ts +0 -93
  146. package/dist/integrations.d.mts +0 -22
  147. package/dist/integrations.d.ts +0 -22
  148. package/dist/internal/build-runtime.d.mts +0 -39
  149. package/dist/internal/build-runtime.d.ts +0 -39
  150. package/dist/internal/client-runtime.d.mts +0 -2
  151. package/dist/internal/client-runtime.d.ts +0 -2
  152. package/dist/internal/config-runtime.d.mts +0 -39
  153. package/dist/internal/config-runtime.d.ts +0 -39
  154. package/dist/internal/production-node-env.d.mts +0 -12
  155. package/dist/internal/production-node-env.d.ts +0 -12
  156. package/dist/internal/production-runtime.d.mts +0 -41
  157. package/dist/internal/production-runtime.d.ts +0 -41
  158. package/dist/markdown.d.mts +0 -60
  159. package/dist/markdown.d.ts +0 -60
  160. package/dist/metadata-7ffpT3jr.d.mts +0 -22
  161. package/dist/metadata-JHn-8eht.d.ts +0 -22
  162. package/dist/middleware.d.mts +0 -164
  163. package/dist/middleware.d.ts +0 -164
  164. package/dist/navigation-errors-Dvwpzaer.d.mts +0 -13
  165. package/dist/navigation-errors-Dvwpzaer.d.ts +0 -13
  166. package/dist/navigation.d.mts +0 -14
  167. package/dist/navigation.d.ts +0 -14
  168. package/dist/observability.d.mts +0 -335
  169. package/dist/observability.d.ts +0 -335
  170. package/dist/params-BALtrRim.d.ts +0 -15
  171. package/dist/params-ry-lxqmy.d.mts +0 -15
  172. package/dist/plugin-BJDf43dc.d.mts +0 -165
  173. package/dist/plugin-BJDf43dc.d.ts +0 -165
  174. package/dist/plugin.d.mts +0 -22
  175. package/dist/plugin.d.ts +0 -22
  176. package/dist/production-runtime-9KG7GuvW.d.ts +0 -79
  177. package/dist/production-runtime-B-fweKts.d.mts +0 -79
  178. package/dist/production-runtime-C_B79w2P.d.mts +0 -28
  179. package/dist/production-runtime-DDEM1D2q.d.ts +0 -28
  180. package/dist/query/client.d.mts +0 -61
  181. package/dist/query/client.d.ts +0 -61
  182. package/dist/query/index.d.mts +0 -90
  183. package/dist/query/index.d.ts +0 -90
  184. package/dist/query/parsers.d.mts +0 -25
  185. package/dist/query/parsers.d.ts +0 -25
  186. package/dist/query/server.d.mts +0 -55
  187. package/dist/query/server.d.ts +0 -55
  188. package/dist/request-Dsq4kGW0.d.mts +0 -6
  189. package/dist/request-udtobOLv.d.ts +0 -6
  190. package/dist/request.d.mts +0 -2
  191. package/dist/request.d.ts +0 -2
  192. package/dist/resolver-DJqjLMg_.d.mts +0 -14
  193. package/dist/resolver-IH4RmPEl.d.ts +0 -14
  194. package/dist/route-runtime-DoOHzCAD.d.mts +0 -38
  195. package/dist/route-runtime-DoOHzCAD.d.ts +0 -38
  196. package/dist/router.d.mts +0 -36
  197. package/dist/router.d.ts +0 -36
  198. package/dist/routes.d.mts +0 -224
  199. package/dist/routes.d.ts +0 -224
  200. package/dist/runtime-9nQjVM7X.d.mts +0 -206
  201. package/dist/runtime-Cxpq6xZN.d.mts +0 -27
  202. package/dist/runtime-DgeS2skB.d.ts +0 -206
  203. package/dist/runtime-bv63eUiO.d.ts +0 -27
  204. package/dist/server-action-security.d.mts +0 -43
  205. package/dist/server-action-security.d.ts +0 -43
  206. package/dist/server-fn-client.d.mts +0 -32
  207. package/dist/server-fn-client.d.ts +0 -32
  208. package/dist/server-fn.d.mts +0 -93
  209. package/dist/server-fn.d.ts +0 -93
  210. package/dist/server-plugins.d.mts +0 -55
  211. package/dist/server-plugins.d.ts +0 -55
  212. package/dist/server-query-client.d.mts +0 -50
  213. package/dist/server-query-client.d.ts +0 -50
  214. package/dist/server-query.d.mts +0 -36
  215. package/dist/server-query.d.ts +0 -36
  216. package/dist/server.d.mts +0 -48
  217. package/dist/server.d.ts +0 -48
  218. package/dist/storage.d.mts +0 -52
  219. package/dist/storage.d.ts +0 -52
  220. package/dist/testing.d.mts +0 -101
  221. package/dist/testing.d.ts +0 -101
  222. package/dist/transport-BmbGTXA5.d.mts +0 -49
  223. package/dist/transport-BmbGTXA5.d.ts +0 -49
  224. package/dist/types-BMxWr97v.d.mts +0 -81
  225. package/dist/types-BMxWr97v.d.ts +0 -81
  226. package/dist/types-C9N-nk5R.d.mts +0 -53
  227. package/dist/types-C9N-nk5R.d.ts +0 -53
  228. package/dist/types-D1A6-XvH.d.mts +0 -73
  229. package/dist/types-D1A6-XvH.d.ts +0 -73
  230. package/dist/utils-CA0z0c-2.d.ts +0 -23
  231. package/dist/utils-mYVkSOt2.d.mts +0 -23
  232. package/dist/version.d.mts +0 -3
  233. package/dist/version.d.ts +0 -3
  234. package/dist/vite.d.mts +0 -22
  235. package/dist/vite.d.ts +0 -22
  236. package/dist/workflows.d.mts +0 -110
  237. package/dist/workflows.d.ts +0 -110
  238. /package/dist/{chunk-7N62DNSO.mjs.map → chunk-H3TE3LOV.mjs.map} +0 -0
@@ -5,13 +5,14 @@ import {
5
5
  loadConfig,
6
6
  resolveConfig,
7
7
  resolveDeployConfig
8
- } from "../chunk-K5ZTUF22.mjs";
8
+ } from "../chunk-L2PE36GQ.mjs";
9
9
  import "../chunk-UVCIEUJC.mjs";
10
10
  import "../chunk-RQ633A5I.mjs";
11
11
  import "../chunk-I4CUBGVF.mjs";
12
+ import "../chunk-7MABZJIM.mjs";
12
13
  import "../chunk-YW7OBE6Q.mjs";
13
14
  import "../chunk-74YTBPTY.mjs";
14
- import "../chunk-7MABZJIM.mjs";
15
+ import "../chunk-7ZVN3YZI.mjs";
15
16
  import "../chunk-GY2STC2S.mjs";
16
17
  import "../chunk-UB5UOSHB.mjs";
17
18
  import "../chunk-ZVWA4ZQ3.mjs";
@@ -0,0 +1,199 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+
31
+ // src/metadata-image.ts
32
+ var metadata_image_exports = {};
33
+ __export(metadata_image_exports, {
34
+ createFarmMetadataImageResponse: () => createFarmMetadataImageResponse
35
+ });
36
+ module.exports = __toCommonJS(metadata_image_exports);
37
+ var import_react = __toESM(require("react"));
38
+ var import_server = require("react-dom/server");
39
+ var REACT_FORWARD_REF_TYPE = /* @__PURE__ */ Symbol.for("react.forward_ref");
40
+ var REACT_MEMO_TYPE = /* @__PURE__ */ Symbol.for("react.memo");
41
+ var REACT_LAZY_TYPE = /* @__PURE__ */ Symbol.for("react.lazy");
42
+ function isResponse(value) {
43
+ return typeof Response !== "undefined" && (value instanceof Response || Boolean(
44
+ value && typeof value === "object" && typeof value.arrayBuffer === "function" && value.headers
45
+ ));
46
+ }
47
+ __name(isResponse, "isResponse");
48
+ function isThenable(value) {
49
+ return Boolean(
50
+ value && (typeof value === "object" || typeof value === "function") && typeof value.then === "function"
51
+ );
52
+ }
53
+ __name(isThenable, "isThenable");
54
+ async function prepareMetadataImageNode(node) {
55
+ if (isThenable(node)) {
56
+ return prepareMetadataImageNode(await node);
57
+ }
58
+ if (Array.isArray(node)) {
59
+ return Promise.all(node.map((child) => prepareMetadataImageNode(child)));
60
+ }
61
+ if (!import_react.default.isValidElement(node)) {
62
+ return node;
63
+ }
64
+ const element = node;
65
+ const type = element.type;
66
+ const props = element.props || {};
67
+ if (typeof type === "function") {
68
+ if (type.prototype?.isReactComponent) {
69
+ throw new Error(
70
+ "Metadata image components must be stateless function components; React class components are not supported."
71
+ );
72
+ }
73
+ return prepareMetadataImageNode(await type(props));
74
+ }
75
+ if (type && typeof type === "object") {
76
+ if (type.$$typeof === REACT_MEMO_TYPE) {
77
+ return prepareMetadataImageNode(import_react.default.createElement(type.type, props));
78
+ }
79
+ if (type.$$typeof === REACT_FORWARD_REF_TYPE) {
80
+ return prepareMetadataImageNode(await type.render(props, null));
81
+ }
82
+ if (type.$$typeof === REACT_LAZY_TYPE) {
83
+ return prepareMetadataImageNode(import_react.default.createElement(type._init(type._payload), props));
84
+ }
85
+ }
86
+ const preparedChildren = await prepareMetadataImageNode(props.children);
87
+ const preparedProps = { ...props };
88
+ if (typeof preparedProps.className === "string") {
89
+ preparedProps.tw = [preparedProps.tw, preparedProps.className].filter(Boolean).join(" ");
90
+ delete preparedProps.className;
91
+ }
92
+ delete preparedProps.children;
93
+ return import_react.default.createElement(type, {
94
+ ...preparedProps,
95
+ key: element.key,
96
+ children: preparedChildren
97
+ });
98
+ }
99
+ __name(prepareMetadataImageNode, "prepareMetadataImageNode");
100
+ async function normalizeFonts(fonts) {
101
+ if (!fonts?.length) return void 0;
102
+ return Promise.all(
103
+ fonts.map(async (font) => {
104
+ const data = await font.data;
105
+ const arrayBuffer = ArrayBuffer.isView(data) ? toArrayBuffer(data) : data;
106
+ return { ...font, data: arrayBuffer };
107
+ })
108
+ );
109
+ }
110
+ __name(normalizeFonts, "normalizeFonts");
111
+ function resolveCacheControl(revalidate) {
112
+ if (revalidate === false) {
113
+ return "public, max-age=31536000, immutable";
114
+ }
115
+ if (typeof revalidate === "number" && Number.isFinite(revalidate) && revalidate > 0) {
116
+ return `public, s-maxage=${Math.floor(revalidate)}, stale-while-revalidate=300`;
117
+ }
118
+ return "public, max-age=0, must-revalidate";
119
+ }
120
+ __name(resolveCacheControl, "resolveCacheControl");
121
+ function toArrayBuffer(value) {
122
+ if (value instanceof ArrayBuffer) return value;
123
+ const bytes = new Uint8Array(value.byteLength);
124
+ bytes.set(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));
125
+ return bytes.buffer;
126
+ }
127
+ __name(toArrayBuffer, "toArrayBuffer");
128
+ async function createEntityTag(body) {
129
+ const digest = await globalThis.crypto.subtle.digest("SHA-256", body);
130
+ const hash = Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("").slice(0, 32);
131
+ return `"${hash}"`;
132
+ }
133
+ __name(createEntityTag, "createEntityTag");
134
+ async function finalizeMetadataImageResponse(body, headers, options) {
135
+ const responseHeaders = new Headers(headers);
136
+ const etag = await createEntityTag(body);
137
+ responseHeaders.set("ETag", etag);
138
+ responseHeaders.set("Content-Length", String(body.byteLength));
139
+ responseHeaders.set("X-Content-Type-Options", "nosniff");
140
+ const matchesEntityTag = options.ifNoneMatch?.trim() === "*" || options.ifNoneMatch?.split(",").some((candidate) => candidate.trim().replace(/^W\//, "") === etag);
141
+ if (matchesEntityTag) {
142
+ return new Response(null, { status: 304, headers: responseHeaders });
143
+ }
144
+ return new Response(options.method?.toUpperCase() === "HEAD" ? null : body, {
145
+ status: 200,
146
+ headers: responseHeaders
147
+ });
148
+ }
149
+ __name(finalizeMetadataImageResponse, "finalizeMetadataImageResponse");
150
+ async function createFarmMetadataImageResponse(value, imageModule, options = {}) {
151
+ const method = (options.method || "GET").toUpperCase();
152
+ if (method !== "GET" && method !== "HEAD") {
153
+ return new Response(null, { status: 405, headers: { Allow: "GET, HEAD" } });
154
+ }
155
+ if (isResponse(value)) {
156
+ return method === "HEAD" ? new Response(null, { status: value.status, headers: value.headers }) : value;
157
+ }
158
+ const cacheControl = resolveCacheControl(imageModule.revalidate);
159
+ const explicitContentType = imageModule.contentType?.split(";", 1)[0]?.trim().toLowerCase();
160
+ if (import_react.default.isValidElement(value) && explicitContentType !== "image/svg+xml") {
161
+ const { ImageResponse } = await import("@vercel/og");
162
+ const element = await prepareMetadataImageNode(value);
163
+ const response = new ImageResponse(element, {
164
+ width: imageModule.size?.width || 1200,
165
+ height: imageModule.size?.height || 630,
166
+ fonts: await normalizeFonts(imageModule.fonts),
167
+ emoji: imageModule.emoji,
168
+ debug: imageModule.debug,
169
+ headers: { "cache-control": cacheControl }
170
+ });
171
+ const headers = new Headers(response.headers);
172
+ headers.set("Cache-Control", cacheControl);
173
+ return finalizeMetadataImageResponse(await response.arrayBuffer(), headers, options);
174
+ }
175
+ let body;
176
+ if (typeof value === "string") {
177
+ body = toArrayBuffer(new TextEncoder().encode(value));
178
+ } else if (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {
179
+ body = toArrayBuffer(value);
180
+ } else if (import_react.default.isValidElement(value)) {
181
+ body = toArrayBuffer(new TextEncoder().encode((0, import_server.renderToStaticMarkup)(value)));
182
+ } else {
183
+ throw new Error("Metadata image must return a Response, string, bytes, or React element");
184
+ }
185
+ return finalizeMetadataImageResponse(
186
+ body,
187
+ {
188
+ "Content-Type": imageModule.contentType || "image/svg+xml; charset=utf-8",
189
+ "Cache-Control": cacheControl
190
+ },
191
+ options
192
+ );
193
+ }
194
+ __name(createFarmMetadataImageResponse, "createFarmMetadataImageResponse");
195
+ // Annotate the CommonJS export names for ESM import in node:
196
+ 0 && (module.exports = {
197
+ createFarmMetadataImageResponse
198
+ });
199
+ //# sourceMappingURL=metadata-image-runtime.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/metadata-image.ts"],"sourcesContent":["import React from \"react\";\nimport { renderToStaticMarkup } from \"react-dom/server\";\nimport type { ImageResponseOptions } from \"@vercel/og\";\n\nconst REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\");\nconst REACT_MEMO_TYPE = Symbol.for(\"react.memo\");\nconst REACT_LAZY_TYPE = Symbol.for(\"react.lazy\");\n\ntype MetadataImageSize = {\n width?: number;\n height?: number;\n};\n\ntype MetadataImageFont = Omit<NonNullable<ImageResponseOptions[\"fonts\"]>[number], \"data\"> & {\n data: ArrayBuffer | ArrayBufferView | Promise<ArrayBuffer | ArrayBufferView>;\n};\n\nexport type FarmMetadataImageModule = {\n size?: MetadataImageSize;\n contentType?: string;\n revalidate?: number | false;\n fonts?: MetadataImageFont[];\n emoji?: ImageResponseOptions[\"emoji\"];\n debug?: boolean;\n};\n\nexport type FarmMetadataImageResponseOptions = {\n method?: string;\n ifNoneMatch?: string | null;\n};\n\nfunction isResponse(value: unknown): value is Response {\n return (\n typeof Response !== \"undefined\" &&\n (value instanceof Response ||\n Boolean(\n value &&\n typeof value === \"object\" &&\n typeof (value as Response).arrayBuffer === \"function\" &&\n (value as Response).headers,\n ))\n );\n}\n\nfunction isThenable(value: unknown): value is PromiseLike<unknown> {\n return Boolean(\n value &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n typeof (value as PromiseLike<unknown>).then === \"function\",\n );\n}\n\nasync function prepareMetadataImageNode(node: unknown): Promise<unknown> {\n if (isThenable(node)) {\n return prepareMetadataImageNode(await node);\n }\n\n if (Array.isArray(node)) {\n return Promise.all(node.map((child) => prepareMetadataImageNode(child)));\n }\n\n if (!React.isValidElement(node)) {\n return node;\n }\n\n const element = node as React.ReactElement<Record<string, unknown>>;\n const type = element.type as any;\n const props = element.props || {};\n\n if (typeof type === \"function\") {\n if (type.prototype?.isReactComponent) {\n throw new Error(\n \"Metadata image components must be stateless function components; React class components are not supported.\",\n );\n }\n return prepareMetadataImageNode(await type(props));\n }\n\n if (type && typeof type === \"object\") {\n if (type.$$typeof === REACT_MEMO_TYPE) {\n return prepareMetadataImageNode(React.createElement(type.type, props));\n }\n if (type.$$typeof === REACT_FORWARD_REF_TYPE) {\n return prepareMetadataImageNode(await type.render(props, null));\n }\n if (type.$$typeof === REACT_LAZY_TYPE) {\n return prepareMetadataImageNode(React.createElement(type._init(type._payload), props));\n }\n }\n\n const preparedChildren = await prepareMetadataImageNode(props.children);\n const preparedProps: Record<string, unknown> = { ...props };\n\n if (typeof preparedProps.className === \"string\") {\n preparedProps.tw = [preparedProps.tw, preparedProps.className].filter(Boolean).join(\" \");\n delete preparedProps.className;\n }\n delete preparedProps.children;\n\n return React.createElement(type, {\n ...preparedProps,\n key: element.key,\n children: preparedChildren,\n });\n}\n\nasync function normalizeFonts(\n fonts: MetadataImageFont[] | undefined,\n): Promise<ImageResponseOptions[\"fonts\"] | undefined> {\n if (!fonts?.length) return undefined;\n\n return Promise.all(\n fonts.map(async (font) => {\n const data = await font.data;\n const arrayBuffer = ArrayBuffer.isView(data) ? toArrayBuffer(data) : data;\n return { ...font, data: arrayBuffer } as NonNullable<ImageResponseOptions[\"fonts\"]>[number];\n }),\n );\n}\n\nfunction resolveCacheControl(revalidate: number | false | undefined): string {\n if (revalidate === false) {\n return \"public, max-age=31536000, immutable\";\n }\n if (typeof revalidate === \"number\" && Number.isFinite(revalidate) && revalidate > 0) {\n return `public, s-maxage=${Math.floor(revalidate)}, stale-while-revalidate=300`;\n }\n return \"public, max-age=0, must-revalidate\";\n}\n\nfunction toArrayBuffer(value: ArrayBuffer | ArrayBufferView): ArrayBuffer {\n if (value instanceof ArrayBuffer) return value;\n const bytes = new Uint8Array(value.byteLength);\n bytes.set(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));\n return bytes.buffer;\n}\n\nasync function createEntityTag(body: ArrayBuffer): Promise<string> {\n const digest = await globalThis.crypto.subtle.digest(\"SHA-256\", body);\n const hash = Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\")\n .slice(0, 32);\n return `\"${hash}\"`;\n}\n\nasync function finalizeMetadataImageResponse(\n body: ArrayBuffer,\n headers: HeadersInit,\n options: FarmMetadataImageResponseOptions,\n): Promise<Response> {\n const responseHeaders = new Headers(headers);\n const etag = await createEntityTag(body);\n responseHeaders.set(\"ETag\", etag);\n responseHeaders.set(\"Content-Length\", String(body.byteLength));\n responseHeaders.set(\"X-Content-Type-Options\", \"nosniff\");\n\n const matchesEntityTag =\n options.ifNoneMatch?.trim() === \"*\" ||\n options.ifNoneMatch\n ?.split(\",\")\n .some((candidate) => candidate.trim().replace(/^W\\//, \"\") === etag);\n if (matchesEntityTag) {\n return new Response(null, { status: 304, headers: responseHeaders });\n }\n\n return new Response(options.method?.toUpperCase() === \"HEAD\" ? null : body, {\n status: 200,\n headers: responseHeaders,\n });\n}\n\n/** @internal */\nexport async function createFarmMetadataImageResponse(\n value: unknown,\n imageModule: FarmMetadataImageModule,\n options: FarmMetadataImageResponseOptions = {},\n): Promise<Response> {\n const method = (options.method || \"GET\").toUpperCase();\n if (method !== \"GET\" && method !== \"HEAD\") {\n return new Response(null, { status: 405, headers: { Allow: \"GET, HEAD\" } });\n }\n\n if (isResponse(value)) {\n return method === \"HEAD\"\n ? new Response(null, { status: value.status, headers: value.headers })\n : value;\n }\n\n const cacheControl = resolveCacheControl(imageModule.revalidate);\n const explicitContentType = imageModule.contentType?.split(\";\", 1)[0]?.trim().toLowerCase();\n\n if (React.isValidElement(value) && explicitContentType !== \"image/svg+xml\") {\n const { ImageResponse } = await import(\"@vercel/og\");\n const element = (await prepareMetadataImageNode(value)) as React.ReactElement;\n const response = new ImageResponse(element, {\n width: imageModule.size?.width || 1200,\n height: imageModule.size?.height || 630,\n fonts: await normalizeFonts(imageModule.fonts),\n emoji: imageModule.emoji,\n debug: imageModule.debug,\n headers: { \"cache-control\": cacheControl },\n });\n const headers = new Headers(response.headers);\n headers.set(\"Cache-Control\", cacheControl);\n return finalizeMetadataImageResponse(await response.arrayBuffer(), headers, options);\n }\n\n let body: ArrayBuffer;\n if (typeof value === \"string\") {\n body = toArrayBuffer(new TextEncoder().encode(value));\n } else if (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {\n body = toArrayBuffer(value);\n } else if (React.isValidElement(value)) {\n body = toArrayBuffer(new TextEncoder().encode(renderToStaticMarkup(value)));\n } else {\n throw new Error(\"Metadata image must return a Response, string, bytes, or React element\");\n }\n\n return finalizeMetadataImageResponse(\n body,\n {\n \"Content-Type\": imageModule.contentType || \"image/svg+xml; charset=utf-8\",\n \"Cache-Control\": cacheControl,\n },\n options,\n );\n}\n"],"mappings":"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","names":["React"]}
@@ -0,0 +1,8 @@
1
+ import {
2
+ createFarmMetadataImageResponse
3
+ } from "../chunk-53MVSX3R.mjs";
4
+ import "../chunk-CGILA3WO.mjs";
5
+ export {
6
+ createFarmMetadataImageResponse
7
+ };
8
+ //# sourceMappingURL=metadata-image-runtime.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -42,9 +42,13 @@ __export(production_runtime_exports, {
42
42
  isFarmRedirectError: () => isFarmRedirectError,
43
43
  localizeFarmHref: () => localizeFarmHref,
44
44
  localizeFarmPathname: () => localizeFarmPathname,
45
+ manageFarmDocumentPreloads: () => manageFarmDocumentPreloads,
46
+ manageFarmHtmlPreloads: () => manageFarmHtmlPreloads,
47
+ manageFarmLinkHeaderPreloads: () => manageFarmLinkHeaderPreloads,
45
48
  mergeMetadata: () => mergeMetadata,
46
49
  normalizeRevalidatePath: () => normalizeRevalidatePath,
47
50
  renderMetadataHead: () => renderMetadataHead,
51
+ reportFarmPreloadWarnings: () => reportFarmPreloadWarnings,
48
52
  resolveFarmRouteContext: () => resolveFarmRouteContext,
49
53
  stripFarmLocaleFromPathname: () => stripFarmLocaleFromPathname,
50
54
  withFarmRouteContext: () => withFarmRouteContext
@@ -2142,6 +2146,308 @@ function withFarmRouteContext(props, context) {
2142
2146
  }
2143
2147
  __name(withFarmRouteContext, "withFarmRouteContext");
2144
2148
 
2149
+ // src/preload.ts
2150
+ var reportedWarnings = /* @__PURE__ */ new Map();
2151
+ var PRELOAD_WARNING_TTL_MS = 6e4;
2152
+ var MAX_REPORTED_PRELOAD_WARNINGS = 256;
2153
+ function manageFarmHtmlPreloads(html, config) {
2154
+ const elements = findHtmlLinkElements(html);
2155
+ const candidates = elements.flatMap((element, index) => {
2156
+ const kind = getHtmlPreloadKind(element.value);
2157
+ return kind ? [
2158
+ {
2159
+ index,
2160
+ kind,
2161
+ highPriority: readHtmlAttribute(element.value, "fetchpriority")?.toLowerCase() === "high"
2162
+ }
2163
+ ] : [];
2164
+ });
2165
+ const budget = selectPreloadsWithinBudget(candidates, config);
2166
+ if (config.mode === "warn" || budget.removed.size === 0) {
2167
+ return { value: html, warnings: budget.warnings };
2168
+ }
2169
+ return {
2170
+ value: removeHtmlLinkElements(html, elements, budget.removed),
2171
+ warnings: budget.warnings
2172
+ };
2173
+ }
2174
+ __name(manageFarmHtmlPreloads, "manageFarmHtmlPreloads");
2175
+ function manageFarmLinkHeaderPreloads(value, config) {
2176
+ if (!value) return { value, warnings: [] };
2177
+ const links = splitLinkHeader(value);
2178
+ const candidates = links.flatMap((link, index) => {
2179
+ const kind = getLinkHeaderPreloadKind(link);
2180
+ return kind ? [
2181
+ {
2182
+ index,
2183
+ kind,
2184
+ highPriority: getLinkHeaderParameter(link, "fetchpriority")?.toLowerCase() === "high"
2185
+ }
2186
+ ] : [];
2187
+ });
2188
+ const budget = selectPreloadsWithinBudget(candidates, config);
2189
+ return {
2190
+ value: config.mode === "enforce" ? links.filter((_, index) => !budget.removed.has(index)).join(", ") : value,
2191
+ warnings: budget.warnings
2192
+ };
2193
+ }
2194
+ __name(manageFarmLinkHeaderPreloads, "manageFarmLinkHeaderPreloads");
2195
+ function manageFarmDocumentPreloads(html, linkHeader, config) {
2196
+ const elements = findHtmlLinkElements(html);
2197
+ const links = linkHeader ? splitLinkHeader(linkHeader) : [];
2198
+ const headerOffset = elements.length;
2199
+ const candidates = [];
2200
+ for (const [index, element] of elements.entries()) {
2201
+ const kind = getHtmlPreloadKind(element.value);
2202
+ if (!kind) continue;
2203
+ candidates.push({
2204
+ index,
2205
+ kind,
2206
+ highPriority: readHtmlAttribute(element.value, "fetchpriority")?.toLowerCase() === "high"
2207
+ });
2208
+ }
2209
+ for (const [index, link] of links.entries()) {
2210
+ const kind = getLinkHeaderPreloadKind(link);
2211
+ if (!kind) continue;
2212
+ candidates.push({
2213
+ index: headerOffset + index,
2214
+ kind,
2215
+ highPriority: getLinkHeaderParameter(link, "fetchpriority")?.toLowerCase() === "high"
2216
+ });
2217
+ }
2218
+ const budget = selectPreloadsWithinBudget(candidates, config);
2219
+ if (config.mode === "warn" || budget.removed.size === 0) {
2220
+ return { html, linkHeader, warnings: budget.warnings };
2221
+ }
2222
+ return {
2223
+ html: removeHtmlLinkElements(html, elements, budget.removed),
2224
+ linkHeader: links.filter((_, index) => !budget.removed.has(headerOffset + index)).join(", "),
2225
+ warnings: budget.warnings
2226
+ };
2227
+ }
2228
+ __name(manageFarmDocumentPreloads, "manageFarmDocumentPreloads");
2229
+ function reportFarmPreloadWarnings(warnings, context = "the rendered document") {
2230
+ const now = Date.now();
2231
+ for (const [key, reportedAt] of reportedWarnings) {
2232
+ if (now - reportedAt >= PRELOAD_WARNING_TTL_MS) reportedWarnings.delete(key);
2233
+ }
2234
+ for (const warning of warnings) {
2235
+ const key = `${context}:${warning.kind}:${warning.count}:${warning.budget}:${warning.removed}`;
2236
+ const reportedAt = reportedWarnings.get(key);
2237
+ if (reportedAt !== void 0 && now - reportedAt < PRELOAD_WARNING_TTL_MS) continue;
2238
+ reportedWarnings.set(key, now);
2239
+ while (reportedWarnings.size > MAX_REPORTED_PRELOAD_WARNINGS) {
2240
+ const oldest = reportedWarnings.keys().next().value;
2241
+ if (oldest === void 0) break;
2242
+ reportedWarnings.delete(oldest);
2243
+ }
2244
+ const action = warning.removed > 0 ? ` Removed ${warning.removed} lower-priority hint(s).` : "";
2245
+ const recommendation = warning.kind === "image" ? ' Mark only the LCP image with `preload` or `fetchPriority="high"`.' : " Set `preload: false` on fonts that are not required above the fold.";
2246
+ console.warn(
2247
+ `[Farm.js] ${context} emitted ${warning.count} ${warning.kind} preload hints (budget: ${warning.budget}).${action}${recommendation}`
2248
+ );
2249
+ }
2250
+ }
2251
+ __name(reportFarmPreloadWarnings, "reportFarmPreloadWarnings");
2252
+ function selectPreloadsWithinBudget(candidates, config) {
2253
+ const removed = /* @__PURE__ */ new Set();
2254
+ const warnings = [];
2255
+ for (const kind of ["image", "font"]) {
2256
+ const matching = candidates.filter((candidate) => candidate.kind === kind);
2257
+ const limit = kind === "image" ? config.maxImages : config.maxFonts;
2258
+ if (matching.length <= limit) continue;
2259
+ const retained = new Set(
2260
+ [...matching].sort(
2261
+ (left, right) => Number(right.highPriority) - Number(left.highPriority) || left.index - right.index
2262
+ ).slice(0, limit).map((candidate) => candidate.index)
2263
+ );
2264
+ if (config.mode === "enforce") {
2265
+ for (const candidate of matching) {
2266
+ if (!retained.has(candidate.index)) removed.add(candidate.index);
2267
+ }
2268
+ }
2269
+ warnings.push({
2270
+ kind,
2271
+ count: matching.length,
2272
+ budget: limit,
2273
+ removed: config.mode === "enforce" ? matching.length - retained.size : 0
2274
+ });
2275
+ }
2276
+ return { removed, warnings };
2277
+ }
2278
+ __name(selectPreloadsWithinBudget, "selectPreloadsWithinBudget");
2279
+ function getHtmlPreloadKind(link) {
2280
+ const rel = readHtmlAttribute(link, "rel")?.toLowerCase().split(/\s+/) || [];
2281
+ if (!rel.includes("preload")) return void 0;
2282
+ return normalizePreloadKind(readHtmlAttribute(link, "as"));
2283
+ }
2284
+ __name(getHtmlPreloadKind, "getHtmlPreloadKind");
2285
+ function getLinkHeaderPreloadKind(link) {
2286
+ const relations = getLinkHeaderParameter(link, "rel")?.toLowerCase().split(/\s+/) ?? [];
2287
+ if (!relations.includes("preload")) return void 0;
2288
+ return normalizePreloadKind(getLinkHeaderParameter(link, "as"));
2289
+ }
2290
+ __name(getLinkHeaderPreloadKind, "getLinkHeaderPreloadKind");
2291
+ function getLinkHeaderParameter(link, name) {
2292
+ const uriEnd = link.indexOf(">");
2293
+ if (uriEnd === -1) return void 0;
2294
+ for (const parameter of splitLinkParameters(link.slice(uriEnd + 1))) {
2295
+ const separator = parameter.indexOf("=");
2296
+ const parameterName = (separator === -1 ? parameter : parameter.slice(0, separator)).trim().toLowerCase();
2297
+ if (parameterName !== name.toLowerCase() || separator === -1) continue;
2298
+ const rawValue = parameter.slice(separator + 1).trim();
2299
+ if (rawValue.startsWith('"') && rawValue.endsWith('"')) {
2300
+ return rawValue.slice(1, -1).replace(/\\([\\"])/g, "$1");
2301
+ }
2302
+ return rawValue;
2303
+ }
2304
+ return void 0;
2305
+ }
2306
+ __name(getLinkHeaderParameter, "getLinkHeaderParameter");
2307
+ function splitLinkParameters(value) {
2308
+ const parameters = [];
2309
+ let start = 0;
2310
+ let quoted = false;
2311
+ for (let index = 0; index < value.length; index += 1) {
2312
+ const character = value[index];
2313
+ if (character === '"' && !isEscaped(value, index)) quoted = !quoted;
2314
+ else if (character === ";" && !quoted) {
2315
+ const parameter2 = value.slice(start, index).trim();
2316
+ if (parameter2) parameters.push(parameter2);
2317
+ start = index + 1;
2318
+ }
2319
+ }
2320
+ const parameter = value.slice(start).trim();
2321
+ if (parameter) parameters.push(parameter);
2322
+ return parameters;
2323
+ }
2324
+ __name(splitLinkParameters, "splitLinkParameters");
2325
+ function normalizePreloadKind(value) {
2326
+ const normalized = value?.toLowerCase();
2327
+ return normalized === "image" || normalized === "font" ? normalized : void 0;
2328
+ }
2329
+ __name(normalizePreloadKind, "normalizePreloadKind");
2330
+ function readHtmlAttribute(element, name) {
2331
+ const match = element.match(
2332
+ new RegExp(`\\s${name}\\s*=\\s*(?:"([^"]*)"|'([^']*)'|([^\\s>]+))`, "i")
2333
+ );
2334
+ return match?.[1] ?? match?.[2] ?? match?.[3];
2335
+ }
2336
+ __name(readHtmlAttribute, "readHtmlAttribute");
2337
+ function findHtmlLinkElements(html) {
2338
+ const elements = [];
2339
+ const lowerHtml = html.toLowerCase();
2340
+ let cursor = 0;
2341
+ while (cursor < html.length) {
2342
+ const start = html.indexOf("<", cursor);
2343
+ if (start === -1) break;
2344
+ if (lowerHtml.startsWith("<!--", start)) {
2345
+ const commentEnd = lowerHtml.indexOf("-->", start + 4);
2346
+ cursor = commentEnd === -1 ? html.length : commentEnd + 3;
2347
+ continue;
2348
+ }
2349
+ const rawText = lowerHtml.slice(start).match(/^<(script|style|template|textarea|title|noscript|svg)(?=[\s/>])/);
2350
+ if (rawText?.[1]) {
2351
+ const openingEnd = findHtmlTagEnd(html, start);
2352
+ if (openingEnd === -1) break;
2353
+ const closingStart = findHtmlClosingTag(lowerHtml, rawText[1], openingEnd);
2354
+ if (closingStart === -1) {
2355
+ cursor = html.length;
2356
+ continue;
2357
+ }
2358
+ const closingEnd = findHtmlTagEnd(html, closingStart);
2359
+ cursor = closingEnd === -1 ? html.length : closingEnd;
2360
+ continue;
2361
+ }
2362
+ if (/^<link(?=[\s/>])/i.test(html.slice(start))) {
2363
+ const end = findHtmlTagEnd(html, start);
2364
+ if (end === -1) break;
2365
+ elements.push({ start, end, value: html.slice(start, end) });
2366
+ cursor = end;
2367
+ continue;
2368
+ }
2369
+ if (/^<\/?[A-Za-z][\w:-]*(?=[\s/>])/.test(html.slice(start))) {
2370
+ const end = findHtmlTagEnd(html, start);
2371
+ cursor = end === -1 ? html.length : end;
2372
+ continue;
2373
+ }
2374
+ cursor = start + 1;
2375
+ }
2376
+ return elements;
2377
+ }
2378
+ __name(findHtmlLinkElements, "findHtmlLinkElements");
2379
+ function findHtmlClosingTag(html, tagName, start) {
2380
+ const prefix = `</${tagName}`;
2381
+ let candidate = html.indexOf(prefix, start);
2382
+ while (candidate !== -1) {
2383
+ const boundary = html[candidate + prefix.length];
2384
+ if (boundary === ">" || boundary === "/" || /\s/.test(boundary ?? "")) return candidate;
2385
+ candidate = html.indexOf(prefix, candidate + prefix.length);
2386
+ }
2387
+ return -1;
2388
+ }
2389
+ __name(findHtmlClosingTag, "findHtmlClosingTag");
2390
+ function findHtmlTagEnd(html, start) {
2391
+ let quote;
2392
+ for (let index = start + 1; index < html.length; index += 1) {
2393
+ const character = html[index];
2394
+ if (quote) {
2395
+ if (character === quote) quote = void 0;
2396
+ } else if (character === '"' || character === "'") {
2397
+ quote = character;
2398
+ } else if (character === ">") {
2399
+ return index + 1;
2400
+ }
2401
+ }
2402
+ return -1;
2403
+ }
2404
+ __name(findHtmlTagEnd, "findHtmlTagEnd");
2405
+ function removeHtmlLinkElements(html, elements, removed) {
2406
+ let cursor = 0;
2407
+ let output = "";
2408
+ for (const [index, element] of elements.entries()) {
2409
+ if (!removed.has(index)) continue;
2410
+ output += html.slice(cursor, element.start);
2411
+ cursor = element.end;
2412
+ }
2413
+ return output + html.slice(cursor);
2414
+ }
2415
+ __name(removeHtmlLinkElements, "removeHtmlLinkElements");
2416
+ function splitLinkHeader(value) {
2417
+ const links = [];
2418
+ let start = 0;
2419
+ let insideAngleBrackets = false;
2420
+ let quoted = false;
2421
+ for (let index = 0; index < value.length; index += 1) {
2422
+ const character = value[index];
2423
+ if (quoted) {
2424
+ if (character === '"' && !isEscaped(value, index)) quoted = false;
2425
+ continue;
2426
+ }
2427
+ if (character === '"') {
2428
+ quoted = true;
2429
+ } else if (character === "<") {
2430
+ insideAngleBrackets = true;
2431
+ } else if (character === ">") {
2432
+ insideAngleBrackets = false;
2433
+ } else if (character === "," && !insideAngleBrackets) {
2434
+ links.push(value.slice(start, index).trim());
2435
+ start = index + 1;
2436
+ }
2437
+ }
2438
+ links.push(value.slice(start).trim());
2439
+ return links.filter(Boolean);
2440
+ }
2441
+ __name(splitLinkHeader, "splitLinkHeader");
2442
+ function isEscaped(value, index) {
2443
+ let backslashes = 0;
2444
+ for (let cursor = index - 1; cursor >= 0 && value[cursor] === "\\"; cursor -= 1) {
2445
+ backslashes += 1;
2446
+ }
2447
+ return backslashes % 2 === 1;
2448
+ }
2449
+ __name(isEscaped, "isEscaped");
2450
+
2145
2451
  // src/nitro/production-runtime.ts
2146
2452
  function appendFarmLinkHeader(headers, value) {
2147
2453
  const current = headers.get("Link");
@@ -2177,9 +2483,13 @@ __name(appendFarmLinkHeader, "appendFarmLinkHeader");
2177
2483
  isFarmRedirectError,
2178
2484
  localizeFarmHref,
2179
2485
  localizeFarmPathname,
2486
+ manageFarmDocumentPreloads,
2487
+ manageFarmHtmlPreloads,
2488
+ manageFarmLinkHeaderPreloads,
2180
2489
  mergeMetadata,
2181
2490
  normalizeRevalidatePath,
2182
2491
  renderMetadataHead,
2492
+ reportFarmPreloadWarnings,
2183
2493
  resolveFarmRouteContext,
2184
2494
  stripFarmLocaleFromPathname,
2185
2495
  withFarmRouteContext