@signalwire/js 4.0.0-beta.3 → 4.0.0-beta.5

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/browser.mjs CHANGED
@@ -6934,7 +6934,7 @@ var require_switchMap = /* @__PURE__ */ __commonJSMin(((exports) => {
6934
6934
  var innerFrom_1$6 = require_innerFrom();
6935
6935
  var lift_1$13 = require_lift();
6936
6936
  var OperatorSubscriber_1$11 = require_OperatorSubscriber();
6937
- function switchMap$2(project, resultSelector) {
6937
+ function switchMap$3(project, resultSelector) {
6938
6938
  return lift_1$13.operate(function(source, subscriber) {
6939
6939
  var innerSubscriber = null;
6940
6940
  var index = 0;
@@ -6958,7 +6958,7 @@ var require_switchMap = /* @__PURE__ */ __commonJSMin(((exports) => {
6958
6958
  }));
6959
6959
  });
6960
6960
  }
6961
- exports.switchMap = switchMap$2;
6961
+ exports.switchMap = switchMap$3;
6962
6962
  }));
6963
6963
 
6964
6964
  //#endregion
@@ -10471,6 +10471,15 @@ const RPCConnect = (params) => {
10471
10471
  });
10472
10472
  };
10473
10473
 
10474
+ //#endregion
10475
+ //#region src/core/RPCMessages/RPCReauthenticate.ts
10476
+ const RPCReauthenticate = (authentication) => {
10477
+ return buildRPCRequest({
10478
+ method: "signalwire.reauthenticate",
10479
+ params: { authentication }
10480
+ });
10481
+ };
10482
+
10474
10483
  //#endregion
10475
10484
  //#region src/core/RPCMessages/RPCPing.ts
10476
10485
  const RPCPingResponse = (id, timestamp$1) => {
@@ -12515,7 +12524,7 @@ var CallEventsManager = class extends Destroyable {
12515
12524
  });
12516
12525
  this.updateParticipants(sessionState.members);
12517
12526
  this._self$.value?.capabilities.updateFromRaw(capabilities);
12518
- this.updateLayouts();
12527
+ if (this._self$.value?.capabilities.setLayout) this.updateLayouts();
12519
12528
  });
12520
12529
  this.subscribeTo(this.memberUpdates$, (member) => {
12521
12530
  logger$15.debug("[CallEventsManager] Handling member update event for member ID:", member);
@@ -13847,7 +13856,10 @@ function isVertoAttachMessage(value) {
13847
13856
  return value.method === "verto.attach";
13848
13857
  }
13849
13858
  function isVertoAnswerInnerParams(value) {
13850
- return isObject(value) && hasProperty(value, "jsonrpc") && value.jsonrpc === "2.0" && hasProperty(value, "method") && value.method === "verto.answer" && isObject(value.params) && hasProperty(value.params, "callID") && hasProperty(value.params, "sdp");
13859
+ return isObject(value) && hasProperty(value, "jsonrpc") && value.jsonrpc === "2.0" && hasProperty(value, "method") && value.method === "verto.answer" && isObject(value.params) && hasProperty(value.params, "callID");
13860
+ }
13861
+ function isVertoMediaInnerParams(value) {
13862
+ return isObject(value) && hasProperty(value, "jsonrpc") && value.jsonrpc === "2.0" && hasProperty(value, "method") && value.method === "verto.media" && isObject(value.params) && hasProperty(value.params, "callID") && hasProperty(value.params, "sdp");
13851
13863
  }
13852
13864
  function isVertoMediaParamsInnerParams(value) {
13853
13865
  return isObject(value) && hasProperty(value, "jsonrpc") && value.jsonrpc === "2.0" && hasProperty(value, "method") && value.method === "verto.mediaParams" && isObject(value.params) && hasProperty(value.params, "mediaParams");
@@ -13957,10 +13969,19 @@ var WebRTCVertoManager = class extends VertoManager {
13957
13969
  ].includes(connectionState)))));
13958
13970
  }
