A simple library for defining and executing JavaScript task trees.
- Support for synchronous, asynchronous, and promise-based tasks.
- Automatic result passing between dependent tasks.
- Rich API for building and modifying task trees.
- Small, dependency-free, and available as both ES2015 and CommonJS libraries.
$ npm install tasker-libNote:
tasker-librequires a Promise implementation available on the global object.
Have you previously used a task-based build system? You'll feel right at home with the tasker-lib API.
Using tasker-lib is quick and easy:
- Create a new
TaskRunner, optionally supplying configuration. - Add tasks through the
addTaskmethod. - Optionally modify the task tree by using
removeTask,addDependencies, andremoveDependencies. These may only be called while tasks are not being executed. - Optionally use the dependency results with the
resultsobject. Each task only has access to the results of its direct dependencies. - Run a task, and all its dependencies, with the
runmethod. All methods are locked during execution.
import {TaskRunner} from "tasker-lib";
const taskRunner = new TaskRunner();
// This sync task returns 1, which becomes available to tasks that depend on it through the "results" object.
taskRunner.addTask("dependency", () => 1);
taskRunner.addTask("root", ["dependency"], (results) => {
const dependencyResult = results["dependency"];
console.log(`Result of "dependency" is: ${dependencyResult}`); // 1
return dependencyResult + 1;
});
taskRunner.run("root").then((finalResult) => {
console.log(`Final results are ${finalResult}`); // finalResult === 2
});// The dependency list is optional for tasks that have no dependencies.
taskRunner.addTask("promise-task", (results) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("some-async-result");
}, 1000);
});
});taskRunner.addTask("async-task", (results, done) => {
setTimeout(() => {
done("some-async-result");
}, 1000);
});Dependencies can be added or removed to any task that has already been added. Calling addDependency multiple times with
the same taskName and dependencies will be ignored after the first call.
taskRunner.addTask("root", () => 3);
// Dependencies may be added before they exist, but the parent task must exist at this point.
taskRunner.addDependencies("root", ["child1"]);
taskRunner.addTask("child1", () => 1);
taskRunner.addTask("child2", () => 2);
taskRunner.addDependencies("child1", "child2"); // A string may be used for sole dependencies.
taskRunner.removeDependencies("root", "child1"); // child2 is still a dependency of child1, but not of root.const options = {
throwOnOverwrite: false // defaults to true
};
const taskRunner = new TaskRunner(options);
taskRunner.addTask("root", () => 1);
taskRunner.addTask("root", () => 1); // This would throw if throwOnOverwrite is true.Before each task starts, onTaskStart will be called with the task name and dependency list. Then, if there are any
dependencies, they will be executed and onTaskStart will likewise be called with their name and dependency list.
onTaskEnd will be called with the task name once the task has completed.
onTaskCancel will be called with the task name if a dependent task prevented it from executing.
onTaskFail will be called with the task name if an error occurred during task execution.
const options = {
onTaskStart: (taskName, taskDependencies) => {
console.log(`Task started: '${taskName}'. Depends on ${taskDependencies}.`);
},
onTaskEnd: (taskName) => {
console.log(`Task ended: '${taskName}'`);
}
};
const taskRunner = new TaskRunner(options);
taskRunner.addTask("child1", () => 1);
taskRunner.addTask("root", ["child1"], () => console.log(" - Running! - "));
taskRunner.run("root");
// Task started: 'root'. Depends on [].
// - Running! -
// Task ended: 'root'For command line usage, see tasker-cli.
tasker-lib uses SemVer for versioning. All releases will be available on both GitHub and npm.
MIT