Data Flow & State Management
ShonenX embraces a unidirectional data flow powered strictly by Riverpod.
State Management
State is initialized and exposed via Notifier and AsyncNotifier implementations inside a feature's providers/ directory.
- UI Consumption:
ConsumerWidgetandConsumerStatefulWidgetare used to bind to providers. The presentation layer never instantiates engine classes directly. - Dependency Injection: Providers are used to inject shared dependencies (e.g.,
sharedPreferencesProvider,databaseProvider) into feature-specific engines.
Example Flow
- User Action: The user taps a "Refresh Library" button.
- Provider Invocation: The UI calls
ref.read(libraryProvider.notifier).refresh(). - Engine Execution: The
LibraryNotifierdelegates the complex synchronization logic toLibraryEngine. - State Mutation: The
LibraryEnginecompletes the fetch and returns the data. TheLibraryNotifierupdates its state (state = AsyncData(newData)). - UI Rebuild: The UI, watching
libraryProvider, automatically rebuilds with the new data.
Persistence
Isar acts as the local source of truth for caching, library entries, and user history.
- Models that require persistence are annotated with
@collection. - When models are modified, you must regenerate the Isar schemas using
dart run build_runner build -d. - Database initialization occurs in
app_init.dart, which opens the instance and executes any necessary data migrations before the UI mounts.