# core/converters/graph.segment.converter.ts

> 51 lines of code and 15 definitions.

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

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

## Definitions

- `add` (lexical_declaration, line 18, exported)
- `targetOf` (lexical_declaration, line 4)
- `chunksOf` (lexical_declaration, line 14, exported)
- `containersOf` (lexical_declaration, line 8)
- `nodes` (lexical_declaration, line 15, exported)
- `containers` (lexical_declaration, line 16, exported)
- `relations` (lexical_declaration, line 17, exported)
- `target` (lexical_declaration, line 19, exported)
- `held` (lexical_declaration, line 23, exported)
- `reverse` (lexical_declaration, line 29, exported)
- `container` (lexical_declaration, line 33, exported)
- `chunks` (lexical_declaration, line 38, exported)
- `node` (lexical_declaration, line 40, exported)
- `key` (lexical_declaration, line 42, exported)
- `chunk` (lexical_declaration, line 43, exported)

## Contained in

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

## Linked from

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

## Source

```typescript
import type { ChunkNode, ChunkTarget, GraphChunk, GraphNode } from "@banes-lab/web/types/graph.types.js";
import type { ChunkRules, Graph } from "#types/graph.types";

const targetOf = function targetOf(node: GraphNode): ChunkTarget {
    return { href: node.href, number: node.number, title: node.title };
};

const containersOf = function containersOf(graph: Graph, rules: ChunkRules): ReadonlyMap<string, string> {
    return new Map(
        graph.edges.filter((edge) => edge.relation === rules.contains).map((edge) => [edge.to, edge.from] as const),
    );
};

export const chunksOf = function chunksOf(graph: Graph, rules: ChunkRules): ReadonlyMap<string, GraphChunk> {
    const nodes = new Map(graph.nodes.map((node) => [node.ref, node]));
    const containers = containersOf(graph, rules);
    const relations = new Map<string, Map<string, ChunkTarget[]>>();
    const add = function add(from: string, relation: string, to: string): void {
        const target = nodes.get(to);
        if (!nodes.has(from) || target === undefined || !rules.keptRelations.has(relation)) {
            return;
        }
        const held = relations.get(from) ?? new Map<string, ChunkTarget[]>();
        held.set(relation, [...(held.get(relation) ?? []), targetOf(target)]);
        relations.set(from, held);
    };
    for (const edge of graph.edges.filter((held) => !rules.skipsSource(held.from))) {
        add(edge.from, edge.relation, edge.to);
        const reverse = rules.pairs.find((pair) => pair.forward === edge.relation)?.reverse;
        if (reverse !== undefined) {
            add(edge.to, reverse, edge.from);
        }
        const container = containers.get(edge.to);
        if (reverse !== undefined && container !== undefined && rules.rollsUp.has(reverse)) {
            add(container, reverse, edge.from);
        }
    }
    const chunks = new Map<string, Record<string, ChunkNode>>();
    for (const [ref, held] of relations) {
        const node = nodes.get(ref);
        if (node !== undefined) {
            const key = rules.keyOf(ref);
            const chunk = chunks.get(key) ?? {};
            chunk[ref] = {
                kind: node.kind,
                number: node.number,
                relations: [...held].map(([relation, targets]) => ({ relation, targets })),
                title: node.title,
            };
            chunks.set(key, chunk);
        }
    }
    return chunks;
};
```
