@alpaca-software/40kdc-data
    Preparing search index...

    Interface CollectionConfig<T, V>

    How a Collection reads keys and builds views from raw records.

    interface CollectionConfig<T, V> {
        items: T[];
        idOf: (item: T) => string;
        dedupeKeyOf?: (item: T) => string;
        nameOf?: (item: T) => string | undefined;
        aliasesOf?: (item: T) => readonly string[] | null | undefined;
        idAliases?: Readonly<Record<string, string>>;
        factionOf?: (item: T) => string | null | undefined;
        guardUnscoped?: boolean;
        entityLabel?: string;
        wrap: (item: T) => V;
    }

    Type Parameters

    • T
    • V
    Index

    Properties

    items: T[]
    idOf: (item: T) => string

    Primary id of a record (e.g. u => u.id, a => a.ability_id).

    dedupeKeyOf?: (item: T) => string

    Uniqueness key used for deduplication. Defaults to 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.

    nameOf?: (item: T) => string | undefined

    Display name, if the record has one — drives Collection.find.

    aliasesOf?: (item: T) => readonly string[] | null | undefined

    Alternate names a record answers to (spelling variants from other tools' exports). Indexed alongside nameOf so Collection.find / Collection.findAll match an alias exactly, but never returned as the record's display name. The canonical name always wins a collision.

    idAliases?: Readonly<Record<string, string>>

    Renamed-id map (old id → current id), consulted by id lookups (Collection.get/Collection.getAny/Collection.getInFaction/ Collection.has) only when the exact id misses. Lets a persisted reference to a since-renamed id (e.g. a saved roster or share link authored before an enhancement id was normalized) still resolve to the current record. The map is expected to be pre-flattened (each key maps directly to a terminal live id), so a single hop suffices. Typically the share registry's aliases.

    factionOf?: (item: T) => string | null | undefined

    Owning faction id, if applicable — drives Collection.byFaction.

    guardUnscoped?: boolean

    When set, a faction-less Collection.get of an id that exists under more than one faction throws outside production (see module docs). Use for collections whose per-faction copies diverge (units), so callers are forced to pass faction via Collection.getInFaction or opt out explicitly with Collection.getAny. Requires factionOf.

    entityLabel?: string

    Noun used in the guardUnscoped throw message (e.g. "unit", "detachment"). Defaults to "entity". Cosmetic — steers the error toward the right collection without changing behaviour.

    wrap: (item: T) => V

    Wrap a raw record in its linked view.