redarx 0.6.0

  • Installing
  • Versions
  • 37


Experimental Dart State Management humbly inspired by ngrx <= Redux <= Elm, André Stalz work & Parsley.




Requests to Commands Mapping via CommanderConfig

final requestMap = new Map<RequestType, CommandBuilder>()
  ..[RequestType.ADD_TODO] = AddTodoCommand.constructor()
  ..[RequestType.ARCHIVE] = ArchiveCommand.constructor()
  ..[RequestType.UPDATE_TODO] = UpdateTodoCommand.constructor()
  ..[RequestType.CLEAR_ARCHIVES] = ClearArchivesCommand.constructor()
  ..[RequestType.TOGGLE_SHOW_COMPLETED] = ToggleShowArchivesCommand.constructor();


final cfg = new CommanderConfig<RequestType>(requestMap);
final store = new Store<TodoModel>(() => new TodoModel.empty());
final dispatcher = new Dispatcher();

final cmder = new Commander(cfg, store, dispatcher.onRequest);

var app = new AppComponent(querySelector('#app') )
..model$ =$
..dispatch = dispatcher.dispatch

Dispatching requests

RequestType are defined via an enum

enum RequestType {

Requests are defined by a type and an optional payload.

dispatch( new Request(
    RequestType.ADD_TODO, withData: new Todo(fldTodo.value))


Requests are mapped to commands by Commander and passed to the store.update()

exec(Request a) {

The commands define a public exec method which receive the currentState and return the new one.

class AddTodoCommand extends Command<TodoModel> {
  Todo todo;


  TodoModel exec(TodoModel model) => model..items.add(todo);

  static CommandBuilder constructor() {
    return (Todo todo) => new AddTodoCommand(todo);

Async Commands

Async commands allows async evaluation of the new state


Basically a (stream<Command<Model>>) => stream<Model> transformer

Receives new commands, and executes those with the current state/Model

Use a CommandStreamReducer<S extends Command, T extends AbstractModel> to stream reduced states

The store manage a stream of immutable states instances.

Reversible Store

The reversible store keep a history list of all executed commands and allow cancelling.

it provide an access to currentState by reducing all the commands history.

State listening

The store exposes a stream of immutable states

Stream<TodoModel> _model$;

set model$(Stream<TodoModel> value) {
_model$ = value;
modelSub = _model$.listen((TodoModel model) {
      list.todos = model.todos;
      footer.numCompleted = model.numCompleted;
      footer.numRemaining = model.numRemaining;
      footer.showCompleted = model.showCompleted;

Experimental multi-channel dispatcher (0.6.0)

Async commands are maybe not the best way to connect a Firebase data-source.

The redarx-ng-firebase example shows a way to dispatch firebase queries via a new dispatcher method : query.

Queries are dispatched to a Firebase service, which update the base. The service handles firebase.database child and values events and dispatch update request via the dispatch() method.

Event$ » Request$ » Command$ » state$

The Application State is managed in a Store<T extends AbstractModel>.

State is updated by commands, and the store keep a list of executed commands.

State is evaluated by commands updates,

In reversible-store, cancellation is allowed by simply remove the last command from "history".

A Commander listen to a stream of Requests dispatched by a Dispatcher injected in the application components | controllers | PM | VM

Each Request is defined by an RequestType enum, and can contains data.

Requests are "converted" to commands by the Commander, based on the definition

  • the dispatcher.dispatch function is injected in view || controller || PresentationModel || ViewModel

  • Request are categorized by types, types are defined in RequestType enum

  • the dispatcher stream Requests

  • the dispatcher requestStream is injected in Commander, the commander listen to it, transforms Request to Command and transfer to the store.apply( command ) method

  • each Request is tied to a command via a CommanderConfig which is injected in Commander

// instanciate commands form requests 
  • Commander need a CommanderConfig containing a Map<RequestType,CommandBuilder>
  • the store then execute commandHistory and push the new model value to a model stream


  • fix the generic/command ( <T extends Model> mess)
  • implements a Scan stream transformer » to allow only run the last commands & emit the last reduced state
  • async commands
  • test Angular integration
  • test with Firebase
  • use values types cf built_value
  • time travel / history UI
  • typed Request ? BookRequest, UserRequest ...?
  • tests
  • external config file ?
  • ...


  • use a EnumClass implementation rather than dart enum type
  • dispatcher : use a streamController.add rather than dispatch method ?
  • multiple store ? dispatcher ? commander ?
  • each component could set an Request stream and the commander could maybe listen to it


  • study Dart : streams, generics, annotations, asynchrony...
  • study Redux & ngrx, play with reducers & Request/Commands mapping...
  • and more studies, more experiments, more play...
  • define a solid architecture for my coming projects



  • prototypal "multi-channels" dispatcher (temporary):

    • query() => QUERIE$ => Prototypal FirebaseService integration
    • dispatch() => REQUEST$ => Commander
  • strong mode with no implicit casts or dynamic


  • immutable model
  • refactoring
  • Angular Dart compatible


  • Async Commands


  • CommandConfig : overload operator[] » allow accessing RequestType associated Command via config[RequestType]
  • generated doc


  • remove Dispatcher injection from AppRoot & Commander
  • dart doc generation


  • Initial version :
    • synchronous commands mapped to Action defined by ActionTypeEnum,
    • ActionType enum definition,
    • basic Action Dispatcher,
    • Commander : listen to dispatched action and
    • Store with Commands reducer
    • basic mapping config
    • basic undo

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:

  redarx: "^0.6.0"

2. Install it

You can install packages from the command line:

with pub:

$ pub get

with Flutter:

$ flutter packages get

Alternatively, your editor might support pub get or flutter packages get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:

      import 'package:redarx/redarx.dart';
Version Uploaded Documentation Archive
0.6.0 Dec 21, 2016 Go to the documentation of redarx 0.6.0 Download redarx 0.6.0 archive
0.5.0+1 Dec 20, 2016 Go to the documentation of redarx 0.5.0+1 Download redarx 0.5.0+1 archive
0.5.0 Dec 20, 2016 Go to the documentation of redarx 0.5.0 Download redarx 0.5.0 archive


We analyzed this package on Jun 19, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.0.0-dev.63.0
  • pana: 0.11.3


Describes how popular the package is relative to other packages. [more]
0 / 100
Code health derived from static analysis. [more]
91 / 100
Reflects how tidy and up-to-date the package is. [more]
50 / 100
Overall score:
Weighted score of the above. [more]
Learn more about scoring.


Detected platforms: Flutter, web, other

No platform restriction found in primary library package:redarx/redarx.dart.


  • Fix analysis and formatting issues.

    Analysis or formatting checks reported 1 error 8 hints.

    Strong-mode analysis of lib/src/commands-reducer-transformer.dart failed with the following error:

    line: 9 col: 7
    Missing concrete implementation of 'StreamTransformer.cast'.

    Run dartfmt to format lib/redarx.dart.

    Similar analysis of the following files failed:

    • lib/src/commander-config.dart (hint)
    • lib/src/commands.dart (hint)
    • lib/src/dispatcher.dart (hint)
    • lib/src/model.dart (hint)
    • lib/src/request.dart (hint)
    • lib/src/reversible-store.dart (hint)
    • lib/src/store.dart (hint)
  • Package is getting outdated.

    The package was released 77 weeks ago.

  • Package is pre-v1 release.

    While there is nothing inherently wrong with versions of 0.*.*, it usually means that the author is still experimenting with the general direction API.

  • Maintain an example.

    Create a short demo in the example/ directory to show how to use this package. Common file name patterns include: main.dart, example.dart or you could also use redarx.dart.

  • Use analysis_options.yaml.

    Rename old .analysis_options file to analysis_options.yaml.


Package Constraint Resolved Available
Direct dependencies
Dart SDK >=1.0.0 <2.0.0
meta >=1.0.4 <2.0.0 1.1.5
Dev dependencies
test >=0.12.0 <0.13.0