webpack 5.93.0 → 5.95.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (344) hide show
  1. package/README.md +8 -5
  2. package/bin/webpack.js +6 -7
  3. package/hot/log.js +1 -2
  4. package/hot/only-dev-server.js +1 -1
  5. package/hot/poll.js +1 -1
  6. package/hot/signal.js +1 -1
  7. package/lib/APIPlugin.js +4 -3
  8. package/lib/AbstractMethodError.js +10 -5
  9. package/lib/AutomaticPrefetchPlugin.js +1 -1
  10. package/lib/BannerPlugin.js +12 -6
  11. package/lib/Cache.js +8 -10
  12. package/lib/CacheFacade.js +3 -3
  13. package/lib/CaseSensitiveModulesWarning.js +5 -7
  14. package/lib/Chunk.js +14 -11
  15. package/lib/ChunkGraph.js +58 -36
  16. package/lib/ChunkGroup.js +2 -3
  17. package/lib/ChunkTemplate.js +43 -0
  18. package/lib/CleanPlugin.js +10 -11
  19. package/lib/CodeGenerationResults.js +6 -5
  20. package/lib/CommentCompilationWarning.js +0 -1
  21. package/lib/Compilation.js +223 -191
  22. package/lib/Compiler.js +81 -82
  23. package/lib/ConcatenationScope.js +3 -6
  24. package/lib/ConditionalInitFragment.js +6 -7
  25. package/lib/ConstPlugin.js +7 -15
  26. package/lib/ContextExclusionPlugin.js +3 -3
  27. package/lib/ContextModule.js +33 -20
  28. package/lib/ContextModuleFactory.js +89 -44
  29. package/lib/ContextReplacementPlugin.js +10 -9
  30. package/lib/DefinePlugin.js +75 -68
  31. package/lib/DelegatedModule.js +7 -3
  32. package/lib/DelegatedModuleFactoryPlugin.js +36 -22
  33. package/lib/DelegatedPlugin.js +4 -0
  34. package/lib/DependenciesBlock.js +0 -1
  35. package/lib/Dependency.js +10 -14
  36. package/lib/DllEntryPlugin.js +4 -2
  37. package/lib/DllModuleFactory.js +1 -0
  38. package/lib/DllPlugin.js +9 -7
  39. package/lib/DllReferencePlugin.js +30 -15
  40. package/lib/EntryPlugin.js +1 -3
  41. package/lib/EnvironmentPlugin.js +6 -2
  42. package/lib/ErrorHelpers.js +11 -12
  43. package/lib/EvalDevToolModulePlugin.js +10 -12
  44. package/lib/EvalSourceMapDevToolPlugin.js +15 -13
  45. package/lib/ExportsInfo.js +185 -120
  46. package/lib/ExternalModule.js +41 -15
  47. package/lib/ExternalModuleFactoryPlugin.js +23 -10
  48. package/lib/FileSystemInfo.js +791 -422
  49. package/lib/FlagAllModulesAsUsedPlugin.js +1 -1
  50. package/lib/FlagDependencyExportsPlugin.js +12 -11
  51. package/lib/FlagDependencyUsagePlugin.js +1 -1
  52. package/lib/Generator.js +2 -5
  53. package/lib/GraphHelpers.js +3 -2
  54. package/lib/HookWebpackError.js +8 -10
  55. package/lib/HotModuleReplacementPlugin.js +78 -64
  56. package/lib/IgnoreErrorModuleFactory.js +3 -3
  57. package/lib/IgnorePlugin.js +1 -3
  58. package/lib/IgnoreWarningsPlugin.js +6 -9
  59. package/lib/InitFragment.js +2 -3
  60. package/lib/LibManifestPlugin.js +4 -3
  61. package/lib/MainTemplate.js +72 -19
  62. package/lib/Module.js +25 -9
  63. package/lib/ModuleBuildError.js +4 -11
  64. package/lib/ModuleDependencyError.js +5 -5
  65. package/lib/ModuleDependencyWarning.js +5 -5
  66. package/lib/ModuleError.js +1 -5
  67. package/lib/ModuleFilenameHelpers.js +29 -46
  68. package/lib/ModuleGraph.js +7 -6
  69. package/lib/ModuleGraphConnection.js +6 -6
  70. package/lib/ModuleInfoHeaderPlugin.js +82 -30
  71. package/lib/ModuleParseError.js +8 -9
  72. package/lib/ModuleRestoreError.js +1 -1
  73. package/lib/ModuleStoreError.js +1 -1
  74. package/lib/ModuleTemplate.js +33 -1
  75. package/lib/ModuleTypeConstants.js +21 -22
  76. package/lib/ModuleWarning.js +1 -5
  77. package/lib/MultiCompiler.js +24 -26
  78. package/lib/MultiStats.js +73 -31
  79. package/lib/MultiWatching.js +1 -1
  80. package/lib/NormalModule.js +130 -69
  81. package/lib/NormalModuleFactory.js +53 -49
  82. package/lib/OptimizationStages.js +3 -3
  83. package/lib/ProgressPlugin.js +9 -9
  84. package/lib/ProvidePlugin.js +4 -4
  85. package/lib/RuntimeGlobals.js +71 -70
  86. package/lib/RuntimeModule.js +1 -1
  87. package/lib/RuntimePlugin.js +24 -12
  88. package/lib/RuntimeTemplate.js +40 -44
  89. package/lib/SizeFormatHelpers.js +2 -4
  90. package/lib/SourceMapDevToolPlugin.js +42 -34
  91. package/lib/Stats.js +5 -11
  92. package/lib/Template.js +18 -24
  93. package/lib/TemplatedPathPlugin.js +21 -13
  94. package/lib/WarnDeprecatedOptionPlugin.js +0 -1
  95. package/lib/WatchIgnorePlugin.js +26 -9
  96. package/lib/Watching.js +10 -5
  97. package/lib/WebpackOptionsApply.js +84 -62
  98. package/lib/asset/AssetGenerator.js +107 -42
  99. package/lib/asset/AssetModulesPlugin.js +29 -23
  100. package/lib/asset/AssetSourceGenerator.js +2 -7
  101. package/lib/async-modules/AwaitDependenciesInitFragment.js +6 -7
  102. package/lib/buildChunkGraph.js +93 -81
  103. package/lib/cache/IdleFileCachePlugin.js +4 -4
  104. package/lib/cache/MemoryWithGcCachePlugin.js +5 -5
  105. package/lib/cache/PackFileCacheStrategy.js +51 -50
  106. package/lib/cache/ResolverCachePlugin.js +6 -6
  107. package/lib/cache/mergeEtags.js +16 -21
  108. package/lib/cli.js +148 -104
  109. package/lib/config/browserslistTargetHandler.js +16 -13
  110. package/lib/config/defaults.js +32 -28
  111. package/lib/config/normalization.js +335 -344
  112. package/lib/config/target.js +42 -52
  113. package/lib/container/ContainerEntryModule.js +2 -2
  114. package/lib/container/ContainerPlugin.js +1 -1
  115. package/lib/container/RemoteRuntimeModule.js +11 -8
  116. package/lib/container/options.js +18 -4
  117. package/lib/css/CssExportsGenerator.js +26 -24
  118. package/lib/css/CssGenerator.js +9 -4
  119. package/lib/css/CssLoadingRuntimeModule.js +10 -10
  120. package/lib/css/CssModulesPlugin.js +127 -47
  121. package/lib/css/CssParser.js +20 -18
  122. package/lib/css/walkCssTokens.js +80 -95
  123. package/lib/debug/ProfilingPlugin.js +19 -20
  124. package/lib/dependencies/AMDDefineDependency.js +1 -1
  125. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +83 -47
  126. package/lib/dependencies/AMDRequireArrayDependency.js +9 -10
  127. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +22 -16
  128. package/lib/dependencies/AMDRuntimeModules.js +2 -2
  129. package/lib/dependencies/CommonJsDependencyHelpers.js +6 -2
  130. package/lib/dependencies/CommonJsExportRequireDependency.js +37 -41
  131. package/lib/dependencies/CommonJsExportsDependency.js +0 -1
  132. package/lib/dependencies/CommonJsExportsParserPlugin.js +19 -23
  133. package/lib/dependencies/CommonJsFullRequireDependency.js +1 -1
  134. package/lib/dependencies/CommonJsImportsParserPlugin.js +52 -61
  135. package/lib/dependencies/CommonJsSelfReferenceDependency.js +6 -8
  136. package/lib/dependencies/ConstDependency.js +1 -1
  137. package/lib/dependencies/ContextDependency.js +7 -2
  138. package/lib/dependencies/ContextDependencyHelpers.js +31 -34
  139. package/lib/dependencies/ContextElementDependency.js +35 -8
  140. package/lib/dependencies/CriticalDependencyWarning.js +1 -1
  141. package/lib/dependencies/CssExportDependency.js +7 -7
  142. package/lib/dependencies/CssImportDependency.js +0 -2
  143. package/lib/dependencies/CssLocalIdentifierDependency.js +3 -3
  144. package/lib/dependencies/CssSelfLocalIdentifierDependency.js +2 -1
  145. package/lib/dependencies/CssUrlDependency.js +4 -5
  146. package/lib/dependencies/DynamicExports.js +5 -5
  147. package/lib/dependencies/ExportsInfoDependency.js +1 -2
  148. package/lib/dependencies/HarmonyAcceptImportDependency.js +1 -1
  149. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +4 -5
  150. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +27 -16
  151. package/lib/dependencies/HarmonyExportExpressionDependency.js +1 -1
  152. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +107 -64
  153. package/lib/dependencies/HarmonyExports.js +2 -2
  154. package/lib/dependencies/HarmonyImportDependency.js +2 -4
  155. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +19 -4
  156. package/lib/dependencies/HarmonyImportSpecifierDependency.js +40 -15
  157. package/lib/dependencies/ImportDependency.js +1 -1
  158. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +5 -5
  159. package/lib/dependencies/ImportMetaPlugin.js +11 -13
  160. package/lib/dependencies/ImportParserPlugin.js +39 -44
  161. package/lib/dependencies/JsonExportsDependency.js +22 -18
  162. package/lib/dependencies/LoaderPlugin.js +47 -36
  163. package/lib/dependencies/LocalModule.js +1 -1
  164. package/lib/dependencies/LocalModulesHelpers.js +4 -4
  165. package/lib/dependencies/ModuleDecoratorDependency.js +1 -1
  166. package/lib/dependencies/ProvidedDependency.js +1 -1
  167. package/lib/dependencies/PureExpressionDependency.js +6 -6
  168. package/lib/dependencies/RequireContextDependencyParserPlugin.js +1 -1
  169. package/lib/dependencies/RuntimeRequirementsDependency.js +1 -1
  170. package/lib/dependencies/SystemPlugin.js +1 -1
  171. package/lib/dependencies/URLDependency.js +3 -3
  172. package/lib/dependencies/URLPlugin.js +66 -12
  173. package/lib/dependencies/WorkerPlugin.js +25 -24
  174. package/lib/dependencies/processExportInfo.js +3 -1
  175. package/lib/electron/ElectronTargetPlugin.js +1 -0
  176. package/lib/esm/ModuleChunkFormatPlugin.js +3 -3
  177. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +7 -3
  178. package/lib/formatLocation.js +1 -2
  179. package/lib/hmr/HotModuleReplacement.runtime.js +4 -5
  180. package/lib/hmr/HotModuleReplacementRuntimeModule.js +1 -0
  181. package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +9 -12
  182. package/lib/hmr/LazyCompilationPlugin.js +27 -12
  183. package/lib/hmr/lazyCompilationBackend.js +64 -40
  184. package/lib/ids/ChunkModuleIdRangePlugin.js +1 -3
  185. package/lib/ids/DeterministicChunkIdsPlugin.js +2 -4
  186. package/lib/ids/DeterministicModuleIdsPlugin.js +1 -1
  187. package/lib/ids/HashedModuleIdsPlugin.js +5 -1
  188. package/lib/ids/IdHelpers.js +29 -39
  189. package/lib/ids/SyncModuleIdsPlugin.js +7 -2
  190. package/lib/index.js +1 -5
  191. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +5 -4
  192. package/lib/javascript/BasicEvaluatedExpression.js +4 -19
  193. package/lib/javascript/ChunkHelpers.js +1 -1
  194. package/lib/javascript/CommonJsChunkFormatPlugin.js +3 -2
  195. package/lib/javascript/EnableChunkLoadingPlugin.js +7 -6
  196. package/lib/javascript/JavascriptGenerator.js +23 -7
  197. package/lib/javascript/JavascriptModulesPlugin.js +133 -86
  198. package/lib/javascript/JavascriptParser.js +179 -200
  199. package/lib/javascript/JavascriptParserHelpers.js +20 -21
  200. package/lib/javascript/StartupHelpers.js +41 -13
  201. package/lib/json/JsonGenerator.js +7 -13
  202. package/lib/json/JsonModulesPlugin.js +1 -4
  203. package/lib/json/JsonParser.js +5 -3
  204. package/lib/library/AmdLibraryPlugin.js +12 -16
  205. package/lib/library/AssignLibraryPlugin.js +8 -10
  206. package/lib/library/EnableLibraryPlugin.js +15 -14
  207. package/lib/library/JsonpLibraryPlugin.js +2 -1
  208. package/lib/library/ModernModuleLibraryPlugin.js +8 -6
  209. package/lib/library/ModuleLibraryPlugin.js +2 -1
  210. package/lib/library/SystemLibraryPlugin.js +2 -1
  211. package/lib/library/UmdLibraryPlugin.js +66 -92
  212. package/lib/logging/Logger.js +32 -4
  213. package/lib/logging/createConsoleLogger.js +12 -13
  214. package/lib/logging/runtime.js +7 -8
  215. package/lib/logging/truncateArgs.js +5 -8
  216. package/lib/node/NodeWatchFileSystem.js +3 -18
  217. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +2 -2
  218. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +1 -0
  219. package/lib/node/RequireChunkLoadingRuntimeModule.js +2 -2
  220. package/lib/node/nodeConsole.js +22 -22
  221. package/lib/optimize/AggressiveMergingPlugin.js +2 -4
  222. package/lib/optimize/AggressiveSplittingPlugin.js +16 -19
  223. package/lib/optimize/ConcatenatedModule.js +81 -51
  224. package/lib/optimize/EnsureChunkConditionsPlugin.js +1 -1
  225. package/lib/optimize/FlagIncludedChunksPlugin.js +3 -3
  226. package/lib/optimize/InnerGraph.js +17 -17
  227. package/lib/optimize/InnerGraphPlugin.js +8 -7
  228. package/lib/optimize/LimitChunkCountPlugin.js +2 -3
  229. package/lib/optimize/MangleExportsPlugin.js +1 -0
  230. package/lib/optimize/MergeDuplicateChunksPlugin.js +2 -2
  231. package/lib/optimize/MinMaxSizeWarning.js +1 -1
  232. package/lib/optimize/ModuleConcatenationPlugin.js +54 -78
  233. package/lib/optimize/RealContentHashPlugin.js +7 -10
  234. package/lib/optimize/RemoveParentModulesPlugin.js +3 -3
  235. package/lib/optimize/SideEffectsFlagPlugin.js +6 -2
  236. package/lib/optimize/SplitChunksPlugin.js +34 -30
  237. package/lib/performance/SizeLimitsPlugin.js +2 -2
  238. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +1 -1
  239. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +1 -1
  240. package/lib/rules/BasicEffectRulePlugin.js +3 -1
  241. package/lib/rules/BasicMatcherRulePlugin.js +3 -1
  242. package/lib/rules/ObjectMatcherRulePlugin.js +4 -1
  243. package/lib/rules/RuleSetCompiler.js +41 -22
  244. package/lib/rules/UseEffectRulePlugin.js +36 -32
  245. package/lib/runtime/AsyncModuleRuntimeModule.js +1 -1
  246. package/lib/runtime/AutoPublicPathRuntimeModule.js +8 -3
  247. package/lib/runtime/CreateFakeNamespaceObjectRuntimeModule.js +2 -2
  248. package/lib/runtime/DefinePropertyGettersRuntimeModule.js +1 -1
  249. package/lib/runtime/EnsureChunkRuntimeModule.js +10 -11
  250. package/lib/runtime/GetChunkFilenameRuntimeModule.js +11 -17
  251. package/lib/runtime/LoadScriptRuntimeModule.js +17 -18
  252. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +1 -3
  253. package/lib/schemes/DataUriPlugin.js +1 -1
  254. package/lib/schemes/HttpUriPlugin.js +241 -126
  255. package/lib/serialization/BinaryMiddleware.js +44 -28
  256. package/lib/serialization/DateObjectSerializer.js +1 -0
  257. package/lib/serialization/ErrorObjectSerializer.js +2 -0
  258. package/lib/serialization/FileMiddleware.js +154 -106
  259. package/lib/serialization/MapObjectSerializer.js +2 -1
  260. package/lib/serialization/NullPrototypeObjectSerializer.js +3 -2
  261. package/lib/serialization/ObjectMiddleware.js +52 -56
  262. package/lib/serialization/PlainObjectSerializer.js +32 -6
  263. package/lib/serialization/RegExpObjectSerializer.js +1 -0
  264. package/lib/serialization/Serializer.js +4 -5
  265. package/lib/serialization/SerializerMiddleware.js +6 -6
  266. package/lib/serialization/SetObjectSerializer.js +2 -1
  267. package/lib/sharing/ConsumeSharedPlugin.js +116 -97
  268. package/lib/sharing/ConsumeSharedRuntimeModule.js +4 -4
  269. package/lib/sharing/ProvideForSharedDependency.js +0 -1
  270. package/lib/sharing/ProvideSharedPlugin.js +2 -2
  271. package/lib/sharing/resolveMatchedConfigs.js +2 -1
  272. package/lib/sharing/utils.js +15 -27
  273. package/lib/stats/DefaultStatsFactoryPlugin.js +424 -281
  274. package/lib/stats/DefaultStatsPresetPlugin.js +73 -18
  275. package/lib/stats/DefaultStatsPrinterPlugin.js +370 -101
  276. package/lib/stats/StatsFactory.js +127 -56
  277. package/lib/stats/StatsPrinter.js +75 -44
  278. package/lib/util/ArrayHelpers.js +8 -4
  279. package/lib/util/ArrayQueue.js +1 -1
  280. package/lib/util/AsyncQueue.js +31 -12
  281. package/lib/util/IterableHelpers.js +3 -4
  282. package/lib/util/LazyBucketSortedSet.js +60 -44
  283. package/lib/util/LazySet.js +13 -0
  284. package/lib/util/MapHelpers.js +1 -3
  285. package/lib/util/ParallelismFactorCalculator.js +1 -1
  286. package/lib/util/Queue.js +1 -1
  287. package/lib/util/Semaphore.js +4 -7
  288. package/lib/util/SetHelpers.js +5 -5
  289. package/lib/util/SortableSet.js +4 -3
  290. package/lib/util/StackedCacheMap.js +4 -6
  291. package/lib/util/StackedMap.js +1 -3
  292. package/lib/util/StringXor.js +0 -5
  293. package/lib/util/TupleQueue.js +1 -1
  294. package/lib/util/TupleSet.js +15 -5
  295. package/lib/util/URLAbsoluteSpecifier.js +7 -7
  296. package/lib/util/WeakTupleMap.js +19 -21
  297. package/lib/util/binarySearchBounds.js +5 -12
  298. package/lib/util/chainedImports.js +1 -1
  299. package/lib/util/cleverMerge.js +21 -19
  300. package/lib/util/comparators.js +57 -52
  301. package/lib/util/compileBooleanMatcher.js +3 -6
  302. package/lib/util/conventions.js +8 -11
  303. package/lib/util/createHash.js +9 -6
  304. package/lib/util/deprecation.js +22 -12
  305. package/lib/util/deterministicGrouping.js +19 -26
  306. package/lib/util/findGraphRoots.js +2 -2
  307. package/lib/util/fs.js +32 -32
  308. package/lib/util/hash/md4.js +2 -2
  309. package/lib/util/hash/wasm-hash.js +7 -7
  310. package/lib/util/hash/xxhash64.js +2 -2
  311. package/lib/util/identifier.js +81 -59
  312. package/lib/util/memoize.js +8 -10
  313. package/lib/util/mergeScope.js +6 -9
  314. package/lib/util/nonNumericOnlyHash.js +2 -2
  315. package/lib/util/numberHash.js +1 -6
  316. package/lib/util/objectToMap.js +0 -1
  317. package/lib/util/propertyAccess.js +2 -5
  318. package/lib/util/propertyName.js +1 -3
  319. package/lib/util/registerExternalSerializer.js +1 -1
  320. package/lib/util/runtime.js +109 -113
  321. package/lib/util/semver.js +29 -27
  322. package/lib/util/serialization.js +16 -1
  323. package/lib/util/smartGrouping.js +5 -5
  324. package/lib/util/source.js +1 -1
  325. package/lib/wasm/EnableWasmLoadingPlugin.js +5 -4
  326. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +3 -3
  327. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +5 -6
  328. package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +3 -3
  329. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +20 -19
  330. package/lib/wasm-sync/WebAssemblyGenerator.js +14 -29
  331. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +1 -1
  332. package/lib/wasm-sync/WebAssemblyUtils.js +2 -2
  333. package/lib/web/JsonpChunkLoadingRuntimeModule.js +2 -3
  334. package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +3 -1
  335. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +1 -1
  336. package/package.json +18 -17
  337. package/schemas/WebpackOptions.check.js +1 -1
  338. package/schemas/WebpackOptions.json +5 -0
  339. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  340. package/schemas/plugins/container/ContainerReferencePlugin.json +1 -0
  341. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  342. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  343. package/schemas/plugins/container/ModuleFederationPlugin.json +1 -0
  344. package/types.d.ts +681 -355
