Skip to content

tarruda/s-pipe

Repository files navigation

s-pipe

Functional streams, with a lisp-inspired chaining syntax

Node.js:

Build Status

Browsers:

Selenium Test Status

Installation

npm install --save s-pipe

Usage:

Array pipeline

var spipe = require('s-pipe');
var filter = require('s-pipe/lib/filter');
var map = require('s-pipe/lib/map');
var reduce = require('s-pipe/lib/reduce');

spipe([1,2,3,4,5])
     (filter, function(n) { return n > 3; })
     (map, function(n) { return n * n; })
     (reduce, function(result, n) { return result + n; })
     (); // returns [41]

Range pipeline(notice the range is evaluated lazily)

spipe(1, 1000000000)
     (map, function(n) { return {square: n * n, number: n}; })
     (find, function(obj) { return obj.square >= 81; })
     (map, function(n) { return n.number; })
     (); // [9]

Node.js streams, print comments in python script:

var fs = require('fs');
var spipe = require('s-pipe');
var filter = require('s-pipe/lib/filter');
var map = require('s-pipe/lib/map');
var split = require('s-pipe/lib/split');

spipe(fs.createReadStream('script.py'))
     (split)
     (filter, function(line) { return /#/.test(line); })
     (map, function(line) { return /#(.*)/.exec(line)[1] + '\n'; })
     ().pipe(process.stdout)

The main function in library can be used with node.js streams, arrays, strings, numbers(as ranges).

The chain style is inspired by lisp(@mlanza came up with the API idea) and ends with a call that doesn't receive a function as first argument. Classic underscore chaining is also supported, the above example may be rewritten as:

var fs = require('fs');
var _ = require('s-pipe/_');

_(fs.createReadStream('script.py'))
    .split()
    .filter(function(line) { return /#/.test(line); })
    .map(function(line) { return /#(.*)/.exec(line)[1] + '\n'; })
    .end().pipe(process.stdout)

Development

Clone, install dependencies and re-test whenever some file is modified:

git clone git://github.com/tarruda/s-pipe.git
cd s-pipe
npm install
grunt