2018-09-27 13:22:19 +08:00
|
|
|
/*
|
|
|
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
|
|
Author Tobias Koppers @sokra
|
|
|
|
*/
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
const { AsyncParallelHook, AsyncSeriesBailHook, SyncHook } = require("tapable");
|
|
|
|
|
2018-12-18 05:20:58 +08:00
|
|
|
/** @typedef {import("./WebpackError")} WebpackError */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @template T
|
|
|
|
* @callback Callback
|
|
|
|
* @param {WebpackError=} err
|
|
|
|
* @param {T=} stats
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @callback GotHandler
|
|
|
|
* @param {any} result
|
|
|
|
* @param {Callback<void>} stats
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
2018-12-28 03:57:54 +08:00
|
|
|
|
2019-01-19 19:31:24 +08:00
|
|
|
const needCalls = (times, callback) => {
|
|
|
|
return err => {
|
|
|
|
if (--times === 0) {
|
|
|
|
return callback(err);
|
|
|
|
}
|
|
|
|
if (err && times > 0) {
|
|
|
|
times = NaN;
|
|
|
|
return callback(err);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2018-09-27 13:22:19 +08:00
|
|
|
class Cache {
|
|
|
|
constructor() {
|
|
|
|
this.hooks = {
|
2018-12-18 05:20:58 +08:00
|
|
|
/** @type {AsyncSeriesBailHook<[string, string, GotHandler[]], any>} */
|
2019-01-19 19:31:24 +08:00
|
|
|
get: new AsyncSeriesBailHook(["identifier", "etag", "gotHandlers"]),
|
2018-12-09 19:54:17 +08:00
|
|
|
/** @type {AsyncParallelHook<[string, string, any]>} */
|
2018-10-11 16:46:48 +08:00
|
|
|
store: new AsyncParallelHook(["identifier", "etag", "data"]),
|
2018-12-09 19:54:17 +08:00
|
|
|
/** @type {SyncHook<[]>} */
|
2018-09-27 13:22:19 +08:00
|
|
|
beginIdle: new SyncHook([]),
|
2018-12-09 19:54:17 +08:00
|
|
|
/** @type {AsyncParallelHook<[]>} */
|
2018-09-27 13:22:19 +08:00
|
|
|
endIdle: new AsyncParallelHook([]),
|
2018-12-09 19:54:17 +08:00
|
|
|
/** @type {AsyncParallelHook<[]>} */
|
2018-09-27 13:22:19 +08:00
|
|
|
shutdown: new AsyncParallelHook([])
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2018-12-18 05:20:58 +08:00
|
|
|
/**
|
|
|
|
* @template T
|
|
|
|
* @param {string} identifier the cache identifier
|
|
|
|
* @param {string} etag the etag
|
|
|
|
* @param {Callback<T>} callback signals when the value is retrieved
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
2018-10-11 16:46:48 +08:00
|
|
|
get(identifier, etag, callback) {
|
2019-01-19 19:31:24 +08:00
|
|
|
const gotHandlers = [];
|
|
|
|
this.hooks.get.callAsync(identifier, etag, gotHandlers, (err, result) => {
|
2018-12-28 03:57:54 +08:00
|
|
|
if (err) {
|
2018-12-31 02:39:11 +08:00
|
|
|
callback(/** @type {WebpackError} */ (err));
|
2018-12-28 03:57:54 +08:00
|
|
|
return;
|
|
|
|
}
|
2019-01-19 19:31:24 +08:00
|
|
|
if (gotHandlers.length > 1) {
|
|
|
|
const innerCallback = needCalls(gotHandlers.length, () =>
|
|
|
|
callback(null, result)
|
|
|
|
);
|
|
|
|
for (const gotHandler of gotHandlers) {
|
|
|
|
gotHandler(result, innerCallback);
|
2018-12-28 03:57:54 +08:00
|
|
|
}
|
2019-01-19 19:31:24 +08:00
|
|
|
} else if (gotHandlers.length === 1) {
|
|
|
|
gotHandlers[0](result, () => callback(null, result));
|
|
|
|
} else {
|
2018-12-28 03:57:54 +08:00
|
|
|
callback(null, result);
|
2019-01-19 19:31:24 +08:00
|
|
|
}
|
2018-12-28 03:57:54 +08:00
|
|
|
});
|
2018-09-27 13:22:19 +08:00
|
|
|
}
|
|
|
|
|
2018-12-18 05:20:58 +08:00
|
|
|
/**
|
|
|
|
* @template T
|
|
|
|
* @param {string} identifier the cache identifier
|
|
|
|
* @param {string} etag the etag
|
|
|
|
* @param {T} data the value to store
|
|
|
|
* @param {Callback<void>} callback signals when the value is stored
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
2018-10-09 20:30:59 +08:00
|
|
|
store(identifier, etag, data, callback) {
|
|
|
|
this.hooks.store.callAsync(identifier, etag, data, callback);
|
2018-09-27 13:22:19 +08:00
|
|
|
}
|
|
|
|
|
2018-12-18 05:20:58 +08:00
|
|
|
/**
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
2018-09-27 13:22:19 +08:00
|
|
|
beginIdle() {
|
|
|
|
this.hooks.beginIdle.call();
|
|
|
|
}
|
|
|
|
|
2018-12-18 05:20:58 +08:00
|
|
|
/**
|
|
|
|
* @param {Callback<void>} callback signals when the call finishes
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
2018-09-27 13:22:19 +08:00
|
|
|
endIdle(callback) {
|
|
|
|
this.hooks.endIdle.callAsync(callback);
|
|
|
|
}
|
|
|
|
|
2018-12-18 05:20:58 +08:00
|
|
|
/**
|
|
|
|
* @param {Callback<void>} callback signals when the call finishes
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
2018-09-27 13:22:19 +08:00
|
|
|
shutdown(callback) {
|
|
|
|
this.hooks.shutdown.callAsync(callback);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = Cache;
|