From e224690049084ecf465e308dbbd77dca02eefd09 Mon Sep 17 00:00:00 2001 From: t8y2 Date: Sun, 4 Oct 2026 21:09:41 +0800 Subject: [PATCH] feat(docs): detect ARM platforms and badge the current-platform bundle --- docs/app/[lang]/drivers/DriversClient.tsx | 56 +++++++++++++++++++++-- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/docs/app/[lang]/drivers/DriversClient.tsx b/docs/app/[lang]/drivers/DriversClient.tsx index b7f899f0f3..b656302637 100644 --- a/docs/app/[lang]/drivers/DriversClient.tsx +++ b/docs/app/[lang]/drivers/DriversClient.tsx @@ -19,6 +19,7 @@ const i18n = { jdbcPluginInstallHint: "Import this ZIP in DBX from Settings > Driver Manager > JDBC Drivers > Local Install.", bundles: "Offline Bundles", bundlesDesc: "Platform-specific ZIP packages that include the agent registry, database drivers, native agents, and the matching JRE.", + currentPlatform: "Current platform", drivers: "Database Drivers", driversDesc: "Single-driver .tar.zst packages for Java agents. Install the matching JRE separately when it is not already available.", nativeAgents: "Native Agents", @@ -76,6 +77,7 @@ const i18n = { jdbcPluginInstallHint: "在 DBX 的“设置 > 驱动管理 > JDBC 驱动 > 本地安装”中导入这个 ZIP。", bundles: "整包下载", bundlesDesc: "按平台提供的 ZIP 离线包,包含 Agent registry、数据库驱动、原生 Agent 和匹配的 JRE。", + currentPlatform: "当前平台", drivers: "数据库驱动", driversDesc: "Java Agent 的单驱动 .tar.zst 包;目标机器尚未安装 JRE 时需要另外安装一次对应 JRE。", nativeAgents: "原生 Agent", @@ -139,6 +141,32 @@ function detectBundlePlatform(): string { return "windows-x64"; } +/** + * Apple Silicon Macs report "Intel Mac OS X" in their UA, so the sync pass + * defaults them to the x64 build. Chromium-based browsers expose the real CPU + * architecture via the async User-Agent Client Hints API; Safari and Firefox + * keep the UA-based guess. + */ +async function refineBundlePlatformWithHints(): Promise { + const uaData = ( + navigator as Navigator & { + userAgentData?: { getHighEntropyValues?: (hints: string[]) => Promise<{ architecture?: string }> }; + } + ).userAgentData; + if (!uaData?.getHighEntropyValues) return null; + try { + const hints = await uaData.getHighEntropyValues(["architecture"]); + if (hints.architecture !== "arm" && hints.architecture !== "arm64") return null; + const ua = navigator.userAgent; + if (/Macintosh|Mac OS/i.test(ua)) return "macos-aarch64"; + if (/Windows/i.test(ua)) return "windows-aarch64"; + if (/Linux|X11/i.test(ua)) return "linux-aarch64"; + return null; + } catch { + return null; + } +} + function platformKey(j: JreDisplayEntry): string { return `${j.jreKey}-${j.platformKey}`; } @@ -197,6 +225,7 @@ export function DriversClient({ initialCatalog, initialRegistry }: { initialCata const [selectedNativePlatforms, setSelectedNativePlatforms] = useState>({}); const [bundlePlatform, setBundlePlatform] = useState("windows-x64"); + const [detectedPlatform, setDetectedPlatform] = useState(null); const [selectedKeys, setSelectedKeys] = useState>(() => new Set()); const [includeJre, setIncludeJre] = useState(false); const [bundleSource, setBundleSource] = useState("cnb"); @@ -205,6 +234,7 @@ export function DriversClient({ initialCatalog, initialRegistry }: { initialCata const [bundleError, setBundleError] = useState(null); const [bundleDone, setBundleDone] = useState(null); const bundleAbortRef = useRef(null); + const platformTouchedRef = useRef(false); const bundles = catalog?.bundles ?? []; const drivers = catalog?.drivers ?? []; @@ -267,8 +297,22 @@ export function DriversClient({ initialCatalog, initialRegistry }: { initialCata useEffect(() => { // Detected after hydration: the prerendered HTML cannot know the visitor's - // platform, and a differing initial state would hydration-mismatch. - setBundlePlatform(detectBundlePlatform()); + // platform, and a differing initial state would hydration-mismatch. The + // detected platform also badges the matching full-bundle row, so it is kept + // separately from the custom-tab selector the visitor may re-target. + const initial = detectBundlePlatform(); + setDetectedPlatform(initial); + setBundlePlatform(initial); + let cancelled = false; + refineBundlePlatformWithHints().then((refined) => { + if (cancelled || !refined) return; + setDetectedPlatform(refined); + // Never override a platform the visitor picked while the hint resolved. + if (!platformTouchedRef.current) setBundlePlatform(refined); + }); + return () => { + cancelled = true; + }; }, []); const bundleOptions = useMemo(() => buildCustomBundleOptions(initialRegistry, bundlePlatform), [initialRegistry, bundlePlatform]); @@ -290,6 +334,7 @@ export function DriversClient({ initialCatalog, initialRegistry }: { initialCata }; const changeBundlePlatform = (platformKey: string) => { + platformTouchedRef.current = true; setBundlePlatform(platformKey); setSelectedKeys(new Set()); }; @@ -394,10 +439,10 @@ export function DriversClient({ initialCatalog, initialRegistry }: { initialCata
-
+
-

{t.title}

+

{t.title}

{t.subtitle}

@@ -525,6 +570,9 @@ export function DriversClient({ initialCatalog, initialRegistry }: { initialCata
{bundle.platformLabel} + {bundle.platformKey === detectedPlatform && ( + {t.currentPlatform} + )} ZIP