@observertc/observer-js 0.42.9 → 1.0.0-beta.1

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 (299) hide show
  1. package/.prettierrc +6 -6
  2. package/README.md +493 -63
  3. package/lib/ObservedCall.d.ts +63 -43
  4. package/lib/ObservedCall.d.ts.map +1 -1
  5. package/lib/ObservedCall.js +188 -108
  6. package/lib/ObservedCallEventMonitor.d.ts +104 -0
  7. package/lib/ObservedCallEventMonitor.d.ts.map +1 -0
  8. package/lib/ObservedCallEventMonitor.js +314 -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 +81 -136
  15. package/lib/ObservedClient.d.ts.map +1 -1
  16. package/lib/ObservedClient.js +581 -744
  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 +32 -0
  42. package/lib/ObservedInboundTrack.d.ts.map +1 -0
  43. package/lib/ObservedInboundTrack.js +60 -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 +32 -0
  54. package/lib/ObservedOutboundTrack.d.ts.map +1 -0
  55. package/lib/ObservedOutboundTrack.js +60 -0
  56. package/lib/ObservedPeerConnection.d.ts +154 -80
  57. package/lib/ObservedPeerConnection.d.ts.map +1 -1
  58. package/lib/ObservedPeerConnection.js +709 -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 +49 -54
  75. package/lib/Observer.d.ts.map +1 -1
  76. package/lib/Observer.js +131 -226
  77. package/lib/ObserverEventMonitor.d.ts +138 -0
  78. package/lib/ObserverEventMonitor.d.ts.map +1 -0
  79. package/lib/ObserverEventMonitor.js +433 -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/common/Middleware.d.ts +10 -1
  84. package/lib/common/Middleware.d.ts.map +1 -1
  85. package/lib/common/Middleware.js +55 -36
  86. package/lib/common/logger.d.ts +8 -4
  87. package/lib/common/logger.d.ts.map +1 -1
  88. package/lib/common/logger.js +44 -68
  89. package/lib/common/types.d.ts +0 -21
  90. package/lib/common/types.d.ts.map +1 -1
  91. package/lib/common/types.js +1 -0
  92. package/lib/common/utils.d.ts +3 -1
  93. package/lib/common/utils.d.ts.map +1 -1
  94. package/lib/common/utils.js +23 -3
  95. package/lib/detectors/Detector.d.ts +5 -0
  96. package/lib/detectors/Detector.d.ts.map +1 -0
  97. package/lib/detectors/Detector.js +3 -0
  98. package/lib/detectors/Detectors.d.ts +11 -0
  99. package/lib/detectors/Detectors.d.ts.map +1 -0
  100. package/lib/detectors/Detectors.js +34 -0
  101. package/lib/index.d.ts +26 -25
  102. package/lib/index.d.ts.map +1 -1
  103. package/lib/index.js +45 -41
  104. package/lib/mediasoup/ObservedMediaRouter.d.ts +10 -0
  105. package/lib/mediasoup/ObservedMediaRouter.d.ts.map +1 -0
  106. package/lib/mediasoup/ObservedMediaRouter.js +6 -0
  107. package/lib/monitors/TurnUsageMonitor.d.ts +0 -52
  108. package/lib/monitors/TurnUsageMonitor.d.ts.map +1 -1
  109. package/lib/monitors/TurnUsageMonitor.js +145 -120
  110. package/lib/schema/ClientEventTypes.d.ts +228 -0
  111. package/lib/schema/ClientEventTypes.d.ts.map +1 -0
  112. package/lib/schema/ClientEventTypes.js +41 -0
  113. package/lib/schema/ClientMetaTypes.d.ts +34 -0
  114. package/lib/schema/ClientMetaTypes.d.ts.map +1 -0
  115. package/lib/schema/ClientMetaTypes.js +16 -0
  116. package/lib/schema/ClientSample.d.ts +1333 -0
  117. package/lib/schema/ClientSample.d.ts.map +1 -0
  118. package/lib/schema/ClientSample.js +4 -0
  119. package/lib/scores/CalculatedScore.d.ts +6 -0
  120. package/lib/scores/CalculatedScore.d.ts.map +1 -0
  121. package/lib/scores/CalculatedScore.js +2 -0
  122. package/lib/scores/DefaultCallScoreCalculator.d.ts +7 -0
  123. package/lib/scores/DefaultCallScoreCalculator.d.ts.map +1 -0
  124. package/lib/scores/DefaultCallScoreCalculator.js +21 -0
  125. package/lib/scores/ScoreCalculator.d.ts +4 -0
  126. package/lib/scores/ScoreCalculator.d.ts.map +1 -0
  127. package/lib/scores/ScoreCalculator.js +2 -0
  128. package/lib/updaters/CallUpdater.d.ts +5 -0
  129. package/lib/updaters/CallUpdater.d.ts.map +1 -0
  130. package/lib/updaters/CallUpdater.js +2 -0
  131. package/lib/updaters/ObserverUpdater.d.ts +5 -0
  132. package/lib/updaters/ObserverUpdater.d.ts.map +1 -0
  133. package/lib/updaters/ObserverUpdater.js +2 -0
  134. package/lib/updaters/OnAllCallObserverUpdater.d.ts +15 -0
  135. package/lib/updaters/OnAllCallObserverUpdater.d.ts.map +1 -0
  136. package/lib/updaters/OnAllCallObserverUpdater.js +50 -0
  137. package/lib/updaters/OnAllClientCallUpdater.d.ts +15 -0
  138. package/lib/updaters/OnAllClientCallUpdater.d.ts.map +1 -0
  139. package/lib/updaters/OnAllClientCallUpdater.js +53 -0
  140. package/lib/updaters/OnAnyCallObserverUpdater.d.ts +12 -0
  141. package/lib/updaters/OnAnyCallObserverUpdater.d.ts.map +1 -0
  142. package/lib/updaters/OnAnyCallObserverUpdater.js +37 -0
  143. package/lib/updaters/OnAnyClientCallUpdater.d.ts +12 -0
  144. package/lib/updaters/OnAnyClientCallUpdater.d.ts.map +1 -0
  145. package/lib/updaters/OnAnyClientCallUpdater.js +36 -0
  146. package/lib/updaters/OnIntervalUpdater.d.ts +10 -0
  147. package/lib/updaters/OnIntervalUpdater.d.ts.map +1 -0
  148. package/lib/updaters/OnIntervalUpdater.js +17 -0
  149. package/lib/updaters/Updater.d.ts +6 -0
  150. package/lib/updaters/Updater.d.ts.map +1 -0
  151. package/lib/updaters/Updater.js +2 -0
  152. package/lib/utils/MediasoupRemoteTrackResolver.d.ts +25 -0
  153. package/lib/utils/MediasoupRemoteTrackResolver.d.ts.map +1 -0
  154. package/lib/utils/MediasoupRemoteTrackResolver.js +110 -0
  155. package/lib/utils/RemoteTrackResolver.d.ts +7 -0
  156. package/lib/utils/RemoteTrackResolver.d.ts.map +1 -0
  157. package/lib/utils/RemoteTrackResolver.js +2 -0
  158. package/package.json +4 -4
  159. package/src/ObservedCall.ts +276 -164
  160. package/src/ObservedCallEventMonitor.ts +392 -0
  161. package/src/ObservedCallSummary.ts +22 -0
  162. package/src/ObservedCertificate.ts +43 -0
  163. package/src/ObservedClient.ts +624 -1007
  164. package/src/ObservedClientEventMonitor.ts +309 -0
  165. package/src/ObservedClientSummary.ts +24 -0
  166. package/src/ObservedCodec.ts +49 -0
  167. package/src/ObservedDataChannel.ts +71 -181
  168. package/src/ObservedIceCandidate.ts +64 -0
  169. package/src/ObservedIceCandidatePair.ts +134 -0
  170. package/src/ObservedIceTransport.ts +99 -0
  171. package/src/ObservedInboundRtp.ts +205 -0
  172. package/src/ObservedInboundTrack.ts +75 -0
  173. package/src/ObservedMediaPlayout.ts +49 -0
  174. package/src/ObservedMediaSource.ts +60 -0
  175. package/src/ObservedOutboundRtp.ts +156 -0
  176. package/src/ObservedOutboundTrack.ts +74 -0
  177. package/src/ObservedPeerConnection.ts +917 -402
  178. package/src/ObservedPeerConnectionTransport.ts +38 -0
  179. package/src/ObservedRemoteInboundRtp.ts +64 -0
  180. package/src/ObservedRemoteOutboundRtp.ts +65 -0
  181. package/src/ObservedTURN.ts +86 -0
  182. package/src/ObservedTurnServer.ts +72 -0
  183. package/src/Observer.ts +182 -298
  184. package/src/ObserverEventMonitor.ts +551 -0
  185. package/src/ObserverSummary.ts +15 -0
  186. package/src/common/Middleware.ts +70 -42
  187. package/src/common/logger.ts +60 -69
  188. package/src/common/types.ts +0 -42
  189. package/src/common/utils.ts +24 -2
  190. package/src/detectors/Detector.ts +6 -0
  191. package/src/detectors/Detectors.ts +38 -0
  192. package/src/index.ts +26 -91
  193. package/src/mediasoup/ObservedMediaRouter.ts +10 -0
  194. package/src/monitors/TurnUsageMonitor.ts +164 -164
  195. package/src/schema/ClientEventTypes.ts +280 -0
  196. package/src/schema/ClientMetaTypes.ts +41 -0
  197. package/src/schema/ClientSample.ts +1682 -0
  198. package/src/scores/CalculatedScore.ts +6 -0
  199. package/src/scores/DefaultCallScoreCalculator.ts +23 -0
  200. package/src/scores/ScoreCalculator.ts +3 -0
  201. package/src/updaters/CallUpdater.ts +5 -0
  202. package/src/updaters/ObserverUpdater.ts +5 -0
  203. package/src/updaters/OnAllCallObserverUpdater.ts +59 -0
  204. package/src/updaters/OnAllClientCallUpdater.ts +61 -0
  205. package/src/updaters/OnAnyCallObserverUpdater.ts +41 -0
  206. package/src/updaters/OnAnyClientCallUpdater.ts +39 -0
  207. package/src/updaters/OnIntervalUpdater.ts +19 -0
  208. package/src/updaters/Updater.ts +5 -0
  209. package/src/utils/MediasoupRemoteTrackResolver.ts +155 -0
  210. package/src/utils/RemoteTrackResolver.ts +12 -0
  211. package/tsconfig.json +3 -3
  212. package/lib/ObservedICE.d.ts +0 -64
  213. package/lib/ObservedICE.d.ts.map +0 -1
  214. package/lib/ObservedICE.js +0 -141
  215. package/lib/ObservedInboundAudioTrack.d.ts +0 -96
  216. package/lib/ObservedInboundAudioTrack.d.ts.map +0 -1
  217. package/lib/ObservedInboundAudioTrack.js +0 -217
  218. package/lib/ObservedInboundVideoTrack.d.ts +0 -101
  219. package/lib/ObservedInboundVideoTrack.d.ts.map +0 -1
  220. package/lib/ObservedInboundVideoTrack.js +0 -232
  221. package/lib/ObservedOutboundAudioTrack.d.ts +0 -87
  222. package/lib/ObservedOutboundAudioTrack.d.ts.map +0 -1
  223. package/lib/ObservedOutboundAudioTrack.js +0 -186
  224. package/lib/ObservedOutboundVideoTrack.d.ts +0 -91
  225. package/lib/ObservedOutboundVideoTrack.d.ts.map +0 -1
  226. package/lib/ObservedOutboundVideoTrack.js +0 -193
  227. package/lib/ObservedSfu.d.ts +0 -59
  228. package/lib/ObservedSfu.d.ts.map +0 -1
  229. package/lib/ObservedSfu.js +0 -157
  230. package/lib/ObservedSfuInboundRtpPad.d.ts +0 -42
  231. package/lib/ObservedSfuInboundRtpPad.d.ts.map +0 -1
  232. package/lib/ObservedSfuInboundRtpPad.js +0 -71
  233. package/lib/ObservedSfuOutboundRtpPad.d.ts +0 -42
  234. package/lib/ObservedSfuOutboundRtpPad.d.ts.map +0 -1
  235. package/lib/ObservedSfuOutboundRtpPad.js +0 -72
  236. package/lib/ObservedSfuSctpChannel.d.ts +0 -42
  237. package/lib/ObservedSfuSctpChannel.d.ts.map +0 -1
  238. package/lib/ObservedSfuSctpChannel.js +0 -57
  239. package/lib/ObservedSfuTransport.d.ts +0 -58
  240. package/lib/ObservedSfuTransport.d.ts.map +0 -1
  241. package/lib/ObservedSfuTransport.js +0 -120
  242. package/lib/RemoteTrackAssigner.d.ts +0 -14
  243. package/lib/RemoteTrackAssigner.d.ts.map +0 -1
  244. package/lib/RemoteTrackAssigner.js +0 -52
  245. package/lib/ReportsCollector.d.ts +0 -109
  246. package/lib/ReportsCollector.d.ts.map +0 -1
  247. package/lib/ReportsCollector.js +0 -207
  248. package/lib/common/CalculatedScore.d.ts +0 -80
  249. package/lib/common/CalculatedScore.d.ts.map +0 -1
  250. package/lib/common/CalculatedScore.js +0 -162
  251. package/lib/common/CallEventType.d.ts +0 -63
  252. package/lib/common/CallEventType.d.ts.map +0 -1
  253. package/lib/common/CallEventType.js +0 -39
  254. package/lib/common/CallMetaReports.d.ts +0 -42
  255. package/lib/common/CallMetaReports.d.ts.map +0 -1
  256. package/lib/common/CallMetaReports.js +0 -36
  257. package/lib/common/QualityScoreUtils.d.ts +0 -1
  258. package/lib/common/QualityScoreUtils.d.ts.map +0 -1
  259. package/lib/common/QualityScoreUtils.js +0 -1
  260. package/lib/common/TypedEventEmitter.d.ts +0 -22
  261. package/lib/common/TypedEventEmitter.d.ts.map +0 -1
  262. package/lib/common/TypedEventEmitter.js +0 -11
  263. package/lib/common/callEventReports.d.ts +0 -10
  264. package/lib/common/callEventReports.d.ts.map +0 -1
  265. package/lib/common/callEventReports.js +0 -112
  266. package/lib/monitors/CallSummary.d.ts +0 -37
  267. package/lib/monitors/CallSummary.d.ts.map +0 -1
  268. package/lib/monitors/CallSummaryMonitor.d.ts +0 -32
  269. package/lib/monitors/CallSummaryMonitor.d.ts.map +0 -1
  270. package/lib/monitors/CallSummaryMonitor.js +0 -152
  271. package/lib/monitors/ClientIssueMonitor.d.ts +0 -32
  272. package/lib/monitors/ClientIssueMonitor.d.ts.map +0 -1
  273. package/lib/monitors/ClientIssueMonitor.js +0 -49
  274. package/lib/monitors/SfuServerMonitor.d.ts +0 -79
  275. package/lib/monitors/SfuServerMonitor.d.ts.map +0 -1
  276. package/lib/monitors/SfuServerMonitor.js +0 -198
  277. package/src/ObservedICE.ts +0 -237
  278. package/src/ObservedInboundAudioTrack.ts +0 -344
  279. package/src/ObservedInboundVideoTrack.ts +0 -361
  280. package/src/ObservedOutboundAudioTrack.ts +0 -307
  281. package/src/ObservedOutboundVideoTrack.ts +0 -319
  282. package/src/ObservedSfu.ts +0 -231
  283. package/src/ObservedSfuInboundRtpPad.ts +0 -106
  284. package/src/ObservedSfuOutboundRtpPad.ts +0 -107
  285. package/src/ObservedSfuSctpChannel.ts +0 -103
  286. package/src/ObservedSfuTransport.ts +0 -185
  287. package/src/RemoteTrackAssigner.ts +0 -68
  288. package/src/ReportsCollector.ts +0 -336
  289. package/src/common/CalculatedScore.ts +0 -188
  290. package/src/common/CallEventType.ts +0 -69
  291. package/src/common/CallMetaReports.ts +0 -82
  292. package/src/common/QualityScoreUtils.ts +0 -0
  293. package/src/common/TypedEventEmitter.ts +0 -32
  294. package/src/common/callEventReports.ts +0 -178
  295. package/src/monitors/CallSummary.ts +0 -38
  296. package/src/monitors/CallSummaryMonitor.ts +0 -192
  297. package/src/monitors/ClientIssueMonitor.ts +0 -88
  298. package/src/monitors/SfuServerMonitor.ts +0 -285
  299. /package/lib/{monitors/CallSummary.js → ObservedCallSummary.js} +0 -0
