{"version":3,"file":"ngs-request-tracker.mjs","sources":["../../../projects/ngs-request-tracker/src/lib/data-access/services/request-tracker.service.ts","../../../projects/ngs-request-tracker/src/lib/data-access/interceptors/request-tracker.interceptor.ts","../../../projects/ngs-request-tracker/src/lib/data-access/components/request-tracker/request-tracker.component.ts","../../../projects/ngs-request-tracker/src/lib/data-access/components/request-tracker/request-tracker.component.html","../../../projects/ngs-request-tracker/src/public-api.ts","../../../projects/ngs-request-tracker/src/ngs-request-tracker.ts"],"sourcesContent":["import { BehaviorSubject, map } from 'rxjs';\nimport { Injectable } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\n\n@Injectable({\n  providedIn: 'root',\n})\nexport class RequestTrackerService {\n  requestId = 0;\n\n  /**\n   * Tracks the number of ongoing HTTP requests.\n   *\n   * @default 0\n   */\n  private _countInProgress$ = new BehaviorSubject<number>(0);\n\n  /**\n   * Tracks the number of aborted HTTP requests.\n   *\n   * @default 0\n   */\n  private _countAborted$ = new BehaviorSubject<number>(0);\n\n  /**\n   * Tracks the number of all HTTP requests.\n   *\n   * @default 0\n   */\n  private _count$ = new BehaviorSubject<number>(0);\n\n  /**\n   * Tracks the number of successfully completed HTTP requests.\n   *\n   * @default 0\n   */\n  private _countSuccess$ = new BehaviorSubject<number>(0);\n\n  /**\n   * Tracks the number of failed HTTP requests.\n   *\n   * @default 0\n   */\n  private _countError$ = new BehaviorSubject<number>(0);\n\n  /**\n   * Stores the duration of completed HTTP requests in milliseconds.\n   * Used for calculating the average response time.\n   */\n  private _requestTimes: number[] = [];\n\n  /**\n   * A map to associate each request ID with its start time.\n   * Used to calculate the duration of individual requests.\n   */\n  private startTimes: Map<number, number> = new Map();\n\n  /**\n   * Observable stream of the number of ongoing HTTP requests.\n   */\n  countInProgress$ = this._countInProgress$.asObservable();\n\n  /**\n   * Signal for the number of ongoing HTTP requests.\n   *\n   * Provides real-time access to the count.\n   */\n  countInProgress = toSignal(this.countInProgress$, { requireSync: true });\n\n  /**\n   * Observable stream of the number of all HTTP requests.\n   */\n  count$ = this._count$.asObservable();\n\n  /**\n   * Signal for the number of all HTTP requests.\n   *\n   * Provides real-time access to the count.\n   */\n  count = toSignal(this.count$, { requireSync: true });\n\n  /**\n   * Observable stream of the number of successful HTTP requests.\n   */\n  countSuccess$ = this._countSuccess$.asObservable();\n\n  /**\n   * Signal for the number of successful HTTP requests.\n   *\n   * Provides real-time access to the count.\n   */\n  countSuccess = toSignal(this.countSuccess$, { requireSync: true });\n\n  /**\n   * Observable stream of the number of failed HTTP requests.\n   */\n  countError$ = this._countError$.asObservable();\n\n  /**\n   * Signal for the number of failed HTTP requests.\n   *\n   * Provides real-time access to the count.\n   */\n  countError = toSignal(this.countError$, { requireSync: true });\n\n  /**\n   * Observable stream of the number of failed HTTP requests.\n   */\n  countAborted$ = this._countAborted$.asObservable();\n\n  /**\n   * Signal for the number of failed HTTP requests.\n   *\n   * Provides real-time access to the count.\n   */\n  countAborted = toSignal(this.countAborted$, { requireSync: true });\n\n  /**\n   * Observable stream indicating whether there are any ongoing HTTP requests.\n   */\n  isInProgress$ = this.countInProgress$.pipe(map((count) => Boolean(count)));\n\n  /**\n   * Signal indicating whether there are any ongoing HTTP requests.\n   */\n  isInProgress = toSignal(this.isInProgress$, { requireSync: true });\n\n  /**\n   * Observable stream of the average response time (in milliseconds) for completed HTTP requests.\n   */\n  averageResponseTime$ = new BehaviorSubject<number>(0);\n\n  /**\n   * Signal for the average response time (in milliseconds) for completed HTTP requests.\n   */\n  averageResponseTime = toSignal(this.averageResponseTime$, {\n    requireSync: true,\n  });\n\n  /**\n   * Observable stream of the success rate as a percentage.\n   */\n  successRate$ = new BehaviorSubject<number>(0);\n\n  /**\n   * Signal for the success rate as a percentage.\n   */\n  successRate = toSignal(this.successRate$, { requireSync: true });\n\n  /**\n   * Observable stream of the aborted rate as a percentage.\n   */\n  abortedRate$ = new BehaviorSubject<number>(0);\n\n  /**\n   * Signal for the aborted rate as a percentage.\n   */\n  abortedRate = toSignal(this.abortedRate$, { requireSync: true });\n\n  /**\n   * Observable stream of the error rate as a percentage.\n   */\n  errorRate$ = new BehaviorSubject<number>(0);\n\n  /**\n   * Signal for the error rate as a percentage.\n   */\n  errorRate = toSignal(this.errorRate$, { requireSync: true });\n\n  /**\n   * Marks the start of an HTTP request.\n   *\n   * @param requestId Unique identifier for the request.\n   */\n  requestSent(requestId: number): void {\n    this.startTimes.set(requestId, performance.now());\n    this._count$.next(this._count$.value + 1);\n    this._countInProgress$.next(this._countInProgress$.value + 1);\n  }\n\n  /**\n   * Marks the successful completion of an HTTP request.\n   *\n   * @param requestId Unique identifier for the request.\n   */\n  requestSuccess(requestId: number): void {\n    const startTime = this.startTimes.get(requestId);\n    if (startTime !== undefined) {\n      const duration = performance.now() - startTime;\n      this._requestTimes.push(duration);\n      this.startTimes.delete(requestId);\n    }\n    this._countInProgress$.next(this._countInProgress$.value - 1);\n    this._countSuccess$.next(this._countSuccess$.value + 1);\n    this.updateMetrics();\n  }\n\n  /**\n   * Marks the failure of an HTTP request.\n   *\n   * @param requestId Unique identifier for the request.\n   */\n  requestError(requestId: number): void {\n    this.startTimes.delete(requestId);\n    this._countInProgress$.next(this._countInProgress$.value - 1);\n    this._countError$.next(this._countError$.value + 1);\n    this.updateMetrics();\n  }\n\n  /**\n   * Marks the aborted HTTP request.\n   *\n   * @param requestId Unique identifier for the request.\n   */\n  requestAborted(requestId: number): void {\n    this.startTimes.delete(requestId);\n    this._countInProgress$.next(this._countInProgress$.value - 1);\n    this._countAborted$.next(this._countAborted$.value + 1);\n    this.updateMetrics();\n  }\n\n  /**\n   * Updates metrics including average response time, success rate, and error rate.\n   */\n  private updateMetrics(): void {\n    if (this._requestTimes.length > 0) {\n      const averageTime =\n        this._requestTimes.reduce((sum, time) => sum + time, 0) /\n        this._requestTimes.length;\n      this.averageResponseTime$.next(averageTime);\n    }\n\n    if (this.count() > 0) {\n      this.errorRate$.next((this.countError() / this.count()) * 100);\n      this.successRate$.next((this.countSuccess() / this.count()) * 100);\n      this.abortedRate$.next((this.countAborted() / this.count()) * 100);\n    }\n  }\n}\n","import {\n  HttpEvent,\n  HttpHandlerFn,\n  HttpInterceptorFn,\n  HttpRequest,\n  HttpResponse,\n} from '@angular/common/http';\nimport { inject } from '@angular/core';\nimport { tap, catchError, Observable, throwError, finalize } from 'rxjs';\nimport { RequestTrackerService } from '../services/request-tracker.service';\n\n/**\n * HTTP Interceptor for tracking HTTP request metrics.\n *\n * This interceptor integrates with the `RequestTrackerService` to monitor HTTP requests,\n * enabling real-time tracking of:\n * - Number of ongoing requests.\n * - Success and error counts.\n * - Average response time.\n * - Success and error rates.\n *\n * ### Workflow\n * 1. Assigns a unique ID to each HTTP request.\n * 2. Notifies the `RequestTrackerService` when a request is initiated.\n * 3. Uses RxJS operators to track successful completions, errors, and aborts.\n * 4. Updates metrics in `RequestTrackerService` based on request outcomes.\n *\n * ### Request Lifecycle\n * - On initiation: Notifies the tracker service with a unique request ID.\n * - On success (2xx status): Marks the request as successful.\n * - On error (non-2xx or network error): Marks the request as failed.\n * - On request cancellation: Marks the request as aborted.\n *\n * @param req - The HTTP request being processed.\n * @param next - The next handler in the interceptor chain.\n * @returns An Observable emitting HTTP events or propagating errors if any occur.\n */\nexport const requestTrackerInterceptor: HttpInterceptorFn = (\n  req: HttpRequest<any>,\n  next: HttpHandlerFn,\n): Observable<HttpEvent<any>> => {\n  const requestTrackerService = inject(RequestTrackerService);\n  const currentRequestId = requestTrackerService.requestId++;\n  let requestWasHandled = false;\n\n  requestTrackerService.requestSent(currentRequestId);\n\n  return next(req).pipe(\n    tap({\n      next: (event) => {\n        if (event instanceof HttpResponse) {\n          requestWasHandled = true;\n          if (event.status >= 200 && event.status < 300) {\n            requestTrackerService.requestSuccess(currentRequestId);\n          } else {\n            requestTrackerService.requestError(currentRequestId);\n          }\n        }\n      },\n      error: () => {\n        requestWasHandled = true;\n        requestTrackerService.requestError(currentRequestId);\n      },\n    }),\n    finalize(() => {\n      if (!requestWasHandled) {\n        requestTrackerService.requestAborted(currentRequestId);\n      }\n    }),\n    catchError((error) => {\n      return throwError(() => error);\n    }),\n  );\n};\n","import { Component, inject, input } from '@angular/core';\nimport { DecimalPipe, NgClass } from '@angular/common';\nimport { RequestTrackerService } from '../../services/request-tracker.service';\n\n@Component({\n  selector: 'ngs-request-tracker',\n  standalone: true,\n  imports: [DecimalPipe, NgClass],\n  templateUrl: './request-tracker.component.html',\n  styleUrl: './request-tracker.component.scss',\n})\nexport class RequestTrackerComponent {\n  xPosition = input<'left' | 'center' | 'right'>('left');\n  yPosition = input<'top' | 'center' | 'bottom'>('top');\n\n  requestTrackerService = inject(RequestTrackerService);\n\n  isLoading = this.requestTrackerService.isInProgress;\n  countInProgress = this.requestTrackerService.countInProgress;\n  count = this.requestTrackerService.count;\n  countSuccess = this.requestTrackerService.countSuccess;\n  countError = this.requestTrackerService.countError;\n  countAborted = this.requestTrackerService.countAborted;\n  averageResponseTime = this.requestTrackerService.averageResponseTime;\n  successRate = this.requestTrackerService.successRate;\n  abortedRate = this.requestTrackerService.abortedRate;\n  errorRate = this.requestTrackerService.errorRate;\n}\n","<div\n  class=\"request-tracker {{ 'x-position-' + xPosition() }} {{\n    'y-position-' + yPosition()\n  }}\"\n>\n  <div class=\"title-wrapper\">\n    <span class=\"request-tracker_title\">ngs-request-tracker</span>\n    <div class=\"spinner\" [ngClass]=\"{ loading: isLoading() }\"></div>\n  </div>\n\n  <div class=\"request-tracker__rows\">\n    <span class=\"request-tracker__rows_row\"\n      ><span>Total:</span><span class=\"blue\">{{ count() }}</span></span\n    >\n    <span class=\"request-tracker__rows_row\"\n      ><span>Active:</span\n      ><span class=\"orange\">{{ countInProgress() }}</span></span\n    >\n\n    <div class=\"wrapper\">\n      <span class=\"request-tracker__rows_row\" style=\"flex: 1\"\n        ><span>Success:</span\n        ><span class=\"green\">{{ countSuccess() }}</span></span\n      >\n      <span class=\"request-tracker__rows_row\"\n        ><span class=\"green\" style=\"min-width: 50px; text-align: end\"\n          >{{ successRate() | number: \"1.0-2\" }}%</span\n        ></span\n      >\n    </div>\n\n    <div class=\"wrapper\">\n      <span class=\"request-tracker__rows_row\" style=\"flex: 1\"\n        ><span>Aborted:</span\n        ><span class=\"blueviolet\">{{ countAborted() }}</span></span\n      >\n      <span class=\"request-tracker__rows_row\"\n        ><span class=\"blueviolet\" style=\"min-width: 50px; text-align: end\"\n          >{{ abortedRate() | number: \"1.0-2\" }}%</span\n        ></span\n      >\n    </div>\n\n    <div class=\"wrapper\">\n      <span class=\"request-tracker__rows_row\" style=\"flex: 1\"\n        ><span>Failed:</span><span class=\"red\">{{ countError() }}</span></span\n      >\n      <span class=\"request-tracker__rows_row\"\n        ><span style=\"min-width: 50px; text-align: end\" class=\"red\"\n          >{{ errorRate() | number: \"1.0-2\" }}%</span\n        ></span\n      >\n    </div>\n\n    <span class=\"request-tracker__rows_row\"\n      ><span>Avg. Time:</span\n      ><span class=\"blue\"\n        >{{ averageResponseTime() | number: \"1.0-2\" }} ms</span\n      ></span\n    >\n  </div>\n</div>\n","/*\n * Public API Surface of ngs-request-tracker\n */\n\nexport * from './lib/data-access/services/request-tracker.service';\nexport * from './lib/data-access/interceptors/request-tracker.interceptor';\nexport * from './lib/data-access/components/request-tracker/request-tracker.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}