@observertc/observer-js 0.42.9 → 1.0.1-23e88d8.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 (239) hide show
  1. package/.prettierrc +6 -6
  2. package/README.md +0 -104
  3. package/lib/ObservedCall.d.ts +25 -41
  4. package/lib/ObservedCall.d.ts.map +1 -1
  5. package/lib/ObservedCall.js +61 -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 +33 -143
  10. package/lib/ObservedClient.d.ts.map +1 -1
  11. package/lib/ObservedClient.js +156 -757
  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 +20 -70
  16. package/lib/ObservedDataChannel.d.ts.map +1 -1
  17. package/lib/ObservedDataChannel.js +39 -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 +40 -0
  22. package/lib/ObservedIceCandidatePair.d.ts.map +1 -0
  23. package/lib/ObservedIceCandidatePair.js +83 -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 +118 -78
  46. package/lib/ObservedPeerConnection.d.ts.map +1 -1
  47. package/lib/ObservedPeerConnection.js +556 -359
  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/Observer.d.ts +30 -53
  58. package/lib/Observer.d.ts.map +1 -1
  59. package/lib/Observer.js +52 -225
  60. package/lib/common/Middleware.d.ts +10 -1
  61. package/lib/common/Middleware.d.ts.map +1 -1
  62. package/lib/common/Middleware.js +55 -36
  63. package/lib/common/logger.d.ts +8 -4
  64. package/lib/common/logger.d.ts.map +1 -1
  65. package/lib/common/logger.js +44 -68
  66. package/lib/common/types.d.ts +0 -21
  67. package/lib/common/types.d.ts.map +1 -1
  68. package/lib/common/types.js +1 -0
  69. package/lib/common/utils.d.ts +1 -0
  70. package/lib/common/utils.d.ts.map +1 -1
  71. package/lib/common/utils.js +13 -1
  72. package/lib/detectors/Detector.d.ts +5 -0
  73. package/lib/detectors/Detector.d.ts.map +1 -0
  74. package/lib/detectors/Detector.js +3 -0
  75. package/lib/detectors/Detectors.d.ts +11 -0
  76. package/lib/detectors/Detectors.d.ts.map +1 -0
  77. package/lib/detectors/Detectors.js +34 -0
  78. package/lib/index.d.ts +23 -25
  79. package/lib/index.d.ts.map +1 -1
  80. package/lib/index.js +41 -41
  81. package/lib/monitors/TurnUsageMonitor.d.ts +0 -52
  82. package/lib/monitors/TurnUsageMonitor.d.ts.map +1 -1
  83. package/lib/monitors/TurnUsageMonitor.js +145 -120
  84. package/lib/schema/ClientEventTypes.d.ts +33 -0
  85. package/lib/schema/ClientEventTypes.d.ts.map +1 -0
  86. package/lib/schema/ClientEventTypes.js +38 -0
  87. package/lib/schema/ClientMetaTypes.d.ts +34 -0
  88. package/lib/schema/ClientMetaTypes.d.ts.map +1 -0
  89. package/lib/schema/ClientMetaTypes.js +16 -0
  90. package/lib/schema/ClientSample.d.ts +1333 -0
  91. package/lib/schema/ClientSample.d.ts.map +1 -0
  92. package/lib/schema/ClientSample.js +4 -0
  93. package/lib/scores/CalculatedScore.d.ts +6 -0
  94. package/lib/scores/CalculatedScore.d.ts.map +1 -0
  95. package/lib/scores/DefaultCallScoreCalculator.d.ts +7 -0
  96. package/lib/scores/DefaultCallScoreCalculator.d.ts.map +1 -0
  97. package/lib/scores/DefaultCallScoreCalculator.js +21 -0
  98. package/lib/scores/ScoreCalculator.d.ts +4 -0
  99. package/lib/scores/ScoreCalculator.d.ts.map +1 -0
  100. package/lib/scores/ScoreCalculator.js +2 -0
  101. package/lib/utils/CallUpdater.d.ts +5 -0
  102. package/lib/utils/CallUpdater.d.ts.map +1 -0
  103. package/lib/utils/CallUpdater.js +2 -0
  104. package/lib/utils/OnAllClientCallUpdater.d.ts +16 -0
  105. package/lib/utils/OnAllClientCallUpdater.d.ts.map +1 -0
  106. package/lib/utils/OnAllClientCallUpdater.js +58 -0
  107. package/lib/utils/RemoteTrackResolver.d.ts +7 -0
  108. package/lib/utils/RemoteTrackResolver.d.ts.map +1 -0
  109. package/lib/utils/RemoteTrackResolver.js +2 -0
  110. package/lib/utils/onAnyClientCallUpdater.d.ts +14 -0
  111. package/lib/utils/onAnyClientCallUpdater.d.ts.map +1 -0
  112. package/lib/utils/onAnyClientCallUpdater.js +51 -0
  113. package/package.json +4 -4
  114. package/src/ObservedCall.ts +74 -167
  115. package/src/ObservedCertificate.ts +43 -0
  116. package/src/ObservedClient.ts +173 -1085
  117. package/src/ObservedCodec.ts +49 -0
  118. package/src/ObservedDataChannel.ts +36 -178
  119. package/src/ObservedIceCandidate.ts +64 -0
  120. package/src/ObservedIceCandidatePair.ts +92 -0
  121. package/src/ObservedIceTransport.ts +70 -0
  122. package/src/ObservedInboundRtp.ts +205 -0
  123. package/src/ObservedInboundTrack.ts +70 -0
  124. package/src/ObservedMediaPlayout.ts +49 -0
  125. package/src/ObservedMediaSource.ts +60 -0
  126. package/src/ObservedOutboundRtp.ts +156 -0
  127. package/src/ObservedOutboundTrack.ts +69 -0
  128. package/src/ObservedPeerConnection.ts +743 -401
  129. package/src/ObservedPeerConnectionTransport.ts +38 -0
  130. package/src/ObservedRemoteInboundRtp.ts +64 -0
  131. package/src/ObservedRemoteOutboundRtp.ts +65 -0
  132. package/src/Observer.ts +65 -285
  133. package/src/common/Middleware.ts +70 -42
  134. package/src/common/logger.ts +60 -69
  135. package/src/common/types.ts +0 -42
  136. package/src/common/utils.ts +12 -0
  137. package/src/detectors/Detector.ts +6 -0
  138. package/src/detectors/Detectors.ts +38 -0
  139. package/src/index.ts +23 -90
  140. package/src/monitors/TurnUsageMonitor.ts +164 -164
  141. package/src/schema/ClientEventTypes.ts +36 -0
  142. package/src/schema/ClientMetaTypes.ts +41 -0
  143. package/src/schema/ClientSample.ts +1682 -0
  144. package/src/scores/CalculatedScore.ts +6 -0
  145. package/src/scores/DefaultCallScoreCalculator.ts +23 -0
  146. package/src/scores/ScoreCalculator.ts +3 -0
  147. package/src/utils/CallUpdater.ts +5 -0
  148. package/src/utils/OnAllClientCallUpdater.ts +68 -0
  149. package/src/utils/RemoteTrackResolver.ts +12 -0
  150. package/src/utils/onAnyClientCallUpdater.ts +59 -0
  151. package/tsconfig.json +3 -3
  152. package/lib/ObservedICE.d.ts +0 -64
  153. package/lib/ObservedICE.d.ts.map +0 -1
  154. package/lib/ObservedICE.js +0 -141
  155. package/lib/ObservedInboundAudioTrack.d.ts +0 -96
  156. package/lib/ObservedInboundAudioTrack.d.ts.map +0 -1
  157. package/lib/ObservedInboundAudioTrack.js +0 -217
  158. package/lib/ObservedInboundVideoTrack.d.ts +0 -101
  159. package/lib/ObservedInboundVideoTrack.d.ts.map +0 -1
  160. package/lib/ObservedInboundVideoTrack.js +0 -232
  161. package/lib/ObservedOutboundAudioTrack.d.ts +0 -87
  162. package/lib/ObservedOutboundAudioTrack.d.ts.map +0 -1
  163. package/lib/ObservedOutboundAudioTrack.js +0 -186
  164. package/lib/ObservedOutboundVideoTrack.d.ts +0 -91
  165. package/lib/ObservedOutboundVideoTrack.d.ts.map +0 -1
  166. package/lib/ObservedOutboundVideoTrack.js +0 -193
  167. package/lib/ObservedSfu.d.ts +0 -59
  168. package/lib/ObservedSfu.d.ts.map +0 -1
  169. package/lib/ObservedSfu.js +0 -157
  170. package/lib/ObservedSfuInboundRtpPad.d.ts +0 -42
  171. package/lib/ObservedSfuInboundRtpPad.d.ts.map +0 -1
  172. package/lib/ObservedSfuInboundRtpPad.js +0 -71
  173. package/lib/ObservedSfuOutboundRtpPad.d.ts +0 -42
  174. package/lib/ObservedSfuOutboundRtpPad.d.ts.map +0 -1
  175. package/lib/ObservedSfuOutboundRtpPad.js +0 -72
  176. package/lib/ObservedSfuSctpChannel.d.ts +0 -42
  177. package/lib/ObservedSfuSctpChannel.d.ts.map +0 -1
  178. package/lib/ObservedSfuSctpChannel.js +0 -57
  179. package/lib/ObservedSfuTransport.d.ts +0 -58
  180. package/lib/ObservedSfuTransport.d.ts.map +0 -1
  181. package/lib/ObservedSfuTransport.js +0 -120
  182. package/lib/RemoteTrackAssigner.d.ts +0 -14
  183. package/lib/RemoteTrackAssigner.d.ts.map +0 -1
  184. package/lib/RemoteTrackAssigner.js +0 -52
  185. package/lib/ReportsCollector.d.ts +0 -109
  186. package/lib/ReportsCollector.d.ts.map +0 -1
  187. package/lib/ReportsCollector.js +0 -207
  188. package/lib/common/CalculatedScore.d.ts +0 -80
  189. package/lib/common/CalculatedScore.d.ts.map +0 -1
  190. package/lib/common/CalculatedScore.js +0 -162
  191. package/lib/common/CallEventType.d.ts +0 -63
  192. package/lib/common/CallEventType.d.ts.map +0 -1
  193. package/lib/common/CallEventType.js +0 -39
  194. package/lib/common/CallMetaReports.d.ts +0 -42
  195. package/lib/common/CallMetaReports.d.ts.map +0 -1
  196. package/lib/common/CallMetaReports.js +0 -36
  197. package/lib/common/QualityScoreUtils.d.ts +0 -1
  198. package/lib/common/QualityScoreUtils.d.ts.map +0 -1
  199. package/lib/common/QualityScoreUtils.js +0 -1
  200. package/lib/common/TypedEventEmitter.d.ts +0 -22
  201. package/lib/common/TypedEventEmitter.d.ts.map +0 -1
  202. package/lib/common/TypedEventEmitter.js +0 -11
  203. package/lib/common/callEventReports.d.ts +0 -10
  204. package/lib/common/callEventReports.d.ts.map +0 -1
  205. package/lib/common/callEventReports.js +0 -112
  206. package/lib/monitors/CallSummary.d.ts +0 -37
  207. package/lib/monitors/CallSummary.d.ts.map +0 -1
  208. package/lib/monitors/CallSummaryMonitor.d.ts +0 -32
  209. package/lib/monitors/CallSummaryMonitor.d.ts.map +0 -1
  210. package/lib/monitors/CallSummaryMonitor.js +0 -152
  211. package/lib/monitors/ClientIssueMonitor.d.ts +0 -32
  212. package/lib/monitors/ClientIssueMonitor.d.ts.map +0 -1
  213. package/lib/monitors/ClientIssueMonitor.js +0 -49
  214. package/lib/monitors/SfuServerMonitor.d.ts +0 -79
  215. package/lib/monitors/SfuServerMonitor.d.ts.map +0 -1
  216. package/lib/monitors/SfuServerMonitor.js +0 -198
  217. package/src/ObservedICE.ts +0 -237
  218. package/src/ObservedInboundAudioTrack.ts +0 -344
  219. package/src/ObservedInboundVideoTrack.ts +0 -361
  220. package/src/ObservedOutboundAudioTrack.ts +0 -307
  221. package/src/ObservedOutboundVideoTrack.ts +0 -319
  222. package/src/ObservedSfu.ts +0 -231
  223. package/src/ObservedSfuInboundRtpPad.ts +0 -106
  224. package/src/ObservedSfuOutboundRtpPad.ts +0 -107
  225. package/src/ObservedSfuSctpChannel.ts +0 -103
  226. package/src/ObservedSfuTransport.ts +0 -185
  227. package/src/RemoteTrackAssigner.ts +0 -68
  228. package/src/ReportsCollector.ts +0 -336
  229. package/src/common/CalculatedScore.ts +0 -188
  230. package/src/common/CallEventType.ts +0 -69
  231. package/src/common/CallMetaReports.ts +0 -82
  232. package/src/common/QualityScoreUtils.ts +0 -0
  233. package/src/common/TypedEventEmitter.ts +0 -32
  234. package/src/common/callEventReports.ts +0 -178
  235. package/src/monitors/CallSummary.ts +0 -38
  236. package/src/monitors/CallSummaryMonitor.ts +0 -192
  237. package/src/monitors/ClientIssueMonitor.ts +0 -88
  238. package/src/monitors/SfuServerMonitor.ts +0 -285
  239. /package/lib/{monitors/CallSummary.js → scores/CalculatedScore.js} +0 -0
