grove/Host/
mod.rs

1//! Host Module
2//!
3//! Provides the core extension hosting functionality for Grove.
4//! Manages extension lifecycle, activation, and API bridging.
5//!
6//! # Architecture
7//!
8//! ```text
9//! +++++++++++++++++++++++++++++++++++++++++++
10//! +         Extension Host                 +
11//! +++++++++++++++++++++++++++++++++++++++++++
12//! +  ExtensionHost  →  Main host controller+
13//! +  ExtensionMgr   →  Extension discovery  +
14//! +  Activation     →  Event handling       +
15//! +  Lifecycle      →  Lifecycle management +
16//! +  APIBridge      →  VS Code API proxy    +
17//! +++++++++++++++++++++++++++++++++++++++++++
18//!           +                    +
19//!           ▼                    ▼
20//! ++++++++++++++++++++  ++++++++++++++++++++
21//! +  WASM Runtime    +  +  Transport       +
22//! +  (Executes)      +  +  (Communicates)  +
23//! ++++++++++++++++++++  ++++++++++++++++++++
24//! ```
25//!
26//! # Key Components
27//!
28//! - [`ExtensionHost`] - Main extension host controller
29//! - [`ExtensionManager`] - Extension discovery and loading
30//! - [`Activation`] - Extension activation event handling
31//! - [`Lifecycle`] - Extension lifecycle management
32//! - [`APIBridge`] - VS Code API implementation bridge
33
34pub mod Activation;
35pub mod APIBridge;
36pub mod ExtensionHost;
37pub mod ExtensionManager;
38pub mod Lifecycle;
39
40// Re-exports for convenience - use module prefix to avoid E0255 conflicts
41pub use Activation::{ActivationEngine, ActivationEvent};
42pub use Lifecycle::{LifecycleEvent, LifecycleManager};
43// Note: ExtensionHost, ExtensionManager, APIBridge must be accessed via module prefix
44use anyhow::Result;
45
46/// Host configuration
47#[derive(Debug, Clone)]
48pub struct HostConfig {
49	/// Maximum number of concurrent extensions
50	pub max_extensions:usize,
51	/// Enable lazy activation
52	pub lazy_activation:bool,
53	/// Enable hot reloading
54	pub hot_reload:bool,
55	/// Extension discovery paths
56	pub discovery_paths:Vec<String>,
57	/// Enable API logging
58	pub api_logging:bool,
59	/// Activation timeout in milliseconds
60	pub activation_timeout_ms:u64,
61}
62
63impl Default for HostConfig {
64	fn default() -> Self {
65		Self {
66			max_extensions:100,
67			lazy_activation:true,
68			hot_reload:false,
69			discovery_paths:vec!["~/.vscode/extensions".to_string(), "~/.grove/extensions".to_string()],
70			api_logging:false,
71			activation_timeout_ms:30000,
72		}
73	}
74}
75
76impl HostConfig {
77	/// Create a new host configuration
78	pub fn new() -> Self { Self::default() }
79
80	/// Set maximum number of extensions
81	pub fn with_max_extensions(mut self, max:usize) -> Self {
82		self.max_extensions = max;
83		self
84	}
85
86	/// Enable or disable lazy activation
87	pub fn with_lazy_activation(mut self, enabled:bool) -> Self {
88		self.lazy_activation = enabled;
89		self
90	}
91
92	/// Enable or disable hot reloading
93	pub fn with_hot_reload(mut self, enabled:bool) -> Self {
94		self.hot_reload = enabled;
95		self
96	}
97
98	/// Set activation timeout
99	pub fn with_activation_timeout(mut self, timeout_ms:u64) -> Self {
100		self.activation_timeout_ms = timeout_ms;
101		self
102	}
103
104	/// Add a discovery path
105	pub fn add_discovery_path(mut self, path:String) -> Self {
106		self.discovery_paths.push(path);
107		self
108	}
109}
110
111/// Extension activation result
112#[derive(Debug, Clone)]
113pub struct ActivationResult {
114	/// Extension ID
115	pub extension_id:String,
116	/// Activation success
117	pub success:bool,
118	/// Activation time in milliseconds
119	pub time_ms:u64,
120	/// Error message if failed
121	pub error:Option<String>,
122	/// Contributed items
123	pub contributes:Vec<String>,
124}
125
126#[cfg(test)]
127mod tests {
128	use super::*;
129
130	#[test]
131	fn test_host_config_default() {
132		let config = HostConfig::default();
133		assert_eq!(config.max_extensions, 100);
134		assert_eq!(config.lazy_activation, true);
135	}
136
137	#[test]
138	fn test_host_config_builder() {
139		let config = HostConfig::default()
140			.with_max_extensions(50)
141			.with_lazy_activation(false)
142			.with_activation_timeout(60000);
143
144		assert_eq!(config.max_extensions, 50);
145		assert_eq!(config.lazy_activation, false);
146		assert_eq!(config.activation_timeout_ms, 60000);
147	}
148
149	#[test]
150	fn test_activation_result() {
151		let result = ActivationResult {
152			extension_id:"test.ext".to_string(),
153			success:true,
154			time_ms:100,
155			error:None,
156			contributes:vec!["command.test".to_string()],
157		};
158
159		assert_eq!(result.extension_id, "test.ext");
160		assert!(result.success);
161		assert_eq!(result.contributes.len(), 1);
162	}
163}