livekit-client 2.18.8 → 2.18.10
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/livekit-client.e2ee.worker.js +1 -1
- package/dist/livekit-client.e2ee.worker.js.map +1 -1
- package/dist/livekit-client.e2ee.worker.mjs +5609 -644
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +2898 -2431
- package/dist/livekit-client.esm.mjs.map +1 -1
- package/dist/livekit-client.pt.worker.js +2 -0
- package/dist/livekit-client.pt.worker.js.map +1 -0
- package/dist/livekit-client.pt.worker.mjs +5834 -0
- package/dist/livekit-client.pt.worker.mjs.map +1 -0
- package/dist/livekit-client.umd.js +1 -1
- package/dist/livekit-client.umd.js.map +1 -1
- package/dist/src/api/SignalClient.d.ts +2 -1
- package/dist/src/api/SignalClient.d.ts.map +1 -1
- package/dist/src/e2ee/E2eeManager.d.ts +8 -7
- package/dist/src/e2ee/E2eeManager.d.ts.map +1 -1
- package/dist/src/e2ee/types.d.ts +35 -8
- package/dist/src/e2ee/types.d.ts.map +1 -1
- package/dist/src/e2ee/utils.d.ts +5 -5
- package/dist/src/e2ee/utils.d.ts.map +1 -1
- package/dist/src/e2ee/worker/DataCryptor.d.ts +5 -5
- package/dist/src/e2ee/worker/DataCryptor.d.ts.map +1 -1
- package/dist/src/e2ee/worker/FrameCryptor.d.ts +21 -4
- package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
- package/dist/src/e2ee/worker/naluUtils.d.ts +1 -1
- package/dist/src/e2ee/worker/naluUtils.d.ts.map +1 -1
- package/dist/src/e2ee/worker/sifPayload.d.ts +7 -7
- package/dist/src/e2ee/worker/sifPayload.d.ts.map +1 -1
- package/dist/src/index.d.ts +4 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/options.d.ts +7 -0
- package/dist/src/options.d.ts.map +1 -1
- package/dist/src/packetTrailer/PacketTrailerManager.d.ts +49 -0
- package/dist/src/packetTrailer/PacketTrailerManager.d.ts.map +1 -0
- package/dist/src/packetTrailer/packetTrailer.d.ts +32 -0
- package/dist/src/packetTrailer/packetTrailer.d.ts.map +1 -0
- package/dist/src/packetTrailer/types.d.ts +57 -0
- package/dist/src/packetTrailer/types.d.ts.map +1 -0
- package/dist/src/packetTrailer/utils.d.ts +9 -0
- package/dist/src/packetTrailer/utils.d.ts.map +1 -0
- package/dist/src/packetTrailer/worker/packetTrailer.worker.d.ts +2 -0
- package/dist/src/packetTrailer/worker/packetTrailer.worker.d.ts.map +1 -0
- package/dist/src/room/RTCEngine.d.ts +2 -1
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +3 -1
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/data-track/LocalDataTrack.d.ts +2 -1
- package/dist/src/room/data-track/LocalDataTrack.d.ts.map +1 -1
- package/dist/src/room/data-track/RemoteDataTrack.d.ts +5 -1
- package/dist/src/room/data-track/RemoteDataTrack.d.ts.map +1 -1
- package/dist/src/room/data-track/depacketizer.d.ts +12 -4
- package/dist/src/room/data-track/depacketizer.d.ts.map +1 -1
- package/dist/src/room/data-track/frame.d.ts +3 -3
- package/dist/src/room/data-track/frame.d.ts.map +1 -1
- package/dist/src/room/data-track/incoming/IncomingDataTrackManager.d.ts +3 -1
- package/dist/src/room/data-track/incoming/IncomingDataTrackManager.d.ts.map +1 -1
- package/dist/src/room/data-track/incoming/pipeline.d.ts +4 -1
- package/dist/src/room/data-track/incoming/pipeline.d.ts.map +1 -1
- package/dist/src/room/data-track/outgoing/OutgoingDataTrackManager.d.ts +2 -2
- package/dist/src/room/data-track/outgoing/OutgoingDataTrackManager.d.ts.map +1 -1
- package/dist/src/room/data-track/outgoing/types.d.ts +4 -3
- package/dist/src/room/data-track/outgoing/types.d.ts.map +1 -1
- package/dist/src/room/data-track/packet/extensions.d.ts +4 -4
- package/dist/src/room/data-track/packet/extensions.d.ts.map +1 -1
- package/dist/src/room/data-track/packet/index.d.ts +5 -5
- package/dist/src/room/data-track/packet/index.d.ts.map +1 -1
- package/dist/src/room/data-track/packet/serializable.d.ts +1 -1
- package/dist/src/room/data-track/packet/serializable.d.ts.map +1 -1
- package/dist/src/room/data-track/types.d.ts +7 -0
- package/dist/src/room/data-track/types.d.ts.map +1 -1
- package/dist/src/room/events.d.ts +2 -2
- package/dist/src/room/participant/LocalParticipant.d.ts +3 -1
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/Participant.d.ts +1 -1
- package/dist/src/room/participant/Participant.d.ts.map +1 -1
- package/dist/src/room/track/PacketTrailerExtractor.d.ts +19 -0
- package/dist/src/room/track/PacketTrailerExtractor.d.ts.map +1 -0
- package/dist/src/room/track/RemoteVideoTrack.d.ts +16 -0
- package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/Track.d.ts +1 -1
- package/dist/src/room/track/Track.d.ts.map +1 -1
- package/dist/src/room/track/create.d.ts.map +1 -1
- package/dist/src/room/track/options.d.ts +10 -0
- package/dist/src/room/track/options.d.ts.map +1 -1
- package/dist/src/room/track/utils.d.ts.map +1 -1
- package/dist/src/room/utils.d.ts +4 -3
- package/dist/src/room/utils.d.ts.map +1 -1
- package/dist/src/test/MockMediaStreamTrack.d.ts.map +1 -1
- package/dist/src/utils/dataPacketBuffer.d.ts +1 -1
- package/dist/src/utils/dataPacketBuffer.d.ts.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/ts4.2/api/SignalClient.d.ts +2 -1
- package/dist/ts4.2/e2ee/E2eeManager.d.ts +8 -7
- package/dist/ts4.2/e2ee/types.d.ts +35 -8
- package/dist/ts4.2/e2ee/utils.d.ts +5 -5
- package/dist/ts4.2/e2ee/worker/DataCryptor.d.ts +5 -5
- package/dist/ts4.2/e2ee/worker/FrameCryptor.d.ts +21 -4
- package/dist/ts4.2/e2ee/worker/naluUtils.d.ts +1 -1
- package/dist/ts4.2/e2ee/worker/sifPayload.d.ts +7 -7
- package/dist/ts4.2/index.d.ts +5 -1
- package/dist/ts4.2/options.d.ts +7 -0
- package/dist/ts4.2/packetTrailer/PacketTrailerManager.d.ts +49 -0
- package/dist/ts4.2/packetTrailer/packetTrailer.d.ts +32 -0
- package/dist/ts4.2/packetTrailer/types.d.ts +57 -0
- package/dist/ts4.2/packetTrailer/utils.d.ts +9 -0
- package/dist/ts4.2/packetTrailer/worker/packetTrailer.worker.d.ts +2 -0
- package/dist/ts4.2/room/RTCEngine.d.ts +2 -1
- package/dist/ts4.2/room/Room.d.ts +3 -1
- package/dist/ts4.2/room/data-track/LocalDataTrack.d.ts +2 -1
- package/dist/ts4.2/room/data-track/RemoteDataTrack.d.ts +5 -1
- package/dist/ts4.2/room/data-track/depacketizer.d.ts +12 -4
- package/dist/ts4.2/room/data-track/frame.d.ts +3 -3
- package/dist/ts4.2/room/data-track/incoming/IncomingDataTrackManager.d.ts +3 -1
- package/dist/ts4.2/room/data-track/incoming/pipeline.d.ts +4 -1
- package/dist/ts4.2/room/data-track/outgoing/OutgoingDataTrackManager.d.ts +2 -2
- package/dist/ts4.2/room/data-track/outgoing/types.d.ts +4 -3
- package/dist/ts4.2/room/data-track/packet/extensions.d.ts +4 -4
- package/dist/ts4.2/room/data-track/packet/index.d.ts +5 -5
- package/dist/ts4.2/room/data-track/packet/serializable.d.ts +1 -1
- package/dist/ts4.2/room/data-track/types.d.ts +7 -0
- package/dist/ts4.2/room/events.d.ts +2 -2
- package/dist/ts4.2/room/participant/LocalParticipant.d.ts +3 -1
- package/dist/ts4.2/room/participant/Participant.d.ts +1 -1
- package/dist/ts4.2/room/track/PacketTrailerExtractor.d.ts +19 -0
- package/dist/ts4.2/room/track/RemoteVideoTrack.d.ts +16 -0
- package/dist/ts4.2/room/track/Track.d.ts +1 -1
- package/dist/ts4.2/room/track/options.d.ts +10 -0
- package/dist/ts4.2/room/utils.d.ts +4 -3
- package/dist/ts4.2/utils/dataPacketBuffer.d.ts +1 -1
- package/dist/ts4.2/version.d.ts +1 -1
- package/package.json +24 -16
- package/src/api/SignalClient.test.ts +102 -10
- package/src/api/SignalClient.ts +4 -2
- package/src/api/WebSocketStream.test.ts +0 -1
- package/src/e2ee/E2eeManager.ts +82 -30
- package/src/e2ee/types.ts +37 -8
- package/src/e2ee/utils.ts +7 -6
- package/src/e2ee/worker/DataCryptor.ts +6 -6
- package/src/e2ee/worker/FrameCryptor.test.ts +177 -4
- package/src/e2ee/worker/FrameCryptor.ts +94 -14
- package/src/e2ee/worker/ParticipantKeyHandler.test.ts +4 -4
- package/src/e2ee/worker/e2ee.worker.ts +13 -5
- package/src/e2ee/worker/naluUtils.ts +4 -4
- package/src/e2ee/worker/sifPayload.ts +10 -8
- package/src/index.ts +7 -0
- package/src/options.ts +8 -0
- package/src/packetTrailer/PacketTrailerManager.test.ts +172 -0
- package/src/packetTrailer/PacketTrailerManager.ts +250 -0
- package/src/packetTrailer/packetTrailer.test.ts +174 -0
- package/src/packetTrailer/packetTrailer.ts +276 -0
- package/src/packetTrailer/types.ts +75 -0
- package/src/packetTrailer/utils.test.ts +105 -0
- package/src/packetTrailer/utils.ts +50 -0
- package/src/packetTrailer/worker/packetTrailer.worker.ts +155 -0
- package/src/packetTrailer/worker/tsconfig.json +14 -0
- package/src/room/BackOffStrategy.test.ts +1 -1
- package/src/room/RTCEngine.test.ts +219 -0
- package/src/room/RTCEngine.ts +86 -20
- package/src/room/Room.test.ts +62 -1
- package/src/room/Room.ts +28 -5
- package/src/room/data-track/LocalDataTrack.ts +15 -7
- package/src/room/data-track/RemoteDataTrack.ts +8 -1
- package/src/room/data-track/depacketizer.test.ts +433 -1
- package/src/room/data-track/depacketizer.ts +79 -61
- package/src/room/data-track/frame.ts +2 -2
- package/src/room/data-track/incoming/IncomingDataTrackManager.test.ts +194 -0
- package/src/room/data-track/incoming/IncomingDataTrackManager.ts +21 -1
- package/src/room/data-track/incoming/pipeline.ts +13 -2
- package/src/room/data-track/outgoing/OutgoingDataTrackManager.test.ts +350 -198
- package/src/room/data-track/outgoing/OutgoingDataTrackManager.ts +9 -3
- package/src/room/data-track/outgoing/types.ts +4 -3
- package/src/room/data-track/packet/extensions.ts +2 -2
- package/src/room/data-track/packet/index.ts +6 -6
- package/src/room/data-track/packet/serializable.ts +1 -1
- package/src/room/data-track/types.ts +8 -0
- package/src/room/events.ts +2 -2
- package/src/room/participant/LocalParticipant.test.ts +81 -0
- package/src/room/participant/LocalParticipant.ts +48 -7
- package/src/room/participant/Participant.ts +1 -1
- package/src/room/participant/publishUtils.ts +1 -1
- package/src/room/track/PacketTrailerExtractor.ts +43 -0
- package/src/room/track/RemoteVideoTrack.ts +23 -2
- package/src/room/track/Track.ts +1 -1
- package/src/room/track/create.ts +0 -4
- package/src/room/track/options.ts +11 -0
- package/src/room/track/record.ts +1 -1
- package/src/room/track/utils.ts +4 -1
- package/src/room/utils.test.ts +14 -1
- package/src/room/utils.ts +17 -3
- package/src/test/MockMediaStreamTrack.ts +0 -1
- package/src/type-polyfills/non-shared-typed-arrays.d.ts +6 -0
- package/src/utils/dataPacketBuffer.ts +1 -1
- package/src/version.ts +1 -1
|
@@ -148,6 +148,8 @@ export default class LocalParticipant extends Participant {
|
|
|
148
148
|
private waitUntilEngineConnected;
|
|
149
149
|
private hasPermissionsToPublish;
|
|
150
150
|
private publish;
|
|
151
|
+
private canPublishPacketTrailer;
|
|
152
|
+
private normalizeRequestedPacketTrailerOptions;
|
|
151
153
|
get isLocal(): boolean;
|
|
152
154
|
/** @internal
|
|
153
155
|
* publish additional codec to existing track
|
|
@@ -163,7 +165,7 @@ export default class LocalParticipant extends Participant {
|
|
|
163
165
|
* @param data Uint8Array of the payload. To send string data, use TextEncoder.encode
|
|
164
166
|
* @param options optionally specify a `reliable`, `topic` and `destination`
|
|
165
167
|
*/
|
|
166
|
-
publishData(data:
|
|
168
|
+
publishData(data: NonSharedUint8Array, options?: DataPublishOptions): Promise<void>;
|
|
167
169
|
/**
|
|
168
170
|
* Publish SIP DTMF message to the room.
|
|
169
171
|
*
|
|
@@ -124,7 +124,7 @@ export type ParticipantEventCallbacks = {
|
|
|
124
124
|
localSenderCreated: (sender: RTCRtpSender, track: Track) => void;
|
|
125
125
|
participantMetadataChanged: (prevMetadata: string | undefined, participant?: any) => void;
|
|
126
126
|
participantNameChanged: (name: string) => void;
|
|
127
|
-
dataReceived: (payload:
|
|
127
|
+
dataReceived: (payload: NonSharedUint8Array, kind: DataPacket_Kind, encryptionType?: Encryption_Type) => void;
|
|
128
128
|
sipDTMFReceived: (dtmf: SipDTMF) => void;
|
|
129
129
|
transcriptionReceived: (transcription: TranscriptionSegment[], publication?: TrackPublication) => void;
|
|
130
130
|
isSpeakingChanged: (speaking: boolean) => void;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { PacketTrailerMetadata } from '../../packetTrailer/types';
|
|
2
|
+
/**
|
|
3
|
+
* Caches packet trailer metadata extracted from received video frames,
|
|
4
|
+
* keyed by RTP timestamp so it can be looked up when the frame is displayed.
|
|
5
|
+
*
|
|
6
|
+
* Metadata is populated either by the packet trailer worker managed by
|
|
7
|
+
* `PacketTrailerManager` (non-E2EE) or by the E2EE FrameCryptor worker
|
|
8
|
+
* after decryption (E2EE).
|
|
9
|
+
*
|
|
10
|
+
* @experimental
|
|
11
|
+
*/
|
|
12
|
+
export declare class PacketTrailerExtractor {
|
|
13
|
+
private metadataMap;
|
|
14
|
+
private activeSsrc;
|
|
15
|
+
storeMetadata(rtpTimestamp: number, ssrc: number, metadata: PacketTrailerMetadata): void;
|
|
16
|
+
lookupMetadata(rtpTimestamp: number): PacketTrailerMetadata | undefined;
|
|
17
|
+
dispose(): void;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=PacketTrailerExtractor.d.ts.map
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import type { PacketTrailerMetadata } from '../../packetTrailer/types';
|
|
1
2
|
import type { VideoReceiverStats } from '../stats';
|
|
2
3
|
import type { LoggerOptions } from '../types';
|
|
4
|
+
import type { PacketTrailerExtractor } from './PacketTrailerExtractor';
|
|
3
5
|
import RemoteTrack from './RemoteTrack';
|
|
4
6
|
import { Track } from './Track';
|
|
5
7
|
import type { AdaptiveStreamSettings } from './types';
|
|
@@ -9,8 +11,22 @@ export default class RemoteVideoTrack extends RemoteTrack<Track.Kind.Video> {
|
|
|
9
11
|
private adaptiveStreamSettings?;
|
|
10
12
|
private lastVisible?;
|
|
11
13
|
private lastDimensions?;
|
|
14
|
+
/** @internal */
|
|
15
|
+
packetTrailerExtractor?: PacketTrailerExtractor;
|
|
12
16
|
constructor(mediaTrack: MediaStreamTrack, sid: string, receiver: RTCRtpReceiver, adaptiveStreamSettings?: AdaptiveStreamSettings, loggerOptions?: LoggerOptions);
|
|
13
17
|
get isAdaptiveStream(): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Look up frame-level metadata for a given RTP timestamp.
|
|
20
|
+
* Use with the `TrackEvent.TimeSyncUpdate` event to correlate displayed frames
|
|
21
|
+
* with their capture-time metadata.
|
|
22
|
+
*
|
|
23
|
+
* Requires the room to be configured with the `packetTrailer` worker option
|
|
24
|
+
* and the publishing track to have packet trailer features enabled.
|
|
25
|
+
*
|
|
26
|
+
*/
|
|
27
|
+
lookupFrameMetadata({ rtpTimestamp, }: {
|
|
28
|
+
rtpTimestamp: number;
|
|
29
|
+
}): PacketTrailerMetadata | undefined;
|
|
14
30
|
setStreamState(value: Track.StreamState): void;
|
|
15
31
|
/**
|
|
16
32
|
* Note: When using adaptiveStream, you need to use remoteVideoTrack.attach() to add the track to a HTMLVideoElement, otherwise your video tracks might never start
|
|
@@ -148,7 +148,7 @@ export type TrackEventCallbacks = {
|
|
|
148
148
|
timestamp: number;
|
|
149
149
|
rtpTimestamp: number;
|
|
150
150
|
}) => void;
|
|
151
|
-
preConnectBufferFlushed: (buffer:
|
|
151
|
+
preConnectBufferFlushed: (buffer: NonSharedUint8Array[]) => void;
|
|
152
152
|
cpuConstrained: () => void;
|
|
153
153
|
};
|
|
154
154
|
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { PacketTrailerPublishOptions } from '../../packetTrailer/types';
|
|
1
2
|
import type { Track } from './Track';
|
|
2
3
|
import type { AudioProcessorOptions, TrackProcessor, VideoProcessorOptions } from './processor/types';
|
|
3
4
|
export interface TrackPublishDefaults {
|
|
@@ -111,6 +112,15 @@ export interface TrackPublishDefaults {
|
|
|
111
112
|
* Defaults to false.
|
|
112
113
|
*/
|
|
113
114
|
preConnectBuffer?: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Packet trailer metadata to append to published video frames.
|
|
117
|
+
*
|
|
118
|
+
* Requires either room-level packet trailer worker configuration or E2EE,
|
|
119
|
+
* because encoded frame transforms are used to write the trailer.
|
|
120
|
+
*
|
|
121
|
+
* @experimental
|
|
122
|
+
*/
|
|
123
|
+
packetTrailer?: PacketTrailerPublishOptions;
|
|
114
124
|
}
|
|
115
125
|
/**
|
|
116
126
|
* Options when publishing tracks
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChatMessage as ChatMessageModel, ClientInfo, DisconnectReason, Transcription as TranscriptionModel } from '@livekit/protocol';
|
|
1
|
+
import { ChatMessage as ChatMessageModel, ClientInfo, ClientInfo_Capability, DisconnectReason, Transcription as TranscriptionModel } from '@livekit/protocol';
|
|
2
2
|
import type { Throws } from '@livekit/throws-transformer/throws';
|
|
3
3
|
import TypedPromise from '../utils/TypedPromise';
|
|
4
4
|
import type { BrowserDetails } from '../utils/browserParser';
|
|
@@ -40,6 +40,7 @@ export declare function supportsAudioOutputSelection(): boolean;
|
|
|
40
40
|
export declare function isBrowserSupported(): boolean;
|
|
41
41
|
export declare function isFireFox(): boolean;
|
|
42
42
|
export declare function isChromiumBased(): boolean;
|
|
43
|
+
export declare function isScriptTransformSupportedForWorker(): boolean;
|
|
43
44
|
export declare function isSafari(): boolean;
|
|
44
45
|
export declare function isSafariBased(): boolean;
|
|
45
46
|
export declare function isSafari17Based(): boolean;
|
|
@@ -67,7 +68,7 @@ export interface ObservableMediaElement extends HTMLMediaElement {
|
|
|
67
68
|
handleResize: (entry: ResizeObserverEntry) => void;
|
|
68
69
|
handleVisibilityChanged: (entry: IntersectionObserverEntry) => void;
|
|
69
70
|
}
|
|
70
|
-
export declare function getClientInfo(): ClientInfo;
|
|
71
|
+
export declare function getClientInfo(capabilities?: ClientInfo_Capability[]): ClientInfo;
|
|
71
72
|
export declare function getEmptyVideoStreamTrack(): MediaStreamTrack;
|
|
72
73
|
export declare function createDummyVideoStreamTrack(width?: number, height?: number, enabled?: boolean, paintContent?: boolean): MediaStreamTrack;
|
|
73
74
|
export declare function getEmptyAudioStreamTrack(): MediaStreamTrack;
|
|
@@ -143,7 +144,7 @@ export declare function isLocalPub(pub: TrackPublication | undefined): pub is Lo
|
|
|
143
144
|
export declare function isRemoteVideoTrack(track: Track | undefined): track is RemoteVideoTrack;
|
|
144
145
|
export declare function isLocalParticipant(p: Participant): p is LocalParticipant;
|
|
145
146
|
export declare function isRemoteParticipant(p: Participant): p is RemoteParticipant;
|
|
146
|
-
export declare function splitUtf8(s: string, n: number):
|
|
147
|
+
export declare function splitUtf8(s: string, n: number): NonSharedUint8Array[];
|
|
147
148
|
export declare function extractMaxAgeFromRequestHeaders(headers: Headers): number | undefined;
|
|
148
149
|
export declare function isCompressionStreamSupported(): boolean;
|
|
149
150
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/ts4.2/version.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "livekit-client",
|
|
3
|
-
"version": "2.18.
|
|
3
|
+
"version": "2.18.10",
|
|
4
4
|
"description": "JavaScript/TypeScript client SDK for LiveKit",
|
|
5
5
|
"main": "./dist/livekit-client.umd.js",
|
|
6
6
|
"unpkg": "./dist/livekit-client.umd.js",
|
|
@@ -15,6 +15,11 @@
|
|
|
15
15
|
"types": "./dist/src/e2ee/worker/e2ee.worker.d.ts",
|
|
16
16
|
"import": "./dist/livekit-client.e2ee.worker.mjs",
|
|
17
17
|
"require": "./dist/livekit-client.e2ee.worker.js"
|
|
18
|
+
},
|
|
19
|
+
"./packet-trailer-worker": {
|
|
20
|
+
"types": "./dist/src/packetTrailer/worker/packetTrailer.worker.d.ts",
|
|
21
|
+
"import": "./dist/livekit-client.pt.worker.mjs",
|
|
22
|
+
"require": "./dist/livekit-client.pt.worker.js"
|
|
18
23
|
}
|
|
19
24
|
},
|
|
20
25
|
"files": [
|
|
@@ -29,6 +34,9 @@
|
|
|
29
34
|
],
|
|
30
35
|
"./dist/src/e2ee/worker/e2ee.worker.d.ts": [
|
|
31
36
|
"./dist/ts4.2/e2ee/worker/e2ee.worker.d.ts"
|
|
37
|
+
],
|
|
38
|
+
"./dist/src/packetTrailer/worker/packetTrailer.worker.d.ts": [
|
|
39
|
+
"./dist/ts4.2/packetTrailer/worker/packetTrailer.worker.d.ts"
|
|
32
40
|
]
|
|
33
41
|
}
|
|
34
42
|
},
|
|
@@ -37,7 +45,7 @@
|
|
|
37
45
|
"license": "Apache-2.0",
|
|
38
46
|
"dependencies": {
|
|
39
47
|
"@livekit/mutex": "1.1.1",
|
|
40
|
-
"@livekit/protocol": "1.45.
|
|
48
|
+
"@livekit/protocol": "1.45.8",
|
|
41
49
|
"events": "^3.3.0",
|
|
42
50
|
"jose": "^6.1.0",
|
|
43
51
|
"loglevel": "^1.9.2",
|
|
@@ -51,28 +59,28 @@
|
|
|
51
59
|
},
|
|
52
60
|
"devDependencies": {
|
|
53
61
|
"@babel/core": "7.29.0",
|
|
54
|
-
"@babel/preset-env": "7.29.
|
|
62
|
+
"@babel/preset-env": "7.29.2",
|
|
55
63
|
"@bufbuild/protoc-gen-es": "^1.10.0",
|
|
56
|
-
"@changesets/cli": "2.
|
|
57
|
-
"@eslint/js": "
|
|
64
|
+
"@changesets/cli": "2.31.0",
|
|
65
|
+
"@eslint/js": "10.0.1",
|
|
58
66
|
"@livekit/changesets-changelog-github": "^0.0.4",
|
|
59
67
|
"@livekit/throws-transformer": "^0.1.3",
|
|
60
68
|
"@rollup/plugin-babel": "7.0.0",
|
|
61
|
-
"@rollup/plugin-commonjs": "
|
|
69
|
+
"@rollup/plugin-commonjs": "29.0.2",
|
|
62
70
|
"@rollup/plugin-json": "6.1.0",
|
|
63
71
|
"@rollup/plugin-node-resolve": "16.0.3",
|
|
64
72
|
"@rollup/plugin-terser": "^0.4.4",
|
|
65
73
|
"@size-limit/file": "^11.2.0",
|
|
66
74
|
"@size-limit/webpack": "^11.2.0",
|
|
67
|
-
"@stylistic/eslint-plugin": "^
|
|
75
|
+
"@stylistic/eslint-plugin": "^5.10.0",
|
|
68
76
|
"@trivago/prettier-plugin-sort-imports": "^5.0.0",
|
|
69
77
|
"@types/events": "^3.0.3",
|
|
70
78
|
"@types/sdp-transform": "2.15.0",
|
|
71
79
|
"@types/ua-parser-js": "0.7.39",
|
|
72
|
-
"@typescript-eslint/eslint-plugin": "
|
|
73
|
-
"@typescript-eslint/parser": "
|
|
80
|
+
"@typescript-eslint/eslint-plugin": "8.59.2",
|
|
81
|
+
"@typescript-eslint/parser": "8.59.2",
|
|
74
82
|
"downlevel-dts": "^0.11.0",
|
|
75
|
-
"eslint": "
|
|
83
|
+
"eslint": "10.2.1",
|
|
76
84
|
"eslint-config-airbnb-extended": "^2.3.2",
|
|
77
85
|
"eslint-config-prettier": "10.1.8",
|
|
78
86
|
"eslint-plugin-compat": "^6.0.2",
|
|
@@ -83,20 +91,20 @@
|
|
|
83
91
|
"happy-dom": "^20.0.0",
|
|
84
92
|
"jsdom": "^26.1.0",
|
|
85
93
|
"prettier": "^3.4.2",
|
|
86
|
-
"rollup": "4.
|
|
94
|
+
"rollup": "4.60.2",
|
|
87
95
|
"rollup-plugin-delete": "^2.1.0",
|
|
88
|
-
"rollup-plugin-typescript2": "0.
|
|
96
|
+
"rollup-plugin-typescript2": "0.37.0",
|
|
89
97
|
"size-limit": "^11.2.0",
|
|
90
98
|
"tsx": "^4.21.0",
|
|
91
|
-
"typedoc": "0.28.
|
|
99
|
+
"typedoc": "0.28.19",
|
|
92
100
|
"typedoc-plugin-no-inherit": "1.6.1",
|
|
93
|
-
"typescript": "5.
|
|
101
|
+
"typescript": "5.9.3",
|
|
94
102
|
"typescript-eslint": "^8.47.0",
|
|
95
|
-
"vite": "7.3.
|
|
103
|
+
"vite": "7.3.2",
|
|
96
104
|
"vitest": "^3.0.0"
|
|
97
105
|
},
|
|
98
106
|
"scripts": {
|
|
99
|
-
"build": "rollup --config --bundleConfigAsCjs && rollup --config rollup.config.worker.js --bundleConfigAsCjs && pnpm downlevel-dts",
|
|
107
|
+
"build": "rollup --config --bundleConfigAsCjs && rollup --config rollup.config.worker.js --bundleConfigAsCjs && rollup --config rollup.config.pt-worker.js --bundleConfigAsCjs && pnpm downlevel-dts",
|
|
100
108
|
"build:clean": "rm -rf ./dist && pnpm build",
|
|
101
109
|
"build:watch": "rollup --watch --config --bundleConfigAsCjs",
|
|
102
110
|
"build:worker:watch": "rollup --watch --config rollup.config.worker.js --bundleConfigAsCjs",
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
+
ClientInfo_Capability,
|
|
2
3
|
DisconnectReason,
|
|
4
|
+
JoinRequest,
|
|
3
5
|
JoinResponse,
|
|
4
6
|
LeaveRequest,
|
|
5
7
|
ReconnectResponse,
|
|
6
8
|
SignalRequest,
|
|
7
9
|
SignalResponse,
|
|
10
|
+
WrappedJoinRequest,
|
|
11
|
+
WrappedJoinRequest_Compression,
|
|
8
12
|
} from '@livekit/protocol';
|
|
9
13
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
10
14
|
import { ConnectionError, ConnectionErrorReason } from '../room/errors';
|
|
@@ -60,6 +64,7 @@ interface MockWebSocketStreamOptions {
|
|
|
60
64
|
connection?: WebSocketConnection;
|
|
61
65
|
opened?: Promise<WebSocketConnection>;
|
|
62
66
|
closed?: Promise<WebSocketCloseInfo>;
|
|
67
|
+
onUrl?: (url: string) => void;
|
|
63
68
|
readyState?: number;
|
|
64
69
|
}
|
|
65
70
|
|
|
@@ -69,18 +74,19 @@ function mockWebSocketStream(options: MockWebSocketStreamOptions = {}) {
|
|
|
69
74
|
opened = connection ? Promise.resolve(connection) : new Promise(() => {}),
|
|
70
75
|
closed = new Promise(() => {}),
|
|
71
76
|
readyState = 1,
|
|
77
|
+
onUrl,
|
|
72
78
|
} = options;
|
|
73
79
|
|
|
74
|
-
return vi.mocked(WebSocketStream).mockImplementationOnce(
|
|
75
|
-
()
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
);
|
|
80
|
+
return vi.mocked(WebSocketStream).mockImplementationOnce((url) => {
|
|
81
|
+
onUrl?.(url);
|
|
82
|
+
return {
|
|
83
|
+
url: 'wss://test.livekit.io',
|
|
84
|
+
opened,
|
|
85
|
+
closed,
|
|
86
|
+
close: vi.fn(),
|
|
87
|
+
readyState,
|
|
88
|
+
} as any;
|
|
89
|
+
});
|
|
84
90
|
}
|
|
85
91
|
|
|
86
92
|
describe('SignalClient.connect', () => {
|
|
@@ -99,6 +105,47 @@ describe('SignalClient.connect', () => {
|
|
|
99
105
|
signalClient = new SignalClient(false);
|
|
100
106
|
});
|
|
101
107
|
|
|
108
|
+
async function decodeJoinRequestFromUrl(url: string): Promise<JoinRequest> {
|
|
109
|
+
const joinRequestParam = new URL(url).searchParams.get('join_request');
|
|
110
|
+
expect(joinRequestParam).toBeTruthy();
|
|
111
|
+
|
|
112
|
+
const paddedBase64Url = joinRequestParam!.padEnd(
|
|
113
|
+
joinRequestParam!.length + ((4 - (joinRequestParam!.length % 4)) % 4),
|
|
114
|
+
'=',
|
|
115
|
+
);
|
|
116
|
+
const binaryString = atob(paddedBase64Url.replace(/-/g, '+').replace(/_/g, '/'));
|
|
117
|
+
const wrappedBytes = new Uint8Array(binaryString.length);
|
|
118
|
+
for (let i = 0; i < binaryString.length; i += 1) {
|
|
119
|
+
wrappedBytes[i] = binaryString.charCodeAt(i);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const wrappedJoinRequest = WrappedJoinRequest.fromBinary(wrappedBytes);
|
|
123
|
+
if (wrappedJoinRequest.compression === WrappedJoinRequest_Compression.NONE) {
|
|
124
|
+
return JoinRequest.fromBinary(wrappedJoinRequest.joinRequest);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const stream = new DecompressionStream('gzip');
|
|
128
|
+
const writer = stream.writable.getWriter();
|
|
129
|
+
writer.write(wrappedJoinRequest.joinRequest);
|
|
130
|
+
writer.close();
|
|
131
|
+
|
|
132
|
+
const chunks: Uint8Array[] = [];
|
|
133
|
+
const reader = stream.readable.getReader();
|
|
134
|
+
while (true) {
|
|
135
|
+
const { done, value } = await reader.read();
|
|
136
|
+
if (done) break;
|
|
137
|
+
chunks.push(value);
|
|
138
|
+
}
|
|
139
|
+
const totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0);
|
|
140
|
+
const bytes = new Uint8Array(totalLength);
|
|
141
|
+
let offset = 0;
|
|
142
|
+
for (const chunk of chunks) {
|
|
143
|
+
bytes.set(chunk, offset);
|
|
144
|
+
offset += chunk.length;
|
|
145
|
+
}
|
|
146
|
+
return JoinRequest.fromBinary(bytes);
|
|
147
|
+
}
|
|
148
|
+
|
|
102
149
|
describe('Happy Path - Initial Join', () => {
|
|
103
150
|
it('should successfully connect and receive join response', async () => {
|
|
104
151
|
const joinResponse = createJoinResponse();
|
|
@@ -113,6 +160,51 @@ describe('SignalClient.connect', () => {
|
|
|
113
160
|
expect(result).toEqual(joinResponse);
|
|
114
161
|
expect(signalClient.currentState).toBe(SignalConnectionState.CONNECTED);
|
|
115
162
|
});
|
|
163
|
+
|
|
164
|
+
it('does not advertise packet trailer capability by default', async () => {
|
|
165
|
+
const joinResponse = createJoinResponse();
|
|
166
|
+
const signalResponse = createSignalResponse('join', joinResponse);
|
|
167
|
+
const mockReadable = createMockReadableStream([signalResponse]);
|
|
168
|
+
const mockConnection = createMockConnection(mockReadable);
|
|
169
|
+
let capturedUrl = '';
|
|
170
|
+
|
|
171
|
+
mockWebSocketStream({
|
|
172
|
+
connection: mockConnection,
|
|
173
|
+
onUrl: (url) => {
|
|
174
|
+
capturedUrl = url;
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
await signalClient.join('wss://test.livekit.io', 'test-token', defaultOptions);
|
|
179
|
+
|
|
180
|
+
const joinRequest = await decodeJoinRequestFromUrl(capturedUrl);
|
|
181
|
+
expect(joinRequest.clientInfo?.capabilities).toEqual([]);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it('advertises packet trailer capability when provided', async () => {
|
|
185
|
+
const joinResponse = createJoinResponse();
|
|
186
|
+
const signalResponse = createSignalResponse('join', joinResponse);
|
|
187
|
+
const mockReadable = createMockReadableStream([signalResponse]);
|
|
188
|
+
const mockConnection = createMockConnection(mockReadable);
|
|
189
|
+
let capturedUrl = '';
|
|
190
|
+
|
|
191
|
+
mockWebSocketStream({
|
|
192
|
+
connection: mockConnection,
|
|
193
|
+
onUrl: (url) => {
|
|
194
|
+
capturedUrl = url;
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
await signalClient.join('wss://test.livekit.io', 'test-token', {
|
|
199
|
+
...defaultOptions,
|
|
200
|
+
clientInfoCapabilities: [ClientInfo_Capability.CAP_PACKET_TRAILER],
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
const joinRequest = await decodeJoinRequestFromUrl(capturedUrl);
|
|
204
|
+
expect(joinRequest.clientInfo?.capabilities).toEqual([
|
|
205
|
+
ClientInfo_Capability.CAP_PACKET_TRAILER,
|
|
206
|
+
]);
|
|
207
|
+
});
|
|
116
208
|
});
|
|
117
209
|
|
|
118
210
|
describe('Happy Path - Reconnect', () => {
|
package/src/api/SignalClient.ts
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
AddTrackRequest,
|
|
4
4
|
AudioTrackFeature,
|
|
5
5
|
ClientInfo,
|
|
6
|
+
ClientInfo_Capability,
|
|
6
7
|
ConnectionQualityUpdate,
|
|
7
8
|
ConnectionSettings,
|
|
8
9
|
DataTrackSubscriberHandles,
|
|
@@ -83,6 +84,7 @@ interface ConnectOpts extends SignalOptions {
|
|
|
83
84
|
export interface SignalOptions {
|
|
84
85
|
autoSubscribe: boolean;
|
|
85
86
|
adaptiveStream?: boolean;
|
|
87
|
+
clientInfoCapabilities?: ClientInfo_Capability[];
|
|
86
88
|
maxRetries: number;
|
|
87
89
|
e2eeEnabled: boolean;
|
|
88
90
|
websocketTimeout: number;
|
|
@@ -320,7 +322,7 @@ export class SignalClient {
|
|
|
320
322
|
this.connectOptions = opts;
|
|
321
323
|
this.useV0SignalPath = useV0Path;
|
|
322
324
|
|
|
323
|
-
const clientInfo = getClientInfo();
|
|
325
|
+
const clientInfo = getClientInfo(opts.clientInfoCapabilities);
|
|
324
326
|
const params = useV0Path
|
|
325
327
|
? createConnectionParams(token, clientInfo, opts)
|
|
326
328
|
: await createJoinRequestConnectionParams(token, clientInfo, opts, publisherOffer);
|
|
@@ -771,7 +773,7 @@ export class SignalClient {
|
|
|
771
773
|
if (this.useJSON) {
|
|
772
774
|
await this.streamWriter.write(req.toJsonString());
|
|
773
775
|
} else {
|
|
774
|
-
await this.streamWriter.write(req.toBinary());
|
|
776
|
+
await this.streamWriter.write((req.toBinary() as NonSharedUint8Array).buffer);
|
|
775
777
|
}
|
|
776
778
|
} catch (e) {
|
|
777
779
|
this.log.error('error sending signal message', { error: e });
|