@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.
@@ -6938,7 +6938,7 @@ var require_switchMap = /* @__PURE__ */ __commonJSMin(((exports) => {
6938
6938
  var innerFrom_1$6 = require_innerFrom();
6939
6939
  var lift_1$13 = require_lift();
6940
6940
  var OperatorSubscriber_1$11 = require_OperatorSubscriber();
6941
- function switchMap$2(project, resultSelector) {
6941
+ function switchMap$3(project, resultSelector) {
6942
6942
  return lift_1$13.operate(function(source, subscriber) {
6943
6943
  var innerSubscriber = null;
6944
6944
  var index = 0;
@@ -6962,7 +6962,7 @@ var require_switchMap = /* @__PURE__ */ __commonJSMin(((exports) => {
6962
6962
  }));
6963
6963
  });
6964
6964
  }
6965
- exports.switchMap = switchMap$2;
6965
+ exports.switchMap = switchMap$3;
6966
6966
  }));
6967
6967
 
6968
6968
  //#endregion
@@ -10475,6 +10475,15 @@ const RPCConnect = (params) => {
10475
10475
  });
10476
10476
  };
10477
10477
 
10478
+ //#endregion
10479
+ //#region src/core/RPCMessages/RPCReauthenticate.ts
10480
+ const RPCReauthenticate = (authentication) => {
10481
+ return buildRPCRequest({
10482
+ method: "signalwire.reauthenticate",
10483
+ params: { authentication }
10484
+ });
10485
+ };
10486
+
10478
10487
  //#endregion
10479
10488
  //#region src/core/RPCMessages/RPCPing.ts
10480
10489
  const RPCPingResponse = (id, timestamp$1) => {
@@ -12519,7 +12528,7 @@ var CallEventsManager = class extends Destroyable {
12519
12528
  });
12520
12529
  this.updateParticipants(sessionState.members);
12521
12530
  this._self$.value?.capabilities.updateFromRaw(capabilities);
12522
- this.updateLayouts();
12531
+ if (this._self$.value?.capabilities.setLayout) this.updateLayouts();
12523
12532
  });
12524
12533
  this.subscribeTo(this.memberUpdates$, (member) => {
12525
12534
  logger$15.debug("[CallEventsManager] Handling member update event for member ID:", member);
@@ -13851,7 +13860,10 @@ function isVertoAttachMessage(value) {
13851
13860
  return value.method === "verto.attach";
13852
13861
  }
13853
13862
  function isVertoAnswerInnerParams(value) {
13854
- 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");
13863
+ return isObject(value) && hasProperty(value, "jsonrpc") && value.jsonrpc === "2.0" && hasProperty(value, "method") && value.method === "verto.answer" && isObject(value.params) && hasProperty(value.params, "callID");
13864
+ }
13865
+ function isVertoMediaInnerParams(value) {
13866
+ 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");
13855
13867
  }
13856
13868
  function isVertoMediaParamsInnerParams(value) {
13857
13869
  return isObject(value) && hasProperty(value, "jsonrpc") && value.jsonrpc === "2.0" && hasProperty(value, "method") && value.method === "verto.mediaParams" && isObject(value.params) && hasProperty(value.params, "mediaParams");
@@ -13961,10 +13973,19 @@ var WebRTCVertoManager = class extends VertoManager {
13961
13973
  ].includes(connectionState)))));
13962
13974
  }
