diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-09-01 14:48:45 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-09-01 14:48:45 +0300 |
| commit | 8a6d697308162874a236c84aac0b0f8c7ac01f83 (patch) | |
| tree | ed7dc7e8c6f50d66bde721fae78576aede929f66 /website/src/site-data.ts | |
| parent | b54a78aa510b87d1e3b56c619b72eaeb59e4a2a1 (diff) | |
refactor: separate website presentation from runtime
Diffstat (limited to 'website/src/site-data.ts')
| -rw-r--r-- | website/src/site-data.ts | 103 |
1 files changed, 0 insertions, 103 deletions
diff --git a/website/src/site-data.ts b/website/src/site-data.ts deleted file mode 100644 index 94836fe7..00000000 --- a/website/src/site-data.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { readdir, readFile } from 'node:fs/promises'; -import { resolve } from 'node:path'; - -/* The numbers the site's chrome shows, resolved once per build. - Stars, installs and plugin counts come from the same R2 snapshots /stats/ - and /plugins/ read; the version comes from latest.json, which release CI - owns. Nothing here is hand-maintained, so no figure on the site can go - stale independently of a deploy. - - Memoised because SiteLayout renders on every blog post, and a build that - renders many pages should still fetch once. */ - -export type SiteStats = { - starCount?: number; - installCount?: number; - pluginCount?: number; -}; - -async function snapshot(url: string): Promise<any | null> { - try { - const res = await fetch(url); - return res.ok ? await res.json() : null; - } catch { - return null; - } -} - -async function load(): Promise<SiteStats> { - const [stats, plugins] = await Promise.all([ - snapshot('https://assets.herdr.dev/stats/stats.json'), - snapshot('https://assets.herdr.dev/plugins/index.json'), - ]); - - return { - starCount: stats?.stars?.total, - installCount: stats?.downloads - ? (stats.downloads.github || 0) + (stats.downloads.brew || 0) - : undefined, - /* `pluginCount` counts validated manifests, which is what the marketplace - lists. `source.totalCount` is the raw GitHub topic search and still - includes blacklisted repositories and ones with no manifest. */ - pluginCount: plugins?.pluginCount ?? plugins?.plugins?.length, - }; -} - -let statsPromise: Promise<SiteStats> | null = null; - -export function siteStats(): Promise<SiteStats> { - statsPromise ??= load(); - return statsPromise; -} - -/* latest.json carries the full release notes, so read and pick rather than - importing it and bundling all of that into the page. */ -async function readVersion(): Promise<string | null> { - try { - const raw = await readFile(new URL('../latest.json', import.meta.url), 'utf8'); - return JSON.parse(raw).version ?? null; - } catch { - return null; - } -} - -let versionPromise: Promise<string | null> | null = null; - -export function releaseVersion(): Promise<string | null> { - versionPromise ??= readVersion(); - return versionPromise; -} - -/* How many agents Herdr detects out of the box, counted from the bundled - manifests. The site is built from the same repo as the binary, so the number - tracks the code and cannot drift the way a written-down one would — add a - manifest and the homepage says so on the next deploy. */ -async function countAgentManifests(): Promise<number | null> { - /* Resolved from cwd, not import.meta.url: once Vite bundles this module for - the build the module URL no longer points at the source file, so a - relative URL silently found nothing and the line vanished from dist while - still rendering in dev. Both candidates cover running the build from - website/ or from the repo root. */ - for (const rel of ['../src/detect/manifests', 'src/detect/manifests']) { - try { - const files = await readdir(resolve(process.cwd(), rel)); - const count = files.filter((f) => f.endsWith('.toml')).length; - if (count > 0) return count; - } catch { - /* try the next candidate */ - } - } - return null; -} - -let agentCountPromise: Promise<number | null> | null = null; - -export function agentCount(): Promise<number | null> { - agentCountPromise ??= countAgentManifests(); - return agentCountPromise; -} - -/* A fetch that failed at build shows an em dash. A stale hardcoded number - would look authoritative and be wrong, which is worse. */ -export const fmt = (n: unknown): string => - typeof n === 'number' ? n.toLocaleString('en-US') : '—'; |
