• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1const { NotCachedError } = require('./errors.js')
2const CacheEntry = require('./entry.js')
3const remote = require('../remote.js')
4
5// do whatever is necessary to get a Response and return it
6const cacheFetch = async (request, options) => {
7  // try to find a cached entry that satisfies this request
8  const entry = await CacheEntry.find(request, options)
9  if (!entry) {
10    // no cached result, if the cache mode is 'only-if-cached' that's a failure
11    if (options.cache === 'only-if-cached') {
12      throw new NotCachedError(request.url)
13    }
14
15    // otherwise, we make a request, store it and return it
16    const response = await remote(request, options)
17    const newEntry = new CacheEntry({ request, response, options })
18    return newEntry.store('miss')
19  }
20
21  // we have a cached response that satisfies this request, however if the cache
22  // mode is 'no-cache' then we send the revalidation request no matter what
23  if (options.cache === 'no-cache') {
24    return entry.revalidate(request, options)
25  }
26
27  // if the cached entry is not stale, or if the cache mode is 'force-cache' or
28  // 'only-if-cached' we can respond with the cached entry. set the status
29  // based on the result of needsRevalidation and respond
30  const _needsRevalidation = entry.policy.needsRevalidation(request)
31  if (options.cache === 'force-cache' ||
32      options.cache === 'only-if-cached' ||
33      !_needsRevalidation) {
34    return entry.respond(request.method, options, _needsRevalidation ? 'stale' : 'hit')
35  }
36
37  // if we got here, the cache entry is stale so revalidate it
38  return entry.revalidate(request, options)
39}
40
41cacheFetch.invalidate = async (request, options) => {
42  if (!options.cachePath) {
43    return
44  }
45
46  return CacheEntry.invalidate(request, options)
47}
48
49module.exports = cacheFetch
50