package/src/Observer.ts CHANGED
@@ -1,48 +1,37 @@
1
1
  import { createLogger } from './common/logger';
2
- import { ObservedCall, ObservedCallModel } from './ObservedCall';
3
- import { ReportsCollector } from './ReportsCollector';
2
+ import { ObservedCall, ObservedCallSettings } from './ObservedCall';
4
3
  import { EventEmitter } from 'events';
5
- import { PartialBy } from './common/utils';
6
- import { createCallEndedEventReport, createCallStartedEventReport } from './common/callEventReports';
7
- import { ObserverSinkContext } from './common/types';
8
- import { ObservedSfu, ObservedSfuModel } from './ObservedSfu';
9
- import { CallSummaryMonitor, CallSummaryMonitorConfig } from './monitors/CallSummaryMonitor';
10
- import { TurnUsageMonitor } from './monitors/TurnUsageMonitor';
4
+ import { ClientEvent, ClientMetaData, ClientIssue, ExtensionStat, ClientSample } from './schema/ClientSample';
11
5
  import { ObservedClient } from './ObservedClient';
12
- import { ObservedPeerConnection } from './ObservedPeerConnection';
13
- import { ClientIssueMonitor } from './monitors/ClientIssueMonitor';
14
- import { SfuServerMonitor } from './monitors/SfuServerMonitor';
6
+ import { ObservedTURN } from './ObservedTURN';
7
+ import { Detectors } from './detectors/Detectors';
8
+ import { Updater } from './updaters/Updater';
9
+ import { OnIntervalUpdater } from './updaters/OnIntervalUpdater';
10
+ import { OnAllCallObserverUpdater } from './updaters/OnAllCallObserverUpdater';
11
+ import { OnAnyCallObserverUpdater } from './updaters/OnAnyCallObserverUpdater';
12
+ import { ObserverEventMonitor } from './ObserverEventMonitor';
13
+ import { MediasoupRemoteTrackResolver } from './utils/MediasoupRemoteTrackResolver';
15
14
 
