All files / cwv/_collections cwv-aggregator.util.ts

96.15% Statements 50/52
91.66% Branches 11/12
100% Functions 2/2
96.15% Lines 50/52

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 531x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 6x     6x 6x 1x 1x 5x 5x 5x 6x 3x 3x 2x 2x 2x 1x 1x 1x 2x 2x 2x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x  
import { DyE2E_CWVMetric_Type } from '../../contracts/_enums/cwv-metric-type.enum';
import { DyE2E_CWVMeasurement_DataModel } from '../_models/cwv-measurement.data-model';
 
/**
 * Percentile + aggregator util — N-iter measurement-tömb → p50/p75/p95 + min/max/mean.
 */
export class DyE2E_CWVAggregator_Util {
 
  /**
   * `arr` legkisebbtől legnagyobbig — visszaadja az adott percentile-t lineáris
   * interpolációval (NIST recipe-mode 8).
   */
  static percentile(values: number[], p: number): number {
    if (values.length === 0) {
      return NaN;
    }
    const sorted: number[] = [...values].sort((a: number, b: number): number => a - b);
    if (sorted.length === 1) {
      return sorted[0];
    }
    const rank: number = p * (sorted.length - 1);
    const lo: number = Math.floor(rank);
    const hi: number = Math.ceil(rank);
    if (lo === hi) {
      return sorted[lo];
    }
    const frac: number = rank - lo;
    return sorted[lo] * (1 - frac) + sorted[hi] * frac;
  }
 
  /** Aggregálja a measurement-eket egy `{ p50, p75, p95, min, max, mean, n }` summary-vé. */
  static summarize(measurements: DyE2E_CWVMeasurement_DataModel[], metric: DyE2E_CWVMetric_Type): {
    p50: number; p75: number; p95: number; min: number; max: number; mean: number; n: number;
  } {
    const values: number[] = measurements
      .filter((m: DyE2E_CWVMeasurement_DataModel): boolean => m.metric === metric)
      .map((m: DyE2E_CWVMeasurement_DataModel): number => m.value);
    if (values.length === 0) {
      return { p50: NaN, p75: NaN, p95: NaN, min: NaN, max: NaN, mean: NaN, n: 0 };
    }
    const sum: number = values.reduce((acc: number, v: number): number => acc + v, 0);
    return {
      p50: DyE2E_CWVAggregator_Util.percentile(values, 0.5),
      p75: DyE2E_CWVAggregator_Util.percentile(values, 0.75),
      p95: DyE2E_CWVAggregator_Util.percentile(values, 0.95),
      min: Math.min(...values),
      max: Math.max(...values),
      mean: sum / values.length,
      n: values.length,
    };
  }
}