sip-connector 15.3.0 → 16.0.0

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.
Files changed (41) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +526 -88
  3. package/dist/@SipConnector-DcaeAFrM.cjs +1 -0
  4. package/dist/{@SipConnector-Gt9XLkRE.js → @SipConnector-uiUlVCMv.js} +962 -401
  5. package/dist/CallManager/types.d.ts +2 -0
  6. package/dist/PresentationManager/@PresentationManager.d.ts +5 -3
  7. package/dist/SipConnector/@SipConnector.d.ts +14 -4
  8. package/dist/SipConnector/eventNames.d.ts +1 -1
  9. package/dist/SipConnectorFacade/SipConnectorFacade.d.ts +10 -21
  10. package/dist/StatsPeerConnection/StatsPeerConnection.d.ts +1 -1
  11. package/dist/StatsPeerConnection/__fixtures__/callStaticsState.d.ts +3 -3
  12. package/dist/StatsPeerConnection/eventNames.d.ts +3 -3
  13. package/dist/StatsPeerConnection/index.d.ts +1 -0
  14. package/dist/StatsPeerConnection/parseStatsReports.d.ts +3 -3
  15. package/dist/StatsPeerConnection/requestAllStatistics.d.ts +1 -1
  16. package/dist/StatsPeerConnection/{typings.d.ts → types.d.ts} +2 -2
  17. package/dist/VideoSendingBalancer/SenderBalancer.d.ts +3 -1
  18. package/dist/VideoSendingBalancer/TrackMonitor.d.ts +38 -0
  19. package/dist/VideoSendingBalancer/VideoSendingBalancer.d.ts +8 -9
  20. package/dist/VideoSendingBalancer/VideoSendingEventHandler.d.ts +4 -9
  21. package/dist/VideoSendingBalancer/__fixtures__/createMockTrack.d.ts +5 -0
  22. package/dist/VideoSendingBalancer/__fixtures__/index.d.ts +1 -0
  23. package/dist/VideoSendingBalancer/index.d.ts +1 -2
  24. package/dist/VideoSendingBalancer/types.d.ts +0 -1
  25. package/dist/VideoSendingBalancerManager/@VideoSendingBalancerManager.d.ts +47 -0
  26. package/dist/VideoSendingBalancerManager/eventNames.d.ts +20 -0
  27. package/dist/VideoSendingBalancerManager/index.d.ts +3 -0
  28. package/dist/doMock.cjs +1 -1
  29. package/dist/doMock.js +1 -1
  30. package/dist/index.cjs +1 -1
  31. package/dist/index.d.ts +2 -2
  32. package/dist/index.js +281 -748
  33. package/dist/logger.d.ts +0 -1
  34. package/dist/tools/setCodecPreferences.d.ts +5 -0
  35. package/dist/tools/setParametersToSender/index.d.ts +1 -0
  36. package/package.json +5 -5
  37. package/dist/@SipConnector-DV4Ywba-.cjs +0 -1
  38. package/dist/tools/generateSimulcastEncodings.d.ts +0 -7
  39. package/dist/tools/resolveUpdateTransceiver.d.ts +0 -6
  40. package/dist/tools/scaleResolutionAndBitrate.d.ts +0 -10
  41. /package/dist/{PresentationManager → SipConnector}/constants.d.ts +0 -0
