# Luxi

Luxi is JS framework based on Flux architecture.
Simple, elegant, and convenient with **Types**.

## Example

```js
/**
 * Action
 */
import {Action, ActionTypeFactory, dispatch} from 'luxi';

const actionTypeFactory = new ActionTypeFactory('User');

const UserActionType = {
  UpdateName: actionTypeFactory.create<string>('UpdateName'),
  RestoreName: actionTypeFactory.create<Promise<string>>('RestoreName'),
};

class UserAction {
  @dispatch
  updateName(nextName: string): Action<UserActionType.UpdateName> {
    return { type: UserActionType.UpdateName, payload: nextName };
  }

  @dispatch
  restoreName(): Action<UserActionType.RestoreName> {
    const restorePromise = this._restoreUserName();
    return { type: UserActionType.RestoreName, payload: restorePromise };
  }

  _restoreUserName(): Promise<string> {
    return Cache.get('user.name');
  }
}

/**
 * Reducer
 */
import {Reducer, reduce} from 'luxi';

interface UserState {
  name: string;
}

class UserStateReducer extends Reducer<UserState> {
  state = { name: '(No name)' };

  @reduce.on(UserActionType.UpdateName)
  @reduce.onResolve(UserActionType.RestoreName)
  updateName(nextName: string): UserState {
    return { name: nextName };
  }
}

/**
 * Store
 */
import {Store} from 'luxi';

interface DataStoreState {
  user: UserState;
}

const userReducer = new UserReducer;

const DataStore = Store.fromReducers<DataStoreState>((delegateTo) => ({
  user: delegateTo(userReducer),
}));

/**
 * Use with React
 */
import {connect} from 'luxi/react';

@connect(DataStore, (store) => ({store}))
class Application extends React.Component<{ store: DataStoreState }> {
  userAction = new UserAction;

  componentWillMount() {
    this.userAction.restoreName();
  }

  handleChange = (e: any) => {
    this.userAction.updateName(e.target.value);
  };

  render() {
    const {store} = this.props;
    return (
      <div>
        Hi!
        <br />
        Your name is <input value={store.user.name} onChange={this.handleChange} />.
      </div>
    );
  }
}
```
