Skip to main content
Glama
di-container.ts7.02 kB
/** * Dependency Injection Container - Clean Architecture Complete * Single responsibility: Wire up all dependencies with clean database management */ import { Neo4jDriverManager, SessionFactory, IndexManager, CleanDatabaseManager } from '../infrastructure/database'; import { CompositeMemoryRepository } from '../infrastructure/repositories/memory'; import { Neo4jSearchRepository } from '../infrastructure/repositories/neo4j-search-repository'; import { CreateMemoryUseCase } from '../application/use-cases/create-memory'; import { SearchMemoriesUseCase } from '../application/use-cases/search-memories'; import { UpdateMemoryUseCase } from '../application/use-cases/update-memory'; import { DeleteMemoryUseCase } from '../application/use-cases/delete-memory'; import { ManageObservationsUseCase } from '../application/use-cases/manage-observations'; import { ManageRelationsUseCase } from '../application/use-cases/manage-relations'; import { XenovaEmbeddingService } from '../infrastructure/services/embedding-service'; import { getVectorConfig } from '../config'; // Configuration constants const MODEL_INITIALIZATION_DELAY = 100; // ms - delay for non-blocking model loading export class DIContainer { private static instance: DIContainer; // Infrastructure private driverManager!: Neo4jDriverManager; private sessionFactory!: SessionFactory; private indexManager!: IndexManager; private databaseManager!: CleanDatabaseManager; // Services private embeddingService!: XenovaEmbeddingService; // Repositories private memoryRepository!: CompositeMemoryRepository; private searchRepository!: Neo4jSearchRepository; // Use Cases private createMemoryUseCase!: CreateMemoryUseCase; private searchMemoriesUseCase!: SearchMemoriesUseCase; private updateMemoryUseCase!: UpdateMemoryUseCase; private deleteMemoryUseCase!: DeleteMemoryUseCase; private manageObservationsUseCase!: ManageObservationsUseCase; private manageRelationsUseCase!: ManageRelationsUseCase; // Session tracking for cleanup private activeSessions: any[] = []; private constructor() { this.initializeInfrastructure(); this.initializeServices(); this.initializeRepositories(); this.initializeUseCases(); } static getInstance(): DIContainer { if (!DIContainer.instance) { DIContainer.instance = new DIContainer(); } return DIContainer.instance; } private initializeInfrastructure(): void { this.driverManager = new Neo4jDriverManager(); this.sessionFactory = new SessionFactory(this.driverManager); this.databaseManager = new CleanDatabaseManager(this.driverManager, this.sessionFactory); } private initializeServices(): void { this.embeddingService = new XenovaEmbeddingService(); // Note: Search orchestrator removed - SimplifiedSearchService used directly in repositories } private initializeRepositories(): void { this.memoryRepository = new CompositeMemoryRepository(this.sessionFactory); this.searchRepository = new Neo4jSearchRepository(this.sessionFactory); } private initializeUseCases(): void { this.createMemoryUseCase = new CreateMemoryUseCase( this.memoryRepository, this.embeddingService ); this.searchMemoriesUseCase = new SearchMemoriesUseCase(this.searchRepository); this.updateMemoryUseCase = new UpdateMemoryUseCase(this.memoryRepository); this.deleteMemoryUseCase = new DeleteMemoryUseCase(this.memoryRepository); this.manageObservationsUseCase = new ManageObservationsUseCase( this.memoryRepository ); this.manageRelationsUseCase = new ManageRelationsUseCase(this.memoryRepository); } // Public getters for use cases getCreateMemoryUseCase(): CreateMemoryUseCase { return this.createMemoryUseCase; } getSearchMemoriesUseCase(): SearchMemoriesUseCase { return this.searchMemoriesUseCase; } getUpdateMemoryUseCase(): UpdateMemoryUseCase { return this.updateMemoryUseCase; } getDeleteMemoryUseCase(): DeleteMemoryUseCase { return this.deleteMemoryUseCase; } getManageObservationsUseCase(): ManageObservationsUseCase { return this.manageObservationsUseCase; } getManageRelationsUseCase(): ManageRelationsUseCase { return this.manageRelationsUseCase; } // Public getters for services getEmbeddingService(): XenovaEmbeddingService { return this.embeddingService; } getDatabaseManager(): CleanDatabaseManager { return this.databaseManager; } getMemoryRepository(): CompositeMemoryRepository { return this.memoryRepository; } getSessionFactory(): SessionFactory { return this.sessionFactory; } getCurrentDatabase(): { database: string } { return this.driverManager.getCurrentDatabase(); } switchDatabase(database: string): void { this.driverManager.switchDatabase(database); } async initializeDatabase(): Promise<void> { // Vector indexes will be created when model becomes available const session = this.sessionFactory.createSession(); try { // Fast schema initialization - no model dependencies this.indexManager = new IndexManager(session, undefined); const hasSchema = await this.indexManager.hasRequiredSchema(); if (!hasSchema) { await this.indexManager.initializeSchema(); } // Background model loading - non-blocking this.initializeModelInBackground(); } finally { await session.close(); } } /** * Background model initialization - does not block tool registration */ private initializeModelInBackground(): void { // Non-blocking background loading with proper preload handling setTimeout(async () => { try { const config = getVectorConfig(); if (config.preload) { await this.embeddingService.preloadModel(); } // Create vector indexes once model is loaded const session = this.sessionFactory.createSession(); try { const dimensions = await this.embeddingService.getModelDimensions(); const vectorIndexManager = new IndexManager(session, dimensions); await vectorIndexManager.ensureVectorIndexes(); } finally { await session.close(); } } catch (error) { // Silent failure - vector search will work when model loads on demand } }, MODEL_INITIALIZATION_DELAY); } async close(): Promise<void> { // Clean shutdown sequence // Close active sessions first for (const session of this.activeSessions) { try { await session.close(); } catch (error) { // Session cleanup error - ignore during shutdown } } this.activeSessions = []; // Shutdown embedding service if (this.embeddingService && typeof this.embeddingService.shutdown === 'function') { await this.embeddingService.shutdown(); } // Close driver last await this.driverManager.close(); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sylweriusz/mcp-neo4j-memory-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server