domain/converters/contract.converter.ts
domain/converters/contract.converter.ts is a file in Bane's Lab Site. 147 lines of code and 15 definitions.
import {
AFTER_TITLE,
AXIS_LABEL,
BEFORE_TITLE,
CANON_LABEL,
COMPOSED_BY_LABEL,
COMPOSES_LABEL,
DERIVATION_LABEL,
DERIVED_BY_LABEL,
DETECTS_LABEL,
DISTINCT_FROM_LABEL,
DOMAIN_CAPTION,
DOMAIN_INTRO,
DOMAIN_LABEL,
FLOW_ARROW,
FLOW_TITLE,
FORCES_LABEL,
GROUNDED_BY_LABEL,
GROUNDS_LABEL,
INTENT_LABEL,
INVARIANT_LABEL,
LABEL_SEPARATOR,
LAYER_LABEL,
MATH_TYPE_LABEL,
META_LABEL,
PRINCIPLE_LABEL,
PRODUCTIONS_TITLE,
PRODUCTION_ARROW,
STAGE_LABEL,
TIER_LABEL,
YIELDS_LABEL,
} from "#configuration/strings/ontology.strings";
import { ALGO_ANCHOR, ALGO_DOMAIN_ANCHOR } from "#core/ids/ontology.ids";
import { ALGO_FACE, FACE_SEPARATOR } from "@govlab/constants";
import { BNF_LANGUAGE, LINE_BREAK, TEXT_LANGUAGE } from "#configuration/constants/code.constants";
import type { ContractDomainView, ContractView, ResolutionView } from "#types/ontology.types";
import type { Section, Subsection } from "#types/document.types";
import { canonOf, checkBlocks } from "#domain/converters/check.converter";
import {
chips,
codeOf,
exemplarBlocks,
glossary,
labeled,
linkList,
linkOf,
linkRow,
linked,
row,
text,
} from "#domain/converters/ontology.converter";
import { diagram, edgeLine, localId, node } from "#domain/converters/ontology.graph.converter";
import type { Block } from "#types/block.types";
import { DOMAIN_SECTION_ICON } from "#configuration/icons/ontology.icons";
import { EDGE_SOLID } from "#configuration/constants/diagram.constants";
import { groupTitleOf } from "#configuration/strings/catalog.strings";
const HEADER = "flowchart LR";
const coordinates = function coordinates(contract: ContractView): Block {
return chips([
linked(DOMAIN_LABEL, contract.domain),
linked(TIER_LABEL, contract.tier),
linked(STAGE_LABEL, contract.stage),
linked(AXIS_LABEL, contract.axis),
linked(MATH_TYPE_LABEL, contract.mathType),
labeled(YIELDS_LABEL, contract.yields),
linked(LAYER_LABEL, contract.layer),
contract.meta ? META_LABEL : null,
]);
};
const joins = function joins(contract: ContractView): Block {
return glossary([
row(COMPOSES_LABEL, linkList(contract.composes)),
...linkRow(COMPOSED_BY_LABEL, contract.composedBy),
...linkRow(DERIVED_BY_LABEL, contract.derivedBy),
row(FORCES_LABEL, linkList(contract.force)),
...linkRow(PRINCIPLE_LABEL, contract.principle === null ? [] : [contract.principle]),
row(GROUNDS_LABEL, linkList(contract.grounds)),
...linkRow(GROUNDED_BY_LABEL, contract.groundedBy),
...linkRow(DETECTS_LABEL, contract.detects),
...contract.distinctFrom.map((entry) =>
row(DISTINCT_FROM_LABEL, linkOf(entry.record) + LABEL_SEPARATOR + entry.reason),
),
...(contract.canon.length === 0 ? [] : [row(CANON_LABEL, canonOf(contract.canon))]),
]);
};
const derivation = function derivation(contract: ContractView): readonly Block[] {
if (contract.derivationMap.length === 0) {
return [];
}
return [
text(DERIVATION_LABEL),
glossary(contract.derivationMap.map((step) => row(step.stage.label, linkOf(step.record)))),
];
};
const productions = function productions(contract: ContractView): readonly Block[] {
if (contract.productions.length === 0) {
return [];
}
const lines = contract.productions.map((production) => production.lhs + PRODUCTION_ARROW + production.rhs);
return [codeOf(PRODUCTIONS_TITLE, lines.join(LINE_BREAK), BNF_LANGUAGE)];
};
const flow = function flow(contract: ContractView): readonly Block[] {
return contract.flow.length === 0 ? [] : [codeOf(FLOW_TITLE, contract.flow.join(FLOW_ARROW), TEXT_LANGUAGE)];
};
const contractSubsection = function contractSubsection(contract: ContractView, resolution: ResolutionView): Subsection {
return {
blocks: [
coordinates(contract),
glossary([row(INTENT_LABEL, contract.intent), row(INVARIANT_LABEL, contract.invariant)]),
...flow(contract),
...productions(contract),
joins(contract),
...derivation(contract),
...exemplarBlocks(contract.exemplar, BEFORE_TITLE, AFTER_TITLE),
...checkBlocks(resolution, ALGO_FACE + FACE_SEPARATOR + contract.id),
],
id: ALGO_ANCHOR + contract.id,
title: contract.title,
};
};
const domainDiagram = function domainDiagram(group: ContractDomainView): string {
const members = new Set(group.contracts.map((contract) => contract.id));
const nodes = group.contracts.map((contract) => node(contract.id, contract.title));
const edges = group.contracts.flatMap((contract) =>
[...contract.composes, ...contract.derivationMap.map((step) => step.record)].flatMap((target) => {
const id = localId(target, ALGO_FACE, members);
return id === null || id === contract.id ? [] : [edgeLine(contract.id, EDGE_SOLID, id)];
}),
);
return diagram(HEADER, [...nodes, ...new Set(edges)]);
};
const domainSection = function domainSection(group: ContractDomainView, resolution: ResolutionView): Section {
return {
blocks: [{ caption: DOMAIN_CAPTION, kind: "mermaid", text: domainDiagram(group) }],
icon: DOMAIN_SECTION_ICON,
id: ALGO_DOMAIN_ANCHOR + group.id,
intro: DOMAIN_INTRO,
subsections: group.contracts.map((contract) => contractSubsection(contract, resolution)),
title: groupTitleOf(group.id, group.domain),
};
};
export const contractSections = function contractSections(
groups: readonly ContractDomainView[],
resolution: ResolutionView,
): readonly Section[] {
return groups.map((group) => domainSection(group, resolution));
};