A library for Communicating Sequential Processes in Node.js, built on top of async/await
.
This library requires async/await
support in your Node.js runtime, so ideally node>=7.4
.
$ npm install --save @paybase/csp
or
$ yarn add @paybase/csp
Below is a trivial example of usage, that plays on the standard ping-pong example.
const { channel, put, take } = require('@paybase/csp');
const timeout = ms => new Promise(resolve => setTimeout(resolve, ms));
const wiff = channel();
const waff = channel();
const createBall = () => ({ hits: 0, status: '' });
const createBat = async (inbound, outbound) => {
while (true) {
const ball = await take(inbound); // wait for an incoming ball
ball.hits++;
ball.status = ball.status === 'wiff!' ? 'waff!' : 'wiff!';
console.log(`🎾 Ball hit ${ball.hits} time(s), ${ball.status}`);
await timeout(500); // assume it's going to take a bit to hit the ball
await put(outbound, ball); // smash the ball back
}
};
createBat(waff, wiff); // create a bat that will wiff waffs
createBat(wiff, waff); // create a bat that will waff wiffs
put(waff, createBall());
This library exposes 5 functions and one factory.
This factory method constructs a new channel
and returns it. A channel contains no publicly accessible properties, but contains information about interactions with the channel
.
const chan = channel();
The put
function requires the channel
on which to put the supplied message
. The put
method returns a Promise
which can be optionally awaited and will resolve when something is ready to take the message
from the channel
.
const chan = channel();
put(chan, 42);
// ...or...
await put(chan, 42);
The take
function requires the channel
to take from. The take
method returns a Promise
which should always be awaited and will resolve with a message, when a message is available.
const chan = channel();
put(chan, 42);
const msg = await take(chan); // will receive 42
The alts
function will race taking values from multiple channels
.
const chan1 = channel();
const chan2 = channel();
put(chan2, 42);
const msg = await alts(chan1, chan2); // will receive 42
The select
function will race taking values from multiple channels
, similar to alts
, but will also return the key of the channel that was selected.
const chan1 = channel();
const chan2 = channel();
put(chan2, 42);
const channels = [chan1, chan2];
const result = await select(channels); // will receive [1, 42]
Works with Map
and Set
as well as with plain-old javascript arrays and objects.
The drain
function requires a channel
which it will drain all messages from until empty, returning an array of messages.
const chan = channel();
put(chan, 42);
put(chan, 41);
put(chan, 40);
put(chan, 39);
const msgs = await drain(chan); // will receive [ 42, 41, 40, 39 ]
Contributions are welcomed and appreciated!
- Fork this repository.
- Make your changes, documenting your new code with comments.
- Submit a pull request with a sane commit message.
Feel free to get in touch if you have any questions.
Please see the LICENSE
file for more information.