@observertc/observer-js 0.30.6-beta → 0.40.1-beta

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 (59) hide show
  1. package/lib/ObservedCall.d.ts +6 -12
  2. package/lib/ObservedCall.d.ts.map +1 -1
  3. package/lib/ObservedCall.js +24 -104
  4. package/lib/ObservedClient.d.ts +16 -32
  5. package/lib/ObservedClient.d.ts.map +1 -1
  6. package/lib/ObservedClient.js +381 -521
  7. package/lib/ObservedDataChannel.d.ts +68 -0
  8. package/lib/ObservedDataChannel.d.ts.map +1 -0
  9. package/lib/ObservedDataChannel.js +110 -0
  10. package/lib/ObservedInboundTrack.d.ts +3 -9
  11. package/lib/ObservedInboundTrack.d.ts.map +1 -1
  12. package/lib/ObservedInboundTrack.js +75 -157
  13. package/lib/ObservedOutboundTrack.d.ts +9 -9
  14. package/lib/ObservedOutboundTrack.d.ts.map +1 -1
  15. package/lib/ObservedOutboundTrack.js +77 -133
  16. package/lib/ObservedPeerConnection.d.ts +21 -15
  17. package/lib/ObservedPeerConnection.d.ts.map +1 -1
  18. package/lib/ObservedPeerConnection.js +85 -171
  19. package/lib/ObservedSfu.d.ts +5 -7
  20. package/lib/ObservedSfu.d.ts.map +1 -1
  21. package/lib/ObservedSfu.js +10 -74
  22. package/lib/Observer.d.ts +5 -6
  23. package/lib/Observer.d.ts.map +1 -1
  24. package/lib/Observer.js +28 -31
  25. package/lib/common/types.d.ts +0 -55
  26. package/lib/common/types.d.ts.map +1 -1
  27. package/lib/index.d.ts +5 -7
  28. package/lib/index.d.ts.map +1 -1
  29. package/package.json +1 -1
  30. package/src/ObservedCall.ts +27 -87
  31. package/src/ObservedClient.ts +451 -586
  32. package/src/ObservedDataChannel.ts +186 -0
  33. package/src/ObservedInboundTrack.ts +18 -72
  34. package/src/ObservedOutboundTrack.ts +36 -60
  35. package/src/ObservedPeerConnection.ts +79 -112
  36. package/src/ObservedSfu.ts +11 -46
  37. package/src/Observer.ts +11 -16
  38. package/src/common/types.ts +0 -69
  39. package/src/index.ts +5 -7
  40. package/lib/models/Models.d.ts +0 -642
  41. package/lib/models/Models.d.ts.map +0 -1
  42. package/lib/models/Models.js +0 -481
  43. package/lib/models/samples_pb.d.ts +0 -2452
  44. package/lib/models/samples_pb.d.ts.map +0 -1
  45. package/lib/models/samples_pb.js +0 -1495
  46. package/lib/storages/ObserverStorage.d.ts +0 -87
  47. package/lib/storages/ObserverStorage.d.ts.map +0 -1
  48. package/lib/storages/ObserverStorage.js +0 -2
  49. package/lib/storages/SimpleStorage.d.ts +0 -19
  50. package/lib/storages/SimpleStorage.d.ts.map +0 -1
  51. package/lib/storages/SimpleStorage.js +0 -106
  52. package/lib/storages/StorageProvider.d.ts +0 -16
  53. package/lib/storages/StorageProvider.d.ts.map +0 -1
  54. package/lib/storages/StorageProvider.js +0 -29
  55. package/src/models/Models.ts +0 -1103
  56. package/src/models/samples_pb.ts +0 -4061
  57. package/src/storages/ObserverStorage.ts +0 -99
  58. package/src/storages/SimpleStorage.ts +0 -120
  59. package/src/storages/StorageProvider.ts +0 -42
