@atlaspack/core 2.33.0 → 2.34.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.
@@ -20,7 +20,7 @@ function _diagnostic() {
20
20
  return data;
21
21
  }
22
22
  function _logger() {
23
- const data = require("@atlaspack/logger");
23
+ const data = _interopRequireWildcard(require("@atlaspack/logger"));
24
24
  _logger = function () {
25
25
  return data;
26
26
  };
@@ -39,13 +39,15 @@ var _SymbolPropagation = require("../SymbolPropagation");
39
39
  var _EnvironmentManager = require("../EnvironmentManager");
40
40
  var _Environment = require("../Environment");
41
41
  var _dumpGraphToGraphViz = _interopRequireDefault(require("../dumpGraphToGraphViz"));
42
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
43
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
42
44
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
43
45
  function createAssetGraphRequestRust(rustAtlaspack) {
44
46
  return input => ({
45
47
  type: _RequestTracker.requestTypes.asset_graph_request,
46
48
  id: input.name,
47
- run: async input => {
48
- let options = input.options;
49
+ run: async runInput => {
50
+ let options = runInput.options;
49
51
  let {
50
52
  assetGraphPromise,
51
53
  commitPromise
@@ -60,7 +62,7 @@ function createAssetGraphRequestRust(rustAtlaspack) {
60
62
  // Don't reuse a previous asset graph result if Rust didn't have one too
61
63
  let prevResult = null;
62
64
  if (serializedAssetGraph.hadPreviousGraph) {
63
- prevResult = await input.api.getPreviousResult();
65
+ prevResult = await runInput.api.getPreviousResult();
64
66
  }
65
67
  let {
66
68
  assetGraph,
@@ -70,20 +72,28 @@ function createAssetGraphRequestRust(rustAtlaspack) {
70
72
  return getAssetGraph(serializedAssetGraph, (_prevResult = prevResult) === null || _prevResult === void 0 ? void 0 : _prevResult.assetGraph);
71
73
  });
72
74
  let changedAssetsPropagation = new Set(changedAssets.keys());
73
- let errors = (0, _SymbolPropagation.propagateSymbols)({
74
- options,
75
- assetGraph,
76
- changedAssetsPropagation,
77
- assetGroupsWithRemovedParents: new Set(),
78
- previousErrors: new Map() //this.previousSymbolPropagationErrors,
79
- });
80
-
81
- if (errors.size > 0) {
82
- // Just throw the first error. Since errors can bubble (e.g. reexporting a reexported symbol also fails),
83
- // determining which failing export is the root cause is nontrivial (because of circular dependencies).
84
- throw new (_diagnostic().default)({
85
- diagnostic: [...errors.values()][0]
75
+ // Skip symbol propagation for runtime assets - they have pre-computed symbol data
76
+ if (input.skipSymbolProp) {
77
+ _logger().default.verbose({
78
+ origin: '@atlaspack/core',
79
+ message: 'Skipping symbol propagation for runtime asset graph'
80
+ });
81
+ } else {
82
+ let errors = (0, _SymbolPropagation.propagateSymbols)({
83
+ options,
84
+ assetGraph,
85
+ changedAssetsPropagation,
86
+ assetGroupsWithRemovedParents: new Set(),
87
+ previousErrors: new Map() //this.previousSymbolPropagationErrors,
86
88
  });
89
+
90
+ if (errors.size > 0) {
91
+ // Just throw the first error. Since errors can bubble (e.g. reexporting a reexported symbol also fails),
92
+ // determining which failing export is the root cause is nontrivial (because of circular dependencies).
93
+ throw new (_diagnostic().default)({
94
+ diagnostic: [...errors.values()][0]
95
+ });
96
+ }
87
97
  }
88
98
  await (0, _dumpGraphToGraphViz.default)(assetGraph, 'AssetGraphV3');
89
99
  let result = {
@@ -102,8 +112,8 @@ function createAssetGraphRequestRust(rustAtlaspack) {
102
112
  }
103
113
  });
104
114
  }
105
- await input.api.storeResult(result);
106
- input.api.invalidateOnBuild();
115
+ await runInput.api.storeResult(result);
116
+ runInput.api.invalidateOnBuild();
107
117
  return result;
108
118
  },
109
119
  input
@@ -253,6 +263,17 @@ function getAssetGraph(serializedGraph, prevAssetGraph) {
253
263
  }
254
264
  let usedSymbolsDown = new Set();
255
265
  let usedSymbolsUp = new Map();
266
+ if (node.used_symbols_up) {
267
+ for (let usedSymbol of node.used_symbols_up) {
268
+ // Transform Rust UsedSymbol { symbol: Symbol, asset: string }
269
+ // to JS format { symbol: string, asset: string } where symbol is the exported name
270
+ const exportedName = usedSymbol.symbol.exported;
271
+ usedSymbolsUp.set(exportedName, {
272
+ asset: usedSymbol.asset,
273
+ symbol: exportedName
274
+ });
275
+ }
276
+ }
256
277
  if (dependency.isEntry && dependency.isLibrary) {
257
278
  usedSymbolsDown.add('*');
258
279
  usedSymbolsUp.set('*', undefined);
@@ -136,7 +136,8 @@ function createBundleGraphRequest(input) {
136
136
  shouldBuildLazily: options.shouldBuildLazily,
137
137
  lazyIncludes: options.lazyIncludes,
138
138
  lazyExcludes: options.lazyExcludes,
139
- requestedAssetIds
139
+ requestedAssetIds,
140
+ skipSymbolProp: (0, _featureFlags().getFeatureFlag)('rustSymbolTracker')
140
141
  });
141
142
  let {
142
143
  assetGraph,
@@ -3,6 +3,8 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.applyReplacementsToSourceMap = applyReplacementsToSourceMap;
7
+ exports.computeSourceMapRoot = computeSourceMapRoot;
6
8
  exports.default = createWriteBundleRequest;
7
9
  var _constants = require("../constants");
8
10
  function _nullthrows() {
@@ -19,6 +21,13 @@ function _path() {
19
21
  };
20
22
  return data;
21
23
  }
24
+ function _url() {
25
+ const data = _interopRequireDefault(require("url"));
26
+ _url = function () {
27
+ return data;
28
+ };
29
+ return data;
30
+ }
22
31
  var _Bundle = require("../public/Bundle");
23
32
  function _utils() {
24
33
  const data = require("@atlaspack/utils");
@@ -68,11 +77,19 @@ function _featureFlags() {
68
77
  return data;
69
78
  }
70
79
  var _EnvironmentManager = require("../EnvironmentManager");
80
+ function _sourceMap() {
81
+ const data = _interopRequireDefault(require("@atlaspack/source-map"));
82
+ _sourceMap = function () {
83
+ return data;
84
+ };
85
+ return data;
86
+ }
71
87
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
72
88
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
73
89
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
74
90
  const HASH_REF_PREFIX_LEN = _constants.HASH_REF_PREFIX.length;
75
91
  const BOUNDARY_LENGTH = _constants.HASH_REF_PREFIX.length + 32 - 1;
92
+ const HASH_REF_PLACEHOLDER_LEN = HASH_REF_PREFIX_LEN + _constants.HASH_REF_HASH_LEN;
76
93
  /**
77
94
  * Writes a bundle to the dist directory, replacing hash references with the final content hashes.
78
95
  */
@@ -158,11 +175,28 @@ async function run({
158
175
  invalidDevDeps
159
176
  } = await (0, _DevDepRequest.getDevDepRequests)(api);
160
177
  (0, _DevDepRequest.invalidateDevDeps)(invalidDevDeps, options, config);
161
- await writeFiles(contentStream, info, hashRefToNameHash, options, config, outputFS, filePath, writeOptions, devDeps, api);
178
+ const bundleReplacements = (0, _featureFlags().getFeatureFlag)('fixSourceMapHashRefs') ? [] : undefined;
179
+ await writeFiles(contentStream, info, hashRefToNameHash, options, config, outputFS, filePath, writeOptions, devDeps, api, bundleReplacements);
162
180
  const hasSourceMap = (0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements') ? await options.cache.hasLargeBlob(mapKey) : await options.cache.has(mapKey);
163
181
  if (mapKey && env.sourceMap && !env.sourceMap.inline && hasSourceMap) {
164
- const mapEntry = (0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements') ? await options.cache.getLargeBlob(mapKey) : await options.cache.getBlob(mapKey);
165
- await writeFiles((0, _utils().blobToStream)(mapEntry), info, hashRefToNameHash, options, config, outputFS, (0, _projectPath.toProjectPathUnsafe)((0, _projectPath.fromProjectPathRelative)(filePath) + '.map'), writeOptions, devDeps, api);
182
+ let mapStream;
183
+ if ((0, _featureFlags().getFeatureFlag)('fixSourceMapHashRefs') && bundleReplacements && bundleReplacements.length > 0) {
184
+ const mapEntry = (0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements') ? await options.cache.getLargeBlob(mapKey) : await options.cache.getBlob(mapKey);
185
+ const mapBuffer = Buffer.isBuffer(mapEntry) ? mapEntry : Buffer.from(mapEntry);
186
+ const projectRoot = typeof options.projectRoot === 'string' ? options.projectRoot : String(options.projectRoot);
187
+ const sourceMap = new (_sourceMap().default)(projectRoot, mapBuffer);
188
+ applyReplacementsToSourceMap(sourceMap, bundleReplacements);
189
+ const mapJson = await sourceMap.stringify({
190
+ format: 'string',
191
+ file: name,
192
+ sourceRoot: computeSourceMapRoot(bundle, options)
193
+ });
194
+ mapStream = (0, _utils().blobToStream)(Buffer.from(typeof mapJson === 'string' ? mapJson : JSON.stringify(mapJson), 'utf8'));
195
+ } else {
196
+ const mapEntry = (0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements') ? await options.cache.getLargeBlob(mapKey) : await options.cache.getBlob(mapKey);
197
+ mapStream = (0, _utils().blobToStream)(mapEntry);
198
+ }
199
+ await writeFiles(mapStream, info, hashRefToNameHash, options, config, outputFS, (0, _projectPath.toProjectPathUnsafe)((0, _projectPath.fromProjectPathRelative)(filePath) + '.map'), writeOptions, devDeps, api);
166
200
  }
167
201
  let res = {
168
202
  filePath,
@@ -176,12 +210,71 @@ async function run({
176
210
  api.storeResult(res);
177
211
  return res;
178
212
  }
213
+ function applyReplacementsToSourceMap(sourceMap, replacements) {
214
+ if (replacements.length === 0) return;
215
+ const sorted = [...replacements].sort((a, b) => a.line - b.line || a.column - b.column);
216
+ for (const r of sorted) {
217
+ const delta = r.newLength - r.originalLength;
218
+ if (delta !== 0) {
219
+ // r.column is in post-replacement coordinates (matching the already-shifted
220
+ // source map state after previous offsetColumns calls). The end of the
221
+ // placeholder in these coordinates is simply r.column + r.originalLength.
222
+ const offsetStartColumn = r.column + r.originalLength;
223
+ const line1Based = r.line + 1;
224
+ if (line1Based >= 1 && offsetStartColumn + delta >= 0) {
225
+ sourceMap.offsetColumns(line1Based, offsetStartColumn, delta);
226
+ }
227
+ }
228
+ }
229
+ }
230
+
231
+ /**
232
+ * Computes the sourceRoot for a source map file. This is the relative path from
233
+ * the output directory back to the project root, so that source paths (stored
234
+ * relative to projectRoot) resolve correctly from the .map file location.
235
+ *
236
+ * Returns undefined when sources are inlined (inlineSources), since the browser
237
+ * doesn't need to fetch them and sourceRoot would be unnecessary.
238
+ *
239
+ * This logic must stay in sync with PackagerRunner.generateSourceMap.
240
+ */
241
+ function computeSourceMapRoot(bundle, options) {
242
+ let name = (0, _nullthrows().default)(bundle.name);
243
+ let filePath = (0, _projectPath.joinProjectPath)(bundle.target.distDir, name);
244
+ let fullPath = (0, _projectPath.fromProjectPath)(options.projectRoot, filePath);
245
+ let sourceRoot = _path().default.relative(_path().default.dirname(fullPath), options.projectRoot);
246
+ let inlineSources = false;
247
+ const bundleEnv = (0, _EnvironmentManager.fromEnvironmentId)(bundle.env);
248
+ if (bundle.target) {
249
+ const bundleTargetEnv = (0, _EnvironmentManager.fromEnvironmentId)(bundle.target.env);
250
+ if (bundleEnv.sourceMap && bundleEnv.sourceMap.sourceRoot !== undefined) {
251
+ sourceRoot = bundleEnv.sourceMap.sourceRoot;
252
+ } else if (options.serveOptions && bundleTargetEnv.context === 'browser') {
253
+ sourceRoot = '/__parcel_source_root';
254
+ }
255
+ if (bundleEnv.sourceMap && bundleEnv.sourceMap.inlineSources !== undefined) {
256
+ inlineSources = bundleEnv.sourceMap.inlineSources;
257
+ } else if (bundleTargetEnv.context !== 'node') {
258
+ inlineSources = options.mode === 'production';
259
+ }
260
+ }
261
+ let isInlineMap = bundleEnv.sourceMap && bundleEnv.sourceMap.inline;
262
+ if ((0, _featureFlags().getFeatureFlag)('omitSourcesContentInMemory') && !isInlineMap) {
263
+ if (!(bundleEnv.sourceMap && bundleEnv.sourceMap.inlineSources === false)) {
264
+ inlineSources = true;
265
+ }
266
+ }
267
+ if (inlineSources) {
268
+ return undefined;
269
+ }
270
+ return _url().default.format(_url().default.parse(sourceRoot + '/'));
271
+ }
179
272
  async function writeFiles(
180
273
  // @ts-expect-error TS2503
181
- inputStream, info, hashRefToNameHash, options, config, outputFS, filePath, writeOptions, devDeps, api) {
274
+ inputStream, info, hashRefToNameHash, options, config, outputFS, filePath, writeOptions, devDeps, api, bundleReplacements) {
182
275
  let compressors = await config.getCompressors((0, _projectPath.fromProjectPathRelative)(filePath));
183
276
  let fullPath = (0, _projectPath.fromProjectPath)(options.projectRoot, filePath);
184
- let stream = info.hashReferences.length ? inputStream.pipe(replaceStream(hashRefToNameHash)) : inputStream;
277
+ let stream = info.hashReferences.length ? inputStream.pipe(replaceStream(hashRefToNameHash, bundleReplacements)) : inputStream;
185
278
  let promises = [];
186
279
  for (let compressor of compressors) {
187
280
  promises.push(
@@ -230,9 +323,25 @@ stream, options, outputFS, filePath, writeOptions, devDeps, api) {
230
323
  await (0, _DevDepRequest.runDevDepRequest)(api, devDepRequest);
231
324
  }
232
325
  }
233
- function replaceStream(hashRefToNameHash) {
326
+ function advanceLineColumn(line, column, buf) {
327
+ for (let i = 0; i < buf.length; i++) {
328
+ if (buf[i] === 0x0a) {
329
+ line++;
330
+ column = 0;
331
+ } else {
332
+ column++;
333
+ }
334
+ }
335
+ return {
336
+ line,
337
+ column
338
+ };
339
+ }
340
+ function replaceStream(hashRefToNameHash, replacements) {
234
341
  let boundaryStr = Buffer.alloc(0);
235
342
  let replaced = Buffer.alloc(0);
343
+ let outputLine = 0;
344
+ let outputColumn = 0;
236
345
  return new (_stream().Transform)({
237
346
  transform(chunk, encoding, cb) {
238
347
  let str = Buffer.concat([boundaryStr, Buffer.from(chunk)]);
@@ -250,15 +359,29 @@ function replaceStream(hashRefToNameHash) {
250
359
  } else {
251
360
  let match = str.subarray(matchI, matchI + HASH_REF_PREFIX_LEN + _constants.HASH_REF_HASH_LEN).toString();
252
361
  let replacement = Buffer.from(hashRefToNameHash.get(match) ?? match);
362
+ // Copy pre-match content FIRST so position calculation includes it
253
363
  replaced.set(str.subarray(lastMatchI, matchI), replacedLength);
254
364
  replacedLength += matchI - lastMatchI;
365
+ if (replacements) {
366
+ const pos = advanceLineColumn(outputLine, outputColumn, replaced.subarray(0, replacedLength));
367
+ replacements.push({
368
+ line: pos.line,
369
+ column: pos.column,
370
+ originalLength: HASH_REF_PLACEHOLDER_LEN,
371
+ newLength: replacement.byteLength
372
+ });
373
+ }
255
374
  replaced.set(replacement, replacedLength);
256
375
  replacedLength += replacement.byteLength;
257
376
  lastMatchI = matchI + HASH_REF_PREFIX_LEN + _constants.HASH_REF_HASH_LEN;
258
377
  }
259
378
  }
379
+ const pushLen = replacedLength - BOUNDARY_LENGTH;
380
+ const pushed = advanceLineColumn(outputLine, outputColumn, replaced.subarray(0, pushLen));
381
+ outputLine = pushed.line;
382
+ outputColumn = pushed.column;
260
383
  boundaryStr = replaced.subarray(replacedLength - BOUNDARY_LENGTH, replacedLength);
261
- let strUpToBoundary = replaced.subarray(0, replacedLength - BOUNDARY_LENGTH);
384
+ let strUpToBoundary = replaced.subarray(0, pushLen);
262
385
  cb(null, strUpToBoundary);
263
386
  },
264
387
  flush(cb) {
@@ -40,6 +40,13 @@ function _utils() {
40
40
  return data;
41
41
  }
42
42
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
43
+ /** Length of the hash suffix in output filenames (e.g. .runtime.13dc01ac.js). */
44
+ const NAME_HASH_DISPLAY_LEN = 8;
45
+
46
+ /** Use at most NAME_HASH_DISPLAY_LEN chars for the name hash so filenames stay short. */
47
+ function nameHashForFilename(hash) {
48
+ return hash.length <= NAME_HASH_DISPLAY_LEN ? hash : hash.slice(-NAME_HASH_DISPLAY_LEN);
49
+ }
43
50
  function reportPackagingProgress(completeBundles, totalBundles) {
44
51
  if (!(0, _featureFlags().getFeatureFlag)('cliProgressReportingImprovements')) {
45
52
  return;
@@ -92,9 +99,9 @@ async function run({
92
99
  // Do not package and write placeholder bundles to disk. We just
93
100
  // need to update the name so other bundles can reference it.
94
101
  if (bundle.isPlaceholder) {
95
- let hash = bundle.id.slice(-8);
96
- hashRefToNameHash.set(bundle.hashReference, hash);
97
- let name = (0, _nullthrows().default)(bundle.name, `Expected ${bundle.type} bundle to have a name`).replace(bundle.hashReference, hash);
102
+ const nameHash = nameHashForFilename(bundle.id);
103
+ hashRefToNameHash.set(bundle.hashReference, nameHash);
104
+ let name = (0, _nullthrows().default)(bundle.name, `Expected ${bundle.type} bundle to have a name`).replace(bundle.hashReference, nameHash);
98
105
  res.set(bundle.id, {
99
106
  filePath: (0, _projectPath.joinProjectPath)(bundle.target.distDir, name),
100
107
  bundleId: bundle.id,
@@ -143,7 +150,7 @@ async function run({
143
150
  }
144
151
  bundleInfoMap[bundle.id] = info;
145
152
  if (!info.hashReferences.length) {
146
- hashRefToNameHash.set(bundle.hashReference, options.shouldContentHash ? info.hash.slice(-8) : bundle.id.slice(-8));
153
+ hashRefToNameHash.set(bundle.hashReference, nameHashForFilename(options.shouldContentHash ? info.hash : bundle.id));
147
154
  let writeBundleRequest = (0, _WriteBundleRequest.default)({
148
155
  bundle,
149
156
  info,
@@ -195,7 +202,7 @@ function assignComplexNameHashes(hashRefToNameHash, bundles, bundleInfoMap, opti
195
202
  if (hashRefToNameHash.get(bundle.hashReference) != null) {
196
203
  continue;
197
204
  }
198
- hashRefToNameHash.set(bundle.hashReference, options.shouldContentHash ? (0, _rust().hashString)([...getBundlesIncludedInHash(bundle.id, bundleInfoMap)].map(bundleId => bundleInfoMap[bundleId].hash).join(':')).slice(-8) : bundle.id.slice(-8));
205
+ hashRefToNameHash.set(bundle.hashReference, nameHashForFilename(options.shouldContentHash ? (0, _rust().hashString)([...getBundlesIncludedInHash(bundle.id, bundleInfoMap)].map(bundleId => bundleInfoMap[bundleId].hash).join(':')) : bundle.id));
199
206
  }
200
207
  }
201
208
  function getBundlesIncludedInHash(bundleId, bundleInfoMap, included = new Set()) {
@@ -1,10 +1,17 @@
1
1
  import type { ContentKey } from '@atlaspack/graph';
2
2
  import type { Async } from '@atlaspack/types';
3
3
  import type { StaticRunOpts } from '../RequestTracker';
4
- import type { Bundle, PackagedBundleInfo } from '../types';
4
+ import type { Bundle, PackagedBundleInfo, AtlaspackOptions } from '../types';
5
5
  import type BundleGraph from '../BundleGraph';
6
6
  import type { BundleInfo } from '../PackagerRunner';
7
7
  import { requestTypes } from '../RequestTracker';
8
+ import SourceMap from '@atlaspack/source-map';
9
+ export type HashRefReplacement = {
10
+ line: number;
11
+ column: number;
12
+ originalLength: number;
13
+ newLength: number;
14
+ };
8
15
  type WriteBundleRequestInput = {
9
16
  bundleGraph: BundleGraph;
10
17
  bundle: Bundle;
@@ -25,4 +32,16 @@ export type WriteBundleRequest = {
25
32
  * Writes a bundle to the dist directory, replacing hash references with the final content hashes.
26
33
  */
27
34
  export default function createWriteBundleRequest(input: WriteBundleRequestInput): WriteBundleRequest;
35
+ export declare function applyReplacementsToSourceMap(sourceMap: SourceMap, replacements: HashRefReplacement[]): void;
36
+ /**
37
+ * Computes the sourceRoot for a source map file. This is the relative path from
38
+ * the output directory back to the project root, so that source paths (stored
39
+ * relative to projectRoot) resolve correctly from the .map file location.
40
+ *
41
+ * Returns undefined when sources are inlined (inlineSources), since the browser
42
+ * doesn't need to fetch them and sourceRoot would be unnecessary.
43
+ *
44
+ * This logic must stay in sync with PackagerRunner.generateSourceMap.
45
+ */
46
+ export declare function computeSourceMapRoot(bundle: Bundle, options: AtlaspackOptions): string | undefined;
28
47
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaspack/core",
3
- "version": "2.33.0",
3
+ "version": "2.34.0",
4
4
  "license": "(MIT OR Apache-2.0)",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -23,22 +23,22 @@
23
23
  },
24
24
  "dependencies": {
25
25
  "@mischnic/json-sourcemap": "^0.1.0",
26
- "@atlaspack/build-cache": "2.13.10",
27
- "@atlaspack/cache": "3.2.47",
26
+ "@atlaspack/build-cache": "2.13.12",
27
+ "@atlaspack/cache": "3.2.49",
28
28
  "@atlaspack/diagnostic": "2.14.4",
29
29
  "@atlaspack/events": "2.14.4",
30
- "@atlaspack/feature-flags": "2.29.0",
31
- "@atlaspack/fs": "2.15.47",
32
- "@atlaspack/graph": "3.6.14",
33
- "@atlaspack/logger": "2.14.44",
34
- "@atlaspack/package-manager": "2.14.52",
35
- "@atlaspack/plugin": "2.14.52",
36
- "@atlaspack/profiler": "2.15.13",
37
- "@atlaspack/rust": "3.22.0",
38
- "@atlaspack/types": "2.15.42",
39
- "@atlaspack/utils": "3.3.4",
40
- "@atlaspack/workers": "2.14.52",
41
- "@atlaspack/source-map": "3.2.7",
30
+ "@atlaspack/feature-flags": "2.30.0",
31
+ "@atlaspack/fs": "2.15.49",
32
+ "@atlaspack/graph": "3.6.16",
33
+ "@atlaspack/logger": "2.14.46",
34
+ "@atlaspack/package-manager": "2.14.54",
35
+ "@atlaspack/plugin": "2.14.54",
36
+ "@atlaspack/profiler": "2.15.15",
37
+ "@atlaspack/rust": "3.23.0",
38
+ "@atlaspack/types": "2.15.44",
39
+ "@atlaspack/utils": "3.3.6",
40
+ "@atlaspack/workers": "2.14.54",
41
+ "@atlaspack/source-map": "3.2.9",
42
42
  "base-x": "^3.0.8",
43
43
  "browserslist": "^4.6.6",
44
44
  "clone": "^2.1.1",
@@ -30,7 +30,6 @@ import ThrowableDiagnostic, {errorToDiagnostic} from '@atlaspack/diagnostic';
30
30
  import {Readable} from 'stream';
31
31
  import nullthrows from 'nullthrows';
32
32
  import path from 'path';
33
- import url from 'url';
34
33
  import {hashString, hashBuffer, Hash} from '@atlaspack/rust';
35
34
 
36
35
  import {NamedBundle, bundleToInternalBundle} from './public/Bundle';
@@ -60,6 +59,7 @@ import {
60
59
  import {getInvalidationId, getInvalidationHash} from './assetUtils';
61
60
  import {optionsProxy} from './utils';
62
61
  import {invalidateDevDeps} from './requests/DevDepRequest';
62
+ import {computeSourceMapRoot} from './requests/WriteBundleRequest';
63
63
  import {tracer, PluginTracer} from '@atlaspack/profiler';
64
64
  import {fromEnvironmentId} from './EnvironmentManager';
65
65
  import {getFeatureFlag} from '@atlaspack/feature-flags';
@@ -590,64 +590,24 @@ export default class PackagerRunner {
590
590
  bundle: InternalBundle,
591
591
  map: SourceMap,
592
592
  ): Promise<string> {
593
- // sourceRoot should be a relative path between outDir and rootDir for node.js targets
593
+ let sourceRoot = computeSourceMapRoot(bundle, this.options);
594
+ let inlineSources = sourceRoot === undefined;
595
+
594
596
  let filePath = joinProjectPath(
595
597
  bundle.target.distDir,
596
598
  nullthrows(bundle.name),
597
599
  );
598
600
  let fullPath = fromProjectPath(this.options.projectRoot, filePath);
599
- let sourceRoot: string = path.relative(
600
- path.dirname(fullPath),
601
- this.options.projectRoot,
602
- );
603
- let inlineSources = false;
601
+ let mapFilename = fullPath + '.map';
604
602
 
605
603
  const bundleEnv = fromEnvironmentId(bundle.env);
606
- if (bundle.target) {
607
- const bundleTargetEnv = fromEnvironmentId(bundle.target.env);
608
-
609
- if (bundleEnv.sourceMap && bundleEnv.sourceMap.sourceRoot !== undefined) {
610
- sourceRoot = bundleEnv.sourceMap.sourceRoot;
611
- } else if (
612
- this.options.serveOptions &&
613
- bundleTargetEnv.context === 'browser'
614
- ) {
615
- sourceRoot = '/__parcel_source_root';
616
- }
617
-
618
- if (
619
- bundleEnv.sourceMap &&
620
- bundleEnv.sourceMap.inlineSources !== undefined
621
- ) {
622
- inlineSources = bundleEnv.sourceMap.inlineSources;
623
- } else if (bundleTargetEnv.context !== 'node') {
624
- // inlining should only happen in production for browser targets by default
625
- inlineSources = this.options.mode === 'production';
626
- }
627
- }
628
-
629
- let mapFilename = fullPath + '.map';
630
604
  let isInlineMap = bundleEnv.sourceMap && bundleEnv.sourceMap.inline;
631
605
 
632
- if (getFeatureFlag('omitSourcesContentInMemory') && !isInlineMap) {
633
- if (
634
- !(bundleEnv.sourceMap && bundleEnv.sourceMap.inlineSources === false)
635
- ) {
636
- /*
637
- We're omitting sourcesContent during transformation to allow GC to run.
638
- Ensure sources are still inlined into the final source maps written to disk. UNLESS the user explicitly disabled inlineSources.
639
- */
640
- inlineSources = true;
641
- }
642
- }
643
-
644
606
  let stringified = await map.stringify({
645
607
  file: path.basename(mapFilename),
646
608
  fs: this.options.inputFS,
647
609
  rootDir: this.options.projectRoot,
648
- sourceRoot: !inlineSources
649
- ? url.format(url.parse(sourceRoot + '/'))
650
- : undefined,
610
+ sourceRoot,
651
611
  inlineSources,
652
612
  format: isInlineMap ? 'inline' : 'string',
653
613
  });
@@ -505,7 +505,9 @@ function reconcileNewRuntimes<TResult extends RequestResult>(
505
505
  name: 'Runtimes',
506
506
  assetGroups,
507
507
  optionsRef,
508
- skipSymbolProp: getFeatureFlag('skipRuntimeSymbolProp'),
508
+ skipSymbolProp:
509
+ getFeatureFlag('skipRuntimeSymbolProp') ||
510
+ getFeatureFlag('rustSymbolTracker'),
509
511
  });
510
512
 
511
513
  // rebuild the graph
@@ -2,7 +2,7 @@ import invariant from 'assert';
2
2
 
3
3
  import ThrowableDiagnostic from '@atlaspack/diagnostic';
4
4
  import type {Async} from '@atlaspack/types';
5
- import {instrument} from '@atlaspack/logger';
5
+ import logger, {instrument} from '@atlaspack/logger';
6
6
  import {getFeatureFlag} from '@atlaspack/feature-flags';
7
7
 
8
8
  import AssetGraph from '../AssetGraph';
@@ -51,8 +51,8 @@ export function createAssetGraphRequestRust(
51
51
  return (input: AssetGraphRequestInput) => ({
52
52
  type: requestTypes.asset_graph_request,
53
53
  id: input.name,
54
- run: async (input) => {
55
- let options = input.options;
54
+ run: async (runInput) => {
55
+ let options = runInput.options;
56
56
  let {assetGraphPromise, commitPromise} =
57
57
  await rustAtlaspack.buildAssetGraph();
58
58
 
@@ -69,7 +69,7 @@ export function createAssetGraphRequestRust(
69
69
  let prevResult = null;
70
70
  if (serializedAssetGraph.hadPreviousGraph) {
71
71
  prevResult =
72
- await input.api.getPreviousResult<AssetGraphRequestResult>();
72
+ await runInput.api.getPreviousResult<AssetGraphRequestResult>();
73
73
  }
74
74
 
75
75
  let {assetGraph, changedAssets} = instrument(
@@ -78,20 +78,28 @@ export function createAssetGraphRequestRust(
78
78
  );
79
79
 
80
80
  let changedAssetsPropagation = new Set(changedAssets.keys());
81
- let errors = propagateSymbols({
82
- options,
83
- assetGraph,
84
- changedAssetsPropagation,
85
- assetGroupsWithRemovedParents: new Set(),
86
- previousErrors: new Map(), //this.previousSymbolPropagationErrors,
87
- });
88
-
89
- if (errors.size > 0) {
90
- // Just throw the first error. Since errors can bubble (e.g. reexporting a reexported symbol also fails),
91
- // determining which failing export is the root cause is nontrivial (because of circular dependencies).
92
- throw new ThrowableDiagnostic({
93
- diagnostic: [...errors.values()][0],
81
+ // Skip symbol propagation for runtime assets - they have pre-computed symbol data
82
+ if (input.skipSymbolProp) {
83
+ logger.verbose({
84
+ origin: '@atlaspack/core',
85
+ message: 'Skipping symbol propagation for runtime asset graph',
94
86
  });
87
+ } else {
88
+ let errors = propagateSymbols({
89
+ options,
90
+ assetGraph,
91
+ changedAssetsPropagation,
92
+ assetGroupsWithRemovedParents: new Set(),
93
+ previousErrors: new Map(), //this.previousSymbolPropagationErrors,
94
+ });
95
+
96
+ if (errors.size > 0) {
97
+ // Just throw the first error. Since errors can bubble (e.g. reexporting a reexported symbol also fails),
98
+ // determining which failing export is the root cause is nontrivial (because of circular dependencies).
99
+ throw new ThrowableDiagnostic({
100
+ diagnostic: [...errors.values()][0],
101
+ });
102
+ }
95
103
  }
96
104
 
97
105
  await dumpGraphToGraphViz(assetGraph, 'AssetGraphV3');
@@ -116,8 +124,8 @@ export function createAssetGraphRequestRust(
116
124
  });
117
125
  }
118
126
 
119
- await input.api.storeResult(result);
120
- input.api.invalidateOnBuild();
127
+ await runInput.api.storeResult(result);
128
+ runInput.api.invalidateOnBuild();
121
129
 
122
130
  return result;
123
131
  },
@@ -314,6 +322,19 @@ export function getAssetGraph(
314
322
 
315
323
  let usedSymbolsDown = new Set();
316
324
  let usedSymbolsUp = new Map();
325
+
326
+ if (node.used_symbols_up) {
327
+ for (let usedSymbol of node.used_symbols_up) {
328
+ // Transform Rust UsedSymbol { symbol: Symbol, asset: string }
329
+ // to JS format { symbol: string, asset: string } where symbol is the exported name
330
+ const exportedName = usedSymbol.symbol.exported;
331
+ usedSymbolsUp.set(exportedName, {
332
+ asset: usedSymbol.asset,
333
+ symbol: exportedName,
334
+ });
335
+ }
336
+ }
337
+
317
338
  if (dependency.isEntry && dependency.isLibrary) {
318
339
  usedSymbolsDown.add('*');
319
340
  usedSymbolsUp.set('*', undefined);
@@ -151,6 +151,7 @@ export default function createBundleGraphRequest(
151
151
  lazyIncludes: options.lazyIncludes,
152
152
  lazyExcludes: options.lazyExcludes,
153
153
  requestedAssetIds,
154
+ skipSymbolProp: getFeatureFlag('rustSymbolTracker'),
154
155
  });
155
156
 
156
157
  let {assetGraph, changedAssets, assetRequests} = await instrumentAsync(