@observertc/observer-js 0.42.9 → 1.0.1-57a1811.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 (247) hide show
  1. package/.prettierrc +6 -6
  2. package/README.md +0 -104
  3. package/lib/ObservedCall.d.ts +38 -41
  4. package/lib/ObservedCall.d.ts.map +1 -1
  5. package/lib/ObservedCall.js +97 -109
  6. package/lib/ObservedCertificate.d.ts +19 -0
  7. package/lib/ObservedCertificate.d.ts.map +1 -0
  8. package/lib/ObservedCertificate.js +38 -0
  9. package/lib/ObservedClient.d.ts +49 -127
  10. package/lib/ObservedClient.d.ts.map +1 -1
  11. package/lib/ObservedClient.js +201 -750
  12. package/lib/ObservedCodec.d.ts +22 -0
  13. package/lib/ObservedCodec.d.ts.map +1 -0
  14. package/lib/ObservedCodec.js +45 -0
  15. package/lib/ObservedDataChannel.d.ts +23 -69
  16. package/lib/ObservedDataChannel.d.ts.map +1 -1
  17. package/lib/ObservedDataChannel.js +67 -109
  18. package/lib/ObservedIceCandidate.d.ts +29 -0
  19. package/lib/ObservedIceCandidate.d.ts.map +1 -0
  20. package/lib/ObservedIceCandidate.js +59 -0
  21. package/lib/ObservedIceCandidatePair.d.ts +44 -0
  22. package/lib/ObservedIceCandidatePair.d.ts.map +1 -0
  23. package/lib/ObservedIceCandidatePair.js +111 -0
  24. package/lib/ObservedIceTransport.d.ts +32 -0
  25. package/lib/ObservedIceTransport.d.ts.map +1 -0
  26. package/lib/ObservedIceTransport.js +65 -0
  27. package/lib/ObservedInboundRtp.d.ts +92 -0
  28. package/lib/ObservedInboundRtp.d.ts.map +1 -0
  29. package/lib/ObservedInboundRtp.js +193 -0
  30. package/lib/ObservedInboundTrack.d.ts +29 -0
  31. package/lib/ObservedInboundTrack.d.ts.map +1 -0
  32. package/lib/ObservedInboundTrack.js +57 -0
  33. package/lib/ObservedMediaPlayout.d.ts +22 -0
  34. package/lib/ObservedMediaPlayout.d.ts.map +1 -0
  35. package/lib/ObservedMediaPlayout.js +42 -0
  36. package/lib/ObservedMediaSource.d.ts +28 -0
  37. package/lib/ObservedMediaSource.d.ts.map +1 -0
  38. package/lib/ObservedMediaSource.js +55 -0
  39. package/lib/ObservedOutboundRtp.d.ts +62 -0
  40. package/lib/ObservedOutboundRtp.d.ts.map +1 -0
  41. package/lib/ObservedOutboundRtp.js +144 -0
  42. package/lib/ObservedOutboundTrack.d.ts +29 -0
  43. package/lib/ObservedOutboundTrack.d.ts.map +1 -0
  44. package/lib/ObservedOutboundTrack.js +57 -0
  45. package/lib/ObservedPeerConnection.d.ts +128 -78
  46. package/lib/ObservedPeerConnection.d.ts.map +1 -1
  47. package/lib/ObservedPeerConnection.js +624 -357
  48. package/lib/ObservedPeerConnectionTransport.d.ts +17 -0
  49. package/lib/ObservedPeerConnectionTransport.d.ts.map +1 -0
  50. package/lib/ObservedPeerConnectionTransport.js +34 -0
  51. package/lib/ObservedRemoteInboundRtp.d.ts +30 -0
  52. package/lib/ObservedRemoteInboundRtp.d.ts.map +1 -0
  53. package/lib/ObservedRemoteInboundRtp.js +60 -0
  54. package/lib/ObservedRemoteOutboundRtp.d.ts +30 -0
  55. package/lib/ObservedRemoteOutboundRtp.d.ts.map +1 -0
  56. package/lib/ObservedRemoteOutboundRtp.js +60 -0
  57. package/lib/ObservedTURN.d.ts +31 -0
  58. package/lib/ObservedTURN.d.ts.map +1 -0
  59. package/lib/ObservedTURN.js +58 -0
  60. package/lib/ObservedTurnServer.d.ts +25 -0
  61. package/lib/ObservedTurnServer.d.ts.map +1 -0
  62. package/lib/ObservedTurnServer.js +59 -0
  63. package/lib/Observer.d.ts +31 -51
  64. package/lib/Observer.d.ts.map +1 -1
  65. package/lib/Observer.js +75 -229
  66. package/lib/common/Middleware.d.ts +10 -1
  67. package/lib/common/Middleware.d.ts.map +1 -1
  68. package/lib/common/Middleware.js +55 -36
  69. package/lib/common/logger.d.ts +8 -4
  70. package/lib/common/logger.d.ts.map +1 -1
  71. package/lib/common/logger.js +44 -68
  72. package/lib/common/types.d.ts +0 -21
  73. package/lib/common/types.d.ts.map +1 -1
  74. package/lib/common/types.js +1 -0
  75. package/lib/common/utils.d.ts +1 -0
  76. package/lib/common/utils.d.ts.map +1 -1
  77. package/lib/common/utils.js +13 -1
  78. package/lib/detectors/Detector.d.ts +5 -0
  79. package/lib/detectors/Detector.d.ts.map +1 -0
  80. package/lib/detectors/Detector.js +3 -0
  81. package/lib/detectors/Detectors.d.ts +11 -0
  82. package/lib/detectors/Detectors.d.ts.map +1 -0
  83. package/lib/detectors/Detectors.js +34 -0
  84. package/lib/index.d.ts +24 -25
  85. package/lib/index.d.ts.map +1 -1
  86. package/lib/index.js +41 -41
  87. package/lib/monitors/TurnUsageMonitor.d.ts +0 -52
  88. package/lib/monitors/TurnUsageMonitor.d.ts.map +1 -1
  89. package/lib/monitors/TurnUsageMonitor.js +145 -120
  90. package/lib/schema/ClientEventTypes.d.ts +33 -0
  91. package/lib/schema/ClientEventTypes.d.ts.map +1 -0
  92. package/lib/schema/ClientEventTypes.js +38 -0
  93. package/lib/schema/ClientMetaTypes.d.ts +34 -0
  94. package/lib/schema/ClientMetaTypes.d.ts.map +1 -0
  95. package/lib/schema/ClientMetaTypes.js +16 -0
  96. package/lib/schema/ClientSample.d.ts +1333 -0
  97. package/lib/schema/ClientSample.d.ts.map +1 -0
  98. package/lib/schema/ClientSample.js +4 -0
  99. package/lib/scores/CalculatedScore.d.ts +6 -0
  100. package/lib/scores/CalculatedScore.d.ts.map +1 -0
  101. package/lib/scores/DefaultCallScoreCalculator.d.ts +7 -0
  102. package/lib/scores/DefaultCallScoreCalculator.d.ts.map +1 -0
  103. package/lib/scores/DefaultCallScoreCalculator.js +21 -0
  104. package/lib/scores/ScoreCalculator.d.ts +4 -0
  105. package/lib/scores/ScoreCalculator.d.ts.map +1 -0
  106. package/lib/scores/ScoreCalculator.js +2 -0
  107. package/lib/utils/CallUpdater.d.ts +5 -0
  108. package/lib/utils/CallUpdater.d.ts.map +1 -0
  109. package/lib/utils/CallUpdater.js +2 -0
  110. package/lib/utils/OnAllClientCallUpdater.d.ts +16 -0
  111. package/lib/utils/OnAllClientCallUpdater.d.ts.map +1 -0
  112. package/lib/utils/OnAllClientCallUpdater.js +58 -0
  113. package/lib/utils/RemoteTrackResolver.d.ts +7 -0
  114. package/lib/utils/RemoteTrackResolver.d.ts.map +1 -0
  115. package/lib/utils/RemoteTrackResolver.js +2 -0
  116. package/lib/utils/onAnyClientCallUpdater.d.ts +14 -0
  117. package/lib/utils/onAnyClientCallUpdater.d.ts.map +1 -0
  118. package/lib/utils/onAnyClientCallUpdater.js +51 -0
  119. package/package.json +4 -4
  120. package/src/ObservedCall.ts +116 -166
  121. package/src/ObservedCertificate.ts +43 -0
  122. package/src/ObservedClient.ts +213 -1060
  123. package/src/ObservedCodec.ts +49 -0
  124. package/src/ObservedDataChannel.ts +68 -181
  125. package/src/ObservedIceCandidate.ts +64 -0
  126. package/src/ObservedIceCandidatePair.ts +118 -0
  127. package/src/ObservedIceTransport.ts +70 -0
  128. package/src/ObservedInboundRtp.ts +205 -0
  129. package/src/ObservedInboundTrack.ts +70 -0
  130. package/src/ObservedMediaPlayout.ts +49 -0
  131. package/src/ObservedMediaSource.ts +60 -0
  132. package/src/ObservedOutboundRtp.ts +156 -0
  133. package/src/ObservedOutboundTrack.ts +69 -0
  134. package/src/ObservedPeerConnection.ts +827 -405
  135. package/src/ObservedPeerConnectionTransport.ts +38 -0
  136. package/src/ObservedRemoteInboundRtp.ts +64 -0
  137. package/src/ObservedRemoteOutboundRtp.ts +65 -0
  138. package/src/ObservedTURN.ts +86 -0
  139. package/src/ObservedTurnServer.ts +72 -0
  140. package/src/Observer.ts +91 -302
  141. package/src/common/Middleware.ts +70 -42
  142. package/src/common/logger.ts +60 -69
  143. package/src/common/types.ts +0 -42
  144. package/src/common/utils.ts +12 -0
  145. package/src/detectors/Detector.ts +6 -0
  146. package/src/detectors/Detectors.ts +38 -0
  147. package/src/index.ts +24 -90
  148. package/src/monitors/TurnUsageMonitor.ts +164 -164
  149. package/src/schema/ClientEventTypes.ts +36 -0
  150. package/src/schema/ClientMetaTypes.ts +41 -0
  151. package/src/schema/ClientSample.ts +1682 -0
  152. package/src/scores/CalculatedScore.ts +6 -0
  153. package/src/scores/DefaultCallScoreCalculator.ts +23 -0
  154. package/src/scores/ScoreCalculator.ts +3 -0
  155. package/src/utils/CallUpdater.ts +5 -0
  156. package/src/utils/OnAllClientCallUpdater.ts +68 -0
  157. package/src/utils/RemoteTrackResolver.ts +12 -0
  158. package/src/utils/onAnyClientCallUpdater.ts +59 -0
  159. package/tsconfig.json +3 -3
  160. package/lib/ObservedICE.d.ts +0 -64
  161. package/lib/ObservedICE.d.ts.map +0 -1
  162. package/lib/ObservedICE.js +0 -141
  163. package/lib/ObservedInboundAudioTrack.d.ts +0 -96
  164. package/lib/ObservedInboundAudioTrack.d.ts.map +0 -1
  165. package/lib/ObservedInboundAudioTrack.js +0 -217
  166. package/lib/ObservedInboundVideoTrack.d.ts +0 -101
  167. package/lib/ObservedInboundVideoTrack.d.ts.map +0 -1
  168. package/lib/ObservedInboundVideoTrack.js +0 -232
  169. package/lib/ObservedOutboundAudioTrack.d.ts +0 -87
  170. package/lib/ObservedOutboundAudioTrack.d.ts.map +0 -1
  171. package/lib/ObservedOutboundAudioTrack.js +0 -186
  172. package/lib/ObservedOutboundVideoTrack.d.ts +0 -91
  173. package/lib/ObservedOutboundVideoTrack.d.ts.map +0 -1
  174. package/lib/ObservedOutboundVideoTrack.js +0 -193
  175. package/lib/ObservedSfu.d.ts +0 -59
  176. package/lib/ObservedSfu.d.ts.map +0 -1
  177. package/lib/ObservedSfu.js +0 -157
  178. package/lib/ObservedSfuInboundRtpPad.d.ts +0 -42
  179. package/lib/ObservedSfuInboundRtpPad.d.ts.map +0 -1
  180. package/lib/ObservedSfuInboundRtpPad.js +0 -71
  181. package/lib/ObservedSfuOutboundRtpPad.d.ts +0 -42
  182. package/lib/ObservedSfuOutboundRtpPad.d.ts.map +0 -1
  183. package/lib/ObservedSfuOutboundRtpPad.js +0 -72
  184. package/lib/ObservedSfuSctpChannel.d.ts +0 -42
  185. package/lib/ObservedSfuSctpChannel.d.ts.map +0 -1
  186. package/lib/ObservedSfuSctpChannel.js +0 -57
  187. package/lib/ObservedSfuTransport.d.ts +0 -58
  188. package/lib/ObservedSfuTransport.d.ts.map +0 -1
  189. package/lib/ObservedSfuTransport.js +0 -120
  190. package/lib/RemoteTrackAssigner.d.ts +0 -14
  191. package/lib/RemoteTrackAssigner.d.ts.map +0 -1
  192. package/lib/RemoteTrackAssigner.js +0 -52
  193. package/lib/ReportsCollector.d.ts +0 -109
  194. package/lib/ReportsCollector.d.ts.map +0 -1
  195. package/lib/ReportsCollector.js +0 -207
  196. package/lib/common/CalculatedScore.d.ts +0 -80
  197. package/lib/common/CalculatedScore.d.ts.map +0 -1
  198. package/lib/common/CalculatedScore.js +0 -162
  199. package/lib/common/CallEventType.d.ts +0 -63
  200. package/lib/common/CallEventType.d.ts.map +0 -1
  201. package/lib/common/CallEventType.js +0 -39
  202. package/lib/common/CallMetaReports.d.ts +0 -42
  203. package/lib/common/CallMetaReports.d.ts.map +0 -1
  204. package/lib/common/CallMetaReports.js +0 -36
  205. package/lib/common/QualityScoreUtils.d.ts +0 -1
  206. package/lib/common/QualityScoreUtils.d.ts.map +0 -1
  207. package/lib/common/QualityScoreUtils.js +0 -1
  208. package/lib/common/TypedEventEmitter.d.ts +0 -22
  209. package/lib/common/TypedEventEmitter.d.ts.map +0 -1
  210. package/lib/common/TypedEventEmitter.js +0 -11
  211. package/lib/common/callEventReports.d.ts +0 -10
  212. package/lib/common/callEventReports.d.ts.map +0 -1
  213. package/lib/common/callEventReports.js +0 -112
  214. package/lib/monitors/CallSummary.d.ts +0 -37
  215. package/lib/monitors/CallSummary.d.ts.map +0 -1
  216. package/lib/monitors/CallSummaryMonitor.d.ts +0 -32
  217. package/lib/monitors/CallSummaryMonitor.d.ts.map +0 -1
  218. package/lib/monitors/CallSummaryMonitor.js +0 -152
  219. package/lib/monitors/ClientIssueMonitor.d.ts +0 -32
  220. package/lib/monitors/ClientIssueMonitor.d.ts.map +0 -1
  221. package/lib/monitors/ClientIssueMonitor.js +0 -49
  222. package/lib/monitors/SfuServerMonitor.d.ts +0 -79
  223. package/lib/monitors/SfuServerMonitor.d.ts.map +0 -1
  224. package/lib/monitors/SfuServerMonitor.js +0 -198
  225. package/src/ObservedICE.ts +0 -237
  226. package/src/ObservedInboundAudioTrack.ts +0 -344
  227. package/src/ObservedInboundVideoTrack.ts +0 -361
  228. package/src/ObservedOutboundAudioTrack.ts +0 -307
  229. package/src/ObservedOutboundVideoTrack.ts +0 -319
  230. package/src/ObservedSfu.ts +0 -231
  231. package/src/ObservedSfuInboundRtpPad.ts +0 -106
  232. package/src/ObservedSfuOutboundRtpPad.ts +0 -107
  233. package/src/ObservedSfuSctpChannel.ts +0 -103
  234. package/src/ObservedSfuTransport.ts +0 -185
  235. package/src/RemoteTrackAssigner.ts +0 -68
  236. package/src/ReportsCollector.ts +0 -336
  237. package/src/common/CalculatedScore.ts +0 -188
  238. package/src/common/CallEventType.ts +0 -69
  239. package/src/common/CallMetaReports.ts +0 -82
  240. package/src/common/QualityScoreUtils.ts +0 -0
  241. package/src/common/TypedEventEmitter.ts +0 -32
  242. package/src/common/callEventReports.ts +0 -178
  243. package/src/monitors/CallSummary.ts +0 -38
  244. package/src/monitors/CallSummaryMonitor.ts +0 -192
  245. package/src/monitors/ClientIssueMonitor.ts +0 -88
  246. package/src/monitors/SfuServerMonitor.ts +0 -285
  247. /package/lib/{monitors/CallSummary.js → scores/CalculatedScore.js} +0 -0
