source: frontend/node_modules/enhanced-resolve/lib/UnsafeCachePlugin.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 5.7 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const { isRelativeRequest } = require("./util/path");
9
10/** @typedef {import("./Resolver")} Resolver */
11/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
12/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
13/** @typedef {import("./Resolver").ResolveContextYield} ResolveContextYield */
14/** @typedef {{ [k: string]: undefined | ResolveRequest | ResolveRequest[] }} Cache */
15
16/**
17 * @param {string} relativePath relative path from package root
18 * @param {string} request relative request
19 * @param {Resolver} resolver resolver instance
20 * @returns {string} normalized request with a preserved leading dot
21 */
22function joinRelativePreservingLeadingDot(relativePath, request, resolver) {
23 const normalized = resolver.join(relativePath, request);
24 return isRelativeRequest(normalized) ? normalized : `./${normalized}`;
25}
26
27/**
28 * @param {ResolveRequest} request request
29 * @returns {string | false | undefined} normalized path
30 */
31function getCachePath(request) {
32 if (request.descriptionFileRoot && !request.module) {
33 return request.descriptionFileRoot;
34 }
35 return request.path;
36}
37
38/**
39 * @param {ResolveRequest} request request
40 * @param {Resolver} resolver resolver instance
41 * @returns {string | undefined} normalized request string
42 */
43function getCacheRequest(request, resolver) {
44 const requestString = request.request;
45 if (
46 !requestString ||
47 !request.relativePath ||
48 !isRelativeRequest(requestString)
49 ) {
50 return requestString;
51 }
52 return joinRelativePreservingLeadingDot(
53 request.relativePath,
54 requestString,
55 resolver,
56 );
57}
58
59// Cache-key separator: `\0` is safe because paths, requests, queries and
60// fragments produced by `parseIdentifier` never contain a raw NUL (the
61// \0-escape in identifier.js is decoded back to the original char), and the
62// context, when included, is passed through `JSON.stringify`, which escapes
63// any NUL to \u0000.
64// const SEP = "\0";
65
66/**
67 * Build the cache id for a request. Called on every `described-resolve`
68 * invocation when `unsafeCache` is on, so it's a hot path.
69 *
70 * Equivalent in meaning to the previous `JSON.stringify({ ... })` form, but
71 * ~3–5× faster since we avoid the object allocation and JSON serializer for
72 * the fields that are already plain strings.
73 * @param {string} type type of cache
74 * @param {ResolveRequest} request request
75 * @param {boolean} withContext cache with context?
76 * @param {Resolver} resolver resolver instance
77 * @returns {string} cache id
78 */
79function getCacheId(type, request, withContext, resolver) {
80 // TODO use it in the next major release, it is faster
81 // const contextPart = withContext ? JSON.stringify(request.context) : "";
82 // const path = getCachePath(request);
83 // const cacheRequest = getCacheRequest(request, resolver);
84 // return (
85 // type +
86 // SEP +
87 // contextPart +
88 // SEP +
89 // (path || "") +
90 // SEP +
91 // (request.query || "") +
92 // SEP +
93 // (request.fragment || "") +
94 // SEP +
95 // (cacheRequest || "")
96 // );
97
98 return JSON.stringify({
99 type,
100 context: withContext ? request.context : "",
101 path: getCachePath(request),
102 query: request.query,
103 fragment: request.fragment,
104 request: getCacheRequest(request, resolver),
105 });
106}
107
108module.exports = class UnsafeCachePlugin {
109 /**
110 * @param {string | ResolveStepHook} source source
111 * @param {(request: ResolveRequest) => boolean} filterPredicate filterPredicate
112 * @param {Cache} cache cache
113 * @param {boolean} withContext withContext
114 * @param {string | ResolveStepHook} target target
115 */
116 constructor(source, filterPredicate, cache, withContext, target) {
117 this.source = source;
118 this.filterPredicate = filterPredicate;
119 this.withContext = withContext;
120 this.cache = cache;
121 this.target = target;
122 }
123
124 /**
125 * @param {Resolver} resolver the resolver
126 * @returns {void}
127 */
128 apply(resolver) {
129 const target = resolver.ensureHook(this.target);
130 resolver
131 .getHook(this.source)
132 .tapAsync("UnsafeCachePlugin", (request, resolveContext, callback) => {
133 if (!this.filterPredicate(request)) {
134 return resolver.doResolve(
135 target,
136 request,
137 null,
138 resolveContext,
139 callback,
140 );
141 }
142 const isYield = typeof resolveContext.yield === "function";
143 const cacheId = getCacheId(
144 isYield ? "yield" : "default",
145 request,
146 this.withContext,
147 resolver,
148 );
149 const cacheEntry = this.cache[cacheId];
150 if (cacheEntry) {
151 if (isYield) {
152 const yield_ =
153 /** @type {ResolveContextYield} */
154 (resolveContext.yield);
155 if (Array.isArray(cacheEntry)) {
156 for (const result of cacheEntry) yield_(result);
157 } else {
158 yield_(cacheEntry);
159 }
160 return callback(null, null);
161 }
162 return callback(null, /** @type {ResolveRequest} */ (cacheEntry));
163 }
164
165 /** @type {ResolveContextYield | undefined} */
166 let yieldFn;
167 /** @type {ResolveContextYield | undefined} */
168 let yield_;
169 /** @type {ResolveRequest[]} */
170 const yieldResult = [];
171 if (isYield) {
172 yieldFn = resolveContext.yield;
173 yield_ = (result) => {
174 yieldResult.push(result);
175 };
176 }
177
178 resolver.doResolve(
179 target,
180 request,
181 null,
182 yield_ ? { ...resolveContext, yield: yield_ } : resolveContext,
183 (err, result) => {
184 if (err) return callback(err);
185 if (isYield) {
186 if (result) yieldResult.push(result);
187 for (const result of yieldResult) {
188 /** @type {ResolveContextYield} */
189 (yieldFn)(result);
190 }
191 this.cache[cacheId] = yieldResult;
192 return callback(null, null);
193 }
194 if (result) return callback(null, (this.cache[cacheId] = result));
195 callback();
196 },
197 );
198 });
199 }
200};
Note: See TracBrowser for help on using the repository browser.