livekit-client 0.17.2 → 0.17.3

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 (36) hide show
  1. package/dist/api/SignalClient.d.ts +2 -1
  2. package/dist/api/SignalClient.js +6 -1
  3. package/dist/api/SignalClient.js.map +1 -1
  4. package/dist/proto/google/protobuf/timestamp.d.ts +122 -0
  5. package/dist/proto/google/protobuf/timestamp.js +93 -0
  6. package/dist/proto/google/protobuf/timestamp.js.map +1 -0
  7. package/dist/proto/livekit_models.d.ts +78 -2
  8. package/dist/proto/livekit_models.js +830 -34
  9. package/dist/proto/livekit_models.js.map +1 -1
  10. package/dist/proto/livekit_rtc.d.ts +12 -0
  11. package/dist/proto/livekit_rtc.js +72 -1
  12. package/dist/proto/livekit_rtc.js.map +1 -1
  13. package/dist/room/Room.d.ts +2 -1
  14. package/dist/room/Room.js +8 -1
  15. package/dist/room/Room.js.map +1 -1
  16. package/dist/room/events.d.ts +12 -2
  17. package/dist/room/events.js +10 -0
  18. package/dist/room/events.js.map +1 -1
  19. package/dist/room/participant/LocalParticipant.d.ts +4 -1
  20. package/dist/room/participant/LocalParticipant.js +18 -0
  21. package/dist/room/participant/LocalParticipant.js.map +1 -1
  22. package/dist/room/participant/Participant.d.ts +5 -1
  23. package/dist/room/participant/Participant.js +15 -1
  24. package/dist/room/participant/Participant.js.map +1 -1
  25. package/dist/version.d.ts +2 -2
  26. package/dist/version.js +2 -2
  27. package/package.json +1 -1
  28. package/src/api/SignalClient.ts +8 -1
  29. package/src/proto/google/protobuf/timestamp.ts +222 -0
  30. package/src/proto/livekit_models.ts +937 -30
  31. package/src/proto/livekit_rtc.ts +107 -0
  32. package/src/room/Room.ts +22 -9
  33. package/src/room/events.ts +12 -0
  34. package/src/room/participant/LocalParticipant.ts +25 -2
  35. package/src/room/participant/Participant.ts +22 -2
  36. package/src/version.ts +2 -2
@@ -152,6 +152,8 @@ export interface SignalResponse {
152
152
  subscriptionPermissionUpdate?: SubscriptionPermissionUpdate | undefined;
153
153
  /** update the token the client was using, to prevent an active client from using an expired token */
154
154
  refreshToken: string | undefined;
155
+ /** server initiated track unpublish */
156
+ trackUnpublished?: TrackUnpublishedResponse | undefined;
155
157
  }
156
158
 
157
159
  export interface AddTrackRequest {
@@ -202,6 +204,10 @@ export interface TrackPublishedResponse {
202
204
  track?: TrackInfo;
203
205
  }
204
206
 
207
+ export interface TrackUnpublishedResponse {
208
+ trackSid: string;
209
+ }
210
+
205
211
  export interface SessionDescription {
206
212
  /** "answer" | "offer" | "pranswer" | "rollback" */
207
213
  type: string;
@@ -738,6 +744,12 @@ export const SignalResponse = {
738
744
  if (message.refreshToken !== undefined) {
739
745
  writer.uint32(130).string(message.refreshToken);
740
746
  }
747
+ if (message.trackUnpublished !== undefined) {
748
+ TrackUnpublishedResponse.encode(
749
+ message.trackUnpublished,
750
+ writer.uint32(138).fork()
751
+ ).ldelim();
752
+ }
741
753
  return writer;
742
754
  },
743
755
 
@@ -809,6 +821,12 @@ export const SignalResponse = {
809
821
  case 16:
810
822
  message.refreshToken = reader.string();
811
823
  break;
824
+ case 17:
825
+ message.trackUnpublished = TrackUnpublishedResponse.decode(
826
+ reader,
827
+ reader.uint32()
828
+ );
829
+ break;
812
830
  default:
813
831
  reader.skipType(tag & 7);
814
832
  break;
@@ -922,6 +940,16 @@ export const SignalResponse = {
922
940
  } else {
923
941
  message.refreshToken = undefined;
924
942
  }
943
+ if (
944
+ object.trackUnpublished !== undefined &&
945
+ object.trackUnpublished !== null
946
+ ) {
947
+ message.trackUnpublished = TrackUnpublishedResponse.fromJSON(
948
+ object.trackUnpublished
949
+ );
950
+ } else {
951
+ message.trackUnpublished = undefined;
952
+ }
925
953
  return message;
926
954
  },
927
955
 
@@ -985,6 +1013,10 @@ export const SignalResponse = {
985
1013
  : undefined);
986
1014
  message.refreshToken !== undefined &&
987
1015
  (obj.refreshToken = message.refreshToken);
1016
+ message.trackUnpublished !== undefined &&
1017
+ (obj.trackUnpublished = message.trackUnpublished
1018
+ ? TrackUnpublishedResponse.toJSON(message.trackUnpublished)
1019
+ : undefined);
988
1020
  return obj;
989
1021
  },
990
1022
 
@@ -1089,6 +1121,16 @@ export const SignalResponse = {
1089
1121
  message.subscriptionPermissionUpdate = undefined;
1090
1122
  }
1091
1123
  message.refreshToken = object.refreshToken ?? undefined;
1124
+ if (
1125
+ object.trackUnpublished !== undefined &&
1126
+ object.trackUnpublished !== null
1127
+ ) {
1128
+ message.trackUnpublished = TrackUnpublishedResponse.fromPartial(
1129
+ object.trackUnpublished
1130
+ );
1131
+ } else {
1132
+ message.trackUnpublished = undefined;
1133
+ }
1092
1134
  return message;
1093
1135
  },