@@ -0,0 +1,186 @@
1
+ import { EventEmitter } from 'events';
2
+ import { ObservedPeerConnection } from './ObservedPeerConnection';
3
+ import { DataChannel } from '@observertc/sample-schemas-js';
4
+ import { ClientDataChannelReport } from '@observertc/report-schemas-js';
5
+
6
+ export type ObservedDataChannelState = 'connecting' | 'open' | 'closing' | 'closed';
7
+
8
+ export type ObservedDataChannelModel = {
9
+ channelId: number;
10
+ }
11
+
12
+ export type ObservedDataChannelEvents = {
13
+ update: [],
14
+ close: [],
15
+ };
16
+
17
+ export type ObservedInboundTrackStats = {
18
+ ssrc: number;
19
+ bitrate: number;
20
+ fractionLost: number;
21
+ rttInMs?: number;
22
+ lostPackets?: number;
23
+ receivedPackets?: number;
24
+ receivedFrames?: number;
25
+ decodedFrames?: number;
26
+ droppedFrames?: number;
27
+ receivedSamples?: number;
28
+ silentConcealedSamples?: number;
29
+ fractionLoss?: number;
30
+ };
31
+
32
+ // {
33
+ // [Property in keyof ObservedInboundTrackStats<K>]: ObservedInboundTrackStats<K>[Property];
34
+ // }
35
+
36
+ export declare interface ObservedDataChannel {
37
+ on<U extends keyof ObservedDataChannelEvents>(event: U, listener: (...args: ObservedDataChannelEvents[U]) => void): this;
38
+ off<U extends keyof ObservedDataChannelEvents>(event: U, listener: (...args: ObservedDataChannelEvents[U]) => void): this;
39
+ once<U extends keyof ObservedDataChannelEvents>(event: U, listener: (...args: ObservedDataChannelEvents[U]) => void): this;
40
+ emit<U extends keyof ObservedDataChannelEvents>(event: U, ...args: ObservedDataChannelEvents[U]): boolean;
41
+ update(sample: DataChannel, timestamp: number): void;
42
+ }
43
+
44
+ export class ObservedDataChannel extends EventEmitter {
45
+ public readonly created = Date.now();
46
+
47
+ private _stats?: DataChannel;
48
+
49
+ private _closed = false;
50
+ private _updated = Date.now();
51
+ public bitrate = 0;
52
+
53
+ public totalReceivedMessages = 0;
54
+ public totalSentMessages = 0;
55
+ public totalBytesReceived = 0;
56
+ public totalBytesSent = 0;
57
+
58
+ public deltaReceivedMessages = 0;
59
+ public deltaSentMessages = 0;
60
+ public deltaBytesReceived = 0;
61
+ public deltaBytesSent = 0;
62
+
63
+ public constructor(
64
+ private readonly _model: ObservedDataChannelModel,
65
+ public readonly peerConnection: ObservedPeerConnection,
66
+ ) {
67
+ super();
68
+ }
69
+
70
+ public get serviceId() {
71
+ return this.peerConnection.serviceId;
72
+ }
73
+
74
+ public get roomId() {
75
+ return this.peerConnection.roomId;
76
+ }
77
+
78
+ public get callId() {
79
+ return this.peerConnection.callId;
80
+ }
81
+
82
+ public get clientId() {
83
+ return this.peerConnection.clientId;
84
+ }
85
+
86
+ public get mediaUnitId() {
87
+ return this.peerConnection.mediaUnitId;
88
+ }
89
+
90
+ public get peerConnectionId() {
91
+ return this.peerConnection.peerConnectionId;
92
+ }
93
+
94
+ public get channelId() {
95
+ return this._model.channelId;
96
+ }
97
+
98
+ public get updated() {
99
+ return this._updated;
100
+ }
101
+
102
+ public get state(): ObservedDataChannelState | undefined {
103
+ return this._stats?.state as ObservedDataChannelState | undefined;
104
+ }
105
+
106
+ public get label() {
107
+ return this._stats?.label;
108
+ }
109
+
110
+ public get protocol() {
111
+ return this._stats?.protocol;
112
+ }
113
+
114
+ public get reports() {
115
+ return this.peerConnection.reports;
116
+ }
117
+
118
+ public get stats() {
119
+ return this._stats;
120
+ }
121
+
122
+ public get closed() {
123
+ return this._closed;
124
+ }
125
+
126
+ public close() {
127
+ if (this._closed) return;
128
+
129
+ this._closed = true;
130
+
131
+ this.emit('close');
132
+ }
133
+
134
+ public resetMetrics() {
135
+ this.bitrate = 0;
136
+ this.totalReceivedMessages = 0;
137
+ this.totalSentMessages = 0;
138
+ this.totalBytesReceived = 0;
139
+ this.totalBytesSent = 0;
140
+ this.deltaReceivedMessages = 0;
141
+ this.deltaSentMessages = 0;
142
+ this.deltaBytesReceived = 0;
143
+ }
144
+
145
+ public update(sample: DataChannel, timestamp: number) {
146
+ if (this._closed) return;
147
+
148
+ const now = Date.now();
149
+
150
+ const report: ClientDataChannelReport = {
151
+ serviceId: this.peerConnection.client.call.serviceId,
152
+ roomId: this.peerConnection.client.call.roomId,
153
+ callId: this.peerConnection.client.call.callId,
154
+ clientId: this.peerConnection.client.clientId,
155
+ userId: this.peerConnection.client.userId,
156
+ mediaUnitId: this.peerConnection.client.mediaUnitId,
157
+ ...sample,
158
+ timestamp,
159
+ sampleSeq: -1,
160
+ };
161
+
162
+ this.reports.addClientDataChannelReport(report);
163
+
164
+ sample.bytesReceived;
165
+ sample.bytesSent;
166
+ sample.messageReceived;
167
+ sample.messageSent;
168
+
169
+ const elapsedTimeInMs = Math.max(1, now - this._updated);
170
+
171
+ this.bitrate = ((sample.bytesReceived ?? 0) - (this._stats?.bytesReceived ?? 0)) * 8 / (elapsedTimeInMs / 1000);
172
+ this.deltaSentMessages = (sample.messageSent ?? 0) - (this._stats?.messageSent ?? 0);
173
+ this.deltaReceivedMessages = (sample.messageReceived ?? 0) - (this._stats?.messageReceived ?? 0);
174
+ this.deltaBytesSent = (sample.bytesSent ?? 0) - (this._stats?.bytesSent ?? 0);
175
+ this.deltaBytesReceived = (sample.bytesReceived ?? 0) - (this._stats?.bytesReceived ?? 0);
176
+
177
+ this.totalBytesReceived = sample.bytesReceived ?? 0;
178
+ this.totalBytesSent = sample.bytesSent ?? 0;
179
+ this.totalReceivedMessages = sample.messageReceived ?? 0;
180
+ this.totalSentMessages = sample.messageSent ?? 0;
181
+
182
+ this._stats = sample;
183
+ this._updated = timestamp;
184
+ this.emit('update');
185
+ }
186
+ }
@@ -1,14 +1,11 @@
1
1
  import { EventEmitter } from 'events';
