npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@konkon5991/pipeline-ts

v0.2.5

Published

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

Readme

PipelineTS

npm version TypeScript Test Coverage License: MIT

A lightweight 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.

Features

  • 🚀 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

Installation

npm install @konkon5991/pipeline-ts
# or
yarn add @konkon5991/pipeline-ts
# or
pnpm add @konkon5991/pipeline-ts

Quick Start

import { pipe, success, failure, map, fold } from '@konkon5991/pipeline-ts';

// 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}`,
  (value) => `Success: ${value}`
)(result);

console.log(output); // "Success: 42"

Core Concepts

Result Type

The Result<T, E> type represents either a success (Success<T>) or a failure (Failure<E>):

import { Result, success, failure, isSuccess, isFailure } from '@konkon5991/pipeline-ts';

const successResult: Result<number, string> = success(42);
const failureResult: Result<number, string> = failure("Error occurred");

if (isSuccess(successResult)) {
  console.log(successResult.value); // 42
}

if (isFailure(failureResult)) {
  console.log(failureResult.error); // "Error occurred"
}

Essential Operations

Map Operations

Transform success values while preserving failures:

import { map, mapAsync, success, failure } from '@konkon5991/pipeline-ts';

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)

FlatMap (Chain) Operations

Chain operations that return Results:

import { flatMap, success, failure } from '@konkon5991/pipeline-ts';

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)

Error Handling

Handle and transform errors:

import { mapError, recover, orElse } from '@konkon5991/pipeline-ts';

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);

Pipelines

Async Pipelines

For functions that may be asynchronous:

import { pipe, success, failure } from '@konkon5991/pipeline-ts';

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("[email protected]");
// Result: success("Email sent to [email protected]")

Sync Pipelines

For better performance with synchronous functions:

import { pipeSync, success, failure } from '@konkon5991/pipeline-ts';

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")

Validation

Accumulate multiple errors instead of short-circuiting:

import { validateObject, valid, invalid } from '@konkon5991/pipeline-ts';

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 @"])

Async Utilities

Parallel Execution

import { parallel, success } from '@konkon5991/pipeline-ts';

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])

Retry with Backoff

import { retry, success, failure } from '@konkon5991/pipeline-ts';

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}`)
});

Sequential Processing

import { sequential, success } from '@konkon5991/pipeline-ts';

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"])

Debugging

Inspection and Logging

import { inspect, trace, log, pipe } from '@konkon5991/pipeline-ts';

const pipeline = pipe(
  inspect({ label: "Input" }),
  (x: number) => success(x * 2),
  log({
    onSuccess: (value) => `Doubled: ${value}`,
    onFailure: (error) => `Error: ${error}`
  }),
  trace("Final step", (result) => {
    // Process result
    return result;
  })
);

Pipeline Debugging

import { PipelineDebugger } from '@konkon5991/pipeline-ts';

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

Error Types and Utilities

Custom Error Types

interface ValidationError {
  field: string;
  message: string;
}

interface NetworkError {
  code: number;
  message: string;
}

type AppError = ValidationError | NetworkError;

const validateField = (value: string): Result<string, ValidationError> =>
  value.length > 0 
    ? success(value)
    : failure({ field: "name", message: "Required" });

Error Recovery Patterns

import { recoverWith, mapError } from '@konkon5991/pipeline-ts';

const fetchWithFallback = pipe(
  primaryAPI,
  recoverWith((error) => fallbackAPI()),
  mapError((error) => ({ ...error, recovered: true }))
);

API Reference

Core Functions

  • success<T>(value: T) - Create a success result
  • failure<E>(error: E) - Create a failure result
  • isSuccess<T, E>(result: Result<T, E>) - Type guard for success
  • isFailure<T, E>(result: Result<T, E>) - Type guard for failure

Transformation Functions

  • map<T, U, E>(fn: (value: T) => U) - Transform success value
  • flatMap<T, U, E>(fn: (value: T) => Result<U, E>) - Chain operations
  • fold<T, E, U>(onFailure: (error: E) => U, onSuccess: (value: T) => U) - Handle both cases
  • bimap<T, U, E, F>(onSuccess: (value: T) => U, onFailure: (error: E) => F) - Transform both cases

Error Handling Functions

  • mapError<T, E, F>(fn: (error: E) => F) - Transform error
  • recover<T, E>(fn: (error: E) => T) - Recover from error
  • orElse<T, E>(fn: () => Result<T, E>) - Provide alternative

Pipeline Functions

  • pipe(...fns) - Async pipeline composition
  • pipeSync(...fns) - Sync pipeline composition

Test Coverage

Current test coverage: 97.45%

  • Statements: 97.45%
  • Branches: 98.11%
  • Functions: 94.73%
  • Lines: 97.45%

Performance

PipelineTS is designed for performance:

  • Zero dependencies
  • Separate sync/async paths
  • Tree-shakable modules
  • Optimized for V8 engine

Comparison with Other Libraries

| 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 |

Contributing

We welcome contributions! Please see our Contributing Guide for details.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Changelog

See CHANGELOG.md for a list of changes.