1094
1136
  };
@@ -1729,6 +1771,71 @@ export const TrackPublishedResponse = {
1729
1771
  },
1730
1772
  };
1731
1773
 
1774
+ const baseTrackUnpublishedResponse: object = { trackSid: "" };
1775
+
1776
+ export const TrackUnpublishedResponse = {
1777
+ encode(
1778
+ message: TrackUnpublishedResponse,
1779
+ writer: _m0.Writer = _m0.Writer.create()
1780
+ ): _m0.Writer {
1781
+ if (message.trackSid !== "") {
1782
+ writer.uint32(10).string(message.trackSid);
1783
+ }
1784
+ return writer;
1785
+ },
1786
+
1787
+ decode(
1788
+ input: _m0.Reader | Uint8Array,
1789
+ length?: number
1790
+ ): TrackUnpublishedResponse {
1791
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
1792
+ let end = length === undefined ? reader.len : reader.pos + length;
1793
+ const message = {
1794
+ ...baseTrackUnpublishedResponse,
1795
+ } as TrackUnpublishedResponse;
1796
+ while (reader.pos < end) {
1797
+ const tag = reader.uint32();
1798
+ switch (tag >>> 3) {
1799
+ case 1:
1800
+ message.trackSid = reader.string();
1801
+ break;
1802
+ default:
1803
+ reader.skipType(tag & 7);
1804
+ break;
1805
+ }
1806
+ }
1807
+ return message;
1808
+ },
1809
+
1810
+ fromJSON(object: any): TrackUnpublishedResponse {
1811
+ const message = {
1812
+ ...baseTrackUnpublishedResponse,
1813
+ } as TrackUnpublishedResponse;
1814
+ if (object.trackSid !== undefined && object.trackSid !== null) {
1815
+ message.trackSid = String(object.trackSid);
1816
+ } else {
1817
+ message.trackSid = "";
1818
+ }
1819
+ return message;
1820
+ },
1821
+
1822
+ toJSON(message: TrackUnpublishedResponse): unknown {
1823
+ const obj: any = {};
1824
+ message.trackSid !== undefined && (obj.trackSid = message.trackSid);
1825
+ return obj;
1826
+ },
1827
+
1828
+ fromPartial(
1829
+ object: DeepPartial<TrackUnpublishedResponse>
1830
+ ): TrackUnpublishedResponse {
1831
+ const message = {
1832
+ ...baseTrackUnpublishedResponse,
1833
+ } as TrackUnpublishedResponse;
1834
+ message.trackSid = object.trackSid ?? "";
1835
+ return message;
1836
+ },
1837
+ };
1838
+
1732
1839
  const baseSessionDescription: object = { type: "", sdp: "" };
1733
1840
 
1734
1841
  export const SessionDescription = {
package/src/room/Room.ts CHANGED
@@ -5,7 +5,7 @@ import log from '../logger';
5
5
  import { RoomConnectOptions, RoomOptions } from '../options';
6
6
  import {
7
7
  DataPacket_Kind, ParticipantInfo,
8
- ParticipantInfo_State, Room as RoomModel, SpeakerInfo, UserPacket,
8
+ ParticipantInfo_State, ParticipantPermission, Room as RoomModel, SpeakerInfo, UserPacket,
9
9
  } from '../proto/livekit_models';
10
10
  import {
11
11
  ConnectionQualityUpdate,
@@ -211,12 +211,9 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
211
211
  this.state = RoomState.Connected;
212
212
  this.emit(RoomEvent.StateChanged, this.state);
213
213
  const pi = joinResponse.participant!;
214
- this.localParticipant = new LocalParticipant(
215
- pi.sid,
216
- pi.identity,
217
- this.engine,
218
- this.options,
219
- );
214
+
215
+ this.localParticipant.sid = pi.sid;
216
+ this.localParticipant.identity = pi.identity;
220
217
 
221
218
  this.localParticipant.updateInfo(pi);
222
219
  // forward metadata changed for the local participant
@@ -244,7 +241,15 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
244
241
  })
