@amityco/ts-sdk 0.0.1-bc64ebf.0 → 0.0.1-bd9dae9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (499) hide show
  1. package/.eslintrc.json +1 -0
  2. package/dist/@types/core/cache.d.ts +3 -0
  3. package/dist/@types/core/cache.d.ts.map +1 -1
  4. package/dist/@types/core/errors.d.ts +2 -1
  5. package/dist/@types/core/errors.d.ts.map +1 -1
  6. package/dist/@types/core/events.d.ts +3 -0
  7. package/dist/@types/core/events.d.ts.map +1 -1
  8. package/dist/@types/core/live.d.ts +8 -4
  9. package/dist/@types/core/live.d.ts.map +1 -1
  10. package/dist/@types/core/payload.d.ts +19 -17
  11. package/dist/@types/core/payload.d.ts.map +1 -1
  12. package/dist/@types/core/query.d.ts +1 -1
  13. package/dist/@types/core/query.d.ts.map +1 -1
  14. package/dist/@types/domains/channel.d.ts +29 -1
  15. package/dist/@types/domains/channel.d.ts.map +1 -1
  16. package/dist/@types/domains/client.d.ts +4 -0
  17. package/dist/@types/domains/client.d.ts.map +1 -1
  18. package/dist/@types/domains/community.d.ts +24 -2
  19. package/dist/@types/domains/community.d.ts.map +1 -1
  20. package/dist/@types/domains/content.d.ts +27 -3
  21. package/dist/@types/domains/content.d.ts.map +1 -1
  22. package/dist/@types/domains/file.d.ts +36 -3
  23. package/dist/@types/domains/file.d.ts.map +1 -1
  24. package/dist/@types/domains/follow.d.ts +11 -0
  25. package/dist/@types/domains/follow.d.ts.map +1 -1
  26. package/dist/@types/domains/group.d.ts +7 -2
  27. package/dist/@types/domains/group.d.ts.map +1 -1
  28. package/dist/@types/domains/message.d.ts +25 -5
  29. package/dist/@types/domains/message.d.ts.map +1 -1
  30. package/dist/@types/domains/post.d.ts +10 -3
  31. package/dist/@types/domains/post.d.ts.map +1 -1
  32. package/dist/@types/domains/user.d.ts +1 -0
  33. package/dist/@types/domains/user.d.ts.map +1 -1
  34. package/dist/@types/global.d.ts +1 -0
  35. package/dist/@types/global.d.ts.map +1 -1
  36. package/dist/@types/index.d.ts +5 -5
  37. package/dist/@types/index.d.ts.map +1 -1
  38. package/dist/cache/api/backupCache.d.ts.map +1 -1
  39. package/dist/cache/api/ingestInCache.d.ts +1 -1
  40. package/dist/cache/api/isInTombstone.d.ts +18 -0
  41. package/dist/cache/api/isInTombstone.d.ts.map +1 -0
  42. package/dist/cache/api/pushToTombstone.d.ts +17 -0
  43. package/dist/cache/api/pushToTombstone.d.ts.map +1 -0
  44. package/dist/cache/api/tests/dropFromCache.test.d.ts +2 -0
  45. package/dist/cache/api/tests/dropFromCache.test.d.ts.map +1 -0
  46. package/dist/cache/api/tests/ingestInCache.test.d.ts +2 -0
  47. package/dist/cache/api/tests/ingestInCache.test.d.ts.map +1 -0
  48. package/dist/cache/api/tests/pullFromCache.test.d.ts +2 -0
  49. package/dist/cache/api/tests/pullFromCache.test.d.ts.map +1 -0
  50. package/dist/cache/api/tests/pushToCache.test.d.ts +2 -0
  51. package/dist/cache/api/tests/pushToCache.test.d.ts.map +1 -0
  52. package/dist/cache/api/tests/upsertInCache.test.d.ts +2 -0
  53. package/dist/cache/api/tests/upsertInCache.test.d.ts.map +1 -0
  54. package/dist/cache/utils/index.d.ts +17 -0
  55. package/dist/cache/utils/index.d.ts.map +1 -1
  56. package/dist/cache/utils/tests/encodeKey.test.d.ts +2 -0
  57. package/dist/cache/utils/tests/encodeKey.test.d.ts.map +1 -0
  58. package/dist/cache/utils/tests/partialMatch.test.d.ts +2 -0
  59. package/dist/cache/utils/tests/partialMatch.test.d.ts.map +1 -0
  60. package/dist/channel/api/addChannelMembers.d.ts.map +1 -1
  61. package/dist/channel/api/addChannelMembersRole.d.ts.map +1 -1
  62. package/dist/channel/api/banChannelMembers.d.ts.map +1 -1
  63. package/dist/channel/api/createChannel.d.ts.map +1 -1
  64. package/dist/channel/api/getChannel.d.ts.map +1 -1
  65. package/dist/channel/api/getChannels.d.ts.map +1 -1
  66. package/dist/channel/api/index.d.ts +2 -0
  67. package/dist/channel/api/index.d.ts.map +1 -1
  68. package/dist/channel/api/joinChannel.d.ts.map +1 -1
  69. package/dist/channel/api/leaveChannel.d.ts.map +1 -1
  70. package/dist/channel/api/queryChannelMembers.d.ts +2 -9
  71. package/dist/channel/api/queryChannelMembers.d.ts.map +1 -1
  72. package/dist/channel/api/queryChannels.d.ts +2 -11
  73. package/dist/channel/api/queryChannels.d.ts.map +1 -1
  74. package/dist/channel/api/removeChannelMembers.d.ts.map +1 -1
  75. package/dist/channel/api/removeChannelMembersRole.d.ts.map +1 -1
  76. package/dist/channel/api/startReading.d.ts +17 -0
  77. package/dist/channel/api/startReading.d.ts.map +1 -0
  78. package/dist/channel/api/stopReading.d.ts +16 -0
  79. package/dist/channel/api/stopReading.d.ts.map +1 -0
  80. package/dist/channel/api/tests/addChannelMembers.test.d.ts +2 -0
  81. package/dist/channel/api/tests/addChannelMembers.test.d.ts.map +1 -0
  82. package/dist/channel/api/tests/createChannel.test.d.ts +2 -0
  83. package/dist/channel/api/tests/createChannel.test.d.ts.map +1 -0
  84. package/dist/channel/api/tests/getChannel.test.d.ts +2 -0
  85. package/dist/channel/api/tests/getChannel.test.d.ts.map +1 -0
  86. package/dist/channel/api/tests/joinChannel.test.d.ts +2 -0
  87. package/dist/channel/api/tests/joinChannel.test.d.ts.map +1 -0
  88. package/dist/channel/api/tests/queryChannelMembers.test.d.ts +2 -0
  89. package/dist/channel/api/tests/queryChannelMembers.test.d.ts.map +1 -0
  90. package/dist/channel/api/tests/queryChannels.test.d.ts +2 -0
  91. package/dist/channel/api/tests/queryChannels.test.d.ts.map +1 -0
  92. package/dist/channel/api/tests/removeChannelMembers.test.d.ts +2 -0
  93. package/dist/channel/api/tests/removeChannelMembers.test.d.ts.map +1 -0
  94. package/dist/channel/api/tests/startReading.test.d.ts +2 -0
  95. package/dist/channel/api/tests/startReading.test.d.ts.map +1 -0
  96. package/dist/channel/api/tests/stopReading.test.d.ts +2 -0
  97. package/dist/channel/api/tests/stopReading.test.d.ts.map +1 -0
  98. package/dist/channel/api/unbanChannelMembers.d.ts.map +1 -1
  99. package/dist/channel/api/updateChannel.d.ts.map +1 -1
  100. package/dist/channel/events/index.d.ts +4 -0
  101. package/dist/channel/events/index.d.ts.map +1 -1
  102. package/dist/channel/events/onChannelCreated.d.ts.map +1 -1
  103. package/dist/channel/events/onChannelDeleted.d.ts.map +1 -1
  104. package/dist/channel/events/onChannelJoined.d.ts.map +1 -1
  105. package/dist/channel/events/onChannelLeft.d.ts.map +1 -1
  106. package/dist/channel/events/onChannelMemberAdded.d.ts.map +1 -1
  107. package/dist/channel/events/onChannelMemberBanned.d.ts +17 -0
  108. package/dist/channel/events/onChannelMemberBanned.d.ts.map +1 -0
  109. package/dist/channel/events/onChannelMemberRead.d.ts +17 -0
  110. package/dist/channel/events/onChannelMemberRead.d.ts.map +1 -0
  111. package/dist/channel/events/onChannelMemberRemoved.d.ts.map +1 -1
  112. package/dist/channel/events/onChannelMemberUnbanned.d.ts +17 -0
  113. package/dist/channel/events/onChannelMemberUnbanned.d.ts.map +1 -0
  114. package/dist/channel/events/onChannelUpdated.d.ts.map +1 -1
  115. package/dist/channel/events/tests/onChannelMemberBanned.test.d.ts +2 -0
  116. package/dist/channel/events/tests/onChannelMemberBanned.test.d.ts.map +1 -0
  117. package/dist/channel/events/tests/onChannelMemberRead.test.d.ts +2 -0
  118. package/dist/channel/events/tests/onChannelMemberRead.test.d.ts.map +1 -0
  119. package/dist/channel/events/tests/onChannelMemberUnbanned.test.d.ts +2 -0
  120. package/dist/channel/events/tests/onChannelMemberUnbanned.test.d.ts.map +1 -0
  121. package/dist/channel/observers/index.d.ts +3 -0
  122. package/dist/channel/observers/index.d.ts.map +1 -1
  123. package/dist/channel/observers/liveChannelMembers.d.ts +20 -0
  124. package/dist/channel/observers/liveChannelMembers.d.ts.map +1 -0
  125. package/dist/channel/observers/liveChannels.d.ts +20 -0
  126. package/dist/channel/observers/liveChannels.d.ts.map +1 -0
  127. package/dist/channel/observers/observeChannel.d.ts +1 -1
  128. package/dist/channel/observers/observeChannel.d.ts.map +1 -1
  129. package/dist/channel/observers/observeChannels.d.ts +17 -0
  130. package/dist/channel/observers/observeChannels.d.ts.map +1 -0
  131. package/dist/channel/observers/tests/liveChannelMembers.test.d.ts +2 -0
  132. package/dist/channel/observers/tests/liveChannelMembers.test.d.ts.map +1 -0
  133. package/dist/channel/observers/tests/liveChannels.test.d.ts +2 -0
  134. package/dist/channel/observers/tests/liveChannels.test.d.ts.map +1 -0
  135. package/dist/channel/utils/index.d.ts +2 -0
  136. package/dist/channel/utils/index.d.ts.map +1 -0
  137. package/dist/channel/utils/prepareChannelPayload.d.ts +3 -0
  138. package/dist/channel/utils/prepareChannelPayload.d.ts.map +1 -0
  139. package/dist/channel/utils/tests/prepareChannelPayload.test.d.ts +2 -0
  140. package/dist/channel/utils/tests/prepareChannelPayload.test.d.ts.map +1 -0
  141. package/dist/client/api/connectClient.d.ts +0 -1
  142. package/dist/client/api/connectClient.d.ts.map +1 -1
  143. package/dist/client/api/createClient.d.ts.map +1 -1
  144. package/dist/client/api/getFeedSettings.d.ts +16 -0
  145. package/dist/client/api/getFeedSettings.d.ts.map +1 -0
  146. package/dist/client/api/getToken.d.ts +1 -3
  147. package/dist/client/api/getToken.d.ts.map +1 -1
  148. package/dist/client/api/index.d.ts +1 -0
  149. package/dist/client/api/index.d.ts.map +1 -1
  150. package/dist/client/api/tests/activeClient.test.d.ts +2 -0
  151. package/dist/client/api/tests/activeClient.test.d.ts.map +1 -0
  152. package/dist/client/api/tests/activeUser.test.d.ts +2 -0
  153. package/dist/client/api/tests/activeUser.test.d.ts.map +1 -0
  154. package/dist/community/api/createCommunity.d.ts +1 -1
  155. package/dist/community/api/createCommunity.d.ts.map +1 -1
  156. package/dist/community/api/getCommunities.d.ts.map +1 -1
  157. package/dist/community/api/getCommunity.d.ts.map +1 -1
  158. package/dist/community/api/getRecommendedCommunities.d.ts.map +1 -1
  159. package/dist/community/api/getTopTrendingCommunities.d.ts.map +1 -1
  160. package/dist/community/api/queryCommunities.d.ts.map +1 -1
  161. package/dist/community/api/queryCommunityMembers.d.ts +6 -1
  162. package/dist/community/api/queryCommunityMembers.d.ts.map +1 -1
  163. package/dist/community/api/test/queryCommunityMembers.test.d.ts +2 -0
  164. package/dist/community/api/test/queryCommunityMembers.test.d.ts.map +1 -0
  165. package/dist/community/api/updateCommunity.d.ts +1 -1
  166. package/dist/community/api/updateCommunity.d.ts.map +1 -1
  167. package/dist/community/events/utils.d.ts.map +1 -1
  168. package/dist/community/utils/index.d.ts +2 -0
  169. package/dist/community/utils/index.d.ts.map +1 -0
  170. package/dist/community/utils/payload.d.ts +11 -0
  171. package/dist/community/utils/payload.d.ts.map +1 -0
  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/query/filtering.d.ts +12 -0
  176. package/dist/core/query/filtering.d.ts.map +1 -1
  177. package/dist/core/query/query.d.ts.map +1 -1
  178. package/dist/core/transports/http.d.ts +5 -0
  179. package/dist/core/transports/http.d.ts.map +1 -1
  180. package/dist/core/transports/test/http.test.d.ts +2 -0
  181. package/dist/core/transports/test/http.test.d.ts.map +1 -0
  182. package/dist/file/api/createVideo.d.ts +2 -1
  183. package/dist/file/api/createVideo.d.ts.map +1 -1
  184. package/dist/follow/api/queryFollowers.d.ts +1 -5
  185. package/dist/follow/api/queryFollowers.d.ts.map +1 -1
  186. package/dist/follow/api/queryFollowings.d.ts +1 -5
  187. package/dist/follow/api/queryFollowings.d.ts.map +1 -1
  188. package/dist/follow/observers/index.d.ts +2 -0
  189. package/dist/follow/observers/index.d.ts.map +1 -1
  190. package/dist/follow/observers/liveFollowers.d.ts +20 -0
  191. package/dist/follow/observers/liveFollowers.d.ts.map +1 -0
  192. package/dist/follow/observers/liveFollowings.d.ts +20 -0
  193. package/dist/follow/observers/liveFollowings.d.ts.map +1 -0
  194. package/dist/follow/tests/observers/liveFollowers.test.d.ts +2 -0
  195. package/dist/follow/tests/observers/liveFollowers.test.d.ts.map +1 -0
  196. package/dist/follow/tests/observers/liveFollowings.test.d.ts +2 -0
  197. package/dist/follow/tests/observers/liveFollowings.test.d.ts.map +1 -0
  198. package/dist/group/utils/index.d.ts +2 -0
  199. package/dist/group/utils/index.d.ts.map +1 -0
  200. package/dist/group/utils/test/withUsers.test.d.ts +2 -0
  201. package/dist/group/utils/test/withUsers.test.d.ts.map +1 -0
  202. package/dist/group/utils/withUser.d.ts +38 -0
  203. package/dist/group/utils/withUser.d.ts.map +1 -0
  204. package/dist/index.cjs.js +1972 -581
  205. package/dist/index.d.ts +1 -1
  206. package/dist/index.d.ts.map +1 -1
  207. package/dist/index.esm.js +1937 -576
  208. package/dist/index.umd.js +4 -4
  209. package/dist/message/api/createMessage.d.ts +4 -1
  210. package/dist/message/api/createMessage.d.ts.map +1 -1
  211. package/dist/message/api/deleteMessage.d.ts.map +1 -1
  212. package/dist/message/api/getMessage.d.ts +1 -1
  213. package/dist/message/api/getMessage.d.ts.map +1 -1
  214. package/dist/message/api/getMessages.d.ts.map +1 -1
  215. package/dist/message/api/queryMessages.d.ts +1 -10
  216. package/dist/message/api/queryMessages.d.ts.map +1 -1
  217. package/dist/message/api/tests/createMessage.test.d.ts +2 -0
  218. package/dist/message/api/tests/createMessage.test.d.ts.map +1 -0
  219. package/dist/message/api/tests/deleteMessage.test.d.ts +2 -0
  220. package/dist/message/api/tests/deleteMessage.test.d.ts.map +1 -0
  221. package/dist/message/api/tests/getMessage.test.d.ts +2 -0
  222. package/dist/message/api/tests/getMessage.test.d.ts.map +1 -0
  223. package/dist/message/api/tests/getMessages.test.d.ts +2 -0
  224. package/dist/message/api/tests/getMessages.test.d.ts.map +1 -0
  225. package/dist/message/api/tests/queryMessages.test.d.ts +2 -0
  226. package/dist/message/api/tests/queryMessages.test.d.ts.map +1 -0
  227. package/dist/message/api/tests/updateMessage.test.d.ts +2 -0
  228. package/dist/message/api/tests/updateMessage.test.d.ts.map +1 -0
  229. package/dist/message/api/updateMessage.d.ts.map +1 -1
  230. package/dist/message/events/index.d.ts +1 -0
  231. package/dist/message/events/index.d.ts.map +1 -1
  232. package/dist/message/events/onMessageFetched.d.ts +17 -0
  233. package/dist/message/events/onMessageFetched.d.ts.map +1 -0
  234. package/dist/message/observers/index.d.ts +2 -0
  235. package/dist/message/observers/index.d.ts.map +1 -1
  236. package/dist/message/observers/liveMessage.d.ts +18 -0
  237. package/dist/message/observers/liveMessage.d.ts.map +1 -0
  238. package/dist/message/observers/liveMessages.d.ts +20 -0
  239. package/dist/message/observers/liveMessages.d.ts.map +1 -0
  240. package/dist/message/observers/observeMessage.d.ts.map +1 -1
  241. package/dist/message/observers/observeMessages.d.ts +0 -1
  242. package/dist/message/observers/observeMessages.d.ts.map +1 -1
  243. package/dist/message/tests/observers/liveMessage.test.d.ts +2 -0
  244. package/dist/message/tests/observers/liveMessage.test.d.ts.map +1 -0
  245. package/dist/message/tests/observers/liveMessages.test.d.ts +2 -0
  246. package/dist/message/tests/observers/liveMessages.test.d.ts.map +1 -0
  247. package/dist/post/api/deletePost.d.ts.map +1 -1
  248. package/dist/post/api/getPost.d.ts.map +1 -1
  249. package/dist/post/api/queryPosts.d.ts.map +1 -1
  250. package/dist/post/api/tests/queryPosts.test.d.ts +2 -0
  251. package/dist/post/api/tests/queryPosts.test.d.ts.map +1 -0
  252. package/dist/post/api/updatePost.d.ts +6 -1
  253. package/dist/post/api/updatePost.d.ts.map +1 -1
  254. package/dist/post/observers/livePosts.d.ts.map +1 -1
  255. package/dist/reaction/api/addReaction.d.ts.map +1 -1
  256. package/dist/reaction/api/removeReaction.d.ts.map +1 -1
  257. package/dist/reaction/api/tests/addReaction.test.d.ts +2 -0
  258. package/dist/reaction/api/tests/addReaction.test.d.ts.map +1 -0
  259. package/dist/reaction/api/tests/removeReaction.test.d.ts +2 -0
  260. package/dist/reaction/api/tests/removeReaction.test.d.ts.map +1 -0
  261. package/dist/user/api/getUser.d.ts +1 -1
  262. package/dist/user/api/getUser.d.ts.map +1 -1
  263. package/dist/user/api/getUsers.d.ts.map +1 -1
  264. package/dist/user/api/queryUsers.d.ts.map +1 -1
  265. package/dist/user/api/tests/queryUsers.test.d.ts +2 -0
  266. package/dist/user/api/tests/queryUsers.test.d.ts.map +1 -0
  267. package/dist/user/api/updateUser.d.ts.map +1 -1
  268. package/dist/user/events/index.d.ts +1 -0
  269. package/dist/user/events/index.d.ts.map +1 -1
  270. package/dist/user/events/onUserFetched.d.ts +17 -0
  271. package/dist/user/events/onUserFetched.d.ts.map +1 -0
  272. package/dist/user/observers/index.d.ts +1 -0
  273. package/dist/user/observers/index.d.ts.map +1 -1
  274. package/dist/user/observers/liveUser.d.ts +18 -0
  275. package/dist/user/observers/liveUser.d.ts.map +1 -0
  276. package/dist/user/observers/observeUser.d.ts.map +1 -1
  277. package/dist/user/tests/api/getUser.test.d.ts +2 -0
  278. package/dist/user/tests/api/getUser.test.d.ts.map +1 -0
  279. package/dist/user/tests/observers/liveUser.test.d.ts +2 -0
  280. package/dist/user/tests/observers/liveUser.test.d.ts.map +1 -0
  281. package/dist/utils/constants.d.ts +4 -0
  282. package/dist/utils/constants.d.ts.map +1 -1
  283. package/dist/utils/tests/client.d.ts +5 -2
  284. package/dist/utils/tests/client.d.ts.map +1 -1
  285. package/dist/utils/tests/dummy/channel.d.ts +128 -0
  286. package/dist/utils/tests/dummy/channel.d.ts.map +1 -0
  287. package/dist/utils/tests/dummy/community.d.ts +34 -0
  288. package/dist/utils/tests/dummy/community.d.ts.map +1 -0
  289. package/dist/utils/tests/dummy/file.d.ts +2 -0
  290. package/dist/utils/tests/dummy/file.d.ts.map +1 -0
  291. package/dist/utils/tests/dummy/follow.d.ts +13 -0
  292. package/dist/utils/tests/dummy/follow.d.ts.map +1 -0
  293. package/dist/utils/tests/dummy/index.d.ts +18 -0
  294. package/dist/utils/tests/dummy/index.d.ts.map +1 -0
  295. package/dist/utils/tests/dummy/member.d.ts +2 -0
  296. package/dist/utils/tests/dummy/member.d.ts.map +1 -0
  297. package/dist/utils/tests/dummy/message.d.ts +24 -0
  298. package/dist/utils/tests/dummy/message.d.ts.map +1 -0
  299. package/dist/utils/tests/dummy/poll.d.ts +3 -0
  300. package/dist/utils/tests/dummy/poll.d.ts.map +1 -0
  301. package/dist/utils/tests/dummy/post.d.ts +23 -0
  302. package/dist/utils/tests/dummy/post.d.ts.map +1 -0
  303. package/dist/utils/tests/dummy/reaction.d.ts +4 -0
  304. package/dist/utils/tests/dummy/reaction.d.ts.map +1 -0
  305. package/dist/utils/tests/dummy/role.d.ts +4 -0
  306. package/dist/utils/tests/dummy/role.d.ts.map +1 -0
  307. package/dist/utils/tests/dummy/user.d.ts +17 -0
  308. package/dist/utils/tests/dummy/user.d.ts.map +1 -0
  309. package/dist/utils/tests/index.d.ts +3 -2
  310. package/dist/utils/tests/index.d.ts.map +1 -1
  311. package/dist/utils/tests/utils.d.ts +3 -0
  312. package/dist/utils/tests/utils.d.ts.map +1 -0
  313. package/package.json +3 -2
  314. package/src/@types/core/cache.ts +4 -0
  315. package/src/@types/core/errors.ts +1 -0
  316. package/src/@types/core/events.ts +3 -0
  317. package/src/@types/core/live.ts +10 -4
  318. package/src/@types/core/payload.ts +23 -17
  319. package/src/@types/core/query.ts +1 -1
  320. package/src/@types/domains/channel.ts +61 -1
  321. package/src/@types/domains/client.ts +6 -0
  322. package/src/@types/domains/community.ts +27 -2
  323. package/src/@types/domains/content.ts +35 -3
  324. package/src/@types/domains/file.ts +42 -3
  325. package/src/@types/domains/follow.ts +28 -0
  326. package/src/@types/domains/group.ts +7 -2
  327. package/src/@types/domains/message.ts +32 -9
  328. package/src/@types/domains/post.ts +10 -3
  329. package/src/@types/domains/user.ts +8 -0
  330. package/src/@types/global.ts +2 -0
  331. package/src/@types/index.ts +6 -5
  332. package/src/cache/api/backupCache.ts +0 -1
  333. package/src/cache/api/index.ts +2 -1
  334. package/src/cache/api/ingestInCache.ts +2 -2
  335. package/src/cache/api/isInTombstone.ts +41 -0
  336. package/src/cache/api/pushToTombstone.ts +33 -0
  337. package/src/cache/api/tests/dropFromCache.test.ts +59 -0
  338. package/src/cache/api/tests/ingestInCache.test.ts +87 -0
  339. package/src/cache/api/tests/pullFromCache.test.ts +42 -0
  340. package/src/cache/api/tests/pushToCache.test.ts +57 -0
  341. package/src/cache/api/tests/upsertInCache.test.ts +60 -0
  342. package/src/cache/utils/index.ts +22 -0
  343. package/src/cache/utils/tests/encodeKey.test.ts +19 -0
  344. package/src/cache/utils/tests/partialMatch.test.ts +13 -0
  345. package/src/channel/api/addChannelMembers.ts +14 -5
  346. package/src/channel/api/addChannelMembersRole.ts +5 -1
  347. package/src/channel/api/banChannelMembers.ts +9 -3
  348. package/src/channel/api/createChannel.ts +6 -2
  349. package/src/channel/api/getChannel.ts +23 -4
  350. package/src/channel/api/getChannels.ts +5 -1
  351. package/src/channel/api/index.ts +3 -0
  352. package/src/channel/api/joinChannel.ts +5 -1
  353. package/src/channel/api/leaveChannel.ts +5 -1
  354. package/src/channel/api/queryChannelMembers.ts +77 -25
  355. package/src/channel/api/queryChannels.ts +43 -18
  356. package/src/channel/api/removeChannelMembers.ts +14 -5
  357. package/src/channel/api/removeChannelMembersRole.ts +5 -1
  358. package/src/channel/api/startReading.ts +46 -0
  359. package/src/channel/api/stopReading.ts +27 -0
  360. package/src/channel/api/tests/addChannelMembers.test.ts +123 -0
  361. package/src/channel/api/tests/createChannel.test.ts +52 -0
  362. package/src/channel/api/tests/getChannel.test.ts +108 -0
  363. package/src/channel/api/tests/joinChannel.test.ts +52 -0
  364. package/src/channel/api/tests/queryChannelMembers.test.ts +131 -0
  365. package/src/channel/api/tests/queryChannels.test.ts +121 -0
  366. package/src/channel/api/tests/removeChannelMembers.test.ts +95 -0
  367. package/src/channel/api/tests/startReading.test.ts +24 -0
  368. package/src/channel/api/tests/stopReading.test.ts +24 -0
  369. package/src/channel/api/unbanChannelMembers.ts +10 -3
  370. package/src/channel/api/updateChannel.ts +5 -1
  371. package/src/channel/events/index.ts +8 -0
  372. package/src/channel/events/onChannelCreated.ts +6 -2
  373. package/src/channel/events/onChannelDeleted.ts +6 -2
  374. package/src/channel/events/onChannelJoined.ts +6 -2
  375. package/src/channel/events/onChannelLeft.ts +6 -2
  376. package/src/channel/events/onChannelMemberAdded.ts +10 -4
  377. package/src/channel/events/onChannelMemberBanned.ts +39 -0
  378. package/src/channel/events/onChannelMemberRead.ts +38 -0
  379. package/src/channel/events/onChannelMemberRemoved.ts +9 -2
  380. package/src/channel/events/onChannelMemberUnbanned.ts +39 -0
  381. package/src/channel/events/onChannelUpdated.ts +6 -2
  382. package/src/channel/events/tests/onChannelMemberBanned.test.ts +60 -0
  383. package/src/channel/events/tests/onChannelMemberRead.test.ts +56 -0
  384. package/src/channel/events/tests/onChannelMemberUnbanned.test.ts +60 -0
  385. package/src/channel/observers/index.ts +3 -0
  386. package/src/channel/observers/liveChannelMembers.ts +185 -0
  387. package/src/channel/observers/liveChannels.ts +191 -0
  388. package/src/channel/observers/observeChannel.ts +3 -11
  389. package/src/channel/observers/observeChannels.ts +61 -0
  390. package/src/channel/observers/tests/liveChannelMembers.test.ts +232 -0
  391. package/src/channel/observers/tests/liveChannels.test.ts +219 -0
  392. package/src/channel/utils/index.ts +1 -0
  393. package/src/channel/utils/prepareChannelPayload.ts +31 -0
  394. package/src/channel/utils/tests/prepareChannelPayload.test.ts +120 -0
  395. package/src/client/api/connectClient.ts +0 -1
  396. package/src/client/api/createClient.ts +3 -0
  397. package/src/client/api/getFeedSettings.ts +29 -0
  398. package/src/client/api/index.ts +2 -0
  399. package/src/client/api/isConnected.ts +1 -1
  400. package/src/client/api/tests/activeClient.test.ts +20 -0
  401. package/src/client/api/tests/activeUser.test.ts +20 -0
  402. package/src/community/api/createCommunity.ts +9 -3
  403. package/src/community/api/getCommunities.ts +10 -3
  404. package/src/community/api/getCommunity.ts +5 -1
  405. package/src/community/api/getRecommendedCommunities.ts +5 -2
  406. package/src/community/api/getTopTrendingCommunities.ts +4 -1
  407. package/src/community/api/queryCommunities.ts +5 -2
  408. package/src/community/api/queryCommunityMembers.ts +59 -14
  409. package/src/community/api/test/queryCommunityMembers.test.ts +122 -0
  410. package/src/community/api/updateCommunity.ts +7 -3
  411. package/src/community/events/utils.ts +23 -9
  412. package/src/community/utils/index.ts +1 -0
  413. package/src/community/utils/payload.ts +44 -0
  414. package/src/core/events.ts +5 -2
  415. package/src/core/model/idResolvers.ts +1 -1
  416. package/src/core/model/identifyModel.ts +1 -1
  417. package/src/core/query/filtering.ts +55 -0
  418. package/src/core/query/query.ts +11 -9
  419. package/src/core/tests/query/query/runQuery.test.ts +2 -3
  420. package/src/core/tests/query/query.test.ts +103 -11
  421. package/src/core/transports/http.ts +3 -17
  422. package/src/core/transports/test/http.test.ts +83 -0
  423. package/src/file/api/createVideo.ts +6 -0
  424. package/src/follow/api/queryFollowers.ts +3 -5
  425. package/src/follow/api/queryFollowings.ts +3 -5
  426. package/src/follow/api/utils.ts +7 -3
  427. package/src/follow/observers/index.ts +3 -0
  428. package/src/follow/observers/liveFollowers.ts +149 -0
  429. package/src/follow/observers/liveFollowings.ts +149 -0
  430. package/src/follow/tests/observers/liveFollowers.test.ts +240 -0
  431. package/src/follow/tests/observers/liveFollowings.test.ts +239 -0
  432. package/src/group/utils/index.ts +1 -0
  433. package/src/group/utils/test/withUsers.test.ts +103 -0
  434. package/src/group/utils/withUser.ts +92 -0
  435. package/src/index.ts +1 -1
  436. package/src/message/api/createMessage.ts +15 -9
  437. package/src/message/api/deleteMessage.ts +4 -4
  438. package/src/message/api/getMessage.ts +32 -4
  439. package/src/message/api/getMessages.ts +6 -1
  440. package/src/message/api/queryMessages.ts +6 -10
  441. package/src/message/api/tests/createMessage.test.ts +99 -0
  442. package/src/message/api/tests/deleteMessage.test.ts +110 -0
  443. package/src/message/api/tests/getMessage.test.ts +121 -0
  444. package/src/message/api/tests/getMessages.test.ts +108 -0
  445. package/src/message/api/tests/queryMessages.test.ts +115 -0
  446. package/src/message/api/tests/updateMessage.test.ts +100 -0
  447. package/src/message/api/updateMessage.ts +2 -0
  448. package/src/message/events/index.ts +1 -0
  449. package/src/message/events/onMessageFetched.ts +30 -0
  450. package/src/message/observers/index.ts +2 -0
  451. package/src/message/observers/liveMessage.ts +100 -0
  452. package/src/message/observers/liveMessages.ts +143 -0
  453. package/src/message/observers/observeMessage.ts +4 -0
  454. package/src/message/observers/observeMessages.ts +0 -1
  455. package/src/message/tests/observers/liveMessage.test.ts +248 -0
  456. package/src/message/tests/observers/liveMessages.test.ts +339 -0
  457. package/src/post/api/deletePost.ts +4 -3
  458. package/src/post/api/getPost.ts +8 -4
  459. package/src/post/api/queryPosts.ts +9 -0
  460. package/src/post/api/tests/queryPosts.test.ts +149 -0
  461. package/src/post/api/updatePost.ts +6 -1
  462. package/src/post/observers/livePosts.ts +2 -1
  463. package/src/post/tests/api/getPost.test.ts +3 -3
  464. package/src/post/tests/api/queryPosts.test.ts +117 -18
  465. package/src/reaction/api/addReaction.ts +17 -6
  466. package/src/reaction/api/removeReaction.ts +17 -6
  467. package/src/reaction/api/tests/addReaction.test.ts +73 -0
  468. package/src/reaction/api/tests/removeReaction.test.ts +79 -0
  469. package/src/user/api/getUser.ts +32 -5
  470. package/src/user/api/getUsers.ts +3 -0
  471. package/src/user/api/queryUsers.ts +27 -5
  472. package/src/user/api/tests/queryUsers.test.ts +124 -0
  473. package/src/user/api/updateUser.ts +3 -0
  474. package/src/user/events/index.ts +1 -0
  475. package/src/user/events/onUserFetched.ts +19 -0
  476. package/src/user/observers/index.ts +1 -0
  477. package/src/user/observers/liveUser.ts +89 -0
  478. package/src/user/observers/observeUser.ts +2 -0
  479. package/src/user/tests/api/getUser.test.ts +112 -0
  480. package/src/user/tests/observers/liveUser.test.ts +224 -0
  481. package/src/utils/constants.ts +6 -0
  482. package/src/utils/tests/client.ts +31 -3
  483. package/src/utils/tests/dummy/channel.ts +200 -0
  484. package/src/utils/tests/dummy/community.ts +92 -0
  485. package/src/utils/tests/dummy/file.ts +20 -0
  486. package/src/utils/tests/dummy/follow.ts +66 -0
  487. package/src/utils/tests/dummy/index.ts +19 -0
  488. package/src/utils/tests/dummy/member.ts +18 -0
  489. package/src/utils/tests/dummy/message.ts +42 -0
  490. package/src/utils/tests/dummy/poll.ts +43 -0
  491. package/src/utils/tests/dummy/post.ts +92 -0
  492. package/src/utils/tests/dummy/reaction.ts +22 -0
  493. package/src/utils/tests/dummy/role.ts +21 -0
  494. package/src/utils/tests/dummy/user.ts +44 -0
  495. package/src/utils/tests/index.ts +3 -2
  496. package/src/utils/tests/utils.ts +13 -0
  497. package/dist/utils/tests/dummy.d.ts +0 -8
  498. package/dist/utils/tests/dummy.d.ts.map +0 -1
  499. package/src/utils/tests/dummy.ts +0 -7
