built_redux 7.5.10

  • Readme
  • Changelog
  • Example
  • Installing
  • 44

built_redux #

Pub codecov.io


built_redux is a state management library written in dart that enforces immutability. built_redux is not only an implementation of redux, but also a framework for building middleware and reducers in a type safe manner.

Inspired by redux

Built using built_value

Framework bindings #

flutter

Examples #

Libraries #

Documentation #

7.5.10 #

  • add workiva_analysis_options
  • remove usage of new keyword in code and examples
  • bump various dependencies lower bounds

7.5.9 #

  • add type_annotate_public_apis lint ignore to generated files

7.5.8 #

  • rework generator to lift analyzer version constraint.
  • open analyzer range
  • generator now uses source parsing to resolve action generic types which allows any unresolved type to be used as an action payload.
  • generated actions classes now use type inference.
  • bump built_value lower bound to 6.1.4 since it is impossible for pub to resolve to anything lower due to the build dependency constraint.

7.5.7 #

open built value range restrict analyzer to less than 0.38.3, issue was introduced in 0.38.3 patch

7.5.6 #

add dart2js:noInline annotations

7.5.5 #

update analyzer dependency to allow '>=0.33.0 <0.39.0'

7.5.4 #

update analyzer dependency to allow '>=0.33.0 <0.37.0' fix type in built_redux_test_utils.dart

7.5.3 #

update analyzer dependency to allow '>=0.33.0 <0.36.0'

7.5.2 #

update analyzer dependency to allow ^0.33.0

7.5.1 #

update build dependencies

7.5.0 #

  • allow 4.x.x of built_collection
  • added combineReducerBuilder to NestedReducerBuilder
  • added a NestedMiddlewareBuilder

7.4.5 #

  • open sdk range to dart 2!
  • update built_value and source_gen dependencies
  • use SharedPartBuilder rather than PartBuilder in the generator

7.4.4-dev #

  • use typedef names in action generator

7.4.3-dev #

  • update dependency range on analyzer
  • update dependency range on test
  • fix broken test caused by dart 2's new asyc behavior

7.4.2 #

  • add lint ignores to generated files

7.4.1-dev #

  • open sourc-gen range
  • run tests on the dev compiler

7.4.1 #

  • fix cast issues around store changes in dart 2
  • open analyzer version range

7.4.0-dev #

  • add build.yaml and build.dart to comply with build_runner 0.7.x

With the dev tag you can consume the latest versions of built_value, build, and build_runner that are only compatable with dart 2.

In order to migrate:

  • remove your old build scripts
  • update your pubspec to include
  build_runner: ^0.7.9
  • add a build.yaml to the root of your repo that contains the following:
targets:
  $default:
    builders:
      built_value_generator|built_value:
        enabled: false
  • run pub run build_runner build.

The build script is only a temporary measure until https://github.com/dart-lang/source_gen/issues/319 is resolved.

7.4.0 #

  • add built_redux_test_utils library - exposes an expectDispatched function for expecting a given action gets dispatched asynchronously
  • add combine to MiddlewareBuilder class - lets you combine middleware builders
  • add toString to Action class
  • add example
  • add docs

7.3.3 #

  • add changelog
  • update readme to include link to todoMVC repo

7.3.2 #

  • open dependency range on the build package

7.3.1 #

  • open dependency range on the built_collection package

7.3.0 #

  • dispose is now awaitable

7.2.0 #

  • Added actionStream stream to the store api so one can listen to changes resulting from a specific action name.
  • Fixed issues called out my adding implicit-dynamic and implicit-cast rules.

7.1.0 #

7.0.0 #

  • Breaking changes:
    • A breaking change in behavior was made to action dispatchers. Before action dispatchers executed the middleware/reducers asynchronously, but they now execute synchronously.

For example you may have:

int getCount(store) {
  print(store.state.count); // prints 0
  store.actions.increment(1);
  print(store.state.count); // would print 1 if actions were sync, 0 if async
  return store.state.count; // would return 1 if actions were sync, 0 if async
}

Before this function would return 0 because the state update that occurs from actions.increment would be processed in a future task. Now this function will return 1 because the state update that occurs from actions.increment is processed in the current task

6.0.0 #

Removes the BuiltReducer interface and the generated BuiltReducer implementation in favor of building a reducer function and passing it to the store at instantiation.

  • Breaking changes:
    • Store now takes a reducer
    • Nested reducers need to be built with the NestedReducerBuilder and merged wth the main ReducerBuilder using ReducerBuilder.addNestedReducer
    • Models no longer implement BuiltReducer
      • Remove references to the reducer on your models
    • Renamed ActionDispatcher.syncWithStore to setDispatcher
    • Renamed SubStateChange to SubstateChange

