11/*
2- Copyright 2018 Google LLC
2+ Copyright 2019 Google LLC
33
44 Use of this source code is governed by an MIT-style
55 license that can be found in the LICENSE file or at
@@ -13,7 +13,8 @@ import {fetchWrapper} from 'workbox-core/_private/fetchWrapper.js';
1313import { logger } from 'workbox-core/_private/logger.js' ;
1414import { WorkboxError } from 'workbox-core/_private/WorkboxError.js' ;
1515import { copyResponse } from 'workbox-core/copyResponse.js' ;
16- import { RouteHandlerCallback } from 'workbox-core/types.js' ;
16+ import { RouteHandlerCallback , RouteHandlerCallbackOptions }
17+ from 'workbox-core/types.js' ;
1718import { WorkboxPlugin } from 'workbox-core/types.js' ;
1819
1920import { PrecacheEntry } from './_types.js' ;
@@ -310,58 +311,96 @@ class PrecacheController {
310311 }
311312
312313 /**
313- * Returns a function that looks up `url` in the precache (taking into
314- * account revision information), and returns the corresponding `Response`.
314+ * This acts as a drop-in replacement for [`cache.match()`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/match)
315+ * with the following differences:
316+ *
317+ * - It knows what the name of the precache is, and only checks in that cache.
318+ * - It allows you to pass in an "original" URL without versioning parameters,
319+ * and it will automatically look up the correct cache key for the currently
320+ * active revision of that URL.
321+ *
322+ * E.g., `matchPrecache('index.html')` will find the correct precached
323+ * response for the currently active service worker, even if the actual cache
324+ * key is `'/index.html?__WB_REVISION__=1234abcd'`.
315325 *
316- * If for an unexpected reason there is a cache miss when looking up `url`,
317- * this will fall back to retrieving the `Response` via `fetch()`.
318- *
319- * @param {string } url The precached URL which will be used to lookup the
320- * `Response`.
321- * @return {workbox.routing.Route~handlerCallback }
326+ * @param {string|Request } request The key (without revisioning parameters)
327+ * to look up in the precache.
328+ * @return {Promise<Response|undefined> }
322329 */
323- createHandlerForURL ( url : string ) : RouteHandlerCallback {
324- if ( process . env . NODE_ENV !== 'production' ) {
325- assert ! . isType ( url , 'string' , {
326- moduleName : 'workbox-precaching' ,
327- funcName : 'createHandlerForURL' ,
328- paramName : 'url' ,
329- } ) ;
330- }
331-
330+ async matchPrecache ( request : string | Request ) : Promise < Response | undefined > {
331+ const url = request instanceof Request ? request . url : request ;
332332 const cacheKey = this . getCacheKeyForURL ( url ) ;
333- if ( ! cacheKey ) {
334- throw new WorkboxError ( 'non-precached-url' , { url} ) ;
333+ if ( cacheKey ) {
334+ const cache = await caches . open ( this . _cacheName ) ;
335+ return cache . match ( cacheKey ) ;
335336 }
337+ return undefined ;
338+ }
336339
337- return async ( ) => {
340+ /**
341+ * Returns a function that can be used within a {@link workbox.routing.Route}
342+ * that will find a response for the incoming request against the precache.
343+ *
344+ * If for an unexpected reason there is a cache miss for the request,
345+ * this will fall back to retrieving the `Response` via `fetch()` when
346+ * `fallbackToNetwork` is `true`.
347+ *
348+ * @param {boolean } [fallbackToNetwork=true] Whether to attempt to get the
349+ * response from the network if there's a precache miss.
350+ * @return {workbox.routing.Route~handlerCallback }
351+ */
352+ createHandler ( fallbackToNetwork = true ) : RouteHandlerCallback {
353+ return async ( { request} : RouteHandlerCallbackOptions ) => {
338354 try {
339- const cache = await caches . open ( this . _cacheName ) ;
340- const response = await cache . match ( cacheKey ) ;
341-
355+ const response = await this . matchPrecache ( request ) ;
342356 if ( response ) {
343357 return response ;
344358 }
345359
346360 // This shouldn't normally happen, but there are edge cases:
347361 // https://github.com/GoogleChrome/workbox/issues/1441
348- throw new Error ( `The cache ${ this . _cacheName } did not have an entry ` +
349- `for ${ cacheKey } .` ) ;
362+ throw new WorkboxError ( 'missing-precache-entry' , {
363+ cacheName : this . _cacheName ,
364+ url : request . url ,
365+ } ) ;
350366 } catch ( error ) {
351- // If there's either a cache miss, or the caches.match() call threw
352- // an exception, then attempt to fulfill the navigation request with
353- // a response from the network rather than leaving the user with a
354- // failed navigation.
355- if ( process . env . NODE_ENV !== 'production' ) {
356- logger . debug ( `Unable to respond to navigation request with ` +
357- `cached response. Falling back to network.` , error ) ;
367+ if ( fallbackToNetwork ) {
368+ if ( process . env . NODE_ENV !== 'production' ) {
369+ logger . debug ( `Unable to respond with precached response. ` +
370+ `Falling back to network.` , error ) ;
371+ }
372+ return fetch ( request ) ;
358373 }
359374
360- // This might still fail if the browser is offline...
361- return fetch ( cacheKey ) ;
375+ throw error ;
362376 }
363377 } ;
364- } ;
378+ }
379+
380+ /**
381+ * Returns a function that looks up `url` in the precache (taking into
382+ * account revision information), and returns the corresponding `Response`.
383+ *
384+ * If for an unexpected reason there is a cache miss when looking up `url`,
385+ * this will fall back to retrieving the `Response` via `fetch()` when
386+ * `fallbackToNetwork` is `true`.
387+ *
388+ * @param {string } url The precached URL which will be used to lookup the
389+ * `Response`.
390+ * @param {boolean } [fallbackToNetwork=true] Whether to attempt to get the
391+ * response from the network if there's a precache miss.
392+ * @return {workbox.routing.Route~handlerCallback }
393+ */
394+ createHandlerBoundToURL ( url : string , fallbackToNetwork = true ) : RouteHandlerCallback {
395+ const cacheKey = this . getCacheKeyForURL ( url ) ;
396+ if ( ! cacheKey ) {
397+ throw new WorkboxError ( 'non-precached-url' , { url} ) ;
398+ }
399+
400+ const handler = this . createHandler ( fallbackToNetwork ) ;
401+ const request = new Request ( url ) ;
402+ return ( ) => handler ( { request} ) ;
403+ }
365404}
366405
367406export { PrecacheController } ;
0 commit comments