@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.
- package/dist/chunk-53MVSX3R.mjs +168 -0
- package/dist/chunk-53MVSX3R.mjs.map +1 -0
- package/dist/{chunk-AW6I64AP.mjs → chunk-6ZXIQSXE.mjs} +16 -1
- package/dist/chunk-6ZXIQSXE.mjs.map +1 -0
- package/dist/chunk-7ZVN3YZI.mjs +333 -0
- package/dist/chunk-7ZVN3YZI.mjs.map +1 -0
- package/dist/{chunk-5EVQFRL2.mjs → chunk-ARCGE2VT.mjs} +2 -2
- package/dist/chunk-ARCGE2VT.mjs.map +1 -0
- package/dist/{chunk-7N62DNSO.mjs → chunk-H3TE3LOV.mjs} +2 -2
- package/dist/{chunk-QTZZ2ISQ.mjs → chunk-KLA67WKG.mjs} +1 -1
- package/dist/chunk-KLA67WKG.mjs.map +1 -0
- package/dist/{chunk-K5ZTUF22.mjs → chunk-L2PE36GQ.mjs} +7 -3
- package/dist/chunk-L2PE36GQ.mjs.map +1 -0
- package/dist/{chunk-4LND3PXF.mjs → chunk-OPHK6OJN.mjs} +513 -48
- package/dist/chunk-OPHK6OJN.mjs.map +1 -0
- package/dist/{chunk-77BOAQHI.mjs → chunk-PNFQQSRA.mjs} +754 -156
- package/dist/chunk-PNFQQSRA.mjs.map +1 -0
- package/dist/chunk-USLFXFFH.mjs +46 -0
- package/dist/chunk-USLFXFFH.mjs.map +1 -0
- package/dist/{chunk-4677KXB7.mjs → chunk-VUL55IAX.mjs} +368 -103
- package/dist/chunk-VUL55IAX.mjs.map +1 -0
- package/dist/client.cjs.map +1 -1
- package/dist/client.mjs +1 -1
- package/dist/{devtools-A22KUJZT.mjs → devtools-GAZ7F3KL.mjs} +4 -3
- package/dist/{devtools-A22KUJZT.mjs.map → devtools-GAZ7F3KL.mjs.map} +1 -1
- package/dist/docs.cjs +622 -124
- package/dist/docs.cjs.map +1 -1
- package/dist/docs.mjs +5 -3
- package/dist/font.cjs +19 -2
- package/dist/font.cjs.map +1 -1
- package/dist/font.mjs +7 -3
- package/dist/index.cjs +2235 -689
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +27 -19
- package/dist/index.mjs.map +1 -1
- package/dist/internal/build-runtime.cjs +2062 -525
- package/dist/internal/build-runtime.cjs.map +1 -1
- package/dist/internal/build-runtime.mjs +13 -10
- package/dist/internal/client-runtime.cjs +169 -2
- package/dist/internal/client-runtime.cjs.map +1 -1
- package/dist/internal/client-runtime.mjs +170 -2
- package/dist/internal/client-runtime.mjs.map +1 -1
- package/dist/internal/config-runtime.cjs +22 -0
- package/dist/internal/config-runtime.cjs.map +1 -1
- package/dist/internal/config-runtime.mjs +3 -2
- package/dist/internal/metadata-image-runtime.cjs +199 -0
- package/dist/internal/metadata-image-runtime.cjs.map +1 -0
- package/dist/internal/metadata-image-runtime.mjs +8 -0
- package/dist/internal/metadata-image-runtime.mjs.map +1 -0
- package/dist/internal/production-runtime.cjs +310 -0
- package/dist/internal/production-runtime.cjs.map +1 -1
- package/dist/internal/production-runtime.mjs +10 -0
- package/dist/internal/production-runtime.mjs.map +1 -1
- package/dist/navigation.cjs.map +1 -1
- package/dist/navigation.mjs +2 -2
- package/dist/plugin.cjs +1550 -348
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.mjs +9 -5
- package/dist/server.cjs +1663 -419
- package/dist/server.cjs.map +1 -1
- package/dist/server.mjs +17 -19
- package/dist/server.mjs.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.mjs +1 -1
- package/dist/vite.cjs +1604 -358
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.mjs +9 -5
- package/package.json +10 -1
- package/types/client.d.ts +115 -4
- package/dist/after.d.mts +0 -25
- package/dist/after.d.ts +0 -25
- package/dist/agent-runtime.d.mts +0 -94
- package/dist/agent-runtime.d.ts +0 -94
- package/dist/api/route-manager.d.mts +0 -66
- package/dist/api/route-manager.d.ts +0 -66
- package/dist/api/runtime.d.mts +0 -3
- package/dist/api/runtime.d.ts +0 -3
- package/dist/api.d.mts +0 -48
- package/dist/api.d.ts +0 -48
- package/dist/app-BNE2FoZ4.d.mts +0 -302
- package/dist/app-DRGUmJ3s.d.ts +0 -302
- package/dist/app-markdown.d.mts +0 -22
- package/dist/app-markdown.d.ts +0 -22
- package/dist/cache.d.mts +0 -192
- package/dist/cache.d.ts +0 -192
- package/dist/chunk-4677KXB7.mjs.map +0 -1
- package/dist/chunk-4LND3PXF.mjs.map +0 -1
- package/dist/chunk-5EVQFRL2.mjs.map +0 -1
- package/dist/chunk-77BOAQHI.mjs.map +0 -1
- package/dist/chunk-AW6I64AP.mjs.map +0 -1
- package/dist/chunk-K5ZTUF22.mjs.map +0 -1
- package/dist/chunk-QM746KUO.mjs +0 -56
- package/dist/chunk-QM746KUO.mjs.map +0 -1
- package/dist/chunk-QTZZ2ISQ.mjs.map +0 -1
- package/dist/client-BT1mFQas.d.mts +0 -447
- package/dist/client-Nn0q4eO4.d.ts +0 -447
- package/dist/client-cache-CIlyBlmx.d.ts +0 -6
- package/dist/client-cache-D-EZ7XVW.d.mts +0 -6
- package/dist/client-plugins-Bc5jHcNr.d.ts +0 -1927
- package/dist/client-plugins-jsk-ZLzJ.d.mts +0 -1927
- package/dist/client-plugins.d.mts +0 -22
- package/dist/client-plugins.d.ts +0 -22
- package/dist/client.d.mts +0 -447
- package/dist/client.d.ts +0 -447
- package/dist/config.d.mts +0 -29
- package/dist/config.d.ts +0 -29
- package/dist/cron.d.mts +0 -78
- package/dist/cron.d.ts +0 -78
- package/dist/deferred.d.mts +0 -42
- package/dist/deferred.d.ts +0 -42
- package/dist/deployment.d.mts +0 -34
- package/dist/deployment.d.ts +0 -34
- package/dist/docs.d.mts +0 -69
- package/dist/docs.d.ts +0 -69
- package/dist/env-types.d.mts +0 -12
- package/dist/env-types.d.ts +0 -12
- package/dist/env.d.mts +0 -45
- package/dist/env.d.ts +0 -45
- package/dist/environment/vite.d.mts +0 -22
- package/dist/environment/vite.d.ts +0 -22
- package/dist/environment.d.mts +0 -18
- package/dist/environment.d.ts +0 -18
- package/dist/font.d.mts +0 -70
- package/dist/font.d.ts +0 -70
- package/dist/headers.d.mts +0 -22
- package/dist/headers.d.ts +0 -22
- package/dist/i18n/client.d.mts +0 -32
- package/dist/i18n/client.d.ts +0 -32
- package/dist/i18n/index.d.mts +0 -20
- package/dist/i18n/index.d.ts +0 -20
- package/dist/i18n/server.d.mts +0 -30
- package/dist/i18n/server.d.ts +0 -30
- package/dist/image/server.d.mts +0 -37
- package/dist/image/server.d.ts +0 -37
- package/dist/image/sharp.d.mts +0 -7
- package/dist/image/sharp.d.ts +0 -7
- package/dist/image-config-Duob7wER.d.mts +0 -50
- package/dist/image-config-Duob7wER.d.ts +0 -50
- package/dist/image.d.mts +0 -39
- package/dist/image.d.ts +0 -39
- package/dist/index.d.mts +0 -455
- package/dist/index.d.ts +0 -455
- package/dist/integration-api-CHT2OKAf.d.mts +0 -93
- package/dist/integration-api-CHT2OKAf.d.ts +0 -93
- package/dist/integrations.d.mts +0 -22
- package/dist/integrations.d.ts +0 -22
- package/dist/internal/build-runtime.d.mts +0 -39
- package/dist/internal/build-runtime.d.ts +0 -39
- package/dist/internal/client-runtime.d.mts +0 -2
- package/dist/internal/client-runtime.d.ts +0 -2
- package/dist/internal/config-runtime.d.mts +0 -39
- package/dist/internal/config-runtime.d.ts +0 -39
- package/dist/internal/production-node-env.d.mts +0 -12
- package/dist/internal/production-node-env.d.ts +0 -12
- package/dist/internal/production-runtime.d.mts +0 -41
- package/dist/internal/production-runtime.d.ts +0 -41
- package/dist/markdown.d.mts +0 -60
- package/dist/markdown.d.ts +0 -60
- package/dist/metadata-7ffpT3jr.d.mts +0 -22
- package/dist/metadata-JHn-8eht.d.ts +0 -22
- package/dist/middleware.d.mts +0 -164
- package/dist/middleware.d.ts +0 -164
- package/dist/navigation-errors-Dvwpzaer.d.mts +0 -13
- package/dist/navigation-errors-Dvwpzaer.d.ts +0 -13
- package/dist/navigation.d.mts +0 -14
- package/dist/navigation.d.ts +0 -14
- package/dist/observability.d.mts +0 -335
- package/dist/observability.d.ts +0 -335
- package/dist/params-BALtrRim.d.ts +0 -15
- package/dist/params-ry-lxqmy.d.mts +0 -15
- package/dist/plugin-BJDf43dc.d.mts +0 -165
- package/dist/plugin-BJDf43dc.d.ts +0 -165
- package/dist/plugin.d.mts +0 -22
- package/dist/plugin.d.ts +0 -22
- package/dist/production-runtime-9KG7GuvW.d.ts +0 -79
- package/dist/production-runtime-B-fweKts.d.mts +0 -79
- package/dist/production-runtime-C_B79w2P.d.mts +0 -28
- package/dist/production-runtime-DDEM1D2q.d.ts +0 -28
- package/dist/query/client.d.mts +0 -61
- package/dist/query/client.d.ts +0 -61
- package/dist/query/index.d.mts +0 -90
- package/dist/query/index.d.ts +0 -90
- package/dist/query/parsers.d.mts +0 -25
- package/dist/query/parsers.d.ts +0 -25
- package/dist/query/server.d.mts +0 -55
- package/dist/query/server.d.ts +0 -55
- package/dist/request-Dsq4kGW0.d.mts +0 -6
- package/dist/request-udtobOLv.d.ts +0 -6
- package/dist/request.d.mts +0 -2
- package/dist/request.d.ts +0 -2
- package/dist/resolver-DJqjLMg_.d.mts +0 -14
- package/dist/resolver-IH4RmPEl.d.ts +0 -14
- package/dist/route-runtime-DoOHzCAD.d.mts +0 -38
- package/dist/route-runtime-DoOHzCAD.d.ts +0 -38
- package/dist/router.d.mts +0 -36
- package/dist/router.d.ts +0 -36
- package/dist/routes.d.mts +0 -224
- package/dist/routes.d.ts +0 -224
- package/dist/runtime-9nQjVM7X.d.mts +0 -206
- package/dist/runtime-Cxpq6xZN.d.mts +0 -27
- package/dist/runtime-DgeS2skB.d.ts +0 -206
- package/dist/runtime-bv63eUiO.d.ts +0 -27
- package/dist/server-action-security.d.mts +0 -43
- package/dist/server-action-security.d.ts +0 -43
- package/dist/server-fn-client.d.mts +0 -32
- package/dist/server-fn-client.d.ts +0 -32
- package/dist/server-fn.d.mts +0 -93
- package/dist/server-fn.d.ts +0 -93
- package/dist/server-plugins.d.mts +0 -55
- package/dist/server-plugins.d.ts +0 -55
- package/dist/server-query-client.d.mts +0 -50
- package/dist/server-query-client.d.ts +0 -50
- package/dist/server-query.d.mts +0 -36
- package/dist/server-query.d.ts +0 -36
- package/dist/server.d.mts +0 -48
- package/dist/server.d.ts +0 -48
- package/dist/storage.d.mts +0 -52
- package/dist/storage.d.ts +0 -52
- package/dist/testing.d.mts +0 -101
- package/dist/testing.d.ts +0 -101
- package/dist/transport-BmbGTXA5.d.mts +0 -49
- package/dist/transport-BmbGTXA5.d.ts +0 -49
- package/dist/types-BMxWr97v.d.mts +0 -81
- package/dist/types-BMxWr97v.d.ts +0 -81
- package/dist/types-C9N-nk5R.d.mts +0 -53
- package/dist/types-C9N-nk5R.d.ts +0 -53
- package/dist/types-D1A6-XvH.d.mts +0 -73
- package/dist/types-D1A6-XvH.d.ts +0 -73
- package/dist/utils-CA0z0c-2.d.ts +0 -23
- package/dist/utils-mYVkSOt2.d.mts +0 -23
- package/dist/version.d.mts +0 -3
- package/dist/version.d.ts +0 -3
- package/dist/vite.d.mts +0 -22
- package/dist/vite.d.ts +0 -22
- package/dist/workflows.d.mts +0 -110
- package/dist/workflows.d.ts +0 -110
- /package/dist/{chunk-7N62DNSO.mjs.map → chunk-H3TE3LOV.mjs.map} +0 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__name
|
|
3
|
+
} from "./chunk-CGILA3WO.mjs";
|
|
4
|
+
|
|
5
|
+
// src/metadata-image.ts
|
|
6
|
+
import React from "react";
|
|
7
|
+
import { renderToStaticMarkup } from "react-dom/server";
|
|
8
|
+
var REACT_FORWARD_REF_TYPE = /* @__PURE__ */ Symbol.for("react.forward_ref");
|
|
9
|
+
var REACT_MEMO_TYPE = /* @__PURE__ */ Symbol.for("react.memo");
|
|
10
|
+
var REACT_LAZY_TYPE = /* @__PURE__ */ Symbol.for("react.lazy");
|
|
11
|
+
function isResponse(value) {
|
|
12
|
+
return typeof Response !== "undefined" && (value instanceof Response || Boolean(
|
|
13
|
+
value && typeof value === "object" && typeof value.arrayBuffer === "function" && value.headers
|
|
14
|
+
));
|
|
15
|
+
}
|
|
16
|
+
__name(isResponse, "isResponse");
|
|
17
|
+
function isThenable(value) {
|
|
18
|
+
return Boolean(
|
|
19
|
+
value && (typeof value === "object" || typeof value === "function") && typeof value.then === "function"
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
__name(isThenable, "isThenable");
|
|
23
|
+
async function prepareMetadataImageNode(node) {
|
|
24
|
+
if (isThenable(node)) {
|
|
25
|
+
return prepareMetadataImageNode(await node);
|
|
26
|
+
}
|
|
27
|
+
if (Array.isArray(node)) {
|
|
28
|
+
return Promise.all(node.map((child) => prepareMetadataImageNode(child)));
|
|
29
|
+
}
|
|
30
|
+
if (!React.isValidElement(node)) {
|
|
31
|
+
return node;
|
|
32
|
+
}
|
|
33
|
+
const element = node;
|
|
34
|
+
const type = element.type;
|
|
35
|
+
const props = element.props || {};
|
|
36
|
+
if (typeof type === "function") {
|
|
37
|
+
if (type.prototype?.isReactComponent) {
|
|
38
|
+
throw new Error(
|
|
39
|
+
"Metadata image components must be stateless function components; React class components are not supported."
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
return prepareMetadataImageNode(await type(props));
|
|
43
|
+
}
|
|
44
|
+
if (type && typeof type === "object") {
|
|
45
|
+
if (type.$$typeof === REACT_MEMO_TYPE) {
|
|
46
|
+
return prepareMetadataImageNode(React.createElement(type.type, props));
|
|
47
|
+
}
|
|
48
|
+
if (type.$$typeof === REACT_FORWARD_REF_TYPE) {
|
|
49
|
+
return prepareMetadataImageNode(await type.render(props, null));
|
|
50
|
+
}
|
|
51
|
+
if (type.$$typeof === REACT_LAZY_TYPE) {
|
|
52
|
+
return prepareMetadataImageNode(React.createElement(type._init(type._payload), props));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const preparedChildren = await prepareMetadataImageNode(props.children);
|
|
56
|
+
const preparedProps = { ...props };
|
|
57
|
+
if (typeof preparedProps.className === "string") {
|
|
58
|
+
preparedProps.tw = [preparedProps.tw, preparedProps.className].filter(Boolean).join(" ");
|
|
59
|
+
delete preparedProps.className;
|
|
60
|
+
}
|
|
61
|
+
delete preparedProps.children;
|
|
62
|
+
return React.createElement(type, {
|
|
63
|
+
...preparedProps,
|
|
64
|
+
key: element.key,
|
|
65
|
+
children: preparedChildren
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
__name(prepareMetadataImageNode, "prepareMetadataImageNode");
|
|
69
|
+
async function normalizeFonts(fonts) {
|
|
70
|
+
if (!fonts?.length) return void 0;
|
|
71
|
+
return Promise.all(
|
|
72
|
+
fonts.map(async (font) => {
|
|
73
|
+
const data = await font.data;
|
|
74
|
+
const arrayBuffer = ArrayBuffer.isView(data) ? toArrayBuffer(data) : data;
|
|
75
|
+
return { ...font, data: arrayBuffer };
|
|
76
|
+
})
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
__name(normalizeFonts, "normalizeFonts");
|
|
80
|
+
function resolveCacheControl(revalidate) {
|
|
81
|
+
if (revalidate === false) {
|
|
82
|
+
return "public, max-age=31536000, immutable";
|
|
83
|
+
}
|
|
84
|
+
if (typeof revalidate === "number" && Number.isFinite(revalidate) && revalidate > 0) {
|
|
85
|
+
return `public, s-maxage=${Math.floor(revalidate)}, stale-while-revalidate=300`;
|
|
86
|
+
}
|
|
87
|
+
return "public, max-age=0, must-revalidate";
|
|
88
|
+
}
|
|
89
|
+
__name(resolveCacheControl, "resolveCacheControl");
|
|
90
|
+
function toArrayBuffer(value) {
|
|
91
|
+
if (value instanceof ArrayBuffer) return value;
|
|
92
|
+
const bytes = new Uint8Array(value.byteLength);
|
|
93
|
+
bytes.set(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));
|
|
94
|
+
return bytes.buffer;
|
|
95
|
+
}
|
|
96
|
+
__name(toArrayBuffer, "toArrayBuffer");
|
|
97
|
+
async function createEntityTag(body) {
|
|
98
|
+
const digest = await globalThis.crypto.subtle.digest("SHA-256", body);
|
|
99
|
+
const hash = Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("").slice(0, 32);
|
|
100
|
+
return `"${hash}"`;
|
|
101
|
+
}
|
|
102
|
+
__name(createEntityTag, "createEntityTag");
|
|
103
|
+
async function finalizeMetadataImageResponse(body, headers, options) {
|
|
104
|
+
const responseHeaders = new Headers(headers);
|
|
105
|
+
const etag = await createEntityTag(body);
|
|
106
|
+
responseHeaders.set("ETag", etag);
|
|
107
|
+
responseHeaders.set("Content-Length", String(body.byteLength));
|
|
108
|
+
responseHeaders.set("X-Content-Type-Options", "nosniff");
|
|
109
|
+
const matchesEntityTag = options.ifNoneMatch?.trim() === "*" || options.ifNoneMatch?.split(",").some((candidate) => candidate.trim().replace(/^W\//, "") === etag);
|
|
110
|
+
if (matchesEntityTag) {
|
|
111
|
+
return new Response(null, { status: 304, headers: responseHeaders });
|
|
112
|
+
}
|
|
113
|
+
return new Response(options.method?.toUpperCase() === "HEAD" ? null : body, {
|
|
114
|
+
status: 200,
|
|
115
|
+
headers: responseHeaders
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
__name(finalizeMetadataImageResponse, "finalizeMetadataImageResponse");
|
|
119
|
+
async function createFarmMetadataImageResponse(value, imageModule, options = {}) {
|
|
120
|
+
const method = (options.method || "GET").toUpperCase();
|
|
121
|
+
if (method !== "GET" && method !== "HEAD") {
|
|
122
|
+
return new Response(null, { status: 405, headers: { Allow: "GET, HEAD" } });
|
|
123
|
+
}
|
|
124
|
+
if (isResponse(value)) {
|
|
125
|
+
return method === "HEAD" ? new Response(null, { status: value.status, headers: value.headers }) : value;
|
|
126
|
+
}
|
|
127
|
+
const cacheControl = resolveCacheControl(imageModule.revalidate);
|
|
128
|
+
const explicitContentType = imageModule.contentType?.split(";", 1)[0]?.trim().toLowerCase();
|
|
129
|
+
if (React.isValidElement(value) && explicitContentType !== "image/svg+xml") {
|
|
130
|
+
const { ImageResponse } = await import("@vercel/og");
|
|
131
|
+
const element = await prepareMetadataImageNode(value);
|
|
132
|
+
const response = new ImageResponse(element, {
|
|
133
|
+
width: imageModule.size?.width || 1200,
|
|
134
|
+
height: imageModule.size?.height || 630,
|
|
135
|
+
fonts: await normalizeFonts(imageModule.fonts),
|
|
136
|
+
emoji: imageModule.emoji,
|
|
137
|
+
debug: imageModule.debug,
|
|
138
|
+
headers: { "cache-control": cacheControl }
|
|
139
|
+
});
|
|
140
|
+
const headers = new Headers(response.headers);
|
|
141
|
+
headers.set("Cache-Control", cacheControl);
|
|
142
|
+
return finalizeMetadataImageResponse(await response.arrayBuffer(), headers, options);
|
|
143
|
+
}
|
|
144
|
+
let body;
|
|
145
|
+
if (typeof value === "string") {
|
|
146
|
+
body = toArrayBuffer(new TextEncoder().encode(value));
|
|
147
|
+
} else if (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {
|
|
148
|
+
body = toArrayBuffer(value);
|
|
149
|
+
} else if (React.isValidElement(value)) {
|
|
150
|
+
body = toArrayBuffer(new TextEncoder().encode(renderToStaticMarkup(value)));
|
|
151
|
+
} else {
|
|
152
|
+
throw new Error("Metadata image must return a Response, string, bytes, or React element");
|
|
153
|
+
}
|
|
154
|
+
return finalizeMetadataImageResponse(
|
|
155
|
+
body,
|
|
156
|
+
{
|
|
157
|
+
"Content-Type": imageModule.contentType || "image/svg+xml; charset=utf-8",
|
|
158
|
+
"Cache-Control": cacheControl
|
|
159
|
+
},
|
|
160
|
+
options
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
__name(createFarmMetadataImageResponse, "createFarmMetadataImageResponse");
|
|
164
|
+
|
|
165
|
+
export {
|
|
166
|
+
createFarmMetadataImageResponse
|
|
167
|
+
};
|
|
168
|
+
//# sourceMappingURL=chunk-53MVSX3R.mjs.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":[]}
|
|
@@ -3,6 +3,19 @@ import {
|
|
|
3
3
|
} from "./chunk-CGILA3WO.mjs";
|
|
4
4
|
|
|
5
5
|
// src/font.ts
|
|
6
|
+
function defineLayoutFonts(fonts) {
|
|
7
|
+
return fonts;
|
|
8
|
+
}
|
|
9
|
+
__name(defineLayoutFonts, "defineLayoutFonts");
|
|
10
|
+
function resolveFarmLayoutFonts(layouts) {
|
|
11
|
+
let resolved;
|
|
12
|
+
for (const layout of layouts) {
|
|
13
|
+
if (!layout.fonts) continue;
|
|
14
|
+
resolved = { ...resolved, ...layout.fonts };
|
|
15
|
+
}
|
|
16
|
+
return resolved;
|
|
17
|
+
}
|
|
18
|
+
__name(resolveFarmLayoutFonts, "resolveFarmLayoutFonts");
|
|
6
19
|
function fontCompilerError(loader) {
|
|
7
20
|
throw new Error(
|
|
8
21
|
`[Farm fonts] ${loader}() must be called at module scope with static options and compiled by the Farm Vite plugin.`
|
|
@@ -19,7 +32,9 @@ function remoteFont(_options) {
|
|
|
19
32
|
__name(remoteFont, "remoteFont");
|
|
20
33
|
|
|
21
34
|
export {
|
|
35
|
+
defineLayoutFonts,
|
|
36
|
+
resolveFarmLayoutFonts,
|
|
22
37
|
localFont,
|
|
23
38
|
remoteFont
|
|
24
39
|
};
|
|
25
|
-
//# sourceMappingURL=chunk-
|
|
40
|
+
//# sourceMappingURL=chunk-6ZXIQSXE.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/font.ts"],"sourcesContent":["export type FarmFontDisplay = \"auto\" | \"block\" | \"swap\" | \"fallback\" | \"optional\";\n\nexport interface FarmFontSource {\n /** Local file path or remote URL, depending on the loader. */\n path: string;\n /** A fixed weight (`400`) or variable range (`100 900`). */\n weight?: number | string;\n /** Font style for this source. */\n style?: string;\n /** Optional CSS unicode-range descriptor. */\n unicodeRange?: string;\n}\n\nexport interface FarmFontOptions {\n /** CSS font-family name. */\n family: string;\n /** A fixed weight (`400`) or variable range (`100 900`). */\n weight?: number | string;\n /** Font style. @default \"normal\" */\n style?: string;\n /** Browser loading behavior. @default \"swap\" */\n display?: FarmFontDisplay;\n /** CSS custom property populated by `variable`, for example `--font-sans`. */\n variable?: `--${string}`;\n /** Fallback family names appended to the generated stack. */\n fallback?: string[];\n /** Emit font preload hints. @default true */\n preload?: boolean;\n}\n\nexport interface LocalFontOptions extends FarmFontOptions {\n /**\n * A file relative to this module, a package font specifier, or explicit\n * sources for a multi-weight family.\n */\n src: string | FarmFontSource[];\n}\n\nexport interface RemoteFontSource extends FarmFontSource {\n /** Optional integrity value for this source. Overrides the family-level value. */\n integrity?: string;\n}\n\nexport interface RemoteFontOptions extends FarmFontOptions {\n /** HTTPS font URL, or explicit remote sources for a multi-weight family. */\n src: string | RemoteFontSource[];\n /** Download and fingerprint the font during the build, or retain its URL. */\n strategy?: \"self-host\" | \"external\";\n /** Optional Subresource Integrity value checked while self-hosting. */\n integrity?: string;\n}\n\nexport interface FarmFont {\n /** Generated class that applies the font family and fallback stack. */\n className: string;\n /** Generated class that defines the configured CSS custom property. */\n variable: string;\n /** Inline-style equivalent of the generated family. */\n style: Readonly<{\n fontFamily: string;\n fontStyle?: string;\n fontWeight?: number | string;\n }>;\n /** Compiled resources that should be preloaded when this font is selected. */\n preloads: readonly Readonly<{\n href: string;\n type: string;\n }>[];\n}\n\n/** Semantic font roles inherited by framework-owned surfaces such as Farm Docs. */\nexport interface FarmLayoutFonts {\n /** Default text and prose font. */\n body?: FarmFont;\n /** Code, keyboard input, and other technical UI font. */\n code?: FarmFont;\n}\n\nexport interface FarmLayoutFontModule {\n fonts?: FarmLayoutFonts;\n}\n\n/**\n * Define the semantic fonts exported by a layout.\n *\n * Layouts are resolved from the root toward the requested route. A nearer\n * layout overrides only the roles it defines, so it can replace `body` while\n * continuing to inherit `code` from a parent layout.\n */\nexport function defineLayoutFonts<const T extends FarmLayoutFonts>(fonts: T): T {\n return fonts;\n}\n\n/** Resolve semantic font roles from root layout to nearest layout. */\nexport function resolveFarmLayoutFonts(\n layouts: readonly FarmLayoutFontModule[],\n): FarmLayoutFonts | undefined {\n let resolved: FarmLayoutFonts | undefined;\n\n for (const layout of layouts) {\n if (!layout.fonts) continue;\n resolved = { ...resolved, ...layout.fonts };\n }\n\n return resolved;\n}\n\nfunction fontCompilerError(loader: string): never {\n throw new Error(\n `[Farm fonts] ${loader}() must be called at module scope with static options and compiled by the Farm Vite plugin.`,\n );\n}\n\n/**\n * Compile local font files into hashed application assets and generated CSS.\n * The call is removed at build time and adds no font-loader runtime code.\n */\nexport function localFont(_options: LocalFontOptions): FarmFont {\n return fontCompilerError(\"localFont\");\n}\n\n/**\n * Compile a remote font into a self-hosted application asset by default.\n * Use `strategy: \"external\"` only when the browser should retain the remote URL.\n */\nexport function remoteFont(_options: RemoteFontOptions): FarmFont {\n return fontCompilerError(\"remoteFont\");\n}\n"],"mappings":";;;;;AAyFO,SAAS,kBAAmD,OAAa;AAC9E,SAAO;AACT;AAFgB;AAKT,SAAS,uBACd,SAC6B;AAC7B,MAAI;AAEJ,aAAW,UAAU,SAAS;AAC5B,QAAI,CAAC,OAAO,MAAO;AACnB,eAAW,EAAE,GAAG,UAAU,GAAG,OAAO,MAAM;AAAA,EAC5C;AAEA,SAAO;AACT;AAXgB;AAahB,SAAS,kBAAkB,QAAuB;AAChD,QAAM,IAAI;AAAA,IACR,gBAAgB,MAAM;AAAA,EACxB;AACF;AAJS;AAUF,SAAS,UAAU,UAAsC;AAC9D,SAAO,kBAAkB,WAAW;AACtC;AAFgB;AAQT,SAAS,WAAW,UAAuC;AAChE,SAAO,kBAAkB,YAAY;AACvC;AAFgB;","names":[]}
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__name
|
|
3
|
+
} from "./chunk-CGILA3WO.mjs";
|
|
4
|
+
|
|
5
|
+
// src/preload.ts
|
|
6
|
+
var DEFAULT_PRELOAD_CONFIG = {
|
|
7
|
+
mode: "enforce",
|
|
8
|
+
maxImages: 1,
|
|
9
|
+
maxFonts: 2
|
|
10
|
+
};
|
|
11
|
+
var reportedWarnings = /* @__PURE__ */ new Map();
|
|
12
|
+
var PRELOAD_WARNING_TTL_MS = 6e4;
|
|
13
|
+
var MAX_REPORTED_PRELOAD_WARNINGS = 256;
|
|
14
|
+
function resolveFarmPerformanceConfig(config) {
|
|
15
|
+
return {
|
|
16
|
+
preload: {
|
|
17
|
+
mode: config?.preload?.mode === "warn" ? "warn" : "enforce",
|
|
18
|
+
maxImages: normalizeBudget(config?.preload?.maxImages, DEFAULT_PRELOAD_CONFIG.maxImages),
|
|
19
|
+
maxFonts: normalizeBudget(config?.preload?.maxFonts, DEFAULT_PRELOAD_CONFIG.maxFonts)
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
__name(resolveFarmPerformanceConfig, "resolveFarmPerformanceConfig");
|
|
24
|
+
function manageFarmHtmlPreloads(html, config) {
|
|
25
|
+
const elements = findHtmlLinkElements(html);
|
|
26
|
+
const candidates = elements.flatMap((element, index) => {
|
|
27
|
+
const kind = getHtmlPreloadKind(element.value);
|
|
28
|
+
return kind ? [
|
|
29
|
+
{
|
|
30
|
+
index,
|
|
31
|
+
kind,
|
|
32
|
+
highPriority: readHtmlAttribute(element.value, "fetchpriority")?.toLowerCase() === "high"
|
|
33
|
+
}
|
|
34
|
+
] : [];
|
|
35
|
+
});
|
|
36
|
+
const budget = selectPreloadsWithinBudget(candidates, config);
|
|
37
|
+
if (config.mode === "warn" || budget.removed.size === 0) {
|
|
38
|
+
return { value: html, warnings: budget.warnings };
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
value: removeHtmlLinkElements(html, elements, budget.removed),
|
|
42
|
+
warnings: budget.warnings
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
__name(manageFarmHtmlPreloads, "manageFarmHtmlPreloads");
|
|
46
|
+
function manageFarmLinkHeaderPreloads(value, config) {
|
|
47
|
+
if (!value) return { value, warnings: [] };
|
|
48
|
+
const links = splitLinkHeader(value);
|
|
49
|
+
const candidates = links.flatMap((link, index) => {
|
|
50
|
+
const kind = getLinkHeaderPreloadKind(link);
|
|
51
|
+
return kind ? [
|
|
52
|
+
{
|
|
53
|
+
index,
|
|
54
|
+
kind,
|
|
55
|
+
highPriority: getLinkHeaderParameter(link, "fetchpriority")?.toLowerCase() === "high"
|
|
56
|
+
}
|
|
57
|
+
] : [];
|
|
58
|
+
});
|
|
59
|
+
const budget = selectPreloadsWithinBudget(candidates, config);
|
|
60
|
+
return {
|
|
61
|
+
value: config.mode === "enforce" ? links.filter((_, index) => !budget.removed.has(index)).join(", ") : value,
|
|
62
|
+
warnings: budget.warnings
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
__name(manageFarmLinkHeaderPreloads, "manageFarmLinkHeaderPreloads");
|
|
66
|
+
function manageFarmDocumentPreloads(html, linkHeader, config) {
|
|
67
|
+
const elements = findHtmlLinkElements(html);
|
|
68
|
+
const links = linkHeader ? splitLinkHeader(linkHeader) : [];
|
|
69
|
+
const headerOffset = elements.length;
|
|
70
|
+
const candidates = [];
|
|
71
|
+
for (const [index, element] of elements.entries()) {
|
|
72
|
+
const kind = getHtmlPreloadKind(element.value);
|
|
73
|
+
if (!kind) continue;
|
|
74
|
+
candidates.push({
|
|
75
|
+
index,
|
|
76
|
+
kind,
|
|
77
|
+
highPriority: readHtmlAttribute(element.value, "fetchpriority")?.toLowerCase() === "high"
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
for (const [index, link] of links.entries()) {
|
|
81
|
+
const kind = getLinkHeaderPreloadKind(link);
|
|
82
|
+
if (!kind) continue;
|
|
83
|
+
candidates.push({
|
|
84
|
+
index: headerOffset + index,
|
|
85
|
+
kind,
|
|
86
|
+
highPriority: getLinkHeaderParameter(link, "fetchpriority")?.toLowerCase() === "high"
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
const budget = selectPreloadsWithinBudget(candidates, config);
|
|
90
|
+
if (config.mode === "warn" || budget.removed.size === 0) {
|
|
91
|
+
return { html, linkHeader, warnings: budget.warnings };
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
html: removeHtmlLinkElements(html, elements, budget.removed),
|
|
95
|
+
linkHeader: links.filter((_, index) => !budget.removed.has(headerOffset + index)).join(", "),
|
|
96
|
+
warnings: budget.warnings
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
__name(manageFarmDocumentPreloads, "manageFarmDocumentPreloads");
|
|
100
|
+
function reportFarmPreloadWarnings(warnings, context = "the rendered document") {
|
|
101
|
+
const now = Date.now();
|
|
102
|
+
for (const [key, reportedAt] of reportedWarnings) {
|
|
103
|
+
if (now - reportedAt >= PRELOAD_WARNING_TTL_MS) reportedWarnings.delete(key);
|
|
104
|
+
}
|
|
105
|
+
for (const warning of warnings) {
|
|
106
|
+
const key = `${context}:${warning.kind}:${warning.count}:${warning.budget}:${warning.removed}`;
|
|
107
|
+
const reportedAt = reportedWarnings.get(key);
|
|
108
|
+
if (reportedAt !== void 0 && now - reportedAt < PRELOAD_WARNING_TTL_MS) continue;
|
|
109
|
+
reportedWarnings.set(key, now);
|
|
110
|
+
while (reportedWarnings.size > MAX_REPORTED_PRELOAD_WARNINGS) {
|
|
111
|
+
const oldest = reportedWarnings.keys().next().value;
|
|
112
|
+
if (oldest === void 0) break;
|
|
113
|
+
reportedWarnings.delete(oldest);
|
|
114
|
+
}
|
|
115
|
+
const action = warning.removed > 0 ? ` Removed ${warning.removed} lower-priority hint(s).` : "";
|
|
116
|
+
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.";
|
|
117
|
+
console.warn(
|
|
118
|
+
`[Farm.js] ${context} emitted ${warning.count} ${warning.kind} preload hints (budget: ${warning.budget}).${action}${recommendation}`
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
__name(reportFarmPreloadWarnings, "reportFarmPreloadWarnings");
|
|
123
|
+
function selectPreloadsWithinBudget(candidates, config) {
|
|
124
|
+
const removed = /* @__PURE__ */ new Set();
|
|
125
|
+
const warnings = [];
|
|
126
|
+
for (const kind of ["image", "font"]) {
|
|
127
|
+
const matching = candidates.filter((candidate) => candidate.kind === kind);
|
|
128
|
+
const limit = kind === "image" ? config.maxImages : config.maxFonts;
|
|
129
|
+
if (matching.length <= limit) continue;
|
|
130
|
+
const retained = new Set(
|
|
131
|
+
[...matching].sort(
|
|
132
|
+
(left, right) => Number(right.highPriority) - Number(left.highPriority) || left.index - right.index
|
|
133
|
+
).slice(0, limit).map((candidate) => candidate.index)
|
|
134
|
+
);
|
|
135
|
+
if (config.mode === "enforce") {
|
|
136
|
+
for (const candidate of matching) {
|
|
137
|
+
if (!retained.has(candidate.index)) removed.add(candidate.index);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
warnings.push({
|
|
141
|
+
kind,
|
|
142
|
+
count: matching.length,
|
|
143
|
+
budget: limit,
|
|
144
|
+
removed: config.mode === "enforce" ? matching.length - retained.size : 0
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
return { removed, warnings };
|
|
148
|
+
}
|
|
149
|
+
__name(selectPreloadsWithinBudget, "selectPreloadsWithinBudget");
|
|
150
|
+
function getHtmlPreloadKind(link) {
|
|
151
|
+
const rel = readHtmlAttribute(link, "rel")?.toLowerCase().split(/\s+/) || [];
|
|
152
|
+
if (!rel.includes("preload")) return void 0;
|
|
153
|
+
return normalizePreloadKind(readHtmlAttribute(link, "as"));
|
|
154
|
+
}
|
|
155
|
+
__name(getHtmlPreloadKind, "getHtmlPreloadKind");
|
|
156
|
+
function getLinkHeaderPreloadKind(link) {
|
|
157
|
+
const relations = getLinkHeaderParameter(link, "rel")?.toLowerCase().split(/\s+/) ?? [];
|
|
158
|
+
if (!relations.includes("preload")) return void 0;
|
|
159
|
+
return normalizePreloadKind(getLinkHeaderParameter(link, "as"));
|
|
160
|
+
}
|
|
161
|
+
__name(getLinkHeaderPreloadKind, "getLinkHeaderPreloadKind");
|
|
162
|
+
function getLinkHeaderParameter(link, name) {
|
|
163
|
+
const uriEnd = link.indexOf(">");
|
|
164
|
+
if (uriEnd === -1) return void 0;
|
|
165
|
+
for (const parameter of splitLinkParameters(link.slice(uriEnd + 1))) {
|
|
166
|
+
const separator = parameter.indexOf("=");
|
|
167
|
+
const parameterName = (separator === -1 ? parameter : parameter.slice(0, separator)).trim().toLowerCase();
|
|
168
|
+
if (parameterName !== name.toLowerCase() || separator === -1) continue;
|
|
169
|
+
const rawValue = parameter.slice(separator + 1).trim();
|
|
170
|
+
if (rawValue.startsWith('"') && rawValue.endsWith('"')) {
|
|
171
|
+
return rawValue.slice(1, -1).replace(/\\([\\"])/g, "$1");
|
|
172
|
+
}
|
|
173
|
+
return rawValue;
|
|
174
|
+
}
|
|
175
|
+
return void 0;
|
|
176
|
+
}
|
|
177
|
+
__name(getLinkHeaderParameter, "getLinkHeaderParameter");
|
|
178
|
+
function splitLinkParameters(value) {
|
|
179
|
+
const parameters = [];
|
|
180
|
+
let start = 0;
|
|
181
|
+
let quoted = false;
|
|
182
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
183
|
+
const character = value[index];
|
|
184
|
+
if (character === '"' && !isEscaped(value, index)) quoted = !quoted;
|
|
185
|
+
else if (character === ";" && !quoted) {
|
|
186
|
+
const parameter2 = value.slice(start, index).trim();
|
|
187
|
+
if (parameter2) parameters.push(parameter2);
|
|
188
|
+
start = index + 1;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
const parameter = value.slice(start).trim();
|
|
192
|
+
if (parameter) parameters.push(parameter);
|
|
193
|
+
return parameters;
|
|
194
|
+
}
|
|
195
|
+
__name(splitLinkParameters, "splitLinkParameters");
|
|
196
|
+
function normalizePreloadKind(value) {
|
|
197
|
+
const normalized = value?.toLowerCase();
|
|
198
|
+
return normalized === "image" || normalized === "font" ? normalized : void 0;
|
|
199
|
+
}
|
|
200
|
+
__name(normalizePreloadKind, "normalizePreloadKind");
|
|
201
|
+
function readHtmlAttribute(element, name) {
|
|
202
|
+
const match = element.match(
|
|
203
|
+
new RegExp(`\\s${name}\\s*=\\s*(?:"([^"]*)"|'([^']*)'|([^\\s>]+))`, "i")
|
|
204
|
+
);
|
|
205
|
+
return match?.[1] ?? match?.[2] ?? match?.[3];
|
|
206
|
+
}
|
|
207
|
+
__name(readHtmlAttribute, "readHtmlAttribute");
|
|
208
|
+
function findHtmlLinkElements(html) {
|
|
209
|
+
const elements = [];
|
|
210
|
+
const lowerHtml = html.toLowerCase();
|
|
211
|
+
let cursor = 0;
|
|
212
|
+
while (cursor < html.length) {
|
|
213
|
+
const start = html.indexOf("<", cursor);
|
|
214
|
+
if (start === -1) break;
|
|
215
|
+
if (lowerHtml.startsWith("<!--", start)) {
|
|
216
|
+
const commentEnd = lowerHtml.indexOf("-->", start + 4);
|
|
217
|
+
cursor = commentEnd === -1 ? html.length : commentEnd + 3;
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
const rawText = lowerHtml.slice(start).match(/^<(script|style|template|textarea|title|noscript|svg)(?=[\s/>])/);
|
|
221
|
+
if (rawText?.[1]) {
|
|
222
|
+
const openingEnd = findHtmlTagEnd(html, start);
|
|
223
|
+
if (openingEnd === -1) break;
|
|
224
|
+
const closingStart = findHtmlClosingTag(lowerHtml, rawText[1], openingEnd);
|
|
225
|
+
if (closingStart === -1) {
|
|
226
|
+
cursor = html.length;
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
const closingEnd = findHtmlTagEnd(html, closingStart);
|
|
230
|
+
cursor = closingEnd === -1 ? html.length : closingEnd;
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (/^<link(?=[\s/>])/i.test(html.slice(start))) {
|
|
234
|
+
const end = findHtmlTagEnd(html, start);
|
|
235
|
+
if (end === -1) break;
|
|
236
|
+
elements.push({ start, end, value: html.slice(start, end) });
|
|
237
|
+
cursor = end;
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
if (/^<\/?[A-Za-z][\w:-]*(?=[\s/>])/.test(html.slice(start))) {
|
|
241
|
+
const end = findHtmlTagEnd(html, start);
|
|
242
|
+
cursor = end === -1 ? html.length : end;
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
cursor = start + 1;
|
|
246
|
+
}
|
|
247
|
+
return elements;
|
|
248
|
+
}
|
|
249
|
+
__name(findHtmlLinkElements, "findHtmlLinkElements");
|
|
250
|
+
function findHtmlClosingTag(html, tagName, start) {
|
|
251
|
+
const prefix = `</${tagName}`;
|
|
252
|
+
let candidate = html.indexOf(prefix, start);
|
|
253
|
+
while (candidate !== -1) {
|
|
254
|
+
const boundary = html[candidate + prefix.length];
|
|
255
|
+
if (boundary === ">" || boundary === "/" || /\s/.test(boundary ?? "")) return candidate;
|
|
256
|
+
candidate = html.indexOf(prefix, candidate + prefix.length);
|
|
257
|
+
}
|
|
258
|
+
return -1;
|
|
259
|
+
}
|
|
260
|
+
__name(findHtmlClosingTag, "findHtmlClosingTag");
|
|
261
|
+
function findHtmlTagEnd(html, start) {
|
|
262
|
+
let quote;
|
|
263
|
+
for (let index = start + 1; index < html.length; index += 1) {
|
|
264
|
+
const character = html[index];
|
|
265
|
+
if (quote) {
|
|
266
|
+
if (character === quote) quote = void 0;
|
|
267
|
+
} else if (character === '"' || character === "'") {
|
|
268
|
+
quote = character;
|
|
269
|
+
} else if (character === ">") {
|
|
270
|
+
return index + 1;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return -1;
|
|
274
|
+
}
|
|
275
|
+
__name(findHtmlTagEnd, "findHtmlTagEnd");
|
|
276
|
+
function removeHtmlLinkElements(html, elements, removed) {
|
|
277
|
+
let cursor = 0;
|
|
278
|
+
let output = "";
|
|
279
|
+
for (const [index, element] of elements.entries()) {
|
|
280
|
+
if (!removed.has(index)) continue;
|
|
281
|
+
output += html.slice(cursor, element.start);
|
|
282
|
+
cursor = element.end;
|
|
283
|
+
}
|
|
284
|
+
return output + html.slice(cursor);
|
|
285
|
+
}
|
|
286
|
+
__name(removeHtmlLinkElements, "removeHtmlLinkElements");
|
|
287
|
+
function splitLinkHeader(value) {
|
|
288
|
+
const links = [];
|
|
289
|
+
let start = 0;
|
|
290
|
+
let insideAngleBrackets = false;
|
|
291
|
+
let quoted = false;
|
|
292
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
293
|
+
const character = value[index];
|
|
294
|
+
if (quoted) {
|
|
295
|
+
if (character === '"' && !isEscaped(value, index)) quoted = false;
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
if (character === '"') {
|
|
299
|
+
quoted = true;
|
|
300
|
+
} else if (character === "<") {
|
|
301
|
+
insideAngleBrackets = true;
|
|
302
|
+
} else if (character === ">") {
|
|
303
|
+
insideAngleBrackets = false;
|
|
304
|
+
} else if (character === "," && !insideAngleBrackets) {
|
|
305
|
+
links.push(value.slice(start, index).trim());
|
|
306
|
+
start = index + 1;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
links.push(value.slice(start).trim());
|
|
310
|
+
return links.filter(Boolean);
|
|
311
|
+
}
|
|
312
|
+
__name(splitLinkHeader, "splitLinkHeader");
|
|
313
|
+
function isEscaped(value, index) {
|
|
314
|
+
let backslashes = 0;
|
|
315
|
+
for (let cursor = index - 1; cursor >= 0 && value[cursor] === "\\"; cursor -= 1) {
|
|
316
|
+
backslashes += 1;
|
|
317
|
+
}
|
|
318
|
+
return backslashes % 2 === 1;
|
|
319
|
+
}
|
|
320
|
+
__name(isEscaped, "isEscaped");
|
|
321
|
+
function normalizeBudget(value, fallback) {
|
|
322
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.floor(value) : fallback;
|
|
323
|
+
}
|
|
324
|
+
__name(normalizeBudget, "normalizeBudget");
|
|
325
|
+
|
|
326
|
+
export {
|
|
327
|
+
resolveFarmPerformanceConfig,
|
|
328
|
+
manageFarmHtmlPreloads,
|
|
329
|
+
manageFarmLinkHeaderPreloads,
|
|
330
|
+
manageFarmDocumentPreloads,
|
|
331
|
+
reportFarmPreloadWarnings
|
|
332
|
+
};
|
|
333
|
+
//# sourceMappingURL=chunk-7ZVN3YZI.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/preload.ts"],"sourcesContent":["export type FarmPreloadMode = \"warn\" | \"enforce\";\n\nexport interface FarmPreloadUserConfig {\n /** Report excess hints or remove the lower-priority hints. @default \"enforce\" */\n mode?: FarmPreloadMode;\n /** Maximum image preload hints per document. @default 1 */\n maxImages?: number;\n /** Maximum font preload hints per document. @default 2 */\n maxFonts?: number;\n}\n\nexport interface ResolvedFarmPreloadConfig {\n mode: FarmPreloadMode;\n maxImages: number;\n maxFonts: number;\n}\n\nexport interface FarmPerformanceConfig {\n preload?: FarmPreloadUserConfig;\n}\n\nexport interface ResolvedFarmPerformanceConfig {\n preload: ResolvedFarmPreloadConfig;\n}\n\nexport type FarmPreloadKind = \"image\" | \"font\";\n\nexport interface FarmPreloadBudgetWarning {\n kind: FarmPreloadKind;\n count: number;\n budget: number;\n removed: number;\n}\n\nexport interface FarmManagedPreloads {\n value: string;\n warnings: FarmPreloadBudgetWarning[];\n}\n\nexport interface FarmManagedDocumentPreloads {\n html: string;\n linkHeader: string;\n warnings: FarmPreloadBudgetWarning[];\n}\n\nconst DEFAULT_PRELOAD_CONFIG: ResolvedFarmPreloadConfig = {\n mode: \"enforce\",\n maxImages: 1,\n maxFonts: 2,\n};\n\nconst reportedWarnings = new Map<string, number>();\nconst PRELOAD_WARNING_TTL_MS = 60_000;\nconst MAX_REPORTED_PRELOAD_WARNINGS = 256;\n\nexport function resolveFarmPerformanceConfig(\n config: FarmPerformanceConfig | undefined,\n): ResolvedFarmPerformanceConfig {\n return {\n preload: {\n mode: config?.preload?.mode === \"warn\" ? \"warn\" : \"enforce\",\n maxImages: normalizeBudget(config?.preload?.maxImages, DEFAULT_PRELOAD_CONFIG.maxImages),\n maxFonts: normalizeBudget(config?.preload?.maxFonts, DEFAULT_PRELOAD_CONFIG.maxFonts),\n },\n };\n}\n\n/**\n * Apply image and font budgets to HTML preload elements. High-priority image\n * hints are retained before ordinary hints, making an explicitly preloaded LCP\n * image the winner when a document contains too many React-generated hints.\n */\nexport function manageFarmHtmlPreloads(\n html: string,\n config: ResolvedFarmPreloadConfig,\n): FarmManagedPreloads {\n const elements = findHtmlLinkElements(html);\n const candidates = elements.flatMap((element, index) => {\n const kind = getHtmlPreloadKind(element.value);\n return kind\n ? [\n {\n index,\n kind,\n highPriority:\n readHtmlAttribute(element.value, \"fetchpriority\")?.toLowerCase() === \"high\",\n },\n ]\n : [];\n });\n\n const budget = selectPreloadsWithinBudget(candidates, config);\n if (config.mode === \"warn\" || budget.removed.size === 0) {\n return { value: html, warnings: budget.warnings };\n }\n\n return {\n value: removeHtmlLinkElements(html, elements, budget.removed),\n warnings: budget.warnings,\n };\n}\n\n/** Apply the same budgets to HTTP Link preload hints, including Farm fonts. */\nexport function manageFarmLinkHeaderPreloads(\n value: string,\n config: ResolvedFarmPreloadConfig,\n): FarmManagedPreloads {\n if (!value) return { value, warnings: [] };\n\n const links = splitLinkHeader(value);\n const candidates = links.flatMap((link, index) => {\n const kind = getLinkHeaderPreloadKind(link);\n return kind\n ? [\n {\n index,\n kind,\n highPriority: getLinkHeaderParameter(link, \"fetchpriority\")?.toLowerCase() === \"high\",\n },\n ]\n : [];\n });\n const budget = selectPreloadsWithinBudget(candidates, config);\n\n return {\n value:\n config.mode === \"enforce\"\n ? links.filter((_, index) => !budget.removed.has(index)).join(\", \")\n : value,\n warnings: budget.warnings,\n };\n}\n\n/** Apply a single document budget across HTML and HTTP Link header hints. */\nexport function manageFarmDocumentPreloads(\n html: string,\n linkHeader: string,\n config: ResolvedFarmPreloadConfig,\n): FarmManagedDocumentPreloads {\n const elements = findHtmlLinkElements(html);\n const links = linkHeader ? splitLinkHeader(linkHeader) : [];\n const headerOffset = elements.length;\n const candidates: PreloadCandidate[] = [];\n\n for (const [index, element] of elements.entries()) {\n const kind = getHtmlPreloadKind(element.value);\n if (!kind) continue;\n candidates.push({\n index,\n kind,\n highPriority: readHtmlAttribute(element.value, \"fetchpriority\")?.toLowerCase() === \"high\",\n });\n }\n for (const [index, link] of links.entries()) {\n const kind = getLinkHeaderPreloadKind(link);\n if (!kind) continue;\n candidates.push({\n index: headerOffset + index,\n kind,\n highPriority: getLinkHeaderParameter(link, \"fetchpriority\")?.toLowerCase() === \"high\",\n });\n }\n\n const budget = selectPreloadsWithinBudget(candidates, config);\n if (config.mode === \"warn\" || budget.removed.size === 0) {\n return { html, linkHeader, warnings: budget.warnings };\n }\n\n return {\n html: removeHtmlLinkElements(html, elements, budget.removed),\n linkHeader: links.filter((_, index) => !budget.removed.has(headerOffset + index)).join(\", \"),\n warnings: budget.warnings,\n };\n}\n\n/** Rate-limit identical route-and-budget warnings within a server process. */\nexport function reportFarmPreloadWarnings(\n warnings: FarmPreloadBudgetWarning[],\n context = \"the rendered document\",\n): void {\n const now = Date.now();\n for (const [key, reportedAt] of reportedWarnings) {\n if (now - reportedAt >= PRELOAD_WARNING_TTL_MS) reportedWarnings.delete(key);\n }\n\n for (const warning of warnings) {\n const key = `${context}:${warning.kind}:${warning.count}:${warning.budget}:${warning.removed}`;\n const reportedAt = reportedWarnings.get(key);\n if (reportedAt !== undefined && now - reportedAt < PRELOAD_WARNING_TTL_MS) continue;\n reportedWarnings.set(key, now);\n while (reportedWarnings.size > MAX_REPORTED_PRELOAD_WARNINGS) {\n const oldest = reportedWarnings.keys().next().value;\n if (oldest === undefined) break;\n reportedWarnings.delete(oldest);\n }\n\n const action = warning.removed > 0 ? ` Removed ${warning.removed} lower-priority hint(s).` : \"\";\n const recommendation =\n warning.kind === \"image\"\n ? ' Mark only the LCP image with `preload` or `fetchPriority=\"high\"`.'\n : \" Set `preload: false` on fonts that are not required above the fold.\";\n console.warn(\n `[Farm.js] ${context} emitted ${warning.count} ${warning.kind} preload hints ` +\n `(budget: ${warning.budget}).${action}${recommendation}`,\n );\n }\n}\n\nexport function clearReportedFarmPreloadWarnings(): void {\n reportedWarnings.clear();\n}\n\ninterface PreloadCandidate {\n index: number;\n kind: FarmPreloadKind;\n highPriority: boolean;\n}\n\nfunction selectPreloadsWithinBudget(\n candidates: PreloadCandidate[],\n config: ResolvedFarmPreloadConfig,\n): { removed: Set<number>; warnings: FarmPreloadBudgetWarning[] } {\n const removed = new Set<number>();\n const warnings: FarmPreloadBudgetWarning[] = [];\n\n for (const kind of [\"image\", \"font\"] as const) {\n const matching = candidates.filter((candidate) => candidate.kind === kind);\n const limit = kind === \"image\" ? config.maxImages : config.maxFonts;\n if (matching.length <= limit) continue;\n\n const retained = new Set(\n [...matching]\n .sort(\n (left, right) =>\n Number(right.highPriority) - Number(left.highPriority) || left.index - right.index,\n )\n .slice(0, limit)\n .map((candidate) => candidate.index),\n );\n\n if (config.mode === \"enforce\") {\n for (const candidate of matching) {\n if (!retained.has(candidate.index)) removed.add(candidate.index);\n }\n }\n\n warnings.push({\n kind,\n count: matching.length,\n budget: limit,\n removed: config.mode === \"enforce\" ? matching.length - retained.size : 0,\n });\n }\n\n return { removed, warnings };\n}\n\nfunction getHtmlPreloadKind(link: string): FarmPreloadKind | undefined {\n const rel = readHtmlAttribute(link, \"rel\")?.toLowerCase().split(/\\s+/) || [];\n if (!rel.includes(\"preload\")) return undefined;\n return normalizePreloadKind(readHtmlAttribute(link, \"as\"));\n}\n\nfunction getLinkHeaderPreloadKind(link: string): FarmPreloadKind | undefined {\n const relations = getLinkHeaderParameter(link, \"rel\")?.toLowerCase().split(/\\s+/) ?? [];\n if (!relations.includes(\"preload\")) return undefined;\n return normalizePreloadKind(getLinkHeaderParameter(link, \"as\"));\n}\n\nfunction getLinkHeaderParameter(link: string, name: string): string | undefined {\n const uriEnd = link.indexOf(\">\");\n if (uriEnd === -1) return undefined;\n\n for (const parameter of splitLinkParameters(link.slice(uriEnd + 1))) {\n const separator = parameter.indexOf(\"=\");\n const parameterName = (separator === -1 ? parameter : parameter.slice(0, separator))\n .trim()\n .toLowerCase();\n if (parameterName !== name.toLowerCase() || separator === -1) continue;\n const rawValue = parameter.slice(separator + 1).trim();\n if (rawValue.startsWith('\"') && rawValue.endsWith('\"')) {\n return rawValue.slice(1, -1).replace(/\\\\([\\\\\"])/g, \"$1\");\n }\n return rawValue;\n }\n return undefined;\n}\n\nfunction splitLinkParameters(value: string): string[] {\n const parameters: string[] = [];\n let start = 0;\n let quoted = false;\n for (let index = 0; index < value.length; index += 1) {\n const character = value[index];\n if (character === '\"' && !isEscaped(value, index)) quoted = !quoted;\n else if (character === \";\" && !quoted) {\n const parameter = value.slice(start, index).trim();\n if (parameter) parameters.push(parameter);\n start = index + 1;\n }\n }\n const parameter = value.slice(start).trim();\n if (parameter) parameters.push(parameter);\n return parameters;\n}\n\nfunction normalizePreloadKind(value: string | undefined): FarmPreloadKind | undefined {\n const normalized = value?.toLowerCase();\n return normalized === \"image\" || normalized === \"font\" ? normalized : undefined;\n}\n\nfunction readHtmlAttribute(element: string, name: string): string | undefined {\n const match = element.match(\n new RegExp(`\\\\s${name}\\\\s*=\\\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\\\s>]+))`, \"i\"),\n );\n return match?.[1] ?? match?.[2] ?? match?.[3];\n}\n\ninterface HtmlLinkElement {\n start: number;\n end: number;\n value: string;\n}\n\nfunction findHtmlLinkElements(html: string): HtmlLinkElement[] {\n const elements: HtmlLinkElement[] = [];\n const lowerHtml = html.toLowerCase();\n let cursor = 0;\n\n while (cursor < html.length) {\n const start = html.indexOf(\"<\", cursor);\n if (start === -1) break;\n\n if (lowerHtml.startsWith(\"<!--\", start)) {\n const commentEnd = lowerHtml.indexOf(\"-->\", start + 4);\n cursor = commentEnd === -1 ? html.length : commentEnd + 3;\n continue;\n }\n\n const rawText = lowerHtml\n .slice(start)\n .match(/^<(script|style|template|textarea|title|noscript|svg)(?=[\\s/>])/);\n if (rawText?.[1]) {\n const openingEnd = findHtmlTagEnd(html, start);\n if (openingEnd === -1) break;\n const closingStart = findHtmlClosingTag(lowerHtml, rawText[1], openingEnd);\n if (closingStart === -1) {\n cursor = html.length;\n continue;\n }\n const closingEnd = findHtmlTagEnd(html, closingStart);\n cursor = closingEnd === -1 ? html.length : closingEnd;\n continue;\n }\n\n if (/^<link(?=[\\s/>])/i.test(html.slice(start))) {\n const end = findHtmlTagEnd(html, start);\n if (end === -1) break;\n elements.push({ start, end, value: html.slice(start, end) });\n cursor = end;\n continue;\n }\n\n if (/^<\\/?[A-Za-z][\\w:-]*(?=[\\s/>])/.test(html.slice(start))) {\n const end = findHtmlTagEnd(html, start);\n cursor = end === -1 ? html.length : end;\n continue;\n }\n\n cursor = start + 1;\n }\n\n return elements;\n}\n\nfunction findHtmlClosingTag(html: string, tagName: string, start: number): number {\n const prefix = `</${tagName}`;\n let candidate = html.indexOf(prefix, start);\n while (candidate !== -1) {\n const boundary = html[candidate + prefix.length];\n if (boundary === \">\" || boundary === \"/\" || /\\s/.test(boundary ?? \"\")) return candidate;\n candidate = html.indexOf(prefix, candidate + prefix.length);\n }\n return -1;\n}\n\nfunction findHtmlTagEnd(html: string, start: number): number {\n let quote: '\"' | \"'\" | undefined;\n for (let index = start + 1; index < html.length; index += 1) {\n const character = html[index];\n if (quote) {\n if (character === quote) quote = undefined;\n } else if (character === '\"' || character === \"'\") {\n quote = character;\n } else if (character === \">\") {\n return index + 1;\n }\n }\n return -1;\n}\n\nfunction removeHtmlLinkElements(\n html: string,\n elements: HtmlLinkElement[],\n removed: ReadonlySet<number>,\n): string {\n let cursor = 0;\n let output = \"\";\n for (const [index, element] of elements.entries()) {\n if (!removed.has(index)) continue;\n output += html.slice(cursor, element.start);\n cursor = element.end;\n }\n return output + html.slice(cursor);\n}\n\nfunction splitLinkHeader(value: string): string[] {\n const links: string[] = [];\n let start = 0;\n let insideAngleBrackets = false;\n let quoted = false;\n\n for (let index = 0; index < value.length; index += 1) {\n const character = value[index];\n if (quoted) {\n if (character === '\"' && !isEscaped(value, index)) quoted = false;\n continue;\n }\n if (character === '\"') {\n quoted = true;\n } else if (character === \"<\") {\n insideAngleBrackets = true;\n } else if (character === \">\") {\n insideAngleBrackets = false;\n } else if (character === \",\" && !insideAngleBrackets) {\n links.push(value.slice(start, index).trim());\n start = index + 1;\n }\n }\n\n links.push(value.slice(start).trim());\n return links.filter(Boolean);\n}\n\nfunction isEscaped(value: string, index: number): boolean {\n let backslashes = 0;\n for (let cursor = index - 1; cursor >= 0 && value[cursor] === \"\\\\\"; cursor -= 1) {\n backslashes += 1;\n }\n return backslashes % 2 === 1;\n}\n\nfunction normalizeBudget(value: number | undefined, fallback: number): number {\n return typeof value === \"number\" && Number.isFinite(value) && value >= 0\n ? Math.floor(value)\n : fallback;\n}\n"],"mappings":"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","names":["parameter"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// package.json
|
|
2
|
-
var version = "0.1.0-beta.
|
|
2
|
+
var version = "0.1.0-beta.14";
|
|
3
3
|
|
|
4
4
|
// src/version.ts
|
|
5
5
|
var FARM_VERSION = version;
|
|
@@ -7,4 +7,4 @@ var FARM_VERSION = version;
|
|
|
7
7
|
export {
|
|
8
8
|
FARM_VERSION
|
|
9
9
|
};
|
|
10
|
-
//# sourceMappingURL=chunk-
|
|
10
|
+
//# sourceMappingURL=chunk-ARCGE2VT.mjs.map
|