# core/counters/dependency.counter.ts

> 25 lines of code and 5 definitions.

Tree: GovLab Patterns
Language: typescript
Layer: operations
Canonical: https://banes-lab.com/anatomy/patterns#file-patterns-core-counters-dependency-counter-ts
Source text: https://banes-lab.com/source/patterns/core/counters/dependency.counter.ts.txt

Listed in [core/counters](https://banes-lab.com/api/source/patterns/core/counters.md), after [core/counters/base.counter.ts](https://banes-lab.com/source/patterns/core/counters/base.counter.ts.md) and before [core/counters/report.counter.ts](https://banes-lab.com/source/patterns/core/counters/report.counter.ts.md).

## Definitions

- `edgesOf` (lexical_declaration, line 9)
- `crossModuleFanIn` (lexical_declaration, line 19, exported)
- `ImportEdge` (interface_declaration, line 4)
- `target` (lexical_declaration, line 11)
- `importers` (lexical_declaration, line 23, exported)

## Contained in

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

## Uses

- [core/formatters/definition.formatter.ts](https://banes-lab.com/source/patterns/core/formatters/definition.formatter.ts.md)

## Used by

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

## Linked from

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

## Source

```typescript
import type { ModuleUnit } from "#types/code.types";
import { keyOf } from "#core/formatters/definition.formatter";

interface ImportEdge {
    key: string;
    importer: string;
}

const edgesOf = function edgesOf(unit: ModuleUnit, packageMap: ReadonlyMap<string, string>): ImportEdge[] {
    return unit.imports.flatMap((binding) => {
        const target = packageMap.get(binding.source);
        if (target === undefined || target === unit.moduleDir) {
            return [];
        }
        return binding.importedNames.map((name) => ({ importer: unit.moduleDir, key: keyOf(target, name) }));
    });
};

export const crossModuleFanIn = function crossModuleFanIn(
    units: readonly ModuleUnit[],
    packageMap: ReadonlyMap<string, string>,
): Map<string, number> {
    const importers = new Map<string, Set<string>>();
    for (const edge of units.flatMap((unit) => edgesOf(unit, packageMap))) {
        importers.set(edge.key, (importers.get(edge.key) ?? new Set<string>()).add(edge.importer));
    }
    return new Map([...importers].map(([key, set]) => [key, set.size]));
};
```
