@versatiles/style
    Preparing search index...

    Type Alias DiagnosticData

    Every diagnostic a migration can report, with the payload it carries.

    The payload is typed per code rather than left an open record, because for the codes that matter most the payload is the diagnostic: color.conflict is worth reporting only if a consumer can read the colours out of it and offer them as a choice, and an untyped field would force a cast at exactly that point. Typing it later would be a breaking change, so the map exists from the start even while it is short.

    Adding a code is not breaking for a consumer that switches on the ones it knows and prints message for the rest.

    There is no vote.tie of its own, and that rests on an invariant worth stating: every payload whose value was chosen by a vote exposes its tally, as a count or as an array whose length is the count. A tie is then two equal counts, which a consumer can see without a second code saying so. A vote-based payload added without a tally would break this quietly, and vote.tie would have to come back. icon.conflict carries no count and needs none — ratios reduce to a mean, not a vote.

    type DiagnosticData = {
        "color.collapsed": {
            chosen: string;
            key: string;
            observed: { color: string; feature: string; layers: string[] }[];
        };
        "color.conflict": {
            chosen: string;
            key: string;
            observed: { color: string; layers: string[] }[];
            rule: "topmost";
        };
        "color.lowConfidence": {
            distance: number;
            estimate: string;
            evidenceShare: number;
            key: string;
            paletteColor: string;
            residual: number;
            threshold: number;
        };
        "color.unobserved": { count: number; keys: string[]; total: number };
        "font.conflict": {
            chosen: string;
            observed: { count: number; font: string }[];
            topic: string;
        };
        "font.unavailable": {
            reason: "not-published"
            | "no-font-list";
            requested: string[];
        };
        "icon.conflict": {
            chosen: number;
            observed: { probe: string; ratio: number }[];
            option: "scale" | "spacing";
        };
        "icons.replaced": { sprite: unknown };
        "input.badOption": { cause: string };
        "input.fetchFailed": { status: number; url: string };
        "input.notAStyle": { received: string };
        "input.unreadable": { cause: string };
        "labelStyle.conflict": {
            chosen: number | string;
            observed: { count: number; value: number | string }[];
            property: string;
            topic: string;
        };
        "language.conflict": {
            chosen?: string;
            observed: { language: string; probes: string[] }[];
        };
        "language.unavailable": { requested: string };
        "layer.unread": { count: number };
        "projection.unsupported": { requested: string };
        "schema.none": { vectorSources: number };
        "schema.partial": { vectorSources: number };
        "source.multiple": { sources: Record<string, string> };
        "source.schemaUnknown": { sourceId: string };
        "source.tilejsonUnavailable": {
            cause: string;
            sourceId: string;
            url: string;
        };
        "theme.ambiguous": {
            chosen: string;
            cost: number;
            margin: number;
            runnerUp: string;
            runnerUpCost: number;
        };
    }
    Index
    "color.collapsed": {
        chosen: string;
        key: string;
        observed: { color: string; feature: string; layers: string[] }[];
    }

    The source draws features in different colours that the target has one setting for — not a z-order contest like color.conflict, but a schema the target is coarser than. Shortbread's POI layer is coarser than OpenMapTiles' by design, so for an OMT style this is systematic rather than incidental, and observed names each feature the source told apart.

    "color.conflict": {
        chosen: string;
        key: string;
        observed: { color: string; layers: string[] }[];
        rule: "topmost";
    }

    Several layers drew a probe in different colours; the topmost was taken. observed groups the layers by the colour they drew, which is the list a consumer offers as a choice.

    Type Declaration

    • chosen: string
    • key: string
    • observed: { color: string; layers: string[] }[]
    • rule: "topmost"

      How the winner was picked, as a rule rather than a sentence.

    "color.lowConfidence": {
        distance: number;
        estimate: string;
        evidenceShare: number;
        key: string;
        paletteColor: string;
        residual: number;
        threshold: number;
    }

    A colour was observed and estimated, but not by enough to override the palette's own value.

    Type Declaration

    • distance: number

      How far the estimate sat from the palette, and how far it had to sit to be taken.

    • estimate: string
    • evidenceShare: number

      0..1 — how strongly the readings constrained this key.

    • key: string
    • paletteColor: string
    • residual: number
    • threshold: number
    "color.unobserved": { count: number; keys: string[]; total: number }

    Colours nothing in the style spoke for, which kept the chosen palette's values.

    "font.conflict": {
        chosen: string;
        observed: { count: number; font: string }[];
        topic: string;
    }

    A topic's labels were set in more than one font; the most used was taken.

    "font.unavailable": {
        reason: "not-published" | "no-font-list";
        requested: string[];
    }

    Fonts the glyph server does not publish; the nearest face it has was used.

    "icon.conflict": {
        chosen: number;
        observed: { probe: string; ratio: number }[];
        option: "scale" | "spacing";
    }

    Icons were sized inconsistently relative to the target's; one multiplier had to serve.

    "icons.replaced": { sprite: unknown }

    The style's sprite is not carried over; the target's own icons are used.

    "input.badOption": { cause: string }

    An option passed to guessOptions was not one it has.

    "input.fetchFailed": { status: number; url: string }

    The style URL could not be fetched.

    "input.notAStyle": { received: string }

    The argument was not a MapLibre style document.

    "input.unreadable": { cause: string }

    Anything else that stopped the read.

    "labelStyle.conflict": {
        chosen: number | string;
        observed: { count: number; value: number | string }[];
        property: string;
        topic: string;
    }

    A topic's labels disagreed on a style property; the median, or most voted, was taken.

    "language.conflict": {
        chosen?: string;
        observed: { language: string; probes: string[] }[];
    }

    Labels were read in more than one language; the first place label's was taken.

    chosen is absent when that first label reads a plain name — local names, which sets no text.language at all — or when the language it reads is one the tiles do not carry. It is optional precisely so that case cannot be mistaken for a language: the field used to name the first language observed, which was not always the one applied.

    "language.unavailable": { requested: string }

    A label language the VersaTiles tiles do not carry; local names are used.

    "layer.unread": { count: number }

    Layers of the input that no probe read. Not necessarily lost — see the code's note.

    "projection.unsupported": { requested: string }

    A projection the options cannot express.

    "schema.none": { vectorSources: number }

    No source of a known schema, and no imagery either.

    "schema.partial": { vectorSources: number }

    No vector source could be read, but something else could — the vector half is missing.

    "source.multiple": { sources: Record<string, string> }

    More than one vector source: all of them were read as one map.

    "source.schemaUnknown": { sourceId: string }

    A vector source carries tiles of no schema this package knows; its layers were not read.

    "source.tilejsonUnavailable": { cause: string; sourceId: string; url: string }

    A source's TileJSON could not be downloaded; its schema was read from the style instead.

    "theme.ambiguous": {
        chosen: string;
        cost: number;
        margin: number;
        runnerUp: string;
        runnerUpCost: number;
    }

    Two palettes fit almost equally well; the cheaper one was taken.