UNPKG

@konkon5991/pipeline-ts

Version:

A lightweight TypeScript library for Railway Oriented Programming (ROP) with comprehensive functional programming utilities.

166 lines 7.02 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { isSuccess, isFailure } from './result'; /** * Default logger function. */ const defaultLogger = console.log; /** * Inspects a result value with optional debugging information. * @template T - The type of the value in case of success. * @template E - The type of the error in case of failure. * @param {DebugOptions} options - Debug options. * @returns {(result: Result<T, E>) => Result<T, E>} - A function that inspects and returns the result. */ export const inspect = (options = {}) => (result) => { const { label = 'Result', includeTimestamp = false, includeStack = false, logger = defaultLogger } = options; const timestamp = includeTimestamp ? new Date().toISOString() : ''; const prefix = timestamp ? `[${timestamp}] ${label}:` : `${label}:`; if (isSuccess(result)) { logger(`${prefix} Success ->`, result.value); } else { logger(`${prefix} Failure ->`, result.error); if (includeStack && result.error instanceof Error) { logger(`Stack trace:`, result.error.stack); } } return result; }; /** * Traces the execution time of a function. * @template T - The type of the value in case of success. * @template E - The type of the error in case of failure. * @param {string} label - Label for the trace. * @param {(result: Result<T, E>) => Result<T, E> | Promise<Result<T, E>>} fn - Function to trace. * @returns {(result: Result<T, E>) => Promise<Result<T, E>>} - A function that traces execution time. */ export const trace = (label, fn) => (result) => __awaiter(void 0, void 0, void 0, function* () { const start = performance.now(); const output = yield fn(result); const duration = performance.now() - start; console.log(`[Trace] ${label}: ${duration.toFixed(2)}ms`); return output; }); /** * Logs a custom message based on the result. * @template T - The type of the value in case of success. * @template E - The type of the error in case of failure. * @param {Object} messages - Custom messages for success and failure. * @param {(value: T) => string} messages.onSuccess - Message generator for success. * @param {(error: E) => string} messages.onFailure - Message generator for failure. * @param {(message: string) => void} logger - Logger function. * @returns {(result: Result<T, E>) => Result<T, E>} - A function that logs and returns the result. */ export const log = (messages, logger = defaultLogger) => (result) => { if (isSuccess(result) && messages.onSuccess) { logger(messages.onSuccess(result.value)); } else if (isFailure(result) && messages.onFailure) { logger(messages.onFailure(result.error)); } return result; }; /** * Creates a breakpoint for debugging. * @template T - The type of the value in case of success. * @template E - The type of the error in case of failure. * @param {(result: Result<T, E>) => boolean} condition - Condition to trigger breakpoint. * @returns {(result: Result<T, E>) => Result<T, E>} - A function that conditionally triggers debugger. */ export const breakpoint = (condition) => (result) => { if (!condition || condition(result)) { debugger; } return result; }; /** * Asserts a condition on a successful result. * @template T - The type of the value in case of success. * @template E - The type of the error in case of failure. * @param {(value: T) => boolean} predicate - Assertion predicate. * @param {string} message - Error message if assertion fails. * @returns {(result: Result<T, E>) => Result<T, E | Error>} - A function that asserts and returns the result. */ export const assert = (predicate, message) => (result) => { if (isSuccess(result) && !predicate(result.value)) { throw new Error(`Assertion failed: ${message}. Value: ${JSON.stringify(result.value)}`); } return result; }; /** * Creates a pipeline debugger that tracks all transformations. */ export class PipelineDebugger { constructor() { this.steps = []; } /** * Wraps a function to track its execution. * @template T - The type of the value in case of success. * @template E - The type of the error in case of failure. * @param {string} label - Label for this step. * @param {Function} fn - Function to wrap. * @returns {Function} - Wrapped function that tracks execution. */ wrap(label, fn) { return (input) => __awaiter(this, void 0, void 0, function* () { const start = performance.now(); const result = yield fn(input); const duration = performance.now() - start; this.steps.push({ label, duration, result: isSuccess(result) ? { success: result.value } : { failure: result.error } }); return result; }); } /** * Gets the debug report. * @returns {Object} - Debug report with all steps and total duration. */ getReport() { const totalDuration = this.steps.reduce((sum, step) => sum + step.duration, 0); return { steps: this.steps, totalDuration, averageDuration: this.steps.length > 0 ? totalDuration / this.steps.length : 0, slowestStep: this.steps.length > 0 ? this.steps.reduce((slowest, step) => step.duration > slowest.duration ? step : slowest) : null }; } /** * Prints the debug report. */ printReport() { const report = this.getReport(); console.log('\n=== Pipeline Debug Report ==='); console.log(`Total duration: ${report.totalDuration.toFixed(2)}ms`); console.log(`Average duration: ${report.averageDuration.toFixed(2)}ms`); if (report.slowestStep) { console.log(`Slowest step: ${report.slowestStep.label} (${report.slowestStep.duration.toFixed(2)}ms)`); } console.log('\nSteps:'); this.steps.forEach((step, index) => { console.log(` ${index + 1}. ${step.label}: ${step.duration.toFixed(2)}ms`); console.log(` Result:`, step.result); }); console.log('========================\n'); } /** * Clears the debug history. */ clear() { this.steps = []; } } //# sourceMappingURL=debug.js.map