@atlaspack/core 2.33.1 → 2.35.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 (68) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/dist/AssetGraph.js +4 -72
  3. package/dist/BundleGraph.js +34 -0
  4. package/dist/PackagerRunner.js +13 -88
  5. package/dist/RequestTracker.js +17 -80
  6. package/dist/TargetDescriptor.schema.js +3 -0
  7. package/dist/UncommittedAsset.js +0 -5
  8. package/dist/applyRuntimes.js +2 -1
  9. package/dist/atlaspack-v3/AtlaspackV3.js +6 -2
  10. package/dist/requests/AssetGraphRequest.js +6 -15
  11. package/dist/requests/AssetGraphRequestRust.js +119 -22
  12. package/dist/requests/AtlaspackBuildRequest.js +8 -2
  13. package/dist/requests/BundleGraphRequest.js +9 -15
  14. package/dist/requests/BundleGraphRequestRust.js +1 -2
  15. package/dist/requests/PackageRequest.js +1 -1
  16. package/dist/requests/TargetRequest.js +5 -0
  17. package/dist/requests/WriteBundleRequest.js +129 -12
  18. package/dist/requests/WriteBundlesRequest.js +15 -9
  19. package/dist/resolveOptions.js +2 -4
  20. package/lib/AssetGraph.js +3 -62
  21. package/lib/BundleGraph.js +38 -0
  22. package/lib/PackagerRunner.js +13 -77
  23. package/lib/RequestTracker.js +15 -69
  24. package/lib/TargetDescriptor.schema.js +3 -0
  25. package/lib/UncommittedAsset.js +0 -11
  26. package/lib/applyRuntimes.js +1 -1
  27. package/lib/atlaspack-v3/AtlaspackV3.js +6 -2
  28. package/lib/requests/AssetGraphRequest.js +4 -18
  29. package/lib/requests/AssetGraphRequestRust.js +88 -23
  30. package/lib/requests/AtlaspackBuildRequest.js +8 -2
  31. package/lib/requests/BundleGraphRequest.js +12 -16
  32. package/lib/requests/BundleGraphRequestRust.js +2 -3
  33. package/lib/requests/PackageRequest.js +3 -1
  34. package/lib/requests/TargetRequest.js +5 -0
  35. package/lib/requests/WriteBundleRequest.js +131 -8
  36. package/lib/requests/WriteBundlesRequest.js +12 -5
  37. package/lib/resolveOptions.js +2 -4
  38. package/lib/types/AssetGraph.d.ts +2 -27
  39. package/lib/types/BundleGraph.d.ts +5 -0
  40. package/lib/types/atlaspack-v3/AtlaspackV3.d.ts +3 -2
  41. package/lib/types/requests/BundleGraphRequest.d.ts +1 -1
  42. package/lib/types/requests/WriteBundleRequest.d.ts +20 -1
  43. package/lib/types/types.d.ts +1 -0
  44. package/package.json +15 -15
  45. package/src/AssetGraph.ts +4 -72
  46. package/src/BundleGraph.ts +39 -0
  47. package/src/PackagerRunner.ts +15 -101
  48. package/src/RequestTracker.ts +24 -110
  49. package/src/TargetDescriptor.schema.ts +3 -0
  50. package/src/UncommittedAsset.ts +1 -11
  51. package/src/applyRuntimes.ts +3 -1
  52. package/src/atlaspack-v3/AtlaspackV3.ts +19 -3
  53. package/src/requests/AssetGraphRequest.ts +8 -20
  54. package/src/requests/AssetGraphRequestRust.ts +96 -23
  55. package/src/requests/AtlaspackBuildRequest.ts +16 -8
  56. package/src/requests/BundleGraphRequest.ts +12 -30
  57. package/src/requests/BundleGraphRequestRust.ts +1 -2
  58. package/src/requests/PackageRequest.ts +1 -1
  59. package/src/requests/TargetRequest.ts +5 -0
  60. package/src/requests/WriteBundleRequest.ts +177 -13
  61. package/src/requests/WriteBundlesRequest.ts +25 -13
  62. package/src/resolveOptions.ts +2 -4
  63. package/src/types.ts +1 -0
  64. package/test/AssetGraph.test.ts +0 -32
  65. package/test/RequestTracker.test.ts +0 -165
  66. package/test/TargetRequest.test.ts +25 -0
  67. package/test/requests/WriteBundleRequest.test.ts +239 -0
  68. package/tsconfig.tsbuildinfo +1 -1
