Skip to content

Commit 4e92c73

Browse files
authored
Merge pull request #45 from Jakedismo/claude/review-current-implementation-011CUr7KL9X815xqg5KbY9PX
feat: TypeScript Integration with NAPI Addon & Real Storage Backend
2 parents ad730ca + e25a754 commit 4e92c73

File tree

13 files changed

+2821
-65
lines changed

13 files changed

+2821
-65
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ members = [
1414
"crates/codegraph-ai",
1515
"crates/codegraph-api",
1616
"crates/codegraph-cli",
17+
"crates/codegraph-napi",
1718
"crates/core-rag-mcp-server",
1819
"scripts",
1920
"tests/integration"

crates/codegraph-api/src/graph_stub.rs

Lines changed: 147 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ impl CodeGraph {
6060
}
6161
}
6262

63-
/// Temporary stub for TransactionalGraph from codegraph-graph crate
63+
/// TransactionalGraph with real storage-backed managers
6464
#[derive(Clone)]
6565
pub struct TransactionalGraph {
6666
pub transaction_manager: ConcurrentTransactionManager,
@@ -69,6 +69,7 @@ pub struct TransactionalGraph {
6969
}
7070

7171
impl TransactionalGraph {
72+
/// Create a new TransactionalGraph with stub managers (for backward compatibility)
7273
pub fn new() -> Self {
7374
Self {
7475
transaction_manager: ConcurrentTransactionManager::new(),
@@ -77,6 +78,32 @@ impl TransactionalGraph {
7778
}
7879
}
7980

81+
/// Create a new TransactionalGraph with real storage-backed managers
82+
pub async fn with_storage(storage_path: &str) -> Result<Self> {
83+
use codegraph_graph::{RecoveryManager as RealRecoveryManager, VersionedRocksDbStorage};
84+
use tokio::sync::RwLock as TokioRwLock;
85+
use std::sync::Arc;
86+
87+
// Initialize storage
88+
let storage = VersionedRocksDbStorage::new(storage_path).await?;
89+
let storage_arc = Arc::new(TokioRwLock::new(storage));
90+
91+
// Create managers with real storage
92+
let transaction_manager = ConcurrentTransactionManager::with_storage(storage_arc.clone());
93+
let version_manager = GitLikeVersionManager::with_storage(storage_arc.clone());
94+
95+
let recovery_manager = RealRecoveryManager::new(
96+
storage_path,
97+
format!("{}_backups", storage_path),
98+
);
99+
100+
Ok(Self {
101+
transaction_manager,
102+
version_manager,
103+
recovery_manager,
104+
})
105+
}
106+
80107
pub async fn begin_transaction(&self) -> Result<Transaction> {
81108
Ok(Transaction {
82109
_marker: std::marker::PhantomData,
@@ -180,46 +207,35 @@ pub struct IntegrityReport {
180207
pub corrupted_data_count: usize,
181208
}
182209

183-
// Stub manager types
184-
// Note: uuid and chrono are already imported at the top of this file
185-
186-
// Define missing types that were incorrectly imported from codegraph_core
187-
pub type TransactionId = Uuid;
188-
pub type SnapshotId = Uuid;
189-
pub type VersionId = Uuid;
190-
191-
#[derive(Debug, Clone)]
192-
pub struct IsolationLevel;
193-
194-
#[derive(Debug, Clone)]
195-
pub struct Snapshot {
196-
pub id: SnapshotId,
197-
pub timestamp: DateTime<Utc>,
198-
}
199-
200-
#[derive(Debug, Clone)]
201-
pub struct Version {
202-
pub id: VersionId,
203-
pub timestamp: DateTime<Utc>,
204-
}
205-
206-
#[derive(Debug, Clone)]
207-
pub struct VersionDiff {
208-
pub added_nodes: Vec<NodeId>,
209-
pub modified_nodes: Vec<NodeId>,
210-
pub deleted_nodes: Vec<NodeId>,
211-
}
210+
// Import the real types from codegraph_core instead of redefining them
211+
pub use codegraph_core::{
212+
IsolationLevel, Snapshot, SnapshotId, TransactionId, Version, VersionDiff, VersionId,
213+
};
212214

213215
#[derive(Clone)]
214-
pub struct ConcurrentTransactionManager;
216+
pub struct ConcurrentTransactionManager {
217+
storage: Option<Arc<tokio::sync::RwLock<codegraph_graph::VersionedRocksDbStorage>>>,
218+
}
215219

216220
impl ConcurrentTransactionManager {
217221
pub fn new() -> Self {
218-
Self
222+
Self { storage: None }
219223
}
220224

221-
pub async fn begin_transaction(&self, _isolation_level: IsolationLevel) -> Result<TransactionId> {
222-
Ok(Uuid::new_v4())
225+
pub fn with_storage(storage: Arc<tokio::sync::RwLock<codegraph_graph::VersionedRocksDbStorage>>) -> Self {
226+
Self {
227+
storage: Some(storage),
228+
}
229+
}
230+
231+
pub async fn begin_transaction(&self, isolation_level: IsolationLevel) -> Result<TransactionId> {
232+
if let Some(storage) = &self.storage {
233+
let mut guard = storage.write().await;
234+
guard.begin_transaction(isolation_level).await
235+
} else {
236+
// Stub fallback
237+
Ok(Uuid::new_v4())
238+
}
223239
}
224240

225241
pub async fn commit_transaction(&self, _tx_id: TransactionId) -> Result<()> {
@@ -241,60 +257,128 @@ impl ConcurrentTransactionManager {
241257
}
242258

243259
#[derive(Clone)]
244-
pub struct GitLikeVersionManager;
260+
pub struct GitLikeVersionManager {
261+
storage: Option<Arc<RwLock<codegraph_graph::VersionedRocksDbStorage>>>,
262+
}
245263

246264
impl GitLikeVersionManager {
247265
pub fn new() -> Self {
248-
Self
266+
Self { storage: None }
249267
}
250268

251-
pub async fn create_version(&self, _name: String, _description: String, _author: String, _parent_versions: Vec<VersionId>) -> Result<VersionId> {
252-
Ok(Uuid::new_v4())
269+
pub fn with_storage(storage: Arc<RwLock<codegraph_graph::VersionedRocksDbStorage>>) -> Self {
270+
Self {
271+
storage: Some(storage),
272+
}
273+
}
274+
275+
pub async fn create_version(&self, name: String, description: String, author: String, parent_versions: Vec<VersionId>) -> Result<VersionId> {
276+
if let Some(storage) = &self.storage {
277+
let snapshot_id = Uuid::new_v4(); // TODO: Create real snapshot
278+
let mut guard = storage.write().await;
279+
guard.create_version(name, description, author, snapshot_id, parent_versions).await
280+
} else {
281+
// Stub fallback
282+
Ok(Uuid::new_v4())
283+
}
253284
}
254285

255286
pub async fn list_versions(&self) -> Result<Vec<Version>> {
256-
Ok(Vec::new())
287+
if let Some(storage) = &self.storage {
288+
let guard = storage.read().await;
289+
guard.list_versions(None).await
290+
} else {
291+
// Stub fallback
292+
Ok(Vec::new())
293+
}
257294
}
258295

259-
pub async fn get_version(&self, _id: VersionId) -> Result<Option<Version>> {
260-
Ok(None)
296+
pub async fn get_version(&self, id: VersionId) -> Result<Option<Version>> {
297+
if let Some(storage) = &self.storage {
298+
let guard = storage.read().await;
299+
guard.get_version(id).await
300+
} else {
301+
// Stub fallback
302+
Ok(None)
303+
}
261304
}
262305

263-
pub async fn tag_version(&self, _version_id: VersionId, _tag_name: String) -> Result<()> {
264-
Ok(())
306+
pub async fn tag_version(&self, version_id: VersionId, tag_name: String) -> Result<()> {
307+
if let Some(storage) = &self.storage {
308+
let mut guard = storage.write().await;
309+
guard.tag_version(version_id, tag_name).await
310+
} else {
311+
Ok(())
312+
}
265313
}
266314

267-
pub async fn compare_versions(&self, _from: VersionId, _to: VersionId) -> Result<VersionDiff> {
268-
Ok(VersionDiff {
269-
added_nodes: Vec::new(),
270-
deleted_nodes: Vec::new(),
271-
modified_nodes: Vec::new(),
272-
})
315+
pub async fn compare_versions(&self, from: VersionId, to: VersionId) -> Result<VersionDiff> {
316+
if let Some(storage) = &self.storage {
317+
let guard = storage.read().await;
318+
guard.compare_versions(from, to).await
319+
} else {
320+
Ok(VersionDiff {
321+
added_nodes: Vec::new(),
322+
deleted_nodes: Vec::new(),
323+
modified_nodes: Vec::new(),
324+
node_changes: HashMap::new(),
325+
})
326+
}
273327
}
274328

275-
pub async fn create_branch(&self, _name: String, _from_version: VersionId) -> Result<()> {
276-
Ok(())
329+
pub async fn create_branch(&self, name: String, from_version: VersionId) -> Result<()> {
330+
if let Some(storage) = &self.storage {
331+
let mut guard = storage.write().await;
332+
use codegraph_graph::GitLikeVersioning;
333+
guard.create_branch(name, from_version, "system".to_string()).await
334+
} else {
335+
Ok(())
336+
}
277337
}
278338

279339
pub async fn list_branches(&self) -> Result<Vec<Branch>> {
280-
Ok(Vec::new())
340+
if let Some(storage) = &self.storage {
341+
let guard = storage.read().await;
342+
use codegraph_graph::GitLikeVersioning;
343+
guard.list_branches().await
344+
} else {
345+
Ok(Vec::new())
346+
}
281347
}
282348

283-
pub async fn get_branch(&self, _name: String) -> Result<Option<Branch>> {
284-
Ok(None)
349+
pub async fn get_branch(&self, name: String) -> Result<Option<Branch>> {
350+
if let Some(storage) = &self.storage {
351+
let guard = storage.read().await;
352+
use codegraph_graph::GitLikeVersioning;
353+
guard.get_branch(&name).await
354+
} else {
355+
Ok(None)
356+
}
285357
}
286358

287-
pub async fn delete_branch(&self, _name: String) -> Result<()> {
288-
Ok(())
359+
pub async fn delete_branch(&self, name: String) -> Result<()> {
360+
if let Some(storage) = &self.storage {
361+
let mut guard = storage.write().await;
362+
use codegraph_graph::GitLikeVersioning;
363+
guard.delete_branch(&name).await
364+
} else {
365+
Ok(())
366+
}
289367
}
290368

291-
pub async fn merge_branches(&self, _source: String, _target: String) -> Result<MergeResult> {
292-
Ok(MergeResult {
293-
success: true,
294-
conflicts: Vec::new(),
295-
merged_version_id: Some(Uuid::new_v4()),
296-
merge_commit_message: "Merged".to_string(),
297-
})
369+
pub async fn merge_branches(&self, source: String, target: String) -> Result<MergeResult> {
370+
if let Some(storage) = &self.storage {
371+
let mut guard = storage.write().await;
372+
use codegraph_graph::GitLikeVersioning;
373+
guard.merge(&source, &target, "system".to_string(), format!("Merge {} into {}", source, target)).await
374+
} else {
375+
Ok(MergeResult {
376+
success: true,
377+
conflicts: Vec::new(),
378+
merged_version_id: Some(Uuid::new_v4()),
379+
merge_commit_message: "Merged".to_string(),
380+
})
381+
}
298382
}
299383

300384
pub async fn resolve_conflicts(&self, _conflicts: Vec<MergeConflict>) -> Result<()> {

crates/codegraph-api/src/state.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,22 @@ pub struct AppState {
111111
impl AppState {
112112
pub async fn new(config: Arc<ConfigManager>) -> codegraph_core::Result<Self> {
113113
let graph = Arc::new(RwLock::new(InMemoryGraph::new()));
114-
let transactional_graph = Arc::new(TransactionalGraph::new());
114+
115+
// Try to initialize with real storage, fallback to stub if it fails
116+
let storage_path = std::env::var("CODEGRAPH_STORAGE_PATH")
117+
.unwrap_or_else(|_| "./codegraph_data".to_string());
118+
119+
let transactional_graph = match TransactionalGraph::with_storage(&storage_path).await {
120+
Ok(tg) => {
121+
tracing::info!("Initialized TransactionalGraph with real storage at {}", storage_path);
122+
Arc::new(tg)
123+
}
124+
Err(e) => {
125+
tracing::warn!("Failed to initialize real storage ({}), using stub fallback", e);
126+
Arc::new(TransactionalGraph::new())
127+
}
128+
};
129+
115130
let parser = Arc::new(TreeSitterParser::new());
116131
let vector_store = Arc::new(FaissVectorStore::new(384)?);
117132
// Use advanced embeddings when CODEGRAPH_EMBEDDING_PROVIDER=local, otherwise fallback

0 commit comments

Comments
 (0)