solver-sdk 5.1.1 → 5.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +485 -365
- package/dist/cjs/api/indexing-api.js +182 -0
- package/dist/cjs/api/indexing-api.js.map +1 -0
- package/dist/cjs/api/projects-api.js +55 -29
- package/dist/cjs/api/projects-api.js.map +1 -1
- package/dist/cjs/api/search-api.js +19 -2
- package/dist/cjs/api/search-api.js.map +1 -1
- package/dist/cjs/code-solver-sdk.js +65 -6
- package/dist/cjs/code-solver-sdk.js.map +1 -1
- package/dist/cjs/utils/project-sync-client.js +284 -0
- package/dist/cjs/utils/project-sync-client.js.map +1 -0
- package/dist/esm/api/indexing-api.js +178 -0
- package/dist/esm/api/indexing-api.js.map +1 -0
- package/dist/esm/api/projects-api.js +55 -29
- package/dist/esm/api/projects-api.js.map +1 -1
- package/dist/esm/api/search-api.js +19 -2
- package/dist/esm/api/search-api.js.map +1 -1
- package/dist/esm/code-solver-sdk.js +65 -6
- package/dist/esm/code-solver-sdk.js.map +1 -1
- package/dist/esm/utils/project-sync-client.js +280 -0
- package/dist/esm/utils/project-sync-client.js.map +1 -0
- package/dist/types/api/indexing-api.d.ts +131 -0
- package/dist/types/api/indexing-api.d.ts.map +1 -0
- package/dist/types/api/projects-api.d.ts +31 -2
- package/dist/types/api/projects-api.d.ts.map +1 -1
- package/dist/types/api/search-api.d.ts +7 -0
- package/dist/types/api/search-api.d.ts.map +1 -1
- package/dist/types/code-solver-sdk.d.ts +30 -1
- package/dist/types/code-solver-sdk.d.ts.map +1 -1
- package/dist/types/interfaces/sdk-options.d.ts +16 -0
- package/dist/types/interfaces/sdk-options.d.ts.map +1 -1
- package/dist/types/utils/project-sync-client.d.ts +142 -0
- package/dist/types/utils/project-sync-client.d.ts.map +1 -0
- package/package.json +14 -8
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 🔌 Project Sync WebSocket Client
|
|
4
|
+
*
|
|
5
|
+
* Клиент для работы с real-time уведомлениями о статусе синхронизации проектов.
|
|
6
|
+
* Интегрируется с backend ProjectSyncGateway через Socket.io.
|
|
7
|
+
*
|
|
8
|
+
* @features
|
|
9
|
+
* - Real-time push notifications о статусе индексации
|
|
10
|
+
* - Auto-reconnection при разрыве соединения
|
|
11
|
+
* - Graceful fallback к REST polling
|
|
12
|
+
* - TypeScript поддержка для всех событий
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.ProjectSyncClient = void 0;
|
|
16
|
+
const socket_io_client_1 = require("socket.io-client");
|
|
17
|
+
/**
|
|
18
|
+
* 🔌 WebSocket клиент для project sync уведомлений
|
|
19
|
+
*/
|
|
20
|
+
class ProjectSyncClient {
|
|
21
|
+
constructor(options) {
|
|
22
|
+
this.socket = null;
|
|
23
|
+
this.connected = false;
|
|
24
|
+
this.retryCount = 0;
|
|
25
|
+
this.reconnectTimer = null;
|
|
26
|
+
this.subscribedProjects = new Set();
|
|
27
|
+
// Event handlers
|
|
28
|
+
this.eventHandlers = new Map();
|
|
29
|
+
this.baseURL = options.baseURL;
|
|
30
|
+
this.options = {
|
|
31
|
+
connectionTimeout: 10000,
|
|
32
|
+
maxRetries: 5,
|
|
33
|
+
retryDelay: 2000,
|
|
34
|
+
debug: false,
|
|
35
|
+
...options
|
|
36
|
+
};
|
|
37
|
+
// Инициализируем logger
|
|
38
|
+
this.logger = {
|
|
39
|
+
log: (msg) => this.options.debug && console.log(`[ProjectSyncClient] ${msg}`),
|
|
40
|
+
warn: (msg) => this.options.debug && console.warn(`[ProjectSyncClient] ${msg}`),
|
|
41
|
+
error: (msg) => console.error(`[ProjectSyncClient] ${msg}`),
|
|
42
|
+
debug: (msg) => this.options.debug && console.debug(`[ProjectSyncClient] ${msg}`)
|
|
43
|
+
};
|
|
44
|
+
// Инициализируем event handlers map
|
|
45
|
+
const eventTypes = ['sync-status-update', 'sync-progress', 'sync-completed', 'error', 'connected', 'disconnected'];
|
|
46
|
+
eventTypes.forEach(type => {
|
|
47
|
+
this.eventHandlers.set(type, new Set());
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 🔌 Подключение к WebSocket
|
|
52
|
+
*/
|
|
53
|
+
async connect() {
|
|
54
|
+
return new Promise((resolve, reject) => {
|
|
55
|
+
try {
|
|
56
|
+
this.logger.debug(`Подключение к ${this.baseURL}/project-sync`);
|
|
57
|
+
// Создаем Socket.io соединение
|
|
58
|
+
this.socket = (0, socket_io_client_1.io)(`${this.baseURL}/project-sync`, {
|
|
59
|
+
transports: ['websocket', 'polling'],
|
|
60
|
+
timeout: this.options.connectionTimeout,
|
|
61
|
+
reconnectionAttempts: 0, // Отключаем автоматический reconnect Socket.io
|
|
62
|
+
extraHeaders: this.options.headers || {},
|
|
63
|
+
});
|
|
64
|
+
// Обработчик успешного подключения
|
|
65
|
+
this.socket.on('connect', () => {
|
|
66
|
+
this.connected = true;
|
|
67
|
+
this.retryCount = 0;
|
|
68
|
+
this.logger.log('✅ WebSocket подключение установлено');
|
|
69
|
+
this.emit('connected', {});
|
|
70
|
+
resolve();
|
|
71
|
+
});
|
|
72
|
+
// Обработчик отключения
|
|
73
|
+
this.socket.on('disconnect', (reason) => {
|
|
74
|
+
this.connected = false;
|
|
75
|
+
this.logger.warn(`🔌 WebSocket отключен: ${reason}`);
|
|
76
|
+
this.emit('disconnected', { reason });
|
|
77
|
+
// Автоматический переподключение если отключение не намеренное
|
|
78
|
+
if (reason === 'io server disconnect') {
|
|
79
|
+
this.scheduleReconnect();
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
// Обработчик ошибок подключения
|
|
83
|
+
this.socket.on('connect_error', (error) => {
|
|
84
|
+
this.logger.error(`❌ Ошибка подключения: ${error.message}`);
|
|
85
|
+
reject(new Error(`WebSocket connection failed: ${error.message}`));
|
|
86
|
+
});
|
|
87
|
+
// 📊 Обработчики project sync событий
|
|
88
|
+
this.setupEventHandlers();
|
|
89
|
+
// Таймаут подключения
|
|
90
|
+
setTimeout(() => {
|
|
91
|
+
if (!this.connected) {
|
|
92
|
+
reject(new Error('WebSocket connection timeout'));
|
|
93
|
+
}
|
|
94
|
+
}, this.options.connectionTimeout);
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
reject(error);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* ❌ Отключение от WebSocket
|
|
103
|
+
*/
|
|
104
|
+
disconnect() {
|
|
105
|
+
if (this.reconnectTimer) {
|
|
106
|
+
clearTimeout(this.reconnectTimer);
|
|
107
|
+
this.reconnectTimer = null;
|
|
108
|
+
}
|
|
109
|
+
if (this.socket) {
|
|
110
|
+
this.socket.disconnect();
|
|
111
|
+
this.socket = null;
|
|
112
|
+
}
|
|
113
|
+
this.connected = false;
|
|
114
|
+
this.subscribedProjects.clear();
|
|
115
|
+
this.logger.log('🔌 WebSocket отключен вручную');
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* 📡 Подписка на проект для получения уведомлений
|
|
119
|
+
*/
|
|
120
|
+
subscribeToProject(projectId, userId) {
|
|
121
|
+
if (!this.connected || !this.socket) {
|
|
122
|
+
this.logger.warn(`⚠️ Попытка подписки на проект ${projectId} без соединения`);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const joinData = {
|
|
126
|
+
projectId,
|
|
127
|
+
userId
|
|
128
|
+
};
|
|
129
|
+
this.socket.emit('join-project-sync', joinData);
|
|
130
|
+
this.subscribedProjects.add(projectId);
|
|
131
|
+
this.logger.debug(`📡 Подписка на проект: ${projectId}`);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* 📡 Отписка от проекта
|
|
135
|
+
*/
|
|
136
|
+
unsubscribeFromProject(projectId) {
|
|
137
|
+
if (!this.connected || !this.socket) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
this.socket.emit('leave-project-sync', { projectId });
|
|
141
|
+
this.subscribedProjects.delete(projectId);
|
|
142
|
+
this.logger.debug(`📡 Отписка от проекта: ${projectId}`);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* 👂 Подписка на события
|
|
146
|
+
*/
|
|
147
|
+
on(event, handler) {
|
|
148
|
+
const handlers = this.eventHandlers.get(event);
|
|
149
|
+
if (handlers) {
|
|
150
|
+
handlers.add(handler);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* 👂 Отписка от событий
|
|
155
|
+
*/
|
|
156
|
+
off(event, handler) {
|
|
157
|
+
const handlers = this.eventHandlers.get(event);
|
|
158
|
+
if (handlers) {
|
|
159
|
+
handlers.delete(handler);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* 📢 Эмиссия событий
|
|
164
|
+
*/
|
|
165
|
+
emit(event, data) {
|
|
166
|
+
const handlers = this.eventHandlers.get(event);
|
|
167
|
+
if (handlers) {
|
|
168
|
+
handlers.forEach(handler => {
|
|
169
|
+
try {
|
|
170
|
+
handler(data);
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
this.logger.error(`Error in event handler for ${event}: ${error}`);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* 🔧 Настройка обработчиков событий от backend
|
|
180
|
+
*/
|
|
181
|
+
setupEventHandlers() {
|
|
182
|
+
if (!this.socket)
|
|
183
|
+
return;
|
|
184
|
+
// 📊 Обновление статуса синхронизации
|
|
185
|
+
this.socket.on('sync-status-update', (data) => {
|
|
186
|
+
const safeData = {
|
|
187
|
+
projectId: data?.projectId || 'unknown',
|
|
188
|
+
sessionId: data?.sessionId || 'unknown',
|
|
189
|
+
status: data?.status || 'unknown',
|
|
190
|
+
progress: data?.progress || 0,
|
|
191
|
+
message: data?.message || '',
|
|
192
|
+
timestamp: data?.timestamp || new Date(),
|
|
193
|
+
chunksProcessed: data?.chunksProcessed || 0,
|
|
194
|
+
totalChunks: data?.totalChunks || 0,
|
|
195
|
+
embeddingsCreated: data?.embeddingsCreated || 0
|
|
196
|
+
};
|
|
197
|
+
this.logger.debug(`📊 Статус обновлен: ${safeData.status} для проекта ${safeData.projectId}`);
|
|
198
|
+
this.emit('sync-status-update', safeData);
|
|
199
|
+
});
|
|
200
|
+
// 📈 Прогресс синхронизации
|
|
201
|
+
this.socket.on('sync-progress', (data) => {
|
|
202
|
+
const safeData = {
|
|
203
|
+
projectId: data?.projectId || 'unknown',
|
|
204
|
+
sessionId: data?.sessionId || 'unknown',
|
|
205
|
+
stage: data?.stage || 'unknown',
|
|
206
|
+
progress: data?.progress || 0,
|
|
207
|
+
currentChunk: data?.currentChunk || 0,
|
|
208
|
+
totalChunks: data?.totalChunks || 0,
|
|
209
|
+
estimatedTimeRemaining: data?.estimatedTimeRemaining || 0,
|
|
210
|
+
details: data?.details || ''
|
|
211
|
+
};
|
|
212
|
+
this.logger.debug(`📈 Прогресс: ${safeData.progress}% (${safeData.stage}) для проекта ${safeData.projectId}`);
|
|
213
|
+
this.emit('sync-progress', safeData);
|
|
214
|
+
});
|
|
215
|
+
// ✅ Синхронизация завершена
|
|
216
|
+
this.socket.on('sync-completed', (data) => {
|
|
217
|
+
const safeData = {
|
|
218
|
+
projectId: data?.projectId || 'unknown',
|
|
219
|
+
sessionId: data?.sessionId || 'unknown',
|
|
220
|
+
success: data?.success !== false, // По умолчанию true
|
|
221
|
+
message: data?.message || '',
|
|
222
|
+
totalProcessed: data?.totalProcessed || 0,
|
|
223
|
+
duration: data?.duration || 0,
|
|
224
|
+
error: data?.error || ''
|
|
225
|
+
};
|
|
226
|
+
this.logger.log(`✅ Синхронизация завершена: ${safeData.success ? 'SUCCESS' : 'FAILED'} для проекта ${safeData.projectId}`);
|
|
227
|
+
this.emit('sync-completed', safeData);
|
|
228
|
+
});
|
|
229
|
+
// ❌ Ошибки
|
|
230
|
+
this.socket.on('error', (data) => {
|
|
231
|
+
// Безопасная обработка undefined/неполных данных
|
|
232
|
+
const safeData = {
|
|
233
|
+
projectId: data?.projectId || 'unknown',
|
|
234
|
+
sessionId: data?.sessionId || 'unknown',
|
|
235
|
+
error: data?.error || String(data) || 'Unknown error',
|
|
236
|
+
code: data?.code || 'UNKNOWN_ERROR',
|
|
237
|
+
timestamp: data?.timestamp || new Date(),
|
|
238
|
+
recoverable: data?.recoverable !== false // По умолчанию true
|
|
239
|
+
};
|
|
240
|
+
this.logger.error(`❌ Ошибка для проекта ${safeData.projectId}: ${safeData.error}`);
|
|
241
|
+
this.emit('error', safeData);
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* 🔄 Планирование переподключения
|
|
246
|
+
*/
|
|
247
|
+
scheduleReconnect() {
|
|
248
|
+
if (this.retryCount >= this.options.maxRetries) {
|
|
249
|
+
this.logger.error(`❌ Превышено максимальное количество попыток переподключения (${this.options.maxRetries})`);
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
const delay = Math.min(this.options.retryDelay * Math.pow(2, this.retryCount), 30000);
|
|
253
|
+
this.retryCount++;
|
|
254
|
+
this.logger.warn(`🔄 Переподключение через ${delay}ms (попытка ${this.retryCount}/${this.options.maxRetries})`);
|
|
255
|
+
this.reconnectTimer = setTimeout(async () => {
|
|
256
|
+
try {
|
|
257
|
+
await this.connect();
|
|
258
|
+
// Восстанавливаем подписки на проекты
|
|
259
|
+
this.subscribedProjects.forEach(projectId => {
|
|
260
|
+
this.subscribeToProject(projectId);
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
catch (error) {
|
|
264
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
265
|
+
this.logger.error(`❌ Ошибка переподключения: ${errorMessage}`);
|
|
266
|
+
this.scheduleReconnect(); // Планируем следующую попытку
|
|
267
|
+
}
|
|
268
|
+
}, delay);
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* 🔍 Проверка статуса подключения
|
|
272
|
+
*/
|
|
273
|
+
get isConnected() {
|
|
274
|
+
return this.connected;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* 📋 Список подписанных проектов
|
|
278
|
+
*/
|
|
279
|
+
get subscribedProjectIds() {
|
|
280
|
+
return Array.from(this.subscribedProjects);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
exports.ProjectSyncClient = ProjectSyncClient;
|
|
284
|
+
//# sourceMappingURL=project-sync-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-sync-client.js","sourceRoot":"","sources":["../../../src/utils/project-sync-client.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;AAEH,uDAA8C;AAmF9C;;GAEG;AACH,MAAa,iBAAiB;IAsB5B,YAAY,OAAiC;QArBrC,WAAM,GAAkB,IAAI,CAAC;QAG7B,cAAS,GAAY,KAAK,CAAC;QAC3B,eAAU,GAAW,CAAC,CAAC;QACvB,mBAAc,GAAQ,IAAI,CAAC;QAC3B,uBAAkB,GAAgB,IAAI,GAAG,EAAE,CAAC;QAEpD,iBAAiB;QACT,kBAAa,GAA+C,IAAI,GAAG,EAAE,CAAC;QAa5E,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,OAAO,GAAG;YACb,iBAAiB,EAAE,KAAK;YACxB,UAAU,EAAE,CAAC;YACb,UAAU,EAAE,IAAI;YAChB,KAAK,EAAE,KAAK;YACZ,GAAG,OAAO;SACX,CAAC;QAEF,wBAAwB;QACxB,IAAI,CAAC,MAAM,GAAG;YACZ,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,GAAG,EAAE,CAAC;YAC7E,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,uBAAuB,GAAG,EAAE,CAAC;YAC/E,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,uBAAuB,GAAG,EAAE,CAAC;YAC3D,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,uBAAuB,GAAG,EAAE,CAAC;SAClF,CAAC;QAEF,oCAAoC;QACpC,MAAM,UAAU,GAAgB,CAAC,oBAAoB,EAAE,eAAe,EAAE,gBAAgB,EAAE,OAAO,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;QAChI,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACxB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,OAAO;QAClB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,CAAC;gBACH,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,IAAI,CAAC,OAAO,eAAe,CAAC,CAAC;gBAEhE,+BAA+B;gBAC/B,IAAI,CAAC,MAAM,GAAG,IAAA,qBAAE,EAAC,GAAG,IAAI,CAAC,OAAO,eAAe,EAAE;oBAC/C,UAAU,EAAE,CAAC,WAAW,EAAE,SAAS,CAAC;oBACpC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB;oBACvC,oBAAoB,EAAE,CAAC,EAAE,+CAA+C;oBACxE,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE;iBACzC,CAAC,CAAC;gBAEH,mCAAmC;gBACnC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;oBAC7B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;oBACtB,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;oBACpB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;oBACvD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;oBAC3B,OAAO,EAAE,CAAC;gBACZ,CAAC,CAAC,CAAC;gBAEH,wBAAwB;gBACxB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE;oBACtC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;oBACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,MAAM,EAAE,CAAC,CAAC;oBACrD,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;oBAEtC,+DAA+D;oBAC/D,IAAI,MAAM,KAAK,sBAAsB,EAAE,CAAC;wBACtC,IAAI,CAAC,iBAAiB,EAAE,CAAC;oBAC3B,CAAC;gBACH,CAAC,CAAC,CAAC;gBAEH,gCAAgC;gBAChC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE;oBACxC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;oBAC5D,MAAM,CAAC,IAAI,KAAK,CAAC,gCAAgC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBACrE,CAAC,CAAC,CAAC;gBAEH,sCAAsC;gBACtC,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAE1B,sBAAsB;gBACtB,UAAU,CAAC,GAAG,EAAE;oBACd,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;wBACpB,MAAM,CAAC,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC,CAAC;oBACpD,CAAC;gBACH,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;YAErC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,KAAK,CAAC,CAAC;YAChB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACI,UAAU;QACf,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAClC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,CAAC;QAED,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACI,kBAAkB,CAAC,SAAiB,EAAE,MAAe;QAC1D,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACpC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iCAAiC,SAAS,iBAAiB,CAAC,CAAC;YAC9E,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAuB;YACnC,SAAS;YACT,MAAM;SACP,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC;QAChD,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,SAAS,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED;;OAEG;IACI,sBAAsB,CAAC,SAAiB;QAC7C,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACpC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,SAAS,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED;;OAEG;IACI,EAAE,CAAI,KAAgB,EAAE,OAA4B;QACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED;;OAEG;IACI,GAAG,CAAI,KAAgB,EAAE,OAA4B;QAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED;;OAEG;IACK,IAAI,CAAI,KAAgB,EAAE,IAAO;QACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;gBACzB,IAAI,CAAC;oBACH,OAAO,CAAC,IAAI,CAAC,CAAC;gBAChB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,KAAK,KAAK,KAAK,EAAE,CAAC,CAAC;gBACrE,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;OAEG;IACK,kBAAkB;QACxB,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QAEzB,sCAAsC;QACtC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,IAA4B,EAAE,EAAE;YACpE,MAAM,QAAQ,GAAG;gBACf,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,SAAS;gBACvC,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,SAAS;gBACvC,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,SAAS;gBACjC,QAAQ,EAAE,IAAI,EAAE,QAAQ,IAAI,CAAC;gBAC7B,OAAO,EAAE,IAAI,EAAE,OAAO,IAAI,EAAE;gBAC5B,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,IAAI,IAAI,EAAE;gBACxC,eAAe,EAAE,IAAI,EAAE,eAAe,IAAI,CAAC;gBAC3C,WAAW,EAAE,IAAI,EAAE,WAAW,IAAI,CAAC;gBACnC,iBAAiB,EAAE,IAAI,EAAE,iBAAiB,IAAI,CAAC;aAChD,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,QAAQ,CAAC,MAAM,gBAAgB,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;YAC9F,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,4BAA4B;QAC5B,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,IAA6B,EAAE,EAAE;YAChE,MAAM,QAAQ,GAAG;gBACf,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,SAAS;gBACvC,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,SAAS;gBACvC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,SAAS;gBAC/B,QAAQ,EAAE,IAAI,EAAE,QAAQ,IAAI,CAAC;gBAC7B,YAAY,EAAE,IAAI,EAAE,YAAY,IAAI,CAAC;gBACrC,WAAW,EAAE,IAAI,EAAE,WAAW,IAAI,CAAC;gBACnC,sBAAsB,EAAE,IAAI,EAAE,sBAAsB,IAAI,CAAC;gBACzD,OAAO,EAAE,IAAI,EAAE,OAAO,IAAI,EAAE;aAC7B,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,QAAQ,CAAC,QAAQ,MAAM,QAAQ,CAAC,KAAK,iBAAiB,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;YAC9G,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,4BAA4B;QAC5B,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC,IAA8B,EAAE,EAAE;YAClE,MAAM,QAAQ,GAAG;gBACf,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,SAAS;gBACvC,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,SAAS;gBACvC,OAAO,EAAE,IAAI,EAAE,OAAO,KAAK,KAAK,EAAE,oBAAoB;gBACtD,OAAO,EAAE,IAAI,EAAE,OAAO,IAAI,EAAE;gBAC5B,cAAc,EAAE,IAAI,EAAE,cAAc,IAAI,CAAC;gBACzC,QAAQ,EAAE,IAAI,EAAE,QAAQ,IAAI,CAAC;gBAC7B,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE;aACzB,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,8BAA8B,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,gBAAgB,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;YAC3H,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,WAAW;QACX,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAsB,EAAE,EAAE;YACjD,iDAAiD;YACjD,MAAM,QAAQ,GAAG;gBACf,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,SAAS;gBACvC,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,SAAS;gBACvC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,eAAe;gBACrD,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,eAAe;gBACnC,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,IAAI,IAAI,EAAE;gBACxC,WAAW,EAAE,IAAI,EAAE,WAAW,KAAK,KAAK,CAAC,oBAAoB;aAC9D,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,QAAQ,CAAC,SAAS,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;YACnF,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,iBAAiB;QACvB,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC,UAAW,EAAE,CAAC;YAChD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gEAAgE,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,CAAC,CAAC;YAC9G,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,UAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,CAAC;QACvF,IAAI,CAAC,UAAU,EAAE,CAAC;QAElB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,4BAA4B,KAAK,eAAe,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,CAAC,CAAC;QAEhH,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE;YAC1C,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;gBAErB,sCAAsC;gBACtC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;oBAC1C,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;gBACrC,CAAC,CAAC,CAAC;YAEL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC5E,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,YAAY,EAAE,CAAC,CAAC;gBAC/D,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC,8BAA8B;YAC1D,CAAC;QACH,CAAC,EAAE,KAAK,CAAC,CAAC;IACZ,CAAC;IAED;;OAEG;IACH,IAAW,WAAW;QACpB,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,IAAW,oBAAoB;QAC7B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC7C,CAAC;CACF;AAvTD,8CAuTC"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🚀 Indexing API - управление индексацией проектов
|
|
3
|
+
*
|
|
4
|
+
* Предоставляет методы для запуска, остановки и мониторинга
|
|
5
|
+
* индексации проектов, а также получения статуса.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* API для управления индексацией проектов
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```javascript
|
|
12
|
+
* // Создание и индексация проекта
|
|
13
|
+
* const result = await sdk.indexing.indexProject('/path/to/project', 'My Project');
|
|
14
|
+
* console.log('Project ID:', result.projectId);
|
|
15
|
+
*
|
|
16
|
+
* // Получение статуса индексации
|
|
17
|
+
* const status = await sdk.indexing.getStatus(result.projectId);
|
|
18
|
+
* console.log('Progress:', status.progress);
|
|
19
|
+
*
|
|
20
|
+
* // Ожидание завершения индексации
|
|
21
|
+
* const finalStatus = await sdk.indexing.waitForCompletion(result.projectId);
|
|
22
|
+
* console.log('Final status:', finalStatus.status);
|
|
23
|
+
*
|
|
24
|
+
* // Отмена индексации
|
|
25
|
+
* await sdk.indexing.cancelIndexing(result.projectId);
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export class IndexingApi {
|
|
29
|
+
constructor(httpClient) {
|
|
30
|
+
this.httpClient = httpClient;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Создает проект и запускает его индексацию
|
|
34
|
+
*
|
|
35
|
+
* @param {string} projectPath Путь к проекту (для совместимости с тестами)
|
|
36
|
+
* @param {string} projectName Имя проекта
|
|
37
|
+
* @param {string} [description] Описание проекта
|
|
38
|
+
* @returns {Promise<IndexProjectResult>} Результат создания проекта
|
|
39
|
+
*/
|
|
40
|
+
async indexProject(projectPath, projectName, description) {
|
|
41
|
+
// Создаем проект
|
|
42
|
+
const createRequest = {
|
|
43
|
+
name: projectName,
|
|
44
|
+
description: description || `Проект из ${projectPath}`
|
|
45
|
+
};
|
|
46
|
+
const project = await this.httpClient.post('/api/v1/projects', createRequest);
|
|
47
|
+
// Запускаем индексацию
|
|
48
|
+
const indexingResult = await this.httpClient.post(`/api/v1/projects/${project.id}/index`);
|
|
49
|
+
return {
|
|
50
|
+
projectId: project.id,
|
|
51
|
+
name: project.name,
|
|
52
|
+
status: indexingResult.status || 'started',
|
|
53
|
+
message: indexingResult.message || 'Индексация запущена'
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Получает текущий статус индексации проекта
|
|
58
|
+
*
|
|
59
|
+
* ⚠️ ВАЖНО: Для real-time уведомлений используйте WebSocket:
|
|
60
|
+
* ```typescript
|
|
61
|
+
* // Правильно (real-time):
|
|
62
|
+
* await sdk.connectWebSocket();
|
|
63
|
+
* sdk.projectSync.on('sync-status-update', (status) => {
|
|
64
|
+
* console.log('Статус обновлен:', status);
|
|
65
|
+
* });
|
|
66
|
+
*
|
|
67
|
+
* // Неправильно (не делайте polling):
|
|
68
|
+
* // setInterval(() => sdk.indexing.getStatus(id), 2000); // ❌
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @param {string} projectId ID проекта
|
|
72
|
+
* @returns {Promise<IndexingStatus>} Текущий статус индексации
|
|
73
|
+
*/
|
|
74
|
+
async getStatus(projectId) {
|
|
75
|
+
this.validateProjectId(projectId);
|
|
76
|
+
const status = await this.httpClient.get(`/api/v1/projects/${projectId}/indexing-status`);
|
|
77
|
+
return {
|
|
78
|
+
status: status.status || 'unknown',
|
|
79
|
+
progress: status.progress || 0,
|
|
80
|
+
totalFiles: status.totalFiles,
|
|
81
|
+
processedFiles: status.processedFiles,
|
|
82
|
+
currentFile: status.currentFile,
|
|
83
|
+
error: status.error,
|
|
84
|
+
updatedAt: new Date().toISOString()
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Ожидает завершения индексации проекта
|
|
89
|
+
*
|
|
90
|
+
* ⚠️ DEPRECATED: Используйте WebSocket для real-time уведомлений
|
|
91
|
+
*
|
|
92
|
+
* @param {string} projectId ID проекта
|
|
93
|
+
* @param {number} [timeout=300000] Таймаут в миллисекундах (по умолчанию 5 минут)
|
|
94
|
+
* @returns {Promise<IndexingStatus>} Финальный статус индексации
|
|
95
|
+
*/
|
|
96
|
+
async waitForCompletion(projectId, timeout = 300000) {
|
|
97
|
+
this.validateProjectId(projectId);
|
|
98
|
+
const startTime = Date.now();
|
|
99
|
+
const pollInterval = 2000; // 2 секунды
|
|
100
|
+
return new Promise((resolve, reject) => {
|
|
101
|
+
const checkStatus = async () => {
|
|
102
|
+
try {
|
|
103
|
+
const status = await this.getStatus(projectId);
|
|
104
|
+
// Проверяем завершение
|
|
105
|
+
if (status.status === 'completed' || status.status === 'complete') {
|
|
106
|
+
resolve(status);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
// Проверяем ошибку
|
|
110
|
+
if (status.status === 'failed' || status.status === 'error') {
|
|
111
|
+
resolve(status);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
// Проверяем таймаут
|
|
115
|
+
if (Date.now() - startTime > timeout) {
|
|
116
|
+
reject(new Error(`Таймаут ожидания завершения индексации (${timeout}ms)`));
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
// Продолжаем ожидание
|
|
120
|
+
setTimeout(checkStatus, pollInterval);
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
reject(error);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
checkStatus();
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Отменяет текущую индексацию проекта
|
|
131
|
+
*
|
|
132
|
+
* @param {string} projectId ID проекта
|
|
133
|
+
* @returns {Promise<void>}
|
|
134
|
+
*/
|
|
135
|
+
async cancelIndexing(projectId) {
|
|
136
|
+
this.validateProjectId(projectId);
|
|
137
|
+
await this.httpClient.post(`/api/v1/projects/${projectId}/cancel-indexing`);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Перезапускает индексацию проекта
|
|
141
|
+
*
|
|
142
|
+
* @param {string} projectId ID проекта
|
|
143
|
+
* @returns {Promise<IndexingStatus>} Статус после перезапуска
|
|
144
|
+
*/
|
|
145
|
+
async restartIndexing(projectId) {
|
|
146
|
+
this.validateProjectId(projectId);
|
|
147
|
+
// Сначала отменяем текущую индексацию
|
|
148
|
+
try {
|
|
149
|
+
await this.cancelIndexing(projectId);
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
// Игнорируем ошибки отмены - возможно индексация уже завершена
|
|
153
|
+
}
|
|
154
|
+
// Запускаем новую индексацию
|
|
155
|
+
const result = await this.httpClient.post(`/api/v1/projects/${projectId}/index`);
|
|
156
|
+
return {
|
|
157
|
+
status: result.status || 'started',
|
|
158
|
+
progress: 0,
|
|
159
|
+
updatedAt: new Date().toISOString()
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Валидация ID проекта
|
|
164
|
+
* @private
|
|
165
|
+
*/
|
|
166
|
+
validateProjectId(projectId) {
|
|
167
|
+
if (projectId === undefined || projectId === null) {
|
|
168
|
+
throw new Error('Project ID is required');
|
|
169
|
+
}
|
|
170
|
+
if (typeof projectId !== 'string') {
|
|
171
|
+
throw new Error('Project ID must be a string');
|
|
172
|
+
}
|
|
173
|
+
if (projectId.trim().length === 0) {
|
|
174
|
+
throw new Error('Project ID cannot be empty');
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=indexing-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexing-api.js","sourceRoot":"","sources":["../../../src/api/indexing-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -73,26 +73,45 @@ export class ProjectsApi {
|
|
|
73
73
|
* @throws {Error} Если не удалось получить проекты или сервер вернул ошибку
|
|
74
74
|
*/
|
|
75
75
|
async getAllProjects() {
|
|
76
|
-
//
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
76
|
+
// HttpClient уже извлекает data из axios response, возвращая прямой массив Project[]
|
|
77
|
+
const projects = await this.httpClient.get('/api/v1/projects');
|
|
78
|
+
return projects;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Псевдоним для getAllProjects() для совместимости с тестами
|
|
82
|
+
*
|
|
83
|
+
* @returns {Promise<Project[]>} Массив проектов пользователя
|
|
84
|
+
*/
|
|
85
|
+
async getProjects() {
|
|
86
|
+
return this.getAllProjects();
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Находит существующий проект или создает новый
|
|
90
|
+
* Для совместимости с интеграционными тестами
|
|
91
|
+
*
|
|
92
|
+
* @param {string} projectPath Путь к проекту (для совместимости)
|
|
93
|
+
* @param {string} projectName Имя проекта
|
|
94
|
+
* @param {string} [description] Описание проекта
|
|
95
|
+
* @returns {Promise<Project>} Найденный или созданный проект
|
|
96
|
+
*/
|
|
97
|
+
async findOrCreateProject(projectPath, projectName, description) {
|
|
98
|
+
// Сначала пытаемся найти существующий проект по имени
|
|
99
|
+
const projects = await this.getAllProjects();
|
|
100
|
+
const existingProject = projects.find(p => p.name === projectName);
|
|
101
|
+
if (existingProject) {
|
|
102
|
+
return existingProject;
|
|
81
103
|
}
|
|
82
|
-
|
|
104
|
+
// Если не найден, создаем новый
|
|
105
|
+
return this.createProject(projectName, projectPath, { description: description || `Проект из ${projectPath}` });
|
|
83
106
|
}
|
|
84
107
|
/**
|
|
85
108
|
* Получает список готовых к работе проектов
|
|
86
109
|
* @returns {Promise<Project[]>} Список готовых проектов
|
|
87
110
|
*/
|
|
88
111
|
async getReadyProjects() {
|
|
89
|
-
//
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
const error = response.error;
|
|
93
|
-
throw new Error(error?.message || 'Не удалось получить готовые проекты');
|
|
94
|
-
}
|
|
95
|
-
return response.data;
|
|
112
|
+
// HttpClient уже извлекает data из axios response, возвращая прямой массив Project[]
|
|
113
|
+
const projects = await this.httpClient.get('/api/v1/projects/ready');
|
|
114
|
+
return projects;
|
|
96
115
|
}
|
|
97
116
|
/**
|
|
98
117
|
* Получает детальную информацию о проекте по его ID
|
|
@@ -123,13 +142,9 @@ export class ProjectsApi {
|
|
|
123
142
|
* @throws {Error} Если проект не найден или произошла ошибка сервера
|
|
124
143
|
*/
|
|
125
144
|
async getProject(projectId) {
|
|
126
|
-
//
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
const error = response.error;
|
|
130
|
-
throw new Error(error?.message || `Не удалось найти проект ${projectId}`);
|
|
131
|
-
}
|
|
132
|
-
return response.data;
|
|
145
|
+
// HttpClient уже извлекает data из axios response, возвращая прямой объект Project
|
|
146
|
+
const project = await this.httpClient.get(`/api/v1/projects/${projectId}`);
|
|
147
|
+
return project;
|
|
133
148
|
}
|
|
134
149
|
/**
|
|
135
150
|
* Создает новый проект или возвращает существующий (автоматическая дедупликация)
|
|
@@ -177,12 +192,9 @@ export class ProjectsApi {
|
|
|
177
192
|
description: data.description,
|
|
178
193
|
...data
|
|
179
194
|
};
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
throw new Error(error?.message || `Не удалось создать проект "${name}"`);
|
|
184
|
-
}
|
|
185
|
-
return response.data;
|
|
195
|
+
// HttpClient уже извлекает data из axios response, возвращая прямой объект Project
|
|
196
|
+
const project = await this.httpClient.post('/api/v1/projects', projectData);
|
|
197
|
+
return project;
|
|
186
198
|
}
|
|
187
199
|
/**
|
|
188
200
|
* Получает статус проекта
|
|
@@ -211,13 +223,25 @@ export class ProjectsApi {
|
|
|
211
223
|
throw new Error('Метод deleteProject не поддерживается текущей версией бэкенда');
|
|
212
224
|
}
|
|
213
225
|
/**
|
|
214
|
-
* Получает статус индексации проекта
|
|
226
|
+
* Получает текущий статус индексации проекта (единичный запрос)
|
|
227
|
+
*
|
|
228
|
+
* ⚠️ ВАЖНО: Для real-time уведомлений используйте WebSocket:
|
|
229
|
+
* ```typescript
|
|
230
|
+
* // Правильно (real-time):
|
|
231
|
+
* await sdk.connectWebSocket();
|
|
232
|
+
* sdk.projectSync.on('sync-status-update', (status) => {
|
|
233
|
+
* console.log('Статус обновлен:', status);
|
|
234
|
+
* });
|
|
235
|
+
*
|
|
236
|
+
* // Неправильно (не делайте polling):
|
|
237
|
+
* // setInterval(() => sdk.projects.getIndexingStatus(id), 2000); // ❌
|
|
238
|
+
* ```
|
|
239
|
+
*
|
|
215
240
|
* @param {string} projectId Идентификатор проекта
|
|
216
|
-
* @returns {Promise<any>}
|
|
241
|
+
* @returns {Promise<any>} Текущий статус индексации (snapshot)
|
|
217
242
|
*/
|
|
218
243
|
async getIndexingStatus(projectId) {
|
|
219
244
|
this.validateProjectId(projectId);
|
|
220
|
-
// ✅ ИСПРАВЛЕНИЕ: Используем новый эндпоинт с real-time статусом и безопасной сериализацией
|
|
221
245
|
return this.httpClient.get(`/api/v1/projects/${projectId}/indexing-status`);
|
|
222
246
|
}
|
|
223
247
|
/**
|
|
@@ -558,6 +582,7 @@ export class ProjectsApi {
|
|
|
558
582
|
async finalizeDeltaSync(projectId) {
|
|
559
583
|
this.validateProjectId(projectId);
|
|
560
584
|
const response = await this.httpClient.post(`/api/v1/projects/${projectId}/sync-finalize`, {});
|
|
585
|
+
// HttpClient уже извлекает data из axios response, response - это прямой объект от backend
|
|
561
586
|
return {
|
|
562
587
|
success: response.success || false,
|
|
563
588
|
projectId,
|
|
@@ -577,6 +602,7 @@ export class ProjectsApi {
|
|
|
577
602
|
async cancelDeltaSync(projectId) {
|
|
578
603
|
this.validateProjectId(projectId);
|
|
579
604
|
const response = await this.httpClient.delete(`/api/v1/projects/${projectId}/sync-cancel`);
|
|
605
|
+
// HttpClient уже извлекает data из axios response, response - это прямой объект от backend
|
|
580
606
|
return {
|
|
581
607
|
success: response.success || false,
|
|
582
608
|
message: response.message
|