export default function getHandlers()

in fusion-plugin-service-worker/src/handlers.js [12:112]


export default function getHandlers(assetInfo: AssetInfo) {
  const {
    precachePaths,
    cacheableResourcePaths,
    cacheableRoutePatternStrings,
    cacheBustingPatternStrings,
    cacheDuration = defaultMaxCacheDuration,
  } = assetInfo;
  const cacheableRoutePatterns = mapToRegex(cacheableRoutePatternStrings);
  const cacheBustingPatterns = mapToRegex(cacheBustingPatternStrings);
  return {
    onInstall: (event: InstallEvent) => {
      self.skipWaiting();
      event.waitUntil(
        // remove old caches, then precache
        caches.delete(cacheName).then(() =>
          caches
            .open(cacheName)
            .then(cache => {
              return cache.addAll(precachePaths);
            })
            .catch(e => {
              // Don't throw an error because we expect CORS (CDN) requests to not be precacheable
              // (`addAll` expects a 200 response, but CORS returns an opaque response)
              // CORS resources will be lazily cached on first fetch instead
              debug.log(`[sw debug] unable to pre-cache some resources: ${e}`);
            })
        )
      );
    },
    onActivate: (event: InstallEvent) => {
      // let all existing clients claim this new worker instance
      event.waitUntil(clients.claim());
      self.clients.matchAll().then(all =>
        all.map(client =>
          client.postMessage({
            type: 'upgrade-available',
            text: '*** from sw: reload for updates',
          })
        )
      );
    },
    onFetch: (event: FetchEvent) => {
      try {
        const expectsHtml = requestExpectsHtml(event.request);
        if (shouldInvalidateCache(event, cacheBustingPatterns)) {
          // clear cache then bypass service worker, use network
          return caches
            .delete(cacheName)
            .then(() =>
              debug.log(
                `[debug] navigation to ${event.request.url}, invalidated cache`
              )
            );
        }
        if (
          !requestIsCacheable(
            expectsHtml,
            cacheableResourcePaths,
            cacheableRoutePatterns,
            event
          )
        ) {
          // bypass service worker, use network
          return;
        }
        const p = caches.match(event.request).then(cachedResponse => {
          if (cachedResponse) {
            if (expectsHtml) {
              if (cacheHasExpired(cachedResponse, cacheDuration)) {
                // if html cache has expired, clear all caches and refetch
                return caches
                  .delete(cacheName)
                  .then(() =>
                    self.clients.matchAll().then(all =>
                      all.map(client =>
                        client.postMessage({
                          type: 'cache-expired',
                          text: '*** from sw: cache expired',
                        })
                      )
                    )
                  )
                  .then(() => fetchAndCache(event.request, expectsHtml));
              }
            }
            fetchAndCache(event.request, expectsHtml); // async update cache for next time
            return cachedResponse; // return cache now
          }
          return fetchAndCache(event.request, expectsHtml); // fetch, then cache and return
        });
        event.respondWith(p);
        event.waitUntil(p);
      } catch (e) {
        caches
          .delete(cacheName)
          .then(() => debug.log(`*** sw fetch failed with`, e));
      }
    },
  };
}