# core/converters/view.converter.ts

> 28 lines of code and 8 definitions.

Tree: Bane's Lab Build Scripts
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/build-scripts#file-build-scripts-core-converters-view-converter-ts
Source text: https://banes-lab.com/source/build-scripts/core/converters/view.converter.ts.txt

Listed in [core/converters](https://banes-lab.com/api/source/build-scripts/core/converters.md), after [core/converters/tab.converter.ts](https://banes-lab.com/source/build-scripts/core/converters/tab.converter.ts.md) and before [core/converters/vocabulary.converter.ts](https://banes-lab.com/source/build-scripts/core/converters/vocabulary.converter.ts.md).

## Definitions

- `distinctsOf` (lexical_declaration, line 28, exported)
- `exemplarOf` (lexical_declaration, line 10, exported)
- `orNull` (lexical_declaration, line 6, exported)
- `groupBy` (lexical_declaration, line 14, exported)
- `groups` (lexical_declaration, line 15, exported)
- `key` (lexical_declaration, line 17, exported)
- `layerRef` (lexical_declaration, line 23, exported)
- `layer` (lexical_declaration, line 24, exported)

## Contained in

- [core/converters](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-converters.md)

## Used by

- [core/converters/grammar.converter.ts](https://banes-lab.com/source/build-scripts/core/converters/grammar.converter.ts.md)
- [core/converters/lexicon.converter.ts](https://banes-lab.com/source/build-scripts/core/converters/lexicon.converter.ts.md)
- [core/converters/ontology.converter.ts](https://banes-lab.com/source/build-scripts/core/converters/ontology.converter.ts.md)

## Linked from

- [core/converters](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-converters.md)

## Source

```typescript
import type { DistinctView, EdgeRef } from "@banes-lab/web/types/link.types.js";
import type { Exemplar } from "@govlab/context";
import type { ExemplarView } from "@banes-lab/web/types/ontology.types.js";
import type { OntologySources } from "#types/ontology.types";

export const orNull = function orNull(value?: string): string | null {
    return value === undefined || value.length === 0 ? null : value;
};

export const exemplarOf = function exemplarOf(exemplar?: Exemplar): ExemplarView | null {
    return exemplar === undefined ? null : { ...exemplar };
};

export const groupBy = function groupBy<T>(items: readonly T[], keyOf: (item: T) => string): readonly [string, T[]][] {
    const groups = new Map<string, T[]>();
    for (const item of items) {
        const key = keyOf(item);
        groups.set(key, [...(groups.get(key) ?? []), item]);
    }
    return [...groups.entries()];
};

export const layerRef = function layerRef(sources: OntologySources, id: string): EdgeRef | null {
    const layer = sources.context.layerOf(id);
    return layer === null ? null : sources.resolve.layer(layer);
};

export const distinctsOf = function distinctsOf(
    declared: readonly { readonly id: string; readonly reason: string }[] | undefined,
    resolveId: (id: string) => EdgeRef,
): readonly DistinctView[] {
    return (declared ?? []).map((entry) => ({ reason: entry.reason, record: resolveId(entry.id) }));
};
```
