moose_core 2.3.0
moose_core: ^2.3.0 copied to clipboard
Core architecture for modular Flutter e-commerce applications with plugin-based architecture, repository pattern, and configurable UI sections.
Changelog #
All notable changes to moose_core will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
2.3.0 - 2026-03-19 #
Changed #
WidgetRegistry— unified registry (breaking):AddonRegistryhas been merged intoWidgetRegistry. There is now a single registry for all dynamic UI composition.registerSection(name, SectionBuilderFn, {int priority = 0})— registers aFeatureSectionbuilder (renamed fromregister)registerWidget(name, WidgetBuilderFn, {int priority = 0})— registers a plainWidget?builder (replacesAddonRegistry.register)buildAll(name, context, {data, onEvent})→List<Widget>— builds all registered builders for a key, filtered and priority-ordered (replacesAddonRegistry.build)build(name, context, {data, onEvent})— unchanged; returns first non-null widget- Both registration methods write to the same internal
Map<String, List<_Entry>>, sobuildandbuildAllwork across bothregisterSectionandregisterWidgetregistrations - Priority controls ordering in both methods: higher priority = earlier in result
Removed #
AddonRegistry— deleted. UseWidgetRegistry.registerWidgetandWidgetRegistry.buildAllinstead.MooseAppContext.addonRegistryfield — removed.widgetRegistryis now the unified registry.MooseScope.addonRegistryOf()static accessor — removed.FeaturePlugin.addonRegistryconvenience getter — removed.
Migration #
// Before
addonRegistry.register('slot', builder, priority: 10);
addonRegistry.build('slot', context, data: {...});
widgetRegistry.register('key', sectionBuilder);
// After
widgetRegistry.registerWidget('slot', builder, priority: 10);
widgetRegistry.buildAll('slot', context, data: {...});
widgetRegistry.registerSection('key', sectionBuilder);
2.2.0 - 2026-03-18 #
Added #
package:moose_core/ui.dart— new barrel export providing hook-calling style facades (AppTextStyles,AppButtonStyles,AppInputStyles). Plugins import this instead of app-level style files, keeping styles swappable via the hook registry.AppTextStyles— facade class with 12 static methods (appBarTitle,sectionHeader,formLabel,screenTitle,modalTitle,bodySecondary,hint,caption,sectionLabel,bodyMedium,bodyLarge,bodyXLarge). Each delegates to thestyles:texthook registered by the active palette plugin.AppButtonStyles— facade class delegatingprimary,primaryCompact,secondary,secondaryCompactto thestyles:buttonhook.labelStyle()is a context-free static.AppInputStyles— facade class delegatingoutlinedandfilledto thestyles:inputhook.
2.1.0 - 2026-03-17 #
Added #
StoreRepository.getStoreLocale()— returns the currently active store locale (language code, e.g.'en','ja'); returnsnullif locale selection is not supported by the backend.StoreRepository.setStoreLocale(String languageCode)— persists the locale preference on the backend if possible (e.g. updates a customer's language preference); returns the accepted locale code ornullif not supported.FeaturePlugin.onInit()now has a default empty body — plugins that don't need async initialisation no longer need to override it.
Changed #
AuthRepository—signOut()is now implemented across all built-in adapters.
2.0.0 - 2026-03-12 #
Breaking Changes #
BackendAdapterrepository storage redesigned. The four separate maps (_factories,_cache,_namedEntries,_namedCache) are replaced by a singleMap<Type, List<_RepoEntry>>structure. EachregisterRepositoryFactorycall is now automatically tagged with the adapter's ownnameas provider — no separate named-registration step is needed.registerNamedRepositoryFactory<T>()removed. UseregisterRepositoryFactory<T>()— the entry is auto-tagged with the adapter'sname.NamedRepositoryEntryclass removed.getRepositoryByType(Type)removed fromBackendAdapter. UsegetRepository<T>()instead.getNamedRepositoryByType(Type, String)removed. UsegetRepository<T>(provider: name).namedRepositoryEntriesgetter removed.getRepository<T>()andgetRepositoryAsync<T>()now take an optional namedproviderparameter instead of a positional one. Call sites usinggetRepository<T>('shopify')must be updated togetRepository<T>(provider: 'shopify').hasRepository<T>(),isRepositoryCached<T>(), andclearRepositoryCache<T>()now take{String? provider}instead of no parameter.AdapterRegistryinternal maps simplified._namedFactoriesand_namedInstancesremoved; delegation now goes directly to each adapter.
Added #
AuthRepository.getOAuthRedirectUri()— default implementation returns''; override in OAuth-capable adapters to return the full redirect URI (non-empty activates in-app WebView mode inOAuthLoginScreen).AuthRepository.getOAuthAuthorizationUrl()andAuthRepository.exchangeOAuthCode()— OAuth 2.0 PKCE base methods withUnsupportedErrordefaults.- Provider-scoped repository retrieval:
appContext.getRepository<AuthRepository>(provider: 'shopify')returns the entry registered by the adapter whosename == 'shopify'. - All repositories registered via
registerRepositoryFactoryare now automatically reachable by provider name (e.g.getRepository<ProductsRepository>(provider: 'shopify')).
1.4.0 - 2026-03-04 #
[1.4.0] - 2026-03-04 #
Added #
-
MooseApp(package:moose_core/app.dart): A self-contained root widget that handles the full bootstrap lifecycle. Passconfig,adapters,plugins, and abuildercallback —MooseAppcreatesMooseAppContext, wraps the tree inMooseScope, runsMooseBootstrapper, and shows a loading indicator until bootstrap completes. SupplyloadingWidgetto replace the default spinner.runApp( MooseApp( config: config, adapters: [WooCommerceAdapter()], plugins: [() => ProductsPlugin(), () => CartPlugin()], builder: (context, appContext) => MyApp(appContext: appContext), ), );This eliminates the boilerplate
_AppBootstrapStatefulWidget previously required in every app'smain.dart.
1.3.1 - 2026-03-04 #
Changed #
- Documentation-only release. Rewrote all
lib/src/app/doc comments to Flutter SDK standard. No API changes.
1.2.0 - 2026-02-27 #
Breaking Changes #
FeaturePlugin.initialize()renamed toFeaturePlugin.onInit(): Plugin implementations must now overrideonInit()instead ofinitialize().PluginRegistry.initializeAll()renamed toPluginRegistry.initAll().
Added #
- Plugin lifecycle hooks on
FeaturePlugin:onStart()— called after all plugins completeonInit()onStop()— called during teardownonAppLifecycle(AppLifecycleState)— receives app foreground/background transitions
PluginRegistry.startAll()andPluginRegistry.stopAll()lifecycle orchestration APIs.PluginRegistry.notifyAppLifecycle()for dispatching Flutter lifecycle changes to plugins.MooseLifecycleObserver(package:moose_core/app.dart) to forwardWidgetsBindingObserverlifecycle events into plugin lifecycle callbacks.
1.1.0 - 2026-02-26 #
Breaking Changes #
BackendAdapter.initializeFromConfig():configManagerparameter is now named and required —({required ConfigManager configManager}). No global fallback exists.MooseBootstrapperpasses the scoped instance automatically; callers that invokedinitializeFromConfig()directly (without the parameter) must now pass the scopedConfigManagerexplicitly.
Changed #
AdapterRegistry: Repository registration is now fully lazy. CallingregisterAdapter()stores factory closures but creates no repository instances. Instances are created on the firstgetRepository<T>()call and cached thereafter. This eliminates all eager repository construction during app startup.AdapterRegistry: Removed theConfigManager()fallback inregisterAdapter(). Adapter defaults are only registered when a scopedConfigManagerhas been injected viasetDependencies(). CallingregisterAdapter(autoInitialize: true)without a priorsetDependencies()call now throws a clearStateError.
Added #
MooseAppContext.getRepository<T>(): Convenience shortcut that delegates toadapterRegistry.getRepository<T>(). Simplifies access from plugins and tests.test/app/moose_app_context_test.dart: New test file covering context isolation, scoped dependency wiring, lazy repository access, and constructor injection.
1.0.0 - 2026-02-22 #
Breaking Changes #
- Singletons removed: Global singleton constructors removed from all registry and
manager classes.
WidgetRegistry(),HookRegistry(),AddonRegistry(),ActionRegistry(),AdapterRegistry(),EventBus(),PluginRegistry(), andConfigManager()no longer return a shared instance — each call creates a new independent object. MooseAppContextreplaces singletons: All registries are now owned by aMooseAppContextinstance. Construct one at app startup and expose viaMooseScope.CoreRepositoryconstructor: Now requires{required HookRegistry hookRegistry, required EventBus eventBus}named parameters. All concrete subclasses must forward viasuper.FeaturePluginfield injection: Registry fields (hookRegistry,addonRegistry,widgetRegistry,adapterRegistry,actionRegistry,eventBus) are now getters delegating to an injectedappContextset byPluginRegistry.register().PluginRegistry:registerPlugin()split into syncregister(plugin, {required appContext})and asyncinitializeAll().FeatureSection.adaptersgetter removed: Replaced byadaptersOf(BuildContext)method. Call insidebuild(context).BackendAdapter:hookRegistryandeventBusare now settable fields (set byAdapterRegistrybeforeinitializeFromConfig). Method signature changed toFuture<void> initializeFromConfig({ConfigManager? configManager}).AppNavigator: No longer holds a static singletonEventBus. CallAppNavigator.setEventBus(eventBus)before navigation (done automatically byMooseBootstrapper).
Added #
MooseAppContext(package:moose_core/app.dart): App-scoped container owning all registries. Supports optional constructor parameters for testing and DI.MooseScope(package:moose_core/app.dart):InheritedWidgetthat exposesMooseAppContextdown the widget tree. Use thecontext.mooseextension from any widget to access registries.MooseBootstrapper(package:moose_core/app.dart): Orchestrates 5-step startup (config → EventBus wiring → adapters → plugin registration → plugin initialization) and returns aBootstrapReportwith per-plugin timings and failure details.BootstrapReport: ExposestotalTime,pluginTimings,failures,succeeded.UnknownSectionWidget(package:moose_core/widgets.dart): Displayed in debug mode whenWidgetRegistry.build()is called with an unregistered section name.WidgetRegistry.setConfigManager()andAdapterRegistry.setDependencies(): Post-construction wiring methods used internally byMooseAppContext.- New barrel
lib/app.dart, re-exported fromlib/moose_core.dart.
0.1.3 - 2026-02-18 #
Fixed #
- Raised
json_schemaminimum constraint to>=5.2.2to prevent downgrade analysis failure (instancePathnullable in older versions) - Added
context.mountedguards inAppNavigatorbefore usingBuildContextafter async gaps
0.1.2 - 2026-02-18 #
Fixed #
- Updated
intlconstraint from^0.19.0to^0.20.2to support latest stable version - Fixed angle-bracket HTML warnings in
PostRepositoryandReviewRepositorydoc comments
0.1.1 - 2026-02-18 #
Changed #
- Comprehensive documentation update for all AI-ready docs in
doc/ai-ready/
Fixed #
- Corrected file paths throughout documentation (
lib/core/→lib/src/) - Fixed
WidgetRegistrytypedef:SectionBuilderFn = FeatureSection Function(...)(was incorrectly documented as returningWidget) - Fixed
buildSectionGroupsignature to use named parameterspluginNameandgroupName - Fixed
EventBususage examples to reflect string-based pub/sub API (not typed events) - Fixed
FeatureSection.getSetting<T>()exception documentation to match actualExceptiontype - Fixed GitHub organisation in README URLs (
your-org→greymooseinc) - Fixed
BackendAdapter.initialize()signature to includeMap<String, dynamic> configparameter - Fixed
CacheManagerAPI documentation to reflect static factory methods - Fixed
AdapterRegistryAPI: removed non-existentgetRepositoryAsync(); addedgetAvailableRepositories(),getInitializedAdapters(),clearAll()
Added #
- Full
AddonRegistrydocumentation indoc/ai-ready/REGISTRIES.md(purpose, API, slot naming, best practices) AddonRegistryentries inai/blueprint.json(templates, checklist rules, add-addon example walkthrough)
0.1.0 - 2025-12-01 #
Added #
CartAmountentity for flexible cart line items (shipping, tax, discount fees)MediaItementity with multi-media support (image, video) and thumbnail variantsShippingMethodandPaymentMethodtypes inCartRepositoryPaymentResult,PaymentStatus,RefundResult, andCartValidationResultinCartRepositoryCheckoutResultwith redirect URL support for external payment flowsShortsRepositoryandShortentity for short-form video contentBannerRepositoryandPromoBannerentityStoreRepositoryfor multi-store supportLocationRepositorywithAddress,Country, andPostalCodeentitiesReviewRepositoryas a standalone interface separate fromProductsRepositoryAddonRegistryfor UI extension points inFeatureSectionEventBusasynchronous publish-subscribe system for inter-plugin communicationBackendAdapter.initializeFromConfig()for automatic configuration loading fromConfigManager- JSON Schema validation in
BackendAdapter.validateConfig()via thejson_schemapackage PluginRegistrybottom tab management withbottomTabshook registrationAppNavigatorservice for plugin-agnostic navigationCurrencyFormatterutility for locale-aware currency displayAdapterRegistryrepository-level management (last-registered-wins model)FeaturePlugin.configSchemaandBackendAdapter.configSchemafor configuration validation- Platform support declarations for Android, iOS, web, Windows, macOS, and Linux
- Comprehensive
///API documentation on all public classes and methods - AI-ready documentation in
docs/ai-ready/covering all architectural patterns
Changed #
AdapterRegistryredesigned from "active adapter" model to repository-level registrationCartentity now includesamountslist replacing fixed fee fieldsCartRepositoryexpanded with full payment, order, and checkout lifecycle methodsProductsRepositorysplit: review methods moved toReviewRepository
0.0.1 - 2025-06-01 #
Added #
- Initial release of the moose_core package
- Plugin-based architecture with
FeaturePluginandPluginRegistry - Repository pattern with
CoreRepositorybase class and interfaces for products, cart, auth, posts, search, and push notifications - Backend adapter pattern with
BackendAdapterandAdapterRegistry FeatureSectionpattern for configurable UI sections with default settingsWidgetRegistryfor dynamic widget composition and registrationHookRegistrysynchronous data transformation system for inter-plugin hooksActionRegistryfor custom user interaction handlingCacheManagerwithMemoryCacheandPersistentCache(TTL support)ConfigManagerfor JSON-based external configurationApiClientbuilt on Dio with configurable interceptors- Core domain entities:
Product,Category,Cart,CartItem,Order,Checkout,User,ProductVariation,ProductAttribute,ProductFilters,ProductSortOption - Modular library structure:
entities,repositories,plugin,widgets,adapters,cache,services - BLoC-ready architecture with
flutter_blocintegration