WXL
4 天以前 3bd962a6d7f61239c020e2dbbeb7341e5b842dd1
node_modules/webpack/lib/FileSystemInfo.js
@@ -25,13 +25,16 @@
/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
/** @typedef {import("../declarations/WebpackOptions").HashFunction} HashFunction */
/** @typedef {import("./util/fs").JsonObject} JsonObject */
/** @typedef {import("./util/fs").IStats} IStats */
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
/**
 * Defines the processor callback type used by this module.
 * @template T
 * @typedef {import("./util/AsyncQueue").Callback<T>} ProcessorCallback
 */
/**
 * Defines the processor type used by this module.
 * @template T, R
 * @typedef {import("./util/AsyncQueue").Processor<T, R>} Processor
 */
@@ -43,6 +46,7 @@
let FS_ACCURACY = 2000;
/** @type {Set<string>} */
const EMPTY_SET = new Set();
const RBDT_RESOLVE_INITIAL = 0;
@@ -60,13 +64,18 @@
const INVALID = Symbol("invalid");
// eslint-disable-next-line jsdoc/ts-no-empty-object-type
/** @typedef {{  }} ExistenceOnlyTimeEntry */
/**
 * Defines the file system info entry type used by this module.
 * @typedef {object} FileSystemInfoEntry
 * @property {number} safeTime
 * @property {number=} timestamp
 */
/**
 * Defines the resolved context file system info entry type used by this module.
 * @typedef {object} ResolvedContextFileSystemInfoEntry
 * @property {number} safeTime
 * @property {string=} timestampHash
@@ -75,6 +84,7 @@
/** @typedef {Set<string>} Symlinks */
/**
 * Defines the context file system info entry type used by this module.
 * @typedef {object} ContextFileSystemInfoEntry
 * @property {number} safeTime
 * @property {string=} timestampHash
@@ -83,6 +93,7 @@
 */
/**
 * Defines the timestamp and hash type used by this module.
 * @typedef {object} TimestampAndHash
 * @property {number} safeTime
 * @property {number=} timestamp
@@ -90,6 +101,7 @@
 */
/**
 * Defines the resolved context timestamp and hash type used by this module.
 * @typedef {object} ResolvedContextTimestampAndHash
 * @property {number} safeTime
 * @property {string=} timestampHash
@@ -97,6 +109,7 @@
 */
/**
 * Defines the context timestamp and hash type used by this module.
 * @typedef {object} ContextTimestampAndHash
 * @property {number} safeTime
 * @property {string=} timestampHash
@@ -106,6 +119,7 @@
 */
/**
 * Defines the context hash type used by this module.
 * @typedef {object} ContextHash
 * @property {string} hash
 * @property {string=} resolved
@@ -115,6 +129,7 @@
/** @typedef {Set<string>} SnapshotContent */
/**
 * Defines the snapshot optimization entry type used by this module.
 * @typedef {object} SnapshotOptimizationEntry
 * @property {Snapshot} snapshot
 * @property {number} shared
@@ -129,6 +144,7 @@
/** @typedef {Set<string>} Missing */
/**
 * Defines the resolve dependencies type used by this module.
 * @typedef {object} ResolveDependencies
 * @property {Files} files list of files
 * @property {Directories} directories list of directories
@@ -136,6 +152,7 @@
 */
/**
 * Defines the resolve build dependencies result type used by this module.
 * @typedef {object} ResolveBuildDependenciesResult
 * @property {Files} files list of files
 * @property {Directories} directories list of directories
@@ -145,6 +162,7 @@
 */
/**
 * Defines the snapshot options type used by this module.
 * @typedef {object} SnapshotOptions
 * @property {boolean=} hash should use hash to snapshot
 * @property {boolean=} timestamp should use timestamp to snapshot
@@ -158,6 +176,7 @@
class SnapshotIterator {
   /**
    * Creates an instance of SnapshotIterator.
    * @param {() => IteratorResult<string>} next next
    */
   constructor(next) {
@@ -166,15 +185,18 @@
}
/**
 * Defines the get maps function type used by this module.
 * @template T
 * @typedef {(snapshot: Snapshot) => T[]} GetMapsFunction
 */
