mistval / node-fetch-cache

Node-fetch with built-in response caching.
MIT License
51 stars 8 forks source link

Have cache strategies support "incremental" caching #21

Closed bas080 closed 1 year ago

bas080 commented 2 years ago

The idea is that the cache is always served unless there is none. Whenever the cache is fetched; it also updates the cache in the background.

I suggest to add this as an option in the options object.

const nodeFetch = fetchBuilder.withCache(new FileSystemCache({
  incremental: true,
  ttl: 2000
}))

Could also be named background...

What I'm doing now which does work :tada: is the following:

function nodeFetch(...args) {
  return nodeFetchCache(...args).then(tap(async res => {
    await res.ejectFromCache()
    await nodeFetchCache(...args)
  }))
}
bas080 commented 2 years ago

The above solution is not actually the feature I'm looking for. The reason being that requests that are performed directly after a previous request result in a wait as the has been rejected by the previous request.

Ideally I would like to serve the previous cache while the cache is updated.

mistval commented 1 year ago

Hi, sorry for the belated response on this.

If I'm understanding right, you always want to make a fresh request, but if a cached version is available, you want to return that immediately, without waiting for the request to finish.

I think that's not quite aligned with what this module aims to achieve, but I can suggest some code that should basically do that:

async function fetchCache(url) {
  const response = await fetch(url);

  // If the response came from the cache, eject it and fetch it again to add a fresh version to the cache
  if (response.fromCache) {
    await response.ejectFromCache();
    fetch(url).catch(console.error);
  }

  return response;
}

One caveat though is that if something calls this function after the response is ejected from the cache and before the new copy gets into the cache, it will wait for the new request to finish.