@sozialhelden/fetch-cache
TypeScript icon, indicating that this package has built-in type declarations

2.0.1 • Public • Published

fetch-cache 🐕

A cache for WhatWG fetch calls.

  • Supports TypeScript
  • Uses normalized URLs as cache keys
  • Can normalize URLs for better performance (you can configure how)
  • Does not request the same resource twice if the first request is still loading
  • Customizable TTLs per request, dependent on HTTP status code or in case of network errors
  • Supports all Hamster Cache features, e.g. eviction based on LRU, maximal cached item count and/or per-item TTL.
  • Runs in NodeJS, but should be isometric && browser-compatible (not tested yet! try at your own risk 🙃)

Installation

npm install --save @sozialhelden/fetch-cache
#or
yarn add @sozialhelden/fetch-cache

Usage examples

Initialization

Bring your own fetch - for example:

Configure the cache and use cache.fetch() as if you would call fetch() directly:

import FetchCache from '@sozialhelden/fetch-cache';

const fetch = require('node-fetch'); // in NodeJS
// or
const fetch = window.fetch; // in newer browsers

const fetchCache = new FetchCache({
  fetch,
  cacheOptions: {
    // Don't save more than 100 responses in the cache. Allows infinite responses by default
    maximalItemCount: 100,
    // When should the cache evict responses when its full?
    evictExceedingItemsBy: 'lru', // Valid values: 'lru' or 'age'
    // ...see https://github.com/sozialhelden/hamster-cache for all possible options
  },
});

// either fetches a response over the network,
// or returns a cached promise with the same URL (if available)
const url = 'https://jsonplaceholder.typicode.com/todos/1';
fetchCache
  .fetch(url, fetchOptions)
  .then(response => response.body())
  .then(console.log)
  .catch(console.log);

Basic caching operations

// Add an external response promise and cache it for 10 seconds
const response = fetch('https://api.example.com');

// Insert a response you got from somewhere else
fetchCache.cache.set('http://example.com', response);

// Set a custom TTL of 10 seconds for this specific response
fetchCache.cache.set('http://example.com', response, { ttl: 10000 });

// gets the cached response without side effects
fetchCache.cache.peek(url);

// `true` if a response exists in the cache, `false` otherwise
fetchCache.cache.has(url);

// same as `peek`, but returns response with meta information
fetchCache.cache.peekItem(url);

// same as `get`, but returns response with meta information
fetchCache.cache.getItem(url);

// Let the cache collect garbage to save memory, for example in fixed time intervals
fetchCache.cache.evictExpiredItems();

// removes a response from the cache
fetchCache.cache.delete(url);

// forgets all cached responses
fetchCache.cache.clear();

Vary TTLs depending on HTTP response code, headers, and more

While the cache tries to guess working TTLs for most use cases, you might want to customize how long a response (or rejected promise) should stay in the cache before it makes a new request when you fetch the same URL again.

For example, you could set the TTL to one second, no matter if a request succeeds or fails (please don't really do this, except you have a good reason):

const fetchCache = new FetchCache({ fetch, ttl: () => 1000 });

…or configure varying TTLs for specific HTTP response status codes (better):

const fetchCache = new FetchCache({
  fetch,
  ttl: ({ response, state, error }) => {
    // state is 'running', 'resolved' or 'rejected' here.
    if (response) {
      // If a response is successful, keep it in the cache for 2 minutes
      if (response.status === 200) return 2 * 60 * 1000;
      // If a response is successful, keep it in the cache for 10 seconds so it shows up if the
      // resource begins to exist in the meantime
      if (response.status === 404) return 10 * 1000;
    }
    // If you return `undefined` here, the cache will use default TTL values for all other cases.
  },
});

For an overview about more cases, consult the default implementation.

Normalize URLs

You can improve caching performance by letting the cache know if more than one URL points to the same server-side resource. For this, provide a normalizeURL function that builds a canonical URL from a given one.

The cache will only hold one response per canonical URL then. This saves memory and network bandwidth.

normalize-url is a helpful NPM package implementing real-world normalization rules like SSL enforcement and www. vs. non-www.-domain names. You can use it as normalization function:

# Install the package with
npm install normalize-url
# or
yarn add normalize-url
import normalizeURL from 'normalize-url';
import fetch from 'node-fetch';

// See https://github.com/sindresorhus/normalize-url#readme for all available normalization options
const cache = new FetchCache({
  fetch,
  normalizeURL(url) {
    return normalizeURL(url, { forceHttps: true });
  },
});

Contributors

Supported by

.

Readme

Keywords

none

Package Sidebar

Install

npm i @sozialhelden/fetch-cache

Weekly Downloads

6

Version

2.0.1

License

MIT

Unpacked Size

17.6 kB

Total Files

16

Last publish

Collaborators

  • sozialhelden_developer