2
- import { StorageProvider } from './storages/StorageProvider';
3
- import * as Models from './models/Models';
4
2
  import { ObservedPeerConnection } from './ObservedPeerConnection';
5
3
  import { InboundAudioTrack, InboundVideoTrack } from '@observertc/sample-schemas-js';
6
4
  import { ObservedOutboundTrack } from './ObservedOutboundTrack';
7
5
  import { InboundAudioTrackReport, InboundVideoTrackReport } from '@observertc/report-schemas-js';
8
6
  import { MediaKind } from './common/types';
9
- import { createSingleExecutor } from './common/SingleExecutor';
10
7
 
11
- export type ObservedInboundTrackConfig<K extends MediaKind> = {
8
+ export type ObservedInboundTrackModel<K extends MediaKind> = {
12
9
  trackId: string;
13
10
  kind: K;
14
11
  sfuStreamId?: string;
@@ -51,35 +48,9 @@ export declare interface ObservedInboundTrack<Kind extends MediaKind> {
51
48
  }
52
49
 
53
50
  export class ObservedInboundTrack<Kind extends MediaKind> extends EventEmitter {
54
- public static async create<K extends MediaKind>(
55
- config: ObservedInboundTrackConfig<K>,
56
- peerConnection: ObservedPeerConnection,
57
- storageProvider: StorageProvider,
58
- ) {
59
- const model = new Models.InboundTrack({
60
- serviceId: peerConnection.client.serviceId,
61
- roomId: peerConnection.client.roomId,
62
- callId: peerConnection.client.callId,
63
- clientId: peerConnection.client.clientId,
64
- mediaUnitId: peerConnection.client.mediaUnitId,
65
- peerConnectionId: peerConnection.peerConnectionId,
66
- trackId: config.trackId,
67
- kind: config.kind,
68
- sfuStreamId: config.sfuStreamId,
69
- sfuSinkId: config.sfuSinkId,
70
- });
71
-
72
- const alreadyInserted = await storageProvider.inboundTrackStorage.insert(config.trackId, model);
73
-
74
- if (alreadyInserted) throw new Error(`InboundAudioTrack with id ${config.trackId} already exists`);
75
-
76
- return new ObservedInboundTrack<K>(model, peerConnection, storageProvider);
77
- }
78
-
79
- public created = Date.now();
51
+ public readonly created = Date.now();
80
52
 
81
53
  private readonly _stats = new Map<number, ObservedInboundTrackStats<Kind>>();
82
- private readonly _execute = createSingleExecutor();
83
54
 
84
55
  private _closed = false;
85
56
  private _updated = Date.now();
@@ -106,52 +77,43 @@ export class ObservedInboundTrack<Kind extends MediaKind> extends EventEmitter {
106
77
  public deltaReceivedSamples = 0;
107
78
  public deltaSilentConcealedSamples = 0;
108
79
 
109
- private constructor(
110
- private readonly _model: Models.InboundTrack,
80
+ public constructor(
81
+ private readonly _model: ObservedInboundTrackModel<Kind>,
111
82
  public readonly peerConnection: ObservedPeerConnection,
112
- private readonly _storageProvider: StorageProvider,
113
83
  ) {
114
84
  super();
115
85
  }
116
86
 
117
87
  public get serviceId() {
118
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
119
- return this._model.serviceId!;
88
+ return this.peerConnection.serviceId;
120
89
  }
121
90
 
122
91
  public get roomId() {
123
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
124
- return this._model.roomId!;
92
+ return this.peerConnection.roomId;
125
93
  }
126
94
 
127
95
  public get callId() {
128
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
129
- return this._model.callId!;
96
+ return this.peerConnection.callId;
130
97
  }
131
98
 
132
99
  public get clientId() {
133
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
134
- return this._model.clientId!;
100
+ return this.peerConnection.clientId;
135
101
  }
136
102
 
137
103
  public get mediaUnitId() {
138
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
139
- return this._model.mediaUnitId!;
104
+ return this.peerConnection.mediaUnitId;
140
105
  }
141
106
 
142
107
  public get peerConnectionId() {
143
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
144
- return this._model.peerConnectionId!;
108
+ return this.peerConnection.peerConnectionId;
145
109
  }
146
110
 
147
111
  public get trackId() {
148
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
149
- return this._model.trackId!;
112
+ return this._model.trackId;
150
113
  }
151
114
 
152
115
  public get kind(): Kind {
153
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
154
- return this._model.kind! as Kind;
116
+ return this._model.kind as Kind;
155
117
  }
156
118
 
157
119
  public get sfuStreamId() {
@@ -174,10 +136,6 @@ export class ObservedInboundTrack<Kind extends MediaKind> extends EventEmitter {
174
136
  return this.peerConnection.reports;
175
137
  }
176
138
 
177
- public get uptimeInMs() {
178
- return this._updated - this.created;
179
- }
180
-
181
139
  public set remoteOutboundTrack(track: ObservedOutboundTrack<Kind> | undefined) {
182
140
  if (this._closed) return;
183
141
  if (this._remoteOutboundTrack) return;
@@ -202,9 +160,7 @@ export class ObservedInboundTrack<Kind extends MediaKind> extends EventEmitter {
202
160
 
203
161
  this._closed = true;
204
162
 
205
- this._execute(() => this._storageProvider.inboundTrackStorage.remove(this.trackId))
206
- .catch(() => void 0)
207
- .finally(() => this.emit('close'));
163
+ this.emit('close');
208
164
  }
209
165
 
210
166
  public resetMetrics() {
@@ -220,10 +176,10 @@ export class ObservedInboundTrack<Kind extends MediaKind> extends EventEmitter {
220
176
  this.fractionLoss = 0;
221
177
  }
222
178
 
223
- public async update(sample: ObservedInboundTrackStatsUpdate<Kind>, timestamp: number) {
179
+ public update(sample: ObservedInboundTrackStatsUpdate<Kind>, timestamp: number) {
224
180
  if (this._closed) return;
225
- let executeSave = false;
226
-
181
+
182
+ const now = Date.now();
227
183
  const report: InboundAudioTrackReport | InboundVideoTrackReport = {
228
184
  serviceId: this.peerConnection.client.call.serviceId,
229
185
  roomId: this.peerConnection.client.call.roomId,
@@ -247,15 +203,13 @@ export class ObservedInboundTrack<Kind extends MediaKind> extends EventEmitter {
247
203
 
248
204
  if (!this._model.sfuStreamId && sample.sfuStreamId) {
249
205
  this._model.sfuStreamId = sample.sfuStreamId;
250
- executeSave = true;
251
206
  }
252
207
 
253
208
  if (!this._model.sfuSinkId && sample.sfuSinkId) {
254
209
  this._model.sfuSinkId = sample.sfuSinkId;
255
- executeSave = true;
256
210
  }
257
211
 
258
- const elapsedTimeInMs = Math.max(1, timestamp - this._updated);
212
+ const elapsedTimeInMs = Math.max(1, now - this._updated);
259
213
  const lastStat = this._stats.get(sample.ssrc);
260
214
  const rttInMs = sample.roundTripTime ? sample.roundTripTime * 1000 : undefined;
261
215
  const bitrate = ((sample.bytesReceived ?? 0) - (lastStat?.bytesReceived ?? 0)) * 8 / (elapsedTimeInMs / 1000);
@@ -318,15 +272,7 @@ export class ObservedInboundTrack<Kind extends MediaKind> extends EventEmitter {
318
272
  this.deltaSilentConcealedSamples = [ ...this._stats.values() ].reduce((acc, stat) => acc + (stat.silentConcealedSamples ?? 0), 0);
319
273
  this.fractionLoss = 0 < this.deltaReceivedPackets && 0 < this.deltaLostPackets ? (this.deltaLostPackets / (this.deltaReceivedPackets + this.deltaLostPackets)) : 0;
320
274
 
321
- if (executeSave) await this._save();
322
-
323
- this._updated = timestamp;
275
+ this._updated = now;
324
276
  this.emit('update');
325
277
  }
326
-
327
- private async _save() {
328
- if (this._closed) throw new Error(`OutboundTrack ${this.trackId} is closed`);
329
-
330
- return this._storageProvider.inboundTrackStorage.set(this.trackId, this._model);
331
- }
332
278
  }
@@ -1,14 +1,11 @@
1
1
  import { EventEmitter } from 'events';
2
- import { StorageProvider } from './storages/StorageProvider';
3
- import * as Models from './models/Models';
4
2
  import { ObservedPeerConnection } from './ObservedPeerConnection';
5
3
  import { OutboundAudioTrack, OutboundVideoTrack } from '@observertc/sample-schemas-js';
6
4
  import { ObservedInboundTrack } from './ObservedInboundTrack';
7
5
  import { OutboundAudioTrackReport, OutboundVideoTrackReport } from '@observertc/report-schemas-js';
8
6
  import { MediaKind } from './common/types';
9
- import { createSingleExecutor } from './common/SingleExecutor';
10
7
 
11
- export type ObservedOutboundTrackConfig<K extends MediaKind> = {
8
+ export type ObservedOutboundTrackModel<K extends MediaKind> = {
12
9
  trackId: string;
13
10
  kind: K;
14
11
  sfuStreamId?: string;
@@ -46,29 +43,7 @@ export declare interface ObservedOutboundTrack<Kind extends MediaKind> {
46
43
  }
47
44
 
48
45
  export class ObservedOutboundTrack<Kind extends MediaKind> extends EventEmitter {
49
- public static async create<K extends MediaKind>(
50
- config: ObservedOutboundTrackConfig<K>,
51
- peerConnection: ObservedPeerConnection,
52
- storageProvider: StorageProvider,
53
- ) {
54
- const model = new Models.OutboundTrack({
55
- serviceId: peerConnection.client.serviceId,
56
- roomId: peerConnection.client.roomId,
57
- callId: peerConnection.client.callId,
58
- clientId: peerConnection.client.clientId,
59
- mediaUnitId: peerConnection.client.mediaUnitId,
60
- peerConnectionId: peerConnection.peerConnectionId,
61
- trackId: config.trackId,
62
- kind: config.kind,
63
- sfuStreamId: config.sfuStreamId,
64
- });
65
-
66
- const alreadyInserted = await storageProvider.outboundTrackStorage.insert(config.trackId, model);
67
-
68
- if (alreadyInserted) throw new Error(`OutboundAudioTrack with id ${config.trackId} already exists`);
69
-
70
- return new ObservedOutboundTrack<K>(model, peerConnection, storageProvider);
71
- }
46
+ public readonly created = Date.now();
72
47
 
73
48
  public bitrate = 0;
74
49
  public rttInMs?: number;
@@ -84,31 +59,49 @@ export class ObservedOutboundTrack<Kind extends MediaKind> extends EventEmitter
84
59
  public deltaSentFrames = 0;
85
60
  public deltaEncodedFrames = 0;
86
61
 
87
- public created = Date.now();
88
-
89
62
  private readonly _stats = new Map<number, ObservedOutboundTrackStats<Kind>>();
90
- private readonly _execute = createSingleExecutor();
91
63
 
92
64
  private _closed = false;
93
65
  private _updated = Date.now();
94
66
  private _remoteInboundTracks = new Map<string, ObservedInboundTrack<Kind>>();
95
67
 
96
- private constructor(
97
- private readonly _model: Models.OutboundTrack,
68
+ public constructor(
69
+ private readonly _model: ObservedOutboundTrackModel<Kind>,
98
70
  public readonly peerConnection: ObservedPeerConnection,
99
- private readonly _storageProvider: StorageProvider,
100
71
  ) {
101
72
  super();
102
73
  }
103
74
 
75
+ public get serviceId() {
76
+ return this.peerConnection.serviceId;
77
+ }
78
+
79
+ public get roomId() {
80
+ return this.peerConnection.roomId;
81
+ }
82
+
83
+ public get callId() {
84
+ return this.peerConnection.callId;
85
+ }
86
+
87
+ public get clientId() {
88
+ return this.peerConnection.clientId;
89
+ }
90
+
91
+ public get mediaUnitId() {
92
+ return this.peerConnection.mediaUnitId;
93
+ }
94
+
95
+ public get peerConnectionId() {
96
+ return this.peerConnection.peerConnectionId;
97
+ }
98
+
104
99
  public get kind(): Kind {
105
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
106
- return this._model.kind! as Kind;
100
+ return this._model.kind as Kind;
107
101
  }
108
102
 
109
103
  public get trackId() {
110
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
111
- return this._model.trackId!;
104
+ return this._model.trackId;
112
105
  }
113
106
 
114
107
  public get sfuStreamId() {
@@ -131,22 +124,15 @@ export class ObservedOutboundTrack<Kind extends MediaKind> extends EventEmitter
131
124
  return this._stats;
132
125
  }
133
126
 
134
- public get uptimeInMs() {
135
- return this._updated - this.created;
136
- }
137
-
138
127
  public get closed() {
139
128
  return this._closed;
140
129
  }
141
130
 
142
131
  public close() {
143
132
  if (this._closed) return;
144
-
145
133
  this._closed = true;
146
134
 
147
- this._execute(() => this._storageProvider.inboundTrackStorage.remove(this.trackId))
148
- .catch(() => void 0)
149
- .finally(() => this.emit('close'));
135
+ this.emit('close');
150
136
  }
151
137
 
152
138
  public resetMetrics() {
@@ -160,10 +146,10 @@ export class ObservedOutboundTrack<Kind extends MediaKind> extends EventEmitter
160
146
  this.deltaEncodedFrames = 0;
161
147
  }
162
148
 
163
- public async update(sample: ObservedOutboundTrackStatsUpdate<Kind>, timestamp: number): Promise<void> {
149
+ public update(sample: ObservedOutboundTrackStatsUpdate<Kind>, timestamp: number): void {
164
150
  if (this._closed) return;
165
- let executeSave = false;
166
-
151
+
152
+ const now = Date.now();
167
153
  const report: OutboundAudioTrackReport | OutboundVideoTrackReport = {
168
154
  serviceId: this.peerConnection.client.serviceId,
169
155
  roomId: this.peerConnection.client.call.roomId,
@@ -180,7 +166,7 @@ export class ObservedOutboundTrack<Kind extends MediaKind> extends EventEmitter
180
166
  if (this.kind === 'audio') this.reports.addOutboundAudioTrackReport(report);
181
167
  else if (this.kind === 'video') this.reports.addOutboundVideoTrackReport(report);
182
168
 
183
- const elapsedTimeInMs = Math.max(1, timestamp - this._updated);
169
+ const elapsedTimeInMs = Math.max(1, now - this._updated);
184
170
  const lastStat = this._stats.get(sample.ssrc);
185
171
  const rttInMs = sample.roundTripTime ? sample.roundTripTime * 1000 : undefined;
186
172
  const bitrate = ((sample.bytesSent ?? 0) - (lastStat?.bytesSent ?? 0)) * 8 / (elapsedTimeInMs / 1000);
@@ -237,13 +223,9 @@ export class ObservedOutboundTrack<Kind extends MediaKind> extends EventEmitter
237
223
 
238
224
  if (this.kind === 'audio') this.peerConnection.client.call.sfuStreamIdToOutboundAudioTrack.set(this._model.sfuStreamId, this as ObservedOutboundTrack<'audio'>);
239
225
  else if (this.kind === 'video') this.peerConnection.client.call.sfuStreamIdToOutboundVideoTrack.set(this._model.sfuStreamId, this as ObservedOutboundTrack<'video'>);
240
-
241
- executeSave = true;
242
226
  }
243
227
 
244
- if (executeSave) await this._save();
245
-
246
- this._updated = timestamp;
228
+ this._updated = now;
247
229
  this.emit('update');
248
230
  }
249
231
 
@@ -257,10 +239,4 @@ export class ObservedOutboundTrack<Kind extends MediaKind> extends EventEmitter
257
239
 
258
240
  this._remoteInboundTracks.set(track.trackId, track);
259
241
  }
260
-
261
- private async _save() {
262
- if (this._closed) throw new Error(`OutboundTrack ${this.trackId} is closed`);
263
-
264
- return this._storageProvider.outboundTrackStorage.set(this.trackId, this._model);
265
- }
266
242
  }