livekit-client 1.12.1 → 1.12.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (167) hide show
  1. package/README.md +7 -3
  2. package/dist/livekit-client.e2ee.worker.js +1 -1
  3. package/dist/livekit-client.e2ee.worker.js.map +1 -1
  4. package/dist/livekit-client.e2ee.worker.mjs +389 -301
  5. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  6. package/dist/livekit-client.esm.mjs +11279 -13498
  7. package/dist/livekit-client.esm.mjs.map +1 -1
  8. package/dist/livekit-client.umd.js +1 -1
  9. package/dist/livekit-client.umd.js.map +1 -1
  10. package/dist/src/api/SignalClient.d.ts +2 -2
  11. package/dist/src/api/SignalClient.d.ts.map +1 -1
  12. package/dist/src/connectionHelper/ConnectionCheck.d.ts +3 -2
  13. package/dist/src/connectionHelper/ConnectionCheck.d.ts.map +1 -1
  14. package/dist/src/connectionHelper/checks/Checker.d.ts +3 -2
  15. package/dist/src/connectionHelper/checks/Checker.d.ts.map +1 -1
  16. package/dist/src/connectionHelper/checks/webrtc.d.ts.map +1 -1
  17. package/dist/src/connectionHelper/checks/websocket.d.ts.map +1 -1
  18. package/dist/src/e2ee/E2eeManager.d.ts +4 -2
  19. package/dist/src/e2ee/E2eeManager.d.ts.map +1 -1
  20. package/dist/src/e2ee/KeyProvider.d.ts +4 -2
  21. package/dist/src/e2ee/KeyProvider.d.ts.map +1 -1
  22. package/dist/src/e2ee/constants.d.ts +1 -0
  23. package/dist/src/e2ee/constants.d.ts.map +1 -1
  24. package/dist/src/e2ee/types.d.ts +1 -0
  25. package/dist/src/e2ee/types.d.ts.map +1 -1
  26. package/dist/src/e2ee/worker/FrameCryptor.d.ts +4 -2
  27. package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
  28. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts +14 -3
  29. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts.map +1 -1
  30. package/dist/src/index.d.ts +1 -1
  31. package/dist/src/index.d.ts.map +1 -1
  32. package/dist/src/proto/livekit_models_pb.d.ts +1264 -0
  33. package/dist/src/proto/livekit_models_pb.d.ts.map +1 -0
  34. package/dist/src/proto/livekit_rtc_pb.d.ts +1373 -0
  35. package/dist/src/proto/livekit_rtc_pb.d.ts.map +1 -0
  36. package/dist/src/room/PCTransport.d.ts +2 -1
  37. package/dist/src/room/PCTransport.d.ts.map +1 -1
  38. package/dist/src/room/RTCEngine.d.ts +9 -5
  39. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  40. package/dist/src/room/RegionUrlProvider.d.ts +4 -1
  41. package/dist/src/room/RegionUrlProvider.d.ts.map +1 -1
  42. package/dist/src/room/Room.d.ts +15 -11
  43. package/dist/src/room/Room.d.ts.map +1 -1
  44. package/dist/src/room/participant/LocalParticipant.d.ts +2 -2
  45. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  46. package/dist/src/room/participant/Participant.d.ts +5 -3
  47. package/dist/src/room/participant/Participant.d.ts.map +1 -1
  48. package/dist/src/room/participant/ParticipantTrackPermission.d.ts +1 -1
  49. package/dist/src/room/participant/ParticipantTrackPermission.d.ts.map +1 -1
  50. package/dist/src/room/participant/RemoteParticipant.d.ts +2 -3
  51. package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
  52. package/dist/src/room/participant/publishUtils.d.ts +1 -1
  53. package/dist/src/room/participant/publishUtils.d.ts.map +1 -1
  54. package/dist/src/room/timers.d.ts +5 -4
  55. package/dist/src/room/timers.d.ts.map +1 -1
  56. package/dist/src/room/track/LocalTrack.d.ts +3 -0
  57. package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
  58. package/dist/src/room/track/LocalTrackPublication.d.ts +1 -1
  59. package/dist/src/room/track/LocalTrackPublication.d.ts.map +1 -1
  60. package/dist/src/room/track/LocalVideoTrack.d.ts +2 -2
  61. package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
  62. package/dist/src/room/track/RemoteTrackPublication.d.ts +1 -1
  63. package/dist/src/room/track/RemoteTrackPublication.d.ts.map +1 -1
  64. package/dist/src/room/track/Track.d.ts +6 -4
  65. package/dist/src/room/track/Track.d.ts.map +1 -1
  66. package/dist/src/room/track/TrackPublication.d.ts +7 -5
  67. package/dist/src/room/track/TrackPublication.d.ts.map +1 -1
  68. package/dist/src/room/track/create.d.ts.map +1 -1
  69. package/dist/src/room/track/options.d.ts +8 -0
  70. package/dist/src/room/track/options.d.ts.map +1 -1
  71. package/dist/src/room/track/utils.d.ts +5 -1
  72. package/dist/src/room/track/utils.d.ts.map +1 -1
  73. package/dist/src/room/utils.d.ts +3 -1
  74. package/dist/src/room/utils.d.ts.map +1 -1
  75. package/dist/src/test/mocks.d.ts +4 -3
  76. package/dist/src/test/mocks.d.ts.map +1 -1
  77. package/dist/ts4.2/src/api/SignalClient.d.ts +2 -2
  78. package/dist/ts4.2/src/connectionHelper/ConnectionCheck.d.ts +3 -2
  79. package/dist/ts4.2/src/connectionHelper/checks/Checker.d.ts +3 -2
  80. package/dist/ts4.2/src/e2ee/E2eeManager.d.ts +4 -2
  81. package/dist/ts4.2/src/e2ee/KeyProvider.d.ts +4 -2
  82. package/dist/ts4.2/src/e2ee/constants.d.ts +1 -0
  83. package/dist/ts4.2/src/e2ee/types.d.ts +1 -0
  84. package/dist/ts4.2/src/e2ee/worker/FrameCryptor.d.ts +4 -2
  85. package/dist/ts4.2/src/e2ee/worker/ParticipantKeyHandler.d.ts +14 -3
  86. package/dist/ts4.2/src/index.d.ts +1 -1
  87. package/dist/ts4.2/src/proto/livekit_models_pb.d.ts +1264 -0
  88. package/dist/ts4.2/src/proto/livekit_rtc_pb.d.ts +1373 -0
  89. package/dist/ts4.2/src/room/PCTransport.d.ts +2 -1
  90. package/dist/ts4.2/src/room/RTCEngine.d.ts +9 -5
  91. package/dist/ts4.2/src/room/RegionUrlProvider.d.ts +4 -1
  92. package/dist/ts4.2/src/room/Room.d.ts +15 -11
  93. package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +2 -2
  94. package/dist/ts4.2/src/room/participant/Participant.d.ts +5 -3
  95. package/dist/ts4.2/src/room/participant/ParticipantTrackPermission.d.ts +1 -1
  96. package/dist/ts4.2/src/room/participant/RemoteParticipant.d.ts +2 -3
  97. package/dist/ts4.2/src/room/participant/publishUtils.d.ts +1 -1
  98. package/dist/ts4.2/src/room/timers.d.ts +5 -4
  99. package/dist/ts4.2/src/room/track/LocalTrack.d.ts +3 -0
  100. package/dist/ts4.2/src/room/track/LocalTrackPublication.d.ts +1 -1
  101. package/dist/ts4.2/src/room/track/LocalVideoTrack.d.ts +2 -2
  102. package/dist/ts4.2/src/room/track/RemoteTrackPublication.d.ts +1 -1
  103. package/dist/ts4.2/src/room/track/Track.d.ts +6 -4
  104. package/dist/ts4.2/src/room/track/TrackPublication.d.ts +7 -5
  105. package/dist/ts4.2/src/room/track/options.d.ts +8 -0
  106. package/dist/ts4.2/src/room/track/utils.d.ts +5 -1
  107. package/dist/ts4.2/src/room/utils.d.ts +3 -1
  108. package/dist/ts4.2/src/test/mocks.d.ts +4 -3
  109. package/package.json +10 -10
  110. package/src/api/SignalClient.ts +104 -101
  111. package/src/connectionHelper/ConnectionCheck.ts +3 -2
  112. package/src/connectionHelper/checks/Checker.ts +3 -3
  113. package/src/connectionHelper/checks/webrtc.ts +66 -2
  114. package/src/connectionHelper/checks/websocket.ts +4 -0
  115. package/src/e2ee/E2eeManager.ts +4 -3
  116. package/src/e2ee/KeyProvider.ts +3 -2
  117. package/src/e2ee/constants.ts +4 -0
  118. package/src/e2ee/types.ts +1 -0
  119. package/src/e2ee/worker/FrameCryptor.test.ts +1 -3
  120. package/src/e2ee/worker/FrameCryptor.ts +5 -5
  121. package/src/e2ee/worker/ParticipantKeyHandler.ts +37 -6
  122. package/src/e2ee/worker/e2ee.worker.ts +1 -1
  123. package/src/index.ts +1 -1
  124. package/src/proto/livekit_models_pb.ts +2096 -0
  125. package/src/proto/livekit_rtc_pb.ts +2332 -0
  126. package/src/room/PCTransport.ts +1 -1
  127. package/src/room/RTCEngine.ts +28 -22
  128. package/src/room/RegionUrlProvider.ts +11 -2
  129. package/src/room/Room.test.ts +1 -0
  130. package/src/room/Room.ts +158 -79
  131. package/src/room/participant/LocalParticipant.ts +43 -59
  132. package/src/room/participant/Participant.ts +6 -4
  133. package/src/room/participant/ParticipantTrackPermission.ts +3 -3
  134. package/src/room/participant/RemoteParticipant.ts +5 -6
  135. package/src/room/participant/publishUtils.test.ts +1 -0
  136. package/src/room/participant/publishUtils.ts +4 -2
  137. package/src/room/track/LocalTrack.ts +24 -9
  138. package/src/room/track/LocalTrackPublication.ts +1 -1
  139. package/src/room/track/LocalVideoTrack.test.ts +2 -1
  140. package/src/room/track/LocalVideoTrack.ts +28 -26
  141. package/src/room/track/RemoteTrackPublication.ts +12 -7
  142. package/src/room/track/RemoteVideoTrack.test.ts +5 -4
  143. package/src/room/track/Track.ts +9 -6
  144. package/src/room/track/TrackPublication.ts +7 -5
  145. package/src/room/track/create.ts +9 -17
  146. package/src/room/track/facingMode.test.ts +1 -0
  147. package/src/room/track/options.ts +23 -16
  148. package/src/room/track/utils.test.ts +1 -0
  149. package/src/room/track/utils.ts +44 -2
  150. package/src/room/utils.test.ts +16 -0
  151. package/src/room/utils.ts +20 -4
  152. package/src/test/mocks.ts +7 -5
  153. package/src/utils/AsyncQueue.test.ts +1 -0
  154. package/src/utils/browserParser.test.ts +33 -3
  155. package/src/utils/browserParser.ts +1 -1
  156. package/dist/src/proto/google/protobuf/timestamp.d.ts +0 -146
  157. package/dist/src/proto/google/protobuf/timestamp.d.ts.map +0 -1
  158. package/dist/src/proto/livekit_models.d.ts +0 -2399
  159. package/dist/src/proto/livekit_models.d.ts.map +0 -1
  160. package/dist/src/proto/livekit_rtc.d.ts +0 -14352
  161. package/dist/src/proto/livekit_rtc.d.ts.map +0 -1
  162. package/dist/ts4.2/src/proto/google/protobuf/timestamp.d.ts +0 -150
  163. package/dist/ts4.2/src/proto/livekit_models.d.ts +0 -2659
  164. package/dist/ts4.2/src/proto/livekit_rtc.d.ts +0 -15764
  165. package/src/proto/google/protobuf/timestamp.ts +0 -230
  166. package/src/proto/livekit_models.ts +0 -4006
  167. package/src/proto/livekit_rtc.ts +0 -4672