/**
 * Represents SnapshotIterable.
 * @template T
 */
class SnapshotIterable {
   /**
    * Creates an instance of SnapshotIterable.
    * @param {Snapshot} snapshot snapshot
    * @param {GetMapsFunction<T>} getMaps get maps function
    */
@@ -315,6 +337,7 @@
   }
   /**
    * Updates start time using the provided value.
    * @param {number} value start value
    */
   setStartTime(value) {
@@ -323,6 +346,7 @@
   }
   /**
    * Sets merged start time.
    * @param {number | undefined} value value
    * @param {Snapshot} snapshot snapshot
    */
@@ -352,6 +376,7 @@
   }
   /**
    * Sets file timestamps.
    * @param {FileTimestamps} value file timestamps
    */
   setFileTimestamps(value) {
@@ -364,6 +389,7 @@
   }
   /**
    * Updates file hashes using the provided value.
    * @param {FileHashes} value file hashes
    */
   setFileHashes(value) {
@@ -376,6 +402,7 @@
   }
   /**
    * Updates file tshs using the provided value.
    * @param {FileTshs} value file tshs
    */
   setFileTshs(value) {
@@ -388,6 +415,7 @@
   }
   /**
    * Sets context timestamps.
    * @param {ContextTimestamps} value context timestamps
    */
   setContextTimestamps(value) {
@@ -400,6 +428,7 @@
   }
   /**
    * Sets context hashes.
    * @param {ContextHashes} value context hashes
    */
   setContextHashes(value) {
@@ -412,6 +441,7 @@
   }
   /**
    * Updates context tshs using the provided value.
    * @param {ContextTshs} value context tshs
    */
   setContextTshs(value) {
@@ -424,6 +454,7 @@
   }
   /**
    * Sets missing existence.
    * @param {MissingExistence} value context tshs
    */
   setMissingExistence(value) {
@@ -436,6 +467,7 @@
   }
   /**
    * Sets managed item info.
    * @param {ManagedItemInfo} value managed item info
    */
   setManagedItemInfo(value) {
@@ -448,6 +480,7 @@
   }
   /**
    * Sets managed files.
    * @param {ManagedFiles} value managed files
    */
   setManagedFiles(value) {
@@ -460,6 +493,7 @@
   }
   /**
    * Sets managed contexts.
    * @param {ManagedContexts} value managed contexts
    */
   setManagedContexts(value) {
@@ -472,6 +506,7 @@
   }
   /**
    * Sets managed missing.
    * @param {ManagedMissing} value managed missing
    */
   setManagedMissing(value) {
@@ -484,6 +519,7 @@
   }
   /**
    * Updates children using the provided value.
    * @param {Children} value children
    */
   setChildren(value) {
@@ -492,6 +528,7 @@
   }
   /**
    * Adds the provided child to the snapshot.
    * @param {Snapshot} child children
    */
   addChild(child) {
@@ -503,6 +540,7 @@
   }
   /**
    * Serializes this instance into the provided serializer context.
    * @param {ObjectSerializerContext} context context
    */
   serialize({ write }) {
@@ -523,6 +561,7 @@
   }
   /**
    * Restores this instance from the provided deserializer context.
    * @param {ObjectDeserializerContext} context context
    */
   deserialize({ read }) {
@@ -543,6 +582,7 @@
   }
   /**
    * Creates an iterable from the provided get map.
    * @template T
    * @param {GetMapsFunction<T>} getMaps first
    * @returns {SnapshotIterable<T>} iterable
@@ -552,6 +592,7 @@
   }
   /**
    * Gets file iterable.
    * @returns {Iterable<string>} iterable
    */
   getFileIterable() {
@@ -567,6 +608,7 @@
   }
   /**
    * Gets context iterable.
    * @returns {Iterable<string>} iterable
    */
   getContextIterable() {
@@ -582,6 +624,7 @@
   }
   /**
    * Gets missing iterable.
    * @returns {Iterable<string>} iterable
    */
   getMissingIterable() {
@@ -600,16 +643,19 @@
const MIN_COMMON_SNAPSHOT_SIZE = 3;
/**
 * Defines the snapshot optimization value type used by this module.
 * @template U, T
 * @typedef {U extends true ? Set<string> : Map<string, T>} SnapshotOptimizationValue
 */
/**
 * Represents SnapshotOptimization.
 * @template T
 * @template {boolean} [U=false]
 */
class SnapshotOptimization {
   /**
    * Creates an instance of SnapshotOptimization.
    * @param {(snapshot: Snapshot) => boolean} has has value
    * @param {(snapshot: Snapshot) => SnapshotOptimizationValue<U, T> | undefined} get get value
    * @param {(snapshot: Snapshot, value: SnapshotOptimizationValue<U, T>) => void} set set value
@@ -658,6 +704,7 @@
   }
   /**
    * Processes the provided new snapshot.
    * @param {Snapshot} newSnapshot snapshot
    * @param {Set<string>} capturedFiles files to snapshot/share
    * @returns {void}
@@ -667,6 +714,7 @@
         return;
      }
      /**
       * Increase shared and store optimization entry.
       * @param {SnapshotOptimizationEntry} entry optimization entry
       * @returns {void}
       */
@@ -680,6 +728,7 @@
         storeOptimizationEntry(entry);
      };
      /**
       * Stores optimization entry.
       * @param {SnapshotOptimizationEntry} entry optimization entry
       * @returns {void}
       */
@@ -767,6 +816,7 @@
                  continue;
               }
               // Extract common timestamps from both snapshots
               /** @type {Set<string> | Map<string, T>} */
               let commonMap;
               if (this._isSet) {
                  commonMap = new Set();
@@ -818,6 +868,7 @@
               // Incomplete snapshot, that can't be used
               continue;
            }
            /** @type {Set<string> | Map<string, T>} */
            let commonMap;
            if (this._isSet) {
               commonMap = new Set();
@@ -879,6 +930,7 @@
}
/**
 * Returns result.
 * @param {string} str input
 * @returns {string} result
 */