package/src/Observer.ts CHANGED
@@ -1,48 +1,25 @@
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';
15
7
 
16
8
  const logger = createLogger('Observer');
17
9
 
18
10
  export type ObserverEvents = {
11
+ 'client-event': [ObservedClient, ClientEvent];
12
+ 'call-updated': [ObservedCall],
13
+ 'client-issue': [ObservedClient, ClientIssue],
14
+ 'client-metadata': [ObservedClient, ClientMetaData],
15
+ 'client-extension-stats': [ObservedClient, ExtensionStat],
19
16
  'newcall': [ObservedCall],
20
- 'newsfu': [ObservedSfu],
21
- 'reports': [ObserverSinkContext],
22
17
  'close': [],
23
18
  }
24
19
 
25
20
  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
- };
21
+ updateIntervalInMs?: number,
22
+ }
46
23
 
47
24
  export declare interface Observer {
48
25
  on<U extends keyof ObserverEvents>(event: U, listener: (...args: ObserverEvents[U]) => void): this;
@@ -51,313 +28,125 @@ export declare interface Observer {
51
28
  emit<U extends keyof ObserverEvents>(event: U, ...args: ObserverEvents[U]): boolean;
52
29
  }
53
30
 
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
- );
31
+ export type ObserverSummary = {
32
+ rttlt50: number;
33
+ }
69
34
 
