Component-Database Relations
Understanding how MonoTerm’s components interact with databases.Copy
╔═════════════════════════════════════════════════════════════════════╗
║ COMPONENT-DATABASE OVERVIEW ║
╠═════════════════════════════════════════════════════════════════════╣
║ ║
║ DAEMON LAYER DATABASE LAYER ║
║ ┌─────────────────┐ ┌─────────────────┐ ║
║ │ PTY Daemon │────Unix─────▶│ No direct DB │ ║
║ │ (pty-daemon- │ Socket │ Pure I/O only │ ║
║ │ rust) │ └─────────────────┘ ║
║ └─────────────────┘ ║
║ ║
║ ┌─────────────────┐ ┌─────────────────┐ ║
║ │ File Watcher │──rusqlite───▶│ niia-watcher.db │ ║
║ │ (niia-watcher) │ direct │ File events │ ║
║ └─────────────────┘ └─────────────────┘ ║
║ ║
║ RUST BACKEND ║
║ ┌─────────────────┐ ┌─────────────────┐ ║
║ │ SessionActor │──rusqlite───▶│ session.db │ ║
║ │ (lib.rs) │ │ Terminal state │ ║
║ └─────────────────┘ └─────────────────┘ ║
║ ║
║ ┌─────────────────┐ ┌─────────────────┐ ║
║ │ PTY Log │──rusqlite───▶│ atomic-term.db │ ║
║ │ (VTE Parser) │ │ Activity logs │ ║
║ └─────────────────┘ └─────────────────┘ ║
║ ║
╚═════════════════════════════════════════════════════════════════════╝
Write Access Matrix
Which components can write to which databases.Copy
╔════════════════════════════════════════════════════════════════════╗
║ WRITE ACCESS MATRIX ║
╠════════════════════════════════════════════════════════════════════╣
║ ║
║ │ atomic- │ session │ onit │ niia- │ work-wiki ║
║ COMPONENT │ term.db │ .db │ .db │ watcher │ -diff.db ║
║ ════════════════│═════════│═════════│═══════│═════════│═══════════║
║ PTY Daemon │ - │ - │ - │ - │ - ║
║ (No DB access) │ │ │ │ │ ║
║ ────────────────│─────────│─────────│───────│─────────│───────────║
║ Rust Backend │ Yes │ Yes │ Yes │ - │ Yes ║
║ (SessionActor) │ │ │ │ │ ║
║ ────────────────│─────────│─────────│───────│─────────│───────────║
║ File Watcher │ - │ - │ - │ Yes │ - ║
║ (Daemon) │ │ │ │ direct │ ║
║ ║
║ Legend: Yes = Write access, - = No access ║
║ ║
╚════════════════════════════════════════════════════════════════════╝
Terminal Input to Activity Log
How user input becomes a logged activity.Copy
╔═════════════════════════════════════════════════════════════════════╗
║ TERMINAL INPUT ──▶ ACTIVITY LOG ║
╠═════════════════════════════════════════════════════════════════════╣
║ ║
║ You Type Command ║
║ │ ║
║ ▼ ║
║ ┌─────────────────┐ ║
║ │ xterm.js │ Frontend terminal display ║
║ └─────────────────┘ ║
║ │ ║
║ │ Tauri IPC ║
║ ▼ ║
║ ┌─────────────────┐ ║
║ │ SessionActor │ Rust backend ║
║ │ (lib.rs) │ Routes to PTY ║
║ └─────────────────┘ ║
║ │ ║
║ │ Unix Socket ║
║ ▼ ║
║ ┌─────────────────┐ ║
║ │ PTY Daemon │ Sends to shell ║
║ └─────────────────┘ ║
║ │ ║
║ │ Shell executes, returns output ║
║ ▼ ║
║ ┌─────────────────┐ ┌─────────────────┐ ║
║ │ VTE Parser │────▶│ Activity Log │ ║
║ │ (Alacritty) │ │ (atomic-term.db)│ ║
║ └─────────────────┘ └─────────────────┘ ║
║ │ ║
║ │ ACK Handshake ║
║ ▼ ║
║ ┌─────────────────┐ ║
║ │ xterm.js │ Display updated ║
║ └─────────────────┘ ║
║ ║
╚═════════════════════════════════════════════════════════════════════╝
File Change to UI Update
How file system changes appear in the UI.Copy
╔═════════════════════════════════════════════════════════════════════╗
║ FILE CHANGE ──▶ UI UPDATE ║
╠═════════════════════════════════════════════════════════════════════╣
║ ║
║ File Created/Modified/Deleted ║
║ │ ║
║ │ OS Event (FSEvents/inotify) ║
║ ▼ ║
║ ┌─────────────────────────────────────────────────────────────┐ ║
║ │ File Watcher Daemon (Sidecar) │ ║
║ │ │ ║
║ │ Rust notify crate │ ║
║ │ │ │ ║
║ │ │ Debounce (100ms) │ ║
║ │ ▼ │ ║
║ │ Direct rusqlite write (NO IPC overhead) │ ║
║ │ │ │ ║
║ │ ▼ │ ║
║ │ niia-watcher.db │ ║
║ └─────────────────────────────────────────────────────────────┘ ║
║ ║
║ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ║
║ Async Polling (every 3-5s) ║
║ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ║
║ ║
║ Frontend polls for new events ║
║ │ ║
║ │ Tauri invoke() ║
║ ▼ ║
║ SELECT * FROM file_events WHERE timestamp > last_check ║
║ │ ║
║ ▼ ║
║ UI Updates with new file events ║
║ ║
╚═════════════════════════════════════════════════════════════════════╝
Session Lifecycle
Four phases of a terminal session.Copy
╔═════════════════════════════════════════════════════════════════════╗
║ SESSION LIFECYCLE ║
╠═════════════════════════════════════════════════════════════════════╣
║ ║
║ PHASE 1: APP LAUNCH ║
║ ┌───────────────────────────────────────────────────────────────┐ ║
║ │ 1. Read saved state from session.db │ ║
║ │ 2. Start PTY Daemon (3-retry pattern) │ ║
║ │ 3. Recover orphaned sessions (reconnect to alive PTYs) │ ║
║ │ 4. Restore document tabs │ ║
║ └───────────────────────────────────────────────────────────────┘ ║
║ ║
║ PHASE 2: ACTIVE SESSION ║
║ ┌───────────────────────────────────────────────────────────────┐ ║
║ │ - Terminal Activity: User Input ──▶ PTY ──▶ Activity Log │ ║
║ │ - Heartbeat (every 10s): UPDATE terminal_heartbeats │ ║
║ │ - Project Switch: Track project associations │ ║
║ └───────────────────────────────────────────────────────────────┘ ║
║ ║
║ PHASE 3: TAB CLOSE ║
║ ┌───────────────────────────────────────────────────────────────┐ ║
║ │ - Terminal: Mark session inactive (is_active=0) │ ║
║ │ - Clean up resources │ ║
║ └───────────────────────────────────────────────────────────────┘ ║
║ ║
║ PHASE 4: APP CLOSE ║
║ ┌───────────────────────────────────────────────────────────────┐ ║
║ │ - Save state to session.db │ ║
║ │ - PTY Daemon: Stays running (detached, crash-resilient) │ ║
║ │ - File Watcher: Stays running (detached) │ ║
║ └───────────────────────────────────────────────────────────────┘ ║
║ ║
╚═════════════════════════════════════════════════════════════════════╝
Cross-Database Sync Points
When data moves between databases.Copy
╔═════════════════════════════════════════════════════════════════════╗
║ CROSS-DATABASE SYNC ║
╠═════════════════════════════════════════════════════════════════════╣
║ ║
║ SYNC POINT SOURCE ──▶ TARGET TRIGGER ║
║ ═══════════════════════════════════════════════════════════════ ║
║ ║
║ Terminal State Rust Backend Session ║
║ ──▶ create/destroy║
║ session.db ║
║ ║
║ Activity Logs atomic-term.db Activity ║
║ ──▶ detected ║
║ onit.db ║
║ ║
║ File Events niia-watcher.db Periodic ║
║ ──▶ (30s) ║
║ onit.db ║
║ ║
║ Path Resolution niia-watcher.db Relative ║
║ ──▶ path lookup ║
║ atomic-term.db ║
║ ║
╚═════════════════════════════════════════════════════════════════════╝
Write Optimization Patterns
How writes are optimized for performance.Copy
╔═════════════════════════════════════════════════════════════════════╗
║ WRITE OPTIMIZATION PATTERNS ║
╠═════════════════════════════════════════════════════════════════════╣
║ ║
║ PATTERN A: Direct Write (Highest Performance) ║
║ ┌───────────────────────────────────────────────────────────────┐ ║
║ │ Use Case: High-frequency events (file watcher) │ ║
║ │ Method: rusqlite direct connection │ ║
║ │ Example: File Watcher ──▶ niia-watcher.db │ ║
║ └───────────────────────────────────────────────────────────────┘ ║
║ ║
║ PATTERN B: Batched Write (Balanced) ║
║ ┌───────────────────────────────────────────────────────────────┐ ║
║ │ Use Case: Medium-frequency events (PTY log) │ ║
║ │ Method: Batch 10 items OR flush every 100ms │ ║
║ │ Example: PTY Log ──▶ atomic-term.db │ ║
║ └───────────────────────────────────────────────────────────────┘ ║
║ ║
║ PATTERN C: Deferred Write (Debounced) ║
║ ┌───────────────────────────────────────────────────────────────┐ ║
║ │ Use Case: Low-frequency events (window state) │ ║
║ │ Method: Debounce 500ms before write │ ║
║ │ Example: Window resize ──▶ session.db │ ║
║ └───────────────────────────────────────────────────────────────┘ ║
║ ║
╚═════════════════════════════════════════════════════════════════════╝
Design Principles Applied
Copy
╔═════════════════════════════════════════════════════════════════════╗
║ DESIGN PRINCIPLES ║
╠═════════════════════════════════════════════════════════════════════╣
║ ║
║ SIMPLICITY (SMPC) ║
║ ┌───────────────────────────────────────────────────────────────┐ ║
║ │ [x] PTY Daemon = No DB access (pure I/O passthrough) │ ║
║ │ [x] VTE Parser = Transform only (no persistence logic) │ ║
║ │ [x] Direct path: Event ──▶ Daemon ──▶ DB │ ║
║ └───────────────────────────────────────────────────────────────┘ ║
║ ║
║ ORDER FROM CHAOS (OFAC) ║
║ ┌───────────────────────────────────────────────────────────────┐ ║
║ │ [x] Daemons survive app crash (detached processes) │ ║
║ │ [x] 3-retry pattern for daemon startup │ ║
║ │ [x] WAL mode for concurrent access │ ║
║ │ [x] Separate DBs per domain (isolation) │ ║
║ └───────────────────────────────────────────────────────────────┘ ║
║ ║
╚═════════════════════════════════════════════════════════════════════╝
Quick Reference
| Component | DB Access | Key Pattern |
|---|---|---|
| PTY Daemon | None | Pure I/O passthrough |
| VTE Parser | None | Transform only |
| PTY Log | 1 DB Write | atomic-term.db |
| File Watcher | 1 DB Write | Detached daemon |
| OnIt Sidebar | 4 DBs Read | Aggregation view |