molc 0.2.1
molc: ^0.2.1 copied to clipboard
A Flutter state management package separating UI state Models from business Logic.
Changelog #
0.2.1 #
Fixes #
- Run
refresh(fn)callbacks beforeSelectorMixindecides whether to notify listeners, so callback-style state updates use the same semantics as mutating state before callingrefresh(). - Reconnect
MoLogicto the currentmodelValuewhenMoLcWidget.valuereceives a replacement model instance.
Docs / tooling #
- Document that
Mutableintentionally uses a static build-phase delegate for GetX-like automatic dependency tracking on Flutter's synchronous build model. - Add focused widget tests for
MutableWidget, provider error paths,top<T>()pre-mount errors, selector callback refresh, andMoLcWidget.valuemodel replacement. - Add package metadata and
.pubignoreentries so local agent files and generated artifacts are excluded from the published package. - Replace the example app's template README with MoLc-specific usage notes.
0.2.0 #
Breaking changes #
- Bumped SDK constraints to Dart
>=3.0.0 <4.0.0and Flutter>=3.7.0. - Removed the
providerpackage dependency. MoLc now uses Flutter's native inherited widget mechanism internally. lib/molc.dartno longer re-exports provider APIs such asChangeNotifierProvider,ReadContext,WatchContext, orMultiProvider. Use MoLc's nativeMoNotifierProvider,MoProvider,MoMultiProvider,context.read<T>(), andcontext.watch<T>()APIs instead.TopProvider.providersnow acceptsList<MoProviderBuilder>instead of provider'sList<SingleChildWidget>. Use helpers such asmoNotifierProvider<T>((context) => T()).- Removed the
lazyparameter fromLogicWidgetandMoLcWidget. It was a no-op:initreadsTfrom the current scope, which forces immediate creation regardless of the flag. - The module-level
coreContainerProvideris gone.TopProvidernow constructs a freshCoreContainerper mount, and asserts that only oneTopProvideris mounted at a time. Tests that mounted multiple roots in parallel must now mount them sequentially.
Features #
TopProvider/TopModel/top<T>()for app-wide model access via a global key.ExposedMixin+ top-levelfind<T>()/findFuzzy()for ad-hoc model lookup.EventModel<T>+EventConsumerMixinfor partial top-model refresh by event.ValueModel<T>/Value2Model/Value3Modeland matchingNoMoWidget/NoMo2Widget/NoMo3Widgetfor trivial value-only state.Mutable<T>+MutableWidgetand a family of typed extensions (MutableStringExt,MutableBoolExt,MutableIntExt, ...) for inline reactive values.- Native MoLc provider primitives:
MoProvider,MoNotifierProvider,MoMultiProvider,MoProviderBuilder,moProvider,moProviderValue,moNotifierProvider,moNotifierProviderValue, andcontext.read/watch. WidgetLogicandMoLogic<T extends Model>(paired withMoLcWidget).SelectorMixin<T>forshouldRefreshshort-circuiting.InitialBuilder.reassemblecallback hook.
Fixes #
WidgetModel.disposedandWidgetLogic.disposedno longer probe element state. They returntrueonly afterdispose()has actually run (i.e._contextwas nulled, or the parentModel._disposedflag was set). This avoids the deactivate/reactivate window where the previous(DEFUNCT)check — and a brief experiment with!context.mounted— would falsely report the model as disposed and silently drop refreshes.WidgetModel.refresh<T>()now propagates the type parameter when recursing into the parent model:context.read<T>().refresh<T>().MoLogic.refreshdeclared with explicitvoidreturn; the type parameter was reverted to keep "refresh self" the only intent.Init,LogicInit<T>,ModelLogicInit<T, R>typedefs declared with explicitvoidreturn instead of bareFunction.EventConsumerMixin._idnow uses a monotonic counter instead of a boundedRandom().nextInt(10000), removing the birthday-paradox collision risk that could silently drop event listeners.ExposedMixinandEventConsumerMixincache theCoreContainerthey registered with, so dispose-time cleanup does not look up inherited ancestors while Flutter is deactivating the tree.ModelWidget.valuenow detachesWidgetModelcontext and removesExposedMixinregistrations when the widget unmounts without disposing the externally owned model.ExposedMixinnow tracks expose owners instead of a raw counter, preserving multi-mount.valuebehavior without leaking stale container registrations.ModelWidget.valuenow detachesEventConsumerMixinlisteners when the widget unmounts without disposing the externally owned model.TopProvidernow keeps itsGlobalKeyon the mounted state and exposes the active state through a single current pointer, avoiding a module-level global key collision path while preservingtop<T>().BuildContext.read<T>()now includes a hint that dispose-time ancestor lookup is unsafe.EventModel.refreshEventsnapshots listeners before invoking callbacks, so a refresh that changes event subscriptions cannot mutate the listener map during iteration.EventModelnow keys listeners by the event object instead ofevent.toString(), avoiding collisions between distinct events with the same string representation.ExposedMixin.find<T>()now usesTypekeys instead of stringified runtime type names;findFuzzy(String)remains available for string lookup.ExposedMixin.topLogicis deprecated and no longer prevents exposed cleanup during dispose, avoiding stale disposed logic instances infind<T>().Mutable._refreshMapnow keys on the_MutableStateobject directly instead of itshashCode, removing the rare hash-collision case where one widget's listener could overwrite another's.- Lint cleanup:
_InitialBuilderState→InitialBuilderState,_MUTABLE_SIZE→_mutableSize, rawSet()literals replaced with typed set literals, function-typed parameter syntax replaced withvoid Function()form,!(this is X && y)→this is! X || !y.
Repo / tooling #
- Added root
analysis_options.yamlincludingpackage:flutter_lints/flutter.yaml. .metadatachannel switched frombetatostable.- Added
dev_dependencies: flutter_lints: ^5.0.0. - Added widget tests for
ModelWidget,LogicWidget,MoLcWidget, native provider read/watch behavior, top models, exposed models, and event refresh. - Example app: dropped unused
getdependency, bumped SDK to Dart 3, bumpedflutter_lintsto^5.0.0.
0.1.6 #
- Synced from a previously released artifact; no new changelog was written at the time. See 0.2.0 for a retrospective summary of what was already shipping in this version.
0.0.2 #
- Initial public release.