@amityco/ts-sdk 7.1.0 → 7.1.1-207e990f.0

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 (68) hide show
  1. package/.env +26 -26
  2. package/dist/@types/core/events.d.ts +2 -1
  3. package/dist/@types/core/events.d.ts.map +1 -1
  4. package/dist/@types/core/model.d.ts +2 -0
  5. package/dist/@types/core/model.d.ts.map +1 -1
  6. package/dist/@types/core/readReceipt.d.ts +12 -1
  7. package/dist/@types/core/readReceipt.d.ts.map +1 -1
  8. package/dist/@types/domains/channel.d.ts +10 -0
  9. package/dist/@types/domains/channel.d.ts.map +1 -1
  10. package/dist/@types/domains/client.d.ts +1 -0
  11. package/dist/@types/domains/client.d.ts.map +1 -1
  12. package/dist/channelRepository/api/markChannelsAsReadBySegment.d.ts +16 -0
  13. package/dist/channelRepository/api/markChannelsAsReadBySegment.d.ts.map +1 -0
  14. package/dist/channelRepository/events/onChannelDeleted.d.ts.map +1 -1
  15. package/dist/channelRepository/events/onChannelLeft.d.ts.map +1 -1
  16. package/dist/{marker → channelRepository}/events/onChannelUnreadUpdatedLocal.d.ts +2 -2
  17. package/dist/channelRepository/events/onChannelUnreadUpdatedLocal.d.ts.map +1 -0
  18. package/dist/channelRepository/observers/getChannel.d.ts.map +1 -1
  19. package/dist/channelRepository/observers/getChannels/ChannelLiveCollectionController.d.ts.map +1 -1
  20. package/dist/channelRepository/utils/constructChannelDynamicValue.d.ts.map +1 -1
  21. package/dist/channelRepository/utils/getLegacyChannelUnread.d.ts +2 -0
  22. package/dist/channelRepository/utils/getLegacyChannelUnread.d.ts.map +1 -0
  23. package/dist/channelRepository/utils/prepareChannelPayload.d.ts.map +1 -1
  24. package/dist/client/api/createClient.d.ts.map +1 -1
  25. package/dist/client/api/enableUnreadCount.d.ts.map +1 -1
  26. package/dist/client/api/login.d.ts.map +1 -1
  27. package/dist/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngine.d.ts +33 -0
  28. package/dist/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngine.d.ts.map +1 -0
  29. package/dist/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngineOnLoginHandler.d.ts +3 -0
  30. package/dist/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngineOnLoginHandler.d.ts.map +1 -0
  31. package/dist/client/utils/ReadReceiptSync/readReceiptSyncEngine.d.ts +2 -4
  32. package/dist/client/utils/ReadReceiptSync/readReceiptSyncEngine.d.ts.map +1 -1
  33. package/dist/core/events.d.ts +3 -3
  34. package/dist/core/events.d.ts.map +1 -1
  35. package/dist/core/model/idResolvers.d.ts.map +1 -1
  36. package/dist/index.cjs.js +407 -50
  37. package/dist/index.esm.js +407 -50
  38. package/dist/index.umd.js +4 -4
  39. package/dist/marker/events/onChannelUnreadInfoUpdatedLocal.d.ts +12 -0
  40. package/dist/marker/events/onChannelUnreadInfoUpdatedLocal.d.ts.map +1 -0
  41. package/dist/messageRepository/events/onMessageCreated.d.ts.map +1 -1
  42. package/dist/messageRepository/utils/markReadMessage.d.ts.map +1 -1
  43. package/package.json +1 -1
  44. package/src/@types/core/events.ts +2 -1
  45. package/src/@types/core/model.ts +4 -0
  46. package/src/@types/core/readReceipt.ts +14 -1
  47. package/src/@types/domains/channel.ts +13 -0
  48. package/src/@types/domains/client.ts +2 -0
  49. package/src/channelRepository/api/markChannelsAsReadBySegment.ts +29 -0
  50. package/src/channelRepository/events/onChannelDeleted.ts +17 -4
  51. package/src/channelRepository/events/onChannelLeft.ts +11 -3
  52. package/src/{marker → channelRepository}/events/onChannelUnreadUpdatedLocal.ts +3 -3
  53. package/src/channelRepository/observers/getChannel.ts +3 -1
  54. package/src/channelRepository/observers/getChannels/ChannelLiveCollectionController.ts +6 -1
  55. package/src/channelRepository/utils/constructChannelDynamicValue.ts +12 -2
  56. package/src/channelRepository/utils/getLegacyChannelUnread.ts +5 -0
  57. package/src/channelRepository/utils/prepareChannelPayload.ts +57 -17
  58. package/src/client/api/createClient.ts +3 -0
  59. package/src/client/api/enableUnreadCount.ts +1 -0
  60. package/src/client/api/login.ts +5 -1
  61. package/src/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngine.ts +267 -0
  62. package/src/client/utils/ReadReceiptSync/legacyReadReceiptSyncEngineOnLoginHandler.ts +21 -0
  63. package/src/client/utils/ReadReceiptSync/readReceiptSyncEngine.ts +70 -99
  64. package/src/core/model/idResolvers.ts +2 -0
  65. package/src/marker/events/onChannelUnreadInfoUpdatedLocal.ts +29 -0
  66. package/src/messageRepository/events/onMessageCreated.ts +34 -0
  67. package/src/messageRepository/utils/markReadMessage.ts +10 -3
  68. package/dist/marker/events/onChannelUnreadUpdatedLocal.d.ts.map +0 -1
package/dist/index.esm.js CHANGED
@@ -501,6 +501,7 @@ const idResolvers = {
501
501
  messagePreviewSubChannel: ({ subChannelId }) => `${subChannelId}`,
502
502
  channelUnreadInfo: ({ channelId }) => channelId,
503
503
  subChannelUnreadInfo: ({ subChannelId }) => subChannelId,
504
+ channelUnread: ({ channelId }) => channelId,
504
505
  channelMarker: ({ entityId, userId }) => `${entityId}#${userId}`,
505
506
  subChannelMarker: ({ entityId, feedId, userId }) => `${entityId}#${feedId}#${userId}`,
506
507
  messageMarker: ({ feedId, contentId, creatorId }) => `${feedId}#${contentId}#${creatorId}`,
@@ -1594,13 +1595,13 @@ class NetworkActivitiesWatcher {
1594
1595
  this._listener.clear();
1595
1596
  }
1596
1597
  }
