tools/core/analyzers/board.analyzer.ts
tools/core/analyzers/board.analyzer.ts is a file in Coordination Surface. 149 lines of code and 52 definitions.
import type { AddressingSite, BoardRecord, RecordKind } from "../types/board.types.ts";
import { fencedFlags } from "../predicates/fence.predicate.ts";
import { indexedStates } from "../inspectors/index.inspector.ts";
import { itemSpanFlags } from "./fence.analyzer.ts";
const AGENT_PREFIX = "Agent ";
const BROADCAST_META = "to:*";
const DIRECTED_OPENER = "To ";
const BROADCAST_OPENER = "To ALL";
const OPENER_PREVIEW = 24;
const LABEL_LIMIT = 24;
const CLOSE_MARKER = "└";
const MARKER_END = "END AGENT ";
const FIELD_INDENT = " ";
export const fieldKeyAt = function fieldKeyAt(line: string): string {
if (!line.startsWith(FIELD_INDENT) || line.charAt(FIELD_INDENT.length) === " ") {
return "";
}
const trimmed = line.trim();
const colon = trimmed.indexOf(":");
if (colon <= 0) {
return "";
}
const key = trimmed.slice(0, colon);
return key.includes(" ") ? "" : key;
};
export const unresolvedAddressing = function unresolvedAddressing(source: string): AddressingSite[] {
const lines = source.split("\n");
const out: AddressingSite[] = [];
for (const [index, line] of lines.entries()) {
const text = (lines[index + 1] ?? "").trim();
const directed = text.startsWith(DIRECTED_OPENER) && !text.startsWith(BROADCAST_OPENER);
if (line.includes(BROADCAST_META) && directed) {
out.push({ line: index + 1, opener: text.slice(0, OPENER_PREVIEW) });
}
}
return out;
};
interface OpenRecord {
readonly kind: RecordKind;
readonly label: string;
readonly state: string;
readonly line: number;
readonly fields: Map<string, string>;
}
const HEADINGS: ReadonlyMap<string, RecordKind> = new Map([
["Agent", "agent"],
["Gate", "gate"],
]);
const headingOf = function headingOf(line: string): { kind: RecordKind; label: string; state: string } | null {
const trimmed = line.trim();
const space = trimmed.indexOf(" ");
if (space === -1) {
return null;
}
const word = trimmed.slice(0, space);
const kind = HEADINGS.get(word);
if (kind === undefined) {
return null;
}
const rest = trimmed.slice(space + 1);
const dash = rest.indexOf("—");
const label = dash === -1 ? rest.trim() : rest.slice(0, dash).trim();
if (label.length === 0 || label.length > LABEL_LIMIT) {
return null;
}
const state = dash === -1 ? "" : rest.slice(dash + 1).trim();
return { kind, label: `${word} ${label}`, state };
};
const fieldOf = function fieldOf(line: string): { key: string; value: string } | null {
if (!line.startsWith(FIELD_INDENT) || line.charAt(FIELD_INDENT.length) === " ") {
return null;
}
const trimmed = line.trim();
const colon = trimmed.indexOf(":");
if (colon <= 0) {
return null;
}
const key = trimmed.slice(0, colon).trim();
return key.includes(" ") ? null : { key, value: trimmed.slice(colon + 1).trim() };
};
const closesRecord = function closesRecord(line: string, label: string): boolean {
const trimmed = line.trim();
const marks = trimmed.indexOf(MARKER_END);
if (!trimmed.startsWith(CLOSE_MARKER) || marks === -1) {
return false;
}
const named = trimmed.slice(marks + MARKER_END.length).trim();
const space = label.indexOf(" ");
const letter = space === -1 ? label : label.slice(space + 1).trim();
return named === letter;
};
interface Advance {
readonly current: OpenRecord | null;
readonly done: OpenRecord | null;
}
const advance = function advance(current: OpenRecord | null, line: string, index: number): Advance {
const heading = headingOf(line);
if (heading !== null) {
return { current: { ...heading, fields: new Map(), line: index + 1 }, done: current };
}
if (current === null) {
return { current: null, done: null };
}
if (closesRecord(line, current.label)) {
return { current: null, done: current };
}
const field = fieldOf(line);
const fields = field === null ? current.fields : new Map([...current.fields, [field.key, field.value]]);
return { current: { ...current, fields }, done: null };
};
const isListOrHeading = function isListOrHeading(line: string): boolean {
const trimmed = line.trim();
return trimmed.startsWith("#") || trimmed.startsWith("-");
};
export const boardRecords = function boardRecords(source: string): BoardRecord[] {
const out: BoardRecord[] = [];
const fenced = fencedFlags(source);
const inItem = itemSpanFlags(source);
let current: OpenRecord | null = null;
for (const [index, line] of source.split("\n").entries()) {
const skipped = fenced[index] === true || inItem[index] === true || isListOrHeading(line);
const step: Advance = skipped ? { current, done: null } : advance(current, line, index);
({ current } = step);
if (step.done !== null) {
out.push(step.done);
}
}
if (current !== null) {
out.push(current);
}
return out;
};
export const ACTIVE_STATE = "ACTIVE";
export const seatState = function seatState(index: string): (letter: string, marker: string) => string {
const bound = indexedStates(index);
const allocating = index.trim().length > 0;
return (letter: string, marker: string): string => (allocating ? (bound.get(letter) ?? "") : marker);
};
export const activeSeats = function activeSeats(board: string, index: string): string[] {
const stateOf = seatState(index);
return boardRecords(board)
.filter((record) => record.kind === "agent")
.map((record) => ({ letter: record.label.slice(AGENT_PREFIX.length).trim(), state: record.state }))
.filter(({ letter, state }) => letter.length > 0 && stateOf(letter, state) === ACTIVE_STATE)
.map(({ letter }) => letter);
};
export const activeAgents = function activeAgents(board: string, index: string): number {
return activeSeats(board, index).length;
};