@farm.js/core 0.1.17 → 0.1.19
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/after.cjs +12 -225
- package/dist/agent-runtime.cjs +83 -2800
- package/dist/api/client.cjs +17 -4060
- package/dist/api/route-manager.cjs +34 -4354
- package/dist/api/runtime.cjs +29 -2696
- package/dist/api.cjs +88 -8434
- package/dist/app-markdown.cjs +39 -280
- package/dist/app-markdown.mjs +3 -3
- package/dist/cache.cjs +38 -1560
- package/dist/chunk-22GUSVNJ.cjs +351 -0
- package/dist/{chunk-EN7WTEAY.mjs → chunk-2ANEVVF7.mjs} +1 -1
- package/dist/chunk-2CQ74SP6.cjs +13 -0
- package/dist/{chunk-YD4J4XCI.mjs → chunk-2GNATDDE.mjs} +1 -1
- package/dist/chunk-2SJ4RQ6P.cjs +57 -0
- package/dist/chunk-3376ZTRC.cjs +1 -0
- package/dist/chunk-4PNUXIVU.cjs +472 -0
- package/dist/chunk-4PPEPOZZ.cjs +21 -0
- package/dist/chunk-4ZFL5GFN.cjs +520 -0
- package/dist/chunk-5OVTOKGH.cjs +65 -0
- package/dist/chunk-5QIKR7RR.cjs +224 -0
- package/dist/chunk-5ZSWG4UX.cjs +127 -0
- package/dist/chunk-62YJ2IEB.cjs +238 -0
- package/dist/chunk-6EODJYCX.cjs +183 -0
- package/dist/chunk-6EXBPJ24.cjs +434 -0
- package/dist/chunk-6QQDAAAZ.cjs +38 -0
- package/dist/chunk-6V4TDWEC.cjs +455 -0
- package/dist/chunk-72ADZ6GQ.cjs +19 -0
- package/dist/chunk-75BRBIFP.cjs +172 -0
- package/dist/{chunk-ZCNJKLA2.mjs → chunk-7BC6GAL7.mjs} +1 -1
- package/dist/chunk-7W3CPVXS.cjs +24 -0
- package/dist/chunk-A6WIQH5Z.cjs +31 -0
- package/dist/chunk-A777V5WU.cjs +725 -0
- package/dist/chunk-AFOD3LYZ.cjs +377 -0
- package/dist/chunk-AH7HOAQ3.cjs +151 -0
- package/dist/chunk-AMDMVWMI.cjs +39 -0
- package/dist/chunk-AORPIPNB.cjs +552 -0
- package/dist/chunk-ARJWXNQL.cjs +256 -0
- package/dist/chunk-AYJR42WX.cjs +711 -0
- package/dist/chunk-BBVSJVBZ.cjs +600 -0
- package/dist/chunk-BIDYX3SL.cjs +91 -0
- package/dist/chunk-BYODCJD6.cjs +663 -0
- package/dist/chunk-C3VRMB6H.cjs +85 -0
- package/dist/chunk-C5GUTBZK.cjs +173 -0
- package/dist/chunk-CIAGU2X4.cjs +337 -0
- package/dist/chunk-CMGMGHUZ.cjs +27 -0
- package/dist/chunk-CXP5U3RW.cjs +54 -0
- package/dist/chunk-D2ULAULS.cjs +166 -0
- package/dist/chunk-D7JTOLFK.cjs +285 -0
- package/dist/chunk-DVM4FKZL.cjs +169 -0
- package/dist/chunk-DYEJQTDN.cjs +49 -0
- package/dist/chunk-E2ROOWQC.cjs +2225 -0
- package/dist/chunk-E3UK5IIB.cjs +593 -0
- package/dist/chunk-EM6SBQKM.cjs +470 -0
- package/dist/chunk-FJSWYIR7.cjs +482 -0
- package/dist/chunk-FK6GO24V.cjs +54 -0
- package/dist/{chunk-MVIWBEJF.mjs → chunk-FVZGEVTO.mjs} +7 -7
- package/dist/chunk-FXUUWYAX.cjs +654 -0
- package/dist/chunk-G3HRIVEY.cjs +395 -0
- package/dist/chunk-G643DQCH.cjs +13 -0
- package/dist/chunk-G7HXGLEC.cjs +175 -0
- package/dist/chunk-GDSHDTJ4.cjs +152 -0
- package/dist/chunk-GPVTX3HT.cjs +1415 -0
- package/dist/chunk-H6G5INWM.cjs +1094 -0
- package/dist/{chunk-DHDVMXYK.mjs → chunk-HALDNTIV.mjs} +30 -4
- package/dist/chunk-HBTUGXHS.cjs +180 -0
- package/dist/chunk-HREOKQWT.cjs +45 -0
- package/dist/{chunk-5QOEPUYE.mjs → chunk-HSDL2AUR.mjs} +1 -1
- package/dist/chunk-I4J452B7.cjs +435 -0
- package/dist/chunk-I57LW5VZ.cjs +94 -0
- package/dist/chunk-I5YBCWQ6.cjs +40 -0
- package/dist/chunk-I7PUUDGY.cjs +389 -0
- package/dist/chunk-IAMRBF3Z.cjs +86 -0
- package/dist/chunk-IQXFRNY2.cjs +169 -0
- package/dist/chunk-ISTFC3MZ.cjs +1357 -0
- package/dist/chunk-IXTFU4PL.cjs +2355 -0
- package/dist/chunk-J3LOGE4T.cjs +42 -0
- package/dist/chunk-J7FSKED3.cjs +93 -0
- package/dist/chunk-JDNHKPTD.cjs +22 -0
- package/dist/chunk-JSROZYYO.cjs +164 -0
- package/dist/chunk-K6FNHVDR.cjs +696 -0
- package/dist/chunk-KGZIORNL.cjs +43 -0
- package/dist/chunk-KR6CKSXT.cjs +15 -0
- package/dist/chunk-KROWKCUH.cjs +185 -0
- package/dist/chunk-KVFPGF2M.cjs +46 -0
- package/dist/{chunk-TNBAYAWO.mjs → chunk-L4DVIHOC.mjs} +1 -1
- package/dist/chunk-LCCBO7PJ.cjs +46 -0
- package/dist/chunk-LIUGYUX3.cjs +22 -0
- package/dist/chunk-LTNGXMQ6.cjs +55 -0
- package/dist/chunk-M2L4MYDQ.cjs +14 -0
- package/dist/chunk-MCJLA63J.cjs +1 -0
- package/dist/chunk-MKB2EGIR.cjs +148 -0
- package/dist/chunk-MQ3H6LT5.cjs +202 -0
- package/dist/chunk-MT763TDW.cjs +43 -0
- package/dist/{chunk-XWAYMDLB.mjs → chunk-MVUREHPN.mjs} +1 -1
- package/dist/chunk-MWSK6C4J.cjs +18 -0
- package/dist/chunk-MWWVKDW3.cjs +169 -0
- package/dist/{chunk-6VQIKZZO.mjs → chunk-N255VYFP.mjs} +1 -1
- package/dist/chunk-NBAHDVOJ.cjs +2040 -0
- package/dist/chunk-NO3WWW3N.cjs +192 -0
- package/dist/chunk-NSFC3LHB.cjs +10244 -0
- package/dist/chunk-NZKJGRB3.cjs +230 -0
- package/dist/chunk-OAVTUMJP.cjs +1496 -0
- package/dist/{chunk-SXHV42UQ.mjs → chunk-OFEY6KHO.mjs} +88 -13
- package/dist/chunk-OHY2ZWUG.cjs +25 -0
- package/dist/chunk-OI6CMLWX.cjs +47 -0
- package/dist/chunk-OWOUTKIJ.cjs +558 -0
- package/dist/chunk-OX6O6WVA.cjs +74 -0
- package/dist/chunk-OXSIH4D6.cjs +476 -0
- package/dist/chunk-OYDRPBBV.cjs +453 -0
- package/dist/chunk-OYEUREB6.cjs +35 -0
- package/dist/chunk-PCOTGFSM.cjs +139 -0
- package/dist/{chunk-76DG3LF3.mjs → chunk-PGQBL5DN.mjs} +1 -1
- package/dist/chunk-PZYCPSCC.cjs +35 -0
- package/dist/chunk-QBK2AA4U.cjs +445 -0
- package/dist/{chunk-UTBVHYS3.mjs → chunk-QBPKKQTD.mjs} +2 -2
- package/dist/chunk-QBPXNZGV.cjs +487 -0
- package/dist/chunk-QNPEUFHQ.cjs +27 -0
- package/dist/chunk-QZRVZSPN.cjs +236 -0
- package/dist/chunk-R5A5KNVX.cjs +20 -0
- package/dist/chunk-R5JIFR6B.cjs +42 -0
- package/dist/chunk-R6AIILII.cjs +193 -0
- package/dist/chunk-RFYO7QUD.cjs +9 -0
- package/dist/chunk-RG3ZOTG5.cjs +34 -0
- package/dist/chunk-ROUTX2E5.cjs +390 -0
- package/dist/chunk-RTHIVJ2G.cjs +54 -0
- package/dist/chunk-S27FMYAM.cjs +644 -0
- package/dist/chunk-S3A45T7F.cjs +166 -0
- package/dist/chunk-S3JO3N4H.cjs +17 -0
- package/dist/chunk-SK35NQKK.cjs +27 -0
- package/dist/chunk-SU7MH53P.cjs +180 -0
- package/dist/chunk-SVRTJOUF.cjs +113 -0
- package/dist/chunk-SWN467MP.cjs +18 -0
- package/dist/chunk-SYQ3MOWW.cjs +73 -0
- package/dist/chunk-T5CERMEH.cjs +417 -0
- package/dist/chunk-TFAXUHWX.cjs +206 -0
- package/dist/chunk-TIWHTW3Q.cjs +24 -0
- package/dist/chunk-TKJZFIML.cjs +20 -0
- package/dist/chunk-TKNSDBBN.cjs +193 -0
- package/dist/chunk-U4KT7QP3.cjs +23 -0
- package/dist/chunk-U5BMPGS3.cjs +862 -0
- package/dist/chunk-UJ2C4ICS.cjs +277 -0
- package/dist/chunk-UQZ4AYTH.cjs +168 -0
- package/dist/chunk-US2QVW3E.cjs +36 -0
- package/dist/{chunk-QGVJVSNX.mjs → chunk-V4AICMQA.mjs} +2 -2
- package/dist/chunk-VB6UCX3V.cjs +421 -0
- package/dist/chunk-VEKFLAQM.cjs +300 -0
- package/dist/chunk-VQDBNVOO.cjs +14 -0
- package/dist/chunk-W4E7WMXE.cjs +71 -0
- package/dist/chunk-WJ3HK3LJ.cjs +1102 -0
- package/dist/chunk-WMAPPDMM.cjs +28 -0
- package/dist/chunk-WMOGFOUJ.cjs +223 -0
- package/dist/chunk-WPYFSQKK.cjs +37 -0
- package/dist/{chunk-56DAX2BE.mjs → chunk-WZXN4R5Y.mjs} +24 -13
- package/dist/chunk-XDGMADQM.cjs +14225 -0
- package/dist/chunk-XGC343EY.cjs +443 -0
- package/dist/chunk-XSKZORAS.cjs +727 -0
- package/dist/chunk-XWAWFQFS.cjs +82 -0
- package/dist/chunk-Y4YMF2NQ.cjs +460 -0
- package/dist/chunk-Y4YWHNKU.cjs +250 -0
- package/dist/chunk-Y53ZSFN6.cjs +504 -0
- package/dist/chunk-YA6LLTIJ.cjs +411 -0
- package/dist/chunk-YFPGHF5F.cjs +202 -0
- package/dist/chunk-YJRZR7VU.cjs +28 -0
- package/dist/chunk-YTAABQEV.cjs +1 -0
- package/dist/chunk-YX3DBN4M.cjs +18 -0
- package/dist/chunk-YZTASLPQ.cjs +64 -0
- package/dist/chunk-Z5HIWVDP.cjs +2173 -0
- package/dist/chunk-ZEG3OPIB.cjs +93 -0
- package/dist/chunk-ZMN3H73H.cjs +155 -0
- package/dist/client/lifecycle.cjs +6 -35
- package/dist/client-plugins.cjs +7 -448
- package/dist/client.cjs +171 -9808
- package/dist/config.cjs +8 -36
- package/dist/cron.cjs +24 -491
- package/dist/deferred.cjs +26 -475
- package/dist/deployment.cjs +39 -210
- package/dist/devtools-5KGPDVKL.cjs +388 -0
- package/dist/{devtools-UFVTMQX5.mjs → devtools-FY5R7TQ4.mjs} +3 -3
- package/dist/devtools-client-4WAPJY5L.cjs +254 -0
- package/dist/devtools-ui-5GBDIGMK.cjs +1296 -0
- package/dist/docs.cjs +46 -5657
- package/dist/docs.mjs +5 -5
- package/dist/env-types.cjs +5 -226
- package/dist/env.cjs +21 -338
- package/dist/environment/vite.cjs +8 -372
- package/dist/environment.cjs +12 -94
- package/dist/font.cjs +13 -63
- package/dist/headers.cjs +7 -123
- package/dist/i18n/client.cjs +55 -294
- package/dist/i18n/index.cjs +22 -209
- package/dist/i18n/server.cjs +22 -745
- package/dist/image/server.cjs +13 -729
- package/dist/image/sharp.cjs +33 -171
- package/dist/image.cjs +41 -85
- package/dist/index.cjs +1151 -68080
- package/dist/index.mjs +14 -14
- package/dist/instrumentation.cjs +12 -138
- package/dist/integration-orm-55F7CII5.cjs +13 -0
- package/dist/integrations.cjs +55 -4090
- package/dist/internal/app-markdown-runtime.cjs +27 -224
- package/dist/internal/app-markdown-runtime.mjs +2 -2
- package/dist/internal/build-runtime.cjs +120 -52259
- package/dist/internal/build-runtime.mjs +13 -13
- package/dist/internal/cli-runtime.cjs +67 -13811
- package/dist/internal/cli-runtime.mjs +7 -7
- package/dist/internal/client-error-overlay.cjs +80 -733
- package/dist/internal/client-error-overlay.mjs +1 -1
- package/dist/internal/client-runtime.cjs +81 -913
- package/dist/internal/compression-runtime.cjs +8 -214
- package/dist/internal/config-runtime.cjs +42 -6547
- package/dist/internal/config-runtime.mjs +3 -3
- package/dist/internal/docs-precompiled-runtime.cjs +26 -46
- package/dist/internal/infra-analytics-runtime.cjs +10 -536
- package/dist/internal/isolated-boundary.cjs +14 -414
- package/dist/internal/metadata-image-runtime.cjs +7 -285
- package/dist/internal/product-telemetry-runtime.cjs +42 -97
- package/dist/internal/product-telemetry-runtime.mjs +1 -1
- package/dist/internal/production-node-env.cjs +6 -63
- package/dist/internal/production-runtime.cjs +418 -7133
- package/dist/internal/production-runtime.mjs +3 -3
- package/dist/internal/request-cookies.cjs +6 -54
- package/dist/json-ld.cjs +24 -50
- package/dist/layers-E4WPJNY5.cjs +17 -0
- package/dist/manager-G4B2IPYE.cjs +14 -0
- package/dist/markdown.cjs +21 -547
- package/dist/markdown.mjs +1 -1
- package/dist/middleware.cjs +36 -2995
- package/dist/navigation.cjs +22 -2588
- package/dist/nitro-4I2MYLY2.cjs +652 -0
- package/dist/observability.cjs +22 -614
- package/dist/og.cjs +5 -28
- package/dist/plugin.cjs +106 -37442
- package/dist/plugin.mjs +9 -9
- package/dist/query/client.cjs +113 -449
- package/dist/query/index.cjs +26 -288
- package/dist/query/parsers.cjs +23 -247
- package/dist/query/server.cjs +36 -298
- package/dist/renderer/react/client.cjs +9 -43
- package/dist/renderer/react/server.cjs +40 -103
- package/dist/renderer/react/vite.cjs +7 -29
- package/dist/renderer-client.cjs +126 -4295
- package/dist/renderer.cjs +31 -249
- package/dist/request.cjs +5 -68
- package/dist/router.cjs +11 -474
- package/dist/routes.cjs +42 -2461
- package/dist/{schema-dev-notice-2IE2F2XI.mjs → schema-dev-notice-O67CPXJ6.mjs} +1 -1
- package/dist/schema-dev-notice-Y7MQEFGN.cjs +56 -0
- package/dist/schema.cjs +6 -33
- package/dist/search-client-G3RICOFU.cjs +13 -0
- package/dist/server-action-security.cjs +25 -541
- package/dist/server-fn-client.cjs +6 -337
- package/dist/server-fn.cjs +32 -1841
- package/dist/server-plugins.cjs +15 -884
- package/dist/server-query-client.cjs +15 -1883
- package/dist/server-query.cjs +16 -1838
- package/dist/server.cjs +296 -44681
- package/dist/server.mjs +11 -11
- package/dist/storage.cjs +57 -576
- package/dist/testing.cjs +89 -3186
- package/dist/theme/client.cjs +13 -108
- package/dist/theme/index.cjs +6 -68
- package/dist/theme/runtime.cjs +13 -78
- package/dist/theme/server.cjs +10 -179
- package/dist/version.cjs +4 -32
- package/dist/version.mjs +1 -1
- package/dist/vite.cjs +119 -37773
- package/dist/vite.mjs +9 -9
- package/dist/workflows.cjs +19 -1040
- package/package.json +1 -1
package/dist/navigation.cjs
CHANGED
|
@@ -1,2608 +1,42 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
-
};
|
|
11
|
-
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
-
for (let key of __getOwnPropNames(from))
|
|
14
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
-
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
20
2
|
|
|
21
|
-
// src/navigation.ts
|
|
22
|
-
var navigation_exports = {};
|
|
23
|
-
__export(navigation_exports, {
|
|
24
|
-
getFarmRedirectError: () => getFarmRedirectError,
|
|
25
|
-
isFarmNotFoundError: () => isFarmNotFoundError,
|
|
26
|
-
isFarmRedirectError: () => isFarmRedirectError,
|
|
27
|
-
notFound: () => notFound,
|
|
28
|
-
permanentRedirect: () => permanentRedirect,
|
|
29
|
-
redirect: () => redirect,
|
|
30
|
-
usePathname: () => usePathname,
|
|
31
|
-
useRouter: () => useRouter2,
|
|
32
|
-
useSearchParams: () => useSearchParams
|
|
33
|
-
});
|
|
34
|
-
module.exports = __toCommonJS(navigation_exports);
|
|
35
3
|
|
|
36
|
-
// src/client/router.ts
|
|
37
|
-
var import_react = require("react");
|
|
38
4
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
};
|
|
54
|
-
__name(_NonTerminalCatchAllRouteError, "NonTerminalCatchAllRouteError");
|
|
55
|
-
var NonTerminalCatchAllRouteError = _NonTerminalCatchAllRouteError;
|
|
56
|
-
var _DuplicateRouteParameterError = class _DuplicateRouteParameterError extends AmbiguousRouteError {
|
|
57
|
-
constructor(message) {
|
|
58
|
-
super(message);
|
|
59
|
-
this.name = "DuplicateRouteParameterError";
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
__name(_DuplicateRouteParameterError, "DuplicateRouteParameterError");
|
|
63
|
-
var DuplicateRouteParameterError = _DuplicateRouteParameterError;
|
|
64
|
-
var _ReservedRouteParameterError = class _ReservedRouteParameterError extends AmbiguousRouteError {
|
|
65
|
-
constructor(message) {
|
|
66
|
-
super(message);
|
|
67
|
-
this.name = "ReservedRouteParameterError";
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
__name(_ReservedRouteParameterError, "ReservedRouteParameterError");
|
|
71
|
-
var ReservedRouteParameterError = _ReservedRouteParameterError;
|
|
72
|
-
var _BrowserUnstableRouteError = class _BrowserUnstableRouteError extends TypeError {
|
|
73
|
-
constructor(message) {
|
|
74
|
-
super(message);
|
|
75
|
-
this.name = "BrowserUnstableRouteError";
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
__name(_BrowserUnstableRouteError, "BrowserUnstableRouteError");
|
|
79
|
-
var BrowserUnstableRouteError = _BrowserUnstableRouteError;
|
|
80
|
-
var SEGMENT_RANK = {
|
|
81
|
-
static: 4,
|
|
82
|
-
dynamic: 3,
|
|
83
|
-
"catch-all": 1,
|
|
84
|
-
"optional-catch-all": 0
|
|
85
|
-
};
|
|
86
|
-
var ROUTE_END_RANK = 2;
|
|
87
|
-
function compareRouteSpecificity(left, right) {
|
|
88
|
-
const length = Math.max(left.length, right.length);
|
|
89
|
-
for (let index = 0; index < length; index++) {
|
|
90
|
-
const leftRank = index < left.length ? SEGMENT_RANK[left[index]] : ROUTE_END_RANK;
|
|
91
|
-
const rightRank = index < right.length ? SEGMENT_RANK[right[index]] : ROUTE_END_RANK;
|
|
92
|
-
if (leftRank !== rightRank) return rightRank - leftRank;
|
|
93
|
-
}
|
|
94
|
-
return 0;
|
|
95
|
-
}
|
|
96
|
-
__name(compareRouteSpecificity, "compareRouteSpecificity");
|
|
97
|
-
var ROUTER_PARAMETER_NAME = "[A-Za-z0-9_$-]+";
|
|
98
|
-
var PAGE_PARAMETER_PATTERN = /^(?:\[\[\.\.\.(.+)\]\]|\[\.\.\.(.+)\]|\[(.+)\])$/;
|
|
99
|
-
var ROUTER_PARAMETER_PATTERN = /^(?:\[\[\.\.\.([A-Za-z0-9_$-]+)\]\]|\[\.\.\.([A-Za-z0-9_$-]+)\]|\[([A-Za-z0-9_$-]+)\]|:([A-Za-z0-9_$-]+)|\*([A-Za-z0-9_$-]+)\??)$/;
|
|
100
|
-
var RESERVED_PARAMETER_NAMES = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
101
|
-
function assertBrowserStableRoutePath(pattern) {
|
|
102
|
-
if (pattern.includes("\\") || hasControlCharacter(pattern)) {
|
|
103
|
-
throw new BrowserUnstableRouteError(
|
|
104
|
-
`Route path "${pattern}" cannot contain backslashes or control characters.`
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
for (const segment of pattern.split("/").filter(Boolean)) {
|
|
108
|
-
if (segment.startsWith("(") && segment.endsWith(")") || segment.startsWith("[") && segment.endsWith("]")) {
|
|
109
|
-
continue;
|
|
110
|
-
}
|
|
111
|
-
let decoded = segment;
|
|
112
|
-
try {
|
|
113
|
-
decoded = decodeURIComponent(segment);
|
|
114
|
-
} catch {
|
|
115
|
-
}
|
|
116
|
-
if (decoded === "." || decoded === ".." || decoded.includes("/") || decoded.includes("\\") || hasControlCharacter(decoded)) {
|
|
117
|
-
throw new BrowserUnstableRouteError(
|
|
118
|
-
`Route path "${pattern}" contains browser-unstable segment "${segment}".`
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
__name(assertBrowserStableRoutePath, "assertBrowserStableRoutePath");
|
|
124
|
-
function hasControlCharacter(value) {
|
|
125
|
-
return Array.from(value).some((character) => {
|
|
126
|
-
const code = character.charCodeAt(0);
|
|
127
|
-
return code <= 31 || code >= 127 && code <= 159;
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
__name(hasControlCharacter, "hasControlCharacter");
|
|
131
|
-
function assertUniqueRouteParameters(pattern, syntax = "page") {
|
|
132
|
-
const parameterPattern = syntax === "router" ? ROUTER_PARAMETER_PATTERN : PAGE_PARAMETER_PATTERN;
|
|
133
|
-
const names = /* @__PURE__ */ new Set();
|
|
134
|
-
for (const segment of splitRoutePattern(pattern, syntax)) {
|
|
135
|
-
const match = parameterPattern.exec(segment);
|
|
136
|
-
const name = match?.slice(1).find(Boolean);
|
|
137
|
-
if (!name) continue;
|
|
138
|
-
if (RESERVED_PARAMETER_NAMES.has(name)) {
|
|
139
|
-
throw new ReservedRouteParameterError(
|
|
140
|
-
`Route parameter "${name}" in route "${pattern}" is reserved. Use a different parameter name.`
|
|
141
|
-
);
|
|
142
|
-
}
|
|
143
|
-
if (names.has(name)) {
|
|
144
|
-
throw new DuplicateRouteParameterError(
|
|
145
|
-
`Duplicate route parameter "${name}" in route "${pattern}". Each dynamic segment must use a unique name.`
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
names.add(name);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
__name(assertUniqueRouteParameters, "assertUniqueRouteParameters");
|
|
152
|
-
function splitRoutePattern(pattern, syntax) {
|
|
153
|
-
return pattern.replace(/\\/g, "/").split("/").filter(Boolean).filter(
|
|
154
|
-
(segment) => syntax === "api" ? true : !(segment.startsWith("(") && segment.endsWith(")"))
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
|
-
__name(splitRoutePattern, "splitRoutePattern");
|
|
158
|
-
function assertTerminalCatchAll(pattern, syntax = "page") {
|
|
159
|
-
const segments = splitRoutePattern(pattern, syntax);
|
|
160
|
-
const parameterName = syntax === "router" ? ROUTER_PARAMETER_NAME : ".+";
|
|
161
|
-
const catchAllPattern = new RegExp(
|
|
162
|
-
syntax === "router" ? `^(?:\\[\\[\\.\\.\\.${parameterName}\\]\\]|\\[\\.\\.\\.${parameterName}\\]|\\*${parameterName}\\??)$` : `^(?:\\[\\[\\.\\.\\.${parameterName}\\]\\]|\\[\\.\\.\\.${parameterName}\\])$`
|
|
163
|
-
);
|
|
164
|
-
const catchAllIndex = segments.findIndex((segment) => catchAllPattern.test(segment));
|
|
165
|
-
if (catchAllIndex >= 0 && catchAllIndex !== segments.length - 1) {
|
|
166
|
-
throw new NonTerminalCatchAllRouteError(
|
|
167
|
-
`Catch-all segment "${segments[catchAllIndex]}" must be the final segment in route "${pattern}".`
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
__name(assertTerminalCatchAll, "assertTerminalCatchAll");
|
|
172
|
-
function getRoutePatternShape(pattern, syntax = "page") {
|
|
173
|
-
assertTerminalCatchAll(pattern, syntax);
|
|
174
|
-
const segments = splitRoutePattern(pattern, syntax).map((segment) => {
|
|
175
|
-
const specificity = getPatternSegmentSpecificity(segment, syntax);
|
|
176
|
-
if (specificity !== "static") return specificity;
|
|
177
|
-
try {
|
|
178
|
-
return `static:${decodeURIComponent(segment)}`;
|
|
179
|
-
} catch {
|
|
180
|
-
return `static:${segment}`;
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
return segments.length === 0 ? "/" : JSON.stringify(segments);
|
|
184
|
-
}
|
|
185
|
-
__name(getRoutePatternShape, "getRoutePatternShape");
|
|
186
|
-
function getPatternSegmentSpecificity(segment, syntax) {
|
|
187
|
-
const parameterName = syntax === "router" ? ROUTER_PARAMETER_NAME : ".+";
|
|
188
|
-
const supportsColonAndStar = syntax === "router";
|
|
189
|
-
if (new RegExp(`^\\[\\[\\.\\.\\.${parameterName}\\]\\]$`).test(segment) || supportsColonAndStar && new RegExp(`^\\*${parameterName}\\?$`).test(segment)) {
|
|
190
|
-
return "optional-catch-all";
|
|
191
|
-
}
|
|
192
|
-
if (new RegExp(`^\\[\\.\\.\\.${parameterName}\\]$`).test(segment) || supportsColonAndStar && new RegExp(`^\\*${parameterName}$`).test(segment)) {
|
|
193
|
-
return "catch-all";
|
|
194
|
-
}
|
|
195
|
-
if (new RegExp(`^\\[${parameterName}\\]$`).test(segment) || supportsColonAndStar && new RegExp(`^:${parameterName}$`).test(segment)) {
|
|
196
|
-
return "dynamic";
|
|
197
|
-
}
|
|
198
|
-
return "static";
|
|
199
|
-
}
|
|
200
|
-
__name(getPatternSegmentSpecificity, "getPatternSegmentSpecificity");
|
|
5
|
+
var _chunkKVFPGF2Mcjs = require('./chunk-KVFPGF2M.cjs');
|
|
6
|
+
require('./chunk-62YJ2IEB.cjs');
|
|
7
|
+
require('./chunk-SU7MH53P.cjs');
|
|
8
|
+
require('./chunk-PCOTGFSM.cjs');
|
|
9
|
+
require('./chunk-WJ3HK3LJ.cjs');
|
|
10
|
+
require('./chunk-5OVTOKGH.cjs');
|
|
11
|
+
require('./chunk-R5A5KNVX.cjs');
|
|
12
|
+
require('./chunk-SWN467MP.cjs');
|
|
13
|
+
require('./chunk-J7FSKED3.cjs');
|
|
14
|
+
require('./chunk-OXSIH4D6.cjs');
|
|
15
|
+
require('./chunk-R5JIFR6B.cjs');
|
|
16
|
+
require('./chunk-C5GUTBZK.cjs');
|
|
17
|
+
require('./chunk-QBK2AA4U.cjs');
|
|
18
|
+
require('./chunk-LIUGYUX3.cjs');
|
|
201
19
|
|
|
202
|
-
// src/routing/matcher.ts
|
|
203
|
-
function parseRoutePattern(pattern) {
|
|
204
|
-
assertBrowserStableRoutePath(pattern);
|
|
205
|
-
assertTerminalCatchAll(pattern, "router");
|
|
206
|
-
assertUniqueRouteParameters(pattern, "router");
|
|
207
|
-
return splitRoutePattern2(pattern).filter((part) => !isRouteGroup(part)).map((part) => {
|
|
208
|
-
const optionalCatchAll = part.match(/^\[\[\.\.\.([A-Za-z0-9_$-]+)\]\]$/);
|
|
209
|
-
if (optionalCatchAll) {
|
|
210
|
-
return {
|
|
211
|
-
type: "dynamic",
|
|
212
|
-
name: optionalCatchAll[1],
|
|
213
|
-
catchAll: true,
|
|
214
|
-
optional: true
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
const catchAll = part.match(/^\[\.\.\.([A-Za-z0-9_$-]+)\]$/);
|
|
218
|
-
if (catchAll) {
|
|
219
|
-
return {
|
|
220
|
-
type: "dynamic",
|
|
221
|
-
name: catchAll[1],
|
|
222
|
-
catchAll: true,
|
|
223
|
-
optional: false
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
const dynamic = part.match(/^\[([A-Za-z0-9_$-]+)\]$/) || part.match(/^:([A-Za-z0-9_$-]+)$/);
|
|
227
|
-
if (dynamic) {
|
|
228
|
-
return {
|
|
229
|
-
type: "dynamic",
|
|
230
|
-
name: dynamic[1],
|
|
231
|
-
catchAll: false,
|
|
232
|
-
optional: false
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
const star = part.match(/^\*([A-Za-z0-9_$-]+)(\?)?$/);
|
|
236
|
-
if (star) {
|
|
237
|
-
return {
|
|
238
|
-
type: "dynamic",
|
|
239
|
-
name: star[1],
|
|
240
|
-
catchAll: true,
|
|
241
|
-
optional: !!star[2]
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
return {
|
|
245
|
-
type: "static",
|
|
246
|
-
value: decodePathSegment(part)
|
|
247
|
-
};
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
__name(parseRoutePattern, "parseRoutePattern");
|
|
251
|
-
function matchSegmentParts(segments, parts, allowTrailingSegments = false) {
|
|
252
|
-
const params = {};
|
|
253
|
-
if (segments.length === 0) {
|
|
254
|
-
return parts.length === 0 ? params : null;
|
|
255
|
-
}
|
|
256
|
-
let pathIndex = 0;
|
|
257
|
-
for (const segment of segments) {
|
|
258
|
-
if (segment.type === "static") {
|
|
259
|
-
if (decodePathSegment(parts[pathIndex] || "") !== segment.value) return null;
|
|
260
|
-
pathIndex++;
|
|
261
|
-
continue;
|
|
262
|
-
}
|
|
263
|
-
if (segment.catchAll) {
|
|
264
|
-
const remaining = parts.slice(pathIndex).map(decodePathSegment);
|
|
265
|
-
if (remaining.length === 0 && !segment.optional) return null;
|
|
266
|
-
params[segment.name] = remaining.join("/");
|
|
267
|
-
pathIndex = parts.length;
|
|
268
|
-
continue;
|
|
269
|
-
}
|
|
270
|
-
const value = parts[pathIndex];
|
|
271
|
-
if (!value) return null;
|
|
272
|
-
params[segment.name] = decodePathSegment(value);
|
|
273
|
-
pathIndex++;
|
|
274
|
-
}
|
|
275
|
-
return allowTrailingSegments || pathIndex === parts.length ? params : null;
|
|
276
|
-
}
|
|
277
|
-
__name(matchSegmentParts, "matchSegmentParts");
|
|
278
|
-
function normalizePathname(value) {
|
|
279
|
-
const raw = value || "/";
|
|
280
|
-
let pathname = raw;
|
|
281
|
-
try {
|
|
282
|
-
pathname = new URL(raw, "http://farm.local").pathname;
|
|
283
|
-
} catch {
|
|
284
|
-
pathname = raw.split(/[?#]/, 1)[0] || "/";
|
|
285
|
-
}
|
|
286
|
-
pathname = pathname.replace(/\\/g, "/").replace(/\/+/g, "/");
|
|
287
|
-
if (!pathname.startsWith("/")) pathname = `/${pathname}`;
|
|
288
|
-
if (pathname.length > 1) pathname = pathname.replace(/\/+$/, "");
|
|
289
|
-
return pathname || "/";
|
|
290
|
-
}
|
|
291
|
-
__name(normalizePathname, "normalizePathname");
|
|
292
|
-
function splitNormalizedPathname(pathname) {
|
|
293
|
-
return pathname.split("/").filter(Boolean);
|
|
294
|
-
}
|
|
295
|
-
__name(splitNormalizedPathname, "splitNormalizedPathname");
|
|
296
|
-
function normalizeRoutePattern(value) {
|
|
297
|
-
let pathname = (value || "/").replace(/\\/g, "/").replace(/\/+/g, "/");
|
|
298
|
-
if (!pathname.startsWith("/")) pathname = `/${pathname}`;
|
|
299
|
-
if (pathname.length > 1) pathname = pathname.replace(/\/+$/, "");
|
|
300
|
-
return pathname || "/";
|
|
301
|
-
}
|
|
302
|
-
__name(normalizeRoutePattern, "normalizeRoutePattern");
|
|
303
|
-
function splitRoutePattern2(pattern) {
|
|
304
|
-
return normalizeRoutePattern(pattern).split("/").filter(Boolean);
|
|
305
|
-
}
|
|
306
|
-
__name(splitRoutePattern2, "splitRoutePattern");
|
|
307
|
-
function isRouteGroup(part) {
|
|
308
|
-
return part.startsWith("(") && part.endsWith(")");
|
|
309
|
-
}
|
|
310
|
-
__name(isRouteGroup, "isRouteGroup");
|
|
311
|
-
function decodePathSegment(value) {
|
|
312
|
-
try {
|
|
313
|
-
return decodeURIComponent(value);
|
|
314
|
-
} catch {
|
|
315
|
-
return value;
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
__name(decodePathSegment, "decodePathSegment");
|
|
319
20
|
|
|
320
|
-
// src/router.ts
|
|
321
|
-
function createFarmRouter(routes) {
|
|
322
|
-
const normalizedRoutes = routes.map(normalizeRouteInput);
|
|
323
|
-
const patternsByShape = /* @__PURE__ */ new Map();
|
|
324
|
-
for (const entry of normalizedRoutes) {
|
|
325
|
-
const shape = getRoutePatternShape(entry.route.path, "router");
|
|
326
|
-
const existingPattern = patternsByShape.get(shape);
|
|
327
|
-
if (existingPattern) {
|
|
328
|
-
throw new AmbiguousRouteError(
|
|
329
|
-
`Ambiguous route patterns "${existingPattern}" and "${entry.route.path}" match the same URLs. Keep only one route for this URL shape.`
|
|
330
|
-
);
|
|
331
|
-
}
|
|
332
|
-
patternsByShape.set(shape, entry.route.path);
|
|
333
|
-
}
|
|
334
|
-
normalizedRoutes.sort(compareRoutes);
|
|
335
|
-
const exactRoutes = /* @__PURE__ */ new Map();
|
|
336
|
-
for (const entry of normalizedRoutes) {
|
|
337
|
-
if (entry.segments.every((segment) => segment.type === "static")) {
|
|
338
|
-
const pathname = entry.segments.length ? `/${entry.segments.map((segment) => encodePathSegment(segment.value)).join("/")}` : "/";
|
|
339
|
-
exactRoutes.set(pathname, entry);
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
return {
|
|
343
|
-
routes: normalizedRoutes.map((entry) => entry.route),
|
|
344
|
-
match(pathname) {
|
|
345
|
-
const normalizedPathname = normalizePathname(pathname);
|
|
346
|
-
const exactRoute = exactRoutes.get(normalizedPathname);
|
|
347
|
-
if (exactRoute) {
|
|
348
|
-
return {
|
|
349
|
-
route: exactRoute.route,
|
|
350
|
-
pathname: normalizedPathname,
|
|
351
|
-
params: {}
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
|
-
const parts = splitNormalizedPathname(normalizedPathname);
|
|
355
|
-
for (const entry of normalizedRoutes) {
|
|
356
|
-
const params = matchSegmentParts(entry.segments, parts);
|
|
357
|
-
if (params) {
|
|
358
|
-
return {
|
|
359
|
-
route: entry.route,
|
|
360
|
-
pathname: normalizedPathname,
|
|
361
|
-
params
|
|
362
|
-
};
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
return null;
|
|
366
|
-
},
|
|
367
|
-
build: buildFarmRoutePath,
|
|
368
|
-
isActive: isFarmRouteActive
|
|
369
|
-
};
|
|
370
|
-
}
|
|
371
|
-
__name(createFarmRouter, "createFarmRouter");
|
|
372
|
-
function buildFarmRoutePath(pattern, params = {}, options = {}) {
|
|
373
|
-
const parts = [];
|
|
374
|
-
for (const segment of parseRoutePattern(pattern)) {
|
|
375
|
-
if (segment.type === "static") {
|
|
376
|
-
parts.push(encodePathSegment(segment.value));
|
|
377
|
-
continue;
|
|
378
|
-
}
|
|
379
|
-
const value = params[segment.name];
|
|
380
|
-
const values = Array.isArray(value) ? value : value == null ? [] : [value];
|
|
381
|
-
if (values.length === 0) {
|
|
382
|
-
if (segment.optional) continue;
|
|
383
|
-
throw new Error(`Missing route param "${segment.name}" for ${pattern}.`);
|
|
384
|
-
}
|
|
385
|
-
if (!segment.catchAll && values.length > 1) {
|
|
386
|
-
throw new Error(`Route param "${segment.name}" for ${pattern} expects a single value.`);
|
|
387
|
-
}
|
|
388
|
-
const encodedValues = values.map((item) => {
|
|
389
|
-
const value2 = String(item);
|
|
390
|
-
if (!value2) {
|
|
391
|
-
throw new Error(
|
|
392
|
-
`Route param "${segment.name}" for ${pattern} cannot contain an empty path segment.`
|
|
393
|
-
);
|
|
394
|
-
}
|
|
395
|
-
return encodePathSegment(value2);
|
|
396
|
-
});
|
|
397
|
-
parts.push(...encodedValues);
|
|
398
|
-
}
|
|
399
|
-
let pathname = parts.length ? `/${parts.join("/")}` : "/";
|
|
400
|
-
if (options.trailingSlash && pathname !== "/") {
|
|
401
|
-
pathname = `${pathname}/`;
|
|
402
|
-
}
|
|
403
|
-
return appendQueryAndHash(pathname, options);
|
|
404
|
-
}
|
|
405
|
-
__name(buildFarmRoutePath, "buildFarmRoutePath");
|
|
406
|
-
function isFarmRouteActive(pattern, pathname, options = {}) {
|
|
407
|
-
const normalizedPathname = normalizePathname(pathname);
|
|
408
|
-
const segments = parseRoutePattern(pattern);
|
|
409
|
-
const parts = splitNormalizedPathname(normalizedPathname);
|
|
410
|
-
if (matchSegmentParts(segments, parts)) return true;
|
|
411
|
-
if (options.exact !== false) return false;
|
|
412
|
-
if (segments.length === 0) return normalizedPathname === "/";
|
|
413
|
-
return matchSegmentParts(segments, parts, true) !== null;
|
|
414
|
-
}
|
|
415
|
-
__name(isFarmRouteActive, "isFarmRouteActive");
|
|
416
|
-
function normalizeRouteInput(input, index) {
|
|
417
|
-
const route = typeof input === "string" ? { path: input } : input;
|
|
418
|
-
const segments = parseRoutePattern(route.path);
|
|
419
|
-
const path = normalizeRoutePattern(route.path);
|
|
420
|
-
return {
|
|
421
|
-
route: {
|
|
422
|
-
...route,
|
|
423
|
-
path
|
|
424
|
-
},
|
|
425
|
-
segments,
|
|
426
|
-
specificity: segments.map(getRouterSegmentSpecificity),
|
|
427
|
-
index
|
|
428
|
-
};
|
|
429
|
-
}
|
|
430
|
-
__name(normalizeRouteInput, "normalizeRouteInput");
|
|
431
|
-
function compareRoutes(left, right) {
|
|
432
|
-
const specificity = compareRouteSpecificity(left.specificity, right.specificity);
|
|
433
|
-
if (specificity !== 0) return specificity;
|
|
434
|
-
return left.index - right.index;
|
|
435
|
-
}
|
|
436
|
-
__name(compareRoutes, "compareRoutes");
|
|
437
|
-
function getRouterSegmentSpecificity(segment) {
|
|
438
|
-
if (segment.type === "static") return "static";
|
|
439
|
-
if (!segment.catchAll) return "dynamic";
|
|
440
|
-
return segment.optional ? "optional-catch-all" : "catch-all";
|
|
441
|
-
}
|
|
442
|
-
__name(getRouterSegmentSpecificity, "getRouterSegmentSpecificity");
|
|
443
|
-
function encodePathSegment(value) {
|
|
444
|
-
return encodeURIComponent(value);
|
|
445
|
-
}
|
|
446
|
-
__name(encodePathSegment, "encodePathSegment");
|
|
447
|
-
function appendQueryAndHash(pathname, options) {
|
|
448
|
-
const search = createSearchParams(options.query);
|
|
449
|
-
const hash = options.hash ? `#${options.hash.replace(/^#/, "")}` : "";
|
|
450
|
-
const query = search.toString();
|
|
451
|
-
return `${pathname}${query ? `?${query}` : ""}${hash}`;
|
|
452
|
-
}
|
|
453
|
-
__name(appendQueryAndHash, "appendQueryAndHash");
|
|
454
|
-
function createSearchParams(query) {
|
|
455
|
-
if (query instanceof URLSearchParams) return query;
|
|
456
|
-
const search = new URLSearchParams();
|
|
457
|
-
if (!query) return search;
|
|
458
|
-
for (const [key, value] of Object.entries(query)) {
|
|
459
|
-
const values = Array.isArray(value) ? value : [value];
|
|
460
|
-
for (const item of values) {
|
|
461
|
-
if (item == null) continue;
|
|
462
|
-
search.append(key, String(item));
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
return search;
|
|
466
|
-
}
|
|
467
|
-
__name(createSearchParams, "createSearchParams");
|
|
468
21
|
|
|
469
|
-
// src/deferred.ts
|
|
470
|
-
var FARM_DEFERRED_CONTENT_TYPE = "application/x-farm-deferred+json";
|
|
471
|
-
var FARM_DEFERRED_ERROR_CODE = "FARM_DEFERRED_DATA_ERROR";
|
|
472
|
-
var FARM_DEFERRED_MARKER = "$farmDeferred";
|
|
473
|
-
var _DeferredDataError = class _DeferredDataError extends Error {
|
|
474
|
-
constructor(message = "Deferred route data failed to load") {
|
|
475
|
-
super(message);
|
|
476
|
-
this.name = "DeferredDataError";
|
|
477
|
-
this.code = FARM_DEFERRED_ERROR_CODE;
|
|
478
|
-
}
|
|
479
|
-
};
|
|
480
|
-
__name(_DeferredDataError, "DeferredDataError");
|
|
481
|
-
var DeferredDataError = _DeferredDataError;
|
|
482
|
-
async function readDeferredDataResponse(response, options = {}) {
|
|
483
|
-
const contentType = response.headers.get("Content-Type") || "";
|
|
484
|
-
if (!contentType.toLowerCase().startsWith(FARM_DEFERRED_CONTENT_TYPE)) {
|
|
485
|
-
const data2 = await response.json();
|
|
486
|
-
notifyDeferredComplete(options);
|
|
487
|
-
return data2;
|
|
488
|
-
}
|
|
489
|
-
if (!response.body) {
|
|
490
|
-
throw new DeferredDataError("Deferred route data response has no body");
|
|
491
|
-
}
|
|
492
|
-
const reader = response.body.getReader();
|
|
493
|
-
const decoder = new TextDecoder();
|
|
494
|
-
const controllers = /* @__PURE__ */ new Map();
|
|
495
|
-
let buffer = "";
|
|
496
|
-
let complete = false;
|
|
497
|
-
const readLine = /* @__PURE__ */ __name(async () => {
|
|
498
|
-
while (true) {
|
|
499
|
-
const newline = buffer.indexOf("\n");
|
|
500
|
-
if (newline >= 0) {
|
|
501
|
-
const line = buffer.slice(0, newline);
|
|
502
|
-
buffer = buffer.slice(newline + 1);
|
|
503
|
-
return line;
|
|
504
|
-
}
|
|
505
|
-
if (complete) {
|
|
506
|
-
if (!buffer) return void 0;
|
|
507
|
-
const line = buffer;
|
|
508
|
-
buffer = "";
|
|
509
|
-
return line;
|
|
510
|
-
}
|
|
511
|
-
const chunk = await reader.read();
|
|
512
|
-
complete = chunk.done;
|
|
513
|
-
if (chunk.value) buffer += decoder.decode(chunk.value, { stream: !chunk.done });
|
|
514
|
-
if (chunk.done) buffer += decoder.decode();
|
|
515
|
-
}
|
|
516
|
-
}, "readLine");
|
|
517
|
-
const firstLine = await readLine();
|
|
518
|
-
if (!firstLine) {
|
|
519
|
-
reader.releaseLock();
|
|
520
|
-
throw new DeferredDataError("Deferred route data response is empty");
|
|
521
|
-
}
|
|
522
|
-
const initial = parseDeferredMessage(firstLine);
|
|
523
|
-
if (initial.type !== "data") {
|
|
524
|
-
reader.releaseLock();
|
|
525
|
-
throw new DeferredDataError("Deferred route data response is invalid");
|
|
526
|
-
}
|
|
527
|
-
const data = reviveDeferredValue(initial.data, controllers);
|
|
528
|
-
void (async () => {
|
|
529
|
-
try {
|
|
530
|
-
for (let line = await readLine(); line !== void 0; line = await readLine()) {
|
|
531
|
-
if (!line) continue;
|
|
532
|
-
const message = parseDeferredMessage(line);
|
|
533
|
-
if (message.type === "resolve") {
|
|
534
|
-
const controller = getControlledDeferred(message.id, controllers);
|
|
535
|
-
controller.resolve(reviveDeferredValue(message.data, controllers));
|
|
536
|
-
} else if (message.type === "reject") {
|
|
537
|
-
getControlledDeferred(message.id, controllers).reject(
|
|
538
|
-
new DeferredDataError(message.error?.message)
|
|
539
|
-
);
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
const outstanding = rejectPendingDeferred(
|
|
543
|
-
controllers,
|
|
544
|
-
"Deferred route data stream ended before completion"
|
|
545
|
-
);
|
|
546
|
-
if (outstanding === 0) notifyDeferredComplete(options);
|
|
547
|
-
} catch {
|
|
548
|
-
rejectPendingDeferred(controllers, "Deferred route data stream could not be read");
|
|
549
|
-
} finally {
|
|
550
|
-
reader.releaseLock();
|
|
551
|
-
}
|
|
552
|
-
})();
|
|
553
|
-
return data;
|
|
554
|
-
}
|
|
555
|
-
__name(readDeferredDataResponse, "readDeferredDataResponse");
|
|
556
|
-
function notifyDeferredComplete(options) {
|
|
557
|
-
try {
|
|
558
|
-
options.onComplete?.();
|
|
559
|
-
} catch {
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
__name(notifyDeferredComplete, "notifyDeferredComplete");
|
|
563
|
-
function reviveDeferredValue(value, controllers, settlements, applyingSettlements = /* @__PURE__ */ new Set()) {
|
|
564
|
-
if (isDeferredMarker(value)) {
|
|
565
|
-
const id = value[FARM_DEFERRED_MARKER];
|
|
566
|
-
if (id.startsWith("!")) {
|
|
567
|
-
return { [FARM_DEFERRED_MARKER]: id.slice(1) };
|
|
568
|
-
}
|
|
569
|
-
const controller = getControlledDeferred(id, controllers);
|
|
570
|
-
const settlement = settlements?.[id];
|
|
571
|
-
if (settlement && controller.promise.status === "pending") {
|
|
572
|
-
if (applyingSettlements.has(id)) return controller.promise;
|
|
573
|
-
applyingSettlements.add(id);
|
|
574
|
-
if (settlement.status === "fulfilled") {
|
|
575
|
-
controller.resolve(
|
|
576
|
-
reviveDeferredValue(settlement.value, controllers, settlements, applyingSettlements)
|
|
577
|
-
);
|
|
578
|
-
} else {
|
|
579
|
-
controller.reject(new DeferredDataError(settlement.error.message));
|
|
580
|
-
}
|
|
581
|
-
applyingSettlements.delete(id);
|
|
582
|
-
} else if (settlements && controller.promise.status === "pending") {
|
|
583
|
-
controller.reject(new DeferredDataError("Deferred route data was not resolved"));
|
|
584
|
-
}
|
|
585
|
-
return controller.promise;
|
|
586
|
-
}
|
|
587
|
-
if (Array.isArray(value)) {
|
|
588
|
-
return value.map(
|
|
589
|
-
(item) => reviveDeferredValue(item, controllers, settlements, applyingSettlements)
|
|
590
|
-
);
|
|
591
|
-
}
|
|
592
|
-
if (!value || typeof value !== "object") return value;
|
|
593
|
-
const prototype = Object.getPrototypeOf(value);
|
|
594
|
-
if (prototype !== Object.prototype && prototype !== null) return value;
|
|
595
|
-
const output = {};
|
|
596
|
-
for (const [key, item] of Object.entries(value)) {
|
|
597
|
-
defineDataProperty(
|
|
598
|
-
output,
|
|
599
|
-
key,
|
|
600
|
-
reviveDeferredValue(item, controllers, settlements, applyingSettlements)
|
|
601
|
-
);
|
|
602
|
-
}
|
|
603
|
-
return output;
|
|
604
|
-
}
|
|
605
|
-
__name(reviveDeferredValue, "reviveDeferredValue");
|
|
606
|
-
function defineDataProperty(output, key, value) {
|
|
607
|
-
if (key === "__proto__") {
|
|
608
|
-
Object.defineProperty(output, key, {
|
|
609
|
-
value,
|
|
610
|
-
enumerable: true,
|
|
611
|
-
writable: true,
|
|
612
|
-
configurable: true
|
|
613
|
-
});
|
|
614
|
-
} else {
|
|
615
|
-
output[key] = value;
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
__name(defineDataProperty, "defineDataProperty");
|
|
619
|
-
function getControlledDeferred(id, controllers) {
|
|
620
|
-
const existing = controllers.get(id);
|
|
621
|
-
if (existing) return existing;
|
|
622
|
-
let nativeResolve;
|
|
623
|
-
let nativeReject;
|
|
624
|
-
const promise = new Promise((resolve, reject) => {
|
|
625
|
-
nativeResolve = resolve;
|
|
626
|
-
nativeReject = reject;
|
|
627
|
-
});
|
|
628
|
-
promise.status = "pending";
|
|
629
|
-
promise.catch(() => void 0);
|
|
630
|
-
const controlled = {
|
|
631
|
-
promise,
|
|
632
|
-
resolve(value) {
|
|
633
|
-
if (promise.status !== "pending") return;
|
|
634
|
-
promise.status = "fulfilled";
|
|
635
|
-
promise.value = value;
|
|
636
|
-
nativeResolve(value);
|
|
637
|
-
},
|
|
638
|
-
reject(error) {
|
|
639
|
-
if (promise.status !== "pending") return;
|
|
640
|
-
promise.status = "rejected";
|
|
641
|
-
promise.reason = error;
|
|
642
|
-
nativeReject(error);
|
|
643
|
-
}
|
|
644
|
-
};
|
|
645
|
-
controllers.set(id, controlled);
|
|
646
|
-
return controlled;
|
|
647
|
-
}
|
|
648
|
-
__name(getControlledDeferred, "getControlledDeferred");
|
|
649
|
-
function isDeferredMarker(value) {
|
|
650
|
-
return Boolean(
|
|
651
|
-
value && typeof value === "object" && Object.keys(value).length === 1 && typeof value[FARM_DEFERRED_MARKER] === "string"
|
|
652
|
-
);
|
|
653
|
-
}
|
|
654
|
-
__name(isDeferredMarker, "isDeferredMarker");
|
|
655
|
-
function parseDeferredMessage(line) {
|
|
656
|
-
try {
|
|
657
|
-
return JSON.parse(line);
|
|
658
|
-
} catch {
|
|
659
|
-
throw new DeferredDataError("Deferred route data response contains invalid JSON");
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
__name(parseDeferredMessage, "parseDeferredMessage");
|
|
663
|
-
function rejectPendingDeferred(controllers, message) {
|
|
664
|
-
let rejected = 0;
|
|
665
|
-
for (const controller of controllers.values()) {
|
|
666
|
-
if (controller.promise.status === "pending") {
|
|
667
|
-
controller.reject(new DeferredDataError(message));
|
|
668
|
-
rejected += 1;
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
return rejected;
|
|
672
|
-
}
|
|
673
|
-
__name(rejectPendingDeferred, "rejectPendingDeferred");
|
|
674
22
|
|
|
675
|
-
// src/client-cancellation.ts
|
|
676
|
-
function createClientCancellation(signal, timeoutMs = 0, parent) {
|
|
677
|
-
let timer;
|
|
678
|
-
let invalid;
|
|
679
|
-
let timeoutReason;
|
|
680
|
-
const signals = [signal, parent].filter((value) => !!value);
|
|
681
|
-
if (!Number.isInteger(timeoutMs) || timeoutMs < 0 || timeoutMs > 2147483647) {
|
|
682
|
-
invalid = new RangeError(
|
|
683
|
-
"timeoutMs must be an integer between 0 and 2147483647 (0 disables the deadline)."
|
|
684
|
-
);
|
|
685
|
-
} else if (timeoutMs > 0) {
|
|
686
|
-
const controller = new AbortController();
|
|
687
|
-
signals.push(controller.signal);
|
|
688
|
-
timer = setTimeout(() => {
|
|
689
|
-
timeoutReason = new DOMException("Client request timed out", "TimeoutError");
|
|
690
|
-
controller.abort(timeoutReason);
|
|
691
|
-
}, timeoutMs);
|
|
692
|
-
}
|
|
693
|
-
const combined = signals.length > 1 ? AbortSignal.any(signals) : signals[0];
|
|
694
|
-
let active = 0;
|
|
695
|
-
let closed = false;
|
|
696
|
-
const cleanup = /* @__PURE__ */ __name(() => {
|
|
697
|
-
if (closed && active === 0 && timer !== void 0) {
|
|
698
|
-
clearTimeout(timer);
|
|
699
|
-
timer = void 0;
|
|
700
|
-
}
|
|
701
|
-
}, "cleanup");
|
|
702
|
-
const check = /* @__PURE__ */ __name(() => {
|
|
703
|
-
if (invalid) throw invalid;
|
|
704
|
-
combined?.throwIfAborted();
|
|
705
|
-
}, "check");
|
|
706
|
-
return {
|
|
707
|
-
signal: combined,
|
|
708
|
-
get timedOut() {
|
|
709
|
-
return timeoutReason !== void 0 && combined?.reason === timeoutReason;
|
|
710
|
-
},
|
|
711
|
-
check,
|
|
712
|
-
hold() {
|
|
713
|
-
active++;
|
|
714
|
-
return () => {
|
|
715
|
-
active--;
|
|
716
|
-
cleanup();
|
|
717
|
-
};
|
|
718
|
-
},
|
|
719
|
-
// A race also bounds cooperative local dispatch and custom HTTP implementations.
|
|
720
|
-
// Late completion is consumed, but cannot turn a cancelled result into success.
|
|
721
|
-
async run(work) {
|
|
722
|
-
check();
|
|
723
|
-
active++;
|
|
724
|
-
let abort;
|
|
725
|
-
try {
|
|
726
|
-
if (!combined) return await work();
|
|
727
|
-
return await new Promise((resolve, reject) => {
|
|
728
|
-
abort = /* @__PURE__ */ __name(() => reject(combined.reason), "abort");
|
|
729
|
-
combined.addEventListener("abort", abort, { once: true });
|
|
730
|
-
Promise.resolve().then(() => {
|
|
731
|
-
check();
|
|
732
|
-
return work();
|
|
733
|
-
}).then(resolve, reject);
|
|
734
|
-
});
|
|
735
|
-
} finally {
|
|
736
|
-
if (abort) combined?.removeEventListener("abort", abort);
|
|
737
|
-
active--;
|
|
738
|
-
cleanup();
|
|
739
|
-
}
|
|
740
|
-
},
|
|
741
|
-
async delay(ms) {
|
|
742
|
-
let retryTimer;
|
|
743
|
-
try {
|
|
744
|
-
await this.run(
|
|
745
|
-
() => new Promise((resolve) => {
|
|
746
|
-
retryTimer = setTimeout(resolve, ms);
|
|
747
|
-
})
|
|
748
|
-
);
|
|
749
|
-
} finally {
|
|
750
|
-
if (retryTimer !== void 0) clearTimeout(retryTimer);
|
|
751
|
-
}
|
|
752
|
-
},
|
|
753
|
-
dispose() {
|
|
754
|
-
closed = true;
|
|
755
|
-
cleanup();
|
|
756
|
-
}
|
|
757
|
-
};
|
|
758
|
-
}
|
|
759
|
-
__name(createClientCancellation, "createClientCancellation");
|
|
760
23
|
|
|
761
|
-
// src/client/history-sync.ts
|
|
762
|
-
var FARM_HISTORY_CHANGE_EVENT = "farm:historychange";
|
|
763
|
-
function dispatchHistoryChange(kind) {
|
|
764
|
-
window.dispatchEvent(
|
|
765
|
-
new CustomEvent(FARM_HISTORY_CHANGE_EVENT, {
|
|
766
|
-
detail: { kind }
|
|
767
|
-
})
|
|
768
|
-
);
|
|
769
|
-
}
|
|
770
|
-
__name(dispatchHistoryChange, "dispatchHistoryChange");
|
|
771
|
-
function notifyHistoryChange(kind) {
|
|
772
|
-
if (typeof window === "undefined") return;
|
|
773
|
-
setTimeout(() => {
|
|
774
|
-
if (kind === "url-search" && !getInstalledFarmSPARouter()) {
|
|
775
|
-
window.dispatchEvent(new PopStateEvent("popstate"));
|
|
776
|
-
return;
|
|
777
|
-
}
|
|
778
|
-
dispatchHistoryChange(kind);
|
|
779
|
-
}, 0);
|
|
780
|
-
}
|
|
781
|
-
__name(notifyHistoryChange, "notifyHistoryChange");
|
|
782
|
-
function notifyRouterHistoryChange() {
|
|
783
|
-
if (typeof window === "undefined") return;
|
|
784
|
-
setTimeout(() => dispatchHistoryChange("url-search"), 0);
|
|
785
|
-
}
|
|
786
|
-
__name(notifyRouterHistoryChange, "notifyRouterHistoryChange");
|
|
787
|
-
function subscribeHistoryChange(listener) {
|
|
788
|
-
if (typeof window === "undefined") return () => {
|
|
789
|
-
};
|
|
790
|
-
window.addEventListener("popstate", listener);
|
|
791
|
-
window.addEventListener(FARM_HISTORY_CHANGE_EVENT, listener);
|
|
792
|
-
return () => {
|
|
793
|
-
window.removeEventListener("popstate", listener);
|
|
794
|
-
window.removeEventListener(FARM_HISTORY_CHANGE_EVENT, listener);
|
|
795
|
-
};
|
|
796
|
-
}
|
|
797
|
-
__name(subscribeHistoryChange, "subscribeHistoryChange");
|
|
798
24
|
|
|
799
|
-
// src/deployment.ts
|
|
800
|
-
var FARM_DEPLOYMENT_ID_HEADER = "x-farm-deployment-id";
|
|
801
|
-
var FARM_DEPLOYMENT_MISMATCH_HEADER = "x-farm-deployment-mismatch";
|
|
802
|
-
var FARM_DEPLOYMENT_MISMATCH_CODE = "FARM_DEPLOYMENT_MISMATCH";
|
|
803
|
-
var FARM_DEPLOYMENT_MISMATCH_STATUS = 409;
|
|
804
|
-
var _FarmDeploymentMismatchError = class _FarmDeploymentMismatchError extends Error {
|
|
805
|
-
constructor(clientDeploymentId, serverDeploymentId) {
|
|
806
|
-
super("The application was updated while this page was open. Refresh before trying again.");
|
|
807
|
-
this.clientDeploymentId = clientDeploymentId;
|
|
808
|
-
this.serverDeploymentId = serverDeploymentId;
|
|
809
|
-
this.name = "FarmDeploymentMismatchError";
|
|
810
|
-
this.code = FARM_DEPLOYMENT_MISMATCH_CODE;
|
|
811
|
-
this.retryable = false;
|
|
812
|
-
}
|
|
813
|
-
};
|
|
814
|
-
__name(_FarmDeploymentMismatchError, "FarmDeploymentMismatchError");
|
|
815
|
-
var FarmDeploymentMismatchError = _FarmDeploymentMismatchError;
|
|
816
|
-
function createFarmDeploymentRequestHeaders(deploymentId, init) {
|
|
817
|
-
const headers = new Headers(init);
|
|
818
|
-
if (deploymentId) {
|
|
819
|
-
headers.set(FARM_DEPLOYMENT_ID_HEADER, deploymentId);
|
|
820
|
-
}
|
|
821
|
-
return headers;
|
|
822
|
-
}
|
|
823
|
-
__name(createFarmDeploymentRequestHeaders, "createFarmDeploymentRequestHeaders");
|
|
824
|
-
function getFarmResponseDeploymentId(response) {
|
|
825
|
-
return response.headers.get(FARM_DEPLOYMENT_ID_HEADER)?.trim() || void 0;
|
|
826
|
-
}
|
|
827
|
-
__name(getFarmResponseDeploymentId, "getFarmResponseDeploymentId");
|
|
828
|
-
function isFarmDeploymentMismatchResponse(response, clientDeploymentId) {
|
|
829
|
-
const serverDeploymentId = getFarmResponseDeploymentId(response);
|
|
830
|
-
if (clientDeploymentId && serverDeploymentId && clientDeploymentId !== serverDeploymentId) {
|
|
831
|
-
return true;
|
|
832
|
-
}
|
|
833
|
-
return response.status === FARM_DEPLOYMENT_MISMATCH_STATUS && response.headers.get(FARM_DEPLOYMENT_MISMATCH_HEADER) === "1";
|
|
834
|
-
}
|
|
835
|
-
__name(isFarmDeploymentMismatchResponse, "isFarmDeploymentMismatchResponse");
|
|
836
|
-
function createFarmDeploymentMismatchError(response, clientDeploymentId) {
|
|
837
|
-
return new FarmDeploymentMismatchError(
|
|
838
|
-
clientDeploymentId,
|
|
839
|
-
getFarmResponseDeploymentId(response) || "unknown"
|
|
840
|
-
);
|
|
841
|
-
}
|
|
842
|
-
__name(createFarmDeploymentMismatchError, "createFarmDeploymentMismatchError");
|
|
843
25
|
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
decoded = decodeURIComponent(fragment);
|
|
851
|
-
} catch {
|
|
852
|
-
}
|
|
853
|
-
return document.getElementById(decoded) || document.getElementById(fragment) || document.getElementsByName(decoded)[0] || null;
|
|
854
|
-
}
|
|
855
|
-
__name(getHashTargetElement, "getHashTargetElement");
|
|
26
|
+
var _chunkOX6O6WVAcjs = require('./chunk-OX6O6WVA.cjs');
|
|
27
|
+
require('./chunk-U4KT7QP3.cjs');
|
|
28
|
+
require('./chunk-BIDYX3SL.cjs');
|
|
29
|
+
require('./chunk-I57LW5VZ.cjs');
|
|
30
|
+
require('./chunk-NO3WWW3N.cjs');
|
|
31
|
+
require('./chunk-S3JO3N4H.cjs');
|
|
856
32
|
|
|
857
|
-
// src/client/navigation-url.ts
|
|
858
|
-
function isFarmExternalNavigationURL(url, currentOrigin) {
|
|
859
|
-
return url.protocol !== "http:" && url.protocol !== "https:" || url.origin !== currentOrigin;
|
|
860
|
-
}
|
|
861
|
-
__name(isFarmExternalNavigationURL, "isFarmExternalNavigationURL");
|
|
862
|
-
function resolveFarmNavigationURL(href, documentUrl) {
|
|
863
|
-
return new URL(href, documentUrl);
|
|
864
|
-
}
|
|
865
|
-
__name(resolveFarmNavigationURL, "resolveFarmNavigationURL");
|
|
866
33
|
|
|
867
|
-
// src/agent-json-ld.ts
|
|
868
|
-
function pruneUndefined(object) {
|
|
869
|
-
const result = {};
|
|
870
|
-
for (const [key, value] of Object.entries(object)) {
|
|
871
|
-
if (value !== void 0 && value !== null && value !== "") result[key] = value;
|
|
872
|
-
}
|
|
873
|
-
return result;
|
|
874
|
-
}
|
|
875
|
-
__name(pruneUndefined, "pruneUndefined");
|
|
876
|
-
function serializeJsonLd(value) {
|
|
877
|
-
return JSON.stringify(value).replace(/</g, "\\u003c");
|
|
878
|
-
}
|
|
879
|
-
__name(serializeJsonLd, "serializeJsonLd");
|
|
880
|
-
function renderFarmAgentJsonLd(config, context) {
|
|
881
|
-
const base = pruneUndefined({
|
|
882
|
-
name: config.name ?? context.siteName ?? context.title,
|
|
883
|
-
url: config.url ?? context.metadataBase,
|
|
884
|
-
description: config.description ?? context.description,
|
|
885
|
-
logo: config.logo,
|
|
886
|
-
sameAs: config.sameAs && config.sameAs.length > 0 ? config.sameAs : void 0
|
|
887
|
-
});
|
|
888
|
-
const object = {
|
|
889
|
-
"@context": "https://schema.org",
|
|
890
|
-
"@type": config.type || "Organization",
|
|
891
|
-
...base,
|
|
892
|
-
...config.properties || {}
|
|
893
|
-
};
|
|
894
|
-
if (Object.keys(object).length <= 2 && !config.properties) {
|
|
895
|
-
return "";
|
|
896
|
-
}
|
|
897
|
-
return `<script type="application/ld+json">${serializeJsonLd(object)}</script>`;
|
|
898
|
-
}
|
|
899
|
-
__name(renderFarmAgentJsonLd, "renderFarmAgentJsonLd");
|
|
900
34
|
|
|
901
|
-
// src/metadata.ts
|
|
902
|
-
var FARM_METADATA_ATTRIBUTE = "data-farm-metadata";
|
|
903
|
-
function renderMetadataHead(metadata, options = {}) {
|
|
904
|
-
const resolvedMetadata = metadata || {};
|
|
905
|
-
const metadataBase = resolveMetadataBase(resolvedMetadata);
|
|
906
|
-
const explicitTitle = resolveMetadataTitle(resolvedMetadata.title);
|
|
907
|
-
const title = explicitTitle || "Farm.js App";
|
|
908
|
-
const tags = [];
|
|
909
|
-
appendMetaName(tags, "description", resolvedMetadata.description);
|
|
910
|
-
appendMetaName(tags, "keywords", normalizeKeywords(resolvedMetadata.keywords));
|
|
911
|
-
appendMetaName(tags, "author", resolvedMetadata.author);
|
|
912
|
-
if (Array.isArray(resolvedMetadata.authors)) {
|
|
913
|
-
for (const author of resolvedMetadata.authors) {
|
|
914
|
-
appendMetaName(tags, "author", author?.name);
|
|
915
|
-
if (author?.url) {
|
|
916
|
-
appendLink(tags, "author", resolveMetadataUrl(author.url, metadataBase));
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
}
|
|
920
|
-
appendMetaName(tags, "creator", resolvedMetadata.creator);
|
|
921
|
-
appendMetaName(tags, "publisher", resolvedMetadata.publisher);
|
|
922
|
-
appendMetaName(tags, "robots", normalizeRobots(resolvedMetadata.robots));
|
|
923
|
-
if (isRecord(resolvedMetadata.robots)) {
|
|
924
|
-
appendMetaName(tags, "googlebot", normalizeRobots(resolvedMetadata.robots.googleBot));
|
|
925
|
-
}
|
|
926
|
-
const alternates = resolvedMetadata.alternates;
|
|
927
|
-
const explicitCanonical = isRecord(alternates) ? alternates.canonical : void 0;
|
|
928
|
-
const canonicalHref = explicitCanonical != null ? resolveMetadataUrl(explicitCanonical, metadataBase) : options.pathname ? resolveMetadataUrl(sanitizeSelfCanonicalPathname(options.pathname), metadataBase) : void 0;
|
|
929
|
-
if (canonicalHref) {
|
|
930
|
-
appendLink(tags, "canonical", canonicalHref);
|
|
931
|
-
}
|
|
932
|
-
if (isRecord(alternates) && isRecord(alternates.languages)) {
|
|
933
|
-
for (const [language, href] of Object.entries(alternates.languages)) {
|
|
934
|
-
appendLink(tags, "alternate", resolveMetadataUrl(href, metadataBase), {
|
|
935
|
-
hreflang: language
|
|
936
|
-
});
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
if (isRecord(alternates) && isRecord(alternates.types)) {
|
|
940
|
-
for (const [type, value] of Object.entries(alternates.types)) {
|
|
941
|
-
for (const entry of normalizeArray(value)) {
|
|
942
|
-
const link = isRecord(entry) ? entry : { url: entry };
|
|
943
|
-
appendLink(tags, "alternate", resolveMetadataUrl(link.url, metadataBase), {
|
|
944
|
-
type,
|
|
945
|
-
title: link.title
|
|
946
|
-
});
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
const hasFavicon = appendIcons(tags, resolvedMetadata.icons, metadataBase);
|
|
951
|
-
if (resolvedMetadata.manifest) {
|
|
952
|
-
appendLink(
|
|
953
|
-
tags,
|
|
954
|
-
"manifest",
|
|
955
|
-
resolveMetadataUrl(resolvedMetadata.manifest, metadataBase)
|
|
956
|
-
);
|
|
957
|
-
}
|
|
958
|
-
appendNamedMetaRecord(tags, resolvedMetadata.other);
|
|
959
|
-
appendOpenGraph(tags, resolvedMetadata.openGraph, metadataBase);
|
|
960
|
-
appendTwitter(tags, resolvedMetadata.twitter, metadataBase);
|
|
961
|
-
appendVerification(tags, resolvedMetadata.verification);
|
|
962
|
-
if (options.jsonLd) {
|
|
963
|
-
const jsonLdConfig = options.jsonLd === true ? {} : options.jsonLd;
|
|
964
|
-
const jsonLdScript = renderFarmAgentJsonLd(jsonLdConfig, {
|
|
965
|
-
metadataBase,
|
|
966
|
-
siteName: isRecord(resolvedMetadata.openGraph) ? normalizeContent(resolvedMetadata.openGraph.siteName) : void 0,
|
|
967
|
-
title: explicitTitle,
|
|
968
|
-
description: normalizeContent(resolvedMetadata.description)
|
|
969
|
-
});
|
|
970
|
-
if (jsonLdScript) tags.push(jsonLdScript);
|
|
971
|
-
}
|
|
972
|
-
for (const entry of normalizeArray(resolvedMetadata.jsonLd)) {
|
|
973
|
-
if (!isRecord(entry)) continue;
|
|
974
|
-
tags.push(
|
|
975
|
-
`<script type="application/ld+json" ${FARM_METADATA_ATTRIBUTE}>${serializeJsonLd(entry)}</script>`
|
|
976
|
-
);
|
|
977
|
-
}
|
|
978
|
-
return {
|
|
979
|
-
title: escapeText(title),
|
|
980
|
-
tags: tags.length > 0 ? `
|
|
981
|
-
${tags.join("\n ")}` : "",
|
|
982
|
-
hasFavicon,
|
|
983
|
-
hasExplicitTitle: Boolean(explicitTitle)
|
|
984
|
-
};
|
|
985
|
-
}
|
|
986
|
-
__name(renderMetadataHead, "renderMetadataHead");
|
|
987
|
-
function appendOpenGraph(tags, openGraph, metadataBase) {
|
|
988
|
-
if (!isRecord(openGraph)) return;
|
|
989
|
-
appendMetaProperty(tags, "og:title", openGraph.title);
|
|
990
|
-
appendMetaProperty(tags, "og:description", openGraph.description);
|
|
991
|
-
appendMetaProperty(tags, "og:url", resolveMetadataUrl(openGraph.url, metadataBase));
|
|
992
|
-
appendMetaProperty(tags, "og:site_name", openGraph.siteName);
|
|
993
|
-
appendMetaProperty(tags, "og:type", openGraph.type ?? "website");
|
|
994
|
-
appendMetaProperty(tags, "og:locale", openGraph.locale);
|
|
995
|
-
const images = normalizeMetadataImages(
|
|
996
|
-
openGraph.images ?? openGraph.image,
|
|
997
|
-
metadataBase
|
|
998
|
-
);
|
|
999
|
-
for (const image of images) {
|
|
1000
|
-
appendMetaProperty(tags, "og:image", image.url);
|
|
1001
|
-
appendMetaProperty(tags, "og:image:width", image.width);
|
|
1002
|
-
appendMetaProperty(tags, "og:image:height", image.height);
|
|
1003
|
-
appendMetaProperty(tags, "og:image:alt", image.alt);
|
|
1004
|
-
appendMetaProperty(tags, "og:image:type", image.type);
|
|
1005
|
-
}
|
|
1006
|
-
if (openGraph.type === "article") {
|
|
1007
|
-
appendMetaProperty(tags, "article:published_time", normalizeDate(openGraph.publishedTime));
|
|
1008
|
-
appendMetaProperty(tags, "article:modified_time", normalizeDate(openGraph.modifiedTime));
|
|
1009
|
-
for (const author of normalizeArray(openGraph.authors)) {
|
|
1010
|
-
appendMetaProperty(tags, "article:author", author);
|
|
1011
|
-
}
|
|
1012
|
-
appendMetaProperty(tags, "article:section", openGraph.section);
|
|
1013
|
-
for (const tag of normalizeArray(openGraph.tags)) {
|
|
1014
|
-
appendMetaProperty(tags, "article:tag", tag);
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
__name(appendOpenGraph, "appendOpenGraph");
|
|
1019
|
-
function appendTwitter(tags, twitter, metadataBase) {
|
|
1020
|
-
if (!isRecord(twitter)) return;
|
|
1021
|
-
appendMetaName(tags, "twitter:card", twitter.card);
|
|
1022
|
-
appendMetaName(tags, "twitter:site", twitter.site);
|
|
1023
|
-
appendMetaName(tags, "twitter:creator", twitter.creator);
|
|
1024
|
-
appendMetaName(tags, "twitter:title", twitter.title);
|
|
1025
|
-
appendMetaName(tags, "twitter:description", twitter.description);
|
|
1026
|
-
for (const image of normalizeMetadataImages(twitter.images, metadataBase)) {
|
|
1027
|
-
appendMetaName(tags, "twitter:image", image.url);
|
|
1028
|
-
appendMetaName(tags, "twitter:image:alt", image.alt);
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
__name(appendTwitter, "appendTwitter");
|
|
1032
|
-
function appendNamedMetaRecord(tags, record) {
|
|
1033
|
-
if (!isRecord(record)) return;
|
|
1034
|
-
for (const [name, value] of Object.entries(record)) {
|
|
1035
|
-
for (const content of normalizeArray(value)) {
|
|
1036
|
-
appendMetaName(tags, name, content, true);
|
|
1037
|
-
}
|
|
1038
|
-
}
|
|
1039
|
-
}
|
|
1040
|
-
__name(appendNamedMetaRecord, "appendNamedMetaRecord");
|
|
1041
|
-
function appendIcons(tags, icons, metadataBase) {
|
|
1042
|
-
if (!icons) return false;
|
|
1043
|
-
if (typeof icons === "string") {
|
|
1044
|
-
const initialTagCount2 = tags.length;
|
|
1045
|
-
appendLink(tags, "icon", resolveMetadataUrl(icons, metadataBase));
|
|
1046
|
-
return tags.length > initialTagCount2;
|
|
1047
|
-
}
|
|
1048
|
-
if (!isRecord(icons)) return false;
|
|
1049
|
-
const initialTagCount = tags.length;
|
|
1050
|
-
appendIconList(tags, "icon", icons.icon, metadataBase);
|
|
1051
|
-
appendIconList(tags, "shortcut icon", icons.shortcut, metadataBase);
|
|
1052
|
-
const hasFavicon = tags.length > initialTagCount;
|
|
1053
|
-
appendIconList(tags, "apple-touch-icon", icons.apple, metadataBase);
|
|
1054
|
-
return hasFavicon;
|
|
1055
|
-
}
|
|
1056
|
-
__name(appendIcons, "appendIcons");
|
|
1057
|
-
function appendIconList(tags, rel, value, metadataBase) {
|
|
1058
|
-
for (const icon of normalizeArray(value)) {
|
|
1059
|
-
if (typeof icon === "string") {
|
|
1060
|
-
appendLink(tags, rel, resolveMetadataUrl(icon, metadataBase));
|
|
1061
|
-
continue;
|
|
1062
|
-
}
|
|
1063
|
-
if (!isRecord(icon)) continue;
|
|
1064
|
-
appendLink(tags, rel, resolveMetadataUrl(icon.url, metadataBase), {
|
|
1065
|
-
sizes: icon.sizes,
|
|
1066
|
-
type: icon.type
|
|
1067
|
-
});
|
|
1068
|
-
}
|
|
1069
|
-
}
|
|
1070
|
-
__name(appendIconList, "appendIconList");
|
|
1071
|
-
function appendMetaName(tags, name, content, marked = false) {
|
|
1072
|
-
const normalized = normalizeContent(content);
|
|
1073
|
-
if (!normalized || !name) return;
|
|
1074
|
-
const marker = marked ? ` ${FARM_METADATA_ATTRIBUTE}` : "";
|
|
1075
|
-
tags.push(
|
|
1076
|
-
`<meta name="${escapeAttribute(name)}" content="${escapeAttribute(normalized)}"${marker}>`
|
|
1077
|
-
);
|
|
1078
|
-
}
|
|
1079
|
-
__name(appendMetaName, "appendMetaName");
|
|
1080
|
-
function appendMetaProperty(tags, property, content) {
|
|
1081
|
-
const normalized = normalizeContent(content);
|
|
1082
|
-
if (!normalized) return;
|
|
1083
|
-
tags.push(
|
|
1084
|
-
`<meta property="${escapeAttribute(property)}" content="${escapeAttribute(normalized)}">`
|
|
1085
|
-
);
|
|
1086
|
-
}
|
|
1087
|
-
__name(appendMetaProperty, "appendMetaProperty");
|
|
1088
|
-
var VERIFICATION_META_NAMES = [
|
|
1089
|
-
["google", "google-site-verification"],
|
|
1090
|
-
["bing", "msvalidate.01"],
|
|
1091
|
-
["yandex", "yandex-verification"]
|
|
1092
|
-
];
|
|
1093
|
-
function appendVerification(tags, verification) {
|
|
1094
|
-
if (!isRecord(verification)) return;
|
|
1095
|
-
for (const [key, name] of VERIFICATION_META_NAMES) {
|
|
1096
|
-
for (const token of normalizeArray(verification[key])) {
|
|
1097
|
-
appendMetaName(tags, name, token);
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1100
|
-
appendNamedMetaRecord(tags, verification.other);
|
|
1101
|
-
}
|
|
1102
|
-
__name(appendVerification, "appendVerification");
|
|
1103
|
-
function appendLink(tags, rel, href, attrs = {}) {
|
|
1104
|
-
const normalizedHref = normalizeContent(href);
|
|
1105
|
-
if (!normalizedHref) return;
|
|
1106
|
-
const attrText = Object.entries(attrs).map(([key, value]) => {
|
|
1107
|
-
const normalized = normalizeContent(value);
|
|
1108
|
-
return normalized ? ` ${key}="${escapeAttribute(normalized)}"` : "";
|
|
1109
|
-
}).join("");
|
|
1110
|
-
tags.push(
|
|
1111
|
-
`<link rel="${escapeAttribute(rel)}" href="${escapeAttribute(normalizedHref)}"${attrText}>`
|
|
1112
|
-
);
|
|
1113
|
-
}
|
|
1114
|
-
__name(appendLink, "appendLink");
|
|
1115
|
-
function normalizeMetadataImages(value, metadataBase) {
|
|
1116
|
-
return normalizeArray(value).map((item) => {
|
|
1117
|
-
if (typeof item === "string") {
|
|
1118
|
-
return { url: resolveMetadataUrl(item, metadataBase) || item };
|
|
1119
|
-
}
|
|
1120
|
-
if (!isRecord(item)) return null;
|
|
1121
|
-
const rawUrl = item.url || item.src;
|
|
1122
|
-
const url = resolveMetadataUrl(rawUrl, metadataBase);
|
|
1123
|
-
if (!url) return null;
|
|
1124
|
-
return {
|
|
1125
|
-
url,
|
|
1126
|
-
width: normalizeNumber(item.width),
|
|
1127
|
-
height: normalizeNumber(item.height),
|
|
1128
|
-
alt: typeof item.alt === "string" ? item.alt : void 0,
|
|
1129
|
-
type: typeof item.type === "string" ? item.type : void 0
|
|
1130
|
-
};
|
|
1131
|
-
}).filter((item) => item !== null);
|
|
1132
|
-
}
|
|
1133
|
-
__name(normalizeMetadataImages, "normalizeMetadataImages");
|
|
1134
|
-
function normalizeArray(value) {
|
|
1135
|
-
if (value == null) return [];
|
|
1136
|
-
return Array.isArray(value) ? value : [value];
|
|
1137
|
-
}
|
|
1138
|
-
__name(normalizeArray, "normalizeArray");
|
|
1139
|
-
function resolveMetadataTitle(title) {
|
|
1140
|
-
if (typeof title === "string") return title;
|
|
1141
|
-
if (isRecord(title)) {
|
|
1142
|
-
return normalizeContent(title.default);
|
|
1143
|
-
}
|
|
1144
|
-
return void 0;
|
|
1145
|
-
}
|
|
1146
|
-
__name(resolveMetadataTitle, "resolveMetadataTitle");
|
|
1147
|
-
function normalizeKeywords(keywords) {
|
|
1148
|
-
if (Array.isArray(keywords)) return keywords.filter(Boolean).join(", ");
|
|
1149
|
-
return keywords;
|
|
1150
|
-
}
|
|
1151
|
-
__name(normalizeKeywords, "normalizeKeywords");
|
|
1152
|
-
var ROBOTS_FLAGS = ["noarchive", "nosnippet", "noimageindex"];
|
|
1153
|
-
var ROBOTS_VALUES = [
|
|
1154
|
-
"max-snippet",
|
|
1155
|
-
"max-image-preview",
|
|
1156
|
-
"max-video-preview",
|
|
1157
|
-
"unavailable_after"
|
|
1158
|
-
];
|
|
1159
|
-
function normalizeRobots(robots) {
|
|
1160
|
-
if (typeof robots === "string") return robots;
|
|
1161
|
-
if (!isRecord(robots)) return void 0;
|
|
1162
|
-
const values = [];
|
|
1163
|
-
if (typeof robots.index === "boolean") values.push(robots.index ? "index" : "noindex");
|
|
1164
|
-
if (typeof robots.follow === "boolean") values.push(robots.follow ? "follow" : "nofollow");
|
|
1165
|
-
for (const flag of ROBOTS_FLAGS) {
|
|
1166
|
-
if (robots[flag] === true) values.push(flag);
|
|
1167
|
-
}
|
|
1168
|
-
for (const directive of ROBOTS_VALUES) {
|
|
1169
|
-
const value = normalizeContent(robots[directive]);
|
|
1170
|
-
if (value) values.push(`${directive}:${value}`);
|
|
1171
|
-
}
|
|
1172
|
-
return values.join(", ") || void 0;
|
|
1173
|
-
}
|
|
1174
|
-
__name(normalizeRobots, "normalizeRobots");
|
|
1175
|
-
function resolveMetadataBase(metadata) {
|
|
1176
|
-
const base = metadata.metadataBase;
|
|
1177
|
-
if (!base) return void 0;
|
|
1178
|
-
return String(base);
|
|
1179
|
-
}
|
|
1180
|
-
__name(resolveMetadataBase, "resolveMetadataBase");
|
|
1181
|
-
function sanitizeSelfCanonicalPathname(pathname) {
|
|
1182
|
-
if (typeof pathname !== "string" || pathname.length === 0) return "/";
|
|
1183
|
-
const collapsed = pathname.replace(/^[/\\]+/, "/");
|
|
1184
|
-
return collapsed.startsWith("/") ? collapsed : `/${collapsed}`;
|
|
1185
|
-
}
|
|
1186
|
-
__name(sanitizeSelfCanonicalPathname, "sanitizeSelfCanonicalPathname");
|
|
1187
|
-
function resolveMetadataUrl(value, metadataBase) {
|
|
1188
|
-
const normalized = normalizeContent(value);
|
|
1189
|
-
if (!normalized) return void 0;
|
|
1190
|
-
if (!metadataBase) return normalized;
|
|
1191
|
-
try {
|
|
1192
|
-
return new URL(normalized, metadataBase).toString();
|
|
1193
|
-
} catch {
|
|
1194
|
-
return normalized;
|
|
1195
|
-
}
|
|
1196
|
-
}
|
|
1197
|
-
__name(resolveMetadataUrl, "resolveMetadataUrl");
|
|
1198
|
-
function normalizeNumber(value) {
|
|
1199
|
-
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
1200
|
-
if (typeof value === "string") {
|
|
1201
|
-
const parsed = Number(value);
|
|
1202
|
-
return Number.isFinite(parsed) ? parsed : void 0;
|
|
1203
|
-
}
|
|
1204
|
-
return void 0;
|
|
1205
|
-
}
|
|
1206
|
-
__name(normalizeNumber, "normalizeNumber");
|
|
1207
|
-
function normalizeDate(value) {
|
|
1208
|
-
if (value instanceof Date) {
|
|
1209
|
-
return Number.isNaN(value.getTime()) ? void 0 : value.toISOString();
|
|
1210
|
-
}
|
|
1211
|
-
return normalizeContent(value);
|
|
1212
|
-
}
|
|
1213
|
-
__name(normalizeDate, "normalizeDate");
|
|
1214
|
-
function normalizeContent(value) {
|
|
1215
|
-
if (value == null) return void 0;
|
|
1216
|
-
if (typeof value === "string") return value;
|
|
1217
|
-
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
1218
|
-
if (value instanceof URL) return value.toString();
|
|
1219
|
-
return void 0;
|
|
1220
|
-
}
|
|
1221
|
-
__name(normalizeContent, "normalizeContent");
|
|
1222
|
-
function isRecord(value) {
|
|
1223
|
-
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
1224
|
-
}
|
|
1225
|
-
__name(isRecord, "isRecord");
|
|
1226
|
-
function escapeText(value) {
|
|
1227
|
-
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
1228
|
-
}
|
|
1229
|
-
__name(escapeText, "escapeText");
|
|
1230
|
-
function escapeAttribute(value) {
|
|
1231
|
-
return escapeText(value).replace(/"/g, """);
|
|
1232
|
-
}
|
|
1233
|
-
__name(escapeAttribute, "escapeAttribute");
|
|
1234
35
|
|
|
1235
|
-
// src/client/metadata-reconciler.ts
|
|
1236
|
-
var MANAGED_ATTRIBUTE = FARM_METADATA_ATTRIBUTE;
|
|
1237
|
-
var OWNED_SELECTORS = [
|
|
1238
|
-
'meta[name="description"]',
|
|
1239
|
-
'meta[name="keywords"]',
|
|
1240
|
-
'meta[name="author"]',
|
|
1241
|
-
'meta[name="google-site-verification"]',
|
|
1242
|
-
'meta[name="msvalidate.01"]',
|
|
1243
|
-
'meta[name="yandex-verification"]',
|
|
1244
|
-
'meta[name="creator"]',
|
|
1245
|
-
'meta[name="publisher"]',
|
|
1246
|
-
'meta[name="robots"]',
|
|
1247
|
-
'meta[name="googlebot"]',
|
|
1248
|
-
'link[rel="author"]',
|
|
1249
|
-
'link[rel="canonical"]',
|
|
1250
|
-
'link[rel="alternate"]',
|
|
1251
|
-
'meta[property^="og:"]',
|
|
1252
|
-
'meta[property^="article:"]',
|
|
1253
|
-
'meta[name^="twitter:"]',
|
|
1254
|
-
// Meta tags named by the app carry the marker, since no fixed name matches them.
|
|
1255
|
-
`meta[${MANAGED_ATTRIBUTE}]`
|
|
1256
|
-
].join(", ");
|
|
1257
|
-
var ICON_SELECTORS = [
|
|
1258
|
-
'link[rel="icon"]',
|
|
1259
|
-
'link[rel="shortcut icon"]',
|
|
1260
|
-
'link[rel="apple-touch-icon"]'
|
|
1261
|
-
].join(", ");
|
|
1262
|
-
var MANIFEST_SELECTOR = 'link[rel="manifest"]';
|
|
1263
|
-
var PAGE_JSON_LD_SELECTOR = `script[type="application/ld+json"][${MANAGED_ATTRIBUTE}]`;
|
|
1264
|
-
function removeAll(selector) {
|
|
1265
|
-
for (const element of Array.from(document.head.querySelectorAll(selector))) {
|
|
1266
|
-
element.remove();
|
|
1267
|
-
}
|
|
1268
|
-
}
|
|
1269
|
-
__name(removeAll, "removeAll");
|
|
1270
|
-
function applyFarmMetadataToDocument(metadata, pathname) {
|
|
1271
|
-
document.title = resolveMetadataTitle(metadata?.title) || "Farm.js App";
|
|
1272
|
-
const rendered = renderMetadataHead(metadata, { pathname });
|
|
1273
|
-
const template = document.createElement("template");
|
|
1274
|
-
template.innerHTML = rendered.tags;
|
|
1275
|
-
removeAll(OWNED_SELECTORS);
|
|
1276
|
-
removeAll(PAGE_JSON_LD_SELECTOR);
|
|
1277
|
-
if (metadata?.icons) removeAll(ICON_SELECTORS);
|
|
1278
|
-
if (metadata?.manifest) removeAll(MANIFEST_SELECTOR);
|
|
1279
|
-
for (const element of Array.from(template.content.children)) {
|
|
1280
|
-
element.setAttribute(MANAGED_ATTRIBUTE, "");
|
|
1281
|
-
document.head.appendChild(element);
|
|
1282
|
-
}
|
|
1283
|
-
}
|
|
1284
|
-
__name(applyFarmMetadataToDocument, "applyFarmMetadataToDocument");
|
|
1285
36
|
|
|
1286
|
-
// src/i18n/bridge.ts
|
|
1287
|
-
var FARM_I18N_SNAPSHOT_RESOLVER = /* @__PURE__ */ Symbol.for("farm.i18n.snapshotResolver");
|
|
1288
|
-
function getActiveFarmI18nSnapshot() {
|
|
1289
|
-
if (typeof window !== "undefined" && window.__FARM_I18N__) {
|
|
1290
|
-
return window.__FARM_I18N__;
|
|
1291
|
-
}
|
|
1292
|
-
return globalThis[FARM_I18N_SNAPSHOT_RESOLVER]?.();
|
|
1293
|
-
}
|
|
1294
|
-
__name(getActiveFarmI18nSnapshot, "getActiveFarmI18nSnapshot");
|
|
1295
37
|
|
|
1296
|
-
// src/base-path.ts
|
|
1297
|
-
var FARM_BASE_PATH = /* @__PURE__ */ Symbol.for("farm.basePath");
|
|
1298
|
-
function getFarmGlobalState() {
|
|
1299
|
-
return globalThis;
|
|
1300
|
-
}
|
|
1301
|
-
__name(getFarmGlobalState, "getFarmGlobalState");
|
|
1302
|
-
function getFarmBasePath() {
|
|
1303
|
-
return getFarmGlobalState()[FARM_BASE_PATH] ?? "";
|
|
1304
|
-
}
|
|
1305
|
-
__name(getFarmBasePath, "getFarmBasePath");
|
|
1306
|
-
function applyFarmBasePath(href, basePath = getFarmBasePath()) {
|
|
1307
|
-
const normalizedBasePath = normalizeFarmBasePath(basePath);
|
|
1308
|
-
if (!normalizedBasePath || !href.startsWith("/") || href.startsWith("//")) return href;
|
|
1309
|
-
const canonicalHref = canonicalizeAppRelativeHref(href);
|
|
1310
|
-
if (canonicalHref === normalizedBasePath || canonicalHref.startsWith(`${normalizedBasePath}/`) || canonicalHref.startsWith(`${normalizedBasePath}?`) || canonicalHref.startsWith(`${normalizedBasePath}#`)) {
|
|
1311
|
-
return canonicalHref;
|
|
1312
|
-
}
|
|
1313
|
-
return `${normalizedBasePath}${canonicalHref}`;
|
|
1314
|
-
}
|
|
1315
|
-
__name(applyFarmBasePath, "applyFarmBasePath");
|
|
1316
|
-
function canonicalizeAppRelativeHref(href) {
|
|
1317
|
-
const origin = "http://farm.local";
|
|
1318
|
-
const resolved = new URL(href, origin);
|
|
1319
|
-
if (resolved.origin !== origin) {
|
|
1320
|
-
throw new Error("Farm app-relative href cannot change the URL origin.");
|
|
1321
|
-
}
|
|
1322
|
-
return `${resolved.pathname}${resolved.search}${resolved.hash}`;
|
|
1323
|
-
}
|
|
1324
|
-
__name(canonicalizeAppRelativeHref, "canonicalizeAppRelativeHref");
|
|
1325
|
-
function stripFarmBasePath(pathname, basePath = getFarmBasePath()) {
|
|
1326
|
-
const normalizedBasePath = normalizeFarmBasePath(basePath);
|
|
1327
|
-
if (!normalizedBasePath) return pathname || "/";
|
|
1328
|
-
if (pathname === normalizedBasePath) return "/";
|
|
1329
|
-
if (!pathname.startsWith(`${normalizedBasePath}/`)) return pathname || "/";
|
|
1330
|
-
return pathname.slice(normalizedBasePath.length) || "/";
|
|
1331
|
-
}
|
|
1332
|
-
__name(stripFarmBasePath, "stripFarmBasePath");
|
|
1333
|
-
function normalizeFarmBasePath(basePath) {
|
|
1334
|
-
if (!basePath || basePath === "/") return "";
|
|
1335
|
-
const hasUnstableCharacters = /* @__PURE__ */ __name((candidate) => candidate.includes("\\") || Array.from(candidate).some((character) => {
|
|
1336
|
-
const code = character.charCodeAt(0);
|
|
1337
|
-
return code <= 31 || code >= 127 && code <= 159;
|
|
1338
|
-
}), "hasUnstableCharacters");
|
|
1339
|
-
if (hasUnstableCharacters(basePath)) {
|
|
1340
|
-
throw new Error("Farm basePath cannot contain backslashes or control characters.");
|
|
1341
|
-
}
|
|
1342
|
-
const pathname = basePath.trim();
|
|
1343
|
-
if (!pathname || pathname === "/") return "";
|
|
1344
|
-
if (pathname.includes("?") || pathname.includes("#")) {
|
|
1345
|
-
throw new Error("Farm basePath cannot contain a query string or hash.");
|
|
1346
|
-
}
|
|
1347
|
-
if (pathname.startsWith("//") || /^[a-z][a-z\d+.-]*:\/\//i.test(pathname)) {
|
|
1348
|
-
throw new Error('Farm basePath must be a pathname such as "/docs", not a URL.');
|
|
1349
|
-
}
|
|
1350
|
-
for (const segment of pathname.split("/")) {
|
|
1351
|
-
let decoded = segment;
|
|
1352
|
-
try {
|
|
1353
|
-
decoded = decodeURIComponent(segment);
|
|
1354
|
-
} catch {
|
|
1355
|
-
}
|
|
1356
|
-
if (hasUnstableCharacters(decoded)) {
|
|
1357
|
-
throw new Error("Farm basePath cannot contain backslashes or control characters.");
|
|
1358
|
-
}
|
|
1359
|
-
if (decoded.includes("/")) {
|
|
1360
|
-
throw new Error("Farm basePath cannot contain percent-encoded path separators.");
|
|
1361
|
-
}
|
|
1362
|
-
if (decoded === "." || decoded === "..") {
|
|
1363
|
-
throw new Error('Farm basePath cannot contain "." or ".." path segments.');
|
|
1364
|
-
}
|
|
1365
|
-
}
|
|
1366
|
-
return `/${pathname}`.replace(/\/{2,}/g, "/").replace(/\/+$/, "");
|
|
1367
|
-
}
|
|
1368
|
-
__name(normalizeFarmBasePath, "normalizeFarmBasePath");
|
|
1369
38
|
|
|
1370
|
-
// src/i18n/routing.ts
|
|
1371
|
-
function resolveFarmLocalePath(pathname, config) {
|
|
1372
|
-
const normalized = normalizePathname2(stripFarmBasePath(pathname, config.basePath));
|
|
1373
|
-
if (config.routing === "none") {
|
|
1374
|
-
return { pathname: normalized, explicit: false };
|
|
1375
|
-
}
|
|
1376
|
-
const segments = normalized.split("/").filter(Boolean);
|
|
1377
|
-
const firstSegment = segments[0];
|
|
1378
|
-
const locale = config.locales.find(
|
|
1379
|
-
(candidate) => candidate.toLowerCase() === firstSegment?.toLowerCase()
|
|
1380
|
-
);
|
|
1381
|
-
if (!locale) {
|
|
1382
|
-
return { pathname: normalized, explicit: false };
|
|
1383
|
-
}
|
|
1384
|
-
const remaining = segments.slice(1);
|
|
1385
|
-
return {
|
|
1386
|
-
locale,
|
|
1387
|
-
pathname: remaining.length > 0 ? `/${remaining.join("/")}` : "/",
|
|
1388
|
-
explicit: true
|
|
1389
|
-
};
|
|
1390
|
-
}
|
|
1391
|
-
__name(resolveFarmLocalePath, "resolveFarmLocalePath");
|
|
1392
|
-
function stripFarmLocaleFromPathname(pathname, config) {
|
|
1393
|
-
return resolveFarmLocalePath(pathname, config).pathname;
|
|
1394
|
-
}
|
|
1395
|
-
__name(stripFarmLocaleFromPathname, "stripFarmLocaleFromPathname");
|
|
1396
|
-
function normalizePathname2(pathname) {
|
|
1397
|
-
const withLeadingSlash = pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
1398
|
-
if (withLeadingSlash === "/") return "/";
|
|
1399
|
-
return withLeadingSlash.replace(/\/{2,}/g, "/").replace(/\/$/, "") || "/";
|
|
1400
|
-
}
|
|
1401
|
-
__name(normalizePathname2, "normalizePathname");
|
|
1402
39
|
|
|
1403
|
-
// src/i18n/client-state.ts
|
|
1404
|
-
var listeners = /* @__PURE__ */ new Set();
|
|
1405
|
-
var compiledFarmI18nMessages = /* @__PURE__ */ new Map();
|
|
1406
|
-
var currentSnapshot;
|
|
1407
|
-
function getFarmI18nClientState() {
|
|
1408
|
-
return currentSnapshot || getActiveFarmI18nSnapshot();
|
|
1409
|
-
}
|
|
1410
|
-
__name(getFarmI18nClientState, "getFarmI18nClientState");
|
|
1411
|
-
function _hydrateFarmI18n(snapshot) {
|
|
1412
|
-
if (!snapshot) return;
|
|
1413
|
-
const changed = currentSnapshot?.locale !== snapshot.locale;
|
|
1414
|
-
currentSnapshot = snapshot;
|
|
1415
|
-
if (typeof window !== "undefined") window.__FARM_I18N__ = snapshot;
|
|
1416
|
-
if (typeof document !== "undefined") {
|
|
1417
|
-
document.documentElement.lang = snapshot.locale;
|
|
1418
|
-
document.documentElement.dir = snapshot.direction;
|
|
1419
|
-
}
|
|
1420
|
-
if (changed) compiledFarmI18nMessages.clear();
|
|
1421
|
-
for (const listener of listeners) listener();
|
|
1422
|
-
}
|
|
1423
|
-
__name(_hydrateFarmI18n, "_hydrateFarmI18n");
|
|
1424
|
-
function isFarmLocaleChangeHref(href) {
|
|
1425
|
-
const snapshot = getFarmI18nClientState();
|
|
1426
|
-
if (!snapshot || typeof window === "undefined") return false;
|
|
1427
|
-
if (snapshot.routing === "none") return false;
|
|
1428
|
-
const target = resolveFarmNavigationURL(href, window.location.href);
|
|
1429
|
-
const match = resolveFarmLocalePath(target.pathname, snapshot);
|
|
1430
|
-
const targetLocale = match.locale || snapshot.defaultLocale;
|
|
1431
|
-
return targetLocale !== snapshot.locale;
|
|
1432
|
-
}
|
|
1433
|
-
__name(isFarmLocaleChangeHref, "isFarmLocaleChangeHref");
|
|
1434
40
|
|
|
1435
|
-
// src/client/spa-router.ts
|
|
1436
|
-
var MAX_CONCURRENT_VIEWPORT_PREFETCHES = 4;
|
|
1437
|
-
var FARM_PAGE_STATE_KEY = "__farmPageState";
|
|
1438
|
-
var FARM_INTERCEPT_FROM_KEY = "__farmInterceptFrom";
|
|
1439
|
-
var FARM_HISTORY_INDEX_KEY = "__farmHistoryIndex";
|
|
1440
|
-
function readHistoryIndex(state) {
|
|
1441
|
-
if (!state || typeof state !== "object") return null;
|
|
1442
|
-
const value = state[FARM_HISTORY_INDEX_KEY];
|
|
1443
|
-
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
1444
|
-
}
|
|
1445
|
-
__name(readHistoryIndex, "readHistoryIndex");
|
|
1446
|
-
var IDLE_NAVIGATION_STATE = {
|
|
1447
|
-
state: "idle",
|
|
1448
|
-
pending: false,
|
|
1449
|
-
from: null,
|
|
1450
|
-
to: null,
|
|
1451
|
-
action: null,
|
|
1452
|
-
startedAt: null
|
|
1453
|
-
};
|
|
1454
|
-
function getActiveLayoutChainHeader() {
|
|
1455
|
-
if (typeof document === "undefined") return void 0;
|
|
1456
|
-
const patterns = Array.from(
|
|
1457
|
-
document.querySelectorAll('[data-farm-layout-boundary="true"]')
|
|
1458
|
-
).map((element) => element.dataset.farmLayoutPattern).filter((pattern) => Boolean(pattern));
|
|
1459
|
-
return patterns.length > 0 ? JSON.stringify(patterns) : void 0;
|
|
1460
|
-
}
|
|
1461
|
-
__name(getActiveLayoutChainHeader, "getActiveLayoutChainHeader");
|
|
1462
|
-
var routerInstance = null;
|
|
1463
|
-
var _SPARouter = class _SPARouter {
|
|
1464
|
-
constructor(options = {}) {
|
|
1465
|
-
this.cache = /* @__PURE__ */ new Map();
|
|
1466
|
-
this.prefetchingUrls = /* @__PURE__ */ new Set();
|
|
1467
|
-
this.pendingPrefetches = /* @__PURE__ */ new Map();
|
|
1468
|
-
this.cacheGeneration = 0;
|
|
1469
|
-
this.observedPrefetchLinks = /* @__PURE__ */ new Map();
|
|
1470
|
-
this.prefetchTimers = /* @__PURE__ */ new Map();
|
|
1471
|
-
this.viewportPrefetchQueue = [];
|
|
1472
|
-
this.viewportPrefetchTasksByHref = /* @__PURE__ */ new Map();
|
|
1473
|
-
this.viewportPrefetchTasksByElement = /* @__PURE__ */ new Map();
|
|
1474
|
-
this.activeViewportPrefetches = 0;
|
|
1475
|
-
this.destroyed = false;
|
|
1476
|
-
this.blockers = /* @__PURE__ */ new Set();
|
|
1477
|
-
this.unloadBlockers = /* @__PURE__ */ new Map();
|
|
1478
|
-
this.navigationListeners = /* @__PURE__ */ new Set();
|
|
1479
|
-
this.navigationState = IDLE_NAVIGATION_STATE;
|
|
1480
|
-
this.currentHistoryPath = null;
|
|
1481
|
-
this.currentHistoryHash = "";
|
|
1482
|
-
this.currentHistoryIndex = null;
|
|
1483
|
-
this.suppressNextPopState = false;
|
|
1484
|
-
this.navigationSequence = 0;
|
|
1485
|
-
this.scrollElements = /* @__PURE__ */ new Map();
|
|
1486
|
-
this.onPopState = /* @__PURE__ */ __name((event) => {
|
|
1487
|
-
void this.handlePopState(event);
|
|
1488
|
-
}, "onPopState");
|
|
1489
|
-
this.onBeforeUnload = /* @__PURE__ */ __name((event) => {
|
|
1490
|
-
if (this.shouldBlockUnload()) {
|
|
1491
|
-
event.preventDefault();
|
|
1492
|
-
event.returnValue = "";
|
|
1493
|
-
}
|
|
1494
|
-
this.saveScrollPosition(window.location.pathname + window.location.search);
|
|
1495
|
-
}, "onBeforeUnload");
|
|
1496
|
-
this.options = {
|
|
1497
|
-
prefetchTimeout: options.prefetchTimeout ?? 100,
|
|
1498
|
-
cacheMaxAge: options.cacheMaxAge ?? 3e4,
|
|
1499
|
-
// 30 seconds
|
|
1500
|
-
scrollRestoration: options.scrollRestoration ?? true,
|
|
1501
|
-
shouldUseDocumentNavigation: options.shouldUseDocumentNavigation ?? (() => false),
|
|
1502
|
-
deploymentId: options.deploymentId ?? readBrowserDeploymentId()
|
|
1503
|
-
};
|
|
1504
|
-
if (typeof window !== "undefined") {
|
|
1505
|
-
window.addEventListener("popstate", this.onPopState);
|
|
1506
|
-
window.addEventListener("beforeunload", this.onBeforeUnload);
|
|
1507
|
-
this.currentHistoryPath = window.location.pathname + window.location.search;
|
|
1508
|
-
this.currentHistoryHash = window.location.hash;
|
|
1509
|
-
this.currentInterceptFrom = window.history.state?.[FARM_INTERCEPT_FROM_KEY];
|
|
1510
|
-
const existingIndex = readHistoryIndex(window.history.state);
|
|
1511
|
-
if (existingIndex == null) {
|
|
1512
|
-
try {
|
|
1513
|
-
window.history.replaceState(
|
|
1514
|
-
{
|
|
1515
|
-
...window.history.state ?? {},
|
|
1516
|
-
[FARM_HISTORY_INDEX_KEY]: 0
|
|
1517
|
-
},
|
|
1518
|
-
"",
|
|
1519
|
-
window.location.href
|
|
1520
|
-
);
|
|
1521
|
-
this.currentHistoryIndex = 0;
|
|
1522
|
-
} catch {
|
|
1523
|
-
this.currentHistoryIndex = null;
|
|
1524
|
-
}
|
|
1525
|
-
} else {
|
|
1526
|
-
this.currentHistoryIndex = existingIndex;
|
|
1527
|
-
}
|
|
1528
|
-
}
|
|
1529
|
-
}
|
|
1530
|
-
/** Remove global listeners. Intended for tests and teardown. */
|
|
1531
|
-
destroy() {
|
|
1532
|
-
if (typeof window === "undefined") return;
|
|
1533
|
-
this.destroyed = true;
|
|
1534
|
-
this.cancelActiveNavigation();
|
|
1535
|
-
this.clearCache();
|
|
1536
|
-
this.prefetchObserver?.disconnect();
|
|
1537
|
-
this.prefetchObserver = void 0;
|
|
1538
|
-
for (const timer of this.prefetchTimers.values()) clearTimeout(timer);
|
|
1539
|
-
this.observedPrefetchLinks.clear();
|
|
1540
|
-
this.prefetchTimers.clear();
|
|
1541
|
-
for (const task of this.viewportPrefetchQueue) task.cancelled = true;
|
|
1542
|
-
this.viewportPrefetchQueue.length = 0;
|
|
1543
|
-
this.viewportPrefetchTasksByHref.clear();
|
|
1544
|
-
this.viewportPrefetchTasksByElement.clear();
|
|
1545
|
-
window.removeEventListener("popstate", this.onPopState);
|
|
1546
|
-
window.removeEventListener("beforeunload", this.onBeforeUnload);
|
|
1547
|
-
}
|
|
1548
|
-
/**
|
|
1549
|
-
* Set the navigation handler that updates React
|
|
1550
|
-
*/
|
|
1551
|
-
setNavigationHandler(handler) {
|
|
1552
|
-
this.onNavigate = handler;
|
|
1553
|
-
}
|
|
1554
|
-
/**
|
|
1555
|
-
* Connect Farm's browser plugin lifecycle to SPA navigation.
|
|
1556
|
-
*/
|
|
1557
|
-
setClientPluginManager(manager) {
|
|
1558
|
-
this.clientPlugins = manager;
|
|
1559
|
-
}
|
|
1560
|
-
/**
|
|
1561
|
-
* Navigate to a new URL
|
|
1562
|
-
*/
|
|
1563
|
-
async navigate(href, options = {}) {
|
|
1564
|
-
const {
|
|
1565
|
-
replace = false,
|
|
1566
|
-
scroll = true,
|
|
1567
|
-
state,
|
|
1568
|
-
viewTransition = false,
|
|
1569
|
-
refresh = false
|
|
1570
|
-
} = options;
|
|
1571
|
-
const url = resolveFarmNavigationURL(href, window.location.href);
|
|
1572
|
-
const pathname = url.pathname;
|
|
1573
|
-
const search = url.search;
|
|
1574
|
-
const fullPath = pathname + search;
|
|
1575
|
-
if (isFarmExternalNavigationURL(url, window.location.origin) || isFarmLocaleChangeHref(url.toString()) || this.options.shouldUseDocumentNavigation(pathname)) {
|
|
1576
|
-
this.cancelActiveNavigation();
|
|
1577
|
-
if (replace) window.location.replace(url.toString());
|
|
1578
|
-
else window.location.assign(url.toString());
|
|
1579
|
-
return;
|
|
1580
|
-
}
|
|
1581
|
-
if (!refresh && pathname === window.location.pathname && search === window.location.search) {
|
|
1582
|
-
this.cancelActiveNavigation();
|
|
1583
|
-
if (url.hash === window.location.hash) return;
|
|
1584
|
-
this.writePageState(
|
|
1585
|
-
replace ? "replace" : "push",
|
|
1586
|
-
state === void 0 ? readPageState() : state,
|
|
1587
|
-
url.toString()
|
|
1588
|
-
);
|
|
1589
|
-
if (scroll) {
|
|
1590
|
-
if (url.hash) {
|
|
1591
|
-
getHashTargetElement(url.hash)?.scrollIntoView();
|
|
1592
|
-
} else {
|
|
1593
|
-
window.scrollTo(0, 0);
|
|
1594
|
-
}
|
|
1595
|
-
}
|
|
1596
|
-
return;
|
|
1597
|
-
}
|
|
1598
|
-
const from = window.location.pathname + window.location.search;
|
|
1599
|
-
if (await this.shouldBlockNavigation({
|
|
1600
|
-
from,
|
|
1601
|
-
to: fullPath,
|
|
1602
|
-
action: replace ? "replace" : "push"
|
|
1603
|
-
})) {
|
|
1604
|
-
return;
|
|
1605
|
-
}
|
|
1606
|
-
if (this.options.scrollRestoration) {
|
|
1607
|
-
this.saveScrollPosition(window.location.pathname + window.location.search);
|
|
1608
|
-
}
|
|
1609
|
-
const navigation = this.startNavigation({
|
|
1610
|
-
from,
|
|
1611
|
-
to: createNavigationLocation(url),
|
|
1612
|
-
action: replace ? "replace" : "push"
|
|
1613
|
-
});
|
|
1614
|
-
let clientNavigation;
|
|
1615
|
-
try {
|
|
1616
|
-
clientNavigation = await this.clientPlugins?.beginNavigation({
|
|
1617
|
-
from,
|
|
1618
|
-
to: url,
|
|
1619
|
-
action: replace ? "replace" : "push"
|
|
1620
|
-
});
|
|
1621
|
-
if (!this.isCurrentNavigation(navigation, clientNavigation)) return;
|
|
1622
|
-
const pageData = await this.fetchPageData(
|
|
1623
|
-
fullPath,
|
|
1624
|
-
true,
|
|
1625
|
-
from,
|
|
1626
|
-
refresh,
|
|
1627
|
-
navigation.controller.signal
|
|
1628
|
-
);
|
|
1629
|
-
if (!this.isCurrentNavigation(navigation, clientNavigation)) return;
|
|
1630
|
-
if (clientNavigation) {
|
|
1631
|
-
await this.clientPlugins?.markNavigationLoaded(clientNavigation, pageData);
|
|
1632
|
-
}
|
|
1633
|
-
if (!this.isCurrentNavigation(navigation, clientNavigation)) return;
|
|
1634
|
-
await this.runViewTransition(
|
|
1635
|
-
viewTransition,
|
|
1636
|
-
() => this.isCurrentNavigation(navigation, clientNavigation) ? this.commitNavigation({
|
|
1637
|
-
fullPath,
|
|
1638
|
-
pageData,
|
|
1639
|
-
pathname,
|
|
1640
|
-
replace,
|
|
1641
|
-
scroll,
|
|
1642
|
-
state,
|
|
1643
|
-
url
|
|
1644
|
-
}) : Promise.resolve()
|
|
1645
|
-
);
|
|
1646
|
-
if (!this.isCurrentNavigation(navigation, clientNavigation)) return;
|
|
1647
|
-
if (clientNavigation) {
|
|
1648
|
-
await this.clientPlugins?.resolveNavigation(clientNavigation);
|
|
1649
|
-
void this.clientPlugins?.scheduleNavigationRendered(clientNavigation);
|
|
1650
|
-
}
|
|
1651
|
-
this.finishNavigation(navigation);
|
|
1652
|
-
} catch (error) {
|
|
1653
|
-
if (!this.isCurrentNavigation(navigation, clientNavigation)) return;
|
|
1654
|
-
if (clientNavigation) {
|
|
1655
|
-
await this.clientPlugins?.failNavigation(clientNavigation, error);
|
|
1656
|
-
}
|
|
1657
|
-
this.finishNavigation(navigation);
|
|
1658
|
-
console.error("[Farm.js] Navigation error:", error);
|
|
1659
|
-
window.location.href = href;
|
|
1660
|
-
}
|
|
1661
|
-
}
|
|
1662
|
-
/**
|
|
1663
|
-
* Re-render the active route from the server while preserving the document,
|
|
1664
|
-
* shared layouts, client runtime, and browser history entry.
|
|
1665
|
-
*/
|
|
1666
|
-
refresh(options = {}) {
|
|
1667
|
-
return this.navigate(window.location.href, {
|
|
1668
|
-
...options,
|
|
1669
|
-
replace: true,
|
|
1670
|
-
refresh: true,
|
|
1671
|
-
scroll: options.scroll ?? false
|
|
1672
|
-
});
|
|
1673
|
-
}
|
|
1674
|
-
/**
|
|
1675
|
-
* Prefetch a URL
|
|
1676
|
-
*/
|
|
1677
|
-
async prefetch(href) {
|
|
1678
|
-
if (this.destroyed) return;
|
|
1679
|
-
if (isFarmLocaleChangeHref(href)) return;
|
|
1680
|
-
const url = resolveFarmNavigationURL(href, window.location.href);
|
|
1681
|
-
if (isFarmExternalNavigationURL(url, window.location.origin)) return;
|
|
1682
|
-
if (this.options.shouldUseDocumentNavigation(url.pathname)) return;
|
|
1683
|
-
const fullPath = url.pathname + url.search;
|
|
1684
|
-
const interceptFrom = window.location.pathname + window.location.search;
|
|
1685
|
-
if (this.prefetchingUrls.has(fullPath)) return;
|
|
1686
|
-
if (this.isCached(fullPath, interceptFrom)) return;
|
|
1687
|
-
this.prefetchingUrls.add(fullPath);
|
|
1688
|
-
try {
|
|
1689
|
-
await this.fetchPageData(fullPath, false, interceptFrom);
|
|
1690
|
-
} catch (error) {
|
|
1691
|
-
console.warn("[Farm.js] Prefetch failed:", href, error);
|
|
1692
|
-
} finally {
|
|
1693
|
-
this.prefetchingUrls.delete(fullPath);
|
|
1694
|
-
}
|
|
1695
|
-
}
|
|
1696
|
-
/**
|
|
1697
|
-
* Observe an element for viewport intersection (prefetch when visible)
|
|
1698
|
-
*/
|
|
1699
|
-
observeForPrefetch(element) {
|
|
1700
|
-
if (this.destroyed || typeof IntersectionObserver === "undefined") return;
|
|
1701
|
-
const href = element.getAttribute("href");
|
|
1702
|
-
if (!href || this.isExternalUrl(href)) return;
|
|
1703
|
-
this.unobserveForPrefetch(element);
|
|
1704
|
-
const observer = this.getPrefetchObserver();
|
|
1705
|
-
this.observedPrefetchLinks.set(element, href);
|
|
1706
|
-
observer.observe(element);
|
|
1707
|
-
}
|
|
1708
|
-
/**
|
|
1709
|
-
* Stop observing an element
|
|
1710
|
-
*/
|
|
1711
|
-
unobserveForPrefetch(element) {
|
|
1712
|
-
if (this.observedPrefetchLinks.delete(element)) {
|
|
1713
|
-
this.prefetchObserver?.unobserve(element);
|
|
1714
|
-
}
|
|
1715
|
-
const timer = this.prefetchTimers.get(element);
|
|
1716
|
-
if (timer !== void 0) {
|
|
1717
|
-
clearTimeout(timer);
|
|
1718
|
-
this.prefetchTimers.delete(element);
|
|
1719
|
-
}
|
|
1720
|
-
this.cancelQueuedViewportPrefetch(element);
|
|
1721
|
-
}
|
|
1722
|
-
getPrefetchObserver() {
|
|
1723
|
-
this.prefetchObserver ?? (this.prefetchObserver = new IntersectionObserver(
|
|
1724
|
-
(entries) => {
|
|
1725
|
-
for (const entry of entries) {
|
|
1726
|
-
if (!entry.isIntersecting) continue;
|
|
1727
|
-
const element = entry.target;
|
|
1728
|
-
const href = this.observedPrefetchLinks.get(element);
|
|
1729
|
-
if (!href) continue;
|
|
1730
|
-
this.prefetchObserver?.unobserve(element);
|
|
1731
|
-
this.observedPrefetchLinks.delete(element);
|
|
1732
|
-
const timer = setTimeout(() => {
|
|
1733
|
-
if (this.prefetchTimers.get(element) !== timer) return;
|
|
1734
|
-
this.prefetchTimers.delete(element);
|
|
1735
|
-
this.enqueueViewportPrefetch(element, href);
|
|
1736
|
-
}, this.options.prefetchTimeout);
|
|
1737
|
-
this.prefetchTimers.set(element, timer);
|
|
1738
|
-
}
|
|
1739
|
-
},
|
|
1740
|
-
{ rootMargin: "200px" }
|
|
1741
|
-
));
|
|
1742
|
-
return this.prefetchObserver;
|
|
1743
|
-
}
|
|
1744
|
-
enqueueViewportPrefetch(element, href) {
|
|
1745
|
-
if (this.destroyed) return;
|
|
1746
|
-
let task = this.viewportPrefetchTasksByHref.get(href);
|
|
1747
|
-
if (!task) {
|
|
1748
|
-
task = { href, elements: /* @__PURE__ */ new Set(), cancelled: false, started: false };
|
|
1749
|
-
this.viewportPrefetchTasksByHref.set(href, task);
|
|
1750
|
-
this.viewportPrefetchQueue.push(task);
|
|
1751
|
-
}
|
|
1752
|
-
task.elements.add(element);
|
|
1753
|
-
this.viewportPrefetchTasksByElement.set(element, task);
|
|
1754
|
-
this.drainViewportPrefetchQueue();
|
|
1755
|
-
}
|
|
1756
|
-
cancelQueuedViewportPrefetch(element) {
|
|
1757
|
-
const task = this.viewportPrefetchTasksByElement.get(element);
|
|
1758
|
-
if (!task) return;
|
|
1759
|
-
this.viewportPrefetchTasksByElement.delete(element);
|
|
1760
|
-
task.elements.delete(element);
|
|
1761
|
-
if (task.elements.size > 0) return;
|
|
1762
|
-
if (task.started) return;
|
|
1763
|
-
task.cancelled = true;
|
|
1764
|
-
if (this.viewportPrefetchTasksByHref.get(task.href) === task) {
|
|
1765
|
-
this.viewportPrefetchTasksByHref.delete(task.href);
|
|
1766
|
-
}
|
|
1767
|
-
}
|
|
1768
|
-
drainViewportPrefetchQueue() {
|
|
1769
|
-
while (!this.destroyed && this.activeViewportPrefetches < MAX_CONCURRENT_VIEWPORT_PREFETCHES && this.viewportPrefetchQueue.length > 0) {
|
|
1770
|
-
const task = this.viewportPrefetchQueue.shift();
|
|
1771
|
-
if (task.cancelled || task.elements.size === 0) {
|
|
1772
|
-
if (this.viewportPrefetchTasksByHref.get(task.href) === task) {
|
|
1773
|
-
this.viewportPrefetchTasksByHref.delete(task.href);
|
|
1774
|
-
}
|
|
1775
|
-
continue;
|
|
1776
|
-
}
|
|
1777
|
-
task.started = true;
|
|
1778
|
-
this.activeViewportPrefetches += 1;
|
|
1779
|
-
let prefetchResult;
|
|
1780
|
-
try {
|
|
1781
|
-
prefetchResult = this.prefetch(task.href);
|
|
1782
|
-
} catch {
|
|
1783
|
-
prefetchResult = void 0;
|
|
1784
|
-
}
|
|
1785
|
-
void Promise.resolve(prefetchResult).catch(() => void 0).finally(() => {
|
|
1786
|
-
if (this.viewportPrefetchTasksByHref.get(task.href) === task) {
|
|
1787
|
-
this.viewportPrefetchTasksByHref.delete(task.href);
|
|
1788
|
-
}
|
|
1789
|
-
for (const element of task.elements) {
|
|
1790
|
-
if (this.viewportPrefetchTasksByElement.get(element) === task) {
|
|
1791
|
-
this.viewportPrefetchTasksByElement.delete(element);
|
|
1792
|
-
}
|
|
1793
|
-
}
|
|
1794
|
-
this.activeViewportPrefetches -= 1;
|
|
1795
|
-
this.drainViewportPrefetchQueue();
|
|
1796
|
-
});
|
|
1797
|
-
}
|
|
1798
|
-
}
|
|
1799
|
-
addBlocker(blocker, shouldBlockUnload) {
|
|
1800
|
-
this.blockers.add(blocker);
|
|
1801
|
-
this.unloadBlockers.set(
|
|
1802
|
-
blocker,
|
|
1803
|
-
shouldBlockUnload ?? (() => this.evaluateBlockerForUnload(blocker))
|
|
1804
|
-
);
|
|
1805
|
-
return () => {
|
|
1806
|
-
this.blockers.delete(blocker);
|
|
1807
|
-
this.unloadBlockers.delete(blocker);
|
|
1808
|
-
};
|
|
1809
|
-
}
|
|
1810
|
-
getNavigationState() {
|
|
1811
|
-
return this.navigationState;
|
|
1812
|
-
}
|
|
1813
|
-
subscribeNavigation(listener) {
|
|
1814
|
-
this.navigationListeners.add(listener);
|
|
1815
|
-
listener(this.navigationState);
|
|
1816
|
-
return () => {
|
|
1817
|
-
this.navigationListeners.delete(listener);
|
|
1818
|
-
};
|
|
1819
|
-
}
|
|
1820
|
-
registerScrollElement(key, element) {
|
|
1821
|
-
this.scrollElements.set(key, element);
|
|
1822
|
-
this.restoreScrollElement(window.location.pathname + window.location.search, key, element);
|
|
1823
|
-
return () => {
|
|
1824
|
-
if (this.scrollElements.get(key) === element) {
|
|
1825
|
-
this.scrollElements.delete(key);
|
|
1826
|
-
}
|
|
1827
|
-
};
|
|
1828
|
-
}
|
|
1829
|
-
pushState(state, href) {
|
|
1830
|
-
this.writePageState("push", state, href);
|
|
1831
|
-
}
|
|
1832
|
-
replaceState(state, href) {
|
|
1833
|
-
this.writePageState("replace", state, href);
|
|
1834
|
-
}
|
|
1835
|
-
/** @internal Keep shallow URL-search writes inside the router's history bookkeeping. */
|
|
1836
|
-
writeURLSearch(action, href) {
|
|
1837
|
-
this.writePageState(action, readPageState(), href, false);
|
|
1838
|
-
}
|
|
1839
|
-
async commitNavigation(options) {
|
|
1840
|
-
const historyUrl = resolveFarmNavigationURL(
|
|
1841
|
-
options.pageData.canonicalPath || options.fullPath,
|
|
1842
|
-
window.location.href
|
|
1843
|
-
);
|
|
1844
|
-
historyUrl.hash = options.url.hash;
|
|
1845
|
-
const historyPath = historyUrl.pathname + historyUrl.search + historyUrl.hash;
|
|
1846
|
-
const historyState = createHistoryState(
|
|
1847
|
-
historyPath,
|
|
1848
|
-
options.state,
|
|
1849
|
-
options.replace ? window.history.state : void 0,
|
|
1850
|
-
options.pageData.interception?.from ?? null
|
|
1851
|
-
);
|
|
1852
|
-
const nextHistoryIndex = this.currentHistoryIndex == null ? null : options.replace ? this.currentHistoryIndex : this.currentHistoryIndex + 1;
|
|
1853
|
-
if (nextHistoryIndex != null) {
|
|
1854
|
-
historyState[FARM_HISTORY_INDEX_KEY] = nextHistoryIndex;
|
|
1855
|
-
}
|
|
1856
|
-
if (options.replace) {
|
|
1857
|
-
window.history.replaceState(historyState, "", historyPath);
|
|
1858
|
-
} else {
|
|
1859
|
-
window.history.pushState(historyState, "", historyPath);
|
|
1860
|
-
}
|
|
1861
|
-
this.currentHistoryIndex = nextHistoryIndex;
|
|
1862
|
-
const resolvedHistoryUrl = resolveFarmNavigationURL(historyPath, window.location.href);
|
|
1863
|
-
this.currentHistoryPath = resolvedHistoryUrl.pathname + resolvedHistoryUrl.search;
|
|
1864
|
-
this.currentHistoryHash = resolvedHistoryUrl.hash;
|
|
1865
|
-
this.currentInterceptFrom = historyState[FARM_INTERCEPT_FROM_KEY];
|
|
1866
|
-
notifyRouterHistoryChange();
|
|
1867
|
-
this.updateDocumentMetadata(options.pageData.metadata);
|
|
1868
|
-
_hydrateFarmI18n(options.pageData.i18n);
|
|
1869
|
-
if (this.onNavigate) {
|
|
1870
|
-
await this.onNavigate(options.pageData);
|
|
1871
|
-
}
|
|
1872
|
-
if (options.scroll) {
|
|
1873
|
-
if (options.url.hash) {
|
|
1874
|
-
const element = getHashTargetElement(options.url.hash);
|
|
1875
|
-
if (element) {
|
|
1876
|
-
element.scrollIntoView();
|
|
1877
|
-
}
|
|
1878
|
-
} else {
|
|
1879
|
-
window.scrollTo(0, 0);
|
|
1880
|
-
}
|
|
1881
|
-
} else if (this.options.scrollRestoration) {
|
|
1882
|
-
const restorePath = this.currentHistoryPath ?? options.fullPath;
|
|
1883
|
-
this.restoreWindowScroll(restorePath);
|
|
1884
|
-
this.restoreScrollElements(restorePath);
|
|
1885
|
-
}
|
|
1886
|
-
}
|
|
1887
|
-
async runViewTransition(mode, callback) {
|
|
1888
|
-
if (!mode || typeof document === "undefined") {
|
|
1889
|
-
await callback();
|
|
1890
|
-
return;
|
|
1891
|
-
}
|
|
1892
|
-
const startViewTransition = document.startViewTransition;
|
|
1893
|
-
if (typeof startViewTransition !== "function") {
|
|
1894
|
-
await callback();
|
|
1895
|
-
return;
|
|
1896
|
-
}
|
|
1897
|
-
const transition = startViewTransition.call(document, () => callback());
|
|
1898
|
-
const updateDone = transition?.updateCallbackDone || transition?.ready;
|
|
1899
|
-
if (updateDone && typeof updateDone.then === "function") {
|
|
1900
|
-
await updateDone;
|
|
1901
|
-
}
|
|
1902
|
-
transition?.finished?.catch?.(() => void 0);
|
|
1903
|
-
}
|
|
1904
|
-
/**
|
|
1905
|
-
* Fetch page data from cache or server
|
|
1906
|
-
*/
|
|
1907
|
-
async fetchPageData(path, recover = true, interceptFrom, fresh = false, signal) {
|
|
1908
|
-
const cacheKey = getPageDataCacheKey(path, interceptFrom);
|
|
1909
|
-
const cached = fresh ? void 0 : this.cache.get(cacheKey);
|
|
1910
|
-
if (cached && Date.now() - cached.timestamp < this.options.cacheMaxAge) {
|
|
1911
|
-
return cached.data;
|
|
1912
|
-
}
|
|
1913
|
-
const activeLayoutChain = getActiveLayoutChainHeader();
|
|
1914
|
-
const prefetchKey = JSON.stringify([path, interceptFrom, activeLayoutChain]);
|
|
1915
|
-
let generation = this.cacheGeneration;
|
|
1916
|
-
const pending = this.pendingPrefetches.get(prefetchKey);
|
|
1917
|
-
if (pending && recover) {
|
|
1918
|
-
if (fresh) {
|
|
1919
|
-
pending.cacheable = false;
|
|
1920
|
-
pending.resolve(void 0);
|
|
1921
|
-
this.pendingPrefetches.delete(prefetchKey);
|
|
1922
|
-
} else {
|
|
1923
|
-
const cancellation = createClientCancellation(signal);
|
|
1924
|
-
try {
|
|
1925
|
-
const data = await cancellation.run(() => pending.data);
|
|
1926
|
-
cancellation.check();
|
|
1927
|
-
if (data && pending.cacheable && generation === this.cacheGeneration) return data;
|
|
1928
|
-
} finally {
|
|
1929
|
-
cancellation.dispose();
|
|
1930
|
-
}
|
|
1931
|
-
}
|
|
1932
|
-
}
|
|
1933
|
-
generation = this.cacheGeneration;
|
|
1934
|
-
let prefetch;
|
|
1935
|
-
if (!recover) {
|
|
1936
|
-
let resolve;
|
|
1937
|
-
const data = new Promise((done) => {
|
|
1938
|
-
resolve = done;
|
|
1939
|
-
});
|
|
1940
|
-
prefetch = { data, resolve, cacheable: true };
|
|
1941
|
-
this.pendingPrefetches.set(prefetchKey, prefetch);
|
|
1942
|
-
}
|
|
1943
|
-
const cacheData = /* @__PURE__ */ __name((data) => {
|
|
1944
|
-
if (!this.destroyed && generation === this.cacheGeneration && prefetch?.cacheable !== false) {
|
|
1945
|
-
this.cachePageData(cacheKey, data);
|
|
1946
|
-
}
|
|
1947
|
-
}, "cacheData");
|
|
1948
|
-
try {
|
|
1949
|
-
return await this.requestPageData(
|
|
1950
|
-
path,
|
|
1951
|
-
recover,
|
|
1952
|
-
interceptFrom,
|
|
1953
|
-
activeLayoutChain,
|
|
1954
|
-
signal,
|
|
1955
|
-
cacheData,
|
|
1956
|
-
prefetch?.resolve
|
|
1957
|
-
);
|
|
1958
|
-
} finally {
|
|
1959
|
-
prefetch?.resolve(void 0);
|
|
1960
|
-
if (prefetch && this.pendingPrefetches.get(prefetchKey) === prefetch) {
|
|
1961
|
-
this.pendingPrefetches.delete(prefetchKey);
|
|
1962
|
-
}
|
|
1963
|
-
}
|
|
1964
|
-
}
|
|
1965
|
-
async requestPageData(path, recover, interceptFrom, activeLayoutChain, signal, cacheData, resolvePrefetch) {
|
|
1966
|
-
const response = await fetch(`/__farm/page-data?path=${encodeURIComponent(path)}`, {
|
|
1967
|
-
signal,
|
|
1968
|
-
headers: createFarmDeploymentRequestHeaders(this.options.deploymentId, {
|
|
1969
|
-
Accept: "application/x-farm-deferred+json, application/json",
|
|
1970
|
-
"X-Farm-SPA": "1",
|
|
1971
|
-
...activeLayoutChain ? { "X-Farm-Layout-Chain": activeLayoutChain } : {},
|
|
1972
|
-
...interceptFrom ? { "X-Farm-Intercept-From": interceptFrom } : {}
|
|
1973
|
-
})
|
|
1974
|
-
});
|
|
1975
|
-
if (isFarmDeploymentMismatchResponse(response, this.options.deploymentId)) {
|
|
1976
|
-
const error = createFarmDeploymentMismatchError(
|
|
1977
|
-
response,
|
|
1978
|
-
this.options.deploymentId || "unknown"
|
|
1979
|
-
);
|
|
1980
|
-
dispatchDeploymentMismatch(error);
|
|
1981
|
-
if (recover) {
|
|
1982
|
-
window.location.assign(path);
|
|
1983
|
-
}
|
|
1984
|
-
throw error;
|
|
1985
|
-
}
|
|
1986
|
-
if (!response.ok) {
|
|
1987
|
-
throw new Error(`Failed to fetch page data: ${response.status}`);
|
|
1988
|
-
}
|
|
1989
|
-
const isDeferredResponse = (response.headers.get("Content-Type") || "").toLowerCase().startsWith("application/x-farm-deferred+json");
|
|
1990
|
-
if (!isDeferredResponse) {
|
|
1991
|
-
const data2 = await readDeferredDataResponse(response);
|
|
1992
|
-
cacheData(data2);
|
|
1993
|
-
resolvePrefetch?.(data2);
|
|
1994
|
-
return data2;
|
|
1995
|
-
}
|
|
1996
|
-
resolvePrefetch?.(void 0);
|
|
1997
|
-
let data;
|
|
1998
|
-
let streamCompleted = false;
|
|
1999
|
-
const markStreamComplete = /* @__PURE__ */ __name(() => {
|
|
2000
|
-
streamCompleted = true;
|
|
2001
|
-
if (data) cacheData(data);
|
|
2002
|
-
}, "markStreamComplete");
|
|
2003
|
-
data = await readDeferredDataResponse(response, {
|
|
2004
|
-
onComplete: markStreamComplete
|
|
2005
|
-
});
|
|
2006
|
-
if (streamCompleted) cacheData(data);
|
|
2007
|
-
return data;
|
|
2008
|
-
}
|
|
2009
|
-
cachePageData(cacheKey, data) {
|
|
2010
|
-
const now = Date.now();
|
|
2011
|
-
for (const [key, entry] of this.cache) {
|
|
2012
|
-
if (now - entry.timestamp >= this.options.cacheMaxAge) this.cache.delete(key);
|
|
2013
|
-
}
|
|
2014
|
-
this.cache.set(cacheKey, { data, timestamp: now });
|
|
2015
|
-
}
|
|
2016
|
-
/**
|
|
2017
|
-
* Put the browser URL back on the rendered page after a blocked pop. When
|
|
2018
|
-
* both entries carry a Farm history index the traversal is reversed
|
|
2019
|
-
* exactly; otherwise the current path is pushed again, which restores the
|
|
2020
|
-
* address bar at the cost of one extra history entry.
|
|
2021
|
-
*/
|
|
2022
|
-
revertBlockedPopState(event, from) {
|
|
2023
|
-
const eventIndex = readHistoryIndex(event.state);
|
|
2024
|
-
if (eventIndex != null && this.currentHistoryIndex != null) {
|
|
2025
|
-
const delta = eventIndex - this.currentHistoryIndex;
|
|
2026
|
-
if (delta !== 0) {
|
|
2027
|
-
this.suppressNextPopState = true;
|
|
2028
|
-
window.history.go(-delta);
|
|
2029
|
-
return;
|
|
2030
|
-
}
|
|
2031
|
-
}
|
|
2032
|
-
try {
|
|
2033
|
-
const restoredState = {
|
|
2034
|
-
path: from
|
|
2035
|
-
};
|
|
2036
|
-
if (this.currentHistoryIndex != null && eventIndex != null) {
|
|
2037
|
-
restoredState[FARM_HISTORY_INDEX_KEY] = eventIndex + 1;
|
|
2038
|
-
this.currentHistoryIndex = eventIndex + 1;
|
|
2039
|
-
}
|
|
2040
|
-
window.history.pushState(restoredState, "", from);
|
|
2041
|
-
} catch {
|
|
2042
|
-
}
|
|
2043
|
-
}
|
|
2044
|
-
/**
|
|
2045
|
-
* Handle browser back/forward navigation
|
|
2046
|
-
*/
|
|
2047
|
-
async handlePopState(event) {
|
|
2048
|
-
if (document.documentElement.dataset.farmDocsRuntime === "true") return;
|
|
2049
|
-
if (this.suppressNextPopState) {
|
|
2050
|
-
this.suppressNextPopState = false;
|
|
2051
|
-
return;
|
|
2052
|
-
}
|
|
2053
|
-
const path = window.location.pathname + window.location.search;
|
|
2054
|
-
const from = this.currentHistoryPath ?? path;
|
|
2055
|
-
if (path === from && window.location.hash !== this.currentHistoryHash && event.state?.[FARM_INTERCEPT_FROM_KEY] === this.currentInterceptFrom) {
|
|
2056
|
-
this.cancelActiveNavigation();
|
|
2057
|
-
this.currentHistoryHash = window.location.hash;
|
|
2058
|
-
this.currentHistoryIndex = readHistoryIndex(event.state);
|
|
2059
|
-
return;
|
|
2060
|
-
}
|
|
2061
|
-
if (await this.shouldBlockNavigation({
|
|
2062
|
-
from,
|
|
2063
|
-
to: path,
|
|
2064
|
-
action: "pop"
|
|
2065
|
-
})) {
|
|
2066
|
-
this.revertBlockedPopState(event, from);
|
|
2067
|
-
return;
|
|
2068
|
-
}
|
|
2069
|
-
this.currentHistoryPath = path;
|
|
2070
|
-
this.currentHistoryHash = window.location.hash;
|
|
2071
|
-
this.currentInterceptFrom = event.state?.[FARM_INTERCEPT_FROM_KEY];
|
|
2072
|
-
this.currentHistoryIndex = readHistoryIndex(event.state);
|
|
2073
|
-
const navigation = this.startNavigation({
|
|
2074
|
-
from,
|
|
2075
|
-
to: createNavigationLocation(new URL(window.location.href)),
|
|
2076
|
-
action: "pop"
|
|
2077
|
-
});
|
|
2078
|
-
let clientNavigation;
|
|
2079
|
-
try {
|
|
2080
|
-
clientNavigation = await this.clientPlugins?.beginNavigation({
|
|
2081
|
-
from: null,
|
|
2082
|
-
to: window.location.href,
|
|
2083
|
-
action: "pop"
|
|
2084
|
-
});
|
|
2085
|
-
if (!this.isCurrentNavigation(navigation, clientNavigation)) return;
|
|
2086
|
-
const interceptFrom = typeof event.state?.[FARM_INTERCEPT_FROM_KEY] === "string" ? event.state[FARM_INTERCEPT_FROM_KEY] : void 0;
|
|
2087
|
-
const pageData = await this.fetchPageData(
|
|
2088
|
-
path,
|
|
2089
|
-
true,
|
|
2090
|
-
interceptFrom,
|
|
2091
|
-
false,
|
|
2092
|
-
navigation.controller.signal
|
|
2093
|
-
);
|
|
2094
|
-
if (!this.isCurrentNavigation(navigation, clientNavigation)) return;
|
|
2095
|
-
if (clientNavigation) {
|
|
2096
|
-
await this.clientPlugins?.markNavigationLoaded(clientNavigation, pageData);
|
|
2097
|
-
}
|
|
2098
|
-
if (!this.isCurrentNavigation(navigation, clientNavigation)) return;
|
|
2099
|
-
this.updateDocumentMetadata(pageData.metadata);
|
|
2100
|
-
_hydrateFarmI18n(pageData.i18n);
|
|
2101
|
-
if (this.onNavigate) {
|
|
2102
|
-
await this.onNavigate(pageData);
|
|
2103
|
-
}
|
|
2104
|
-
const destinationPath = window.location.pathname + window.location.search;
|
|
2105
|
-
if (window.location.hash) {
|
|
2106
|
-
const target = getHashTargetElement(window.location.hash);
|
|
2107
|
-
if (target) {
|
|
2108
|
-
target.scrollIntoView();
|
|
2109
|
-
} else if (this.options.scrollRestoration) {
|
|
2110
|
-
this.restoreWindowScroll(destinationPath);
|
|
2111
|
-
}
|
|
2112
|
-
} else if (this.options.scrollRestoration) {
|
|
2113
|
-
this.restoreWindowScroll(destinationPath);
|
|
2114
|
-
}
|
|
2115
|
-
if (this.options.scrollRestoration) {
|
|
2116
|
-
this.restoreScrollElements(destinationPath);
|
|
2117
|
-
}
|
|
2118
|
-
if (clientNavigation) {
|
|
2119
|
-
await this.clientPlugins?.resolveNavigation(clientNavigation);
|
|
2120
|
-
void this.clientPlugins?.scheduleNavigationRendered(clientNavigation);
|
|
2121
|
-
}
|
|
2122
|
-
this.finishNavigation(navigation);
|
|
2123
|
-
} catch (error) {
|
|
2124
|
-
if (!this.isCurrentNavigation(navigation, clientNavigation)) return;
|
|
2125
|
-
if (clientNavigation) {
|
|
2126
|
-
await this.clientPlugins?.failNavigation(clientNavigation, error);
|
|
2127
|
-
}
|
|
2128
|
-
this.finishNavigation(navigation);
|
|
2129
|
-
console.error("[Farm.js] Popstate navigation error:", error);
|
|
2130
|
-
window.location.reload();
|
|
2131
|
-
}
|
|
2132
|
-
}
|
|
2133
|
-
/**
|
|
2134
|
-
* Check if URL is cached
|
|
2135
|
-
*/
|
|
2136
|
-
isCached(path, interceptFrom) {
|
|
2137
|
-
const cached = this.cache.get(getPageDataCacheKey(path, interceptFrom));
|
|
2138
|
-
return cached !== void 0 && Date.now() - cached.timestamp < this.options.cacheMaxAge;
|
|
2139
|
-
}
|
|
2140
|
-
/**
|
|
2141
|
-
* Check if URL is external
|
|
2142
|
-
*/
|
|
2143
|
-
isExternalUrl(href) {
|
|
2144
|
-
return href.startsWith("http://") || href.startsWith("https://") || href.startsWith("//");
|
|
2145
|
-
}
|
|
2146
|
-
async shouldBlockNavigation(context) {
|
|
2147
|
-
for (const blocker of this.blockers) {
|
|
2148
|
-
if (await blocker(context)) {
|
|
2149
|
-
return true;
|
|
2150
|
-
}
|
|
2151
|
-
}
|
|
2152
|
-
return false;
|
|
2153
|
-
}
|
|
2154
|
-
evaluateBlockerForUnload(blocker) {
|
|
2155
|
-
const path = window.location.pathname + window.location.search;
|
|
2156
|
-
const result = blocker({ from: path, to: path, action: "replace" });
|
|
2157
|
-
if (result && typeof result !== "boolean") {
|
|
2158
|
-
void result.catch(() => void 0);
|
|
2159
|
-
return true;
|
|
2160
|
-
}
|
|
2161
|
-
return result === true;
|
|
2162
|
-
}
|
|
2163
|
-
shouldBlockUnload() {
|
|
2164
|
-
for (const blocker of this.blockers) {
|
|
2165
|
-
try {
|
|
2166
|
-
if (this.unloadBlockers.get(blocker)?.()) return true;
|
|
2167
|
-
} catch {
|
|
2168
|
-
return true;
|
|
2169
|
-
}
|
|
2170
|
-
}
|
|
2171
|
-
return false;
|
|
2172
|
-
}
|
|
2173
|
-
updateDocumentMetadata(metadata) {
|
|
2174
|
-
applyFarmMetadataToDocument(metadata, window.location.pathname);
|
|
2175
|
-
}
|
|
2176
|
-
startNavigation(options) {
|
|
2177
|
-
this.activeNavigation?.controller.abort("superseded");
|
|
2178
|
-
const navigation = {
|
|
2179
|
-
id: ++this.navigationSequence,
|
|
2180
|
-
controller: new AbortController()
|
|
2181
|
-
};
|
|
2182
|
-
this.activeNavigation = navigation;
|
|
2183
|
-
this.setNavigationState({
|
|
2184
|
-
state: "loading",
|
|
2185
|
-
pending: true,
|
|
2186
|
-
from: options.from,
|
|
2187
|
-
to: options.to,
|
|
2188
|
-
action: options.action,
|
|
2189
|
-
startedAt: Date.now()
|
|
2190
|
-
});
|
|
2191
|
-
return navigation;
|
|
2192
|
-
}
|
|
2193
|
-
isCurrentNavigation(navigation, clientNavigation) {
|
|
2194
|
-
return this.activeNavigation?.id === navigation.id && !navigation.controller.signal.aborted && !clientNavigation?.signal.aborted;
|
|
2195
|
-
}
|
|
2196
|
-
finishNavigation(navigation) {
|
|
2197
|
-
if (this.activeNavigation?.id !== navigation.id) return;
|
|
2198
|
-
this.activeNavigation = void 0;
|
|
2199
|
-
this.setNavigationState(IDLE_NAVIGATION_STATE);
|
|
2200
|
-
}
|
|
2201
|
-
cancelActiveNavigation() {
|
|
2202
|
-
if (!this.activeNavigation) return;
|
|
2203
|
-
this.activeNavigation.controller.abort("superseded");
|
|
2204
|
-
this.activeNavigation = void 0;
|
|
2205
|
-
this.setNavigationState(IDLE_NAVIGATION_STATE);
|
|
2206
|
-
}
|
|
2207
|
-
setNavigationState(state) {
|
|
2208
|
-
this.navigationState = state;
|
|
2209
|
-
for (const listener of this.navigationListeners) {
|
|
2210
|
-
listener(state);
|
|
2211
|
-
}
|
|
2212
|
-
}
|
|
2213
|
-
writePageState(action, state, href, notify = true) {
|
|
2214
|
-
if (typeof window === "undefined") return;
|
|
2215
|
-
const url = href ? resolveFarmNavigationURL(href, window.location.href).toString() : window.location.href;
|
|
2216
|
-
const parsedUrl = new URL(url);
|
|
2217
|
-
const nextPath = parsedUrl.pathname + parsedUrl.search;
|
|
2218
|
-
const historyPath = nextPath + parsedUrl.hash;
|
|
2219
|
-
const nextState = createHistoryState(historyPath, state, window.history.state);
|
|
2220
|
-
if (action === "replace") {
|
|
2221
|
-
window.history.replaceState(nextState, "", url);
|
|
2222
|
-
} else {
|
|
2223
|
-
if (this.currentHistoryIndex != null) {
|
|
2224
|
-
nextState[FARM_HISTORY_INDEX_KEY] = this.currentHistoryIndex + 1;
|
|
2225
|
-
}
|
|
2226
|
-
window.history.pushState(nextState, "", url);
|
|
2227
|
-
this.currentHistoryIndex = this.currentHistoryIndex == null ? null : this.currentHistoryIndex + 1;
|
|
2228
|
-
}
|
|
2229
|
-
this.currentHistoryPath = nextPath;
|
|
2230
|
-
this.currentHistoryHash = parsedUrl.hash;
|
|
2231
|
-
this.currentInterceptFrom = nextState[FARM_INTERCEPT_FROM_KEY];
|
|
2232
|
-
if (notify) notifyHistoryChange("page-state");
|
|
2233
|
-
}
|
|
2234
|
-
/**
|
|
2235
|
-
* Save scroll position for a path
|
|
2236
|
-
*/
|
|
2237
|
-
saveScrollPosition(path) {
|
|
2238
|
-
try {
|
|
2239
|
-
sessionStorage.setItem(
|
|
2240
|
-
`farm-scroll-${path}`,
|
|
2241
|
-
JSON.stringify({ x: window.scrollX, y: window.scrollY })
|
|
2242
|
-
);
|
|
2243
|
-
for (const [key, element] of this.scrollElements) {
|
|
2244
|
-
sessionStorage.setItem(
|
|
2245
|
-
getScrollElementStorageKey(path, key),
|
|
2246
|
-
JSON.stringify({ x: element.scrollLeft, y: element.scrollTop })
|
|
2247
|
-
);
|
|
2248
|
-
}
|
|
2249
|
-
} catch {
|
|
2250
|
-
}
|
|
2251
|
-
}
|
|
2252
|
-
/**
|
|
2253
|
-
* Restore the saved window scroll position for a path.
|
|
2254
|
-
*/
|
|
2255
|
-
restoreWindowScroll(path) {
|
|
2256
|
-
try {
|
|
2257
|
-
const saved = sessionStorage.getItem(`farm-scroll-${path}`);
|
|
2258
|
-
if (saved) {
|
|
2259
|
-
const { x, y } = JSON.parse(saved);
|
|
2260
|
-
setTimeout(() => window.scrollTo(x, y), 0);
|
|
2261
|
-
}
|
|
2262
|
-
} catch {
|
|
2263
|
-
}
|
|
2264
|
-
}
|
|
2265
|
-
/**
|
|
2266
|
-
* Restore saved scroll positions for every registered scroll element. Keys
|
|
2267
|
-
* are hash-stripped (see getScrollElementStorageKey), so this runs regardless
|
|
2268
|
-
* of whether the destination URL carries a fragment.
|
|
2269
|
-
*/
|
|
2270
|
-
restoreScrollElements(path) {
|
|
2271
|
-
try {
|
|
2272
|
-
for (const [key, element] of this.scrollElements) {
|
|
2273
|
-
this.restoreScrollElement(path, key, element);
|
|
2274
|
-
}
|
|
2275
|
-
} catch {
|
|
2276
|
-
}
|
|
2277
|
-
}
|
|
2278
|
-
restoreScrollElement(path, key, element) {
|
|
2279
|
-
try {
|
|
2280
|
-
const saved = sessionStorage.getItem(getScrollElementStorageKey(path, key));
|
|
2281
|
-
if (!saved) return;
|
|
2282
|
-
const { x, y } = JSON.parse(saved);
|
|
2283
|
-
setTimeout(() => {
|
|
2284
|
-
element.scrollLeft = x;
|
|
2285
|
-
element.scrollTop = y;
|
|
2286
|
-
}, 0);
|
|
2287
|
-
} catch {
|
|
2288
|
-
}
|
|
2289
|
-
}
|
|
2290
|
-
/**
|
|
2291
|
-
* Clear the page cache
|
|
2292
|
-
*/
|
|
2293
|
-
clearCache() {
|
|
2294
|
-
this.cacheGeneration += 1;
|
|
2295
|
-
this.cache.clear();
|
|
2296
|
-
for (const pending of this.pendingPrefetches.values()) {
|
|
2297
|
-
pending.cacheable = false;
|
|
2298
|
-
pending.resolve(void 0);
|
|
2299
|
-
}
|
|
2300
|
-
this.pendingPrefetches.clear();
|
|
2301
|
-
}
|
|
2302
|
-
};
|
|
2303
|
-
__name(_SPARouter, "SPARouter");
|
|
2304
|
-
var SPARouter = _SPARouter;
|
|
2305
|
-
function readBrowserDeploymentId() {
|
|
2306
|
-
if (typeof window === "undefined") return void 0;
|
|
2307
|
-
const runtimeId = window.__FARM_DEPLOYMENT_ID__;
|
|
2308
|
-
if (typeof runtimeId === "string" && runtimeId) return runtimeId;
|
|
2309
|
-
return document.querySelector('meta[name="farm-deployment-id"]')?.content;
|
|
2310
|
-
}
|
|
2311
|
-
__name(readBrowserDeploymentId, "readBrowserDeploymentId");
|
|
2312
|
-
function dispatchDeploymentMismatch(error) {
|
|
2313
|
-
if (typeof window === "undefined" || typeof CustomEvent === "undefined") return;
|
|
2314
|
-
window.dispatchEvent(new CustomEvent("farm:deployment-mismatch", { detail: error }));
|
|
2315
|
-
}
|
|
2316
|
-
__name(dispatchDeploymentMismatch, "dispatchDeploymentMismatch");
|
|
2317
|
-
function getInstalledFarmSPARouter() {
|
|
2318
|
-
if (typeof window === "undefined") return void 0;
|
|
2319
|
-
return window.__FARM_SPA_ROUTER__;
|
|
2320
|
-
}
|
|
2321
|
-
__name(getInstalledFarmSPARouter, "getInstalledFarmSPARouter");
|
|
2322
|
-
function getRouter() {
|
|
2323
|
-
if (typeof window === "undefined") {
|
|
2324
|
-
return new SPARouter();
|
|
2325
|
-
}
|
|
2326
|
-
const installedRouter = getInstalledFarmSPARouter();
|
|
2327
|
-
if (installedRouter) {
|
|
2328
|
-
routerInstance = installedRouter;
|
|
2329
|
-
return installedRouter;
|
|
2330
|
-
}
|
|
2331
|
-
if (!routerInstance) {
|
|
2332
|
-
routerInstance = new SPARouter();
|
|
2333
|
-
}
|
|
2334
|
-
return routerInstance;
|
|
2335
|
-
}
|
|
2336
|
-
__name(getRouter, "getRouter");
|
|
2337
|
-
function readPageState() {
|
|
2338
|
-
if (typeof window === "undefined") return null;
|
|
2339
|
-
const state = window.history.state;
|
|
2340
|
-
if (!state || typeof state !== "object") return null;
|
|
2341
|
-
return state[FARM_PAGE_STATE_KEY] ?? null;
|
|
2342
|
-
}
|
|
2343
|
-
__name(readPageState, "readPageState");
|
|
2344
|
-
function createHistoryState(path, pageState, currentState, interceptFrom) {
|
|
2345
|
-
const base = currentState && typeof currentState === "object" ? { ...currentState } : {};
|
|
2346
|
-
const nextState = {
|
|
2347
|
-
...base,
|
|
2348
|
-
path,
|
|
2349
|
-
[FARM_PAGE_STATE_KEY]: pageState
|
|
2350
|
-
};
|
|
2351
|
-
if (interceptFrom === null) {
|
|
2352
|
-
delete nextState[FARM_INTERCEPT_FROM_KEY];
|
|
2353
|
-
} else if (interceptFrom) {
|
|
2354
|
-
nextState[FARM_INTERCEPT_FROM_KEY] = interceptFrom;
|
|
2355
|
-
}
|
|
2356
|
-
return nextState;
|
|
2357
|
-
}
|
|
2358
|
-
__name(createHistoryState, "createHistoryState");
|
|
2359
|
-
function getPageDataCacheKey(path, interceptFrom) {
|
|
2360
|
-
return interceptFrom ? `${path}
|
|
2361
|
-
intercept:${interceptFrom}` : path;
|
|
2362
|
-
}
|
|
2363
|
-
__name(getPageDataCacheKey, "getPageDataCacheKey");
|
|
2364
|
-
function createNavigationLocation(url) {
|
|
2365
|
-
return {
|
|
2366
|
-
href: url.href,
|
|
2367
|
-
pathname: url.pathname,
|
|
2368
|
-
search: url.search,
|
|
2369
|
-
hash: url.hash
|
|
2370
|
-
};
|
|
2371
|
-
}
|
|
2372
|
-
__name(createNavigationLocation, "createNavigationLocation");
|
|
2373
|
-
function getScrollElementStorageKey(path, key) {
|
|
2374
|
-
return `farm-scroll-${path}:${key}`;
|
|
2375
|
-
}
|
|
2376
|
-
__name(getScrollElementStorageKey, "getScrollElementStorageKey");
|
|
2377
41
|
|
|
2378
|
-
|
|
2379
|
-
var CURRENT_REQUEST_RESOLVER_KEY = /* @__PURE__ */ Symbol.for("farm.currentRequestResolver");
|
|
2380
|
-
function getGlobalState() {
|
|
2381
|
-
return globalThis;
|
|
2382
|
-
}
|
|
2383
|
-
__name(getGlobalState, "getGlobalState");
|
|
2384
|
-
function _resolveCurrentRequest() {
|
|
2385
|
-
return getGlobalState()[CURRENT_REQUEST_RESOLVER_KEY]?.();
|
|
2386
|
-
}
|
|
2387
|
-
__name(_resolveCurrentRequest, "_resolveCurrentRequest");
|
|
2388
|
-
|
|
2389
|
-
// src/client/router.ts
|
|
2390
|
-
function navigateViaRouter(href, basePath, replace) {
|
|
2391
|
-
if (typeof window === "undefined") return;
|
|
2392
|
-
const url = applyFarmBasePath(href, basePath);
|
|
2393
|
-
const spaRouter = getInstalledFarmSPARouter();
|
|
2394
|
-
if (spaRouter) {
|
|
2395
|
-
void spaRouter.navigate(url, { replace });
|
|
2396
|
-
return;
|
|
2397
|
-
}
|
|
2398
|
-
if (replace) {
|
|
2399
|
-
window.history.replaceState(null, "", url);
|
|
2400
|
-
} else {
|
|
2401
|
-
window.history.pushState(null, "", url);
|
|
2402
|
-
}
|
|
2403
|
-
notifyHistoryChange("url-search");
|
|
2404
|
-
}
|
|
2405
|
-
__name(navigateViaRouter, "navigateViaRouter");
|
|
2406
|
-
function useRouter(options = {}) {
|
|
2407
|
-
const basePath = options.basePath === void 0 ? getFarmBasePath() : normalizeFarmBasePath(options.basePath);
|
|
2408
|
-
const routes = options.routes;
|
|
2409
|
-
const routeKey = routes?.map((route) => typeof route === "string" ? route : route.path).join("\n") || "";
|
|
2410
|
-
const routeMatcher = (0, import_react.useMemo)(
|
|
2411
|
-
() => routeKey ? createFarmRouter(routeKey.split("\n")) : null,
|
|
2412
|
-
[routeKey]
|
|
2413
|
-
);
|
|
2414
|
-
const [state, setState] = (0, import_react.useState)(() => {
|
|
2415
|
-
return readRouterState(basePath, routeMatcher);
|
|
2416
|
-
});
|
|
2417
|
-
(0, import_react.useEffect)(() => {
|
|
2418
|
-
if (typeof window === "undefined") return;
|
|
2419
|
-
const handlePopState = /* @__PURE__ */ __name(() => {
|
|
2420
|
-
setState(readRouterState(basePath, routeMatcher));
|
|
2421
|
-
}, "handlePopState");
|
|
2422
|
-
handlePopState();
|
|
2423
|
-
const unsubscribe = subscribeHistoryChange(handlePopState);
|
|
2424
|
-
return unsubscribe;
|
|
2425
|
-
}, [basePath, routeMatcher]);
|
|
2426
|
-
const push = /* @__PURE__ */ __name((href) => {
|
|
2427
|
-
navigateViaRouter(href, basePath, false);
|
|
2428
|
-
}, "push");
|
|
2429
|
-
const replace = /* @__PURE__ */ __name((href) => {
|
|
2430
|
-
navigateViaRouter(href, basePath, true);
|
|
2431
|
-
}, "replace");
|
|
2432
|
-
const pushState = /* @__PURE__ */ __name((pageState, href) => {
|
|
2433
|
-
if (typeof window === "undefined") return;
|
|
2434
|
-
getRouter().pushState(pageState, resolveClientHref(href, basePath));
|
|
2435
|
-
}, "pushState");
|
|
2436
|
-
const replaceState = /* @__PURE__ */ __name((pageState, href) => {
|
|
2437
|
-
if (typeof window === "undefined") return;
|
|
2438
|
-
getRouter().replaceState(pageState, resolveClientHref(href, basePath));
|
|
2439
|
-
}, "replaceState");
|
|
2440
|
-
const back = /* @__PURE__ */ __name(() => {
|
|
2441
|
-
if (typeof window !== "undefined") {
|
|
2442
|
-
window.history.back();
|
|
2443
|
-
}
|
|
2444
|
-
}, "back");
|
|
2445
|
-
const forward = /* @__PURE__ */ __name(() => {
|
|
2446
|
-
if (typeof window !== "undefined") {
|
|
2447
|
-
window.history.forward();
|
|
2448
|
-
}
|
|
2449
|
-
}, "forward");
|
|
2450
|
-
return {
|
|
2451
|
-
...state,
|
|
2452
|
-
push,
|
|
2453
|
-
replace,
|
|
2454
|
-
pushState,
|
|
2455
|
-
replaceState,
|
|
2456
|
-
back,
|
|
2457
|
-
forward
|
|
2458
|
-
};
|
|
2459
|
-
}
|
|
2460
|
-
__name(useRouter, "useRouter");
|
|
2461
|
-
function readRouterState(basePath, routeMatcher) {
|
|
2462
|
-
const url = readCurrentUrl();
|
|
2463
|
-
if (!url) {
|
|
2464
|
-
return {
|
|
2465
|
-
pathname: "/",
|
|
2466
|
-
searchParams: new URLSearchParams(),
|
|
2467
|
-
params: {},
|
|
2468
|
-
pageState: null
|
|
2469
|
-
};
|
|
2470
|
-
}
|
|
2471
|
-
const pathname = normalizeClientPathname(url.pathname, basePath);
|
|
2472
|
-
const i18n = getFarmI18nClientState();
|
|
2473
|
-
const routePathname = i18n ? stripFarmLocaleFromPathname(pathname, i18n) : pathname;
|
|
2474
|
-
return {
|
|
2475
|
-
pathname,
|
|
2476
|
-
searchParams: url.searchParams,
|
|
2477
|
-
params: routeMatcher?.match(routePathname)?.params || {},
|
|
2478
|
-
pageState: typeof window === "undefined" ? null : readPageState()
|
|
2479
|
-
};
|
|
2480
|
-
}
|
|
2481
|
-
__name(readRouterState, "readRouterState");
|
|
2482
|
-
function readCurrentUrl() {
|
|
2483
|
-
if (typeof window !== "undefined") {
|
|
2484
|
-
try {
|
|
2485
|
-
return new URL(window.location.href);
|
|
2486
|
-
} catch {
|
|
2487
|
-
return void 0;
|
|
2488
|
-
}
|
|
2489
|
-
}
|
|
2490
|
-
const request = _resolveCurrentRequest();
|
|
2491
|
-
if (!request) return void 0;
|
|
2492
|
-
try {
|
|
2493
|
-
return new URL(request.url);
|
|
2494
|
-
} catch {
|
|
2495
|
-
return void 0;
|
|
2496
|
-
}
|
|
2497
|
-
}
|
|
2498
|
-
__name(readCurrentUrl, "readCurrentUrl");
|
|
2499
|
-
function normalizeClientPathname(pathname, basePath) {
|
|
2500
|
-
return stripFarmBasePath(pathname, basePath);
|
|
2501
|
-
}
|
|
2502
|
-
__name(normalizeClientPathname, "normalizeClientPathname");
|
|
2503
|
-
function resolveClientHref(href, basePath) {
|
|
2504
|
-
if (!href) return void 0;
|
|
2505
|
-
return applyFarmBasePath(href, basePath);
|
|
2506
|
-
}
|
|
2507
|
-
__name(resolveClientHref, "resolveClientHref");
|
|
2508
|
-
|
|
2509
|
-
// src/navigation-errors.ts
|
|
2510
|
-
var REDIRECT_ERROR_CODE = "FARM_REDIRECT";
|
|
2511
|
-
var NOT_FOUND_ERROR_CODE = "FARM_NOT_FOUND";
|
|
2512
|
-
var REDIRECT_ERROR_SYMBOL = /* @__PURE__ */ Symbol.for("farm.navigation.redirect");
|
|
2513
|
-
var NOT_FOUND_ERROR_SYMBOL = /* @__PURE__ */ Symbol.for("farm.navigation.notFound");
|
|
2514
|
-
function redirect(url, status = 307) {
|
|
2515
|
-
throw createRedirectError(url, status);
|
|
2516
|
-
}
|
|
2517
|
-
__name(redirect, "redirect");
|
|
2518
|
-
function permanentRedirect(url) {
|
|
2519
|
-
redirect(url, 308);
|
|
2520
|
-
}
|
|
2521
|
-
__name(permanentRedirect, "permanentRedirect");
|
|
2522
|
-
function notFound() {
|
|
2523
|
-
const error = new Error(NOT_FOUND_ERROR_CODE);
|
|
2524
|
-
error.digest = NOT_FOUND_ERROR_CODE;
|
|
2525
|
-
error[NOT_FOUND_ERROR_SYMBOL] = true;
|
|
2526
|
-
throw error;
|
|
2527
|
-
}
|
|
2528
|
-
__name(notFound, "notFound");
|
|
2529
|
-
function isFarmRedirectError(error) {
|
|
2530
|
-
return Boolean(getFarmRedirectError(error));
|
|
2531
|
-
}
|
|
2532
|
-
__name(isFarmRedirectError, "isFarmRedirectError");
|
|
2533
|
-
function getFarmRedirectError(error) {
|
|
2534
|
-
if (!error || typeof error !== "object") return null;
|
|
2535
|
-
const candidate = error;
|
|
2536
|
-
if (candidate[REDIRECT_ERROR_SYMBOL]) {
|
|
2537
|
-
return candidate[REDIRECT_ERROR_SYMBOL];
|
|
2538
|
-
}
|
|
2539
|
-
if (typeof candidate.digest === "string" && candidate.digest.startsWith(`${REDIRECT_ERROR_CODE};`)) {
|
|
2540
|
-
const [, status, ...urlParts] = candidate.digest.split(";");
|
|
2541
|
-
const parsedStatus = Number(status);
|
|
2542
|
-
if (isFarmRedirectStatus(parsedStatus)) {
|
|
2543
|
-
return {
|
|
2544
|
-
status: parsedStatus,
|
|
2545
|
-
url: urlParts.join(";")
|
|
2546
|
-
};
|
|
2547
|
-
}
|
|
2548
|
-
}
|
|
2549
|
-
return null;
|
|
2550
|
-
}
|
|
2551
|
-
__name(getFarmRedirectError, "getFarmRedirectError");
|
|
2552
|
-
function isFarmNotFoundError(error) {
|
|
2553
|
-
if (!error || typeof error !== "object") return false;
|
|
2554
|
-
const candidate = error;
|
|
2555
|
-
return Boolean(candidate[NOT_FOUND_ERROR_SYMBOL] || candidate.digest === NOT_FOUND_ERROR_CODE);
|
|
2556
|
-
}
|
|
2557
|
-
__name(isFarmNotFoundError, "isFarmNotFoundError");
|
|
2558
|
-
function createRedirectError(url, status) {
|
|
2559
|
-
const error = new Error(`${REDIRECT_ERROR_CODE};${status};${url}`);
|
|
2560
|
-
error.digest = `${REDIRECT_ERROR_CODE};${status};${url}`;
|
|
2561
|
-
error[REDIRECT_ERROR_SYMBOL] = { url, status };
|
|
2562
|
-
return error;
|
|
2563
|
-
}
|
|
2564
|
-
__name(createRedirectError, "createRedirectError");
|
|
2565
|
-
function isFarmRedirectStatus(status) {
|
|
2566
|
-
return status === 301 || status === 302 || status === 303 || status === 307 || status === 308;
|
|
2567
|
-
}
|
|
2568
|
-
__name(isFarmRedirectStatus, "isFarmRedirectStatus");
|
|
2569
|
-
|
|
2570
|
-
// src/navigation.ts
|
|
2571
|
-
function useRouter2() {
|
|
2572
|
-
const router = useRouter();
|
|
2573
|
-
return {
|
|
2574
|
-
push: router.push,
|
|
2575
|
-
replace: router.replace,
|
|
2576
|
-
back: router.back,
|
|
2577
|
-
forward: router.forward,
|
|
2578
|
-
refresh() {
|
|
2579
|
-
if (typeof window === "undefined") return Promise.resolve();
|
|
2580
|
-
return getRouter().refresh();
|
|
2581
|
-
},
|
|
2582
|
-
prefetch(href) {
|
|
2583
|
-
if (typeof window === "undefined") return Promise.resolve();
|
|
2584
|
-
return getRouter().prefetch(applyFarmBasePath(href));
|
|
2585
|
-
}
|
|
2586
|
-
};
|
|
2587
|
-
}
|
|
2588
|
-
__name(useRouter2, "useRouter");
|
|
2589
|
-
function usePathname() {
|
|
2590
|
-
return useRouter().pathname;
|
|
2591
|
-
}
|
|
2592
|
-
__name(usePathname, "usePathname");
|
|
2593
|
-
function useSearchParams() {
|
|
2594
|
-
return useRouter().searchParams;
|
|
2595
|
-
}
|
|
2596
|
-
__name(useSearchParams, "useSearchParams");
|
|
2597
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
2598
|
-
0 && (module.exports = {
|
|
2599
|
-
getFarmRedirectError,
|
|
2600
|
-
isFarmNotFoundError,
|
|
2601
|
-
isFarmRedirectError,
|
|
2602
|
-
notFound,
|
|
2603
|
-
permanentRedirect,
|
|
2604
|
-
redirect,
|
|
2605
|
-
usePathname,
|
|
2606
|
-
useRouter,
|
|
2607
|
-
useSearchParams
|
|
2608
|
-
});
|
|
42
|
+
exports.getFarmRedirectError = _chunkOX6O6WVAcjs.getFarmRedirectError; exports.isFarmNotFoundError = _chunkOX6O6WVAcjs.isFarmNotFoundError; exports.isFarmRedirectError = _chunkOX6O6WVAcjs.isFarmRedirectError; exports.notFound = _chunkOX6O6WVAcjs.notFound; exports.permanentRedirect = _chunkOX6O6WVAcjs.permanentRedirect; exports.redirect = _chunkOX6O6WVAcjs.redirect; exports.usePathname = _chunkKVFPGF2Mcjs.usePathname; exports.useRouter = _chunkKVFPGF2Mcjs.useRouter; exports.useSearchParams = _chunkKVFPGF2Mcjs.useSearchParams;
|