WXL
3 天以前 9bce51f651aad297ef9eb6df832bfdaf1de05d84
node_modules/webpack/lib/cache/PackFileCacheStrategy.js
@@ -18,6 +18,7 @@
} = require("../util/serialization");
/** @typedef {import("../../declarations/WebpackOptions").SnapshotOptions} SnapshotOptions */
/** @typedef {import("../Compilation").FileSystemDependencies} FileSystemDependencies */
/** @typedef {import("../Cache").Data} Data */
/** @typedef {import("../Cache").Etag} Etag */
/** @typedef {import("../Compiler")} Compiler */
@@ -27,7 +28,7 @@
/** @typedef {import("../logging/Logger").Logger} Logger */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
/** @typedef {typeof import("../util/Hash")} Hash */
/** @typedef {import("../util/Hash").HashFunction} HashFunction */
/** @typedef {import("../util/fs").IntermediateFileSystem} IntermediateFileSystem */
/** @typedef {Set<string>} Items */
@@ -36,6 +37,7 @@
class PackContainer {
   /**
    * Creates an instance of PackContainer.
    * @param {Pack} data stored data
    * @param {string} version version identifier
    * @param {Snapshot} buildSnapshot snapshot of all build dependencies
@@ -51,7 +53,7 @@
      resolveResults,
      resolveBuildDependenciesSnapshot
   ) {
      /** @type {Pack | (() => Pack) } */
      /** @type {Pack | (() => Pack)} */
      this.data = data;
      /** @type {string} */
      this.version = version;
@@ -66,6 +68,7 @@
   }
   /**
    * Serializes this instance into the provided serializer context.
    * @param {ObjectSerializerContext} context context
    */
   serialize({ write, writeLazy }) {
@@ -79,6 +82,7 @@
   }
   /**
    * Restores this instance from the provided deserializer context.
    * @param {ObjectDeserializerContext} context context
    */
   deserialize({ read }) {
@@ -105,6 +109,7 @@
class PackItemInfo {
   /**
    * Creates an instance of PackItemInfo.
    * @param {string} identifier identifier of item
    * @param {string | null | undefined} etag etag of item
    * @param {Data} value fresh value of item
@@ -125,6 +130,7 @@
class Pack {
   /**
    * Creates an instance of Pack.
    * @param {Logger} logger a logger
    * @param {number} maxAge max age of cache items
    */
@@ -133,17 +139,22 @@
      this.itemInfo = new Map();
      /** @type {(string | undefined)[]} */
      this.requests = [];
      /** @type {undefined | NodeJS.Timeout} */
      this.requestsTimeout = undefined;
      /** @type {ItemInfo} */
      this.freshContent = new Map();
      /** @type {(undefined | PackContent)[]} */
      this.content = [];
      /** @type {boolean} */
      this.invalid = false;
      /** @type {Logger} */
      this.logger = logger;
      /** @type {number} */
      this.maxAge = maxAge;
   }
   /**
    * Adds the provided identifier to the pack.
    * @param {string} identifier identifier
    */
   _addRequest(identifier) {
@@ -165,6 +176,7 @@
   }
   /**
    * Returns cached content.
    * @param {string} identifier unique name for the resource
    * @param {string | null} etag etag of the resource
    * @returns {Data} cached content
@@ -188,6 +200,7 @@
   }
   /**
    * Updates value using the provided identifier.
    * @param {string} identifier unique name for the resource
    * @param {string | null} etag etag of the resource
    * @param {Data} data cached content
@@ -239,15 +252,18 @@
   }
   /**
    * Returns new location of data entries.
    * @returns {number} new location of data entries
    */
   _findLocation() {
      /** @type {number} */
      let i;
      for (i = 0; i < this.content.length && this.content[i] !== undefined; i++);
      return i;
   }
   /**
    * Gc and update location.
    * @private
    * @param {Items} items items
    * @param {Items} usedItems used items
@@ -255,6 +271,7 @@
    */
   _gcAndUpdateLocation(items, usedItems, newLoc) {
      let count = 0;
      /** @type {undefined | string} */
      let lastGC;
      const now = Date.now();
      for (const identifier of items) {
@@ -380,6 +397,7 @@
      }
      // 2. Check if minimum number is reached
      /** @type {number[]} */
      let mergedIndices;
      if (
         smallUsedContents.length >= CONTENT_COUNT_TO_MERGE ||
@@ -395,7 +413,7 @@
         return;
      }
      /** @type {PackContent[] } */
      /** @type {PackContent[]} */
      const mergedContent = [];
      // 3. Remove old content entries
@@ -504,6 +522,7 @@
            // 5. Determine items for the unused content file
            const unusedItems = new Set(content.items);
            /** @type {Items} */
            const usedOfUnusedItems = new Set();
            for (const identifier of usedItems) {
               unusedItems.delete(identifier);
@@ -520,6 +539,7 @@
                     await content.unpack(
                        "it should be splitted into used and unused items"
                     );
                     /** @type {Content} */
                     const map = new Map();
                     for (const identifier of unusedItems) {
                        map.set(
@@ -578,6 +598,7 @@
                     await content.unpack(
                        "it contains old items that should be garbage collected"
                     );
                     /** @type {Content} */
                     const map = new Map();
                     for (const identifier of items) {
                        map.set(
@@ -593,6 +614,7 @@
   }
   /**
    * Serializes this instance into the provided serializer context.
    * @param {ObjectSerializerContext} context context
    */
   serialize({ write, writeSeparate }) {
@@ -626,6 +648,7 @@
   }
   /**
    * Restores this instance from the provided deserializer context.
    * @param {ObjectDeserializerContext & { logger: Logger }} context context
    */
   deserialize({ read, logger }) {
@@ -683,6 +706,7 @@
class PackContentItems {
   /**
    * Creates an instance of PackContentItems.
    * @param {Content} map items
    */
   constructor(map) {
@@ -690,7 +714,8 @@
   }
   /**
    * @param {ObjectSerializerContext & { logger: Logger, profile: boolean | undefined  }} context context
    * Serializes this instance into the provided serializer context.
    * @param {ObjectSerializerContext & { logger: Logger, profile: boolean | undefined }} context context
    */
   serialize({ write, snapshot, rollback, logger, profile }) {
      if (profile) {
@@ -767,12 +792,14 @@
   }
   /**
    * Restores this instance from the provided deserializer context.
    * @param {ObjectDeserializerContext & { logger: Logger, profile: boolean | undefined }} context context
    */
   deserialize({ read, logger, profile }) {
      if (read()) {
         this.map = read();
      } else if (profile) {
         /** @type {Map<EXPECTED_ANY, EXPECTED_ANY>} */
         const map = new Map();
         let key = read();
         while (key !== null) {
@@ -798,6 +825,7 @@
         }
         this.map = map;
      } else {
         /** @type {Map<EXPECTED_ANY, EXPECTED_ANY>} */
         const map = new Map();
         let key = read();
         while (key !== null) {
@@ -815,7 +843,7 @@
   "PackContentItems"
);
/** @typedef {(() => Promise<PackContentItems> | PackContentItems) & Partial<{ options: { size?: number }}>} LazyFunction */
/** @typedef {(() => Promise<PackContentItems> | PackContentItems) & Partial<{ options: { size?: number } }>} LazyFunction */
class PackContent {
   /*
@@ -838,6 +866,7 @@
   */
   /**
    * Creates an instance of PackContent.
    * @param {Items} items keys
    * @param {Items} usedItems used keys
    * @param {PackContentItems | (() => Promise<PackContentItems>)} dataOrFn sync or async content
@@ -845,18 +874,24 @@
    * @param {string=} lazyName name of dataOrFn for logging
    */
   constructor(items, usedItems, dataOrFn, logger, lazyName) {
      /** @type {Items} */
      this.items = items;
      /** @type {LazyFunction | undefined} */
      this.lazy = typeof dataOrFn === "function" ? dataOrFn : undefined;
      /** @type {Content | undefined} */
      this.content = typeof dataOrFn === "function" ? undefined : dataOrFn.map;
      /** @type {boolean} */
      this.outdated = false;
      /** @type {Items} */
      this.used = usedItems;
      /** @type {Logger | undefined} */
      this.logger = logger;
      /** @type {string | undefined} */
      this.lazyName = lazyName;
   }
   /**
    * Returns result.
    * @param {string} identifier identifier
    * @returns {string | Promise<string>} result
    */
@@ -909,6 +944,7 @@
   }
   /**
    * Returns maybe a promise if lazy.
    * @param {string} reason explanation why unpack is necessary
    * @returns {void | Promise<void>} maybe a promise if lazy
    */
@@ -953,6 +989,7 @@
   }
   /**
    * Returns the estimated size for the requested source type.
    * @returns {number} size of the content or -1 if not known
    */
   getSize() {
@@ -967,6 +1004,7 @@
   }
   /**
    * Processes the provided identifier.
    * @param {string} identifier identifier
    */
   delete(identifier) {
@@ -976,6 +1014,7 @@
   }
   /**
    * Processes the provided write.
    * @param {(lazy: LazyFunction) => (() => PackContentItems | Promise<PackContentItems>)} write write function
    * @returns {void}
    */
@@ -1068,6 +1107,7 @@
}
/**
 * Allow collecting memory.
 * @param {Buffer} buf buffer
 * @returns {Buffer} buffer that can be collected
 */
@@ -1081,6 +1121,7 @@
class PackFileCacheStrategy {
   /**
    * Creates an instance of PackFileCacheStrategy.
    * @param {object} options options
    * @param {Compiler} options.compiler the compiler
    * @param {IntermediateFileSystem} options.fs the filesystem
@@ -1090,10 +1131,10 @@
    * @param {Logger} options.logger a logger
    * @param {SnapshotOptions} options.snapshot options regarding snapshotting
    * @param {number} options.maxAge max age of cache items
    * @param {boolean | undefined} options.profile track and log detailed timing information for individual cache items
    * @param {boolean | undefined} options.allowCollectingMemory allow to collect unused memory created during deserialization
    * @param {false | "gzip" | "brotli" | undefined} options.compression compression used
    * @param {boolean | undefined} options.readonly disable storing cache into filesystem
    * @param {boolean=} options.profile track and log detailed timing information for individual cache items
    * @param {boolean=} options.allowCollectingMemory allow to collect unused memory created during deserialization
    * @param {false | "gzip" | "brotli"=} options.compression compression used
    * @param {boolean=} options.readonly disable storing cache into filesystem
    */
   constructor({
      compiler,
@@ -1109,38 +1150,51 @@
      compression,
      readonly
   }) {
      /** @type {import("../serialization/Serializer")<PackContainer, null, {}>} */
      /** @type {import("../serialization/Serializer")<PackContainer, null, EXPECTED_OBJECT>} */
      this.fileSerializer = createFileSerializer(
         fs,
         /** @type {string | Hash} */
         /** @type {HashFunction} */
         (compiler.options.output.hashFunction)
      );
      /** @type {FileSystemInfo} */
      this.fileSystemInfo = new FileSystemInfo(fs, {
         managedPaths: snapshot.managedPaths,
         immutablePaths: snapshot.immutablePaths,
         logger: logger.getChildLogger("webpack.FileSystemInfo"),
         hashFunction: compiler.options.output.hashFunction
      });
      /** @type {Compiler} */
      this.compiler = compiler;
      /** @type {string} */
      this.context = context;
      /** @type {string} */
      this.cacheLocation = cacheLocation;
      /** @type {string} */
      this.version = version;
      /** @type {Logger} */
      this.logger = logger;
      /** @type {number} */
      this.maxAge = maxAge;
      /** @type {boolean | undefined} */
      this.profile = profile;
      /** @type {boolean | undefined} */
      this.readonly = readonly;
      /** @type {boolean | undefined} */
      this.allowCollectingMemory = allowCollectingMemory;
      /** @type {false | "gzip" | "brotli" | undefined} */
      this.compression = compression;
      /** @type {string} */
      this._extension =
         compression === "brotli"
            ? ".pack.br"
            : compression === "gzip"
               ? ".pack.gz"
               : ".pack";
      /** @type {SnapshotOptions} */
      this.snapshot = snapshot;
      /** @type {BuildDependencies} */
      this.buildDependencies = new Set();
      /** @type {LazySet<string>} */
      /** @type {FileSystemDependencies} */
      this.newBuildDependencies = new LazySet();
      /** @type {Snapshot | undefined} */
      this.resolveBuildDependenciesSnapshot = undefined;
@@ -1150,10 +1204,12 @@
      this.buildSnapshot = undefined;
      /** @type {Promise<Pack> | undefined} */
      this.packPromise = this._openPack();
      /** @type {Promise<void>} */
      this.storePromise = Promise.resolve();
   }
   /**
    * Returns pack.
    * @returns {Promise<Pack>} pack
    */
   _getPack() {
@@ -1164,6 +1220,7 @@
   }
   /**
    * Returns the pack.
    * @returns {Promise<Pack>} the pack
    */
   _openPack() {
@@ -1330,6 +1387,7 @@
   }
   /**
    * Returns promise.
    * @param {string} identifier unique name for the resource
    * @param {Etag | null} etag etag of the resource
    * @param {Data} data cached content
@@ -1344,6 +1402,7 @@
   }
   /**
    * Returns promise to the cached content.
    * @param {string} identifier unique name for the resource
    * @param {Etag | null} etag etag of the resource
    * @returns {Promise<Data>} promise to the cached content
@@ -1364,7 +1423,8 @@
   }
   /**
    * @param {LazySet<string> | Iterable<string>} dependencies dependencies to store
    * Stores build dependencies.
    * @param {FileSystemDependencies | Iterable<string>} dependencies dependencies to store
    */
   storeBuildDependencies(dependencies) {
      if (this.readonly) return;
@@ -1381,7 +1441,9 @@
            if (!pack.invalid) return;
            this.packPromise = undefined;
            this.logger.log("Storing pack...");
            /** @type {undefined | Promise<void>} */
            let promise;
            /** @type {Set<string>} */
            const newBuildDependencies = new Set();
            for (const dep of this.newBuildDependencies) {
               if (!this.buildDependencies.has(dep)) {
@@ -1395,6 +1457,7 @@
               );
               promise = new Promise(
                  /**
                   * Handles the callback logic for this hook.
                   * @param {(value?: undefined) => void} resolve resolve
                   * @param {(reason?: Error) => void} reject reject
                   */