@observertc/observer-js 1.0.1-c3edea3.0 → 1.0.1-ec27289.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 (125) hide show
  1. package/lib/ObservedCall.d.ts +41 -7
  2. package/lib/ObservedCall.d.ts.map +1 -1
  3. package/lib/ObservedCall.js +125 -13
  4. package/lib/ObservedCallSummary.d.ts +18 -0
  5. package/lib/ObservedCallSummary.d.ts.map +1 -0
  6. package/lib/ObservedClient.d.ts +70 -11
  7. package/lib/ObservedClient.d.ts.map +1 -1
  8. package/lib/ObservedClient.js +394 -72
  9. package/lib/ObservedClientEventMonitor.d.ts +89 -0
  10. package/lib/ObservedClientEventMonitor.d.ts.map +1 -0
  11. package/lib/ObservedClientEventMonitor.js +247 -0
  12. package/lib/ObservedClientSummary.d.ts +23 -0
  13. package/lib/ObservedClientSummary.d.ts.map +1 -0
  14. package/lib/ObservedClientSummary.js +2 -0
  15. package/lib/ObservedDataChannel.d.ts +6 -0
  16. package/lib/ObservedDataChannel.d.ts.map +1 -1
  17. package/lib/ObservedDataChannel.js +30 -0
  18. package/lib/ObservedIceCandidatePair.d.ts +4 -0
  19. package/lib/ObservedIceCandidatePair.d.ts.map +1 -1
  20. package/lib/ObservedIceCandidatePair.js +28 -0
  21. package/lib/ObservedIceTransport.d.ts +4 -0
  22. package/lib/ObservedIceTransport.d.ts.map +1 -1
  23. package/lib/ObservedIceTransport.js +28 -0
  24. package/lib/ObservedInboundTrack.d.ts +2 -0
  25. package/lib/ObservedInboundTrack.d.ts.map +1 -1
  26. package/lib/ObservedInboundTrack.js +2 -0
  27. package/lib/ObservedOutboundTrack.d.ts +2 -0
  28. package/lib/ObservedOutboundTrack.d.ts.map +1 -1
  29. package/lib/ObservedOutboundTrack.js +2 -0
  30. package/lib/ObservedPeerConnection.d.ts +14 -2
  31. package/lib/ObservedPeerConnection.d.ts.map +1 -1
  32. package/lib/ObservedPeerConnection.js +106 -14
  33. package/lib/ObservedTURN.d.ts +31 -0
  34. package/lib/ObservedTURN.d.ts.map +1 -0
  35. package/lib/ObservedTURN.js +58 -0
  36. package/lib/ObservedTurnServer.d.ts +25 -0
  37. package/lib/ObservedTurnServer.d.ts.map +1 -0
  38. package/lib/ObservedTurnServer.js +59 -0
  39. package/lib/Observer.d.ts +38 -21
  40. package/lib/Observer.d.ts.map +1 -1
  41. package/lib/Observer.js +114 -40
  42. package/lib/ObserverSummary.d.ts +13 -0
  43. package/lib/ObserverSummary.d.ts.map +1 -0
  44. package/lib/ObserverSummary.js +2 -0
  45. package/lib/common/utils.d.ts +2 -1
  46. package/lib/common/utils.d.ts.map +1 -1
  47. package/lib/common/utils.js +11 -3
  48. package/lib/index.d.ts +5 -0
  49. package/lib/index.d.ts.map +1 -1
  50. package/lib/index.js +7 -1
  51. package/lib/schema/ClientEventTypes.d.ts +100 -0
  52. package/lib/schema/ClientEventTypes.d.ts.map +1 -0
  53. package/lib/schema/ClientEventTypes.js +38 -0
  54. package/lib/schema/{metaTypes.d.ts → ClientMetaTypes.d.ts} +2 -2
  55. package/lib/schema/ClientMetaTypes.d.ts.map +1 -0
  56. package/lib/schema/ClientMetaTypes.js +16 -0
  57. package/lib/updaters/CallUpdater.d.ts.map +1 -0
  58. package/lib/updaters/CallUpdater.js +2 -0
  59. package/lib/updaters/ObserverUpdater.d.ts +5 -0
  60. package/lib/updaters/ObserverUpdater.d.ts.map +1 -0
  61. package/lib/updaters/ObserverUpdater.js +2 -0
  62. package/lib/updaters/OnAllCallObserverUpdater_.d.ts +13 -0
  63. package/lib/updaters/OnAllCallObserverUpdater_.d.ts.map +1 -0
  64. package/lib/updaters/OnAllCallObserverUpdater_.js +38 -0
  65. package/lib/updaters/OnAllClientCallUpdater.d.ts +13 -0
  66. package/lib/updaters/OnAllClientCallUpdater.d.ts.map +1 -0
  67. package/lib/updaters/OnAllClientCallUpdater.js +37 -0
  68. package/lib/updaters/OnAnyCallObserverUpdater_.d.ts +11 -0
  69. package/lib/updaters/OnAnyCallObserverUpdater_.d.ts.map +1 -0
  70. package/lib/updaters/OnAnyCallObserverUpdater_.js +27 -0
  71. package/lib/updaters/OnAnyClientCallUpdater.d.ts +11 -0
  72. package/lib/updaters/OnAnyClientCallUpdater.d.ts.map +1 -0
  73. package/lib/updaters/OnAnyClientCallUpdater.js +27 -0
  74. package/lib/updaters/OnIntervalUpdater.d.ts +10 -0
  75. package/lib/updaters/OnIntervalUpdater.d.ts.map +1 -0
  76. package/lib/updaters/OnIntervalUpdater.js +17 -0
  77. package/lib/updaters/Updater.d.ts +6 -0
  78. package/lib/updaters/Updater.d.ts.map +1 -0
  79. package/lib/updaters/Updater.js +2 -0
  80. package/package.json +1 -1
  81. package/src/ObservedCall.ts +205 -16
  82. package/src/ObservedCallSummary.ts +22 -0
  83. package/src/ObservedClient.ts +492 -78
  84. package/src/ObservedClientEventMonitor.ts +301 -0
  85. package/src/ObservedClientSummary.ts +24 -0
  86. package/src/ObservedDataChannel.ts +32 -0
  87. package/src/ObservedIceCandidatePair.ts +26 -0
  88. package/src/ObservedIceTransport.ts +29 -0
  89. package/src/ObservedInboundTrack.ts +3 -0
  90. package/src/ObservedOutboundTrack.ts +3 -0
  91. package/src/ObservedPeerConnection.ts +120 -16
  92. package/src/ObservedTURN.ts +86 -0
  93. package/src/ObservedTurnServer.ts +72 -0
  94. package/src/Observer.ts +164 -64
  95. package/src/ObserverSummary.ts +15 -0
  96. package/src/common/utils.ts +12 -2
  97. package/src/index.ts +5 -0
  98. package/src/schema/ClientEventTypes.ts +112 -0
  99. package/src/schema/{metaTypes.ts → ClientMetaTypes.ts} +1 -1
  100. package/src/updaters/ObserverUpdater.ts +5 -0
  101. package/src/updaters/OnAllCallObserverUpdater_.ts +46 -0
  102. package/src/updaters/OnAllClientCallUpdater.ts +46 -0
  103. package/src/updaters/OnAnyCallObserverUpdater_.ts +32 -0
  104. package/src/updaters/OnAnyClientCallUpdater.ts +32 -0
  105. package/src/updaters/OnIntervalUpdater.ts +19 -0
  106. package/src/updaters/Updater.ts +5 -0
  107. package/tsconfig.json +1 -1
  108. package/lib/schema/eventTypes.d.ts +0 -33
  109. package/lib/schema/eventTypes.d.ts.map +0 -1
  110. package/lib/schema/eventTypes.js +0 -38
  111. package/lib/schema/metaTypes.d.ts.map +0 -1
  112. package/lib/schema/metaTypes.js +0 -16
  113. package/lib/utils/CallUpdater.d.ts.map +0 -1
  114. package/lib/utils/OnAllClientCallUpdater.d.ts +0 -16
  115. package/lib/utils/OnAllClientCallUpdater.d.ts.map +0 -1
  116. package/lib/utils/OnAllClientCallUpdater.js +0 -58
  117. package/lib/utils/onAnyClientCallUpdater.d.ts +0 -14
  118. package/lib/utils/onAnyClientCallUpdater.d.ts.map +0 -1
  119. package/lib/utils/onAnyClientCallUpdater.js +0 -51
  120. package/src/schema/eventTypes.ts +0 -36
  121. package/src/utils/OnAllClientCallUpdater.ts +0 -68
  122. package/src/utils/onAnyClientCallUpdater.ts +0 -59
  123. /package/lib/{utils/CallUpdater.js → ObservedCallSummary.js} +0 -0
  124. /package/lib/{utils → updaters}/CallUpdater.d.ts +0 -0
  125. /package/src/{utils → updaters}/CallUpdater.ts +0 -0
