source: frontend/node_modules/webpack/lib/CacheFacade.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: 9.4 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const { forEachBail } = require("enhanced-resolve");
9const asyncLib = require("neo-async");
10const getLazyHashedEtag = require("./cache/getLazyHashedEtag");
11const mergeEtags = require("./cache/mergeEtags");
12
13/** @typedef {import("./Cache")} Cache */
14/** @typedef {import("./Cache").Etag} Etag */
15/** @typedef {import("./cache/getLazyHashedEtag").HashableObject} HashableObject */
16/** @typedef {import("./util/Hash").HashFunction} HashFunction */
17
18/**
19 * Defines the callback cache callback.
20 * @template T
21 * @callback CallbackCache
22 * @param {(Error | null)=} err
23 * @param {(T | null)=} result
24 * @returns {void}
25 */
26
27/**
28 * Defines the callback normal error cache callback.
29 * @template T
30 * @callback CallbackNormalErrorCache
31 * @param {(Error | null)=} err
32 * @param {T=} result
33 * @returns {void}
34 */
35
36class MultiItemCache {
37 /**
38 * Creates an instance of MultiItemCache.
39 * @param {ItemCacheFacade[]} items item caches
40 */
41 constructor(items) {
42 this._items = items;
43 // @ts-expect-error expected - returns the single ItemCacheFacade when passed an array of length 1
44 // eslint-disable-next-line no-constructor-return
45 if (items.length === 1) return /** @type {ItemCacheFacade} */ (items[0]);
46 }
47
48 /**
49 * Returns value.
50 * @template T
51 * @param {CallbackCache<T>} callback signals when the value is retrieved
52 * @returns {void}
53 */
54 get(callback) {
55 forEachBail(this._items, (item, callback) => item.get(callback), callback);
56 }
57
58 /**
59 * Returns promise with the data.
60 * @template T
61 * @returns {Promise<T>} promise with the data
62 */
63 getPromise() {
64 /**
65 * Returns promise with the data.
66 * @param {number} i index
67 * @returns {Promise<T>} promise with the data
68 */
69 const next = (i) =>
70 this._items[i].getPromise().then((result) => {
71 if (result !== undefined) return result;
72 if (++i < this._items.length) return next(i);
73 });
74 return next(0);
75 }
76
77 /**
78 * Processes the provided data.
79 * @template T
80 * @param {T} data the value to store
81 * @param {CallbackCache<void>} callback signals when the value is stored
82 * @returns {void}
83 */
84 store(data, callback) {
85 asyncLib.each(
86 this._items,
87 (item, callback) => item.store(data, callback),
88 callback
89 );
90 }
91
92 /**
93 * Stores the provided data.
94 * @template T
95 * @param {T} data the value to store
96 * @returns {Promise<void>} promise signals when the value is stored
97 */
98 storePromise(data) {
99 return Promise.all(this._items.map((item) => item.storePromise(data))).then(
100 () => {}
101 );
102 }
103}
104
105class ItemCacheFacade {
106 /**
107 * Creates an instance of ItemCacheFacade.
108 * @param {Cache} cache the root cache
109 * @param {string} name the child cache item name
110 * @param {Etag | null} etag the etag
111 */
112 constructor(cache, name, etag) {
113 this._cache = cache;
114 this._name = name;
115 this._etag = etag;
116 }
117
118 /**
119 * Returns value.
120 * @template T
121 * @param {CallbackCache<T>} callback signals when the value is retrieved
122 * @returns {void}
123 */
124 get(callback) {
125 this._cache.get(this._name, this._etag, callback);
126 }
127
128 /**
129 * Returns promise with the data.
130 * @template T
131 * @returns {Promise<T>} promise with the data
132 */
133 getPromise() {
134 return new Promise((resolve, reject) => {
135 this._cache.get(this._name, this._etag, (err, data) => {
136 if (err) {
137 reject(err);
138 } else {
139 resolve(data);
140 }
141 });
142 });
143 }
144
145 /**
146 * Processes the provided data.
147 * @template T
148 * @param {T} data the value to store
149 * @param {CallbackCache<void>} callback signals when the value is stored
150 * @returns {void}
151 */
152 store(data, callback) {
153 this._cache.store(this._name, this._etag, data, callback);
154 }
155
156 /**
157 * Stores the provided data.
158 * @template T
159 * @param {T} data the value to store
160 * @returns {Promise<void>} promise signals when the value is stored
161 */
162 storePromise(data) {
163 return new Promise((resolve, reject) => {
164 this._cache.store(this._name, this._etag, data, (err) => {
165 if (err) {
166 reject(err);
167 } else {
168 resolve();
169 }
170 });
171 });
172 }
173
174 /**
175 * Processes the provided computer.
176 * @template T
177 * @param {(callback: CallbackNormalErrorCache<T>) => void} computer function to compute the value if not cached
178 * @param {CallbackNormalErrorCache<T>} callback signals when the value is retrieved
179 * @returns {void}
180 */
181 provide(computer, callback) {
182 this.get((err, cacheEntry) => {
183 if (err) return callback(err);
184 if (cacheEntry !== undefined) return cacheEntry;
185 computer((err, result) => {
186 if (err) return callback(err);
187 this.store(result, (err) => {
188 if (err) return callback(err);
189 callback(null, result);
190 });
191 });
192 });
193 }
194
195 /**
196 * Returns promise with the data.
197 * @template T
198 * @param {() => Promise<T> | T} computer function to compute the value if not cached
199 * @returns {Promise<T>} promise with the data
200 */
201 async providePromise(computer) {
202 const cacheEntry = await this.getPromise();
203 if (cacheEntry !== undefined) return cacheEntry;
204 const result = await computer();
205 await this.storePromise(result);
206 return result;
207 }
208}
209
210class CacheFacade {
211 /**
212 * Creates an instance of CacheFacade.
213 * @param {Cache} cache the root cache
214 * @param {string} name the child cache name
215 * @param {HashFunction=} hashFunction the hash function to use
216 */
217 constructor(cache, name, hashFunction) {
218 this._cache = cache;
219 this._name = name;
220 this._hashFunction = hashFunction;
221 }
222
223 /**
224 * Returns child cache.
225 * @param {string} name the child cache name#
226 * @returns {CacheFacade} child cache
227 */
228 getChildCache(name) {
229 return new CacheFacade(
230 this._cache,
231 `${this._name}|${name}`,
232 this._hashFunction
233 );
234 }
235
236 /**
237 * Returns item cache.
238 * @param {string} identifier the cache identifier
239 * @param {Etag | null} etag the etag
240 * @returns {ItemCacheFacade} item cache
241 */
242 getItemCache(identifier, etag) {
243 return new ItemCacheFacade(
244 this._cache,
245 `${this._name}|${identifier}`,
246 etag
247 );
248 }
249
250 /**
251 * Gets lazy hashed etag.
252 * @param {HashableObject} obj an hashable object
253 * @returns {Etag} an etag that is lazy hashed
254 */
255 getLazyHashedEtag(obj) {
256 return getLazyHashedEtag(obj, this._hashFunction);
257 }
258
259 /**
260 * Merges the provided values into a single result.
261 * @param {Etag} a an etag
262 * @param {Etag} b another etag
263 * @returns {Etag} an etag that represents both
264 */
265 mergeEtags(a, b) {
266 return mergeEtags(a, b);
267 }
268
269 /**
270 * Returns value.
271 * @template T
272 * @param {string} identifier the cache identifier
273 * @param {Etag | null} etag the etag
274 * @param {CallbackCache<T>} callback signals when the value is retrieved
275 * @returns {void}
276 */
277 get(identifier, etag, callback) {
278 this._cache.get(`${this._name}|${identifier}`, etag, callback);
279 }
280
281 /**
282 * Returns promise with the data.
283 * @template T
284 * @param {string} identifier the cache identifier
285 * @param {Etag | null} etag the etag
286 * @returns {Promise<T>} promise with the data
287 */
288 getPromise(identifier, etag) {
289 return new Promise((resolve, reject) => {
290 this._cache.get(`${this._name}|${identifier}`, etag, (err, data) => {
291 if (err) {
292 reject(err);
293 } else {
294 resolve(data);
295 }
296 });
297 });
298 }
299
300 /**
301 * Processes the provided identifier.
302 * @template T
303 * @param {string} identifier the cache identifier
304 * @param {Etag | null} etag the etag
305 * @param {T} data the value to store
306 * @param {CallbackCache<void>} callback signals when the value is stored
307 * @returns {void}
308 */
309 store(identifier, etag, data, callback) {
310 this._cache.store(`${this._name}|${identifier}`, etag, data, callback);
311 }
312
313 /**
314 * Stores the provided identifier.
315 * @template T
316 * @param {string} identifier the cache identifier
317 * @param {Etag | null} etag the etag
318 * @param {T} data the value to store
319 * @returns {Promise<void>} promise signals when the value is stored
320 */
321 storePromise(identifier, etag, data) {
322 return new Promise((resolve, reject) => {
323 this._cache.store(`${this._name}|${identifier}`, etag, data, (err) => {
324 if (err) {
325 reject(err);
326 } else {
327 resolve();
328 }
329 });
330 });
331 }
332
333 /**
334 * Processes the provided identifier.
335 * @template T
336 * @param {string} identifier the cache identifier
337 * @param {Etag | null} etag the etag
338 * @param {(callback: CallbackNormalErrorCache<T>) => void} computer function to compute the value if not cached
339 * @param {CallbackNormalErrorCache<T>} callback signals when the value is retrieved
340 * @returns {void}
341 */
342 provide(identifier, etag, computer, callback) {
343 this.get(identifier, etag, (err, cacheEntry) => {
344 if (err) return callback(err);
345 if (cacheEntry !== undefined) return cacheEntry;
346 computer((err, result) => {
347 if (err) return callback(err);
348 this.store(identifier, etag, result, (err) => {
349 if (err) return callback(err);
350 callback(null, result);
351 });
352 });
353 });
354 }
355
356 /**
357 * Returns promise with the data.
358 * @template T
359 * @param {string} identifier the cache identifier
360 * @param {Etag | null} etag the etag
361 * @param {() => Promise<T> | T} computer function to compute the value if not cached
362 * @returns {Promise<T>} promise with the data
363 */
364 async providePromise(identifier, etag, computer) {
365 const cacheEntry = await this.getPromise(identifier, etag);
366 if (cacheEntry !== undefined) return cacheEntry;
367 const result = await computer();
368 await this.storePromise(identifier, etag, result);
369 return result;
370 }
371}
372
373module.exports = CacheFacade;
374module.exports.ItemCacheFacade = ItemCacheFacade;
375module.exports.MultiItemCache = MultiItemCache;
Note: See TracBrowser for help on using the repository browser.