@amityco/ts-sdk 0.0.1-beta.32 → 0.0.1-beta.36

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 (567) hide show
  1. package/dist/@types/core/events.d.ts +47 -22
  2. package/dist/@types/core/events.d.ts.map +1 -1
  3. package/dist/@types/core/model.d.ts +2 -0
  4. package/dist/@types/core/model.d.ts.map +1 -1
  5. package/dist/@types/core/payload.d.ts +15 -5
  6. package/dist/@types/core/payload.d.ts.map +1 -1
  7. package/dist/@types/domains/channel.d.ts +12 -7
  8. package/dist/@types/domains/channel.d.ts.map +1 -1
  9. package/dist/@types/domains/client.d.ts +19 -0
  10. package/dist/@types/domains/client.d.ts.map +1 -1
  11. package/dist/@types/domains/content.d.ts +2 -3
  12. package/dist/@types/domains/content.d.ts.map +1 -1
  13. package/dist/@types/domains/group.d.ts +6 -2
  14. package/dist/@types/domains/group.d.ts.map +1 -1
  15. package/dist/@types/domains/message.d.ts +37 -17
  16. package/dist/@types/domains/message.d.ts.map +1 -1
  17. package/dist/@types/domains/post.d.ts +2 -2
  18. package/dist/@types/domains/post.d.ts.map +1 -1
  19. package/dist/@types/domains/subChannel.d.ts +39 -0
  20. package/dist/@types/domains/subChannel.d.ts.map +1 -0
  21. package/dist/@types/index.d.ts +1 -0
  22. package/dist/@types/index.d.ts.map +1 -1
  23. package/dist/cache/api/ingestInCache.d.ts +1 -1
  24. package/dist/cache/api/tests/dropFromCache.test.d.ts +2 -0
  25. package/dist/cache/api/tests/dropFromCache.test.d.ts.map +1 -0
  26. package/dist/cache/api/tests/enableCache.test.d.ts +2 -0
  27. package/dist/cache/api/tests/enableCache.test.d.ts.map +1 -0
  28. package/dist/cache/api/tests/ingestInCache.test.d.ts +2 -0
  29. package/dist/cache/api/tests/ingestInCache.test.d.ts.map +1 -0
  30. package/dist/cache/api/tests/pullFromCache.test.d.ts +2 -0
  31. package/dist/cache/api/tests/pullFromCache.test.d.ts.map +1 -0
  32. package/dist/cache/api/tests/upsertInCache.test.d.ts +2 -0
  33. package/dist/cache/api/tests/upsertInCache.test.d.ts.map +1 -0
  34. package/dist/cache/utils/tests/encodeKey.test.d.ts +2 -0
  35. package/dist/cache/utils/tests/encodeKey.test.d.ts.map +1 -0
  36. package/dist/cache/utils/tests/partialMatch.test.d.ts +2 -0
  37. package/dist/cache/utils/tests/partialMatch.test.d.ts.map +1 -0
  38. package/dist/channel/api/banChannelMembers.d.ts.map +1 -1
  39. package/dist/channel/api/createChannel.d.ts +1 -1
  40. package/dist/channel/api/index.d.ts +2 -0
  41. package/dist/channel/api/index.d.ts.map +1 -1
  42. package/dist/channel/api/queryChannelMembers.d.ts.map +1 -1
  43. package/dist/channel/api/removeChannelMembers.d.ts.map +1 -1
  44. package/dist/channel/api/startReading.d.ts +17 -0
  45. package/dist/channel/api/startReading.d.ts.map +1 -0
  46. package/dist/channel/api/stopReading.d.ts +16 -0
  47. package/dist/channel/api/stopReading.d.ts.map +1 -0
  48. package/dist/channel/api/tests/createChannel.test.d.ts +2 -0
  49. package/dist/channel/api/tests/createChannel.test.d.ts.map +1 -0
  50. package/dist/channel/api/tests/joinChannel.test.d.ts +2 -0
  51. package/dist/channel/api/tests/joinChannel.test.d.ts.map +1 -0
  52. package/dist/channel/api/tests/removeChannelMembers.test.d.ts +2 -0
  53. package/dist/channel/api/tests/removeChannelMembers.test.d.ts.map +1 -0
  54. package/dist/channel/api/tests/startReading.test.d.ts +2 -0
  55. package/dist/channel/api/tests/startReading.test.d.ts.map +1 -0
  56. package/dist/channel/api/tests/stopReading.test.d.ts +2 -0
  57. package/dist/channel/api/tests/stopReading.test.d.ts.map +1 -0
  58. package/dist/channel/api/unbanChannelMembers.d.ts.map +1 -1
  59. package/dist/channel/events/index.d.ts +1 -0
  60. package/dist/channel/events/index.d.ts.map +1 -1
  61. package/dist/channel/events/onChannelJoined.d.ts +2 -2
  62. package/dist/channel/events/onChannelJoined.d.ts.map +1 -1
  63. package/dist/channel/events/onChannelLeft.d.ts +2 -2
  64. package/dist/channel/events/onChannelLeft.d.ts.map +1 -1
  65. package/dist/channel/events/onChannelMemberAdded.d.ts.map +1 -1
  66. package/dist/channel/events/onChannelMemberBanned.d.ts.map +1 -1
  67. package/dist/channel/events/onChannelMemberRemoved.d.ts.map +1 -1
  68. package/dist/channel/events/onChannelMemberUnbanned.d.ts.map +1 -1
  69. package/dist/channel/events/onChannelMuted.d.ts +17 -0
  70. package/dist/channel/events/onChannelMuted.d.ts.map +1 -0
  71. package/dist/channel/events/onChannelUpdated.d.ts +1 -1
  72. package/dist/channel/events/onChannelUpdated.d.ts.map +1 -1
  73. package/dist/channel/events/tests/onChannelCreated.test.d.ts +2 -0
  74. package/dist/channel/events/tests/onChannelCreated.test.d.ts.map +1 -0
  75. package/dist/channel/events/tests/onChannelJoined.test.d.ts +2 -0
  76. package/dist/channel/events/tests/onChannelJoined.test.d.ts.map +1 -0
  77. package/dist/channel/events/tests/onChannelMemberAdded.test.d.ts +2 -0
  78. package/dist/channel/events/tests/onChannelMemberAdded.test.d.ts.map +1 -0
  79. package/dist/channel/events/tests/onChannelMemberRemoved.test.d.ts +2 -0
  80. package/dist/channel/events/tests/onChannelMemberRemoved.test.d.ts.map +1 -0
  81. package/dist/channel/events/tests/onChannelUpdated.test.d.ts +2 -0
  82. package/dist/channel/events/tests/onChannelUpdated.test.d.ts.map +1 -0
  83. package/dist/channel/observers/index.d.ts +1 -0
  84. package/dist/channel/observers/index.d.ts.map +1 -1
  85. package/dist/channel/observers/liveChannel.d.ts +21 -0
  86. package/dist/channel/observers/liveChannel.d.ts.map +1 -0
  87. package/dist/channel/observers/liveChannelMembers.d.ts.map +1 -1
  88. package/dist/channel/observers/liveChannels.d.ts.map +1 -1
  89. package/dist/channel/observers/observeChannel.d.ts +1 -1
  90. package/dist/channel/observers/observeChannel.d.ts.map +1 -1
  91. package/dist/channel/observers/observeChannels.d.ts.map +1 -1
  92. package/dist/channel/utils/index.d.ts +2 -1
  93. package/dist/channel/utils/index.d.ts.map +1 -1
  94. package/dist/client/api/connectClient.d.ts.map +1 -1
  95. package/dist/client/api/getChatSettings.d.ts +15 -0
  96. package/dist/client/api/getChatSettings.d.ts.map +1 -0
  97. package/dist/client/api/getSocialSettings.d.ts +15 -0
  98. package/dist/client/api/getSocialSettings.d.ts.map +1 -0
  99. package/dist/client/api/tests/activeClient.test.d.ts +2 -0
  100. package/dist/client/api/tests/activeClient.test.d.ts.map +1 -0
  101. package/dist/client/api/tests/activeUser.test.d.ts +2 -0
  102. package/dist/client/api/tests/activeUser.test.d.ts.map +1 -0
  103. package/dist/client/api/tests/createClient.test.d.ts +2 -0
  104. package/dist/client/api/tests/createClient.test.d.ts.map +1 -0
  105. package/dist/client/tests/connectClient.test.d.ts +2 -0
  106. package/dist/client/tests/connectClient.test.d.ts.map +1 -0
  107. package/dist/comment/api/createComment.d.ts +1 -1
  108. package/dist/comment/api/createComment.d.ts.map +1 -1
  109. package/dist/comment/api/tests/createComment.test.d.ts +2 -0
  110. package/dist/comment/api/tests/createComment.test.d.ts.map +1 -0
  111. package/dist/comment/api/tests/getComments.test.d.ts +2 -0
  112. package/dist/comment/api/tests/getComments.test.d.ts.map +1 -0
  113. package/dist/comment/events/tests/onCommentCreated.test.d.ts +2 -0
  114. package/dist/comment/events/tests/onCommentCreated.test.d.ts.map +1 -0
  115. package/dist/comment/events/utils.d.ts +1 -1
  116. package/dist/comment/events/utils.d.ts.map +1 -1
  117. package/dist/community/api/queryCommunities.d.ts.map +1 -1
  118. package/dist/community/api/queryCommunityMembers.d.ts +6 -1
  119. package/dist/community/api/queryCommunityMembers.d.ts.map +1 -1
  120. package/dist/community/api/test/addCommunityMember.test.d.ts +2 -0
  121. package/dist/community/api/test/addCommunityMember.test.d.ts.map +1 -0
  122. package/dist/community/api/test/addCommunityMemberRole.test.d.ts +2 -0
  123. package/dist/community/api/test/addCommunityMemberRole.test.d.ts.map +1 -0
  124. package/dist/community/api/test/createCommunity.test.d.ts +2 -0
  125. package/dist/community/api/test/createCommunity.test.d.ts.map +1 -0
  126. package/dist/community/api/test/deleteCommunity.test.d.ts +2 -0
  127. package/dist/community/api/test/deleteCommunity.test.d.ts.map +1 -0
  128. package/dist/community/api/test/getCommunities.test.d.ts +2 -0
  129. package/dist/community/api/test/getCommunities.test.d.ts.map +1 -0
  130. package/dist/community/api/test/getCommunity.test.d.ts +2 -0
  131. package/dist/community/api/test/getCommunity.test.d.ts.map +1 -0
  132. package/dist/community/api/test/getRecommendedCommunities.test.d.ts +2 -0
  133. package/dist/community/api/test/getRecommendedCommunities.test.d.ts.map +1 -0
  134. package/dist/community/api/test/getTopTrendingCommunities.test.d.ts +2 -0
  135. package/dist/community/api/test/getTopTrendingCommunities.test.d.ts.map +1 -0
  136. package/dist/community/api/test/joinCommunity.test.d.ts +2 -0
  137. package/dist/community/api/test/joinCommunity.test.d.ts.map +1 -0
  138. package/dist/community/api/test/leaveCommunity.test.d.ts +2 -0
  139. package/dist/community/api/test/leaveCommunity.test.d.ts.map +1 -0
  140. package/dist/community/api/test/queryCommunity.test.d.ts +2 -0
  141. package/dist/community/api/test/queryCommunity.test.d.ts.map +1 -0
  142. package/dist/community/api/test/queryCommunityMembers.test.d.ts +2 -0
  143. package/dist/community/api/test/queryCommunityMembers.test.d.ts.map +1 -0
  144. package/dist/community/api/test/removeCommunityMemberRole.test.d.ts +2 -0
  145. package/dist/community/api/test/removeCommunityMemberRole.test.d.ts.map +1 -0
  146. package/dist/community/api/test/removeCommunityMembers.test.d.ts +2 -0
  147. package/dist/community/api/test/removeCommunityMembers.test.d.ts.map +1 -0
  148. package/dist/community/api/test/updateCommunity.test.d.ts +2 -0
  149. package/dist/community/api/test/updateCommunity.test.d.ts.map +1 -0
  150. package/dist/community/events/test/onCommunityCreated.test.d.ts +2 -0
  151. package/dist/community/events/test/onCommunityCreated.test.d.ts.map +1 -0
  152. package/dist/community/events/test/onCommunityDeleted.test.d.ts +2 -0
  153. package/dist/community/events/test/onCommunityDeleted.test.d.ts.map +1 -0
  154. package/dist/community/events/test/onCommunityJoined.test.d.ts +2 -0
  155. package/dist/community/events/test/onCommunityJoined.test.d.ts.map +1 -0
  156. package/dist/community/events/test/onCommunityLeft.test.d.ts +2 -0
  157. package/dist/community/events/test/onCommunityLeft.test.d.ts.map +1 -0
  158. package/dist/community/events/test/onCommunityUpdated.test.d.ts +2 -0
  159. package/dist/community/events/test/onCommunityUpdated.test.d.ts.map +1 -0
  160. package/dist/community/events/test/onCommunityUserAdded.test.d.ts +2 -0
  161. package/dist/community/events/test/onCommunityUserAdded.test.d.ts.map +1 -0
  162. package/dist/community/events/test/onCommunityUserBanned.test.d.ts +2 -0
  163. package/dist/community/events/test/onCommunityUserBanned.test.d.ts.map +1 -0
  164. package/dist/community/events/test/onCommunityUserRemoved.test.d.ts +2 -0
  165. package/dist/community/events/test/onCommunityUserRemoved.test.d.ts.map +1 -0
  166. package/dist/community/events/test/onCommunityUserUnbaned.test.d.ts +2 -0
  167. package/dist/community/events/test/onCommunityUserUnbaned.test.d.ts.map +1 -0
  168. package/dist/community/events/test/utils.test.d.ts +2 -0
  169. package/dist/community/events/test/utils.test.d.ts.map +1 -0
  170. package/dist/community/events/utils.d.ts +2 -2
  171. package/dist/community/events/utils.d.ts.map +1 -1
  172. package/dist/core/events.d.ts +3 -3
  173. package/dist/core/events.d.ts.map +1 -1
  174. package/dist/core/model/idResolvers.d.ts.map +1 -1
  175. package/dist/core/model/identifyModel.d.ts.map +1 -1
  176. package/dist/core/model/index.d.ts +5 -0
  177. package/dist/core/model/index.d.ts.map +1 -1
  178. package/dist/core/query/filtering.d.ts.map +1 -1
  179. package/dist/core/query/query.d.ts.map +1 -1
  180. package/dist/core/subscription.d.ts +26 -1
  181. package/dist/core/subscription.d.ts.map +1 -1
  182. package/dist/core/tests/subscription.test.d.ts +2 -0
  183. package/dist/core/tests/subscription.test.d.ts.map +1 -0
  184. package/dist/feed/api/queryGlobalFeed.d.ts +1 -1
  185. package/dist/feed/api/queryGlobalFeed.d.ts.map +1 -1
  186. package/dist/feed/api/test/queryGlobalFeed.test.d.ts +2 -0
  187. package/dist/feed/api/test/queryGlobalFeed.test.d.ts.map +1 -0
  188. package/dist/follow/events/utils.d.ts +1 -1
  189. package/dist/follow/events/utils.d.ts.map +1 -1
  190. package/dist/group/utils/index.d.ts +2 -0
  191. package/dist/group/utils/index.d.ts.map +1 -0
  192. package/dist/group/utils/test/withUsers.test.d.ts +2 -0
  193. package/dist/group/utils/test/withUsers.test.d.ts.map +1 -0
  194. package/dist/group/utils/withUser.d.ts +38 -0
  195. package/dist/group/utils/withUser.d.ts.map +1 -0
  196. package/dist/index.cjs.js +2053 -818
  197. package/dist/index.d.ts +3 -0
  198. package/dist/index.d.ts.map +1 -1
  199. package/dist/index.esm.js +2028 -817
  200. package/dist/index.umd.js +4 -4
  201. package/dist/message/api/createMessage.d.ts +15 -9
  202. package/dist/message/api/createMessage.d.ts.map +1 -1
  203. package/dist/message/api/deleteMessage.d.ts +2 -2
  204. package/dist/message/api/getMessage.d.ts.map +1 -1
  205. package/dist/message/api/getMessages.d.ts.map +1 -1
  206. package/dist/message/api/queryMessages.d.ts.map +1 -1
  207. package/dist/message/api/updateMessage.d.ts +1 -1
  208. package/dist/message/api/updateMessage.d.ts.map +1 -1
  209. package/dist/message/events/index.d.ts +5 -1
  210. package/dist/message/events/index.d.ts.map +1 -1
  211. package/dist/message/events/onMessageCreated.d.ts.map +1 -1
  212. package/dist/message/events/onMessageDeleted.d.ts.map +1 -1
  213. package/dist/message/events/onMessageFlagCleared.d.ts +17 -0
  214. package/dist/message/events/onMessageFlagCleared.d.ts.map +1 -0
  215. package/dist/message/events/onMessageFlagged.d.ts +17 -0
  216. package/dist/message/events/onMessageFlagged.d.ts.map +1 -0
  217. package/dist/message/events/onMessageReactionAdded.d.ts +18 -0
  218. package/dist/message/events/onMessageReactionAdded.d.ts.map +1 -0
  219. package/dist/message/events/onMessageReactionRemoved.d.ts +18 -0
  220. package/dist/message/events/onMessageReactionRemoved.d.ts.map +1 -0
  221. package/dist/message/events/onMessageUnflagged.d.ts +17 -0
  222. package/dist/message/events/onMessageUnflagged.d.ts.map +1 -0
  223. package/dist/message/events/onMessageUpdated.d.ts.map +1 -1
  224. package/dist/message/observers/liveMessage.d.ts +7 -4
  225. package/dist/message/observers/liveMessage.d.ts.map +1 -1
  226. package/dist/message/observers/liveMessages.d.ts +7 -6
  227. package/dist/message/observers/liveMessages.d.ts.map +1 -1
  228. package/dist/message/observers/observeMessage.d.ts +1 -0
  229. package/dist/message/observers/observeMessage.d.ts.map +1 -1
  230. package/dist/message/observers/observeMessages.d.ts +5 -4
  231. package/dist/message/observers/observeMessages.d.ts.map +1 -1
  232. package/dist/message/tests/events.test.d.ts +2 -0
  233. package/dist/message/tests/events.test.d.ts.map +1 -0
  234. package/dist/message/utils/index.d.ts +18 -0
  235. package/dist/message/utils/index.d.ts.map +1 -0
  236. package/dist/post/api/queryPosts.d.ts.map +1 -1
  237. package/dist/post/api/tests/queryPosts.test.d.ts +2 -0
  238. package/dist/post/api/tests/queryPosts.test.d.ts.map +1 -0
  239. package/dist/post/events/tests/onPostApproved.test.d.ts +2 -0
  240. package/dist/post/events/tests/onPostApproved.test.d.ts.map +1 -0
  241. package/dist/post/events/tests/onPostCreated.test.d.ts +2 -0
  242. package/dist/post/events/tests/onPostCreated.test.d.ts.map +1 -0
  243. package/dist/post/events/tests/onPostDeclined.test.d.ts +2 -0
  244. package/dist/post/events/tests/onPostDeclined.test.d.ts.map +1 -0
  245. package/dist/post/events/tests/onPostDeleted.test.d.ts +2 -0
  246. package/dist/post/events/tests/onPostDeleted.test.d.ts.map +1 -0
  247. package/dist/post/events/tests/onPostFlagged.test.d.ts +2 -0
  248. package/dist/post/events/tests/onPostFlagged.test.d.ts.map +1 -0
  249. package/dist/post/events/tests/onPostReactionAdded.test.d.ts +2 -0
  250. package/dist/post/events/tests/onPostReactionAdded.test.d.ts.map +1 -0
  251. package/dist/post/events/tests/onPostReactionRemoved.test.d.ts +2 -0
  252. package/dist/post/events/tests/onPostReactionRemoved.test.d.ts.map +1 -0
  253. package/dist/post/events/tests/onPostUnflagged.test.d.ts +2 -0
  254. package/dist/post/events/tests/onPostUnflagged.test.d.ts.map +1 -0
  255. package/dist/post/events/tests/onPostUpdated.test.d.ts +2 -0
  256. package/dist/post/events/tests/onPostUpdated.test.d.ts.map +1 -0
  257. package/dist/post/events/utils.d.ts +1 -1
  258. package/dist/post/events/utils.d.ts.map +1 -1
  259. package/dist/post/observers/livePosts.d.ts.map +1 -1
  260. package/dist/post/observers/tests/livePosts.test.d.ts +2 -0
  261. package/dist/post/observers/tests/livePosts.test.d.ts.map +1 -0
  262. package/dist/reaction/api/addReaction.d.ts.map +1 -1
  263. package/dist/reaction/api/removeReaction.d.ts.map +1 -1
  264. package/dist/reaction/events/onReactionAdded.d.ts.map +1 -1
  265. package/dist/reaction/events/onReactionRemoved.d.ts.map +1 -1
  266. package/dist/reaction/events/onReactorAdded.d.ts.map +1 -1
  267. package/dist/reaction/events/onReactorRemoved.d.ts.map +1 -1
  268. package/dist/report/api/createReport.d.ts.map +1 -1
  269. package/dist/report/api/deleteReport.d.ts.map +1 -1
  270. package/dist/report/api/isReportedByMe.d.ts.map +1 -1
  271. package/dist/subChannel/api/createSubChannel.d.ts +16 -0
  272. package/dist/subChannel/api/createSubChannel.d.ts.map +1 -0
  273. package/dist/subChannel/api/deleteSubChannel.d.ts +16 -0
  274. package/dist/subChannel/api/deleteSubChannel.d.ts.map +1 -0
  275. package/dist/subChannel/api/getSubChannel.d.ts +32 -0
  276. package/dist/subChannel/api/getSubChannel.d.ts.map +1 -0
  277. package/dist/subChannel/api/getSubChannels.d.ts +32 -0
  278. package/dist/subChannel/api/getSubChannels.d.ts.map +1 -0
  279. package/dist/subChannel/api/index.d.ts +7 -0
  280. package/dist/subChannel/api/index.d.ts.map +1 -0
  281. package/dist/subChannel/api/querySubChannels.d.ts +32 -0
  282. package/dist/subChannel/api/querySubChannels.d.ts.map +1 -0
  283. package/dist/subChannel/api/updateSubChannel.d.ts +17 -0
  284. package/dist/subChannel/api/updateSubChannel.d.ts.map +1 -0
  285. package/dist/subChannel/events/index.d.ts +4 -0
  286. package/dist/subChannel/events/index.d.ts.map +1 -0
  287. package/dist/subChannel/events/onSubChannelCreated.d.ts +17 -0
  288. package/dist/subChannel/events/onSubChannelCreated.d.ts.map +1 -0
  289. package/dist/subChannel/events/onSubChannelDeleted.d.ts +17 -0
  290. package/dist/subChannel/events/onSubChannelDeleted.d.ts.map +1 -0
  291. package/dist/subChannel/events/onSubChannelFetched.d.ts +3 -0
  292. package/dist/subChannel/events/onSubChannelFetched.d.ts.map +1 -0
  293. package/dist/subChannel/events/onSubChannelUpdated.d.ts +17 -0
  294. package/dist/subChannel/events/onSubChannelUpdated.d.ts.map +1 -0
  295. package/dist/subChannel/observers/index.d.ts +3 -0
  296. package/dist/subChannel/observers/index.d.ts.map +1 -0
  297. package/dist/subChannel/observers/liveSubChannel.d.ts +21 -0
  298. package/dist/subChannel/observers/liveSubChannel.d.ts.map +1 -0
  299. package/dist/subChannel/observers/liveSubChannels.d.ts +21 -0
  300. package/dist/subChannel/observers/liveSubChannels.d.ts.map +1 -0
  301. package/dist/subChannel/observers/tests/liveSubChannel.test.d.ts +2 -0
  302. package/dist/subChannel/observers/tests/liveSubChannel.test.d.ts.map +1 -0
  303. package/dist/subChannel/observers/tests/liveSubChannels.test.d.ts +2 -0
  304. package/dist/subChannel/observers/tests/liveSubChannels.test.d.ts.map +1 -0
  305. package/dist/subChannel/utils/index.d.ts +8 -0
  306. package/dist/subChannel/utils/index.d.ts.map +1 -0
  307. package/dist/user/events/index.d.ts +0 -1
  308. package/dist/user/events/index.d.ts.map +1 -1
  309. package/dist/user/events/utils.d.ts +1 -1
  310. package/dist/user/events/utils.d.ts.map +1 -1
  311. package/dist/user/observers/liveUser.d.ts +7 -4
  312. package/dist/user/observers/liveUser.d.ts.map +1 -1
  313. package/dist/utils/index.d.ts +4 -0
  314. package/dist/utils/index.d.ts.map +1 -0
  315. package/dist/utils/tests/dummy/channel.d.ts +51 -20
  316. package/dist/utils/tests/dummy/channel.d.ts.map +1 -1
  317. package/dist/utils/tests/dummy/community.d.ts +36 -0
  318. package/dist/utils/tests/dummy/community.d.ts.map +1 -0
  319. package/dist/utils/tests/dummy/file.d.ts +2 -0
  320. package/dist/utils/tests/dummy/file.d.ts.map +1 -0
  321. package/dist/utils/tests/dummy/follow.d.ts +1 -0
  322. package/dist/utils/tests/dummy/follow.d.ts.map +1 -1
  323. package/dist/utils/tests/dummy/index.d.ts +7 -0
  324. package/dist/utils/tests/dummy/index.d.ts.map +1 -1
  325. package/dist/utils/tests/dummy/member.d.ts +2 -0
  326. package/dist/utils/tests/dummy/member.d.ts.map +1 -0
  327. package/dist/utils/tests/dummy/message.d.ts +7 -1
  328. package/dist/utils/tests/dummy/message.d.ts.map +1 -1
  329. package/dist/utils/tests/dummy/poll.d.ts +3 -0
  330. package/dist/utils/tests/dummy/poll.d.ts.map +1 -0
  331. package/dist/utils/tests/dummy/post.d.ts +18 -0
  332. package/dist/utils/tests/dummy/post.d.ts.map +1 -1
  333. package/dist/utils/tests/dummy/reaction.d.ts +4 -0
  334. package/dist/utils/tests/dummy/reaction.d.ts.map +1 -0
  335. package/dist/utils/tests/dummy/role.d.ts +4 -0
  336. package/dist/utils/tests/dummy/role.d.ts.map +1 -0
  337. package/dist/utils/tests/dummy/subChannel.d.ts +3 -0
  338. package/dist/utils/tests/dummy/subChannel.d.ts.map +1 -0
  339. package/dist/utils/tests/dummy/user.d.ts +2 -0
  340. package/dist/utils/tests/dummy/user.d.ts.map +1 -1
  341. package/dist/utils/tests/utils.d.ts +1 -0
  342. package/dist/utils/tests/utils.d.ts.map +1 -1
  343. package/package.json +1 -1
  344. package/src/@types/core/events.ts +56 -28
  345. package/src/@types/core/model.ts +2 -0
  346. package/src/@types/core/payload.ts +21 -5
  347. package/src/@types/domains/channel.ts +23 -6
  348. package/src/@types/domains/client.ts +21 -0
  349. package/src/@types/domains/content.ts +4 -3
  350. package/src/@types/domains/group.ts +6 -2
  351. package/src/@types/domains/message.ts +59 -26
  352. package/src/@types/domains/post.ts +2 -2
  353. package/src/@types/domains/subChannel.ts +48 -0
  354. package/src/@types/index.ts +1 -0
  355. package/src/cache/api/ingestInCache.ts +2 -2
  356. package/src/cache/api/tests/dropFromCache.test.ts +59 -0
  357. package/src/cache/api/tests/enableCache.test.ts +15 -0
  358. package/src/cache/api/tests/ingestInCache.test.ts +87 -0
  359. package/src/cache/api/tests/pullFromCache.test.ts +42 -0
  360. package/src/cache/api/tests/upsertInCache.test.ts +60 -0
  361. package/src/cache/utils/tests/encodeKey.test.ts +19 -0
  362. package/src/cache/utils/tests/partialMatch.test.ts +13 -0
  363. package/src/channel/api/addChannelMembers.ts +2 -2
  364. package/src/channel/api/banChannelMembers.ts +5 -3
  365. package/src/channel/api/createChannel.ts +1 -1
  366. package/src/channel/api/getChannels.ts +2 -2
  367. package/src/channel/api/index.ts +3 -0
  368. package/src/channel/api/queryChannelMembers.ts +15 -10
  369. package/src/channel/api/queryChannels.ts +1 -1
  370. package/src/channel/api/removeChannelMembers.ts +9 -1
  371. package/src/channel/api/startReading.ts +53 -0
  372. package/src/channel/api/stopReading.ts +49 -0
  373. package/src/channel/api/tests/addChannelMembers.test.ts +36 -8
  374. package/src/channel/api/tests/createChannel.test.ts +53 -0
  375. package/src/channel/api/tests/getChannel.test.ts +3 -2
  376. package/src/channel/api/tests/joinChannel.test.ts +52 -0
  377. package/src/channel/api/tests/queryChannelMembers.test.ts +27 -11
  378. package/src/channel/api/tests/queryChannels.test.ts +2 -2
  379. package/src/channel/api/tests/removeChannelMembers.test.ts +95 -0
  380. package/src/channel/api/tests/startReading.test.ts +25 -0
  381. package/src/channel/api/tests/stopReading.test.ts +25 -0
  382. package/src/channel/api/unbanChannelMembers.ts +6 -3
  383. package/src/channel/events/index.ts +1 -0
  384. package/src/channel/events/onChannelCreated.ts +1 -1
  385. package/src/channel/events/onChannelDeleted.ts +1 -1
  386. package/src/channel/events/onChannelJoined.ts +12 -7
  387. package/src/channel/events/onChannelLeft.ts +12 -7
  388. package/src/channel/events/onChannelMemberAdded.ts +8 -6
  389. package/src/channel/events/onChannelMemberBanned.ts +7 -4
  390. package/src/channel/events/onChannelMemberRemoved.ts +7 -9
  391. package/src/channel/events/onChannelMemberUnbanned.ts +7 -4
  392. package/src/channel/events/onChannelMuted.ts +34 -0
  393. package/src/channel/events/onChannelUpdated.ts +10 -1
  394. package/src/channel/events/tests/onChannelCreated.test.ts +55 -0
  395. package/src/channel/events/tests/onChannelJoined.test.ts +56 -0
  396. package/src/channel/events/tests/onChannelMemberAdded.test.ts +56 -0
  397. package/src/channel/events/tests/onChannelMemberBanned.test.ts +13 -12
  398. package/src/channel/events/tests/onChannelMemberRemoved.test.ts +56 -0
  399. package/src/channel/events/tests/onChannelMemberUnbanned.test.ts +13 -12
  400. package/src/channel/events/tests/onChannelUpdated.test.ts +55 -0
  401. package/src/channel/observers/index.ts +1 -0
  402. package/src/channel/observers/liveChannel.ts +108 -0
  403. package/src/channel/observers/liveChannelMembers.ts +40 -34
  404. package/src/channel/observers/liveChannels.ts +25 -14
  405. package/src/channel/observers/observeChannel.ts +2 -0
  406. package/src/channel/observers/observeChannels.ts +2 -0
  407. package/src/channel/observers/tests/liveChannelMembers.test.ts +107 -95
  408. package/src/channel/observers/tests/liveChannels.test.ts +385 -126
  409. package/src/channel/utils/index.ts +54 -1
  410. package/src/channel/utils/tests/prepareChannelPayload.test.ts +22 -22
  411. package/src/client/api/connectClient.ts +11 -4
  412. package/src/client/api/createClient.ts +1 -1
  413. package/src/client/api/getChatSettings.ts +22 -0
  414. package/src/client/api/getSocialSettings.ts +24 -0
  415. package/src/client/api/tests/activeClient.test.ts +20 -0
  416. package/src/client/api/tests/activeUser.test.ts +20 -0
  417. package/src/client/api/tests/createClient.test.ts +40 -0
  418. package/src/client/tests/connectClient.test.ts +35 -0
  419. package/src/comment/api/createComment.ts +3 -3
  420. package/src/comment/api/tests/createComment.test.ts +49 -0
  421. package/src/comment/api/tests/getComments.test.ts +36 -0
  422. package/src/comment/events/tests/onCommentCreated.test.ts +27 -0
  423. package/src/comment/events/utils.ts +1 -1
  424. package/src/comment/observers/liveComments.ts +8 -8
  425. package/src/community/api/queryCommunities.ts +3 -2
  426. package/src/community/api/queryCommunityMembers.ts +59 -14
  427. package/src/community/api/test/addCommunityMember.test.ts +71 -0
  428. package/src/community/api/test/addCommunityMemberRole.test.ts +67 -0
  429. package/src/community/api/test/createCommunity.test.ts +61 -0
  430. package/src/community/api/test/deleteCommunity.test.ts +74 -0
  431. package/src/community/api/test/getCommunities.test.ts +73 -0
  432. package/src/community/api/test/getCommunity.test.ts +69 -0
  433. package/src/community/api/test/getRecommendedCommunities.test.ts +102 -0
  434. package/src/community/api/test/getTopTrendingCommunities.test.ts +102 -0
  435. package/src/community/api/test/joinCommunity.test.ts +70 -0
  436. package/src/community/api/test/leaveCommunity.test.ts +78 -0
  437. package/src/community/api/test/queryCommunity.test.ts +108 -0
  438. package/src/community/api/test/queryCommunityMembers.test.ts +122 -0
  439. package/src/community/api/test/removeCommunityMemberRole.test.ts +67 -0
  440. package/src/community/api/test/removeCommunityMembers.test.ts +75 -0
  441. package/src/community/api/test/updateCommunity.test.ts +65 -0
  442. package/src/community/events/test/onCommunityCreated.test.ts +46 -0
  443. package/src/community/events/test/onCommunityDeleted.test.ts +35 -0
  444. package/src/community/events/test/onCommunityJoined.test.ts +50 -0
  445. package/src/community/events/test/onCommunityLeft.test.ts +50 -0
  446. package/src/community/events/test/onCommunityUpdated.test.ts +49 -0
  447. package/src/community/events/test/onCommunityUserAdded.test.ts +50 -0
  448. package/src/community/events/test/onCommunityUserBanned.test.ts +50 -0
  449. package/src/community/events/test/onCommunityUserRemoved.test.ts +50 -0
  450. package/src/community/events/test/onCommunityUserUnbaned.test.ts +50 -0
  451. package/src/community/events/test/utils.test.ts +158 -0
  452. package/src/community/events/utils.ts +18 -10
  453. package/src/core/events.ts +9 -20
  454. package/src/core/model/idResolvers.ts +2 -1
  455. package/src/core/model/identifyModel.ts +1 -0
  456. package/src/core/model/index.ts +15 -0
  457. package/src/core/query/filtering.ts +2 -9
  458. package/src/core/query/query.ts +2 -34
  459. package/src/core/subscription.ts +47 -9
  460. package/src/core/tests/query/query/runQuery.test.ts +15 -38
  461. package/src/core/tests/subscription.test.ts +15 -0
  462. package/src/feed/api/queryGlobalFeed.ts +1 -1
  463. package/src/feed/api/test/queryGlobalFeed.test.ts +138 -0
  464. package/src/follow/events/utils.ts +1 -1
  465. package/src/follow/observers/liveFollowers.ts +8 -8
  466. package/src/follow/observers/liveFollowings.ts +8 -8
  467. package/src/group/utils/index.ts +1 -0
  468. package/src/group/utils/test/withUsers.test.ts +103 -0
  469. package/src/group/utils/withUser.ts +92 -0
  470. package/src/index.ts +4 -0
  471. package/src/message/api/createMessage.ts +60 -29
  472. package/src/message/api/deleteMessage.ts +6 -6
  473. package/src/message/api/getMessage.ts +5 -4
  474. package/src/message/api/getMessages.ts +7 -5
  475. package/src/message/api/queryMessages.ts +13 -25
  476. package/src/message/api/tests/createMessage.test.ts +129 -37
  477. package/src/message/api/tests/deleteMessage.test.ts +18 -12
  478. package/src/message/api/tests/getMessage.test.ts +6 -4
  479. package/src/message/api/tests/getMessages.test.ts +7 -8
  480. package/src/message/api/tests/queryMessages.test.ts +20 -23
  481. package/src/message/api/tests/updateMessage.test.ts +13 -12
  482. package/src/message/api/updateMessage.ts +12 -9
  483. package/src/message/events/index.ts +7 -1
  484. package/src/message/events/onMessageCreated.ts +50 -3
  485. package/src/message/events/onMessageDeleted.ts +14 -2
  486. package/src/message/events/onMessageFetched.ts +1 -1
  487. package/src/message/events/onMessageFlagCleared.ts +34 -0
  488. package/src/message/events/onMessageFlagged.ts +33 -0
  489. package/src/message/events/onMessageReactionAdded.ts +35 -0
  490. package/src/message/events/onMessageReactionRemoved.ts +40 -0
  491. package/src/message/events/onMessageUnflagged.ts +32 -0
  492. package/src/message/events/onMessageUpdated.ts +14 -10
  493. package/src/message/observers/liveMessage.ts +42 -23
  494. package/src/message/observers/liveMessages.ts +30 -16
  495. package/src/message/observers/observeMessage.ts +1 -0
  496. package/src/message/observers/observeMessages.ts +6 -5
  497. package/src/message/tests/events.test.ts +53 -0
  498. package/src/message/tests/observers/liveMessage.test.ts +46 -49
  499. package/src/message/tests/observers/liveMessages.test.ts +45 -37
  500. package/src/message/utils/index.ts +129 -0
  501. package/src/post/api/queryPosts.ts +9 -0
  502. package/src/post/api/tests/queryPosts.test.ts +149 -0
  503. package/src/post/events/tests/onPostApproved.test.ts +33 -0
  504. package/src/post/events/tests/onPostCreated.test.ts +33 -0
  505. package/src/post/events/tests/onPostDeclined.test.ts +33 -0
  506. package/src/post/events/tests/onPostDeleted.test.ts +33 -0
  507. package/src/post/events/tests/onPostFlagged.test.ts +33 -0
  508. package/src/post/events/tests/onPostReactionAdded.test.ts +40 -0
  509. package/src/post/events/tests/onPostReactionRemoved.test.ts +40 -0
  510. package/src/post/events/tests/onPostUnflagged.test.ts +33 -0
  511. package/src/post/events/tests/onPostUpdated.test.ts +33 -0
  512. package/src/post/events/utils.ts +1 -1
  513. package/src/post/observers/livePosts.ts +32 -12
  514. package/src/post/observers/tests/livePosts.test.ts +302 -0
  515. package/src/reaction/api/addReaction.ts +18 -3
  516. package/src/reaction/api/removeReaction.ts +23 -4
  517. package/src/reaction/api/tests/addReaction.test.ts +42 -6
  518. package/src/reaction/api/tests/removeReaction.test.ts +49 -13
  519. package/src/reaction/events/onReactionAdded.ts +4 -7
  520. package/src/reaction/events/onReactionRemoved.ts +4 -7
  521. package/src/reaction/events/onReactorAdded.ts +4 -2
  522. package/src/reaction/events/onReactorRemoved.ts +4 -7
  523. package/src/reaction/observers/liveReactions.ts +6 -6
  524. package/src/reaction/utils/dispatchReactable.ts +1 -1
  525. package/src/report/api/createReport.ts +28 -18
  526. package/src/report/api/deleteReport.ts +28 -18
  527. package/src/report/api/isReportedByMe.ts +9 -2
  528. package/src/subChannel/api/createSubChannel.ts +41 -0
  529. package/src/subChannel/api/deleteSubChannel.ts +53 -0
  530. package/src/subChannel/api/getSubChannel.ts +85 -0
  531. package/src/subChannel/api/getSubChannels.ts +77 -0
  532. package/src/subChannel/api/index.ts +8 -0
  533. package/src/subChannel/api/querySubChannels.ts +115 -0
  534. package/src/subChannel/api/updateSubChannel.ts +43 -0
  535. package/src/subChannel/events/index.ts +3 -0
  536. package/src/subChannel/events/onSubChannelCreated.ts +32 -0
  537. package/src/subChannel/events/onSubChannelDeleted.ts +44 -0
  538. package/src/subChannel/events/onSubChannelFetched.ts +12 -0
  539. package/src/subChannel/events/onSubChannelUpdated.ts +32 -0
  540. package/src/subChannel/observers/index.ts +2 -0
  541. package/src/subChannel/observers/liveSubChannel.ts +84 -0
  542. package/src/subChannel/observers/liveSubChannels.ts +137 -0
  543. package/src/subChannel/observers/tests/liveSubChannel.test.ts +212 -0
  544. package/src/subChannel/observers/tests/liveSubChannels.test.ts +206 -0
  545. package/src/subChannel/utils/index.ts +50 -0
  546. package/src/user/events/index.ts +0 -1
  547. package/src/user/events/utils.ts +1 -1
  548. package/src/user/observers/liveUser.ts +29 -23
  549. package/src/user/tests/observers/liveUser.test.ts +5 -9
  550. package/src/utils/index.ts +52 -0
  551. package/src/utils/tests/dummy/channel.ts +128 -114
  552. package/src/utils/tests/dummy/community.ts +108 -0
  553. package/src/utils/tests/dummy/file.ts +20 -0
  554. package/src/utils/tests/dummy/follow.ts +6 -0
  555. package/src/utils/tests/dummy/index.ts +11 -0
  556. package/src/utils/tests/dummy/member.ts +18 -0
  557. package/src/utils/tests/dummy/message.ts +44 -16
  558. package/src/utils/tests/dummy/poll.ts +43 -0
  559. package/src/utils/tests/dummy/post.ts +73 -1
  560. package/src/utils/tests/dummy/reaction.ts +22 -0
  561. package/src/utils/tests/dummy/role.ts +21 -0
  562. package/src/utils/tests/dummy/subChannel.ts +29 -0
  563. package/src/utils/tests/dummy/user.ts +8 -0
  564. package/src/utils/tests/utils.ts +2 -0
  565. package/dist/channel/utils/prepareChannelPayload.d.ts +0 -3
  566. package/dist/channel/utils/prepareChannelPayload.d.ts.map +0 -1
  567. package/src/channel/utils/prepareChannelPayload.ts +0 -31
