An open API service indexing awesome lists of open source software.

https://github.com/ildella/pipelean

A pragmatic library for sequential async operations with first-class error handling.
https://github.com/ildella/pipelean

function-composition functional-programming javascript javascript-library

Last synced: 6 days ago
JSON representation

A pragmatic library for sequential async operations with first-class error handling.

Awesome Lists containing this project

README

          

# Pipelean

[![npm version](https://img.shields.io/npm/v/pipelean.svg)](https://www.npmjs.com/package/pipelean)
[![Build Status](https://github.com/ildella/pipelean/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/ildella/pipelean/actions)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

Sequential async pipelines with **first-class retry, error boundaries, and smart failure strategies**. Pragmatic, direct, no heavy abstractions.

Just plain JavaScript. Eager execution. Perfect stack traces.

```js
const result = await series([
() => fetchUser(id),
user => validateAndEnrich(user),
final => saveToDatabase(final),
saved => sendWebhook(saved),
], { strategy: collect }); // or failFast, retry(3), custom...
```

## Why Pipelean?

To stop writing the same try/catch and manual accumulation boilerplate.

```js

## This is bad coding
for await (const item of iterable) {
try {
const result = await execute(item)
} catch (error) {
// OH BOY
console.error(error)
}
}

## This does not have async transformations and error control
array.filter(predicate).map(transform)
````

Pipelean gives you:

- `series` & `scan` for horizontal flows (independent or stateful steps)
- `pipe` for vertical composition
- `tryCatch` and `retry` middleware you can reuse across your app
- Built-in error strategies with sensible defaults for each operation
- Structured results and progress hooks — no silent crashes

## The alternatives

Need parallel? → p-map
Want lazy iterators? → iter-tools
Love reactive streams? → RxJS / most.js

We believe Pipelean is a pragmatic middle path: sequential by design, with built-in error control and resiliency — so you stop rewriting the same boilerplate every time.

## ESLint Plugin

Pipelean ships a small ESLint plugin that flags `.forEach()`, `.reduce()`, `.map(async ...)`, `for await...of`, and `Promise.*` static combinators, suggesting pipelean equivalents. It is a separate entry point — importing it does not pull in the runtime library.

```js
import pipeleanPlugin from 'pipelean/eslint'

export default [
{
plugins: { pipelean: pipeleanPlugin },
rules: {
'pipelean/no-array-foreach': 'warn', // suggests series()
'pipelean/no-array-reduce': 'warn', // suggests scan()
'pipelean/no-array-map-async': 'warn', // suggests series()
'pipelean/no-for-await-of': 'warn', // suggests series()
'pipelean/no-promise-combinators': 'warn', // suggests series() / tryCatch()
},
},
]
```

## AI & Agentic Development

Pipelean is "Agent-Ready." It ships with built-in **Skills** and an **Agent Persona** to help AI assistants (like Claude, Gemini CLI, or Cursor) write better code using this library.

### 1. Install Skills

The easiest way to install the skills is using the Vercel [agent-skills](https://github.com/vercel-labs/skills) CLI:

```sh
npx skills add https://github.com/ildella/pipelean/tree/master/skills
```

This will install:
- `pipelean-core`
- `pipelean-functional-programming`

### 2. (Experimental) using [skills-npm](https://github.com/antfu/skills-npm/)

```sh
yarn add -D skills-npm
yarn skills-npm
```

## Documentation

* [Architecture](docs/architecture.md) : The philosophy and design principles.
* [Guide](docs/guide.md) : Core concepts and usage patterns.
* [Examples](docs/examples.md) - Practical usage examples for all functions
* [Reference](docs/reference.md) - Reference docs

## Example

```js
import { pipe, series } from 'pipelean'

const downloadSomething = async () => {...}
const transformSomething = () => {...}
const writeToDatabase = async () => {...}

const pipeline = await pipe(
downloadSomething,
transformSomething,
writeToDatabase,
)

const {results, errors} = await series(items, pipeline, {
strategy: failFast,
})
```