@inappstory/react-sdk 1.15.0 → 1.15.2

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.
@@ -2617,25 +2617,45 @@ class ApiRequestError extends Error {
2617
2617
  writable: true,
2618
2618
  value: void 0
2619
2619
  });
2620
+ Object.defineProperty(this, "requestUrl", {
2621
+ enumerable: true,
2622
+ configurable: true,
2623
+ writable: true,
2624
+ value: void 0
2625
+ });
2620
2626
  this.name = "IasNetworkError";
2621
2627
  this.networkStatus = networkStatus;
2622
2628
  this.networkMessage = networkMessage;
2623
2629
  this.response = response !== null && response !== void 0 ? response : null;
2624
- /* console.error({ name: this.name, networkStatus, networkMessage, response }); */
2625
2630
  }
2626
2631
  static createByRequestError(response) {
2627
2632
  return new ApiRequestError(null, JSON.stringify(response.data), response);
2628
2633
  }
2629
2634
  static createByFetchError(error) {
2635
+ const requestUrl = error.requestUrl ? decodeURIComponent(error.requestUrl) : "";
2630
2636
  const isOnline = window.navigator && window.navigator.onLine;
2631
- if (isOnline)
2632
- return new ApiRequestError(null, error.name === "AbortError"
2633
- ? "The operation was aborted by the AbortController signal. Make sure you don't destroy the InAppStoryManager while it's running."
2634
- : error.message);
2635
- return new ApiRequestError(null, "net::ERR_INTERNET_DISCONNECTED");
2637
+ let networkMessage = error.message;
2638
+ if (error.name === "AbortError") {
2639
+ if (error.abortedBySdkConfigUpdate) {
2640
+ networkMessage = `The request with URL <${requestUrl}> was interrupted due to an SDK config update (changed userId, lang or apiKey).`;
2641
+ }
2642
+ else {
2643
+ networkMessage = `The request with URL <${requestUrl}> was aborted. Make sure you don't destroy the <InAppStoryManager> while it's running.`;
2644
+ }
2645
+ }
2646
+ if (!isOnline) {
2647
+ networkMessage = "net::ERR_INTERNET_DISCONNECTED";
2648
+ }
2649
+ const apiError = new ApiRequestError(null, networkMessage);
2650
+ apiError.requestUrl = error.requestUrl;
2651
+ return apiError;
2636
2652
  }
2637
2653
  }
2638
2654
 
2655
+ ;// ../core/src/helpers/awaitMacrotask.ts
2656
+ /** Schedules a macrotask so pending microtasks can run before continuing. */
2657
+ const awaitMacrotask = () => new Promise(resolve => setTimeout(resolve));
2658
+
2639
2659
  ;// ../core/src/helpers/classificators/isNumeric.ts
