@depup/webpack-sources 3.3.4-depup.0 → 3.6.0-depup.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 (53) hide show
  1. package/README.md +2 -2
  2. package/changes.json +1 -1
  3. package/lib/CachedSource.js +257 -63
  4. package/lib/CompatSource.js +42 -1
  5. package/lib/ConcatSource.js +100 -28
  6. package/lib/OriginalSource.js +111 -45
  7. package/lib/PrefixSource.js +60 -11
  8. package/lib/RawSource.js +85 -29
  9. package/lib/ReplaceSource.js +269 -73
  10. package/lib/SizeOnlySource.js +10 -1
  11. package/lib/Source.js +39 -0
  12. package/lib/SourceMapSource.js +92 -10
  13. package/lib/helpers/createMappingsSerializer.js +307 -54
  14. package/lib/helpers/getFromStreamChunks.js +165 -73
  15. package/lib/helpers/getGeneratedSourceInfo.js +7 -4
  16. package/lib/helpers/readMappings.js +6 -3
  17. package/lib/helpers/scopes.js +438 -0
  18. package/lib/helpers/splitIntoLines.js +10 -9
  19. package/lib/helpers/splitIntoPotentialTokens.js +99 -26
  20. package/lib/helpers/streamAndGetSourceAndMap.js +61 -22
  21. package/lib/helpers/streamChunks.js +3 -2
  22. package/lib/helpers/streamChunksOfCombinedSourceMap.js +7 -3
  23. package/lib/helpers/streamChunksOfRawSource.js +23 -15
  24. package/lib/helpers/streamChunksOfSourceMap.js +50 -42
  25. package/lib/index.js +3 -0
  26. package/package.json +34 -23
  27. package/types/CachedSource.d.ts +192 -0
  28. package/types/CompatSource.d.ts +87 -0
  29. package/types/ConcatSource.d.ts +75 -0
  30. package/types/OriginalSource.d.ts +87 -0
  31. package/types/PrefixSource.d.ts +59 -0
  32. package/types/RawSource.d.ts +75 -0
  33. package/types/ReplaceSource.d.ts +107 -0
  34. package/types/SizeOnlySource.d.ts +24 -0
  35. package/types/Source.d.ts +189 -0
  36. package/types/SourceMapSource.d.ts +136 -0
  37. package/types/helpers/createMappingsSerializer.d.ts +60 -0
  38. package/types/helpers/getFromStreamChunks.d.ts +16 -0
  39. package/types/helpers/getGeneratedSourceInfo.d.ts +31 -0
  40. package/types/helpers/getName.d.ts +15 -0
  41. package/types/helpers/getSource.d.ts +15 -0
  42. package/types/helpers/readMappings.d.ts +19 -0
  43. package/types/helpers/scopes.d.ts +119 -0
  44. package/types/helpers/splitIntoLines.d.ts +6 -0
  45. package/types/helpers/splitIntoPotentialTokens.d.ts +37 -0
  46. package/types/helpers/streamAndGetSourceAndMap.d.ts +39 -0
  47. package/types/helpers/streamChunks.d.ts +56 -0
  48. package/types/helpers/streamChunksOfCombinedSourceMap.d.ts +42 -0
  49. package/types/helpers/streamChunksOfRawSource.d.ts +16 -0
  50. package/types/helpers/streamChunksOfSourceMap.d.ts +19 -0
  51. package/types/helpers/stringBufferUtils.d.ts +55 -0
  52. package/types/index.d.ts +50 -0
  53. package/types.d.ts +42 -439
@@ -5,7 +5,7 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const createMappingsSerializer = require("./createMappingsSerializer");
8
+ const { createMappingsWriter } = require("./createMappingsSerializer");
9
9
 
10
10
  /** @typedef {import("../Source").RawSourceMap} RawSourceMap */
11
11
  /** @typedef {import("../Source").SourceAndMap} SourceAndMap */
@@ -14,73 +14,141 @@ const createMappingsSerializer = require("./createMappingsSerializer");
14
14
 
15
15
  /** @typedef {{ streamChunks: StreamChunksFunction }} SourceLikeWithStreamChunks */
16
16
 
