@atlaspack/core 2.12.1-dev.3401 → 2.12.1-dev.3443
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/lib/AssetGraph.js +1 -2
- package/lib/Atlaspack.js +25 -3
- package/lib/AtlaspackConfig.schema.js +10 -36
- package/lib/BundleGraph.js +59 -5
- package/lib/Dependency.js +46 -1
- package/lib/Environment.js +12 -2
- package/lib/PackagerRunner.js +3 -45
- package/lib/RequestTracker.js +112 -30
- package/lib/SymbolPropagation.js +1 -1
- package/lib/Transformation.js +1 -15
- package/lib/UncommittedAsset.js +4 -4
- package/lib/Validation.js +1 -13
- package/lib/applyRuntimes.js +96 -20
- package/lib/assetUtils.js +9 -3
- package/lib/atlaspack-v3/AtlaspackV3.js +6 -8
- package/lib/atlaspack-v3/fs.js +8 -1
- package/lib/atlaspack-v3/worker/compat.js +57 -0
- package/lib/atlaspack-v3/worker/worker.js +156 -1
- package/lib/public/BundleGraph.js +68 -0
- package/lib/requests/AssetGraphRequestRust.js +79 -12
- package/lib/requests/BundleGraphRequest.js +19 -0
- package/lib/requests/WriteBundleRequest.js +15 -15
- package/lib/requests/asset-graph-diff.js +128 -0
- package/lib/resolveOptions.js +15 -8
- package/lib/types.js +2 -1
- package/package.json +19 -17
- package/src/AssetGraph.js +1 -1
- package/src/Atlaspack.js +28 -6
- package/src/AtlaspackConfig.schema.js +13 -36
- package/src/BundleGraph.js +77 -1
- package/src/CommittedAsset.js +1 -1
- package/src/Dependency.js +50 -12
- package/src/Environment.js +13 -15
- package/src/PackagerRunner.js +5 -53
- package/src/RequestTracker.js +144 -38
- package/src/SymbolPropagation.js +5 -2
- package/src/Transformation.js +1 -9
- package/src/UncommittedAsset.js +6 -6
- package/src/Validation.js +1 -7
- package/src/applyRuntimes.js +86 -22
- package/src/assetUtils.js +12 -19
- package/src/atlaspack-v3/AtlaspackV3.js +8 -11
- package/src/atlaspack-v3/fs.js +8 -3
- package/src/atlaspack-v3/jsCallable.js +4 -0
- package/src/atlaspack-v3/worker/compat.js +82 -0
- package/src/atlaspack-v3/worker/worker.js +209 -2
- package/src/public/BundleGraph.js +106 -0
- package/src/requests/AssetGraphRequestRust.js +105 -17
- package/src/requests/BundleGraphRequest.js +18 -0
- package/src/requests/WriteBundleRequest.js +17 -23
- package/src/requests/asset-graph-diff.js +145 -0
- package/src/resolveOptions.js +12 -2
- package/src/types.js +10 -0
- package/test/AssetGraph.test.js +23 -9
- package/test/AtlaspackConfigRequest.test.js +0 -161
- package/test/BundleGraph.test.js +8 -3
- package/test/Dependency.test.js +21 -0
- package/test/Environment.test.js +16 -5
- package/test/InternalAsset.test.js +8 -2
- package/test/PublicAsset.test.js +6 -2
- package/test/PublicBundle.test.js +1 -0
- package/test/PublicMutableBundleGraph.test.js +9 -4
- package/test/RequestTracker.test.js +139 -2
- package/test/SymbolPropagation.test.js +1 -0
- package/test/TargetRequest.test.js +25 -25
- package/test/requests/WriteBundleRequest.test.js +132 -0
- package/lib/atlaspack-v3/plugins/Resolver.js +0 -12
- package/lib/atlaspack-v3/plugins/index.js +0 -16
- package/src/atlaspack-v3/plugins/Resolver.js +0 -9
- package/src/atlaspack-v3/plugins/index.js +0 -3
package/lib/RequestTracker.js
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.RequestGraph = void 0;
|
|
7
|
+
exports.cleanUpOrphans = cleanUpOrphans;
|
|
8
|
+
exports.default = void 0;
|
|
7
9
|
exports.getWatcherOptions = getWatcherOptions;
|
|
8
10
|
exports.readAndDeserializeRequestGraph = readAndDeserializeRequestGraph;
|
|
9
11
|
exports.requestTypes = exports.requestGraphEdgeTypes = void 0;
|
|
@@ -21,6 +23,13 @@ function _path2() {
|
|
|
21
23
|
};
|
|
22
24
|
return data;
|
|
23
25
|
}
|
|
26
|
+
function _featureFlags() {
|
|
27
|
+
const data = require("@atlaspack/feature-flags");
|
|
28
|
+
_featureFlags = function () {
|
|
29
|
+
return data;
|
|
30
|
+
};
|
|
31
|
+
return data;
|
|
32
|
+
}
|
|
24
33
|
function _graph() {
|
|
25
34
|
const data = require("@atlaspack/graph");
|
|
26
35
|
_graph = function () {
|
|
@@ -204,7 +213,7 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
204
213
|
this.removeCachedRequestChunkForNode(nodeId);
|
|
205
214
|
return nodeId;
|
|
206
215
|
}
|
|
207
|
-
removeNode(nodeId) {
|
|
216
|
+
removeNode(nodeId, removeOrphans = true) {
|
|
208
217
|
this.invalidNodeIds.delete(nodeId);
|
|
209
218
|
this.incompleteNodeIds.delete(nodeId);
|
|
210
219
|
this.incompleteNodePromises.delete(nodeId);
|
|
@@ -222,7 +231,7 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
222
231
|
configKeyNodes.delete(nodeId);
|
|
223
232
|
}
|
|
224
233
|
}
|
|
225
|
-
return super.removeNode(nodeId);
|
|
234
|
+
return super.removeNode(nodeId, removeOrphans);
|
|
226
235
|
}
|
|
227
236
|
getRequestNode(nodeId) {
|
|
228
237
|
let node = (0, _nullthrows().default)(this.getNode(nodeId));
|
|
@@ -456,18 +465,32 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
456
465
|
return node;
|
|
457
466
|
});
|
|
458
467
|
}
|
|
459
|
-
invalidateFileNameNode(node, filePath, matchNodes) {
|
|
468
|
+
invalidateFileNameNode(node, filePath, matchNodes, invalidateNode) {
|
|
460
469
|
// If there is an edge between this file_name node and one of the original file nodes pointed to
|
|
461
470
|
// by the original file_name node, and the matched node is inside the current directory, invalidate
|
|
462
471
|
// all connected requests pointed to by the file node.
|
|
463
|
-
|
|
472
|
+
|
|
464
473
|
let nodeId = this.getNodeIdByContentKey(node.id);
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
474
|
+
let dirname = _path2().default.dirname((0, _projectPath.fromProjectPathRelative)(filePath));
|
|
475
|
+
if ((0, _featureFlags().getFeatureFlag)('fixQuadraticCacheInvalidation')) {
|
|
476
|
+
while (dirname !== '/') {
|
|
477
|
+
if (!this.hasContentKey(dirname)) break;
|
|
478
|
+
const matchNodeId = this.getNodeIdByContentKey(dirname);
|
|
479
|
+
if (!this.hasEdge(nodeId, matchNodeId, requestGraphEdgeTypes.invalidated_by_create_above)) break;
|
|
480
|
+
const connectedNodes = this.getNodeIdsConnectedTo(matchNodeId, requestGraphEdgeTypes.invalidated_by_create);
|
|
469
481
|
for (let connectedNode of connectedNodes) {
|
|
470
|
-
|
|
482
|
+
invalidateNode(connectedNode, _constants.FILE_CREATE);
|
|
483
|
+
}
|
|
484
|
+
dirname = _path2().default.dirname(dirname);
|
|
485
|
+
}
|
|
486
|
+
} else {
|
|
487
|
+
for (let matchNode of matchNodes) {
|
|
488
|
+
let matchNodeId = this.getNodeIdByContentKey(matchNode.id);
|
|
489
|
+
if (this.hasEdge(nodeId, matchNodeId, requestGraphEdgeTypes.invalidated_by_create_above) && (0, _utils().isDirectoryInside)((0, _projectPath.fromProjectPathRelative)((0, _projectPath.toProjectPathUnsafe)(matchNode.id)), dirname)) {
|
|
490
|
+
let connectedNodes = this.getNodeIdsConnectedTo(matchNodeId, requestGraphEdgeTypes.invalidated_by_create);
|
|
491
|
+
for (let connectedNode of connectedNodes) {
|
|
492
|
+
this.invalidateNode(connectedNode, _constants.FILE_CREATE);
|
|
493
|
+
}
|
|
471
494
|
}
|
|
472
495
|
}
|
|
473
496
|
}
|
|
@@ -480,7 +503,7 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
480
503
|
if (this.hasEdge(nodeId, this.getNodeIdByContentKey(contentKey), requestGraphEdgeTypes.dirname)) {
|
|
481
504
|
let parent = (0, _nullthrows().default)(this.getNodeByContentKey(contentKey));
|
|
482
505
|
(0, _assert().default)(parent.type === FILE_NAME);
|
|
483
|
-
this.invalidateFileNameNode(parent, (0, _projectPath.toProjectPathUnsafe)(dirname), matchNodes);
|
|
506
|
+
this.invalidateFileNameNode(parent, (0, _projectPath.toProjectPathUnsafe)(dirname), matchNodes, invalidateNode);
|
|
484
507
|
}
|
|
485
508
|
}
|
|
486
509
|
}
|
|
@@ -489,11 +512,38 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
489
512
|
let count = 0;
|
|
490
513
|
let predictedTime = 0;
|
|
491
514
|
let startTime = Date.now();
|
|
515
|
+
const enableOptimization = (0, _featureFlags().getFeatureFlag)('fixQuadraticCacheInvalidation');
|
|
516
|
+
const removeOrphans = !enableOptimization;
|
|
517
|
+
const invalidatedNodes = new Set();
|
|
518
|
+
const invalidateNode = (nodeId, reason) => {
|
|
519
|
+
if (enableOptimization && invalidatedNodes.has(nodeId)) {
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
invalidatedNodes.add(nodeId);
|
|
523
|
+
this.invalidateNode(nodeId, reason);
|
|
524
|
+
};
|
|
525
|
+
const aboveCache = new Map();
|
|
526
|
+
const getAbove = fileNameNodeId => {
|
|
527
|
+
const cachedResult = aboveCache.get(fileNameNodeId);
|
|
528
|
+
if (enableOptimization && cachedResult) {
|
|
529
|
+
return cachedResult;
|
|
530
|
+
}
|
|
531
|
+
let above = [];
|
|
532
|
+
const children = this.getNodeIdsConnectedTo(fileNameNodeId, requestGraphEdgeTypes.invalidated_by_create_above);
|
|
533
|
+
for (const nodeId of children) {
|
|
534
|
+
let node = (0, _nullthrows().default)(this.getNode(nodeId));
|
|
535
|
+
if (node.type === FILE) {
|
|
536
|
+
above.push(node);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
aboveCache.set(fileNameNodeId, above);
|
|
540
|
+
return above;
|
|
541
|
+
};
|
|
492
542
|
for (let {
|
|
493
543
|
path: _path,
|
|
494
544
|
type
|
|
495
545
|
} of events) {
|
|
496
|
-
if (++count === 256) {
|
|
546
|
+
if (!enableOptimization && process.env.ATLASPACK_DISABLE_CACHE_TIMEOUT !== 'true' && ++count === 256) {
|
|
497
547
|
let duration = Date.now() - startTime;
|
|
498
548
|
predictedTime = duration * (events.length >> 8);
|
|
499
549
|
if (predictedTime > threshold) {
|
|
@@ -540,13 +590,13 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
540
590
|
let nodes = this.getNodeIdsConnectedTo(nodeId, requestGraphEdgeTypes.invalidated_by_update);
|
|
541
591
|
for (let connectedNode of nodes) {
|
|
542
592
|
didInvalidate = true;
|
|
543
|
-
|
|
593
|
+
invalidateNode(connectedNode, _constants.FILE_UPDATE);
|
|
544
594
|
}
|
|
545
595
|
if (type === 'create') {
|
|
546
596
|
let nodes = this.getNodeIdsConnectedTo(nodeId, requestGraphEdgeTypes.invalidated_by_create);
|
|
547
597
|
for (let connectedNode of nodes) {
|
|
548
598
|
didInvalidate = true;
|
|
549
|
-
|
|
599
|
+
invalidateNode(connectedNode, _constants.FILE_CREATE);
|
|
550
600
|
}
|
|
551
601
|
}
|
|
552
602
|
} else if (type === 'create') {
|
|
@@ -556,17 +606,10 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
556
606
|
let fileNameNodeId = this.getNodeIdByContentKey('file_name:' + basename);
|
|
557
607
|
|
|
558
608
|
// Find potential file nodes to be invalidated if this file name pattern matches
|
|
559
|
-
let above =
|
|
560
|
-
for (const nodeId of this.getNodeIdsConnectedTo(fileNameNodeId, requestGraphEdgeTypes.invalidated_by_create_above)) {
|
|
561
|
-
let node = (0, _nullthrows().default)(this.getNode(nodeId));
|
|
562
|
-
// these might also be `glob` nodes which get handled below, we only care about files here.
|
|
563
|
-
if (node.type === FILE) {
|
|
564
|
-
above.push(node);
|
|
565
|
-
}
|
|
566
|
-
}
|
|
609
|
+
let above = getAbove(fileNameNodeId);
|
|
567
610
|
if (above.length > 0) {
|
|
568
611
|
didInvalidate = true;
|
|
569
|
-
this.invalidateFileNameNode(fileNameNode, _filePath, above);
|
|
612
|
+
this.invalidateFileNameNode(fileNameNode, _filePath, above, invalidateNode);
|
|
570
613
|
}
|
|
571
614
|
}
|
|
572
615
|
for (let globeNodeId of this.globNodeIds) {
|
|
@@ -576,7 +619,7 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
576
619
|
let connectedNodes = this.getNodeIdsConnectedTo(globeNodeId, requestGraphEdgeTypes.invalidated_by_create);
|
|
577
620
|
for (let connectedNode of connectedNodes) {
|
|
578
621
|
didInvalidate = true;
|
|
579
|
-
|
|
622
|
+
invalidateNode(connectedNode, _constants.FILE_CREATE);
|
|
580
623
|
}
|
|
581
624
|
}
|
|
582
625
|
}
|
|
@@ -584,13 +627,13 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
584
627
|
let nodeId = this.getNodeIdByContentKey(filePath);
|
|
585
628
|
for (let connectedNode of this.getNodeIdsConnectedTo(nodeId, requestGraphEdgeTypes.invalidated_by_delete)) {
|
|
586
629
|
didInvalidate = true;
|
|
587
|
-
|
|
630
|
+
invalidateNode(connectedNode, _constants.FILE_DELETE);
|
|
588
631
|
}
|
|
589
632
|
|
|
590
633
|
// Delete the file node since it doesn't exist anymore.
|
|
591
634
|
// This ensures that files that don't exist aren't sent
|
|
592
635
|
// to requests as invalidations for future requests.
|
|
593
|
-
this.removeNode(nodeId);
|
|
636
|
+
this.removeNode(nodeId, removeOrphans);
|
|
594
637
|
}
|
|
595
638
|
let configKeyNodes = this.configKeyNodes.get(_filePath);
|
|
596
639
|
if (configKeyNodes && (type === 'delete' || type === 'update')) {
|
|
@@ -604,14 +647,17 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
604
647
|
}
|
|
605
648
|
if (isInvalid) {
|
|
606
649
|
for (let connectedNode of this.getNodeIdsConnectedTo(nodeId, requestGraphEdgeTypes.invalidated_by_update)) {
|
|
607
|
-
|
|
650
|
+
invalidateNode(connectedNode, type === 'delete' ? _constants.FILE_DELETE : _constants.FILE_UPDATE);
|
|
608
651
|
}
|
|
609
652
|
didInvalidate = true;
|
|
610
|
-
this.removeNode(nodeId);
|
|
653
|
+
this.removeNode(nodeId, removeOrphans);
|
|
611
654
|
}
|
|
612
655
|
}
|
|
613
656
|
}
|
|
614
657
|
}
|
|
658
|
+
if ((0, _featureFlags().getFeatureFlag)('fixQuadraticCacheInvalidation')) {
|
|
659
|
+
cleanUpOrphans(this);
|
|
660
|
+
}
|
|
615
661
|
let duration = Date.now() - startTime;
|
|
616
662
|
_logger().default.verbose({
|
|
617
663
|
origin: '@atlaspack/core',
|
|
@@ -619,7 +665,9 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
619
665
|
meta: {
|
|
620
666
|
trackableEvent: 'fsevent_response_time',
|
|
621
667
|
duration,
|
|
622
|
-
predictedTime
|
|
668
|
+
predictedTime,
|
|
669
|
+
numberOfEvents: events.length,
|
|
670
|
+
numberOfInvalidatedNodes: invalidatedNodes.size
|
|
623
671
|
}
|
|
624
672
|
});
|
|
625
673
|
return didInvalidate && this.invalidNodeIds.size > 0;
|
|
@@ -1022,7 +1070,16 @@ async function loadRequestGraph(options) {
|
|
|
1022
1070
|
let cacheKey = getCacheKey(options);
|
|
1023
1071
|
let requestGraphKey = `requestGraph-${cacheKey}`;
|
|
1024
1072
|
let timeout;
|
|
1025
|
-
const
|
|
1073
|
+
const snapshotKey = `snapshot-${cacheKey}`;
|
|
1074
|
+
const snapshotPath = _path2().default.join(options.cacheDir, snapshotKey + '.txt');
|
|
1075
|
+
_logger().default.verbose({
|
|
1076
|
+
origin: '@atlaspack/core',
|
|
1077
|
+
message: 'Loading request graph',
|
|
1078
|
+
meta: {
|
|
1079
|
+
cacheKey,
|
|
1080
|
+
snapshotKey
|
|
1081
|
+
}
|
|
1082
|
+
});
|
|
1026
1083
|
if (await options.cache.hasLargeBlob(requestGraphKey)) {
|
|
1027
1084
|
try {
|
|
1028
1085
|
let {
|
|
@@ -1062,6 +1119,14 @@ async function loadRequestGraph(options) {
|
|
|
1062
1119
|
return new RequestGraph();
|
|
1063
1120
|
}
|
|
1064
1121
|
}
|
|
1122
|
+
_logger().default.verbose({
|
|
1123
|
+
origin: '@atlaspack/core',
|
|
1124
|
+
message: 'Cache entry for request tracker was not found, initializing a clean cache.',
|
|
1125
|
+
meta: {
|
|
1126
|
+
cacheKey,
|
|
1127
|
+
snapshotKey
|
|
1128
|
+
}
|
|
1129
|
+
});
|
|
1065
1130
|
return new RequestGraph();
|
|
1066
1131
|
}
|
|
1067
1132
|
function logErrorOnBailout(options, snapshotPath, e) {
|
|
@@ -1086,4 +1151,21 @@ function logErrorOnBailout(options, snapshotPath, e) {
|
|
|
1086
1151
|
}
|
|
1087
1152
|
});
|
|
1088
1153
|
}
|
|
1154
|
+
}
|
|
1155
|
+
function cleanUpOrphans(graph) {
|
|
1156
|
+
if (graph.rootNodeId == null) {
|
|
1157
|
+
return [];
|
|
1158
|
+
}
|
|
1159
|
+
const reachableNodes = new Set();
|
|
1160
|
+
graph.traverse(nodeId => {
|
|
1161
|
+
reachableNodes.add(nodeId);
|
|
1162
|
+
});
|
|
1163
|
+
const removedNodeIds = [];
|
|
1164
|
+
graph.nodes.forEach((_node, nodeId) => {
|
|
1165
|
+
if (!reachableNodes.has(nodeId)) {
|
|
1166
|
+
removedNodeIds.push(nodeId);
|
|
1167
|
+
graph.removeNode(nodeId);
|
|
1168
|
+
}
|
|
1169
|
+
});
|
|
1170
|
+
return removedNodeIds;
|
|
1089
1171
|
}
|
package/lib/SymbolPropagation.js
CHANGED
|
@@ -108,7 +108,7 @@ function propagateSymbols({
|
|
|
108
108
|
namespaceReexportedSymbols.add('*');
|
|
109
109
|
} else {
|
|
110
110
|
for (let incomingDep of incomingDeps) {
|
|
111
|
-
if (incomingDep.value.symbols == null) {
|
|
111
|
+
if (incomingDep.value.symbols == null || incomingDep.value.priority === _types.Priority.conditional) {
|
|
112
112
|
if (incomingDep.value.sourceAssetId == null) {
|
|
113
113
|
// The root dependency on non-library builds
|
|
114
114
|
isEntry = true;
|
package/lib/Transformation.js
CHANGED
|
@@ -46,13 +46,6 @@ function _utils() {
|
|
|
46
46
|
};
|
|
47
47
|
return data;
|
|
48
48
|
}
|
|
49
|
-
function _rust() {
|
|
50
|
-
const data = require("@atlaspack/rust");
|
|
51
|
-
_rust = function () {
|
|
52
|
-
return data;
|
|
53
|
-
};
|
|
54
|
-
return data;
|
|
55
|
-
}
|
|
56
49
|
var _Dependency = require("./Dependency");
|
|
57
50
|
var _AtlaspackConfig = _interopRequireDefault(require("./AtlaspackConfig"));
|
|
58
51
|
var _PathRequest = require("./requests/PathRequest");
|
|
@@ -181,16 +174,9 @@ class Transformation {
|
|
|
181
174
|
|
|
182
175
|
// Prefer `isSource` originating from the AssetRequest.
|
|
183
176
|
|
|
184
|
-
// If the transformer request passed code, use a hash in addition
|
|
185
|
-
// to the filename as the base for the id to ensure it is unique.
|
|
186
|
-
let idBase = (0, _projectPath.fromProjectPathRelative)(filePath);
|
|
187
|
-
if (code != null) {
|
|
188
|
-
idBase += (0, _rust().hashString)(code);
|
|
189
|
-
}
|
|
190
177
|
return new _UncommittedAsset.default({
|
|
191
|
-
idBase,
|
|
192
178
|
value: (0, _assetUtils.createAsset)(this.options.projectRoot, {
|
|
193
|
-
|
|
179
|
+
code,
|
|
194
180
|
filePath,
|
|
195
181
|
isSource: isSourceOverride ?? summarizedIsSource,
|
|
196
182
|
type: _path().default.extname((0, _projectPath.fromProjectPathRelative)(filePath)).slice(1),
|
package/lib/UncommittedAsset.js
CHANGED
|
@@ -56,7 +56,7 @@ class UncommittedAsset {
|
|
|
56
56
|
mapBuffer,
|
|
57
57
|
ast,
|
|
58
58
|
isASTDirty,
|
|
59
|
-
|
|
59
|
+
code,
|
|
60
60
|
invalidations
|
|
61
61
|
}) {
|
|
62
62
|
this.value = value;
|
|
@@ -65,7 +65,7 @@ class UncommittedAsset {
|
|
|
65
65
|
this.mapBuffer = mapBuffer;
|
|
66
66
|
this.ast = ast;
|
|
67
67
|
this.isASTDirty = isASTDirty || false;
|
|
68
|
-
this.
|
|
68
|
+
this.code = code;
|
|
69
69
|
this.invalidations = invalidations || (0, _utils2.createInvalidations)();
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -289,7 +289,7 @@ class UncommittedAsset {
|
|
|
289
289
|
let content = result.content ?? null;
|
|
290
290
|
let asset = new UncommittedAsset({
|
|
291
291
|
value: (0, _assetUtils.createAsset)(this.options.projectRoot, {
|
|
292
|
-
|
|
292
|
+
code: this.code,
|
|
293
293
|
filePath: this.value.filePath,
|
|
294
294
|
type: result.type,
|
|
295
295
|
bundleBehavior: result.bundleBehavior ?? (this.value.bundleBehavior == null ? null : _types.BundleBehaviorNames[this.value.bundleBehavior]),
|
|
@@ -323,7 +323,7 @@ class UncommittedAsset {
|
|
|
323
323
|
ast: result.ast,
|
|
324
324
|
isASTDirty: result.ast === this.ast ? this.isASTDirty : true,
|
|
325
325
|
mapBuffer: result.map ? result.map.toBuffer() : null,
|
|
326
|
-
|
|
326
|
+
code: this.code,
|
|
327
327
|
invalidations: this.invalidations
|
|
328
328
|
});
|
|
329
329
|
let dependencies = result.dependencies;
|
package/lib/Validation.js
CHANGED
|
@@ -46,13 +46,6 @@ function _profiler() {
|
|
|
46
46
|
};
|
|
47
47
|
return data;
|
|
48
48
|
}
|
|
49
|
-
function _rust() {
|
|
50
|
-
const data = require("@atlaspack/rust");
|
|
51
|
-
_rust = function () {
|
|
52
|
-
return data;
|
|
53
|
-
};
|
|
54
|
-
return data;
|
|
55
|
-
}
|
|
56
49
|
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); }
|
|
57
50
|
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; }
|
|
58
51
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -188,14 +181,9 @@ class Validation {
|
|
|
188
181
|
} = await (0, _summarizeRequest.default)(this.options.inputFS, {
|
|
189
182
|
filePath: (0, _projectPath.fromProjectPath)(this.options.projectRoot, request.filePath)
|
|
190
183
|
});
|
|
191
|
-
|
|
192
|
-
// If the transformer request passed code rather than a filename,
|
|
193
|
-
// use a hash as the base for the id to ensure it is unique.
|
|
194
|
-
let idBase = code != null ? (0, _rust().hashString)(code) : (0, _projectPath.fromProjectPathRelative)(filePath);
|
|
195
184
|
return new _UncommittedAsset.default({
|
|
196
|
-
idBase,
|
|
197
185
|
value: (0, _assetUtils.createAsset)(this.options.projectRoot, {
|
|
198
|
-
|
|
186
|
+
code,
|
|
199
187
|
filePath: filePath,
|
|
200
188
|
isSource,
|
|
201
189
|
type: _path().default.extname((0, _projectPath.fromProjectPathRelative)(filePath)).slice(1),
|
package/lib/applyRuntimes.js
CHANGED
|
@@ -62,6 +62,13 @@ function _profiler() {
|
|
|
62
62
|
};
|
|
63
63
|
return data;
|
|
64
64
|
}
|
|
65
|
+
function _utils() {
|
|
66
|
+
const data = require("@atlaspack/utils");
|
|
67
|
+
_utils = function () {
|
|
68
|
+
return data;
|
|
69
|
+
};
|
|
70
|
+
return data;
|
|
71
|
+
}
|
|
65
72
|
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); }
|
|
66
73
|
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; }
|
|
67
74
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -81,6 +88,15 @@ function nameRuntimeBundle(bundle, siblingBundle) {
|
|
|
81
88
|
bundle.name = name;
|
|
82
89
|
bundle.displayName = name.replace(hashReference, '[hash]');
|
|
83
90
|
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* The applyRuntimes function is responsible for generating all the runtimes
|
|
94
|
+
* (assets created during the build that don't actually exist on disk) and then
|
|
95
|
+
* linking them into the bundle graph.
|
|
96
|
+
*
|
|
97
|
+
* Introduction of manifest bundles: https://github.com/parcel-bundler/parcel/pull/8837
|
|
98
|
+
* Introduction of reverse topology: https://github.com/parcel-bundler/parcel/pull/8981
|
|
99
|
+
*/
|
|
84
100
|
async function applyRuntimes({
|
|
85
101
|
bundleGraph,
|
|
86
102
|
config,
|
|
@@ -93,17 +109,27 @@ async function applyRuntimes({
|
|
|
93
109
|
configs
|
|
94
110
|
}) {
|
|
95
111
|
let runtimes = await config.getRuntimes();
|
|
96
|
-
let connections = [];
|
|
97
112
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
113
|
+
/**
|
|
114
|
+
* Usually, the assets returned from a runtime will go in the same bundle. It is
|
|
115
|
+
* possible though, for a runtime to return an asset with a `parallel` priority,
|
|
116
|
+
* which allows it to be moved to a separate bundle. In practice, this is
|
|
117
|
+
* usually used to generate application manifest files.
|
|
118
|
+
*
|
|
119
|
+
* When adding a manifest bundle (a whole new separate bundle) during a runtime,
|
|
120
|
+
* it needs to be added to a bundle group which will be potentially referenced
|
|
121
|
+
* by another bundle group. To avoid trying to reference a manifest entry which
|
|
122
|
+
* hasn't been created yet, we process the bundles from the bottom up (topological
|
|
123
|
+
* order), so that children will always be available when parents try to reference
|
|
124
|
+
* them.
|
|
125
|
+
*/
|
|
101
126
|
let bundles = [];
|
|
102
127
|
bundleGraph.traverseBundles({
|
|
103
128
|
exit(bundle) {
|
|
104
129
|
bundles.push(bundle);
|
|
105
130
|
}
|
|
106
131
|
});
|
|
132
|
+
let connectionMap = new (_utils().DefaultMap)(() => []);
|
|
107
133
|
for (let bundle of bundles) {
|
|
108
134
|
for (let runtime of runtimes) {
|
|
109
135
|
let measurement;
|
|
@@ -144,6 +170,12 @@ async function applyRuntimes({
|
|
|
144
170
|
isSource: true
|
|
145
171
|
};
|
|
146
172
|
let connectionBundle = bundle;
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* If a runtime asset is marked with a priority of `parallel` this
|
|
176
|
+
* means we need to create a new bundle for the asset and add it to
|
|
177
|
+
* all the same bundle groups.
|
|
178
|
+
*/
|
|
147
179
|
if (priority === 'parallel' && !bundle.needsStableName) {
|
|
148
180
|
let bundleGroups = bundleGraph.getBundleGroupsContainingBundle(bundle);
|
|
149
181
|
connectionBundle = (0, _nullthrows().default)(bundleGraph.createBundle({
|
|
@@ -158,9 +190,12 @@ async function applyRuntimes({
|
|
|
158
190
|
bundleGraph.addBundleToBundleGroup(connectionBundle, bundleGroup);
|
|
159
191
|
}
|
|
160
192
|
bundleGraph.createBundleReference(bundle, connectionBundle);
|
|
193
|
+
|
|
194
|
+
// Ensure we name the bundle now as all other bundles have already
|
|
195
|
+
// been named as this point.
|
|
161
196
|
nameRuntimeBundle(connectionBundle, bundle);
|
|
162
197
|
}
|
|
163
|
-
|
|
198
|
+
connectionMap.get(connectionBundle).push({
|
|
164
199
|
bundle: connectionBundle,
|
|
165
200
|
assetGroup,
|
|
166
201
|
dependency,
|
|
@@ -180,8 +215,28 @@ async function applyRuntimes({
|
|
|
180
215
|
}
|
|
181
216
|
}
|
|
182
217
|
|
|
183
|
-
|
|
184
|
-
|
|
218
|
+
/**
|
|
219
|
+
* When merging the connections in to the bundle graph, the topological
|
|
220
|
+
* order can create module not found errors in some situations, often when HMR
|
|
221
|
+
* is enabled. To fix this, we put the connections into DFS order.
|
|
222
|
+
*
|
|
223
|
+
* Note: While DFS order seems to be the most reliable order to process the
|
|
224
|
+
* connections, this is likely due to it being close to the order that the bundles were
|
|
225
|
+
* inserted into the graph. There is a known issue where runtime assets marked
|
|
226
|
+
* as `isEntry` can create scenarios where there is no correct load order that
|
|
227
|
+
* won't error, as the entry runtime assets are added to many bundles in a
|
|
228
|
+
* single bundle group but their dependencies are not.
|
|
229
|
+
*
|
|
230
|
+
* This issue is almost exclusive to HMR scenarios as the two HMR runtime
|
|
231
|
+
* plugins (@atlaspack/runtime-browser-hmr and @atlaspack/runtime-react-refresh)
|
|
232
|
+
* are the only known cases where a runtime asset is marked as `isEntry`.
|
|
233
|
+
*/
|
|
234
|
+
let connections = [];
|
|
235
|
+
bundleGraph.traverseBundles({
|
|
236
|
+
enter(bundle) {
|
|
237
|
+
connections.push(...connectionMap.get(bundle));
|
|
238
|
+
}
|
|
239
|
+
});
|
|
185
240
|
|
|
186
241
|
// Add dev deps for runtime plugins AFTER running them, to account for lazy require().
|
|
187
242
|
for (let runtime of runtimes) {
|
|
@@ -192,18 +247,29 @@ async function applyRuntimes({
|
|
|
192
247
|
devDepRequests.set(`${devDepRequest.specifier}:${(0, _projectPath.fromProjectPathRelative)(devDepRequest.resolveFrom)}`, devDepRequest);
|
|
193
248
|
await (0, _DevDepRequest.runDevDepRequest)(api, devDepRequest);
|
|
194
249
|
}
|
|
250
|
+
|
|
251
|
+
// Create a new AssetGraph from the generated runtime assets which also runs
|
|
252
|
+
// transforms and resolves all dependencies.
|
|
195
253
|
let {
|
|
196
254
|
assetGraph: runtimesAssetGraph,
|
|
197
255
|
changedAssets
|
|
198
256
|
} = await reconcileNewRuntimes(api, connections, optionsRef);
|
|
199
|
-
let runtimesGraph = _BundleGraph2.default.fromAssetGraph(runtimesAssetGraph, options.mode === 'production', bundleGraph._publicIdByAssetId, bundleGraph._assetPublicIds);
|
|
200
257
|
|
|
201
|
-
//
|
|
202
|
-
|
|
203
|
-
|
|
258
|
+
// Convert the runtime AssetGraph into a BundleGraph, this includes assigning
|
|
259
|
+
// the assets their public ids
|
|
260
|
+
let runtimesBundleGraph = _BundleGraph2.default.fromAssetGraph(runtimesAssetGraph, options.mode === 'production', bundleGraph._publicIdByAssetId, bundleGraph._assetPublicIds);
|
|
261
|
+
|
|
262
|
+
// Merge the runtimes bundle graph into the main bundle graph.
|
|
263
|
+
bundleGraph.merge(runtimesBundleGraph);
|
|
264
|
+
|
|
265
|
+
// Add the public id mappings from the runtumes bundlegraph to the main bundle graph
|
|
266
|
+
for (let [assetId, publicId] of runtimesBundleGraph._publicIdByAssetId) {
|
|
204
267
|
bundleGraph._publicIdByAssetId.set(assetId, publicId);
|
|
205
268
|
bundleGraph._assetPublicIds.add(publicId);
|
|
206
269
|
}
|
|
270
|
+
|
|
271
|
+
// Connect each of the generated runtime assets to bundles in the main bundle
|
|
272
|
+
// graph. This is like a mini-bundling algorithm for runtime assets.
|
|
207
273
|
for (let {
|
|
208
274
|
bundle,
|
|
209
275
|
assetGroup,
|
|
@@ -216,16 +282,24 @@ async function applyRuntimes({
|
|
|
216
282
|
let runtimeNodeId = assetGroupAssetNodeIds[0];
|
|
217
283
|
let runtimeNode = (0, _nullthrows().default)(runtimesAssetGraph.getNode(runtimeNodeId));
|
|
218
284
|
(0, _assert().default)(runtimeNode.type === 'asset');
|
|
285
|
+
|
|
286
|
+
// Find the asset that the runtime asset should be connected from by resolving
|
|
287
|
+
// it's dependency.
|
|
219
288
|
let resolution = dependency && bundleGraph.getResolvedAsset((0, _Dependency.dependencyToInternalDependency)(dependency), bundle);
|
|
220
|
-
|
|
289
|
+
|
|
290
|
+
// Walk all the dependencies of the runtime assets and check if they are
|
|
291
|
+
// already reachable from the bundle that the runtime asset is assigned to.
|
|
292
|
+
// If so, we add them to `duplicatedContentKeys` to be skipped when assigning
|
|
293
|
+
// assets to bundles.
|
|
294
|
+
let runtimesBundleGraphRuntimeNodeId = runtimesBundleGraph._graph.getNodeIdByContentKey(runtimeNode.id);
|
|
221
295
|
let duplicatedContentKeys = new Set();
|
|
222
|
-
|
|
223
|
-
let node = (0, _nullthrows().default)(
|
|
296
|
+
runtimesBundleGraph._graph.traverse((nodeId, _, actions) => {
|
|
297
|
+
let node = (0, _nullthrows().default)(runtimesBundleGraph._graph.getNode(nodeId));
|
|
224
298
|
if (node.type !== 'dependency') {
|
|
225
299
|
return;
|
|
226
300
|
}
|
|
227
|
-
let assets =
|
|
228
|
-
let assetNode = (0, _nullthrows().default)(
|
|
301
|
+
let assets = runtimesBundleGraph._graph.getNodeIdsConnectedFrom(nodeId).map(assetNodeId => {
|
|
302
|
+
let assetNode = (0, _nullthrows().default)(runtimesBundleGraph._graph.getNode(assetNodeId));
|
|
229
303
|
(0, _assert().default)(assetNode.type === 'asset');
|
|
230
304
|
return assetNode.value;
|
|
231
305
|
});
|
|
@@ -235,12 +309,14 @@ async function applyRuntimes({
|
|
|
235
309
|
actions.skipChildren();
|
|
236
310
|
}
|
|
237
311
|
}
|
|
238
|
-
},
|
|
312
|
+
}, runtimesBundleGraphRuntimeNodeId);
|
|
239
313
|
let bundleNodeId = bundleGraph._graph.getNodeIdByContentKey(bundle.id);
|
|
240
314
|
let bundleGraphRuntimeNodeId = bundleGraph._graph.getNodeIdByContentKey(runtimeNode.id); // the node id is not constant between graphs
|
|
241
315
|
|
|
242
|
-
|
|
243
|
-
|
|
316
|
+
// Assign the runtime assets and all of it's depepdencies to the bundle unless
|
|
317
|
+
// we have detected it as already being reachable from this bundle via `duplicatedContentKeys`.
|
|
318
|
+
runtimesBundleGraph._graph.traverse((nodeId, _, actions) => {
|
|
319
|
+
let node = (0, _nullthrows().default)(runtimesBundleGraph._graph.getNode(nodeId));
|
|
244
320
|
if (node.type === 'asset' || node.type === 'dependency') {
|
|
245
321
|
if (duplicatedContentKeys.has(node.id)) {
|
|
246
322
|
actions.skipChildren();
|
|
@@ -249,7 +325,7 @@ async function applyRuntimes({
|
|
|
249
325
|
const bundleGraphNodeId = bundleGraph._graph.getNodeIdByContentKey(node.id); // the node id is not constant between graphs
|
|
250
326
|
bundleGraph._graph.addEdge(bundleNodeId, bundleGraphNodeId, _BundleGraph2.bundleGraphEdgeTypes.contains);
|
|
251
327
|
}
|
|
252
|
-
},
|
|
328
|
+
}, runtimesBundleGraphRuntimeNodeId);
|
|
253
329
|
if (isEntry) {
|
|
254
330
|
bundleGraph._graph.addEdge(bundleNodeId, bundleGraphRuntimeNodeId);
|
|
255
331
|
bundle.entryAssetIds.unshift(runtimeNode.id);
|
package/lib/assetUtils.js
CHANGED
|
@@ -61,9 +61,15 @@ function _profiler() {
|
|
|
61
61
|
}
|
|
62
62
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
63
63
|
function createAssetIdFromOptions(options) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
return (0, _rust().createAssetId)({
|
|
65
|
+
env: options.env,
|
|
66
|
+
filePath: options.filePath,
|
|
67
|
+
code: options.code,
|
|
68
|
+
pipeline: options.pipeline,
|
|
69
|
+
query: options.query,
|
|
70
|
+
uniqueKey: options.uniqueKey,
|
|
71
|
+
fileType: options.type
|
|
72
|
+
});
|
|
67
73
|
}
|
|
68
74
|
function createAsset(projectRoot, options) {
|
|
69
75
|
return {
|
|
@@ -35,6 +35,12 @@ class AtlaspackV3 {
|
|
|
35
35
|
threads,
|
|
36
36
|
...options
|
|
37
37
|
}) {
|
|
38
|
+
options.logLevel = options.logLevel || 'error';
|
|
39
|
+
options.defaultTargetOptions = options.defaultTargetOptions || {};
|
|
40
|
+
// $FlowFixMe "engines" are readonly
|
|
41
|
+
options.defaultTargetOptions.engines = options.defaultTargetOptions.engines || {
|
|
42
|
+
browsers: []
|
|
43
|
+
};
|
|
38
44
|
this._internal = new (_rust().AtlaspackNapi)({
|
|
39
45
|
fs,
|
|
40
46
|
nodeWorkers,
|
|
@@ -43,14 +49,6 @@ class AtlaspackV3 {
|
|
|
43
49
|
options
|
|
44
50
|
});
|
|
45
51
|
}
|
|
46
|
-
async build() {
|
|
47
|
-
const [workers, registerWorker] = this.#createWorkers();
|
|
48
|
-
let result = await this._internal.build({
|
|
49
|
-
registerWorker
|
|
50
|
-
});
|
|
51
|
-
for (const worker of workers) worker.terminate();
|
|
52
|
-
return result;
|
|
53
|
-
}
|
|
54
52
|
async buildAssetGraph() {
|
|
55
53
|
const [workers, registerWorker] = this.#createWorkers();
|
|
56
54
|
let result = await this._internal.buildAssetGraph({
|
package/lib/atlaspack-v3/fs.js
CHANGED
|
@@ -11,7 +11,14 @@ function toFileSystemV3(fs) {
|
|
|
11
11
|
canonicalize: (0, _jsCallable.jsCallable)(path => fs.realpathSync(path)),
|
|
12
12
|
createDirectory: (0, _jsCallable.jsCallable)(path => fs.mkdirp(path)),
|
|
13
13
|
cwd: (0, _jsCallable.jsCallable)(() => fs.cwd()),
|
|
14
|
-
readFile: (0, _jsCallable.jsCallable)((path, encoding) =>
|
|
14
|
+
readFile: (0, _jsCallable.jsCallable)((path, encoding) => {
|
|
15
|
+
if (!encoding) {
|
|
16
|
+
// $FlowFixMe
|
|
17
|
+
return [...fs.readFileSync(path)];
|
|
18
|
+
} else {
|
|
19
|
+
return fs.readFileSync(path, encoding);
|
|
20
|
+
}
|
|
21
|
+
}),
|
|
15
22
|
isFile: path => {
|
|
16
23
|
try {
|
|
17
24
|
return fs.statSync(path).isFile();
|