createCacheRequestInterceptor =
  (getCacheId, globalCacheOptions) => /** @param {CacheRequest} request */ async request => {
    validateCacheOptions(request.cacheOptions);
    const getCacheIdResult = getCacheId();
    const isPromise = typeof getCacheIdResult !== 'string' && 'then' in getCacheIdResult;
    const cacheSessionId = isPromise ? await getCacheIdResult : getCacheIdResult;
    resetCacheSession(cacheSessionId); // cacheSessionId is used to bind the cache to the current session

    const cacheOptions = extendCacheOptions({
      ...globalCacheOptions,
      ...request.cacheOptions,
    });

    const { useCache, requestIdFunction, methods, contentTypes, maxAge, maxResponseSize } =
      cacheOptions;

    // store cacheOptions and cacheSessionId in the request, to use it in the response interceptor.
    request.cacheOptions = cacheOptions;
    request.cacheSessionId = cacheSessionId;

    if (!useCache) {
      return request;
    }

    const requestId = requestIdFunction(request);

    if (!isMethodSupported(methods, request.method)) {
      invalidateMatchingCache(requestId, cacheOptions);
      return request;
    }

    const pendingRequest = pendingRequestStore.get(requestId);
    if (pendingRequest) {
      // there is another concurrent request, wait for it to finish
      await pendingRequest;

      // If session ID changes while waiting for the pending request to complete,
      // then do not read the cache.
      if (!isCurrentSessionId(request.cacheSessionId)) {
        return request;
      }
    }

    const cachedResponse = ajaxCache.get(requestId, { maxAge, maxResponseSize });
    if (cachedResponse && isResponseContentTypeSupported(cachedResponse, contentTypes)) {
      // Return the response from cache
      request.cacheOptions = request.cacheOptions ?? { useCache: false };

      const response = cachedResponse.clone();
      response.request = request;
      response.fromCache = true;
      return response;
    }

    // Mark this as a pending request, so that concurrent requests can use the response from this request
    pendingRequestStore.set(requestId);
    return request;
  }
Request interceptor to return relevant cached requests
@param {function(): string|Promise<string>} getCacheId used to invalidate cache if identifier is changed
@param {CacheOptions} globalCacheOptions
@returns {RequestInterceptor}