package/.prettierrc CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
- "tabWidth": 2,
3
- "useTabs": true,
4
- "trailingComma": "es5",
5
- "singleQuote": true,
6
- "printWidth": 120
7
- }
2
+ "tabWidth": 2,
3
+ "useTabs": true,
4
+ "trailingComma": "es5",
5
+ "singleQuote": true,
6
+ "printWidth": 120
7
+ }
package/README.md CHANGED
@@ -1,106 +1,2 @@
1
1
  Server side component for monitoring WebRTC applications and services
2
2
  ---
3
-
4
- Table of Contents:
5
-
6
- * [Quick Start](#quick-start)
7
- * [Configurations](#configurations)
8
- * [NPM package](#npm-package)
9
- * [Schemas](#schemas)
10
- * [License](#license)
11
-
12
- ## Qucik Start
13
-
14
- Install it from [npm](https://www.npmjs.com/package/@observertc/observer-js) package repository.
15
-
16
- ```
17
- npm i @observertc/observer-js
18
- ```
19
-
20
- Use it in your server side NodeJS app.
21
-
22
- ```javascript
23
- import { createObserver, ClientSample } from "@observertc/observer-js";
24
-
25
- const observer = createObserver({
26
- defaultServiceId: 'my-service-name',
27
- defaultMediaUnitId: 'my-reporting-component',
28
- });
29
-
30
- const observedCall = observer.createObservedCall({
31
- roomId: 'roomId',
32
- callId: 'room-session-id',
33
- });
34
-
35
- const observedClient = observedCall.createObservedClient({
36
- clientId: 'client-id',
37
- mediaUnitId: 'media-unit-id',
38
- });
39
-
40
- const clientSample: ClientSample; // Receive your samples, for example, from a WebSocket
41
-
42
- observedClient.accept(clientSample);
43
- ```
44
-
45
- The above example do as follows:
46
- 1. create an observer to evaluate samples from clients and sfus
47
- 2. create a client source object to accept client samples
48
- 3. add an evaluator process to evaluate ended calls
49
-
50
- ### Get a Summary of a call when it ends
51
-
52
- ```javascript
53
-
54
- const monitor = observer.createCallSummaryMonitor('summary', (summary) => {
55
- console.log('Call Summary', summary);
56
- });
57
- ```
58
-
59
- ### How Many Clients are using TURN?
60
-
61
- ```javascript
62
- const monitor = observer.createTurnUsageMonitor('turn', (turn) => {
63
- console.log('TURN', turn);
64
- });
65
-
66
- // at any point of time you can get the current state of the turn usage
67
-
68
- console.log('Currently ', monitor.clients.size, 'clients are using TURN');
69
-
70
- // you can get the incoming and outgoing bytes of the TURN server
71
- console.log(`${YOUR_TURN_SERVER_ADDRESS} usage:`, monitor.getUsage(YOUR_TURN_SERVER_ADDRESS));
72
-
73
- ```
74
-
75
- ### Monitor Calls and Clients as they updated
76
-
77
- ```javascript
78
- observer.on('newcall', (call) => {
79
- call.on('update', () => {
80
- console.log('Call Updated', call.callId);
81
- });
82
-
83
- call.on('newclient', (client) => {
84
-
85
- client.on('update', () => {
86
- console.log('Client Updated', client.clientId);
87
-
88
- console.log(`The avaialble incoming bitrate for the client ${client.clientId} is: ${client.availableIncomingBitrate}`)
89
- });
90
- })
91
- });
92
- ```
93
-
94
- ## NPM package
95
-
96
- https://www.npmjs.com/package/@observertc/observer-js
97
-
98
-
99
- ## Schemas
100
-
101
- https://github.com/observertc/schemas
102
-
103
-
104
- ## License
105
-
106
- Apache-2.0
@@ -1,23 +1,23 @@
1
1
  /// <reference types="node" />
2
2
  import { EventEmitter } from 'events';
3
- import { ObservedClient, ObservedClientModel } from './ObservedClient';
3
+ import { ObservedClient, ObservedClientSettings } from './ObservedClient';
4
4
  import { Observer } from './Observer';
5
- import { PartialBy } from './common/utils';
6
- import { CallEventReport } from '@observertc/report-schemas-js';
7
- import { ClientSample } from '@observertc/sample-schemas-js';
8
- import { ObservedOutboundAudioTrack } from './ObservedOutboundAudioTrack';
9
- import { ObservedOutboundVideoTrack } from './ObservedOutboundVideoTrack';
10
- import { CalculatedScore } from './common/CalculatedScore';
11
- export type ObservedCallModel = {
12
- serviceId: string;
13
- roomId: string;
5
+ import { ScoreCalculator } from './scores/ScoreCalculator';
6
+ import { CalculatedScore } from './scores/CalculatedScore';
7
+ import { Detectors } from './detectors/Detectors';
8
+ import { RemoteTrackResolver } from './utils/RemoteTrackResolver';
9
+ import { CallUpdater } from './utils/CallUpdater';
10
+ export type ObservedCallSettings<AppData extends Record<string, unknown> = Record<string, unknown>> = {
14
11
  callId: string;
12
+ appData?: AppData;
13
+ remoteTrackResolvePolicy?: 'p2p' | 'mediasoup-sfu';
14
+ callUpdaterPolicy?: 'onAnyClientUpdate' | 'onAllClientsUpdate';
15
15
  };
16
16
  export type ObservedCallEvents = {
17
17
  update: [];
18
18
  newclient: [ObservedClient];
19
- callevent: [Omit<CallEventReport, 'callId' | 'serviceId' | 'roomId'>];
20
19
  empty: [];
20
+ 'not-empty': [];
21
21
  close: [];
22
22
  };
23
23
  export declare interface ObservedCall {
@@ -27,39 +27,23 @@ export declare interface ObservedCall {
27
27
  emit<U extends keyof ObservedCallEvents>(event: U, ...args: ObservedCallEvents[U]): boolean;
28
28
  }
29
29
  export declare class ObservedCall<AppData extends Record<string, unknown> = Record<string, unknown>> extends EventEmitter {
30
- private readonly _model;
31
30
  readonly observer: Observer;
32
- readonly appData: AppData;
33
- readonly created: number;
34
- readonly processor: import("./common/Middleware").Processor<ClientSample>;
35
- private readonly _clients;
36
- _scoreData?: {
37
- score: CalculatedScore;
38
- calculated: number;
39
- };
40
- readonly sfuStreamIdToOutboundAudioTrack: Map<string | number, ObservedOutboundAudioTrack>;
41
- readonly sfuStreamIdToOutboundVideoTrack: Map<string | number, ObservedOutboundVideoTrack>;
42
- private _closed;
31
+ readonly detectors: Detectors;
32
+ readonly callId: string;
33
+ readonly observedClients: Map<string, ObservedClient<Record<string, unknown>>>;
34
+ readonly calculatedScore: CalculatedScore;
35
+ remoteTrackResolver?: RemoteTrackResolver;
36
+ callUpdater?: CallUpdater;
37
+ appData?: AppData;
38
+ closed: boolean;
43
39
  started?: number;
44
40
  ended?: number;
45
- observationUpdated: number;
46
- observationEnded?: number;
47
- readonly observationStarted: number;
48
- constructor(_model: ObservedCallModel, observer: Observer, appData: AppData);
49
- get serviceId(): string;
50
- get reports(): import("./ReportsCollector").ReportsCollector;
51
- get roomId(): string;
52
- get callId(): string;
53
- get clients(): ReadonlyMap<string, ObservedClient>;
54
- get score(): CalculatedScore | undefined;
55
- get closed(): boolean;
41
+ scoreCalculator: ScoreCalculator;
42
+ constructor(settings: ObservedCallSettings<AppData>, observer: Observer);
43
+ get score(): number | undefined;
56
44
  close(): void;
57
- addEventReport(params: PartialBy<Omit<CallEventReport, 'serviceId' | 'roomId' | 'callId'>, 'timestamp'>): void;
58
- createClient<ClientAppData extends Record<string, unknown> = Record<string, unknown>>(config: ObservedClientModel & {
59
- appData: ClientAppData;
60
- joinedTimestamp?: number;
61
- createClientJoinedReport?: boolean;
62
- createClientLeftReport?: boolean;
63
- }): ObservedClient<ClientAppData>;
45
+ getObservedClient<ClientAppData extends Record<string, unknown> = Record<string, unknown>>(clientId: string): ObservedClient<ClientAppData> | undefined;
46
+ createObservedClient<ClientAppData extends Record<string, unknown> = Record<string, unknown>>(settings: ObservedClientSettings<ClientAppData>): ObservedClient<ClientAppData>;
47
+ update(): void;
64
48
  }
65
49
  //# sourceMappingURL=ObservedCall.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ObservedCall.d.ts","sourceRoot":"","sources":["../src/ObservedCall.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ObservedCall.d.ts","sourceRoot":"","sources":["../src/ObservedCall.ts"],"names":[],"mappings":"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"}
@@ -1,139 +1,91 @@
1
1
  "use strict";
2
- var __rest = (this && this.__rest) || function (s, e) {
3
- var t = {};
4
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
- t[p] = s[p];
6
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
- t[p[i]] = s[p[i]];
10
- }
11
- return t;
12
- };
13
2
  Object.defineProperty(exports, "__esModule", { value: true });
14
3
  exports.ObservedCall = void 0;
15
4
  const events_1 = require("events");
16
5
  const ObservedClient_1 = require("./ObservedClient");
17
- const callEventReports_1 = require("./common/callEventReports");
18
- const utils_1 = require("./common/utils");
19
- const Middleware_1 = require("./common/Middleware");
6
+ const DefaultCallScoreCalculator_1 = require("./scores/DefaultCallScoreCalculator");
7
+ const Detectors_1 = require("./detectors/Detectors");
8
+ const OnAllClientCallUpdater_1 = require("./utils/OnAllClientCallUpdater");
9
+ const onAnyClientCallUpdater_1 = require("./utils/onAnyClientCallUpdater");
20
10
  class ObservedCall extends events_1.EventEmitter {
21
- constructor(_model, observer, appData) {
11
+ observer;
12
+ detectors;
13
+ callId;
14
+ observedClients = new Map();
15
+ calculatedScore = {
16
+ weight: 1,
17
+ value: undefined,
18
+ };
19
+ remoteTrackResolver;
20
+ callUpdater;
21
+ appData;
22
+ closed = false;
23
+ started;
24
+ ended;
25
+ scoreCalculator;
26
+ constructor(settings, observer) {
22
27
  super();
23
- this._model = _model;
24
28
  this.observer = observer;
25
- this.appData = appData;
26
- this.created = Date.now();
27
- this.processor = (0, Middleware_1.createProcessor)();
28
- this._clients = new Map();
29
- this.sfuStreamIdToOutboundAudioTrack = new Map();
30
- this.sfuStreamIdToOutboundVideoTrack = new Map();
31
- this._closed = false;
32
- this.observationUpdated = Date.now();
33
- this.observationStarted = Date.now();
34
29
  this.setMaxListeners(Infinity);
35
- }
36
- get serviceId() {
37
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
38
- return this._model.serviceId;
39
- }
40
- get reports() {
41
- return this.observer.reports;
42
- }
43
- get roomId() {
44
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
45
- return this._model.roomId;
46
- }
47
- get callId() {
48
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
49
- return this._model.callId;
50
- }
51
- get clients() {
52
- return this._clients;
53
- }
54
- get score() {
55
- var _a, _b, _c;
56
- const now = Date.now();
57
- if (now - 15000 < ((_b = (_a = this._scoreData) === null || _a === void 0 ? void 0 : _a.calculated) !== null && _b !== void 0 ? _b : 0)) {
58
- return (_c = this._scoreData) === null || _c === void 0 ? void 0 : _c.score;
30
+ this.callId = settings.callId;
31
+ this.appData = settings.appData;
32
+ this.scoreCalculator = new DefaultCallScoreCalculator_1.DefaultCallScoreCalculator(this);
33
+ this.detectors = new Detectors_1.Detectors();
34
+ switch (settings.callUpdaterPolicy) {
35
+ case 'onAllClientsUpdate':
36
+ this.callUpdater = new OnAllClientCallUpdater_1.OnAllClientCallUpdater(this);
37
+ break;
38
+ case 'onAnyClientUpdate':
39
+ this.callUpdater = new onAnyClientCallUpdater_1.OnAnyClientCallUpdater(this);
40
+ break;
59
41
  }
60
- else if (this.clients.size < 1) {
61
- return {
62
- remarks: [{
63
- severity: 'none',
64
- text: 'No clients',
65
- }],
66
- score: 5.0,
67
- timestamp: now,
68
- };
42
+ switch (settings.remoteTrackResolvePolicy) {
43
+ case 'mediasoup-sfu':
44
+ break;
69
45
  }
70
- const scores = [...this.clients.values()].map((client) => { var _a, _b; return (_b = (_a = client.score) === null || _a === void 0 ? void 0 : _a.score) !== null && _b !== void 0 ? _b : 5.0; });
71
- this._scoreData = {
72
- score: {
73
- remarks: [],
74
- score: (0, utils_1.getMedian)(scores),
75
- timestamp: now,
76
- },
77
- calculated: now,
78
- };
79
- return this._scoreData.score;
80
46
  }
81
- get closed() {
82
- return this._closed;
47
+ get score() {
48
+ return this.calculatedScore.value;
83
49
  }
84
50
  close() {
85
- if (this._closed)
51
+ if (this.closed)
86
52
  return;
87
- this._closed = true;
88
- Array.from(this._clients.values()).forEach((client) => client.close());
89
- this.observationEnded = Date.now();
53
+ this.closed = true;
54
+ [...this.observedClients.values()].forEach((client) => client.close());
90
55
  this.emit('close');
91
56
  }
92
- addEventReport(params) {
93
- var _a;
94
- this.reports.addCallEventReport(Object.assign(Object.assign({}, params), { serviceId: this.serviceId, roomId: this.roomId, callId: this.callId, timestamp: (_a = params.timestamp) !== null && _a !== void 0 ? _a : Date.now() }));
57
+ getObservedClient(clientId) {
58
+ if (this.closed || !this.observedClients.has(clientId))
59
+ return;
60
+ return this.observedClients.get(clientId);
95
61
  }
96
- createClient(config) {
97
- var _a;
98
- if (this._closed)
62
+ createObservedClient(settings) {
63
+ if (this.closed)
99
64
  throw new Error(`Call ${this.callId} is closed`);
100
- const { appData, createClientJoinedReport, createClientLeftReport, joinedTimestamp = Date.now() } = config, model = __rest(config, ["appData", "createClientJoinedReport", "createClientLeftReport", "joinedTimestamp"]);
101
- const result = new ObservedClient_1.ObservedClient(model, this, appData);
102
- const onUpdate = ({ sample }) => {
103
- this.observationUpdated = Date.now();
104
- if (result.joined) {
105
- if (this.started === undefined || result.joined < this.started) {
106
- this.started = result.joined;
107
- }
108
- }
109
- if (result.left) {
110
- if (this.ended === undefined || result.left > this.ended) {
111
- this.ended = result.left;
112
- }
113
- }
114
- this.emit('update');
115
- this.processor.process(sample);
116
- };
65
+ if (this.observedClients.has(settings.clientId))
66
+ throw new Error(`Client with id ${settings.clientId} already exists`);
67
+ const result = new ObservedClient_1.ObservedClient(settings, this);
68
+ const wasEmpty = this.observedClients.size === 0;
69
+ const onUpdate = () => this.callUpdater?.onClientUpdate(result);
117
70
  result.once('close', () => {
118
71
  result.off('update', onUpdate);
119
- this._clients.delete(result.clientId);
120
- if (this._clients.size === 0) {
72
+ this.observedClients.delete(settings.clientId);
73
+ if (this.observedClients.size === 0) {
121
74
  this.emit('empty');
122
75
  }
123
76
  });
124
77
  result.on('update', onUpdate);
125
- this._clients.set(result.clientId, result);
126
- if (createClientJoinedReport) {
127
- this.reports.addCallEventReport((0, callEventReports_1.createClientJoinedEventReport)(this.serviceId, result.mediaUnitId, this.roomId, this.callId, result.clientId, (_a = result.joined) !== null && _a !== void 0 ? _a : joinedTimestamp, result.userId, result.marker));
128
- }
129
- result.once('close', () => {
130
- var _a;
131
- if (createClientLeftReport) {
132
- this.reports.addCallEventReport((0, callEventReports_1.createClientLeftEventReport)(this.serviceId, result.mediaUnitId, this.roomId, this.callId, result.clientId, (_a = result.left) !== null && _a !== void 0 ? _a : Date.now(), result.userId, result.marker));
133
- }
134
- });
78
+ this.observedClients.set(settings.clientId, result);
135
79
  this.emit('newclient', result);
80
+ if (wasEmpty) {
81
+ this.emit('not-empty');
82
+ }
136
83
  return result;
137
84
  }
85
+ update() {
86
+ this.detectors.update();
87
+ this.scoreCalculator.update();
88
+ this.emit('update');
89
+ }
138
90
  }
139
91
  exports.ObservedCall = ObservedCall;
@@ -0,0 +1,19 @@
1
+ import { ObservedPeerConnection } from './ObservedPeerConnection';
2
+ import { CertificateStats } from './schema/ClientSample';
3
+ export declare class ObservedCertificate implements CertificateStats {
4
+ timestamp: number;
5
+ id: string;
6
+ private readonly _peerConnection;
7
+ appData?: Record<string, unknown>;
8
+ private _visited;
9
+ fingerprint?: string;
10
+ fingerprintAlgorithm?: string;
11
+ base64Certificate?: string;
12
+ issuerCertificateId?: string;
13
+ attachments?: Record<string, unknown>;
14
+ constructor(timestamp: number, id: string, _peerConnection: ObservedPeerConnection);
15
+ get visited(): boolean;
16
+ getPeerConnection(): ObservedPeerConnection;
17
+ update(stats: CertificateStats): void;
18
+ }
19
+ //# sourceMappingURL=ObservedCertificate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ObservedCertificate.d.ts","sourceRoot":"","sources":["../src/ObservedCertificate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,qBAAa,mBAAoB,YAAW,gBAAgB;IAYnD,SAAS,EAAE,MAAM;IACjB,EAAE,EAAE,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAb1B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEzC,OAAO,CAAC,QAAQ,CAAS;IAEzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAG9B,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACA,eAAe,EAAE,sBAAsB;IAGzD,IAAW,OAAO,YAMjB;IAEM,iBAAiB;IAIjB,MAAM,CAAC,KAAK,EAAE,gBAAgB;CAUrC"}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ObservedCertificate = void 0;
4
+ class ObservedCertificate {
5
+ timestamp;
6
+ id;
7
+ _peerConnection;
8
+ appData;
9
+ _visited = false;
10
+ fingerprint;
11
+ fingerprintAlgorithm;
12
+ base64Certificate;
13
+ issuerCertificateId;
14
+ attachments;
15
+ constructor(timestamp, id, _peerConnection) {
16
+ this.timestamp = timestamp;
17
+ this.id = id;
18
+ this._peerConnection = _peerConnection;
19
+ }
20
+ get visited() {
21
+ const visited = this._visited;
22
+ this._visited = false;
23
+ return visited;
24
+ }
25
+ getPeerConnection() {
26
+ return this._peerConnection;
27
+ }
28
+ update(stats) {
29
+ this._visited = true;
30
+ this.timestamp = stats.timestamp;
31
+ this.fingerprint = stats.fingerprint;
32
+ this.fingerprintAlgorithm = stats.fingerprintAlgorithm;
33
+ this.base64Certificate = stats.base64Certificate;
34
+ this.issuerCertificateId = stats.issuerCertificateId;
35
+ this.attachments = stats.attachments;
36
+ }
37
+ }
38
+ exports.ObservedCertificate = ObservedCertificate;