# core/selectors/reason.selector.ts

> 75 lines of code and 10 definitions.

Tree: GovLab Context
Language: typescript
Layer: application
Canonical: https://banes-lab.com/anatomy/context#file-context-core-selectors-reason-selector-ts
Source text: https://banes-lab.com/source/context/core/selectors/reason.selector.ts.txt

Listed in [core/selectors](https://banes-lab.com/api/source/context/core/selectors.md), after [core/selectors/pattern.selector.ts](https://banes-lab.com/source/context/core/selectors/pattern.selector.ts.md) and before [core/selectors/vocabulary.selector.ts](https://banes-lab.com/source/context/core/selectors/vocabulary.selector.ts.md).

## Definitions

- `schemaOf` (lexical_declaration, line 38, exported)
- `uncoveredCellsOf` (lexical_declaration, line 74, exported)
- `kindMembersOf` (lexical_declaration, line 32, exported)
- `collectIds` (lexical_declaration, line 46, exported)
- `cellOf` (lexical_declaration, line 70, exported)
- `REASON_KINDS` (lexical_declaration, line 7, exported)
- `schema` (lexical_declaration, line 39, exported)
- `groups` (lexical_declaration, line 47, exported)
- `ids` (lexical_declaration, line 66, exported)
- `covered` (lexical_declaration, line 75, exported)

## Contained in

- [core/selectors](https://banes-lab.com/anatomy/context/folder-context-core-selectors.md)

## Uses

- [configuration/strings/reason.strings.ts](https://banes-lab.com/source/context/configuration/strings/reason.strings.ts.md)

## Used by

- [core/factories/reason.factory.ts](https://banes-lab.com/source/context/core/factories/reason.factory.ts.md)
- [core/normalizers/reason.normalizer.ts](https://banes-lab.com/source/context/core/normalizers/reason.normalizer.ts.md)

## Linked from

- [configuration/strings](https://banes-lab.com/anatomy/context/folder-context-configuration-strings.md)
- [core/factories](https://banes-lab.com/anatomy/context/folder-context-core-factories.md)
- [core/normalizers](https://banes-lab.com/anatomy/context/folder-context-core-normalizers.md)
- [core/selectors](https://banes-lab.com/anatomy/context/folder-context-core-selectors.md)

## Source

```typescript
import { CELL_SEPARATOR } from "#configuration/constants/reason.constants";
import type { KindSchema } from "#types/field.types";
import { REASON_SCHEMA } from "#configuration/schemas/reason.schema";
import type { ReasonData } from "#types/reason.types";
import { undeclaredReasonKind } from "#configuration/strings/reason.strings";

export const REASON_KINDS: ReadonlyMap<string, (data: ReasonData) => readonly { id: string }[]> = new Map<
    string,
    (data: ReasonData) => readonly { id: string }[]
>([
    ["axis", (data) => data.axes],
    ["dimension", (data) => data.dimensions],
    ["failure-shape", (data) => data.failureShapes],
    ["invariant", (data) => data.invariants],
    ["layer", (data) => data.layers],
    ["lens", (data) => data.lenses],
    ["loop", (data) => [data.derivationLoop]],
    ["math-domain", (data) => data.mathDomains],
    ["math-type", (data) => data.mathTypes],
    ["mode", (data) => data.modes],
    ["model", (data) => data.models],
    ["node", (data) => data.nodes],
    ["pattern-type", (data) => data.patternTypes],
    ["representation", (data) => data.representations],
    ["stage", (data) => data.derivationLoop.stages],
    ["substrate-node", (data) => data.substrate.nodes],
    ["technique", (data) => data.techniques],
    ["test-surface", (data) => data.testSurfaces],
    ["universal-axis", (data) => data.universalAxes],
]);

export const kindMembersOf = function kindMembersOf(data: ReasonData): ReadonlyMap<string, ReadonlySet<string>> {
    return new Map(
        [...REASON_KINDS].map(([kind, recordsOf]) => [kind, new Set(recordsOf(data).map((record) => record.id))]),
    );
};

export const schemaOf = function schemaOf(kind: string): KindSchema {
    const schema = REASON_SCHEMA.get(kind);
    if (schema === undefined) {
        throw new Error(undeclaredReasonKind(kind));
    }
    return schema;
};

export const collectIds = function collectIds(data: ReasonData): string[] {
    const groups: readonly (readonly { id: string }[])[] = [
        data.nodes,
        data.axes,
        data.layers,
        data.mathTypes,
        data.substrate.nodes,
        data.dimensions,
        data.lenses,
        data.modes,
        data.representations,
        data.mathDomains,
        data.patternTypes,
        data.models,
        data.universalAxes,
        data.testSurfaces,
        data.techniques,
        data.invariants,
        data.failureShapes,
    ];
    const ids = new Set<string>([...groups.flat().map((record) => record.id), data.derivationLoop.id]);
    return [...ids].toSorted((a, b) => a.localeCompare(b));
};

export const cellOf = function cellOf(dimension: string, lens: string): string {
    return `${dimension}${CELL_SEPARATOR}${lens}`;
};

export const uncoveredCellsOf = function uncoveredCellsOf(data: ReasonData): { dimension: string; lens: string }[] {
    const covered = new Set(data.testSurfaces.map((surface) => cellOf(surface.dimension, surface.lens)));
    return data.dimensions.flatMap((dimension) =>
        data.lenses
            .filter((lens) => !covered.has(cellOf(dimension.id, lens.id)))
            .map((lens) => ({ dimension: dimension.id, lens: lens.id })),
    );
};
```
