import { type SigDbPkgMeta, type SigDbShard, type SigDbTier } from './schema';
import type { ByteRange, SigDbIndexWire, SigShardIndexWire } from './index-format';
export declare const SigDbManifestMagic = "flowr-sigdb-manifest";
export declare const SigDbManifestSchema = 2;
/** shared-dictionary descriptor in a {@link SigDbManifest}: where it lives and how to seek/verify it */
export interface SigDbDictRef {
    id: string;
    path: string;
    hash: string;
    range: ByteRange;
    byteCount: number;
    strings: number;
}
/** one shard within a {@link SigDbManifest} */
export interface SigDbShardRef {
    /** stable id, e.g. `current-top` */
    id: string;
    tier: SigDbTier;
    shard?: SigDbShard;
    topN?: number;
    /** path to the shard's `.sigs.ndjson` (relative to the manifest); the `.br` alongside is used when only it ships */
    path: string;
    hash: string;
    packages: number;
    versions: number;
    /** id of the shared dictionary this shard's blobs reindex into (see {@link SigDbManifest.dicts}) */
    dict?: string;
    /**
     * the shard's compact index embedded in the manifest (without its own `meta`/`d` -- those are shared). A
     * reader routes and seeks from the manifest alone, needing only the `.br` files (no `.idx` sidecars).
     */
    idx?: SigDbIndexWire | SigShardIndexWire;
}
/** a set of shard files (and shared dictionaries) plus the routing needed to read them as one database */
export interface SigDbManifest {
    format: string;
    schema: number;
    date: string;
    generated: number;
    cranBase?: string;
    /** package metadata, hoisted here once and shared by every shard (they hold overlapping package sets) */
    meta?: Record<string, SigDbPkgMeta>;
    /** shared string dictionaries; a shard references one by id (they are stored once, not per shard) */
    dicts?: SigDbDictRef[];
    shards: SigDbShardRef[];
}
/** write a {@link SigDbManifest} (compact JSON) plus a compressed copy per available codec (`.br` always, `.zst` when supported) beside it */
export declare function writeManifest(file: string, manifest: SigDbManifest): void;
/** read a manifest file (transparently decompressing a `.br`/`.zst`/`.gz`) */
export declare function readManifestFile(manifestFile: string): SigDbManifest;
/**
 * The `date` of a manifest without parsing the rest of it, whose `meta` is megabytes of packages.
 * Falls back to a full parse if the date is not where we expect it.
 */
export declare function readManifestDate(manifestFile: string): string | undefined;
/** breadth/temporal scope of a bundled sigdb: base R only, `current` (latest CRAN + base R), or the `full` history */
export type SigDbScope = 'base' | 'current' | 'full';
/**
 * Location of a bundled sigdb **manifest**, found by walking up from several roots (this module,
 * `$FLOWR_SIGDB_DIR`, the working directory) across the dev (`src`), build (`dist`) and data-mount
 * layouts. With no `scope` it returns the richest available (`full` &gt; `current` &gt; `base`), so a
 * container that ships the full set uses it automatically while a plain npm install falls back to the
 * bundled `base`. Node only (needs `fs`); pass `searchRoots` to override where it looks.
 */
export declare function defaultSigDbPath(scope?: SigDbScope, searchRoots?: readonly string[]): string | undefined;
/**
 * Every distinct sigdb bundle discoverable in the search dirs (see {@link defaultSigDbPath}) -- not just the
 * richest scope. So dropping an extra bundle next to the shipped default (a downloaded full-history
 * `full.manifest.json.br`, a custom `*.manifest.json`, or a standalone `*.sigs.ndjson`) makes flowR mount it
 * automatically. Manifests come first (scope-named leading, richest scope first), then standalone bundles; the
 * shard and dictionary files a manifest already owns are skipped. Deduped by filename, first search location wins.
 */
export declare function defaultSigDbPaths(searchRoots?: readonly string[]): string[];
