solver-sdk
Version:
SDK для интеграции с Code Solver Backend API
543 lines • 26.2 kB
JavaScript
"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