UNPKG

caminho

Version:

Tool for creating efficient data pipelines in a JavaScript environment

89 lines 3.78 kB
import { from, lastValueFrom, tap } from 'rxjs'; import { wrapGenerator, wrapGeneratorWithBackPressure } from './operators/generator'; import { pipe } from './operators/pipe'; import { batch } from './operators/batch'; import { parallel } from './operators/parallel'; import { reduce } from './operators/reduce'; import { filter } from './operators/filter'; import { applyOperator, isBatch, } from './operators/helpers/operatorHelpers'; import { PendingDataControlInMemory } from './utils/PendingDataControl'; import { getOnStepFinished } from './utils/onStepFinished'; import { getOnStepStarted } from './utils/onStepStarted'; import { generateId } from './utils/generateId'; export class Caminho { options; generator; operators = []; pendingDataControl; constructor(generatorParams, options) { this.options = options; this.addOperatorApplier = this.addOperatorApplier.bind(this); this.getApplierForPipeOrBatch = this.getApplierForPipeOrBatch.bind(this); this.run = this.run.bind(this); if (options?.maxItemsFlowing) { this.pendingDataControl = new PendingDataControlInMemory(); } this.generator = this.getGenerator(generatorParams); } getNumberOfItemsFlowing() { return this.pendingDataControl?.size; } pipe(params) { const operatorApplier = this.getApplierForPipeOrBatch(params); this.addOperatorApplier(() => operatorApplier); return this; } parallel(params) { const operatorAppliers = params.map(this.getApplierForPipeOrBatch); const operatorApplier = parallel(params, operatorAppliers); this.addOperatorApplier(() => operatorApplier); return this; } filter(params) { const loggers = this.getLoggers(params); this.addOperatorApplier(filter(params.fn, loggers, this.pendingDataControl)); return this; } reduce(reduceParams) { const loggers = this.getLoggers(reduceParams); this.addOperatorApplier(reduce(reduceParams, loggers, this.pendingDataControl)); return this; } async run(initialBag) { const runId = generateId(); const initial$ = from(this.generator({ ...initialBag }, runId)); const observable$ = this.operators.reduce((acc, operator) => applyOperator(acc, operator, runId), initial$); const finalObservable$ = this.options?.maxItemsFlowing ? observable$.pipe(tap(() => this.pendingDataControl.decrement(runId))) : observable$; try { return await lastValueFrom(finalObservable$, { defaultValue: initialBag }); } finally { this.pendingDataControl?.destroyBucket(runId); } } getGenerator(generatorParams) { const loggers = this.getLoggers(generatorParams); if (this.options?.maxItemsFlowing) { const pendingDataControl = this.pendingDataControl; return wrapGeneratorWithBackPressure(generatorParams, this.options.maxItemsFlowing, pendingDataControl, loggers); } return wrapGenerator(generatorParams, loggers); } addOperatorApplier(operatorApplier) { this.operators.push(operatorApplier); } getApplierForPipeOrBatch(params) { return isBatch(params) ? batch(params, this.getLoggers(params)) : pipe(params, this.getLoggers(params)); } getLoggers(params) { const stepName = params.name ?? params.fn.name; const onStepStarted = getOnStepStarted(stepName, this.options?.onStepStarted); const onStepFinished = getOnStepFinished(stepName, this.options?.onStepFinished); return { onStepFinished, onStepStarted }; } } //# sourceMappingURL=Caminho.js.map