@observertc/observer-js 0.9.11-beta → 0.9.12-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 (91) hide show
  1. package/lib/Evaluator.d.ts +2 -0
  2. package/lib/Evaluator.d.ts.map +1 -1
  3. package/lib/Evaluator.js +2 -1
  4. package/lib/Observer.d.ts.map +1 -1
  5. package/lib/Observer.js +1 -0
  6. package/lib/common/callMetaReports.d.ts +1 -1
  7. package/lib/common/callMetaReports.d.ts.map +1 -1
  8. package/lib/common/callMetaReports.js +2 -1
  9. package/lib/common/utils.d.ts +1 -0
  10. package/lib/common/utils.d.ts.map +1 -1
  11. package/lib/common/utils.js +12 -0
  12. package/lib/middlewares/DeleteOutdatedCallEntries.d.ts +6 -0
  13. package/lib/middlewares/DeleteOutdatedCallEntries.d.ts.map +1 -0
  14. package/lib/middlewares/DeleteOutdatedCallEntries.js +112 -0
  15. package/lib/middlewares/DeleteOutdatedSfuEntries.d.ts +6 -0
  16. package/lib/middlewares/DeleteOutdatedSfuEntries.d.ts.map +1 -0
  17. package/lib/middlewares/DeleteOutdatedSfuEntries.js +118 -0
  18. package/lib/middlewares/TransactionContext.d.ts.map +1 -1
  19. package/lib/middlewares/TransactionContext.js +42 -26
  20. package/lib/middlewares/TransactoinProcessor.d.ts +1 -1
  21. package/lib/middlewares/TransactoinProcessor.d.ts.map +1 -1
  22. package/lib/middlewares/TransactoinProcessor.js +4 -2
  23. package/lib/middlewares/VisitObservedCallsMiddleware.d.ts +2 -1
  24. package/lib/middlewares/VisitObservedCallsMiddleware.d.ts.map +1 -1
  25. package/lib/middlewares/VisitObservedCallsMiddleware.js +19 -90
  26. package/lib/middlewares/visitors/visitClient.d.ts.map +1 -1
  27. package/lib/middlewares/visitors/visitClient.js +15 -13
  28. package/lib/middlewares/visitors/visitInboundAudioTrack.d.ts +1 -1
  29. package/lib/middlewares/visitors/visitInboundAudioTrack.d.ts.map +1 -1
  30. package/lib/middlewares/visitors/visitInboundAudioTrack.js +10 -2
  31. package/lib/middlewares/visitors/visitInboundVideoTrack.d.ts +1 -1
  32. package/lib/middlewares/visitors/visitInboundVideoTrack.d.ts.map +1 -1
  33. package/lib/middlewares/visitors/visitInboundVideoTrack.js +10 -2
  34. package/lib/middlewares/visitors/visitOutboundAudioTrack.d.ts.map +1 -1
  35. package/lib/middlewares/visitors/visitOutboundAudioTrack.js +5 -1
  36. package/lib/middlewares/visitors/visitOutboundVideoTarck.d.ts.map +1 -1
  37. package/lib/middlewares/visitors/visitOutboundVideoTarck.js +5 -1
  38. package/lib/middlewares/visitors/visitPeerConnection.d.ts.map +1 -1
  39. package/lib/middlewares/visitors/visitPeerConnection.js +15 -0
  40. package/lib/models/Models.d.ts +26 -22
  41. package/lib/models/Models.d.ts.map +1 -1
  42. package/lib/models/Models.js +16 -11
  43. package/lib/processes/findRemoteMatches.d.ts +9 -0
  44. package/lib/processes/findRemoteMatches.d.ts.map +1 -0
  45. package/lib/processes/findRemoteMatches.js +83 -0
  46. package/lib/samples/ObservedCalls.d.ts.map +1 -1
  47. package/lib/samples/ObservedCalls.js +16 -7
  48. package/lib/samples/ObservedInboundAudioTrack.d.ts +2 -0
  49. package/lib/samples/ObservedInboundAudioTrack.d.ts.map +1 -1
  50. package/lib/samples/ObservedInboundVideoTrack.d.ts +2 -0
  51. package/lib/samples/ObservedInboundVideoTrack.d.ts.map +1 -1
  52. package/lib/samples/ObservedOutboundAudioTrack.d.ts +1 -0
  53. package/lib/samples/ObservedOutboundAudioTrack.d.ts.map +1 -1
  54. package/lib/samples/ObservedOutboundVideoTrack.d.ts +1 -0
  55. package/lib/samples/ObservedOutboundVideoTrack.d.ts.map +1 -1
  56. package/lib/samples/ObservedPeerConnection.d.ts.map +1 -1
  57. package/lib/samples/ObservedPeerConnection.js +14 -8
  58. package/lib/samples/ObservedSfus.d.ts.map +1 -1
  59. package/lib/samples/ObservedSfus.js +10 -4
  60. package/lib/storages/ObserverStorage.d.ts +4 -0
  61. package/lib/storages/ObserverStorage.d.ts.map +1 -1
  62. package/lib/storages/SimpleStorage.d.ts +1 -0
  63. package/lib/storages/SimpleStorage.d.ts.map +1 -1
  64. package/lib/storages/SimpleStorage.js +3 -0
  65. package/package.json +1 -1
  66. package/src/Evaluator.ts +7 -3
  67. package/src/Observer.ts +1 -0
  68. package/src/common/callMetaReports.ts +2 -0
  69. package/src/common/utils.ts +11 -0
  70. package/src/middlewares/DeleteOutdatedCallEntries.ts +151 -0
  71. package/src/middlewares/DeleteOutdatedSfuEntries.ts +159 -0
  72. package/src/middlewares/TransactionContext.ts +61 -29
  73. package/src/middlewares/TransactoinProcessor.ts +8 -2
  74. package/src/middlewares/VisitObservedCallsMiddleware.ts +40 -125
  75. package/src/middlewares/visitors/visitClient.ts +15 -13
  76. package/src/middlewares/visitors/visitInboundAudioTrack.ts +15 -5
  77. package/src/middlewares/visitors/visitInboundVideoTrack.ts +14 -2
  78. package/src/middlewares/visitors/visitOutboundAudioTrack.ts +6 -2
  79. package/src/middlewares/visitors/visitOutboundVideoTarck.ts +5 -1
  80. package/src/middlewares/visitors/visitPeerConnection.ts +17 -1
  81. package/src/models/Models.ts +40 -34
  82. package/src/processes/findRemoteMatches.ts +94 -0
  83. package/src/samples/ObservedCalls.ts +17 -7
  84. package/src/samples/ObservedInboundAudioTrack.ts +2 -0
  85. package/src/samples/ObservedInboundVideoTrack.ts +3 -1
  86. package/src/samples/ObservedOutboundAudioTrack.ts +2 -1
  87. package/src/samples/ObservedOutboundVideoTrack.ts +2 -1
  88. package/src/samples/ObservedPeerConnection.ts +28 -8
  89. package/src/samples/ObservedSfus.ts +10 -5
  90. package/src/storages/ObserverStorage.ts +5 -0
  91. package/src/storages/SimpleStorage.ts +4 -0
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ObservedSfusBuilder = void 0;
4
+ const utils_1 = require("../common/utils");
4
5
  const ObservedSfu_1 = require("./ObservedSfu");
