core/converters/graph.concern.converter.ts
core/converters/graph.concern.converter.ts is a file in Bane's Lab Build Scripts. 49 lines of code and 10 definitions.
import type { AnatomyFile, AnatomyFolder } from "@banes-lab/web/types/anatomy.types.js";
import type { ConcernScope, ConcernSource } from "#types/graph.types";
import { FACE_SEPARATOR, LEX_CATEGORY_FACE, LEX_FACE } from "@govlab/constants";
import { ANATOMY_PREFIX } from "#configuration/constants/graph.constants";
import type { GraphEdge } from "@banes-lab/web/types/graph.types.js";
import type { Term } from "@govlab/context";
import { tagOfTerm } from "@govlab/context/core/selectors/lexicon.selector.ts";
export const concernScopeOf = function concernScopeOf(context: ConcernSource): ConcernScope {
return {
fileRef: (path) => ANATOMY_PREFIX + context.ids.fileId(path),
records: new Set(context.ontology.nodes.map((node) => node.ref)),
roots: context.trees.map((tree) => tree.snapshot.tree),
terms: context.built.context.lex.all(),
};
};
const filesOf = function filesOf(folder: AnatomyFolder): readonly AnatomyFile[] {
return [...folder.files, ...folder.folders.flatMap(filesOf)];
};
const termsByTag = function termsByTag(terms: readonly Term[]): ReadonlyMap<string, Term> {
return new Map(
terms.flatMap((term) => {
const tag = tagOfTerm(term);
return tag === null ? [] : [[tag, term] as const];
}),
);
};
const edgesOf = function edgesOf(
scope: ConcernScope,
relation: string,
targetOf: (file: AnatomyFile, term: Term) => string | null,
): readonly GraphEdge[] {
const byTag = termsByTag(scope.terms);
return scope.roots.flatMap(filesOf).flatMap((file): readonly GraphEdge[] => {
const term = file.slots === null ? undefined : byTag.get(file.slots.concern);
const to = term === undefined ? null : targetOf(file, term);
return to === null || !scope.records.has(to) ? [] : [{ from: scope.fileRef(file.path), relation, to }];
});
};
export const concernEdges = function concernEdges(scope: ConcernScope, relation: string): readonly GraphEdge[] {
return edgesOf(scope, relation, (file, term) => (file.slots === null ? null : LEX_FACE + FACE_SEPARATOR + term.id));
};
export const concernLayerEdges = function concernLayerEdges(
scope: ConcernScope,
relation: string,
): readonly GraphEdge[] {
return edgesOf(scope, relation, (file, term) =>
file.layer === null ? null : LEX_CATEGORY_FACE + FACE_SEPARATOR + term.category,
);
};