CacheFirst.js 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /*
  2. Copyright 2018 Google LLC
  3. Use of this source code is governed by an MIT-style
  4. license that can be found in the LICENSE file or at
  5. https://opensource.org/licenses/MIT.
  6. */
  7. import { assert } from 'workbox-core/_private/assert.js';
  8. import { logger } from 'workbox-core/_private/logger.js';
  9. import { WorkboxError } from 'workbox-core/_private/WorkboxError.js';
  10. import { Strategy } from './Strategy.js';
  11. import { messages } from './utils/messages.js';
  12. import './_version.js';
  13. /**
  14. * An implementation of a [cache-first](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#cache-first-falling-back-to-network)
  15. * request strategy.
  16. *
  17. * A cache first strategy is useful for assets that have been revisioned,
  18. * such as URLs like `/styles/example.a8f5f1.css`, since they
  19. * can be cached for long periods of time.
  20. *
  21. * If the network request fails, and there is no cache match, this will throw
  22. * a `WorkboxError` exception.
  23. *
  24. * @extends workbox-strategies.Strategy
  25. * @memberof workbox-strategies
  26. */
  27. class CacheFirst extends Strategy {
  28. /**
  29. * @private
  30. * @param {Request|string} request A request to run this strategy for.
  31. * @param {workbox-strategies.StrategyHandler} handler The event that
  32. * triggered the request.
  33. * @return {Promise<Response>}
  34. */
  35. async _handle(request, handler) {
  36. const logs = [];
  37. if (process.env.NODE_ENV !== 'production') {
  38. assert.isInstance(request, Request, {
  39. moduleName: 'workbox-strategies',
  40. className: this.constructor.name,
  41. funcName: 'makeRequest',
  42. paramName: 'request',
  43. });
  44. }
  45. let response = await handler.cacheMatch(request);
  46. let error = undefined;
  47. if (!response) {
  48. if (process.env.NODE_ENV !== 'production') {
  49. logs.push(`No response found in the '${this.cacheName}' cache. ` +
  50. `Will respond with a network request.`);
  51. }
  52. try {
  53. response = await handler.fetchAndCachePut(request);
  54. }
  55. catch (err) {
  56. if (err instanceof Error) {
  57. error = err;
  58. }
  59. }
  60. if (process.env.NODE_ENV !== 'production') {
  61. if (response) {
  62. logs.push(`Got response from network.`);
  63. }
  64. else {
  65. logs.push(`Unable to get a response from the network.`);
  66. }
  67. }
  68. }
  69. else {
  70. if (process.env.NODE_ENV !== 'production') {
  71. logs.push(`Found a cached response in the '${this.cacheName}' cache.`);
  72. }
  73. }
  74. if (process.env.NODE_ENV !== 'production') {
  75. logger.groupCollapsed(messages.strategyStart(this.constructor.name, request));
  76. for (const log of logs) {
  77. logger.log(log);
  78. }
  79. messages.printFinalResponse(response);
  80. logger.groupEnd();
  81. }
  82. if (!response) {
  83. throw new WorkboxError('no-response', { url: request.url, error });
  84. }
  85. return response;
  86. }
  87. }
  88. export { CacheFirst };