13963
13975
  initSubscriptions() {
13976
+ this.subscribeTo(this.vertoMedia$, (event) => {
13977
+ logger$10.debug("[WebRTCManager] Received Verto media event (early media SDP):", event);
13978
+ this._signalingStatus$.next("ringing");
13979
+ const { sdp, callID } = event;
13980
+ this._rtcPeerConnectionsMap.get(callID)?.updateAnswerStatus({
13981
+ status: "received",
13982
+ sdp
13983
+ });
13984
+ });
13964
13985
  this.subscribeTo(this.vertoAnswer$, (event) => {
13965
13986
  logger$10.debug("[WebRTCManager] Received Verto answer event:", event);
13966
- const { sdp } = event;
13967
- this._rtcPeerConnectionsMap.get(event.callID)?.updateAnswerStatus({
13987
+ const { sdp, callID } = event;
13988
+ this._rtcPeerConnectionsMap.get(callID)?.updateAnswerStatus({
13968
13989
  status: "received",
13969
13990
  sdp
13970
13991
  });
@@ -14005,6 +14026,9 @@ var WebRTCVertoManager = class extends VertoManager {
14005
14026
  get selfId() {
14006
14027
  return this._selfId$.value;
14007
14028
  }
14029
+ get vertoMedia$() {
14030
+ return this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoMediaInnerParams, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$));
14031
+ }
14008
14032
  get vertoAnswer$() {
14009
14033
  return this.cachedObservable("vertoAnswer$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoAnswerInnerParams, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
14010
14034
  }
@@ -14088,7 +14112,6 @@ var WebRTCVertoManager = class extends VertoManager {
14088
14112
  this._selfId$.next(memberId);
14089
14113
  rtcPeerConnController.setMemberId(memberId);
14090
14114
  if (callId) this.webRtcCallSession.addCallId(callId);
14091
- this._signalingStatus$.next("ringing");
14092
14115
  this.attachManager.attach(this.webRtcCallSession);
14093
14116
  logger$10.info("[WebRTCManager] Verto invite successful");
14094
14117
  logger$10.debug(`[WebRTCManager] nodeid: ${this._nodeId$.value}, selfId: ${this._selfId$.value}`);
@@ -14183,6 +14206,7 @@ var WebRTCVertoManager = class extends VertoManager {
14183
14206
  }
14184
14207
  setupVertoByeHandler() {
14185
14208
  this.subscribeTo(this.vertoBye$, () => {
14209
+ this._signalingStatus$.next("disconnected");
14186
14210
  this.attachManager.detach(this.webRtcCallSession);
14187
14211
  this.callSession?.destroy();
14188
14212
  });
@@ -14210,7 +14234,12 @@ var WebRTCVertoManager = class extends VertoManager {
14210
14234
  this.callSession?.destroy();
14211
14235
  } else if (!vertoByeOrAccepted) {
14212
14236
  logger$10.info("[WebRTCManager] Call was not accepted, sending verto.bye.");
14213
- await this.bye("USER_BUSY");
14237
+ try {
14238
+ await this.bye("USER_BUSY");
14239
+ } finally {
14240
+ this._signalingStatus$.next("disconnected");
14241
+ this.callSession?.destroy();
14242
+ }
14214
14243
  } else {
14215
14244
  logger$10.debug("[WebRTCManager] Call accepted, sending answer");
14216
14245
  try {
@@ -14240,8 +14269,7 @@ var WebRTCVertoManager = class extends VertoManager {
14240
14269
  userVariables: {
14241
14270
  memberCallId: this.webRtcCallSession.id,
14242
14271
  memberId,
14243
- ...this.webRtcCallSession.options.userVariables,
14244
- ...PreferencesContainer.instance.userVariables
14272
+ ...this.webRtcCallSession.userVariables
14245
14273
  },
14246
14274
  screenShare: rtcPeerConnectionController.isScreenShare,
14247
14275
  additionalDevice: rtcPeerConnectionController.isAdditionalDevice,
@@ -14440,6 +14468,20 @@ var ParticipantFactory = class {
14440
14468
  //#region src/core/entities/Call.ts
14441
14469
  var import_cjs$9 = require_cjs();
14442
14470
  const logger$9 = getLogger();
14471
+ const fromDestinationParams = (destination) => {
14472
+ if (!destination) return {};
14473
+ try {
14474
+ const url = new URL(`destination:${destination}`);
14475
+ const params = {};
14476
+ url.searchParams.forEach((value, key) => {
14477
+ params[key] = value;
14478
+ });
14479
+ return params;
14480
+ } catch (error) {
14481
+ logger$9.warn(`Failed to parse destination URI: ${destination}`, error);
14482
+ return {};
14483
+ }
14484
+ };
14443
14485
  /**
14444
14486
  * Concrete WebRTC call implementation.
14445
14487
  *
@@ -14457,8 +14499,21 @@ var WebRTCCall = class extends Destroyable {
14457
14499
  this._errors$ = this.createSubject();
14458
14500
  this._answered$ = this.createReplaySubject();
14459
14501
  this._holdState = false;
14502
+ this._userVariables$ = this.createBehaviorSubject({ ...PreferencesContainer.instance.userVariables });
14460
14503
  this.id = options.callId ?? v4_default();
14461
14504
  this.to = options.to;
14505
+ this._userVariables$.next({
14506
+ ...this._userVariables$.value,
14507
+ ...fromDestinationParams(options.to),
14508
+ ...options.userVariables
14509
+ });
14510
+ this.subscribeTo(this.webrtcMessages$, (message) => {
14511
+ const userVars = getValueFrom(message, "params.userVariables");
14512
+ if (userVars) this._userVariables$.next({
14513
+ ...this._userVariables$.value,
14514
+ ...userVars
14515
+ });
14516
+ });
14462
14517
  const managers = initialization.initializeManagers(this);
14463
14518
  this.vertoManager = managers.vertoManager;
14464
14519
  this.callEventsManager = managers.callEventsManager;
@@ -14672,6 +14727,21 @@ var WebRTCCall = class extends Destroyable {
14672
14727
  get remoteStream() {
14673
14728
  return this.vertoManager.remoteStream;
14674
14729
  }
14730
+ /** Observable of custom user variables associated with the call. */
14731
+ get userVariables$() {
14732
+ return this._userVariables$.asObservable();
14733
+ }
14734
+ /** a copy of the current custom user variables of the call. */
14735
+ get userVariables() {
14736
+ return { ...this._userVariables$.value };
14737
+ }
14738
+ /** Merge current custom user variables of the call. */
14739
+ set userVariables(variables) {
14740
+ this._userVariables$.next({
14741
+ ...this._userVariables$.value,
14742
+ ...variables
14743
+ });
14744
+ }
14675
14745
  /** @internal */
14676
14746
  createParticipant(memberId, selfId) {
14677
14747
  if (memberId === (selfId ?? this.vertoManager.selfId)) return this.participantFactory.createSelfParticipant(memberId);
@@ -14777,7 +14847,6 @@ var WebRTCCall = class extends Destroyable {
14777
14847
  try {
14778
14848
  await this.vertoManager.bye();
14779
14849
  } finally {
14780
- this._status$.next("destroyed");
14781
14850
  this.destroy();
14782
14851
  }
14783
14852
  }
@@ -14816,6 +14885,7 @@ var WebRTCCall = class extends Destroyable {
14816
14885
  }
14817
14886
  /** Destroys the call, releasing all resources and subscriptions. */
14818
14887
  destroy() {
14888
+ this._status$.next("destroyed");
14819
14889
  this.vertoManager.destroy();
14820
14890
  this.callEventsManager.destroy();
14821
14891
  this.participantsMap.clear();
@@ -14870,7 +14940,10 @@ var Fetcher = class {
14870
14940
  this.nextUrl = `${this.endpoint}?${params}`;
14871
14941
  }
14872
14942
  async next() {
14873
- if (!this.nextUrl) return [];
14943
+ if (!this.nextUrl) {
14944
+ this.hasMore = false;
14945
+ return [];
14946
+ }
14874
14947
  const response = await this.http.request({
14875
14948
  ...GET_PARAMS,
14876
14949
  url: this.nextUrl
@@ -14878,6 +14951,7 @@ var Fetcher = class {
14878
14951
  if (response.ok && !!response.body) {
14879
14952
  const result = JSON.parse(response.body);
14880
14953
  this.nextUrl = result.links.next;
14954
+ this.hasMore = !!this.nextUrl;
14881
14955
  return result.data.filter(this.filter).map(this.mapper);
14882
14956
  }
14883
14957
  logger$8.error("Failed to fetch entity");
@@ -14911,10 +14985,11 @@ var EntityCollection = class extends Destroyable {
14911
14985
  this.observablesRegistry.get(data.id)?.next(updated);
14912
14986
  this.values$.next(Array.from(this.collectionData.values()));
14913
14987
  };
14988
+ this._hasMore$ = this.createBehaviorSubject(true);
14914
14989
  this._destroy$ = new import_cjs$8.Subject();
14915
14990
  this.updateSubscription = this.update$.subscribe(this.upsertData);
14916
14991
  this.loading$.next(false);
14917
- 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$));
14992
+ 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$));
14918
14993
  }
14919
14994
  get loading() {
14920
14995
  return this.loading$.value;
@@ -14929,17 +15004,21 @@ var EntityCollection = class extends Destroyable {
14929
15004
  return Array.from(this.collectionData.values());
14930
15005
  }
14931
15006
  async init() {
14932
- if (this.fetchController.hasMore === false) return Promise.resolve(false);
15007
+ if (this.fetchController.hasMore === false) {
15008
+ this._hasMore$.next(false);
15009
+ return;
15010
+ }
14933
15011
  await this.fetchMore();
14934
- return this.fetchController.hasMore ?? true;
14935
15012
  }
14936
15013
  async fetchMore() {
14937
15014
  try {
14938
15015
  this.loading$.next(true);
14939
15016
  (await this.fetchController.next()).forEach(this.upsertData);
15017
+ this._hasMore$.next(this.fetchController.hasMore ?? false);
14940
15018
  this.loading$.next(false);
14941
15019
  } catch (error) {
14942
15020
  logger$8.error(`Failed to fetch initial collection data`, error);
15021
+ this._hasMore$.next(this.fetchController.hasMore ?? false);
14943
15022
  this.loading$.next(false);
14944
15023
  this.onError?.(new CollectionFetchError("fetchMore", error));
14945
15024
  }
@@ -15269,13 +15348,13 @@ var ClientSessionManager = class extends Destroyable {
15269
15348
  this.callCreateTimeout = 6e3;
15270
15349
  this.agent = `signalwire-typescript-sdk/1.0.0`;
15271
15350
  this.eventAcks = true;
15272
- this.authorization$ = this.createSubject();
15273
15351
  this.authorizationState$ = this.createReplaySubject(1);
15274
15352
  this.connectVersion = {
15275
15353
  major: 4,
15276
15354
  minor: 0,
15277
15355
  revision: 0
15278
15356
  };
15357
+ this._authorization$ = this.createBehaviorSubject(void 0);
15279
15358
  this._errors$ = this.createSubject();
15280
15359
  this._authenticated$ = this.createBehaviorSubject(false);
15281
15360
  this._subscriberInfo$ = this.createBehaviorSubject(null);
@@ -15306,6 +15385,12 @@ var ClientSessionManager = class extends Destroyable {
15306
15385
  get iceServers() {
15307
15386
  return this._iceServers$.value;
15308
15387
  }
15388
+ get authorization$() {
15389
+ return this._authorization$.asObservable();
15390
+ }
15391
+ get authorization() {
15392
+ return this._authorization$.value;
15393
+ }
15309
15394
  get errors$() {
15310
15395
  return this._errors$.asObservable();
15311
15396
  }
@@ -15457,6 +15542,24 @@ var ClientSessionManager = class extends Destroyable {
15457
15542
  this._errors$.next(new AuthStateHandlerError(error));
15458
15543
  }
15459
15544
  }
15545
+ async reauthenticate(token) {
15546
+ logger$6.debug("[Session] Re-authenticating session");
15547
+ try {
15548
+ const request = RPCReauthenticate({
15549
+ project: this._authorization$.value?.project_id ?? "",
15550
+ jwt_token: token
15551
+ });
15552
+ 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) => {
15553
+ logger$6.error("[Session] Re-authentication RPC failed:", err);
15554
+ throw err;
15555
+ })));
15556
+ logger$6.debug("[Session] Re-authentication successful, updating stored auth state");
15557
+ } catch (error) {
15558
+ logger$6.error("[Session] Re-authentication failed:", error);
15559
+ this._errors$.next(new AuthStateHandlerError(error));
15560
+ throw error;
15561
+ }
15562
+ }
15460
15563
  async authenticate() {
15461
15564
  logger$6.debug("[Session] Starting authentication process");
15462
15565
  const params = {
@@ -15492,7 +15595,7 @@ var ClientSessionManager = class extends Destroyable {
15492
15595
  hasIceServers: !!response.ice_servers
15493
15596
  });
15494
15597
  if (response.protocol) await this.transport.setProtocol(response.protocol);
15495
- this.authorization$.next(response.authorization);
15598
+ this._authorization$.next(response.authorization);
15496
15599
  this._iceServers$.next(response.ice_servers ?? []);
15497
15600
  this._authenticated$.next(true);
15498
15601
  logger$6.debug("[Session] Authentication completed successfully");
@@ -15511,7 +15614,8 @@ var ClientSessionManager = class extends Destroyable {
15511
15614
  to: invite.callee_id_number,
15512
15615
  fromName: invite.caller_id_name,
15513
15616
  from: invite.caller_id_number,
15514
- displayDirection: invite.display_direction
15617
+ displayDirection: invite.display_direction,
15618
+ userVariables: invite.userVariables
15515
15619
  });
15516
15620
  await (0, import_cjs$5.firstValueFrom)(callSession.status$);
15517
15621
  this._calls$.next({
@@ -15543,12 +15647,14 @@ var ClientSessionManager = class extends Destroyable {
15543
15647
  try {
15544
15648
  const addressURI = getAddressSearchURI(options);
15545
15649
  let address;
15546
- if (!addressURI.startsWith("+")) {
15650
+ try {
15547
15651
  if (!this._directory) throw new DependencyError("Directory not initialized");
15548
15652
  const addressId = await this._directory.findAddressIdByURI(addressURI);
15549
15653
  if (!addressId) throw new DependencyError(`Address name: ${addressURI} not found`);
15550
15654
  address = this._directory.get(addressId);
15551
15655
  if (!address) throw new DependencyError(`Address ID: ${addressId} not found`);
15656
+ } catch (error) {
15657
+ logger$6.warn(`[Session] Directory lookup failed for ${addressURI}, proceeding with raw URI`);
15552
15658
  }
15553
15659
  const callSession = this.callFactory.createCall(address, { ...options });
15554
15660
  callSession.status$.pipe((0, import_cjs$5.filter)((status) => status === "destroyed"), (0, import_cjs$5.take)(1)).subscribe(() => {
@@ -16226,6 +16332,13 @@ var SignalWire = class extends Destroyable {
16226
16332
  }, refreshInterval);
16227
16333
  }
16228
16334
  this._deps.credential = _credentials;
16335
+ if (this.isConnected && this._clientSession.authenticated && _credentials.token) try {
16336
+ await this._clientSession.reauthenticate(_credentials.token);
16337
+ logger$1.info("[SignalWire] Session refreshed with new credentials.");
16338
+ } catch (error) {
16339
+ logger$1.error("[SignalWire] Failed to refresh session with new credentials:", error);
16340
+ this._errors$.next(error instanceof Error ? error : new Error(String(error), { cause: error }));
16341
+ }
16229
16342
  }
16230
16343
  async init() {
16231
16344
  this._subscriber$.next(new Subscriber(this._deps.http));