blackbox_flutter 0.2.1
blackbox_flutter: ^0.2.1 copied to clipboard
Flutter bindings for Blackbox (BoxObserver + BoxProvider + persistence adapters).
blackbox_flutter #
Flutter bindings for blackbox —
state management with one law: output = compute(input, state).
This package adds the three things a Flutter app needs on top of the pure-Dart core:
BoxObserver— rebuilds a widget when the boxes it actually read change (MobX-style tracking, no manual subscriptions);BoxProvider+context.box<T>()— delivery down the tree;SharedPrefsStore— persistence backend forstate(persist:)cells andCache(persist:)on top ofshared_preferences.
Setup #
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await SharedPrefsStore.preload(); // persistence backend, once
final app = createApp(...); // your graph — pure Dart
runApp(BoxProvider.multi(
boxes: app.boxes, // every declared box, one line
child: const App(),
));
}
Reading boxes — granularity for free #
BoxObserver subscribes to exactly what the builder reads. A progress
bar ticking five times a second never rebuilds the track title:
final player = context.box<PlayerBox>();
BoxObserver(builder: (_) => Text(player.track.value?.title ?? '—'));
BoxObserver(builder: (_) => ProgressBar(at: player.position.value));
BoxObserver(builder: (_) => PlayButton(
playing: player.status.value == PlayerStatus.playing,
onTap: player.toggle,
));
The whole app router is a switch over one box:
BoxObserver(builder: (context) =>
switch (context.box<AppPhaseBox>().value) {
AppLoadingPhase() => const SplashScreen(),
OnboardingPhase() => const OnboardingScreen(),
HomePhase(:final config) => HomeScreen(config: config),
});
Testing — swap boxes by type #
BoxProvider.overrides(
overrides: [BoxOverride.of<CounterBox>(mockCounter)],
child: widgetUnderTest,
);
BoxProvider.multi asserts on two boxes of the same runtime type —
collisions are loud, never silent.
Non-primitive persistence #
Register codecs once, before boxes are created:
await SharedPrefsStore.preload();
BlackboxPersistence.registerCodec(UserJsonCodec());
See the blackbox README for the model, and ARCHITECTURE.md for how a whole production app is assembled.