245
242
  .on(ParticipantEvent.MediaDevicesError, (e: Error) => {
246
243
  this.emit(RoomEvent.MediaDevicesError, e);
247
- });
244
+ })
245
+ .on(ParticipantEvent.ParticipantPermissionsChanged,
246
+ (prevPermissions: ParticipantPermission) => {
247
+ this.emit(
248
+ RoomEvent.ParticipantPermissionsChanged,
249
+ prevPermissions,
250
+ this.localParticipant,
251
+ );
252
+ });
248
253
 
249
254
  // populate remote participants, these should not trigger new events
250
255
  joinResponse.otherParticipants.forEach((info) => {
@@ -802,7 +807,11 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
802
807
  })
803
808
  .on(ParticipantEvent.ConnectionQualityChanged, (quality: ConnectionQuality) => {
804
809
  this.emit(RoomEvent.ConnectionQualityChanged, quality, participant);
805
- });
810
+ })
811
+ .on(ParticipantEvent.ParticipantPermissionsChanged,
812
+ (prevPermissions: ParticipantPermission) => {
813
+ this.emit(RoomEvent.ParticipantPermissionsChanged, prevPermissions, participant);
814
+ });
806
815
  return participant;
807
816
  }
808
817
 
@@ -907,6 +916,10 @@ export type RoomEventCallbacks = {
907
916
  metadata: string | undefined,
908
917
  participant: RemoteParticipant | LocalParticipant
909
918
  ) => void,
919
+ participantPermissionsChanged: (
920
+ prevPermissions: ParticipantPermission,
921
+ participant: RemoteParticipant | LocalParticipant
922
+ ) => void,
910
923
  activeSpeakersChanged: (speakers: Array<Participant>) => void,
911
924
  roomMetadataChanged: (metadata: string) => void,
