Skip to main content
Glama
repository-factory.ts7.64 kB
import { KuzuDBClient } from './kuzu'; import { RepositoryRepository, MetadataRepository, ContextRepository, ComponentRepository, DecisionRepository, RuleRepository, } from '../repositories'; import { Mutex } from '../utils/mutex'; import { loggers } from '../utils/logger'; /** * RepositoryFactory - Manages creation of repository instances * * This factory is responsible for: * 1. Creating repository instances with the correct KuzuDBClient * 2. Caching repositories to prevent redundant creation * 3. Providing a clean interface for accessing various repository types * * Implements the Singleton pattern to ensure consistent caching across the application */ export class RepositoryFactory { private static instance: RepositoryFactory; private static initializationLock = new Mutex(); private static logger = loggers.repository(); // Cache maps to store repositories by database path private repositoryRepoCache: Map<string, RepositoryRepository> = new Map(); private metadataRepoCache: Map<string, MetadataRepository> = new Map(); private contextRepoCache: Map<string, ContextRepository> = new Map(); private componentRepoCache: Map<string, ComponentRepository> = new Map(); private decisionRepoCache: Map<string, DecisionRepository> = new Map(); private ruleRepoCache: Map<string, RuleRepository> = new Map(); /** * Private constructor to enforce Singleton pattern */ private constructor() { RepositoryFactory.logger.info('RepositoryFactory initialized'); } /** * Get the singleton instance of RepositoryFactory * Creates the instance if it doesn't exist * Thread-safe with mutex locking */ public static async getInstance(): Promise<RepositoryFactory> { if (!RepositoryFactory.instance) { const release = await RepositoryFactory.initializationLock.acquire(); try { if (!RepositoryFactory.instance) { RepositoryFactory.instance = new RepositoryFactory(); RepositoryFactory.logger.info('RepositoryFactory singleton instance created'); } } finally { release(); } } return RepositoryFactory.instance; } /** * Get a RepositoryRepository instance for the given KuzuDBClient * Uses caching to prevent redundant repository creation * * @param kuzuClient The KuzuDBClient instance * @returns RepositoryRepository instance */ getRepositoryRepository(kuzuClient: KuzuDBClient): RepositoryRepository { const dbPath = kuzuClient.dbPath; if (!this.repositoryRepoCache.has(dbPath)) { RepositoryFactory.logger.info(`Creating new RepositoryRepository for ${dbPath}`); this.repositoryRepoCache.set(dbPath, new RepositoryRepository(kuzuClient)); } return this.repositoryRepoCache.get(dbPath)!; } /** * Get a MetadataRepository instance for the given KuzuDBClient * Uses caching to prevent redundant repository creation * * @param kuzuClient The KuzuDBClient instance * @returns MetadataRepository instance */ getMetadataRepository(kuzuClient: KuzuDBClient): MetadataRepository { const dbPath = kuzuClient.dbPath; if (!this.metadataRepoCache.has(dbPath)) { RepositoryFactory.logger.info(`Creating new MetadataRepository for ${dbPath}`); const repositoryRepo = this.getRepositoryRepository(kuzuClient); this.metadataRepoCache.set(dbPath, new MetadataRepository(kuzuClient, repositoryRepo)); } return this.metadataRepoCache.get(dbPath)!; } /** * Get a ContextRepository instance for the given KuzuDBClient * Uses caching to prevent redundant repository creation * * @param kuzuClient The KuzuDBClient instance * @returns ContextRepository instance */ getContextRepository(kuzuClient: KuzuDBClient): ContextRepository { const dbPath = kuzuClient.dbPath; if (!this.contextRepoCache.has(dbPath)) { RepositoryFactory.logger.info(`Creating new ContextRepository for ${dbPath}`); const repositoryRepo = this.getRepositoryRepository(kuzuClient); this.contextRepoCache.set(dbPath, new ContextRepository(kuzuClient, repositoryRepo)); } return this.contextRepoCache.get(dbPath)!; } /** * Get a ComponentRepository instance for the given KuzuDBClient * Uses caching to prevent redundant repository creation * * @param kuzuClient The KuzuDBClient instance * @returns ComponentRepository instance */ getComponentRepository(kuzuClient: KuzuDBClient): ComponentRepository { const dbPath = kuzuClient.dbPath; if (!this.componentRepoCache.has(dbPath)) { RepositoryFactory.logger.info(`Creating new ComponentRepository for ${dbPath}`); const repositoryRepo = this.getRepositoryRepository(kuzuClient); this.componentRepoCache.set(dbPath, new ComponentRepository(kuzuClient, repositoryRepo)); } return this.componentRepoCache.get(dbPath)!; } /** * Get a DecisionRepository instance for the given KuzuDBClient * Uses caching to prevent redundant repository creation * * @param kuzuClient The KuzuDBClient instance * @returns DecisionRepository instance */ getDecisionRepository(kuzuClient: KuzuDBClient): DecisionRepository { const dbPath = kuzuClient.dbPath; if (!this.decisionRepoCache.has(dbPath)) { RepositoryFactory.logger.info(`Creating new DecisionRepository for ${dbPath}`); const repositoryRepo = this.getRepositoryRepository(kuzuClient); this.decisionRepoCache.set(dbPath, new DecisionRepository(kuzuClient, repositoryRepo)); } return this.decisionRepoCache.get(dbPath)!; } /** * Get a RuleRepository instance for the given KuzuDBClient * Uses caching to prevent redundant repository creation * * @param kuzuClient The KuzuDBClient instance * @returns RuleRepository instance */ getRuleRepository(kuzuClient: KuzuDBClient): RuleRepository { const dbPath = kuzuClient.dbPath; if (!this.ruleRepoCache.has(dbPath)) { RepositoryFactory.logger.info(`Creating new RuleRepository for ${dbPath}`); const repositoryRepo = this.getRepositoryRepository(kuzuClient); this.ruleRepoCache.set(dbPath, new RuleRepository(kuzuClient, repositoryRepo)); } return this.ruleRepoCache.get(dbPath)!; } /** * Initialize all repositories for a given KuzuDBClient * This creates and caches all repositories at once * * @param kuzuClient The KuzuDBClient instance * @returns Object containing all repository instances */ initializeRepositories(kuzuClient: KuzuDBClient): { repositoryRepository: RepositoryRepository; metadataRepository: MetadataRepository; contextRepository: ContextRepository; componentRepository: ComponentRepository; decisionRepository: DecisionRepository; ruleRepository: RuleRepository; } { return { repositoryRepository: this.getRepositoryRepository(kuzuClient), metadataRepository: this.getMetadataRepository(kuzuClient), contextRepository: this.getContextRepository(kuzuClient), componentRepository: this.getComponentRepository(kuzuClient), decisionRepository: this.getDecisionRepository(kuzuClient), ruleRepository: this.getRuleRepository(kuzuClient), }; } /** * Clear all repository caches * Useful for testing or when managing memory usage */ clearCaches(): void { this.repositoryRepoCache.clear(); this.metadataRepoCache.clear(); this.contextRepoCache.clear(); this.componentRepoCache.clear(); this.decisionRepoCache.clear(); this.ruleRepoCache.clear(); RepositoryFactory.logger.info('All repository caches cleared'); } }

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/Jakedismo/KuzuMem-MCP'

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