source: frontend/node_modules/workbox-expiration/src/CacheExpiration.ts

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: 6.5 KB
Line 
1/*
2 Copyright 2018 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*/
8
9import {assert} from 'workbox-core/_private/assert.js';
10import {dontWaitFor} from 'workbox-core/_private/dontWaitFor.js';
11import {logger} from 'workbox-core/_private/logger.js';
12import {WorkboxError} from 'workbox-core/_private/WorkboxError.js';
13
14import {CacheTimestampsModel} from './models/CacheTimestampsModel.js';
15
16import './_version.js';
17
18interface CacheExpirationConfig {
19 maxEntries?: number;
20 maxAgeSeconds?: number;
21 matchOptions?: CacheQueryOptions;
22}
23
24/**
25 * The `CacheExpiration` class allows you define an expiration and / or
26 * limit on the number of responses stored in a
27 * [`Cache`](https://developer.mozilla.org/en-US/docs/Web/API/Cache).
28 *
29 * @memberof workbox-expiration
30 */
31class CacheExpiration {
32 private _isRunning = false;
33 private _rerunRequested = false;
34 private readonly _maxEntries?: number;
35 private readonly _maxAgeSeconds?: number;
36 private readonly _matchOptions?: CacheQueryOptions;
37 private readonly _cacheName: string;
38 private readonly _timestampModel: CacheTimestampsModel;
39
40 /**
41 * To construct a new CacheExpiration instance you must provide at least
42 * one of the `config` properties.
43 *
44 * @param {string} cacheName Name of the cache to apply restrictions to.
45 * @param {Object} config
46 * @param {number} [config.maxEntries] The maximum number of entries to cache.
47 * Entries used the least will be removed as the maximum is reached.
48 * @param {number} [config.maxAgeSeconds] The maximum age of an entry before
49 * it's treated as stale and removed.
50 * @param {Object} [config.matchOptions] The [`CacheQueryOptions`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/delete#Parameters)
51 * that will be used when calling `delete()` on the cache.
52 */
53 constructor(cacheName: string, config: CacheExpirationConfig = {}) {
54 if (process.env.NODE_ENV !== 'production') {
55 assert!.isType(cacheName, 'string', {
56 moduleName: 'workbox-expiration',
57 className: 'CacheExpiration',
58 funcName: 'constructor',
59 paramName: 'cacheName',
60 });
61
62 if (!(config.maxEntries || config.maxAgeSeconds)) {
63 throw new WorkboxError('max-entries-or-age-required', {
64 moduleName: 'workbox-expiration',
65 className: 'CacheExpiration',
66 funcName: 'constructor',
67 });
68 }
69
70 if (config.maxEntries) {
71 assert!.isType(config.maxEntries, 'number', {
72 moduleName: 'workbox-expiration',
73 className: 'CacheExpiration',
74 funcName: 'constructor',
75 paramName: 'config.maxEntries',
76 });
77 }
78
79 if (config.maxAgeSeconds) {
80 assert!.isType(config.maxAgeSeconds, 'number', {
81 moduleName: 'workbox-expiration',
82 className: 'CacheExpiration',
83 funcName: 'constructor',
84 paramName: 'config.maxAgeSeconds',
85 });
86 }
87 }
88
89 this._maxEntries = config.maxEntries;
90 this._maxAgeSeconds = config.maxAgeSeconds;
91 this._matchOptions = config.matchOptions;
92 this._cacheName = cacheName;
93 this._timestampModel = new CacheTimestampsModel(cacheName);
94 }
95
96 /**
97 * Expires entries for the given cache and given criteria.
98 */
99 async expireEntries(): Promise<void> {
100 if (this._isRunning) {
101 this._rerunRequested = true;
102 return;
103 }
104 this._isRunning = true;
105
106 const minTimestamp = this._maxAgeSeconds
107 ? Date.now() - this._maxAgeSeconds * 1000
108 : 0;
109
110 const urlsExpired = await this._timestampModel.expireEntries(
111 minTimestamp,
112 this._maxEntries,
113 );
114
115 // Delete URLs from the cache
116 const cache = await self.caches.open(this._cacheName);
117 for (const url of urlsExpired) {
118 await cache.delete(url, this._matchOptions);
119 }
120
121 if (process.env.NODE_ENV !== 'production') {
122 if (urlsExpired.length > 0) {
123 logger.groupCollapsed(
124 `Expired ${urlsExpired.length} ` +
125 `${urlsExpired.length === 1 ? 'entry' : 'entries'} and removed ` +
126 `${urlsExpired.length === 1 ? 'it' : 'them'} from the ` +
127 `'${this._cacheName}' cache.`,
128 );
129 logger.log(
130 `Expired the following ${urlsExpired.length === 1 ? 'URL' : 'URLs'}:`,
131 );
132 urlsExpired.forEach((url) => logger.log(` ${url}`));
133 logger.groupEnd();
134 } else {
135 logger.debug(`Cache expiration ran and found no entries to remove.`);
136 }
137 }
138
139 this._isRunning = false;
140 if (this._rerunRequested) {
141 this._rerunRequested = false;
142 dontWaitFor(this.expireEntries());
143 }
144 }
145
146 /**
147 * Update the timestamp for the given URL. This ensures the when
148 * removing entries based on maximum entries, most recently used
149 * is accurate or when expiring, the timestamp is up-to-date.
150 *
151 * @param {string} url
152 */
153 async updateTimestamp(url: string): Promise<void> {
154 if (process.env.NODE_ENV !== 'production') {
155 assert!.isType(url, 'string', {
156 moduleName: 'workbox-expiration',
157 className: 'CacheExpiration',
158 funcName: 'updateTimestamp',
159 paramName: 'url',
160 });
161 }
162
163 await this._timestampModel.setTimestamp(url, Date.now());
164 }
165
166 /**
167 * Can be used to check if a URL has expired or not before it's used.
168 *
169 * This requires a look up from IndexedDB, so can be slow.
170 *
171 * Note: This method will not remove the cached entry, call
172 * `expireEntries()` to remove indexedDB and Cache entries.
173 *
174 * @param {string} url
175 * @return {boolean}
176 */
177 async isURLExpired(url: string): Promise<boolean> {
178 if (!this._maxAgeSeconds) {
179 if (process.env.NODE_ENV !== 'production') {
180 throw new WorkboxError(`expired-test-without-max-age`, {
181 methodName: 'isURLExpired',
182 paramName: 'maxAgeSeconds',
183 });
184 }
185 return false;
186 } else {
187 const timestamp = await this._timestampModel.getTimestamp(url);
188 const expireOlderThan = Date.now() - this._maxAgeSeconds * 1000;
189 return timestamp !== undefined ? timestamp < expireOlderThan : true;
190 }
191 }
192
193 /**
194 * Removes the IndexedDB object store used to keep track of cache expiration
195 * metadata.
196 */
197 async delete(): Promise<void> {
198 // Make sure we don't attempt another rerun if we're called in the middle of
199 // a cache expiration.
200 this._rerunRequested = false;
201 await this._timestampModel.expireEntries(Infinity); // Expires all.
202 }
203}
204
205export {CacheExpiration};
Note: See TracBrowser for help on using the repository browser.