import type { AgNumericValue } from 'ag-charts-types'; import type { BandedReducer } from './data-model/reducers/bandedReducer'; import type { DataChangeDescription } from './dataChangeDescription'; import type { BandedDomain, BandedDomainConfig } from './dataDomain'; import type { DataSet } from './dataSet'; import type { RangeLookup } from './rangeLookup'; import type { SortOrder } from './sortOrder'; export interface ScopeProvider { id: string; } export interface DataGroup { keys: any[]; datumIndices: readonly (readonly number[])[]; aggregation: any[][]; validScopes: Set; } export interface UngroupedDataItem { index: I; keys: any[]; values: V; aggValues?: [AgNumericValue, AgNumericValue][]; datum: D; validScopes?: Set; } export declare const KEY_SORT_ORDERS: unique symbol; export declare const COLUMN_SORT_ORDERS: unique symbol; export declare const DOMAIN_RANGES: unique symbol; export declare const DOMAIN_BANDS: unique symbol; export declare const REDUCER_BANDS: unique symbol; export interface BandedReducerStats extends Record { totalBands: number; dirtyBands: number; dataSize: number; scanRatio: number; cacheHits: number; } export declare const SHARED_ZERO_INDICES: readonly number[]; export type ScopeId = string; /** * Per-column value type, set once during extraction; an advisory tag consumers dispatch off rather than * re-sniffing values. `'mixed-numeric'` is a column of both `number` and `bigint`; `'object'` is non-`Date` * objects whose element type the caller supplies rather than this tag. */ export type ColumnValueType = 'number' | 'bigint' | 'date' | 'string' | 'boolean' | 'mixed-numeric' | 'object'; export type ColumnValueTypeMapping = { number: number; bigint: bigint; date: Date; string: string; boolean: boolean; 'mixed-numeric': AgNumericValue; object: unknown; }; export type ProcessedValue = { value: unknown; missing: boolean; valid: boolean; }; export type SortOrderEntry = { sortOrder: SortOrder; isUnique?: boolean; isDirty?: boolean; }; export type ProcessedValueEntry = { value: any; valid: boolean; }; export interface GroupDatumIteratorOutput { group: DataGroup; groupIndex: number; columnIndex: number; datumIndex: number; } export type InsertionCacheValue = { keys: Map; values: Map; hasInvalidKey: boolean; hasInvalidValue: boolean; hasMissingValue: boolean; }; export type InsertionCache = Map; export type ColumnBatch = [ScopeId, number[], unknown[][], Set, boolean[] | undefined, boolean[] | undefined]; export type MergedColumnBatch = [ ScopeId[], number[], unknown[][], Set, boolean[] | undefined, boolean[] | undefined ]; export interface CommonMetadata { input: { count: number; }; scopes: Set; dataSources: Map>; invalidKeys: Map | undefined; invalidKeyCount: Map | undefined; invalidData: Map | undefined; invalidDataCount: Map | undefined; missingData: Map | undefined; keys: Map[]; columns: any[][]; columnScopes: Set[]; columnNeedValueOf?: boolean[]; columnValueType?: (ColumnValueType | undefined)[]; domain: { keys: any[][]; values: any[][]; groups?: any[][]; aggValues?: [AgNumericValue, AgNumericValue][]; }; reduced?: { diff?: Record; smallestKeyInterval?: AgNumericValue; largestKeyInterval?: AgNumericValue; filteredValueExceedUnfiltered?: boolean; sortedGroupDomain?: any[][]; animationValidation?: { uniqueKeys: boolean; orderedKeys: boolean; }; }; defs: { keys: (Scoped & DatumPropertyDefinition)[]; values: (Scoped & DatumPropertyDefinition)[]; allScopesHaveSameDefs: boolean; }; partialValidDataCount: number; time: number; /** Monotonically increasing version counter, incremented on every processing cycle */ version: number; optimizations?: OptimizationMetadata; [DOMAIN_RANGES]: Map; [KEY_SORT_ORDERS]: Map; [COLUMN_SORT_ORDERS]: Map; [DOMAIN_BANDS]: Map, BandedDomain>; [REDUCER_BANDS]?: Map; changeDescription?: DataChangeDescription; } export interface UngroupedData extends CommonMetadata { type: 'ungrouped'; aggregation?: [AgNumericValue, AgNumericValue][][]; } export interface GroupedData extends CommonMetadata { type: 'grouped'; groups: DataGroup[]; groupsUnique: boolean; } export type ProcessedOutputDiff = { changed: boolean; added: Set; updated: Set; removed: Set; moved: Set; }; export interface ProcessedDataDef { index: number; def: PropertyDefinition; } export type ProcessedData = UngroupedData | GroupedData; /** Metadata about applied/skipped optimizations for debugging */ export interface OptimizationMetadata { /** Was reprocessing path used? */ reprocessing?: { applied: boolean; reason?: string; }; /** Domain banding optimization per definition */ domainBanding?: { keyDefs: Array<{ property: string; applied: boolean; reason?: string; stats?: { totalBands: number; dirtyBands: number; dataSize: number; scanRatio: number; }; }>; valueDefs: Array<{ property: string; applied: boolean; reason?: string; stats?: { totalBands: number; dirtyBands: number; dataSize: number; scanRatio: number; }; }>; }; /** Shared datum indices optimization (grouped data only) */ sharedDatumIndices?: { applied: boolean; sharedGroupCount: number; totalGroupCount: number; }; /** Batch merging optimization */ batchMerging?: { originalBatchCount: number; mergedBatchCount: number; mergeRatio: number; }; /** Reducer banding optimization */ reducerBanding?: { reducers: Array<{ property: string; applied: boolean; reason?: string; stats?: BandedReducerStats; }>; }; /** Overall performance metrics */ performance?: { processingTime: number; pathTaken: 'full-process' | 'reprocess'; }; } export type DatumPropertyType = 'range' | 'category'; export type MissMap = Map; export type GroupingFn = (keys: unknown[]) => K[]; export type GroupByFn = (extractedData: UngroupedData) => GroupingFn; export type DataModelOptions = { props: PropertyDefinition[]; groupByKeys?: Grouped; groupByData?: Grouped; groupByFn?: GroupByFn; domainBandingConfig?: BandedDomainConfig; }; export type PropertyDefinition = (DatumPropertyDefinition & (IsScoped extends true ? Scoped : unknown)) | AggregatePropertyDefinition | (PropertyValueProcessorDefinition & (IsScoped extends true ? Scoped : unknown)) | GroupValueProcessorDefinition | ReducerOutputPropertyDefinition | ProcessorOutputPropertyDefinition; export type ProcessorFn = (datum: unknown, index: number) => unknown; export type PropertyId = K | { id: string; }; export type Scoped = { /** Scope(s) a property definition belongs to (typically the defining entities unique identifier). */ scopes: ScopeId[]; }; export type PropertyIdentifiers = { id?: string; /** Map> */ idsMap?: Map>; /** Optional group a property belongs to, for cross-scope combination. */ groupId?: string; }; export type PropertySelectors = { /** Optional group a property belongs to, for cross-scope combination. */ matchGroupIds?: string[]; }; export type DatumPropertyDefinition = PropertyIdentifiers & { type: 'key' | 'value'; valueType: DatumPropertyType; /** True for time scales, so a discrete domain coerces ISO 8601 strings to Date instants. */ timeDomain?: boolean; property: K; forceValue?: any; includeProperty?: boolean; invalidValue?: any; missing?: MissMap; missingValue?: any; separateNegative?: boolean; validation?: (value: any, datum: any, index: number) => boolean; processor?: () => ProcessorFn; allowNullKey?: boolean; }; export type InternalDefinition = { index: number; } & (IsScoped extends true ? Scoped : unknown); export type InternalDatumPropertyDefinition = DatumPropertyDefinition & InternalDefinition & { missing: MissMap; }; export type AggregatePropertyDefinition = Omit & PropertySelectors & { type: 'aggregate'; aggregateFunction: (values: D[K][], keys?: D[K][]) => R; groupAggregateFunction?: (next?: R, acc?: R2) => R2; finalFunction?: (result: R2) => [number, number]; }; export type GroupValueAdjustFn = (columns: D[K][][], indexes: number[], dataGroup: DataGroup, groupIndex: number) => void; export type GroupValueProcessorDefinition = PropertyIdentifiers & PropertySelectors & { type: 'group-value-processor'; /** * Outer function called once per all data processing; inner function called once per group; * innermost called once per datum. */ adjust: () => () => GroupValueAdjustFn; /** * Indicates whether this processor supports incremental reprocessing. * When true, the processor can safely be reapplied to modified data without * causing double-processing issues. */ supportsReprocessing?: boolean; }; export type PropertyValueAdjustFn = (processedData: ProcessedData, valueIndex: number) => void; export type PropertyValueProcessorDefinition = PropertyIdentifiers & { type: 'property-value-processor'; property: string; adjust: () => PropertyValueAdjustFn; }; export type ReducerOutputTypes = NonNullable['reduced']>; export type ReducerOutputKeys = keyof ReducerOutputTypes; export type ReducerBandKey = Extract; export type ReducerOutputPropertyDefinition

= PropertyIdentifiers & { type: 'reducer'; property: P; initialValue?: ReducerOutputTypes[P]; reducer: () => (acc: ReducerOutputTypes[P], keys: unknown[]) => ReducerOutputTypes[P]; supportsBanding?: boolean; combineResults?: (bandResults: ReducerOutputTypes[P][]) => ReducerOutputTypes[P]; needsOverlap?: boolean; }; export type ProcessorOutputPropertyDefinition

= PropertyIdentifiers & { type: 'processor'; property: P; calculate: (data: ProcessedData, previousValue: ReducerOutputTypes[P] | undefined) => ReducerOutputTypes[P]; incrementalCalculate?: (data: ProcessedData, previousValue: ReducerOutputTypes[P] | undefined) => ReducerOutputTypes[P]; };