@blogmcp/nav-core
v0.2.1
Published
Framework-agnostic navigation tree core — types, validation, traversal, and immutable mutations for the KB information-architecture (menu) layer. Zero framework dependencies; consumed by the API service, MCP tools, and the blog SDK.
Maintainers
Readme
@blogmcp/nav-core
Framework-agnostic core for the KB navigation (menu) tree. Pure TypeScript — no
I/O, no framework. The design lives in
competitor-monitor/docs/internal/navigation-model.md.
This package is the shared logic surfaced two ways: the SDK runs it in-memory
over a cached tree, and the server exposes it as MCP/API tools. Mirrors the
@blogmcp/mdx-schema → renderer split.
Modules
| Import | Contents |
|---|---|
| @blogmcp/nav-core | everything (barrel) |
| @blogmcp/nav-core/types | node model: NavNode union, NavTree, FlatNode, LocalizedNode |
| @blogmcp/nav-core/validate | validate(tree, opts) / assertValid — cycles, depth, dangling refs, single-owner, data-bag caps |
| @blogmcp/nav-core/traverse | findNode, breadcrumbs, getSiblings, getNextPrev, getSubtree, flatten (FLAT), localize, prune, sortTree |
| @blogmcp/nav-core/mutate | insertNode, removeNode, moveNode, reorderChildren — immutable; throw NavMutationError |
Invariants
- Immutable: traversal and mutation never edit inputs; mutations return new trees.
- Server-authoritative: the API re-runs
validate()after every mutation. - Opaque
data: thedatabag is never interpreted, only size/depth-capped. - Single multilingual tree:
labelsis a per-locale map;localize()resolves to one locale with fallback + an optionallabelResolver(article titles come from the consumer — nav-core does not know article content).
Not here yet
The content→default-tree auto-builder and the auto-build ⊕ overrides merge ship with the API service slice (they need the article content index and the auto-append policy — see navigation-model.md §9).
Scripts
npm test --workspace=@blogmcp/nav-core # vitest
npm run build --workspace=@blogmcp/nav-core # tsc → dist