@amityco/ts-sdk-react-native 7.22.1-f15e84ea.0 → 7.23.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 (222) hide show
  1. package/dist/@types/core/errors.d.ts +3 -1
  2. package/dist/@types/core/errors.d.ts.map +1 -1
  3. package/dist/@types/core/events.d.ts +7 -1
  4. package/dist/@types/core/events.d.ts.map +1 -1
  5. package/dist/@types/core/model.d.ts +4 -0
  6. package/dist/@types/core/model.d.ts.map +1 -1
  7. package/dist/@types/core/payload.d.ts +15 -0
  8. package/dist/@types/core/payload.d.ts.map +1 -1
  9. package/dist/@types/core/transport.d.ts +1 -0
  10. package/dist/@types/core/transport.d.ts.map +1 -1
  11. package/dist/@types/domains/analytics.d.ts +3 -2
  12. package/dist/@types/domains/analytics.d.ts.map +1 -1
  13. package/dist/@types/domains/block.d.ts +5 -0
  14. package/dist/@types/domains/block.d.ts.map +1 -1
  15. package/dist/@types/domains/channel.d.ts +31 -0
  16. package/dist/@types/domains/channel.d.ts.map +1 -1
  17. package/dist/@types/domains/client.d.ts +31 -2
  18. package/dist/@types/domains/client.d.ts.map +1 -1
  19. package/dist/@types/domains/comment.d.ts +1 -0
  20. package/dist/@types/domains/comment.d.ts.map +1 -1
  21. package/dist/@types/domains/feed.d.ts +14 -0
  22. package/dist/@types/domains/feed.d.ts.map +1 -1
  23. package/dist/@types/domains/message.d.ts +16 -0
  24. package/dist/@types/domains/message.d.ts.map +1 -1
  25. package/dist/@types/domains/post.d.ts +2 -0
  26. package/dist/@types/domains/post.d.ts.map +1 -1
  27. package/dist/@types/domains/sharableContentType.d.ts +9 -0
  28. package/dist/@types/domains/sharableContentType.d.ts.map +1 -0
  29. package/dist/@types/index.d.ts +2 -1
  30. package/dist/@types/index.d.ts.map +1 -1
  31. package/dist/analytic/service/analytic/AnalyticsEngine.d.ts +1 -0
  32. package/dist/analytic/service/analytic/AnalyticsEngine.d.ts.map +1 -1
  33. package/dist/analytic/service/analytic/AnalyticsEventCapturer.d.ts +2 -1
  34. package/dist/analytic/service/analytic/AnalyticsEventCapturer.d.ts.map +1 -1
  35. package/dist/analytic/service/analytic/AnalyticsService.d.ts +1 -0
  36. package/dist/analytic/service/analytic/AnalyticsService.d.ts.map +1 -1
  37. package/dist/channelRepository/api/archiveChannel.d.ts +16 -0
  38. package/dist/channelRepository/api/archiveChannel.d.ts.map +1 -0
  39. package/dist/channelRepository/api/getArchivedChannelIds.d.ts +13 -0
  40. package/dist/channelRepository/api/getArchivedChannelIds.d.ts.map +1 -0
  41. package/dist/channelRepository/api/index.d.ts +3 -0
  42. package/dist/channelRepository/api/index.d.ts.map +1 -1
  43. package/dist/channelRepository/api/unarchiveChannel.d.ts +16 -0
  44. package/dist/channelRepository/api/unarchiveChannel.d.ts.map +1 -0
  45. package/dist/channelRepository/api/updateChannel.d.ts +1 -1
  46. package/dist/channelRepository/api/updateChannel.d.ts.map +1 -1
  47. package/dist/channelRepository/channelMembership/observers/getMembers/ChannelMemberQueryStreamController.d.ts.map +1 -1
  48. package/dist/channelRepository/channelModeration/api/banMembers.d.ts.map +1 -1
  49. package/dist/channelRepository/channelModeration/api/muteMembers.d.ts.map +1 -1
  50. package/dist/channelRepository/channelModeration/api/unbanMembers.d.ts.map +1 -1
  51. package/dist/channelRepository/channelModeration/api/unmuteMembers.d.ts.map +1 -1
  52. package/dist/channelRepository/events/index.d.ts +2 -0
  53. package/dist/channelRepository/events/index.d.ts.map +1 -1
  54. package/dist/channelRepository/events/onChannelArchived.d.ts +10 -0
  55. package/dist/channelRepository/events/onChannelArchived.d.ts.map +1 -0
  56. package/dist/channelRepository/events/onChannelMemberRoleRemoved.d.ts.map +1 -1
  57. package/dist/channelRepository/events/onChannelUnarchived.d.ts +11 -0
  58. package/dist/channelRepository/events/onChannelUnarchived.d.ts.map +1 -0
  59. package/dist/channelRepository/observers/getArchivedChannels/ArchivedChannelLiveCollectionController.d.ts +12 -0
  60. package/dist/channelRepository/observers/getArchivedChannels/ArchivedChannelLiveCollectionController.d.ts.map +1 -0
  61. package/dist/channelRepository/observers/getArchivedChannels/ArchivedChannelPaginationController.d.ts +11 -0
  62. package/dist/channelRepository/observers/getArchivedChannels/ArchivedChannelPaginationController.d.ts.map +1 -0
  63. package/dist/channelRepository/observers/getArchivedChannels/ArchivedChannelQueryStreamController.d.ts +13 -0
  64. package/dist/channelRepository/observers/getArchivedChannels/ArchivedChannelQueryStreamController.d.ts.map +1 -0
  65. package/dist/channelRepository/observers/getArchivedChannels/getArchivedChannels.d.ts +20 -0
  66. package/dist/channelRepository/observers/getArchivedChannels/getArchivedChannels.d.ts.map +1 -0
  67. package/dist/channelRepository/observers/getArchivedChannels/index.d.ts +2 -0
  68. package/dist/channelRepository/observers/getArchivedChannels/index.d.ts.map +1 -0
  69. package/dist/channelRepository/observers/getChannels/ChannelLiveCollectionController.d.ts.map +1 -1
  70. package/dist/channelRepository/observers/getChannels/ChannelQueryStreamController.d.ts.map +1 -1
  71. package/dist/channelRepository/observers/index.d.ts +2 -0
  72. package/dist/channelRepository/observers/index.d.ts.map +1 -1
  73. package/dist/channelRepository/observers/searchChannels/SearchChannelLiveCollectionController.d.ts +14 -0
  74. package/dist/channelRepository/observers/searchChannels/SearchChannelLiveCollectionController.d.ts.map +1 -0
  75. package/dist/channelRepository/observers/searchChannels/SearchChannelPaginationController.d.ts +10 -0
  76. package/dist/channelRepository/observers/searchChannels/SearchChannelPaginationController.d.ts.map +1 -0
  77. package/dist/channelRepository/observers/searchChannels/SearchChannelQueryStreamController.d.ts +13 -0
  78. package/dist/channelRepository/observers/searchChannels/SearchChannelQueryStreamController.d.ts.map +1 -0
  79. package/dist/channelRepository/observers/searchChannels.d.ts +21 -0
  80. package/dist/channelRepository/observers/searchChannels.d.ts.map +1 -0
  81. package/dist/channelRepository/observers/tests/integrations/searchChannels.integration.test.d.ts +2 -0
  82. package/dist/channelRepository/observers/tests/integrations/searchChannels.integration.test.d.ts.map +1 -0
  83. package/dist/channelRepository/utils/prepareChannelPayload.d.ts.map +1 -1
  84. package/dist/client/api/autoSubscription.d.ts +47 -0
  85. package/dist/client/api/autoSubscription.d.ts.map +1 -0
  86. package/dist/client/api/createClient.d.ts.map +1 -1
  87. package/dist/client/api/getCoreUserSettings.d.ts +16 -0
  88. package/dist/client/api/getCoreUserSettings.d.ts.map +1 -0
  89. package/dist/client/api/getForYouFeedSetting.d.ts +17 -0
  90. package/dist/client/api/getForYouFeedSetting.d.ts.map +1 -0
  91. package/dist/client/api/getShareableLinkConfiguration.d.ts.map +1 -1
  92. package/dist/client/api/index.d.ts +4 -0
  93. package/dist/client/api/index.d.ts.map +1 -1
  94. package/dist/client/api/setupLoginSubscriptions.d.ts.map +1 -1
  95. package/dist/client/api/tests/ShareableLinkConfiguration.test.d.ts +2 -0
  96. package/dist/client/api/tests/ShareableLinkConfiguration.test.d.ts.map +1 -0
  97. package/dist/client/api/tests/notifications.integration.test.d.ts +2 -0
  98. package/dist/client/api/tests/notifications.integration.test.d.ts.map +1 -0
  99. package/dist/client/services/ReadReceiptSync/readReceiptSyncEngine.d.ts.map +1 -1
  100. package/dist/client/utils/autoSubscriptionManager.d.ts +21 -0
  101. package/dist/client/utils/autoSubscriptionManager.d.ts.map +1 -0
  102. package/dist/client/utils/subscribeGlobalTopic.d.ts +6 -1
  103. package/dist/client/utils/subscribeGlobalTopic.d.ts.map +1 -1
  104. package/dist/client/utils/tests/autoSubscriptionManager.test.d.ts +2 -0
  105. package/dist/client/utils/tests/autoSubscriptionManager.test.d.ts.map +1 -0
  106. package/dist/commentRepository/observers/getComments/CommentLiveCollectionController.d.ts.map +1 -1
  107. package/dist/commentRepository/observers/tests/integrations/getCommentsExcludeBlockUser.integration.test.d.ts +2 -0
  108. package/dist/commentRepository/observers/tests/integrations/getCommentsExcludeBlockUser.integration.test.d.ts.map +1 -0
  109. package/dist/core/events.d.ts +3 -3
  110. package/dist/core/events.d.ts.map +1 -1
  111. package/dist/core/model/idResolvers.d.ts.map +1 -1
  112. package/dist/core/model/index.d.ts.map +1 -1
  113. package/dist/core/query/filtering.d.ts +32 -0
  114. package/dist/core/query/filtering.d.ts.map +1 -1
  115. package/dist/core/query/paging.d.ts +1 -0
  116. package/dist/core/query/paging.d.ts.map +1 -1
  117. package/dist/core/subscription.d.ts +3 -0
  118. package/dist/core/subscription.d.ts.map +1 -1
  119. package/dist/feedRepository/errors/AmityForYouFeedDisabledError.d.ts +13 -0
  120. package/dist/feedRepository/errors/AmityForYouFeedDisabledError.d.ts.map +1 -0
  121. package/dist/feedRepository/index.d.ts +2 -1
  122. package/dist/feedRepository/index.d.ts.map +1 -1
  123. package/dist/feedRepository/observers/getForYouFeed/CursorController.d.ts +19 -0
  124. package/dist/feedRepository/observers/getForYouFeed/CursorController.d.ts.map +1 -0
  125. package/dist/feedRepository/observers/getForYouFeed/LiveCollectionController.d.ts +13 -0
  126. package/dist/feedRepository/observers/getForYouFeed/LiveCollectionController.d.ts.map +1 -0
  127. package/dist/feedRepository/observers/getForYouFeed/PaginationController.d.ts +13 -0
  128. package/dist/feedRepository/observers/getForYouFeed/PaginationController.d.ts.map +1 -0
  129. package/dist/feedRepository/observers/getForYouFeed/QueryStreamController.d.ts +15 -0
  130. package/dist/feedRepository/observers/getForYouFeed/QueryStreamController.d.ts.map +1 -0
  131. package/dist/feedRepository/observers/getForYouFeed.d.ts +19 -0
  132. package/dist/feedRepository/observers/getForYouFeed.d.ts.map +1 -0
  133. package/dist/feedRepository/observers/index.d.ts +1 -0
  134. package/dist/feedRepository/observers/index.d.ts.map +1 -1
  135. package/dist/feedRepository/observers/tests/integration/getForYouFeed.integration.test.d.ts +2 -0
  136. package/dist/feedRepository/observers/tests/integration/getForYouFeed.integration.test.d.ts.map +1 -0
  137. package/dist/feedRepository/observers/tests/unit/CursorController.test.d.ts +2 -0
  138. package/dist/feedRepository/observers/tests/unit/CursorController.test.d.ts.map +1 -0
  139. package/dist/index.cjs.js +2544 -441
  140. package/dist/index.esm.js +2541 -442
  141. package/dist/index.umd.js +3 -3
  142. package/dist/messagePreview/utils/getChannelMessagePreviewWithUser.d.ts +1 -0
  143. package/dist/messagePreview/utils/getChannelMessagePreviewWithUser.d.ts.map +1 -1
  144. package/dist/messagePreview/utils/updateChannelMessagePreviewCache.d.ts.map +1 -1
  145. package/dist/messageRepository/events/onMessageCreated.d.ts.map +1 -1
  146. package/dist/messageRepository/observers/index.d.ts +1 -0
  147. package/dist/messageRepository/observers/index.d.ts.map +1 -1
  148. package/dist/messageRepository/observers/searchMessage/SearchMessageLiveCollectionController.d.ts +12 -0
  149. package/dist/messageRepository/observers/searchMessage/SearchMessageLiveCollectionController.d.ts.map +1 -0
  150. package/dist/messageRepository/observers/searchMessage/SearchMessagePaginationController.d.ts +10 -0
  151. package/dist/messageRepository/observers/searchMessage/SearchMessagePaginationController.d.ts.map +1 -0
  152. package/dist/messageRepository/observers/searchMessage/SearchMessageQueryStreamController.d.ts +8 -0
  153. package/dist/messageRepository/observers/searchMessage/SearchMessageQueryStreamController.d.ts.map +1 -0
  154. package/dist/messageRepository/observers/searchMessage/index.d.ts +2 -0
  155. package/dist/messageRepository/observers/searchMessage/index.d.ts.map +1 -0
  156. package/dist/messageRepository/observers/searchMessage/searchMessage.d.ts +24 -0
  157. package/dist/messageRepository/observers/searchMessage/searchMessage.d.ts.map +1 -0
  158. package/dist/postRepository/observers/getPosts/PostLiveCollectionController.d.ts.map +1 -1
  159. package/dist/postRepository/observers/tests/getPostsExcludeBlockUser.test.d.ts +2 -0
  160. package/dist/postRepository/observers/tests/getPostsExcludeBlockUser.test.d.ts.map +1 -0
  161. package/dist/postRepository/tests/integration/postAnalytics.integration.test.d.ts +2 -0
  162. package/dist/postRepository/tests/integration/postAnalytics.integration.test.d.ts.map +1 -0
  163. package/dist/postRepository/tests/integration/setup.d.ts +6 -0
  164. package/dist/postRepository/tests/integration/setup.d.ts.map +1 -0
  165. package/dist/reactionRepository/internalApi/addReaction.d.ts.map +1 -1
  166. package/dist/reactionRepository/internalApi/removeReaction.d.ts.map +1 -1
  167. package/dist/streamRepository/observers/getStreams/GetStreamsPageController.d.ts +1 -0
  168. package/dist/streamRepository/observers/getStreams/GetStreamsPageController.d.ts.map +1 -1
  169. package/dist/userRepository/api/getAllBlockedUsers.d.ts.map +1 -1
  170. package/dist/userRepository/api/getAllBlockingUsers.d.ts +20 -0
  171. package/dist/userRepository/api/getAllBlockingUsers.d.ts.map +1 -0
  172. package/dist/userRepository/api/index.d.ts +1 -0
  173. package/dist/userRepository/api/index.d.ts.map +1 -1
  174. package/dist/userRepository/api/tests/integration/getAllBlockingUsers.integration.test.d.ts +2 -0
  175. package/dist/userRepository/api/tests/integration/getAllBlockingUsers.integration.test.d.ts.map +1 -0
  176. package/dist/userRepository/observers/getBlockedUsers/BlockedUserLiveCollectionController.d.ts.map +1 -1
  177. package/dist/userRepository/observers/getBlockedUsers/BlockedUserQueryStreamController.d.ts +4 -3
  178. package/dist/userRepository/observers/getBlockedUsers/BlockedUserQueryStreamController.d.ts.map +1 -1
  179. package/dist/userRepository/observers/getBlockingUsers/LiveCollectionController.d.ts +13 -0
  180. package/dist/userRepository/observers/getBlockingUsers/LiveCollectionController.d.ts.map +1 -0
  181. package/dist/userRepository/observers/getBlockingUsers/PaginationController.d.ts +5 -0
  182. package/dist/userRepository/observers/getBlockingUsers/PaginationController.d.ts.map +1 -0
  183. package/dist/userRepository/observers/getBlockingUsers/QueryStreamController.d.ts +16 -0
  184. package/dist/userRepository/observers/getBlockingUsers/QueryStreamController.d.ts.map +1 -0
  185. package/dist/userRepository/observers/getBlockingUsers.d.ts +17 -0
  186. package/dist/userRepository/observers/getBlockingUsers.d.ts.map +1 -0
  187. package/dist/userRepository/observers/index.d.ts +1 -0
  188. package/dist/userRepository/observers/index.d.ts.map +1 -1
  189. package/dist/userRepository/observers/tests/integrations/getBlockingUsers.integration.test.d.ts +2 -0
  190. package/dist/userRepository/observers/tests/integrations/getBlockingUsers.integration.test.d.ts.map +1 -0
  191. package/dist/userRepository/relationship/block/enum/index.d.ts +5 -0
  192. package/dist/userRepository/relationship/block/enum/index.d.ts.map +1 -0
  193. package/dist/userRepository/relationship/block/events/index.d.ts +3 -0
  194. package/dist/userRepository/relationship/block/events/index.d.ts.map +1 -0
  195. package/dist/userRepository/relationship/block/events/onUserDidBlock.d.ts +20 -0
  196. package/dist/userRepository/relationship/block/events/onUserDidBlock.d.ts.map +1 -0
  197. package/dist/userRepository/relationship/block/events/onUserDidUnblock.d.ts +20 -0
  198. package/dist/userRepository/relationship/block/events/onUserDidUnblock.d.ts.map +1 -0
  199. package/dist/userRepository/relationship/block/index.d.ts +1 -0
  200. package/dist/userRepository/relationship/block/index.d.ts.map +1 -1
  201. package/dist/userRepository/relationship/block/utils/blockRealtimeOnLoginHandler.d.ts +12 -0
  202. package/dist/userRepository/relationship/block/utils/blockRealtimeOnLoginHandler.d.ts.map +1 -0
  203. package/dist/userRepository/relationship/block/utils/createBlockEventSubscriber.d.ts +11 -0
  204. package/dist/userRepository/relationship/block/utils/createBlockEventSubscriber.d.ts.map +1 -0
  205. package/dist/userRepository/services/BlockedUserSyncEngine/blockedUserSyncEngine.d.ts +13 -13
  206. package/dist/userRepository/services/BlockedUserSyncEngine/blockedUserSyncEngine.d.ts.map +1 -1
  207. package/dist/userRepository/services/BlockingUserSyncEngine/blockingUserSyncEngine.d.ts +56 -0
  208. package/dist/userRepository/services/BlockingUserSyncEngine/blockingUserSyncEngine.d.ts.map +1 -0
  209. package/dist/userRepository/services/BlockingUserSyncEngine/blockingUserSyncEngineOnLoginHandler.d.ts +3 -0
  210. package/dist/userRepository/services/BlockingUserSyncEngine/blockingUserSyncEngineOnLoginHandler.d.ts.map +1 -0
  211. package/dist/userRepository/utils/prepareBlockingUserPayload.d.ts +2 -0
  212. package/dist/userRepository/utils/prepareBlockingUserPayload.d.ts.map +1 -0
  213. package/dist/utils/constants.d.ts +4 -0
  214. package/dist/utils/constants.d.ts.map +1 -1
  215. package/dist/utils/linkedObject/channelLinkedObject.d.ts.map +1 -1
  216. package/dist/utils/linkedObject/postLinkedObject.d.ts.map +1 -1
  217. package/dist/utils/tests/dummy/block.d.ts +16 -0
  218. package/dist/utils/tests/dummy/block.d.ts.map +1 -1
  219. package/dist/utils/tests/dummy/community.d.ts +2 -0
  220. package/dist/utils/tests/dummy/community.d.ts.map +1 -1
  221. package/dist/utils/tests/dummy/post.d.ts.map +1 -1
  222. package/package.json +1 -1
package/dist/index.esm.js CHANGED
@@ -15,6 +15,13 @@ var MembershipAcceptanceTypeEnum;
15
15
  MembershipAcceptanceTypeEnum["AUTOMATIC"] = "automatic";
16
16
  MembershipAcceptanceTypeEnum["INVITATION"] = "invitation";
17
17
  })(MembershipAcceptanceTypeEnum || (MembershipAcceptanceTypeEnum = {}));
18
+ var AmityAutoSubscription;
19
+ (function (AmityAutoSubscription) {
20
+ AmityAutoSubscription["CHAT"] = "chat";
21
+ AmityAutoSubscription["NETWORK"] = "network";
22
+ AmityAutoSubscription["LIVESTREAM"] = "livestream";
23
+ AmityAutoSubscription["BLOCK"] = "block";
24
+ })(AmityAutoSubscription || (AmityAutoSubscription = {}));
18
25
 
19
26
  var UserTypeEnum;
20
27
  (function (UserTypeEnum) {
@@ -61,6 +68,13 @@ var FileAccessTypeEnum;
61
68
  FileAccessTypeEnum["NETWORK"] = "network";
62
69
  })(FileAccessTypeEnum || (FileAccessTypeEnum = {}));
63
70
 
71
+ var AmityChannelNotificationModeEnum;
72
+ (function (AmityChannelNotificationModeEnum) {
73
+ AmityChannelNotificationModeEnum["Default"] = "default";
74
+ AmityChannelNotificationModeEnum["Silent"] = "silent";
75
+ AmityChannelNotificationModeEnum["Subscribe"] = "subscribe";
76
+ })(AmityChannelNotificationModeEnum || (AmityChannelNotificationModeEnum = {}));
77
+
64
78
  const CommunityPostSettings = Object.freeze({
65
79
  ONLY_ADMIN_CAN_POST: 'ONLY_ADMIN_CAN_POST',
66
80
  ADMIN_REVIEW_POST_REQUIRED: 'ADMIN_REVIEW_POST_REQUIRED',
@@ -236,6 +250,15 @@ var AmityEventOrderOption;
236
250
  AmityEventOrderOption["Descending"] = "desc";
237
251
  })(AmityEventOrderOption || (AmityEventOrderOption = {}));
238
252
 
253
+ var AmitySharableContentType;
254
+ (function (AmitySharableContentType) {
255
+ AmitySharableContentType["POST"] = "post";
256
+ AmitySharableContentType["COMMUNITY"] = "community";
257
+ AmitySharableContentType["USER"] = "user";
258
+ AmitySharableContentType["LIVESTREAM"] = "livestream";
259
+ AmitySharableContentType["EVENT"] = "event";
260
+ })(AmitySharableContentType || (AmitySharableContentType = {}));
261
+
239
262
  var AnalyticsSourceTypeEnum;
