async fetch(info, init, parseErrorResponse = false) {
    const request = /** @type {CacheRequest} */ (new Request(info, { ...init }));
    request.cacheOptions = init?.cacheOptions;
    request.params = init?.params;

    // run request interceptors, returning directly and skipping the network
    const interceptedRequestOrResponse = await this.__interceptRequest(request);
    if (interceptedRequestOrResponse instanceof Response) {
      const response = /** @type {CacheResponse} */ (interceptedRequestOrResponse);
      response.request = request;
      if (isFailedResponse(interceptedRequestOrResponse)) {
        throw new AjaxFetchError(
          request,
          response,
          parseErrorResponse ? await this.__attemptParseFailedResponseBody(response) : undefined,
        );
      }
      // prevent network request, return cached response
      return response;
    }

    const response = /** @type {CacheResponse} */ (await fetch(interceptedRequestOrResponse));
    response.request = interceptedRequestOrResponse;

    const interceptedResponse = await this.__interceptResponse(response);

    if (isFailedResponse(interceptedResponse)) {
      throw new AjaxFetchError(
        request,
        response,
        parseErrorResponse ? await this.__attemptParseFailedResponseBody(response) : undefined,
      );
    }
    return interceptedResponse;
  }
Fetch by calling the registered request and response interceptors.

@param {RequestInfo} info
@param {RequestInit & Partial<CacheRequestExtension>} [init]
@param {Boolean} [parseErrorResponse]
@returns {Promise<Response>}