Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/phadej/menrva

Ambitious data-flow library
https://github.com/phadej/menrva

Last synced: 10 days ago
JSON representation

Ambitious data-flow library

Awesome Lists containing this project

README

        

# menrva

[![Build Status](https://secure.travis-ci.org/phadej/menrva.svg?branch=master)](http://travis-ci.org/phadej/menrva)
[![NPM version](http://img.shields.io/npm/v/menrva.svg)](https://www.npmjs.org/package/menrva)
[![Dependency Status](https://david-dm.org/phadej/menrva.svg)](https://david-dm.org/phadej/menrva)
[![devDependency Status](https://david-dm.org/phadej/menrva/dev-status.svg)](https://david-dm.org/phadej/menrva#info=devDependencies)
[![Coverage Status](https://img.shields.io/coveralls/phadej/menrva.svg)](https://coveralls.io/r/phadej/menrva?branch=master)
[![Code Climate](http://img.shields.io/codeclimate/github/phadej/menrva.svg)](https://codeclimate.com/github/phadej/menrva)

Ambitious data-flow library.

## Getting Started
Install the module with: `npm install menrva`

```js
var menrva = require('menrva');
menrva.some('awe'); // some, as in awesome?
```

## API

### Signal

The core type of menrva. `Signal` is abstract class, and cannot be created explicitly.

Similar concepts are: *Behaviours* in FRP, *Properties* in bacon.js.

You can add methods to `Signal`'s prototype. They will be available on all signals.

#### signal.map

> map (@ : Signal a, f : a -> b, eq = egal : b -> b -> boolean) : Signal b

#### signal.onValue

> onValue (@ : Signal a, callback : a -> void) -> Unsubscriber

Add value callback. `callback` is immediately executed with the current value of signal.
After than `callback` will be called, each time signal's value changes.

The return value is a function, which will remove the callback if executed.

#### signal.value()

> value (@ : Signal a): Signal a

Returns the current value of signal.

### Source

A signal which value you can set.

Similar concepts are: *Bacon.Model* in bacon.js, *BehaviourSubject* in Rx.

#### source

> source (initialValue : a, eq = egal : a -> a -> boolean) : Source a

#### source.set

> set (@ : Source a, tx : Transaction, value : a) : void

#### source.modify

> modify (@ : Source a, tx : Transaction, f : a -> a) : void

Mofify source value. `f` will be called with current value of signal inside the transaction.

### Signal combinators

#### combine

> combine (Signal a..., f : a... -> b) : Signal b

Applicative n-ary lift. Lift pure function to operate on signals:
```js
var $sum = menrva.combine($a, $b, function (a, b) {
return a + b;
});
```

### Transaction

One gathers atomic updates into single transaction (to avoid glitches).

```js
var tx = menrva.transaction();
sourceA.set(tx, 42);
sourceB.modify(tx, function (x) { return x + x; });
tx.commit(); // not necessary, transactions are auto-commited
```

There are also optional syntaxes for simple transactions:
```js
menrva.transaction()
.set(sourceA, 42)
.modify(sourceB, function (x) { return x + x; })
.commit();
```
or even
```js
menrva.transaction([sourceA, 42, sourceB, function(x) { return x + x; }]).commit();
```

#### transaction

> transaction (facts) : Transaction

Create transaction.

Shorthand syntax:

> transaction ([sourceA, valueA, sourceB, valueB ...]) : Transaction

If `value` is function, `source.modify(tx, value)` is called; otherwise `source.set(tx, value)`.

#### transaction.commit

Commit the transaction, forcing synchronous data propagation.

#### transaction.rollback

Rollback the transaction. Maybe be called multiple times (consecutives calls are no-op).

*Note: for now `rollback` only resets the pending actions in transactions. Transaction is still valid, and more actions can be added*

### Lens

Lenses are composable functional references.
They allow you to *access* and *modify* data potentially very deep within a structure!

#### source.zoom

> zoom (@ : Source a, path : Path a b, eq = egal : b -> b -> boolean) : Source b

Zoom (or focus) into part specified by `path` of the original signal.
One can `set` and `modify` zoomed signals, they act as sources.

```js
var quux = source.zoom("foo.bar.quux");
```

### Convenience methods

#### signal.log

> signal.log (@ : Signal a, args...) : Unsubscriber

Essentially `signal.onValue(console.log.bind(console, args...))

#### signal.onSpread

> signal.onSpread (@ : Signal [a, b...], callback : a -> b ... -> void) : Unsubscriber

`onValue` with signal's tuple arguments spread.

#### tuple

> tuple (x : Signal a, y : Signal b...) : Signal [a, b...]

Combine signals into tuple.

#### sequence

> sequence [Signal a, Signal b, ..] : Signal [a, b...]

In promise libraries this might be called `all`.

#### record

> record {k: Signal a, l: Signal b...} : Signal {k: a, l: b...}

Like `sequence` but for records i.e. objects.

### Equalities

#### egal

> egal (a, b) : boolean

Identity check. `Object.is`. http://wiki.ecmascript.org/doku.php?id=harmony:egal

### Option

Also known as `Maybe`.

#### option.equals

> equals (@ : option a, other : *, eq = eqal : a -> a -> boolean) : boolean

Equality check.

#### option.map

> map (@ : option a, f : a -> b) : option b

#### option.elim

> elim (@ : option a, x : b, f : a -> b) : b

#### option.orElse

> orElse (@ : option a, x : a) : a

## Contributing

In lieu of a formal styleguide, take care to maintain the existing coding style.

Add tests for any new or changed functionality. 100% coverage isn't hard. Semantic coverage is important too though.

Note: `README.md` is autogenerated file.

## Release History

- **0.0.7** `sequence` and `record`
- **0.0.6** Convenience methods
- **0.0.5** Lens
- **0.0.4** Internal improvements
- **0.0.3** Slight changes in API
- **0.0.2** Basic data-flow functionality
- **0.0.1** Name reservation

## License

Copyright (c) 2014 Oleg Grenrus.
Licensed under the MIT license.