@fishjam-cloud/webrtc-client 0.25.1 → 0.25.2

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 (85) hide show
  1. package/dist/protobufs/fishjam/media_events/peer/peer.d.ts +130 -0
  2. package/dist/protobufs/fishjam/media_events/peer/peer.js +1283 -0
  3. package/dist/protobufs/fishjam/media_events/server/server.d.ts +197 -0
  4. package/dist/protobufs/fishjam/media_events/server/server.js +2121 -0
  5. package/dist/protobufs/fishjam/media_events/shared.d.ts +48 -0
  6. package/dist/protobufs/fishjam/media_events/shared.js +315 -0
  7. package/dist/webrtc-client/src/CommandsQueue.d.ts +23 -0
  8. package/dist/webrtc-client/src/CommandsQueue.js +87 -0
  9. package/dist/webrtc-client/src/ConnectionManager.d.ts +17 -0
  10. package/dist/webrtc-client/src/ConnectionManager.js +49 -0
  11. package/dist/webrtc-client/src/bitrate.d.ts +12 -0
  12. package/dist/webrtc-client/src/bitrate.js +15 -0
  13. package/dist/webrtc-client/src/dataChannels/DataChannel.d.ts +56 -0
  14. package/dist/webrtc-client/src/dataChannels/DataChannel.js +144 -0
  15. package/dist/webrtc-client/src/dataChannels/DataChannelManager.d.ts +83 -0
  16. package/dist/webrtc-client/src/dataChannels/DataChannelManager.js +184 -0
  17. package/dist/webrtc-client/src/deferred.d.ts +8 -0
  18. package/dist/webrtc-client/src/deferred.js +17 -0
  19. package/dist/webrtc-client/src/index.d.ts +6 -0
  20. package/dist/webrtc-client/src/index.js +4 -0
  21. package/dist/webrtc-client/src/internal.d.ts +27 -0
  22. package/dist/webrtc-client/src/internal.js +18 -0
  23. package/dist/webrtc-client/src/logger.d.ts +5 -0
  24. package/dist/webrtc-client/src/logger.js +15 -0
  25. package/dist/webrtc-client/src/mediaEvent.d.ts +13 -0
  26. package/dist/webrtc-client/src/mediaEvent.js +20 -0
  27. package/dist/webrtc-client/src/tracks/Local.d.ts +49 -0
  28. package/dist/webrtc-client/src/tracks/Local.js +243 -0
  29. package/dist/webrtc-client/src/tracks/LocalTrack.d.ts +61 -0
  30. package/dist/webrtc-client/src/tracks/LocalTrack.js +212 -0
  31. package/dist/webrtc-client/src/tracks/LocalTrackManager.d.ts +39 -0
  32. package/dist/webrtc-client/src/tracks/LocalTrackManager.js +76 -0
  33. package/dist/webrtc-client/src/tracks/Remote.d.ts +32 -0
  34. package/dist/webrtc-client/src/tracks/Remote.js +165 -0
  35. package/dist/webrtc-client/src/tracks/RemoteTrack.d.ts +40 -0
  36. package/dist/webrtc-client/src/tracks/RemoteTrack.js +71 -0
  37. package/dist/webrtc-client/src/tracks/TrackCommon.d.ts +9 -0
  38. package/dist/webrtc-client/src/tracks/TrackCommon.js +1 -0
  39. package/dist/webrtc-client/src/tracks/bandwidth.d.ts +1 -0
  40. package/dist/webrtc-client/src/tracks/bandwidth.js +27 -0
  41. package/dist/webrtc-client/src/tracks/encodings.d.ts +3 -0
  42. package/dist/webrtc-client/src/tracks/encodings.js +11 -0
  43. package/dist/webrtc-client/src/tracks/muteTrackUtils.d.ts +3 -0
  44. package/dist/webrtc-client/src/tracks/muteTrackUtils.js +23 -0
  45. package/dist/webrtc-client/src/tracks/transceivers.d.ts +2 -0
  46. package/dist/webrtc-client/src/tracks/transceivers.js +93 -0
  47. package/dist/webrtc-client/src/types.d.ts +340 -0
  48. package/dist/webrtc-client/src/types.js +1 -0
  49. package/dist/webrtc-client/src/webRTCEndpoint.d.ts +350 -0
  50. package/dist/webrtc-client/src/webRTCEndpoint.js +747 -0
  51. package/dist/webrtc-client/tests/events/bandwidthEstimationEvent.test.d.ts +1 -0
  52. package/dist/webrtc-client/tests/events/bandwidthEstimationEvent.test.js +21 -0
  53. package/dist/webrtc-client/tests/events/connectedEvent.test.d.ts +1 -0
  54. package/dist/webrtc-client/tests/events/connectedEvent.test.js +70 -0
  55. package/dist/webrtc-client/tests/events/encodingSwitchedEvent.test.d.ts +1 -0
  56. package/dist/webrtc-client/tests/events/encodingSwitchedEvent.test.js +60 -0
  57. package/dist/webrtc-client/tests/events/endpointAddedEvent.test.d.ts +1 -0
  58. package/dist/webrtc-client/tests/events/endpointAddedEvent.test.js +57 -0
  59. package/dist/webrtc-client/tests/events/endpointRemovedEvent.test.d.ts +1 -0
  60. package/dist/webrtc-client/tests/events/endpointRemovedEvent.test.js +64 -0
  61. package/dist/webrtc-client/tests/events/endpointUpdatedEvent.test.d.ts +1 -0
  62. package/dist/webrtc-client/tests/events/endpointUpdatedEvent.test.js +78 -0
  63. package/dist/webrtc-client/tests/events/trackAddedEvent.test.d.ts +1 -0
  64. package/dist/webrtc-client/tests/events/trackAddedEvent.test.js +84 -0
  65. package/dist/webrtc-client/tests/events/trackRemovedEvent.test.d.ts +1 -0
  66. package/dist/webrtc-client/tests/events/trackRemovedEvent.test.js +26 -0
  67. package/dist/webrtc-client/tests/events/trackUpdatedEvent.test.d.ts +1 -0
  68. package/dist/webrtc-client/tests/events/trackUpdatedEvent.test.js +77 -0
  69. package/dist/webrtc-client/tests/events/vadNotificationEvent.test.d.ts +1 -0
  70. package/dist/webrtc-client/tests/events/vadNotificationEvent.test.js +42 -0
  71. package/dist/webrtc-client/tests/fixtures.d.ts +27 -0
  72. package/dist/webrtc-client/tests/fixtures.js +172 -0
  73. package/dist/webrtc-client/tests/methods/addTrackMethod.test.d.ts +1 -0
  74. package/dist/webrtc-client/tests/methods/addTrackMethod.test.js +46 -0
  75. package/dist/webrtc-client/tests/methods/cleanUpMethod.test.d.ts +1 -0
  76. package/dist/webrtc-client/tests/methods/cleanUpMethod.test.js +14 -0
  77. package/dist/webrtc-client/tests/methods/connectMethod.test.d.ts +1 -0
  78. package/dist/webrtc-client/tests/methods/connectMethod.test.js +40 -0
  79. package/dist/webrtc-client/tests/methods/disconnectMethod.test.d.ts +1 -0
  80. package/dist/webrtc-client/tests/methods/disconnectMethod.test.js +29 -0
  81. package/dist/webrtc-client/tests/mocks.d.ts +5 -0
  82. package/dist/webrtc-client/tests/mocks.js +80 -0
  83. package/dist/webrtc-client/tests/utils.d.ts +3 -0
  84. package/dist/webrtc-client/tests/utils.js +56 -0
  85. package/package.json +3 -3
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Wrapper class for RTCDataChannel.
3
+ * Handles bidirectional data transmission.
4
+ * @internal
5
+ */
6
+ export class DataChannel {
7
+ type;
8
+ logger;
9
+ channel = null;
10
+ dataCallback = null;
11
+ openCallback = null;
12
+ errorCallback = null;
13
+ _status = 'init';
14
+ constructor(type, logger) {
15
+ this.type = type;
16
+ this.logger = logger;
17
+ }
18
+ /**
19
+ * Get the current status of the data channel
20
+ */
21
+ get status() {
22
+ return this._status;
23
+ }
24
+ /**
25
+ * Set the underlying RTCDataChannel and set up event listeners
26
+ */
27
+ setChannel(channel) {
28
+ this._status = 'creating';
29
+ this.channel = channel;
30
+ this.setupListeners();
31
+ }
32
+ /**
33
+ * Set callback to be called when the channel is opened
34
+ */
35
+ setOnOpen(callback) {
36
+ this.openCallback = callback;
37
+ }
38
+ /**
39
+ * Set callback to be called when the channel errors
40
+ */
41
+ setOnError(callback) {
42
+ this.errorCallback = callback;
43
+ }
44
+ /**
45
+ * Send data through the channel
46
+ * @param data - The data to send as Uint8Array
47
+ */
48
+ send(data) {
49
+ if (!this.channel || this._status !== 'open') {
50
+ this.logger.warn(`Cannot send data on ${this.type} channel: channel not ready (status: ${this._status})`);
51
+ return;
52
+ }
53
+ try {
54
+ this.channel.send(data);
55
+ }
56
+ catch (error) {
57
+ this.logger.error(`Error sending data on ${this.type} channel:`, error);
58
+ }
59
+ }
60
+ /**
61
+ * Set the callback for receiving data
62
+ * @param callback - Function to call when data is received
63
+ */
64
+ setCallback(callback) {
65
+ this.dataCallback = callback;
66
+ }
67
+ /**
68
+ * Close the data channel
69
+ */
70
+ close() {
71
+ if (this.channel) {
72
+ this.channel.close();
73
+ }
74
+ this._status = 'closed';
75
+ this.dataCallback = null;
76
+ }
77
+ /**
78
+ * Set up event listeners for the RTCDataChannel
79
+ * @private
80
+ */
81
+ setupListeners() {
82
+ if (!this.channel)
83
+ return;
84
+ this.channel.onopen = () => {
85
+ this._status = 'open';
86
+ this.logger.debug(`Data channel ${this.type} opened`);
87
+ this.openCallback?.();
88
+ };
89
+ this.channel.onclose = () => {
90
+ this._status = 'closed';
91
+ this.logger.debug(`Data channel ${this.type} closed`);
92
+ };
93
+ this.channel.onerror = (event) => {
94
+ this.logger.error(`Data channel ${this.type} error:`, event);
95
+ this.errorCallback?.(event);
96
+ };
97
+ this.channel.onmessage = (event) => {
98
+ this.handleMessage(event.data);
99
+ };
100
+ }
101
+ /**
102
+ * Handle incoming message data
103
+ * @private
104
+ */
105
+ handleMessage(data) {
106
+ if (!this.dataCallback) {
107
+ this.logger.warn(`Received data on ${this.type} channel but no callback is set`);
108
+ return;
109
+ }
110
+ try {
111
+ // Convert data to Uint8Array
112
+ let uint8Data;
113
+ if (data instanceof ArrayBuffer) {
114
+ uint8Data = new Uint8Array(data);
115
+ }
116
+ else if (data instanceof Uint8Array) {
117
+ uint8Data = data;
118
+ }
119
+ else if (typeof data === 'string') {
120
+ // Convert string to Uint8Array using TextEncoder
121
+ uint8Data = new TextEncoder().encode(data);
122
+ }
123
+ else if (data instanceof Blob) {
124
+ // For Blob, we need to read it asynchronously
125
+ const reader = new FileReader();
126
+ reader.onload = () => {
127
+ if (reader.result instanceof ArrayBuffer) {
128
+ this.dataCallback?.(new Uint8Array(reader.result));
129
+ }
130
+ };
131
+ reader.readAsArrayBuffer(data);
132
+ return;
133
+ }
134
+ else {
135
+ this.logger.warn(`Received unsupported data type on ${this.type} channel:`, typeof data);
136
+ return;
137
+ }
138
+ this.dataCallback(uint8Data);
139
+ }
140
+ catch (error) {
141
+ this.logger.error(`Error handling message on ${this.type} channel:`, error);
142
+ }
143
+ }
144
+ }
@@ -0,0 +1,83 @@
1
+ import type TypedEmitter from 'typed-emitter';
2
+ import type { DataChannelManagerEvents, DataChannelOptions, Logger } from '../types';
3
+ declare const DataChannelManager_base: new () => TypedEmitter<Required<DataChannelManagerEvents>>;
4
+ /**
5
+ * Manages data channels for WebRTC connection.
6
+ * Handles automatic creation and lifecycle of up to 2 bidirectional channels (reliable and lossy).
7
+ *
8
+ * Events:
9
+ * - `ready` - Emitted when both reliable and lossy data channel publishers are ready to send data.
10
+ * - `channelOpen` - Emitted when a data channel is opened. Payload includes the channel type.
11
+ * - `error` - Emitted when a data channel errors. Payload includes the channel type and error.
12
+ * - `data` - Emitted when data is received on any data channel. Payload includes channel type and binary data.
13
+ *
14
+ * @internal
15
+ */
16
+ export declare class DataChannelManager extends DataChannelManager_base {
17
+ private readonly createDataChannel;
18
+ private readonly triggerRenegotiation;
19
+ private readonly logger;
20
+ private reliableChannel;
21
+ private lossyChannel;
22
+ constructor(createDataChannel: (label: string, init: RTCDataChannelInit) => RTCDataChannel, triggerRenegotiation: () => void, logger: Logger);
23
+ /**
24
+ * Initialize channels and trigger renegotiation.
25
+ * Returns when both channels are open or throws if any channel errors.
26
+ */
27
+ connect(): Promise<void>;
28
+ /**
29
+ * Wait for both channels to be ready or throw on error.
30
+ * @private
31
+ */
32
+ private waitForChannelsReady;
33
+ /**
34
+ * Publish data through a data channel.
35
+ * Throws an error if the channel doesn't exist or isn't ready.
36
+ * @param data - The data to send as Uint8Array
37
+ * @param options - Options specifying which channel to use
38
+ * @throws Error if the channel doesn't exist or isn't open
39
+ */
40
+ publishData(data: Uint8Array, options: DataChannelOptions): void;
41
+ /**
42
+ * Close all data channels and remove all event listeners.
43
+ * Called during cleanup/disconnect.
44
+ */
45
+ cleanup(): void;
46
+ /**
47
+ * Check if both data channels are open and ready to send data.
48
+ * @returns true if both channels are open and ready, false otherwise
49
+ */
50
+ getChannelsReadiness(): boolean;
51
+ private createChannels;
52
+ /**
53
+ * Create a single data channel.
54
+ * @private
55
+ */
56
+ private createChannel;
57
+ /**
58
+ * Called when a data channel opens.
59
+ * Emits channelOpen event and checks if both channels are open.
60
+ * @private
61
+ */
62
+ private onChannelOpen;
63
+ /**
64
+ * Called when a data channel errors.
65
+ * @private
66
+ */
67
+ private onChannelError;
68
+ /**
69
+ * Handle data received from a channel and emit the dataReceived event.
70
+ * @param type - The type of channel the data was received on
71
+ * @param data - The received binary data
72
+ * @private
73
+ */
74
+ private onDataReceived;
75
+ /**
76
+ * Get existing channel wrapper or create a new one (without RTCDataChannel).
77
+ * @param type - The type of channel
78
+ * @returns The DataChannel wrapper instance
79
+ * @private
80
+ */
81
+ private getOrCreateChannelWrapper;
82
+ }
83
+ export {};
@@ -0,0 +1,184 @@
1
+ import { EventEmitter } from 'events';
2
+ import { DataChannel } from './DataChannel';
3
+ /**
4
+ * Manages data channels for WebRTC connection.
5
+ * Handles automatic creation and lifecycle of up to 2 bidirectional channels (reliable and lossy).
6
+ *
7
+ * Events:
8
+ * - `ready` - Emitted when both reliable and lossy data channel publishers are ready to send data.
9
+ * - `channelOpen` - Emitted when a data channel is opened. Payload includes the channel type.
10
+ * - `error` - Emitted when a data channel errors. Payload includes the channel type and error.
11
+ * - `data` - Emitted when data is received on any data channel. Payload includes channel type and binary data.
12
+ *
13
+ * @internal
14
+ */
15
+ export class DataChannelManager extends EventEmitter {
16
+ createDataChannel;
17
+ triggerRenegotiation;
18
+ logger;
19
+ reliableChannel = null;
20
+ lossyChannel = null;
21
+ constructor(createDataChannel, triggerRenegotiation, logger) {
22
+ super();
23
+ this.createDataChannel = createDataChannel;
24
+ this.triggerRenegotiation = triggerRenegotiation;
25
+ this.logger = logger;
26
+ }
27
+ /**
28
+ * Initialize channels and trigger renegotiation.
29
+ * Returns when both channels are open or throws if any channel errors.
30
+ */
31
+ async connect() {
32
+ if (this.getChannelsReadiness())
33
+ return;
34
+ this.createChannels();
35
+ this.triggerRenegotiation();
36
+ await this.waitForChannelsReady();
37
+ }
38
+ /**
39
+ * Wait for both channels to be ready or throw on error.
40
+ * @private
41
+ */
42
+ waitForChannelsReady() {
43
+ if (this.getChannelsReadiness())
44
+ return Promise.resolve();
45
+ return new Promise((resolve, reject) => {
46
+ const onReady = () => {
47
+ cleanup();
48
+ resolve();
49
+ };
50
+ const onError = (type, error) => {
51
+ cleanup();
52
+ reject(new Error(`Data channel ${type} error: ${error}`));
53
+ };
54
+ const cleanup = () => {
55
+ this.removeListener('ready', onReady);
56
+ this.removeListener('error', onError);
57
+ };
58
+ this.on('ready', onReady);
59
+ this.on('error', onError);
60
+ });
61
+ }
62
+ /**
63
+ * Publish data through a data channel.
64
+ * Throws an error if the channel doesn't exist or isn't ready.
65
+ * @param data - The data to send as Uint8Array
66
+ * @param options - Options specifying which channel to use
67
+ * @throws Error if the channel doesn't exist or isn't open
68
+ */
69
+ publishData(data, options) {
70
+ const type = options.reliable ? 'reliable' : 'lossy';
71
+ const channel = type === 'reliable' ? this.reliableChannel : this.lossyChannel;
72
+ if (!channel) {
73
+ throw new Error(`Cannot publish data: ${type} channel not created. Call connectDataPublishers() first or enable negotiateOnConnect.`);
74
+ }
75
+ if (channel.status !== 'open') {
76
+ throw new Error(`Cannot publish data: ${type} channel not ready (status: ${channel.status}). Wait for dataChannelsReady event.`);
77
+ }
78
+ channel.send(data);
79
+ }
80
+ /**
81
+ * Close all data channels and remove all event listeners.
82
+ * Called during cleanup/disconnect.
83
+ */
84
+ cleanup() {
85
+ this.logger.warn('Cleaning up data channels');
86
+ if (this.reliableChannel) {
87
+ this.reliableChannel.close();
88
+ this.reliableChannel = null;
89
+ }
90
+ if (this.lossyChannel) {
91
+ this.lossyChannel.close();
92
+ this.lossyChannel = null;
93
+ }
94
+ this.removeAllListeners();
95
+ }
96
+ /**
97
+ * Check if both data channels are open and ready to send data.
98
+ * @returns true if both channels are open and ready, false otherwise
99
+ */
100
+ getChannelsReadiness() {
101
+ return this.reliableChannel?.status === 'open' && this.lossyChannel?.status === 'open';
102
+ }
103
+ createChannels() {
104
+ this.createChannel('reliable');
105
+ this.createChannel('lossy');
106
+ }
107
+ /**
108
+ * Create a single data channel.
109
+ * @private
110
+ */
111
+ createChannel(type) {
112
+ const channel = this.getOrCreateChannelWrapper(type);
113
+ if (channel.status !== 'init')
114
+ return;
115
+ const label = type;
116
+ const config = type === 'reliable' ? { ordered: true } : { ordered: false, maxRetransmits: 0 };
117
+ const rtcChannel = this.createDataChannel(label, config);
118
+ channel.setOnOpen(() => this.onChannelOpen(type));
119
+ channel.setOnError((error) => this.onChannelError(type, error));
120
+ channel.setChannel(rtcChannel);
121
+ this.logger.warn(`Created ${type} data channel`);
122
+ }
123
+ /**
124
+ * Called when a data channel opens.
125
+ * Emits channelOpen event and checks if both channels are open.
126
+ * @private
127
+ */
128
+ onChannelOpen(type) {
129
+ this.logger.warn(`Data channel ${type} opened`);
130
+ this.emit('channelOpen', type);
131
+ // Check if both channels are now open
132
+ const bothReady = this.reliableChannel &&
133
+ this.reliableChannel.status === 'open' &&
134
+ this.lossyChannel &&
135
+ this.lossyChannel.status === 'open';
136
+ if (bothReady) {
137
+ this.logger.warn('All data publishers ready');
138
+ this.emit('ready');
139
+ }
140
+ }
141
+ /**
142
+ * Called when a data channel errors.
143
+ * @private
144
+ */
145
+ onChannelError(type, error) {
146
+ this.logger.error(`Data channel ${type} error:`, error);
147
+ this.emit('error', type, error);
148
+ }
149
+ /**
150
+ * Handle data received from a channel and emit the dataReceived event.
151
+ * @param type - The type of channel the data was received on
152
+ * @param data - The received binary data
153
+ * @private
154
+ */
155
+ onDataReceived(type, data) {
156
+ const payload = {
157
+ channelType: type,
158
+ data,
159
+ };
160
+ this.emit('data', payload);
161
+ }
162
+ /**
163
+ * Get existing channel wrapper or create a new one (without RTCDataChannel).
164
+ * @param type - The type of channel
165
+ * @returns The DataChannel wrapper instance
166
+ * @private
167
+ */
168
+ getOrCreateChannelWrapper(type) {
169
+ if (type === 'reliable') {
170
+ if (!this.reliableChannel) {
171
+ this.reliableChannel = new DataChannel(type, this.logger);
172
+ this.reliableChannel.setCallback((data) => this.onDataReceived(type, data));
173
+ }
174
+ return this.reliableChannel;
175
+ }
176
+ else {
177
+ if (!this.lossyChannel) {
178
+ this.lossyChannel = new DataChannel(type, this.logger);
179
+ this.lossyChannel.setCallback((data) => this.onDataReceived(type, data));
180
+ }
181
+ return this.lossyChannel;
182
+ }
183
+ }
184
+ }
@@ -0,0 +1,8 @@
1
+ export declare class Deferred<T, E = unknown> {
2
+ promise: Promise<T>;
3
+ private resolveFn;
4
+ private rejectFn;
5
+ constructor();
6
+ resolve(value: T): void;
7
+ reject(reason?: E): void;
8
+ }
@@ -0,0 +1,17 @@
1
+ export class Deferred {
2
+ promise;
3
+ resolveFn = () => null;
4
+ rejectFn = () => null;
5
+ constructor() {
6
+ this.promise = new Promise((resolve, reject) => {
7
+ this.resolveFn = resolve;
8
+ this.rejectFn = reject;
9
+ });
10
+ }
11
+ resolve(value) {
12
+ this.resolveFn(value);
13
+ }
14
+ reject(reason) {
15
+ this.rejectFn(reason);
16
+ }
17
+ }
@@ -0,0 +1,6 @@
1
+ export { getLogger } from './logger';
2
+ export type { MediaEvent, SerializedMediaEvent } from './mediaEvent';
3
+ export type { BandwidthLimit, DataCallback, DataChannelMessagePayload, DataChannelOptions, DataChannelType, EncodingReason, Endpoint, Logger, SimulcastBandwidthLimit, TrackBandwidthLimit, TrackContext, TrackContextEvents, TrackKind, VadStatus, WebRTCEndpointEvents, } from './types';
4
+ export { WebRTCEndpoint } from './webRTCEndpoint';
5
+ export { MediaEvent_Track_SimulcastConfig as SimulcastConfig } from '@fishjam-cloud/protobufs/server';
6
+ export { Variant } from '@fishjam-cloud/protobufs/shared';
@@ -0,0 +1,4 @@
1
+ export { getLogger } from './logger';
2
+ export { WebRTCEndpoint } from './webRTCEndpoint';
3
+ export { MediaEvent_Track_SimulcastConfig as SimulcastConfig } from '@fishjam-cloud/protobufs/server';
4
+ export { Variant } from '@fishjam-cloud/protobufs/shared';
@@ -0,0 +1,27 @@
1
+ import type { MediaEvent_Track_SimulcastConfig } from '@fishjam-cloud/protobufs/server';
2
+ import type { Variant } from '@fishjam-cloud/protobufs/shared';
3
+ import type TypedEmitter from 'typed-emitter';
4
+ import type { EncodingReason, Endpoint, TrackBandwidthLimit, TrackContext, TrackContextEvents, TrackKind, TrackNegotiationStatus, VadStatus } from './types';
5
+ export declare const isTrackKind: (kind: string) => kind is TrackKind;
6
+ declare const TrackContextImpl_base: new () => TypedEmitter<Required<TrackContextEvents>>;
7
+ export declare class TrackContextImpl extends TrackContextImpl_base implements TrackContext {
8
+ endpoint: Endpoint;
9
+ trackId: string;
10
+ track: MediaStreamTrack | null;
11
+ trackKind: TrackKind | null;
12
+ stream: MediaStream | null;
13
+ metadata?: unknown;
14
+ metadataParsingError?: any;
15
+ simulcastConfig?: MediaEvent_Track_SimulcastConfig;
16
+ maxBandwidth: TrackBandwidthLimit;
17
+ encoding?: Variant;
18
+ encodingReason?: EncodingReason;
19
+ vadStatus: VadStatus;
20
+ negotiationStatus: TrackNegotiationStatus;
21
+ pendingMetadataUpdate: boolean;
22
+ constructor(endpoint: Endpoint, trackId: string, metadata: any, simulcastConfig?: MediaEvent_Track_SimulcastConfig);
23
+ }
24
+ export type EndpointWithTrackContext = Omit<Endpoint, 'tracks'> & {
25
+ tracks: Map<string, TrackContextImpl>;
26
+ };
27
+ export {};
@@ -0,0 +1,18 @@
1
+ import EventEmitter from 'events';
2
+ export const isTrackKind = (kind) => kind === 'audio' || kind === 'video';
3
+ export class TrackContextImpl extends EventEmitter {
4
+ constructor(endpoint, trackId, metadata, simulcastConfig = { enabled: false, enabledVariants: [], disabledVariants: [] }) {
5
+ super();
6
+ this.endpoint = endpoint;
7
+ this.trackId = trackId;
8
+ this.track = null;
9
+ this.trackKind = null;
10
+ this.stream = null;
11
+ this.metadata = metadata;
12
+ this.simulcastConfig = simulcastConfig;
13
+ this.maxBandwidth = 0;
14
+ this.vadStatus = 'silence';
15
+ this.negotiationStatus = 'awaiting';
16
+ this.pendingMetadataUpdate = false;
17
+ }
18
+ }
@@ -0,0 +1,5 @@
1
+ export declare const getLogger: (enableLogging: boolean) => {
2
+ readonly debug: (arg: unknown, ...args: unknown[]) => void;
3
+ readonly warn: (arg: unknown, ...args: unknown[]) => void;
4
+ readonly error: (arg: unknown, ...args: unknown[]) => void;
5
+ };
@@ -0,0 +1,15 @@
1
+ const FISHJAM_PREFIX = '[FISHJAM]';
2
+ export const getLogger = (enableLogging) => ({
3
+ debug: (arg, ...args) => {
4
+ if (enableLogging)
5
+ console.debug(FISHJAM_PREFIX, arg, ...args);
6
+ },
7
+ warn: (arg, ...args) => {
8
+ if (enableLogging)
9
+ console.warn(FISHJAM_PREFIX, arg, ...args);
10
+ },
11
+ error: (arg, ...args) => {
12
+ if (enableLogging)
13
+ console.error(FISHJAM_PREFIX, arg, ...args);
14
+ },
15
+ });
@@ -0,0 +1,13 @@
1
+ import { MediaEvent as PeerMediaEvent } from '@fishjam-cloud/protobufs/peer';
2
+ import { MediaEvent as ServerMediaEvent } from '@fishjam-cloud/protobufs/server';
3
+ export type SerializedMediaEvent = Uint8Array;
4
+ export interface MediaEvent {
5
+ type: keyof PeerMediaEvent;
6
+ key?: string;
7
+ data?: any;
8
+ }
9
+ export declare function serializePeerMediaEvent(mediaEvent: PeerMediaEvent): Uint8Array;
10
+ export declare function serializeServerMediaEvent(mediaEvent: ServerMediaEvent): Uint8Array;
11
+ export declare function deserializeServerMediaEvent(serializedMediaEvent: SerializedMediaEvent): ServerMediaEvent;
12
+ export declare function deserializePeerMediaEvent(serializedMediaEvent: SerializedMediaEvent): PeerMediaEvent;
13
+ export declare function generateMediaEvent<T extends keyof PeerMediaEvent>(type: T, data?: PeerMediaEvent[T]): MediaEvent;
@@ -0,0 +1,20 @@
1
+ import { MediaEvent as PeerMediaEvent } from '@fishjam-cloud/protobufs/peer';
2
+ import { MediaEvent as ServerMediaEvent } from '@fishjam-cloud/protobufs/server';
3
+ export function serializePeerMediaEvent(mediaEvent) {
4
+ const encodedEvent = PeerMediaEvent.encode(mediaEvent).finish();
5
+ return encodedEvent;
6
+ }
7
+ export function serializeServerMediaEvent(mediaEvent) {
8
+ const encodedEvent = ServerMediaEvent.encode(mediaEvent).finish();
9
+ return encodedEvent;
10
+ }
11
+ export function deserializeServerMediaEvent(serializedMediaEvent) {
12
+ return ServerMediaEvent.decode(serializedMediaEvent);
13
+ }
14
+ export function deserializePeerMediaEvent(serializedMediaEvent) {
15
+ return PeerMediaEvent.decode(serializedMediaEvent);
16
+ }
17
+ export function generateMediaEvent(type, data) {
18
+ const mediaEvent = { type, data };
19
+ return mediaEvent;
20
+ }
@@ -0,0 +1,49 @@
1
+ import { MediaEvent as PeerMediaEvent, MediaEvent_SdpOffer } from '@fishjam-cloud/protobufs/peer';
2
+ import { type MediaEvent_Track_SimulcastConfig } from '@fishjam-cloud/protobufs/server';
3
+ import { Variant } from '@fishjam-cloud/protobufs/shared';
4
+ import type { ConnectionManager } from '../ConnectionManager';
5
+ import type { EndpointWithTrackContext } from '../internal';
6
+ import { TrackContextImpl } from '../internal';
7
+ import type { BandwidthLimit, RemoteTrackId, TrackBandwidthLimit, WebRTCEndpointEvents } from '../types';
8
+ import type { WebRTCEndpoint } from '../webRTCEndpoint';
9
+ import { LocalTrack } from './LocalTrack';
10
+ import type { EndpointId, TrackId } from './TrackCommon';
11
+ /**
12
+ * This class encapsulates methods related to handling the list of local tracks and local endpoint.
13
+ * It stores and mutates part of the client state for this local peer.
14
+ * It emits local events for local tracks and endpoints,
15
+ * and delegates mutation logic to the appropriate `LocalTrack` objects.
16
+ * It's responsible for creating `MidToTrackId` record which is required in `sdpOffer`
17
+ */
18
+ export declare class Local {
19
+ private readonly localTracks;
20
+ private readonly localEndpoint;
21
+ private readonly emit;
22
+ private readonly sendMediaEvent;
23
+ private connection;
24
+ constructor(emit: <E extends keyof Required<WebRTCEndpointEvents>>(event: E, ...args: Parameters<Required<WebRTCEndpointEvents>[E]>) => void, sendMediaEvent: (mediaEvent: PeerMediaEvent) => void);
25
+ updateSenders: () => void;
26
+ updateMLineIds: (midToTrackIds: Record<string, string>) => void;
27
+ updateConnection: (connection: ConnectionManager) => void;
28
+ createSdpOfferEvent: (sdpOffer: RTCSessionDescriptionInit) => MediaEvent_SdpOffer;
29
+ addTrack: (connection: ConnectionManager | undefined, trackId: string, track: MediaStreamTrack, stream: MediaStream, trackMetadata: unknown | undefined, simulcastConfig: MediaEvent_Track_SimulcastConfig, maxBandwidth: TrackBandwidthLimit) => LocalTrack;
30
+ getTrackByMidOrNull: (mid: string) => LocalTrack | null;
31
+ removeTrack: (trackId: TrackId) => void;
32
+ replaceTrack: (webrtc: WebRTCEndpoint, trackId: TrackId, newTrack: MediaStreamTrack | null) => Promise<void>;
33
+ setEndpointMetadata: (metadata: unknown) => void;
34
+ getEndpoint: () => EndpointWithTrackContext;
35
+ setTrackBandwidth: (trackId: string, bandwidth: BandwidthLimit) => Promise<void>;
36
+ getTrackIdToTrack: () => Map<RemoteTrackId, TrackContextImpl>;
37
+ setLocalEndpointId: (endpointId: EndpointId) => void;
38
+ setEncodingBandwidth: (trackId: TrackId, rid: Variant, bandwidth: BandwidthLimit) => Promise<void>;
39
+ updateEndpointMetadata: (metadata: unknown) => void;
40
+ updateLocalTrackMetadata: (trackId: TrackId, metadata: unknown) => void;
41
+ disableLocalTrackEncoding: (trackId: string, encoding: Variant) => Promise<void>;
42
+ enableLocalTrackEncoding: (trackId: TrackId, variant: Variant) => Promise<void>;
43
+ private getTrackIdToMetadataJson;
44
+ private getTrackIdToTrackBitrates;
45
+ private getMidToTrackId;
46
+ private getTransceiverMapping;
47
+ setLocalTrackStatusToOffered: () => void;
48
+ addAllTracksToConnection: () => void;
49
+ }