A lightweight, dependency-free TypeScript library for Railway Oriented Programming (ROP) with comprehensive functional programming utilities.
npm install ts-dependency-free-pipeline



A lightweight, dependency-free TypeScript library for Railway Oriented Programming (ROP). PipelineTS provides a comprehensive set of functional programming utilities for handling success and failure cases with type safety.
- ๐ Zero Dependencies - Lightweight and fast
- ๐ Type-Safe - Full TypeScript support with strict typing
- โก Performance - Separate sync/async pipelines for optimal performance
- ๐ ๏ธ Comprehensive - Complete set of monadic operations
- ๐งช Validation - Error accumulation support
- ๐ง Debugging - Built-in debugging and tracing utilities
- ๐ฆ Tree-shakable - Import only what you need
``bash`
npm install ts-dependency-free-pipelineor
yarn add ts-dependency-free-pipelineor
pnpm add ts-dependency-free-pipeline
`typescript
import { pipe, success, failure, map, fold } from 'ts-dependency-free-pipeline';
// Define your functions
const parseNumber = (input: string) =>
isNaN(Number(input)) ? failure("Not a number") : success(Number(input));
const double = (num: number) => success(num * 2);
const toString = (num: number) => success(num.toString());
// Create a pipeline
const pipeline = pipe(parseNumber, double, toString);
// Execute the pipeline
const result = await pipeline("21");
const output = fold(
(error) => Error: ${error},Success: ${value}
(value) =>
)(result);
console.log(output); // "Success: 42"
`
The Result type represents either a success (Success) or a failure (Failure):
`typescript
import { Result, success, failure, isSuccess, isFailure } from 'ts-dependency-free-pipeline';
const successResult: Result
const failureResult: Result
if (isSuccess(successResult)) {
console.log(successResult.value); // 42
}
if (isFailure(failureResult)) {
console.log(failureResult.error); // "Error occurred"
}
`
Transform success values while preserving failures:
`typescript
import { map, mapAsync, success, failure } from 'ts-dependency-free-pipeline';
const result = success(5);
const doubled = map((x: number) => x * 2)(result);
// Result: success(10)
const asyncDoubled = await mapAsync(async (x: number) => x * 2)(result);
// Result: success(10)
`
Chain operations that return Results:
`typescript
import { flatMap, success, failure } from 'ts-dependency-free-pipeline';
const divide = (x: number, y: number) =>
y === 0 ? failure("Division by zero") : success(x / y);
const result = success(10);
const divided = flatMap((x: number) => divide(x, 2))(result);
// Result: success(5)
`
Handle and transform errors:
`typescript
import { mapError, recover, orElse } from 'ts-dependency-free-pipeline';
const result = failure("Network error");
// Transform error
const mappedError = mapError((err: string) => err.toUpperCase())(result);
// Recover from error
const recovered = recover((err: string) => 42)(result);
// Provide alternative
const alternative = orElse(() => success(0))(result);
`
For functions that may be asynchronous:
`typescript
import { pipe, success, failure } from 'ts-dependency-free-pipeline';
const validateEmail = async (email: string) =>
email.includes("@") ? success(email) : failure("Invalid email");
const normalizeEmail = async (email: string) =>
success(email.toLowerCase().trim());
const sendEmail = async (email: string) => {
// Simulate API call
return success(Email sent to ${email});
};
const pipeline = pipe(validateEmail, normalizeEmail, sendEmail);
const result = await pipeline("USER@EXAMPLE.COM");
// Result: success("Email sent to user@example.com")
`
For better performance with synchronous functions:
`typescript
import { pipeSync, success, failure } from 'ts-dependency-free-pipeline';
const validateAge = (age: number) =>
age >= 18 ? success(age) : failure("Must be 18 or older");
const calculateDiscount = (age: number) =>
age >= 65 ? success(0.2) : success(0.1);
const formatDiscount = (discount: number) =>
success(${(discount * 100).toFixed(0)}% discount);
const pipeline = pipeSync(validateAge, calculateDiscount, formatDiscount);
const result = pipeline(25);
// Result: success("10% discount")
`
Accumulate multiple errors instead of short-circuiting:
`typescript
import { validateObject, valid, invalid } from 'ts-dependency-free-pipeline';
const validators = {
name: (value: any) =>
typeof value === "string" && value.length > 0
? valid(value)
: invalid("Name is required"),
age: (value: any) =>
typeof value === "number" && value >= 0
? valid(value)
: invalid("Age must be a positive number"),
email: (value: any) =>
typeof value === "string" && value.includes("@")
? valid(value)
: invalid("Email must contain @")
};
const result = validateObject(validators)({
name: "",
age: -5,
email: "invalid"
});
// Result: failure(["Name is required", "Age must be a positive number", "Email must contain @"])
`
`typescript
import { parallel, success } from 'ts-dependency-free-pipeline';
const fetchUser = async () => success({ id: 1, name: "John" });
const fetchPosts = async () => success([{ id: 1, title: "Hello" }]);
const fetchComments = async () => success([{ id: 1, text: "Nice!" }]);
const result = await parallel(fetchUser, fetchPosts, fetchComments);
// Result: success([user, posts, comments])
`
`typescript
import { retry, success, failure } from 'ts-dependency-free-pipeline';
const unstableAPI = async () => {
if (Math.random() < 0.7) {
return failure("Network error");
}
return success("Data fetched");
};
const result = await retry(unstableAPI, {
maxAttempts: 3,
delay: 1000,
backoff: 'exponential',
onRetry: (attempt, error) => console.log(Retry ${attempt}: ${error})`
});
`typescript
import { sequential, success } from 'ts-dependency-free-pipeline';
const step1 = async () => success("Step 1 complete");
const step2 = async () => success("Step 2 complete");
const step3 = async () => success("Step 3 complete");
const result = await sequential(step1, step2, step3);
// Result: success(["Step 1 complete", "Step 2 complete", "Step 3 complete"])
`
`typescript
import { inspect, trace, log, pipe } from 'ts-dependency-free-pipeline';
const pipeline = pipe(
inspect({ label: "Input" }),
(x: number) => success(x * 2),
log({
onSuccess: (value) => Doubled: ${value},Error: ${error}
onFailure: (error) => `
}),
trace("Final step", (result) => {
// Process result
return result;
})
);
`typescript
import { PipelineDebugger } from 'ts-dependency-free-pipeline';
const debugger = new PipelineDebugger();
const step1 = debugger.wrap("parse", parseNumber);
const step2 = debugger.wrap("validate", validateAge);
const step3 = debugger.wrap("transform", transformData);
await step1("42");
await step2(42);
await step3(validatedData);
debugger.printReport();
// Outputs timing and result information for each step
`
`typescript
interface ValidationError {
field: string;
message: string;
}
interface NetworkError {
code: number;
message: string;
}
type AppError = ValidationError | NetworkError;
const validateField = (value: string): Result
value.length > 0
? success(value)
: failure({ field: "name", message: "Required" });
`
`typescript
import { recoverWith, mapError } from 'ts-dependency-free-pipeline';
const fetchWithFallback = pipe(
primaryAPI,
recoverWith((error) => fallbackAPI()),
mapError((error) => ({ ...error, recovered: true }))
);
`
- success - Create a success resultfailure
- - Create a failure resultisSuccess
- - Type guard for successisFailure
- - Type guard for failure
- map - Transform success valueflatMap
- - Chain operationsfold
- - Handle both casesbimap
- - Transform both cases
- mapError - Transform errorrecover
- - Recover from errororElse
- - Provide alternative
- pipe(...fns) - Async pipeline compositionpipeSync(...fns)` - Sync pipeline composition
-
Current test coverage: 97.45%
- Statements: 97.45%
- Branches: 98.11%
- Functions: 94.73%
- Lines: 97.45%
PipelineTS is designed for performance:
- Zero dependencies
- Separate sync/async paths
- Tree-shakable modules
- Optimized for V8 engine
| Feature | PipelineTS | fp-ts | Effect-ts |
|---------|------------|-------|-----------|
| Bundle Size | ~5KB | ~50KB | ~200KB |
| Dependencies | 0 | 0 | Many |
| Learning Curve | Low | High | Very High |
| Type Safety | High | Very High | Very High |
| Performance | High | Medium | Low |
We welcome contributions! Please see our Contributing Guide for details.
This project is licensed under the MIT License - see the LICENSE file for details.
See CHANGELOG.md for a list of changes.