@plaudit/webpack-extensions 4.0.0-rc.1 → 4.0.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 (242) hide show
  1. package/CHANGELOG.md +5 -1
  2. package/dist/api/asset-information-emission.d.ts +74 -0
  3. package/dist/api/asset-information-emission.d.ts.map +1 -0
  4. package/dist/api/asset-information-emission.js +398 -0
  5. package/dist/api/asset-information-emission.js.map +1 -0
  6. package/dist/api/configuration.d.ts +102 -0
  7. package/dist/api/configuration.d.ts.map +1 -0
  8. package/dist/api/configuration.js +83 -0
  9. package/dist/api/configuration.js.map +1 -0
  10. package/dist/api/coordinatable-emitter.d.ts +27 -0
  11. package/dist/api/coordinatable-emitter.d.ts.map +1 -0
  12. package/dist/api/coordinatable-emitter.js +20 -0
  13. package/dist/api/coordinatable-emitter.js.map +1 -0
  14. package/dist/api/entries/dependencies.d.ts +69 -0
  15. package/dist/api/entries/dependencies.d.ts.map +1 -0
  16. package/dist/api/entries/dependencies.js +61 -0
  17. package/dist/api/entries/dependencies.js.map +1 -0
  18. package/dist/api/entries/flag-logic.d.ts +37 -0
  19. package/dist/api/entries/flag-logic.d.ts.map +1 -0
  20. package/dist/api/entries/flag-logic.js +110 -0
  21. package/dist/api/entries/flag-logic.js.map +1 -0
  22. package/dist/api/entries/identifiers.d.ts +84 -0
  23. package/dist/api/entries/identifiers.d.ts.map +1 -0
  24. package/dist/api/entries/identifiers.js +590 -0
  25. package/dist/api/entries/identifiers.js.map +1 -0
  26. package/dist/api/entries/index.d.ts +6 -0
  27. package/dist/api/entries/index.d.ts.map +1 -0
  28. package/dist/api/entries/index.js +22 -0
  29. package/dist/api/entries/index.js.map +1 -0
  30. package/dist/api/entries/locations.d.ts +135 -0
  31. package/dist/api/entries/locations.d.ts.map +1 -0
  32. package/dist/api/entries/locations.js +174 -0
  33. package/dist/api/entries/locations.js.map +1 -0
  34. package/dist/api/entries/manager.d.ts +12 -0
  35. package/dist/api/entries/manager.d.ts.map +1 -0
  36. package/dist/api/entries/manager.js +35 -0
  37. package/dist/api/entries/manager.js.map +1 -0
  38. package/dist/api/handle-derivation.d.ts +32 -0
  39. package/dist/api/handle-derivation.d.ts.map +1 -0
  40. package/dist/api/handle-derivation.js +77 -0
  41. package/dist/api/handle-derivation.js.map +1 -0
  42. package/dist/api/index.d.ts +7 -0
  43. package/dist/api/index.d.ts.map +1 -0
  44. package/dist/api/index.js +23 -0
  45. package/dist/api/index.js.map +1 -0
  46. package/dist/api/shared-types.d.ts +86 -0
  47. package/dist/api/shared-types.d.ts.map +1 -0
  48. package/dist/api/shared-types.js +3 -0
  49. package/dist/api/shared-types.js.map +1 -0
  50. package/dist/internal-utils/auto-registering-plugins-loader.d.ts +3 -0
  51. package/dist/internal-utils/auto-registering-plugins-loader.d.ts.map +1 -0
  52. package/dist/internal-utils/auto-registering-plugins-loader.js +42 -0
  53. package/dist/internal-utils/auto-registering-plugins-loader.js.map +1 -0
  54. package/dist/internal-utils/common-config-helpers.d.ts +14 -0
  55. package/dist/internal-utils/common-config-helpers.d.ts.map +1 -0
  56. package/dist/internal-utils/common-config-helpers.js +140 -0
  57. package/dist/internal-utils/common-config-helpers.js.map +1 -0
  58. package/dist/internal-utils/entrypoint-resolution-logic.d.ts +14 -0
  59. package/dist/internal-utils/entrypoint-resolution-logic.d.ts.map +1 -0
  60. package/dist/internal-utils/entrypoint-resolution-logic.js +223 -0
  61. package/dist/internal-utils/entrypoint-resolution-logic.js.map +1 -0
  62. package/dist/internal-utils/internal-pseudo-plugin.d.ts +6 -0
  63. package/dist/internal-utils/internal-pseudo-plugin.d.ts.map +1 -0
  64. package/dist/internal-utils/internal-pseudo-plugin.js +46 -0
  65. package/dist/internal-utils/internal-pseudo-plugin.js.map +1 -0
  66. package/dist/mocks/blocks.d.ts +32 -0
  67. package/dist/mocks/blocks.d.ts.map +1 -0
  68. package/dist/mocks/blocks.js +3 -0
  69. package/dist/mocks/blocks.js.map +1 -0
  70. package/dist/mocks/index.d.ts +2 -0
  71. package/dist/mocks/index.d.ts.map +1 -0
  72. package/dist/mocks/index.js +18 -0
  73. package/dist/mocks/index.js.map +1 -0
  74. package/dist/plugins/AdditionalDependencyInjectorPlugin.d.ts +5 -0
  75. package/dist/plugins/AdditionalDependencyInjectorPlugin.d.ts.map +1 -0
  76. package/dist/plugins/AdditionalDependencyInjectorPlugin.js +59 -0
  77. package/dist/plugins/AdditionalDependencyInjectorPlugin.js.map +1 -0
  78. package/dist/plugins/MiniCSSExtractPluginErrorCleaner.d.ts +5 -0
  79. package/dist/plugins/MiniCSSExtractPluginErrorCleaner.d.ts.map +1 -0
  80. package/dist/plugins/MiniCSSExtractPluginErrorCleaner.js +16 -0
  81. package/dist/plugins/MiniCSSExtractPluginErrorCleaner.js.map +1 -0
  82. package/dist/plugins/PackageConfigSanityChecker.d.ts +5 -0
  83. package/dist/plugins/PackageConfigSanityChecker.d.ts.map +1 -0
  84. package/dist/plugins/PackageConfigSanityChecker.js +31 -0
  85. package/dist/plugins/PackageConfigSanityChecker.js.map +1 -0
  86. package/dist/plugins/RootCoordinatorPluginImpl.d.ts +56 -0
  87. package/dist/plugins/RootCoordinatorPluginImpl.d.ts.map +1 -0
  88. package/dist/plugins/RootCoordinatorPluginImpl.js +767 -0
  89. package/dist/plugins/RootCoordinatorPluginImpl.js.map +1 -0
  90. package/dist/plugins/VariablesJSMonitorPlugin.d.ts +8 -0
  91. package/dist/plugins/VariablesJSMonitorPlugin.d.ts.map +1 -0
  92. package/dist/plugins/VariablesJSMonitorPlugin.js +21 -0
  93. package/dist/plugins/VariablesJSMonitorPlugin.js.map +1 -0
  94. package/dist/plugins/blocks/BlocksDirectoryLoaderEmitterPlugin.d.ts +25 -0
  95. package/dist/plugins/blocks/BlocksDirectoryLoaderEmitterPlugin.d.ts.map +1 -0
  96. package/dist/plugins/blocks/BlocksDirectoryLoaderEmitterPlugin.js +458 -0
  97. package/dist/plugins/blocks/BlocksDirectoryLoaderEmitterPlugin.js.map +1 -0
  98. package/dist/plugins/blocks/BlocksDirectoryProcessingPlugin.d.ts +29 -0
  99. package/dist/plugins/blocks/BlocksDirectoryProcessingPlugin.d.ts.map +1 -0
  100. package/dist/plugins/blocks/BlocksDirectoryProcessingPlugin.js +290 -0
  101. package/dist/plugins/blocks/BlocksDirectoryProcessingPlugin.js.map +1 -0
  102. package/dist/plugins/blocks/register.d.ts +6 -0
  103. package/dist/plugins/blocks/register.d.ts.map +1 -0
  104. package/dist/plugins/blocks/register.js +14 -0
  105. package/dist/plugins/blocks/register.js.map +1 -0
  106. package/dist/plugins/blocks/registerEmitter.d.ts +4 -0
  107. package/dist/plugins/blocks/registerEmitter.d.ts.map +1 -0
  108. package/dist/plugins/blocks/registerEmitter.js +13 -0
  109. package/dist/plugins/blocks/registerEmitter.js.map +1 -0
  110. package/dist/plugins/blocks/registerProcessor.d.ts +4 -0
  111. package/dist/plugins/blocks/registerProcessor.d.ts.map +1 -0
  112. package/dist/plugins/blocks/registerProcessor.js +46 -0
  113. package/dist/plugins/blocks/registerProcessor.js.map +1 -0
  114. package/dist/plugins/dependency-extraction-webpack-plugin-config-builder.d.ts +5 -0
  115. package/dist/plugins/dependency-extraction-webpack-plugin-config-builder.d.ts.map +1 -0
  116. package/dist/plugins/dependency-extraction-webpack-plugin-config-builder.js +148 -0
  117. package/dist/plugins/dependency-extraction-webpack-plugin-config-builder.js.map +1 -0
  118. package/dist/plugins/extensions/ExtensionsDirectoryLoaderEmitterPlugin.d.ts +14 -0
  119. package/dist/plugins/extensions/ExtensionsDirectoryLoaderEmitterPlugin.d.ts.map +1 -0
  120. package/dist/plugins/extensions/ExtensionsDirectoryLoaderEmitterPlugin.js +191 -0
  121. package/dist/plugins/extensions/ExtensionsDirectoryLoaderEmitterPlugin.js.map +1 -0
  122. package/dist/plugins/extensions/ExtensionsDirectoryLoaderEmitterPluginV1.d.ts +14 -0
  123. package/dist/plugins/extensions/ExtensionsDirectoryLoaderEmitterPluginV1.d.ts.map +1 -0
  124. package/dist/plugins/extensions/ExtensionsDirectoryLoaderEmitterPluginV1.js +102 -0
  125. package/dist/plugins/extensions/ExtensionsDirectoryLoaderEmitterPluginV1.js.map +1 -0
  126. package/dist/plugins/extensions/ExtensionsDirectoryProcessingPlugin.d.ts +25 -0
  127. package/dist/plugins/extensions/ExtensionsDirectoryProcessingPlugin.d.ts.map +1 -0
  128. package/dist/plugins/extensions/ExtensionsDirectoryProcessingPlugin.js +229 -0
  129. package/dist/plugins/extensions/ExtensionsDirectoryProcessingPlugin.js.map +1 -0
  130. package/dist/plugins/extensions/register.d.ts +6 -0
  131. package/dist/plugins/extensions/register.d.ts.map +1 -0
  132. package/dist/plugins/extensions/register.js +14 -0
  133. package/dist/plugins/extensions/register.js.map +1 -0
  134. package/dist/plugins/extensions/registerEmitter.d.ts +4 -0
  135. package/dist/plugins/extensions/registerEmitter.d.ts.map +1 -0
  136. package/dist/plugins/extensions/registerEmitter.js +18 -0
  137. package/dist/plugins/extensions/registerEmitter.js.map +1 -0
  138. package/dist/plugins/extensions/registerProcessor.d.ts +4 -0
  139. package/dist/plugins/extensions/registerProcessor.d.ts.map +1 -0
  140. package/dist/plugins/extensions/registerProcessor.js +42 -0
  141. package/dist/plugins/extensions/registerProcessor.js.map +1 -0
  142. package/dist/plugins/plain/PlainEntrypointProcessingPlugin.d.ts +18 -0
  143. package/dist/plugins/plain/PlainEntrypointProcessingPlugin.d.ts.map +1 -0
  144. package/dist/plugins/plain/PlainEntrypointProcessingPlugin.js +203 -0
  145. package/dist/plugins/plain/PlainEntrypointProcessingPlugin.js.map +1 -0
  146. package/dist/plugins/plain/PlainEntrypointsConfigEmitterPlugin.d.ts +13 -0
  147. package/dist/plugins/plain/PlainEntrypointsConfigEmitterPlugin.d.ts.map +1 -0
  148. package/dist/plugins/plain/PlainEntrypointsConfigEmitterPlugin.js +51 -0
  149. package/dist/plugins/plain/PlainEntrypointsConfigEmitterPlugin.js.map +1 -0
  150. package/dist/plugins/plain/register.d.ts +6 -0
  151. package/dist/plugins/plain/register.d.ts.map +1 -0
  152. package/dist/plugins/plain/register.js +14 -0
  153. package/dist/plugins/plain/register.js.map +1 -0
  154. package/dist/plugins/plain/registerEmitter.d.ts +4 -0
  155. package/dist/plugins/plain/registerEmitter.d.ts.map +1 -0
  156. package/dist/plugins/plain/registerEmitter.js +21 -0
  157. package/dist/plugins/plain/registerEmitter.js.map +1 -0
  158. package/dist/plugins/plain/registerProcessor.d.ts +4 -0
  159. package/dist/plugins/plain/registerProcessor.d.ts.map +1 -0
  160. package/dist/plugins/plain/registerProcessor.js +34 -0
  161. package/dist/plugins/plain/registerProcessor.js.map +1 -0
  162. package/dist/plugins/register.d.ts +3 -0
  163. package/dist/plugins/register.d.ts.map +1 -0
  164. package/dist/plugins/register.js +17 -0
  165. package/dist/plugins/register.js.map +1 -0
  166. package/dist/plugins/special-assets/SpecialAssetsCollectorPlugin.d.ts +20 -0
  167. package/dist/plugins/special-assets/SpecialAssetsCollectorPlugin.d.ts.map +1 -0
  168. package/dist/plugins/special-assets/SpecialAssetsCollectorPlugin.js +56 -0
  169. package/dist/plugins/special-assets/SpecialAssetsCollectorPlugin.js.map +1 -0
  170. package/dist/plugins/special-assets/SpecialAssetsLoaderEmitterPlugin.d.ts +13 -0
  171. package/dist/plugins/special-assets/SpecialAssetsLoaderEmitterPlugin.d.ts.map +1 -0
  172. package/dist/plugins/special-assets/SpecialAssetsLoaderEmitterPlugin.js +105 -0
  173. package/dist/plugins/special-assets/SpecialAssetsLoaderEmitterPlugin.js.map +1 -0
  174. package/dist/plugins/special-assets/register.d.ts +6 -0
  175. package/dist/plugins/special-assets/register.d.ts.map +1 -0
  176. package/dist/plugins/special-assets/register.js +14 -0
  177. package/dist/plugins/special-assets/register.js.map +1 -0
  178. package/dist/plugins/special-assets/registerEmitter.d.ts +4 -0
  179. package/dist/plugins/special-assets/registerEmitter.d.ts.map +1 -0
  180. package/dist/plugins/special-assets/registerEmitter.js +15 -0
  181. package/dist/plugins/special-assets/registerEmitter.js.map +1 -0
  182. package/dist/plugins/special-assets/registerProcessor.d.ts +4 -0
  183. package/dist/plugins/special-assets/registerProcessor.d.ts.map +1 -0
  184. package/dist/plugins/special-assets/registerProcessor.js +15 -0
  185. package/dist/plugins/special-assets/registerProcessor.js.map +1 -0
  186. package/dist/plugins/unified-loader/UnifiedLoaderGenerator.d.ts +22 -0
  187. package/dist/plugins/unified-loader/UnifiedLoaderGenerator.d.ts.map +1 -0
  188. package/dist/plugins/unified-loader/UnifiedLoaderGenerator.js +95 -0
  189. package/dist/plugins/unified-loader/UnifiedLoaderGenerator.js.map +1 -0
  190. package/dist/plugins/wpml-config/WPMLConfigBuilder.d.ts +24 -0
  191. package/dist/plugins/wpml-config/WPMLConfigBuilder.d.ts.map +1 -0
  192. package/dist/plugins/wpml-config/WPMLConfigBuilder.js +542 -0
  193. package/dist/plugins/wpml-config/WPMLConfigBuilder.js.map +1 -0
  194. package/dist/plugins/wpml-config/register.d.ts +6 -0
  195. package/dist/plugins/wpml-config/register.d.ts.map +1 -0
  196. package/dist/plugins/wpml-config/register.js +25 -0
  197. package/dist/plugins/wpml-config/register.js.map +1 -0
  198. package/dist/shared.d.ts +38 -0
  199. package/dist/shared.d.ts.map +1 -0
  200. package/dist/shared.js +163 -0
  201. package/dist/shared.js.map +1 -0
  202. package/dist/utils/error-helpers.d.ts +7 -0
  203. package/dist/utils/error-helpers.d.ts.map +1 -0
  204. package/dist/utils/error-helpers.js +73 -0
  205. package/dist/utils/error-helpers.js.map +1 -0
  206. package/dist/utils/index.d.ts +6 -0
  207. package/dist/utils/index.d.ts.map +1 -0
  208. package/dist/utils/index.js +22 -0
  209. package/dist/utils/index.js.map +1 -0
  210. package/dist/utils/misc.d.ts +4 -0
  211. package/dist/utils/misc.d.ts.map +1 -0
  212. package/dist/utils/misc.js +18 -0
  213. package/dist/utils/misc.js.map +1 -0
  214. package/dist/utils/path-helpers.d.ts +16 -0
  215. package/dist/utils/path-helpers.d.ts.map +1 -0
  216. package/dist/utils/path-helpers.js +115 -0
  217. package/dist/utils/path-helpers.js.map +1 -0
  218. package/dist/utils/pseudo-semaphore.d.ts +15 -0
  219. package/dist/utils/pseudo-semaphore.d.ts.map +1 -0
  220. package/dist/utils/pseudo-semaphore.js +77 -0
  221. package/dist/utils/pseudo-semaphore.js.map +1 -0
  222. package/dist/utils/type-helpers.d.ts +27 -0
  223. package/dist/utils/type-helpers.d.ts.map +1 -0
  224. package/dist/utils/type-helpers.js +33 -0
  225. package/dist/utils/type-helpers.js.map +1 -0
  226. package/dist/utils/writer-utils.d.ts +8 -0
  227. package/dist/utils/writer-utils.d.ts.map +1 -0
  228. package/dist/utils/writer-utils.js +35 -0
  229. package/dist/utils/writer-utils.js.map +1 -0
  230. package/dist/wordpress-ports/dependency-extraction-webpack-plugin/index.d.ts +73 -0
  231. package/dist/wordpress-ports/dependency-extraction-webpack-plugin/index.d.ts.map +1 -0
  232. package/dist/wordpress-ports/dependency-extraction-webpack-plugin/index.js +516 -0
  233. package/dist/wordpress-ports/dependency-extraction-webpack-plugin/index.js.map +1 -0
  234. package/dist/wordpress-ports/dependency-extraction-webpack-plugin/util.d.ts +57 -0
  235. package/dist/wordpress-ports/dependency-extraction-webpack-plugin/util.d.ts.map +1 -0
  236. package/dist/wordpress-ports/dependency-extraction-webpack-plugin/util.js +156 -0
  237. package/dist/wordpress-ports/dependency-extraction-webpack-plugin/util.js.map +1 -0
  238. package/dist/wordpress-scripts-wrapper.d.ts +5 -0
  239. package/dist/wordpress-scripts-wrapper.d.ts.map +1 -0
  240. package/dist/wordpress-scripts-wrapper.js +444 -0
  241. package/dist/wordpress-scripts-wrapper.js.map +1 -0
  242. package/package.json +3 -3
