deep-package-manager
Version:
DEEP Package Manager
222 lines (179 loc) • 4.95 kB
JavaScript
/**
* Created by AlexanderC on 2/5/16.
*/
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Dumper = undefined;
var _WaitFor = require('../../Helpers/WaitFor');
var _DuplicateModulesException = require('./Exception/DuplicateModulesException');
class Dumper {
/**
* @param {DependenciesResolver|*} dependenciesResolver
* @param {Storage|*} storage
* @param {AbstractDriver|FSDriver|*} dumpDriver
*/
constructor(dependenciesResolver, storage, dumpDriver) {
this._dependenciesResolver = dependenciesResolver;
this._storage = storage;
this._dumpDriver = dumpDriver;
}
/**
* @returns {DependenciesResolver|*}
*/
get dependenciesResolver() {
return this._dependenciesResolver;
}
/**
* @returns {Storage|*}
*/
get storage() {
return this._storage;
}
/**
* @returns {AbstractDriver|FSDriver|*}
*/
get dumpDriver() {
return this._dumpDriver;
}
/**
* @param {Function} cb
*/
dump(cb) {
this._dependenciesResolver.resolve((error, depsTree) => {
if (error) {
cb(error);
return;
}
let cbCalled = false;
let wait = new _WaitFor.WaitFor();
let depObjectsStack = Dumper._collectDepsObjects(depsTree);
try {
this._checkForDuplicates(depObjectsStack);
} catch (error) {
cb(error);
return;
}
let remaining = depObjectsStack.length;
wait.push(() => {
return remaining <= 0;
});
depObjectsStack.forEach(dependencyObj => {
this._dumpSingle(dependencyObj.context, error => {
if (error) {
if (!cbCalled) {
cbCalled = true;
cb(error);
}
}
remaining--;
});
});
wait.ready(() => {
if (!cbCalled) {
cb(null);
}
});
});
}
/**
* @param {Object} depObjectsStack
* @private
*/
_checkForDuplicates(depObjectsStack) {
let depStack = {};
let duplicatesStack = {};
depObjectsStack.forEach(dependencyObj => {
let depContext = dependencyObj.context;
depStack[depContext.name] = depStack[depContext.name] || [];
depStack[depContext.name].push(depContext.version);
});
for (let depName in depStack) {
if (!depStack.hasOwnProperty(depName)) {
continue;
}
let depVersions = depStack[depName];
if (depVersions.length > 1) {
duplicatesStack[depName] = depVersions;
}
}
if (Object.keys(duplicatesStack).length > 0) {
throw new _DuplicateModulesException.DuplicateModulesException(duplicatesStack);
}
}
/**
* @param {Context} moduleContext
* @param {Function} cb
* @private
*/
_dumpSingle(moduleContext, cb) {
let moduleName = moduleContext.name;
let moduleVersion = moduleContext.version;
this._dumpDriver.hasToDump(moduleContext, (error, hasToDump) => {
if (error) {
cb(error);
return;
} else if (!hasToDump) {
console.debug(`Module '${moduleName}@${moduleVersion}' has been already dumped. Skipping...`);
cb(null);
return;
}
console.debug(`Fetching '${moduleName}@${moduleVersion}' module data`);
this._storage.readModule(moduleContext, (error, moduleObj) => {
if (error) {
cb(error);
return;
}
console.debug(`Dumping '${moduleName}@${moduleVersion}' module`);
this._dumpDriver.dump(moduleObj, () => {
console.debug(`Initializing '${moduleName}@${moduleVersion}' module`);
this._dumpDriver.initialize(moduleObj, cb);
});
});
});
}
/**
* @param {Object} depsTree
* @returns {{name:*,version:*}[]}
* @private
*/
static _collectDepsObjects(depsTree) {
let depsVector = [];
// @todo: return circular deps?
// although these are removed on Dumper._removeDepsVectorDuplicates()
if (depsTree._isCircular) {
return depsVector;
}
depsVector.push({
context: depsTree.context
});
let deps = depsTree.dependencies || {};
for (let depName in deps) {
if (!deps.hasOwnProperty(depName)) {
continue;
}
let nestedDepsTree = deps[depName];
depsVector = depsVector.concat(Dumper._collectDepsObjects(nestedDepsTree));
}
return Dumper._removeDepsVectorDuplicates(depsVector);
}
/**
* @param {{context:*}[]} depsVector
* @returns {{context:*}[]}
* @private
*/
static _removeDepsVectorDuplicates(depsVector) {
let storageKeys = [];
let cleanVector = [];
depsVector.forEach(depObj => {
let storageKey = depObj.context.toString();
if (storageKeys.indexOf(storageKey) === -1) {
storageKeys.push(storageKey);
cleanVector.push(depObj);
}
});
return cleanVector;
}
}
exports.Dumper = Dumper;