@amityco/ts-sdk 0.0.1-beta.25 → 0.0.1-beta.28

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 (295) hide show
  1. package/.eslintrc.json +5 -1
  2. package/dist/@types/core/events.d.ts +7 -7
  3. package/dist/@types/core/events.d.ts.map +1 -1
  4. package/dist/@types/core/live.d.ts +23 -0
  5. package/dist/@types/core/live.d.ts.map +1 -0
  6. package/dist/@types/core/paging.d.ts +1 -1
  7. package/dist/@types/core/paging.d.ts.map +1 -1
  8. package/dist/@types/core/payload.d.ts +15 -15
  9. package/dist/@types/core/payload.d.ts.map +1 -1
  10. package/dist/@types/domains/channel.d.ts +5 -1
  11. package/dist/@types/domains/channel.d.ts.map +1 -1
  12. package/dist/@types/domains/client.d.ts +13 -0
  13. package/dist/@types/domains/client.d.ts.map +1 -1
  14. package/dist/@types/domains/comment.d.ts +14 -0
  15. package/dist/@types/domains/comment.d.ts.map +1 -1
  16. package/dist/@types/domains/content.d.ts +26 -3
  17. package/dist/@types/domains/content.d.ts.map +1 -1
  18. package/dist/@types/domains/file.d.ts +36 -3
  19. package/dist/@types/domains/file.d.ts.map +1 -1
  20. package/dist/@types/domains/follow.d.ts +13 -1
  21. package/dist/@types/domains/follow.d.ts.map +1 -1
  22. package/dist/@types/domains/group.d.ts +1 -0
  23. package/dist/@types/domains/group.d.ts.map +1 -1
  24. package/dist/@types/domains/message.d.ts +13 -0
  25. package/dist/@types/domains/message.d.ts.map +1 -1
  26. package/dist/@types/domains/post.d.ts +17 -0
  27. package/dist/@types/domains/post.d.ts.map +1 -1
  28. package/dist/@types/domains/reaction.d.ts +10 -0
  29. package/dist/@types/domains/reaction.d.ts.map +1 -1
  30. package/dist/@types/global.d.ts +1 -0
  31. package/dist/@types/global.d.ts.map +1 -1
  32. package/dist/@types/index.d.ts +3 -2
  33. package/dist/@types/index.d.ts.map +1 -1
  34. package/dist/cache/api/ingestInCache.d.ts +1 -1
  35. package/dist/cache/api/ingestInCache.d.ts.map +1 -1
  36. package/dist/cache/api/mergeInCache.d.ts +1 -1
  37. package/dist/cache/api/mergeInCache.d.ts.map +1 -1
  38. package/dist/category/api/queryCategories.d.ts +3 -3
  39. package/dist/category/api/queryCategories.d.ts.map +1 -1
  40. package/dist/channel/api/addChannelMembers.d.ts.map +1 -1
  41. package/dist/channel/api/addChannelMembersRole.d.ts.map +1 -1
  42. package/dist/channel/api/banChannelMembers.d.ts +16 -0
  43. package/dist/channel/api/banChannelMembers.d.ts.map +1 -0
  44. package/dist/channel/api/createChannel.d.ts.map +1 -1
  45. package/dist/channel/api/getChannel.d.ts.map +1 -1
  46. package/dist/channel/api/getChannels.d.ts.map +1 -1
  47. package/dist/channel/api/index.d.ts +2 -0
  48. package/dist/channel/api/index.d.ts.map +1 -1
  49. package/dist/channel/api/joinChannel.d.ts.map +1 -1
  50. package/dist/channel/api/leaveChannel.d.ts.map +1 -1
  51. package/dist/channel/api/queryChannelMembers.d.ts.map +1 -1
  52. package/dist/channel/api/queryChannels.d.ts +6 -6
  53. package/dist/channel/api/queryChannels.d.ts.map +1 -1
  54. package/dist/channel/api/removeChannelMembers.d.ts.map +1 -1
  55. package/dist/channel/api/removeChannelMembersRole.d.ts.map +1 -1
  56. package/dist/channel/api/unbanChannelMembers.d.ts +16 -0
  57. package/dist/channel/api/unbanChannelMembers.d.ts.map +1 -0
  58. package/dist/channel/api/updateChannel.d.ts.map +1 -1
  59. package/dist/channel/events/index.d.ts +1 -0
  60. package/dist/channel/events/index.d.ts.map +1 -1
  61. package/dist/channel/events/onChannelCreated.d.ts.map +1 -1
  62. package/dist/channel/events/onChannelDeleted.d.ts.map +1 -1
  63. package/dist/channel/events/onChannelJoined.d.ts.map +1 -1
  64. package/dist/channel/events/onChannelLeft.d.ts.map +1 -1
  65. package/dist/channel/events/onChannelMemberAdded.d.ts.map +1 -1
  66. package/dist/channel/events/onChannelMemberRemoved.d.ts.map +1 -1
  67. package/dist/channel/events/onChannelUpdated.d.ts.map +1 -1
  68. package/dist/channel/observers/index.d.ts +1 -0
  69. package/dist/channel/observers/index.d.ts.map +1 -1
  70. package/dist/channel/observers/observeChannel.d.ts +1 -1
  71. package/dist/channel/observers/observeChannel.d.ts.map +1 -1
  72. package/dist/channel/observers/observeChannels.d.ts +17 -0
  73. package/dist/channel/observers/observeChannels.d.ts.map +1 -0
  74. package/dist/channel/tests/utils/prepareChannelPayload.test.d.ts +2 -0
  75. package/dist/channel/tests/utils/prepareChannelPayload.test.d.ts.map +1 -0
  76. package/dist/channel/utils/index.d.ts +2 -0
  77. package/dist/channel/utils/index.d.ts.map +1 -0
  78. package/dist/channel/utils/prepareChannelPayload.d.ts +3 -0
  79. package/dist/channel/utils/prepareChannelPayload.d.ts.map +1 -0
  80. package/dist/client/api/connectClient.d.ts +1 -8
  81. package/dist/client/api/connectClient.d.ts.map +1 -1
  82. package/dist/client/api/createClient.d.ts +8 -1
  83. package/dist/client/api/createClient.d.ts.map +1 -1
  84. package/dist/client/api/getFeedSettings.d.ts +16 -0
  85. package/dist/client/api/getFeedSettings.d.ts.map +1 -0
  86. package/dist/client/api/index.d.ts +1 -0
  87. package/dist/client/api/index.d.ts.map +1 -1
  88. package/dist/comment/api/queryComments.d.ts +1 -9
  89. package/dist/comment/api/queryComments.d.ts.map +1 -1
  90. package/dist/comment/observers/index.d.ts +1 -0
  91. package/dist/comment/observers/index.d.ts.map +1 -1
  92. package/dist/comment/observers/liveComments.d.ts +22 -0
  93. package/dist/comment/observers/liveComments.d.ts.map +1 -0
  94. package/dist/comment/observers/observeComments.d.ts.map +1 -1
  95. package/dist/community/api/getRecommendedCommunities.d.ts +1 -1
  96. package/dist/community/api/getRecommendedCommunities.d.ts.map +1 -1
  97. package/dist/community/api/getTopTrendingCommunities.d.ts +1 -1
  98. package/dist/community/api/getTopTrendingCommunities.d.ts.map +1 -1
  99. package/dist/community/api/queryCommunities.d.ts +7 -7
  100. package/dist/community/api/queryCommunities.d.ts.map +1 -1
  101. package/dist/core/debug.d.ts +1 -1
  102. package/dist/core/debug.d.ts.map +1 -1
  103. package/dist/core/events.d.ts +3 -3
  104. package/dist/core/events.d.ts.map +1 -1
  105. package/dist/core/query/paging.d.ts +2 -2
  106. package/dist/core/query/paging.d.ts.map +1 -1
  107. package/dist/core/query/query.d.ts +2 -2
  108. package/dist/core/query/query.d.ts.map +1 -1
  109. package/dist/core/tests/query/filtering.test.d.ts +2 -0
  110. package/dist/core/tests/query/filtering.test.d.ts.map +1 -0
  111. package/dist/core/tests/query/query/runQuery.test.d.ts +2 -0
  112. package/dist/core/tests/query/query/runQuery.test.d.ts.map +1 -0
  113. package/dist/core/tests/query/query.test.d.ts +2 -0
  114. package/dist/core/tests/query/query.test.d.ts.map +1 -0
  115. package/dist/core/transports/ws.d.ts +1 -1
  116. package/dist/core/transports/ws.d.ts.map +1 -1
  117. package/dist/external/api/createUserToken.d.ts +1 -1
  118. package/dist/external/api/createUserToken.d.ts.map +1 -1
  119. package/dist/feed/api/queryGlobalFeed.d.ts +4 -4
  120. package/dist/feed/api/queryGlobalFeed.d.ts.map +1 -1
  121. package/dist/file/api/createVideo.d.ts +2 -1
  122. package/dist/file/api/createVideo.d.ts.map +1 -1
  123. package/dist/follow/api/follow.d.ts.map +1 -1
  124. package/dist/follow/api/getFollowInfo.d.ts.map +1 -1
  125. package/dist/follow/api/queryFollowers.d.ts +2 -6
  126. package/dist/follow/api/queryFollowers.d.ts.map +1 -1
  127. package/dist/follow/api/queryFollowings.d.ts +2 -6
  128. package/dist/follow/api/queryFollowings.d.ts.map +1 -1
  129. package/dist/follow/api/utils.d.ts +4 -4
  130. package/dist/follow/api/utils.d.ts.map +1 -1
  131. package/dist/follow/events/utils.d.ts.map +1 -1
  132. package/dist/follow/observers/index.d.ts +2 -0
  133. package/dist/follow/observers/index.d.ts.map +1 -1
  134. package/dist/follow/observers/liveFollowers.d.ts +20 -0
  135. package/dist/follow/observers/liveFollowers.d.ts.map +1 -0
  136. package/dist/follow/observers/liveFollowings.d.ts +20 -0
  137. package/dist/follow/observers/liveFollowings.d.ts.map +1 -0
  138. package/dist/index.cjs.js +18706 -17726
  139. package/dist/index.d.ts +2 -1
  140. package/dist/index.d.ts.map +1 -1
  141. package/dist/index.esm.js +18688 -17727
  142. package/dist/index.umd.js +4 -19
  143. package/dist/message/api/queryMessages.d.ts +1 -10
  144. package/dist/message/api/queryMessages.d.ts.map +1 -1
  145. package/dist/message/observers/index.d.ts +1 -0
  146. package/dist/message/observers/index.d.ts.map +1 -1
  147. package/dist/message/observers/liveMessages.d.ts +20 -0
  148. package/dist/message/observers/liveMessages.d.ts.map +1 -0
  149. package/dist/message/observers/observeMessages.d.ts +0 -1
  150. package/dist/message/observers/observeMessages.d.ts.map +1 -1
  151. package/dist/message/observers/tests/liveMessages.test.d.ts +2 -0
  152. package/dist/message/observers/tests/liveMessages.test.d.ts.map +1 -0
  153. package/dist/post/api/queryPosts.d.ts +1 -12
  154. package/dist/post/api/queryPosts.d.ts.map +1 -1
  155. package/dist/post/observers/index.d.ts +1 -0
  156. package/dist/post/observers/index.d.ts.map +1 -1
  157. package/dist/post/observers/livePosts.d.ts +22 -0
  158. package/dist/post/observers/livePosts.d.ts.map +1 -0
  159. package/dist/post/observers/observePosts.d.ts.map +1 -1
  160. package/dist/post/tests/api/getPost.test.d.ts +2 -0
  161. package/dist/post/tests/api/getPost.test.d.ts.map +1 -0
  162. package/dist/post/tests/api/queryPosts.test.d.ts +2 -0
  163. package/dist/post/tests/api/queryPosts.test.d.ts.map +1 -0
  164. package/dist/reaction/api/queryReactions.d.ts +1 -6
  165. package/dist/reaction/api/queryReactions.d.ts.map +1 -1
  166. package/dist/reaction/events/index.d.ts +3 -0
  167. package/dist/reaction/events/index.d.ts.map +1 -1
  168. package/dist/reaction/events/onReactorAdded.d.ts +19 -0
  169. package/dist/reaction/events/onReactorAdded.d.ts.map +1 -0
  170. package/dist/reaction/events/onReactorRemoved.d.ts +19 -0
  171. package/dist/reaction/events/onReactorRemoved.d.ts.map +1 -0
  172. package/dist/reaction/observers/index.d.ts +2 -0
  173. package/dist/reaction/observers/index.d.ts.map +1 -0
  174. package/dist/reaction/observers/liveReactions.d.ts +22 -0
  175. package/dist/reaction/observers/liveReactions.d.ts.map +1 -0
  176. package/dist/role/api/queryRoles.d.ts +4 -4
  177. package/dist/role/api/queryRoles.d.ts.map +1 -1
  178. package/dist/stream/api/queryStreams.d.ts +6 -6
  179. package/dist/stream/api/queryStreams.d.ts.map +1 -1
  180. package/dist/utils/constants.d.ts +4 -0
  181. package/dist/utils/constants.d.ts.map +1 -0
  182. package/dist/utils/tests/client.d.ts +6 -0
  183. package/dist/utils/tests/client.d.ts.map +1 -0
  184. package/dist/utils/tests/dummy/channel.d.ts +10 -0
  185. package/dist/utils/tests/dummy/channel.d.ts.map +1 -0
  186. package/dist/utils/tests/dummy/index.d.ts +10 -0
  187. package/dist/utils/tests/dummy/index.d.ts.map +1 -0
  188. package/dist/utils/tests/dummy/message.d.ts +8 -0
  189. package/dist/utils/tests/dummy/message.d.ts.map +1 -0
  190. package/dist/utils/tests/dummy/post.d.ts +9 -0
  191. package/dist/utils/tests/dummy/post.d.ts.map +1 -0
  192. package/dist/utils/tests/dummy/user.d.ts +2 -0
  193. package/dist/utils/tests/dummy/user.d.ts.map +1 -0
  194. package/dist/utils/tests/index.d.ts +3 -0
  195. package/dist/utils/tests/index.d.ts.map +1 -0
  196. package/jest.config.ts +15 -0
  197. package/package.json +21 -16
  198. package/src/@types/core/events.ts +7 -7
  199. package/src/@types/core/live.ts +28 -0
  200. package/src/@types/core/paging.ts +1 -1
  201. package/src/@types/core/payload.ts +21 -16
  202. package/src/@types/domains/channel.ts +16 -1
  203. package/src/@types/domains/client.ts +17 -0
  204. package/src/@types/domains/comment.ts +31 -0
  205. package/src/@types/domains/content.ts +34 -3
  206. package/src/@types/domains/file.ts +42 -3
  207. package/src/@types/domains/follow.ts +31 -1
  208. package/src/@types/domains/group.ts +1 -0
  209. package/src/@types/domains/message.ts +20 -0
  210. package/src/@types/domains/post.ts +37 -0
  211. package/src/@types/domains/reaction.ts +17 -0
  212. package/src/@types/global.ts +2 -0
  213. package/src/@types/index.ts +4 -2
  214. package/src/channel/api/addChannelMembers.ts +6 -5
  215. package/src/channel/api/addChannelMembersRole.ts +5 -1
  216. package/src/channel/api/banChannelMembers.ts +45 -0
  217. package/src/channel/api/createChannel.ts +6 -2
  218. package/src/channel/api/getChannel.ts +5 -1
  219. package/src/channel/api/getChannels.ts +5 -1
  220. package/src/channel/api/index.ts +3 -0
  221. package/src/channel/api/joinChannel.ts +5 -1
  222. package/src/channel/api/leaveChannel.ts +5 -1
  223. package/src/channel/api/queryChannelMembers.ts +16 -12
  224. package/src/channel/api/queryChannels.ts +9 -4
  225. package/src/channel/api/removeChannelMembers.ts +6 -5
  226. package/src/channel/api/removeChannelMembersRole.ts +5 -1
  227. package/src/channel/api/unbanChannelMembers.ts +45 -0
  228. package/src/channel/api/updateChannel.ts +5 -1
  229. package/src/channel/events/index.ts +1 -0
  230. package/src/channel/events/onChannelCreated.ts +6 -2
  231. package/src/channel/events/onChannelDeleted.ts +6 -2
  232. package/src/channel/events/onChannelJoined.ts +6 -2
  233. package/src/channel/events/onChannelLeft.ts +6 -2
  234. package/src/channel/events/onChannelMemberAdded.ts +6 -2
  235. package/src/channel/events/onChannelMemberRemoved.ts +6 -2
  236. package/src/channel/events/onChannelUpdated.ts +6 -2
  237. package/src/channel/observers/index.ts +1 -0
  238. package/src/channel/observers/observeChannel.ts +1 -11
  239. package/src/channel/observers/observeChannels.ts +59 -0
  240. package/src/channel/tests/utils/prepareChannelPayload.test.ts +120 -0
  241. package/src/channel/utils/index.ts +1 -0
  242. package/src/channel/utils/prepareChannelPayload.ts +31 -0
  243. package/src/client/api/connectClient.ts +4 -9
  244. package/src/client/api/createClient.ts +19 -4
  245. package/src/client/api/getFeedSettings.ts +29 -0
  246. package/src/client/api/index.ts +2 -0
  247. package/src/comment/api/queryComments.ts +3 -9
  248. package/src/comment/observers/index.ts +1 -0
  249. package/src/comment/observers/liveComments.ts +172 -0
  250. package/src/comment/observers/observeComments.ts +1 -11
  251. package/src/core/events.ts +2 -1
  252. package/src/core/query/query.ts +16 -3
  253. package/src/core/tests/query/filtering.test.ts +11 -0
  254. package/src/core/tests/query/query/runQuery.test.ts +182 -0
  255. package/src/core/tests/query/query.test.ts +19 -0
  256. package/src/file/api/createVideo.ts +6 -0
  257. package/src/follow/api/acceptFollower.ts +1 -1
  258. package/src/follow/api/declineFollower.ts +1 -1
  259. package/src/follow/api/follow.ts +1 -4
  260. package/src/follow/api/getFollowInfo.ts +8 -5
  261. package/src/follow/api/queryFollowers.ts +5 -6
  262. package/src/follow/api/queryFollowings.ts +5 -6
  263. package/src/follow/api/unfollow.ts +1 -1
  264. package/src/follow/api/utils.ts +17 -13
  265. package/src/follow/events/utils.ts +9 -6
  266. package/src/follow/observers/index.ts +3 -0
  267. package/src/follow/observers/liveFollowers.ts +149 -0
  268. package/src/follow/observers/liveFollowings.ts +149 -0
  269. package/src/index.ts +2 -1
  270. package/src/message/api/queryMessages.ts +3 -10
  271. package/src/message/observers/index.ts +1 -0
  272. package/src/message/observers/liveMessages.ts +141 -0
  273. package/src/message/observers/observeMessages.ts +0 -1
  274. package/src/message/observers/tests/liveMessages.test.ts +133 -0
  275. package/src/post/api/queryPosts.ts +3 -12
  276. package/src/post/observers/index.ts +1 -0
  277. package/src/post/observers/livePosts.ts +171 -0
  278. package/src/post/observers/observePosts.ts +1 -13
  279. package/src/post/tests/api/getPost.test.ts +88 -0
  280. package/src/post/tests/api/queryPosts.test.ts +23 -0
  281. package/src/reaction/api/queryReactions.ts +14 -14
  282. package/src/reaction/events/index.ts +4 -0
  283. package/src/reaction/events/onReactorAdded.ts +80 -0
  284. package/src/reaction/events/onReactorRemoved.ts +85 -0
  285. package/src/reaction/observers/index.ts +1 -0
  286. package/src/reaction/observers/liveReactions.ts +142 -0
  287. package/src/utils/constants.ts +3 -0
  288. package/src/utils/tests/client.ts +33 -0
  289. package/src/utils/tests/dummy/channel.ts +52 -0
  290. package/src/utils/tests/dummy/index.ts +7 -0
  291. package/src/utils/tests/dummy/message.ts +21 -0
  292. package/src/utils/tests/dummy/post.ts +31 -0
  293. package/src/utils/tests/dummy/user.ts +11 -0
  294. package/src/utils/tests/index.ts +2 -0
  295. package/tsconfig.json +23 -22
