Son CV dans un terminal web en Javascript! https://terminal-cv.gregandev.fr
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

601 lines
18 KiB

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.nodeFromDep = nodeFromDep;
2 years ago
exports.nodeFromAssetGroup = nodeFromAssetGroup;
exports.nodeFromAsset = nodeFromAsset;
exports.nodeFromEntrySpecifier = nodeFromEntrySpecifier;
2 years ago
exports.nodeFromEntryFile = nodeFromEntryFile;
exports.default = void 0;
function _assert() {
const data = _interopRequireDefault(require("assert"));
_assert = function () {
return data;
};
return data;
}
function _hash() {
const data = require("@parcel/hash");
_hash = function () {
return data;
};
return data;
}
function _utils() {
const data = require("@parcel/utils");
_utils = function () {
return data;
};
return data;
}
function _nullthrows() {
const data = _interopRequireDefault(require("nullthrows"));
_nullthrows = function () {
return data;
};
return data;
}
function _graph() {
const data = require("@parcel/graph");
_graph = function () {
return data;
};
return data;
}
var _Dependency = require("./Dependency");
var _projectPath = require("./projectPath");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function nodeFromDep(dep) {
return {
id: dep.id,
type: 'dependency',
value: dep,
deferred: false,
excluded: false,
usedSymbolsDown: new Set(),
usedSymbolsUp: new Set(),
usedSymbolsDownDirty: true,
usedSymbolsUpDirtyDown: true,
usedSymbolsUpDirtyUp: true
};
}
function nodeFromAssetGroup(assetGroup) {
var _assetGroup$code, _assetGroup$pipeline, _assetGroup$query;
return {
id: (0, _hash().hashString)((0, _projectPath.fromProjectPathRelative)(assetGroup.filePath) + assetGroup.env.id + String(assetGroup.isSource) + String(assetGroup.sideEffects) + ((_assetGroup$code = assetGroup.code) !== null && _assetGroup$code !== void 0 ? _assetGroup$code : '') + ':' + ((_assetGroup$pipeline = assetGroup.pipeline) !== null && _assetGroup$pipeline !== void 0 ? _assetGroup$pipeline : '') + ':' + ((_assetGroup$query = assetGroup.query) !== null && _assetGroup$query !== void 0 ? _assetGroup$query : '')),
type: 'asset_group',
value: assetGroup,
usedSymbolsDownDirty: true
};
}
function nodeFromAsset(asset) {
return {
id: asset.id,
type: 'asset',
value: asset,
usedSymbols: new Set(),
usedSymbolsDownDirty: true,
usedSymbolsUpDirty: true
};
}
function nodeFromEntrySpecifier(entry) {
return {
id: 'entry_specifier:' + (0, _projectPath.fromProjectPathRelative)(entry),
type: 'entry_specifier',
value: entry
};
}
function nodeFromEntryFile(entry) {
return {
id: 'entry_file:' + (0, _utils().hashObject)(entry),
type: 'entry_file',
value: entry
};
}
class AssetGraph extends _graph().ContentGraph {
constructor(opts) {
if (opts) {
let {
hash,
symbolPropagationRan,
...rest
} = opts;
super(rest);
this.hash = hash;
this.symbolPropagationRan = symbolPropagationRan;
} else {
super();
this.setRootNodeId(this.addNode({
id: '@@root',
type: 'root',
value: null
}));
}
this.envCache = new Map();
this.symbolPropagationRan = false;
} // $FlowFixMe[prop-missing]
static deserialize(opts) {
return new AssetGraph(opts);
} // $FlowFixMe[prop-missing]
serialize() {
return { ...super.serialize(),
hash: this.hash,
symbolPropagationRan: this.symbolPropagationRan
};
} // Deduplicates Environments by making them referentially equal
normalizeEnvironment(input) {
let {
id,
context
} = input.env;
let idAndContext = `${id}-${context}`;
let env = this.envCache.get(idAndContext);
if (env) {
input.env = env;
} else {
this.envCache.set(idAndContext, input.env);
}
}
setRootConnections({
entries,
assetGroups
}) {
let nodes = [];
if (entries) {
for (let entry of entries) {
let node = nodeFromEntrySpecifier(entry);
nodes.push(node);
}
} else if (assetGroups) {
nodes.push(...assetGroups.map(assetGroup => nodeFromAssetGroup(assetGroup)));
}
this.replaceNodeIdsConnectedTo((0, _nullthrows().default)(this.rootNodeId), nodes.map(node => this.addNode(node)));
}
addNode(node) {
this.hash = null;
let existing = this.getNodeByContentKey(node.id);
if (existing != null) {
(0, _assert().default)(existing.type === node.type); // $FlowFixMe[incompatible-type] Checked above
// $FlowFixMe[prop-missing]
existing.value = node.value;
let existingId = this.getNodeIdByContentKey(node.id);
this.updateNode(existingId, existing);
return existingId;
}
return super.addNodeByContentKey(node.id, node);
}
removeNode(nodeId) {
this.hash = null;
this.onNodeRemoved && this.onNodeRemoved(nodeId); // This needs to mark all connected nodes that doesn't become orphaned
// due to replaceNodesConnectedTo to make sure that the symbols of
// nodes from which at least one parent was removed are updated.
let node = (0, _nullthrows().default)(this.getNode(nodeId));
if (this.isOrphanedNode(nodeId) && node.type === 'dependency') {
let children = this.getNodeIdsConnectedFrom(nodeId).map(id => (0, _nullthrows().default)(this.getNode(id)));
for (let n of children) {
(0, _assert().default)(n.type === 'asset_group' || n.type === 'asset');
n.usedSymbolsDownDirty = true;
}
}
return super.removeNode(nodeId);
}
resolveEntry(entry, resolved, correspondingRequest) {
let entrySpecifierNodeId = this.getNodeIdByContentKey(nodeFromEntrySpecifier(entry).id);
let entrySpecifierNode = (0, _nullthrows().default)(this.getNode(entrySpecifierNodeId));
(0, _assert().default)(entrySpecifierNode.type === 'entry_specifier');
entrySpecifierNode.correspondingRequest = correspondingRequest;
this.replaceNodeIdsConnectedTo(entrySpecifierNodeId, resolved.map(file => this.addNode(nodeFromEntryFile(file))));
}
resolveTargets(entry, targets, correspondingRequest) {
let depNodes = targets.map(target => {
let node = nodeFromDep( // The passed project path is ignored in this case, because there is no `loc`
(0, _Dependency.createDependency)('', {
specifier: (0, _projectPath.fromProjectPathRelative)(entry.filePath),
specifierType: 'esm',
// ???
pipeline: target.pipeline,
target: target,
env: target.env,
isEntry: true,
needsStableName: true,
symbols: target.env.isLibrary ? new Map([['*', {
local: '*',
isWeak: true,
loc: null
}]]) : undefined
}));
if (node.value.env.isLibrary) {
// in library mode, all of the entry's symbols are "used"
node.usedSymbolsDown.add('*');
}
return node;
});
let entryNodeId = this.getNodeIdByContentKey(nodeFromEntryFile(entry).id);
let entryNode = (0, _nullthrows().default)(this.getNode(entryNodeId));
(0, _assert().default)(entryNode.type === 'entry_file');
entryNode.correspondingRequest = correspondingRequest;
this.replaceNodeIdsConnectedTo(entryNodeId, depNodes.map(node => this.addNode(node)));
}
resolveDependency(dependency, assetGroup, correspondingRequest) {
let depNodeId = this.getNodeIdByContentKey(dependency.id);
let depNode = (0, _nullthrows().default)(this.getNode(depNodeId));
(0, _assert().default)(depNode.type === 'dependency');
depNode.correspondingRequest = correspondingRequest;
if (!assetGroup) {
return;
}
let assetGroupNode = nodeFromAssetGroup(assetGroup);
let existing = this.getNodeByContentKey(assetGroupNode.id);
if (existing != null) {
(0, _assert().default)(existing.type === 'asset_group');
assetGroupNode.value.canDefer = assetGroupNode.value.canDefer && existing.value.canDefer;
}
let assetGroupNodeId = this.addNode(assetGroupNode);
this.replaceNodeIdsConnectedTo(this.getNodeIdByContentKey(dependency.id), [assetGroupNodeId]);
this.replaceNodeIdsConnectedTo(depNodeId, [assetGroupNodeId]);
}
shouldVisitChild(nodeId, childNodeId) {
let node = (0, _nullthrows().default)(this.getNode(nodeId));
let childNode = (0, _nullthrows().default)(this.getNode(childNodeId));
if (node.type !== 'dependency' || childNode.type !== 'asset_group' || childNode.deferred === false) {
return true;
} // Node types are proved above
let dependencyNode = node;
let assetGroupNode = childNode;
let {
sideEffects,
canDefer = true
} = assetGroupNode.value;
let dependency = dependencyNode.value;
let dependencyPreviouslyDeferred = dependencyNode.hasDeferred;
let assetGroupPreviouslyDeferred = assetGroupNode.deferred;
let defer = this.shouldDeferDependency(dependency, sideEffects, canDefer);
dependencyNode.hasDeferred = defer;
assetGroupNode.deferred = defer;
if (!dependencyPreviouslyDeferred && defer) {
this.markParentsWithHasDeferred(nodeId);
} else if (assetGroupPreviouslyDeferred && !defer) {
this.unmarkParentsWithHasDeferred(childNodeId);
}
return !defer;
} // Dependency: mark parent Asset <- AssetGroup with hasDeferred true
markParentsWithHasDeferred(nodeId) {
this.traverseAncestors(nodeId, (traversedNodeId, _, actions) => {
let traversedNode = (0, _nullthrows().default)(this.getNode(traversedNodeId));
if (traversedNode.type === 'asset') {
traversedNode.hasDeferred = true;
} else if (traversedNode.type === 'asset_group') {
traversedNode.hasDeferred = true;
actions.skipChildren();
} else if (nodeId !== traversedNodeId) {
actions.skipChildren();
}
});
} // AssetGroup: update hasDeferred of all parent Dependency <- Asset <- AssetGroup
unmarkParentsWithHasDeferred(nodeId) {
this.traverseAncestors(nodeId, (traversedNodeId, ctx, actions) => {
let traversedNode = (0, _nullthrows().default)(this.getNode(traversedNodeId));
if (traversedNode.type === 'asset') {
let hasDeferred = this.getNodeIdsConnectedFrom(traversedNodeId).some(childNodeId => {
let childNode = (0, _nullthrows().default)(this.getNode(childNodeId));
return childNode.hasDeferred == null ? false : childNode.hasDeferred;
});
if (!hasDeferred) {
delete traversedNode.hasDeferred;
}
return {
hasDeferred
};
} else if (traversedNode.type === 'asset_group' && nodeId !== traversedNodeId) {
if (!(ctx !== null && ctx !== void 0 && ctx.hasDeferred)) {
delete traversedNode.hasDeferred;
}
actions.skipChildren();
} else if (traversedNode.type === 'dependency') {
traversedNode.hasDeferred = false;
} else if (nodeId !== traversedNodeId) {
actions.skipChildren();
}
});
} // Defer transforming this dependency if it is marked as weak, there are no side effects,
// no re-exported symbols are used by ancestor dependencies and the re-exporting asset isn't
// using a wildcard and isn't an entry (in library mode).
// This helps with performance building large libraries like `lodash-es`, which re-exports
// a huge number of functions since we can avoid even transforming the files that aren't used.
shouldDeferDependency(dependency, sideEffects, canDefer) {
let defer = false;
let dependencySymbols = dependency.symbols;
if (dependencySymbols && [...dependencySymbols].every(([, {
isWeak
}]) => isWeak) && sideEffects === false && canDefer && !dependencySymbols.has('*')) {
let depNodeId = this.getNodeIdByContentKey(dependency.id);
let depNode = this.getNode(depNodeId);
(0, _assert().default)(depNode);
let assets = this.getNodeIdsConnectedTo(depNodeId);
let symbols = new Map([...dependencySymbols].map(([key, val]) => [val.local, key]));
(0, _assert().default)(assets.length === 1);
let firstAsset = (0, _nullthrows().default)(this.getNode(assets[0]));
(0, _assert().default)(firstAsset.type === 'asset');
let resolvedAsset = firstAsset.value;
let deps = this.getIncomingDependencies(resolvedAsset);
defer = deps.every(d => d.symbols && !(d.env.isLibrary && d.isEntry) && !d.symbols.has('*') && ![...d.symbols.keys()].some(symbol => {
var _resolvedAsset$symbol, _resolvedAsset$symbol2;
if (!resolvedAsset.symbols) return true;
let assetSymbol = (_resolvedAsset$symbol = resolvedAsset.symbols) === null || _resolvedAsset$symbol === void 0 ? void 0 : (_resolvedAsset$symbol2 = _resolvedAsset$symbol.get(symbol)) === null || _resolvedAsset$symbol2 === void 0 ? void 0 : _resolvedAsset$symbol2.local;
return assetSymbol != null && symbols.has(assetSymbol);
}));
}
return defer;
}
resolveAssetGroup(assetGroup, assets, correspondingRequest) {
this.normalizeEnvironment(assetGroup);
let assetGroupNode = nodeFromAssetGroup(assetGroup);
assetGroupNode = this.getNodeByContentKey(assetGroupNode.id);
if (!assetGroupNode) {
return;
}
(0, _assert().default)(assetGroupNode.type === 'asset_group');
assetGroupNode.correspondingRequest = correspondingRequest;
let assetsByKey = new Map();
for (let asset of assets) {
if (asset.uniqueKey != null) {
assetsByKey.set(asset.uniqueKey, asset);
}
}
let dependentAssetKeys = new Set();
for (let asset of assets) {
for (let dep of asset.dependencies.values()) {
if (assetsByKey.has(dep.specifier)) {
dependentAssetKeys.add(dep.specifier);
}
}
}
let assetObjects = [];
let assetNodeIds = [];
for (let asset of assets) {
this.normalizeEnvironment(asset);
let isDirect = !dependentAssetKeys.has(asset.uniqueKey);
let dependentAssets = [];
for (let dep of asset.dependencies.values()) {
let dependentAsset = assetsByKey.get(dep.specifier);
if (dependentAsset) {
dependentAssets.push(dependentAsset);
}
}
let id = this.addNode(nodeFromAsset(asset));
assetObjects.push({
assetNodeId: id,
dependentAssets
});
if (isDirect) {
assetNodeIds.push(id);
}
}
this.replaceNodeIdsConnectedTo(this.getNodeIdByContentKey(assetGroupNode.id), assetNodeIds);
for (let {
assetNodeId,
dependentAssets
} of assetObjects) {
// replaceNodesConnectedTo has merged the value into the existing node, retrieve
// the actual current node.
let assetNode = (0, _nullthrows().default)(this.getNode(assetNodeId));
(0, _assert().default)(assetNode.type === 'asset');
this.resolveAsset(assetNode, dependentAssets);
}
}
resolveAsset(assetNode, dependentAssets) {
let depNodeIds = [];
let depNodesWithAssets = [];
for (let dep of assetNode.value.dependencies.values()) {
this.normalizeEnvironment(dep);
let depNode = nodeFromDep(dep);
let existing = this.getNodeByContentKey(depNode.id);
if ((existing === null || existing === void 0 ? void 0 : existing.type) === 'dependency' && existing.value.resolverMeta != null) {
depNode.value.meta = { ...depNode.value.meta,
...existing.value.resolverMeta
};
}
let dependentAsset = dependentAssets.find(a => a.uniqueKey === dep.specifier);
if (dependentAsset) {
depNode.complete = true;
depNodesWithAssets.push([depNode, nodeFromAsset(dependentAsset)]);
}
depNode.value.sourceAssetType = assetNode.value.type;
depNodeIds.push(this.addNode(depNode));
}
assetNode.usedSymbolsDownDirty = true;
this.replaceNodeIdsConnectedTo(this.getNodeIdByContentKey(assetNode.id), depNodeIds);
for (let [depNode, dependentAssetNode] of depNodesWithAssets) {
let depAssetNodeId = this.addNode(dependentAssetNode);
this.replaceNodeIdsConnectedTo(this.getNodeIdByContentKey(depNode.id), [depAssetNodeId]);
}
}
getIncomingDependencies(asset) {
let nodeId = this._contentKeyToNodeId.get(asset.id);
if (!nodeId) {
return [];
}
let assetGroupIds = this.getNodeIdsConnectedTo(nodeId);
let dependencies = [];
for (let i = 0; i < assetGroupIds.length; i++) {
let assetGroupId = assetGroupIds[i]; // Sometimes assets are connected directly to dependencies
// rather than through an asset group. This happens due to
// inline dependencies on assets via uniqueKey. See resolveAsset.
let node = this.getNode(assetGroupId);
if ((node === null || node === void 0 ? void 0 : node.type) === 'dependency') {
dependencies.push(node.value);
continue;
}
let assetIds = this.getNodeIdsConnectedTo(assetGroupId);
for (let j = 0; j < assetIds.length; j++) {
let node = this.getNode(assetIds[j]);
if (!node || node.type !== 'dependency') {
continue;
}
dependencies.push(node.value);
}
}
return dependencies;
}
traverseAssets(visit, startNodeId) {
return this.filteredTraverse(nodeId => {
let node = (0, _nullthrows().default)(this.getNode(nodeId));
return node.type === 'asset' ? node.value : null;
}, visit, startNodeId);
}
getEntryAssetGroupNodes() {
let entryNodes = [];
this.traverse((nodeId, _, actions) => {
let node = (0, _nullthrows().default)(this.getNode(nodeId));
if (node.type === 'asset_group') {
entryNodes.push(node);
actions.skipChildren();
}
});
return entryNodes;
}
getEntryAssets() {
let entries = [];
this.traverseAssets((asset, ctx, traversal) => {
entries.push(asset);
traversal.skipChildren();
});
return entries;
}
getHash() {
if (this.hash != null) {
return this.hash;
}
let hash = new (_hash().Hash)(); // TODO: sort??
this.traverse(nodeId => {
let node = (0, _nullthrows().default)(this.getNode(nodeId));
if (node.type === 'asset') {
hash.writeString((0, _nullthrows().default)(node.value.outputHash));
} else if (node.type === 'dependency' && node.value.target) {
hash.writeString(JSON.stringify(node.value.target));
}
});
this.hash = hash.finish();
return this.hash;
}
}
exports.default = AssetGraph;