@observertc/observer-js 0.9.1-beta → 0.9.2-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 (102) hide show
  1. package/lib/Evaluator.d.ts.map +1 -1
  2. package/lib/Evaluator.js +13 -2
  3. package/lib/Observer.d.ts +3 -1
  4. package/lib/Observer.d.ts.map +1 -1
  5. package/lib/Observer.js +19 -1
  6. package/lib/common/logger.d.ts +2 -2
  7. package/lib/common/logger.d.ts.map +1 -1
  8. package/lib/common/logger.js +49 -35
  9. package/lib/common/types.d.ts +22 -0
  10. package/lib/common/types.d.ts.map +1 -1
  11. package/lib/middlewares/CommitTransactionMiddleware.d.ts.map +1 -1
  12. package/lib/middlewares/CommitTransactionMiddleware.js +25 -0
  13. package/lib/middlewares/TransactionContext.d.ts +4 -2
  14. package/lib/middlewares/TransactionContext.d.ts.map +1 -1
  15. package/lib/middlewares/TransactionContext.js +2 -1
  16. package/lib/middlewares/TransactoinProcessor.d.ts.map +1 -1
  17. package/lib/middlewares/TransactoinProcessor.js +3 -2
  18. package/lib/middlewares/VisitObservedCallsMiddleware.d.ts +1 -1
  19. package/lib/middlewares/VisitObservedCallsMiddleware.d.ts.map +1 -1
  20. package/lib/middlewares/VisitObservedCallsMiddleware.js +2 -2
  21. package/lib/middlewares/VisitObservedSfusMiddleware.d.ts +6 -0
  22. package/lib/middlewares/VisitObservedSfusMiddleware.d.ts.map +1 -0
  23. package/lib/middlewares/VisitObservedSfusMiddleware.js +142 -0
  24. package/lib/middlewares/visitors/visitClient.d.ts.map +1 -1
  25. package/lib/middlewares/visitors/visitClient.js +13 -0
  26. package/lib/middlewares/visitors/{visitOutboundVideoTarcks.d.ts → visitOutboundVideoTarck.d.ts} +1 -1
  27. package/lib/middlewares/visitors/visitOutboundVideoTarck.d.ts.map +1 -0
  28. package/lib/middlewares/visitors/visitSfu.d.ts +5 -0
  29. package/lib/middlewares/visitors/visitSfu.d.ts.map +1 -0
  30. package/lib/middlewares/visitors/visitSfu.js +79 -0
  31. package/lib/middlewares/visitors/visitSfuInboundRtpPad.d.ts +5 -0
  32. package/lib/middlewares/visitors/visitSfuInboundRtpPad.d.ts.map +1 -0
  33. package/lib/middlewares/visitors/visitSfuInboundRtpPad.js +60 -0
  34. package/lib/middlewares/visitors/visitSfuOutboundRtpPad.d.ts +5 -0
  35. package/lib/middlewares/visitors/visitSfuOutboundRtpPad.d.ts.map +1 -0
  36. package/lib/middlewares/visitors/visitSfuOutboundRtpPad.js +61 -0
  37. package/lib/middlewares/visitors/visitSfuSctpChannel.d.ts +5 -0
  38. package/lib/middlewares/visitors/visitSfuSctpChannel.d.ts.map +1 -0
  39. package/lib/middlewares/visitors/visitSfuSctpChannel.js +58 -0
  40. package/lib/middlewares/visitors/visitSfuTransport.d.ts +5 -0
  41. package/lib/middlewares/visitors/visitSfuTransport.d.ts.map +1 -0
  42. package/lib/middlewares/visitors/visitSfuTransport.js +59 -0
  43. package/lib/samples/ObservedSfu.d.ts +27 -0
  44. package/lib/samples/ObservedSfu.d.ts.map +1 -0
  45. package/lib/samples/ObservedSfu.js +72 -0
  46. package/lib/samples/ObservedSfuInboundRtpPad.d.ts +15 -0
  47. package/lib/samples/ObservedSfuInboundRtpPad.d.ts.map +1 -0
  48. package/lib/samples/ObservedSfuInboundRtpPad.js +21 -0
  49. package/lib/samples/ObservedSfuOutboundRtpPad.d.ts +15 -0
  50. package/lib/samples/ObservedSfuOutboundRtpPad.d.ts.map +1 -0
  51. package/lib/samples/ObservedSfuOutboundRtpPad.js +21 -0
  52. package/lib/samples/ObservedSfuSctpChannel.d.ts +15 -0
  53. package/lib/samples/ObservedSfuSctpChannel.d.ts.map +1 -0
  54. package/lib/samples/ObservedSfuSctpChannel.js +21 -0
  55. package/lib/samples/ObservedSfuTransport.d.ts +30 -0
  56. package/lib/samples/ObservedSfuTransport.d.ts.map +1 -0
  57. package/lib/samples/ObservedSfuTransport.js +93 -0
  58. package/lib/samples/ObservedSfus.d.ts +16 -0
  59. package/lib/samples/ObservedSfus.d.ts.map +1 -0
  60. package/lib/samples/ObservedSfus.js +66 -0
  61. package/lib/sinks/ObserverSink.d.ts +3 -3
  62. package/lib/sinks/ObserverSink.d.ts.map +1 -1
  63. package/lib/sources/ObservedSfuSource.d.ts +14 -0
  64. package/lib/sources/ObservedSfuSource.d.ts.map +1 -0
  65. package/lib/sources/ObservedSfuSource.js +2 -0
  66. package/lib/sources/Sources.d.ts +8 -0
  67. package/lib/sources/Sources.d.ts.map +1 -1
  68. package/lib/sources/Sources.js +47 -1
  69. package/lib/storages/StorageProvider.d.ts.map +1 -1
  70. package/package.json +1 -1
  71. package/src/Evaluator.ts +14 -2
  72. package/src/Observer.ts +22 -1
  73. package/src/common/logger.ts +145 -127
  74. package/src/common/types.ts +27 -0
  75. package/src/middlewares/CommitTransactionMiddleware.ts +46 -6
  76. package/src/middlewares/TransactionContext.ts +7 -3
  77. package/src/middlewares/TransactoinProcessor.ts +3 -1
  78. package/src/middlewares/VisitObservedCallsMiddleware.ts +1 -1
  79. package/src/middlewares/VisitObservedSfusMiddleware.ts +202 -0
  80. package/src/middlewares/visitors/visitClient.ts +15 -0
  81. package/src/middlewares/visitors/visitSfu.ts +64 -0
  82. package/src/middlewares/visitors/visitSfuInboundRtpPad.ts +50 -0
  83. package/src/middlewares/visitors/visitSfuOutboundRtpPad.ts +51 -0
  84. package/src/middlewares/visitors/visitSfuSctpChannel.ts +48 -0
  85. package/src/middlewares/visitors/visitSfuTransport.ts +48 -0
  86. package/src/samples/ObservedSfu.ts +108 -0
  87. package/src/samples/ObservedSfuInboundRtpPad.ts +34 -0
  88. package/src/samples/ObservedSfuOutboundRtpPad.ts +34 -0
  89. package/src/samples/ObservedSfuSctpChannel.ts +35 -0
  90. package/src/samples/ObservedSfuTransport.ts +130 -0
  91. package/src/samples/ObservedSfus.ts +85 -0
  92. package/src/sinks/ObserverSink.ts +5 -3
  93. package/src/sources/ObservedSfuSource.ts +23 -0
  94. package/src/sources/Sources.ts +54 -3
  95. package/src/storages/StorageProvider.ts +1 -4
  96. package/lib/middlewares/visitors/visitOutboundVideoTarcks.d.ts.map +0 -1
  97. package/lib/storages/StorageFactory.d.ts +0 -27
  98. package/lib/storages/StorageFactory.d.ts.map +0 -1
  99. package/lib/storages/StorageFactory.js +0 -37
  100. package/src/storages/StorageFactory.ts +0 -58
  101. /package/lib/middlewares/visitors/{visitOutboundVideoTarcks.js → visitOutboundVideoTarck.js} +0 -0
  102. /package/src/middlewares/visitors/{visitOutboundVideoTarcks.ts → visitOutboundVideoTarck.ts} +0 -0
