![Scramjet Logo](https://signicode.com/scramjet-logo-light.svg)
Version 4
![Known Vulnerabilities](https://snyk.io/test/github/signicode/scramjet/badge.svg)
What does it do?
Scramjet is a fast, simple, multi-threaded functional stream programming framework written on top of node.js object
streams. It exposes a standards inspired javascript API and written fully in native ES6. Thanks to it some built in
optimizations scramjet is much faster and much much simpler than similar frameworks when using asynchronous operations.
It is built upon the logic behind three well known javascript array operations - namingly map, filter and reduce. This
means that if you've ever performed operations on an Array in JavaScript - you already know Scramjet like the back of
your hand.
The main advantage of scramjet is running asynchronous operations on your data streams. First of all it allows you to
perform the transformations both synchronously and asynchronously by using the same API - so now you can "map" your
stream from whatever source and call any number of API's consecutively.
The benchmarks are published in the scramjet-benchmark repo.
Example
How about a CSV parser of all the parkings in the city of Wrocław from http://www.wroclaw.pl/open-data/...
const request = require("request");
const StringStream = require("scramjet").StringStream;
request.get("http://www.wroclaw.pl/open-data/opendata/its/parkingi/parkingi.csv")
.pipe(new StringStream())
.CSVParse()
.each(console.log)
Usage
Scramjet uses functional programming to run transformations on your data streams in a fashion very similar to the well
known event-stream node module. Most transformations are done by passing a transform function. You can write your
function in three ways:
- Synchronous
Example: a simple stream transform that outputs a stream of objects of the same id property and the length of the value string.
datastream.map(
(item) => ({id: item.id, length: item.value.length})
)
- Asynchronous using ES2015 async await
Example: A simple stream that uses Fetch API to get all the contents of all entries in the stream
datastream.map(
async (item) => fetch(item)
)
- Asynchronous using Promises
Example: A simple stream that fetches an url mentioned in the incoming object
datastream.map(
(item) => new Promise((resolve, reject) => {
request(item.url, (err, res, data) => {
if (err)
reject(err);
else
resolve(data);
});
})
)
The actual logic of this transform function is as if you passed your function to the then
method of a Promise
resolved with the data from the input stream.
- Streams with multi-Threading
To distribute your code among the processor cores, just use the method distribute
:
datastream.distribute(
(item) => item.value % 4
(stream) => {
}
)
API Docs
Here's the list of the exposed classes and methods, please review the specific documentation for details:
Note that:
- Most of the methods take a callback argument that operates on the stream items.
- The callback, unless it's stated otherwise, will receive an argument with the next chunk.
- If you want to perform your operations asynchronously, return a Promise, otherwise just return the right value.
Browserifying
Scramjet works in the browser too, there's a nice, self-contained sample in here, just run it:
git clone https://github.com/signicode/scramjet.git
cd scramjet
npm install .
cd samples/browser
npm start
If you need your scramjet version for the browser, grab browserify and just run:
browserify lib/index -standalone scramjet -o /path/to/your/browserified-scramjet.js
With this you can run your transformations in the browser, use websockets to send them back and forth. If you do and fail for some reason, please remember to be issuing those issues - as no one person can test all the use cases and I am but one person.
License and contributions
As of version 2.0 Scramjet is MIT Licensed.
Help wanted
The project need's your help! There's lots of work to do - transforming and muxing, joining and splitting, browserifying, modularizing, documenting and issuing those issues.
If you want to help and be part of the Scramjet team, please reach out to me, signicode on Github or email me: scramjet@signicode.com.