Skip to main content

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;
35
36pub mod APIBridge;
37
38pub mod ExtensionHost;
39
40pub mod ExtensionManager;
41
42pub mod Lifecycle;
43
44/// Host configuration
45#[derive(Debug, Clone)]
46pub struct HostConfig {
47	/// Maximum number of concurrent extensions
48	pub max_extensions:usize,
49
50	/// Enable lazy activation
51	pub lazy_activation:bool,
52
53	/// Enable hot reloading
54	pub hot_reload:bool,
55
56	/// Extension discovery paths
57	pub discovery_paths:Vec<String>,
58
59	/// Enable API logging
60	pub api_logging:bool,
61
62	/// Activation timeout in milliseconds
63	pub activation_timeout_ms:u64,
64}
65
66impl Default for HostConfig {
67	fn default() -> Self {
68		Self {
69			max_extensions:100,
70
71			lazy_activation:true,
72
73			hot_reload:false,
74
75			discovery_paths:vec!["~/.vscode/extensions".to_string(), "~/.grove/extensions".to_string()],
76
77			api_logging:false,
78
79			activation_timeout_ms:30000,
80		}
81	}
82}
83
84impl HostConfig {
85	/// Create a new host configuration
86	pub fn new() -> Self { Self::default() }
87
88	/// Set maximum number of extensions
89	pub fn with_max_extensions(mut self, max:usize) -> Self {
90		self.max_extensions = max;
91
92		self
93	}
94
95	/// Enable or disable lazy activation
96	pub fn with_lazy_activation(mut self, enabled:bool) -> Self {
97		self.lazy_activation = enabled;
98
99		self
100	}
101
102	/// Enable or disable hot reloading
103	pub fn with_hot_reload(mut self, enabled:bool) -> Self {
104		self.hot_reload = enabled;
105
106		self
107	}
108
109	/// Set activation timeout
110	pub fn with_activation_timeout(mut self, timeout_ms:u64) -> Self {
111		self.activation_timeout_ms = timeout_ms;
112
113		self
114	}
115
116	/// Add a discovery path
117	pub fn add_discovery_path(mut self, path:String) -> Self {
118		self.discovery_paths.push(path);
119
120		self
121	}
122}
123
124/// Extension activation result
125#[derive(Debug, Clone)]
126pub struct ActivationResult {
127	/// Extension ID
128	pub extension_id:String,
129
130	/// Activation success
131	pub success:bool,
132
133	/// Activation time in milliseconds
134	pub time_ms:u64,
135
136	/// Error message if failed
137	pub error:Option<String>,
138
139	/// Contributed items
140	pub contributes:Vec<String>,
141}
142
143#[cfg(test)]
144mod tests {
145
146	use super::*;
147
148	#[test]
149	fn test_host_config_default() {
150		let config = HostConfig::default();
151
152		assert_eq!(config.max_extensions, 100);
153
154		assert_eq!(config.lazy_activation, true);
155	}
156
157	#[test]
158	fn test_host_config_builder() {
159		let config = HostConfig::default()
160			.with_max_extensions(50)
161			.with_lazy_activation(false)
162			.with_activation_timeout(60000);
163
164		assert_eq!(config.max_extensions, 50);
165
166		assert_eq!(config.lazy_activation, false);
167
168		assert_eq!(config.activation_timeout_ms, 60000);
169	}
170
171	#[test]
172	fn test_activation_result() {
173		let result = ActivationResult {
174			extension_id:"test.ext".to_string(),
175
176			success:true,
177
178			time_ms:100,
179
180			error:None,
181
182			contributes:vec!["command.test".to_string()],
183		};
184
185		assert_eq!(result.extension_id, "test.ext");
186
187		assert!(result.success);
188
189		assert_eq!(result.contributes.len(), 1);
190	}
191}