package/dist/index.cjs.js CHANGED
@@ -106,6 +106,78 @@ const isProduction = ((_a$1 = safeProcess.env) === null || _a$1 === void 0 ? voi
106
106
  var _a, _b;
107
107
  const VERSION$1 = (_b = (_a = safeProcess.env) === null || _a === void 0 ? void 0 : _a.VERSION) !== null && _b !== void 0 ? _b : '__dev__';
108
108
 
109
+ // cache constants
110
+ const CACHE_KEY_GET = 'get';
111
+ const CACHE_KEY_TOMBSTONE = 'dead';
112
+ const CACHE_LIFESPAN = 1 * 60 * 1000; // 1 minute
113
+ const CACHE_LIFESPAN_TOMBSTONE = 3 * 60 * 1000; // 3 minutes
114
+ /**
115
+ * Shallow-clones an object and sort its keys
116
+ *
117
+ * @param source a plain object to clone
118
+ * @returns a clone of source, with keys sorted with default javascript sorting
119
+ *
120
+ * @category Cache
121
+ * @hidden
122
+ */
123
+ const normalize = (source) => Object.keys(source)
124
+ .sort()
125
+ .reduce((acc, key) => (Object.assign(Object.assign({}, acc), { [key]: source[key] })), {});
126
+ /**
127
+ * Encodes a given {@link Amity.CacheKey} to a plain string
128
+ *
129
+ * @param key the key to encode
130
+ * @returns an encoded string
131
+ *
132
+ * @category Cache
133
+ * @hidden
134
+ */
135
+ const encodeKey = (key) => JSON.stringify(key, (_, val) => (typeof val === 'object' ? normalize(val) : val));
136
+ /**
137
+ * Decodes a string back into a {@link Amity.CacheKey}
138
+
139
+ *
140
+ * @param key the string key to decode
141
+ * @returns a plain Amity.CacheKey object.
142
+ *
143
+ * @category Cache
144
+ * @hidden
145
+ */
146
+ const decodeKey = (key) => JSON.parse(key);
147
+ /**
148
+ * Performs a recursive partial deep equal check on two objects.
149
+ *
150
+ * @param predicate the reference object containing the partial information
151
+ * @param candidate the object to check against
152
+ * @returns true if the candidate contains all the values of the predicate
153
+ *
154
+ * @category Cache
155
+ */
156
+ const partialMatch = (predicate, candidate) => {
157
+ if (predicate === candidate)
158
+ return true;
159
+ // if one or the other is nullish, there can't be equality
160
+ if (!predicate || !candidate)
161
+ return false;
162
+ // we only perform recursive check on objects
163
+ if (typeof predicate !== 'object') {
164
+ return false;
165
+ }
166
+ // recursively call for partial match based on the predicate
167
+ return Object.keys(predicate).every(key => partialMatch(predicate[key], candidate[key]));
168
+ };
169
+ /**
170
+ * checks if passed error code is included in
171
+ * Tombstone errors list
172
+ *
173
+ * @param errorCode as {@link Amity.ServerError}
174
+ * @returns success boolean if the given errorCode
175
+ * is included in Tombstone errors list
176
+ *
177
+ * @category Cache
178
+ */
179
+ const checkIfShouldGoesToTombstone = (errorCode) => [400400 /* Amity.ServerError.ITEM_NOT_FOUND */, 400300 /* Amity.ServerError.FORBIDDEN */].includes(errorCode);
180
+
109
181
  /**
110
182
  * Type guard to find if the a given decoded backend token uses "skip/limit" pagination style
111
183
  *
@@ -255,12 +327,180 @@ const toPageRaw = (token) => {
255
327
  return undefined;
256
328
  };
257
329
 
330
+ /* eslint-disable no-use-before-define */
331
+ /**
332
+ * Type guard to check and cast that a given async function is has the ".locally" property
333
+ *
334
+ * @param func any SDK APi function
335
+ * @returns success boolean if the function has a 'locally' twin
336
+ *
337
+ * @hidden
338
+ */
339
+ const isFetcher = (func) => 'locally' in func;
340
+ /**
341
+ * Type guard to check and cast that a given async function is has the ".optimistically" property
342
+ *
343
+ * @param func any SDK APi function
344
+ * @returns success boolean if the function has an 'optimistically' twin
345
+ *
346
+ * @hidden
347
+ */
348
+ const isMutator = (func) => 'optimistically' in func;
349
+ /**
350
+ * Type guard to check and cast that a given async function is has
351
+ * the ".locally" or ".optimistically" property
352
+ *
353
+ * @param func any SDK APi function
354
+ * @returns success boolean if the function has an offline twin
355
+ *
356
+ * @hidden
357
+ */
358
+ const isOffline = (func) => isFetcher(func) || isMutator(func);
359
+ /**
360
+ * Type guard to check and cast that a given object has the "cachedAt" property
361
+ *
362
+ * @param model any object to check on
363
+ * @returns success boolean if the object has property "cachedAt"
364
+ *
365
+ * @hidden
366
+ */
367
+ const isCachable = (model) => model === null || model === void 0 ? void 0 : model.hasOwnProperty('cachedAt');
368
+ /**
369
+ * Checks if a model is considered local (cachedAt === -1)
370
+ *
371
+ * @param model any cachable object to check
372
+ * @returns success boolean if the object is marked as local
373
+ *
374
+ * @hidden
375
+ */
376
+ const isLocal = (model) => {
377
+ return isCachable(model) && (model === null || model === void 0 ? void 0 : model.cachedAt) === -1;
378
+ };
379
+ /**
380
+ * Checks if a model is considered fresh
381
+ *
382
+ * @param model any cachable object to check
383
+ * @param lifeSpan the supposedly duration for which the object is considered synced
384
+ * @returns success boolean if the object is below the given lifespan
385
+ *
386
+ * @hidden
387
+ */
388
+ const isFresh = (model, lifeSpan = CACHE_LIFESPAN) => {
389
+ var _a;
390
+ return Date.now() - ((_a = model === null || model === void 0 ? void 0 : model.cachedAt) !== null && _a !== void 0 ? _a : 0) <= lifeSpan;
391
+ };
392
+ /**
393
+ * ```js
394
+ * import { createQuery, getUser } from '@amityco/ts-sdk'
395
+ * const query = createQuery(getUser, 'foobar')
396
+ * ```
397
+ *
398
+ * Creates a wrapper for the API call you wish to call.
399
+ * This wrapper is necessary to create for optimistically calls
400
+ *
401
+ *
402
+ * @param func A compatible API function from the ts sdk
403
+ * @param args The arguments to pass to the function passed as `fn`
404
+ * @returns A wrapper containing both the function and its future arguments
405
+ *
406
+ * @category Query
407
+ */
408
+ const createQuery = (func, ...args) => ({ func, args });
409
+ /**
410
+ * ```js
411
+ * import { queryOptions } from '@amityco/ts-sdk'
412
+ * const options = queryOptions('no_fetch', lifeSpan)
413
+ * ```
414
+ *
415
+ * Creates a query options object based on the query policy passed
416
+ *
417
+ * @param policy The policy to apply to a query
418
+ * @returns A properly set query options object
419
+ *
420
+ * @category Query
421
+ */
422
+ const queryOptions = (policy, lifeSpan = CACHE_LIFESPAN) => {
423
+ if (policy === 'cache_only')
424
+ return { lifeSpan: Infinity };
425
+ return { lifeSpan: lifeSpan < CACHE_LIFESPAN ? CACHE_LIFESPAN : lifeSpan };
426
+ };
427
+ /**
428
+ * ```js
429
+ * import { createQuery, getUser, runQuery } from '@amityco/ts-sdk'
430
+ * const query = createQuery(getUser, client, 'foobar')
431
+ * runQuery(query, user => console.log(user))
432
+ * ```
433
+ *
434
+ * Calls an API function wrapped around a Amity.Query, and executes the callback whenever
435
+ * a value is available. The value can be picked either from the local cache and/or
436
+ * from the server afterwards depending on the query options passed
437
+ *
438
+ * @param query A query object wrapping the call to be made
439
+ * @param callback A function to execute when a value is available
440
+ * @param options the query options
441
+ *
442
+ * @category Query
443
+ */
444
+ const runQuery = ({ func, args }, callback, options = queryOptions('cache_then_server')) => {
445
+ let local;
446
+ const { lifeSpan } = queryOptions('cache_then_server', options.lifeSpan);
447
+ // offline first
448
+ if (isOffline(func)) {
449
+ try {
450
+ local = isMutator(func) ? func.optimistically(...args) : func.locally(...args);
451
+ }
452
+ catch (error) {
453
+ callback === null || callback === void 0 ? void 0 : callback(createSnapshot(undefined, {
454
+ origin: 'local',
455
+ loading: false,
456
+ error,
457
+ }));
458
+ }
459
+ const shouldAbort = isCachable(local) && isFresh(local, lifeSpan);
460
+ callback === null || callback === void 0 ? void 0 : callback(createSnapshot(local, {
461
+ origin: 'local',
462
+ loading: !(isFetcher(func) && shouldAbort),
463
+ }));
464
+ if (shouldAbort)
465
+ return;
466
+ }
467
+ else {
468
+ callback === null || callback === void 0 ? void 0 : callback(createSnapshot(undefined, {
469
+ origin: 'local',
470
+ loading: true,
471
+ }));
472
+ }
473
+ func(...args)
474
+ .then(fresh => {
475
+ // @ts-ignore i know.
476
+ // isLocal(local) && syncInCache(local, fresh)
477
+ callback === null || callback === void 0 ? void 0 : callback(createSnapshot(fresh, {
478
+ origin: 'server',
479
+ loading: false,
480
+ }));
481
+ })
482
+ .catch(error => {
483
+ callback === null || callback === void 0 ? void 0 : callback(createSnapshot(undefined, {
484
+ origin: 'server',
485
+ loading: false,
486
+ error,
487
+ }));
488
+ });
489
+ };
490
+ // eslint-disable-next-line no-redeclare
491
+ function createSnapshot(data, options) {
492
+ if (isPaged(data) || isCachable(data))
493
+ return Object.assign(Object.assign({}, options), data);
494
+ return Object.assign(Object.assign({}, options), { data });
495
+ }
496
+
258
497
  /** @hidden */
259
498
  const idResolvers = {
260
499
  user: ({ userId }) => userId,
261
500
  file: ({ fileId }) => fileId,
262
501
  role: ({ roleId }) => roleId,
263
502
  channel: ({ channelId }) => channelId,
503
+ subChannel: ({ subChannelId }) => subChannelId,
264
504
  channelUsers: ({ channelId, userId }) => `${channelId}#${userId}`,
265
505
  message: ({ messageId }) => messageId,
266
506
  community: ({ communityId }) => communityId,
@@ -297,6 +537,7 @@ const CRITERIAS = {
297
537
  user: ['userId', 'avatarFileId'],
298
538
  role: ['roleId'],
299
539
  channel: ['channelId', 'rateLimit'],
540
+ subChannel: ['subChannelId'],
300
541
  channelUsers: ['channelId', 'userId', 'membership'],
301
542
  message: ['messageId'],
302
543
  community: ['communityId', 'postSetting'],
@@ -355,6 +596,7 @@ const PAYLOAD2MODEL = {
355
596
  files: 'file',
356
597
  roles: 'role',
357
598
  channels: 'channel',
599
+ messageFeeds: 'subChannel',
358
600
  channelUsers: 'channelUsers',
359
601
  messages: 'message',
360
602
  communities: 'community',
@@ -368,277 +610,17 @@ const PAYLOAD2MODEL = {
368
610
  videoStreamings: 'stream',
369
611
  follows: 'follow',
370
612
  followCounts: 'followCount',
371
- };
613
+ };
614
+ /** hidden */
615
+ const hasUpdates = (prevData, nextData) => {
616
+ return new Date(prevData.updatedAt) < new Date(nextData.updatedAt);
617
+ };
618
+ /** hidden */
619
+ function getFutureDate(date = new Date().toISOString()) {
620
+ return new Date(new Date(date).getTime() + 1).toISOString();
621
+ }
372
622
 
373
- // cache constants
374
- const CACHE_KEY_GET = 'get';
375
- const CACHE_KEY_TOMBSTONE = 'dead';
376
- const CACHE_LIFESPAN = 1 * 60 * 1000; // 1 minute
377
- const CACHE_LIFESPAN_TOMBSTONE = 3 * 60 * 1000; // 3 minutes
378
- /**
379
- * Shallow-clones an object and sort its keys
380
- *
381
- * @param source a plain object to clone
382
- * @returns a clone of source, with keys sorted with default javascript sorting
383
- *
384
- * @category Cache
385
- * @hidden
386
- */
387
- const normalize = (source) => Object.keys(source)
388
- .sort()
389
- .reduce((acc, key) => (Object.assign(Object.assign({}, acc), { [key]: source[key] })), {});
390
- /**
391
- * Encodes a given {@link Amity.CacheKey} to a plain string
392
- *
393
- * @param key the key to encode
394
- * @returns an encoded string
395
- *
396
- * @category Cache
397
- * @hidden
398
- */
399
- const encodeKey = (key) => JSON.stringify(key, (_, val) => (typeof val === 'object' ? normalize(val) : val));
400
- /**
401
- * Decodes a string back into a {@link Amity.CacheKey}
402
-
403
- *
404
- * @param key the string key to decode
405
- * @returns a plain Amity.CacheKey object.
406
- *
407
- * @category Cache
408
- * @hidden
409
- */
410
- const decodeKey = (key) => JSON.parse(key);
411
- /**
412
- * Performs a recursive partial deep equal check on two objects.
413
- *
414
- * @param predicate the reference object containing the partial information
415
- * @param candidate the object to check against
416
- * @returns true if the candidate contains all the values of the predicate
417
- *
418
- * @category Cache
419
- */
420
- const partialMatch = (predicate, candidate) => {
421
- if (predicate === candidate)
422
- return true;
423
- // if one or the other is nullish, there can't be equality
424
- if (!predicate || !candidate)
425
- return false;
426
- // we only perform recursive check on objects
427
- if (typeof predicate !== 'object') {
428
- return false;
429
- }
430
- // recursively call for partial match based on the predicate
431
- return Object.keys(predicate).every(key => partialMatch(predicate[key], candidate[key]));
432
- };
433
- /**
434
- * checks if passed error code is included in
435
- * Tombstone errors list
436
- *
437
- * @param errorCode as {@link Amity.ServerError}
438
- * @returns success boolean if the given errorCode
439
- * is included in Tombstone errors list
440
- *
441
- * @category Cache
442
- */
443
- const checkIfShouldGoesToTombstone = (errorCode) => [400400 /* Amity.ServerError.ITEM_NOT_FOUND */, 400300 /* Amity.ServerError.FORBIDDEN */].includes(errorCode);
444
-
445
- /* eslint-disable no-use-before-define */
446
- /**
447
- * Type guard to check and cast that a given async function is has the ".locally" property
448
- *
449
- * @param func any SDK APi function
450
- * @returns success boolean if the function has a 'locally' twin
451
- *
452
- * @hidden
453
- */
454
- const isFetcher = (func) => 'locally' in func;
455
- /**
456
- * Type guard to check and cast that a given async function is has the ".optimistically" property
457
- *
458
- * @param func any SDK APi function
459
- * @returns success boolean if the function has an 'optimistically' twin
460
- *
461
- * @hidden
462
- */
463
- const isMutator = (func) => 'optimistically' in func;
464
- /**
465
- * Type guard to check and cast that a given async function is has
466
- * the ".locally" or ".optimistically" property
467
- *
468
- * @param func any SDK APi function
469
- * @returns success boolean if the function has an offline twin
470
- *
471
- * @hidden
472
- */
473
- const isOffline = (func) => isFetcher(func) || isMutator(func);
474
- /**
475
- * Type guard to check and cast that a given object has the "cachedAt" property
476
- *
477
- * @param model any object to check on
478
- * @returns success boolean if the object has property "cachedAt"
479
- *
480
- * @hidden
481
- */
482
- const isCachable = (model) => model === null || model === void 0 ? void 0 : model.hasOwnProperty('cachedAt');
483
- /**
484
- * Checks if a model is considered local (cachedAt === -1)
485
- *
486
- * @param model any cachable object to check
487
- * @returns success boolean if the object is marked as local
488
- *
489
- * @hidden
490
- */
491
- const isLocal = (model) => {
492
- return isCachable(model) && (model === null || model === void 0 ? void 0 : model.cachedAt) === -1;
493
- };
494
- /**
495
- * Checks if a model is considered fresh
496
- *
497
- * @param model any cachable object to check
498
- * @param lifeSpan the supposedly duration for which the object is considered synced
499
- * @returns success boolean if the object is below the given lifespan
500
- *
501
- * @hidden
502
- */
503
- const isFresh = (model, lifeSpan = CACHE_LIFESPAN) => {
504
- var _a;
505
- return Date.now() - ((_a = model === null || model === void 0 ? void 0 : model.cachedAt) !== null && _a !== void 0 ? _a : 0) <= lifeSpan;
506
- };
507
- /**
508
- * ```js
509
- * import { createQuery, getUser } from '@amityco/ts-sdk'
510
- * const query = createQuery(getUser, 'foobar')
511
- * ```
512
- *
513
- * Creates a wrapper for the API call you wish to call.
514
- * This wrapper is necessary to create for optimistically calls
515
- *
516
- *
517
- * @param func A compatible API function from the ts sdk
518
- * @param args The arguments to pass to the function passed as `fn`
519
- * @returns A wrapper containing both the function and its future arguments
520
- *
521
- * @category Query
522
- */
523
- const createQuery = (func, ...args) => ({ func, args });
524
- /**
525
- * ```js
526
- * import { queryOptions } from '@amityco/ts-sdk'
527
- * const options = queryOptions('no_fetch', lifeSpan)
528
- * ```
529
- *
530
- * Creates a query options object based on the query policy passed
531
- *
532
- * @param policy The policy to apply to a query
533
- * @returns A properly set query options object
534
- *
535
- * @category Query
536
- */
537
- const queryOptions = (policy, lifeSpan = CACHE_LIFESPAN) => {
538
- if (policy === 'cache_only')
539
- return { lifeSpan: Infinity };
540
- return { lifeSpan: lifeSpan < CACHE_LIFESPAN ? CACHE_LIFESPAN : lifeSpan };
541
- };
542
- /**
543
- * ```js
544
- * import { createQuery, getUser, runQuery } from '@amityco/ts-sdk'
545
- * const query = createQuery(getUser, client, 'foobar')
546
- * runQuery(query, user => console.log(user))
547
- * ```
548
- *
549
- * Calls an API function wrapped around a Amity.Query, and executes the callback whenever
550
- * a value is available. The value can be picked either from the local cache and/or
551
- * from the server afterwards depending on the query options passed
552
- *
553
- * @param query A query object wrapping the call to be made
554
- * @param callback A function to execute when a value is available
555
- * @param options the query options
556
- *
557
- * @category Query
558
- */
559
- const runQuery = ({ func, args }, callback, options = queryOptions('cache_then_server')) => {
560
- let local;
561
- const { lifeSpan } = queryOptions('cache_then_server', options.lifeSpan);
562
- // offline first
563
- if (isOffline(func)) {
564
- try {
565
- local = isMutator(func) ? func.optimistically(...args) : func.locally(...args);
566
- }
567
- catch (error) {
568
- callback === null || callback === void 0 ? void 0 : callback(createSnapshot(undefined, {
569
- origin: 'local',
570
- loading: false,
571
- error,
572
- }));
573
- }
574
- const shouldAbort = isCachable(local) && isFresh(local, lifeSpan);
575
- callback === null || callback === void 0 ? void 0 : callback(createSnapshot(local, {
576
- origin: 'local',
577
- loading: !(isFetcher(func) && shouldAbort),
578
- }));
579
- if (shouldAbort)
580
- return;
581
- }
582
- else {
583
- callback === null || callback === void 0 ? void 0 : callback(createSnapshot(undefined, {
584
- origin: 'local',
585
- loading: true,
586
- }));
587
- }
588
- let optimisticArgs = args;
589
- /* get args for optimistic method calls
590
- *
591
- * On optimistic updates, the modal key for the update needs to be passed to
592
- * the server so as to avoid duplicate modal creation
593
- *
594
- * ex: on creating a new message pass the modalKey is messageId, pass this
595
- * id onto the server so that a duplicate with seperate messageId is not
596
- * created.
597
- */
598
- if (isMutator(func)) {
599
- // @ts-ignore
600
- const modelKey = local && local.data && identifyModelKey(local.data);
601
- if (modelKey) {
602
- /*
603
- * modal key is only required for create as update and delete queries pass
604
- * the modal key in the param itself
605
- * For update & delete the first argument is always an id which is of type
606
- * string, whereas for create the first and only argument is the param object
607
- *
608
- * When creating an AmityObject optimistically we need to pass the modal key
609
- * on to the server. ex: for create message modal key will be 'messageId`
610
- */
611
- if (typeof args[0] !== 'string') {
612
- // @ts-ignore
613
- optimisticArgs = [Object.assign(Object.assign({}, args[0]), { [modelKey]: local.data[modelKey] })];
614
- }
615
- }
616
- }
617
- func(...optimisticArgs)
618
- .then(fresh => {
619
- // @ts-ignore i know.
620
- // isLocal(local) && syncInCache(local, fresh)
621
- callback === null || callback === void 0 ? void 0 : callback(createSnapshot(fresh, {
622
- origin: 'server',
623
- loading: false,
624
- }));
625
- })
626
- .catch(error => {
627
- callback === null || callback === void 0 ? void 0 : callback(createSnapshot(undefined, {
628
- origin: 'server',
629
- loading: false,
630
- error,
631
- }));
632
- });
633
- };
634
- // eslint-disable-next-line no-redeclare
635
- function createSnapshot(data, options) {
636
- if (isPaged(data) || isCachable(data))
637
- return Object.assign(Object.assign({}, options), data);
638
- return Object.assign(Object.assign({}, options), { data });
639
- }
640
-
641
- /* eslint-disable max-classes-per-file */
623
+ /* eslint-disable max-classes-per-file */
642
624
  /**
643
625
  * Generic ASC error
644
626
  * @category Errors
@@ -1094,16 +1076,10 @@ const filterByChannelMembership = (collection, membership, userId) => {
1094
1076
  'get',
1095
1077
  channelUserCacheKey,
1096
1078
  ])) === null || _a === void 0 ? void 0 : _a.data;
1097
- // if channel user is defined for user, user is a member
1098
- if (membership === 'member' && channelUser) {
1099
- return true;
1100
- }
1101
- // if channel user by user id not found, user is not a member of that
1102
- // channel
1103
- if (membership === 'notMember' && !channelUser) {
1079
+ if (membership === 'member' && channelUser && channelUser.membership !== 'none') {
1104
1080
  return true;
1105
1081
  }
1106
- return false;
1082
+ return membership === 'notMember' && (!channelUser || channelUser.membership === 'none');
1107
1083
  });
1108
1084
  };
1109
1085
 
@@ -1164,19 +1140,6 @@ const WS_EVENTS = [
1164
1140
  'connect_error',
1165
1141
  'reconnect_error',
1166
1142
  'reconnect_failed',
1167
- 'v3.channel.didCreate',
1168
- 'v3.channel.didUpdate',
1169
- 'v3.channel.didDelete',
1170
- 'v3.channel.didJoin',
1171
- 'v3.channel.didLeave',
1172
- 'v3.channel.didAddUsers',
1173
- 'v3.channel.didRemoveUsers',
1174
- 'v3.channel.didBan',
1175
- 'v3.channel.didUnban',
1176
- 'v3.message.didFetch',
1177
- 'v3.message.didCreate',
1178
- 'v3.message.didUpdate',
1179
- 'v3.message.didDelete',
1180
1143
  ];
1181
1144
  const MQTT_EVENTS = [
1182
1145
  'connect',
@@ -1203,16 +1166,23 @@ const createEventEmitter = () => {
1203
1166
  */
1204
1167
  const proxyWebsocketEvents = (ws, emitter) => {
1205
1168
  WS_EVENTS.forEach(event => {
1206
- ws.on(event, (param) => emitter.emit(event, param));
1169
+ ws.on(event, (param) => {
1170
+ console.log('ws', event, param);
1171
+ emitter.emit(event, param);
1172
+ });
1207
1173
  });
1208
1174
  };
1209
1175
  const proxyMqttEvents = (mqttClient, emitter) => {
1210
1176
  MQTT_EVENTS.forEach(event => {
1211
- mqttClient.on(event, (...params) => emitter.emit(event, params.length === 1 ? params[0] : params));
1177
+ mqttClient.on(event, (...params) => {
1178
+ console.log('mqtt', event, params);
1179
+ emitter.emit(event, params.length === 1 ? params[0] : params);
1180
+ });
1212
1181
  });
1213
1182
  // @ts-ignore
1214
1183
  mqttClient.on('message', (topic, payload) => {
1215
1184
  const message = JSON.parse(payload.toString());
1185
+ console.log('mqtt message', message);
1216
1186
  emitter.emit(message.eventType, message.data);
1217
1187
  });
1218
1188
  };
@@ -1292,6 +1262,7 @@ const getCommunityUserTopic = (path, level) => {
1292
1262
  return path;
1293
1263
  }
1294
1264
  };
1265
+ const getNetworkId = (user) => user.path.split('/user/')[0];
1295
1266
  const getCommunityTopic = ({ path }, level = exports.SubscriptionLevels.COMMUNITY) => getCommunityUserTopic(path, level);
1296
1267
  const getUserTopic = ({ path }, level = exports.SubscriptionLevels.USER) => getCommunityUserTopic(level === exports.SubscriptionLevels.USER ? path : path.replace(/^(\w*)/, '$1/social'), level);
1297
1268
  const getPostTopic = ({ path }, level = exports.SubscriptionLevels.POST) => {
@@ -1307,24 +1278,54 @@ const getCommentTopic = ({ path }) => {
1307
1278
  };
1308
1279
  const getMyFollowersTopic = () => {
1309
1280
  const user = getActiveUser();
1310
- const [networkId] = user.path.split('/user/');
1311
- return `${networkId}/membership/${user._id}/+/+`;
1281
+ return `${getNetworkId(user)}/membership/${user._id}/+/+`;
1312
1282
  };
1313
1283
  const getMyFollowingsTopic = () => {
1314
1284
  const user = getActiveUser();
1315
- const [networkId] = user.path.split('/user/');
1316
- return `${networkId}/membership/+/${user._id}/+`;
1285
+ return `${getNetworkId(user)}/membership/+/${user._id}/+`;
1317
1286
  };
1318
- /** @hidden */
1287
+ const getChannelTopic = (channel) => `${channel.path}/#`;
1288
+ const getSubChannelTopic = (subChannel) => `${subChannel.path}/#`;
1289
+ const getMessageTopic = (message) => message.path;
1290
+ /**
1291
+ * @hidden
1292
+ *
1293
+ * Create a topic to subscribe to network level events like 'user is deleted from the network'
1294
+ */
1319
1295
  const getNetworkTopic = () => {
1320
- const user = getActiveUser();
1321
- const [networkId] = user.path.split('/user/');
1322
- return networkId;
1296
+ return getNetworkId(getActiveUser());
1323
1297
  };
1324
- let mqttAccessToken;
1325
- let mqttUserId;
1326
- function subscribeTopic(topic, callback) {
1327
- const { mqtt, emitter, accessToken } = getActiveClient();
1298
+ /**
1299
+ * @hidden
1300
+ *
1301
+ * Create a topic to subscribe to channel events for 'conversation', 'community' channel
1302
+ */
1303
+ const getSmartFeedChannelTopic = () => {
1304
+ const user = getActiveUser();
1305
+ return `${getNetworkId(user)}/smartfeed/${user._id}/channels`;
1306
+ };
1307
+ /**
1308
+ * @hidden
1309
+ *
1310
+ * Create a topic to subscribe to sub channel events for 'conversation', 'community' channel
1311
+ */
1312
+ const getSmartFeedSubChannelTopic = () => {
1313
+ const user = getActiveUser();
1314
+ return `${getNetworkId(user)}/smartfeed/${user._id}/messagefeeds`;
1315
+ };
1316
+ /**
1317
+ * @hidden
1318
+ *
1319
+ * Create a topic to subscribe to message events for 'conversation', 'community' channel
1320
+ */
1321
+ const getSmartFeedMessageTopic = () => {
1322
+ const user = getActiveUser();
1323
+ return `${getNetworkId(user)}/smartfeed/${user._id}/messages`;
1324
+ };
1325
+ let mqttAccessToken;
1326
+ let mqttUserId;
1327
+ function subscribeTopic(topic, callback) {
1328
+ const { mqtt, emitter, accessToken } = getActiveClient();
1328
1329
  const user = getActiveUser();
1329
1330
  if (mqttAccessToken !== accessToken || mqttUserId !== user._id) {
1330
1331
  mqttAccessToken = accessToken;
@@ -20335,7 +20336,7 @@ const createClient = (apiKey, apiRegion = API_REGIONS.SG, { debugSession = DEFAU
20335
20336
  getFeedSettings,
20336
20337
  };
20337
20338
  try {
20338
- getActiveClient();
20339
+ return getActiveClient();
20339
20340
  }
20340
20341
  catch (_c) {
20341
20342
  setActiveClient(client);
@@ -20410,7 +20411,7 @@ const getDeviceInfo = () => {
20410
20411
  * Ingest a payload (v3) into the cache
20411
20412
  *
20412
20413
  * @param payload a "backend v3" payload object
20413
- * @param order the order of the keys to process (in case of need)
20414
+ * @param options caching options like cachedAt or offline
20414
20415
  *
20415
20416
  * @category Cache
20416
20417
  * @hidden
@@ -20422,9 +20423,7 @@ const ingestInCache = (payload = {}, options) => {
20422
20423
  return;
20423
20424
  const resolver = getResolver(type);
20424
20425
  models.forEach(model => {
20425
- upsertInCache(
20426
- // eslint-disable @typescript-eslint no-explicit-any
20427
- [type, 'get', resolver(model)], // this 'any' cannot be avoided, sorry.
20426
+ upsertInCache([type, 'get', resolver(model)], // this 'any' cannot be avoided, sorry.
20428
20427
  model, options);
20429
20428
  });
20430
20429
  });
@@ -20588,9 +20587,8 @@ const connectClient = async (params, config) => {
20588
20587
  // @ts-ignore: in that particular case, typing can be
20589
20588
  // ignored since we enforce default values just before.
20590
20589
  const { accessToken, users } = await getToken(params);
20591
- // manually setup the token for http transport
20590
+ // manually setup the token for http, ws transport
20592
20591
  client.http.defaults.headers.common.Authorization = `Bearer ${accessToken}`;
20593
- // manually setup the token for ws transport
20594
20592
  client.ws.io.opts.query = { token: accessToken };
20595
20593
  // FIXME: events are duplicated if connectClient is called few times without disconnectClient
20596
20594
  // wire websocket events to our event emitter
@@ -20606,6 +20604,9 @@ const connectClient = async (params, config) => {
20606
20604
  setActiveUser(users[0]);
20607
20605
  if ((config === null || config === void 0 ? void 0 : config.disableRTE) !== true) {
20608
20606
  subscribeTopic(getNetworkTopic());
20607
+ subscribeTopic(getSmartFeedChannelTopic());
20608
+ subscribeTopic(getSmartFeedSubChannelTopic());
20609
+ subscribeTopic(getSmartFeedMessageTopic());
20609
20610
  }
20610
20611
  const subscriptions = [
20611
20612
  onClientBanned(() => {
@@ -20958,23 +20959,6 @@ const updateUser = async (userId, patch) => {
20958
20959
  };
20959
20960
  };
20960
20961
 
20961
- /**
20962
- * ```js
20963
- * import { onUserFetched } from '@amityco/ts-sdk'
20964
- * const dispose = onUserFetched(user => {
20965
- * // ...
20966
- * })
20967
- * ```
20968
- *
20969
- * Fired when a {@link Amity.User} has been fetched
20970
- *
20971
- * @param callback The function to call when the event was fired
20972
- * @returns an {@link Amity.Unsubscriber} function to stop listening
20973
- *
20974
- * @category User Events
20975
- */
20976
- const onUserFetched = (callback) => createUserEventSubscriber('user.fetched', callback);
20977
-
20978
20962
  /**
20979
20963
  * ```js
20980
20964
  * import { onUserUpdated } from '@amityco/ts-sdk'
@@ -21052,52 +21036,72 @@ const UNSYNCED_OBJECT_CACHED_AT_VALUE = -5;
21052
21036
 
21053
21037
  /**
21054
21038
  * ```js
21055
- * import { liveUser } from '@amityco/ts-sdk'
21039
+ * import { onUserFetched } from '@amityco/ts-sdk'
21040
+ * const dispose = onUserFetched(user => {
21041
+ * // ...
21042
+ * })
21043
+ * ```
21044
+ *
21045
+ * Fired when a {@link Amity.User} has been fetched
21046
+ *
21047
+ * @param callback The function to call when the event was fired
21048
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
21049
+ *
21050
+ * @category User Events
21051
+ */
21052
+ const onUserFetched = (callback) => createUserEventSubscriber('user.fetched', callback);
21053
+
21054
+ /**
21055
+ * ```js
21056
+ * import { liveUser } from '@amityco/ts-sdk';
21056
21057
  *
21057
- * let users = []
21058
- * const unsub = liveUser(userId, response => merge(users, response.data))
21058
+ * let user;
21059
+ *
21060
+ * const unsubscribe = liveUser(userId, response => {
21061
+ * user = response.data;
21062
+ * });
21059
21063
  * ```
21060
21064
  *
21061
21065
  * Observe all mutation on a given {@link Amity.User}
21062
21066
  *
21063
21067
  * @param userId the ID of the user to observe
21064
21068
  * @param callback the function to call when new data are available
21065
- * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the users
21069
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the user
21066
21070
  *
21067
21071
  * @category Message Live Object
21068
21072
  */
21069
21073
  const liveUser = (userId, callback) => {
21070
21074
  const { log, cache } = getActiveClient();
21071
- let user;
21075
+ const timestamp = Date.now();
21076
+ log(`liveUser(tmpid: ${timestamp}) > listen`);
21072
21077
  if (!cache) {
21073
21078
  console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
21074
21079
  }
21075
- const timestamp = Date.now();
21076
- log(`liveUser(tmpid: ${timestamp}) > listen`);
21080
+ let user;
21077
21081
  const disposers = [];
21078
21082
  const dispatcher = (data) => {
21079
- var _a;
21080
- // we check updatedAt to see if the current snapshot is new so
21081
- // we won't send old data back, only fresh new data
21082
- if (user && ((_a = data.data) === null || _a === void 0 ? void 0 : _a.updatedAt) === (user === null || user === void 0 ? void 0 : user.updatedAt) && data.origin !== 'server')
21083
- return;
21084
- callback(data);
21085
21083
  user = data.data;
21084
+ callback(data);
21086
21085
  };
21087
- const realtimeRouter = (user, action) => {
21088
- dispatcher({ loading: false, data: user, origin: 'event' });
21086
+ const realtimeRouter = (eventUser) => {
21087
+ if (userId !== eventUser.userId) {
21088
+ return;
21089
+ }
21090
+ if (user && !hasUpdates(user, eventUser)) {
21091
+ return;
21092
+ }
21093
+ dispatcher({ loading: false, data: eventUser, origin: 'event' });
21089
21094
  };
21090
21095
  const onFetch = () => {
21091
21096
  const query = createQuery(getUser, userId, true);
21092
21097
  runQuery(query, ({ loading, data, error, origin }) => {
21093
21098
  dispatcher({ loading, data, origin, error });
21094
21099
  if (error) {
21095
- // Terminate observe functionality on error
21096
21100
  disposers.forEach(fn => fn());
21097
21101
  }
21098
21102
  });
21099
21103
  };
21100
- disposers.push(onUserFetched(user => realtimeRouter(user)), onUserUpdated(user => realtimeRouter(user)), onUserDeleted(user => realtimeRouter(user)), onUserFlagged(user => realtimeRouter(user)), onUserUnflagged(user => realtimeRouter(user)), onUserFlagCleared(user => realtimeRouter(user)));
21104
+ disposers.push(onUserFetched(realtimeRouter), onUserUpdated(realtimeRouter), onUserDeleted(realtimeRouter), onUserFlagged(realtimeRouter), onUserUnflagged(realtimeRouter), onUserFlagCleared(realtimeRouter));
21101
21105
  onFetch();
21102
21106
  return () => {
21103
21107
  log(`liveUser(tmpid: ${timestamp}) > dispose`);
@@ -21511,7 +21515,7 @@ getRole.locally = (roleId) => {
21511
21515
  const dispatchReactable = (referenceType, model) => {
21512
21516
  if (referenceType === 'message')
21513
21517
  // @ts-ignore: refactor later
21514
- fireEvent('v3.message.didUpdate', { messages: [model] });
21518
+ fireEvent('local.message.updated', { messages: [model] });
21515
21519
  else if (referenceType === 'post')
21516
21520
  // @ts-ignore: refactor later
21517
21521
  fireEvent('post.updated', { posts: [model] });
@@ -21520,6 +21524,100 @@ const dispatchReactable = (referenceType, model) => {
21520
21524
  fireEvent('comment.updated', { comments: [model] });
21521
21525
  };
21522
21526
 
21527
+ /** @hidden */
21528
+ /*
21529
+ * @param message payload from http request without myReactions
21530
+ * add myReactions to http response if the event was a reaction event
21531
+ */
21532
+ const prepareMessagePayloadForCache = (payload) => {
21533
+ const client = getActiveClient();
21534
+ const cached = pullFromCache(['message', 'get', payload.messageId]);
21535
+ // '[]' in cases where the new reaction is the first one
21536
+ const myReactions = (cached === null || cached === void 0 ? void 0 : cached.data.myReactions) || [];
21537
+ // add myReactions to the payload
21538
+ Object.assign(payload, { myReactions });
21539
+ // check if there are any updates to the reactions
21540
+ const latestReaction = payload === null || payload === void 0 ? void 0 : payload.latestReaction;
21541
+ const isLatestReactionMine = latestReaction && latestReaction.userId === client.userId;
21542
+ if (!isLatestReactionMine) {
21543
+ return;
21544
+ }
21545
+ // new reaction added
21546
+ if (latestReaction.eventName === 'add' && !myReactions.includes(latestReaction.reactionName)) {
21547
+ Object.assign(payload, {
21548
+ myReactions: [...myReactions, latestReaction.reactionName],
21549
+ });
21550
+ }
21551
+ // existing reaction removed
21552
+ if (latestReaction.eventName === 'remove' && myReactions.includes(latestReaction.reactionName)) {
21553
+ Object.assign(payload, {
21554
+ myReactions: myReactions.filter(x => x !== latestReaction.reactionName),
21555
+ });
21556
+ }
21557
+ };
21558
+
21559
+ function convertFromRaw$2(_a) {
21560
+ var { channelPublicId, childCount, creatorPublicId, mentionedUsers, messageFeedId, myReactions, reactionCount, reactions, referenceId, segment } = _a, rest = __rest(_a, ["channelPublicId", "childCount", "creatorPublicId", "mentionedUsers", "messageFeedId", "myReactions", "reactionCount", "reactions", "referenceId", "segment"]);
21561
+ let cache;
21562
+ if (referenceId) {
21563
+ try {
21564
+ cache = pullFromCache(['message', 'get', referenceId]);
21565
+ // eslint-disable-next-line no-empty
21566
+ }
21567
+ catch (_b) { }
21568
+ }
21569
+ if (!cache) {
21570
+ try {
21571
+ cache = pullFromCache(['message', 'get', rest.messageId]);
21572
+ // eslint-disable-next-line no-empty
21573
+ }
21574
+ catch (_c) { }
21575
+ }
21576
+ const out = Object.assign(Object.assign({}, rest), { channelId: channelPublicId, channelSegment: segment, childrenNumber: childCount, creatorId: creatorPublicId, reactions: reactions !== null && reactions !== void 0 ? reactions : {}, reactionsCount: reactionCount, subChannelId: messageFeedId, uniqueId: cache ? cache.data.uniqueId : rest.messageId });
21577
+ if (mentionedUsers) {
21578
+ out.mentionees = mentionedUsers.map(mention => {
21579
+ if (mention.type === 'channel') {
21580
+ return mention;
21581
+ }
21582
+ return { type: 'user', userIds: mention.userPublicIds };
21583
+ });
21584
+ }
21585
+ if (myReactions) {
21586
+ // http response
21587
+ out.myReactions = myReactions;
21588
+ }
21589
+ else {
21590
+ // mqtt event
21591
+ try {
21592
+ prepareMessagePayloadForCache(out);
21593
+ // eslint-disable-next-line no-empty
21594
+ }
21595
+ catch (_d) { }
21596
+ }
21597
+ return out;
21598
+ }
21599
+ const prepareMessagePayload = (payload) => {
21600
+ return Object.assign(Object.assign({}, payload), { messages: payload.messages.map(convertFromRaw$2) });
21601
+ };
21602
+ const convertResponseFromRaw = (response) => {
21603
+ return Object.assign(Object.assign({}, response), { data: Object.assign(Object.assign({}, response.data), { messages: response.data.messages.map(convertFromRaw$2) }) });
21604
+ };
21605
+ function convertParams(_a) {
21606
+ var { subChannelId, mentionees } = _a, rest = __rest(_a, ["subChannelId", "mentionees"]);
21607
+ return Object.assign({ messageFeedId: subChannelId, mentionedUsers: mentionees }, rest);
21608
+ }
21609
+ function convertQueryParams$1(_a) {
21610
+ var { page, sortBy, subChannelId, tags } = _a, rest = __rest(_a, ["page", "sortBy", "subChannelId", "tags"]);
21611
+ const out = Object.assign(Object.assign({}, rest), { messageFeedId: subChannelId, options: { token: toToken(page || { limit: 10 }, 'afterbeforeraw') } });
21612
+ if (sortBy !== undefined) {
21613
+ out.options.sortBy = sortBy;
21614
+ }
21615
+ if (tags) {
21616
+ out.includeTags = tags;
21617
+ }
21618
+ return out;
21619
+ }
21620
+
21523
21621
  /**
21524
21622
  * ```js
21525
21623
  * import { getMessage } from '@amityco/ts-sdk'
@@ -21544,7 +21642,9 @@ const getMessage = async (messageId, isLive = false) => {
21544
21642
  let data;
21545
21643
  try {
21546
21644
  // API-FIX: endpoint should not be /list, parameters should be querystring.
21547
- const response = await client.http.get(`/api/v3/messages/${encodeURIComponent(messageId)}`);
21645
+ const response = await client.http
21646
+ .get(`/api/v5/messages/${encodeURIComponent(messageId)}`)
21647
+ .then(convertResponseFromRaw);
21548
21648
  data = response.data;
21549
21649
  }
21550
21650
  catch (error) {
@@ -21557,7 +21657,7 @@ const getMessage = async (messageId, isLive = false) => {
21557
21657
  if (client.cache)
21558
21658
  ingestInCache(data, { cachedAt });
21559
21659
  const { messages } = data;
21560
- fireEvent('v3.message.didFetch', { messages });
21660
+ fireEvent('local.message.fetched', { messages });
21561
21661
  return {
21562
21662
  data: messages.find(message => message.messageId === messageId),
21563
21663
  cachedAt,
@@ -21607,15 +21707,16 @@ getMessage.locally = (messageId) => {
21607
21707
  const getMessages = async (messageIds) => {
21608
21708
  const client = getActiveClient();
21609
21709
  client.log('message/getMessages', messageIds);
21610
- // API-FIX: endpoint should not be /list, parameters should be querystring.
21611
- const { data } = await client.http.get(`/api/v3/messages/list`, {
21612
- params: { messageIds },
21613
- });
21710
+ const { data } = await client.http
21711
+ .get(`/api/v5/messages/list`, {
21712
+ params: { messageIds: messageIds.map(encodeURIComponent) },
21713
+ })
21714
+ .then(convertResponseFromRaw);
21614
21715
  const cachedAt = client.cache && Date.now();
21615
21716
  if (client.cache)
21616
21717
  ingestInCache(data, { cachedAt });
21617
21718
  const { messages } = data;
21618
- fireEvent('v3.message.didFetch', { messages });
21719
+ fireEvent('local.message.fetched', { messages });
21619
21720
  return {
21620
21721
  data: messages,
21621
21722
  cachedAt,
@@ -21670,31 +21771,25 @@ getMessages.locally = (messageIds) => {
21670
21771
  const queryMessages = async (query) => {
21671
21772
  const client = getActiveClient();
21672
21773
  client.log('message/queryMessages', query);
21673
- const { page = { limit: 10 } } = query, params = __rest(query, ["page"]);
21774
+ const params = convertQueryParams$1(query);
21674
21775
  // API-FIX: parameters should be querystring. (1)
21675
21776
  // API-FIX: backend should answer Amity.Response (2)
21676
21777
  // API-FIX: pagination should not be indexed on channelSegment (3)
21677
21778
  // const { data } = await client.http.get<Amity.Response<Amity.Paged<Amity.MessagePayload>>>(
21678
- const { data } = await client.http.get(`/api/v3/messages`, {
21679
- params: Object.assign(Object.assign({}, params), { options: {
21680
- token: toToken(page, 'afterbefore'),
21681
- } }),
21682
- });
21779
+ const response = await client.http
21780
+ .get(`/api/v5/messages`, { params })
21781
+ .then(convertResponseFromRaw);
21683
21782
  // API-FIX: backend should answer Amity.Response (2)
21684
21783
  // const { paging, messages } = unwrapPayload(data)
21685
- const { paging } = data, payload = __rest(data, ["paging"]);
21686
- const { messages } = payload;
21784
+ const _a = response.data, { paging } = _a, data = __rest(_a, ["paging"]);
21785
+ const { messages } = data;
21687
21786
  const cachedAt = client.cache && Date.now();
21688
21787
  if (client.cache) {
21689
- ingestInCache(payload, { cachedAt });
21690
- const cacheKey = [
21691
- 'message',
21692
- 'query',
21693
- Object.assign(Object.assign({}, params), { options: Object.assign({}, page) }),
21694
- ];
21788
+ ingestInCache(data, { cachedAt });
21789
+ const cacheKey = ['message', 'query', params];
21695
21790
  pushToCache(cacheKey, { messages: messages.map(getResolver('message')), paging });
21696
21791
  }
21697
- fireEvent('v3.message.didFetch', { messages });
21792
+ fireEvent('local.message.fetched', { messages });
21698
21793
  const nextPage = toPage(paging.next);
21699
21794
  const prevPage = toPage(paging.previous);
21700
21795
  return { data: messages, cachedAt, prevPage, nextPage };
@@ -21718,8 +21813,8 @@ queryMessages.locally = (query) => {
21718
21813
  client.log('message/queryMessages.locally', query);
21719
21814
  if (!client.cache)
21720
21815
  return;
21721
- const { page = { limit: 10 } } = query, params = __rest(query, ["page"]);
21722
- const queryKey = ['message', 'query', Object.assign(Object.assign({}, params), { options: Object.assign({}, page) })];
21816
+ const params = convertQueryParams$1(query);
21817
+ const queryKey = ['message', 'query', params];
21723
21818
  const { data, cachedAt } = (_a = pullFromCache(queryKey)) !== null && _a !== void 0 ? _a : {};
21724
21819
  if (!(data === null || data === void 0 ? void 0 : data.messages.length))
21725
21820
  return;
@@ -21736,13 +21831,20 @@ queryMessages.locally = (query) => {
21736
21831
 
21737
21832
  const uuid = () => nativeIdGenerator__default["default"].v4().toString();
21738
21833
 
21834
+ // FIXME: temp solution
21835
+ let uniqueId;
21739
21836
  /**
21740
21837
  * ```js
21741
- * import { createMessage } from '@amityco/ts-sdk'
21742
- * const created = await createMessage({
21743
- * channelId: 'foobar',
21744
- * data: { text: 'hello world' }
21745
- * })
21838
+ * import { createMessage, createQuery, runQuery } from '@amityco/ts-sdk'
21839
+ *
21840
+ * const query = createQuery(createMessage, {
21841
+ * subChannelId: 'foobar',
21842
+ * data: { text: 'hello world' },
21843
+ * });
21844
+ *
21845
+ * runQuery(query, ({ data: message, loading }) => {
21846
+ * console.log(message);
21847
+ * });
21746
21848
  * ```
21747
21849
  *
21748
21850
  * Creates an {@link Amity.Message}
@@ -21755,13 +21857,19 @@ const uuid = () => nativeIdGenerator__default["default"].v4().toString();
21755
21857
  */
21756
21858
  const createMessage = async (bundle) => {
21757
21859
  const client = getActiveClient();
21758
- client.log('user/createMessage', bundle);
21759
- const { data } = await client.http.post('/api/v3/messages', bundle);
21860
+ client.log('message/createMessage', bundle);
21861
+ const referenceId = uniqueId;
21862
+ uniqueId = undefined;
21863
+ const { data } = await client.http
21864
+ .post('/api/v5/messages', Object.assign(Object.assign({}, convertParams(bundle)), { referenceId }))
21865
+ .then(convertResponseFromRaw);
21760
21866
  const cachedAt = client.cache && Date.now();
21761
- if (client.cache)
21867
+ if (client.cache) {
21868
+ dropFromCache(['message', 'get', referenceId]);
21762
21869
  ingestInCache(data, { cachedAt });
21870
+ }
21763
21871
  const { messages } = data;
21764
- fireEvent('v3.message.didCreate', { messages });
21872
+ fireEvent('local.message.created', { messages });
21765
21873
  return {
21766
21874
  data: messages[0],
21767
21875
  cachedAt,
@@ -21770,7 +21878,8 @@ const createMessage = async (bundle) => {
21770
21878
  /**
21771
21879
  * ```js
21772
21880
  * import { createMessage } from '@amityco/ts-sdk'
21773
- * const created = createMessage.locally({
21881
+ *
21882
+ * const created = createMessage.optimistically({
21774
21883
  * channelId: 'foobar',
21775
21884
  * data: { text: 'hello world' }
21776
21885
  * })
@@ -21795,17 +21904,26 @@ createMessage.optimistically = (bundle) => {
21795
21904
  * Updated to handle client requirement to add messageId while uploading
21796
21905
  * message with image. Temporary!
21797
21906
  */
21798
- const bundleWithMessageId = Object.assign({ messageId: uuid() }, bundle);
21799
- // only log if cache is enabled
21800
- client.log('user/createMessage.locally', bundleWithMessageId);
21801
- const channel = pullFromCache(['channel', 'get', bundleWithMessageId.channelId]);
21802
- upsertInCache(['channel', 'get', bundleWithMessageId.channelId], Object.assign(Object.assign({}, channel === null || channel === void 0 ? void 0 : channel.data), { messageCount: ((_a = channel === null || channel === void 0 ? void 0 : channel.data.messageCount) !== null && _a !== void 0 ? _a : 0) + 1 }));
21907
+ const localId = `LOCAL_${uuid()}`;
21908
+ uniqueId = localId;
21909
+ const bundleWithMessageId = Object.assign({ messageId: localId, uniqueId: localId }, bundle);
21910
+ client.log('message/createMessage.optimistically', bundleWithMessageId);
21911
+ const subChannel = pullFromCache(['subChannel', 'get', bundle.subChannelId]);
21912
+ if (subChannel) {
21913
+ upsertInCache(['subChannel', 'get', bundle.subChannelId], Object.assign(Object.assign({}, subChannel.data), { messageCount: subChannel.data.messageCount + 1 }));
21914
+ if (subChannel.data.channelId === subChannel.data.subChannelId) {
21915
+ const channel = pullFromCache(['channel', 'get', subChannel.data.channelId]);
21916
+ if (channel === null || channel === void 0 ? void 0 : channel.data) {
21917
+ upsertInCache(['channel', 'get', subChannel.data.channelId], Object.assign(Object.assign({}, channel.data), { messageCount: ((_a = channel.data.messageCount) !== null && _a !== void 0 ? _a : 0) + 1 }));
21918
+ }
21919
+ }
21920
+ }
21803
21921
  // as reused to update created and updated time, which should be the same
21804
21922
  const createdTime = new Date().toISOString();
21805
- const message = Object.assign({ userId: client.userId, channelSegment: ((_b = channel === null || channel === void 0 ? void 0 : channel.data.messageCount) !== null && _b !== void 0 ? _b : 0) + 1, createdAt: createdTime, updatedAt: createdTime }, bundleWithMessageId);
21923
+ const message = Object.assign({ creatorId: client.userId, channelSegment: ((_b = subChannel === null || subChannel === void 0 ? void 0 : subChannel.data.messageCount) !== null && _b !== void 0 ? _b : 0) + 1, childrenNumber: 0, createdAt: createdTime, updatedAt: createdTime }, bundleWithMessageId);
21806
21924
  const cachedAt = UNSYNCED_OBJECT_CACHED_AT_VALUE;
21807
21925
  pushToCache(['message', 'get', message.messageId], message, { cachedAt });
21808
- fireEvent('v3.message.didCreate', { messages: [message] });
21926
+ fireEvent('local.message.created', { messages: [message] });
21809
21927
  return {
21810
21928
  cachedAt,
21811
21929
  data: message,
@@ -21831,13 +21949,15 @@ createMessage.optimistically = (bundle) => {
21831
21949
  */
21832
21950
  const updateMessage = async (messageId, patch) => {
21833
21951
  const client = getActiveClient();
21834
- client.log('user/updateMessage', patch);
21835
- const { data } = await client.http.put(`/api/v3/messages/${encodeURIComponent(messageId)}`, patch);
21952
+ client.log('message/updateMessage', patch);
21953
+ const { data } = await client.http
21954
+ .put(`/api/v5/messages/${encodeURIComponent(messageId)}`, convertParams(patch))
21955
+ .then(convertResponseFromRaw);
21836
21956
  const cachedAt = client.cache && Date.now();
21837
21957
  if (client.cache)
21838
21958
  ingestInCache(data, { cachedAt });
21839
21959
  const { messages } = data;
21840
- fireEvent('v3.message.didUpdate', { messages });
21960
+ fireEvent('local.message.updated', { messages });
21841
21961
  return {
21842
21962
  data: messages.find(message => message.messageId === messageId),
21843
21963
  cachedAt,
@@ -21846,7 +21966,7 @@ const updateMessage = async (messageId, patch) => {
21846
21966
  /**
21847
21967
  * ```js
21848
21968
  * import { updateMessage } from '@amityco/ts-sdk'
21849
- * const updated = updateMessage.locally('foobar', {
21969
+ * const updated = updateMessage.optimistically('foobar', {
21850
21970
  * data: { text: 'hello world' }
21851
21971
  * })
21852
21972
  * ```
@@ -21861,7 +21981,7 @@ const updateMessage = async (messageId, patch) => {
21861
21981
  */
21862
21982
  updateMessage.optimistically = (messageId, patch) => {
21863
21983
  const client = getActiveClient();
21864
- client.log('user/updateMessage', patch);
21984
+ client.log('message/updateMessage.optimistically', patch);
21865
21985
  if (!client.cache)
21866
21986
  return;
21867
21987
  const message = pullFromCache(['message', 'get', messageId]);
@@ -21870,7 +21990,7 @@ updateMessage.optimistically = (messageId, patch) => {
21870
21990
  const cachedAt = -1;
21871
21991
  const updated = Object.assign(Object.assign(Object.assign({}, message.data), patch), { updatedAt: new Date().toISOString() });
21872
21992
  upsertInCache(['message', 'get', messageId], updated, { cachedAt });
21873
- fireEvent('v3.message.didUpdate', { messages: [updated] });
21993
+ fireEvent('local.message.updated', { messages: [updated] });
21874
21994
  return {
21875
21995
  data: updated,
21876
21996
  cachedAt,
@@ -21885,7 +22005,7 @@ updateMessage.optimistically = (messageId, patch) => {
21885
22005
  *
21886
22006
  * Delete a {@link Amity.Message}
21887
22007
  *
21888
- * @param The ID of the {@link Amity.Message} to delete
22008
+ * @param messageId the ID of the {@link Amity.Message} to delete
21889
22009
  * @return A success boolean if the {@link Amity.Message} was deleted
21890
22010
  *
21891
22011
  * @category Message API
@@ -21895,15 +22015,15 @@ const deleteMessage = async (messageId) => {
21895
22015
  const client = getActiveClient();
21896
22016
  client.log('message/deleteMessage', messageId);
21897
22017
  // API-FIX: This endpoint has not been implemented yet.
21898
- await client.http.delete(`/api/v3/messages/${encodeURIComponent(messageId)}`);
22018
+ await client.http.delete(`/api/v5/messages/${encodeURIComponent(messageId)}`);
21899
22019
  const deleted = await getMessage(messageId);
21900
- fireEvent('v3.message.didDelete', { messages: [deleted.data] });
22020
+ fireEvent('local.message.deleted', { messages: [deleted.data] });
21901
22021
  return deleted.data;
21902
22022
  };
21903
22023
  /**
21904
22024
  * ```js
21905
22025
  * import { deleteMessage } from '@amityco/ts-sdk'
21906
- * const success = deleteMessage.locally('foobar')
22026
+ * const success = deleteMessage.optimistically('foobar')
21907
22027
  * ```
21908
22028
  *
21909
22029
  * Deletes a {@link Amity.Message}
@@ -21915,14 +22035,14 @@ const deleteMessage = async (messageId) => {
21915
22035
  */
21916
22036
  deleteMessage.optimistically = (messageId) => {
21917
22037
  const client = getActiveClient();
21918
- client.log('message/deleteMessage', messageId);
22038
+ client.log('message/deleteMessage.optimistically', messageId);
21919
22039
  const message = pullFromCache(['message', 'get', messageId]);
21920
22040
  if (!message)
21921
22041
  return;
21922
22042
  const cachedAt = -1;
21923
22043
  const deleted = Object.assign(Object.assign({}, message.data), { isDeleted: true, updatedAt: new Date().toISOString() });
21924
22044
  upsertInCache(['message', 'get', messageId], deleted, { cachedAt });
21925
- fireEvent('v3.message.didDelete', { messages: [deleted] });
22045
+ fireEvent('local.message.deleted', { messages: [deleted] });
21926
22046
  return {
21927
22047
  data: deleted,
21928
22048
  cachedAt,
@@ -21947,11 +22067,20 @@ const queryPosts = async (query) => {
21947
22067
  const client = getActiveClient();
21948
22068
  client.log('post/queryPosts', query);
21949
22069
  const { page = { limit: 10 } } = query, params = __rest(query, ["page"]);
22070
+ const { dataTypes, matchingOnlyParentPost } = params;
21950
22071
  // API-FIX: parameters should be querystring. (1)
21951
22072
  // API-FIX: backend should answer Amity.Response (2)
21952
22073
  // const { data } = await client.http.get<Amity.Response<Amity.PagedResponse<Amity.PostPayload>>>(
21953
22074
  const { data } = await client.http.get(`/api/v4/posts`, {
21954
- params: Object.assign(Object.assign({}, params), { options: {
22075
+ params: Object.assign(Object.assign({}, params), {
22076
+ /*
22077
+ * when creating post like image, file, video BE will create 2 posts
22078
+ * 1. parent post to store text with dataType=text
22079
+ * 2. child post to store dataTypes post data
22080
+ *
22081
+ * By default BE queries only parent post
22082
+ */
22083
+ matchingOnlyParentPost: matchingOnlyParentPost !== null && matchingOnlyParentPost !== void 0 ? matchingOnlyParentPost : !(dataTypes === null || dataTypes === void 0 ? void 0 : dataTypes.length), options: {
21955
22084
  token: toToken(page, 'afterbeforeraw'),
21956
22085
  } }),
21957
22086
  });
@@ -22249,12 +22378,13 @@ const queryCommunities = async (query) => {
22249
22378
  const client = getActiveClient();
22250
22379
  client.log('channel/queryCommunities', query);
22251
22380
  // safe decapsulation
22252
- const _a = query !== null && query !== void 0 ? query : {}, { page, displayName, membership } = _a, params = __rest(_a, ["page", "displayName", "membership"]);
22381
+ const _a = query !== null && query !== void 0 ? query : {}, { page } = _a, params = __rest(_a, ["page"]);
22382
+ const _b = params !== null && params !== void 0 ? params : {}, { displayName, membership } = _b, restParams = __rest(_b, ["displayName", "membership"]);
22253
22383
  // API-FIX: parameters should be querystring.
22254
22384
  // API-FIX: backend doesnt answer Amity.Response
22255
22385
  // const { data } = await client.http.get<Amity.Response<Amity.PagedResponse<CommunityPayload>>>(
22256
22386
  const { data } = await client.http.get(`/api/v3/communities`, {
22257
- params: Object.assign(Object.assign({}, params), { keyword: displayName, filter: membership, options: {
22387
+ params: Object.assign(Object.assign({}, restParams), { keyword: displayName, filter: membership, options: {
22258
22388
  token: toToken(page, 'skiplimit'),
22259
22389
  } }),
22260
22390
  });
@@ -22549,6 +22679,58 @@ const leaveCommunity = async (communityId) => {
22549
22679
  return !!communityUsers.find(communityUser => communityUser.communityId === communityId && communityUser.communityMembership !== 'member');
22550
22680
  };
22551
22681
 
22682
+ /**
22683
+ * Attach user object to membership model
22684
+ * - If cache is not enabled, set user to undefined ({..., user: undefined})
22685
+ * - If user object is not found in cache, set user to undefined
22686
+ * ({..., user: undefined})
22687
+ * - If a user is found in the cache, it attaches the user from the cache
22688
+ * ({..., user: { userId, displayName,... }})
22689
+ *
22690
+ * @param member The membership model object
22691
+ * @param userIdProp The user ID prop name of membership object
22692
+ * @param userProp The user prop name of destination object
22693
+ * @returns The membership model object that is already mapped to user
22694
+ * @hidden
22695
+ */
22696
+ const withUser = (member, userIdProp = 'userId', userProp = 'user') => (Object.assign({ get [userProp]() {
22697
+ var _a;
22698
+ const client = getActiveClient();
22699
+ if (!client.cache)
22700
+ return undefined;
22701
+ const userCache = (_a = pullFromCache(['user', 'get', member[userIdProp]])) === null || _a === void 0 ? void 0 : _a.data;
22702
+ if (!userCache) {
22703
+ return undefined;
22704
+ }
22705
+ return userCache;
22706
+ } }, member));
22707
+ /**
22708
+ * Mapping membership model with user object
22709
+ *
22710
+ * @param members The membership model objects
22711
+ * @param userIdProp The user ID prop name of membership object
22712
+ * @param userProp The user prop name of destination object
22713
+ * @returns The membership model objects that is already
22714
+ * mapped to users
22715
+ * @hidden
22716
+ */
22717
+ const withUsers = (members, userIdProp = 'userId', userProp = 'user') => members.map(member => withUser(member, userIdProp, userProp));
22718
+ /**
22719
+ * Transform members prop in any payload with attached users members
22720
+ *
22721
+ * @param payload The payload contain members prop
22722
+ * @param memberProp A name of members prop
22723
+ * @param userIdProp The user ID prop name of membership object
22724
+ * @param userProp The user prop name of destination object
22725
+ * @returns The transforming payload
22726
+ * @hidden
22727
+ */
22728
+ const prepareMembershipPayload = (payload, memberProp, userIdProp = 'userId', userProp = 'user') => {
22729
+ const _a = payload, _b = memberProp, memberPayload = _a[_b], rest = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
22730
+ const members = withUsers(memberPayload, userIdProp, userProp);
22731
+ return Object.assign(Object.assign({}, rest), { [memberProp]: members });
22732
+ };
22733
+
22552
22734
  /**
22553
22735
  * ```js
22554
22736
  * import { queryCommunityMembers } from '@amityco/ts-sdk'
@@ -22566,17 +22748,27 @@ const leaveCommunity = async (communityId) => {
22566
22748
  const queryCommunityMembers = async (query) => {
22567
22749
  const client = getActiveClient();
22568
22750
  client.log('community/queryCommunityMembers', query);
22569
- const _a = query !== null && query !== void 0 ? query : {}, { page, communityId } = _a, params = __rest(_a, ["page", "communityId"]);
22570
- const { data } = await client.http.get(`/api/v3/communities/${communityId}/users`, {
22751
+ const _a = query !== null && query !== void 0 ? query : {}, { page } = _a, params = __rest(_a, ["page"]);
22752
+ const { data: queryPayload } = await client.http.get(`/api/v3/communities/${params.communityId}/users`, {
22571
22753
  params: Object.assign(Object.assign({}, params), { options: {
22572
22754
  token: toToken(page, 'skiplimit'),
22573
22755
  } }),
22574
22756
  });
22575
- const { paging } = data, payload = __rest(data, ["paging"]);
22576
- const { communityUsers } = payload;
22757
+ const { paging } = queryPayload, payload = __rest(queryPayload, ["paging"]);
22758
+ const preparedPayload = prepareMembershipPayload(payload, 'communityUsers');
22759
+ const { communityUsers } = preparedPayload;
22577
22760
  const cachedAt = client.cache && Date.now();
22578
22761
  if (client.cache) {
22579
- ingestInCache(payload, { cachedAt });
22762
+ ingestInCache(preparedPayload, { cachedAt });
22763
+ const cacheKey = [
22764
+ 'communityUsers',
22765
+ 'query',
22766
+ Object.assign(Object.assign({}, params), { options: Object.assign({}, page) }),
22767
+ ];
22768
+ pushToCache(cacheKey, {
22769
+ communityUsers: communityUsers.map(({ communityId, userId }) => getResolver('communityUsers')({ communityId, userId })),
22770
+ paging,
22771
+ });
22580
22772
  }
22581
22773
  const nextPage = toPage(paging.next);
22582
22774
  const prevPage = toPage(paging.previous);
@@ -22596,9 +22788,29 @@ const queryCommunityMembers = async (query) => {
22596
22788
  * @category Post API
22597
22789
  */
22598
22790
  queryCommunityMembers.locally = (query) => {
22791
+ var _a, _b;
22599
22792
  const client = getActiveClient();
22600
22793
  client.log('community/queryCommunityMembers', query);
22601
- // TODO
22794
+ if (!client.cache)
22795
+ return;
22796
+ const _c = query !== null && query !== void 0 ? query : {}, { page } = _c, params = __rest(_c, ["page"]);
22797
+ const cacheKey = [
22798
+ 'communityUsers',
22799
+ 'query',
22800
+ Object.assign(Object.assign({}, params), { options: Object.assign({}, page) }),
22801
+ ];
22802
+ const { data, cachedAt } = (_a = pullFromCache(cacheKey)) !== null && _a !== void 0 ? _a : {};
22803
+ if (!(data === null || data === void 0 ? void 0 : data.communityUsers.length))
22804
+ return;
22805
+ const communityUsers = data.communityUsers
22806
+ .map(key => pullFromCache(['communityUsers', 'get', key]))
22807
+ .filter(Boolean)
22808
+ .map(({ data }) => data);
22809
+ const prevPage = toPage(data === null || data === void 0 ? void 0 : data.paging.previous);
22810
+ const nextPage = toPage(data === null || data === void 0 ? void 0 : data.paging.next);
22811
+ return communityUsers.length === ((_b = data === null || data === void 0 ? void 0 : data.communityUsers) === null || _b === void 0 ? void 0 : _b.length)
22812
+ ? { data: communityUsers, cachedAt, prevPage, nextPage }
22813
+ : undefined;
22602
22814
  };
22603
22815
 
22604
22816
  /**
@@ -23307,38 +23519,6 @@ const preparePayloadForCache = (event, payload) => {
23307
23519
  }
23308
23520
  };
23309
23521
 
23310
- /** @hidden */
23311
- /*
23312
- * @param message payload from http request without myReactions
23313
- * add myReactions to http response if the event was a reaction event
23314
- */
23315
- const prepareMessagePayloadForCache = (payload) => {
23316
- const client = getActiveClient();
23317
- const cached = pullFromCache(['message', 'get', payload.messageId]);
23318
- // '[]' in cases where the new reaction is the first one
23319
- const myReactions = (cached === null || cached === void 0 ? void 0 : cached.data.myReactions) || [];
23320
- // add myReactions to the payload
23321
- Object.assign(payload, { myReactions });
23322
- // check if there are any updates to the reactions
23323
- const latestReaction = payload === null || payload === void 0 ? void 0 : payload.latestReaction;
23324
- const isLatestReactionMine = latestReaction && latestReaction.userId === client.userId;
23325
- if (!isLatestReactionMine) {
23326
- return;
23327
- }
23328
- // new reaction added
23329
- if (latestReaction.eventName === 'add' && !myReactions.includes(latestReaction.reactionName)) {
23330
- Object.assign(payload, {
23331
- myReactions: [...myReactions, latestReaction.reactionName],
23332
- });
23333
- }
23334
- // existing reaction removed
23335
- if (latestReaction.eventName === 'remove' && myReactions.includes(latestReaction.reactionName)) {
23336
- Object.assign(payload, {
23337
- myReactions: myReactions.filter(x => x !== latestReaction.reactionName),
23338
- });
23339
- }
23340
- };
23341
-
23342
23522
  /**
23343
23523
  * ```js
23344
23524
  * import { addReaction } from '@amityco/ts-sdk'
@@ -23366,7 +23546,17 @@ const addReaction = async (referenceType, referenceId, reactionName) => {
23366
23546
  referenceId,
23367
23547
  referenceType,
23368
23548
  reactionName,
23549
+ referenceVersion: referenceType === 'message' ? 5 : undefined,
23369
23550
  });
23551
+ if (client.cache) {
23552
+ const model = pullFromCache([
23553
+ referenceType,
23554
+ 'get',
23555
+ referenceId,
23556
+ ]);
23557
+ (model === null || model === void 0 ? void 0 : model.data) &&
23558
+ pushToCache([referenceType, 'get', referenceId], model.data, { cachedAt: Date.now() });
23559
+ }
23370
23560
  return true;
23371
23561
  };
23372
23562
  /**
@@ -23402,7 +23592,9 @@ addReaction.optimistically = (referenceType, referenceId, reactionName) => {
23402
23592
  if (!(model === null || model === void 0 ? void 0 : model.data) || ((_a = model.data.myReactions) === null || _a === void 0 ? void 0 : _a.includes(reactionName)))
23403
23593
  return;
23404
23594
  const reaction = Object.assign(Object.assign({}, model.data), { reactionsCount: model.data.reactionsCount + 1, myReactions: [...((_b = model.data.myReactions) !== null && _b !== void 0 ? _b : []), reactionName], reactions: Object.assign(Object.assign({}, model.data.reactions), { [reactionName]: ((_c = model.data.reactions[reactionName]) !== null && _c !== void 0 ? _c : 0) + 1 }) });
23405
- upsertInCache([referenceType, 'get', referenceId], reaction, { cachedAt: -1 });
23595
+ upsertInCache([referenceType, 'get', referenceId], reaction, {
23596
+ cachedAt: UNSYNCED_OBJECT_CACHED_AT_VALUE,
23597
+ });
23406
23598
  dispatchReactable(referenceType, reaction);
23407
23599
  return (_e = (_d = reaction === null || reaction === void 0 ? void 0 : reaction.myReactions) === null || _d === void 0 ? void 0 : _d.includes(reactionName)) !== null && _e !== void 0 ? _e : false;
23408
23600
  };
@@ -23431,8 +23623,22 @@ const removeReaction = async (referenceType, referenceId, reactionName) => {
23431
23623
  reactionName,
23432
23624
  });
23433
23625
  await client.http.delete(`/api/v2/reactions`, {
23434
- data: { referenceId, referenceType, reactionName },
23626
+ data: {
23627
+ referenceId,
23628
+ referenceType,
23629
+ reactionName,
23630
+ referenceVersion: referenceType === 'message' ? 5 : undefined,
23631
+ },
23435
23632
  });
23633
+ if (client.cache) {
23634
+ const model = pullFromCache([
23635
+ referenceType,
23636
+ 'get',
23637
+ referenceId,
23638
+ ]);
23639
+ (model === null || model === void 0 ? void 0 : model.data) &&
23640
+ pushToCache([referenceType, 'get', referenceId], model.data, { cachedAt: Date.now() });
23641
+ }
23436
23642
  return true;
23437
23643
  };
23438
23644
  /**
@@ -23468,7 +23674,9 @@ removeReaction.optimistically = (referenceType, referenceId, reactionName) => {
23468
23674
  if (!(model === null || model === void 0 ? void 0 : model.data) || !((_a = model.data.myReactions) === null || _a === void 0 ? void 0 : _a.includes(reactionName)))
23469
23675
  return;
23470
23676
  const reaction = Object.assign(Object.assign({}, model.data), { reactionsCount: Math.max(0, model.data.reactionsCount - 1), myReactions: ((_b = model.data.myReactions) !== null && _b !== void 0 ? _b : []).filter(item => item !== reactionName), reactions: Object.assign(Object.assign({}, model.data.reactions), { [reactionName]: Math.max(0, ((_c = model.data.reactions[reactionName]) !== null && _c !== void 0 ? _c : 0) - 1) }) });
23471
- upsertInCache([referenceType, 'get', referenceId], reaction, { cachedAt: -1 });
23677
+ upsertInCache([referenceType, 'get', referenceId], reaction, {
23678
+ cachedAt: UNSYNCED_OBJECT_CACHED_AT_VALUE,
23679
+ });
23472
23680
  dispatchReactable(referenceType, reaction);
23473
23681
  return (_e = !((_d = reaction === null || reaction === void 0 ? void 0 : reaction.myReactions) === null || _d === void 0 ? void 0 : _d.includes(reactionName))) !== null && _e !== void 0 ? _e : false;
23474
23682
  };
@@ -23933,8 +24141,9 @@ const onReactionAdded = (referenceType, referenceId, callback) => {
23933
24141
  */
23934
24142
  if (referenceType === 'message') {
23935
24143
  const client = getActiveClient();
23936
- const filter = (payload) => {
24144
+ const filter = (rawPayload) => {
23937
24145
  var _a;
24146
+ const payload = prepareMessagePayload(rawPayload);
23938
24147
  const cached = pullFromCache([
23939
24148
  'message',
23940
24149
  'get',
@@ -23946,7 +24155,7 @@ const onReactionAdded = (referenceType, referenceId, callback) => {
23946
24155
  callbackWrapper(payload.messages[0]);
23947
24156
  }
23948
24157
  };
23949
- return createEventSubscriber(client, 'reaction/onReactionAdded', 'v3.message.didUpdate', filter);
24158
+ return createEventSubscriber(client, 'reaction/onReactionAdded', 'message.updated', filter);
23950
24159
  }
23951
24160
  if (referenceType === 'post') {
23952
24161
  return onPostReactionAdded(callbackWrapper);
@@ -23979,8 +24188,9 @@ const onReactionRemoved = (referenceType, referenceId, callback) => {
23979
24188
  };
23980
24189
  if (referenceType === 'message') {
23981
24190
  const client = getActiveClient();
23982
- const filter = (payload) => {
24191
+ const filter = (rawPayload) => {
23983
24192
  var _a;
24193
+ const payload = prepareMessagePayload(rawPayload);
23984
24194
  const cached = pullFromCache([
23985
24195
  'message',
23986
24196
  'get',
@@ -23992,7 +24202,7 @@ const onReactionRemoved = (referenceType, referenceId, callback) => {
23992
24202
  callbackWrapper(payload.messages[0]);
23993
24203
  }
23994
24204
  };
23995
- return createEventSubscriber(client, 'reaction/onReactionRemoved', 'v3.message.didUpdate', filter);
24205
+ return createEventSubscriber(client, 'reaction/onReactionRemoved', 'message.updated', filter);
23996
24206
  }
23997
24207
  if (referenceType === 'post') {
23998
24208
  return onPostReactionRemoved(callbackWrapper);
@@ -24025,7 +24235,8 @@ const onReactorAdded = (referenceType, referenceId, callback) => {
24025
24235
  }
24026
24236
  };
24027
24237
  if (referenceType === 'message') {
24028
- const filter = (payload) => {
24238
+ const filter = (rawPayload) => {
24239
+ const payload = prepareMessagePayload(rawPayload);
24029
24240
  if (!payload.messages[0].latestReaction)
24030
24241
  return;
24031
24242
  const _a = payload.messages[0].latestReaction, { eventName, referenceId, referenceType, userDisplayName } = _a, reactor = __rest(_a, ["eventName", "referenceId", "referenceType", "userDisplayName"]);
@@ -24035,7 +24246,7 @@ const onReactorAdded = (referenceType, referenceId, callback) => {
24035
24246
  ingestInCache({ reactions: [reactor] });
24036
24247
  callbackWrapper('message', payload.messages[0].messageId, reactor);
24037
24248
  };
24038
- return createEventSubscriber(client, 'reaction/onReactorAdded', 'v3.message.didUpdate', filter);
24249
+ return createEventSubscriber(client, 'reaction/onReactorAdded', 'message.updated', filter);
24039
24250
  }
24040
24251
  if (referenceType === 'post') {
24041
24252
  const filter = (payload) => {
@@ -24080,7 +24291,8 @@ const onReactorRemoved = (referenceType, referenceId, callback) => {
24080
24291
  }
24081
24292
  };
24082
24293
  if (referenceType === 'message') {
24083
- const filter = (payload) => {
24294
+ const filter = (rawPayload) => {
24295
+ const payload = prepareMessagePayload(rawPayload);
24084
24296
  if (!payload.messages[0].latestReaction)
24085
24297
  return;
24086
24298
  const _a = payload.messages[0].latestReaction, { eventName, referenceId, referenceType } = _a, reactor = __rest(_a, ["eventName", "referenceId", "referenceType"]);
@@ -24090,7 +24302,7 @@ const onReactorRemoved = (referenceType, referenceId, callback) => {
24090
24302
  ingestInCache({ reactions: [reactor] });
24091
24303
  callbackWrapper('message', payload.messages[0].messageId, reactor);
24092
24304
  };
24093
- return createEventSubscriber(client, 'reaction/onReactorRemoved', 'v3.message.didUpdate', filter);
24305
+ return createEventSubscriber(client, 'reaction/onReactorRemoved', 'message.updated', filter);
24094
24306
  }
24095
24307
  if (referenceType === 'post') {
24096
24308
  const filter = (payload) => {
@@ -24160,7 +24372,7 @@ const liveReactions = (params, callback, config) => {
24160
24372
  error: data.error,
24161
24373
  });
24162
24374
  };
24163
- const realtimeRouter = (reaction, action) => {
24375
+ const realtimeRouter = (action) => (reaction) => {
24164
24376
  var _a;
24165
24377
  const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
24166
24378
  if (!collection)
@@ -24197,7 +24409,7 @@ const liveReactions = (params, callback, config) => {
24197
24409
  responder(data);
24198
24410
  }, queryOptions(policy));
24199
24411
  };
24200
- disposers.push(onReactorAdded(queryParams.referenceType, queryParams.referenceId, reaction => realtimeRouter(reaction, 'onAdded')), onReactorRemoved(queryParams.referenceType, queryParams.referenceId, reaction => realtimeRouter(reaction, 'onRemoved')));
24412
+ disposers.push(onReactorAdded(queryParams.referenceType, queryParams.referenceId, realtimeRouter('onAdded')), onReactorRemoved(queryParams.referenceType, queryParams.referenceId, realtimeRouter('onRemoved')));
24201
24413
  onFetch();
24202
24414
  return () => {
24203
24415
  log(`liveReactions(tmpid: ${timestamp}) > dispose`);
@@ -24244,18 +24456,28 @@ var REFERENCE_TYPES = {
24244
24456
  const createReport = async (referenceType, referenceId) => {
24245
24457
  const client = getActiveClient();
24246
24458
  client.log('report/createReport', { referenceType, referenceId });
24247
- const { domainName } = REFERENCE_TYPES[referenceType];
24248
- const { data } = await client.http.post(`/api/${referenceType === 'user'
24249
- ? `v4/me/flags/${encodeURIComponent(referenceId)}`
24250
- : `v3/${domainName}/${encodeURIComponent(referenceId)}/flag`}`);
24459
+ const getAPIUrl = () => {
24460
+ if (referenceType === 'user') {
24461
+ return `/api/v4/me/flags/${encodeURIComponent(referenceId)}`;
24462
+ }
24463
+ if (referenceType === 'message') {
24464
+ return `/api/v5/messages/${encodeURIComponent(referenceId)}/flags`;
24465
+ }
24466
+ const { domainName } = REFERENCE_TYPES[referenceType];
24467
+ return `/api/v3/${domainName}/${encodeURIComponent(referenceId)}/flag`;
24468
+ };
24469
+ const { data } = await client.http.post(getAPIUrl());
24251
24470
  if (client.cache)
24252
- ingestInCache(data);
24253
- const event = referenceType === 'message'
24254
- ? 'v3.message.didUpdate'
24255
- : `${referenceType}.flagged`;
24256
- fireEvent(event, data);
24257
- return !!data;
24258
- };
24471
+ ingestInCache(referenceType === 'message' ? prepareMessagePayload(data) : data);
24472
+ if (referenceType === 'message') {
24473
+ fireEvent('message.flagged', data);
24474
+ }
24475
+ else {
24476
+ // @ts-ignore
24477
+ fireEvent(`${referenceType}.flagged`, data);
24478
+ }
24479
+ return !!data;
24480
+ };
24259
24481
 
24260
24482
  /**
24261
24483
  * ```js
@@ -24273,16 +24495,26 @@ const createReport = async (referenceType, referenceId) => {
24273
24495
  const deleteReport = async (referenceType, referenceId) => {
24274
24496
  const client = getActiveClient();
24275
24497
  client.log('report/deleteReport', { referenceType, referenceId });
24276
- const { domainName } = REFERENCE_TYPES[referenceType];
24277
- const { data } = await client.http.delete(`/api/${referenceType === 'user'
24278
- ? `v4/me/flags/${encodeURIComponent(referenceId)}`
24279
- : `v3/${domainName}/${encodeURIComponent(referenceId)}/unflag`}`);
24498
+ const getAPIUrl = () => {
24499
+ if (referenceType === 'user') {
24500
+ return `/api/v4/me/flags/${encodeURIComponent(referenceId)}`;
24501
+ }
24502
+ if (referenceType === 'message') {
24503
+ return `/api/v5/messages/${encodeURIComponent(referenceId)}/flags`;
24504
+ }
24505
+ const { domainName } = REFERENCE_TYPES[referenceType];
24506
+ return `/api/v3/${domainName}/${encodeURIComponent(referenceId)}/unflag`;
24507
+ };
24508
+ const { data } = await client.http.delete(getAPIUrl());
24280
24509
  if (client.cache)
24281
- ingestInCache(data);
24282
- const event = referenceType === 'message'
24283
- ? 'v3.message.didUpdate'
24284
- : `${referenceType}.unflagged`;
24285
- fireEvent(event, data);
24510
+ ingestInCache(referenceType === 'message' ? prepareMessagePayload(data) : data);
24511
+ if (referenceType === 'message') {
24512
+ fireEvent('message.unflagged', data);
24513
+ }
24514
+ else {
24515
+ // @ts-ignore
24516
+ fireEvent(`${referenceType}.unflagged`, data);
24517
+ }
24286
24518
  return !!data;
24287
24519
  };
24288
24520
 
@@ -24304,26 +24536,45 @@ const isReportedByMe = async (referenceType, referenceId) => {
24304
24536
  const client = getActiveClient();
24305
24537
  client.log('report/isReportedByMe', { referenceType, referenceId });
24306
24538
  const { eventName, primaryKey } = REFERENCE_TYPES[referenceType];
24539
+ if (referenceType === 'message') {
24540
+ const { data } = await client.http.get(`/api/v5/messages/${encodeURIComponent(referenceId)}/flags`);
24541
+ return data.result;
24542
+ }
24307
24543
  const { result, isFlagByMe } = (_a = (await synchronousWSCall(client, eventName, {
24308
24544
  [primaryKey]: referenceId,
24309
24545
  }))) !== null && _a !== void 0 ? _a : {};
24310
24546
  return (_b = result !== null && result !== void 0 ? result : isFlagByMe) !== null && _b !== void 0 ? _b : false;
24311
24547
  };
24312
24548
 
24313
- /** @hidden */
24549
+ function convertFromRaw$1(_a, params) {
24550
+ var { _id } = _a, rest = __rest(_a, ["_id"]);
24551
+ return Object.assign(Object.assign(Object.assign({}, rest), params), { defaultSubChannelId: _id });
24552
+ }
24553
+ function getSegmentParams(rawChannel) {
24554
+ let cached;
24555
+ try {
24556
+ cached = pullFromCache(['channel', 'get', rawChannel.channelId]);
24557
+ // eslint-disable-next-line no-empty
24558
+ }
24559
+ catch (_a) { }
24560
+ if (cached) {
24561
+ return {
24562
+ defaultSubChannelHasUnreadMention: cached.data.defaultSubChannelHasUnreadMention,
24563
+ defaultSubChannelUnreadCount: cached.data.defaultSubChannelUnreadCount,
24564
+ localReadToSegment: cached.data.localReadToSegment,
24565
+ localLastMentionSegment: cached.data.localLastMentionSegment,
24566
+ };
24567
+ }
24568
+ return {
24569
+ defaultSubChannelHasUnreadMention: false,
24570
+ defaultSubChannelUnreadCount: 0,
24571
+ // @ts-ignore
24572
+ localReadToSegment: rawChannel.messageCount > 0 ? rawChannel.messageCount - 1 : 0,
24573
+ localLastMentionSegment: 0,
24574
+ };
24575
+ }
24314
24576
  const prepareChannelPayload = (payload) => {
24315
- const client = getActiveClient();
24316
- const channels = payload.channels.map(channel => {
24317
- const channelUser = payload.channelUsers.find(channelUser => channelUser.userId === client.userId && channel.channelId === channelUser.channelId);
24318
- const hasMention = channelUser
24319
- ? channelUser.readToSegment < channelUser.lastMentionedSegment
24320
- : false;
24321
- const unreadCount = channelUser && channelUser.membership === 'member' && channel.messageCount
24322
- ? Math.max(0, channel.messageCount - channelUser.readToSegment)
24323
- : 0;
24324
- return Object.assign(Object.assign({}, channel), { hasMention,
24325
- unreadCount });
24326
- });
24577
+ const channels = payload.channels.map(channel => convertFromRaw$1(channel, getSegmentParams(channel)));
24327
24578
  return Object.assign(Object.assign({}, payload), { channels });
24328
24579
  };
24329
24580
 
@@ -24459,10 +24710,10 @@ getChannels.locally = (channelIds) => {
24459
24710
  const cached = channelIds
24460
24711
  .map(channelId => pullFromCache(['channel', 'get', channelId]))
24461
24712
  .filter(Boolean);
24462
- const channels = cached.map(({ data }) => data);
24463
- const oldest = (_a = cached.sort((a, b) => (a.cachedAt < b.cachedAt ? -1 : 1))) === null || _a === void 0 ? void 0 : _a[0];
24464
24713
  if ((cached === null || cached === void 0 ? void 0 : cached.length) < channelIds.length)
24465
24714
  return;
24715
+ const channels = cached.map(({ data }) => data);
24716
+ const oldest = (_a = cached.sort((a, b) => (a.cachedAt < b.cachedAt ? -1 : 1))) === null || _a === void 0 ? void 0 : _a[0];
24466
24717
  return {
24467
24718
  data: channels,
24468
24719
  cachedAt: oldest.cachedAt,
@@ -24537,7 +24788,7 @@ getChannel.locally = (channelId) => {
24537
24788
  /**
24538
24789
  * ```js
24539
24790
  * import { createChannel } from '@amityco/ts-sdk'
24540
- * const created = await createChannel({ channelId: 'foobar', displayName: 'foobar' })
24791
+ * const created = await createChannel({ displayName: 'foobar' })
24541
24792
  * ```
24542
24793
  *
24543
24794
  * Creates an {@link Amity.Channel}
@@ -24689,18 +24940,19 @@ const leaveChannel = async (channelId) => {
24689
24940
  const queryChannelMembers = async (query) => {
24690
24941
  const client = getActiveClient();
24691
24942
  client.log('channel/queryChannelMembers', query);
24692
- const _a = query !== null && query !== void 0 ? query : {}, { page = { limit: 10 } } = _a, params = __rest(_a, ["page"]);
24943
+ const _a = query !== null && query !== void 0 ? query : {}, { page } = _a, params = __rest(_a, ["page"]);
24693
24944
  const { data: queryPayload } = await client.http.get(`/api/v4/channels/${encodeURIComponent(params.channelId)}/users`, {
24694
24945
  params: Object.assign(Object.assign({}, params), { options: {
24695
24946
  token: toToken(page, 'skiplimit'),
24696
24947
  } }),
24697
24948
  });
24698
24949
  const { paging } = queryPayload, payload = __rest(queryPayload, ["paging"]);
24699
- const data = prepareChannelPayload(payload);
24700
- const { channelUsers } = data;
24950
+ const channelPayload = prepareChannelPayload(payload);
24951
+ const preparedPayload = prepareMembershipPayload(channelPayload, 'channelUsers');
24952
+ const { channelUsers } = preparedPayload;
24701
24953
  const cachedAt = client.cache && Date.now();
24702
24954
  if (client.cache) {
24703
- ingestInCache(data);
24955
+ ingestInCache(preparedPayload);
24704
24956
  const cacheKey = [
24705
24957
  'channelUsers',
24706
24958
  'query',
@@ -24713,7 +24965,12 @@ const queryChannelMembers = async (query) => {
24713
24965
  }
24714
24966
  const nextPage = toPage(paging.next);
24715
24967
  const prevPage = toPage(paging.previous);
24716
- return { data: channelUsers, cachedAt, nextPage, prevPage };
24968
+ return {
24969
+ data: channelUsers,
24970
+ cachedAt,
24971
+ nextPage,
24972
+ prevPage,
24973
+ };
24717
24974
  };
24718
24975
  /**
24719
24976
  * ```js
@@ -24734,7 +24991,7 @@ queryChannelMembers.locally = (query) => {
24734
24991
  client.log('channel/queryChannelMembers.locally', query);
24735
24992
  if (!client.cache)
24736
24993
  return;
24737
- const { page = { limit: 10 } } = query, params = __rest(query, ["page"]);
24994
+ const { page } = query, params = __rest(query, ["page"]);
24738
24995
  const cacheKey = [
24739
24996
  'channelUsers',
24740
24997
  'query',
@@ -24780,7 +25037,7 @@ const addChannelMembers = async (channelId, userIds) => {
24780
25037
  /*
24781
25038
  * should fire event for each user that was added
24782
25039
  */
24783
- userIds.forEach(id => fireEvent('v3.channel.didAddUsers', Object.assign(Object.assign({}, data), { channelUsers: data.channelUsers.filter(u => u.userId === id) })));
25040
+ userIds.forEach(id => fireEvent('channel.membersAdded', Object.assign(Object.assign({}, payload), { channelUsers: data.channelUsers.filter(u => u.userId === id) })));
24784
25041
  const { channelUsers } = data;
24785
25042
  return !!channelUsers.find(channelUser => channelUser.channelId === channelId && channelUser.membership === 'member');
24786
25043
  };
@@ -24807,7 +25064,10 @@ const removeChannelMembers = async (channelId, userIds) => {
24807
25064
  const data = prepareChannelPayload(payload);
24808
25065
  if (client.cache)
24809
25066
  ingestInCache(data);
24810
- fireEvent('v3.channel.didRemoveUsers', data);
25067
+ /*
25068
+ * should fire event for each user that was removed
25069
+ */
25070
+ userIds.forEach(id => fireEvent('channel.membersRemoved', Object.assign(Object.assign({}, payload), { channelUsers: data.channelUsers.filter(u => u.userId === id) })));
24811
25071
  const { channelUsers } = data;
24812
25072
  return !!channelUsers.find(channelUser => channelUser.channelId === channelId && channelUser.membership !== 'member');
24813
25073
  };
@@ -24886,11 +25146,12 @@ const banChannelMembers = async (channelId, userIds) => {
24886
25146
  const { data: payload } = await client.http.put(`/api/v3/channels/${channelId}/users/ban`, {
24887
25147
  userIds,
24888
25148
  });
24889
- const data = prepareChannelPayload(payload);
25149
+ const channelPayload = prepareChannelPayload(payload);
25150
+ const preparedPayload = prepareMembershipPayload(channelPayload, 'channelUsers');
25151
+ const { channelUsers } = preparedPayload;
24890
25152
  const cachedAt = client.cache && Date.now();
24891
25153
  if (client.cache)
24892
- ingestInCache(data, { cachedAt });
24893
- const { channelUsers } = data;
25154
+ ingestInCache(preparedPayload, { cachedAt });
24894
25155
  return {
24895
25156
  data: channelUsers === null || channelUsers === void 0 ? void 0 : channelUsers.filter(user => user.membership === 'banned'),
24896
25157
  cachedAt,
@@ -24917,17 +25178,92 @@ const unbanChannelMembers = async (channelId, userIds) => {
24917
25178
  const { data: payload } = await client.http.put(`/api/v3/channels/${encodeURIComponent(channelId)}/users/unban`, {
24918
25179
  userIds,
24919
25180
  });
24920
- const data = prepareChannelPayload(payload);
25181
+ const channelPayload = prepareChannelPayload(payload);
25182
+ const preparedPayload = prepareMembershipPayload(channelPayload, 'channelUsers');
24921
25183
  const cachedAt = client.cache && Date.now();
24922
25184
  if (client.cache)
24923
- ingestInCache(data, { cachedAt });
24924
- const { channelUsers } = data;
25185
+ ingestInCache(preparedPayload, { cachedAt });
25186
+ const { channelUsers } = preparedPayload;
24925
25187
  return {
24926
25188
  data: channelUsers === null || channelUsers === void 0 ? void 0 : channelUsers.filter(user => user.membership === 'member'),
24927
25189
  cachedAt,
24928
25190
  };
24929
25191
  };
24930
25192
 
25193
+ /**
25194
+ * ```js
25195
+ * import { startReading } from '@amityco/ts-sdk'
25196
+ * const success = await startReading('foo')
25197
+ * ```
25198
+ *
25199
+ * Mark all messages as read and start reading message inside channel
25200
+ *
25201
+ * @param {string} subChannelId - The channel ID to start reading.
25202
+ * @param {string} userId - The user ID of channel member.
25203
+ * @return {Promise<boolean>>} A success boolean if the channel reading of the sub channel had begun.
25204
+ *
25205
+ * @category Message API
25206
+ * @async
25207
+ */
25208
+ const startReading = async (subChannelId, userId = getActiveClient().userId) => {
25209
+ const client = getActiveClient();
25210
+ client.log('message/startReading', { subChannelId });
25211
+ const subChannel = pullFromCache(['subChannel', 'get', subChannelId]);
25212
+ if (!subChannel) {
25213
+ return;
25214
+ }
25215
+ const { channelId } = subChannel.data;
25216
+ const channel = pullFromCache(['channel', 'get', channelId]);
25217
+ if (!channel || channel.data.defaultSubChannelId !== subChannelId) {
25218
+ return;
25219
+ }
25220
+ const update = Object.assign(Object.assign({}, channel.data), {
25221
+ // @ts-ignore
25222
+ localReading: true, defaultSubChannelUnreadCount: 0, defaultSubChannelHasUnreadMention: false });
25223
+ pushToCache(['channel', 'get', channelId], update);
25224
+ client.emitter.emit('local.channel.updated', { channels: [update] });
25225
+ const result = await synchronousWSCall(client, 'channel.startReading', {
25226
+ channelId,
25227
+ });
25228
+ return !!result;
25229
+ };
25230
+
25231
+ /**
25232
+ * ```js
25233
+ * import { stopReading } from '@amityco/ts-sdk'
25234
+ * const success = await stopReading('foo')
25235
+ * ```
25236
+ *
25237
+ * Stop reading message inside channel
25238
+ *
25239
+ * @param {string} subChannelId - The channel ID to stop reading.
25240
+ * @return {Promise<boolean>>} A success boolean if the sub channel reading was halted.
25241
+ *
25242
+ * @category Message API
25243
+ * @async
25244
+ */
25245
+ const stopReading = async (subChannelId) => {
25246
+ const client = getActiveClient();
25247
+ client.log('message/stopReading', { subChannelId });
25248
+ const subChannel = pullFromCache(['subChannel', 'get', subChannelId]);
25249
+ if (!subChannel) {
25250
+ return;
25251
+ }
25252
+ const { channelId } = subChannel.data;
25253
+ const channel = pullFromCache(['channel', 'get', channelId]);
25254
+ if (!channel || channel.data.defaultSubChannelId !== subChannelId) {
25255
+ return;
25256
+ }
25257
+ const update = Object.assign(Object.assign({}, channel.data), {
25258
+ // @ts-ignore
25259
+ localReading: false });
25260
+ pushToCache(['channel', 'get', channelId], update);
25261
+ const result = await synchronousWSCall(client, 'channel.stopReading', {
25262
+ channelId,
25263
+ });
25264
+ return !!result;
25265
+ };
25266
+
24931
25267
  /**
24932
25268
  * ```js
24933
25269
  * import { onChannelCreated } from '@amityco/ts-sdk'
@@ -24950,7 +25286,7 @@ const onChannelCreated = (callback) => {
24950
25286
  ingestInCache(data);
24951
25287
  callback(data.channels[0]);
24952
25288
  };
24953
- return createEventSubscriber(client, 'onChannelCreated', 'v3.channel.didCreate', filter);
25289
+ return createEventSubscriber(client, 'onChannelCreated', 'channel.created', filter);
24954
25290
  };
24955
25291
 
24956
25292
  /**
@@ -24975,7 +25311,13 @@ const onChannelUpdated = (callback) => {
24975
25311
  ingestInCache(data);
24976
25312
  callback(data.channels[0]);
24977
25313
  };
24978
- return createEventSubscriber(client, 'onChannelUpdated', 'v3.channel.didUpdate', filter);
25314
+ const disposers = [
25315
+ createEventSubscriber(client, 'onChannelUpdated', 'channel.updated', filter),
25316
+ createEventSubscriber(client, 'local.channel.updated', 'local.channel.updated', payload => callback(payload.channels[0])),
25317
+ ];
25318
+ return () => {
25319
+ disposers.forEach(fn => fn());
25320
+ };
24979
25321
  };
24980
25322
 
24981
25323
  /**
@@ -25000,13 +25342,13 @@ const onChannelDeleted = (callback) => {
25000
25342
  ingestInCache(data);
25001
25343
  callback(data.channels[0]);
25002
25344
  };
25003
- return createEventSubscriber(client, 'onChannelDeleted', 'v3.channel.didDelete', filter);
25345
+ return createEventSubscriber(client, 'onChannelDeleted', 'channel.deleted', filter);
25004
25346
  };
25005
25347
 
25006
25348
  /**
25007
25349
  * ```js
25008
25350
  * import { onChannelJoined } from '@amityco/ts-sdk'
25009
- * const dispose = onChannelJoined(channel => {
25351
+ * const dispose = onChannelJoined((channel, member) => {
25010
25352
  * // ...
25011
25353
  * })
25012
25354
  * ```
@@ -25021,17 +25363,19 @@ const onChannelDeleted = (callback) => {
25021
25363
  const onChannelJoined = (callback) => {
25022
25364
  const client = getActiveClient();
25023
25365
  const filter = (payload) => {
25024
- const data = prepareChannelPayload(payload);
25025
- ingestInCache(data);
25026
- callback(data.channels[0]);
25366
+ const channelPayload = prepareChannelPayload(payload);
25367
+ const preparedPayload = prepareMembershipPayload(channelPayload, 'channelUsers');
25368
+ const { channels, channelUsers } = preparedPayload;
25369
+ ingestInCache(preparedPayload);
25370
+ callback(channels[0], channelUsers[0]);
25027
25371
  };
25028
- return createEventSubscriber(client, 'onChannelJoined', 'v3.channel.didJoin', filter);
25372
+ return createEventSubscriber(client, 'onChannelJoined', 'channel.joined', filter);
25029
25373
  };
25030
25374
 
25031
25375
  /**
25032
25376
  * ```js
25033
25377
  * import { onChannelLeft } from '@amityco/ts-sdk'
25034
- * const dispose = onChannelLeft(channel => {
25378
+ * const dispose = onChannelLeft((channel, member) => {
25035
25379
  * // ...
25036
25380
  * })
25037
25381
  * ```
@@ -25044,13 +25388,40 @@ const onChannelJoined = (callback) => {
25044
25388
  * @category Channel Events
25045
25389
  */
25046
25390
  const onChannelLeft = (callback) => {
25391
+ const client = getActiveClient();
25392
+ const filter = (payload) => {
25393
+ const channelPayload = prepareChannelPayload(payload);
25394
+ const preparedPayload = prepareMembershipPayload(channelPayload, 'channelUsers');
25395
+ const { channels, channelUsers } = preparedPayload;
25396
+ ingestInCache(preparedPayload);
25397
+ callback(channels[0], channelUsers[0]);
25398
+ };
25399
+ return createEventSubscriber(client, 'onChannelLeft', 'channel.left', filter);
25400
+ };
25401
+
25402
+ /**
25403
+ * ```js
25404
+ * import { onChannelMuted } from '@amityco/ts-sdk'
25405
+ * const dispose = onChannelMuted(channel => {
25406
+ * // ...
25407
+ * })
25408
+ * ```
25409
+ *
25410
+ * Fired when any {@link Amity.Channel} have been muted
25411
+ *
25412
+ * @param callback The function to call when the event was fired
25413
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
25414
+ *
25415
+ * @category Channel Events
25416
+ */
25417
+ const onChannelMuted = (callback) => {
25047
25418
  const client = getActiveClient();
25048
25419
  const filter = (payload) => {
25049
25420
  const data = prepareChannelPayload(payload);
25050
25421
  ingestInCache(data);
25051
25422
  callback(data.channels[0]);
25052
25423
  };
25053
- return createEventSubscriber(client, 'onChannelLeft', 'v3.channel.didLeave', filter);
25424
+ return createEventSubscriber(client, 'onChannelMuted', 'channel.setMuted', filter);
25054
25425
  };
25055
25426
 
25056
25427
  /**
@@ -25071,11 +25442,13 @@ const onChannelLeft = (callback) => {
25071
25442
  const onChannelMemberAdded = (callback) => {
25072
25443
  const client = getActiveClient();
25073
25444
  const filter = (payload) => {
25074
- const data = prepareChannelPayload(payload);
25075
- ingestInCache(data);
25076
- callback(data.channels[0], data.channelUsers[0]);
25445
+ const channelPayload = prepareChannelPayload(payload);
25446
+ const preparedPayload = prepareMembershipPayload(channelPayload, 'channelUsers');
25447
+ const { channels, channelUsers } = preparedPayload;
25448
+ ingestInCache(preparedPayload);
25449
+ callback(channels[0], channelUsers.find(cu => cu.membership === 'member'));
25077
25450
  };
25078
- return createEventSubscriber(client, 'onChannelMemberAdded', 'v3.channel.didAddUsers', filter);
25451
+ return createEventSubscriber(client, 'onChannelMemberAdded', 'channel.membersAdded', filter);
25079
25452
  };
25080
25453
 
25081
25454
  /**
@@ -25096,11 +25469,13 @@ const onChannelMemberAdded = (callback) => {
25096
25469
  const onChannelMemberRemoved = (callback) => {
25097
25470
  const client = getActiveClient();
25098
25471
  const filter = (payload) => {
25099
- const data = prepareChannelPayload(payload);
25100
- ingestInCache(data);
25101
- callback(data.channels[0], data.channelUsers[0]);
25472
+ const channelPayload = prepareChannelPayload(payload);
25473
+ const preparedPayload = prepareMembershipPayload(channelPayload, 'channelUsers');
25474
+ const { channels, channelUsers } = preparedPayload;
25475
+ ingestInCache(preparedPayload);
25476
+ callback(channels[0], channelUsers[0]);
25102
25477
  };
25103
- return createEventSubscriber(client, 'onChannelMemberRemoved', 'v3.channel.didRemoveUsers', filter);
25478
+ return createEventSubscriber(client, 'onChannelMemberRemoved', 'channel.membersRemoved', filter);
25104
25479
  };
25105
25480
 
25106
25481
  /**
@@ -25121,11 +25496,13 @@ const onChannelMemberRemoved = (callback) => {
25121
25496
  const onChannelMemberBanned = (callback) => {
25122
25497
  const client = getActiveClient();
25123
25498
  const filter = (payload) => {
25124
- const data = prepareChannelPayload(payload);
25125
- ingestInCache(data);
25126
- callback(data.channels[0], data.channelUsers.find(cu => cu.membership === 'banned'));
25499
+ const channelPayload = prepareChannelPayload(payload);
25500
+ const preparedPayload = prepareMembershipPayload(channelPayload, 'channelUsers');
25501
+ const { channels, channelUsers } = preparedPayload;
25502
+ ingestInCache(preparedPayload);
25503
+ callback(channels[0], channelUsers.find(cu => cu.membership === 'banned'));
25127
25504
  };
25128
- return createEventSubscriber(client, 'onChannelMemberBanned', 'v3.channel.didBan', filter);
25505
+ return createEventSubscriber(client, 'onChannelMemberBanned', 'channel.banned', filter);
25129
25506
  };
25130
25507
 
25131
25508
  /**
@@ -25146,11 +25523,13 @@ const onChannelMemberBanned = (callback) => {
25146
25523
  const onChannelMemberUnbanned = (callback) => {
25147
25524
  const client = getActiveClient();
25148
25525
  const filter = (payload) => {
25149
- const data = prepareChannelPayload(payload);
25150
- ingestInCache(data);
25151
- callback(data.channels[0], data.channelUsers.find(cu => cu.membership === 'none'));
25526
+ const channelPayload = prepareChannelPayload(payload);
25527
+ const preparedPayload = prepareMembershipPayload(channelPayload, 'channelUsers');
25528
+ const { channels, channelUsers } = preparedPayload;
25529
+ ingestInCache(preparedPayload);
25530
+ callback(channels[0], channelUsers.find(cu => cu.membership === 'none'));
25152
25531
  };
25153
- return createEventSubscriber(client, 'onChannelMemberBanned', 'v3.channel.didUnban', filter);
25532
+ return createEventSubscriber(client, 'onChannelMemberUnbanned', 'channel.unbanned', filter);
25154
25533
  };
25155
25534
 
25156
25535
  /**
@@ -25186,7 +25565,7 @@ const observeChannel = (channelId, callback) => {
25186
25565
  (_c = callback[action]) === null || _c === void 0 ? void 0 : _c.call(callback, result);
25187
25566
  };
25188
25567
  const disposers = [];
25189
- disposers.push(onChannelUpdated(data => router({ data, loading: false, origin: 'event' }, 'onUpdate')), onChannelDeleted(data => router({ data, loading: false, origin: 'event' }, 'onDelete')), onChannelJoined(data => router({ data, loading: false, origin: 'event' }, 'onJoin')), onChannelLeft(data => router({ data, loading: false, origin: 'event' }, 'onLeft')), onChannelMemberAdded(data => router({ data, loading: false, origin: 'event' }, 'onMemberAdded')), onChannelMemberRemoved(data => router({ data, loading: false, origin: 'event' }, 'onMemberRemoved')));
25568
+ disposers.push(onChannelUpdated(data => router({ data, loading: false, origin: 'event' }, 'onUpdate')), onChannelDeleted(data => router({ data, loading: false, origin: 'event' }, 'onDelete')), onChannelJoined(data => router({ data, loading: false, origin: 'event' }, 'onJoin')), onChannelLeft(data => router({ data, loading: false, origin: 'event' }, 'onLeft')), onChannelMuted(data => router({ data, loading: false, origin: 'event' }, 'onMute')), onChannelMemberAdded(data => router({ data, loading: false, origin: 'event' }, 'onMemberAdded')), onChannelMemberRemoved(data => router({ data, loading: false, origin: 'event' }, 'onMemberRemoved')));
25190
25569
  runQuery(createQuery(getChannel, channelId), result => result.data && router(result, 'onFetch'));
25191
25570
  return () => {
25192
25571
  log(`observeChannel(tmpid: ${timestamp}) > dispose`);
@@ -25221,324 +25600,1131 @@ const observeChannels = (callback) => {
25221
25600
  (_a = callback.onEvent) === null || _a === void 0 ? void 0 : _a.call(callback, action, channel);
25222
25601
  (_b = callback[action]) === null || _b === void 0 ? void 0 : _b.call(callback, channel);
25223
25602
  };
25224
- disposers.push(onChannelCreated(data => router(data, 'onCreate')), onChannelUpdated(data => router(data, 'onUpdate')), onChannelDeleted(data => router(data, 'onDelete')), onChannelJoined(data => router(data, 'onJoin')), onChannelLeft(data => router(data, 'onLeft')), onChannelMemberAdded(data => router(data, 'onMemberAdded')), onChannelMemberRemoved(data => router(data, 'onMemberRemoved')));
25603
+ disposers.push(onChannelCreated(data => router(data, 'onCreate')), onChannelUpdated(data => router(data, 'onUpdate')), onChannelDeleted(data => router(data, 'onDelete')), onChannelJoined(data => router(data, 'onJoin')), onChannelLeft(data => router(data, 'onLeft')), onChannelMuted(data => router(data, 'onMute')), onChannelMemberAdded(data => router(data, 'onMemberAdded')), onChannelMemberRemoved(data => router(data, 'onMemberRemoved')));
25225
25604
  return () => {
25226
25605
  log(`observeChannels(tmpid: ${timestamp}) > dispose`);
25227
25606
  disposers.forEach(fn => fn());
25228
25607
  };
25229
25608
  };
25230
25609
 
25610
+ function hasMention(model, userId) {
25611
+ var _a, _b;
25612
+ const channelMention = (_a = model === null || model === void 0 ? void 0 : model.mentionees) === null || _a === void 0 ? void 0 : _a.find(x => x.type === 'channel');
25613
+ if (channelMention) {
25614
+ return true;
25615
+ }
25616
+ const userMention = (_b = model === null || model === void 0 ? void 0 : model.mentionees) === null || _b === void 0 ? void 0 : _b.find(x => x.type === 'user');
25617
+ if (userMention) {
25618
+ return userMention.userIds.includes(userId);
25619
+ }
25620
+ return false;
25621
+ }
25622
+ function isCollectionOutdated(collection, newItem, action) {
25623
+ const key = identifyModelKey(newItem);
25624
+ // @ts-ignore
25625
+ const item = collection.find(x => x[key] === newItem[key]);
25626
+ if (item) {
25627
+ return hasUpdates(item, newItem);
25628
+ }
25629
+ return action === 'onCreate';
25630
+ }
25631
+ function merge(collection1, collection2) {
25632
+ const temp = [...collection1, ...collection2];
25633
+ if (temp.length === 0) {
25634
+ return [];
25635
+ }
25636
+ const key = identifyModelKey(temp[0]);
25637
+ const map = new Map();
25638
+ // @ts-ignore
25639
+ temp.forEach(x => map.set(x[key], x));
25640
+ return Array.from(map.values());
25641
+ }
25642
+
25231
25643
  /**
25232
25644
  * ```js
25233
- * import { liveChannels } from '@amityco/ts-sdk'
25234
- *
25235
- * let channels = []
25236
- * const unsub = liveChannels({
25237
- * displayName: Amity.Channel['displayName'],
25238
- * }, response => merge(channels, response.data))
25645
+ * import { onMessageCreated } from '@amityco/ts-sdk'
25646
+ * const dispose = onMessageCreated(message => {
25647
+ * // ...
25648
+ * })
25239
25649
  * ```
25240
25650
  *
25241
- * Observe all mutations on a list of {@link Amity.Channel}s
25651
+ * Fired when an {@link Amity.Message} has been created
25242
25652
  *
25243
- * @param params for querying channels
25244
- * @param callback the function to call when new data are available
25245
- * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the channels
25653
+ * @param callback The function to call when the event was fired
25654
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
25246
25655
  *
25247
- * @category Channel Live Collection
25656
+ * @category Message Events
25248
25657
  */
25249
- const liveChannels = (params, callback, config) => {
25250
- const { log, cache, userId } = getActiveClient();
25251
- if (!cache) {
25252
- console.log(ENABLE_CACHE_MESSAGE);
25253
- }
25254
- const timestamp = Date.now();
25255
- log(`liveChannels(tmpid: ${timestamp}) > listen`);
25256
- const { limit: queryLimit } = params, queryParams = __rest(params, ["limit"]);
25257
- const limit = queryLimit !== null && queryLimit !== void 0 ? queryLimit : COLLECTION_DEFAULT_PAGINATION_LIMIT;
25258
- const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config !== null && config !== void 0 ? config : {};
25259
- const disposers = [];
25260
- const cacheKey = ['channel', 'collection', {}];
25261
- const responder = (data) => {
25262
- var _a, _b;
25263
- let channels = (_a = data.data
25264
- .map(channelId => pullFromCache(['channel', 'get', channelId]))
25265
- .filter(Boolean)
25266
- .map(({ data }) => data)) !== null && _a !== void 0 ? _a : [];
25267
- channels = filterByPropEquality(channels, 'isDeleted', params.isDeleted);
25268
- channels = filterByPropEquality(channels, 'displayName', params.displayName);
25269
- if (params.types) {
25270
- channels = channels.filter(c => { var _a; return (_a = params.types) === null || _a === void 0 ? void 0 : _a.includes(c.type); });
25271
- }
25272
- if (params.tags) {
25273
- channels = channels.filter(c => { var _a; return (_a = c.tags) === null || _a === void 0 ? void 0 : _a.some(t => { var _a; return (_a = params.tags) === null || _a === void 0 ? void 0 : _a.includes(t); }); });
25274
- }
25275
- if (params.excludeTags) {
25276
- channels = channels.filter(c => { var _a; return !((_a = c.tags) === null || _a === void 0 ? void 0 : _a.some(t => { var _a; return (_a = params.excludeTags) === null || _a === void 0 ? void 0 : _a.includes(t); })); });
25277
- }
25278
- // userId is required to be able to filter channel by current active user
25279
- if (params.membership && userId) {
25280
- channels = filterByChannelMembership(channels, params.membership, userId);
25281
- }
25282
- const sortBy = params.sortBy || 'lastCreated';
25283
- if (sortBy === 'lastCreated' || sortBy === 'firstCreated') {
25284
- channels = channels.sort(sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated);
25285
- }
25286
- /*
25287
- * The server returns channels with empty | null displayName's first before
25288
- * returning sorted list of channels with displayNames
25289
- *
25290
- * This section needs to be updated as displayNames can be null as well
25291
- */
25292
- if (sortBy === 'displayName') {
25293
- channels = channels
25294
- // this needs to be aligned with the backend data type
25295
- .map(c => (c.displayName ? c : Object.assign(Object.assign({}, c), { displayName: '' })))
25296
- // @ts-ignore
25297
- .sort(sortByDisplayName);
25658
+ const onMessageCreated = (callback) => {
25659
+ const client = getActiveClient();
25660
+ const filter = (rawPayload) => {
25661
+ const payload = prepareMessagePayload(rawPayload);
25662
+ const message = payload.messages[0];
25663
+ const cached = pullFromCache(['channel', 'get', message.channelId]);
25664
+ if (cached && cached.data.defaultSubChannelId === message.subChannelId) {
25665
+ let update;
25666
+ // @ts-ignore
25667
+ if (cached.data.localReading) {
25668
+ update = Object.assign(Object.assign({}, cached.data), { localReadToSegment: message.channelSegment, localLastMentionSegment: hasMention(message, client.userId)
25669
+ ? message.channelSegment
25670
+ : cached.data.localLastMentionSegment, messageCount: message.channelSegment, lastActivity: message.createdAt, updatedAt: message.createdAt });
25671
+ }
25672
+ else {
25673
+ update = Object.assign(Object.assign({}, cached.data), { defaultSubChannelHasUnreadMention: hasMention(message, client.userId) || cached.data.defaultSubChannelHasUnreadMention, defaultSubChannelUnreadCount: message.channelSegment - cached.data.localReadToSegment, lastActivity: message.createdAt, messageCount: message.channelSegment, updatedAt: message.createdAt });
25674
+ }
25675
+ pushToCache(['channel', 'get', message.channelId], update);
25676
+ client.emitter.emit('local.channel.updated', { channels: [update] });
25298
25677
  }
25299
- callback({
25300
- onNextPage: onFetch,
25301
- data: channels,
25302
- hasNextPage: !!((_b = data.params) === null || _b === void 0 ? void 0 : _b.page),
25303
- loading: data.loading,
25304
- error: data.error,
25305
- });
25678
+ ingestInCache(payload);
25679
+ callback(message);
25306
25680
  };
25307
- const realtimeRouter = (channel, action) => {
25308
- var _a;
25309
- const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
25310
- if (!collection)
25311
- return;
25312
- if (action === 'onCreate') {
25313
- collection.data = [...new Set([channel.channelId, ...collection.data])];
25314
- /*
25315
- * if the filter isDeleted is set, only collection item must be updated and not
25316
- * the collection
25317
- */
25318
- }
25319
- else if (action === 'onDelete' && !params.isDeleted) {
25320
- collection.data = collection.data.filter(c => c !== channel.channelId);
25321
- }
25322
- pushToCache(cacheKey, collection);
25323
- responder(collection);
25681
+ const disposers = [
25682
+ createEventSubscriber(client, 'message/onMessageCreated', 'message.created', filter),
25683
+ createEventSubscriber(client, 'local.message.created', 'local.message.created', payload => callback(payload.messages[0])),
25684
+ ];
25685
+ return () => {
25686
+ disposers.forEach(fn => fn());
25324
25687
  };
25325
- const onFetch = () => {
25326
- var _a, _b, _c;
25327
- const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
25328
- const channels = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
25329
- if (channels.length > 0 && !(collection === null || collection === void 0 ? void 0 : collection.params.page))
25330
- return;
25331
- const query = createQuery(queryChannels, Object.assign(Object.assign({}, queryParams), { page: (_c = collection === null || collection === void 0 ? void 0 : collection.params.page) !== null && _c !== void 0 ? _c : { limit } }));
25332
- runQuery(query, ({ data: result, error, loading, nextPage: page }) => {
25333
- const data = {
25334
- loading,
25335
- error,
25336
- params: { page },
25337
- data: channels,
25338
- };
25339
- if (result) {
25340
- data.data = [...new Set([...channels, ...result.map(getResolver('channel'))])];
25341
- }
25342
- pushToCache(cacheKey, data);
25343
- responder(data);
25688
+ };
25689
+
25690
+ /**
25691
+ * ```js
25692
+ * import { onMessageUpdated } from '@amityco/ts-sdk'
25693
+ * const dispose = onMessageUpdated(message => {
25694
+ * // ...
25695
+ * })
25696
+ * ```
25697
+ *
25698
+ * Fired when an {@link Amity.Message} has been updated
25699
+ *
25700
+ * @param callback The function to call when the event was fired
25701
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
25702
+ *
25703
+ * @category Message Events
25704
+ */
25705
+ const onMessageUpdated = (callback) => {
25706
+ const client = getActiveClient();
25707
+ const filter = (rawPayload) => {
25708
+ const payload = prepareMessagePayload(rawPayload);
25709
+ ingestInCache(payload);
25710
+ callback(payload.messages[0]);
25711
+ };
25712
+ const disposers = [
25713
+ createEventSubscriber(client, 'message/onMessageUpdated', 'message.updated', filter),
25714
+ createEventSubscriber(client, 'local.message.updated', 'local.message.updated', payload => callback(payload.messages[0])),
25715
+ ];
25716
+ return () => {
25717
+ disposers.forEach(fn => fn());
25718
+ };
25719
+ };
25720
+
25721
+ /**
25722
+ * ```js
25723
+ * import { onMessageDeleted } from '@amityco/ts-sdk'
25724
+ * const dispose = onMessageDeleted(message => {
25725
+ * // ...
25726
+ * })
25727
+ * ```
25728
+ *
25729
+ * Fired when an {@link Amity.Message} was deleted
25730
+ *
25731
+ * @param callback The function to call when the event was fired
25732
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
25733
+ *
25734
+ * @category Message Events
25735
+ */
25736
+ const onMessageDeleted = (callback) => {
25737
+ const client = getActiveClient();
25738
+ const filter = (rawPayload) => {
25739
+ const payload = prepareMessagePayload(rawPayload);
25740
+ ingestInCache(payload);
25741
+ callback(payload.messages[0]);
25742
+ };
25743
+ const disposers = [
25744
+ createEventSubscriber(client, 'message/onMessageDeleted', 'message.deleted', filter),
25745
+ createEventSubscriber(client, 'local.message.deleted', 'local.message.deleted', payload => callback(payload.messages[0])),
25746
+ ];
25747
+ return () => {
25748
+ disposers.forEach(fn => fn());
25749
+ };
25750
+ };
25751
+
25752
+ /**
25753
+ * ```js
25754
+ * import { onMessageFlagged } from '@amityco/ts-sdk'
25755
+ * const dispose = onMessageFlagged(message => {
25756
+ * // ...
25757
+ * })
25758
+ * ```
25759
+ *
25760
+ * Fired when a {@link Amity.Message} has been flagged
25761
+ *
25762
+ * @param callback The function to call when the event was fired
25763
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
25764
+ *
25765
+ * @category Message Events
25766
+ */
25767
+ const onMessageFlagged = (callback) => {
25768
+ const client = getActiveClient();
25769
+ const filter = (rawPayload) => {
25770
+ const payload = prepareMessagePayload(rawPayload);
25771
+ ingestInCache(payload);
25772
+ callback(payload.messages[0]);
25773
+ };
25774
+ return createEventSubscriber(client, 'onMessageFlagged', 'message.flagged', filter);
25775
+ };
25776
+
25777
+ /**
25778
+ * ```js
25779
+ * import { onMessageUnflagged } from '@amityco/ts-sdk'
25780
+ * const dispose = onMessageUnflagged(message => {
25781
+ * // ...
25782
+ * })
25783
+ * ```
25784
+ *
25785
+ * Fired when a flag has been removed from a {@link Amity.Message}
25786
+ *
25787
+ * @param callback The function to call when the event was fired
25788
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
25789
+ *
25790
+ * @category Message Events
25791
+ */
25792
+ const onMessageUnflagged = (callback) => {
25793
+ const client = getActiveClient();
25794
+ const filter = (rawPayload) => {
25795
+ const payload = prepareMessagePayload(rawPayload);
25796
+ ingestInCache(payload);
25797
+ callback(payload.messages[0]);
25798
+ };
25799
+ return createEventSubscriber(client, 'onMessageUnflagged', 'message.unflagged', filter);
25800
+ };
25801
+
25802
+ /**
25803
+ * ```js
25804
+ * import { onMessageFlagCleared } from '@amityco/ts-sdk'
25805
+ * const dispose = onMessageFlagCleared(message => {
25806
+ * // ...
25807
+ * })
25808
+ * ```
25809
+ *
25810
+ * Fired when flags have been cleared for a {@link Amity.Message}
25811
+ *
25812
+ * @param callback The function to call when the event was fired
25813
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
25814
+ *
25815
+ * @category Message Events
25816
+ */
25817
+ const onMessageFlagCleared = (callback) => {
25818
+ const client = getActiveClient();
25819
+ const filter = (rawPayload) => {
25820
+ const payload = prepareMessagePayload(rawPayload);
25821
+ ingestInCache(payload);
25822
+ callback(payload.messages[0]);
25823
+ };
25824
+ return createEventSubscriber(client, 'onMessageFlagCleared', 'message.flagCleared', filter);
25825
+ };
25826
+
25827
+ /**
25828
+ * ```js
25829
+ * import { onMessageReactionAdded } from '@amityco/ts-sdk';
25830
+ *
25831
+ * const unsubscribe = onMessageReactionAdded(message => {
25832
+ * // ...
25833
+ * });
25834
+ * ```
25835
+ *
25836
+ * Fired when a {@link Amity.Message} has been reacted
25837
+ *
25838
+ * @param callback The function to call when the event was fired
25839
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
25840
+ *
25841
+ * @category Post Events
25842
+ */
25843
+ const onMessageReactionAdded = (callback) => {
25844
+ const client = getActiveClient();
25845
+ const filter = (rawPayload) => {
25846
+ const payload = prepareMessagePayload(rawPayload);
25847
+ ingestInCache(payload);
25848
+ callback(payload.messages[0]);
25849
+ };
25850
+ return createEventSubscriber(client, 'onMessageReactionAdded', 'message.reactionAdded', filter);
25851
+ };
25852
+
25853
+ /**
25854
+ * ```js
25855
+ * import { onMessageReactionRemoved } from '@amityco/ts-sdk';
25856
+ *
25857
+ * const unsubscribe = onMessageReactionRemoved(message => {
25858
+ * // ...
25859
+ * });
25860
+ * ```
25861
+ *
25862
+ * Fired when a reaction has been removed from a {@link Amity.Message}
25863
+ *
25864
+ * @param callback The function to call when the event was fired
25865
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
25866
+ *
25867
+ * @category Post Events
25868
+ */
25869
+ const onMessageReactionRemoved = (callback) => {
25870
+ const client = getActiveClient();
25871
+ const filter = (rawPayload) => {
25872
+ const payload = prepareMessagePayload(rawPayload);
25873
+ ingestInCache(payload);
25874
+ callback(payload.messages[0]);
25875
+ };
25876
+ return createEventSubscriber(client, 'onMessageReactionRemoved', 'message.reactionRemoved', filter);
25877
+ };
25878
+
25879
+ /**
25880
+ * ```js
25881
+ * import { liveChannel } from '@amityco/ts-sdk';
25882
+ *
25883
+ * let channel;
25884
+ *
25885
+ * const unsubscribe = liveChannel(channelId, response => {
25886
+ * channel = response.data;
25887
+ * });
25888
+ * ```
25889
+ *
25890
+ * Observe all mutation on a given {@link Amity.Channel}
25891
+ *
25892
+ * @param channelId the ID of the channel to observe
25893
+ * @param callback the function to call when new data are available
25894
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the channel
25895
+ *
25896
+ * @category Message Live Object
25897
+ */
25898
+ const liveChannel = (channelId, callback) => {
25899
+ const { log, cache } = getActiveClient();
25900
+ const timestamp = Date.now();
25901
+ log(`liveChannel(tmpid: ${timestamp}) > listen`);
25902
+ if (!cache) {
25903
+ console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
25904
+ }
25905
+ let channel;
25906
+ let isUnsyncedObject = false;
25907
+ const disposers = [];
25908
+ const dispatcher = (data) => {
25909
+ channel = data.data;
25910
+ callback(data);
25911
+ };
25912
+ const realtimeRouter = (eventChannel) => {
25913
+ if (channelId !== eventChannel.channelId) {
25914
+ return;
25915
+ }
25916
+ if (channel && !hasUpdates(channel, eventChannel)) {
25917
+ return;
25918
+ }
25919
+ dispatcher({ loading: false, data: eventChannel, origin: 'event' });
25920
+ };
25921
+ const onFetch = () => {
25922
+ const query = createQuery(getChannel, channelId);
25923
+ runQuery(query, ({ loading, data, error, origin, cachedAt }) => {
25924
+ if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
25925
+ dispatcher({
25926
+ data,
25927
+ origin,
25928
+ loading: false,
25929
+ error: new ASCApiError(UNSYNCED_OBJECT_CACHED_AT_MESSAGE, 800800 /* Amity.ClientError.DISALOOW_UNSYNCED_OBJECT */, "error" /* Amity.ErrorLevel.ERROR */),
25930
+ });
25931
+ isUnsyncedObject = true;
25932
+ disposers.forEach(fn => fn());
25933
+ }
25934
+ else if (!isUnsyncedObject) {
25935
+ dispatcher({ loading, data, origin, error });
25936
+ }
25937
+ if (error) {
25938
+ disposers.forEach(fn => fn());
25939
+ }
25940
+ });
25941
+ };
25942
+ disposers.push(onChannelUpdated(realtimeRouter), onChannelDeleted(realtimeRouter), onChannelJoined(realtimeRouter), onChannelMuted(realtimeRouter), onMessageCreated(() => null));
25943
+ onFetch();
25944
+ return () => {
25945
+ log(`liveChannel(tmpid: ${timestamp}) > dispose`);
25946
+ disposers.forEach(fn => fn());
25947
+ };
25948
+ };
25949
+
25950
+ /**
25951
+ * ```js
25952
+ * import { liveChannels } from '@amityco/ts-sdk'
25953
+ *
25954
+ * let channels = []
25955
+ * const unsub = liveChannels({
25956
+ * displayName: Amity.Channel['displayName'],
25957
+ * }, response => merge(channels, response.data))
25958
+ * ```
25959
+ *
25960
+ * Observe all mutations on a list of {@link Amity.Channel}s
25961
+ *
25962
+ * @param params for querying channels
25963
+ * @param callback the function to call when new data are available
25964
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the channels
25965
+ *
25966
+ * @category Channel Live Collection
25967
+ */
25968
+ const liveChannels = (params, callback, config) => {
25969
+ const { log, cache, userId } = getActiveClient();
25970
+ if (!cache) {
25971
+ console.log(ENABLE_CACHE_MESSAGE);
25972
+ }
25973
+ const timestamp = Date.now();
25974
+ log(`liveChannels(tmpid: ${timestamp}) > listen`);
25975
+ const { limit: queryLimit } = params, queryParams = __rest(params, ["limit"]);
25976
+ const limit = queryLimit !== null && queryLimit !== void 0 ? queryLimit : COLLECTION_DEFAULT_PAGINATION_LIMIT;
25977
+ const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config !== null && config !== void 0 ? config : {};
25978
+ const disposers = [];
25979
+ const cacheKey = ['channel', 'collection', {}];
25980
+ const responder = (data) => {
25981
+ var _a, _b;
25982
+ let channels = (_a = data.data
25983
+ .map(channelId => pullFromCache(['channel', 'get', channelId]))
25984
+ .filter(Boolean)
25985
+ .map(({ data }) => data)) !== null && _a !== void 0 ? _a : [];
25986
+ channels = filterByPropEquality(channels, 'isDeleted', params.isDeleted);
25987
+ channels = filterByPropEquality(channels, 'displayName', params.displayName);
25988
+ if (params.types) {
25989
+ channels = channels.filter(c => { var _a; return (_a = params.types) === null || _a === void 0 ? void 0 : _a.includes(c.type); });
25990
+ }
25991
+ if (params.tags) {
25992
+ channels = channels.filter(c => { var _a; return (_a = c.tags) === null || _a === void 0 ? void 0 : _a.some(t => { var _a; return (_a = params.tags) === null || _a === void 0 ? void 0 : _a.includes(t); }); });
25993
+ }
25994
+ if (params.excludeTags) {
25995
+ channels = channels.filter(c => { var _a; return !((_a = c.tags) === null || _a === void 0 ? void 0 : _a.some(t => { var _a; return (_a = params.excludeTags) === null || _a === void 0 ? void 0 : _a.includes(t); })); });
25996
+ }
25997
+ // userId is required to be able to filter channel by current active user
25998
+ if (params.membership && userId) {
25999
+ channels = filterByChannelMembership(channels, params.membership, userId);
26000
+ }
26001
+ const sortBy = params.sortBy || 'lastCreated';
26002
+ if (sortBy === 'lastCreated' || sortBy === 'firstCreated') {
26003
+ channels = channels.sort(sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated);
26004
+ }
26005
+ /*
26006
+ * The server returns channels with empty | null displayName's first before
26007
+ * returning sorted list of channels with displayNames
26008
+ *
26009
+ * This section needs to be updated as displayNames can be null as well
26010
+ */
26011
+ if (sortBy === 'displayName') {
26012
+ channels = channels
26013
+ // this needs to be aligned with the backend data type
26014
+ .map(c => (c.displayName ? c : Object.assign(Object.assign({}, c), { displayName: '' })))
26015
+ // @ts-ignore
26016
+ .sort(sortByDisplayName);
26017
+ }
26018
+ callback({
26019
+ onNextPage: onFetch,
26020
+ data: channels,
26021
+ hasNextPage: !!((_b = data.params) === null || _b === void 0 ? void 0 : _b.page),
26022
+ loading: data.loading,
26023
+ error: data.error,
26024
+ });
26025
+ };
26026
+ const realtimeRouter = (action) => (channel) => {
26027
+ var _a;
26028
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
26029
+ if (!collection)
26030
+ return;
26031
+ if (action === 'onDelete' && params.isDeleted === false) {
26032
+ collection.data = collection.data.filter(c => c !== channel.channelId);
26033
+ }
26034
+ else {
26035
+ collection.data = [...new Set([channel.channelId, ...collection.data])];
26036
+ }
26037
+ pushToCache(cacheKey, collection);
26038
+ responder(collection);
26039
+ };
26040
+ const onFetch = () => {
26041
+ var _a, _b, _c;
26042
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
26043
+ const channels = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
26044
+ if (channels.length > 0 && !(collection === null || collection === void 0 ? void 0 : collection.params.page))
26045
+ return;
26046
+ const query = createQuery(queryChannels, Object.assign(Object.assign({}, queryParams), { page: (_c = collection === null || collection === void 0 ? void 0 : collection.params.page) !== null && _c !== void 0 ? _c : { limit } }));
26047
+ runQuery(query, ({ data: result, error, loading, nextPage: page }) => {
26048
+ const data = {
26049
+ loading,
26050
+ error,
26051
+ params: { page },
26052
+ data: channels,
26053
+ };
26054
+ if (result) {
26055
+ data.data = [...new Set([...channels, ...result.map(getResolver('channel'))])];
26056
+ }
26057
+ pushToCache(cacheKey, data);
26058
+ responder(data);
26059
+ }, queryOptions(policy));
26060
+ };
26061
+ disposers.push(onChannelCreated(realtimeRouter('onCreate')), onChannelDeleted(realtimeRouter('onDelete')), onChannelUpdated(realtimeRouter('onUpdate')), onChannelMuted(realtimeRouter('onMute')), onChannelJoined(realtimeRouter('onJoin')), onChannelLeft(realtimeRouter('onLeft')), onChannelMemberAdded(realtimeRouter('onMemberAdded')), onChannelMemberRemoved(realtimeRouter('onMemberRemoved')), onMessageCreated(() => null));
26062
+ onFetch();
26063
+ return () => {
26064
+ log(`liveChannels(tmpid: ${timestamp}) > dispose`);
26065
+ disposers.forEach(fn => fn());
26066
+ };
26067
+ };
26068
+
26069
+ /**
26070
+ * ```js
26071
+ * import { liveChannelMembers } from '@amityco/ts-sdk'
26072
+ *
26073
+ * let channelMembers = []
26074
+ * const unsub = liveChannelMembers({
26075
+ * channelId: Amity.Channel['channelId'],
26076
+ * }, response => merge(channelMembers, response.data))
26077
+ * ```
26078
+ *
26079
+ * Observe all mutations on a list of {@link Amity.ChannelUser}s
26080
+ *
26081
+ * @param params for querying channel users
26082
+ * @param callback the function to call when new data are available
26083
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the channel users
26084
+ *
26085
+ * @category Channel Live Collection
26086
+ */
26087
+ const liveChannelMembers = (params, callback, config) => {
26088
+ const { log, cache } = getActiveClient();
26089
+ if (!cache) {
26090
+ console.log(ENABLE_CACHE_MESSAGE);
26091
+ }
26092
+ const timestamp = Date.now();
26093
+ log(`liveChannelMembers(tmpid: ${timestamp}) > listen`);
26094
+ const { limit: queryLimit } = params, queryParams = __rest(params, ["limit"]);
26095
+ const limit = queryLimit !== null && queryLimit !== void 0 ? queryLimit : COLLECTION_DEFAULT_PAGINATION_LIMIT;
26096
+ const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config !== null && config !== void 0 ? config : {};
26097
+ const disposers = [];
26098
+ const cacheKey = ['channelUsers', 'collection', { channelId: params.channelId }];
26099
+ const responder = (data) => {
26100
+ var _a, _b;
26101
+ let channelMembers = (_a = data.data
26102
+ .map(id => pullFromCache(['channelUsers', 'get', id]))
26103
+ .filter(Boolean)
26104
+ .map(({ data }) => data)) !== null && _a !== void 0 ? _a : [];
26105
+ channelMembers = filterByPropEquality(channelMembers, 'roles', params.roles);
26106
+ if (params.memberships) {
26107
+ /*
26108
+ * even though membership includes muted as a possible value
26109
+ * when querying the server.
26110
+ * Muted is specified under seperarte property namely isMuted
26111
+ * Hence why I've seperately checked for it's equality
26112
+ */
26113
+ channelMembers = channelMembers.filter(member => {
26114
+ // @ts-ignore
26115
+ if (params.memberships.includes('muted') && member.isMuted) {
26116
+ return true;
26117
+ }
26118
+ // @ts-ignore
26119
+ return params.memberships.includes(member.membership);
26120
+ });
26121
+ }
26122
+ if (params.search) {
26123
+ const containsMatcher = new RegExp(params.search);
26124
+ channelMembers = channelMembers.filter(m => m.userId.match(containsMatcher));
26125
+ }
26126
+ // sort, 'lastCreated' is the default sort order
26127
+ const sortBy = params.sortBy ? params.sortBy : 'lastCreated';
26128
+ channelMembers = channelMembers.sort(sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated);
26129
+ callback({
26130
+ onNextPage: onFetch,
26131
+ data: channelMembers,
26132
+ hasNextPage: !!((_b = data.params) === null || _b === void 0 ? void 0 : _b.page),
26133
+ loading: data.loading,
26134
+ error: data.error,
26135
+ });
26136
+ };
26137
+ const realtimeRouter = (action) => (channel, channelMember) => {
26138
+ var _a;
26139
+ if (params.channelId !== channelMember.channelId) {
26140
+ return;
26141
+ }
26142
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
26143
+ if (!collection)
26144
+ return;
26145
+ const channelMemberCacheId = getResolver('channelUsers')({
26146
+ channelId: params.channelId,
26147
+ userId: channelMember.userId,
26148
+ });
26149
+ if (channelMember.membership === 'none') {
26150
+ collection.data = collection.data.filter(m => m !== channelMemberCacheId);
26151
+ }
26152
+ else if (!collection.data.includes(channelMemberCacheId)) {
26153
+ collection.data = [channelMemberCacheId, ...collection.data];
26154
+ }
26155
+ pushToCache(cacheKey, collection);
26156
+ responder(collection);
26157
+ };
26158
+ const onFetch = () => {
26159
+ var _a, _b, _c;
26160
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
26161
+ const channelMembers = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
26162
+ if (channelMembers.length > 0 && !(collection === null || collection === void 0 ? void 0 : collection.params.page))
26163
+ return;
26164
+ const query = createQuery(queryChannelMembers, Object.assign(Object.assign({}, queryParams), { page: (_c = collection === null || collection === void 0 ? void 0 : collection.params.page) !== null && _c !== void 0 ? _c : { limit } }));
26165
+ runQuery(query, ({ data: result, error, loading, nextPage: page }) => {
26166
+ const data = {
26167
+ loading,
26168
+ error,
26169
+ params: { page },
26170
+ data: channelMembers,
26171
+ };
26172
+ if (result) {
26173
+ data.data = [...new Set([...channelMembers, ...result.map(getResolver('channelUsers'))])];
26174
+ }
26175
+ pushToCache(cacheKey, data);
26176
+ responder(data);
25344
26177
  }, queryOptions(policy));
25345
26178
  };
25346
- disposers.push(onChannelCreated(channel => realtimeRouter(channel, 'onCreate')), onChannelDeleted(channel => realtimeRouter(channel, 'onDelete')), onChannelUpdated(channel => realtimeRouter(channel, 'onUpdate')));
26179
+ disposers.push(onChannelJoined(realtimeRouter()), onChannelLeft(realtimeRouter()), onChannelMemberAdded(realtimeRouter()), onChannelMemberRemoved(realtimeRouter()), onChannelMemberBanned(realtimeRouter()), onChannelMemberUnbanned(realtimeRouter()));
25347
26180
  onFetch();
25348
26181
  return () => {
25349
- log(`liveChannels(tmpid: ${timestamp}) > dispose`);
26182
+ log(`liveChannelMembers(tmpid: ${timestamp}) > dispose`);
25350
26183
  disposers.forEach(fn => fn());
25351
26184
  };
25352
26185
  };
25353
26186
 
26187
+ function convertFromRaw(_a) {
26188
+ var { channelId, channelPublicId, channelType, childCount, creatorId, creatorPublicId, lastMessageId, lastMessageTimestamp, messageFeedId, name } = _a, rest = __rest(_a, ["channelId", "channelPublicId", "channelType", "childCount", "creatorId", "creatorPublicId", "lastMessageId", "lastMessageTimestamp", "messageFeedId", "name"]);
26189
+ return Object.assign(Object.assign({}, rest), { channelId: channelPublicId, creatorId: creatorPublicId, displayName: name, lastActivity: lastMessageTimestamp, latestMessageId: lastMessageId, messageCount: childCount, subChannelId: messageFeedId });
26190
+ }
26191
+ const prepareSubChannelPayload = (payload) => {
26192
+ return Object.assign(Object.assign({}, payload), { messageFeeds: payload.messageFeeds.map(convertFromRaw) });
26193
+ };
26194
+ function convertQueryParams(_a) {
26195
+ var { excludeDefaultSubChannel } = _a, rest = __rest(_a, ["excludeDefaultSubChannel"]);
26196
+ const out = Object.assign({}, rest);
26197
+ if (excludeDefaultSubChannel !== undefined) {
26198
+ out.excludeDefaultMessageFeed = excludeDefaultSubChannel;
26199
+ }
26200
+ return out;
26201
+ }
26202
+
25354
26203
  /**
25355
26204
  * ```js
25356
- * import { liveChannelMembers } from '@amityco/ts-sdk'
26205
+ * import { querySubChannels } from '@amityco/ts-sdk'
26206
+ * const subChannels = await querySubChannels({ channelId: 'channelId' })
26207
+ * ```
25357
26208
  *
25358
- * let channelMembers = []
25359
- * const unsub = liveChannelMembers({
25360
- * channelId: Amity.Channel['channelId'],
25361
- * }, response => merge(channelMembers, response.data))
26209
+ * Queries a paginable list of {@link Amity.SubChannel} objects
26210
+ *
26211
+ * @param query The query parameters
26212
+ * @returns A page of {@link Amity.SubChannel} objects
26213
+ *
26214
+ * @category Channel API
26215
+ * @async
26216
+ */
26217
+ const querySubChannels = async (query) => {
26218
+ const client = getActiveClient();
26219
+ client.log('channel/querySubChannels', query);
26220
+ const _a = convertQueryParams(query), { page = { limit: 10 }, channelId } = _a, params = __rest(_a, ["page", "channelId"]);
26221
+ const response = await client.http.get(`/api/v5/message-feeds/channel/${channelId}`, {
26222
+ params: Object.assign(Object.assign({}, params), { options: {
26223
+ token: toToken(page, 'skiplimit'),
26224
+ } }),
26225
+ });
26226
+ const _b = response.data, { paging } = _b, payload = __rest(_b, ["paging"]);
26227
+ const data = prepareSubChannelPayload(payload);
26228
+ const subChannels = data.messageFeeds;
26229
+ const cachedAt = client.cache && Date.now();
26230
+ if (client.cache) {
26231
+ ingestInCache(data, { cachedAt });
26232
+ const cacheKey = [
26233
+ 'subChannel',
26234
+ 'query',
26235
+ Object.assign(Object.assign({ channelId }, params), { options: Object.assign({}, page) }),
26236
+ ];
26237
+ pushToCache(cacheKey, { subChannels: subChannels.map(getResolver('subChannel')), paging });
26238
+ }
26239
+ fireEvent('local.message-feed.fetched', data);
26240
+ const nextPage = toPage(paging.next);
26241
+ const prevPage = toPage(paging.previous);
26242
+ return { data: subChannels, cachedAt, prevPage, nextPage };
26243
+ };
26244
+ /**
26245
+ * ```js
26246
+ * import { querySubChannels } from '@amityco/ts-sdk'
26247
+ * const subChannels = querySubChannels.locally({ channelId: 'channelId' })
26248
+ * ```
26249
+ *
26250
+ * Queries a paginable list of {@link Amity.SubChannel} objects from cache
26251
+ *
26252
+ * @param query The query parameters
26253
+ * @returns sub channels
26254
+ *
26255
+ * @category Channel API
26256
+ */
26257
+ querySubChannels.locally = (query) => {
26258
+ var _a, _b, _c;
26259
+ const client = getActiveClient();
26260
+ client.log('channel/querySubChannels.locally', query);
26261
+ // @ts-ignore
26262
+ const _d = (_a = convertQueryParams(query)) !== null && _a !== void 0 ? _a : {}, { page = { limit: 10 }, channelId } = _d, params = __rest(_d, ["page", "channelId"]);
26263
+ const cacheKey = [
26264
+ 'subChannel',
26265
+ 'query',
26266
+ Object.assign(Object.assign({ channelId }, params), { options: Object.assign({}, page) }),
26267
+ ];
26268
+ const { data, cachedAt } = (_b = pullFromCache(cacheKey)) !== null && _b !== void 0 ? _b : {};
26269
+ if (!(data === null || data === void 0 ? void 0 : data.subChannels.length))
26270
+ return;
26271
+ const subChannels = data.subChannels
26272
+ .map(ck => pullFromCache(['subChannel', 'get', ck]))
26273
+ .filter(Boolean)
26274
+ .map(({ data }) => data);
26275
+ const prevPage = toPage(data === null || data === void 0 ? void 0 : data.paging.previous);
26276
+ const nextPage = toPage(data === null || data === void 0 ? void 0 : data.paging.next);
26277
+ return subChannels.length === ((_c = data === null || data === void 0 ? void 0 : data.subChannels) === null || _c === void 0 ? void 0 : _c.length)
26278
+ ? { data: subChannels, cachedAt, prevPage, nextPage }
26279
+ : undefined;
26280
+ };
26281
+
26282
+ /**
26283
+ * ```js
26284
+ * import { getSubChannels } from '@amityco/ts-sdk'
26285
+ * const subChannels = await getSubChannels(['foo', 'bar'])
26286
+ * ```
26287
+ *
26288
+ * Fetches a collection of {@link Amity.SubChannel} objects
26289
+ *
26290
+ * @param subChannelIds the IDs of the {@link Amity.SubChannel} to fetch
26291
+ * @returns the associated collection of {@link Amity.SubChannel} objects
26292
+ *
26293
+ * @category Channel API
26294
+ * @async
26295
+ */
26296
+ const getSubChannels = async (subChannelIds) => {
26297
+ const client = getActiveClient();
26298
+ client.log('channel/getSubChannels', subChannelIds);
26299
+ const response = await client.http.get('/api/v5/message-feeds/list', {
26300
+ params: { messageFeedIds: subChannelIds.map(encodeURIComponent) },
26301
+ });
26302
+ const data = prepareSubChannelPayload(response.data);
26303
+ const cachedAt = client.cache && Date.now();
26304
+ if (client.cache)
26305
+ ingestInCache(data, { cachedAt });
26306
+ fireEvent('local.message-feed.fetched', data);
26307
+ return {
26308
+ data: data.messageFeeds,
26309
+ cachedAt,
26310
+ };
26311
+ };
26312
+ /**
26313
+ * ```js
26314
+ * import { getSubChannels } from '@amityco/ts-sdk'
26315
+ * const subChannels = getSubChannels.locally(['foo', 'bar']) ?? []
26316
+ * ```
26317
+ *
26318
+ * Fetches a collection of {@link Amity.SubChannel} objects from cache
26319
+ *
26320
+ * @param subChannelIds the IDs of the {@link Amity.SubChannel} to fetch
26321
+ * @returns the associated collection of {@link Amity.SubChannel} objects
26322
+ *
26323
+ * @category Channel API
26324
+ */
26325
+ getSubChannels.locally = (subChannelIds) => {
26326
+ var _a;
26327
+ const client = getActiveClient();
26328
+ client.log('channel/getSubChannels.locally', subChannelIds);
26329
+ if (!client.cache)
26330
+ return;
26331
+ const cached = subChannelIds
26332
+ .map(channelId => pullFromCache(['subChannel', 'get', channelId]))
26333
+ .filter(Boolean);
26334
+ if ((cached === null || cached === void 0 ? void 0 : cached.length) < subChannelIds.length)
26335
+ return;
26336
+ const subChannels = cached.map(({ data }) => data);
26337
+ const oldest = (_a = cached.sort((a, b) => (a.cachedAt < b.cachedAt ? -1 : 1))) === null || _a === void 0 ? void 0 : _a[0];
26338
+ return {
26339
+ data: subChannels,
26340
+ cachedAt: oldest.cachedAt,
26341
+ };
26342
+ };
26343
+
26344
+ /**
26345
+ * ```js
26346
+ * import { getSubChannel } from '@amityco/ts-sdk'
26347
+ * const subChannel = await getSubChannel('foobar')
26348
+ * ```
26349
+ *
26350
+ * Fetches a {@link Amity.SubChannel} object
26351
+ *
26352
+ * @param subChannelId the ID of the {@link Amity.SubChannel} to fetch
26353
+ * @returns the associated {@link Amity.SubChannel} object
26354
+ *
26355
+ * @category Channel API
26356
+ * @async
26357
+ */
26358
+ const getSubChannel = async (subChannelId) => {
26359
+ const client = getActiveClient();
26360
+ client.log('channel/getSubChannel', subChannelId);
26361
+ isInTombstone('subChannel', subChannelId);
26362
+ try {
26363
+ const response = await client.http.get(`/api/v5/message-feeds/${encodeURIComponent(subChannelId)}`);
26364
+ const data = prepareSubChannelPayload(response.data);
26365
+ const cachedAt = client.cache && Date.now();
26366
+ if (client.cache)
26367
+ ingestInCache(data, { cachedAt });
26368
+ fireEvent('local.message-feed.fetched', data);
26369
+ return {
26370
+ data: data.messageFeeds[0],
26371
+ cachedAt,
26372
+ };
26373
+ }
26374
+ catch (error) {
26375
+ if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
26376
+ pushToTombstone('subChannel', subChannelId);
26377
+ }
26378
+ throw error;
26379
+ }
26380
+ };
26381
+ /**
26382
+ * ```js
26383
+ * import { getSubChannel } from '@amityco/ts-sdk'
26384
+ * const subChannel = getSubChannel.locally('foobar')
26385
+ * ```
26386
+ *
26387
+ * Fetches a {@link Amity.SubChannel} object from cache
26388
+ *
26389
+ * @param subChannelId the ID of the {@link Amity.SubChannel} to fetch
26390
+ * @returns the associated {@link Amity.SubChannel} object
26391
+ *
26392
+ * @category Channel API
26393
+ */
26394
+ getSubChannel.locally = (subChannelId) => {
26395
+ const client = getActiveClient();
26396
+ client.log('channel/getSubChannel.locally', subChannelId);
26397
+ if (!client.cache)
26398
+ return;
26399
+ const cached = pullFromCache(['subChannel', 'get', subChannelId]);
26400
+ if (!cached)
26401
+ return;
26402
+ return {
26403
+ data: cached.data,
26404
+ cachedAt: cached.cachedAt,
26405
+ };
26406
+ };
26407
+
26408
+ /**
26409
+ * ```js
26410
+ * import { createSubChannel } from '@amityco/ts-sdk'
26411
+ * const created = await createSubChannel({ channelId: 'foobar', name: 'foobar' })
26412
+ * ```
26413
+ *
26414
+ * Creates an {@link Amity.SubChannel}
26415
+ *
26416
+ * @param bundle The data necessary to create a new {@link Amity.SubChannel}
26417
+ * @returns The newly created {@link Amity.SubChannel}
26418
+ *
26419
+ * @category Channel API
26420
+ * @async
26421
+ */
26422
+ const createSubChannel = async (bundle) => {
26423
+ const client = getActiveClient();
26424
+ client.log('user/createSubChannel', bundle);
26425
+ const response = await client.http.post('/api/v5/message-feeds', {
26426
+ channelId: bundle.channelId,
26427
+ name: bundle.displayName,
26428
+ });
26429
+ const data = prepareSubChannelPayload(response.data);
26430
+ const cachedAt = client.cache && Date.now();
26431
+ if (client.cache)
26432
+ ingestInCache(data, { cachedAt });
26433
+ fireEvent('message-feed.created', response.data);
26434
+ return {
26435
+ data: data.messageFeeds[0],
26436
+ cachedAt,
26437
+ };
26438
+ };
26439
+
26440
+ /**
26441
+ * ```js
26442
+ * import { updateSubChannel } from '@amityco/ts-sdk'
26443
+ * const updated = await updateSubChannel(subChannelId, { name: 'foobar' })
26444
+ * ```
26445
+ *
26446
+ * Updates an {@link Amity.SubChannel}
26447
+ *
26448
+ * @param subChannelId The ID of the {@link Amity.SubChannel} to edit
26449
+ * @param patch The patch data to apply
26450
+ * @returns the updated {@link Amity.SubChannel} object
26451
+ *
26452
+ * @category Channel API
26453
+ * @async
26454
+ */
26455
+ const updateSubChannel = async (subChannelId, patch) => {
26456
+ const client = getActiveClient();
26457
+ client.log('channel/updateSubChannel', subChannelId, patch);
26458
+ const response = await client.http.put(`/api/v5/message-feeds/${encodeURIComponent(subChannelId)}`, { name: patch.displayName });
26459
+ const data = prepareSubChannelPayload(response.data);
26460
+ const cachedAt = client.cache && Date.now();
26461
+ if (client.cache)
26462
+ ingestInCache(data, { cachedAt });
26463
+ fireEvent('message-feed.updated', response.data);
26464
+ return {
26465
+ data: data.messageFeeds[0],
26466
+ cachedAt,
26467
+ };
26468
+ };
26469
+
26470
+ /**
26471
+ * ```js
26472
+ * import { deleteSubChannel } from '@amityco/ts-sdk'
26473
+ * const success = await deleteSubChannel('foobar')
25362
26474
  * ```
25363
26475
  *
25364
- * Observe all mutations on a list of {@link Amity.ChannelUser}s
26476
+ * Deletes a {@link Amity.SubChannel}
25365
26477
  *
25366
- * @param params for querying channel users
25367
- * @param callback the function to call when new data are available
25368
- * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the channel users
26478
+ * @param subChannelId The {@link Amity.SubChannel} ID to delete
26479
+ * @return A success boolean if the {@link Amity.SubChannel} was deleted
25369
26480
  *
25370
- * @category Channel Live Collection
26481
+ * @category Channel API
26482
+ * @async
25371
26483
  */
25372
- const liveChannelMembers = (params, callback, config) => {
25373
- const { log, cache } = getActiveClient();
25374
- if (!cache) {
25375
- console.log(ENABLE_CACHE_MESSAGE);
26484
+ const deleteSubChannel = async (subChannelId, permanent = false) => {
26485
+ const client = getActiveClient();
26486
+ client.log('channel/deleteSubChannel', subChannelId);
26487
+ const subChannel = await getSubChannel(subChannelId);
26488
+ await client.http.delete(`/api/v5/message-feeds/${encodeURIComponent(subChannelId)}`, { params: { permanent } });
26489
+ const deleted = Object.assign(Object.assign({}, subChannel.data), { isDeleted: true, updatedAt: getFutureDate(subChannel.data.updatedAt) });
26490
+ if (permanent) {
26491
+ setTimeout(() => {
26492
+ pushToTombstone('subChannel', subChannelId);
26493
+ }, 0);
25376
26494
  }
25377
- const timestamp = Date.now();
25378
- log(`liveChannelMembers(tmpid: ${timestamp}) > listen`);
25379
- const { limit: queryLimit } = params, queryParams = __rest(params, ["limit"]);
25380
- const limit = queryLimit !== null && queryLimit !== void 0 ? queryLimit : COLLECTION_DEFAULT_PAGINATION_LIMIT;
25381
- const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config !== null && config !== void 0 ? config : {};
25382
- const disposers = [];
25383
- const cacheKey = ['channelUsers', 'collection', { channelId: params.channelId }];
25384
- const responder = (data) => {
25385
- var _a, _b;
25386
- let channelMembers = (_a = data.data
25387
- .map(id => pullFromCache(['channelUsers', 'get', id]))
25388
- .filter(Boolean)
25389
- .map(({ data }) => data)) !== null && _a !== void 0 ? _a : [];
25390
- channelMembers = filterByPropEquality(channelMembers, 'roles', params.roles);
25391
- if (params.memberships) {
25392
- /*
25393
- * even though membership includes muted as a possible value
25394
- * when querying the server.
25395
- * Muted is specified under seperarte property namely isMuted
25396
- * Hence why I've seperately checked for it's equality
25397
- */
25398
- if (params.memberships.some(m => ['member', 'banned'].includes(m))) {
25399
- channelMembers = filterByPropInclusion(channelMembers, 'membership', params.memberships);
25400
- }
25401
- if (params.memberships.includes('muted')) {
25402
- channelMembers = filterByPropEquality(channelMembers, 'isMuted', true);
25403
- }
25404
- }
25405
- if (params.search) {
25406
- const containsMatcher = new RegExp(params.search);
25407
- channelMembers = channelMembers.filter(m => m.userId.match(containsMatcher));
25408
- }
25409
- // sort, 'lastCreated' is the default sort order
25410
- const sortBy = params.sortBy ? params.sortBy : 'lastCreated';
25411
- channelMembers = channelMembers.sort(sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated);
25412
- callback({
25413
- onNextPage: onFetch,
25414
- data: channelMembers,
25415
- hasNextPage: !!((_b = data.params) === null || _b === void 0 ? void 0 : _b.page),
25416
- loading: data.loading,
25417
- error: data.error,
25418
- });
25419
- };
25420
- const realtimeRouter = (channelMember, action) => {
25421
- var _a;
25422
- const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
25423
- if (!collection)
25424
- return;
25425
- const channelMemberCacheId = getResolver('channelUsers')({
25426
- channelId: params.channelId,
25427
- userId: channelMember.userId,
25428
- });
25429
- if (action === 'onMemberAdded') {
25430
- collection.data = [...new Set([channelMemberCacheId, ...collection.data])];
25431
- }
25432
- if (action === 'onMemberRemoved') {
25433
- collection.data = collection.data.filter(m => m !== channelMemberCacheId);
25434
- }
25435
- pushToCache(cacheKey, collection);
25436
- responder(collection);
25437
- };
25438
- const onFetch = () => {
25439
- var _a, _b, _c;
25440
- const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
25441
- const channelMembers = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
25442
- if (channelMembers.length > 0 && !(collection === null || collection === void 0 ? void 0 : collection.params.page))
25443
- return;
25444
- const query = createQuery(queryChannelMembers, Object.assign(Object.assign({}, queryParams), { page: (_c = collection === null || collection === void 0 ? void 0 : collection.params.page) !== null && _c !== void 0 ? _c : { limit } }));
25445
- runQuery(query, ({ data: result, error, loading, nextPage: page }) => {
25446
- const data = {
25447
- loading,
25448
- error,
25449
- params: { page },
25450
- data: channelMembers,
25451
- };
25452
- if (result) {
25453
- data.data = [...new Set([...channelMembers, ...result.map(getResolver('channelUsers'))])];
25454
- }
25455
- pushToCache(cacheKey, data);
25456
- responder(data);
25457
- }, queryOptions(policy));
25458
- };
25459
- disposers.push(onChannelMemberAdded((_, member) => realtimeRouter(member, 'onMemberAdded')), onChannelMemberRemoved((_, member) => realtimeRouter(member, 'onMemberRemoved')), onChannelMemberBanned((_, member) => realtimeRouter(member, 'onChannelMemberBanned')), onChannelMemberUnbanned((_, member) => realtimeRouter(member, 'onChannelMemberUnbanned')));
25460
- onFetch();
25461
- return () => {
25462
- log(`liveChannelMembers(tmpid: ${timestamp}) > dispose`);
25463
- disposers.forEach(fn => fn());
25464
- };
26495
+ else {
26496
+ upsertInCache(['subChannel', 'get', subChannelId], deleted);
26497
+ }
26498
+ fireEvent('local.message-feed.deleted', { messageFeeds: [deleted] });
26499
+ return deleted;
25465
26500
  };
25466
26501
 
25467
26502
  /**
25468
26503
  * ```js
25469
- * import { onMessageCreated } from '@amityco/ts-sdk'
25470
- * const dispose = onMessageCreated(message => {
26504
+ * import { onChannelSubCreated } from '@amityco/ts-sdk'
26505
+ * const dispose = onSubChannelCreated(subChannel => {
25471
26506
  * // ...
25472
26507
  * })
25473
26508
  * ```
25474
26509
  *
25475
- * Fired when an {@link Amity.Message} has been created
26510
+ * Fired when any {@link Amity.SubChannel} have been created
25476
26511
  *
25477
26512
  * @param callback The function to call when the event was fired
25478
26513
  * @returns an {@link Amity.Unsubscriber} function to stop listening
25479
26514
  *
25480
- * @category Message Events
26515
+ * @category Channel Events
25481
26516
  */
25482
- const onMessageCreated = (callback) => {
26517
+ const onSubChannelCreated = (callback) => {
25483
26518
  const client = getActiveClient();
25484
- const filter = (payload) => {
26519
+ const filter = (rawPayload) => {
26520
+ const payload = prepareSubChannelPayload(rawPayload);
25485
26521
  ingestInCache(payload);
25486
- callback(payload.messages[0]);
26522
+ callback(payload.messageFeeds[0]);
25487
26523
  };
25488
- return createEventSubscriber(client, 'message/onMessageCreated', 'v3.message.didCreate', filter);
26524
+ return createEventSubscriber(client, 'onSubChannelCreated', 'message-feed.created', filter);
25489
26525
  };
25490
26526
 
25491
26527
  /**
25492
26528
  * ```js
25493
- * import { onMessageUpdated } from '@amityco/ts-sdk'
25494
- * const dispose = onMessageUpdated(message => {
26529
+ * import { onSubChannelUpdated } from '@amityco/ts-sdk'
26530
+ * const dispose = onSubChannelUpdated(subChannel => {
25495
26531
  * // ...
25496
26532
  * })
25497
26533
  * ```
25498
26534
  *
25499
- * Fired when an {@link Amity.Message} has been updated
26535
+ * Fired when any {@link Amity.SubChannel} have been updated
25500
26536
  *
25501
26537
  * @param callback The function to call when the event was fired
25502
26538
  * @returns an {@link Amity.Unsubscriber} function to stop listening
25503
26539
  *
25504
- * @category Message Events
26540
+ * @category Channel Events
25505
26541
  */
25506
- const onMessageUpdated = (callback) => {
26542
+ const onSubChannelUpdated = (callback) => {
25507
26543
  const client = getActiveClient();
25508
- const filter = (payload) => {
26544
+ const filter = (rawPayload) => {
26545
+ const payload = prepareSubChannelPayload(rawPayload);
25509
26546
  ingestInCache(payload);
25510
- const message = payload.messages[0];
25511
- // if payload does not have myReactions
25512
- if (!(message === null || message === void 0 ? void 0 : message.myReactions)) {
25513
- prepareMessagePayloadForCache(message);
25514
- }
25515
- callback(message);
26547
+ callback(payload.messageFeeds[0]);
25516
26548
  };
25517
- return createEventSubscriber(client, 'message/onMessageUpdated', 'v3.message.didUpdate', filter);
26549
+ return createEventSubscriber(client, 'onSubChannelUpdated', 'message-feed.updated', filter);
25518
26550
  };
25519
26551
 
25520
26552
  /**
25521
26553
  * ```js
25522
- * import { onMessageDeleted } from '@amityco/ts-sdk'
25523
- * const dispose = onMessageDeleted(message => {
26554
+ * import { onSubChannelDeleted } from '@amityco/ts-sdk'
26555
+ * const dispose = onSubChannelDeleted(subChannel => {
25524
26556
  * // ...
25525
26557
  * })
25526
26558
  * ```
25527
26559
  *
25528
- * Fired when an {@link Amity.Message} was deleted
26560
+ * Fired when any {@link Amity.SubChannel} have been deleted
25529
26561
  *
25530
26562
  * @param callback The function to call when the event was fired
25531
26563
  * @returns an {@link Amity.Unsubscriber} function to stop listening
25532
26564
  *
25533
- * @category Message Events
26565
+ * @category Channel Events
25534
26566
  */
25535
- const onMessageDeleted = (callback) => {
26567
+ const onSubChannelDeleted = (callback) => {
25536
26568
  const client = getActiveClient();
25537
- const filter = (payload) => {
26569
+ const filter = (rawPayload) => {
26570
+ const payload = prepareSubChannelPayload(rawPayload);
25538
26571
  ingestInCache(payload);
25539
- callback(payload.messages[0]);
26572
+ callback(payload.messageFeeds[0]);
26573
+ };
26574
+ const disposers = [
26575
+ createEventSubscriber(client, 'onSubChannelDeleted', 'message-feed.deleted', filter),
26576
+ createEventSubscriber(client, 'local.message-feed.deleted', 'local.message-feed.deleted', payload => callback(payload.messageFeeds[0])),
26577
+ ];
26578
+ return () => {
26579
+ disposers.forEach(fn => fn());
26580
+ };
26581
+ };
26582
+
26583
+ /** @hidden */
26584
+ const onSubChannelFetched = (callback) => {
26585
+ return createEventSubscriber(getActiveClient(), 'onSubChannelFetched', 'local.message-feed.fetched', payload => callback(payload.messageFeeds[0]));
26586
+ };
26587
+
26588
+ /**
26589
+ * ```js
26590
+ * import { liveSubChannel } from '@amityco/ts-sdk';
26591
+ *
26592
+ * let subChannel;
26593
+ *
26594
+ * const unsubscribe = liveSubChannel(subChannelId, response => {
26595
+ * subChannel = response.data;
26596
+ * });
26597
+ * ```
26598
+ *
26599
+ * Observe all mutation on a given {@link Amity.SubChannel}
26600
+ *
26601
+ * @param subChannelId the ID of the message to observe
26602
+ * @param callback the function to call when new data are available
26603
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the sub channel
26604
+ *
26605
+ * @category SubChannel Live Object
26606
+ */
26607
+ const liveSubChannel = (subChannelId, callback) => {
26608
+ const { log, cache } = getActiveClient();
26609
+ const timestamp = Date.now();
26610
+ log(`liveSubChannel(tmpid: ${timestamp}) > listen`);
26611
+ if (!cache) {
26612
+ console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
26613
+ }
26614
+ let subChannel;
26615
+ const disposers = [];
26616
+ const dispatcher = (data) => {
26617
+ subChannel = data.data;
26618
+ callback(data);
26619
+ };
26620
+ const realtimeRouter = (eventSubChannel) => {
26621
+ if (subChannelId !== eventSubChannel.subChannelId) {
26622
+ return;
26623
+ }
26624
+ if (subChannel && !hasUpdates(subChannel, eventSubChannel)) {
26625
+ return;
26626
+ }
26627
+ dispatcher({ loading: false, data: eventSubChannel, origin: 'event' });
26628
+ };
26629
+ const onFetch = () => {
26630
+ const query = createQuery(getSubChannel, subChannelId);
26631
+ runQuery(query, ({ error, data, loading, origin }) => {
26632
+ dispatcher({ error, data, loading, origin });
26633
+ if (error) {
26634
+ disposers.forEach(fn => fn());
26635
+ }
26636
+ });
26637
+ };
26638
+ disposers.push(onSubChannelFetched(realtimeRouter), onSubChannelUpdated(realtimeRouter), onSubChannelDeleted(realtimeRouter));
26639
+ onFetch();
26640
+ return () => {
26641
+ log(`liveSubChannel(tmpid: ${timestamp}) > dispose`);
26642
+ disposers.forEach(fn => fn());
26643
+ };
26644
+ };
26645
+
26646
+ /**
26647
+ * ```js
26648
+ * import { liveSubChannels } from '@amityco/ts-sdk';
26649
+ *
26650
+ * let subChannels = [];
26651
+ *
26652
+ * const unsubscribe = liveSubChannels({ channelId }, response => {
26653
+ * merge(subChannels, response.data);
26654
+ * });
26655
+ * ```
26656
+ *
26657
+ * Observe all mutations on a list of {@link Amity.SubChannel}s
26658
+ *
26659
+ * @param params for querying sub channels
26660
+ * @param callback the function to call when new data are available
26661
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the sub channels
26662
+ *
26663
+ * @category SubChannel Live Collection
26664
+ */
26665
+ const liveSubChannels = (params, callback, config) => {
26666
+ const { log, cache } = getActiveClient();
26667
+ const timestamp = Date.now();
26668
+ log(`liveSubChannels(tmpid: ${timestamp}) > listen`);
26669
+ if (!cache) {
26670
+ console.log(ENABLE_CACHE_MESSAGE);
26671
+ }
26672
+ const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT } = params, queryParams = __rest(params, ["limit"]);
26673
+ const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config !== null && config !== void 0 ? config : {};
26674
+ let snapshot;
26675
+ const disposers = [];
26676
+ const responder = (data) => {
26677
+ var _a;
26678
+ let subChannels = data.data;
26679
+ if (params.isDeleted !== undefined) {
26680
+ subChannels = filterByPropEquality(subChannels, 'isDeleted', params.isDeleted);
26681
+ }
26682
+ subChannels.sort(sortByLastActivity);
26683
+ callback({
26684
+ onNextPage: onFetch,
26685
+ data: subChannels,
26686
+ hasNextPage: !!((_a = data.params) === null || _a === void 0 ? void 0 : _a.page),
26687
+ loading: data.loading,
26688
+ error: data.error,
26689
+ });
26690
+ };
26691
+ const realtimeRouter = (action) => (subChannel) => {
26692
+ if (params.channelId !== subChannel.channelId ||
26693
+ !snapshot ||
26694
+ !isCollectionOutdated(snapshot.data, subChannel, action)) {
26695
+ return;
26696
+ }
26697
+ if (action === 'onCreate') {
26698
+ snapshot.data = [subChannel, ...snapshot.data];
26699
+ }
26700
+ else {
26701
+ snapshot.data = snapshot.data.map(x => x.subChannelId === subChannel.subChannelId ? subChannel : x);
26702
+ }
26703
+ responder(snapshot);
26704
+ };
26705
+ const onFetch = () => {
26706
+ var _a;
26707
+ const subChannels = snapshot ? snapshot.data : [];
26708
+ if (subChannels.length > 0 && !(snapshot === null || snapshot === void 0 ? void 0 : snapshot.params.page)) {
26709
+ return;
26710
+ }
26711
+ const query = createQuery(querySubChannels, Object.assign(Object.assign({}, queryParams), { page: (_a = snapshot === null || snapshot === void 0 ? void 0 : snapshot.params.page) !== null && _a !== void 0 ? _a : { limit } }));
26712
+ runQuery(query, ({ data: result, error, loading, nextPage: page }) => {
26713
+ snapshot = {
26714
+ loading,
26715
+ error,
26716
+ params: { page },
26717
+ data: result ? merge(subChannels, result) : subChannels,
26718
+ };
26719
+ responder(snapshot);
26720
+ }, queryOptions(policy));
26721
+ };
26722
+ disposers.push(onSubChannelCreated(realtimeRouter('onCreate')), onSubChannelDeleted(realtimeRouter('onDelete')), onSubChannelFetched(realtimeRouter('onFetch')), onSubChannelUpdated(realtimeRouter('onUpdate')));
26723
+ onFetch();
26724
+ return () => {
26725
+ log(`liveSubChannels(tmpid: ${timestamp}) > dispose`);
26726
+ disposers.forEach(fn => fn());
25540
26727
  };
25541
- return createEventSubscriber(client, 'message/onMessageDeleted', 'v3.message.didDelete', filter);
25542
26728
  };
25543
26729
 
25544
26730
  /**
@@ -25562,46 +26748,50 @@ const onMessageFetched = (callback) => {
25562
26748
  ingestInCache(payload);
25563
26749
  callback(payload.messages[0]);
25564
26750
  };
25565
- return createEventSubscriber(client, 'message/onMessageFetched', 'v3.message.didFetch', filter);
26751
+ return createEventSubscriber(client, 'message/onMessageFetched', 'local.message.fetched', filter);
25566
26752
  };
25567
26753
 
25568
26754
  /**
25569
26755
  * ```js
25570
- * import { liveMessage } from '@amityco/ts-sdk'
26756
+ * import { liveMessage } from '@amityco/ts-sdk';
25571
26757
  *
25572
- * let messages = []
25573
- * const unsub = liveMessage(messageId, response => merge(messages, response.data))
26758
+ * let message;
26759
+ *
26760
+ * const unsubscribe = liveMessage(messageId, response => {
26761
+ * message = response.data;
26762
+ * });
25574
26763
  * ```
25575
26764
  *
25576
26765
  * Observe all mutation on a given {@link Amity.Message}
25577
26766
  *
25578
26767
  * @param messageId the ID of the message to observe
25579
26768
  * @param callback the function to call when new data are available
25580
- * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the messages
26769
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the message
25581
26770
  *
25582
26771
  * @category Message Live Object
25583
26772
  */
25584
26773
  const liveMessage = (messageId, callback) => {
25585
26774
  const { log, cache } = getActiveClient();
25586
- let message;
25587
- let isUnsyncedObject = false;
26775
+ const timestamp = Date.now();
26776
+ log(`liveMessage(tmpid: ${timestamp}) > listen`);
25588
26777
  if (!cache) {
25589
26778
  console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
25590
26779
  }
25591
- const timestamp = Date.now();
25592
- log(`liveMessage(tmpid: ${timestamp}) > listen`);
26780
+ let message;
26781
+ let isUnsyncedObject = false;
25593
26782
  const disposers = [];
25594
26783
  const dispatcher = (data) => {
25595
- var _a;
25596
- // we check updatedAt to see if the current snapshot is new so
25597
- // we won't send old data back, only fresh new data
25598
- if (message && ((_a = data.data) === null || _a === void 0 ? void 0 : _a.updatedAt) === (message === null || message === void 0 ? void 0 : message.updatedAt) && data.origin !== 'server')
25599
- return;
25600
- callback(data);
25601
26784
  message = data.data;
26785
+ callback(data);
25602
26786
  };
25603
- const realtimeRouter = (message, action) => {
25604
- dispatcher({ loading: false, data: message, origin: 'event' });
26787
+ const realtimeRouter = (eventMessage) => {
26788
+ if (messageId !== eventMessage.messageId) {
26789
+ return;
26790
+ }
26791
+ if (message && !hasUpdates(message, eventMessage)) {
26792
+ return;
26793
+ }
26794
+ dispatcher({ loading: false, data: eventMessage, origin: 'event' });
25605
26795
  };
25606
26796
  const onFetch = () => {
25607
26797
  const query = createQuery(getMessage, messageId, true);
@@ -25620,12 +26810,11 @@ const liveMessage = (messageId, callback) => {
25620
26810
  dispatcher({ loading, data, origin, error });
25621
26811
  }
25622
26812
  if (error) {
25623
- // Terminate observe functionality on error
25624
26813
  disposers.forEach(fn => fn());
25625
26814
  }
25626
26815
  });
25627
26816
  };
25628
- disposers.push(onMessageFetched(message => realtimeRouter(message)), onMessageUpdated(message => realtimeRouter(message)), onMessageDeleted(message => realtimeRouter(message)));
26817
+ disposers.push(onMessageFetched(realtimeRouter), onMessageUpdated(realtimeRouter), onMessageDeleted(realtimeRouter), onMessageFlagged(realtimeRouter), onMessageUnflagged(realtimeRouter), onMessageFlagCleared(realtimeRouter), onMessageReactionAdded(realtimeRouter), onMessageReactionRemoved(realtimeRouter));
25629
26818
  onFetch();
25630
26819
  return () => {
25631
26820
  log(`liveMessage(tmpid: ${timestamp}) > dispose`);
@@ -25635,17 +26824,18 @@ const liveMessage = (messageId, callback) => {
25635
26824
 
25636
26825
  /**
25637
26826
  * ```js
25638
- * import { liveMessages } from '@amityco/ts-sdk'
26827
+ * import { liveMessages } from '@amityco/ts-sdk';
25639
26828
  *
25640
- * let messages = []
25641
- * const unsub = liveMessages({
25642
- * channelId: Amity.Channel['channelId'];
25643
- * }, response => merge(messages, response.data))
26829
+ * let messages = [];
26830
+ *
26831
+ * const unsubscribe = liveMessages({
26832
+ * subChannelId: Amity.SubChannel['subChannelId'];
26833
+ * }, response => merge(messages, response.data));
25644
26834
  * ```
25645
26835
  *
25646
26836
  * Observe all mutations on a list of {@link Amity.Message} for a given target object
25647
26837
  *
25648
- * @param params for querying memssages from a channel
26838
+ * @param params for querying messages from a sub channel
25649
26839
  * @param callback the function to call when new data are available
25650
26840
  * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the messages
25651
26841
  *
@@ -25662,7 +26852,7 @@ const liveMessages = (params, callback, config) => {
25662
26852
  const limit = queryLimit !== null && queryLimit !== void 0 ? queryLimit : COLLECTION_DEFAULT_PAGINATION_LIMIT;
25663
26853
  const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config !== null && config !== void 0 ? config : {};
25664
26854
  const disposers = [];
25665
- const cacheKey = ['message', 'collection', { channelId: params.channelId }];
26855
+ const cacheKey = ['message', 'collection', { subChannelId: params.subChannelId }];
25666
26856
  const responder = (data) => {
25667
26857
  var _a, _b;
25668
26858
  let messages = (_a = data.data
@@ -25682,10 +26872,10 @@ const liveMessages = (params, callback, config) => {
25682
26872
  error: data.error,
25683
26873
  });
25684
26874
  };
25685
- const realtimeRouter = (message, action) => {
26875
+ const realtimeRouter = (action) => (message) => {
25686
26876
  var _a;
25687
26877
  const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
25688
- if (params.channelId !== message.channelId || !collection)
26878
+ if (params.subChannelId !== message.subChannelId || !collection)
25689
26879
  return;
25690
26880
  if (action === 'onCreate') {
25691
26881
  collection.data = [...new Set([message.messageId, ...collection.data])];
@@ -25717,7 +26907,7 @@ const liveMessages = (params, callback, config) => {
25717
26907
  responder(data);
25718
26908
  }, queryOptions(policy));
25719
26909
  };
25720
- disposers.push(onMessageFetched(message => realtimeRouter(message, 'onFetch')), onMessageCreated(message => realtimeRouter(message, 'onCreate')), onMessageDeleted(message => realtimeRouter(message, 'onDelete')), onMessageUpdated(message => realtimeRouter(message, 'onUpdate')));
26910
+ disposers.push(onMessageFetched(realtimeRouter('onFetch')), onMessageCreated(realtimeRouter('onCreate')), onMessageUpdated(realtimeRouter('onUpdate')), onMessageDeleted(realtimeRouter('onDelete')), onMessageFlagged(realtimeRouter('onFlagged')), onMessageUnflagged(realtimeRouter('onUnflagged')), onMessageFlagCleared(realtimeRouter('onFlagCleared')), onMessageReactionAdded(realtimeRouter('onReactionAdded')), onMessageReactionRemoved(realtimeRouter('onReactionRemoved')));
25721
26911
  onFetch();
25722
26912
  return () => {
25723
26913
  log(`liveMessages(tmpid: ${timestamp}) > dispose`);
@@ -25730,6 +26920,7 @@ const liveMessages = (params, callback, config) => {
25730
26920
  * import { observeMessage } from '@amityco/ts-sdk'
25731
26921
  *
25732
26922
  * let message = {}
26923
+ *
25733
26924
  * const unsub = observeMessage(messageId, updated => message = updated)
25734
26925
  * ```
25735
26926
  *
@@ -25776,25 +26967,26 @@ const observeMessage = (messageId, callback, policy = 'cache_then_server') => {
25776
26967
  * import { observeMessages } from '@amityco/ts-sdk'
25777
26968
  *
25778
26969
  * let messages = []
25779
- * const unsub = observeMessages(channelId, message => merge(messages, message))
26970
+ *
26971
+ * const unsubscribe = observeMessages(channelId, message => merge(messages, message))
25780
26972
  * ```
25781
26973
  *
25782
- * Observe all mutations on a list of {@link Amity.Message} for a given {@link Amity.Channel} object
26974
+ * Observe all mutations on a list of {@link Amity.Message} for a given {@link Amity.SubChannel} object
25783
26975
  *
25784
- * @param channelId the ID of the channel where to observe the messages
26976
+ * @param subChannelId the ID of the channel where to observe the messages
25785
26977
  * @param callback the function to call when new data are available
25786
26978
  * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the messages
25787
26979
  *
25788
26980
  * @category Message Observer
25789
26981
  */
25790
- const observeMessages = (channelId, callback) => {
26982
+ const observeMessages = (subChannelId, callback) => {
25791
26983
  const { log } = getActiveClient();
25792
26984
  const timestamp = Date.now();
25793
26985
  log(`observeMessages(tmpid: ${timestamp}) > listen`);
25794
26986
  const disposers = [];
25795
26987
  const router = (message, action) => {
25796
26988
  var _a, _b, _c;
25797
- if (((_a = message.data) === null || _a === void 0 ? void 0 : _a.channelId) !== channelId)
26989
+ if (((_a = message.data) === null || _a === void 0 ? void 0 : _a.subChannelId) !== subChannelId)
25798
26990
  return;
25799
26991
  if (callback instanceof Function)
25800
26992
  return callback(message);
@@ -25857,22 +27049,23 @@ function getEventRelatedMember(event, payload) {
25857
27049
  const createCommunityMemberEventSubscriber = (event, callback) => {
25858
27050
  const client = getActiveClient();
25859
27051
  const filter = (payload) => {
25860
- const unpackedPayload = unpackCommunityPayload(payload);
27052
+ const communityPayload = unpackCommunityPayload(payload);
27053
+ const preparedPayload = prepareMembershipPayload(communityPayload, 'communityUsers');
25861
27054
  if (!client.cache) {
25862
27055
  // TODO: here we are missing specific properties here!
25863
- callback(unpackedPayload.communities[0], getEventRelatedMember(event, unpackedPayload));
27056
+ callback(preparedPayload.communities[0], getEventRelatedMember(event, preparedPayload));
25864
27057
  }
25865
27058
  else {
25866
- ingestInCache(unpackedPayload);
27059
+ ingestInCache(preparedPayload);
25867
27060
  const community = pullFromCache([
25868
27061
  'community',
25869
27062
  'get',
25870
- unpackedPayload.communities[0].communityId,
27063
+ preparedPayload.communities[0].communityId,
25871
27064
  ]);
25872
27065
  const member = pullFromCache([
25873
27066
  'communityUsers',
25874
27067
  'get',
25875
- getResolver('communityUsers')(getEventRelatedMember(event, unpackedPayload)),
27068
+ getResolver('communityUsers')(getEventRelatedMember(event, preparedPayload)),
25876
27069
  ]);
25877
27070
  callback(community.data, member.data);
25878
27071
  }
@@ -26911,7 +28104,7 @@ const liveFollowers = (params, callback, config) => {
26911
28104
  error: data.error,
26912
28105
  });
26913
28106
  };
26914
- const realtimeRouter = (followStatus, action) => {
28107
+ const realtimeRouter = (action) => (followStatus) => {
26915
28108
  var _a;
26916
28109
  const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
26917
28110
  if (params.userId !== followStatus.to || !collection)
@@ -26946,7 +28139,7 @@ const liveFollowers = (params, callback, config) => {
26946
28139
  responder(data);
26947
28140
  }, queryOptions(policy));
26948
28141
  };
26949
- disposers.push(onFollowerRequested(followStatus => realtimeRouter(followStatus, 'onRequested')), onFollowRequestAccepted(followStatus => realtimeRouter(followStatus, 'onAccepted')), onFollowRequestDeclined(followStatus => realtimeRouter(followStatus, 'onDeclined')), onFollowRequestCanceled(followStatus => realtimeRouter(followStatus, 'onCanceled')), onUserFollowed(followStatus => realtimeRouter(followStatus, 'onFollowed')), onUserUnfollowed(followStatus => realtimeRouter(followStatus, 'onUnfollowed')), onFollowerDeleted(followStatus => realtimeRouter(followStatus, 'onDeleted')));
28142
+ disposers.push(onFollowerRequested(realtimeRouter('onRequested')), onFollowRequestAccepted(realtimeRouter('onAccepted')), onFollowRequestDeclined(realtimeRouter('onDeclined')), onFollowRequestCanceled(realtimeRouter('onCanceled')), onUserFollowed(realtimeRouter('onFollowed')), onUserUnfollowed(realtimeRouter('onUnfollowed')), onFollowerDeleted(realtimeRouter('onDeleted')));
26950
28143
  onFetch();
26951
28144
  return () => {
26952
28145
  log(`liveFollowers(tmpid: ${timestamp}) > dispose`);
@@ -27001,7 +28194,7 @@ const liveFollowings = (params, callback, config) => {
27001
28194
  error: data.error,
27002
28195
  });
27003
28196
  };
27004
- const realtimeRouter = (followStatus, action) => {
28197
+ const realtimeRouter = (action) => (followStatus) => {
27005
28198
  var _a;
27006
28199
  const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
27007
28200
  if (params.userId !== followStatus.from || !collection)
@@ -27036,7 +28229,7 @@ const liveFollowings = (params, callback, config) => {
27036
28229
  responder(data);
27037
28230
  }, queryOptions(policy));
27038
28231
  };
27039
- disposers.push(onFollowerRequested(followStatus => realtimeRouter(followStatus, 'onRequested')), onFollowRequestAccepted(followStatus => realtimeRouter(followStatus, 'onAccepted')), onFollowRequestDeclined(followStatus => realtimeRouter(followStatus, 'onDeclined')), onFollowRequestCanceled(followStatus => realtimeRouter(followStatus, 'onCanceled')), onUserFollowed(followStatus => realtimeRouter(followStatus, 'onFollowed')), onUserUnfollowed(followStatus => realtimeRouter(followStatus, 'onUnfollowed')), onFollowerDeleted(followStatus => realtimeRouter(followStatus, 'onDeleted')));
28232
+ disposers.push(onFollowerRequested(realtimeRouter('onRequested')), onFollowRequestAccepted(realtimeRouter('onAccepted')), onFollowRequestDeclined(realtimeRouter('onDeclined')), onFollowRequestCanceled(realtimeRouter('onCanceled')), onUserFollowed(realtimeRouter('onFollowed')), onUserUnfollowed(realtimeRouter('onUnfollowed')), onFollowerDeleted(realtimeRouter('onDeleted')));
27040
28233
  onFetch();
27041
28234
  return () => {
27042
28235
  log(`liveFollowings(tmpid: ${timestamp}) > dispose`);
@@ -27174,6 +28367,9 @@ const livePosts = (params, callback, config) => {
27174
28367
  posts = filterByPropEquality(posts, 'isDeleted', params.isDeleted);
27175
28368
  const sortBy = params.sortBy ? params.sortBy : 'lastCreated';
27176
28369
  posts = posts.sort(sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated);
28370
+ if (params.tags) {
28371
+ posts = posts.filter(p => { var _a; return (_a = p.tags) === null || _a === void 0 ? void 0 : _a.some(t => { var _a; return (_a = params.tags) === null || _a === void 0 ? void 0 : _a.includes(t); }); });
28372
+ }
27177
28373
  callback({
27178
28374
  onNextPage: onFetch,
27179
28375
  data: posts,
@@ -27182,17 +28378,32 @@ const livePosts = (params, callback, config) => {
27182
28378
  error: data.error,
27183
28379
  });
27184
28380
  };
27185
- const realtimeRouter = (post, action) => {
28381
+ const realtimeRouter = (action) => (post) => {
27186
28382
  var _a;
27187
28383
  const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
27188
28384
  if (params.targetId !== post.targetId || params.targetType !== post.targetType || !collection)
27189
28385
  return;
27190
- if (action === 'onCreate') {
28386
+ if (['onCreate', 'onApproved'].includes(action)) {
27191
28387
  collection.data = [...new Set([post.postId, ...collection.data])];
27192
28388
  }
27193
28389
  else if (['onDelete', 'onDeclined'].includes(action)) {
27194
28390
  collection.data = collection.data.filter(p => p !== post.postId);
28391
+ /*
28392
+ * if isDeleted is true, collection should add deleted items to the
28393
+ * begining of the collection
28394
+ */
28395
+ if (params.isDeleted)
28396
+ collection.data.unshift(post.postId);
27195
28397
  }
28398
+ /*
28399
+ * FIX-ME
28400
+ * This is a shortcoming as the feed object is not saved to the cache.
28401
+ * The responder should pull the feed from cache once available and should
28402
+ * match the collection to feedType param
28403
+ * https://ekoapp.atlassian.net/browse/ASC-9382
28404
+ */
28405
+ if (params.feedType === 'reviewing' && action === 'onApproved')
28406
+ collection.data = collection.data.filter(p => p !== post.postId);
27196
28407
  pushToCache(cacheKey, collection);
27197
28408
  responder(collection);
27198
28409
  };
@@ -27217,7 +28428,7 @@ const livePosts = (params, callback, config) => {
27217
28428
  responder(data);
27218
28429
  }, queryOptions(policy));
27219
28430
  };
27220
- disposers.push(onPostCreated(post => realtimeRouter(post, 'onCreate')), onPostApproved(post => realtimeRouter(post, 'onApproved')), onPostDeclined(post => realtimeRouter(post, 'onDeclined')), onPostDeleted(post => realtimeRouter(post, 'onDelete')), onPostUpdated(post => realtimeRouter(post, 'onUpdate')), onPostFlagged(post => realtimeRouter(post, 'onFlagged')), onPostUnflagged(post => realtimeRouter(post, 'onUnflagged')), onPostReactionAdded(post => realtimeRouter(post, 'onReactionAdded')), onPostReactionRemoved(post => realtimeRouter(post, 'onReactionRemoved')));
28431
+ disposers.push(onPostCreated(realtimeRouter('onCreate')), onPostApproved(realtimeRouter('onApproved')), onPostDeclined(realtimeRouter('onDeclined')), onPostDeleted(realtimeRouter('onDelete')), onPostUpdated(realtimeRouter('onUpdate')), onPostFlagged(realtimeRouter('onFlagged')), onPostUnflagged(realtimeRouter('onUnflagged')), onPostReactionAdded(realtimeRouter('onReactionAdded')), onPostReactionRemoved(realtimeRouter('onReactionRemoved')));
27221
28432
  onFetch();
27222
28433
  return () => {
27223
28434
  log(`livePosts(tmpid: ${timestamp}) > dispose`);
@@ -27359,7 +28570,7 @@ const liveComments = (params, callback, config) => {
27359
28570
  error: data.error,
27360
28571
  });
27361
28572
  };
27362
- const realtimeRouter = (comment, action) => {
28573
+ const realtimeRouter = (action) => (comment) => {
27363
28574
  var _a;
27364
28575
  const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
27365
28576
  if (params.referenceId !== comment.referenceId ||
@@ -27398,7 +28609,7 @@ const liveComments = (params, callback, config) => {
27398
28609
  responder(data);
27399
28610
  }, queryOptions(policy));
27400
28611
  };
27401
- disposers.push(onCommentCreated(comment => realtimeRouter(comment, 'onCreate')), onCommentUpdated(comment => realtimeRouter(comment, 'onUpdate')), onCommentDeleted(comment => realtimeRouter(comment, 'onDelete')), onCommentFlagged(comment => realtimeRouter(comment, 'onFlagged')), onCommentUnflagged(comment => realtimeRouter(comment, 'onUnflagged')), onCommentReactionAdded(comment => realtimeRouter(comment, 'onReactionAdded')), onCommentReactionRemoved(comment => realtimeRouter(comment, 'onReactionRemoved')));
28612
+ disposers.push(onCommentCreated(realtimeRouter('onCreate')), onCommentUpdated(realtimeRouter('onUpdate')), onCommentDeleted(realtimeRouter('onDelete')), onCommentFlagged(realtimeRouter('onFlagged')), onCommentUnflagged(realtimeRouter('onUnflagged')), onCommentReactionAdded(realtimeRouter('onReactionAdded')), onCommentReactionRemoved(realtimeRouter('onReactionRemoved')));
27402
28613
  onFetch();
27403
28614
  return () => {
27404
28615
  log(`liveComments(tmpid: ${timestamp}) > dispose`);
@@ -28025,6 +29236,7 @@ exports.createPost = createPost;
28025
29236
  exports.createQuery = createQuery;
28026
29237
  exports.createReport = createReport;
28027
29238
  exports.createStream = createStream;
29239
+ exports.createSubChannel = createSubChannel;
28028
29240
  exports.createUserToken = createUserToken;
28029
29241
  exports.createVideo = createVideo;
28030
29242
  exports.declineFollower = declineFollower;
@@ -28038,6 +29250,7 @@ exports.deletePoll = deletePoll;
28038
29250
  exports.deletePost = deletePost;
28039
29251
  exports.deleteReport = deleteReport;
28040
29252
  exports.deleteStream = deleteStream;
29253
+ exports.deleteSubChannel = deleteSubChannel;
28041
29254
  exports.disableCache = disableCache;
28042
29255
  exports.disconnectClient = disconnectClient;
28043
29256
  exports.disposeStream = disposeStream;
@@ -28051,6 +29264,7 @@ exports.follow = follow;
28051
29264
  exports.getActiveClient = getActiveClient;
28052
29265
  exports.getCategory = getCategory;
28053
29266
  exports.getChannel = getChannel;
29267
+ exports.getChannelTopic = getChannelTopic;
28054
29268
  exports.getChannels = getChannels;
28055
29269
  exports.getComment = getComment;
28056
29270
  exports.getCommentTopic = getCommentTopic;
@@ -28062,6 +29276,7 @@ exports.getFeedSettings = getFeedSettings;
28062
29276
  exports.getFile = getFile;
28063
29277
  exports.getFollowInfo = getFollowInfo;
28064
29278
  exports.getMessage = getMessage;
29279
+ exports.getMessageTopic = getMessageTopic;
28065
29280
  exports.getMessages = getMessages;
28066
29281
  exports.getMyFollowersTopic = getMyFollowersTopic;
28067
29282
  exports.getMyFollowingsTopic = getMyFollowingsTopic;
@@ -28072,7 +29287,13 @@ exports.getPostTopic = getPostTopic;
28072
29287
  exports.getPosts = getPosts;
28073
29288
  exports.getRecommendedCommunities = getRecommendedCommunities;
28074
29289
  exports.getRole = getRole;
29290
+ exports.getSmartFeedChannelTopic = getSmartFeedChannelTopic;
29291
+ exports.getSmartFeedMessageTopic = getSmartFeedMessageTopic;
29292
+ exports.getSmartFeedSubChannelTopic = getSmartFeedSubChannelTopic;
28075
29293
  exports.getStream = getStream;
29294
+ exports.getSubChannel = getSubChannel;
29295
+ exports.getSubChannelTopic = getSubChannelTopic;
29296
+ exports.getSubChannels = getSubChannels;
28076
29297
  exports.getTopTrendingCommunities = getTopTrendingCommunities;
28077
29298
  exports.getUser = getUser;
28078
29299
  exports.getUserTopic = getUserTopic;
@@ -28093,6 +29314,7 @@ exports.joinChannel = joinChannel;
28093
29314
  exports.joinCommunity = joinCommunity;
28094
29315
  exports.leaveChannel = leaveChannel;
28095
29316
  exports.leaveCommunity = leaveCommunity;
29317
+ exports.liveChannel = liveChannel;
28096
29318
  exports.liveChannelMembers = liveChannelMembers;
28097
29319
  exports.liveChannels = liveChannels;
28098
29320
  exports.liveComments = liveComments;
@@ -28102,6 +29324,8 @@ exports.liveMessage = liveMessage;
28102
29324
  exports.liveMessages = liveMessages;
28103
29325
  exports.livePosts = livePosts;
28104
29326
  exports.liveReactions = liveReactions;
29327
+ exports.liveSubChannel = liveSubChannel;
29328
+ exports.liveSubChannels = liveSubChannels;
28105
29329
  exports.liveUser = liveUser;
28106
29330
  exports.mergeInCache = mergeInCache;
28107
29331
  exports.observeChannel = observeChannel;
@@ -28127,6 +29351,7 @@ exports.onChannelMemberAdded = onChannelMemberAdded;
28127
29351
  exports.onChannelMemberBanned = onChannelMemberBanned;
28128
29352
  exports.onChannelMemberRemoved = onChannelMemberRemoved;
28129
29353
  exports.onChannelMemberUnbanned = onChannelMemberUnbanned;
29354
+ exports.onChannelMuted = onChannelMuted;
28130
29355
  exports.onChannelUpdated = onChannelUpdated;
28131
29356
  exports.onClientBanned = onClientBanned;
28132
29357
  exports.onClientDisconnected = onClientDisconnected;
@@ -28155,7 +29380,11 @@ exports.onFollowerDeleted = onFollowerDeleted;
28155
29380
  exports.onFollowerRequested = onFollowerRequested;
28156
29381
  exports.onMessageCreated = onMessageCreated;
28157
29382
  exports.onMessageDeleted = onMessageDeleted;
28158
- exports.onMessageFetched = onMessageFetched;
29383
+ exports.onMessageFlagCleared = onMessageFlagCleared;
29384
+ exports.onMessageFlagged = onMessageFlagged;
29385
+ exports.onMessageReactionAdded = onMessageReactionAdded;
29386
+ exports.onMessageReactionRemoved = onMessageReactionRemoved;
29387
+ exports.onMessageUnflagged = onMessageUnflagged;
28159
29388
  exports.onMessageUpdated = onMessageUpdated;
28160
29389
  exports.onPollDeleted = onPollDeleted;
28161
29390
  exports.onPollUpdated = onPollUpdated;
@@ -28175,8 +29404,10 @@ exports.onReactorRemoved = onReactorRemoved;
28175
29404
  exports.onStreamRecorded = onStreamRecorded;
28176
29405
  exports.onStreamStarted = onStreamStarted;
28177
29406
  exports.onStreamStopped = onStreamStopped;
29407
+ exports.onSubChannelCreated = onSubChannelCreated;
29408
+ exports.onSubChannelDeleted = onSubChannelDeleted;
29409
+ exports.onSubChannelUpdated = onSubChannelUpdated;
28178
29410
  exports.onUserDeleted = onUserDeleted;
28179
- exports.onUserFetched = onUserFetched;
28180
29411
  exports.onUserFlagCleared = onUserFlagCleared;
28181
29412
  exports.onUserFlagged = onUserFlagged;
28182
29413
  exports.onUserFollowed = onUserFollowed;
@@ -28201,6 +29432,7 @@ exports.queryPosts = queryPosts;
28201
29432
  exports.queryReactions = queryReactions;
28202
29433
  exports.queryRoles = queryRoles;
28203
29434
  exports.queryStreams = queryStreams;
29435
+ exports.querySubChannels = querySubChannels;
28204
29436
  exports.queryUsers = queryUsers;
28205
29437
  exports.removeChannelMembers = removeChannelMembers;
28206
29438
  exports.removeChannelMembersRole = removeChannelMembersRole;
@@ -28215,6 +29447,8 @@ exports.sortByFirstCreated = sortByFirstCreated;
28215
29447
  exports.sortByLastActivity = sortByLastActivity;
28216
29448
  exports.sortByLastCreated = sortByLastCreated;
28217
29449
  exports.sortBySegmentNumber = sortBySegmentNumber;
29450
+ exports.startReading = startReading;
29451
+ exports.stopReading = stopReading;
28218
29452
  exports.subscribeTopic = subscribeTopic;
28219
29453
  exports.toPage = toPage;
28220
29454
  exports.toPageRaw = toPageRaw;
@@ -28227,6 +29461,7 @@ exports.updateCommunity = updateCommunity;
28227
29461
  exports.updateMessage = updateMessage;
28228
29462
  exports.updatePost = updatePost;
28229
29463
  exports.updateStream = updateStream;
29464
+ exports.updateSubChannel = updateSubChannel;
28230
29465
  exports.updateUser = updateUser;
28231
29466
  exports.upsertInCache = upsertInCache;
28232
29467
  exports.votePoll = votePoll;