<commit_before># μflux

**uflux** - Another implementation for the Flux architecture for React apps that pushes minimalism far.

* Store works with immutable objects
* Unidirectional flow

But also:

* Reduced verbosity. no action constants, no action methods. To fire a method, just emit a signal from the disptacher.

See [API.md](API.md) for full API documentation.

[![Status](https://travis-ci.org/rstacruz/uflux.svg?branch=master)](https://travis-ci.org/rstacruz/uflux "See test builds")

## Usage

```js
import { Dispatcher, Store, connectToStores } from 'uflux'
```

Your application will be composed of:

* One and only one Dispatcher singleton.
* Many stores (singletons), each listening to the one Dispatcher.
* Many React components, with some listening to changes to one or more stores.

### Dispatcher

A disptacher is simply an [EventEmitter].

```js
const App = new Dispatcher()

App.on('eventname', function () { ... })
App.emit('eventname')
App.emit('eventname', arg1, arg2)
```

[EventEmitter]: http://devdocs.io/iojs/events#events_class_events_eventemitter

### Store

A store is an object that keeps a state and listens to dispatcher events.
Create a new store using `new Store(dispatcher, initialState, handlers)`.

It listens to events from the dispatcher and responds by updating the store's state.

Each handler is a pure function that takes in the `state` and returns the new
state—no mutation should be done here.

```js
const ListStore = new Store(App, {
  items: []
}, {
  'list:add': function (state, item) {
    return {
      ...state,
      items: state.items.concat([ item ])
    }
  }
})

App.emit('list:add', '2')
ListStore.getState() /* { items: [2] } */
```

### Actions

To fire an action, just emit directly on your main dispatcher. No need for action methods.

```js
App.emit('list:add')
```

### React

You can connect a react Component to a store using `connectToStores()`. The
state of the store will be available as properties (`this.props`).

```js
const ListView = React.createClass({
  statics: {
    getStores () {
      return [ ListStore ]
    },
 
    getPropsFromStores() {
      return ListStore.getState()
    }
  },
  render () {
    return <div>hi, {this.props.name}</div>
  }

})

ListView = connectToStores(ListView)
```

## Chaining events

You can emit events inside handlers. They will be fired after committing the new state to the store.

```js
const ListStore = new Store(App, {
  items: []
}, {
  'list:add': function (state, item) {
    if (state.locked) {
      const err = new Error('List is locked')
      App.emit('list:error', err)
      return { ...state, error: err }
    }
  }
})

App.on('list:error', function (err) {
  console.log(err.message) //=> "List is locked"
  console.log(ListStore.getState().error.message) //=> "List is locked"
})
```

## API

See [API.md](API.md) for full API documentation.

Unresolved API issues:

 * testing stores?
 * atomicity?
 * components listening to dispatch events?<commit_msg>Document .dup()<commit_after># μflux

**uflux** - Another implementation for the Flux architecture for React apps that pushes minimalism far.

* Store works with immutable objects
* Unidirectional flow

But also:

* Reduced verbosity. no action constants, no action methods. To fire a method, just emit a signal from the disptacher.

See [API.md](API.md) for full API documentation.

[![Status](https://travis-ci.org/rstacruz/uflux.svg?branch=master)](https://travis-ci.org/rstacruz/uflux "See test builds")

## Usage

```js
import { Dispatcher, Store, connectToStores } from 'uflux'
```

Your application will be composed of:

* One and only one Dispatcher singleton.
* Many stores (singletons), each listening to the one Dispatcher.
* Many React components, with some listening to changes to one or more stores.

### Dispatcher

A disptacher is simply an [EventEmitter].

```js
const App = new Dispatcher()

App.on('eventname', function () { ... })
App.emit('eventname')
App.emit('eventname', arg1, arg2)
```

[EventEmitter]: http://devdocs.io/iojs/events#events_class_events_eventemitter

### Store

A store is an object that keeps a state and listens to dispatcher events.
Create a new store using `new Store(dispatcher, initialState, handlers)`.

It listens to events from the dispatcher and responds by updating the store's state.

Each handler is a pure function that takes in the `state` and returns the new
state—no mutation should be done here.

```js
const ListStore = new Store(App, {
  items: []
}, {
  'list:add': function (state, item) {
    return {
      ...state,
      items: state.items.concat([ item ])
    }
  }
})

App.emit('list:add', '2')
ListStore.getState() /* { items: [2] } */
```

### Actions

To fire an action, just emit directly on your main dispatcher. No need for action methods.

```js
App.emit('list:add')
```

### React

You can connect a react Component to a store using `connectToStores()`. The
state of the store will be available as properties (`this.props`).

```js
const ListView = React.createClass({
  statics: {
    getStores () {
      return [ ListStore ]
    },
 
    getPropsFromStores() {
      return ListStore.getState()
    }
  },
  render () {
    return <div>hi, {this.props.name}</div>
  }

})

ListView = connectToStores(ListView)
```

### Chaining events

You can emit events inside handlers. They will be fired after committing the new state to the store.

```js
const ListStore = new Store(App, {
  items: []
}, {
  'list:add': function (state, item) {
    if (state.locked) {
      const err = new Error('List is locked')
      App.emit('list:error', err)
      return { ...state, error: err }
    }
  }
})

App.on('list:error', function (err) {
  console.log(err.message) //=> "List is locked"
  console.log(ListStore.getState().error.message) //=> "List is locked"
})
```

### Testing stores

Create unit tests for stores by duplicating it and assigning it to a new dispatcher via `.dup()`.

```js
const ListStore = new Store(...)

const App = new Dispatcher()
const TestListStore = ListStore.dup(App)

App.emit('list:clear')
// ...will only be received by TestListStore, not ListStore.
```

## API

See [API.md](API.md) for full API documentation.

Unresolved API issues:

 * testing stores?
 * atomicity?
 * components listening to dispatch events?
{'fraction_non_alphanumeric': 0.13142041851616995, 'fraction_numerical': 0.0012682308180088776, 'mean_word_length': 3.7687074829931975, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '692858', 'n_tokens_mistral': 2045, 'n_tokens_neox': 1942, 'n_words': 694}