Code coverage report for browser/src/apm/performance-timer.ts

Statements: 0% (0 / 33)      Branches: 0% (0 / 32)      Functions: 0% (0 / 8)      Lines: 0% (0 / 33)      Ignored: none     

All files » browser/src/apm/ » performance-timer.ts
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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109                                                                                                                                                                                                                         
import {
  Providers,
  Props,
  Tags,
  joinFqn,
  TimerWrapperFactory,
  TimerWrapper,
  PropEnabled,
  Env,
} from '@btilford/ts-base-core';
 
 
export type PerformanceTimerOptions = {
  performance?: Performance;
  env?: Props;
  tags?: Tags;
  parent?: PerformanceTimer<any>;
  startSuffix?: string;
  endSuffix?: string;
  measureSuffix?: string;
}
 
 
export class PerformanceTimer<T> extends TimerWrapper<T> {
  readonly tags: Tags;
  readonly fqn: string;
 
  protected readonly options: PerformanceTimerOptions;
  protected readonly perf: Performance;
  protected readonly _enabled: PropEnabled;
 
 
  constructor(readonly name: string, tags: Tags, options: PerformanceTimerOptions) {
    super();
    this.fqn = joinFqn(name, options.parent?.fqn);
    this.perf = options.performance || performance;
    this.options = { ...options };
    this.tags = {
      ...options.tags,
      ...tags,
    };
    const env = options.env
                || options.parent?.options.env?.getConfig(this.name)
                || Providers.provide(Env).getConfig(this.fqn);
 
    this._enabled = options.parent?._enabled.extend(this.name, 'true') ||
                    new PropEnabled(
                      { name: this.name },
                      Providers.useOrProvide(Env, env).getConfig(this.name),
                    )
  }
 
 
  wrap(func: (...args: unknown[]) => T): (...args: unknown[]) => T {
    const label = this.fqn;
    const perf = this.perf;
    const end = joinFqn(this.options.measureSuffix || this.options.endSuffix || 'end', label)
    const start = joinFqn(this.options.startSuffix || 'start', label);
    return function consoleTimerWrapper(...args: unknown[]): T {
      perf.mark(start);
 
      const result: T = func(...args);
      try {
        if (result instanceof Promise) {
          result.then(result => {
            perf.measure(end);
            return result;
          }).catch(err => {
            perf.measure(end);
            return err;
          });
        }
        else {
          perf.measure(end);
        }
      }
      catch (error) {
        perf.measure(end);
        throw error;
      }
      return result;
    };
  }
 
}
 
 
export class PerformanceTimerFactory extends TimerWrapperFactory {
  protected readonly options: PerformanceTimerOptions;
 
 
  constructor(options: PerformanceTimerOptions) {
    super();
    this.options = { ...options };
  }
 
 
  asyncTimer<T>(name: string, tags: Tags = {}): TimerWrapper<Promise<T>> {
    return new PerformanceTimer(name, tags, this.options);
  }
 
 
  timer<T>(name: string, tags: Tags = {}): TimerWrapper<T> {
    return new PerformanceTimer(name, tags, this.options);
  }
 
 
}