# shared/factories/vocabulary.factory.ts

> 58 lines of code and 12 definitions.

Tree: Governance tree
Language: typescript
Layer: infrastructure
Canonical: https://banes-lab.com/anatomy/governance#file-governance-shared-factories-vocabulary-factory-ts
Source text: https://banes-lab.com/source/governance/shared/factories/vocabulary.factory.ts.txt

Listed in [shared/factories](https://banes-lab.com/api/source/governance/shared/factories.md), after [shared/factories/listener.factory.ts](https://banes-lab.com/source/governance/shared/factories/listener.factory.ts.md).

## Definitions

- `importedRootsOf` (lexical_declaration, line 7, exported)
- `grammarRolesOf` (lexical_declaration, line 20)
- `createVocabulary` (lexical_declaration, line 33, exported)
- `DEPTH_KEYS` (lexical_declaration, line 3)
- `IMPORT_SELF` (lexical_declaration, line 5)
- `keys` (lexical_declaration, line 8, exported)
- `roleOf` (lexical_declaration, line 16)
- `rolesAtDepth` (lexical_declaration, line 21)
- `tokens` (lexical_declaration, line 23)
- `roleOrder` (lexical_declaration, line 29)
- `byTag` (lexical_declaration, line 34, exported)
- `subjects` (lexical_declaration, line 41, exported)

## Used by

- [shared/registries/taxonomy.registry.ts](https://banes-lab.com/source/governance/shared/registries/taxonomy.registry.ts.md)

## Source

```typescript
import type { Concern, GrammarRoles, TaxonomySource, Vocabulary } from "../../types/taxonomy.types.ts";

const DEPTH_KEYS = ["depthOne", "depthTwo", "depthThree", "depthFour"] as const;

const IMPORT_SELF = ".";

export const importedRootsOf = function importedRootsOf(base: string, source: TaxonomySource): Map<string, string> {
    const keys = new Set([
        ...Object.keys(source.containers),
        ...Object.keys(source.specialContainers),
        ...Object.keys(source.foreignContainers ?? {}),
    ]);
    return new Map([...keys].map((key) => [key === IMPORT_SELF ? base : `${base}/${key}`, key]));
};

const roleOf = function roleOf(token: string): string {
    return token.slice(1, -1);
};

const grammarRolesOf = function grammarRolesOf(folder: Readonly<Record<string, readonly string[]>>): GrammarRoles {
    const rolesAtDepth: string[][] = [];
    for (const key of DEPTH_KEYS) {
        const tokens = folder[key];
        if (tokens === undefined) {
            break;
        }
        rolesAtDepth.push(tokens.map(roleOf));
    }
    const roleOrder = [...new Set(rolesAtDepth.flat())];
    return { roleOrder, rolesAtDepth, terminalRole: roleOrder.at(-1) ?? "" };
};

export const createVocabulary = function createVocabulary(source: TaxonomySource): Vocabulary {
    const byTag = new Map<string, Concern>(
        source.concerns.flatMap((concern) =>
            concern.collection === undefined
                ? [[concern.tag, concern] as const]
                : [[concern.tag, concern] as const, [concern.collection, concern] as const],
        ),
    );
    const subjects = new Set<string>(source.subjects);
    return {
        boundaryDocuments: new Set<string>(source.boundaryDocuments),
        byFolder: new Map<string, Concern>(source.concerns.map((concern) => [concern.folder, concern])),
        byTag,
        case: source.grammar.case,
        compoundMarkers: source.grammar.compoundMarkers,
        dialects: source.grammar.dialects ?? [],
        excludedTrees: source.Excluded?.trees ?? [],
        fileShapes: source.grammar.file,
        generatedFolder: source.grammar.generatedFolder ?? null,
        ignoredNames: source.Ignored.foldersFiles,
        legalSubjects: new Set<string>([...subjects, ...byTag.keys()]),
        markerFolders: new Map<string, string>(Object.entries(source.grammar.markerFolders ?? {})),
        maxDepth: source.grammar.maxDepthFromRoot,
        roles: grammarRolesOf(source.grammar.folder),
        separator: source.grammar.separator,
        splitters: new Map((source.grammar.splitters ?? []).map((splitter) => [splitter.name, splitter])),
        subjects,
        fixtureMarkers: source.grammar.fixtureMarkers ?? [],
        testMarkers: source.grammar.testMarkers ?? [],
        variants: new Set<string>(source.variants),
    };
};
```
