/** How a {@link Collection} reads keys and builds views from raw records. */
export interface CollectionConfig<T, V> {
    items: T[];
    /** Primary id of a record (e.g. `u => u.id`, `a => a.ability_id`). */
    idOf: (item: T) => string;
    /**
     * Uniqueness key used for deduplication. Defaults to {@link idOf}. Set to a
     * composite (e.g. `(faction_id, id)`) for records that share an id across
     * factions, so distinct copies are preserved rather than collapsed.
     */
    dedupeKeyOf?: (item: T) => string;
    /** Display name, if the record has one — drives {@link Collection.find}. */
    nameOf?: (item: T) => string | undefined;
    /** Owning faction id, if applicable — drives {@link Collection.byFaction}. */
    factionOf?: (item: T) => string | null | undefined;
    /** Wrap a raw record in its linked view. */
    wrap: (item: T) => V;
}
/**
 * A collection of one entity type, exposing id/name/faction lookups.
 *
 * Iterable: `for (const unit of units) { … }`.
 *
 * @typeParam T - the raw (generated) record type
 * @typeParam V - the linked view type returned to callers
 */
export declare class Collection<T, V> implements Iterable<V> {
    private readonly items;
    private readonly byId;
    private readonly byNorm;
    private readonly byFactionId;
    private readonly idOf;
    private readonly nameOf?;
    private readonly wrapFn;
    constructor(cfg: CollectionConfig<T, V>);
    /** Every record, deduplicated by id, in first-seen order. */
    get all(): V[];
    /** Number of distinct records. */
    get size(): number;
    /** Look up by exact id. */
    get(id: string): V | undefined;
    /**
     * Look up by exact id *within a faction*. Use this when an id is shared
     * across factions (e.g. `chaos-land-raider` lives under five Chaos factions)
     * and a faction context is known — {@link get} would return whichever copy
     * was registered first, which may belong to the wrong faction. Returns
     * `undefined` when no record with that id belongs to `factionId`.
     */
    getInFaction(id: string, factionId: string): V | undefined;
    /** Whether a record with this exact id exists. */
    has(id: string): boolean;
    /**
     * Find one record by id or name. Name matching is diacritic- and
     * punctuation-insensitive (see {@link normalizeName}), trying, in order:
     * exact id → exact normalized name → normalized-name substring. Returns the
     * first match; names can repeat across factions, so use {@link findAll} or
     * {@link byFaction} when a query may be ambiguous.
     *
     * @example
     * units.find("Kharn"); // resolves "Khârn the Betrayer"
     */
    find(query: string): V | undefined;
    /**
     * All records matching a query, by the same rules as {@link find}. An exact id
     * match returns just that record; otherwise every normalized-name-exact match
     * is returned, falling back to every normalized-name-substring match. Useful
     * to surface (rather than silently collapse) names shared across factions.
     */
    findAll(query: string): V[];
    /** All records belonging to a faction id (empty if the type has no faction). */
    byFaction(factionId: string): V[];
    [Symbol.iterator](): Iterator<V>;
}
//# sourceMappingURL=collection.d.ts.map