| 
									
										
										
										
											2018-07-23 20:53:50 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Florent Cailhol @ooflorent | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-05 04:05:17 +08:00
										 |  |  | const { ConcatSource } = require("webpack-sources"); | 
					
						
							| 
									
										
										
										
											2021-09-02 23:23:02 +08:00
										 |  |  | const makeSerializable = require("./util/makeSerializable"); | 
					
						
							| 
									
										
										
										
											2019-11-05 04:05:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-23 20:53:50 +08:00
										 |  |  | /** @typedef {import("webpack-sources").Source} Source */ | 
					
						
							| 
									
										
										
										
											2019-08-27 02:21:07 +08:00
										 |  |  | /** @typedef {import("./Generator").GenerateContext} GenerateContext */ | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  | /** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ | 
					
						
							|  |  |  | /** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ | 
					
						
							| 
									
										
										
										
											2018-07-23 20:53:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-05 04:05:17 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  |  * @template T | 
					
						
							|  |  |  |  * @param {InitFragment<T>} fragment the init fragment | 
					
						
							| 
									
										
										
										
											2019-11-05 04:05:17 +08:00
										 |  |  |  * @param {number} index index | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  |  * @returns {[InitFragment<T>, number]} tuple with both | 
					
						
							| 
									
										
										
										
											2019-11-05 04:05:17 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | const extractFragmentIndex = (fragment, index) => [fragment, index]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  |  * @template T | 
					
						
							|  |  |  |  * @param {[InitFragment<T>, number]} a first pair | 
					
						
							|  |  |  |  * @param {[InitFragment<T>, number]} b second pair | 
					
						
							| 
									
										
										
										
											2019-11-05 04:05:17 +08:00
										 |  |  |  * @returns {number} sort value | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const sortFragmentWithIndex = ([a, i], [b, j]) => { | 
					
						
							|  |  |  | 	const stageCmp = a.stage - b.stage; | 
					
						
							|  |  |  | 	if (stageCmp !== 0) return stageCmp; | 
					
						
							|  |  |  | 	const positionCmp = a.position - b.position; | 
					
						
							|  |  |  | 	if (positionCmp !== 0) return positionCmp; | 
					
						
							|  |  |  | 	return i - j; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-24 22:44:14 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2024-01-27 00:17:45 +08:00
										 |  |  |  * @template GenerateContext | 
					
						
							| 
									
										
										
										
											2021-06-24 22:44:14 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-07-23 20:53:50 +08:00
										 |  |  | class InitFragment { | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2024-03-18 01:15:44 +08:00
										 |  |  | 	 * @param {string | Source | undefined} content the source code that will be included as initialization code | 
					
						
							| 
									
										
										
										
											2018-07-30 18:09:42 +08:00
										 |  |  | 	 * @param {number} stage category of initialization code (contribute to order) | 
					
						
							|  |  |  | 	 * @param {number} position position in the category (contribute to order) | 
					
						
							|  |  |  | 	 * @param {string=} key unique key to avoid emitting the same initialization code twice | 
					
						
							| 
									
										
										
										
											2024-01-26 22:47:14 +08:00
										 |  |  | 	 * @param {string | Source=} endContent the source code that will be included at the end of the module | 
					
						
							| 
									
										
										
										
											2018-07-23 20:53:50 +08:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2019-05-23 02:11:16 +08:00
										 |  |  | 	constructor(content, stage, position, key, endContent) { | 
					
						
							| 
									
										
										
										
											2018-07-23 20:53:50 +08:00
										 |  |  | 		this.content = content; | 
					
						
							| 
									
										
										
										
											2018-07-30 16:15:18 +08:00
										 |  |  | 		this.stage = stage; | 
					
						
							| 
									
										
										
										
											2018-07-30 18:09:42 +08:00
										 |  |  | 		this.position = position; | 
					
						
							| 
									
										
										
										
											2018-07-23 20:53:50 +08:00
										 |  |  | 		this.key = key; | 
					
						
							| 
									
										
										
										
											2019-05-23 02:11:16 +08:00
										 |  |  | 		this.endContent = endContent; | 
					
						
							| 
									
										
										
										
											2018-07-23 20:53:50 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-08-23 20:07:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2024-01-27 00:17:45 +08:00
										 |  |  | 	 * @param {GenerateContext} context context | 
					
						
							| 
									
										
										
										
											2024-03-18 01:15:44 +08:00
										 |  |  | 	 * @returns {string | Source | undefined} the source code that will be included as initialization code | 
					
						
							| 
									
										
										
										
											2019-08-23 20:07:01 +08:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2021-06-24 22:44:14 +08:00
										 |  |  | 	getContent(context) { | 
					
						
							| 
									
										
										
										
											2019-08-23 20:07:01 +08:00
										 |  |  | 		return this.content; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2024-01-27 00:17:45 +08:00
										 |  |  | 	 * @param {GenerateContext} context context | 
					
						
							| 
									
										
										
										
											2025-03-27 08:07:25 +08:00
										 |  |  | 	 * @returns {string | Source=} the source code that will be included at the end of the module | 
					
						
							| 
									
										
										
										
											2019-08-23 20:07:01 +08:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2021-06-24 22:44:14 +08:00
										 |  |  | 	getEndContent(context) { | 
					
						
							| 
									
										
										
										
											2019-08-23 20:07:01 +08:00
										 |  |  | 		return this.endContent; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-11-05 04:05:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @template Context | 
					
						
							|  |  |  | 	 * @template T | 
					
						
							|  |  |  | 	 * @param {Source} source sources | 
					
						
							|  |  |  | 	 * @param {InitFragment<T>[]} initFragments init fragments | 
					
						
							|  |  |  | 	 * @param {Context} context context | 
					
						
							|  |  |  | 	 * @returns {Source} source | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2021-06-24 22:44:14 +08:00
										 |  |  | 	static addToSource(source, initFragments, context) { | 
					
						
							| 
									
										
										
										
											2019-11-05 04:05:17 +08:00
										 |  |  | 		if (initFragments.length > 0) { | 
					
						
							|  |  |  | 			// Sort fragments by position. If 2 fragments have the same position,
 | 
					
						
							|  |  |  | 			// use their index.
 | 
					
						
							|  |  |  | 			const sortedFragments = initFragments | 
					
						
							|  |  |  | 				.map(extractFragmentIndex) | 
					
						
							|  |  |  | 				.sort(sortFragmentWithIndex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// Deduplicate fragments. If a fragment has no key, it is always included.
 | 
					
						
							|  |  |  | 			const keyedFragments = new Map(); | 
					
						
							|  |  |  | 			for (const [fragment] of sortedFragments) { | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  | 				if ( | 
					
						
							|  |  |  | 					typeof ( | 
					
						
							| 
									
										
										
										
											2024-01-26 22:47:14 +08:00
										 |  |  | 						/** @type {InitFragment<T> & { mergeAll?: (fragments: InitFragment<Context>[]) => InitFragment<Context>[] }} */ | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  | 						(fragment).mergeAll | 
					
						
							|  |  |  | 					) === "function" | 
					
						
							|  |  |  | 				) { | 
					
						
							| 
									
										
										
										
											2021-04-27 20:01:22 +08:00
										 |  |  | 					if (!fragment.key) { | 
					
						
							|  |  |  | 						throw new Error( | 
					
						
							|  |  |  | 							`InitFragment with mergeAll function must have a valid key: ${fragment.constructor.name}` | 
					
						
							|  |  |  | 						); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					const oldValue = keyedFragments.get(fragment.key); | 
					
						
							|  |  |  | 					if (oldValue === undefined) { | 
					
						
							|  |  |  | 						keyedFragments.set(fragment.key, fragment); | 
					
						
							|  |  |  | 					} else if (Array.isArray(oldValue)) { | 
					
						
							|  |  |  | 						oldValue.push(fragment); | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						keyedFragments.set(fragment.key, [oldValue, fragment]); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					continue; | 
					
						
							|  |  |  | 				} else if (typeof fragment.merge === "function") { | 
					
						
							| 
									
										
										
										
											2019-11-05 04:05:17 +08:00
										 |  |  | 					const oldValue = keyedFragments.get(fragment.key); | 
					
						
							|  |  |  | 					if (oldValue !== undefined) { | 
					
						
							| 
									
										
										
										
											2021-04-27 20:01:22 +08:00
										 |  |  | 						keyedFragments.set(fragment.key, fragment.merge(oldValue)); | 
					
						
							| 
									
										
										
										
											2019-11-05 04:05:17 +08:00
										 |  |  | 						continue; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2024-07-31 09:37:24 +08:00
										 |  |  | 				keyedFragments.set(fragment.key || Symbol("fragment key"), fragment); | 
					
						
							| 
									
										
										
										
											2019-11-05 04:05:17 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			const concatSource = new ConcatSource(); | 
					
						
							|  |  |  | 			const endContents = []; | 
					
						
							| 
									
										
										
										
											2021-04-27 20:01:22 +08:00
										 |  |  | 			for (let fragment of keyedFragments.values()) { | 
					
						
							|  |  |  | 				if (Array.isArray(fragment)) { | 
					
						
							|  |  |  | 					fragment = fragment[0].mergeAll(fragment); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2021-06-24 22:44:14 +08:00
										 |  |  | 				concatSource.add(fragment.getContent(context)); | 
					
						
							|  |  |  | 				const endContent = fragment.getEndContent(context); | 
					
						
							| 
									
										
										
										
											2019-11-05 04:05:17 +08:00
										 |  |  | 				if (endContent) { | 
					
						
							|  |  |  | 					endContents.push(endContent); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			concatSource.add(source); | 
					
						
							|  |  |  | 			for (const content of endContents.reverse()) { | 
					
						
							|  |  |  | 				concatSource.add(content); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return concatSource; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-07-31 04:21:27 +08:00
										 |  |  | 		return source; | 
					
						
							| 
									
										
										
										
											2019-11-05 04:05:17 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-09-02 23:23:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {ObjectSerializerContext} context context | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2021-09-02 23:23:02 +08:00
										 |  |  | 	serialize(context) { | 
					
						
							|  |  |  | 		const { write } = context; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		write(this.content); | 
					
						
							|  |  |  | 		write(this.stage); | 
					
						
							|  |  |  | 		write(this.position); | 
					
						
							|  |  |  | 		write(this.key); | 
					
						
							|  |  |  | 		write(this.endContent); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {ObjectDeserializerContext} context context | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2021-09-02 23:23:02 +08:00
										 |  |  | 	deserialize(context) { | 
					
						
							|  |  |  | 		const { read } = context; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		this.content = read(); | 
					
						
							|  |  |  | 		this.stage = read(); | 
					
						
							|  |  |  | 		this.position = read(); | 
					
						
							|  |  |  | 		this.key = read(); | 
					
						
							|  |  |  | 		this.endContent = read(); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-07-23 20:53:50 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-02 23:23:02 +08:00
										 |  |  | makeSerializable(InitFragment, "webpack/lib/InitFragment"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | InitFragment.prototype.merge = | 
					
						
							|  |  |  | 	/** @type {TODO} */ | 
					
						
							|  |  |  | 	(undefined); | 
					
						
							| 
									
										
										
										
											2019-05-23 02:11:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-30 16:15:18 +08:00
										 |  |  | InitFragment.STAGE_CONSTANTS = 10; | 
					
						
							| 
									
										
										
										
											2019-06-05 20:17:15 +08:00
										 |  |  | InitFragment.STAGE_ASYNC_BOUNDARY = 20; | 
					
						
							|  |  |  | InitFragment.STAGE_HARMONY_EXPORTS = 30; | 
					
						
							|  |  |  | InitFragment.STAGE_HARMONY_IMPORTS = 40; | 
					
						
							|  |  |  | InitFragment.STAGE_PROVIDES = 50; | 
					
						
							|  |  |  | InitFragment.STAGE_ASYNC_DEPENDENCIES = 60; | 
					
						
							| 
									
										
										
										
											2020-05-15 22:24:11 +08:00
										 |  |  | InitFragment.STAGE_ASYNC_HARMONY_IMPORTS = 70; | 
					
						
							| 
									
										
										
										
											2018-07-30 16:15:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-23 20:53:50 +08:00
										 |  |  | module.exports = InitFragment; |