# core/factories/layer.factory.ts

> 63 lines of code and 10 definitions.

Tree: GovLab Context
Language: typescript
Layer: infrastructure
Canonical: https://banes-lab.com/anatomy/context#file-context-core-factories-layer-factory-ts
Source text: https://banes-lab.com/source/context/core/factories/layer.factory.ts.txt

Listed in [core/factories](https://banes-lab.com/api/source/context/core/factories.md), after [core/factories/grammar.factory.ts](https://banes-lab.com/source/context/core/factories/grammar.factory.ts.md) and before [core/factories/lexicon.factory.ts](https://banes-lab.com/source/context/core/factories/lexicon.factory.ts.md).

## Definitions

- `nodeIds` (lexical_declaration, line 50)
- `buildJoinState` (lexical_declaration, line 33)
- `createLayerJoin` (lexical_declaration, line 54, exported)
- `JoinSources` (interface_declaration, line 27)
- `edges` (lexical_declaration, line 34)
- `membership` (lexical_declaration, line 35)
- `resolutionList` (lexical_declaration, line 36)
- `refs` (lexical_declaration, line 37)
- `audit` (lexical_declaration, line 55, exported)
- `state` (lexical_declaration, line 56, exported)

## Contained in

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

## Uses

- [core/resolvers/layer.resolver.ts](https://banes-lab.com/source/context/core/resolvers/layer.resolver.ts.md)

## Linked from

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

## Source

```typescript
import {
    EDGES_KEY,
    GRAPH_FILE,
    INDEX_FILE,
    MEMBERSHIP_KEY,
    RESOLUTIONS_KEY,
    TENSION_FILE,
} from "#configuration/constants/layer.constants";
import type { JoinState, LayerEdge, LayerJoin } from "#types/layer.types";
import { asLayerEdge, asLayerMembership, asTensionResolution } from "#core/normalizers/layer.normalizer";
import {
    buildLayerByKey,
    buildLiveEdgePairs,
    buildRefMaps,
    buildResolutionByPair,
    layerOf,
    pairKey,
    resolveTension,
} from "#core/resolvers/layer.resolver";
import type { AlgoGrammar } from "#types/algorithm.types";
import type { ArchRelations } from "#types/architecture.types";
import { COLLECTIONS } from "#configuration/constants/ontology.constants";
import type { Lexicon } from "#types/lexicon.types";
import { ReadAudit } from "#core/observers/record.observer";
import { readLayerList } from "#core/loaders/layer.loader";

interface JoinSources {
    arch: ArchRelations;
    algo: AlgoGrammar;
    lex: Lexicon;
}

const buildJoinState = function buildJoinState(sources: JoinSources, audit: ReadAudit): JoinState {
    const edges = readLayerList(audit, GRAPH_FILE, EDGES_KEY, asLayerEdge);
    const membership = readLayerList(audit, INDEX_FILE, MEMBERSHIP_KEY, asLayerMembership);
    const resolutionList = readLayerList(audit, TENSION_FILE, RESOLUTIONS_KEY, asTensionResolution);
    const refs = buildRefMaps(sources.arch);
    return {
        edges,
        layerByKey: buildLayerByKey(membership),
        liveEdgePairs: buildLiveEdgePairs(sources.arch, refs),
        refs,
        resolutionByPair: buildResolutionByPair(resolutionList, refs),
        resolutionList,
        termCategoryOf: (idOrName) => sources.lex.resolve(idOrName)?.category ?? null,
        titleOf: (id) => sources.algo.get(id)?.title ?? null,
    };
};

const nodeIds = function nodeIds(edges: readonly LayerEdge[]): string[] {
    return [...new Set(edges.flatMap((edge) => [edge.from, edge.to]))].toSorted((a, b) => a.localeCompare(b));
};

export const createLayerJoin = function createLayerJoin(sources: JoinSources): LayerJoin {
    const audit = new ReadAudit(COLLECTIONS.layers);
    const state = buildJoinState(sources, audit);
    return {
        deadSeeds: () =>
            state.resolutionList.filter((seed) => !state.liveEdgePairs.has(pairKey(state.refs, seed.a, seed.b))),
        layerOf: (idOrName) => layerOf(state, idOrName),
        layers: () => nodeIds(state.edges).map((id) => ({ id, label: state.titleOf(id) ?? id })),
        resolutions: () => [...state.resolutionList],
        resolveTension: (a, b) => resolveTension(state, a, b),
        topology: () => [...state.edges],
        unreadKeys: () => audit.unread(),
    };
};
```
