Extend search hub/panel live regions with active channel context and mesh notes; tighten search-errors reaction bleed exclusion; refresh composer search hints for hub and panel; platform guild.search.cache/mesh spans include activeChannelId; agentctl and phase627 smoke bundle.
pearcord-db
Local persistence for Pearcord: HyperDB (RocksDB) when the schema is built, with automatic fallback to a JSON file store.
Mission
Offer one LocalDatabase class that serializes all reads/writes, picks the best engine at runtime, and exposes a minimal insert / get / find / delete API aligned with @pearcord/* collections from pearcord-shared.
When to use / not
Use when:
- Any module needs durable guild, user, message, or invite rows on disk.
- You want engine-agnostic storage (
hyperdbvsjson) without branching in callers.
Do not use when:
- You only need in-memory structures or P2P gossip without local materialization.
- You need Autobase multi-writer replication — planned in
pearcord-sync(not wired yet).
Public API
| Export | Role |
|---|---|
LocalDatabase |
Main facade (storagePath → db/ directory) |
LocalDatabase#ready() |
Opens HyperDB or JsonStore backend |
LocalDatabase#insert(collection, record) |
Upsert by collection primary key |
LocalDatabase#get(collection, query) |
Single-row lookup |
LocalDatabase#find(collection, query, opts?) |
Query; supports { limit }; normalizes async iterators |
LocalDatabase#delete(collection, query) |
Remove matching row |
LocalDatabase#close() |
Close backend |
LocalDatabase#getEngine() |
'hyperdb' or 'json' |
hasHyperDB |
true if hyperdb + generated spec/hyperdb loaded |
jsonStoreHasUsers(storagePath) |
Migration probe: legacy JSON has users |
JsonStore |
Subpath export pearcord-db/store-json — standalone JSON backend |
LocalDatabase uses an internal promise chain (_serialize) so concurrent mutations do not interleave.
P2P surface
None. This module is local-only. Peers replicate via gossip into the same collections on other devices; pearcord-guild writes inbound RPC payloads through platform handlers that call db.insert.
Storage
| Engine | Path | When |
|---|---|---|
| HyperDB | {storagePath}/ (RocksDB files) |
hyperdb installed and spec/hyperdb/index.js exists after npm run build:schema |
| JSON | {storagePath}/pearcord-db.json |
Fallback if HyperDB unavailable, or HyperDB empty while JSON already has users |
Platform default path: {PEARCORD_STORAGE or ~/.config/pearcord}/db.
DM metadata uses a separate JsonStore at {storagePath}/dm-meta (platform-only).
Platform integration
const { LocalDatabase } = require('pearcord-db')
// PearcordPlatform constructor:
this.dbPath = path.join(this.storagePath, 'db')
this.db = new LocalDatabase(this.dbPath)
Shared by pearcord-identity, pearcord-guild, pearcord-message, pearcord-invite, and direct platform queries (listGuilds, search, audit). Platform checks this.db.getEngine() for HyperDB-optimized message scans.
UI / IPC
No direct UI dependency. All IPC flows go through pearcord-platform, which owns the single LocalDatabase instance per session.
Related docs
- HYPERDB.md — schema build, collections, v9
replyToId - MODULES.md — dependency graph
- ARCHITECTURE.md — storage layout
- GETTING_STARTED.md —
PEARCORD_STORAGE - AUTOMATED_TESTING.md — schema smoke targets
Tests
From apps/pearcord:
npm run test:hyperdb—smoke-hyperdb.cjsnpm run test:schema-v9—smoke-schema-v9.cjs
Both use LocalDatabase and hasHyperDB from this package.
Code example
const path = require('bare-path')
const { LocalDatabase } = require('pearcord-db')
const { COLLECTIONS, id, now } = require('pearcord-shared')
const db = new LocalDatabase(path.join('/tmp/pearcord-demo', 'db'))
await db.ready()
console.log('engine:', db.getEngine())
await db.insert(COLLECTIONS.USERS, {
id: id(),
username: 'alice',
createdAt: now()
})
const users = await db.find(COLLECTIONS.USERS, {})
await db.close()
Build HyperDB schema:
cd modules/pearcord-db && npm install && npm run build:schema
Repository
Part of Pearcord.
- Org:
pearcord - Clone:
git clone https://git.ssh.surf/pearcord/pearcord-db.git - Install:
npm install git+https://git.ssh.surf/pearcord/pearcord-db.git#main