jintent 3.0.0
jintent: ^3.0.0 copied to clipboard
jintent is a Flutter package that provides an architecture for managing state changes in your application using the concept of intents.
JIntent #
JIntent is a Flutter library for explicit intents, immutable state and one-time UI effects. Controllers manage state; intents perform operations; effect handlers present dialogs, navigation and feedback outside persistent state.
Installation #
flutter pub add jintent
Import the public entry point:
import 'package:jintent/jintent.dart';
Optional pieces have their own entry points, so the core stays small:
| Import | Contents |
|---|---|
package:jintent/jintent.dart |
State, intents, controller, effects, dispatchers, JObserver, Either, use cases, mappers |
package:jintent/devtools.dart |
Structured logging, correlation, metrics, debug overlay |
package:jintent/testing.dart |
State and effect recorders, global reset |
package:jintent/widgets.dart |
Controller builder and selector without a provider package |
package:jintent/undo_redo.dart |
Stable undo/redo, observable history and commands |
package:jintent/navigation.dart |
Thin Navigator abstraction |
package:jintent/utils.dart |
Throttler, validation, color and platform helpers |
See undo and redo for local edit history, UI integration, ordering and migration from the legacy experimental import.
Upgrading from 2.x changes state equality, effect failures and disposal behavior. Review the migration guide first.
Minimal example #
import 'package:jintent/jintent.dart';
class CounterState extends JState {
final int count;
const CounterState({this.count = 0});
@override
CounterState copyWith({int? count}) =>
CounterState(count: count ?? this.count);
@override
List<Object?> get props => [count];
}
class IncrementIntent extends JIntent<CounterState>
with JIntentHelpers<CounterState> {
@override
Future<void> onInvoke() async {
update((state) => state.copyWith(count: state.count + 1));
}
}
class CounterController extends JController<CounterState> {
CounterController() : super(const CounterState());
Future<void> increment() => intent(IncrementIntent());
@override
void onInit() {}
}
Future<void> main() async {
final controller = CounterController();
try {
await controller.increment();
print(controller.currentState.count); // 1
} finally {
controller.dispose();
}
}
Connect the controller directly with JControllerBuilder or
JControllerSelector from package:jintent/widgets.dart, or use your
StateNotifier integration. The widget guide covers ownership,
controller replacement and selecting part of a state. The
example gallery uses the builders in its four focused labs and
Riverpod with JEffectListener in the counter.
Contracts #
JState: include relevant values inprops; return new immutable states. Updates equal to the current state are skipped.JIntent: overrideonInvokeand await its work. One instance cannot run concurrently; it can be reused after completion.JController: dispatches sequentially by default. Return dispatch futures and handle their errors at the UI boundary.onInitruns synchronously from the base constructor, before the subclass constructor body. PasseffectBufferSizeto retain effects emitted before the UI attaches.JEffect: transient UI events. Register each concrete effect type in aJSideEffectHandlerand complete awaited results. A subscription alone does not guarantee completion; configure a timeout for awaited UI work.JObserver: registerJObserverDelegates to observe intents (including failures), state and effects; see observability.- Disposal rejects queued intents and pending effect results; running service calls and handlers need their own cancellation or lifecycle checks.
See effects for registration, failures and timeouts, and error handling for operation boundaries.
Documentation #
- Interactive guide in English and Spanish, with live demos and diagrams.
- Effects and error handling.
- Concurrency strategies: sequential, droppable, restartable and cooperative cancellation.
- Testing: state and effect recorders, global reset.
- Domain helpers: validation and mappers.
- Observability and extension points.
- Migration: upgrading from 2.x to 3.0.0.
- Security policy.
- Changelog: version history.
- Architecture records: ADR-000, ADR-001 and ADR-002 (all accepted).
Contributing #
Discuss substantial changes in an issue and keep pull requests focused. Follow
repository instructions and the task workflow.
For Dart changes, format affected files, run flutter analyze and relevant tests;
before delivering library changes, run flutter test --coverage. Root analysis
excludes the example, which needs separate validation when affected.
Documentation changes require checking references and git diff --check.
See the CI workflow for executable checks and the
code of conduct for community guidelines.
License #
MIT.