Architecture
Novon is built using the Flutter framework and utilizes a modular, feature-based architecture. State management is handled through Riverpod with a focus on immutability and high-performance reactive updates.
Technical Stack
- Framework: Flutter 3.22 (Stable)
- State Management: Riverpod 2.0 (Code Generation)
- Persistence Layer: Drift (SQLite) for large-scale data and Hive for rapid configuration caching.
- Network Stack: Dio with custom interceptors for proxying and security bypasses.
- JavaScript Runtime:
flutter_js(QuickJS) running in dedicated isolates.
Layered Design
The codebase residing in lib/ is organized into five primary layers to maintain a clean separation of concerns.
1. Core Layer (lib/core/)
Defines the enterprise business models and contracts.
models/: Immutable data classes generated withFreezed(e.g.,Novel,Chapter).repositories/: Abstract interface definitions for data handling.
2. Data Layer (lib/data/)
Handles all external I/O operations and provides concrete implementations for core repositories.
database/: Contains the Drift SQL schema definitions.network/: Logic for theDioFactory, including cookie management and domain whitelisting.services/: The high-level processing engines:ExtensionEngine,BackupService, andStoragePathService.
3. Providers Layer (lib/providers/)
Serves as the glue between the Data and Presentation layers.
- Uses
@riverpodannotations to generate reactive states. - Caches domain models and exposes
AsyncValuestreams to the UI.
4. Features Layer (lib/features/)
The interactive user interface. This is strictly organized by business feature (e.g., browse/, library/, reader/, settings/).
- Contains Flutter Widgets and Feature Controllers.
- Only interacts with data through Riverpod providers to ensure UI stability.
5. Runtime Layer (lib/runtime/)
Handles the low-level bootstrapping of the JavaScript sandbox and native platform channels.
Extension Lifecycle
The ExtensionEngine (lib/data/services/extension_engine.dart) manages the runtime lifecycle for every community-maintained source.
- Discovery: Scans the local extensions directory and parses
manifest.jsonfiles into a rapid Hive cache. - Bootstrapping: Spawns an isolated
Isolatecontaining a QuickJS runtime for the target source. - Binding: Injects the
http,console, andparseHtmlbridge functions into the JS memory space. - Evaluation: Executes
source.jsand registers critical methods (likefetchPopular) to the internal__novonExtensionobject for future calls.