@@ -891,6 +943,7 @@
/* istanbul ignore next */
/**
 * Processes the provided mtime.
 * @param {number} mtime mtime
 */
const applyMtime = (mtime) => {
@@ -901,6 +954,7 @@
};
/**
 * Merges the provided values into a single result.
 * @template T
 * @template K
 * @param {Map<T, K> | undefined} a source map
@@ -919,6 +973,7 @@
};
/**
 * Merges the provided values into a single result.
 * @template T
 * @param {Set<T> | undefined} a source map
 * @param {Set<T> | undefined} b joining map
@@ -1020,6 +1075,7 @@
};
/**
 * Gets resolved timestamp.
 * @template {ContextFileSystemInfoEntry | ContextTimestampAndHash} T
 * @param {T | null} entry entry
 * @returns {T["resolved"] | null | undefined} the resolved entry
@@ -1031,6 +1087,7 @@
};
/**
 * Gets resolved hash.
 * @param {ContextHash | null} entry entry
 * @returns {string | null | undefined} the resolved entry
 */
@@ -1041,6 +1098,7 @@
};
/**
 * Adds the provided source to the snapshot optimization.
 * @template T
 * @param {Set<T>} source source
 * @param {Set<T>} target target
@@ -1064,6 +1122,7 @@
 */