13959
13971
  initSubscriptions() {
13972
+ this.subscribeTo(this.vertoMedia$, (event) => {
13973
+ logger$10.debug("[WebRTCManager] Received Verto media event (early media SDP):", event);
13974
+ this._signalingStatus$.next("ringing");
13975
+ const { sdp, callID } = event;
13976
+ this._rtcPeerConnectionsMap.get(callID)?.updateAnswerStatus({
13977
+ status: "received",
13978
+ sdp
13979
+ });
13980
+ });
13960
13981
  this.subscribeTo(this.vertoAnswer$, (event) => {
13961
13982
  logger$10.debug("[WebRTCManager] Received Verto answer event:", event);
13962
- const { sdp } = event;
13963
- this._rtcPeerConnectionsMap.get(event.callID)?.updateAnswerStatus({
13983
+ const { sdp, callID } = event;
13984
+ this._rtcPeerConnectionsMap.get(callID)?.updateAnswerStatus({
13964
13985
  status: "received",
13965
13986
  sdp
13966
13987
  });
@@ -14001,6 +14022,9 @@ var WebRTCVertoManager = class extends VertoManager {
14001
14022
  get selfId() {
14002
14023
  return this._selfId$.value;
14003
14024
  }
14025
+ get vertoMedia$() {
14026
+ return this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoMediaInnerParams, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$));
14027
+ }
14004
14028
  get vertoAnswer$() {
14005
14029
  return this.cachedObservable("vertoAnswer$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoAnswerInnerParams, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
14006
14030
  }
@@ -14084,7 +14108,6 @@ var WebRTCVertoManager = class extends VertoManager {
14084
14108
  this._selfId$.next(memberId);
14085
14109
  rtcPeerConnController.setMemberId(memberId);
14086
14110
  if (callId) this.webRtcCallSession.addCallId(callId);
14087
- this._signalingStatus$.next("ringing");
14088
14111
  this.attachManager.attach(this.webRtcCallSession);
14089
14112
  logger$10.info("[WebRTCManager] Verto invite successful");
14090
14113
  logger$10.debug(`[WebRTCManager] nodeid: ${this._nodeId$.value}, selfId: ${this._selfId$.value}`);
@@ -14179,6 +14202,7 @@ var WebRTCVertoManager = class extends VertoManager {
14179
14202
  }
14180
14203
  setupVertoByeHandler() {
14181
14204
  this.subscribeTo(this.vertoBye$, () => {
14205
+ this._signalingStatus$.next("disconnected");
14182
14206
  this.attachManager.detach(this.webRtcCallSession);
14183
14207
  this.callSession?.destroy();
14184
14208
  });
@@ -14206,7 +14230,12 @@ var WebRTCVertoManager = class extends VertoManager {
14206
14230
  this.callSession?.destroy();
14207
14231
  } else if (!vertoByeOrAccepted) {
14208
14232
  logger$10.info("[WebRTCManager] Call was not accepted, sending verto.bye.");
14209
- await this.bye("USER_BUSY");
14233
+ try {
14234
+ await this.bye("USER_BUSY");
14235
+ } finally {
14236
+ this._signalingStatus$.next("disconnected");
14237
+ this.callSession?.destroy();
14238
+ }
14210
14239
  } else {
14211
14240
  logger$10.debug("[WebRTCManager] Call accepted, sending answer");
14212
14241
  try {
@@ -14236,8 +14265,7 @@ var WebRTCVertoManager = class extends VertoManager {
14236
14265
  userVariables: {
14237
14266
  memberCallId: this.webRtcCallSession.id,
14238
14267
  memberId,
14239
- ...this.webRtcCallSession.options.userVariables,
14240
- ...PreferencesContainer.instance.userVariables
14268
+ ...this.webRtcCallSession.userVariables
14241
14269
  },
14242
14270
  screenShare: rtcPeerConnectionController.isScreenShare,
14243
14271
  additionalDevice: rtcPeerConnectionController.isAdditionalDevice,
@@ -14436,6 +14464,20 @@ var ParticipantFactory = class {
14436
14464
  //#region src/core/entities/Call.ts
14437
14465
  var import_cjs$9 = require_cjs();
14438
14466
  const logger$9 = getLogger();
14467
+ const fromDestinationParams = (destination) => {
14468
+ if (!destination) return {};
14469
+ try {
14470
+ const url = new URL(`destination:${destination}`);
14471
+ const params = {};
14472
+ url.searchParams.forEach((value, key) => {
14473
+ params[key] = value;
14474
+ });
14475
+ return params;
14476
+ } catch (error) {
14477
+ logger$9.warn(`Failed to parse destination URI: ${destination}`, error);
14478
+ return {};
14479
+ }
14480
+ };
14439
14481
  /**
14440
14482
  * Concrete WebRTC call implementation.
14441
14483
  *
@@ -14453,8 +14495,21 @@ var WebRTCCall = class extends Destroyable {
14453
14495
  this._errors$ = this.createSubject();
14454
14496
  this._answered$ = this.createReplaySubject();
14455
14497
  this._holdState = false;
14498
+ this._userVariables$ = this.createBehaviorSubject({ ...PreferencesContainer.instance.userVariables });
14456
14499
  this.id = options.callId ?? v4_default();
14457
14500
  this.to = options.to;
14501
+ this._userVariables$.next({
14502
+ ...this._userVariables$.value,
14503
+ ...fromDestinationParams(options.to),
14504
+ ...options.userVariables
14505
+ });
14506
+ this.subscribeTo(this.webrtcMessages$, (message) => {
14507
+ const userVars = getValueFrom(message, "params.userVariables");
14508
+ if (userVars) this._userVariables$.next({
14509
+ ...this._userVariables$.value,
14510
+ ...userVars
14511
+ });
14512
+ });
14458
14513
  const managers = initialization.initializeManagers(this);
14459
14514
  this.vertoManager = managers.vertoManager;
14460
14515
  this.callEventsManager = managers.callEventsManager;
@@ -14668,6 +14723,21 @@ var WebRTCCall = class extends Destroyable {
14668
14723
  get remoteStream() {
14669
14724
  return this.vertoManager.remoteStream;
14670
14725
  }
14726
+ /** Observable of custom user variables associated with the call. */
14727
+ get userVariables$() {
14728
+ return this._userVariables$.asObservable();
14729
+ }
14730
+ /** a copy of the current custom user variables of the call. */
14731
+ get userVariables() {
14732
+ return { ...this._userVariables$.value };
14733
+ }
14734
+ /** Merge current custom user variables of the call. */
14735
+ set userVariables(variables) {
14736
+ this._userVariables$.next({
14737
+ ...this._userVariables$.value,
14738
+ ...variables
14739
+ });
14740
+ }
14671
14741
  /** @internal */
14672
14742
  createParticipant(memberId, selfId) {
14673
14743
  if (memberId === (selfId ?? this.vertoManager.selfId)) return this.participantFactory.createSelfParticipant(memberId);
@@ -14773,7 +14843,6 @@ var WebRTCCall = class extends Destroyable {
14773
14843
  try {
14774
14844
  await this.vertoManager.bye();
14775
14845
  } finally {
14776
- this._status$.next("destroyed");
14777
14846
  this.destroy();
14778
14847
  }
14779
14848
  }
@@ -14812,6 +14881,7 @@ var WebRTCCall = class extends Destroyable {
14812
14881
  }
14813
14882
  /** Destroys the call, releasing all resources and subscriptions. */
14814
14883
  destroy() {
14884
+ this._status$.next("destroyed");
14815
14885
  this.vertoManager.destroy();
14816
14886
  this.callEventsManager.destroy();
14817
14887
  this.participantsMap.clear();
@@ -14866,7 +14936,10 @@ var Fetcher = class {
14866
14936
  this.nextUrl = `${this.endpoint}?${params}`;
14867
14937
  }
14868
14938
  async next() {
14869
- if (!this.nextUrl) return [];
14939
+ if (!this.nextUrl) {
14940
+ this.hasMore = false;
14941
+ return [];
14942
+ }
14870
14943
  const response = await this.http.request({
14871
14944
  ...GET_PARAMS,
14872
14945
  url: this.nextUrl
@@ -14874,6 +14947,7 @@ var Fetcher = class {
14874
14947
  if (response.ok && !!response.body) {
14875
14948
  const result = JSON.parse(response.body);
14876
14949
  this.nextUrl = result.links.next;
14950
+ this.hasMore = !!this.nextUrl;
14877
14951
  return result.data.filter(this.filter).map(this.mapper);
14878
14952
  }
14879
14953
  logger$8.error("Failed to fetch entity");
@@ -14907,10 +14981,11 @@ var EntityCollection = class extends Destroyable {
14907
14981
  this.observablesRegistry.get(data.id)?.next(updated);
14908
14982
  this.values$.next(Array.from(this.collectionData.values()));
14909
14983
  };
14984
+ this._hasMore$ = this.createBehaviorSubject(true);
14910
14985
  this._destroy$ = new import_cjs$8.Subject();
14911
14986
  this.updateSubscription = this.update$.subscribe(this.upsertData);
14912
14987
  this.loading$.next(false);
14913
- this.hasMore$ = (0, import_cjs$8.defer)(() => (0, import_cjs$8.from)(this.init())).pipe((0, import_cjs$8.shareReplay)(1), (0, import_cjs$8.takeUntil)(this._destroy$));
14988
+ this.hasMore$ = (0, import_cjs$8.defer)(() => (0, import_cjs$8.from)(this.init())).pipe((0, import_cjs$8.switchMap)(() => this._hasMore$), (0, import_cjs$8.distinctUntilChanged)(), (0, import_cjs$8.shareReplay)(1), (0, import_cjs$8.takeUntil)(this._destroy$));
14914
14989
  }
14915
14990
  get loading() {
14916
14991
  return this.loading$.value;
@@ -14925,17 +15000,21 @@ var EntityCollection = class extends Destroyable {
14925
15000
  return Array.from(this.collectionData.values());
14926
15001
  }
14927
15002
  async init() {
14928
- if (this.fetchController.hasMore === false) return Promise.resolve(false);
15003
+ if (this.fetchController.hasMore === false) {
15004
+ this._hasMore$.next(false);
15005
+ return;
15006
+ }
14929
15007
  await this.fetchMore();
14930
- return this.fetchController.hasMore ?? true;
14931
15008
  }
14932
15009
  async fetchMore() {
14933
15010
  try {
14934
15011
  this.loading$.next(true);
14935
15012
  (await this.fetchController.next()).forEach(this.upsertData);
15013
+ this._hasMore$.next(this.fetchController.hasMore ?? false);
14936
15014
  this.loading$.next(false);
14937
15015
  } catch (error) {
14938
15016
  logger$8.error(`Failed to fetch initial collection data`, error);
15017
+ this._hasMore$.next(this.fetchController.hasMore ?? false);
14939
15018
  this.loading$.next(false);
14940
15019
  this.onError?.(new CollectionFetchError("fetchMore", error));
14941
15020
  }
@@ -15265,13 +15344,13 @@ var ClientSessionManager = class extends Destroyable {
15265
15344
  this.callCreateTimeout = 6e3;
15266
15345
  this.agent = `signalwire-typescript-sdk/1.0.0`;
15267
15346
  this.eventAcks = true;
15268
- this.authorization$ = this.createSubject();
15269
15347
  this.authorizationState$ = this.createReplaySubject(1);
15270
15348
  this.connectVersion = {
15271
15349
  major: 4,
15272
15350
  minor: 0,
15273
15351
  revision: 0
15274
15352
  };
15353
+ this._authorization$ = this.createBehaviorSubject(void 0);
15275
15354
  this._errors$ = this.createSubject();
15276
15355
  this._authenticated$ = this.createBehaviorSubject(false);
15277
15356
  this._subscriberInfo$ = this.createBehaviorSubject(null);
@@ -15302,6 +15381,12 @@ var ClientSessionManager = class extends Destroyable {
15302
15381
  get iceServers() {
15303
15382
  return this._iceServers$.value;
15304
15383
  }
15384
+ get authorization$() {
15385
+ return this._authorization$.asObservable();
15386
+ }
15387
+ get authorization() {
15388
+ return this._authorization$.value;
15389
+ }
15305
15390
  get errors$() {
15306
15391
  return this._errors$.asObservable();
15307
15392
  }
@@ -15453,6 +15538,24 @@ var ClientSessionManager = class extends Destroyable {
15453
15538
  this._errors$.next(new AuthStateHandlerError(error));
15454
15539
  }
15455
15540
  }
15541
+ async reauthenticate(token) {
15542
+ logger$6.debug("[Session] Re-authenticating session");
15543
+ try {
15544
+ const request = RPCReauthenticate({
15545
+ project: this._authorization$.value?.project_id ?? "",
15546
+ jwt_token: token
15547
+ });
15548
+ await (0, import_cjs$5.lastValueFrom)((0, import_cjs$5.from)(this.transport.execute(request)).pipe(throwOnRPCError(), (0, import_cjs$5.take)(1), (0, import_cjs$5.catchError)((err) => {
15549
+ logger$6.error("[Session] Re-authentication RPC failed:", err);
15550
+ throw err;
15551
+ })));
15552
+ logger$6.debug("[Session] Re-authentication successful, updating stored auth state");
15553
+ } catch (error) {
15554
+ logger$6.error("[Session] Re-authentication failed:", error);
15555
+ this._errors$.next(new AuthStateHandlerError(error));
15556
+ throw error;
15557
+ }
15558
+ }
15456
15559
  async authenticate() {
15457
15560
  logger$6.debug("[Session] Starting authentication process");
15458
15561
  const params = {
@@ -15488,7 +15591,7 @@ var ClientSessionManager = class extends Destroyable {
15488
15591
  hasIceServers: !!response.ice_servers
15489
15592
  });
15490
15593
  if (response.protocol) await this.transport.setProtocol(response.protocol);
15491
- this.authorization$.next(response.authorization);
15594
+ this._authorization$.next(response.authorization);
15492
15595
  this._iceServers$.next(response.ice_servers ?? []);
15493
15596
  this._authenticated$.next(true);
15494
15597
  logger$6.debug("[Session] Authentication completed successfully");
@@ -15507,7 +15610,8 @@ var ClientSessionManager = class extends Destroyable {
15507
15610
  to: invite.callee_id_number,
15508
15611
  fromName: invite.caller_id_name,
15509
15612
  from: invite.caller_id_number,
15510
- displayDirection: invite.display_direction
15613
+ displayDirection: invite.display_direction,
15614
+ userVariables: invite.userVariables
15511
15615
  });
15512
15616
  await (0, import_cjs$5.firstValueFrom)(callSession.status$);
15513
15617
  this._calls$.next({
@@ -15539,12 +15643,14 @@ var ClientSessionManager = class extends Destroyable {
15539
15643
  try {
15540
15644
  const addressURI = getAddressSearchURI(options);
15541
15645
  let address;
15542
- if (!addressURI.startsWith("+")) {
15646
+ try {
15543
15647
  if (!this._directory) throw new DependencyError("Directory not initialized");
15544
15648
  const addressId = await this._directory.findAddressIdByURI(addressURI);
15545
15649
  if (!addressId) throw new DependencyError(`Address name: ${addressURI} not found`);
15546
15650
  address = this._directory.get(addressId);
15547
15651
  if (!address) throw new DependencyError(`Address ID: ${addressId} not found`);
15652
+ } catch (error) {
15653
+ logger$6.warn(`[Session] Directory lookup failed for ${addressURI}, proceeding with raw URI`);
15548
15654
  }
15549
15655
  const callSession = this.callFactory.createCall(address, { ...options });
15550
15656
  callSession.status$.pipe((0, import_cjs$5.filter)((status) => status === "destroyed"), (0, import_cjs$5.take)(1)).subscribe(() => {
@@ -16222,6 +16328,13 @@ var SignalWire = class extends Destroyable {
16222
16328
  }, refreshInterval);
16223
16329
  }
16224
16330
  this._deps.credential = _credentials;
16331
+ if (this.isConnected && this._clientSession.authenticated && _credentials.token) try {
16332
+ await this._clientSession.reauthenticate(_credentials.token);
16333
+ logger$1.info("[SignalWire] Session refreshed with new credentials.");
16334
+ } catch (error) {
16335
+ logger$1.error("[SignalWire] Failed to refresh session with new credentials:", error);
16336
+ this._errors$.next(error instanceof Error ? error : new Error(String(error), { cause: error }));
16337
+ }
16225
16338
  }
16226
16339
  async init() {
16227
16340
  this._subscriber$.next(new Subscriber(this._deps.http));