Reasoning:

  • Decouples your models and reducers.
  • Requires less generated code.
  • Reducing requires less map look ups. Previously N map look ups were required where N was the number of BuiltReducers in your state tree. Now only 1 map look up is required per action dispatched.

Examples:

  • Example model change. Remove the generated BuiltReducer mixin and the reducer getter

Before:

  abstract class Counter extends Object
     with CounterReducer
     implements Built<Counter, CounterBuilder> {
   int get count;

   get reducer => _reducer;

   Counter._();
   factory BaseCounter() => new _$BaseCounter._(count: 1);
 }

After:

  abstract class Counter implements Built<Counter, CounterBuilder> {
   int get count;

   Counter._();
   factory BaseCounter() => new _$BaseCounter._(count: 1);
 }
  • Example nested reducer change. Change NestedCounter's reducer builder to a NestedReducerBuilder. Pass the NestedReducerBuilder mapper functions from the main state/builder to the nested state/builder.

Before


// Built Reducer
abstract class BaseCounter extends Object
    with BaseCounterReducer
    implements Built<BaseCounter, BaseCounterBuilder> {
  int get count;

  BuiltList<int> get indexOutOfRangeList;

  NestedCounter get nestedCounter;

  @override
  get reducer => _baseReducer;

  // Built value constructor
  BaseCounter._();
  factory BaseCounter() => new _$BaseCounter._(
        count: 1,
        nestedCounter: new NestedCounter(),
      );
}

final _baseReducer = (new ReducerBuilder<BaseCounter, BaseCounterBuilder>()
      ..add(BaseCounterActionsNames.increment, _baseIncrement)
      ..add(BaseCounterActionsNames.decrement, _baseDecrement))
    .build();

abstract class NestedCounter extends Object
    with NestedCounterReducer
    implements Built<NestedCounter, NestedCounterBuilder> {
  int get count;

  get reducer => _nestedReducer;

  // Built value constructor
  NestedCounter._();
  factory NestedCounter() => new _$NestedCounter._(count: 1);
}

final _nestedReducer =  (new ReducerBuilder<NestedCounter, NestedCounterBuilder>()
          ..add(NestedCounterActionsNames.increment, _nestedIncrement)
          ..add(NestedCounterActionsNames.decrement, _nestedDecrement))
        .build();

After

abstract class BaseCounter implements Built<BaseCounter, BaseCounterBuilder> {
  int get count;

  NestedCounter get nestedCounter;

  BaseCounter._();
  factory BaseCounter() => new _$BaseCounter._(
        count: 1,
        nestedCounter: new NestedCounter(),
      );
}

// the reducer passed to the store
final reducer = (new ReducerBuilder<BaseCounter, BaseCounterBuilder>()
      ..add(BaseCounterActionsNames.increment, _baseIncrement)
      ..add(BaseCounterActionsNames.decrement, _baseDecrement)
      ..combineNested(_nestedReducer))
    .build();

abstract class NestedCounter implements Built<NestedCounter, NestedCounterBuilder> {
  int get count;

  // Built value constructor
  NestedCounter._();
  factory NestedCounter() => new _$NestedCounter._(count: 1);
}

final _nestedReducer = new NestedReducerBuilder<BaseCounter, BaseCounterBuilder,
    NestedCounter, NestedCounterBuilder>(
  (state) => state.nestedCounter,
  (builder) => builder.nestedCounter,
)
  ..add(NestedCounterActionsNames.increment, _nestedIncrement)
  ..add(NestedCounterActionsNames.decrement, _nestedDecrement);

example/example.dart

library example;

import 'package:built_value/built_value.dart';
import 'package:built_redux/built_redux.dart';

part 'example.g.dart';

void main() {
// Create a redux store holding the state of your app.
// Its API contains three getters: stream, state, and actions.
  final store = Store<Counter, CounterBuilder, CounterActions>(
    reducerBuilder.build(), // build returns a reducer function
    Counter(),
    CounterActions(),
  );

  print(store.state.count); // 0
  store.actions.increment(1);
  print(store.state.count); // 1
  store.actions.increment(2);
  print(store.state.count); // 3
  store.actions.decrement(1);
  print(store.state.count); // 2
}

// This is a an implementation of ReduxActions. Actions are what middleware and ui
// components invoke a change to the redux store's state. By extending ReduxActions
// the built_redux generator will generate the required boilerplate to create
// each action and an ActionNames class. The ActionNames class is used to register
// reducers
abstract class CounterActions extends ReduxActions {
  ActionDispatcher<int> get increment;
  ActionDispatcher<int> get decrement;

