@maschinenlesbar.org/openka-cli
    Preparing search index...

    Interface Store

    The corpus, as the roles that make it up.

    Store is their intersection and nothing in the codebase has to change because of the split — but a consumer that only reads the catalog can now say so, and a test double for it does not have to implement blob addressing, index sharding and artifact storage to compile. DiscoverOptions already took this shape by hand (Pick<Store, "loadArtifact">); these are the seams it was reaching for.

    The file store draws exactly these lines with section separators, which is the class saying out loud that it is nine concerns wearing one name.

    interface Store {
        root: string;
        assertBlobStore?(): void;
        batchCatalog<T>(work: () => Promise<T>): Promise<T>;
        blobDigests(): string[];
        blobPath(sha256: string): string;
        catalog(): CatalogEntry[];
        catalogEntry(id: string): CatalogEntry | undefined;
        deleteBlob(sha256: string): void;
        deleteRecord(id: string): void;
        getBlob(sha256: string): Buffer;
        getRecord(id: string): KaRecord | undefined;
        getRecordBytes(id: string): Buffer<ArrayBufferLike> | undefined;
        getSourceState(source: string): SourceState;
        hasBlob(sha256: string): boolean;
        hasRecord(id: string): boolean;
        loadArtifact<T>(name: string): T | undefined;
        loadEmbeddings(): EmbeddingSet | undefined;
        loadShard(shard: string): IndexShard;
        lock?(purpose: string): () => void;
        putBlob(data: Buffer): string;
        putCatalogEntries(entries: readonly CatalogEntry[]): void;
        putCatalogEntry(entry: CatalogEntry): void;
        putRecord(record: KaRecord): void;
        putSourceState(state: SourceState): void;
        queuePostings?(shard: string, change: PostingChange): boolean;
        recordIds(): string[];
        removeCatalogEntry(id: string): void;
        replaceCatalog(entries: readonly CatalogEntry[]): void;
        saveArtifact(name: string, value: unknown): void;
        saveEmbeddings(set: EmbeddingSet): void;
        saveShard(shard: string, data: IndexShard): void;
        shardNames(): string[];
        sourceStateKeys(): string[];
    }

    Hierarchy (View Summary)

    Implemented by

    Index
    root: string

    Absolute path of the corpus root, for messages and ka open.

    • Throw StoreError when the blobs cannot be reached at all — a blob directory on a drive that is not mounted. Optional: a store whose blobs are always there (the in-memory double) has nothing to check.

      Returns void

    • Run work with catalog writes deferred, and persist the catalog once when it returns — also when it throws, so an interrupted run keeps what it indexed.

      putCatalogEntry persists on every call, which is the right default for a one-off caller and the wrong shape for a sync: indexing a record at a time re-read and rewrote the whole catalog per record, quadratic in the corpus. The pipeline wraps its record loop in this; nested batches flush once, at the outermost, and concurrent ones each at their own end.

      Type Parameters

      • T

      Parameters

      • work: () => Promise<T>

      Returns Promise<T>

    • The digest of every blob held, sorted.

      Returns string[]

    • Filesystem path of a stored blob — what ka open hands to the OS.

      Parameters

      • sha256: string

      Returns string

    • Remove a stored blob; nothing happens when there is none. ka rm --blobs only (issue #28).

      Parameters

      • sha256: string

      Returns void

    • Parameters

      • id: string

      Returns void

    • Parameters

      • sha256: string

      Returns Buffer

    • Parameters

      • id: string

      Returns KaRecord | undefined

    • Canonical bytes of a stored record, exactly as they sit on disk.

      Parameters

      • id: string

      Returns Buffer<ArrayBufferLike> | undefined

    • Parameters

      • sha256: string

      Returns boolean

    • Parameters

      • id: string

      Returns boolean

    • A frozen artifact the factory built and the line consumes — see CONCEPT.md §0. Named, JSON, and written once by a build-time job rather than by a sync.

      Type Parameters

      • T

      Parameters

      • name: string

      Returns T | undefined

    • Take the corpus for writing, or throw CorpusLockedError when another run holds it. Returns the release. Re-entrant within one store object, so a writer may call another writer; withCorpusLock is the usual way in.

      Parameters

      • purpose: string

      Returns () => void

    • Store bytes under their own digest; returns the digest. Idempotent.

      Parameters

      • data: Buffer

      Returns string

    • Insert or replace many rows and persist once.

      putCatalogEntry rewrites the whole catalog on every call, so building an index a record at a time wrote it N times — 5.6 MiB to land a 153 KiB file for 200 records, quadratic in the corpus.

      Parameters

      Returns void

    • Inside batchCatalog: keep a change to shard's postings and apply it when the batch ends, with every other change to that shard, before the catalog is written. Returns false outside a batch, and the caller applies the change at once. Optional: a store without it applies every change at once (issue #30).

      Parameters

      Returns boolean

    • Every record id in the corpus, sorted.

      Returns string[]

    • Parameters

      • id: string

      Returns void

    • Replace every catalog row with entries and persist, without reading what is there. That is what a rebuild needs: ka reindex read the old catalog in order to clear it, so a corrupt catalog was the one thing it could not repair.

      Parameters

      Returns void

    • Parameters

      • name: string
      • value: unknown

      Returns void

    • Every index shard present, sorted.

      Returns string[]

    • Every source that has state in this corpus, sorted — including one that synced and stored nothing. The health report needs it: a source is otherwise only visible through the records it produced, so the very case worth flagging (discovery returned nothing) is the case that leaves no trace.

      Returns string[]