package/README.md CHANGED
@@ -3,189 +3,627 @@
3
3
  [![npm](https://img.shields.io/npm/v/sip-connector?style=flat-square)](https://www.npmjs.com/package/sip-connector)
4
4
  ![npm bundle size](https://img.shields.io/bundlephobia/minzip/sip-connector?style=flat-square)
5
5
 
6
- TypeScript SDK для подключения к Vinteo по WebRTC через SIP (на базе `@krivega/jssip`). Предоставляет высокий уровень API для:
6
+ ---
7
7
 
8
- - подключения/регистрации на SIP-сервере;
9
- - исходящих/входящих звонков;
10
- - управления презентацией (share screen/video);
11
- - отправки служебных сообщений (DTMF, каналы, синхронизация медиа-состояния);
12
- - подписки на события платформы.
8
+ ## 📖 Описание
13
9
 
14
- ## Установка
10
+ **sip-connector** — это TypeScript SDK для интеграции WebRTC-приложений с платформой Vinteo через SIP-протокол. Библиотека построена на базе `@krivega/jssip` и предоставляет высокоуровневый API для создания полнофункциональных видеоконференций.
15
11
 
16
- ```sh
12
+ ### 🎯 Основные возможности
13
+
14
+ SDK предоставляет комплексное решение для:
15
+
16
+ | Категория | Возможности |
17
+ | ---------------------------- | ------------------------------------------------------------- |
18
+ | **SIP-подключения** | Регистрация на сервере (SIP REGISTER), управление сессиями |
19
+ | **WebRTC-коммуникации** | Исходящие/входящие звонки (SIP INVITE/200 OK), медиа-потоки |
20
+ | **Презентации** | Отправка второго потока (screen sharing, демонстрация экрана) |
21
+ | **Системные сообщения** | DTMF, SIP INFO, синхронизация медиа-состояния |
22
+ | **Событийная архитектура** | Подписка на события платформы в реальном времени |
23
+ | **Мониторинг** | WebRTC-статистика (RTCRtpStats, ICE candidate stats) |
24
+ | **Управление конференциями** | Перемещение участников между ролями (участник/зритель) |
25
+ | **Лицензирование** | Мониторинг использования лицензий и состояния презентаций |
26
+
27
+ ### 🏗️ Архитектура
28
+
29
+ SDK построен по принципу **слоистой архитектуры**:
30
+
31
+ - **SipConnector** — низкоуровневый слой с менеджерами (Connection, Call, Presentation, API)
32
+ - **SipConnectorFacade** — высокоуровневый фасад с готовыми сценариями
33
+ - **Специализированные менеджеры** — для статистики, участников, медиа-потоков
34
+
35
+ ---
36
+
37
+ ## 🚀 Установка
38
+
39
+ ### Команды установки
40
+
41
+ ```bash
42
+ # npm
17
43
  npm install sip-connector
18
- # или
44
+
45
+ # yarn
19
46
  yarn add sip-connector
47
+
48
+ # pnpm
49
+ pnpm add sip-connector
20
50
  ```
21
51
 
22
- Минимально требуется передать `JsSIP` из `@krivega/jssip` при создании `SipConnector`.
52
+ ### 📋 Системные требования
53
+
54
+ #### Обязательные зависимости
55
+
56
+ | Компонент | Требование | Описание |
57
+ | ------------------ | -------------------- | ------------------------------ |
58
+ | `@krivega/jssip` | peer dependency | Для SIP-функциональности |
59
+ | WebRTC API | Поддержка в браузере | Стандартные WebRTC возможности |
60
+ | JavaScript runtime | ES2017+ | Современный синтаксис |
61
+
62
+ #### Рекомендуемые зависимости
63
+
64
+ | Компонент | Версия | Назначение |
65
+ | ---------- | ------ | ------------------- |
66
+ | TypeScript | 4.5+ | Полная типизация |
67
+ | Node.js | 16+ | Сборка и разработка |
23
68
 
24
- ## Быстрый старт
69
+ ---
25
70
 
26
- ```ts
71
+ ## 🎯 Быстрый старт
72
+
73
+ ### Шаг 1: Инициализация
74
+
75
+ ```typescript
27
76
  import { UA, WebSocketInterface } from '@krivega/jssip';
28
77
  import { SipConnector, SipConnectorFacade, tools } from 'sip-connector';
29
78
 
30
- // 1) Инициализация низкоуровневого коннектора
31
- const sipConnector = new SipConnector({ JsSIP: { UA, WebSocketInterface } });
79
+ // Создание низкоуровневого коннектора
80
+ const sipConnector = new SipConnector({
81
+ JsSIP: { UA, WebSocketInterface },
82
+ });
32
83
 
33
- // 2) Фасад с готовыми сценариями и проксированием событий/методов
84
+ // Создание фасада с настройками кодеков
34
85
  const facade = new SipConnectorFacade(sipConnector, {
35
- // опционально: приоритезировать/исключить кодеки видео
86
+ // Приоритизация современных кодеков
36
87
  preferredMimeTypesVideoCodecs: ['video/AV1', 'video/VP9'],
37
88
  excludeMimeTypesVideoCodecs: ['video/H264'],
38
89
  });
90
+ ```
91
+
92
+ ### Шаг 2: Подключение к серверу
39
93
 
40
- // 3) Подключение к серверу
94
+ ```typescript
41
95
  await facade.connectToServer({
42
96
  userAgent: tools.getUserAgent({ appName: 'MyApp' }),
43
97
  sipWebSocketServerURL: 'wss://sip.example.com/ws',
44
98
  sipServerUrl: 'sip:example.com',
45
- name: '1001', // пользователь (SIP URI user)
99
+ name: '1001', // SIP URI user part
46
100
  password: 'secret',
47
- isRegisteredUser: true, // включить SIP REGISTER
101
+ isRegisteredUser: true, // Включить SIP REGISTER
48
102
  });
103
+ ```
104
+
105
+ ### Шаг 3: Исходящий звонок
49
106
 
50
- // 4) Исходящий звонок
51
- const localStream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
107
+ ```typescript
108
+ // Получение локального медиа-потока
109
+ const localStream = await navigator.mediaDevices.getUserMedia({
110
+ audio: true,
111
+ video: true,
112
+ });
113
+
114
+ // Инициация звонка
52
115
  const pc = await facade.callToServer({
53
116
  conference: '12345',
54
117
  mediaStream: localStream,
55
118
  setRemoteStreams: (streams) => {
56
- // отобразите удалённые потоки в плеере
57
- console.log('remote streams', streams);
119
+ // Обработка удаленных потоков
120
+ console.log('Получены удаленные потоки:', streams);
58
121
  },
59
122
  });
60
123
 
61
- // 5) Завершение
124
+ // Подписка на WebRTC-статистику
125
+ const unsubscribeStats = facade.onStats(({ outbound, inbound }) => {
126
+ console.log('Исходящая статистика:', outbound);
127
+ console.log('Входящая статистика:', inbound);
128
+ });
129
+ ```
130
+
131
+ ### Шаг 4: Завершение работы
132
+
133
+ ```typescript
62
134
  await facade.disconnectFromServer();
135
+ unsubscribeStats();
63
136
  ```
64
137
 
65
- ## Входящий звонок (пример)
138
+ ---
139
+
140
+ ## 📞 Входящие звонки
141
+
142
+ ### Обработка входящих вызовов
66
143
 
67
- ```ts
144
+ ```typescript
68
145
  // Подписка на входящие события
69
146
  sipConnector.on('incoming-call:incoming', () => {
70
- // ответить с локальным стримом
147
+ // Автоматический ответ с локальным потоком
71
148
  facade.answerToIncomingCall({
72
149
  mediaStream: localStream,
73
150
  setRemoteStreams: (streams) => {
74
- /* ... */
151
+ // Отображение удаленных потоков
152
+ displayRemoteStreams(streams);
75
153
  },
76
154
  });
77
155
  });
78
156
  ```
79
157
 
80
- ## Управление презентацией
158
+ ### Управление состоянием звонка
159
+
160
+ ```typescript
161
+ // Отслеживание жизненного цикла звонка
162
+ sipConnector.on('call:accepted', () => {
163
+ console.log('Звонок принят');
164
+ });
165
+
166
+ sipConnector.on('call:ended', () => {
167
+ console.log('Звонок завершен');
168
+ });
169
+
170
+ sipConnector.on('call:failed', (error) => {
171
+ console.error('Ошибка звонка:', error);
172
+ });
173
+ ```
174
+
175
+ ---
176
+
177
+ ## 🖥️ Управление презентациями
81
178
 
82
- ```ts
83
- // старт
84
- const displayStream = await navigator.mediaDevices.getDisplayMedia({ video: true, audio: true });
179
+ ### Запуск презентации
180
+
181
+ ```typescript
182
+ // Получение потока экрана
183
+ const displayStream = await navigator.mediaDevices.getDisplayMedia({
184
+ video: true,
185
+ audio: true,
186
+ });
187
+
188
+ // Запуск презентации с настройками качества
85
189
  await facade.startPresentation({
86
190
  mediaStream: displayStream,
87
- isP2P: false,
88
- contentHint: 'detail',
191
+ isP2P: false, // MCU режим
192
+ contentHint: 'detail', // Оптимизация для детального контента
89
193
  simulcastEncodings: [
90
194
  { width: 1920, height: 1080, scalabilityMode: 'L3T3_KEY' },
91
195
  { width: 1280, height: 720 },
92
196
  ],
93
197
  });
198
+ ```
94
199
 
95
- // обновление (например, смена потока)
96
- await facade.updatePresentation({ mediaStream: displayStream, isP2P: false });
200
+ ### Обновление и остановка
97
201
 
98
- // стоп
202
+ ```typescript
203
+ // Обновление потока презентации
204
+ await facade.updatePresentation({
205
+ mediaStream: newDisplayStream,
206
+ isP2P: false,
207
+ });
208
+
209
+ // Остановка презентации
99
210
  await facade.stopShareSipConnector();
100
211
  ```
101
212
 
102
- ## События
213
+ ---
214
+
215
+ ## 👥 Управление участниками конференции
216
+
217
+ ### Отслеживание перемещений
103
218
 
104
- События агрегируются и отдаются с префиксами менеджеров. Полный перечень смотрите в:
219
+ ```typescript
220
+ // Подписка на перемещение в зрители
221
+ const unsubscribeMoveToSpectators = facade.onMoveToSpectators(() => {
222
+ console.log('Участник перемещен в зрители');
223
+ updateParticipantRole('spectator');
224
+ });
105
225
 
106
- - `src/SipConnector/eventNames.ts`
107
- - `src/ApiManager/eventNames.ts`
226
+ // Подписка на перемещение в участники
227
+ const unsubscribeMoveToParticipants = facade.onMoveToParticipants(() => {
228
+ console.log('Участник перемещен в участники');
229
+ updateParticipantRole('participant');
230
+ });
108
231
 
109
- Примеры часто используемых событий:
232
+ // Отписка при необходимости
233
+ unsubscribeMoveToSpectators();
234
+ unsubscribeMoveToParticipants();
235
+ ```
110
236
 
111
- - `connection:connected`, `connection:disconnected` — состояние подключения;
112
- - `call:accepted`, `call:ended`, `call:failed` — жизненный цикл звонка;
113
- - `api:enterRoom`, `api:useLicense`, `api:mustStopPresentation`, `api:newDTMF` — события от сервера;
114
- - `incoming-call:incoming`, `incoming-call:failed` — входящие вызовы;
115
- - `presentation:started`, `presentation:stopped` — презентация.
237
+ ### Административные функции
116
238
 
117
- Подписка:
239
+ ```typescript
240
+ // Принудительная остановка презентации
241
+ facade.onMustStopPresentation(() => {
242
+ console.log('Администратор требует остановить презентацию');
243
+ facade.stopShareSipConnector();
244
+ });
118
245
 
119
- ```ts
120
- const unsubscribe = sipConnector.on('api:enterRoom', ({ room }) => {
121
- console.log('entered room', room);
246
+ // Мониторинг лицензий
247
+ facade.onUseLicense((license) => {
248
+ console.log('Используется лицензия:', license);
249
+ updateLicenseStatus(license);
122
250
  });
251
+ ```
123
252
 
124
- // разовая подписка на несколько событий
253
+ ---
254
+
255
+ ## 📊 Управление медиа-потоками
256
+
257
+ ### Работа с удаленными потоками
258
+
259
+ ```typescript
260
+ // Получение текущих удаленных потоков
261
+ const remoteStreams = facade.getRemoteStreams();
262
+ if (remoteStreams) {
263
+ console.log('Активные удаленные потоки:', remoteStreams.length);
264
+ remoteStreams.forEach((stream) => {
265
+ displayStream(stream);
266
+ });
267
+ }
268
+ ```
269
+
270
+ ### Обработка готовых потоков
271
+
272
+ ```typescript
273
+ // Обработка с debounce (рекомендуется для UI)
274
+ const handleReadyRemoteStreamsDebounced = facade.resolveHandleReadyRemoteStreamsDebounced({
275
+ onReadyRemoteStreams: (streams) => {
276
+ console.log('Готовые удаленные потоки:', streams);
277
+ updateStreamsDisplay(streams);
278
+ },
279
+ });
280
+
281
+ // Обработка без debounce (для критичных операций)
282
+ const handleReadyRemoteStreams = facade.resolveHandleReadyRemoteStreams({
283
+ onReadyRemoteStreams: () => {
284
+ console.log('Новый поток готов');
285
+ handleNewStream();
286
+ },
287
+ });
288
+ ```
289
+
290
+ ### Управление разрешениями
291
+
292
+ ```typescript
293
+ // Запрос разрешения на камеру
294
+ try {
295
+ await facade.askPermissionToEnableCam();
296
+ console.log('Разрешение на камеру получено');
297
+ } catch (error) {
298
+ console.error('Ошибка получения разрешения:', error);
299
+ }
300
+ ```
301
+
302
+ ---
303
+
304
+ ## 📡 События и их обработка
305
+
306
+ ### Архитектура событий
307
+
308
+ SDK использует **событийно-ориентированную архитектуру** с префиксами для группировки:
309
+
310
+ | Префикс | Описание | Примеры событий |
311
+ | ---------------- | ------------------- | ----------------------------- |
312
+ | `connection:*` | События подключения | `connected`, `disconnected` |
313
+ | `call:*` | События звонков | `accepted`, `ended`, `failed` |
314
+ | `api:*` | События от сервера | `enterRoom`, `useLicense` |
315
+ | `presentation:*` | События презентаций | `started`, `stopped` |
316
+ | `stats:*` | События статистики | `collected` |
317
+
318
+ ### Основные события
319
+
320
+ ```typescript
321
+ // Подключение
322
+ sipConnector.on('connection:connected', () => {
323
+ console.log('Подключение установлено');
324
+ });
325
+
326
+ sipConnector.on('connection:disconnected', () => {
327
+ console.log('Подключение разорвано');
328
+ });
329
+
330
+ // Звонки
331
+ sipConnector.on('call:accepted', () => {
332
+ console.log('Звонок принят');
333
+ });
334
+
335
+ sipConnector.on('call:ended', () => {
336
+ console.log('Звонок завершен');
337
+ });
338
+
339
+ // API события
340
+ sipConnector.on('api:enterRoom', ({ room }) => {
341
+ console.log('Вход в комнату:', room);
342
+ });
343
+
344
+ sipConnector.on('api:useLicense', (license) => {
345
+ console.log('Лицензия:', license);
346
+ });
347
+ ```
348
+
349
+ ### Продвинутые паттерны
350
+
351
+ ```typescript
352
+ // Ожидание одного из нескольких событий
125
353
  sipConnector.onceRace(['call:ended', 'call:failed'], (_payload, eventName) => {
126
- console.log('call finished by', eventName);
354
+ console.log('Звонок завершен событием:', eventName);
355
+ cleanupCall();
127
356
  });
357
+
358
+ // Ожидание конкретного события
359
+ const roomData = await sipConnector.wait('api:enterRoom');
360
+ console.log('Данные комнаты:', roomData);
128
361
  ```
129
362
 
130
- ## Экспорты
363
+ ---
364
+
365
+ ## 📈 WebRTC Статистика
366
+
367
+ ### Обзор возможностей
368
+
369
+ SDK предоставляет детальную WebRTC-статистику, основанную на [W3C WebRTC Statistics API](https://www.w3.org/TR/webrtc-stats/), включающую:
370
+
371
+ | Тип статистики | Описание | Метрики |
372
+ | ------------------ | --------------------- | ----------------------------- |
373
+ | **RTP статистика** | Потоковые данные | Пакеты, байты, jitter, loss |
374
+ | **Кодеки** | Параметры кодирования | Параметры, реализация |
375
+ | **ICE кандидаты** | Сетевые соединения | Типы, приоритеты, состояния |
376
+ | **Транспорт** | Защищенные соединения | DTLS, соединения, сертификаты |
377
+
378
+ ### Использование статистики
379
+
380
+ ```typescript
381
+ import { StatsPeerConnection, EStatsTypes, hasAvailableStats } from 'sip-connector';
131
382
 
132
- ```ts
383
+ // Проверка доступности
384
+ if (hasAvailableStats()) {
385
+ const statsCollector = new StatsPeerConnection();
386
+
387
+ // Подписка на события статистики
388
+ statsCollector.on('collected', ({ outbound, inbound }) => {
389
+ console.log('Исходящая статистика:', outbound);
390
+ console.log('Входящая статистика:', inbound);
391
+
392
+ // Анализ качества соединения
393
+ analyzeConnectionQuality(outbound, inbound);
394
+ });
395
+ }
396
+ ```
397
+
398
+ ### Типы статистики
399
+
400
+ | Категория | Типы | Описание |
401
+ | ---------------------- | --------------------------------- | ------------------------------------------ |
402
+ | **Аудио потоки** | `TInboundAudio`, `TOutboundAudio` | RTP, кодек, jitter buffer, audio level |
403
+ | **Видео потоки** | `TInboundVideo`, `TOutboundVideo` | RTP, кодек, frames, bitrate, resolution |
404
+ | **Сетевая информация** | `TAdditional` | ICE кандидаты, DTLS транспорт, сертификаты |
405
+
406
+ ---
407
+
408
+ ## 🔧 API и экспорты
409
+
410
+ ### Основные классы
411
+
412
+ ```typescript
133
413
  import {
134
- SipConnector,
135
- SipConnectorFacade,
136
- debug,
137
- enableDebug,
138
- disableDebug,
139
- ECallCause,
140
- hasCanceledCallError,
141
- EUseLicense,
142
- EMimeTypesVideoCodecs,
143
- type TContentHint,
144
- type TCustomError,
145
- type TJsSIP,
146
- tools, // { getUserAgent, getExtraHeaders, hasPurgatory, ... }
414
+ SipConnector, // Низкоуровневый API
415
+ SipConnectorFacade, // Высокоуровневый фасад
416
+ StatsPeerConnection, // Сбор статистики
417
+ // ... другие экспорты
147
418
  } from 'sip-connector';
148
419
  ```
149
420
 
150
- ## Заметки по API
421
+ ### Утилиты и типы
151
422
 
152
- - `SipConnector` — низкоуровневый класс, инкапсулирующий менеджеры подключения/звонков/презентаций. Требует `JsSIP` при создании.
153
- - `SipConnectorFacade` — удобный фасад с готовыми сценариями: `connectToServer`, `callToServer`, `answerToIncomingCall`, `disconnectFromServer`, `replaceMediaStream`, `sendMediaState`, `sendRefusalToTurnOnMic/Cam`, `onUseLicense`, `onMustStopPresentation`, `onMoveToSpectators/Participants` и др. Также проксирует методы `on/once/onceRace/wait/off`, `ping`, `hangUp`, `sendDTMF`, `checkTelephony`, `connection`, `isConfigured`, `isRegistered`.
154
- - Поддерживаются настройки качества: `contentHint`, `degradationPreference`, `simulcastEncodings`, `sendEncodings`, фильтрация кодеков видео через `preferredMimeTypesVideoCodecs`/`excludeMimeTypesVideoCodecs`.
423
+ ```typescript
424
+ import {
425
+ // Утилиты
426
+ tools, // getUserAgent, getExtraHeaders, hasPurgatory
427
+ hasAvailableStats, // Проверка доступности статистики
428
+
429
+ // Константы
430
+ EStatsTypes, // Типы статистики
431
+ EMimeTypesVideoCodecs, // MIME-типы кодеков
432
+ EUseLicense, // Типы лицензий
433
+
434
+ // Типы
435
+ type TContentHint, // Подсказки для кодирования
436
+ type TInboundStats, // Входящая статистика
437
+ type TOutboundStats, // Исходящая статистика
438
+ } from 'sip-connector';
439
+ ```
440
+
441
+ ---
442
+
443
+ ## 🏗️ Архитектура и паттерны
155
444
 
156
- ## Отладка
445
+ ### Слоистая архитектура
446
+
447
+ ```shell
448
+ ┌─────────────────────────────────────┐
449
+ │ SipConnectorFacade │ ← Высокоуровневый API
450
+ ├─────────────────────────────────────┤
451
+ │ SipConnector │ ← Координация менеджеров
452
+ ├─────────────────────────────────────┤
453
+ │ Connection │ Call │ API │ ← Специализированные менеджеры
454
+ │ Manager │ Manager │ Manager │
455
+ ├─────────────────────────────────────┤
456
+ │ @krivega/jssip │ ← SIP-функциональность
457
+ └─────────────────────────────────────┘
458
+ ```
459
+
460
+ ### Паттерны проектирования
461
+
462
+ | Паттерн | Описание | Применение |
463
+ | --------------- | --------------------------------- | ------------------------ |
464
+ | **Фасад** | Упрощение сложных операций | `SipConnectorFacade` |
465
+ | **Стратегия** | Различные стратегии для звонков | MCU, P2P режимы |
466
+ | **Наблюдатель** | Событийная модель для уведомлений | Event-driven архитектура |
467
+ | **Фабрика** | Создание UA и сессий | `UAFactory` |
468
+
469
+ ---
470
+
471
+ ## 📚 Лучшие практики
472
+
473
+ ### Обработка ошибок
474
+
475
+ ```typescript
476
+ try {
477
+ await facade.connectToServer(config);
478
+ } catch (error) {
479
+ if (error.code === 'CONNECTION_FAILED') {
480
+ // Повторная попытка подключения
481
+ await retryConnection();
482
+ } else {
483
+ // Логирование и уведомление пользователя
484
+ logError(error);
485
+ notifyUser('Ошибка подключения');
486
+ }
487
+ }
488
+ ```
157
489
 
158
- ```ts
490
+ ### Управление ресурсами
491
+
492
+ ```typescript
493
+ // Всегда отписывайтесь от событий
494
+ const unsubscribe = facade.onStats(handleStats);
495
+
496
+ // Очистка при размонтировании
497
+ useEffect(() => {
498
+ return () => {
499
+ unsubscribe();
500
+ facade.disconnectFromServer();
501
+ };
502
+ }, []);
503
+ ```
504
+
505
+ ### Оптимизация производительности
506
+
507
+ ```typescript
508
+ // Используйте debounce для частых событий
509
+ const debouncedStatsHandler = debounce(handleStats, 1000);
510
+ facade.onStats(debouncedStatsHandler);
511
+
512
+ // Приоритизируйте современные кодеки
513
+ const facade = new SipConnectorFacade(sipConnector, {
514
+ preferredMimeTypesVideoCodecs: ['video/AV1', 'video/VP9'],
515
+ });
516
+ ```
517
+
518
+ ---
519
+
520
+ ## 🐛 Отладка и диагностика
521
+
522
+ ### Включение отладочного режима
523
+
524
+ ```typescript
159
525
  import { enableDebug, disableDebug } from 'sip-connector';
160
526
 
527
+ // Включение детального логирования
161
528
  enableDebug();
162
- // ...
529
+
530
+ // Отключение для продакшена
163
531
  disableDebug();
164
532
  ```
165
533
 
166
- ## Тесты
534
+ ### Мониторинг состояния
535
+
536
+ ```typescript
537
+ // Проверка состояния подключения
538
+ console.log('Подключен:', facade.connection.isConnected());
539
+ console.log('Зарегистрирован:', facade.isRegistered());
540
+
541
+ // Проверка конфигурации
542
+ console.log('Настроен:', facade.isConfigured());
543
+ ```
544
+
545
+ ---
167
546
 
168
- ```sh
547
+ ## 🧪 Тестирование
548
+
549
+ ### Запуск тестов
550
+
551
+ ```bash
552
+ # Все тесты
169
553
  npm test
554
+
555
+ # Тесты с покрытием
556
+ npm run test:coverage
557
+
558
+ # Тесты в watch режиме
559
+ npm run test:watch
170
560
  ```
171
561
 
172
- ## Поддержка браузеров
562
+ ### Тестовые фикстуры
563
+
564
+ SDK включает готовые моки для тестирования:
173
565
 
174
- SDK использует стандартные WebRTC API. Для максимально старых браузеров проверьте поддержку необходимых возможностей (кодеки, Unified Plan, `getDisplayMedia`).
566
+ | Мок | Назначение | Описание |
567
+ | ----------------------- | -------------------- | -------------------------- |
568
+ | `RTCPeerConnectionMock` | WebRTC API | Имитация WebRTC соединений |
569
+ | `UA.mock.ts` | SIP-функциональность | Имитация SIP User Agent |
570
+ | `BaseSession.mock.ts` | Сессии | Имитация SIP сессий |
175
571
 
176
- ## Maintainer
572
+ ---
177
573
 
178
- Krivega Dmitriy
574
+ ## 🌐 Совместимость браузеров
179
575
 
180
- - Website: [krivega.com](https://krivega.com)
181
- - Github: [@Krivega](https://github.com/Krivega)
576
+ ### WebRTC поддержка
182
577
 
183
- ## Contributing
578
+ SDK использует стандартные WebRTC API и совместим с:
579
+
580
+ | Браузер | Версия | Уровень поддержки | Особенности |
581
+ | ----------- | ------ | ----------------- | ------------------------------ |
582
+ | **Chrome** | 67+ | Полная поддержка | Все возможности WebRTC |
583
+ | **Firefox** | 60+ | Полная поддержка | Все возможности WebRTC |
584
+ | **Safari** | 11+ | Базовая поддержка | Ограниченная поддержка кодеков |
585
+ | **Edge** | 79+ | Полная поддержка | Chromium-based |
586
+
587
+ ### Проверка возможностей
588
+
589
+ ```typescript
590
+ // Проверка поддержки WebRTC
591
+ if (!navigator.mediaDevices?.getUserMedia) {
592
+ throw new Error('WebRTC не поддерживается');
593
+ }
594
+
595
+ // Проверка поддержки презентаций
596
+ if (!navigator.mediaDevices?.getDisplayMedia) {
597
+ console.warn('Screen sharing не поддерживается');
598
+ }
599
+ ```
184
600
 
185
- Contributions, issues and feature requests are welcome!
186
- Feel free to check [issues page](https://github.com/Krivega/sip-connector/issues). You can also take a look at the [contributing guide](https://github.com/Krivega/sip-connector/blob/master/CONTRIBUTING.md).
601
+ ---
187
602
 
188
- ## 📝 License
603
+ ## 🤝 Поддержка и сообщество
604
+
605
+ ### Документация
606
+
607
+ - **API Reference**: Полное описание всех методов и типов
608
+ - **Примеры**: Готовые сценарии использования
609
+ - **Архитектура**: Детальное описание внутренней структуры
610
+
611
+ ### Сообщество
612
+
613
+ - **Issues**: [GitHub Issues](https://github.com/Krivega/sip-connector/issues)
614
+ - **Discussions**: Обсуждения и вопросы
615
+ - **Contributing**: Руководство по участию в разработке
616
+
617
+ ## 👨‍💻 Автор
618
+
619
+ **Krivega Dmitriy**
620
+
621
+ - 🌐 Website: [krivega.com](https://krivega.com)
622
+ - 📱 Github: [@Krivega](https://github.com/Krivega)
623
+ - 📧 Email: <mr.krivega@gmail.com>
624
+
625
+ ## 📄 Лицензия
189
626
 
190
627
  Copyright © 2021‑2025 [Krivega Dmitriy](https://github.com/Krivega).
191
- This project is [MIT](https://github.com/Krivega/sip-connector/blob/master/LICENSE) licensed.
628
+
629
+ This project is licensed under the [MIT License](https://github.com/Krivega/sip-connector/blob/master/LICENSE) - see the LICENSE file for details.