@fishjam-cloud/ts-client 0.5.5 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/FishjamClient.d.ts +6 -1
- package/dist/src/FishjamClient.js +5 -1
- package/dist/src/connectEventsHandler.d.ts +2 -0
- package/dist/src/connectEventsHandler.js +22 -0
- package/dist/src/webrtc/ConnectionManager.d.ts +0 -2
- package/dist/src/webrtc/ConnectionManager.js +0 -11
- package/dist/src/webrtc/tracks/Local.d.ts +0 -1
- package/dist/src/webrtc/tracks/Local.js +0 -10
- package/dist/src/webrtc/tracks/LocalTrack.d.ts +1 -1
- package/dist/src/webrtc/tracks/LocalTrackManager.js +0 -1
- package/dist/src/webrtc/webRTCEndpoint.js +0 -2
- package/package.json +11 -12
|
@@ -12,6 +12,11 @@ export type Component<PeerMetadata, TrackMetadata> = Omit<Endpoint<PeerMetadata,
|
|
|
12
12
|
* Events emitted by the client with their arguments.
|
|
13
13
|
*/
|
|
14
14
|
export interface MessageEvents<PeerMetadata, TrackMetadata> {
|
|
15
|
+
/**
|
|
16
|
+
* Emitted when connect method invoked
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
connectionStarted: () => void;
|
|
15
20
|
/**
|
|
16
21
|
* Emitted when the websocket connection is closed
|
|
17
22
|
*
|
|
@@ -210,7 +215,7 @@ export declare class FishjamClient<PeerMetadata, TrackMetadata> extends FishjamC
|
|
|
210
215
|
*
|
|
211
216
|
* @param {ConnectConfig} config - Configuration object for the client
|
|
212
217
|
*/
|
|
213
|
-
connect(config: ConnectConfig<PeerMetadata>): void
|
|
218
|
+
connect(config: ConnectConfig<PeerMetadata>): Promise<void>;
|
|
214
219
|
private initConnection;
|
|
215
220
|
private getUrl;
|
|
216
221
|
private initWebsocket;
|
|
@@ -3,6 +3,7 @@ import { EventEmitter } from 'events';
|
|
|
3
3
|
import { PeerMessage } from './protos';
|
|
4
4
|
import { ReconnectManager } from './reconnection';
|
|
5
5
|
import { isAuthError } from './auth';
|
|
6
|
+
import { connectEventsHandler } from './connectEventsHandler';
|
|
6
7
|
const STATISTICS_INTERVAL = 10_000;
|
|
7
8
|
const isPeer = (endpoint) => endpoint.type === 'webrtc';
|
|
8
9
|
const isComponent = (endpoint) => endpoint.type === 'recording' ||
|
|
@@ -77,10 +78,13 @@ export class FishjamClient extends EventEmitter {
|
|
|
77
78
|
*
|
|
78
79
|
* @param {ConnectConfig} config - Configuration object for the client
|
|
79
80
|
*/
|
|
80
|
-
connect(config) {
|
|
81
|
+
async connect(config) {
|
|
82
|
+
this.emit('connectionStarted');
|
|
83
|
+
const result = connectEventsHandler(this);
|
|
81
84
|
this.reconnectManager.reset(config.peerMetadata);
|
|
82
85
|
this.connectConfig = config;
|
|
83
86
|
this.initConnection(config.peerMetadata);
|
|
87
|
+
return result;
|
|
84
88
|
}
|
|
85
89
|
async initConnection(peerMetadata) {
|
|
86
90
|
if (this.status === 'initialized') {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function connectEventsHandler(fishjamClient) {
|
|
2
|
+
return new Promise((resolve, reject) => {
|
|
3
|
+
const onSuccess = () => {
|
|
4
|
+
clearCallbacks();
|
|
5
|
+
resolve();
|
|
6
|
+
};
|
|
7
|
+
const onError = () => {
|
|
8
|
+
clearCallbacks();
|
|
9
|
+
reject();
|
|
10
|
+
};
|
|
11
|
+
fishjamClient.on('joined', onSuccess);
|
|
12
|
+
fishjamClient.on('joinError', onError);
|
|
13
|
+
fishjamClient.on('authError', onError);
|
|
14
|
+
fishjamClient.on('socketError', onError);
|
|
15
|
+
const clearCallbacks = () => {
|
|
16
|
+
fishjamClient.removeListener('joined', onSuccess);
|
|
17
|
+
fishjamClient.removeListener('joinError', onError);
|
|
18
|
+
fishjamClient.removeListener('authError', onError);
|
|
19
|
+
fishjamClient.removeListener('socketError', onError);
|
|
20
|
+
};
|
|
21
|
+
});
|
|
22
|
+
}
|
|
@@ -15,14 +15,12 @@ export declare class ConnectionManager {
|
|
|
15
15
|
*/
|
|
16
16
|
private getIceServers;
|
|
17
17
|
getConnection: () => RTCPeerConnection;
|
|
18
|
-
setTransceiversToReadOnly: () => void;
|
|
19
18
|
addTransceiversIfNeeded: (serverTracks: Map<string, number>) => void;
|
|
20
19
|
private getNeededTransceiversTypes;
|
|
21
20
|
addTransceiver: (track: MediaStreamTrack, transceiverConfig: RTCRtpTransceiverInit) => void;
|
|
22
21
|
setOnTrackReady: (onTrackReady: (event: RTCTrackEvent) => void) => void;
|
|
23
22
|
setRemoteDescription: (data: RTCSessionDescriptionInit) => Promise<void>;
|
|
24
23
|
isTrackInUse: (track: MediaStreamTrack) => boolean;
|
|
25
|
-
setTransceiverDirection: () => void;
|
|
26
24
|
removeTrack: (sender: RTCRtpSender) => void;
|
|
27
25
|
findSender: (mediaStreamTrackId: MediaStreamTrackId) => RTCRtpSender;
|
|
28
26
|
addIceCandidate: (iceCandidate: RTCIceCandidate) => Promise<void>;
|
|
@@ -34,9 +34,6 @@ export class ConnectionManager {
|
|
|
34
34
|
getConnection = () => {
|
|
35
35
|
return this.connection;
|
|
36
36
|
};
|
|
37
|
-
setTransceiversToReadOnly = () => {
|
|
38
|
-
this.connection.getTransceivers().forEach((transceiver) => (transceiver.direction = 'sendonly'));
|
|
39
|
-
};
|
|
40
37
|
addTransceiversIfNeeded = (serverTracks) => {
|
|
41
38
|
const recvTransceivers = this.connection.getTransceivers().filter((elem) => elem.direction === 'recvonly');
|
|
42
39
|
['audio', 'video']
|
|
@@ -58,14 +55,6 @@ export class ConnectionManager {
|
|
|
58
55
|
await this.connection.setRemoteDescription(data);
|
|
59
56
|
};
|
|
60
57
|
isTrackInUse = (track) => this.connection.getSenders().some((val) => val.track === track);
|
|
61
|
-
setTransceiverDirection = () => {
|
|
62
|
-
this.connection
|
|
63
|
-
.getTransceivers()
|
|
64
|
-
.filter((transceiver) => transceiver.direction === 'sendrecv')
|
|
65
|
-
.forEach((transceiver) => {
|
|
66
|
-
transceiver.direction = 'sendonly';
|
|
67
|
-
});
|
|
68
|
-
};
|
|
69
58
|
removeTrack = (sender) => {
|
|
70
59
|
this.connection.removeTrack(sender);
|
|
71
60
|
};
|
|
@@ -28,7 +28,6 @@ export declare class Local<EndpointMetadata, TrackMetadata> {
|
|
|
28
28
|
updateConnection: (connection: ConnectionManager) => void;
|
|
29
29
|
createSdpOfferEvent: (offer: RTCSessionDescriptionInit) => MediaEvent;
|
|
30
30
|
addTrack: (connection: ConnectionManager | undefined, trackId: string, track: MediaStreamTrack, stream: MediaStream, trackMetadata: TrackMetadata | undefined, simulcastConfig: SimulcastConfig, maxBandwidth: TrackBandwidthLimit) => LocalTrack<EndpointMetadata, TrackMetadata>;
|
|
31
|
-
disableAllLocalTrackEncodings: () => Promise<void>;
|
|
32
31
|
getTrackByMidOrNull: (mid: string) => LocalTrack<EndpointMetadata, TrackMetadata> | null;
|
|
33
32
|
removeTrack: (trackId: TrackId) => void;
|
|
34
33
|
replaceTrack: (webrtc: WebRTCEndpoint<EndpointMetadata, TrackMetadata>, trackId: TrackId, newTrack: MediaStreamTrack | null) => Promise<void>;
|
|
@@ -74,16 +74,6 @@ export class Local {
|
|
|
74
74
|
this.localTracks[trackId] = trackManager;
|
|
75
75
|
return trackManager;
|
|
76
76
|
};
|
|
77
|
-
disableAllLocalTrackEncodings = async () => {
|
|
78
|
-
// TODO: Why are we disabling already disabled encodings?
|
|
79
|
-
// I think this part of the code is invoked to mutate RTCRtpSender.getParameters().encodings.active.
|
|
80
|
-
// We should probably implement a separate method for that, because disabling already disabled tracks seems weird.
|
|
81
|
-
for (const [trackId, trackManager] of Object.entries(this.localTracks)) {
|
|
82
|
-
for (const encoding of trackManager.getDisabledEncodings()) {
|
|
83
|
-
await this.disableLocalTrackEncoding(trackId, encoding);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
77
|
getTrackByMidOrNull = (mid) => {
|
|
88
78
|
return Object.values(this.localTracks).find((track) => track.mLineId === mid) ?? null;
|
|
89
79
|
};
|
|
@@ -58,5 +58,5 @@ export declare class LocalTrack<EndpointMetadata, TrackMetadata> implements Trac
|
|
|
58
58
|
setMLineId: (mLineId: MLineId) => void;
|
|
59
59
|
private isNotSimulcastTrack;
|
|
60
60
|
getTrackBitrates: () => Bitrates;
|
|
61
|
-
createTrackVariantBitratesEvent: () => import("
|
|
61
|
+
createTrackVariantBitratesEvent: () => import("..").MediaEvent;
|
|
62
62
|
}
|
|
@@ -48,7 +48,6 @@ export class LocalTrackManager {
|
|
|
48
48
|
const trackManager = this.local.addTrack(this.connection, trackId, track, stream, trackMetadata, simulcastConfig, maxBandwidth);
|
|
49
49
|
if (this.connection) {
|
|
50
50
|
trackManager.addTrackToConnection();
|
|
51
|
-
this.connection.setTransceiverDirection();
|
|
52
51
|
}
|
|
53
52
|
const mediaEvent = generateCustomEvent({ type: 'renegotiateTracks' });
|
|
54
53
|
this.sendMediaEvent(mediaEvent);
|
|
@@ -265,7 +265,6 @@ export class WebRTCEndpoint extends EventEmitter {
|
|
|
265
265
|
});
|
|
266
266
|
try {
|
|
267
267
|
await this.connectionManager.setRemoteDescription(data);
|
|
268
|
-
await this.local.disableAllLocalTrackEncodings();
|
|
269
268
|
}
|
|
270
269
|
catch (err) {
|
|
271
270
|
console.error(err);
|
|
@@ -626,7 +625,6 @@ export class WebRTCEndpoint extends EventEmitter {
|
|
|
626
625
|
connection.getConnection().addEventListener('iceconnectionstatechange', onIceConnectionStateChange);
|
|
627
626
|
this.commandsQueue.initConnection(connection);
|
|
628
627
|
this.local.addAllTracksToConnection();
|
|
629
|
-
connection.setTransceiversToReadOnly();
|
|
630
628
|
}
|
|
631
629
|
this.localTrackManager.updateSenders();
|
|
632
630
|
const tracks = new Map(Object.entries(offerData.data.tracksTypes));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fishjam-cloud/ts-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Typescript client library for Fishjam Cloud",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Fishjam Cloud Team",
|
|
@@ -41,7 +41,6 @@
|
|
|
41
41
|
"test": "vitest run tests/**",
|
|
42
42
|
"test:e2e": "NODE_OPTIONS=--dns-result-order=ipv4first playwright test",
|
|
43
43
|
"test:coverage": "vitest run tests/** --coverage",
|
|
44
|
-
"typecheck": "tsc",
|
|
45
44
|
"prepare": "tsc",
|
|
46
45
|
"prepack": "yarn build"
|
|
47
46
|
},
|
|
@@ -52,22 +51,22 @@
|
|
|
52
51
|
"uuid": "^10.0.0"
|
|
53
52
|
},
|
|
54
53
|
"devDependencies": {
|
|
55
|
-
"@playwright/test": "^1.
|
|
54
|
+
"@playwright/test": "^1.47.1",
|
|
56
55
|
"@types/events": "^3.0.3",
|
|
57
|
-
"@types/node": "^22.
|
|
56
|
+
"@types/node": "^22.5.5",
|
|
58
57
|
"@types/uuid": "^10.0.0",
|
|
59
|
-
"@vitest/coverage-v8": "^2.
|
|
58
|
+
"@vitest/coverage-v8": "^2.1.1",
|
|
60
59
|
"fake-mediastreamtrack": "^1.2.0",
|
|
61
|
-
"husky": "^9.1.
|
|
62
|
-
"lint-staged": "^15.2.
|
|
60
|
+
"husky": "^9.1.6",
|
|
61
|
+
"lint-staged": "^15.2.10",
|
|
63
62
|
"react": "^18.2.0",
|
|
64
|
-
"ts-proto": "^2.0
|
|
63
|
+
"ts-proto": "^2.2.0",
|
|
65
64
|
"typed-emitter": "^2.1.0",
|
|
66
|
-
"typedoc": "^0.26.
|
|
65
|
+
"typedoc": "^0.26.7",
|
|
67
66
|
"typedoc-plugin-external-resolver": "^1.0.3",
|
|
68
|
-
"typedoc-plugin-mdn-links": "^3.2.
|
|
69
|
-
"typescript": "^5.
|
|
70
|
-
"vitest": "^2.
|
|
67
|
+
"typedoc-plugin-mdn-links": "^3.2.12",
|
|
68
|
+
"typescript": "^5.6.2",
|
|
69
|
+
"vitest": "^2.1.1",
|
|
71
70
|
"zod": "^3.23.6"
|
|
72
71
|
},
|
|
73
72
|
"lint-staged": {
|