@@ -0,0 +1,31 @@
1
+ import { getActiveClient } from '~/client/api';
2
+
3
+ /** @hidden */
4
+ export const prepareChannelPayload = (
5
+ payload: Amity.ChannelPayload,
6
+ ): Amity.ChannelPayload<any, Amity.Channel> => {
7
+ const client = getActiveClient();
8
+
9
+ const channels: Amity.Channel[] = payload.channels.map(channel => {
10
+ const channelUser = payload.channelUsers.find(
11
+ channelUser =>
12
+ channelUser.userId === client.userId && channel.channelId === channelUser.channelId,
13
+ )!;
14
+
15
+ const hasMention = channelUser
16
+ ? channelUser.readToSegment < channelUser.lastMentionedSegment
17
+ : false;
18
+ const unreadCount =
19
+ channelUser && channelUser.membership === 'member' && channel.messageCount
20
+ ? Math.max(0, channel.messageCount - channelUser.readToSegment)
21
+ : 0;
22
+
23
+ return {
24
+ ...channel,
25
+ hasMention,
26
+ unreadCount,
27
+ };
28
+ });
29
+
30
+ return { ...payload, channels };
31
+ };
@@ -3,14 +3,14 @@
3
3
  import { disconnectClient } from '~/client/api/disconnectClient';
