UNPKG

lasso

Version:

Lasso.js is a build tool and runtime library for building and bundling all of the resources needed by a web application

168 lines (140 loc) 6.28 kB
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } var dependencyWalker = require('../dependency-walker'); var DependencyList = require('../DependencyList'); var thresholdRegex = /^(\d+)([%]*)$/; function onDependency(tracking, strictIntersection, firstSet, i) { return function (dependency, context) { if (dependency.isPackageDependency()) { return; } var key = dependency.getKey(); var info = tracking[key]; if (info === undefined) { tracking[key] = { dependency: dependency, count: 1 }; } else { info.count++; } if (i === 0 && strictIntersection) { // strict intersection so only need to keep track // dependencies from first set (which is a little // arbitrary but will work) firstSet.push(dependency); } }; } module.exports = { properties: { dependencies: 'array', threshold: 'object' }, init(lassoContext) { var _this = this; return _asyncToGenerator(function* () { if (!_this.dependencies) { throw new Error('"dependencies" property is required'); } if (!Array.isArray(_this.dependencies)) { throw new Error('"dependencies" property is required'); } _this.dependencies = new DependencyList(_this.dependencies, lassoContext.dependencyRegistry, _this.getParentManifestDir(), _this.getParentManifestPath()); if (_this.threshold) { if (typeof _this.threshold === 'string') { var match = thresholdRegex.exec(_this.threshold); var units; if (!match || (units = match[2]) && units !== '%') { throw new Error('Invalid threshold: ' + _this.threshold); } _this.threshold = { value: parseInt(match[1], 10), units: units }; } else { _this.threshold = { value: _this.threshold }; } } })(); }, getDir: function () { return null; }, getDependencies(lassoContext) { var _this2 = this; return _asyncToGenerator(function* () { var tracking = {}; var flags = lassoContext.flags; var firstSet = []; let dependencies = yield _this2.dependencies.normalize(); var numDependencies = dependencies.length; var thresholdValue; if (_this2.threshold) { thresholdValue = _this2.threshold.value; if (_this2.threshold.units === '%') { // A dependency will become part of the intersection if it is in at X percent of the enumerated list of dependencies thresholdValue = thresholdValue / 100 * numDependencies; } else { // A dependency will become part of the intersection if it is in at least X of the enumerated list of dependencies thresholdValue = _this2.threshold.value; } } else { // strict intersection -- only include the dependencies that are in the enumerated list of dependencies thresholdValue = numDependencies; } var strictIntersection = thresholdValue >= numDependencies; for (const [i, dependency] of dependencies.entries()) { // HACK: The built-in `dep-require` dependency type // uses its `Deduper` instance to ignore dependencies // within the same "phase" of a lasso operation. // // However, for the purposes of calculating intersection // we should not de-duplicate across each "walk" of // starting dependency. // // The `Deduper` stores a cache of "visited" dependencies in // `lassoContext.phaseData['dependency-require']`. // // We reset the `phaseData` property to remove this // cache before we walk each starting dependency. let oldPhaseData = lassoContext.phaseData; lassoContext.phaseData = {}; yield dependencyWalker.walk({ lassoContext: lassoContext, dependency: dependency, flags: flags, on: { dependency: onDependency(tracking, strictIntersection, firstSet, i) } }); lassoContext.phaseData = oldPhaseData; } var intersection = []; function checkDependency(info) { if (info.count >= thresholdValue) { intersection.push(info.dependency); } } if (strictIntersection) { // strict intersection for (var i = 0, len = firstSet.length; i < len; i++) { var dependency = firstSet[i]; checkDependency(tracking[dependency.getKey()]); } } else { // not a strict intersection so we need to check counts for all dependencies for (var key in tracking) { if (tracking.hasOwnProperty(key)) { checkDependency(tracking[key]); } } } return intersection; })(); }, calculateKey() { return null; // A just use a unique ID for this dependency } };