rafa
Version:
Rafa.js is a Javascript framework for building concurrent applications.
62 lines (47 loc) • 2.14 kB
Markdown
The Stream is our protagonist. It is a single node in a N-Ary tree of other
stream nodes. Messages pass through streams and their values can be handled,
transformed, or filtered. A stream handles three types of messages: a value,
an error, and a done message which indicates that the source that produced
values is done sending new values. In many cases the done message also contains
the last value emitted by a source.
Stream nodes can be merged with nodes from other trees and a single stream
node's messages can be grouped, creating a new tree for each group. In other
words, we can fan-in, fan-out, or chain multiple stream nodes.
Stream handlers, which perform filtering or transforming of messages passing
through the stream, can be concurrent (return a promise). In this case, the
stream will wait for the promise to complete before allowing new messages
to be processed by the stream. Together with Channels, the stream can
implement message processing with backpressure.
<aside>
```js
// create a new stream
const stream = Rafa.stream();
// bind to DOM buttons
const button = document.querySelector("#saveButton");
button.addEventListener("click", stream.listener());
// onclick: post form to server; backpressure will prevent two clicks from
// creating multiple post requests; will accept clicks again after response
// from server.
stream = stream.map(v => {
const future = Rafa.future();
const form = name => encodeURIComponent(document.querySelector("#"+name).value);
const req = new XMLHttpRequest();
req.onreadystatechange = () => {
if (req.readyState === 4) {
if (req.status === 200) future.resolve(req.responseText);
else future.reject(req);
}
};
req.open("POST", URL);
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
req.send("name=" + form("name") + "&age=" + form("age"));
return future.promise;
});
// this will only execute when the RPC call is successful
stream.each(response => {
document.querySelector("#result").textContent = response;
});
// display alert if something goes wrong
stream.error(req => alert("Oops"));
```
</aside>