plgg-content
v0.0.1
Published
A derived, rebuildable SQLite index over a git-primary Markdown corpus, with an HTTP-agnostic MicroCMS-like read-only query API and always-on FTS5 (BM25) search, built on the plgg family
Readme
plgg-content
UNSTABLE — Experimental study work (POC). Part of the plgg monorepo.
A derived, rebuildable SQLite index over a git-primary Markdown corpus, with an HTTP-agnostic, MicroCMS-like read-only query API and always-on FTS5 (BM25) search, built from scratch on the plgg family (plgg-md, plgg-sql, plgg-db-migration).
The governing decision is D4: content is git/filesystem-primary; SQLite is a
derived, rebuildable index. Every row is reconstructable from the Markdown —
losing the database costs nothing but a rebuildIndex. The primary operation is
therefore a full, idempotent rebuild; incremental indexDocument /
removeDocument are optimizations over it.
HTTP-free query core
The query surface is plain typed Db-taking functions, not an HTTP
framework — the same functions back the SPA delivery API, the admin UI, the MCP
tools, and the Claude Code plugin export. An HTTP layer (e.g. plggpress's /api
mount) is a thin adapter over them.
import {
openIndex,
registerCollection,
indexDocument,
rebuildIndex,
listCollection,
getDocument,
searchIndex,
} from "plgg-content";
// open a ready index (schema created idempotently)
const db = /* Ok */ await openIndex("content.db");
// ingest already-validated pages (ticket-17 content models
// validate upstream; plgg-content stores + serves)
await rebuildIndex(db)(pages);
// MicroCMS-style delivery
await listCollection(db)("blog", listQuery); // { contents, totalCount, limit, offset }
await getDocument(db)("blog", "/blog/hello"); // Option<Document>
await searchIndex(db)("kangaroo", 10); // BM25-ranked hits, no LLM key neededDesign
- Schema (
Schema/) —documents(one row per page, typed frontmatter serialized),chunks(heading-scoped RAG/search granularity),collections(serializedCollectionSchema), and an external-content FTS5 table overchunkswith its sync triggers — all emitted through plgg-sql's FTS5 builders (no raw FTS5 SQL). The schema is created idempotently viaexecScript(D4: the whole DB is rebuildable, so no versioned ledger). - Ingest (
Ingest/) — a pure heading-scopedchunkBlocksfold over plgg-md'sBlockAST, a transactional idempotentindexDocument(skips an unchangedcontent_hash), andrebuildIndex(ingest- prune vanished paths).
- Query (
Query/) —listCollections/listCollection/getDocument/searchIndex, plus theListQuerycaster (boundedlimit, closedorderBy, sanitizedq) and the serializableCollectionSchema. - vendors/ — the only driver-aware code: the
node:sqliteimplementation of plgg-sql'sDbseam.
The only runtime dependencies are plgg, plgg-md, plgg-sql, and
plgg-db-migration; it is plggpress-agnostic (plggpress depends on it, never
the reverse).