@@ -16,6 +16,9 @@ const { join, dirname, relative, lstatReadlinkAbsolute } = require("./util/fs");
16
16
  const makeSerializable = require("./util/makeSerializable");
17
17
  const processAsyncTree = require("./util/processAsyncTree");
18
18
 
19
+ /** @typedef {import("enhanced-resolve").Resolver} Resolver */
20
+ /** @typedef {import("enhanced-resolve").ResolveRequest} ResolveRequest */
21
+ /** @typedef {import("enhanced-resolve").ResolveFunctionAsync} ResolveFunctionAsync */
19
22
  /** @typedef {import("./WebpackError")} WebpackError */
20
23
  /** @typedef {import("./logging/Logger").Logger} Logger */
21
24
  /** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
@@ -23,9 +26,20 @@ const processAsyncTree = require("./util/processAsyncTree");
23
26
  /** @typedef {typeof import("./util/Hash")} Hash */
24
27
  /** @typedef {import("./util/fs").IStats} IStats */
25
28
  /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
29
+ /** @typedef {import("./util/fs").PathLike} PathLike */
30
+ /** @typedef {import("./util/fs").StringCallback} StringCallback */
31
+ /**
32
+ * @template T
33
+ * @typedef {import("./util/AsyncQueue").Callback<T>} ProcessorCallback
34
+ */
35
+ /**
36
+ * @template T, R
37
+ * @typedef {import("./util/AsyncQueue").Processor<T, R>} Processor
38
+ */
26
39
 
27
- const supportsEsm = +process.versions.modules >= 83;
40
+ const supportsEsm = Number(process.versions.modules) >= 83;
28
41
 
42
+ /** @type {Set<string>} */
29
43
  const builtinModules = new Set(nodeModule.builtinModules);
30
44
 
31
45
  let FS_ACCURACY = 2000;
@@ -43,6 +57,8 @@ const RBDT_FILE = 7;
43
57
  const RBDT_DIRECTORY_DEPENDENCIES = 8;
44
58
  const RBDT_FILE_DEPENDENCIES = 9;
45
59
 
60
+ /** @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 */
61
+
46
62
  const INVALID = Symbol("invalid");
47
63
 
48
64
  /**
@@ -79,27 +95,31 @@ const INVALID = Symbol("invalid");
79
95
  * @property {string} hash
80
96
  */
81
97
 
98
+ /** @typedef {Set<string>} Symlinks */
99
+
82
100
  /**
83
101
  * @typedef {object} ContextTimestampAndHash
84
102
  * @property {number} safeTime
85
103
  * @property {string=} timestampHash
86
104
  * @property {string} hash
87
105
  * @property {ResolvedContextTimestampAndHash=} resolved
88
- * @property {Set<string>=} symlinks
106
+ * @property {Symlinks=} symlinks
89
107
  */
90
108
 
91
109
  /**
92
110
  * @typedef {object} ContextHash
93
111
  * @property {string} hash
94
112
  * @property {string=} resolved
95
- * @property {Set<string>=} symlinks
113
+ * @property {Symlinks=} symlinks
96
114
  */
97
115
 
116
+ /** @typedef {Set<string>} SnapshotContent */
117
+
98
118
  /**
99
119
  * @typedef {object} SnapshotOptimizationEntry
100
120
  * @property {Snapshot} snapshot
101
121
  * @property {number} shared
102
- * @property {Set<string> | undefined} snapshotContent
122
+ * @property {SnapshotContent | undefined} snapshotContent
103
123
  * @property {Set<SnapshotOptimizationEntry> | undefined} children
104
124
  */
105
125
 
@@ -108,7 +128,7 @@ const INVALID = Symbol("invalid");
108
128
  * @property {Set<string>} files list of files
109
129
  * @property {Set<string>} directories list of directories
110
130
  * @property {Set<string>} missing list of missing entries
111
- * @property {Map<string, string | false>} resolveResults stored resolve results
131
+ * @property {Map<string, string | false | undefined>} resolveResults stored resolve results
112
132
  * @property {object} resolveDependencies dependencies of the resolving
113
133
  * @property {Set<string>} resolveDependencies.files list of files
114
134
  * @property {Set<string>} resolveDependencies.directories list of directories
@@ -128,12 +148,17 @@ const DONE_ITERATOR_RESULT = new Set().keys().next();
128
148
  // Tshs = Timestamp + Hash combinations
129
149
 
130
150
  class SnapshotIterator {
151
+ /**
152
+ * @param {() => IteratorResult<string>} next next
153
+ */
131
154
  constructor(next) {
132
155
  this.next = next;
133
156
  }
134
157
  }
135
158
 
136
- /** @typedef {(snapshot: Snapshot) => (Map<string, any> | Set<string>)[]} GetMapsFunction */
159
+ /**
160
+ * @typedef {(snapshot: Snapshot) => (Map<string, any> | Set<string> | undefined)[]} GetMapsFunction
161
+ */
137
162
 
