summaryrefslogtreecommitdiff
path: root/node_modules/webpack/lib/CacheFacade.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/webpack/lib/CacheFacade.js')
-rw-r--r--node_modules/webpack/lib/CacheFacade.js349
1 files changed, 349 insertions, 0 deletions
diff --git a/node_modules/webpack/lib/CacheFacade.js b/node_modules/webpack/lib/CacheFacade.js
new file mode 100644
index 00000000..eece9631
--- /dev/null
+++ b/node_modules/webpack/lib/CacheFacade.js
@@ -0,0 +1,349 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { forEachBail } = require("enhanced-resolve");
+const asyncLib = require("neo-async");
+const getLazyHashedEtag = require("./cache/getLazyHashedEtag");
+const mergeEtags = require("./cache/mergeEtags");
+
+/** @typedef {import("./Cache")} Cache */
+/** @typedef {import("./Cache").Etag} Etag */
+/** @typedef {import("./WebpackError")} WebpackError */
+/** @typedef {import("./cache/getLazyHashedEtag").HashableObject} HashableObject */
+/** @typedef {typeof import("./util/Hash")} HashConstructor */
+
+/**
+ * @template T
+ * @callback CallbackCache
+ * @param {(Error | null)=} err
+ * @param {(T | null)=} result
+ * @returns {void}
+ */
+
+/**
+ * @template T
+ * @callback CallbackNormalErrorCache
+ * @param {(Error | null)=} err
+ * @param {T=} result
+ * @returns {void}
+ */
+
+class MultiItemCache {
+ /**
+ * @param {ItemCacheFacade[]} items item caches
+ */
+ constructor(items) {
+ this._items = items;
+ // eslint-disable-next-line no-constructor-return
+ if (items.length === 1) return /** @type {any} */ (items[0]);
+ }
+
+ /**
+ * @template T
+ * @param {CallbackCache<T>} callback signals when the value is retrieved
+ * @returns {void}
+ */
+ get(callback) {
+ forEachBail(this._items, (item, callback) => item.get(callback), callback);
+ }
+
+ /**
+ * @template T
+ * @returns {Promise<T>} promise with the data
+ */
+ getPromise() {
+ /**
+ * @param {number} i index
+ * @returns {Promise<T>} promise with the data
+ */
+ const next = i =>
+ this._items[i].getPromise().then(result => {
+ if (result !== undefined) return result;
+ if (++i < this._items.length) return next(i);
+ });
+ return next(0);
+ }
+
+ /**
+ * @template T
+ * @param {T} data the value to store
+ * @param {CallbackCache<void>} callback signals when the value is stored
+ * @returns {void}
+ */
+ store(data, callback) {
+ asyncLib.each(
+ this._items,
+ (item, callback) => item.store(data, callback),
+ callback
+ );
+ }
+
+ /**
+ * @template T
+ * @param {T} data the value to store
+ * @returns {Promise<void>} promise signals when the value is stored
+ */
+ storePromise(data) {
+ return Promise.all(this._items.map(item => item.storePromise(data))).then(
+ () => {}
+ );
+ }
+}
+
+class ItemCacheFacade {
+ /**
+ * @param {Cache} cache the root cache
+ * @param {string} name the child cache item name
+ * @param {Etag | null} etag the etag
+ */
+ constructor(cache, name, etag) {
+ this._cache = cache;
+ this._name = name;
+ this._etag = etag;
+ }
+
+ /**
+ * @template T
+ * @param {CallbackCache<T>} callback signals when the value is retrieved
+ * @returns {void}
+ */
+ get(callback) {
+ this._cache.get(this._name, this._etag, callback);
+ }
+
+ /**
+ * @template T
+ * @returns {Promise<T>} promise with the data
+ */
+ getPromise() {
+ return new Promise((resolve, reject) => {
+ this._cache.get(this._name, this._etag, (err, data) => {
+ if (err) {
+ reject(err);
+ } else {
+ resolve(data);
+ }
+ });
+ });
+ }
+
+ /**
+ * @template T
+ * @param {T} data the value to store
+ * @param {CallbackCache<void>} callback signals when the value is stored
+ * @returns {void}
+ */
+ store(data, callback) {
+ this._cache.store(this._name, this._etag, data, callback);
+ }
+
+ /**
+ * @template T
+ * @param {T} data the value to store
+ * @returns {Promise<void>} promise signals when the value is stored
+ */
+ storePromise(data) {
+ return new Promise((resolve, reject) => {
+ this._cache.store(this._name, this._etag, data, err => {
+ if (err) {
+ reject(err);
+ } else {
+ resolve();
+ }
+ });
+ });
+ }
+
+ /**
+ * @template T
+ * @param {function(CallbackNormalErrorCache<T>): void} computer function to compute the value if not cached
+ * @param {CallbackNormalErrorCache<T>} callback signals when the value is retrieved
+ * @returns {void}
+ */
+ provide(computer, callback) {
+ this.get((err, cacheEntry) => {
+ if (err) return callback(err);
+ if (cacheEntry !== undefined) return cacheEntry;
+ computer((err, result) => {
+ if (err) return callback(err);
+ this.store(result, err => {
+ if (err) return callback(err);
+ callback(null, result);
+ });
+ });
+ });
+ }
+
+ /**
+ * @template T
+ * @param {function(): Promise<T> | T} computer function to compute the value if not cached
+ * @returns {Promise<T>} promise with the data
+ */
+ async providePromise(computer) {
+ const cacheEntry = await this.getPromise();
+ if (cacheEntry !== undefined) return cacheEntry;
+ const result = await computer();
+ await this.storePromise(result);
+ return result;
+ }
+}
+
+class CacheFacade {
+ /**
+ * @param {Cache} cache the root cache
+ * @param {string} name the child cache name
+ * @param {(string | HashConstructor)=} hashFunction the hash function to use
+ */
+ constructor(cache, name, hashFunction) {
+ this._cache = cache;
+ this._name = name;
+ this._hashFunction = hashFunction;
+ }
+
+ /**
+ * @param {string} name the child cache name#
+ * @returns {CacheFacade} child cache
+ */
+ getChildCache(name) {
+ return new CacheFacade(
+ this._cache,
+ `${this._name}|${name}`,
+ this._hashFunction
+ );
+ }
+
+ /**
+ * @param {string} identifier the cache identifier
+ * @param {Etag | null} etag the etag
+ * @returns {ItemCacheFacade} item cache
+ */
+ getItemCache(identifier, etag) {
+ return new ItemCacheFacade(
+ this._cache,
+ `${this._name}|${identifier}`,
+ etag
+ );
+ }
+
+ /**
+ * @param {HashableObject} obj an hashable object
+ * @returns {Etag} an etag that is lazy hashed
+ */
+ getLazyHashedEtag(obj) {
+ return getLazyHashedEtag(obj, this._hashFunction);
+ }
+
+ /**
+ * @param {Etag} a an etag
+ * @param {Etag} b another etag
+ * @returns {Etag} an etag that represents both
+ */
+ mergeEtags(a, b) {
+ return mergeEtags(a, b);
+ }
+
+ /**
+ * @template T
+ * @param {string} identifier the cache identifier
+ * @param {Etag | null} etag the etag
+ * @param {CallbackCache<T>} callback signals when the value is retrieved
+ * @returns {void}
+ */
+ get(identifier, etag, callback) {
+ this._cache.get(`${this._name}|${identifier}`, etag, callback);
+ }
+
+ /**
+ * @template T
+ * @param {string} identifier the cache identifier
+ * @param {Etag | null} etag the etag
+ * @returns {Promise<T>} promise with the data
+ */
+ getPromise(identifier, etag) {
+ return new Promise((resolve, reject) => {
+ this._cache.get(`${this._name}|${identifier}`, etag, (err, data) => {
+ if (err) {
+ reject(err);
+ } else {
+ resolve(data);
+ }
+ });
+ });
+ }
+
+ /**
+ * @template T
+ * @param {string} identifier the cache identifier
+ * @param {Etag | null} etag the etag
+ * @param {T} data the value to store
+ * @param {CallbackCache<void>} callback signals when the value is stored
+ * @returns {void}
+ */
+ store(identifier, etag, data, callback) {
+ this._cache.store(`${this._name}|${identifier}`, etag, data, callback);
+ }
+
+ /**
+ * @template T
+ * @param {string} identifier the cache identifier
+ * @param {Etag | null} etag the etag
+ * @param {T} data the value to store
+ * @returns {Promise<void>} promise signals when the value is stored
+ */
+ storePromise(identifier, etag, data) {
+ return new Promise((resolve, reject) => {
+ this._cache.store(`${this._name}|${identifier}`, etag, data, err => {
+ if (err) {
+ reject(err);
+ } else {
+ resolve();
+ }
+ });
+ });
+ }
+
+ /**
+ * @template T
+ * @param {string} identifier the cache identifier
+ * @param {Etag | null} etag the etag
+ * @param {function(CallbackNormalErrorCache<T>): void} computer function to compute the value if not cached
+ * @param {CallbackNormalErrorCache<T>} callback signals when the value is retrieved
+ * @returns {void}
+ */
+ provide(identifier, etag, computer, callback) {
+ this.get(identifier, etag, (err, cacheEntry) => {
+ if (err) return callback(err);
+ if (cacheEntry !== undefined) return cacheEntry;
+ computer((err, result) => {
+ if (err) return callback(err);
+ this.store(identifier, etag, result, err => {
+ if (err) return callback(err);
+ callback(null, result);
+ });
+ });
+ });
+ }
+
+ /**
+ * @template T
+ * @param {string} identifier the cache identifier
+ * @param {Etag | null} etag the etag
+ * @param {function(): Promise<T> | T} computer function to compute the value if not cached
+ * @returns {Promise<T>} promise with the data
+ */
+ async providePromise(identifier, etag, computer) {
+ const cacheEntry = await this.getPromise(identifier, etag);
+ if (cacheEntry !== undefined) return cacheEntry;
+ const result = await computer();
+ await this.storePromise(identifier, etag, result);
+ return result;
+ }
+}
+
+module.exports = CacheFacade;
+module.exports.ItemCacheFacade = ItemCacheFacade;
+module.exports.MultiItemCache = MultiItemCache;