@observertc/observer-js 0.42.9 → 1.0.0-5f150eb.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 (303) hide show
  1. package/.prettierrc +6 -6
  2. package/README.md +493 -63
  3. package/lib/ObservedCall.d.ts +48 -43
  4. package/lib/ObservedCall.d.ts.map +1 -1
  5. package/lib/ObservedCall.js +164 -107
  6. package/lib/ObservedCallEventMonitor.d.ts +107 -0
  7. package/lib/ObservedCallEventMonitor.d.ts.map +1 -0
  8. package/lib/ObservedCallEventMonitor.js +321 -0
  9. package/lib/ObservedCallSummary.d.ts +18 -0
  10. package/lib/ObservedCallSummary.d.ts.map +1 -0
  11. package/lib/ObservedCertificate.d.ts +19 -0
  12. package/lib/ObservedCertificate.d.ts.map +1 -0
  13. package/lib/ObservedCertificate.js +38 -0
  14. package/lib/ObservedClient.d.ts +78 -145
  15. package/lib/ObservedClient.d.ts.map +1 -1
  16. package/lib/ObservedClient.js +661 -746
  17. package/lib/ObservedClientEventMonitor.d.ts +91 -0
  18. package/lib/ObservedClientEventMonitor.d.ts.map +1 -0
  19. package/lib/ObservedClientEventMonitor.js +254 -0
  20. package/lib/ObservedClientSummary.d.ts +23 -0
  21. package/lib/ObservedClientSummary.d.ts.map +1 -0
  22. package/lib/ObservedClientSummary.js +2 -0
  23. package/lib/ObservedCodec.d.ts +22 -0
  24. package/lib/ObservedCodec.d.ts.map +1 -0
  25. package/lib/ObservedCodec.js +45 -0
  26. package/lib/ObservedDataChannel.d.ts +25 -69
  27. package/lib/ObservedDataChannel.d.ts.map +1 -1
  28. package/lib/ObservedDataChannel.js +69 -109
  29. package/lib/ObservedIceCandidate.d.ts +29 -0
  30. package/lib/ObservedIceCandidate.d.ts.map +1 -0
  31. package/lib/ObservedIceCandidate.js +59 -0
  32. package/lib/ObservedIceCandidatePair.d.ts +45 -0
  33. package/lib/ObservedIceCandidatePair.d.ts.map +1 -0
  34. package/lib/ObservedIceCandidatePair.js +127 -0
  35. package/lib/ObservedIceTransport.d.ts +36 -0
  36. package/lib/ObservedIceTransport.d.ts.map +1 -0
  37. package/lib/ObservedIceTransport.js +93 -0
  38. package/lib/ObservedInboundRtp.d.ts +92 -0
  39. package/lib/ObservedInboundRtp.d.ts.map +1 -0
  40. package/lib/ObservedInboundRtp.js +193 -0
  41. package/lib/ObservedInboundTrack.d.ts +34 -0
  42. package/lib/ObservedInboundTrack.d.ts.map +1 -0
  43. package/lib/ObservedInboundTrack.js +92 -0
  44. package/lib/ObservedMediaPlayout.d.ts +22 -0
  45. package/lib/ObservedMediaPlayout.d.ts.map +1 -0
  46. package/lib/ObservedMediaPlayout.js +42 -0
  47. package/lib/ObservedMediaSource.d.ts +28 -0
  48. package/lib/ObservedMediaSource.d.ts.map +1 -0
  49. package/lib/ObservedMediaSource.js +55 -0
  50. package/lib/ObservedOutboundRtp.d.ts +62 -0
  51. package/lib/ObservedOutboundRtp.d.ts.map +1 -0
  52. package/lib/ObservedOutboundRtp.js +144 -0
  53. package/lib/ObservedOutboundTrack.d.ts +34 -0
  54. package/lib/ObservedOutboundTrack.d.ts.map +1 -0
  55. package/lib/ObservedOutboundTrack.js +65 -0
  56. package/lib/ObservedPeerConnection.d.ts +154 -80
  57. package/lib/ObservedPeerConnection.d.ts.map +1 -1
  58. package/lib/ObservedPeerConnection.js +724 -357
  59. package/lib/ObservedPeerConnectionTransport.d.ts +17 -0
  60. package/lib/ObservedPeerConnectionTransport.d.ts.map +1 -0
  61. package/lib/ObservedPeerConnectionTransport.js +34 -0
  62. package/lib/ObservedRemoteInboundRtp.d.ts +30 -0
  63. package/lib/ObservedRemoteInboundRtp.d.ts.map +1 -0
  64. package/lib/ObservedRemoteInboundRtp.js +60 -0
  65. package/lib/ObservedRemoteOutboundRtp.d.ts +30 -0
  66. package/lib/ObservedRemoteOutboundRtp.d.ts.map +1 -0
  67. package/lib/ObservedRemoteOutboundRtp.js +60 -0
  68. package/lib/ObservedTURN.d.ts +31 -0
  69. package/lib/ObservedTURN.d.ts.map +1 -0
  70. package/lib/ObservedTURN.js +58 -0
  71. package/lib/ObservedTurnServer.d.ts +25 -0
  72. package/lib/ObservedTurnServer.d.ts.map +1 -0
  73. package/lib/ObservedTurnServer.js +59 -0
  74. package/lib/Observer.d.ts +46 -54
  75. package/lib/Observer.d.ts.map +1 -1
  76. package/lib/Observer.js +131 -226
  77. package/lib/ObserverEventMonitor.d.ts +141 -0
  78. package/lib/ObserverEventMonitor.d.ts.map +1 -0
  79. package/lib/ObserverEventMonitor.js +440 -0
  80. package/lib/ObserverSummary.d.ts +13 -0
  81. package/lib/ObserverSummary.d.ts.map +1 -0
  82. package/lib/ObserverSummary.js +2 -0
  83. package/lib/Reports.d.ts +85 -0
  84. package/lib/Reports.d.ts.map +1 -0
  85. package/lib/Reports.js +2 -0
  86. package/lib/common/Middleware.d.ts +10 -1
  87. package/lib/common/Middleware.d.ts.map +1 -1
  88. package/lib/common/Middleware.js +55 -36
  89. package/lib/common/logger.d.ts +8 -4
  90. package/lib/common/logger.d.ts.map +1 -1
  91. package/lib/common/logger.js +44 -68
  92. package/lib/common/types.d.ts +0 -21
  93. package/lib/common/types.d.ts.map +1 -1
  94. package/lib/common/types.js +1 -0
  95. package/lib/common/utils.d.ts +3 -1
  96. package/lib/common/utils.d.ts.map +1 -1
  97. package/lib/common/utils.js +23 -3
  98. package/lib/detectors/Detector.d.ts +5 -0
  99. package/lib/detectors/Detector.d.ts.map +1 -0
  100. package/lib/detectors/Detector.js +3 -0
  101. package/lib/detectors/Detectors.d.ts +11 -0
  102. package/lib/detectors/Detectors.d.ts.map +1 -0
  103. package/lib/detectors/Detectors.js +34 -0
  104. package/lib/index.d.ts +27 -25
  105. package/lib/index.d.ts.map +1 -1
  106. package/lib/index.js +45 -41
  107. package/lib/mediasoup/ObservedMediaRouter.d.ts +10 -0
  108. package/lib/mediasoup/ObservedMediaRouter.d.ts.map +1 -0
  109. package/lib/mediasoup/ObservedMediaRouter.js +6 -0
  110. package/lib/monitors/TurnUsageMonitor.d.ts +0 -52
  111. package/lib/monitors/TurnUsageMonitor.d.ts.map +1 -1
  112. package/lib/monitors/TurnUsageMonitor.js +145 -120
  113. package/lib/schema/ClientEventTypes.d.ts +228 -0
  114. package/lib/schema/ClientEventTypes.d.ts.map +1 -0
  115. package/lib/schema/ClientEventTypes.js +41 -0
  116. package/lib/schema/ClientMetaTypes.d.ts +34 -0
  117. package/lib/schema/ClientMetaTypes.d.ts.map +1 -0
  118. package/lib/schema/ClientMetaTypes.js +16 -0
  119. package/lib/schema/ClientSample.d.ts +1333 -0
  120. package/lib/schema/ClientSample.d.ts.map +1 -0
  121. package/lib/schema/ClientSample.js +4 -0
  122. package/lib/scores/CalculatedScore.d.ts +6 -0
  123. package/lib/scores/CalculatedScore.d.ts.map +1 -0
  124. package/lib/scores/CalculatedScore.js +2 -0
  125. package/lib/scores/DefaultCallScoreCalculator.d.ts +7 -0
  126. package/lib/scores/DefaultCallScoreCalculator.d.ts.map +1 -0
  127. package/lib/scores/DefaultCallScoreCalculator.js +21 -0
  128. package/lib/scores/ScoreCalculator.d.ts +4 -0
  129. package/lib/scores/ScoreCalculator.d.ts.map +1 -0
  130. package/lib/scores/ScoreCalculator.js +2 -0
  131. package/lib/updaters/CallUpdater.d.ts +5 -0
  132. package/lib/updaters/CallUpdater.d.ts.map +1 -0
  133. package/lib/updaters/CallUpdater.js +2 -0
  134. package/lib/updaters/ObserverUpdater.d.ts +5 -0
  135. package/lib/updaters/ObserverUpdater.d.ts.map +1 -0
  136. package/lib/updaters/ObserverUpdater.js +2 -0
  137. package/lib/updaters/OnAllCallObserverUpdater.d.ts +15 -0
  138. package/lib/updaters/OnAllCallObserverUpdater.d.ts.map +1 -0
  139. package/lib/updaters/OnAllCallObserverUpdater.js +50 -0
  140. package/lib/updaters/OnAllClientCallUpdater.d.ts +15 -0
  141. package/lib/updaters/OnAllClientCallUpdater.d.ts.map +1 -0
  142. package/lib/updaters/OnAllClientCallUpdater.js +53 -0
  143. package/lib/updaters/OnAnyCallObserverUpdater.d.ts +12 -0
  144. package/lib/updaters/OnAnyCallObserverUpdater.d.ts.map +1 -0
  145. package/lib/updaters/OnAnyCallObserverUpdater.js +37 -0
  146. package/lib/updaters/OnAnyClientCallUpdater.d.ts +12 -0
  147. package/lib/updaters/OnAnyClientCallUpdater.d.ts.map +1 -0
  148. package/lib/updaters/OnAnyClientCallUpdater.js +36 -0
  149. package/lib/updaters/OnIntervalUpdater.d.ts +10 -0
  150. package/lib/updaters/OnIntervalUpdater.d.ts.map +1 -0
  151. package/lib/updaters/OnIntervalUpdater.js +17 -0
  152. package/lib/updaters/Updater.d.ts +6 -0
  153. package/lib/updaters/Updater.d.ts.map +1 -0
  154. package/lib/updaters/Updater.js +2 -0
  155. package/lib/utils/MediasoupRemoteTrackResolver.d.ts +25 -0
  156. package/lib/utils/MediasoupRemoteTrackResolver.d.ts.map +1 -0
  157. package/lib/utils/MediasoupRemoteTrackResolver.js +110 -0
  158. package/lib/utils/RemoteTrackResolver.d.ts +7 -0
  159. package/lib/utils/RemoteTrackResolver.d.ts.map +1 -0
  160. package/lib/utils/RemoteTrackResolver.js +2 -0
  161. package/package.json +4 -4
  162. package/src/ObservedCall.ts +243 -161
  163. package/src/ObservedCallEventMonitor.ts +402 -0
  164. package/src/ObservedCallSummary.ts +22 -0
  165. package/src/ObservedCertificate.ts +43 -0
  166. package/src/ObservedClient.ts +715 -1003
  167. package/src/ObservedClientEventMonitor.ts +309 -0
  168. package/src/ObservedClientSummary.ts +24 -0
  169. package/src/ObservedCodec.ts +49 -0
  170. package/src/ObservedDataChannel.ts +71 -181
  171. package/src/ObservedIceCandidate.ts +64 -0
  172. package/src/ObservedIceCandidatePair.ts +134 -0
  173. package/src/ObservedIceTransport.ts +99 -0
  174. package/src/ObservedInboundRtp.ts +205 -0
  175. package/src/ObservedInboundTrack.ts +105 -0
  176. package/src/ObservedMediaPlayout.ts +49 -0
  177. package/src/ObservedMediaSource.ts +60 -0
  178. package/src/ObservedOutboundRtp.ts +156 -0
  179. package/src/ObservedOutboundTrack.ts +82 -0
  180. package/src/ObservedPeerConnection.ts +933 -402
  181. package/src/ObservedPeerConnectionTransport.ts +38 -0
  182. package/src/ObservedRemoteInboundRtp.ts +64 -0
  183. package/src/ObservedRemoteOutboundRtp.ts +65 -0
  184. package/src/ObservedTURN.ts +86 -0
  185. package/src/ObservedTurnServer.ts +72 -0
  186. package/src/Observer.ts +183 -298
  187. package/src/ObserverEventMonitor.ts +561 -0
  188. package/src/ObserverSummary.ts +15 -0
  189. package/src/Reports.ts +87 -0
  190. package/src/common/Middleware.ts +70 -42
  191. package/src/common/logger.ts +60 -69
  192. package/src/common/types.ts +0 -42
  193. package/src/common/utils.ts +24 -2
  194. package/src/detectors/Detector.ts +6 -0
  195. package/src/detectors/Detectors.ts +38 -0
  196. package/src/index.ts +30 -91
  197. package/src/mediasoup/ObservedMediaRouter.ts +10 -0
  198. package/src/monitors/TurnUsageMonitor.ts +164 -164
  199. package/src/schema/ClientEventTypes.ts +280 -0
  200. package/src/schema/ClientMetaTypes.ts +41 -0
  201. package/src/schema/ClientSample.ts +1682 -0
  202. package/src/scores/CalculatedScore.ts +6 -0
  203. package/src/scores/DefaultCallScoreCalculator.ts +23 -0
  204. package/src/scores/ScoreCalculator.ts +3 -0
  205. package/src/updaters/CallUpdater.ts +5 -0
  206. package/src/updaters/ObserverUpdater.ts +5 -0
  207. package/src/updaters/OnAllCallObserverUpdater.ts +59 -0
  208. package/src/updaters/OnAllClientCallUpdater.ts +61 -0
  209. package/src/updaters/OnAnyCallObserverUpdater.ts +41 -0
  210. package/src/updaters/OnAnyClientCallUpdater.ts +39 -0
  211. package/src/updaters/OnIntervalUpdater.ts +19 -0
  212. package/src/updaters/Updater.ts +5 -0
  213. package/src/utils/MediasoupRemoteTrackResolver.ts +155 -0
  214. package/src/utils/RemoteTrackResolver.ts +12 -0
  215. package/tsconfig.json +3 -3
  216. package/lib/ObservedICE.d.ts +0 -64
  217. package/lib/ObservedICE.d.ts.map +0 -1
  218. package/lib/ObservedICE.js +0 -141
  219. package/lib/ObservedInboundAudioTrack.d.ts +0 -96
  220. package/lib/ObservedInboundAudioTrack.d.ts.map +0 -1
  221. package/lib/ObservedInboundAudioTrack.js +0 -217
  222. package/lib/ObservedInboundVideoTrack.d.ts +0 -101
  223. package/lib/ObservedInboundVideoTrack.d.ts.map +0 -1
  224. package/lib/ObservedInboundVideoTrack.js +0 -232
  225. package/lib/ObservedOutboundAudioTrack.d.ts +0 -87
  226. package/lib/ObservedOutboundAudioTrack.d.ts.map +0 -1
  227. package/lib/ObservedOutboundAudioTrack.js +0 -186
  228. package/lib/ObservedOutboundVideoTrack.d.ts +0 -91
  229. package/lib/ObservedOutboundVideoTrack.d.ts.map +0 -1
  230. package/lib/ObservedOutboundVideoTrack.js +0 -193
  231. package/lib/ObservedSfu.d.ts +0 -59
  232. package/lib/ObservedSfu.d.ts.map +0 -1
  233. package/lib/ObservedSfu.js +0 -157
  234. package/lib/ObservedSfuInboundRtpPad.d.ts +0 -42
  235. package/lib/ObservedSfuInboundRtpPad.d.ts.map +0 -1
  236. package/lib/ObservedSfuInboundRtpPad.js +0 -71
  237. package/lib/ObservedSfuOutboundRtpPad.d.ts +0 -42
  238. package/lib/ObservedSfuOutboundRtpPad.d.ts.map +0 -1
  239. package/lib/ObservedSfuOutboundRtpPad.js +0 -72
  240. package/lib/ObservedSfuSctpChannel.d.ts +0 -42
  241. package/lib/ObservedSfuSctpChannel.d.ts.map +0 -1
  242. package/lib/ObservedSfuSctpChannel.js +0 -57
  243. package/lib/ObservedSfuTransport.d.ts +0 -58
  244. package/lib/ObservedSfuTransport.d.ts.map +0 -1
  245. package/lib/ObservedSfuTransport.js +0 -120
  246. package/lib/RemoteTrackAssigner.d.ts +0 -14
  247. package/lib/RemoteTrackAssigner.d.ts.map +0 -1
  248. package/lib/RemoteTrackAssigner.js +0 -52
  249. package/lib/ReportsCollector.d.ts +0 -109
  250. package/lib/ReportsCollector.d.ts.map +0 -1
  251. package/lib/ReportsCollector.js +0 -207
  252. package/lib/common/CalculatedScore.d.ts +0 -80
  253. package/lib/common/CalculatedScore.d.ts.map +0 -1
  254. package/lib/common/CalculatedScore.js +0 -162
  255. package/lib/common/CallEventType.d.ts +0 -63
  256. package/lib/common/CallEventType.d.ts.map +0 -1
  257. package/lib/common/CallEventType.js +0 -39
  258. package/lib/common/CallMetaReports.d.ts +0 -42
  259. package/lib/common/CallMetaReports.d.ts.map +0 -1
  260. package/lib/common/CallMetaReports.js +0 -36
  261. package/lib/common/QualityScoreUtils.d.ts +0 -1
  262. package/lib/common/QualityScoreUtils.d.ts.map +0 -1
  263. package/lib/common/QualityScoreUtils.js +0 -1
  264. package/lib/common/TypedEventEmitter.d.ts +0 -22
  265. package/lib/common/TypedEventEmitter.d.ts.map +0 -1
  266. package/lib/common/TypedEventEmitter.js +0 -11
  267. package/lib/common/callEventReports.d.ts +0 -10
  268. package/lib/common/callEventReports.d.ts.map +0 -1
  269. package/lib/common/callEventReports.js +0 -112
  270. package/lib/monitors/CallSummary.d.ts +0 -37
  271. package/lib/monitors/CallSummary.d.ts.map +0 -1
  272. package/lib/monitors/CallSummaryMonitor.d.ts +0 -32
  273. package/lib/monitors/CallSummaryMonitor.d.ts.map +0 -1
  274. package/lib/monitors/CallSummaryMonitor.js +0 -152
  275. package/lib/monitors/ClientIssueMonitor.d.ts +0 -32
  276. package/lib/monitors/ClientIssueMonitor.d.ts.map +0 -1
  277. package/lib/monitors/ClientIssueMonitor.js +0 -49
  278. package/lib/monitors/SfuServerMonitor.d.ts +0 -79
  279. package/lib/monitors/SfuServerMonitor.d.ts.map +0 -1
  280. package/lib/monitors/SfuServerMonitor.js +0 -198
  281. package/src/ObservedICE.ts +0 -237
  282. package/src/ObservedInboundAudioTrack.ts +0 -344
  283. package/src/ObservedInboundVideoTrack.ts +0 -361
  284. package/src/ObservedOutboundAudioTrack.ts +0 -307
  285. package/src/ObservedOutboundVideoTrack.ts +0 -319
  286. package/src/ObservedSfu.ts +0 -231
  287. package/src/ObservedSfuInboundRtpPad.ts +0 -106
  288. package/src/ObservedSfuOutboundRtpPad.ts +0 -107
  289. package/src/ObservedSfuSctpChannel.ts +0 -103
  290. package/src/ObservedSfuTransport.ts +0 -185
  291. package/src/RemoteTrackAssigner.ts +0 -68
  292. package/src/ReportsCollector.ts +0 -336
  293. package/src/common/CalculatedScore.ts +0 -188
  294. package/src/common/CallEventType.ts +0 -69
  295. package/src/common/CallMetaReports.ts +0 -82
  296. package/src/common/QualityScoreUtils.ts +0 -0
  297. package/src/common/TypedEventEmitter.ts +0 -32
  298. package/src/common/callEventReports.ts +0 -178
  299. package/src/monitors/CallSummary.ts +0 -38
  300. package/src/monitors/CallSummaryMonitor.ts +0 -192
  301. package/src/monitors/ClientIssueMonitor.ts +0 -88
  302. package/src/monitors/SfuServerMonitor.ts +0 -285
  303. /package/lib/{monitors/CallSummary.js → ObservedCallSummary.js} +0 -0