class FileSystemInfo {
   /**
    * Creates an instance of FileSystemInfo.
    * @param {InputFileSystem} fs file system
    * @param {object} options options
    * @param {Iterable<string | RegExp>=} options.unmanagedPaths paths that are not managed by a package manager and the contents are subject to change
@@ -1257,6 +1316,7 @@
   logStatistics() {
      const logger = /** @type {Logger} */ (this.logger);
      /**
       * Processes the provided header.
       * @param {string} header header
       * @param {string | undefined} message message
       */
@@ -1344,6 +1404,7 @@
   }
   /**
    * Processes the provided path.
    * @private
    * @param {string} path path
    * @param {string} reason reason
@@ -1401,26 +1462,37 @@
   }
   /**
    * @param {ReadonlyMap<string, FileTimestamp>} map timestamps
    * Adds file timestamps.
    * @param {ReadonlyMap<string, FileSystemInfoEntry | ExistenceOnlyTimeEntry | "ignore" | null>} map timestamps
    * @param {boolean=} immutable if 'map' is immutable and FileSystemInfo can keep referencing it
    * @returns {void}
    */
   addFileTimestamps(map, immutable) {
      this._fileTimestamps.addAll(map, immutable);
      this._fileTimestamps.addAll(
         /** @type {ReadonlyMap<string, FileTimestamp>} */
         (map),
         immutable
      );
      this._cachedDeprecatedFileTimestamps = undefined;
   }
   /**
    * @param {ReadonlyMap<string, ContextTimestamp>} map timestamps
    * Adds context timestamps.
    * @param {ReadonlyMap<string, ContextFileSystemInfoEntry | ExistenceOnlyTimeEntry | "ignore" | null>} map timestamps
    * @param {boolean=} immutable if 'map' is immutable and FileSystemInfo can keep referencing it
    * @returns {void}
    */
   addContextTimestamps(map, immutable) {
      this._contextTimestamps.addAll(map, immutable);
      this._contextTimestamps.addAll(
         /** @type {ReadonlyMap<string, ContextTimestamp>} */
         (map),
         immutable
      );
      this._cachedDeprecatedContextTimestamps = undefined;
   }
   /**
    * Gets file timestamp.
    * @param {string} path file path
    * @param {(err?: WebpackError | null, fileTimestamp?: FileTimestamp) => void} callback callback function
    * @returns {void}
@@ -1432,6 +1504,7 @@
   }
   /**
    * Gets context timestamp.
    * @param {string} path context path
    * @param {(err?: WebpackError | null, resolvedContextTimestamp?: ResolvedContextTimestamp) => void} callback callback function
    * @returns {void}
@@ -1458,6 +1531,7 @@
   }
   /**
    * Get unresolved context timestamp.
    * @private
    * @param {string} path context path
    * @param {(err?: WebpackError | null, contextTimestamp?: ContextTimestamp) => void} callback callback function
@@ -1470,6 +1544,7 @@
   }
   /**
    * Returns file hash.
    * @param {string} path file path
    * @param {(err?: WebpackError | null, hash?: string | null) => void} callback callback function
    * @returns {void}
@@ -1481,6 +1556,7 @@
   }
   /**
    * Returns context hash.
    * @param {string} path context path
    * @param {(err?: WebpackError | null, contextHash?: string) => void} callback callback function
    * @returns {void}
@@ -1506,6 +1582,7 @@
   }
   /**
    * Get unresolved context hash.
    * @private
    * @param {string} path context path
    * @param {(err?: WebpackError | null, contextHash?: ContextHash | null) => void} callback callback function
@@ -1518,6 +1595,7 @@
   }
   /**
    * Returns context tsh.
    * @param {string} path context path
    * @param {(err?: WebpackError | null, resolvedContextTimestampAndHash?: ResolvedContextTimestampAndHash | null) => void} callback callback function
    * @returns {void}
@@ -1539,6 +1617,7 @@
   }
   /**
    * Get unresolved context tsh.
    * @private
    * @param {string} path context path
    * @param {(err?: WebpackError | null, contextTimestampAndHash?: ContextTimestampAndHash | null) => void} callback callback function
@@ -1579,6 +1658,7 @@
   }
   /**
    * Resolves build dependencies.
    * @param {string} context context directory
    * @param {Iterable<string>} deps dependencies
    * @param {(err?: Error | null, resolveBuildDependenciesResult?: ResolveBuildDependenciesResult) => void} callback callback function
@@ -1614,6 +1694,7 @@
         missingDependencies: resolveMissing
      };
      /**
       * Expected to string.
       * @param {undefined | boolean | string} expected expected result
       * @returns {string} expected result
       */
