import * as plugins from './classes.plugins.js'; export interface ITimedAggregatorOptions { aggregationIntervalInMillis: number; functionForAggregation: (input: T[]) => void; } export class TimedAggregtor { public options: ITimedAggregatorOptions; private storageArray: T[] = []; private isStopped = false; constructor(optionsArg: ITimedAggregatorOptions) { this.options = optionsArg; } private aggregationTimer: plugins.smarttime.Timer; private checkAggregationStatus() { if (this.isStopped) { return; } const addAggregationTimer = () => { this.aggregationTimer = new plugins.smarttime.Timer(this.options.aggregationIntervalInMillis); this.aggregationTimer.completed.then(() => { if (this.isStopped) { this.aggregationTimer = null; return; } const aggregateForProcessing = this.storageArray; if (aggregateForProcessing.length === 0) { this.aggregationTimer = null; return; } this.storageArray = []; addAggregationTimer(); this.options.functionForAggregation(aggregateForProcessing); }); this.aggregationTimer.start(); }; if (!this.aggregationTimer) { addAggregationTimer(); } } public add(aggregationArg: T) { if (this.isStopped) { return; } this.storageArray.push(aggregationArg); this.checkAggregationStatus(); } /** * stops the aggregation timer chain * @param flushRemaining if true, calls functionForAggregation with any remaining items */ public stop(flushRemaining: boolean = false) { this.isStopped = true; if (this.aggregationTimer) { this.aggregationTimer.reset(); this.aggregationTimer = null; } if (flushRemaining && this.storageArray.length > 0) { const remaining = this.storageArray; this.storageArray = []; this.options.functionForAggregation(remaining); } else { this.storageArray = []; } } }