16
15
  const logger = createLogger('Observer');
17
16
 
18
17
  export type ObserverEvents = {
18
+ 'client-event': [ObservedClient, ClientEvent];
19
+ 'call-updated': [ObservedCall],
20
+ 'client-issue': [ObservedClient, ClientIssue];
21
+ 'client-metadata': [ObservedClient, ClientMetaData];
22
+ 'client-extension-stats': [ObservedClient, ExtensionStat];
19
23
  'newcall': [ObservedCall],
20
- 'newsfu': [ObservedSfu],
21
- 'reports': [ObserverSinkContext],
24
+ 'update': [],
22
25
  'close': [],
23
26
  }
24
27
 
25
- export type ObserverConfig = {
26
-
27
- /**
28
- *
29
- * Sets the default serviceId for samples.
30
- *
31
- * For more information about a serviceId please visit https://observertc.org
32
- *
33
- */
34
- defaultServiceId: string;
35
-
36
- /**
37
- * Sets the default mediaUnitId for samples.
38
- *
39
- * For more information about a mediaUnitId please visit https://observertc.org
40
- */
41
- defaultMediaUnitId: string;
42
-
43
- maxReports?: number | undefined;
44
- maxCollectingTimeInMs?: number | undefined;
45
- };
28
+ export type ObserverConfig<AppData extends Record<string, unknown> = Record<string, unknown>> = {
29
+ updatePolicy?: 'update-on-any-call-updated' | 'update-when-all-call-updated' | 'update-on-interval',
30
+ updateIntervalInMs?: number,
31
+ defaultCallUpdatePolicy?: ObservedCallSettings['updatePolicy'],
32
+ defaultCallUpdateIntervalInMs?: number,
33
+ appData?: AppData,
34
+ }
46
35
 