17
+ /** @type {typeof import("./scopes") | undefined} */
18
+ let scopesHelpers;
19
+
20
+ /**
21
+ * Loads the scopes helpers on first use. They are only reachable through the
22
+ * `scopes` option, so requiring them eagerly would put the encoder in the
23
+ * module graph of every caller that never asks for the field.
24
+ * @returns {ReturnType<typeof import("./scopes").createScopesWriter>} writer
25
+ */
26
+ const createScopesWriter = () => {
27
+ if (scopesHelpers === undefined) scopesHelpers = require("./scopes");
28
+ return scopesHelpers.createScopesWriter();
29
+ };
30
+
31
+ /**
32
+ * Assign `value` at index `i` of `arr`, padding earlier slots with `null`.
33
+ * Hoisted helper so `getMap` and `getSourceAndMap` share one
34
+ * implementation. Uses `push` rather than `arr.length = i + 1` because the
35
+ * latter forces V8's HOLEY_ELEMENTS kind permanently — push keeps the
36
+ * backing store PACKED, which the downstream source-map serializer iterates
37
+ * over far more efficiently.
38
+ * @template T
39
+ * @param {(T | null)[]} arr destination array
40
+ * @param {number} i index to assign
41
+ * @param {T} value value to assign
42
+ * @returns {void}
43
+ */
44
+ const setAtIndex = (arr, i, value) => {
45
+ while (arr.length < i) arr.push(null);
46
+ // `arr[i] = value` where `i === arr.length` extends the array exactly
47
+ // like `push` (V8 keeps PACKED_ELEMENTS); after the while-loop
48
+ // `i <= arr.length` always, so the hole case that would force HOLEY is
49
+ // impossible here.
50
+ arr[i] = value;
51
+ };
52
+
17
53
  /**
18
54
  * @param {SourceLikeWithStreamChunks} source source
19
55
  * @param {Options=} options options
20
56
  * @returns {RawSourceMap | null} map
21
57
  */
