@stream-io/video-client 0.0.2-alpha.2 → 0.0.2-alpha.21

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/index.cjs.js CHANGED
@@ -5737,14 +5737,13 @@ class Publisher {
5737
5737
  };
5738
5738
  this.updateVideoPublishQuality = (enabledRids) => __awaiter(this, void 0, void 0, function* () {
5739
5739
  var _a;
5740
- console.log('Updating publish quality, qualities requested by SFU:', enabledRids);
5740
+ console.log('Update publish quality, requested rids by SFU:', enabledRids);
5741
5741
  const videoSender = (_a = this.transceiverRegistry[TrackType.VIDEO]) === null || _a === void 0 ? void 0 : _a.sender;
5742
5742
  if (!videoSender)
5743
5743
  return;
5744
5744
  const params = videoSender.getParameters();
5745
5745
  let changed = false;
5746
5746
  params.encodings.forEach((enc) => {
5747
- console.log(enc.rid, enc.active);
5748
5747
  // flip 'active' flag only when necessary
5749
5748
  const shouldEnable = enabledRids.includes(enc.rid);
5750
5749
  if (shouldEnable !== enc.active) {
@@ -5757,6 +5756,10 @@ class Publisher {
5757
5756
  console.warn('No suitable video encoding quality found');
5758
5757
  }
5759
5758
  yield videoSender.setParameters(params);
5759
+ console.log(`Update publish quality, enabled rids: ${params.encodings
5760
+ .filter((e) => e.active)
5761
+ .map((e) => e.rid)
5762
+ .join(', ')}`);
5760
5763
  }
5761
5764
  });
5762
5765
  this.getCodecPreferences = (trackType, preferredCodec) => {
@@ -6619,6 +6622,12 @@ class CallState {
6619
6622
  * @internal
6620
6623
  */
6621
6624
  this.membersSubject = new rxjs.BehaviorSubject([]);
6625
+ /**
6626
+ * The list of capabilities of the current user.
6627
+ *
6628
+ * @private
6629
+ */
6630
+ this.ownCapabilitiesSubject = new rxjs.BehaviorSubject([]);
6622
6631
  /**
6623
6632
  * The calling state.
6624
6633
  *
@@ -6801,6 +6810,15 @@ class CallState {
6801
6810
  this.setMembers = (members) => {
6802
6811
  this.setCurrentValue(this.membersSubject, members);
6803
6812
  };
6813
+ /**
6814
+ * Sets the own capabilities.
6815
+ *
6816
+ * @internal
6817
+ * @param capabilities the capabilities to set.
6818
+ */
6819
+ this.setOwnCapabilities = (capabilities) => {
6820
+ return this.setCurrentValue(this.ownCapabilitiesSubject, capabilities);
6821
+ };
6804
6822
  /**
6805
6823
  * Will try to find the participant with the given sessionId in the current call.
6806
6824
  *
@@ -6890,6 +6908,7 @@ class CallState {
6890
6908
  this.callRecordingList$ = this.callRecordingListSubject.asObservable();
6891
6909
  this.metadata$ = this.metadataSubject.asObservable();
6892
6910
  this.members$ = this.membersSubject.asObservable();
6911
+ this.ownCapabilities$ = this.ownCapabilitiesSubject.asObservable();
6893
6912
  this.callingState$ = this.callingStateSubject.asObservable();
6894
6913
  }
6895
6914
  /**
@@ -6985,6 +7004,12 @@ class CallState {
6985
7004
  get members() {
6986
7005
  return this.getCurrentValue(this.members$);
6987
7006
  }
7007
+ /**
7008
+ * The capabilities of the current user for the current call.
7009
+ */
7010
+ get ownCapabilities() {
7011
+ return this.getCurrentValue(this.ownCapabilities$);
7012
+ }
6988
7013
  }
6989
7014
 
6990
7015
  class StreamVideoWriteableStateStore {
@@ -7048,6 +7073,15 @@ class StreamVideoWriteableStateStore {
7048
7073
  this.unregisterCall = (call) => {
7049
7074
  return this.setCalls((calls) => calls.filter((c) => c !== call));
7050
7075
  };
7076
+ /**
7077
+ * Finds a {@link Call} object in the list of {@link Call} objects created/tracked by this client.
7078
+ *
7079
+ * @param type the type of call to find.
7080
+ * @param id the id of the call to find.
7081
+ */
7082
+ this.findCall = (type, id) => {
7083
+ return this.calls.find((c) => c.type === type && c.id === id);
7084
+ };
7051
7085
  this.connectedUserSubject.subscribe((user) => __awaiter(this, void 0, void 0, function* () {
7052
7086
  // leave all calls when the user disconnects.
7053
7087
  if (!user) {
@@ -7167,16 +7201,39 @@ const watchCallAccepted = (call) => {
7167
7201
  * Once the event is received, the call is left.
7168
7202
  */
7169
7203
  const watchCallRejected = (call) => {
7170
- let totalRejections = 0;
7171
7204
  return function onCallRejected(event) {
7172
7205
  return __awaiter(this, void 0, void 0, function* () {
7173
7206
  if (event.type !== 'call.rejected')
7174
7207
  return;
7175
- totalRejections++;
7176
- const { state } = call;
7177
- if (totalRejections >= state.members.length &&
7178
- state.callingState === exports.CallingState.RINGING) {
7179
- yield call.leave();
7208
+ // We want to discard the event if it's from the current user
7209
+ if (event.user.id === call.currentUserId)
7210
+ return;
7211
+ const { call: eventCall } = event;
7212
+ const { session: callSession } = eventCall;
7213
+ if (!callSession) {
7214
+ console.log('No call session provided. Ignoring call.rejected event.');
7215
+ return;
7216
+ }
7217
+ const rejectedBy = callSession.rejected_by;
7218
+ const { members, callingState } = call.state;
7219
+ if (callingState !== exports.CallingState.RINGING) {
7220
+ console.log('Call is not in ringing mode (it is either accepted or rejected already). Ignoring call.rejected event.');
7221
+ return;
7222
+ }
7223
+ if (call.isCreatedByMe) {
7224
+ const everyoneElseRejected = members
7225
+ .filter((m) => m.user_id !== call.currentUserId)
7226
+ .every((m) => rejectedBy[m.user_id]);
7227
+ if (everyoneElseRejected) {
7228
+ console.log('everyone rejected, leaving the call');
7229
+ yield call.leave();
7230
+ }
7231
+ }
7232
+ else {
7233
+ if (rejectedBy[eventCall.created_by.id]) {
7234
+ console.log('call creator rejected, leaving call');
7235
+ yield call.leave();
7236
+ }
7180
7237
  }
7181
7238
  });
7182
7239
  };
@@ -7217,7 +7274,10 @@ const watchCallPermissionRequest = (state) => {
7217
7274
  return function onCallPermissionRequest(event) {
7218
7275
  if (event.type !== 'call.permission_request')
7219
7276
  return;
7220
- state.setCallPermissionRequest(event);
7277
+ const { localParticipant } = state;
7278
+ if (event.user.id !== (localParticipant === null || localParticipant === void 0 ? void 0 : localParticipant.userId)) {
7279
+ state.setCallPermissionRequest(event);
7280
+ }
7221
7281
  };
7222
7282
  };
7223
7283
  /**
@@ -7229,7 +7289,7 @@ const watchCallPermissionsUpdated = (state) => {
7229
7289
  return;
7230
7290
  const { localParticipant } = state;
7231
7291
  if (event.user.id === (localParticipant === null || localParticipant === void 0 ? void 0 : localParticipant.userId)) {
7232
- state.setMetadata((metadata) => (Object.assign(Object.assign({}, metadata), { own_capabilities: event.own_capabilities })));
7292
+ state.setOwnCapabilities(event.own_capabilities);
7233
7293
  }
7234
7294
  };
7235
7295
  };
@@ -7240,7 +7300,6 @@ const watchCallPermissionsUpdated = (state) => {
7240
7300
  */
7241
7301
  const watchCallGrantsUpdated = (state) => {
7242
7302
  return function onCallGrantsUpdated(event) {
7243
- var _a;
7244
7303
  if (event.eventPayload.oneofKind !== 'callGrantsUpdated')
7245
7304
  return;
7246
7305
  const { currentGrants } = event.eventPayload.callGrantsUpdated;
@@ -7251,15 +7310,13 @@ const watchCallGrantsUpdated = (state) => {
7251
7310
  [OwnCapability.SEND_VIDEO]: canPublishVideo,
7252
7311
  [OwnCapability.SCREENSHARE]: canScreenshare,
7253
7312
  };
7254
- const nextCapabilities = (((_a = state.metadata) === null || _a === void 0 ? void 0 : _a.own_capabilities) || []).filter((capability) => update[capability] !== false);
7313
+ const nextCapabilities = state.ownCapabilities.filter((capability) => update[capability] !== false);
7255
7314
  Object.entries(update).forEach(([capability, value]) => {
7256
7315
  if (value && !nextCapabilities.includes(capability)) {
7257
7316
  nextCapabilities.push(capability);
7258
7317
  }
7259
7318
  });
7260
- state.setMetadata((metadata) => {
7261
- return Object.assign(Object.assign({}, metadata), { own_capabilities: nextCapabilities });
7262
- });
7319
+ state.setOwnCapabilities(nextCapabilities);
7263
7320
  }
7264
7321
  };
7265
7322
  };
@@ -7552,10 +7609,7 @@ const watchCallSessionStarted = (state) => {
7552
7609
  return function onCallSessionStarted(event) {
7553
7610
  if (event.type !== 'call.session_started')
7554
7611
  return;
7555
- const { call } = event;
7556
- state.setMetadata((metadata) => (Object.assign(Object.assign({}, call), {
7557
- // FIXME OL: temporary, until the backend sends the own_capabilities
7558
- own_capabilities: (metadata === null || metadata === void 0 ? void 0 : metadata.own_capabilities) || [] })));
7612
+ state.setMetadata(event.call);
7559
7613
  };
7560
7614
  };
7561
7615
  /**
@@ -7567,10 +7621,7 @@ const watchCallSessionEnded = (state) => {
7567
7621
  return function onCallSessionEnded(event) {
7568
7622
  if (event.type !== 'call.session_ended')
7569
7623
  return;
7570
- const { call } = event;
7571
- state.setMetadata((metadata) => (Object.assign(Object.assign({}, call), {
7572
- // FIXME OL: temporary, until the backend sends the own_capabilities
7573
- own_capabilities: (metadata === null || metadata === void 0 ? void 0 : metadata.own_capabilities) || [] })));
7624
+ state.setMetadata(event.call);
7574
7625
  };
7575
7626
  };
7576
7627
  /**
@@ -7647,6 +7698,13 @@ const watchUnblockedUser = (state) => (event) => {
7647
7698
  });
7648
7699
  };
7649
7700
 
7701
+ /**
7702
+ * Registers the default event handlers for a call during its lifecycle.
7703
+ *
7704
+ * @param call the call to register event handlers for.
7705
+ * @param state the call state.
7706
+ * @param dispatcher the dispatcher.
7707
+ */
7650
7708
  const registerEventHandlers = (call, state, dispatcher) => {
7651
7709
  const coordinatorEvents = {
7652
7710
  'call.blocked_user': watchBlockedUser(state),
@@ -7669,8 +7727,6 @@ const registerEventHandlers = (call, state, dispatcher) => {
7669
7727
  'call.session_participant_left': watchCallSessionParticipantLeft(state),
7670
7728
  'call.unblocked_user': watchUnblockedUser(state),
7671
7729
  'call.updated': watchCallUpdated(state),
7672
- 'call.notification': (event) => console.log(`Received ${event.type} event`, event),
7673
- 'call.ring': (event) => console.log(`Received ${event.type} event`, event),
7674
7730
  };
7675
7731
  const eventHandlers = [
7676
7732
  watchChangePublishQuality(dispatcher, call),
@@ -7696,6 +7752,11 @@ const registerEventHandlers = (call, state, dispatcher) => {
7696
7752
  eventHandlers.forEach((unsubscribe) => unsubscribe());
7697
7753
  };
7698
7754
  };
7755
+ /**
7756
+ * Registers event handlers for a call that is of ringing type.
7757
+ *
7758
+ * @param call the call to register event handlers for.
7759
+ */
7699
7760
  const registerRingingCallEventHandlers = (call) => {
7700
7761
  const coordinatorRingEvents = {
7701
7762
  'call.accepted': watchCallAccepted(call),
@@ -7722,13 +7783,14 @@ const registerRingingCallEventHandlers = (call) => {
7722
7783
  const join = (httpClient, type, id, data) => __awaiter(void 0, void 0, void 0, function* () {
7723
7784
  yield httpClient.connectionIdPromise;
7724
7785
  const joinCallResponse = yield doJoin(httpClient, type, id, data);
7725
- const { call, credentials, members } = joinCallResponse;
7786
+ const { call, credentials, members, own_capabilities } = joinCallResponse;
7726
7787
  return {
7727
7788
  connectionConfig: toRtcConfiguration(credentials.ice_servers),
7728
7789
  sfuServer: credentials.server,
7729
7790
  token: credentials.token,
7730
7791
  metadata: call,
7731
7792
  members,
7793
+ ownCapabilities: own_capabilities,
7732
7794
  };
7733
7795
  });
7734
7796
  const doJoin = (httpClient, type, id, data) => __awaiter(void 0, void 0, void 0, function* () {
@@ -7745,9 +7807,12 @@ const doJoin = (httpClient, type, id, data) => __awaiter(void 0, void 0, void 0,
7745
7807
  });
7746
7808
  const getLocationHint = () => __awaiter(void 0, void 0, void 0, function* () {
7747
7809
  const hintURL = `https://hint.stream-io-video.com/`;
7810
+ const abortController = new AbortController();
7811
+ const timeoutId = setTimeout(() => abortController.abort(), 1000);
7748
7812
  try {
7749
7813
  const response = yield fetch(hintURL, {
7750
7814
  method: 'HEAD',
7815
+ signal: abortController.signal,
7751
7816
  });
7752
7817
  const awsPop = response.headers.get('x-amz-cf-pop') || 'ERR';
7753
7818
  return awsPop.substring(0, 3); // AMS1-P2 -> AMS
@@ -7756,6 +7821,9 @@ const getLocationHint = () => __awaiter(void 0, void 0, void 0, function* () {
7756
7821
  console.error(`Failed to get location hint from ${hintURL}`, e);
7757
7822
  return 'ERR';
7758
7823
  }
7824
+ finally {
7825
+ clearTimeout(timeoutId);
7826
+ }
7759
7827
  });
7760
7828
  const toRtcConfiguration = (config) => {
7761
7829
  if (!config || config.length === 0)
@@ -8258,7 +8326,7 @@ class Call {
8258
8326
  * Use the [`StreamVideoClient.call`](./StreamVideoClient.md/#call)
8259
8327
  * method to construct a `Call` instance.
8260
8328
  */
8261
- constructor({ type, id, streamClient, metadata, members, sortParticipantsBy, clientStore, ringing = false, watching = false, }) {
8329
+ constructor({ type, id, streamClient, metadata, members, ownCapabilities, sortParticipantsBy, clientStore, ringing = false, watching = false, }) {
8262
8330
  /**
8263
8331
  * ViewportTracker instance
8264
8332
  */
@@ -8302,13 +8370,11 @@ class Call {
8302
8370
  if (this.isCreatedByMe && !hasOtherParticipants) {
8303
8371
  // Signals other users that I have cancelled my call to them
8304
8372
  // before they accepted it.
8305
- // Causes the `call.ended` event to be emitted to all the call members.
8306
- yield this.endCall();
8373
+ yield this.reject();
8307
8374
  }
8308
8375
  else if (reject && callingState === exports.CallingState.RINGING) {
8309
8376
  // Signals other users that I have rejected the incoming call.
8310
- // Causes the `call.rejected` event to be emitted to all the call members.
8311
- yield this.sendEvent({ type: 'call.rejected' });
8377
+ yield this.reject();
8312
8378
  }
8313
8379
  }
8314
8380
  (_a = this.statsReporter) === null || _a === void 0 ? void 0 : _a.stop();
@@ -8340,11 +8406,19 @@ class Call {
8340
8406
  });
8341
8407
  /**
8342
8408
  * Loads the information about the call.
8409
+ *
8410
+ * @param params.ring if set to true, a `call.ring` event will be sent to the call members.
8411
+ * @param params.notify if set to true, a `call.notification` event will be sent to the call members.
8412
+ * @param params.members_limit the members limit.
8343
8413
  */
8344
8414
  this.get = (params) => __awaiter(this, void 0, void 0, function* () {
8345
8415
  const response = yield this.streamClient.get(this.streamClientBasePath, params);
8416
+ if ((params === null || params === void 0 ? void 0 : params.ring) && !this.ringing) {
8417
+ this.ringingSubject.next(true);
8418
+ }
8346
8419
  this.state.setMetadata(response.call);
8347
8420
  this.state.setMembers(response.members);
8421
+ this.state.setOwnCapabilities(response.own_capabilities);
8348
8422
  if (this.streamClient._hasConnectionID()) {
8349
8423
  this.watching = true;
8350
8424
  this.clientStore.registerCall(this);
@@ -8358,20 +8432,52 @@ class Call {
8358
8432
  */
8359
8433
  this.getOrCreate = (data) => __awaiter(this, void 0, void 0, function* () {
8360
8434
  const response = yield this.streamClient.post(this.streamClientBasePath, data);
8435
+ if ((data === null || data === void 0 ? void 0 : data.ring) && !this.ringing) {
8436
+ this.ringingSubject.next(true);
8437
+ }
8361
8438
  this.state.setMetadata(response.call);
8362
8439
  this.state.setMembers(response.members);
8440
+ this.state.setOwnCapabilities(response.own_capabilities);
8363
8441
  if (this.streamClient._hasConnectionID()) {
8364
8442
  this.watching = true;
8365
8443
  this.clientStore.registerCall(this);
8366
8444
  }
8367
8445
  return response;
8368
8446
  });
8447
+ /**
8448
+ * A shortcut for {@link Call.get} with `ring` parameter set to `true`.
8449
+ * Will send a `call.ring` event to the call members.
8450
+ */
8369
8451
  this.ring = () => __awaiter(this, void 0, void 0, function* () {
8370
8452
  return yield this.get({ ring: true });
8371
8453
  });
8454
+ /**
8455
+ * A shortcut for {@link Call.get} with `notify` parameter set to `true`.
8456
+ * Will send a `call.notification` event to the call members.
8457
+ */
8372
8458
  this.notify = () => __awaiter(this, void 0, void 0, function* () {
8373
8459
  return yield this.get({ notify: true });
8374
8460
  });
8461
+ /**
8462
+ * Marks the incoming call as accepted.
8463
+ *
8464
+ * This method should be used only for "ringing" call flows.
8465
+ * {@link Call.join} invokes this method automatically for you when joining a call.
8466
+ * Unless you are implementing a custom "ringing" flow, you should not use this method.
8467
+ */
8468
+ this.accept = () => __awaiter(this, void 0, void 0, function* () {
8469
+ return this.streamClient.post(`${this.streamClientBasePath}/accept`);
8470
+ });
8471
+ /**
8472
+ * Marks the incoming call as rejected.
8473
+ *
8474
+ * This method should be used only for "ringing" call flows.
8475
+ * {@link Call.leave} invokes this method automatically for you when you leave or reject this call.
8476
+ * Unless you are implementing a custom "ringing" flow, you should not use this method.
8477
+ */
8478
+ this.reject = () => __awaiter(this, void 0, void 0, function* () {
8479
+ return this.streamClient.post(`${this.streamClientBasePath}/reject`);
8480
+ });
8375
8481
  /**
8376
8482
  * Will start to watch for call related WebSocket events and initiate a call session with the server.
8377
8483
  *
@@ -8384,6 +8490,13 @@ class Call {
8384
8490
  }
8385
8491
  const previousCallingState = this.state.callingState;
8386
8492
  this.state.setCallingState(exports.CallingState.JOINING);
8493
+ if ((data === null || data === void 0 ? void 0 : data.ring) && !this.ringing) {
8494
+ this.ringingSubject.next(true);
8495
+ }
8496
+ if (this.ringing && !this.isCreatedByMe) {
8497
+ // signals other users that I have accepted the incoming call.
8498
+ yield this.accept();
8499
+ }
8387
8500
  let sfuServer;
8388
8501
  let sfuToken;
8389
8502
  let connectionConfig;
@@ -8391,6 +8504,7 @@ class Call {
8391
8504
  const call = yield join(this.streamClient, this.type, this.id, data);
8392
8505
  this.state.setMetadata(call.metadata);
8393
8506
  this.state.setMembers(call.members);
8507
+ this.state.setOwnCapabilities(call.ownCapabilities);
8394
8508
  connectionConfig = call.connectionConfig;
8395
8509
  sfuServer = call.sfuServer;
8396
8510
  sfuToken = call.token;
@@ -8580,15 +8694,6 @@ class Call {
8580
8694
  }
8581
8695
  }
8582
8696
  });
8583
- /**
8584
- * Will update the call members.
8585
- *
8586
- * @param data the request data.
8587
- */
8588
- this.updateCallMembers = (data) => __awaiter(this, void 0, void 0, function* () {
8589
- // FIXME: OL: implement kick-users
8590
- return this.streamClient.post(`${this.streamClientBasePath}/members`, data);
8591
- });
8592
8697
  /**
8593
8698
  * Starts publishing the given video stream to the call.
8594
8699
  * The stream will be stopped if the user changes an input device, or if the user leaves the call.
@@ -9041,7 +9146,12 @@ class Call {
9041
9146
  * @param updates the updates to apply to the call.
9042
9147
  */
9043
9148
  this.update = (updates) => __awaiter(this, void 0, void 0, function* () {
9044
- return this.streamClient.patch(`${this.streamClientBasePath}`, updates);
9149
+ const response = yield this.streamClient.patch(`${this.streamClientBasePath}`, updates);
9150
+ const { call, members, own_capabilities } = response;
9151
+ this.state.setMetadata(call);
9152
+ this.state.setMembers(members);
9153
+ this.state.setOwnCapabilities(own_capabilities);
9154
+ return response;
9045
9155
  });
9046
9156
  /**
9047
9157
  * Ends the call. Once the call is ended, it cannot be re-joined.
@@ -9068,7 +9178,17 @@ class Call {
9068
9178
  this.queryMembers = (request) => {
9069
9179
  return this.streamClient.post('/call/members', Object.assign(Object.assign({}, request), { id: this.id, type: this.type }));
9070
9180
  };
9181
+ /**
9182
+ * Will update the call members.
9183
+ *
9184
+ * @param data the request data.
9185
+ */
9186
+ this.updateCallMembers = (data) => __awaiter(this, void 0, void 0, function* () {
9187
+ return this.streamClient.post(`${this.streamClientBasePath}/members`, data);
9188
+ });
9071
9189
  this.scheduleAutoDrop = () => {
9190
+ if (this.dropTimeout)
9191
+ clearTimeout(this.dropTimeout);
9072
9192
  const subscription = this.state.metadata$
9073
9193
  .pipe(rxjs.pairwise(), rxjs.tap(([prevMeta, currentMeta]) => {
9074
9194
  if (!(currentMeta && this.clientStore.connectedUser))
@@ -9080,8 +9200,8 @@ class Call {
9080
9200
  currentMeta.settings.ring.auto_cancel_timeout_ms,
9081
9201
  ]
9082
9202
  : [
9083
- prevMeta === null || prevMeta === void 0 ? void 0 : prevMeta.settings.ring.auto_reject_timeout_ms,
9084
- currentMeta.settings.ring.auto_reject_timeout_ms,
9203
+ prevMeta === null || prevMeta === void 0 ? void 0 : prevMeta.settings.ring.incoming_call_timeout_ms,
9204
+ currentMeta.settings.ring.incoming_call_timeout_ms,
9085
9205
  ];
9086
9206
  if (typeof timeoutMs === 'undefined' || timeoutMs === prevTimeoutMs)
9087
9207
  return;
@@ -9095,25 +9215,23 @@ class Call {
9095
9215
  });
9096
9216
  };
9097
9217
  /**
9098
- * Performs HTTP request to retrieve the list of recordings for the current call
9099
- * Updates the call state with provided array of CallRecording objects
9218
+ * Retrieves the list of recordings for the current call or call session.
9219
+ * Updates the call state with the returned array of CallRecording objects.
9220
+ *
9221
+ * If `callSessionId` is provided, it will return the recordings for that call session.
9222
+ * Otherwise, all recordings for the current call will be returned.
9223
+ *
9224
+ * @param callSessionId the call session id to retrieve recordings for.
9100
9225
  */
9101
- this.queryRecordings = () => __awaiter(this, void 0, void 0, function* () {
9102
- // FIXME: this is a temporary setting to take call ID as session ID
9103
- const sessionId = this.id;
9104
- const response = yield this.streamClient.get(`${this.streamClientBasePath}/${sessionId}/recordings`);
9226
+ this.queryRecordings = (callSessionId) => __awaiter(this, void 0, void 0, function* () {
9227
+ let endpoint = this.streamClientBasePath;
9228
+ if (callSessionId) {
9229
+ endpoint = `${endpoint}/${callSessionId}`;
9230
+ }
9231
+ const response = yield this.streamClient.get(`${endpoint}/recordings`);
9105
9232
  this.state.setCallRecordingsList(response.recordings);
9106
9233
  return response;
9107
9234
  });
9108
- /**
9109
- * Returns a list of Edge Serves for current call.
9110
- *
9111
- * @deprecated merged with `call.join`.
9112
- * @param data the data.
9113
- */
9114
- this.getEdgeServer = (data) => {
9115
- return this.streamClient.post(`${this.streamClientBasePath}/get_edge_server`, data);
9116
- };
9117
9235
  /**
9118
9236
  * Sends an event to all call participants.
9119
9237
  *
@@ -9122,12 +9240,6 @@ class Call {
9122
9240
  this.sendEvent = (event) => __awaiter(this, void 0, void 0, function* () {
9123
9241
  return this.streamClient.post(`${this.streamClientBasePath}/event`, event);
9124
9242
  });
9125
- this.accept = () => __awaiter(this, void 0, void 0, function* () {
9126
- return this.streamClient.post(`${this.streamClientBasePath}/accept`);
9127
- });
9128
- this.reject = () => __awaiter(this, void 0, void 0, function* () {
9129
- return this.streamClient.post(`${this.streamClientBasePath}/reject`);
9130
- });
9131
9243
  this.type = type;
9132
9244
  this.id = id;
9133
9245
  this.cid = `${type}:${id}`;
@@ -9143,6 +9255,7 @@ class Call {
9143
9255
  }
9144
9256
  this.state.setMetadata(metadata);
9145
9257
  this.state.setMembers(members || []);
9258
+ this.state.setOwnCapabilities(ownCapabilities || []);
9146
9259
  this.state.setCallingState(ringing ? exports.CallingState.RINGING : exports.CallingState.IDLE);
9147
9260
  this.leaveCallHooks.push(registerEventHandlers(this, this.state, this.dispatcher));
9148
9261
  this.registerEffects();
@@ -9154,23 +9267,13 @@ class Call {
9154
9267
  createSubscription(this.state.metadata$, (metadata) => {
9155
9268
  if (!metadata)
9156
9269
  return;
9157
- this.permissionsContext.setPermissions(metadata.own_capabilities);
9158
9270
  this.permissionsContext.setCallSettings(metadata.settings);
9159
9271
  }),
9160
- // handles the case when the user is blocked by the call owner.
9161
- createSubscription(this.state.metadata$, (metadata) => __awaiter(this, void 0, void 0, function* () {
9162
- if (!metadata)
9163
- return;
9164
- const currentUserId = this.currentUserId;
9165
- if (currentUserId &&
9166
- metadata.blocked_user_ids.includes(currentUserId)) {
9167
- yield this.leave();
9168
- }
9169
- })),
9170
- // handle the case when the user permissions are revoked.
9171
- createSubscription(this.state.metadata$, (metadata) => {
9172
- if (!metadata)
9173
- return;
9272
+ // handle the case when the user permissions are modified.
9273
+ createSubscription(this.state.ownCapabilities$, (ownCapabilities) => {
9274
+ // update the permission context.
9275
+ this.permissionsContext.setPermissions(ownCapabilities);
9276
+ // check if the user still has publishing permissions and stop publishing if not.
9174
9277
  const permissionToTrackType = {
9175
9278
  [OwnCapability.SEND_AUDIO]: TrackType.AUDIO,
9176
9279
  [OwnCapability.SEND_VIDEO]: TrackType.VIDEO,
@@ -9185,6 +9288,16 @@ class Call {
9185
9288
  }
9186
9289
  });
9187
9290
  }),
9291
+ // handles the case when the user is blocked by the call owner.
9292
+ createSubscription(this.state.metadata$, (metadata) => __awaiter(this, void 0, void 0, function* () {
9293
+ if (!metadata)
9294
+ return;
9295
+ const currentUserId = this.currentUserId;
9296
+ if (currentUserId &&
9297
+ metadata.blocked_user_ids.includes(currentUserId)) {
9298
+ yield this.leave();
9299
+ }
9300
+ })),
9188
9301
  // watch for auto drop cancellation
9189
9302
  createSubscription(this.state.callingState$, (callingState) => {
9190
9303
  if (!this.ringing)
@@ -10875,7 +10988,7 @@ class StreamClient {
10875
10988
  }
10876
10989
  getUserAgent() {
10877
10990
  return (this.userAgent ||
10878
- `stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${"0.0.2-alpha.1"}`);
10991
+ `stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${"0.0.2-alpha.20"}`);
10879
10992
  }
10880
10993
  setUserAgent(userAgent) {
10881
10994
  this.userAgent = userAgent;
@@ -10921,6 +11034,7 @@ class StreamVideoClient {
10921
11034
  * @param opts the options for the client.
10922
11035
  */
10923
11036
  constructor(apiKey, opts) {
11037
+ this.eventHandlersToUnregister = [];
10924
11038
  /**
10925
11039
  * Connects the given user to the client.
10926
11040
  * Only one user can connect at a time, if you want to change users, call `disconnectUser` before connecting a new user.
@@ -10933,8 +11047,8 @@ class StreamVideoClient {
10933
11047
  const connectUserResponse = yield this.streamClient.connectUser(
10934
11048
  // @ts-expect-error
10935
11049
  user, tokenOrProvider);
10936
- // FIXME OL: unregister the event listeners.
10937
- this.on('connection.changed', (e) => {
11050
+ this.writeableStateStore.setConnectedUser(user);
11051
+ this.eventHandlersToUnregister.push(this.on('connection.changed', (e) => {
10938
11052
  const event = e;
10939
11053
  if (event.online) {
10940
11054
  const callsToReWatch = this.writeableStateStore.calls
@@ -10952,9 +11066,8 @@ class StreamVideoClient {
10952
11066
  });
10953
11067
  }
10954
11068
  }
10955
- });
10956
- // FIXME: OL: unregister the event listeners.
10957
- this.on('call.created', (event) => {
11069
+ }));
11070
+ this.eventHandlersToUnregister.push(this.on('call.created', (event) => {
10958
11071
  if (event.type !== 'call.created')
10959
11072
  return;
10960
11073
  const { call, members } = event;
@@ -10968,11 +11081,36 @@ class StreamVideoClient {
10968
11081
  id: call.id,
10969
11082
  metadata: call,
10970
11083
  members,
10971
- ringing: false,
10972
11084
  clientStore: this.writeableStateStore,
10973
11085
  }));
10974
- });
10975
- this.writeableStateStore.setConnectedUser(user);
11086
+ }));
11087
+ this.eventHandlersToUnregister.push(this.on('call.ring', (event) => __awaiter(this, void 0, void 0, function* () {
11088
+ if (event.type !== 'call.ring')
11089
+ return;
11090
+ const { call, members } = event;
11091
+ if (user.id === call.created_by.id) {
11092
+ console.warn('Received `call.ring` sent by the current user');
11093
+ return;
11094
+ }
11095
+ // The call might already be tracked by the client,
11096
+ // if `call.created` was received before `call.ring`.
11097
+ // In that case, we just reuse the already tracked call.
11098
+ let theCall = this.writeableStateStore.findCall(call.type, call.id);
11099
+ if (!theCall) {
11100
+ // otherwise, we create a new call
11101
+ theCall = new Call({
11102
+ streamClient: this.streamClient,
11103
+ type: call.type,
11104
+ id: call.id,
11105
+ members,
11106
+ clientStore: this.writeableStateStore,
11107
+ ringing: true,
11108
+ });
11109
+ }
11110
+ // we fetch the latest metadata for the call from the server
11111
+ yield theCall.get({ ring: true });
11112
+ this.writeableStateStore.registerCall(theCall);
11113
+ })));
10976
11114
  return connectUserResponse;
10977
11115
  });
10978
11116
  /**
@@ -10995,6 +11133,8 @@ class StreamVideoClient {
10995
11133
  */
10996
11134
  this.disconnectUser = (timeout) => __awaiter(this, void 0, void 0, function* () {
10997
11135
  yield this.streamClient.disconnectUser(timeout);
11136
+ this.eventHandlersToUnregister.forEach((unregister) => unregister());
11137
+ this.eventHandlersToUnregister = [];
10998
11138
  this.writeableStateStore.setConnectedUser(undefined);
10999
11139
  });
11000
11140
  /**
@@ -11056,6 +11196,7 @@ class StreamVideoClient {
11056
11196
  type: c.call.type,
11057
11197
  metadata: c.call,
11058
11198
  members: c.members,
11199
+ ownCapabilities: c.own_capabilities,
11059
11200
  watching: data.watch,
11060
11201
  clientStore: this.writeableStateStore,
11061
11202
  });
@@ -11405,7 +11546,7 @@ const createSoundDetector = (audioStream, onSoundDetectedStateChanged, options =
11405
11546
  const percentage = averagedDataValue > audioLevelThreshold
11406
11547
  ? 100
11407
11548
  : Math.round((averagedDataValue / audioLevelThreshold) * 100);
11408
- onSoundDetectedStateChanged(isSoundDetected, percentage);
11549
+ onSoundDetectedStateChanged({ isSoundDetected, audioLevel: percentage });
11409
11550
  }, detectionFrequencyInMs);
11410
11551
  return function stop() {
11411
11552
  return __awaiter(this, void 0, void 0, function* () {