@stream-io/video-client 0.1.2 → 0.1.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 (36) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/index.browser.es.js +391 -68
  3. package/dist/index.browser.es.js.map +1 -1
  4. package/dist/index.cjs.js +391 -68
  5. package/dist/index.cjs.js.map +1 -1
  6. package/dist/index.es.js +391 -68
  7. package/dist/index.es.js.map +1 -1
  8. package/dist/src/StreamSfuClient.d.ts +2 -1
  9. package/dist/src/__tests__/StreamVideoClient.test.d.ts +1 -1
  10. package/dist/src/coordinator/connection/client.d.ts +2 -2
  11. package/dist/src/gen/video/sfu/event/events.d.ts +45 -2
  12. package/dist/src/gen/video/sfu/models/models.d.ts +12 -0
  13. package/dist/src/gen/video/sfu/signal_rpc/signal.client.d.ts +9 -1
  14. package/dist/src/gen/video/sfu/signal_rpc/signal.d.ts +42 -0
  15. package/dist/src/rtc/Publisher.d.ts +10 -2
  16. package/dist/src/rtc/Subscriber.d.ts +8 -3
  17. package/dist/version.d.ts +1 -1
  18. package/package.json +1 -1
  19. package/src/Call.ts +2 -0
  20. package/src/StreamSfuClient.ts +16 -5
  21. package/src/__tests__/StreamVideoClient.test.ts +85 -4
  22. package/src/__tests__/StreamVideoServerClient.test.ts +22 -0
  23. package/src/coordinator/connection/client.ts +22 -11
  24. package/src/coordinator/connection/connection.ts +2 -2
  25. package/src/coordinator/connection/connection_fallback.ts +3 -2
  26. package/src/gen/google/protobuf/struct.ts +1 -2
  27. package/src/gen/google/protobuf/timestamp.ts +1 -1
  28. package/src/gen/video/sfu/event/events.ts +165 -5
  29. package/src/gen/video/sfu/models/models.ts +13 -1
  30. package/src/gen/video/sfu/signal_rpc/signal.client.ts +27 -1
  31. package/src/gen/video/sfu/signal_rpc/signal.ts +194 -1
  32. package/src/rtc/Dispatcher.ts +1 -0
  33. package/src/rtc/Publisher.ts +69 -34
  34. package/src/rtc/Subscriber.ts +74 -7
  35. package/src/rtc/__tests__/Publisher.test.ts +82 -2
  36. package/src/rtc/__tests__/Subscriber.test.ts +84 -1
package/dist/index.es.js CHANGED
@@ -372,7 +372,6 @@ class Value$Type extends MessageType {
372
372
  };
373
373
  }