70
- return new Observer(config);
35
+ export class Observer extends EventEmitter {
36
+ public readonly observedTURN = new ObservedTURN();
37
+ public readonly observedCalls = new Map<string, ObservedCall>();
38
+ public readonly config: ObserverConfig;
39
+
40
+ public closed = false;
41
+
42
+ public numberOfClients = 0;
43
+ public numberOfInboundRtpStreams = 0;
44
+ public numberOfOutboundRtpStreams = 0;
45
+ public numberOfDataChannels = 0;
46
+ public numberOfPeerConnections = 0;
47
+
48
+ public get numberOfCalls() {
49
+ return this.observedCalls.size;
71
50
  }
72
51
 
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 }>();
52
+ private _timer?: ReturnType<typeof setInterval>;
77
53
 
78
- private _reportTimer?: ReturnType<typeof setTimeout>;
79
- private _closed = false;
80
- public constructor(
81
- public readonly config: ObserverConfig,
82
- ) {
54
+ public constructor(config: ObserverConfig = {
55
+ updateIntervalInMs: 10000,
56
+ }) {
83
57
  super();
84
58
  this.setMaxListeners(Infinity);
59
+ this.config = config;
60
+ this.update = this.update.bind(this);
85
61
 
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();
93
- }
94
- };
95
-
96
- this._emitReports();
62
+ if (this.config.updateIntervalInMs) {
63
+ this._timer = setInterval(this.update.bind(this), this.config.updateIntervalInMs);
64
+ }
65
+ }
97
66
 
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);
67
+ public getObservedCall<T extends Record<string, unknown> = Record<string, unknown>>(callId: string): ObservedCall<T> | undefined {
68
+ if (this.closed || !this.observedCalls.has(callId)) return;
69
+
70
+ return this.observedCalls.get(callId) as ObservedCall<T>;
104
71
  }
