{"version":3,"file":"ng-http-caching.mjs","sources":["../../../projects/ng-http-caching/src/lib/storage/ng-http-caching-memory-storage.ts","../../../projects/ng-http-caching/src/lib/ng-http-caching.service.ts","../../../projects/ng-http-caching/src/lib/ng-http-caching-interceptor.service.ts","../../../projects/ng-http-caching/src/lib/ng-http-caching.module.ts","../../../projects/ng-http-caching/src/lib/ng-http-caching-provider.ts","../../../projects/ng-http-caching/src/lib/storage/ng-http-caching-browser-storage.ts","../../../projects/ng-http-caching/src/lib/storage/ng-http-caching-local-storage.ts","../../../projects/ng-http-caching/src/lib/storage/ng-http-caching-session-storage.ts","../../../projects/ng-http-caching/src/public-api.ts","../../../projects/ng-http-caching/src/ng-http-caching.ts"],"sourcesContent":["import { NgHttpCachingStorageInterface } from './ng-http-caching-storage.interface';\r\nimport { NgHttpCachingEntry } from '../ng-http-caching.service';\r\n\r\nexport class NgHttpCachingMemoryStorage extends Map<string, NgHttpCachingEntry<any, any>> implements NgHttpCachingStorageInterface { }\r\n","import { Injectable, InjectionToken, VERSION, isDevMode, inject } from '@angular/core';\r\nimport { HttpRequest, HttpResponse, HttpEvent, HttpContextToken, HttpContext, HttpHeaders } from '@angular/common/http';\r\nimport { Observable } from 'rxjs/internal/Observable';\r\nimport { NgHttpCachingStorageInterface } from './storage/ng-http-caching-storage.interface';\r\nimport { NgHttpCachingMemoryStorage } from './storage/ng-http-caching-memory-storage';\r\n\r\nexport type NgHttpCachingContext = Pick<NgHttpCachingConfig, 'getKey' | 'isCacheable' | 'isExpired' | 'isValid'>;\r\n\r\nexport const NG_HTTP_CACHING_CONTEXT = new HttpContextToken<NgHttpCachingContext>(() => ({}));\r\n\r\nexport const withNgHttpCachingContext = (value: NgHttpCachingContext, context: HttpContext = new HttpContext()) => context.set(NG_HTTP_CACHING_CONTEXT, value)\r\n\r\nexport const checkCacheHeaders = (headers: HttpHeaders): boolean => {\r\n  // check Cache-Control\r\n  const cacheControlHeader = headers.get('cache-control');\r\n  if (cacheControlHeader) {\r\n    const cacheControl = cacheControlHeader.toLowerCase();\r\n    if (cacheControl.includes('no-store')) {\r\n      return false;\r\n    } else if (cacheControl.includes('no-cache')) {\r\n      return false;\r\n    } else {\r\n      return true;\r\n    }\r\n  }\r\n\r\n  // check Expires header Expires if response is without Cache-Control\r\n  const expiresHeader = headers.get('expires');\r\n  if (expiresHeader) {\r\n    const expires = Date.parse(expiresHeader);\r\n    if (!isNaN(expires)) {\r\n      return expires > Date.now();\r\n    }\r\n  }\r\n\r\n  return true;\r\n}\r\n\r\nexport interface NgHttpCachingEntry<K = any, T = any> {\r\n  /**\r\n   * URL\r\n   */\r\n  url: string;\r\n  /**\r\n   * HttpResponse\r\n   */\r\n  response: HttpResponse<T>;\r\n  /**\r\n   * HttpRequest\r\n   */\r\n  request: HttpRequest<K>;\r\n  /**\r\n   * Timestamp of add to cache time\r\n   */\r\n  addedTime: number;\r\n  /**\r\n   * Cache version\r\n   */\r\n  version: string;\r\n}\r\n\r\nexport const NG_HTTP_CACHING_CONFIG = new InjectionToken<NgHttpCachingContext>(\r\n  'ng-http-caching.config'\r\n);\r\n\r\nexport enum NgHttpCachingStrategy {\r\n  /**\r\n   * All request are cacheable if HTTP method is into `allowedMethod`\r\n   */\r\n  ALLOW_ALL = 'ALLOW_ALL',\r\n  /**\r\n   * Only the request with `X-NG-HTTP-CACHING-ALLOW-CACHE` header are cacheable if HTTP method is into `allowedMethod`\r\n   */\r\n  DISALLOW_ALL = 'DISALLOW_ALL'\r\n}\r\n\r\nexport enum NgHttpCachingHeaders {\r\n  /**\r\n   * Request is cacheable if HTTP method is into `allowedMethod`\r\n   */\r\n  ALLOW_CACHE = 'X-NG-HTTP-CACHING-ALLOW-CACHE',\r\n  /**\r\n   * Request isn't cacheable\r\n   */\r\n  DISALLOW_CACHE = 'X-NG-HTTP-CACHING-DISALLOW-CACHE',\r\n  /**\r\n   * Specific cache lifetime for the request\r\n   */\r\n  LIFETIME = 'X-NG-HTTP-CACHING-LIFETIME',\r\n  /**\r\n   * You can tag multiple request by adding this header with the same tag and \r\n   * using `NgHttpCachingService.clearCacheByTag(tag: string)` for delete all the tagged request\r\n   */\r\n  TAG = 'X-NG-HTTP-CACHING-TAG'\r\n}\r\n\r\nexport const NgHttpCachingHeadersList = Object.values(NgHttpCachingHeaders);\r\n\r\nexport const NG_HTTP_CACHING_SECOND_IN_MS = 1000;\r\nexport const NG_HTTP_CACHING_MINUTE_IN_MS = NG_HTTP_CACHING_SECOND_IN_MS * 60;\r\nexport const NG_HTTP_CACHING_HOUR_IN_MS = NG_HTTP_CACHING_MINUTE_IN_MS * 60;\r\nexport const NG_HTTP_CACHING_DAY_IN_MS = NG_HTTP_CACHING_HOUR_IN_MS * 24;\r\nexport const NG_HTTP_CACHING_WEEK_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 7;\r\nexport const NG_HTTP_CACHING_MONTH_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 30;\r\nexport const NG_HTTP_CACHING_YEAR_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 365;\r\n\r\nexport interface NgHttpCachingConfig {\r\n  /**\r\n   * Set the cache store. You can implement your custom store by implement the `NgHttpCachingStorageInterface` interface, eg.:\r\n   */\r\n  store?: NgHttpCachingStorageInterface;\r\n  /**\r\n   * Number of millisecond that a response is stored in the cache. \r\n   * You can set specific \"lifetime\" for each request by add the header `X-NG-HTTP-CACHING-LIFETIME` (see example below).\r\n   */\r\n  lifetime?: number;\r\n  /**\r\n   * Array of allowed HTTP methods to cache. \r\n   * You can allow multiple methods, eg.: `['GET', 'POST', 'PUT', 'DELETE', 'HEAD']` or \r\n   * allow all methods by: `['ALL']`. If `allowedMethod` is an empty array (`[]`), no response are cached.\r\n   * *Warning!* `NgHttpCaching` use the full url (url with query parameters) as unique key for the cached response,\r\n   * this is correct for the `GET` request but is _potentially_ wrong for other type of request (eg. `POST`, `PUT`). \r\n   * You can set a different \"key\" by customizing the `getKey` config method (see `getKey` section).\r\n   */\r\n  allowedMethod?: string[];\r\n  /**\r\n   * Set the cache strategy, possible strategies are:\r\n   * - `NgHttpCachingStrategy.ALLOW_ALL`: All request are cacheable if HTTP method is into `allowedMethod`;\r\n   * - `NgHttpCachingStrategy.DISALLOW_ALL`: Only the request with `X-NG-HTTP-CACHING-ALLOW-CACHE` header are cacheable if HTTP method is into `allowedMethod`;\r\n   */\r\n  cacheStrategy?: NgHttpCachingStrategy;\r\n  /**\r\n   * Cache version. When you have a breaking change, change the version, and it'll delete the current cache automatically.\r\n   * The default value is Angular major version (eg. 13), in this way, the cache is invalidated on every Angular upgrade.\r\n   */\r\n  version?: string;\r\n  /**\r\n   * If true response headers cache-control and expires are respected.\r\n   */\r\n  checkResponseHeaders?: boolean;\r\n  /**\r\n   * If this function return `true` the request is expired and a new request is send to backend, if return `false` isn't expired. \r\n   * If the result is `undefined`, the normal behaviour is provided.\r\n   */\r\n  isExpired?: <K, T>(entry: NgHttpCachingEntry<K, T>) => boolean | undefined | void;\r\n  /**\r\n   * If this function return `true` the request is cacheable, if return `false` isn't cacheable. \r\n   * If the result is `undefined`, the normal behaviour is provided.\r\n   */\r\n  isCacheable?: <K>(req: HttpRequest<K>) => boolean | undefined | void;\r\n  /**\r\n   * This function return the unique key (`string`) for store the response into the cache. \r\n   * If the result is `undefined`, the normal behaviour is provided.\r\n   */\r\n  getKey?: <K>(req: HttpRequest<K>) => string | undefined | void;\r\n  /**\r\n   * If this function return `true` the cache entry is valid and can be stored, if return `false` isn't valid. \r\n   * If the result is `undefined`, the normal behaviour is provided.\r\n   */\r\n  isValid?: <K, T>(entry: NgHttpCachingEntry<K, T>) => boolean | undefined | void;\r\n}\r\n\r\nexport interface NgHttpCachingDefaultConfig extends NgHttpCachingConfig {\r\n  store: NgHttpCachingStorageInterface;\r\n  lifetime: number;\r\n  allowedMethod: string[];\r\n  cacheStrategy: NgHttpCachingStrategy;\r\n  version: string;\r\n  checkResponseHeaders: boolean;\r\n}\r\n\r\nexport const NgHttpCachingConfigDefault: Readonly<NgHttpCachingDefaultConfig> = {\r\n  store: new NgHttpCachingMemoryStorage(),\r\n  lifetime: NG_HTTP_CACHING_HOUR_IN_MS,\r\n  version: VERSION.major,\r\n  allowedMethod: ['GET', 'HEAD'],\r\n  cacheStrategy: NgHttpCachingStrategy.ALLOW_ALL,\r\n  checkResponseHeaders: false\r\n};\r\n\r\n@Injectable()\r\nexport class NgHttpCachingService {\r\n\r\n  private readonly queue = new Map<string, Observable<HttpEvent<any>>>();\r\n\r\n  private readonly config: NgHttpCachingDefaultConfig;\r\n\r\n  private gcLock = false;\r\n\r\n  private devMode: boolean = isDevMode();\r\n\r\n  constructor() {\r\n    const config: Readonly<NgHttpCachingConfig | null> = inject(NG_HTTP_CACHING_CONFIG, { optional: true });\r\n    if (config) {\r\n      this.config = { ...NgHttpCachingConfigDefault, ...config };\r\n    } else {\r\n      this.config = { ...NgHttpCachingConfigDefault };\r\n    }\r\n    // start cache clean\r\n    this.runGc();\r\n  }\r\n\r\n  /**\r\n   * Return the config\r\n   */\r\n  getConfig(): Readonly<NgHttpCachingConfig> {\r\n    return this.config;\r\n  }\r\n\r\n  /**\r\n   * Return the queue map\r\n   */\r\n  getQueue(): Readonly<Map<string, Observable<HttpEvent<any>>>> {\r\n    return this.queue;\r\n  }\r\n\r\n  /**\r\n   * Return the cache store\r\n   */\r\n  getStore(): Readonly<NgHttpCachingStorageInterface> {\r\n    return this.config.store;\r\n  }\r\n\r\n  /**\r\n   * Return response from cache\r\n   */\r\n  getFromCache<K, T>(req: HttpRequest<K>): Readonly<HttpResponse<T>> | undefined {\r\n    const key: string = this.getKey(req);\r\n    const cached: NgHttpCachingEntry<K, T> | undefined = this.config.store.get<K, T>(key);\r\n\r\n    if (!cached) {\r\n      return undefined;\r\n    }\r\n\r\n    if (this.isExpired(cached)) {\r\n      this.clearCacheByKey(key);\r\n      return undefined;\r\n    }\r\n\r\n    return this.deepFreeze(cached.response);\r\n  }\r\n\r\n  /**\r\n   * Add response to cache\r\n   */\r\n  addToCache<K, T>(req: HttpRequest<K>, res: HttpResponse<T>): boolean {\r\n    const entry: NgHttpCachingEntry<K, T> = {\r\n      url: req.urlWithParams,\r\n      response: res,\r\n      request: req,\r\n      addedTime: Date.now(),\r\n      version: this.config.version,\r\n    };\r\n    if (this.isValid(entry)) {\r\n      const key: string = this.getKey(req);\r\n      this.config.store.set(key, entry);\r\n      return true;\r\n    }\r\n    return false;\r\n  }\r\n\r\n  /**\r\n   * Delete response from cache\r\n   */\r\n  deleteFromCache<K>(req: HttpRequest<K>): boolean {\r\n    const key: string = this.getKey(req);\r\n    return this.clearCacheByKey(key);\r\n  }\r\n\r\n  /**\r\n   * Clear the cache\r\n   */\r\n  clearCache(): void {\r\n    this.config.store.clear();\r\n  }\r\n\r\n  /**\r\n   * Clear the cache by key\r\n   */\r\n  clearCacheByKey(key: string): boolean {\r\n    return this.config.store.delete(key);\r\n  }\r\n\r\n  /**\r\n   * Clear the cache by keys\r\n   */\r\n  clearCacheByKeys(keys: Array<string>): number {\r\n    let counter = 0;\r\n    if (keys) {\r\n      for (const key of keys) {\r\n        if (this.clearCacheByKey(key)) {\r\n          counter++;\r\n        }\r\n      }\r\n    }\r\n    return counter;\r\n  }\r\n\r\n  /**\r\n   * Clear the cache by regex\r\n   */\r\n  clearCacheByRegex<K, T>(regex: RegExp): number {\r\n    const keys: Array<string> = [];\r\n    this.config.store.forEach<K, T>((_: NgHttpCachingEntry<K, T>, key: string) => {\r\n      if (regex.test(key)) {\r\n        keys.push(key);\r\n      }\r\n    });\r\n    return this.clearCacheByKeys(keys);\r\n  }\r\n\r\n  /**\r\n   * Clear the cache by TAG\r\n   */\r\n  clearCacheByTag<K, T>(tag: string): number {\r\n    const keys: Array<string> = [];\r\n    this.config.store.forEach<K, T>((entry: NgHttpCachingEntry<K, T>, key: string) => {\r\n      const tagHeader = entry.request.headers.get(NgHttpCachingHeaders.TAG);\r\n      if (tagHeader && tagHeader.split(',').includes(tag)) {\r\n        keys.push(key);\r\n      }\r\n    });\r\n    return this.clearCacheByKeys(keys);\r\n  }\r\n\r\n  /**\r\n   * Run garbage collector (delete expired cache entry)\r\n   */\r\n  runGc<K, T>(): boolean {\r\n    if (this.gcLock) {\r\n      return false;\r\n    }\r\n    this.gcLock = true;\r\n    const keys: Array<string> = [];\r\n    this.config.store.forEach<K, T>((entry: NgHttpCachingEntry<K, T>, key: string) => {\r\n      if (this.isExpired(entry)) {\r\n        keys.push(key);\r\n      }\r\n    });\r\n    this.clearCacheByKeys(keys);\r\n    this.gcLock = false;\r\n    return true;\r\n  }\r\n\r\n  /**\r\n   * Return true if cache entry is expired\r\n   */\r\n  isExpired<K, T>(entry: NgHttpCachingEntry<K, T>): boolean {\r\n    // if user provide custom method, use it\r\n    const context = entry.request.context.get(NG_HTTP_CACHING_CONTEXT);\r\n    if (typeof context?.isExpired === 'function') {\r\n      const result = context.isExpired(entry);\r\n      // if result is undefined, normal behaviour is provided\r\n      if (result !== undefined) {\r\n        return result;\r\n      }\r\n    }\r\n    // if user provide custom method, use it\r\n    if (typeof this.config.isExpired === 'function') {\r\n      const result = this.config.isExpired(entry);\r\n      // if result is undefined, normal behaviour is provided\r\n      if (result !== undefined) {\r\n        return result;\r\n      }\r\n    }\r\n    // if version change, always expire\r\n    if (this.config.version !== entry.version) {\r\n      return true;\r\n    }\r\n    // config/default lifetime\r\n    let lifetime: number = this.config.lifetime;\r\n    // request has own lifetime\r\n    const headerLifetime = entry.request.headers.get(NgHttpCachingHeaders.LIFETIME);\r\n    if (headerLifetime) {\r\n      lifetime = +headerLifetime;\r\n    }\r\n    // never expire if 0\r\n    if (lifetime === 0) {\r\n      return false;\r\n    }\r\n    // wrong lifetime\r\n    if (lifetime < 0 || isNaN(lifetime)) {\r\n      throw new Error('lifetime must be greater than or equal 0');\r\n    }\r\n    return entry.addedTime + lifetime < Date.now();\r\n  }\r\n\r\n  /**\r\n   * Return true if cache entry is valid for store in the cache\r\n   * Default behaviour is whether the status code falls in the 2xx range and response headers cache-control and expires allow cache.\r\n   */\r\n  isValid<K, T>(entry: NgHttpCachingEntry<K, T>): boolean {\r\n    const context = entry.request.context.get(NG_HTTP_CACHING_CONTEXT);\r\n    // if user provide custom method, use it\r\n    if (typeof context.isValid === 'function') {\r\n      const result = context.isValid(entry);\r\n      // if result is undefined, normal behaviour is provided\r\n      if (result !== undefined) {\r\n        return result;\r\n      }\r\n    }\r\n    // if user provide custom method, use it\r\n    if (typeof this.config.isValid === 'function') {\r\n      const result = this.config.isValid(entry);\r\n      // if result is undefined, normal behaviour is provided\r\n      if (result !== undefined) {\r\n        return result;\r\n      }\r\n    }\r\n    // different version\r\n    if (this.config.version !== entry.version) {\r\n      return false;\r\n    }\r\n\r\n    let fromHeader = true;\r\n    if (this.config.checkResponseHeaders) {\r\n      // check if response headers allow cache\r\n      fromHeader = checkCacheHeaders(entry.response.headers);\r\n    }\r\n    return entry.response.ok && fromHeader;\r\n  }\r\n\r\n  /**\r\n   * Return true if the request is cacheable\r\n   */\r\n  isCacheable<K>(req: HttpRequest<K>): boolean {\r\n    const context = req.context.get(NG_HTTP_CACHING_CONTEXT);\r\n    // if user provide custom method, use it\r\n    if (typeof context?.isCacheable === 'function') {\r\n      const result = context.isCacheable(req);\r\n      // if result is undefined, normal behaviour is provided\r\n      if (result !== undefined) {\r\n        return result;\r\n      }\r\n    }\r\n    // if user provide custom method, use it\r\n    if (typeof this.config.isCacheable === 'function') {\r\n      const result = this.config.isCacheable(req);\r\n      // if result is undefined, normal behaviour is provided\r\n      if (result !== undefined) {\r\n        return result;\r\n      }\r\n    }\r\n    // request has disallow cache header\r\n    if (req.headers.has(NgHttpCachingHeaders.DISALLOW_CACHE)) {\r\n      return false;\r\n    }\r\n    // strategy is disallow all...\r\n    if (this.config.cacheStrategy === NgHttpCachingStrategy.DISALLOW_ALL) {\r\n      // request isn't allowed if come without allow header\r\n      if (!req.headers.has(NgHttpCachingHeaders.ALLOW_CACHE)) {\r\n        return false;\r\n      }\r\n    }\r\n    // if allowed method is only ALL, allow all http methods\r\n    if (this.config.allowedMethod.length === 1) {\r\n      if (this.config.allowedMethod[0] === 'ALL') {\r\n        return true;\r\n      }\r\n    }\r\n    // request is allowed if method is in allowedMethod\r\n    return this.config.allowedMethod.indexOf(req.method) !== -1;\r\n  }\r\n\r\n  /**\r\n   * Return the cache key.\r\n   * Default key is http method plus url with query parameters, eg.:\r\n   * `GET@https://github.com/nigrosimone/ng-http-caching`\r\n   */\r\n  getKey<K>(req: HttpRequest<K>): string {\r\n    // if user provide custom method, use it\r\n    const context = req.context.get(NG_HTTP_CACHING_CONTEXT);\r\n    if (typeof context.getKey === 'function') {\r\n      const result = context.getKey(req);\r\n      // if result is undefined, normal behaviour is provided\r\n      if (result !== undefined) {\r\n        return result;\r\n      }\r\n    }\r\n    // if user provide custom method, use it\r\n    if (typeof this.config.getKey === 'function') {\r\n      const result = this.config.getKey(req);\r\n      // if result is undefined, normal behaviour is provided\r\n      if (result !== undefined) {\r\n        return result;\r\n      }\r\n    }\r\n    // default key is req.method plus url with query parameters\r\n    return req.method + '@' + req.urlWithParams;\r\n  }\r\n\r\n  /**\r\n   * Return observable from cache\r\n   */\r\n  getFromQueue<K, T>(req: HttpRequest<K>): Observable<HttpEvent<T>> | undefined {\r\n    const key: string = this.getKey(req);\r\n    const cached: Observable<HttpEvent<T>> | undefined = this.queue.get(key);\r\n\r\n    if (!cached) {\r\n      return undefined;\r\n    }\r\n\r\n    return cached;\r\n  }\r\n\r\n  /**\r\n   * Add observable to cache\r\n   */\r\n  addToQueue<K, T>(req: HttpRequest<K>, obs: Observable<HttpEvent<T>>): void {\r\n    const key: string = this.getKey(req);\r\n    this.queue.set(key, obs);\r\n  }\r\n\r\n  /**\r\n   * Delete observable from cache\r\n   */\r\n  deleteFromQueue<K>(req: HttpRequest<K>): boolean {\r\n    const key: string = this.getKey(req);\r\n    return this.queue.delete(key);\r\n  }\r\n\r\n  /**\r\n   * Recursively Object.freeze simple Javascript structures consisting of plain objects, arrays, and primitives.\r\n   * Make the data immutable.\r\n   * @returns immutable object\r\n   */\r\n  private deepFreeze<S>(object: S): Readonly<S> {\r\n    // No freezing in production (for better performance).\r\n    if (!this.devMode || !object || typeof object !== 'object') {\r\n      return object as Readonly<S>;\r\n    }\r\n\r\n    // When already frozen, we assume its children are frozen (for better performance).\r\n    // This should be true if you always use `deepFreeze` to freeze objects.\r\n    //\r\n    // Note that Object.isFrozen will also return `true` for primitives (numbers,\r\n    // strings, booleans, undefined, null), so there is no need to check for\r\n    // those explicitly.\r\n    if (Object.isFrozen(object)) {\r\n      return object as Readonly<S>;\r\n    }\r\n\r\n    // At this point we know that we're dealing with either an array or plain object, so\r\n    // just freeze it and recurse on its values.\r\n    Object.freeze(object);\r\n    Object.keys(object).forEach(key => this.deepFreeze((object as any)[key]));\r\n\r\n    return object as Readonly<S>;\r\n  }\r\n}\r\n","import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';\r\nimport { inject, Injectable } from '@angular/core';\r\nimport { asyncScheduler, Observable, of, scheduled } from 'rxjs';\r\nimport { tap, finalize, shareReplay } from 'rxjs/operators';\r\nimport { NgHttpCachingService, NgHttpCachingHeadersList } from './ng-http-caching.service';\r\n\r\n@Injectable()\r\nexport class NgHttpCachingInterceptorService implements HttpInterceptor {\r\n\r\n  private readonly cacheService: NgHttpCachingService = inject(NgHttpCachingService);\r\n\r\n  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\r\n    // run garbage collector\r\n    this.cacheService.runGc();\r\n\r\n    // Don't cache if it's not cacheable\r\n    if (!this.cacheService.isCacheable(req)) {\r\n      return this.sendRequest(req, next);\r\n    }\r\n\r\n    // Checked if there is pending response for this request\r\n    const cachedObservable: Observable<HttpEvent<any>> | undefined = this.cacheService.getFromQueue(req);\r\n    if (cachedObservable) {\r\n      // console.log('cachedObservable',cachedObservable);\r\n      return cachedObservable;\r\n    }\r\n\r\n    // Checked if there is cached response for this request\r\n    const cachedResponse: HttpResponse<any> | undefined = this.cacheService.getFromCache(req);\r\n    if (cachedResponse) {\r\n      // console.log('cachedResponse');\r\n      return scheduled(of(cachedResponse.clone()), asyncScheduler);\r\n    }\r\n\r\n    // If the request of going through for first time\r\n    // then let the request proceed and cache the response\r\n    // console.log('sendRequest', req);\r\n    const shared = this.sendRequest(req, next).pipe(\r\n      tap(event => {\r\n        if (event instanceof HttpResponse) {\r\n          this.cacheService.addToCache(req, event.clone());\r\n        }\r\n      }),\r\n      finalize(() => {\r\n        // delete pending request\r\n        this.cacheService.deleteFromQueue(req);\r\n      }),\r\n      shareReplay()\r\n    );\r\n\r\n    // add pending request to queue for cache parallel request\r\n    this.cacheService.addToQueue(req, shared);\r\n\r\n    return shared;\r\n  }\r\n\r\n  /**\r\n   * Send http request (next handler)\r\n   */\r\n  sendRequest(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\r\n    let cloned: HttpRequest<any> = req.clone();\r\n    // trim custom headers before send request\r\n    NgHttpCachingHeadersList.forEach(ngHttpCachingHeaders => {\r\n      if (cloned.headers.has(ngHttpCachingHeaders)) {\r\n        cloned = cloned.clone({ headers: cloned.headers.delete(ngHttpCachingHeaders) });\r\n      }\r\n    });\r\n    return next.handle(cloned);\r\n  }\r\n}\r\n","import { NgModule, ModuleWithProviders } from '@angular/core';\r\nimport { HTTP_INTERCEPTORS } from '@angular/common/http';\r\nimport {\r\n  NG_HTTP_CACHING_CONFIG,\r\n  NgHttpCachingConfig,\r\n  NgHttpCachingService,\r\n} from './ng-http-caching.service';\r\nimport { NgHttpCachingInterceptorService } from './ng-http-caching-interceptor.service';\r\n\r\n@NgModule({\r\n  providers: [\r\n    NgHttpCachingService,\r\n    NgHttpCachingInterceptorService,\r\n    {\r\n      provide: HTTP_INTERCEPTORS,\r\n      useClass: NgHttpCachingInterceptorService,\r\n      multi: true,\r\n    },\r\n  ]\r\n})\r\nexport class NgHttpCachingModule {\r\n  static forRoot(\r\n    ngHttpCachingConfig?: NgHttpCachingConfig\r\n  ): ModuleWithProviders<NgHttpCachingModule> {\r\n    return {\r\n      ngModule: NgHttpCachingModule,\r\n      providers: [\r\n        {\r\n          provide: NG_HTTP_CACHING_CONFIG,\r\n          useValue: ngHttpCachingConfig,\r\n        },\r\n      ],\r\n    };\r\n  }\r\n}\r\n","import { EnvironmentProviders, makeEnvironmentProviders } from \"@angular/core\";\r\nimport { HTTP_INTERCEPTORS } from \"@angular/common/http\";\r\nimport { NgHttpCachingInterceptorService } from \"./ng-http-caching-interceptor.service\";\r\nimport { NG_HTTP_CACHING_CONFIG, NgHttpCachingConfig, NgHttpCachingService } from \"./ng-http-caching.service\";\r\n\r\nexport function provideNgHttpCaching(ngHttpCachingConfig?: NgHttpCachingConfig) {\r\n    const providers: EnvironmentProviders[] = [];\r\n    if (ngHttpCachingConfig) {\r\n        providers.push(makeEnvironmentProviders([{\r\n            provide: NG_HTTP_CACHING_CONFIG,\r\n            useValue: ngHttpCachingConfig,\r\n        }]));\r\n    }\r\n    providers.push(makeEnvironmentProviders([\r\n        NgHttpCachingService,\r\n        {\r\n            provide: HTTP_INTERCEPTORS,\r\n            useClass: NgHttpCachingInterceptorService,\r\n            multi: true,\r\n        },\r\n        NgHttpCachingInterceptorService\r\n    ]));\r\n    return providers;\r\n}\r\n","import { NgHttpCachingStorageInterface } from './ng-http-caching-storage.interface';\r\nimport { NgHttpCachingEntry } from '../ng-http-caching.service';\r\nimport { HttpHeaders, HttpParams, HttpRequest, HttpResponse } from '@angular/common/http';\r\n\r\nconst KEY_PREFIX = 'NgHttpCaching::';\r\n\r\nexport interface NgHttpCachingStorageEntry {\r\n    url: string;\r\n    response: string;\r\n    request: string;\r\n    addedTime: number;\r\n    version: string;\r\n}\r\n\r\nexport const serializeRequest = (req: HttpRequest<any>): string => {\r\n    const request = req.clone(); // Make a clone, useful for doing destructive things\r\n    return JSON.stringify({\r\n        headers: Object.fromEntries( // Just a helper to make this into an object, not really required but makes the output nicer\r\n            request.headers.keys().map( // Get all of the headers\r\n                (key: string) => [key, request.headers.getAll(key)] // Get all of the corresponding values for the headers\r\n            )\r\n        ),\r\n        method: request.method, // The Request Method, e.g. GET, POST, DELETE\r\n        url: request.url, // The URL\r\n        params: Object.fromEntries( // Just a helper to make this into an object, not really required but makes the output nicer\r\n            request.headers.keys().map( // Get all of the headers\r\n                (key: string) => [key, request.headers.getAll(key)] // Get all of the corresponding values for the headers\r\n            )\r\n        ), // The request parameters\r\n        withCredentials: request.withCredentials, // Whether credentials are being sent\r\n        responseType: request.responseType, // The response type\r\n        body: request.serializeBody() // Serialize the body, all well and good since we are working on a clone\r\n    });\r\n}\r\n\r\nexport const serializeResponse = (res: HttpResponse<any>): string => {\r\n    const response = res.clone();\r\n    return JSON.stringify({\r\n        headers: Object.fromEntries( // Just a helper to make this into an object, not really required but makes the output nicer\r\n            response.headers.keys().map( // Get all of the headers\r\n                (key: string) => [key, response.headers.getAll(key)] // Get all of the corresponding values for the headers\r\n            )\r\n        ),\r\n        status: response.status,\r\n        statusText: response.statusText,\r\n        url: response.url,\r\n        body: response.body // Serialize the body, all well and good since we are working on a clone\r\n    });\r\n}\r\n\r\nexport const deserializeRequest = <T = any>(req: string): HttpRequest<T> => {\r\n    const request = JSON.parse(req);\r\n    const headers = new HttpHeaders(request.headers);\r\n    const params = new HttpParams(); // Probably some way to make this a one-liner, but alas, there are no good docs\r\n    for (const parameter in request.params) {\r\n        request.params[parameter].forEach((paramValue: string) => params.append(parameter, paramValue));\r\n    }\r\n    return new HttpRequest(request.method, request.url, request.body, {\r\n        headers,\r\n        params,\r\n        responseType: request.responseType,\r\n        withCredentials: request.withCredentials\r\n    });\r\n}\r\n\r\nexport const deserializeResponse = <T = any>(res: string): HttpResponse<T> => {\r\n    const response = JSON.parse(res);\r\n    return new HttpResponse<T>({\r\n        url: response.url,\r\n        headers: new HttpHeaders(response.headers),\r\n        body: response.body,\r\n        status: response.status,\r\n        statusText: response.statusText,\r\n    });\r\n}\r\n\r\nexport class NgHttpCachingBrowserStorage implements NgHttpCachingStorageInterface {\r\n\r\n    constructor(private storage: Storage) { }\r\n\r\n    get size(): number {\r\n        let count = 0;\r\n        for (let i = 0, e = this.storage.length; i < e; i++) {\r\n            const key = this.storage.key(i);\r\n            if (key && key.startsWith(KEY_PREFIX)) {\r\n                count++;\r\n            }\r\n        }\r\n        return count;\r\n    }\r\n\r\n    clear(): void {\r\n        for (let i = this.storage.length; i >= 0; i--) {\r\n            const key = this.storage.key(i);\r\n            if (key && key.startsWith(KEY_PREFIX)) {\r\n                this.storage.removeItem(key);\r\n            }\r\n        }\r\n    }\r\n\r\n    delete(key: string): boolean {\r\n        if (!key) {\r\n            return false;\r\n        }\r\n        if (!key.startsWith(KEY_PREFIX)) {\r\n            key = KEY_PREFIX + key;\r\n        }\r\n        this.storage.removeItem(key);\r\n        return true;\r\n    }\r\n\r\n    forEach(callbackfn: (value: NgHttpCachingEntry, key: string) => void): void {\r\n        // iterate this.storage\r\n        for (let i = 0, e = this.storage.length; i < e; i++) {\r\n            const keyWithPrefix = this.storage.key(i);\r\n            if (keyWithPrefix && keyWithPrefix.startsWith(KEY_PREFIX)) {\r\n                const value = this.get(keyWithPrefix);\r\n                if (value) {\r\n                    const keyWithoutPrefix = keyWithPrefix.substring(KEY_PREFIX.length);\r\n                    callbackfn(value, keyWithoutPrefix);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    get(key: string): Readonly<NgHttpCachingEntry> | undefined {\r\n        if (!key) {\r\n            return undefined;\r\n        }\r\n        if (!key.startsWith(KEY_PREFIX)) {\r\n            key = KEY_PREFIX + key;\r\n        }\r\n        const item = this.storage.getItem(key);\r\n        if (item) {\r\n            const parsedItem: NgHttpCachingStorageEntry = JSON.parse(item);\r\n            return this.deserialize(parsedItem);\r\n        }\r\n        return undefined;\r\n    }\r\n\r\n    has(key: string): boolean {\r\n        if (!key) {\r\n            return false;\r\n        }\r\n        if (!key.startsWith(KEY_PREFIX)) {\r\n            key = KEY_PREFIX + key;\r\n        }\r\n        return !!this.storage.getItem(key);\r\n    }\r\n\r\n    set(key: string, value: NgHttpCachingEntry): void {\r\n        if (!key) {\r\n            return;\r\n        }\r\n        if (!key.startsWith(KEY_PREFIX)) {\r\n            key = KEY_PREFIX + key;\r\n        }\r\n        const unParsedItem: NgHttpCachingStorageEntry = this.serialize(value);\r\n        this.storage.setItem(key, JSON.stringify(unParsedItem));\r\n    }\r\n\r\n    protected serialize(value: NgHttpCachingEntry): NgHttpCachingStorageEntry {\r\n        return {\r\n            url: value.url,\r\n            response: serializeResponse(value.response),\r\n            request: serializeRequest(value.request),\r\n            addedTime: value.addedTime,\r\n            version: value.version\r\n        };\r\n    }\r\n\r\n    protected deserialize(value: NgHttpCachingStorageEntry): NgHttpCachingEntry {\r\n        return {\r\n            url: value.url,\r\n            response: deserializeResponse(value.response),\r\n            request: deserializeRequest(value.request),\r\n            addedTime: value.addedTime,\r\n            version: value.version\r\n        };\r\n    }\r\n}\r\n\r\n","import { NgHttpCachingBrowserStorage } from './ng-http-caching-browser-storage';\r\n\r\nexport class NgHttpCachingLocalStorage extends NgHttpCachingBrowserStorage {\r\n\r\n    constructor() {\r\n        super(localStorage);\r\n    }\r\n}\r\n\r\nexport const withNgHttpCachingLocalStorage = () => new NgHttpCachingLocalStorage();","import { NgHttpCachingBrowserStorage } from './ng-http-caching-browser-storage';\r\n\r\nexport class NgHttpCachingSessionStorage extends NgHttpCachingBrowserStorage {\r\n\r\n    constructor() {\r\n        super(sessionStorage);\r\n    }\r\n}\r\n\r\nexport const withNgHttpCachingSessionStorage = () => new NgHttpCachingSessionStorage();","/*\r\n * Public API Surface of ng-http-caching\r\n */\r\nexport * from './lib/ng-http-caching-interceptor.service';\r\nexport * from './lib/ng-http-caching.service';\r\nexport * from './lib/ng-http-caching.module';\r\nexport * from './lib/ng-http-caching-provider';\r\nexport * from './lib/storage/ng-http-caching-storage.interface';\r\nexport * from './lib/storage/ng-http-caching-memory-storage';\r\nexport * from './lib/storage/ng-http-caching-local-storage';\r\nexport * from './lib/storage/ng-http-caching-session-storage';\r\nexport * from './lib/storage/ng-http-caching-browser-storage';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}