source: frontend/node_modules/workbox-precaching/PrecacheController.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 11.9 KB
Line 
1/*
2 Copyright 2019 Google LLC
3
4 Use of this source code is governed by an MIT-style
5 license that can be found in the LICENSE file or at
6 https://opensource.org/licenses/MIT.
7*/
8import { assert } from 'workbox-core/_private/assert.js';
9import { cacheNames } from 'workbox-core/_private/cacheNames.js';
10import { logger } from 'workbox-core/_private/logger.js';
11import { WorkboxError } from 'workbox-core/_private/WorkboxError.js';
12import { waitUntil } from 'workbox-core/_private/waitUntil.js';
13import { createCacheKey } from './utils/createCacheKey.js';
14import { PrecacheInstallReportPlugin } from './utils/PrecacheInstallReportPlugin.js';
15import { PrecacheCacheKeyPlugin } from './utils/PrecacheCacheKeyPlugin.js';
16import { printCleanupDetails } from './utils/printCleanupDetails.js';
17import { printInstallDetails } from './utils/printInstallDetails.js';
18import { PrecacheStrategy } from './PrecacheStrategy.js';
19import './_version.js';
20/**
21 * Performs efficient precaching of assets.
22 *
23 * @memberof workbox-precaching
24 */
25class PrecacheController {
26 /**
27 * Create a new PrecacheController.
28 *
29 * @param {Object} [options]
30 * @param {string} [options.cacheName] The cache to use for precaching.
31 * @param {string} [options.plugins] Plugins to use when precaching as well
32 * as responding to fetch events for precached assets.
33 * @param {boolean} [options.fallbackToNetwork=true] Whether to attempt to
34 * get the response from the network if there's a precache miss.
35 */
36 constructor({ cacheName, plugins = [], fallbackToNetwork = true, } = {}) {
37 this._urlsToCacheKeys = new Map();
38 this._urlsToCacheModes = new Map();
39 this._cacheKeysToIntegrities = new Map();
40 this._strategy = new PrecacheStrategy({
41 cacheName: cacheNames.getPrecacheName(cacheName),
42 plugins: [
43 ...plugins,
44 new PrecacheCacheKeyPlugin({ precacheController: this }),
45 ],
46 fallbackToNetwork,
47 });
48 // Bind the install and activate methods to the instance.
49 this.install = this.install.bind(this);
50 this.activate = this.activate.bind(this);
51 }
52 /**
53 * @type {workbox-precaching.PrecacheStrategy} The strategy created by this controller and
54 * used to cache assets and respond to fetch events.
55 */
56 get strategy() {
57 return this._strategy;
58 }
59 /**
60 * Adds items to the precache list, removing any duplicates and
61 * stores the files in the
62 * {@link workbox-core.cacheNames|"precache cache"} when the service
63 * worker installs.
64 *
65 * This method can be called multiple times.
66 *
67 * @param {Array<Object|string>} [entries=[]] Array of entries to precache.
68 */
69 precache(entries) {
70 this.addToCacheList(entries);
71 if (!this._installAndActiveListenersAdded) {
72 self.addEventListener('install', this.install);
73 self.addEventListener('activate', this.activate);
74 this._installAndActiveListenersAdded = true;
75 }
76 }
77 /**
78 * This method will add items to the precache list, removing duplicates
79 * and ensuring the information is valid.
80 *
81 * @param {Array<workbox-precaching.PrecacheController.PrecacheEntry|string>} entries
82 * Array of entries to precache.
83 */
84 addToCacheList(entries) {
85 if (process.env.NODE_ENV !== 'production') {
86 assert.isArray(entries, {
87 moduleName: 'workbox-precaching',
88 className: 'PrecacheController',
89 funcName: 'addToCacheList',
90 paramName: 'entries',
91 });
92 }
93 const urlsToWarnAbout = [];
94 for (const entry of entries) {
95 // See https://github.com/GoogleChrome/workbox/issues/2259
96 if (typeof entry === 'string') {
97 urlsToWarnAbout.push(entry);
98 }
99 else if (entry && entry.revision === undefined) {
100 urlsToWarnAbout.push(entry.url);
101 }
102 const { cacheKey, url } = createCacheKey(entry);
103 const cacheMode = typeof entry !== 'string' && entry.revision ? 'reload' : 'default';
104 if (this._urlsToCacheKeys.has(url) &&
105 this._urlsToCacheKeys.get(url) !== cacheKey) {
106 throw new WorkboxError('add-to-cache-list-conflicting-entries', {
107 firstEntry: this._urlsToCacheKeys.get(url),
108 secondEntry: cacheKey,
109 });
110 }
111 if (typeof entry !== 'string' && entry.integrity) {
112 if (this._cacheKeysToIntegrities.has(cacheKey) &&
113 this._cacheKeysToIntegrities.get(cacheKey) !== entry.integrity) {
114 throw new WorkboxError('add-to-cache-list-conflicting-integrities', {
115 url,
116 });
117 }
118 this._cacheKeysToIntegrities.set(cacheKey, entry.integrity);
119 }
120 this._urlsToCacheKeys.set(url, cacheKey);
121 this._urlsToCacheModes.set(url, cacheMode);
122 if (urlsToWarnAbout.length > 0) {
123 const warningMessage = `Workbox is precaching URLs without revision ` +
124 `info: ${urlsToWarnAbout.join(', ')}\nThis is generally NOT safe. ` +
125 `Learn more at https://bit.ly/wb-precache`;
126 if (process.env.NODE_ENV === 'production') {
127 // Use console directly to display this warning without bloating
128 // bundle sizes by pulling in all of the logger codebase in prod.
129 console.warn(warningMessage);
130 }
131 else {
132 logger.warn(warningMessage);
133 }
134 }
135 }
136 }
137 /**
138 * Precaches new and updated assets. Call this method from the service worker
139 * install event.
140 *
141 * Note: this method calls `event.waitUntil()` for you, so you do not need
142 * to call it yourself in your event handlers.
143 *
144 * @param {ExtendableEvent} event
145 * @return {Promise<workbox-precaching.InstallResult>}
146 */
147 install(event) {
148 // waitUntil returns Promise<any>
149 // eslint-disable-next-line @typescript-eslint/no-unsafe-return
150 return waitUntil(event, async () => {
151 const installReportPlugin = new PrecacheInstallReportPlugin();
152 this.strategy.plugins.push(installReportPlugin);
153 // Cache entries one at a time.
154 // See https://github.com/GoogleChrome/workbox/issues/2528
155 for (const [url, cacheKey] of this._urlsToCacheKeys) {
156 const integrity = this._cacheKeysToIntegrities.get(cacheKey);
157 const cacheMode = this._urlsToCacheModes.get(url);
158 const request = new Request(url, {
159 integrity,
160 cache: cacheMode,
161 credentials: 'same-origin',
162 });
163 await Promise.all(this.strategy.handleAll({
164 params: { cacheKey },
165 request,
166 event,
167 }));
168 }
169 const { updatedURLs, notUpdatedURLs } = installReportPlugin;
170 if (process.env.NODE_ENV !== 'production') {
171 printInstallDetails(updatedURLs, notUpdatedURLs);
172 }
173 return { updatedURLs, notUpdatedURLs };
174 });
175 }
176 /**
177 * Deletes assets that are no longer present in the current precache manifest.
178 * Call this method from the service worker activate event.
179 *
180 * Note: this method calls `event.waitUntil()` for you, so you do not need
181 * to call it yourself in your event handlers.
182 *
183 * @param {ExtendableEvent} event
184 * @return {Promise<workbox-precaching.CleanupResult>}
185 */
186 activate(event) {
187 // waitUntil returns Promise<any>
188 // eslint-disable-next-line @typescript-eslint/no-unsafe-return
189 return waitUntil(event, async () => {
190 const cache = await self.caches.open(this.strategy.cacheName);
191 const currentlyCachedRequests = await cache.keys();
192 const expectedCacheKeys = new Set(this._urlsToCacheKeys.values());
193 const deletedURLs = [];
194 for (const request of currentlyCachedRequests) {
195 if (!expectedCacheKeys.has(request.url)) {
196 await cache.delete(request);
197 deletedURLs.push(request.url);
198 }
199 }
200 if (process.env.NODE_ENV !== 'production') {
201 printCleanupDetails(deletedURLs);
202 }
203 return { deletedURLs };
204 });
205 }
206 /**
207 * Returns a mapping of a precached URL to the corresponding cache key, taking
208 * into account the revision information for the URL.
209 *
210 * @return {Map<string, string>} A URL to cache key mapping.
211 */
212 getURLsToCacheKeys() {
213 return this._urlsToCacheKeys;
214 }
215 /**
216 * Returns a list of all the URLs that have been precached by the current
217 * service worker.
218 *
219 * @return {Array<string>} The precached URLs.
220 */
221 getCachedURLs() {
222 return [...this._urlsToCacheKeys.keys()];
223 }
224 /**
225 * Returns the cache key used for storing a given URL. If that URL is
226 * unversioned, like `/index.html', then the cache key will be the original
227 * URL with a search parameter appended to it.
228 *
229 * @param {string} url A URL whose cache key you want to look up.
230 * @return {string} The versioned URL that corresponds to a cache key
231 * for the original URL, or undefined if that URL isn't precached.
232 */
233 getCacheKeyForURL(url) {
234 const urlObject = new URL(url, location.href);
235 return this._urlsToCacheKeys.get(urlObject.href);
236 }
237 /**
238 * @param {string} url A cache key whose SRI you want to look up.
239 * @return {string} The subresource integrity associated with the cache key,
240 * or undefined if it's not set.
241 */
242 getIntegrityForCacheKey(cacheKey) {
243 return this._cacheKeysToIntegrities.get(cacheKey);
244 }
245 /**
246 * This acts as a drop-in replacement for
247 * [`cache.match()`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/match)
248 * with the following differences:
249 *
250 * - It knows what the name of the precache is, and only checks in that cache.
251 * - It allows you to pass in an "original" URL without versioning parameters,
252 * and it will automatically look up the correct cache key for the currently
253 * active revision of that URL.
254 *
255 * E.g., `matchPrecache('index.html')` will find the correct precached
256 * response for the currently active service worker, even if the actual cache
257 * key is `'/index.html?__WB_REVISION__=1234abcd'`.
258 *
259 * @param {string|Request} request The key (without revisioning parameters)
260 * to look up in the precache.
261 * @return {Promise<Response|undefined>}
262 */
263 async matchPrecache(request) {
264 const url = request instanceof Request ? request.url : request;
265 const cacheKey = this.getCacheKeyForURL(url);
266 if (cacheKey) {
267 const cache = await self.caches.open(this.strategy.cacheName);
268 return cache.match(cacheKey);
269 }
270 return undefined;
271 }
272 /**
273 * Returns a function that looks up `url` in the precache (taking into
274 * account revision information), and returns the corresponding `Response`.
275 *
276 * @param {string} url The precached URL which will be used to lookup the
277 * `Response`.
278 * @return {workbox-routing~handlerCallback}
279 */
280 createHandlerBoundToURL(url) {
281 const cacheKey = this.getCacheKeyForURL(url);
282 if (!cacheKey) {
283 throw new WorkboxError('non-precached-url', { url });
284 }
285 return (options) => {
286 options.request = new Request(url);
287 options.params = Object.assign({ cacheKey }, options.params);
288 return this.strategy.handle(options);
289 };
290 }
291}
292export { PrecacheController };
Note: See TracBrowser for help on using the repository browser.