@farm.js/core 0.1.0-beta.11 → 0.1.0-beta.13
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-5EVQFRL2.mjs → chunk-3WIRO3N7.mjs} +2 -2
- package/dist/chunk-3WIRO3N7.mjs.map +1 -0
- 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-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-USLFXFFH.mjs +46 -0
- package/dist/chunk-USLFXFFH.mjs.map +1 -0
- package/dist/{chunk-4677KXB7.mjs → chunk-VSDZEB5M.mjs} +368 -103
- package/dist/chunk-VSDZEB5M.mjs.map +1 -0
- package/dist/{chunk-77BOAQHI.mjs → chunk-Z3YG4OZT.mjs} +725 -147
- package/dist/chunk-Z3YG4OZT.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 +2206 -680
- 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 +2033 -516
- 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 +1521 -339
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.mjs +9 -5
- package/dist/server.cjs +1634 -410
- 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 +1575 -349
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.mjs +9 -5
- package/package.json +10 -1
- 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
|
@@ -6,6 +6,12 @@ import {
|
|
|
6
6
|
mergeMetadata,
|
|
7
7
|
renderMetadataHead
|
|
8
8
|
} from "./chunk-FRPWCMMG.mjs";
|
|
9
|
+
import {
|
|
10
|
+
createFarmMetadataImageResponse
|
|
11
|
+
} from "./chunk-53MVSX3R.mjs";
|
|
12
|
+
import {
|
|
13
|
+
resolveFarmLayoutFonts
|
|
14
|
+
} from "./chunk-6ZXIQSXE.mjs";
|
|
9
15
|
import {
|
|
10
16
|
farmEnvironmentFunctionsPlugin
|
|
11
17
|
} from "./chunk-V6WE6JSZ.mjs";
|
|
@@ -24,9 +30,18 @@ import {
|
|
|
24
30
|
isFarmNotFoundError,
|
|
25
31
|
isFarmRedirectError
|
|
26
32
|
} from "./chunk-7HO6AEOP.mjs";
|
|
33
|
+
import {
|
|
34
|
+
resolveFarmDocsFontAssets,
|
|
35
|
+
toFarmDocsPublicFontAssets
|
|
36
|
+
} from "./chunk-USLFXFFH.mjs";
|
|
27
37
|
import {
|
|
28
38
|
resolveFarmAuthConfig
|
|
29
39
|
} from "./chunk-I4CUBGVF.mjs";
|
|
40
|
+
import {
|
|
41
|
+
FARM_DEVTOOLS_LAUNCH_PARAM,
|
|
42
|
+
FARM_DEVTOOLS_PATH,
|
|
43
|
+
resolveFarmDevtoolsConfig
|
|
44
|
+
} from "./chunk-7MABZJIM.mjs";
|
|
30
45
|
import {
|
|
31
46
|
normalizeRouteRules
|
|
32
47
|
} from "./chunk-YW7OBE6Q.mjs";
|
|
@@ -36,10 +51,8 @@ import {
|
|
|
36
51
|
getFarmSourceRoots
|
|
37
52
|
} from "./chunk-74YTBPTY.mjs";
|
|
38
53
|
import {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
resolveFarmDevtoolsConfig
|
|
42
|
-
} from "./chunk-7MABZJIM.mjs";
|
|
54
|
+
resolveFarmPerformanceConfig
|
|
55
|
+
} from "./chunk-7ZVN3YZI.mjs";
|
|
43
56
|
import {
|
|
44
57
|
getPublicFarmImageConfig,
|
|
45
58
|
resolveFarmImageConfig
|
|
@@ -147,7 +160,7 @@ import {
|
|
|
147
160
|
} from "./chunk-RHIFZZUI.mjs";
|
|
148
161
|
import {
|
|
149
162
|
FARM_VERSION
|
|
150
|
-
} from "./chunk-
|
|
163
|
+
} from "./chunk-3WIRO3N7.mjs";
|
|
151
164
|
import {
|
|
152
165
|
FARM_DEPLOYMENT_ID_HEADER,
|
|
153
166
|
createFarmDeploymentCookie,
|
|
@@ -185,6 +198,22 @@ import { readFile } from "fs/promises";
|
|
|
185
198
|
var OPTIONAL_CATCH_ALL_SEGMENT = /^\[\[\.\.\.([^\]]+)\]\]$/;
|
|
186
199
|
var REQUIRED_CATCH_ALL_SEGMENT = /^\[\.\.\.([^\]]+)\]$/;
|
|
187
200
|
var REQUIRED_DYNAMIC_SEGMENT = /^\[([^\]]+)\]$/;
|
|
201
|
+
var REQUEST_API_LABELS = /* @__PURE__ */ new Map([
|
|
202
|
+
["cookies", "request cookies"],
|
|
203
|
+
["headers", "request headers"],
|
|
204
|
+
["getCurrentRequest", "the current Request"],
|
|
205
|
+
["useSearchParams", "URL search parameters"],
|
|
206
|
+
["auth", "request authentication"],
|
|
207
|
+
["getServerSession", "request authentication"],
|
|
208
|
+
["getSession", "request authentication"],
|
|
209
|
+
["currentUser", "request authentication"]
|
|
210
|
+
]);
|
|
211
|
+
var ROUTE_PROP_LABELS = /* @__PURE__ */ new Map([
|
|
212
|
+
["searchParams", "URL search parameters"],
|
|
213
|
+
["middleware", "middleware request data"],
|
|
214
|
+
["middlewareData", "middleware request data"],
|
|
215
|
+
["context", "request context"]
|
|
216
|
+
]);
|
|
188
217
|
function resolveRouteRenderingConfig(mod, source) {
|
|
189
218
|
const directiveConfig = parseRouteRenderingDirective(source);
|
|
190
219
|
let ssg = directiveConfig?.ssg ?? false;
|
|
@@ -237,6 +266,221 @@ async function resolveRouteRenderingConfigFromFile(mod, filePath) {
|
|
|
237
266
|
return resolveRouteRenderingConfig(mod, source);
|
|
238
267
|
}
|
|
239
268
|
__name(resolveRouteRenderingConfigFromFile, "resolveRouteRenderingConfigFromFile");
|
|
269
|
+
function analyzeStaticRouteCandidate(mod, source, options = {}) {
|
|
270
|
+
const blockers = [];
|
|
271
|
+
if (!source) {
|
|
272
|
+
blockers.push("route source is unavailable");
|
|
273
|
+
}
|
|
274
|
+
if (options.isDynamic) {
|
|
275
|
+
blockers.push("the route has dynamic path segments");
|
|
276
|
+
}
|
|
277
|
+
if (hasExplicitRenderingConfig(mod, source)) {
|
|
278
|
+
blockers.push("the route already has explicit rendering config");
|
|
279
|
+
}
|
|
280
|
+
if (source) {
|
|
281
|
+
blockers.push(...findRequestBoundSourceBlockers(source));
|
|
282
|
+
}
|
|
283
|
+
return {
|
|
284
|
+
candidate: blockers.length === 0,
|
|
285
|
+
blockers
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
__name(analyzeStaticRouteCandidate, "analyzeStaticRouteCandidate");
|
|
289
|
+
function findRequestBoundSourceBlockers(source) {
|
|
290
|
+
const blockers = /* @__PURE__ */ new Set();
|
|
291
|
+
const code = stripCommentsAndLiteralContents(source);
|
|
292
|
+
const sourceWithoutComments = stripComments(source);
|
|
293
|
+
for (const binding of readRequestApiImportBindings(sourceWithoutComments)) {
|
|
294
|
+
if (new RegExp(`\\b${escapeRegExp(binding.local)}\\s*(?:\\?\\.\\s*)?\\(`).test(code)) {
|
|
295
|
+
blockers.add(`the route reads ${binding.label}`);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
for (const namespace of readNamespaceImportBindings(sourceWithoutComments)) {
|
|
299
|
+
for (const [name, label] of REQUEST_API_LABELS) {
|
|
300
|
+
if (new RegExp(
|
|
301
|
+
`\\b${escapeRegExp(namespace)}\\s*(?:\\?\\.\\s*|\\.\\s*)${name}\\s*(?:\\?\\.\\s*)?\\(`
|
|
302
|
+
).test(code)) {
|
|
303
|
+
blockers.add(`the route reads ${label}`);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
const params = readDefaultRouteParameters(code);
|
|
308
|
+
if (params) {
|
|
309
|
+
for (const [name, label] of ROUTE_PROP_LABELS) {
|
|
310
|
+
if (new RegExp(`\\b${name}\\b`).test(params)) {
|
|
311
|
+
blockers.add(`the route reads ${label}`);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
const propsName = params.match(/^\s*([A-Za-z_$][\w$]*)\s*(?::|,|$)/)?.[1];
|
|
315
|
+
if (propsName) {
|
|
316
|
+
for (const [name, label] of ROUTE_PROP_LABELS) {
|
|
317
|
+
if (new RegExp(`\\b${escapeRegExp(propsName)}\\s*\\.\\s*${name}\\b`).test(code)) {
|
|
318
|
+
blockers.add(`the route reads ${label}`);
|
|
319
|
+
}
|
|
320
|
+
if (new RegExp(`\\{[^}]*\\b${name}\\b[^}]*\\}\\s*=\\s*${escapeRegExp(propsName)}\\b`).test(
|
|
321
|
+
code
|
|
322
|
+
)) {
|
|
323
|
+
blockers.add(`the route reads ${label}`);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return [...blockers];
|
|
329
|
+
}
|
|
330
|
+
__name(findRequestBoundSourceBlockers, "findRequestBoundSourceBlockers");
|
|
331
|
+
function readRequestApiImportBindings(source) {
|
|
332
|
+
const bindings = [];
|
|
333
|
+
for (const clause of readStaticImportClauses(source)) {
|
|
334
|
+
const namedGroup = clause.match(/\{([\s\S]*?)\}/)?.[1];
|
|
335
|
+
for (const rawSpecifier of (namedGroup ?? "").split(",")) {
|
|
336
|
+
const specifier = rawSpecifier.trim().replace(/^type\s+/, "");
|
|
337
|
+
const imported = specifier.match(/^([A-Za-z_$][\w$]*)(?:\s+as\s+([A-Za-z_$][\w$]*))?$/);
|
|
338
|
+
if (!imported?.[1]) continue;
|
|
339
|
+
const label = REQUEST_API_LABELS.get(imported[1]);
|
|
340
|
+
if (label) bindings.push({ local: imported[2] ?? imported[1], label });
|
|
341
|
+
}
|
|
342
|
+
const local = clause.match(/^\s*([A-Za-z_$][\w$]*)\s*(?:,|$)/)?.[1];
|
|
343
|
+
if (local) {
|
|
344
|
+
const label = REQUEST_API_LABELS.get(local);
|
|
345
|
+
if (label) bindings.push({ local, label });
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return bindings;
|
|
349
|
+
}
|
|
350
|
+
__name(readRequestApiImportBindings, "readRequestApiImportBindings");
|
|
351
|
+
function readNamespaceImportBindings(source) {
|
|
352
|
+
return readStaticImportClauses(source).map((clause) => clause.match(/\*\s*as\s*([A-Za-z_$][\w$]*)/)?.[1]).filter((binding) => Boolean(binding));
|
|
353
|
+
}
|
|
354
|
+
__name(readNamespaceImportBindings, "readNamespaceImportBindings");
|
|
355
|
+
function readStaticImportClauses(source) {
|
|
356
|
+
return [...source.matchAll(/\bimport\s+(?!\()([\s\S]*?)\s+from\s*["'][^"']+["']/g)].map((match) => match[1]).filter((clause) => Boolean(clause));
|
|
357
|
+
}
|
|
358
|
+
__name(readStaticImportClauses, "readStaticImportClauses");
|
|
359
|
+
function readDefaultRouteParameters(code) {
|
|
360
|
+
const inlineParams = code.match(/\bexport\s+default\s+(?:async\s+)?function\b[^(]*\(([^)]*)\)/)?.[1] ?? code.match(/\bexport\s+default\s+(?:async\s+)?\(([^)]*)\)\s*=>/)?.[1];
|
|
361
|
+
if (inlineParams !== void 0) return inlineParams;
|
|
362
|
+
const binding = code.match(/\bexport\s+default\s+([A-Za-z_$][\w$]*)\s*;?/)?.[1] ?? code.match(/\bexport\s*\{\s*([A-Za-z_$][\w$]*)\s+as\s+default\s*\}/)?.[1];
|
|
363
|
+
if (!binding) return void 0;
|
|
364
|
+
const escapedBinding = escapeRegExp(binding);
|
|
365
|
+
return code.match(new RegExp(`\\bfunction\\s+${escapedBinding}\\s*\\(([^)]*)\\)`))?.[1] ?? code.match(
|
|
366
|
+
new RegExp(
|
|
367
|
+
`\\b(?:const|let|var)\\s+${escapedBinding}\\s*=\\s*(?:async\\s+)?\\(([^)]*)\\)\\s*=>`
|
|
368
|
+
)
|
|
369
|
+
)?.[1] ?? code.match(
|
|
370
|
+
new RegExp(`\\b(?:const|let|var)\\s+${escapedBinding}\\s*=\\s*function\\s*\\(([^)]*)\\)`)
|
|
371
|
+
)?.[1];
|
|
372
|
+
}
|
|
373
|
+
__name(readDefaultRouteParameters, "readDefaultRouteParameters");
|
|
374
|
+
function stripCommentsAndLiteralContents(source) {
|
|
375
|
+
return sanitizeSource(source, true);
|
|
376
|
+
}
|
|
377
|
+
__name(stripCommentsAndLiteralContents, "stripCommentsAndLiteralContents");
|
|
378
|
+
function stripComments(source) {
|
|
379
|
+
return sanitizeSource(source, false);
|
|
380
|
+
}
|
|
381
|
+
__name(stripComments, "stripComments");
|
|
382
|
+
function sanitizeSource(source, maskLiterals) {
|
|
383
|
+
const output = [...source];
|
|
384
|
+
const mask = /* @__PURE__ */ __name((index) => {
|
|
385
|
+
if (output[index] !== "\n" && output[index] !== "\r") output[index] = " ";
|
|
386
|
+
}, "mask");
|
|
387
|
+
const scanQuoted = /* @__PURE__ */ __name((start, quote) => {
|
|
388
|
+
let index = start;
|
|
389
|
+
if (maskLiterals) mask(index);
|
|
390
|
+
index += 1;
|
|
391
|
+
while (index < source.length) {
|
|
392
|
+
if (source[index] === "\\") {
|
|
393
|
+
if (maskLiterals) mask(index);
|
|
394
|
+
if (index + 1 < source.length && maskLiterals) mask(index + 1);
|
|
395
|
+
index += 2;
|
|
396
|
+
continue;
|
|
397
|
+
}
|
|
398
|
+
const character = source[index];
|
|
399
|
+
if (maskLiterals) mask(index);
|
|
400
|
+
index += 1;
|
|
401
|
+
if (character === quote) break;
|
|
402
|
+
}
|
|
403
|
+
return index;
|
|
404
|
+
}, "scanQuoted");
|
|
405
|
+
const scanCode = /* @__PURE__ */ __name((start, stopAtTemplateBrace) => {
|
|
406
|
+
let index = start;
|
|
407
|
+
let braceDepth = 0;
|
|
408
|
+
while (index < source.length) {
|
|
409
|
+
const character = source[index];
|
|
410
|
+
const next = source[index + 1];
|
|
411
|
+
if (character === "/" && next === "/") {
|
|
412
|
+
while (index < source.length && source[index] !== "\n" && source[index] !== "\r") {
|
|
413
|
+
mask(index++);
|
|
414
|
+
}
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
if (character === "/" && next === "*") {
|
|
418
|
+
mask(index++);
|
|
419
|
+
mask(index++);
|
|
420
|
+
while (index < source.length) {
|
|
421
|
+
const closesComment = source[index] === "*" && source[index + 1] === "/";
|
|
422
|
+
mask(index++);
|
|
423
|
+
if (closesComment) {
|
|
424
|
+
mask(index++);
|
|
425
|
+
break;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
continue;
|
|
429
|
+
}
|
|
430
|
+
if (character === "'" || character === '"') {
|
|
431
|
+
index = scanQuoted(index, character);
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
if (character === "`") {
|
|
435
|
+
if (maskLiterals) mask(index);
|
|
436
|
+
index += 1;
|
|
437
|
+
while (index < source.length) {
|
|
438
|
+
if (source[index] === "\\") {
|
|
439
|
+
if (maskLiterals) mask(index);
|
|
440
|
+
if (index + 1 < source.length && maskLiterals) mask(index + 1);
|
|
441
|
+
index += 2;
|
|
442
|
+
} else if (source[index] === "`") {
|
|
443
|
+
if (maskLiterals) mask(index);
|
|
444
|
+
index += 1;
|
|
445
|
+
break;
|
|
446
|
+
} else if (source[index] === "$" && source[index + 1] === "{") {
|
|
447
|
+
if (maskLiterals) {
|
|
448
|
+
mask(index);
|
|
449
|
+
mask(index + 1);
|
|
450
|
+
}
|
|
451
|
+
index = scanCode(index + 2, true);
|
|
452
|
+
} else {
|
|
453
|
+
if (maskLiterals) mask(index);
|
|
454
|
+
index += 1;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
continue;
|
|
458
|
+
}
|
|
459
|
+
if (character === "{") {
|
|
460
|
+
braceDepth += 1;
|
|
461
|
+
} else if (character === "}") {
|
|
462
|
+
if (stopAtTemplateBrace && braceDepth === 0) {
|
|
463
|
+
if (maskLiterals) mask(index);
|
|
464
|
+
return index + 1;
|
|
465
|
+
}
|
|
466
|
+
braceDepth = Math.max(0, braceDepth - 1);
|
|
467
|
+
}
|
|
468
|
+
index += 1;
|
|
469
|
+
}
|
|
470
|
+
return index;
|
|
471
|
+
}, "scanCode");
|
|
472
|
+
scanCode(0, false);
|
|
473
|
+
return output.join("");
|
|
474
|
+
}
|
|
475
|
+
__name(sanitizeSource, "sanitizeSource");
|
|
476
|
+
function escapeRegExp(value) {
|
|
477
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
478
|
+
}
|
|
479
|
+
__name(escapeRegExp, "escapeRegExp");
|
|
480
|
+
function hasExplicitRenderingConfig(mod, source) {
|
|
481
|
+
return typeof mod?.ssg === "boolean" || typeof mod?.ppr === "boolean" || typeof mod?.experimental_ppr === "boolean" || typeof mod?.revalidate !== "undefined" || typeof mod?.dynamic !== "undefined" || typeof parseRouteRenderingDirective(source) !== "undefined";
|
|
482
|
+
}
|
|
483
|
+
__name(hasExplicitRenderingConfig, "hasExplicitRenderingConfig");
|
|
240
484
|
function parseRouteRenderingDirective(source) {
|
|
241
485
|
if (!source) {
|
|
242
486
|
return void 0;
|
|
@@ -368,9 +612,10 @@ function skipHorizontalWhitespace(source, start) {
|
|
|
368
612
|
return index;
|
|
369
613
|
}
|
|
370
614
|
__name(skipHorizontalWhitespace, "skipHorizontalWhitespace");
|
|
371
|
-
async function collectSSGPages(routes, loadModule) {
|
|
615
|
+
async function collectSSGPages(routes, loadModule, options = {}) {
|
|
372
616
|
const ssgPages = [];
|
|
373
617
|
const ssrRoutes = [];
|
|
618
|
+
const staticCandidateRoutes = [];
|
|
374
619
|
for (const route of routes) {
|
|
375
620
|
try {
|
|
376
621
|
const mod = await loadModule(route.filePath);
|
|
@@ -378,7 +623,8 @@ async function collectSSGPages(routes, loadModule) {
|
|
|
378
623
|
ssrRoutes.push(route.path);
|
|
379
624
|
continue;
|
|
380
625
|
}
|
|
381
|
-
const
|
|
626
|
+
const source = await readFile(route.filePath, "utf8").catch(() => void 0);
|
|
627
|
+
const rendering = resolveRouteRenderingConfig(mod, source);
|
|
382
628
|
if (rendering.ssg) {
|
|
383
629
|
if (route.isDynamic) {
|
|
384
630
|
const getStaticPaths = mod.getStaticPaths || mod.generateStaticParams;
|
|
@@ -405,12 +651,26 @@ async function collectSSGPages(routes, loadModule) {
|
|
|
405
651
|
}
|
|
406
652
|
} else {
|
|
407
653
|
ssrRoutes.push(route.path);
|
|
654
|
+
if (options.suggestStaticRendering !== false && analyzeStaticRouteCandidate(mod, source, { isDynamic: route.isDynamic }).candidate) {
|
|
655
|
+
staticCandidateRoutes.push(route.path);
|
|
656
|
+
}
|
|
408
657
|
}
|
|
409
658
|
} catch (error) {
|
|
410
659
|
console.error(`Error processing route ${route.path}:`, error);
|
|
411
660
|
ssrRoutes.push(route.path);
|
|
412
661
|
}
|
|
413
662
|
}
|
|
663
|
+
if (staticCandidateRoutes.length > 0) {
|
|
664
|
+
const visibleRoutes = staticCandidateRoutes.slice(0, 10);
|
|
665
|
+
const remainingCount = staticCandidateRoutes.length - visibleRoutes.length;
|
|
666
|
+
const remainingSuffix = remainingCount > 0 ? `
|
|
667
|
+
\u2026and ${remainingCount} more` : "";
|
|
668
|
+
console.warn(
|
|
669
|
+
`[Farm.js] ${staticCandidateRoutes.length} route${staticCandidateRoutes.length === 1 ? " appears" : "s appear"} eligible for static rendering:
|
|
670
|
+
${visibleRoutes.join("\n ")}${remainingSuffix}
|
|
671
|
+
Add \`export const dynamic = "force-static";\` after verifying that imported code does not read cookies, headers, authentication, or other request data.`
|
|
672
|
+
);
|
|
673
|
+
}
|
|
414
674
|
return { ssg: ssgPages, ssr: ssrRoutes };
|
|
415
675
|
}
|
|
416
676
|
__name(collectSSGPages, "collectSSGPages");
|
|
@@ -558,6 +818,15 @@ import path3 from "path";
|
|
|
558
818
|
import fs from "fs";
|
|
559
819
|
import path from "path";
|
|
560
820
|
import { fileURLToPath } from "url";
|
|
821
|
+
|
|
822
|
+
// src/island.ts
|
|
823
|
+
var FARM_ISLAND_STRATEGIES = ["load", "interaction", "visible", "idle"];
|
|
824
|
+
function isFarmIslandStrategy(value) {
|
|
825
|
+
return FARM_ISLAND_STRATEGIES.includes(value);
|
|
826
|
+
}
|
|
827
|
+
__name(isFarmIslandStrategy, "isFarmIslandStrategy");
|
|
828
|
+
|
|
829
|
+
// src/utils/client-component.ts
|
|
561
830
|
function readIfExists(filePath) {
|
|
562
831
|
try {
|
|
563
832
|
if (!filePath || !fs.existsSync(filePath)) {
|
|
@@ -628,56 +897,186 @@ function hasHydrateExport(content) {
|
|
|
628
897
|
return /\bexport\s+const\s+hydrate\s*=\s*true\b/.test(content) || /\bexport\s*\{\s*hydrate\s*\}\b/.test(content);
|
|
629
898
|
}
|
|
630
899
|
__name(hasHydrateExport, "hasHydrateExport");
|
|
900
|
+
function tokenizeModuleSource(content) {
|
|
901
|
+
const tokens = [];
|
|
902
|
+
let index = 0;
|
|
903
|
+
let line = 1;
|
|
904
|
+
while (index < content.length) {
|
|
905
|
+
const character = content[index];
|
|
906
|
+
if (/\s/.test(character)) {
|
|
907
|
+
if (character === "\n") line++;
|
|
908
|
+
index++;
|
|
909
|
+
continue;
|
|
910
|
+
}
|
|
911
|
+
if (character === "/" && content[index + 1] === "/") {
|
|
912
|
+
index += 2;
|
|
913
|
+
while (index < content.length && content[index] !== "\n") index++;
|
|
914
|
+
continue;
|
|
915
|
+
}
|
|
916
|
+
if (character === "/" && content[index + 1] === "*") {
|
|
917
|
+
index += 2;
|
|
918
|
+
while (index < content.length) {
|
|
919
|
+
if (content[index] === "\n") line++;
|
|
920
|
+
if (content[index] === "*" && content[index + 1] === "/") {
|
|
921
|
+
index += 2;
|
|
922
|
+
break;
|
|
923
|
+
}
|
|
924
|
+
index++;
|
|
925
|
+
}
|
|
926
|
+
continue;
|
|
927
|
+
}
|
|
928
|
+
if (character === '"' || character === "'") {
|
|
929
|
+
const quote = character;
|
|
930
|
+
const tokenLine = line;
|
|
931
|
+
let value = "";
|
|
932
|
+
index++;
|
|
933
|
+
while (index < content.length) {
|
|
934
|
+
const next = content[index];
|
|
935
|
+
if (next === "\\") {
|
|
936
|
+
value += next;
|
|
937
|
+
if (index + 1 < content.length) value += content[index + 1];
|
|
938
|
+
index += 2;
|
|
939
|
+
continue;
|
|
940
|
+
}
|
|
941
|
+
if (next === quote) {
|
|
942
|
+
index++;
|
|
943
|
+
break;
|
|
944
|
+
}
|
|
945
|
+
if (next === "\n") line++;
|
|
946
|
+
value += next;
|
|
947
|
+
index++;
|
|
948
|
+
}
|
|
949
|
+
tokens.push({ kind: "string", value, line: tokenLine });
|
|
950
|
+
continue;
|
|
951
|
+
}
|
|
952
|
+
if (character === "`") {
|
|
953
|
+
index++;
|
|
954
|
+
while (index < content.length) {
|
|
955
|
+
const next = content[index];
|
|
956
|
+
if (next === "\\") {
|
|
957
|
+
index += 2;
|
|
958
|
+
continue;
|
|
959
|
+
}
|
|
960
|
+
if (next === "`") {
|
|
961
|
+
index++;
|
|
962
|
+
break;
|
|
963
|
+
}
|
|
964
|
+
if (next === "\n") line++;
|
|
965
|
+
index++;
|
|
966
|
+
}
|
|
967
|
+
continue;
|
|
968
|
+
}
|
|
969
|
+
if (/[A-Za-z_$]/.test(character)) {
|
|
970
|
+
const start = index++;
|
|
971
|
+
while (index < content.length && /[\w$]/.test(content[index])) index++;
|
|
972
|
+
tokens.push({ kind: "identifier", value: content.slice(start, index), line });
|
|
973
|
+
continue;
|
|
974
|
+
}
|
|
975
|
+
tokens.push({ kind: "punctuation", value: character, line });
|
|
976
|
+
index++;
|
|
977
|
+
}
|
|
978
|
+
return tokens;
|
|
979
|
+
}
|
|
980
|
+
__name(tokenizeModuleSource, "tokenizeModuleSource");
|
|
981
|
+
function isIslandExportStart(tokens, index) {
|
|
982
|
+
const token = tokens[index];
|
|
983
|
+
const previous = tokens[index - 1];
|
|
984
|
+
const startsStatement = !previous || previous.value === ";" || previous.value === "{" || previous.value === "}" || token.line > previous.line;
|
|
985
|
+
return startsStatement && token.value === "export" && tokens[index + 1]?.value === "const" && tokens[index + 2]?.value === "island";
|
|
986
|
+
}
|
|
987
|
+
__name(isIslandExportStart, "isIslandExportStart");
|
|
988
|
+
function getIslandStrategyExport(content) {
|
|
989
|
+
if (!content) return null;
|
|
990
|
+
const tokens = tokenizeModuleSource(content);
|
|
991
|
+
for (let index = 0; index < tokens.length - 2; index++) {
|
|
992
|
+
if (!isIslandExportStart(tokens, index)) continue;
|
|
993
|
+
let valueIndex = index + 3;
|
|
994
|
+
if (tokens[valueIndex]?.value === ":") {
|
|
995
|
+
while (valueIndex < tokens.length && tokens[valueIndex].value !== "=") valueIndex++;
|
|
996
|
+
}
|
|
997
|
+
if (tokens[valueIndex]?.value !== "=") break;
|
|
998
|
+
valueIndex++;
|
|
999
|
+
const literal = tokens[valueIndex];
|
|
1000
|
+
if (!literal || literal.kind !== "string" || !isFarmIslandStrategy(literal.value)) break;
|
|
1001
|
+
let trailingIndex = valueIndex + 1;
|
|
1002
|
+
if (tokens[trailingIndex]?.value === "as" && tokens[trailingIndex + 1]?.value === "const") {
|
|
1003
|
+
trailingIndex += 2;
|
|
1004
|
+
}
|
|
1005
|
+
const trailing = tokens[trailingIndex];
|
|
1006
|
+
if (trailing && trailing.value !== ";" && trailing.line === literal.line) break;
|
|
1007
|
+
return literal.value;
|
|
1008
|
+
}
|
|
1009
|
+
if (tokens.some((_token, index) => isIslandExportStart(tokens, index))) {
|
|
1010
|
+
throw new Error(
|
|
1011
|
+
'Farm island configuration must be a static "load", "interaction", "visible", or "idle" string literal.'
|
|
1012
|
+
);
|
|
1013
|
+
}
|
|
1014
|
+
return null;
|
|
1015
|
+
}
|
|
1016
|
+
__name(getIslandStrategyExport, "getIslandStrategyExport");
|
|
631
1017
|
function stripUseClientDirective(content) {
|
|
632
1018
|
return content.replace(/^\s*(["'])use client\1\s*;?\s*/, "");
|
|
633
1019
|
}
|
|
634
1020
|
__name(stripUseClientDirective, "stripUseClientDirective");
|
|
635
|
-
function parseClientModuleMetadata(content) {
|
|
1021
|
+
function parseClientModuleMetadata(content, inspectIslandExport) {
|
|
636
1022
|
if (!content) {
|
|
637
1023
|
return {
|
|
638
1024
|
isClientComponent: false,
|
|
639
|
-
hasHydrateExport: false
|
|
1025
|
+
hasHydrateExport: false,
|
|
1026
|
+
islandStrategy: null
|
|
640
1027
|
};
|
|
641
1028
|
}
|
|
1029
|
+
const isClientComponent = hasUseClientDirective(content);
|
|
1030
|
+
const hasHydrate = hasHydrateExport(content);
|
|
642
1031
|
return {
|
|
643
|
-
isClientComponent
|
|
644
|
-
hasHydrateExport:
|
|
1032
|
+
isClientComponent,
|
|
1033
|
+
hasHydrateExport: hasHydrate,
|
|
1034
|
+
islandStrategy: inspectIslandExport || isClientComponent || hasHydrate ? getIslandStrategyExport(content) : null
|
|
645
1035
|
};
|
|
646
1036
|
}
|
|
647
1037
|
__name(parseClientModuleMetadata, "parseClientModuleMetadata");
|
|
648
1038
|
function getClientModuleMetadata(modulePath, root) {
|
|
649
1039
|
const resolvedPath = resolveModuleSourcePath(modulePath, root);
|
|
650
|
-
return inspectClientModuleMetadata(resolvedPath, root, /* @__PURE__ */ new Set());
|
|
1040
|
+
return inspectClientModuleMetadata(resolvedPath, root, /* @__PURE__ */ new Set(), true);
|
|
651
1041
|
}
|
|
652
1042
|
__name(getClientModuleMetadata, "getClientModuleMetadata");
|
|
653
|
-
function inspectClientModuleMetadata(resolvedPath, root, visited) {
|
|
1043
|
+
function inspectClientModuleMetadata(resolvedPath, root, visited, inspectIslandExport) {
|
|
654
1044
|
if (!resolvedPath || visited.has(resolvedPath)) {
|
|
655
1045
|
return {
|
|
656
1046
|
isClientComponent: false,
|
|
657
|
-
shouldHydrate: false
|
|
1047
|
+
shouldHydrate: false,
|
|
1048
|
+
islandStrategy: null
|
|
658
1049
|
};
|
|
659
1050
|
}
|
|
660
1051
|
visited.add(resolvedPath);
|
|
661
1052
|
const content = readIfExists(resolvedPath);
|
|
662
|
-
const parsed = parseClientModuleMetadata(content);
|
|
1053
|
+
const parsed = parseClientModuleMetadata(content, inspectIslandExport);
|
|
663
1054
|
if (parsed.isClientComponent) {
|
|
664
1055
|
return {
|
|
665
1056
|
isClientComponent: true,
|
|
666
|
-
shouldHydrate: true
|
|
1057
|
+
shouldHydrate: true,
|
|
1058
|
+
islandStrategy: parsed.islandStrategy ?? "load"
|
|
667
1059
|
};
|
|
668
1060
|
}
|
|
669
1061
|
let importsClientBoundary = false;
|
|
1062
|
+
let importedIslandStrategy = null;
|
|
670
1063
|
for (const specifier of getRelativeImportSpecifiers(content)) {
|
|
671
1064
|
const importedPath = resolveImportedModuleSourcePath(resolvedPath, specifier, root);
|
|
672
|
-
const importedMetadata = inspectClientModuleMetadata(importedPath, root, visited);
|
|
1065
|
+
const importedMetadata = inspectClientModuleMetadata(importedPath, root, visited, false);
|
|
673
1066
|
if (importedMetadata.isClientComponent || importedMetadata.shouldHydrate) {
|
|
674
1067
|
importsClientBoundary = true;
|
|
675
|
-
|
|
1068
|
+
if (importedIslandStrategy === null) {
|
|
1069
|
+
importedIslandStrategy = importedMetadata.islandStrategy;
|
|
1070
|
+
} else if (importedIslandStrategy !== importedMetadata.islandStrategy) {
|
|
1071
|
+
importedIslandStrategy = "load";
|
|
1072
|
+
}
|
|
676
1073
|
}
|
|
677
1074
|
}
|
|
1075
|
+
const shouldHydrate = parsed.hasHydrateExport || importsClientBoundary;
|
|
678
1076
|
return {
|
|
679
1077
|
isClientComponent: false,
|
|
680
|
-
shouldHydrate
|
|
1078
|
+
shouldHydrate,
|
|
1079
|
+
islandStrategy: shouldHydrate ? parsed.islandStrategy ?? importedIslandStrategy ?? "load" : null
|
|
681
1080
|
};
|
|
682
1081
|
}
|
|
683
1082
|
__name(inspectClientModuleMetadata, "inspectClientModuleMetadata");
|
|
@@ -855,6 +1254,10 @@ function parseInterceptionMarker(segment) {
|
|
|
855
1254
|
__name(parseInterceptionMarker, "parseInterceptionMarker");
|
|
856
1255
|
|
|
857
1256
|
// src/routing/route-manager.ts
|
|
1257
|
+
function shouldSuggestStaticRenderingForI18n(i18n) {
|
|
1258
|
+
return !i18n || i18n.routing === "prefix-always" || i18n.routing === "prefix-except-default" && i18n.detection.every((signal) => signal === "url");
|
|
1259
|
+
}
|
|
1260
|
+
__name(shouldSuggestStaticRenderingForI18n, "shouldSuggestStaticRenderingForI18n");
|
|
858
1261
|
function routeSpecificity(entry) {
|
|
859
1262
|
return entry.route.segments.reduce((score, segment) => {
|
|
860
1263
|
if (!segment.isDynamic) return score + 100;
|
|
@@ -1098,6 +1501,7 @@ var _RouteManager = class _RouteManager {
|
|
|
1098
1501
|
modulePath: toUrlPath(entry.modulePath),
|
|
1099
1502
|
shouldHydrate: metadata.shouldHydrate,
|
|
1100
1503
|
isClientComponent: metadata.isClientComponent,
|
|
1504
|
+
islandStrategy: metadata.islandStrategy,
|
|
1101
1505
|
search: getProgrammaticRouteSearchClientOptions(programmaticPage?.search),
|
|
1102
1506
|
segments: entry.route.segments.map((seg) => ({
|
|
1103
1507
|
segment: seg.segment,
|
|
@@ -1560,8 +1964,10 @@ var _RouteManager = class _RouteManager {
|
|
|
1560
1964
|
isDynamic: entry.route.segments.some((seg) => seg.isDynamic),
|
|
1561
1965
|
pattern: entry.pattern
|
|
1562
1966
|
}));
|
|
1563
|
-
const result = await collectSSGPages(routes, (filePath) => this.loadRouteModule(filePath));
|
|
1564
1967
|
const i18n = this.getI18nConfig();
|
|
1968
|
+
const result = await collectSSGPages(routes, (filePath) => this.loadRouteModule(filePath), {
|
|
1969
|
+
suggestStaticRendering: shouldSuggestStaticRenderingForI18n(i18n)
|
|
1970
|
+
});
|
|
1565
1971
|
if (!i18n) {
|
|
1566
1972
|
return result;
|
|
1567
1973
|
}
|
|
@@ -1693,7 +2099,7 @@ __name(safeGlobFiles, "safeGlobFiles");
|
|
|
1693
2099
|
|
|
1694
2100
|
// src/server/renderer.ts
|
|
1695
2101
|
import React from "react";
|
|
1696
|
-
import { renderToPipeableStream
|
|
2102
|
+
import { renderToPipeableStream } from "react-dom/server";
|
|
1697
2103
|
import * as fs2 from "fs";
|
|
1698
2104
|
import * as path5 from "path";
|
|
1699
2105
|
import { Writable } from "stream";
|
|
@@ -2027,6 +2433,10 @@ ${FONT_SECTION_END}
|
|
|
2027
2433
|
fallback,
|
|
2028
2434
|
display,
|
|
2029
2435
|
preload: raw.preload !== false,
|
|
2436
|
+
preloadResources: raw.preload === false ? [] : normalizedSources.map(({ resource }) => ({
|
|
2437
|
+
href: resourceUrl(resource, production, this.basePath),
|
|
2438
|
+
type: fontContentType(resource.extension)
|
|
2439
|
+
})),
|
|
2030
2440
|
weight: defaultWeight,
|
|
2031
2441
|
style: raw.style === void 0 ? void 0 : defaultStyle,
|
|
2032
2442
|
sources: normalizedSources
|
|
@@ -2123,7 +2533,7 @@ ${FONT_SECTION_END}
|
|
|
2123
2533
|
const normalizedExtension = extension.toLowerCase();
|
|
2124
2534
|
const hash = createHash2("sha256").update(bytes).digest("hex").slice(0, 12);
|
|
2125
2535
|
const baseName = sanitizeFileName(path4.basename(fileName, extension)) || "font";
|
|
2126
|
-
const outputFileName = `assets/fonts/${baseName}
|
|
2536
|
+
const outputFileName = `assets/fonts/${baseName}-h${hash}${normalizedExtension}`;
|
|
2127
2537
|
const key = `${hash}${normalizedExtension}`;
|
|
2128
2538
|
const existing = this.resources.get(key);
|
|
2129
2539
|
if (existing) return existing;
|
|
@@ -2393,7 +2803,8 @@ function serializeFontResult(font) {
|
|
|
2393
2803
|
fontFamily: stack,
|
|
2394
2804
|
...font.style ? { fontStyle: font.style } : {},
|
|
2395
2805
|
...font.weight !== void 0 && !String(font.weight).includes(" ") ? { fontWeight: font.weight } : {}
|
|
2396
|
-
}
|
|
2806
|
+
},
|
|
2807
|
+
preloads: font.preloadResources
|
|
2397
2808
|
});
|
|
2398
2809
|
}
|
|
2399
2810
|
__name(serializeFontResult, "serializeFontResult");
|
|
@@ -2813,7 +3224,7 @@ function createPPRRefreshScript() {
|
|
|
2813
3224
|
}
|
|
2814
3225
|
__name(createPPRRefreshScript, "createPPRRefreshScript");
|
|
2815
3226
|
function createPreHydrationClickQueueScript() {
|
|
2816
|
-
return `<script>(function(){if(window.__FARM_PREHYDRATION_CLICK_QUEUE__)return;var queue=[];window.__FARM_PREHYDRATION_CLICK_QUEUE__=queue;window.__FARM_HYDRATED__=false;document.documentElement.dataset.farmHydrated="false";function isModified(event){return !!(event.metaKey||event.altKey||event.ctrlKey||event.shiftKey)}function closestQueuedTarget(target){while(target&&target!==document.documentElement){if(target.matches&&target.matches('button,[role="button"],input[type="button"],input[type="submit"],input[type="reset"]'))return target;target=target.parentElement}return null}document.addEventListener("click",function(event){if(window.__FARM_HYDRATED__)return;if(event.defaultPrevented||event.button!==0||isModified(event))return;var target=closestQueuedTarget(event.target);if(!target||target.closest&&target.closest("a[href]"))return;if(queue.some(function(item){return item.target===target}))return;queue.push({target:target,createdAt:Date.now()});event.preventDefault();event.stopImmediatePropagation()},true);})();</script>`;
|
|
3227
|
+
return `<script>(function(){if(window.__FARM_PREHYDRATION_CLICK_QUEUE__)return;var queue=[];window.__FARM_PREHYDRATION_CLICK_QUEUE__=queue;window.__FARM_HYDRATED__=false;document.documentElement.dataset.farmHydrated="false";function isModified(event){return !!(event.metaKey||event.altKey||event.ctrlKey||event.shiftKey)}function closestQueuedTarget(target){while(target&&target!==document.documentElement){if(target.matches&&target.matches('button,[role="button"],input[type="button"],input[type="submit"],input[type="reset"]'))return target;target=target.parentElement}return null}document.addEventListener("click",function(event){if(window.__FARM_HYDRATED__)return;if(event.defaultPrevented||event.button!==0||isModified(event))return;var target=closestQueuedTarget(event.target);if(!target||target.closest&&target.closest("a[href]")||target.closest&&target.closest('[data-farm-island-hydrated="true"]'))return;if(queue.some(function(item){return item.target===target}))return;queue.push({target:target,createdAt:Date.now()});document.dispatchEvent(new CustomEvent("farm:island-interaction",{detail:{target:target}}));event.preventDefault();event.stopImmediatePropagation()},true);})();</script>`;
|
|
2817
3228
|
}
|
|
2818
3229
|
__name(createPreHydrationClickQueueScript, "createPreHydrationClickQueueScript");
|
|
2819
3230
|
function searchParamsToObject(searchParams) {
|
|
@@ -3424,6 +3835,7 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
3424
3835
|
req.__FARM_ROUTE__ = pathname;
|
|
3425
3836
|
req.__FARM_IS_CLIENT_COMPONENT__ = isClientComponent;
|
|
3426
3837
|
req.__FARM_SHOULD_HYDRATE__ = shouldHydrate;
|
|
3838
|
+
req.__FARM_ISLAND_STRATEGY__ = moduleMetadata.islandStrategy;
|
|
3427
3839
|
req.__FARM_HAS_HYDRATABLE_ROUTE_SLOTS__ = hasHydratableRouteSlots;
|
|
3428
3840
|
req.__FARM_LOADING_MODULE_PATH__ = loadingBoundaryEntry?.modulePath ? loadingBoundaryEntry.modulePath.substring(
|
|
3429
3841
|
loadingBoundaryEntry.modulePath.indexOf("/src/app/")
|
|
@@ -3499,7 +3911,12 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
3499
3911
|
if (isClientComponent || shouldHydrate) {
|
|
3500
3912
|
pageElement = React.createElement(
|
|
3501
3913
|
"div",
|
|
3502
|
-
{
|
|
3914
|
+
{
|
|
3915
|
+
id: "__farm_page__",
|
|
3916
|
+
"data-farm-client": "true",
|
|
3917
|
+
"data-farm-island": "page",
|
|
3918
|
+
"data-farm-island-strategy": moduleMetadata.islandStrategy ?? "load"
|
|
3919
|
+
},
|
|
3503
3920
|
pageElement
|
|
3504
3921
|
);
|
|
3505
3922
|
}
|
|
@@ -3744,6 +4161,13 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
3744
4161
|
return reference;
|
|
3745
4162
|
}
|
|
3746
4163
|
async renderMetadataImage(req, res, options) {
|
|
4164
|
+
const method = (req.method || "GET").toUpperCase();
|
|
4165
|
+
if (method !== "GET" && method !== "HEAD") {
|
|
4166
|
+
res.statusCode = 405;
|
|
4167
|
+
res.setHeader("Allow", "GET, HEAD");
|
|
4168
|
+
res.end();
|
|
4169
|
+
return;
|
|
4170
|
+
}
|
|
3747
4171
|
if (options.image.sourceType === "static") {
|
|
3748
4172
|
if (!options.image.staticInfo) {
|
|
3749
4173
|
throw new Error(`Static metadata image ${options.image.modulePath} is missing file info`);
|
|
@@ -3769,42 +4193,12 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
3769
4193
|
await this.writeMetadataImageResponse(req, res, handlerResult, imageModule);
|
|
3770
4194
|
}
|
|
3771
4195
|
async writeMetadataImageResponse(req, res, value, imageModule) {
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
res.end();
|
|
3779
|
-
return;
|
|
3780
|
-
}
|
|
3781
|
-
const body2 = Buffer.from(await value.arrayBuffer());
|
|
3782
|
-
res.write(body2);
|
|
3783
|
-
res.end();
|
|
3784
|
-
return;
|
|
3785
|
-
}
|
|
3786
|
-
const contentType = imageModule.contentType || "image/svg+xml; charset=utf-8";
|
|
3787
|
-
let body;
|
|
3788
|
-
if (typeof value === "string") {
|
|
3789
|
-
body = value;
|
|
3790
|
-
} else if (value instanceof ArrayBuffer) {
|
|
3791
|
-
body = Buffer.from(value);
|
|
3792
|
-
} else if (ArrayBuffer.isView(value)) {
|
|
3793
|
-
body = Buffer.from(value.buffer, value.byteOffset, value.byteLength);
|
|
3794
|
-
} else if (React.isValidElement(value)) {
|
|
3795
|
-
body = renderToStaticMarkup(value);
|
|
3796
|
-
} else {
|
|
3797
|
-
throw new Error("Metadata image must return a Response, string, bytes, or React element");
|
|
3798
|
-
}
|
|
3799
|
-
res.statusCode = res.statusCode || 200;
|
|
3800
|
-
res.setHeader("Content-Type", contentType);
|
|
3801
|
-
res.setHeader("Cache-Control", "public, max-age=0, must-revalidate");
|
|
3802
|
-
if (req.method === "HEAD") {
|
|
3803
|
-
res.end();
|
|
3804
|
-
return;
|
|
3805
|
-
}
|
|
3806
|
-
res.write(body);
|
|
3807
|
-
res.end();
|
|
4196
|
+
const ifNoneMatch = req.headers["if-none-match"];
|
|
4197
|
+
const response = await createFarmMetadataImageResponse(value, imageModule, {
|
|
4198
|
+
method: req.method,
|
|
4199
|
+
ifNoneMatch: Array.isArray(ifNoneMatch) ? ifNoneMatch[0] : ifNoneMatch
|
|
4200
|
+
});
|
|
4201
|
+
await sendWebResponse(res, response);
|
|
3808
4202
|
}
|
|
3809
4203
|
async writeStaticMetadataImageResponse(req, res, image) {
|
|
3810
4204
|
const method = (req.method || "GET").toUpperCase();
|
|
@@ -3934,6 +4328,7 @@ var _ServerRenderer = class _ServerRenderer {
|
|
|
3934
4328
|
search: routeEntry.search,
|
|
3935
4329
|
isClientComponent: routeEntry.isClientComponent,
|
|
3936
4330
|
shouldHydrate: routeEntry.shouldHydrate,
|
|
4331
|
+
islandStrategy: routeEntry.islandStrategy,
|
|
3937
4332
|
preloads: [routeEntry.modulePath],
|
|
3938
4333
|
assets: []
|
|
3939
4334
|
};
|
|
@@ -3970,6 +4365,7 @@ window.__FARM_DEPLOYMENT_ID__ = ${serializeInlineValue(deploymentId)};
|
|
|
3970
4365
|
window.__FARM_PATH__ = ${JSON.stringify(req.__FARM_ROUTE__ || req.url || "/")};
|
|
3971
4366
|
window.__FARM_IS_CLIENT__ = ${JSON.stringify(isClientComponent)};
|
|
3972
4367
|
window.__FARM_SHOULD_HYDRATE__ = ${JSON.stringify(req.__FARM_SHOULD_HYDRATE__ === true)};
|
|
4368
|
+
window.__FARM_ISLAND_STRATEGY__ = ${JSON.stringify(req.__FARM_ISLAND_STRATEGY__ || "load")};
|
|
3973
4369
|
window.__FARM_PAGE_MODULE__ = ${JSON.stringify(relativePath)};
|
|
3974
4370
|
window.__FARM_LOADING_MODULE__ = ${JSON.stringify(
|
|
3975
4371
|
req.__FARM_LOADING_MODULE_PATH__ || null
|
|
@@ -4330,6 +4726,7 @@ var _FarmApp = class _FarmApp {
|
|
|
4330
4726
|
context: config.context || (() => void 0),
|
|
4331
4727
|
serverActions: resolveServerActionsConfig(config.serverActions),
|
|
4332
4728
|
images: resolveFarmImageConfig(config.images),
|
|
4729
|
+
performance: resolveFarmPerformanceConfig(config.performance),
|
|
4333
4730
|
i18n: isResolvedI18nConfig(config.i18n) ? config.i18n : resolveFarmI18nConfig(config.i18n, {
|
|
4334
4731
|
root,
|
|
4335
4732
|
mode: process.env.NODE_ENV === "production" ? "production" : "development"
|
|
@@ -5076,7 +5473,7 @@ __name(removeLegacyTypeArtifacts, "removeLegacyTypeArtifacts");
|
|
|
5076
5473
|
|
|
5077
5474
|
// src/vite.ts
|
|
5078
5475
|
import * as fs4 from "fs";
|
|
5079
|
-
import * as
|
|
5476
|
+
import * as path11 from "path";
|
|
5080
5477
|
|
|
5081
5478
|
// src/image-vite.ts
|
|
5082
5479
|
import { readFile as readFile4 } from "fs/promises";
|
|
@@ -5147,6 +5544,100 @@ async function createBlurDataURL(bytes) {
|
|
|
5147
5544
|
}
|
|
5148
5545
|
__name(createBlurDataURL, "createBlurDataURL");
|
|
5149
5546
|
|
|
5547
|
+
// src/server/vite-config.ts
|
|
5548
|
+
import path10 from "path";
|
|
5549
|
+
var FARM_CLIENT_ENTRY_PATTERN = "**/{page,layout,loading,error,not-found,default}.{js,jsx,ts,tsx}";
|
|
5550
|
+
var FARM_CLIENT_OPTIMIZE_DEPS_INCLUDE = [
|
|
5551
|
+
"react",
|
|
5552
|
+
"react-dom",
|
|
5553
|
+
"react-dom/client",
|
|
5554
|
+
"react/jsx-runtime",
|
|
5555
|
+
"react/jsx-dev-runtime",
|
|
5556
|
+
"@farm.js/core/client",
|
|
5557
|
+
"@farm.js/core/plugin/client",
|
|
5558
|
+
"@farm.js/core/deferred",
|
|
5559
|
+
"@farm.js/core/deployment",
|
|
5560
|
+
"@farm.js/core/i18n/client",
|
|
5561
|
+
"@farm.js/core/query/client",
|
|
5562
|
+
"@farm.js/core/server-fn/client",
|
|
5563
|
+
"@farm.js/core/server-query/client"
|
|
5564
|
+
];
|
|
5565
|
+
function createFarmClientOptimizeDepsEntries(projectRoot, appDirectories) {
|
|
5566
|
+
const resolvedProjectRoot = path10.resolve(projectRoot);
|
|
5567
|
+
return appDirectories.map((appDirectory) => {
|
|
5568
|
+
const relativeAppDirectory = path10.relative(resolvedProjectRoot, path10.resolve(appDirectory)).replace(/\\/g, "/");
|
|
5569
|
+
const prefix = relativeAppDirectory || ".";
|
|
5570
|
+
return `${prefix}/${FARM_CLIENT_ENTRY_PATTERN}`;
|
|
5571
|
+
});
|
|
5572
|
+
}
|
|
5573
|
+
__name(createFarmClientOptimizeDepsEntries, "createFarmClientOptimizeDepsEntries");
|
|
5574
|
+
function createFarmClientOptimizeDepsConfig(entries) {
|
|
5575
|
+
return {
|
|
5576
|
+
// Keep normal application dependency discovery for CJS-only packages, but
|
|
5577
|
+
// seed every Farm browser runtime so React is present in the first crawl.
|
|
5578
|
+
noDiscovery: false,
|
|
5579
|
+
// Waiting for the crawl avoids serving a partial optimizer generation and
|
|
5580
|
+
// then changing browser hashes while hydration is already in progress.
|
|
5581
|
+
holdUntilCrawlEnd: true,
|
|
5582
|
+
include: [...FARM_CLIENT_OPTIMIZE_DEPS_INCLUDE],
|
|
5583
|
+
// Farm's HTML boots through a virtual module and imports route UI lazily.
|
|
5584
|
+
// Explicit entries let Vite finish that crawl before a navigation can
|
|
5585
|
+
// rotate the optimizer hash underneath a hydrated React runtime.
|
|
5586
|
+
...entries?.length ? { entries: [...entries] } : {}
|
|
5587
|
+
};
|
|
5588
|
+
}
|
|
5589
|
+
__name(createFarmClientOptimizeDepsConfig, "createFarmClientOptimizeDepsConfig");
|
|
5590
|
+
function mergeNoExternal(farmValue, userValue) {
|
|
5591
|
+
if (farmValue === true || userValue === true) return true;
|
|
5592
|
+
const normalize = /* @__PURE__ */ __name((value) => value == null || value === true ? [] : Array.isArray(value) ? value : [value], "normalize");
|
|
5593
|
+
return Array.from(/* @__PURE__ */ new Set([...normalize(farmValue), ...normalize(userValue)]));
|
|
5594
|
+
}
|
|
5595
|
+
__name(mergeNoExternal, "mergeNoExternal");
|
|
5596
|
+
function mergeFarmViteConfig(farmConfig, userConfig = {}) {
|
|
5597
|
+
const noDiscovery = userConfig.optimizeDeps?.noDiscovery ?? farmConfig.optimizeDeps?.noDiscovery;
|
|
5598
|
+
const holdUntilCrawlEnd = userConfig.optimizeDeps?.holdUntilCrawlEnd ?? (userConfig.optimizeDeps?.noDiscovery === true ? false : farmConfig.optimizeDeps?.holdUntilCrawlEnd);
|
|
5599
|
+
return {
|
|
5600
|
+
...farmConfig,
|
|
5601
|
+
...userConfig,
|
|
5602
|
+
plugins: [...farmConfig.plugins || [], ...userConfig.plugins || []],
|
|
5603
|
+
server: {
|
|
5604
|
+
...farmConfig.server,
|
|
5605
|
+
...userConfig.server
|
|
5606
|
+
},
|
|
5607
|
+
resolve: {
|
|
5608
|
+
...farmConfig.resolve,
|
|
5609
|
+
...userConfig.resolve,
|
|
5610
|
+
dedupe: Array.from(
|
|
5611
|
+
/* @__PURE__ */ new Set([...farmConfig.resolve?.dedupe || [], ...userConfig.resolve?.dedupe || []])
|
|
5612
|
+
)
|
|
5613
|
+
},
|
|
5614
|
+
optimizeDeps: {
|
|
5615
|
+
...farmConfig.optimizeDeps,
|
|
5616
|
+
...userConfig.optimizeDeps,
|
|
5617
|
+
noDiscovery,
|
|
5618
|
+
holdUntilCrawlEnd,
|
|
5619
|
+
include: Array.from(
|
|
5620
|
+
/* @__PURE__ */ new Set([
|
|
5621
|
+
...farmConfig.optimizeDeps?.include || [],
|
|
5622
|
+
...userConfig.optimizeDeps?.include || []
|
|
5623
|
+
])
|
|
5624
|
+
),
|
|
5625
|
+
exclude: Array.from(
|
|
5626
|
+
/* @__PURE__ */ new Set([
|
|
5627
|
+
...farmConfig.optimizeDeps?.exclude || [],
|
|
5628
|
+
...userConfig.optimizeDeps?.exclude || []
|
|
5629
|
+
])
|
|
5630
|
+
)
|
|
5631
|
+
},
|
|
5632
|
+
ssr: {
|
|
5633
|
+
...farmConfig.ssr,
|
|
5634
|
+
...userConfig.ssr,
|
|
5635
|
+
noExternal: mergeNoExternal(farmConfig.ssr?.noExternal, userConfig.ssr?.noExternal)
|
|
5636
|
+
}
|
|
5637
|
+
};
|
|
5638
|
+
}
|
|
5639
|
+
__name(mergeFarmViteConfig, "mergeFarmViteConfig");
|
|
5640
|
+
|
|
5150
5641
|
// src/vite.ts
|
|
5151
5642
|
var ALL_TYPE_ARTIFACTS = {
|
|
5152
5643
|
routes: true,
|
|
@@ -5189,7 +5680,7 @@ function loadFarmWorkflowsDevRuntime() {
|
|
|
5189
5680
|
}
|
|
5190
5681
|
__name(loadFarmWorkflowsDevRuntime, "loadFarmWorkflowsDevRuntime");
|
|
5191
5682
|
function loadFarmDevtoolsSnapshotRuntime() {
|
|
5192
|
-
return import("./devtools-
|
|
5683
|
+
return import("./devtools-GAZ7F3KL.mjs");
|
|
5193
5684
|
}
|
|
5194
5685
|
__name(loadFarmDevtoolsSnapshotRuntime, "loadFarmDevtoolsSnapshotRuntime");
|
|
5195
5686
|
function loadFarmDevtoolsUIRuntime() {
|
|
@@ -5368,7 +5859,7 @@ function fileContainsProgrammaticPageRoute(file) {
|
|
|
5368
5859
|
__name(fileContainsProgrammaticPageRoute, "fileContainsProgrammaticPageRoute");
|
|
5369
5860
|
function rewriteEarlySsrRelativeImports(options) {
|
|
5370
5861
|
const cleanId = options.id.split("?", 1)[0];
|
|
5371
|
-
if (!
|
|
5862
|
+
if (!path11.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
|
|
5372
5863
|
return null;
|
|
5373
5864
|
}
|
|
5374
5865
|
const replacements = [];
|
|
@@ -5388,7 +5879,7 @@ function rewriteEarlySsrRelativeImports(options) {
|
|
|
5388
5879
|
const suffixIndex = source.value.search(/[?#]/);
|
|
5389
5880
|
const sourcePath = suffixIndex === -1 ? source.value : source.value.slice(0, suffixIndex);
|
|
5390
5881
|
const suffix = suffixIndex === -1 ? "" : source.value.slice(suffixIndex);
|
|
5391
|
-
const resolvedPath =
|
|
5882
|
+
const resolvedPath = path11.resolve(path11.dirname(cleanId), sourcePath);
|
|
5392
5883
|
replacements.push({
|
|
5393
5884
|
start: source.start,
|
|
5394
5885
|
end: source.end,
|
|
@@ -5473,7 +5964,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
5473
5964
|
...layerRoots.length ? {
|
|
5474
5965
|
server: {
|
|
5475
5966
|
fs: {
|
|
5476
|
-
allow: [
|
|
5967
|
+
allow: [path11.resolve(options.root || process.cwd()), ...layerRoots]
|
|
5477
5968
|
}
|
|
5478
5969
|
}
|
|
5479
5970
|
} : {}
|
|
@@ -5504,9 +5995,9 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
5504
5995
|
},
|
|
5505
5996
|
server
|
|
5506
5997
|
);
|
|
5507
|
-
const globalsCSSPath =
|
|
5998
|
+
const globalsCSSPath = path11.join(server.config.root, "src/app/globals.css");
|
|
5508
5999
|
if (!fs4.existsSync(globalsCSSPath)) {
|
|
5509
|
-
const appDir =
|
|
6000
|
+
const appDir = path11.join(server.config.root, "src/app");
|
|
5510
6001
|
if (!fs4.existsSync(appDir)) {
|
|
5511
6002
|
fs4.mkdirSync(appDir, { recursive: true });
|
|
5512
6003
|
}
|
|
@@ -5528,10 +6019,10 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
5528
6019
|
});
|
|
5529
6020
|
}
|
|
5530
6021
|
const sourceRoots = getFarmSourceRoots(farmConfig);
|
|
5531
|
-
server.watcher.add(sourceRoots.map((source) =>
|
|
6022
|
+
server.watcher.add(sourceRoots.map((source) => path11.join(source.root, source.srcDir)));
|
|
5532
6023
|
if (farmConfig.i18n.enabled) {
|
|
5533
6024
|
server.watcher.add(
|
|
5534
|
-
farmConfig.i18n.messages.includes("{locale}") ?
|
|
6025
|
+
farmConfig.i18n.messages.includes("{locale}") ? path11.dirname(farmConfig.i18n.messages) : farmConfig.i18n.messages
|
|
5535
6026
|
);
|
|
5536
6027
|
}
|
|
5537
6028
|
const workflowConfig = farmConfig.workflows;
|
|
@@ -5541,7 +6032,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
5541
6032
|
...farmDocsDevRuntime?.getFarmDocsRouteTypeEntries(farmConfig.docs) ?? []
|
|
5542
6033
|
], "getExtraRouteTypes");
|
|
5543
6034
|
const appDirSlugs = sourceRoots.map(
|
|
5544
|
-
(source) =>
|
|
6035
|
+
(source) => path11.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
|
|
5545
6036
|
);
|
|
5546
6037
|
const generateTypeArtifacts = /* @__PURE__ */ __name(async (reason, selection = ALL_TYPE_ARTIFACTS, log = false) => {
|
|
5547
6038
|
try {
|
|
@@ -5581,7 +6072,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
5581
6072
|
}, "generateTypeArtifacts");
|
|
5582
6073
|
await generateTypeArtifacts("startup");
|
|
5583
6074
|
const srcDirSlugs = sourceRoots.map(
|
|
5584
|
-
(source) =>
|
|
6075
|
+
(source) => path11.join(source.root, source.srcDir).replace(/\\/g, "/")
|
|
5585
6076
|
);
|
|
5586
6077
|
const layerConfigFiles = new Set(
|
|
5587
6078
|
farmConfig.layers.map((layer) => layer.configFile?.replace(/\\/g, "/")).filter((file) => Boolean(file))
|
|
@@ -5699,7 +6190,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
5699
6190
|
await apiRouteManager.discoverRoutes();
|
|
5700
6191
|
let discoveredWorkflows = [];
|
|
5701
6192
|
const hasWorkflowDirectory = workflowConfig.enabled && workflowConfig.dirs.some(
|
|
5702
|
-
(dir) => fs4.existsSync(
|
|
6193
|
+
(dir) => fs4.existsSync(path11.isAbsolute(dir) ? dir : path11.join(farmConfig.root, dir))
|
|
5703
6194
|
);
|
|
5704
6195
|
if (hasWorkflowDirectory) {
|
|
5705
6196
|
const { createFarmWorkflowRequestHandler, discoverFarmWorkflows } = await loadFarmWorkflowsDevRuntime();
|
|
@@ -5763,10 +6254,20 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
5763
6254
|
logger.info(`Refreshed routes: ${reason}`);
|
|
5764
6255
|
}
|
|
5765
6256
|
}, "refreshRouteDiscovery");
|
|
6257
|
+
const farmDocsFontAssetList = farmDocsDevRuntime ? resolveFarmDocsFontAssets(farmConfig.root) : [];
|
|
5766
6258
|
const farmDocsHandler = farmDocsDevRuntime ? farmDocsDevRuntime.createFarmDocsHandler(farmConfig.docs, {
|
|
5767
6259
|
root: farmConfig.root,
|
|
5768
6260
|
srcDir: farmConfig.srcDir,
|
|
5769
|
-
clientEntry: "/@farm/client.js"
|
|
6261
|
+
clientEntry: "/@farm/client.js",
|
|
6262
|
+
fontAssets: toFarmDocsPublicFontAssets(farmDocsFontAssetList),
|
|
6263
|
+
resolveLayoutFonts: /* @__PURE__ */ __name(async (pathname) => {
|
|
6264
|
+
const layouts = routeManager.matchRoute(pathname).layouts;
|
|
6265
|
+
const layoutModules = await Promise.all(
|
|
6266
|
+
layouts.map((layout) => routeManager.loadLayoutModule(layout.modulePath))
|
|
6267
|
+
);
|
|
6268
|
+
return resolveFarmLayoutFonts(layoutModules);
|
|
6269
|
+
}, "resolveLayoutFonts"),
|
|
6270
|
+
fontStylesheetHref: "/@farm/fonts.css"
|
|
5770
6271
|
}) : null;
|
|
5771
6272
|
const farmDocsAPIHandler = farmDocsDevRuntime ? farmDocsDevRuntime.createFarmDocsAPIHandler({
|
|
5772
6273
|
rootDir: farmConfig.root,
|
|
@@ -5774,22 +6275,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
5774
6275
|
docs: farmConfig.docs
|
|
5775
6276
|
}) : null;
|
|
5776
6277
|
const farmDocsFontAssets = new Map(
|
|
5777
|
-
|
|
5778
|
-
[
|
|
5779
|
-
"/assets/Geist-Variable-CrgPqtmy.woff2",
|
|
5780
|
-
path10.join(
|
|
5781
|
-
farmConfig.root,
|
|
5782
|
-
"node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2"
|
|
5783
|
-
)
|
|
5784
|
-
],
|
|
5785
|
-
[
|
|
5786
|
-
"/assets/GeistMono-Variable-BNLlm6Cd.woff2",
|
|
5787
|
-
path10.join(
|
|
5788
|
-
farmConfig.root,
|
|
5789
|
-
"node_modules/geist/dist/fonts/geist-mono/GeistMono-Variable.woff2"
|
|
5790
|
-
)
|
|
5791
|
-
]
|
|
5792
|
-
] : []
|
|
6278
|
+
farmDocsFontAssetList.map(({ url, sourcePath }) => [url, sourcePath])
|
|
5793
6279
|
);
|
|
5794
6280
|
const logRequest = /* @__PURE__ */ __name((method, urlPath, tag) => {
|
|
5795
6281
|
try {
|
|
@@ -5853,11 +6339,12 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
5853
6339
|
}
|
|
5854
6340
|
}
|
|
5855
6341
|
const farmDocsFontPath = farmDocsFontAssets.get(requestPathname);
|
|
5856
|
-
if (farmDocsFontPath && fs4.existsSync(farmDocsFontPath)) {
|
|
6342
|
+
if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs4.existsSync(farmDocsFontPath)) {
|
|
5857
6343
|
res.statusCode = 200;
|
|
5858
6344
|
res.setHeader("Content-Type", "font/woff2");
|
|
5859
6345
|
res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
|
|
5860
|
-
|
|
6346
|
+
if (requestMethod === "HEAD") res.end();
|
|
6347
|
+
else fs4.createReadStream(farmDocsFontPath).pipe(res);
|
|
5861
6348
|
return;
|
|
5862
6349
|
}
|
|
5863
6350
|
if (requestMethod === "GET" && (requestPathname === FARM_DEVTOOLS_PATH || requestPathname === `${FARM_DEVTOOLS_PATH}.json`)) {
|
|
@@ -6463,6 +6950,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
6463
6950
|
modulePath: toUrlPath(route.modulePath),
|
|
6464
6951
|
isClientComponent: routeSlots.length > 0 ? false : isClientComponent,
|
|
6465
6952
|
shouldHydrate: shouldHydrate || routeSlots.some((slot) => slot.isClientComponent || slot.shouldHydrate),
|
|
6953
|
+
islandStrategy: moduleMetadata.islandStrategy,
|
|
6466
6954
|
metadata: {
|
|
6467
6955
|
title: mergedMetadata.title,
|
|
6468
6956
|
description: mergedMetadata.description
|
|
@@ -6847,6 +7335,7 @@ export const getManifest = () => ({
|
|
|
6847
7335
|
search: route.search,
|
|
6848
7336
|
isClientComponent: moduleMetadata.isClientComponent,
|
|
6849
7337
|
shouldHydrate: moduleMetadata.shouldHydrate,
|
|
7338
|
+
islandStrategy: moduleMetadata.islandStrategy,
|
|
6850
7339
|
preloads: [route.modulePath],
|
|
6851
7340
|
// In dev, preload is just the module
|
|
6852
7341
|
assets: []
|
|
@@ -6973,8 +7462,8 @@ if (import.meta.hot) {
|
|
|
6973
7462
|
}
|
|
6974
7463
|
logger.info(`Found ${ssgPages.length} SSG pages, ${ssrRoutes.length} SSR routes`);
|
|
6975
7464
|
logger.info("Pre-rendering SSG pages...");
|
|
6976
|
-
const outDir =
|
|
6977
|
-
const clientDir =
|
|
7465
|
+
const outDir = path11.join(server?.config.root || process.cwd(), options.outDir || "dist");
|
|
7466
|
+
const clientDir = path11.join(outDir, "client");
|
|
6978
7467
|
for (const page of ssgPages) {
|
|
6979
7468
|
try {
|
|
6980
7469
|
const staticRequest = new Request(new URL(page.urlPath, "http://farm.static"));
|
|
@@ -7026,8 +7515,8 @@ if (import.meta.hot) {
|
|
|
7026
7515
|
<script type="module" src="/assets/client.js"></script>
|
|
7027
7516
|
</body>
|
|
7028
7517
|
</html>`;
|
|
7029
|
-
const outputPath = page.urlPath === "/" ?
|
|
7030
|
-
fs4.mkdirSync(
|
|
7518
|
+
const outputPath = page.urlPath === "/" ? path11.join(clientDir, "index.html") : path11.join(clientDir, page.urlPath + ".html");
|
|
7519
|
+
fs4.mkdirSync(path11.dirname(outputPath), { recursive: true });
|
|
7031
7520
|
fs4.writeFileSync(outputPath, fullHtml);
|
|
7032
7521
|
const revalidateInfo = page.revalidate ? ` (revalidate: ${page.revalidate}s)` : "";
|
|
7033
7522
|
logger.success(` \u2713 ${page.urlPath}${revalidateInfo}`);
|
|
@@ -7036,7 +7525,7 @@ if (import.meta.hot) {
|
|
|
7036
7525
|
logger.error(` \u2717 ${page.urlPath}: ${error}`);
|
|
7037
7526
|
}
|
|
7038
7527
|
}
|
|
7039
|
-
const manifestPath =
|
|
7528
|
+
const manifestPath = path11.join(outDir, "__ssg_manifest.json");
|
|
7040
7529
|
fs4.writeFileSync(
|
|
7041
7530
|
manifestPath,
|
|
7042
7531
|
JSON.stringify(
|
|
@@ -7072,9 +7561,9 @@ if (import.meta.hot) {
|
|
|
7072
7561
|
}
|
|
7073
7562
|
const currentFarmConfig = farmApp?.getConfig();
|
|
7074
7563
|
const normalizedFile = file.replace(/\\/g, "/");
|
|
7075
|
-
const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) =>
|
|
7564
|
+
const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) => path11.join(source.root, source.srcDir).replace(/\\/g, "/")).find((sourceRoot) => normalizedFile.startsWith(`${sourceRoot}/`)) || null : null;
|
|
7076
7565
|
if (currentSrcRoot && normalizedFile.startsWith(`${currentSrcRoot}/`) && isProgrammaticRoutesFileName(normalizedFile)) {
|
|
7077
|
-
logUpdate("PAGE", `updated ${
|
|
7566
|
+
logUpdate("PAGE", `updated ${path11.basename(file)}`);
|
|
7078
7567
|
for (const mod of modules) {
|
|
7079
7568
|
server2.moduleGraph.invalidateModule(mod);
|
|
7080
7569
|
}
|
|
@@ -7471,6 +7960,7 @@ import React from 'react'
|
|
|
7471
7960
|
import { hydrateRoot, createRoot } from 'react-dom/client'
|
|
7472
7961
|
import { installChunkErrorRecovery, SPARouter } from '@farm.js/core/client'
|
|
7473
7962
|
import { createClientPluginManager } from '@farm.js/core/plugin/client'
|
|
7963
|
+
import { scheduleFarmIslandHydration } from '@farm.js/core/internal/client-runtime'
|
|
7474
7964
|
import { reviveDeferredData } from '@farm.js/core/deferred'
|
|
7475
7965
|
import {
|
|
7476
7966
|
createFarmDeploymentMismatchError,
|
|
@@ -7723,6 +8213,7 @@ class LegacyManifestSPARouter {
|
|
|
7723
8213
|
|
|
7724
8214
|
// Only prefetch routes that will hydrate on the client.
|
|
7725
8215
|
if (!match.route.isClientComponent && !match.route.shouldHydrate) return;
|
|
8216
|
+
if (match.route.islandStrategy && match.route.islandStrategy !== 'load') return;
|
|
7726
8217
|
|
|
7727
8218
|
const modulePath = match.route.modulePath;
|
|
7728
8219
|
if (this.moduleCache.has(modulePath)) return;
|
|
@@ -7867,6 +8358,12 @@ let hasClientTakenOver = false;
|
|
|
7867
8358
|
const routeSlotRoots = new Map();
|
|
7868
8359
|
const routeSlotDefinitions = new Map();
|
|
7869
8360
|
let activeRouteInterception = null;
|
|
8361
|
+
let pendingPageHydrationController = null;
|
|
8362
|
+
|
|
8363
|
+
function cancelPendingPageHydration() {
|
|
8364
|
+
pendingPageHydrationController?.abort();
|
|
8365
|
+
pendingPageHydrationController = null;
|
|
8366
|
+
}
|
|
7870
8367
|
|
|
7871
8368
|
function normalizeServerProps(rawProps) {
|
|
7872
8369
|
const props = rawProps && typeof rawProps === 'object' ? { ...rawProps } : {};
|
|
@@ -7935,7 +8432,11 @@ async function hydrateInitialRouteSlots() {
|
|
|
7935
8432
|
routeSlotDefinitions.set(getRouteSlotKey(slot), slot);
|
|
7936
8433
|
if (!slot.isClientComponent && !slot.shouldHydrate) continue;
|
|
7937
8434
|
try {
|
|
7938
|
-
|
|
8435
|
+
const slotHydrated = await renderRouteSlot(slot, 'hydrate');
|
|
8436
|
+
hydrated = slotHydrated || hydrated;
|
|
8437
|
+
if (slotHydrated) {
|
|
8438
|
+
replayPreHydrationClicks(document.getElementById(slot.containerId));
|
|
8439
|
+
}
|
|
7939
8440
|
} catch (error) {
|
|
7940
8441
|
console.warn('[Farm.js] Could not hydrate route slot:', slot.name, error);
|
|
7941
8442
|
}
|
|
@@ -8006,16 +8507,29 @@ function applyCanonicalPathFromProps(props) {
|
|
|
8006
8507
|
window.history.replaceState({ ...(window.history.state || {}), path: canonicalPath }, '', canonicalPath);
|
|
8007
8508
|
}
|
|
8008
8509
|
|
|
8009
|
-
function replayPreHydrationClicks() {
|
|
8010
|
-
|
|
8011
|
-
|
|
8510
|
+
function replayPreHydrationClicks(container = null) {
|
|
8511
|
+
if (!container) {
|
|
8512
|
+
markFarmHydrated();
|
|
8513
|
+
} else {
|
|
8514
|
+
container.dataset.farmIslandHydrated = 'true';
|
|
8515
|
+
}
|
|
8012
8516
|
|
|
8013
8517
|
const queue = Array.isArray(window.__FARM_PREHYDRATION_CLICK_QUEUE__)
|
|
8014
8518
|
? window.__FARM_PREHYDRATION_CLICK_QUEUE__
|
|
8015
8519
|
: [];
|
|
8016
8520
|
if (queue.length === 0) return;
|
|
8017
8521
|
|
|
8018
|
-
const queuedClicks =
|
|
8522
|
+
const queuedClicks = [];
|
|
8523
|
+
const remainingClicks = [];
|
|
8524
|
+
for (const queuedClick of queue) {
|
|
8525
|
+
const target = queuedClick?.target;
|
|
8526
|
+
if (!container || (target instanceof Node && container.contains(target))) {
|
|
8527
|
+
queuedClicks.push(queuedClick);
|
|
8528
|
+
} else {
|
|
8529
|
+
remainingClicks.push(queuedClick);
|
|
8530
|
+
}
|
|
8531
|
+
}
|
|
8532
|
+
queue.splice(0, queue.length, ...remainingClicks);
|
|
8019
8533
|
for (const queuedClick of queuedClicks) {
|
|
8020
8534
|
const target = queuedClick?.target;
|
|
8021
8535
|
if (!target || typeof target.click !== 'function') continue;
|
|
@@ -8024,6 +8538,11 @@ function replayPreHydrationClicks() {
|
|
|
8024
8538
|
}
|
|
8025
8539
|
}
|
|
8026
8540
|
|
|
8541
|
+
function markFarmHydrated() {
|
|
8542
|
+
window.__FARM_HYDRATED__ = true;
|
|
8543
|
+
document.documentElement.dataset.farmHydrated = 'true';
|
|
8544
|
+
}
|
|
8545
|
+
|
|
8027
8546
|
async function buildClientHydrationElement(PageComponent, pageProps) {
|
|
8028
8547
|
let element = React.createElement(PageComponent, pageProps);
|
|
8029
8548
|
const loadingModulePath = window.__FARM_LOADING_MODULE__;
|
|
@@ -8166,9 +8685,10 @@ async function tryHydrateImportedPage(
|
|
|
8166
8685
|
layouts,
|
|
8167
8686
|
useHydrate = false,
|
|
8168
8687
|
existingProps = null,
|
|
8688
|
+
signal = null,
|
|
8169
8689
|
) {
|
|
8170
8690
|
const modulePath = route?.modulePath;
|
|
8171
|
-
if (!modulePath) {
|
|
8691
|
+
if (!modulePath || signal?.aborted) {
|
|
8172
8692
|
return false;
|
|
8173
8693
|
}
|
|
8174
8694
|
|
|
@@ -8177,6 +8697,7 @@ async function tryHydrateImportedPage(
|
|
|
8177
8697
|
pageModule = await import(/* @vite-ignore */ modulePath);
|
|
8178
8698
|
pageModuleCache.set(modulePath, pageModule);
|
|
8179
8699
|
}
|
|
8700
|
+
if (signal?.aborted || !container?.isConnected) return false;
|
|
8180
8701
|
|
|
8181
8702
|
const PageComponent = pageModule?.default;
|
|
8182
8703
|
if (!PageComponent) {
|
|
@@ -8191,6 +8712,7 @@ async function tryHydrateImportedPage(
|
|
|
8191
8712
|
window.location.pathname,
|
|
8192
8713
|
existingProps,
|
|
8193
8714
|
);
|
|
8715
|
+
if (signal?.aborted || !container?.isConnected) return false;
|
|
8194
8716
|
|
|
8195
8717
|
const wrappedElement = useHydrate && container?.id === '__farm_page__'
|
|
8196
8718
|
? wrapWithIntegrationProviders(
|
|
@@ -8201,6 +8723,7 @@ async function tryHydrateImportedPage(
|
|
|
8201
8723
|
currentPageProps,
|
|
8202
8724
|
layouts,
|
|
8203
8725
|
);
|
|
8726
|
+
if (signal?.aborted || !container?.isConnected) return false;
|
|
8204
8727
|
|
|
8205
8728
|
if (useHydrate) {
|
|
8206
8729
|
try {
|
|
@@ -8231,6 +8754,7 @@ async function tryHydrateImportedPage(
|
|
|
8231
8754
|
async function renderPage(pageData) {
|
|
8232
8755
|
const container = document.getElementById('root');
|
|
8233
8756
|
if (!container) return;
|
|
8757
|
+
cancelPendingPageHydration();
|
|
8234
8758
|
const destination = window.location.pathname + window.location.search;
|
|
8235
8759
|
|
|
8236
8760
|
if (pageData.interception) {
|
|
@@ -8247,6 +8771,7 @@ async function renderPage(pageData) {
|
|
|
8247
8771
|
modulePath: pageData.modulePath,
|
|
8248
8772
|
isClientComponent: pageData.isClientComponent === true,
|
|
8249
8773
|
shouldHydrate: pageData.shouldHydrate === true,
|
|
8774
|
+
islandStrategy: pageData.islandStrategy || 'load',
|
|
8250
8775
|
};
|
|
8251
8776
|
const params = pageData.props?.params || {};
|
|
8252
8777
|
const layouts = (pageData.layoutModules || []).map((modulePath, index) => ({
|
|
@@ -8446,14 +8971,6 @@ async function hydrate() {
|
|
|
8446
8971
|
}
|
|
8447
8972
|
|
|
8448
8973
|
try {
|
|
8449
|
-
// Pre-load layout for SPA navigation
|
|
8450
|
-
try {
|
|
8451
|
-
const layoutModule = await import(/* @vite-ignore */ '/src/app/layout.tsx');
|
|
8452
|
-
LayoutComponent = layoutModule.default;
|
|
8453
|
-
} catch (e) {
|
|
8454
|
-
console.warn('[Farm.js] Could not preload layout:', e);
|
|
8455
|
-
}
|
|
8456
|
-
|
|
8457
8974
|
// Check if this is a client component (set by SSR)
|
|
8458
8975
|
const isClientComponent = window.__FARM_IS_CLIENT__ === true;
|
|
8459
8976
|
const modulePath = window.__FARM_PAGE_MODULE__;
|
|
@@ -8501,34 +9018,88 @@ async function hydrate() {
|
|
|
8501
9018
|
return
|
|
8502
9019
|
}
|
|
8503
9020
|
|
|
8504
|
-
const
|
|
8505
|
-
|
|
8506
|
-
|
|
8507
|
-
|
|
9021
|
+
const currentRoute = findRoute(window.location.pathname)?.route;
|
|
9022
|
+
const islandStrategy = window.__FARM_ISLAND_STRATEGY__ || currentRoute?.islandStrategy || 'load';
|
|
9023
|
+
pageContainer.dataset.farmIsland = 'page';
|
|
9024
|
+
pageContainer.dataset.farmIslandStrategy = islandStrategy;
|
|
8508
9025
|
|
|
8509
|
-
|
|
9026
|
+
const hydrationPathname = window.location.pathname;
|
|
9027
|
+
const hydrationController = new AbortController();
|
|
9028
|
+
pendingPageHydrationController = hydrationController;
|
|
8510
9029
|
try {
|
|
8511
|
-
|
|
8512
|
-
pageContainer,
|
|
8513
|
-
|
|
8514
|
-
|
|
8515
|
-
|
|
8516
|
-
|
|
8517
|
-
|
|
8518
|
-
|
|
8519
|
-
|
|
8520
|
-
|
|
8521
|
-
|
|
8522
|
-
|
|
8523
|
-
}
|
|
9030
|
+
await scheduleFarmIslandHydration({
|
|
9031
|
+
container: pageContainer,
|
|
9032
|
+
strategy: islandStrategy,
|
|
9033
|
+
signal: hydrationController.signal,
|
|
9034
|
+
hydrate: async () => {
|
|
9035
|
+
if (
|
|
9036
|
+
hydrationController.signal.aborted ||
|
|
9037
|
+
!pageContainer.isConnected ||
|
|
9038
|
+
window.location.pathname !== hydrationPathname
|
|
9039
|
+
) {
|
|
9040
|
+
return;
|
|
9041
|
+
}
|
|
8524
9042
|
|
|
8525
|
-
|
|
8526
|
-
|
|
8527
|
-
|
|
8528
|
-
|
|
8529
|
-
|
|
9043
|
+
// Layout code is only needed when this route boundary actually hydrates.
|
|
9044
|
+
try {
|
|
9045
|
+
const layoutModule = await import(/* @vite-ignore */ '/src/app/layout.tsx');
|
|
9046
|
+
LayoutComponent = layoutModule.default;
|
|
9047
|
+
} catch (e) {
|
|
9048
|
+
console.warn('[Farm.js] Could not preload layout:', e);
|
|
9049
|
+
}
|
|
9050
|
+
if (hydrationController.signal.aborted || !pageContainer.isConnected) return;
|
|
8530
9051
|
|
|
8531
|
-
|
|
9052
|
+
const hydrationSession = await farmClientRuntime.beginHydration({
|
|
9053
|
+
container: pageContainer,
|
|
9054
|
+
mode: shouldHydrate ? 'hydrate' : 'render',
|
|
9055
|
+
});
|
|
9056
|
+
|
|
9057
|
+
let hydrated = false;
|
|
9058
|
+
try {
|
|
9059
|
+
if (hydrationController.signal.aborted || !pageContainer.isConnected) {
|
|
9060
|
+
await farmClientRuntime.failHydration(
|
|
9061
|
+
hydrationSession,
|
|
9062
|
+
new DOMException('Route hydration was cancelled', 'AbortError'),
|
|
9063
|
+
);
|
|
9064
|
+
return;
|
|
9065
|
+
}
|
|
9066
|
+
hydrated = await tryHydrateImportedPage(
|
|
9067
|
+
pageContainer,
|
|
9068
|
+
{ modulePath },
|
|
9069
|
+
currentPageProps.params || {},
|
|
9070
|
+
layouts,
|
|
9071
|
+
shouldHydrate,
|
|
9072
|
+
currentPageProps,
|
|
9073
|
+
hydrationController.signal,
|
|
9074
|
+
);
|
|
9075
|
+
if (hydrationController.signal.aborted || !pageContainer.isConnected) {
|
|
9076
|
+
await farmClientRuntime.failHydration(
|
|
9077
|
+
hydrationSession,
|
|
9078
|
+
new DOMException('Route hydration was cancelled', 'AbortError'),
|
|
9079
|
+
);
|
|
9080
|
+
return;
|
|
9081
|
+
}
|
|
9082
|
+
await farmClientRuntime.completeHydration(hydrationSession);
|
|
9083
|
+
} catch (error) {
|
|
9084
|
+
await farmClientRuntime.failHydration(hydrationSession, error);
|
|
9085
|
+
throw error;
|
|
9086
|
+
}
|
|
9087
|
+
|
|
9088
|
+
if (hydrated) {
|
|
9089
|
+
// The scheduler owns queue draining and exactly-once click replay.
|
|
9090
|
+
markFarmHydrated();
|
|
9091
|
+
console.log('[Farm.js] \u2705 Hydrated:', modulePath, '(' + islandStrategy + ')');
|
|
9092
|
+
return;
|
|
9093
|
+
}
|
|
9094
|
+
|
|
9095
|
+
console.log('[Farm.js] Server component - SPA router ready')
|
|
9096
|
+
},
|
|
9097
|
+
});
|
|
9098
|
+
} finally {
|
|
9099
|
+
if (pendingPageHydrationController === hydrationController) {
|
|
9100
|
+
pendingPageHydrationController = null;
|
|
9101
|
+
}
|
|
9102
|
+
}
|
|
8532
9103
|
} catch (error) {
|
|
8533
9104
|
console.error('[Farm.js] Hydration error:', error)
|
|
8534
9105
|
}
|
|
@@ -8634,7 +9205,7 @@ function generateClientManifest(bundle) {
|
|
|
8634
9205
|
__name(generateClientManifest, "generateClientManifest");
|
|
8635
9206
|
async function defineConfig(config = {}) {
|
|
8636
9207
|
const tailwindcss = (await import("@tailwindcss/vite")).default;
|
|
8637
|
-
const appRoot =
|
|
9208
|
+
const appRoot = path11.resolve(config.root || process.cwd());
|
|
8638
9209
|
if (config.extends?.length) {
|
|
8639
9210
|
const { config: layeredConfig } = await import("./layers-VWVDTPUZ.mjs").then(
|
|
8640
9211
|
({ resolveFarmLayers }) => resolveFarmLayers(config, {
|
|
@@ -8779,13 +9350,16 @@ async function defineConfig(config = {}) {
|
|
|
8779
9350
|
customLogger: farmLogger,
|
|
8780
9351
|
clearScreen: false,
|
|
8781
9352
|
optimizeDeps: {
|
|
8782
|
-
|
|
8783
|
-
|
|
8784
|
-
|
|
8785
|
-
|
|
8786
|
-
|
|
8787
|
-
|
|
8788
|
-
|
|
9353
|
+
...createFarmClientOptimizeDepsConfig(
|
|
9354
|
+
createFarmClientOptimizeDepsEntries(
|
|
9355
|
+
appRoot,
|
|
9356
|
+
getFarmAppDirectories({ ...config, root: appRoot })
|
|
9357
|
+
)
|
|
9358
|
+
),
|
|
9359
|
+
// Pre-bundle every framework client-runtime entry with React. Without
|
|
9360
|
+
// this, Vite can discover a linked Farm entry after the page has loaded,
|
|
9361
|
+
// regenerate the optimizer browser hash, and leave React DOM holding a
|
|
9362
|
+
// different React module instance from a client component.
|
|
8789
9363
|
// Exclude server-side packages from browser bundling
|
|
8790
9364
|
exclude: [
|
|
8791
9365
|
"@farm.js/core/server",
|
|
@@ -8820,7 +9394,7 @@ async function defineConfig(config = {}) {
|
|
|
8820
9394
|
// Stub out problematic server-only modules during dev mode
|
|
8821
9395
|
alias: {
|
|
8822
9396
|
...getFarmLayerAliases(config.layers),
|
|
8823
|
-
"@":
|
|
9397
|
+
"@": path11.resolve(appRoot, "src"),
|
|
8824
9398
|
// Nitro internals that should not be resolved in browser
|
|
8825
9399
|
"supports-color": "data:text/javascript,export default false; export const supportsColor = false; export const stdout = false; export const stderr = false;",
|
|
8826
9400
|
"@poppinss/dumper": "data:text/javascript,export default {};",
|
|
@@ -8842,6 +9416,7 @@ __name(defineConfig, "defineConfig");
|
|
|
8842
9416
|
export {
|
|
8843
9417
|
resolveRouteRenderingConfig,
|
|
8844
9418
|
resolveRouteRenderingConfigFromFile,
|
|
9419
|
+
analyzeStaticRouteCandidate,
|
|
8845
9420
|
parseRouteRenderingDirective,
|
|
8846
9421
|
collectSSGPages,
|
|
8847
9422
|
isSSGModule,
|
|
@@ -8864,9 +9439,12 @@ export {
|
|
|
8864
9439
|
createFarmImageTypeDeclarations,
|
|
8865
9440
|
generateFarmI18nTypes,
|
|
8866
9441
|
generateFarmTypeArtifacts,
|
|
9442
|
+
createFarmClientOptimizeDepsEntries,
|
|
9443
|
+
createFarmClientOptimizeDepsConfig,
|
|
9444
|
+
mergeFarmViteConfig,
|
|
8867
9445
|
farmI18nClientBridgePlugin,
|
|
8868
9446
|
rewriteEarlySsrRelativeImports,
|
|
8869
9447
|
farmPlugin,
|
|
8870
9448
|
defineConfig
|
|
8871
9449
|
};
|
|
8872
|
-
//# sourceMappingURL=chunk-
|
|
9450
|
+
//# sourceMappingURL=chunk-Z3YG4OZT.mjs.map
|