374
374
  else {
375
- Struct.fromJson(json);
376
375
  target.kind = {
377
376
  oneofKind: 'structValue',
378
377
  structValue: Struct.fromJson(json),
@@ -828,6 +827,18 @@ var ErrorCode;
828
827
  * @generated from protobuf enum value: ERROR_CODE_PARTICIPANT_MIGRATION_FAILED = 202;
829
828
  */
830
829
  ErrorCode[ErrorCode["PARTICIPANT_MIGRATION_FAILED"] = 202] = "PARTICIPANT_MIGRATION_FAILED";
830
+ /**
831
+ * @generated from protobuf enum value: ERROR_CODE_PARTICIPANT_MIGRATING = 203;
832
+ */
833
+ ErrorCode[ErrorCode["PARTICIPANT_MIGRATING"] = 203] = "PARTICIPANT_MIGRATING";
834
+ /**
835
+ * @generated from protobuf enum value: ERROR_CODE_PARTICIPANT_RECONNECT_FAILED = 204;
836
+ */
837
+ ErrorCode[ErrorCode["PARTICIPANT_RECONNECT_FAILED"] = 204] = "PARTICIPANT_RECONNECT_FAILED";
838
+ /**
839
+ * @generated from protobuf enum value: ERROR_CODE_PARTICIPANT_MEDIA_TRANSPORT_FAILURE = 205;
840
+ */
841
+ ErrorCode[ErrorCode["PARTICIPANT_MEDIA_TRANSPORT_FAILURE"] = 205] = "PARTICIPANT_MEDIA_TRANSPORT_FAILURE";
831
842
  /**
832
843
  * @generated from protobuf enum value: ERROR_CODE_CALL_NOT_FOUND = 300;
833
844
  */
@@ -2404,10 +2415,122 @@ var models = /*#__PURE__*/Object.freeze({
2404
2415
  });
2405
2416
 
2406
2417
  /* eslint-disable */
2407
- // @generated by protobuf-ts 2.8.1 with parameter long_type_string,client_generic,server_none,eslint_disable
2418
+ // @generated by protobuf-ts 2.9.0 with parameter long_type_string,client_generic,server_none,eslint_disable
2408
2419
  // @generated from protobuf file "video/sfu/signal_rpc/signal.proto" (package "stream.video.sfu.signal", syntax proto3)
2409
2420
  // tslint:disable
2410
2421
  // @generated message type with reflection information, may provide speed optimized methods
2422
+ class ICERestartRequest$Type extends MessageType {
2423
+ constructor() {
2424
+ super('stream.video.sfu.signal.ICERestartRequest', [
2425
+ { no: 1, name: 'session_id', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
2426
+ {
2427
+ no: 2,
2428
+ name: 'peer_type',
2429
+ kind: 'enum',
2430
+ T: () => ['stream.video.sfu.models.PeerType', PeerType, 'PEER_TYPE_'],
2431
+ },
2432
+ ]);
2433
+ }
2434
+ create(value) {
2435
+ const message = { sessionId: '', peerType: 0 };
2436
+ globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
2437
+ enumerable: false,
2438
+ value: this,
2439
+ });
2440
+ if (value !== undefined)
2441
+ reflectionMergePartial(this, message, value);
2442
+ return message;
2443
+ }
2444
+ internalBinaryRead(reader, length, options, target) {
2445
+ let message = target !== null && target !== void 0 ? target : this.create(), end = reader.pos + length;
2446
+ while (reader.pos < end) {
2447
+ let [fieldNo, wireType] = reader.tag();
2448
+ switch (fieldNo) {
2449
+ case /* string session_id */ 1:
2450
+ message.sessionId = reader.string();
2451
+ break;
2452
+ case /* stream.video.sfu.models.PeerType peer_type */ 2:
2453
+ message.peerType = reader.int32();
2454
+ break;
2455
+ default:
2456
+ let u = options.readUnknownField;
2457
+ if (u === 'throw')
2458
+ throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
2459
+ let d = reader.skip(wireType);
2460
+ if (u !== false)
2461
+ (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
2462
+ }
2463
+ }
2464
+ return message;
2465
+ }
2466
+ internalBinaryWrite(message, writer, options) {
2467
+ /* string session_id = 1; */
2468
+ if (message.sessionId !== '')
2469
+ writer.tag(1, WireType.LengthDelimited).string(message.sessionId);
2470
+ /* stream.video.sfu.models.PeerType peer_type = 2; */
2471
+ if (message.peerType !== 0)
2472
+ writer.tag(2, WireType.Varint).int32(message.peerType);
2473
+ let u = options.writeUnknownFields;
2474
+ if (u !== false)
2475
+ (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
2476
+ return writer;
2477
+ }
2478
+ }
2479
+ /**
2480
+ * @generated MessageType for protobuf message stream.video.sfu.signal.ICERestartRequest
2481
+ */
2482
+ const ICERestartRequest = new ICERestartRequest$Type();
2483
+ // @generated message type with reflection information, may provide speed optimized methods
2484
+ class ICERestartResponse$Type extends MessageType {
2485
+ constructor() {
2486
+ super('stream.video.sfu.signal.ICERestartResponse', [
2487
+ { no: 1, name: 'error', kind: 'message', T: () => Error$2 },
2488
+ ]);
2489
+ }
2490
+ create(value) {
2491
+ const message = {};
2492
+ globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
2493
+ enumerable: false,
2494
+ value: this,
2495
+ });
2496
+ if (value !== undefined)
2497
+ reflectionMergePartial(this, message, value);
2498
+ return message;
2499
+ }
2500
+ internalBinaryRead(reader, length, options, target) {
2501
+ let message = target !== null && target !== void 0 ? target : this.create(), end = reader.pos + length;
2502
+ while (reader.pos < end) {
2503
+ let [fieldNo, wireType] = reader.tag();
2504
+ switch (fieldNo) {
2505
+ case /* stream.video.sfu.models.Error error */ 1:
2506
+ message.error = Error$2.internalBinaryRead(reader, reader.uint32(), options, message.error);
2507
+ break;
2508
+ default:
2509
+ let u = options.readUnknownField;
2510
+ if (u === 'throw')
2511
+ throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
2512
+ let d = reader.skip(wireType);
2513
+ if (u !== false)
2514
+ (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
2515
+ }
2516
+ }
2517
+ return message;
2518
+ }
2519
+ internalBinaryWrite(message, writer, options) {
2520
+ /* stream.video.sfu.models.Error error = 1; */
2521
+ if (message.error)
2522
+ Error$2.internalBinaryWrite(message.error, writer.tag(1, WireType.LengthDelimited).fork(), options).join();
2523
+ let u = options.writeUnknownFields;
2524
+ if (u !== false)
2525
+ (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
2526
+ return writer;
2527
+ }
2528
+ }
2529
+ /**
2530
+ * @generated MessageType for protobuf message stream.video.sfu.signal.ICERestartResponse
2531
+ */
2532
+ const ICERestartResponse = new ICERestartResponse$Type();
2533
+ // @generated message type with reflection information, may provide speed optimized methods
2411
2534
  class UpdateMuteStatesRequest$Type extends MessageType {
2412
2535
  constructor() {
2413
2536
  super('stream.video.sfu.signal.UpdateMuteStatesRequest', [
@@ -3218,6 +3341,12 @@ const SignalServer = new ServiceType('stream.video.sfu.signal.SignalServer', [
3218
3341
  I: UpdateMuteStatesRequest,
3219
3342
  O: UpdateMuteStatesResponse,
3220
3343
  },
3344
+ {
3345
+ name: 'IceRestart',
3346
+ options: {},
3347
+ I: ICERestartRequest,
3348
+ O: ICERestartResponse,
3349
+ },
3221
3350
  ]);
3222
3351
 
3223
3352
  /**
@@ -3358,6 +3487,13 @@ class SfuEvent$Type extends MessageType {
3358
3487
  oneof: 'eventPayload',
3359
3488
  T: () => GoAway,
3360
3489
  },
3490
+ {
3491
+ no: 21,
3492
+ name: 'ice_restart',
3493
+ kind: 'message',
3494
+ oneof: 'eventPayload',
3495
+ T: () => ICERestart,
3496
+ },
3361
3497
  ]);
3362
3498
  }
3363
3499
  create(value) {
@@ -3471,6 +3607,12 @@ class SfuEvent$Type extends MessageType {
3471
3607
  goAway: GoAway.internalBinaryRead(reader, reader.uint32(), options, message.eventPayload.goAway),
3472
3608
  };
3473
3609
  break;
3610
+ case /* stream.video.sfu.event.ICERestart ice_restart */ 21:
3611
+ message.eventPayload = {
3612
+ oneofKind: 'iceRestart',
3613
+ iceRestart: ICERestart.internalBinaryRead(reader, reader.uint32(), options, message.eventPayload.iceRestart),
3614
+ };
3615
+ break;
3474
3616
  default:
3475
3617
  let u = options.readUnknownField;
3476
3618
  if (u === 'throw')
@@ -3531,6 +3673,9 @@ class SfuEvent$Type extends MessageType {
3531
3673
  /* stream.video.sfu.event.GoAway go_away = 20; */
3532
3674
  if (message.eventPayload.oneofKind === 'goAway')
3533
3675
  GoAway.internalBinaryWrite(message.eventPayload.goAway, writer.tag(20, WireType.LengthDelimited).fork(), options).join();
3676
+ /* stream.video.sfu.event.ICERestart ice_restart = 21; */
3677
+ if (message.eventPayload.oneofKind === 'iceRestart')
3678
+ ICERestart.internalBinaryWrite(message.eventPayload.iceRestart, writer.tag(21, WireType.LengthDelimited).fork(), options).join();
3534
3679
  let u = options.writeUnknownFields;
3535
3680
  if (u !== false)
3536
3681
  (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
@@ -3659,6 +3804,61 @@ class ICETrickle$Type extends MessageType {
3659
3804
  */
3660
3805
  const ICETrickle = new ICETrickle$Type();
3661
3806
  // @generated message type with reflection information, may provide speed optimized methods
3807
+ class ICERestart$Type extends MessageType {
3808
+ constructor() {
3809
+ super('stream.video.sfu.event.ICERestart', [
3810
+ {
3811
+ no: 1,
3812
+ name: 'peer_type',
3813
+ kind: 'enum',
3814
+ T: () => ['stream.video.sfu.models.PeerType', PeerType, 'PEER_TYPE_'],
3815
+ },
3816
+ ]);
3817
+ }
3818
+ create(value) {
3819
+ const message = { peerType: 0 };
3820
+ globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
3821
+ enumerable: false,
3822
+ value: this,
3823
+ });
3824
+ if (value !== undefined)
3825
+ reflectionMergePartial(this, message, value);
3826
+ return message;
3827
+ }
3828
+ internalBinaryRead(reader, length, options, target) {
3829
+ let message = target !== null && target !== void 0 ? target : this.create(), end = reader.pos + length;
3830
+ while (reader.pos < end) {
3831
+ let [fieldNo, wireType] = reader.tag();
3832
+ switch (fieldNo) {
3833
+ case /* stream.video.sfu.models.PeerType peer_type */ 1:
3834
+ message.peerType = reader.int32();
3835
+ break;
3836
+ default:
3837
+ let u = options.readUnknownField;
3838
+ if (u === 'throw')
3839
+ throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
3840
+ let d = reader.skip(wireType);
3841
+ if (u !== false)
3842
+ (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
3843
+ }
3844
+ }
3845
+ return message;
3846
+ }
3847
+ internalBinaryWrite(message, writer, options) {
3848
+ /* stream.video.sfu.models.PeerType peer_type = 1; */
3849
+ if (message.peerType !== 0)
3850
+ writer.tag(1, WireType.Varint).int32(message.peerType);
3851
+ let u = options.writeUnknownFields;
3852
+ if (u !== false)
3853
+ (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
3854
+ return writer;
3855
+ }
3856
+ }
3857
+ /**
3858
+ * @generated MessageType for protobuf message stream.video.sfu.event.ICERestart
3859
+ */
3860
+ const ICERestart = new ICERestart$Type();
3861
+ // @generated message type with reflection information, may provide speed optimized methods
3662
3862
  class SfuRequest$Type extends MessageType {
3663
3863
  constructor() {
3664
3864
  super('stream.video.sfu.event.SfuRequest', [
@@ -4012,10 +4212,21 @@ class JoinRequest$Type extends MessageType {
4012
4212
  T: () => ClientDetails,
4013
4213
  },
4014
4214
  { no: 5, name: 'migration', kind: 'message', T: () => Migration },
4215
+ {
4216
+ no: 6,
4217
+ name: 'fast_reconnect',
4218
+ kind: 'scalar',
4219
+ T: 8 /*ScalarType.BOOL*/,
4220
+ },
4015
4221
  ]);
4016
4222
  }
4017
4223
  create(value) {
4018
- const message = { token: '', sessionId: '', subscriberSdp: '' };
4224
+ const message = {
4225
+ token: '',
4226
+ sessionId: '',
4227
+ subscriberSdp: '',
4228
+ fastReconnect: false,
4229
+ };
4019
4230
  globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
4020
4231
  enumerable: false,
4021
4232
  value: this,
@@ -4044,6 +4255,9 @@ class JoinRequest$Type extends MessageType {
4044
4255
  case /* stream.video.sfu.event.Migration migration */ 5:
4045
4256
  message.migration = Migration.internalBinaryRead(reader, reader.uint32(), options, message.migration);
4046
4257
  break;
4258
+ case /* bool fast_reconnect */ 6:
4259
+ message.fastReconnect = reader.bool();
4260
+ break;
4047
4261
  default:
4048
4262
  let u = options.readUnknownField;
4049
4263
  if (u === 'throw')
@@ -4071,6 +4285,9 @@ class JoinRequest$Type extends MessageType {
4071
4285
  /* stream.video.sfu.event.Migration migration = 5; */
4072
4286
  if (message.migration)
4073
4287
  Migration.internalBinaryWrite(message.migration, writer.tag(5, WireType.LengthDelimited).fork(), options).join();
4288
+ /* bool fast_reconnect = 6; */
4289
+ if (message.fastReconnect !== false)
4290
+ writer.tag(6, WireType.Varint).bool(message.fastReconnect);
4074
4291
  let u = options.writeUnknownFields;
4075
4292
  if (u !== false)
4076
4293
  (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
@@ -4167,10 +4384,11 @@ class JoinResponse$Type extends MessageType {
4167
4384
  constructor() {
4168
4385
  super('stream.video.sfu.event.JoinResponse', [
4169
4386
  { no: 1, name: 'call_state', kind: 'message', T: () => CallState$1 },
4387
+ { no: 2, name: 'reconnected', kind: 'scalar', T: 8 /*ScalarType.BOOL*/ },
4170
4388
  ]);
4171
4389
  }
4172
4390
  create(value) {
4173
- const message = {};
4391
+ const message = { reconnected: false };
4174
4392
  globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
4175
4393
  enumerable: false,
4176
4394
  value: this,
@@ -4187,6 +4405,9 @@ class JoinResponse$Type extends MessageType {
4187
4405
  case /* stream.video.sfu.models.CallState call_state */ 1:
4188
4406
  message.callState = CallState$1.internalBinaryRead(reader, reader.uint32(), options, message.callState);
4189
4407
  break;
4408
+ case /* bool reconnected */ 2:
4409
+ message.reconnected = reader.bool();
4410
+ break;
4190
4411
  default:
4191
4412
  let u = options.readUnknownField;
4192
4413
  if (u === 'throw')
@@ -4202,6 +4423,9 @@ class JoinResponse$Type extends MessageType {
4202
4423
  /* stream.video.sfu.models.CallState call_state = 1; */
4203
4424
  if (message.callState)
4204
4425
  CallState$1.internalBinaryWrite(message.callState, writer.tag(1, WireType.LengthDelimited).fork(), options).join();
4426
+ /* bool reconnected = 2; */
4427
+ if (message.reconnected !== false)
4428
+ writer.tag(2, WireType.Varint).bool(message.reconnected);
4205
4429
  let u = options.writeUnknownFields;
4206
4430
  if (u !== false)
4207
4431
  (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
@@ -5318,6 +5542,7 @@ var events = /*#__PURE__*/Object.freeze({
5318
5542
  GoAway: GoAway,
5319
5543
  HealthCheckRequest: HealthCheckRequest,
5320
5544
  HealthCheckResponse: HealthCheckResponse,
5545
+ ICERestart: ICERestart,
5321
5546
  ICETrickle: ICETrickle,
5322
5547
  JoinRequest: JoinRequest,
5323
5548
  JoinResponse: JoinResponse,
@@ -5434,6 +5659,13 @@ class SignalServerClient {
5434
5659
  const method = this.methods[4], opt = this._transport.mergeOptions(options);
5435
5660
  return stackIntercept('unary', this._transport, method, opt, input);
5436
5661
  }
5662
+ /**
5663
+ * @generated from protobuf rpc: IceRestart(stream.video.sfu.signal.ICERestartRequest) returns (stream.video.sfu.signal.ICERestartResponse);
5664
+ */
5665
+ iceRestart(input, options) {
5666
+ const method = this.methods[5], opt = this._transport.mergeOptions(options);
5667
+ return stackIntercept('unary', this._transport, method, opt, input);
5668
+ }
5437
5669
  }
5438
5670
 
5439
5671
  const defaultOptions = {
@@ -5668,7 +5900,7 @@ const logLevels = Object.freeze({
5668
5900
  warn: 3,
5669
5901
  error: 4,
5670
5902
  });
5671
- let logger$3;
5903
+ let logger$4;
5672
5904
  let level = 'info';
5673
5905
  const logToConsole = (logLevel, message, ...args) => {
5674
5906
  let logMethod;
@@ -5692,7 +5924,7 @@ const logToConsole = (logLevel, message, ...args) => {
5692
5924
  logMethod(message, ...args);
5693
5925
  };
5694
5926
  const setLogger = (l, lvl) => {
5695
- logger$3 = l;
5927
+ logger$4 = l;
5696
5928
  if (lvl) {
5697
5929
  setLogLevel(lvl);
5698
5930
  }
@@ -5701,7 +5933,7 @@ const setLogLevel = (l) => {
5701
5933
  level = l;
5702
5934
  };
5703
5935
  const getLogger = (withTags) => {
5704
- const loggerMethod = logger$3 || logToConsole;
5936
+ const loggerMethod = logger$4 || logToConsole;
5705
5937
  const tags = (withTags || []).join(':');
5706
5938
  const result = (logLevel, message, ...args) => {
5707
5939
  if (logLevels[logLevel] >= logLevels[level]) {
@@ -5808,6 +6040,7 @@ const sfuEventKinds = {
5808
6040
  error: undefined,
5809
6041
  callGrantsUpdated: undefined,
5810
6042
  goAway: undefined,
6043
+ iceRestart: undefined,
5811
6044
  };
5812
6045
  const isSfuEvent = (eventName) => {
5813
6046
  return Object.prototype.hasOwnProperty.call(sfuEventKinds, eventName);
@@ -6033,6 +6266,7 @@ const muteTypeToTrackType = (muteType) => {
6033
6266
  }
6034
6267
  };
6035
6268
 
6269
+ const logger$3 = getLogger(['Publisher']);
6036
6270
  /**
6037
6271
  * The `Publisher` is responsible for publishing/unpublishing media streams to/from the SFU
6038
6272
  * @internal
@@ -6044,11 +6278,13 @@ class Publisher {
6044
6278
  * @param connectionConfig the connection configuration to use.
6045
6279
  * @param sfuClient the SFU client to use.
6046
6280
  * @param state the call state to use.
6281
+ * @param dispatcher the dispatcher to use.
6047
6282
  * @param isDtxEnabled whether DTX is enabled.
6048
6283
  * @param isRedEnabled whether RED is enabled.
6049
6284
  * @param preferredVideoCodec the preferred video codec.
6285
+ * @param iceRestartDelay the delay in milliseconds to wait before restarting ICE once connection goes to `disconnected` state.
6050
6286
  */
6051
- constructor({ connectionConfig, sfuClient, state, isDtxEnabled, isRedEnabled, preferredVideoCodec, }) {
6287
+ constructor({ connectionConfig, sfuClient, dispatcher, state, isDtxEnabled, isRedEnabled, preferredVideoCodec, iceRestartDelay = 2500, }) {
6052
6288
  this.transceiverRegistry = {
6053
6289
  [TrackType.AUDIO]: undefined,
6054
6290
  [TrackType.VIDEO]: undefined,
@@ -6078,7 +6314,7 @@ class Publisher {
6078
6314
  [TrackType.SCREEN_SHARE_AUDIO]: undefined,
6079
6315
  [TrackType.UNSPECIFIED]: undefined,
6080
6316
  };
6081
- this.logger = getLogger(['Publisher']);
6317
+ this.isIceRestarting = false;
6082
6318
  this.createPeerConnection = (connectionConfig) => {
6083
6319
  const pc = new RTCPeerConnection(connectionConfig);
6084
6320
  pc.addEventListener('icecandidate', this.onIceCandidate);
@@ -6104,6 +6340,7 @@ class Publisher {
6104
6340
  this.trackLayersCache[trackType] = undefined;
6105
6341
  });
6106
6342
  }
6343
+ this.unsubscribeOnIceRestart();
6107
6344
  this.pc.removeEventListener('negotiationneeded', this.onNegotiationNeeded);
6108
6345
  this.pc.close();
6109
6346
  };
@@ -6134,7 +6371,7 @@ class Publisher {
6134
6371
  * Once the track has ended, it will notify the SFU and update the state.
6135
6372
  */
6136
6373
  const handleTrackEnded = () => __awaiter(this, void 0, void 0, function* () {
6137
- this.logger('info', `Track ${TrackType[trackType]} has ended, notifying the SFU`);
6374
+ logger$3('info', `Track ${TrackType[trackType]} has ended, notifying the SFU`);
6138
6375
  yield this.notifyTrackMuteStateChanged(mediaStream, track, trackType, true);
6139
6376
  // clean-up, this event listener needs to run only once.
6140
6377
  track.removeEventListener('ended', handleTrackEnded);
@@ -6157,11 +6394,11 @@ class Publisher {
6157
6394
  : undefined,
6158
6395
  sendEncodings: videoEncodings,
6159
6396
  });
6160
- this.logger('debug', `Added ${TrackType[trackType]} transceiver`);
6397
+ logger$3('debug', `Added ${TrackType[trackType]} transceiver`);
6161
6398
  this.transceiverInitOrder.push(trackType);
6162
6399
  this.transceiverRegistry[trackType] = transceiver;
6163
6400
  if ('setCodecPreferences' in transceiver && codecPreferences) {
6164
- this.logger('info', `Setting ${TrackType[trackType]} codec preferences`, codecPreferences);
6401
+ logger$3('info', `Setting ${TrackType[trackType]} codec preferences`, codecPreferences);
6165
6402
  transceiver.setCodecPreferences(codecPreferences);
6166
6403
  }
6167
6404
  }
@@ -6229,7 +6466,7 @@ class Publisher {
6229
6466
  * Stops publishing all tracks and stop all tracks.
6230
6467
  */
6231
6468
  this.stopPublishing = () => {
6232
- this.logger('debug', 'Stopping publishing all tracks');
6469
+ logger$3('debug', 'Stopping publishing all tracks');
6233
6470
  this.pc.getSenders().forEach((s) => {
6234
6471
  var _a;
6235
6472
  (_a = s.track) === null || _a === void 0 ? void 0 : _a.stop();
@@ -6240,15 +6477,15 @@ class Publisher {
6240
6477
  };
6241
6478
  this.updateVideoPublishQuality = (enabledRids) => __awaiter(this, void 0, void 0, function* () {
6242
6479
  var _a;
6243
- this.logger('info', 'Update publish quality, requested rids by SFU:', enabledRids);
6480
+ logger$3('info', 'Update publish quality, requested rids by SFU:', enabledRids);
6244
6481
  const videoSender = (_a = this.transceiverRegistry[TrackType.VIDEO]) === null || _a === void 0 ? void 0 : _a.sender;
6245
6482
  if (!videoSender) {
6246
- this.logger('warn', 'Update publish quality, no video sender found.');
6483
+ logger$3('warn', 'Update publish quality, no video sender found.');
6247
6484
  return;
6248
6485
  }
6249
6486
  const params = videoSender.getParameters();
6250
6487
  if (params.encodings.length === 0) {
6251
- this.logger('warn', 'Update publish quality, No suitable video encoding quality found');
6488
+ logger$3('warn', 'Update publish quality, No suitable video encoding quality found');
6252
6489
  return;
6253
6490
  }
6254
6491
  let changed = false;
@@ -6266,10 +6503,10 @@ class Publisher {
6266
6503
  .join(', ');
6267
6504
  if (changed) {
6268
6505
  yield videoSender.setParameters(params);
6269
- this.logger('info', `Update publish quality, enabled rids: ${activeRids}`);
6506
+ logger$3('info', `Update publish quality, enabled rids: ${activeRids}`);
6270
6507
  }
6271
6508
  else {
6272
- this.logger('info', `Update publish quality, no change: ${activeRids}`);
6509
+ logger$3('info', `Update publish quality, no change: ${activeRids}`);
6273
6510
  }
6274
6511
  });
6275
6512
  /**
@@ -6293,7 +6530,7 @@ class Publisher {
6293
6530
  this.onIceCandidate = (e) => __awaiter(this, void 0, void 0, function* () {
6294
6531
  const { candidate } = e;
6295
6532
  if (!candidate) {
6296
- this.logger('debug', 'null ice candidate');
6533
+ logger$3('debug', 'null ice candidate');
6297
6534
  return;
6298
6535
  }
6299
6536
  yield this.sfuClient.iceTrickle({
@@ -6322,7 +6559,12 @@ class Publisher {
6322
6559
  * Restarts the ICE connection and renegotiates with the SFU.
6323
6560
  */
6324
6561
  this.restartIce = () => __awaiter(this, void 0, void 0, function* () {
6325
- this.logger('debug', 'Restarting ICE connection');
6562
+ logger$3('debug', 'Restarting ICE connection');
6563
+ const signalingState = this.pc.signalingState;
6564
+ if (this.isIceRestarting || signalingState === 'have-local-offer') {
6565
+ logger$3('debug', 'ICE restart is already in progress');
6566
+ return;
6567
+ }
6326
6568
  yield this.negotiate({ iceRestart: true });
6327
6569
  });
6328
6570
  this.onNegotiationNeeded = () => __awaiter(this, void 0, void 0, function* () {
@@ -6334,6 +6576,8 @@ class Publisher {
6334
6576
  * @param options the optional offer options to use.
6335
6577
  */
6336
6578
  this.negotiate = (options) => __awaiter(this, void 0, void 0, function* () {
6579
+ var _b;
6580
+ this.isIceRestarting = (_b = options === null || options === void 0 ? void 0 : options.iceRestart) !== null && _b !== void 0 ? _b : false;
6337
6581
  const offer = yield this.pc.createOffer(options);
6338
6582
  offer.sdp = this.mungeCodecs(offer.sdp);
6339
6583
  const trackInfos = this.getCurrentTrackInfos(offer.sdp);
@@ -6352,21 +6596,19 @@ class Publisher {
6352
6596
  });
6353
6597
  }
6354
6598
  catch (e) {
6355
- this.logger('error', `setRemoteDescription error`, {
6599
+ logger$3('error', `setRemoteDescription error`, {
6356
6600
  sdp: response.sdp,
6357
6601
  error: e,
6358
6602
  });
6359
6603
  }
6604
+ this.isIceRestarting = false;
6360
6605
  this.sfuClient.iceTrickleBuffer.publisherCandidates.subscribe((candidate) => __awaiter(this, void 0, void 0, function* () {
6361
6606
  try {
6362
6607
  const iceCandidate = JSON.parse(candidate.iceCandidate);
6363
6608
  yield this.pc.addIceCandidate(iceCandidate);
6364
6609
  }
6365
6610
  catch (e) {
6366
- this.logger('error', `ICE candidate error`, {
6367
- error: e,
6368
- candidate,
6369
- });
6611
+ logger$3('warn', `ICE candidate error`, [e, candidate]);
6370
6612
  }
6371
6613
  }));
6372
6614
  });
@@ -6392,10 +6634,10 @@ class Publisher {
6392
6634
  if (defaultMid)
6393
6635
  return defaultMid;
6394
6636
  if (!sdp) {
6395
- this.logger('warn', 'No SDP found. Returning empty mid');
6637
+ logger$3('warn', 'No SDP found. Returning empty mid');
6396
6638
  return '';
6397
6639
  }
6398
- this.logger('debug', `No 'mid' found for track. Trying to find it from the Offer SDP`);
6640
+ logger$3('debug', `No 'mid' found for track. Trying to find it from the Offer SDP`);
6399
6641
  const parsedSdp = SDP.parse(sdp);
6400
6642
  const media = parsedSdp.media.find((m) => {
6401
6643
  var _a, _b;
@@ -6404,12 +6646,12 @@ class Publisher {
6404
6646
  ((_b = (_a = m.msid) === null || _a === void 0 ? void 0 : _a.includes(track.id)) !== null && _b !== void 0 ? _b : true));
6405
6647
  });
6406
6648
  if (typeof (media === null || media === void 0 ? void 0 : media.mid) === 'undefined') {
6407
- this.logger('debug', `No mid found in SDP for track type ${track.kind} and id ${track.id}. Attempting to find a heuristic mid`);
6649
+ logger$3('debug', `No mid found in SDP for track type ${track.kind} and id ${track.id}. Attempting to find a heuristic mid`);
6408
6650
  const heuristicMid = this.transceiverInitOrder.indexOf(trackType);
6409
6651
  if (heuristicMid !== -1) {
6410
6652
  return String(heuristicMid);
6411
6653
  }
6412
- this.logger('debug', 'No heuristic mid found. Returning empty mid');
6654
+ logger$3('debug', 'No heuristic mid found. Returning empty mid');
6413
6655
  return '';
6414
6656
  }
6415
6657
  return String(media.mid);
@@ -6435,7 +6677,7 @@ class Publisher {
6435
6677
  else {
6436
6678
  // we report the last known optimal layers for ended tracks
6437
6679
  optimalLayers = this.trackLayersCache[trackType] || [];
6438
- this.logger('debug', `Track ${TrackType[trackType]} is ended. Announcing last known optimal layers`, optimalLayers);
6680
+ logger$3('debug', `Track ${TrackType[trackType]} is ended. Announcing last known optimal layers`, optimalLayers);
6439
6681
  }
6440
6682
  const layers = optimalLayers.map((optimalLayer) => ({
6441
6683
  rid: optimalLayer.rid || '',
@@ -6462,38 +6704,41 @@ class Publisher {
6462
6704
  this.onIceCandidateError = (e) => {
6463
6705
  const errorMessage = e instanceof RTCPeerConnectionIceErrorEvent &&
6464
6706
  `${e.errorCode}: ${e.errorText}`;
6465
- this.logger('error', `ICE Candidate error`, errorMessage);
6707
+ logger$3('error', `ICE Candidate error`, errorMessage);
6466
6708
  };
6467
6709
  this.onIceConnectionStateChange = () => {
6468
6710
  const state = this.pc.iceConnectionState;
6469
- this.logger('debug', `ICE Connection state changed to`, state);
6711
+ logger$3('debug', `ICE Connection state changed to`, state);
6470
6712
  if (state === 'failed') {
6471
- this.logger('warn', `Attempting to restart ICE`);
6713
+ logger$3('warn', `Attempting to restart ICE`);
6472
6714
  this.restartIce().catch((e) => {
6473
- this.logger('error', `ICE restart error`, e);
6715
+ logger$3('error', `ICE restart error`, e);
6474
6716
  });
6475
6717
  }
6476
6718
  else if (state === 'disconnected') {
6477
6719
  // when in `disconnected` state, the browser may recover automatically,
6478
6720
  // hence, we delay the ICE restart
6479
- this.logger('warn', `Scheduling ICE restart in 5 seconds`);
6721
+ logger$3('warn', `Scheduling ICE restart in ${this.iceRestartDelay} ms.`);
6480
6722
  setTimeout(() => {
6481
6723
  // check if the state is still `disconnected` or `failed`
6482
6724
  // as the connection may have recovered (or failed) in the meantime
6483
6725
  if (this.pc.iceConnectionState === 'disconnected' ||
6484
6726
  this.pc.iceConnectionState === 'failed') {
6485
6727
  this.restartIce().catch((e) => {
6486
- this.logger('error', `ICE restart error`, e);
6728
+ logger$3('error', `ICE restart error`, e);
6487
6729
  });
6488
6730
  }
6489
- }, 5000);
6731
+ else {
6732
+ logger$3('debug', `Scheduled ICE restart: connection recovered, canceled.`);
6733
+ }
6734
+ }, this.iceRestartDelay);
6490
6735
  }
6491
6736
  };
6492
6737
  this.onIceGatheringStateChange = () => {
6493
- this.logger('debug', `ICE Gathering State`, this.pc.iceGatheringState);
6738
+ logger$3('debug', `ICE Gathering State`, this.pc.iceGatheringState);
6494
6739
  };
6495
6740
  this.onSignalingStateChange = () => {
6496
- this.logger('debug', `Signaling state changed`, this.pc.signalingState);
6741
+ logger$3('debug', `Signaling state changed`, this.pc.signalingState);
6497
6742
  };
6498
6743
  this.ridToVideoQuality = (rid) => {
6499
6744
  return rid === 'q'
@@ -6505,9 +6750,19 @@ class Publisher {
6505
6750
  this.pc = this.createPeerConnection(connectionConfig);
6506
6751
  this.sfuClient = sfuClient;
6507
6752
  this.state = state;
6753
+ this.dispatcher = dispatcher;
6508
6754
  this.isDtxEnabled = isDtxEnabled;
6509
6755
  this.isRedEnabled = isRedEnabled;
6510
6756
  this.preferredVideoCodec = preferredVideoCodec;
6757
+ this.iceRestartDelay = iceRestartDelay;
6758
+ this.unsubscribeOnIceRestart = dispatcher.on('iceRestart', (message) => __awaiter(this, void 0, void 0, function* () {
6759
+ if (message.eventPayload.oneofKind !== 'iceRestart')
6760
+ return;
6761
+ const { iceRestart } = message.eventPayload;
6762
+ if (iceRestart.peerType !== PeerType.PUBLISHER_UNSPECIFIED)
6763
+ return;
6764
+ yield this.restartIce();
6765
+ }));
6511
6766
  }
6512
6767
  }
6513
6768
 
@@ -6524,8 +6779,10 @@ class Subscriber {
6524
6779
  * @param dispatcher the dispatcher to use.
6525
6780
  * @param state the state of the call.
6526
6781
  * @param connectionConfig the connection configuration to use.
6782
+ * @param iceRestartDelay the delay in milliseconds to wait before restarting ICE when connection goes to `disconnected` state.
6527
6783
  */
6528
- constructor({ sfuClient, dispatcher, state, connectionConfig, }) {
6784
+ constructor({ sfuClient, dispatcher, state, connectionConfig, iceRestartDelay = 2500, }) {
6785
+ this.isIceRestarting = false;
6529
6786
  /**
6530
6787
  * Creates a new `RTCPeerConnection` instance with the given configuration.
6531
6788
  *
@@ -6545,6 +6802,7 @@ class Subscriber {
6545
6802
  */
6546
6803
  this.close = () => {
6547
6804
  this.unregisterOnSubscriberOffer();
6805
+ this.unregisterOnIceRestart();
6548
6806
  this.pc.close();
6549
6807
  };
6550
6808
  /**
@@ -6617,10 +6875,25 @@ class Subscriber {
6617
6875
  /**
6618
6876
  * Restarts the ICE connection and renegotiates with the SFU.
6619
6877
  */
6620
- this.restartIce = () => {
6878
+ this.restartIce = () => __awaiter(this, void 0, void 0, function* () {
6621
6879
  logger$2('debug', 'Restarting ICE connection');
6622
- this.pc.restartIce();
6623
- };
6880
+ if (this.pc.signalingState === 'have-remote-offer') {
6881
+ logger$2('debug', 'ICE restart is already in progress');
6882
+ return;
6883
+ }
6884
+ const previousIsIceRestarting = this.isIceRestarting;
6885
+ try {
6886
+ this.isIceRestarting = true;
6887
+ yield this.sfuClient.iceRestart({
6888
+ peerType: PeerType.SUBSCRIBER,
6889
+ });
6890
+ }
6891
+ catch (e) {
6892
+ // restore the previous state, as our intent for restarting ICE failed
6893
+ this.isIceRestarting = previousIsIceRestarting;
6894
+ throw e;
6895
+ }
6896
+ });
6624
6897
  this.handleOnTrack = (e) => {
6625
6898
  const [primaryStream] = e.streams;
6626
6899
  // example: `e3f6aaf8-b03d-4911-be36-83f47d37a76a:TRACK_TYPE_VIDEO`
@@ -6684,22 +6957,50 @@ class Subscriber {
6684
6957
  yield this.pc.addIceCandidate(iceCandidate);
6685
6958
  }
6686
6959
  catch (e) {
6687
- logger$2('error', `ICE candidate error`, [e, candidate]);
6960
+ logger$2('warn', `ICE candidate error`, [e, candidate]);
6688
6961
  }
6689
6962
  }));
6690
- // apply ice candidates
6691
6963
  const answer = yield this.pc.createAnswer();
6692
6964
  yield this.pc.setLocalDescription(answer);
6693
6965
  yield this.sfuClient.sendAnswer({
6694
6966
  peerType: PeerType.SUBSCRIBER,
6695
6967
  sdp: answer.sdp || '',
6696
6968
  });
6969
+ this.isIceRestarting = false;
6697
6970
  });
6698
6971
  this.onIceConnectionStateChange = () => {
6699
- logger$2('info', `ICE connection state changed`, this.pc.iceConnectionState);
6972
+ const state = this.pc.iceConnectionState;
6973
+ logger$2('debug', `ICE connection state changed`, state);
6974
+ // do nothing when ICE is restarting
6975
+ if (this.isIceRestarting)
6976
+ return;
6977
+ if (state === 'failed') {
6978
+ logger$2('warn', `Attempting to restart ICE`);
6979
+ this.restartIce().catch((e) => {
6980
+ logger$2('error', `ICE restart failed`, e);
6981
+ });
6982
+ }
6983
+ else if (state === 'disconnected') {
6984
+ // when in `disconnected` state, the browser may recover automatically,
6985
+ // hence, we delay the ICE restart
6986
+ logger$2('warn', `Scheduling ICE restart in ${this.iceRestartDelay} ms.`);
6987
+ setTimeout(() => {
6988
+ // check if the state is still `disconnected` or `failed`
6989
+ // as the connection may have recovered (or failed) in the meantime
6990
+ if (this.pc.iceConnectionState === 'disconnected' ||
6991
+ this.pc.iceConnectionState === 'failed') {
6992
+ this.restartIce().catch((e) => {
6993
+ logger$2('error', `ICE restart failed`, e);
6994
+ });
6995
+ }
6996
+ else {
6997
+ logger$2('debug', `Scheduled ICE restart: connection recovered, canceled.`);
6998
+ }
6999
+ }, 5000);
7000
+ }
6700
7001
  };
6701
7002
  this.onIceGatheringStateChange = () => {
6702
- logger$2('info', `ICE gathering state changed`, this.pc.iceGatheringState);
7003
+ logger$2('debug', `ICE gathering state changed`, this.pc.iceGatheringState);
6703
7004
  };
6704
7005
  this.onIceCandidateError = (e) => {
6705
7006
  const errorMessage = e instanceof RTCPeerConnectionIceErrorEvent &&
@@ -6709,6 +7010,7 @@ class Subscriber {
6709
7010
  this.sfuClient = sfuClient;
6710
7011
  this.dispatcher = dispatcher;
6711
7012
  this.state = state;
7013
+ this.iceRestartDelay = iceRestartDelay;
6712
7014
  this.pc = this.createPeerConnection(connectionConfig);
6713
7015
  this.unregisterOnSubscriberOffer = dispatcher.on('subscriberOffer', (message) => __awaiter(this, void 0, void 0, function* () {
6714
7016
  if (message.eventPayload.oneofKind !== 'subscriberOffer')
@@ -6716,6 +7018,14 @@ class Subscriber {
6716
7018
  const { subscriberOffer } = message.eventPayload;
6717
7019
  yield this.negotiate(subscriberOffer);
6718
7020
  }));
7021
+ this.unregisterOnIceRestart = dispatcher.on('iceRestart', (message) => __awaiter(this, void 0, void 0, function* () {
7022
+ if (message.eventPayload.oneofKind !== 'iceRestart')
7023
+ return;
7024
+ const { iceRestart } = message.eventPayload;
7025
+ if (iceRestart.peerType !== PeerType.SUBSCRIBER)
7026
+ return;
7027
+ yield this.restartIce();
7028
+ }));
6719
7029
  }
6720
7030
  }
6721
7031
 
@@ -6902,6 +7212,7 @@ class StreamSfuClient {
6902
7212
  this.pingIntervalInMs = 10 * 1000;
6903
7213
  this.unhealthyTimeoutInMs = this.pingIntervalInMs + 5 * 1000;
6904
7214
  this.close = (code = 1000, reason = 'Requested signal connection close') => {
7215
+ this.logger('debug', 'Closing SFU WS connection', code, reason);
6905
7216
  this.signalWs.close(code, reason);
6906
7217
  this.unsubscribeIceTrickle();
6907
7218
  clearInterval(this.keepAliveInterval);
@@ -6922,6 +7233,9 @@ class StreamSfuClient {
6922
7233
  this.iceTrickle = (data) => __awaiter(this, void 0, void 0, function* () {
6923
7234
  return retryable(() => this.rpc.iceTrickle(Object.assign(Object.assign({}, data), { sessionId: this.sessionId })), this.logger);
6924
7235
  });
7236
+ this.iceRestart = (data) => __awaiter(this, void 0, void 0, function* () {
7237
+ return retryable(() => this.rpc.iceRestart(Object.assign(Object.assign({}, data), { sessionId: this.sessionId })), this.logger);
7238
+ });
6925
7239
  this.updateMuteState = (trackType, muted) => __awaiter(this, void 0, void 0, function* () {
6926
7240
  return this.updateMuteStates({
6927
7241
  muteStates: [
@@ -6973,7 +7287,6 @@ class StreamSfuClient {
6973
7287
  if (this.lastMessageTimestamp) {
6974
7288
  const timeSinceLastMessage = new Date().getTime() - this.lastMessageTimestamp.getTime();
6975
7289
  if (timeSinceLastMessage > this.unhealthyTimeoutInMs) {
6976
- this.logger('debug', 'SFU connection unhealthy, closing');
6977
7290
  this.close(4001, `SFU connection unhealthy. Didn't receive any healthcheck messages for ${this.unhealthyTimeoutInMs}ms`);
6978
7291
  }
6979
7292
  }
@@ -6984,10 +7297,9 @@ class StreamSfuClient {
6984
7297
  this.edgeName = sfuServer.edge_name;
6985
7298
  this.token = token;
6986
7299
  this.logger = getLogger(['sfu-client']);
6987
- const logger = this.logger;
6988
7300
  const logInterceptor = {
6989
- interceptUnary(next, method, input, options) {
6990
- logger('trace', `Calling SFU RPC method ${method.name}`, {
7301
+ interceptUnary: (next, method, input, options) => {
7302
+ this.logger('trace', `Calling SFU RPC method ${method.name}`, {
6991
7303
  input,
6992
7304
  options,
6993
7305
  });
@@ -9463,6 +9775,7 @@ class Call {
9463
9775
  if (!this.publisher) {
9464
9776
  this.publisher = new Publisher({
9465
9777
  sfuClient,
9778
+ dispatcher: this.dispatcher,
9466
9779
  state: this.state,
9467
9780
  connectionConfig,
9468
9781
  isDtxEnabled,
@@ -9499,6 +9812,7 @@ class Call {
9499
9812
  subscriberSdp: sdp || '',
9500
9813
  clientDetails: getClientDetails(),
9501
9814
  migration,
9815
+ fastReconnect: false,
9502
9816
  });
9503
9817
  });
9504
9818
  // 2. in parallel, wait for the SFU to send us the "joinResponse"
@@ -10726,6 +11040,7 @@ class StableWSConnection {
10726
11040
  * @return {ConnectAPIResponse<ConnectedEvent>} Promise that completes once the first health check message is received
10727
11041
  */
10728
11042
  _connect() {
11043
+ var _a, _b, _c, _d;
10729
11044
  return __awaiter(this, void 0, void 0, function* () {
10730
11045
  if (this.isConnecting ||
10731
11046
  (this.isDisconnected && this.client.options.enableWSFallback))
@@ -10762,7 +11077,7 @@ class StableWSConnection {
10762
11077
  this.isConnecting = false;
10763
11078
  if (response) {
10764
11079
  this.connectionID = response.connection_id;
10765
- this.client.resolveConnectionId(this.connectionID);
11080
+ (_b = (_a = this.client).resolveConnectionId) === null || _b === void 0 ? void 0 : _b.call(_a, this.connectionID);
10766
11081
  if (this.client.insightMetrics.wsConsecutiveFailures > 0 &&
10767
11082
  this.client.options.enableInsights) {
10768
11083
  postInsights('ws_success_after_failure', buildWsSuccessAfterFailureInsight(this));
@@ -10781,7 +11096,7 @@ class StableWSConnection {
10781
11096
  const insights = buildWsFatalInsight(this, convertErrorToJson(err));
10782
11097
  postInsights === null || postInsights === void 0 ? void 0 : postInsights('ws_fatal', insights);
10783
11098
  }
10784
- this.client.rejectConnectionId();
11099
+ (_d = (_c = this.client).rejectConnectionId) === null || _d === void 0 ? void 0 : _d.call(_c);
10785
11100
  throw err;
10786
11101
  }
10787
11102
  });
@@ -11190,6 +11505,7 @@ class WSConnectionFallback {
11190
11505
  undefined, {
11191
11506
  config: Object.assign(Object.assign({}, config), { cancelToken: (_a = this.cancelToken) === null || _a === void 0 ? void 0 : _a.token }),
11192
11507
  params,
11508
+ publicEndpoint: true,
11193
11509
  });
11194
11510
  this.consecutiveFailures = 0; // always reset in case of no error
11195
11511
  return res;
@@ -11246,6 +11562,7 @@ class WSConnectionFallback {
11246
11562
  * @param reconnect should be false for first call and true for subsequent calls to keep the connection alive and call recoverState
11247
11563
  */
11248
11564
  this.connect = (reconnect = false) => __awaiter(this, void 0, void 0, function* () {
11565
+ var _c, _d, _e, _f;
11249
11566
  if (this.state === ConnectionState.Connecting) {
11250
11567
  this._log('connect() - connecting already in progress', { reconnect }, 'warn');
11251
11568
  return;
@@ -11262,7 +11579,7 @@ class WSConnectionFallback {
11262
11579
  }, reconnect);
11263
11580
  this._setState(ConnectionState.Connected);
11264
11581
  this.connectionID = event.connection_id;
11265
- this.client.resolveConnectionId();
11582
+ (_d = (_c = this.client).resolveConnectionId) === null || _d === void 0 ? void 0 : _d.call(_c);
11266
11583
  // @ts-expect-error
11267
11584
  this.client.dispatchEvent(event);
11268
11585
  this._poll();
@@ -11270,7 +11587,7 @@ class WSConnectionFallback {
11270
11587
  }
11271
11588
  catch (err) {
11272
11589
  this._setState(ConnectionState.Closed);
11273
- this.client.rejectConnectionId();
11590
+ (_f = (_e = this.client).rejectConnectionId) === null || _f === void 0 ? void 0 : _f.call(_e);
11274
11591
  throw err;
11275
11592
  }
11276
11593
  });
@@ -11281,10 +11598,10 @@ class WSConnectionFallback {
11281
11598
  return !!this.connectionID && this.state === ConnectionState.Connected;
11282
11599
  };
11283
11600
  this.disconnect = (timeout = 2000) => __awaiter(this, void 0, void 0, function* () {
11284
- var _c;
11601
+ var _g;
11285
11602
  removeConnectionEventListeners(this._onlineStatusChanged);
11286
11603
  this._setState(ConnectionState.Disconnected);
11287
- (_c = this.cancelToken) === null || _c === void 0 ? void 0 : _c.cancel('disconnect() is called');
11604
+ (_g = this.cancelToken) === null || _g === void 0 ? void 0 : _g.cancel('disconnect() is called');
11288
11605
  this.cancelToken = undefined;
11289
11606
  const connection_id = this.connectionID;
11290
11607
  this.connectionID = undefined;
@@ -11321,7 +11638,7 @@ class WSConnectionFallback {
11321
11638
  }
11322
11639
  }
11323
11640
 
11324
- const version = '0.1.2';
11641
+ const version = '0.1.4';
11325
11642
 
11326
11643
  const logger = getLogger(['location']);
11327
11644
  const HINT_URL = `https://hint.stream-io-video.com/`;
@@ -11498,6 +11815,10 @@ class StreamClient {
11498
11815
  this.logger('info', 'client:openConnection() - openConnection called twice, healthy connection already exists');
11499
11816
  return Promise.resolve();
11500
11817
  }
11818
+ this.connectionIdPromise = new Promise((resolve, reject) => {
11819
+ this.resolveConnectionId = resolve;
11820
+ this.rejectConnectionId = reject;
11821
+ });
11501
11822
  this.clientID = `${this.userID}--${randomId()}`;
11502
11823
  this.wsPromise = this.connect();
11503
11824
  return this.wsPromise;
@@ -11526,11 +11847,19 @@ class StreamClient {
11526
11847
  this.anonymous = false;
11527
11848
  yield this.closeConnection(timeout);
11528
11849
  this.tokenManager.reset();
11850
+ this.connectionIdPromise = undefined;
11851
+ this.rejectConnectionId = undefined;
11852
+ this.resolveConnectionId = undefined;
11529
11853
  });
11530
11854
  /**
11531
11855
  * connectAnonymousUser - Set an anonymous user and open a WebSocket connection
11532
11856
  */
11533
11857
  this.connectAnonymousUser = (user, tokenOrProvider) => __awaiter(this, void 0, void 0, function* () {
11858
+ var _g;
11859
+ this.connectionIdPromise = new Promise((resolve, reject) => {
11860
+ this.resolveConnectionId = resolve;
11861
+ this.rejectConnectionId = reject;
11862
+ });
11534
11863
  this.anonymous = true;
11535
11864
  yield this._setToken(user, tokenOrProvider, this.anonymous);
11536
11865
  if (this.resolveConnectPromise) {
@@ -11542,7 +11871,7 @@ class StreamClient {
11542
11871
  // some endpoints require a connection_id to be resolved.
11543
11872
  // as anonymous users aren't allowed to open WS connections, we just
11544
11873
  // resolve the connection_id here.
11545
- this.resolveConnectionId();
11874
+ (_g = this.resolveConnectionId) === null || _g === void 0 ? void 0 : _g.call(this);
11546
11875
  });
11547
11876
  /**
11548
11877
  * on - Listen to events on all channels and users your watching
@@ -11605,8 +11934,8 @@ class StreamClient {
11605
11934
  });
11606
11935
  };
11607
11936
  this.doAxiosRequest = (type, url, data, options = {}) => __awaiter(this, void 0, void 0, function* () {
11608
- var _g;
11609
- if (!options.publicEndpoint || this.user) {
11937
+ var _h;
11938
+ if (!options.publicEndpoint) {
11610
11939
  if (this.waitForConnectPromise) {
11611
11940
  yield this.waitForConnectPromise;
11612
11941
  }
@@ -11647,7 +11976,7 @@ class StreamClient {
11647
11976
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
11648
11977
  }
11649
11978
  catch (e /**TODO: generalize error types */) {
11650
- e.client_request_id = (_g = requestConfig.headers) === null || _g === void 0 ? void 0 : _g['x-client-request-id'];
11979
+ e.client_request_id = (_h = requestConfig.headers) === null || _h === void 0 ? void 0 : _h['x-client-request-id'];
11651
11980
  this._logApiError(type, url, e);
11652
11981
  this.consecutiveFailures += 1;
11653
11982
  if (e.response) {
@@ -11912,12 +12241,6 @@ class StreamClient {
11912
12241
  keepAliveMsecs: 3000,
11913
12242
  });
11914
12243
  }
11915
- this.connectionIdPromise = this.secret
11916
- ? undefined
11917
- : new Promise((resolve, reject) => {
11918
- this.resolveConnectionId = resolve;
11919
- this.rejectConnectionId = reject;
11920
- });
11921
12244
  this.setBaseURL(this.options.baseURL || 'https://video.stream-io-api.com/video');
11922
12245
  if (typeof process !== 'undefined' && process.env.STREAM_LOCAL_TEST_RUN) {
11923
12246
  this.setBaseURL('http://localhost:3030/video');