Repository: angular/angular
File: packages/common/http/src/transfer_cache.ts (TypeScript)

Code before:
  /** headers */
  [HEADERS]: Record<string, string[]>;
  /** status */
  [STATUS]?: number;
  /** statusText */
  [STATUS_TEXT]?: string;
  /** url */
  [REQ_URL]?: string;
  /** responseType */
  [RESPONSE_TYPE]?: HttpRequest<unknown>['responseType'];
}

interface CacheOptions extends HttpTransferCacheOptions {
  isCacheActive: boolean;
}

export const CACHE_OPTIONS = new InjectionToken<CacheOptions>(
  typeof ngDevMode !== 'undefined' && ngDevMode ? 'HTTP_TRANSFER_STATE_CACHE_OPTIONS' : '',
);

/**
 * A list of allowed HTTP methods to cache.
 */
const ALLOWED_METHODS = ['GET', 'HEAD'];

export function StateFromCache(
  req: HttpRequest<unknown>,
  options: CacheOptions,
  transferState: TransferState,
  originMap: Record<string, string> | null,
): HttpResponse<unknown> | null {
  const {isCacheActive, ...globalOptions} = options;
  const {transferCache: requestOptions, method: requestMethod} = req;

  // In the following situations we do not want to cache the request
  if (
    !isCacheActive ||
    requestOptions === false ||
    // POST requests are allowed either globally or at request level
    (requestMethod === 'POST' && !globalOptions.includePostRequests && !requestOptions) ||
    (requestMethod !== 'POST' && !ALLOWED_METHODS.includes(requestMethod)) ||
    // Do not cache request that require authorization when includeRequestsWithAuthHeaders is falsey
    (!globalOptions.includeRequestsWithAuthHeaders && hasAuthHeaders(req)) ||
    globalOptions.filter?.(req) === false
  ) {
    return null;
  }

  if (typeof ngServerMode !== 'undefined' && !ngServerMode && originMap) {
    throw new RuntimeError(
      RuntimeErrorCode.HTTP_ORIGIN_MAP_USED_IN_CLIENT,

Review comment (performance):
nit: naming suggestion
```suggestion
export function retrieveStateFromCache(
```

Code after:
  /** headers */
  [HEADERS]: Record<string, string[]>;
  /** status */
  [STATUS]?: number;
  /** statusText */
  [STATUS_TEXT]?: string;
  /** url */
  [REQ_URL]?: string;
  /** responseType */
  [RESPONSE_TYPE]?: HttpRequest<unknown>['responseType'];
}

interface CacheOptions extends HttpTransferCacheOptions {
  isCacheActive: boolean;
}

export const CACHE_OPTIONS = new InjectionToken<CacheOptions>(
  typeof ngDevMode !== 'undefined' && ngDevMode ? 'HTTP_TRANSFER_STATE_CACHE_OPTIONS' : '',
);

/**
 * A list of allowed HTTP methods to cache.
 */
const ALLOWED_METHODS = ['GET', 'HEAD'];

function shouldCacheRequest(req: HttpRequest<unknown>, options: CacheOptions): boolean {
  const {isCacheActive, ...globalOptions} = options;
  const {transferCache: requestOptions, method: requestMethod} = req;

  if (
    !isCacheActive ||
    requestOptions === false ||
    // POST requests are allowed either globally or at request level
    (requestMethod === 'POST' && !globalOptions.includePostRequests && !requestOptions) ||
    (requestMethod !== 'POST' && !ALLOWED_METHODS.includes(requestMethod)) ||
    // Do not cache request that require authorization when includeRequestsWithAuthHeaders is falsey
    (!globalOptions.includeRequestsWithAuthHeaders && hasAuthHeaders(req)) ||
    globalOptions.filter?.(req) === false
  ) {
    return false;
  }

  return true;
}

function getHeadersToInclude(
  options: CacheOptions,
  requestOptions: HttpTransferCacheOptions | boolean | undefined,
): string[] | undefined {
  const {includeHeaders: globalHeaders} = options;
  let headersToInclude = globalHeaders;