StackGenVis: Alignment of Data, Algorithms, and Models for Stacking Ensemble Learning Using Performance Metrics
https://doi.org/10.1109/TVCG.2020.3030352
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.
223 lines
5.6 KiB
223 lines
5.6 KiB
'use strict';
|
|
|
|
var Run = require('./lib/run');
|
|
var Task = require('./lib/task');
|
|
var noop = require('./lib/noop');
|
|
var utils = require('./lib/utils');
|
|
var map = require('./lib/map-deps');
|
|
var inspect = require('./lib/inspect');
|
|
var flowFactory = require('./lib/flow');
|
|
var Emitter = require('component-emitter');
|
|
var builds = [];
|
|
|
|
/**
|
|
* Composer constructor. Create an instance of `Composer`
|
|
*
|
|
* ```js
|
|
* var composer = new Composer();
|
|
* ```
|
|
*/
|
|
|
|
function Composer(name) {
|
|
Emitter.call(this);
|
|
this.tasks = {};
|
|
utils.define(this, '_appname', name || this._appname || 'composer');
|
|
utils.define(this, 'buildHistory', {
|
|
configurable: true,
|
|
get: function() {
|
|
return builds;
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Mix in `Emitter` methods
|
|
*/
|
|
|
|
Emitter(Composer.prototype);
|
|
|
|
/**
|
|
* Register a new task with it's options and dependencies.
|
|
*
|
|
* Dependencies may also be specified as a glob pattern. Be aware that
|
|
* the order cannot be guarenteed when using a glob pattern.
|
|
*
|
|
* ```js
|
|
* // register task "site" with composer
|
|
* app.task('site', ['styles'], function() {
|
|
* return app.src('templates/pages/*.hbs')
|
|
* .pipe(app.dest('_gh_pages'));
|
|
* });
|
|
* ```
|
|
* @param {String} `name` Name of the task to register
|
|
* @param {Object} `options` Options to set dependencies or control flow.
|
|
* @param {Object} `options.deps` array of dependencies
|
|
* @param {Object} `options.flow` How this task will be executed with it's dependencies (`series`, `parallel`, `settleSeries`, `settleParallel`)
|
|
* @param {String|Array|Function} `deps` Additional dependencies for this task.
|
|
* @param {Function} `fn` Final function is the task to register.
|
|
* @return {Object} Return the instance for chaining
|
|
* @api public
|
|
*/
|
|
|
|
Composer.prototype.task = function(name/*, options, deps, task */) {
|
|
if (typeof name !== 'string') {
|
|
throw new TypeError('expected `name` to be a string');
|
|
}
|
|
|
|
var deps = [].concat.apply([], [].slice.call(arguments, 1));
|
|
|
|
var options = {};
|
|
var fn = noop;
|
|
if (deps.length && typeof deps[deps.length - 1] === 'function') {
|
|
fn = deps.pop();
|
|
}
|
|
|
|
if (deps.length && utils.isobject(deps[0])) {
|
|
options = deps.shift();
|
|
}
|
|
|
|
options.deps = utils.unique(deps
|
|
.concat(options.deps || [])
|
|
.map(map.bind(this)));
|
|
|
|
var task = new Task({
|
|
name: name,
|
|
options: options,
|
|
fn: fn,
|
|
app: this
|
|
});
|
|
|
|
inspect(this, task);
|
|
|
|
// bubble up events from tasks
|
|
task.on('starting', this.emit.bind(this, 'task:starting'));
|
|
task.on('finished', this.emit.bind(this, 'task:finished'));
|
|
task.on('error', this.emit.bind(this, 'task:error'));
|
|
|
|
this.tasks[name] = task;
|
|
this.emit('task', this.name, task);
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Build a task or array of tasks.
|
|
*
|
|
* ```js
|
|
* app.build('default', function(err, results) {
|
|
* if (err) return console.error(err);
|
|
* console.log(results);
|
|
* });
|
|
* ```
|
|
*
|
|
* @param {String|Array|Function} `tasks` List of tasks by name, function, or array of names/functions. (Defaults to `[default]`).
|
|
* @param {Object} `options` Optional options object to merge onto each task's options when building.
|
|
* @param {Function} `cb` Callback function to be called when all tasks are finished building.
|
|
* @api public
|
|
*/
|
|
|
|
Composer.prototype.build = function(/* [tasks,] [options,] callback */) {
|
|
var args = [].concat.apply([], [].slice.call(arguments));
|
|
var done = args.pop();
|
|
if (typeof done !== 'function') {
|
|
throw new TypeError('Expected the last argument to be a callback function, but got `' + typeof done + '`.');
|
|
}
|
|
|
|
var options = {};
|
|
if (args.length && utils.isobject(args[args.length - 1])) {
|
|
options = args.pop();
|
|
}
|
|
|
|
if (args.length === 0) {
|
|
args = ['default'];
|
|
}
|
|
|
|
args.push(options);
|
|
|
|
// gather total build time information
|
|
var self = this;
|
|
var build = new Run(builds.length);
|
|
builds.push(build);
|
|
build.start();
|
|
this.emit('starting', this, build);
|
|
function finishBuild(err) {
|
|
build.end();
|
|
if (err) {
|
|
utils.define(err, 'app', self);
|
|
utils.define(err, 'build', build);
|
|
self.emit('error', err);
|
|
} else {
|
|
self.emit('finished', self, build);
|
|
}
|
|
return done.apply(null, arguments);
|
|
};
|
|
|
|
var fn = this.series.apply(this, args);
|
|
return fn(finishBuild);
|
|
};
|
|
|
|
/**
|
|
* Compose task or list of tasks into a single function that runs the tasks in series.
|
|
*
|
|
* ```js
|
|
* app.task('foo', function(done) {
|
|
* console.log('this is foo');
|
|
* done();
|
|
* });
|
|
*
|
|
* var fn = app.series('foo', function bar(done) {
|
|
* console.log('this is bar');
|
|
* done();
|
|
* });
|
|
*
|
|
* fn(function(err) {
|
|
* if (err) return console.error(err);
|
|
* console.log('done');
|
|
* });
|
|
* //=> this is foo
|
|
* //=> this is bar
|
|
* //=> done
|
|
* ```
|
|
* @param {String|Array|Function} `tasks` List of tasks by name, function, or array of names/functions.
|
|
* @return {Function} Composed function that may take a callback function.
|
|
* @api public
|
|
*/
|
|
|
|
Composer.prototype.series = flowFactory('series');
|
|
|
|
/**
|
|
* Compose task or list of tasks into a single function that runs the tasks in parallel.
|
|
*
|
|
* ```js
|
|
* app.task('foo', function(done) {
|
|
* setTimeout(function() {
|
|
* console.log('this is foo');
|
|
* done();
|
|
* }, 500);
|
|
* });
|
|
*
|
|
* var fn = app.parallel('foo', function bar(done) {
|
|
* console.log('this is bar');
|
|
* done();
|
|
* });
|
|
*
|
|
* fn(function(err) {
|
|
* if (err) return console.error(err);
|
|
* console.log('done');
|
|
* });
|
|
* //=> this is bar
|
|
* //=> this is foo
|
|
* //=> done
|
|
* ```
|
|
*
|
|
* @param {String|Array|Function} `tasks` List of tasks by name, function, or array of names/functions.
|
|
* @return {Function} Composed function that may take a callback function.
|
|
* @api public
|
|
*/
|
|
|
|
Composer.prototype.parallel = flowFactory('parallel');
|
|
|
|
/**
|
|
* Expose Composer
|
|
*/
|
|
|
|
module.exports = Composer;
|
|
|