138
163
  class SnapshotIterable {
139
164
  /**
@@ -149,12 +174,13 @@ class SnapshotIterable {
149
174
  let state = 0;
150
175
  /** @type {IterableIterator<string>} */
151
176
  let it;
152
- /** @type {(snapshot: Snapshot) => (Map<string, any> | Set<string>)[]} */
177
+ /** @type {(snapshot: Snapshot) => (Map<string, any> | Set<string> | undefined)[]} */
153
178
  let getMaps;
154
- /** @type {(Map<string, any> | Set<string>)[]} */
179
+ /** @type {(Map<string, any> | Set<string> | undefined)[]} */
155
180
  let maps;
156
181
  /** @type {Snapshot} */
157
182
  let snapshot;
183
+ /** @type {Snapshot[] | undefined} */
158
184
  let queue;
159
185
  return new SnapshotIterator(() => {
160
186
  for (;;) {
@@ -202,7 +228,7 @@ class SnapshotIterable {
202
228
  }
203
229
  }
204
230
  if (queue !== undefined && queue.length > 0) {
205
- snapshot = queue.pop();
231
+ snapshot = /** @type {Snapshot} */ (queue.pop());
206
232
  maps = getMaps(snapshot);
207
233
  state = 1;
208
234
  break;
@@ -225,6 +251,12 @@ class SnapshotIterable {
225
251
  /** @typedef {Map<string, ResolvedContextFileSystemInfoEntry | null>} ContextTimestamps */
226
252
  /** @typedef {Map<string, string | null>} ContextHashes */
227
253
  /** @typedef {Map<string, ResolvedContextTimestampAndHash | null>} ContextTshs */
254
+ /** @typedef {Map<string, boolean>} MissingExistence */
255
+ /** @typedef {Map<string, string>} ManagedItemInfo */
256
+ /** @typedef {Set<string>} ManagedFiles */
257
+ /** @typedef {Set<string>} ManagedContexts */
258
+ /** @typedef {Set<string>} ManagedMissing */
259
+ /** @typedef {Set<Snapshot>} Children */
228
260
 
229
261
  class Snapshot {
230
262
  constructor() {
@@ -249,17 +281,17 @@ class Snapshot {
249
281
  this.contextHashes = undefined;
250
282
  /** @type {ContextTshs | undefined} */
251
283
  this.contextTshs = undefined;
252
- /** @type {Map<string, boolean> | undefined} */
284
+ /** @type {MissingExistence | undefined} */
253
285
  this.missingExistence = undefined;
254
- /** @type {Map<string, string> | undefined} */
286
+ /** @type {ManagedItemInfo | undefined} */
255
287
  this.managedItemInfo = undefined;
256
- /** @type {Set<string> | undefined} */
288
+ /** @type {ManagedFiles | undefined} */
257
289
  this.managedFiles = undefined;
258
- /** @type {Set<string> | undefined} */
290
+ /** @type {ManagedContexts | undefined} */
259
291
  this.managedContexts = undefined;
260
- /** @type {Set<string> | undefined} */
292
+ /** @type {ManagedMissing | undefined} */
261
293
  this.managedMissing = undefined;
262
- /** @type {Set<Snapshot> | undefined} */
294
+ /** @type {Children | undefined} */
263
295
  this.children = undefined;
264
296
  }
265
297
 
@@ -275,15 +307,28 @@ class Snapshot {
275
307
  this.startTime = value;
276
308
  }
277
309
 
310
+ /**
311
+ * @param {number | undefined} value value
312
+ * @param {Snapshot} snapshot snapshot
313
+ */
278
314
  setMergedStartTime(value, snapshot) {
279
315
  if (value) {
280
316
  if (snapshot.hasStartTime()) {
281
- this.setStartTime(Math.min(value, snapshot.startTime));
317
+ this.setStartTime(
318
+ Math.min(
319
+ value,
320
+ /** @type {NonNullable<Snapshot["startTime"]>} */
321
+ (snapshot.startTime)
322
+ )
323
+ );
282
324
  } else {
283
325
  this.setStartTime(value);
284
326
  }
285
- } else {
286
- if (snapshot.hasStartTime()) this.setStartTime(snapshot.startTime);
327
+ } else if (snapshot.hasStartTime()) {
328
+ this.setStartTime(
329
+ /** @type {NonNullable<Snapshot["startTime"]>} */
330
+ (snapshot.startTime)
331
+ );
287
332
  }
288
333
  }
289
334
 
@@ -291,6 +336,9 @@ class Snapshot {
291
336
  return (this._flags & 2) !== 0;
292
337
  }
293
338
 
339
+ /**
340
+ * @param {FileTimestamps} value file timestamps
341
+ */
294
342
  setFileTimestamps(value) {
295
343
  this._flags = this._flags | 2;
296
344
  this.fileTimestamps = value;
@@ -300,6 +348,9 @@ class Snapshot {
300
348
  return (this._flags & 4) !== 0;
301
349
  }
302
350
 
351
+ /**
352
+ * @param {FileHashes} value file hashes
353
+ */
303
354
  setFileHashes(value) {
304
355
  this._flags = this._flags | 4;
305
356
  this.fileHashes = value;
@@ -309,6 +360,9 @@ class Snapshot {
309
360
  return (this._flags & 8) !== 0;
310
361
  }
311
362
 
363
+ /**
364
+ * @param {FileTshs} value file tshs
365
+ */
312
366
  setFileTshs(value) {
313
367
  this._flags = this._flags | 8;
314
368
  this.fileTshs = value;
@@ -318,6 +372,9 @@ class Snapshot {
318
372
  return (this._flags & 0x10) !== 0;
319
373
  }
320
374
 
375
+ /**
376
+ * @param {ContextTimestamps} value context timestamps
377
+ */
321
378
  setContextTimestamps(value) {
322
379
  this._flags = this._flags | 0x10;
323
380
  this.contextTimestamps = value;
@@ -327,6 +384,9 @@ class Snapshot {
327
384
  return (this._flags & 0x20) !== 0;
328
385
  }
329
386
 
387
+ /**
388
+ * @param {ContextHashes} value context hashes
389
+ */
330
390
  setContextHashes(value) {
331
391
  this._flags = this._flags | 0x20;
332
392
  this.contextHashes = value;
@@ -336,6 +396,9 @@ class Snapshot {
336
396
  return (this._flags & 0x40) !== 0;
337
397
  }
338
398
 
399
+ /**
400
+ * @param {ContextTshs} value context tshs
401
+ */
339
402
  setContextTshs(value) {
340
403
  this._flags = this._flags | 0x40;
341
404
  this.contextTshs = value;
@@ -345,6 +408,9 @@ class Snapshot {
345
408
  return (this._flags & 0x80) !== 0;
346
409
  }
347
410
 
411
+ /**
412
+ * @param {MissingExistence} value context tshs
413
+ */
348
414
  setMissingExistence(value) {
349
415
  this._flags = this._flags | 0x80;
350
416
  this.missingExistence = value;
@@ -354,6 +420,9 @@ class Snapshot {
354
420
  return (this._flags & 0x100) !== 0;
355
421
  }
356
422
 
423
+ /**
424
+ * @param {ManagedItemInfo} value managed item info
425
+ */
357
426
  setManagedItemInfo(value) {
358
427
  this._flags = this._flags | 0x100;
359
428
  this.managedItemInfo = value;
@@ -363,6 +432,9 @@ class Snapshot {
363
432
  return (this._flags & 0x200) !== 0;
364
433
  }
365
434
 
435
+ /**
436
+ * @param {ManagedFiles} value managed files
437
+ */
366
438
  setManagedFiles(value) {
367
439
  this._flags = this._flags | 0x200;
368
440
  this.managedFiles = value;
@@ -372,6 +444,9 @@ class Snapshot {
372
444
  return (this._flags & 0x400) !== 0;
373
445
  }
374
446
 
447
+ /**
448
+ * @param {ManagedContexts} value managed contexts
449
+ */
375
450
  setManagedContexts(value) {
376
451
  this._flags = this._flags | 0x400;
377
452
  this.managedContexts = value;
@@ -381,6 +456,9 @@ class Snapshot {
381
456
  return (this._flags & 0x800) !== 0;
382
457
  }
383
458
 
459
+ /**
460
+ * @param {ManagedMissing} value managed missing
461
+ */
384
462
  setManagedMissing(value) {
385
463
  this._flags = this._flags | 0x800;
386
464
  this.managedMissing = value;
@@ -390,16 +468,23 @@ class Snapshot {
390
468
  return (this._flags & 0x1000) !== 0;
391
469
  }
392
470
 
471
+ /**
472
+ * @param {Children} value children
473
+ */
393
474
  setChildren(value) {
394
475
  this._flags = this._flags | 0x1000;
395
476
  this.children = value;
396
477
  }
397
478
 
479
+ /**
480
+ * @param {Snapshot} child children
481
+ */
398
482
  addChild(child) {
399
483
  if (!this.hasChildren()) {
400
484
  this.setChildren(new Set());
401
485
  }
402
- this.children.add(child);
486
+ /** @type {Children} */
487
+ (this.children).add(child);
403
488
  }
404
489
 
405
490
  /**
@@ -498,22 +583,35 @@ makeSerializable(Snapshot, "webpack/lib/FileSystemInfo", "Snapshot");
498
583
 
499
584
  const MIN_COMMON_SNAPSHOT_SIZE = 3;
500
585
 
586
+ /**
587
+ * @template U, T
588
+ * @typedef {U extends true ? Set<string> : Map<string, T>} SnapshotOptimizationValue
589
+ */
590
+
501
591
  /**
502
592
  * @template T
593
+ * @template {boolean} [U=false]
503
594
  */
504
595
  class SnapshotOptimization {
505
596
  /**
506
597
  * @param {function(Snapshot): boolean} has has value
507
- * @param {function(Snapshot): Map<string, T> | Set<string>} get get value
508
- * @param {function(Snapshot, Map<string, T> | Set<string>): void} set set value
598
+ * @param {function(Snapshot): SnapshotOptimizationValue<U, T> | undefined} get get value
599
+ * @param {function(Snapshot, SnapshotOptimizationValue<U, T>): void} set set value
509
600
  * @param {boolean=} useStartTime use the start time of snapshots
510
- * @param {boolean=} isSet value is an Set instead of a Map
601
+ * @param {U=} isSet value is an Set instead of a Map
511
602
  */
512
- constructor(has, get, set, useStartTime = true, isSet = false) {
603
+ constructor(
604
+ has,
605
+ get,
606
+ set,
607
+ useStartTime = true,
608
+ isSet = /** @type {U} */ (false)
609
+ ) {
513
610
  this._has = has;
514
611
  this._get = get;
515
612
  this._set = set;
516
613
  this._useStartTime = useStartTime;
614
+ /** @type {U} */
517
615
  this._isSet = isSet;
518
616
  /** @type {Map<string, SnapshotOptimizationEntry>} */
519
617
  this._map = new Map();
@@ -525,7 +623,7 @@ class SnapshotOptimization {
525
623
 
526
624
  getStatisticMessage() {
527
625
  const total = this._statItemsShared + this._statItemsUnshared;
528
- if (total === 0) return undefined;
626
+ if (total === 0) return;
529
627
  return `${
530
628
  this._statItemsShared && Math.round((this._statItemsShared * 100) / total)
531
629
  }% (${this._statItemsShared}/${total}) entries shared via ${
@@ -555,7 +653,9 @@ class SnapshotOptimization {
555
653
  */
556
654
  const increaseSharedAndStoreOptimizationEntry = entry => {
557
655
  if (entry.children !== undefined) {
558
- entry.children.forEach(increaseSharedAndStoreOptimizationEntry);
656
+ for (const child of entry.children) {
657
+ increaseSharedAndStoreOptimizationEntry(child);
658
+ }
559
659
  }
560
660
  entry.shared++;
561
661
  storeOptimizationEntry(entry);
@@ -565,8 +665,12 @@ class SnapshotOptimization {
565
665
  * @returns {void}
566
666
  */
567
667
  const storeOptimizationEntry = entry => {
568
- for (const path of entry.snapshotContent) {
569
- const old = this._map.get(path);
668
+ for (const path of /** @type {SnapshotContent} */ (
669
+ entry.snapshotContent
670
+ )) {
671
+ const old =
672
+ /** @type {SnapshotOptimizationEntry} */
673
+ (this._map.get(path));
570
674
  if (old.shared < entry.shared) {
571
675
  this._map.set(path, entry);
572
676
  }
@@ -575,7 +679,7 @@ class SnapshotOptimization {
575
679
  };
576
680
 
577
681
  /** @type {SnapshotOptimizationEntry | undefined} */
578
- let newOptimizationEntry = undefined;
682
+ let newOptimizationEntry;
579
683
 
580
684
  const capturedFilesSize = capturedFiles.size;
581
685
 
@@ -600,7 +704,7 @@ class SnapshotOptimization {
600
704
  }
601
705
  }
602
706
 
603
- optimizationEntries: for (const optimizationEntry of optimizationEntries) {
707
+ optimizationEntriesLabel: for (const optimizationEntry of optimizationEntries) {
604
708
  const snapshot = optimizationEntry.snapshot;
605
709
  if (optimizationEntry.shared > 0) {
606
710
  // It's a shared snapshot
@@ -614,14 +718,18 @@ class SnapshotOptimization {
614
718
  continue;
615
719
  }
616
720
  const nonSharedFiles = new Set();
617
- const snapshotContent = optimizationEntry.snapshotContent;
618
- const snapshotEntries = this._get(snapshot);
721
+ const snapshotContent =
722
+ /** @type {NonNullable<SnapshotOptimizationEntry["snapshotContent"]>} */
723
+ (optimizationEntry.snapshotContent);
724
+ const snapshotEntries =
725
+ /** @type {SnapshotOptimizationValue<U, T>} */
726
+ (this._get(snapshot));
619
727
  for (const path of snapshotContent) {
620
728
  if (!capturedFiles.has(path)) {
621
729
  if (!snapshotEntries.has(path)) {
622
730
  // File is not shared and can't be removed from the snapshot
623
731
  // because it's in a child of the snapshot
624
- continue optimizationEntries;
732
+ continue optimizationEntriesLabel;
625
733
  }
626
734
  nonSharedFiles.add(path);
627
735
  continue;
@@ -638,7 +746,7 @@ class SnapshotOptimization {
638
746
  const sharedCount = snapshotContent.size - nonSharedFiles.size;
639
747
  if (sharedCount < MIN_COMMON_SNAPSHOT_SIZE) {
640
748
  // Common part it too small
641
- continue optimizationEntries;
749
+ continue;
642
750
  }
643
751
  // Extract common timestamps from both snapshots
644
752
  let commonMap;
@@ -663,7 +771,10 @@ class SnapshotOptimization {
663
771
  if (this._useStartTime) {
664
772
  commonSnapshot.setMergedStartTime(newSnapshot.startTime, snapshot);
665
773
  }
666
- this._set(commonSnapshot, commonMap);
774
+ this._set(
775
+ commonSnapshot,
776
+ /** @type {SnapshotOptimizationValue<U, T>} */ (commonMap)
777
+ );
667
778
  newSnapshot.addChild(commonSnapshot);
668
779
  snapshot.addChild(commonSnapshot);
669
780
  // Create optimization entry
@@ -686,7 +797,7 @@ class SnapshotOptimization {
686
797
  const snapshotEntries = this._get(snapshot);
687
798
  if (snapshotEntries === undefined) {
688
799
  // Incomplete snapshot, that can't be used
689
- continue optimizationEntries;
800
+ continue;
690
801
  }
691
802
  let commonMap;
692
803
  if (this._isSet) {
@@ -713,14 +824,18 @@ class SnapshotOptimization {
713
824
 
714
825
  if (commonMap.size < MIN_COMMON_SNAPSHOT_SIZE) {
715
826
  // Common part it too small
716
- continue optimizationEntries;
827
+ continue;
717
828
  }
718
829
  // Create and attach snapshot
719
830
  const commonSnapshot = new Snapshot();
720
831
  if (this._useStartTime) {
721
832
  commonSnapshot.setMergedStartTime(newSnapshot.startTime, snapshot);
722
833
  }
723
- this._set(commonSnapshot, commonMap);
834
+ this._set(
835
+ commonSnapshot,
836
+ /** @type {SnapshotOptimizationValue<U, T>} */
837
+ (commonMap)
838
+ );
724
839
  newSnapshot.addChild(commonSnapshot);
725
840
  snapshot.addChild(commonSnapshot);
726
841
  // Remove files from snapshot
@@ -746,7 +861,7 @@ class SnapshotOptimization {
746
861
 
747
862
  /**
748
863
  * @param {string} str input
749
- * @returns {TODO} result
864
+ * @returns {string} result
750
865
  */
751
866
  const parseString = str => {
752
867
  if (str[0] === "'" || str[0] === "`")
@@ -768,13 +883,14 @@ const applyMtime = mtime => {
768
883
  /**
769
884
  * @template T
770
885
  * @template K
771
- * @param {Map<T, K>} a source map
772
- * @param {Map<T, K>} b joining map
886
+ * @param {Map<T, K> | undefined} a source map
887
+ * @param {Map<T, K> | undefined} b joining map
773
888
  * @returns {Map<T, K>} joined map
774
889
  */
775
890
  const mergeMaps = (a, b) => {
776
- if (!b || b.size === 0) return a;
777
- if (!a || a.size === 0) return b;
891
+ if (!b || b.size === 0) return /** @type {Map<T, K>} */ (a);
892
+ if (!a || a.size === 0) return /** @type {Map<T, K>} */ (b);
893
+ /** @type {Map<T, K>} */
778
894
  const map = new Map(a);
779
895
  for (const [key, value] of b) {
780
896
  map.set(key, value);
@@ -784,13 +900,14 @@ const mergeMaps = (a, b) => {
784
900
 
785
901
  /**
786
902
  * @template T
787
- * @param {Set<T>} a source map
788
- * @param {Set<T>} b joining map
903
+ * @param {Set<T> | undefined} a source map
904
+ * @param {Set<T> | undefined} b joining map
789
905
  * @returns {Set<T>} joined map
790
906
  */
791
907
  const mergeSets = (a, b) => {
792
- if (!b || b.size === 0) return a;
793
- if (!a || a.size === 0) return b;
908
+ if (!b || b.size === 0) return /** @type {Set<T>} */ (a);
909
+ if (!a || a.size === 0) return /** @type {Set<T>} */ (b);
910
+ /** @type {Set<T>} */
794
911
  const map = new Set(a);
795
912
  for (const item of b) {
796
913
  map.add(item);
@@ -912,6 +1029,8 @@ const addAll = (source, target) => {
912
1029
  for (const key of source) target.add(key);
913
1030
  };
914
1031
 
1032
+ /** @typedef {Set<string>} LoggedPaths */
1033
+
915
1034
  /**
916
1035
  * Used to access information about the filesystem in a cached way
917
1036
  */
@@ -938,9 +1057,10 @@ class FileSystemInfo {
938
1057
  this.fs = fs;
939
1058
  this.logger = logger;
940
1059
  this._remainingLogs = logger ? 40 : 0;
1060
+ /** @type {LoggedPaths | undefined} */
941
1061
  this._loggedPaths = logger ? new Set() : undefined;
942
1062
  this._hashFunction = hashFunction;
943
- /** @type {WeakMap<Snapshot, boolean | (function(WebpackError=, boolean=): void)[]>} */
1063
+ /** @type {WeakMap<Snapshot, boolean | (function((WebpackError | null)=, boolean=): void)[]>} */
944
1064
  this._snapshotCache = new WeakMap();
945
1065
  this._fileTimestampsOptimization = new SnapshotOptimization(
946
1066
  s => s.hasFileTimestamps(),
@@ -1021,37 +1141,37 @@ class FileSystemInfo {
1021
1141
  this._contextTshs = new Map();
1022
1142
  /** @type {Map<string, string>} */
1023
1143
  this._managedItems = new Map();
1024
- /** @type {AsyncQueue<string, string, FileSystemInfoEntry | null>} */
1144
+ /** @type {AsyncQueue<string, string, FileSystemInfoEntry>} */
1025
1145
  this.fileTimestampQueue = new AsyncQueue({
1026
1146
  name: "file timestamp",
1027
1147
  parallelism: 30,
1028
1148
  processor: this._readFileTimestamp.bind(this)
1029
1149
  });
1030
- /** @type {AsyncQueue<string, string, string | null>} */
1150
+ /** @type {AsyncQueue<string, string, string>} */
1031
1151
  this.fileHashQueue = new AsyncQueue({
1032
1152
  name: "file hash",
1033
1153
  parallelism: 10,
1034
1154
  processor: this._readFileHash.bind(this)
1035
1155
  });
1036
- /** @type {AsyncQueue<string, string, ContextFileSystemInfoEntry | null>} */
1156
+ /** @type {AsyncQueue<string, string, ContextFileSystemInfoEntry>} */
1037
1157
  this.contextTimestampQueue = new AsyncQueue({
1038
1158
  name: "context timestamp",
1039
1159
  parallelism: 2,
1040
1160
  processor: this._readContextTimestamp.bind(this)
1041
1161
  });
1042
- /** @type {AsyncQueue<string, string, ContextHash | null>} */
1162
+ /** @type {AsyncQueue<string, string, ContextHash>} */
1043
1163
  this.contextHashQueue = new AsyncQueue({
1044
1164
  name: "context hash",
1045
1165
  parallelism: 2,
1046
1166
  processor: this._readContextHash.bind(this)
1047
1167
  });
1048
- /** @type {AsyncQueue<string, string, ContextTimestampAndHash | null>} */
1168
+ /** @type {AsyncQueue<string, string, ContextTimestampAndHash>} */
1049
1169
  this.contextTshQueue = new AsyncQueue({
1050
1170
  name: "context hash and timestamp",
1051
1171
  parallelism: 2,
1052
1172
  processor: this._readContextTimestampAndHash.bind(this)
1053
1173
  });
1054
- /** @type {AsyncQueue<string, string, string | null>} */
1174
+ /** @type {AsyncQueue<string, string, string>} */
1055
1175
  this.managedItemQueue = new AsyncQueue({
1056
1176
  name: "managed item info",
1057
1177
  parallelism: 10,
@@ -1140,51 +1260,51 @@ class FileSystemInfo {
1140
1260
  `File info in cache: ${this._fileTimestamps.size} timestamps ${this._fileHashes.size} hashes ${this._fileTshs.size} timestamp hash combinations`
1141
1261
  );
1142
1262
  logWhenMessage(
1143
- `File timestamp snapshot optimization`,
1263
+ "File timestamp snapshot optimization",
1144
1264
  this._fileTimestampsOptimization.getStatisticMessage()
1145
1265
  );
1146
1266
  logWhenMessage(
1147
- `File hash snapshot optimization`,
1267
+ "File hash snapshot optimization",
1148
1268
  this._fileHashesOptimization.getStatisticMessage()
1149
1269
  );
1150
1270
  logWhenMessage(
1151
- `File timestamp hash combination snapshot optimization`,
1271
+ "File timestamp hash combination snapshot optimization",
1152
1272
  this._fileTshsOptimization.getStatisticMessage()
1153
1273
  );
1154
1274
  logger.log(
1155
1275
  `Directory info in cache: ${this._contextTimestamps.size} timestamps ${this._contextHashes.size} hashes ${this._contextTshs.size} timestamp hash combinations`
1156
1276
  );
1157
1277
  logWhenMessage(
1158
- `Directory timestamp snapshot optimization`,
1278
+ "Directory timestamp snapshot optimization",
1159
1279
  this._contextTimestampsOptimization.getStatisticMessage()
1160
1280
  );
1161
1281
  logWhenMessage(
1162
- `Directory hash snapshot optimization`,
1282
+ "Directory hash snapshot optimization",
1163
1283
  this._contextHashesOptimization.getStatisticMessage()
1164
1284
  );
1165
1285
  logWhenMessage(
1166
- `Directory timestamp hash combination snapshot optimization`,
1286
+ "Directory timestamp hash combination snapshot optimization",
1167
1287
  this._contextTshsOptimization.getStatisticMessage()
1168
1288
  );
1169
1289
  logWhenMessage(
1170
- `Missing items snapshot optimization`,
1290
+ "Missing items snapshot optimization",
1171
1291
  this._missingExistenceOptimization.getStatisticMessage()
1172
1292
  );
1173
1293
  logger.log(`Managed items info in cache: ${this._managedItems.size} items`);
1174
1294
  logWhenMessage(
1175
- `Managed items snapshot optimization`,
1295
+ "Managed items snapshot optimization",
1176
1296
  this._managedItemInfoOptimization.getStatisticMessage()
1177
1297
  );
1178
1298
  logWhenMessage(
1179
- `Managed files snapshot optimization`,
1299
+ "Managed files snapshot optimization",
1180
1300
  this._managedFilesOptimization.getStatisticMessage()
1181
1301
  );
1182
1302
  logWhenMessage(
1183
- `Managed contexts snapshot optimization`,
1303
+ "Managed contexts snapshot optimization",
1184
1304
  this._managedContextsOptimization.getStatisticMessage()
1185
1305
  );
1186
1306
  logWhenMessage(
1187
- `Managed missing snapshot optimization`,
1307
+ "Managed missing snapshot optimization",
1188
1308
  this._managedMissingOptimization.getStatisticMessage()
1189
1309
  );
1190
1310
  }
@@ -1196,11 +1316,14 @@ class FileSystemInfo {
1196
1316
  */
1197
1317
  _log(path, reason, ...args) {
1198
1318
  const key = path + reason;
1199
- if (this._loggedPaths.has(key)) return;
1200
- this._loggedPaths.add(key);
1201
- this.logger.debug(`${path} invalidated because ${reason}`, ...args);
1319
+ const loggedPaths = /** @type {LoggedPaths} */ (this._loggedPaths);
1320
+ if (loggedPaths.has(key)) return;
1321
+ loggedPaths.add(key);
1322
+ /** @type {Logger} */
1323
+ (this.logger).debug(`${path} invalidated because ${reason}`, ...args);
1202
1324
  if (--this._remainingLogs === 0) {
1203
- this.logger.debug(
1325
+ /** @type {Logger} */
1326
+ (this.logger).debug(
1204
1327
  "Logging limit has been reached and no further logging will be emitted by FileSystemInfo"
1205
1328
  );
1206
1329
  }
@@ -1284,10 +1407,15 @@ class FileSystemInfo {
1284
1407
  if (cache === "ignore") return callback(null, "ignore");
1285
1408
  const resolved = getResolvedTimestamp(cache);
1286
1409
  if (resolved !== undefined) return callback(null, resolved);
1287
- return this._resolveContextTimestamp(cache, callback);
1410
+ return this._resolveContextTimestamp(
1411
+ /** @type {ResolvedContextFileSystemInfoEntry} */
1412
+ (cache),
1413
+ callback
1414
+ );
1288
1415
  }
1289
- this.contextTimestampQueue.add(path, (err, entry) => {
1416
+ this.contextTimestampQueue.add(path, (err, _entry) => {
1290
1417
  if (err) return callback(err);
1418
+ const entry = /** @type {ContextFileSystemInfoEntry} */ (_entry);
1291
1419
  const resolved = getResolvedTimestamp(entry);
1292
1420
  if (resolved !== undefined) return callback(null, resolved);
1293
1421
  this._resolveContextTimestamp(entry, callback);
@@ -1329,8 +1457,9 @@ class FileSystemInfo {
1329
1457
  return callback(null, /** @type {string} */ (resolved));
1330
1458
  return this._resolveContextHash(cache, callback);
1331
1459
  }
1332
- this.contextHashQueue.add(path, (err, entry) => {
1460
+ this.contextHashQueue.add(path, (err, _entry) => {
1333
1461
  if (err) return callback(err);
1462
+ const entry = /** @type {ContextHash} */ (_entry);
1334
1463
  const resolved = getResolvedHash(entry);
1335
1464
  if (resolved !== undefined)
1336
1465
  return callback(null, /** @type {string} */ (resolved));
@@ -1351,7 +1480,7 @@ class FileSystemInfo {
1351
1480
 
1352
1481
  /**
1353
1482
  * @param {string} path context path
1354
- * @param {function((WebpackError | null)=, ResolvedContextTimestampAndHash=): void} callback callback function
1483
+ * @param {function((WebpackError | null)=, (ResolvedContextTimestampAndHash | null)=): void} callback callback function
1355
1484
  * @returns {void}
1356
1485
  */
1357
1486
  getContextTsh(path, callback) {
@@ -1361,8 +1490,9 @@ class FileSystemInfo {
1361
1490
  if (resolved !== undefined) return callback(null, resolved);
1362
1491
  return this._resolveContextTsh(cache, callback);
1363
1492
  }
1364
- this.contextTshQueue.add(path, (err, entry) => {
1493
+ this.contextTshQueue.add(path, (err, _entry) => {
1365
1494
  if (err) return callback(err);
1495
+ const entry = /** @type {ContextTimestampAndHash} */ (_entry);
1366
1496
  const resolved = getResolvedTimestamp(entry);
1367
1497
  if (resolved !== undefined) return callback(null, resolved);
1368
1498
  this._resolveContextTsh(entry, callback);
@@ -1443,12 +1573,17 @@ class FileSystemInfo {
1443
1573
  missingDependencies: resolveMissing
1444
1574
  };
1445
1575
  /**
1446
- * @param {string} expected expected result
1576
+ * @param {undefined | boolean | string} expected expected result
1447
1577
  * @returns {string} expected result
1448
1578
  */
1449
- const expectedToString = expected => {
1450
- return expected ? ` (expected ${expected})` : "";
1451
- };
1579
+ const expectedToString = expected =>
1580
+ expected ? ` (expected ${expected})` : "";
1581
+ /** @typedef {{ type: JobType, context: string | undefined, path: string, issuer: Job | undefined, expected: undefined | boolean | string }} Job */
1582
+
1583
+ /**
1584
+ * @param {Job} job job
1585
+ * @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
1586
+ */
1452
1587
  const jobToString = job => {
1453
1588
  switch (job.type) {
1454
1589
  case RBDT_RESOLVE_CJS:
@@ -1478,105 +1613,135 @@ class FileSystemInfo {
1478
1613
  }
1479
1614
  return `unknown ${job.type} ${job.path}`;
1480
1615
  };
1616
+ /**
1617
+ * @param {Job} job job
1618
+ * @returns {string} string value
1619
+ */
1481
1620
  const pathToString = job => {
1482
1621
  let result = ` at ${jobToString(job)}`;
1483
- job = job.issuer;
1622
+ /** @type {Job | undefined} */
1623
+ (job) = job.issuer;
1484
1624
  while (job !== undefined) {
1485
1625
  result += `\n at ${jobToString(job)}`;
1486
- job = job.issuer;
1626
+ job = /** @type {Job} */ (job.issuer);
1487
1627
  }
1488
1628
  return result;
1489
1629
  };
1630
+ const logger = /** @type {Logger} */ (this.logger);
1490
1631
  processAsyncTree(
1491
- Array.from(deps, dep => ({
1492
- type: RBDT_RESOLVE_CJS,
1493
- context,
1494
- path: dep,
1495
- expected: undefined,
1496
- issuer: undefined
1497
- })),
1632
+ Array.from(
1633
+ deps,
1634
+ dep =>
1635
+ /** @type {Job} */ ({
1636
+ type: RBDT_RESOLVE_CJS,
1637
+ context,
1638
+ path: dep,
1639
+ expected: undefined,
1640
+ issuer: undefined
1641
+ })
1642
+ ),
1498
1643
  20,
1499
1644
  (job, push, callback) => {
1500
1645
  const { type, context, path, expected } = job;
1646
+ /**
1647
+ * @param {string} path path
1648
+ * @returns {void}
1649
+ */
1501
1650
  const resolveDirectory = path => {
1502
1651
  const key = `d\n${context}\n${path}`;
1503
1652
  if (resolveResults.has(key)) {
1504
1653
  return callback();
1505
1654
  }
1506
1655
  resolveResults.set(key, undefined);
1507
- resolveContext(context, path, resolverContext, (err, _, result) => {
1508
- if (err) {
1509
- if (expected === false) {
1510
- resolveResults.set(key, false);
1511
- return callback();
1512
- }
1513
- invalidResolveResults.add(key);
1514
- err.message += `\nwhile resolving '${path}' in ${context} to a directory`;
1515
- return callback(err);
1516
- }
1517
- const resultPath = result.path;
1518
- resolveResults.set(key, resultPath);
1519
- push({
1520
- type: RBDT_DIRECTORY,
1521
- context: undefined,
1522
- path: /** @type {string} */ (resultPath),
1523
- expected: undefined,
1524
- issuer: job
1525
- });
1526
- callback();
1527
- });
1528
- };
1529
- const resolveFile = (path, symbol, resolve) => {
1530
- const key = `${symbol}\n${context}\n${path}`;
1531
- if (resolveResults.has(key)) {
1532
- return callback();
1533
- }
1534
- resolveResults.set(key, undefined);
1535
- resolve(context, path, resolverContext, (err, _, result) => {
1536
- if (typeof expected === "string") {
1537
- if (!err && result && result.path === expected) {
1538
- resolveResults.set(key, result.path);
1539
- } else {
1540
- invalidResolveResults.add(key);
1541
- /** @type {Logger} */
1542
- (this.logger).warn(
1543
- `Resolving '${path}' in ${context} for build dependencies doesn't lead to expected result '${expected}', but to '${
1544
- err || (result && result.path)
1545
- }' instead. Resolving dependencies are ignored for this path.\n${pathToString(
1546
- job
1547
- )}`
1548
- );
1549
- }
1550
- } else {
1656
+ resolveContext(
1657
+ /** @type {string} */ (context),
1658
+ path,
1659
+ resolverContext,
1660
+ (err, _, result) => {
1551
1661
  if (err) {
1552
1662
  if (expected === false) {
1553
1663
  resolveResults.set(key, false);
1554
1664
  return callback();
1555
1665
  }
1556
1666
  invalidResolveResults.add(key);
1557
- err.message += `\nwhile resolving '${path}' in ${context} as file\n${pathToString(
1558
- job
1559
- )}`;
1667
+ err.message += `\nwhile resolving '${path}' in ${context} to a directory`;
1560
1668
  return callback(err);
1561
1669
  }
1562
- const resultPath = result.path;
1670
+ const resultPath = /** @type {ResolveRequest} */ (result).path;
1563
1671
  resolveResults.set(key, resultPath);
1564
1672
  push({
1565
- type: RBDT_FILE,
1673
+ type: RBDT_DIRECTORY,
1566
1674
  context: undefined,
1567
- path: resultPath,
1675
+ path: /** @type {string} */ (resultPath),
1568
1676
  expected: undefined,
1569
1677
  issuer: job
1570
1678
  });
1679
+ callback();
1571
1680
  }
1572
- callback();
1573
- });
1681
+ );
1682
+ };
1683
+ /**
1684
+ * @param {string} path path
1685
+ * @param {("f" | "c" | "e")=} symbol symbol
1686
+ * @param {(ResolveFunctionAsync)=} resolve resolve fn
1687
+ * @returns {void}
1688
+ */
1689
+ const resolveFile = (path, symbol, resolve) => {
1690
+ const key = `${symbol}\n${context}\n${path}`;
1691
+ if (resolveResults.has(key)) {
1692
+ return callback();
1693
+ }
1694
+ resolveResults.set(key, undefined);
1695
+ /** @type {ResolveFunctionAsync} */
1696
+ (resolve)(
1697
+ /** @type {string} */ (context),
1698
+ path,
1699
+ resolverContext,
1700
+ (err, _, result) => {
1701
+ if (typeof expected === "string") {
1702
+ if (!err && result && result.path === expected) {
1703
+ resolveResults.set(key, result.path);
1704
+ } else {
1705
+ invalidResolveResults.add(key);
1706
+ logger.warn(
1707
+ `Resolving '${path}' in ${context} for build dependencies doesn't lead to expected result '${expected}', but to '${
1708
+ err || (result && result.path)
1709
+ }' instead. Resolving dependencies are ignored for this path.\n${pathToString(
1710
+ job
1711
+ )}`
1712
+ );
1713
+ }
1714
+ } else {
1715
+ if (err) {
1716
+ if (expected === false) {
1717
+ resolveResults.set(key, false);
1718
+ return callback();
1719
+ }
1720
+ invalidResolveResults.add(key);
1721
+ err.message += `\nwhile resolving '${path}' in ${context} as file\n${pathToString(
1722
+ job
1723
+ )}`;
1724
+ return callback(err);
1725
+ }
1726
+ const resultPath = /** @type {ResolveRequest} */ (result).path;
1727
+ resolveResults.set(key, resultPath);
1728
+ push({
1729
+ type: RBDT_FILE,
1730
+ context: undefined,
1731
+ path: /** @type {string} */ (resultPath),
1732
+ expected: undefined,
1733
+ issuer: job
1734
+ });
1735
+ }
1736
+ callback();
1737
+ }
1738
+ );
1574
1739
  };
1575
1740
  switch (type) {
1576
1741
  case RBDT_RESOLVE_CJS: {
1577
1742
  const isDirectory = /[\\/]$/.test(path);
1578
1743
  if (isDirectory) {
1579
- resolveDirectory(path.slice(0, path.length - 1));
1744
+ resolveDirectory(path.slice(0, -1));
1580
1745
  } else {
1581
1746
  resolveFile(path, "f", resolveCjs);
1582
1747
  }
@@ -1585,7 +1750,7 @@ class FileSystemInfo {
1585
1750
  case RBDT_RESOLVE_ESM: {
1586
1751
  const isDirectory = /[\\/]$/.test(path);
1587
1752
  if (isDirectory) {
1588
- resolveDirectory(path.slice(0, path.length - 1));
1753
+ resolveDirectory(path.slice(0, -1));
1589
1754
  } else {
1590
1755
  resolveFile(path);
1591
1756
  }
@@ -1613,7 +1778,8 @@ class FileSystemInfo {
1613
1778
  break;
1614
1779
  }
1615
1780
  files.add(path);
1616
- this.fs.realpath(path, (err, _realPath) => {
1781
+ /** @type {NonNullable<InputFileSystem["realpath"]>} */
1782
+ (this.fs.realpath)(path, (err, _realPath) => {
1617
1783
  if (err) return callback(err);
1618
1784
  const realPath = /** @type {string} */ (_realPath);
1619
1785
  if (realPath !== path) {
@@ -1639,7 +1805,8 @@ class FileSystemInfo {
1639
1805
  break;
1640
1806
  }
1641
1807
  directories.add(path);
1642
- this.fs.realpath(path, (err, _realPath) => {
1808
+ /** @type {NonNullable<InputFileSystem["realpath"]>} */
1809
+ (this.fs.realpath)(path, (err, _realPath) => {
1643
1810
  if (err) return callback(err);
1644
1811
  const realPath = /** @type {string} */ (_realPath);
1645
1812
  if (realPath !== path) {
@@ -1670,7 +1837,7 @@ class FileSystemInfo {
1670
1837
  const module = require.cache[path];
1671
1838
  if (module && Array.isArray(module.children)) {
1672
1839
  children: for (const child of module.children) {
1673
- let childPath = child.filename;
1840
+ const childPath = child.filename;
1674
1841
  if (childPath) {
1675
1842
  push({
1676
1843
  type: RBDT_FILE,
@@ -1682,7 +1849,7 @@ class FileSystemInfo {
1682
1849
  const context = dirname(this.fs, path);
1683
1850
  for (const modulePath of module.paths) {
1684
1851
  if (childPath.startsWith(modulePath)) {
1685
- let subPath = childPath.slice(modulePath.length + 1);
1852
+ const subPath = childPath.slice(modulePath.length + 1);
1686
1853
  const packageMatch = /^(@[^\\/]+[\\/])[^\\/]+/.exec(
1687
1854
  subPath
1688
1855
  );
@@ -1690,12 +1857,12 @@ class FileSystemInfo {
1690
1857
  push({
1691
1858
  type: RBDT_FILE,
1692
1859
  context: undefined,
1693
- path:
1860
+ path: `${
1694
1861
  modulePath +
1695
1862
  childPath[modulePath.length] +
1696
1863
  packageMatch[0] +
1697
- childPath[modulePath.length] +
1698
- "package.json",
1864
+ childPath[modulePath.length]
1865
+ }package.json`,
1699
1866
  expected: false,
1700
1867
  issuer: job
1701
1868
  });
@@ -1730,7 +1897,7 @@ class FileSystemInfo {
1730
1897
  }
1731
1898
  } else if (supportsEsm && /\.m?js$/.test(path)) {
1732
1899
  if (!this._warnAboutExperimentalEsmTracking) {
1733
- this.logger.log(
1900
+ logger.log(
1734
1901
  "Node.js doesn't offer a (nice) way to introspect the ESM dependency graph yet.\n" +
1735
1902
  "Until a full solution is available webpack uses an experimental ESM tracking based on parsing.\n" +
1736
1903
  "As best effort webpack parses the ESM files to guess dependencies. But this can lead to expensive and incorrect tracking."
@@ -1743,7 +1910,7 @@ class FileSystemInfo {
1743
1910
  if (err) return callback(err);
1744
1911
  try {
1745
1912
  const context = dirname(this.fs, path);
1746
- const source = content.toString();
1913
+ const source = /** @type {Buffer} */ (content).toString();
1747
1914
  const [imports] = lexer.parse(source);
1748
1915
  for (const imp of imports) {
1749
1916
  try {
@@ -1755,7 +1922,7 @@ class FileSystemInfo {
1755
1922
  );
1756
1923
  } else if (imp.d > -1) {
1757
1924
  // import()
1758
- let expr = source.substring(imp.s, imp.e).trim();
1925
+ const expr = source.substring(imp.s, imp.e).trim();
1759
1926
  dependency = parseString(expr);
1760
1927
  } else {
1761
1928
  // e.g. import.meta
@@ -1773,34 +1940,34 @@ class FileSystemInfo {
1773
1940
  expected: imp.d > -1 ? false : undefined,
1774
1941
  issuer: job
1775
1942
  });
1776
- } catch (e) {
1777
- this.logger.warn(
1943
+ } catch (err1) {
1944
+ logger.warn(
1778
1945
  `Parsing of ${path} for build dependencies failed at 'import(${source.substring(
1779
1946
  imp.s,
1780
1947
  imp.e
1781
1948
  )})'.\n` +
1782
1949
  "Build dependencies behind this expression are ignored and might cause incorrect cache invalidation."
1783
1950
  );
1784
- this.logger.debug(pathToString(job));
1785
- this.logger.debug(e.stack);
1951
+ logger.debug(pathToString(job));
1952
+ logger.debug(/** @type {Error} */ (err1).stack);
1786
1953
  }
1787
1954
  }
1788
- } catch (e) {
1789
- this.logger.warn(
1955
+ } catch (err2) {
1956
+ logger.warn(
1790
1957
  `Parsing of ${path} for build dependencies failed and all dependencies of this file are ignored, which might cause incorrect cache invalidation..`
1791
1958
  );
1792
- this.logger.debug(pathToString(job));
1793
- this.logger.debug(e.stack);
1959
+ logger.debug(pathToString(job));
1960
+ logger.debug(/** @type {Error} */ (err2).stack);
1794
1961
  }
1795
1962
  process.nextTick(callback);
1796
1963
  });
1797
1964
  }, callback);
1798
1965
  break;
1799
1966
  } else {
1800
- this.logger.log(
1967
+ logger.log(
1801
1968
  `Assuming ${path} has no dependencies as we were unable to assign it to any module system.`
1802
1969
  );
1803
- this.logger.debug(pathToString(job));
1970
+ logger.debug(pathToString(job));
1804
1971
  }
1805
1972
  process.nextTick(callback);
1806
1973
  break;
@@ -1832,9 +1999,11 @@ class FileSystemInfo {
1832
1999
  resolveFiles.add(packageJson);
1833
2000
  let packageData;
1834
2001
  try {
1835
- packageData = JSON.parse(content.toString("utf-8"));
1836
- } catch (e) {
1837
- return callback(e);
2002
+ packageData = JSON.parse(
2003
+ /** @type {Buffer} */ (content).toString("utf-8")
2004
+ );
2005
+ } catch (parseErr) {
2006
+ return callback(/** @type {Error} */ (parseErr));
1838
2007
  }
1839
2008
  const depsObject = packageData.dependencies;
1840
2009
  const optionalDepsObject = packageData.optionalDependencies;
@@ -1908,7 +2077,7 @@ class FileSystemInfo {
1908
2077
  if (expectedResult === false)
1909
2078
  return callback(err ? undefined : INVALID);
1910
2079
  if (err) return callback(err);
1911
- const resultPath = result.path;
2080
+ const resultPath = /** @type {ResolveRequest} */ (result).path;
1912
2081
  if (resultPath !== expectedResult) return callback(INVALID);
1913
2082
  callback();
1914
2083
  });
@@ -1918,7 +2087,7 @@ class FileSystemInfo {
1918
2087
  if (expectedResult === false)
1919
2088
  return callback(err ? undefined : INVALID);
1920
2089
  if (err) return callback(err);
1921
- const resultPath = result.path;
2090
+ const resultPath = /** @type {ResolveRequest} */ (result).path;
1922
2091
  if (resultPath !== expectedResult) return callback(INVALID);
1923
2092
  callback();
1924
2093
  });
@@ -1928,7 +2097,7 @@ class FileSystemInfo {
1928
2097
  if (expectedResult === false)
1929
2098
  return callback(err ? undefined : INVALID);
1930
2099
  if (err) return callback(err);
1931
- const resultPath = result.path;
2100
+ const resultPath = /** @type {ResolveRequest} */ (result).path;
1932
2101
  if (resultPath !== expectedResult) return callback(INVALID);
1933
2102
  callback();
1934
2103
  });
@@ -1938,7 +2107,7 @@ class FileSystemInfo {
1938
2107
  if (expectedResult === false)
1939
2108
  return callback(err ? undefined : INVALID);
1940
2109
  if (err) return callback(err);
1941
- const resultPath = result.path;
2110
+ const resultPath = /** @type {ResolveRequest} */ (result).path;
1942
2111
  if (resultPath !== expectedResult) return callback(INVALID);
1943
2112
  callback();
1944
2113
  });
@@ -1965,39 +2134,38 @@ class FileSystemInfo {
1965
2134
  }
1966
2135
 
1967
2136
  /**
1968
- *
1969
2137
  * @param {number | null | undefined} startTime when processing the files has started
1970
2138
  * @param {Iterable<string> | null} files all files
1971
2139
  * @param {Iterable<string> | null} directories all directories
1972
2140
  * @param {Iterable<string> | null} missing all missing files or directories
1973
2141
  * @param {SnapshotOptions | null | undefined} options options object (for future extensions)
1974
- * @param {function((WebpackError | null)=, (Snapshot | null)=): void} callback callback function
2142
+ * @param {function(WebpackError | null, Snapshot | null): void} callback callback function
1975
2143
  * @returns {void}
1976
2144
  */
1977
2145
  createSnapshot(startTime, files, directories, missing, options, callback) {
1978
- /** @type {Map<string, FileSystemInfoEntry | null>} */
2146
+ /** @type {FileTimestamps} */
1979
2147
  const fileTimestamps = new Map();
1980
- /** @type {Map<string, string | null>} */
2148
+ /** @type {FileHashes} */
1981
2149
  const fileHashes = new Map();
1982
- /** @type {Map<string, TimestampAndHash | string | null>} */
2150
+ /** @type {FileTshs} */
1983
2151
  const fileTshs = new Map();
1984
- /** @type {Map<string, FileSystemInfoEntry | null>} */
2152
+ /** @type {ContextTimestamps} */
1985
2153
  const contextTimestamps = new Map();
1986
- /** @type {Map<string, string | null>} */
2154
+ /** @type {ContextHashes} */
1987
2155
  const contextHashes = new Map();
1988
- /** @type {Map<string, ResolvedContextTimestampAndHash | null>} */
2156
+ /** @type {ContextTshs} */
1989
2157
  const contextTshs = new Map();
1990
- /** @type {Map<string, boolean>} */
2158
+ /** @type {MissingExistence} */
1991
2159
  const missingExistence = new Map();
1992
- /** @type {Map<string, string>} */
2160
+ /** @type {ManagedItemInfo} */
1993
2161
  const managedItemInfo = new Map();
1994
- /** @type {Set<string>} */
2162
+ /** @type {ManagedFiles} */
1995
2163
  const managedFiles = new Set();
1996
- /** @type {Set<string>} */
2164
+ /** @type {ManagedContexts} */
1997
2165
  const managedContexts = new Set();
1998
- /** @type {Set<string>} */
2166
+ /** @type {ManagedMissing} */
1999
2167
  const managedMissing = new Set();
2000
- /** @type {Set<Snapshot>} */
2168
+ /** @type {Children} */
2001
2169
  const children = new Set();
2002
2170
 
2003
2171
  const snapshot = new Snapshot();
@@ -2064,6 +2232,11 @@ class FileSystemInfo {
2064
2232
  callback(null, null);
2065
2233
  }
2066
2234
  };
2235
+ /**
2236
+ * @param {string} path path
2237
+ * @param {Set<string>} managedSet managed set
2238
+ * @returns {boolean} true when managed
2239
+ */
2067
2240
  const checkManaged = (path, managedSet) => {
2068
2241
  for (const unmanagedPath of this.unmanagedPathsRegExps) {
2069
2242
  if (unmanagedPath.test(path)) return false;
@@ -2106,6 +2279,11 @@ class FileSystemInfo {
2106
2279
  }
2107
2280
  return false;
2108
2281
  };
2282
+ /**
2283
+ * @param {Iterable<string>} items items
2284
+ * @param {Set<string>} managedSet managed set
2285
+ * @returns {Set<string>} result
2286
+ */
2109
2287
  const captureNonManaged = (items, managedSet) => {
2110
2288
  const capturedItems = new Set();
2111
2289
  for (const path of items) {
@@ -2135,7 +2313,7 @@ class FileSystemInfo {
2135
2313
  }
2136
2314
  jobError();
2137
2315
  } else {
2138
- fileTshs.set(path, entry);
2316
+ fileTshs.set(path, /** @type {TimestampAndHash} */ (entry));
2139
2317
  jobDone();
2140
2318
  }
2141
2319
  });
@@ -2159,7 +2337,7 @@ class FileSystemInfo {
2159
2337
  }
2160
2338
  jobError();
2161
2339
  } else {
2162
- fileHashes.set(path, entry);
2340
+ fileHashes.set(path, /** @type {string} */ (entry));
2163
2341
  jobDone();
2164
2342
  }
2165
2343
  });
@@ -2185,7 +2363,11 @@ class FileSystemInfo {
2185
2363
  }
2186
2364
  jobError();
2187
2365
  } else {
2188
- fileTimestamps.set(path, entry);
2366
+ fileTimestamps.set(
2367
+ path,
2368
+ /** @type {FileSystemInfoEntry} */
2369
+ (entry)
2370
+ );
2189
2371
  jobDone();
2190
2372
  }
2191
2373
  });
@@ -2197,13 +2379,16 @@ class FileSystemInfo {
2197
2379
  if (files) {
2198
2380
  processCapturedFiles(captureNonManaged(files, managedFiles));
2199
2381
  }
2382
+ /**
2383
+ * @param {Set<string>} capturedDirectories captured directories
2384
+ */
2200
2385
  const processCapturedDirectories = capturedDirectories => {
2201
2386
  switch (mode) {
2202
2387
  case 3:
2203
2388
  this._contextTshsOptimization.optimize(snapshot, capturedDirectories);
2204
2389
  for (const path of capturedDirectories) {
2205
2390
  const cache = this._contextTshs.get(path);
2206
- /** @type {ResolvedContextTimestampAndHash} */
2391
+ /** @type {ResolvedContextTimestampAndHash | null | undefined} */
2207
2392
  let resolved;
2208
2393
  if (
2209
2394
  cache !== undefined &&
@@ -2213,8 +2398,8 @@ class FileSystemInfo {
2213
2398
  } else {
2214
2399
  jobs++;
2215
2400
  /**
2216
- * @param {Error=} err error
2217
- * @param {ResolvedContextTimestampAndHash=} entry entry
2401
+ * @param {(WebpackError | null)=} err error
2402
+ * @param {(ResolvedContextTimestampAndHash | null)=} entry entry
2218
2403
  * @returns {void}
2219
2404
  */
2220
2405
  const callback = (err, entry) => {
@@ -2226,7 +2411,11 @@ class FileSystemInfo {
2226
2411
  }
2227
2412
  jobError();
2228
2413
  } else {
2229
- contextTshs.set(path, entry);
2414
+ contextTshs.set(
2415
+ path,
2416
+ /** @type {ResolvedContextTimestampAndHash | null} */
2417
+ (entry)
2418
+ );
2230
2419
  jobDone();
2231
2420
  }
2232
2421
  };
@@ -2253,6 +2442,10 @@ class FileSystemInfo {
2253
2442
  contextHashes.set(path, resolved);
2254
2443
  } else {
2255
2444
  jobs++;
2445
+ /**
2446
+ * @param {(WebpackError | null)=} err err
2447
+ * @param {string=} entry entry
2448
+ */
2256
2449
  const callback = (err, entry) => {
2257
2450
  if (err) {
2258
2451
  if (this.logger) {
@@ -2262,7 +2455,7 @@ class FileSystemInfo {
2262
2455
  }
2263
2456
  jobError();
2264
2457
  } else {
2265
- contextHashes.set(path, entry);
2458
+ contextHashes.set(path, /** @type {string} */ (entry));
2266
2459
  jobDone();
2267
2460
  }
2268
2461
  };
@@ -2291,8 +2484,8 @@ class FileSystemInfo {
2291
2484
  } else {
2292
2485
  jobs++;
2293
2486
  /**
2294
- * @param {Error=} err error
2295
- * @param {ResolvedContextFileSystemInfoEntry=} entry entry
2487
+ * @param {(Error | null)=} err error
2488
+ * @param {(FileSystemInfoEntry | "ignore" | null)=} entry entry
2296
2489
  * @returns {void}
2297
2490
  */
2298
2491
  const callback = (err, entry) => {
@@ -2304,12 +2497,20 @@ class FileSystemInfo {
2304
2497
  }
2305
2498
  jobError();
2306
2499
  } else {
2307
- contextTimestamps.set(path, entry);
2500
+ contextTimestamps.set(
2501
+ path,
2502
+ /** @type {FileSystemInfoEntry | null} */
2503
+ (entry)
2504
+ );
2308
2505
  jobDone();
2309
2506
  }
2310
2507
  };
2311
2508
  if (cache !== undefined) {
2312
- this._resolveContextTimestamp(cache, callback);
2509
+ this._resolveContextTimestamp(
2510
+ /** @type {ContextFileSystemInfoEntry} */
2511
+ (cache),
2512
+ callback
2513
+ );
2313
2514
  } else {
2314
2515
  this.getContextTimestamp(path, callback);
2315
2516
  }
@@ -2323,6 +2524,9 @@ class FileSystemInfo {
2323
2524
  captureNonManaged(directories, managedContexts)
2324
2525
  );
2325
2526
  }
2527
+ /**
2528
+ * @param {Set<string>} capturedMissing captured missing
2529
+ */
2326
2530
  const processCapturedMissing = capturedMissing => {
2327
2531
  this._missingExistenceOptimization.optimize(snapshot, capturedMissing);
2328
2532
  for (const path of capturedMissing) {
@@ -2382,6 +2586,10 @@ class FileSystemInfo {
2382
2586
  jobDone();
2383
2587
  } else {
2384
2588
  // Fallback to normal snapshotting
2589
+ /**
2590
+ * @param {Set<string>} set set
2591
+ * @param {function(Set<string>): void} fn fn
2592
+ */
2385
2593
  const process = (set, fn) => {
2386
2594
  if (set.size === 0) return;
2387
2595
  const captured = new Set();
@@ -2408,10 +2616,20 @@ class FileSystemInfo {
2408
2616
  */
2409
2617
  mergeSnapshots(snapshot1, snapshot2) {
2410
2618
  const snapshot = new Snapshot();
2411
- if (snapshot1.hasStartTime() && snapshot2.hasStartTime())
2412
- snapshot.setStartTime(Math.min(snapshot1.startTime, snapshot2.startTime));
2413
- else if (snapshot2.hasStartTime()) snapshot.startTime = snapshot2.startTime;
2414
- else if (snapshot1.hasStartTime()) snapshot.startTime = snapshot1.startTime;
2619
+ if (snapshot1.hasStartTime() && snapshot2.hasStartTime()) {
2620
+ snapshot.setStartTime(
2621
+ Math.min(
2622
+ /** @type {NonNullable<Snapshot["startTime"]>} */
2623
+ (snapshot1.startTime),
2624
+ /** @type {NonNullable<Snapshot["startTime"]>} */
2625
+ (snapshot2.startTime)
2626
+ )
2627
+ );
2628
+ } else if (snapshot2.hasStartTime()) {
2629
+ snapshot.startTime = snapshot2.startTime;
2630
+ } else if (snapshot1.hasStartTime()) {
2631
+ snapshot.startTime = snapshot1.startTime;
2632
+ }
2415
2633
  if (snapshot1.hasFileTimestamps() || snapshot2.hasFileTimestamps()) {
2416
2634
  snapshot.setFileTimestamps(
2417
2635
  mergeMaps(snapshot1.fileTimestamps, snapshot2.fileTimestamps)
@@ -2504,7 +2722,7 @@ class FileSystemInfo {
2504
2722
  */
2505
2723
  _checkSnapshotValidNoCache(snapshot, callback) {
2506
2724
  /** @type {number | undefined} */
2507
- let startTime = undefined;
2725
+ let startTime;
2508
2726
  if (snapshot.hasStartTime()) {
2509
2727
  startTime = snapshot.startTime;
2510
2728
  }
@@ -2523,23 +2741,27 @@ class FileSystemInfo {
2523
2741
  callback(null, false);
2524
2742
  }
2525
2743
  };
2744
+ /**
2745
+ * @param {string} path path
2746
+ * @param {WebpackError} err err
2747
+ */
2526
2748
  const invalidWithError = (path, err) => {
2527
2749
  if (this._remainingLogs > 0) {
2528
- this._log(path, `error occurred: %s`, err);
2750
+ this._log(path, "error occurred: %s", err);
2529
2751
  }
2530
2752
  invalid();
2531
2753
  };
2532
2754
  /**
2533
2755
  * @param {string} path file path
2534
- * @param {string} current current hash
2535
- * @param {string} snap snapshot hash
2756
+ * @param {string | null} current current hash
2757
+ * @param {string | null} snap snapshot hash
2536
2758
  * @returns {boolean} true, if ok
2537
2759
  */
2538
2760
  const checkHash = (path, current, snap) => {
2539
2761
  if (current !== snap) {
2540
2762
  // If hash differ it's invalid
2541
2763
  if (this._remainingLogs > 0) {
2542
- this._log(path, `hashes differ (%s != %s)`, current, snap);
2764
+ this._log(path, "hashes differ (%s != %s)", current, snap);
2543
2765
  }
2544
2766
  return false;
2545
2767
  }
@@ -2567,40 +2789,38 @@ class FileSystemInfo {
2567
2789
  };
2568
2790
  /**
2569
2791
  * @param {string} path file path
2570
- * @param {FileSystemInfoEntry} current current entry
2571
- * @param {FileSystemInfoEntry} snap entry from snapshot
2792
+ * @param {FileSystemInfoEntry | null} c current entry
2793
+ * @param {FileSystemInfoEntry | null} s entry from snapshot
2572
2794
  * @param {boolean} log log reason
2573
2795
  * @returns {boolean} true, if ok
2574
2796
  */
2575
- const checkFile = (path, current, snap, log = true) => {
2576
- if (current === snap) return true;
2577
- if (!checkExistence(path, Boolean(current), Boolean(snap))) return false;
2578
- if (current) {
2797
+ const checkFile = (path, c, s, log = true) => {
2798
+ if (c === s) return true;
2799
+ if (!checkExistence(path, Boolean(c), Boolean(s))) return false;
2800
+ if (c) {
2579
2801
  // For existing items only
2580
- if (typeof startTime === "number" && current.safeTime > startTime) {
2802
+ if (typeof startTime === "number" && c.safeTime > startTime) {
2581
2803
  // If a change happened after starting reading the item
2582
2804
  // this may no longer be valid
2583
2805
  if (log && this._remainingLogs > 0) {
2584
2806
  this._log(
2585
2807
  path,
2586
- `it may have changed (%d) after the start time of the snapshot (%d)`,
2587
- current.safeTime,
2808
+ "it may have changed (%d) after the start time of the snapshot (%d)",
2809
+ c.safeTime,
2588
2810
  startTime
2589
2811
  );
2590
2812
  }
2591
2813
  return false;
2592
2814
  }
2593
- if (
2594
- snap.timestamp !== undefined &&
2595
- current.timestamp !== snap.timestamp
2596
- ) {
2815
+ const snap = /** @type {FileSystemInfoEntry} */ (s);
2816
+ if (snap.timestamp !== undefined && c.timestamp !== snap.timestamp) {
2597
2817
  // If we have a timestamp (it was a file or symlink) and it differs from current timestamp
2598
2818
  // it's invalid
2599
2819
  if (log && this._remainingLogs > 0) {
2600
2820
  this._log(
2601
2821
  path,
2602
- `timestamps differ (%d != %d)`,
2603
- current.timestamp,
2822
+ "timestamps differ (%d != %d)",
2823
+ c.timestamp,
2604
2824
  snap.timestamp
2605
2825
  );
2606
2826
  }
@@ -2611,40 +2831,41 @@ class FileSystemInfo {
2611
2831
  };
2612
2832
  /**
2613
2833
  * @param {string} path file path
2614
- * @param {ResolvedContextFileSystemInfoEntry} current current entry
2615
- * @param {ResolvedContextFileSystemInfoEntry} snap entry from snapshot
2834
+ * @param {ResolvedContextFileSystemInfoEntry | null} c current entry
2835
+ * @param {ResolvedContextFileSystemInfoEntry | null} s entry from snapshot
2616
2836
  * @param {boolean} log log reason
2617
2837
  * @returns {boolean} true, if ok
2618
2838
  */
2619
- const checkContext = (path, current, snap, log = true) => {
2620
- if (current === snap) return true;
2621
- if (!checkExistence(path, Boolean(current), Boolean(snap))) return false;
2622
- if (current) {
2839
+ const checkContext = (path, c, s, log = true) => {
2840
+ if (c === s) return true;
2841
+ if (!checkExistence(path, Boolean(c), Boolean(s))) return false;
2842
+ if (c) {
2623
2843
  // For existing items only
2624
- if (typeof startTime === "number" && current.safeTime > startTime) {
2844
+ if (typeof startTime === "number" && c.safeTime > startTime) {
2625
2845
  // If a change happened after starting reading the item
2626
2846
  // this may no longer be valid
2627
2847
  if (log && this._remainingLogs > 0) {
2628
2848
  this._log(
2629
2849
  path,
2630
- `it may have changed (%d) after the start time of the snapshot (%d)`,
2631
- current.safeTime,
2850
+ "it may have changed (%d) after the start time of the snapshot (%d)",
2851
+ c.safeTime,
2632
2852
  startTime
2633
2853
  );
2634
2854
  }
2635
2855
  return false;
2636
2856
  }
2857
+ const snap = /** @type {ResolvedContextFileSystemInfoEntry} */ (s);
2637
2858
  if (
2638
2859
  snap.timestampHash !== undefined &&
2639
- current.timestampHash !== snap.timestampHash
2860
+ c.timestampHash !== snap.timestampHash
2640
2861
  ) {
2641
2862
  // If we have a timestampHash (it was a directory) and it differs from current timestampHash
2642
2863
  // it's invalid
2643
2864
  if (log && this._remainingLogs > 0) {
2644
2865
  this._log(
2645
2866
  path,
2646
- `timestamps hashes differ (%s != %s)`,
2647
- current.timestampHash,
2867
+ "timestamps hashes differ (%s != %s)",
2868
+ c.timestampHash,
2648
2869
  snap.timestampHash
2649
2870
  );
2650
2871
  }
@@ -2654,11 +2875,16 @@ class FileSystemInfo {
2654
2875
  return true;
2655
2876
  };
2656
2877
  if (snapshot.hasChildren()) {
2878
+ /**
2879
+ * @param {(WebpackError | null)=} err err
2880
+ * @param {boolean=} result result
2881
+ * @returns {void}
2882
+ */
2657
2883
  const childCallback = (err, result) => {
2658
2884
  if (err || !result) return invalid();
2659
- else jobDone();
2885
+ jobDone();
2660
2886
  };
2661
- for (const child of snapshot.children) {
2887
+ for (const child of /** @type {Children} */ (snapshot.children)) {
2662
2888
  const cache = this._snapshotCache.get(child);
2663
2889
  if (cache !== undefined) {
2664
2890
  this._statTestedChildrenCached++;
@@ -2680,7 +2906,9 @@ class FileSystemInfo {
2680
2906
  }
2681
2907
  }
2682
2908
  if (snapshot.hasFileTimestamps()) {
2683
- const { fileTimestamps } = snapshot;
2909
+ const fileTimestamps =
2910
+ /** @type {FileTimestamps} */
2911
+ (snapshot.fileTimestamps);
2684
2912
  this._statTestedEntries += fileTimestamps.size;
2685
2913
  for (const [path, ts] of fileTimestamps) {
2686
2914
  const cache = this._fileTimestamps.get(path);
@@ -2693,7 +2921,13 @@ class FileSystemInfo {
2693
2921
  jobs++;
2694
2922
  this.fileTimestampQueue.add(path, (err, entry) => {
2695
2923
  if (err) return invalidWithError(path, err);
2696
- if (!checkFile(path, entry, ts)) {
2924
+ if (
2925
+ !checkFile(
2926
+ path,
2927
+ /** @type {FileSystemInfoEntry | null} */ (entry),
2928
+ ts
2929
+ )
2930
+ ) {
2697
2931
  invalid();
2698
2932
  } else {
2699
2933
  jobDone();
@@ -2704,20 +2938,19 @@ class FileSystemInfo {
2704
2938
  }
2705
2939
  /**
2706
2940
  * @param {string} path file path
2707
- * @param {string} hash hash
2941
+ * @param {string | null} hash hash
2708
2942
  */
2709
2943
  const processFileHashSnapshot = (path, hash) => {
2710
2944
  const cache = this._fileHashes.get(path);
2711
2945
  if (cache !== undefined) {
2712
2946
  if (cache !== "ignore" && !checkHash(path, cache, hash)) {
2713
2947
  invalid();
2714
- return;
2715
2948
  }
2716
2949
  } else {
2717
2950
  jobs++;
2718
2951
  this.fileHashQueue.add(path, (err, entry) => {
2719
2952
  if (err) return invalidWithError(path, err);
2720
- if (!checkHash(path, entry, hash)) {
2953
+ if (!checkHash(path, /** @type {string} */ (entry), hash)) {
2721
2954
  invalid();
2722
2955
  } else {
2723
2956
  jobDone();
@@ -2726,14 +2959,14 @@ class FileSystemInfo {
2726
2959
  }
2727
2960
  };
2728
2961
  if (snapshot.hasFileHashes()) {
2729
- const { fileHashes } = snapshot;
2962
+ const fileHashes = /** @type {FileHashes} */ (snapshot.fileHashes);
2730
2963
  this._statTestedEntries += fileHashes.size;
2731
2964
  for (const [path, hash] of fileHashes) {
2732
2965
  processFileHashSnapshot(path, hash);
2733
2966
  }
2734
2967
  }
2735
2968
  if (snapshot.hasFileTshs()) {
2736
- const { fileTshs } = snapshot;
2969
+ const fileTshs = /** @type {FileTshs} */ (snapshot.fileTshs);
2737
2970
  this._statTestedEntries += fileTshs.size;
2738
2971
  for (const [path, tsh] of fileTshs) {
2739
2972
  if (typeof tsh === "string") {
@@ -2748,7 +2981,15 @@ class FileSystemInfo {
2748
2981
  jobs++;
2749
2982
  this.fileTimestampQueue.add(path, (err, entry) => {
2750
2983
  if (err) return invalidWithError(path, err);
2751
- if (!checkFile(path, entry, tsh, false)) {
2984
+ if (
2985
+ !checkFile(
2986
+ path,
2987
+ /** @type {FileSystemInfoEntry | null} */
2988
+ (entry),
2989
+ tsh,
2990
+ false
2991
+ )
2992
+ ) {
2752
2993
  processFileHashSnapshot(path, tsh && tsh.hash);
2753
2994
  }
2754
2995
  jobDone();
@@ -2758,7 +2999,9 @@ class FileSystemInfo {
2758
2999
  }
2759
3000
  }
2760
3001
  if (snapshot.hasContextTimestamps()) {
2761
- const { contextTimestamps } = snapshot;
3002
+ const contextTimestamps =
3003
+ /** @type {ContextTimestamps} */
3004
+ (snapshot.contextTimestamps);
2762
3005
  this._statTestedEntries += contextTimestamps.size;
2763
3006
  for (const [path, ts] of contextTimestamps) {
2764
3007
  const cache = this._contextTimestamps.get(path);
@@ -2775,26 +3018,41 @@ class FileSystemInfo {
2775
3018
  } else {
2776
3019
  jobs++;
2777
3020
  /**
2778
- * @param {Error=} err error
2779
- * @param {ResolvedContextFileSystemInfoEntry=} entry entry
3021
+ * @param {(WebpackError | null)=} err error
3022
+ * @param {(ResolvedContextFileSystemInfoEntry | "ignore" | null)=} entry entry
2780
3023
  * @returns {void}
2781
3024
  */
2782
3025
  const callback = (err, entry) => {
2783
3026
  if (err) return invalidWithError(path, err);
2784
- if (!checkContext(path, entry, ts)) {
3027
+ if (
3028
+ !checkContext(
3029
+ path,
3030
+ /** @type {ResolvedContextFileSystemInfoEntry | null} */
3031
+ (entry),
3032
+ ts
3033
+ )
3034
+ ) {
2785
3035
  invalid();
2786
3036
  } else {
2787
3037
  jobDone();
2788
3038
  }
2789
3039
  };
2790
3040
  if (cache !== undefined) {
2791
- this._resolveContextTimestamp(cache, callback);
3041
+ this._resolveContextTimestamp(
3042
+ /** @type {ContextFileSystemInfoEntry} */
3043
+ (cache),
3044
+ callback
3045
+ );
2792
3046
  } else {
2793
3047
  this.getContextTimestamp(path, callback);
2794
3048
  }
2795
3049
  }
2796
3050
  }
2797
3051
  }
3052
+ /**
3053
+ * @param {string} path path
3054
+ * @param {string | null} hash hash
3055
+ */
2798
3056
  const processContextHashSnapshot = (path, hash) => {
2799
3057
  const cache = this._contextHashes.get(path);
2800
3058
  let resolved;
@@ -2804,13 +3062,17 @@ class FileSystemInfo {
2804
3062
  ) {
2805
3063
  if (!checkHash(path, resolved, hash)) {
2806
3064
  invalid();
2807
- return;
2808
3065
  }
2809
3066
  } else {
2810
3067
  jobs++;
3068
+ /**
3069
+ * @param {(WebpackError | null)=} err err
3070
+ * @param {string=} entry entry
3071
+ * @returns {void}
3072
+ */
2811
3073
  const callback = (err, entry) => {
2812
3074
  if (err) return invalidWithError(path, err);
2813
- if (!checkHash(path, entry, hash)) {
3075
+ if (!checkHash(path, /** @type {string} */ (entry), hash)) {
2814
3076
  invalid();
2815
3077
  } else {
2816
3078
  jobDone();
@@ -2824,14 +3086,16 @@ class FileSystemInfo {
2824
3086
  }
2825
3087
  };
2826
3088
  if (snapshot.hasContextHashes()) {
2827
- const { contextHashes } = snapshot;
3089
+ const contextHashes =
3090
+ /** @type {ContextHashes} */
3091
+ (snapshot.contextHashes);
2828
3092
  this._statTestedEntries += contextHashes.size;
2829
3093
  for (const [path, hash] of contextHashes) {
2830
3094
  processContextHashSnapshot(path, hash);
2831
3095
  }
2832
3096
  }
2833
3097
  if (snapshot.hasContextTshs()) {
2834
- const { contextTshs } = snapshot;
3098
+ const contextTshs = /** @type {ContextTshs} */ (snapshot.contextTshs);
2835
3099
  this._statTestedEntries += contextTshs.size;
2836
3100
  for (const [path, tsh] of contextTshs) {
2837
3101
  if (typeof tsh === "string") {
@@ -2844,25 +3108,46 @@ class FileSystemInfo {
2844
3108
  cache !== undefined &&
2845
3109
  (resolved = getResolvedTimestamp(cache)) !== undefined
2846
3110
  ) {
2847
- if (!checkContext(path, resolved, tsh, false)) {
3111
+ if (
3112
+ !checkContext(
3113
+ path,
3114
+ /** @type {ResolvedContextFileSystemInfoEntry | null} */
3115
+ (resolved),
3116
+ tsh,
3117
+ false
3118
+ )
3119
+ ) {
2848
3120
  processContextHashSnapshot(path, tsh && tsh.hash);
2849
3121
  }
2850
3122
  } else {
2851
3123
  jobs++;
2852
3124
  /**
2853
- * @param {Error=} err error
2854
- * @param {ResolvedContextFileSystemInfoEntry=} entry entry
3125
+ * @param {(WebpackError | null)=} err error
3126
+ * @param {(ResolvedContextFileSystemInfoEntry | "ignore" | null)=} entry entry
2855
3127
  * @returns {void}
2856
3128
  */
2857
3129
  const callback = (err, entry) => {
2858
3130
  if (err) return invalidWithError(path, err);
2859
- if (!checkContext(path, entry, tsh, false)) {
3131
+ if (
3132
+ !checkContext(
3133
+ path,
3134
+ // TODO: test with `"ignore"`
3135
+ /** @type {ResolvedContextFileSystemInfoEntry | null} */
3136
+ (entry),
3137
+ tsh,
3138
+ false
3139
+ )
3140
+ ) {
2860
3141
  processContextHashSnapshot(path, tsh && tsh.hash);
2861
3142
  }
2862
3143
  jobDone();
2863
3144
  };
2864
3145
  if (cache !== undefined) {
2865
- this._resolveContextTimestamp(cache, callback);
3146
+ this._resolveContextTimestamp(
3147
+ /** @type {ContextFileSystemInfoEntry} */
3148
+ (cache),
3149
+ callback
3150
+ );
2866
3151
  } else {
2867
3152
  this.getContextTimestamp(path, callback);
2868
3153
  }
@@ -2871,7 +3156,9 @@ class FileSystemInfo {
2871
3156
  }
2872
3157
  }
2873
3158
  if (snapshot.hasMissingExistence()) {
2874
- const { missingExistence } = snapshot;
3159
+ const missingExistence =
3160
+ /** @type {MissingExistence} */
3161
+ (snapshot.missingExistence);
2875
3162
  this._statTestedEntries += missingExistence.size;
2876
3163
  for (const [path, existence] of missingExistence) {
2877
3164
  const cache = this._fileTimestamps.get(path);
@@ -2897,7 +3184,9 @@ class FileSystemInfo {
2897
3184
  }
2898
3185
  }
2899
3186
  if (snapshot.hasManagedItemInfo()) {
2900
- const { managedItemInfo } = snapshot;
3187
+ const managedItemInfo =
3188
+ /** @type {ManagedItemInfo} */
3189
+ (snapshot.managedItemInfo);
2901
3190
  this._statTestedEntries += managedItemInfo.size;
2902
3191
  for (const [path, info] of managedItemInfo) {
2903
3192
  const cache = this._managedItems.get(path);
@@ -2910,7 +3199,7 @@ class FileSystemInfo {
2910
3199
  jobs++;
2911
3200
  this.managedItemQueue.add(path, (err, entry) => {
2912
3201
  if (err) return invalidWithError(path, err);
2913
- if (!checkHash(path, entry, info)) {
3202
+ if (!checkHash(path, /** @type {string} */ (entry), info)) {
2914
3203
  invalid();
2915
3204
  } else {
2916
3205
  jobDone();
@@ -2932,17 +3221,21 @@ class FileSystemInfo {
2932
3221
  }
2933
3222
  }
2934
3223
 
3224
+ /**
3225
+ * @type {Processor<string, FileSystemInfoEntry>}
3226
+ * @private
3227
+ */
2935
3228
  _readFileTimestamp(path, callback) {
2936
- this.fs.stat(path, (err, stat) => {
3229
+ this.fs.stat(path, (err, _stat) => {
2937
3230
  if (err) {
2938
3231
  if (err.code === "ENOENT") {
2939
3232
  this._fileTimestamps.set(path, null);
2940
3233
  this._cachedDeprecatedFileTimestamps = undefined;
2941
3234
  return callback(null, null);
2942
3235
  }
2943
- return callback(err);
3236
+ return callback(/** @type {WebpackError} */ (err));
2944
3237
  }
2945
-
3238
+ const stat = /** @type {IStats} */ (_stat);
2946
3239
  let ts;
2947
3240
  if (stat.isDirectory()) {
2948
3241
  ts = {
@@ -2950,7 +3243,7 @@ class FileSystemInfo {
2950
3243
  timestamp: undefined
2951
3244
  };
2952
3245
  } else {
2953
- const mtime = +stat.mtime;
3246
+ const mtime = Number(stat.mtime);
2954
3247
 
2955
3248
  if (mtime) applyMtime(mtime);
2956
3249
 
@@ -2967,6 +3260,10 @@ class FileSystemInfo {
2967
3260
  });
2968
3261
  }
2969
3262
 
3263
+ /**
3264
+ * @type {Processor<string, string>}
3265
+ * @private
3266
+ */
2970
3267
  _readFileHash(path, callback) {
2971
3268
  this.fs.readFile(path, (err, content) => {
2972
3269
  if (err) {
@@ -2979,11 +3276,12 @@ class FileSystemInfo {
2979
3276
  return callback(null, null);
2980
3277
  }
2981
3278
  if (err.code === "ERR_FS_FILE_TOO_LARGE") {
2982
- this.logger.warn(`Ignoring ${path} for hashing as it's very large`);
3279
+ /** @type {Logger} */
3280
+ (this.logger).warn(`Ignoring ${path} for hashing as it's very large`);
2983
3281
  this._fileHashes.set(path, "too large");
2984
3282
  return callback(null, "too large");
2985
3283
  }
2986
- return callback(err);
3284
+ return callback(/** @type {WebpackError} */ (err));
2987
3285
  }
2988
3286
 
2989
3287
  const hash = createHash(this._hashFunction);
@@ -2998,45 +3296,54 @@ class FileSystemInfo {
2998
3296
  });
2999
3297
  }
3000
3298
 
3299
+ /**
3300
+ * @param {string} path path
3301
+ * @param {function(WebpackError | null, TimestampAndHash=) : void} callback callback
3302
+ * @private
3303
+ */
3001
3304
  _getFileTimestampAndHash(path, callback) {
3305
+ /**
3306
+ * @param {string} hash hash
3307
+ * @returns {void}
3308
+ */
3002
3309
  const continueWithHash = hash => {
3003
3310
  const cache = this._fileTimestamps.get(path);
3004
3311
  if (cache !== undefined) {
3005
3312
  if (cache !== "ignore") {
3313
+ /** @type {TimestampAndHash} */
3006
3314
  const result = {
3007
- ...cache,
3315
+ .../** @type {FileSystemInfoEntry} */ (cache),
3008
3316
  hash
3009
3317
  };
3010
3318
  this._fileTshs.set(path, result);
3011
3319
  return callback(null, result);
3012
- } else {
3013
- this._fileTshs.set(path, hash);
3014
- return callback(null, hash);
3015
3320
  }
3016
- } else {
3017
- this.fileTimestampQueue.add(path, (err, entry) => {
3018
- if (err) {
3019
- return callback(err);
3020
- }
3021
- const result = {
3022
- ...entry,
3023
- hash
3024
- };
3025
- this._fileTshs.set(path, result);
3026
- return callback(null, result);
3027
- });
3321
+ this._fileTshs.set(path, hash);
3322
+ return callback(null, /** @type {TODO} */ (hash));
3028
3323
  }
3324
+ this.fileTimestampQueue.add(path, (err, entry) => {
3325
+ if (err) {
3326
+ return callback(err);
3327
+ }
3328
+ /** @type {TimestampAndHash} */
3329
+ const result = {
3330
+ .../** @type {FileSystemInfoEntry} */ (entry),
3331
+ hash
3332
+ };
3333
+ this._fileTshs.set(path, result);
3334
+ return callback(null, result);
3335
+ });
3029
3336
  };
3030
3337
 
3031
3338
  const cache = this._fileHashes.get(path);
3032
3339
  if (cache !== undefined) {
3033
- continueWithHash(cache);
3340
+ continueWithHash(/** @type {string} */ (cache));
3034
3341
  } else {
3035
3342
  this.fileHashQueue.add(path, (err, entry) => {
3036
3343
  if (err) {
3037
3344
  return callback(err);
3038
3345
  }
3039
- continueWithHash(entry);
3346
+ continueWithHash(/** @type {string} */ (entry));
3040
3347
  });
3041
3348
  }
3042
3349
  }
@@ -3048,9 +3355,9 @@ class FileSystemInfo {
3048
3355
  * @param {string} options.path path
3049
3356
  * @param {function(string): ItemType} options.fromImmutablePath called when context item is an immutable path
3050
3357
  * @param {function(string): ItemType} options.fromManagedItem called when context item is a managed path
3051
- * @param {function(string, string, function(Error=, ItemType=): void): void} options.fromSymlink called when context item is a symlink
3052
- * @param {function(string, IStats, function(Error=, ItemType=): void): void} options.fromFile called when context item is a file
3053
- * @param {function(string, IStats, function(Error=, ItemType=): void): void} options.fromDirectory called when context item is a directory
3358
+ * @param {function(string, string, function((WebpackError | null)=, ItemType=): void): void} options.fromSymlink called when context item is a symlink
3359
+ * @param {function(string, IStats, function((WebpackError | null)=, (ItemType | null)=): void): void} options.fromFile called when context item is a file
3360
+ * @param {function(string, IStats, function((WebpackError | null)=, ItemType=): void): void} options.fromDirectory called when context item is a directory
3054
3361
  * @param {function(string[], ItemType[]): T} options.reduce called from all context items
3055
3362
  * @param {function((Error | null)=, (T | null)=): void} callback callback
3056
3363
  */
@@ -3101,7 +3408,10 @@ class FileSystemInfo {
3101
3408
  // construct timestampHash from managed info
3102
3409
  return this.managedItemQueue.add(managedItem, (err, info) => {
3103
3410
  if (err) return callback(err);
3104
- return callback(null, fromManagedItem(info));
3411
+ return callback(
3412
+ null,
3413
+ fromManagedItem(/** @type {string} */ (info))
3414
+ );
3105
3415
  });
3106
3416
  }
3107
3417
  }
@@ -3113,15 +3423,20 @@ class FileSystemInfo {
3113
3423
  // construct timestampHash from managed info
3114
3424
  return this.managedItemQueue.add(managedItem, (err, info) => {
3115
3425
  if (err) return callback(err);
3116
- return callback(null, fromManagedItem(info));
3426
+ return callback(
3427
+ null,
3428
+ fromManagedItem(/** @type {string} */ (info))
3429
+ );
3117
3430
  });
3118
3431
  }
3119
3432
  }
3120
3433
  }
3121
3434
 
3122
- lstatReadlinkAbsolute(this.fs, child, (err, stat) => {
3435
+ lstatReadlinkAbsolute(this.fs, child, (err, _stat) => {
3123
3436
  if (err) return callback(err);
3124
3437
 
3438
+ const stat = /** @type {IStats | string} */ (_stat);
3439
+
3125
3440
  if (typeof stat === "string") {
3126
3441
  return fromSymlink(child, stat, callback);
3127
3442
  }
@@ -3137,27 +3452,37 @@ class FileSystemInfo {
3137
3452
  },
3138
3453
  (err, results) => {
3139
3454
  if (err) return callback(err);
3140
- const result = reduce(files, results);
3455
+ const result = reduce(files, /** @type {ItemType[]} */ (results));
3141
3456
  callback(null, result);
3142
3457
  }
3143
3458
  );
3144
3459
  });
3145
3460
  }
3146
3461
 
3462
+ /**
3463
+ * @type {Processor<string, ContextFileSystemInfoEntry>}
3464
+ * @private
3465
+ */
3147
3466
  _readContextTimestamp(path, callback) {
3148
3467
  this._readContext(
3149
3468
  {
3150
3469
  path,
3151
- fromImmutablePath: () => null,
3470
+ fromImmutablePath: () =>
3471
+ /** @type {ContextFileSystemInfoEntry | FileSystemInfoEntry | "ignore" | null} */
3472
+ (null),
3152
3473
  fromManagedItem: info => ({
3153
3474
  safeTime: 0,
3154
3475
  timestampHash: info
3155
3476
  }),
3156
3477
  fromSymlink: (file, target, callback) => {
3157
- callback(null, {
3158
- timestampHash: target,
3159
- symlinks: new Set([target])
3160
- });
3478
+ callback(
3479
+ null,
3480
+ /** @type {ContextFileSystemInfoEntry} */
3481
+ ({
3482
+ timestampHash: target,
3483
+ symlinks: new Set([target])
3484
+ })
3485
+ );
3161
3486
  },
3162
3487
  fromFile: (file, stat, callback) => {
3163
3488
  // Prefer the cached value over our new stat to report consistent results
@@ -3165,10 +3490,11 @@ class FileSystemInfo {
3165
3490
  if (cache !== undefined)
3166
3491
  return callback(null, cache === "ignore" ? null : cache);
3167
3492
 
3168
- const mtime = +stat.mtime;
3493
+ const mtime = Number(stat.mtime);
3169
3494
 
3170
3495
  if (mtime) applyMtime(mtime);
3171
3496
 
3497
+ /** @type {FileSystemInfoEntry} */
3172
3498
  const ts = {
3173
3499
  safeTime: mtime ? mtime + FS_ACCURACY : Infinity,
3174
3500
  timestamp: mtime
@@ -3186,27 +3512,42 @@ class FileSystemInfo {
3186
3512
  });
3187
3513
  },
3188
3514
  reduce: (files, tsEntries) => {
3189
- let symlinks = undefined;
3515
+ let symlinks;
3190
3516
 
3191
3517
  const hash = createHash(this._hashFunction);
3192
3518
 
3193
3519
  for (const file of files) hash.update(file);
3194
3520
  let safeTime = 0;
3195
- for (const entry of tsEntries) {
3196
- if (!entry) {
3521
+ for (const _e of tsEntries) {
3522
+ if (!_e) {
3197
3523
  hash.update("n");
3198
3524
  continue;
3199
3525
  }
3200
- if (entry.timestamp) {
3526
+ const entry =
3527
+ /** @type {FileSystemInfoEntry | ContextFileSystemInfoEntry} */
3528
+ (_e);
3529
+ if (/** @type {FileSystemInfoEntry} */ (entry).timestamp) {
3201
3530
  hash.update("f");
3202
- hash.update(`${entry.timestamp}`);
3203
- } else if (entry.timestampHash) {
3531
+ hash.update(
3532
+ `${/** @type {FileSystemInfoEntry} */ (entry).timestamp}`
3533
+ );
3534
+ } else if (
3535
+ /** @type {ContextFileSystemInfoEntry} */ (entry).timestampHash
3536
+ ) {
3204
3537
  hash.update("d");
3205
- hash.update(`${entry.timestampHash}`);
3538
+ hash.update(
3539
+ `${/** @type {ContextFileSystemInfoEntry} */ (entry).timestampHash}`
3540
+ );
3206
3541
  }
3207
- if (entry.symlinks !== undefined) {
3542
+ if (
3543
+ /** @type {ContextFileSystemInfoEntry} */
3544
+ (entry).symlinks !== undefined
3545
+ ) {
3208
3546
  if (symlinks === undefined) symlinks = new Set();
3209
- addAll(entry.symlinks, symlinks);
3547
+ addAll(
3548
+ /** @type {ContextFileSystemInfoEntry} */ (entry).symlinks,
3549
+ symlinks
3550
+ );
3210
3551
  }
3211
3552
  if (entry.safeTime) {
3212
3553
  safeTime = Math.max(safeTime, entry.safeTime);
@@ -3214,7 +3555,7 @@ class FileSystemInfo {
3214
3555
  }
3215
3556
 
3216
3557
  const digest = /** @type {string} */ (hash.digest("hex"));
3217
-
3558
+ /** @type {ContextFileSystemInfoEntry} */
3218
3559
  const result = {
3219
3560
  safeTime,
3220
3561
  timestampHash: digest
@@ -3224,7 +3565,7 @@ class FileSystemInfo {
3224
3565
  }
3225
3566
  },
3226
3567
  (err, result) => {
3227
- if (err) return callback(err);
3568
+ if (err) return callback(/** @type {WebpackError} */ (err));
3228
3569
  this._contextTimestamps.set(path, result);
3229
3570
  this._cachedDeprecatedContextTimestamps = undefined;
3230
3571
 
@@ -3235,7 +3576,7 @@ class FileSystemInfo {
3235
3576
 
3236
3577
  /**
3237
3578
  * @param {ContextFileSystemInfoEntry} entry entry
3238
- * @param {function((Error | null)=, ResolvedContextFileSystemInfoEntry=): void} callback callback
3579
+ * @param {function((WebpackError | null)=, (ResolvedContextFileSystemInfoEntry | "ignore" | null)=): void} callback callback
3239
3580
  * @returns {void}
3240
3581
  */
3241
3582
  _resolveContextTimestamp(entry, callback) {
@@ -3243,13 +3584,13 @@ class FileSystemInfo {
3243
3584
  const hashes = [];
3244
3585
  let safeTime = 0;
3245
3586
  processAsyncTree(
3246
- entry.symlinks,
3587
+ /** @type {NonNullable<ContextHash["symlinks"]>} */ (entry.symlinks),
3247
3588
  10,
3248
3589
  (target, push, callback) => {
3249
3590
  this._getUnresolvedContextTimestamp(target, (err, entry) => {
3250
3591
  if (err) return callback(err);
3251
3592
  if (entry && entry !== "ignore") {
3252
- hashes.push(entry.timestampHash);
3593
+ hashes.push(/** @type {string} */ (entry.timestampHash));
3253
3594
  if (entry.safeTime) {
3254
3595
  safeTime = Math.max(safeTime, entry.safeTime);
3255
3596
  }
@@ -3261,9 +3602,9 @@ class FileSystemInfo {
3261
3602
  });
3262
3603
  },
3263
3604
  err => {
3264
- if (err) return callback(err);
3605
+ if (err) return callback(/** @type {WebpackError} */ (err));
3265
3606
  const hash = createHash(this._hashFunction);
3266
- hash.update(entry.timestampHash);
3607
+ hash.update(/** @type {string} */ (entry.timestampHash));
3267
3608
  if (entry.safeTime) {
3268
3609
  safeTime = Math.max(safeTime, entry.safeTime);
3269
3610
  }
@@ -3282,17 +3623,26 @@ class FileSystemInfo {
3282
3623
  );
3283
3624
  }
3284
3625
 
3626
+ /**
3627
+ * @type {Processor<string, ContextHash>}
3628
+ * @private
3629
+ */
3285
3630
  _readContextHash(path, callback) {
3286
3631
  this._readContext(
3287
3632
  {
3288
3633
  path,
3289
- fromImmutablePath: () => "",
3634
+ fromImmutablePath: () =>
3635
+ /** @type {ContextHash} */ (/** @type {unknown} */ ("")),
3290
3636
  fromManagedItem: info => info || "",
3291
3637
  fromSymlink: (file, target, callback) => {
3292
- callback(null, {
3293
- hash: target,
3294
- symlinks: new Set([target])
3295
- });
3638
+ callback(
3639
+ null,
3640
+ /** @type {ContextHash} */
3641
+ ({
3642
+ hash: target,
3643
+ symlinks: new Set([target])
3644
+ })
3645
+ );
3296
3646
  },
3297
3647
  fromFile: (file, stat, callback) =>
3298
3648
  this.getFileHash(file, (err, hash) => {
@@ -3311,7 +3661,7 @@ class FileSystemInfo {
3311
3661
  * @returns {ContextHash} reduced hash
3312
3662
  */
3313
3663
  reduce: (files, fileHashes) => {
3314
- let symlinks = undefined;
3664
+ let symlinks;
3315
3665
  const hash = createHash(this._hashFunction);
3316
3666
 
3317
3667
  for (const file of files) hash.update(file);
@@ -3327,6 +3677,7 @@ class FileSystemInfo {
3327
3677
  }
3328
3678
  }
3329
3679
 
3680
+ /** @type {ContextHash} */
3330
3681
  const result = {
3331
3682
  hash: /** @type {string} */ (hash.digest("hex"))
3332
3683
  };
@@ -3334,8 +3685,9 @@ class FileSystemInfo {
3334
3685
  return result;
3335
3686
  }
3336
3687
  },
3337
- (err, result) => {
3338
- if (err) return callback(err);
3688
+ (err, _result) => {
3689
+ if (err) return callback(/** @type {WebpackError} */ (err));
3690
+ const result = /** @type {ContextHash} */ (_result);
3339
3691
  this._contextHashes.set(path, result);
3340
3692
  return callback(null, result);
3341
3693
  }
@@ -3344,14 +3696,14 @@ class FileSystemInfo {
3344
3696
 
3345
3697
  /**
3346
3698
  * @param {ContextHash} entry context hash
3347
- * @param {function((WebpackError | null)=, string=): void} callback callback
3699
+ * @param {function(WebpackError | null, string=): void} callback callback
3348
3700
  * @returns {void}
3349
3701
  */
3350
3702
  _resolveContextHash(entry, callback) {
3351
3703
  /** @type {string[]} */
3352
3704
  const hashes = [];
3353
3705
  processAsyncTree(
3354
- entry.symlinks,
3706
+ /** @type {NonNullable<ContextHash["symlinks"]>} */ (entry.symlinks),
3355
3707
  10,
3356
3708
  (target, push, callback) => {
3357
3709
  this._getUnresolvedContextHash(target, (err, hash) => {
@@ -3381,15 +3733,19 @@ class FileSystemInfo {
3381
3733
  );
3382
3734
  }
3383
3735
 
3736
+ /**
3737
+ * @type {Processor<string, ContextTimestampAndHash>}
3738
+ * @private
3739
+ */
3384
3740
  _readContextTimestampAndHash(path, callback) {
3741
+ /**
3742
+ * @param {ContextFileSystemInfoEntry | "ignore" | null} timestamp timestamp
3743
+ * @param {ContextHash} hash hash
3744
+ */
3385
3745
  const finalize = (timestamp, hash) => {
3386
3746
  const result =
3387
- timestamp === "ignore"
3388
- ? hash
3389
- : {
3390
- ...timestamp,
3391
- ...hash
3392
- };
3747
+ /** @type {ContextTimestampAndHash} */
3748
+ (timestamp === "ignore" ? hash : { ...timestamp, ...hash });
3393
3749
  this._contextTshs.set(path, result);
3394
3750
  callback(null, result);
3395
3751
  };
@@ -3401,107 +3757,111 @@ class FileSystemInfo {
3401
3757
  } else {
3402
3758
  this.contextTimestampQueue.add(path, (err, entry) => {
3403
3759
  if (err) return callback(err);
3404
- finalize(entry, cachedHash);
3760
+ finalize(
3761
+ /** @type {ContextFileSystemInfoEntry} */
3762
+ (entry),
3763
+ cachedHash
3764
+ );
3405
3765
  });
3406
3766
  }
3767
+ } else if (cachedTimestamp !== undefined) {
3768
+ this.contextHashQueue.add(path, (err, entry) => {
3769
+ if (err) return callback(err);
3770
+ finalize(cachedTimestamp, /** @type {ContextHash} */ (entry));
3771
+ });
3407
3772
  } else {
3408
- if (cachedTimestamp !== undefined) {
3409
- this.contextHashQueue.add(path, (err, entry) => {
3410
- if (err) return callback(err);
3411
- finalize(cachedTimestamp, entry);
3412
- });
3413
- } else {
3414
- this._readContext(
3415
- {
3416
- path,
3417
- fromImmutablePath: () => null,
3418
- fromManagedItem: info => ({
3419
- safeTime: 0,
3420
- timestampHash: info,
3421
- hash: info || ""
3422
- }),
3423
- fromSymlink: (file, target, callback) => {
3424
- callback(null, {
3425
- timestampHash: target,
3426
- hash: target,
3427
- symlinks: new Set([target])
3428
- });
3429
- },
3430
- fromFile: (file, stat, callback) => {
3431
- this._getFileTimestampAndHash(file, callback);
3432
- },
3433
- fromDirectory: (directory, stat, callback) => {
3434
- this.contextTshQueue.increaseParallelism();
3435
- this.contextTshQueue.add(directory, (err, result) => {
3436
- this.contextTshQueue.decreaseParallelism();
3437
- callback(err, result);
3438
- });
3439
- },
3440
- /**
3441
- * @param {string[]} files files
3442
- * @param {(Partial<TimestampAndHash> & Partial<ContextTimestampAndHash> | string | null)[]} results results
3443
- * @returns {ContextTimestampAndHash} tsh
3444
- */
3445
- reduce: (files, results) => {
3446
- let symlinks = undefined;
3773
+ this._readContext(
3774
+ {
3775
+ path,
3776
+ fromImmutablePath: () => null,
3777
+ fromManagedItem: info => ({
3778
+ safeTime: 0,
3779
+ timestampHash: info,
3780
+ hash: info || ""
3781
+ }),
3782
+ fromSymlink: (file, target, callback) => {
3783
+ callback(null, {
3784
+ timestampHash: target,
3785
+ hash: target,
3786
+ symlinks: new Set([target])
3787
+ });
3788
+ },
3789
+ fromFile: (file, stat, callback) => {
3790
+ this._getFileTimestampAndHash(file, callback);
3791
+ },
3792
+ fromDirectory: (directory, stat, callback) => {
3793
+ this.contextTshQueue.increaseParallelism();
3794
+ this.contextTshQueue.add(directory, (err, result) => {
3795
+ this.contextTshQueue.decreaseParallelism();
3796
+ callback(err, result);
3797
+ });
3798
+ },
3799
+ /**
3800
+ * @param {string[]} files files
3801
+ * @param {(Partial<TimestampAndHash> & Partial<ContextTimestampAndHash> | string | null)[]} results results
3802
+ * @returns {ContextTimestampAndHash} tsh
3803
+ */
3804
+ reduce: (files, results) => {
3805
+ let symlinks;
3447
3806
 
3448
- const tsHash = createHash(this._hashFunction);
3449
- const hash = createHash(this._hashFunction);
3807
+ const tsHash = createHash(this._hashFunction);
3808
+ const hash = createHash(this._hashFunction);
3450
3809
 
3451
- for (const file of files) {
3452
- tsHash.update(file);
3453
- hash.update(file);
3810
+ for (const file of files) {
3811
+ tsHash.update(file);
3812
+ hash.update(file);
3813
+ }
3814
+ let safeTime = 0;
3815
+ for (const entry of results) {
3816
+ if (!entry) {
3817
+ tsHash.update("n");
3818
+ continue;
3454
3819
  }
3455
- let safeTime = 0;
3456
- for (const entry of results) {
3457
- if (!entry) {
3458
- tsHash.update("n");
3459
- continue;
3460
- }
3461
- if (typeof entry === "string") {
3462
- tsHash.update("n");
3463
- hash.update(entry);
3464
- continue;
3465
- }
3466
- if (entry.timestamp) {
3467
- tsHash.update("f");
3468
- tsHash.update(`${entry.timestamp}`);
3469
- } else if (entry.timestampHash) {
3470
- tsHash.update("d");
3471
- tsHash.update(`${entry.timestampHash}`);
3472
- }
3473
- if (entry.symlinks !== undefined) {
3474
- if (symlinks === undefined) symlinks = new Set();
3475
- addAll(entry.symlinks, symlinks);
3476
- }
3477
- if (entry.safeTime) {
3478
- safeTime = Math.max(safeTime, entry.safeTime);
3479
- }
3480
- hash.update(entry.hash);
3820
+ if (typeof entry === "string") {
3821
+ tsHash.update("n");
3822
+ hash.update(entry);
3823
+ continue;
3481
3824
  }
3482
-
3483
- const result = {
3484
- safeTime,
3485
- timestampHash: /** @type {string} */ (tsHash.digest("hex")),
3486
- hash: /** @type {string} */ (hash.digest("hex"))
3487
- };
3488
- if (symlinks) result.symlinks = symlinks;
3489
- return result;
3825
+ if (entry.timestamp) {
3826
+ tsHash.update("f");
3827
+ tsHash.update(`${entry.timestamp}`);
3828
+ } else if (entry.timestampHash) {
3829
+ tsHash.update("d");
3830
+ tsHash.update(`${entry.timestampHash}`);
3831
+ }
3832
+ if (entry.symlinks !== undefined) {
3833
+ if (symlinks === undefined) symlinks = new Set();
3834
+ addAll(entry.symlinks, symlinks);
3835
+ }
3836
+ if (entry.safeTime) {
3837
+ safeTime = Math.max(safeTime, entry.safeTime);
3838
+ }
3839
+ hash.update(/** @type {string} */ (entry.hash));
3490
3840
  }
3491
- },
3492
- (err, result) => {
3493
- if (err) return callback(err);
3494
- this._contextTshs.set(path, result);
3495
- return callback(null, result);
3841
+
3842
+ /** @type {ContextTimestampAndHash} */
3843
+ const result = {
3844
+ safeTime,
3845
+ timestampHash: /** @type {string} */ (tsHash.digest("hex")),
3846
+ hash: /** @type {string} */ (hash.digest("hex"))
3847
+ };
3848
+ if (symlinks) result.symlinks = symlinks;
3849
+ return result;
3496
3850
  }
3497
- );
3498
- }
3851
+ },
3852
+ (err, _result) => {
3853
+ if (err) return callback(/** @type {WebpackError} */ (err));
3854
+ const result = /** @type {ContextTimestampAndHash} */ (_result);
3855
+ this._contextTshs.set(path, result);
3856
+ return callback(null, result);
3857
+ }
3858
+ );
3499
3859
  }
3500
3860
  }
3501
3861
 
3502
3862
  /**
3503
3863
  * @param {ContextTimestampAndHash} entry entry
3504
- * @param {function((Error | null)=, ResolvedContextTimestampAndHash=): void} callback callback
3864
+ * @param {ProcessorCallback<ResolvedContextTimestampAndHash>} callback callback
3505
3865
  * @returns {void}
3506
3866
  */
3507
3867
  _resolveContextTsh(entry, callback) {
@@ -3511,7 +3871,7 @@ class FileSystemInfo {
3511
3871
  const tsHashes = [];
3512
3872
  let safeTime = 0;
3513
3873
  processAsyncTree(
3514
- entry.symlinks,
3874
+ /** @type {NonNullable<ContextHash["symlinks"]>} */ (entry.symlinks),
3515
3875
  10,
3516
3876
  (target, push, callback) => {
3517
3877
  this._getUnresolvedContextTsh(target, (err, entry) => {
@@ -3530,7 +3890,7 @@ class FileSystemInfo {
3530
3890
  });
3531
3891
  },
3532
3892
  err => {
3533
- if (err) return callback(err);
3893
+ if (err) return callback(/** @type {WebpackError} */ (err));
3534
3894
  const hash = createHash(this._hashFunction);
3535
3895
  const tsHash = createHash(this._hashFunction);
3536
3896
  hash.update(entry.hash);
@@ -3558,13 +3918,17 @@ class FileSystemInfo {
3558
3918
  );
3559
3919
  }
3560
3920
 
3921
+ /**
3922
+ * @type {Processor<string, Set<string>>}
3923
+ * @private
3924
+ */
3561
3925
  _getManagedItemDirectoryInfo(path, callback) {
3562
3926
  this.fs.readdir(path, (err, elements) => {
3563
3927
  if (err) {
3564
3928
  if (err.code === "ENOENT" || err.code === "ENOTDIR") {
3565
3929
  return callback(null, EMPTY_SET);
3566
3930
  }
3567
- return callback(err);
3931
+ return callback(/** @type {WebpackError} */ (err));
3568
3932
  }
3569
3933
  const set = new Set(
3570
3934
  /** @type {string[]} */ (elements).map(element =>
@@ -3575,13 +3939,17 @@ class FileSystemInfo {
3575
3939
  });
3576
3940
  }
3577
3941
 
3942
+ /**
3943
+ * @type {Processor<string, string>}
3944
+ * @private
3945
+ */
3578
3946
  _getManagedItemInfo(path, callback) {
3579
3947
  const dir = dirname(this.fs, path);
3580
3948
  this.managedItemDirectoryQueue.add(dir, (err, elements) => {
3581
3949
  if (err) {
3582
3950
  return callback(err);
3583
3951
  }
3584
- if (!elements.has(path)) {
3952
+ if (!(/** @type {Set<string>} */ (elements).has(path))) {
3585
3953
  // file or directory doesn't exist
3586
3954
  this._managedItems.set(path, "*missing");
3587
3955
  return callback(null, "*missing");
@@ -3606,28 +3974,29 @@ class FileSystemInfo {
3606
3974
  this.fs.readdir(path, (err, elements) => {
3607
3975
  if (
3608
3976
  !err &&
3609
- elements.length === 1 &&
3610
- elements[0] === "node_modules"
3977
+ /** @type {string[]} */ (elements).length === 1 &&
3978
+ /** @type {string[]} */ (elements)[0] === "node_modules"
3611
3979
  ) {
3612
3980
  // This is only a grouping folder e.g. used by yarn
3613
3981
  // we are only interested in existence of this special directory
3614
3982
  this._managedItems.set(path, "*nested");
3615
3983
  return callback(null, "*nested");
3616
3984
  }
3617
- this.logger.warn(
3985
+ /** @type {Logger} */
3986
+ (this.logger).warn(
3618
3987
  `Managed item ${path} isn't a directory or doesn't contain a package.json (see snapshot.managedPaths option)`
3619
3988
  );
3620
3989
  return callback();
3621
3990
  });
3622
3991
  return;
3623
3992
  }
3624
- return callback(err);
3993
+ return callback(/** @type {WebpackError} */ (err));
3625
3994
  }
3626
3995
  let data;
3627
3996
  try {
3628
3997
  data = JSON.parse(/** @type {Buffer} */ (content).toString("utf-8"));
3629
- } catch (e) {
3630
- return callback(e);
3998
+ } catch (parseErr) {
3999
+ return callback(/** @type {WebpackError} */ (parseErr));
3631
4000
  }
3632
4001
  if (!data.name) {
3633
4002
  /** @type {Logger} */