easy_state_m 1.2.2
easy_state_m: ^1.2.2 copied to clipboard
Easy State Framework is a lightweight, high-performance, strongly-typed state management micro-framework for Flutter.
1.2.2 #
Breaking Changes #
EasyScope— default constructor removed. Use the explicit named constructors that declare lifecycle ownership:EasyScope<T>.build(create: ..., builder: (ctx, controller) => ...)— the scope owns the controller (callsinitialize()/dispose()).EasyScope<T>.share(value: ..., builder: (ctx, controller) => ...)— the scope wraps an externally managed controller and never disposes it. Replaces the formerEasyScope.value.
EasyScopeProvide— default constructor removed. Same.build/.sharesplit asEasyScope:EasyScopeProvide<T>.build(create: () => T())(was the unnamed ctor).EasyScopeProvide<T>.share(value: existing)(wasEasyScopeProvide.value).
EasyScope—childparameter removed. All scopes now consume the unified two-argumentEasyScopeBuilder<T>of the form(BuildContext context, T controller) => Widget. When you do not need the controller directly (e.g. insideEasyMultiScopeadapters), usebuilder: (_, _) => myChildinstead of the oldchild:parameter.
Improvements #
- Added the
EasyScopeBuilder<T>typedef and exposed it as the public signature for bothEasyScope.buildandEasyScope.share. EasyScopedoc-comments and error hints now point at the new.build/.shareconstructors.- Example app rewritten: PageA → PageB demo shows the recommended pattern of
re-injecting a controller across a Navigator barrier with
EasyScope<T>.shareso that the destination page can resolve it withEasyScope.of<T>(context)without taking it through a widget constructor.
Migration #
// Before (1.2.1)
EasyScope<CounterController>(
create: () => CounterController(),
builder: (context, controller) => CounterView(),
);
EasyScope<AuthController>.value(
value: authController,
child: const ProfilePage(),
);
EasyMultiScope(entries: [
EasyScopeProvide(create: () => CartController()),
EasyScopeProvide.value(value: authController),
]);
// After (1.2.2)
EasyScope<CounterController>.build(
create: () => CounterController(),
builder: (context, controller) => CounterView(),
);
EasyScope<AuthController>.share(
value: authController,
builder: (_, _) => const ProfilePage(),
);
EasyMultiScope(entries: [
EasyScopeProvide<CartController>.build(create: () => CartController()),
EasyScopeProvide<AuthController>.share(value: authController),
]);
1.2.1 #
- Fix compatibility: replace Dart 3 record type
(String, void Function(dynamic))with private class_ChannelEntryto support Dart 2.17+. - Update SDK constraint from
^3.11.0to>=2.17.0 <4.0.0(Flutter >= 3.0.0). - Fix example pubspec: rename dependency key
easy_state→easy_state_mto match the package name, and update all import paths accordingly.
1.2.0 #
Breaking Changes #
- Removed
EasyEvent,EasyEventBinding,EasyEventBus, andEasyBusRegistry. The event-driven cross-controller API has been replaced by a typed channel system (see below). - Renamed
MultiEasyScope→EasyMultiScopefor naming consistency with the rest of the API. EasyScopeBindingreplaced byEasyScopeProvide/EasyScopeProvide.value.
New Features #
-
Typed channel bus — zero-coupling cross-controller messaging.
EasyChannelBinding<T>— declarative, type-safe channel subscription. Declare subscriptions by overridingEasyController.channelBindings.EasyController.emit<C>(channel, data)— sends a message to all instances of controller typeCthat have registered a binding forchannel. Annotated@protected; only callable from withinEasyControllersubclasses.EasyChannelBus— public abstract interface for the channel bus, enabling clean test doubles viaEasyChannel.override(mock).EasyChannel— global registry withoverride()andreset()for testing.- Channel names are automatically namespaced by the target controller's
runtimeType, so the same channel name in different controllers never collides.
-
_RefreshNotifier— allocation-free hot path. ReplacedList.of()defensive copies with an iteration-depth counter and null-mark strategy (modelled after Flutter'sChangeNotifier). The common path — no structural changes during notification — is now fully allocation-free. Compaction runs once after the outermostnotifyreturns, and reentrantrefresh()calls are handled correctly via a depth counter. -
_ChannelBus.emit— index-based iteration. ReplacedList.of(handlers)with a length-snapshot loop, eliminating one temporary list allocation per dispatch.
Improvements #
EasyChannelBindingconstructor asserts that the type parameterTis notdynamic, catching type-erasure bugs at construction time in debug mode.EasyController.emit<C>asserts thatCis not the baseEasyControllertype, preventing silent no-op dispatches caused by a missing generic argument.EasyScope.of<T>documentation updated with an async-safety pattern: store the controller reference before anyawaitto avoid accessing an invalidatedBuildContext.- Full English API documentation on all public classes and members (pub.dev standard).
- Updated
README.mdwith architecture diagram, data-flow table, performance notes, and complete bilingual (English / 中文) usage guide.
1.0.2 #
- Add Support Files.
1.1.0 #
- Add MultiEasyScope
- Update README.md
1.0.0 #
- Initial release of Easy State.
- Added
EasyControllerandEasyScopefor O(1) dependency injection. - Added
EasyEventand_EasyEventBusfor multi-way data synchronization. - Added
EasyConsumerfor granular local UI rebuilds. - Implemented strict architectural guardrails and assertions.