core/converters/graph.link.converter.ts
core/converters/graph.link.converter.ts is a file in Bane's Lab Build Scripts. 50 lines of code and 10 definitions.
import { BUILDS_ON_RELATION, EVIDENCE_RELATION_ID, LINKS_TO_RELATION } from "@banes-lab/web/constants/graph.constants";
import type { RouteEdges, SiteScope } from "#types/graph.types";
import { CHAPTER_PREFIX } from "#configuration/constants/graph.constants";
import type { EvidenceNode } from "@banes-lab/web/types/evidence.types.js";
import type { GraphEdge } from "@banes-lab/web/types/graph.types.js";
import type { RouteStop } from "#types/learning.types";
import type { WebModules } from "#types/loader.types";
import { sectionEdges } from "#core/converters/section.converter";
import { unresolvedEvidence } from "#configuration/strings/graph.strings";
const FACE_MARK = ":";
const refsOf = function refsOf(links: readonly { readonly ref: string | null }[]): readonly string[] {
return links.flatMap((link) => (link.ref === null ? [] : [link.ref]));
};
export const linkEdges = function linkEdges(scope: Pick<SiteScope, "linker" | "plans">): readonly GraphEdge[] {
const { outgoing } = sectionEdges(scope.plans, scope.linker);
const relation = LINKS_TO_RELATION;
return [...outgoing.entries()].flatMap(([from, links]) => refsOf(links).map((to) => ({ from, relation, to })));
};
export const evidenceEdges = function evidenceEdges(
web: Pick<WebModules, "evidence" | "evidenceConstants">,
targetOf: (node: EvidenceNode) => string | null,
subjects: readonly string[],
): readonly GraphEdge[] {
const relation = EVIDENCE_RELATION_ID;
return subjects.flatMap((from) =>
web.evidence
.evidenceFor({ face: from.slice(0, from.indexOf(FACE_MARK)), ref: from }, web.evidenceConstants.EVIDENCE)
.flatMap((entry) => entry.nodes)
.map((node) => {
const to = targetOf(node);
if (to === null) {
throw new Error(unresolvedEvidence(from, node));
}
return { from, relation, to };
}),
);
};
export const routeEdges = function routeEdges(stops: readonly RouteStop[]): RouteEdges {
const pathOf = new Map(stops.map((stop) => [stop.id, stop.path]));
const relation = BUILDS_ON_RELATION;
const required = stops.flatMap((stop) => stop.requires.map((id) => ({ id, path: pathOf.get(id), stop })));
return {
edges: required.flatMap(({ path, stop }) =>
path === undefined ? [] : [{ from: CHAPTER_PREFIX + stop.path, relation, to: CHAPTER_PREFIX + path }],
),
unresolved: required
.filter(({ path }) => path === undefined)
.map(({ id, stop }) => ({ from: CHAPTER_PREFIX + stop.path, label: id, relation })),
};
};