Permalink
January 18, 2023 20:50
Newer
100644
99 lines (92 sloc)
2.64 KB
Ignoring revisions in .git-blame-ignore-revs.
1
/*
2
MIT License http://www.opensource.org/licenses/mit-license.php
3
Author Tobias Koppers @sokra
4
*/
5
6
"use strict";
7
8
/** @typedef {import("./Resolver")} Resolver */
9
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
10
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
11
/** @typedef {{[k: string]: any}} Cache */
12
13
function getCacheId(type, request, withContext) {
14
return JSON.stringify({
15
type,
16
context: withContext ? request.context : "",
17
path: request.path,
18
query: request.query,
19
fragment: request.fragment,
20
request: request.request
21
});
22
}
23
24
module.exports = class UnsafeCachePlugin {
25
/**
26
* @param {string | ResolveStepHook} source source
27
* @param {function(ResolveRequest): boolean} filterPredicate filterPredicate
28
* @param {Cache} cache cache
29
* @param {boolean} withContext withContext
30
* @param {string | ResolveStepHook} target target
31
*/
32
constructor(source, filterPredicate, cache, withContext, target) {
33
this.source = source;
34
this.filterPredicate = filterPredicate;
35
this.withContext = withContext;
36
this.cache = cache;
37
this.target = target;
38
}
39
40
/**
41
* @param {Resolver} resolver the resolver
42
* @returns {void}
43
*/
44
apply(resolver) {
45
const target = resolver.ensureHook(this.target);
46
resolver
47
.getHook(this.source)
48
.tapAsync("UnsafeCachePlugin", (request, resolveContext, callback) => {
49
if (!this.filterPredicate(request)) return callback();
50
const isYield = typeof resolveContext.yield === "function";
51
const cacheId = getCacheId(
52
isYield ? "yield" : "default",
53
request,
54
this.withContext
55
);
56
const cacheEntry = this.cache[cacheId];
57
if (cacheEntry) {
58
if (isYield) {
59
const yield_ = /** @type {Function} */ (resolveContext.yield);
60
if (Array.isArray(cacheEntry)) {
61
for (const result of cacheEntry) yield_(result);
62
} else {
63
yield_(cacheEntry);
64
}
65
return callback(null, null);
66
}
67
return callback(null, cacheEntry);
68
}
69
70
let yieldFn;
71
let yield_;
72
const yieldResult = [];
73
if (isYield) {
74
yieldFn = resolveContext.yield;
75
yield_ = result => {
76
yieldResult.push(result);
77
};
78
}
79
80
resolver.doResolve(
81
target,
82
request,
83
null,
84
yield_ ? { ...resolveContext, yield: yield_ } : resolveContext,
85
(err, result) => {
86
if (err) return callback(err);
87
if (isYield) {
88
if (result) yieldResult.push(result);
89
for (const result of yieldResult) yieldFn(result);
90
this.cache[cacheId] = yieldResult;
91
return callback(null, null);
92
}
93
if (result) return callback(null, (this.cache[cacheId] = result));
94
callback();
95
}
96
);
97
});
98
}
99
};