store_keeper 0.0.1

  • Readme
  • Changelog
  • Installing
  • 45

StoreKeeper #

StoreKeeper is an easy and flexible state management system for Flutter apps. The API is structured in a way that it will not add a lot of boiler plate code regardless of the project size. StoreKeeper is based on the InheritedModel widget from Flutter and it was initially developed as the backend of Kite.

It is an action oriented system. Which means it applies changes to the UI when an action is performed. On the other hand libraries like Redux triggers the render when there is modification in the data.

Store #

This is where all the data of your app stored. You can have only a single store in the app. If you want to divide the store, you can create more models and add their instances to this class.

class AppStore extends Store {
  int count = 0;
}

Mutations #

This is where the app's logic is written.

// Write it as a class
class Increment extends Mutation<AppStore> {
  exec() => store.count++;
}

// or write it as a function
void increment() {
  (StoreKeeper.store as AppStore).count++;
  StoreKeeper.notify(increment);
}

Initialization #

You can attach store to your app like this:

void main() {
  runApp(StoreKeeper(
    store: AppStore(),
    child: MyApp(),
  ));
}

Listening #

In your widget if you want to rebuild it whenever a mutation happens call update with list of mutations:

@override
Widget build(BuildContext context) {
  StoreKeeper.update(context, on: [Increment, Multiply]);
  var store = StoreKeeper.store as AppStore;

  return ...
}

APIs #

StoreKeeper.store

Returns the current instance of the store.

StoreKeeper.update(BuildContext context, {List<Object> on})

Rebuilds the widget with context everytime a mutation given to on is performed.

StoreKeeper.getStreamOf(Object mutation)

Returns a stream associated with the mutation which sends an update everytime the mutation is performed. Useful if you want to use it with a StreamBuilder. You can use UpdateOn widget which combines these ideas. This is useful if you want to update only a small piece of the screen.

UpdateOn(
  mutations: [increment, multiply],
  builder: (_) => Text("Count: ${store.count}"),
),

StoreKeeper.notify(Object mutation)

Notifies StoreKeeper that the mutation has performed. This will internally notify all the listeners of that mutation. Used when you write mutations in functions.

StoreKeeper.mutate(Object key, Function(Store) mutation)

An inline method to mutate a state. Key defines the name of the mutation. Use this API like this:

StoreKeeper.mutate("increment", (AppStore store) => store.count++);

Simple Example #

import 'package:flutter/material.dart';
import 'package:store_keeper/store_keeper.dart';

// Build store and make it part of app
void main() {
  runApp(StoreKeeper(
    store: AppStore(),
    child: MyApp(),
  ));
}

// Store definition
class AppStore extends Store {
  int count = 0;
}

// Mutations
class Increment extends Mutation<AppStore> {
  exec() => store.count++;
}

class Multiply extends Mutation<AppStore> {
  final int by;

  Multiply({this.by});

  exec() => store.count *= by;
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Define when this widget should re render
    StoreKeeper.update(context, on: [Increment, Multiply]);

    // Get access to the store
    var store = StoreKeeper.store as AppStore;

    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Text("Count: ${store.count}"),
              RaisedButton(
                child: Text("Increment"),
                onPressed: () {
                  // Invoke mutation
                  Increment();
                },
              ),
              RaisedButton(
                child: Text("Decrement"),
                onPressed: () {
                  // Invoke mutation with params
                  Multiply(by: 2);
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Mutations using functions #

import 'package:flutter/material.dart';
import 'package:store_keeper/store_keeper.dart';

// Build store and make it part of app
void main() {
  runApp(StoreKeeper(
    store: AppStore(),
    child: MyApp(),
  ));
}

// Store definition
class AppStore extends Store {
  int count = 0;
}

// Mutations
void increment() {
  (StoreKeeper.store as AppStore).count++;
  StoreKeeper.notify(increment);
}

void multiply({int by}) {
  (StoreKeeper.store as AppStore).count *= by;
  StoreKeeper.notify(multiply);
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Define when this widget should re render
    StoreKeeper.update(context, on: [increment, multiply]);

    // Get access to the store
    var store = StoreKeeper.store as AppStore;

    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Text("Count: ${store.count}"),
              RaisedButton(
                child: Text("Increment"),
                onPressed: () {
                  // Invoke mutation
                  increment();
                },
              ),
              RaisedButton(
                child: Text("Decrement"),
                onPressed: () {
                  // Invoke mutation with params
                  multiply(by: 2);
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

[0.0.1]

  • Initial release with basic features

Use this package as a library

1. Depend on it

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


dependencies:
  store_keeper: ^0.0.1

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

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

3. Import it

Now in your Dart code, you can use:


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

We analyzed this package on Nov 21, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.6.0
  • pana: 0.12.21
  • Flutter: 1.9.1+hotfix.6

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Health suggestions

Fix lib/inherited_model.dart. (-0.50 points)

Analysis of lib/inherited_model.dart reported 1 hint:

line 1 col 8: Unused import: 'dart:async'.

Fix lib/inventory.dart. (-0.50 points)

Analysis of lib/inventory.dart reported 1 hint:

line 2 col 8: Unused import: 'mutation.dart'.

Fix lib/store_keeper.dart. (-0.50 points)

Analysis of lib/store_keeper.dart reported 1 hint:

line 26 col 48: The member 'setState' can only be used within instance members of subclasses of 'package:flutter/src/widgets/framework.dart'.

Fix lib/update_on.dart. (-0.50 points)

Analysis of lib/update_on.dart reported 1 hint:

line 13 col 5: The class 'Stream' wasn't exported from 'dart:core' until version 2.1, but this code is required to be able to run on earlier versions.

Maintenance suggestions

Maintain an example. (-10 points)

Create a short demo in the example/ directory to show how to use this package.

Common filename patterns include main.dart, example.dart, and store_keeper.dart. Packages with multiple examples should provide example/README.md.

For more information see the pub package layout conventions.

Package is pre-v0.1 release. (-10 points)

While nothing is inherently wrong with versions of 0.0.*, it might mean that the author is still experimenting with the general direction of the API.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev.68.0 <3.0.0
async ^2.2.0 2.4.0
flutter 0.0.0
http ^0.12.0 0.12.0+2
Transitive dependencies
charcode 1.1.2
collection 1.14.11 1.14.12
http_parser 3.1.3
meta 1.1.7 1.1.8
path 1.6.4
pedantic 1.8.0+1
sky_engine 0.0.99
source_span 1.5.5
string_scanner 1.0.5
term_glyph 1.1.0
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test