@@ -1622,6 +1703,7 @@
      /** @typedef {{ type: JobType, context: string | undefined, path: string, issuer: Job | undefined, expected: undefined | boolean | string }} Job */
      /**
       * Returns result.
       * @param {Job} job job
       * @returns {string} result
       */
@@ -1651,6 +1733,7 @@
         return `unknown ${job.type} ${job.path}`;
      };
      /**
       * Returns string value.
       * @param {Job} job job
       * @returns {string} string value
       */
@@ -1681,6 +1764,7 @@
         (job, push, callback) => {
            const { type, context, path, expected } = job;
            /**
             * Resolves directory.
             * @param {string} path path
             * @returns {void}
             */
@@ -1718,6 +1802,7 @@
               );
            };
            /**
             * Processes the provided path.
             * @param {string} path path
             * @param {("f" | "c" | "e")=} symbol symbol
             * @param {(ResolveFunctionAsync)=} resolve resolve fn
@@ -1790,7 +1875,9 @@
                  break;
               }
               case RBDT_RESOLVE_DIRECTORY: {
                  resolveDirectory(RBDT_RESOLVE_INITIAL ? path.slice(0, -1) : path);
                  resolveDirectory(
                     type === RBDT_RESOLVE_INITIAL ? path.slice(0, -1) : path
                  );
                  break;
               }
               case RBDT_RESOLVE_CJS_FILE: {
@@ -1889,7 +1976,7 @@
                           for (const modulePath of module.paths) {
                              if (childPath.startsWith(modulePath)) {
                                 const subPath = childPath.slice(modulePath.length + 1);
                                 const packageMatch = /^(@[^\\/]+[\\/])[^\\/]+/.exec(
                                 const packageMatch = /^@[^\\/]+[\\/][^\\/]+/.exec(
                                    subPath
                                 );
                                 if (packageMatch) {
@@ -1954,9 +2041,11 @@
                              const context = dirname(this.fs, path);
                              const source = /** @type {Buffer} */ (content).toString();
                              const [imports] = lexer.parse(source);
                              /** @type {Set<string>} */
                              const added = new Set();
                              for (const imp of imports) {
                                 try {
                                    /** @type {string} */
                                    let dependency;
                                    if (imp.d === -1) {
                                       // import ... from "..."
@@ -2043,6 +2132,7 @@
                        return callback(err);
                     }
                     resolveFiles.add(packageJson);
                     /** @type {JsonObject} */
                     let packageData;
                     try {
                        packageData = JSON.parse(
@@ -2054,7 +2144,9 @@
                     }
                     const depsObject = packageData.dependencies;
                     const optionalDepsObject = packageData.optionalDependencies;
                     /** @type {Set<string>} */
                     const allDeps = new Set();
                     /** @type {Set<string>} */
                     const optionalDeps = new Set();
                     if (typeof depsObject === "object" && depsObject) {
                        for (const dep of Object.keys(depsObject)) {
@@ -2106,6 +2198,7 @@
   }
   /**
    * Checks resolve results valid.
    * @param {ResolveResults} resolveResults results from resolving
    * @param {(err?: Error | null, result?: boolean) => void} callback callback with true when resolveResults resolve the same way
    * @returns {void}
@@ -2169,9 +2262,11 @@
            }
         },
         /**
          * Processes the provided err.
          * @param {Error | typeof INVALID=} err error or invalid flag
          * @returns {void}
          */
         /** @type {import("neo-async").ErrorCallback<Error | typeof INVALID>} */ (
         (err) => {
            if (err === INVALID) {
               return callback(null, false);
@@ -2181,10 +2276,12 @@
            }
            return callback(null, true);
         }
         )
      );
   }
   /**
    * Creates a snapshot.
    * @param {number | null | undefined} startTime when processing the files has started
    * @param {Iterable<string> | null | undefined} files all files
    * @param {Iterable<string> | null | undefined} directories all directories
@@ -2284,6 +2381,7 @@
         }
      };
      /**
       * Checks true when managed.
       * @param {string} path path
       * @param {ManagedFiles} managedSet managed set
       * @returns {boolean} true when managed
@@ -2331,6 +2429,7 @@
         return false;
      };
      /**
       * Capture non managed.
       * @param {Iterable<string>} items items
       * @param {Set<string>} managedSet managed set
       * @returns {Set<string>} result
@@ -2344,6 +2443,7 @@
         return capturedItems;
      };
      /**
       * Process captured files.
       * @param {ManagedFiles} capturedFiles captured files
       */
      const processCapturedFiles = (capturedFiles) => {
@@ -2435,6 +2535,7 @@
         processCapturedFiles(captureNonManaged(files, managedFiles));
      }
      /**
       * Process captured directories.
       * @param {ManagedContexts} capturedDirectories captured directories
       */
      const processCapturedDirectories = (capturedDirectories) => {
@@ -2456,6 +2557,7 @@
                  } else {
                     jobs++;
                     /**
                      * Processes the provided err.
                      * @param {(WebpackError | null)=} err error
                      * @param {(ResolvedContextTimestampAndHash | null)=} entry entry
                      * @returns {void}
@@ -2492,6 +2594,7 @@
               );
               for (const path of capturedDirectories) {
                  const cache = this._contextHashes.get(path);
                  /** @type {undefined | null | string} */
                  let resolved;
                  if (
                     cache !== undefined &&
@@ -2501,6 +2604,7 @@
                  } else {
                     jobs++;
                     /**
                      * Processes the provided err.
                      * @param {(WebpackError | null)=} err err
                      * @param {string=} entry entry
                      */
@@ -2533,6 +2637,7 @@
               for (const path of capturedDirectories) {
                  const cache = this._contextTimestamps.get(path);
                  if (cache === "ignore") continue;
                  /** @type {undefined | null | ResolvedContextFileSystemInfoEntry} */
                  let resolved;
                  if (
                     cache !== undefined &&
@@ -2542,6 +2647,7 @@
                  } else {
                     jobs++;
                     /**
                      * Processes the provided err.
                      * @param {(Error | null)=} err error
                      * @param {FileTimestamp=} entry entry
                      * @returns {void}
@@ -2583,6 +2689,7 @@
         );
      }
      /**
       * Process captured missing.
       * @param {ManagedMissing} capturedMissing captured missing
       */
      const processCapturedMissing = (capturedMissing) => {
@@ -2648,11 +2755,13 @@
               } else {
                  // Fallback to normal snapshotting
                  /**
                   * Processes the provided set.
                   * @param {Set<string>} set set
                   * @param {(set: Set<string>) => void} fn fn
                   */
                  const process = (set, fn) => {
                     if (set.size === 0) return;
                     /** @type {Set<string>} */
                     const captured = new Set();
                     for (const file of set) {
                        if (file.startsWith(path)) captured.add(file);
@@ -2671,6 +2780,7 @@
   }
   /**
    * Merges the provided values into a single result.
    * @param {Snapshot} snapshot1 a snapshot
    * @param {Snapshot} snapshot2 a snapshot
    * @returns {Snapshot} merged snapshot
@@ -2757,6 +2867,7 @@
   }
   /**
    * Checks snapshot valid.
    * @param {Snapshot} snapshot the snapshot made
    * @param {CheckSnapshotValidCallback} callback callback function
    * @returns {void}
@@ -2777,6 +2888,7 @@
   }
   /**
    * Check snapshot valid no cache.
    * @private
    * @param {Snapshot} snapshot the snapshot made
    * @param {CheckSnapshotValidCallback} callback callback function
@@ -2804,6 +2916,7 @@
         }
      };
      /**
       * Invalid with error.
       * @param {string} path path
       * @param {WebpackError} err err
       */
@@ -2814,6 +2927,7 @@
         invalid();
      };
      /**
       * Checks true, if ok.
       * @param {string} path file path
       * @param {string | null} current current hash
       * @param {string | null} snap snapshot hash
@@ -2830,6 +2944,7 @@
         return true;
      };
      /**
       * Checks true, if ok.
       * @param {string} path file path
       * @param {boolean} current current entry
       * @param {boolean} snap entry from snapshot
@@ -2850,6 +2965,7 @@
         return true;
      };
      /**
       * Checks true, if ok.
       * @param {string} path file path
       * @param {FileSystemInfoEntry | null} c current entry
       * @param {FileSystemInfoEntry | null} s entry from snapshot
@@ -2892,6 +3008,7 @@
         return true;
      };
      /**
       * Checks true, if ok.
       * @param {string} path file path
       * @param {ResolvedContextFileSystemInfoEntry | null} c current entry
       * @param {ResolvedContextFileSystemInfoEntry | null} s entry from snapshot
@@ -2938,6 +3055,7 @@
      };
      if (snapshot.hasChildren()) {
         /**
          * Processes the provided err.
          * @param {(WebpackError | null)=} err err
          * @param {boolean=} result result
          * @returns {void}
@@ -2999,6 +3117,7 @@
         }
      }
      /**
       * Process file hash snapshot.
       * @param {string} path file path
       * @param {string | null} hash hash
       */
@@ -3068,6 +3187,7 @@
         for (const [path, ts] of contextTimestamps) {
            const cache = this._contextTimestamps.get(path);
            if (cache === "ignore") continue;
            /** @type {undefined | null | ResolvedContextFileSystemInfoEntry} */
            let resolved;
            if (
               cache !== undefined &&
@@ -3080,6 +3200,7 @@
            } else {
               jobs++;
               /**
                * Processes the provided err.
                * @param {(WebpackError | null)=} err error
                * @param {ResolvedContextTimestamp=} entry entry
                * @returns {void}
@@ -3112,11 +3233,13 @@
         }
      }
      /**
       * Process context hash snapshot.
       * @param {string} path path
       * @param {string | null} hash hash
       */
      const processContextHashSnapshot = (path, hash) => {
         const cache = this._contextHashes.get(path);
         /** @type {undefined | null | string} */
         let resolved;
         if (
            cache !== undefined &&
@@ -3128,6 +3251,7 @@
         } else {
            jobs++;
            /**
             * Processes the provided err.
             * @param {(WebpackError | null)=} err err
             * @param {string=} entry entry
             * @returns {void}
@@ -3165,25 +3289,19 @@
            } else {
               const cache = this._contextTimestamps.get(path);
               if (cache === "ignore") continue;
               /** @type {undefined | null | ResolvedContextFileSystemInfoEntry} */
               let resolved;
               if (
                  cache !== undefined &&
                  (resolved = getResolvedTimestamp(cache)) !== undefined
               ) {
                  if (
                     !checkContext(
                        path,
                        /** @type {ResolvedContextFileSystemInfoEntry | null} */
                        (resolved),
                        tsh,
                        false
                     )
                  ) {
                  if (!checkContext(path, resolved, tsh, false)) {
                     processContextHashSnapshot(path, tsh && tsh.hash);
                  }
               } else {
                  jobs++;
                  /**
                   * Processes the provided err.
                   * @param {(WebpackError | null)=} err error
                   * @param {ResolvedContextTimestamp=} entry entry
                   * @returns {void}
@@ -3298,6 +3416,7 @@
            return callback(/** @type {WebpackError} */ (err));
         }
         const stat = /** @type {IStats} */ (_stat);
         /** @type {FileSystemInfoEntry} */
         let ts;
         if (stat.isDirectory()) {
            ts = {
@@ -3359,12 +3478,14 @@
   }
   /**
    * Get file timestamp and hash.
    * @private
    * @param {string} path path
    * @param {(err: WebpackError | null, timestampAndHash?: TimestampAndHash | string) => void} callback callback
    */
   _getFileTimestampAndHash(path, callback) {
      /**
       * Continue with hash.
       * @param {string} hash hash
       * @returns {void}
       */
@@ -3411,6 +3532,7 @@
   }
   /**
    * Processes the provided object.
    * @private
    * @template T
    * @template ItemType
@@ -3576,6 +3698,7 @@
               });
            },
            reduce: (files, tsEntries) => {
               /** @type {undefined | Symlinks} */
               let symlinks;
               const hash = createHash(this._hashFunction);
@@ -3639,6 +3762,7 @@
   }
   /**
    * Resolve context timestamp.
    * @private
    * @param {ContextFileSystemInfoEntry} entry entry
    * @param {(err?: WebpackError | null, resolvedContextTimestamp?: ResolvedContextTimestamp) => void} callback callback
@@ -3720,11 +3844,13 @@
               });
            },
            /**
             * Returns reduced hash.
             * @param {string[]} files files
             * @param {(string | ContextHash)[]} fileHashes hashes
             * @returns {ContextHash} reduced hash
             */
            reduce: (files, fileHashes) => {
               /** @type {undefined | Symlinks} */
               let symlinks;
               const hash = createHash(this._hashFunction);
@@ -3759,6 +3885,7 @@
   }
   /**
    * Resolve context hash.
    * @private
    * @param {ContextHash} entry context hash
    * @param {(err: WebpackError | null, contextHash?: string) => void} callback callback
@@ -3801,6 +3928,7 @@
    */
   _readContextTimestampAndHash(path, callback) {
      /**
       * Processes the provided timestamp.
       * @param {ContextTimestamp} timestamp timestamp
       * @param {ContextHash} hash hash
       */
@@ -3862,11 +3990,13 @@
                  });
               },
               /**
                * Returns tsh.
                * @param {string[]} files files
                * @param {(Partial<TimestampAndHash> & Partial<ContextTimestampAndHash> | string | null)[]} results results
                * @returns {ContextTimestampAndHash} tsh
                */
               reduce: (files, results) => {
                  /** @type {undefined | Symlinks} */
                  let symlinks;
                  const tsHash = createHash(this._hashFunction);
@@ -3925,6 +4055,7 @@
   }
   /**
    * Resolve context tsh.
    * @private
    * @param {ContextTimestampAndHash} entry entry
    * @param {ProcessorCallback<ResolvedContextTimestampAndHash>} callback callback
@@ -3997,9 +4128,8 @@
            return callback(/** @type {WebpackError} */ (err));
         }
         const set = new Set(
            /** @type {string[]} */ (elements).map((element) =>
               join(this.fs, path, element)
            )
            /** @type {string[]} */
            (elements).map((element) => join(this.fs, path, element))
         );
         callback(null, set);
      });
@@ -4058,6 +4188,7 @@
               }
               return callback(/** @type {WebpackError} */ (err));
            }
            /** @type {JsonObject} */
            let data;
            try {
               data = JSON.parse(/** @type {Buffer} */ (content).toString("utf8"));