  // factory to create on instance of the generated implementation of CounterActions
  CounterActions._();
  factory CounterActions() => _$CounterActions();
}

// This is a built value. It is an immutable model that implements the Built interface.
// All of the state in your redux store is contained in a single built value model.
abstract class Counter implements Built<Counter, CounterBuilder> {
  /// [count] value of the counter
  int get count;

  // Built value constructor. The factory is returning the default state
  Counter._();
  factory Counter() => _$Counter._(count: 0);
}

// These are reducer functions. They have a (state, action, builder) => void signature.
// They describes how an action transforms the state into the next state by applying changes to the builder supplied.
// You are required to use the builder passed, calling state.rebuild will NOT update the state in your redux store.
void increment(Counter state, Action<int> action, CounterBuilder builder) =>
    builder.count = state.count + action.payload;

void decrement(Counter state, Action<int> action, CounterBuilder builder) =>
    builder.count = state.count - action.payload;

// This is a reducer builder. Use of ReducerBuilder is not required, however it
// is strongly recommended as it gives you static type checking to make sure
// the payload for action name provided is the same as the expected payload
// for the action provided to your reducer. Calling .build() returns a reducer function
// that can be passed to the store's constructor.
final reducerBuilder = ReducerBuilder<Counter, CounterBuilder>()
  ..add(CounterActionsNames.increment, increment)
  ..add(CounterActionsNames.decrement, decrement);

Use this package as a library

1. Depend on it

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


dependencies:
  built_redux: ^7.5.10

2. Install it

You can install packages from the command line:

with pub:


$ pub get

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

3. Import it

Now in your Dart code, you can use:


import 'package:built_redux/built_redux.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
89
Health:
Code health derived from static analysis. [more]
0
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
0
Overall:
Weighted score of the above. [more]
44
Learn more about scoring.

We analyzed this package on Mar 30, 2020, and provided a score, details, and suggestions below. Analysis was completed with status aborted using:

  • Dart:
  • pana:

Maintenance issues and suggestions

Make sure dartdoc successfully runs on your package's source files. (-10 points)