2640
2660
  function isNumeric(str) {
2641
2661
  if (typeof str != "string")
@@ -3522,6 +3542,7 @@ function safeJson(input) {
3522
3542
 
3523
3543
 
3524
3544
 
3545
+
3525
3546
  ;// ../core/src/api/deviceDescriptor.ts
3526
3547
 
3527
3548
 
@@ -3593,7 +3614,7 @@ class InterceptorManager {
3593
3614
  ;// ../core/src/api/exceptions/apiAbortRequestError.ts
3594
3615
  class IasAbortRequestError extends Error {
3595
3616
  constructor(url) {
3596
- super(`The request with URL <${url}> was aborted. Make sure you don't destroy the InAppStoryManager while it's running.`);
3617
+ super(`The request with URL <${url}> was aborted. Make sure you don't destroy the <InAppStoryManager> while it's running.`);
3597
3618
  this.name = "IasAbortRequestError";
3598
3619
  }
3599
3620
  }
@@ -10335,7 +10356,7 @@ class GameClientConfig {
10335
10356
  value: void 0
10336
10357
  });
10337
10358
  const storyManagerConfig = this.storyManager.config;
10338
- const sdkVersion = "1.15.0";
10359
+ const sdkVersion = "1.15.2";
10339
10360
  const placeholders = this.storyManager.rootStore.placeholderStore.placeholders;
10340
10361
  const session = this.storyManager.rootStore.sessionStore.session;
10341
10362
  this.sessionId = session.id;
@@ -15229,6 +15250,9 @@ let StoryManagerConfig = (() => {
15229
15250
  /** Fast user switching breaks feed loading (may close session while feed is loading). Added noConcurrent */
15230
15251
  async reloadSdk() {
15231
15252
  try {
15253
+ await api.abortBySdkConfigUpdate();
15254
+ // Let microtasks from aborted request handlers run (e.g. isLoading → false) before reloading lists.
15255
+ await awaitMacrotask();
15232
15256
  this.storyManager.emit("requestSDKReload");
15233
15257
  this.storyManager.rootStore.sessionStore.close();
15234
15258
  this.storyManager.closeAllReaders();
@@ -15400,6 +15424,77 @@ class StoryManagerConfigValidator {
15400
15424
 
15401
15425
 
15402
15426
 
15427
+ ;// ../core/src/api/apiRequest.ts
15428
+ class ApiRequest {
15429
+ constructor(externalSignal) {
15430
+ Object.defineProperty(this, "_abortController", {
15431
+ enumerable: true,
15432
+ configurable: true,
15433
+ writable: true,
15434
+ value: new AbortController()
15435
+ });
15436
+ Object.defineProperty(this, "_inFlight", {
15437
+ enumerable: true,
15438
+ configurable: true,
15439
+ writable: true,
15440
+ value: true
15441
+ });
15442
+ Object.defineProperty(this, "_abortedBySdkConfigUpdate", {
15443
+ enumerable: true,
15444
+ configurable: true,
15445
+ writable: true,
15446
+ value: false
15447
+ });
15448
+ Object.defineProperty(this, "_resolve", {
15449
+ enumerable: true,
15450
+ configurable: true,
15451
+ writable: true,
15452
+ value: void 0
15453
+ });
15454
+ Object.defineProperty(this, "promise", {
15455
+ enumerable: true,
15456
+ configurable: true,
15457
+ writable: true,
15458
+ value: void 0
15459
+ });
15460
+ this.promise = new Promise(resolve => {
15461
+ this._resolve = resolve;
15462
+ });
15463
+ this.bindExternalSignal(externalSignal);
15464
+ }
15465
+ get signal() {
15466
+ return this._abortController.signal;
15467
+ }
15468
+ get inFlight() {
15469
+ return this._inFlight;
15470
+ }
15471
+ get abortedBySdkConfigUpdate() {
15472
+ return this._abortedBySdkConfigUpdate;
15473
+ }
15474
+ abort() {
15475
+ this._abortController.abort();
15476
+ }
15477
+ abortBySdkConfigUpdate() {
15478
+ this._abortedBySdkConfigUpdate = true;
15479
+ this._abortController.abort();
15480
+ }
15481
+ complete() {
15482
+ if (!this._inFlight)
15483
+ return;
15484
+ this._inFlight = false;
15485
+ this._resolve();
15486
+ }
15487
+ bindExternalSignal(signal) {
15488
+ if (!signal)
15489
+ return;
15490
+ if (signal.aborted) {
15491
+ this.abort();
15492
+ return;
15493
+ }
15494
+ signal.addEventListener("abort", () => this.abort(), { once: true });
15495
+ }
15496
+ }
15497
+
15403
15498
  ;// ../core/src/api/api.ts
15404
15499
 
15405
15500
 
@@ -15409,6 +15504,7 @@ class StoryManagerConfigValidator {
15409
15504
 
15410
15505
 
15411
15506
 
15507
+
15412
15508
  class API {
15413
15509
  constructor(config) {
15414
15510
  var _a;
@@ -15424,6 +15520,12 @@ class API {
15424
15520
  writable: true,
15425
15521
  value: {}
15426
15522
  });
15523
+ Object.defineProperty(this, "_inFlightRequests", {
15524
+ enumerable: true,
15525
+ configurable: true,
15526
+ writable: true,
15527
+ value: new Set()
15528
+ });
15427
15529
  Object.defineProperty(this, "interceptors", {
15428
15530
  enumerable: true,
15429
15531
  configurable: true,
@@ -15444,16 +15546,36 @@ class API {
15444
15546
  set baseHeaders(headers) {
15445
15547
  this._baseHeaders = headers;
15446
15548
  }
15549
+ async abortBySdkConfigUpdate() {
15550
+ const inFlightRequests = Array.from(this._inFlightRequests);
15551
+ for (const apiRequest of inFlightRequests) {
15552
+ apiRequest.abortBySdkConfigUpdate();
15553
+ }
15554
+ await Promise.allSettled(inFlightRequests.map(apiRequest => apiRequest.promise));
15555
+ }
15447
15556
  async request(config) {
15557
+ const apiRequest = new ApiRequest(config.signal);
15558
+ this.registerInFlight(apiRequest);
15559
+ config.signal = apiRequest.signal;
15448
15560
  try {
15449
15561
  const processedConfig = await this.interceptors.request.run(config);
15450
- const response = await this.dispatchRequest(processedConfig);
15451
- return await this.interceptors.response.run(response);
15562
+ const requestUrl = this.buildURL(processedConfig.url, processedConfig.params).toString();
15563
+ try {
15564
+ const response = await this.dispatchRequest(processedConfig);
15565
+ return await this.interceptors.response.run(response);
15566
+ }
15567
+ catch (error) {
15568
+ if (error instanceof ApiRequestError)
15569
+ throw error;
15570
+ const fetchError = error;
15571
+ fetchError.requestUrl = requestUrl;
15572
+ fetchError.abortedBySdkConfigUpdate = apiRequest.abortedBySdkConfigUpdate;
15573
+ throw ApiRequestError.createByFetchError(fetchError);
15574
+ }
15452
15575
  }
15453
- catch (error) {
15454
- if (error instanceof ApiRequestError)
15455
- throw error;
15456
- throw ApiRequestError.createByFetchError(error);
15576
+ finally {
15577
+ apiRequest.complete();
15578
+ this.unregisterInFlight(apiRequest);
15457
15579
  }
15458
15580
  }
15459
15581
  get(url, config = {}) {
@@ -15578,6 +15700,12 @@ class API {
15578
15700
  }
15579
15701
  return result;
15580
15702
  }
15703
+ registerInFlight(apiRequest) {
15704
+ this._inFlightRequests.add(apiRequest);
15705
+ }
15706
+ unregisterInFlight(apiRequest) {
15707
+ this._inFlightRequests.delete(apiRequest);
15708
+ }
15581
15709
  }
15582
15710
  const APIInstance = new API();
15583
15711
  APIInstance.interceptors.request.use(config => {
@@ -15690,7 +15818,7 @@ let IamApi = (() => {
15690
15818
  value: (iamApi_runInitializers(this, _instanceExtraInitializers), storyManager)
15691
15819
  });
15692
15820
  }
15693
- async fetchAll({ tags, options }) {
15821
+ async fetchAll({ tags, options, signal }) {
15694
15822
  const response = await api.post("inappmessaging", {
15695
15823
  tags: tags.join(","),
15696
15824
  options
@@ -15698,25 +15826,28 @@ let IamApi = (() => {
15698
15826
  params: {
15699
15827
  fields: messageFieldsWithPrefix,
15700
15828
  expand: "messages.slides"
15701
- }
15829
+ },
15830
+ signal
15702
15831
  });
15703
15832
  return response.data.messages;
15704
15833
  }
15705
- async fetchContext({ needFetchStyles, messageIds }) {
15834
+ async fetchContext({ needFetchStyles, messageIds, signal }) {
15706
15835
  const response = await api.get("inappmessaging/message-context", {
15707
15836
  params: {
15708
15837
  fields: "widgetsData" + (needFetchStyles ? ",style" : ""),
15709
15838
  id: messageIds.join()
15710
- }
15839
+ },
15840
+ signal
15711
15841
  });
15712
15842
  return response.data;
15713
15843
  }
15714
- async fetchById(messageId) {
15844
+ async fetchById(messageId, signal) {
15715
15845
  const response = await api.get(`inappmessaging/message/${messageId}`, {
15716
15846
  params: {
15717
15847
  expand: "slides",
15718
- fields: messageFields,
15719
- }
15848
+ fields: messageFields
15849
+ },
15850
+ signal
15720
15851
  });
15721
15852
  const messageDto = response.data;
15722
15853
  if (!messageDto)
@@ -15766,7 +15897,7 @@ let IamApi = (() => {
15766
15897
  console.error(error);
15767
15898
  }
15768
15899
  }
15769
- async checkMesageLimit(messageId) {
15900
+ async checkMesageLimit(messageId, signal) {
15770
15901
  if (this.storyManager.isStatisticsDisabled) {
15771
15902
  return {
15772
15903
  canOpen: true
@@ -15774,7 +15905,7 @@ let IamApi = (() => {
15774
15905
  }
15775
15906
  const response = await api.post("inappmessaging/message-limit", {
15776
15907
  id: [messageId]
15777
- });
15908
+ }, { signal });
15778
15909
  const messageLimitDto = response.data.find(messageLimitDto => messageLimitDto.messageId.toString() === messageId.toString());
15779
15910
  if (!messageLimitDto)
15780
15911
  throw new IamNotFoundLimitError(messageId);
@@ -16943,29 +17074,29 @@ class IamDisplayService {
16943
17074
  value: iamApi
16944
17075
  });
16945
17076
  }
16946
- async getMessageById(messageId, options) {
17077
+ async getMessageById(messageId, options = {}) {
16947
17078
  new IamValidator(this.storyManager, this.iamStore)
16948
17079
  .checkOtherReadersAreClosed()
16949
17080
  .checkShowOnlyIfLoaded(options.showOnlyIfLoaded)
16950
17081
  .validate();
16951
- const message = await this.iamStore.findById(messageId);
17082
+ const message = await this.iamStore.findById(messageId, { signal: options.signal });
16952
17083
  if (message.hasLimit)
16953
- await this.checkMesageLimit(messageId);
17084
+ await this.checkMesageLimit(messageId, options.signal);
16954
17085
  return message;
16955
17086
  }
16956
- async getMessageByEvent(eventName, options) {
17087
+ async getMessageByEvent(eventName, options = {}) {
16957
17088
  const validator = new IamValidator(this.storyManager, this.iamStore);
16958
17089
  validator.checkOtherReadersAreClosed().checkShowOnlyIfLoaded(options.showOnlyIfLoaded).validate();
16959
- await this.iamStore.preload({ tags: options.tags });
17090
+ await this.iamStore.preload({ tags: options.tags, signal: options.signal });
16960
17091
  const messages = this.iamStore.findAllByEvent(eventName);
16961
17092
  const messagesSortedByPriority = this.getMessagesSortedByEventPriority(eventName, messages);
16962
- return this.getFirstValidMessageByEvent(messagesSortedByPriority);
17093
+ return this.getFirstValidMessageByEvent(messagesSortedByPriority, options.signal);
16963
17094
  }
16964
- async getFirstValidMessageByEvent(messages) {
17095
+ async getFirstValidMessageByEvent(messages, signal) {
16965
17096
  let validationError = new Error();
16966
17097
  for (const message of messages) {
16967
17098
  try {
16968
- const validMessage = await this.validateMessageByEvent(message);
17099
+ const validMessage = await this.validateMessageByEvent(message, signal);
16969
17100
  return validMessage;
16970
17101
  }
16971
17102
  catch (error) {
@@ -16974,15 +17105,15 @@ class IamDisplayService {
16974
17105
  }
16975
17106
  throw validationError;
16976
17107
  }
16977
- async validateMessageByEvent(message) {
17108
+ async validateMessageByEvent(message, signal) {
16978
17109
  const validator = new IamValidator(this.storyManager, this.iamStore);
16979
17110
  validator.checkFrequencyLimit(message).checkDisplayTimeRange(message).validate();
16980
17111
  if (message.hasLimit)
16981
- await this.checkMesageLimit(message.id);
17112
+ await this.checkMesageLimit(message.id, signal);
16982
17113
  return message;
16983
17114
  }
16984
- async checkMesageLimit(messageId) {
16985
- const { canOpen } = await this.iamApi.checkMesageLimit(messageId);
17115
+ async checkMesageLimit(messageId, signal) {
17116
+ const { canOpen } = await this.iamApi.checkMesageLimit(messageId, signal);
16986
17117
  if (!canOpen)
16987
17118
  throw new IamMessageLimitExceededError(messageId);
16988
17119
  }
@@ -20973,11 +21104,11 @@ let IamStore = (() => {
20973
21104
  this._isLoading = false;
20974
21105
  }
20975
21106
  }
20976
- async findById(messageId) {
21107
+ async findById(messageId, options = {}) {
20977
21108
  const message = this._messages.get(messageId.toString());
20978
21109
  if (message)
20979
21110
  return message;
20980
- return this.fetchById(messageId);
21111
+ return this.fetchById(messageId, options.signal);
20981
21112
  }
20982
21113
  findAllByEvent(eventName) {
20983
21114
  let messages = Array.from(this._messages.values()).filter(message => message.hasEvent(eventName));
@@ -20988,27 +21119,33 @@ let IamStore = (() => {
20988
21119
  async updateMessageUserData(messageId, data) {
20989
21120
  return this.iamApi.updateUserData(messageId, data);
20990
21121
  }
20991
- async fetchById(messageId) {
21122
+ async fetchById(messageId, signal) {
20992
21123
  await this.rootStore.sessionStore.open();
20993
- const messageContext = await this.fetchMessageContext({ messageIds: [messageId] });
20994
- const messageDto = await this.iamApi.fetchById(messageId);
21124
+ const messageContext = await this.fetchMessageContext({ messageIds: [messageId], signal });
21125
+ const messageDto = await this.iamApi.fetchById(messageId, signal);
20995
21126
  return this.createMessageByDto(messageDto, messageContext);
20996
21127
  }
20997
21128
  async fetchAll(params) {
20998
21129
  await this.rootStore.sessionStore.open();
20999
21130
  const config = this.rootStore.storyManagerConfigStore.config;
21000
21131
  const tags = params.tags ? params.tags : config.tags;
21001
- const messageDtos = await this.iamApi.fetchAll({ tags: filterTags(tags), options: config.options });
21132
+ const messageDtos = await this.iamApi.fetchAll({
21133
+ tags: filterTags(tags),
21134
+ options: config.options,
21135
+ signal: params.signal
21136
+ });
21002
21137
  const messageContext = await this.fetchMessageContext({
21003
- messageIds: messageDtos.map(message => message.id)
21138
+ messageIds: messageDtos.map(message => message.id),
21139
+ signal: params.signal
21004
21140
  });
21005
21141
  return this.createMessagesByDtos(messageDtos, messageContext);
21006
21142
  }
21007
- async fetchMessageContext({ messageIds }) {
21143
+ async fetchMessageContext({ messageIds, signal }) {
21008
21144
  await this.rootStore.sessionStore.open();
21009
21145
  const messageContextDto = await this.iamApi.fetchContext({
21010
21146
  needFetchStyles: !this.iamCSS,
21011
- messageIds
21147
+ messageIds,
21148
+ signal
21012
21149
  });
21013
21150
  if (!this.iamCSS && messageContextDto.style) {
21014
21151
  this.iamCSS = applyInternalFontFamilyPrefix(messageContextDto.style, this.rootStore.storyManagerConfigStore.config.fontPrefix);
@@ -21796,7 +21933,7 @@ class UgcEditorStore {
21796
21933
  const session = await this.storyManager.rootStore.sessionStore.open();
21797
21934
  const ugcEditorConfigDto = await this.ugcEditorApi.fetchUgcEditorConfig();
21798
21935
  const storyManagerConfig = this.storyManager.config;
21799
- const sdkVersion = "1.15.0";
21936
+ const sdkVersion = "1.15.2";
21800
21937
  this._config = {
21801
21938
  sessionId: session.id,
21802
21939
  apiKey: storyManagerConfig.apiKey,
@@ -22256,11 +22393,11 @@ class StoryManager extends TypedEventEmitter {
22256
22393
  return deviceDescriptor.deviceId;
22257
22394
  }
22258
22395
  get sdkVersionName() {
22259
- const sdkVersionName = "1.15.0";
22396
+ const sdkVersionName = "1.15.2";
22260
22397
  return sdkVersionName || "0.0.0";
22261
22398
  }
22262
22399
  get sdkVersionCode() {
22263
- const sdkVersionCode = 11500;
22400
+ const sdkVersionCode = 11502;
22264
22401
  return sdkVersionCode ? parseInt(sdkVersionCode) : 0;
22265
22402
  }
22266
22403
  get lang() {
@@ -22324,7 +22461,7 @@ class StoryManager extends TypedEventEmitter {
22324
22461
  this.rootStore.storyManagerConfigStore.setConfig(configDto);
22325
22462
  }
22326
22463
  setUserAgent(userAgent) {
22327
- const sdkVersionCode = 11500;
22464
+ const sdkVersionCode = 11502;
22328
22465
  const buildVersion = sdkVersionCode ? parseInt(sdkVersionCode) : 0;
22329
22466
  // According to RFC5987, HTTP header values can legitimately be supplied using the ISO-8859-1 encoding.
22330
22467
  this._userAgent = `${userAgent} ${convertStrToLatin1(navigator.userAgent)}`;