package/dist/index.esm.js CHANGED
@@ -1,12 +1,85 @@
1
1
  import { encode, decode } from 'js-base64';
2
- import mitt from 'mitt';
3
2
  import AsyncStorage from '@react-native-async-storage/async-storage';
3
+ import mitt from 'mitt';
4
4
  import debug from 'debug';
5
5
  import axios from 'axios';
6
+ import qs from 'qs';
6
7
  import HttpAgent, { HttpsAgent } from 'agentkeepalive';
7
8
  import io from 'socket.io-client';
8
9
  import nativeIdGenerator from 'react-native-uuid';
9
10
 
11
+ const CommunityPostSettings = Object.freeze({
12
+ ONLY_ADMIN_CAN_POST: 'ONLY_ADMIN_CAN_POST',
13
+ ADMIN_REVIEW_POST_REQUIRED: 'ADMIN_REVIEW_POST_REQUIRED',
14
+ ANYONE_CAN_POST: 'ANYONE_CAN_POST',
15
+ });
16
+ const CommunityPostSettingMaps = Object.freeze({
17
+ ONLY_ADMIN_CAN_POST: {
18
+ needApprovalOnPostCreation: false,
19
+ onlyAdminCanPost: true,
20
+ },
21
+ ADMIN_REVIEW_POST_REQUIRED: {
22
+ needApprovalOnPostCreation: true,
23
+ onlyAdminCanPost: false,
24
+ },
25
+ ANYONE_CAN_POST: {
26
+ needApprovalOnPostCreation: false,
27
+ onlyAdminCanPost: false,
28
+ },
29
+ });
30
+ const DefaultCommunityPostSetting = 'ONLY_ADMIN_CAN_POST';
31
+
32
+ const ContentFeedType = Object.freeze({
33
+ STORY: 'story',
34
+ CLIP: 'clip',
35
+ CHAT: 'chat',
36
+ POST: 'post',
37
+ MESSAGE: 'message',
38
+ });
39
+
40
+ const FileType = Object.freeze({
41
+ FILE: 'file',
42
+ IMAGE: 'image',
43
+ VIDEO: 'video',
44
+ });
45
+ const VideoResolution = Object.freeze({
46
+ '1080P': '1080p',
47
+ '720P': '720p',
48
+ '480P': '480p',
49
+ '360P': '360p',
50
+ ORIGINAL: 'original',
51
+ });
52
+ const VideoTranscodingStatus = Object.freeze({
53
+ UPLOADED: 'uploaded',
54
+ TRANSCODING: 'transcoding',
55
+ TRANSCODED: 'transcoded',
56
+ TRANSCODE_FAILED: 'transcodeFailed',
57
+ });
58
+ const VideoSize = Object.freeze({
59
+ LOW: 'low',
60
+ MEDIUM: 'medium',
61
+ HIGH: 'high',
62
+ ORIGINAL: 'original',
63
+ });
64
+
65
+ const MessageContentType = Object.freeze({
66
+ TEXT: 'text',
67
+ IMAGE: 'image',
68
+ FILE: 'file',
69
+ VIDEO: 'video',
70
+ AUDIO: 'audio',
71
+ CUSTOM: 'custom',
72
+ });
73
+
74
+ const PostContentType = Object.freeze({
75
+ TEXT: 'text',
76
+ IMAGE: 'image',
77
+ FILE: 'file',
78
+ VIDEO: 'video',
79
+ LIVESTREAM: 'liveStream',
80
+ POLL: 'poll',
81
+ });
82
+
10
83
  var _a$1;
11
84
  /* eslint-disable no-undef */
12
85
  const theGlobal =
