blackbox_jaspr
Jaspr bindings for
blackbox — state management with one
law: output = compute(input, state).
Your boxes are pure Dart and identical between Flutter and Jaspr — this package provides the web-side delivery and persistence:
BoxObserver— rebuilds a component when the boxes it actually read change;BoxProvider+context.box<T>()— delivery down the component tree;LocalStorageStore— persistence backend forstate(persist:)cells andCache(persist:)on top ofwindow.localStorage.
Setup
void main() {
LocalStorageStore.preload(); // persistence backend, once
final app = createApp(...); // your graph — pure Dart,
// often the same createApp as the Flutter app
runApp(BoxProvider.multi(
boxes: app.boxes,
child: const App(),
));
}
Reading boxes
class CounterView extends StatelessComponent {
@override
Iterable<Component> build(BuildContext context) sync* {
final counter = context.box<CounterBox>();
yield BoxObserver(builder: (_) sync* {
yield text('${counter.value}');
yield button(onClick: counter.increment, [text('+')]);
});
}
}
BoxObserver subscribes to exactly what the builder reads — components
rebuild independently, at the rhythm of their own data.
Testing — swap boxes by type
BoxProvider.overrides(
overrides: [BoxOverride.of<CounterBox>(mockCounter)],
child: componentUnderTest,
);
BoxProvider.multi asserts on two boxes of the same runtime type —
collisions are loud, never silent.
See the blackbox README for the model, and ARCHITECTURE.md for how a whole production app is assembled.
Libraries
- blackbox_jaspr
- Jaspr integration for Blackbox reactive boxes.