@atlaspack/core 2.38.3-dev-862af7d26.0 → 2.38.3
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 +24 -0
- package/dist/requests/AssetGraphRequestRust.js +169 -72
- package/lib/requests/AssetGraphRequestRust.js +157 -68
- package/package.json +21 -22
- package/src/requests/AssetGraphRequestRust.ts +195 -79
- package/tsconfig.tsbuildinfo +1 -1
- package/LICENSE +0 -201
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @atlaspack/core
|
|
2
2
|
|
|
3
|
+
## 2.38.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1065](https://github.com/atlassian-labs/atlaspack/pull/1065) [`e898fda`](https://github.com/atlassian-labs/atlaspack/commit/e898fda7511d98e5597d847c4a32c028a8a24d6c) Thanks [@at-nathan](https://github.com/at-nathan)! - Update third-party dependencies to align with AFM
|
|
8
|
+
|
|
9
|
+
- [#1073](https://github.com/atlassian-labs/atlaspack/pull/1073) [`3ff901a`](https://github.com/atlassian-labs/atlaspack/commit/3ff901a222d5e077a3bb96031a89c3b5173ece69) Thanks [@matt-koko](https://github.com/matt-koko)! - Improve Rust/JS asset graph interop for atlaspack v3 by reducing scenarios where Rust/JS can diverge their respective previous asset graphs.
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [[`07edc83`](https://github.com/atlassian-labs/atlaspack/commit/07edc83079f6a752b09b28a9fe8b45f6523f0f81), [`e898fda`](https://github.com/atlassian-labs/atlaspack/commit/e898fda7511d98e5597d847c4a32c028a8a24d6c), [`3ff901a`](https://github.com/atlassian-labs/atlaspack/commit/3ff901a222d5e077a3bb96031a89c3b5173ece69), [`e8fe5c0`](https://github.com/atlassian-labs/atlaspack/commit/e8fe5c0070f0d92d68f98902edcc96dc82c1e52d), [`ff7e3f0`](https://github.com/atlassian-labs/atlaspack/commit/ff7e3f08c3977b0d9b9edfe739a8e596abbdd729), [`508e15c`](https://github.com/atlassian-labs/atlaspack/commit/508e15c7acd187703bade4d613ca7f5739ae3af7), [`34c7cec`](https://github.com/atlassian-labs/atlaspack/commit/34c7cecebae240f11f36971b4eeaeaaf579531c9), [`5256d37`](https://github.com/atlassian-labs/atlaspack/commit/5256d37a88334554ae78456622389c97f66a2196)]:
|
|
12
|
+
- @atlaspack/rust@3.29.0
|
|
13
|
+
- @atlaspack/cache@3.2.56
|
|
14
|
+
- @atlaspack/utils@3.4.3
|
|
15
|
+
- @atlaspack/feature-flags@2.31.1
|
|
16
|
+
- @atlaspack/fs@2.15.56
|
|
17
|
+
- @atlaspack/logger@2.14.53
|
|
18
|
+
- @atlaspack/source-map@3.3.5
|
|
19
|
+
- @atlaspack/package-manager@2.14.61
|
|
20
|
+
- @atlaspack/profiler@2.15.22
|
|
21
|
+
- @atlaspack/workers@2.14.61
|
|
22
|
+
- @atlaspack/build-cache@2.13.15
|
|
23
|
+
- @atlaspack/graph@3.6.23
|
|
24
|
+
- @atlaspack/types@2.15.51
|
|
25
|
+
- @atlaspack/plugin@2.14.61
|
|
26
|
+
|
|
3
27
|
## 2.38.2
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
|
@@ -74,30 +74,6 @@ function createAssetGraphRequestRust(rustAtlaspack) {
|
|
|
74
74
|
}
|
|
75
75
|
let { assetGraph, changedAssets } = (0, logger_1.instrument)('atlaspack_v3_getAssetGraph', () => getAssetGraph(serializedAssetGraph, prevResult?.assetGraph));
|
|
76
76
|
let changedAssetsPropagation = new Set(changedAssets.keys());
|
|
77
|
-
// Skip symbol propagation for runtime assets - they have pre-computed symbol data
|
|
78
|
-
if (input.skipSymbolProp) {
|
|
79
|
-
logger_1.default.verbose({
|
|
80
|
-
origin: '@atlaspack/core',
|
|
81
|
-
message: 'Skipping symbol propagation for runtime asset graph',
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
let errors = (0, SymbolPropagation_1.propagateSymbols)({
|
|
86
|
-
options,
|
|
87
|
-
assetGraph,
|
|
88
|
-
changedAssetsPropagation,
|
|
89
|
-
assetGroupsWithRemovedParents: new Set(),
|
|
90
|
-
previousErrors: new Map(), //this.previousSymbolPropagationErrors,
|
|
91
|
-
});
|
|
92
|
-
if (errors.size > 0) {
|
|
93
|
-
// Just throw the first error. Since errors can bubble (e.g. reexporting a reexported symbol also fails),
|
|
94
|
-
// determining which failing export is the root cause is nontrivial (because of circular dependencies).
|
|
95
|
-
throw new diagnostic_1.default({
|
|
96
|
-
diagnostic: [...errors.values()][0],
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
await (0, dumpGraphToGraphViz_1.default)(assetGraph, 'AssetGraphV3');
|
|
101
77
|
let result = {
|
|
102
78
|
assetGraph,
|
|
103
79
|
assetRequests: [],
|
|
@@ -106,16 +82,56 @@ function createAssetGraphRequestRust(rustAtlaspack) {
|
|
|
106
82
|
changedAssetsPropagation,
|
|
107
83
|
previousSymbolPropagationErrors: undefined,
|
|
108
84
|
};
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
85
|
+
// When v3AssetGraphSyncImprovements is enabled, wrap downstream steps
|
|
86
|
+
// in try/catch and store the result even on error. This prevents Rust/JS
|
|
87
|
+
// divergence when symbol propagation or commit_assets fails.
|
|
88
|
+
let storeResultOnError = (0, feature_flags_1.getFeatureFlag)('v3AssetGraphSyncImprovements');
|
|
89
|
+
try {
|
|
90
|
+
// Skip symbol propagation for runtime assets - they have pre-computed symbol data
|
|
91
|
+
if (input.skipSymbolProp) {
|
|
92
|
+
logger_1.default.verbose({
|
|
93
|
+
origin: '@atlaspack/core',
|
|
94
|
+
message: 'Skipping symbol propagation for runtime asset graph',
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
let errors = (0, SymbolPropagation_1.propagateSymbols)({
|
|
99
|
+
options,
|
|
100
|
+
assetGraph,
|
|
101
|
+
changedAssetsPropagation,
|
|
102
|
+
assetGroupsWithRemovedParents: new Set(),
|
|
103
|
+
previousErrors: new Map(), //this.previousSymbolPropagationErrors,
|
|
104
|
+
});
|
|
105
|
+
if (errors.size > 0) {
|
|
106
|
+
// Just throw the first error. Since errors can bubble (e.g. reexporting a reexported symbol also fails),
|
|
107
|
+
// determining which failing export is the root cause is nontrivial (because of circular dependencies).
|
|
108
|
+
throw new diagnostic_1.default({
|
|
109
|
+
diagnostic: [...errors.values()][0],
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
await (0, dumpGraphToGraphViz_1.default)(assetGraph, 'AssetGraphV3');
|
|
114
|
+
let [_commitResult, commitError] = await commitPromise;
|
|
115
|
+
if (commitError) {
|
|
116
|
+
throw new diagnostic_1.default({
|
|
117
|
+
diagnostic: {
|
|
118
|
+
message: 'Error committing asset graph in Rust: ' + commitError.message,
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
await runInput.api.storeResult(result);
|
|
123
|
+
runInput.api.invalidateOnBuild();
|
|
124
|
+
}
|
|
125
|
+
catch (e) {
|
|
126
|
+
if (storeResultOnError) {
|
|
127
|
+
// Store the graph even on error to prevent Rust/JS divergence.
|
|
128
|
+
// The graph from getAssetGraph is structurally correct — only
|
|
129
|
+
// downstream processing (symbols, commit) failed.
|
|
130
|
+
await runInput.api.storeResult(result);
|
|
131
|
+
runInput.api.invalidateOnBuild();
|
|
132
|
+
}
|
|
133
|
+
throw e;
|
|
116
134
|
}
|
|
117
|
-
await runInput.api.storeResult(result);
|
|
118
|
-
runInput.api.invalidateOnBuild();
|
|
119
135
|
return result;
|
|
120
136
|
},
|
|
121
137
|
input,
|
|
@@ -124,27 +140,52 @@ function createAssetGraphRequestRust(rustAtlaspack) {
|
|
|
124
140
|
function getAssetGraph(serializedGraph, prevAssetGraph) {
|
|
125
141
|
let graph;
|
|
126
142
|
let reuseEdges = false;
|
|
143
|
+
let clonePrevGraph = (0, feature_flags_1.getFeatureFlag)('v3AssetGraphSyncImprovements');
|
|
127
144
|
if (prevAssetGraph && serializedGraph.safeToSkipBundling) {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
145
|
+
if (clonePrevGraph) {
|
|
146
|
+
graph = new AssetGraph_1.default({
|
|
147
|
+
_contentKeyToNodeId: new Map(prevAssetGraph._contentKeyToNodeId),
|
|
148
|
+
_nodeIdToContentKey: new Map(prevAssetGraph._nodeIdToContentKey),
|
|
149
|
+
nodes: [...prevAssetGraph.nodes],
|
|
150
|
+
rootNodeId: prevAssetGraph.rootNodeId,
|
|
151
|
+
adjacencyList: prevAssetGraph.adjacencyList,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
graph = new AssetGraph_1.default({
|
|
156
|
+
_contentKeyToNodeId: prevAssetGraph._contentKeyToNodeId,
|
|
157
|
+
_nodeIdToContentKey: prevAssetGraph._nodeIdToContentKey,
|
|
158
|
+
nodes: prevAssetGraph.nodes,
|
|
159
|
+
rootNodeId: prevAssetGraph.rootNodeId,
|
|
160
|
+
adjacencyList: prevAssetGraph.adjacencyList,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
135
163
|
reuseEdges = true;
|
|
136
164
|
}
|
|
137
165
|
else if (prevAssetGraph &&
|
|
138
166
|
(serializedGraph.updates.length > 0 || serializedGraph.nodes.length > 0)) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
167
|
+
if (clonePrevGraph) {
|
|
168
|
+
graph = new AssetGraph_1.default({
|
|
169
|
+
_contentKeyToNodeId: new Map(prevAssetGraph._contentKeyToNodeId),
|
|
170
|
+
_nodeIdToContentKey: new Map(prevAssetGraph._nodeIdToContentKey),
|
|
171
|
+
nodes: [...prevAssetGraph.nodes],
|
|
172
|
+
initialCapacity: serializedGraph.edges.length,
|
|
173
|
+
// Accomodate the root node
|
|
174
|
+
initialNodeCapacity: prevAssetGraph.nodes.length + 1,
|
|
175
|
+
rootNodeId: prevAssetGraph.rootNodeId,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
graph = new AssetGraph_1.default({
|
|
180
|
+
_contentKeyToNodeId: prevAssetGraph._contentKeyToNodeId,
|
|
181
|
+
_nodeIdToContentKey: prevAssetGraph._nodeIdToContentKey,
|
|
182
|
+
nodes: prevAssetGraph.nodes,
|
|
183
|
+
initialCapacity: serializedGraph.edges.length,
|
|
184
|
+
// Accomodate the root node
|
|
185
|
+
initialNodeCapacity: prevAssetGraph.nodes.length + 1,
|
|
186
|
+
rootNodeId: prevAssetGraph.rootNodeId,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
148
189
|
graph.safeToIncrementallyBundle = false;
|
|
149
190
|
}
|
|
150
191
|
else {
|
|
@@ -228,36 +269,92 @@ function getAssetGraph(serializedGraph, prevAssetGraph) {
|
|
|
228
269
|
}
|
|
229
270
|
return base;
|
|
230
271
|
}
|
|
272
|
+
function buildDivergenceDiagnostics(divergenceType, newNode, existingNode, index) {
|
|
273
|
+
return {
|
|
274
|
+
contentKey: newNode.id,
|
|
275
|
+
divergenceType,
|
|
276
|
+
newNode: describeNode(newNode),
|
|
277
|
+
existingNode: existingNode ? describeNode(existingNode) : null,
|
|
278
|
+
iterationIndex: index,
|
|
279
|
+
totalSerializedNodes: nodesCount,
|
|
280
|
+
newNodesCount: serializedGraph.nodes.length,
|
|
281
|
+
updatesCount: serializedGraph.updates.length,
|
|
282
|
+
edgesCount: serializedGraph.edges.length,
|
|
283
|
+
hadPreviousGraph: !!prevAssetGraph,
|
|
284
|
+
safeToSkipBundling: serializedGraph.safeToSkipBundling,
|
|
285
|
+
graphNodeCount: graph._contentKeyToNodeId.size,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
231
288
|
function updateNode(newNode, isUpdateNode, index) {
|
|
289
|
+
let healDivergence = (0, feature_flags_1.getFeatureFlag)('v3AssetGraphSyncImprovements');
|
|
232
290
|
if (isUpdateNode) {
|
|
233
291
|
let existingNode = graph.getNodeByContentKey(newNode.id);
|
|
234
|
-
(
|
|
235
|
-
|
|
292
|
+
if (healDivergence) {
|
|
293
|
+
if (existingNode) {
|
|
294
|
+
(0, assert_2.default)(existingNode.type === newNode.type);
|
|
295
|
+
Object.assign(existingNode, newNode);
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
// Rust sent an update for a node JS doesn't have.
|
|
299
|
+
// This means JS's graph is stale. Add the node as new instead.
|
|
300
|
+
// This handles the "undefined == true" error class.
|
|
301
|
+
let diagnostics = buildDivergenceDiagnostics('update_node_not_found', newNode, existingNode, index);
|
|
302
|
+
logger_1.default.warn({
|
|
303
|
+
origin: '@atlaspack/core',
|
|
304
|
+
message: `Rust/JS asset graph divergence healed: update node not found, ` +
|
|
305
|
+
`adding as new. contentKey=${newNode.id} type=${newNode.type} iterationIndex=${index}`,
|
|
306
|
+
meta: {
|
|
307
|
+
trackableEvent: 'asset_graph_divergence_healed',
|
|
308
|
+
...diagnostics,
|
|
309
|
+
},
|
|
310
|
+
});
|
|
311
|
+
graph.addNodeByContentKey(newNode.id, newNode);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
(0, assert_2.default)(existingNode && existingNode.type === newNode.type);
|
|
316
|
+
Object.assign(existingNode, newNode);
|
|
317
|
+
}
|
|
236
318
|
}
|
|
237
319
|
else {
|
|
238
|
-
|
|
239
|
-
graph.
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
320
|
+
if (healDivergence) {
|
|
321
|
+
if (graph.hasContentKey(newNode.id)) {
|
|
322
|
+
// Rust sent a "new" node that JS already has.
|
|
323
|
+
// This means JS's graph has nodes that Rust considers new.
|
|
324
|
+
// Treat as an update instead of throwing.
|
|
325
|
+
// This handles the "Graph already has content key" error class.
|
|
244
326
|
let existingNode = graph.getNodeByContentKey(newNode.id);
|
|
245
|
-
let diagnostics =
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
258
|
-
|
|
327
|
+
let diagnostics = buildDivergenceDiagnostics('new_node_already_exists', newNode, existingNode, index);
|
|
328
|
+
logger_1.default.warn({
|
|
329
|
+
origin: '@atlaspack/core',
|
|
330
|
+
message: `Rust/JS asset graph divergence healed: new node already exists, ` +
|
|
331
|
+
`treating as update. contentKey=${newNode.id} type=${newNode.type} iterationIndex=${index}`,
|
|
332
|
+
meta: {
|
|
333
|
+
trackableEvent: 'asset_graph_divergence_healed',
|
|
334
|
+
...diagnostics,
|
|
335
|
+
},
|
|
336
|
+
});
|
|
337
|
+
if (existingNode) {
|
|
338
|
+
Object.assign(existingNode, newNode);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
graph.addNodeByContentKey(newNode.id, newNode);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
try {
|
|
347
|
+
graph.addNodeByContentKey(newNode.id, newNode);
|
|
348
|
+
}
|
|
349
|
+
catch (e) {
|
|
350
|
+
if (e instanceof Error &&
|
|
351
|
+
e.message.includes('already has content key')) {
|
|
352
|
+
let existingNode = graph.getNodeByContentKey(newNode.id);
|
|
353
|
+
let diagnostics = buildDivergenceDiagnostics('new_node_already_exists', newNode, existingNode, index);
|
|
354
|
+
throw new Error(`Graph already has content key '${newNode.id}'. Diagnostics: ${JSON.stringify(diagnostics, null, 2)}`);
|
|
355
|
+
}
|
|
356
|
+
throw e;
|
|
259
357
|
}
|
|
260
|
-
throw e;
|
|
261
358
|
}
|
|
262
359
|
}
|
|
263
360
|
}
|
|
@@ -75,29 +75,6 @@ function createAssetGraphRequestRust(rustAtlaspack) {
|
|
|
75
75
|
return getAssetGraph(serializedAssetGraph, (_prevResult = prevResult) === null || _prevResult === void 0 ? void 0 : _prevResult.assetGraph);
|
|
76
76
|
});
|
|
77
77
|
let changedAssetsPropagation = new Set(changedAssets.keys());
|
|
78
|
-
// Skip symbol propagation for runtime assets - they have pre-computed symbol data
|
|
79
|
-
if (input.skipSymbolProp) {
|
|
80
|
-
_logger().default.verbose({
|
|
81
|
-
origin: '@atlaspack/core',
|
|
82
|
-
message: 'Skipping symbol propagation for runtime asset graph'
|
|
83
|
-
});
|
|
84
|
-
} else {
|
|
85
|
-
let errors = (0, _SymbolPropagation.propagateSymbols)({
|
|
86
|
-
options,
|
|
87
|
-
assetGraph,
|
|
88
|
-
changedAssetsPropagation,
|
|
89
|
-
assetGroupsWithRemovedParents: new Set(),
|
|
90
|
-
previousErrors: new Map() //this.previousSymbolPropagationErrors,
|
|
91
|
-
});
|
|
92
|
-
if (errors.size > 0) {
|
|
93
|
-
// Just throw the first error. Since errors can bubble (e.g. reexporting a reexported symbol also fails),
|
|
94
|
-
// determining which failing export is the root cause is nontrivial (because of circular dependencies).
|
|
95
|
-
throw new (_diagnostic().default)({
|
|
96
|
-
diagnostic: [...errors.values()][0]
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
await (0, _dumpGraphToGraphViz.default)(assetGraph, 'AssetGraphV3');
|
|
101
78
|
let result = {
|
|
102
79
|
assetGraph,
|
|
103
80
|
assetRequests: [],
|
|
@@ -106,16 +83,55 @@ function createAssetGraphRequestRust(rustAtlaspack) {
|
|
|
106
83
|
changedAssetsPropagation,
|
|
107
84
|
previousSymbolPropagationErrors: undefined
|
|
108
85
|
};
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
86
|
+
|
|
87
|
+
// When v3AssetGraphSyncImprovements is enabled, wrap downstream steps
|
|
88
|
+
// in try/catch and store the result even on error. This prevents Rust/JS
|
|
89
|
+
// divergence when symbol propagation or commit_assets fails.
|
|
90
|
+
let storeResultOnError = (0, _featureFlags().getFeatureFlag)('v3AssetGraphSyncImprovements');
|
|
91
|
+
try {
|
|
92
|
+
// Skip symbol propagation for runtime assets - they have pre-computed symbol data
|
|
93
|
+
if (input.skipSymbolProp) {
|
|
94
|
+
_logger().default.verbose({
|
|
95
|
+
origin: '@atlaspack/core',
|
|
96
|
+
message: 'Skipping symbol propagation for runtime asset graph'
|
|
97
|
+
});
|
|
98
|
+
} else {
|
|
99
|
+
let errors = (0, _SymbolPropagation.propagateSymbols)({
|
|
100
|
+
options,
|
|
101
|
+
assetGraph,
|
|
102
|
+
changedAssetsPropagation,
|
|
103
|
+
assetGroupsWithRemovedParents: new Set(),
|
|
104
|
+
previousErrors: new Map() //this.previousSymbolPropagationErrors,
|
|
105
|
+
});
|
|
106
|
+
if (errors.size > 0) {
|
|
107
|
+
// Just throw the first error. Since errors can bubble (e.g. reexporting a reexported symbol also fails),
|
|
108
|
+
// determining which failing export is the root cause is nontrivial (because of circular dependencies).
|
|
109
|
+
throw new (_diagnostic().default)({
|
|
110
|
+
diagnostic: [...errors.values()][0]
|
|
111
|
+
});
|
|
114
112
|
}
|
|
115
|
-
}
|
|
113
|
+
}
|
|
114
|
+
await (0, _dumpGraphToGraphViz.default)(assetGraph, 'AssetGraphV3');
|
|
115
|
+
let [_commitResult, commitError] = await commitPromise;
|
|
116
|
+
if (commitError) {
|
|
117
|
+
throw new (_diagnostic().default)({
|
|
118
|
+
diagnostic: {
|
|
119
|
+
message: 'Error committing asset graph in Rust: ' + commitError.message
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
await runInput.api.storeResult(result);
|
|
124
|
+
runInput.api.invalidateOnBuild();
|
|
125
|
+
} catch (e) {
|
|
126
|
+
if (storeResultOnError) {
|
|
127
|
+
// Store the graph even on error to prevent Rust/JS divergence.
|
|
128
|
+
// The graph from getAssetGraph is structurally correct — only
|
|
129
|
+
// downstream processing (symbols, commit) failed.
|
|
130
|
+
await runInput.api.storeResult(result);
|
|
131
|
+
runInput.api.invalidateOnBuild();
|
|
132
|
+
}
|
|
133
|
+
throw e;
|
|
116
134
|
}
|
|
117
|
-
await runInput.api.storeResult(result);
|
|
118
|
-
runInput.api.invalidateOnBuild();
|
|
119
135
|
return result;
|
|
120
136
|
},
|
|
121
137
|
input
|
|
@@ -124,25 +140,48 @@ function createAssetGraphRequestRust(rustAtlaspack) {
|
|
|
124
140
|
function getAssetGraph(serializedGraph, prevAssetGraph) {
|
|
125
141
|
let graph;
|
|
126
142
|
let reuseEdges = false;
|
|
143
|
+
let clonePrevGraph = (0, _featureFlags().getFeatureFlag)('v3AssetGraphSyncImprovements');
|
|
127
144
|
if (prevAssetGraph && serializedGraph.safeToSkipBundling) {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
145
|
+
if (clonePrevGraph) {
|
|
146
|
+
graph = new _AssetGraph.default({
|
|
147
|
+
_contentKeyToNodeId: new Map(prevAssetGraph._contentKeyToNodeId),
|
|
148
|
+
_nodeIdToContentKey: new Map(prevAssetGraph._nodeIdToContentKey),
|
|
149
|
+
nodes: [...prevAssetGraph.nodes],
|
|
150
|
+
rootNodeId: prevAssetGraph.rootNodeId,
|
|
151
|
+
adjacencyList: prevAssetGraph.adjacencyList
|
|
152
|
+
});
|
|
153
|
+
} else {
|
|
154
|
+
graph = new _AssetGraph.default({
|
|
155
|
+
_contentKeyToNodeId: prevAssetGraph._contentKeyToNodeId,
|
|
156
|
+
_nodeIdToContentKey: prevAssetGraph._nodeIdToContentKey,
|
|
157
|
+
nodes: prevAssetGraph.nodes,
|
|
158
|
+
rootNodeId: prevAssetGraph.rootNodeId,
|
|
159
|
+
adjacencyList: prevAssetGraph.adjacencyList
|
|
160
|
+
});
|
|
161
|
+
}
|
|
135
162
|
reuseEdges = true;
|
|
136
163
|
} else if (prevAssetGraph && (serializedGraph.updates.length > 0 || serializedGraph.nodes.length > 0)) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
164
|
+
if (clonePrevGraph) {
|
|
165
|
+
graph = new _AssetGraph.default({
|
|
166
|
+
_contentKeyToNodeId: new Map(prevAssetGraph._contentKeyToNodeId),
|
|
167
|
+
_nodeIdToContentKey: new Map(prevAssetGraph._nodeIdToContentKey),
|
|
168
|
+
nodes: [...prevAssetGraph.nodes],
|
|
169
|
+
initialCapacity: serializedGraph.edges.length,
|
|
170
|
+
// Accomodate the root node
|
|
171
|
+
initialNodeCapacity: prevAssetGraph.nodes.length + 1,
|
|
172
|
+
rootNodeId: prevAssetGraph.rootNodeId
|
|
173
|
+
});
|
|
174
|
+
} else {
|
|
175
|
+
graph = new _AssetGraph.default({
|
|
176
|
+
_contentKeyToNodeId: prevAssetGraph._contentKeyToNodeId,
|
|
177
|
+
_nodeIdToContentKey: prevAssetGraph._nodeIdToContentKey,
|
|
178
|
+
nodes: prevAssetGraph.nodes,
|
|
179
|
+
initialCapacity: serializedGraph.edges.length,
|
|
180
|
+
// Accomodate the root node
|
|
181
|
+
initialNodeCapacity: prevAssetGraph.nodes.length + 1,
|
|
182
|
+
rootNodeId: prevAssetGraph.rootNodeId
|
|
183
|
+
});
|
|
184
|
+
}
|
|
146
185
|
graph.safeToIncrementallyBundle = false;
|
|
147
186
|
} else {
|
|
148
187
|
graph = new _AssetGraph.default({
|
|
@@ -220,33 +259,83 @@ function getAssetGraph(serializedGraph, prevAssetGraph) {
|
|
|
220
259
|
}
|
|
221
260
|
return base;
|
|
222
261
|
}
|
|
262
|
+
function buildDivergenceDiagnostics(divergenceType, newNode, existingNode, index) {
|
|
263
|
+
return {
|
|
264
|
+
contentKey: newNode.id,
|
|
265
|
+
divergenceType,
|
|
266
|
+
newNode: describeNode(newNode),
|
|
267
|
+
existingNode: existingNode ? describeNode(existingNode) : null,
|
|
268
|
+
iterationIndex: index,
|
|
269
|
+
totalSerializedNodes: nodesCount,
|
|
270
|
+
newNodesCount: serializedGraph.nodes.length,
|
|
271
|
+
updatesCount: serializedGraph.updates.length,
|
|
272
|
+
edgesCount: serializedGraph.edges.length,
|
|
273
|
+
hadPreviousGraph: !!prevAssetGraph,
|
|
274
|
+
safeToSkipBundling: serializedGraph.safeToSkipBundling,
|
|
275
|
+
graphNodeCount: graph._contentKeyToNodeId.size
|
|
276
|
+
};
|
|
277
|
+
}
|
|
223
278
|
function updateNode(newNode, isUpdateNode, index) {
|
|
279
|
+
let healDivergence = (0, _featureFlags().getFeatureFlag)('v3AssetGraphSyncImprovements');
|
|
224
280
|
if (isUpdateNode) {
|
|
225
281
|
let existingNode = graph.getNodeByContentKey(newNode.id);
|
|
226
|
-
|
|
227
|
-
|
|
282
|
+
if (healDivergence) {
|
|
283
|
+
if (existingNode) {
|
|
284
|
+
(0, _assert().default)(existingNode.type === newNode.type);
|
|
285
|
+
Object.assign(existingNode, newNode);
|
|
286
|
+
} else {
|
|
287
|
+
// Rust sent an update for a node JS doesn't have.
|
|
288
|
+
// This means JS's graph is stale. Add the node as new instead.
|
|
289
|
+
// This handles the "undefined == true" error class.
|
|
290
|
+
let diagnostics = buildDivergenceDiagnostics('update_node_not_found', newNode, existingNode, index);
|
|
291
|
+
_logger().default.warn({
|
|
292
|
+
origin: '@atlaspack/core',
|
|
293
|
+
message: `Rust/JS asset graph divergence healed: update node not found, ` + `adding as new. contentKey=${newNode.id} type=${newNode.type} iterationIndex=${index}`,
|
|
294
|
+
meta: {
|
|
295
|
+
trackableEvent: 'asset_graph_divergence_healed',
|
|
296
|
+
...diagnostics
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
graph.addNodeByContentKey(newNode.id, newNode);
|
|
300
|
+
}
|
|
301
|
+
} else {
|
|
302
|
+
(0, _assert().default)(existingNode && existingNode.type === newNode.type);
|
|
303
|
+
Object.assign(existingNode, newNode);
|
|
304
|
+
}
|
|
228
305
|
} else {
|
|
229
|
-
|
|
230
|
-
graph.
|
|
231
|
-
|
|
232
|
-
|
|
306
|
+
if (healDivergence) {
|
|
307
|
+
if (graph.hasContentKey(newNode.id)) {
|
|
308
|
+
// Rust sent a "new" node that JS already has.
|
|
309
|
+
// This means JS's graph has nodes that Rust considers new.
|
|
310
|
+
// Treat as an update instead of throwing.
|
|
311
|
+
// This handles the "Graph already has content key" error class.
|
|
233
312
|
let existingNode = graph.getNodeByContentKey(newNode.id);
|
|
234
|
-
let diagnostics =
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
313
|
+
let diagnostics = buildDivergenceDiagnostics('new_node_already_exists', newNode, existingNode, index);
|
|
314
|
+
_logger().default.warn({
|
|
315
|
+
origin: '@atlaspack/core',
|
|
316
|
+
message: `Rust/JS asset graph divergence healed: new node already exists, ` + `treating as update. contentKey=${newNode.id} type=${newNode.type} iterationIndex=${index}`,
|
|
317
|
+
meta: {
|
|
318
|
+
trackableEvent: 'asset_graph_divergence_healed',
|
|
319
|
+
...diagnostics
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
if (existingNode) {
|
|
323
|
+
Object.assign(existingNode, newNode);
|
|
324
|
+
}
|
|
325
|
+
} else {
|
|
326
|
+
graph.addNodeByContentKey(newNode.id, newNode);
|
|
327
|
+
}
|
|
328
|
+
} else {
|
|
329
|
+
try {
|
|
330
|
+
graph.addNodeByContentKey(newNode.id, newNode);
|
|
331
|
+
} catch (e) {
|
|
332
|
+
if (e instanceof Error && e.message.includes('already has content key')) {
|
|
333
|
+
let existingNode = graph.getNodeByContentKey(newNode.id);
|
|
334
|
+
let diagnostics = buildDivergenceDiagnostics('new_node_already_exists', newNode, existingNode, index);
|
|
335
|
+
throw new Error(`Graph already has content key '${newNode.id}'. Diagnostics: ${JSON.stringify(diagnostics, null, 2)}`);
|
|
336
|
+
}
|
|
337
|
+
throw e;
|
|
248
338
|
}
|
|
249
|
-
throw e;
|
|
250
339
|
}
|
|
251
340
|
}
|
|
252
341
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaspack/core",
|
|
3
|
-
"version": "2.38.3
|
|
3
|
+
"version": "2.38.3",
|
|
4
4
|
"license": "(MIT OR Apache-2.0)",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -22,23 +22,23 @@
|
|
|
22
22
|
"build:lib": "gulp build --gulpfile ../../../gulpfile.js --cwd ."
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@atlaspack/build-cache": "2.13.15-dev-862af7d26.0",
|
|
26
|
-
"@atlaspack/cache": "3.2.56-dev-862af7d26.0",
|
|
27
|
-
"@atlaspack/diagnostic": "2.14.5-dev-862af7d26.0",
|
|
28
|
-
"@atlaspack/events": "2.14.5-dev-862af7d26.0",
|
|
29
|
-
"@atlaspack/feature-flags": "2.31.1-dev-862af7d26.0",
|
|
30
|
-
"@atlaspack/fs": "2.15.56-dev-862af7d26.0",
|
|
31
|
-
"@atlaspack/graph": "3.6.23-dev-862af7d26.0",
|
|
32
|
-
"@atlaspack/logger": "2.14.53-dev-862af7d26.0",
|
|
33
|
-
"@atlaspack/package-manager": "2.14.61-dev-862af7d26.0",
|
|
34
|
-
"@atlaspack/plugin": "2.14.61-dev-862af7d26.0",
|
|
35
|
-
"@atlaspack/profiler": "2.15.22-dev-862af7d26.0",
|
|
36
|
-
"@atlaspack/rust": "3.28.1-dev-862af7d26.0",
|
|
37
|
-
"@atlaspack/source-map": "3.3.5-dev-862af7d26.0",
|
|
38
|
-
"@atlaspack/types": "2.15.51-dev-862af7d26.0",
|
|
39
|
-
"@atlaspack/utils": "3.4.3-dev-862af7d26.0",
|
|
40
|
-
"@atlaspack/workers": "2.14.61-dev-862af7d26.0",
|
|
41
25
|
"@mischnic/json-sourcemap": "^0.1.0",
|
|
26
|
+
"@atlaspack/build-cache": "2.13.15",
|
|
27
|
+
"@atlaspack/cache": "3.2.56",
|
|
28
|
+
"@atlaspack/diagnostic": "2.14.4",
|
|
29
|
+
"@atlaspack/events": "2.14.4",
|
|
30
|
+
"@atlaspack/feature-flags": "2.31.1",
|
|
31
|
+
"@atlaspack/fs": "2.15.56",
|
|
32
|
+
"@atlaspack/graph": "3.6.23",
|
|
33
|
+
"@atlaspack/logger": "2.14.53",
|
|
34
|
+
"@atlaspack/package-manager": "2.14.61",
|
|
35
|
+
"@atlaspack/plugin": "2.14.61",
|
|
36
|
+
"@atlaspack/profiler": "2.15.22",
|
|
37
|
+
"@atlaspack/rust": "3.29.0",
|
|
38
|
+
"@atlaspack/types": "2.15.51",
|
|
39
|
+
"@atlaspack/utils": "3.4.3",
|
|
40
|
+
"@atlaspack/workers": "2.14.61",
|
|
41
|
+
"@atlaspack/source-map": "3.3.5",
|
|
42
42
|
"base-x": "^3.0.8",
|
|
43
43
|
"browserslist": "^4.6.6",
|
|
44
44
|
"clone": "^2.1.1",
|
|
@@ -50,16 +50,15 @@
|
|
|
50
50
|
"semver": "^7.5.2"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@atlaspack/babel-register": "2.14.5
|
|
53
|
+
"@atlaspack/babel-register": "2.14.5",
|
|
54
54
|
"@types/node": ">= 18",
|
|
55
|
-
"graphviz": "^0.0.9",
|
|
56
|
-
"jest-diff": "*",
|
|
57
55
|
"rfdc": "1",
|
|
56
|
+
"jest-diff": "*",
|
|
57
|
+
"graphviz": "^0.0.9",
|
|
58
58
|
"tempy": "^0.2.1"
|
|
59
59
|
},
|
|
60
60
|
"browser": {
|
|
61
61
|
"./src/serializerCore.js": "./src/serializerCore.browser.js"
|
|
62
62
|
},
|
|
63
|
-
"type": "commonjs"
|
|
64
|
-
"gitHead": "862af7d26148df894cc5217b53d6cfac1bdc1026"
|
|
63
|
+
"type": "commonjs"
|
|
65
64
|
}
|