core/analyzers/field.analyzer.ts
core/analyzers/field.analyzer.ts is a file in GovLab Patterns. 43 lines of code and 14 definitions.
import { analysisNode, findingNode } from "#core/factories/node.factory";
import type { FieldOutput } from "#types/record.types";
import type { RepresentationRuntime } from "#types/representation.types";
import { runtimeFor } from "#core/selectors/representation.selector";
interface BoundRuntime {
representation: string;
runtime: RepresentationRuntime;
}
const bind = function bind(field: string, representations: readonly string[]): BoundRuntime[] {
return representations.flatMap((representation) => {
const factory = runtimeFor(representation);
return factory ? [{ representation, runtime: factory(field) }] : [];
});
};
export class FieldAnalyzer {
private readonly field: string;
private readonly runtimes: readonly BoundRuntime[];
public constructor(field: string, representations: readonly string[]) {
this.field = field;
this.runtimes = bind(field, representations);
}
public update(chunk: readonly unknown[]): void {
for (const { runtime } of this.runtimes) {
runtime.update(chunk);
}
}
public produce(): FieldOutput {
const fragments = this.runtimes.map((bound) => this.emit(bound));
return {
findings: fragments.flatMap((fragment) => fragment.findings),
nodes: fragments.flatMap((fragment) => fragment.nodes),
};
}
private emit(bound: BoundRuntime): FieldOutput {
const produced = bound.runtime.findings();
if (produced.length === 0) {
return { findings: [], nodes: [] };
}
const analysis = analysisNode(this.field, bound.representation);
const findingNodes = produced.map((finding) => findingNode(analysis.id, finding.name, finding.coordinate));
return { findings: produced, nodes: [analysis, ...findingNodes] };
}
}