@atlaspack/core 2.33.1 → 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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # @atlaspack/core
2
2
 
3
+ ## 2.34.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1010](https://github.com/atlassian-labs/atlaspack/pull/1010) [`45a0dc5`](https://github.com/atlassian-labs/atlaspack/commit/45a0dc530fd9472dbfdebcbb05f1aad812ab3b23) Thanks [@benjervis](https://github.com/benjervis)! - Add initial implementation of native symbol propagation
8
+
9
+ ### Patch Changes
10
+
11
+ - [#1027](https://github.com/atlassian-labs/atlaspack/pull/1027) [`d8e984b`](https://github.com/atlassian-labs/atlaspack/commit/d8e984b7f6d04fa03707fa299bfd8b8bf9f58280) Thanks [@marcins](https://github.com/marcins)! - Improve source map quality through various accuracy fixes.
12
+
13
+ - Updated dependencies [[`c4082ba`](https://github.com/atlassian-labs/atlaspack/commit/c4082ba3fc1a9328a2e5f23195d5972fbc5d10c8), [`d8e984b`](https://github.com/atlassian-labs/atlaspack/commit/d8e984b7f6d04fa03707fa299bfd8b8bf9f58280), [`ca78e1d`](https://github.com/atlassian-labs/atlaspack/commit/ca78e1d2007bfecd267b283d66a73f3695da4234), [`94e1a58`](https://github.com/atlassian-labs/atlaspack/commit/94e1a58a1a8ed5a4e329745d8a7e6a9530b5cb11), [`3ad8e88`](https://github.com/atlassian-labs/atlaspack/commit/3ad8e880c4c2b9126cbfb6963a3862a75306a26f), [`4c1f39a`](https://github.com/atlassian-labs/atlaspack/commit/4c1f39a911acaefd630d877af1ae5a039931662f), [`fcf7ec5`](https://github.com/atlassian-labs/atlaspack/commit/fcf7ec56fea644e21f7a67d649e6efd1f03c4a6e), [`45a0dc5`](https://github.com/atlassian-labs/atlaspack/commit/45a0dc530fd9472dbfdebcbb05f1aad812ab3b23)]:
14
+ - @atlaspack/rust@3.23.0
15
+ - @atlaspack/package-manager@2.14.54
16
+ - @atlaspack/feature-flags@2.30.0
17
+ - @atlaspack/utils@3.3.6
18
+ - @atlaspack/cache@3.2.49
19
+ - @atlaspack/fs@2.15.49
20
+ - @atlaspack/logger@2.14.46
21
+ - @atlaspack/source-map@3.2.9
22
+ - @atlaspack/build-cache@2.13.12
23
+ - @atlaspack/graph@3.6.16
24
+ - @atlaspack/profiler@2.15.15
25
+ - @atlaspack/workers@2.14.54
26
+ - @atlaspack/plugin@2.14.54
27
+ - @atlaspack/types@2.15.44
28
+
3
29
  ## 2.33.1
4
30
 
5
31
  ### Patch Changes
@@ -44,7 +44,6 @@ const diagnostic_1 = __importStar(require("@atlaspack/diagnostic"));
44
44
  const stream_1 = require("stream");
45
45
  const nullthrows_1 = __importDefault(require("nullthrows"));
46
46
  const path_1 = __importDefault(require("path"));
47
- const url_1 = __importDefault(require("url"));
48
47
  const rust_1 = require("@atlaspack/rust");
49
48
  const Bundle_1 = require("./public/Bundle");
50
49
  const BundleGraph_1 = __importStar(require("./public/BundleGraph"));
@@ -58,6 +57,7 @@ const DevDepRequest_1 = require("./requests/DevDepRequest");
58
57
  const assetUtils_1 = require("./assetUtils");
59
58
  const utils_2 = require("./utils");
60
59
  const DevDepRequest_2 = require("./requests/DevDepRequest");
60
+ const WriteBundleRequest_1 = require("./requests/WriteBundleRequest");
61
61
  const profiler_1 = require("@atlaspack/profiler");
62
62
  const EnvironmentManager_1 = require("./EnvironmentManager");
63
63
  const feature_flags_1 = require("@atlaspack/feature-flags");
@@ -330,48 +330,18 @@ class PackagerRunner {
330
330
  return optimized;
331
331
  }
332
332
  async generateSourceMap(bundle, map) {
333
- // sourceRoot should be a relative path between outDir and rootDir for node.js targets
333
+ let sourceRoot = (0, WriteBundleRequest_1.computeSourceMapRoot)(bundle, this.options);
334
+ let inlineSources = sourceRoot === undefined;
334
335
  let filePath = (0, projectPath_1.joinProjectPath)(bundle.target.distDir, (0, nullthrows_1.default)(bundle.name));
335
336
  let fullPath = (0, projectPath_1.fromProjectPath)(this.options.projectRoot, filePath);
336
- let sourceRoot = path_1.default.relative(path_1.default.dirname(fullPath), this.options.projectRoot);
337
- let inlineSources = false;
338
- const bundleEnv = (0, EnvironmentManager_1.fromEnvironmentId)(bundle.env);
339
- if (bundle.target) {
340
- const bundleTargetEnv = (0, EnvironmentManager_1.fromEnvironmentId)(bundle.target.env);
341
- if (bundleEnv.sourceMap && bundleEnv.sourceMap.sourceRoot !== undefined) {
342
- sourceRoot = bundleEnv.sourceMap.sourceRoot;
343
- }
344
- else if (this.options.serveOptions &&
345
- bundleTargetEnv.context === 'browser') {
346
- sourceRoot = '/__parcel_source_root';
347
- }
348
- if (bundleEnv.sourceMap &&
349
- bundleEnv.sourceMap.inlineSources !== undefined) {
350
- inlineSources = bundleEnv.sourceMap.inlineSources;
351
- }
352
- else if (bundleTargetEnv.context !== 'node') {
353
- // inlining should only happen in production for browser targets by default
354
- inlineSources = this.options.mode === 'production';
355
- }
356
- }
357
337
  let mapFilename = fullPath + '.map';
338
+ const bundleEnv = (0, EnvironmentManager_1.fromEnvironmentId)(bundle.env);
358
339
  let isInlineMap = bundleEnv.sourceMap && bundleEnv.sourceMap.inline;
359
- if ((0, feature_flags_1.getFeatureFlag)('omitSourcesContentInMemory') && !isInlineMap) {
360
- if (!(bundleEnv.sourceMap && bundleEnv.sourceMap.inlineSources === false)) {
361
- /*
362
- We're omitting sourcesContent during transformation to allow GC to run.
363
- Ensure sources are still inlined into the final source maps written to disk. UNLESS the user explicitly disabled inlineSources.
364
- */
365
- inlineSources = true;
366
- }
367
- }
368
340
  let stringified = await map.stringify({
369
341
  file: path_1.default.basename(mapFilename),
370
342
  fs: this.options.inputFS,
371
343
  rootDir: this.options.projectRoot,
372
- sourceRoot: !inlineSources
373
- ? url_1.default.format(url_1.default.parse(sourceRoot + '/'))
374
- : undefined,
344
+ sourceRoot,
375
345
  inlineSources,
376
346
  format: isInlineMap ? 'inline' : 'string',
377
347
  });
@@ -376,7 +376,8 @@ function reconcileNewRuntimes(api, connections, optionsRef) {
376
376
  name: 'Runtimes',
377
377
  assetGroups,
378
378
  optionsRef,
379
- skipSymbolProp: (0, feature_flags_1.getFeatureFlag)('skipRuntimeSymbolProp'),
379
+ skipSymbolProp: (0, feature_flags_1.getFeatureFlag)('skipRuntimeSymbolProp') ||
380
+ (0, feature_flags_1.getFeatureFlag)('rustSymbolTracker'),
380
381
  });
381
382
  // rebuild the graph
382
383
  return api.runRequest(request, { force: true });
@@ -1,4 +1,37 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
37
  };
@@ -7,7 +40,7 @@ exports.createAssetGraphRequestRust = createAssetGraphRequestRust;
7
40
  exports.getAssetGraph = getAssetGraph;
8
41
  const assert_1 = __importDefault(require("assert"));
9
42
  const diagnostic_1 = __importDefault(require("@atlaspack/diagnostic"));
10
- const logger_1 = require("@atlaspack/logger");
43
+ const logger_1 = __importStar(require("@atlaspack/logger"));
11
44
  const feature_flags_1 = require("@atlaspack/feature-flags");
12
45
  const AssetGraph_1 = __importDefault(require("../AssetGraph"));
13
46
  const RequestTracker_1 = require("../RequestTracker");
@@ -20,8 +53,8 @@ function createAssetGraphRequestRust(rustAtlaspack) {
20
53
  return (input) => ({
21
54
  type: RequestTracker_1.requestTypes.asset_graph_request,
22
55
  id: input.name,
23
- run: async (input) => {
24
- let options = input.options;
56
+ run: async (runInput) => {
57
+ let options = runInput.options;
25
58
  let { assetGraphPromise, commitPromise } = await rustAtlaspack.buildAssetGraph();
26
59
  let [serializedAssetGraph, assetGraphError] = (await assetGraphPromise);
27
60
  if (assetGraphError) {
@@ -33,24 +66,33 @@ function createAssetGraphRequestRust(rustAtlaspack) {
33
66
  let prevResult = null;
34
67
  if (serializedAssetGraph.hadPreviousGraph) {
35
68
  prevResult =
36
- await input.api.getPreviousResult();
69
+ await runInput.api.getPreviousResult();
37
70
  }
38
71
  let { assetGraph, changedAssets } = (0, logger_1.instrument)('atlaspack_v3_getAssetGraph', () => getAssetGraph(serializedAssetGraph, prevResult?.assetGraph));
39
72
  let changedAssetsPropagation = new Set(changedAssets.keys());
40
- let errors = (0, SymbolPropagation_1.propagateSymbols)({
41
- options,
42
- assetGraph,
43
- changedAssetsPropagation,
44
- assetGroupsWithRemovedParents: new Set(),
45
- previousErrors: new Map(), //this.previousSymbolPropagationErrors,
46
- });
47
- if (errors.size > 0) {
48
- // Just throw the first error. Since errors can bubble (e.g. reexporting a reexported symbol also fails),
49
- // determining which failing export is the root cause is nontrivial (because of circular dependencies).
50
- throw new diagnostic_1.default({
51
- diagnostic: [...errors.values()][0],
73
+ // Skip symbol propagation for runtime assets - they have pre-computed symbol data
74
+ if (input.skipSymbolProp) {
75
+ logger_1.default.verbose({
76
+ origin: '@atlaspack/core',
77
+ message: 'Skipping symbol propagation for runtime asset graph',
52
78
  });
53
79
  }
80
+ else {
81
+ let errors = (0, SymbolPropagation_1.propagateSymbols)({
82
+ options,
83
+ assetGraph,
84
+ changedAssetsPropagation,
85
+ assetGroupsWithRemovedParents: new Set(),
86
+ previousErrors: new Map(), //this.previousSymbolPropagationErrors,
87
+ });
88
+ if (errors.size > 0) {
89
+ // Just throw the first error. Since errors can bubble (e.g. reexporting a reexported symbol also fails),
90
+ // determining which failing export is the root cause is nontrivial (because of circular dependencies).
91
+ throw new diagnostic_1.default({
92
+ diagnostic: [...errors.values()][0],
93
+ });
94
+ }
95
+ }
54
96
  await (0, dumpGraphToGraphViz_1.default)(assetGraph, 'AssetGraphV3');
55
97
  let result = {
56
98
  assetGraph,
@@ -68,8 +110,8 @@ function createAssetGraphRequestRust(rustAtlaspack) {
68
110
  },
69
111
  });
70
112
  }
71
- await input.api.storeResult(result);
72
- input.api.invalidateOnBuild();
113
+ await runInput.api.storeResult(result);
114
+ runInput.api.invalidateOnBuild();
73
115
  return result;
74
116
  },
75
117
  input,
@@ -230,6 +272,17 @@ function getAssetGraph(serializedGraph, prevAssetGraph) {
230
272
  }
231
273
  let usedSymbolsDown = new Set();
232
274
  let usedSymbolsUp = new Map();
275
+ if (node.used_symbols_up) {
276
+ for (let usedSymbol of node.used_symbols_up) {
277
+ // Transform Rust UsedSymbol { symbol: Symbol, asset: string }
278
+ // to JS format { symbol: string, asset: string } where symbol is the exported name
279
+ const exportedName = usedSymbol.symbol.exported;
280
+ usedSymbolsUp.set(exportedName, {
281
+ asset: usedSymbol.asset,
282
+ symbol: exportedName,
283
+ });
284
+ }
285
+ }
233
286
  if (dependency.isEntry && dependency.isLibrary) {
234
287
  usedSymbolsDown.add('*');
235
288
  usedSymbolsUp.set('*', undefined);
@@ -110,6 +110,7 @@ function createBundleGraphRequest(input) {
110
110
  lazyIncludes: options.lazyIncludes,
111
111
  lazyExcludes: options.lazyExcludes,
112
112
  requestedAssetIds,
113
+ skipSymbolProp: (0, feature_flags_1.getFeatureFlag)('rustSymbolTracker'),
113
114
  });
114
115
  let { assetGraph, changedAssets, assetRequests } = await (0, logger_1.instrumentAsync)('asset-graph-request', () => {
115
116
  return api.runRequest(request, {
@@ -37,9 +37,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.default = createWriteBundleRequest;
40
+ exports.applyReplacementsToSourceMap = applyReplacementsToSourceMap;
41
+ exports.computeSourceMapRoot = computeSourceMapRoot;
40
42
  const constants_1 = require("../constants");
41
43
  const nullthrows_1 = __importDefault(require("nullthrows"));
42
44
  const path_1 = __importDefault(require("path"));
45
+ const url_1 = __importDefault(require("url"));
43
46
  const Bundle_1 = require("../public/Bundle");
44
47
  const utils_1 = require("@atlaspack/utils");
45
48
  const stream_1 = require("stream");
@@ -53,8 +56,10 @@ const profiler_1 = require("@atlaspack/profiler");
53
56
  const RequestTracker_1 = require("../RequestTracker");
54
57
  const feature_flags_1 = require("@atlaspack/feature-flags");
55
58
  const EnvironmentManager_1 = require("../EnvironmentManager");
59
+ const source_map_1 = __importDefault(require("@atlaspack/source-map"));
56
60
  const HASH_REF_PREFIX_LEN = constants_1.HASH_REF_PREFIX.length;
57
61
  const BOUNDARY_LENGTH = constants_1.HASH_REF_PREFIX.length + 32 - 1;
62
+ const HASH_REF_PLACEHOLDER_LEN = HASH_REF_PREFIX_LEN + constants_1.HASH_REF_HASH_LEN;
58
63
  /**
59
64
  * Writes a bundle to the dist directory, replacing hash references with the final content hashes.
60
65
  */
@@ -125,15 +130,43 @@ async function run({ input, options, api }) {
125
130
  let config = (0, AtlaspackConfigRequest_1.getCachedAtlaspackConfig)(configResult, options);
126
131
  let { devDeps, invalidDevDeps } = await (0, DevDepRequest_1.getDevDepRequests)(api);
127
132
  (0, DevDepRequest_1.invalidateDevDeps)(invalidDevDeps, options, config);
128
- await writeFiles(contentStream, info, hashRefToNameHash, options, config, outputFS, filePath, writeOptions, devDeps, api);
133
+ const bundleReplacements = (0, feature_flags_1.getFeatureFlag)('fixSourceMapHashRefs')
134
+ ? []
135
+ : undefined;
136
+ await writeFiles(contentStream, info, hashRefToNameHash, options, config, outputFS, filePath, writeOptions, devDeps, api, bundleReplacements);
129
137
  const hasSourceMap = (0, feature_flags_1.getFeatureFlag)('cachePerformanceImprovements')
130
138
  ? await options.cache.hasLargeBlob(mapKey)
131
139
  : await options.cache.has(mapKey);
132
140
  if (mapKey && env.sourceMap && !env.sourceMap.inline && hasSourceMap) {
133
- const mapEntry = (0, feature_flags_1.getFeatureFlag)('cachePerformanceImprovements')
134
- ? await options.cache.getLargeBlob(mapKey)
135
- : await options.cache.getBlob(mapKey);
136
- await writeFiles((0, utils_1.blobToStream)(mapEntry), info, hashRefToNameHash, options, config, outputFS, (0, projectPath_1.toProjectPathUnsafe)((0, projectPath_1.fromProjectPathRelative)(filePath) + '.map'), writeOptions, devDeps, api);
141
+ let mapStream;
142
+ if ((0, feature_flags_1.getFeatureFlag)('fixSourceMapHashRefs') &&
143
+ bundleReplacements &&
144
+ bundleReplacements.length > 0) {
145
+ const mapEntry = (0, feature_flags_1.getFeatureFlag)('cachePerformanceImprovements')
146
+ ? await options.cache.getLargeBlob(mapKey)
147
+ : await options.cache.getBlob(mapKey);
148
+ const mapBuffer = Buffer.isBuffer(mapEntry)
149
+ ? mapEntry
150
+ : Buffer.from(mapEntry);
151
+ const projectRoot = typeof options.projectRoot === 'string'
152
+ ? options.projectRoot
153
+ : String(options.projectRoot);
154
+ const sourceMap = new source_map_1.default(projectRoot, mapBuffer);
155
+ applyReplacementsToSourceMap(sourceMap, bundleReplacements);
156
+ const mapJson = await sourceMap.stringify({
157
+ format: 'string',
158
+ file: name,
159
+ sourceRoot: computeSourceMapRoot(bundle, options),
160
+ });
161
+ mapStream = (0, utils_1.blobToStream)(Buffer.from(typeof mapJson === 'string' ? mapJson : JSON.stringify(mapJson), 'utf8'));
162
+ }
163
+ else {
164
+ const mapEntry = (0, feature_flags_1.getFeatureFlag)('cachePerformanceImprovements')
165
+ ? await options.cache.getLargeBlob(mapKey)
166
+ : await options.cache.getBlob(mapKey);
167
+ mapStream = (0, utils_1.blobToStream)(mapEntry);
168
+ }
169
+ await writeFiles(mapStream, info, hashRefToNameHash, options, config, outputFS, (0, projectPath_1.toProjectPathUnsafe)((0, projectPath_1.fromProjectPathRelative)(filePath) + '.map'), writeOptions, devDeps, api);
137
170
  }
138
171
  let res = {
139
172
  filePath,
@@ -147,13 +180,75 @@ async function run({ input, options, api }) {
147
180
  api.storeResult(res);
148
181
  return res;
149
182
  }
183
+ function applyReplacementsToSourceMap(sourceMap, replacements) {
184
+ if (replacements.length === 0)
185
+ return;
186
+ const sorted = [...replacements].sort((a, b) => a.line - b.line || a.column - b.column);
187
+ for (const r of sorted) {
188
+ const delta = r.newLength - r.originalLength;
189
+ if (delta !== 0) {
190
+ // r.column is in post-replacement coordinates (matching the already-shifted
191
+ // source map state after previous offsetColumns calls). The end of the
192
+ // placeholder in these coordinates is simply r.column + r.originalLength.
193
+ const offsetStartColumn = r.column + r.originalLength;
194
+ const line1Based = r.line + 1;
195
+ if (line1Based >= 1 && offsetStartColumn + delta >= 0) {
196
+ sourceMap.offsetColumns(line1Based, offsetStartColumn, delta);
197
+ }
198
+ }
199
+ }
200
+ }
201
+ /**
202
+ * Computes the sourceRoot for a source map file. This is the relative path from
203
+ * the output directory back to the project root, so that source paths (stored
204
+ * relative to projectRoot) resolve correctly from the .map file location.
205
+ *
206
+ * Returns undefined when sources are inlined (inlineSources), since the browser
207
+ * doesn't need to fetch them and sourceRoot would be unnecessary.
208
+ *
209
+ * This logic must stay in sync with PackagerRunner.generateSourceMap.
210
+ */
211
+ function computeSourceMapRoot(bundle, options) {
212
+ let name = (0, nullthrows_1.default)(bundle.name);
213
+ let filePath = (0, projectPath_1.joinProjectPath)(bundle.target.distDir, name);
214
+ let fullPath = (0, projectPath_1.fromProjectPath)(options.projectRoot, filePath);
215
+ let sourceRoot = path_1.default.relative(path_1.default.dirname(fullPath), options.projectRoot);
216
+ let inlineSources = false;
217
+ const bundleEnv = (0, EnvironmentManager_1.fromEnvironmentId)(bundle.env);
218
+ if (bundle.target) {
219
+ const bundleTargetEnv = (0, EnvironmentManager_1.fromEnvironmentId)(bundle.target.env);
220
+ if (bundleEnv.sourceMap && bundleEnv.sourceMap.sourceRoot !== undefined) {
221
+ sourceRoot = bundleEnv.sourceMap.sourceRoot;
222
+ }
223
+ else if (options.serveOptions && bundleTargetEnv.context === 'browser') {
224
+ sourceRoot = '/__parcel_source_root';
225
+ }
226
+ if (bundleEnv.sourceMap &&
227
+ bundleEnv.sourceMap.inlineSources !== undefined) {
228
+ inlineSources = bundleEnv.sourceMap.inlineSources;
229
+ }
230
+ else if (bundleTargetEnv.context !== 'node') {
231
+ inlineSources = options.mode === 'production';
232
+ }
233
+ }
234
+ let isInlineMap = bundleEnv.sourceMap && bundleEnv.sourceMap.inline;
235
+ if ((0, feature_flags_1.getFeatureFlag)('omitSourcesContentInMemory') && !isInlineMap) {
236
+ if (!(bundleEnv.sourceMap && bundleEnv.sourceMap.inlineSources === false)) {
237
+ inlineSources = true;
238
+ }
239
+ }
240
+ if (inlineSources) {
241
+ return undefined;
242
+ }
243
+ return url_1.default.format(url_1.default.parse(sourceRoot + '/'));
244
+ }
150
245
  async function writeFiles(
151
246
  // @ts-expect-error TS2503
152
- inputStream, info, hashRefToNameHash, options, config, outputFS, filePath, writeOptions, devDeps, api) {
247
+ inputStream, info, hashRefToNameHash, options, config, outputFS, filePath, writeOptions, devDeps, api, bundleReplacements) {
153
248
  let compressors = await config.getCompressors((0, projectPath_1.fromProjectPathRelative)(filePath));
154
249
  let fullPath = (0, projectPath_1.fromProjectPath)(options.projectRoot, filePath);
155
250
  let stream = info.hashReferences.length
156
- ? inputStream.pipe(replaceStream(hashRefToNameHash))
251
+ ? inputStream.pipe(replaceStream(hashRefToNameHash, bundleReplacements))
157
252
  : inputStream;
158
253
  let promises = [];
159
254
  for (let compressor of compressors) {
@@ -202,9 +297,23 @@ stream, options, outputFS, filePath, writeOptions, devDeps, api) {
202
297
  await (0, DevDepRequest_1.runDevDepRequest)(api, devDepRequest);
203
298
  }
204
299
  }
205
- function replaceStream(hashRefToNameHash) {
300
+ function advanceLineColumn(line, column, buf) {
301
+ for (let i = 0; i < buf.length; i++) {
302
+ if (buf[i] === 0x0a) {
303
+ line++;
304
+ column = 0;
305
+ }
306
+ else {
307
+ column++;
308
+ }
309
+ }
310
+ return { line, column };
311
+ }
312
+ function replaceStream(hashRefToNameHash, replacements) {
206
313
  let boundaryStr = Buffer.alloc(0);
207
314
  let replaced = Buffer.alloc(0);
315
+ let outputLine = 0;
316
+ let outputColumn = 0;
208
317
  return new stream_1.Transform({
209
318
  transform(chunk, encoding, cb) {
210
319
  let str = Buffer.concat([boundaryStr, Buffer.from(chunk)]);
@@ -225,15 +334,29 @@ function replaceStream(hashRefToNameHash) {
225
334
  .subarray(matchI, matchI + HASH_REF_PREFIX_LEN + constants_1.HASH_REF_HASH_LEN)
226
335
  .toString();
227
336
  let replacement = Buffer.from(hashRefToNameHash.get(match) ?? match);
337
+ // Copy pre-match content FIRST so position calculation includes it
228
338
  replaced.set(str.subarray(lastMatchI, matchI), replacedLength);
229
339
  replacedLength += matchI - lastMatchI;
340
+ if (replacements) {
341
+ const pos = advanceLineColumn(outputLine, outputColumn, replaced.subarray(0, replacedLength));
342
+ replacements.push({
343
+ line: pos.line,
344
+ column: pos.column,
345
+ originalLength: HASH_REF_PLACEHOLDER_LEN,
346
+ newLength: replacement.byteLength,
347
+ });
348
+ }
230
349
  replaced.set(replacement, replacedLength);
231
350
  replacedLength += replacement.byteLength;
232
351
  lastMatchI = matchI + HASH_REF_PREFIX_LEN + constants_1.HASH_REF_HASH_LEN;
233
352
  }
234
353
  }
354
+ const pushLen = replacedLength - BOUNDARY_LENGTH;
355
+ const pushed = advanceLineColumn(outputLine, outputColumn, replaced.subarray(0, pushLen));
356
+ outputLine = pushed.line;
357
+ outputColumn = pushed.column;
235
358
  boundaryStr = replaced.subarray(replacedLength - BOUNDARY_LENGTH, replacedLength);
236
- let strUpToBoundary = replaced.subarray(0, replacedLength - BOUNDARY_LENGTH);
359
+ let strUpToBoundary = replaced.subarray(0, pushLen);
237
360
  cb(null, strUpToBoundary);
238
361
  },
239
362
  flush(cb) {
@@ -15,6 +15,14 @@ const rust_1 = require("@atlaspack/rust");
15
15
  const PackageRequest_1 = require("./PackageRequest");
16
16
  const WriteBundleRequest_1 = __importDefault(require("./WriteBundleRequest"));
17
17
  const utils_1 = require("@atlaspack/utils");
18
+ /** Length of the hash suffix in output filenames (e.g. .runtime.13dc01ac.js). */
19
+ const NAME_HASH_DISPLAY_LEN = 8;
20
+ /** Use at most NAME_HASH_DISPLAY_LEN chars for the name hash so filenames stay short. */
21
+ function nameHashForFilename(hash) {
22
+ return hash.length <= NAME_HASH_DISPLAY_LEN
23
+ ? hash
24
+ : hash.slice(-NAME_HASH_DISPLAY_LEN);
25
+ }
18
26
  function reportPackagingProgress(completeBundles, totalBundles) {
19
27
  if (!(0, feature_flags_1.getFeatureFlag)('cliProgressReportingImprovements')) {
20
28
  return;
@@ -57,9 +65,9 @@ async function run({ input, api, farm, options, }) {
57
65
  // Do not package and write placeholder bundles to disk. We just
58
66
  // need to update the name so other bundles can reference it.
59
67
  if (bundle.isPlaceholder) {
60
- let hash = bundle.id.slice(-8);
61
- hashRefToNameHash.set(bundle.hashReference, hash);
62
- let name = (0, nullthrows_1.default)(bundle.name, `Expected ${bundle.type} bundle to have a name`).replace(bundle.hashReference, hash);
68
+ const nameHash = nameHashForFilename(bundle.id);
69
+ hashRefToNameHash.set(bundle.hashReference, nameHash);
70
+ let name = (0, nullthrows_1.default)(bundle.name, `Expected ${bundle.type} bundle to have a name`).replace(bundle.hashReference, nameHash);
63
71
  res.set(bundle.id, {
64
72
  filePath: (0, projectPath_1.joinProjectPath)(bundle.target.distDir, name),
65
73
  bundleId: bundle.id,
@@ -106,9 +114,7 @@ async function run({ input, api, farm, options, }) {
106
114
  }
107
115
  bundleInfoMap[bundle.id] = info;
108
116
  if (!info.hashReferences.length) {
109
- hashRefToNameHash.set(bundle.hashReference, options.shouldContentHash
110
- ? info.hash.slice(-8)
111
- : bundle.id.slice(-8));
117
+ hashRefToNameHash.set(bundle.hashReference, nameHashForFilename(options.shouldContentHash ? info.hash : bundle.id));
112
118
  let writeBundleRequest = (0, WriteBundleRequest_1.default)({
113
119
  bundle,
114
120
  info,
@@ -162,11 +168,11 @@ function assignComplexNameHashes(hashRefToNameHash, bundles, bundleInfoMap, opti
162
168
  if (hashRefToNameHash.get(bundle.hashReference) != null) {
163
169
  continue;
164
170
  }
165
- hashRefToNameHash.set(bundle.hashReference, options.shouldContentHash
171
+ hashRefToNameHash.set(bundle.hashReference, nameHashForFilename(options.shouldContentHash
166
172
  ? (0, rust_1.hashString)([...getBundlesIncludedInHash(bundle.id, bundleInfoMap)]
167
173
  .map((bundleId) => bundleInfoMap[bundleId].hash)
168
- .join(':')).slice(-8)
169
- : bundle.id.slice(-8));
174
+ .join(':'))
175
+ : bundle.id));
170
176
  }
171
177
  }
172
178
  function getBundlesIncludedInHash(bundleId, bundleInfoMap, included = new Set()) {
@@ -60,13 +60,6 @@ function _path() {
60
60
  };
61
61
  return data;
62
62
  }
63
- function _url() {
64
- const data = _interopRequireDefault(require("url"));
65
- _url = function () {
66
- return data;
67
- };
68
- return data;
69
- }
70
63
  function _rust() {
71
64
  const data = require("@atlaspack/rust");
72
65
  _rust = function () {
@@ -85,6 +78,7 @@ var _ConfigRequest = require("./requests/ConfigRequest");
85
78
  var _DevDepRequest = require("./requests/DevDepRequest");
86
79
  var _assetUtils = require("./assetUtils");
87
80
  var _utils2 = require("./utils");
81
+ var _WriteBundleRequest = require("./requests/WriteBundleRequest");
88
82
  function _profiler() {
89
83
  const data = require("@atlaspack/profiler");
90
84
  _profiler = function () {
@@ -407,42 +401,18 @@ class PackagerRunner {
407
401
  return optimized;
408
402
  }
409
403
  async generateSourceMap(bundle, map) {
410
- // sourceRoot should be a relative path between outDir and rootDir for node.js targets
404
+ let sourceRoot = (0, _WriteBundleRequest.computeSourceMapRoot)(bundle, this.options);
405
+ let inlineSources = sourceRoot === undefined;
411
406
  let filePath = (0, _projectPath.joinProjectPath)(bundle.target.distDir, (0, _nullthrows().default)(bundle.name));
412
407
  let fullPath = (0, _projectPath.fromProjectPath)(this.options.projectRoot, filePath);
413
- let sourceRoot = _path().default.relative(_path().default.dirname(fullPath), this.options.projectRoot);
414
- let inlineSources = false;
415
- const bundleEnv = (0, _EnvironmentManager.fromEnvironmentId)(bundle.env);
416
- if (bundle.target) {
417
- const bundleTargetEnv = (0, _EnvironmentManager.fromEnvironmentId)(bundle.target.env);
418
- if (bundleEnv.sourceMap && bundleEnv.sourceMap.sourceRoot !== undefined) {
419
- sourceRoot = bundleEnv.sourceMap.sourceRoot;
420
- } else if (this.options.serveOptions && bundleTargetEnv.context === 'browser') {
421
- sourceRoot = '/__parcel_source_root';
422
- }
423
- if (bundleEnv.sourceMap && bundleEnv.sourceMap.inlineSources !== undefined) {
424
- inlineSources = bundleEnv.sourceMap.inlineSources;
425
- } else if (bundleTargetEnv.context !== 'node') {
426
- // inlining should only happen in production for browser targets by default
427
- inlineSources = this.options.mode === 'production';
428
- }
429
- }
430
408
  let mapFilename = fullPath + '.map';
409
+ const bundleEnv = (0, _EnvironmentManager.fromEnvironmentId)(bundle.env);
431
410
  let isInlineMap = bundleEnv.sourceMap && bundleEnv.sourceMap.inline;
432
- if ((0, _featureFlags().getFeatureFlag)('omitSourcesContentInMemory') && !isInlineMap) {
433
- if (!(bundleEnv.sourceMap && bundleEnv.sourceMap.inlineSources === false)) {
434
- /*
435
- We're omitting sourcesContent during transformation to allow GC to run.
436
- Ensure sources are still inlined into the final source maps written to disk. UNLESS the user explicitly disabled inlineSources.
437
- */
438
- inlineSources = true;
439
- }
440
- }
441
411
  let stringified = await map.stringify({
442
412
  file: _path().default.basename(mapFilename),
443
413
  fs: this.options.inputFS,
444
414
  rootDir: this.options.projectRoot,
445
- sourceRoot: !inlineSources ? _url().default.format(_url().default.parse(sourceRoot + '/')) : undefined,
415
+ sourceRoot,
446
416
  inlineSources,
447
417
  format: isInlineMap ? 'inline' : 'string'
448
418
  });
@@ -437,7 +437,7 @@ function reconcileNewRuntimes(api, connections, optionsRef) {
437
437
  name: 'Runtimes',
438
438
  assetGroups,
439
439
  optionsRef,
440
- skipSymbolProp: (0, _featureFlags().getFeatureFlag)('skipRuntimeSymbolProp')
440
+ skipSymbolProp: (0, _featureFlags().getFeatureFlag)('skipRuntimeSymbolProp') || (0, _featureFlags().getFeatureFlag)('rustSymbolTracker')
441
441
  });
442
442
 
443
443
  // rebuild the graph