105
72
 
106
73
  public createObservedCall<T extends Record<string, unknown> = Record<string, unknown>>(
107
- config: PartialBy<ObservedCallModel, 'serviceId'> & { appData: T, reportCallStarted?: boolean, reportCallEnded?: boolean }
74
+ settings: ObservedCallSettings<T>
108
75
  ): ObservedCall<T> {
109
- if (this._closed) {
76
+ if (this.closed) {
110
77
  throw new Error('Attempted to create a call source on a closed observer');
111
78
  }
112
79
 
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);
80
+ const observedCall = new ObservedCall(settings, this);
123
81
 
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`);
82
+ if (this.observedCalls.has(observedCall.callId)) throw new Error(`Observed Call with id ${observedCall.callId} already exists`);
126
83
 
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
- ));
84
+ observedCall.once('close', () => {
85
+ this.observedCalls.delete(observedCall.callId);
86
+ observedCall.off('update', this.update);
135
87
  });
136
88
 
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
- ));
89
+ this.observedCalls.set(observedCall.callId, observedCall);
90
+ observedCall.on('update', this.update);
144
91
 
145
- this.emit('newcall', call);
92
+ this.emit('newcall', observedCall);
146
93
 
147
- return call;
94
+ return observedCall;
148
95
  }
149
96
 
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');
97
+ public close() {
98
+ if (this.closed) {
99
+ return logger.debug('Attempted to close twice');
156
100
  }
157
-
158
- const sfu = new ObservedSfu<AppData>(model, this, appData);
159
-
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`);
162
-
163
- sfu.once('close', () => {
164
- this._observedSfus.delete(sfu.sfuId);
165
- });
166
-
167
- this._observedSfus.set(sfu.sfuId, sfu);
168
- this.emit('newsfu', sfu);
101
+ this.closed = true;
102
+ clearInterval(this._timer);
103
+ this._timer = undefined;
169
104
 
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);
105
+ this.observedCalls.forEach((call) => call.close());
177
106
 
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);
186
-
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);
199
-
200
- this.once('close', () => {
201
- monitor.close();
202
- });
203
-
204
- return monitor;
205
- }
206
-
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
- });
243
-
244
- this._monitors.set(TurnUsageMonitor.name, monitor);
245
- this.on('newcall', onNewCall);
246
-
247
- this.once('close', () => {
248
- monitor.close();
249
- });
250
-
251
- return monitor;
252
- }
253
-
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
- };
283
-
284
- monitor.once('close', () => {
285
- this._monitors.delete(SfuServerMonitor.name);
286
- this.off('newcall', onNewCall);
287
- });
288
-
289
- this._monitors.set(SfuServerMonitor.name, monitor);
290
- this.on('newcall', onNewCall);
291
-
292
- this.once('close', () => {
293
- monitor.close();
294
- });
295
-
296
- return monitor;
107
+ this.emit('close');
297
108
  }
