state_pulse 1.1.1
state_pulse: ^1.1.1 copied to clipboard
Lightweight reactive & persistent state management for Flutter.
StatePulse
A lightweight, reactive, hydrated state-management library for Flutter โ inspired by Provider + Hydrated Bloc, but 10ร simpler.
๐ Features #
- ๐ Simple API โ only a few core classes
- ๐ฅ Ultra-fast UI updates (InheritedNotifier + AnimatedBuilder)
- ๐พ Built-in hydration using
HydratedStatePulse - ๐ฏ Selectors, Listeners, and Consumers (like Bloc/Provider)
- ๐งฉ Supports local store instances (per-widget state)
- โก Zero boilerplate
- ๐ฆ Zero dependencies (only
shared_preferencesfor persistence) - ๐ง Designed for small โ large production apps
๐ฆ Install #
dependencies:
state_pulse: ^1.1.0
๐ Migration Guide (0.0.8 โ 1.0.0) #
Before (0.0.8) #
class CounterStore extends ChangeNotifier with HydratedStatePulse {
int value = 0;
void increment() {
value++;
notifyListeners();
}
@override
Map<String, dynamic> toJson() => {'value': value};
@override
void fromJson(Map<String, dynamic> json) {
value = json['value'] ?? 0;
}
}
Now Breaking Change(1.0.0) #
- Required initialization
void main() async {
WidgetsFlutterBinding.ensureInitialized(); // REQUIRED
await StatePulse.initialize(); // REQUIRED
runApp(MyApp());
}
- Store inheritance change
class CounterStore extends HydratedStatePulse {
int value = 0;
void increment() {
value++;
notifyListeners();
}
@override
Map<String, dynamic> toJson() => {'value': value};
@override
void fromJson(Map<String, dynamic> json) {
value = json['value'] ?? 0;
}
}
๐งฉ Quick Start Example #
Create a Store #
class CounterStore extends HydratedStatePulse {
int value = 0;
void increment() {
value++;
notifyListeners();
}
@override
Map<String, dynamic> toJson() => {'value': value};
@override
void fromJson(Map<String, dynamic> json) {
value = json['value'] ?? 0;
}
}
Provide the Store #
StatePulseProvider(
store: CounterStore(),
child: MyApp(),
);
Use With Builder #
StatePulseBuilder<CounterStore>(
builder: (_, store) => Text('${store.value}'),
);
๐ฏ Selector Example (High Performance Rebuilds) #
Only rebuilds when the selected value changes.
StatePulseSelector<CounterStore, int>(
selector: (store) => store.value,
builder: (_, value) => Text('$value'),
);
๐ Listener Example (Side-effects โ No UI Rebuild) #
StatePulseListener<CounterStore>(
listener: (_, store) {
if (store.value == 10) {
print("Reached 10!");
}
},
child: SomeWidget(),
);
๐ Consumer Example (Listener + Builder) #
StatePulseConsumer<CounterStore>(
listener: (_, store) => print("Changed!"),
builder: (_, store) => Text("${store.value}"),
);
๐งช Local Store Instance (Widget-Scoped State) #
Each widget has its own isolated store:
final localStore = CounterStore();
return StatePulseBuilder<CounterStore>(
store: localStore,
builder: (_, store) => Text("${store.value}"),
);
๐ง Advanced Example โ Hydrated User Store #
class UserStore extends HydratedStatePulse {
UserModel? user;
bool loading = false;
Future<void> fetchUser() async {
loading = true;
notifyListeners();
await Future.delayed(Duration(seconds: 1));
user = UserModel(id: "1", name: "Alex", email: "alex@mail.com");
loading = false;
notifyListeners();
}
@override
Map<String, dynamic> toJson() => user == null ? {} : {"user": user!.toJson()};
@override
void fromJson(Map<String, dynamic> json) {
if (json["user"] != null) {
user = UserModel.fromJson(json["user"]);
}
}
}