@@ -0,0 +1,202 @@
1
+ import { Middleware } from './Middleware';
2
+ import { TransactionContext } from './TransactionContext';
3
+ import { ReportsCollector } from '../common/ReportsCollector';
4
+ import { createLogger } from '../common/logger';
5
+ import { visitSfu } from './visitors/visitSfu';
6
+ import { visitSfuTransport } from './visitors/visitSfuTransport';
7
+ import { visitSfuInboundRtpPad } from './visitors/visitSfuInboundRtpPad';
8
+ import { visitSfuOutboundRtpPad } from './visitors/visitSfuOutboundRtpPad';
9
+ import { visitSfuSctpChannel } from './visitors/visitSfuSctpChannel';
10
+
11
+ export const logger = createLogger('VisitObservedCallsMiddleware');
12
+
13
+ export function createVisitObservedSfusMiddleware(
14
+ reports: ReportsCollector,
15
+ fetchSamples: boolean
16
+ ): Middleware<TransactionContext> {
17
+ const process = async (transaction: TransactionContext) => {
18
+ const {
19
+ observedSfus,
20
+ updatedSfus,
21
+ deletedSfus,
22
+
23
+ updatedSfuTransports,
24
+ deletedSfuTransports,
25
+
26
+ updatedSfuInboundRtpPads,
27
+ deletedSfuInboundRtpPads,
28
+
29
+ updatedSfuOutboundRtpPads,
30
+ deletedSfuOutboundRtpPads,
31
+
32
+ updatedSfuSctpChannels,
33
+ deletedSfuSctpChannels
34
+
35
+ } = transaction;
36
+
37
+ const visitedSfuIds = new Set<string>();
38
+ const visitedSfuTransportIds = new Set<string>();
39
+ const visitedSfuInboundRtpPadIds = new Set<string>();
40
+ const visitedSfuOutboundRtpPadIds = new Set<string>();
41
+ const visitedSfuSctpChannels = new Set<string>();
42
+
43
+ for (const observedSfu of observedSfus.observedSfus()) {
44
+ const { sfuId } = observedSfu;
45
+
46
+ visitSfu(observedSfu, updatedSfus, reports, fetchSamples);
47
+
48
+ visitedSfuIds.add(sfuId);
49
+ const storedSfu = updatedSfus.get(sfuId);
50
+
51
+ if (!storedSfu) {
52
+ continue;
53
+ }
54
+
55
+ for (const observedSfuTransport of observedSfu.observedSfuTransports()) {
56
+ const { transportId } = observedSfuTransport;
57
+
58
+ visitSfuTransport(observedSfuTransport, storedSfu, updatedSfuTransports, reports, fetchSamples);
59
+
60
+ visitedSfuTransportIds.add(transportId);
61
+ const storedSfuTransport = updatedSfuTransports.get(transportId);
62
+
63
+ if (!storedSfuTransport) {
64
+ continue;
65
+ }
66
+
67
+ for (const sfuInboundRtpPad of observedSfuTransport.inboundRtpPads()) {
68
+ visitSfuInboundRtpPad(sfuInboundRtpPad, storedSfuTransport, updatedSfuInboundRtpPads, reports, fetchSamples);
69
+
70
+ visitedSfuInboundRtpPadIds.add(sfuInboundRtpPad.padId);
71
+ }
72
+
73
+ for (const sfuOutboundRtpPad of observedSfuTransport.outboundRtpPads()) {
74
+ visitSfuOutboundRtpPad(sfuOutboundRtpPad, storedSfuTransport, updatedSfuOutboundRtpPads, reports, fetchSamples);
75
+
76
+ visitedSfuInboundRtpPadIds.add(sfuOutboundRtpPad.padId);
77
+ }
78
+
79
+ for (const sfuSctpChannel of observedSfuTransport.sfuSctpChannels()) {
80
+ visitSfuSctpChannel(sfuSctpChannel, storedSfuTransport, updatedSfuSctpChannels, reports, fetchSamples);
81
+
82
+ visitedSfuSctpChannels.add(sfuSctpChannel.channelId);
83
+ }
84
+ }
85
+ }
86
+
87
+ for (const [sfuId, sfu] of Array.from(updatedSfus.entries())) {
88
+
89
+ if (visitedSfuIds.has(sfuId)) {
90
+ continue;
91
+ }
92
+ deletedSfus.add(sfuId);
93
+
94
+ if (sfu.serviceId && sfu.mediaUnitId) {
95
+ reports.addSfuEventReport({
96
+ serviceId: sfu.serviceId,
97
+ mediaUnitId: sfu.mediaUnitId,
98
+ name: "SFU_LEFT",
99
+ sfuId,
100
+ timestamp: Date.now(),
101
+ marker: sfu.marker,
102
+ message: 'SFU is detached',
103
+ });
104
+ }
105
+ }
106
+
107
+ for (const [sfuTransportId, sfuTransport] of Array.from(updatedSfuTransports.entries())) {
108
+ if (visitedSfuTransportIds.has(sfuTransportId)) {
109
+ continue;
110
+ }
111
+ // delete PeerConnection
112
+ const { serviceId, sfuId, transportId } = sfuTransport;
113
+
114
+ if (!serviceId || !sfuId || !transportId) {
115
+ continue;
116
+ }
117
+
118
+ const storedSfu = updatedSfus.get(sfuId);
119
+
120
+ updatedSfuTransports.delete(transportId);
121
+ deletedSfuTransports.add(transportId);
122
+
123
+ // also update the peer connection model
124
+ if (storedSfu) {
125
+ storedSfu.sfuTransportIds = storedSfu.sfuTransportIds.filter((tId) => tId !== transportId);
126
+ }
127
+ }
128
+
129
+ for (const [padId, sfuInboundRtpPad] of Array.from(updatedSfuInboundRtpPads.entries())) {
130
+ if (visitedSfuInboundRtpPadIds.has(padId)) {
131
+ continue;
132
+ }
133
+ // delete Sfu Inbound Rtp Pad
134
+ const { serviceId, rtpPadId, sfuTransportId } = sfuInboundRtpPad;
135
+
136
+ if (!serviceId || !sfuTransportId || !rtpPadId) {
137
+ continue;
138
+ }
139
+
140
+ const storedSfuTransport = updatedSfuTransports.get(sfuTransportId);
141
+
142
+ updatedSfuInboundRtpPads.delete(rtpPadId);
143
+ deletedSfuInboundRtpPads.add(rtpPadId);
144
+
145
+ // also update the sfu transport model
146
+ if (storedSfuTransport) {
147
+ storedSfuTransport.inboundRtpPadIds = storedSfuTransport.inboundRtpPadIds.filter((tId) => tId !== rtpPadId);
148
+ }
149
+ }
150
+
151
+ for (const [padId, sfuOutboundRtpPad] of Array.from(updatedSfuOutboundRtpPads.entries())) {
152
+ if (visitedSfuOutboundRtpPadIds.has(padId)) {
153
+ continue;
154
+ }
155
+
156
+ // delete Sfu Outbound Rtp Pad
157
+ const { serviceId, rtpPadId, sfuTransportId } = sfuOutboundRtpPad;
158
+
159
+ if (!serviceId || !sfuTransportId || !rtpPadId) {
160
+ continue;
161
+ }
162
+
163
+ const storedSfuTransport = updatedSfuTransports.get(sfuTransportId);
164
+
165
+ updatedSfuOutboundRtpPads.delete(rtpPadId);
166
+ deletedSfuOutboundRtpPads.add(rtpPadId);
167
+
168
+ // also update the sfu transport model
169
+ if (storedSfuTransport) {
170
+ storedSfuTransport.outboundRtpPadIds = storedSfuTransport.outboundRtpPadIds.filter((tId) => tId !== rtpPadId);
171
+ }
172
+ }
173
+
174
+ for (const [channelId, sfuSctpChannel] of Array.from(updatedSfuSctpChannels.entries())) {
175
+ if (visitedSfuSctpChannels.has(channelId)) {
176
+ continue;
177
+ }
178
+
179
+ // delete Sfu Outbound Rtp Pad
180
+ const { serviceId, sfuSctpChannelId, sfuTransportId } = sfuSctpChannel;
181
+
182
+ if (!serviceId || !sfuTransportId || !sfuSctpChannelId) {
183
+ continue;
184
+ }
185
+
186
+ const storedSfuTransport = updatedSfuTransports.get(sfuTransportId);
187
+
188
+ updatedSfuSctpChannels.delete(sfuSctpChannelId);
189
+ deletedSfuSctpChannels.add(sfuSctpChannelId);
190
+
191
+ // also update the sfu transport model
192
+ if (storedSfuTransport) {
193
+ storedSfuTransport.sctpChannelIds = storedSfuTransport.sctpChannelIds.filter((tId) => tId !== sfuSctpChannelId);
194
+ }
195
+ }
196
+ };
197
+ const result = async (context: TransactionContext, next?: Middleware<TransactionContext>) => {
198
+ await process(context);
199
+ if (next) await next(context);
200
+ };
201
+ return result;
202
+ }
@@ -85,6 +85,7 @@ export function visitClient(
85
85
  reports.addCallMetaReport(callMetaReport);
86
86
  }
