livekit-client 1.6.3 → 1.6.4

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 (45) hide show
  1. package/dist/livekit-client.esm.mjs +158 -41
  2. package/dist/livekit-client.esm.mjs.map +1 -1
  3. package/dist/livekit-client.umd.js +1 -1
  4. package/dist/livekit-client.umd.js.map +1 -1
  5. package/dist/src/api/SignalClient.d.ts.map +1 -1
  6. package/dist/src/connectionHelper/ConnectionCheck.d.ts +2 -2
  7. package/dist/src/connectionHelper/ConnectionCheck.d.ts.map +1 -1
  8. package/dist/src/proto/livekit_models.d.ts +10 -3
  9. package/dist/src/proto/livekit_models.d.ts.map +1 -1
  10. package/dist/src/proto/livekit_rtc.d.ts +188 -98
  11. package/dist/src/proto/livekit_rtc.d.ts.map +1 -1
  12. package/dist/src/room/Room.d.ts +1 -1
  13. package/dist/src/room/Room.d.ts.map +1 -1
  14. package/dist/src/room/errors.d.ts +3 -0
  15. package/dist/src/room/errors.d.ts.map +1 -1
  16. package/dist/src/room/participant/LocalParticipant.d.ts +1 -3
  17. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  18. package/dist/src/room/participant/Participant.d.ts +1 -1
  19. package/dist/src/room/participant/Participant.d.ts.map +1 -1
  20. package/dist/src/room/track/create.d.ts.map +1 -1
  21. package/dist/src/room/track/options.d.ts +2 -2
  22. package/dist/src/room/track/options.d.ts.map +1 -1
  23. package/dist/src/test/mocks.d.ts +1 -1
  24. package/dist/ts4.2/src/connectionHelper/ConnectionCheck.d.ts +2 -2
  25. package/dist/ts4.2/src/proto/livekit_models.d.ts +14 -3
  26. package/dist/ts4.2/src/proto/livekit_rtc.d.ts +237 -129
  27. package/dist/ts4.2/src/room/Room.d.ts +1 -1
  28. package/dist/ts4.2/src/room/errors.d.ts +3 -0
  29. package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +1 -3
  30. package/dist/ts4.2/src/room/participant/Participant.d.ts +1 -1
  31. package/dist/ts4.2/src/room/track/options.d.ts +2 -2
  32. package/dist/ts4.2/src/test/mocks.d.ts +1 -1
  33. package/package.json +17 -17
  34. package/src/api/SignalClient.ts +5 -1
  35. package/src/connectionHelper/ConnectionCheck.ts +1 -1
  36. package/src/proto/google/protobuf/timestamp.ts +2 -2
  37. package/src/proto/livekit_models.ts +42 -9
  38. package/src/proto/livekit_rtc.ts +99 -4
  39. package/src/room/RTCEngine.ts +2 -2
  40. package/src/room/Room.ts +4 -7
  41. package/src/room/errors.ts +6 -0
  42. package/src/room/participant/LocalParticipant.ts +12 -17
  43. package/src/room/participant/Participant.ts +10 -2
  44. package/src/room/track/create.ts +6 -1
  45. package/src/room/track/options.ts +2 -2
