source: imaps-frontend/node_modules/webpack/lib/CacheFacade.js@ 79a0317

main
Last change on this file since 79a0317 was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 3 days ago

F4 Finalna Verzija

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