5
6
  class ObservedSfusBuilder {
6
7
  constructor() {
@@ -18,19 +19,21 @@ class ObservedSfusBuilder {
18
19
  }
19
20
  build() {
20
21
  const observedSfus = new Map();
21
- const sfuIds = function* () {
22
+ const sfuIdsGenerator = function* () {
22
23
  for (const observedSfu of observedSfus.values()) {
23
24
  yield observedSfu.sfuId;
24
25
  }
25
26
  };
26
- const sfuTransportIds = function* () {
27
+ const sfuIds = () => (0, utils_1.iteratorConverter)(sfuIdsGenerator());
28
+ const sfuTransportIdsGenerator = function* () {
27
29
  for (const observedSfu of observedSfus.values()) {
28
30
  for (const observedTransport of observedSfu.observedSfuTransports()) {
29
31
  yield observedTransport.transportId;
30
32
  }
31
33
  }
32
34
  };
33
- const sfuInboundRtpPadIds = function* () {
35
+ const sfuTransportIds = () => (0, utils_1.iteratorConverter)(sfuTransportIdsGenerator());
36
+ const sfuInboundRtpPadIdsGenerator = function* () {
34
37
  for (const observedSfu of observedSfus.values()) {
35
38
  for (const observedTransport of observedSfu.observedSfuTransports()) {
36
39
  for (const sfuInboundRtpPad of observedTransport.inboundRtpPads()) {
@@ -39,7 +42,8 @@ class ObservedSfusBuilder {
39
42
  }
40
43
  }
41
44
  };
42
- const sfuOutboundRtpPadIds = function* () {
45
+ const sfuInboundRtpPadIds = () => (0, utils_1.iteratorConverter)(sfuInboundRtpPadIdsGenerator());
46
+ const sfuOutboundRtpPadIdsGenerator = function* () {
43
47
  for (const observedSfu of observedSfus.values()) {
44
48
  for (const observedTransport of observedSfu.observedSfuTransports()) {
45
49
  for (const sfuOutboundRtpPad of observedTransport.outboundRtpPads()) {
@@ -48,6 +52,7 @@ class ObservedSfusBuilder {
48
52
  }
49
53
  }
50
54
  };
55
+ const sfuOutboundRtpPadIds = () => (0, utils_1.iteratorConverter)(sfuOutboundRtpPadIdsGenerator());
51
56
  const result = {
52
57
  sfuIds,
53
58
  sfuTransportIds,
@@ -60,6 +65,7 @@ class ObservedSfusBuilder {
60
65
  const observedSfu = builder.build();
61
66
  observedSfus.set(observedSfu.sfuId, observedSfu);
62
67
  }
68
+ this._builders.clear();
63
69
  return result;
64
70
  }
65
71
  }
@@ -79,5 +79,9 @@ export interface ObserverStorage<K, V> {
79
79
  * Returns an async iterable iterator for the key-value pairs in the storage.
80
80
  */
81
81
  [Symbol.asyncIterator](): AsyncIterableIterator<[K, V]>;
82
+ /**
83
+ * Returns an iterable iterator for the key-value pairs stored in this local instance of the storage.
84
+ */
85
+ localEntries(): IterableIterator<[K, V]>;
82
86
  }
83
87
  //# sourceMappingURL=ObserverStorage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ObserverStorage.d.ts","sourceRoot":"","sources":["../../src/storages/ObserverStorage.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,EAAE,CAAC;IACpC;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAExB;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;;;OAKG;IACH,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAEpC;;;;;OAKG;IACH,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEtD;;;;;;OAMG;IACH,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAE9C;;;;;OAKG;IACH,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAE/D;;;;;;OAMG;IACH,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAEjD;;;;;;;;OAQG;IACH,SAAS,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;IAE9E;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAEvC;;;;;OAKG;IACH,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEzD;;OAEG;IACH,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;CACxD"}
1
+ {"version":3,"file":"ObserverStorage.d.ts","sourceRoot":"","sources":["../../src/storages/ObserverStorage.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,EAAE,CAAC;IACpC;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAExB;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;;;OAKG;IACH,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAEpC;;;;;OAKG;IACH,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEtD;;;;;;OAMG;IACH,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAE9C;;;;;OAKG;IACH,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAE/D;;;;;;OAMG;IACH,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAEjD;;;;;;;;OAQG;IACH,SAAS,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;IAE9E;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAEvC;;;;;OAKG;IACH,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEzD;;OAEG;IACH,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAExD;;OAEG;IACH,YAAY,IAAI,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;CACzC"}
@@ -14,5 +14,6 @@ export declare class SimpleStorage<K, V> implements ObserverStorage<K, V> {
14
14
  remove(key: K): Promise<V | undefined>;
15
15
  removeAll(keys: Iterable<K>): Promise<ReadonlyMap<K, V>>;
16
16
  [Symbol.asyncIterator](): AsyncIterableIterator<[K, V]>;
17
+ localEntries(): IterableIterator<[K, V]>;
17
18
  }
18
19
  //# sourceMappingURL=SimpleStorage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SimpleStorage.d.ts","sourceRoot":"","sources":["../../src/storages/SimpleStorage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,qBAAa,aAAa,CAAC,CAAC,EAAE,CAAC,CAAE,YAAW,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC;aAG7B,EAAE,EAAE,MAAM;IAF7C,OAAO,CAAC,IAAI,CAAmB;gBAEI,EAAE,EAAE,MAAM;IAEhC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IAIvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAInC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAWrD,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAM7C,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAY9D,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAQhD,SAAS,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAajE,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAMtC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAYvD,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAKrE"}
1
+ {"version":3,"file":"SimpleStorage.d.ts","sourceRoot":"","sources":["../../src/storages/SimpleStorage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,qBAAa,aAAa,CAAC,CAAC,EAAE,CAAC,CAAE,YAAW,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC;aAG7B,EAAE,EAAE,MAAM;IAF7C,OAAO,CAAC,IAAI,CAAmB;gBAEI,EAAE,EAAE,MAAM;IAEhC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IAIvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAInC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAWrD,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAM7C,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAY9D,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAQhD,SAAS,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAajE,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAMtC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAYvD,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAM9D,YAAY,IAAI,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAG/C"}
@@ -82,5 +82,8 @@ class SimpleStorage {
82
82
  yield entry;
83
83
  }
84
84
  }
85
+ localEntries() {
86
+ return this._map.entries();
87
+ }
85
88
  }
86
89
  exports.SimpleStorage = SimpleStorage;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@observertc/observer-js",
3
- "version": "0.9.11-beta",
3
+ "version": "0.9.12-beta",
4
4
  "description": "Server Side NodeJS Library for processing ObserveRTC Samples",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
package/src/Evaluator.ts CHANGED
@@ -21,6 +21,8 @@ export type EvaluatorEvents = {
21
21
 
22
22
  export type EvaluatorConfig = {
23
23
  fetchSamples: boolean;
24
+ maxIdleTimeInMs?: number,
25
+ findRemoteMatches?: boolean,
24
26
  };
25
27
 
26
28
  export type EvaluatorProcess = (evaluatorContext: EvaluatorContext) => Promise<void>;
@@ -50,7 +52,9 @@ export class Evaluator {
50
52
  this._transactionProcessor = createTransactionProcessor(
51
53
  _storageProvider,
52
54
  _reportsCollector,
53
- this.config.fetchSamples
55
+ this.config.fetchSamples,
56
+ BigInt(this.config.maxIdleTimeInMs ?? 10000),
57
+ this.config.findRemoteMatches,
54
58
  );
55
59
 
56
60
  this._customProcessor = createProcessor();
@@ -106,7 +110,7 @@ export class Evaluator {
106
110
  public addObservedSamples(samples: SourcesEvents['observed-samples']): void {
107
111
  // this triggers the evaluation
108
112
  const { observedCalls, observedSfus } = samples;
109
-
113
+
110
114
  const evaluatorContext: EvaluatorContext = {
111
115
  observedCalls,
112
116
  observedSfus,
@@ -142,7 +146,7 @@ export class Evaluator {
142
146
  sfuEvents: [],
143
147
  sfuExtensionStats: [],
144
148
  };
145
-
149
+
146
150
  const callOperations = createCallOperationContext(this._clientOperations, evaluatorContext);
147
151
  this._clientOperations.clear();
148
152
 
package/src/Observer.ts CHANGED
@@ -53,6 +53,7 @@ export class Observer {
53
53
  },
54
54
  evaluator: {
55
55
  fetchSamples: true,
56
+ maxIdleTimeInMs: 300 * 1000,
56
57
  },
57
58
  sink: {},
58
59
  logLevel: 'info',
@@ -82,6 +82,7 @@ export function createCallMetaReport(
82
82
  callId: string,
83
83
  clientId: string,
84
84
  reportType: CallMetaReportType,
85
+ userId?: string,
85
86
  timestamp?: number
86
87
  ) {
87
88
  const report: CallMetaReport = {
@@ -91,6 +92,7 @@ export function createCallMetaReport(
91
92
  roomId,
92
93
  callId,
93
94
  clientId,
95
+ userId,
94
96
  payload: JSON.stringify(reportType.payload),
95
97
  timestamp: timestamp ?? Date.now(),
96
98
  };
@@ -1,3 +1,14 @@
1
1
  export type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
2
2
 
3
3
  export type Writable<T> = T extends object ? { -readonly [K in keyof T]: Writable<T[K]> } : T;
4
+
5
+ export function iteratorConverter<T>(generator: Generator<T, void, undefined>): IterableIterator<T> {
6
+ return {
7
+ [Symbol.iterator](): IterableIterator<T> {
8
+ return this;
9
+ },
10
+ next(): IteratorResult<T> {
11
+ return generator.next();
12
+ },
13
+ }
14
+ }
@@ -0,0 +1,151 @@
1
+ import { Middleware } from './Middleware';
2
+ import { TransactionContext } from './TransactionContext';
3
+ import { createLogger } from '../common/logger';
4
+ import { StorageProvider } from '..';
5
+
6
+ export const logger = createLogger('DeleteOutdatedCallEntries');
7
+
8
+ export function createDeleteOutdatedCallEntries(
9
+ storages: StorageProvider,
10
+ maxIdleTimeInMs: BigInt,
11
+ ): Middleware<TransactionContext> {
12
+ const process = async (transaction: TransactionContext) => {
13
+ const {
14
+ clients,
15
+
16
+ evaluatorContext,
17
+
18
+ updatedPeerConnections,
19
+ deletedPeerConnections,
20
+
21
+ updatedInboundAudioTracks,
22
+ deletedInboundAudioTracks,
23
+
24
+ updatedInboundVideoTracks,
25
+ deletedInboundVideoTracks,
26
+
27
+ updatedOutboundAudioTracks,
28
+ deletedOutboundAudioTracks,
29
+
30
+ updatedOutboundVideoTracks,
31
+ deletedOutboundVideoTracks,
32
+ } = transaction;
33
+
34
+ const now = BigInt(Date.now());
35
+ const deletedCallIds = new Set(evaluatorContext.endedCalls.map(c => c.callId).filter(id => !!id))
36
+ const deletedClientIds = new Set(evaluatorContext.detachedClients.map(c => c.clientId).filter(id => !!id));
37
+ for (const [peerConnectionId, peerConnection] of storages.peerConnectionStorage.localEntries()) {
38
+ if (updatedPeerConnections.has(peerConnectionId)) {
39
+ continue;
40
+ }
41
+
42
+ const { touched, clientId, callId } = peerConnection;
43
+ if (touched && now - touched < maxIdleTimeInMs) {
44
+ if (
45
+ !deletedCallIds.has(callId ?? "not exists") &&
46
+ !deletedClientIds.has(clientId ?? "not exists")
47
+ ){
48
+ continue;
49
+ }
50
+ }
51
+
52
+ deletedPeerConnections.add(peerConnectionId);
53
+
54
+ if (clientId) {
55
+ let storedClient = clients.get(clientId);
56
+ if (storedClient) {
57
+ storedClient.peerConnectionIds = storedClient.peerConnectionIds.filter((pcId) => pcId !== peerConnectionId);
58
+ } else {
59
+ storedClient = await storages.clientStorage.get(clientId);
60
+ if (storedClient) {
61
+ storedClient.peerConnectionIds = storedClient.peerConnectionIds.filter((pcId) => pcId !== peerConnectionId);
62
+ await storages.clientStorage.set(clientId, storedClient);
63
+ }
64
+ }
65
+ }
66
+ }
67
+
68
+ for (const [trackId, inboundTrack] of storages.inboundTrackStorage.localEntries()) {
69
+ if (updatedInboundAudioTracks.has(trackId) || updatedInboundVideoTracks.has(trackId)) {
70
+ continue;
71
+ }
72
+
73
+ const { touched, clientId, callId, peerConnectionId } = inboundTrack;
74
+ if (touched && now - touched < maxIdleTimeInMs) {
75
+ if (
76
+ !deletedCallIds.has(callId ?? "not exists") &&
77
+ !deletedClientIds.has(clientId ?? "not exists") &&
78
+ !deletedPeerConnections.has(peerConnectionId ?? "not exists")
79
+ ){
80
+ continue;
81
+ }
82
+ }
83
+
84
+ switch (inboundTrack.kind) {
85
+ case 'audio':
86
+ deletedInboundAudioTracks.add(trackId);
87
+ break;
88
+ case 'video':
89
+ deletedInboundVideoTracks.add(trackId);
90
+ }
91
+
92
+ if (peerConnectionId) {
93
+ let storedPeerConnection = updatedPeerConnections.get(peerConnectionId);
94
+ if (!storedPeerConnection) {
95
+ storedPeerConnection = await storages.peerConnectionStorage.get(peerConnectionId);
96
+ if (storedPeerConnection) {
97
+ updatedPeerConnections.set(peerConnectionId, storedPeerConnection);
98
+ }
99
+ }
100
+ if (storedPeerConnection) {
101
+ storedPeerConnection.inboundTrackIds = storedPeerConnection.inboundTrackIds.filter((tId) => tId !== trackId);
102
+ }
103
+ }
104
+ }
105
+
106
+ // console.warn("auodiaussdoi", updatedOutboundAudioTracks, updatedOutboundVideoTracks);
107
+ for (const [trackId, outboundTrack] of storages.outboundTrackStorage.localEntries()) {
108
+ if (updatedOutboundAudioTracks.has(trackId) || updatedOutboundVideoTracks.has(trackId)) {
109
+ continue;
110
+ }
111
+
112
+ const { touched, clientId, callId, peerConnectionId } = outboundTrack;
113
+ // console.warn("deprecated outb tracks", outboundTrack, now, touched, maxIdleTimeInMs, touched && now - touched < maxIdleTimeInMs, callId)
114
+ if (touched && now - touched < maxIdleTimeInMs) {
115
+ if (
116
+ !deletedCallIds.has(callId ?? "not exists") &&
117
+ !deletedClientIds.has(clientId ?? "not exists") &&
118
+ !deletedPeerConnections.has(peerConnectionId ?? "not exists")
119
+ ){
120
+ continue;
121
+ }
122
+ }
123
+
124
+ switch (outboundTrack.kind) {
125
+ case 'audio':
126
+ deletedOutboundAudioTracks.add(trackId);
127
+ break;
128
+ case 'video':
129
+ deletedOutboundVideoTracks.add(trackId);
130
+ }
131
+
132
+ if (peerConnectionId) {
133
+ let storedPeerConnection = updatedPeerConnections.get(peerConnectionId);
134
+ if (!storedPeerConnection) {
135
+ storedPeerConnection = await storages.peerConnectionStorage.get(peerConnectionId);
136
+ if (storedPeerConnection) {
137
+ updatedPeerConnections.set(peerConnectionId, storedPeerConnection);
138
+ }
139
+ }
140
+ if (storedPeerConnection) {
141
+ storedPeerConnection.outboundTrackIds = storedPeerConnection.outboundTrackIds.filter((tId) => tId !== trackId);
142
+ }
143
+ }
144
+ }
145
+ };
146
+ const result = async (context: TransactionContext, next?: Middleware<TransactionContext>) => {
147
+ await process(context);
148
+ if (next) await next(context);
149
+ };
150
+ return result;
151
+ }
@@ -0,0 +1,159 @@
1
+ import { Middleware } from './Middleware';
2
+ import { TransactionContext } from './TransactionContext';
3
+ import { createLogger } from '../common/logger';
4
+ import { StorageProvider } from '..';
5
+
6
+ export const logger = createLogger('DeleteOutdatedSfuEntries');
7
+
8
+ export function createDeleteOutdatedSfuEntries(
9
+ storages: StorageProvider,
10
+ maxIdleTimeInMs: BigInt,
11
+ ): Middleware<TransactionContext> {
12
+ const process = async (transaction: TransactionContext) => {
13
+ const {
14
+ updatedSfus,
15
+ deletedSfus,
16
+
17
+ updatedSfuTransports,
18
+ deletedSfuTransports,
19
+
20
+ updatedSfuInboundRtpPads,
21
+ deletedSfuInboundRtpPads,
22
+
23
+ updatedSfuOutboundRtpPads,
24
+ deletedSfuOutboundRtpPads,
25
+
26
+ updatedSfuSctpChannels,
27
+ deletedSfuSctpChannels
28
+
29
+ } = transaction;
30
+
31
+ const now = BigInt(Date.now());
32
+ for (const [sfuTransportId, sfuTransport] of storages.sfuTransportStorage.localEntries()) {
33
+ if (updatedSfuTransports.has(sfuTransportId)) {
34
+ continue;
35
+ }
36
+
37
+ const { touched, sfuId } = sfuTransport;
38
+ if (touched && now - touched < maxIdleTimeInMs) {
39
+ if (!deletedSfus.has(sfuId ?? "not exists")){
40
+ continue;
41
+ }
42
+ }
43
+
44
+ deletedSfuTransports.add(sfuTransportId);
45
+
46
+ if (sfuId) {
47
+ let storedSfu = updatedSfus.get(sfuId);
48
+ if (storedSfu) {
49
+ storedSfu.sfuTransportIds = storedSfu.sfuTransportIds.filter((transportId) => transportId !== sfuTransportId);
50
+ } else {
51
+ storedSfu = await storages.sfuStorage.get(sfuId);
52
+ if (storedSfu) {
53
+ storedSfu.sfuTransportIds = storedSfu.sfuTransportIds.filter((transportId) => transportId !== sfuTransportId);
54
+ await storages.sfuStorage.set(sfuId, storedSfu);
55
+ }
56
+ }
57
+ }
58
+ }
59
+
60
+ for (const [sfuInboundPadId, sfuInboundPad] of storages.sfuInboundRtpPadStorage.localEntries()) {
61
+ if (updatedSfuInboundRtpPads.has(sfuInboundPadId)) {
62
+ continue;
63
+ }
64
+
65
+ const { touched, sfuTransportId, sfuId } = sfuInboundPad;
66
+ if (touched && now - touched < maxIdleTimeInMs) {
67
+ if (
68
+ !deletedSfuTransports.has(sfuTransportId ?? "not exists") &&
69
+ !deletedSfus.has(sfuId ?? "not exists")
70
+ ){
71
+ continue;
72
+ }
73
+ }
74
+
75
+ deletedSfuInboundRtpPads.add(sfuInboundPadId);
76
+
77
+ if (sfuTransportId) {
78
+ let storedSfuTransport = updatedSfuTransports.get(sfuTransportId);
79
+ if (!storedSfuTransport) {
80
+ storedSfuTransport = await storages.sfuTransportStorage.get(sfuTransportId);
81
+ if (storedSfuTransport) {
82
+ updatedSfuTransports.set(sfuTransportId, storedSfuTransport);
83
+ }
84
+ }
85
+ if (storedSfuTransport) {
86
+ storedSfuTransport.inboundRtpPadIds = storedSfuTransport.inboundRtpPadIds.filter((tId) => tId !== sfuInboundPadId);
87
+ }
88
+ }
89
+ }
90
+
91
+
92
+ for (const [sfuOutboundPadId, sfuOutboundPad] of storages.sfuOutboundRtpPadStorage.localEntries()) {
93
+ if (updatedSfuOutboundRtpPads.has(sfuOutboundPadId)) {
94
+ continue;
95
+ }
96
+
97
+ const { touched, sfuTransportId, sfuId } = sfuOutboundPad;
98
+ if (touched && now - touched < maxIdleTimeInMs) {
99
+ if (
100
+ !deletedSfuTransports.has(sfuTransportId ?? "not exists") &&
101
+ !deletedSfus.has(sfuId ?? "not exists")
102
+ ){
103
+ continue;
104
+ }
105
+ }
106
+
107
+ deletedSfuOutboundRtpPads.add(sfuOutboundPadId);
108
+
109
+ if (sfuTransportId) {
110
+ let storedSfuTransport = updatedSfuTransports.get(sfuTransportId);
111
+ if (!storedSfuTransport) {
112
+ storedSfuTransport = await storages.sfuTransportStorage.get(sfuTransportId);
113
+ if (storedSfuTransport) {
114
+ updatedSfuTransports.set(sfuTransportId, storedSfuTransport);
115
+ }
116
+ }
117
+ if (storedSfuTransport) {
118
+ storedSfuTransport.outboundRtpPadIds = storedSfuTransport.outboundRtpPadIds.filter((tId) => tId !== sfuOutboundPadId);
119
+ }
120
+ }
121
+ }
122
+
123
+ for (const [sctpChannelId, sctpChannel] of storages.sfuSctpChannelStorage.localEntries()) {
124
+ if (updatedSfuSctpChannels.has(sctpChannelId)) {
125
+ continue;
126
+ }
127
+
128
+ const { touched, sfuTransportId, sfuId } = sctpChannel;
129
+ if (touched && now - touched < maxIdleTimeInMs) {
130
+ if (
131
+ !deletedSfuTransports.has(sfuTransportId ?? "not exists") &&
132
+ !deletedSfus.has(sfuId ?? "not exists")
133
+ ){
134
+ continue;
135
+ }
136
+ }
137
+
138
+ deletedSfuSctpChannels.add(sctpChannelId);
139
+
140
+ if (sfuTransportId) {
141
+ let storedSfuTransport = updatedSfuTransports.get(sfuTransportId);
142
+ if (!storedSfuTransport) {
143
+ storedSfuTransport = await storages.sfuTransportStorage.get(sfuTransportId);
144
+ if (storedSfuTransport) {
145
+ updatedSfuTransports.set(sfuTransportId, storedSfuTransport);
146
+ }
147
+ }
148
+ if (storedSfuTransport) {
149
+ storedSfuTransport.sctpChannelIds = storedSfuTransport.sctpChannelIds.filter((tId) => tId !== sctpChannelId);
150
+ }
151
+ }
152
+ }
153
+ };
154
+ const result = async (context: TransactionContext, next?: Middleware<TransactionContext>) => {
155
+ await process(context);
156
+ if (next) await next(context);
157
+ };
158
+ return result;
159
+ }
@@ -67,41 +67,73 @@ export async function createTransactionContext(
67
67
  sfuSctpChannelStorage,
68
68
  } = storageProvider;
69
69
 
70
- const [clients, sfus] = await Promise.all([clientStorage.getAll(observedCalls.clientIds()), sfuStorage.getAll([])]);
70
+ const [
71
+ [
72
+ clients,
73
+ peerConnections,
74
+ inboundAudioTrackEntries,
75
+ inboundVideoTrackEntries,
76
+ outboundAudioTrackEntries,
77
+ outboundVideoTrackEntries,
78
+ ],
79
+ [
80
+ sfus,
81
+ sfuTransports,
82
+ sfuInboundRtpPads,
83
+ sfuOutboundRtpPads,
84
+ sfuSctpChannels
85
+ ]
86
+ ] = await Promise.all([
87
+ Promise.all([
88
+ clientStorage.getAll(observedCalls.clientIds()),
89
+ peerConnectionStorage.getAll(observedCalls.peerConnectionIds()),
90
+ inboundTrackStorage.getAll(observedCalls.inboundAudioTrackIds()),
91
+ inboundTrackStorage.getAll(observedCalls.inboundVideoTrackIds()),
92
+ outboundTrackStorage.getAll(observedCalls.outboundAudioTrackIds()),
93
+ outboundTrackStorage.getAll(observedCalls.outboundVideoTrackIds()),
94
+ ]),
95
+ Promise.all([
96
+ sfuStorage.getAll(observedSfus.sfuIds()),
97
+ sfuTransportStorage.getAll(observedSfus.sfuTransportIds()),
98
+ sfuInboundRtpPadStorage.getAll(observedCalls.peerConnectionIds()),
99
+ sfuOutboundRtpPadStorage.getAll(observedCalls.peerConnectionIds()),
100
+ sfuSctpChannelStorage.getAll(observedCalls.peerConnectionIds()),
101
+ ])
102
+ ]);
71
103
 
72
- const peerConnectionIds = Array.from(clients.values()).flatMap((client) => client.peerConnectionIds);
104
+ // const peerConnectionIds = Array.from(clients.values()).flatMap((client) => client.peerConnectionIds);
73
105
 
74
- const sfuTransportIds = Array.from(sfus.values()).flatMap((sfu) => sfu.sfuTransportIds);
106
+ // const sfuTransportIds = Array.from(sfus.values()).flatMap((sfu) => sfu.sfuTransportIds);
75
107
 
76
- const [peerConnections, sfuTransports] = await Promise.all([
77
- peerConnectionStorage.getAll(peerConnectionIds),
78
- sfuTransportStorage.getAll(sfuTransportIds),
79
- ]);
108
+ // const [peerConnections, sfuTransports] = await Promise.all([
109
+ // peerConnectionStorage.getAll(peerConnectionIds),
110
+ // sfuTransportStorage.getAll(sfuTransportIds),
111
+ // ]);
80
112
 
81
- const peerConnectionValues = Array.from(peerConnections.values());
82
- const inboundTrackIds = peerConnectionValues.flatMap((pc) => pc.inboundTrackIds);
83
- const outboundTrackIds = peerConnectionValues.flatMap((pc) => pc.outboundTrackIds);
84
-
85
- const sfuTransportValues = Array.from(sfuTransports.values());
86
- const sfuInboundRtpPadIds = sfuTransportValues.flatMap((sfuTransport) => sfuTransport.inboundRtpPadIds);
87
- const sfuOutboundRtpPadIds = sfuTransportValues.flatMap((sfuTransport) => sfuTransport.outboundRtpPadIds);
88
- const sfuSctpChannelIds = sfuTransportValues.flatMap((sfuTransport) => sfuTransport.sctpChannelIds);
89
-
90
- const [inboundTracks, outboundTracks, sfuInboundRtpPads, sfuOutboundRtpPads, sfuSctpChannels] = await Promise.all([
91
- inboundTrackStorage.getAll(inboundTrackIds),
92
- outboundTrackStorage.getAll(outboundTrackIds),
93
- sfuInboundRtpPadStorage.getAll(sfuInboundRtpPadIds),
94
- sfuOutboundRtpPadStorage.getAll(sfuOutboundRtpPadIds),
95
- sfuSctpChannelStorage.getAll(sfuSctpChannelIds),
96
- ]);
113
+ // const peerConnectionValues = Array.from(peerConnections.values());
114
+ // const inboundTrackIds = peerConnectionValues.flatMap((pc) => pc.inboundTrackIds);
115
+ // const outboundTrackIds = peerConnectionValues.flatMap((pc) => pc.outboundTrackIds);
116
+
117
+ // const sfuTransportValues = Array.from(sfuTransports.values());
118
+ // const sfuInboundRtpPadIds = sfuTransportValues.flatMap((sfuTransport) => sfuTransport.inboundRtpPadIds);
119
+ // const sfuOutboundRtpPadIds = sfuTransportValues.flatMap((sfuTransport) => sfuTransport.outboundRtpPadIds);
120
+ // const sfuSctpChannelIds = sfuTransportValues.flatMap((sfuTransport) => sfuTransport.sctpChannelIds);
121
+
122
+ // const [inboundTracks, outboundTracks, sfuInboundRtpPads, sfuOutboundRtpPads, sfuSctpChannels] = await Promise.all([
123
+ // inboundTrackStorage.getAll(inboundTrackIds),
124
+ // outboundTrackStorage.getAll(outboundTrackIds),
125
+ // sfuInboundRtpPadStorage.getAll(sfuInboundRtpPadIds),
126
+ // sfuOutboundRtpPadStorage.getAll(sfuOutboundRtpPadIds),
127
+ // sfuSctpChannelStorage.getAll(sfuSctpChannelIds),
128
+ // ]);
97
129
 
98
- const inboundTrackEntries = Array.from(inboundTracks);
99
- const outboundTrackEntries = Array.from(outboundTracks);
130
+ // const inboundTrackEntries = Array.from(inboundTracks);
131
+ // const outboundTrackEntries = Array.from(outboundTracks);
100
132
 
101
- const inboundAudioTrackEntries = inboundTrackEntries.filter((e) => e[1].kind === 'audio');
102
- const inboundVideoTrackEntries = inboundTrackEntries.filter((e) => e[1].kind === 'video');
103
- const outboundAudioTrackEntries = outboundTrackEntries.filter((e) => e[1].kind === 'audio');
104
- const outboundVideoTrackEntries = outboundTrackEntries.filter((e) => e[1].kind === 'video');
133
+ // const inboundAudioTrackEntries = inboundTrackEntries.filter((e) => e[1].kind === 'audio');
134
+ // const inboundVideoTrackEntries = inboundTrackEntries.filter((e) => e[1].kind === 'video');
135
+ // const outboundAudioTrackEntries = outboundTrackEntries.filter((e) => e[1].kind === 'audio');
136
+ // const outboundVideoTrackEntries = outboundTrackEntries.filter((e) => e[1].kind === 'video');
105
137
 
106
138
  const transactionContext: TransactionContext = {
107
139
  id: uuid(),
@@ -1,6 +1,8 @@
1
1
  import { ReportsCollector } from '../common/ReportsCollector';
2
2
  import { StorageProvider } from '../storages/StorageProvider';
3
3
  import { createCommitTransactionMiddleware } from './CommitTransactionMiddleware';
4
+ import { createDeleteOutdatedCallEntries } from './DeleteOutdatedCallEntries';
5
+ import { createDeleteOutdatedSfuEntries } from './DeleteOutdatedSfuEntries';
4
6
  import { Processor, createProcessor } from './Processor';
5
7
  import { TransactionContext } from './TransactionContext';
6
8
  import { createVisitObservedCallsMiddleware } from './VisitObservedCallsMiddleware';
@@ -9,12 +11,16 @@ import { createVisitObservedSfusMiddleware } from './VisitObservedSfusMiddleware
9
11
  export function createTransactionProcessor(
10
12
  storageProvider: StorageProvider,
11
13
  reportsCollector: ReportsCollector,
12
- fetchSamples: boolean
14
+ fetchSamples: boolean,
15
+ maxIdleTimeInMs: BigInt,
16
+ findRemoteMatches?: boolean,
13
17
  ): Processor<TransactionContext> {
14
18
  return createProcessor(
15
19
  // all of these middlewares must execute sequentially!
16
- createVisitObservedCallsMiddleware(reportsCollector, fetchSamples),
20
+ createVisitObservedCallsMiddleware(storageProvider, reportsCollector, fetchSamples, findRemoteMatches),
17
21
  createVisitObservedSfusMiddleware(reportsCollector, fetchSamples),
22
+ createDeleteOutdatedCallEntries(storageProvider, maxIdleTimeInMs),
23
+ createDeleteOutdatedSfuEntries(storageProvider, maxIdleTimeInMs),
18
24
 
19
25
  // must be the last one!
20
26
  createCommitTransactionMiddleware(storageProvider, reportsCollector)