240
263
  (function (AnalyticsSourceTypeEnum) {
241
264
  AnalyticsSourceTypeEnum["POST"] = "post";
@@ -277,8 +300,8 @@ var NotificationRolesFilterTypeEnum;
277
300
 
278
301
  function getVersion() {
279
302
  try {
280
- // the string ''v7.22.0-esm'' should be replaced by actual value by @rollup/plugin-replace
281
- return 'v7.22.0-esm';
303
+ // the string ''v7.23.0-esm'' should be replaced by actual value by @rollup/plugin-replace
304
+ return 'v7.23.0-esm';
282
305
  }
283
306
  catch (error) {
284
307
  return '__dev__';
@@ -287,6 +310,7 @@ function getVersion() {
287
310
  const VERSION = getVersion();
288
311
 
289
312
  const COLLECTION_DEFAULT_PAGINATION_LIMIT = 5;
313
+ const COLLECTION_DEFAULT_PAGINATION_SIZE = 20;
290
314
  const COLLECTION_DEFAULT_CACHING_POLICY = 'cache_then_server';
291
315
  const ENABLE_CACHE_MESSAGE = 'For using Live Collection feature you need to enable Cache!';
292
316
  const LIVE_OBJECT_ENABLE_CACHE_MESSAGE = 'For using Live Object feature you need to enable Cache!';
@@ -299,6 +323,9 @@ const DAY = 24 * HOUR;
299
323
  const WEEK = 7 * DAY;
300
324
  const YEAR = 365 * DAY;
301
325
  const ACCESS_TOKEN_WATCHER_INTERVAL = 10 * MINUTE;
326
+ const API_ENDPOINTS = {
327
+ forYouFeed: '/api/v1/feeds/for-you',
328
+ };
302
329
 
303
330
  // cache constants
304
331
  const CACHE_KEY_GET = 'get';
@@ -679,6 +706,107 @@ function createSnapshot(data, options) {
679
706
  return Object.assign(Object.assign({}, options), { data });
680
707
  }
681
708
 
709
+ /* eslint-disable max-classes-per-file */
710
+ /**
711
+ * Generic ASC error
712
+ * @category Errors
713
+ */
714
+ class ASCError extends Error {
715
+ /**
716
+ * @param message A custom error message
717
+ * @param code A normalized error code
718
+ * @param level A normalized failure level descriptor
719
+ */
720
+ constructor(message, code, level) {
721
+ super(`Amity SDK (${code}): ${message}`);
722
+ this.code = code;
723
+ this.level = level;
724
+ this.type = 'ASC';
725
+ this.timestamp = Date.now();
726
+ if (Error.captureStackTrace)
727
+ Error.captureStackTrace(this, ASCError);
728
+ }
729
+ }
730
+ /**
731
+ * API level error
732
+ * @category Errors
733
+ */
734
+ class ASCApiError extends ASCError {
735
+ /**
736
+ * @param code A normalized error code
737
+ * @param level A normalized failure level descriptor
738
+ */
739
+ // eslint-disable-next-line no-useless-constructor
740
+ constructor(message, code, level) {
741
+ super(message, code, level);
742
+ }
743
+ }
744
+ /**
745
+ * Unexpected error
746
+ * @category Errors
747
+ */
748
+ class ASCUnknownError extends ASCError {
749
+ /**
750
+ * @param code A normalized error code
751
+ * @param level A normalized failure level descriptor
752
+ */
753
+ constructor(code = 800000 /* Amity.ClientError.UNKNOWN_ERROR */, level = "fatal" /* Amity.ErrorLevel.FATAL */) {
754
+ super('Unexpected error', code, level);
755
+ }
756
+ }
757
+ /**
758
+ * Network related error
759
+ * @category Errors
760
+ */
761
+ class ASCConnectionError extends ASCError {
762
+ /**
763
+ * @param message A custom error message
764
+ */
765
+ constructor(event, message = 'SDK client is having connection issues') {
766
+ super(`${message} (${event})`, event === 'disconnected'
767
+ ? 800211 /* Amity.ClientError.DISCONNECTED */
768
+ : 800210 /* Amity.ClientError.CONNECTION_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
769
+ this.event = event;
770
+ }
771
+ }
772
+ /**
773
+ * Input sanitization related error
774
+ * @category Errors
775
+ */
776
+ class ASCInvalidParameterError extends ASCError {
777
+ /**
778
+ * @param message A custom error message
779
+ */
780
+ constructor(message) {
781
+ super(message, 800110 /* Amity.ClientError.INVALID_PARAMETERS */, "error" /* Amity.ErrorLevel.ERROR */);
782
+ }
783
+ }
784
+
785
+ let activeClient = null;
786
+ /**
787
+ * Get the active client
788
+ *
789
+ * @returns the active client instance
790
+ *
791
+ * @hidden
792
+ */
793
+ const getActiveClient = () => {
794
+ if (!activeClient) {
795
+ throw new ASCError('There is no active client', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "fatal" /* Amity.ErrorLevel.FATAL */);
796
+ }
797
+ return activeClient;
798
+ };
799
+ /**
800
+ * Sets the active client
801
+ *
802
+ * @param client the client to assume as currently active client
803
+ *
804
+ * @hidden
805
+ */
806
+ const setActiveClient = (client) => {
807
+ activeClient = client;
808
+ };
809
+
682
810
  /** @hidden */
683
811
  const idResolvers = {
684
812
  user: ({ userId }) => userId,
@@ -687,6 +815,7 @@ const idResolvers = {
687
815
  channel: ({ channelInternalId }) => channelInternalId,
688
816
  subChannel: ({ subChannelId }) => subChannelId,
689
817
  channelUsers: ({ channelId, userId }) => `${channelId}#${userId}`,
818
+ archivedChannel: ({ channelId }) => channelId,
690
819
  message: ({ messageId, referenceId }) => referenceId !== null && referenceId !== void 0 ? referenceId : messageId,
691
820
  messagePreviewChannel: ({ channelId }) => `${channelId}`,
692
821
  messagePreviewSubChannel: ({ subChannelId }) => `${subChannelId}`,
@@ -728,6 +857,7 @@ const idResolvers = {
728
857
  event: ({ eventId }) => eventId,
729
858
  eventResponse: ({ userId }) => userId,
730
859
  product: ({ productId }) => productId,
860
+ feedMetadata: ({ postId }) => postId,
731
861
  };
732
862
  /**
733
863
  * Retrieve the id resolver matching a domain name
@@ -750,6 +880,7 @@ const PAYLOAD2MODEL = {
750
880
  channels: 'channel',
751
881
  messageFeeds: 'subChannel',
752
882
  channelUsers: 'channelUsers',
883
+ archives: 'archivedChannel',
753
884
  messages: 'message',
754
885
  messagePreviewChannel: 'messagePreviewChannel',
755
886
  messagePreviewSubChannel: 'messagePreviewSubChannel',
@@ -788,6 +919,7 @@ const PAYLOAD2MODEL = {
788
919
  viewers: 'viewer',
789
920
  eventResponses: 'eventResponse',
790
921
  products: 'product',
922
+ feedMetadata: 'feedMetadata',
791
923
  };
792
924
  /** hidden */
793
925
  const isOutdated = (prevData, nextData) => {
@@ -802,107 +934,6 @@ function getFutureDate(date = new Date().toISOString()) {
802
934
  return new Date(new Date(date).getTime() + 1).toISOString();
803
935
  }
804
936
 
805
- /* eslint-disable max-classes-per-file */
806
- /**
807
- * Generic ASC error
808
- * @category Errors
809
- */
810
- class ASCError extends Error {
811
- /**
812
- * @param message A custom error message
813
- * @param code A normalized error code
814
- * @param level A normalized failure level descriptor
815
- */
816
- constructor(message, code, level) {
817
- super(`Amity SDK (${code}): ${message}`);
818
- this.code = code;
819
- this.level = level;
820
- this.type = 'ASC';
821
- this.timestamp = Date.now();
822
- if (Error.captureStackTrace)
823
- Error.captureStackTrace(this, ASCError);
824
- }
825
- }
826
- /**
827
- * API level error
828
- * @category Errors
829
- */
830
- class ASCApiError extends ASCError {
831
- /**
832
- * @param code A normalized error code
833
- * @param level A normalized failure level descriptor
834
- */
835
- // eslint-disable-next-line no-useless-constructor
836
- constructor(message, code, level) {
837
- super(message, code, level);
838
- }
839
- }
840
- /**
841
- * Unexpected error
842
- * @category Errors
843
- */
844
- class ASCUnknownError extends ASCError {
845
- /**
846
- * @param code A normalized error code
847
- * @param level A normalized failure level descriptor
848
- */
849
- constructor(code = 800000 /* Amity.ClientError.UNKNOWN_ERROR */, level = "fatal" /* Amity.ErrorLevel.FATAL */) {
850
- super('Unexpected error', code, level);
851
- }
852
- }
853
- /**
854
- * Network related error
855
- * @category Errors
856
- */
857
- class ASCConnectionError extends ASCError {
858
- /**
859
- * @param message A custom error message
860
- */
861
- constructor(event, message = 'SDK client is having connection issues') {
862
- super(`${message} (${event})`, event === 'disconnected'
863
- ? 800211 /* Amity.ClientError.DISCONNECTED */
864
- : 800210 /* Amity.ClientError.CONNECTION_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
865
- this.event = event;
866
- }
867
- }
868
- /**
869
- * Input sanitization related error
870
- * @category Errors
871
- */
872
- class ASCInvalidParameterError extends ASCError {
873
- /**
874
- * @param message A custom error message
875
- */
876
- constructor(message) {
877
- super(message, 800110 /* Amity.ClientError.INVALID_PARAMETERS */, "error" /* Amity.ErrorLevel.ERROR */);
878
- }
879
- }
880
-
881
- let activeClient = null;
882
- /**
883
- * Get the active client
884
- *
885
- * @returns the active client instance
886
- *
887
- * @hidden
888
- */
889
- const getActiveClient = () => {
890
- if (!activeClient) {
891
- throw new ASCError('There is no active client', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "fatal" /* Amity.ErrorLevel.FATAL */);
892
- }
893
- return activeClient;
894
- };
895
- /**
896
- * Sets the active client
897
- *
898
- * @param client the client to assume as currently active client
899
- *
900
- * @hidden
901
- */
902
- const setActiveClient = (client) => {
903
- activeClient = client;
904
- };
905
-
906
937
  /**
907
938
  * ```js
908
939
  * import { enableCache } from '@amityco/ts-sdk-react-native'
@@ -1410,6 +1441,65 @@ const filterBySearchTerm = (collection, searchTerm) => {
1410
1441
  return m.user && ((_a = m.user.displayName) === null || _a === void 0 ? void 0 : _a.match(containsMatcher));
1411
1442
  });
1412
1443
  };
1444
+ /**
1445
+ * The ids of users in a block relationship with the current user — in BOTH
1446
+ * directions — derived synchronously from the local follow cache. For every
1447
+ * `status === 'blocked'` row that involves the current user, the OTHER party
1448
+ * is collected: `from === me` (users I blocked, outgoing) contributes `to`;
1449
+ * `to === me` (users who blocked me, incoming) contributes `from`.
1450
+ *
1451
+ * @returns a set of block-related user ids (both directions)
1452
+ *
1453
+ * @hidden
1454
+ */
1455
+ const getBlockUsersId = () => {
1456
+ var _a;
1457
+ const { userId } = getActiveClient();
1458
+ const ids = new Set();
1459
+ ((_a = queryCache(['follow', 'get'])) !== null && _a !== void 0 ? _a : [])
1460
+ .map(entry => entry.data)
1461
+ .filter(follow => (follow === null || follow === void 0 ? void 0 : follow.status) === 'blocked' && (follow.from === userId || follow.to === userId))
1462
+ .forEach(follow => {
1463
+ ids.add(follow.from === userId ? follow.to : follow.from);
1464
+ });
1465
+ return ids;
1466
+ };
1467
+ /**
1468
+ * Filter out posts whose author or any mentionee is in a block relationship
1469
+ * with the current user, in either direction (see {@link getBlockUsersId}).
1470
+ *
1471
+ * @param collection the post collection to filter
1472
+ * @returns a filtered collection excluding posts involving block-related users
1473
+ *
1474
+ * @hidden
1475
+ */
1476
+ const filterPostsByBlockUsers = (collection) => {
1477
+ const blockUsersId = getBlockUsersId();
1478
+ if (blockUsersId.size === 0)
1479
+ return collection;
1480
+ return collection.filter(post => {
1481
+ var _a, _b;
1482
+ if (blockUsersId.has(post.postedUserId))
1483
+ return false;
1484
+ const mentionedUserIds = (_b = (_a = post.mentionees) === null || _a === void 0 ? void 0 : _a.flatMap(mention => (mention.type === 'user' ? mention.userIds : []))) !== null && _b !== void 0 ? _b : [];
1485
+ return !mentionedUserIds.some(id => blockUsersId.has(id));
1486
+ });
1487
+ };
1488
+ /**
1489
+ * Filter out comments whose creator is in a block relationship with the
1490
+ * current user, in either direction (see {@link getBlockUsersId}).
1491
+ *
1492
+ * @param collection the comment collection to filter
1493
+ * @returns a filtered collection excluding comments from block-related users
1494
+ *
1495
+ * @hidden
1496
+ */
1497
+ const filterCommentsByBlockUsers = (collection) => {
1498
+ const blockUsersId = getBlockUsersId();
1499
+ if (blockUsersId.size === 0)
1500
+ return collection;
1501
+ return collection.filter(comment => !blockUsersId.has(comment.userId));
1502
+ };
1413
1503
 
1414
1504
  // Note:
1415
1505
  // this file should contain a suite of sorting utilities to help the
@@ -1880,13 +1970,13 @@ class NetworkActivitiesWatcher {
1880
1970
  this._listener.clear();
1881
1971
  }
1882
1972
  }
1883
- let instance$9;
1973
+ let instance$b;
1884
1974
  var NetworkActivitiesWatcher$1 = {
1885
1975
  getInstance: () => {
1886
- if (!instance$9) {
1887
- instance$9 = new NetworkActivitiesWatcher();
1976
+ if (!instance$b) {
1977
+ instance$b = new NetworkActivitiesWatcher();
1888
1978
  }
1889
- return instance$9;
1979
+ return instance$b;
1890
1980
  },
1891
1981
  };
1892
1982
 
@@ -20725,18 +20815,149 @@ var mqtt$1 = {exports: {}};
20725
20815
 
20726
20816
  var mqtt = /*@__PURE__*/getDefaultExportFromCjs(mqtt$1.exports);
20727
20817
 
20818
+ class SessionWatcher {
20819
+ constructor() {
20820
+ this._sessionState = "notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */;
20821
+ this._listener = new Map();
20822
+ }
20823
+ onSessionStateChange(callback) {
20824
+ this._listener.set(callback, callback);
20825
+ return () => {
20826
+ this._listener.delete(callback);
20827
+ };
20828
+ }
20829
+ setSessionState(state, reason) {
20830
+ if (this._sessionState === state)
20831
+ return;
20832
+ this._sessionState = state;
20833
+ this._listener.forEach(cb => cb(state, reason));
20834
+ }
20835
+ destroy() {
20836
+ this._listener.clear();
20837
+ }
20838
+ }
20839
+ let instance$a;
20840
+ var SessionWatcher$1 = {
20841
+ getInstance: () => {
20842
+ if (!instance$a) {
20843
+ instance$a = new SessionWatcher();
20844
+ }
20845
+ return instance$a;
20846
+ },
20847
+ };
20848
+
20849
+ /**
20850
+ * ```js
20851
+ * import { onSessionStateChange } from '@amityco/ts-sdk-react-native'
20852
+ * const dispose = onSessionStateChange((state: Amity.SessionStates) => {
20853
+ * // ...
20854
+ * })
20855
+ * ```
20856
+ *
20857
+ * Fired when any {@link Amity.Client} has a session state change
20858
+ *
20859
+ * @param callback The function to call when the event was fired
20860
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
20861
+ *
20862
+ * @category Client Events
20863
+ */
20864
+ const onSessionStateChange = (callback) => SessionWatcher$1.getInstance().onSessionStateChange(callback);
20865
+
20866
+ const TOPICS = {
20867
+ [AmityAutoSubscription.NETWORK]: [getNetworkTopic],
20868
+ [AmityAutoSubscription.CHAT]: [
20869
+ getSmartFeedChannelTopic,
20870
+ getSmartFeedSubChannelTopic,
20871
+ getSmartFeedMessageTopic,
20872
+ ],
20873
+ [AmityAutoSubscription.LIVESTREAM]: [getLiveStreamTopic],
20874
+ [AmityAutoSubscription.BLOCK]: [getMyFollowersTopic, getMyFollowingsTopic],
20875
+ };
20876
+ const DEFAULT_TOPICS = [
20877
+ AmityAutoSubscription.CHAT,
20878
+ AmityAutoSubscription.NETWORK,
20879
+ AmityAutoSubscription.LIVESTREAM,
20880
+ AmityAutoSubscription.BLOCK,
20881
+ ];
20882
+ const ALL_FEATURES = Object.values(AmityAutoSubscription);
20883
+ /** Ref-counted, reconnect-resilient registry of the managed auto-subscriptions. */
20884
+ class AutoSubscriptionManager {
20885
+ constructor() {
20886
+ this.refCountByFeature = new Map();
20887
+ this.disposers = new Map();
20888
+ this.seed();
20889
+ }
20890
+ seed() {
20891
+ this.refCountByFeature.clear();
20892
+ DEFAULT_TOPICS.forEach(feature => this.refCountByFeature.set(feature, 1));
20893
+ }
20894
+ isActive(feature) {
20895
+ var _a;
20896
+ return ((_a = this.refCountByFeature.get(feature)) !== null && _a !== void 0 ? _a : 0) > 0;
20897
+ }
20898
+ subscribeTopics(feature) {
20899
+ this.unsubscribeTopics(feature);
20900
+ this.disposers.set(feature, TOPICS[feature].map(buildTopic => subscribeTopic(buildTopic())));
20901
+ }
20902
+ unsubscribeTopics(feature) {
20903
+ var _a;
20904
+ ((_a = this.disposers.get(feature)) !== null && _a !== void 0 ? _a : []).forEach(dispose => dispose());
20905
+ this.disposers.delete(feature);
20906
+ }
20907
+ /** Subscribe every enabled handle's topics, converging the broker to the registry. Called on each (re)connect. */
20908
+ initialize() {
20909
+ ALL_FEATURES.forEach(feature => {
20910
+ if (this.isActive(feature))
20911
+ this.subscribeTopics(feature);
20912
+ });
20913
+ }
20914
+ subscribe(feature) {
20915
+ var _a;
20916
+ const next = ((_a = this.refCountByFeature.get(feature)) !== null && _a !== void 0 ? _a : 0) + 1;
20917
+ this.refCountByFeature.set(feature, next);
20918
+ if (next === 1)
20919
+ this.subscribeTopics(feature);
20920
+ }
20921
+ unsubscribe(feature) {
20922
+ var _a;
20923
+ const next = Math.max(0, ((_a = this.refCountByFeature.get(feature)) !== null && _a !== void 0 ? _a : 0) - 1);
20924
+ this.refCountByFeature.set(feature, next);
20925
+ if (next === 0)
20926
+ this.unsubscribeTopics(feature);
20927
+ }
20928
+ subscriptions() {
20929
+ return ALL_FEATURES.map(feature => ({
20930
+ feature,
20931
+ isActive: this.isActive(feature),
20932
+ isSystem: true,
20933
+ topicCount: TOPICS[feature].length,
20934
+ }));
20935
+ }
20936
+ reset() {
20937
+ ALL_FEATURES.forEach(feature => this.unsubscribeTopics(feature));
20938
+ this.disposers.clear();
20939
+ this.seed();
20940
+ }
20941
+ }
20942
+ let instance$9 = null;
20943
+ const getAutoSubscriptionManager = () => {
20944
+ if (!instance$9)
20945
+ instance$9 = new AutoSubscriptionManager();
20946
+ return instance$9;
20947
+ };
20948
+ /** Resets the registry to its default baseline when the session ends. */
20949
+ const resetAutoSubscriptionsOnLogout = () => onSessionStateChange(state => {
20950
+ if (state !== "established" /* Amity.SessionStates.ESTABLISHED */)
20951
+ getAutoSubscriptionManager().reset();
20952
+ });
20953
+
20954
+ /**
20955
+ * (Re)subscribes the managed auto-subscription registry on every (re)connect.
20956
+ * The hardcoded topic list was promoted to the toggleable, ref-counted registry
20957
+ * in {@link getAutoSubscriptionManager} — see `client.manageAutoSubscriptions`.
20958
+ */
20728
20959
  const subscribeGlobalTopic = () => {
20729
- const disposers = [
20730
- subscribeTopic(getNetworkTopic()),
20731
- subscribeTopic(getSmartFeedChannelTopic()),
20732
- subscribeTopic(getSmartFeedSubChannelTopic()),
20733
- subscribeTopic(getSmartFeedMessageTopic()),
20734
- // subscribing to user topic is necessary to handle ban event
20735
- subscribeTopic(getUserTopic(getActiveUser())),
20736
- subscribeTopic(getMarkerUserFeedTopic()),
20737
- subscribeTopic(getLiveStreamTopic()),
20738
- ];
20739
- return () => disposers.forEach(fn => fn());
20960
+ getAutoSubscriptionManager().initialize();
20740
20961
  };
20741
20962
 
20742
20963
  class OnMemoryStorage {
@@ -21309,8 +21530,12 @@ const getChannelMessagePreviewWithUser = (channel) => {
21309
21530
  return Object.assign(Object.assign({}, channel), { messagePreview: messagePreviewWithUser });
21310
21531
  };
21311
21532
 
21533
+ const convertDateStringToTimestamp = (dateString) => {
21534
+ return new Date(dateString).getTime();
21535
+ };
21536
+
21312
21537
  const updateChannelMessagePreviewCache = (rawPayload) => {
21313
- var _a, _b;
21538
+ var _a;
21314
21539
  const withMessageFeedInfo = (messagePreview) => {
21315
21540
  var _a;
21316
21541
  const messageFeedInfo = (_a = rawPayload.messageFeedsInfo) === null || _a === void 0 ? void 0 : _a.find(messageFeed => {
@@ -21332,10 +21557,26 @@ const updateChannelMessagePreviewCache = (rawPayload) => {
21332
21557
  subChannelUpdatedAt: messageFeedInfo === null || messageFeedInfo === void 0 ? void 0 : messageFeedInfo.updatedAt,
21333
21558
  };
21334
21559
  };
21335
- const newData = {
21336
- messagePreviewChannel: (_b = (_a = rawPayload.messagePreviews) === null || _a === void 0 ? void 0 : _a.map(messagePreview => withMessageFeedInfo(messagePreview))) !== null && _b !== void 0 ? _b : [],
21337
- };
21338
- ingestInCache(newData);
21560
+ // Skip server previews older than what's cached — the cache may carry a newer
21561
+ // preview written by handleMessageCreated from an MQTT message that the server
21562
+ // payload hasn't surfaced yet. Mirrors isLastestMessageOnChannel.
21563
+ const newPreviews = ((_a = rawPayload.messagePreviews) !== null && _a !== void 0 ? _a : [])
21564
+ .map(withMessageFeedInfo)
21565
+ .filter(preview => {
21566
+ var _a;
21567
+ const cached = (_a = pullFromCache([
21568
+ 'messagePreviewChannel',
21569
+ 'get',
21570
+ preview.channelId,
21571
+ ])) === null || _a === void 0 ? void 0 : _a.data;
21572
+ if (!cached)
21573
+ return true;
21574
+ return (convertDateStringToTimestamp(cached.createdAt) <=
21575
+ convertDateStringToTimestamp(preview.createdAt));
21576
+ });
21577
+ if (newPreviews.length === 0)
21578
+ return;
21579
+ ingestInCache({ messagePreviewChannel: newPreviews });
21339
21580
  };
21340
21581
 
21341
21582
  const getSubChannelMessagePreview = (subChannelId) => {
@@ -21963,11 +22204,7 @@ getSubChannel$1.locally = (subChannelId) => {
21963
22204
  };
21964
22205
  };
21965
22206
 
21966
- const convertDateStringToTimestamp = (dateString) => {
21967
- return new Date(dateString).getTime();
21968
- };
21969
-
21970
- const getMessagePreviewSetting$1 = async () => {
22207
+ const getMessagePreviewSetting$2 = async () => {
21971
22208
  const client = getActiveClient();
21972
22209
  return client.getMessagePreviewSetting(false);
21973
22210
  };
@@ -22002,7 +22239,7 @@ const isLastestMessageOnChannel = (message) => {
22002
22239
  convertDateStringToTimestamp(cache.createdAt) <= convertDateStringToTimestamp(message.createdAt));
22003
22240
  };
22004
22241
  const handleMessageCreatedOnSubChannel = async (message) => {
22005
- const messagePreviewSetting = await getMessagePreviewSetting$1();
22242
+ const messagePreviewSetting = await getMessagePreviewSetting$2();
22006
22243
  const { channelId, messageId: messagePreviewId, creatorId, createdAt, updatedAt, data, dataType, subChannelId, channelSegment: segment, isDeleted, } = message;
22007
22244
  // 1. get subChannel from cache, if not exist fetch from server
22008
22245
  const subChannelCache = await getSubChannelCache(subChannelId);
@@ -22174,24 +22411,41 @@ const preUpdateChannelCache = (rawPayload, options = { isMessagePreviewUpdated:
22174
22411
  });
22175
22412
  };
22176
22413
  const updateChannelUnread = ({ currentUserId, channels, channelUsers, }) => {
22414
+ var _a, _b;
22177
22415
  const channelsUnread = [];
22178
22416
  for (let i = 0; i < channels.length; i += 1) {
22179
22417
  if (isUnreadCountSupport(channels[i])) {
22180
22418
  const cacheKey = ['channelUnread', 'get', channels[i].channelId];
22181
22419
  const channelUser = channelUsers.find(channelUser => channelUser.channelId === channels[i].channelId && channelUser.userId === currentUserId);
22182
- let unreadCount = 0;
22420
+ // readToSegment, lastMentionedSegment and lastSegment are monotonically non-decreasing;
22421
+ // prefer cached values when ahead of the server so a refetch returning stale data cannot
22422
+ const cached = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
22423
+ const lastSegment = Math.max((_b = cached === null || cached === void 0 ? void 0 : cached.lastSegment) !== null && _b !== void 0 ? _b : 0, channels[i].messageCount);
22183
22424
  let readToSegment = null;
22184
22425
  let lastMentionedSegment = null;
22426
+ let unreadCount = 0;
22185
22427
  let isMentioned = false;
22186
22428
  if (channelUser) {
22187
- readToSegment = channelUser.readToSegment;
22188
- lastMentionedSegment = channelUser.lastMentionedSegment;
22189
- unreadCount = Math.max(channels[i].messageCount - readToSegment, 0);
22190
- isMentioned = lastMentionedSegment > readToSegment;
22429
+ const serverRead = channelUser.readToSegment;
22430
+ const serverMention = channelUser.lastMentionedSegment;
22431
+ readToSegment =
22432
+ typeof (cached === null || cached === void 0 ? void 0 : cached.readToSegment) === 'number' &&
22433
+ (typeof serverRead !== 'number' || cached.readToSegment > serverRead)
22434
+ ? cached.readToSegment
22435
+ : serverRead !== null && serverRead !== void 0 ? serverRead : null;
22436
+ lastMentionedSegment =
22437
+ typeof (cached === null || cached === void 0 ? void 0 : cached.lastMentionedSegment) === 'number' &&
22438
+ (typeof serverMention !== 'number' || cached.lastMentionedSegment > serverMention)
22439
+ ? cached.lastMentionedSegment
22440
+ : serverMention !== null && serverMention !== void 0 ? serverMention : null;
22441
+ const readForCalc = readToSegment !== null && readToSegment !== void 0 ? readToSegment : 0;
22442
+ unreadCount = Math.max(lastSegment - readForCalc, 0);
22443
+ isMentioned =
22444
+ typeof lastMentionedSegment === 'number' && readForCalc < lastMentionedSegment;
22191
22445
  }
22192
22446
  const cacheChannelUnread = {
22193
22447
  channelId: channels[i].channelId,
22194
- lastSegment: channels[i].messageCount,
22448
+ lastSegment,
22195
22449
  readToSegment,
22196
22450
  lastMentionedSegment,
22197
22451
  unreadCount,
@@ -22201,6 +22455,8 @@ const updateChannelUnread = ({ currentUserId, channels, channelUsers, }) => {
22201
22455
  pushToCache(cacheKey, cacheChannelUnread);
22202
22456
  channelsUnread.push(cacheChannelUnread);
22203
22457
  }
22458
+ }
22459
+ if (channelsUnread.length > 0) {
22204
22460
  fireEvent('local.channelUnread.updated', channelsUnread);
22205
22461
  }
22206
22462
  };
@@ -22900,7 +23156,7 @@ const onChannelMemberRoleRemoved = (callback) => {
22900
23156
  const client = getActiveClient();
22901
23157
  const filter = async (payload) => {
22902
23158
  const { channels, channelUsers } = payload;
22903
- callback(channels[0], channelUsers.find(channelUser => channelUser.membership === 'member'));
23159
+ callbacks$1.forEach(cb => cb(channels[0], channelUsers.find(channelUser => channelUser.membership === 'member')));
22904
23160
  };
22905
23161
  mainDisposer$1 = createEventSubscriber(client, 'onChannelMemberRoleRemoved', 'local.channel-moderator.role-removed', filter);
22906
23162
  }
@@ -22908,6 +23164,39 @@ const onChannelMemberRoleRemoved = (callback) => {
22908
23164
  return () => dispose$1(callback);
22909
23165
  };
22910
23166
 
23167
+ /**
23168
+ * Fired when a {@link Amity.Channel} has been archived by the active user.
23169
+ *
23170
+ * @param callback The function to call when the event was fired
23171
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
23172
+ *
23173
+ * @category Channel Events
23174
+ */
23175
+ const onChannelArchived = (callback) => {
23176
+ const client = getActiveClient();
23177
+ const filter = async (payload) => {
23178
+ callback(payload);
23179
+ };
23180
+ return createEventSubscriber(client, 'onChannelArchived', 'local.channel.archived', filter);
23181
+ };
23182
+
23183
+ /**
23184
+ * Fired when a previously archived {@link Amity.Channel} has been unarchived
23185
+ * by the active user.
23186
+ *
23187
+ * @param callback The function to call when the event was fired
23188
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
23189
+ *
23190
+ * @category Channel Events
23191
+ */
23192
+ const onChannelUnarchived = (callback) => {
23193
+ const client = getActiveClient();
23194
+ const filter = async (payload) => {
23195
+ callback(payload);
23196
+ };
23197
+ return createEventSubscriber(client, 'onChannelUnarchived', 'local.channel.unarchived', filter);
23198
+ };
23199
+
22911
23200
  const callbacks = [];
22912
23201
  let mainDisposer = null;
22913
23202
  const dispose = (cb) => {
@@ -23021,6 +23310,17 @@ const channelLinkedObject = (channel) => {
23021
23310
  markAsRead: () => markAsRead(channel.channelInternalId),
23022
23311
  previewMembers,
23023
23312
  myMembership: (callback) => getMyMembership(channel.channelId, callback),
23313
+ get avatar() {
23314
+ var _a;
23315
+ if (!channel.avatarFileId)
23316
+ return undefined;
23317
+ const avatar = (_a = pullFromCache([
23318
+ 'file',
23319
+ 'get',
23320
+ `${channel.avatarFileId}`,
23321
+ ])) === null || _a === void 0 ? void 0 : _a.data;
23322
+ return avatar;
23323
+ },
23024
23324
  });
23025
23325
  };
23026
23326
 
@@ -23119,54 +23419,6 @@ getChannelByIds$1.locally = (channelIds) => {
23119
23419
  };
23120
23420
  };
23121
23421
 
23122
- class SessionWatcher {
23123
- constructor() {
23124
- this._sessionState = "notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */;
23125
- this._listener = new Map();
23126
- }
23127
- onSessionStateChange(callback) {
23128
- this._listener.set(callback, callback);
23129
- return () => {
23130
- this._listener.delete(callback);
23131
- };
23132
- }
23133
- setSessionState(state, reason) {
23134
- if (this._sessionState === state)
23135
- return;
23136
- this._sessionState = state;
23137
- this._listener.forEach(cb => cb(state, reason));
23138
- }
23139
- destroy() {
23140
- this._listener.clear();
23141
- }
23142
- }
23143
- let instance$8;
23144
- var SessionWatcher$1 = {
23145
- getInstance: () => {
23146
- if (!instance$8) {
23147
- instance$8 = new SessionWatcher();
23148
- }
23149
- return instance$8;
23150
- },
23151
- };
23152
-
23153
- /**
23154
- * ```js
23155
- * import { onSessionStateChange } from '@amityco/ts-sdk-react-native'
23156
- * const dispose = onSessionStateChange((state: Amity.SessionStates) => {
23157
- * // ...
23158
- * })
23159
- * ```
23160
- *
23161
- * Fired when any {@link Amity.Client} has a session state change
23162
- *
23163
- * @param callback The function to call when the event was fired
23164
- * @returns an {@link Amity.Unsubscriber} function to stop listening
23165
- *
23166
- * @category Client Events
23167
- */
23168
- const onSessionStateChange = (callback) => SessionWatcher$1.getInstance().onSessionStateChange(callback);
23169
-
23170
23422
  const setIntervalTask = (handler, timeout) => {
23171
23423
  const timer = setInterval(handler, timeout);
23172
23424
  return () => clearInterval(timer);
@@ -23338,7 +23590,7 @@ const convertMessagePreviewSetting = (chatSetting) => {
23338
23590
  * @category private
23339
23591
  * @async
23340
23592
  */
23341
- const getMessagePreviewSetting = async (refresh = true) => {
23593
+ const getMessagePreviewSetting$1 = async (refresh = true) => {
23342
23594
  var _a;
23343
23595
  const messagePreviewSetting = (_a = pullFromCache([
23344
23596
  'MessagePreviewSetting',
@@ -23359,7 +23611,7 @@ const getMessagePreviewSetting = async (refresh = true) => {
23359
23611
  */
23360
23612
  const initializeMessagePreviewSetting = async () => {
23361
23613
  var _a;
23362
- const newMessagePreviewSetting = await getMessagePreviewSetting();
23614
+ const newMessagePreviewSetting = await getMessagePreviewSetting$1();
23363
23615
  const messagePreviewSetting = (_a = pullFromCache([
23364
23616
  'MessagePreviewSetting',
23365
23617
  ])) === null || _a === void 0 ? void 0 : _a.data;
@@ -23430,6 +23682,26 @@ const getSocialSettings = async () => {
23430
23682
  return data.socialNetworkSetting;
23431
23683
  };
23432
23684
 
23685
+ /**
23686
+ * ```js
23687
+ * import { createClient } from '@amityco/ts-sdk'
23688
+ * const client = createClient(apiKey, apiRegion)
23689
+ * const userSettings = await client.getCoreUserSettings()
23690
+ * ```
23691
+ *
23692
+ * Fetches a {@link Amity.CoreUserSettings} object
23693
+ *
23694
+ * @returns A Promise of {@link Amity.CoreUserSettings} object
23695
+ *
23696
+ * @category Client API
23697
+ * @async
23698
+ */
23699
+ const getCoreUserSettings = async () => {
23700
+ const client = getActiveClient();
23701
+ const { data } = await client.http.get(`/api/v3/network-settings/users`);
23702
+ return data;
23703
+ };
23704
+
23433
23705
  /* begin_public_function
23434
23706
  id: client.getProductCatalogueSetting
23435
23707
  */
@@ -23453,6 +23725,33 @@ const getProductCatalogueSetting = async () => {
23453
23725
  };
23454
23726
  /* end_public_function */
23455
23727
 
23728
+ /* begin_public_function
23729
+ id: client.getForYouFeedSetting
23730
+ */
23731
+ /**
23732
+ * ```js
23733
+ * import { Client } from '@amityco/ts-sdk'
23734
+ * const forYouFeedSetting = await Client.getForYouFeedSetting()
23735
+ * ```
23736
+ *
23737
+ * Fetches the network-level {@link Amity.ForYouFeedSetting} — whether the For You
23738
+ * feed feature is enabled for the current network. Use `forYouFeed.enabled` as a
23739
+ * feature gate before querying {@link getForYouFeed}.
23740
+ *
23741
+ * @returns A Promise of {@link Amity.ForYouFeedSetting} object
23742
+ *
23743
+ * @category Client API
23744
+ * @async
23745
+ */
23746
+ const getForYouFeedSetting = async () => {
23747
+ var _a, _b;
23748
+ const client = getActiveClient();
23749
+ const { data } = await client.http.get(`/api/v3/network-settings/for-you-feed`);
23750
+ // Surface only `enabled`; ignore server-side ranking config (scoringConfig, etc.)
23751
+ return { forYouFeed: { enabled: (_b = (_a = data.forYouFeed) === null || _a === void 0 ? void 0 : _a.enabled) !== null && _b !== void 0 ? _b : false } };
23752
+ };
23753
+ /* end_public_function */
23754
+
23456
23755
  const checkUserPermission = (userId, permission) => {
23457
23756
  var _a;
23458
23757
  const user = (_a = pullFromCache(['user', 'get', userId])) === null || _a === void 0 ? void 0 : _a.data;
@@ -23960,7 +24259,7 @@ class AnalyticsEventSyncer {
23960
24259
 
23961
24260
  class AnalyticsEventCapturer {
23962
24261
  constructor() {
23963
- this._expireTime = 5 * MINUTE;
24262
+ this._expireTime = 5 * SECOND$1;
23964
24263
  this._poolLimit = 1000;
23965
24264
  this._recentViewed = {};
23966
24265
  this._recentHighPriorityViewed = {};
@@ -24014,12 +24313,36 @@ class AnalyticsEventCapturer {
24014
24313
  }
24015
24314
  markPostAsViewed(postId) {
24016
24315
  this.markAs({
24017
- uniqueId: postId,
24316
+ uniqueId: `post.${postId}`,
24018
24317
  contentId: postId,
24019
24318
  contentType: "post" /* Amity.AnalyticEventContentType.Post */,
24020
24319
  activityType: "view" /* Amity.AnalyticEventActivityType.View */,
24021
24320
  });
24022
24321
  }
24322
+ markPostAsMeaningfullyViewed(postId, feedRenderPosition) {
24323
+ var _a;
24324
+ const cached = (_a = pullFromCache(['feedMetadata', 'get', postId])) === null || _a === void 0 ? void 0 : _a.data;
24325
+ const metadata = {};
24326
+ if (feedRenderPosition !== undefined)
24327
+ metadata.feedRenderPosition = feedRenderPosition;
24328
+ if (cached) {
24329
+ metadata.feedSnapshotPosition = cached.feedSnapshotPosition;
24330
+ metadata.feedInjectionType = cached.feedInjectionType;
24331
+ metadata.feedRelevanceScore = cached.feedRelevanceScore;
24332
+ metadata.feedPopularityScore = cached.feedPopularityScore;
24333
+ metadata.feedFreshnessScore = cached.feedFreshnessScore;
24334
+ metadata.feedAffinityScore = cached.feedAffinityScore;
24335
+ metadata.feedFinalScore = cached.feedFinalScore;
24336
+ metadata.feedMmrPenalty = cached.feedMmrPenalty;
24337
+ }
24338
+ this.markAs({
24339
+ uniqueId: `post.${postId}.meaningfulView`,
24340
+ contentId: postId,
24341
+ contentType: "post" /* Amity.AnalyticEventContentType.Post */,
24342
+ activityType: "meaningfulView" /* Amity.AnalyticEventActivityType.MeaningfulView */,
24343
+ metadata: Object.keys(metadata).length > 0 ? metadata : undefined,
24344
+ });
24345
+ }
24023
24346
  markStory(story, activityType) {
24024
24347
  if (!story.expiresAt)
24025
24348
  return;
@@ -24159,6 +24482,12 @@ class AnalyticsEngine {
24159
24482
  this._eventCapturer.markPostAsViewed(postId);
24160
24483
  }
24161
24484
  }
24485
+ markPostAsMeaningfullyViewed(postId, feedRenderPosition) {
24486
+ if (this._client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */ ||
24487
+ this._client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */) {
24488
+ this._eventCapturer.markPostAsMeaningfullyViewed(postId, feedRenderPosition);
24489
+ }
24490
+ }
24162
24491
  markStoryAsViewed(story) {
24163
24492
  if (this._client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */ ||
24164
24493
  this._client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ // For case token_expired, we assume token is expired and gonna re-connect soon
@@ -24210,13 +24539,13 @@ class AnalyticsEngine {
24210
24539
  this._eventCapturer.resetAllBuckets();
24211
24540
  }
24212
24541
  }
24213
- let instance$7;
24542
+ let instance$8;
24214
24543
  var AnalyticsEngine$1 = {
24215
24544
  getInstance: () => {
24216
- if (!instance$7) {
24217
- instance$7 = new AnalyticsEngine();
24545
+ if (!instance$8) {
24546
+ instance$8 = new AnalyticsEngine();
24218
24547
  }
24219
- return instance$7;
24548
+ return instance$8;
24220
24549
  },
24221
24550
  };
24222
24551
 
@@ -24383,9 +24712,8 @@ class MessageReadReceiptSyncEngine {
24383
24712
  // Step 1: Optimistic update of channelUnread.readToSegment to message.segment and update unreadCount value
24384
24713
  const cacheKey = ['channelUnread', 'get', channelId];
24385
24714
  const channelUnread = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
24386
- if (typeof (channelUnread === null || channelUnread === void 0 ? void 0 : channelUnread.readToSegment) === 'number' &&
24387
- channelUnread &&
24388
- segment > channelUnread.readToSegment) {
24715
+ if (channelUnread &&
24716
+ (typeof channelUnread.readToSegment !== 'number' || segment > channelUnread.readToSegment)) {
24389
24717
  channelUnread.readToSegment = segment;
24390
24718
  channelUnread.unreadCount = Math.max(channelUnread.lastSegment - segment, 0);
24391
24719
  pushToCache(cacheKey, channelUnread);
@@ -24444,12 +24772,12 @@ class MessageReadReceiptSyncEngine {
24444
24772
  }
24445
24773
  }
24446
24774
  }
24447
- let instance$6 = null;
24775
+ let instance$7 = null;
24448
24776
  var ReadReceiptSyncEngine = {
24449
24777
  getInstance: () => {
24450
- if (!instance$6)
24451
- instance$6 = new MessageReadReceiptSyncEngine();
24452
- return instance$6;
24778
+ if (!instance$7)
24779
+ instance$7 = new MessageReadReceiptSyncEngine();
24780
+ return instance$7;
24453
24781
  },
24454
24782
  };
24455
24783
 
@@ -24703,12 +25031,12 @@ class LegacyMessageReadReceiptSyncEngine {
24703
25031
  }
24704
25032
  }
24705
25033
  }
24706
- let instance$5 = null;
25034
+ let instance$6 = null;
24707
25035
  var LegacyReadReceiptSyncEngine = {
24708
25036
  getInstance: () => {
24709
- if (!instance$5)
24710
- instance$5 = new LegacyMessageReadReceiptSyncEngine();
24711
- return instance$5;
25037
+ if (!instance$6)
25038
+ instance$6 = new LegacyMessageReadReceiptSyncEngine();
25039
+ return instance$6;
24712
25040
  },
24713
25041
  };
24714
25042
 
@@ -24984,12 +25312,12 @@ class ObjectResolverEngine {
24984
25312
  this.stopResolver();
24985
25313
  }
24986
25314
  }
24987
- let instance$4 = null;
25315
+ let instance$5 = null;
24988
25316
  var ObjectResolverEngine$1 = {
24989
25317
  getInstance: () => {
24990
- if (!instance$4)
24991
- instance$4 = new ObjectResolverEngine();
24992
- return instance$4;
25318
+ if (!instance$5)
25319
+ instance$5 = new ObjectResolverEngine();
25320
+ return instance$5;
24993
25321
  },
24994
25322
  };
24995
25323
 
@@ -25139,13 +25467,13 @@ class LiveReactionSyncEngine {
25139
25467
  this.stopReactionsSync();
25140
25468
  }
25141
25469
  }
25142
- let instance$3;
25470
+ let instance$4;
25143
25471
  var ReactionSyncEngine = {
25144
25472
  getInstance: () => {
25145
- if (!instance$3) {
25146
- instance$3 = new LiveReactionSyncEngine();
25473
+ if (!instance$4) {
25474
+ instance$4 = new LiveReactionSyncEngine();
25147
25475
  }
25148
- return instance$3;
25476
+ return instance$4;
25149
25477
  },
25150
25478
  };
25151
25479
 
@@ -25175,19 +25503,20 @@ function prepareBlockedUserPayload(response) {
25175
25503
  }), users: users.map(convertRawUserToInternalUser) });
25176
25504
  }
25177
25505
 
25178
- const BLOCK_LIST_LIMIT = 100;
25179
- const TTL_MS = 5 * 60 * 1000; // 5 minutes
25506
+ const BLOCK_LIST_LIMIT$1 = 100;
25507
+ const TTL_MS$1 = 5 * 60 * 1000; // 5 minutes
25180
25508
  /**
25181
25509
  * Session-scoped singleton engine that manages TTL-based fetching and caching
25182
25510
  * of blocked users. Provides a lazy `ensureFetched()` gate for the
25183
25511
  * `getAllBlockedUsers()` API.
25184
25512
  *
25185
25513
  * Key behaviours:
25186
- * - `establish()` is a no-op — fetch is lazy, triggered only by consumer call
25187
- * - `destroy()` resets `lastFetchedAt` to null (ensures fresh fetch on next session)
25514
+ * - `onSessionEstablished()` is a no-op — fetch is lazy, triggered only by consumer call
25515
+ * - `onSessionDestroyed()` resets `lastFetchedAt` to null (ensures fresh fetch on next session)
25188
25516
  * - `ensureFetched()` fetches from server only when cache is expired or never fetched
25189
25517
  * - `lastFetchedAt` is only updated on successful fetch
25190
- * - `blockedUserIds` is kept in sync with each successful fetch
25518
+ * - reads query the follow cache live, so block/unblock changes are reflected
25519
+ * even within the TTL window
25191
25520
  *
25192
25521
  * @internal
25193
25522
  */
@@ -25195,12 +25524,7 @@ class BlockedUserSyncEngine {
25195
25524
  constructor() {
25196
25525
  /** Epoch ms of last successful fetch. null = never fetched in this session. */
25197
25526
  this.lastFetchedAt = null;
25198
- /** Ordered list of userId strings from the most recent successful fetch. */
25199
- this.blockedUserIds = [];
25200
25527
  }
25201
- // ---------------------------------------------------------------------------
25202
- // SessionComponent lifecycle
25203
- // ---------------------------------------------------------------------------
25204
25528
  /** No-op — fetch is lazy, triggered by consumer calling getAllBlockedUsers(). */
25205
25529
  // eslint-disable-next-line class-methods-use-this
25206
25530
  onSessionEstablished() {
@@ -25209,24 +25533,17 @@ class BlockedUserSyncEngine {
25209
25533
  /** Resets state so the next session starts with a cold cache. */
25210
25534
  onSessionDestroyed() {
25211
25535
  this.lastFetchedAt = null;
25212
- this.blockedUserIds = [];
25213
25536
  }
25214
25537
  /** No-op for this engine. */
25215
25538
  // eslint-disable-next-line class-methods-use-this
25216
25539
  onTokenExpired() {
25217
25540
  // intentionally empty
25218
25541
  }
25219
- // ---------------------------------------------------------------------------
25220
- // Cache helpers
25221
- // ---------------------------------------------------------------------------
25222
25542
  isCacheExpired() {
25223
25543
  if (this.lastFetchedAt === null)
25224
25544
  return true;
25225
- return Date.now() - this.lastFetchedAt > TTL_MS;
25545
+ return Date.now() - this.lastFetchedAt > TTL_MS$1;
25226
25546
  }
25227
- // ---------------------------------------------------------------------------
25228
- // Core fetch gate
25229
- // ---------------------------------------------------------------------------
25230
25547
  /**
25231
25548
  * Ensures the local store is populated with fresh blocked-user data.
25232
25549
  *
@@ -25242,52 +25559,50 @@ class BlockedUserSyncEngine {
25242
25559
  if (!this.isCacheExpired())
25243
25560
  return;
25244
25561
  const client = getActiveClient();
25245
- const { data } = await client.http.get('/api/v4/me/user-blocks', { params: { options: { limit: BLOCK_LIST_LIMIT }, isDeleted: false } });
25562
+ const { data } = await client.http.get('/api/v4/me/user-blocks', { params: { options: { limit: BLOCK_LIST_LIMIT$1 }, isDeleted: false } });
25246
25563
  const cachedAt = client.cache && Date.now();
25247
25564
  const payload = prepareBlockedUserPayload(data);
25248
25565
  if (client.cache) {
25249
25566
  ingestInCache(payload, { cachedAt });
25250
25567
  }
25251
- // Keep the ordered list of blocked user IDs for getCachedUsers()
25252
- this.blockedUserIds = payload.users.map(u => u.userId);
25253
25568
  // Only update timestamp on success — failure leaves it unchanged so the
25254
25569
  // next call retries.
25255
25570
  this.lastFetchedAt = Date.now();
25256
25571
  }
25257
- // ---------------------------------------------------------------------------
25258
- // Local store read
25259
- // ---------------------------------------------------------------------------
25260
25572
  /**
25261
- * Returns blocked {@link Amity.InternalUser} objects from the in-memory cache.
25262
- *
25263
- * Applies the spec-mandated filter:
25264
- * - Only users whose `isDeleted` is false or null
25265
- * - Hard limit of 100 results
25573
+ * Returns the blocked users by querying the follow cache live — the outgoing
25574
+ * direction (`from === me`, `status === 'blocked'`). Reading the cache (not a
25575
+ * fetched snapshot) means `blockUser()` / `unblockUser()` changes are reflected
25576
+ * even within the TTL window.
25266
25577
  *
25267
- * This always reads the latest local state, so changes made by `blockUser()`
25268
- * and `unblockUser()` are reflected even within the TTL window.
25578
+ * Applies the spec-mandated query:
25579
+ * - filter `from === currentUserId`, `status === 'blocked'`, blocked user not deleted
25580
+ * - sort by `updatedAt` DESC
25581
+ * - hard limit of 100 results
25269
25582
  */
25583
+ // eslint-disable-next-line class-methods-use-this
25270
25584
  getCachedUsers() {
25585
+ var _a;
25271
25586
  const client = getActiveClient();
25272
- if (!client.cache) {
25273
- // No cache available — fall back to the in-memory list from the last fetch
25587
+ if (!client.cache)
25274
25588
  return [];
25275
- }
25276
- return this.blockedUserIds
25277
- .map(id => { var _a; return (_a = pullFromCache(['user', 'get', id])) === null || _a === void 0 ? void 0 : _a.data; })
25589
+ const { userId } = client;
25590
+ return ((_a = queryCache(['follow', 'get'])) !== null && _a !== void 0 ? _a : [])
25591
+ .map(entry => entry.data)
25592
+ .filter(follow => (follow === null || follow === void 0 ? void 0 : follow.status) === 'blocked' && follow.from === userId)
25593
+ .sort((a, b) => { var _a, _b; return (((_a = a.updatedAt) !== null && _a !== void 0 ? _a : '') < ((_b = b.updatedAt) !== null && _b !== void 0 ? _b : '') ? 1 : -1); })
25594
+ .map(follow => { var _a; return (_a = pullFromCache(['user', 'get', follow.to])) === null || _a === void 0 ? void 0 : _a.data; })
25278
25595
  .filter((user) => user != null && user.isDeleted !== true)
25279
- .slice(0, BLOCK_LIST_LIMIT);
25596
+ .slice(0, BLOCK_LIST_LIMIT$1)
25597
+ .map(userLinkedObject);
25280
25598
  }
25281
25599
  }
25282
- // ---------------------------------------------------------------------------
25283
- // Module-level singleton
25284
- // ---------------------------------------------------------------------------
25285
- let instance$2 = null;
25600
+ let instance$3 = null;
25286
25601
  var BlockedUserSyncEngine$1 = {
25287
25602
  getInstance: () => {
25288
- if (!instance$2)
25289
- instance$2 = new BlockedUserSyncEngine();
25290
- return instance$2;
25603
+ if (!instance$3)
25604
+ instance$3 = new BlockedUserSyncEngine();
25605
+ return instance$3;
25291
25606
  },
25292
25607
  };
25293
25608
 
@@ -25309,6 +25624,290 @@ var blockedUserSyncEngineOnLoginHandler = () => {
25309
25624
  };
25310
25625
  };
25311
25626
 
25627
+ function prepareBlockingUserPayload(response) {
25628
+ const { users, follows } = response, rest = __rest(response, ["users", "follows"]);
25629
+ return Object.assign(Object.assign({}, rest), { follows: follows.map(follow => {
25630
+ const followUser = users.find(user => user.userId === follow.from);
25631
+ return Object.assign(Object.assign({}, follow), { user: convertRawUserToInternalUser(followUser) });
25632
+ }), users: users.map(convertRawUserToInternalUser) });
25633
+ }
25634
+
25635
+ const BLOCK_LIST_LIMIT = 100;
25636
+ const TTL_MS = 5 * 60 * 1000; // 5 minutes
25637
+ /**
25638
+ * Session-scoped singleton engine that manages TTL-based fetching and caching
25639
+ * of blocking users (the "blocked-by" list — users who blocked the current
25640
+ * user). Provides a lazy `ensureFetched()` gate for the `getAllBlockingUsers()`
25641
+ * API. Directional inverse of {@link BlockedUserSyncEngine}.
25642
+ *
25643
+ * Key behaviours:
25644
+ * - `onSessionEstablished()` is a no-op — fetch is lazy, triggered only by consumer call
25645
+ * - `onSessionDestroyed()` resets `lastFetchedAt` to null (ensures fresh fetch on next session)
25646
+ * - `ensureFetched()` fetches from server only when cache is expired or never fetched
25647
+ * - `lastFetchedAt` is only updated on successful fetch
25648
+ * - reads query the follow cache live, so block/unblock changes are reflected
25649
+ * even within the TTL window
25650
+ *
25651
+ * @internal
25652
+ */
25653
+ class BlockingUserSyncEngine {
25654
+ constructor() {
25655
+ /** Epoch ms of last successful fetch. null = never fetched in this session. */
25656
+ this.lastFetchedAt = null;
25657
+ }
25658
+ /** No-op — fetch is lazy, triggered by consumer calling getAllBlockingUsers(). */
25659
+ // eslint-disable-next-line class-methods-use-this
25660
+ onSessionEstablished() {
25661
+ // intentionally empty
25662
+ }
25663
+ /** Resets state so the next session starts with a cold cache. */
25664
+ onSessionDestroyed() {
25665
+ this.lastFetchedAt = null;
25666
+ }
25667
+ /** No-op for this engine. */
25668
+ // eslint-disable-next-line class-methods-use-this
25669
+ onTokenExpired() {
25670
+ // intentionally empty
25671
+ }
25672
+ isCacheExpired() {
25673
+ if (this.lastFetchedAt === null)
25674
+ return true;
25675
+ return Date.now() - this.lastFetchedAt > TTL_MS;
25676
+ }
25677
+ /**
25678
+ * Ensures the local store is populated with fresh blocking-user data.
25679
+ *
25680
+ * - If the cache is still within the 5-minute TTL window: resolves immediately
25681
+ * (no server call).
25682
+ * - If the cache is expired (or never fetched): fetches from the server,
25683
+ * persists the payload to the cache, and updates `lastFetchedAt`.
25684
+ *
25685
+ * On failure the error propagates to the caller and `lastFetchedAt` is NOT
25686
+ * updated, so the next call will retry.
25687
+ */
25688
+ async ensureFetched() {
25689
+ if (!this.isCacheExpired())
25690
+ return;
25691
+ const client = getActiveClient();
25692
+ const { data } = await client.http.get('/api/v4/me/blockers', { params: { options: { limit: BLOCK_LIST_LIMIT }, isDeleted: false } });
25693
+ const cachedAt = client.cache && Date.now();
25694
+ const payload = prepareBlockingUserPayload(data);
25695
+ if (client.cache) {
25696
+ ingestInCache(payload, { cachedAt });
25697
+ }
25698
+ // Only update timestamp on success — failure leaves it unchanged so the
25699
+ // next call retries.
25700
+ this.lastFetchedAt = Date.now();
25701
+ }
25702
+ /**
25703
+ * Returns the "blocked-by" users by querying the follow cache live — the
25704
+ * incoming direction (`to === me`, `status === 'blocked'`). Reading the cache
25705
+ * (not a fetched snapshot) means RTE `user.didBlock` / `user.didUnblock`
25706
+ * changes are reflected even within the TTL window.
25707
+ *
25708
+ * Applies the spec-mandated query (REQ-012/013/014):
25709
+ * - filter `to === currentUserId`, `status === 'blocked'`, blocker not deleted
25710
+ * - sort by `updatedAt` DESC
25711
+ * - hard limit of 100 results
25712
+ */
25713
+ // eslint-disable-next-line class-methods-use-this
25714
+ getCachedUsers() {
25715
+ var _a;
25716
+ const client = getActiveClient();
25717
+ if (!client.cache)
25718
+ return [];
25719
+ const { userId } = client;
25720
+ return ((_a = queryCache(['follow', 'get'])) !== null && _a !== void 0 ? _a : [])
25721
+ .map(entry => entry.data)
25722
+ .filter(follow => (follow === null || follow === void 0 ? void 0 : follow.status) === 'blocked' && follow.to === userId)
25723
+ .sort((a, b) => { var _a, _b; return (((_a = a.updatedAt) !== null && _a !== void 0 ? _a : '') < ((_b = b.updatedAt) !== null && _b !== void 0 ? _b : '') ? 1 : -1); })
25724
+ .map(follow => { var _a; return (_a = pullFromCache(['user', 'get', follow.from])) === null || _a === void 0 ? void 0 : _a.data; })
25725
+ .filter((user) => user != null && user.isDeleted !== true)
25726
+ .slice(0, BLOCK_LIST_LIMIT)
25727
+ .map(userLinkedObject);
25728
+ }
25729
+ }
25730
+ let instance$2 = null;
25731
+ var BlockingUserSyncEngine$1 = {
25732
+ getInstance: () => {
25733
+ if (!instance$2)
25734
+ instance$2 = new BlockingUserSyncEngine();
25735
+ return instance$2;
25736
+ },
25737
+ };
25738
+
25739
+ var blockingUserSyncEngineOnLoginHandler = () => {
25740
+ const blockingUserSyncEngine = BlockingUserSyncEngine$1.getInstance();
25741
+ onSessionStateChange(state => {
25742
+ if (state === "established" /* Amity.SessionStates.ESTABLISHED */) {
25743
+ blockingUserSyncEngine.onSessionEstablished();
25744
+ }
25745
+ else if (state === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */) {
25746
+ blockingUserSyncEngine.onTokenExpired();
25747
+ }
25748
+ else {
25749
+ blockingUserSyncEngine.onSessionDestroyed();
25750
+ }
25751
+ });
25752
+ return () => {
25753
+ blockingUserSyncEngine.onSessionDestroyed();
25754
+ };
25755
+ };
25756
+
25757
+ function prepareFollowersPayload(response) {
25758
+ const { users, follows } = response, rest = __rest(response, ["users", "follows"]);
25759
+ return Object.assign(Object.assign({}, rest), { follows, users: users.map(convertRawUserToInternalUser) });
25760
+ }
25761
+ function prepareFollowingsPayload(response) {
25762
+ const { users, follows } = response, rest = __rest(response, ["users", "follows"]);
25763
+ return Object.assign(Object.assign({}, rest), { follows, users: users.map(convertRawUserToInternalUser) });
25764
+ }
25765
+ function prepareFollowStatusPayload(response) {
25766
+ const { follows } = response, rest = __rest(response, ["follows"]);
25767
+ return Object.assign(Object.assign({}, rest), { follows });
25768
+ }
25769
+
25770
+ /**
25771
+ * Subscribes to a block MQTT event (`user.didBlock` / `user.didUnblock`),
25772
+ * ingests the carried `FollowersPayload` (follows + users) into the cache so
25773
+ * the block-relationship rows (`['follow', 'get', from#to]`) and user rows are
25774
+ * kept current, then forwards the affected {@link Amity.FollowStatus} to the
25775
+ * caller.
25776
+ *
25777
+ * @hidden
25778
+ */
25779
+ const createBlockEventSubscriber = (event, callback) => {
25780
+ const client = getActiveClient();
25781
+ const filter = (data) => {
25782
+ const payload = prepareFollowersPayload(data);
25783
+ if (client.cache) {
25784
+ ingestInCache(payload);
25785
+ }
25786
+ callback(payload.follows[0]);
25787
+ };
25788
+ return createEventSubscriber(client, event, event, filter);
25789
+ };
25790
+
25791
+ /**
25792
+ * ```js
25793
+ * import { onUserDidBlock } from '@amityco/ts-sdk'
25794
+ * const dispose = onUserDidBlock(status => {
25795
+ * // ...
25796
+ * })
25797
+ * ```
25798
+ *
25799
+ * Fired when a block relationship is created in real time — either a user
25800
+ * blocks the current user (incoming) or the current user blocks someone on
25801
+ * another device (outgoing). The local block-relationship store is updated
25802
+ * before the callback runs.
25803
+ *
25804
+ * @param callback The function to call when the event was fired
25805
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
25806
+ *
25807
+ * @category Block Events
25808
+ */
25809
+ const onUserDidBlock = (callback) => createBlockEventSubscriber('user.didBlock', callback);
25810
+
25811
+ /**
25812
+ * ```js
25813
+ * import { onUserDidUnblock } from '@amityco/ts-sdk'
25814
+ * const dispose = onUserDidUnblock(status => {
25815
+ * // ...
25816
+ * })
25817
+ * ```
25818
+ *
25819
+ * Fired when a block relationship is removed in real time — either a user
25820
+ * unblocks the current user (incoming) or the current user unblocks someone on
25821
+ * another device (outgoing). The local block-relationship store is updated
25822
+ * before the callback runs.
25823
+ *
25824
+ * @param callback The function to call when the event was fired
25825
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
25826
+ *
25827
+ * @category Block Events
25828
+ */
25829
+ const onUserDidUnblock = (callback) => createBlockEventSubscriber('user.didUnblock', callback);
25830
+
25831
+ /**
25832
+ * Keeps the follow cache current for incoming/outgoing block changes for the
25833
+ * whole session — the ingest happens as a side effect inside
25834
+ * createBlockEventSubscriber, so the one-shot `getAllBlockedUsers()` /
25835
+ * `getAllBlockingUsers()` reflect RTE block/unblock within the TTL window.
25836
+ *
25837
+ * Registered via `setupLoginSubscriptions`; the returned unsubscriber is torn
25838
+ * down on logout.
25839
+ */
25840
+ var blockRealtimeOnLoginHandler = () => {
25841
+ const disposers = [onUserDidBlock(() => { }), onUserDidUnblock(() => { })];
25842
+ return () => disposers.forEach(dispose => dispose());
25843
+ };
25844
+
25845
+ class CursorController {
25846
+ constructor(networkId, userId) {
25847
+ this.networkId = networkId;
25848
+ this.userId = userId;
25849
+ }
25850
+ static current() {
25851
+ try {
25852
+ const user = getCurrentUser();
25853
+ if (!user)
25854
+ return null;
25855
+ const networkId = getNetworkId(user);
25856
+ const { userId } = user;
25857
+ return networkId && userId ? new CursorController(networkId, userId) : null;
25858
+ }
25859
+ catch (_a) {
25860
+ return null;
25861
+ }
25862
+ }
25863
+ static isExpired(expiredAt) {
25864
+ return Date.now() >= expiredAt;
25865
+ }
25866
+ static clearOnLogout() {
25867
+ return onSessionStateChange(state => {
25868
+ var _a;
25869
+ if (state === "terminated" /* Amity.SessionStates.TERMINATED */)
25870
+ (_a = CursorController.current()) === null || _a === void 0 ? void 0 : _a.clear();
25871
+ });
25872
+ }
25873
+ get key() {
25874
+ return `amity:forYouFeed:cursor:${this.networkId}:${this.userId}`;
25875
+ }
25876
+ async get() {
25877
+ const raw = await getItem(this.key);
25878
+ if (!raw)
25879
+ return null;
25880
+ try {
25881
+ const parsed = JSON.parse(raw);
25882
+ if (typeof (parsed === null || parsed === void 0 ? void 0 : parsed.cursor) !== 'string' || typeof (parsed === null || parsed === void 0 ? void 0 : parsed.expiredAt) !== 'number')
25883
+ return null;
25884
+ return {
25885
+ cursor: parsed.cursor,
25886
+ expiredAt: parsed.expiredAt,
25887
+ reachedEndOfFeed: parsed.reachedEndOfFeed === true,
25888
+ };
25889
+ }
25890
+ catch (_a) {
25891
+ return null;
25892
+ }
25893
+ }
25894
+ async set(value) {
25895
+ await setItem(this.key, JSON.stringify(value));
25896
+ }
25897
+ async markReachedEndOfFeed(expiredAt) {
25898
+ var _a;
25899
+ const stored = await this.get();
25900
+ await this.set({
25901
+ cursor: (_a = stored === null || stored === void 0 ? void 0 : stored.cursor) !== null && _a !== void 0 ? _a : '',
25902
+ expiredAt,
25903
+ reachedEndOfFeed: true,
25904
+ });
25905
+ }
25906
+ async clear() {
25907
+ await setItem(this.key, '');
25908
+ }
25909
+ }
25910
+
25312
25911
  const EVENTS = [
25313
25912
  'disconnected',
25314
25913
  'error',
@@ -25498,7 +26097,7 @@ const setupLoginSubscriptions = (unsubWatcher) => {
25498
26097
  // NOTE: This is a temporary solution to handle the channel marker when the user is forced to leave
25499
26098
  // the channel because currently backend can't handle this, so every time a user is banned from
25500
26099
  // a channel or the channel is deleted the channel's unread count will not be reset to zero
25501
- onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler(), reactionSyncEngineOnLoginHandler(), blockedUserSyncEngineOnLoginHandler());
26100
+ onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler(), reactionSyncEngineOnLoginHandler(), blockedUserSyncEngineOnLoginHandler(), blockingUserSyncEngineOnLoginHandler(), blockRealtimeOnLoginHandler(), resetAutoSubscriptionsOnLogout(), CursorController.clearOnLogout());
25502
26101
  if (client.useLegacyUnreadCount) {
25503
26102
  subscriptions.push(readReceiptSyncEngineOnLoginHandler());
25504
26103
  }
@@ -26197,16 +26796,13 @@ const onMessageCreatedMqtt = (callback) => {
26197
26796
  }
26198
26797
  if (client.useLegacyUnreadCount) {
26199
26798
  rawPayload.messages.forEach(message => {
26200
- var _a, _b;
26799
+ var _a, _b, _c;
26201
26800
  const channelUnread = (_a = pullFromCache([
26202
26801
  'channelUnread',
26203
26802
  'get',
26204
26803
  message.channelId,
26205
26804
  ])) === null || _a === void 0 ? void 0 : _a.data;
26206
- if (!channelUnread ||
26207
- channelUnread.lastSegment >= message.segment ||
26208
- typeof channelUnread.readToSegment !== 'number' ||
26209
- typeof channelUnread.lastMentionedSegment !== 'number')
26805
+ if (!channelUnread || channelUnread.lastSegment >= message.segment)
26210
26806
  return;
26211
26807
  const lastSegment = message.segment;
26212
26808
  const isMentionedInMessage = (_b = message.mentionedUsers) === null || _b === void 0 ? void 0 : _b.some(mention => {
@@ -26218,7 +26814,8 @@ const onMessageCreatedMqtt = (callback) => {
26218
26814
  const lastMentionedSegment = isMentionedInMessage
26219
26815
  ? message.segment
26220
26816
  : channelUnread.lastMentionedSegment;
26221
- const updatedChannelUnread = Object.assign(Object.assign({}, channelUnread), { lastSegment, unreadCount: Math.max(lastSegment - channelUnread.readToSegment, 0), lastMentionedSegment, isMentioned: !(channelUnread.readToSegment >= lastMentionedSegment) });
26817
+ const readToSegment = (_c = channelUnread.readToSegment) !== null && _c !== void 0 ? _c : 0;
26818
+ const updatedChannelUnread = Object.assign(Object.assign({}, channelUnread), { lastSegment, unreadCount: Math.max(lastSegment - readToSegment, 0), lastMentionedSegment, isMentioned: typeof lastMentionedSegment === 'number' && readToSegment < lastMentionedSegment });
26222
26819
  pushToCache(['channelUnread', 'get', message.channelId], updatedChannelUnread);
26223
26820
  fireEvent('local.channelUnread.updated', [updatedChannelUnread]);
26224
26821
  });
@@ -26601,15 +27198,18 @@ const createClient = (apiKey, apiRegion = API_REGIONS.SG, { debugSession = DEFAU
26601
27198
  validateUrls,
26602
27199
  validateTexts,
26603
27200
  getFeedSettings,
27201
+ getCoreUserSettings,
26604
27202
  getSocialSettings,
27203
+ getChatSettings,
26605
27204
  getVisitorDeviceId: getDeviceId,
26606
- getMessagePreviewSetting,
27205
+ getMessagePreviewSetting: getMessagePreviewSetting$1,
26607
27206
  onRTEConnectionStateChange,
26608
27207
  use: () => setActiveClient(client),
26609
27208
  isUnreadCountEnabled,
26610
27209
  useLegacyUnreadCount,
26611
27210
  getMarkerSyncConsistentMode,
26612
27211
  getProductCatalogueSetting,
27212
+ getForYouFeedSetting,
26613
27213
  /**
26614
27214
  * Prefix for the deviceId key in the local storage or async storage.
26615
27215
  * This is allow user to have multiple SDK client and Mqtt client within the same app.
@@ -26921,6 +27521,13 @@ const getLinkPreviewMetadata = async (url) => {
26921
27521
  return data;
26922
27522
  };
26923
27523
 
27524
+ const CONTENT_TYPE_CONFIG = {
27525
+ [AmitySharableContentType.POST]: { key: 'posts', placeholder: 'postId' },
27526
+ [AmitySharableContentType.COMMUNITY]: { key: 'communities', placeholder: 'communityId' },
27527
+ [AmitySharableContentType.USER]: { key: 'users', placeholder: 'userId' },
27528
+ [AmitySharableContentType.LIVESTREAM]: { key: 'livestream', placeholder: 'livestream' },
27529
+ [AmitySharableContentType.EVENT]: { key: 'events', placeholder: 'eventId' },
27530
+ };
26924
27531
  /**
26925
27532
  * ```js
26926
27533
  * import Client from '@amityco/ts-sdk-react-native'
@@ -26936,9 +27543,29 @@ const getLinkPreviewMetadata = async (url) => {
26936
27543
  * @async
26937
27544
  */
26938
27545
  const getShareableLinkConfiguration = async () => {
27546
+ var _a, _b;
26939
27547
  const client = getActiveClient();
26940
27548
  const { data } = await client.http.get(`/api/v3/network-settings/shareable-deep-links`);
26941
- return data;
27549
+ const domain = (_a = data.domain) !== null && _a !== void 0 ? _a : '';
27550
+ const patterns = (_b = data.patterns) !== null && _b !== void 0 ? _b : {};
27551
+ return {
27552
+ domain,
27553
+ patterns,
27554
+ isEnabled(contentType) {
27555
+ const { key } = CONTENT_TYPE_CONFIG[contentType];
27556
+ return !!domain && !!patterns[key];
27557
+ },
27558
+ getPattern(contentType) {
27559
+ const { key } = CONTENT_TYPE_CONFIG[contentType];
27560
+ return patterns[key] || null;
27561
+ },
27562
+ generateLink(contentType, referenceId) {
27563
+ const { key, placeholder } = CONTENT_TYPE_CONFIG[contentType];
27564
+ if (!domain || !patterns[key])
27565
+ return null;
27566
+ return domain + patterns[key].replace(`{${placeholder}}`, referenceId);
27567
+ },
27568
+ };
26942
27569
  };
26943
27570
 
26944
27571
  /**
@@ -27263,6 +27890,71 @@ class Notifications {
27263
27890
  }
27264
27891
  const notifications = () => new Notifications();
27265
27892
 
27893
+ /* begin_public_function
27894
+ id: client.enable_auto_subscriptions
27895
+ */
27896
+ /**
27897
+ * ```js
27898
+ * import { Client, AmityAutoSubscription } from '@amityco/ts-sdk'
27899
+ * Client.enableAutoSubscriptions([AmityAutoSubscription.BLOCK])
27900
+ * ```
27901
+ *
27902
+ * Enables one or more managed auto-subscription handles. Managed handles are
27903
+ * re-applied on every (re)connect and ref-counted. All handles are on by
27904
+ * default; use this to re-enable handles previously turned off via
27905
+ * {@link disableAutoSubscriptions}. Synchronous fire-and-forget — the registry
27906
+ * updates immediately and the broker subscribe is retried on reconnect.
27907
+ *
27908
+ * @param features the {@link AmityAutoSubscription} handles to enable
27909
+ *
27910
+ * @category Client API
27911
+ */
27912
+ const enableAutoSubscriptions = (features) => {
27913
+ const manager = getAutoSubscriptionManager();
27914
+ features.forEach(feature => manager.subscribe(feature));
27915
+ };
27916
+ /* end_public_function */
27917
+ /* begin_public_function
27918
+ id: client.disable_auto_subscriptions
27919
+ */
27920
+ /**
27921
+ * ```js
27922
+ * import { Client, AmityAutoSubscription } from '@amityco/ts-sdk'
27923
+ * Client.disableAutoSubscriptions([AmityAutoSubscription.LIVESTREAM])
27924
+ * ```
27925
+ *
27926
+ * Disables one or more managed auto-subscription handles. The change persists
27927
+ * across reconnect (it is not silently re-enabled) until
27928
+ * {@link enableAutoSubscriptions} is called again. Synchronous fire-and-forget.
27929
+ *
27930
+ * @param features the {@link AmityAutoSubscription} handles to disable
27931
+ *
27932
+ * @category Client API
27933
+ */
27934
+ const disableAutoSubscriptions = (features) => {
27935
+ const manager = getAutoSubscriptionManager();
27936
+ features.forEach(feature => manager.unsubscribe(feature));
27937
+ };
27938
+ /* end_public_function */
27939
+ /* begin_public_function
27940
+ id: client.auto_subscriptions
27941
+ */
27942
+ /**
27943
+ * ```js
27944
+ * import { Client } from '@amityco/ts-sdk'
27945
+ * Client.autoSubscriptions().forEach(s => console.log(s.feature, s.isActive, s.topicCount))
27946
+ * ```
27947
+ *
27948
+ * Inspects the managed auto-subscription registry — each handle's `isActive`,
27949
+ * `isSystem`, and `topicCount`.
27950
+ *
27951
+ * @returns a snapshot of the managed subscription registry
27952
+ *
27953
+ * @category Client API
27954
+ */
27955
+ const autoSubscriptions = () => getAutoSubscriptionManager().subscriptions();
27956
+ /* end_public_function */
27957
+
27266
27958
  /**
27267
27959
  * ```js
27268
27960
  * import { onChannelMarkerFetched } from '@amityco/ts-sdk-react-native'
@@ -27640,13 +28332,19 @@ var index$s = /*#__PURE__*/Object.freeze({
27640
28332
  getSocialSettings: getSocialSettings,
27641
28333
  getShareableLinkConfiguration: getShareableLinkConfiguration,
27642
28334
  getProductCatalogueSetting: getProductCatalogueSetting,
28335
+ getForYouFeedSetting: getForYouFeedSetting,
27643
28336
  loginAsVisitor: loginAsVisitor,
27644
28337
  loginAsBot: loginAsBot,
27645
28338
  getCurrentUser: getCurrentUser,
27646
28339
  getCurrentUserType: getCurrentUserType,
27647
28340
  setCurrentUserType: setCurrentUserType,
27648
28341
  setAccessTokenHandler: setAccessTokenHandler,
28342
+ getChatSettings: getChatSettings,
28343
+ getCoreUserSettings: getCoreUserSettings,
27649
28344
  notifications: notifications,
28345
+ enableAutoSubscriptions: enableAutoSubscriptions,
28346
+ disableAutoSubscriptions: disableAutoSubscriptions,
28347
+ autoSubscriptions: autoSubscriptions,
27650
28348
  onConnectionError: onConnectionError,
27651
28349
  onClientDisconnected: onClientDisconnected,
27652
28350
  onClientBanned: onClientBanned,
@@ -27664,19 +28362,6 @@ var index$s = /*#__PURE__*/Object.freeze({
27664
28362
  getMarkerSyncConsistentMode: getMarkerSyncConsistentMode
27665
28363
  });
27666
28364
 
27667
- function prepareFollowersPayload(response) {
27668
- const { users, follows } = response, rest = __rest(response, ["users", "follows"]);
27669
- return Object.assign(Object.assign({}, rest), { follows, users: users.map(convertRawUserToInternalUser) });
27670
- }
27671
- function prepareFollowingsPayload(response) {
27672
- const { users, follows } = response, rest = __rest(response, ["users", "follows"]);
27673
- return Object.assign(Object.assign({}, rest), { follows, users: users.map(convertRawUserToInternalUser) });
27674
- }
27675
- function prepareFollowStatusPayload(response) {
27676
- const { follows } = response, rest = __rest(response, ["follows"]);
27677
- return Object.assign(Object.assign({}, rest), { follows });
27678
- }
27679
-
27680
28365
  /* begin_public_function
27681
28366
  id: user.relationship.block
27682
28367
  */
@@ -28854,6 +29539,8 @@ var index$r = /*#__PURE__*/Object.freeze({
28854
29539
  __proto__: null,
28855
29540
  blockUser: blockUser,
28856
29541
  unBlockUser: unBlockUser,
29542
+ onUserDidBlock: onUserDidBlock,
29543
+ onUserDidUnblock: onUserDidUnblock,
28857
29544
  follow: follow,
28858
29545
  unfollow: unfollow,
28859
29546
  acceptMyFollower: acceptMyFollower,
@@ -29683,7 +30370,7 @@ const getWatchSessionStorage = () => {
29683
30370
  return storageInstance;
29684
30371
  };
29685
30372
 
29686
- 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-----";
30373
+ 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-----";
29687
30374
  /*
29688
30375
  * The crypto algorithm used for importing key and signing string
29689
30376
  */
@@ -31005,6 +31692,10 @@ const postLinkedObject = (post) => {
31005
31692
  const analyticsEngineInstance = AnalyticsEngine$1.getInstance();
31006
31693
  analyticsEngineInstance.markPostAsViewed(post.postId);
31007
31694
  },
31695
+ markAsMeaningfullyViewed: (feedRenderPosition) => {
31696
+ const analyticsEngineInstance = AnalyticsEngine$1.getInstance();
31697
+ analyticsEngineInstance.markPostAsMeaningfullyViewed(post.postId, feedRenderPosition);
31698
+ },
31008
31699
  },
31009
31700
  get productTags() {
31010
31701
  var _a, _b;
@@ -31194,6 +31885,11 @@ const addReaction$1 = async (referenceType, referenceId, reactionName, reference
31194
31885
  });
31195
31886
  return true;
31196
31887
  }
31888
+ if (referenceType === 'message') {
31889
+ upsertInCache(['message', 'get', referenceId], updatedModel);
31890
+ fireEvent('local.message.updated', { messages: [updatedModel] });
31891
+ return true;
31892
+ }
31197
31893
  }
31198
31894
  return true;
31199
31895
  };
@@ -31272,7 +31968,7 @@ const removeReaction$1 = async (referenceType, referenceId, reactionName, refere
31272
31968
  return true;
31273
31969
  }
31274
31970
  if (referenceType === 'story') {
31275
- fireEvent('local.story.reactionAdded', {
31971
+ fireEvent('local.story.reactionRemoved', {
31276
31972
  story: updatedModel,
31277
31973
  reactor: {
31278
31974
  userId: client.userId,
@@ -31282,6 +31978,11 @@ const removeReaction$1 = async (referenceType, referenceId, reactionName, refere
31282
31978
  });
31283
31979
  return true;
31284
31980
  }
31981
+ if (referenceType === 'message') {
31982
+ upsertInCache(['message', 'get', referenceId], updatedModel);
31983
+ fireEvent('local.message.updated', { messages: [updatedModel] });
31984
+ return true;
31985
+ }
31285
31986
  }
31286
31987
  return true;
31287
31988
  };
@@ -31554,7 +32255,7 @@ const createEventResponseSubscriber = (event, callback) => {
31554
32255
  const eventResponse = pullFromCache([
31555
32256
  'eventResponse',
31556
32257
  'get',
31557
- payload.eventResponses[0].eventId,
32258
+ unpackedPayload.eventResponses[0].userId,
31558
32259
  ]);
31559
32260
  callback(eventResponse.data);
31560
32261
  }
@@ -32218,7 +32919,38 @@ const getAllBlockedUsers = async () => {
32218
32919
  const engine = BlockedUserSyncEngine$1.getInstance();
32219
32920
  // Ensure data is fetched (no-op if cache is fresh)
32220
32921
  await engine.ensureFetched();
32221
- // Read from the engine's bounded ID list — O(blocked users) not O(cache size)
32922
+ return engine.getCachedUsers();
32923
+ };
32924
+ /* end_public_function */
32925
+
32926
+ /* begin_public_function
32927
+ id: user.get_all_blocking_users
32928
+ */
32929
+ /**
32930
+ * ```js
32931
+ * import { UserRepository } from '@amityco/ts-sdk'
32932
+ * const blockingUsers = await UserRepository.getAllBlockingUsers()
32933
+ * ```
32934
+ *
32935
+ * Returns all users who have blocked the current user
32936
+ * non-paginated list (limit 100) with TTL-based caching (5-minute window). Within the
32937
+ * TTL window, subsequent calls resolve instantly from the local store without any
32938
+ * server call. After the TTL expires, the next call triggers a fresh server fetch.
32939
+ *
32940
+ * The directional inverse of {@link getAllBlockedUsers}.
32941
+ *
32942
+ * @returns A promise that resolves to an array of blocking {@link Amity.User} objects
32943
+ *
32944
+ * @category Block API
32945
+ * @async
32946
+ */
32947
+ const getAllBlockingUsers = async () => {
32948
+ const client = getActiveClient();
32949
+ client.log('user/getAllBlockingUsers');
32950
+ const engine = BlockingUserSyncEngine$1.getInstance();
32951
+ // Ensure data is fetched (no-op if cache is fresh)
32952
+ await engine.ensureFetched();
32953
+ // Read from the engine's bounded ID list — O(blocking users) not O(cache size)
32222
32954
  return engine.getCachedUsers();
32223
32955
  };
32224
32956
  /* end_public_function */
@@ -32601,6 +33333,12 @@ class BlockedUserPaginationController extends PaginationController {
32601
33333
  }
32602
33334
  }
32603
33335
 
33336
+ var EnumBlockActions;
33337
+ (function (EnumBlockActions) {
33338
+ EnumBlockActions["OnBlocked"] = "onBlocked";
33339
+ EnumBlockActions["OnUnblocked"] = "onUnblocked";
33340
+ })(EnumBlockActions || (EnumBlockActions = {}));
33341
+
32604
33342
  class BlockedUserQueryStreamController extends QueryStreamController {
32605
33343
  constructor(query, cacheKey, notifyChange, preparePayload) {
32606
33344
  super(query, cacheKey);
@@ -32630,11 +33368,16 @@ class BlockedUserQueryStreamController extends QueryStreamController {
32630
33368
  }
32631
33369
  reactor(action) {
32632
33370
  return (targetUser) => {
32633
- var _a;
32634
- if (action === EnumFollowActions.OnFollowed) {
33371
+ var _a, _b;
33372
+ const isRemoval = action === EnumFollowActions.OnFollowed || action === EnumBlockActions.OnUnblocked;
33373
+ const isAddition = action === EnumBlockActions.OnBlocked;
33374
+ if (isRemoval || isAddition) {
32635
33375
  const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
32636
- const updatedCollection = collection === null || collection === void 0 ? void 0 : collection.data.filter(id => id !== targetUser.userId);
32637
- pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: updatedCollection }));
33376
+ const ids = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
33377
+ const data = isAddition
33378
+ ? [...new Set([...ids, targetUser.userId])]
33379
+ : ids.filter(id => id !== targetUser.userId);
33380
+ pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data }));
32638
33381
  }
32639
33382
  this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
32640
33383
  };
@@ -32689,7 +33432,6 @@ class BlockedUserLiveCollectionController extends LiveCollectionController {
32689
33432
  fn: onUserDeleted$2,
32690
33433
  action: EnumUserActions.OnUserDeleted,
32691
33434
  },
32692
- // In the case of unblocking a user, we need to subscribe to the follow events
32693
33435
  {
32694
33436
  fn: convertEventPayload(onLocalUserFollowed, 'to', 'user'),
32695
33437
  action: EnumFollowActions.OnFollowed,
@@ -32698,6 +33440,28 @@ class BlockedUserLiveCollectionController extends LiveCollectionController {
32698
33440
  fn: convertEventPayload(onUserFollowed, 'to', 'user'),
32699
33441
  action: EnumFollowActions.OnFollowed,
32700
33442
  },
33443
+ {
33444
+ fn: (reactor) => onUserDidBlock(status => {
33445
+ var _a;
33446
+ if (status.from !== getActiveClient().userId)
33447
+ return;
33448
+ const blocked = (_a = pullFromCache(['user', 'get', status.to])) === null || _a === void 0 ? void 0 : _a.data;
33449
+ if (blocked)
33450
+ reactor(blocked);
33451
+ }),
33452
+ action: EnumBlockActions.OnBlocked,
33453
+ },
33454
+ {
33455
+ fn: (reactor) => onUserDidUnblock(status => {
33456
+ var _a;
33457
+ if (status.from !== getActiveClient().userId)
33458
+ return;
33459
+ const blocked = (_a = pullFromCache(['user', 'get', status.to])) === null || _a === void 0 ? void 0 : _a.data;
33460
+ if (blocked)
33461
+ reactor(blocked);
33462
+ }),
33463
+ action: EnumBlockActions.OnUnblocked,
33464
+ },
32701
33465
  ]);
32702
33466
  }
32703
33467
  notifyChange({ origin, loading, error }) {
@@ -32765,6 +33529,184 @@ const getBlockedUsers = (params, callback, config) => {
32765
33529
  };
32766
33530
  /* end_public_function */
32767
33531
 
33532
+ class BlockingUserQueryStreamController extends QueryStreamController {
33533
+ constructor(query, cacheKey, notifyChange, preparePayload) {
33534
+ super(query, cacheKey);
33535
+ this.notifyChange = notifyChange;
33536
+ this.preparePayload = preparePayload;
33537
+ }
33538
+ async saveToMainDB(response) {
33539
+ const processedPayload = await this.preparePayload(response);
33540
+ const client = getActiveClient();
33541
+ const cachedAt = client.cache && Date.now();
33542
+ if (client.cache) {
33543
+ ingestInCache(processedPayload, { cachedAt });
33544
+ }
33545
+ }
33546
+ appendToQueryStream(response, direction, refresh = false) {
33547
+ var _a, _b;
33548
+ if (refresh) {
33549
+ pushToCache(this.cacheKey, {
33550
+ data: response.users.map(getResolver('user')),
33551
+ });
33552
+ }
33553
+ else {
33554
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
33555
+ const users = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
33556
+ pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [...new Set([...users, ...response.users.map(getResolver('user'))])] }));
33557
+ }
33558
+ }
33559
+ reactor(action) {
33560
+ return (user) => {
33561
+ var _a, _b;
33562
+ if (user &&
33563
+ (action === EnumBlockActions.OnBlocked || action === EnumBlockActions.OnUnblocked)) {
33564
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
33565
+ const ids = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
33566
+ const data = action === EnumBlockActions.OnBlocked
33567
+ ? [...new Set([...ids, user.userId])]
33568
+ : ids.filter(id => id !== user.userId);
33569
+ pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data }));
33570
+ }
33571
+ this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
33572
+ };
33573
+ }
33574
+ subscribeRTE(createSubscriber) {
33575
+ return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
33576
+ }
33577
+ }
33578
+
33579
+ class BlockingUserPaginationController extends PaginationController {
33580
+ async getRequest(queryParams, token) {
33581
+ const { limit = COLLECTION_DEFAULT_PAGINATION_SIZE } = queryParams, params = __rest(queryParams, ["limit"]);
33582
+ const options = token ? { token } : { limit };
33583
+ const { data: queryResponse } = await this.http.get('/api/v4/me/blockers', {
33584
+ params: Object.assign(Object.assign({}, params), { options, isDeleted: false }),
33585
+ });
33586
+ return queryResponse;
33587
+ }
33588
+ }
33589
+
33590
+ class BlockingUserLiveCollectionController extends LiveCollectionController {
33591
+ constructor(callback) {
33592
+ const queryStreamId = `blocking-users-${getActiveClient().userId}`;
33593
+ const query = {};
33594
+ const cacheKey = ['blockingUsers', 'collection', queryStreamId];
33595
+ const paginationController = new BlockingUserPaginationController(query);
33596
+ super(paginationController, queryStreamId, cacheKey, callback);
33597
+ this.queryStreamController = new BlockingUserQueryStreamController(query, this.cacheKey, this.notifyChange.bind(this), prepareBlockingUserPayload);
33598
+ this.callback = callback.bind(this);
33599
+ this.loadPage({ initial: true });
33600
+ }
33601
+ setup() {
33602
+ var _a;
33603
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
33604
+ if (!collection) {
33605
+ pushToCache(this.cacheKey, {
33606
+ data: [],
33607
+ params: {},
33608
+ });
33609
+ }
33610
+ }
33611
+ async persistModel(queryPayload) {
33612
+ await this.queryStreamController.saveToMainDB(queryPayload);
33613
+ }
33614
+ persistQueryStream({ response, direction, refresh, }) {
33615
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
33616
+ }
33617
+ startSubscription() {
33618
+ return this.queryStreamController.subscribeRTE([
33619
+ {
33620
+ fn: onUserDeleted$2,
33621
+ action: EnumUserActions.OnUserDeleted,
33622
+ },
33623
+ {
33624
+ fn: (reactor) => onUserDidBlock(status => {
33625
+ var _a;
33626
+ if (status.to !== getActiveClient().userId)
33627
+ return;
33628
+ const blocker = (_a = pullFromCache(['user', 'get', status.from])) === null || _a === void 0 ? void 0 : _a.data;
33629
+ if (blocker)
33630
+ reactor(blocker);
33631
+ }),
33632
+ action: EnumBlockActions.OnBlocked,
33633
+ },
33634
+ {
33635
+ fn: (reactor) => onUserDidUnblock(status => {
33636
+ var _a;
33637
+ if (status.to !== getActiveClient().userId)
33638
+ return;
33639
+ const blocker = (_a = pullFromCache(['user', 'get', status.from])) === null || _a === void 0 ? void 0 : _a.data;
33640
+ if (blocker)
33641
+ reactor(blocker);
33642
+ }),
33643
+ action: EnumBlockActions.OnUnblocked,
33644
+ },
33645
+ ]);
33646
+ }
33647
+ notifyChange({ origin, loading, error }) {
33648
+ var _a, _b;
33649
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
33650
+ if (!collection)
33651
+ return;
33652
+ const data = this.applyFilter((_b = collection.data
33653
+ .map(id => pullFromCache(['user', 'get', id]))
33654
+ .filter(isNonNullable)
33655
+ .map(({ data }) => data)
33656
+ .map(LinkedObject.user)) !== null && _b !== void 0 ? _b : []);
33657
+ if (!this.shouldNotify(data) && origin === 'event')
33658
+ return;
33659
+ this.callback({
33660
+ onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
33661
+ data,
33662
+ hasNextPage: !!this.paginationController.getNextToken(),
33663
+ loading,
33664
+ error,
33665
+ });
33666
+ }
33667
+ applyFilter(data) {
33668
+ let users = data;
33669
+ users = users.filter(user => user.isDeleted == null || user.isDeleted === false);
33670
+ return users;
33671
+ }
33672
+ }
33673
+
33674
+ /* begin_public_function
33675
+ id: user.get_blocking_users
33676
+ */
33677
+ /**
33678
+ * ```js
33679
+ * import { UserRepository } from '@amityco/ts-sdk'
33680
+ * const unsubscribe = UserRepository.getBlockingUsers(({ data: users }) => {
33681
+ * console.log(users)
33682
+ * })
33683
+ * ```
33684
+ *
33685
+ * Observe the {@link Amity.User}s who have blocked the current user
33686
+ *
33687
+ * @param callback to receive updates on the blocking {@link Amity.User}s
33688
+ * @returns {@link Amity.Unsubscriber} to unsubscribe from collection
33689
+ *
33690
+ * @category User API
33691
+ */
33692
+ const getBlockingUsers = (callback) => {
33693
+ const { log, cache } = getActiveClient();
33694
+ if (!cache)
33695
+ console.log(ENABLE_CACHE_MESSAGE);
33696
+ const timestamp = Date.now();
33697
+ log(`getBlockingUsers(tmpid: ${timestamp}) > listen`);
33698
+ const blockingUserLiveCollection = new BlockingUserLiveCollectionController(callback);
33699
+ const disposers = blockingUserLiveCollection.startSubscription();
33700
+ const cacheKey = blockingUserLiveCollection.getCacheKey();
33701
+ disposers.push(() => dropFromCache(cacheKey));
33702
+ return () => {
33703
+ log(`getBlockingUsers(tmpid: ${timestamp}) > dispose`);
33704
+ disposers.forEach(fn => fn());
33705
+ dropFromCache(cacheKey);
33706
+ };
33707
+ };
33708
+ /* end_public_function */
33709
+
32768
33710
  class SearchUserPaginationController extends PaginationController {
32769
33711
  async getRequest(queryParams, token) {
32770
33712
  const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT, displayName } = queryParams, params = __rest(queryParams, ["limit", "displayName"]);
@@ -33031,6 +33973,7 @@ var index$q = /*#__PURE__*/Object.freeze({
33031
33973
  unflagUser: unflagUser,
33032
33974
  isUserFlaggedByMe: isUserFlaggedByMe,
33033
33975
  getAllBlockedUsers: getAllBlockedUsers,
33976
+ getAllBlockingUsers: getAllBlockingUsers,
33034
33977
  onUserUpdated: onUserUpdated,
33035
33978
  onUserDeleted: onUserDeleted$2,
33036
33979
  onUserFlagged: onUserFlagged,
@@ -33039,6 +33982,7 @@ var index$q = /*#__PURE__*/Object.freeze({
33039
33982
  getUser: getUser,
33040
33983
  getUsers: getUsers,
33041
33984
  getBlockedUsers: getBlockedUsers,
33985
+ getBlockingUsers: getBlockingUsers,
33042
33986
  searchUserByDisplayName: searchUserByDisplayName,
33043
33987
  getReachedUsers: getReachedUsers,
33044
33988
  get AmityUserSearchMatchType () { return AmityUserSearchMatchType; }
@@ -34205,7 +35149,7 @@ const removeReaction = async (referenceType, referenceId, reactionName) => {
34205
35149
  return true;
34206
35150
  }
34207
35151
  if (referenceType === 'story') {
34208
- fireEvent('local.story.reactionAdded', {
35152
+ fireEvent('local.story.reactionRemoved', {
34209
35153
  story: updatedModel,
34210
35154
  reactor: {
34211
35155
  userId: client.userId,
@@ -35789,6 +36733,104 @@ const unmuteChannel = async (channelId) => {
35789
36733
  };
35790
36734
  /* end_public_function */
35791
36735
 
36736
+ /* begin_public_function
36737
+ id: channel.archive
36738
+ */
36739
+ /**
36740
+ * ```js
36741
+ * import { ChannelRepository } from '@amityco/ts-sdk'
36742
+ * const success = await ChannelRepository.archiveChannel('foobar')
36743
+ * ```
36744
+ *
36745
+ * Archive a {@link Amity.Channel}.
36746
+ *
36747
+ * @param channelId The id of the {@link Amity.Channel} to archive
36748
+ * @returns A success boolean
36749
+ *
36750
+ * @category Channel API
36751
+ * @async
36752
+ */
36753
+ const archiveChannel = async (channelId) => {
36754
+ const client = getActiveClient();
36755
+ client.log('channel/archiveChannel', channelId);
36756
+ await client.http.post(`/api/v1/archives/channels/${encodeURIComponent(channelId)}`);
36757
+ const archive = {
36758
+ channelId,
36759
+ archivedAt: new Date().toISOString(),
36760
+ };
36761
+ if (client.cache) {
36762
+ pushToCache(['archivedChannel', 'get', getResolver('archivedChannel')(archive)], archive);
36763
+ }
36764
+ fireEvent('local.channel.archived', { archives: [archive] });
36765
+ };
36766
+ /* end_public_function */
36767
+
36768
+ /* begin_public_function
36769
+ id: channel.unarchive
36770
+ */
36771
+ /**
36772
+ * ```js
36773
+ * import { ChannelRepository } from '@amityco/ts-sdk'
36774
+ * const success = await ChannelRepository.unarchiveChannel('foobar')
36775
+ * ```
36776
+ *
36777
+ * Unarchive a previously archived {@link Amity.Channel}.
36778
+ *
36779
+ * @param channelId The id of the {@link Amity.Channel} to unarchive
36780
+ * @returns A success boolean
36781
+ *
36782
+ * @category Channel API
36783
+ * @async
36784
+ */
36785
+ const unarchiveChannel = async (channelId) => {
36786
+ var _a;
36787
+ const client = getActiveClient();
36788
+ client.log('channel/unarchiveChannel', channelId);
36789
+ await client.http.delete(`/api/v1/archives/channels/${encodeURIComponent(channelId)}`);
36790
+ const cached = (_a = pullFromCache(['archivedChannel', 'get', channelId])) === null || _a === void 0 ? void 0 : _a.data;
36791
+ const archive = cached !== null && cached !== void 0 ? cached : {
36792
+ channelId,
36793
+ archivedAt: new Date().toISOString(),
36794
+ };
36795
+ if (client.cache) {
36796
+ dropFromCache(['archivedChannel', 'get', channelId], true);
36797
+ }
36798
+ fireEvent('local.channel.unarchived', { archives: [archive] });
36799
+ };
36800
+ /* end_public_function */
36801
+
36802
+ /* begin_public_function
36803
+ id: channel.archive.ids
36804
+ */
36805
+ /**
36806
+ * ```js
36807
+ * import { ChannelRepository } from '@amityco/ts-sdk'
36808
+ * const ids = await ChannelRepository.getArchivedChannelIds()
36809
+ * ```
36810
+ *
36811
+ * @returns A list of archived channel ids sorted by `archivedAt` descending.
36812
+ *
36813
+ * @category Channel API
36814
+ * @async
36815
+ */
36816
+ const getArchivedChannelIds = async () => {
36817
+ var _a;
36818
+ const client = getActiveClient();
36819
+ client.log('channel/getArchivedChannelIds');
36820
+ const { data: payload } = await client.http.get(`/api/v1/archives/channels`);
36821
+ const archives = (_a = payload.archives) !== null && _a !== void 0 ? _a : [];
36822
+ if (client.cache) {
36823
+ dropFromCache(['archivedChannel', 'get']);
36824
+ archives.forEach(archive => {
36825
+ if (!archive.channelId)
36826
+ return;
36827
+ pushToCache(['archivedChannel', 'get', archive.channelId], archive);
36828
+ });
36829
+ }
36830
+ return archives.map(entry => entry.channelId).filter(channelId => !!channelId);
36831
+ };
36832
+ /* end_public_function */
36833
+
35792
36834
  /**
35793
36835
  * ```js
35794
36836
  * import { onMessageUpdated } from '@amityco/ts-sdk-react-native'
@@ -37167,6 +38209,160 @@ const getMessages = (params, callback, config) => {
37167
38209
  };
37168
38210
  /* end_public_function */
37169
38211
 
38212
+ class SearchMessagePaginationController extends PaginationController {
38213
+ async getRequest(queryParams, token) {
38214
+ const { query, exactMatch, channelId, messageFeedId, userIds, tags, types, sortBy, orderBy, limit = COLLECTION_DEFAULT_PAGINATION_LIMIT, } = queryParams;
38215
+ const options = token ? { token } : { limit, sortBy, orderBy };
38216
+ const { data: queryResponse } = await this.http.get(`/api/v2/search/messages`, {
38217
+ params: {
38218
+ query,
38219
+ exactMatch,
38220
+ channelId,
38221
+ messageFeedId,
38222
+ userIds,
38223
+ tags,
38224
+ types,
38225
+ options,
38226
+ },
38227
+ });
38228
+ return queryResponse;
38229
+ }
38230
+ }
38231
+
38232
+ class SearchMessageQueryStreamController extends QueryStreamController {
38233
+ constructor(query, cacheKey, notifyChange) {
38234
+ super(query, cacheKey);
38235
+ this.notifyChange = notifyChange;
38236
+ }
38237
+ async saveToMainDB(response) {
38238
+ var _a;
38239
+ const processedPayload = await prepareMessagePayload(response);
38240
+ const client = getActiveClient();
38241
+ const cachedAt = client.cache && Date.now();
38242
+ if (client.cache) {
38243
+ ingestInCache(processedPayload, { cachedAt });
38244
+ if ((_a = response.channels) === null || _a === void 0 ? void 0 : _a.length) {
38245
+ response.channels.forEach(channel => {
38246
+ pushToCache(['channel', 'get', channel.channelId], channel, { cachedAt });
38247
+ });
38248
+ }
38249
+ }
38250
+ }
38251
+ appendToQueryStream(response, direction, refresh = false) {
38252
+ var _a, _b;
38253
+ if (refresh) {
38254
+ pushToCache(this.cacheKey, {
38255
+ data: response.messages.map(getResolver('message')),
38256
+ });
38257
+ return;
38258
+ }
38259
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
38260
+ const existing = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
38261
+ const incoming = response.messages.map(getResolver('message'));
38262
+ pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: direction === "prev" /* Amity.LiveCollectionPageDirection.PREV */
38263
+ ? [...new Set([...incoming, ...existing])]
38264
+ : [...new Set([...existing, ...incoming])] }));
38265
+ }
38266
+ }
38267
+
38268
+ class SearchMessageLiveCollectionController extends LiveCollectionController {
38269
+ constructor(query, callback) {
38270
+ const queryStreamId = hash(query);
38271
+ const cacheKey = ['message', 'search', queryStreamId];
38272
+ const paginationController = new SearchMessagePaginationController(query);
38273
+ super(paginationController, queryStreamId, cacheKey, callback);
38274
+ this.queryStreamController = new SearchMessageQueryStreamController(query, this.cacheKey, this.notifyChange.bind(this));
38275
+ this.callback = callback.bind(this);
38276
+ this.loadPage({ initial: true });
38277
+ }
38278
+ startSubscription() {
38279
+ return [];
38280
+ }
38281
+ notifyChange({ origin, loading, error }) {
38282
+ var _a, _b;
38283
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
38284
+ if (!collection)
38285
+ return;
38286
+ const data = (_b = collection.data
38287
+ .map(messageId => getMessageFromMainDB(messageId))
38288
+ .filter(isNonNullable)
38289
+ .map(message => LinkedObject.message(message))) !== null && _b !== void 0 ? _b : [];
38290
+ if (!this.shouldNotify(data) && origin === 'event')
38291
+ return;
38292
+ this.callback({
38293
+ onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
38294
+ data,
38295
+ hasNextPage: !!this.paginationController.getNextToken(),
38296
+ loading,
38297
+ error,
38298
+ });
38299
+ }
38300
+ setup() {
38301
+ var _a;
38302
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
38303
+ if (!collection) {
38304
+ pushToCache(this.cacheKey, {
38305
+ data: [],
38306
+ params: {},
38307
+ });
38308
+ }
38309
+ }
38310
+ async persistModel(response) {
38311
+ await this.queryStreamController.saveToMainDB(response);
38312
+ }
38313
+ persistQueryStream({ response, direction, refresh, }) {
38314
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
38315
+ }
38316
+ }
38317
+
38318
+ /* begin_public_function
38319
+ id: message.search
38320
+ */
38321
+ /**
38322
+ * ```js
38323
+ * import { MessageRepository } from '@amityco/ts-sdk';
38324
+ *
38325
+ * let messages = [];
38326
+ *
38327
+ * const unsubscribe = MessageRepository.searchMessage(
38328
+ * { query: 'hello' },
38329
+ * response => merge(messages, response.data),
38330
+ * );
38331
+ * ```
38332
+ *
38333
+ * Live collection of {@link Amity.Message}s matching the search query. Backed
38334
+ * by `GET /api/v2/search/messages`. The first emission delivers the first
38335
+ * page; pagination is driven by `response.onNextPage()`.
38336
+ *
38337
+ * @param params Search parameters. `query` is required.
38338
+ * @param callback Called whenever new data are available.
38339
+ * @returns An {@link Amity.Unsubscriber} function to stop observing.
38340
+ *
38341
+ * @category Message Live Collection
38342
+ */
38343
+ const searchMessage = (params, callback) => {
38344
+ if (!params.query || params.query.trim().length === 0) {
38345
+ throw new Error('Query is required for message search');
38346
+ }
38347
+ const { log, cache } = getActiveClient();
38348
+ if (!cache) {
38349
+ console.log(ENABLE_CACHE_MESSAGE);
38350
+ }
38351
+ const timestamp = Date.now();
38352
+ log(`searchMessage(tmpid: ${timestamp}) > listen`);
38353
+ const controller = new SearchMessageLiveCollectionController(params, callback);
38354
+ const disposers = controller.startSubscription();
38355
+ const cacheKey = controller.getCacheKey();
38356
+ disposers.push(() => {
38357
+ dropFromCache(cacheKey);
38358
+ });
38359
+ return () => {
38360
+ log(`searchMessage(tmpid: ${timestamp}) > dispose`);
38361
+ disposers.forEach(fn => fn());
38362
+ };
38363
+ };
38364
+ /* end_public_function */
38365
+
37170
38366
  var index$n = /*#__PURE__*/Object.freeze({
37171
38367
  __proto__: null,
37172
38368
  createMessage: createMessage,
@@ -37192,6 +38388,7 @@ var index$n = /*#__PURE__*/Object.freeze({
37192
38388
  onMessageFetched: onMessageFetched,
37193
38389
  getMessage: getMessage,
37194
38390
  getMessages: getMessages,
38391
+ searchMessage: searchMessage,
37195
38392
  convertFromRaw: convertFromRaw$1,
37196
38393
  prepareMessagePayload: prepareMessagePayload,
37197
38394
  convertParams: convertParams,
@@ -38039,6 +39236,7 @@ class ChannelQueryStreamController extends QueryStreamController {
38039
39236
  "onCreate" /* Amity.ChannelActionType.OnCreate */,
38040
39237
  "onJoin" /* Amity.ChannelActionType.OnJoin */,
38041
39238
  "onResolveChannel" /* Amity.ChannelActionType.OnResolveChannel */,
39239
+ "onUnarchived" /* Amity.ChannelActionType.OnUnarchived */,
38042
39240
  ].includes(action)) {
38043
39241
  if (Array.isArray(payload)) {
38044
39242
  collection.data = [
@@ -38048,6 +39246,12 @@ class ChannelQueryStreamController extends QueryStreamController {
38048
39246
  else
38049
39247
  collection.data = [...new Set([payload.channelInternalId, ...collection.data])];
38050
39248
  }
39249
+ if (action === "onArchived" /* Amity.ChannelActionType.OnArchived */) {
39250
+ const ids = Array.isArray(payload)
39251
+ ? payload.map(getResolver('channel'))
39252
+ : [getResolver('channel')(payload)];
39253
+ collection.data = collection.data.filter(channelInternalId => !ids.includes(channelInternalId));
39254
+ }
38051
39255
  pushToCache(this.cacheKey, collection);
38052
39256
  this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
38053
39257
  };
@@ -38314,6 +39518,32 @@ class ChannelLiveCollectionController extends LiveCollectionController {
38314
39518
  },
38315
39519
  { fn: onChannelMemberAdded, action: "onMemberAdded" /* Amity.ChannelActionType.OnMemberAdded */ },
38316
39520
  { fn: onChannelMemberRemoved, action: "onMemberRemoved" /* Amity.ChannelActionType.OnMemberRemoved */ },
39521
+ {
39522
+ fn: (reactor) => onChannelArchived(payload => {
39523
+ const channels = payload.archives
39524
+ .map(archive => {
39525
+ var _a;
39526
+ return (_a = pullFromCache(['channel', 'get', archive.channelId])) === null || _a === void 0 ? void 0 : _a.data;
39527
+ })
39528
+ .filter((c) => Boolean(c));
39529
+ if (channels.length > 0)
39530
+ reactor(channels);
39531
+ }),
39532
+ action: "onArchived" /* Amity.ChannelActionType.OnArchived */,
39533
+ },
39534
+ {
39535
+ fn: (reactor) => onChannelUnarchived(payload => {
39536
+ const channels = payload.archives
39537
+ .map(archive => {
39538
+ var _a;
39539
+ return (_a = pullFromCache(['channel', 'get', archive.channelId])) === null || _a === void 0 ? void 0 : _a.data;
39540
+ })
39541
+ .filter((c) => Boolean(c));
39542
+ if (channels.length > 0)
39543
+ reactor(channels);
39544
+ }),
39545
+ action: "onUnarchived" /* Amity.ChannelActionType.OnUnarchived */,
39546
+ },
38317
39547
  {
38318
39548
  fn: convertEventPayload(onChannelMarkerFetched, 'entityId', 'channel'),
38319
39549
  action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
@@ -38492,181 +39722,766 @@ class ChannelLiveCollectionController extends LiveCollectionController {
38492
39722
  action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
38493
39723
  },
38494
39724
  ];
38495
- if (this.paginationController instanceof PaginationController) {
38496
- return [
38497
- ...subscriptions,
38498
- {
38499
- fn: (callback) => {
38500
- return onChannelCreated(channel => {
38501
- resolveUnreadInfoOnChannelEvent(channel);
38502
- callback(channel);
38503
- });
38504
- },
38505
- action: "onCreate" /* Amity.ChannelActionType.OnCreate */,
38506
- },
38507
- ];
38508
- }
38509
- return subscriptions;
39725
+ if (this.paginationController instanceof PaginationController) {
39726
+ return [
39727
+ ...subscriptions,
39728
+ {
39729
+ fn: (callback) => {
39730
+ return onChannelCreated(channel => {
39731
+ resolveUnreadInfoOnChannelEvent(channel);
39732
+ callback(channel);
39733
+ });
39734
+ },
39735
+ action: "onCreate" /* Amity.ChannelActionType.OnCreate */,
39736
+ },
39737
+ ];
39738
+ }
39739
+ return subscriptions;
39740
+ }
39741
+ }
39742
+
39743
+ /* eslint-disable no-use-before-define */
39744
+ /* begin_public_function
39745
+ id: channel.query
39746
+ */
39747
+ /**
39748
+ * ```js
39749
+ * import { getChannels } from '@amityco/ts-sdk-react-native'
39750
+ *
39751
+ * let channels = []
39752
+ * const unsub = getChannels({
39753
+ * displayName: Amity.Channel['displayName'],
39754
+ * }, response => merge(channels, response.data))
39755
+ * ```
39756
+ *
39757
+ * Observe all mutations on a list of {@link Amity.Channel}s
39758
+ *
39759
+ * @param params for querying channels
39760
+ * @param callback the function to call when new data are available
39761
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the channels
39762
+ *
39763
+ * @category Channel Live Collection
39764
+ */
39765
+ const getChannels = (params, callback, config) => {
39766
+ const { log, cache, userId } = getActiveClient();
39767
+ if (!cache) {
39768
+ console.log(ENABLE_CACHE_MESSAGE);
39769
+ }
39770
+ const timestamp = Date.now();
39771
+ log(`getChannels(tmpid: ${timestamp}) > listen`);
39772
+ const channelLiveCollection = new ChannelLiveCollectionController(params, callback);
39773
+ const disposers = channelLiveCollection.startSubscription();
39774
+ const cacheKey = channelLiveCollection.getCacheKey();
39775
+ disposers.push(() => {
39776
+ dropFromCache(cacheKey);
39777
+ });
39778
+ return () => {
39779
+ log(`getChannels(tmpid: ${timestamp}) > dispose`);
39780
+ disposers.forEach(fn => fn());
39781
+ };
39782
+ };
39783
+ /* end_public_function */
39784
+
39785
+ /**
39786
+ *
39787
+ * Calculate user unread from {@link Amity.ChannelUnread} objects
39788
+ *
39789
+ * @returns the {@link Amity.UserUnread} objects
39790
+ *
39791
+ * @category Channel API
39792
+ * @async
39793
+ */
39794
+ const getTotalChannelsUnread$1 = () => {
39795
+ var _a;
39796
+ const client = getActiveClient();
39797
+ client.log('channel/getTotalChannelsUnread.locally');
39798
+ const cachedChannelsUnread = ((_a = queryCache(['channelUnread', 'get'])) === null || _a === void 0 ? void 0 : _a.filter(({ data }) => {
39799
+ return !data.isDeleted;
39800
+ })) || [];
39801
+ const totalChannelsUnread = (cachedChannelsUnread === null || cachedChannelsUnread === void 0 ? void 0 : cachedChannelsUnread.reduce((acc, { data }) => {
39802
+ acc.unreadCount += data.unreadCount;
39803
+ acc.isMentioned = acc.isMentioned || data.isMentioned;
39804
+ return acc;
39805
+ }, { unreadCount: 0, isMentioned: false })) || { unreadCount: 0, isMentioned: false };
39806
+ const cachedAt = client.cache && Date.now();
39807
+ return {
39808
+ data: totalChannelsUnread,
39809
+ cachedAt,
39810
+ };
39811
+ };
39812
+
39813
+ /* begin_public_function
39814
+ id: totalChannelsUnread.get
39815
+ */
39816
+ /**
39817
+ * ```js
39818
+ * import { ChannelRepository } from '@amityco/ts-sdk-react-native';
39819
+ *
39820
+ * let totalChannelsUnread;
39821
+ *
39822
+ * const unsubscribe = ChannelRepository.getTotalChannelsUnread(response => {
39823
+ * unread = response.data;
39824
+ * });
39825
+ * ```
39826
+ *
39827
+ * Observe all mutation on a given {@link Amity.UserUnread}
39828
+ *
39829
+ * @returns An {@link Amity.UserUnread} function to run when willing to stop observing the message
39830
+ *
39831
+ * @category User Unread Live Object
39832
+ *
39833
+ */
39834
+ const getTotalChannelsUnread = (callback) => {
39835
+ const { _id: userId } = getActiveUser();
39836
+ if (!userId)
39837
+ throw new ASCError('The _id has not been defined in ActiveUser', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
39838
+ const { log, cache } = getActiveClient();
39839
+ if (!cache) {
39840
+ console.log('For using Live Object feature you need to enable Cache!');
39841
+ }
39842
+ const timestamp = Date.now();
39843
+ log(`liveTotalChannelsUnread(tmpid: ${timestamp}) > listen`);
39844
+ const disposers = [];
39845
+ let isUnsyncedModel = false; // for messages
39846
+ let model;
39847
+ const dispatcher = (data) => {
39848
+ const { data: userUnread } = data;
39849
+ const callbackModel = userUnread
39850
+ ? {
39851
+ unreadCount: userUnread.unreadCount,
39852
+ isMentioned: userUnread.isMentioned,
39853
+ }
39854
+ : undefined;
39855
+ model = callbackModel ? convertGetterPropsToStatic(callbackModel) : callbackModel;
39856
+ callback({
39857
+ data: callbackModel
39858
+ ? Object.assign(Object.assign({}, callbackModel), { isMentioned: callbackModel.isMentioned }) : callbackModel,
39859
+ loading: data.loading,
39860
+ error: data.error,
39861
+ });
39862
+ };
39863
+ const realtimeRouter = (_) => {
39864
+ const { data: userUnread } = getTotalChannelsUnread$1();
39865
+ if (isEqual(model, userUnread))
39866
+ return;
39867
+ dispatcher({
39868
+ loading: false,
39869
+ data: userUnread,
39870
+ });
39871
+ };
39872
+ const onFetch = () => {
39873
+ const query = createQuery(async () => getTotalChannelsUnread$1());
39874
+ runQuery(query, ({ error, data, loading, origin, cachedAt }) => {
39875
+ if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
39876
+ dispatcher({
39877
+ data,
39878
+ origin,
39879
+ loading: false,
39880
+ error: new ASCApiError(UNSYNCED_OBJECT_CACHED_AT_MESSAGE, 800800 /* Amity.ClientError.DISALOOW_UNSYNCED_OBJECT */, "error" /* Amity.ErrorLevel.ERROR */),
39881
+ });
39882
+ isUnsyncedModel = true;
39883
+ disposers.forEach(fn => fn());
39884
+ }
39885
+ else if (!isUnsyncedModel) {
39886
+ dispatcher({ loading, data, origin, error });
39887
+ }
39888
+ if (error) {
39889
+ disposers.forEach(fn => fn());
39890
+ }
39891
+ });
39892
+ };
39893
+ disposers.push(onChannelUnreadUpdatedLocal(realtimeRouter));
39894
+ onFetch();
39895
+ return () => {
39896
+ disposers.forEach(fn => fn());
39897
+ };
39898
+ };
39899
+
39900
+ class ArchivedChannelPaginationController extends PaginationController {
39901
+ async getRequest(queryParams, token) {
39902
+ var _a, _b;
39903
+ const limit = (_a = queryParams.limit) !== null && _a !== void 0 ? _a : COLLECTION_DEFAULT_PAGINATION_LIMIT;
39904
+ const pageIndex = token ? Number.parseInt(token, 10) : 0;
39905
+ if (pageIndex === 0) {
39906
+ await getArchivedChannelIds();
39907
+ }
39908
+ const cached = (_b = queryCache(['archivedChannel', 'get'])) !== null && _b !== void 0 ? _b : [];
39909
+ const archives = cached
39910
+ .map(entry => entry.data)
39911
+ .slice()
39912
+ .sort((a, b) => Number(new Date(b.archivedAt)) - Number(new Date(a.archivedAt)));
39913
+ const start = pageIndex * limit;
39914
+ const end = start + limit;
39915
+ const slice = archives.slice(start, end);
39916
+ const hasMore = end < archives.length;
39917
+ if (slice.length > 0) {
39918
+ await getChannelByIds$1(slice.map(archive => archive.channelId));
39919
+ }
39920
+ return {
39921
+ archives: slice,
39922
+ paging: {
39923
+ next: hasMore ? String(pageIndex + 1) : undefined,
39924
+ previous: undefined,
39925
+ },
39926
+ };
39927
+ }
39928
+ }
39929
+
39930
+ class ArchivedChannelQueryStreamController extends QueryStreamController {
39931
+ constructor(query, cacheKey, notifyChange) {
39932
+ super(query, cacheKey);
39933
+ this.notifyChange = notifyChange;
39934
+ }
39935
+ async saveToMainDB(_response) {
39936
+ //
39937
+ }
39938
+ appendToQueryStream(response, direction, refresh = false) {
39939
+ var _a, _b;
39940
+ const channelIds = response.archives.map(archive => archive.channelId);
39941
+ if (refresh) {
39942
+ pushToCache(this.cacheKey, {
39943
+ data: channelIds,
39944
+ params: {},
39945
+ });
39946
+ return;
39947
+ }
39948
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
39949
+ const existing = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
39950
+ pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: direction === "prev" /* Amity.LiveCollectionPageDirection.PREV */
39951
+ ? [...new Set([...channelIds, ...existing])]
39952
+ : [...new Set([...existing, ...channelIds])] }));
39953
+ }
39954
+ reactor(action) {
39955
+ return (channelIds) => {
39956
+ var _a;
39957
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
39958
+ if (!collection)
39959
+ return;
39960
+ if (action === "onArchived" /* Amity.ChannelActionType.OnArchived */) {
39961
+ const filtered = collection.data.filter(id => !channelIds.includes(id));
39962
+ collection.data = [...channelIds, ...filtered];
39963
+ }
39964
+ if (action === "onUnarchived" /* Amity.ChannelActionType.OnUnarchived */ ||
39965
+ action === "onDelete" /* Amity.ChannelActionType.OnDelete */) {
39966
+ collection.data = collection.data.filter(id => !channelIds.includes(id));
39967
+ }
39968
+ pushToCache(this.cacheKey, collection);
39969
+ this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
39970
+ };
39971
+ }
39972
+ subscribeRTE(createSubscriber) {
39973
+ return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
39974
+ }
39975
+ }
39976
+
39977
+ class ArchivedChannelLiveCollectionController extends LiveCollectionController {
39978
+ constructor(query, callback) {
39979
+ const queryStreamId = hash(query);
39980
+ const cacheKey = ['archivedChannel', 'collection', queryStreamId];
39981
+ const paginationController = new ArchivedChannelPaginationController(query);
39982
+ super(paginationController, queryStreamId, cacheKey, callback);
39983
+ this.queryStreamController = new ArchivedChannelQueryStreamController(query, this.cacheKey, this.notifyChange.bind(this));
39984
+ this.callback = callback.bind(this);
39985
+ this.loadPage({ initial: true });
39986
+ }
39987
+ setup() {
39988
+ var _a;
39989
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
39990
+ if (!collection) {
39991
+ pushToCache(this.cacheKey, {
39992
+ data: [],
39993
+ params: {},
39994
+ });
39995
+ }
39996
+ }
39997
+ async persistModel(response) {
39998
+ await this.queryStreamController.saveToMainDB(response);
39999
+ }
40000
+ persistQueryStream({ response, direction, refresh, }) {
40001
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
40002
+ }
40003
+ startSubscription() {
40004
+ return this.queryStreamController.subscribeRTE([
40005
+ {
40006
+ fn: reactor => onChannelArchived(payload => reactor(payload.archives.map(archive => archive.channelId))),
40007
+ action: "onArchived" /* Amity.ChannelActionType.OnArchived */,
40008
+ },
40009
+ {
40010
+ fn: reactor => onChannelUnarchived(payload => reactor(payload.archives.map(archive => archive.channelId))),
40011
+ action: "onUnarchived" /* Amity.ChannelActionType.OnUnarchived */,
40012
+ },
40013
+ {
40014
+ fn: reactor => onChannelUpdated(channel => reactor([channel.channelId])),
40015
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
40016
+ },
40017
+ {
40018
+ fn: reactor => onChannelDeleted(channel => reactor([channel.channelId])),
40019
+ action: "onDelete" /* Amity.ChannelActionType.OnDelete */,
40020
+ },
40021
+ ]);
40022
+ }
40023
+ notifyChange({ origin, loading, error }) {
40024
+ var _a, _b;
40025
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
40026
+ if (!collection)
40027
+ return;
40028
+ const data = (_b = collection.data
40029
+ .map(channelId => pullFromCache(['channel', 'get', channelId]))
40030
+ .filter((entry) => Boolean(entry))
40031
+ .map(({ data: channel }) => channel)
40032
+ .map(constructChannelObject)) !== null && _b !== void 0 ? _b : [];
40033
+ if (!this.shouldNotify(data) && origin === 'event')
40034
+ return;
40035
+ this.callback({
40036
+ onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
40037
+ data,
40038
+ hasNextPage: !!this.paginationController.getNextToken(),
40039
+ loading,
40040
+ error,
40041
+ });
40042
+ }
40043
+ }
40044
+
40045
+ /* begin_public_function
40046
+ id: channel.archive.collection
40047
+ */
40048
+ /**
40049
+ * ```js
40050
+ * import { ChannelRepository } from '@amityco/ts-sdk'
40051
+ *
40052
+ * let channels = []
40053
+ * const unsub = ChannelRepository.getArchivedChannels(params, response => merge(channels, response.data))
40054
+ * ```
40055
+ *
40056
+ * Live collection of {@link Amity.Channel}s archived by the active user.
40057
+ *
40058
+ * @param params Live collection parameters (only `limit` is honored; the
40059
+ * archive list takes no other filters).
40060
+ * @param callback the function to call when new data are available
40061
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to
40062
+ * stop observing.
40063
+ *
40064
+ * @category Channel Live Collection
40065
+ */
40066
+ const getArchivedChannels = (params, callback) => {
40067
+ const { log, cache } = getActiveClient();
40068
+ if (!cache) {
40069
+ console.log(ENABLE_CACHE_MESSAGE);
40070
+ }
40071
+ const timestamp = Date.now();
40072
+ log(`getArchivedChannels(tmpid: ${timestamp}) > listen`);
40073
+ const controller = new ArchivedChannelLiveCollectionController(params, callback);
40074
+ const disposers = controller.startSubscription();
40075
+ const cacheKey = controller.getCacheKey();
40076
+ disposers.push(() => {
40077
+ dropFromCache(cacheKey);
40078
+ });
40079
+ return () => {
40080
+ log(`getArchivedChannels(tmpid: ${timestamp}) > dispose`);
40081
+ disposers.forEach(fn => fn());
40082
+ };
40083
+ };
40084
+ /* end_public_function */
40085
+
40086
+ class SearchChannelPaginationController extends PaginationController {
40087
+ async getRequest(queryParams, token) {
40088
+ const { query, exactMatch, isMemberOnly, types, tags, sortBy, orderBy, limit = COLLECTION_DEFAULT_PAGINATION_SIZE, } = queryParams;
40089
+ const options = token ? { token } : { limit: Math.min(100, Math.max(1, limit)) };
40090
+ const { data: queryResponse } = await this.http.get(`/api/v2/search/channels`, {
40091
+ params: {
40092
+ query,
40093
+ exactMatch,
40094
+ isMemberOnly,
40095
+ types,
40096
+ tags,
40097
+ sortBy,
40098
+ orderBy,
40099
+ options,
40100
+ },
40101
+ });
40102
+ return queryResponse;
40103
+ }
40104
+ }
40105
+
40106
+ class SearchChannelQueryStreamController extends QueryStreamController {
40107
+ constructor(query, cacheKey, notifyChange) {
40108
+ super(query, cacheKey);
40109
+ this.notifyChange = notifyChange;
40110
+ }
40111
+ async saveToMainDB(response) {
40112
+ const processedPayload = await prepareChannelPayload(response);
40113
+ const client = getActiveClient();
40114
+ const cachedAt = client.cache && Date.now();
40115
+ if (client.cache) {
40116
+ ingestInCache(processedPayload, { cachedAt });
40117
+ }
40118
+ }
40119
+ appendToQueryStream(response, direction, refresh = false) {
40120
+ var _a, _b;
40121
+ if (refresh) {
40122
+ pushToCache(this.cacheKey, {
40123
+ data: response.channels.map(getResolver('channel')),
40124
+ });
40125
+ return;
40126
+ }
40127
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
40128
+ const existing = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
40129
+ const incoming = response.channels.map(getResolver('channel'));
40130
+ pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: direction === "prev" /* Amity.LiveCollectionPageDirection.PREV */
40131
+ ? [...new Set([...incoming, ...existing])]
40132
+ : [...new Set([...existing, ...incoming])] }));
40133
+ }
40134
+ reactor() {
40135
+ return () => this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
40136
+ }
40137
+ subscribeRTE(createSubscriber) {
40138
+ return createSubscriber.map(subscriber => subscriber.fn(this.reactor()));
40139
+ }
40140
+ }
40141
+
40142
+ /* eslint-disable no-use-before-define */
40143
+ const getMessagePreviewSetting = () => {
40144
+ const client = getActiveClient();
40145
+ return client.getMessagePreviewSetting(false);
40146
+ };
40147
+ class SearchChannelLiveCollectionController extends LiveCollectionController {
40148
+ constructor(query, callback) {
40149
+ const queryStreamId = hash(query);
40150
+ const cacheKey = ['channel', 'search', queryStreamId];
40151
+ const paginationController = new SearchChannelPaginationController(query);
40152
+ super(paginationController, queryStreamId, cacheKey, callback);
40153
+ this.queryStreamController = new SearchChannelQueryStreamController(query, this.cacheKey, this.notifyChange.bind(this));
40154
+ this.callback = callback.bind(this);
40155
+ this.loadPage({ initial: true });
40156
+ }
40157
+ startSubscription() {
40158
+ return this.queryStreamController.subscribeRTE(this.getSubscriptions());
40159
+ }
40160
+ notifyChange({ origin, loading, error }) {
40161
+ var _a, _b;
40162
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
40163
+ if (!collection)
40164
+ return;
40165
+ const data = (_b = collection.data
40166
+ .map(channelId => pullFromCache(['channel', 'get', channelId]))
40167
+ .filter(Boolean)
40168
+ .map(cached => constructChannelObject(cached.data))) !== null && _b !== void 0 ? _b : [];
40169
+ if (!this.shouldNotify(data) && origin === 'event')
40170
+ return;
40171
+ this.callback({
40172
+ onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
40173
+ data,
40174
+ hasNextPage: !!this.paginationController.getNextToken(),
40175
+ loading,
40176
+ error,
40177
+ });
40178
+ }
40179
+ setup() {
40180
+ var _a;
40181
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
40182
+ if (!collection) {
40183
+ pushToCache(this.cacheKey, {
40184
+ data: [],
40185
+ params: {},
40186
+ });
40187
+ }
40188
+ }
40189
+ async persistModel(response) {
40190
+ await this.queryStreamController.saveToMainDB(response);
40191
+ }
40192
+ persistQueryStream({ response, direction, refresh, }) {
40193
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
40194
+ }
40195
+ shouldAbort(targetChannelId) {
40196
+ var _a;
40197
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
40198
+ if (!collection)
40199
+ return true;
40200
+ return !collection.data.find(channelId => channelId === targetChannelId);
40201
+ }
40202
+ getSubscriptions() {
40203
+ return [
40204
+ {
40205
+ fn: convertEventPayload((callback) => {
40206
+ return onMessageCreatedMqtt(message => {
40207
+ var _a;
40208
+ const cacheData = (_a = pullFromCache([
40209
+ 'channel',
40210
+ 'get',
40211
+ message.channelId,
40212
+ ])) === null || _a === void 0 ? void 0 : _a.data;
40213
+ if (!cacheData)
40214
+ return;
40215
+ updateChannelCache(cacheData, {
40216
+ lastActivity: message.createdAt,
40217
+ });
40218
+ callback(message);
40219
+ });
40220
+ }, 'channelId', 'channel'),
40221
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
40222
+ },
40223
+ {
40224
+ fn: convertEventPayload((callback) => {
40225
+ return onMessageCreatedLocal(message => {
40226
+ var _a;
40227
+ const cacheData = (_a = pullFromCache([
40228
+ 'channel',
40229
+ 'get',
40230
+ message.channelId,
40231
+ ])) === null || _a === void 0 ? void 0 : _a.data;
40232
+ if (!cacheData)
40233
+ return;
40234
+ updateChannelCache(cacheData, {
40235
+ lastActivity: message.createdAt,
40236
+ });
40237
+ callback(message);
40238
+ });
40239
+ }, 'channelId', 'channel'),
40240
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
40241
+ },
40242
+ { fn: onChannelDeleted, action: "onDelete" /* Amity.ChannelActionType.OnDelete */ },
40243
+ { fn: onChannelUpdated, action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */ },
40244
+ { fn: onChannelSetMuted, action: "onMute" /* Amity.ChannelActionType.OnMute */ },
40245
+ {
40246
+ fn: (reactor) => onChannelArchived(payload => {
40247
+ const channels = payload.archives
40248
+ .map(archive => {
40249
+ var _a;
40250
+ return (_a = pullFromCache(['channel', 'get', archive.channelId])) === null || _a === void 0 ? void 0 : _a.data;
40251
+ })
40252
+ .filter((c) => Boolean(c));
40253
+ if (channels.length > 0)
40254
+ reactor(channels);
40255
+ }),
40256
+ action: "onArchived" /* Amity.ChannelActionType.OnArchived */,
40257
+ },
40258
+ {
40259
+ fn: (reactor) => onChannelUnarchived(payload => {
40260
+ const channels = payload.archives
40261
+ .map(archive => {
40262
+ var _a;
40263
+ return (_a = pullFromCache(['channel', 'get', archive.channelId])) === null || _a === void 0 ? void 0 : _a.data;
40264
+ })
40265
+ .filter((c) => Boolean(c));
40266
+ if (channels.length > 0)
40267
+ reactor(channels);
40268
+ }),
40269
+ action: "onUnarchived" /* Amity.ChannelActionType.OnUnarchived */,
40270
+ },
40271
+ {
40272
+ fn: convertEventPayload(onChannelMarkerFetched, 'entityId', 'channel'),
40273
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
40274
+ },
40275
+ {
40276
+ fn: convertEventPayload(onChannelMarkerUpdated, 'entityId', 'channel'),
40277
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
40278
+ },
40279
+ {
40280
+ fn: convertEventPayload((callback) => {
40281
+ const updateMessagePreview = async (message) => {
40282
+ var _a;
40283
+ const messagePreviewSetting = await getMessagePreviewSetting();
40284
+ if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */)
40285
+ return;
40286
+ handleMessageCreated(message);
40287
+ if (this.shouldAbort(message.channelId))
40288
+ return;
40289
+ const channel = (_a = pullFromCache([
40290
+ 'channel',
40291
+ 'get',
40292
+ message.channelId,
40293
+ ])) === null || _a === void 0 ? void 0 : _a.data;
40294
+ if (!channel)
40295
+ return;
40296
+ updateChannelCache(channel, {
40297
+ messagePreviewId: message.messageId,
40298
+ });
40299
+ callback(message);
40300
+ };
40301
+ return onMessageCreatedMqtt(updateMessagePreview);
40302
+ }, 'channelId', 'channel'),
40303
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
40304
+ },
40305
+ {
40306
+ fn: convertEventPayload((callback) => {
40307
+ const updateMessagePreview = async (message) => {
40308
+ var _a;
40309
+ const messagePreviewSetting = await getMessagePreviewSetting();
40310
+ if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */)
40311
+ return;
40312
+ handleMessageCreated(message);
40313
+ if (this.shouldAbort(message.channelId))
40314
+ return;
40315
+ const channel = (_a = pullFromCache([
40316
+ 'channel',
40317
+ 'get',
40318
+ message.channelId,
40319
+ ])) === null || _a === void 0 ? void 0 : _a.data;
40320
+ if (!channel)
40321
+ return;
40322
+ updateChannelCache(channel, {
40323
+ messagePreviewId: message.messageId,
40324
+ });
40325
+ callback(message);
40326
+ };
40327
+ return onMessageCreatedLocal(updateMessagePreview);
40328
+ }, 'channelId', 'channel'),
40329
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
40330
+ },
40331
+ {
40332
+ fn: convertEventPayload((callback) => {
40333
+ const updateMessagePreview = async (message) => {
40334
+ const messagePreviewSetting = await getMessagePreviewSetting();
40335
+ if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */)
40336
+ return;
40337
+ handleMessageUpdated(message);
40338
+ if (this.shouldAbort(message.channelId))
40339
+ return;
40340
+ callback(message);
40341
+ };
40342
+ return onMessageUpdated(updateMessagePreview);
40343
+ }, 'channelId', 'channel'),
40344
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
40345
+ },
40346
+ {
40347
+ fn: convertEventPayload((callback) => {
40348
+ const updateMessagePreview = async (message) => {
40349
+ const messagePreviewSetting = await getMessagePreviewSetting();
40350
+ if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */)
40351
+ return;
40352
+ if (messagePreviewSetting ===
40353
+ "message-preview-include-deleted" /* Amity.MessagePreviewSetting.MESSAGE_PREVIEW_INCLUDE_DELETED */)
40354
+ await handleMessageUpdated(message);
40355
+ if (this.shouldAbort(message.channelId))
40356
+ return;
40357
+ if (messagePreviewSetting ===
40358
+ "message-preview-not-include-deleted" /* Amity.MessagePreviewSetting.MESSAGE_PREVIEW_NOT_INCLUDE_DELETED */) {
40359
+ await getChannel$1(message.channelId);
40360
+ }
40361
+ callback(message);
40362
+ };
40363
+ return onMessageDeleted(updateMessagePreview);
40364
+ }, 'channelId', 'channel'),
40365
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
40366
+ },
40367
+ {
40368
+ fn: convertEventPayload((callback) => {
40369
+ const updateMessagePreview = async (subChannel) => {
40370
+ var _a;
40371
+ const collections = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
40372
+ if (!collections)
40373
+ return;
40374
+ const channelId = collections.data.find(channel => {
40375
+ const messagePreviewCache = getChannelMessagePreview(channel);
40376
+ return (messagePreviewCache === null || messagePreviewCache === void 0 ? void 0 : messagePreviewCache.subChannelId) === subChannel.subChannelId;
40377
+ });
40378
+ if (!channelId)
40379
+ return;
40380
+ await getChannel$1(subChannel.channelId);
40381
+ callback(subChannel);
40382
+ };
40383
+ return onSubChannelDeleted(updateMessagePreview);
40384
+ }, 'channelId', 'channel'),
40385
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
40386
+ },
40387
+ {
40388
+ fn: convertEventPayload((callback) => {
40389
+ const updateMessagePreview = async (subChannel) => {
40390
+ var _a;
40391
+ const messagePreviewSetting = await getMessagePreviewSetting();
40392
+ if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */)
40393
+ return;
40394
+ const collections = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
40395
+ if (!collections)
40396
+ return;
40397
+ await handleSubChannelUpdated(subChannel);
40398
+ if (this.shouldAbort(subChannel.channelId))
40399
+ return;
40400
+ callback(subChannel);
40401
+ };
40402
+ return onSubChannelUpdated(updateMessagePreview);
40403
+ }, 'channelId', 'channel'),
40404
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
40405
+ },
40406
+ {
40407
+ fn: (callback) => {
40408
+ const handleUserFeedMarkerResolved = async (marker) => {
40409
+ if (marker.feedMarkers) {
40410
+ const channels = marker.feedMarkers
40411
+ .map(feedMarker => {
40412
+ var _a;
40413
+ return (_a = pullFromCache([
40414
+ 'channel',
40415
+ 'get',
40416
+ feedMarker.entityId,
40417
+ ])) === null || _a === void 0 ? void 0 : _a.data;
40418
+ })
40419
+ .filter(Boolean);
40420
+ callback(channels);
40421
+ }
40422
+ };
40423
+ return onUserMessageFeedMarkerResolved(handleUserFeedMarkerResolved);
40424
+ },
40425
+ action: "OnResolveUnread" /* Amity.ChannelActionType.OnResolveUnread */,
40426
+ },
40427
+ {
40428
+ fn: convertEventPayload(onChannelUnreadInfoUpdatedLocal, 'channelId', 'channel'),
40429
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
40430
+ },
40431
+ {
40432
+ fn: convertEventPayload((callback) => {
40433
+ const processPayload = (payloads) => {
40434
+ payloads.forEach(callback);
40435
+ };
40436
+ return onChannelUnreadUpdatedLocal(processPayload);
40437
+ }, 'channelId', 'channel'),
40438
+ action: "onUpdate" /* Amity.ChannelActionType.OnUpdate */,
40439
+ },
40440
+ ];
38510
40441
  }
38511
40442
  }
38512
40443
 
38513
- /* eslint-disable no-use-before-define */
38514
40444
  /* begin_public_function
38515
- id: channel.query
40445
+ id: channel.search
38516
40446
  */
38517
40447
  /**
38518
40448
  * ```js
38519
- * import { getChannels } from '@amityco/ts-sdk-react-native'
40449
+ * import { ChannelRepository } from '@amityco/ts-sdk';
38520
40450
  *
38521
- * let channels = []
38522
- * const unsub = getChannels({
38523
- * displayName: Amity.Channel['displayName'],
38524
- * }, response => merge(channels, response.data))
40451
+ * const unsubscribe = ChannelRepository.searchChannels(
40452
+ * { query: 'hello' },
40453
+ * response => response.data,
40454
+ * );
38525
40455
  * ```
38526
40456
  *
38527
- * Observe all mutations on a list of {@link Amity.Channel}s
40457
+ * Live collection of {@link Amity.Channel}s matching the search query. Backed by
40458
+ * `GET /api/v2/search/channels`.
38528
40459
  *
38529
- * @param params for querying channels
38530
- * @param callback the function to call when new data are available
38531
- * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the channels
40460
+ * @param params Search parameters.
40461
+ * @param callback Called whenever new data are available.
40462
+ * @returns An {@link Amity.Unsubscriber} function to stop observing.
38532
40463
  *
38533
40464
  * @category Channel Live Collection
38534
40465
  */
38535
- const getChannels = (params, callback, config) => {
38536
- const { log, cache, userId } = getActiveClient();
38537
- if (!cache) {
40466
+ const searchChannels = (params, callback) => {
40467
+ const { log, cache } = getActiveClient();
40468
+ if (!cache)
38538
40469
  console.log(ENABLE_CACHE_MESSAGE);
38539
- }
38540
40470
  const timestamp = Date.now();
38541
- log(`getChannels(tmpid: ${timestamp}) > listen`);
38542
- const channelLiveCollection = new ChannelLiveCollectionController(params, callback);
38543
- const disposers = channelLiveCollection.startSubscription();
38544
- const cacheKey = channelLiveCollection.getCacheKey();
40471
+ log(`searchChannels(tmpid: ${timestamp}) > listen`);
40472
+ const searchChannelLiveCollection = new SearchChannelLiveCollectionController(params, callback);
40473
+ const disposers = searchChannelLiveCollection.startSubscription();
40474
+ const cacheKey = searchChannelLiveCollection.getCacheKey();
38545
40475
  disposers.push(() => {
38546
40476
  dropFromCache(cacheKey);
38547
40477
  });
38548
40478
  return () => {
38549
- log(`getChannels(tmpid: ${timestamp}) > dispose`);
40479
+ log(`searchChannels(tmpid: ${timestamp}) > dispose`);
38550
40480
  disposers.forEach(fn => fn());
38551
40481
  };
38552
40482
  };
38553
40483
  /* end_public_function */
38554
40484
 
38555
- /**
38556
- *
38557
- * Calculate user unread from {@link Amity.ChannelUnread} objects
38558
- *
38559
- * @returns the {@link Amity.UserUnread} objects
38560
- *
38561
- * @category Channel API
38562
- * @async
38563
- */
38564
- const getTotalChannelsUnread$1 = () => {
38565
- var _a;
38566
- const client = getActiveClient();
38567
- client.log('channel/getTotalChannelsUnread.locally');
38568
- const cachedChannelsUnread = ((_a = queryCache(['channelUnread', 'get'])) === null || _a === void 0 ? void 0 : _a.filter(({ data }) => {
38569
- return !data.isDeleted;
38570
- })) || [];
38571
- const totalChannelsUnread = (cachedChannelsUnread === null || cachedChannelsUnread === void 0 ? void 0 : cachedChannelsUnread.reduce((acc, { data }) => {
38572
- acc.unreadCount += data.unreadCount;
38573
- acc.isMentioned = acc.isMentioned || data.isMentioned;
38574
- return acc;
38575
- }, { unreadCount: 0, isMentioned: false })) || { unreadCount: 0, isMentioned: false };
38576
- const cachedAt = client.cache && Date.now();
38577
- return {
38578
- data: totalChannelsUnread,
38579
- cachedAt,
38580
- };
38581
- };
38582
-
38583
- /* begin_public_function
38584
- id: totalChannelsUnread.get
38585
- */
38586
- /**
38587
- * ```js
38588
- * import { ChannelRepository } from '@amityco/ts-sdk-react-native';
38589
- *
38590
- * let totalChannelsUnread;
38591
- *
38592
- * const unsubscribe = ChannelRepository.getTotalChannelsUnread(response => {
38593
- * unread = response.data;
38594
- * });
38595
- * ```
38596
- *
38597
- * Observe all mutation on a given {@link Amity.UserUnread}
38598
- *
38599
- * @returns An {@link Amity.UserUnread} function to run when willing to stop observing the message
38600
- *
38601
- * @category User Unread Live Object
38602
- *
38603
- */
38604
- const getTotalChannelsUnread = (callback) => {
38605
- const { _id: userId } = getActiveUser();
38606
- if (!userId)
38607
- throw new ASCError('The _id has not been defined in ActiveUser', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
38608
- const { log, cache } = getActiveClient();
38609
- if (!cache) {
38610
- console.log('For using Live Object feature you need to enable Cache!');
38611
- }
38612
- const timestamp = Date.now();
38613
- log(`liveTotalChannelsUnread(tmpid: ${timestamp}) > listen`);
38614
- const disposers = [];
38615
- let isUnsyncedModel = false; // for messages
38616
- let model;
38617
- const dispatcher = (data) => {
38618
- const { data: userUnread } = data;
38619
- const callbackModel = userUnread
38620
- ? {
38621
- unreadCount: userUnread.unreadCount,
38622
- isMentioned: userUnread.isMentioned,
38623
- }
38624
- : undefined;
38625
- model = callbackModel ? convertGetterPropsToStatic(callbackModel) : callbackModel;
38626
- callback({
38627
- data: callbackModel
38628
- ? Object.assign(Object.assign({}, callbackModel), { isMentioned: callbackModel.isMentioned }) : callbackModel,
38629
- loading: data.loading,
38630
- error: data.error,
38631
- });
38632
- };
38633
- const realtimeRouter = (_) => {
38634
- const { data: userUnread } = getTotalChannelsUnread$1();
38635
- if (isEqual(model, userUnread))
38636
- return;
38637
- dispatcher({
38638
- loading: false,
38639
- data: userUnread,
38640
- });
38641
- };
38642
- const onFetch = () => {
38643
- const query = createQuery(async () => getTotalChannelsUnread$1());
38644
- runQuery(query, ({ error, data, loading, origin, cachedAt }) => {
38645
- if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
38646
- dispatcher({
38647
- data,
38648
- origin,
38649
- loading: false,
38650
- error: new ASCApiError(UNSYNCED_OBJECT_CACHED_AT_MESSAGE, 800800 /* Amity.ClientError.DISALOOW_UNSYNCED_OBJECT */, "error" /* Amity.ErrorLevel.ERROR */),
38651
- });
38652
- isUnsyncedModel = true;
38653
- disposers.forEach(fn => fn());
38654
- }
38655
- else if (!isUnsyncedModel) {
38656
- dispatcher({ loading, data, origin, error });
38657
- }
38658
- if (error) {
38659
- disposers.forEach(fn => fn());
38660
- }
38661
- });
38662
- };
38663
- disposers.push(onChannelUnreadUpdatedLocal(realtimeRouter));
38664
- onFetch();
38665
- return () => {
38666
- disposers.forEach(fn => fn());
38667
- };
38668
- };
38669
-
38670
40485
  /* begin_public_function
38671
40486
  id: channel.member.add
38672
40487
  */
@@ -38798,7 +40613,9 @@ class ChannelMemberQueryStreamController extends QueryStreamController {
38798
40613
  channelId: this.query.channelId,
38799
40614
  userId: channelMember.userId,
38800
40615
  });
38801
- if (channelMember.membership === 'none') {
40616
+ const membershipFilter = this.query.memberships;
40617
+ const isInFilter = !membershipFilter || membershipFilter.includes(channelMember.membership);
40618
+ if (channelMember.membership === 'none' || !isInFilter) {
38802
40619
  collection.data = collection.data.filter(m => m !== channelMemberCacheId);
38803
40620
  }
38804
40621
  else if (!collection.data.includes(channelMemberCacheId)) {
@@ -39134,6 +40951,7 @@ const banMembers$1 = async (channelId, userIds) => {
39134
40951
  const cachedAt = client.cache && Date.now();
39135
40952
  if (client.cache)
39136
40953
  ingestInCache(preparedPayload, { cachedAt });
40954
+ fireEvent('channel.banned', payload);
39137
40955
  return {
39138
40956
  data: channelUsers === null || channelUsers === void 0 ? void 0 : channelUsers.filter(user => user.membership === 'banned'),
39139
40957
  cachedAt,
@@ -39168,6 +40986,7 @@ const unbanMembers$1 = async (channelId, userIds) => {
39168
40986
  const cachedAt = client.cache && Date.now();
39169
40987
  if (client.cache)
39170
40988
  ingestInCache(preparedPayload, { cachedAt });
40989
+ fireEvent('channel.unbanned', payload);
39171
40990
  const { channelUsers } = preparedPayload;
39172
40991
  return {
39173
40992
  data: channelUsers === null || channelUsers === void 0 ? void 0 : channelUsers.filter(user => user.membership === 'member'),
@@ -39196,6 +41015,7 @@ const MUTE_FOREVER = -1;
39196
41015
  * @async
39197
41016
  * */
39198
41017
  const muteMembers = async (channelId, userIds, mutePeriod = MUTE_FOREVER) => {
41018
+ var _a;
39199
41019
  const client = getActiveClient();
39200
41020
  client.log('channel/muteMembers', { userIds, channelId, mutePeriod });
39201
41021
  const { data } = await client.http.put(`/api/v2/channel/${channelId}/users/mute`, {
@@ -39203,6 +41023,15 @@ const muteMembers = async (channelId, userIds, mutePeriod = MUTE_FOREVER) => {
39203
41023
  mutePeriod: mutePeriod === MUTE_FOREVER ? mutePeriod : mutePeriod * 1000,
39204
41024
  });
39205
41025
  const { success } = data;
41026
+ const muteTimeout = mutePeriod === MUTE_FOREVER
41027
+ ? new Date('9999-12-31T23:59:59.999Z').toISOString()
41028
+ : new Date(Date.now() + mutePeriod * 1000).toISOString();
41029
+ fireEvent('channel.setMutedUsers', {
41030
+ channelId,
41031
+ userIds,
41032
+ muteTimeout,
41033
+ actor: (_a = client.userId) !== null && _a !== void 0 ? _a : '',
41034
+ });
39206
41035
  return success;
39207
41036
  };
39208
41037
  /* end_public_function */
@@ -39225,6 +41054,7 @@ const muteMembers = async (channelId, userIds, mutePeriod = MUTE_FOREVER) => {
39225
41054
  * @async
39226
41055
  * */
39227
41056
  const unmuteMembers = async (channelId, userIds) => {
41057
+ var _a;
39228
41058
  const client = getActiveClient();
39229
41059
  client.log('channel/unmuteMembers', { userIds, channelId });
39230
41060
  const { data } = await client.http.put(`/api/v2/channel/${encodeURIComponent(channelId)}/users/mute`, {
@@ -39232,6 +41062,12 @@ const unmuteMembers = async (channelId, userIds) => {
39232
41062
  mutePeriod: 0,
39233
41063
  });
39234
41064
  const { success } = data;
41065
+ fireEvent('channel.setMutedUsers', {
41066
+ channelId,
41067
+ userIds,
41068
+ muteTimeout: new Date(0).toISOString(),
41069
+ actor: (_a = client.userId) !== null && _a !== void 0 ? _a : '',
41070
+ });
39235
41071
  return success;
39236
41072
  };
39237
41073
  /* end_public_function */
@@ -39258,6 +41094,9 @@ var index$j = /*#__PURE__*/Object.freeze({
39258
41094
  leaveChannel: leaveChannel,
39259
41095
  muteChannel: muteChannel,
39260
41096
  unmuteChannel: unmuteChannel,
41097
+ archiveChannel: archiveChannel,
41098
+ unarchiveChannel: unarchiveChannel,
41099
+ getArchivedChannelIds: getArchivedChannelIds,
39261
41100
  onChannelCreated: onChannelCreated,
39262
41101
  onChannelUpdated: onChannelUpdated,
39263
41102
  onChannelDeleted: onChannelDeleted,
@@ -39270,9 +41109,13 @@ var index$j = /*#__PURE__*/Object.freeze({
39270
41109
  onChannelMemberUnbanned: onChannelMemberUnbanned,
39271
41110
  onChannelMemberRoleAdded: onChannelMemberRoleAdded,
39272
41111
  onChannelMemberRoleRemoved: onChannelMemberRoleRemoved,
41112
+ onChannelArchived: onChannelArchived,
41113
+ onChannelUnarchived: onChannelUnarchived,
39273
41114
  getChannel: getChannel,
39274
41115
  getChannels: getChannels,
39275
41116
  getTotalChannelsUnread: getTotalChannelsUnread,
41117
+ getArchivedChannels: getArchivedChannels,
41118
+ searchChannels: searchChannels,
39276
41119
  MARKER_INCLUDED_CHANNEL_TYPE: MARKER_INCLUDED_CHANNEL_TYPE,
39277
41120
  isUnreadCountSupport: isUnreadCountSupport,
39278
41121
  convertFromRaw: convertFromRaw,
@@ -43169,7 +45012,7 @@ class CommentLiveCollectionController extends LiveCollectionController {
43169
45012
  this.queryStreamController.appendToQueryStream(response, direction, refresh);
43170
45013
  }
43171
45014
  startSubscription() {
43172
- return this.queryStreamController.subscribeRTE([
45015
+ const disposers = this.queryStreamController.subscribeRTE([
43173
45016
  { fn: onCommentCreatedLocal, action: EnumCommentActions.OnCommentCreated },
43174
45017
  { fn: onCommentDeleteLocal, action: EnumCommentActions.OnCommentDeleted },
43175
45018
  { fn: onCommentCreated, action: EnumCommentActions.OnCommentCreated },
@@ -43182,6 +45025,11 @@ class CommentLiveCollectionController extends LiveCollectionController {
43182
45025
  { fn: onLocalCommentReactionAdded, action: EnumCommentActions.OnCommentReactionAdded },
43183
45026
  { fn: onLocalCommentReactionRemoved, action: EnumCommentActions.OnCommentReactionRemoved },
43184
45027
  ]);
45028
+ if (this.query.excludeBlockUserComments) {
45029
+ const refresh = () => this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
45030
+ disposers.push(onUserDidBlock(refresh), onUserDidUnblock(refresh));
45031
+ }
45032
+ return disposers;
43185
45033
  }
43186
45034
  notifyChange({ origin, loading, error }) {
43187
45035
  var _a, _b;
@@ -43234,6 +45082,9 @@ class CommentLiveCollectionController extends LiveCollectionController {
43234
45082
  comments = comments.filter(comment => { var _a; return (_a = this.query.dataTypes) === null || _a === void 0 ? void 0 : _a.values.some(value => { var _a; return (_a = comment.dataTypes) === null || _a === void 0 ? void 0 : _a.includes(value); }); });
43235
45083
  }
43236
45084
  }
45085
+ if (this.query.excludeBlockUserComments) {
45086
+ comments = filterCommentsByBlockUsers(comments);
45087
+ }
43237
45088
  switch (this.query.sortBy) {
43238
45089
  case 'firstCreated':
43239
45090
  comments = comments.sort(sortByFirstCreated);
@@ -44319,13 +46170,253 @@ const getCommunityFeed = (params, callback, config) => {
44319
46170
  };
44320
46171
  /* end_public_function */
44321
46172
 
46173
+ /**
46174
+ * Thrown by `getForYouFeed` when the network has the For You feature
46175
+ * disabled. Mapped from HTTP 404 NOT_FOUND. Distinct from a generic
46176
+ * not-found so consumers can hide the For You tab without retrying.
46177
+ *
46178
+ * @category Errors
46179
+ */
46180
+ class AmityForYouFeedDisabledError extends ASCApiError {
46181
+ constructor(message = 'For You feed is not enabled for this network') {
46182
+ super(message, 400400 /* Amity.ServerError.ITEM_NOT_FOUND */, "error" /* Amity.ErrorLevel.ERROR */);
46183
+ this.type = 'AmityForYouFeedDisabledError';
46184
+ }
46185
+ }
46186
+
46187
+ class ForYouFeedPaginationController extends PaginationController {
46188
+ constructor(query) {
46189
+ super(query);
46190
+ this.checkedDisk = false;
46191
+ this.hasDeliveredPost = false;
46192
+ this.cursor = CursorController.current();
46193
+ }
46194
+ async getRequest(_queryParams, token) {
46195
+ var _a, _b, _c, _d, _e;
46196
+ const isFirstPage = token === undefined;
46197
+ let stored = null;
46198
+ // On the first page of a fresh collection, load the saved cursor from disk once.
46199
+ // Drop it if the snapshot has already expired so we start fresh.
46200
+ if (isFirstPage && !this.checkedDisk && this.cursor) {
46201
+ this.checkedDisk = true;
46202
+ stored = await this.cursor.get();
46203
+ if (stored && CursorController.isExpired(stored.expiredAt)) {
46204
+ await this.cursor.clear();
46205
+ stored = null;
46206
+ }
46207
+ }
46208
+ // Already paged to the end before. Ask the BE fresh (no cursor) and check if it's
46209
+ // still the same snapshot the user finished.
46210
+ if (isFirstPage && (stored === null || stored === void 0 ? void 0 : stored.reachedEndOfFeed)) {
46211
+ const fresh = await this.fetch();
46212
+ const freshExpiredAt = Date.parse((_b = (_a = fresh.paging) === null || _a === void 0 ? void 0 : _a.expiredAt) !== null && _b !== void 0 ? _b : '');
46213
+ const rolledOver = !Number.isNaN(freshExpiredAt) && freshExpiredAt !== stored.expiredAt;
46214
+ // New snapshot → serve it. Same snapshot → user has seen it all, show empty.
46215
+ if (rolledOver) {
46216
+ await this.persistCursor(fresh);
46217
+ if (fresh.posts.length > 0)
46218
+ this.hasDeliveredPost = true;
46219
+ return fresh;
46220
+ }
46221
+ return Object.assign(Object.assign({}, fresh), { posts: [], paging: {} });
46222
+ }
46223
+ // Resume from the saved cursor on re-entry; otherwise use the live-collection token.
46224
+ const effectiveToken = isFirstPage && stored ? stored.cursor : token;
46225
+ const response = await this.fetch(effectiveToken);
46226
+ if (response.posts.length > 0)
46227
+ this.hasDeliveredPost = true;
46228
+ if ((_c = response.paging) === null || _c === void 0 ? void 0 : _c.next) {
46229
+ // More pages left → advance the saved cursor.
46230
+ await this.persistCursor(response);
46231
+ }
46232
+ else if (this.hasDeliveredPost && this.cursor) {
46233
+ // Reached the end and mark end of feed
46234
+ const expiredAt = Date.parse((_e = (_d = response.paging) === null || _d === void 0 ? void 0 : _d.expiredAt) !== null && _e !== void 0 ? _e : '');
46235
+ if (!Number.isNaN(expiredAt))
46236
+ await this.cursor.markReachedEndOfFeed(expiredAt);
46237
+ }
46238
+ return response;
46239
+ }
46240
+ async fetch(token) {
46241
+ const options = { limit: COLLECTION_DEFAULT_PAGINATION_SIZE };
46242
+ if (token)
46243
+ options.token = token;
46244
+ try {
46245
+ const { data } = await this.http.get(API_ENDPOINTS.forYouFeed, {
46246
+ params: { options },
46247
+ });
46248
+ return data;
46249
+ }
46250
+ catch (error) {
46251
+ if (error instanceof ASCApiError && error.code === 400300 /* Amity.ServerError.FORBIDDEN */) {
46252
+ throw new AmityForYouFeedDisabledError();
46253
+ }
46254
+ const recoverable = error instanceof ASCApiError && error.code === 400322 /* Amity.ServerError.FEED_SNAPSHOT_EXPIRED */;
46255
+ if (recoverable && token !== undefined) {
46256
+ if (this.cursor)
46257
+ await this.cursor.clear();
46258
+ const { data } = await this.http.get(API_ENDPOINTS.forYouFeed, {
46259
+ params: { options: { limit: COLLECTION_DEFAULT_PAGINATION_SIZE } },
46260
+ });
46261
+ return data;
46262
+ }
46263
+ throw error;
46264
+ }
46265
+ }
46266
+ async persistCursor(response) {
46267
+ var _a, _b;
46268
+ if (!this.cursor)
46269
+ return;
46270
+ const cursor = (_a = response.paging) === null || _a === void 0 ? void 0 : _a.next;
46271
+ const expiredAtIso = (_b = response.paging) === null || _b === void 0 ? void 0 : _b.expiredAt;
46272
+ if (!cursor || !expiredAtIso)
46273
+ return;
46274
+ const expiredAt = Date.parse(expiredAtIso);
46275
+ if (Number.isNaN(expiredAt))
46276
+ return;
46277
+ await this.cursor.set({ cursor, expiredAt });
46278
+ }
46279
+ }
46280
+
46281
+ class ForYouFeedQueryStreamController extends QueryStreamController {
46282
+ constructor(query, cacheKey, notifyChange, preparePayload) {
46283
+ super(query, cacheKey);
46284
+ this.notifyChange = notifyChange;
46285
+ this.preparePayload = preparePayload;
46286
+ }
46287
+ async saveToMainDB(response) {
46288
+ const processedPayload = await this.preparePayload(response);
46289
+ const client = getActiveClient();
46290
+ const cachedAt = client.cache && Date.now();
46291
+ if (client.cache)
46292
+ ingestInCache(processedPayload, { cachedAt });
46293
+ }
46294
+ appendToQueryStream(response, _direction, refresh = false) {
46295
+ var _a, _b;
46296
+ if (refresh) {
46297
+ pushToCache(this.cacheKey, {
46298
+ data: response.posts.map(getResolver('post')),
46299
+ });
46300
+ }
46301
+ else {
46302
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
46303
+ const posts = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
46304
+ pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [...new Set([...posts, ...response.posts.map(getResolver('post'))])] }));
46305
+ }
46306
+ }
46307
+ reactor(action) {
46308
+ return (post) => {
46309
+ var _a;
46310
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
46311
+ if (!collection)
46312
+ return;
46313
+ if (post.parentPostId && !collection.data.includes(post.parentPostId))
46314
+ return;
46315
+ if (action === EnumPostActions.OnPostDeleted || action === EnumPostActions.OnPostDeclined) {
46316
+ collection.data = collection.data.filter(postId => postId !== post.postId);
46317
+ }
46318
+ pushToCache(this.cacheKey, collection);
46319
+ this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
46320
+ };
46321
+ }
46322
+ subscribeRTE(createSubscriber) {
46323
+ return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
46324
+ }
46325
+ }
46326
+
46327
+ const FOR_YOU_FEED_CACHE_KEY = ['forYouFeed', 'collection'];
46328
+ class ForYouFeedLiveCollectionController extends LiveCollectionController {
46329
+ constructor(callback) {
46330
+ const queryStreamId = `for-you-feed-${getActiveClient().userId}`;
46331
+ const query = {};
46332
+ const paginationController = new ForYouFeedPaginationController(query);
46333
+ super(paginationController, queryStreamId, FOR_YOU_FEED_CACHE_KEY, callback);
46334
+ this.queryStreamController = new ForYouFeedQueryStreamController(query, this.cacheKey, this.notifyChange.bind(this), preparePostPayload);
46335
+ this.callback = callback.bind(this);
46336
+ this.loadPage({ initial: true });
46337
+ }
46338
+ setup() {
46339
+ var _a;
46340
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
46341
+ if (!collection)
46342
+ pushToCache(this.cacheKey, { data: [], params: {} });
46343
+ }
46344
+ async persistModel(payload) {
46345
+ await this.queryStreamController.saveToMainDB(payload);
46346
+ }
46347
+ persistQueryStream({ response, direction, refresh, }) {
46348
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
46349
+ }
46350
+ startSubscription() {
46351
+ return this.queryStreamController.subscribeRTE(getGlobalFeedSubscriptions(this.cacheKey));
46352
+ }
46353
+ notifyChange({ origin, loading, error }) {
46354
+ var _a, _b;
46355
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
46356
+ if (!collection)
46357
+ return;
46358
+ const data = ((_b = collection.data
46359
+ .map(id => pullFromCache(['post', 'get', id]))
46360
+ .filter(isNonNullable)
46361
+ .map(({ data }) => data)) !== null && _b !== void 0 ? _b : []).map(LinkedObject.post);
46362
+ if (!this.shouldNotify(data) && origin === 'event')
46363
+ return;
46364
+ this.callback({
46365
+ onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
46366
+ data,
46367
+ hasNextPage: !!this.paginationController.getNextToken(),
46368
+ loading,
46369
+ error,
46370
+ });
46371
+ }
46372
+ }
46373
+
46374
+ /* begin_public_function
46375
+ id: feed.query.for_you_feed
46376
+ */
46377
+ /**
46378
+ * ```js
46379
+ * import { FeedRepository } from '@amityco/ts-sdk'
46380
+ *
46381
+ * const unsub = FeedRepository.getForYouFeed(({ data, loading, error, hasNextPage, onNextPage }) => {
46382
+ * // render posts; call onNextPage() to load the next page (20 posts)
46383
+ * })
46384
+ * ```
46385
+ *
46386
+ * Observe the For You feed — a personalized, server-ranked
46387
+ * {@link Amity.LiveCollection} of {@link Amity.Post}.
46388
+ *
46389
+ * @param callback the function to call when new data is available
46390
+ * @returns an {@link Amity.Unsubscriber} function to stop observing
46391
+ *
46392
+ * @category Posts Live Collection
46393
+ */
46394
+ const getForYouFeed = (callback) => {
46395
+ const { log, cache } = getActiveClient();
46396
+ if (!cache)
46397
+ console.log(ENABLE_CACHE_MESSAGE);
46398
+ const timestamp = Date.now();
46399
+ log(`getForYouFeed(tmpid: ${timestamp}) > listen`);
46400
+ const forYouFeedLiveCollection = new ForYouFeedLiveCollectionController(callback);
46401
+ const disposers = forYouFeedLiveCollection.startSubscription();
46402
+ const cacheKey = forYouFeedLiveCollection.getCacheKey();
46403
+ disposers.push(() => dropFromCache(cacheKey));
46404
+ return () => {
46405
+ log(`getForYouFeed(tmpid: ${timestamp}) > dispose`);
46406
+ disposers.forEach(fn => fn());
46407
+ };
46408
+ };
46409
+ /* end_public_function */
46410
+
44322
46411
  var index$d = /*#__PURE__*/Object.freeze({
44323
46412
  __proto__: null,
44324
46413
  queryGlobalFeed: queryGlobalFeed,
44325
46414
  getCustomRankingGlobalFeed: getCustomRankingGlobalFeed,
44326
46415
  getGlobalFeed: getGlobalFeed,
44327
46416
  getUserFeed: getUserFeed,
44328
- getCommunityFeed: getCommunityFeed
46417
+ getCommunityFeed: getCommunityFeed,
46418
+ getForYouFeed: getForYouFeed,
46419
+ AmityForYouFeedDisabledError: AmityForYouFeedDisabledError
44329
46420
  });
44330
46421
 
44331
46422
  /* begin_public_function
@@ -45338,7 +47429,12 @@ class PostLiveCollectionController extends LiveCollectionController {
45338
47429
  this.queryStreamController.appendToQueryStream(response, direction, refresh);
45339
47430
  }
45340
47431
  startSubscription() {
45341
- return this.queryStreamController.subscribeRTE(getPostSubscription(this.cacheKey));
47432
+ const disposers = this.queryStreamController.subscribeRTE(getPostSubscription(this.cacheKey));
47433
+ if (this.query.excludeBlockUserPosts) {
47434
+ const refresh = () => this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
47435
+ disposers.push(onUserDidBlock(refresh), onUserDidUnblock(refresh));
47436
+ }
47437
+ return disposers;
45342
47438
  }
45343
47439
  notifyChange({ origin, loading, error }) {
45344
47440
  var _a, _b;
@@ -45384,6 +47480,9 @@ class PostLiveCollectionController extends LiveCollectionController {
45384
47480
  const sortBy = this.query.sortBy || 'lastCreated';
45385
47481
  posts = posts.filter(post => !exceedsUntilAtBoundary(post.createdAt, validatedUntilAt, sortBy));
45386
47482
  }
47483
+ if (this.query.excludeBlockUserPosts) {
47484
+ posts = filterPostsByBlockUsers(posts);
47485
+ }
45387
47486
  switch (this.query.sortBy) {
45388
47487
  case 'firstCreated':
45389
47488
  posts = posts.sort(sortByFirstCreated);
@@ -52041,4 +54140,4 @@ class AmityAttachmentProductTags {
52041
54140
  }
52042
54141
  }
52043
54142
 
52044
- export { API_REGIONS, index$5 as AdRepository, AmityAttachmentProductTags, AmityCommunityType, AmityEventOrderOption, AmityEventOriginType, AmityEventResponseStatus, AmityEventSortOption, AmityEventStatus, AmityEventType, AnalyticsSourceTypeEnum, index$f as CategoryRepository, index$j as ChannelRepository, index$s as Client, index$e as CommentRepository, CommunityNotificationEventNameEnum, CommunityPostSettingMaps, CommunityPostSettings, index$g as CommunityRepository, ContentFeedType, ContentFlagReasonEnum, DefaultCommunityPostSetting, index$1 as EventRepository, FeedDataTypeEnum, index$d as FeedRepository, FeedSortByEnum, FeedSourceEnum, FeedTypeEnum, FileAccessTypeEnum, index$p as FileRepository, FileType, GET_WATCHER_URLS, index$3 as InvitationRepository, InvitationSortByEnum, InvitationStatusEnum, InvitationTargetTypeEnum, InvitationTypeEnum, JoinRequestStatusEnum, JoinResultStatusEnum, index$2 as LiveReactionRepository, index$7 as LiveStreamPlayer, MembershipAcceptanceTypeEnum, MessageContentType, index$n as MessageRepository, NotificationRolesFilterTypeEnum, NotificationSettingsLevelEnum, index$8 as PollRepository, PostContentType, index$b as PostRepository, PostStructureType, index as ProductRepository, index$o as ReactionRepository, index$9 as RoomPresenceRepository, index$c as RoomRepository, SearchUsersByEnum, index$6 as StoryRepository, index$a as StreamRepository, index$m as SubChannelRepository, SubscriptionLevels, UserNotificationModuleNameEnum, index$q as UserRepository, UserTypeEnum, VERSION, VideoResolution, VideoSize, VideoTranscodingStatus, backupCache, createQuery, createReport, createUserToken, deleteReport, disableCache, dropFromCache, enableCache, exceedsUntilAtBoundary, filterByChannelMembership, filterByCommunityMembership, filterByFeedType, filterByPostDataTypes, filterByPropEquality, filterByPropInclusion, filterByPropIntersection, filterBySearchTerm, filterByStringComparePartially, filterByUntilAt, getChannelTopic, getCommentTopic, getCommunityStoriesTopic, getCommunityTopic, getLiveReactionTopic, getLiveStreamTopic, getMarkedMessageTopic, getMarkerUserFeedTopic, getMessageTopic, getMyFollowersTopic, getMyFollowingsTopic, getNetworkTopic, getPostTopic, getRole, getRoomStreamerTopic, getRoomWatcherTopic, getSmartFeedChannelTopic, getSmartFeedMessageTopic, getSmartFeedSubChannelTopic, getStoryTopic, getSubChannelTopic, getUserTopic, isAfterBefore, isAfterBeforeRaw, isCachable, isFetcher, isFresh, isLocal, isMutator, isOffline, isPaged, isReportedByMe, isSkip, mergeInCache, index$4 as notificationTray, onChannelMarkerFetched, onFeedMarkerFetched, onFeedMarkerUpdated, onMessageMarked, onMessageMarkerFetched, onSubChannelMarkerFetched, onSubChannelMarkerUpdated, onUserMarkerFetched, onUserMarkerFetchedLegacy, pullFromCache, pushToCache, queryCache, queryOptions, queryRoles, restoreCache, runQuery, sortByChannelSegment, sortByDisplayName, sortByFirstCreated, sortByFirstUpdated, sortByLastActivity, sortByLastCreated, sortByLastUpdated, sortByLocalSortingDate, sortByName, sortBySegmentNumber, subscribeTopic, toPage, toPageRaw, toToken, upsertInCache, validateUntilAt, wipeCache };
54143
+ export { API_REGIONS, index$5 as AdRepository, AmityAttachmentProductTags, AmityAutoSubscription, AmityChannelNotificationModeEnum, AmityCommunityType, AmityEventOrderOption, AmityEventOriginType, AmityEventResponseStatus, AmityEventSortOption, AmityEventStatus, AmityEventType, AmitySharableContentType, AnalyticsSourceTypeEnum, index$f as CategoryRepository, index$j as ChannelRepository, index$s as Client, index$e as CommentRepository, CommunityNotificationEventNameEnum, CommunityPostSettingMaps, CommunityPostSettings, index$g as CommunityRepository, ContentFeedType, ContentFlagReasonEnum, DefaultCommunityPostSetting, index$1 as EventRepository, FeedDataTypeEnum, index$d as FeedRepository, FeedSortByEnum, FeedSourceEnum, FeedTypeEnum, FileAccessTypeEnum, index$p as FileRepository, FileType, GET_WATCHER_URLS, index$3 as InvitationRepository, InvitationSortByEnum, InvitationStatusEnum, InvitationTargetTypeEnum, InvitationTypeEnum, JoinRequestStatusEnum, JoinResultStatusEnum, index$2 as LiveReactionRepository, index$7 as LiveStreamPlayer, MembershipAcceptanceTypeEnum, MessageContentType, index$n as MessageRepository, NotificationRolesFilterTypeEnum, NotificationSettingsLevelEnum, index$8 as PollRepository, PostContentType, index$b as PostRepository, PostStructureType, index as ProductRepository, index$o as ReactionRepository, index$9 as RoomPresenceRepository, index$c as RoomRepository, SearchUsersByEnum, index$6 as StoryRepository, index$a as StreamRepository, index$m as SubChannelRepository, SubscriptionLevels, UserNotificationModuleNameEnum, index$q as UserRepository, UserTypeEnum, VERSION, VideoResolution, VideoSize, VideoTranscodingStatus, backupCache, createQuery, createReport, createUserToken, deleteReport, disableCache, dropFromCache, enableCache, exceedsUntilAtBoundary, filterByChannelMembership, filterByCommunityMembership, filterByFeedType, filterByPostDataTypes, filterByPropEquality, filterByPropInclusion, filterByPropIntersection, filterBySearchTerm, filterByStringComparePartially, filterByUntilAt, filterCommentsByBlockUsers, filterPostsByBlockUsers, getBlockUsersId, getChannelTopic, getCommentTopic, getCommunityStoriesTopic, getCommunityTopic, getLiveReactionTopic, getLiveStreamTopic, getMarkedMessageTopic, getMarkerUserFeedTopic, getMessageTopic, getMyFollowersTopic, getMyFollowingsTopic, getNetworkId, getNetworkTopic, getPostTopic, getRole, getRoomStreamerTopic, getRoomWatcherTopic, getSmartFeedChannelTopic, getSmartFeedMessageTopic, getSmartFeedSubChannelTopic, getStoryTopic, getSubChannelTopic, getUserTopic, isAfterBefore, isAfterBeforeRaw, isCachable, isFetcher, isFresh, isLocal, isMutator, isOffline, isPaged, isReportedByMe, isSkip, mergeInCache, index$4 as notificationTray, onChannelMarkerFetched, onFeedMarkerFetched, onFeedMarkerUpdated, onMessageMarked, onMessageMarkerFetched, onSubChannelMarkerFetched, onSubChannelMarkerUpdated, onUserMarkerFetched, onUserMarkerFetchedLegacy, pullFromCache, pushToCache, queryCache, queryOptions, queryRoles, restoreCache, runQuery, sortByChannelSegment, sortByDisplayName, sortByFirstCreated, sortByFirstUpdated, sortByLastActivity, sortByLastCreated, sortByLastUpdated, sortByLocalSortingDate, sortByName, sortBySegmentNumber, subscribeTopic, toPage, toPageRaw, toToken, upsertInCache, validateUntilAt, wipeCache };