SolidJS State Management
Relevant source files
The following files were used as context for generating this wiki page:
State management in Keynobi is primarily handled through SolidJS Stores, specifically utilizing createStore and produce. This architecture is designed to handle high-frequency updates (such as real-time logs) while maintaining UI performance and reactivity. The system follows a domain-driven approach where different aspects of the application (builds, health, settings, MCP) are managed by specialized stores.
Sources: AGENTS.md:12, README.md:Project Structure
Core Architectural Patterns
Keynobi employs a centralized but modular state management strategy. Each domain store manages its own state and provides specific actions to modify that state.
Store Creation and Mutation
The project uses createStore for complex nested state and createSignal for simple, atomic pieces of state. To maintain immutability and predictable updates, the produce utility is frequently used within store actions to perform granular updates to the state tree.
Sources: AGENTS.md:12, src/stores/build.store.ts:25-36
High-Frequency Data Handling
A critical feature of the state management system is the handling of streaming data, such as Gradle build logs. To prevent UI "flooding," the stores implement batching mechanisms. For instance, the build.store.ts uses a pending buffer and a 50ms flush interval to batch log entries before updating the reactive store.
Domain Store Implementations
The application state is partitioned into several key stores:
1. Build Store
Manages the lifecycle of Gradle builds, including execution phases, error/warning tracking, and log streaming.
| Field | Type | Description |
|---|---|---|
phase | BuildPhase | Current status (idle, running, success, etc.) |
errors | BuildError[] | List of errors captured from the build output |
history | BuildRecord[] | Persistent list of past build results |
deployPhase | DeployPhase | Current deployment step (installing, launching) |
Sources: src/stores/build.store.ts:10-23
2. Health Store
Combines reactive state derived from other stores with active results from system health checks (e.g., SDK path validation, Java version).
3. Settings Store
Handles application-wide configurations including Android SDK paths, UI font sizes, and MCP behavior. It supports persistence and resetting to defaults.
Sources: src/components/settings/SettingsPanel.tsx:120-200, README.md:Project Structure
Reactive Utilities and Derived State
The stores leverage SolidJS's createMemo to compute derived values that automatically update when underlying state changes.
- buildDurationMs: A reactive heartbeat that calculates elapsed time every second while a build is active. Sources: src/stores/build.store.ts:46-52
- overallHealth: Computes the system status based on the aggregation of multiple health checks (Android SDK, ADB, Java, etc.). Sources: src/stores/health.store.ts:182-188
- isBuilding / isDeploying: Simple boolean flags derived from
buildState.phaseandbuildState.deployPhase. Sources: src/stores/build.store.ts:56-57
State and IPC Integration
State management is tightly coupled with Tauri's IPC mechanism. Rust backend events are translated into store actions, and store actions often trigger backend commands.
- Rust to Store: The backend emits events (e.g.,
logcatentries) which are captured by listeners that call store mutation functions likeaddBuildLine. Sources: src/stores/build.store.ts:100-104 - Store to Rust: Actions like
clearBuildHistorycall typed wrappers intauri-api.ts, which then invoke Rust commands. Sources: src/stores/build.store.ts:153-156
The project uses ts-rs to generate TypeScript bindings from Rust models, ensuring that the data structures in the stores remain synchronized with the backend.
Sources: AGENTS.md:12, README.md:Key design decisions
Summary
Keynobi's use of SolidJS Stores provides a high-performance, reactive foundation for Android development tooling. By separating state into logical domains and implementing batching for high-frequency updates, the application ensures that the UI remains responsive even during heavy log streaming or complex build processes.