@@ -1,8 +1,9 @@
1
- import EventEmitter from 'eventemitter3';
1
+ import { EventEmitter } from 'events';
2
+ import type TypedEventEmitter from 'typed-emitter';
2
3
  import log from '../../logger';
3
- import { Encryption_Type } from '../../proto/livekit_models';
4
- import type { SubscriptionError, TrackInfo } from '../../proto/livekit_models';
5
- import type { UpdateSubscription, UpdateTrackSettings } from '../../proto/livekit_rtc';
4
+ import { Encryption_Type } from '../../proto/livekit_models_pb';
5
+ import type { SubscriptionError, TrackInfo } from '../../proto/livekit_models_pb';
6
+ import type { UpdateSubscription, UpdateTrackSettings } from '../../proto/livekit_rtc_pb';
6
7
  import { TrackEvent } from '../events';
7
8
  import LocalAudioTrack from './LocalAudioTrack';
8
9
  import LocalVideoTrack from './LocalVideoTrack';
@@ -11,7 +12,7 @@ import type RemoteTrack from './RemoteTrack';
11
12
  import RemoteVideoTrack from './RemoteVideoTrack';
12
13
  import { Track } from './Track';
13
14
 
14
- export class TrackPublication extends EventEmitter<PublicationEventCallbacks> {
15
+ export class TrackPublication extends (EventEmitter as new () => TypedEventEmitter<PublicationEventCallbacks>) {
15
16
  kind: Track.Kind;
16
17
 
17
18
  trackName: string;
@@ -40,6 +41,7 @@ export class TrackPublication extends EventEmitter<PublicationEventCallbacks> {
40
41
 
41
42
  constructor(kind: Track.Kind, id: string, name: string) {
42
43
  super();
44
+ this.setMaxListeners(100);
43
45
  this.kind = kind;
44
46
  this.trackSid = id;
45
47
  this.trackName = name;
@@ -6,14 +6,18 @@ import LocalAudioTrack from './LocalAudioTrack';
6
6
  import type LocalTrack from './LocalTrack';
7
7
  import LocalVideoTrack from './LocalVideoTrack';
8
8
  import { Track } from './Track';
9
- import { VideoPresets } from './options';
9
+ import { ScreenSharePresets } from './options';
10
10
  import type {
11
11
  AudioCaptureOptions,
12
12
  CreateLocalTracksOptions,
13
13
  ScreenShareCaptureOptions,
14
14
  VideoCaptureOptions,
15
15
  } from './options';
16
- import { constraintsForOptions, mergeDefaultOptions } from './utils';
16
+ import {
17
+ constraintsForOptions,
18
+ mergeDefaultOptions,
19
+ screenCaptureToDisplayMediaStreamOptions,
20
+ } from './utils';
17
21
 
18
22
  /**
19
23
  * Creates a local video and audio track at the same time. When acquiring both
@@ -113,27 +117,15 @@ export async function createLocalScreenTracks(
113
117
  options = {};
114
118
  }
115
119
  if (options.resolution === undefined) {
116
- options.resolution = VideoPresets.h1080.resolution;
117
- }
118
-
119
- let videoConstraints: MediaTrackConstraints | boolean = true;
120
- if (options.resolution) {
121
- videoConstraints = {
122
- width: options.resolution.width,
123
- height: options.resolution.height,
124
- };
120
+ options.resolution = ScreenSharePresets.h1080fps15.resolution;
125
121
  }
126
122
 
127
123
  if (navigator.mediaDevices.getDisplayMedia === undefined) {
128
124
  throw new DeviceUnsupportedError('getDisplayMedia not supported');
129
125
  }
130
126
 
131
- // typescript definition is missing getDisplayMedia: https://github.com/microsoft/TypeScript/issues/33232
132
- // @ts-ignore
133
- const stream: MediaStream = await navigator.mediaDevices.getDisplayMedia({
134
- audio: options.audio ?? false,
135
- video: videoConstraints,
136
- });
127
+ const constraints = screenCaptureToDisplayMediaStreamOptions(options);
128
+ const stream: MediaStream = await navigator.mediaDevices.getDisplayMedia(constraints);
137
129
 
138
130
  const tracks = stream.getVideoTracks();
139
131
  if (tracks.length === 0) {
@@ -1,3 +1,4 @@
1
+ import { describe, expect, test } from 'vitest';
1
2
  import { facingModeFromDeviceLabel } from './facingMode';
2
3
 
3
4
  describe('Test facingMode detection', () => {
@@ -147,6 +147,12 @@ export interface ScreenShareCaptureOptions {
147
147
  */
148
148
  audio?: boolean | AudioCaptureOptions;
149
149
 
150
+ /**
151
+ * only allows for 'true' and chrome allows for additional options to be passed in
152
+ * https://developer.chrome.com/docs/web-platform/screen-sharing-controls/#displaySurface
153
+ */
154
+ video?: true | { displaySurface?: 'window' | 'browser' | 'monitor' };
155
+
150
156
  /** capture resolution, defaults to full HD */
151
157
  resolution?: VideoResolution;
152
158
 
@@ -321,11 +327,11 @@ export namespace AudioPresets {
321
327
  * Sane presets for video resolution/encoding
322
328
  */
323
329
  export const VideoPresets = {
324
- h90: new VideoPreset(160, 90, 60_000, 15),
325
- h180: new VideoPreset(320, 180, 120_000, 15),
326
- h216: new VideoPreset(384, 216, 180_000, 15),
327
- h360: new VideoPreset(640, 360, 300_000, 20),
328
- h540: new VideoPreset(960, 540, 600_000, 25),
330
+ h90: new VideoPreset(160, 90, 90_000, 20),
331
+ h180: new VideoPreset(320, 180, 160_000, 20),
332
+ h216: new VideoPreset(384, 216, 180_000, 20),
333
+ h360: new VideoPreset(640, 360, 450_000, 20),
334
+ h540: new VideoPreset(960, 540, 800_000, 25),
329
335
  h720: new VideoPreset(1280, 720, 1_700_000, 30),
330
336
  h1080: new VideoPreset(1920, 1080, 3_000_000, 30),
331
337
  h1440: new VideoPreset(2560, 1440, 5_000_000, 30),
@@ -336,21 +342,22 @@ export const VideoPresets = {
336
342
  * Four by three presets
337
343
  */
338
344
  export const VideoPresets43 = {
339
- h120: new VideoPreset(160, 120, 80_000, 15),
340
- h180: new VideoPreset(240, 180, 100_000, 15),
341
- h240: new VideoPreset(320, 240, 150_000, 15),
345
+ h120: new VideoPreset(160, 120, 70_000, 20),
346
+ h180: new VideoPreset(240, 180, 125_000, 20),
347
+ h240: new VideoPreset(320, 240, 140_000, 20),
342
348
  h360: new VideoPreset(480, 360, 225_000, 20),
343
- h480: new VideoPreset(640, 480, 300_000, 20),
344
- h540: new VideoPreset(720, 540, 450_000, 25),
345
- h720: new VideoPreset(960, 720, 1_500_000, 30),
346
- h1080: new VideoPreset(1440, 1080, 2_500_000, 30),
347
- h1440: new VideoPreset(1920, 1440, 3_500_000, 30),
349
+ h480: new VideoPreset(640, 480, 500_000, 20),
350
+ h540: new VideoPreset(720, 540, 600_000, 25),
351
+ h720: new VideoPreset(960, 720, 1_300_000, 30),
352
+ h1080: new VideoPreset(1440, 1080, 2_300_000, 30),
353
+ h1440: new VideoPreset(1920, 1440, 3_800_000, 30),
348
354
  } as const;
349
355
 
350
356
  export const ScreenSharePresets = {
351
357
  h360fps3: new VideoPreset(640, 360, 200_000, 3, 'medium'),
352
358
  h720fps5: new VideoPreset(1280, 720, 400_000, 5, 'medium'),
353
- h720fps15: new VideoPreset(1280, 720, 1_000_000, 15, 'medium'),
354
- h1080fps15: new VideoPreset(1920, 1080, 1_500_000, 15, 'medium'),
355
- h1080fps30: new VideoPreset(1920, 1080, 3_000_000, 30, 'medium'),
359
+ h720fps15: new VideoPreset(1280, 720, 1_500_000, 15, 'medium'),
360
+ h720fps30: new VideoPreset(1280, 720, 2_000_000, 30, 'medium'),
361
+ h1080fps15: new VideoPreset(1920, 1080, 2_500_000, 15, 'medium'),
362
+ h1080fps30: new VideoPreset(1920, 1080, 4_000_000, 30, 'medium'),
356
363
  } as const;
@@ -1,3 +1,4 @@
1
+ import { describe, expect, it } from 'vitest';
1
2
  import { AudioCaptureOptions, VideoCaptureOptions, VideoPresets } from './options';
2
3
  import { constraintsForOptions, mergeDefaultOptions } from './utils';
3
4
 
@@ -1,6 +1,11 @@
1
- import { sleep } from '../utils';
1
+ import { isSafari, sleep } from '../utils';
2
2
  import { Track } from './Track';
3
- import type { AudioCaptureOptions, CreateLocalTracksOptions, VideoCaptureOptions } from './options';
3
+ import type {
4
+ AudioCaptureOptions,
5
+ CreateLocalTracksOptions,
6
+ ScreenShareCaptureOptions,
7
+ VideoCaptureOptions,
8
+ } from './options';
4
9
  import type { AudioTrack } from './types';
5
10
 
6
11
  export function mergeDefaultOptions(
@@ -139,3 +144,40 @@ export function sourceToKind(source: Track.Source): MediaDeviceKind | undefined
139
144
  return undefined;
140
145
  }
141
146
  }
147
+
148
+ /**
149
+ * @internal
150
+ */
151
+ export function screenCaptureToDisplayMediaStreamOptions(
152
+ options: ScreenShareCaptureOptions,
153
+ ): DisplayMediaStreamOptions {
154
+ let videoConstraints: MediaTrackConstraints | boolean = options.video ?? true;
155
+ if (options.resolution) {
156
+ videoConstraints = typeof videoConstraints === 'boolean' ? {} : videoConstraints;
157
+ if (isSafari()) {
158
+ videoConstraints = {
159
+ ...videoConstraints,
160
+ width: { max: options.resolution.width },
161
+ height: { max: options.resolution.height },
162
+ frameRate: options.resolution.frameRate,
163
+ };
164
+ } else {
165
+ videoConstraints = {
166
+ ...videoConstraints,
167
+ width: { ideal: options.resolution.width },
168
+ height: { ideal: options.resolution.height },
169
+ frameRate: options.resolution.frameRate,
170
+ };
171
+ }
172
+ }
173
+
174
+ return {
175
+ audio: options.audio ?? false,
176
+ video: videoConstraints,
177
+ // @ts-expect-error support for experimental display media features
178
+ controller: options.controller,
179
+ selfBrowserSurface: options.selfBrowserSurface,
180
+ surfaceSwitching: options.surfaceSwitching,
181
+ systemAudio: options.systemAudio,
182
+ };
183
+ }
@@ -0,0 +1,16 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { toWebsocketUrl } from './utils';
3
+
4
+ describe('toWebsocketUrl', () => {
5
+ it('leaves wss urls alone', () => {
6
+ expect(toWebsocketUrl('ws://mywebsite.com')).toEqual('ws://mywebsite.com');
7
+ });
8
+
9
+ it('converts https to wss', () => {
10
+ expect(toWebsocketUrl('https://mywebsite.com')).toEqual('wss://mywebsite.com');
11
+ });
12
+
13
+ it('does not convert other parts of URL', () => {
14
+ expect(toWebsocketUrl('https://httpsmywebsite.com')).toEqual('wss://httpsmywebsite.com');
15
+ });
16
+ });
package/src/room/utils.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { ClientInfo, ClientInfo_SDK } from '../proto/livekit_models';
2
- import { getBrowser } from '../utils/browserParser';
1
+ import { ClientInfo, ClientInfo_SDK } from '../proto/livekit_models_pb';
3
2
  import type { DetectableBrowser } from '../utils/browserParser';
3
+ import { getBrowser } from '../utils/browserParser';
4
4
  import { protocolVersion, version } from '../version';
5
5
  import type LocalAudioTrack from './track/LocalAudioTrack';
6
6
  import type RemoteAudioTrack from './track/RemoteAudioTrack';
@@ -148,7 +148,9 @@ export function isReactNative(): boolean {
148
148
  }
149
149
 
150
150
  export function isCloud(serverUrl: URL) {
151
- return serverUrl.hostname.endsWith('.livekit.cloud');
151
+ return (
152
+ serverUrl.hostname.endsWith('.livekit.cloud') || serverUrl.hostname.endsWith('.livekit.run')
153
+ );
152
154
  }
153
155
 
154
156
  function getLKReactNativeInfo(): LiveKitReactNativeInfo | undefined {
@@ -244,7 +246,7 @@ export interface ObservableMediaElement extends HTMLMediaElement {
244
246
  }
245
247
 
246
248
  export function getClientInfo(): ClientInfo {
247
- const info = ClientInfo.fromPartial({
249
+ const info = new ClientInfo({
248
250
  sdk: ClientInfo_SDK.JS,
249
251
  protocol: protocolVersion,
250
252
  version,
@@ -483,3 +485,17 @@ export function unwrapConstraint(constraint: ConstrainDOMString): string {
483
485
  }
484
486
  throw Error('could not unwrap constraint');
485
487
  }
488
+
489
+ export function toWebsocketUrl(url: string): string {
490
+ if (url.startsWith('http')) {
491
+ return url.replace(/^(http)/, 'ws');
492
+ }
493
+ return url;
494
+ }
495
+
496
+ export function toHttpUrl(url: string): string {
497
+ if (url.startsWith('ws')) {
498
+ return url.replace(/^(ws)/, 'http');
499
+ }
500
+ return url;
501
+ }
package/src/test/mocks.ts CHANGED
@@ -1,16 +1,18 @@
1
+ // eslint-disable-next-line import/no-extraneous-dependencies
2
+ import { MockedClass, vi } from 'vitest';
1
3
  import { SignalClient } from '../api/SignalClient';
2
4
  import RTCEngine from '../room/RTCEngine';
3
5
 
4
- jest.mock('../api/SignalClient');
5
- jest.mock('../room/RTCEngine');
6
+ vi.mock('../api/SignalClient');
7
+ vi.mock('../room/RTCEngine');
6
8
 
7
9
  // mock helpers for testing
8
10
 
9
11
  const mocks = {
10
- SignalClient: SignalClient as jest.MockedClass<typeof SignalClient>,
11
- RTCEngine: RTCEngine as jest.MockedClass<typeof RTCEngine>,
12
+ SignalClient: SignalClient as MockedClass<typeof SignalClient>,
13
+ RTCEngine: RTCEngine as MockedClass<typeof RTCEngine>,
12
14
  MockLocalVideoTrack: {
13
- stop: jest.fn(),
15
+ stop: vi.fn(),
14
16
  },
15
17
  };
16
18
 
@@ -1,3 +1,4 @@
1
+ import { describe, expect, it } from 'vitest';
1
2
  import { sleep } from '../room/utils';
2
3
  import { AsyncQueue } from './AsyncQueue';
3
4
 
@@ -1,33 +1,63 @@
1
+ import { describe, expect, it } from 'vitest';
1
2
  import { compareVersions } from '../room/utils';
2
3
  import { getBrowser } from './browserParser';
3
4
 
4
5
  describe('browser parser', () => {
5
- const safariUA =
6
+ const macOSSafariUA =
6
7
  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Safari/605.1.15';
8
+
9
+ const iOSSafariUA =
10
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 Safari/604.1';
11
+
7
12
  const firefoxUA =
8
13
  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/112.0';
9
14
 
15
+ const iOSFirefoxUA =
16
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/115.0 Mobile/15E148 Safari/605.1.15';
17
+
10
18
  const chromeUA =
11
19
  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36';
12
20
 
21
+ const iOSChromeUA =
22
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/115.0.5790.130 Mobile/15E148 Safari/604.11';
23
+
13
24
  const braveUA =
14
25
  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36';
15
26
 
16
- it('parses Safari correctly', () => {
17
- const details = getBrowser(safariUA, true);
27
+ it('parses Safari macOS correctly', () => {
28
+ const details = getBrowser(macOSSafariUA, true);
18
29
  expect(details?.name).toBe('Safari');
19
30
  expect(details?.version).toBe('16.3');
31
+ expect(details?.os).toBe('macOS');
32
+ });
33
+ it('parses Safari iOS correctly', () => {
34
+ const details = getBrowser(iOSSafariUA, true);
35
+ expect(details?.name).toBe('Safari');
36
+ expect(details?.version).toBe('16.5');
37
+ expect(details?.os).toBe('iOS');
20
38
  });
21
39
  it('parses Firefox correctly', () => {
22
40
  const details = getBrowser(firefoxUA, true);
23
41
  expect(details?.name).toBe('Firefox');
24
42
  expect(details?.version).toBe('112.0');
25
43
  });
44
+ it('parses iOS Firefox correctly', () => {
45
+ const details = getBrowser(iOSFirefoxUA, true);
46
+ expect(details?.name).toBe('Firefox');
47
+ expect(details?.version).toBe('115.0');
48
+ expect(details?.os).toBe('iOS');
49
+ });
26
50
  it('parses Chrome correctly', () => {
27
51
  const details = getBrowser(chromeUA, true);
28
52
  expect(details?.name).toBe('Chrome');
29
53
  expect(details?.version).toBe('112.0.0.0');
30
54
  });
55
+ it('parses iOS Chrome correctly', () => {
56
+ const details = getBrowser(iOSChromeUA, true);
57
+ expect(details?.name).toBe('Chrome');
58
+ expect(details?.version).toBe('115.0.5790.130');
59
+ expect(details?.os).toBe('iOS');
60
+ });
31
61
  it('detects brave as chromium based', () => {
32
62
  const details = getBrowser(braveUA, true);
33
63
  expect(details?.name).toBe('Chrome');
@@ -60,7 +60,7 @@ const browsersList = [
60
60
  const browser: BrowserDetails = {
61
61
  name: 'Safari',
62
62
  version: getMatch(commonVersionIdentifier, ua),
63
- os: ua.includes('Mobile/') ? 'iOS' : 'macOS',
63
+ os: ua.includes('mobile/') ? 'iOS' : 'macOS',
64
64
  };
65
65
 
66
66
  return browser;
@@ -1,146 +0,0 @@
1
- import _m0 from "protobufjs/minimal";
2
- export declare const protobufPackage = "google.protobuf";
3
- /**
4
- * A Timestamp represents a point in time independent of any time zone or local
5
- * calendar, encoded as a count of seconds and fractions of seconds at
6
- * nanosecond resolution. The count is relative to an epoch at UTC midnight on
7
- * January 1, 1970, in the proleptic Gregorian calendar which extends the
8
- * Gregorian calendar backwards to year one.
9
- *
10
- * All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap
11
- * second table is needed for interpretation, using a [24-hour linear
12
- * smear](https://developers.google.com/time/smear).
13
- *
14
- * The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By
15
- * restricting to that range, we ensure that we can convert to and from [RFC
16
- * 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings.
17
- *
18
- * # Examples
19
- *
20
- * Example 1: Compute Timestamp from POSIX `time()`.
21
- *
22
- * Timestamp timestamp;
23
- * timestamp.set_seconds(time(NULL));
24
- * timestamp.set_nanos(0);
25
- *
26
- * Example 2: Compute Timestamp from POSIX `gettimeofday()`.
27
- *
28
- * struct timeval tv;
29
- * gettimeofday(&tv, NULL);
30
- *
31
- * Timestamp timestamp;
32
- * timestamp.set_seconds(tv.tv_sec);
33
- * timestamp.set_nanos(tv.tv_usec * 1000);
34
- *
35
- * Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
36
- *
37
- * FILETIME ft;
38
- * GetSystemTimeAsFileTime(&ft);
39
- * UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
40
- *
41
- * // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
42
- * // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
43
- * Timestamp timestamp;
44
- * timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
45
- * timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
46
- *
47
- * Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
48
- *
49
- * long millis = System.currentTimeMillis();
50
- *
51
- * Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
52
- * .setNanos((int) ((millis % 1000) * 1000000)).build();
53
- *
54
- * Example 5: Compute Timestamp from Java `Instant.now()`.
55
- *
56
- * Instant now = Instant.now();
57
- *
58
- * Timestamp timestamp =
59
- * Timestamp.newBuilder().setSeconds(now.getEpochSecond())
60
- * .setNanos(now.getNano()).build();
61
- *
62
- * Example 6: Compute Timestamp from current time in Python.
63
- *
64
- * timestamp = Timestamp()
65
- * timestamp.GetCurrentTime()
66
- *
67
- * # JSON Mapping
68
- *
69
- * In JSON format, the Timestamp type is encoded as a string in the
70
- * [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the
71
- * format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
72
- * where {year} is always expressed using four digits while {month}, {day},
73
- * {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
74
- * seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
75
- * are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
76
- * is required. A proto3 JSON serializer should always use UTC (as indicated by
77
- * "Z") when printing the Timestamp type and a proto3 JSON parser should be
78
- * able to accept both UTC and other timezones (as indicated by an offset).
79
- *
80
- * For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
81
- * 01:30 UTC on January 15, 2017.
82
- *
83
- * In JavaScript, one can convert a Date object to this format using the
84
- * standard
85
- * [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
86
- * method. In Python, a standard `datetime.datetime` object can be converted
87
- * to this format using
88
- * [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with
89
- * the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use
90
- * the Joda Time's [`ISODateTimeFormat.dateTime()`](
91
- * http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D
92
- * ) to obtain a formatter capable of generating timestamps in this format.
93
- */
94
- export interface Timestamp {
95
- /**
96
- * Represents seconds of UTC time since Unix epoch
97
- * 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
98
- * 9999-12-31T23:59:59Z inclusive.
99
- */
100
- seconds: number;
101
- /**
102
- * Non-negative fractions of a second at nanosecond resolution. Negative
103
- * second values with fractions must still have non-negative nanos values
104
- * that count forward in time. Must be from 0 to 999,999,999
105
- * inclusive.
106
- */
107
- nanos: number;
108
- }
109
- export declare const Timestamp: {
110
- encode(message: Timestamp, writer?: _m0.Writer): _m0.Writer;
111
- decode(input: _m0.Reader | Uint8Array, length?: number): Timestamp;
112
- fromJSON(object: any): Timestamp;
113
- toJSON(message: Timestamp): unknown;
114
- create<I extends {
115
- seconds?: number | undefined;
116
- nanos?: number | undefined;
117
- } & {
118
- seconds?: number | undefined;
119
- nanos?: number | undefined;
120
- } & { [K in Exclude<keyof I, keyof Timestamp>]: never; }>(base?: I | undefined): Timestamp;
121
- fromPartial<I_1 extends {
122
- seconds?: number | undefined;
123
- nanos?: number | undefined;
124
- } & {
125
- seconds?: number | undefined;
126
- nanos?: number | undefined;
127
- } & { [K_1 in Exclude<keyof I_1, keyof Timestamp>]: never; }>(object: I_1): Timestamp;
128
- };
129
- type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
130
- export type DeepPartial<T> = T extends Builtin ? T : T extends Array<infer U> ? Array<DeepPartial<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>> : T extends {
131
- $case: string;
132
- } ? {
133
- [K in keyof Omit<T, "$case">]?: DeepPartial<T[K]>;
134
- } & {
135
- $case: T["$case"];
136
- } : T extends {} ? {
137
- [K in keyof T]?: DeepPartial<T[K]>;
138
- } : Partial<T>;
139
- type KeysOfUnion<T> = T extends T ? keyof T : never;
140
- export type Exact<P, I extends P> = P extends Builtin ? P : P & {
141
- [K in keyof P]: Exact<P[K], I[K]>;
142
- } & {
143
- [K in Exclude<keyof I, KeysOfUnion<P>>]: never;
144
- };
145
- export {};
146
- //# sourceMappingURL=timestamp.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"timestamp.d.ts","sourceRoot":"","sources":["../../../../../src/proto/google/protobuf/timestamp.ts"],"names":[],"mappings":"AAEA,OAAO,GAAG,MAAM,oBAAoB,CAAC;AAErC,eAAO,MAAM,eAAe,oBAAoB,CAAC;AAEjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0FG;AACH,MAAM,WAAW,SAAS;IACxB;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAMD,eAAO,MAAM,SAAS;oBACJ,SAAS,WAAU,IAAI,MAAM,GAAyB,IAAI,MAAM;kBAUlE,IAAI,MAAM,GAAG,UAAU,WAAW,MAAM,GAAG,SAAS;qBA8BjD,GAAG,GAAG,SAAS;oBAOhB,SAAS,GAAG,OAAO;;;;;;;qFAO2B,SAAS;;;;;;;gFAIH,SAAS;CAM9E,CAAC;AAqBF,KAAK,OAAO,GAAG,IAAI,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAEpF,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,OAAO,GAAG,CAAC,GAC9C,CAAC,SAAS,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GACnH,CAAC,SAAS;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;KAAG,CAAC,IAAI,MAAM,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG;IAAE,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,CAAA;CAAE,GAC3G,CAAC,SAAS,EAAE,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,GACrD,OAAO,CAAC,CAAC,CAAC,CAAC;AAEf,KAAK,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC,GAAG,KAAK,CAAC;AACpD,MAAM,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,OAAO,GAAG,CAAC,GACrD,CAAC,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG;KAAG,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK;CAAE,CAAC"}