@@ -211,7 +284,7 @@ const CRITERIAS = {
211
284
  channel: ['channelId', 'rateLimit'],
212
285
  channelUsers: ['channelId', 'userId', 'membership'],
213
286
  message: ['messageId'],
214
- community: ['communityId', 'onlyAdminCanPost'],
287
+ community: ['communityId', 'postSetting'],
215
288
  category: ['categoryId'],
216
289
  communityUsers: ['userId', 'communityId', 'communityMembership'],
217
290
  post: ['postId', 'feedId'],
@@ -282,6 +355,78 @@ const PAYLOAD2MODEL = {
282
355
  followCounts: 'followCount',
283
356
  };
284
357
 
358
+ // cache constants
359
+ const CACHE_KEY_GET = 'get';
360
+ const CACHE_KEY_TOMBSTONE = 'dead';
361
+ const CACHE_LIFESPAN = 1 * 60 * 1000; // 1 minute
362
+ const CACHE_LIFESPAN_TOMBSTONE = 3 * 60 * 1000; // 3 minutes
363
+ /**
364
+ * Shallow-clones an object and sort its keys
365
+ *
366
+ * @param source a plain object to clone
367
+ * @returns a clone of source, with keys sorted with default javascript sorting
368
+ *
369
+ * @category Cache
370
+ * @hidden
371
+ */
372
+ const normalize = (source) => Object.keys(source)
373
+ .sort()
374
+ .reduce((acc, key) => (Object.assign(Object.assign({}, acc), { [key]: source[key] })), {});
375
+ /**
376
+ * Encodes a given {@link Amity.CacheKey} to a plain string
377
+ *
378
+ * @param key the key to encode
379
+ * @returns an encoded string
380
+ *
381
+ * @category Cache
382
+ * @hidden
383
+ */
384
+ const encodeKey = (key) => JSON.stringify(key, (_, val) => (typeof val === 'object' ? normalize(val) : val));
385
+ /**
386
+ * Decodes a string back into a {@link Amity.CacheKey}
387
+
388
+ *
389
+ * @param key the string key to decode
390
+ * @returns a plain Amity.CacheKey object.
391
+ *
392
+ * @category Cache
393
+ * @hidden
394
+ */
395
+ const decodeKey = (key) => JSON.parse(key);
396
+ /**
397
+ * Performs a recursive partial deep equal check on two objects.
398
+ *
399
+ * @param predicate the reference object containing the partial information
400
+ * @param candidate the object to check against
401
+ * @returns true if the candidate contains all the values of the predicate
402
+ *
403
+ * @category Cache
404
+ */
405
+ const partialMatch = (predicate, candidate) => {
406
+ if (predicate === candidate)
407
+ return true;
408
+ // if one or the other is nullish, there can't be equality
409
+ if (!predicate || !candidate)
410
+ return false;
411
+ // we only perform recursive check on objects
412
+ if (typeof predicate !== 'object') {
413
+ return false;
414
+ }
415
+ // recursively call for partial match based on the predicate
416
+ return Object.keys(predicate).every(key => partialMatch(predicate[key], candidate[key]));
417
+ };
418
+ /**
419
+ * checks if passed error code is included in
420
+ * Tombstone errors list
421
+ *
422
+ * @param errorCode as {@link Amity.ServerError}
423
+ * @returns success boolean if the given errorCode
424
+ * is included in Tombstone errors list
425
+ *
426
+ * @category Cache
427
+ */
428
+ const checkIfShouldGoesToTombstone = (errorCode) => [400400 /* Amity.ServerError.ITEM_NOT_FOUND */, 400300 /* Amity.ServerError.FORBIDDEN */].includes(errorCode);
429
+
285
430
  /* eslint-disable no-use-before-define */
286
431
  /**
287
432
  * Type guard to check and cast that a given async function is has the ".locally" property
@@ -340,7 +485,7 @@ const isLocal = (model) => {
340
485
  *
341
486
  * @hidden
342
487
  */
343
- const isFresh = (model, lifeSpan = 0) => {
488
+ const isFresh = (model, lifeSpan = CACHE_LIFESPAN) => {
344
489
  var _a;
345
490
  return Date.now() - ((_a = model === null || model === void 0 ? void 0 : model.cachedAt) !== null && _a !== void 0 ? _a : 0) <= lifeSpan;
346
491
  };
@@ -374,12 +519,10 @@ const createQuery = (func, ...args) => ({ func, args });
374
519
  *
375
520
  * @category Query
376
521
  */
377
- const queryOptions = (policy, lifeSpan = 2 * 60 * 1000) => {
522
+ const queryOptions = (policy, lifeSpan = CACHE_LIFESPAN) => {
378
523
  if (policy === 'cache_only')
379
524
  return { lifeSpan: Infinity };
380
- if (policy === 'server_only')
381
- return { lifeSpan: 0 };
382
- return { lifeSpan };
525
+ return { lifeSpan: lifeSpan < CACHE_LIFESPAN ? CACHE_LIFESPAN : lifeSpan };
383
526
  };
384
527
  /**
385
528
  * ```js
@@ -400,8 +543,9 @@ const queryOptions = (policy, lifeSpan = 2 * 60 * 1000) => {
400
543
  */
401
544
  const runQuery = ({ func, args }, callback, options = queryOptions('cache_then_server')) => {
402
545
  let local;
546
+ const { lifeSpan } = queryOptions('cache_then_server', options.lifeSpan);
403
547
  // offline first
404
- if (isOffline(func) && options.lifeSpan !== 0) {
548
+ if (isOffline(func)) {
405
549
  try {
406
550
  local = isMutator(func) ? func.optimistically(...args) : func.locally(...args);
407
551
  }
@@ -412,7 +556,7 @@ const runQuery = ({ func, args }, callback, options = queryOptions('cache_then_s
412
556
  error,
413
557
  }));
414
558
  }
415
- const shouldAbort = isCachable(local) && isFresh(local, options.lifeSpan);
559
+ const shouldAbort = isCachable(local) && isFresh(local, lifeSpan);
416
560
  callback === null || callback === void 0 ? void 0 : callback(createSnapshot(local, {
417
561
  origin: 'local',
418
562
  loading: !(isFetcher(func) && shouldAbort),
@@ -479,53 +623,6 @@ function createSnapshot(data, options) {
479
623
  return Object.assign(Object.assign({}, options), { data });
480
624
  }
481
625
 
482
- // Note:
483
- // this file should contain a suite of filtering utilities to help the
484
- // local version of the query functions.
485
- /**
486
- * Filter a given collection with strict equality against a param
487
- *
488
- * @param collection the collection to filter
489
- * @param key the key of the collection's items to challenge
490
- * @param value the expected value
491
- * @returns a filtered collection with items only matching the criteria
492
- *
493
- * @hidden
494
- */
495
- const filterByPropEquality = (collection, key, value) => (value !== undefined ? collection.filter(item => item[key] === value) : collection);
496
-
497
- // Note:
498
- // this file should contain a suite of sorting utilities to help the
499
- // local version of the query functions.
500
- /**
501
- * Alphabetic sorting of objects having a displayName
502
- */
503
- const sortByDisplayName = ({ displayName: a }, { displayName: b }) => {
504
- if (a === b)
505
- return 0;
506
- return a < b ? -1 : 1;
507
- };
508
- /**
509
- * Sorting a collection by their apparition order (oldest first)
510
- */
511
- const sortByChannelSegment = ({ channelSegment: a }, { channelSegment: b }) => a - b;
512
- /**
513
- * Sorting a collection by their apparition order (oldest first)
514
- */
515
- const sortBySegmentNumber = ({ segmentNumber: a }, { segmentNumber: b }) => a - b;
516
- /**
517
- * Sorting a collection by its oldest items
518
- */
519
- const sortByFirstCreated = ({ createdAt: a }, { createdAt: b }) => new Date(a).valueOf() - new Date(b).valueOf();
520
- /**
521
- * Sorting a collection by its newest items
522
- */
523
- const sortByLastCreated = ({ createdAt: a }, { createdAt: b }) => new Date(b).valueOf() - new Date(a).valueOf();
524
- /**
525
- * Sorting a collection by the items with most recent activity
526
- */
527
- const sortByLastActivity = ({ lastActivity: a }, { lastActivity: b }) => new Date(b).valueOf() - new Date(a).valueOf();
528
-
529
626
  /* eslint-disable max-classes-per-file */
530
627
  /**
531
628
  * Generic ASC error
@@ -615,264 +712,70 @@ const setActiveClient = (client) => {
615
712
  activeClient = client;
616
713
  };
617
714
 
618
- /* eslint-disable @typescript-eslint/ban-types */
619
- let tasks = [];
620
- let timer;
621
715
  /**
622
- * Add a function to run just before the next tick
716
+ * ```js
717
+ * import { enableCache } from '@amityco/ts-sdk'
718
+ * enableCache()
719
+ * ```
623
720
  *
624
- * @param task function to schedule for later execution
721
+ * Adds a new {@link Amity.Cache} object to
722
+ * an {@link Amity.Client} instance
723
+ *
724
+ * @param prevState a previous state of cache instance (useful for SSR)
725
+ * @param persistIf a function to determine if an entry inserted in cache
726
+ * is destined to be also saved in the persistent storage when
727
+ * calling {@link backupCache}
728
+ *
729
+ * @category Cache API
625
730
  */
626
- const scheduleTask = (task) => {
627
- clearTimeout(timer);
628
- tasks.push(task);
629
- timer = setTimeout(() => {
630
- tasks.forEach(fn => fn());
631
- tasks = [];
632
- }, 0);
731
+ const enableCache = (prevState = {}, persistIf) => {
732
+ const client = getActiveClient();
733
+ if (client.cache)
734
+ return;
735
+ client.log('cache/api/enableCache');
736
+ client.cache = { data: prevState, persistIf };
633
737
  };
634
738
 
635
- /* eslint-disable @typescript-eslint/no-unused-vars */
636
- // need to sync up the list
637
- const WS_EVENTS = [
638
- 'disconnected',
639
- 'error',
640
- 'connect_error',
641
- 'reconnect_error',
642
- 'reconnect_failed',
643
- 'v3.channel.didUpdate',
644
- 'v3.channel.didUpdate',
645
- 'v3.channel.didJoin',
646
- 'v3.channel.didLeave',
647
- 'v3.channel.didAddUsers',
648
- 'v3.channel.didRemoveUsers',
649
- 'v3.channel.didBan',
650
- 'v3.channel.didUnban',
651
- 'v3.message.didCreate',
652
- 'v3.message.didUpdate',
653
- 'v3.message.didDelete',
654
- ];
655
- const MQTT_EVENTS = [
656
- 'connect',
657
- 'message',
658
- 'disconnect',
659
- 'error',
660
- 'close',
661
- 'end',
662
- 'reconnect',
663
- ];
664
- /** @hidden */
665
- const createEventEmitter = () => {
666
- return mitt();
667
- };
668
739
  /**
669
- * Wraps the websocket events into the client's event emitter for
670
- * abstraction of transport.
740
+ * ```js
741
+ * import { disableCache } from '@amityco/ts-sdk'
742
+ * disableCache()
743
+ * ```
671
744
  *
672
- * @param ws A websocket connection to listen from
673
- * @param emitter An event emitter to wire the events to
745
+ * Wipes the existing {@link Amity.Cache} object attached to
746
+ * an {@link Amity.Client} instance
674
747
  *
675
- * @category Transport
676
- * @hidden
748
+ * @category Cache API
677
749
  */
678
- const proxyWebsocketEvents = (ws, emitter) => {
679
- WS_EVENTS.forEach(event => {
680
- ws.on(event, (param) => emitter.emit(event, param));
681
- });
682
- };
683
- const proxyMqttEvents = (mqttClient, emitter) => {
684
- MQTT_EVENTS.forEach(event => {
685
- mqttClient.on(event, (...params) => emitter.emit(event, params.length === 1 ? params[0] : params));
686
- });
687
- // @ts-ignore
688
- mqttClient.on('message', (topic, payload) => {
689
- const message = JSON.parse(payload.toString());
690
- emitter.emit(message.eventType, message.data);
691
- });
692
- };
750
+ const disableCache = () => {
751
+ const client = getActiveClient();
752
+ if (!client.cache)
753
+ return;
754
+ client.log('cache/api/disableCache');
755
+ // we do this so that testing if cache is enabled
756
+ // is only `if (client.cache)
757
+ delete client.cache;
758
+ };
759
+
693
760
  /**
694
- * Standardize the subscription of SSE through web sockets
761
+ * ```js
762
+ * import { restoreCache } from '@amityco/ts-sdk'
763
+ * const success = await restoreCache()
764
+ * ```
695
765
  *
696
- * @param client The current client for which to subscribe the event to
697
- * @param namespace A unique name for the logger
698
- * @param event The websocket event name
699
- * @param fn A wrapper for the callback.
700
- * @returns A dispose function to unsubscribe to the event
766
+ * Reads a previously saved {@link Amity.Cache} from a persistent storage,
767
+ * and inserts it into the current {@link Amity.Cache} instance.
701
768
  *
702
- * @category Transport
703
- * @hidden
704
- */
705
- const createEventSubscriber = (client, namespace, event, fn) => {
706
- const { log, emitter } = client;
707
- const timestamp = Date.now();
708
- log(`${namespace}(tmpid: ${timestamp}) > listen`);
709
- const handler = (...payload) => {
710
- log(`${namespace}(tmpid: ${timestamp}) > trigger`, payload);
711
- fn(...payload);
712
- };
713
- emitter.on(event, handler);
714
- return () => {
715
- log(`${namespace}(tmpid: ${timestamp}) > dispose`);
716
- emitter.off(event, handler);
717
- };
718
- };
719
- /**
720
- * Wrapper around dispatch event
769
+ * The strategy for persistent storage will depend on the runtime,
770
+ * which is supported by @react-native-async-storage/async-storage.
721
771
  *
722
- * @hidden
723
- */
724
- const fireEvent = (event, payload) => {
725
- const { emitter } = getActiveClient();
726
- scheduleTask(() => {
727
- emitter.emit(event, payload);
728
- });
729
- };
730
-
731
- let activeUser = null;
732
- /**
733
- * for internal use
734
- */
735
- const getActiveUser = () => {
736
- if (!activeUser) {
737
- throw new ASCError('Connect client first', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "fatal" /* Amity.ErrorLevel.FATAL */);
738
- }
739
- return activeUser;
740
- };
741
- const setActiveUser = (user) => {
742
- activeUser = {
743
- _id: user._id,
744
- userId: user.userId,
745
- path: user.path,
746
- };
747
- };
748
-
749
- var SubscriptionLevels;
750
- (function (SubscriptionLevels) {
751
- SubscriptionLevels["COMMUNITY"] = "community";
752
- SubscriptionLevels["POST"] = "post";
753
- SubscriptionLevels["COMMENT"] = "comment";
754
- SubscriptionLevels["POST_AND_COMMENT"] = "post_and_comment";
755
- SubscriptionLevels["USER"] = "user";
756
- })(SubscriptionLevels || (SubscriptionLevels = {}));
757
- const getCommunityUserTopic = (path, level) => {
758
- switch (level) {
759
- case 'post':
760
- return `${path}/post/+`;
761
- case 'comment':
762
- return `${path}/post/+/comment/+`;
763
- case 'post_and_comment':
764
- return `${path}/post/#`;
765
- default:
766
- return path;
767
- }
768
- };
769
- const getCommunityTopic = ({ path }, level = SubscriptionLevels.COMMUNITY) => getCommunityUserTopic(path, level);
770
- const getUserTopic = ({ path }, level = SubscriptionLevels.USER) => getCommunityUserTopic(level === SubscriptionLevels.USER ? path : path.replace(/^(\w*)/, '$1/social'), level);
771
- const getPostTopic = ({ path }, level = SubscriptionLevels.POST) => {
772
- switch (level) {
773
- case 'comment':
774
- return `${path}/comment/+`;
775
- default:
776
- return path;
777
- }
778
- };
779
- const getCommentTopic = ({ path }) => {
780
- return path;
781
- };
782
- const getMyFollowersTopic = () => {
783
- const user = getActiveUser();
784
- const [networkId] = user.path.split('/user/');
785
- return `${networkId}/membership/${user._id}/+/+`;
786
- };
787
- const getMyFollowingsTopic = () => {
788
- const user = getActiveUser();
789
- const [networkId] = user.path.split('/user/');
790
- return `${networkId}/membership/+/${user._id}/+`;
791
- };
792
- /** @hidden */
793
- const getNetworkTopic = () => {
794
- const user = getActiveUser();
795
- const [networkId] = user.path.split('/user/');
796
- return networkId;
797
- };
798
- let mqttAccessToken;
799
- let mqttUserId;
800
- function subscribeTopic(topic, callback) {
801
- const { mqtt, emitter, accessToken } = getActiveClient();
802
- const user = getActiveUser();
803
- if (mqttAccessToken !== accessToken || mqttUserId !== user._id) {
804
- mqttAccessToken = accessToken;
805
- mqttUserId = user._id;
806
- mqtt.connect({ accessToken: mqttAccessToken, userId: mqttUserId });
807
- proxyMqttEvents(mqtt, emitter);
808
- }
809
- return mqtt.subscribe(topic, callback);
810
- }
811
-
812
- /**
813
- * ```js
814
- * import { enableCache } from '@amityco/ts-sdk'
815
- * enableCache()
816
- * ```
817
- *
818
- * Adds a new {@link Amity.Cache} object to
819
- * an {@link Amity.Client} instance
820
- *
821
- * @param prevState a previous state of cache instance (useful for SSR)
822
- * @param persistIf a function to determine if an entry inserted in cache
823
- * is destined to be also saved in the persistent storage when
824
- * calling {@link backupCache}
825
- *
826
- * @category Cache API
827
- */
828
- const enableCache = (prevState = {}, persistIf) => {
829
- const client = getActiveClient();
830
- if (client.cache)
831
- return;
832
- client.log('cache/api/enableCache');
833
- client.cache = { data: prevState, persistIf };
834
- };
835
-
836
- /**
837
- * ```js
838
- * import { disableCache } from '@amityco/ts-sdk'
839
- * disableCache()
840
- * ```
841
- *
842
- * Wipes the existing {@link Amity.Cache} object attached to
843
- * an {@link Amity.Client} instance
844
- *
845
- * @category Cache API
846
- */
847
- const disableCache = () => {
848
- const client = getActiveClient();
849
- if (!client.cache)
850
- return;
851
- client.log('cache/api/disableCache');
852
- // we do this so that testing if cache is enabled
853
- // is only `if (client.cache)
854
- delete client.cache;
855
- };
856
-
857
- /**
858
- * ```js
859
- * import { restoreCache } from '@amityco/ts-sdk'
860
- * const success = await restoreCache()
861
- * ```
862
- *
863
- * Reads a previously saved {@link Amity.Cache} from a persistent storage,
864
- * and inserts it into the current {@link Amity.Cache} instance.
865
- *
866
- * The strategy for persistent storage will depend on the runtime,
867
- * which is supported by @react-native-async-storage/async-storage.
868
- *
869
- * The current userId will be appended to the given storageKey to ensures
870
- * the cached data concerns only the current user.
871
- *
872
- * @param storageKey the name of the persistent storage
873
- * @returns a success boolean if the cache was dumped to persistent storage
874
- *
875
- * @category Cache API
772
+ * The current userId will be appended to the given storageKey to ensures
773
+ * the cached data concerns only the current user.
774
+ *
775
+ * @param storageKey the name of the persistent storage
776
+ * @returns a success boolean if the cache was dumped to persistent storage
777
+ *
778
+ * @category Cache API
876
779
  */
877
780
  const restoreCache = async (storageKey = 'amitySdk') => {
878
781
  var _a;
@@ -893,7 +796,6 @@ const restoreCache = async (storageKey = 'amitySdk') => {
893
796
  return true;
894
797
  };
895
798
 
896
- /* eslint-disable @typescript-eslint/no-unused-vars */
897
799
  /**
898
800
  * ```js
899
801
  * import { backupCache } from '@amityco/ts-sdk'
@@ -960,62 +862,6 @@ const wipeCache = async (storageKey = 'amitySdk') => {
960
862
  return true;
961
863
  };
962
864
 
963
- /**
964
- * Shallow-clones an object and sort its keys
965
- *
966
- * @param source a plain object to clone
967
- * @returns a clone of source, with keys sorted with default javascript sorting
968
- *
969
- * @category Cache
970
- * @hidden
971
- */
972
- const normalize = (source) => Object.keys(source)
973
- .sort()
974
- .reduce((acc, key) => (Object.assign(Object.assign({}, acc), { [key]: source[key] })), {});
975
- /**
976
- * Encodes a given {@link Amity.CacheKey} to a plain string
977
- *
978
- * @param key the key to encode
979
- * @returns an encoded string
980
- *
981
- * @category Cache
982
- * @hidden
983
- */
984
- const encodeKey = (key) => JSON.stringify(key, (_, val) => (typeof val === 'object' ? normalize(val) : val));
985
- /**
986
- * Decodes a string back into a {@link Amity.CacheKey}
987
-
988
- *
989
- * @param key the string key to decode
990
- * @returns a plain Amity.CacheKey object.
991
- *
992
- * @category Cache
993
- * @hidden
994
- */
995
- const decodeKey = (key) => JSON.parse(key);
996
- /**
997
- * Performs a recursive partial deep equal check on two objects.
998
- *
999
- * @param predicate the reference object containing the partial information
1000
- * @param candidate the object to check against
1001
- * @returns true if the candidate contains all the values of the predicate
1002
- *
1003
- * @category Cache
1004
- */
1005
- const partialMatch = (predicate, candidate) => {
1006
- if (predicate === candidate)
1007
- return true;
1008
- // if one or the other is nullish, there can't be equality
1009
- if (!predicate || !candidate)
1010
- return false;
1011
- // we only perform recursive check on objects
1012
- if (typeof predicate !== 'object') {
1013
- return false;
1014
- }
1015
- // recursively call for partial match based on the predicate
1016
- return Object.keys(predicate).every(key => partialMatch(predicate[key], candidate[key]));
1017
- };
1018
-
1019
865
  /**
1020
866
  * ```js
1021
867
  * import { queryCache } from '@amityco/ts-sdk'
@@ -1192,53 +1038,336 @@ const dropFromCache = (key, exact = false) => {
1192
1038
  return false;
1193
1039
  };
1194
1040
 
1041
+ // Note:
1042
+ // this file should contain a suite of filtering utilities to help the
1043
+ // local version of the query functions.
1195
1044
  /**
1196
- * Creates a pre-configured logger instance
1045
+ * Filter a given collection with strict equality against a param
1197
1046
  *
1198
- * @param session The name of the debug session
1199
- * @returns A pre-configured logger function
1047
+ * @param collection the collection to filter
1048
+ * @param key the key of the collection's items to challenge
1049
+ * @param value the expected value
1050
+ * @returns a filtered collection with items only matching the criteria
1200
1051
  *
1201
- * @category Debug
1202
1052
  * @hidden
1203
1053
  */
1204
- const createLogger = (session) => {
1205
- const active = `${session === null || session === void 0 ? void 0 : session.trim()}`.length > 0 && !isProduction;
1206
- const logger = debug(session);
1207
- const print = (topic, ...args) => {
1208
- active && logger(topic, args);
1209
- };
1210
- // eslint-disable-next-line no-underscore-dangle
1211
- print.__instance__ = logger;
1212
- return print;
1213
- };
1214
-
1215
- const API_REGIONS = {
1216
- EU: 'eu',
1217
- SG: 'sg',
1218
- US: 'us',
1219
- };
1220
- const URLS = {
1221
- http: 'https://api.{region}.amity.co',
1222
- mqtt: 'wss://sse.{region}.amity.co:443/mqtt',
1223
- };
1224
- function computeUrl(type, region) {
1225
- return URLS[type].replace('{region}', region);
1226
- }
1227
-
1054
+ const filterByPropEquality = (collection, key, value) => (value !== undefined ? collection.filter(item => item[key] === value) : collection);
1055
+ const filterByPropInclusion = (collection, key, value) => (value !== undefined ? collection.filter(item => value.includes(item[key])) : collection);
1228
1056
  /**
1229
- * Unwraps v3 server payload (for error handling and type extraction)
1230
- *
1231
- * @param response A typical "v3" response (related to backend's service strategy)
1057
+ * Filter a channel collection by membership of the userId
1232
1058
  *
1233
- * @returns The data returned by the backend
1234
- * @throws An error related to backend's rejection
1059
+ * @param collection the channel collection to filter
1060
+ * @param membership the membership to be filtered by
1061
+ * @param userId user id to be filtered by
1062
+ * @returns a filtered collection with items only matching the criteria
1235
1063
  *
1236
- * @category Transport
1237
1064
  * @hidden
1238
1065
  */
1239
- const unwrapPayload = (response) => {
1240
- if (response.status === 'success') {
1241
- return response.data;
1066
+ const filterByChannelMembership = (collection, membership, userId) => {
1067
+ if (membership === 'all') {
1068
+ return collection;
1069
+ }
1070
+ return collection.filter(c => {
1071
+ var _a;
1072
+ // get resolver for the channel by user
1073
+ const channelUserCacheKey = getResolver('channelUsers')({
1074
+ channelId: c.channelId,
1075
+ userId,
1076
+ });
1077
+ const channelUser = (_a = pullFromCache([
1078
+ 'channelUsers',
1079
+ 'get',
1080
+ channelUserCacheKey,
1081
+ ])) === null || _a === void 0 ? void 0 : _a.data;
1082
+ // if channel user is defined for user, user is a member
1083
+ if (membership === 'member' && channelUser) {
1084
+ return true;
1085
+ }
1086
+ // if channel user by user id not found, user is not a member of that
1087
+ // channel
1088
+ if (membership === 'notMember' && !channelUser) {
1089
+ return true;
1090
+ }
1091
+ return false;
1092
+ });
1093
+ };
1094
+
1095
+ // Note:
1096
+ // this file should contain a suite of sorting utilities to help the
1097
+ // local version of the query functions.
1098
+ /**
1099
+ * Alphabetic sorting of objects having a displayName
1100
+ */
1101
+ const sortByDisplayName = ({ displayName: a }, { displayName: b }) => {
1102
+ if (a === b)
1103
+ return 0;
1104
+ return a < b ? -1 : 1;
1105
+ };
1106
+ /**
1107
+ * Sorting a collection by their apparition order (oldest first)
1108
+ */
1109
+ const sortByChannelSegment = ({ channelSegment: a }, { channelSegment: b }) => a - b;
1110
+ /**
1111
+ * Sorting a collection by their apparition order (oldest first)
1112
+ */
1113
+ const sortBySegmentNumber = ({ segmentNumber: a }, { segmentNumber: b }) => a - b;
1114
+ /**
1115
+ * Sorting a collection by its oldest items
1116
+ */
1117
+ const sortByFirstCreated = ({ createdAt: a }, { createdAt: b }) => new Date(a).valueOf() - new Date(b).valueOf();
1118
+ /**
1119
+ * Sorting a collection by its newest items
1120
+ */
1121
+ const sortByLastCreated = ({ createdAt: a }, { createdAt: b }) => new Date(b).valueOf() - new Date(a).valueOf();
1122
+ /**
1123
+ * Sorting a collection by the items with most recent activity
1124
+ */
1125
+ const sortByLastActivity = ({ lastActivity: a }, { lastActivity: b }) => new Date(b).valueOf() - new Date(a).valueOf();
1126
+
1127
+ /* eslint-disable @typescript-eslint/ban-types */
1128
+ let tasks = [];
1129
+ let timer;
1130
+ /**
1131
+ * Add a function to run just before the next tick
1132
+ *
1133
+ * @param task function to schedule for later execution
1134
+ */
1135
+ const scheduleTask = (task) => {
1136
+ clearTimeout(timer);
1137
+ tasks.push(task);
1138
+ timer = setTimeout(() => {
1139
+ tasks.forEach(fn => fn());
1140
+ tasks = [];
1141
+ }, 0);
1142
+ };
1143
+
1144
+ /* eslint-disable @typescript-eslint/no-unused-vars */
1145
+ // need to sync up the list
1146
+ const WS_EVENTS = [
1147
+ 'disconnected',
1148
+ 'error',
1149
+ 'connect_error',
1150
+ 'reconnect_error',
1151
+ 'reconnect_failed',
1152
+ 'v3.channel.didCreate',
1153
+ 'v3.channel.didUpdate',
1154
+ 'v3.channel.didDelete',
1155
+ 'v3.channel.didMarkSeen',
1156
+ 'v3.channel.didJoin',
1157
+ 'v3.channel.didLeave',
1158
+ 'v3.channel.didAddUsers',
1159
+ 'v3.channel.didRemoveUsers',
1160
+ 'v3.channel.didBan',
1161
+ 'v3.channel.didUnban',
1162
+ 'v3.message.didFetch',
1163
+ 'v3.message.didCreate',
1164
+ 'v3.message.didUpdate',
1165
+ 'v3.message.didDelete',
1166
+ ];
1167
+ const MQTT_EVENTS = [
1168
+ 'connect',
1169
+ 'message',
1170
+ 'disconnect',
1171
+ 'error',
1172
+ 'close',
1173
+ 'end',
1174
+ 'reconnect',
1175
+ ];
1176
+ /** @hidden */
1177
+ const createEventEmitter = () => {
1178
+ return mitt();
1179
+ };
1180
+ /**
1181
+ * Wraps the websocket events into the client's event emitter for
1182
+ * abstraction of transport.
1183
+ *
1184
+ * @param ws A websocket connection to listen from
1185
+ * @param emitter An event emitter to wire the events to
1186
+ *
1187
+ * @category Transport
1188
+ * @hidden
1189
+ */
1190
+ const proxyWebsocketEvents = (ws, emitter) => {
1191
+ WS_EVENTS.forEach(event => {
1192
+ ws.on(event, (param) => emitter.emit(event, param));
1193
+ });
1194
+ };
1195
+ const proxyMqttEvents = (mqttClient, emitter) => {
1196
+ MQTT_EVENTS.forEach(event => {
1197
+ mqttClient.on(event, (...params) => emitter.emit(event, params.length === 1 ? params[0] : params));
1198
+ });
1199
+ // @ts-ignore
1200
+ mqttClient.on('message', (topic, payload) => {
1201
+ const message = JSON.parse(payload.toString());
1202
+ emitter.emit(message.eventType, message.data);
1203
+ });
1204
+ };
1205
+ /**
1206
+ * Standardize the subscription of SSE through web sockets
1207
+ *
1208
+ * @param client The current client for which to subscribe the event to
1209
+ * @param namespace A unique name for the logger
1210
+ * @param event The websocket event name
1211
+ * @param fn A wrapper for the callback.
1212
+ * @returns A dispose function to unsubscribe to the event
1213
+ *
1214
+ * @category Transport
1215
+ * @hidden
1216
+ */
1217
+ const createEventSubscriber = (client, namespace, event, fn) => {
1218
+ const { log, emitter } = client;
1219
+ const timestamp = Date.now();
1220
+ log(`${namespace}(tmpid: ${timestamp}) > listen`);
1221
+ const handler = (...payload) => {
1222
+ log(`${namespace}(tmpid: ${timestamp}) > trigger`, payload);
1223
+ fn(...payload);
1224
+ };
1225
+ emitter.on(event, handler);
1226
+ return () => {
1227
+ log(`${namespace}(tmpid: ${timestamp}) > dispose`);
1228
+ emitter.off(event, handler);
1229
+ };
1230
+ };
1231
+ /**
1232
+ * Wrapper around dispatch event
1233
+ *
1234
+ * @hidden
1235
+ */
1236
+ const fireEvent = (event, payload) => {
1237
+ const { emitter } = getActiveClient();
1238
+ scheduleTask(() => {
1239
+ emitter.emit(event, payload);
1240
+ });
1241
+ };
1242
+
1243
+ let activeUser = null;
1244
+ /**
1245
+ * for internal use
1246
+ */
1247
+ const getActiveUser = () => {
1248
+ if (!activeUser) {
1249
+ throw new ASCError('Connect client first', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "fatal" /* Amity.ErrorLevel.FATAL */);
1250
+ }
1251
+ return activeUser;
1252
+ };
1253
+ const setActiveUser = (user) => {
1254
+ activeUser = {
1255
+ _id: user._id,
1256
+ userId: user.userId,
1257
+ path: user.path,
1258
+ };
1259
+ };
1260
+
1261
+ var SubscriptionLevels;
1262
+ (function (SubscriptionLevels) {
1263
+ SubscriptionLevels["COMMUNITY"] = "community";
1264
+ SubscriptionLevels["POST"] = "post";
1265
+ SubscriptionLevels["COMMENT"] = "comment";
1266
+ SubscriptionLevels["POST_AND_COMMENT"] = "post_and_comment";
1267
+ SubscriptionLevels["USER"] = "user";
1268
+ })(SubscriptionLevels || (SubscriptionLevels = {}));
1269
+ const getCommunityUserTopic = (path, level) => {
1270
+ switch (level) {
1271
+ case 'post':
1272
+ return `${path}/post/+`;
1273
+ case 'comment':
1274
+ return `${path}/post/+/comment/+`;
1275
+ case 'post_and_comment':
1276
+ return `${path}/post/#`;
1277
+ default:
1278
+ return path;
1279
+ }
1280
+ };
1281
+ const getCommunityTopic = ({ path }, level = SubscriptionLevels.COMMUNITY) => getCommunityUserTopic(path, level);
1282
+ const getUserTopic = ({ path }, level = SubscriptionLevels.USER) => getCommunityUserTopic(level === SubscriptionLevels.USER ? path : path.replace(/^(\w*)/, '$1/social'), level);
1283
+ const getPostTopic = ({ path }, level = SubscriptionLevels.POST) => {
1284
+ switch (level) {
1285
+ case 'comment':
1286
+ return `${path}/comment/+`;
1287
+ default:
1288
+ return path;
1289
+ }
1290
+ };
1291
+ const getCommentTopic = ({ path }) => {
1292
+ return path;
1293
+ };
1294
+ const getMyFollowersTopic = () => {
1295
+ const user = getActiveUser();
1296
+ const [networkId] = user.path.split('/user/');
1297
+ return `${networkId}/membership/${user._id}/+/+`;
1298
+ };
1299
+ const getMyFollowingsTopic = () => {
1300
+ const user = getActiveUser();
1301
+ const [networkId] = user.path.split('/user/');
1302
+ return `${networkId}/membership/+/${user._id}/+`;
1303
+ };
1304
+ /** @hidden */
1305
+ const getNetworkTopic = () => {
1306
+ const user = getActiveUser();
1307
+ const [networkId] = user.path.split('/user/');
1308
+ return networkId;
1309
+ };
1310
+ let mqttAccessToken;
1311
+ let mqttUserId;
1312
+ function subscribeTopic(topic, callback) {
1313
+ const { mqtt, emitter, accessToken } = getActiveClient();
1314
+ const user = getActiveUser();
1315
+ if (mqttAccessToken !== accessToken || mqttUserId !== user._id) {
1316
+ mqttAccessToken = accessToken;
1317
+ mqttUserId = user._id;
1318
+ mqtt.connect({ accessToken: mqttAccessToken, userId: mqttUserId });
1319
+ proxyMqttEvents(mqtt, emitter);
1320
+ }
1321
+ return mqtt.subscribe(topic, callback);
1322
+ }
1323
+
1324
+ /**
1325
+ * Creates a pre-configured logger instance
1326
+ *
1327
+ * @param session The name of the debug session
1328
+ * @returns A pre-configured logger function
1329
+ *
1330
+ * @category Debug
1331
+ * @hidden
1332
+ */
1333
+ const createLogger = (session) => {
1334
+ const active = `${session === null || session === void 0 ? void 0 : session.trim()}`.length > 0 && !isProduction;
1335
+ const logger = debug(session);
1336
+ const print = (topic, ...args) => {
1337
+ active && logger(topic, args);
1338
+ };
1339
+ // eslint-disable-next-line no-underscore-dangle
1340
+ print.__instance__ = logger;
1341
+ return print;
1342
+ };
1343
+
1344
+ const API_REGIONS = {
1345
+ EU: 'eu',
1346
+ SG: 'sg',
1347
+ US: 'us',
1348
+ };
1349
+ const URLS = {
1350
+ http: 'https://api.{region}.amity.co',
1351
+ mqtt: 'wss://sse.{region}.amity.co:443/mqtt',
1352
+ };
1353
+ function computeUrl(type, region) {
1354
+ return URLS[type].replace('{region}', region);
1355
+ }
1356
+
1357
+ /**
1358
+ * Unwraps v3 server payload (for error handling and type extraction)
1359
+ *
1360
+ * @param response A typical "v3" response (related to backend's service strategy)
1361
+ *
1362
+ * @returns The data returned by the backend
1363
+ * @throws An error related to backend's rejection
1364
+ *
1365
+ * @category Transport
1366
+ * @hidden
1367
+ */
1368
+ const unwrapPayload = (response) => {
1369
+ if (response.status === 'success') {
1370
+ return response.data;
1242
1371
  }
1243
1372
  if (response.status === 'fail') {
1244
1373
  throw new ASCUnknownError(response.code);
@@ -1254,21 +1383,8 @@ const unwrapPayload = (response) => {
1254
1383
  * Axios param serializer (for querystring)
1255
1384
  * @hidden
1256
1385
  */
1257
- const stringify = (params, prefix) => {
1258
- return Object.entries(params)
1259
- .filter(([, value]) => value !== undefined)
1260
- .map(([name, value]) => {
1261
- const key = prefix ? `${prefix}[${name}]` : name;
1262
- if (Array.isArray(value)) {
1263
- return value.map(item => `${key}[]=${item}`).join('&');
1264
- }
1265
- if (typeof value !== 'object') {
1266
- return `${key}=${value}`;
1267
- }
1268
- // @ts-ignore
1269
- return stringify(value, prefix !== null && prefix !== void 0 ? prefix : name);
1270
- })
1271
- .join('&');
1386
+ const stringify = (params) => {
1387
+ return qs.stringify(params, { arrayFormat: 'brackets' });
1272
1388
  };
1273
1389
  /**
1274
1390
  * Creates a pre-configured axios instance
@@ -20141,6 +20257,28 @@ const createMqttTransport = (endpoint) => {
20141
20257
  };
20142
20258
  };
20143
20259
 
20260
+ /**
20261
+ * ```js
20262
+ * import { getFeedSettings } from '@amityco/ts-sdk'
20263
+ * const feedSettings = await getFeedSettings()
20264
+ * const postFeedSetting = feedSettings.post
20265
+ * ```
20266
+ *
20267
+ * Fetches a {@link Amity.FeedSettings} object
20268
+ *
20269
+ * @returns A Promise of {@link Amity.FeedSettings} object
20270
+ *
20271
+ * @category Client API
20272
+ * @async
20273
+ */
20274
+ const getFeedSettings = async () => {
20275
+ const client = getActiveClient();
20276
+ const { data } = await client.http.get(`/api/v3/network-settings/feed-setting`);
20277
+ return Object.fromEntries(data.feedSettings.map(({ feedType, contentSettings }) => {
20278
+ return [feedType, contentSettings];
20279
+ }));
20280
+ };
20281
+
20144
20282
  const DEFAULT_DEBUG_SESSION = 'amity';
20145
20283
  /**
20146
20284
  * ```js
@@ -20180,6 +20318,7 @@ const createClient = (apiKey, apiRegion = API_REGIONS.SG, { debugSession = DEFAU
20180
20318
  mqtt,
20181
20319
  emitter,
20182
20320
  use: () => setActiveClient(client),
20321
+ getFeedSettings,
20183
20322
  };
20184
20323
  try {
20185
20324
  getActiveClient();
@@ -20257,7 +20396,7 @@ const getDeviceInfo = () => {
20257
20396
  * Ingest a payload (v3) into the cache
20258
20397
  *
20259
20398
  * @param payload a "backend v3" payload object
20260
- * @param order the order of the keys to process (in case of need)
20399
+ * @param options caching options like cachedAt or offline
20261
20400
  *
20262
20401
  * @category Cache
20263
20402
  * @hidden
@@ -20269,9 +20408,7 @@ const ingestInCache = (payload = {}, options) => {
20269
20408
  return;
20270
20409
  const resolver = getResolver(type);
20271
20410
  models.forEach(model => {
20272
- upsertInCache(
20273
- // eslint-disable @typescript-eslint no-explicit-any
20274
- [type, 'get', resolver(model)], // this 'any' cannot be avoided, sorry.
20411
+ upsertInCache([type, 'get', resolver(model)], // this 'any' cannot be avoided, sorry.
20275
20412
  model, options);
20276
20413
  });
20277
20414
  });
@@ -20421,7 +20558,6 @@ const onClientBanned = (callback) => {
20421
20558
  * @param params.displayName the user's displayName for the current session
20422
20559
  * @param params.deviceId Manual override of the user's device id (for device management)
20423
20560
  * @param params.authToken The authentication token - necessary when network option is set to secure
20424
- * @param config
20425
20561
  * @returns a success boolean if connected
20426
20562
  *
20427
20563
  * @category Client API
@@ -20482,10 +20618,65 @@ const isConnected = () => {
20482
20618
  const client = getActiveClient();
20483
20619
  client.log('client/api/isConnected', client);
20484
20620
  return !!(client.userId &&
20485
- ((_b = (_a = client.http.defaults.headers.common) === null || _a === void 0 ? void 0 : _a.Authorization) === null || _b === void 0 ? void 0 : _b.length) &&
20621
+ ((_b = String((_a = client.http.defaults.headers.common) === null || _a === void 0 ? void 0 : _a.Authorization)) === null || _b === void 0 ? void 0 : _b.length) &&
20486
20622
  client.ws.connected);
20487
20623
  };
20488
20624
 
20625
+ /**
20626
+ * ```js
20627
+ * import { isInTombstone } from '@amityco/ts-sdk'
20628
+ * const user = isInTombstone(["message", "messageId"])
20629
+ * ```
20630
+ *
20631
+ * Checks if the {@link Amity.TombstoneCacheOptions} exists
20632
+ * in cache and it's not expired means it's in tombstone
20633
+ * and we throw an Error
20634
+ *
20635
+ * @param model the model to check
20636
+ * @param modelId the object id to check
20637
+ * @returns the matching cache entry, or undefined.
20638
+ *
20639
+ * @category Cache API
20640
+ */
20641
+ const isInTombstone = (model, modelId) => {
20642
+ const { log, cache } = getActiveClient();
20643
+ const key = [model, CACHE_KEY_TOMBSTONE, modelId];
20644
+ if (!cache)
20645
+ return;
20646
+ log('cache/api/isInTombstone', key);
20647
+ const isInTombstone = pullFromCache(key);
20648
+ const { lifeSpan } = queryOptions('cache_then_server', CACHE_LIFESPAN_TOMBSTONE);
20649
+ if (isInTombstone && isFresh(isInTombstone.data, lifeSpan)) {
20650
+ throw new ASCApiError('Item not found!', 400400 /* Amity.ServerError.ITEM_NOT_FOUND */, "error" /* Amity.ErrorLevel.ERROR */);
20651
+ }
20652
+ };
20653
+
20654
+ /**
20655
+ * ```js
20656
+ * import { pushToTombstone } from '@amityco/ts-sdk'
20657
+ * pushToTombstone(["message", "messageId"], { cachedAt: Date.now() })
20658
+ * ```
20659
+ *
20660
+ * Removes an existing {@link Amity.CacheEntry} from the {@link Amity.Client}'s
20661
+ * {@link Amity.Cache} from a given {@link Amity.CacheKey}
20662
+ *
20663
+ * @param model the model to remove and push to Tombstone
20664
+ * @param modelId the related model id
20665
+ *
20666
+ * @category Cache API
20667
+ * @hidden
20668
+ */
20669
+ const pushToTombstone = (model, modelId) => {
20670
+ const { log, cache } = getActiveClient();
20671
+ const cacheKey = [model, CACHE_KEY_TOMBSTONE, modelId];
20672
+ const data = { cachedAt: Date.now() };
20673
+ if (!cache)
20674
+ return;
20675
+ log('cache/api/pushToTombstone', { cacheKey, data });
20676
+ dropFromCache([model, CACHE_KEY_GET, modelId], true);
20677
+ pushToCache(cacheKey, data);
20678
+ };
20679
+
20489
20680
  /**
20490
20681
  * ```js
20491
20682
  * import { getUser } from '@amityco/ts-sdk'
@@ -20500,15 +20691,29 @@ const isConnected = () => {
20500
20691
  * @category User API
20501
20692
  * @async
20502
20693
  */
20503
- const getUser = async (userId) => {
20694
+ const getUser = async (userId, isLive = false) => {
20504
20695
  const client = getActiveClient();
20505
20696
  client.log('user/getUser', userId);
20506
- // API-FIX: endpoint should not be /list, parameters should be querystring.
20507
- const { data } = await client.http.get(`/api/v3/users/${encodeURIComponent(userId)}`);
20697
+ if (!isLive) {
20698
+ console.log('getUser will be deprecated on 25th November 2022, please use liveUser instead.');
20699
+ }
20700
+ isInTombstone('user', userId);
20701
+ let data;
20702
+ try {
20703
+ const response = await client.http.get(`/api/v3/users/${encodeURIComponent(userId)}`);
20704
+ data = response.data;
20705
+ }
20706
+ catch (error) {
20707
+ if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
20708
+ pushToTombstone('user', userId);
20709
+ }
20710
+ throw error;
20711
+ }
20508
20712
  const cachedAt = client.cache && Date.now();
20509
20713
  if (client.cache)
20510
20714
  ingestInCache(data, { cachedAt });
20511
20715
  const { users } = data;
20716
+ fireEvent('user.fetched', data);
20512
20717
  return {
20513
20718
  data: users.find(user => user.userId === userId),
20514
20719
  cachedAt,
@@ -20558,6 +20763,7 @@ const getUsers = async (userIds) => {
20558
20763
  const cachedAt = client.cache && Date.now();
20559
20764
  if (client.cache)
20560
20765
  ingestInCache(data, { cachedAt });
20766
+ fireEvent('user.fetched', data);
20561
20767
  return {
20562
20768
  data: data.users,
20563
20769
  cachedAt,
@@ -20640,8 +20846,7 @@ function __rest(s, e) {
20640
20846
  const queryUsers = async (query = {}) => {
20641
20847
  const client = getActiveClient();
20642
20848
  client.log('user/queryUsers', query);
20643
- const { page, displayName, filter = 'all', sortBy = 'displayName' } = query, params = __rest(query, ["page", "displayName", "filter", "sortBy"]);
20644
- // API-FIX: parameters should be querystring.
20849
+ const { page = { limit: 10 }, displayName, filter = 'all', sortBy = 'displayName' } = query, params = __rest(query, ["page", "displayName", "filter", "sortBy"]);
20645
20850
  const { data } = await client.http.get(`/api/v3/users`, {
20646
20851
  params: Object.assign(Object.assign({}, params), { keyword: displayName, filter,
20647
20852
  sortBy, options: {
@@ -20654,9 +20859,14 @@ const queryUsers = async (query = {}) => {
20654
20859
  const cachedAt = client.cache && Date.now();
20655
20860
  if (client.cache) {
20656
20861
  ingestInCache(payload, { cachedAt });
20657
- const cacheKey = ['user', 'query', query];
20862
+ /*
20863
+ * using query as cache key over params because if the keyword, filter, sort
20864
+ * change the API will NOT cache results, when it should
20865
+ */
20866
+ const cacheKey = ['user', 'query', Object.assign(Object.assign({}, query), { options: Object.assign({}, page) })];
20658
20867
  pushToCache(cacheKey, { users: users.map(getResolver('user')), paging });
20659
20868
  }
20869
+ fireEvent('user.fetched', data);
20660
20870
  const prevPage = toPage(paging.previous);
20661
20871
  const nextPage = toPage(paging.next);
20662
20872
  return { data: users, cachedAt, prevPage, nextPage };
@@ -20681,8 +20891,13 @@ queryUsers.locally = (query = {}) => {
20681
20891
  client.log('user/queryUsers.locally', query);
20682
20892
  if (!client.cache)
20683
20893
  return;
20684
- const queryKey = ['user', 'query', query];
20685
- const { data, cachedAt } = (_a = pullFromCache(queryKey)) !== null && _a !== void 0 ? _a : {};
20894
+ const { page = { limit: 10 } } = query !== null && query !== void 0 ? query : {};
20895
+ const cacheKey = [
20896
+ 'user',
20897
+ 'query',
20898
+ Object.assign(Object.assign({}, query), { options: Object.assign({}, page) }),
20899
+ ];
20900
+ const { data, cachedAt } = (_a = pullFromCache(cacheKey)) !== null && _a !== void 0 ? _a : {};
20686
20901
  const users = (_b = data === null || data === void 0 ? void 0 : data.users.map(userId => pullFromCache(['user', 'get', userId])).filter(Boolean).map(({ data }) => data)) !== null && _b !== void 0 ? _b : [];
20687
20902
  const prevPage = toPage(data === null || data === void 0 ? void 0 : data.paging.previous);
20688
20903
  const nextPage = toPage(data === null || data === void 0 ? void 0 : data.paging.next);
@@ -20720,12 +20935,30 @@ const updateUser = async (userId, patch) => {
20720
20935
  if (client.cache)
20721
20936
  ingestInCache(data, { cachedAt });
20722
20937
  const { users } = data;
20938
+ fireEvent('user.updated', data);
20723
20939
  return {
20724
20940
  data: users.find(user => user.userId === userId),
20725
20941
  cachedAt,
20726
20942
  };
20727
20943
  };
20728
20944
 
20945
+ /**
20946
+ * ```js
20947
+ * import { onUserFetched } from '@amityco/ts-sdk'
20948
+ * const dispose = onUserFetched(user => {
20949
+ * // ...
20950
+ * })
20951
+ * ```
20952
+ *
20953
+ * Fired when a {@link Amity.User} has been fetched
20954
+ *
20955
+ * @param callback The function to call when the event was fired
20956
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
20957
+ *
20958
+ * @category User Events
20959
+ */
20960
+ const onUserFetched = (callback) => createUserEventSubscriber('user.fetched', callback);
20961
+
20729
20962
  /**
20730
20963
  * ```js
20731
20964
  * import { onUserUpdated } from '@amityco/ts-sdk'
@@ -20794,6 +21027,68 @@ const onUserUnflagged = (callback) => createUserEventSubscriber('user.unflagged'
20794
21027
  */
20795
21028
  const onUserFlagCleared = (callback) => createUserEventSubscriber('user.flagCleared', callback);
20796
21029
 
21030
+ const COLLECTION_DEFAULT_PAGINATION_LIMIT = 5;
21031
+ const COLLECTION_DEFAULT_CACHING_POLICY = 'cache_then_server';
21032
+ const ENABLE_CACHE_MESSAGE = 'For using Live Collection feature you need to enable Cache!';
21033
+ const LIVE_OBJECT_ENABLE_CACHE_MESSAGE = 'For using Live Object feature you need to enable Cache!';
21034
+ const UNSYNCED_OBJECT_CACHED_AT_MESSAGE = 'Observing unsynced object is not supported by Live Object.';
21035
+ const UNSYNCED_OBJECT_CACHED_AT_VALUE = -5;
21036
+
21037
+ /**
21038
+ * ```js
21039
+ * import { liveUser } from '@amityco/ts-sdk'
21040
+ *
21041
+ * let users = []
21042
+ * const unsub = liveUser(userId, response => merge(users, response.data))
21043
+ * ```
21044
+ *
21045
+ * Observe all mutation on a given {@link Amity.User}
21046
+ *
21047
+ * @param userId the ID of the user to observe
21048
+ * @param callback the function to call when new data are available
21049
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the users
21050
+ *
21051
+ * @category Message Live Object
21052
+ */
21053
+ const liveUser = (userId, callback) => {
21054
+ const { log, cache } = getActiveClient();
21055
+ let user;
21056
+ if (!cache) {
21057
+ console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
21058
+ }
21059
+ const timestamp = Date.now();
21060
+ log(`liveUser(tmpid: ${timestamp}) > listen`);
21061
+ const disposers = [];
21062
+ const dispatcher = (data) => {
21063
+ var _a;
21064
+ // we check updatedAt to see if the current snapshot is new so
21065
+ // we won't send old data back, only fresh new data
21066
+ 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')
21067
+ return;
21068
+ callback(data);
21069
+ user = data.data;
21070
+ };
21071
+ const realtimeRouter = (user, action) => {
21072
+ dispatcher({ loading: false, data: user, origin: 'event' });
21073
+ };
21074
+ const onFetch = () => {
21075
+ const query = createQuery(getUser, userId, true);
21076
+ runQuery(query, ({ loading, data, error, origin }) => {
21077
+ dispatcher({ loading, data, origin, error });
21078
+ if (error) {
21079
+ // Terminate observe functionality on error
21080
+ disposers.forEach(fn => fn());
21081
+ }
21082
+ });
21083
+ };
21084
+ 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)));
21085
+ onFetch();
21086
+ return () => {
21087
+ log(`liveUser(tmpid: ${timestamp}) > dispose`);
21088
+ disposers.forEach(fn => fn());
21089
+ };
21090
+ };
21091
+
20797
21092
  /**
20798
21093
  * ```js
20799
21094
  * import { observeUser } from '@amityco/ts-sdk'
@@ -20813,6 +21108,7 @@ const observeUser = (userId, callback) => {
20813
21108
  const { log } = getActiveClient();
20814
21109
  const timestamp = Date.now();
20815
21110
  log(`observeUser(tmpid: ${timestamp}) > listen`);
21111
+ console.log('observeUser will be deprecated on 25th November 2022, please use liveUser instead.');
20816
21112
  // wrapper function to make sure
20817
21113
  const router = (result, action) => {
20818
21114
  var _a, _b, _c;
@@ -20973,17 +21269,21 @@ const fileUrlWithSize = (fileUrl, size) => {
20973
21269
  * Creates an {@link Amity.File<'video'>}
20974
21270
  *
20975
21271
  * @param formData The data necessary to create a new {@link Amity.File<'video'>}
21272
+ * @param feedType The {@link Amity.File<'video'>} feed type
20976
21273
  * @param onProgress The callback to track the upload progress
20977
21274
  * @returns The newly created {@link Amity.File<'video'>}
20978
21275
  *
20979
21276
  * @category File API
20980
21277
  * @async
20981
21278
  */
20982
- const createVideo = async (formData, onProgress) => {
21279
+ const createVideo = async (formData, feedType, onProgress) => {
20983
21280
  const client = getActiveClient();
20984
21281
  client.log('file/createVideo', formData);
20985
21282
  if (!formData.getAll('files').length)
20986
21283
  throw new Error('The formData object must have a `files` key.');
21284
+ if (feedType) {
21285
+ formData.append('feedType', feedType);
21286
+ }
20987
21287
  const headers = 'getHeaders' in formData
20988
21288
  ? formData.getHeaders()
20989
21289
  : { 'content-type': 'multipart/form-data' };
@@ -21218,15 +21518,30 @@ const dispatchReactable = (referenceType, model) => {
21218
21518
  * @category Message API
21219
21519
  * @async
21220
21520
  */
21221
- const getMessage = async (messageId) => {
21521
+ const getMessage = async (messageId, isLive = false) => {
21222
21522
  const client = getActiveClient();
21223
21523
  client.log('message/getMessage', messageId);
21224
- // API-FIX: endpoint should not be /list, parameters should be querystring.
21225
- const { data } = await client.http.get(`/api/v3/messages/${encodeURIComponent(messageId)}`);
21524
+ if (!isLive) {
21525
+ console.log('getMessage will be deprecated on 15th November 2022, please use liveMessage instead.');
21526
+ }
21527
+ isInTombstone('message', messageId);
21528
+ let data;
21529
+ try {
21530
+ // API-FIX: endpoint should not be /list, parameters should be querystring.
21531
+ const response = await client.http.get(`/api/v3/messages/${encodeURIComponent(messageId)}`);
21532
+ data = response.data;
21533
+ }
21534
+ catch (error) {
21535
+ if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
21536
+ pushToTombstone('message', messageId);
21537
+ }
21538
+ throw error;
21539
+ }
21226
21540
  const cachedAt = client.cache && Date.now();
21227
21541
  if (client.cache)
21228
21542
  ingestInCache(data, { cachedAt });
21229
21543
  const { messages } = data;
21544
+ fireEvent('v3.message.didFetch', { messages });
21230
21545
  return {
21231
21546
  data: messages.find(message => message.messageId === messageId),
21232
21547
  cachedAt,
@@ -21283,8 +21598,10 @@ const getMessages = async (messageIds) => {
21283
21598
  const cachedAt = client.cache && Date.now();
21284
21599
  if (client.cache)
21285
21600
  ingestInCache(data, { cachedAt });
21601
+ const { messages } = data;
21602
+ fireEvent('v3.message.didFetch', { messages });
21286
21603
  return {
21287
- data: data.messages,
21604
+ data: messages,
21288
21605
  cachedAt,
21289
21606
  };
21290
21607
  };
@@ -21361,6 +21678,7 @@ const queryMessages = async (query) => {
21361
21678
  ];
21362
21679
  pushToCache(cacheKey, { messages: messages.map(getResolver('message')), paging });
21363
21680
  }
21681
+ fireEvent('v3.message.didFetch', { messages });
21364
21682
  const nextPage = toPage(paging.next);
21365
21683
  const prevPage = toPage(paging.previous);
21366
21684
  return { data: messages, cachedAt, prevPage, nextPage };
@@ -21426,8 +21744,8 @@ const createMessage = async (bundle) => {
21426
21744
  const cachedAt = client.cache && Date.now();
21427
21745
  if (client.cache)
21428
21746
  ingestInCache(data, { cachedAt });
21429
- // no need for event, fired by server
21430
21747
  const { messages } = data;
21748
+ fireEvent('v3.message.didCreate', { messages });
21431
21749
  return {
21432
21750
  data: messages[0],
21433
21751
  cachedAt,
@@ -21469,11 +21787,12 @@ createMessage.optimistically = (bundle) => {
21469
21787
  // as reused to update created and updated time, which should be the same
21470
21788
  const createdTime = new Date().toISOString();
21471
21789
  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);
21472
- pushToCache(['message', 'get', message.messageId], message, { cachedAt: -1 });
21790
+ const cachedAt = UNSYNCED_OBJECT_CACHED_AT_VALUE;
21791
+ pushToCache(['message', 'get', message.messageId], message, { cachedAt });
21473
21792
  fireEvent('v3.message.didCreate', { messages: [message] });
21474
21793
  return {
21794
+ cachedAt,
21475
21795
  data: message,
21476
- cachedAt: -1,
21477
21796
  };
21478
21797
  };
21479
21798
 
@@ -21502,6 +21821,7 @@ const updateMessage = async (messageId, patch) => {
21502
21821
  if (client.cache)
21503
21822
  ingestInCache(data, { cachedAt });
21504
21823
  const { messages } = data;
21824
+ fireEvent('v3.message.didUpdate', { messages });
21505
21825
  return {
21506
21826
  data: messages.find(message => message.messageId === messageId),
21507
21827
  cachedAt,
@@ -21561,7 +21881,7 @@ const deleteMessage = async (messageId) => {
21561
21881
  // API-FIX: This endpoint has not been implemented yet.
21562
21882
  await client.http.delete(`/api/v3/messages/${encodeURIComponent(messageId)}`);
21563
21883
  const deleted = await getMessage(messageId);
21564
- // no need for event, fired by server
21884
+ fireEvent('v3.message.didDelete', { messages: [deleted.data] });
21565
21885
  return deleted.data;
21566
21886
  };
21567
21887
  /**
@@ -21611,11 +21931,20 @@ const queryPosts = async (query) => {
21611
21931
  const client = getActiveClient();
21612
21932
  client.log('post/queryPosts', query);
21613
21933
  const { page = { limit: 10 } } = query, params = __rest(query, ["page"]);
21934
+ const { dataTypes, matchingOnlyParentPost } = params;
21614
21935
  // API-FIX: parameters should be querystring. (1)
21615
21936
  // API-FIX: backend should answer Amity.Response (2)
21616
21937
  // const { data } = await client.http.get<Amity.Response<Amity.PagedResponse<Amity.PostPayload>>>(
21617
21938
  const { data } = await client.http.get(`/api/v4/posts`, {
21618
- params: Object.assign(Object.assign({}, params), { options: {
21939
+ params: Object.assign(Object.assign({}, params), {
21940
+ /*
21941
+ * when creating post like image, file, video BE will create 2 posts
21942
+ * 1. parent post to store text with dataType=text
21943
+ * 2. child post to store dataTypes post data
21944
+ *
21945
+ * By default BE queries only parent post
21946
+ */
21947
+ matchingOnlyParentPost: matchingOnlyParentPost !== null && matchingOnlyParentPost !== void 0 ? matchingOnlyParentPost : !(dataTypes === null || dataTypes === void 0 ? void 0 : dataTypes.length), options: {
21619
21948
  token: toToken(page, 'afterbeforeraw'),
21620
21949
  } }),
21621
21950
  });
@@ -21748,6 +22077,7 @@ getPosts.locally = (postIds) => {
21748
22077
  const getPost = async (postId) => {
21749
22078
  const client = getActiveClient();
21750
22079
  client.log('post/getPost', postId);
22080
+ isInTombstone('post', postId);
21751
22081
  let data;
21752
22082
  try {
21753
22083
  // API-FIX: endpoint should not be /list, parameters should be querystring.
@@ -21755,8 +22085,8 @@ const getPost = async (postId) => {
21755
22085
  data = response.data;
21756
22086
  }
21757
22087
  catch (error) {
21758
- if ((error === null || error === void 0 ? void 0 : error.code) === 400400 /* Amity.ServerError.ITEM_NOT_FOUND */) {
21759
- dropFromCache(['post', 'get', postId], true);
22088
+ if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
22089
+ pushToTombstone('post', postId);
21760
22090
  }
21761
22091
  throw error;
21762
22092
  }
@@ -21866,6 +22196,33 @@ const updatePost = async (postId, patch) => {
21866
22196
  };
21867
22197
  };
21868
22198
 
22199
+ const getMatchPostSetting = (value) => {
22200
+ var _a;
22201
+ return (_a = Object.keys(CommunityPostSettingMaps).find(key => value.needApprovalOnPostCreation ===
22202
+ CommunityPostSettingMaps[key].needApprovalOnPostCreation &&
22203
+ value.onlyAdminCanPost === CommunityPostSettingMaps[key].onlyAdminCanPost)) !== null && _a !== void 0 ? _a : DefaultCommunityPostSetting;
22204
+ };
22205
+ /*
22206
+ * Unpack community payload by mapping payload field to postSetting value.
22207
+ */
22208
+ const unpackCommunityPayload = (_a) => {
22209
+ var { communities } = _a, restPayload = __rest(_a, ["communities"]);
22210
+ return (Object.assign({ communities: communities.map((_a) => {
22211
+ var { needApprovalOnPostCreation, onlyAdminCanPost } = _a, restCommunityPayload = __rest(_a, ["needApprovalOnPostCreation", "onlyAdminCanPost"]);
22212
+ return (Object.assign({ postSetting: getMatchPostSetting({
22213
+ needApprovalOnPostCreation,
22214
+ onlyAdminCanPost,
22215
+ }) }, restCommunityPayload));
22216
+ }) }, restPayload));
22217
+ };
22218
+ /*
22219
+ * Repack community payload by mapping postSetting to the actual value.
22220
+ */
22221
+ const packCommunityPayload = (_a) => {
22222
+ var { postSetting = undefined } = _a, restParam = __rest(_a, ["postSetting"]);
22223
+ return (Object.assign(Object.assign({}, restParam), (postSetting ? CommunityPostSettingMaps[postSetting] : undefined)));
22224
+ };
22225
+
21869
22226
  /**
21870
22227
  * ```js
21871
22228
  * import { queryCommunities } from '@amityco/ts-sdk'
@@ -21895,10 +22252,11 @@ const queryCommunities = async (query) => {
21895
22252
  } }),
21896
22253
  });
21897
22254
  const { paging } = data, payload = __rest(data, ["paging"]);
21898
- const { communities } = payload;
22255
+ const unpackedPayload = unpackCommunityPayload(payload);
22256
+ const { communities } = unpackedPayload;
21899
22257
  const cachedAt = client.cache && Date.now();
21900
22258
  if (client.cache) {
21901
- ingestInCache(payload, { cachedAt });
22259
+ ingestInCache(unpackedPayload, { cachedAt });
21902
22260
  const cacheKey = [
21903
22261
  'community',
21904
22262
  'query',
@@ -21947,9 +22305,10 @@ const getCommunities = async (communityIds) => {
21947
22305
  const client = getActiveClient();
21948
22306
  client.log('community/getCommunities', communityIds);
21949
22307
  // API-FIX: endpoint should not be /list, parameters should be querystring.
21950
- const { data } = await client.http.get(`/api/v3/communities/list`, {
22308
+ const { data: payload } = await client.http.get(`/api/v3/communities/list`, {
21951
22309
  params: { communityIds },
21952
22310
  });
22311
+ const data = unpackCommunityPayload(payload);
21953
22312
  const cachedAt = client.cache && Date.now();
21954
22313
  if (client.cache)
21955
22314
  ingestInCache(data, { cachedAt });
@@ -22008,7 +22367,8 @@ const getCommunity = async (communityId) => {
22008
22367
  const client = getActiveClient();
22009
22368
  client.log('community/getCommunity', communityId);
22010
22369
  // API-FIX: endpoint should not be /list, parameters should be querystring.
22011
- const { data } = await client.http.get(`/api/v3/communities/${communityId}`);
22370
+ const { data: payload } = await client.http.get(`/api/v3/communities/${communityId}`);
22371
+ const data = unpackCommunityPayload(payload);
22012
22372
  const cachedAt = client.cache && Date.now();
22013
22373
  if (client.cache)
22014
22374
  ingestInCache(data, { cachedAt });
@@ -22062,7 +22422,8 @@ getCommunity.locally = (communityId) => {
22062
22422
  const createCommunity = async (bundle) => {
22063
22423
  const client = getActiveClient();
22064
22424
  client.log('user/createCommunity', bundle);
22065
- const { data } = await client.http.post('/api/v3/communities/', bundle);
22425
+ const { data: payload } = await client.http.post('/api/v3/communities/', packCommunityPayload(bundle));
22426
+ const data = unpackCommunityPayload(payload);
22066
22427
  const cachedAt = client.cache && Date.now();
22067
22428
  if (client.cache)
22068
22429
  ingestInCache(data, { cachedAt });
@@ -22092,7 +22453,8 @@ const createCommunity = async (bundle) => {
22092
22453
  const updateCommunity = async (communityId, patch) => {
22093
22454
  const client = getActiveClient();
22094
22455
  client.log('community/updateCommunity', communityId, patch);
22095
- const { data } = await client.http.put(`/api/v3/communities/${communityId}`, patch);
22456
+ const { data: payload } = await client.http.put(`/api/v3/communities/${communityId}`, packCommunityPayload(patch));
22457
+ const data = unpackCommunityPayload(payload);
22096
22458
  const cachedAt = client.cache && Date.now();
22097
22459
  if (client.cache)
22098
22460
  ingestInCache(data, { cachedAt });
@@ -22180,6 +22542,58 @@ const leaveCommunity = async (communityId) => {
22180
22542
  return !!communityUsers.find(communityUser => communityUser.communityId === communityId && communityUser.communityMembership !== 'member');
22181
22543
  };
22182
22544
 
22545
+ /**
22546
+ * Attach user object to membership model
22547
+ * - If cache is not enabled, set user to undefined ({..., user: undefined})
22548
+ * - If user object is not found in cache, set user to undefined
22549
+ * ({..., user: undefined})
22550
+ * - If a user is found in the cache, it attaches the user from the cache
22551
+ * ({..., user: { userId, displayName,... }})
22552
+ *
22553
+ * @param member The membership model object
22554
+ * @param userIdProp The user ID prop name of membership object
22555
+ * @param userProp The user prop name of destination object
22556
+ * @returns The membership model object that is already mapped to user
22557
+ * @hidden
22558
+ */
22559
+ const withUser = (member, userIdProp = 'userId', userProp = 'user') => (Object.assign({ get [userProp]() {
22560
+ var _a;
22561
+ const client = getActiveClient();
22562
+ if (!client.cache)
22563
+ return undefined;
22564
+ const userCache = (_a = pullFromCache(['user', 'get', member[userIdProp]])) === null || _a === void 0 ? void 0 : _a.data;
22565
+ if (!userCache) {
22566
+ return undefined;
22567
+ }
22568
+ return userCache;
22569
+ } }, member));
22570
+ /**
22571
+ * Mapping membership model with user object
22572
+ *
22573
+ * @param members The membership model objects
22574
+ * @param userIdProp The user ID prop name of membership object
22575
+ * @param userProp The user prop name of destination object
22576
+ * @returns The membership model objects that is already
22577
+ * mapped to users
22578
+ * @hidden
22579
+ */
22580
+ const withUsers = (members, userIdProp = 'userId', userProp = 'user') => members.map(member => withUser(member, userIdProp, userProp));
22581
+ /**
22582
+ * Transform members prop in any payload with attached users members
22583
+ *
22584
+ * @param payload The payload contain members prop
22585
+ * @param memberProp A name of members prop
22586
+ * @param userIdProp The user ID prop name of membership object
22587
+ * @param userProp The user prop name of destination object
22588
+ * @returns The transforming payload
22589
+ * @hidden
22590
+ */
22591
+ const prepareMembershipPayload = (payload, memberProp, userIdProp = 'userId', userProp = 'user') => {
22592
+ const _a = payload, _b = memberProp, memberPayload = _a[_b], rest = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
22593
+ const members = withUsers(memberPayload, userIdProp, userProp);
22594
+ return Object.assign(Object.assign({}, rest), { [memberProp]: members });
22595
+ };
22596
+
22183
22597
  /**
22184
22598
  * ```js
22185
22599
  * import { queryCommunityMembers } from '@amityco/ts-sdk'
@@ -22197,17 +22611,27 @@ const leaveCommunity = async (communityId) => {
22197
22611
  const queryCommunityMembers = async (query) => {
22198
22612
  const client = getActiveClient();
22199
22613
  client.log('community/queryCommunityMembers', query);
22200
- const _a = query !== null && query !== void 0 ? query : {}, { page, communityId } = _a, params = __rest(_a, ["page", "communityId"]);
22201
- const { data } = await client.http.get(`/api/v3/communities/${communityId}/users`, {
22614
+ const _a = query !== null && query !== void 0 ? query : {}, { page } = _a, params = __rest(_a, ["page"]);
22615
+ const { data: queryPayload } = await client.http.get(`/api/v3/communities/${params.communityId}/users`, {
22202
22616
  params: Object.assign(Object.assign({}, params), { options: {
22203
22617
  token: toToken(page, 'skiplimit'),
22204
22618
  } }),
22205
22619
  });
22206
- const { paging } = data, payload = __rest(data, ["paging"]);
22207
- const { communityUsers } = payload;
22620
+ const { paging } = queryPayload, payload = __rest(queryPayload, ["paging"]);
22621
+ const preparedPayload = prepareMembershipPayload(payload, 'communityUsers');
22622
+ const { communityUsers } = preparedPayload;
22208
22623
  const cachedAt = client.cache && Date.now();
22209
22624
  if (client.cache) {
22210
- ingestInCache(payload, { cachedAt });
22625
+ ingestInCache(preparedPayload, { cachedAt });
22626
+ const cacheKey = [
22627
+ 'communityUsers',
22628
+ 'query',
22629
+ Object.assign(Object.assign({}, params), { options: Object.assign({}, page) }),
22630
+ ];
22631
+ pushToCache(cacheKey, {
22632
+ communityUsers: communityUsers.map(({ communityId, userId }) => getResolver('communityUsers')({ communityId, userId })),
22633
+ paging,
22634
+ });
22211
22635
  }
22212
22636
  const nextPage = toPage(paging.next);
22213
22637
  const prevPage = toPage(paging.previous);
@@ -22227,9 +22651,29 @@ const queryCommunityMembers = async (query) => {
22227
22651
  * @category Post API
22228
22652
  */
22229
22653
  queryCommunityMembers.locally = (query) => {
22654
+ var _a, _b;
22230
22655
  const client = getActiveClient();
22231
22656
  client.log('community/queryCommunityMembers', query);
22232
- // TODO
22657
+ if (!client.cache)
22658
+ return;
22659
+ const _c = query !== null && query !== void 0 ? query : {}, { page } = _c, params = __rest(_c, ["page"]);
22660
+ const cacheKey = [
22661
+ 'communityUsers',
22662
+ 'query',
22663
+ Object.assign(Object.assign({}, params), { options: Object.assign({}, page) }),
22664
+ ];
22665
+ const { data, cachedAt } = (_a = pullFromCache(cacheKey)) !== null && _a !== void 0 ? _a : {};
22666
+ if (!(data === null || data === void 0 ? void 0 : data.communityUsers.length))
22667
+ return;
22668
+ const communityUsers = data.communityUsers
22669
+ .map(key => pullFromCache(['communityUsers', 'get', key]))
22670
+ .filter(Boolean)
22671
+ .map(({ data }) => data);
22672
+ const prevPage = toPage(data === null || data === void 0 ? void 0 : data.paging.previous);
22673
+ const nextPage = toPage(data === null || data === void 0 ? void 0 : data.paging.next);
22674
+ return communityUsers.length === ((_b = data === null || data === void 0 ? void 0 : data.communityUsers) === null || _b === void 0 ? void 0 : _b.length)
22675
+ ? { data: communityUsers, cachedAt, prevPage, nextPage }
22676
+ : undefined;
22233
22677
  };
22234
22678
 
22235
22679
  /**
@@ -22358,7 +22802,8 @@ const getTopTrendingCommunities = async (query) => {
22358
22802
  const { limit = 5 } = query !== null && query !== void 0 ? query : {};
22359
22803
  // API-FIX: backend doesnt answer Amity.Response
22360
22804
  // const { data } = await client.http.get<Amity.Response<CommunityPayload>>(
22361
- const { data } = await client.http.get(`/api/v3/communities/top-trending`, { params: { options: { limit } } });
22805
+ const { data: payload } = await client.http.get(`/api/v3/communities/top-trending`, { params: { options: { limit } } });
22806
+ const data = unpackCommunityPayload(payload);
22362
22807
  const { communities } = data;
22363
22808
  const cachedAt = client.cache && Date.now();
22364
22809
  if (client.cache) {
@@ -22420,8 +22865,9 @@ const getRecommendedCommunities = async (query) => {
22420
22865
  client.log('channel/getRecommendedCommunities', query);
22421
22866
  const { limit = 5 } = query !== null && query !== void 0 ? query : {};
22422
22867
  // API-FIX: backend doesnt answer Amity.Response
22423
- // const { data } = await client.http.get<Amity.Response<CommunityPayload>>(
22424
- const { data } = await client.http.get(`/api/v3/communities/recommended`, { params: { options: { limit } } });
22868
+ // const { data: payload } = await client.http.get<Amity.Response<CommunityPayload>>(
22869
+ const { data: payload } = await client.http.get(`/api/v3/communities/recommended`, { params: { options: { limit } } });
22870
+ const data = unpackCommunityPayload(payload);
22425
22871
  const { communities } = data;
22426
22872
  const cachedAt = client.cache && Date.now();
22427
22873
  if (client.cache) {
@@ -22502,7 +22948,7 @@ const deletePost = async (postId, permanent = false) => {
22502
22948
  fireEvent('post.deleted', { posts: [deleted] });
22503
22949
  if (permanent) {
22504
22950
  setTimeout(() => {
22505
- dropFromCache(['post', 'get', postId], true);
22951
+ pushToTombstone('post', postId);
22506
22952
  }, 0);
22507
22953
  }
22508
22954
  else {
@@ -22898,17 +23344,6 @@ const deleteComment = async (commentId, permanent = false) => {
22898
23344
  return deleted;
22899
23345
  };
22900
23346
 
22901
- /** @hidden */
22902
- const fetchReference = async (referenceType, referenceId) => {
22903
- if (referenceType === 'message')
22904
- return getMessage(referenceId);
22905
- if (referenceType === 'post')
22906
- return getPost(referenceId);
22907
- if (referenceType === 'comment')
22908
- return getComment(referenceId);
22909
- throw new Error(`Incorrect referenceType: ${referenceType}`);
22910
- };
22911
-
22912
23347
  /** @hidden */
22913
23348
  const preparePayloadForCache = (event, payload) => {
22914
23349
  var _a, _b;
@@ -22996,7 +23431,6 @@ const prepareMessagePayloadForCache = (payload) => {
22996
23431
  * @async
22997
23432
  * */
22998
23433
  const addReaction = async (referenceType, referenceId, reactionName) => {
22999
- var _a, _b;
23000
23434
  const client = getActiveClient();
23001
23435
  client.log('reaction/createReaction', {
23002
23436
  referenceId,
@@ -23008,9 +23442,16 @@ const addReaction = async (referenceType, referenceId, reactionName) => {
23008
23442
  referenceType,
23009
23443
  reactionName,
23010
23444
  });
23011
- const model = await fetchReference(referenceType, referenceId);
23012
- dispatchReactable(referenceType, model.data);
23013
- return (_b = (_a = model.data.myReactions) === null || _a === void 0 ? void 0 : _a.includes(reactionName)) !== null && _b !== void 0 ? _b : false;
23445
+ if (client.cache) {
23446
+ const model = pullFromCache([
23447
+ referenceType,
23448
+ 'get',
23449
+ referenceId,
23450
+ ]);
23451
+ (model === null || model === void 0 ? void 0 : model.data) &&
23452
+ pushToCache([referenceType, 'get', referenceId], model.data, { cachedAt: Date.now() });
23453
+ }
23454
+ return true;
23014
23455
  };
23015
23456
  /**
23016
23457
  * ```js
@@ -23045,7 +23486,9 @@ addReaction.optimistically = (referenceType, referenceId, reactionName) => {
23045
23486
  if (!(model === null || model === void 0 ? void 0 : model.data) || ((_a = model.data.myReactions) === null || _a === void 0 ? void 0 : _a.includes(reactionName)))
23046
23487
  return;
23047
23488
  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 }) });
23048
- upsertInCache([referenceType, 'get', referenceId], reaction, { cachedAt: -1 });
23489
+ upsertInCache([referenceType, 'get', referenceId], reaction, {
23490
+ cachedAt: UNSYNCED_OBJECT_CACHED_AT_VALUE,
23491
+ });
23049
23492
  dispatchReactable(referenceType, reaction);
23050
23493
  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;
23051
23494
  };
@@ -23067,7 +23510,6 @@ addReaction.optimistically = (referenceType, referenceId, reactionName) => {
23067
23510
  * @async
23068
23511
  * */
23069
23512
  const removeReaction = async (referenceType, referenceId, reactionName) => {
23070
- var _a, _b;
23071
23513
  const client = getActiveClient();
23072
23514
  client.log('reaction/removeReaction', {
23073
23515
  referenceId,
@@ -23077,9 +23519,16 @@ const removeReaction = async (referenceType, referenceId, reactionName) => {
23077
23519
  await client.http.delete(`/api/v2/reactions`, {
23078
23520
  data: { referenceId, referenceType, reactionName },
23079
23521
  });
23080
- const model = await fetchReference(referenceType, referenceId);
23081
- dispatchReactable(referenceType, model.data);
23082
- return (_b = !((_a = model.data.myReactions) === null || _a === void 0 ? void 0 : _a.includes(reactionName))) !== null && _b !== void 0 ? _b : false;
23522
+ if (client.cache) {
23523
+ const model = pullFromCache([
23524
+ referenceType,
23525
+ 'get',
23526
+ referenceId,
23527
+ ]);
23528
+ (model === null || model === void 0 ? void 0 : model.data) &&
23529
+ pushToCache([referenceType, 'get', referenceId], model.data, { cachedAt: Date.now() });
23530
+ }
23531
+ return true;
23083
23532
  };
23084
23533
  /**
23085
23534
  * ```js
@@ -23114,7 +23563,9 @@ removeReaction.optimistically = (referenceType, referenceId, reactionName) => {
23114
23563
  if (!(model === null || model === void 0 ? void 0 : model.data) || !((_a = model.data.myReactions) === null || _a === void 0 ? void 0 : _a.includes(reactionName)))
23115
23564
  return;
23116
23565
  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) }) });
23117
- upsertInCache([referenceType, 'get', referenceId], reaction, { cachedAt: -1 });
23566
+ upsertInCache([referenceType, 'get', referenceId], reaction, {
23567
+ cachedAt: UNSYNCED_OBJECT_CACHED_AT_VALUE,
23568
+ });
23118
23569
  dispatchReactable(referenceType, reaction);
23119
23570
  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;
23120
23571
  };
@@ -23756,9 +24207,6 @@ const onReactorRemoved = (referenceType, referenceId, callback) => {
23756
24207
  return createEventSubscriber(client, 'comment.removeReaction', 'comment.removeReaction', filter);
23757
24208
  };
23758
24209
 
23759
- const COLLECTION_DEFAULT_PAGINATION_LIMIT = 5;
23760
- const COLLECTION_DEFAULT_CACHING_POLICY = 'cache_then_server';
23761
-
23762
24210
  /**
23763
24211
  * ```js
23764
24212
  * import { liveReactions } from '@amityco/ts-sdk'
@@ -23959,6 +24407,23 @@ const isReportedByMe = async (referenceType, referenceId) => {
23959
24407
  return (_b = result !== null && result !== void 0 ? result : isFlagByMe) !== null && _b !== void 0 ? _b : false;
23960
24408
  };
23961
24409
 
24410
+ /** @hidden */
24411
+ const prepareChannelPayload = (payload) => {
24412
+ const client = getActiveClient();
24413
+ const channels = payload.channels.map(channel => {
24414
+ const channelUser = payload.channelUsers.find(channelUser => channelUser.userId === client.userId && channel.channelId === channelUser.channelId);
24415
+ const hasMention = channelUser
24416
+ ? channelUser.readToSegment < channelUser.lastMentionedSegment
24417
+ : false;
24418
+ const unreadCount = channelUser && channelUser.membership === 'member' && channel.messageCount
24419
+ ? Math.max(0, channel.messageCount - channelUser.readToSegment)
24420
+ : 0;
24421
+ return Object.assign(Object.assign({}, channel), { hasMention,
24422
+ unreadCount });
24423
+ });
24424
+ return Object.assign(Object.assign({}, payload), { channels });
24425
+ };
24426
+
23962
24427
  /**
23963
24428
  * ```js
23964
24429
  * import { queryChannels } from '@amityco/ts-sdk'
@@ -23982,16 +24447,17 @@ const queryChannels = async (query) => {
23982
24447
  // API-FIX: parameters should be querystring.
23983
24448
  // API-FIX: backend doesnt answer Amity.Response
23984
24449
  // const { data } = await client.http.get<Amity.Response<Amity.Paged<ChannelPayload>>>(
23985
- const { data } = await client.http.get(`/api/v3/channels`, {
24450
+ const { data: queryPayload } = await client.http.get(`/api/v3/channels`, {
23986
24451
  params: Object.assign(Object.assign({}, params), { keyword: displayName, filter: membership, options: {
23987
24452
  token: toToken(page, 'skiplimit'),
23988
24453
  } }),
23989
24454
  });
23990
- const { paging } = data, payload = __rest(data, ["paging"]);
23991
- const { channels } = payload;
24455
+ const { paging } = queryPayload, payload = __rest(queryPayload, ["paging"]);
24456
+ const data = prepareChannelPayload(payload);
24457
+ const { channels } = data;
23992
24458
  const cachedAt = client.cache && Date.now();
23993
24459
  if (client.cache) {
23994
- ingestInCache(payload, { cachedAt });
24460
+ ingestInCache(data, { cachedAt });
23995
24461
  const cacheKey = [
23996
24462
  'channel',
23997
24463
  'query',
@@ -24017,9 +24483,24 @@ const queryChannels = async (query) => {
24017
24483
  * @category Channel API
24018
24484
  */
24019
24485
  queryChannels.locally = (query) => {
24486
+ var _a, _b;
24020
24487
  const client = getActiveClient();
24021
24488
  client.log('channel/queryChannels.locally', query);
24022
- // TODO
24489
+ const _c = query !== null && query !== void 0 ? query : {}, { page = { limit: 10 } } = _c, params = __rest(_c, ["page"]);
24490
+ const cacheKey = ['channel', 'query', Object.assign(Object.assign({}, params), { options: Object.assign({}, page) })];
24491
+ const { data, cachedAt } = (_a = pullFromCache(cacheKey)) !== null && _a !== void 0 ? _a : {};
24492
+ if (!(data === null || data === void 0 ? void 0 : data.channels.length))
24493
+ return;
24494
+ const channels = data.channels
24495
+ // ck -> cacheKey, abbrevated to avoid confusion from the above cache key
24496
+ .map(ck => pullFromCache(['channel', 'get', ck]))
24497
+ .filter(Boolean)
24498
+ .map(({ data }) => data);
24499
+ const prevPage = toPage(data === null || data === void 0 ? void 0 : data.paging.previous);
24500
+ const nextPage = toPage(data === null || data === void 0 ? void 0 : data.paging.next);
24501
+ return channels.length === ((_b = data === null || data === void 0 ? void 0 : data.channels) === null || _b === void 0 ? void 0 : _b.length)
24502
+ ? { data: channels, cachedAt, prevPage, nextPage }
24503
+ : undefined;
24023
24504
  };
24024
24505
 
24025
24506
  /**
@@ -24041,9 +24522,10 @@ const getChannels = async (channelIds) => {
24041
24522
  client.log('channel/getChannels', channelIds);
24042
24523
  const encodedChannelIds = channelIds.map(channelId => encodeURIComponent(channelId));
24043
24524
  // API-FIX: endpoint should not be /list, parameters should be querystring.
24044
- const { data } = await client.http.get(`/api/v3/channels/list`, {
24525
+ const { data: payload } = await client.http.get(`/api/v3/channels/list`, {
24045
24526
  params: { channelIds: encodedChannelIds },
24046
24527
  });
24528
+ const data = prepareChannelPayload(payload);
24047
24529
  const cachedAt = client.cache && Date.now();
24048
24530
  if (client.cache)
24049
24531
  ingestInCache(data, { cachedAt });
@@ -24101,8 +24583,18 @@ getChannels.locally = (channelIds) => {
24101
24583
  const getChannel = async (channelId) => {
24102
24584
  const client = getActiveClient();
24103
24585
  client.log('channel/getChannel', channelId);
24104
- // API-FIX: endpoint should not be /list, parameters should be querystring.
24105
- const { data } = await client.http.get(`/api/v3/channels/${encodeURIComponent(channelId)}`);
24586
+ isInTombstone('channel', channelId);
24587
+ let data;
24588
+ try {
24589
+ const { data: payload } = await client.http.get(`/api/v3/channels/${encodeURIComponent(channelId)}`);
24590
+ data = prepareChannelPayload(payload);
24591
+ }
24592
+ catch (error) {
24593
+ if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
24594
+ pushToTombstone('channel', channelId);
24595
+ }
24596
+ throw error;
24597
+ }
24106
24598
  const cachedAt = client.cache && Date.now();
24107
24599
  if (client.cache)
24108
24600
  ingestInCache(data, { cachedAt });
@@ -24163,10 +24655,11 @@ const createChannel = async (bundle) => {
24163
24655
  else {
24164
24656
  payload = await client.http.post('/api/v3/channels', bundle);
24165
24657
  }
24658
+ const data = prepareChannelPayload(payload.data);
24166
24659
  const cachedAt = client.cache && Date.now();
24167
24660
  if (client.cache)
24168
- ingestInCache(payload.data, { cachedAt });
24169
- const { channels } = payload.data;
24661
+ ingestInCache(data, { cachedAt });
24662
+ const { channels } = data;
24170
24663
  return {
24171
24664
  data: channels[0],
24172
24665
  cachedAt,
@@ -24191,7 +24684,8 @@ const createChannel = async (bundle) => {
24191
24684
  const updateChannel = async (channelId, patch) => {
24192
24685
  const client = getActiveClient();
24193
24686
  client.log('channel/updateChannel', channelId, patch);
24194
- const { data } = await client.http.put(`/api/v3/channels/${encodeURIComponent(channelId)}`, patch);
24687
+ const { data: payload } = await client.http.put(`/api/v3/channels/${encodeURIComponent(channelId)}`, patch);
24688
+ const data = prepareChannelPayload(payload);
24195
24689
  const cachedAt = client.cache && Date.now();
24196
24690
  if (client.cache)
24197
24691
  ingestInCache(data, { cachedAt });
@@ -24242,7 +24736,8 @@ const deleteChannel = async (channelId) => {
24242
24736
  const joinChannel = async (channelId) => {
24243
24737
  const client = getActiveClient();
24244
24738
  client.log('channel/joinChannel', channelId);
24245
- const { data } = await client.http.post(`/api/v3/channels/${encodeURIComponent(channelId)}/join`);
24739
+ const { data: payload } = await client.http.post(`/api/v3/channels/${encodeURIComponent(channelId)}/join`);
24740
+ const data = prepareChannelPayload(payload);
24246
24741
  if (client.cache)
24247
24742
  ingestInCache(data);
24248
24743
  const { channelUsers } = data;
@@ -24266,7 +24761,8 @@ const joinChannel = async (channelId) => {
24266
24761
  const leaveChannel = async (channelId) => {
24267
24762
  const client = getActiveClient();
24268
24763
  client.log('channel/leaveChannel', channelId);
24269
- const { data } = await client.http.delete(`/api/v3/channels/${encodeURIComponent(channelId)}/leave`);
24764
+ const { data: payload } = await client.http.delete(`/api/v3/channels/${encodeURIComponent(channelId)}/leave`);
24765
+ const data = prepareChannelPayload(payload);
24270
24766
  if (client.cache)
24271
24767
  ingestInCache(data);
24272
24768
  const { channelUsers } = data;
@@ -24290,21 +24786,37 @@ const leaveChannel = async (channelId) => {
24290
24786
  const queryChannelMembers = async (query) => {
24291
24787
  const client = getActiveClient();
24292
24788
  client.log('channel/queryChannelMembers', query);
24293
- const _a = query !== null && query !== void 0 ? query : {}, { page, channelId } = _a, params = __rest(_a, ["page", "channelId"]);
24294
- const { data } = await client.http.get(`/api/v4/channels/${encodeURIComponent(channelId)}/users`, {
24789
+ const _a = query !== null && query !== void 0 ? query : {}, { page } = _a, params = __rest(_a, ["page"]);
24790
+ const { data: queryPayload } = await client.http.get(`/api/v4/channels/${encodeURIComponent(params.channelId)}/users`, {
24295
24791
  params: Object.assign(Object.assign({}, params), { options: {
24296
24792
  token: toToken(page, 'skiplimit'),
24297
24793
  } }),
24298
24794
  });
24299
- const { paging } = data, payload = __rest(data, ["paging"]);
24300
- const { channelUsers } = payload;
24795
+ const { paging } = queryPayload, payload = __rest(queryPayload, ["paging"]);
24796
+ const channelPayload = prepareChannelPayload(payload);
24797
+ const preparedPayload = prepareMembershipPayload(channelPayload, 'channelUsers');
24798
+ const { channelUsers } = preparedPayload;
24301
24799
  const cachedAt = client.cache && Date.now();
24302
24800
  if (client.cache) {
24303
- ingestInCache(payload);
24801
+ ingestInCache(preparedPayload);
24802
+ const cacheKey = [
24803
+ 'channelUsers',
24804
+ 'query',
24805
+ Object.assign(Object.assign({}, params), { options: Object.assign({}, page) }),
24806
+ ];
24807
+ pushToCache(cacheKey, {
24808
+ channelUsers: channelUsers.map(({ channelId, userId }) => getResolver('channelUsers')({ channelId, userId })),
24809
+ paging,
24810
+ });
24304
24811
  }
24305
24812
  const nextPage = toPage(paging.next);
24306
24813
  const prevPage = toPage(paging.previous);
24307
- return { data: channelUsers, cachedAt, nextPage, prevPage };
24814
+ return {
24815
+ data: channelUsers,
24816
+ cachedAt,
24817
+ nextPage,
24818
+ prevPage,
24819
+ };
24308
24820
  };
24309
24821
  /**
24310
24822
  * ```js
@@ -24320,9 +24832,30 @@ const queryChannelMembers = async (query) => {
24320
24832
  * @category Post API
24321
24833
  */
24322
24834
  queryChannelMembers.locally = (query) => {
24835
+ var _a, _b;
24323
24836
  const client = getActiveClient();
24324
- client.log('channel/queryChannelMembers', query);
24325
- // TODO
24837
+ client.log('channel/queryChannelMembers.locally', query);
24838
+ if (!client.cache)
24839
+ return;
24840
+ const { page } = query, params = __rest(query, ["page"]);
24841
+ const cacheKey = [
24842
+ 'channelUsers',
24843
+ 'query',
24844
+ Object.assign(Object.assign({}, params), { options: Object.assign({}, page) }),
24845
+ ];
24846
+ const { data, cachedAt } = (_a = pullFromCache(cacheKey)) !== null && _a !== void 0 ? _a : {};
24847
+ if (!(data === null || data === void 0 ? void 0 : data.channelUsers.length))
24848
+ return;
24849
+ const channelUsers = data.channelUsers
24850
+ // ck -> cacheKey, abbrevated to avoid confusion from the above cache key
24851
+ .map(ck => pullFromCache(['channelUsers', 'get', ck]))
24852
+ .filter(Boolean)
24853
+ .map(({ data }) => data);
24854
+ const prevPage = toPage(data === null || data === void 0 ? void 0 : data.paging.previous);
24855
+ const nextPage = toPage(data === null || data === void 0 ? void 0 : data.paging.next);
24856
+ return channelUsers.length === ((_b = data === null || data === void 0 ? void 0 : data.channelUsers) === null || _b === void 0 ? void 0 : _b.length)
24857
+ ? { data: channelUsers, cachedAt, prevPage, nextPage }
24858
+ : undefined;
24326
24859
  };
24327
24860
 
24328
24861
  /**
@@ -24343,13 +24876,14 @@ queryChannelMembers.locally = (query) => {
24343
24876
  const addChannelMembers = async (channelId, userIds) => {
24344
24877
  const client = getActiveClient();
24345
24878
  client.log('channel/addChannelMembers', channelId, userIds);
24346
- const { data } = await client.http.post(`/api/v3/channels/${encodeURIComponent(channelId)}/users`, { channelId, userIds });
24879
+ const { data: payload } = await client.http.post(`/api/v3/channels/${encodeURIComponent(channelId)}/users`, { channelId, userIds });
24880
+ const data = prepareChannelPayload(payload);
24347
24881
  if (client.cache)
24348
24882
  ingestInCache(data);
24349
- fireEvent('v3.channel.didAddUsers', {
24350
- channels: data.channels,
24351
- channelUsers: data.channelUsers,
24352
- });
24883
+ /*
24884
+ * should fire event for each user that was added
24885
+ */
24886
+ userIds.forEach(id => fireEvent('v3.channel.didAddUsers', Object.assign(Object.assign({}, data), { channelUsers: data.channelUsers.filter(u => u.userId === id) })));
24353
24887
  const { channelUsers } = data;
24354
24888
  return !!channelUsers.find(channelUser => channelUser.channelId === channelId && channelUser.membership === 'member');
24355
24889
  };
@@ -24372,13 +24906,14 @@ const addChannelMembers = async (channelId, userIds) => {
24372
24906
  const removeChannelMembers = async (channelId, userIds) => {
24373
24907
  const client = getActiveClient();
24374
24908
  client.log('channel/removeChannelMembers', channelId, userIds);
24375
- const { data } = await client.http.delete(`/api/v3/channels/${encodeURIComponent(channelId)}/users`, { data: { channelId, userIds } });
24909
+ const { data: payload } = await client.http.delete(`/api/v3/channels/${encodeURIComponent(channelId)}/users`, { data: { channelId, userIds } });
24910
+ const data = prepareChannelPayload(payload);
24376
24911
  if (client.cache)
24377
24912
  ingestInCache(data);
24378
- fireEvent('v3.channel.didRemoveUsers', {
24379
- channels: data.channels,
24380
- channelUsers: data.channelUsers,
24381
- });
24913
+ /*
24914
+ * should fire event for each user that was removed
24915
+ */
24916
+ userIds.forEach(id => fireEvent('v3.channel.didRemoveUsers', Object.assign(Object.assign({}, data), { channelUsers: data.channelUsers.filter(u => u.userId === id) })));
24382
24917
  const { channelUsers } = data;
24383
24918
  return !!channelUsers.find(channelUser => channelUser.channelId === channelId && channelUser.membership !== 'member');
24384
24919
  };
@@ -24402,7 +24937,8 @@ const removeChannelMembers = async (channelId, userIds) => {
24402
24937
  const addChannelMembersRole = async (channelId, roleId, userIds) => {
24403
24938
  const client = getActiveClient();
24404
24939
  client.log('channel/addChannelMembersRole', channelId, roleId, userIds);
24405
- const { data } = await client.http.post(`/api/v3/channels/${encodeURIComponent(channelId)}/users/roles`, { channelId, role: roleId, userIds });
24940
+ const { data: payload } = await client.http.post(`/api/v3/channels/${encodeURIComponent(channelId)}/users/roles`, { channelId, role: roleId, userIds });
24941
+ const data = prepareChannelPayload(payload);
24406
24942
  if (client.cache)
24407
24943
  ingestInCache(data);
24408
24944
  const { channelUsers } = data;
@@ -24428,7 +24964,8 @@ const addChannelMembersRole = async (channelId, roleId, userIds) => {
24428
24964
  const removeChannelMembersRole = async (channelId, roleId, userIds) => {
24429
24965
  const client = getActiveClient();
24430
24966
  client.log('channel/removeChannelMembersRole', channelId, roleId, userIds);
24431
- const { data } = await client.http.delete(`/api/v3/channels/${encodeURIComponent(channelId)}/users/roles`, { data: { channelId, role: roleId, userIds } });
24967
+ const { data: payload } = await client.http.delete(`/api/v3/channels/${encodeURIComponent(channelId)}/users/roles`, { data: { channelId, role: roleId, userIds } });
24968
+ const data = prepareChannelPayload(payload);
24432
24969
  if (client.cache)
24433
24970
  ingestInCache(data);
24434
24971
  const { channelUsers } = data;
@@ -24442,57 +24979,150 @@ const removeChannelMembersRole = async (channelId, roleId, userIds) => {
24442
24979
  * await banChannelMembers('channel-id-1', ['userId1', 'userId2'])
24443
24980
  * ```
24444
24981
  *
24445
- * @param channelId of {@link Amity.Channel} from which the users should be banned
24446
- * @param userIds of the {@link Amity.User}'s to be banned
24447
- * @returns the updated {@link Amity.Membership}'s object
24982
+ * @param channelId of {@link Amity.Channel} from which the users should be banned
24983
+ * @param userIds of the {@link Amity.User}'s to be banned
24984
+ * @returns the updated {@link Amity.Membership}'s object
24985
+ *
24986
+ * @category Channel API
24987
+ * @async
24988
+ * */
24989
+ const banChannelMembers = async (channelId, userIds) => {
24990
+ const client = getActiveClient();
24991
+ client.log('channel/banChannelMembers', { userIds, channelId });
24992
+ const { data: payload } = await client.http.put(`/api/v3/channels/${channelId}/users/ban`, {
24993
+ userIds,
24994
+ });
24995
+ const channelPayload = prepareChannelPayload(payload);
24996
+ const preparedPayload = prepareMembershipPayload(channelPayload, 'channelUsers');
24997
+ const { channelUsers } = preparedPayload;
24998
+ const cachedAt = client.cache && Date.now();
24999
+ if (client.cache)
25000
+ ingestInCache(preparedPayload, { cachedAt });
25001
+ return {
25002
+ data: channelUsers === null || channelUsers === void 0 ? void 0 : channelUsers.filter(user => user.membership === 'banned'),
25003
+ cachedAt,
25004
+ };
25005
+ };
25006
+
25007
+ /**
25008
+ * ```js
25009
+ * import { unbanChannelMembers } from '@amityco/ts-sdk'
25010
+ *
25011
+ * await unbanChannelMembers('channel-id-1', ['userId1', 'userId2'])
25012
+ * ```
25013
+ *
25014
+ * @param channelId of {@link Amity.Channel} where the users should be unbanned
25015
+ * @param userIds of the {@link Amity.User}'s to be unbanned
25016
+ * @returns the updated {@link Amity.Membership}'s object
25017
+ *
25018
+ * @category Channel API
25019
+ * @async
25020
+ * */
25021
+ const unbanChannelMembers = async (channelId, userIds) => {
25022
+ const client = getActiveClient();
25023
+ client.log('channel/unbanChannelMembers', { userIds, channelId });
25024
+ const { data: payload } = await client.http.put(`/api/v3/channels/${encodeURIComponent(channelId)}/users/unban`, {
25025
+ userIds,
25026
+ });
25027
+ const channelPayload = prepareChannelPayload(payload);
25028
+ const preparedPayload = prepareMembershipPayload(channelPayload, 'channelUsers');
25029
+ const cachedAt = client.cache && Date.now();
25030
+ if (client.cache)
25031
+ ingestInCache(preparedPayload, { cachedAt });
25032
+ const { channelUsers } = preparedPayload;
25033
+ return {
25034
+ data: channelUsers === null || channelUsers === void 0 ? void 0 : channelUsers.filter(user => user.membership === 'member'),
25035
+ cachedAt,
25036
+ };
25037
+ };
25038
+
25039
+ /**
25040
+ * ```js
25041
+ * import { startReading } from '@amityco/ts-sdk'
25042
+ * const success = await startReading('foo')
25043
+ * ```
25044
+ *
25045
+ * Mark all messages as read and start reading message inside channel
25046
+ *
25047
+ * @param {string} channelId - The channel ID to start reading.
25048
+ * @param {string} userId - The user ID of channel member.
25049
+ * @return {Promise<boolean>>} A success boolean if the channel reading of the channel had begun.
25050
+ *
25051
+ * @category Message API
25052
+ * @async
25053
+ */
25054
+ const startReading = async (channelId, userId = getActiveClient().userId) => {
25055
+ const client = getActiveClient();
25056
+ client.log('message/startReading', { channelId });
25057
+ const result = await synchronousWSCall(client, 'channel.startReading', {
25058
+ channelId,
25059
+ });
25060
+ // TODO: Implement optimistic update for `readyToSegment`
25061
+ // const cachedChannel = pullFromCache<Amity.Channel>(['channel', 'get', channelId]);
25062
+ // const cachedMember = pullFromCache<Amity.Membership<'channel'>>(['channelUsers', 'get', userId]);
25063
+ //
25064
+ // if (cachedChannel && cachedMember) {
25065
+ // fireEvent('v3.channel.didMarkSeen', {
25066
+ // channelUsers: [
25067
+ // {
25068
+ // ...cachedMember.data,
25069
+ // readToSegment: cachedChannel.data.messageCount ?? 0,
25070
+ // },
25071
+ // ],
25072
+ // channels: [],
25073
+ // users: [],
25074
+ // files: [],
25075
+ // });
25076
+ // }
25077
+ return !!result;
25078
+ };
25079
+
25080
+ /**
25081
+ * ```js
25082
+ * import { stopReading } from '@amityco/ts-sdk'
25083
+ * const success = await stopReading('foo')
25084
+ * ```
25085
+ *
25086
+ * Stop reading message inside channel
25087
+ *
25088
+ * @param {string} channelId - The channel ID to stop reading.
25089
+ * @return {Promise<boolean>>} A success boolean if the channel reading was halted.
24448
25090
  *
24449
- * @category Channel API
25091
+ * @category Message API
24450
25092
  * @async
24451
- * */
24452
- const banChannelMembers = async (channelId, userIds) => {
25093
+ */
25094
+ const stopReading = async (channelId) => {
24453
25095
  const client = getActiveClient();
24454
- client.log('channel/banChannelMembers', { userIds, channelId });
24455
- const payload = await client.http.put(`/api/v3/channels/${channelId}/users/ban`, {
24456
- userIds,
25096
+ client.log('message/stopReading', { channelId });
25097
+ const result = await synchronousWSCall(client, 'channel.stopReading', {
25098
+ channelId,
24457
25099
  });
24458
- const cachedAt = client.cache && Date.now();
24459
- if (client.cache)
24460
- ingestInCache(payload.data, { cachedAt });
24461
- const { channelUsers } = payload.data;
24462
- return {
24463
- data: channelUsers === null || channelUsers === void 0 ? void 0 : channelUsers.filter(user => user.membership === 'banned'),
24464
- cachedAt,
24465
- };
25100
+ return !!result;
24466
25101
  };
24467
25102
 
24468
25103
  /**
24469
25104
  * ```js
24470
- * import { unbanChannelMembers } from '@amityco/ts-sdk'
24471
- *
24472
- * await unbanChannelMembers('channel-id-1', ['userId1', 'userId2'])
25105
+ * import { onChannelCreated } from '@amityco/ts-sdk'
25106
+ * const dispose = onChannelCreated(channel => {
25107
+ * // ...
25108
+ * })
24473
25109
  * ```
24474
25110
  *
24475
- * @param channelId of {@link Amity.Channel} where the users should be unbanned
24476
- * @param userIds of the {@link Amity.User}'s to be unbanned
24477
- * @returns the updated {@link Amity.Membership}'s object
25111
+ * Fired when any {@link Amity.Channel} have been created
24478
25112
  *
24479
- * @category Channel API
24480
- * @async
24481
- * */
24482
- const unbanChannelMembers = async (channelId, userIds) => {
25113
+ * @param callback The function to call when the event was fired
25114
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
25115
+ *
25116
+ * @category Channel Events
25117
+ */
25118
+ const onChannelCreated = (callback) => {
24483
25119
  const client = getActiveClient();
24484
- client.log('channel/unbanChannelMembers', { userIds, channelId });
24485
- const payload = await client.http.put(`/api/v3/channels/${encodeURIComponent(channelId)}/users/unban`, {
24486
- userIds,
24487
- });
24488
- const cachedAt = client.cache && Date.now();
24489
- if (client.cache)
24490
- ingestInCache(payload.data, { cachedAt });
24491
- const { channelUsers } = payload.data;
24492
- return {
24493
- data: channelUsers === null || channelUsers === void 0 ? void 0 : channelUsers.filter(user => user.membership === 'member'),
24494
- cachedAt,
25120
+ const filter = (payload) => {
25121
+ const data = prepareChannelPayload(payload);
25122
+ ingestInCache(data);
25123
+ callback(data.channels[0]);
24495
25124
  };
25125
+ return createEventSubscriber(client, 'onChannelCreated', 'v3.channel.didCreate', filter);
24496
25126
  };
24497
25127
 
24498
25128
  /**
@@ -24513,8 +25143,9 @@ const unbanChannelMembers = async (channelId, userIds) => {
24513
25143
  const onChannelUpdated = (callback) => {
24514
25144
  const client = getActiveClient();
24515
25145
  const filter = (payload) => {
24516
- ingestInCache(payload);
24517
- callback(payload.channels[0]);
25146
+ const data = prepareChannelPayload(payload);
25147
+ ingestInCache(data);
25148
+ callback(data.channels[0]);
24518
25149
  };
24519
25150
  return createEventSubscriber(client, 'onChannelUpdated', 'v3.channel.didUpdate', filter);
24520
25151
  };
@@ -24537,8 +25168,9 @@ const onChannelUpdated = (callback) => {
24537
25168
  const onChannelDeleted = (callback) => {
24538
25169
  const client = getActiveClient();
24539
25170
  const filter = (payload) => {
24540
- ingestInCache(payload);
24541
- callback(payload.channels[0]);
25171
+ const data = prepareChannelPayload(payload);
25172
+ ingestInCache(data);
25173
+ callback(data.channels[0]);
24542
25174
  };
24543
25175
  return createEventSubscriber(client, 'onChannelDeleted', 'v3.channel.didDelete', filter);
24544
25176
  };
@@ -24561,8 +25193,9 @@ const onChannelDeleted = (callback) => {
24561
25193
  const onChannelJoined = (callback) => {
24562
25194
  const client = getActiveClient();
24563
25195
  const filter = (payload) => {
24564
- ingestInCache(payload);
24565
- callback(payload.channels[0]);
25196
+ const data = prepareChannelPayload(payload);
25197
+ ingestInCache(data);
25198
+ callback(data.channels[0]);
24566
25199
  };
24567
25200
  return createEventSubscriber(client, 'onChannelJoined', 'v3.channel.didJoin', filter);
24568
25201
  };
@@ -24585,8 +25218,9 @@ const onChannelJoined = (callback) => {
24585
25218
  const onChannelLeft = (callback) => {
24586
25219
  const client = getActiveClient();
24587
25220
  const filter = (payload) => {
24588
- ingestInCache(payload);
24589
- callback(payload.channels[0]);
25221
+ const data = prepareChannelPayload(payload);
25222
+ ingestInCache(data);
25223
+ callback(data.channels[0]);
24590
25224
  };
24591
25225
  return createEventSubscriber(client, 'onChannelLeft', 'v3.channel.didLeave', filter);
24592
25226
  };
@@ -24609,8 +25243,11 @@ const onChannelLeft = (callback) => {
24609
25243
  const onChannelMemberAdded = (callback) => {
24610
25244
  const client = getActiveClient();
24611
25245
  const filter = (payload) => {
24612
- ingestInCache(payload);
24613
- callback(payload.channels[0], payload.channelUsers[0]);
25246
+ const channelPayload = prepareChannelPayload(payload);
25247
+ const preparedPayload = prepareMembershipPayload(channelPayload, 'channelUsers');
25248
+ const { channels, channelUsers } = preparedPayload;
25249
+ ingestInCache(preparedPayload);
25250
+ callback(channels[0], channelUsers.find(cu => cu.membership === 'member'));
24614
25251
  };
24615
25252
  return createEventSubscriber(client, 'onChannelMemberAdded', 'v3.channel.didAddUsers', filter);
24616
25253
  };
@@ -24633,12 +25270,95 @@ const onChannelMemberAdded = (callback) => {
24633
25270
  const onChannelMemberRemoved = (callback) => {
24634
25271
  const client = getActiveClient();
24635
25272
  const filter = (payload) => {
24636
- ingestInCache(payload);
24637
- callback(payload.channels[0], payload.channelUsers[0]);
25273
+ const channelPayload = prepareChannelPayload(payload);
25274
+ const preparedPayload = prepareMembershipPayload(channelPayload, 'channelUsers');
25275
+ const { channels, channelUsers } = preparedPayload;
25276
+ ingestInCache(preparedPayload);
25277
+ callback(channels[0], channelUsers[0]);
24638
25278
  };
24639
25279
  return createEventSubscriber(client, 'onChannelMemberRemoved', 'v3.channel.didRemoveUsers', filter);
24640
25280
  };
24641
25281
 
25282
+ /**
25283
+ * ```js
25284
+ * import { onChannelMemberBanned } from '@amityco/ts-sdk'
25285
+ * const dispose = onChannelMemberBanned((channel, member) => {
25286
+ * // ...
25287
+ * })
25288
+ * ```
25289
+ *
25290
+ * Fired when any {@link Amity.User} has been banned from any {@link Amity.Channel}
25291
+ *
25292
+ * @param callback The function to call when the event was fired
25293
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
25294
+ *
25295
+ * @category Channel Events
25296
+ */
25297
+ const onChannelMemberBanned = (callback) => {
25298
+ const client = getActiveClient();
25299
+ const filter = (payload) => {
25300
+ const channelPayload = prepareChannelPayload(payload);
25301
+ const preparedPayload = prepareMembershipPayload(channelPayload, 'channelUsers');
25302
+ const { channels, channelUsers } = preparedPayload;
25303
+ ingestInCache(preparedPayload);
25304
+ callback(channels[0], channelUsers.find(cu => cu.membership === 'banned'));
25305
+ };
25306
+ return createEventSubscriber(client, 'onChannelMemberBanned', 'v3.channel.didBan', filter);
25307
+ };
25308
+
25309
+ /**
25310
+ * ```js
25311
+ * import { onChannelMemberUnbanned } from '@amityco/ts-sdk'
25312
+ * const dispose = onChannelMemberUnbanned((channel, member) => {
25313
+ * // ...
25314
+ * })
25315
+ * ```
25316
+ *
25317
+ * Fired when any {@link Amity.User} has been unbanned from any {@link Amity.Channel}
25318
+ *
25319
+ * @param callback The function to call when the event was fired
25320
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
25321
+ *
25322
+ * @category Channel Events
25323
+ */
25324
+ const onChannelMemberUnbanned = (callback) => {
25325
+ const client = getActiveClient();
25326
+ const filter = (payload) => {
25327
+ const channelPayload = prepareChannelPayload(payload);
25328
+ const preparedPayload = prepareMembershipPayload(channelPayload, 'channelUsers');
25329
+ const { channels, channelUsers } = preparedPayload;
25330
+ ingestInCache(preparedPayload);
25331
+ callback(channels[0], channelUsers.find(cu => cu.membership === 'none'));
25332
+ };
25333
+ return createEventSubscriber(client, 'onChannelMemberUnbanned', 'v3.channel.didUnban', filter);
25334
+ };
25335
+
25336
+ /**
25337
+ * ```js
25338
+ * import { onChannelMemberRead } from '@amityco/ts-sdk'
25339
+ * const dispose = onChannelMemberRead((channel, member) => {
25340
+ * // ...
25341
+ * })
25342
+ * ```
25343
+ *
25344
+ * Fired when any {@link Amity.User} has been read from any {@link Amity.Channel}
25345
+ *
25346
+ * @param callback The function to call when the event was fired
25347
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
25348
+ *
25349
+ * @category Channel Events
25350
+ */
25351
+ const onChannelMemberRead = (callback) => {
25352
+ const client = getActiveClient();
25353
+ const filter = (payload) => {
25354
+ const channelPayload = prepareChannelPayload(payload);
25355
+ const preparedPayload = prepareMembershipPayload(channelPayload, 'channelUsers');
25356
+ ingestInCache(preparedPayload);
25357
+ callback(preparedPayload.channels[0], preparedPayload.channelUsers[0]);
25358
+ };
25359
+ return createEventSubscriber(client, 'onChannelMemberRead', 'v3.channel.didMarkSeen', filter);
25360
+ };
25361
+
24642
25362
  /**
24643
25363
  * ```js
24644
25364
  * import { observeChannel } from '@amityco/ts-sdk'
@@ -24671,11 +25391,281 @@ const observeChannel = (channelId, callback) => {
24671
25391
  (_b = callback.onEvent) === null || _b === void 0 ? void 0 : _b.call(callback, action, result);
24672
25392
  (_c = callback[action]) === null || _c === void 0 ? void 0 : _c.call(callback, result);
24673
25393
  };
24674
- const disposers = [];
24675
- 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')));
24676
- runQuery(createQuery(getChannel, channelId), result => result.data && router(result, 'onFetch'));
25394
+ const disposers = [];
25395
+ 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')), onChannelMemberRead(data => router({ data, loading: false, origin: 'event' }, 'onRead')));
25396
+ runQuery(createQuery(getChannel, channelId), result => result.data && router(result, 'onFetch'));
25397
+ return () => {
25398
+ log(`observeChannel(tmpid: ${timestamp}) > dispose`);
25399
+ disposers.forEach(fn => fn());
25400
+ };
25401
+ };
25402
+
25403
+ /**
25404
+ * ```js
25405
+ * import { observeChannels } from '@amityco/ts-sdk'
25406
+ *
25407
+ * let channels = []
25408
+ * const unsub = observeChannels(channel => merge(channels, channel))
25409
+ * ```
25410
+ *
25411
+ * Observe all mutations on a list of {@link Amity.Channel} for a current user
25412
+ *
25413
+ * @param callback the function to call when new data are available
25414
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the channels
25415
+ *
25416
+ * @category Channel Observer
25417
+ */
25418
+ const observeChannels = (callback) => {
25419
+ const { log } = getActiveClient();
25420
+ const timestamp = Date.now();
25421
+ log(`observeChannels(tmpid: ${timestamp}) > listen`);
25422
+ const disposers = [];
25423
+ const router = (channel, action) => {
25424
+ var _a, _b;
25425
+ if (callback instanceof Function)
25426
+ return callback(channel);
25427
+ (_a = callback.onEvent) === null || _a === void 0 ? void 0 : _a.call(callback, action, channel);
25428
+ (_b = callback[action]) === null || _b === void 0 ? void 0 : _b.call(callback, channel);
25429
+ };
25430
+ 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')), onChannelMemberRead(data => router(data, 'onRead')));
25431
+ return () => {
25432
+ log(`observeChannels(tmpid: ${timestamp}) > dispose`);
25433
+ disposers.forEach(fn => fn());
25434
+ };
25435
+ };
25436
+
25437
+ /**
25438
+ * ```js
25439
+ * import { liveChannels } from '@amityco/ts-sdk'
25440
+ *
25441
+ * let channels = []
25442
+ * const unsub = liveChannels({
25443
+ * displayName: Amity.Channel['displayName'],
25444
+ * }, response => merge(channels, response.data))
25445
+ * ```
25446
+ *
25447
+ * Observe all mutations on a list of {@link Amity.Channel}s
25448
+ *
25449
+ * @param params for querying channels
25450
+ * @param callback the function to call when new data are available
25451
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the channels
25452
+ *
25453
+ * @category Channel Live Collection
25454
+ */
25455
+ const liveChannels = (params, callback, config) => {
25456
+ const { log, cache, userId } = getActiveClient();
25457
+ if (!cache) {
25458
+ console.log(ENABLE_CACHE_MESSAGE);
25459
+ }
25460
+ const timestamp = Date.now();
25461
+ log(`liveChannels(tmpid: ${timestamp}) > listen`);
25462
+ const { limit: queryLimit } = params, queryParams = __rest(params, ["limit"]);
25463
+ const limit = queryLimit !== null && queryLimit !== void 0 ? queryLimit : COLLECTION_DEFAULT_PAGINATION_LIMIT;
25464
+ const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config !== null && config !== void 0 ? config : {};
25465
+ const disposers = [];
25466
+ const cacheKey = ['channel', 'collection', {}];
25467
+ const responder = (data) => {
25468
+ var _a, _b;
25469
+ let channels = (_a = data.data
25470
+ .map(channelId => pullFromCache(['channel', 'get', channelId]))
25471
+ .filter(Boolean)
25472
+ .map(({ data }) => data)) !== null && _a !== void 0 ? _a : [];
25473
+ channels = filterByPropEquality(channels, 'isDeleted', params.isDeleted);
25474
+ channels = filterByPropEquality(channels, 'displayName', params.displayName);
25475
+ if (params.types) {
25476
+ channels = channels.filter(c => { var _a; return (_a = params.types) === null || _a === void 0 ? void 0 : _a.includes(c.type); });
25477
+ }
25478
+ if (params.tags) {
25479
+ 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); }); });
25480
+ }
25481
+ if (params.excludeTags) {
25482
+ 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); })); });
25483
+ }
25484
+ // userId is required to be able to filter channel by current active user
25485
+ if (params.membership && userId) {
25486
+ channels = filterByChannelMembership(channels, params.membership, userId);
25487
+ }
25488
+ const sortBy = params.sortBy || 'lastCreated';
25489
+ if (sortBy === 'lastCreated' || sortBy === 'firstCreated') {
25490
+ channels = channels.sort(sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated);
25491
+ }
25492
+ /*
25493
+ * The server returns channels with empty | null displayName's first before
25494
+ * returning sorted list of channels with displayNames
25495
+ *
25496
+ * This section needs to be updated as displayNames can be null as well
25497
+ */
25498
+ if (sortBy === 'displayName') {
25499
+ channels = channels
25500
+ // this needs to be aligned with the backend data type
25501
+ .map(c => (c.displayName ? c : Object.assign(Object.assign({}, c), { displayName: '' })))
25502
+ // @ts-ignore
25503
+ .sort(sortByDisplayName);
25504
+ }
25505
+ callback({
25506
+ onNextPage: onFetch,
25507
+ data: channels,
25508
+ hasNextPage: !!((_b = data.params) === null || _b === void 0 ? void 0 : _b.page),
25509
+ loading: data.loading,
25510
+ error: data.error,
25511
+ });
25512
+ };
25513
+ const realtimeRouter = (channel, action) => {
25514
+ var _a;
25515
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
25516
+ if (!collection)
25517
+ return;
25518
+ if (action === 'onCreate') {
25519
+ collection.data = [...new Set([channel.channelId, ...collection.data])];
25520
+ /*
25521
+ * if the filter isDeleted is set, only collection item must be updated and not
25522
+ * the collection
25523
+ */
25524
+ }
25525
+ else if (action === 'onDelete' && !params.isDeleted) {
25526
+ collection.data = collection.data.filter(c => c !== channel.channelId);
25527
+ }
25528
+ pushToCache(cacheKey, collection);
25529
+ responder(collection);
25530
+ };
25531
+ const onFetch = () => {
25532
+ var _a, _b, _c;
25533
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
25534
+ const channels = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
25535
+ if (channels.length > 0 && !(collection === null || collection === void 0 ? void 0 : collection.params.page))
25536
+ return;
25537
+ 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 } }));
25538
+ runQuery(query, ({ data: result, error, loading, nextPage: page }) => {
25539
+ const data = {
25540
+ loading,
25541
+ error,
25542
+ params: { page },
25543
+ data: channels,
25544
+ };
25545
+ if (result) {
25546
+ data.data = [...new Set([...channels, ...result.map(getResolver('channel'))])];
25547
+ }
25548
+ pushToCache(cacheKey, data);
25549
+ responder(data);
25550
+ }, queryOptions(policy));
25551
+ };
25552
+ disposers.push(onChannelCreated(channel => realtimeRouter(channel, 'onCreate')), onChannelDeleted(channel => realtimeRouter(channel, 'onDelete')), onChannelUpdated(channel => realtimeRouter(channel, 'onUpdate')), onChannelMemberRead(channel => realtimeRouter(channel, 'onRead')));
25553
+ onFetch();
25554
+ return () => {
25555
+ log(`liveChannels(tmpid: ${timestamp}) > dispose`);
25556
+ disposers.forEach(fn => fn());
25557
+ };
25558
+ };
25559
+
25560
+ /**
25561
+ * ```js
25562
+ * import { liveChannelMembers } from '@amityco/ts-sdk'
25563
+ *
25564
+ * let channelMembers = []
25565
+ * const unsub = liveChannelMembers({
25566
+ * channelId: Amity.Channel['channelId'],
25567
+ * }, response => merge(channelMembers, response.data))
25568
+ * ```
25569
+ *
25570
+ * Observe all mutations on a list of {@link Amity.ChannelUser}s
25571
+ *
25572
+ * @param params for querying channel users
25573
+ * @param callback the function to call when new data are available
25574
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the channel users
25575
+ *
25576
+ * @category Channel Live Collection
25577
+ */
25578
+ const liveChannelMembers = (params, callback, config) => {
25579
+ const { log, cache } = getActiveClient();
25580
+ if (!cache) {
25581
+ console.log(ENABLE_CACHE_MESSAGE);
25582
+ }
25583
+ const timestamp = Date.now();
25584
+ log(`liveChannelMembers(tmpid: ${timestamp}) > listen`);
25585
+ const { limit: queryLimit } = params, queryParams = __rest(params, ["limit"]);
25586
+ const limit = queryLimit !== null && queryLimit !== void 0 ? queryLimit : COLLECTION_DEFAULT_PAGINATION_LIMIT;
25587
+ const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config !== null && config !== void 0 ? config : {};
25588
+ const disposers = [];
25589
+ const cacheKey = ['channelUsers', 'collection', { channelId: params.channelId }];
25590
+ const responder = (data) => {
25591
+ var _a, _b;
25592
+ let channelMembers = (_a = data.data
25593
+ .map(id => pullFromCache(['channelUsers', 'get', id]))
25594
+ .filter(Boolean)
25595
+ .map(({ data }) => data)) !== null && _a !== void 0 ? _a : [];
25596
+ channelMembers = filterByPropEquality(channelMembers, 'roles', params.roles);
25597
+ if (params.memberships) {
25598
+ /*
25599
+ * even though membership includes muted as a possible value
25600
+ * when querying the server.
25601
+ * Muted is specified under seperarte property namely isMuted
25602
+ * Hence why I've seperately checked for it's equality
25603
+ */
25604
+ if (params.memberships.some(m => ['member', 'banned'].includes(m))) {
25605
+ channelMembers = filterByPropInclusion(channelMembers, 'membership', params.memberships);
25606
+ }
25607
+ if (params.memberships.includes('muted')) {
25608
+ channelMembers = filterByPropEquality(channelMembers, 'isMuted', true);
25609
+ }
25610
+ }
25611
+ if (params.search) {
25612
+ const containsMatcher = new RegExp(params.search);
25613
+ channelMembers = channelMembers.filter(m => m.userId.match(containsMatcher));
25614
+ }
25615
+ // sort, 'lastCreated' is the default sort order
25616
+ const sortBy = params.sortBy ? params.sortBy : 'lastCreated';
25617
+ channelMembers = channelMembers.sort(sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated);
25618
+ callback({
25619
+ onNextPage: onFetch,
25620
+ data: channelMembers,
25621
+ hasNextPage: !!((_b = data.params) === null || _b === void 0 ? void 0 : _b.page),
25622
+ loading: data.loading,
25623
+ error: data.error,
25624
+ });
25625
+ };
25626
+ const realtimeRouter = (channelMember, action) => {
25627
+ var _a;
25628
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
25629
+ if (!collection)
25630
+ return;
25631
+ const channelMemberCacheId = getResolver('channelUsers')({
25632
+ channelId: params.channelId,
25633
+ userId: channelMember.userId,
25634
+ });
25635
+ if (action === 'onMemberAdded') {
25636
+ collection.data = [...new Set([channelMemberCacheId, ...collection.data])];
25637
+ }
25638
+ if (action === 'onMemberRemoved') {
25639
+ collection.data = collection.data.filter(m => m !== channelMemberCacheId);
25640
+ }
25641
+ pushToCache(cacheKey, collection);
25642
+ responder(collection);
25643
+ };
25644
+ const onFetch = () => {
25645
+ var _a, _b, _c;
25646
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
25647
+ const channelMembers = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
25648
+ if (channelMembers.length > 0 && !(collection === null || collection === void 0 ? void 0 : collection.params.page))
25649
+ return;
25650
+ 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 } }));
25651
+ runQuery(query, ({ data: result, error, loading, nextPage: page }) => {
25652
+ const data = {
25653
+ loading,
25654
+ error,
25655
+ params: { page },
25656
+ data: channelMembers,
25657
+ };
25658
+ if (result) {
25659
+ data.data = [...new Set([...channelMembers, ...result.map(getResolver('channelUsers'))])];
25660
+ }
25661
+ pushToCache(cacheKey, data);
25662
+ responder(data);
25663
+ }, queryOptions(policy));
25664
+ };
25665
+ disposers.push(onChannelMemberAdded((_, member) => realtimeRouter(member, 'onMemberAdded')), onChannelMemberRemoved((_, member) => realtimeRouter(member, 'onMemberRemoved')), onChannelMemberBanned((_, member) => realtimeRouter(member, 'onChannelMemberBanned')), onChannelMemberUnbanned((_, member) => realtimeRouter(member, 'onChannelMemberUnbanned')), onChannelMemberRead((_, member) => realtimeRouter(member, 'onMemberRead')));
25666
+ onFetch();
24677
25667
  return () => {
24678
- log(`observeChannel(tmpid: ${timestamp}) > dispose`);
25668
+ log(`liveChannelMembers(tmpid: ${timestamp}) > dispose`);
24679
25669
  disposers.forEach(fn => fn());
24680
25670
  };
24681
25671
  };
@@ -24757,6 +25747,190 @@ const onMessageDeleted = (callback) => {
24757
25747
  return createEventSubscriber(client, 'message/onMessageDeleted', 'v3.message.didDelete', filter);
24758
25748
  };
24759
25749
 
25750
+ /**
25751
+ * ```js
25752
+ * import { onMessageFetched } from '@amityco/ts-sdk'
25753
+ * const dispose = onMessageFetched(message => {
25754
+ * // ...
25755
+ * })
25756
+ * ```
25757
+ *
25758
+ * Fired when an {@link Amity.Message} has been fetched
25759
+ *
25760
+ * @param callback The function to call when the event was fired
25761
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
25762
+ *
25763
+ * @category Message Events
25764
+ */
25765
+ const onMessageFetched = (callback) => {
25766
+ const client = getActiveClient();
25767
+ const filter = (payload) => {
25768
+ ingestInCache(payload);
25769
+ callback(payload.messages[0]);
25770
+ };
25771
+ return createEventSubscriber(client, 'message/onMessageFetched', 'v3.message.didFetch', filter);
25772
+ };
25773
+
25774
+ /**
25775
+ * ```js
25776
+ * import { liveMessage } from '@amityco/ts-sdk'
25777
+ *
25778
+ * let messages = []
25779
+ * const unsub = liveMessage(messageId, response => merge(messages, response.data))
25780
+ * ```
25781
+ *
25782
+ * Observe all mutation on a given {@link Amity.Message}
25783
+ *
25784
+ * @param messageId the ID of the message to observe
25785
+ * @param callback the function to call when new data are available
25786
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the messages
25787
+ *
25788
+ * @category Message Live Object
25789
+ */
25790
+ const liveMessage = (messageId, callback) => {
25791
+ const { log, cache } = getActiveClient();
25792
+ let message;
25793
+ let isUnsyncedObject = false;
25794
+ if (!cache) {
25795
+ console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
25796
+ }
25797
+ const timestamp = Date.now();
25798
+ log(`liveMessage(tmpid: ${timestamp}) > listen`);
25799
+ const disposers = [];
25800
+ const dispatcher = (data) => {
25801
+ var _a;
25802
+ // we check updatedAt to see if the current snapshot is new so
25803
+ // we won't send old data back, only fresh new data
25804
+ 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')
25805
+ return;
25806
+ callback(data);
25807
+ message = data.data;
25808
+ };
25809
+ const realtimeRouter = (message, action) => {
25810
+ dispatcher({ loading: false, data: message, origin: 'event' });
25811
+ };
25812
+ const onFetch = () => {
25813
+ const query = createQuery(getMessage, messageId, true);
25814
+ runQuery(query, ({ loading, data, error, origin, cachedAt }) => {
25815
+ if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
25816
+ dispatcher({
25817
+ data,
25818
+ origin,
25819
+ loading: false,
25820
+ error: new ASCApiError(UNSYNCED_OBJECT_CACHED_AT_MESSAGE, 800800 /* Amity.ClientError.DISALOOW_UNSYNCED_OBJECT */, "error" /* Amity.ErrorLevel.ERROR */),
25821
+ });
25822
+ isUnsyncedObject = true;
25823
+ disposers.forEach(fn => fn());
25824
+ }
25825
+ else if (!isUnsyncedObject) {
25826
+ dispatcher({ loading, data, origin, error });
25827
+ }
25828
+ if (error) {
25829
+ // Terminate observe functionality on error
25830
+ disposers.forEach(fn => fn());
25831
+ }
25832
+ });
25833
+ };
25834
+ disposers.push(onMessageFetched(message => realtimeRouter(message)), onMessageUpdated(message => realtimeRouter(message)), onMessageDeleted(message => realtimeRouter(message)));
25835
+ onFetch();
25836
+ return () => {
25837
+ log(`liveMessage(tmpid: ${timestamp}) > dispose`);
25838
+ disposers.forEach(fn => fn());
25839
+ };
25840
+ };
25841
+
25842
+ /**
25843
+ * ```js
25844
+ * import { liveMessages } from '@amityco/ts-sdk'
25845
+ *
25846
+ * let messages = []
25847
+ * const unsub = liveMessages({
25848
+ * channelId: Amity.Channel['channelId'];
25849
+ * }, response => merge(messages, response.data))
25850
+ * ```
25851
+ *
25852
+ * Observe all mutations on a list of {@link Amity.Message} for a given target object
25853
+ *
25854
+ * @param params for querying memssages from a channel
25855
+ * @param callback the function to call when new data are available
25856
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the messages
25857
+ *
25858
+ * @category Messages Live Collection
25859
+ */
25860
+ const liveMessages = (params, callback, config) => {
25861
+ const { log, cache } = getActiveClient();
25862
+ if (!cache) {
25863
+ console.log(ENABLE_CACHE_MESSAGE);
25864
+ }
25865
+ const timestamp = Date.now();
25866
+ log(`liveMessages(tmpid: ${timestamp}) > listen`);
25867
+ const { limit: queryLimit } = params, queryParams = __rest(params, ["limit"]);
25868
+ const limit = queryLimit !== null && queryLimit !== void 0 ? queryLimit : COLLECTION_DEFAULT_PAGINATION_LIMIT;
25869
+ const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config !== null && config !== void 0 ? config : {};
25870
+ const disposers = [];
25871
+ const cacheKey = ['message', 'collection', { channelId: params.channelId }];
25872
+ const responder = (data) => {
25873
+ var _a, _b;
25874
+ let messages = (_a = data.data
25875
+ .map(messageId => pullFromCache(['message', 'get', messageId]))
25876
+ .filter(Boolean)
25877
+ .map(({ data }) => data)) !== null && _a !== void 0 ? _a : [];
25878
+ /*
25879
+ * for cases when message is deleted via RTE, this flag is used to get
25880
+ * items fro cache that are deleted | !deleted
25881
+ */
25882
+ messages = filterByPropEquality(messages, 'isDeleted', params.isDeleted);
25883
+ callback({
25884
+ onNextPage: onFetch,
25885
+ data: messages,
25886
+ hasNextPage: !!((_b = data.params) === null || _b === void 0 ? void 0 : _b.page),
25887
+ loading: data.loading,
25888
+ error: data.error,
25889
+ });
25890
+ };
25891
+ const realtimeRouter = (message, action) => {
25892
+ var _a;
25893
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
25894
+ if (params.channelId !== message.channelId || !collection)
25895
+ return;
25896
+ if (action === 'onCreate') {
25897
+ collection.data = [...new Set([message.messageId, ...collection.data])];
25898
+ }
25899
+ else if (['onDelete'].includes(action)) {
25900
+ collection.data = collection.data.filter(m => m !== message.messageId);
25901
+ }
25902
+ pushToCache(cacheKey, collection);
25903
+ responder(collection);
25904
+ };
25905
+ const onFetch = () => {
25906
+ var _a, _b, _c, _d, _e;
25907
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
25908
+ const messages = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
25909
+ if (messages.length > 0 && !((_c = collection === null || collection === void 0 ? void 0 : collection.params) === null || _c === void 0 ? void 0 : _c.page))
25910
+ return;
25911
+ const query = createQuery(queryMessages, Object.assign(Object.assign({}, queryParams), { page: (_e = (_d = collection === null || collection === void 0 ? void 0 : collection.params) === null || _d === void 0 ? void 0 : _d.page) !== null && _e !== void 0 ? _e : { limit } }));
25912
+ runQuery(query, ({ data: result, error, loading, prevPage: page }) => {
25913
+ const data = {
25914
+ loading,
25915
+ error,
25916
+ params: { page },
25917
+ data: messages,
25918
+ };
25919
+ if (result) {
25920
+ data.data = [...new Set([...messages, ...result.map(getResolver('message'))])];
25921
+ }
25922
+ pushToCache(cacheKey, data);
25923
+ responder(data);
25924
+ }, queryOptions(policy));
25925
+ };
25926
+ disposers.push(onMessageFetched(message => realtimeRouter(message, 'onFetch')), onMessageCreated(message => realtimeRouter(message, 'onCreate')), onMessageDeleted(message => realtimeRouter(message, 'onDelete')), onMessageUpdated(message => realtimeRouter(message, 'onUpdate')));
25927
+ onFetch();
25928
+ return () => {
25929
+ log(`liveMessages(tmpid: ${timestamp}) > dispose`);
25930
+ disposers.forEach(fn => fn());
25931
+ };
25932
+ };
25933
+
24760
25934
  /**
24761
25935
  * ```js
24762
25936
  * import { observeMessage } from '@amityco/ts-sdk'
@@ -24779,6 +25953,7 @@ const observeMessage = (messageId, callback, policy = 'cache_then_server') => {
24779
25953
  const { log } = getActiveClient();
24780
25954
  const timestamp = Date.now();
24781
25955
  log(`observeMessage(tmpid: ${timestamp}) > listen`);
25956
+ console.log('observeMessage will be deprecated on 15th November 2022, please use liveMessage instead.');
24782
25957
  // wrapper function to make sure
24783
25958
  const router = (result, action) => {
24784
25959
  var _a, _b, _c;
@@ -24812,7 +25987,6 @@ const observeMessage = (messageId, callback, policy = 'cache_then_server') => {
24812
25987
  *
24813
25988
  * Observe all mutations on a list of {@link Amity.Message} for a given {@link Amity.Channel} object
24814
25989
  *
24815
- * @param client the client to observe the message with
24816
25990
  * @param channelId the ID of the channel where to observe the messages
24817
25991
  * @param callback the function to call when new data are available
24818
25992
  * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the messages
@@ -24843,16 +26017,17 @@ const observeMessages = (channelId, callback) => {
24843
26017
  const createCommunityEventSubscriber = (event, callback) => {
24844
26018
  const client = getActiveClient();
24845
26019
  const filter = (payload) => {
26020
+ const unpackedPayload = unpackCommunityPayload(payload);
24846
26021
  if (!client.cache) {
24847
26022
  // TODO: here we are missing specific properties here!
24848
- callback(payload.communities[0]);
26023
+ callback(unpackedPayload.communities[0]);
24849
26024
  }
24850
26025
  else {
24851
- ingestInCache(payload);
26026
+ ingestInCache(unpackedPayload);
24852
26027
  const community = pullFromCache([
24853
26028
  'community',
24854
26029
  'get',
24855
- payload.communities[0].communityId,
26030
+ unpackedPayload.communities[0].communityId,
24856
26031
  ]);
24857
26032
  callback(community.data);
24858
26033
  }
@@ -24888,21 +26063,23 @@ function getEventRelatedMember(event, payload) {
24888
26063
  const createCommunityMemberEventSubscriber = (event, callback) => {
24889
26064
  const client = getActiveClient();
24890
26065
  const filter = (payload) => {
26066
+ const communityPayload = unpackCommunityPayload(payload);
26067
+ const preparedPayload = prepareMembershipPayload(communityPayload, 'communityUsers');
24891
26068
  if (!client.cache) {
24892
26069
  // TODO: here we are missing specific properties here!
24893
- callback(payload.communities[0], getEventRelatedMember(event, payload));
26070
+ callback(preparedPayload.communities[0], getEventRelatedMember(event, preparedPayload));
24894
26071
  }
24895
26072
  else {
24896
- ingestInCache(payload);
26073
+ ingestInCache(preparedPayload);
24897
26074
  const community = pullFromCache([
24898
26075
  'community',
24899
26076
  'get',
24900
- payload.communities[0].communityId,
26077
+ preparedPayload.communities[0].communityId,
24901
26078
  ]);
24902
26079
  const member = pullFromCache([
24903
26080
  'communityUsers',
24904
26081
  'get',
24905
- getResolver('communityUsers')(getEventRelatedMember(event, payload)),
26082
+ getResolver('communityUsers')(getEventRelatedMember(event, preparedPayload)),
24906
26083
  ]);
24907
26084
  callback(community.data, member.data);
24908
26085
  }
@@ -25327,9 +26504,9 @@ const queryFollows = async (key, query) => {
25327
26504
  if (client.cache) {
25328
26505
  ingestInCache(payload, { cachedAt });
25329
26506
  const cacheKey = [
25330
- key,
26507
+ 'follow',
25331
26508
  'query',
25332
- Object.assign(Object.assign({}, params), { userId, options: Object.assign({}, page) }),
26509
+ Object.assign(Object.assign({}, params), { userId, options: Object.assign({}, page), type: key }),
25333
26510
  ];
25334
26511
  pushToCache(cacheKey, { follows: follows.map(getResolver('follow')), paging });
25335
26512
  }
@@ -25344,7 +26521,11 @@ queryFollows.locally = (key, query) => {
25344
26521
  if (!client.cache)
25345
26522
  return;
25346
26523
  const { page } = query, params = __rest(query, ["page"]);
25347
- const queryKey = [key, 'query', Object.assign(Object.assign({}, params), { options: Object.assign({}, page) })];
26524
+ const queryKey = [
26525
+ 'follow',
26526
+ 'query',
26527
+ Object.assign(Object.assign({}, params), { options: Object.assign({}, page), type: key }),
26528
+ ];
25348
26529
  const { data, cachedAt } = (_a = pullFromCache(queryKey)) !== null && _a !== void 0 ? _a : {};
25349
26530
  if (!(data === null || data === void 0 ? void 0 : data.follows.length)) {
25350
26531
  return;
@@ -25890,6 +27071,186 @@ const observeFollowings = (userId, callback) => {
25890
27071
  };
25891
27072
  };
25892
27073
 
27074
+ /**
27075
+ * ```js
27076
+ * import { liveFollowers } from '@amityco/ts-sdk'
27077
+ *
27078
+ * let followers = []
27079
+ * const unsub = liveFollowers({
27080
+ * userId: Amity.User['userId'];
27081
+ * }, response => merge(followers, response.data))
27082
+ * ```
27083
+ *
27084
+ * Observe all mutations on a list of {@link Amity.FollowStatus} followers for a given userId
27085
+ *
27086
+ * @param userId the user
27087
+ * @param callback the function to call when new data are available
27088
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the messages
27089
+ *
27090
+ * @category Followers Live Collection
27091
+ */
27092
+ const liveFollowers = (params, callback, config) => {
27093
+ const { log, cache } = getActiveClient();
27094
+ if (!cache) {
27095
+ console.log('For using Live Collection feature you need to enable Cache!');
27096
+ }
27097
+ const timestamp = Date.now();
27098
+ log(`liveFollowers(tmpid: ${timestamp}) > listen`);
27099
+ const { limit: queryLimit } = params, queryParams = __rest(params, ["limit"]);
27100
+ const limit = queryLimit !== null && queryLimit !== void 0 ? queryLimit : COLLECTION_DEFAULT_PAGINATION_LIMIT;
27101
+ const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config !== null && config !== void 0 ? config : {};
27102
+ const disposers = [];
27103
+ const cacheKey = ['follow', 'collection', { userId: params.userId, type: 'follower' }];
27104
+ const responder = (data) => {
27105
+ var _a, _b;
27106
+ let followers = (_a = data.data
27107
+ .map(key => pullFromCache(['follow', 'get', key]))
27108
+ .filter(Boolean)
27109
+ .map(({ data }) => data)) !== null && _a !== void 0 ? _a : [];
27110
+ if (params.status && params.status !== 'all') {
27111
+ followers = filterByPropEquality(followers, 'status', params.status);
27112
+ }
27113
+ callback({
27114
+ onNextPage: onFetch,
27115
+ data: followers,
27116
+ hasNextPage: !!((_b = data.params) === null || _b === void 0 ? void 0 : _b.page),
27117
+ loading: data.loading,
27118
+ error: data.error,
27119
+ });
27120
+ };
27121
+ const realtimeRouter = (followStatus, action) => {
27122
+ var _a;
27123
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
27124
+ if (params.userId !== followStatus.to || !collection)
27125
+ return;
27126
+ if (['onDeclined', 'onCanceled', 'onUnfollowed', 'onDeleted'].includes(action)) {
27127
+ collection.data = collection.data.filter(p => p !== getResolver('follow')(followStatus));
27128
+ }
27129
+ else if (['onRequested', 'onAccepted', 'onFollowed'].includes(action)) {
27130
+ collection.data = [...new Set([getResolver('follow')(followStatus), ...collection.data])];
27131
+ }
27132
+ pushToCache(cacheKey, collection);
27133
+ responder(collection);
27134
+ };
27135
+ const onFetch = () => {
27136
+ var _a, _b, _c, _d, _e;
27137
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
27138
+ const followers = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
27139
+ if (followers.length > 0 && !((_c = collection === null || collection === void 0 ? void 0 : collection.params) === null || _c === void 0 ? void 0 : _c.page))
27140
+ return;
27141
+ const query = createQuery(queryFollowers, Object.assign(Object.assign({}, queryParams), { page: (_e = (_d = collection === null || collection === void 0 ? void 0 : collection.params) === null || _d === void 0 ? void 0 : _d.page) !== null && _e !== void 0 ? _e : { limit } }));
27142
+ runQuery(query, ({ data: result, error, loading, nextPage: page }) => {
27143
+ const data = {
27144
+ loading,
27145
+ error,
27146
+ params: { page },
27147
+ data: followers,
27148
+ };
27149
+ if (result) {
27150
+ data.data = [...new Set([...followers, ...result.map(getResolver('follow'))])];
27151
+ }
27152
+ pushToCache(cacheKey, data);
27153
+ responder(data);
27154
+ }, queryOptions(policy));
27155
+ };
27156
+ 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')));
27157
+ onFetch();
27158
+ return () => {
27159
+ log(`liveFollowers(tmpid: ${timestamp}) > dispose`);
27160
+ disposers.forEach(fn => fn());
27161
+ };
27162
+ };
27163
+
27164
+ /**
27165
+ * ```js
27166
+ * import { liveFollowings } from '@amityco/ts-sdk'
27167
+ *
27168
+ * let followings = []
27169
+ * const unsub = liveFollowings({
27170
+ * userId: Amity.User['userId'];
27171
+ * }, response => merge(followings, response.data))
27172
+ * ```
27173
+ *
27174
+ * Observe all mutations on a list of {@link Amity.FollowStatus} followings for a given userId
27175
+ *
27176
+ * @param userId the user
27177
+ * @param callback the function to call when new data are available
27178
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the messages
27179
+ *
27180
+ * @category Followings Live Collection
27181
+ */
27182
+ const liveFollowings = (params, callback, config) => {
27183
+ const { log, cache } = getActiveClient();
27184
+ if (!cache) {
27185
+ console.log('For using Live Collection feature you need to enable Cache!');
27186
+ }
27187
+ const timestamp = Date.now();
27188
+ log(`liveFollowings(tmpid: ${timestamp}) > listen`);
27189
+ const { limit: queryLimit } = params, queryParams = __rest(params, ["limit"]);
27190
+ const limit = queryLimit !== null && queryLimit !== void 0 ? queryLimit : COLLECTION_DEFAULT_PAGINATION_LIMIT;
27191
+ const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config !== null && config !== void 0 ? config : {};
27192
+ const disposers = [];
27193
+ const cacheKey = ['follow', 'collection', { userId: params.userId, type: 'following' }];
27194
+ const responder = (data) => {
27195
+ var _a, _b;
27196
+ let followings = (_a = data.data
27197
+ .map(key => pullFromCache(['follow', 'get', key]))
27198
+ .filter(Boolean)
27199
+ .map(({ data }) => data)) !== null && _a !== void 0 ? _a : [];
27200
+ if (params.status && params.status !== 'all') {
27201
+ followings = filterByPropEquality(followings, 'status', params.status);
27202
+ }
27203
+ callback({
27204
+ onNextPage: onFetch,
27205
+ data: followings,
27206
+ hasNextPage: !!((_b = data.params) === null || _b === void 0 ? void 0 : _b.page),
27207
+ loading: data.loading,
27208
+ error: data.error,
27209
+ });
27210
+ };
27211
+ const realtimeRouter = (followStatus, action) => {
27212
+ var _a;
27213
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
27214
+ if (params.userId !== followStatus.from || !collection)
27215
+ return;
27216
+ if (['onDeclined', 'onCanceled', 'onUnfollowed', 'onDeleted'].includes(action)) {
27217
+ collection.data = collection.data.filter(p => p !== getResolver('follow')(followStatus));
27218
+ }
27219
+ else if (['onRequested', 'onAccepted', 'onFollowed'].includes(action)) {
27220
+ collection.data = [...new Set([getResolver('follow')(followStatus), ...collection.data])];
27221
+ }
27222
+ pushToCache(cacheKey, collection);
27223
+ responder(collection);
27224
+ };
27225
+ const onFetch = () => {
27226
+ var _a, _b, _c, _d, _e;
27227
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
27228
+ const followings = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
27229
+ if (followings.length > 0 && !((_c = collection === null || collection === void 0 ? void 0 : collection.params) === null || _c === void 0 ? void 0 : _c.page))
27230
+ return;
27231
+ const query = createQuery(queryFollowings, Object.assign(Object.assign({}, queryParams), { page: (_e = (_d = collection === null || collection === void 0 ? void 0 : collection.params) === null || _d === void 0 ? void 0 : _d.page) !== null && _e !== void 0 ? _e : { limit } }));
27232
+ runQuery(query, ({ data: result, error, loading, nextPage: page }) => {
27233
+ const data = {
27234
+ loading,
27235
+ error,
27236
+ params: { page },
27237
+ data: followings,
27238
+ };
27239
+ if (result) {
27240
+ data.data = [...new Set([...followings, ...result.map(getResolver('follow'))])];
27241
+ }
27242
+ pushToCache(cacheKey, data);
27243
+ responder(data);
27244
+ }, queryOptions(policy));
27245
+ };
27246
+ 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')));
27247
+ onFetch();
27248
+ return () => {
27249
+ log(`liveFollowings(tmpid: ${timestamp}) > dispose`);
27250
+ disposers.forEach(fn => fn());
27251
+ };
27252
+ };
27253
+
25893
27254
  /**
25894
27255
  * ```js
25895
27256
  * import { observePosts } from '@amityco/ts-sdk'
@@ -25998,7 +27359,7 @@ const observePost = (postId, callback, policy = 'cache_then_server') => {
25998
27359
  const livePosts = (params, callback, config) => {
25999
27360
  const { log, cache } = getActiveClient();
26000
27361
  if (!cache) {
26001
- console.log('For using Live Collection feature you need to enable Cache!');
27362
+ console.log(ENABLE_CACHE_MESSAGE);
26002
27363
  }
26003
27364
  const timestamp = Date.now();
26004
27365
  log(`livePosts(tmpid: ${timestamp}) > listen`);
@@ -26836,4 +28197,4 @@ const createUserToken = async (apiKey, apiRegion, params) => {
26836
28197
  return { accessToken: data.accessToken };
26837
28198
  };
26838
28199
 
26839
- export { API_REGIONS, SubscriptionLevels, VERSION$1 as VERSION, acceptFollower, addChannelMembers, addChannelMembersRole, addCommunityMembers, addCommunityMembersRoles, addReaction, approvePost, backupCache, banChannelMembers, closePoll, connectClient, createChannel, createClient, createComment, createCommunity, createFile, createImage, createMessage, createPoll, createPost, createQuery, createReport, createStream, createUserToken, createVideo, declineFollower, declinePost, deleteChannel, deleteComment, deleteCommunity, deleteFile, deleteMessage, deletePoll, deletePost, deleteReport, deleteStream, disableCache, disconnectClient, disposeStream, dropFromCache, enableCache, fileUrlWithSize, filterByPropEquality, follow, getActiveClient, getCategory, getChannel, getChannels, getComment, getCommentTopic, getComments, getCommunities, getCommunity, getCommunityTopic, getFile, getFollowInfo, getMessage, getMessages, getMyFollowersTopic, getMyFollowingsTopic, getNetworkTopic, getPoll, getPost, getPostTopic, getPosts, getRecommendedCommunities, getRole, getStream, getTopTrendingCommunities, getUser, getUserTopic, getUsers, isAfterBefore, isAfterBeforeRaw, isCachable, isConnected, isFetcher, isFresh, isLocal, isMutator, isOffline, isPaged, isReportedByMe, isSkipLimit, joinChannel, joinCommunity, leaveChannel, leaveCommunity, liveComments, livePosts, liveReactions, mergeInCache, observeChannel, observeComment, observeComments, observeCommunity, observeFile, observeFollowInfo, observeFollowers, observeFollowings, observeMessage, observeMessages, observePoll, observePost, observePosts, observeUser, onChannelDeleted, onChannelJoined, onChannelLeft, onChannelMemberAdded, onChannelMemberRemoved, onChannelUpdated, onClientBanned, onClientDisconnected, onCommentCreated, onCommentDeleted, onCommentFlagged, onCommentReactionAdded, onCommentReactionRemoved, onCommentUnflagged, onCommentUpdated, onCommunityCreated, onCommunityDeleted, onCommunityJoined, onCommunityLeft, onCommunityUpdated, onCommunityUserAdded, onCommunityUserBanned, onCommunityUserRemoved, onCommunityUserUnbanned, onConnectionError, onFollowInfoUpdated, onFollowRequestAccepted, onFollowRequestCanceled, onFollowRequestDeclined, onFollowerDeleted, onFollowerRequested, onMessageCreated, onMessageDeleted, onMessageUpdated, onPollDeleted, onPollUpdated, onPostApproved, onPostCreated, onPostDeclined, onPostDeleted, onPostFlagged, onPostReactionAdded, onPostReactionRemoved, onPostUnflagged, onPostUpdated, onReactionAdded, onReactionRemoved, onReactorAdded, onReactorRemoved, onStreamRecorded, onStreamStarted, onStreamStopped, onUserDeleted, onUserFlagCleared, onUserFlagged, onUserFollowed, onUserUnflagged, onUserUnfollowed, onUserUpdated, pullFromCache, pushToCache, queryCache, queryCategories, queryChannelMembers, queryChannels, queryComments, queryCommunities, queryCommunityMembers, queryFollowers, queryFollowings, queryGlobalFeed, queryMessages, queryOptions, queryPosts, queryReactions, queryRoles, queryStreams, queryUsers, removeChannelMembers, removeChannelMembersRole, removeCommunityMembers, removeCommunityMembersRoles, removeReaction, restoreCache, runQuery, sortByChannelSegment, sortByDisplayName, sortByFirstCreated, sortByLastActivity, sortByLastCreated, sortBySegmentNumber, subscribeTopic, toPage, toPageRaw, toToken, unbanChannelMembers, unfollow, updateChannel, updateComment, updateCommunity, updateMessage, updatePost, updateStream, updateUser, upsertInCache, votePoll, wipeCache };
28200
+ export { API_REGIONS, CommunityPostSettingMaps, CommunityPostSettings, ContentFeedType, DefaultCommunityPostSetting, FileType, MessageContentType, PostContentType, SubscriptionLevels, VERSION$1 as VERSION, VideoResolution, VideoSize, VideoTranscodingStatus, acceptFollower, addChannelMembers, addChannelMembersRole, addCommunityMembers, addCommunityMembersRoles, addReaction, approvePost, backupCache, banChannelMembers, closePoll, connectClient, createChannel, createClient, createComment, createCommunity, createFile, createImage, createMessage, createPoll, createPost, createQuery, createReport, createStream, createUserToken, createVideo, declineFollower, declinePost, deleteChannel, deleteComment, deleteCommunity, deleteFile, deleteMessage, deletePoll, deletePost, deleteReport, deleteStream, disableCache, disconnectClient, disposeStream, dropFromCache, enableCache, fileUrlWithSize, filterByChannelMembership, filterByPropEquality, filterByPropInclusion, follow, getActiveClient, getCategory, getChannel, getChannels, getComment, getCommentTopic, getComments, getCommunities, getCommunity, getCommunityTopic, getFeedSettings, getFile, getFollowInfo, getMessage, getMessages, getMyFollowersTopic, getMyFollowingsTopic, getNetworkTopic, getPoll, getPost, getPostTopic, getPosts, getRecommendedCommunities, getRole, getStream, getTopTrendingCommunities, getUser, getUserTopic, getUsers, isAfterBefore, isAfterBeforeRaw, isCachable, isConnected, isFetcher, isFresh, isLocal, isMutator, isOffline, isPaged, isReportedByMe, isSkipLimit, joinChannel, joinCommunity, leaveChannel, leaveCommunity, liveChannelMembers, liveChannels, liveComments, liveFollowers, liveFollowings, liveMessage, liveMessages, livePosts, liveReactions, liveUser, mergeInCache, observeChannel, observeChannels, observeComment, observeComments, observeCommunity, observeFile, observeFollowInfo, observeFollowers, observeFollowings, observeMessage, observeMessages, observePoll, observePost, observePosts, observeUser, onChannelCreated, onChannelDeleted, onChannelJoined, onChannelLeft, onChannelMemberAdded, onChannelMemberBanned, onChannelMemberRead, onChannelMemberRemoved, onChannelMemberUnbanned, onChannelUpdated, onClientBanned, onClientDisconnected, onCommentCreated, onCommentDeleted, onCommentFlagged, onCommentReactionAdded, onCommentReactionRemoved, onCommentUnflagged, onCommentUpdated, onCommunityCreated, onCommunityDeleted, onCommunityJoined, onCommunityLeft, onCommunityUpdated, onCommunityUserAdded, onCommunityUserBanned, onCommunityUserRemoved, onCommunityUserUnbanned, onConnectionError, onFollowInfoUpdated, onFollowRequestAccepted, onFollowRequestCanceled, onFollowRequestDeclined, onFollowerDeleted, onFollowerRequested, onMessageCreated, onMessageDeleted, onMessageFetched, onMessageUpdated, onPollDeleted, onPollUpdated, onPostApproved, onPostCreated, onPostDeclined, onPostDeleted, onPostFlagged, onPostReactionAdded, onPostReactionRemoved, onPostUnflagged, onPostUpdated, onReactionAdded, onReactionRemoved, onReactorAdded, onReactorRemoved, onStreamRecorded, onStreamStarted, onStreamStopped, onUserDeleted, onUserFetched, onUserFlagCleared, onUserFlagged, onUserFollowed, onUserUnflagged, onUserUnfollowed, onUserUpdated, pullFromCache, pushToCache, queryCache, queryCategories, queryChannelMembers, queryChannels, queryComments, queryCommunities, queryCommunityMembers, queryFollowers, queryFollowings, queryGlobalFeed, queryMessages, queryOptions, queryPosts, queryReactions, queryRoles, queryStreams, queryUsers, removeChannelMembers, removeChannelMembersRole, removeCommunityMembers, removeCommunityMembersRoles, removeReaction, restoreCache, runQuery, sortByChannelSegment, sortByDisplayName, sortByFirstCreated, sortByLastActivity, sortByLastCreated, sortBySegmentNumber, startReading, stopReading, subscribeTopic, toPage, toPageRaw, toToken, unbanChannelMembers, unfollow, updateChannel, updateComment, updateCommunity, updateMessage, updatePost, updateStream, updateUser, upsertInCache, votePoll, wipeCache };