UNPKG

acelga-bus

Version:

An extensible typescript message bus with support for middlewares

95 lines (74 loc) 2.65 kB
import {Dispatcher} from './single'; import { Constructable, EventSubscriptionCallback, IScheduler, ErrorLogger, PipelinePlan, PipelineResult, ExecutionResult, PipelineExecutionResult, PipelineFactory, } from '../interfaces'; export default class BulkDispatcher<T> { dispatcher: Dispatcher<T>; scheduler: IScheduler<T>; pipelineFactory: PipelineFactory<T>; errorLogger: ErrorLogger; constructor(dispatcher: Dispatcher<T>, scheduler: IScheduler<T>, pipelineFactory: PipelineFactory<T>, errorLogger: ErrorLogger) { this.dispatcher = dispatcher; this.scheduler = scheduler; this.pipelineFactory = pipelineFactory; this.errorLogger = errorLogger; } public on<T1 extends T>(eventType: Constructable<T1>, callback: EventSubscriptionCallback<T1> ): void { return this.dispatcher.on(eventType, callback); } public onAny(callback: EventSubscriptionCallback<T>): void { return this.dispatcher.onAny(callback); } public async trigger<R extends T = T>(events: R[]): Promise<ExecutionResult<T, R>[]> { try { const plan = this.scheduler.schedule(events); const pipelinesPromises = plan.plan.map(pipelinePlan => this.executePipelinePlan(pipelinePlan)); const results: any[] = await this.mapPipelinePromises(pipelinesPromises); const errors = this.getAllErrors<R>(results); if (errors.length){ return Promise.resolve(errors); } return []; } catch (error) { this.errorLogger(error); return Promise.reject(error); } } protected getAllErrors<R extends T = T>(results: Array<PipelineResult<T, R>>): ExecutionResult<T, R>[] { const errors: PipelineResult<T, R> = []; results.forEach(result => { result.forEach(error => errors.push(error)); }); return errors; } public isListened(eventType: Constructable<T>): boolean { return this.dispatcher.isListened(eventType); } protected executePipelinePlan(pipelinePlan: PipelinePlan<T>) { const pipeline = this.pipelineFactory(this.dispatcher); if (pipelinePlan.preserveOrder) return pipeline.executeStopOnError(pipelinePlan.payloads); return pipeline.executeContinueOnError(pipelinePlan.payloads); } protected async mapPipelinePromises(pipelines: PipelineExecutionResult<T>[]){ const results: any[] = []; const pipelinesPromises = pipelines.map((pipeline, index) => { return pipeline .then(result => results[index] = result) .catch((error: any) => this.errorLogger(error)); }); await Promise.all(pipelinesPromises); return results; } public off<T1 extends T>(eventType: Constructable<T1>, callback?: EventSubscriptionCallback<T1> ): void { this.dispatcher.off(eventType, callback); } }