912
925
  dataReceived: (
@@ -225,6 +225,12 @@ export enum RoomEvent {
225
225
  * args: (error: Error)
226
226
  */
227
227
  MediaDevicesError = 'mediaDevicesError',
228
+
229
+ /**
230
+ * A participant's permission has changed. Currently only fired on LocalParticipant.
231
+ * args: (prevPermissions: [[ParticipantPermission]], participant: [[Participant]])
232
+ */
233
+ ParticipantPermissionsChanged = 'participantPermissionsChanged',
228
234
  }
229
235
 
230
236
  export enum ParticipantEvent {
@@ -370,6 +376,12 @@ export enum ParticipantEvent {
370
376
  // fired only on LocalParticipant
371
377
  /** @internal */
372
378
  MediaDevicesError = 'mediaDevicesError',
379
+
380
+ /**
381
+ * A participant's permission has changed. Currently only fired on LocalParticipant.
382
+ * args: (prevPermissions: [[ParticipantPermission]])
383
+ */
384
+ ParticipantPermissionsChanged = 'participantPermissionsChanged',
373
385
  }
374
386
 
375
387
  /** @internal */
@@ -1,10 +1,11 @@
1
1
  import log from '../../logger';
2
2
  import { RoomOptions } from '../../options';
3
3
  import {
4
- DataPacket, DataPacket_Kind,
4
+ DataPacket, DataPacket_Kind, ParticipantPermission,
5
5
  } from '../../proto/livekit_models';
6
6
  import {
7
- AddTrackRequest, DataChannelInfo, SubscribedQualityUpdate, TrackPublishedResponse,
7
+ AddTrackRequest, DataChannelInfo,
8
+ SubscribedQualityUpdate, TrackPublishedResponse, TrackUnpublishedResponse,
8
9
  } from '../../proto/livekit_rtc';
9
10
  import {
10
11
  TrackInvalidError,
@@ -71,6 +72,8 @@ export default class LocalParticipant extends Participant {
71
72
  };
72
73
 
73
74
  this.engine.client.onSubscribedQualityUpdate = this.handleSubscribedQualityUpdate;
75
+
76
+ this.engine.client.onLocalTrackUnpublished = this.handleLocalTrackUnpublished;
74
77
  }
75
78
 
76
79
  get lastCameraError(): Error | undefined {
@@ -120,6 +123,16 @@ export default class LocalParticipant extends Participant {
120
123
  return this.setTrackEnabled(Track.Source.ScreenShare, enabled);
121
124
  }
122
125
 
126
+ /** @internal */
127
+ setPermissions(permissions: ParticipantPermission): boolean {
128
+ const prevPermissions = this.permissions;
129
+ const changed = super.setPermissions(permissions);
130
+ if (changed && prevPermissions) {
131
+ this.emit(ParticipantEvent.ParticipantPermissionsChanged, prevPermissions);
132
+ }
133
+ return changed;
134
+ }
135
+
123
136
  /**
124
137
  * Enable or disable publishing for a track by source. This serves as a simple
125
138
  * way to manage the common tracks (camera, mic, or screen share)
@@ -620,6 +633,16 @@ export default class LocalParticipant extends Participant {
620
633
  pub.videoTrack?.setPublishingLayers(update.subscribedQualities);
621
634
  };
622
635
 
636
+ private handleLocalTrackUnpublished = (unpublished: TrackUnpublishedResponse) => {
637
+ const track = this.tracks.get(unpublished.trackSid);
638
+ if (!track) {
639
+ log.warn('handleLocalTrackUnpublished',
640
+ 'received unpublished event for unknown track', unpublished.trackSid);
641
+ return;
642
+ }
643
+ this.unpublishTrack(track.track!);
644
+ };
645
+
623
646
  private onTrackUnpublish = (track: LocalTrack) => {
624
647
  this.unpublishTrack(track);
625
648
  };
@@ -1,6 +1,8 @@
1
1
  import { EventEmitter } from 'events';
2
2
  import type TypedEmitter from 'typed-emitter';
3
- import { ConnectionQuality as ProtoQuality, DataPacket_Kind, ParticipantInfo } from '../../proto/livekit_models';
3
+ import {
4
+ ConnectionQuality as ProtoQuality, DataPacket_Kind, ParticipantInfo, ParticipantPermission,
5
+ } from '../../proto/livekit_models';
4
6
  import { ParticipantEvent, TrackEvent } from '../events';
5
7
  import LocalTrackPublication from '../track/LocalTrackPublication';
6
8
  import RemoteTrackPublication from '../track/RemoteTrackPublication';
@@ -60,6 +62,8 @@ export default class Participant extends (
60
62
 
61
63
  lastSpokeAt?: Date | undefined;
62
64
 
65
+ permissions?: ParticipantPermission;
66
+
63
67
  private _connectionQuality: ConnectionQuality = ConnectionQuality.Unknown;
64
68
 
65
69
  /** @internal */
@@ -153,13 +157,16 @@ export default class Participant extends (
153
157
  this.sid = info.sid;
154
158
  this.name = info.name;
155
159
  this.setMetadata(info.metadata);
160
+ if (info.permission) {
161
+ this.setPermissions(info.permission);
162
+ }
156
163
  // set this last so setMetadata can detect changes
157
164
  this.participantInfo = info;
158
165
  }
159
166
 
160
167
  /** @internal */
161
168
  setMetadata(md: string) {
162
- const changed = !this.participantInfo || this.participantInfo.metadata !== md;
169
+ const changed = this.metadata !== md;
163
170
  const prevMetadata = this.metadata;
164
171
  this.metadata = md;
165
172
 
@@ -169,6 +176,18 @@ export default class Participant extends (
169
176
  }
170
177
  }
171
178
 
179
+ /** @internal */
180
+ setPermissions(permissions: ParticipantPermission): boolean {
181
+ const changed = permissions.canPublish !== this.permissions?.canPublish
182
+ || permissions.canSubscribe !== this.permissions?.canSubscribe
183
+ || permissions.canPublishData !== this.permissions?.canPublishData
184
+ || permissions.hidden !== this.permissions?.hidden
185
+ || permissions.recorder !== this.permissions?.recorder;
186
+ this.permissions = permissions;
187
+
188
+ return changed;
189
+ }
190
+
172
191
  /** @internal */
173
192
  setIsSpeaking(speaking: boolean) {
174
193
  if (speaking === this.isSpeaking) {
@@ -246,4 +265,5 @@ export type ParticipantEventCallbacks = {
246
265
  status: TrackPublication.SubscriptionStatus
247
266
  ) => void,
248
267
  mediaDevicesError: (error: Error) => void,
268
+ participantPermissionsChanged: (prevPermissions: ParticipantPermission) => void,
249
269
  };
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
- export const version = '0.17.2';
2
- export const protocolVersion = 6;
1
+ export const version = '0.17.3';
2
+ export const protocolVersion = 7;