22
58
  module.exports.getMap = (source, options) => {
23
- let mappings = "";
24
59
  /** @type {(string | null)[]} */
25
60
  const potentialSources = [];
26
61
  /** @type {(string | null)[]} */
27
62
  const potentialSourcesContent = [];
28
63
  /** @type {(string | null)[]} */
29
64
  const potentialNames = [];
30
- const addMapping = createMappingsSerializer(options);
31
- source.streamChunks(
65
+ const mappingsWriter = createMappingsWriter(options);
66
+ const addMapping = mappingsWriter.add;
67
+ const scopesWriter =
68
+ options && options.scopes ? createScopesWriter() : undefined;
69
+ // Chosen once rather than tested per segment: this callback is the whole of
70
+ // the mapping loop, so a branch in it is measurable on every map built.
71
+ const generated = source.streamChunks(
32
72
  { ...options, source: false, finalSource: true },
33
- (
34
- chunk,
35
- generatedLine,
36
- generatedColumn,
37
- sourceIndex,
38
- originalLine,
39
- originalColumn,
40
- nameIndex,
41
- ) => {
42
- mappings += addMapping(
43
- generatedLine,
44
- generatedColumn,
45
- sourceIndex,
46
- originalLine,
47
- originalColumn,
48
- nameIndex,
49
- );
50
- },
51
- (sourceIndex, source, sourceContent) => {
52
- while (potentialSources.length < sourceIndex) {
53
- potentialSources.push(null);
54
- }
55
- potentialSources[sourceIndex] = source;
56
- if (sourceContent !== undefined) {
57
- while (potentialSourcesContent.length < sourceIndex) {
58
- potentialSourcesContent.push(null);
73
+ scopesWriter === undefined
74
+ ? (
75
+ chunk,
76
+ generatedLine,
77
+ generatedColumn,
78
+ sourceIndex,
79
+ originalLine,
80
+ originalColumn,
81
+ nameIndex,
82
+ ) => {
83
+ addMapping(
84
+ generatedLine,
85
+ generatedColumn,
86
+ sourceIndex,
87
+ originalLine,
88
+ originalColumn,
89
+ nameIndex,
90
+ );
59
91
  }
60
- potentialSourcesContent[sourceIndex] = sourceContent;
92
+ : (
93
+ chunk,
94
+ generatedLine,
95
+ generatedColumn,
96
+ sourceIndex,
97
+ originalLine,
98
+ originalColumn,
99
+ nameIndex,
100
+ ) => {
101
+ addMapping(
102
+ generatedLine,
103
+ generatedColumn,
104
+ sourceIndex,
105
+ originalLine,
106
+ originalColumn,
107
+ nameIndex,
108
+ );
109
+ scopesWriter.add(
110
+ generatedLine,
111
+ generatedColumn,
112
+ sourceIndex,
113
+ originalLine,
114
+ );
115
+ },
116
+ (sourceIndex, source, sourceContent, scopeBindings) => {
117
+ setAtIndex(potentialSources, sourceIndex, source);
118
+ if (sourceContent !== undefined) {
119
+ setAtIndex(potentialSourcesContent, sourceIndex, sourceContent);
120
+ }
121
+ if (scopesWriter !== undefined) {
122
+ scopesWriter.addSource(sourceIndex, scopeBindings);
61
123
  }
62
124
  },
63
125
  (nameIndex, name) => {
64
- while (potentialNames.length < nameIndex) {
65
- potentialNames.push(null);
66
- }
67
- potentialNames[nameIndex] = name;
126
+ setAtIndex(potentialNames, nameIndex, name);
68
127
  },
69
128
  );
70
- return mappings.length > 0
71
- ? {
72
- version: 3,
73
- file: "x",
74
- mappings,
75
- // We handle broken sources as `null`, in spec this field should be string, but no information what we should do in such cases if we change type it will be breaking change
76
- sources: /** @type {string[]} */ (potentialSources),
77
- sourcesContent:
78
- potentialSourcesContent.length > 0
79
- ? /** @type {string[]} */ (potentialSourcesContent)
80
- : undefined,
81
- names: /** @type {string[]} */ (potentialNames),
82
- }
83
- : null;
129
+ const mappings = mappingsWriter.finish();
130
+ if (mappings.length === 0) return null;
131
+ /** @type {RawSourceMap} */
132
+ const map = {
133
+ version: 3,
134
+ file: "x",
135
+ mappings,
136
+ // We handle broken sources as `null`, in spec this field should be string, but no information what we should do in such cases if we change type it will be breaking change
137
+ sources: /** @type {string[]} */ (potentialSources),
138
+ sourcesContent:
139
+ potentialSourcesContent.length > 0
140
+ ? /** @type {string[]} */ (potentialSourcesContent)
141
+ : undefined,
142
+ names: /** @type {string[]} */ (potentialNames),
143
+ };
144
+ if (scopesWriter !== undefined) {
145
+ scopesWriter.finish(
146
+ map,
147
+ generated.generatedLine,
148
+ generated.generatedColumn,
149
+ );
150
+ }
151
+ return map;
84
152
  };
85
153
 
86
154
  /**
@@ -90,16 +158,21 @@ module.exports.getMap = (source, options) => {
90
158
  */
91
159
  module.exports.getSourceAndMap = (inputSource, options) => {
92
160
  let code = "";
93
- let mappings = "";
94
161
  /** @type {(string | null)[]} */
95
162
  const potentialSources = [];
96
163
  /** @type {(string | null)[]} */
97
164
  const potentialSourcesContent = [];
98
165
  /** @type {(string | null)[]} */
99
166
  const potentialNames = [];
100
- const addMapping = createMappingsSerializer(options);
101
- const { source } = inputSource.streamChunks(
102
- { ...options, finalSource: true },
167
+ const mappingsWriter = createMappingsWriter(options);
168
+ const addMapping = mappingsWriter.add;
169
+ const scopesWriter =
170
+ options && options.scopes ? createScopesWriter() : undefined;
171
+ const generated = inputSource.streamChunks(
172
+ // `source: true` overrides any `source: false` a caller forwarded
173
+ // (e.g. the streamChunks fallback passing getMap options through
174
+ // sourceAndMap) — this helper always consumes the source.
175
+ { ...options, finalSource: true, source: true },
103
176
  (
104
177
  chunk,
105
178
  generatedLine,
@@ -110,7 +183,7 @@ module.exports.getSourceAndMap = (inputSource, options) => {
110
183
  nameIndex,
111
184
  ) => {
112
185
  if (chunk !== undefined) code += chunk;
113
- mappings += addMapping(
186
+ addMapping(
114
187
  generatedLine,
115
188
  generatedColumn,
116
189
  sourceIndex,
@@ -118,8 +191,19 @@ module.exports.getSourceAndMap = (inputSource, options) => {
118
191
  originalColumn,
119
192
  nameIndex,
120
193
  );
194
+ if (scopesWriter !== undefined) {
195
+ scopesWriter.add(
196
+ generatedLine,
197
+ generatedColumn,
198
+ sourceIndex,
199
+ originalLine,
200
+ );
201
+ }
121
202
  },
122
- (sourceIndex, source, sourceContent) => {
203
+ (sourceIndex, source, sourceContent, scopeBindings) => {
204
+ if (scopesWriter !== undefined) {
205
+ scopesWriter.addSource(sourceIndex, scopeBindings);
206
+ }
123
207
  while (potentialSources.length < sourceIndex) {
124
208
  potentialSources.push(null);
125
209
  }
@@ -138,22 +222,30 @@ module.exports.getSourceAndMap = (inputSource, options) => {
138
222
  potentialNames[nameIndex] = name;
139
223
  },
140
224
  );
141
- return {
142
- source: source !== undefined ? source : code,
143
- map:
144
- mappings.length > 0
145
- ? {
146
- version: 3,
147
- file: "x",
148
- mappings,
149
- // We handle broken sources as `null`, in spec this field should be string, but no information what we should do in such cases if we change type it will be breaking change
150
- sources: /** @type {string[]} */ (potentialSources),
151
- sourcesContent:
152
- potentialSourcesContent.length > 0
153
- ? /** @type {string[]} */ (potentialSourcesContent)
154
- : undefined,
155
- names: /** @type {string[]} */ (potentialNames),
156
- }
157
- : null,
158
- };
225
+ const mappings = mappingsWriter.finish();
226
+ const { source } = generated;
227
+ /** @type {RawSourceMap | null} */
228
+ let map = null;
229
+ if (mappings.length > 0) {
230
+ map = {
231
+ version: 3,
232
+ file: "x",
233
+ mappings,
234
+ // We handle broken sources as `null`, in spec this field should be string, but no information what we should do in such cases if we change type it will be breaking change
235
+ sources: /** @type {string[]} */ (potentialSources),
236
+ sourcesContent:
237
+ potentialSourcesContent.length > 0
238
+ ? /** @type {string[]} */ (potentialSourcesContent)
239
+ : undefined,
240
+ names: /** @type {string[]} */ (potentialNames),
241
+ };
242
+ if (scopesWriter !== undefined) {
243
+ scopesWriter.finish(
244
+ map,
245
+ generated.generatedLine,
246
+ generated.generatedColumn,
247
+ );
248
+ }
249
+ }
250
+ return { source: source !== undefined ? source : code, map };
159
251
  };
@@ -5,8 +5,6 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const CHAR_CODE_NEW_LINE = "\n".charCodeAt(0);
9
-
10
8
  /**
11
9
  * @typedef {object} GeneratedSourceInfo
12
10
  * @property {number=} generatedLine generated line
@@ -30,9 +28,14 @@ const getGeneratedSourceInfo = (source) => {
30
28
  source,
31
29
  };
32
30
  }
31
+ // Use native indexOf to scan for newlines instead of charCodeAt loops.
32
+ // This is significantly faster on large sources since indexOf uses
33
+ // vectorized/native string scanning.
33
34
  let generatedLine = 2;
34
- for (let i = 0; i < lastLineStart; i++) {
35
- if (source.charCodeAt(i) === CHAR_CODE_NEW_LINE) generatedLine++;
35
+ let idx = source.indexOf("\n");
36
+ while (idx !== -1 && idx < lastLineStart) {
37
+ generatedLine++;
38
+ idx = source.indexOf("\n", idx + 1);
36
39
  }
37
40
  return {
38
41
  generatedLine,
@@ -35,8 +35,8 @@ const ccMax = ccToValue.length - 1;
35
35
  * @returns {void}
36
36
  */
37
37
  const readMappings = (mappings, onMapping) => {
38
- // generatedColumn, [sourceIndex, originalLine, orignalColumn, [nameIndex]]
39
- const currentData = new Uint32Array([0, 0, 1, 0, 0]);
38
+ // generatedColumn, [sourceIndex, originalLine, originalColumn, [nameIndex]]
39
+ const currentData = new Int32Array([0, 0, 1, 0, 0]);
40
40
  let currentDataPos = 0;
41
41
  // currentValue will include a sign bit at bit 0
42
42
  let currentValue = 0;
@@ -71,7 +71,10 @@ const readMappings = (mappings, onMapping) => {
71
71
  currentData[4],
72
72
  );
73
73
  }
74
- [generatedColumn] = currentData;
74
+ // Direct typed-array index is faster here than destructuring,
75
+ // which would invoke the Int32Array iterator protocol.
76
+ // eslint-disable-next-line prefer-destructuring
77
+ generatedColumn = currentData[0];
75
78
  }
76
79
  currentDataPos = 0;
77
80
  if (value === NEXT_LINE) {