47
36
  export declare interface Observer {
48
37
  on<U extends keyof ObserverEvents>(event: U, listener: (...args: ObserverEvents[U]) => void): this;
@@ -51,313 +40,208 @@ export declare interface Observer {
51
40
  emit<U extends keyof ObserverEvents>(event: U, ...args: ObserverEvents[U]): boolean;
52
41
  }
53
42
 
54
- export class Observer extends EventEmitter {
55
- public static create(providedConfig: Partial<ObserverConfig>): Observer {
56
- const config: ObserverConfig = Object.assign(
57
- {
58
- defaultServiceId: 'default-service-id',
59
- defaultMediaUnitId: 'default-media-unit-id',
60
- evaluator: {
61
- fetchSamples: true,
62
- maxIdleTimeInMs: 300 * 1000,
63
- },
64
- sink: {},
65
- logLevel: 'info',
66
- },
67
- providedConfig
68
- );
69
-
70
- return new Observer(config);
43
+ export class Observer<AppData extends Record<string, unknown> = Record<string, unknown>> extends EventEmitter {
44
+ public readonly detectors: Detectors;
45
+
46
+ public readonly observedTURN = new ObservedTURN();
47
+ public readonly observedCalls = new Map<string, ObservedCall>();
48
+ public updater?: Updater;
49
+
50
+ public closed = false;
51
+
52
+ public totalAddedCall = 0;
53
+ public totalRemovedCall = 0;
54
+ public totalRttLt50Measurements = 0;
55
+ public totalRttLt150Measurements = 0;
56
+ public totalRttLt300Measurements = 0;
57
+ public totalRttGtOrEq300Measurements = 0;
58
+ public totalClientIssues = 0;
59
+
60
+ public numberOfClientsUsingTurn = 0;
61
+ public numberOfClients = 0;
62
+ public numberOfInboundRtpStreams = 0;
63
+ public numberOfOutboundRtpStreams = 0;
64
+ public numberOfDataChannels = 0;
65
+ public numberOfPeerConnections = 0;
66
+
67
+ public get numberOfCalls() {
68
+ return this.observedCalls.size;
71
69
  }
72
70
 
73
- public readonly reports = new ReportsCollector();
74
- private readonly _observedCalls = new Map<string, ObservedCall>();
75
- private readonly _observedSfus = new Map<string, ObservedSfu>();
76
- private readonly _monitors = new Map<string, { close:() => void, once: (e: 'close', l: () => void) => void }>();
71
+ private _timer?: ReturnType<typeof setInterval>;
77
72
 
78
- private _reportTimer?: ReturnType<typeof setTimeout>;
79
- private _closed = false;
80
- public constructor(
81
- public readonly config: ObserverConfig,
82
- ) {
73
+ public constructor(public readonly config: ObserverConfig<AppData> = {
74
+ updatePolicy: 'update-when-all-call-updated',
75
+ updateIntervalInMs: undefined,
76
+ appData: {} as AppData,
77
+ }) {
83
78
  super();
84
79
  this.setMaxListeners(Infinity);
85
-
86
- logger.debug('Observer is created with config', this.config);
87
-
88
- const onReports = (context: ObserverSinkContext) => this.emit('reports', context);
89
- const onNewReport = (collectedReports: number) => {
90
- if (!this.config.maxReports || this._closed) return;
91
- if (this.config.maxReports < collectedReports) {
92
- this._emitReports();
80
+ this.update = this.update.bind(this);
81
+
82
+ const currentUpdatePolicy = (config?.updatePolicy) ?? 'update-when-all-call-updated';
83
+
84
+ switch (currentUpdatePolicy) {
85
+ case 'update-on-any-call-updated':
86
+ this.updater = new OnAnyCallObserverUpdater(this);
87
+ break;
88
+ case 'update-when-all-call-updated':
89
+ this.updater = new OnAllCallObserverUpdater(this);
90
+ break;
91
+ case 'update-on-interval': {
92
+ const interval = config?.updateIntervalInMs;
93
+
94
+ if (!interval) {
95
+ throw new Error('updateIntervalInMs setting in config must be set if updatePolicy is update-on-interval');
96
+ }
97
+ this.updater = new OnIntervalUpdater(
98
+ interval,
99
+ this.update.bind(this),
100
+ );
101
+ break;
93
102
  }
94
- };
103
+ }
104
+
105
+ this.detectors = new Detectors();
106
+ }
95
107
 
96
- this._emitReports();
108
+ public get appData() {
109
+ return this.config.appData;
110
+ }
97
111
 
98
- this.once('close', () => {
99
- this.reports.off('newreport', onNewReport);
100
- this.reports.off('reports', onReports);
101
- });
102
- this.reports.on('newreport', onNewReport);
103
- this.reports.on('reports', onReports);
112
+ public getObservedCall<T extends Record<string, unknown> = Record<string, unknown>>(callId: string): ObservedCall<T> | undefined {
113
+ if (this.closed || !this.observedCalls.has(callId)) return;
114
+
115
+ return this.observedCalls.get(callId) as ObservedCall<T>;
104
116
  }
105
117
 
106
118
  public createObservedCall<T extends Record<string, unknown> = Record<string, unknown>>(
107
- config: PartialBy<ObservedCallModel, 'serviceId'> & { appData: T, reportCallStarted?: boolean, reportCallEnded?: boolean }
119
+ settings: ObservedCallSettings<T>
108
120
  ): ObservedCall<T> {
109
- if (this._closed) {
121
+ if (this.closed) {
110
122
  throw new Error('Attempted to create a call source on a closed observer');
111
123
  }
112
-
113
- const {
114
- appData,
115
- reportCallEnded = true,
116
- reportCallStarted = true,
117
- ...model
118
- } = config;
119
- const call = new ObservedCall({
120
- ...model,
121
- serviceId: this.config.defaultServiceId,
122
- }, this, appData);
123
-
124
- if (this._closed) throw new Error('Cannot create an observed call on a closed observer');
125
- if (this._observedCalls.has(call.callId)) throw new Error(`Observed Call with id ${call.callId} already exists`);
126
-
127
- call.once('close', () => {
128
- this._observedCalls.delete(call.callId);
129
- reportCallEnded && this.reports.addCallEventReport(createCallEndedEventReport(
130
- call.serviceId,
131
- call.roomId,
132
- call.callId,
133
- call.observationEnded ?? Date.now(),
134
- ));
135
- });
136
-
137
- this._observedCalls.set(call.callId, call);
138
- reportCallStarted && this.reports.addCallEventReport(createCallStartedEventReport(
139
- call.serviceId,
140
- call.roomId,
141
- call.callId,
142
- call.observationStarted,
143
- ));
144
-
145
- this.emit('newcall', call);
146
-
147
- return call;
148
- }
149
-
150
- public createObservedSfu<AppData extends Record<string, unknown> = Record<string, unknown>>(
151
- model: ObservedSfuModel,
152
- appData: AppData,
153
- ): ObservedSfu<AppData> {
154
- if (this._closed) {
155
- throw new Error('Attempted to create an sfu source on a closed observer');
124
+ if (!settings.updatePolicy) {
125
+ settings.updatePolicy = this.config.defaultCallUpdatePolicy;
126
+ settings.updateIntervalInMs = this.config.defaultCallUpdateIntervalInMs;
156
127
  }
128
+ const observedCall = new ObservedCall(settings, this);
129
+ const onCallUpdated = () => this._onObservedCallUpdated(observedCall);
157
130
 
158
- const sfu = new ObservedSfu<AppData>(model, this, appData);
131
+ if (this.observedCalls.has(observedCall.callId)) throw new Error(`Observed Call with id ${observedCall.callId} already exists`);
159
132
 
160
- if (this._closed) throw new Error('Cannot create an observed sfu on a closed observer');
161
- if (this._observedSfus.has(sfu.sfuId)) throw new Error(`Observed SFU with id ${sfu.sfuId} already exists`);
133
+ if (settings.remoteTrackResolvePolicy === 'mediasoup-sfu') {
134
+ observedCall.remoteTrackResolver = new MediasoupRemoteTrackResolver(observedCall);
135
+ }
162
136
 
163
- sfu.once('close', () => {
164
- this._observedSfus.delete(sfu.sfuId);
137
+ observedCall.once('close', () => {
138
+ this.observedCalls.delete(observedCall.callId);
139
+ observedCall.off('update', onCallUpdated);
140
+ ++this.totalRemovedCall;
165
141
  });
166
142
 
167
- this._observedSfus.set(sfu.sfuId, sfu);
168
- this.emit('newsfu', sfu);
169
-
170
- return sfu;
171
- }
172
-
173
- public createCallSummaryMonitor(options?: CallSummaryMonitorConfig & { timeoutAfterCallClose?: number }): CallSummaryMonitor {
174
- if (this._closed) throw new Error('Cannot create a call summary monitor on a closed observer');
175
-
176
- const existingMonitor = this._monitors.get(CallSummaryMonitor.name);
177
-
178
- if (existingMonitor) return existingMonitor as CallSummaryMonitor;
179
-
180
- const monitor = new CallSummaryMonitor(options);
181
- const onNewCall = (call: ObservedCall) => {
182
- monitor.addCall(call);
183
-
184
- call.once('close', () => setTimeout(() => {
185
- const summary = monitor.takeSummary(call.callId);
143
+ this.observedCalls.set(observedCall.callId, observedCall);
144
+ observedCall.on('update', onCallUpdated);
145
+ ++this.totalAddedCall;
186
146
 
187
- summary && monitor.emit('summary', summary);
188
-
189
- }, options?.timeoutAfterCallClose ?? 1000));
190
- };
191
-
192
- monitor.once('close', () => {
193
- this._monitors.delete(CallSummaryMonitor.name);
194
- this.off('newcall', onNewCall);
195
- });
196
-
197
- this._monitors.set(CallSummaryMonitor.name, monitor);
198
- this.on('newcall', onNewCall);
147
+ this.emit('newcall', observedCall);
199
148
 
200
- this.once('close', () => {
201
- monitor.close();
202
- });
203
-
204
- return monitor;
149
+ return observedCall;
205
150
  }
206
151
 
207
- public createTurnUsageMonitor() {
208
- if (this._closed) throw new Error('Cannot create a turn usage monitor on a closed observer');
209
-
210
- const existingMonitor = this._monitors.get(TurnUsageMonitor.name);
211
-
212
- if (existingMonitor) return existingMonitor as TurnUsageMonitor;
213
-
214
- const monitor = new TurnUsageMonitor();
215
-
216
- const onNewCall = (call: ObservedCall) => {
217
- const onNewClient = (client: ObservedClient) => {
218
- const onNewPeerConnection = (pc: ObservedPeerConnection) => {
219
- const onUsingTurnChanged = (usingTurn: boolean) => {
220
- if (usingTurn) monitor.addPeerConnection(pc);
221
- else monitor.removePeerConnection(pc);
222
- };
223
-
224
- pc.once('close', () => {
225
- pc.ICE.off('usingturnchanged', onUsingTurnChanged);
226
- monitor.removePeerConnection(pc);
227
- });
228
- pc.ICE.on('usingturnchanged', onUsingTurnChanged);
229
- };
230
-
231
- client.once('close', () => client.off('newpeerconnection', onNewPeerConnection));
232
- client.on('newpeerconnection', onNewPeerConnection);
233
- };
234
-
235
- call.once('close', () => call.off('newclient', onNewClient));
236
- call.on('newclient', onNewClient);
237
- };
238
-
239
- monitor.once('close', () => {
240
- this._monitors.delete(TurnUsageMonitor.name);
241
- this.off('newcall', onNewCall);
242
- });
152
+ public close() {
153
+ if (this.closed) {
154
+ return logger.debug('Attempted to close twice');
155
+ }
156
+ this.closed = true;
157
+ clearInterval(this._timer);
158
+ this._timer = undefined;
243
159
 
244
- this._monitors.set(TurnUsageMonitor.name, monitor);
245
- this.on('newcall', onNewCall);
160
+ this.observedCalls.forEach((call) => call.close());
246
161
 
247
- this.once('close', () => {
248
- monitor.close();
249
- });
250
-
251
- return monitor;
162
+ this.emit('close');
252
163
  }
253
164
 
254
- public createSfuServerMonitor() {
255
- if (this._closed) throw new Error('Cannot create a turn usage monitor on a closed observer');
256
-
257
- const existingMonitor = this._monitors.get(SfuServerMonitor.name);
258
-
259
- if (existingMonitor) return existingMonitor as SfuServerMonitor;
260
-
261
- const monitor = new SfuServerMonitor({
262
- tooHighRttAlertSettings: {
263
- minNumberOfPeerConnections: 10,
264
- percentageOfPeerConnectionsHighWatermark: 0.5,
265
- percentageOfPeerConnectionsLowWatermark: 0.2,
266
- threshold: 'rtt-gt-300',
267
- }
268
- });
269
-
270
- const onNewCall = (call: ObservedCall) => {
271
- const onNewClient = (client: ObservedClient) => {
272
- const onNewPeerConnection = (pc: ObservedPeerConnection) => {
273
- monitor.addPeerConnection(pc);
274
- };
275
-
276
- client.once('close', () => client.off('newpeerconnection', onNewPeerConnection));
277
- client.on('newpeerconnection', onNewPeerConnection);
278
- };
279
-
280
- call.once('close', () => call.off('newclient', onNewClient));
281
- call.on('newclient', onNewClient);
282
- };
165
+ public accept(sample: ClientSample) {
166
+ if (this.closed) return;
167
+ if (!sample.callId) return logger.warn('Received sample without callId. %o', sample);
168
+ if (!sample.clientId) return logger.warn('Received sample without clientId %o', sample);
283
169
 
284
- monitor.once('close', () => {
285
- this._monitors.delete(SfuServerMonitor.name);
286
- this.off('newcall', onNewCall);
170
+ const call = this.getObservedCall(sample.callId) ?? this.createObservedCall({
171
+ callId: sample.callId,
172
+ updateIntervalInMs: this.config.defaultCallUpdateIntervalInMs,
173
+ updatePolicy: this.config.defaultCallUpdatePolicy,
287
174
  });
288
175
 
289
- this._monitors.set(SfuServerMonitor.name, monitor);
290
- this.on('newcall', onNewCall);
291
-
292
- this.once('close', () => {
293
- monitor.close();
176
+ const client = call.getObservedClient(sample.clientId) ?? call.createObservedClient({
177
+ clientId: sample.clientId,
294
178
  });
295
179
 
296
- return monitor;
180
+ client.accept(sample);
297
181
  }
298
182
 
299
- public createClientIssueMonitor() {
300
- if (this._closed) throw new Error('Cannot create a turn usage monitor on a closed observer');
301
-
302
- const existingMonitor = this._monitors.get(ClientIssueMonitor.name);
303
-
304
- if (existingMonitor) return existingMonitor as ClientIssueMonitor;
305
-
306
- const monitor = new ClientIssueMonitor();
307
-
308
- const onNewCall = (call: ObservedCall) => monitor.addCall(call);
309
-
310
- monitor.once('close', () => {
311
- this._monitors.delete(ClientIssueMonitor.name);
312
- this.off('newcall', onNewCall);
313
- });
314
-
315
- this._monitors.set(ClientIssueMonitor.name, monitor);
316
- this.on('newcall', onNewCall);
317
-
318
- this.once('close', () => {
319
- monitor.close();
320
- });
183
+ public update() {
184
+ if (this.closed) {
185
+ return;
186
+ }
321
187
 
322
- return monitor;
323
- }
188
+ this.numberOfInboundRtpStreams = 0;
189
+ this.numberOfOutboundRtpStreams = 0;
190
+ this.numberOfPeerConnections = 0;
191
+ this.numberOfDataChannels = 0;
192
+ this.numberOfClients = 0;
193
+ this.numberOfClientsUsingTurn = 0;
194
+
195
+ for (const call of this.observedCalls.values()) {
196
+ this.numberOfInboundRtpStreams += call.numberOfInboundRtpStreams;
197
+ this.numberOfOutboundRtpStreams += call.numberOfOutboundRtpStreams;
198
+ this.numberOfPeerConnections += call.numberOfPeerConnections;
199
+ this.numberOfDataChannels += call.numberOfDataChannels;
200
+ this.numberOfClients += call.numberOfClients;
201
+ this.numberOfClientsUsingTurn += call.clientsUsedTurn.size;
202
+ }
324
203
 
325
- public get observedCalls(): ReadonlyMap<string, ObservedCall> {
326
- return this._observedCalls;
327
- }
204
+ this.observedTURN.update();
328
205
 
329
- public get observedSfus(): ReadonlyMap<string, ObservedSfu> {
330
- return this._observedSfus;
206
+ this.emit('update');
331
207
  }
332
208
 
333
- public get closed() {
334
- return this._closed;
209
+ private _onObservedCallUpdated(call: ObservedCall) {
210
+ this.totalRttLt50Measurements += call.deltaRttLt50Measurements;
211
+ this.totalRttLt150Measurements += call.deltaRttLt150Measurements;
212
+ this.totalRttLt300Measurements += call.deltaRttLt300Measurements;
213
+ this.totalRttGtOrEq300Measurements += call.deltaRttGtOrEq300Measurements;
214
+ this.totalClientIssues += call.deltaNumberOfIssues;
335
215
  }
336
216
 
337
- public close() {
338
- if (this._closed) {
339
- return logger.debug('Attempted to close twice');
340
- }
341
- this._closed = true;
342
-
343
- this._observedCalls.forEach((call) => call.close());
344
-
345
- this.emit('close');
217
+ public createEventMonitor<CTX = unknown>(ctx?: CTX): ObserverEventMonitor<CTX> {
218
+ return new ObserverEventMonitor<CTX>(this, ctx ?? {} as CTX);
346
219
  }
347
220
 
348
- private _emitReports() {
349
- if (this._reportTimer) {
350
- clearTimeout(this._reportTimer);
351
- this._reportTimer = undefined;
352
- }
353
-
354
- this.reports.emit();
221
+ // public resetSummaryMetrics() {
222
+ // this.totalAddedCall = 0;
223
+ // this.totalRemovedCall = 0;
224
+ // this.totalRttLt50Measurements = 0;
225
+ // this.totalRttLt150Measurements = 0;
226
+ // this.totalRttLt300Measurements = 0;
227
+ // this.totalRttGtOrEq300Measurements = 0;
228
+ // this.totalClientIssues = 0;
229
+ // }
230
+
231
+ // public createSummary(): ObserverSummary {
232
+ // return {
233
+ // totalAddedCall: this.totalAddedCall,
234
+ // totalRemovedCall: this.totalRemovedCall,
235
+ // totalRttLt50Measurements: this.totalRttLt50Measurements,
236
+ // totalRttLt150Measurements: this.totalRttLt150Measurements,
237
+ // totalRttLt300Measurements: this.totalRttLt300Measurements,
238
+ // totalRttGtOrEq300Measurements: this.totalRttGtOrEq300Measurements,
239
+
240
+ // totalClientIssues: this.totalClientIssues,
241
+ // currentActiveCalls: this.observedCalls.size,
242
+ // currentNumberOfClients: this.numberOfClients,
243
+ // currentNumberOfClientsUsingTURN: this.numberOfClientsUsedTurn,
244
+ // };
245
+ // }
355
246
 
356
- if (this.config.maxCollectingTimeInMs) {
357
- this._reportTimer = setTimeout(() => {
358
- this._reportTimer = undefined;
359
- this._emitReports();
360
- }, this.config.maxCollectingTimeInMs);
361
- }
362
- }
363
247
  }