mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-31 00:10:22 +08:00
- Revised the README files for shared data and main data layers to improve clarity and structure. - Consolidated documentation on shared data types and API types, removing the now-deleted `api-design-guidelines.md`. - Streamlined directory structure descriptions and updated links to relevant documentation. - Enhanced quick reference sections for better usability and understanding of the data architecture.
6.7 KiB
6.7 KiB
Preference System Overview
The Preference system provides centralized management for user configuration and application settings with cross-window synchronization.
Purpose
PreferenceService handles data that:
- Is a user-modifiable setting that affects app behavior
- Has a fixed key structure with stable value types
- Needs to persist permanently until explicitly changed
- Should sync automatically across all application windows
Key Characteristics
Fixed Key Structure
- Predefined keys in the schema (users modify values, not keys)
- Supports 158 configuration items
- Nested key paths supported (e.g.,
app.theme.mode)
Atomic Values
- Each preference item represents one logical setting
- Values are typically: boolean, string, number, or simple array/object
- Changes are independent (updating one doesn't affect others)
Cross-Window Synchronization
- Changes automatically broadcast to all windows
- Consistent state across main window, mini window, etc.
- Conflict resolution handled by Main process
Update Strategies
Optimistic Updates (Default)
// UI updates immediately, then syncs to database
await preferenceService.set('app.theme.mode', 'dark')
- Best for: frequent, non-critical settings
- Behavior: Local state updates first, then persists
- Rollback: Automatic revert if persistence fails
Pessimistic Updates
// Waits for database confirmation before updating UI
await preferenceService.set('api.key', 'secret', { optimistic: false })
- Best for: critical settings (API keys, security options)
- Behavior: Persists first, then updates local state
- No rollback needed: UI only updates on success
Architecture Diagram
┌─────────────────────────────────────────────────────────────┐
│ Renderer Process │
│ ┌─────────────────────────────────────────────────┐ │
│ │ usePreference Hook │ │
│ │ - Subscribe to preference changes │ │
│ │ - Optimistic/pessimistic update support │ │
│ └──────────────────────┬──────────────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ PreferenceService (Renderer) │ │
│ │ - Local cache for fast reads │ │
│ │ - IPC proxy to Main process │ │
│ │ - Subscription management │ │
│ └──────────────────────┬──────────────────────────┘ │
└─────────────────────────┼────────────────────────────────────┘
│ IPC
┌─────────────────────────┼────────────────────────────────────┐
│ Main Process ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ PreferenceService (Main) │ │
│ │ - Full memory cache of all preferences │ │
│ │ - SQLite persistence via Drizzle ORM │ │
│ │ - Cross-window broadcast │ │
│ └──────────────────────┬──────────────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ SQLite Database (preference table) │ │
│ │ - scope + key structure │ │
│ │ - JSON value storage │ │
│ └─────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
Main vs Renderer Responsibilities
Main Process PreferenceService
- Source of truth for all preferences
- Full memory cache for fast access
- SQLite persistence via preference table
- Broadcasts changes to all renderer windows
- Handles batch operations and transactions
Renderer Process PreferenceService
- Local cache for read performance
- Proxies write operations to Main
- Manages React hook subscriptions
- Handles optimistic update rollbacks
- Listens for cross-window updates
Database Schema
Preferences are stored in the preference table:
// Simplified schema
{
scope: string // e.g., 'default', 'user'
key: string // e.g., 'app.theme.mode'
value: json // The preference value
createdAt: number
updatedAt: number
}
Preference Categories
Application Settings
- Theme mode, language, font sizes
- Window behavior, startup options
Feature Toggles
- Show/hide UI elements
- Enable/disable features
User Customization
- Keyboard shortcuts
- Default values for operations
Provider Configuration
- AI provider settings
- API endpoints and tokens
Usage Summary
For detailed code examples and API usage, see Preference Usage Guide.
| Operation | Hook | Service Method |
|---|---|---|
| Read single | usePreference(key) |
preferenceService.get(key) |
| Write single | setPreference(value) |
preferenceService.set(key, value) |
| Read multiple | usePreferences([...keys]) |
preferenceService.getMultiple([...keys]) |
| Write multiple | - | preferenceService.setMultiple({...}) |