/** * hmem v2 — entries & nodes CRUD with ULID identity. * * Identity model (master-plan Goal #1): the ULID `uid` is the immutable primary * key and the only thing references point at; the human `label` (`P0048`) is * mutable display sugar. `seq` is a monotonic per-prefix counter — soft-deleted * labels are NEVER recycled, so a reference to a deleted entry stays dead rather * than silently resolving to a different entry. * * In-prose refs are stored as `{{u:}}` tokens. `renderRefs` turns those * back into the entry's *current* label at read time, so renaming a label * rewrites zero stored text. */ import type Database from 'better-sqlite3'; import type { EntryRow, NodeRow, Prefix } from './types.js'; export interface EntriesApi { createEntry(p: { prefix: Prefix; level_1: string; }): { uid: string; label: string; }; getEntry(uid: string): EntryRow | null; getEntryByLabel(label: string): EntryRow | null; labelToUid(label: string): string | null; uidToLabel(uid: string): string | null; renderRefs(text: string): string; relabel(uid: string, newLabel: string): boolean; /** Normalize the seq→label bijection for a prefix after a sync import may have * introduced a transient seq collision. Deterministic over the live set (order * by seq,uid: smallest keeps its seq, clashers bump to the next free seq), idempotent. * Bumps both seq and label and touches updated_at so the fix propagates via LWW. * Returns the number of rows changed. */ resolveLabelCollisions(prefix: string): number; addNode(p: { root_uid: string; parent_uid?: string; content: string; tags?: string[]; }): { uid: string; }; getNode(uid: string): NodeRow | null; updateNodeContent(uid: string, content: string): boolean; softDelete(uid: string): boolean; } export declare function createEntriesApi(db: Database.Database): EntriesApi;