UNPKG

solver-sdk

Version:

SDK для интеграции с Code Solver Backend API

543 lines 26.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CodeSolverWebSocketClient = exports.WebSocketNamespace = void 0; const websocket_events_constants_1 = require("../constants/websocket-events.constants"); const websocket_namespaces_constants_js_1 = require("../constants/websocket-namespaces.constants.js"); const logger_js_1 = require("./logger.js"); const base_ws_client_js_1 = require("../ws/base-ws-client.js"); // Реэкспортируем WebSocketNamespace для других модулей var websocket_namespaces_constants_js_2 = require("../constants/websocket-namespaces.constants.js"); Object.defineProperty(exports, "WebSocketNamespace", { enumerable: true, get: function () { return websocket_namespaces_constants_js_2.WebSocketNamespace; } }); // Дополнительные события, которые могут отсутствовать в основном перечислении const CUSTOM_EVENTS = { GET_REASONING_STATUS: 'get_reasoning_status' }; /** * Специализированный WebSocket клиент для пространства имен reasoning */ class ReasoningWsClient extends base_ws_client_js_1.BaseWebSocketClient { /** * Создает новый WebSocket клиент для рассуждений * @param {string} baseURL Базовый URL API * @param {BaseWebSocketClientOptions} options Опции клиента */ constructor(baseURL, options = {}) { super(websocket_namespaces_constants_js_1.WebSocketNamespace.REASONING, baseURL, options); /** Активная сессия рассуждения */ this.activeReasoningId = null; } /** * Подключается к серверу WebSocket с указанным ID рассуждения * @param {string} reasoningId ID рассуждения * @param {object} options Дополнительные опции * @returns {Promise<boolean>} Успешность подключения */ async connectWithReasoning(reasoningId, options = {}) { if (reasoningId) { this.activeReasoningId = reasoningId; } return super.connect({ reasoningId: this.activeReasoningId, ...options }); } /** * Присоединяется к сессии рассуждения * @param {string} reasoningId ID рассуждения * @param {boolean} setActive Установить ли как активную сессию * @returns {Promise<boolean>} Успешность операции */ async joinReasoning(reasoningId, setActive = true) { if (!this.isConnected()) { this.logger.warn(`Попытка присоединения к рассуждению ${reasoningId}, но клиент не подключен`); return false; } try { // Отправляем запрос на присоединение const result = await this.emitWithAck(websocket_events_constants_1.WebSocketEvents.JOIN_REASONING, { reasoningId }); if (result.success && setActive) { this.activeReasoningId = reasoningId; } return result.success; } catch (error) { this.logger.error(`Ошибка при присоединении к рассуждению ${reasoningId}`, error); return false; } } /** * Подключает к сессии рассуждения и устанавливает обработчик для thinking * @param {string} reasoningId ID рассуждения * @param {function} thinkingHandler Обработчик событий thinking * @returns {Promise<string>} ID рассуждения */ async connectToThinkingSession(reasoningId, thinkingHandler) { // Сначала подключаемся к сессии рассуждения const connected = await this.connectWithReasoning(reasoningId, { autoJoin: true }); if (!connected) { throw new Error(`Не удалось подключиться к рассуждению ${reasoningId}`); } // Затем подписываемся на мышление, если указан обработчик if (thinkingHandler) { this.subscribeToThinking(thinkingHandler); } return reasoningId; } /** * Подписаться на события мышления * @param callback Функция обратного вызова для обработки событий мышления */ subscribeToThinking(callback) { this.on(websocket_events_constants_1.ReasoningEventNames.THINKING, callback); } /** * Отписаться от событий мышления * @param callback Функция обратного вызова для обработки событий мышления */ unsubscribeFromThinking(callback) { this.off(websocket_events_constants_1.ReasoningEventNames.THINKING, callback); } /** * Проверяет статус рассуждения * @param {string} reasoningId ID рассуждения * @returns {Promise<object>} Объект с информацией о статусе */ async getReasoningStatus(reasoningId) { const id = reasoningId || this.activeReasoningId; if (!id) { return { exists: false, isActive: false }; } try { if (!this.isConnected()) { await this.connect(); } const result = await this.emitWithAck(CUSTOM_EVENTS.GET_REASONING_STATUS, { reasoningId: id }); return result; } catch (error) { this.logger.error(`Ошибка при получении статуса рассуждения ${id}`, error); return { exists: false, isActive: false }; } } /** * Проверяет существование рассуждения * @param {string} reasoningId ID рассуждения * @returns {Promise<boolean>} true, если рассуждение существует */ async checkReasoningExists(reasoningId) { try { const { exists } = await this.getReasoningStatus(reasoningId); return exists; } catch (error) { return false; } } /** * Получает ID активной сессии рассуждения * @returns {string | null} ID активной сессии или null */ getActiveReasoningId() { return this.activeReasoningId; } } /** * Специализированный WebSocket клиент для пространства имен indexing */ class IndexingWsClient extends base_ws_client_js_1.BaseWebSocketClient { /** * Создает новый WebSocket клиент для индексации * @param {string} baseURL Базовый URL API * @param {BaseWebSocketClientOptions} options Опции клиента */ constructor(baseURL, options = {}) { super(websocket_namespaces_constants_js_1.WebSocketNamespace.INDEXING, baseURL, options); /** Активный проект */ this.activeProjectId = null; } /** * Подключается к серверу WebSocket с указанным ID проекта * @param {string} projectId ID проекта * @returns {Promise<boolean>} Успешность подключения */ async connectWithProject(projectId) { if (projectId) { this.activeProjectId = projectId; } return super.connect({ projectId: this.activeProjectId }); } /** * Получает ID активного проекта * @returns {string | null} ID активного проекта или null */ getActiveProjectId() { return this.activeProjectId; } } /** * Специализированный WebSocket клиент для пространства имен dependencies */ class DependenciesWsClient extends base_ws_client_js_1.BaseWebSocketClient { /** * Создает новый WebSocket клиент для зависимостей * @param {string} baseURL Базовый URL API * @param {BaseWebSocketClientOptions} options Опции клиента */ constructor(baseURL, options = {}) { super(websocket_namespaces_constants_js_1.WebSocketNamespace.DEPENDENCIES, baseURL, options); } /** * Подключается к серверу WebSocket с указанным ID проекта * @param {string} projectId ID проекта * @returns {Promise<boolean>} Успешность подключения */ async connectWithProject(projectId) { return super.connect({ projectId }); } } /** * Специализированный WebSocket клиент для пространства имен notifications */ class NotificationsWsClient extends base_ws_client_js_1.BaseWebSocketClient { /** * Создает новый WebSocket клиент для уведомлений * @param {string} baseURL Базовый URL API * @param {BaseWebSocketClientOptions} options Опции клиента */ constructor(baseURL, options = {}) { super(websocket_namespaces_constants_js_1.WebSocketNamespace.DEFAULT, baseURL, options); } } /** * Сервис для диагностики WebSocket соединений */ class DiagnosticsService { /** * Создает новый сервис диагностики * @param {DiagnosticsServiceOptions} options Опции сервиса */ constructor(options) { this.clients = options.clients; this.logger = options.logger; } /** * Получает диагностическую информацию о всех соединениях * @returns {object} Диагностическая информация */ getDiagnostics() { const result = {}; // Собираем информацию о каждом соединении for (const [namespace, client] of Object.entries(this.clients)) { result[namespace] = { isConnected: client.isConnected(), socketId: client.getSocketId() // При необходимости можно добавить дополнительную информацию }; } return result; } } /** * WebSocket клиент для работы с Code Solver API (фасад) */ class CodeSolverWebSocketClient { /** * Создает новый WebSocket клиент для Code Solver API * @param {string} baseURL Базовый URL API * @param {CodeSolverWebSocketOptions} [options] Опции клиента */ constructor(baseURL, options = {}) { this.baseURL = baseURL.replace(/^http/, 'ws'); this.options = { ...options, headers: { ...(options.headers || {}), ...(options.apiKey ? { 'Authorization': `Bearer ${options.apiKey}` } : {}) } }; // Создаем логгер this.logger = (0, logger_js_1.createWebSocketLogger)('CodeSolverWebSocket'); // Трансформируем опции для специализированных клиентов const clientOptions = { ...this.options, enableAutoPing: options.enableAutoPing !== false, enableSessionPersistence: options.enableSessionPersistence !== false, // Преобразуем функцию логгера в экземпляр Logger, если передана функция logger: typeof options.logger === 'function' ? (0, logger_js_1.createWebSocketLogger)('CodeSolverWebSocket', options.logger) : options.logger }; // Создаем специализированные клиенты this.reasoningClient = new ReasoningWsClient(this.baseURL, { ...clientOptions, logger: this.logger.withPrefix('Reasoning') }); this.indexingClient = new IndexingWsClient(this.baseURL, { ...clientOptions, logger: this.logger.withPrefix('Indexing') }); this.dependenciesClient = new DependenciesWsClient(this.baseURL, { ...clientOptions, logger: this.logger.withPrefix('Dependencies') }); this.notificationsClient = new NotificationsWsClient(this.baseURL, { ...clientOptions, logger: this.logger.withPrefix('Notifications') }); // Создаем сервис диагностики this.diagnosticsService = new DiagnosticsService({ clients: { [websocket_namespaces_constants_js_1.WebSocketNamespace.REASONING]: this.reasoningClient, [websocket_namespaces_constants_js_1.WebSocketNamespace.INDEXING]: this.indexingClient, [websocket_namespaces_constants_js_1.WebSocketNamespace.DEPENDENCIES]: this.dependenciesClient, [websocket_namespaces_constants_js_1.WebSocketNamespace.DEFAULT]: this.notificationsClient }, logger: this.logger.withPrefix('Diagnostics') }); } /** * Подключается к пространству имен рассуждений * @param {string} reasoningId ID рассуждения (опционально) * @param {object} options Дополнительные настройки подключения * @returns {Promise<boolean>} Результат подключения */ async connectToReasoning(reasoningId, options = {}) { return this.reasoningClient.connectWithReasoning(reasoningId, options); } /** * Подключается к пространству имен индексации * @param {string} projectId ID проекта (опционально) * @returns {Promise<boolean>} Результат подключения */ async connectToIndexing(projectId) { return this.indexingClient.connectWithProject(projectId); } /** * Подключается к уведомлениям * @returns {Promise<boolean>} Результат подключения */ async connectToNotifications() { return this.notificationsClient.connect({}); } /** * Подключается к пространству имен dependencies * @param {string} projectId ID проекта (опционально) * @returns {Promise<boolean>} Результат подключения */ async connectToDependencies(projectId) { return this.dependenciesClient.connectWithProject(projectId); } /** * Отключается от пространства имен * @param {WebSocketNamespace} namespace Пространство имен */ disconnect(namespace) { switch (namespace) { case websocket_namespaces_constants_js_1.WebSocketNamespace.REASONING: this.reasoningClient.disconnect(); break; case websocket_namespaces_constants_js_1.WebSocketNamespace.INDEXING: this.indexingClient.disconnect(); break; case websocket_namespaces_constants_js_1.WebSocketNamespace.DEPENDENCIES: this.dependenciesClient.disconnect(); break; case websocket_namespaces_constants_js_1.WebSocketNamespace.DEFAULT: this.notificationsClient.disconnect(); break; } } /** * Отключается от всех пространств имен */ disconnectAll() { this.reasoningClient.disconnect(); this.indexingClient.disconnect(); this.dependenciesClient.disconnect(); this.notificationsClient.disconnect(); } /** * Проверяет, подключен ли клиент к указанному пространству имен * @param {WebSocketNamespace} namespace Пространство имен * @returns {boolean} Статус подключения */ isConnected(namespace) { switch (namespace) { case websocket_namespaces_constants_js_1.WebSocketNamespace.REASONING: return this.reasoningClient.isConnected(); case websocket_namespaces_constants_js_1.WebSocketNamespace.INDEXING: return this.indexingClient.isConnected(); case websocket_namespaces_constants_js_1.WebSocketNamespace.DEPENDENCIES: return this.dependenciesClient.isConnected(); case websocket_namespaces_constants_js_1.WebSocketNamespace.DEFAULT: return this.notificationsClient.isConnected(); default: return false; } } /** * Проверяет, подключен ли клиент к пространству имен рассуждений * @returns {boolean} Статус подключения */ isConnectedToReasoning() { return this.reasoningClient.isConnected(); } /** * Проверяет, подключен ли клиент к пространству имен индексации * @returns {boolean} Статус подключения */ isConnectedToIndexing() { return this.indexingClient.isConnected(); } /** * Проверяет, подключен ли клиент к пространству имен уведомлений * @returns {boolean} Статус подключения */ isConnectedToNotifications() { return this.notificationsClient.isConnected(); } /** * Получает ID активной сессии рассуждения * @returns {string | null} ID активной сессии рассуждения или null */ getActiveReasoningId() { return this.reasoningClient.getActiveReasoningId(); } /** * Получает ID активного проекта * @returns {string | null} ID активного проекта или null */ getActiveProjectId() { return this.indexingClient.getActiveProjectId(); } /** * Отправляет сообщение в пространство имен * @param {WebSocketNamespace} namespace Пространство имен * @param {string} eventType Тип события * @param {any} [data] Данные сообщения * @returns {boolean} Успешно ли отправлено сообщение */ send(namespace, eventType, data) { switch (namespace) { case websocket_namespaces_constants_js_1.WebSocketNamespace.REASONING: return this.reasoningClient.send(eventType, data); case websocket_namespaces_constants_js_1.WebSocketNamespace.INDEXING: return this.indexingClient.send(eventType, data); case websocket_namespaces_constants_js_1.WebSocketNamespace.DEPENDENCIES: return this.dependenciesClient.send(eventType, data); case websocket_namespaces_constants_js_1.WebSocketNamespace.DEFAULT: return this.notificationsClient.send(eventType, data); default: throw new Error(`Неизвестное пространство имен ${namespace}`); } } /** * Отправляет сообщение в активную сессию рассуждения * @param {string} eventType Тип события * @param {any} [data] Данные сообщения * @returns {boolean} Успешно ли отправлено сообщение */ sendToReasoning(eventType, data) { return this.reasoningClient.send(eventType, data); } /** * Отправляет сообщение в активную сессию индексации * @param {string} eventType Тип события * @param {any} [data] Данные сообщения * @returns {boolean} Успешно ли отправлено сообщение */ sendToIndexing(eventType, data) { return this.indexingClient.send(eventType, data); } /** * Отправляет сообщение в уведомления * @param {string} eventType Тип события * @param {any} [data] Данные сообщения * @returns {boolean} Успешно ли отправлено сообщение */ sendToNotifications(eventType, data) { return this.notificationsClient.send(eventType, data); } /** * Добавляет обработчик события для пространства имен * @param {string} eventType Тип события * @param {Function} handler Обработчик события * @param {WebSocketNamespace} [namespace] Пространство имен (если не указано, добавляется ко всем активным) */ on(eventType, handler, namespace) { if (namespace) { // Если указано пространство имен, добавляем обработчик только к нему switch (namespace) { case websocket_namespaces_constants_js_1.WebSocketNamespace.REASONING: this.reasoningClient.on(eventType, handler); break; case websocket_namespaces_constants_js_1.WebSocketNamespace.INDEXING: this.indexingClient.on(eventType, handler); break; case websocket_namespaces_constants_js_1.WebSocketNamespace.DEPENDENCIES: this.dependenciesClient.on(eventType, handler); break; case websocket_namespaces_constants_js_1.WebSocketNamespace.DEFAULT: this.notificationsClient.on(eventType, handler); break; } } else { // Если пространство имен не указано, добавляем обработчик ко всем активным this.reasoningClient.on(eventType, handler); this.indexingClient.on(eventType, handler); this.dependenciesClient.on(eventType, handler); this.notificationsClient.on(eventType, handler); } } /** * Удаляет обработчик события для пространства имен * @param {string} eventType Тип события * @param {Function} [handler] Обработчик события (если не указан, удаляются все обработчики) * @param {WebSocketNamespace} [namespace] Пространство имен (если не указано, удаляется из всех активных) */ off(eventType, handler, namespace) { if (namespace) { // Если указано пространство имен, удаляем обработчик только из него switch (namespace) { case websocket_namespaces_constants_js_1.WebSocketNamespace.REASONING: this.reasoningClient.off(eventType, handler); break; case websocket_namespaces_constants_js_1.WebSocketNamespace.INDEXING: this.indexingClient.off(eventType, handler); break; case websocket_namespaces_constants_js_1.WebSocketNamespace.DEPENDENCIES: this.dependenciesClient.off(eventType, handler); break; case websocket_namespaces_constants_js_1.WebSocketNamespace.DEFAULT: this.notificationsClient.off(eventType, handler); break; } } else { // Если пространство имен не указано, удаляем обработчик из всех активных this.reasoningClient.off(eventType, handler); this.indexingClient.off(eventType, handler); this.dependenciesClient.off(eventType, handler); this.notificationsClient.off(eventType, handler); } } /** * Получает ID сокета для указанного пространства имен * @param {WebSocketNamespace} [namespace=WebSocketNamespace.REASONING] Пространство имен * @returns {string|null} ID сокета или null, если соединение не установлено */ getSocketId(namespace = websocket_namespaces_constants_js_1.WebSocketNamespace.REASONING) { switch (namespace) { case websocket_namespaces_constants_js_1.WebSocketNamespace.REASONING: return this.reasoningClient.getSocketId(); case websocket_namespaces_constants_js_1.WebSocketNamespace.INDEXING: return this.indexingClient.getSocketId(); case websocket_namespaces_constants_js_1.WebSocketNamespace.DEPENDENCIES: return this.dependenciesClient.getSocketId(); case websocket_namespaces_constants_js_1.WebSocketNamespace.DEFAULT: return this.notificationsClient.getSocketId(); default: return null; } } /** * Получает диагностическую информацию о соединениях * @returns {object} Диагностическая информация */ getDiagnostics() { return this.diagnosticsService.getDiagnostics(); } } exports.CodeSolverWebSocketClient = CodeSolverWebSocketClient; //# sourceMappingURL=code-solver-websocket-client.js.map