package/src/Observer.ts CHANGED
@@ -1,21 +1,33 @@
1
1
  import { createLogger } from './common/logger';
2
- import { Middleware, MiddlewareProcessor } from './common/Middleware';
3
2
  import { ObservedCall, ObservedCallSettings } from './ObservedCall';
4
3
  import { EventEmitter } from 'events';
5
- import { ClientEvent, ClientMetaData, ClientIssue, ExtensionStat } from './schema/ClientSample';
4
+ import { ClientEvent, ClientMetaData, ClientIssue, ExtensionStat, ClientSample } from './schema/ClientSample';
6
5
  import { ObservedClient } from './ObservedClient';
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_';
7
12
 
8
13
  const logger = createLogger('Observer');
9
14
 
10
15
  export type ObserverEvents = {
16
+ 'client-event': [ObservedClient, ClientEvent];
17
+ 'call-updated': [ObservedCall],
18
+ 'client-issue': [ObservedClient, ClientIssue],
19
+ 'client-metadata': [ObservedClient, ClientMetaData],
20
+ 'client-extension-stats': [ObservedClient, ExtensionStat],
11
21
  'newcall': [ObservedCall],
22
+ 'update': [],
12
23
  'close': [],
13
24
  }
14
25
 
15
- export type ProcessorInputContext<T> = {
16
- call: ObservedCall;
17
- client: ObservedClient;
18
- data: T;
26
+ export type ObserverConfig = {
27
+ updatePolicy?: 'update-on-any-call-updated' | 'update-when-all-call-updated' | 'update-on-interval',
28
+ updateIntervalInMs?: number,
29
+ defaultCallUpdatePolicy?: ObservedCallSettings['updatePolicy'],
30
+ defaultCallUpdateIntervalInMs?: number,
19
31
  }
20
32
 
21
33
  export declare interface Observer {
@@ -26,20 +38,74 @@ export declare interface Observer {
26
38
  }
27
39
 
28
40
  export class Observer extends EventEmitter {
29
- public readonly processors = {
30
- events: new MiddlewareProcessor<ProcessorInputContext<ClientEvent>>(),
31
- metaData: new MiddlewareProcessor<ProcessorInputContext<ClientMetaData>>(),
32
- issues: new MiddlewareProcessor<ProcessorInputContext<ClientIssue>>(),
33
- extensionStats: new MiddlewareProcessor<ProcessorInputContext<ExtensionStat>>(),
34
- };
41
+ public readonly detectors: Detectors;
35
42
 
43
+ public readonly observedTURN = new ObservedTURN();
36
44
  public readonly observedCalls = new Map<string, ObservedCall>();
45
+ public updater?: Updater;
46
+
37
47
  public closed = false;
38
48
 
39
- public constructor(
40
- ) {
49
+ public totalAddedCall = 0;
50
+ public totalRemovedCall = 0;
51
+ public totalRttLt50Measurements = 0;
52
+ public totalRttLt150Measurements = 0;
53
+ public totalRttLt300Measurements = 0;
54
+ public totalRttGtOrEq300Measurements = 0;
55
+ public totalClientIssues = 0;
56
+
57
+ public numberOfClientsUsingTurn = 0;
58
+ public numberOfClients = 0;
59
+ public numberOfInboundRtpStreams = 0;
60
+ public numberOfOutboundRtpStreams = 0;
61
+ public numberOfDataChannels = 0;
62
+ public numberOfPeerConnections = 0;
63
+
64
+ public get numberOfCalls() {
65
+ return this.observedCalls.size;
66
+ }
67
+
68
+ private _timer?: ReturnType<typeof setInterval>;
69
+
70
+ public constructor(public readonly config: ObserverConfig = {
71
+ updatePolicy: 'update-when-all-call-updated',
72
+ updateIntervalInMs: undefined,
73
+ }) {
41
74
  super();
42
75
  this.setMaxListeners(Infinity);
76
+ this.update = this.update.bind(this);
77
+
78
+ if (this.config.updateIntervalInMs) {
79
+ if (this.config.updatePolicy && this.config.updatePolicy !== 'update-on-interval') {
80
+ throw new Error('update policy must be update-on-interval if updateIntervalInMs is set in config');
81
+ }
82
+ this._timer = setInterval(this.update.bind(this), this.config.updateIntervalInMs);
83
+ }
84
+
85
+ if (this.config.updateIntervalInMs) {
86
+ if (this.config.updatePolicy !== 'update-on-interval') {
87
+ throw new Error('updatePolicy must be update-on-interval if updateIntervalInMs is set in config');
88
+ }
89
+ }
90
+ switch (this.config.updatePolicy) {
91
+ case 'update-on-any-call-updated':
92
+ this.updater = new OnAllCallObserverUpdater(this);
93
+ break;
94
+ case 'update-when-all-call-updated':
95
+ this.updater = new OnAnyCallObserverUpdater(this);
96
+ break;
97
+ case 'update-on-interval':
98
+ if (!this.config.updateIntervalInMs) {
99
+ throw new Error('updateIntervalInMs setting in config must be set if updatePolicy is update-on-interval');
100
+ }
101
+ this.updater = new OnIntervalUpdater(
102
+ this.config.updateIntervalInMs,
103
+ this.update.bind(this),
104
+ );
105
+ break;
106
+ }
107
+
108
+ this.detectors = new Detectors();
43
109
  }
44
110
 
45
111
  public getObservedCall<T extends Record<string, unknown> = Record<string, unknown>>(callId: string): ObservedCall<T> | undefined {
@@ -54,86 +120,120 @@ export class Observer extends EventEmitter {
54
120
  if (this.closed) {
55
121
  throw new Error('Attempted to create a call source on a closed observer');
56
122
  }
123
+ if (!settings.updatePolicy) {
124
+ settings.updatePolicy = this.config.defaultCallUpdatePolicy;
125
+ settings.updateIntervalInMs = this.config.defaultCallUpdateIntervalInMs;
126
+ }
57
127
 
58
128
  const observedCall = new ObservedCall(settings, this);
129
+ const onCallUpdated = () => this._onObservedCallUpdated(observedCall);
59
130
 
60
131
  if (this.observedCalls.has(observedCall.callId)) throw new Error(`Observed Call with id ${observedCall.callId} already exists`);
61
132
 
62
133
  observedCall.once('close', () => {
63
134
  this.observedCalls.delete(observedCall.callId);
135
+ observedCall.off('update', onCallUpdated);
136
+ ++this.totalRemovedCall;
64
137
  });
65
138
 
66
139
  this.observedCalls.set(observedCall.callId, observedCall);
140
+ observedCall.on('update', onCallUpdated);
141
+ ++this.totalAddedCall;
67
142
 
68
143
  this.emit('newcall', observedCall);
69
144
 
70
145
  return observedCall;
71
146
  }
72
147
 
73
- public addClientEventMiddleware(...middlewares: Middleware<ProcessorInputContext<ClientEvent>>[]): Observer {
74
-
75
- this.processors.events.addMiddleware(...middlewares);
76
-
77
- return this;
78
- }
79
-
80
- public removeClientEventMiddleware(...middlewares: Middleware<ProcessorInputContext<ClientEvent>>[]): Observer {
81
-
82
- this.processors.events.removeMiddleware(...middlewares);
83
-
84
- return this;
85
- }
86
-
87
- public addClientMetaDataMiddleware(...middlewares: Middleware<ProcessorInputContext<ClientMetaData>>[]): Observer {
88
-
89
- this.processors.metaData.addMiddleware(...middlewares);
148
+ public close() {
149
+ if (this.closed) {
150
+ return logger.debug('Attempted to close twice');
151
+ }
152
+ this.closed = true;
153
+ clearInterval(this._timer);
154
+ this._timer = undefined;
90
155
 
91
- return this;
156
+ this.observedCalls.forEach((call) => call.close());
157
+
158
+ this.emit('close');
92
159
  }
93
160
 
94
- public removeClientMetaDataMiddleware(...middlewares: Middleware<ProcessorInputContext<ClientMetaData>>[]): Observer {
95
-
96
- this.processors.metaData.removeMiddleware(...middlewares);
161
+ public accept(sample: ClientSample) {
162
+ if (this.closed) return;
163
+ if (!sample.callId) return logger.warn('Received sample without callId. %o', sample);
164
+ if (!sample.clientId) return logger.warn('Received sample without clientId %o', sample);
97
165
 
98
- return this;
99
- }
100
-
101
- public addClientIssueMiddleware(...middlewares: Middleware<ProcessorInputContext<ClientIssue>>[]): Observer {
166
+ const call = this.getObservedCall(sample.callId) ?? this.createObservedCall({
167
+ callId: sample.callId,
168
+ updateIntervalInMs: this.config.defaultCallUpdateIntervalInMs,
169
+ updatePolicy: this.config.defaultCallUpdatePolicy,
170
+ });
102
171
 
103
- this.processors.issues.addMiddleware(...middlewares);
172
+ const client = call.getObservedClient(sample.clientId) ?? call.createObservedClient({
173
+ clientId: sample.clientId,
174
+ });
104
175
 
105
- return this;
176
+ client.accept(sample);
106
177
  }
107
178
 
108
- public removeClientIssueMiddleware(...middlewares: Middleware<ProcessorInputContext<ClientIssue>>[]): Observer {
109
-
110
- this.processors.issues.removeMiddleware(...middlewares);
111
-
112
- return this;
113
- }
179
+ public update() {
180
+ if (this.closed) {
181
+ return;
182
+ }
114
183
 
115
- public addExtensionStatMiddleware(...middlewares: Middleware<ProcessorInputContext<ExtensionStat>>[]): Observer {
184
+ this.numberOfInboundRtpStreams = 0;
185
+ this.numberOfOutboundRtpStreams = 0;
186
+ this.numberOfPeerConnections = 0;
187
+ this.numberOfDataChannels = 0;
188
+ this.numberOfClients = 0;
189
+ this.numberOfClientsUsingTurn = 0;
190
+
191
+ for (const call of this.observedCalls.values()) {
192
+ this.numberOfInboundRtpStreams += call.numberOfInboundRtpStreams;
193
+ this.numberOfOutboundRtpStreams += call.numberOfOutboundRtpStreams;
194
+ this.numberOfPeerConnections += call.numberOfPeerConnections;
195
+ this.numberOfDataChannels += call.numberOfDataChannels;
196
+ this.numberOfClients += call.numberOfClients;
197
+ this.numberOfClientsUsingTurn += call.clientsUsedTurn.size;
198
+ }
116
199
 
117
- this.processors.extensionStats.addMiddleware(...middlewares);
200
+ this.observedTURN.update();
118
201
 
119
- return this;
202
+ this.emit('update');
120
203
  }
121
204
 
122
- public removeExtensionStatMiddleware(...middlewares: Middleware<ProcessorInputContext<ExtensionStat>>[]): Observer {
123
-
124
- this.processors.extensionStats.removeMiddleware(...middlewares);
125
-
126
- return this;
205
+ private _onObservedCallUpdated(call: ObservedCall) {
206
+ this.totalRttLt50Measurements += call.deltaRttLt50Measurements;
207
+ this.totalRttLt150Measurements += call.deltaRttLt150Measurements;
208
+ this.totalRttLt300Measurements += call.deltaRttLt300Measurements;
209
+ this.totalRttGtOrEq300Measurements += call.deltaRttGtOrEq300Measurements;
210
+ this.totalClientIssues += call.deltaNumberOfIssues;
127
211
  }
128
212
 
129
- public close() {
130
- if (this.closed) {
131
- return logger.debug('Attempted to close twice');
132
- }
133
- this.closed = true;
213
+ // public resetSummaryMetrics() {
214
+ // this.totalAddedCall = 0;
215
+ // this.totalRemovedCall = 0;
216
+ // this.totalRttLt50Measurements = 0;
217
+ // this.totalRttLt150Measurements = 0;
218
+ // this.totalRttLt300Measurements = 0;
219
+ // this.totalRttGtOrEq300Measurements = 0;
220
+ // this.totalClientIssues = 0;
221
+ // }
222
+
223
+ // public createSummary(): ObserverSummary {
224
+ // return {
225
+ // totalAddedCall: this.totalAddedCall,
226
+ // totalRemovedCall: this.totalRemovedCall,
227
+ // totalRttLt50Measurements: this.totalRttLt50Measurements,
228
+ // totalRttLt150Measurements: this.totalRttLt150Measurements,
229
+ // totalRttLt300Measurements: this.totalRttLt300Measurements,
230
+ // totalRttGtOrEq300Measurements: this.totalRttGtOrEq300Measurements,
231
+
232
+ // totalClientIssues: this.totalClientIssues,
233
+ // currentActiveCalls: this.observedCalls.size,
234
+ // currentNumberOfClients: this.numberOfClients,
235
+ // currentNumberOfClientsUsingTURN: this.numberOfClientsUsedTurn,
236
+ // };
237
+ // }
134
238
 
135
- this.observedCalls.forEach((call) => call.close());
136
-
137
- this.emit('close');
138
- }
139
239
  }
@@ -0,0 +1,15 @@
1
+ export type ObserverSummary = {
2
+ currentActiveCalls: number;
3
+ currentNumberOfClientsUsingTURN: number;
4
+ currentNumberOfClients: number;
5
+
6
+ totalAddedCall: number;
7
+ totalRemovedCall: number;
8
+
9
+ totalRttLt50Measurements: number,
10
+ totalRttLt150Measurements: number,
11
+ totalRttLt300Measurements: number,
12
+ totalRttGtOrEq300Measurements: number,
13
+
14
+ totalClientIssues: number,
15
+ }
@@ -30,9 +30,19 @@ export function isValidUuid(str: string): boolean {
30
30
  return regexp.test(str);
31
31
  }
32
32
 
33
- export function getMedian(arr: number[]): number {
33
+ export function getAverage(arr: number[], defaultAvgIfArrLengthIs0 = 0): number {
34
+ if (arr.length === 0) return defaultAvgIfArrLengthIs0;
35
+
36
+ return arr.reduce((a, b) => a + b, 0) / arr.length;
37
+ }
38
+
39
+ export function getMedian(arr: number[], copyArrayForSorting = true): number {
34
40
  // Sort the array in ascending order
35
- const sortedArr = arr.slice().sort((a, b) => a - b);
41
+ const sortedArr = copyArrayForSorting
42
+ ? arr.slice().sort((a, b) => a - b)
43
+ : arr.sort((a, b) => a-b)
44
+
45
+ ;
36
46
 
37
47
  // Calculate the middle index
38
48
  const mid = Math.floor(sortedArr.length / 2);
package/src/index.ts CHANGED
@@ -19,5 +19,10 @@ export { ObservedIceCandidatePair } from './ObservedIceCandidatePair';
19
19
  export { ObservedIceCandidate } from './ObservedIceCandidate';
20
20
  export { ObservedIceTransport } from './ObservedIceTransport';
21
21
  export { ObservedPeerConnectionTransport } from './ObservedPeerConnectionTransport';
22
+ export { ClientEventTypes } from './schema/ClientEventTypes';
23
+ export { ClientMetaTypes } from './schema/ClientMetaTypes';
24
+ export { ClientSample } from './schema/ClientSample';
25
+ export { ScoreCalculator } from './scores/ScoreCalculator';
26
+ export { ObservedClientEventMonitor } from './ObservedClientEventMonitor';
22
27
 
23
28
  export { Middleware } from './common/Middleware';
@@ -0,0 +1,112 @@
1
+ /* eslint-disable no-shadow */
2
+
3
+ export enum ClientEventTypes {
4
+ CLIENT_JOINED = 'CLIENT_JOINED',
5
+ CLIENT_LEFT = 'CLIENT_LEFT',
6
+ PEER_CONNECTION_OPENED = 'PEER_CONNECTION_OPENED',
7
+ PEER_CONNECTION_CLOSED = 'PEER_CONNECTION_CLOSED',
8
+ MEDIA_TRACK_ADDED = 'MEDIA_TRACK_ADDED',
9
+ MEDIA_TRACK_REMOVED = 'MEDIA_TRACK_REMOVED',
10
+ MEDIA_TRACK_RESUMED = 'MEDIA_TRACK_RESUMED',
11
+ MEDIA_TRACK_MUTED = 'MEDIA_TRACK_MUTED',
12
+ MEDIA_TRACK_UNMUTED = 'MEDIA_TRACK_UNMUTED',
13
+ ICE_GATHERING_STATE_CHANGED = 'ICE_GATHERING_STATE_CHANGED',
14
+ PEER_CONNECTION_STATE_CHANGED = 'PEER_CONNECTION_STATE_CHANGED',
15
+ ICE_CONNECTION_STATE_CHANGED = 'ICE_CONNECTION_STATE_CHANGED',
16
+ DATA_CHANNEL_OPEN = 'DATA_CHANNEL_OPEN',
17
+ DATA_CHANNEL_CLOSED = 'DATA_CHANNEL_CLOSED',
18
+ DATA_CHANNEL_ERROR = 'DATA_CHANNEL_ERROR',
19
+ NEGOTIATION_NEEDED = 'NEGOTIATION_NEEDED',
20
+ SIGNALING_STATE_CHANGE = 'SIGNALING_STATE_CHANGE',
21
+ ICE_GATHERING_STATE_CHANGE = 'ICE_GATHERING_STATE_CHANGE',
22
+ ICE_CONNECTION_STATE_CHANGE = 'ICE_CONNECTION_STATE_CHANGE',
23
+ ICE_CANDIDATE = 'ICE_CANDIDATE',
24
+
25
+ // mediasoup events
26
+ PRODUCER_ADDED = 'PRODUCER_ADDED',
27
+ PRODUCER_REMOVED = 'PRODUCER_REMOVED',
28
+ PRODUCER_PAUSED = 'PRODUCER_PAUSED',
29
+ PRODUCER_RESUMED = 'PRODUCER_RESUMED',
30
+ CONSUMER_ADDED = 'CONSUMER_ADDED',
31
+ CONSUMER_REMOVED = 'CONSUMER_REMOVED',
32
+ DATA_PRODUCER_CREATED = 'DATA_PRODUCER_CREATED',
33
+ DATA_PRODUCER_CLOSED = 'DATA_PRODUCER_CLOSED',
34
+ DATA_CONSUMER_CREATED = 'DATA_CONSUMER_CREATED',
35
+ DATA_CONSUMER_CLOSED = 'DATA_CONSUMER_CLOSED',
36
+ }
37
+
38
+ export interface PeerConnectionOpenedEventPayload extends Record<string, unknown> {
39
+ peerConnectionId: string;
40
+ iceConnectionState: string;
41
+ iceGatheringState: string;
42
+ signalingState: string;
43
+ }
44
+
45
+ export interface PeerConnectionClosedEventPayload extends Record<string, unknown> {
46
+ peerConnectionId: string;
47
+ iceConnectionState: string;
48
+ iceGatheringState: string;
49
+ signalingState: string;
50
+ }
51
+
52
+ export interface MediaTrackMutedEventPayload extends Record<string, unknown> {
53
+ trackId: string;
54
+ kind: 'audio' | 'video';
55
+ label?: string;
56
+ muted: boolean;
57
+ enabled: boolean;
58
+ readyState: string;
59
+ contentHint?: string;
60
+ }
61
+
62
+ export interface MediaTrackUnmutedEventPayload extends Record<string, unknown> {
63
+ trackId: string;
64
+ kind: 'audio' | 'video';
65
+ label?: string;
66
+ muted: boolean;
67
+ enabled: boolean;
68
+ readyState: string;
69
+ contentHint?: string;
70
+ }
71
+
72
+ export interface MediaTrackAddedEventPayload extends Record<string, unknown> {
73
+ trackId: string;
74
+ kind: 'audio' | 'video';
75
+ label?: string;
76
+ muted: boolean;
77
+ enabled: boolean;
78
+ readyState: string;
79
+ contentHint?: string;
80
+ constraints: MediaTrackConstraints,
81
+ capabilities: MediaTrackCapabilities,
82
+ settings: MediaTrackSettings,
83
+ }
84
+
85
+ export interface MediaTrackRemovedEventPayload extends Record<string, unknown> {
86
+ trackId: string;
87
+ kind: 'audio' | 'video';
88
+ label?: string;
89
+ muted: boolean;
90
+ enabled: boolean;
91
+ readyState: string;
92
+ contentHint?: string;
93
+ }
94
+
95
+ export interface DataChannelErrorEventPayload extends Record<string, unknown> {
96
+ label: string;
97
+ readyState: string;
98
+ dataChannelId: string,
99
+ error: string,
100
+ }
101
+
102
+ export interface DataChannelOpenEventPayload extends Record<string, unknown> {
103
+ label: string;
104
+ readyState: string;
105
+ dataChannelId: string,
106
+ }
107
+
108
+ export interface DataChannelClosedEventPayload extends Record<string, unknown> {
109
+ label: string;
110
+ readyState: string;
111
+ dataChannelId: string,
112
+ }
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable no-shadow */
2
2
 
3
- export enum ClientMetaType {
3
+ export enum ClientMetaTypes {
4
4
  MEDIA_CONSTRAINT = 'MEDIA_CONSTRAINT',
5
5
  MEDIA_DEVICE = 'MEDIA_DEVICE',
6
6
  MEDIA_DEVICES_SUPPORTED_CONSTRAINTS = 'MEDIA_DEVICES_SUPPORTED_CONSTRAINTS',
@@ -0,0 +1,5 @@
1
+ import { ObservedCall } from '../ObservedCall';
2
+
3
+ export interface ObserverUpdater {
4
+ onCallUpdate(observedCall: ObservedCall): void;
5
+ }
@@ -0,0 +1,46 @@
1
+ import { ObservedCall } from '../ObservedCall';
2
+ import { Observer } from '../Observer';
3
+ import { Updater } from './Updater';
4
+
5
+ export class OnAllCallObserverUpdater implements Updater {
6
+ public readonly name = 'OnAllCallObserverUpdater';
7
+ public readonly description = 'Call Observer\'s update() method when all of the ObservedCalls are updated';
8
+
9
+ private readonly _updatedCalls = new Set<string>();
10
+
11
+ public constructor(
12
+ private observer: Observer
13
+ ) {
14
+ this._onNewObservedCall = this._onNewObservedCall.bind(this);
15
+
16
+ this.observer.once('close', () => {
17
+ this.observer.off('newcall', this._onNewObservedCall);
18
+ });
19
+ this.observer.on('newcall', this._onNewObservedCall);
20
+ }
21
+
22
+ close(): void {
23
+ // do nothing, because we unsubscribe once close is emitted from observer
24
+ }
25
+
26
+ private _onNewObservedCall(observedCall: ObservedCall) {
27
+ const onUpdate = () => this._onObservedCallUpdated(observedCall);
28
+
29
+ observedCall.once('close', () => {
30
+ observedCall.off('update', onUpdate);
31
+ this._updatedCalls.delete(observedCall.callId);
32
+ });
33
+ observedCall.on('update', onUpdate);
34
+ }
35
+
36
+ private _onObservedCallUpdated(observedCall: ObservedCall) {
37
+ if (observedCall.closed) return;
38
+
39
+ this._updatedCalls.add(observedCall.callId);
40
+
41
+ if (this._updatedCalls.size < this.observer.observedCalls.size) return;
42
+
43
+ this._updatedCalls.clear();
44
+ this.observer.update();
45
+ }
46
+ }
@@ -0,0 +1,46 @@
1
+ import { ObservedCall } from '../ObservedCall';
2
+ import { ObservedClient } from '../ObservedClient';
3
+ import { Updater } from './Updater';
4
+
5
+ export class OnAllClientCallUpdater implements Updater {
6
+ readonly name = 'OnAllClientCallUpdater';
7
+ readonly description = 'Call the update() method of the ObservedCall once all client has been updated';
8
+
9
+ private readonly _updatedClients = new Set<string>();
10
+
11
+ public constructor(
12
+ private _observedCall: ObservedCall
13
+ ) {
14
+ this._onNewObservedClient = this._onNewObservedClient.bind(this);
15
+
16
+ this._observedCall.once('close', () => {
17
+ this._observedCall.off('newclient', this._onNewObservedClient);
18
+ });
19
+ this._observedCall.on('newclient', this._onNewObservedClient);
20
+ }
21
+
22
+ public close(): void {
23
+ // do nothing, as close once emitted unsubscription happened
24
+ }
25
+
26
+ private _onNewObservedClient(observedClient: ObservedClient) {
27
+ const onUpdate = () => this._onClientUpdate(observedClient);
28
+
29
+ observedClient.once('close', () => {
30
+ observedClient.off('update', onUpdate);
31
+ this._updatedClients.delete(observedClient.clientId);
32
+ });
33
+ observedClient.on('update', onUpdate);
34
+ }
35
+
36
+ private _onClientUpdate(observedClient: ObservedClient) {
37
+ this._updatedClients.add(observedClient.clientId);
38
+
39
+ if (this._updatedClients.size < this._observedCall.observedClients.size) {
40
+ return;
41
+ }
42
+ this._updatedClients.clear();
43
+ this._observedCall.update();
44
+ }
45
+
46
+ }
@@ -0,0 +1,32 @@
1
+ import { ObservedCall } from '../ObservedCall';
2
+ import { Observer } from '../Observer';
3
+ import { Updater } from './Updater';
4
+
5
+ export class OnAnyCallObserverUpdater implements Updater {
6
+ public readonly name = 'OnAnyCallObserverUpdater';
7
+ public readonly description = 'Call Observer\'s update() method on any of the ObservedCall is updated';
8
+
9
+ public constructor(
10
+ private observver: Observer
11
+ ) {
12
+ this._onNewObservedCall = this._onNewObservedCall.bind(this);
13
+
14
+ this.observver.once('close', () => {
15
+ this.observver.off('newcall', this._onNewObservedCall);
16
+ });
17
+ this.observver.on('newcall', this._onNewObservedCall);
18
+ }
19
+
20
+ close(): void {
21
+ // do nothing, because we unsubscribe once close is emitted from observer
22
+ }
23
+
24
+ private _onNewObservedCall(observedCall: ObservedCall) {
25
+ const onUpdate = () => this.observver.update();
26
+
27
+ observedCall.once('close', () => {
28
+ observedCall.off('update', onUpdate);
29
+ });
30
+ observedCall.on('update', onUpdate);
31
+ }
32
+ }
@@ -0,0 +1,32 @@
1
+ import { ObservedCall } from '../ObservedCall';
2
+ import { ObservedClient } from '../ObservedClient';
3
+ import { Updater } from './Updater';
4
+
5
+ export class OnAnyClientCallUpdater implements Updater {
6
+ readonly name = 'OnAnyClientCallUpdater';
7
+ readonly description = 'Call the update() method of the ObservedCall when any of the client has been updated';
8
+
9
+ public constructor(
10
+ private _observedCall: ObservedCall
11
+ ) {
12
+ this._onNewObservedClient = this._onNewObservedClient.bind(this);
13
+
14
+ this._observedCall.once('close', () => {
15
+ this._observedCall.off('newclient', this._onNewObservedClient);
16
+ });
17
+ this._observedCall.on('newclient', this._onNewObservedClient);
18
+ }
19
+
20
+ public close(): void {
21
+ // do nothing, as close once emitted unsubscription happened
22
+ }
23
+
24
+ private _onNewObservedClient(observedClient: ObservedClient) {
25
+ const onUpdate = () => this._observedCall.update();
26
+
27
+ observedClient.once('close', () => {
28
+ observedClient.off('update', onUpdate);
29
+ });
30
+ observedClient.on('update', onUpdate);
31
+ }
32
+ }
@@ -0,0 +1,19 @@
1
+ import { Updater } from './Updater';
2
+
3
+ export class OnIntervalUpdater implements Updater {
4
+ readonly name = 'OnIntervalUpdater';
5
+ readonly description = 'Call the update() method given in the constructor once the interval elapsed';
6
+
7
+ public timer: ReturnType<typeof setInterval>;
8
+
9
+ public constructor(
10
+ intervalInMs: number,
11
+ private readonly _update: () => void,
12
+ ) {
13
+ this.timer = setInterval(() => this._update(), intervalInMs);
14
+ }
15
+
16
+ public close(): void {
17
+ clearInterval(this.timer);
18
+ }
19
+ }
@@ -0,0 +1,5 @@
1
+ export interface Updater {
2
+ readonly name: string;
3
+ readonly description?: string;
4
+ close(): void;
5
+ }
package/tsconfig.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "compileOnSave": true,
3
3
  "compilerOptions":
4
4
  {
5
- "lib": [ "ES2020" ],
5
+ "lib": [ "ES2020", "dom" ],
6
6
  "target": "ESNext",
7
7
  "module": "CommonJS",
8
8
  "moduleResolution": "node",