exitCode: 255 stdout: parsing /tmp/pub-dartlang-dartdocAISDVX/pkg/lib/built_redux.dart... parsing /tmp/pub-dartlang-dartdocAISDVX/pkg/lib/builder.dart... parsing /tmp/pub-dartlang-dartdocAISDVX/pkg/lib/built_redux_test_utils.dart... parsing /tmp/pub-dartlang-dartdocAISDVX/pkg/lib/generator.dart... parsing /dart-sdk/lib/core/core.dart... parsing /dart-sdk/lib/collection/collection.dart... parsing /dart-sdk/lib/internal/internal.dart... parsing /dart-sdk/lib/async/async.dart... parsing /dart-sdk/lib/convert/convert.dart... parsing /dart-sdk/lib/typed_data/typed_data.dart... parsing /dart-sdk/lib/math/math.dart... parsing /tmp/pub-dartlang-dartdocAISDVX/pkg/lib/src/action.dart... parsing /tmp/pub-dartlang-dartdocAISDVX/pkg/lib/src/reducer_builder.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/built_value-7.0.9/lib/built_value.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/built_collection-4.3.2/lib/built_collection.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/built_collection-4.3.2/lib/src/list.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/built_collection-4.3.2/lib/src/iterable.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/built_collection-4.3.2/lib/src/set.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/collection-1.14.12/lib/collection.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/collection-1.14.12/lib/src/algorithms.dart... [...] parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/kernel-0.3.27/lib/testing/mock_sdk_component.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/kernel-0.3.27/lib/external_name.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/kernel-0.3.27/lib/type_checker.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/kernel-0.3.27/lib/transformations/method_call.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/kernel-0.3.27/lib/transformations/mixin_full_resolution.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/kernel-0.3.27/lib/transformations/continuation.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/kernel-0.3.27/lib/transformations/async.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/kernel-0.3.27/lib/transformations/track_widget_constructor_locations.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/kernel-0.3.27/lib/transformations/empty.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/package_config-1.9.3/lib/discovery_analysis.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/package_config-1.9.3/lib/package_config.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/package_config-1.9.3/lib/package_config_types.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/package_config-1.9.3/lib/discovery.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/args-1.6.0/lib/command_runner.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/test-1.14.2/lib/bootstrap/node.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/test-1.14.2/lib/bootstrap/browser.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/test-1.14.2/lib/bootstrap/vm.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/test_core-0.3.3/lib/backend.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/matcher-0.12.6/lib/mirror_matchers.dart... parsing /tmp/pub-cache-dirKRRFQB/hosted/pub.dartlang.org/stream_channel-2.0.0/lib/isolate_channel.dart... stderr: Documenting built_redux... Unhandled exception: Stack Overflow #0 Dart2TypeSystem._isInterfaceSubtypeOf (package:analyzer/src/generated/type_system.dart:2167:3) #1 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1388:14) #2 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1367:11) #3 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1289:14) #4 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1282:14) #5 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1321:13) #6 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1289:14) #7 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1282:14) #8 Dart2TypeSystem._isInterfaceSubtypeOf (package:analyzer/src/generated/type_system.dart:2197:16) #9 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1388:14) #10 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1367:11) #11 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1289:14) #12 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1282:14) #13 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1321:13) #14 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1289:14) #15 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1282:14) #16 Dart2TypeSystem._isInterfaceSubtypeOf (package:analyzer/src/generated/type_system.dart:2197:16) #17 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1388:14) #18 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1367:11) #19 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1289:14) #20 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1282:14) #21 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1321:13) #22 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1289:14) #23 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1282:14) #24 Dart2TypeSystem._isInterfaceSubtypeOf (package:analyzer/src/generated/type_system.dart:2197:16) #25 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1388:14) #26 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1367:11) #27 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1289:14) #28 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1282:14) #29 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1321:13) #30 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1289:14) #31 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1282:14) #32 Dart2TypeSystem._isInterfaceSubtypeOf (package:analyzer/src/generated/type_system.dart:2197:16) #33 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1388:14) #34 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1367:11) #35 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1289:14) #36 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1282:14) #37 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1321:13) #38 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1289:14) #39 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1282:14) #40 Dart2TypeSystem._isInterfaceSubtypeOf (package:analyzer/src/generated/type_system.dart:2197:16) #41 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1388:14) #42 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1367:11) #43 Dart2TypeSystem.isSubtypeOf (package:analyzer/src/generated/type_system.dart:1289:14) ... ... #6831 ExpressionStatementImpl.accept (package:analyzer/src/dart/ast/ast.dart:3668:49) #6832 RecursiveAstVisitor.visitBlock (package:analyzer/dart/ast/visitor.dart:3501:130146) #6833 RecursiveAstVisitor.visitBlockFunctionBody (package:analyzer/dart/ast/visitor.dart:1157:52) #6834 FunctionExpressionImpl.visitChildren (package:analyzer/src/dart/ast/ast.dart:1036:49) #6835 RecursiveAstVisitor.visitFunctionExpression (package:analyzer/dart/ast/visitor.dart:923:10) #6836 FunctionExpressionImpl.accept (package:analyzer/src/dart/ast/ast.dart:4969:49) #6837 AssignmentExpressionImpl.visitChildren (package:analyzer/src/dart/ast/ast.dart:730:21) #6838 CodeChecker.visitAssignmentExpression (package:analyzer/src/task/strong/checker.dart:255:10) #6839 AssignmentExpressionImpl.accept (package:analyzer/src/dart/ast/ast.dart:725:49) #6840 RecursiveAstVisitor.visitExpressionStatement (package:analyzer/dart/ast/visitor.dart:3501:18178) #6841 ExpressionStatementImpl.accept (package:analyzer/src/dart/ast/ast.dart:3668:49) #6842 RecursiveAstVisitor.visitBlock (package:analyzer/dart/ast/visitor.dart:3501:130146) #6843 RecursiveAstVisitor.visitBlockFunctionBody (package:analyzer/dart/ast/visitor.dart:1157:52) #6844 MethodDeclarationImpl.visitChildren (package:analyzer/src/dart/ast/ast.dart:1036:49) #6845 RecursiveAstVisitor.visitMethodDeclaration (package:analyzer/dart/ast/visitor.dart:1061:10) #6846 MethodDeclarationImpl.accept (package:analyzer/src/dart/ast/ast.dart:6943:49) #6847 ClassDeclarationImpl.visitChildren (package:analyzer/src/dart/ast/ast.dart:7520:20) #6848 RecursiveAstVisitor.visitClassDeclaration (package:analyzer/dart/ast/visitor.dart:701:10) #6849 ClassDeclarationImpl.accept (package:analyzer/src/dart/ast/ast.dart:1519:49) #6850 NodeListImpl.accept (package:analyzer/src/dart/ast/ast.dart:7520:20) #6851 CompilationUnitImpl.visitChildren (package:analyzer/src/dart/ast/ast.dart:2102:21) #6852 CodeChecker.visitCompilationUnit (package:analyzer/src/task/strong/checker.dart:288:10) #6853 LibraryAnalyzer._computeVerifyErrors (package:analyzer/src/dart/analysis/library_analyzer.dart:381:13) #6854 LibraryAnalyzer.analyzeSync.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.4.0 <3.0.0