1597
- let instance$5;
1598
+ let instance$6;
1598
1599
  var NetworkActivitiesWatcher$1 = {
1599
1600
  getInstance: () => {
1600
- if (!instance$5) {
1601
- instance$5 = new NetworkActivitiesWatcher();
1601
+ if (!instance$6) {
1602
+ instance$6 = new NetworkActivitiesWatcher();
1602
1603
  }
1603
- return instance$5;
1604
+ return instance$6;
1604
1605
  },
1605
1606
  };
1606
1607
 
@@ -21240,13 +21241,13 @@ class AnalyticsEngine {
21240
21241
  this._eventCapturer.resetAllBuckets();
21241
21242
  }
21242
21243
  }
21243
- let instance$4;
21244
+ let instance$5;
21244
21245
  var AnalyticsEngine$1 = {
21245
21246
  getInstance: () => {
21246
- if (!instance$4) {
21247
- instance$4 = new AnalyticsEngine();
21247
+ if (!instance$5) {
21248
+ instance$5 = new AnalyticsEngine();
21248
21249
  }
21249
- return instance$4;
21250
+ return instance$5;
21250
21251
  },
21251
21252
  };
21252
21253
 
@@ -21672,6 +21673,221 @@ const getMessageReadCount = (message, marker) => {
21672
21673
  getCachedMarker$2(message)) !== null && _a !== void 0 ? _a : { readCount: 0, deliveredCount: 0 };
21673
21674
  }; // and if not found in cache use default value `0`
21674
21675
 
