# tools/core/resolvers/converge.resolver.ts

> 134 lines of code and 24 definitions.

Tree: Coordination tree
Language: typescript
Layer: infrastructure
Canonical: https://banes-lab.com/anatomy/coordination#file-coordination-tools-core-resolvers-converge-resolver-ts
Source text: https://banes-lab.com/source/coordination/tools/core/resolvers/converge.resolver.ts.txt

Listed in [tools/core/resolvers](https://banes-lab.com/api/source/coordination/tools/core/resolvers.md), after [tools/core/resolvers/conduct.resolver.ts](https://banes-lab.com/source/coordination/tools/core/resolvers/conduct.resolver.ts.md) and before [tools/core/resolvers/corpus.resolver.ts](https://banes-lab.com/source/coordination/tools/core/resolvers/corpus.resolver.ts.md).

## Definitions

- `absorptionDetail` (lexical_declaration, line 97)
- `absorptionEdge` (lexical_declaration, line 112, exported)
- `isAllDigits` (lexical_declaration, line 37)
- `absorbed` (lexical_declaration, line 93)
- `isTaskId` (lexical_declaration, line 46)
- `DISTRIBUTES_FIELD` (lexical_declaration, line 16, exported)
- `CLOSES_FIELD` (lexical_declaration, line 18, exported)
- `OPEN_TASK` (lexical_declaration, line 20)
- `AWAITING_LINE` (lexical_declaration, line 22)
- `PlannedSurface` (interface_declaration, line 24)
- `Distribution` (interface_declaration, line 31)
- `taskIdOf` (lexical_declaration, line 50)
- `plannedSurface` (lexical_declaration, line 54)
- `lines` (lexical_declaration, line 55)
- `closesLine` (lexical_declaration, line 58)
- `absorptionState` (lexical_declaration, line 71, exported)
- `planning` (lexical_declaration, line 72, exported)
- `declaring` (lexical_declaration, line 77, exported)
- `[first]` (lexical_declaration, line 80, exported)
- `absorption` (lexical_declaration, line 113, exported)
- `declaredDistributions` (lexical_declaration, line 122, exported)
- `trimmed` (lexical_declaration, line 130, exported)
- `declares` (lexical_declaration, line 131, exported)
- `hasReadMark` (lexical_declaration, line 141, exported)

## Uses

- [tools/core/strings/converge.strings.ts](https://banes-lab.com/source/coordination/tools/core/strings/converge.strings.ts.md)

## Used by

- [tools/core/validators/converge.validator.ts](https://banes-lab.com/source/coordination/tools/core/validators/converge.validator.ts.md)

## Source

```typescript
import type { Absorption, Edge } from "../types/converge.types.ts";
import {
    CHECK_ABSORPTION,
    absorptionDuplicated,
    absorptionHolds,
    absorptionNoCloses,
    absorptionOpen,
    absorptionUndistributed,
} from "../strings/converge.strings.ts";
import { PLACEHOLDER, SIGN_OFF_ABSENT } from "../analyzers/converge.analyzer.ts";
import { basename, resolve } from "node:path";
import { existsSync, readFileSync, readdirSync } from "node:fs";
import { AWAITING_MARKER } from "../constants/blocking.constants.ts";
import { surfacePath } from "../../../config/surface.config.ts";

export const DISTRIBUTES_FIELD = "DISTRIBUTES:";

export const CLOSES_FIELD = "CLOSES:";

const OPEN_TASK = "- [ ]";

const AWAITING_LINE = AWAITING_MARKER;

interface PlannedSurface {
    readonly entry: string;
    readonly declares: boolean;
    readonly closes: string;
    readonly open: readonly string[];
}

interface Distribution {
    readonly path: string;
    readonly line: number;
    readonly declares: string;
}

const isAllDigits = function isAllDigits(text: string): boolean {
    for (const character of text) {
        if (character < "0" || character > "9") {
            return false;
        }
    }
    return text.length > 0;
};

const isTaskId = function isTaskId(token: string): boolean {
    return token.includes(".") && isAllDigits(token.replaceAll(".", ""));
};

const taskIdOf = function taskIdOf(trimmed: string): string {
    return trimmed.slice(OPEN_TASK.length).trim().split(" ")[0] ?? "";
};

const plannedSurface = function plannedSurface(planning: string, entry: string, venueName: string): PlannedSurface {
    const lines = readFileSync(resolve(planning, entry), "utf8")
        .split("\n")
        .map((line) => line.trim());
    const closesLine = lines.findLast((line) => line.startsWith(CLOSES_FIELD));

    return {
        closes: closesLine === undefined ? "" : closesLine.slice(CLOSES_FIELD.length).trim(),
        declares: lines.some((line) => line.startsWith(DISTRIBUTES_FIELD) && line.includes(venueName)),
        entry,
        open: lines
            .filter((line) => line.startsWith(OPEN_TASK))
            .map(taskIdOf)
            .filter(isTaskId),
    };
};

export const absorptionState = function absorptionState(repoRoot: string, venueName: string): Absorption | null {
    const planning = resolve(repoRoot, surfacePath("planning"));
    if (!existsSync(planning)) {
        return null;
    }

    const declaring = readdirSync(planning)
        .map((entry) => plannedSurface(planning, entry, venueName))
        .filter((surface) => surface.declares);
    const [first] = declaring;
    if (first === undefined) {
        return null;
    }

    return {
        checklist: first.entry,
        closes: first.closes,
        declaring: declaring.map((surface) => surface.entry),
        open: first.open.filter((id) => id !== first.closes),
    };
};

const absorbed = function absorbed(absorption: Absorption | null): boolean {
    return absorption?.declaring.length === 1 && absorption.closes.length > 0 && absorption.open.length === 0;
};

const absorptionDetail = function absorptionDetail(absorption: Absorption | null, target: string): string {
    if (absorption === null) {
        return absorptionUndistributed(basename(target), DISTRIBUTES_FIELD);
    }
    if (absorption.declaring.length > 1) {
        return absorptionDuplicated(absorption.declaring);
    }
    if (absorption.closes.length === 0) {
        return absorptionNoCloses(absorption.checklist, CLOSES_FIELD);
    }
    return absorption.open.length === 0
        ? absorptionHolds(absorption.checklist, absorption.closes)
        : absorptionOpen(absorption.checklist, absorption.open);
};

export const absorptionEdge = function absorptionEdge(repoRoot: string, target: string): Edge {
    const absorption = absorptionState(repoRoot, basename(target));
    return {
        detail: absorptionDetail(absorption, target),
        edge: CHECK_ABSORPTION,
        holds: absorbed(absorption),
        step: "absorption",
    };
};

export const declaredDistributions = function declaredDistributions(
    surfaces: readonly string[],
    read: (path: string) => string,
): Distribution[] {
    return surfaces.flatMap((path) =>
        read(path)
            .split("\n")
            .flatMap((line, index) => {
                const trimmed = line.trim();
                const declares = trimmed.startsWith(DISTRIBUTES_FIELD)
                    ? trimmed.slice(DISTRIBUTES_FIELD.length).trim()
                    : "";
                return declares.length === 0 || declares.startsWith(PLACEHOLDER)
                    ? []
                    : [{ declares, line: index + 1, path }];
            }),
    );
};

export const hasReadMark = function hasReadMark(venue: string): boolean {
    return venue
        .split("\n")
        .map((line) => line.trim())
        .filter((line) => line.startsWith(AWAITING_LINE))
        .some((line) =>
            line
                .slice(AWAITING_LINE.length)
                .split(" ")
                .map((token) => token.trim())
                .some((letter) => letter.length > 0 && letter !== SIGN_OFF_ABSENT),
        );
};
```
