Docs

@avelonjs

docs-site

Docs site

@avelonjs/docs-site

@avelonjs/docs-site builds the Avelon documentation site from the same Markdown the repo already ships. The landing page is the Avelon map: vocabulary, then the commands and types you reach for. Fenced examples are syntax-colored. Reach for this package when you need to regenerate index.html after a README or catalog change.

Installation

bun install

This package lives in the Avelon workspace. You run it from the repository, not as an application dependency.

Basic Usage

import { mkdir } from 'node:fs/promises'
import { buildSite } from '@avelonjs/docs-site'

await mkdir('/tmp/avelon-docs', { recursive: true })
await buildSite({
  repoRoot: process.cwd(),
  outDir: '/tmp/avelon-docs',
})
bun run build

build writes dist/index.html as the Avelon map, dist/packages/<name>/index.html from each package README, and dist/drivers/index.html from docs/15-driver-authoring.md.

Landing page

The first page is the map of the framework. A vocabulary table names the Avelon words. Catalog sections then list what you want, what you reach for, and a one-line note. Package READMEs are not the homepage; they hang off /packages.

Presentation

The static renderer and interactive docs share the Avelon wordmark, five-layer poster geometry, semantic tokens, and appearance behavior. Static layout, typography, and focus rules apply under body.docs-static, so interactive renderers retain their own stylesheet cascade. The initial appearance is system. It follows the operating-system preference until a reader selects light or dark; the selected appearance is stored under avelon-docs-appearance. The root element exposes the selected appearance through data-appearance and the resolved result through data-theme.

import { resolveDocsTheme } from '@avelonjs/docs-site'

const theme = resolveDocsTheme('system', true)

Browser components import presentation data from the server-free subpath:

import { AVELON_POSTER_LAYERS, type DocsAppearance } from '@avelonjs/docs-site/presentation'

const appearance: DocsAppearance = 'system'
const firstLayer = AVELON_POSTER_LAYERS[0]

The static stylesheet requests no remote font assets. It uses installed local copies of Inter and IBM Plex Mono when present, then falls back to the system sans and monospace stacks. The Next docs app bundles both families through next/font.

Method Reference

Method / exportSignatureDescription
CATALOGreadonly CatalogSection[]Grouped jobs and Avelon names rendered as the landing tables.
CatalogRowinterfaceterm, youReachFor, and notes.
CatalogSectioninterfacetitle plus rows.
VOCABULARYreadonly VocabularyEntry[]Named Avelon words and one-line jobs.
VocabularyEntryinterfacename and job.
VocabularyLabelinterfacePlain primary label and Avelon aka name.
guideLabelFor(slug: string) => VocabularyLabel | undefinedLooks up a guide label by document slug.
packageRoleFor(name: string) => VocabularyLabel | undefinedLooks up a package role by unscoped name.
buildSite(options: BuildSiteOptions) => Promise<BuildSiteResult>Writes index.html and derived pages.
buildFromRepo() => Promise<BuildSiteResult>Builds into this package's dist/ from the repo root.
BuildSiteOptionsinterfacerepoRoot and outDir.
BuildSiteResultinterfacelandingPage and pages.
DocsAppearance'system' | 'light' | 'dark'Reader preference before system resolution.
DocsTheme'light' | 'dark'Resolved visual theme.
DOCS_APPEARANCE_STORAGE_KEY'avelon-docs-appearance'Browser storage key for the appearance preference.
DOCS_APPEARANCE_SCRIPTstringPre-paint script that applies and persists appearance.
resolveDocsTheme(appearance: DocsAppearance, systemDark: boolean) => DocsThemeResolves an appearance preference.
DOCS_PRESENTATION_CSSstringShared semantic CSS for documentation renderers.
AVELON_WORDMARK_PATHSreadonly string[]SVG paths for the Avelon wordmark.
AvelonPosterLayerinterfaceA giant-A poster layer with offset and path.
AVELON_POSTER_LAYERSreadonly AvelonPosterLayer[]SVG paths for the five-layer poster.
markdownToHtml(source: string) => stringConverts house-style Markdown to HTML, with syntax-colored fences.
headingId(text: string) => stringStable slug for a heading, used as the HTML id.
escapeHtml(value: string) => stringEscapes text for HTML.

Testing

import { mkdtemp } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { buildSite } from '@avelonjs/docs-site'

const outDir = await mkdtemp(join(tmpdir(), 'avelon-docs-'))
const result = await buildSite({ repoRoot: process.cwd(), outDir })
await Bun.file(result.landingPage).text()
bun test
bun run typecheck
reeve docs:check