123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- import { assert } from 'workbox-core/_private/assert.js';
- import { logger } from 'workbox-core/_private/logger.js';
- import { WorkboxError } from 'workbox-core/_private/WorkboxError.js';
- import { cacheOkAndOpaquePlugin } from './plugins/cacheOkAndOpaquePlugin.js';
- import { Strategy } from './Strategy.js';
- import { messages } from './utils/messages.js';
- import './_version.js';
- class NetworkFirst extends Strategy {
-
- constructor(options = {}) {
- super(options);
-
-
- if (!this.plugins.some((p) => 'cacheWillUpdate' in p)) {
- this.plugins.unshift(cacheOkAndOpaquePlugin);
- }
- this._networkTimeoutSeconds = options.networkTimeoutSeconds || 0;
- if (process.env.NODE_ENV !== 'production') {
- if (this._networkTimeoutSeconds) {
- assert.isType(this._networkTimeoutSeconds, 'number', {
- moduleName: 'workbox-strategies',
- className: this.constructor.name,
- funcName: 'constructor',
- paramName: 'networkTimeoutSeconds',
- });
- }
- }
- }
-
- async _handle(request, handler) {
- const logs = [];
- if (process.env.NODE_ENV !== 'production') {
- assert.isInstance(request, Request, {
- moduleName: 'workbox-strategies',
- className: this.constructor.name,
- funcName: 'handle',
- paramName: 'makeRequest',
- });
- }
- const promises = [];
- let timeoutId;
- if (this._networkTimeoutSeconds) {
- const { id, promise } = this._getTimeoutPromise({ request, logs, handler });
- timeoutId = id;
- promises.push(promise);
- }
- const networkPromise = this._getNetworkPromise({
- timeoutId,
- request,
- logs,
- handler,
- });
- promises.push(networkPromise);
- const response = await handler.waitUntil((async () => {
-
- return ((await handler.waitUntil(Promise.race(promises))) ||
-
-
-
-
-
- (await networkPromise));
- })());
- if (process.env.NODE_ENV !== 'production') {
- logger.groupCollapsed(messages.strategyStart(this.constructor.name, request));
- for (const log of logs) {
- logger.log(log);
- }
- messages.printFinalResponse(response);
- logger.groupEnd();
- }
- if (!response) {
- throw new WorkboxError('no-response', { url: request.url });
- }
- return response;
- }
-
- _getTimeoutPromise({ request, logs, handler, }) {
- let timeoutId;
- const timeoutPromise = new Promise((resolve) => {
- const onNetworkTimeout = async () => {
- if (process.env.NODE_ENV !== 'production') {
- logs.push(`Timing out the network response at ` +
- `${this._networkTimeoutSeconds} seconds.`);
- }
- resolve(await handler.cacheMatch(request));
- };
- timeoutId = setTimeout(onNetworkTimeout, this._networkTimeoutSeconds * 1000);
- });
- return {
- promise: timeoutPromise,
- id: timeoutId,
- };
- }
-
- async _getNetworkPromise({ timeoutId, request, logs, handler, }) {
- let error;
- let response;
- try {
- response = await handler.fetchAndCachePut(request);
- }
- catch (fetchError) {
- if (fetchError instanceof Error) {
- error = fetchError;
- }
- }
- if (timeoutId) {
- clearTimeout(timeoutId);
- }
- if (process.env.NODE_ENV !== 'production') {
- if (response) {
- logs.push(`Got response from network.`);
- }
- else {
- logs.push(`Unable to get a response from the network. Will respond ` +
- `with a cached response.`);
- }
- }
- if (error || !response) {
- response = await handler.cacheMatch(request);
- if (process.env.NODE_ENV !== 'production') {
- if (response) {
- logs.push(`Found a cached response in the '${this.cacheName}'` + ` cache.`);
- }
- else {
- logs.push(`No response found in the '${this.cacheName}' cache.`);
- }
- }
- }
- return response;
- }
- }
- export { NetworkFirst };
|