import { useMemo } from 'react' import { fillTimeseries } from '@/components/interfaces/Settings/Logs/Logs.utils' import type { Datum } from '@/components/ui/Charts/Charts.types' export type FillTimeseriesOptions = { /** The timeseries data to fill gaps in */ data: T[] /** The key in each data object that contains the timestamp */ timestampKey: string /** The key(s) to fill with default values when gaps exist */ valueKey: string | string[] /** Default value to use for gaps */ defaultValue: number /** Start of the time range (ISO string) */ startDate?: string /** End of the time range (ISO string) */ endDate?: string /** Minimum number of points before filling is applied */ minPointsToFill?: number /** Optional interval specification (e.g., '5m', '1h') */ interval?: string } export type FillTimeseriesResult = { data: T[] error: Error | null isError: boolean } /** * Sorts timeseries data by timestamp in ascending order * Returns a new sorted array without mutating the input */ export function sortByTimestamp(data: T[], timestampKey: string): T[] { return [...data].sort((a, b) => { return ( new Date(a[timestampKey] as string).getTime() - new Date(b[timestampKey] as string).getTime() ) }) } /** * Validates that the data has a valid timestamp key */ export function hasValidTimestamp(data: T[], timestampKey: string): boolean { return Boolean(data[0]?.[timestampKey]) } /** * Convenience hook for memoized filling of timeseries data. * * Fills gaps in timeseries data and sorts results by timestamp. * * @example * ```ts * const { data, error, isError } = useFillTimeseriesSorted({ * data: chartData, * timestampKey: 'timestamp', * valueKey: 'count', * defaultValue: 0, * startDate: startIso, * endDate: endIso * }) * ``` */ export const useFillTimeseriesSorted = ( options: FillTimeseriesOptions ): FillTimeseriesResult => { const { data, timestampKey, valueKey, defaultValue, startDate, endDate, minPointsToFill = 20, interval, } = options return useMemo(() => { // Early return if no valid timestamp if (!hasValidTimestamp(data, timestampKey)) { return { data, error: null, isError: false, } } try { const filled = fillTimeseries( data, timestampKey, valueKey, defaultValue, startDate, endDate, minPointsToFill, interval ) as T[] const sorted = sortByTimestamp(filled, timestampKey) return { data: sorted, error: null, isError: false, } } catch (error: unknown) { return { data: [], error: error instanceof Error ? error : new Error(String(error)), isError: true, } } }, [ JSON.stringify(data), timestampKey, JSON.stringify(valueKey), defaultValue, startDate, endDate, minPointsToFill, interval, ]) }