4
4
  import { getDeviceId } from '~/core/device';
5
5
  import { proxyWebsocketEvents } from '~/core/events';
6
+ import { getNetworkTopic, subscribeTopic } from '~/core/subscription';
7
+ import { onUserDeleted } from '~/user/events/onUserDeleted';
6
8
 
7
9
  import { getActiveClient } from './activeClient';
8
10
  import { setActiveUser } from './activeUser';
9
11
 
10
12
  import { getToken } from './getToken';
11
13
  import { onClientBanned } from '../events';
12
- import { getNetworkTopic, subscribeTopic } from '~/core/subscription';
13
- import { onUserDeleted } from '~/user/events/onUserDeleted';
14
14
 
15
15
  /**
16
16
  * ```js
@@ -33,13 +33,8 @@ import { onUserDeleted } from '~/user/events/onUserDeleted';
33
33
  * @async
34
34
  */
35
35
  export const connectClient = async (
36
- params: {
37
- userId: Amity.User['userId'];
38
- displayName?: Amity.User['displayName'];
39
- authToken?: string;
40
- deviceId?: Amity.Device['deviceId'];
41
- },
42
- config?: { disableRTE: boolean },
36
+ params: Amity.ConnectClientParams,
37
+ config?: Amity.ConnectClientConfig,
43
38
  ): Promise<boolean> => {
44
39
  const client = getActiveClient();
45
40
  client.log('client/api/connectClient', { apiKey: client.apiKey, ...params });
@@ -12,6 +12,9 @@ import {
12
12
  import { createEventEmitter } from '~/core/events';
13
13
 
14
14
  import { getActiveClient, setActiveClient } from './activeClient';
15
+ import { getFeedSettings } from './getFeedSettings';
16
+
17
+ const DEFAULT_DEBUG_SESSION = 'amity';
15
18
 
16
19
  /**
17
20
  * ```js
@@ -23,6 +26,7 @@ import { getActiveClient, setActiveClient } from './activeClient';
23
26
  *
24
27
  * @param apiKey for the {@link Amity.Client} instance
25
28
  * @param apiRegion endpoint to connect to
29
+ * @param apiEndpoint custom endpoint in case you don't want to use a preset endpoint
26
30
  * @param debugSession session's identifier for the client's logger instance
27
31
  * @returns A {@link Amity.Client} instance
28
32
  *
@@ -31,7 +35,13 @@ import { getActiveClient, setActiveClient } from './activeClient';
31
35
  export const createClient = (
32
36
  apiKey: string,
33
37
  apiRegion: typeof API_REGIONS[keyof typeof API_REGIONS] = API_REGIONS.SG,
34
- debugSession = 'amity',
38
+ {
39
+ debugSession = DEFAULT_DEBUG_SESSION,
40
+ apiEndpoint,
41
+ }: {
42
+ debugSession?: string;
43
+ apiEndpoint?: { http?: string; mqtt?: string };
44
+ } = {},
35
45
  ): Amity.Client => {
36
46
  const log = createLogger(debugSession);
37
47
 
@@ -40,9 +50,12 @@ export const createClient = (
40
50
  apiRegion,
41
51
  });
42
52
 
43
- const http = createHttpTransport(computeUrl('http', apiRegion));
44
- const ws = createWebsocketTransport(computeUrl('http', apiRegion));
45
- const mqtt = createMqttTransport(computeUrl('mqtt', apiRegion));
53
+ const httpEndpoint = apiEndpoint?.http ?? computeUrl('http', apiRegion);
54
+ const mqttEndpoint = apiEndpoint?.mqtt ?? computeUrl('mqtt', apiRegion);
55
+
56
+ const http = createHttpTransport(httpEndpoint);
57
+ const ws = createWebsocketTransport(httpEndpoint);
58
+ const mqtt = createMqttTransport(mqttEndpoint);
46
59
 
47
60
  const emitter = createEventEmitter();
48
61
 
@@ -56,6 +69,8 @@ export const createClient = (
56
69
  mqtt,
57
70
  emitter,
58
71
  use: () => setActiveClient(client),
72
+
73
+ getFeedSettings,
59
74
  };
60
75
 
61
76
  try {
@@ -0,0 +1,29 @@
1
+ import { getActiveClient } from './activeClient';
2
+
3
+ /**
4
+ * ```js
5
+ * import { getFeedSettings } from '@amityco/ts-sdk'
6
+ * const feedSettings = await getFeedSettings()
7
+ * const postFeedSetting = feedSettings.post
8
+ * ```
9
+ *
10
+ * Fetches a {@link Amity.FeedSettings} object
11
+ *
12
+ * @returns A Promise of {@link Amity.FeedSettings} object
13
+ *
14
+ * @category Client API
15
+ * @async
16
+ */
17
+ export const getFeedSettings = async (): Promise<Amity.FeedSettings> => {
18
+ const client = getActiveClient();
19
+
20
+ const { data } = await client.http.get<Amity.FeedSettingPayload>(
21
+ `/api/v3/network-settings/feed-setting`,
22
+ );
23
+
24
+ return Object.fromEntries(
25
+ data.feedSettings.map(({ feedType, contentSettings }) => {
26
+ return [feedType, contentSettings];
27
+ }),
28
+ );
29
+ };
@@ -6,3 +6,5 @@ export * from './connectClient';
6
6
  export * from './disconnectClient';
7
7
 
8
8
  export * from './isConnected';
9
+
10
+ export * from './getFeedSettings';
@@ -19,15 +19,9 @@ import { getResolver } from '~/core/model';
19
19
  * @category Comment API
20
20
  * @async
21
21
  */
22
- export const queryComments = async (query: {
23
- referenceType: Amity.Comment['referenceType'];
24
- referenceId: Amity.Comment['referenceId'];
25
- sortBy?: 'lastCreated' | 'firstCreated' | 'lastUpdated' | 'firstUpdated';
26
- parentId?: Amity.Comment['commentId'] | null;
27
- hasFlag?: boolean;
28
- isDeleted?: Amity.Comment['isDeleted'];
29
- page?: Amity.Page;
30
- }): Promise<Amity.Cached<Amity.Paged<Amity.Comment>>> => {
22
+ export const queryComments = async (
23
+ query: Amity.QueryComments,
24
+ ): Promise<Amity.Cached<Amity.Paged<Amity.Comment>>> => {
31
25
  const client = getActiveClient();
32
26
  client.log('comment/queryComments', query);
33
27
 
@@ -1,2 +1,3 @@
1
1
  export * from './observeComments';
2
2
  export * from './observeComment';
3
+ export * from './liveComments';
@@ -0,0 +1,172 @@
1
+ /* eslint-disable no-use-before-define */
2
+ import { getResolver } from '~/core/model';
3
+ import { getActiveClient } from '~/client/api';
4
+ import { pushToCache, pullFromCache } from '~/cache/api';
5
+ import {
6
+ createQuery,
7
+ runQuery,
8
+ queryOptions,
9
+ filterByPropEquality,
10
+ sortByFirstCreated,
11
+ sortByLastCreated,
12
+ } from '~/core/query';
13
+
14
+ import {
15
+ COLLECTION_DEFAULT_CACHING_POLICY,
16
+ COLLECTION_DEFAULT_PAGINATION_LIMIT,
17
+ } from '~/utils/constants';
18
+
19
+ import {
20
+ onCommentCreated,
21
+ onCommentUpdated,
22
+ onCommentDeleted,
23
+ onCommentFlagged,
24
+ onCommentUnflagged,
25
+ onCommentReactionAdded,
26
+ onCommentReactionRemoved,
27
+ } from '../events';
28
+ import { queryComments } from '../api';
29
+
30
+ /**
31
+ * ```js
32
+ * import { liveComments } from '@amityco/ts-sdk'
33
+ *
34
+ * let comments = []
35
+ * const unsub = liveComments({
36
+ * referenceType: Amity.Comment['referenceType'];
37
+ * referenceId: Amity.Comment['referenceId'];
38
+ * }, response => merge(comments, response.data))
39
+ * ```
40
+ *
41
+ * Observe all mutations on a list of {@link Amity.Comment} for a given target object
42
+ *
43
+ * @param referenceType the type of the target
44
+ * @param referenceId the ID of the target
45
+ * @param callback the function to call when new data are available
46
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the messages
47
+ *
48
+ * @category Comments Live Collection
49
+ */
50
+ export const liveComments = (
51
+ params: Amity.CommentLiveCollection,
52
+ callback: Amity.LiveCollectionCallback<Amity.Comment>,
53
+ config?: Amity.LiveCollectionConfig,
54
+ ): Amity.Unsubscriber => {
55
+ const { log, cache } = getActiveClient();
56
+
57
+ if (!cache) {
58
+ console.log('For using Live Collection feature you need to enable Cache!');
59
+ }
60
+
61
+ const timestamp = Date.now();
62
+ log(`liveComments(tmpid: ${timestamp}) > listen`);
63
+
64
+ const { limit: queryLimit, ...queryParams } = params;
65
+
66
+ const limit = queryLimit ?? COLLECTION_DEFAULT_PAGINATION_LIMIT;
67
+ const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config ?? {};
68
+
69
+ const disposers: Amity.Unsubscriber[] = [];
70
+ const cacheKey = [
71
+ 'comment',
72
+ 'collection',
73
+ { referenceId: params.referenceType, referenceType: params.referenceId },
74
+ ];
75
+
76
+ const responder = (data: Amity.CommentLiveCollectionCache) => {
77
+ let comments: Amity.Comment[] =
78
+ data.data
79
+ .map(commentId => pullFromCache<Amity.Comment>(['comment', 'get', commentId])!)
80
+ .filter(Boolean)
81
+ .map(({ data }) => data) ?? [];
82
+
83
+ comments = filterByPropEquality(comments, 'isDeleted', params.isDeleted);
84
+
85
+ const sortBy = params.sortBy ? params.sortBy : 'lastCreated';
86
+
87
+ comments = comments.sort(sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated);
88
+
89
+ callback({
90
+ onNextPage: onFetch,
91
+ data: comments,
92
+ hasNextPage: !!data.params?.page,
93
+ loading: data.loading,
94
+ error: data.error,
95
+ });
96
+ };
97
+
98
+ const realtimeRouter = (comment: Amity.Comment, action: Amity.CommentActionType) => {
99
+ const collection = pullFromCache<Amity.CommentLiveCollectionCache>(cacheKey)?.data;
100
+
101
+ if (
102
+ params.referenceId !== comment.referenceId ||
103
+ params.referenceType !== comment.referenceType ||
104
+ !collection
105
+ )
106
+ return;
107
+
108
+ if (action === 'onCreate') {
109
+ collection.data = [...new Set([comment.commentId, ...collection.data])];
110
+ } else if (action === 'onDelete') {
111
+ collection.data = collection.data.filter(p => p !== comment.commentId);
112
+ }
113
+
114
+ pushToCache(cacheKey, collection);
115
+
116
+ responder(collection);
117
+ };
118
+
119
+ const onFetch = () => {
120
+ const collection = pullFromCache<Amity.CommentLiveCollectionCache>(cacheKey)?.data;
121
+
122
+ const comments = collection?.data ?? [];
123
+
124
+ if (comments.length > 0 && !collection?.params?.page) return;
125
+
126
+ const query = createQuery(queryComments, {
127
+ ...queryParams,
128
+ page: collection?.params?.page ?? { limit },
129
+ });
130
+
131
+ runQuery(
132
+ query,
133
+ ({ data: result, error, loading, prevPage, nextPage }) => {
134
+ // depend on sortBy value we have two different pagination type
135
+ const page = queryParams.sortBy ? nextPage : prevPage;
136
+
137
+ const data = {
138
+ loading,
139
+ error,
140
+ params: { page },
141
+ data: comments,
142
+ };
143
+
144
+ if (result) {
145
+ data.data = [...new Set([...comments, ...result.map(getResolver('comment'))])];
146
+ }
147
+
148
+ pushToCache(cacheKey, data);
149
+
150
+ responder(data);
151
+ },
152
+ queryOptions(policy),
153
+ );
154
+ };
155
+
156
+ disposers.push(
157
+ onCommentCreated(comment => realtimeRouter(comment, 'onCreate')),
158
+ onCommentUpdated(comment => realtimeRouter(comment, 'onUpdate')),
159
+ onCommentDeleted(comment => realtimeRouter(comment, 'onDelete')),
160
+ onCommentFlagged(comment => realtimeRouter(comment, 'onFlagged')),
161
+ onCommentUnflagged(comment => realtimeRouter(comment, 'onUnflagged')),
162
+ onCommentReactionAdded(comment => realtimeRouter(comment, 'onReactionAdded')),
163
+ onCommentReactionRemoved(comment => realtimeRouter(comment, 'onReactionRemoved')),
164
+ );
165
+
166
+ onFetch();
167
+
168
+ return () => {
169
+ log(`liveComments(tmpid: ${timestamp}) > dispose`);
170
+ disposers.forEach(fn => fn());
171
+ };
172
+ };
@@ -48,17 +48,7 @@ export const observeComments = (
48
48
 
49
49
  const disposers: Amity.Unsubscriber[] = [];
50
50
 
51
- const router = (
52
- comment: Amity.Comment,
53
- action:
54
- | 'onCreate'
55
- | 'onUpdate'
56
- | 'onDelete'
57
- | 'onFlagged'
58
- | 'onUnflagged'
59
- | 'onReactionAdded'
60
- | 'onReactionRemoved',
61
- ) => {
51
+ const router = (comment: Amity.Comment, action: Exclude<Amity.CommentActionType, 'onFetch'>) => {
62
52
  if (comment.referenceId !== postId) return;
63
53
 
64
54
  if (callback instanceof Function) return callback(comment);
@@ -13,8 +13,9 @@ const WS_EVENTS = [
13
13
  'reconnect_error',
14
14
  'reconnect_failed',
15
15
 
16
+ 'v3.channel.didCreate',
16
17
  'v3.channel.didUpdate',
17
- 'v3.channel.didUpdate',
18
+ 'v3.channel.didDelete',
18
19
  'v3.channel.didJoin',
19
20
  'v3.channel.didLeave',
20
21
  'v3.channel.didAddUsers',
@@ -85,7 +85,7 @@ export const isFresh = (model?: Amity.Cachable, lifeSpan = 0) => {
85
85
  * This wrapper is necessary to create for optimistically calls
86
86
  *
87
87
  *
88
- * @param fn A compatible API function from the ts sdk
88
+ * @param func A compatible API function from the ts sdk
89
89
  * @param args The arguments to pass to the function passed as `fn`
90
90
  * @returns A wrapper containing both the function and its future arguments
91
91
  *
@@ -215,8 +215,21 @@ export const runQuery = <Args extends any[], Returned extends any>(
215
215
  if (isMutator(func)) {
216
216
  // @ts-ignore
217
217
  const modelKey = local && local.data && identifyModelKey(local.data);
218
- // @ts-ignore
219
- optimisticArgs = modelKey ? [...args, { [modelKey]: local.data[modelKey] }] : args;
218
+ if (modelKey) {
219
+ /*
220
+ * modal key is only required for create as update and delete queries pass
221
+ * the modal key in the param itself
222
+ * For update & delete the first argument is always an id which is of type
223
+ * string, whereas for create the first and only argument is the param object
224
+ *
225
+ * When creating an AmityObject optimistically we need to pass the modal key
226
+ * on to the server. ex: for create message modal key will be 'messageId`
227
+ */
228
+ if (typeof args[0] !== 'string') {
229
+ // @ts-ignore
230
+ optimisticArgs = [{ ...args[0], [modelKey]: local.data[modelKey] }];
231
+ }
232
+ }
220
233
  }
221
234
 
222
235
  func(...optimisticArgs)
@@ -0,0 +1,11 @@
1
+ import { filterByPropEquality } from '~/core/query';
2
+
3
+ describe('Core/Query/Filtering', () => {
4
+ test('check filterByPropEquality', () => {
5
+ const prop = 'prop';
6
+ const collection = [{ [prop]: 'value' }];
7
+
8
+ expect(filterByPropEquality(collection, prop, 'value')).toStrictEqual(collection);
9
+ expect(filterByPropEquality(collection, prop, 'otherValue')).toStrictEqual([]);
10
+ });
11
+ });
@@ -0,0 +1,182 @@
1
+ import { ASCApiError } from '~/core/errors';
2
+ import { disableCache, enableCache, pushToCache } from '~/cache/api';
3
+ import { runQuery, createQuery } from '~/core/query';
4
+ import { createPost, getPost } from '~/post/api';
5
+ import { deleteMessage } from '~/message/api';
6
+
7
+ import { posts, client } from '~/utils/tests';
8
+
9
+ const createPostArgs: Parameters<typeof createPost> = [
10
+ {
11
+ tags: ['a', 'b'],
12
+ data: {
13
+ text: 'hello!',
14
+ },
15
+ targetType: 'user',
16
+ targetId: 'userId1',
17
+ },
18
+ ];
19
+ const post = { postId: posts.page1[0] };
20
+ const deletingMsgId = 'deletingId';
21
+
22
+ describe('Core/Query/runQuery', () => {
23
+ test('should call query with arguments', () => {
24
+ const createPostMock = jest.fn().mockResolvedValue('test');
25
+
26
+ const query = createQuery(createPostMock, createPostArgs);
27
+ runQuery(query);
28
+
29
+ expect(createPostMock).toBeCalledTimes(1);
30
+ });
31
+
32
+ test('should call callback with cache when valid', () => {
33
+ enableCache();
34
+
35
+ const callback = jest.fn();
36
+
37
+ const cachedAt = Date.now();
38
+ pushToCache(['post', 'get', post.postId], post, { cachedAt });
39
+
40
+ const query = createQuery(getPost, post.postId);
41
+ runQuery(query, callback);
42
+
43
+ expect(callback).toBeCalled();
44
+ expect(callback).toBeCalledTimes(1);
45
+ expect(callback).toHaveBeenCalledWith({
46
+ cachedAt,
47
+ origin: 'local',
48
+ loading: false,
49
+ data: post,
50
+ });
51
+
52
+ disableCache();
53
+ });
54
+
55
+ test('should call callback with server data for invalid cache', async () => {
56
+ enableCache();
57
+
58
+ const callback = jest.fn();
59
+ client.http.get = jest.fn().mockResolvedValue({ data: { posts: [post] } });
60
+
61
+ // at the time of writing this test, cache is valid for 2 minutes
62
+ const expiredDate = Date.parse('04 Dec 1995 00:12:00 GMT');
63
+ pushToCache(['post', 'get', post.postId], post, { cachedAt: expiredDate });
64
+
65
+ const query = createQuery(getPost, post.postId);
66
+ runQuery(query, callback);
67
+
68
+ expect(callback).toHaveBeenCalledWith({
69
+ cachedAt: expiredDate,
70
+ origin: 'local',
71
+ loading: true,
72
+ data: post,
73
+ });
74
+
75
+ await expect(getPost(post.postId)).resolves.toBeTruthy();
76
+
77
+ expect(callback).toHaveBeenCalledTimes(2);
78
+ // checking object containing as expiredAt cannot be predicted :D
79
+ expect(callback).toHaveBeenCalledWith(
80
+ expect.objectContaining({
81
+ origin: 'server',
82
+ loading: false,
83
+ data: post,
84
+ }),
85
+ );
86
+
87
+ disableCache();
88
+ });
89
+
90
+ test('should execute mutators optimistically', () => {
91
+ enableCache();
92
+
93
+ const createMessage: any = jest.fn().mockResolvedValue('test');
94
+ // mutators are defined as having a property called optimistically
95
+ createMessage.optimistically = jest.fn();
96
+
97
+ const query = createQuery(createMessage);
98
+ runQuery(query);
99
+
100
+ expect(createMessage.optimistically).toHaveBeenCalled();
101
+ // should call server right after
102
+ expect(createMessage).toHaveBeenCalled();
103
+
104
+ disableCache();
105
+ });
106
+
107
+ /*
108
+ * NOTE: del not tested as the args are exactly the same as update
109
+ *
110
+ * Tested due to bug where optimistic args was modifying args for del &
111
+ * update when it does not need to
112
+ */
113
+ test('should not change args optimistically for update', () => {
114
+ enableCache();
115
+
116
+ client.http.delete = jest.fn().mockResolvedValue(true);
117
+ // 'get', gets called after delete to verify delete
118
+ client.http.get = jest.fn();
119
+
120
+ const query = createQuery(deleteMessage, deletingMsgId);
121
+ runQuery(query);
122
+
123
+ expect(client.http.delete).toHaveBeenCalledWith(`/api/v3/messages/${deletingMsgId}`);
124
+
125
+ disableCache();
126
+ });
127
+
128
+ test('should throw error if optimistic execution fails', async () => {
129
+ enableCache();
130
+
131
+ const callback = jest.fn();
132
+ const createMessage: any = jest.fn().mockResolvedValue('test');
133
+ // mutators are defined as having a property called optimistically
134
+ createMessage.optimistically = jest.fn().mockImplementation(() => {
135
+ throw new Error();
136
+ });
137
+
138
+ const query = createQuery(createMessage);
139
+ runQuery(query, callback);
140
+
141
+ expect(createMessage.optimistically).toThrow();
142
+ expect(callback).toBeCalledWith({
143
+ origin: 'local',
144
+ loading: true,
145
+ data: undefined,
146
+ });
147
+
148
+ disableCache();
149
+ });
150
+
151
+ test('should return error if call to server fails', async () => {
152
+ enableCache();
153
+
154
+ client.http.delete = jest
155
+ .fn()
156
+ .mockRejectedValueOnce(
157
+ new ASCApiError('not found!', Amity.ServerError.ITEM_NOT_FOUND, Amity.ErrorLevel.ERROR),
158
+ );
159
+ const callback = jest.fn();
160
+
161
+ const query = createQuery(deleteMessage, deletingMsgId);
162
+ runQuery(query, callback);
163
+
164
+ expect(callback).toHaveBeenCalledWith({
165
+ origin: 'local',
166
+ loading: true,
167
+ data: undefined,
168
+ });
169
+
170
+ await expect(deleteMessage(deletingMsgId)).rejects.toThrow();
171
+
172
+ expect(callback).toHaveBeenCalledTimes(2);
173
+ expect(callback).toHaveBeenCalledWith(
174
+ expect.objectContaining({
175
+ origin: 'server',
176
+ loading: false,
177
+ }),
178
+ );
179
+
180
+ disableCache();
181
+ });
182
+ });
@@ -0,0 +1,19 @@
1
+ import { isFetcher } from '~/core/query';
2
+
3
+ type isFetcherMockType = jest.Mock<any, any> & {
4
+ locally?: jest.Mock<any, any>;
5
+ };
6
+
7
+ describe('Core/Query/Query', () => {
8
+ const isFetcherMock: isFetcherMockType = jest.fn();
9
+
10
+ test('isFetcher without locally', () => {
11
+ expect(isFetcher(isFetcherMock)).toBe(false);
12
+ });
13
+
14
+ test('isFetcher with locally', () => {
15
+ isFetcherMock.locally = jest.fn();
16
+
17
+ expect(isFetcher(isFetcherMock)).toBe(true);
18
+ });
19
+ });
@@ -11,6 +11,7 @@ import { ingestInCache } from '~/cache/api/ingestInCache';
11
11
  * Creates an {@link Amity.File<'video'>}
12
12
  *
13
13
  * @param formData The data necessary to create a new {@link Amity.File<'video'>}
14
+ * @param feedType The {@link Amity.File<'video'>} feed type
14
15
  * @param onProgress The callback to track the upload progress
15
16
  * @returns The newly created {@link Amity.File<'video'>}
16
17
  *
@@ -19,6 +20,7 @@ import { ingestInCache } from '~/cache/api/ingestInCache';
19
20
  */
20
21
  export const createVideo = async (
21
22
  formData: FormData,
23
+ feedType?: Amity.ContentFeedType,
22
24
  onProgress?: (percent: number) => void,
23
25
  ): Promise<Amity.Cached<Amity.File<'video'>[]>> => {
24
26
  const client = getActiveClient();
@@ -27,6 +29,10 @@ export const createVideo = async (
27
29
  if (!formData.getAll('files').length)
28
30
  throw new Error('The formData object must have a `files` key.');
29
31
 
32
+ if (feedType) {
33
+ formData.append('feedType', feedType);
34
+ }
35
+
30
36
  const headers =
31
37
  'getHeaders' in formData
32
38
  ? (formData as any).getHeaders()
@@ -28,7 +28,7 @@ export const acceptFollower = async (userId: Amity.User['userId']): Promise<bool
28
28
  ingestInCache(data);
29
29
  }
30
30
 
31
- fireEvent('follow.accepted', data.follows[0]);
31
+ fireEvent('follow.accepted', data);
32
32
 
33
33
  return true;
34
34
  };
@@ -28,7 +28,7 @@ export const declineFollower = async (userId: Amity.User['userId']): Promise<boo
28
28
  ingestInCache(data);
29
29
  }
30
30
 
31
- fireEvent('follow.requestDeclined', data.follows[0]);
31
+ fireEvent('follow.requestDeclined', data);
32
32
 
33
33
  return true;
34
34
  };