@@ -0,0 +1,767 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RootCoordinatorPluginImpl = void 0;
4
+ exports.canMergeHandles = canMergeHandles;
5
+ const node_crypto_1 = require("node:crypto");
6
+ const node_path_1 = require("node:path");
7
+ const php_writer_1 = require("@plaudit/php-writer");
8
+ const webpack_1 = require("webpack");
9
+ const api_1 = require("../api");
10
+ const shared_1 = require("../shared");
11
+ const utils_1 = require("../utils");
12
+ /**
13
+ * NOTE: You MUST use a SINGLE instance of this plugin across all compilers (both module and non-module) in order for things to work correctly
14
+ */
15
+ class RootCoordinatorPluginImpl {
16
+ /**
17
+ * Maps from the path to the coordinated asset to a mapping of plugin -> available data. False means that the plugin should be providing data
18
+ */
19
+ coordinatedEmitterData = Object.create(null);
20
+ compiledAssets = new Map();
21
+ // This is kept separate to allow us to avoid recomputing handles on every change
22
+ internalHandlesCache = undefined;
23
+ // This is what gets passed to logic that emits files like blockdir-loader.php
24
+ unifiedAssetsCache = undefined;
25
+ isStaticallyLoadedByEmitterName = Object.create(null);
26
+ constructor() { }
27
+ enableAssetPhpFileEmission(coordinatedLoaderName) {
28
+ this.isStaticallyLoadedByEmitterName[coordinatedLoaderName] = true;
29
+ }
30
+ apply(compiler) {
31
+ compiler.hooks.thisCompilation.tap(this.constructor.name, compilation => {
32
+ const priorCompiledAssets = this.compiledAssets.get(compiler)?.value ?? Object.create(null);
33
+ const insertionTarget = (0, shared_1.promiseWithResolversAndValue)();
34
+ this.compiledAssets.set(compiler, insertionTarget);
35
+ compilation.hooks.processAssets.tapPromise({ name: this.constructor.name, stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_REPORT + 1000 }, async () => {
36
+ const assetsJson = (0, shared_1.getAssetsJson)(compilation);
37
+ let isDifferent = false;
38
+ const existingEntryOptions = priorCompiledAssets;
39
+ const entryOptions = Object.create(null);
40
+ for (const entrypoint of compilation.entrypoints.values()) {
41
+ const plauditOptions = (0, api_1.getPlauditEntryOptions)(entrypoint);
42
+ if (!plauditOptions) {
43
+ continue;
44
+ }
45
+ const entrypointChunkIsScript = api_1.isScriptExtensionRegex.test(plauditOptions.absoluteSrc);
46
+ for (const chunk of entrypoint.chunks) {
47
+ for (const file of chunk.files) {
48
+ const isScript = api_1.isScriptExtensionRegex.test(file);
49
+ const isPrimary = isScript === entrypointChunkIsScript ? 1 : 0; //TODO: Confirm that this is correct (ex: auxiliary CSS files should not be primary)
50
+ const assetData = assetsJson[file] ?? assetsJson[file.replace(/\.css$/, ".js")]; //TODO: Confirm that assuming all files we need to emit will be in assets.json won't cause issues
51
+ if (assetData && (entrypointChunkIsScript || !isScript)) {
52
+ //TODO: Fix fetchpriority for CSS files - it currently attempts to write an array to the $media property, which is incorrect
53
+ let scriptArgsObject;
54
+ if (isScript) {
55
+ if (plauditOptions.flags.strategy !== undefined) {
56
+ scriptArgsObject = { strategy: plauditOptions.flags.strategy };
57
+ }
58
+ if (plauditOptions.flags.in_footer !== undefined) {
59
+ (scriptArgsObject ??= {}).in_footer = plauditOptions.flags.in_footer;
60
+ }
61
+ if (isPrimary && assetData.module_dependencies?.length) {
62
+ (scriptArgsObject ??= {}).module_dependencies = assetData.module_dependencies;
63
+ }
64
+ if (plauditOptions.flags.fetchpriority !== undefined) {
65
+ (scriptArgsObject ??= {}).fetchpriority = plauditOptions.flags.fetchpriority;
66
+ }
67
+ }
68
+ const type = isPrimary ? plauditOptions.type : (0, api_1.getAssetType)(file);
69
+ if (!type) {
70
+ continue;
71
+ }
72
+ const options = {
73
+ isPrimary,
74
+ finalizedHandleMetadata: {
75
+ src: file,
76
+ dependencies: isPrimary ? assetData.dependencies : [],
77
+ version: assetData.version,
78
+ scriptArgsObject,
79
+ },
80
+ options: plauditOptions,
81
+ type
82
+ };
83
+ if (plauditOptions.flags.inline ?? plauditOptions.mayInline?.(file, plauditOptions) ?? false) {
84
+ options.finalizedHandleMetadata.contents = compilation.getAsset(file)?.source.source().toString('utf-8') ?? "";
85
+ if (!(plauditOptions.writeToDisk?.(file, plauditOptions) ?? false)) {
86
+ compilation.deleteAsset(file);
87
+ }
88
+ }
89
+ else if (!(plauditOptions.writeToDisk?.(file, plauditOptions) ?? true)) {
90
+ compilation.deleteAsset(file);
91
+ }
92
+ entryOptions[file] = options;
93
+ if (!isDifferent) {
94
+ const eeo = existingEntryOptions[file];
95
+ if (eeo === undefined ||
96
+ eeo.options.absoluteSrc !== plauditOptions.absoluteSrc) {
97
+ isDifferent = true;
98
+ }
99
+ else {
100
+ const eeoInitialHandleName = eeo.options.initialHandleName;
101
+ const newInitialHandleName = plauditOptions.initialHandleName;
102
+ if (newInitialHandleName === false) {
103
+ if (eeoInitialHandleName !== false) {
104
+ isDifferent = true;
105
+ }
106
+ }
107
+ else if (eeoInitialHandleName === false ||
108
+ eeoInitialHandleName.handle !== newInitialHandleName.handle ||
109
+ eeoInitialHandleName.derivation !== newInitialHandleName.derivation) {
110
+ isDifferent = true;
111
+ }
112
+ }
113
+ }
114
+ }
115
+ }
116
+ }
117
+ }
118
+ if (isDifferent || Object.keys(entryOptions).length !== Object.keys(existingEntryOptions).length) { // The length check also takes care of "in prior but not in current"-like differences
119
+ this.internalHandlesCache = undefined; // Recomputing this is expensive
120
+ }
121
+ this.unifiedAssetsCache = undefined; // Recomputing this is relatively cheap
122
+ insertionTarget.resolve(entryOptions);
123
+ });
124
+ compilation.hooks.afterProcessAssets.tap(this.constructor.name, () => {
125
+ const rawStaticallyLoadedEntrypoints = [];
126
+ for (const entrypoint of compilation.entrypoints.values()) {
127
+ const options = (0, api_1.getPlauditEntryOptions)(entrypoint);
128
+ if (options?.staticallyLoaded ?? (options?.coordinatedLoaderName === undefined || !this.isStaticallyLoadedByEmitterName[options.coordinatedLoaderName])) {
129
+ rawStaticallyLoadedEntrypoints.push(...entrypoint.getEntrypointChunk().files);
130
+ }
131
+ }
132
+ const staticallyLoadedEntrypoints = new Set(rawStaticallyLoadedEntrypoints);
133
+ for (const [file, assetData] of Object.entries((0, shared_1.getAssetsJson)(compilation))) {
134
+ if (staticallyLoadedEntrypoints.has(file) || !compilation.getAsset(file)) {
135
+ continue;
136
+ }
137
+ if (file.endsWith(".css") && staticallyLoadedEntrypoints.has(file.slice(0, -4) + ".js")) {
138
+ continue;
139
+ }
140
+ if (file.endsWith(".js") && staticallyLoadedEntrypoints.has(file.slice(0, -3) + ".css")) {
141
+ continue;
142
+ }
143
+ const parsedPath = (0, node_path_1.parse)(file);
144
+ const contents = `<?php return ${(0, php_writer_1.json2php)(assetData)};\n`;
145
+ const assetName = (0, node_path_1.join)(parsedPath.dir, parsedPath.name) + ".asset.php";
146
+ compilation[assetName in compilation.assets ? 'updateAsset' : 'emitAsset'](assetName, new webpack_1.sources.RawSource(contents), { size: Buffer.byteLength(contents) });
147
+ }
148
+ compilation.deleteAsset("assets.json");
149
+ });
150
+ });
151
+ compiler.hooks.shutdown.tap(this.constructor.name, () => {
152
+ this.compiledAssets.delete(compiler);
153
+ for (const map of Object.values(this.coordinatedEmitterData)) {
154
+ map.delete(compiler);
155
+ }
156
+ this.internalHandlesCache = undefined;
157
+ this.unifiedAssetsCache = undefined;
158
+ });
159
+ }
160
+ registerDataEmitter(compiler, emitter, ...emissionTargets) {
161
+ if (emissionTargets.length === 0) {
162
+ return;
163
+ }
164
+ compiler.hooks.thisCompilation.tap(`${this.constructor.name}_EmittedDataCleaner`, () => {
165
+ for (const emissionTarget of emissionTargets) {
166
+ const items = (this.coordinatedEmitterData[emissionTarget] ??= new Map())
167
+ .getOrInsert(compiler, new Map());
168
+ items.set(emitter, false);
169
+ }
170
+ });
171
+ }
172
+ reportData(compilation, emitter, emissionTarget, data) {
173
+ const map = this.coordinatedEmitterData[emissionTarget]?.get(compilation.compiler);
174
+ if (map?.has(emitter)) {
175
+ map.set(emitter, data);
176
+ }
177
+ else {
178
+ (0, utils_1.emitError)(`Attempted to report data from an emitter to "${emissionTarget}" that was not pre-registered`, { compilation });
179
+ }
180
+ }
181
+ async getCompiledAssets() {
182
+ const res = {};
183
+ for (const compiledAssetsSegment of await Promise.all(this.compiledAssets.values().map(v => v.promise))) {
184
+ for (const [key, value] of Object.entries(compiledAssetsSegment)) {
185
+ if (res[key]) {
186
+ (0, utils_1.emitError)("Encountered a duplicate compilation request for file", { rawIdentifier: key });
187
+ }
188
+ res[key] = value;
189
+ }
190
+ }
191
+ return res;
192
+ }
193
+ /**
194
+ * This MUST NOT be called from within plugins associated with compilers that produce basic assets
195
+ *
196
+ * @param compilation
197
+ */
198
+ async getHandles(compilation) {
199
+ if (this.internalHandlesCache === undefined) {
200
+ const allTypeGroupedHandlesItems = [];
201
+ const combinedCompiledAssets = await this.getCompiledAssets();
202
+ for (const [asset, { options, isPrimary, finalizedHandleMetadata, type }] of Object.entries(combinedCompiledAssets)) {
203
+ const { initialHandleName } = options;
204
+ if (initialHandleName) {
205
+ const use = { asset, ...initialHandleName, isPrimary, options, finalizedHandleMetadata, type, originalHandle: initialHandleName.handle };
206
+ allTypeGroupedHandlesItems.push(use);
207
+ }
208
+ }
209
+ let isFirstPass = true;
210
+ let handlesNeedingFallbackNameApplication = [];
211
+ do {
212
+ if (handlesNeedingFallbackNameApplication.length > 0) {
213
+ for (const use of handlesNeedingFallbackNameApplication) {
214
+ const res = use.fallbackHandleProducer?.();
215
+ delete use.fallbackHandleProducer;
216
+ if (res !== undefined) {
217
+ use.originalHandle = use.handle = res.handle;
218
+ use.fallbackHandleProducer = res.fallbackHandleProducer;
219
+ use.derivation = res.derivation;
220
+ if (use.associatedAssets) {
221
+ for (const aa of use.associatedAssets) {
222
+ if (aa.associationMechanism === 'merged') {
223
+ use.originalHandle = aa.handle = res.handle;
224
+ aa.fallbackHandleProducer = res.fallbackHandleProducer;
225
+ aa.derivation = res.derivation;
226
+ }
227
+ }
228
+ }
229
+ }
230
+ }
231
+ }
232
+ handlesNeedingFallbackNameApplication = [];
233
+ const typeGroupedHandles = {
234
+ script: {},
235
+ script_module: {},
236
+ style: {},
237
+ };
238
+ for (const use of allTypeGroupedHandlesItems) {
239
+ const { type, originalHandle } = use;
240
+ const existing = typeGroupedHandles[type][originalHandle];
241
+ if (existing) {
242
+ existing.push(use);
243
+ }
244
+ else {
245
+ typeGroupedHandles[type][originalHandle] = [use];
246
+ }
247
+ }
248
+ const remainingHopefullyModifiableHandles = {
249
+ script: {},
250
+ script_module: {},
251
+ style: {},
252
+ };
253
+ const usedHandlesForFancyPrinting = {
254
+ script: new Map(),
255
+ script_module: new Map(),
256
+ style: new Map(),
257
+ };
258
+ for (const [type, handleGroups] of (0, utils_1.constantEntries)(typeGroupedHandles)) {
259
+ for (const [handleName, uncondensedUses] of Object.entries(handleGroups).sort(([a], [b]) => a.localeCompare(b))) {
260
+ let uses;
261
+ if (uncondensedUses.length === 1 || !uncondensedUses.some(u => u.options.flags.inline !== undefined)) {
262
+ uses = uncondensedUses;
263
+ }
264
+ else {
265
+ const tempUses = [];
266
+ const usesByParentDirectory = {};
267
+ for (const use of uncondensedUses) {
268
+ (usesByParentDirectory[(0, node_path_1.dirname)(use.options.absoluteSrc)] ??= []).push(use);
269
+ }
270
+ for (const potentiallyCollatableUses of Object.values(usesByParentDirectory)) {
271
+ if (isFirstPass) {
272
+ const nonInlinedUses = potentiallyCollatableUses.filter(use => use.options.flags.inline === undefined);
273
+ if ((0, utils_1.arrayIsLength)(nonInlinedUses, 1)) {
274
+ const primaryUse = nonInlinedUses[0];
275
+ tempUses.push(primaryUse);
276
+ for (const inlinedUse of potentiallyCollatableUses.filter(use => use.options.flags.inline !== undefined)) {
277
+ const mechanism = canMergeHandles(primaryUse, inlinedUse);
278
+ inlinedUse.associationMechanism = mechanism;
279
+ if (mechanism === 'merged') {
280
+ inlinedUse.omitRegistration = true;
281
+ (primaryUse.associatedAssets ??= []).push(inlinedUse);
282
+ }
283
+ else {
284
+ if (mechanism) {
285
+ (primaryUse.associatedAssets ??= []).push(inlinedUse);
286
+ }
287
+ tempUses.push(inlinedUse);
288
+ }
289
+ }
290
+ }
291
+ else {
292
+ tempUses.push(...potentiallyCollatableUses);
293
+ }
294
+ }
295
+ else {
296
+ tempUses.push(...potentiallyCollatableUses.filter(use => use.associationMechanism !== 'merged'));
297
+ }
298
+ }
299
+ if (!(0, utils_1.hasAtLeastOneItem)(tempUses)) {
300
+ continue;
301
+ }
302
+ uses = tempUses;
303
+ }
304
+ if (uses.length === 1) {
305
+ checkAndApplyOrEnqueueHandleNameInstances(compilation, usedHandlesForFancyPrinting, remainingHopefullyModifiableHandles, type, handleName, uses);
306
+ }
307
+ else {
308
+ const unmodifiable = [];
309
+ const modifiable = [];
310
+ for (const use of uses) {
311
+ if ((0, api_1.handleCannotBeModifiedForConflictAvoidance)(use)) {
312
+ unmodifiable.push(use);
313
+ }
314
+ else {
315
+ modifiable.push(use);
316
+ }
317
+ }
318
+ if ((0, utils_1.hasAtLeastOneItem)(unmodifiable)) {
319
+ checkAndApplyOrEnqueueHandleNameInstances(compilation, usedHandlesForFancyPrinting, remainingHopefullyModifiableHandles, type, handleName, unmodifiable);
320
+ }
321
+ if ((0, utils_1.hasAtLeastOneItem)(modifiable)) {
322
+ const batch = remainingHopefullyModifiableHandles[type][handleName];
323
+ if (batch) {
324
+ batch.push(...modifiable);
325
+ }
326
+ else {
327
+ remainingHopefullyModifiableHandles[type][handleName] = [...modifiable];
328
+ }
329
+ }
330
+ }
331
+ }
332
+ }
333
+ // This applies deduping logic to hooks that were either generated (aka not user-specified) or that we have no choice but to dedupe.
334
+ // It doesn't do any further checking because that has already been done in the prior steps
335
+ const usedHandles = {
336
+ script: new Set(usedHandlesForFancyPrinting.script.keys()),
337
+ script_module: new Set(usedHandlesForFancyPrinting.script_module.keys()),
338
+ style: new Set(usedHandlesForFancyPrinting.style.keys()),
339
+ };
340
+ const firstOfEachUsedHandle = {
341
+ script: {},
342
+ script_module: {},
343
+ style: {},
344
+ };
345
+ for (const [type, handleGroups] of (0, utils_1.constantEntries)(remainingHopefullyModifiableHandles)) {
346
+ for (const [handleName, uses] of Object.entries(handleGroups).sort(([a], [b]) => a.localeCompare(b))) {
347
+ let dedupedHandle, count = 0;
348
+ for (const use of uses.sort(compareTypeGroupedHandlesItems)) {
349
+ if (!usedHandles[type].has(handleName)) {
350
+ dedupedHandle = handleName;
351
+ }
352
+ else {
353
+ if (firstOfEachUsedHandle[type][handleName]?.fallbackHandleProducer) {
354
+ handlesNeedingFallbackNameApplication.push(firstOfEachUsedHandle[type][handleName]);
355
+ delete firstOfEachUsedHandle[type][handleName];
356
+ }
357
+ if (use.fallbackHandleProducer !== undefined) {
358
+ handlesNeedingFallbackNameApplication.push(use);
359
+ continue;
360
+ }
361
+ do {
362
+ count++;
363
+ } while (usedHandles[type].has(dedupedHandle = `${handleName}-${count}`));
364
+ }
365
+ usedHandles[type].add(dedupedHandle);
366
+ firstOfEachUsedHandle[type][dedupedHandle] ??= use;
367
+ use.handle = dedupedHandle;
368
+ if (use.associatedAssets) {
369
+ for (const associated of use.associatedAssets) {
370
+ if (associated.associationMechanism === 'merged') {
371
+ associated.handle = dedupedHandle;
372
+ associated.omitRegistration = true;
373
+ }
374
+ }
375
+ }
376
+ }
377
+ }
378
+ }
379
+ isFirstPass = false;
380
+ } while (handlesNeedingFallbackNameApplication.length > 0);
381
+ const internalHandlesCache = Object.create(null);
382
+ const unifiedAssetsCache = Object.create(null);
383
+ const buildUnifiedAssetsCacheEntry = (item) => {
384
+ const { asset, associatedAssets, associationMechanism, finalizedHandleMetadata, handle, omitRegistration, options, type } = item;
385
+ if (handle === undefined) {
386
+ throw (0, utils_1.newWebpackErrorForFile)("Encountered a TypeGroupedHandlesItem instance that was not compatible with the CachedHandleData type", asset);
387
+ }
388
+ let res = unifiedAssetsCache[asset];
389
+ if (res === undefined) {
390
+ res = unifiedAssetsCache[asset] = {
391
+ handle,
392
+ omitRegistration,
393
+ associationMechanism,
394
+ finalizedHandleMetadata,
395
+ options,
396
+ type,
397
+ };
398
+ if (associatedAssets) {
399
+ res.associatedAssets = associatedAssets.map(buildUnifiedAssetsCacheEntry);
400
+ }
401
+ }
402
+ return res;
403
+ };
404
+ for (const use of allTypeGroupedHandlesItems) {
405
+ const { associatedAssets, handle, ...rest } = use;
406
+ if (handle === undefined) {
407
+ throw (0, utils_1.newWebpackErrorForFile)("Encountered a TypeGroupedHandlesItem instance that was not compatible with the CachedHandleData type", use.asset);
408
+ }
409
+ internalHandlesCache[use.asset] = { ...rest, handle, associatedAssets: associatedAssets?.map(a => a.asset) };
410
+ buildUnifiedAssetsCacheEntry(use);
411
+ }
412
+ this.internalHandlesCache = internalHandlesCache;
413
+ this.unifiedAssetsCache = unifiedAssetsCache;
414
+ }
415
+ else if (this.unifiedAssetsCache === undefined) {
416
+ const compiledAssets = await this.getCompiledAssets();
417
+ const unifiedAssetsCache = Object.create(null);
418
+ const internalHandlesCache = this.internalHandlesCache;
419
+ const buildUnifiedAssetsCacheEntry = (asset) => {
420
+ // biome-ignore lint/style/noNonNullAssertion: We set up compiledAssets in a way that guarantees that this will always be valid
421
+ const { finalizedHandleMetadata, options, type } = compiledAssets[asset];
422
+ // biome-ignore lint/style/noNonNullAssertion: We set up internalHandlesCache in a way that guarantees that this will always be valid
423
+ const { handle, omitRegistration, associatedAssets, associationMechanism } = internalHandlesCache[asset];
424
+ let res = unifiedAssetsCache[asset];
425
+ if (res === undefined) {
426
+ res = unifiedAssetsCache[asset] = {
427
+ handle,
428
+ omitRegistration,
429
+ associationMechanism,
430
+ finalizedHandleMetadata,
431
+ options,
432
+ type,
433
+ };
434
+ if (associatedAssets) {
435
+ res.associatedAssets = associatedAssets.map(buildUnifiedAssetsCacheEntry);
436
+ }
437
+ }
438
+ return res;
439
+ };
440
+ Object.keys(compiledAssets).forEach(buildUnifiedAssetsCacheEntry);
441
+ this.unifiedAssetsCache = unifiedAssetsCache;
442
+ }
443
+ return this.unifiedAssetsCache;
444
+ }
445
+ static make() {
446
+ const coordinator = new RootCoordinatorPluginImpl();
447
+ return {
448
+ coordinator,
449
+ finalizer: (configs) => {
450
+ const usedConfigNames = new Set();
451
+ const res = configs.map(config => {
452
+ if (config.name !== undefined) {
453
+ if (usedConfigNames.has(config.name)) {
454
+ let count = 0, name;
455
+ do {
456
+ name = `${config.name}-${++count}`;
457
+ } while (usedConfigNames.has(name));
458
+ usedConfigNames.add(name);
459
+ return { ...config, name };
460
+ }
461
+ else {
462
+ usedConfigNames.add(config.name);
463
+ }
464
+ }
465
+ return config;
466
+ });
467
+ const allocateName = (config) => {
468
+ // Yes, this is a lot, but it is to ensure that the output is trivially-readable
469
+ const hasBase = (dep) => dep.includes(":base:") || dep.startsWith("base:");
470
+ const namedDep = config.dependencies?.find(dep => hasBase(dep) && !dep.endsWith(":modules")) ?? config.dependencies?.find(hasBase);
471
+ const availableNames = config.plugins
472
+ ?.map(plugin => plugin instanceof api_1.CoordinatableEmitter ? plugin.defaultCompilationName : undefined)
473
+ .filter(name => name !== undefined)
474
+ .map(name => namedDep?.replaceAll(/(^|:)base(:)?(?:modules|non-modules)?/gi, "$1base:" + name.replaceAll("$", "\\$") + "$2") ?? name)
475
+ .map(name => name.endsWith(":") ? name.slice(0, -1) : name);
476
+ let name;
477
+ if ((0, utils_1.hasAtLeastOneItem)(availableNames)) {
478
+ name = availableNames.find(name => !usedConfigNames.has(name));
479
+ if (name === undefined) {
480
+ let count = 0;
481
+ do {
482
+ name = `${availableNames[0]}-${++count}`;
483
+ } while (usedConfigNames.has(name));
484
+ }
485
+ }
486
+ if (name === undefined) {
487
+ do {
488
+ name = (0, node_crypto_1.randomUUID)();
489
+ } while (usedConfigNames.has(name));
490
+ }
491
+ usedConfigNames.add(name);
492
+ return name;
493
+ };
494
+ const makeGeneratedCfgSafe = (cfg) => {
495
+ if (cfg.output?.clean) {
496
+ cfg.output = {
497
+ ...cfg.output,
498
+ clean: false,
499
+ };
500
+ }
501
+ if (cfg.name !== undefined) {
502
+ if (usedConfigNames.has(cfg.name)) {
503
+ delete cfg.name;
504
+ }
505
+ else {
506
+ usedConfigNames.add(cfg.name);
507
+ }
508
+ }
509
+ if (cfg.dependencies !== undefined) {
510
+ cfg.dependencies = [...cfg.dependencies];
511
+ }
512
+ return cfg;
513
+ };
514
+ const allCreatedConfigs = Object.create(null);
515
+ let novelConfigs = configs;
516
+ while (novelConfigs.length > 0) {
517
+ const iter = novelConfigs.values();
518
+ novelConfigs = [];
519
+ for (const config of iter) {
520
+ const coordinatableEmitters = config.plugins?.filter(p => p instanceof api_1.CoordinatableEmitter);
521
+ if (!coordinatableEmitters?.length) {
522
+ continue;
523
+ }
524
+ config.name ??= allocateName(config);
525
+ for (const emitter of coordinatableEmitters) {
526
+ for (const [target, configBuilder] of emitter.getCoordinatedEmissionTargets()) {
527
+ if (!allCreatedConfigs[target]) {
528
+ const cfg = makeGeneratedCfgSafe(configBuilder(config, coordinator));
529
+ allCreatedConfigs[target] = cfg;
530
+ novelConfigs.push(cfg);
531
+ res.push(cfg);
532
+ }
533
+ if (allCreatedConfigs[target].name !== config.name) {
534
+ (allCreatedConfigs[target].dependencies ??= []).push(config.name);
535
+ }
536
+ }
537
+ }
538
+ }
539
+ }
540
+ let verifiedConfigs = res;
541
+ let configProvisionAndRequirements;
542
+ let changed;
543
+ do {
544
+ const iter = verifiedConfigs.values();
545
+ verifiedConfigs = [];
546
+ changed = false;
547
+ configProvisionAndRequirements = [];
548
+ for (const config of iter) {
549
+ const provides = [];
550
+ const requires = [];
551
+ const emitters = config.plugins?.filter(p => p instanceof api_1.CoordinatableEmitter);
552
+ if (emitters?.length) {
553
+ for (const emitter of emitters) {
554
+ provides.push(...emitter.provides.filter(p => !provides.includes(p)));
555
+ requires.push(...emitter.requires.filter(p => !requires.includes(p)));
556
+ }
557
+ }
558
+ configProvisionAndRequirements.push({ config, provides, requires });
559
+ }
560
+ for (const { config, provides, requires } of configProvisionAndRequirements) {
561
+ verifiedConfigs.push(config);
562
+ if (!config.plugins) {
563
+ continue;
564
+ }
565
+ if (provides.some(p => requires.includes(p))) {
566
+ const retainablePlugins = config.plugins.filter(plugin => {
567
+ return !(plugin instanceof api_1.CoordinatableEmitter) || !plugin.requires.some(r => provides.includes(r));
568
+ });
569
+ if (retainablePlugins.find(p => p instanceof api_1.CoordinatableEmitter) === undefined) {
570
+ throw new Error("Encountered an infinite dependency loop");
571
+ }
572
+ const otherPlugins = config.plugins.filter(plugin => {
573
+ return plugin instanceof api_1.CoordinatableEmitter && plugin.requires.some(r => provides.includes(r));
574
+ });
575
+ config.plugins = retainablePlugins;
576
+ verifiedConfigs.push(makeGeneratedCfgSafe({ ...config, plugins: otherPlugins, dependencies: [config.name ??= allocateName(config)] }));
577
+ changed = true;
578
+ }
579
+ }
580
+ } while (changed);
581
+ const requirementToCompilerNames = Object.create(null);
582
+ for (const { config, provides } of configProvisionAndRequirements) {
583
+ config.name ??= allocateName(config);
584
+ for (const provide of provides) {
585
+ (requirementToCompilerNames[provide] ??= []).push(config.name);
586
+ }
587
+ }
588
+ for (const { config, requires } of configProvisionAndRequirements) {
589
+ for (const req of requires) {
590
+ if (requirementToCompilerNames[req]) {
591
+ const cfgDeps = config.dependencies ??= [];
592
+ config.dependencies.push(...requirementToCompilerNames[req].filter(dep => !cfgDeps.includes(dep)));
593
+ }
594
+ }
595
+ }
596
+ return configProvisionAndRequirements.map(item => item.config);
597
+ }
598
+ };
599
+ }
600
+ getData(emissionTarget) {
601
+ return (this.coordinatedEmitterData[emissionTarget]?.values().flatMap(m => {
602
+ return m.values().filter((v) => v !== false);
603
+ }).toArray() ?? []);
604
+ }
605
+ }
606
+ exports.RootCoordinatorPluginImpl = RootCoordinatorPluginImpl;
607
+ /**
608
+ * Only call this with items that are user-specified OR generated, but not a mix of both
609
+ */
610
+ function checkAndApplyOrEnqueueHandleNameInstances(compilation, usedHandles, remainingHopefullyModifiableHandles, type, handleName, items) {
611
+ if (!items.some(api_1.handleCannotBeModifiedForConflictAvoidance)) {
612
+ const batch = remainingHopefullyModifiableHandles[type][handleName];
613
+ if (batch) {
614
+ batch.push(...items);
615
+ }
616
+ else {
617
+ remainingHopefullyModifiableHandles[type][handleName] = [...items];
618
+ }
619
+ return;
620
+ }
621
+ let existing = usedHandles[type].get(handleName);
622
+ if (existing) {
623
+ existing.push(...items.map(item => item.asset));
624
+ if (items.some(api_1.handleCannotBeModifiedForConflictAvoidance)) {
625
+ (0, utils_1.emitError)(`Encountered multiple assets with the same user-specified handle ("${handleName}"). The emitted assets will have unstable handle names.`, { rawIdentifier: existing.join(", "), compilation });
626
+ }
627
+ const batch = remainingHopefullyModifiableHandles[type][handleName];
628
+ if (batch) {
629
+ batch.push(...items);
630
+ }
631
+ else {
632
+ remainingHopefullyModifiableHandles[type][handleName] = [...items];
633
+ }
634
+ }
635
+ else {
636
+ const [valid, ...invalid] = items.sort(compareTypeGroupedHandlesItems);
637
+ valid.handle = handleName;
638
+ if (valid.associatedAssets) {
639
+ for (const associated of valid.associatedAssets) {
640
+ if (associated.associationMechanism === 'merged') {
641
+ associated.handle = handleName;
642
+ associated.omitRegistration = true;
643
+ }
644
+ }
645
+ }
646
+ usedHandles[type].set(handleName, existing = [valid.asset]);
647
+ if ((0, utils_1.hasAtLeastOneItem)(invalid)) {
648
+ existing.push(...invalid.map(item => item.asset));
649
+ (0, utils_1.emitError)(`Encountered multiple assets with the same user-specified handle ("${handleName}"). The emitted assets will have unstable handle names.`, { rawIdentifier: existing.join(", "), compilation });
650
+ const batch = remainingHopefullyModifiableHandles[type][handleName];
651
+ if (batch) {
652
+ batch.push(...invalid);
653
+ }
654
+ else {
655
+ remainingHopefullyModifiableHandles[type][handleName] = invalid;
656
+ }
657
+ }
658
+ }
659
+ }
660
+ const compareTypeGroupedHandlesItems = (a, b) => {
661
+ return (a.derivation - b.derivation) || (b.isPrimary - a.isPrimary) || a.asset.localeCompare(b.asset);
662
+ };
663
+ /**
664
+ * @return {@code 'merged'} -> "can share the same handle", {@code false} -> "cannot be merged", {@code 'dependent'} -> "one handle can be listed as a dependency of the other"
665
+ */
666
+ function canMergeHandles(handleA, handleB) {
667
+ const optionsA = handleA.options, optionsB = handleB.options;
668
+ if (optionsA.flags.inline === undefined && optionsB.flags.inline === undefined) {
669
+ return undefined; // We cannot merge handles for two non-inlined assets
670
+ }
671
+ if ((0, node_path_1.dirname)(optionsA.absoluteSrc) !== (0, node_path_1.dirname)(optionsB.absoluteSrc)) {
672
+ return undefined; // We don't want assets from different locations to be able to have their handles overlap
673
+ }
674
+ if (optionsA.flags.in_footer !== optionsB.flags.in_footer) {
675
+ return 'dependent';
676
+ }
677
+ if ((0, api_1.isDeferringLoadingStrategy)(optionsA.flags.strategy) && optionsB.flags.inline === 'after') {
678
+ return undefined;
679
+ }
680
+ if ((0, api_1.isDeferringLoadingStrategy)(optionsB.flags.strategy) && optionsA.flags.inline === 'after') {
681
+ return undefined;
682
+ }
683
+ if (!optionsA.computedHandleArguments || !optionsB.computedHandleArguments) {
684
+ return undefined; //TODO: Print an error or something?
685
+ }
686
+ const additionalArgsA = optionsA.computedHandleArguments.length === 3 ? optionsA.computedHandleArguments[2] : {};
687
+ const additionalArgsB = optionsB.computedHandleArguments.length === 3 ? optionsB.computedHandleArguments[2] : {};
688
+ if (typeof additionalArgsA !== 'string') {
689
+ if (typeof additionalArgsB === 'string') {
690
+ return undefined;
691
+ }
692
+ if (additionalArgsA.module_dependencies !== additionalArgsB.module_dependencies) {
693
+ if (additionalArgsA.module_dependencies === undefined) {
694
+ return undefined;
695
+ }
696
+ if (additionalArgsB.module_dependencies === undefined) {
697
+ return undefined;
698
+ }
699
+ if (additionalArgsA.module_dependencies.length !== additionalArgsB.module_dependencies.length) {
700
+ return undefined;
701
+ }
702
+ for (const modDep of additionalArgsA.module_dependencies) {
703
+ if (!additionalArgsB.module_dependencies.includes(modDep)) {
704
+ return undefined;
705
+ }
706
+ }
707
+ }
708
+ }
709
+ else if (typeof additionalArgsB !== 'string' || additionalArgsA !== additionalArgsB) {
710
+ return undefined;
711
+ }
712
+ const depsA = optionsA.computedHandleArguments[0];
713
+ const depsB = optionsB.computedHandleArguments[0];
714
+ if (depsA.length !== depsB.length) {
715
+ return undefined;
716
+ }
717
+ //TODO: Maybe account for import potentially being undefined?
718
+ for (const dep of depsA) {
719
+ if (typeof dep === 'string') {
720
+ if (!depsB.includes(dep)) {
721
+ return undefined;
722
+ }
723
+ }
724
+ else {
725
+ if (!depsB.find(v => v === dep || (typeof v !== 'string' && dep.id === v.id && dep.import === v.import))) {
726
+ return undefined;
727
+ }
728
+ }
729
+ }
730
+ if (optionsA.locations.register !== optionsB.locations.register) {
731
+ return undefined; //TODO: Maybe make this more granular?
732
+ }
733
+ for (const standardLocation of (0, utils_1.constantKeys)(api_1.standardLocationNamesMeta)) {
734
+ if (!(0, api_1.isLocationNameWithActionSupport)(standardLocation)) {
735
+ if (optionsA.locations[standardLocation] !== optionsB.locations[standardLocation]) {
736
+ return undefined;
737
+ }
738
+ continue;
739
+ }
740
+ const locA = optionsA.locations[standardLocation];
741
+ const locB = optionsB.locations[standardLocation];
742
+ if (locA === locB) {
743
+ continue;
744
+ }
745
+ // This works because if they were BOTH undefined, the prior condition would have been hit, and this, therefore, would have been skipped
746
+ if (locA === undefined || locB === undefined) {
747
+ return undefined;
748
+ }
749
+ const [locAHookNames, locAPriority] = (0, api_1.convertHookLocationToNamesAndPriority)(locA);
750
+ const [locBHookNames, locBPriority] = (0, api_1.convertHookLocationToNamesAndPriority)(locB);
751
+ if (locAHookNames.length !== locBHookNames.length) {
752
+ return undefined;
753
+ }
754
+ if (locAHookNames.length > 0) {
755
+ for (const hookName of locAHookNames) {
756
+ if (!locBHookNames.includes(hookName)) {
757
+ return undefined;
758
+ }
759
+ }
760
+ }
761
+ if (locAPriority !== locBPriority) {
762
+ return 'dependent'; // We cannot merge hooks across priority boundaries, but we can have one require the other
763
+ }
764
+ }
765
+ return 'merged';
766
+ }
767
+ //# sourceMappingURL=RootCoordinatorPluginImpl.js.map