/** * Pure grouping logic for SmartGroupFieldRecipe (the "auto" / Field Recipe mode). * * Mirrors the design prototype's live grouping engine: groups are formed by * joining the values of whichever fields are switched on, in field order. * Kept framework-free so it is unit-testable in isolation from the component. */ /** A field/factor the user can group by. */ export interface SmartGroupField { /** Column key as it appears in each sample record. */ key: string; /** Display role, e.g. `Factor` or `Replicate`. */ role: string; /** Comma-separated preview of the field's distinct values. */ vals: string; /** Whether this field is a replicate dimension (grouping by it shatters groups). */ rep: boolean; } /** A single sample as a flat key → value record. */ export type SmartGroupSampleRecord = Record; /** A resolved group in the live preview rail. */ export interface FieldRecipeGroup { name: string; count: number; color: string; } /** Name of the QC pool group appended by `appendQcGroup`. */ export declare const QC_POOL_NAME = "QC_Pool"; /** How QC samples are routed relative to the biological groups. */ export type QcRoute = 'Overlay only' | 'Exclude' | 'Mix into groups'; /** * Kind of inline summary callout to render. `warn`: a replicate field is on. * `singletons`: no replicate field is on, but half or more of the groups have one sample. */ export type FieldRecipeSummaryKind = 'mute' | 'warn' | 'singletons' | 'info'; export interface FieldRecipeSummary { kind: FieldRecipeSummaryKind; /** Number of base (non-QC) groups the current toggles produce. */ groupCount: number; } /** * Build the ordered group list from whichever fields are switched on. * Returns an empty list when no field is active. `layerOrder` (field indices * in layer order) overrides the default field-order joining of the group name. */ export declare function computeFieldGroups(samples: SmartGroupSampleRecord[], fields: SmartGroupField[], on: boolean[], palette: string[], layerOrder?: readonly number[]): FieldRecipeGroup[]; /** * Append the QC pool group when QC is mixed into the biological groups. * `Overlay only` and `Exclude` leave the group list untouched. */ export declare function appendQcGroup(groups: FieldRecipeGroup[], route: QcRoute, qcColor: string, qcCount?: number): FieldRecipeGroup[]; /** Total samples the grouping applies to: QC is dropped only when excluded. */ export declare function sampleTotalFor(route: QcRoute, realCount?: number, qcCount?: number): number; /** * True when half or more of the groups have one sample: the design has no * replicate in the names, or a field that is on is not part of the condition. */ export declare function mostlySingletons(groups: FieldRecipeGroup[]): boolean; /** Decide which inline summary callout the Field Recipe should show. */ export declare function fieldRecipeSummary(input: { activeFactors: string[]; repOn: boolean; baseGroups: FieldRecipeGroup[]; }): FieldRecipeSummary;