add provide and mergeEtags to CacheFacade
This commit is contained in:
parent
2748077a4d
commit
48ff7043f1
|
@ -177,6 +177,7 @@
|
|||
"eqeqeq",
|
||||
"boolish",
|
||||
"analysing",
|
||||
"etags",
|
||||
|
||||
"webassemblyjs",
|
||||
"fsevents",
|
||||
|
|
|
@ -7,12 +7,29 @@
|
|||
|
||||
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 */
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @callback CallbackCache
|
||||
* @param {WebpackError=} err
|
||||
* @param {T=} result
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @callback CallbackNormalErrorCache
|
||||
* @param {Error=} err
|
||||
* @param {T=} result
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
class MultiItemCache {
|
||||
/**
|
||||
* @param {ItemCacheFacade[]} items item caches
|
||||
|
@ -78,14 +95,6 @@ class MultiItemCache {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @callback CallbackCache
|
||||
* @param {WebpackError=} err
|
||||
* @param {T=} result
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
class ItemCacheFacade {
|
||||
/**
|
||||
* @param {Cache} cache the root cache
|
||||
|
@ -149,6 +158,39 @@ class ItemCacheFacade {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 {
|
||||
|
@ -190,6 +232,15 @@ class CacheFacade {
|
|||
return getLazyHashedEtag(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
@ -249,6 +300,43 @@ class CacheFacade {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/** @typedef {import("../Cache").Etag} Etag */
|
||||
|
||||
class MergedEtag {
|
||||
/**
|
||||
* @param {Etag} a first
|
||||
* @param {Etag} b second
|
||||
*/
|
||||
constructor(a, b) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
toString() {
|
||||
return `${this.a.toString()}|${this.b.toString()}`;
|
||||
}
|
||||
}
|
||||
|
||||
const dualObjectMap = new WeakMap();
|
||||
const objectStringMap = new WeakMap();
|
||||
|
||||
/**
|
||||
* @param {Etag} a first
|
||||
* @param {Etag} b second
|
||||
* @returns {Etag} result
|
||||
*/
|
||||
const mergeEtags = (a, b) => {
|
||||
if (typeof a === "string") {
|
||||
if (typeof b === "string") {
|
||||
return `${a}|${b}`;
|
||||
} else {
|
||||
const temp = b;
|
||||
b = a;
|
||||
a = temp;
|
||||
}
|
||||
} else {
|
||||
if (typeof b !== "string") {
|
||||
// both a and b are objects
|
||||
let map = dualObjectMap.get(a);
|
||||
if (map === undefined) {
|
||||
dualObjectMap.set(a, (map = new WeakMap()));
|
||||
}
|
||||
const mergedEtag = map.get(b);
|
||||
if (mergedEtag === undefined) {
|
||||
const newMergedEtag = new MergedEtag(a, b);
|
||||
map.set(b, newMergedEtag);
|
||||
return newMergedEtag;
|
||||
} else {
|
||||
return mergedEtag;
|
||||
}
|
||||
}
|
||||
}
|
||||
// a is object, b is string
|
||||
let map = objectStringMap.get(a);
|
||||
if (map === undefined) {
|
||||
objectStringMap.set(a, (map = new Map()));
|
||||
}
|
||||
const mergedEtag = map.get(b);
|
||||
if (mergedEtag === undefined) {
|
||||
const newMergedEtag = new MergedEtag(a, b);
|
||||
map.set(b, newMergedEtag);
|
||||
return newMergedEtag;
|
||||
} else {
|
||||
return mergedEtag;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = mergeEtags;
|
|
@ -505,6 +505,7 @@ declare abstract class CacheFacade {
|
|||
getChildCache(name: string): CacheFacade;
|
||||
getItemCache(identifier: string, etag: Etag): ItemCacheFacade;
|
||||
getLazyHashedEtag(obj: HashableObject): Etag;
|
||||
mergeEtags(a: Etag, b: Etag): Etag;
|
||||
get<T>(identifier: string, etag: Etag, callback: CallbackCache<T>): void;
|
||||
getPromise<T>(identifier: string, etag: Etag): Promise<T>;
|
||||
store<T>(
|
||||
|
@ -514,6 +515,17 @@ declare abstract class CacheFacade {
|
|||
callback: CallbackCache<void>
|
||||
): void;
|
||||
storePromise<T>(identifier: string, etag: Etag, data: T): Promise<void>;
|
||||
provide<T>(
|
||||
identifier: string,
|
||||
etag: Etag,
|
||||
computer: (arg0: CallbackNormalErrorCache<T>) => void,
|
||||
callback: CallbackNormalErrorCache<T>
|
||||
): void;
|
||||
providePromise<T>(
|
||||
identifier: string,
|
||||
etag: Etag,
|
||||
computer: () => T | Promise<T>
|
||||
): Promise<T>;
|
||||
}
|
||||
declare interface CacheGroupSource {
|
||||
key?: string;
|
||||
|
@ -548,6 +560,9 @@ declare interface CallbackCache<T> {
|
|||
declare interface CallbackFunction<T> {
|
||||
(err?: Error, result?: T): any;
|
||||
}
|
||||
declare interface CallbackNormalErrorCache<T> {
|
||||
(err?: Error, result?: T): void;
|
||||
}
|
||||
declare interface CallbackWebpack<T> {
|
||||
(err?: Error, stats?: T): void;
|
||||
}
|
||||
|
@ -3293,6 +3308,11 @@ declare abstract class ItemCacheFacade {
|
|||
getPromise<T>(): Promise<T>;
|
||||
store<T>(data: T, callback: CallbackCache<void>): void;
|
||||
storePromise<T>(data: T): Promise<void>;
|
||||
provide<T>(
|
||||
computer: (arg0: CallbackNormalErrorCache<T>) => void,
|
||||
callback: CallbackNormalErrorCache<T>
|
||||
): void;
|
||||
providePromise<T>(computer: () => T | Promise<T>): Promise<T>;
|
||||
}
|
||||
declare class JavascriptModulesPlugin {
|
||||
constructor(options?: {});
|
||||
|
|
Loading…
Reference in New Issue