@@ -204,7 +204,7 @@ export type RoomEventCallbacks = {
204
204
  localTrackPublished: (publication: LocalTrackPublication, participant: LocalParticipant) => void;
205
205
  localTrackUnpublished: (publication: LocalTrackPublication, participant: LocalParticipant) => void;
206
206
  participantMetadataChanged: (metadata: string | undefined, participant: RemoteParticipant | LocalParticipant) => void;
207
- participantPermissionsChanged: (prevPermissions: ParticipantPermission, participant: RemoteParticipant | LocalParticipant) => void;
207
+ participantPermissionsChanged: (prevPermissions: ParticipantPermission | undefined, participant: RemoteParticipant | LocalParticipant) => void;
208
208
  activeSpeakersChanged: (speakers: Array<Participant>) => void;
209
209
  roomMetadataChanged: (metadata: string) => void;
210
210
  dataReceived: (payload: Uint8Array, participant?: RemoteParticipant, kind?: DataPacket_Kind) => void;
@@ -12,6 +12,9 @@ export declare class ConnectionError extends LivekitError {
12
12
  reason?: ConnectionErrorReason;
13
13
  constructor(message?: string, reason?: ConnectionErrorReason, status?: number);
14
14
  }
15
+ export declare class DeviceUnsupportedError extends LivekitError {
16
+ constructor(message?: string);
17
+ }
15
18
  export declare class TrackInvalidError extends LivekitError {
16
19
  constructor(message?: string);
17
20
  }
@@ -1,6 +1,6 @@
1
1
  import 'webrtc-adapter';
2
2
  import type { InternalRoomOptions } from '../../options';
3
- import { DataPacket_Kind, ParticipantInfo, ParticipantPermission } from '../../proto/livekit_models';
3
+ import { DataPacket_Kind, ParticipantInfo } from '../../proto/livekit_models';
4
4
  import { DataChannelInfo, TrackPublishedResponse } from '../../proto/livekit_rtc';
5
5
  import type RTCEngine from '../RTCEngine';
6
6
  import LocalTrack from '../track/LocalTrack';
@@ -52,8 +52,6 @@ export default class LocalParticipant extends Participant {
52
52
  * Resolves with a `LocalTrackPublication` instance if successful and `undefined` otherwise
53
53
  */
54
54
  setScreenShareEnabled(enabled: boolean, options?: ScreenShareCaptureOptions, publishOptions?: TrackPublishOptions): Promise<LocalTrackPublication | undefined>;
55
- /** @internal */
56
- setPermissions(permissions: ParticipantPermission): boolean;
57
55
  /**
58
56
  * Enable or disable publishing for a track by source. This serves as a simple
59
57
  * way to manage the common tracks (camera, mic, or screen share).
@@ -85,7 +85,7 @@ export type ParticipantEventCallbacks = {
85
85
  trackStreamStateChanged: (publication: RemoteTrackPublication, streamState: Track.StreamState) => void;
86
86
  trackSubscriptionPermissionChanged: (publication: RemoteTrackPublication, status: TrackPublication.PermissionStatus) => void;
87
87
  mediaDevicesError: (error: Error) => void;
88
- participantPermissionsChanged: (prevPermissions: ParticipantPermission) => void;
88
+ participantPermissionsChanged: (prevPermissions?: ParticipantPermission) => void;
89
89
  trackSubscriptionStatusChanged: (publication: RemoteTrackPublication, status: TrackPublication.SubscriptionStatus) => void;
90
90
  };
91
91
  export {};
@@ -187,8 +187,8 @@ declare const backupCodecs: readonly [
187
187
  "vp8",
188
188
  "h264"
189
189
  ];
190
- export type VideoCodec = typeof codecs[number];
191
- export type BackupVideoCodec = typeof backupCodecs[number];
190
+ export type VideoCodec = (typeof codecs)[number];
191
+ export type BackupVideoCodec = (typeof backupCodecs)[number];
192
192
  export declare function isBackupCodec(codec: string): codec is BackupVideoCodec;
193
193
  /**
194
194
  * scalability modes for svc, only supprot l3t3 now.
@@ -4,7 +4,7 @@ declare const mocks: {
4
4
  SignalClient: jest.MockedClass<typeof SignalClient>;
5
5
  RTCEngine: jest.MockedClass<typeof RTCEngine>;
6
6
  MockLocalVideoTrack: {
7
- stop: jest.Mock<any, any>;
7
+ stop: jest.Mock<any, any, any>;
8
8
  };
9
9
  };
10
10
  export default mocks;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "livekit-client",
3
- "version": "1.6.3",
3
+ "version": "1.6.4",
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",
@@ -51,40 +51,40 @@
51
51
  "webrtc-adapter": "^8.1.1"
52
52
  },
53
53
  "devDependencies": {
54
- "@babel/core": "7.20.7",
54
+ "@babel/core": "7.20.12",
55
55
  "@babel/preset-env": "7.20.2",
56
56
  "@changesets/changelog-github": "0.4.8",
57
57
  "@changesets/cli": "2.26.0",
58
58
  "@rollup/plugin-babel": "6.0.3",
59
- "@rollup/plugin-commonjs": "24.0.0",
59
+ "@rollup/plugin-commonjs": "24.0.1",
60
60
  "@rollup/plugin-json": "6.0.0",
61
61
  "@rollup/plugin-node-resolve": "15.0.1",
62
- "@types/jest": "29.2.5",
62
+ "@types/jest": "29.4.0",
63
63
  "@types/sdp-transform": "2.4.5",
64
64
  "@types/ua-parser-js": "0.7.36",
65
65
  "@types/ws": "8.5.4",
66
- "@typescript-eslint/eslint-plugin": "5.47.1",
67
- "@typescript-eslint/parser": "5.47.1",
66
+ "@typescript-eslint/eslint-plugin": "5.50.0",
67
+ "@typescript-eslint/parser": "5.50.0",
68
68
  "downlevel-dts": "^0.11.0",
69
- "eslint": "8.31.0",
69
+ "eslint": "8.33.0",
70
70
  "eslint-config-airbnb-typescript": "17.0.0",
71
- "eslint-config-prettier": "8.5.0",
72
- "eslint-plugin-import": "2.26.0",
71
+ "eslint-config-prettier": "8.6.0",
72
+ "eslint-plugin-import": "2.27.5",
73
73
  "gh-pages": "4.0.0",
74
- "jest": "29.3.1",
75
- "prettier": "2.8.1",
76
- "rollup": "3.9.1",
74
+ "jest": "29.4.1",
75
+ "prettier": "2.8.3",
76
+ "rollup": "3.12.1",
77
77
  "rollup-plugin-delete": "^2.0.0",
78
78
  "rollup-plugin-filesize": "9.1.2",
79
79
  "rollup-plugin-re": "1.0.7",
80
80
  "rollup-plugin-terser": "7.0.2",
81
81
  "rollup-plugin-typescript2": "0.34.1",
82
- "ts-jest": "29.0.3",
83
- "ts-proto": "1.137.0",
84
- "typedoc": "0.23.23",
82
+ "ts-jest": "29.0.5",
83
+ "ts-proto": "1.139.0",
84
+ "typedoc": "0.23.24",
85
85
  "typedoc-plugin-no-inherit": "1.4.0",
86
- "typescript": "4.9.4",
87
- "vite": "4.0.3"
86
+ "typescript": "4.9.5",
87
+ "vite": "4.0.4"
88
88
  },
89
89
  "browserslist": [
90
90
  "safari >= 11",
@@ -493,7 +493,11 @@ export class SignalClient {
493
493
  }
494
494
 
495
495
  private handleSignalResponse(res: SignalResponse) {
496
- const msg = res.message!;
496
+ const msg = res.message;
497
+ if (msg == undefined) {
498
+ log.debug('received unsupported message');
499
+ return;
500
+ }
497
501
  if (msg.$case === 'answer') {
498
502
  const sd = fromProtoSessionDescription(msg.answer);
499
503
  if (this.onAnswer) {
@@ -9,7 +9,7 @@ import { TURNCheck } from './checks/turn';
9
9
  import { WebRTCCheck } from './checks/webrtc';
10
10
  import { WebSocketCheck } from './checks/websocket';
11
11
 
12
- export type { CheckInfo };
12
+ export type { CheckInfo, CheckStatus };
13
13
 
14
14
  export class ConnectionCheck extends (EventEmitter as new () => TypedEmitter<ConnectionCheckCallbacks>) {
15
15
  token: string;
@@ -172,7 +172,7 @@ export const Timestamp = {
172
172
  declare var self: any | undefined;
173
173
  declare var window: any | undefined;
174
174
  declare var global: any | undefined;
175
- var globalThis: any = (() => {
175
+ var tsProtoGlobalThis: any = (() => {
176
176
  if (typeof globalThis !== "undefined") {
177
177
  return globalThis;
178
178
  }
@@ -202,7 +202,7 @@ export type Exact<P, I extends P> = P extends Builtin ? P
202
202
 
203
203
  function longToNumber(long: Long): number {
204
204
  if (long.gt(Number.MAX_SAFE_INTEGER)) {
205
- throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
205
+ throw new tsProtoGlobalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
206
206
  }
207
207
  return long.toNumber();
208
208
  }
@@ -312,6 +312,8 @@ export interface ParticipantPermission {
312
312
  canPublish: boolean;
313
313
  /** allow participant to publish data */
314
314
  canPublishData: boolean;
315
+ /** sources that are allowed to be published */
316
+ canPublishSources: TrackSource[];
315
317
  /** indicates that it's hidden to others */
316
318
  hidden: boolean;
317
319
  /** indicates it's a recorder instance */
@@ -940,7 +942,14 @@ export const Codec = {
940
942
  };
941
943
 
942
944
  function createBaseParticipantPermission(): ParticipantPermission {
943
- return { canSubscribe: false, canPublish: false, canPublishData: false, hidden: false, recorder: false };
945
+ return {
946
+ canSubscribe: false,
947
+ canPublish: false,
948
+ canPublishData: false,
949
+ canPublishSources: [],
950
+ hidden: false,
951
+ recorder: false,
952
+ };
944
953
  }
945
954
 
946
955
  export const ParticipantPermission = {
@@ -954,6 +963,11 @@ export const ParticipantPermission = {
954
963
  if (message.canPublishData === true) {
955
964
  writer.uint32(24).bool(message.canPublishData);
956
965
  }
966
+ writer.uint32(74).fork();
967
+ for (const v of message.canPublishSources) {
968
+ writer.int32(v);
969
+ }
970
+ writer.ldelim();
957
971
  if (message.hidden === true) {
958
972
  writer.uint32(56).bool(message.hidden);
959
973
  }
@@ -979,6 +993,16 @@ export const ParticipantPermission = {
979
993
  case 3:
980
994
  message.canPublishData = reader.bool();
981
995
  break;
996
+ case 9:
997
+ if ((tag & 7) === 2) {
998
+ const end2 = reader.uint32() + reader.pos;
999
+ while (reader.pos < end2) {
1000
+ message.canPublishSources.push(reader.int32() as any);
1001
+ }
1002
+ } else {
1003
+ message.canPublishSources.push(reader.int32() as any);
1004
+ }
1005
+ break;
982
1006
  case 7:
983
1007
  message.hidden = reader.bool();
984
1008
  break;
@@ -998,6 +1022,9 @@ export const ParticipantPermission = {
998
1022
  canSubscribe: isSet(object.canSubscribe) ? Boolean(object.canSubscribe) : false,
999
1023
  canPublish: isSet(object.canPublish) ? Boolean(object.canPublish) : false,
1000
1024
  canPublishData: isSet(object.canPublishData) ? Boolean(object.canPublishData) : false,
1025
+ canPublishSources: Array.isArray(object?.canPublishSources)
1026
+ ? object.canPublishSources.map((e: any) => trackSourceFromJSON(e))
1027
+ : [],
1001
1028
  hidden: isSet(object.hidden) ? Boolean(object.hidden) : false,
1002
1029
  recorder: isSet(object.recorder) ? Boolean(object.recorder) : false,
1003
1030
  };
@@ -1008,6 +1035,11 @@ export const ParticipantPermission = {
1008
1035
  message.canSubscribe !== undefined && (obj.canSubscribe = message.canSubscribe);
1009
1036
  message.canPublish !== undefined && (obj.canPublish = message.canPublish);
1010
1037
  message.canPublishData !== undefined && (obj.canPublishData = message.canPublishData);
1038
+ if (message.canPublishSources) {
1039
+ obj.canPublishSources = message.canPublishSources.map((e) => trackSourceToJSON(e));
1040
+ } else {
1041
+ obj.canPublishSources = [];
1042
+ }
1011
1043
  message.hidden !== undefined && (obj.hidden = message.hidden);
1012
1044
  message.recorder !== undefined && (obj.recorder = message.recorder);
1013
1045
  return obj;
@@ -1018,6 +1050,7 @@ export const ParticipantPermission = {
1018
1050
  message.canSubscribe = object.canSubscribe ?? false;
1019
1051
  message.canPublish = object.canPublish ?? false;
1020
1052
  message.canPublishData = object.canPublishData ?? false;
1053
+ message.canPublishSources = object.canPublishSources?.map((e) => e) || [];
1021
1054
  message.hidden = object.hidden ?? false;
1022
1055
  message.recorder = object.recorder ?? false;
1023
1056
  return message;
@@ -2940,7 +2973,7 @@ export const TimedVersion = {
2940
2973
  declare var self: any | undefined;
2941
2974
  declare var window: any | undefined;
2942
2975
  declare var global: any | undefined;
2943
- var globalThis: any = (() => {
2976
+ var tsProtoGlobalThis: any = (() => {
2944
2977
  if (typeof globalThis !== "undefined") {
2945
2978
  return globalThis;
2946
2979
  }
@@ -2957,10 +2990,10 @@ var globalThis: any = (() => {
2957
2990
  })();
2958
2991
 
2959
2992
  function bytesFromBase64(b64: string): Uint8Array {
2960
- if (globalThis.Buffer) {
2961
- return Uint8Array.from(globalThis.Buffer.from(b64, "base64"));
2993
+ if (tsProtoGlobalThis.Buffer) {
2994
+ return Uint8Array.from(tsProtoGlobalThis.Buffer.from(b64, "base64"));
2962
2995
  } else {
2963
- const bin = globalThis.atob(b64);
2996
+ const bin = tsProtoGlobalThis.atob(b64);
2964
2997
  const arr = new Uint8Array(bin.length);
2965
2998
  for (let i = 0; i < bin.length; ++i) {
2966
2999
  arr[i] = bin.charCodeAt(i);
@@ -2970,14 +3003,14 @@ function bytesFromBase64(b64: string): Uint8Array {
2970
3003
  }
2971
3004
 
2972
3005
  function base64FromBytes(arr: Uint8Array): string {
2973
- if (globalThis.Buffer) {
2974
- return globalThis.Buffer.from(arr).toString("base64");
3006
+ if (tsProtoGlobalThis.Buffer) {
3007
+ return tsProtoGlobalThis.Buffer.from(arr).toString("base64");
2975
3008
  } else {
2976
3009
  const bin: string[] = [];
2977
3010
  arr.forEach((byte) => {
2978
3011
  bin.push(String.fromCharCode(byte));
2979
3012
  });
2980
- return globalThis.btoa(bin.join(""));
3013
+ return tsProtoGlobalThis.btoa(bin.join(""));
2981
3014
  }
2982
3015
  }
2983
3016
 
@@ -3017,7 +3050,7 @@ function fromJsonTimestamp(o: any): Date {
3017
3050
 
3018
3051
  function longToNumber(long: Long): number {
3019
3052
  if (long.gt(Number.MAX_SAFE_INTEGER)) {
3020
- throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
3053
+ throw new tsProtoGlobalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
3021
3054
  }
3022
3055
  return long.toNumber();
3023
3056
  }
@@ -151,7 +151,8 @@ export interface SignalRequest {
151
151
  | { $case: "subscriptionPermission"; subscriptionPermission: SubscriptionPermission }
152
152
  | { $case: "syncState"; syncState: SyncState }
153
153
  | { $case: "simulate"; simulate: SimulateScenario }
154
- | { $case: "ping"; ping: number };
154
+ | { $case: "ping"; ping: number }
155
+ | { $case: "updateMetadata"; updateMetadata: UpdateParticipantMetadata };
155
156
  }
156
157
 
157
158
  export interface SignalResponse {
@@ -278,6 +279,16 @@ export interface UpdateTrackSettings {
278
279
  /** for video, height to receive */
279
280
  height: number;
280
281
  fps: number;
282
+ /**
283
+ * subscription priority. 1 being the highest (0 is unset)
284
+ * when unset, server sill assign priority based on the order of subscription
285
+ * server will use priority in the following ways:
286
+ * 1. when subscribed tracks exceed per-participant subscription limit, server will
287
+ * pause the lowest priority tracks
288
+ * 2. when the network is congested, server will assign available bandwidth to
289
+ * higher priority tracks first. lowest priority tracks can be paused
290
+ */
291
+ priority: number;
281
292
  }
282
293
 
283
294
  export interface LeaveRequest {
@@ -295,6 +306,10 @@ export interface UpdateVideoLayers {
295
306
  layers: VideoLayer[];
296
307
  }
297
308
 
309
+ export interface UpdateParticipantMetadata {
310
+ metadata: string;
311
+ }
312
+
298
313
  export interface ICEServer {
299
314
  urls: string[];
300
315
  username: string;
@@ -434,6 +449,9 @@ export const SignalRequest = {
434
449
  if (message.message?.$case === "ping") {
435
450
  writer.uint32(112).int64(message.message.ping);
436
451
  }
452
+ if (message.message?.$case === "updateMetadata") {
453
+ UpdateParticipantMetadata.encode(message.message.updateMetadata, writer.uint32(122).fork()).ldelim();
454
+ }
437
455
  return writer;
438
456
  },
439
457
 
@@ -489,6 +507,12 @@ export const SignalRequest = {
489
507
  case 14:
490
508
  message.message = { $case: "ping", ping: longToNumber(reader.int64() as Long) };
491
509
  break;
510
+ case 15:
511
+ message.message = {
512
+ $case: "updateMetadata",
513
+ updateMetadata: UpdateParticipantMetadata.decode(reader, reader.uint32()),
514
+ };
515
+ break;
492
516
  default:
493
517
  reader.skipType(tag & 7);
494
518
  break;
@@ -528,6 +552,8 @@ export const SignalRequest = {
528
552
  ? { $case: "simulate", simulate: SimulateScenario.fromJSON(object.simulate) }
529
553
  : isSet(object.ping)
530
554
  ? { $case: "ping", ping: Number(object.ping) }
555
+ : isSet(object.updateMetadata)
556
+ ? { $case: "updateMetadata", updateMetadata: UpdateParticipantMetadata.fromJSON(object.updateMetadata) }
531
557
  : undefined,
532
558
  };
533
559
  },
@@ -564,6 +590,9 @@ export const SignalRequest = {
564
590
  message.message?.$case === "simulate" &&
565
591
  (obj.simulate = message.message?.simulate ? SimulateScenario.toJSON(message.message?.simulate) : undefined);
566
592
  message.message?.$case === "ping" && (obj.ping = Math.round(message.message?.ping));
593
+ message.message?.$case === "updateMetadata" && (obj.updateMetadata = message.message?.updateMetadata
594
+ ? UpdateParticipantMetadata.toJSON(message.message?.updateMetadata)
595
+ : undefined);
567
596
  return obj;
568
597
  },
569
598
 
@@ -650,6 +679,16 @@ export const SignalRequest = {
650
679
  if (object.message?.$case === "ping" && object.message?.ping !== undefined && object.message?.ping !== null) {
651
680
  message.message = { $case: "ping", ping: object.message.ping };
652
681
  }
682
+ if (
683
+ object.message?.$case === "updateMetadata" &&
684
+ object.message?.updateMetadata !== undefined &&
685
+ object.message?.updateMetadata !== null
686
+ ) {
687
+ message.message = {
688
+ $case: "updateMetadata",
689
+ updateMetadata: UpdateParticipantMetadata.fromPartial(object.message.updateMetadata),
690
+ };
691
+ }
653
692
  return message;
654
693
  },
655
694
  };
@@ -1949,7 +1988,7 @@ export const UpdateSubscription = {
1949
1988
  };
1950
1989
 
1951
1990
  function createBaseUpdateTrackSettings(): UpdateTrackSettings {
1952
- return { trackSids: [], disabled: false, quality: 0, width: 0, height: 0, fps: 0 };
1991
+ return { trackSids: [], disabled: false, quality: 0, width: 0, height: 0, fps: 0, priority: 0 };
1953
1992
  }
1954
1993
 
1955
1994
  export const UpdateTrackSettings = {
@@ -1972,6 +2011,9 @@ export const UpdateTrackSettings = {
1972
2011
  if (message.fps !== 0) {
1973
2012
  writer.uint32(56).uint32(message.fps);
1974
2013
  }
2014
+ if (message.priority !== 0) {
2015
+ writer.uint32(64).uint32(message.priority);
2016
+ }
1975
2017
  return writer;
1976
2018
  },
1977
2019
 
@@ -2000,6 +2042,9 @@ export const UpdateTrackSettings = {
2000
2042
  case 7:
2001
2043
  message.fps = reader.uint32();
2002
2044
  break;
2045
+ case 8:
2046
+ message.priority = reader.uint32();
2047
+ break;
2003
2048
  default:
2004
2049
  reader.skipType(tag & 7);
2005
2050
  break;
@@ -2016,6 +2061,7 @@ export const UpdateTrackSettings = {
2016
2061
  width: isSet(object.width) ? Number(object.width) : 0,
2017
2062
  height: isSet(object.height) ? Number(object.height) : 0,
2018
2063
  fps: isSet(object.fps) ? Number(object.fps) : 0,
2064
+ priority: isSet(object.priority) ? Number(object.priority) : 0,
2019
2065
  };
2020
2066
  },
2021
2067
 
@@ -2031,6 +2077,7 @@ export const UpdateTrackSettings = {
2031
2077
  message.width !== undefined && (obj.width = Math.round(message.width));
2032
2078
  message.height !== undefined && (obj.height = Math.round(message.height));
2033
2079
  message.fps !== undefined && (obj.fps = Math.round(message.fps));
2080
+ message.priority !== undefined && (obj.priority = Math.round(message.priority));
2034
2081
  return obj;
2035
2082
  },
2036
2083
 
@@ -2042,6 +2089,7 @@ export const UpdateTrackSettings = {
2042
2089
  message.width = object.width ?? 0;
2043
2090
  message.height = object.height ?? 0;
2044
2091
  message.fps = object.fps ?? 0;
2092
+ message.priority = object.priority ?? 0;
2045
2093
  return message;
2046
2094
  },
2047
2095
  };
@@ -2166,6 +2214,53 @@ export const UpdateVideoLayers = {
2166
2214
  },
2167
2215
  };
2168
2216
 
2217
+ function createBaseUpdateParticipantMetadata(): UpdateParticipantMetadata {
2218
+ return { metadata: "" };
2219
+ }
2220
+
2221
+ export const UpdateParticipantMetadata = {
2222
+ encode(message: UpdateParticipantMetadata, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
2223
+ if (message.metadata !== "") {
2224
+ writer.uint32(10).string(message.metadata);
2225
+ }
2226
+ return writer;
2227
+ },
2228
+
2229
+ decode(input: _m0.Reader | Uint8Array, length?: number): UpdateParticipantMetadata {
2230
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
2231
+ let end = length === undefined ? reader.len : reader.pos + length;
2232
+ const message = createBaseUpdateParticipantMetadata();
2233
+ while (reader.pos < end) {
2234
+ const tag = reader.uint32();
2235
+ switch (tag >>> 3) {
2236
+ case 1:
2237
+ message.metadata = reader.string();
2238
+ break;
2239
+ default:
2240
+ reader.skipType(tag & 7);
2241
+ break;
2242
+ }
2243
+ }
2244
+ return message;
2245
+ },
2246
+
2247
+ fromJSON(object: any): UpdateParticipantMetadata {
2248
+ return { metadata: isSet(object.metadata) ? String(object.metadata) : "" };
2249
+ },
2250
+
2251
+ toJSON(message: UpdateParticipantMetadata): unknown {
2252
+ const obj: any = {};
2253
+ message.metadata !== undefined && (obj.metadata = message.metadata);
2254
+ return obj;
2255
+ },
2256
+
2257
+ fromPartial<I extends Exact<DeepPartial<UpdateParticipantMetadata>, I>>(object: I): UpdateParticipantMetadata {
2258
+ const message = createBaseUpdateParticipantMetadata();
2259
+ message.metadata = object.metadata ?? "";
2260
+ return message;
2261
+ },
2262
+ };
2263
+
2169
2264
  function createBaseICEServer(): ICEServer {
2170
2265
  return { urls: [], username: "", credential: "" };
2171
2266
  }
@@ -3296,7 +3391,7 @@ export const SimulateScenario = {
3296
3391
  declare var self: any | undefined;
3297
3392
  declare var window: any | undefined;
3298
3393
  declare var global: any | undefined;
3299
- var globalThis: any = (() => {
3394
+ var tsProtoGlobalThis: any = (() => {
3300
3395
  if (typeof globalThis !== "undefined") {
3301
3396
  return globalThis;
3302
3397
  }
@@ -3326,7 +3421,7 @@ export type Exact<P, I extends P> = P extends Builtin ? P
3326
3421
 
3327
3422
  function longToNumber(long: Long): number {
3328
3423
  if (long.gt(Number.MAX_SAFE_INTEGER)) {
3329
- throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
3424
+ throw new tsProtoGlobalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
3330
3425
  }
3331
3426
  return long.toNumber();
3332
3427
  }
@@ -681,14 +681,14 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
681
681
  return;
682
682
  }
683
683
 
684
- log.debug(`${connection} disconnected`);
684
+ log.warn(`${connection} disconnected`);
685
685
  if (this.reconnectAttempts === 0) {
686
686
  // only reset start time on the first try
687
687
  this.reconnectStart = Date.now();
688
688
  }
689
689
 
690
690
  const disconnect = (duration: number) => {
691
- log.info(
691
+ log.warn(
692
692
  `could not recover connection after ${this.reconnectAttempts} attempts, ${duration}ms. giving up`,
693
693
  );
694
694
  this.emit(EngineEvent.Disconnected);
package/src/room/Room.ts CHANGED
@@ -843,10 +843,7 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
843
843
  private handleParticipantUpdates = (participantInfos: ParticipantInfo[]) => {
844
844
  // handle changes to participant state, and send events
845
845
  participantInfos.forEach((info) => {
846
- if (
847
- info.sid === this.localParticipant.sid ||
848
- info.identity === this.localParticipant.identity
849
- ) {
846
+ if (info.identity === this.localParticipant.identity) {
850
847
  this.localParticipant.updateInfo(info);
851
848
  return;
852
849
  }
@@ -1138,7 +1135,7 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
1138
1135
  })
1139
1136
  .on(
1140
1137
  ParticipantEvent.ParticipantPermissionsChanged,
1141
- (prevPermissions: ParticipantPermission) => {
1138
+ (prevPermissions?: ParticipantPermission) => {
1142
1139
  this.emitWhenConnected(
1143
1140
  RoomEvent.ParticipantPermissionsChanged,
1144
1141
  prevPermissions,
@@ -1273,7 +1270,7 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
1273
1270
  this.emit(RoomEvent.MediaDevicesError, e);
1274
1271
  };
1275
1272
 
1276
- private onLocalParticipantPermissionsChanged = (prevPermissions: ParticipantPermission) => {
1273
+ private onLocalParticipantPermissionsChanged = (prevPermissions?: ParticipantPermission) => {
1277
1274
  this.emit(RoomEvent.ParticipantPermissionsChanged, prevPermissions, this.localParticipant);
1278
1275
  };
1279
1276
 
@@ -1442,7 +1439,7 @@ export type RoomEventCallbacks = {
1442
1439
  participant: RemoteParticipant | LocalParticipant,
1443
1440
  ) => void;
1444
1441
  participantPermissionsChanged: (
1445
- prevPermissions: ParticipantPermission,
1442
+ prevPermissions: ParticipantPermission | undefined,
1446
1443
  participant: RemoteParticipant | LocalParticipant,
1447
1444
  ) => void;
1448
1445
  activeSpeakersChanged: (speakers: Array<Participant>) => void;
@@ -25,6 +25,12 @@ export class ConnectionError extends LivekitError {
25
25
  }
26
26
  }
27
27
 
28
+ export class DeviceUnsupportedError extends LivekitError {
29
+ constructor(message?: string) {
30
+ super(21, message ?? 'device is unsupported');
31
+ }
32
+ }
33
+
28
34
  export class TrackInvalidError extends LivekitError {
29
35
  constructor(message?: string) {
30
36
  super(20, message ?? 'track is invalid');
@@ -1,12 +1,7 @@
1
1
  import 'webrtc-adapter';
2
2
  import log from '../../logger';
3
3
  import type { InternalRoomOptions } from '../../options';
4
- import {
5
- DataPacket,
6
- DataPacket_Kind,
7
- ParticipantInfo,
8
- ParticipantPermission,
9
- } from '../../proto/livekit_models';
4
+ import { DataPacket, DataPacket_Kind, ParticipantInfo } from '../../proto/livekit_models';
10
5
  import {
11
6
  AddTrackRequest,
12
7
  DataChannelInfo,
@@ -15,7 +10,7 @@ import {
15
10
  TrackPublishedResponse,
16
11
  TrackUnpublishedResponse,
17
12
  } from '../../proto/livekit_rtc';
18
- import { TrackInvalidError, UnexpectedConnectionState } from '../errors';
13
+ import { DeviceUnsupportedError, TrackInvalidError, UnexpectedConnectionState } from '../errors';
19
14
  import { EngineEvent, ParticipantEvent, TrackEvent } from '../events';
20
15
  import type RTCEngine from '../RTCEngine';
21
16
  import LocalAudioTrack from '../track/LocalAudioTrack';
@@ -168,16 +163,6 @@ export default class LocalParticipant extends Participant {
168
163
  return this.setTrackEnabled(Track.Source.ScreenShare, enabled, options, publishOptions);
169
164
  }
170
165
 
171
- /** @internal */
172
- setPermissions(permissions: ParticipantPermission): boolean {
173
- const prevPermissions = this.permissions;
174
- const changed = super.setPermissions(permissions);
175
- if (changed && prevPermissions) {
176
- this.emit(ParticipantEvent.ParticipantPermissionsChanged, prevPermissions);
177
- }
178
- return changed;
179
- }
180
-
181
166
  /**
182
167
  * Enable or disable publishing for a track by source. This serves as a simple
183
168
  * way to manage the common tracks (camera, mic, or screen share).
@@ -389,6 +374,11 @@ export default class LocalParticipant extends Participant {
389
374
  };
390
375
  }
391
376
  }
377
+
378
+ if (navigator.mediaDevices.getDisplayMedia === undefined) {
379
+ throw new DeviceUnsupportedError('getDisplayMedia not supported');
380
+ }
381
+
392
382
  const stream: MediaStream = await navigator.mediaDevices.getDisplayMedia({
393
383
  audio: options.audio ?? false,
394
384
  video: videoConstraints,
@@ -876,6 +866,11 @@ export default class LocalParticipant extends Participant {
876
866
 
877
867
  /** @internal */
878
868
  updateInfo(info: ParticipantInfo) {
869
+ if (info.sid !== this.sid) {
870
+ // drop updates that specify a wrong sid.
871
+ // the sid for local participant is only explicitly set on join and full reconnect
872
+ return;
873
+ }
879
874
  super.updateInfo(info);
880
875
 
881
876
  // reconcile track mute status.