source: frontend/node_modules/webpack/lib/InitFragment.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 7.0 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Florent Cailhol @ooflorent
4*/
5
6"use strict";
7
8const { ConcatSource } = require("webpack-sources");
9const makeSerializable = require("./util/makeSerializable");
10
11/** @typedef {import("webpack-sources").Source} Source */
12/** @typedef {import("./Generator").GenerateContext} GenerateContext */
13/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
14/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
15
16/** @typedef {string} InitFragmentKey */
17
18/**
19 * Defines the maybe mergeable init fragment type used by this module.
20 * @template GenerateContext
21 * @typedef {object} MaybeMergeableInitFragment
22 * @property {InitFragmentKey=} key
23 * @property {number} stage
24 * @property {number} position
25 * @property {(context: GenerateContext) => string | Source | undefined} getContent
26 * @property {(context: GenerateContext) => string | Source | undefined} getEndContent
27 * @property {(fragments: MaybeMergeableInitFragment<GenerateContext>) => MaybeMergeableInitFragment<GenerateContext>=} merge
28 * @property {(fragments: MaybeMergeableInitFragment<GenerateContext>[]) => MaybeMergeableInitFragment<GenerateContext>[]=} mergeAll
29 */
30
31/**
32 * Extract fragment index.
33 * @template T
34 * @param {T} fragment the init fragment
35 * @param {number} index index
36 * @returns {[T, number]} tuple with both
37 */
38const extractFragmentIndex = (fragment, index) => [fragment, index];
39
40/**
41 * Sorts fragment with index.
42 * @template T
43 * @param {[MaybeMergeableInitFragment<T>, number]} a first pair
44 * @param {[MaybeMergeableInitFragment<T>, number]} b second pair
45 * @returns {number} sort value
46 */
47const sortFragmentWithIndex = ([a, i], [b, j]) => {
48 const stageCmp = a.stage - b.stage;
49 if (stageCmp !== 0) return stageCmp;
50 const positionCmp = a.position - b.position;
51 if (positionCmp !== 0) return positionCmp;
52 return i - j;
53};
54
55/**
56 * Represents InitFragment.
57 * @template GenerateContext
58 * @implements {MaybeMergeableInitFragment<GenerateContext>}
59 */
60class InitFragment {
61 /**
62 * Creates an instance of InitFragment.
63 * @param {string | Source | undefined} content the source code that will be included as initialization code
64 * @param {number} stage category of initialization code (contribute to order)
65 * @param {number} position position in the category (contribute to order)
66 * @param {InitFragmentKey=} key unique key to avoid emitting the same initialization code twice
67 * @param {string | Source=} endContent the source code that will be included at the end of the module
68 */
69 constructor(content, stage, position, key, endContent) {
70 this.content = content;
71 this.stage = stage;
72 this.position = position;
73 this.key = key;
74 this.endContent = endContent;
75 }
76
77 /**
78 * Returns the source code that will be included as initialization code.
79 * @param {GenerateContext} context context
80 * @returns {string | Source | undefined} the source code that will be included as initialization code
81 */
82 getContent(context) {
83 return this.content;
84 }
85
86 /**
87 * Returns the source code that will be included at the end of the module.
88 * @param {GenerateContext} context context
89 * @returns {string | Source | undefined} the source code that will be included at the end of the module
90 */
91 getEndContent(context) {
92 return this.endContent;
93 }
94
95 /**
96 * Adds the provided source to the init fragment.
97 * @template Context
98 * @param {Source} source sources
99 * @param {MaybeMergeableInitFragment<Context>[]} initFragments init fragments
100 * @param {Context} context context
101 * @returns {Source} source
102 */
103 static addToSource(source, initFragments, context) {
104 if (initFragments.length > 0) {
105 // Sort fragments by position. If 2 fragments have the same position,
106 // use their index.
107 const sortedFragments = initFragments
108 .map(extractFragmentIndex)
109 .sort(sortFragmentWithIndex);
110
111 // Deduplicate fragments. If a fragment has no key, it is always included.
112 /** @type {Map<InitFragmentKey | symbol, MaybeMergeableInitFragment<Context> | MaybeMergeableInitFragment<Context>[]>} */
113 const keyedFragments = new Map();
114 for (const [fragment] of sortedFragments) {
115 if (typeof fragment.mergeAll === "function") {
116 if (!fragment.key) {
117 throw new Error(
118 `InitFragment with mergeAll function must have a valid key: ${fragment.constructor.name}`
119 );
120 }
121 const oldValue = keyedFragments.get(fragment.key);
122 if (oldValue === undefined) {
123 keyedFragments.set(fragment.key, fragment);
124 } else if (Array.isArray(oldValue)) {
125 oldValue.push(fragment);
126 } else {
127 keyedFragments.set(fragment.key, [oldValue, fragment]);
128 }
129 continue;
130 } else if (typeof fragment.merge === "function") {
131 const key = /** @type {InitFragmentKey} */ (fragment.key);
132 const oldValue =
133 /** @type {MaybeMergeableInitFragment<Context>} */
134 (keyedFragments.get(key));
135 if (oldValue !== undefined) {
136 keyedFragments.set(key, fragment.merge(oldValue));
137 continue;
138 }
139 }
140 keyedFragments.set(fragment.key || Symbol("fragment key"), fragment);
141 }
142
143 const concatSource = new ConcatSource();
144 /** @type {(string | Source)[]} */
145 const endContents = [];
146 for (let fragment of keyedFragments.values()) {
147 if (Array.isArray(fragment)) {
148 fragment =
149 /** @type {[MaybeMergeableInitFragment<Context> & { mergeAll: (fragments: MaybeMergeableInitFragment<Context>[]) => MaybeMergeableInitFragment<Context>[] }, ...MaybeMergeableInitFragment<Context>[]]} */
150 (fragment)[0].mergeAll(fragment);
151 }
152 const content =
153 /** @type {MaybeMergeableInitFragment<Context>} */
154 (fragment).getContent(context);
155 if (content) {
156 concatSource.add(content);
157 }
158 const endContent =
159 /** @type {MaybeMergeableInitFragment<Context>} */
160 (fragment).getEndContent(context);
161 if (endContent) {
162 endContents.push(endContent);
163 }
164 }
165
166 concatSource.add(source);
167 for (const content of endContents.reverse()) {
168 concatSource.add(content);
169 }
170 return concatSource;
171 }
172 return source;
173 }
174
175 /**
176 * Serializes this instance into the provided serializer context.
177 * @param {ObjectSerializerContext} context context
178 */
179 serialize(context) {
180 const { write } = context;
181
182 write(this.content);
183 write(this.stage);
184 write(this.position);
185 write(this.key);
186 write(this.endContent);
187 }
188
189 /**
190 * Restores this instance from the provided deserializer context.
191 * @param {ObjectDeserializerContext} context context
192 */
193 deserialize(context) {
194 const { read } = context;
195
196 this.content = read();
197 this.stage = read();
198 this.position = read();
199 this.key = read();
200 this.endContent = read();
201 }
202}
203
204makeSerializable(InitFragment, "webpack/lib/InitFragment");
205
206InitFragment.STAGE_CONSTANTS = 10;
207InitFragment.STAGE_ASYNC_BOUNDARY = 20;
208InitFragment.STAGE_HARMONY_EXPORTS = 30;
209InitFragment.STAGE_HARMONY_IMPORTS = 40;
210InitFragment.STAGE_PROVIDES = 50;
211InitFragment.STAGE_ASYNC_DEPENDENCIES = 60;
212InitFragment.STAGE_ASYNC_HARMONY_IMPORTS = 70;
213
214module.exports = InitFragment;
Note: See TracBrowser for help on using the repository browser.