87
87
  }
88
+
88
89
 
89
90
  if (clientSample.localSDPs && 0 < clientSample.localSDPs.length) {
90
91
  for (const localSDP of clientSample.localSDPs) {
@@ -111,6 +112,20 @@ export function visitClient(
111
112
  }
112
113
  }
113
114
 
115
+ if (clientSample.customCallEvents && 0 < clientSample.customCallEvents.length) {
116
+ for (const callEvent of clientSample.customCallEvents) {
117
+ reports.addCallEventReport({
118
+ serviceId,
119
+ mediaUnitId,
120
+ roomId,
121
+ callId,
122
+ clientId,
123
+ timestamp: Date.now(),
124
+ ...callEvent,
125
+ });
126
+ }
127
+ }
128
+
114
129
  if (clientSample.userMediaErrors && 0 < clientSample.userMediaErrors.length) {
115
130
  for (const userMediaError of clientSample.userMediaErrors) {
116
131
  const callMetaReport = createCallMetaReport(serviceId, mediaUnitId, roomId, callId, clientId, {
@@ -0,0 +1,64 @@
1
+ import * as Models from '../../models/Models';
2
+ import { ReportsCollector } from '../../common/ReportsCollector';
3
+ import { ObservedSfu } from '../../samples/ObservedSfu';
4
+
5
+ export function visitSfu(
6
+ observedSfu: ObservedSfu,
7
+ storedSfus: Map<string, Models.Sfu>,
8
+ reports: ReportsCollector,
9
+ fetchSamples: boolean
10
+ ) {
11
+ const { mediaUnitId, serviceId, sfuId, timeZoneId, marker } = observedSfu;
12
+ let storedSfu = storedSfus.get(sfuId);
13
+ if (!storedSfu) {
14
+ const timestamp = Date.now();
15
+ storedSfu = new Models.Sfu({
16
+ serviceId,
17
+ sfuId,
18
+ joined: BigInt(timestamp),
19
+ mediaUnitId,
20
+ timeZoneId,
21
+ marker,
22
+ sfuTransportIds: [],
23
+ });
24
+ storedSfus.set(sfuId, storedSfu);
25
+
26
+ reports.addSfuEventReport({
27
+ serviceId,
28
+ mediaUnitId,
29
+ name: "SFU_JOINED",
30
+ sfuId,
31
+ timestamp,
32
+ marker,
33
+ message: 'SFU is joined',
34
+ });
35
+ }
36
+
37
+ for (const sfuSample of observedSfu.samples()) {
38
+
39
+ if (sfuSample.customSfuEvents) {
40
+ for (const sfuEvent of sfuSample.customSfuEvents) {
41
+ reports.addSfuEventReport({
42
+ serviceId,
43
+ mediaUnitId,
44
+ sfuId,
45
+ timestamp: Date.now(),
46
+ ...sfuEvent,
47
+ });
48
+ }
49
+ }
50
+
51
+ if (sfuSample.extensionStats) {
52
+ for (const extensionStats of sfuSample.extensionStats) {
53
+ reports.addSfuExtensionReport({
54
+ serviceId,
55
+ mediaUnitId,
56
+ sfuId,
57
+ timestamp: Date.now(),
58
+ payload: extensionStats.payload,
59
+ extensionType: extensionStats.type,
60
+ });
61
+ }
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,50 @@
1
+ import * as Models from '../../models/Models';
2
+ import { ReportsCollector } from '../../common/ReportsCollector';
3
+ import { SfuInboundRtpPadReport } from '@observertc/report-schemas-js';
4
+ import { ObservedSfuInboundRtpPad } from '../../samples/ObservedSfuInboundRtpPad';
5
+
6
+ export function visitSfuInboundRtpPad(
7
+ observedSfuInboundRtpPad: ObservedSfuInboundRtpPad,
8
+ storedSfuTransport: Models.SfuTransport,
9
+ storedSfuInboundRtpPads: Map<string, Models.SfuInboundRtpPad>,
10
+ reports: ReportsCollector,
11
+ fetchSamples: boolean
12
+ ) {
13
+ const { padId: rtpPadId } = observedSfuInboundRtpPad;
14
+
15
+ const { transportId: sfuTransportId } = observedSfuInboundRtpPad.sfuTransport;
16
+
17
+ const { serviceId, sfuId, mediaUnitId, marker, minTimestamp: timestamp } = observedSfuInboundRtpPad.sfuTransport.sfu;
18
+
19
+
20
+ let storedSfuInboundRtpPad = storedSfuInboundRtpPads.get(rtpPadId);
21
+ if (!storedSfuInboundRtpPad) {
22
+ storedSfuInboundRtpPad = new Models.SfuInboundRtpPad({
23
+ serviceId,
24
+ sfuId,
25
+ mediaUnitId,
26
+ sfuTransportId,
27
+ added: BigInt(Date.now()),
28
+ marker,
29
+ });
30
+ storedSfuInboundRtpPads.set(rtpPadId, storedSfuInboundRtpPad);
31
+
32
+ storedSfuTransport.inboundRtpPadIds.push(rtpPadId);
33
+ }
34
+
35
+ for (const sfuInboundRtpPad of observedSfuInboundRtpPad.samples()) {
36
+ const report: SfuInboundRtpPadReport = {
37
+ serviceId,
38
+ sfuId,
39
+ mediaUnitId,
40
+ rtpPadId,
41
+ ...sfuInboundRtpPad,
42
+ sfuStreamId: sfuInboundRtpPad.streamId,
43
+ timestamp,
44
+ };
45
+ reports.addSfuTransportReport(report);
46
+ }
47
+
48
+ if (fetchSamples) {
49
+ }
50
+ }
@@ -0,0 +1,51 @@
1
+ import * as Models from '../../models/Models';
2
+ import { ReportsCollector } from '../../common/ReportsCollector';
3
+ import { SfuOutboundRtpPadReport } from '@observertc/report-schemas-js';
4
+ import { ObservedSfuTransport } from '../../samples/ObservedSfuTransport';
5
+ import { ObservedSfuOutboundRtpPad } from '../../samples/ObservedSfuOutboundRtpPad';
6
+
7
+ export function visitSfuOutboundRtpPad(
8
+ observedSfuOutboundRtpPad: ObservedSfuOutboundRtpPad,
9
+ storedSfuTransport: Models.SfuTransport,
10
+ storedSfuOutboundRtpPads: Map<string, Models.SfuOutboundRtpPad>,
11
+ reports: ReportsCollector,
12
+ fetchSamples: boolean
13
+ ) {
14
+ const { padId: rtpPadId } = observedSfuOutboundRtpPad;
15
+
16
+ const { transportId: sfuTransportId } = observedSfuOutboundRtpPad.sfuTransport;
17
+
18
+ const { serviceId, sfuId, mediaUnitId, marker, minTimestamp: timestamp } = observedSfuOutboundRtpPad.sfuTransport.sfu;
19
+
20
+ let storedSfuOutboundRtpPad = storedSfuOutboundRtpPads.get(rtpPadId);
21
+ if (!storedSfuOutboundRtpPad) {
22
+ storedSfuOutboundRtpPad = new Models.SfuOutboundRtpPad({
23
+ serviceId,
24
+ sfuId,
25
+ mediaUnitId,
26
+ sfuTransportId,
27
+ added: BigInt(Date.now()),
28
+ marker,
29
+ });
30
+ storedSfuOutboundRtpPads.set(rtpPadId, storedSfuOutboundRtpPad);
31
+
32
+ storedSfuTransport.outboundRtpPadIds.push(rtpPadId);
33
+ }
34
+
35
+ for (const sfuOutboundRtpPad of observedSfuOutboundRtpPad.samples()) {
36
+ const report: SfuOutboundRtpPadReport = {
37
+ serviceId,
38
+ sfuId,
39
+ mediaUnitId,
40
+ rtpPadId,
41
+ ...sfuOutboundRtpPad,
42
+ sfuStreamId: sfuOutboundRtpPad.streamId,
43
+ sfuSinkId: sfuOutboundRtpPad.sinkId,
44
+ timestamp,
45
+ };
46
+ reports.addSfuTransportReport(report);
47
+ }
48
+
49
+ if (fetchSamples) {
50
+ }
51
+ }
@@ -0,0 +1,48 @@
1
+ import * as Models from '../../models/Models';
2
+ import { ReportsCollector } from '../../common/ReportsCollector';
3
+ import { SfuSctpStreamReport } from '@observertc/report-schemas-js';
4
+ import { ObservedSfuSctpChannel } from '../../samples/ObservedSfuSctpChannel';
5
+
6
+ export function visitSfuSctpChannel(
7
+ observedSfuSctpChannel: ObservedSfuSctpChannel,
8
+ storedSfuTransport: Models.SfuTransport,
9
+ storedSfuSctpChannels: Map<string, Models.SfuSctpChannel>,
10
+ reports: ReportsCollector,
11
+ fetchSamples: boolean
12
+ ) {
13
+ const { channelId } = observedSfuSctpChannel;
14
+
15
+ const { transportId: sfuTransportId } = observedSfuSctpChannel.sfuTransport;
16
+
17
+ const { serviceId, sfuId, mediaUnitId, marker, minTimestamp: timestamp } = observedSfuSctpChannel.sfuTransport.sfu;
18
+
19
+ let storedSfuSctpChannel = storedSfuSctpChannels.get(channelId);
20
+ if (!storedSfuSctpChannel) {
21
+ storedSfuSctpChannel = new Models.SfuSctpChannel({
22
+ serviceId,
23
+ sfuId,
24
+ mediaUnitId,
25
+ sfuTransportId,
26
+ opened: BigInt(Date.now()),
27
+ marker,
28
+ });
29
+ storedSfuSctpChannels.set(channelId, storedSfuSctpChannel);
30
+
31
+ storedSfuTransport.sctpChannelIds.push(channelId);
32
+ }
33
+
34
+ for (const sfuSctpChannel of observedSfuSctpChannel.samples()) {
35
+ const report: SfuSctpStreamReport = {
36
+ serviceId,
37
+ sfuId,
38
+ mediaUnitId,
39
+ ...sfuSctpChannel,
40
+ timestamp,
41
+ };
42
+ reports.addSfuTransportReport(report);
43
+ }
44
+
45
+ if (fetchSamples) {
46
+ }
47
+ }
48
+
@@ -0,0 +1,48 @@
1
+ import * as Models from '../../models/Models';
2
+ import { ReportsCollector } from '../../common/ReportsCollector';
3
+ import { SFUTransportReport } from '@observertc/report-schemas-js';
4
+ import { ObservedSfuTransport } from '../../samples/ObservedSfuTransport';
5
+
6
+ export function visitSfuTransport(
7
+ observedSfuTransport: ObservedSfuTransport,
8
+ storedSfu: Models.Sfu,
9
+ storedSfuTransports: Map<string, Models.SfuTransport>,
10
+ reports: ReportsCollector,
11
+ fetchSamples: boolean
12
+ ) {
13
+ const { transportId } = observedSfuTransport;
14
+
15
+ const { serviceId, sfuId, mediaUnitId, marker, minTimestamp: timestamp } = observedSfuTransport.sfu;
16
+
17
+
18
+ let storedSfuTransport = storedSfuTransports.get(transportId);
19
+ if (!storedSfuTransport) {
20
+ storedSfuTransport = new Models.SfuTransport({
21
+ serviceId,
22
+ sfuId,
23
+ mediaUnitId,
24
+ transportId,
25
+ opened: BigInt(Date.now()),
26
+ marker,
27
+ inboundRtpPadIds: [],
28
+ outboundRtpPadIds: [],
29
+ });
30
+ storedSfuTransports.set(transportId, storedSfuTransport);
31
+
32
+ storedSfu.sfuTransportIds.push(transportId);
33
+ }
34
+
35
+ for (const sfuTransport of observedSfuTransport.transportSamples()) {
36
+ const report: SFUTransportReport = {
37
+ serviceId,
38
+ sfuId,
39
+ mediaUnitId,
40
+ ...sfuTransport,
41
+ timestamp,
42
+ };
43
+ reports.addSfuTransportReport(report);
44
+ }
45
+
46
+ if (fetchSamples) {
47
+ }
48
+ }
@@ -0,0 +1,108 @@
1
+ import { ClientSample, SfuSample } from '@observertc/sample-schemas-js';
2
+ import { ObservedPeerConnection, ObservedPeerConnectionBuilder } from './ObservedPeerConnection';
3
+ import { ObservedCall } from './ObservedCall';
4
+ import { ObservedSfuTransport, ObservedSfuTransportBuilder } from './ObservedSfuTransport';
5
+
6
+ export interface ObservedSfu {
7
+ readonly serviceId: string;
8
+ readonly sfuId: string;
9
+ readonly mediaUnitId: string;
10
+
11
+ observedSfuTransports(): IterableIterator<ObservedSfuTransport>;
12
+ getObservedSfuTransport(sfuId: string): ObservedSfuTransport | undefined;
13
+ samples(): IterableIterator<SfuSample>;
14
+
15
+ readonly marker?: string;
16
+ readonly timeZoneId?: string;
17
+
18
+ minTimestamp: number;
19
+ maxTimestamp: number;
20
+ }
21
+
22
+ export class ObservedSfuBuilder {
23
+ private _minTimestamp?: number;
24
+ private _maxTimestamp?: number;
25
+ private _sfuTransports = new Map<string, ObservedSfuTransportBuilder>();
26
+ private _sfuSamples: SfuSample[] = [];
27
+ public constructor(
28
+ private _config: Omit<
29
+ ObservedSfu,
30
+ | keyof IterableIterator<ObservedPeerConnection>
31
+ | 'samples'
32
+ | 'observedSfuTransports'
33
+ | 'getObservedSfuTransport'
34
+ | 'minTimestamp'
35
+ | 'maxTimestamp'
36
+ >
37
+ ) {}
38
+
39
+ public addSfuSample(sfuSample: SfuSample) {
40
+ this._sfuSamples.push(sfuSample);
41
+
42
+ if (sfuSample.transports) {
43
+ for (const sfuTransport of sfuSample.transports) {
44
+ const builder = this._getOrCreateSfuTransportBuilder(sfuTransport.transportId);
45
+ builder.addTransportSample(sfuTransport);
46
+ }
47
+ }
48
+
49
+ if (sfuSample.inboundRtpPads) {
50
+ for (const inboundRtpPad of sfuSample.inboundRtpPads) {
51
+ const builder = this._getOrCreateSfuTransportBuilder(inboundRtpPad.transportId);
52
+ builder.addSfuInboundRtpPad(inboundRtpPad);
53
+ }
54
+ }
55
+
56
+ if (sfuSample.outboundRtpPads) {
57
+ for (const outboundRtpPad of sfuSample.outboundRtpPads) {
58
+ const builder = this._getOrCreateSfuTransportBuilder(outboundRtpPad.transportId);
59
+ builder.addSfuOutboundRtpPad(outboundRtpPad);
60
+ }
61
+ }
62
+
63
+ if (sfuSample.sctpChannels) {
64
+ for (const sctpChannel of sfuSample.sctpChannels) {
65
+ const builder = this._getOrCreateSfuTransportBuilder(sctpChannel.transportId);
66
+ builder.addSfuSctpChannel(sctpChannel);
67
+ }
68
+ }
69
+
70
+ if (this._minTimestamp === undefined || sfuSample.timestamp < this._minTimestamp) {
71
+ this._minTimestamp = sfuSample.timestamp;
72
+ }
73
+
74
+ if (this._maxTimestamp === undefined || this._maxTimestamp < sfuSample.timestamp) {
75
+ this._maxTimestamp = sfuSample.timestamp;
76
+ }
77
+ }
78
+
79
+ private _getOrCreateSfuTransportBuilder(transportId: string): ObservedSfuTransportBuilder {
80
+ let result = this._sfuTransports.get(transportId);
81
+ if (!result) {
82
+ result = new ObservedSfuTransportBuilder({
83
+ transportId,
84
+ });
85
+ this._sfuTransports.set(transportId, result);
86
+ }
87
+ return result;
88
+ }
89
+
90
+ public build(): ObservedSfu {
91
+ const observedSfuTransports = new Map<string, ObservedSfuTransport>();
92
+
93
+ const result: ObservedSfu = {
94
+ ...this._config,
95
+ minTimestamp: this._minTimestamp ?? Date.now(),
96
+ maxTimestamp: this._maxTimestamp ?? Date.now(),
97
+ samples: () => this._sfuSamples.values(),
98
+ observedSfuTransports: () => observedSfuTransports.values(),
99
+ getObservedSfuTransport: (transportId: string) => observedSfuTransports.get(transportId),
100
+ };
101
+
102
+ for (const builder of this._sfuTransports.values()) {
103
+ const observedSfuTransport = builder.build(result);
104
+ observedSfuTransports.set(observedSfuTransport.transportId, observedSfuTransport);
105
+ }
106
+ return result;
107
+ }
108
+ }
@@ -0,0 +1,34 @@
1
+ import { SfuInboundRtpPad } from '@observertc/sample-schemas-js';
2
+ import { ObservedSfuTransport } from './ObservedSfuTransport';
3
+
4
+ export interface ObservedSfuInboundRtpPad {
5
+ readonly sfuTransport: ObservedSfuTransport;
6
+ readonly padId: string;
7
+
8
+ samples(): IterableIterator<SfuInboundRtpPad>;
9
+ }
10
+
11
+ export class ObservedSfuInboundRtpPadBuilder {
12
+ private _samples: SfuInboundRtpPad[] = [];
13
+ public constructor(
14
+ private _config: Omit<
15
+ ObservedSfuInboundRtpPad,
16
+ | keyof IterableIterator<SfuInboundRtpPad>
17
+ | 'sfuTransport'
18
+ | 'samples'
19
+ >
20
+ ) {}
21
+
22
+ public addSample(sfuInboundRtpPad: SfuInboundRtpPad) {
23
+ this._samples.push(sfuInboundRtpPad);
24
+ }
25
+
26
+ public build(sfuTransport: ObservedSfuTransport): ObservedSfuInboundRtpPad {
27
+ const result: ObservedSfuInboundRtpPad = {
28
+ sfuTransport,
29
+ ...this._config,
30
+ samples: () => this._samples.values(),
31
+ };
32
+ return result;
33
+ }
34
+ }
@@ -0,0 +1,34 @@
1
+ import { SfuOutboundRtpPad } from '@observertc/sample-schemas-js';
2
+ import { ObservedSfuTransport } from './ObservedSfuTransport';
3
+
4
+ export interface ObservedSfuOutboundRtpPad {
5
+ readonly sfuTransport: ObservedSfuTransport;
6
+ readonly padId: string;
7
+
8
+ samples(): IterableIterator<SfuOutboundRtpPad>;
9
+ }
10
+
11
+ export class ObservedSfuOutboundRtpPadBuilder {
12
+ private _samples: SfuOutboundRtpPad[] = [];
13
+ public constructor(
14
+ private _config: Omit<
15
+ ObservedSfuOutboundRtpPad,
16
+ | keyof IterableIterator<SfuOutboundRtpPad>
17
+ | 'sfuTransport'
18
+ | 'samples'
19
+ >
20
+ ) {}
21
+
22
+ public addSample(sfuInboundRtpPad: SfuOutboundRtpPad) {
23
+ this._samples.push(sfuInboundRtpPad);
24
+ }
25
+
26
+ public build(sfuTransport: ObservedSfuTransport): ObservedSfuOutboundRtpPad {
27
+ const result: ObservedSfuOutboundRtpPad = {
28
+ sfuTransport,
29
+ ...this._config,
30
+ samples: () => this._samples.values(),
31
+ };
32
+ return result;
33
+ }
34
+ }