@@ -1,26 +1,31 @@
1
1
  import { EventEmitter } from 'events';
2
- import { ObservedClient, ObservedClientModel } from './ObservedClient';
2
+ import { ObservedClient, ObservedClientSettings } from './ObservedClient';
3
3
  import { Observer } from './Observer';
4
- import { createClientJoinedEventReport, createClientLeftEventReport } from './common/callEventReports';
5
- import { getMedian, PartialBy } from './common/utils';
6
- import { CallEventReport } from '@observertc/report-schemas-js';
7
- import { createProcessor } from './common/Middleware';
8
- import { ClientSample } from '@observertc/sample-schemas-js';
9
- import { ObservedOutboundAudioTrack } from './ObservedOutboundAudioTrack';
10
- import { ObservedOutboundVideoTrack } from './ObservedOutboundVideoTrack';
11
- import { CalculatedScore } from './common/CalculatedScore';
12
-
13
- export type ObservedCallModel = {
14
- serviceId: string;
15
- roomId: string;
4
+ import { ScoreCalculator } from './scores/ScoreCalculator';
5
+ import { CalculatedScore } from './scores/CalculatedScore';
6
+ import { DefaultCallScoreCalculator } from './scores/DefaultCallScoreCalculator';
7
+ import { Detectors } from './detectors/Detectors';
8
+ import { RemoteTrackResolver } from './utils/RemoteTrackResolver';
9
+ import { OnAllClientCallUpdater } from './updaters/OnAllClientCallUpdater';
10
+ import { Updater } from './updaters/Updater';
11
+ import { OnIntervalUpdater } from './updaters/OnIntervalUpdater';
12
+ import { OnAnyClientCallUpdater } from './updaters/OnAnyClientCallUpdater';
13
+ import { ObservedCallEventMonitor } from './ObservedCallEventMonitor';
14
+
15
+ export type ObservedCallSettings<AppData extends Record<string, unknown> = Record<string, unknown>> = {
16
16
  callId: string;
17
+ appData?: AppData;
18
+ remoteTrackResolvePolicy?: 'p2p' | 'mediasoup-sfu' | 'none',
19
+ updatePolicy?: 'update-on-any-client-updated' | 'update-when-all-client-updated' | 'update-on-interval',
20
+ updateIntervalInMs?: number,
21
+ closeCallIfEmptyForMs?: number,
17
22
  };
18
23
 
19
24
  export type ObservedCallEvents = {
20
25
  update: [],
21
26
  newclient: [ObservedClient],
22
- callevent: [Omit<CallEventReport, 'callId' | 'serviceId' | 'roomId'>],
23
27
  empty: [],
28
+ 'not-empty': [],
24
29
  close: [],
25
30
  }
26
31
 
@@ -32,195 +37,272 @@ export declare interface ObservedCall {
32
37
  }
33
38
 
34
39
  export class ObservedCall<AppData extends Record<string, unknown> = Record<string, unknown>> extends EventEmitter {
35
- public readonly created = Date.now();
40
+ public readonly detectors: Detectors;
41
+ public updater?: Updater;
42
+ public scoreCalculator: ScoreCalculator;
43
+ public readonly callId: string;
44
+ public readonly observedClients = new Map<string, ObservedClient>();
45
+ public readonly clientsUsedTurn = new Set<string>();
46
+ public readonly calculatedScore: CalculatedScore = {
47
+ weight: 1,
48
+ value: undefined,
49
+ };
50
+ public remoteTrackResolver?: RemoteTrackResolver;
51
+
52
+ public totalAddedClients = 0;
53
+ public totalRemovedClients = 0;
36
54
 
37
- public readonly processor = createProcessor<ClientSample>();
55
+ public numberOfIssues = 0;
56
+ public numberOfPeerConnections = 0;
57
+ public numberOfInboundRtpStreams = 0;
58
+ public numberOfOutboundRtpStreams = 0;
59
+ public numberOfDataChannels = 0;
38
60
 
39
- private readonly _clients = new Map<string, ObservedClient>();
40
-
41
- public _scoreData?: {
42
- score: CalculatedScore,
43
- calculated: number,
44
- };
61
+ public maxNumberOfClients = 0;
62
+ public deltaNumberOfIssues = 0;
63
+
64
+ // public deltaRttLt50Measurements = 0;
65
+ // public deltaRttLt150Measurements = 0;
66
+ // public deltaRttLt300Measurements = 0;
67
+ // public deltaRttGtOrEq300Measurements = 0;
45
68
 
46
- public readonly sfuStreamIdToOutboundAudioTrack = new Map<string | number, ObservedOutboundAudioTrack>();
47
- public readonly sfuStreamIdToOutboundVideoTrack = new Map<string | number, ObservedOutboundVideoTrack>();
48
- private _closed = false;
49
- // this changes as clients emitting their joined event, as the call starts when the first client joins
50
- public started?: number;
51
- // this changes as clients emitting their left event, as the call ends when the last client leaves
52
- public ended?: number;
69
+ public appData: AppData;
70
+ public closed = false;
71
+ public startedAt?: number;
72
+ public endedAt?: number;
73
+ public closedAt?: number;
53
74
 
54
- public observationUpdated = Date.now();
55
- public observationEnded?: number;
56
- public readonly observationStarted = Date.now();
75
+ public readonly settings: Pick<ObservedCallSettings, 'closeCallIfEmptyForMs'>;
76
+ private closeTimer?: ReturnType<typeof setTimeout>;
57
77
 
58
78
  public constructor(
59
- private readonly _model: ObservedCallModel,
79
+ settings: ObservedCallSettings<AppData>,
60
80
  public readonly observer: Observer,
61
- public readonly appData: AppData,
62
81
  ) {
63
82
  super();
64
83
  this.setMaxListeners(Infinity);
65
- }
66
84
 
67
- public get serviceId(): string {
68
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
69
- return this._model.serviceId!;
70
- }
85
+ this.callId = settings.callId;
86
+ this.appData = settings.appData ?? {} as AppData;
87
+ this.scoreCalculator = new DefaultCallScoreCalculator(this);
88
+ this.detectors = new Detectors();
89
+
90
+ if (settings.updateIntervalInMs) {
91
+ if (settings.updatePolicy !== 'update-on-interval') {
92
+ throw new Error('updatePolicy must be update-on-interval if updateIntervalInMs is set in config');
93
+ }
94
+ }
95
+ switch (settings.updatePolicy) {
96
+ case 'update-on-any-client-updated':
97
+ this.updater = new OnAnyClientCallUpdater(this);
98
+ break;
99
+ case 'update-when-all-client-updated':
100
+ this.updater = new OnAllClientCallUpdater(this);
101
+ break;
102
+ case 'update-on-interval':
103
+ if (!settings.updateIntervalInMs) {
104
+ throw new Error('updateIntervalInMs setting in config must be set if updatePolicy is update-on-interval');
105
+ }
106
+ this.updater = new OnIntervalUpdater(
107
+ settings.updateIntervalInMs,
108
+ this.update.bind(this),
109
+ );
110
+ break;
111
+ }
71
112
 
72
- public get reports() {
73
- return this.observer.reports;
74
- }
113
+ switch (settings.remoteTrackResolvePolicy) {
114
+ case 'mediasoup-sfu':
115
+ break;
116
+ }
75
117
 
76
- public get roomId() {
77
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
78
- return this._model.roomId!;
118
+ this.settings = {
119
+ closeCallIfEmptyForMs: settings.closeCallIfEmptyForMs,
120
+ };
79
121
  }
80
122
 
81
- public get callId() {
82
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
83
- return this._model.callId!;
123
+ public get numberOfClients() {
124
+ return this.observedClients.size;
84
125
  }
85
126
 
86
- public get clients(): ReadonlyMap<string, ObservedClient> {
87
- return this._clients;
127
+ public get score() {
128
+ return this.calculatedScore.value;
88
129
  }
89
130
 
90
- public get score(): CalculatedScore | undefined {
91
- const now = Date.now();
92
-
93
- if (now - 15000 < (this._scoreData?.calculated ?? 0)) {
94
- return this._scoreData?.score;
95
- } else if (this.clients.size < 1) {
96
- return {
97
- remarks: [ {
98
- severity: 'none',
99
- text: 'No clients',
100
- } ],
101
- score: 5.0,
102
- timestamp: now,
103
- };
104
- }
105
- const scores = [ ...this.clients.values() ].map((client) => client.score?.score ?? 5.0);
106
-
107
- this._scoreData = {
108
- score: {
109
- remarks: [],
110
- score: getMedian(scores),
111
- timestamp: now,
112
- },
113
- calculated: now,
114
- };
131
+ public close() {
132
+ if (this.closed) return;
133
+ this.update(); // last update before closing
134
+ this.closed = true;
115
135
 
116
- return this._scoreData.score;
117
- }
136
+ this.updater?.close();
118
137
 
119
- public get closed() {
120
- return this._closed;
121
- }
138
+ let minSampleTimestamps: number | undefined;
139
+ let maxSampleTimestamps: number | undefined;
122
140
 
123
- public close() {
124
- if (this._closed) return;
125
- this._closed = true;
141
+ for (const client of this.observedClients.values()) {
142
+ client.close();
126
143
 
127
- Array.from(this._clients.values()).forEach((client) => client.close());
144
+ if (client.joinedAt) minSampleTimestamps = Math.min(minSampleTimestamps ?? client.joinedAt, client.joinedAt);
145
+ if (client.leftAt) maxSampleTimestamps = Math.max(maxSampleTimestamps ?? client.leftAt, client.leftAt);
146
+ }
128
147
 
129
- this.observationEnded = Date.now();
130
-
148
+ if (this.startedAt === undefined) this.startedAt = minSampleTimestamps;
149
+ if (this.endedAt === undefined) this.endedAt = maxSampleTimestamps;
150
+
151
+ this.closedAt = Date.now();
131
152
  this.emit('close');
132
153
  }
133
154
 
134
- public addEventReport(params: PartialBy<Omit<CallEventReport, 'serviceId' | 'roomId' | 'callId' >, 'timestamp'>) {
135
- this.reports.addCallEventReport({
136
- ...params,
137
- serviceId: this.serviceId,
138
- roomId: this.roomId,
139
- callId: this.callId,
140
- timestamp: params.timestamp ?? Date.now(),
141
- });
155
+ public getObservedClient<ClientAppData extends Record<string, unknown> = Record<string, unknown>>(clientId: string): ObservedClient<ClientAppData> | undefined {
156
+ if (this.closed || !this.observedClients.has(clientId)) return;
157
+
158
+ return this.observedClients.get(clientId) as ObservedClient<ClientAppData>;
142
159
  }
143
160
 
144
- public createClient<ClientAppData extends Record<string, unknown> = Record<string, unknown>>(config: ObservedClientModel & {
145
- appData: ClientAppData,
146
- // in case we generate the CLIENT_JOINED report we can set the timestamp of the event
147
- // in that case we should set the client.left to the timestamp of the leaving.
148
- // by default the timestamp is set to the current time
149
- joinedTimestamp?: number,
150
- createClientJoinedReport?: boolean,
151
- createClientLeftReport?: boolean,
152
- }) {
153
- if (this._closed) throw new Error(`Call ${this.callId} is closed`);
154
-
155
- const {
156
- appData,
157
- createClientJoinedReport,
158
- createClientLeftReport,
159
- joinedTimestamp = Date.now(),
160
- ...model
161
- } = config;
162
-
163
- const result = new ObservedClient(model, this, appData);
164
- const onUpdate = ({ sample }: { sample: ClientSample }) => {
165
- this.observationUpdated = Date.now();
166
- if (result.joined) {
167
- if (this.started === undefined || result.joined < this.started) {
168
- this.started = result.joined;
169
- }
170
- }
171
- if (result.left) {
172
- if (this.ended === undefined || result.left > this.ended) {
173
- this.ended = result.left;
174
- }
175
- }
161
+ public createObservedClient<ClientAppData extends Record<string, unknown> = Record<string, unknown>>(settings: ObservedClientSettings<ClientAppData>): ObservedClient<ClientAppData> {
162
+ if (this.closed) throw new Error(`Call ${this.callId} is closed`);
163
+ if (this.observedClients.has(settings.clientId)) throw new Error(`Client with id ${settings.clientId} already exists`);
176
164
 
177
- this.emit('update');
165
+ if (!settings.closeClientIfIdleForMs) {
166
+ settings.closeClientIfIdleForMs = this.observer.config.closeClientIfIdleForMs;
167
+ }
178
168
 
179
- this.processor.process(sample);
180
- };
169
+ const result = new ObservedClient<ClientAppData>(settings, this);
170
+ const wasEmpty = this.observedClients.size === 0;
171
+ const onUpdate = () => this._onClientUpdate(result);
172
+ const joined = () => this._clientJoined(result);
173
+ const left = () => this._clientLeft(result);
181
174
 
182
175
  result.once('close', () => {
183
176
  result.off('update', onUpdate);
184
- this._clients.delete(result.clientId);
185
-
186
- if (this._clients.size === 0) {
177
+ result.off('joined', joined);
178
+ result.off('left', left);
179
+ this.observedClients.delete(settings.clientId);
180
+
181
+ if (this.observedClients.size === 0) {
187
182
  this.emit('empty');
183
+
184
+ if (this.settings.closeCallIfEmptyForMs) {
185
+ this.closeTimer = setTimeout(() => {
186
+ this.close();
187
+ }, this.settings.closeCallIfEmptyForMs);
188
+ }
188
189
  }
190
+ ++this.totalRemovedClients;
189
191
  });
190
-
191
192
  result.on('update', onUpdate);
192
- this._clients.set(result.clientId, result);
193
-
194
- if (createClientJoinedReport) {
195
- this.reports.addCallEventReport(createClientJoinedEventReport(
196
- this.serviceId,
197
- result.mediaUnitId,
198
- this.roomId,
199
- this.callId,
200
- result.clientId,
201
- result.joined ?? joinedTimestamp,
202
- result.userId,
203
- result.marker,
204
- ));
205
- }
193
+ result.on('joined', joined);
194
+ result.on('left', left);
195
+ ++this.totalAddedClients;
206
196
 
207
- result.once('close', () => {
208
- if (createClientLeftReport) {
209
- this.reports.addCallEventReport(createClientLeftEventReport(
210
- this.serviceId,
211
- result.mediaUnitId,
212
- this.roomId,
213
- this.callId,
214
- result.clientId,
215
- result.left ?? Date.now(),
216
- result.userId,
217
- result.marker,
218
- ));
219
- }
220
- });
197
+ this.observedClients.set(settings.clientId, result);
198
+ this.maxNumberOfClients = Math.max(this.maxNumberOfClients, this.observedClients.size);
199
+
200
+ if (this.closeTimer) {
201
+ clearTimeout(this.closeTimer);
202
+ this.closeTimer = undefined;
203
+ }
221
204
 
222
205
  this.emit('newclient', result);
206
+
207
+ if (wasEmpty) {
208
+ this.emit('not-empty');
209
+ }
223
210
 
224
211
  return result;
225
212
  }
213
+
214
+ public createEventMonitor<CTX>(context: CTX): ObservedCallEventMonitor<CTX> {
215
+ return new ObservedCallEventMonitor(this, context);
216
+ }
217
+
218
+ public update() {
219
+ if (this.closed) return;
220
+
221
+ this.numberOfInboundRtpStreams = 0;
222
+ this.numberOfOutboundRtpStreams = 0;
223
+ this.numberOfPeerConnections = 0;
224
+ this.numberOfDataChannels = 0;
225
+
226
+ for (const client of this.observedClients.values()) {
227
+ this.numberOfInboundRtpStreams += client.numberOfInboundRtpStreams;
228
+ this.numberOfOutboundRtpStreams += client.numberOfOutboundRtpStreams;
229
+ this.numberOfPeerConnections += client.numberOfPeerConnections;
230
+ this.numberOfDataChannels += client.numberOfDataChannels;
231
+ }
232
+
233
+ this.detectors.update();
234
+ this.scoreCalculator.update();
235
+
236
+ this.emit('update');
237
+
238
+ this.deltaNumberOfIssues = 0;
239
+ }
240
+
241
+ private _onClientUpdate(client: ObservedClient) {
242
+ this.deltaNumberOfIssues += client.deltaNumberOfIssues;
243
+ this.numberOfIssues += client.deltaNumberOfIssues;
244
+
245
+ if (client.usingTURN) {
246
+ this.clientsUsedTurn.add(client.clientId);
247
+ }
248
+ }
249
+
250
+ private _clientJoined(client: ObservedClient) {
251
+ if (!client.joinedAt) return;
252
+
253
+ this.startedAt = Math.min(this.startedAt ?? client.joinedAt, client.joinedAt);
254
+ }
255
+
256
+ private _clientLeft(client: ObservedClient) {
257
+ if (!client.leftAt) return;
258
+
259
+ this.endedAt = Math.max(this.endedAt ?? client.leftAt, client.leftAt);
260
+ }
261
+
262
+ // public resetSummaryMetrics() {
263
+ // this.totalAddedClients = 0;
264
+ // this.totalRemovedClients = 0;
265
+
266
+ // this.totalClientsReceivedAudioBytes = 0;
267
+ // this.totalClientsReceivedVideoBytes = 0;
268
+ // this.totalClientsReceivedBytes = 0;
269
+
270
+ // this.totalClientsSentAudioBytes = 0;
271
+ // this.totalClientsSentVideoBytes = 0;
272
+ // this.totalClientsSentBytes = 0;
273
+
274
+ // this.totalRttLt50Measurements = 0;
275
+ // this.totalRttLt150Measurements = 0;
276
+ // this.totalRttLt300Measurements = 0;
277
+ // this.totalRttGtOrEq300Measurements = 0;
278
+
279
+ // this.numberOfIssues = 0;
280
+
281
+ // this.clientsUsedTurn.clear();
282
+
283
+ // }
284
+
285
+ // public createSummary(): ObservedCallSummary {
286
+ // return {
287
+ // currentActiveClients: this.observedClients.size,
288
+ // totalAddedClients: this.totalAddedClients,
289
+ // totalRemovedClients: this.totalRemovedClients,
290
+
291
+ // totalClientsReceivedAudioBytes: this.totalClientsReceivedBytes,
292
+ // totalClientsReceivedVideoBytes: this.totalClientsReceivedVideoBytes,
293
+ // totalClientsReceivedBytes: this.totalClientsReceivedBytes,
294
+
295
+ // totalClientsSentAudioBytes: this.totalClientsSentAudioBytes,
296
+ // totalClientsSentVideoBytes: this.totalClientsSentVideoBytes,
297
+ // totalClientsSentBytes: this.totalClientsSentBytes,
298
+
299
+ // totalRttLt50Measurements: this.totalRttLt50Measurements,
300
+ // totalRttLt150Measurements: this.totalRttLt150Measurements,
301
+ // totalRttLt300Measurements: this.totalRttLt300Measurements,
302
+ // totalRttGtOrEq300Measurements: this.totalRttGtOrEq300Measurements,
303
+
304
+ // numberOfIssues: this.numberOfIssues,
305
+ // numberOfClientsUsedTurn: this.clientsUsedTurn.size,
306
+ // };
307
+ // }
226
308
  }