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.
3.0.0 - 2026-10-16 #
Upgrading from 2.2.0: read the migration guide. Requires Flutter 3.29.2 or newer.
Breaking changes #
package:jintent/jintent.dartexports only the core, domain helpers,JObserverand the dispatcher contracts. Devtools, experimental, navigation and utilities moved to their own entry points. See entry points.JController.updateandsetStateskip equal states (==), so no listener or observer is notified. Mutating state in place is no longer supported; this reverses the 2.0.1 behavior. See state equality.- Effects: awaitable effects emitted without a listener, and unhandled awaitable
effects, now complete with a
StateErrorinstead of being lost or completing withnull.warnAndCompleteErrorreplaces the deprecatedwarnAndAutoComplete. See effects and listeners. - Lifecycle: invoking a running
JIntentinstance again, or dispatching or invoking against a disposed controller, fails withStateError. Disposal fails pending effect results, and the sequential dispatcher rejects that controller's queued intents immediately. See disposal. Eitheris sealed and cannot be extended or implemented. See Either.JIntent.runandJIntent.invokeare@nonVirtual, andJIntentgainscancel()andisCancelled. Mocks used with dispatchers must stubisCancelled. See intent methods.- Undo/redo capacities must be positive. See undo/redo promotion.
Added #
package:jintent/undo_redo.dart: stable snapshot and command history with an observablehistory. History is preserved for equal, cancelled or disposed updates. The experimental import remains a compatibility export. See undo/redo.package:jintent/widgets.dart:JControllerBuilderandJControllerSelector. See widgets.package:jintent/testing.dart:JStateRecorder,JEffectRecorderandresetJIntentGlobals, plusJEffectsConfig.reset(). See testing.JDroppableIntentDispatcher,JRestartableIntentDispatcher(grouped withkeyOf/JIntentKey), cooperative cancellation throughJIntent.cancel, and the optionalJPendingIntentCancellationcontract. See concurrency.package:jintent/jintent.dartexportsJEffectsConfigandUnhandledEffectStrategy; 2.x required importing them fromsrc. See effects.JIntent.current:JController.updateinside an intent is attributed to it and ignored once it is cancelled, without passingorigin.- Composable observers:
JObserverDelegate,JObserver.addObserver/removeObserver/reset, andonIntentStarted,onIntentFailed,onIntentCancelledandonIntentDroppednotifications. See observability. JController(effectBufferSize: n)buffers effects emitted before a listener attaches (opt-in; the default 0 keeps the previous behavior). See effects.Either: exhaustiveswitch, destructurablevalue, value equality andtoString;Rightisconst.JMetrics:maxMetrics,detachFromObserver,intent.failed,intent.cancelledandintent.droppedcounters and a realintent.execution.durationtimer.JDevToolsOverlaylists failed, cancelled and dropped intents.
Changed #
- Observer and callback failures no longer reach the observed code; they are
reported through
FlutterError.reportError. enableLoggingObserver,JEffectsLogger.attachandJDevToolsOverlayregister observers instead of assigning the static callbacks, so they coexist.LoggingDispatcherforwards cancellation to compatible inner dispatchers, and shared sequential queues preserve other controllers' tasks and order.- A cancelled intent is no longer reported as dispatched.
- Effect handlers must be registered for the concrete effect type; the superclass lookup never worked and was removed.
Deprecated #
UnhandledEffectStrategy.warnAndAutoComplete: usewarnAndCompleteError.
Fixed #
JController.updateprintedState updated.in release builds, and the core importedmaterial.dart.JMetricsleft an intent timer running and doubled counts when attached twice.Leftthrew when its value wasnulland an error logger was set.JColorUtils.blendreturned near-black colors, andJThrottler.resetleft a pending timer that could release the throttle early.JEffectListenernow replaces subscriptions when its controller changes, and handler failures complete pending effect results with the original error.- Effect timeouts report
TimeoutException. setStatepreserves the originating intent for observers, and accessing an intent's controller before invocation reports a descriptive error.- Corrected the
JUseCaseVoid,JIntentHelpersandCorrelationContextdocs.
Documentation #
- New guides for concurrency, testing, widgets, undo/redo and migration, a rewritten observability guide, and ADR-001 and ADR-002.
2.2.0 - 2025-11-11 #
Documentation #
- Data Layer Guide: Added comprehensive
docs/DATA_LAYER_GUIDE.mdcovering repository patterns, mappers, Either-based error handling, and validation pipelines - Mapper Tests: Added
test/src/domain/mapper_test.dartdemonstrating ArgumentError handling and recovery patterns - Example Repository: Added complete repository example in
example/lib/src/data/showing:- Repository interface and implementations (in-memory, cached, failing mock)
- Mapper patterns (JMapper and IBiMapper)
- Either-based error handling
- ArgumentError handling and recovery
- Validation at multiple layers
- Example Tests: Added comprehensive tests for mappers and repositories demonstrating best practices
2.1.0 - 2025-08-09 #
2.0.1 Bug Fix - (2025-08-05) #
Fixed #
- State changes are now always notified in
JController, even for internal mutations (such as modifying items within a list or map). - Removed equality check between previous and new state in the
setStateandupdatemethods, ensuring that all state updates are propagated to listeners and debugging observers.
Notes #
- This update improves reactivity and observability for state changes that involve mutations within objects or collections.
- No breaking changes to the API.
2.0.0 Side Effects, UI Decoupling, Dependency Cleanup (2024/06/10) #
✨ New Features: Side Effects
- Side Effect Stream: Introduced a
Stream<JEffect>insideJControllerto handle transient UI actions like navigation, dialogs, and snackbars. These are events that don't modify the application state but require a one-time reaction from the UI. - emitSideEffect(): You can now trigger a side effect from the controller using
emitSideEffect(effect)oremitAndWaitSideEffect(effect)to optionally wait for a result. - JEffect: A new abstract class to represent side effects. Can optionally return a result using a
Completer<T>, useful for awaiting user input (e.g. confirmation dialogs). - JSideEffectHandler: A centralized handler in the UI to react to emitted side effects by type, keeping business logic and UI logic cleanly separated.
🔄 Architecture Improvements
- UI Decoupling: The UI no longer directly interacts with the controller for triggering logic or responses. Instead, the UI listens to sideEffects and emits
JIntentinstances indirectly, promoting a fully decoupled flow. - Intent-Centric Workflow: The communication between UI and logic is now entirely intent-driven. The controller receives intents and updates state or emits side effects, maintaining separation of concerns.
🧹 Dependency Cleanup
- Removed get_it Dependency: The package is no longer used internally. All dependency injection is now left to the user's implementation or application layer, giving you full control over your architecture and reducing tight coupling.
1.0.0 Initial Release(2024/04/28) #
Key Features
- Intent Handling: Introduces the concept of intents to encapsulate user actions and other events that can modify the state of a Flutter application. This approach promotes modularity and scalability.
- State Management: The JController class provides a way to manage application state and handle updates. It ensures a clean and organized process for handling state changes.
- Dependency Injection: Integration with the GetIt package for efficient dependency injection. This allows for easy registration and retrieval of services throughout the application.
- Common Functionalities: The JCommonsMixin mixin offers convenient access to common Flutter functionalities, such as navigation and progress dialog management.*
- Progress Dialog Management: The JProgressDialogManagerController class allows for easy management of progress dialogs, facilitating the display and hiding of loading indicators.
1.0.0+1 Dependency Injection Enhancement(2024/04/29) #
- Dependency Injection: Implemented get_it as the dependency injection system for the project. This change was made because the previous implementation was suboptimal and not functioning as expected. With this enhancement, you can expect improved modularity and easier testing.
- Improved Documentation: Enhanced the documentation for key components, providing clearer explanations and detailed information about dependencies, including JNavigatorService, JState, and others. These updates aim to make the codebase more accessible and easier to understand for developers.
1.0.0+2 -OnInit and dispose events controller(2024/05/03) #
OnInit Event #
Initialization method for the controller. This method is called once when the controller is created. It is used to set up the initial state of the controller, subscribe to events, configure services, or perform any necessary setup at the beginning of the controller's lifecycle.
This method can be overridden by subclasses to implement their own initialization logic.
Examples of usage for onInit():
- Subscribing to data providers or services.
- Setting default values for the controller's state.
- Registering listeners for events that affect the controller.
Ensure that any resources used in onInit()
are properly released when the controller is deactivated or removed.
For this purpose, you can use a dispose() method or another
mechanism to clean up resources when the controller's lifecycle ends.
Dispose event #
Cleans up resources and performs necessary teardown operations.
This method is called when the controller is being disposed of, usually at the end of its lifecycle. It is crucial to override this method to ensure proper cleanup of resources, like unsubscribing from providers, removing listeners, or releasing references to large objects.
When overriding this method, always call super.dispose() to ensure
that the base class's disposal logic is also executed.
Common cleanup tasks include:
- Unsubscribing from event listeners or streams.
- Releasing references to large objects or services.
- Closing resources like file handles, database connections, or network sockets.
Important: Failing to clean up resources can lead to memory leaks and other unpredictable behavior, so always ensure proper disposal.
1.0.0+3 call OnInit in contracutor(to get expected behavior with OnInit Event) (2024/05/03) #
- call OnInit JController contructor as default.
1.0.1 Side Effects System & Decoupling UI from Controller (2024/06/10) #
✨ New Features: Side Effects Side Effect Stream: Introduced a Stream
emitSideEffect(): You can now trigger a side effect from the controller using emitSideEffect(effect) or emitAndWaitSideEffect(effect) to optionally wait for a result.
JEffect: A new abstract class to represent side effects. Can optionally return a result using a Completer
JSideEffectHandler: A centralized handler in the UI to react to emitted side effects by type, keeping business logic and UI logic cleanly separated.
🔄 Architecture Improvements UI Decoupling: The UI no longer directly interacts with the controller for triggering logic or responses. Instead, the UI listens to sideEffects and emits JIntent instances indirectly, promoting a fully decoupled flow.
Intent-Centric Workflow: The communication between UI and logic is now entirely intent-driven. The controller receives intents and updates state or emits side effects, maintaining separation of concerns.
🧹 Dependency Cleanup Removed get_it Dependency: The package is no longer used internally. All dependency injection is now left to the user's implementation or application layer, giving you full control over your architecture and reducing tight coupling.