@stone-js/pipeline v0.1.1
Stone.js - Pipeline
An implementation of the Chain of Responsibility (CoR) pattern tailored for modern JavaScript and TypeScript apps using the Continuum Architecture philosophy.
Overview
The Pipeline
class is a flexible processor of "passable" values through a series of configurable steps called pipes. Pipes can be functions, factory-generated handlers, or class instances. Pipelines can run synchronously or asynchronously, support custom hook events, and allow pipe resolution via a resolver for advanced dependency injection scenarios.
Installation
npm i @stone-js/pipeline
# or
yarn add @stone-js/pipeline
# or
pnpm add @stone-js/pipeline
[!IMPORTANT] This package is pure ESM. Ensure your
package.json
includes"type": "module"
or configure your bundler appropriately.
import { Pipeline } from '@stone-js/pipeline'
Quick Start
import { Pipeline } from '@stone-js/pipeline'
const addOne = (v, next) => next(v + 1)
const timesTwo = (v, next) => next(v * 2)
const result = Pipeline.create<number>()
.send(1)
.through(addOne, timesTwo)
.sync()
.thenReturn()
console.log(result) // Output: 4
Features
- Chain-of-responsibility execution
- Supports function, factory, and class-based pipes
- Works in both sync and async mode
- Custom
resolver
support - Pipe lifecycle hooks via
on()
- Priority-based execution order
- Type-safe with TypeScript, compatible with JavaScript
Usage Patterns
Synchronous Pipeline
const pipeline = Pipeline.create<number>()
.send(2)
.through([
(v, next) => next(v + 3),
(v, next) => next(v * 2)
])
.sync()
const result = pipeline.thenReturn()
console.log(result) // Output: 10
Asynchronous Pipeline
const fetch = async (v, next) => next(await mockFetch(v))
const mockFetch = async (v) => new Promise(res => setTimeout(() => res(v * 10), 500))
const result = await Pipeline.create<number>()
.send(5)
.through(fetch)
.thenReturn()
console.log(result) // Output: 50
Using .pipe()
Incrementally
const result = Pipeline.create<number>()
.send(1)
.pipe(v => v + 1)
.pipe(v => v * 5)
.sync()
.thenReturn()
console.log(result) // Output: 10
Resolver for Dependency Injection
class MyPipe {
handle(v, next) {
return next(`Resolved: ${v}`)
}
}
const resolver = () => new MyPipe()
const result = Pipeline.create<string>({ resolver })
.send('value')
.through({ module: MyPipe, isClass: true })
.sync()
.thenReturn()
console.log(result) // Output: Resolved: value
Hooking Into Lifecycle
const pipeline = Pipeline.create<number>()
.on('onProcessingPipe', ({ passable }) => console.log('Processing', passable))
.on('onPipeProcessed', ({ passable }) => console.log('Processed', passable))
.send(3)
.through((v, next) => next(v + 2))
.sync()
const result = pipeline.thenReturn()
console.log(result) // Output: 5
Factory and Class-Based Pipes
const factoryPipe = () => (v, next) => next(v + 2)
class CustomPipe {
handle(v, next) {
return next(v * 3)
}
}
const result = Pipeline.create<number>()
.send(1)
.through(
{ module: CustomPipe, isClass: true },
{ module: factoryPipe, isFactory: true }
)
.sync()
.thenReturn()
console.log(result) // Output: 9
Using .via()
to Customize Method Name
class Pipe {
transform(value, next) {
return next(value + '!')
}
}
const result = Pipeline.create<string>()
.send('Wow')
.through({ module: Pipe, isClass: true })
.via('transform')
.sync()
.thenReturn()
console.log(result) // Output: Wow!
Priority-based Execution
const p1 = { module: (v, next) => next(v + 1), priority: 10 }
const p2 = { module: (v, next) => next(v * 2), priority: 20 }
const result = Pipeline.create<number>()
.send(1)
.through(p1, p2)
.sync()
.thenReturn()
console.log(result) // Output: 4 → (1 + 1) * 2
API
All methods are chainable:
.send(passable)
.through(...pipes)
.pipe(...pipes)
.sync(true|false)
.via(methodName)
.on(hookName, listener)
.then(fn)
.thenReturn()
Pipes can be:
Function
:(value, next) => next(...)
Factory
:() => (value, next) => next(...)
Class
:new MyPipe().handle(...)
Summary
The Pipeline
class provides a powerful and flexible way to process values through a series of steps, allowing for both synchronous and asynchronous operations. It supports various types of pipes, including functions, factories, and classes, and offers lifecycle hooks for custom behavior during processing.
Learn More
This package is part of the Stone.js ecosystem, a modern JavaScript framework built around the Continuum Architecture.
Explore the full documentation: https://stonejs.dev
API documentation
Contributing
Credits
Inspired by Laravel's Pipeline