core/factories/record.factory.ts
core/factories/record.factory.ts is a file in GovLab Patterns. 48 lines of code and 11 definitions.
import type { RepresentationRuntime } from "#types/representation.types";
import type { Rng } from "#types/seed.types";
import type { SynthesizeOptions } from "#types/record.types";
import { createRng } from "#core/factories/seed.factory";
import { detectSchema } from "#core/analyzers/schema.analyzer";
import { inferMapping } from "#core/resolvers/representation.resolver";
import { runtimeFor } from "#core/selectors/representation.selector";
const DEFAULT_COUNT = 10;
const buildSamplers = function buildSamplers(
mapping: ReadonlyMap<string, readonly string[]>,
records: readonly unknown[],
): Map<string, RepresentationRuntime> {
const samplers = new Map<string, RepresentationRuntime>();
for (const [field, [first]] of mapping) {
const factory = first === undefined ? undefined : runtimeFor(first);
if (factory) {
const runtime = factory(field);
runtime.update(records);
samplers.set(field, runtime);
}
}
return samplers;
};
const drawRecord = function drawRecord(
samplers: ReadonlyMap<string, RepresentationRuntime>,
rng: Rng,
): Record<string, unknown> {
const record: Record<string, unknown> = {};
for (const [field, runtime] of samplers) {
const value = runtime.sample(rng);
if (value !== null) {
record[field] = value;
}
}
return record;
};
export const synthesize = function synthesize(
records: readonly unknown[],
options: SynthesizeOptions = {},
): Record<string, unknown>[] {
const mapping = options.mapping ?? inferMapping(detectSchema(records, options.floatFields));
const samplers = buildSamplers(mapping, records);
if (samplers.size === 0) {
return [];
}
const rng = createRng(options.seed ?? 0);
return Array.from({ length: options.count ?? DEFAULT_COUNT }, () => drawRecord(samplers, rng));
};