syia-mcp-utils
Version:
Global utility functions for MCP server
128 lines (127 loc) • 4.46 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.initializeConnection = initializeConnection;
exports.getTypesenseClient = getTypesenseClient;
exports.isTypesenseConnected = isTypesenseConnected;
exports.closeConnection = closeConnection;
const typesense_1 = require("typesense");
const logger_js_1 = require("./logger.js");
const config_1 = require("./config");
let client = null;
let isConnected = false;
// Typesense connection options
const typesenseOptions = {
connectionTimeoutSeconds: 5,
retryIntervalSeconds: 0.1,
numRetries: 3,
healthCheckIntervalSeconds: 60
};
/**
* Test Typesense connection by performing a health check
* @param typesenseClient The Typesense client to test
* @returns True if connection is successful, false otherwise
*/
async function testConnection(typesenseClient) {
try {
// Attempt to get health stats as a connection test
const health = await typesenseClient.health.retrieve();
logger_js_1.logger.debug('Typesense health check successful', { health });
return true;
}
catch (error) {
logger_js_1.logger.error('Typesense health check failed:', error);
return false;
}
}
/**
* Initialize Typesense client connection with retry logic
* This should be called during server startup
*/
function initializeConnection() {
if (!client) {
try {
// Create client instance
client = new typesense_1.Client({
nodes: [{
host: (0, config_1.getConfig)().typesenseHost,
port: parseInt((0, config_1.getConfig)().typesensePort, 10),
protocol: (0, config_1.getConfig)().typesenseProtocol
}],
apiKey: (0, config_1.getConfig)().typesenseApiKey,
...typesenseOptions
});
// Schedule periodic health checks in production
if (process.env.NODE_ENV === 'production') {
setInterval(async () => {
isConnected = await testConnection(client);
if (!isConnected) {
logger_js_1.logger.warn('Typesense connection check failed, may need reconnection');
}
}, typesenseOptions.healthCheckIntervalSeconds * 1000);
}
logger_js_1.logger.info('Initialized Typesense client', {
host: (0, config_1.getConfig)().typesenseHost,
port: (0, config_1.getConfig)().typesensePort,
protocol: (0, config_1.getConfig)().typesenseProtocol
});
// Test connection immediately
testConnection(client)
.then(result => {
isConnected = result;
if (result) {
logger_js_1.logger.info('Successfully connected to Typesense');
}
else {
logger_js_1.logger.warn('Failed initial connection to Typesense, operations may fail');
}
})
.catch(err => {
logger_js_1.logger.error('Error testing Typesense connection:', err);
});
}
catch (error) {
logger_js_1.logger.error('Error initializing Typesense client:', error);
throw error;
}
}
return client;
}
/**
* Get Typesense client
* If not already initialized, this will initialize the client
*/
function getTypesenseClient() {
if (!client) {
return initializeConnection();
}
return client;
}
/**
* Check if Typesense connection is healthy
* @returns True if connected, false otherwise
*/
function isTypesenseConnected() {
return isConnected;
}
/**
* Close Typesense connection
* This should be called during server shutdown
*/
async function closeConnection() {
if (client) {
try {
// Clear any scheduled health checks
for (let i = 0; i < 1000; i++) {
clearInterval(i);
}
// Typesense doesn't have a direct close method, but we can nullify the client
client = null;
isConnected = false;
logger_js_1.logger.info('Closed Typesense connection');
}
catch (error) {
logger_js_1.logger.error('Error closing Typesense connection:', error);
throw error;
}
}
}