Package Exports
- js-csp
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (js-csp) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
js-csp
Communicating sequential processes for Javascript (like Clojurescript core.async, or Go).
WARNING: This is currently alpha software.
Examples
var csp = require("js-csp");Pingpong (ported from Go).
function* player(name, table) {
  while (true) {
    var ball = yield csp.take(table);
    if (ball === null) {
      console.log(name + ": table's gone");
      return;
    }
    ball.hits += 1;
    console.log(name + " " + ball.hits);
    yield csp.wait(100);
    yield csp.put(table, ball);
  }
}
csp.go(function* () {
  var table = csp.chan();
  csp.go(player, ["ping", table]);
  csp.go(player, ["pong", table]);
  yield csp.put(table, {hits: 0});
  yield csp.wait(1000);
  table.close();
});Supported runtimes
js-csp requires ES6 generators
Firefox >= 27
Earlier versions of Firefox either had ES6 generators turned off, or supported old style generators.
Node.JS >= 0.11.6
Run with --harmony or --harmony-generators flag.
Check support using
node --v8-options | grep harmonyChrome with experimental flag turned on
Look for "Enable Experimental JavaScript" at chrome://flags.
Other
Use one of the js-to-js compilers:
Or, if you use Python's Twisted: https://github.com/ubolonton/twisted-csp
Or, if you want a better language: https://github.com/clojure/core.async
API
This is an almost exact clone of Clojurescript's core.async. The most significant difference is that the IOC logic is encapsulated using generators (yield) instead of macros.
Channels
These are not constructor functions. Don't use new.
chan([bufferOrNumber])
Creates a channel.
- If a number is passed, the channel is backed by a fixed buffer of that size (bounded asynchronization).
- If a buffer is passed, the channel is backed by that buffer (bounded asynchronization).
- If no argument is passed, the channel is unbuffered (synchronization).
buffers.fixed(n)
Creates a fixed buffer of size n. When full, puts will block. TODO: When to use (e.g. backpressure)
buffers.dropping(n)
Creates a dropping buffer of size n. When full, puts will not block, but the value is discarded. TODO: When to use (stop responding to fast stuff)
buffers.sliding(n)
Creates a sliding buffer of size n. When full, puts will not block, but the oldest value is discarded. TODO: When to use (uninteresting stale values)
Goroutines
go(f* [, args [, returnChannel]])
Spawns a "goroutine" from the supplied generator function, and arguments.
If returnChannel is true, returns a channel with that will receive the value returned by the goroutine. Returns null if returnChannel is omitted.
Note: Do not return null from the channel.
// Spawn a goroutine, and immediately return a channel
var ch = csp.go(function*(x) {
  yield csp.wait(1000);
  return x;
}, [42], true);
// Will "block" for 1 second then print 42;
console.log((yield csp.take(chan)));spawn(generator [, returnChannel])
Similar to go, but takes a generator instead of creating one.
// Spawn a goroutine, and immediately return a channel
function* id(x) {
  yield csp.wait(1000);
  return x;
}
var ch = csp.spawn(id(42), true);
// Will "block" for 1 second then print 42;
console.log((yield csp.take(chan)));Channel operations
These operations (except for close) must be prefixed with yield, and must be used inside goroutines, not normal functions. This makes sense, since these are (potentially) "blocking" operations.
yield put(ch, value)
Puts a value into the channel. "Returns" true unless channel is already closed.
yield take(ch)
Takes a value from the channel. "Returns" null if channel is already closed.
yield alts(operations [, options])
Completes at most one of the channel operations. Each operation is either a channel to be taken from, or a 2-element array of the form [channel-to-put-into, value-to-put].
"Returns" an object with 2 properties: The channel of the succeeding operation, and the value returned by the corresponding put/take operation.
- If no operation is ready:- If options.defaultis specified, "returns"{value: options.default, channel: csp.DEFAULT}.
- Otherwise block until the an operation completes.
 
- If 
- If more than one operation is ready:- If options.priorityistrue, tries the operations in order.
- Otherwise makes a non-deterministic choice.
 
- If 
yield wait(msecs)
"Blocks" the current goroutine for msecs milliseconds.
ch.close()
Close a channel.
- Pending and future takes "return" the buffered values, then null.
- Pending and future puts "return" false.
Other types of endpoint
TODO
Multiplexers
Mixers
Publishers
Composition operations
TODO
Install
    npm install js-cspTODO
- Achieve feature parity with Clojurescript's core.async.
- Add More documentation and examples.
- Add browser builds and tests.
- Add conversion functions that "de-IOC" promises and callback-based APIs.
- Publish to bower.
Inspiration
- http://swannodette.github.io/2013/08/24/es6-generators-and-csp
- https://github.com/clojure/core.async
- https://github.com/olahol/node-csp
License
Distributed under Eclipese Public License.