// TaskChain chains tasks // and extends Task import * as plugins from './taskbuffer.plugins.js'; import { Task } from './taskbuffer.classes.task.js'; import { logger } from './taskbuffer.logging.js'; export class Taskchain extends Task { taskArray: Task[]; constructor(optionsArg: { taskArray: Task[]; name?: string; log?: boolean; buffered?: boolean; bufferMax?: number; }) { const options = { ...{ name: 'unnamed Taskchain', log: false, }, ...optionsArg, ...{ taskFunction: (x: any) => { // this is the function that gets executed when TaskChain is triggered const done = plugins.smartpromise.defer(); // this is the starting Deferred object let taskCounter = 0; // counter for iterating async over the taskArray const iterateTasks = (x: any) => { if (typeof this.taskArray[taskCounter] !== 'undefined') { logger.log('info', `${this.name} running: Task ${this.taskArray[taskCounter].name}`); this.taskArray[taskCounter].trigger(x).then((x) => { logger.log('info', this.taskArray[taskCounter].name); taskCounter++; iterateTasks(x); }).catch((err) => { const chainError = new Error( `Taskchain "${this.name}": task "${this.taskArray[taskCounter].name || 'unnamed'}" (index ${taskCounter}) failed: ${err instanceof Error ? err.message : String(err)}` ); (chainError as any).cause = err; done.reject(chainError); }); } else { logger.log('info', `Taskchain "${this.name}" completed successfully`); done.resolve(x); } }; iterateTasks(x); return done.promise; }, }, }; super(options); this.taskArray = optionsArg.taskArray; } addTask(taskArg: Task) { this.taskArray.push(taskArg); } removeTask(taskArg: Task): boolean { const index = this.taskArray.indexOf(taskArg); if (index === -1) { return false; } this.taskArray.splice(index, 1); return true; } shiftTask(): Task | undefined { return this.taskArray.shift(); } }