96 lines
3.5 KiB
JavaScript
96 lines
3.5 KiB
JavaScript
/*
|
|
Copyright 2019 Google LLC
|
|
|
|
Use of this source code is governed by an MIT-style
|
|
license that can be found in the LICENSE file or at
|
|
https://opensource.org/licenses/MIT.
|
|
*/
|
|
|
|
import {assert} from 'workbox-core/_private/assert.mjs';
|
|
import {cacheNames} from 'workbox-core/_private/cacheNames.mjs';
|
|
import {logger} from 'workbox-core/_private/logger.mjs';
|
|
import {NavigationRoute} from './NavigationRoute.mjs';
|
|
import {getOrCreateDefaultRouter} from './utils/getOrCreateDefaultRouter.mjs';
|
|
import './_version.mjs';
|
|
|
|
|
|
/**
|
|
* Registers a route that will return a precached file for a navigation
|
|
* request. This is useful for the
|
|
* [application shell pattern]{@link https://developers.google.com/web/fundamentals/architecture/app-shell}.
|
|
*
|
|
* When determining the URL of the precached HTML document, you will likely need
|
|
* to call `workbox.precaching.getCacheKeyForURL(originalUrl)`, to account for
|
|
* the fact that Workbox's precaching naming conventions often results in URL
|
|
* cache keys that contain extra revisioning info.
|
|
*
|
|
* This method will generate a
|
|
* [NavigationRoute]{@link workbox.routing.NavigationRoute}
|
|
* and call
|
|
* [Router.registerRoute()]{@link workbox.routing.Router#registerRoute} on a
|
|
* singleton Router instance.
|
|
*
|
|
* @param {string} cachedAssetUrl The cache key to use for the HTML file.
|
|
* @param {Object} [options]
|
|
* @param {string} [options.cacheName] Cache name to store and retrieve
|
|
* requests. Defaults to precache cache name provided by
|
|
* [workbox-core.cacheNames]{@link workbox.core.cacheNames}.
|
|
* @param {Array<RegExp>} [options.blacklist=[]] If any of these patterns
|
|
* match, the route will not handle the request (even if a whitelist entry
|
|
* matches).
|
|
* @param {Array<RegExp>} [options.whitelist=[/./]] If any of these patterns
|
|
* match the URL's pathname and search parameter, the route will handle the
|
|
* request (assuming the blacklist doesn't match).
|
|
* @return {workbox.routing.NavigationRoute} Returns the generated
|
|
* Route.
|
|
*
|
|
* @alias workbox.routing.registerNavigationRoute
|
|
*/
|
|
export const registerNavigationRoute = (cachedAssetUrl, options = {}) => {
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
assert.isType(cachedAssetUrl, 'string', {
|
|
moduleName: 'workbox-routing',
|
|
funcName: 'registerNavigationRoute',
|
|
paramName: 'cachedAssetUrl',
|
|
});
|
|
}
|
|
|
|
const cacheName = cacheNames.getPrecacheName(options.cacheName);
|
|
const handler = async () => {
|
|
try {
|
|
const response = await caches.match(cachedAssetUrl, {cacheName});
|
|
|
|
if (response) {
|
|
return response;
|
|
}
|
|
|
|
// This shouldn't normally happen, but there are edge cases:
|
|
// https://github.com/GoogleChrome/workbox/issues/1441
|
|
throw new Error(`The cache ${cacheName} did not have an entry for ` +
|
|
`${cachedAssetUrl}.`);
|
|
} catch (error) {
|
|
// If there's either a cache miss, or the caches.match() call threw
|
|
// an exception, then attempt to fulfill the navigation request with
|
|
// a response from the network rather than leaving the user with a
|
|
// failed navigation.
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
logger.debug(`Unable to respond to navigation request with ` +
|
|
`cached response. Falling back to network.`, error);
|
|
}
|
|
|
|
// This might still fail if the browser is offline...
|
|
return fetch(cachedAssetUrl);
|
|
}
|
|
};
|
|
|
|
const route = new NavigationRoute(handler, {
|
|
whitelist: options.whitelist,
|
|
blacklist: options.blacklist,
|
|
});
|
|
|
|
const defaultRouter = getOrCreateDefaultRouter();
|
|
defaultRouter.registerRoute(route);
|
|
|
|
return route;
|
|
};
|