@xiaohui-wang/mcpadvisor
Version:
MCP Advisor & Installation - Find the right MCP server for your needs
176 lines (175 loc) • 6.21 kB
JavaScript
/**
* Meilisearch 客户端控制器
* 提供与 Meilisearch 交互的功能,支持本地和云端实例
*/
import { MeiliSearch } from 'meilisearch';
import { MEILISEARCH_CONFIG, MeilisearchConfigManager } from '../../../config/meilisearch.js';
import { LocalMeilisearchController } from './localController.js';
import logger from '../../../utils/logger.js';
/**
* 创建云端 Meilisearch 客户端
*/
const createCloudMeilisearchClient = (config) => {
try {
const client = new MeiliSearch({
host: config.host,
apiKey: config.apiKey,
});
const index = client.index(config.indexName);
logger.info(`Cloud Meilisearch client initialized with host: ${config.host}`);
logger.info(`Using index: ${config.indexName}`);
return {
search: async (query, options = {}) => {
try {
const results = await index.search(query, options);
logger.debug(`Cloud Meilisearch search for "${query}" returned ${results.hits.length} results`);
return results;
}
catch (error) {
const message = error instanceof Error ? error.message : String(error);
logger.error(`Cloud Meilisearch search error: ${message}`);
throw error;
}
},
healthCheck: async () => {
try {
await client.health();
return true;
}
catch (error) {
logger.warn('Cloud Meilisearch health check failed:', error);
return false;
}
}
};
}
catch (error) {
const message = error instanceof Error ? error.message : String(error);
logger.error(`Failed to initialize cloud Meilisearch client: ${message}`);
throw error;
}
};
/**
* Meilisearch 客户端工厂
*/
export class MeilisearchClientFactory {
static configManager = MeilisearchConfigManager.getInstance();
/**
* 创建主要客户端
*/
static createPrimaryClient() {
const config = this.configManager.getActiveConfig();
if (config.type === 'local') {
logger.info('Creating local Meilisearch client');
return new LocalMeilisearchController(config);
}
else {
logger.info('Creating cloud Meilisearch client');
return createCloudMeilisearchClient(config);
}
}
/**
* 创建 fallback 客户端
*/
static createFallbackClient() {
const fallbackConfig = this.configManager.getFallbackConfig();
if (fallbackConfig) {
logger.info('Creating fallback Meilisearch client');
return createCloudMeilisearchClient(fallbackConfig);
}
return null;
}
}
/**
* 带故障转移的 Meilisearch 客户端
*/
export class FailoverMeilisearchClient {
primaryClient;
fallbackClient;
constructor() {
this.primaryClient = MeilisearchClientFactory.createPrimaryClient();
this.fallbackClient = MeilisearchClientFactory.createFallbackClient();
}
async search(query, options) {
try {
return await this.primaryClient.search(query, options);
}
catch (error) {
if (this.fallbackClient) {
logger.warn('Primary Meilisearch failed, using fallback client');
try {
return await this.fallbackClient.search(query, options);
}
catch (fallbackError) {
logger.error('Both primary and fallback Meilisearch clients failed');
throw fallbackError;
}
}
throw error;
}
}
async healthCheck() {
try {
if (this.primaryClient.healthCheck) {
return await this.primaryClient.healthCheck();
}
return true;
}
catch (error) {
if (this.fallbackClient?.healthCheck) {
return await this.fallbackClient.healthCheck();
}
return false;
}
}
}
/**
* 创建传统 Meilisearch 客户端(向后兼容)
*/
const createMeilisearchClient = () => {
try {
// 使用配置文件中的配置创建客户端
const client = new MeiliSearch({
host: MEILISEARCH_CONFIG.host,
apiKey: MEILISEARCH_CONFIG.apiKey,
});
// 获取索引
const index = client.index(MEILISEARCH_CONFIG.indexName);
logger.info(`Legacy Meilisearch client initialized with host: ${MEILISEARCH_CONFIG.host}`);
logger.info(`Using index: ${MEILISEARCH_CONFIG.indexName}`);
// 返回客户端接口实现
return {
/**
* 搜索文档
*/
search: async (query, options = {}) => {
try {
const results = await index.search(query, options);
logger.debug(`Legacy Meilisearch search for "${query}" returned ${results.hits.length} results`);
return results;
}
catch (error) {
const message = error instanceof Error ? error.message : String(error);
logger.error(`Legacy Meilisearch search error: ${message}`);
throw error;
}
},
};
}
catch (error) {
const message = error instanceof Error ? error.message : String(error);
logger.error(`Failed to initialize legacy Meilisearch client: ${message}`);
// 返回一个空的客户端实现,避免应用崩溃
return {
search: async () => {
logger.warn('Using fallback Meilisearch client implementation');
return { hits: [] };
},
};
}
};
/**
* Meilisearch 客户端实例(向后兼容)
* @deprecated 请使用 FailoverMeilisearchClient 或 MeilisearchClientFactory
*/
export const meilisearchClient = createMeilisearchClient();