// which section each doc sits in, its short label and its icon. the files in docs/ say
// what a page is, this says where it goes: every doc has to be in here exactly once,
// either as a page or as a section's index, and the build fails otherwise.
export interface NavPage {
doc: string;
label: string;
icon: string;
}
export interface NavSection {
id: string;
title: string;
/** a README that becomes the section's own page */
index?: string;
pages: NavPage[];
}
export const SECTIONS: NavSection[] = [
{
id: "guide",
title: "guide",
pages: [
{ doc: "README", label: "overview", icon: "hydrant" },
{ doc: "getting-started", label: "getting started", icon: "flag" },
{ doc: "configuration", label: "configuration", icon: "sliders" },
{ doc: "build-features", label: "build features", icon: "pieces" },
{ doc: "embedding", label: "embedding", icon: "chip" },
],
},
{
id: "concepts",
title: "concepts",
index: "concepts/README",
pages: [
{ doc: "concepts/vs-tap", label: "vs tap", icon: "scale" },
{ doc: "concepts/relay", label: "relay & seeding", icon: "waves" },
{ doc: "concepts/retention", label: "retention", icon: "hourglass" },
],
},
{
id: "streams",
title: "streams",
pages: [
{ doc: "api/stream", label: "/stream", icon: "stream" },
{ doc: "api/jetstream", label: "jetstream", icon: "jetstream" },
],
},
{
id: "management-api",
title: "management api",
index: "api/README",
pages: [
{ doc: "api/filter", label: "filter", icon: "funnel" },
{ doc: "api/repos", label: "repos", icon: "repo" },
{ doc: "api/ingestion", label: "ingestion", icon: "switch" },
{ doc: "api/crawler", label: "crawler", icon: "glass" },
{ doc: "api/firehose", label: "firehose", icon: "nozzle" },
{ doc: "api/pds", label: "pds", icon: "server" },
{ doc: "api/database", label: "database", icon: "cyl" },
],
},
{
id: "xrpc",
title: "xrpc",
index: "xrpc/README",
pages: [
{ doc: "xrpc/atproto", label: "com.atproto.*", icon: "globe" },
{ doc: "xrpc/hydrant", label: "systems.gaze.hydrant.*", icon: "globe:#ffd0c0:#a8200f" },
{ doc: "xrpc/identity", label: "identity", icon: "card" },
{ doc: "xrpc/repo", label: "repo", icon: "repo" },
{ doc: "xrpc/backlinks", label: "links", icon: "link" },
],
},
{
id: "internals",
title: "internals",
pages: [
{ doc: "specs/db-layer", label: "db layer", icon: "cyl:#e0e0e0:#5a5a5a" },
{ doc: "specs/block-gc", label: "record storage", icon: "trash" },
],
},
];
/** docs whose variable | default | description tables become a settings list + inspector */
export const SETTINGS_PAGES = ["configuration"];
/** icon for a section's index page in the home grid and in menus */
export const INDEX_ICON = "doc";
export interface Placement {
section: NavSection;
label: string;
icon: string;
/** true for a section's README */
isIndex: boolean;
}
export function placements(): Map<string, Placement> {
const out = new Map<string, Placement>();
for (const section of SECTIONS) {
if (section.index) {
out.set(section.index, { section, label: "overview", icon: INDEX_ICON, isIndex: true });
}
for (const page of section.pages) {
if (out.has(page.doc)) throw new Error(`nav lists ${page.doc} twice`);
out.set(page.doc, { section, label: page.label, icon: page.icon, isIndex: false });
}
}
return out;
}
/** every icon spec the site draws, so the sprite has them all */
export function iconSpecs(): string[] {
const specs = new Set(["hydrant", "glass", "sliders", INDEX_ICON]);
for (const s of SECTIONS) for (const p of s.pages) specs.add(p.icon);
return [...specs];
}