@@ -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
  },
@@ -230,7 +238,32 @@ export function getAssetGraph(
230
238
  return envId;
231
239
  };
232
240
 
233
- function updateNode(newNode: AssetGraphNode, isUpdateNode: boolean) {
241
+ function describeNode(node: AssetGraphNode): Record<string, unknown> {
242
+ const base = {type: node.type, id: node.id};
243
+ if (node.type === 'asset') {
244
+ return {
245
+ ...base,
246
+ filePath: node.value.filePath,
247
+ fileType: node.value.type,
248
+ pipeline: node.value.pipeline,
249
+ };
250
+ } else if (node.type === 'dependency') {
251
+ return {
252
+ ...base,
253
+ specifier: node.value.specifier,
254
+ specifierType: node.value.specifierType,
255
+ sourceAssetId: node.value.sourceAssetId,
256
+ sourcePath: node.value.sourcePath,
257
+ };
258
+ }
259
+ return base;
260
+ }
261
+
262
+ function updateNode(
263
+ newNode: AssetGraphNode,
264
+ isUpdateNode: boolean,
265
+ index: number,
266
+ ) {
234
267
  if (isUpdateNode) {
235
268
  let existingNode = graph.getNodeByContentKey(newNode.id);
236
269
 
@@ -238,7 +271,34 @@ export function getAssetGraph(
238
271
 
239
272
  Object.assign(existingNode, newNode);
240
273
  } else {
241
- graph.addNodeByContentKey(newNode.id, newNode);
274
+ try {
275
+ graph.addNodeByContentKey(newNode.id, newNode);
276
+ } catch (e) {
277
+ if (
278
+ e instanceof Error &&
279
+ e.message.includes('already has content key')
280
+ ) {
281
+ let existingNode = graph.getNodeByContentKey(newNode.id);
282
+ let diagnostics = {
283
+ contentKey: newNode.id,
284
+ newNode: describeNode(newNode),
285
+ existingNode: existingNode ? describeNode(existingNode) : null,
286
+ iterationIndex: index,
287
+ totalSerializedNodes: nodesCount,
288
+ newNodesCount: serializedGraph.nodes.length,
289
+ updatesCount: serializedGraph.updates.length,
290
+ edgesCount: serializedGraph.edges.length,
291
+ hadPreviousGraph: !!prevAssetGraph,
292
+ safeToSkipBundling: serializedGraph.safeToSkipBundling,
293
+ graphNodeCount: graph._contentKeyToNodeId.size,
294
+ };
295
+
296
+ throw new Error(
297
+ `Graph already has content key '${newNode.id}'. Diagnostics: ${JSON.stringify(diagnostics, null, 2)}`,
298
+ );
299
+ }
300
+ throw e;
301
+ }
242
302
  }
243
303
  }
244
304
 
@@ -297,7 +357,7 @@ export function getAssetGraph(
297
357
  usedSymbolsUpDirty: true,
298
358
  value: asset,
299
359
  };
300
- updateNode(assetNode, isUpdateNode);
360
+ updateNode(assetNode, isUpdateNode, index);
301
361
  } else if (node.type === 'dependency') {
302
362
  let {dependency, id} = node.value;
303
363
 
@@ -314,6 +374,19 @@ export function getAssetGraph(
314
374
 
315
375
  let usedSymbolsDown = new Set();
316
376
  let usedSymbolsUp = new Map();
377
+
378
+ if (node.used_symbols_up) {
379
+ for (let usedSymbol of node.used_symbols_up) {
380
+ // Transform Rust UsedSymbol { symbol: Symbol, asset: string, resolved_symbol: string }
381
+ // to JS format { symbol: string, asset: string } where symbol is the resolved name
382
+ const exportedName = usedSymbol.symbol.exported;
383
+ usedSymbolsUp.set(exportedName, {
384
+ asset: usedSymbol.asset,
385
+ symbol: usedSymbol.resolved_symbol ?? exportedName,
386
+ });
387
+ }
388
+ }
389
+
317
390
  if (dependency.isEntry && dependency.isLibrary) {
318
391
  usedSymbolsDown.add('*');
319
392
  usedSymbolsUp.set('*', undefined);
@@ -334,7 +407,7 @@ export function getAssetGraph(
334
407
  value: dependency,
335
408
  };
336
409
 
337
- updateNode(depNode, isUpdateNode);
410
+ updateNode(depNode, isUpdateNode, index);
338
411
  }
339
412
  }
340
413
 
@@ -23,7 +23,6 @@ import {tracer} from '@atlaspack/profiler';
23
23
  import {requestTypes} from '../RequestTracker';
24
24
  import {getFeatureFlag} from '@atlaspack/feature-flags';
25
25
  import {fromEnvironmentId} from '../EnvironmentManager';
26
- import invariant from 'assert';
27
26
 
28
27
  type AtlaspackBuildRequestInput = {
29
28
  optionsRef: SharedReference;
@@ -87,12 +86,16 @@ async function run({
87
86
  signal,
88
87
  });
89
88
 
90
- let {bundleGraph, changedAssets, assetRequests}: BundleGraphResult =
91
- await api.runRequest(bundleGraphRequest, {
92
- force:
93
- Boolean(rustAtlaspack) ||
94
- (options.shouldBuildLazily && requestedAssetIds.size > 0),
95
- });
89
+ let {
90
+ bundleGraph,
91
+ changedAssets,
92
+ assetRequests,
93
+ didIncrementallyBundle,
94
+ }: BundleGraphResult = await api.runRequest(bundleGraphRequest, {
95
+ force:
96
+ Boolean(rustAtlaspack) ||
97
+ (options.shouldBuildLazily && requestedAssetIds.size > 0),
98
+ });
96
99
 
97
100
  if (
98
101
  getFeatureFlag('nativePackager') &&
@@ -110,7 +113,12 @@ async function run({
110
113
  }
111
114
  });
112
115
  if (hasSupportedTarget) {
113
- await rustAtlaspack.loadBundleGraph(bundleGraph);
116
+ if (didIncrementallyBundle) {
117
+ const changedAssetIds = Array.from(changedAssets.keys());
118
+ await rustAtlaspack.updateBundleGraph(bundleGraph, changedAssetIds);
119
+ } else {
120
+ await rustAtlaspack.loadBundleGraph(bundleGraph);
121
+ }
114
122
  }
115
123
  }
116
124
 
@@ -14,7 +14,6 @@ import type {ConfigAndCachePath} from './AtlaspackConfigRequest';
14
14
 
15
15
  import fs from 'fs';
16
16
  import invariant from 'assert';
17
- import assert from 'assert';
18
17
  import nullthrows from 'nullthrows';
19
18
  import {instrumentAsync, PluginLogger} from '@atlaspack/logger';
20
19
  import {getFeatureFlag} from '@atlaspack/feature-flags';
@@ -36,13 +35,8 @@ import {
36
35
  createDevDependency,
37
36
  getDevDepRequests,
38
37
  invalidateDevDeps,
39
- runDevDepRequest,
40
38
  } from './DevDepRequest';
41
- import {
42
- loadPluginConfig,
43
- runConfigRequest,
44
- PluginWithLoadConfig,
45
- } from './ConfigRequest';
39
+ import {PluginWithLoadConfig} from './ConfigRequest';
46
40
  import {fromProjectPathRelative} from '../projectPath';
47
41
  import {
48
42
  validateBundles,
@@ -74,9 +68,9 @@ type RunInput = {
74
68
  // TODO: Rename to BundleGraphRequestResult
75
69
  export type BundleGraphResult = {
76
70
  bundleGraph: InternalBundleGraph;
77
- assetGraphBundlingVersion: number;
78
71
  changedAssets: Map<string, Asset>;
79
72
  assetRequests: Array<AssetGroup>;
73
+ didIncrementallyBundle: boolean;
80
74
  };
81
75
 
82
76
  type BundleGraphRequest = {
@@ -151,6 +145,7 @@ export default function createBundleGraphRequest(
151
145
  lazyIncludes: options.lazyIncludes,
152
146
  lazyExcludes: options.lazyExcludes,
153
147
  requestedAssetIds,
148
+ skipSymbolProp: getFeatureFlag('rustSymbolTracker'),
154
149
  });
155
150
 
156
151
  let {assetGraph, changedAssets, assetRequests} = await instrumentAsync(
@@ -213,7 +208,6 @@ export default function createBundleGraphRequest(
213
208
 
214
209
  if (subRequestsInvalid) {
215
210
  assetGraph.safeToIncrementallyBundle = false;
216
- assetGraph.setNeedsBundling();
217
211
  }
218
212
 
219
213
  let configResult = nullthrows(
@@ -282,21 +276,12 @@ class BundlerRunner {
282
276
  this.pluginOptions = new PluginOptions(
283
277
  optionsProxy(this.options, api.invalidateOnOptionChange),
284
278
  );
285
- if (getFeatureFlag('cachePerformanceImprovements')) {
286
- const key = hashString(
279
+ this.cacheKey =
280
+ hashString(
287
281
  `${ATLASPACK_VERSION}:BundleGraph:${
288
282
  JSON.stringify(options.entries) ?? ''
289
283
  }${options.mode}${options.shouldBuildLazily ? 'lazy' : 'eager'}`,
290
- );
291
- this.cacheKey = `BundleGraph/${ATLASPACK_VERSION}/${options.mode}/${key}`;
292
- } else {
293
- this.cacheKey =
294
- hashString(
295
- `${ATLASPACK_VERSION}:BundleGraph:${
296
- JSON.stringify(options.entries) ?? ''
297
- }${options.mode}${options.shouldBuildLazily ? 'lazy' : 'eager'}`,
298
- ) + '-BundleGraph';
299
- }
284
+ ) + '-BundleGraph';
300
285
  }
301
286
 
302
287
  async loadConfigs() {
@@ -343,7 +328,7 @@ class BundlerRunner {
343
328
  type: 'buildProgress',
344
329
  phase: 'bundling',
345
330
  });
346
-
331
+ let didIncrementallyBundle = false;
347
332
  await this.loadConfigs();
348
333
 
349
334
  let plugin = await this.config.getBundler();
@@ -353,14 +338,10 @@ class BundlerRunner {
353
338
  const previousBundleGraphResult: BundleGraphResult | null | undefined =
354
339
  await this.api.getPreviousResult();
355
340
  const canIncrementallyBundle =
356
- previousBundleGraphResult?.assetGraphBundlingVersion != null &&
357
- graph.canIncrementallyBundle(
358
- previousBundleGraphResult.assetGraphBundlingVersion,
359
- );
341
+ previousBundleGraphResult != null && graph.canIncrementallyBundle();
360
342
 
361
343
  if (graph.safeToIncrementallyBundle && previousBundleGraphResult == null) {
362
344
  graph.safeToIncrementallyBundle = false;
363
- graph.setNeedsBundling();
364
345
  }
365
346
 
366
347
  let internalBundleGraph;
@@ -381,6 +362,7 @@ class BundlerRunner {
381
362
  invariant(changedAssetNode.type === 'asset');
382
363
  internalBundleGraph.updateAsset(changedAssetNode);
383
364
  }
365
+ didIncrementallyBundle = true;
384
366
  } else {
385
367
  internalBundleGraph = InternalBundleGraph.fromAssetGraph(
386
368
  graph,
@@ -473,9 +455,9 @@ class BundlerRunner {
473
455
  this.api.storeResult(
474
456
  {
475
457
  bundleGraph: internalBundleGraph,
476
- assetGraphBundlingVersion: graph.getBundlingVersion(),
477
458
  changedAssets: new Map(),
478
459
  assetRequests: [],
460
+ didIncrementallyBundle,
479
461
  },
480
462
  this.cacheKey,
481
463
  );
@@ -559,18 +541,18 @@ class BundlerRunner {
559
541
  this.api.storeResult(
560
542
  {
561
543
  bundleGraph: internalBundleGraph,
562
- assetGraphBundlingVersion: graph.getBundlingVersion(),
563
544
  changedAssets: new Map(),
564
545
  assetRequests: [],
546
+ didIncrementallyBundle,
565
547
  },
566
548
  this.cacheKey,
567
549
  );
568
550
 
569
551
  return {
570
552
  bundleGraph: internalBundleGraph,
571
- assetGraphBundlingVersion: graph.getBundlingVersion(),
572
553
  changedAssets: changedRuntimes,
573
554
  assetRequests,
555
+ didIncrementallyBundle,
574
556
  };
575
557
  }
576
558
  }
@@ -181,10 +181,9 @@ export default function createBundleGraphRequestRust(
181
181
 
182
182
  return {
183
183
  bundleGraph,
184
- // Not accurate yet — ok for now.
185
- assetGraphBundlingVersion: 0,
186
184
  changedAssets: changedRuntimes,
187
185
  assetRequests: [],
186
+ didIncrementallyBundle: false,
188
187
  };
189
188
  },
190
189
  input,
@@ -72,7 +72,7 @@ async function run({input, api, farm, rustAtlaspack}: RunInput<BundleInfo>) {
72
72
  bundle.type === 'js'
73
73
  ) {
74
74
  // Once this actually does something, the code below will be in an `else` block (i.e. we'll only run one or the other)
75
- let result = await rustAtlaspack.package(bundle.id);
75
+ let result = await rustAtlaspack.package(bundle.id, {inlineRequires: true});
76
76
  let error: Diagnostic | null = null;
77
77
  [packagingResult, error] = result;
78
78
  if (error) {
@@ -332,6 +332,7 @@ export class TargetResolver {
332
332
  publicUrl:
333
333
  descriptor.publicUrl ??
334
334
  this.options.defaultTargetOptions.publicUrl,
335
+ inlineRequires: descriptor.inlineRequires ?? false,
335
336
  env: createEnvironment({
336
337
  engines: descriptor.engines,
337
338
  context: descriptor.context,
@@ -426,6 +427,7 @@ export class TargetResolver {
426
427
  this.options.serveOptions.distDir,
427
428
  ),
428
429
  publicUrl: this.options.defaultTargetOptions.publicUrl ?? '/',
430
+ inlineRequires: false,
429
431
  env: createEnvironment({
430
432
  context: 'browser',
431
433
  engines: {
@@ -930,6 +932,7 @@ export class TargetResolver {
930
932
  distEntry,
931
933
  publicUrl:
932
934
  descriptor.publicUrl ?? this.options.defaultTargetOptions.publicUrl,
935
+ inlineRequires: descriptor.inlineRequires ?? false,
933
936
  env: createEnvironment({
934
937
  engines: descriptor.engines ?? pkgEngines,
935
938
  // @ts-expect-error TS2322
@@ -1131,6 +1134,7 @@ export class TargetResolver {
1131
1134
  distEntry,
1132
1135
  publicUrl:
1133
1136
  descriptor.publicUrl ?? this.options.defaultTargetOptions.publicUrl,
1137
+ inlineRequires: descriptor.inlineRequires ?? false,
1134
1138
  env: createEnvironment({
1135
1139
  engines: descriptor.engines ?? pkgEngines,
1136
1140
  context: descriptor.context,
@@ -1205,6 +1209,7 @@ export class TargetResolver {
1205
1209
  path.join(pkgDir, DEFAULT_DIST_DIRNAME),
1206
1210
  ),
1207
1211
  publicUrl: this.options.defaultTargetOptions.publicUrl,
1212
+ inlineRequires: false,
1208
1213
  env: createEnvironment({
1209
1214
  engines: pkgEngines,
1210
1215
  // @ts-expect-error TS2322