Skip to main content
Glama
base-kuzu-client.ts3.96 kB
import fs from 'fs'; import path from 'path'; import { kuzuLogger } from '../../utils/logger'; import config from '../config'; // Connection constants export const CONNECTION_VALIDATION_INTERVAL = 5 * 60 * 1000; // 5 minutes export const SCHEMA_CHECK_TIMEOUT = 5000; // 5 seconds timeout for schema check export const MAX_CONNECTION_AGE = 30 * 60 * 1000; // 30 minutes max connection age /** * Helper function to track, log, and report progress for operation timing */ export async function timeOperation<T>( operation: string, context: string, progressCallback: ((message: string, percent?: number) => Promise<void>) | null = null, fn: () => Promise<T>, ): Promise<T> { const logger = kuzuLogger.child({ operation, context }); try { logger.debug('Operation starting'); // Send progress notification if callback provided if (progressCallback) { await progressCallback(`${operation} for ${context}`); } const result = await fn(); logger.debug('Operation completed successfully'); return result; } catch (error) { logger.error('Operation failed', { error }); throw error; } } /** * Base class for Kuzu database operations * Provides common configuration, logging, and utility methods */ export abstract class BaseKuzuClient { public readonly dbPath: string; protected logger = kuzuLogger.child({ component: 'BaseKuzuClient' }); constructor(clientProjectRoot: string) { this.dbPath = this.initializeDbPath(clientProjectRoot); this.logger = kuzuLogger.child({ component: this.constructor.name, dbPath: this.dbPath, }); this.logger.info('Kuzu client instance created'); } /** * Initialize database path from client project root or environment override */ private initializeDbPath(clientProjectRoot: string): string { const logger = kuzuLogger.child({ operation: 'initialize-db-path' }); const overrideDbPath = process.env.DB_PATH_OVERRIDE; if (overrideDbPath) { logger.info({ dbPath: overrideDbPath }, 'Using DB_PATH_OVERRIDE from environment'); // Ensure the directory for the override path exists const dbDir = path.dirname(overrideDbPath); if (!fs.existsSync(dbDir)) { fs.mkdirSync(dbDir, { recursive: true }); logger.info({ dbDir }, 'Created directory for override DB path'); } return overrideDbPath; } // Validate and use client project root if (!clientProjectRoot || clientProjectRoot.trim() === '') { const envClientRoot = process.env.CLIENT_PROJECT_ROOT; if (!envClientRoot || envClientRoot.trim() === '') { throw new Error( 'KuzuDBClient requires a valid clientProjectRoot path. None provided and no CLIENT_PROJECT_ROOT environment variable set.', ); } clientProjectRoot = envClientRoot; logger.info({ clientProjectRoot }, 'Using CLIENT_PROJECT_ROOT from environment'); } if (!path.isAbsolute(clientProjectRoot)) { throw new Error('KuzuDBClient requires an absolute clientProjectRoot path.'); } const repoDbDir = path.join(clientProjectRoot, config.DB_RELATIVE_DIR); const dbPath = path.join(repoDbDir, config.DB_FILENAME); // Ensure the directory for the constructed path exists const dbDir = path.dirname(dbPath); if (!fs.existsSync(dbDir)) { fs.mkdirSync(dbDir, { recursive: true }); logger.info({ dbDir }, 'Created database directory'); } return dbPath; } /** * Create a child logger with operation context */ protected createOperationLogger(operation: string, context: Record<string, any> = {}) { return this.logger.child({ operation, ...context, }); } /** * Get database directory path */ protected getDbDirectory(): string { return path.dirname(this.dbPath); } /** * Get database filename */ protected getDbFilename(): string { return path.basename(this.dbPath); } }

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