# core/counters/report.counter.ts

> 21 lines of code and 4 definitions.

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

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

## Definitions

- `metricsOf` (lexical_declaration, line 11, exported)
- `resolutionRate` (lexical_declaration, line 6, exported)
- `RATE_SCALE` (lexical_declaration, line 4)
- `total` (lexical_declaration, line 7, exported)

## Contained in

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

## Uses

- [core/counters/base.counter.ts](https://banes-lab.com/source/patterns/core/counters/base.counter.ts.md)

## Used by

- [core/coordinators/package.coordinator.ts](https://banes-lab.com/source/patterns/core/coordinators/package.coordinator.ts.md)
- [core/coordinators/page.coordinator.ts](https://banes-lab.com/source/patterns/core/coordinators/page.coordinator.ts.md)

## Linked from

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

## Source

```typescript
import type { MetricScope, ReportMetrics } from "#types/report.types";
import { maxOf, tally } from "#core/counters/base.counter";

const RATE_SCALE = 100;

export const resolutionRate = function resolutionRate(resolved: number, unresolved: number): number {
    const total = resolved + unresolved;
    return total === 0 ? 1 : Math.round((resolved / total) * RATE_SCALE) / RATE_SCALE;
};

export const metricsOf = function metricsOf(scope: MetricScope): ReportMetrics {
    return {
        callable: scope.symbols.filter((symbol) => symbol.callable).length,
        definitions: scope.symbols.length,
        edges: scope.edges.length,
        exported: scope.symbols.filter((symbol) => symbol.exported).length,
        findings: tally(scope.findings, (finding) => finding.kind),
        flows: tally(scope.symbols, (symbol) => symbol.flow),
        maxInDegree: maxOf(scope.symbols.map((symbol) => symbol.inDegree)),
        maxOutDegree: maxOf(scope.symbols.map((symbol) => symbol.outDegree)),
        resolutionRate: resolutionRate(scope.edges.length, scope.unresolved),
        unresolvedCalls: scope.unresolved,
    };
};
```
