| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-11 22:25:03 +08:00
										 |  |  | const { create: createResolver } = require("enhanced-resolve"); | 
					
						
							| 
									
										
										
										
											2022-04-01 20:52:40 +08:00
										 |  |  | const nodeModule = require("module"); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | const asyncLib = require("neo-async"); | 
					
						
							| 
									
										
										
										
											2022-06-02 18:06:41 +08:00
										 |  |  | const { isAbsolute } = require("path"); | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | const AsyncQueue = require("./util/AsyncQueue"); | 
					
						
							| 
									
										
										
										
											2021-07-16 19:05:18 +08:00
										 |  |  | const StackedCacheMap = require("./util/StackedCacheMap"); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | const createHash = require("./util/createHash"); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | const { join, dirname, relative, lstatReadlinkAbsolute } = require("./util/fs"); | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | const makeSerializable = require("./util/makeSerializable"); | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | const processAsyncTree = require("./util/processAsyncTree"); | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | /** @typedef {import("enhanced-resolve").Resolver} Resolver */ | 
					
						
							|  |  |  | /** @typedef {import("enhanced-resolve").ResolveRequest} ResolveRequest */ | 
					
						
							|  |  |  | /** @typedef {import("enhanced-resolve").ResolveFunctionAsync} ResolveFunctionAsync */ | 
					
						
							| 
									
										
										
										
											2019-07-18 05:35:05 +08:00
										 |  |  | /** @typedef {import("./WebpackError")} WebpackError */ | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | /** @typedef {import("./logging/Logger").Logger} Logger */ | 
					
						
							| 
									
										
										
										
											2023-04-12 02:57:43 +08:00
										 |  |  | /** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ | 
					
						
							|  |  |  | /** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ | 
					
						
							| 
									
										
										
										
											2021-09-22 18:12:46 +08:00
										 |  |  | /** @typedef {typeof import("./util/Hash")} Hash */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | /** @typedef {import("./util/fs").IStats} IStats */ | 
					
						
							| 
									
										
										
										
											2019-07-18 05:35:05 +08:00
										 |  |  | /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | /** @typedef {import("./util/fs").PathLike} PathLike */ | 
					
						
							|  |  |  | /** @typedef {import("./util/fs").StringCallback} StringCallback */ | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * @template T | 
					
						
							|  |  |  |  * @typedef {import("./util/AsyncQueue").Callback<T>} ProcessorCallback | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * @template T, R | 
					
						
							|  |  |  |  * @typedef {import("./util/AsyncQueue").Processor<T, R>} Processor | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-07-18 05:35:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-31 11:11:11 +08:00
										 |  |  | const supportsEsm = Number(process.versions.modules) >= 83; | 
					
						
							| 
									
										
										
										
											2021-01-14 04:16:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | /** @type {Set<string>} */ | 
					
						
							| 
									
										
										
										
											2022-04-01 20:52:40 +08:00
										 |  |  | const builtinModules = new Set(nodeModule.builtinModules); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | let FS_ACCURACY = 2000; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | const EMPTY_SET = new Set(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | const RBDT_RESOLVE_CJS = 0; | 
					
						
							|  |  |  | const RBDT_RESOLVE_ESM = 1; | 
					
						
							|  |  |  | const RBDT_RESOLVE_DIRECTORY = 2; | 
					
						
							|  |  |  | const RBDT_RESOLVE_CJS_FILE = 3; | 
					
						
							| 
									
										
										
										
											2021-04-06 19:58:36 +08:00
										 |  |  | const RBDT_RESOLVE_CJS_FILE_AS_CHILD = 4; | 
					
						
							|  |  |  | const RBDT_RESOLVE_ESM_FILE = 5; | 
					
						
							|  |  |  | const RBDT_DIRECTORY = 6; | 
					
						
							|  |  |  | const RBDT_FILE = 7; | 
					
						
							|  |  |  | const RBDT_DIRECTORY_DEPENDENCIES = 8; | 
					
						
							|  |  |  | const RBDT_FILE_DEPENDENCIES = 9; | 
					
						
							| 
									
										
										
										
											2019-08-13 23:21:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | /** @typedef {RBDT_RESOLVE_CJS | RBDT_RESOLVE_ESM | RBDT_RESOLVE_DIRECTORY | RBDT_RESOLVE_CJS_FILE | RBDT_RESOLVE_CJS_FILE_AS_CHILD | RBDT_RESOLVE_ESM_FILE | RBDT_DIRECTORY | RBDT_FILE | RBDT_DIRECTORY_DEPENDENCIES | RBDT_FILE_DEPENDENCIES} JobType */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-20 03:57:49 +08:00
										 |  |  | const INVALID = Symbol("invalid"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2024-06-11 21:09:50 +08:00
										 |  |  |  * @typedef {object} FileSystemInfoEntry | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  |  * @property {number} safeTime | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  |  * @property {number=} timestamp | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2024-06-11 21:09:50 +08:00
										 |  |  |  * @typedef {object} ResolvedContextFileSystemInfoEntry | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  |  * @property {number} safeTime | 
					
						
							|  |  |  |  * @property {string=} timestampHash | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2024-06-11 21:09:50 +08:00
										 |  |  |  * @typedef {object} ContextFileSystemInfoEntry | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  |  * @property {number} safeTime | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  |  * @property {string=} timestampHash | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  |  * @property {ResolvedContextFileSystemInfoEntry=} resolved | 
					
						
							|  |  |  |  * @property {Set<string>=} symlinks | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2024-06-11 21:09:50 +08:00
										 |  |  |  * @typedef {object} TimestampAndHash | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  |  * @property {number} safeTime | 
					
						
							|  |  |  |  * @property {number=} timestamp | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  |  * @property {string} hash | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2024-06-11 21:09:50 +08:00
										 |  |  |  * @typedef {object} ResolvedContextTimestampAndHash | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  |  * @property {number} safeTime | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  |  * @property {string=} timestampHash | 
					
						
							|  |  |  |  * @property {string} hash | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | /** @typedef {Set<string>} Symlinks */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2024-06-11 21:09:50 +08:00
										 |  |  |  * @typedef {object} ContextTimestampAndHash | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  |  * @property {number} safeTime | 
					
						
							|  |  |  |  * @property {string=} timestampHash | 
					
						
							|  |  |  |  * @property {string} hash | 
					
						
							|  |  |  |  * @property {ResolvedContextTimestampAndHash=} resolved | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  |  * @property {Symlinks=} symlinks | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2024-06-11 21:09:50 +08:00
										 |  |  |  * @typedef {object} ContextHash | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  |  * @property {string} hash | 
					
						
							|  |  |  |  * @property {string=} resolved | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  |  * @property {Symlinks=} symlinks | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | /** @typedef {Set<string>} SnapshotContent */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-31 17:59:28 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2024-06-11 21:09:50 +08:00
										 |  |  |  * @typedef {object} SnapshotOptimizationEntry | 
					
						
							| 
									
										
										
										
											2020-01-31 17:59:28 +08:00
										 |  |  |  * @property {Snapshot} snapshot | 
					
						
							|  |  |  |  * @property {number} shared | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  |  * @property {SnapshotContent | undefined} snapshotContent | 
					
						
							| 
									
										
										
										
											2023-06-22 05:55:05 +08:00
										 |  |  |  * @property {Set<SnapshotOptimizationEntry> | undefined} children | 
					
						
							| 
									
										
										
										
											2019-07-18 05:35:05 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2024-06-11 21:09:50 +08:00
										 |  |  |  * @typedef {object} ResolveBuildDependenciesResult | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  |  * @property {Set<string>} files list of files | 
					
						
							|  |  |  |  * @property {Set<string>} directories list of directories | 
					
						
							|  |  |  |  * @property {Set<string>} missing list of missing entries | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  |  * @property {Map<string, string | false | undefined>} resolveResults stored resolve results | 
					
						
							| 
									
										
										
										
											2024-06-11 21:09:50 +08:00
										 |  |  |  * @property {object} resolveDependencies dependencies of the resolving | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  |  * @property {Set<string>} resolveDependencies.files list of files | 
					
						
							|  |  |  |  * @property {Set<string>} resolveDependencies.directories list of directories | 
					
						
							|  |  |  |  * @property {Set<string>} resolveDependencies.missing list of missing entries | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-22 05:55:05 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2024-06-11 21:09:50 +08:00
										 |  |  |  * @typedef {object} SnapshotOptions | 
					
						
							| 
									
										
										
										
											2023-06-22 05:55:05 +08:00
										 |  |  |  * @property {boolean=} hash should use hash to snapshot | 
					
						
							|  |  |  |  * @property {boolean=} timestamp should use timestamp to snapshot | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | const DONE_ITERATOR_RESULT = new Set().keys().next(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | // cspell:word tshs
 | 
					
						
							|  |  |  | // Tsh = Timestamp + Hash
 | 
					
						
							|  |  |  | // Tshs = Timestamp + Hash combinations
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-15 21:16:44 +08:00
										 |  |  | class SnapshotIterator { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {() => IteratorResult<string>} next next | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2021-04-15 21:16:44 +08:00
										 |  |  | 	constructor(next) { | 
					
						
							|  |  |  | 		this.next = next; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @typedef {(snapshot: Snapshot) => (Map<string, any> | Set<string> | undefined)[]} GetMapsFunction | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-15 21:16:44 +08:00
										 |  |  | class SnapshotIterable { | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {Snapshot} snapshot snapshot | 
					
						
							|  |  |  | 	 * @param {GetMapsFunction} getMaps get maps function | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2021-04-15 21:16:44 +08:00
										 |  |  | 	constructor(snapshot, getMaps) { | 
					
						
							|  |  |  | 		this.snapshot = snapshot; | 
					
						
							|  |  |  | 		this.getMaps = getMaps; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	[Symbol.iterator]() { | 
					
						
							|  |  |  | 		let state = 0; | 
					
						
							|  |  |  | 		/** @type {IterableIterator<string>} */ | 
					
						
							|  |  |  | 		let it; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {(snapshot: Snapshot) => (Map<string, any> | Set<string> | undefined)[]} */ | 
					
						
							| 
									
										
										
										
											2021-04-15 21:16:44 +08:00
										 |  |  | 		let getMaps; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {(Map<string, any> | Set<string> | undefined)[]} */ | 
					
						
							| 
									
										
										
										
											2021-04-15 21:16:44 +08:00
										 |  |  | 		let maps; | 
					
						
							|  |  |  | 		/** @type {Snapshot} */ | 
					
						
							|  |  |  | 		let snapshot; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {Snapshot[] | undefined} */ | 
					
						
							| 
									
										
										
										
											2021-04-15 21:16:44 +08:00
										 |  |  | 		let queue; | 
					
						
							|  |  |  | 		return new SnapshotIterator(() => { | 
					
						
							|  |  |  | 			for (;;) { | 
					
						
							|  |  |  | 				switch (state) { | 
					
						
							|  |  |  | 					case 0: | 
					
						
							|  |  |  | 						snapshot = this.snapshot; | 
					
						
							|  |  |  | 						getMaps = this.getMaps; | 
					
						
							|  |  |  | 						maps = getMaps(snapshot); | 
					
						
							|  |  |  | 						state = 1; | 
					
						
							|  |  |  | 					/* falls through */ | 
					
						
							|  |  |  | 					case 1: | 
					
						
							|  |  |  | 						if (maps.length > 0) { | 
					
						
							|  |  |  | 							const map = maps.pop(); | 
					
						
							|  |  |  | 							if (map !== undefined) { | 
					
						
							|  |  |  | 								it = map.keys(); | 
					
						
							|  |  |  | 								state = 2; | 
					
						
							|  |  |  | 							} else { | 
					
						
							|  |  |  | 								break; | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} else { | 
					
						
							|  |  |  | 							state = 3; | 
					
						
							|  |  |  | 							break; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					/* falls through */ | 
					
						
							|  |  |  | 					case 2: { | 
					
						
							|  |  |  | 						const result = it.next(); | 
					
						
							|  |  |  | 						if (!result.done) return result; | 
					
						
							|  |  |  | 						state = 1; | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					case 3: { | 
					
						
							|  |  |  | 						const children = snapshot.children; | 
					
						
							|  |  |  | 						if (children !== undefined) { | 
					
						
							|  |  |  | 							if (children.size === 1) { | 
					
						
							|  |  |  | 								// shortcut for a single child
 | 
					
						
							|  |  |  | 								// avoids allocation of queue
 | 
					
						
							|  |  |  | 								for (const child of children) snapshot = child; | 
					
						
							|  |  |  | 								maps = getMaps(snapshot); | 
					
						
							|  |  |  | 								state = 1; | 
					
						
							|  |  |  | 								break; | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							if (queue === undefined) queue = []; | 
					
						
							|  |  |  | 							for (const child of children) { | 
					
						
							|  |  |  | 								queue.push(child); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						if (queue !== undefined && queue.length > 0) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							snapshot = /** @type {Snapshot} */ (queue.pop()); | 
					
						
							| 
									
										
										
										
											2021-04-15 21:16:44 +08:00
										 |  |  | 							maps = getMaps(snapshot); | 
					
						
							|  |  |  | 							state = 1; | 
					
						
							|  |  |  | 							break; | 
					
						
							|  |  |  | 						} else { | 
					
						
							|  |  |  | 							state = 4; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					/* falls through */ | 
					
						
							|  |  |  | 					case 4: | 
					
						
							|  |  |  | 						return DONE_ITERATOR_RESULT; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | /** @typedef {Map<string, FileSystemInfoEntry | null>} FileTimestamps */ | 
					
						
							|  |  |  | /** @typedef {Map<string, string | null>} FileHashes */ | 
					
						
							|  |  |  | /** @typedef {Map<string, TimestampAndHash | string | null>} FileTshs */ | 
					
						
							|  |  |  | /** @typedef {Map<string, ResolvedContextFileSystemInfoEntry | null>} ContextTimestamps */ | 
					
						
							|  |  |  | /** @typedef {Map<string, string | null>} ContextHashes */ | 
					
						
							|  |  |  | /** @typedef {Map<string, ResolvedContextTimestampAndHash | null>} ContextTshs */ | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | /** @typedef {Map<string, boolean>} MissingExistence */ | 
					
						
							|  |  |  | /** @typedef {Map<string, string>} ManagedItemInfo */ | 
					
						
							|  |  |  | /** @typedef {Set<string>} ManagedFiles */ | 
					
						
							|  |  |  | /** @typedef {Set<string>} ManagedContexts */ | 
					
						
							|  |  |  | /** @typedef {Set<string>} ManagedMissing */ | 
					
						
							|  |  |  | /** @typedef {Set<Snapshot>} Children */ | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | class Snapshot { | 
					
						
							|  |  |  | 	constructor() { | 
					
						
							|  |  |  | 		this._flags = 0; | 
					
						
							| 
									
										
										
										
											2022-07-02 00:57:17 +08:00
										 |  |  | 		/** @type {Iterable<string> | undefined} */ | 
					
						
							|  |  |  | 		this._cachedFileIterable = undefined; | 
					
						
							|  |  |  | 		/** @type {Iterable<string> | undefined} */ | 
					
						
							|  |  |  | 		this._cachedContextIterable = undefined; | 
					
						
							|  |  |  | 		/** @type {Iterable<string> | undefined} */ | 
					
						
							|  |  |  | 		this._cachedMissingIterable = undefined; | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		/** @type {number | undefined} */ | 
					
						
							|  |  |  | 		this.startTime = undefined; | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 		/** @type {FileTimestamps | undefined} */ | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		this.fileTimestamps = undefined; | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 		/** @type {FileHashes | undefined} */ | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		this.fileHashes = undefined; | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 		/** @type {FileTshs | undefined} */ | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		this.fileTshs = undefined; | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 		/** @type {ContextTimestamps | undefined} */ | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		this.contextTimestamps = undefined; | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 		/** @type {ContextHashes | undefined} */ | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		this.contextHashes = undefined; | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 		/** @type {ContextTshs | undefined} */ | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		this.contextTshs = undefined; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {MissingExistence | undefined} */ | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		this.missingExistence = undefined; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {ManagedItemInfo | undefined} */ | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		this.managedItemInfo = undefined; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {ManagedFiles | undefined} */ | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		this.managedFiles = undefined; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {ManagedContexts | undefined} */ | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		this.managedContexts = undefined; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {ManagedMissing | undefined} */ | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		this.managedMissing = undefined; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {Children | undefined} */ | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		this.children = undefined; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hasStartTime() { | 
					
						
							|  |  |  | 		return (this._flags & 1) !== 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {number} value start value | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 	setStartTime(value) { | 
					
						
							|  |  |  | 		this._flags = this._flags | 1; | 
					
						
							|  |  |  | 		this.startTime = value; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {number | undefined} value value | 
					
						
							|  |  |  | 	 * @param {Snapshot} snapshot snapshot | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 	setMergedStartTime(value, snapshot) { | 
					
						
							|  |  |  | 		if (value) { | 
					
						
							|  |  |  | 			if (snapshot.hasStartTime()) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				this.setStartTime( | 
					
						
							|  |  |  | 					Math.min( | 
					
						
							|  |  |  | 						value, | 
					
						
							|  |  |  | 						/** @type {NonNullable<Snapshot["startTime"]>} */ | 
					
						
							|  |  |  | 						(snapshot.startTime) | 
					
						
							|  |  |  | 					) | 
					
						
							|  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				this.setStartTime(value); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		} else if (snapshot.hasStartTime()) { | 
					
						
							|  |  |  | 			this.setStartTime( | 
					
						
							|  |  |  | 				/** @type {NonNullable<Snapshot["startTime"]>} */ | 
					
						
							|  |  |  | 				(snapshot.startTime) | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hasFileTimestamps() { | 
					
						
							|  |  |  | 		return (this._flags & 2) !== 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {FileTimestamps} value file timestamps | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 	setFileTimestamps(value) { | 
					
						
							|  |  |  | 		this._flags = this._flags | 2; | 
					
						
							|  |  |  | 		this.fileTimestamps = value; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hasFileHashes() { | 
					
						
							|  |  |  | 		return (this._flags & 4) !== 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {FileHashes} value file hashes | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 	setFileHashes(value) { | 
					
						
							|  |  |  | 		this._flags = this._flags | 4; | 
					
						
							|  |  |  | 		this.fileHashes = value; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 	hasFileTshs() { | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		return (this._flags & 8) !== 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {FileTshs} value file tshs | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 	setFileTshs(value) { | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		this._flags = this._flags | 8; | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		this.fileTshs = value; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hasContextTimestamps() { | 
					
						
							|  |  |  | 		return (this._flags & 0x10) !== 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {ContextTimestamps} value context timestamps | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 	setContextTimestamps(value) { | 
					
						
							|  |  |  | 		this._flags = this._flags | 0x10; | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		this.contextTimestamps = value; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hasContextHashes() { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		return (this._flags & 0x20) !== 0; | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {ContextHashes} value context hashes | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 	setContextHashes(value) { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		this._flags = this._flags | 0x20; | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		this.contextHashes = value; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 	hasContextTshs() { | 
					
						
							|  |  |  | 		return (this._flags & 0x40) !== 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {ContextTshs} value context tshs | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 	setContextTshs(value) { | 
					
						
							|  |  |  | 		this._flags = this._flags | 0x40; | 
					
						
							|  |  |  | 		this.contextTshs = value; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 	hasMissingExistence() { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		return (this._flags & 0x80) !== 0; | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {MissingExistence} value context tshs | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 	setMissingExistence(value) { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		this._flags = this._flags | 0x80; | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		this.missingExistence = value; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hasManagedItemInfo() { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		return (this._flags & 0x100) !== 0; | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {ManagedItemInfo} value managed item info | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 	setManagedItemInfo(value) { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		this._flags = this._flags | 0x100; | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		this.managedItemInfo = value; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 	hasManagedFiles() { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		return (this._flags & 0x200) !== 0; | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 	 * @param {ManagedFiles} value managed files | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 	setManagedFiles(value) { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		this._flags = this._flags | 0x200; | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		this.managedFiles = value; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hasManagedContexts() { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		return (this._flags & 0x400) !== 0; | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {ManagedContexts} value managed contexts | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 	setManagedContexts(value) { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		this._flags = this._flags | 0x400; | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		this.managedContexts = value; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hasManagedMissing() { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		return (this._flags & 0x800) !== 0; | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {ManagedMissing} value managed missing | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 	setManagedMissing(value) { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		this._flags = this._flags | 0x800; | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		this.managedMissing = value; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hasChildren() { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		return (this._flags & 0x1000) !== 0; | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {Children} value children | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 	setChildren(value) { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		this._flags = this._flags | 0x1000; | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		this.children = value; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {Snapshot} child children | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 	addChild(child) { | 
					
						
							|  |  |  | 		if (!this.hasChildren()) { | 
					
						
							|  |  |  | 			this.setChildren(new Set()); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {Children} */ | 
					
						
							|  |  |  | 		(this.children).add(child); | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-12 02:57:43 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {ObjectSerializerContext} context context | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 	serialize({ write }) { | 
					
						
							|  |  |  | 		write(this._flags); | 
					
						
							|  |  |  | 		if (this.hasStartTime()) write(this.startTime); | 
					
						
							|  |  |  | 		if (this.hasFileTimestamps()) write(this.fileTimestamps); | 
					
						
							|  |  |  | 		if (this.hasFileHashes()) write(this.fileHashes); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		if (this.hasFileTshs()) write(this.fileTshs); | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		if (this.hasContextTimestamps()) write(this.contextTimestamps); | 
					
						
							|  |  |  | 		if (this.hasContextHashes()) write(this.contextHashes); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		if (this.hasContextTshs()) write(this.contextTshs); | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		if (this.hasMissingExistence()) write(this.missingExistence); | 
					
						
							|  |  |  | 		if (this.hasManagedItemInfo()) write(this.managedItemInfo); | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		if (this.hasManagedFiles()) write(this.managedFiles); | 
					
						
							|  |  |  | 		if (this.hasManagedContexts()) write(this.managedContexts); | 
					
						
							|  |  |  | 		if (this.hasManagedMissing()) write(this.managedMissing); | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		if (this.hasChildren()) write(this.children); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-12 02:57:43 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {ObjectDeserializerContext} context context | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 	deserialize({ read }) { | 
					
						
							|  |  |  | 		this._flags = read(); | 
					
						
							|  |  |  | 		if (this.hasStartTime()) this.startTime = read(); | 
					
						
							|  |  |  | 		if (this.hasFileTimestamps()) this.fileTimestamps = read(); | 
					
						
							|  |  |  | 		if (this.hasFileHashes()) this.fileHashes = read(); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		if (this.hasFileTshs()) this.fileTshs = read(); | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		if (this.hasContextTimestamps()) this.contextTimestamps = read(); | 
					
						
							|  |  |  | 		if (this.hasContextHashes()) this.contextHashes = read(); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		if (this.hasContextTshs()) this.contextTshs = read(); | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		if (this.hasMissingExistence()) this.missingExistence = read(); | 
					
						
							|  |  |  | 		if (this.hasManagedItemInfo()) this.managedItemInfo = read(); | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		if (this.hasManagedFiles()) this.managedFiles = read(); | 
					
						
							|  |  |  | 		if (this.hasManagedContexts()) this.managedContexts = read(); | 
					
						
							|  |  |  | 		if (this.hasManagedMissing()) this.managedMissing = read(); | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		if (this.hasChildren()) this.children = read(); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 	 * @param {GetMapsFunction} getMaps first | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 	 * @returns {Iterable<string>} iterable | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 	_createIterable(getMaps) { | 
					
						
							| 
									
										
										
										
											2021-04-15 21:16:44 +08:00
										 |  |  | 		return new SnapshotIterable(this, getMaps); | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * @returns {Iterable<string>} iterable | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	getFileIterable() { | 
					
						
							| 
									
										
										
										
											2022-07-02 00:57:17 +08:00
										 |  |  | 		if (this._cachedFileIterable === undefined) { | 
					
						
							|  |  |  | 			this._cachedFileIterable = this._createIterable(s => [ | 
					
						
							|  |  |  | 				s.fileTimestamps, | 
					
						
							|  |  |  | 				s.fileHashes, | 
					
						
							|  |  |  | 				s.fileTshs, | 
					
						
							|  |  |  | 				s.managedFiles | 
					
						
							|  |  |  | 			]); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return this._cachedFileIterable; | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * @returns {Iterable<string>} iterable | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	getContextIterable() { | 
					
						
							| 
									
										
										
										
											2022-07-02 00:57:17 +08:00
										 |  |  | 		if (this._cachedContextIterable === undefined) { | 
					
						
							|  |  |  | 			this._cachedContextIterable = this._createIterable(s => [ | 
					
						
							|  |  |  | 				s.contextTimestamps, | 
					
						
							|  |  |  | 				s.contextHashes, | 
					
						
							|  |  |  | 				s.contextTshs, | 
					
						
							|  |  |  | 				s.managedContexts | 
					
						
							|  |  |  | 			]); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return this._cachedContextIterable; | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * @returns {Iterable<string>} iterable | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	getMissingIterable() { | 
					
						
							| 
									
										
										
										
											2022-07-02 00:57:17 +08:00
										 |  |  | 		if (this._cachedMissingIterable === undefined) { | 
					
						
							|  |  |  | 			this._cachedMissingIterable = this._createIterable(s => [ | 
					
						
							|  |  |  | 				s.missingExistence, | 
					
						
							|  |  |  | 				s.managedMissing | 
					
						
							|  |  |  | 			]); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return this._cachedMissingIterable; | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | makeSerializable(Snapshot, "webpack/lib/FileSystemInfo", "Snapshot"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | const MIN_COMMON_SNAPSHOT_SIZE = 3; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @template U, T | 
					
						
							|  |  |  |  * @typedef {U extends true ? Set<string> : Map<string, T>} SnapshotOptimizationValue | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @template T | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  |  * @template {boolean} [U=false] | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | class SnapshotOptimization { | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 	 * @param {function(Snapshot): boolean} has has value | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	 * @param {function(Snapshot): SnapshotOptimizationValue<U, T> | undefined} get get value | 
					
						
							|  |  |  | 	 * @param {function(Snapshot, SnapshotOptimizationValue<U, T>): void} set set value | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 	 * @param {boolean=} useStartTime use the start time of snapshots | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	 * @param {U=} isSet value is an Set instead of a Map | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 	constructor( | 
					
						
							|  |  |  | 		has, | 
					
						
							|  |  |  | 		get, | 
					
						
							|  |  |  | 		set, | 
					
						
							|  |  |  | 		useStartTime = true, | 
					
						
							|  |  |  | 		isSet = /** @type {U} */ (false) | 
					
						
							|  |  |  | 	) { | 
					
						
							|  |  |  | 		this._has = has; | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		this._get = get; | 
					
						
							|  |  |  | 		this._set = set; | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 		this._useStartTime = useStartTime; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {U} */ | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		this._isSet = isSet; | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 		/** @type {Map<string, SnapshotOptimizationEntry>} */ | 
					
						
							|  |  |  | 		this._map = new Map(); | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 		this._statItemsShared = 0; | 
					
						
							|  |  |  | 		this._statItemsUnshared = 0; | 
					
						
							|  |  |  | 		this._statSharedSnapshots = 0; | 
					
						
							| 
									
										
										
										
											2020-08-22 17:15:07 +08:00
										 |  |  | 		this._statReusedSharedSnapshots = 0; | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	getStatisticMessage() { | 
					
						
							|  |  |  | 		const total = this._statItemsShared + this._statItemsUnshared; | 
					
						
							| 
									
										
										
										
											2024-08-02 02:36:27 +08:00
										 |  |  | 		if (total === 0) return; | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 		return `${ | 
					
						
							|  |  |  | 			this._statItemsShared && Math.round((this._statItemsShared * 100) / total) | 
					
						
							|  |  |  | 		}% (${this._statItemsShared}/${total}) entries shared via ${ | 
					
						
							|  |  |  | 			this._statSharedSnapshots | 
					
						
							| 
									
										
										
										
											2020-08-22 17:15:07 +08:00
										 |  |  | 		} shared snapshots (${ | 
					
						
							|  |  |  | 			this._statReusedSharedSnapshots + this._statSharedSnapshots | 
					
						
							|  |  |  | 		} times referenced)`;
 | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-25 23:35:19 +08:00
										 |  |  | 	clear() { | 
					
						
							|  |  |  | 		this._map.clear(); | 
					
						
							|  |  |  | 		this._statItemsShared = 0; | 
					
						
							|  |  |  | 		this._statItemsUnshared = 0; | 
					
						
							|  |  |  | 		this._statSharedSnapshots = 0; | 
					
						
							|  |  |  | 		this._statReusedSharedSnapshots = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {Snapshot} newSnapshot snapshot | 
					
						
							|  |  |  | 	 * @param {Set<string>} capturedFiles files to snapshot/share | 
					
						
							|  |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	optimize(newSnapshot, capturedFiles) { | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {SnapshotOptimizationEntry} entry optimization entry | 
					
						
							|  |  |  | 		 * @returns {void} | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		const increaseSharedAndStoreOptimizationEntry = entry => { | 
					
						
							|  |  |  | 			if (entry.children !== undefined) { | 
					
						
							| 
									
										
										
										
											2024-08-02 02:36:27 +08:00
										 |  |  | 				for (const child of entry.children) { | 
					
						
							|  |  |  | 					increaseSharedAndStoreOptimizationEntry(child); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			entry.shared++; | 
					
						
							|  |  |  | 			storeOptimizationEntry(entry); | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {SnapshotOptimizationEntry} entry optimization entry | 
					
						
							|  |  |  | 		 * @returns {void} | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		const storeOptimizationEntry = entry => { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			for (const path of /** @type {SnapshotContent} */ ( | 
					
						
							|  |  |  | 				entry.snapshotContent | 
					
						
							|  |  |  | 			)) { | 
					
						
							|  |  |  | 				const old = | 
					
						
							|  |  |  | 					/** @type {SnapshotOptimizationEntry} */ | 
					
						
							|  |  |  | 					(this._map.get(path)); | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 				if (old.shared < entry.shared) { | 
					
						
							|  |  |  | 					this._map.set(path, entry); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				capturedFiles.delete(path); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-22 05:55:05 +08:00
										 |  |  | 		/** @type {SnapshotOptimizationEntry | undefined} */ | 
					
						
							| 
									
										
										
										
											2024-07-31 06:15:03 +08:00
										 |  |  | 		let newOptimizationEntry; | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 		const capturedFilesSize = capturedFiles.size; | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/** @type {Set<SnapshotOptimizationEntry> | undefined} */ | 
					
						
							|  |  |  | 		const optimizationEntries = new Set(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (const path of capturedFiles) { | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 			const optimizationEntry = this._map.get(path); | 
					
						
							|  |  |  | 			if (optimizationEntry === undefined) { | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 				if (newOptimizationEntry === undefined) { | 
					
						
							|  |  |  | 					newOptimizationEntry = { | 
					
						
							|  |  |  | 						snapshot: newSnapshot, | 
					
						
							|  |  |  | 						shared: 0, | 
					
						
							|  |  |  | 						snapshotContent: undefined, | 
					
						
							|  |  |  | 						children: undefined | 
					
						
							|  |  |  | 					}; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				this._map.set(path, newOptimizationEntry); | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 				continue; | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				optimizationEntries.add(optimizationEntry); | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-31 09:37:24 +08:00
										 |  |  | 		optimizationEntriesLabel: for (const optimizationEntry of optimizationEntries) { | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 			const snapshot = optimizationEntry.snapshot; | 
					
						
							|  |  |  | 			if (optimizationEntry.shared > 0) { | 
					
						
							|  |  |  | 				// It's a shared snapshot
 | 
					
						
							|  |  |  | 				// We can't change it, so we can only use it when all files match
 | 
					
						
							|  |  |  | 				// and startTime is compatible
 | 
					
						
							|  |  |  | 				if ( | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 					this._useStartTime && | 
					
						
							|  |  |  | 					newSnapshot.startTime && | 
					
						
							|  |  |  | 					(!snapshot.startTime || snapshot.startTime > newSnapshot.startTime) | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 				) { | 
					
						
							|  |  |  | 					continue; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				const nonSharedFiles = new Set(); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				const snapshotContent = | 
					
						
							|  |  |  | 					/** @type {NonNullable<SnapshotOptimizationEntry["snapshotContent"]>} */ | 
					
						
							|  |  |  | 					(optimizationEntry.snapshotContent); | 
					
						
							|  |  |  | 				const snapshotEntries = | 
					
						
							|  |  |  | 					/** @type {SnapshotOptimizationValue<U, T>} */ | 
					
						
							|  |  |  | 					(this._get(snapshot)); | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 				for (const path of snapshotContent) { | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 					if (!capturedFiles.has(path)) { | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 						if (!snapshotEntries.has(path)) { | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 							// File is not shared and can't be removed from the snapshot
 | 
					
						
							|  |  |  | 							// because it's in a child of the snapshot
 | 
					
						
							| 
									
										
										
										
											2024-07-31 09:37:24 +08:00
										 |  |  | 							continue optimizationEntriesLabel; | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 						} | 
					
						
							|  |  |  | 						nonSharedFiles.add(path); | 
					
						
							|  |  |  | 						continue; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (nonSharedFiles.size === 0) { | 
					
						
							|  |  |  | 					// The complete snapshot is shared
 | 
					
						
							|  |  |  | 					// add it as child
 | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 					newSnapshot.addChild(snapshot); | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 					increaseSharedAndStoreOptimizationEntry(optimizationEntry); | 
					
						
							| 
									
										
										
										
											2020-08-22 17:15:07 +08:00
										 |  |  | 					this._statReusedSharedSnapshots++; | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 				} else { | 
					
						
							|  |  |  | 					// Only a part of the snapshot is shared
 | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 					const sharedCount = snapshotContent.size - nonSharedFiles.size; | 
					
						
							|  |  |  | 					if (sharedCount < MIN_COMMON_SNAPSHOT_SIZE) { | 
					
						
							|  |  |  | 						// Common part it too small
 | 
					
						
							| 
									
										
										
										
											2024-07-31 09:37:24 +08:00
										 |  |  | 						continue; | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 					// Extract common timestamps from both snapshots
 | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 					let commonMap; | 
					
						
							|  |  |  | 					if (this._isSet) { | 
					
						
							|  |  |  | 						commonMap = new Set(); | 
					
						
							|  |  |  | 						for (const path of /** @type {Set<string>} */ (snapshotEntries)) { | 
					
						
							|  |  |  | 							if (nonSharedFiles.has(path)) continue; | 
					
						
							|  |  |  | 							commonMap.add(path); | 
					
						
							|  |  |  | 							snapshotEntries.delete(path); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						commonMap = new Map(); | 
					
						
							|  |  |  | 						const map = /** @type {Map<string, T>} */ (snapshotEntries); | 
					
						
							|  |  |  | 						for (const [path, value] of map) { | 
					
						
							|  |  |  | 							if (nonSharedFiles.has(path)) continue; | 
					
						
							|  |  |  | 							commonMap.set(path, value); | 
					
						
							|  |  |  | 							snapshotEntries.delete(path); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					// Create and attach snapshot
 | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 					const commonSnapshot = new Snapshot(); | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 					if (this._useStartTime) { | 
					
						
							|  |  |  | 						commonSnapshot.setMergedStartTime(newSnapshot.startTime, snapshot); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 					this._set( | 
					
						
							|  |  |  | 						commonSnapshot, | 
					
						
							|  |  |  | 						/** @type {SnapshotOptimizationValue<U, T>} */ (commonMap) | 
					
						
							|  |  |  | 					); | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 					newSnapshot.addChild(commonSnapshot); | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 					snapshot.addChild(commonSnapshot); | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 					// Create optimization entry
 | 
					
						
							|  |  |  | 					const newEntry = { | 
					
						
							|  |  |  | 						snapshot: commonSnapshot, | 
					
						
							|  |  |  | 						shared: optimizationEntry.shared + 1, | 
					
						
							|  |  |  | 						snapshotContent: new Set(commonMap.keys()), | 
					
						
							|  |  |  | 						children: undefined | 
					
						
							|  |  |  | 					}; | 
					
						
							|  |  |  | 					if (optimizationEntry.children === undefined) | 
					
						
							|  |  |  | 						optimizationEntry.children = new Set(); | 
					
						
							|  |  |  | 					optimizationEntry.children.add(newEntry); | 
					
						
							|  |  |  | 					storeOptimizationEntry(newEntry); | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 					this._statSharedSnapshots++; | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				// It's a unshared snapshot
 | 
					
						
							|  |  |  | 				// We can extract a common shared snapshot
 | 
					
						
							|  |  |  | 				// with all common files
 | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 				const snapshotEntries = this._get(snapshot); | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 				if (snapshotEntries === undefined) { | 
					
						
							|  |  |  | 					// Incomplete snapshot, that can't be used
 | 
					
						
							| 
									
										
										
										
											2024-07-31 09:37:24 +08:00
										 |  |  | 					continue; | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 				let commonMap; | 
					
						
							|  |  |  | 				if (this._isSet) { | 
					
						
							|  |  |  | 					commonMap = new Set(); | 
					
						
							|  |  |  | 					const set = /** @type {Set<string>} */ (snapshotEntries); | 
					
						
							|  |  |  | 					if (capturedFiles.size < set.size) { | 
					
						
							|  |  |  | 						for (const path of capturedFiles) { | 
					
						
							|  |  |  | 							if (set.has(path)) commonMap.add(path); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						for (const path of set) { | 
					
						
							|  |  |  | 							if (capturedFiles.has(path)) commonMap.add(path); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					commonMap = new Map(); | 
					
						
							|  |  |  | 					const map = /** @type {Map<string, T>} */ (snapshotEntries); | 
					
						
							|  |  |  | 					for (const path of capturedFiles) { | 
					
						
							|  |  |  | 						const ts = map.get(path); | 
					
						
							|  |  |  | 						if (ts === undefined) continue; | 
					
						
							|  |  |  | 						commonMap.set(path, ts); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 				if (commonMap.size < MIN_COMMON_SNAPSHOT_SIZE) { | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 					// Common part it too small
 | 
					
						
							| 
									
										
										
										
											2024-07-31 09:37:24 +08:00
										 |  |  | 					continue; | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				// Create and attach snapshot
 | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 				const commonSnapshot = new Snapshot(); | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 				if (this._useStartTime) { | 
					
						
							|  |  |  | 					commonSnapshot.setMergedStartTime(newSnapshot.startTime, snapshot); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				this._set( | 
					
						
							|  |  |  | 					commonSnapshot, | 
					
						
							|  |  |  | 					/** @type {SnapshotOptimizationValue<U, T>} */ | 
					
						
							|  |  |  | 					(commonMap) | 
					
						
							|  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 				newSnapshot.addChild(commonSnapshot); | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 				snapshot.addChild(commonSnapshot); | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 				// Remove files from snapshot
 | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 				for (const path of commonMap.keys()) snapshotEntries.delete(path); | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 				const sharedCount = commonMap.size; | 
					
						
							|  |  |  | 				this._statItemsUnshared -= sharedCount; | 
					
						
							|  |  |  | 				this._statItemsShared += sharedCount; | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 				// Create optimization entry
 | 
					
						
							|  |  |  | 				storeOptimizationEntry({ | 
					
						
							|  |  |  | 					snapshot: commonSnapshot, | 
					
						
							|  |  |  | 					shared: 2, | 
					
						
							|  |  |  | 					snapshotContent: new Set(commonMap.keys()), | 
					
						
							|  |  |  | 					children: undefined | 
					
						
							|  |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 				this._statSharedSnapshots++; | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 		const unshared = capturedFiles.size; | 
					
						
							|  |  |  | 		this._statItemsUnshared += unshared; | 
					
						
							|  |  |  | 		this._statItemsShared += capturedFilesSize - unshared; | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {string} str input | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  |  * @returns {string} result | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-11-09 19:24:53 +08:00
										 |  |  | const parseString = str => { | 
					
						
							| 
									
										
										
										
											2024-01-05 23:18:42 +08:00
										 |  |  | 	if (str[0] === "'" || str[0] === "`") | 
					
						
							|  |  |  | 		str = `"${str.slice(1, -1).replace(/"/g, '\\"')}"`; | 
					
						
							| 
									
										
										
										
											2021-11-09 19:24:53 +08:00
										 |  |  | 	return JSON.parse(str); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-23 16:48:36 +08:00
										 |  |  | /* istanbul ignore next */ | 
					
						
							| 
									
										
										
										
											2019-10-20 17:35:36 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {number} mtime mtime | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | const applyMtime = mtime => { | 
					
						
							|  |  |  | 	if (FS_ACCURACY > 1 && mtime % 2 !== 0) FS_ACCURACY = 1; | 
					
						
							|  |  |  | 	else if (FS_ACCURACY > 10 && mtime % 20 !== 0) FS_ACCURACY = 10; | 
					
						
							|  |  |  | 	else if (FS_ACCURACY > 100 && mtime % 200 !== 0) FS_ACCURACY = 100; | 
					
						
							|  |  |  | 	else if (FS_ACCURACY > 1000 && mtime % 2000 !== 0) FS_ACCURACY = 1000; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 17:35:36 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @template T | 
					
						
							|  |  |  |  * @template K | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  |  * @param {Map<T, K> | undefined} a source map | 
					
						
							|  |  |  |  * @param {Map<T, K> | undefined} b joining map | 
					
						
							| 
									
										
										
										
											2019-10-20 17:35:36 +08:00
										 |  |  |  * @returns {Map<T, K>} joined map | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | const mergeMaps = (a, b) => { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	if (!b || b.size === 0) return /** @type {Map<T, K>} */ (a); | 
					
						
							|  |  |  | 	if (!a || a.size === 0) return /** @type {Map<T, K>} */ (b); | 
					
						
							|  |  |  | 	/** @type {Map<T, K>} */ | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 	const map = new Map(a); | 
					
						
							|  |  |  | 	for (const [key, value] of b) { | 
					
						
							|  |  |  | 		map.set(key, value); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return map; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @template T | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  |  * @param {Set<T> | undefined} a source map | 
					
						
							|  |  |  |  * @param {Set<T> | undefined} b joining map | 
					
						
							| 
									
										
										
										
											2023-06-22 05:55:05 +08:00
										 |  |  |  * @returns {Set<T>} joined map | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | const mergeSets = (a, b) => { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	if (!b || b.size === 0) return /** @type {Set<T>} */ (a); | 
					
						
							|  |  |  | 	if (!a || a.size === 0) return /** @type {Set<T>} */ (b); | 
					
						
							|  |  |  | 	/** @type {Set<T>} */ | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 	const map = new Set(a); | 
					
						
							|  |  |  | 	for (const item of b) { | 
					
						
							|  |  |  | 		map.add(item); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return map; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 17:35:36 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Finding file or directory to manage | 
					
						
							|  |  |  |  * @param {string} managedPath path that is managing by {@link FileSystemInfo} | 
					
						
							|  |  |  |  * @param {string} path path to file or directory | 
					
						
							|  |  |  |  * @returns {string|null} managed item | 
					
						
							|  |  |  |  * @example | 
					
						
							|  |  |  |  * getManagedItem( | 
					
						
							| 
									
										
										
										
											2019-10-20 20:53:17 +08:00
										 |  |  |  *   '/Users/user/my-project/node_modules/', | 
					
						
							| 
									
										
										
										
											2019-10-20 17:35:36 +08:00
										 |  |  |  *   '/Users/user/my-project/node_modules/package/index.js' | 
					
						
							|  |  |  |  * ) === '/Users/user/my-project/node_modules/package' | 
					
						
							|  |  |  |  * getManagedItem( | 
					
						
							| 
									
										
										
										
											2019-10-20 20:53:17 +08:00
										 |  |  |  *   '/Users/user/my-project/node_modules/', | 
					
						
							|  |  |  |  *   '/Users/user/my-project/node_modules/package1/node_modules/package2' | 
					
						
							|  |  |  |  * ) === '/Users/user/my-project/node_modules/package1/node_modules/package2' | 
					
						
							|  |  |  |  * getManagedItem( | 
					
						
							|  |  |  |  *   '/Users/user/my-project/node_modules/', | 
					
						
							|  |  |  |  *   '/Users/user/my-project/node_modules/.bin/script.js' | 
					
						
							| 
									
										
										
										
											2019-10-20 17:35:36 +08:00
										 |  |  |  * ) === null // hidden files are disallowed as managed items
 | 
					
						
							|  |  |  |  * getManagedItem( | 
					
						
							| 
									
										
										
										
											2019-10-20 20:53:17 +08:00
										 |  |  |  *   '/Users/user/my-project/node_modules/', | 
					
						
							|  |  |  |  *   '/Users/user/my-project/node_modules/package' | 
					
						
							|  |  |  |  * ) === '/Users/user/my-project/node_modules/package' | 
					
						
							| 
									
										
										
										
											2019-10-20 17:35:36 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | const getManagedItem = (managedPath, path) => { | 
					
						
							| 
									
										
										
										
											2019-08-13 23:15:47 +08:00
										 |  |  | 	let i = managedPath.length; | 
					
						
							| 
									
										
										
										
											2019-08-13 23:58:51 +08:00
										 |  |  | 	let slashes = 1; | 
					
						
							| 
									
										
										
										
											2019-09-08 21:26:40 +08:00
										 |  |  | 	let startingPosition = true; | 
					
						
							| 
									
										
										
										
											2019-08-13 23:15:47 +08:00
										 |  |  | 	loop: while (i < path.length) { | 
					
						
							|  |  |  | 		switch (path.charCodeAt(i)) { | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 			case 47: // slash
 | 
					
						
							|  |  |  | 			case 92: // backslash
 | 
					
						
							|  |  |  | 				if (--slashes === 0) break loop; | 
					
						
							| 
									
										
										
										
											2019-09-08 21:26:40 +08:00
										 |  |  | 				startingPosition = true; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case 46: // .
 | 
					
						
							|  |  |  | 				// hidden files are disallowed as managed items
 | 
					
						
							|  |  |  | 				// it's probably .yarn-integrity or .cache
 | 
					
						
							|  |  |  | 				if (startingPosition) return null; | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			case 64: // @
 | 
					
						
							| 
									
										
										
										
											2019-09-08 21:26:40 +08:00
										 |  |  | 				if (!startingPosition) return null; | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 				slashes++; | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2019-09-08 21:26:40 +08:00
										 |  |  | 			default: | 
					
						
							|  |  |  | 				startingPosition = false; | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		i++; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 	if (i === path.length) slashes--; | 
					
						
							|  |  |  | 	// return null when path is incomplete
 | 
					
						
							|  |  |  | 	if (slashes !== 0) return null; | 
					
						
							| 
									
										
										
										
											2019-08-13 23:58:51 +08:00
										 |  |  | 	// if (path.slice(i + 1, i + 13) === "node_modules")
 | 
					
						
							|  |  |  | 	if ( | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 		path.length >= i + 13 && | 
					
						
							| 
									
										
										
										
											2019-08-13 23:58:51 +08:00
										 |  |  | 		path.charCodeAt(i + 1) === 110 && | 
					
						
							|  |  |  | 		path.charCodeAt(i + 2) === 111 && | 
					
						
							|  |  |  | 		path.charCodeAt(i + 3) === 100 && | 
					
						
							|  |  |  | 		path.charCodeAt(i + 4) === 101 && | 
					
						
							|  |  |  | 		path.charCodeAt(i + 5) === 95 && | 
					
						
							|  |  |  | 		path.charCodeAt(i + 6) === 109 && | 
					
						
							|  |  |  | 		path.charCodeAt(i + 7) === 111 && | 
					
						
							|  |  |  | 		path.charCodeAt(i + 8) === 100 && | 
					
						
							|  |  |  | 		path.charCodeAt(i + 9) === 117 && | 
					
						
							|  |  |  | 		path.charCodeAt(i + 10) === 108 && | 
					
						
							|  |  |  | 		path.charCodeAt(i + 11) === 101 && | 
					
						
							|  |  |  | 		path.charCodeAt(i + 12) === 115 | 
					
						
							|  |  |  | 	) { | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 		// if this is the end of the path
 | 
					
						
							|  |  |  | 		if (path.length === i + 13) { | 
					
						
							|  |  |  | 			// return the node_modules directory
 | 
					
						
							|  |  |  | 			// it's special
 | 
					
						
							|  |  |  | 			return path; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-08-13 23:58:51 +08:00
										 |  |  | 		const c = path.charCodeAt(i + 13); | 
					
						
							| 
									
										
										
										
											2019-10-20 17:35:36 +08:00
										 |  |  | 		// if next symbol is slash or backslash
 | 
					
						
							| 
									
										
										
										
											2019-08-13 23:58:51 +08:00
										 |  |  | 		if (c === 47 || c === 92) { | 
					
						
							|  |  |  | 			// Managed subpath
 | 
					
						
							|  |  |  | 			return getManagedItem(path.slice(0, i + 14), path); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-08-13 23:15:47 +08:00
										 |  |  | 	return path.slice(0, i); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 23:49:45 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  |  * @template {ContextFileSystemInfoEntry | ContextTimestampAndHash} T | 
					
						
							| 
									
										
										
										
											2023-06-22 05:55:05 +08:00
										 |  |  |  * @param {T | null} entry entry | 
					
						
							|  |  |  |  * @returns {T["resolved"] | null | undefined} the resolved entry | 
					
						
							| 
									
										
										
										
											2019-11-14 23:49:45 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | const getResolvedTimestamp = entry => { | 
					
						
							| 
									
										
										
										
											2021-08-26 22:03:27 +08:00
										 |  |  | 	if (entry === null) return null; | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 	if (entry.resolved !== undefined) return entry.resolved; | 
					
						
							|  |  |  | 	return entry.symlinks === undefined ? entry : undefined; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2023-06-22 05:55:05 +08:00
										 |  |  |  * @param {ContextHash | null} entry entry | 
					
						
							|  |  |  |  * @returns {string | null | undefined} the resolved entry | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | const getResolvedHash = entry => { | 
					
						
							| 
									
										
										
										
											2021-08-26 22:03:27 +08:00
										 |  |  | 	if (entry === null) return null; | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 	if (entry.resolved !== undefined) return entry.resolved; | 
					
						
							|  |  |  | 	return entry.symlinks === undefined ? entry.hash : undefined; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-22 08:59:10 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @template T | 
					
						
							|  |  |  |  * @param {Set<T>} source source | 
					
						
							|  |  |  |  * @param {Set<T>} target target | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | const addAll = (source, target) => { | 
					
						
							|  |  |  | 	for (const key of source) target.add(key); | 
					
						
							| 
									
										
										
										
											2019-11-14 23:49:45 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | /** @typedef {Set<string>} LoggedPaths */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 17:35:36 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Used to access information about the filesystem in a cached way | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | class FileSystemInfo { | 
					
						
							| 
									
										
										
										
											2019-07-18 05:35:05 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {InputFileSystem} fs file system | 
					
						
							| 
									
										
										
										
											2024-06-11 21:09:50 +08:00
										 |  |  | 	 * @param {object} options options | 
					
						
							| 
									
										
										
										
											2023-09-28 04:17:11 +08:00
										 |  |  | 	 * @param {Iterable<string | RegExp>=} options.unmanagedPaths paths that are not managed by a package manager and the contents are subject to change | 
					
						
							| 
									
										
										
										
											2021-10-18 22:07:41 +08:00
										 |  |  | 	 * @param {Iterable<string | RegExp>=} options.managedPaths paths that are only managed by a package manager | 
					
						
							|  |  |  | 	 * @param {Iterable<string | RegExp>=} options.immutablePaths paths that are immutable | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 	 * @param {Logger=} options.logger logger used to log invalid snapshots | 
					
						
							| 
									
										
										
										
											2021-09-22 18:12:46 +08:00
										 |  |  | 	 * @param {string | Hash=} options.hashFunction the hash function to use | 
					
						
							| 
									
										
										
										
											2019-07-18 05:35:05 +08:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2021-09-22 18:12:46 +08:00
										 |  |  | 	constructor( | 
					
						
							|  |  |  | 		fs, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-09-28 04:17:11 +08:00
										 |  |  | 			unmanagedPaths = [], | 
					
						
							| 
									
										
										
										
											2021-09-22 18:12:46 +08:00
										 |  |  | 			managedPaths = [], | 
					
						
							|  |  |  | 			immutablePaths = [], | 
					
						
							|  |  |  | 			logger, | 
					
						
							|  |  |  | 			hashFunction = "md4" | 
					
						
							|  |  |  | 		} = {} | 
					
						
							|  |  |  | 	) { | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 		this.fs = fs; | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 		this.logger = logger; | 
					
						
							|  |  |  | 		this._remainingLogs = logger ? 40 : 0; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {LoggedPaths | undefined} */ | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 		this._loggedPaths = logger ? new Set() : undefined; | 
					
						
							| 
									
										
										
										
											2021-09-22 18:12:46 +08:00
										 |  |  | 		this._hashFunction = hashFunction; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {WeakMap<Snapshot, boolean | (function((WebpackError | null)=, boolean=): void)[]>} */ | 
					
						
							| 
									
										
										
										
											2019-10-27 14:38:06 +08:00
										 |  |  | 		this._snapshotCache = new WeakMap(); | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 		this._fileTimestampsOptimization = new SnapshotOptimization( | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 			s => s.hasFileTimestamps(), | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 			s => s.fileTimestamps, | 
					
						
							|  |  |  | 			(s, v) => s.setFileTimestamps(v) | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 		this._fileHashesOptimization = new SnapshotOptimization( | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 			s => s.hasFileHashes(), | 
					
						
							|  |  |  | 			s => s.fileHashes, | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 			(s, v) => s.setFileHashes(v), | 
					
						
							|  |  |  | 			false | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		this._fileTshsOptimization = new SnapshotOptimization( | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 			s => s.hasFileTshs(), | 
					
						
							|  |  |  | 			s => s.fileTshs, | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 			(s, v) => s.setFileTshs(v) | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2020-08-20 17:41:20 +08:00
										 |  |  | 		this._contextTimestampsOptimization = new SnapshotOptimization( | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 			s => s.hasContextTimestamps(), | 
					
						
							|  |  |  | 			s => s.contextTimestamps, | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 			(s, v) => s.setContextTimestamps(v) | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 		this._contextHashesOptimization = new SnapshotOptimization( | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 			s => s.hasContextHashes(), | 
					
						
							|  |  |  | 			s => s.contextHashes, | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 			(s, v) => s.setContextHashes(v), | 
					
						
							|  |  |  | 			false | 
					
						
							| 
									
										
										
										
											2020-08-20 17:41:20 +08:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		this._contextTshsOptimization = new SnapshotOptimization( | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 			s => s.hasContextTshs(), | 
					
						
							|  |  |  | 			s => s.contextTshs, | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 			(s, v) => s.setContextTshs(v) | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2020-08-20 17:41:20 +08:00
										 |  |  | 		this._missingExistenceOptimization = new SnapshotOptimization( | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 			s => s.hasMissingExistence(), | 
					
						
							|  |  |  | 			s => s.missingExistence, | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 			(s, v) => s.setMissingExistence(v), | 
					
						
							|  |  |  | 			false | 
					
						
							| 
									
										
										
										
											2020-08-20 17:41:20 +08:00
										 |  |  | 		); | 
					
						
							|  |  |  | 		this._managedItemInfoOptimization = new SnapshotOptimization( | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 			s => s.hasManagedItemInfo(), | 
					
						
							|  |  |  | 			s => s.managedItemInfo, | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 			(s, v) => s.setManagedItemInfo(v), | 
					
						
							|  |  |  | 			false | 
					
						
							| 
									
										
										
										
											2020-08-20 17:41:20 +08:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		this._managedFilesOptimization = new SnapshotOptimization( | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 			s => s.hasManagedFiles(), | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 			s => s.managedFiles, | 
					
						
							|  |  |  | 			(s, v) => s.setManagedFiles(v), | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 			false, | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 			true | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 		this._managedContextsOptimization = new SnapshotOptimization( | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 			s => s.hasManagedContexts(), | 
					
						
							|  |  |  | 			s => s.managedContexts, | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 			(s, v) => s.setManagedContexts(v), | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 			false, | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 			true | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 		this._managedMissingOptimization = new SnapshotOptimization( | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 			s => s.hasManagedMissing(), | 
					
						
							|  |  |  | 			s => s.managedMissing, | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 			(s, v) => s.setManagedMissing(v), | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 			false, | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 			true | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2021-07-16 19:05:18 +08:00
										 |  |  | 		/** @type {StackedCacheMap<string, FileSystemInfoEntry | "ignore" | null>} */ | 
					
						
							|  |  |  | 		this._fileTimestamps = new StackedCacheMap(); | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 		/** @type {Map<string, string | null>} */ | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 		this._fileHashes = new Map(); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		/** @type {Map<string, TimestampAndHash | string>} */ | 
					
						
							|  |  |  | 		this._fileTshs = new Map(); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 		/** @type {StackedCacheMap<string, ContextFileSystemInfoEntry | "ignore" | null>} */ | 
					
						
							| 
									
										
										
										
											2021-07-16 19:05:18 +08:00
										 |  |  | 		this._contextTimestamps = new StackedCacheMap(); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 		/** @type {Map<string, ContextHash>} */ | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 		this._contextHashes = new Map(); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 		/** @type {Map<string, ContextTimestampAndHash>} */ | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		this._contextTshs = new Map(); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 		/** @type {Map<string, string>} */ | 
					
						
							|  |  |  | 		this._managedItems = new Map(); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {AsyncQueue<string, string, FileSystemInfoEntry>} */ | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 		this.fileTimestampQueue = new AsyncQueue({ | 
					
						
							|  |  |  | 			name: "file timestamp", | 
					
						
							|  |  |  | 			parallelism: 30, | 
					
						
							|  |  |  | 			processor: this._readFileTimestamp.bind(this) | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {AsyncQueue<string, string, string>} */ | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 		this.fileHashQueue = new AsyncQueue({ | 
					
						
							|  |  |  | 			name: "file hash", | 
					
						
							|  |  |  | 			parallelism: 10, | 
					
						
							|  |  |  | 			processor: this._readFileHash.bind(this) | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {AsyncQueue<string, string, ContextFileSystemInfoEntry>} */ | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 		this.contextTimestampQueue = new AsyncQueue({ | 
					
						
							|  |  |  | 			name: "context timestamp", | 
					
						
							|  |  |  | 			parallelism: 2, | 
					
						
							|  |  |  | 			processor: this._readContextTimestamp.bind(this) | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {AsyncQueue<string, string, ContextHash>} */ | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 		this.contextHashQueue = new AsyncQueue({ | 
					
						
							|  |  |  | 			name: "context hash", | 
					
						
							|  |  |  | 			parallelism: 2, | 
					
						
							|  |  |  | 			processor: this._readContextHash.bind(this) | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {AsyncQueue<string, string, ContextTimestampAndHash>} */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 		this.contextTshQueue = new AsyncQueue({ | 
					
						
							|  |  |  | 			name: "context hash and timestamp", | 
					
						
							|  |  |  | 			parallelism: 2, | 
					
						
							|  |  |  | 			processor: this._readContextTimestampAndHash.bind(this) | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {AsyncQueue<string, string, string>} */ | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 		this.managedItemQueue = new AsyncQueue({ | 
					
						
							|  |  |  | 			name: "managed item info", | 
					
						
							|  |  |  | 			parallelism: 10, | 
					
						
							|  |  |  | 			processor: this._getManagedItemInfo.bind(this) | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2020-01-28 21:01:19 +08:00
										 |  |  | 		/** @type {AsyncQueue<string, string, Set<string>>} */ | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 		this.managedItemDirectoryQueue = new AsyncQueue({ | 
					
						
							|  |  |  | 			name: "managed item directory info", | 
					
						
							|  |  |  | 			parallelism: 10, | 
					
						
							|  |  |  | 			processor: this._getManagedItemDirectoryInfo.bind(this) | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2023-09-28 04:17:11 +08:00
										 |  |  | 		const _unmanagedPaths = Array.from(unmanagedPaths); | 
					
						
							|  |  |  | 		this.unmanagedPathsWithSlash = /** @type {string[]} */ ( | 
					
						
							|  |  |  | 			_unmanagedPaths.filter(p => typeof p === "string") | 
					
						
							|  |  |  | 		).map(p => join(fs, p, "_").slice(0, -1)); | 
					
						
							|  |  |  | 		this.unmanagedPathsRegExps = /** @type {RegExp[]} */ ( | 
					
						
							|  |  |  | 			_unmanagedPaths.filter(p => typeof p !== "string") | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 		this.managedPaths = Array.from(managedPaths); | 
					
						
							| 
									
										
										
										
											2021-10-18 22:07:41 +08:00
										 |  |  | 		this.managedPathsWithSlash = /** @type {string[]} */ ( | 
					
						
							|  |  |  | 			this.managedPaths.filter(p => typeof p === "string") | 
					
						
							|  |  |  | 		).map(p => join(fs, p, "_").slice(0, -1)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		this.managedPathsRegExps = /** @type {RegExp[]} */ ( | 
					
						
							|  |  |  | 			this.managedPaths.filter(p => typeof p !== "string") | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2019-08-16 17:55:10 +08:00
										 |  |  | 		this.immutablePaths = Array.from(immutablePaths); | 
					
						
							| 
									
										
										
										
											2021-10-18 22:07:41 +08:00
										 |  |  | 		this.immutablePathsWithSlash = /** @type {string[]} */ ( | 
					
						
							|  |  |  | 			this.immutablePaths.filter(p => typeof p === "string") | 
					
						
							|  |  |  | 		).map(p => join(fs, p, "_").slice(0, -1)); | 
					
						
							|  |  |  | 		this.immutablePathsRegExps = /** @type {RegExp[]} */ ( | 
					
						
							|  |  |  | 			this.immutablePaths.filter(p => typeof p !== "string") | 
					
						
							| 
									
										
										
										
											2019-08-16 17:55:10 +08:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-15 20:39:09 +08:00
										 |  |  | 		this._cachedDeprecatedFileTimestamps = undefined; | 
					
						
							|  |  |  | 		this._cachedDeprecatedContextTimestamps = undefined; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-14 04:16:55 +08:00
										 |  |  | 		this._warnAboutExperimentalEsmTracking = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 		this._statCreatedSnapshots = 0; | 
					
						
							|  |  |  | 		this._statTestedSnapshotsCached = 0; | 
					
						
							|  |  |  | 		this._statTestedSnapshotsNotCached = 0; | 
					
						
							|  |  |  | 		this._statTestedChildrenCached = 0; | 
					
						
							|  |  |  | 		this._statTestedChildrenNotCached = 0; | 
					
						
							|  |  |  | 		this._statTestedEntries = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	logStatistics() { | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 		const logger = /** @type {Logger} */ (this.logger); | 
					
						
							|  |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {string} header header | 
					
						
							|  |  |  | 		 * @param {string | undefined} message message | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		const logWhenMessage = (header, message) => { | 
					
						
							|  |  |  | 			if (message) { | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 				logger.log(`${header}: ${message}`); | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 		logger.log(`${this._statCreatedSnapshots} new snapshots created`); | 
					
						
							|  |  |  | 		logger.log( | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 			`${ | 
					
						
							| 
									
										
										
										
											2020-08-22 17:15:07 +08:00
										 |  |  | 				this._statTestedSnapshotsNotCached && | 
					
						
							|  |  |  | 				Math.round( | 
					
						
							|  |  |  | 					(this._statTestedSnapshotsNotCached * 100) / | 
					
						
							|  |  |  | 						(this._statTestedSnapshotsCached + | 
					
						
							|  |  |  | 							this._statTestedSnapshotsNotCached) | 
					
						
							|  |  |  | 				) | 
					
						
							|  |  |  | 			}% root snapshot uncached (${this._statTestedSnapshotsNotCached} / ${ | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 				this._statTestedSnapshotsCached + this._statTestedSnapshotsNotCached | 
					
						
							| 
									
										
										
										
											2020-08-22 17:15:07 +08:00
										 |  |  | 			})`
 | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 		logger.log( | 
					
						
							| 
									
										
										
										
											2020-08-22 17:15:07 +08:00
										 |  |  | 			`${ | 
					
						
							|  |  |  | 				this._statTestedChildrenNotCached && | 
					
						
							|  |  |  | 				Math.round( | 
					
						
							|  |  |  | 					(this._statTestedChildrenNotCached * 100) / | 
					
						
							|  |  |  | 						(this._statTestedChildrenCached + this._statTestedChildrenNotCached) | 
					
						
							|  |  |  | 				) | 
					
						
							|  |  |  | 			}% children snapshot uncached (${this._statTestedChildrenNotCached} / ${ | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 				this._statTestedChildrenCached + this._statTestedChildrenNotCached | 
					
						
							| 
									
										
										
										
											2020-08-22 17:15:07 +08:00
										 |  |  | 			})`
 | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 		logger.log(`${this._statTestedEntries} entries tested`); | 
					
						
							|  |  |  | 		logger.log( | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 			`File info in cache: ${this._fileTimestamps.size} timestamps ${this._fileHashes.size} hashes ${this._fileTshs.size} timestamp hash combinations` | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		logWhenMessage( | 
					
						
							| 
									
										
										
										
											2024-07-31 12:23:44 +08:00
										 |  |  | 			"File timestamp snapshot optimization", | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 			this._fileTimestampsOptimization.getStatisticMessage() | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		logWhenMessage( | 
					
						
							| 
									
										
										
										
											2024-07-31 12:23:44 +08:00
										 |  |  | 			"File hash snapshot optimization", | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 			this._fileHashesOptimization.getStatisticMessage() | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		logWhenMessage( | 
					
						
							| 
									
										
										
										
											2024-07-31 12:23:44 +08:00
										 |  |  | 			"File timestamp hash combination snapshot optimization", | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 			this._fileTshsOptimization.getStatisticMessage() | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 		logger.log( | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 			`Directory info in cache: ${this._contextTimestamps.size} timestamps ${this._contextHashes.size} hashes ${this._contextTshs.size} timestamp hash combinations` | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		logWhenMessage( | 
					
						
							| 
									
										
										
										
											2024-07-31 12:23:44 +08:00
										 |  |  | 			"Directory timestamp snapshot optimization", | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 			this._contextTimestampsOptimization.getStatisticMessage() | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		logWhenMessage( | 
					
						
							| 
									
										
										
										
											2024-07-31 12:23:44 +08:00
										 |  |  | 			"Directory hash snapshot optimization", | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 			this._contextHashesOptimization.getStatisticMessage() | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		logWhenMessage( | 
					
						
							| 
									
										
										
										
											2024-07-31 12:23:44 +08:00
										 |  |  | 			"Directory timestamp hash combination snapshot optimization", | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 			this._contextTshsOptimization.getStatisticMessage() | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		logWhenMessage( | 
					
						
							| 
									
										
										
										
											2024-07-31 12:23:44 +08:00
										 |  |  | 			"Missing items snapshot optimization", | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 			this._missingExistenceOptimization.getStatisticMessage() | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 		logger.log(`Managed items info in cache: ${this._managedItems.size} items`); | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		logWhenMessage( | 
					
						
							| 
									
										
										
										
											2024-07-31 12:23:44 +08:00
										 |  |  | 			"Managed items snapshot optimization", | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 			this._managedItemInfoOptimization.getStatisticMessage() | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 		logWhenMessage( | 
					
						
							| 
									
										
										
										
											2024-07-31 12:23:44 +08:00
										 |  |  | 			"Managed files snapshot optimization", | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 			this._managedFilesOptimization.getStatisticMessage() | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 		logWhenMessage( | 
					
						
							| 
									
										
										
										
											2024-07-31 12:23:44 +08:00
										 |  |  | 			"Managed contexts snapshot optimization", | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 			this._managedContextsOptimization.getStatisticMessage() | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 		logWhenMessage( | 
					
						
							| 
									
										
										
										
											2024-07-31 12:23:44 +08:00
										 |  |  | 			"Managed missing snapshot optimization", | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 			this._managedMissingOptimization.getStatisticMessage() | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-22 08:59:10 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {string} path path | 
					
						
							|  |  |  | 	 * @param {string} reason reason | 
					
						
							| 
									
										
										
										
											2023-06-22 09:08:40 +08:00
										 |  |  | 	 * @param {any[]} args arguments | 
					
						
							| 
									
										
										
										
											2023-06-22 08:59:10 +08:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2019-11-15 00:28:10 +08:00
										 |  |  | 	_log(path, reason, ...args) { | 
					
						
							|  |  |  | 		const key = path + reason; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		const loggedPaths = /** @type {LoggedPaths} */ (this._loggedPaths); | 
					
						
							|  |  |  | 		if (loggedPaths.has(key)) return; | 
					
						
							|  |  |  | 		loggedPaths.add(key); | 
					
						
							|  |  |  | 		/** @type {Logger} */ | 
					
						
							|  |  |  | 		(this.logger).debug(`${path} invalidated because ${reason}`, ...args); | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 		if (--this._remainingLogs === 0) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			/** @type {Logger} */ | 
					
						
							|  |  |  | 			(this.logger).debug( | 
					
						
							| 
									
										
										
										
											2020-03-10 09:59:46 +08:00
										 |  |  | 				"Logging limit has been reached and no further logging will be emitted by FileSystemInfo" | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 			); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-25 23:35:19 +08:00
										 |  |  | 	clear() { | 
					
						
							|  |  |  | 		this._remainingLogs = this.logger ? 40 : 0; | 
					
						
							|  |  |  | 		if (this._loggedPaths !== undefined) this._loggedPaths.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		this._snapshotCache = new WeakMap(); | 
					
						
							|  |  |  | 		this._fileTimestampsOptimization.clear(); | 
					
						
							|  |  |  | 		this._fileHashesOptimization.clear(); | 
					
						
							|  |  |  | 		this._fileTshsOptimization.clear(); | 
					
						
							|  |  |  | 		this._contextTimestampsOptimization.clear(); | 
					
						
							|  |  |  | 		this._contextHashesOptimization.clear(); | 
					
						
							|  |  |  | 		this._contextTshsOptimization.clear(); | 
					
						
							|  |  |  | 		this._missingExistenceOptimization.clear(); | 
					
						
							|  |  |  | 		this._managedItemInfoOptimization.clear(); | 
					
						
							|  |  |  | 		this._managedFilesOptimization.clear(); | 
					
						
							|  |  |  | 		this._managedContextsOptimization.clear(); | 
					
						
							|  |  |  | 		this._managedMissingOptimization.clear(); | 
					
						
							| 
									
										
										
										
											2021-07-16 19:07:56 +08:00
										 |  |  | 		this._fileTimestamps.clear(); | 
					
						
							| 
									
										
										
										
											2021-03-25 23:35:19 +08:00
										 |  |  | 		this._fileHashes.clear(); | 
					
						
							|  |  |  | 		this._fileTshs.clear(); | 
					
						
							| 
									
										
										
										
											2021-07-16 19:07:56 +08:00
										 |  |  | 		this._contextTimestamps.clear(); | 
					
						
							| 
									
										
										
										
											2021-03-25 23:35:19 +08:00
										 |  |  | 		this._contextHashes.clear(); | 
					
						
							|  |  |  | 		this._contextTshs.clear(); | 
					
						
							|  |  |  | 		this._managedItems.clear(); | 
					
						
							|  |  |  | 		this._managedItems.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		this._cachedDeprecatedFileTimestamps = undefined; | 
					
						
							|  |  |  | 		this._cachedDeprecatedContextTimestamps = undefined; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		this._statCreatedSnapshots = 0; | 
					
						
							|  |  |  | 		this._statTestedSnapshotsCached = 0; | 
					
						
							|  |  |  | 		this._statTestedSnapshotsNotCached = 0; | 
					
						
							|  |  |  | 		this._statTestedChildrenCached = 0; | 
					
						
							|  |  |  | 		this._statTestedChildrenNotCached = 0; | 
					
						
							|  |  |  | 		this._statTestedEntries = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2021-07-16 19:05:18 +08:00
										 |  |  | 	 * @param {ReadonlyMap<string, FileSystemInfoEntry | "ignore" | null>} map timestamps | 
					
						
							|  |  |  | 	 * @param {boolean=} immutable if 'map' is immutable and FileSystemInfo can keep referencing it | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2021-07-16 19:05:18 +08:00
										 |  |  | 	addFileTimestamps(map, immutable) { | 
					
						
							|  |  |  | 		this._fileTimestamps.addAll(map, immutable); | 
					
						
							| 
									
										
										
										
											2021-07-14 06:13:40 +08:00
										 |  |  | 		this._cachedDeprecatedFileTimestamps = undefined; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2021-07-16 19:05:18 +08:00
										 |  |  | 	 * @param {ReadonlyMap<string, FileSystemInfoEntry | "ignore" | null>} map timestamps | 
					
						
							|  |  |  | 	 * @param {boolean=} immutable if 'map' is immutable and FileSystemInfo can keep referencing it | 
					
						
							| 
									
										
										
										
											2021-07-14 06:13:40 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2021-07-16 19:05:18 +08:00
										 |  |  | 	addContextTimestamps(map, immutable) { | 
					
						
							|  |  |  | 		this._contextTimestamps.addAll(map, immutable); | 
					
						
							| 
									
										
										
										
											2020-09-15 20:39:09 +08:00
										 |  |  | 		this._cachedDeprecatedContextTimestamps = undefined; | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {string} path file path | 
					
						
							| 
									
										
										
										
											2021-12-24 20:27:31 +08:00
										 |  |  | 	 * @param {function((WebpackError | null)=, (FileSystemInfoEntry | "ignore" | null)=): void} callback callback function | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	getFileTimestamp(path, callback) { | 
					
						
							|  |  |  | 		const cache = this._fileTimestamps.get(path); | 
					
						
							| 
									
										
										
										
											2018-09-28 03:28:07 +08:00
										 |  |  | 		if (cache !== undefined) return callback(null, cache); | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 		this.fileTimestampQueue.add(path, callback); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {string} path context path | 
					
						
							| 
									
										
										
										
											2021-12-24 20:27:31 +08:00
										 |  |  | 	 * @param {function((WebpackError | null)=, (ResolvedContextFileSystemInfoEntry | "ignore" | null)=): void} callback callback function | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	getContextTimestamp(path, callback) { | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 		const cache = this._contextTimestamps.get(path); | 
					
						
							|  |  |  | 		if (cache !== undefined) { | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 			if (cache === "ignore") return callback(null, "ignore"); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 			const resolved = getResolvedTimestamp(cache); | 
					
						
							|  |  |  | 			if (resolved !== undefined) return callback(null, resolved); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			return this._resolveContextTimestamp( | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 				/** @type {ResolvedContextFileSystemInfoEntry} */ | 
					
						
							|  |  |  | 				(cache), | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				callback | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		this.contextTimestampQueue.add(path, (err, _entry) => { | 
					
						
							| 
									
										
										
										
											2021-08-26 22:02:54 +08:00
										 |  |  | 			if (err) return callback(err); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			const entry = /** @type {ContextFileSystemInfoEntry} */ (_entry); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 			const resolved = getResolvedTimestamp(entry); | 
					
						
							|  |  |  | 			if (resolved !== undefined) return callback(null, resolved); | 
					
						
							|  |  |  | 			this._resolveContextTimestamp(entry, callback); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {string} path context path | 
					
						
							| 
									
										
										
										
											2021-12-24 20:27:31 +08:00
										 |  |  | 	 * @param {function((WebpackError | null)=, (ContextFileSystemInfoEntry | "ignore" | null)=): void} callback callback function | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	_getUnresolvedContextTimestamp(path, callback) { | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 		const cache = this._contextTimestamps.get(path); | 
					
						
							| 
									
										
										
										
											2018-09-28 03:28:07 +08:00
										 |  |  | 		if (cache !== undefined) return callback(null, cache); | 
					
						
							| 
									
										
										
										
											2021-08-26 22:02:54 +08:00
										 |  |  | 		this.contextTimestampQueue.add(path, callback); | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {string} path file path | 
					
						
							| 
									
										
										
										
											2023-06-22 08:59:10 +08:00
										 |  |  | 	 * @param {function((WebpackError | null)=, (string | null)=): void} callback callback function | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	getFileHash(path, callback) { | 
					
						
							|  |  |  | 		const cache = this._fileHashes.get(path); | 
					
						
							|  |  |  | 		if (cache !== undefined) return callback(null, cache); | 
					
						
							|  |  |  | 		this.fileHashQueue.add(path, callback); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {string} path context path | 
					
						
							| 
									
										
										
										
											2021-12-24 20:27:31 +08:00
										 |  |  | 	 * @param {function((WebpackError | null)=, string=): void} callback callback function | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	getContextHash(path, callback) { | 
					
						
							|  |  |  | 		const cache = this._contextHashes.get(path); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 		if (cache !== undefined) { | 
					
						
							|  |  |  | 			const resolved = getResolvedHash(cache); | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 			if (resolved !== undefined) | 
					
						
							|  |  |  | 				return callback(null, /** @type {string} */ (resolved)); | 
					
						
							| 
									
										
										
										
											2021-08-26 22:02:54 +08:00
										 |  |  | 			return this._resolveContextHash(cache, callback); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		this.contextHashQueue.add(path, (err, _entry) => { | 
					
						
							| 
									
										
										
										
											2021-08-26 22:02:54 +08:00
										 |  |  | 			if (err) return callback(err); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			const entry = /** @type {ContextHash} */ (_entry); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 			const resolved = getResolvedHash(entry); | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 			if (resolved !== undefined) | 
					
						
							|  |  |  | 				return callback(null, /** @type {string} */ (resolved)); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 			this._resolveContextHash(entry, callback); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {string} path context path | 
					
						
							| 
									
										
										
										
											2023-06-22 08:59:10 +08:00
										 |  |  | 	 * @param {function((WebpackError | null)=, (ContextHash | null)=): void} callback callback function | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	_getUnresolvedContextHash(path, callback) { | 
					
						
							|  |  |  | 		const cache = this._contextHashes.get(path); | 
					
						
							|  |  |  | 		if (cache !== undefined) return callback(null, cache); | 
					
						
							| 
									
										
										
										
											2021-08-26 22:02:54 +08:00
										 |  |  | 		this.contextHashQueue.add(path, callback); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {string} path context path | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	 * @param {function((WebpackError | null)=, (ResolvedContextTimestampAndHash | null)=): void} callback callback function | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	getContextTsh(path, callback) { | 
					
						
							|  |  |  | 		const cache = this._contextTshs.get(path); | 
					
						
							|  |  |  | 		if (cache !== undefined) { | 
					
						
							|  |  |  | 			const resolved = getResolvedTimestamp(cache); | 
					
						
							|  |  |  | 			if (resolved !== undefined) return callback(null, resolved); | 
					
						
							| 
									
										
										
										
											2021-08-26 22:02:54 +08:00
										 |  |  | 			return this._resolveContextTsh(cache, callback); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		this.contextTshQueue.add(path, (err, _entry) => { | 
					
						
							| 
									
										
										
										
											2021-08-26 22:02:54 +08:00
										 |  |  | 			if (err) return callback(err); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			const entry = /** @type {ContextTimestampAndHash} */ (_entry); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 			const resolved = getResolvedTimestamp(entry); | 
					
						
							|  |  |  | 			if (resolved !== undefined) return callback(null, resolved); | 
					
						
							|  |  |  | 			this._resolveContextTsh(entry, callback); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {string} path context path | 
					
						
							| 
									
										
										
										
											2023-06-22 08:59:10 +08:00
										 |  |  | 	 * @param {function((WebpackError | null)=, (ContextTimestampAndHash | null)=): void} callback callback function | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	_getUnresolvedContextTsh(path, callback) { | 
					
						
							|  |  |  | 		const cache = this._contextTshs.get(path); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 		if (cache !== undefined) return callback(null, cache); | 
					
						
							| 
									
										
										
										
											2021-08-26 22:02:54 +08:00
										 |  |  | 		this.contextTshQueue.add(path, callback); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 	_createBuildDependenciesResolvers() { | 
					
						
							|  |  |  | 		const resolveContext = createResolver({ | 
					
						
							|  |  |  | 			resolveToContext: true, | 
					
						
							|  |  |  | 			exportsFields: [], | 
					
						
							|  |  |  | 			fileSystem: this.fs | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 		const resolveCjs = createResolver({ | 
					
						
							|  |  |  | 			extensions: [".js", ".json", ".node"], | 
					
						
							|  |  |  | 			conditionNames: ["require", "node"], | 
					
						
							| 
									
										
										
										
											2021-04-06 19:58:36 +08:00
										 |  |  | 			exportsFields: ["exports"], | 
					
						
							|  |  |  | 			fileSystem: this.fs | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 		const resolveCjsAsChild = createResolver({ | 
					
						
							|  |  |  | 			extensions: [".js", ".json", ".node"], | 
					
						
							|  |  |  | 			conditionNames: ["require", "node"], | 
					
						
							|  |  |  | 			exportsFields: [], | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 			fileSystem: this.fs | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 		const resolveEsm = createResolver({ | 
					
						
							|  |  |  | 			extensions: [".js", ".json", ".node"], | 
					
						
							|  |  |  | 			fullySpecified: true, | 
					
						
							|  |  |  | 			conditionNames: ["import", "node"], | 
					
						
							| 
									
										
										
										
											2021-04-06 19:58:36 +08:00
										 |  |  | 			exportsFields: ["exports"], | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 			fileSystem: this.fs | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2021-04-06 19:58:36 +08:00
										 |  |  | 		return { resolveContext, resolveEsm, resolveCjs, resolveCjsAsChild }; | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {string} context context directory | 
					
						
							|  |  |  | 	 * @param {Iterable<string>} deps dependencies | 
					
						
							| 
									
										
										
										
											2021-12-24 20:27:31 +08:00
										 |  |  | 	 * @param {function((Error | null)=, ResolveBuildDependenciesResult=): void} callback callback function | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 	resolveBuildDependencies(context, deps, callback) { | 
					
						
							| 
									
										
										
										
											2021-05-11 15:31:46 +08:00
										 |  |  | 		const { resolveContext, resolveEsm, resolveCjs, resolveCjsAsChild } = | 
					
						
							|  |  |  | 			this._createBuildDependenciesResolvers(); | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 17:35:36 +08:00
										 |  |  | 		/** @type {Set<string>} */ | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 		const files = new Set(); | 
					
						
							| 
									
										
										
										
											2019-10-20 17:35:36 +08:00
										 |  |  | 		/** @type {Set<string>} */ | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 		const fileSymlinks = new Set(); | 
					
						
							|  |  |  | 		/** @type {Set<string>} */ | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 		const directories = new Set(); | 
					
						
							| 
									
										
										
										
											2019-10-20 17:35:36 +08:00
										 |  |  | 		/** @type {Set<string>} */ | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 		const directorySymlinks = new Set(); | 
					
						
							|  |  |  | 		/** @type {Set<string>} */ | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 		const missing = new Set(); | 
					
						
							| 
									
										
										
										
											2019-10-20 17:35:36 +08:00
										 |  |  | 		/** @type {Set<string>} */ | 
					
						
							| 
									
										
										
										
											2019-08-20 03:57:49 +08:00
										 |  |  | 		const resolveFiles = new Set(); | 
					
						
							| 
									
										
										
										
											2019-10-20 17:35:36 +08:00
										 |  |  | 		/** @type {Set<string>} */ | 
					
						
							| 
									
										
										
										
											2019-08-20 03:57:49 +08:00
										 |  |  | 		const resolveDirectories = new Set(); | 
					
						
							| 
									
										
										
										
											2019-10-20 17:35:36 +08:00
										 |  |  | 		/** @type {Set<string>} */ | 
					
						
							| 
									
										
										
										
											2019-08-20 03:57:49 +08:00
										 |  |  | 		const resolveMissing = new Set(); | 
					
						
							| 
									
										
										
										
											2023-06-22 05:55:05 +08:00
										 |  |  | 		/** @type {Map<string, string | false | undefined>} */ | 
					
						
							| 
									
										
										
										
											2019-08-20 03:57:49 +08:00
										 |  |  | 		const resolveResults = new Map(); | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 		const invalidResolveResults = new Set(); | 
					
						
							|  |  |  | 		const resolverContext = { | 
					
						
							|  |  |  | 			fileDependencies: resolveFiles, | 
					
						
							|  |  |  | 			contextDependencies: resolveDirectories, | 
					
						
							|  |  |  | 			missingDependencies: resolveMissing | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2023-06-22 08:59:10 +08:00
										 |  |  | 		/** | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		 * @param {undefined | boolean | string} expected expected result | 
					
						
							| 
									
										
										
										
											2023-06-22 08:59:10 +08:00
										 |  |  | 		 * @returns {string} expected result | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2024-07-31 11:31:11 +08:00
										 |  |  | 		const expectedToString = expected => | 
					
						
							|  |  |  | 			expected ? ` (expected ${expected})` : ""; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @typedef {{ type: JobType, context: string | undefined, path: string, issuer: Job | undefined, expected: undefined | boolean | string }} Job */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {Job} job job | 
					
						
							|  |  |  | 		 * @returns {`resolve commonjs file ${string}${string}`|`resolve esm file ${string}${string}`|`resolve esm ${string}${string}`|`resolve directory ${string}`|`file ${string}`|`unknown ${string} ${string}`|`resolve commonjs ${string}${string}`|`directory ${string}`|`file dependencies ${string}`|`directory dependencies ${string}`} result | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2021-03-29 02:35:42 +08:00
										 |  |  | 		const jobToString = job => { | 
					
						
							|  |  |  | 			switch (job.type) { | 
					
						
							|  |  |  | 				case RBDT_RESOLVE_CJS: | 
					
						
							|  |  |  | 					return `resolve commonjs ${job.path}${expectedToString( | 
					
						
							|  |  |  | 						job.expected | 
					
						
							|  |  |  | 					)}`;
 | 
					
						
							|  |  |  | 				case RBDT_RESOLVE_ESM: | 
					
						
							|  |  |  | 					return `resolve esm ${job.path}${expectedToString(job.expected)}`; | 
					
						
							|  |  |  | 				case RBDT_RESOLVE_DIRECTORY: | 
					
						
							|  |  |  | 					return `resolve directory ${job.path}`; | 
					
						
							|  |  |  | 				case RBDT_RESOLVE_CJS_FILE: | 
					
						
							|  |  |  | 					return `resolve commonjs file ${job.path}${expectedToString( | 
					
						
							|  |  |  | 						job.expected | 
					
						
							|  |  |  | 					)}`;
 | 
					
						
							|  |  |  | 				case RBDT_RESOLVE_ESM_FILE: | 
					
						
							|  |  |  | 					return `resolve esm file ${job.path}${expectedToString( | 
					
						
							|  |  |  | 						job.expected | 
					
						
							|  |  |  | 					)}`;
 | 
					
						
							|  |  |  | 				case RBDT_DIRECTORY: | 
					
						
							|  |  |  | 					return `directory ${job.path}`; | 
					
						
							|  |  |  | 				case RBDT_FILE: | 
					
						
							|  |  |  | 					return `file ${job.path}`; | 
					
						
							|  |  |  | 				case RBDT_DIRECTORY_DEPENDENCIES: | 
					
						
							|  |  |  | 					return `directory dependencies ${job.path}`; | 
					
						
							|  |  |  | 				case RBDT_FILE_DEPENDENCIES: | 
					
						
							|  |  |  | 					return `file dependencies ${job.path}`; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return `unknown ${job.type} ${job.path}`; | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {Job} job job | 
					
						
							|  |  |  | 		 * @returns {string} string value | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2021-03-29 02:35:42 +08:00
										 |  |  | 		const pathToString = job => { | 
					
						
							|  |  |  | 			let result = ` at ${jobToString(job)}`; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			/** @type {Job | undefined} */ | 
					
						
							|  |  |  | 			(job) = job.issuer; | 
					
						
							| 
									
										
										
										
											2021-03-29 02:35:42 +08:00
										 |  |  | 			while (job !== undefined) { | 
					
						
							|  |  |  | 				result += `\n at ${jobToString(job)}`; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				job = /** @type {Job} */ (job.issuer); | 
					
						
							| 
									
										
										
										
											2021-03-29 02:35:42 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			return result; | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		const logger = /** @type {Logger} */ (this.logger); | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 		processAsyncTree( | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			Array.from( | 
					
						
							|  |  |  | 				deps, | 
					
						
							|  |  |  | 				dep => | 
					
						
							|  |  |  | 					/** @type {Job} */ ({ | 
					
						
							|  |  |  | 						type: RBDT_RESOLVE_CJS, | 
					
						
							|  |  |  | 						context, | 
					
						
							|  |  |  | 						path: dep, | 
					
						
							|  |  |  | 						expected: undefined, | 
					
						
							|  |  |  | 						issuer: undefined | 
					
						
							|  |  |  | 					}) | 
					
						
							|  |  |  | 			), | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 			20, | 
					
						
							| 
									
										
										
										
											2021-03-29 02:35:42 +08:00
										 |  |  | 			(job, push, callback) => { | 
					
						
							|  |  |  | 				const { type, context, path, expected } = job; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				/** | 
					
						
							|  |  |  | 				 * @param {string} path path | 
					
						
							|  |  |  | 				 * @returns {void} | 
					
						
							|  |  |  | 				 */ | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 				const resolveDirectory = path => { | 
					
						
							|  |  |  | 					const key = `d\n${context}\n${path}`; | 
					
						
							|  |  |  | 					if (resolveResults.has(key)) { | 
					
						
							|  |  |  | 						return callback(); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 					resolveResults.set(key, undefined); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 					resolveContext( | 
					
						
							|  |  |  | 						/** @type {string} */ (context), | 
					
						
							|  |  |  | 						path, | 
					
						
							|  |  |  | 						resolverContext, | 
					
						
							|  |  |  | 						(err, _, result) => { | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 							if (err) { | 
					
						
							| 
									
										
										
										
											2021-04-06 17:28:27 +08:00
										 |  |  | 								if (expected === false) { | 
					
						
							|  |  |  | 									resolveResults.set(key, false); | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 									return callback(); | 
					
						
							| 
									
										
										
										
											2020-08-11 01:24:11 +08:00
										 |  |  | 								} | 
					
						
							| 
									
										
										
										
											2021-04-06 17:28:27 +08:00
										 |  |  | 								invalidResolveResults.add(key); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 								err.message += `\nwhile resolving '${path}' in ${context} to a directory`; | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 								return callback(err); | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							const resultPath = /** @type {ResolveRequest} */ (result).path; | 
					
						
							| 
									
										
										
										
											2021-04-19 18:13:47 +08:00
										 |  |  | 							resolveResults.set(key, resultPath); | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 							push({ | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 								type: RBDT_DIRECTORY, | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 								context: undefined, | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 								path: /** @type {string} */ (resultPath), | 
					
						
							| 
									
										
										
										
											2021-03-29 02:35:42 +08:00
										 |  |  | 								expected: undefined, | 
					
						
							|  |  |  | 								issuer: job | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 							}); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							callback(); | 
					
						
							| 
									
										
										
										
											2019-08-20 03:57:49 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 					); | 
					
						
							|  |  |  | 				}; | 
					
						
							|  |  |  | 				/** | 
					
						
							|  |  |  | 				 * @param {string} path path | 
					
						
							|  |  |  | 				 * @param {("f" | "c" | "e")=} symbol symbol | 
					
						
							|  |  |  | 				 * @param {(ResolveFunctionAsync)=} resolve resolve fn | 
					
						
							|  |  |  | 				 * @returns {void} | 
					
						
							|  |  |  | 				 */ | 
					
						
							|  |  |  | 				const resolveFile = (path, symbol, resolve) => { | 
					
						
							|  |  |  | 					const key = `${symbol}\n${context}\n${path}`; | 
					
						
							|  |  |  | 					if (resolveResults.has(key)) { | 
					
						
							|  |  |  | 						return callback(); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					resolveResults.set(key, undefined); | 
					
						
							|  |  |  | 					/** @type {ResolveFunctionAsync} */ | 
					
						
							|  |  |  | 					(resolve)( | 
					
						
							|  |  |  | 						/** @type {string} */ (context), | 
					
						
							|  |  |  | 						path, | 
					
						
							|  |  |  | 						resolverContext, | 
					
						
							|  |  |  | 						(err, _, result) => { | 
					
						
							|  |  |  | 							if (typeof expected === "string") { | 
					
						
							|  |  |  | 								if (!err && result && result.path === expected) { | 
					
						
							|  |  |  | 									resolveResults.set(key, result.path); | 
					
						
							|  |  |  | 								} else { | 
					
						
							|  |  |  | 									invalidResolveResults.add(key); | 
					
						
							|  |  |  | 									logger.warn( | 
					
						
							|  |  |  | 										`Resolving '${path}' in ${context} for build dependencies doesn't lead to expected result '${expected}', but to '${ | 
					
						
							|  |  |  | 											err || (result && result.path) | 
					
						
							|  |  |  | 										}' instead. Resolving dependencies are ignored for this path.\n${pathToString( | 
					
						
							|  |  |  | 											job | 
					
						
							|  |  |  | 										)}`
 | 
					
						
							|  |  |  | 									); | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} else { | 
					
						
							|  |  |  | 								if (err) { | 
					
						
							|  |  |  | 									if (expected === false) { | 
					
						
							|  |  |  | 										resolveResults.set(key, false); | 
					
						
							|  |  |  | 										return callback(); | 
					
						
							|  |  |  | 									} | 
					
						
							|  |  |  | 									invalidResolveResults.add(key); | 
					
						
							|  |  |  | 									err.message += `\nwhile resolving '${path}' in ${context} as file\n${pathToString( | 
					
						
							|  |  |  | 										job | 
					
						
							|  |  |  | 									)}`;
 | 
					
						
							|  |  |  | 									return callback(err); | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 								const resultPath = /** @type {ResolveRequest} */ (result).path; | 
					
						
							|  |  |  | 								resolveResults.set(key, resultPath); | 
					
						
							|  |  |  | 								push({ | 
					
						
							|  |  |  | 									type: RBDT_FILE, | 
					
						
							|  |  |  | 									context: undefined, | 
					
						
							|  |  |  | 									path: /** @type {string} */ (resultPath), | 
					
						
							|  |  |  | 									expected: undefined, | 
					
						
							|  |  |  | 									issuer: job | 
					
						
							|  |  |  | 								}); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							callback(); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					); | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 				}; | 
					
						
							|  |  |  | 				switch (type) { | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 					case RBDT_RESOLVE_CJS: { | 
					
						
							|  |  |  | 						const isDirectory = /[\\/]$/.test(path); | 
					
						
							|  |  |  | 						if (isDirectory) { | 
					
						
							| 
									
										
										
										
											2024-08-02 02:36:27 +08:00
										 |  |  | 							resolveDirectory(path.slice(0, -1)); | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 						} else { | 
					
						
							|  |  |  | 							resolveFile(path, "f", resolveCjs); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					case RBDT_RESOLVE_ESM: { | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 						const isDirectory = /[\\/]$/.test(path); | 
					
						
							|  |  |  | 						if (isDirectory) { | 
					
						
							| 
									
										
										
										
											2024-08-02 02:36:27 +08:00
										 |  |  | 							resolveDirectory(path.slice(0, -1)); | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 						} else { | 
					
						
							|  |  |  | 							resolveFile(path); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						break; | 
					
						
							| 
									
										
										
										
											2019-08-20 03:57:49 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 					case RBDT_RESOLVE_DIRECTORY: { | 
					
						
							|  |  |  | 						resolveDirectory(path); | 
					
						
							|  |  |  | 						break; | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 					case RBDT_RESOLVE_CJS_FILE: { | 
					
						
							|  |  |  | 						resolveFile(path, "f", resolveCjs); | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2021-04-06 19:58:36 +08:00
										 |  |  | 					case RBDT_RESOLVE_CJS_FILE_AS_CHILD: { | 
					
						
							|  |  |  | 						resolveFile(path, "c", resolveCjsAsChild); | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 					case RBDT_RESOLVE_ESM_FILE: { | 
					
						
							|  |  |  | 						resolveFile(path, "e", resolveEsm); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 					case RBDT_FILE: { | 
					
						
							|  |  |  | 						if (files.has(path)) { | 
					
						
							|  |  |  | 							callback(); | 
					
						
							|  |  |  | 							break; | 
					
						
							| 
									
										
										
										
											2019-08-20 03:57:49 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 						files.add(path); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 						/** @type {NonNullable<InputFileSystem["realpath"]>} */ | 
					
						
							|  |  |  | 						(this.fs.realpath)(path, (err, _realPath) => { | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 							if (err) return callback(err); | 
					
						
							| 
									
										
										
										
											2021-01-13 07:09:19 +08:00
										 |  |  | 							const realPath = /** @type {string} */ (_realPath); | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 							if (realPath !== path) { | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 								fileSymlinks.add(path); | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 								resolveFiles.add(path); | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 								if (files.has(realPath)) return callback(); | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 								files.add(realPath); | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 							push({ | 
					
						
							|  |  |  | 								type: RBDT_FILE_DEPENDENCIES, | 
					
						
							|  |  |  | 								context: undefined, | 
					
						
							|  |  |  | 								path: realPath, | 
					
						
							| 
									
										
										
										
											2021-03-29 02:35:42 +08:00
										 |  |  | 								expected: undefined, | 
					
						
							|  |  |  | 								issuer: job | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 							}); | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 							callback(); | 
					
						
							|  |  |  | 						}); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 					case RBDT_DIRECTORY: { | 
					
						
							|  |  |  | 						if (directories.has(path)) { | 
					
						
							|  |  |  | 							callback(); | 
					
						
							|  |  |  | 							break; | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 						directories.add(path); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 						/** @type {NonNullable<InputFileSystem["realpath"]>} */ | 
					
						
							|  |  |  | 						(this.fs.realpath)(path, (err, _realPath) => { | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 							if (err) return callback(err); | 
					
						
							| 
									
										
										
										
											2021-01-13 07:09:19 +08:00
										 |  |  | 							const realPath = /** @type {string} */ (_realPath); | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 							if (realPath !== path) { | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 								directorySymlinks.add(path); | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 								resolveFiles.add(path); | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 								if (directories.has(realPath)) return callback(); | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 								directories.add(realPath); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 							push({ | 
					
						
							|  |  |  | 								type: RBDT_DIRECTORY_DEPENDENCIES, | 
					
						
							|  |  |  | 								context: undefined, | 
					
						
							|  |  |  | 								path: realPath, | 
					
						
							| 
									
										
										
										
											2021-03-29 02:35:42 +08:00
										 |  |  | 								expected: undefined, | 
					
						
							|  |  |  | 								issuer: job | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 							}); | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 							callback(); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 						}); | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 						break; | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 					case RBDT_FILE_DEPENDENCIES: { | 
					
						
							| 
									
										
										
										
											2021-01-14 04:16:55 +08:00
										 |  |  | 						// Check for known files without dependencies
 | 
					
						
							|  |  |  | 						if (/\.json5?$|\.yarn-integrity$|yarn\.lock$|\.ya?ml/.test(path)) { | 
					
						
							|  |  |  | 							process.nextTick(callback); | 
					
						
							|  |  |  | 							break; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						// Check commonjs cache for the module
 | 
					
						
							| 
									
										
										
										
											2023-06-22 05:55:05 +08:00
										 |  |  | 						/** @type {NodeModule | undefined} */ | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 						const module = require.cache[path]; | 
					
						
							|  |  |  | 						if (module && Array.isArray(module.children)) { | 
					
						
							|  |  |  | 							children: for (const child of module.children) { | 
					
						
							| 
									
										
										
										
											2024-07-31 04:09:42 +08:00
										 |  |  | 								const childPath = child.filename; | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 								if (childPath) { | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 									push({ | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 										type: RBDT_FILE, | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 										context: undefined, | 
					
						
							|  |  |  | 										path: childPath, | 
					
						
							| 
									
										
										
										
											2021-03-29 02:35:42 +08:00
										 |  |  | 										expected: undefined, | 
					
						
							|  |  |  | 										issuer: job | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 									}); | 
					
						
							|  |  |  | 									const context = dirname(this.fs, path); | 
					
						
							|  |  |  | 									for (const modulePath of module.paths) { | 
					
						
							|  |  |  | 										if (childPath.startsWith(modulePath)) { | 
					
						
							| 
									
										
										
										
											2024-07-31 04:09:42 +08:00
										 |  |  | 											const subPath = childPath.slice(modulePath.length + 1); | 
					
						
							| 
									
										
										
										
											2021-04-06 19:58:36 +08:00
										 |  |  | 											const packageMatch = /^(@[^\\/]+[\\/])[^\\/]+/.exec( | 
					
						
							|  |  |  | 												subPath | 
					
						
							|  |  |  | 											); | 
					
						
							|  |  |  | 											if (packageMatch) { | 
					
						
							|  |  |  | 												push({ | 
					
						
							|  |  |  | 													type: RBDT_FILE, | 
					
						
							|  |  |  | 													context: undefined, | 
					
						
							| 
									
										
										
										
											2024-07-31 10:39:30 +08:00
										 |  |  | 													path: `${ | 
					
						
							| 
									
										
										
										
											2021-04-06 19:58:36 +08:00
										 |  |  | 														modulePath + | 
					
						
							|  |  |  | 														childPath[modulePath.length] + | 
					
						
							|  |  |  | 														packageMatch[0] + | 
					
						
							| 
									
										
										
										
											2024-07-31 10:39:30 +08:00
										 |  |  | 														childPath[modulePath.length] | 
					
						
							|  |  |  | 													}package.json`,
 | 
					
						
							| 
									
										
										
										
											2021-04-06 19:58:36 +08:00
										 |  |  | 													expected: false, | 
					
						
							|  |  |  | 													issuer: job | 
					
						
							|  |  |  | 												}); | 
					
						
							|  |  |  | 											} | 
					
						
							|  |  |  | 											let request = subPath.replace(/\\/g, "/"); | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 											if (request.endsWith(".js")) | 
					
						
							|  |  |  | 												request = request.slice(0, -3); | 
					
						
							|  |  |  | 											push({ | 
					
						
							| 
									
										
										
										
											2021-04-06 19:58:36 +08:00
										 |  |  | 												type: RBDT_RESOLVE_CJS_FILE_AS_CHILD, | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 												context, | 
					
						
							|  |  |  | 												path: request, | 
					
						
							| 
									
										
										
										
											2021-03-29 02:35:42 +08:00
										 |  |  | 												expected: child.filename, | 
					
						
							|  |  |  | 												issuer: job | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 											}); | 
					
						
							|  |  |  | 											continue children; | 
					
						
							|  |  |  | 										} | 
					
						
							|  |  |  | 									} | 
					
						
							|  |  |  | 									let request = relative(this.fs, context, childPath); | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 									if (request.endsWith(".js")) request = request.slice(0, -3); | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 									request = request.replace(/\\/g, "/"); | 
					
						
							| 
									
										
										
										
											2022-06-02 18:06:41 +08:00
										 |  |  | 									if (!request.startsWith("../") && !isAbsolute(request)) { | 
					
						
							|  |  |  | 										request = `./${request}`; | 
					
						
							|  |  |  | 									} | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 									push({ | 
					
						
							|  |  |  | 										type: RBDT_RESOLVE_CJS_FILE, | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 										context, | 
					
						
							|  |  |  | 										path: request, | 
					
						
							| 
									
										
										
										
											2021-03-29 02:35:42 +08:00
										 |  |  | 										expected: child.filename, | 
					
						
							|  |  |  | 										issuer: job | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 									}); | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2021-01-14 04:16:55 +08:00
										 |  |  | 						} else if (supportsEsm && /\.m?js$/.test(path)) { | 
					
						
							|  |  |  | 							if (!this._warnAboutExperimentalEsmTracking) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 								logger.log( | 
					
						
							| 
									
										
										
										
											2021-01-14 04:16:55 +08:00
										 |  |  | 									"Node.js doesn't offer a (nice) way to introspect the ESM dependency graph yet.\n" + | 
					
						
							|  |  |  | 										"Until a full solution is available webpack uses an experimental ESM tracking based on parsing.\n" + | 
					
						
							|  |  |  | 										"As best effort webpack parses the ESM files to guess dependencies. But this can lead to expensive and incorrect tracking." | 
					
						
							|  |  |  | 								); | 
					
						
							|  |  |  | 								this._warnAboutExperimentalEsmTracking = true; | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							const lexer = require("es-module-lexer"); | 
					
						
							|  |  |  | 							lexer.init.then(() => { | 
					
						
							|  |  |  | 								this.fs.readFile(path, (err, content) => { | 
					
						
							|  |  |  | 									if (err) return callback(err); | 
					
						
							|  |  |  | 									try { | 
					
						
							|  |  |  | 										const context = dirname(this.fs, path); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 										const source = /** @type {Buffer} */ (content).toString(); | 
					
						
							| 
									
										
										
										
											2021-01-14 04:16:55 +08:00
										 |  |  | 										const [imports] = lexer.parse(source); | 
					
						
							|  |  |  | 										for (const imp of imports) { | 
					
						
							|  |  |  | 											try { | 
					
						
							|  |  |  | 												let dependency; | 
					
						
							|  |  |  | 												if (imp.d === -1) { | 
					
						
							|  |  |  | 													// import ... from "..."
 | 
					
						
							| 
									
										
										
										
											2021-11-09 19:24:53 +08:00
										 |  |  | 													dependency = parseString( | 
					
						
							| 
									
										
										
										
											2021-01-14 04:16:55 +08:00
										 |  |  | 														source.substring(imp.s - 1, imp.e + 1) | 
					
						
							|  |  |  | 													); | 
					
						
							|  |  |  | 												} else if (imp.d > -1) { | 
					
						
							|  |  |  | 													// import()
 | 
					
						
							| 
									
										
										
										
											2024-07-31 04:09:42 +08:00
										 |  |  | 													const expr = source.substring(imp.s, imp.e).trim(); | 
					
						
							| 
									
										
										
										
											2021-11-09 19:24:53 +08:00
										 |  |  | 													dependency = parseString(expr); | 
					
						
							| 
									
										
										
										
											2021-01-14 04:16:55 +08:00
										 |  |  | 												} else { | 
					
						
							|  |  |  | 													// e.g. import.meta
 | 
					
						
							|  |  |  | 													continue; | 
					
						
							|  |  |  | 												} | 
					
						
							| 
									
										
										
										
											2022-03-23 16:27:37 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 												// we should not track Node.js build dependencies
 | 
					
						
							|  |  |  | 												if (dependency.startsWith("node:")) continue; | 
					
						
							| 
									
										
										
										
											2022-04-01 20:52:40 +08:00
										 |  |  | 												if (builtinModules.has(dependency)) continue; | 
					
						
							| 
									
										
										
										
											2022-03-23 16:27:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 												push({ | 
					
						
							|  |  |  | 													type: RBDT_RESOLVE_ESM_FILE, | 
					
						
							| 
									
										
										
										
											2021-01-14 04:16:55 +08:00
										 |  |  | 													context, | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 													path: dependency, | 
					
						
							| 
									
										
										
										
											2024-01-05 23:18:42 +08:00
										 |  |  | 													expected: imp.d > -1 ? false : undefined, | 
					
						
							| 
									
										
										
										
											2021-03-29 02:35:42 +08:00
										 |  |  | 													issuer: job | 
					
						
							| 
									
										
										
										
											2021-01-14 04:16:55 +08:00
										 |  |  | 												}); | 
					
						
							| 
									
										
										
										
											2024-07-31 15:37:05 +08:00
										 |  |  | 											} catch (err1) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 												logger.warn( | 
					
						
							| 
									
										
										
										
											2021-01-14 04:16:55 +08:00
										 |  |  | 													`Parsing of ${path} for build dependencies failed at 'import(${source.substring( | 
					
						
							|  |  |  | 														imp.s, | 
					
						
							|  |  |  | 														imp.e | 
					
						
							|  |  |  | 													)})'.\n` +
 | 
					
						
							|  |  |  | 														"Build dependencies behind this expression are ignored and might cause incorrect cache invalidation." | 
					
						
							|  |  |  | 												); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 												logger.debug(pathToString(job)); | 
					
						
							|  |  |  | 												logger.debug(/** @type {Error} */ (err1).stack); | 
					
						
							| 
									
										
										
										
											2021-01-14 04:16:55 +08:00
										 |  |  | 											} | 
					
						
							|  |  |  | 										} | 
					
						
							| 
									
										
										
										
											2024-07-31 15:37:05 +08:00
										 |  |  | 									} catch (err2) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 										logger.warn( | 
					
						
							| 
									
										
										
										
											2021-01-14 04:16:55 +08:00
										 |  |  | 											`Parsing of ${path} for build dependencies failed and all dependencies of this file are ignored, which might cause incorrect cache invalidation..` | 
					
						
							|  |  |  | 										); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 										logger.debug(pathToString(job)); | 
					
						
							|  |  |  | 										logger.debug(/** @type {Error} */ (err2).stack); | 
					
						
							| 
									
										
										
										
											2021-01-14 04:16:55 +08:00
										 |  |  | 									} | 
					
						
							|  |  |  | 									process.nextTick(callback); | 
					
						
							|  |  |  | 								}); | 
					
						
							|  |  |  | 							}, callback); | 
					
						
							|  |  |  | 							break; | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 						} else { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							logger.log( | 
					
						
							| 
									
										
										
										
											2021-01-14 04:16:55 +08:00
										 |  |  | 								`Assuming ${path} has no dependencies as we were unable to assign it to any module system.` | 
					
						
							|  |  |  | 							); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							logger.debug(pathToString(job)); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2020-09-17 16:57:47 +08:00
										 |  |  | 						process.nextTick(callback); | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					case RBDT_DIRECTORY_DEPENDENCIES: { | 
					
						
							| 
									
										
										
										
											2021-05-11 15:31:46 +08:00
										 |  |  | 						const match = | 
					
						
							|  |  |  | 							/(^.+[\\/]node_modules[\\/](?:@[^\\/]+[\\/])?[^\\/]+)/.exec(path); | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 						const packagePath = match ? match[1] : path; | 
					
						
							|  |  |  | 						const packageJson = join(this.fs, packagePath, "package.json"); | 
					
						
							|  |  |  | 						this.fs.readFile(packageJson, (err, content) => { | 
					
						
							|  |  |  | 							if (err) { | 
					
						
							|  |  |  | 								if (err.code === "ENOENT") { | 
					
						
							|  |  |  | 									resolveMissing.add(packageJson); | 
					
						
							|  |  |  | 									const parent = dirname(this.fs, packagePath); | 
					
						
							|  |  |  | 									if (parent !== packagePath) { | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 										push({ | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 											type: RBDT_DIRECTORY_DEPENDENCIES, | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 											context: undefined, | 
					
						
							|  |  |  | 											path: parent, | 
					
						
							| 
									
										
										
										
											2021-03-29 02:35:42 +08:00
										 |  |  | 											expected: undefined, | 
					
						
							|  |  |  | 											issuer: job | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 										}); | 
					
						
							|  |  |  | 									} | 
					
						
							|  |  |  | 									callback(); | 
					
						
							|  |  |  | 									return; | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 								return callback(err); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							resolveFiles.add(packageJson); | 
					
						
							|  |  |  | 							let packageData; | 
					
						
							|  |  |  | 							try { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 								packageData = JSON.parse( | 
					
						
							|  |  |  | 									/** @type {Buffer} */ (content).toString("utf-8") | 
					
						
							|  |  |  | 								); | 
					
						
							| 
									
										
										
										
											2024-07-31 15:37:05 +08:00
										 |  |  | 							} catch (parseErr) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 								return callback(/** @type {Error} */ (parseErr)); | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 							} | 
					
						
							|  |  |  | 							const depsObject = packageData.dependencies; | 
					
						
							| 
									
										
										
										
											2021-04-06 17:28:27 +08:00
										 |  |  | 							const optionalDepsObject = packageData.optionalDependencies; | 
					
						
							|  |  |  | 							const allDeps = new Set(); | 
					
						
							|  |  |  | 							const optionalDeps = new Set(); | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 							if (typeof depsObject === "object" && depsObject) { | 
					
						
							|  |  |  | 								for (const dep of Object.keys(depsObject)) { | 
					
						
							| 
									
										
										
										
											2021-04-06 17:28:27 +08:00
										 |  |  | 									allDeps.add(dep); | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							if ( | 
					
						
							|  |  |  | 								typeof optionalDepsObject === "object" && | 
					
						
							|  |  |  | 								optionalDepsObject | 
					
						
							|  |  |  | 							) { | 
					
						
							|  |  |  | 								for (const dep of Object.keys(optionalDepsObject)) { | 
					
						
							|  |  |  | 									allDeps.add(dep); | 
					
						
							|  |  |  | 									optionalDeps.add(dep); | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2021-04-06 17:28:27 +08:00
										 |  |  | 							for (const dep of allDeps) { | 
					
						
							|  |  |  | 								push({ | 
					
						
							|  |  |  | 									type: RBDT_RESOLVE_DIRECTORY, | 
					
						
							|  |  |  | 									context: packagePath, | 
					
						
							|  |  |  | 									path: dep, | 
					
						
							|  |  |  | 									expected: !optionalDeps.has(dep), | 
					
						
							|  |  |  | 									issuer: job | 
					
						
							|  |  |  | 								}); | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 							callback(); | 
					
						
							|  |  |  | 						}); | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 			err => { | 
					
						
							|  |  |  | 				if (err) return callback(err); | 
					
						
							|  |  |  | 				for (const l of fileSymlinks) files.delete(l); | 
					
						
							|  |  |  | 				for (const l of directorySymlinks) directories.delete(l); | 
					
						
							|  |  |  | 				for (const k of invalidResolveResults) resolveResults.delete(k); | 
					
						
							|  |  |  | 				callback(null, { | 
					
						
							|  |  |  | 					files, | 
					
						
							|  |  |  | 					directories, | 
					
						
							|  |  |  | 					missing, | 
					
						
							|  |  |  | 					resolveResults, | 
					
						
							|  |  |  | 					resolveDependencies: { | 
					
						
							|  |  |  | 						files: resolveFiles, | 
					
						
							|  |  |  | 						directories: resolveDirectories, | 
					
						
							|  |  |  | 						missing: resolveMissing | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-08-20 19:50:14 +08:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-20 03:57:49 +08:00
										 |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2021-04-06 17:28:27 +08:00
										 |  |  | 	 * @param {Map<string, string | false>} resolveResults results from resolving | 
					
						
							| 
									
										
										
										
											2021-12-24 20:27:31 +08:00
										 |  |  | 	 * @param {function((Error | null)=, boolean=): void} callback callback with true when resolveResults resolve the same way | 
					
						
							| 
									
										
										
										
											2019-08-20 03:57:49 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	checkResolveResultsValid(resolveResults, callback) { | 
					
						
							| 
									
										
										
										
											2021-05-11 15:31:46 +08:00
										 |  |  | 		const { resolveCjs, resolveCjsAsChild, resolveEsm, resolveContext } = | 
					
						
							|  |  |  | 			this._createBuildDependenciesResolvers(); | 
					
						
							| 
									
										
										
										
											2019-08-20 03:57:49 +08:00
										 |  |  | 		asyncLib.eachLimit( | 
					
						
							|  |  |  | 			resolveResults, | 
					
						
							|  |  |  | 			20, | 
					
						
							|  |  |  | 			([key, expectedResult], callback) => { | 
					
						
							|  |  |  | 				const [type, context, path] = key.split("\n"); | 
					
						
							|  |  |  | 				switch (type) { | 
					
						
							|  |  |  | 					case "d": | 
					
						
							| 
									
										
										
										
											2021-04-19 18:13:47 +08:00
										 |  |  | 						resolveContext(context, path, {}, (err, _, result) => { | 
					
						
							| 
									
										
										
										
											2021-04-06 17:28:27 +08:00
										 |  |  | 							if (expectedResult === false) | 
					
						
							|  |  |  | 								return callback(err ? undefined : INVALID); | 
					
						
							| 
									
										
										
										
											2019-08-20 03:57:49 +08:00
										 |  |  | 							if (err) return callback(err); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							const resultPath = /** @type {ResolveRequest} */ (result).path; | 
					
						
							| 
									
										
										
										
											2021-04-19 18:13:47 +08:00
										 |  |  | 							if (resultPath !== expectedResult) return callback(INVALID); | 
					
						
							| 
									
										
										
										
											2019-08-20 03:57:49 +08:00
										 |  |  | 							callback(); | 
					
						
							|  |  |  | 						}); | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					case "f": | 
					
						
							| 
									
										
										
										
											2021-04-19 18:13:47 +08:00
										 |  |  | 						resolveCjs(context, path, {}, (err, _, result) => { | 
					
						
							| 
									
										
										
										
											2021-04-06 17:28:27 +08:00
										 |  |  | 							if (expectedResult === false) | 
					
						
							|  |  |  | 								return callback(err ? undefined : INVALID); | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 							if (err) return callback(err); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							const resultPath = /** @type {ResolveRequest} */ (result).path; | 
					
						
							| 
									
										
										
										
											2021-04-19 18:13:47 +08:00
										 |  |  | 							if (resultPath !== expectedResult) return callback(INVALID); | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 							callback(); | 
					
						
							|  |  |  | 						}); | 
					
						
							|  |  |  | 						break; | 
					
						
							| 
									
										
										
										
											2021-04-06 19:58:36 +08:00
										 |  |  | 					case "c": | 
					
						
							| 
									
										
										
										
											2021-04-19 18:13:47 +08:00
										 |  |  | 						resolveCjsAsChild(context, path, {}, (err, _, result) => { | 
					
						
							| 
									
										
										
										
											2021-04-06 19:58:36 +08:00
										 |  |  | 							if (expectedResult === false) | 
					
						
							|  |  |  | 								return callback(err ? undefined : INVALID); | 
					
						
							|  |  |  | 							if (err) return callback(err); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							const resultPath = /** @type {ResolveRequest} */ (result).path; | 
					
						
							| 
									
										
										
										
											2021-04-19 18:13:47 +08:00
										 |  |  | 							if (resultPath !== expectedResult) return callback(INVALID); | 
					
						
							| 
									
										
										
										
											2021-04-06 19:58:36 +08:00
										 |  |  | 							callback(); | 
					
						
							|  |  |  | 						}); | 
					
						
							|  |  |  | 						break; | 
					
						
							| 
									
										
										
										
											2021-01-15 17:50:02 +08:00
										 |  |  | 					case "e": | 
					
						
							| 
									
										
										
										
											2021-04-19 18:13:47 +08:00
										 |  |  | 						resolveEsm(context, path, {}, (err, _, result) => { | 
					
						
							| 
									
										
										
										
											2021-04-06 17:28:27 +08:00
										 |  |  | 							if (expectedResult === false) | 
					
						
							|  |  |  | 								return callback(err ? undefined : INVALID); | 
					
						
							| 
									
										
										
										
											2019-08-20 03:57:49 +08:00
										 |  |  | 							if (err) return callback(err); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							const resultPath = /** @type {ResolveRequest} */ (result).path; | 
					
						
							| 
									
										
										
										
											2021-04-19 18:13:47 +08:00
										 |  |  | 							if (resultPath !== expectedResult) return callback(INVALID); | 
					
						
							| 
									
										
										
										
											2019-08-20 03:57:49 +08:00
										 |  |  | 							callback(); | 
					
						
							|  |  |  | 						}); | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					default: | 
					
						
							|  |  |  | 						callback(new Error("Unexpected type in resolve result key")); | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			/** | 
					
						
							|  |  |  | 			 * @param {Error | typeof INVALID=} err error or invalid flag | 
					
						
							|  |  |  | 			 * @returns {void} | 
					
						
							|  |  |  | 			 */ | 
					
						
							|  |  |  | 			err => { | 
					
						
							|  |  |  | 				if (err === INVALID) { | 
					
						
							|  |  |  | 					return callback(null, false); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (err) { | 
					
						
							|  |  |  | 					return callback(err); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				return callback(null, true); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-18 05:35:05 +08:00
										 |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2023-06-22 05:55:05 +08:00
										 |  |  | 	 * @param {number | null | undefined} startTime when processing the files has started | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 	 * @param {Iterable<string> | null} files all files | 
					
						
							|  |  |  | 	 * @param {Iterable<string> | null} directories all directories | 
					
						
							|  |  |  | 	 * @param {Iterable<string> | null} missing all missing files or directories | 
					
						
							| 
									
										
										
										
											2023-06-22 05:55:05 +08:00
										 |  |  | 	 * @param {SnapshotOptions | null | undefined} options options object (for future extensions) | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	 * @param {function(WebpackError | null, Snapshot | null): void} callback callback function | 
					
						
							| 
									
										
										
										
											2019-07-18 05:35:05 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 	createSnapshot(startTime, files, directories, missing, options, callback) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {FileTimestamps} */ | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 		const fileTimestamps = new Map(); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {FileHashes} */ | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 		const fileHashes = new Map(); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {FileTshs} */ | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		const fileTshs = new Map(); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {ContextTimestamps} */ | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 		const contextTimestamps = new Map(); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {ContextHashes} */ | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 		const contextHashes = new Map(); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {ContextTshs} */ | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		const contextTshs = new Map(); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {MissingExistence} */ | 
					
						
							| 
									
										
										
										
											2020-03-13 19:09:14 +08:00
										 |  |  | 		const missingExistence = new Map(); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {ManagedItemInfo} */ | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 		const managedItemInfo = new Map(); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {ManagedFiles} */ | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		const managedFiles = new Set(); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {ManagedContexts} */ | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		const managedContexts = new Set(); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {ManagedMissing} */ | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		const managedMissing = new Set(); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** @type {Children} */ | 
					
						
							| 
									
										
										
										
											2020-01-31 17:59:28 +08:00
										 |  |  | 		const children = new Set(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 		const snapshot = new Snapshot(); | 
					
						
							|  |  |  | 		if (startTime) snapshot.setStartTime(startTime); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-28 21:01:19 +08:00
										 |  |  | 		/** @type {Set<string>} */ | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 		const managedItems = new Set(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		/** 1 = timestamp, 2 = hash, 3 = timestamp + hash */ | 
					
						
							|  |  |  | 		const mode = options && options.hash ? (options.timestamp ? 3 : 2) : 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 		let jobs = 1; | 
					
						
							|  |  |  | 		const jobDone = () => { | 
					
						
							|  |  |  | 			if (--jobs === 0) { | 
					
						
							| 
									
										
										
										
											2020-08-20 17:41:20 +08:00
										 |  |  | 				if (fileTimestamps.size !== 0) { | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 					snapshot.setFileTimestamps(fileTimestamps); | 
					
						
							| 
									
										
										
										
											2020-08-20 17:41:20 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				if (fileHashes.size !== 0) { | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 					snapshot.setFileHashes(fileHashes); | 
					
						
							| 
									
										
										
										
											2020-08-20 17:41:20 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 				if (fileTshs.size !== 0) { | 
					
						
							|  |  |  | 					snapshot.setFileTshs(fileTshs); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2020-08-20 17:41:20 +08:00
										 |  |  | 				if (contextTimestamps.size !== 0) { | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 					snapshot.setContextTimestamps(contextTimestamps); | 
					
						
							| 
									
										
										
										
											2020-08-20 17:41:20 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				if (contextHashes.size !== 0) { | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 					snapshot.setContextHashes(contextHashes); | 
					
						
							| 
									
										
										
										
											2020-08-20 17:41:20 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 				if (contextTshs.size !== 0) { | 
					
						
							|  |  |  | 					snapshot.setContextTshs(contextTshs); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2020-08-20 17:41:20 +08:00
										 |  |  | 				if (missingExistence.size !== 0) { | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 					snapshot.setMissingExistence(missingExistence); | 
					
						
							| 
									
										
										
										
											2020-08-20 17:41:20 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				if (managedItemInfo.size !== 0) { | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 					snapshot.setManagedItemInfo(managedItemInfo); | 
					
						
							| 
									
										
										
										
											2020-08-20 17:41:20 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 				this._managedFilesOptimization.optimize(snapshot, managedFiles); | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 				if (managedFiles.size !== 0) { | 
					
						
							|  |  |  | 					snapshot.setManagedFiles(managedFiles); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 				this._managedContextsOptimization.optimize(snapshot, managedContexts); | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 				if (managedContexts.size !== 0) { | 
					
						
							|  |  |  | 					snapshot.setManagedContexts(managedContexts); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 				this._managedMissingOptimization.optimize(snapshot, managedMissing); | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 				if (managedMissing.size !== 0) { | 
					
						
							|  |  |  | 					snapshot.setManagedMissing(managedMissing); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2020-08-20 17:41:20 +08:00
										 |  |  | 				if (children.size !== 0) { | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 					snapshot.setChildren(children); | 
					
						
							| 
									
										
										
										
											2020-08-20 17:41:20 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-11-08 00:31:18 +08:00
										 |  |  | 				this._snapshotCache.set(snapshot, true); | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 				this._statCreatedSnapshots++; | 
					
						
							| 
									
										
										
										
											2020-08-20 17:41:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 				callback(null, snapshot); | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2020-01-28 21:01:19 +08:00
										 |  |  | 		const jobError = () => { | 
					
						
							|  |  |  | 			if (jobs > 0) { | 
					
						
							|  |  |  | 				// large negative number instead of NaN or something else to keep jobs to stay a SMI (v8)
 | 
					
						
							|  |  |  | 				jobs = -100000000; | 
					
						
							|  |  |  | 				callback(null, null); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {string} path path | 
					
						
							|  |  |  | 		 * @param {Set<string>} managedSet managed set | 
					
						
							|  |  |  | 		 * @returns {boolean} true when managed | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		const checkManaged = (path, managedSet) => { | 
					
						
							| 
									
										
										
										
											2023-09-28 04:17:11 +08:00
										 |  |  | 			for (const unmanagedPath of this.unmanagedPathsRegExps) { | 
					
						
							|  |  |  | 				if (unmanagedPath.test(path)) return false; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			for (const unmanagedPath of this.unmanagedPathsWithSlash) { | 
					
						
							|  |  |  | 				if (path.startsWith(unmanagedPath)) return false; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-10-18 22:07:41 +08:00
										 |  |  | 			for (const immutablePath of this.immutablePathsRegExps) { | 
					
						
							|  |  |  | 				if (immutablePath.test(path)) { | 
					
						
							|  |  |  | 					managedSet.add(path); | 
					
						
							|  |  |  | 					return true; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 			for (const immutablePath of this.immutablePathsWithSlash) { | 
					
						
							|  |  |  | 				if (path.startsWith(immutablePath)) { | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 					managedSet.add(path); | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 					return true; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-10-18 22:07:41 +08:00
										 |  |  | 			for (const managedPath of this.managedPathsRegExps) { | 
					
						
							|  |  |  | 				const match = managedPath.exec(path); | 
					
						
							|  |  |  | 				if (match) { | 
					
						
							| 
									
										
										
										
											2021-10-20 16:41:48 +08:00
										 |  |  | 					const managedItem = getManagedItem(match[1], path); | 
					
						
							| 
									
										
										
										
											2021-10-18 22:07:41 +08:00
										 |  |  | 					if (managedItem) { | 
					
						
							|  |  |  | 						managedItems.add(managedItem); | 
					
						
							|  |  |  | 						managedSet.add(path); | 
					
						
							|  |  |  | 						return true; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 			for (const managedPath of this.managedPathsWithSlash) { | 
					
						
							|  |  |  | 				if (path.startsWith(managedPath)) { | 
					
						
							|  |  |  | 					const managedItem = getManagedItem(managedPath, path); | 
					
						
							|  |  |  | 					if (managedItem) { | 
					
						
							|  |  |  | 						managedItems.add(managedItem); | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 						managedSet.add(path); | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 						return true; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {Iterable<string>} items items | 
					
						
							|  |  |  | 		 * @param {Set<string>} managedSet managed set | 
					
						
							|  |  |  | 		 * @returns {Set<string>} result | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 		const captureNonManaged = (items, managedSet) => { | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 			const capturedItems = new Set(); | 
					
						
							|  |  |  | 			for (const path of items) { | 
					
						
							| 
									
										
										
										
											2020-08-23 03:54:34 +08:00
										 |  |  | 				if (!checkManaged(path, managedSet)) capturedItems.add(path); | 
					
						
							| 
									
										
										
										
											2020-08-20 17:17:55 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			return capturedItems; | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2023-06-22 08:59:10 +08:00
										 |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {Set<string>} capturedFiles captured files | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2021-11-15 21:18:58 +08:00
										 |  |  | 		const processCapturedFiles = capturedFiles => { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 			switch (mode) { | 
					
						
							|  |  |  | 				case 3: | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 					this._fileTshsOptimization.optimize(snapshot, capturedFiles); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 					for (const path of capturedFiles) { | 
					
						
							|  |  |  | 						const cache = this._fileTshs.get(path); | 
					
						
							|  |  |  | 						if (cache !== undefined) { | 
					
						
							|  |  |  | 							fileTshs.set(path, cache); | 
					
						
							|  |  |  | 						} else { | 
					
						
							|  |  |  | 							jobs++; | 
					
						
							|  |  |  | 							this._getFileTimestampAndHash(path, (err, entry) => { | 
					
						
							|  |  |  | 								if (err) { | 
					
						
							|  |  |  | 									if (this.logger) { | 
					
						
							|  |  |  | 										this.logger.debug( | 
					
						
							| 
									
										
										
										
											2021-01-14 03:37:45 +08:00
										 |  |  | 											`Error snapshotting file timestamp hash combination of ${path}: ${err.stack}` | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 										); | 
					
						
							|  |  |  | 									} | 
					
						
							|  |  |  | 									jobError(); | 
					
						
							|  |  |  | 								} else { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 									fileTshs.set(path, /** @type {TimestampAndHash} */ (entry)); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 									jobDone(); | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 								} | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 							}); | 
					
						
							| 
									
										
										
										
											2020-01-28 21:01:19 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				case 2: | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 					this._fileHashesOptimization.optimize(snapshot, capturedFiles); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 					for (const path of capturedFiles) { | 
					
						
							|  |  |  | 						const cache = this._fileHashes.get(path); | 
					
						
							|  |  |  | 						if (cache !== undefined) { | 
					
						
							|  |  |  | 							fileHashes.set(path, cache); | 
					
						
							|  |  |  | 						} else { | 
					
						
							|  |  |  | 							jobs++; | 
					
						
							|  |  |  | 							this.fileHashQueue.add(path, (err, entry) => { | 
					
						
							|  |  |  | 								if (err) { | 
					
						
							|  |  |  | 									if (this.logger) { | 
					
						
							|  |  |  | 										this.logger.debug( | 
					
						
							| 
									
										
										
										
											2021-01-14 03:37:45 +08:00
										 |  |  | 											`Error snapshotting file hash of ${path}: ${err.stack}` | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 										); | 
					
						
							|  |  |  | 									} | 
					
						
							|  |  |  | 									jobError(); | 
					
						
							|  |  |  | 								} else { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 									fileHashes.set(path, /** @type {string} */ (entry)); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 									jobDone(); | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 								} | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 							}); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				case 1: | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 					this._fileTimestampsOptimization.optimize(snapshot, capturedFiles); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 					for (const path of capturedFiles) { | 
					
						
							|  |  |  | 						const cache = this._fileTimestamps.get(path); | 
					
						
							|  |  |  | 						if (cache !== undefined) { | 
					
						
							|  |  |  | 							if (cache !== "ignore") { | 
					
						
							|  |  |  | 								fileTimestamps.set(path, cache); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 						} else { | 
					
						
							|  |  |  | 							jobs++; | 
					
						
							|  |  |  | 							this.fileTimestampQueue.add(path, (err, entry) => { | 
					
						
							|  |  |  | 								if (err) { | 
					
						
							|  |  |  | 									if (this.logger) { | 
					
						
							|  |  |  | 										this.logger.debug( | 
					
						
							| 
									
										
										
										
											2021-01-14 03:37:45 +08:00
										 |  |  | 											`Error snapshotting file timestamp of ${path}: ${err.stack}` | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 										); | 
					
						
							|  |  |  | 									} | 
					
						
							|  |  |  | 									jobError(); | 
					
						
							|  |  |  | 								} else { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 									fileTimestamps.set( | 
					
						
							|  |  |  | 										path, | 
					
						
							|  |  |  | 										/** @type {FileSystemInfoEntry} */ | 
					
						
							|  |  |  | 										(entry) | 
					
						
							|  |  |  | 									); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 									jobDone(); | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							}); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-11-15 21:18:58 +08:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 		if (files) { | 
					
						
							|  |  |  | 			processCapturedFiles(captureNonManaged(files, managedFiles)); | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {Set<string>} capturedDirectories captured directories | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2021-11-15 21:18:58 +08:00
										 |  |  | 		const processCapturedDirectories = capturedDirectories => { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 			switch (mode) { | 
					
						
							|  |  |  | 				case 3: | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 					this._contextTshsOptimization.optimize(snapshot, capturedDirectories); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 					for (const path of capturedDirectories) { | 
					
						
							|  |  |  | 						const cache = this._contextTshs.get(path); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 						/** @type {ResolvedContextTimestampAndHash | null | undefined} */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 						let resolved; | 
					
						
							|  |  |  | 						if ( | 
					
						
							|  |  |  | 							cache !== undefined && | 
					
						
							|  |  |  | 							(resolved = getResolvedTimestamp(cache)) !== undefined | 
					
						
							|  |  |  | 						) { | 
					
						
							|  |  |  | 							contextTshs.set(path, resolved); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 						} else { | 
					
						
							|  |  |  | 							jobs++; | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 							/** | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							 * @param {(WebpackError | null)=} err error | 
					
						
							|  |  |  | 							 * @param {(ResolvedContextTimestampAndHash | null)=} entry entry | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 							 * @returns {void} | 
					
						
							|  |  |  | 							 */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 							const callback = (err, entry) => { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 								if (err) { | 
					
						
							|  |  |  | 									if (this.logger) { | 
					
						
							|  |  |  | 										this.logger.debug( | 
					
						
							| 
									
										
										
										
											2021-01-14 03:37:45 +08:00
										 |  |  | 											`Error snapshotting context timestamp hash combination of ${path}: ${err.stack}` | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 										); | 
					
						
							|  |  |  | 									} | 
					
						
							|  |  |  | 									jobError(); | 
					
						
							|  |  |  | 								} else { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 									contextTshs.set( | 
					
						
							|  |  |  | 										path, | 
					
						
							|  |  |  | 										/** @type {ResolvedContextTimestampAndHash | null} */ | 
					
						
							|  |  |  | 										(entry) | 
					
						
							|  |  |  | 									); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 									jobDone(); | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 								} | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 							}; | 
					
						
							|  |  |  | 							if (cache !== undefined) { | 
					
						
							|  |  |  | 								this._resolveContextTsh(cache, callback); | 
					
						
							|  |  |  | 							} else { | 
					
						
							|  |  |  | 								this.getContextTsh(path, callback); | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2020-01-28 21:01:19 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				case 2: | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 					this._contextHashesOptimization.optimize( | 
					
						
							|  |  |  | 						snapshot, | 
					
						
							|  |  |  | 						capturedDirectories | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 					); | 
					
						
							|  |  |  | 					for (const path of capturedDirectories) { | 
					
						
							|  |  |  | 						const cache = this._contextHashes.get(path); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 						let resolved; | 
					
						
							|  |  |  | 						if ( | 
					
						
							|  |  |  | 							cache !== undefined && | 
					
						
							|  |  |  | 							(resolved = getResolvedHash(cache)) !== undefined | 
					
						
							|  |  |  | 						) { | 
					
						
							|  |  |  | 							contextHashes.set(path, resolved); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 						} else { | 
					
						
							|  |  |  | 							jobs++; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							/** | 
					
						
							|  |  |  | 							 * @param {(WebpackError | null)=} err err | 
					
						
							|  |  |  | 							 * @param {string=} entry entry | 
					
						
							|  |  |  | 							 */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 							const callback = (err, entry) => { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 								if (err) { | 
					
						
							|  |  |  | 									if (this.logger) { | 
					
						
							|  |  |  | 										this.logger.debug( | 
					
						
							| 
									
										
										
										
											2021-01-14 03:37:45 +08:00
										 |  |  | 											`Error snapshotting context hash of ${path}: ${err.stack}` | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 										); | 
					
						
							|  |  |  | 									} | 
					
						
							|  |  |  | 									jobError(); | 
					
						
							|  |  |  | 								} else { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 									contextHashes.set(path, /** @type {string} */ (entry)); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 									jobDone(); | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 								} | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 							}; | 
					
						
							|  |  |  | 							if (cache !== undefined) { | 
					
						
							|  |  |  | 								this._resolveContextHash(cache, callback); | 
					
						
							|  |  |  | 							} else { | 
					
						
							|  |  |  | 								this.getContextHash(path, callback); | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				case 1: | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 					this._contextTimestampsOptimization.optimize( | 
					
						
							|  |  |  | 						snapshot, | 
					
						
							|  |  |  | 						capturedDirectories | 
					
						
							|  |  |  | 					); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 					for (const path of capturedDirectories) { | 
					
						
							|  |  |  | 						const cache = this._contextTimestamps.get(path); | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 						if (cache === "ignore") continue; | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 						let resolved; | 
					
						
							|  |  |  | 						if ( | 
					
						
							|  |  |  | 							cache !== undefined && | 
					
						
							|  |  |  | 							(resolved = getResolvedTimestamp(cache)) !== undefined | 
					
						
							|  |  |  | 						) { | 
					
						
							|  |  |  | 							contextTimestamps.set(path, resolved); | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 						} else { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 							jobs++; | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 							/** | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							 * @param {(Error | null)=} err error | 
					
						
							|  |  |  | 							 * @param {(FileSystemInfoEntry | "ignore" | null)=} entry entry | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 							 * @returns {void} | 
					
						
							|  |  |  | 							 */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 							const callback = (err, entry) => { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 								if (err) { | 
					
						
							|  |  |  | 									if (this.logger) { | 
					
						
							|  |  |  | 										this.logger.debug( | 
					
						
							| 
									
										
										
										
											2021-01-14 03:37:45 +08:00
										 |  |  | 											`Error snapshotting context timestamp of ${path}: ${err.stack}` | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 										); | 
					
						
							|  |  |  | 									} | 
					
						
							|  |  |  | 									jobError(); | 
					
						
							|  |  |  | 								} else { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 									contextTimestamps.set( | 
					
						
							|  |  |  | 										path, | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 										/** @type {FileSystemInfoEntry | null} */ | 
					
						
							|  |  |  | 										(entry) | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 									); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 									jobDone(); | 
					
						
							|  |  |  | 								} | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 							}; | 
					
						
							|  |  |  | 							if (cache !== undefined) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 								this._resolveContextTimestamp( | 
					
						
							|  |  |  | 									/** @type {ContextFileSystemInfoEntry} */ | 
					
						
							|  |  |  | 									(cache), | 
					
						
							|  |  |  | 									callback | 
					
						
							|  |  |  | 								); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 							} else { | 
					
						
							|  |  |  | 								this.getContextTimestamp(path, callback); | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2019-01-09 20:23:26 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-11-15 21:18:58 +08:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 		if (directories) { | 
					
						
							|  |  |  | 			processCapturedDirectories( | 
					
						
							|  |  |  | 				captureNonManaged(directories, managedContexts) | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {Set<string>} capturedMissing captured missing | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2021-11-15 21:18:58 +08:00
										 |  |  | 		const processCapturedMissing = capturedMissing => { | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 			this._missingExistenceOptimization.optimize(snapshot, capturedMissing); | 
					
						
							| 
									
										
										
										
											2020-08-20 17:41:20 +08:00
										 |  |  | 			for (const path of capturedMissing) { | 
					
						
							| 
									
										
										
										
											2019-01-09 20:23:26 +08:00
										 |  |  | 				const cache = this._fileTimestamps.get(path); | 
					
						
							|  |  |  | 				if (cache !== undefined) { | 
					
						
							| 
									
										
										
										
											2020-01-28 21:01:19 +08:00
										 |  |  | 					if (cache !== "ignore") { | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 						missingExistence.set(path, Boolean(cache)); | 
					
						
							| 
									
										
										
										
											2020-01-28 21:01:19 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-01-09 20:23:26 +08:00
										 |  |  | 				} else { | 
					
						
							|  |  |  | 					jobs++; | 
					
						
							|  |  |  | 					this.fileTimestampQueue.add(path, (err, entry) => { | 
					
						
							|  |  |  | 						if (err) { | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 							if (this.logger) { | 
					
						
							|  |  |  | 								this.logger.debug( | 
					
						
							| 
									
										
										
										
											2021-01-14 03:37:45 +08:00
										 |  |  | 									`Error snapshotting missing timestamp of ${path}: ${err.stack}` | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 								); | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2020-01-28 21:01:19 +08:00
										 |  |  | 							jobError(); | 
					
						
							| 
									
										
										
										
											2019-01-09 20:23:26 +08:00
										 |  |  | 						} else { | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 							missingExistence.set(path, Boolean(entry)); | 
					
						
							| 
									
										
										
										
											2020-01-28 21:01:19 +08:00
										 |  |  | 							jobDone(); | 
					
						
							| 
									
										
										
										
											2019-01-09 20:23:26 +08:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					}); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-11-15 21:18:58 +08:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 		if (missing) { | 
					
						
							|  |  |  | 			processCapturedMissing(captureNonManaged(missing, managedMissing)); | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-09-08 03:06:46 +08:00
										 |  |  | 		this._managedItemInfoOptimization.optimize(snapshot, managedItems); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 		for (const path of managedItems) { | 
					
						
							|  |  |  | 			const cache = this._managedItems.get(path); | 
					
						
							|  |  |  | 			if (cache !== undefined) { | 
					
						
							| 
									
										
										
										
											2021-12-06 23:09:22 +08:00
										 |  |  | 				if (!cache.startsWith("*")) { | 
					
						
							| 
									
										
										
										
											2021-11-20 00:24:10 +08:00
										 |  |  | 					managedFiles.add(join(this.fs, path, "package.json")); | 
					
						
							| 
									
										
										
										
											2021-12-06 23:09:22 +08:00
										 |  |  | 				} else if (cache === "*nested") { | 
					
						
							|  |  |  | 					managedMissing.add(join(this.fs, path, "package.json")); | 
					
						
							| 
									
										
										
										
											2021-11-20 00:24:10 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 				managedItemInfo.set(path, cache); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				jobs++; | 
					
						
							|  |  |  | 				this.managedItemQueue.add(path, (err, entry) => { | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 					if (err) { | 
					
						
							|  |  |  | 						if (this.logger) { | 
					
						
							|  |  |  | 							this.logger.debug( | 
					
						
							| 
									
										
										
										
											2021-01-14 03:37:45 +08:00
										 |  |  | 								`Error snapshotting managed item ${path}: ${err.stack}` | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 							); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2020-01-28 21:01:19 +08:00
										 |  |  | 						jobError(); | 
					
						
							| 
									
										
										
										
											2021-11-15 21:18:58 +08:00
										 |  |  | 					} else if (entry) { | 
					
						
							| 
									
										
										
										
											2021-12-06 23:09:22 +08:00
										 |  |  | 						if (!entry.startsWith("*")) { | 
					
						
							| 
									
										
										
										
											2021-11-20 00:24:10 +08:00
										 |  |  | 							managedFiles.add(join(this.fs, path, "package.json")); | 
					
						
							| 
									
										
										
										
											2021-12-06 23:09:22 +08:00
										 |  |  | 						} else if (cache === "*nested") { | 
					
						
							|  |  |  | 							managedMissing.add(join(this.fs, path, "package.json")); | 
					
						
							| 
									
										
										
										
											2021-11-20 00:24:10 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 						managedItemInfo.set(path, entry); | 
					
						
							| 
									
										
										
										
											2020-01-28 21:01:19 +08:00
										 |  |  | 						jobDone(); | 
					
						
							| 
									
										
										
										
											2021-11-15 21:18:58 +08:00
										 |  |  | 					} else { | 
					
						
							|  |  |  | 						// Fallback to normal snapshotting
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 						/** | 
					
						
							|  |  |  | 						 * @param {Set<string>} set set | 
					
						
							|  |  |  | 						 * @param {function(Set<string>): void} fn fn | 
					
						
							|  |  |  | 						 */ | 
					
						
							| 
									
										
										
										
											2021-11-15 21:18:58 +08:00
										 |  |  | 						const process = (set, fn) => { | 
					
						
							|  |  |  | 							if (set.size === 0) return; | 
					
						
							|  |  |  | 							const captured = new Set(); | 
					
						
							|  |  |  | 							for (const file of set) { | 
					
						
							|  |  |  | 								if (file.startsWith(path)) captured.add(file); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							if (captured.size > 0) fn(captured); | 
					
						
							|  |  |  | 						}; | 
					
						
							|  |  |  | 						process(managedFiles, processCapturedFiles); | 
					
						
							|  |  |  | 						process(managedContexts, processCapturedDirectories); | 
					
						
							|  |  |  | 						process(managedMissing, processCapturedMissing); | 
					
						
							|  |  |  | 						jobDone(); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 		jobDone(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {Snapshot} snapshot1 a snapshot | 
					
						
							|  |  |  | 	 * @param {Snapshot} snapshot2 a snapshot | 
					
						
							|  |  |  | 	 * @returns {Snapshot} merged snapshot | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	mergeSnapshots(snapshot1, snapshot2) { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		const snapshot = new Snapshot(); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		if (snapshot1.hasStartTime() && snapshot2.hasStartTime()) { | 
					
						
							|  |  |  | 			snapshot.setStartTime( | 
					
						
							|  |  |  | 				Math.min( | 
					
						
							|  |  |  | 					/** @type {NonNullable<Snapshot["startTime"]>} */ | 
					
						
							|  |  |  | 					(snapshot1.startTime), | 
					
						
							|  |  |  | 					/** @type {NonNullable<Snapshot["startTime"]>} */ | 
					
						
							|  |  |  | 					(snapshot2.startTime) | 
					
						
							|  |  |  | 				) | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 		} else if (snapshot2.hasStartTime()) { | 
					
						
							|  |  |  | 			snapshot.startTime = snapshot2.startTime; | 
					
						
							|  |  |  | 		} else if (snapshot1.hasStartTime()) { | 
					
						
							|  |  |  | 			snapshot.startTime = snapshot1.startTime; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		if (snapshot1.hasFileTimestamps() || snapshot2.hasFileTimestamps()) { | 
					
						
							|  |  |  | 			snapshot.setFileTimestamps( | 
					
						
							|  |  |  | 				mergeMaps(snapshot1.fileTimestamps, snapshot2.fileTimestamps) | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (snapshot1.hasFileHashes() || snapshot2.hasFileHashes()) { | 
					
						
							|  |  |  | 			snapshot.setFileHashes( | 
					
						
							|  |  |  | 				mergeMaps(snapshot1.fileHashes, snapshot2.fileHashes) | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (snapshot1.hasFileTshs() || snapshot2.hasFileTshs()) { | 
					
						
							|  |  |  | 			snapshot.setFileTshs(mergeMaps(snapshot1.fileTshs, snapshot2.fileTshs)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (snapshot1.hasContextTimestamps() || snapshot2.hasContextTimestamps()) { | 
					
						
							|  |  |  | 			snapshot.setContextTimestamps( | 
					
						
							|  |  |  | 				mergeMaps(snapshot1.contextTimestamps, snapshot2.contextTimestamps) | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (snapshot1.hasContextHashes() || snapshot2.hasContextHashes()) { | 
					
						
							|  |  |  | 			snapshot.setContextHashes( | 
					
						
							|  |  |  | 				mergeMaps(snapshot1.contextHashes, snapshot2.contextHashes) | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 			); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		if (snapshot1.hasContextTshs() || snapshot2.hasContextTshs()) { | 
					
						
							|  |  |  | 			snapshot.setContextTshs( | 
					
						
							|  |  |  | 				mergeMaps(snapshot1.contextTshs, snapshot2.contextTshs) | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 			); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		if (snapshot1.hasMissingExistence() || snapshot2.hasMissingExistence()) { | 
					
						
							|  |  |  | 			snapshot.setMissingExistence( | 
					
						
							|  |  |  | 				mergeMaps(snapshot1.missingExistence, snapshot2.missingExistence) | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 			); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		if (snapshot1.hasManagedItemInfo() || snapshot2.hasManagedItemInfo()) { | 
					
						
							|  |  |  | 			snapshot.setManagedItemInfo( | 
					
						
							|  |  |  | 				mergeMaps(snapshot1.managedItemInfo, snapshot2.managedItemInfo) | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 			); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		if (snapshot1.hasManagedFiles() || snapshot2.hasManagedFiles()) { | 
					
						
							|  |  |  | 			snapshot.setManagedFiles( | 
					
						
							|  |  |  | 				mergeSets(snapshot1.managedFiles, snapshot2.managedFiles) | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 			); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		if (snapshot1.hasManagedContexts() || snapshot2.hasManagedContexts()) { | 
					
						
							|  |  |  | 			snapshot.setManagedContexts( | 
					
						
							|  |  |  | 				mergeSets(snapshot1.managedContexts, snapshot2.managedContexts) | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 			); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		if (snapshot1.hasManagedMissing() || snapshot2.hasManagedMissing()) { | 
					
						
							|  |  |  | 			snapshot.setManagedMissing( | 
					
						
							|  |  |  | 				mergeSets(snapshot1.managedMissing, snapshot2.managedMissing) | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (snapshot1.hasChildren() || snapshot2.hasChildren()) { | 
					
						
							|  |  |  | 			snapshot.setChildren(mergeSets(snapshot1.children, snapshot2.children)); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-11-08 00:31:18 +08:00
										 |  |  | 		if ( | 
					
						
							|  |  |  | 			this._snapshotCache.get(snapshot1) === true && | 
					
						
							|  |  |  | 			this._snapshotCache.get(snapshot2) === true | 
					
						
							|  |  |  | 		) { | 
					
						
							|  |  |  | 			this._snapshotCache.set(snapshot, true); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 		return snapshot; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-18 05:35:05 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {Snapshot} snapshot the snapshot made | 
					
						
							| 
									
										
										
										
											2021-12-24 20:27:31 +08:00
										 |  |  | 	 * @param {function((WebpackError | null)=, boolean=): void} callback callback function | 
					
						
							| 
									
										
										
										
											2019-07-18 05:35:05 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 	checkSnapshotValid(snapshot, callback) { | 
					
						
							| 
									
										
										
										
											2019-10-27 14:38:06 +08:00
										 |  |  | 		const cachedResult = this._snapshotCache.get(snapshot); | 
					
						
							|  |  |  | 		if (cachedResult !== undefined) { | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 			this._statTestedSnapshotsCached++; | 
					
						
							| 
									
										
										
										
											2019-10-27 14:38:06 +08:00
										 |  |  | 			if (typeof cachedResult === "boolean") { | 
					
						
							|  |  |  | 				callback(null, cachedResult); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				cachedResult.push(callback); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 		this._statTestedSnapshotsNotCached++; | 
					
						
							| 
									
										
										
										
											2020-01-31 17:59:28 +08:00
										 |  |  | 		this._checkSnapshotValidNoCache(snapshot, callback); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {Snapshot} snapshot the snapshot made | 
					
						
							| 
									
										
										
										
											2021-12-24 20:27:31 +08:00
										 |  |  | 	 * @param {function((WebpackError | null)=, boolean=): void} callback callback function | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-01-31 17:59:28 +08:00
										 |  |  | 	_checkSnapshotValidNoCache(snapshot, callback) { | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		/** @type {number | undefined} */ | 
					
						
							| 
									
										
										
										
											2024-07-31 06:15:03 +08:00
										 |  |  | 		let startTime; | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		if (snapshot.hasStartTime()) { | 
					
						
							|  |  |  | 			startTime = snapshot.startTime; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 		let jobs = 1; | 
					
						
							|  |  |  | 		const jobDone = () => { | 
					
						
							|  |  |  | 			if (--jobs === 0) { | 
					
						
							| 
									
										
										
										
											2019-10-27 14:38:06 +08:00
										 |  |  | 				this._snapshotCache.set(snapshot, true); | 
					
						
							| 
									
										
										
										
											2019-11-01 19:16:30 +08:00
										 |  |  | 				callback(null, true); | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		const invalid = () => { | 
					
						
							|  |  |  | 			if (jobs > 0) { | 
					
						
							| 
									
										
										
										
											2019-11-01 19:16:30 +08:00
										 |  |  | 				// large negative number instead of NaN or something else to keep jobs to stay a SMI (v8)
 | 
					
						
							|  |  |  | 				jobs = -100000000; | 
					
						
							| 
									
										
										
										
											2019-10-27 14:38:06 +08:00
										 |  |  | 				this._snapshotCache.set(snapshot, false); | 
					
						
							| 
									
										
										
										
											2019-11-01 19:16:30 +08:00
										 |  |  | 				callback(null, false); | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {string} path path | 
					
						
							|  |  |  | 		 * @param {WebpackError} err err | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 		const invalidWithError = (path, err) => { | 
					
						
							|  |  |  | 			if (this._remainingLogs > 0) { | 
					
						
							| 
									
										
										
										
											2024-07-31 12:23:44 +08:00
										 |  |  | 				this._log(path, "error occurred: %s", err); | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			invalid(); | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {string} path file path | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		 * @param {string | null} current current hash | 
					
						
							|  |  |  | 		 * @param {string | null} snap snapshot hash | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 		 * @returns {boolean} true, if ok | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		const checkHash = (path, current, snap) => { | 
					
						
							|  |  |  | 			if (current !== snap) { | 
					
						
							|  |  |  | 				// If hash differ it's invalid
 | 
					
						
							|  |  |  | 				if (this._remainingLogs > 0) { | 
					
						
							| 
									
										
										
										
											2024-07-31 12:23:44 +08:00
										 |  |  | 					this._log(path, "hashes differ (%s != %s)", current, snap); | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				return false; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return true; | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2019-07-18 05:35:05 +08:00
										 |  |  | 		/** | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 		 * @param {string} path file path | 
					
						
							| 
									
										
										
										
											2020-01-28 21:01:19 +08:00
										 |  |  | 		 * @param {boolean} current current entry | 
					
						
							|  |  |  | 		 * @param {boolean} snap entry from snapshot | 
					
						
							| 
									
										
										
										
											2019-07-18 05:35:05 +08:00
										 |  |  | 		 * @returns {boolean} true, if ok | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2020-03-13 19:09:14 +08:00
										 |  |  | 		const checkExistence = (path, current, snap) => { | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 			if (!current !== !snap) { | 
					
						
							| 
									
										
										
										
											2020-03-10 09:59:46 +08:00
										 |  |  | 				// If existence of item differs
 | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 				// it's invalid
 | 
					
						
							|  |  |  | 				if (this._remainingLogs > 0) { | 
					
						
							|  |  |  | 					this._log( | 
					
						
							|  |  |  | 						path, | 
					
						
							|  |  |  | 						current ? "it didn't exist before" : "it does no longer exist" | 
					
						
							|  |  |  | 					); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				return false; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return true; | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2019-07-18 05:35:05 +08:00
										 |  |  | 		/** | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 		 * @param {string} path file path | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		 * @param {FileSystemInfoEntry | null} c current entry | 
					
						
							|  |  |  | 		 * @param {FileSystemInfoEntry | null} s entry from snapshot | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		 * @param {boolean} log log reason | 
					
						
							| 
									
										
										
										
											2019-07-18 05:35:05 +08:00
										 |  |  | 		 * @returns {boolean} true, if ok | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		const checkFile = (path, c, s, log = true) => { | 
					
						
							|  |  |  | 			if (c === s) return true; | 
					
						
							|  |  |  | 			if (!checkExistence(path, Boolean(c), Boolean(s))) return false; | 
					
						
							|  |  |  | 			if (c) { | 
					
						
							| 
									
										
										
										
											2019-01-09 20:23:26 +08:00
										 |  |  | 				// For existing items only
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				if (typeof startTime === "number" && c.safeTime > startTime) { | 
					
						
							| 
									
										
										
										
											2020-01-28 21:01:19 +08:00
										 |  |  | 					// If a change happened after starting reading the item
 | 
					
						
							|  |  |  | 					// this may no longer be valid
 | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 					if (log && this._remainingLogs > 0) { | 
					
						
							| 
									
										
										
										
											2020-01-28 21:01:19 +08:00
										 |  |  | 						this._log( | 
					
						
							|  |  |  | 							path, | 
					
						
							| 
									
										
										
										
											2024-07-31 12:23:44 +08:00
										 |  |  | 							"it may have changed (%d) after the start time of the snapshot (%d)", | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							c.safeTime, | 
					
						
							| 
									
										
										
										
											2020-01-28 21:01:19 +08:00
										 |  |  | 							startTime | 
					
						
							|  |  |  | 						); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					return false; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				const snap = /** @type {FileSystemInfoEntry} */ (s); | 
					
						
							|  |  |  | 				if (snap.timestamp !== undefined && c.timestamp !== snap.timestamp) { | 
					
						
							| 
									
										
										
										
											2019-01-09 20:23:26 +08:00
										 |  |  | 					// If we have a timestamp (it was a file or symlink) and it differs from current timestamp
 | 
					
						
							|  |  |  | 					// it's invalid
 | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 					if (log && this._remainingLogs > 0) { | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 						this._log( | 
					
						
							|  |  |  | 							path, | 
					
						
							| 
									
										
										
										
											2024-07-31 12:23:44 +08:00
										 |  |  | 							"timestamps differ (%d != %d)", | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							c.timestamp, | 
					
						
							| 
									
										
										
										
											2019-11-15 00:28:10 +08:00
										 |  |  | 							snap.timestamp | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 						); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-01-09 20:23:26 +08:00
										 |  |  | 					return false; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {string} path file path | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		 * @param {ResolvedContextFileSystemInfoEntry | null} c current entry | 
					
						
							|  |  |  | 		 * @param {ResolvedContextFileSystemInfoEntry | null} s entry from snapshot | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 		 * @param {boolean} log log reason | 
					
						
							|  |  |  | 		 * @returns {boolean} true, if ok | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		const checkContext = (path, c, s, log = true) => { | 
					
						
							|  |  |  | 			if (c === s) return true; | 
					
						
							|  |  |  | 			if (!checkExistence(path, Boolean(c), Boolean(s))) return false; | 
					
						
							|  |  |  | 			if (c) { | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 				// For existing items only
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				if (typeof startTime === "number" && c.safeTime > startTime) { | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 					// If a change happened after starting reading the item
 | 
					
						
							|  |  |  | 					// this may no longer be valid
 | 
					
						
							|  |  |  | 					if (log && this._remainingLogs > 0) { | 
					
						
							|  |  |  | 						this._log( | 
					
						
							|  |  |  | 							path, | 
					
						
							| 
									
										
										
										
											2024-07-31 12:23:44 +08:00
										 |  |  | 							"it may have changed (%d) after the start time of the snapshot (%d)", | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							c.safeTime, | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 							startTime | 
					
						
							|  |  |  | 						); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					return false; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				const snap = /** @type {ResolvedContextFileSystemInfoEntry} */ (s); | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 				if ( | 
					
						
							|  |  |  | 					snap.timestampHash !== undefined && | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 					c.timestampHash !== snap.timestampHash | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 				) { | 
					
						
							|  |  |  | 					// If we have a timestampHash (it was a directory) and it differs from current timestampHash
 | 
					
						
							|  |  |  | 					// it's invalid
 | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 					if (log && this._remainingLogs > 0) { | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 						this._log( | 
					
						
							|  |  |  | 							path, | 
					
						
							| 
									
										
										
										
											2024-07-31 12:23:44 +08:00
										 |  |  | 							"timestamps hashes differ (%s != %s)", | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							c.timestampHash, | 
					
						
							| 
									
										
										
										
											2019-11-15 00:28:10 +08:00
										 |  |  | 							snap.timestampHash | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 						); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 					return false; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-01-09 20:23:26 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			return true; | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		if (snapshot.hasChildren()) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			/** | 
					
						
							|  |  |  | 			 * @param {(WebpackError | null)=} err err | 
					
						
							|  |  |  | 			 * @param {boolean=} result result | 
					
						
							|  |  |  | 			 * @returns {void} | 
					
						
							|  |  |  | 			 */ | 
					
						
							| 
									
										
										
										
											2020-01-31 17:59:28 +08:00
										 |  |  | 			const childCallback = (err, result) => { | 
					
						
							|  |  |  | 				if (err || !result) return invalid(); | 
					
						
							| 
									
										
										
										
											2024-07-31 04:21:27 +08:00
										 |  |  | 				jobDone(); | 
					
						
							| 
									
										
										
										
											2020-01-31 17:59:28 +08:00
										 |  |  | 			}; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			for (const child of /** @type {Children} */ (snapshot.children)) { | 
					
						
							| 
									
										
										
										
											2020-01-31 17:59:28 +08:00
										 |  |  | 				const cache = this._snapshotCache.get(child); | 
					
						
							|  |  |  | 				if (cache !== undefined) { | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 					this._statTestedChildrenCached++; | 
					
						
							|  |  |  | 					/* istanbul ignore else */ | 
					
						
							|  |  |  | 					if (typeof cache === "boolean") { | 
					
						
							|  |  |  | 						if (cache === false) { | 
					
						
							|  |  |  | 							invalid(); | 
					
						
							|  |  |  | 							return; | 
					
						
							| 
									
										
										
										
											2020-01-31 17:59:28 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 					} else { | 
					
						
							|  |  |  | 						jobs++; | 
					
						
							|  |  |  | 						cache.push(childCallback); | 
					
						
							| 
									
										
										
										
											2020-01-31 17:59:28 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 					this._statTestedChildrenNotCached++; | 
					
						
							| 
									
										
										
										
											2020-01-31 17:59:28 +08:00
										 |  |  | 					jobs++; | 
					
						
							|  |  |  | 					this._checkSnapshotValidNoCache(child, childCallback); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		if (snapshot.hasFileTimestamps()) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			const fileTimestamps = | 
					
						
							|  |  |  | 				/** @type {FileTimestamps} */ | 
					
						
							|  |  |  | 				(snapshot.fileTimestamps); | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 			this._statTestedEntries += fileTimestamps.size; | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 			for (const [path, ts] of fileTimestamps) { | 
					
						
							|  |  |  | 				const cache = this._fileTimestamps.get(path); | 
					
						
							|  |  |  | 				if (cache !== undefined) { | 
					
						
							| 
									
										
										
										
											2020-01-28 21:01:19 +08:00
										 |  |  | 					if (cache !== "ignore" && !checkFile(path, cache, ts)) { | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 						invalid(); | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 						return; | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					jobs++; | 
					
						
							|  |  |  | 					this.fileTimestampQueue.add(path, (err, entry) => { | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 						if (err) return invalidWithError(path, err); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 						if ( | 
					
						
							|  |  |  | 							!checkFile( | 
					
						
							|  |  |  | 								path, | 
					
						
							|  |  |  | 								/** @type {FileSystemInfoEntry | null} */ (entry), | 
					
						
							|  |  |  | 								ts | 
					
						
							|  |  |  | 							) | 
					
						
							|  |  |  | 						) { | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 							invalid(); | 
					
						
							|  |  |  | 						} else { | 
					
						
							|  |  |  | 							jobDone(); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-06-22 05:55:05 +08:00
										 |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {string} path file path | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		 * @param {string | null} hash hash | 
					
						
							| 
									
										
										
										
											2023-06-22 05:55:05 +08:00
										 |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		const processFileHashSnapshot = (path, hash) => { | 
					
						
							|  |  |  | 			const cache = this._fileHashes.get(path); | 
					
						
							|  |  |  | 			if (cache !== undefined) { | 
					
						
							|  |  |  | 				if (cache !== "ignore" && !checkHash(path, cache, hash)) { | 
					
						
							|  |  |  | 					invalid(); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				jobs++; | 
					
						
							|  |  |  | 				this.fileHashQueue.add(path, (err, entry) => { | 
					
						
							|  |  |  | 					if (err) return invalidWithError(path, err); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 					if (!checkHash(path, /** @type {string} */ (entry), hash)) { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 						invalid(); | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						jobDone(); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		if (snapshot.hasFileHashes()) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			const fileHashes = /** @type {FileHashes} */ (snapshot.fileHashes); | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 			this._statTestedEntries += fileHashes.size; | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 			for (const [path, hash] of fileHashes) { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 				processFileHashSnapshot(path, hash); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (snapshot.hasFileTshs()) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			const fileTshs = /** @type {FileTshs} */ (snapshot.fileTshs); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 			this._statTestedEntries += fileTshs.size; | 
					
						
							|  |  |  | 			for (const [path, tsh] of fileTshs) { | 
					
						
							|  |  |  | 				if (typeof tsh === "string") { | 
					
						
							|  |  |  | 					processFileHashSnapshot(path, tsh); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 					const cache = this._fileTimestamps.get(path); | 
					
						
							|  |  |  | 					if (cache !== undefined) { | 
					
						
							|  |  |  | 						if (cache === "ignore" || !checkFile(path, cache, tsh, false)) { | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 							processFileHashSnapshot(path, tsh && tsh.hash); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 					} else { | 
					
						
							|  |  |  | 						jobs++; | 
					
						
							|  |  |  | 						this.fileTimestampQueue.add(path, (err, entry) => { | 
					
						
							|  |  |  | 							if (err) return invalidWithError(path, err); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							if ( | 
					
						
							|  |  |  | 								!checkFile( | 
					
						
							|  |  |  | 									path, | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 									/** @type {FileSystemInfoEntry | null} */ | 
					
						
							|  |  |  | 									(entry), | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 									tsh, | 
					
						
							|  |  |  | 									false | 
					
						
							|  |  |  | 								) | 
					
						
							|  |  |  | 							) { | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 								processFileHashSnapshot(path, tsh && tsh.hash); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 							} | 
					
						
							|  |  |  | 							jobDone(); | 
					
						
							|  |  |  | 						}); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		if (snapshot.hasContextTimestamps()) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			const contextTimestamps = | 
					
						
							|  |  |  | 				/** @type {ContextTimestamps} */ | 
					
						
							|  |  |  | 				(snapshot.contextTimestamps); | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 			this._statTestedEntries += contextTimestamps.size; | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 			for (const [path, ts] of contextTimestamps) { | 
					
						
							|  |  |  | 				const cache = this._contextTimestamps.get(path); | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 				if (cache === "ignore") continue; | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 				let resolved; | 
					
						
							|  |  |  | 				if ( | 
					
						
							|  |  |  | 					cache !== undefined && | 
					
						
							|  |  |  | 					(resolved = getResolvedTimestamp(cache)) !== undefined | 
					
						
							|  |  |  | 				) { | 
					
						
							|  |  |  | 					if (!checkContext(path, resolved, ts)) { | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 						invalid(); | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 						return; | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 					jobs++; | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 					/** | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 					 * @param {(WebpackError | null)=} err error | 
					
						
							|  |  |  | 					 * @param {(ResolvedContextFileSystemInfoEntry | "ignore" | null)=} entry entry | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 					 * @returns {void} | 
					
						
							|  |  |  | 					 */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 					const callback = (err, entry) => { | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 						if (err) return invalidWithError(path, err); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 						if ( | 
					
						
							|  |  |  | 							!checkContext( | 
					
						
							|  |  |  | 								path, | 
					
						
							|  |  |  | 								/** @type {ResolvedContextFileSystemInfoEntry | null} */ | 
					
						
							|  |  |  | 								(entry), | 
					
						
							|  |  |  | 								ts | 
					
						
							|  |  |  | 							) | 
					
						
							|  |  |  | 						) { | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 							invalid(); | 
					
						
							|  |  |  | 						} else { | 
					
						
							|  |  |  | 							jobDone(); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 					}; | 
					
						
							|  |  |  | 					if (cache !== undefined) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 						this._resolveContextTimestamp( | 
					
						
							|  |  |  | 							/** @type {ContextFileSystemInfoEntry} */ | 
					
						
							|  |  |  | 							(cache), | 
					
						
							|  |  |  | 							callback | 
					
						
							|  |  |  | 						); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 					} else { | 
					
						
							|  |  |  | 						this.getContextTimestamp(path, callback); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {string} path path | 
					
						
							|  |  |  | 		 * @param {string | null} hash hash | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		const processContextHashSnapshot = (path, hash) => { | 
					
						
							|  |  |  | 			const cache = this._contextHashes.get(path); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 			let resolved; | 
					
						
							|  |  |  | 			if ( | 
					
						
							|  |  |  | 				cache !== undefined && | 
					
						
							|  |  |  | 				(resolved = getResolvedHash(cache)) !== undefined | 
					
						
							|  |  |  | 			) { | 
					
						
							|  |  |  | 				if (!checkHash(path, resolved, hash)) { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 					invalid(); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				jobs++; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				/** | 
					
						
							|  |  |  | 				 * @param {(WebpackError | null)=} err err | 
					
						
							|  |  |  | 				 * @param {string=} entry entry | 
					
						
							|  |  |  | 				 * @returns {void} | 
					
						
							|  |  |  | 				 */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 				const callback = (err, entry) => { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 					if (err) return invalidWithError(path, err); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 					if (!checkHash(path, /** @type {string} */ (entry), hash)) { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 						invalid(); | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						jobDone(); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 				}; | 
					
						
							|  |  |  | 				if (cache !== undefined) { | 
					
						
							|  |  |  | 					this._resolveContextHash(cache, callback); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					this.getContextHash(path, callback); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		if (snapshot.hasContextHashes()) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			const contextHashes = | 
					
						
							|  |  |  | 				/** @type {ContextHashes} */ | 
					
						
							|  |  |  | 				(snapshot.contextHashes); | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 			this._statTestedEntries += contextHashes.size; | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 			for (const [path, hash] of contextHashes) { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 				processContextHashSnapshot(path, hash); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (snapshot.hasContextTshs()) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			const contextTshs = /** @type {ContextTshs} */ (snapshot.contextTshs); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 			this._statTestedEntries += contextTshs.size; | 
					
						
							|  |  |  | 			for (const [path, tsh] of contextTshs) { | 
					
						
							|  |  |  | 				if (typeof tsh === "string") { | 
					
						
							|  |  |  | 					processContextHashSnapshot(path, tsh); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 					const cache = this._contextTimestamps.get(path); | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 					if (cache === "ignore") continue; | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 					let resolved; | 
					
						
							|  |  |  | 					if ( | 
					
						
							|  |  |  | 						cache !== undefined && | 
					
						
							|  |  |  | 						(resolved = getResolvedTimestamp(cache)) !== undefined | 
					
						
							|  |  |  | 					) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 						if ( | 
					
						
							|  |  |  | 							!checkContext( | 
					
						
							|  |  |  | 								path, | 
					
						
							|  |  |  | 								/** @type {ResolvedContextFileSystemInfoEntry | null} */ | 
					
						
							|  |  |  | 								(resolved), | 
					
						
							|  |  |  | 								tsh, | 
					
						
							|  |  |  | 								false | 
					
						
							|  |  |  | 							) | 
					
						
							|  |  |  | 						) { | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 							processContextHashSnapshot(path, tsh && tsh.hash); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 					} else { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 						jobs++; | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 						/** | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 						 * @param {(WebpackError | null)=} err error | 
					
						
							|  |  |  | 						 * @param {(ResolvedContextFileSystemInfoEntry | "ignore" | null)=} entry entry | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 						 * @returns {void} | 
					
						
							|  |  |  | 						 */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 						const callback = (err, entry) => { | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 							if (err) return invalidWithError(path, err); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							if ( | 
					
						
							|  |  |  | 								!checkContext( | 
					
						
							|  |  |  | 									path, | 
					
						
							|  |  |  | 									// TODO: test with `"ignore"`
 | 
					
						
							|  |  |  | 									/** @type {ResolvedContextFileSystemInfoEntry | null} */ | 
					
						
							|  |  |  | 									(entry), | 
					
						
							|  |  |  | 									tsh, | 
					
						
							|  |  |  | 									false | 
					
						
							|  |  |  | 								) | 
					
						
							|  |  |  | 							) { | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 								processContextHashSnapshot(path, tsh && tsh.hash); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 							} | 
					
						
							|  |  |  | 							jobDone(); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 						}; | 
					
						
							|  |  |  | 						if (cache !== undefined) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							this._resolveContextTimestamp( | 
					
						
							|  |  |  | 								/** @type {ContextFileSystemInfoEntry} */ | 
					
						
							|  |  |  | 								(cache), | 
					
						
							|  |  |  | 								callback | 
					
						
							|  |  |  | 							); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 						} else { | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 							this.getContextTimestamp(path, callback); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		if (snapshot.hasMissingExistence()) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			const missingExistence = | 
					
						
							|  |  |  | 				/** @type {MissingExistence} */ | 
					
						
							|  |  |  | 				(snapshot.missingExistence); | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 			this._statTestedEntries += missingExistence.size; | 
					
						
							| 
									
										
										
										
											2020-03-13 19:09:14 +08:00
										 |  |  | 			for (const [path, existence] of missingExistence) { | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 				const cache = this._fileTimestamps.get(path); | 
					
						
							|  |  |  | 				if (cache !== undefined) { | 
					
						
							| 
									
										
										
										
											2020-01-28 21:01:19 +08:00
										 |  |  | 					if ( | 
					
						
							|  |  |  | 						cache !== "ignore" && | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 						!checkExistence(path, Boolean(cache), Boolean(existence)) | 
					
						
							| 
									
										
										
										
											2020-01-28 21:01:19 +08:00
										 |  |  | 					) { | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 						invalid(); | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 						return; | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 				} else { | 
					
						
							|  |  |  | 					jobs++; | 
					
						
							|  |  |  | 					this.fileTimestampQueue.add(path, (err, entry) => { | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 						if (err) return invalidWithError(path, err); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 						if (!checkExistence(path, Boolean(entry), Boolean(existence))) { | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 							invalid(); | 
					
						
							|  |  |  | 						} else { | 
					
						
							|  |  |  | 							jobDone(); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					}); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 		if (snapshot.hasManagedItemInfo()) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			const managedItemInfo = | 
					
						
							|  |  |  | 				/** @type {ManagedItemInfo} */ | 
					
						
							|  |  |  | 				(snapshot.managedItemInfo); | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 			this._statTestedEntries += managedItemInfo.size; | 
					
						
							| 
									
										
										
										
											2019-08-13 23:26:54 +08:00
										 |  |  | 			for (const [path, info] of managedItemInfo) { | 
					
						
							|  |  |  | 				const cache = this._managedItems.get(path); | 
					
						
							|  |  |  | 				if (cache !== undefined) { | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 					if (!checkHash(path, cache, info)) { | 
					
						
							| 
									
										
										
										
											2019-08-13 23:26:54 +08:00
										 |  |  | 						invalid(); | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 						return; | 
					
						
							| 
									
										
										
										
											2019-08-13 23:26:54 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					jobs++; | 
					
						
							|  |  |  | 					this.managedItemQueue.add(path, (err, entry) => { | 
					
						
							| 
									
										
										
										
											2019-11-04 17:06:53 +08:00
										 |  |  | 						if (err) return invalidWithError(path, err); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 						if (!checkHash(path, /** @type {string} */ (entry), info)) { | 
					
						
							| 
									
										
										
										
											2019-08-13 23:26:54 +08:00
										 |  |  | 							invalid(); | 
					
						
							|  |  |  | 						} else { | 
					
						
							|  |  |  | 							jobDone(); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					}); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 		jobDone(); | 
					
						
							| 
									
										
										
										
											2019-11-01 19:16:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// if there was an async action
 | 
					
						
							|  |  |  | 		// try to join multiple concurrent request for this snapshot
 | 
					
						
							|  |  |  | 		if (jobs > 0) { | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | 			const callbacks = [callback]; | 
					
						
							| 
									
										
										
										
											2019-11-01 19:16:30 +08:00
										 |  |  | 			callback = (err, result) => { | 
					
						
							|  |  |  | 				for (const callback of callbacks) callback(err, result); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 			this._snapshotCache.set(snapshot, callbacks); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-01-05 21:58:06 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @type {Processor<string, FileSystemInfoEntry>} | 
					
						
							|  |  |  | 	 * @private | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 	_readFileTimestamp(path, callback) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		this.fs.stat(path, (err, _stat) => { | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 			if (err) { | 
					
						
							|  |  |  | 				if (err.code === "ENOENT") { | 
					
						
							|  |  |  | 					this._fileTimestamps.set(path, null); | 
					
						
							| 
									
										
										
										
											2020-09-15 20:39:09 +08:00
										 |  |  | 					this._cachedDeprecatedFileTimestamps = undefined; | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 					return callback(null, null); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				return callback(/** @type {WebpackError} */ (err)); | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			const stat = /** @type {IStats} */ (_stat); | 
					
						
							| 
									
										
										
										
											2019-11-14 23:49:14 +08:00
										 |  |  | 			let ts; | 
					
						
							|  |  |  | 			if (stat.isDirectory()) { | 
					
						
							|  |  |  | 				ts = { | 
					
						
							|  |  |  | 					safeTime: 0, | 
					
						
							|  |  |  | 					timestamp: undefined | 
					
						
							|  |  |  | 				}; | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2024-07-31 11:11:11 +08:00
										 |  |  | 				const mtime = Number(stat.mtime); | 
					
						
							| 
									
										
										
										
											2019-01-09 20:23:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 23:49:14 +08:00
										 |  |  | 				if (mtime) applyMtime(mtime); | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 23:49:14 +08:00
										 |  |  | 				ts = { | 
					
						
							|  |  |  | 					safeTime: mtime ? mtime + FS_ACCURACY : Infinity, | 
					
						
							|  |  |  | 					timestamp: mtime | 
					
						
							|  |  |  | 				}; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			this._fileTimestamps.set(path, ts); | 
					
						
							| 
									
										
										
										
											2020-09-15 20:39:09 +08:00
										 |  |  | 			this._cachedDeprecatedFileTimestamps = undefined; | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			callback(null, ts); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @type {Processor<string, string>} | 
					
						
							|  |  |  | 	 * @private | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 	_readFileHash(path, callback) { | 
					
						
							|  |  |  | 		this.fs.readFile(path, (err, content) => { | 
					
						
							|  |  |  | 			if (err) { | 
					
						
							| 
									
										
										
										
											2020-08-21 03:57:44 +08:00
										 |  |  | 				if (err.code === "EISDIR") { | 
					
						
							|  |  |  | 					this._fileHashes.set(path, "directory"); | 
					
						
							|  |  |  | 					return callback(null, "directory"); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 				if (err.code === "ENOENT") { | 
					
						
							|  |  |  | 					this._fileHashes.set(path, null); | 
					
						
							|  |  |  | 					return callback(null, null); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2021-01-14 03:37:45 +08:00
										 |  |  | 				if (err.code === "ERR_FS_FILE_TOO_LARGE") { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 					/** @type {Logger} */ | 
					
						
							|  |  |  | 					(this.logger).warn(`Ignoring ${path} for hashing as it's very large`); | 
					
						
							| 
									
										
										
										
											2021-01-14 03:37:45 +08:00
										 |  |  | 					this._fileHashes.set(path, "too large"); | 
					
						
							|  |  |  | 					return callback(null, "too large"); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				return callback(/** @type {WebpackError} */ (err)); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-22 18:12:46 +08:00
										 |  |  | 			const hash = createHash(this._hashFunction); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-22 08:59:10 +08:00
										 |  |  | 			hash.update(/** @type {string | Buffer} */ (content)); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			const digest = /** @type {string} */ (hash.digest("hex")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			this._fileHashes.set(path, digest); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			callback(null, digest); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {string} path path | 
					
						
							|  |  |  | 	 * @param {function(WebpackError | null, TimestampAndHash=) : void} callback callback | 
					
						
							|  |  |  | 	 * @private | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 	_getFileTimestampAndHash(path, callback) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {string} hash hash | 
					
						
							|  |  |  | 		 * @returns {void} | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		const continueWithHash = hash => { | 
					
						
							|  |  |  | 			const cache = this._fileTimestamps.get(path); | 
					
						
							|  |  |  | 			if (cache !== undefined) { | 
					
						
							|  |  |  | 				if (cache !== "ignore") { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 					/** @type {TimestampAndHash} */ | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 					const result = { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 						.../** @type {FileSystemInfoEntry} */ (cache), | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 						hash | 
					
						
							|  |  |  | 					}; | 
					
						
							|  |  |  | 					this._fileTshs.set(path, result); | 
					
						
							|  |  |  | 					return callback(null, result); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2024-07-31 04:21:27 +08:00
										 |  |  | 				this._fileTshs.set(path, hash); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				return callback(null, /** @type {TODO} */ (hash)); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2024-07-31 04:21:27 +08:00
										 |  |  | 			this.fileTimestampQueue.add(path, (err, entry) => { | 
					
						
							|  |  |  | 				if (err) { | 
					
						
							|  |  |  | 					return callback(err); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				/** @type {TimestampAndHash} */ | 
					
						
							| 
									
										
										
										
											2024-07-31 04:21:27 +08:00
										 |  |  | 				const result = { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 					.../** @type {FileSystemInfoEntry} */ (entry), | 
					
						
							| 
									
										
										
										
											2024-07-31 04:21:27 +08:00
										 |  |  | 					hash | 
					
						
							|  |  |  | 				}; | 
					
						
							|  |  |  | 				this._fileTshs.set(path, result); | 
					
						
							|  |  |  | 				return callback(null, result); | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		const cache = this._fileHashes.get(path); | 
					
						
							|  |  |  | 		if (cache !== undefined) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			continueWithHash(/** @type {string} */ (cache)); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			this.fileHashQueue.add(path, (err, entry) => { | 
					
						
							|  |  |  | 				if (err) { | 
					
						
							|  |  |  | 					return callback(err); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				continueWithHash(/** @type {string} */ (entry)); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @template T | 
					
						
							|  |  |  | 	 * @template ItemType | 
					
						
							| 
									
										
										
										
											2024-06-11 21:09:50 +08:00
										 |  |  | 	 * @param {object} options options | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 	 * @param {string} options.path path | 
					
						
							|  |  |  | 	 * @param {function(string): ItemType} options.fromImmutablePath called when context item is an immutable path | 
					
						
							|  |  |  | 	 * @param {function(string): ItemType} options.fromManagedItem called when context item is a managed path | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	 * @param {function(string, string, function((WebpackError | null)=, ItemType=): void): void} options.fromSymlink called when context item is a symlink | 
					
						
							|  |  |  | 	 * @param {function(string, IStats, function((WebpackError | null)=, (ItemType | null)=): void): void} options.fromFile called when context item is a file | 
					
						
							|  |  |  | 	 * @param {function(string, IStats, function((WebpackError | null)=, ItemType=): void): void} options.fromDirectory called when context item is a directory | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 	 * @param {function(string[], ItemType[]): T} options.reduce called from all context items | 
					
						
							| 
									
										
										
										
											2023-06-22 08:59:10 +08:00
										 |  |  | 	 * @param {function((Error | null)=, (T | null)=): void} callback callback | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 	 */ | 
					
						
							|  |  |  | 	_readContext( | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			path, | 
					
						
							|  |  |  | 			fromImmutablePath, | 
					
						
							|  |  |  | 			fromManagedItem, | 
					
						
							|  |  |  | 			fromSymlink, | 
					
						
							|  |  |  | 			fromFile, | 
					
						
							|  |  |  | 			fromDirectory, | 
					
						
							|  |  |  | 			reduce | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		callback | 
					
						
							|  |  |  | 	) { | 
					
						
							| 
									
										
										
										
											2021-01-13 07:09:19 +08:00
										 |  |  | 		this.fs.readdir(path, (err, _files) => { | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 			if (err) { | 
					
						
							|  |  |  | 				if (err.code === "ENOENT") { | 
					
						
							|  |  |  | 					return callback(null, null); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				return callback(err); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-01-13 07:09:19 +08:00
										 |  |  | 			const files = /** @type {string[]} */ (_files) | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 				.map(file => file.normalize("NFC")) | 
					
						
							|  |  |  | 				.filter(file => !/^\./.test(file)) | 
					
						
							|  |  |  | 				.sort(); | 
					
						
							|  |  |  | 			asyncLib.map( | 
					
						
							|  |  |  | 				files, | 
					
						
							|  |  |  | 				(file, callback) => { | 
					
						
							|  |  |  | 					const child = join(this.fs, path, file); | 
					
						
							| 
									
										
										
										
											2021-10-18 22:07:41 +08:00
										 |  |  | 					for (const immutablePath of this.immutablePathsRegExps) { | 
					
						
							|  |  |  | 						if (immutablePath.test(path)) { | 
					
						
							|  |  |  | 							// ignore any immutable path for timestamping
 | 
					
						
							|  |  |  | 							return callback(null, fromImmutablePath(path)); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 					for (const immutablePath of this.immutablePathsWithSlash) { | 
					
						
							|  |  |  | 						if (path.startsWith(immutablePath)) { | 
					
						
							|  |  |  | 							// ignore any immutable path for timestamping
 | 
					
						
							| 
									
										
										
										
											2021-10-18 22:07:41 +08:00
										 |  |  | 							return callback(null, fromImmutablePath(path)); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					for (const managedPath of this.managedPathsRegExps) { | 
					
						
							|  |  |  | 						const match = managedPath.exec(path); | 
					
						
							|  |  |  | 						if (match) { | 
					
						
							| 
									
										
										
										
											2021-10-20 16:41:48 +08:00
										 |  |  | 							const managedItem = getManagedItem(match[1], path); | 
					
						
							| 
									
										
										
										
											2021-10-18 22:07:41 +08:00
										 |  |  | 							if (managedItem) { | 
					
						
							|  |  |  | 								// construct timestampHash from managed info
 | 
					
						
							|  |  |  | 								return this.managedItemQueue.add(managedItem, (err, info) => { | 
					
						
							|  |  |  | 									if (err) return callback(err); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 									return callback( | 
					
						
							|  |  |  | 										null, | 
					
						
							|  |  |  | 										fromManagedItem(/** @type {string} */ (info)) | 
					
						
							|  |  |  | 									); | 
					
						
							| 
									
										
										
										
											2021-10-18 22:07:41 +08:00
										 |  |  | 								}); | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					for (const managedPath of this.managedPathsWithSlash) { | 
					
						
							|  |  |  | 						if (path.startsWith(managedPath)) { | 
					
						
							|  |  |  | 							const managedItem = getManagedItem(managedPath, child); | 
					
						
							|  |  |  | 							if (managedItem) { | 
					
						
							|  |  |  | 								// construct timestampHash from managed info
 | 
					
						
							|  |  |  | 								return this.managedItemQueue.add(managedItem, (err, info) => { | 
					
						
							|  |  |  | 									if (err) return callback(err); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 									return callback( | 
					
						
							|  |  |  | 										null, | 
					
						
							|  |  |  | 										fromManagedItem(/** @type {string} */ (info)) | 
					
						
							|  |  |  | 									); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 								}); | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 					lstatReadlinkAbsolute(this.fs, child, (err, _stat) => { | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 						if (err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 						const stat = /** @type {IStats | string} */ (_stat); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 						if (typeof stat === "string") { | 
					
						
							|  |  |  | 							return fromSymlink(child, stat, callback); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 						if (stat.isFile()) { | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 							return fromFile(child, stat, callback); | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 						} | 
					
						
							|  |  |  | 						if (stat.isDirectory()) { | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 							return fromDirectory(child, stat, callback); | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 						} | 
					
						
							|  |  |  | 						callback(null, null); | 
					
						
							|  |  |  | 					}); | 
					
						
							|  |  |  | 				}, | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 				(err, results) => { | 
					
						
							| 
									
										
										
										
											2019-09-08 21:53:12 +08:00
										 |  |  | 					if (err) return callback(err); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 					const result = reduce(files, /** @type {ItemType[]} */ (results)); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 					callback(null, result); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @type {Processor<string, ContextFileSystemInfoEntry>} | 
					
						
							|  |  |  | 	 * @private | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 	_readContextTimestamp(path, callback) { | 
					
						
							|  |  |  | 		this._readContext( | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				path, | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				fromImmutablePath: () => | 
					
						
							|  |  |  | 					/** @type {ContextFileSystemInfoEntry | FileSystemInfoEntry | "ignore" | null} */ | 
					
						
							|  |  |  | 					(null), | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 				fromManagedItem: info => ({ | 
					
						
							|  |  |  | 					safeTime: 0, | 
					
						
							|  |  |  | 					timestampHash: info | 
					
						
							|  |  |  | 				}), | 
					
						
							|  |  |  | 				fromSymlink: (file, target, callback) => { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 					callback( | 
					
						
							|  |  |  | 						null, | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 						/** @type {ContextFileSystemInfoEntry} */ | 
					
						
							|  |  |  | 						({ | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							timestampHash: target, | 
					
						
							|  |  |  | 							symlinks: new Set([target]) | 
					
						
							|  |  |  | 						}) | 
					
						
							|  |  |  | 					); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 				}, | 
					
						
							|  |  |  | 				fromFile: (file, stat, callback) => { | 
					
						
							|  |  |  | 					// Prefer the cached value over our new stat to report consistent results
 | 
					
						
							|  |  |  | 					const cache = this._fileTimestamps.get(file); | 
					
						
							|  |  |  | 					if (cache !== undefined) | 
					
						
							|  |  |  | 						return callback(null, cache === "ignore" ? null : cache); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-31 11:11:11 +08:00
										 |  |  | 					const mtime = Number(stat.mtime); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					if (mtime) applyMtime(mtime); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 					/** @type {FileSystemInfoEntry} */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 					const ts = { | 
					
						
							|  |  |  | 						safeTime: mtime ? mtime + FS_ACCURACY : Infinity, | 
					
						
							|  |  |  | 						timestamp: mtime | 
					
						
							|  |  |  | 					}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					this._fileTimestamps.set(file, ts); | 
					
						
							|  |  |  | 					this._cachedDeprecatedFileTimestamps = undefined; | 
					
						
							|  |  |  | 					callback(null, ts); | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				fromDirectory: (directory, stat, callback) => { | 
					
						
							|  |  |  | 					this.contextTimestampQueue.increaseParallelism(); | 
					
						
							|  |  |  | 					this._getUnresolvedContextTimestamp(directory, (err, tsEntry) => { | 
					
						
							|  |  |  | 						this.contextTimestampQueue.decreaseParallelism(); | 
					
						
							|  |  |  | 						callback(err, tsEntry); | 
					
						
							|  |  |  | 					}); | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				reduce: (files, tsEntries) => { | 
					
						
							| 
									
										
										
										
											2024-07-31 06:15:03 +08:00
										 |  |  | 					let symlinks; | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-22 18:12:46 +08:00
										 |  |  | 					const hash = createHash(this._hashFunction); | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					for (const file of files) hash.update(file); | 
					
						
							|  |  |  | 					let safeTime = 0; | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 					for (const _e of tsEntries) { | 
					
						
							|  |  |  | 						if (!_e) { | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 							hash.update("n"); | 
					
						
							|  |  |  | 							continue; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 						const entry = | 
					
						
							|  |  |  | 							/** @type {FileSystemInfoEntry | ContextFileSystemInfoEntry} */ | 
					
						
							|  |  |  | 							(_e); | 
					
						
							|  |  |  | 						if (/** @type {FileSystemInfoEntry} */ (entry).timestamp) { | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 							hash.update("f"); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							hash.update( | 
					
						
							|  |  |  | 								`${/** @type {FileSystemInfoEntry} */ (entry).timestamp}` | 
					
						
							|  |  |  | 							); | 
					
						
							|  |  |  | 						} else if ( | 
					
						
							|  |  |  | 							/** @type {ContextFileSystemInfoEntry} */ (entry).timestampHash | 
					
						
							|  |  |  | 						) { | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 							hash.update("d"); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							hash.update( | 
					
						
							|  |  |  | 								`${/** @type {ContextFileSystemInfoEntry} */ (entry).timestampHash}` | 
					
						
							|  |  |  | 							); | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 						if ( | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							/** @type {ContextFileSystemInfoEntry} */ | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 							(entry).symlinks !== undefined | 
					
						
							|  |  |  | 						) { | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 							if (symlinks === undefined) symlinks = new Set(); | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 							addAll( | 
					
						
							|  |  |  | 								/** @type {ContextFileSystemInfoEntry} */ (entry).symlinks, | 
					
						
							|  |  |  | 								symlinks | 
					
						
							|  |  |  | 							); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 						if (entry.safeTime) { | 
					
						
							|  |  |  | 							safeTime = Math.max(safeTime, entry.safeTime); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					const digest = /** @type {string} */ (hash.digest("hex")); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 					/** @type {ContextFileSystemInfoEntry} */ | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 					const result = { | 
					
						
							|  |  |  | 						safeTime, | 
					
						
							|  |  |  | 						timestampHash: digest | 
					
						
							|  |  |  | 					}; | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 					if (symlinks) result.symlinks = symlinks; | 
					
						
							|  |  |  | 					return result; | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			(err, result) => { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				if (err) return callback(/** @type {WebpackError} */ (err)); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 				this._contextTimestamps.set(path, result); | 
					
						
							|  |  |  | 				this._cachedDeprecatedContextTimestamps = undefined; | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 				callback(null, result); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 		); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {ContextFileSystemInfoEntry} entry entry | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	 * @param {function((WebpackError | null)=, (ResolvedContextFileSystemInfoEntry | "ignore" | null)=): void} callback callback | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 	_resolveContextTimestamp(entry, callback) { | 
					
						
							| 
									
										
										
										
											2023-06-22 08:59:10 +08:00
										 |  |  | 		/** @type {string[]} */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 		const hashes = []; | 
					
						
							|  |  |  | 		let safeTime = 0; | 
					
						
							|  |  |  | 		processAsyncTree( | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			/** @type {NonNullable<ContextHash["symlinks"]>} */ (entry.symlinks), | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 			10, | 
					
						
							|  |  |  | 			(target, push, callback) => { | 
					
						
							|  |  |  | 				this._getUnresolvedContextTimestamp(target, (err, entry) => { | 
					
						
							|  |  |  | 					if (err) return callback(err); | 
					
						
							|  |  |  | 					if (entry && entry !== "ignore") { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 						hashes.push(/** @type {string} */ (entry.timestampHash)); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 						if (entry.safeTime) { | 
					
						
							|  |  |  | 							safeTime = Math.max(safeTime, entry.safeTime); | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 						if (entry.symlinks !== undefined) { | 
					
						
							|  |  |  | 							for (const target of entry.symlinks) push(target); | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					callback(); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			err => { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				if (err) return callback(/** @type {WebpackError} */ (err)); | 
					
						
							| 
									
										
										
										
											2021-09-22 18:12:46 +08:00
										 |  |  | 				const hash = createHash(this._hashFunction); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				hash.update(/** @type {string} */ (entry.timestampHash)); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 				if (entry.safeTime) { | 
					
						
							|  |  |  | 					safeTime = Math.max(safeTime, entry.safeTime); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				hashes.sort(); | 
					
						
							|  |  |  | 				for (const h of hashes) { | 
					
						
							|  |  |  | 					hash.update(h); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				callback( | 
					
						
							|  |  |  | 					null, | 
					
						
							|  |  |  | 					(entry.resolved = { | 
					
						
							|  |  |  | 						safeTime, | 
					
						
							|  |  |  | 						timestampHash: /** @type {string} */ (hash.digest("hex")) | 
					
						
							|  |  |  | 					}) | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @type {Processor<string, ContextHash>} | 
					
						
							|  |  |  | 	 * @private | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 	_readContextHash(path, callback) { | 
					
						
							|  |  |  | 		this._readContext( | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				path, | 
					
						
							| 
									
										
										
										
											2024-10-02 05:18:10 +08:00
										 |  |  | 				fromImmutablePath: () => /** @type {ContextHash | ""} */ (""), | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 				fromManagedItem: info => info || "", | 
					
						
							|  |  |  | 				fromSymlink: (file, target, callback) => { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 					callback( | 
					
						
							|  |  |  | 						null, | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 						/** @type {ContextHash} */ | 
					
						
							|  |  |  | 						({ | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							hash: target, | 
					
						
							|  |  |  | 							symlinks: new Set([target]) | 
					
						
							|  |  |  | 						}) | 
					
						
							|  |  |  | 					); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 				}, | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 				fromFile: (file, stat, callback) => | 
					
						
							|  |  |  | 					this.getFileHash(file, (err, hash) => { | 
					
						
							|  |  |  | 						callback(err, hash || ""); | 
					
						
							|  |  |  | 					}), | 
					
						
							|  |  |  | 				fromDirectory: (directory, stat, callback) => { | 
					
						
							|  |  |  | 					this.contextHashQueue.increaseParallelism(); | 
					
						
							|  |  |  | 					this._getUnresolvedContextHash(directory, (err, hash) => { | 
					
						
							|  |  |  | 						this.contextHashQueue.decreaseParallelism(); | 
					
						
							|  |  |  | 						callback(err, hash || ""); | 
					
						
							|  |  |  | 					}); | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				/** | 
					
						
							|  |  |  | 				 * @param {string[]} files files | 
					
						
							|  |  |  | 				 * @param {(string | ContextHash)[]} fileHashes hashes | 
					
						
							|  |  |  | 				 * @returns {ContextHash} reduced hash | 
					
						
							|  |  |  | 				 */ | 
					
						
							|  |  |  | 				reduce: (files, fileHashes) => { | 
					
						
							| 
									
										
										
										
											2024-07-31 06:15:03 +08:00
										 |  |  | 					let symlinks; | 
					
						
							| 
									
										
										
										
											2021-09-22 18:12:46 +08:00
										 |  |  | 					const hash = createHash(this._hashFunction); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					for (const file of files) hash.update(file); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 					for (const entry of fileHashes) { | 
					
						
							|  |  |  | 						if (typeof entry === "string") { | 
					
						
							|  |  |  | 							hash.update(entry); | 
					
						
							|  |  |  | 						} else { | 
					
						
							|  |  |  | 							hash.update(entry.hash); | 
					
						
							|  |  |  | 							if (entry.symlinks) { | 
					
						
							|  |  |  | 								if (symlinks === undefined) symlinks = new Set(); | 
					
						
							|  |  |  | 								addAll(entry.symlinks, symlinks); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 					/** @type {ContextHash} */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 					const result = { | 
					
						
							|  |  |  | 						hash: /** @type {string} */ (hash.digest("hex")) | 
					
						
							|  |  |  | 					}; | 
					
						
							|  |  |  | 					if (symlinks) result.symlinks = symlinks; | 
					
						
							|  |  |  | 					return result; | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			(err, _result) => { | 
					
						
							|  |  |  | 				if (err) return callback(/** @type {WebpackError} */ (err)); | 
					
						
							|  |  |  | 				const result = /** @type {ContextHash} */ (_result); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 				this._contextHashes.set(path, result); | 
					
						
							|  |  |  | 				return callback(null, result); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {ContextHash} entry context hash | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	 * @param {function(WebpackError | null, string=): void} callback callback | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 	_resolveContextHash(entry, callback) { | 
					
						
							| 
									
										
										
										
											2023-06-22 08:59:10 +08:00
										 |  |  | 		/** @type {string[]} */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 		const hashes = []; | 
					
						
							|  |  |  | 		processAsyncTree( | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			/** @type {NonNullable<ContextHash["symlinks"]>} */ (entry.symlinks), | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 			10, | 
					
						
							|  |  |  | 			(target, push, callback) => { | 
					
						
							|  |  |  | 				this._getUnresolvedContextHash(target, (err, hash) => { | 
					
						
							|  |  |  | 					if (err) return callback(err); | 
					
						
							|  |  |  | 					if (hash) { | 
					
						
							|  |  |  | 						hashes.push(hash.hash); | 
					
						
							|  |  |  | 						if (hash.symlinks !== undefined) { | 
					
						
							|  |  |  | 							for (const target of hash.symlinks) push(target); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					callback(); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			err => { | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 				if (err) return callback(/** @type {WebpackError} */ (err)); | 
					
						
							| 
									
										
										
										
											2021-09-22 18:12:46 +08:00
										 |  |  | 				const hash = createHash(this._hashFunction); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 				hash.update(entry.hash); | 
					
						
							|  |  |  | 				hashes.sort(); | 
					
						
							|  |  |  | 				for (const h of hashes) { | 
					
						
							|  |  |  | 					hash.update(h); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 				callback( | 
					
						
							|  |  |  | 					null, | 
					
						
							|  |  |  | 					(entry.resolved = /** @type {string} */ (hash.digest("hex"))) | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @type {Processor<string, ContextTimestampAndHash>} | 
					
						
							|  |  |  | 	 * @private | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 	_readContextTimestampAndHash(path, callback) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {ContextFileSystemInfoEntry | "ignore" | null} timestamp timestamp | 
					
						
							|  |  |  | 		 * @param {ContextHash} hash hash | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 		const finalize = (timestamp, hash) => { | 
					
						
							|  |  |  | 			const result = | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				/** @type {ContextTimestampAndHash} */ | 
					
						
							|  |  |  | 				(timestamp === "ignore" ? hash : { ...timestamp, ...hash }); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 			this._contextTshs.set(path, result); | 
					
						
							|  |  |  | 			callback(null, result); | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		const cachedHash = this._contextHashes.get(path); | 
					
						
							|  |  |  | 		const cachedTimestamp = this._contextTimestamps.get(path); | 
					
						
							|  |  |  | 		if (cachedHash !== undefined) { | 
					
						
							|  |  |  | 			if (cachedTimestamp !== undefined) { | 
					
						
							|  |  |  | 				finalize(cachedTimestamp, cachedHash); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				this.contextTimestampQueue.add(path, (err, entry) => { | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 					if (err) return callback(err); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 					finalize( | 
					
						
							| 
									
										
										
										
											2024-08-06 22:14:33 +08:00
										 |  |  | 						/** @type {ContextFileSystemInfoEntry} */ | 
					
						
							|  |  |  | 						(entry), | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 						cachedHash | 
					
						
							|  |  |  | 					); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 				}); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2024-07-31 04:54:55 +08:00
										 |  |  | 		} else if (cachedTimestamp !== undefined) { | 
					
						
							|  |  |  | 			this.contextHashQueue.add(path, (err, entry) => { | 
					
						
							|  |  |  | 				if (err) return callback(err); | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				finalize(cachedTimestamp, /** @type {ContextHash} */ (entry)); | 
					
						
							| 
									
										
										
										
											2024-07-31 04:54:55 +08:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2024-07-31 04:54:55 +08:00
										 |  |  | 			this._readContext( | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					path, | 
					
						
							| 
									
										
										
										
											2024-10-02 05:18:10 +08:00
										 |  |  | 					fromImmutablePath: () => | 
					
						
							|  |  |  | 						/** @type {ContextTimestampAndHash | null} */ (null), | 
					
						
							| 
									
										
										
										
											2024-07-31 04:54:55 +08:00
										 |  |  | 					fromManagedItem: info => ({ | 
					
						
							|  |  |  | 						safeTime: 0, | 
					
						
							|  |  |  | 						timestampHash: info, | 
					
						
							|  |  |  | 						hash: info || "" | 
					
						
							|  |  |  | 					}), | 
					
						
							|  |  |  | 					fromSymlink: (file, target, callback) => { | 
					
						
							| 
									
										
										
										
											2024-10-02 05:18:10 +08:00
										 |  |  | 						callback( | 
					
						
							|  |  |  | 							null, | 
					
						
							|  |  |  | 							/** @type {TODO} */ | 
					
						
							|  |  |  | 							({ | 
					
						
							|  |  |  | 								timestampHash: target, | 
					
						
							|  |  |  | 								hash: target, | 
					
						
							|  |  |  | 								symlinks: new Set([target]) | 
					
						
							|  |  |  | 							}) | 
					
						
							|  |  |  | 						); | 
					
						
							| 
									
										
										
										
											2024-07-31 04:54:55 +08:00
										 |  |  | 					}, | 
					
						
							|  |  |  | 					fromFile: (file, stat, callback) => { | 
					
						
							|  |  |  | 						this._getFileTimestampAndHash(file, callback); | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 					fromDirectory: (directory, stat, callback) => { | 
					
						
							|  |  |  | 						this.contextTshQueue.increaseParallelism(); | 
					
						
							|  |  |  | 						this.contextTshQueue.add(directory, (err, result) => { | 
					
						
							|  |  |  | 							this.contextTshQueue.decreaseParallelism(); | 
					
						
							|  |  |  | 							callback(err, result); | 
					
						
							|  |  |  | 						}); | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 					/** | 
					
						
							|  |  |  | 					 * @param {string[]} files files | 
					
						
							|  |  |  | 					 * @param {(Partial<TimestampAndHash> & Partial<ContextTimestampAndHash> | string | null)[]} results results | 
					
						
							|  |  |  | 					 * @returns {ContextTimestampAndHash} tsh | 
					
						
							|  |  |  | 					 */ | 
					
						
							|  |  |  | 					reduce: (files, results) => { | 
					
						
							| 
									
										
										
										
											2024-07-31 06:15:03 +08:00
										 |  |  | 						let symlinks; | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-31 04:54:55 +08:00
										 |  |  | 						const tsHash = createHash(this._hashFunction); | 
					
						
							|  |  |  | 						const hash = createHash(this._hashFunction); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-31 04:54:55 +08:00
										 |  |  | 						for (const file of files) { | 
					
						
							|  |  |  | 							tsHash.update(file); | 
					
						
							|  |  |  | 							hash.update(file); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						let safeTime = 0; | 
					
						
							|  |  |  | 						for (const entry of results) { | 
					
						
							|  |  |  | 							if (!entry) { | 
					
						
							|  |  |  | 								tsHash.update("n"); | 
					
						
							|  |  |  | 								continue; | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2024-07-31 04:54:55 +08:00
										 |  |  | 							if (typeof entry === "string") { | 
					
						
							|  |  |  | 								tsHash.update("n"); | 
					
						
							|  |  |  | 								hash.update(entry); | 
					
						
							|  |  |  | 								continue; | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2024-07-31 04:54:55 +08:00
										 |  |  | 							if (entry.timestamp) { | 
					
						
							|  |  |  | 								tsHash.update("f"); | 
					
						
							|  |  |  | 								tsHash.update(`${entry.timestamp}`); | 
					
						
							|  |  |  | 							} else if (entry.timestampHash) { | 
					
						
							|  |  |  | 								tsHash.update("d"); | 
					
						
							|  |  |  | 								tsHash.update(`${entry.timestampHash}`); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							if (entry.symlinks !== undefined) { | 
					
						
							|  |  |  | 								if (symlinks === undefined) symlinks = new Set(); | 
					
						
							|  |  |  | 								addAll(entry.symlinks, symlinks); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							if (entry.safeTime) { | 
					
						
							|  |  |  | 								safeTime = Math.max(safeTime, entry.safeTime); | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							hash.update(/** @type {string} */ (entry.hash)); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2024-07-31 04:54:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 						/** @type {ContextTimestampAndHash} */ | 
					
						
							| 
									
										
										
										
											2024-07-31 04:54:55 +08:00
										 |  |  | 						const result = { | 
					
						
							|  |  |  | 							safeTime, | 
					
						
							|  |  |  | 							timestampHash: /** @type {string} */ (tsHash.digest("hex")), | 
					
						
							|  |  |  | 							hash: /** @type {string} */ (hash.digest("hex")) | 
					
						
							|  |  |  | 						}; | 
					
						
							|  |  |  | 						if (symlinks) result.symlinks = symlinks; | 
					
						
							|  |  |  | 						return result; | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2024-07-31 04:54:55 +08:00
										 |  |  | 				}, | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				(err, _result) => { | 
					
						
							|  |  |  | 					if (err) return callback(/** @type {WebpackError} */ (err)); | 
					
						
							|  |  |  | 					const result = /** @type {ContextTimestampAndHash} */ (_result); | 
					
						
							| 
									
										
										
										
											2024-07-31 04:54:55 +08:00
										 |  |  | 					this._contextTshs.set(path, result); | 
					
						
							|  |  |  | 					return callback(null, result); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2020-08-26 06:36:16 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {ContextTimestampAndHash} entry entry | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	 * @param {ProcessorCallback<ResolvedContextTimestampAndHash>} callback callback | 
					
						
							| 
									
										
										
										
											2021-10-13 16:25:25 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 	_resolveContextTsh(entry, callback) { | 
					
						
							| 
									
										
										
										
											2023-06-22 08:59:10 +08:00
										 |  |  | 		/** @type {string[]} */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 		const hashes = []; | 
					
						
							| 
									
										
										
										
											2023-06-22 08:59:10 +08:00
										 |  |  | 		/** @type {string[]} */ | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 		const tsHashes = []; | 
					
						
							|  |  |  | 		let safeTime = 0; | 
					
						
							|  |  |  | 		processAsyncTree( | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			/** @type {NonNullable<ContextHash["symlinks"]>} */ (entry.symlinks), | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 			10, | 
					
						
							|  |  |  | 			(target, push, callback) => { | 
					
						
							|  |  |  | 				this._getUnresolvedContextTsh(target, (err, entry) => { | 
					
						
							|  |  |  | 					if (err) return callback(err); | 
					
						
							|  |  |  | 					if (entry) { | 
					
						
							|  |  |  | 						hashes.push(entry.hash); | 
					
						
							|  |  |  | 						if (entry.timestampHash) tsHashes.push(entry.timestampHash); | 
					
						
							|  |  |  | 						if (entry.safeTime) { | 
					
						
							|  |  |  | 							safeTime = Math.max(safeTime, entry.safeTime); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						if (entry.symlinks !== undefined) { | 
					
						
							|  |  |  | 							for (const target of entry.symlinks) push(target); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					callback(); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			err => { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				if (err) return callback(/** @type {WebpackError} */ (err)); | 
					
						
							| 
									
										
										
										
											2021-09-22 18:12:46 +08:00
										 |  |  | 				const hash = createHash(this._hashFunction); | 
					
						
							|  |  |  | 				const tsHash = createHash(this._hashFunction); | 
					
						
							| 
									
										
										
										
											2021-08-17 14:19:01 +08:00
										 |  |  | 				hash.update(entry.hash); | 
					
						
							|  |  |  | 				if (entry.timestampHash) tsHash.update(entry.timestampHash); | 
					
						
							|  |  |  | 				if (entry.safeTime) { | 
					
						
							|  |  |  | 					safeTime = Math.max(safeTime, entry.safeTime); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				hashes.sort(); | 
					
						
							|  |  |  | 				for (const h of hashes) { | 
					
						
							|  |  |  | 					hash.update(h); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				tsHashes.sort(); | 
					
						
							|  |  |  | 				for (const h of tsHashes) { | 
					
						
							|  |  |  | 					tsHash.update(h); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				callback( | 
					
						
							|  |  |  | 					null, | 
					
						
							|  |  |  | 					(entry.resolved = { | 
					
						
							|  |  |  | 						safeTime, | 
					
						
							|  |  |  | 						timestampHash: /** @type {string} */ (tsHash.digest("hex")), | 
					
						
							|  |  |  | 						hash: /** @type {string} */ (hash.digest("hex")) | 
					
						
							|  |  |  | 					}) | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @type {Processor<string, Set<string>>} | 
					
						
							|  |  |  | 	 * @private | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 	_getManagedItemDirectoryInfo(path, callback) { | 
					
						
							|  |  |  | 		this.fs.readdir(path, (err, elements) => { | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 			if (err) { | 
					
						
							| 
									
										
										
										
											2019-09-09 03:30:27 +08:00
										 |  |  | 				if (err.code === "ENOENT" || err.code === "ENOTDIR") { | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 					return callback(null, EMPTY_SET); | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 				return callback(/** @type {WebpackError} */ (err)); | 
					
						
							| 
									
										
										
										
											2019-09-04 19:34:34 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 			const set = new Set( | 
					
						
							| 
									
										
										
										
											2021-01-13 07:09:19 +08:00
										 |  |  | 				/** @type {string[]} */ (elements).map(element => | 
					
						
							|  |  |  | 					join(this.fs, path, element) | 
					
						
							|  |  |  | 				) | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 			); | 
					
						
							|  |  |  | 			callback(null, set); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @type {Processor<string, string>} | 
					
						
							|  |  |  | 	 * @private | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 	_getManagedItemInfo(path, callback) { | 
					
						
							|  |  |  | 		const dir = dirname(this.fs, path); | 
					
						
							|  |  |  | 		this.managedItemDirectoryQueue.add(dir, (err, elements) => { | 
					
						
							|  |  |  | 			if (err) { | 
					
						
							|  |  |  | 				return callback(err); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 			if (!(/** @type {Set<string>} */ (elements).has(path))) { | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 				// file or directory doesn't exist
 | 
					
						
							| 
									
										
										
										
											2021-12-06 23:09:22 +08:00
										 |  |  | 				this._managedItems.set(path, "*missing"); | 
					
						
							|  |  |  | 				return callback(null, "*missing"); | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			// something exists
 | 
					
						
							|  |  |  | 			// it may be a file or directory
 | 
					
						
							|  |  |  | 			if ( | 
					
						
							|  |  |  | 				path.endsWith("node_modules") && | 
					
						
							|  |  |  | 				(path.endsWith("/node_modules") || path.endsWith("\\node_modules")) | 
					
						
							|  |  |  | 			) { | 
					
						
							| 
									
										
										
										
											2020-03-10 09:59:46 +08:00
										 |  |  | 				// we are only interested in existence of this special directory
 | 
					
						
							| 
									
										
										
										
											2021-12-06 23:09:22 +08:00
										 |  |  | 				this._managedItems.set(path, "*node_modules"); | 
					
						
							|  |  |  | 				return callback(null, "*node_modules"); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// we assume it's a directory, as files shouldn't occur in managed paths
 | 
					
						
							|  |  |  | 			const packageJsonPath = join(this.fs, path, "package.json"); | 
					
						
							|  |  |  | 			this.fs.readFile(packageJsonPath, (err, content) => { | 
					
						
							|  |  |  | 				if (err) { | 
					
						
							|  |  |  | 					if (err.code === "ENOENT" || err.code === "ENOTDIR") { | 
					
						
							|  |  |  | 						// no package.json or path is not a directory
 | 
					
						
							| 
									
										
										
										
											2020-09-17 21:08:38 +08:00
										 |  |  | 						this.fs.readdir(path, (err, elements) => { | 
					
						
							|  |  |  | 							if ( | 
					
						
							|  |  |  | 								!err && | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 								/** @type {string[]} */ (elements).length === 1 && | 
					
						
							|  |  |  | 								/** @type {string[]} */ (elements)[0] === "node_modules" | 
					
						
							| 
									
										
										
										
											2020-09-17 21:08:38 +08:00
										 |  |  | 							) { | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 								// This is only a grouping folder e.g. used by yarn
 | 
					
						
							| 
									
										
										
										
											2020-09-17 21:08:38 +08:00
										 |  |  | 								// we are only interested in existence of this special directory
 | 
					
						
							| 
									
										
										
										
											2021-12-06 23:09:22 +08:00
										 |  |  | 								this._managedItems.set(path, "*nested"); | 
					
						
							|  |  |  | 								return callback(null, "*nested"); | 
					
						
							| 
									
										
										
										
											2020-09-17 21:08:38 +08:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 							/** @type {Logger} */ | 
					
						
							|  |  |  | 							(this.logger).warn( | 
					
						
							| 
									
										
										
										
											2021-11-15 21:18:58 +08:00
										 |  |  | 								`Managed item ${path} isn't a directory or doesn't contain a package.json (see snapshot.managedPaths option)` | 
					
						
							|  |  |  | 							); | 
					
						
							|  |  |  | 							return callback(); | 
					
						
							| 
									
										
										
										
											2020-09-17 21:08:38 +08:00
										 |  |  | 						}); | 
					
						
							|  |  |  | 						return; | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 					return callback(/** @type {WebpackError} */ (err)); | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				let data; | 
					
						
							|  |  |  | 				try { | 
					
						
							| 
									
										
										
										
											2023-06-22 08:59:10 +08:00
										 |  |  | 					data = JSON.parse(/** @type {Buffer} */ (content).toString("utf-8")); | 
					
						
							| 
									
										
										
										
											2024-07-31 15:37:05 +08:00
										 |  |  | 				} catch (parseErr) { | 
					
						
							| 
									
										
										
										
											2024-08-06 11:08:48 +08:00
										 |  |  | 					return callback(/** @type {WebpackError} */ (parseErr)); | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2021-11-15 21:18:58 +08:00
										 |  |  | 				if (!data.name) { | 
					
						
							| 
									
										
										
										
											2024-03-26 00:05:56 +08:00
										 |  |  | 					/** @type {Logger} */ | 
					
						
							|  |  |  | 					(this.logger).warn( | 
					
						
							| 
									
										
										
										
											2021-11-15 21:18:58 +08:00
										 |  |  | 						`${packageJsonPath} doesn't contain a "name" property (see snapshot.managedPaths option)` | 
					
						
							|  |  |  | 					); | 
					
						
							|  |  |  | 					return callback(); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-11-05 23:47:45 +08:00
										 |  |  | 				const info = `${data.name || ""}@${data.version || ""}`; | 
					
						
							|  |  |  | 				this._managedItems.set(path, info); | 
					
						
							|  |  |  | 				callback(null, info); | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2019-08-13 04:59:09 +08:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 	getDeprecatedFileTimestamps() { | 
					
						
							| 
									
										
										
										
											2020-09-15 20:39:09 +08:00
										 |  |  | 		if (this._cachedDeprecatedFileTimestamps !== undefined) | 
					
						
							|  |  |  | 			return this._cachedDeprecatedFileTimestamps; | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 		const map = new Map(); | 
					
						
							|  |  |  | 		for (const [path, info] of this._fileTimestamps) { | 
					
						
							| 
									
										
										
										
											2019-11-06 06:46:34 +08:00
										 |  |  | 			if (info) map.set(path, typeof info === "object" ? info.safeTime : null); | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-09-15 20:39:09 +08:00
										 |  |  | 		return (this._cachedDeprecatedFileTimestamps = map); | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	getDeprecatedContextTimestamps() { | 
					
						
							| 
									
										
										
										
											2020-09-15 20:39:09 +08:00
										 |  |  | 		if (this._cachedDeprecatedContextTimestamps !== undefined) | 
					
						
							|  |  |  | 			return this._cachedDeprecatedContextTimestamps; | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 		const map = new Map(); | 
					
						
							|  |  |  | 		for (const [path, info] of this._contextTimestamps) { | 
					
						
							| 
									
										
										
										
											2019-11-06 06:46:34 +08:00
										 |  |  | 			if (info) map.set(path, typeof info === "object" ? info.safeTime : null); | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-09-15 20:39:09 +08:00
										 |  |  | 		return (this._cachedDeprecatedContextTimestamps = map); | 
					
						
							| 
									
										
										
										
											2018-09-27 13:22:19 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = FileSystemInfo; | 
					
						
							| 
									
										
										
										
											2020-08-22 18:01:28 +08:00
										 |  |  | module.exports.Snapshot = Snapshot; |