21676
+ /**
21677
+ *
21678
+ * Mark subChannel as read by readToSegment
21679
+ *
21680
+ * @param subChannelIds the IDs of the {@link Amity.SubChannel} to update
21681
+ * @param readToSegment the segment to mark as read
21682
+ * @returns a success boolean if the {@link Amity.SubChannel} was updated
21683
+ *
21684
+ * @category Channel API
21685
+ * @async
21686
+ */
21687
+ const markChannelsAsReadBySegment = async (readings) => {
21688
+ const client = getActiveClient();
21689
+ try {
21690
+ await client.http.post('api/v3/channels/seen', { channels: readings });
21691
+ return true;
21692
+ }
21693
+ catch (e) {
21694
+ return false;
21695
+ }
21696
+ };
21697
+
21698
+ class MessageReadReceiptSyncEngine {
21699
+ constructor() {
21700
+ this.isActive = true;
21701
+ this.MAX_RETRY = 3;
21702
+ this.JOB_QUEUE_SIZE = 120;
21703
+ this.jobQueue = [];
21704
+ // Interval for message read receipt sync in seconds
21705
+ this.RECEIPT_SYNC_INTERVAL = 1;
21706
+ this.client = getActiveClient();
21707
+ // Get remaining unsync read receipts from cache
21708
+ this.getUnsyncJobs();
21709
+ }
21710
+ // Call this when client call client.login
21711
+ startSyncReadReceipt() {
21712
+ // Start timer when start receipt sync
21713
+ this.timer = setInterval(() => {
21714
+ this.syncReadReceipts();
21715
+ }, this.RECEIPT_SYNC_INTERVAL * 1000);
21716
+ }
21717
+ // Read receipt observer handling
21718
+ syncReadReceipts() {
21719
+ if (this.jobQueue.length === 0 || this.isActive === false)
21720
+ return;
21721
+ const readReceipts = this.getReadReceipts();
21722
+ if (readReceipts) {
21723
+ this.markReadApi(readReceipts);
21724
+ }
21725
+ }
21726
+ getUnsyncJobs() {
21727
+ var _a;
21728
+ // Get all read receipts that has latestSyncSegment < latestSegment
21729
+ const readReceipts = (_a = queryCache(['readReceipt'])) === null || _a === void 0 ? void 0 : _a.filter(({ data }) => {
21730
+ return data.latestSyncSegment < data.latestSegment;
21731
+ });
21732
+ // Enqueue unsync read receipts to the job queue
21733
+ readReceipts === null || readReceipts === void 0 ? void 0 : readReceipts.forEach(({ data: readReceipt }) => {
21734
+ this.enqueueReadReceipt(readReceipt.channelId, readReceipt.latestSegment);
21735
+ });
21736
+ }
21737
+ getReadReceipts() {
21738
+ // get all read receipts from queue, now the queue is empty
21739
+ const syncJob = this.jobQueue.splice(0, this.jobQueue.length);
21740
+ if (syncJob.length === 0)
21741
+ return;
21742
+ return syncJob.filter(job => {
21743
+ var _a;
21744
+ const readReceipt = (_a = pullFromCache(['readReceipt', job.channelId])) === null || _a === void 0 ? void 0 : _a.data;
21745
+ if (!readReceipt)
21746
+ return false;
21747
+ if (readReceipt.latestSegment > readReceipt.latestSyncSegment)
21748
+ return true;
21749
+ return false;
21750
+ });
21751
+ }
21752
+ async markReadApi(syncJobs) {
21753
+ var _a;
21754
+ // constuct payload
21755
+ // example: [{ channelId: 'channelId', readToSegment: 2 }]
21756
+ const syncJobsPayload = syncJobs.map(job => {
21757
+ return {
21758
+ channelId: job.channelId,
21759
+ readToSegment: job.segment,
21760
+ };
21761
+ });
21762
+ const response = await markChannelsAsReadBySegment(syncJobsPayload);
21763
+ if (response) {
21764
+ for (let i = 0; i < syncJobs.length; i += 1) {
21765
+ // update lastestSyncSegment in read receipt cache
21766
+ const cacheKey = ['readReceipt', syncJobs[i].channelId];
21767
+ const readReceiptCache = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
21768
+ pushToCache(cacheKey, Object.assign(Object.assign({}, readReceiptCache), { latestSyncSegment: syncJobs[i].segment }));
21769
+ }
21770
+ }
21771
+ else {
21772
+ for (let i = 0; i < syncJobs.length; i += 1) {
21773
+ // push them back to queue if the syncing is failed and retry count is less than max retry
21774
+ if (syncJobs[i].retryCount >= this.MAX_RETRY)
21775
+ return;
21776
+ const updatedJob = Object.assign(Object.assign({}, syncJobs[i]), { syncState: "create" /* Amity.ReadReceiptSyncState.CREATED */, retryCount: syncJobs[i].retryCount + 1 });
21777
+ this.enqueueJob(updatedJob);
21778
+ }
21779
+ }
21780
+ }
21781
+ startObservingReadReceiptQueue() {
21782
+ if (this.client.useLegacyUnreadCount) {
21783
+ this.isActive = true;
21784
+ this.startSyncReadReceipt();
21785
+ }
21786
+ }
21787
+ stopObservingReadReceiptQueue() {
21788
+ this.isActive = false;
21789
+ this.jobQueue.map(job => {
21790
+ if (job.syncState === "syncing" /* Amity.ReadReceiptSyncState.SYNCING */) {
21791
+ return Object.assign(Object.assign({}, job), { syncState: "create" /* Amity.ReadReceiptSyncState.CREATED */ });
21792
+ }
21793
+ return job;
21794
+ });
21795
+ if (this.timer)
21796
+ clearInterval(this.timer);
21797
+ }
21798
+ // Session Management
21799
+ onSessionEstablished() {
21800
+ this.startObservingReadReceiptQueue();
21801
+ }
21802
+ onSessionDestroyed() {
21803
+ this.stopObservingReadReceiptQueue();
21804
+ this.jobQueue = [];
21805
+ }
21806
+ onTokenExpired() {
21807
+ this.stopObservingReadReceiptQueue();
21808
+ }
21809
+ // Network Connection Management
21810
+ onNetworkOffline() {
21811
+ // Stop observing to the read receipt queue.
21812
+ this.stopObservingReadReceiptQueue();
21813
+ }
21814
+ onNetworkOnline() {
21815
+ // Resume observing to the read receipt queue.
21816
+ this.startObservingReadReceiptQueue();
21817
+ }
21818
+ markRead(channelId, segment) {
21819
+ var _a;
21820
+ // Step 1: Optimistic update of channelUnread.readToSegment to message.segment and update unreadCount value
21821
+ const cacheKey = ['channelUnread', 'get', channelId];
21822
+ const channelUnread = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
21823
+ if (channelUnread && segment > channelUnread.readToSegment) {
21824
+ channelUnread.readToSegment = segment;
21825
+ channelUnread.unreadCount = Math.max(channelUnread.lastSegment - segment, 0);
21826
+ pushToCache(cacheKey, channelUnread);
21827
+ fireEvent('local.channelUnread.updated', channelUnread);
21828
+ }
21829
+ // Step 2: Enqueue the read receipt
21830
+ this.enqueueReadReceipt(channelId, segment);
21831
+ }
21832
+ enqueueReadReceipt(channelId, segment) {
21833
+ var _a;
21834
+ const readReceipt = (_a = pullFromCache(['readReceipt', channelId])) === null || _a === void 0 ? void 0 : _a.data;
21835
+ // Create new read receipt if it's not exists and add the job to queue
21836
+ if (!readReceipt) {
21837
+ const readReceiptChannel = {
21838
+ channelId,
21839
+ latestSegment: segment,
21840
+ latestSyncSegment: 0,
21841
+ };
21842
+ pushToCache(['readReceipt', channelId], readReceiptChannel);
21843
+ }
21844
+ else if (readReceipt.latestSegment < segment) {
21845
+ // Update latestSegment in read receipt cache
21846
+ pushToCache(['readReceipt', channelId], Object.assign(Object.assign({}, readReceipt), { latestSegment: segment }));
21847
+ }
21848
+ else if (readReceipt.latestSyncSegment >= segment) {
21849
+ // Skip the job when lastSyncSegment > = segment
21850
+ return;
21851
+ }
21852
+ let syncJob = this.getSyncJob(channelId);
21853
+ if (syncJob === null || syncJob.syncState === "syncing" /* Amity.ReadReceiptSyncState.SYNCING */) {
21854
+ syncJob = {
21855
+ channelId,
21856
+ segment,
21857
+ syncState: "create" /* Amity.ReadReceiptSyncState.CREATED */,
21858
+ retryCount: 0,
21859
+ };
21860
+ this.enqueueJob(syncJob);
21861
+ }
21862
+ else if (syncJob.segment < segment) {
21863
+ syncJob.segment = segment;
21864
+ }
21865
+ }
21866
+ getSyncJob(channelId) {
21867
+ const { jobQueue } = this;
21868
+ const targetJob = jobQueue.find(job => job.channelId === channelId);
21869
+ return targetJob || null;
21870
+ }
21871
+ enqueueJob(syncJob) {
21872
+ if (this.jobQueue.length < this.JOB_QUEUE_SIZE) {
21873
+ this.jobQueue.push(syncJob);
21874
+ }
21875
+ else {
21876
+ // Remove oldest job when queue reach maximum capacity
21877
+ this.jobQueue.shift();
21878
+ this.jobQueue.push(syncJob);
21879
+ }
21880
+ }
21881
+ }
21882
+ let instance$4 = null;
21883
+ var ReadReceiptSyncEngine = {
21884
+ getInstance: () => {
21885
+ if (!instance$4)
21886
+ instance$4 = new MessageReadReceiptSyncEngine();
21887
+ return instance$4;
21888
+ },
21889
+ };
21890
+
21675
21891
  /**
21676
21892
  *
21677
21893
  * Mark subChannel as read by readToSegment
@@ -21720,7 +21936,7 @@ const reCalculateChannelUnreadInfo = (channelId) => {
21720
21936
  return channelUnreadInfo;
21721
21937
  };
21722
21938
 
21723
- class MessageReadReceiptSyncEngine {
21939
+ class LegacyMessageReadReceiptSyncEngine {
21724
21940
  constructor() {
21725
21941
  this.isActive = true;
21726
21942
  this.MAX_RETRY = 3;
@@ -21751,7 +21967,7 @@ class MessageReadReceiptSyncEngine {
21751
21967
  getUnsyncJobs() {
21752
21968
  var _a;
21753
21969
  // Get all read receipts that has latestSyncSegment < latestSegment
21754
- const readReceipts = (_a = queryCache(['readReceipt'])) === null || _a === void 0 ? void 0 : _a.filter(({ data }) => {
21970
+ const readReceipts = (_a = queryCache(['legacyReadReceipt'])) === null || _a === void 0 ? void 0 : _a.filter(({ data }) => {
21755
21971
  return data.latestSyncSegment < data.latestSegment;
21756
21972
  });
21757
21973
  // Enqueue unsync read receipts to the job queue
@@ -21770,7 +21986,7 @@ class MessageReadReceiptSyncEngine {
21770
21986
  return;
21771
21987
  // Get readReceipt from cache by subChannelId
21772
21988
  const readReceipt = (_a = pullFromCache([
21773
- 'readReceipt',
21989
+ 'legacyReadReceipt',
21774
21990
  syncJob.subChannelId,
21775
21991
  ])) === null || _a === void 0 ? void 0 : _a.data;
21776
21992
  if (!readReceipt)
@@ -21793,10 +22009,10 @@ class MessageReadReceiptSyncEngine {
21793
22009
  if (response) {
21794
22010
  this.removeSynedReceipt(syncJob.subChannelId, syncJob.segment);
21795
22011
  const readReceiptCache = (_a = pullFromCache([
21796
- 'readReceipt',
22012
+ 'legacyReadReceipt',
21797
22013
  subChannelId,
21798
22014
  ])) === null || _a === void 0 ? void 0 : _a.data;
21799
- pushToCache(['readReceipt', subChannelId], Object.assign(Object.assign({}, readReceiptCache), { latestSyncSegment: segment }));
22015
+ pushToCache(['legacyReadReceipt', subChannelId], Object.assign(Object.assign({}, readReceiptCache), { latestSyncSegment: segment }));
21800
22016
  }
21801
22017
  else if (!response) {
21802
22018
  if (newSyncJob.retryCount > this.MAX_RETRY) {
@@ -21863,7 +22079,7 @@ class MessageReadReceiptSyncEngine {
21863
22079
  subChannelUnreadInfo.readToSegment = segment;
21864
22080
  subChannelUnreadInfo.unreadCount = Math.max(subChannelUnreadInfo.lastSegment - segment, 0);
21865
22081
  const channelUnreadInfo = reCalculateChannelUnreadInfo(subChannelUnreadInfo.channelId);
21866
- fireEvent('local.channelUnread.updated', channelUnreadInfo);
22082
+ fireEvent('local.channelUnreadInfo.updated', channelUnreadInfo);
21867
22083
  pushToCache(cacheKey, subChannelUnreadInfo);
21868
22084
  fireEvent('local.subChannelUnread.updated', subChannelUnreadInfo);
21869
22085
  }
@@ -21872,7 +22088,10 @@ class MessageReadReceiptSyncEngine {
21872
22088
  }
21873
22089
  enqueueReadReceipt(subChannelId, segment) {
21874
22090
  var _a;
21875
- const readReceipt = (_a = pullFromCache(['readReceipt', subChannelId])) === null || _a === void 0 ? void 0 : _a.data;
22091
+ const readReceipt = (_a = pullFromCache([
22092
+ 'legacyReadReceipt',
22093
+ subChannelId,
22094
+ ])) === null || _a === void 0 ? void 0 : _a.data;
21876
22095
  // Create new read receipt if it's not exists and add job to queue
21877
22096
  if (!readReceipt) {
21878
22097
  const readReceiptSubChannel = {
@@ -21880,10 +22099,10 @@ class MessageReadReceiptSyncEngine {
21880
22099
  latestSegment: segment,
21881
22100
  latestSyncSegment: 0,
21882
22101
  };
21883
- pushToCache(['readReceipt', subChannelId], readReceiptSubChannel);
22102
+ pushToCache(['legacyReadReceipt', subChannelId], readReceiptSubChannel);
21884
22103
  }
21885
22104
  else if (readReceipt.latestSegment < segment) {
21886
- pushToCache(['readReceipt', subChannelId], Object.assign(Object.assign({}, readReceipt), { latestSegment: segment }));
22105
+ pushToCache(['legacyReadReceipt', subChannelId], Object.assign(Object.assign({}, readReceipt), { latestSegment: segment }));
21887
22106
  }
21888
22107
  else if (readReceipt.latestSyncSegment >= segment) {
21889
22108
  // Skip the job when lastSyncSegment > = segment
@@ -21926,18 +22145,24 @@ class MessageReadReceiptSyncEngine {
21926
22145
  }
21927
22146
  }
21928
22147
  let instance$3 = null;
21929
- var ReadReceiptSyncEngine = {
22148
+ var LegacyReadReceiptSyncEngine = {
21930
22149
  getInstance: () => {
21931
22150
  if (!instance$3)
21932
- instance$3 = new MessageReadReceiptSyncEngine();
22151
+ instance$3 = new LegacyMessageReadReceiptSyncEngine();
21933
22152
  return instance$3;
21934
22153
  },
21935
22154
  };
21936
22155
 
21937
22156
  const markReadMessage = (message) => {
21938
- const { subChannelId, channelSegment } = message;
21939
- const markReadReceiptEngine = ReadReceiptSyncEngine.getInstance();
21940
- markReadReceiptEngine.markRead(subChannelId, channelSegment);
22157
+ const client = getActiveClient();
22158
+ if (client.useLegacyUnreadCount) {
22159
+ const markReadReceiptEngine = ReadReceiptSyncEngine.getInstance();
22160
+ markReadReceiptEngine.markRead(message.channelId, message.channelSegment);
22161
+ }
22162
+ else {
22163
+ const markReadReceiptEngine = LegacyReadReceiptSyncEngine.getInstance();
22164
+ markReadReceiptEngine.markRead(message.subChannelId, message.channelSegment);
22165
+ }
21941
22166
  };
21942
22167
 
21943
22168
  const messageLinkedObject = (message) => {
@@ -22925,6 +23150,24 @@ const preUpdateChannelCache = (rawPayload, options = { isMessagePreviewUpdated:
22925
23150
  channels: rawPayload.channels.map(channel => convertFromRaw(channel, { isMessagePreviewUpdated: options.isMessagePreviewUpdated })),
22926
23151
  });
22927
23152
  };
23153
+ const updateChannelUnread = ({ currentUserId, channels, channelUsers, }) => {
23154
+ for (let i = 0; i < channels.length; i += 1) {
23155
+ const cacheKey = ['channelUnread', 'get', channels[i].channelId];
23156
+ const { readToSegment, lastMentionedSegment } = channelUsers.find(channelUser => channelUser.channelId === channels[i].channelId && channelUser.userId === currentUserId) || {
23157
+ readToSegment: 0,
23158
+ lastMentionedSegment: 0,
23159
+ };
23160
+ pushToCache(cacheKey, {
23161
+ channelId: channels[i].channelId,
23162
+ lastSegment: channels[i].messageCount,
23163
+ readToSegment,
23164
+ lastMentionedSegment,
23165
+ unreadCount: channels[i].messageCount - readToSegment,
23166
+ isMentioned: lastMentionedSegment > readToSegment,
23167
+ isDeleted: channels[i].isDeleted,
23168
+ });
23169
+ }
23170
+ };
22928
23171
  const prepareChannelPayload = async (rawPayload, options = { isMessagePreviewUpdated: true }) => {
22929
23172
  const client = getActiveClient();
22930
23173
  const networkPreviewSetting = await client.getMessagePreviewSetting(false);
@@ -22934,23 +23177,34 @@ const prepareChannelPayload = async (rawPayload, options = { isMessagePreviewUpd
22934
23177
  rawPayload.messagePreviews.length > 0) {
22935
23178
  updateChannelMessagePreviewCache(rawPayload);
22936
23179
  }
22937
- const markerIds = rawPayload.channels
22938
- // filter channel by type. Only conversation, community and broadcast type are included.
22939
- .filter(isUnreadCountSupport)
22940
- .map(({ channelInternalId }) => channelInternalId);
22941
- if (markerIds.length > 0) {
22942
- // since the get markers method requires a channel cache to function with the reducer.
22943
- preUpdateChannelCache(rawPayload, { isMessagePreviewUpdated: options.isMessagePreviewUpdated });
22944
- try {
22945
- await getChannelMarkers(markerIds);
22946
- }
22947
- catch (e) {
22948
- // empty block (from the spec, allow marker fetch to fail without having to do anything)
23180
+ if (client.useLegacyUnreadCount) {
23181
+ updateChannelUnread({
23182
+ channels: rawPayload.channels,
23183
+ channelUsers: rawPayload.channelUsers,
23184
+ currentUserId: client.userId,
23185
+ });
23186
+ }
23187
+ else {
23188
+ const markerIds = rawPayload.channels
23189
+ // filter channel by type. Only conversation, community and broadcast type are included.
23190
+ .filter(isUnreadCountSupport)
23191
+ .map(({ channelInternalId }) => channelInternalId);
23192
+ if (markerIds.length > 0) {
23193
+ // since the get markers method requires a channel cache to function with the reducer.
23194
+ preUpdateChannelCache(rawPayload, {
23195
+ isMessagePreviewUpdated: options.isMessagePreviewUpdated,
23196
+ });
23197
+ try {
23198
+ await getChannelMarkers(markerIds);
23199
+ }
23200
+ catch (e) {
23201
+ // empty block (from the spec, allow marker fetch to fail without having to do anything)
23202
+ }
22949
23203
  }
22950
23204
  }
22951
- // attach marker to channel
23205
+ // convert raw channel to internal channel
22952
23206
  const channels = rawPayload.channels.map(payload => convertFromRaw(payload, { isMessagePreviewUpdated: options.isMessagePreviewUpdated }));
22953
- // user marker to channel users
23207
+ // convert raw channel user to membership (add user object)
22954
23208
  const channelUsers = rawPayload.channelUsers.map(channelUser => {
22955
23209
  return convertRawMembershipToMembership(channelUser);
22956
23210
  });
@@ -23077,15 +23331,28 @@ const getSubChannelsUnreadCount = (channel, marker) => {
23077
23331
  return (_e = (_c = marker === null || marker === void 0 ? void 0 : marker.unreadCount) !== null && _c !== void 0 ? _c : (_d = getCachedMarker(channel.channelInternalId)) === null || _d === void 0 ? void 0 : _d.unreadCount) !== null && _e !== void 0 ? _e : 0;
23078
23332
  };
23079
23333
 
23334
+ const getLegacyChannelUnread = (channelId) => {
23335
+ var _a;
23336
+ return (_a = pullFromCache(['channelUnread', 'get', channelId])) === null || _a === void 0 ? void 0 : _a.data;
23337
+ };
23338
+
23080
23339
  const constructChannelDynamicValue = (channel) => {
23340
+ const client = getActiveClient();
23081
23341
  const rest = __rest(channel, ["messageCount"]);
23082
23342
  return shallowClone(rest, {
23083
- get isMentioned() {
23084
- return getChannelIsMentioned(rest);
23343
+ get unreadCount() {
23344
+ var _a, _b;
23345
+ return (_b = (_a = getLegacyChannelUnread(rest.channelId)) === null || _a === void 0 ? void 0 : _a.unreadCount) !== null && _b !== void 0 ? _b : 0;
23085
23346
  },
23086
23347
  get subChannelsUnreadCount() {
23087
23348
  return getSubChannelsUnreadCount(rest);
23088
23349
  },
23350
+ get isMentioned() {
23351
+ var _a, _b;
23352
+ if (client.useLegacyUnreadCount)
23353
+ return (_b = (_a = getLegacyChannelUnread(rest.channelId)) === null || _a === void 0 ? void 0 : _a.isMentioned) !== null && _b !== void 0 ? _b : false;
23354
+ return getChannelIsMentioned(rest);
23355
+ },
23089
23356
  });
23090
23357
  };
23091
23358
 
@@ -23742,12 +24009,21 @@ const onChannelDeleted = (callback) => {
23742
24009
  const client = getActiveClient();
23743
24010
  const filter = async (payload) => {
23744
24011
  const data = await prepareChannelPayload(payload);
23745
- if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode()) {
23746
- data.channels.forEach(channel => {
24012
+ const isConsistentMode = client.getMarkerSyncConsistentMode() && client.isUnreadCountEnabled;
24013
+ const isLegacyUnreadCount = client.useLegacyUnreadCount;
24014
+ data.channels.forEach(channel => {
24015
+ if (isConsistentMode) {
23747
24016
  addFlagIsDeletedSubChannelUnreadByChannelId(channel.channelId);
23748
24017
  deleteChannelUnreadByChannelId(channel.channelId);
23749
- });
23750
- }
24018
+ }
24019
+ else if (isLegacyUnreadCount) {
24020
+ const cacheKey = ['channelUnread', 'get', channel.channelId];
24021
+ const cache = pullFromCache(cacheKey);
24022
+ if (cache) {
24023
+ pushToCache(cacheKey, Object.assign(Object.assign({}, cache), { isDeleted: true }));
24024
+ }
24025
+ }
24026
+ });
23751
24027
  ingestInCache(data);
23752
24028
  callbacks$b.forEach(cb => cb(data.channels[0]));
23753
24029
  };
@@ -23861,6 +24137,25 @@ var readReceiptSyncEngineOnLoginHandler = () => {
23861
24137
  };
23862
24138
  };
23863
24139
 
24140
+ var legacyReadReceiptSyncEngineOnLoginHandler = () => {
24141
+ const readReceiptSyncEngine = LegacyReadReceiptSyncEngine.getInstance();
24142
+ readReceiptSyncEngine.startSyncReadReceipt();
24143
+ onSessionStateChange(state => {
24144
+ if (state === "established" /* Amity.SessionStates.ESTABLISHED */) {
24145
+ readReceiptSyncEngine.onSessionEstablished();
24146
+ }
24147
+ else if (state === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */) {
24148
+ readReceiptSyncEngine.onTokenExpired();
24149
+ }
24150
+ else {
24151
+ readReceiptSyncEngine.onSessionDestroyed();
24152
+ }
24153
+ });
24154
+ return () => {
24155
+ readReceiptSyncEngine.onSessionDestroyed();
24156
+ };
24157
+ };
24158
+
23864
24159
  const onOnline = (callback) => {
23865
24160
  if (typeof window !== 'undefined' && window.addEventListener) {
23866
24161
  window.addEventListener('online', callback);
@@ -24427,10 +24722,17 @@ const onChannelLeft = (callback) => {
24427
24722
  const preparedPayload = await prepareChannelPayload(payload, {
24428
24723
  isMessagePreviewUpdated: isLeftByMe,
24429
24724
  });
24430
- if (client.isUnreadCountEnabled && client.getMarkerSyncConsistentMode() && isLeftByMe) {
24725
+ const isConsistentMode = client.getMarkerSyncConsistentMode() && client.isUnreadCountEnabled;
24726
+ const isLegacyUnreadCount = client.useLegacyUnreadCount;
24727
+ if (isLeftByMe) {
24431
24728
  preparedPayload.channels.forEach(channel => {
24432
- addFlagIsDeletedSubChannelUnreadByChannelId(channel.channelId);
24433
- deleteChannelUnreadByChannelId(channel.channelId);
24729
+ if (isConsistentMode) {
24730
+ addFlagIsDeletedSubChannelUnreadByChannelId(channel.channelId);
24731
+ deleteChannelUnreadByChannelId(channel.channelId);
24732
+ }
24733
+ else if (isLegacyUnreadCount) {
24734
+ dropFromCache(['channelUnread', 'get', channel.channelId]);
24735
+ }
24434
24736
  });
24435
24737
  }
24436
24738
  const { channels, channelUsers } = preparedPayload;
@@ -24698,6 +25000,29 @@ const onMessageCreatedMqtt = (callback) => {
24698
25000
  reCalculateChannelUnreadInfo(message.channelId);
24699
25001
  });
24700
25002
  }
25003
+ if (client.useLegacyUnreadCount) {
25004
+ rawPayload.messages.forEach(message => {
25005
+ var _a, _b;
25006
+ const channelUnread = (_a = pullFromCache([
25007
+ 'channelUnread',
25008
+ 'get',
25009
+ message.channelId,
25010
+ ])) === null || _a === void 0 ? void 0 : _a.data;
25011
+ if (!channelUnread || channelUnread.lastSegment >= message.segment)
25012
+ return;
25013
+ const lastSegment = message.segment;
25014
+ const isMentionedInMessage = (_b = message.mentionedUsers) === null || _b === void 0 ? void 0 : _b.some(mention => {
25015
+ return (mention.type === 'channel' ||
25016
+ (mention.type === 'user' &&
25017
+ client.userId &&
25018
+ mention.userPublicIds.includes(client.userId)));
25019
+ });
25020
+ const lastMentionSegment = isMentionedInMessage
25021
+ ? message.segment
25022
+ : channelUnread.lastMentionSegment;
25023
+ pushToCache(['channelUnread', 'get', message.channelId], Object.assign(Object.assign({}, channelUnread), { lastSegment, unreadCount: lastSegment - channelUnread.readToSegment, lastMentionSegment, isMentioned: !(channelUnread.readToSegment >= lastMentionSegment) }));
25024
+ });
25025
+ }
24701
25026
  // Update in cache
24702
25027
  ingestInCache(payload);
24703
25028
  payload.messages.forEach(message => {
@@ -24873,6 +25198,7 @@ const enableUnreadCount = () => {
24873
25198
  if (client.isUnreadCountEnabled)
24874
25199
  return false;
24875
25200
  client.isUnreadCountEnabled = true;
25201
+ client.useLegacyUnreadCount = false;
24876
25202
  client.emitter.emit('unreadCountEnabled', true);
24877
25203
  return true;
24878
25204
  };
@@ -25188,7 +25514,12 @@ const login = async (params, sessionHandler, config) => {
25188
25514
  // NOTE: This is a temporary solution to handle the channel marker when the user is forced to leave
25189
25515
  // the channel because currently backend can't handle this, so every time a user is banned from
25190
25516
  // a channel or the channel is deleted the channel's unread count will not be reset to zero
25191
- onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), readReceiptSyncEngineOnLoginHandler(), objectResolverEngineOnLoginHandler());
25517
+ onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler());
25518
+ if (client.useLegacyUnreadCount) {
25519
+ subscriptions.push(readReceiptSyncEngineOnLoginHandler());
25520
+ }
25521
+ else
25522
+ subscriptions.push(legacyReadReceiptSyncEngineOnLoginHandler());
25192
25523
  const markerSyncUnsubscriber = await startMarkerSync();
25193
25524
  subscriptions.push(markerSyncUnsubscriber);
25194
25525
  }
@@ -25369,6 +25700,8 @@ const createClient = (apiKey, apiRegion = API_REGIONS.SG, { debugSession = DEFAU
25369
25700
  const sessionState = "notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */;
25370
25701
  const sessionHandler = undefined;
25371
25702
  const isUnreadCountEnabled = false;
25703
+ // Legacy unread count is true by default
25704
+ const useLegacyUnreadCount = true;
25372
25705
  const client = {
25373
25706
  version: `${VERSION}`,
25374
25707
  apiKey,
@@ -25398,6 +25731,7 @@ const createClient = (apiKey, apiRegion = API_REGIONS.SG, { debugSession = DEFAU
25398
25731
  getMessagePreviewSetting,
25399
25732
  use: () => setActiveClient(client),
25400
25733
  isUnreadCountEnabled,
25734
+ useLegacyUnreadCount,
25401
25735
  getMarkerSyncConsistentMode,
25402
25736
  /**
25403
25737
  * Prefix for the deviceId key in the local storage or async storage.
@@ -32531,19 +32865,37 @@ var index$f = /*#__PURE__*/Object.freeze({
32531
32865
  /**
32532
32866
  * Internal used only
32533
32867
  *
32534
- * Fired when an {@link Amity.userMessageFeedMarkers} has been resolved by Object Rsesolver
32868
+ * Fired when an {@link Amity.channelUnreadInfo} has been updated.
32535
32869
  *
32536
32870
  * @param callback The function to call when the event was fired
32537
32871
  * @returns an {@link Amity.Unsubscriber} function to stop listening
32538
32872
  *
32539
- * @category MessageMarker Events
32873
+ * @category ChannelMarker Events
32874
+ */
32875
+ const onChannelUnreadInfoUpdatedLocal = (callback) => {
32876
+ const client = getActiveClient();
32877
+ const filter = (payload) => {
32878
+ callback(payload);
32879
+ };
32880
+ return createEventSubscriber(client, 'channelMarker/onChannelUnreadInfoUpdatedLocal', 'local.channelUnreadInfo.updated', filter);
32881
+ };
32882
+
32883
+ /**
32884
+ * Internal used only
32885
+ *
32886
+ * Fired when an {@link Amity.ChannelUnread} has been updated.
32887
+ *
32888
+ * @param callback The function to call when the event was fired
32889
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
32890
+ *
32891
+ * @category Channel Events
32540
32892
  */
32541
32893
  const onChannelUnreadUpdatedLocal = (callback) => {
32542
32894
  const client = getActiveClient();
32543
32895
  const filter = (payload) => {
32544
32896
  callback(payload);
32545
32897
  };
32546
- return createEventSubscriber(client, 'channelMarker/onChannelUnreadUpdatedLocal', 'local.channelUnread.updated', filter);
32898
+ return createEventSubscriber(client, 'channel/onChannelUnreadUpdatedLocal', 'local.channelUnread.updated', filter);
32547
32899
  };
32548
32900
 
32549
32901
  /* begin_public_function
@@ -32745,6 +33097,7 @@ const getChannel = (channelId, callback) => {
32745
33097
  return onSubChannelUpdated(updateMessagePreview);
32746
33098
  }, 'channelId', 'channel'),
32747
33099
  convertEventPayload(onSubChannelCreated, 'channelId', 'channel'),
33100
+ convertEventPayload(onChannelUnreadInfoUpdatedLocal, 'channelId', 'channel'),
32748
33101
  convertEventPayload(onChannelUnreadUpdatedLocal, 'channelId', 'channel'),
32749
33102
  ], {
32750
33103
  forceDispatch: true,
@@ -33258,6 +33611,10 @@ class ChannelLiveCollectionController extends LiveCollectionController {
33258
33611
  },
33259
33612
  action: "OnResolveUnread" /* Amity.ChannelActionType.OnResolveUnread */,
33260
33613
  },
33614
+ {
33615
+ fn: convertEventPayload(onChannelUnreadInfoUpdatedLocal, 'channelId', 'channel'),
33616
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
33617
+ },
33261
33618
  {
33262
33619
  fn: convertEventPayload(onChannelUnreadUpdatedLocal, 'channelId', 'channel'),
33263
33620
  action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
@@ -39873,7 +40230,7 @@ var index$3 = /*#__PURE__*/Object.freeze({
39873
40230
  getPoll: getPoll
39874
40231
  });
39875
40232
 
39876
- const privateKey = "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDHo80SecH7FuF2\nhFYnb+l26/VN8UMLXAQFLnxciNTEwkGVFMpdezlH8rU2HtUJL4RETogbAOLVY0XM\njs6sPn8G1nALmh9qeDpUtVqFOVtBHxEZ910TLOtQiunjqJKO5nWdqZ71EC3OFluR\niGQkO84BiIFbv37ub7xl3S8XarbtKoLcyVpkDHi+1wx1pgCAn6gtBUgckPL5NR8j\nLseabl3HAXQfhTCKo4tmOFM2Dxwl1IUMmIJrJg/aIU/U0tj/1Eoo7mG0JcNWX19l\nW3EecCbi0ncCJOrkUdwlBrcjaMayaX/ubEwyUeTGiLdyc4L3GRLHjyK8xgVNXRMH\nbZWJ2a5NAgMBAAECggEASxuE+35zTFO/XydKgmvIGcWL9FbgMlXb7Vcf0nBoG945\nbiz0NVc2paraIhJXc608xbYF3qLmtAE1MVBI0ORyRdBHNxY024l/6H6SH60Ed+uI\nM4ysp5ourY6Vj+DLwpdRiI9YDjqYAQDIUmhNxJP7XPhOMoZI6st+xZQBM34ic/bv\nAMSJm9OZphSp3+qXVkFZztr2mxD2EZSJJLYxi8BCdgM2qhazalbcJ6zDKHCZWVWm\n8RRxDGldyMb/237JxETzP40tAlzOZDmBAbUgEnurDJ93RVDIE3rbZUshwgeQd18a\nem096mWgvB1AIKYgsTAR3pw+V19YWAjq/glP6fz8wQKBgQD/oQq+ukKF0PRgBeM5\ngeTjSwsdGppQLmf5ndujvoiz/TpdjDEPu6R8kigQr1rG2t4K/yfdZoI8RdmJD1al\n3Q7N9hofooSy4rj6E3txzWZCHJjHad2cnCp/O26HiReGAl7wTcfTmNdiFHhZQzm5\nJBkvWAiwuvQMNfEbnXxw6/vIDwKBgQDH7fX8gsc77JLvAWgp1MaQN/sbqVb6JeT1\nFQfR8E/WFCSmzQBtNzd5KgYuCeelwr/8DyYytvN2BzCYZXp73gI1jF3YlW5jVn74\nOY6TwQ095digwo6Z0yuxopdIOApKgAkL9PRKgNrqAf3NAyMua6lOGifzjDojC3KU\nfylQmxMn4wKBgHp2B9O/H0dEBw5JQ8W0+JX6yWQz7mEjGiR2/1W+XXb8hQ1zr709\nw1r6Gb+EghRpnZ3fBpYGGbYOMFx8wKHM+N6qW3F0ReX8v2juFGE8aRSa5oYBrWzt\nU16Idjbv8hj84cZ1PJmdyvDtpYn9rpWHOZl4rxEbPvbqkIsOMyNVqdT5AoGAOSge\nmwIIU2le2FVeohbibXiToWTYKMuMmURZ5/r72AgKMmWJKbAPe+Q3wBG01/7FRBpQ\noU8Ma0HC8s6QJbliiEyIx9JwrJWd1vkdecBHONrtA4ibm/5zD2WcOllLF+FitLhi\n3qnX6+6F0IaFGFBPJrTzlv0P4dTz/OAdv52V7GECgYEA2TttOKBAqWllgOaZOkql\nLVMJVmgR7s6tLi1+cEP8ZcapV9aRbRzTAKXm4f8AEhtlG9F9kCOvHYCYGi6JaiWJ\nZkHjeex3T+eE6Di6y5Bm/Ift5jtVhJ4jCVwHOKTMej79NPUFTJfv8hCo29haBDv6\nRXFrv+T21KCcw8k3sJeJWWQ=\n-----END PRIVATE KEY-----";
40233
+ const privateKey = "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDAARz+hmBgi8pJ\nQb8LeY41gtHhk+ACMwRfhsn7GqpqRQNG2qU0755mzZuVDUqjQMGSo8THJB7O+OJs\nflbZRkFXlFoFOVNw1UpNOgwEQZ6wB9oRwzepTJAfF1sVhm/o/ixvXh1zDFNDy6yZ\npXyiiJHUVxqyjllZhxnwdvjoVtDs6hW6awG09bB9nh/TTejlUKXoAgzqVwu/1QMu\nUVViET495elEe19aUarEy+oL2iKeXCEvqda/pWNBdbieFyJvvZ08HN8dPuT88wq2\njZLEAth1vrwQ2IAa4ktaLcBQdLJgIkrbDvAiVZ8lQAjS/bq5vXQikTGvoPlC5bbn\nvuOM/3eLAgMBAAECggEAVZ+peHAghq2QVj71nX5lxsNCKaCyYwixSJBpfouTt7Rz\nE6PpzMOXFi1W1o+I22jDakuSM2SOQKqI/u0QefB0r0O/KVk5NrZHXk0mkrdYtxOp\nUgaGyf8UvmjB+8VqHrNKyZdk9qtmbnNj01kTTcAtmE4H39zPR7eR/8Rul94vaZbs\nwCnKJS3mLT3JxyGug6lxanveKkjG+CKC1nJQYWaxCJxaFSzbwXQPvDhB+TvrIbee\npd5v4EAyEJohpr+T9oDGGJkb/KARBZCtwLyB976PKJwwBA8MRVL1i5QwawuMiMq5\nUtnOnbGKtCeFzaLbNU0Qi8bqyims84EQxC6DOu1fkQKBgQDdvsoBsEhsOXV7hlIJ\naEd0eSJZVkdqimxH8uGoMM2FeNaOrcB6yBXqTSP0R3OIyf8eaY6yjRvP30ZNXcll\n/gD3O1Mu6YmWQdt1W2WA6pKOsUuPXasf0pdOF7IiFZKlSabz5YHXFqwVuqm8loaj\nsXel3YWqPVdHiankE7tz+3ssnQKBgQDdqi4TNdD1MdEpihx19jr0QjUiXW3939FK\nqp30HESPEGDGQzXdmJgif9HhZb+cJSuWaHEbjgBrYahvgCF+y6LbEpOD+D/dmT+s\nDEAQaR84sah6dokwPjV8fjBSrcVFjCS+doxv0d3p/9OUEeyUhFrY03nxtIEYkLIE\n/Zvn37b4RwKBgQCLENVFe9XfsaVhQ5r9dV2iyTlmh7qgMZG5CbTFs12hQGhm8McO\n+Z7s41YSJCFr/yq1WwP4LJDtrBw99vyQr1zRsG35tNLp3gGRNzGQSQyC2uQFVHw2\np+7mNewsfhUK/gbrXNsyFnDz6635rPlhfbII3sWuP2wWXFqkxE9CbMwR7QKBgQC6\nawDMzxmo2/iYArrkyevSuEuPVxvFwpF1RgAI6C0QVCnPE38dmdN4UB7mfHekje4W\nVEercMURidPp0cxZolCYBQtilUjAyL0vqC3In1/Ogjq6oy3FEMxSop1pKxMY5j+Q\nnoqFD+6deLUrddeNH7J3X4LSr4dSbX4JjG+tlgt+yQKBgQCuwTL4hA6KqeInQ0Ta\n9VQX5Qr8hFlqJz1gpymi/k63tW/Ob8yedbg3WWNWyShwRMFYyY9S81ITFWM95uL6\nvF3x9rmRjwElJw9PMwVu6dmf/CO0Z1wzXSp2VVD12gbrUD/0/d7MUoJ9LgC8X8f/\nn0txLHYGHbx+nf95+JUg6lV3hg==\n-----END PRIVATE KEY-----";
39877
40234
  /*
39878
40235
  * The crypto algorithm used for importing key and signing string
39879
40236
  */