298
109
 
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);
110
+ public accept(sample: ClientSample & { callId: string; clientId: string }) {
111
+ if (this.closed) return;
112
+ if (!sample.callId) return logger.warn('Received sample without callId. %o', sample);
113
+ if (!sample.clientId) return logger.warn('Received sample without clientId %o', sample);
309
114
 
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
- });
321
-
322
- return monitor;
323
- }
324
-
325
- public get observedCalls(): ReadonlyMap<string, ObservedCall> {
326
- return this._observedCalls;
327
- }
115
+ const call = this.getObservedCall(sample.callId);
328
116
 
329
- public get observedSfus(): ReadonlyMap<string, ObservedSfu> {
330
- return this._observedSfus;
331
- }
117
+ if (!call) {
118
+ return logger.warn(`Received sample for unknown call ${sample.callId}. %o`, sample);
119
+ }
332
120
 
333
- public get closed() {
334
- return this._closed;
335
- }
121
+ const client = call.getObservedClient(sample.clientId);
336
122
 
337
- public close() {
338
- if (this._closed) {
339
- return logger.debug('Attempted to close twice');
123
+ if (!client) {
124
+ return logger.warn(`Received sample for unknown client ${sample.clientId} in call ${sample.callId}. %o`, sample);
340
125
  }
341
- this._closed = true;
342
126
 
343
- this._observedCalls.forEach((call) => call.close());
344
-
345
- this.emit('close');
127
+ client.accept(sample);
346
128
  }
347
129
 
348
- private _emitReports() {
349
- if (this._reportTimer) {
350
- clearTimeout(this._reportTimer);
351
- this._reportTimer = undefined;
130
+ public update() {
131
+ if (this.closed) {
132
+ return;
352
133
  }
353
134
 
354
- this.reports.emit();
355
-
356
- if (this.config.maxCollectingTimeInMs) {
357
- this._reportTimer = setTimeout(() => {
358
- this._reportTimer = undefined;
359
- this._emitReports();
360
- }, this.config.maxCollectingTimeInMs);
135
+ this.numberOfInboundRtpStreams = 0;
136
+ this.numberOfOutboundRtpStreams = 0;
137
+ this.numberOfPeerConnections = 0;
138
+ this.numberOfDataChannels = 0;
139
+ this.numberOfClients = 0;
140
+
141
+ for (const call of this.observedCalls.values()) {
142
+ this.numberOfInboundRtpStreams += call.numberOfInboundRtpStreams;
143
+ this.numberOfOutboundRtpStreams += call.numberOfOutboundRtpStreams;
144
+ this.numberOfPeerConnections += call.numberOfPeerConnections;
145
+ this.numberOfDataChannels += call.numberOfDataChannels;
146
+ this.numberOfClients += call.numberOfClients;
361
147
  }
148
+
149
+ this.observedTURN.update();
362
150
  }
151
+
363
152
  }
@@ -1,56 +1,84 @@
1
1
  export type Middleware<T> = (
2
2
  input: T,
3
- next: (nextInput: T) => void,
3
+ next: (nextInput: T) => void
4
4
  ) => void;
5
5
 
6
6
  export interface Processor<T> {
7
+ finalCallback?: Callback<T>;
7
8
  process(value: T): void;
8
9
  addMiddleware(...middlewares: Middleware<T>[]): Processor<T>;
9
10
  removeMiddleware(...middlewares: Middleware<T>[]): Processor<T>;
10
11
  }
11
12
 
12
- export function createProcessor<T>(
13
- ): Processor<T> {
14
- const stack: Middleware<T>[] = [];
15
- const result: Processor<T> = {
16
- addMiddleware: (...middlewares: Middleware<T>[]) => {
17
- if (middlewares && 0 < middlewares.length) {
18
- stack.push(...middlewares);
19
- }
20
-
21
- return result;
22
- },
13
+ type Callback<T> = (input: T) => void;
14
+
15
+ class Executor<T> {
16
+ public done = false;
17
+ private index = 0;
18
+ private prevIndex = -1;
19
+
20
+ constructor(
21
+ private readonly stack: Middleware<T>[],
22
+ private readonly finalCallback?: Callback<T>
23
+ ) {
24
+ }
25
+
26
+ // Executes the middleware stack
27
+ public execute(input: T): void {
28
+ if (this.index <= this.prevIndex) {
29
+ throw new Error('Middleware must call next() only once!');
30
+ } else if (this.done) {
31
+ throw new Error('Middleware stack has already been executed!');
32
+ }
33
+
34
+ this.prevIndex = this.index;
35
+
36
+ const middleware = this.stack[this.index];
37
+
38
+ this.index++;
39
+
40
+ if (middleware) {
41
+ return middleware(input, (nextInput: T) => this.execute(nextInput));
42
+ }
43
+
44
+ this.done = true;
45
+ this.finalCallback?.(input);
46
+ }
47
+ }
48
+
49
+ export class MiddlewareProcessor<T> implements Processor<T> {
50
+ private stack: Middleware<T>[] = [];
51
+ public finalCallback?: Callback<T>;
52
+
53
+ public addMiddleware(...middlewares: Middleware<T>[]): Processor<T> {
54
+ if (middlewares && middlewares.length > 0) {
55
+ this.stack.push(...middlewares);
56
+ }
57
+
58
+ return this;
59
+ }
23
60
 
24
- removeMiddleware: (...middlewares: Middleware<T>[]) => {
25
- if (middlewares && 0 < middlewares.length) {
26
- for (const process of middlewares) {
27
- const index = stack.indexOf(process);
61
+ public removeMiddleware(...middlewares: Middleware<T>[]): Processor<T> {
62
+ if (middlewares && middlewares.length > 0) {
63
+ for (const middleware of middlewares) {
64
+ const index = this.stack.indexOf(middleware);
28
65
 
29
- if (0 < index) stack.splice(index, 1);
66
+ if (index >= 0) {
67
+ this.stack.splice(index, 1);
30
68
  }
31
69
  }
32
-
33
- return result;
34
- },
35
- process: (value: T) => {
36
- let prevIndex = -1;
37
- const execute = (index: number, input: T): void => {
38
- if (index <= prevIndex) {
39
- throw new Error('middleware must call next() only once!');
40
- }
41
- prevIndex = index;
42
- const middleware = stack[index];
43
-
44
- if (!middleware) return;
45
-
46
- const next = (nextInput: T) => execute(index + 1, nextInput);
47
-
48
- return middleware(input, next);
49
- };
50
-
51
- return execute(0, value);
52
- },
53
- };
54
-
55
- return result;
56
- }
70
+ }
71
+
72
+ return this;
73
+ }
74
+
75
+ public process(value: T): void {
76
+ if (this.stack.length === 0) {
77
+ return this.finalCallback?.(value);
78
+ }
79
+
80
+ const executor = new Executor(this.stack, this.finalCallback);
81
+
82
+ executor.execute(value);
83
+ }
84
+ }