hybrid_manager 0.0.5
hybrid_manager: ^0.0.5 copied to clipboard
Hybrid Manager is a robust, lightweight state management library for Flutter, combining the best of GetX and Riverpod patterns. It offers reactive programming, class-based state notifiers, dependency [...]
β‘ Hybrid Manager #
A powerful yet lightweight state management solution for Flutter that combines the best of GetX and Riverpod patterns. Use reactive programming, class-based state notifiers, dependency injection, and hot-reload-friendly APIs β all in one clean package.
β¨ Features #
- π Reactive Values:
Reactive<T>
for reactive state management (inspired by GetX's Rx) - π§ State Notifiers:
StateNotifier<T>
for class-based state logic (inspired by Riverpod) - π± Provider System:
Provider<T>
andScopedProvider<T>
for dependency injection - π‘ Functional Hooks:
useState
,useComputed
,useEffect
for functional programming - π Hot-reload Friendly: Maintains state during development
- π Route Management: Built-in reactive route management
- π§ͺ Type Safe: Full TypeScript-level type safety
- π¦ Lightweight: Minimal dependencies, maximum performance
π¦ Installation #
Add the package to your pubspec.yaml
:
dependencies:
hybrid_manager: ^0.0.4
Then run:
flutter pub get
οΏ½ Quick Start #
Reactive Values #
import 'package:hybrid_manager/hybrid_manager.dart';
// Create a reactive value
final counter = Reactive<int>(0);
// Listen to changes
counter.listen((value) => print('Counter: $value'));
// Update the value
counter.value++; // prints: Counter: 1
// Use in widgets (pseudo-code)
Widget build(BuildContext context) {
return Text('${counter.value}');
}
State Notifiers #
class CounterNotifier extends StateNotifier<int> {
CounterNotifier() : super(0);
void increment() {
state = state + 1;
}
void decrement() {
if (state > 0) {
state = state - 1;
}
}
void reset() {
state = 0;
}
}
// Usage
final counterNotifier = CounterNotifier();
counterNotifier.addListener((state) => print('State: $state'));
counterNotifier.increment(); // prints: State: 1
Providers & Dependency Injection #
// Create providers
final apiProvider = Provider<ApiService>(() => ApiService());
final userProvider = Provider<UserService>(() => UserService(apiProvider.create()));
// Register with injector
Injector.putProvider<ApiService>(apiProvider);
Injector.putProvider<UserService>(userProvider);
// Use anywhere in your app
final userService = Injector.get<UserService>();
Scoped Providers #
final configProvider = ScopedProvider<Config>(() => Config.production());
// Override for testing
configProvider.overrideWithValue(Config.testing());
// Use the overridden value
final config = configProvider.create(); // Returns Config.testing()
Functional Hooks #
// State hook
final count = useState(0);
count.value++; // Reactive updates
// Computed values
final doubled = useComputed(() => count.value * 2, dependencies: [count]);
// Effects
useEffect(() {
print('Count changed to: ${count.value}');
}, dependencies: [count]);
Route Management #
final routeManager = RouteManager.instance;
// Navigate
routeManager.navigateTo('/profile', name: 'profile');
// Listen to route changes
routeManager.currentRoute.listen((route) {
print('Current route: ${route.path}');
});
// Go back
if (routeManager.canGoBack) {
routeManager.goBack();
}
π Advanced Usage #
Provider Families #
final userProvider = ProviderFamily<User, String>((userId) {
return UserRepository().getUser(userId);
});
// Usage
final user1Provider = userProvider('user1');
final user2Provider = userProvider('user2');
Reactive Providers #
final weatherReactive = Reactive<String>('sunny');
final temperatureReactive = Reactive<int>(25);
final weatherProvider = ReactiveProvider<String>(
() => '${weatherReactive.value} and ${temperatureReactive.value}Β°C',
dependencies: [weatherReactive, temperatureReactive],
);
// Automatically updates when dependencies change
weatherReactive.value = 'cloudy'; // Provider updates automatically
Hot Reload Support #
HotReloadUtils.onHotReload(() {
// Reset state or perform cleanup
Injector.reset();
print('Hot reload detected!');
});
π§ͺ Testing #
Hybrid Manager is designed with testing in mind:
void main() {
group('Counter Tests', () {
late CounterNotifier counter;
setUp(() {
counter = CounterNotifier();
});
tearDown(() {
counter.dispose();
});
test('should increment counter', () {
counter.increment();
expect(counter.state, equals(1));
});
test('should notify listeners', () {
int? notifiedValue;
counter.addListener((value) => notifiedValue = value);
counter.increment();
expect(notifiedValue, equals(1));
});
});
}
π― Architecture Patterns #
MVVM with Hybrid Manager #
// Model
class User {
final String name;
final String email;
User({required this.name, required this.email});
}
// ViewModel
class UserViewModel extends StateNotifier<User?> {
UserViewModel() : super(null);
void loadUser(String id) async {
try {
final user = await UserRepository().getUser(id);
state = user;
} catch (e) {
// Handle error
}
}
}
// View (Widget)
class UserProfileWidget extends StatelessWidget {
final UserViewModel viewModel;
UserProfileWidget({required this.viewModel});
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: viewModel.stream,
builder: (context, snapshot) {
final user = snapshot.data;
if (user == null) return CircularProgressIndicator();
return Column(
children: [
Text(user.name),
Text(user.email),
],
);
},
);
}
}
π§ Best Practices #
- Use StateNotifier for Complex Logic: When you have complex state transitions, use
StateNotifier
- Use Reactive for Simple State: For simple values that need reactivity, use
Reactive<T>
- Scope Your Providers: Use
ScopedProvider
for different app contexts (testing, development, production) - Dispose Resources: Always dispose of state notifiers and reactive values when done
- Test Your State: Use the provided testing utilities to ensure your state management works correctly
π€ Contributing #
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
π License #
This project is licensed under the MIT License - see the LICENSE file for details.
π Acknowledgments #
- Inspired by GetX for reactive programming
- Inspired by Riverpod for provider patterns
- Built with β€οΈ for the Flutter community
π Support #
If you like this package, please give it a β on GitHub and π on pub.flutter-io.cn!
For issues and feature requests, please use the GitHub issue tracker. class CounterNotifier extends MyStateNotifier
void increment() => state++; }
Register it:
```dart
final counterProvider = createNotifier(() => CounterNotifier());
Use it:
final counter = watch(counterProvider);
Scoped Overrides #
ProviderScope(
overrides: [
counterProvider.overrideWithValue(CounterNotifier()..state = 999),
],
child: MyApp(),
);
π Tooling & Code Generation #
Built-in Testing Utilities #
Hybrid Manager provides helpers for testing providers, notifiers, and reactive state:
import 'package:hybrid_manager/test_utils.dart';
final values = testReactive(counter, (r) => r.value = 42);
final states = testNotifier(counterNotifier, (n) => n.increment());
final result = testProvider(apiProvider, (api) => api.fetchData());
CLI Tool #
Scaffold providers and notifiers from the command line:
dart tooling/hybrid_manager_cli.dart create provider MyProvider
dart tooling/hybrid_manager_cli.dart create notifier MyNotifier
This generates boilerplate files in your project.
Code Generation Annotation #
Annotate your classes with @yourProvider
for future codegen support:
import 'package:hybrid_manager/annotations/annotation.dart';
@yourProvider(singleton: true)
class MyService {
// ...
}
Run the stub generator:
dart tooling/your_provider_generator.dart
License #
MIT License
Author #
omJamnekar GitHub
π Contributions #
Feel free to open issues or pull requests! Help improve this package and make Flutter state management more enjoyable.