@amityco/ts-sdk 0.0.1-beta.37 → 0.0.1-beta.39

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 (251) hide show
  1. package/.eslintrc.json +3 -5
  2. package/dist/@types/core/events.d.ts +1 -0
  3. package/dist/@types/core/events.d.ts.map +1 -1
  4. package/dist/@types/core/model.d.ts +2 -0
  5. package/dist/@types/core/model.d.ts.map +1 -1
  6. package/dist/@types/domains/category.d.ts +7 -0
  7. package/dist/@types/domains/category.d.ts.map +1 -1
  8. package/dist/@types/domains/channel.d.ts +2 -2
  9. package/dist/@types/domains/channel.d.ts.map +1 -1
  10. package/dist/@types/domains/community.d.ts +12 -0
  11. package/dist/@types/domains/community.d.ts.map +1 -1
  12. package/dist/@types/domains/feed.d.ts +1 -2
  13. package/dist/@types/domains/feed.d.ts.map +1 -1
  14. package/dist/@types/domains/message.d.ts +1 -1
  15. package/dist/@types/domains/message.d.ts.map +1 -1
  16. package/dist/@types/domains/post.d.ts +1 -1
  17. package/dist/@types/domains/post.d.ts.map +1 -1
  18. package/dist/@types/domains/user.d.ts +8 -0
  19. package/dist/@types/domains/user.d.ts.map +1 -1
  20. package/dist/@types/global.d.ts +5 -0
  21. package/dist/@types/global.d.ts.map +1 -1
  22. package/dist/category/api/queryCategories.d.ts +1 -5
  23. package/dist/category/api/queryCategories.d.ts.map +1 -1
  24. package/dist/category/observers/index.d.ts +2 -0
  25. package/dist/category/observers/index.d.ts.map +1 -0
  26. package/dist/category/observers/liveCategories.d.ts +18 -0
  27. package/dist/category/observers/liveCategories.d.ts.map +1 -0
  28. package/dist/category/observers/tests/liveCategories.test.d.ts +2 -0
  29. package/dist/category/observers/tests/liveCategories.test.d.ts.map +1 -0
  30. package/dist/channel/api/tests/getChannels.test.d.ts +2 -0
  31. package/dist/channel/api/tests/getChannels.test.d.ts.map +1 -0
  32. package/dist/channel/api/tests/leaveChannel.test.d.ts +2 -0
  33. package/dist/channel/api/tests/leaveChannel.test.d.ts.map +1 -0
  34. package/dist/channel/observers/liveChannel.d.ts.map +1 -1
  35. package/dist/channel/observers/liveChannels.d.ts.map +1 -1
  36. package/dist/client/api/accessTokenExpiryWatcher.d.ts +4 -1
  37. package/dist/client/api/accessTokenExpiryWatcher.d.ts.map +1 -1
  38. package/dist/client/api/connectClient.d.ts.map +1 -1
  39. package/dist/client/api/getToken.d.ts +3 -1
  40. package/dist/client/api/getToken.d.ts.map +1 -1
  41. package/dist/client/utils/setClientToken.d.ts +3 -3
  42. package/dist/comment/api/deleteComment.d.ts.map +1 -1
  43. package/dist/comment/api/getComment.d.ts.map +1 -1
  44. package/dist/comment/observers/index.d.ts +1 -0
  45. package/dist/comment/observers/index.d.ts.map +1 -1
  46. package/dist/comment/observers/liveComment.d.ts +21 -0
  47. package/dist/comment/observers/liveComment.d.ts.map +1 -0
  48. package/dist/comment/observers/tests/liveComment.test.d.ts +2 -0
  49. package/dist/comment/observers/tests/liveComment.test.d.ts.map +1 -0
  50. package/dist/community/api/queryCommunities.d.ts +1 -10
  51. package/dist/community/api/queryCommunities.d.ts.map +1 -1
  52. package/dist/community/events/index.d.ts +1 -0
  53. package/dist/community/events/index.d.ts.map +1 -1
  54. package/dist/community/events/onCommunityUserChanged.d.ts +17 -0
  55. package/dist/community/events/onCommunityUserChanged.d.ts.map +1 -0
  56. package/dist/community/events/utils.d.ts +1 -0
  57. package/dist/community/events/utils.d.ts.map +1 -1
  58. package/dist/community/observers/index.d.ts +1 -0
  59. package/dist/community/observers/index.d.ts.map +1 -1
  60. package/dist/community/observers/liveCommunities.d.ts +20 -0
  61. package/dist/community/observers/liveCommunities.d.ts.map +1 -0
  62. package/dist/community/observers/tests/liveCommunities.test.d.ts +2 -0
  63. package/dist/community/observers/tests/liveCommunities.test.d.ts.map +1 -0
  64. package/dist/core/events.d.ts +3 -3
  65. package/dist/core/events.d.ts.map +1 -1
  66. package/dist/core/model/idResolvers.d.ts.map +1 -1
  67. package/dist/core/model/identifyModel.d.ts.map +1 -1
  68. package/dist/core/model/index.d.ts.map +1 -1
  69. package/dist/core/query/filtering.d.ts +10 -0
  70. package/dist/core/query/filtering.d.ts.map +1 -1
  71. package/dist/core/query/paging.d.ts +2 -2
  72. package/dist/core/query/paging.d.ts.map +1 -1
  73. package/dist/core/query/sorting.d.ts +6 -0
  74. package/dist/core/query/sorting.d.ts.map +1 -1
  75. package/dist/core/query/tests/paging.test.d.ts +2 -0
  76. package/dist/core/query/tests/paging.test.d.ts.map +1 -0
  77. package/dist/core/transports/http.d.ts +0 -5
  78. package/dist/core/transports/http.d.ts.map +1 -1
  79. package/dist/file/api/test/createImage.test.d.ts +2 -0
  80. package/dist/file/api/test/createImage.test.d.ts.map +1 -0
  81. package/dist/file/api/test/createVideo.test.d.ts +2 -0
  82. package/dist/file/api/test/createVideo.test.d.ts.map +1 -0
  83. package/dist/index.cjs.js +607 -252
  84. package/dist/index.d.ts +1 -0
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.esm.js +599 -251
  87. package/dist/index.umd.js +4 -4
  88. package/dist/message/api/queryMessages.d.ts +2 -2
  89. package/dist/message/api/queryMessages.d.ts.map +1 -1
  90. package/dist/message/observers/liveMessage.d.ts.map +1 -1
  91. package/dist/post/observers/index.d.ts +1 -0
  92. package/dist/post/observers/index.d.ts.map +1 -1
  93. package/dist/post/observers/livePost.d.ts +21 -0
  94. package/dist/post/observers/livePost.d.ts.map +1 -0
  95. package/dist/post/observers/livePosts.d.ts +2 -2
  96. package/dist/post/observers/livePosts.d.ts.map +1 -1
  97. package/dist/post/observers/tests/livePost.test.d.ts +2 -0
  98. package/dist/post/observers/tests/livePost.test.d.ts.map +1 -0
  99. package/dist/report/api/createReport.d.ts.map +1 -1
  100. package/dist/report/api/deleteReport.d.ts.map +1 -1
  101. package/dist/report/api/tests/createReport.test.d.ts +2 -0
  102. package/dist/report/api/tests/createReport.test.d.ts.map +1 -0
  103. package/dist/report/api/tests/deleteReport.test.d.ts +2 -0
  104. package/dist/report/api/tests/deleteReport.test.d.ts.map +1 -0
  105. package/dist/subChannel/api/tests/deleteSubChannel.test.d.ts +2 -0
  106. package/dist/subChannel/api/tests/deleteSubChannel.test.d.ts.map +1 -0
  107. package/dist/subChannel/api/tests/getSubChannel.test.d.ts +2 -0
  108. package/dist/subChannel/api/tests/getSubChannel.test.d.ts.map +1 -0
  109. package/dist/subChannel/api/tests/getSubChannels.test.d.ts +2 -0
  110. package/dist/subChannel/api/tests/getSubChannels.test.d.ts.map +1 -0
  111. package/dist/subChannel/api/tests/updateSubChannel.test.d.ts +2 -0
  112. package/dist/subChannel/api/tests/updateSubChannel.test.d.ts.map +1 -0
  113. package/dist/subChannel/observers/liveSubChannel.d.ts.map +1 -1
  114. package/dist/user/api/queryUsers.d.ts +1 -6
  115. package/dist/user/api/queryUsers.d.ts.map +1 -1
  116. package/dist/user/api/tests/updateUser.test.d.ts +2 -0
  117. package/dist/user/api/tests/updateUser.test.d.ts.map +1 -0
  118. package/dist/user/observers/index.d.ts +1 -0
  119. package/dist/user/observers/index.d.ts.map +1 -1
  120. package/dist/user/observers/liveUser.d.ts.map +1 -1
  121. package/dist/user/observers/liveUsers.d.ts +18 -0
  122. package/dist/user/observers/liveUsers.d.ts.map +1 -0
  123. package/dist/user/observers/tests/liveUsers.test.d.ts +2 -0
  124. package/dist/user/observers/tests/liveUsers.test.d.ts.map +1 -0
  125. package/dist/utils/liveObject.d.ts +2 -0
  126. package/dist/utils/liveObject.d.ts.map +1 -0
  127. package/dist/utils/tests/dummy/category.d.ts +64 -0
  128. package/dist/utils/tests/dummy/category.d.ts.map +1 -0
  129. package/dist/utils/tests/dummy/channel.d.ts +50 -0
  130. package/dist/utils/tests/dummy/channel.d.ts.map +1 -1
  131. package/dist/utils/tests/dummy/community.d.ts +132 -0
  132. package/dist/utils/tests/dummy/community.d.ts.map +1 -1
  133. package/dist/utils/tests/dummy/feed.d.ts +21 -0
  134. package/dist/utils/tests/dummy/feed.d.ts.map +1 -0
  135. package/dist/utils/tests/dummy/file.d.ts +3 -0
  136. package/dist/utils/tests/dummy/file.d.ts.map +1 -1
  137. package/dist/utils/tests/dummy/index.d.ts +2 -0
  138. package/dist/utils/tests/dummy/index.d.ts.map +1 -1
  139. package/dist/utils/tests/dummy/post.d.ts +11 -0
  140. package/dist/utils/tests/dummy/post.d.ts.map +1 -1
  141. package/dist/utils/tests/dummy/subChannel.d.ts +0 -20
  142. package/dist/utils/tests/dummy/subChannel.d.ts.map +1 -1
  143. package/dist/utils/tests/dummy/user.d.ts +81 -0
  144. package/dist/utils/tests/dummy/user.d.ts.map +1 -1
  145. package/dist/utils/tests/liveObject.test.d.ts +2 -0
  146. package/dist/utils/tests/liveObject.test.d.ts.map +1 -0
  147. package/package.json +4 -4
  148. package/src/@types/core/events.ts +1 -0
  149. package/src/@types/core/model.ts +4 -0
  150. package/src/@types/domains/category.ts +13 -0
  151. package/src/@types/domains/channel.ts +2 -2
  152. package/src/@types/domains/community.ts +25 -0
  153. package/src/@types/domains/feed.ts +1 -3
  154. package/src/@types/domains/message.ts +4 -1
  155. package/src/@types/domains/post.ts +1 -1
  156. package/src/@types/domains/user.ts +14 -0
  157. package/src/@types/global.ts +5 -0
  158. package/src/cache/api/tests/ingestInCache.test.ts +2 -0
  159. package/src/category/api/queryCategories.ts +3 -5
  160. package/src/category/observers/index.ts +1 -0
  161. package/src/category/observers/liveCategories.ts +141 -0
  162. package/src/category/observers/tests/liveCategories.test.ts +147 -0
  163. package/src/channel/api/tests/createChannel.test.ts +30 -6
  164. package/src/channel/api/tests/getChannel.test.ts +3 -1
  165. package/src/channel/api/tests/getChannels.test.ts +97 -0
  166. package/src/channel/api/tests/joinChannel.test.ts +62 -3
  167. package/src/channel/api/tests/leaveChannel.test.ts +90 -0
  168. package/src/channel/api/tests/queryChannels.test.ts +38 -1
  169. package/src/channel/observers/liveChannel.ts +8 -80
  170. package/src/channel/observers/liveChannels.ts +29 -24
  171. package/src/client/api/accessTokenExpiryWatcher.ts +7 -5
  172. package/src/client/api/connectClient.ts +0 -2
  173. package/src/client/api/tests/accessTokenExpiryWatcher.test.ts +8 -5
  174. package/src/comment/api/deleteComment.ts +5 -5
  175. package/src/comment/api/getComment.ts +8 -3
  176. package/src/comment/observers/index.ts +1 -0
  177. package/src/comment/observers/liveComment.ts +43 -0
  178. package/src/comment/observers/tests/liveComment.test.ts +95 -0
  179. package/src/community/api/queryCommunities.ts +3 -10
  180. package/src/community/api/test/addCommunityMember.test.ts +14 -2
  181. package/src/community/api/test/joinCommunity.test.ts +14 -2
  182. package/src/community/api/test/leaveCommunity.test.ts +11 -1
  183. package/src/community/api/test/removeCommunityMembers.test.ts +11 -1
  184. package/src/community/events/index.ts +1 -0
  185. package/src/community/events/onCommunityUserChanged.ts +20 -0
  186. package/src/community/events/test/onCommunityJoined.test.ts +1 -1
  187. package/src/community/events/test/onCommunityUserAdded.test.ts +1 -1
  188. package/src/community/events/test/onCommunityUserBanned.test.ts +1 -1
  189. package/src/community/events/test/onCommunityUserUnbaned.test.ts +1 -1
  190. package/src/community/events/test/utils.test.ts +52 -3
  191. package/src/community/events/utils.ts +49 -0
  192. package/src/community/observers/index.ts +1 -0
  193. package/src/community/observers/liveCommunities.ts +188 -0
  194. package/src/community/observers/tests/liveCommunities.test.ts +284 -0
  195. package/src/core/model/idResolvers.ts +2 -0
  196. package/src/core/model/identifyModel.ts +1 -0
  197. package/src/core/model/index.ts +2 -0
  198. package/src/core/query/filtering.ts +33 -3
  199. package/src/core/query/paging.ts +5 -4
  200. package/src/core/query/sorting.ts +8 -0
  201. package/src/core/query/tests/paging.test.ts +66 -0
  202. package/src/core/transports/http.ts +17 -13
  203. package/src/core/transports/test/http.test.ts +49 -60
  204. package/src/file/api/createFile.ts +1 -1
  205. package/src/file/api/createImage.ts +1 -1
  206. package/src/file/api/createVideo.ts +1 -1
  207. package/src/file/api/test/createImage.test.ts +69 -0
  208. package/src/file/api/test/createVideo.test.ts +81 -0
  209. package/src/index.ts +1 -0
  210. package/src/message/api/queryMessages.ts +7 -7
  211. package/src/message/api/tests/queryMessages.test.ts +6 -6
  212. package/src/message/observers/liveMessage.ts +11 -83
  213. package/src/message/tests/observers/liveMessage.test.ts +1 -143
  214. package/src/message/tests/observers/liveMessages.test.ts +4 -4
  215. package/src/post/observers/index.ts +1 -0
  216. package/src/post/observers/livePost.ts +47 -0
  217. package/src/post/observers/livePosts.ts +14 -22
  218. package/src/post/observers/tests/livePost.test.ts +97 -0
  219. package/src/post/observers/tests/livePosts.test.ts +65 -8
  220. package/src/report/api/createReport.ts +1 -6
  221. package/src/report/api/deleteReport.ts +2 -6
  222. package/src/report/api/tests/createReport.test.ts +93 -0
  223. package/src/report/api/tests/deleteReport.test.ts +93 -0
  224. package/src/stream/api/tests/createStream.test.ts +3 -11
  225. package/src/stream/api/tests/deleteStream.test.ts +5 -3
  226. package/src/subChannel/api/tests/createSubChannel.test.ts +21 -14
  227. package/src/subChannel/api/tests/deleteSubChannel.test.ts +112 -0
  228. package/src/subChannel/api/tests/getSubChannel.test.ts +97 -0
  229. package/src/subChannel/api/tests/getSubChannels.test.ts +97 -0
  230. package/src/subChannel/api/tests/updateSubChannel.test.ts +86 -0
  231. package/src/subChannel/observers/liveSubChannel.ts +6 -56
  232. package/src/subChannel/observers/tests/liveSubChannel.test.ts +0 -82
  233. package/src/user/api/queryUsers.ts +1 -6
  234. package/src/user/api/tests/updateUser.test.ts +60 -0
  235. package/src/user/observers/index.ts +1 -0
  236. package/src/user/observers/liveUser.ts +9 -61
  237. package/src/user/observers/liveUsers.ts +162 -0
  238. package/src/user/observers/tests/liveUsers.test.ts +202 -0
  239. package/src/user/tests/observers/liveUser.test.ts +1 -154
  240. package/src/utils/liveObject.ts +86 -0
  241. package/src/utils/tests/dummy/category.ts +57 -0
  242. package/src/utils/tests/dummy/channel.ts +52 -1
  243. package/src/utils/tests/dummy/community.ts +94 -0
  244. package/src/utils/tests/dummy/feed.ts +13 -0
  245. package/src/utils/tests/dummy/file.ts +32 -0
  246. package/src/utils/tests/dummy/index.ts +3 -0
  247. package/src/utils/tests/dummy/post.ts +62 -47
  248. package/src/utils/tests/dummy/stream.ts +73 -73
  249. package/src/utils/tests/dummy/subChannel.ts +0 -22
  250. package/src/utils/tests/dummy/user.ts +57 -0
  251. package/src/utils/tests/liveObject.test.ts +172 -0
package/dist/index.esm.js CHANGED
@@ -3,7 +3,6 @@ import AsyncStorage from '@react-native-async-storage/async-storage';
3
3
  import mitt from 'mitt';
4
4
  import debug from 'debug';
5
5
  import axios from 'axios';
6
- import qs from 'qs';
7
6
  import HttpAgent, { HttpsAgent } from 'agentkeepalive';
8
7
  import io from 'socket.io-client';
9
8
  import nativeIdGenerator from 'react-native-uuid';
@@ -164,14 +163,14 @@ const partialMatch = (predicate, candidate) => {
164
163
  const checkIfShouldGoesToTombstone = (errorCode) => [400400 /* Amity.ServerError.ITEM_NOT_FOUND */, 400300 /* Amity.ServerError.FORBIDDEN */].includes(errorCode);
165
164
 
166
165
  /**
167
- * Type guard to find if the a given decoded backend token uses "skip/limit" pagination style
166
+ * Type guard to find if the a given decoded backend token uses "skip" pagination style
168
167
  *
169
168
  * @param json any json object as extracted from the backend
170
169
  * @returns success boolean if the token has either "skip" or "limit" props
171
170
  *
172
171
  * @hidden
173
172
  */
174
- const isSkipLimit = (json) => ['skip', 'limit'].some(prop => prop in json);
173
+ const isSkip = (json) => ['skip'].some(prop => prop in json);
175
174
  /**
176
175
  * Type guard to find if the a given decoded backend token uses "after/before" pagination style
177
176
  *
@@ -271,7 +270,7 @@ const toPage = (token) => {
271
270
  return undefined;
272
271
  // don't try catch, let it throw
273
272
  const json = JSON.parse(decode(token));
274
- if (isSkipLimit(json)) {
273
+ if (isSkip(json)) {
275
274
  return {
276
275
  after: json.skip,
277
276
  limit: json.limit,
@@ -498,6 +497,7 @@ const idResolvers = {
498
497
  stream: ({ streamId }) => streamId,
499
498
  follow: ({ from, to }) => `${from}#${to}`,
500
499
  followCount: ({ userId }) => userId,
500
+ feed: ({ targetId, feedId }) => `${targetId}#${feedId}`,
501
501
  };
502
502
  /**
503
503
  * Retrieve the id resolver matching a domain name
@@ -535,6 +535,7 @@ const CRITERIAS = {
535
535
  stream: ['streamId'],
536
536
  follow: ['from', 'to'],
537
537
  followCount: ['userId', 'followerCount'],
538
+ feed: ['feedId', 'feedType'],
538
539
  };
539
540
  /** @hidden */
540
541
  const hasKeys = (object, needles) => {
@@ -595,6 +596,7 @@ const PAYLOAD2MODEL = {
595
596
  videoStreamings: 'stream',
596
597
  follows: 'follow',
597
598
  followCounts: 'followCount',
599
+ feeds: 'feed',
598
600
  };
599
601
  /** hidden */
600
602
  const hasUpdates = (prevData, nextData) => {
@@ -1061,10 +1063,36 @@ const filterByChannelMembership = (collection, membership, userId) => {
1061
1063
  'get',
1062
1064
  channelUserCacheKey,
1063
1065
  ])) === null || _a === void 0 ? void 0 : _a.data;
1064
- if (membership === 'member' && channelUser && channelUser.membership !== 'none') {
1065
- return true;
1066
+ if (membership === 'member') {
1067
+ return channelUser && channelUser.membership !== 'none';
1066
1068
  }
1067
- return membership === 'notMember' && (!channelUser || channelUser.membership === 'none');
1069
+ // only membership value remainging is 'notMember'
1070
+ return !channelUser || channelUser.membership === 'none';
1071
+ });
1072
+ };
1073
+ /**
1074
+ * Filter a channel collection by membership of the userId
1075
+ *
1076
+ * @param collection the channel collection to filter
1077
+ * @param feedType to be filtered by
1078
+ * @returns a filtered collection with items only matching the criteria
1079
+ *
1080
+ * @hidden
1081
+ */
1082
+ const filterByFeedType = (collection, feedType) => {
1083
+ /*
1084
+ * It is possible that the targetId & feedId are the same for most of the posts
1085
+ * But since cache is in-memory, i've avoided memoizing, to avoid premature
1086
+ * optimization. Can be revisited if performance issues arise
1087
+ */
1088
+ return collection.filter(({ targetId, feedId }) => {
1089
+ var _a;
1090
+ const feed = (_a = pullFromCache([
1091
+ 'feed',
1092
+ 'get',
1093
+ getResolver('feed')({ targetId, feedId }),
1094
+ ])) === null || _a === void 0 ? void 0 : _a.data;
1095
+ return feed && feed.feedType === feedType;
1068
1096
  });
1069
1097
  };
1070
1098
 
@@ -1079,6 +1107,14 @@ const sortByDisplayName = ({ displayName: a }, { displayName: b }) => {
1079
1107
  return 0;
1080
1108
  return a < b ? -1 : 1;
1081
1109
  };
1110
+ /**
1111
+ * Alphabetic sorting of objects having a name
1112
+ */
1113
+ const sortByName = ({ name: a }, { name: b }) => {
1114
+ if (a === b)
1115
+ return 0;
1116
+ return a < b ? -1 : 1;
1117
+ };
1082
1118
  /**
1083
1119
  * Sorting a collection by their apparition order (oldest first)
1084
1120
  */
@@ -1382,13 +1418,6 @@ const unwrapPayload = (response) => {
1382
1418
  return undefined;
1383
1419
  };
1384
1420
 
1385
- /**
1386
- * Axios param serializer (for querystring)
1387
- * @hidden
1388
- */
1389
- const stringify = (params) => {
1390
- return qs.stringify(params, { arrayFormat: 'brackets' });
1391
- };
1392
1421
  /**
1393
1422
  * Creates a pre-configured axios instance
1394
1423
  *
@@ -1409,7 +1438,14 @@ const createHttpTransport = (endpoint) => {
1409
1438
  baseURL: endpoint,
1410
1439
  httpAgent: new HttpAgent(options),
1411
1440
  httpsAgent: new HttpsAgent(options),
1412
- paramsSerializer: stringify,
1441
+ /*
1442
+ * If paramSerializer is required, use the serialize option to stringify
1443
+ * params. The encode option will pass complex params as string only whereas
1444
+ * the serialize option will pass params in the format Record<string, any>
1445
+ *
1446
+ * For more details:
1447
+ * https://github.com/axios/axios#request-config
1448
+ */
1413
1449
  });
1414
1450
  instance.interceptors.request.use(config => {
1415
1451
  var _a;
@@ -1423,10 +1459,8 @@ const createHttpTransport = (endpoint) => {
1423
1459
  return config;
1424
1460
  });
1425
1461
  instance.interceptors.response.use(response => response, error => {
1426
- var _a;
1462
+ var _a, _b;
1427
1463
  const { response } = error;
1428
- // eslint-disable-next-line no-console
1429
- console.error((_a = response === null || response === void 0 ? void 0 : response.data) !== null && _a !== void 0 ? _a : error);
1430
1464
  // handle unauthorized request
1431
1465
  if (response.data.code === 400100 /* Amity.ServerError.UNAUTHORIZED */) {
1432
1466
  fireEvent('tokenTerminated', "terminated" /* Amity.SessionStates.TERMINATED */);
@@ -1436,8 +1470,15 @@ const createHttpTransport = (endpoint) => {
1436
1470
  fireEvent('tokenExpired', "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */);
1437
1471
  throw new ASCError('Token expired', 800403 /* Amity.ClientError.TOKEN_EXPIRED */, "fatal" /* Amity.ErrorLevel.FATAL */);
1438
1472
  }
1439
- if (response === null || response === void 0 ? void 0 : response.data)
1440
- unwrapPayload(response.data);
1473
+ // if it's an error with status in the response payload,
1474
+ // then it's an expected error.
1475
+ if ((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.status) {
1476
+ unwrapPayload(response === null || response === void 0 ? void 0 : response.data);
1477
+ }
1478
+ // unexpected error.
1479
+ else {
1480
+ throw new Error((_b = response === null || response === void 0 ? void 0 : response.data) !== null && _b !== void 0 ? _b : error);
1481
+ }
1441
1482
  });
1442
1483
  return instance;
1443
1484
  };
@@ -20794,7 +20835,7 @@ const connectClient = async (params, sessionHandler, config) => {
20794
20835
  setSessionState(state);
20795
20836
  disconnectClient();
20796
20837
  subscriptions.forEach(fn => fn());
20797
- }), onUserDeleted(() => null));
20838
+ }));
20798
20839
  return client.ws.connected;
20799
20840
  };
20800
20841
 
@@ -20877,7 +20918,8 @@ const isExpired = (expiresAt) => Date.now() > Date.parse(expiresAt) - COMPENSATE
20877
20918
  *
20878
20919
  * @category private
20879
20920
  */
20880
- const isAboutToExpire = (expiresAt, issuedAt) => {
20921
+ const isAboutToExpire = (params) => {
20922
+ const { expiresAt, issuedAt } = params;
20881
20923
  const expires = Date.parse(expiresAt);
20882
20924
  const issued = Date.parse(issuedAt);
20883
20925
  const now = Date.now();
@@ -20912,7 +20954,7 @@ const accessTokenExpiryWatcher = (expiresAt, issuedAt, sessionHandler) => {
20912
20954
  scheduleTask(() => sessionHandler.sessionWillRenewAccessToken(renewal()));
20913
20955
  return;
20914
20956
  }
20915
- if (isAboutToExpire(issuedAt, expiresAt)) {
20957
+ if (isAboutToExpire({ expiresAt, issuedAt })) {
20916
20958
  sessionHandler.sessionWillRenewAccessToken(renewal());
20917
20959
  }
20918
20960
  }, ACCESS_TOKEN_WATCHER_INTERVAL);
@@ -21383,6 +21425,58 @@ const onUserUnflagged = (callback) => createUserEventSubscriber('user.unflagged'
21383
21425
  */
21384
21426
  const onUserFlagCleared = (callback) => createUserEventSubscriber('user.flagCleared', callback);
21385
21427
 
21428
+ const liveObject = (id, callback, key, fetcher, eventHandlers) => {
21429
+ const { cache } = getActiveClient();
21430
+ if (!cache) {
21431
+ console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
21432
+ }
21433
+ let model;
21434
+ let isUnsyncedModel = false; // for messages
21435
+ const disposers = [];
21436
+ const dispatcher = (data) => {
21437
+ model = data.data;
21438
+ callback(data);
21439
+ };
21440
+ const realtimeRouter = (eventModel) => {
21441
+ if (id !== eventModel[key]) {
21442
+ return;
21443
+ }
21444
+ if (model && !hasUpdates(model, eventModel)) {
21445
+ return;
21446
+ }
21447
+ dispatcher({ loading: false, data: eventModel, origin: 'event' });
21448
+ };
21449
+ const onFetch = () => {
21450
+ // @ts-ignore
21451
+ const query = createQuery(fetcher, id, true);
21452
+ runQuery(query, ({ error, data, loading, origin, cachedAt }) => {
21453
+ if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
21454
+ dispatcher({
21455
+ // @ts-ignore
21456
+ data,
21457
+ origin,
21458
+ loading: false,
21459
+ error: new ASCApiError(UNSYNCED_OBJECT_CACHED_AT_MESSAGE, 800800 /* Amity.ClientError.DISALOOW_UNSYNCED_OBJECT */, "error" /* Amity.ErrorLevel.ERROR */),
21460
+ });
21461
+ isUnsyncedModel = true;
21462
+ disposers.forEach(fn => fn());
21463
+ }
21464
+ else if (!isUnsyncedModel) {
21465
+ // @ts-ignore
21466
+ dispatcher({ loading, data, origin, error });
21467
+ }
21468
+ if (error) {
21469
+ disposers.forEach(fn => fn());
21470
+ }
21471
+ });
21472
+ };
21473
+ disposers.push(...eventHandlers.map(fn => fn(realtimeRouter)));
21474
+ onFetch();
21475
+ return () => {
21476
+ disposers.forEach(fn => fn());
21477
+ };
21478
+ };
21479
+
21386
21480
  /**
21387
21481
  * ```js
21388
21482
  * import { onUserFetched } from '@amityco/ts-sdk'
@@ -21420,40 +21514,107 @@ const onUserFetched = (callback) => createUserEventSubscriber('user.fetched', ca
21420
21514
  * @category Message Live Object
21421
21515
  */
21422
21516
  const liveUser = (userId, callback) => {
21517
+ return liveObject(userId, callback, 'userId', getUser, [
21518
+ onUserFetched,
21519
+ onUserUpdated,
21520
+ onUserDeleted,
21521
+ onUserFlagged,
21522
+ onUserUnflagged,
21523
+ onUserFlagCleared,
21524
+ ]);
21525
+ };
21526
+
21527
+ /**
21528
+ * ```js
21529
+ * import { liveUsers } from '@amityco/ts-sdk'
21530
+ *
21531
+ * let users = []
21532
+ * const unsub = liveUsers({}, response => merge(users, response.data))
21533
+ * ```
21534
+ *
21535
+ * Observe all mutations on a list of {@link Amity.User}s
21536
+ *
21537
+ * @param params for querying users
21538
+ * @param callback the function to call when new data are available
21539
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the users
21540
+ *
21541
+ * @category Category Live Collection
21542
+ */
21543
+ const liveUsers = (params, callback, config) => {
21423
21544
  const { log, cache } = getActiveClient();
21424
- const timestamp = Date.now();
21425
- log(`liveUser(tmpid: ${timestamp}) > listen`);
21426
21545
  if (!cache) {
21427
- console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
21546
+ console.log(ENABLE_CACHE_MESSAGE);
21428
21547
  }
21429
- let user;
21548
+ const timestamp = Date.now();
21549
+ log(`liveUsers(tmpid: ${timestamp}) > listen`);
21550
+ const { limit: queryLimit } = params, queryParams = __rest(params, ["limit"]);
21551
+ const limit = queryLimit !== null && queryLimit !== void 0 ? queryLimit : COLLECTION_DEFAULT_PAGINATION_LIMIT;
21552
+ const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config !== null && config !== void 0 ? config : {};
21430
21553
  const disposers = [];
21431
- const dispatcher = (data) => {
21432
- user = data.data;
21433
- callback(data);
21434
- };
21435
- const realtimeRouter = (eventUser) => {
21436
- if (userId !== eventUser.userId) {
21437
- return;
21554
+ const cacheKey = ['user', 'collection', {}];
21555
+ const responder = (data) => {
21556
+ var _a, _b;
21557
+ let users = (_a = data.data
21558
+ .map(userId => pullFromCache(['user', 'get', userId]))
21559
+ .filter(Boolean)
21560
+ .map(({ data }) => data)) !== null && _a !== void 0 ? _a : [];
21561
+ users = filterByPropEquality(users, 'displayName', params.displayName);
21562
+ switch (params.sortBy) {
21563
+ case 'firstCreated':
21564
+ users = users.sort(sortByFirstCreated);
21565
+ break;
21566
+ case 'lastCreated':
21567
+ users = users.sort(sortByLastCreated);
21568
+ break;
21569
+ default:
21570
+ users = users
21571
+ // this needs to be aligned with the backend data type
21572
+ .map(u => (u.displayName ? u : Object.assign(Object.assign({}, u), { displayName: '' })))
21573
+ // @ts-ignore
21574
+ .sort(sortByDisplayName);
21438
21575
  }
21439
- if (user && !hasUpdates(user, eventUser)) {
21576
+ callback({
21577
+ onNextPage: onFetch,
21578
+ data: users,
21579
+ hasNextPage: !!((_b = data.params) === null || _b === void 0 ? void 0 : _b.page),
21580
+ loading: data.loading,
21581
+ error: data.error,
21582
+ });
21583
+ };
21584
+ const realtimeRouter = (_) => (user) => {
21585
+ var _a;
21586
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
21587
+ if (!collection)
21440
21588
  return;
21441
- }
21442
- dispatcher({ loading: false, data: eventUser, origin: 'event' });
21589
+ collection.data = [...new Set([user.userId, ...collection.data])];
21590
+ pushToCache(cacheKey, collection);
21591
+ responder(collection);
21443
21592
  };
21444
21593
  const onFetch = () => {
21445
- const query = createQuery(getUser, userId, true);
21446
- runQuery(query, ({ loading, data, error, origin }) => {
21447
- dispatcher({ loading, data, origin, error });
21448
- if (error) {
21449
- disposers.forEach(fn => fn());
21594
+ var _a, _b, _c;
21595
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
21596
+ const users = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
21597
+ if (users.length > 0 && !(collection === null || collection === void 0 ? void 0 : collection.params.page))
21598
+ return;
21599
+ const query = createQuery(queryUsers, Object.assign(Object.assign({}, queryParams), { page: (_c = collection === null || collection === void 0 ? void 0 : collection.params.page) !== null && _c !== void 0 ? _c : { limit } }));
21600
+ runQuery(query, ({ data: result, error, loading, nextPage: page }) => {
21601
+ const data = {
21602
+ loading,
21603
+ error,
21604
+ params: { page },
21605
+ data: users,
21606
+ };
21607
+ if (result) {
21608
+ data.data = [...new Set([...users, ...result.map(getResolver('user'))])];
21450
21609
  }
21451
- });
21610
+ pushToCache(cacheKey, data);
21611
+ responder(data);
21612
+ }, queryOptions(policy));
21452
21613
  };
21453
- disposers.push(onUserFetched(realtimeRouter), onUserUpdated(realtimeRouter), onUserDeleted(realtimeRouter), onUserFlagged(realtimeRouter), onUserUnflagged(realtimeRouter), onUserFlagCleared(realtimeRouter));
21614
+ disposers.push(onUserUpdated(realtimeRouter()), onUserDeleted(realtimeRouter()), onUserFlagged(realtimeRouter()), onUserUnflagged(realtimeRouter()), onUserFlagCleared(realtimeRouter()));
21454
21615
  onFetch();
21455
21616
  return () => {
21456
- log(`liveUser(tmpid: ${timestamp}) > dispose`);
21617
+ log(`liveUsers(tmpid: ${timestamp}) > dispose`);
21457
21618
  disposers.forEach(fn => fn());
21458
21619
  };
21459
21620
  };
@@ -21579,7 +21740,7 @@ const createFile = async (formData, onProgress) => {
21579
21740
  : { 'content-type': 'multipart/form-data' };
21580
21741
  const { data } = await client.http.post('/api/v4/files', formData, {
21581
21742
  headers,
21582
- onUploadProgress({ loaded, total }) {
21743
+ onUploadProgress({ loaded, total = 100 }) {
21583
21744
  onProgress && onProgress(Math.round((loaded * 100) / total));
21584
21745
  },
21585
21746
  });
@@ -21658,7 +21819,7 @@ const createVideo = async (formData, feedType, onProgress) => {
21658
21819
  : { 'content-type': 'multipart/form-data' };
21659
21820
  const { data } = await client.http.post('/api/v4/videos', formData, {
21660
21821
  headers,
21661
- onUploadProgress({ loaded, total }) {
21822
+ onUploadProgress({ loaded, total = 100 }) {
21662
21823
  onProgress && onProgress(Math.round((loaded * 100) / total));
21663
21824
  },
21664
21825
  });
@@ -21699,7 +21860,7 @@ const createImage = async (formData, onProgress) => {
21699
21860
  : { 'content-type': 'multipart/form-data' };
21700
21861
  const { data } = await client.http.post('/api/v4/images', formData, {
21701
21862
  headers,
21702
- onUploadProgress({ loaded, total }) {
21863
+ onUploadProgress({ loaded, total = 100 }) {
21703
21864
  onProgress && onProgress(Math.round((loaded * 100) / total));
21704
21865
  },
21705
21866
  });
@@ -22139,8 +22300,8 @@ const queryMessages = async (query) => {
22139
22300
  pushToCache(cacheKey, { messages: messages.map(getResolver('message')), paging });
22140
22301
  }
22141
22302
  fireEvent('local.message.fetched', { messages });
22142
- const nextPage = toPage(paging.next);
22143
- const prevPage = toPage(paging.previous);
22303
+ const nextPage = toPageRaw(paging.next);
22304
+ const prevPage = toPageRaw(paging.previous);
22144
22305
  return { data: messages, cachedAt, prevPage, nextPage };
22145
22306
  };
22146
22307
  /**
@@ -22171,8 +22332,8 @@ queryMessages.locally = (query) => {
22171
22332
  .map(messageId => pullFromCache(['message', 'get', messageId]))
22172
22333
  .filter(Boolean)
22173
22334
  .map(({ data }) => data);
22174
- const prevPage = toPage(data === null || data === void 0 ? void 0 : data.paging.previous);
22175
- const nextPage = toPage(data === null || data === void 0 ? void 0 : data.paging.next);
22335
+ const prevPage = toPageRaw(data === null || data === void 0 ? void 0 : data.paging.previous);
22336
+ const nextPage = toPageRaw(data === null || data === void 0 ? void 0 : data.paging.next);
22176
22337
  return messages.length === ((_b = data === null || data === void 0 ? void 0 : data.messages) === null || _b === void 0 ? void 0 : _b.length)
22177
22338
  ? { data: messages, cachedAt, prevPage, nextPage }
22178
22339
  : undefined;
@@ -23678,6 +23839,7 @@ getComments.locally = (commentIds) => {
23678
23839
  const getComment = async (commentId) => {
23679
23840
  const client = getActiveClient();
23680
23841
  client.log('comment/getComment', commentId);
23842
+ isInTombstone('comment', commentId);
23681
23843
  let data;
23682
23844
  try {
23683
23845
  // API-FIX: endpoint should not be /list, parameters should be querystring.
@@ -23685,8 +23847,8 @@ const getComment = async (commentId) => {
23685
23847
  data = response.data;
23686
23848
  }
23687
23849
  catch (error) {
23688
- if ((error === null || error === void 0 ? void 0 : error.code) === 400400 /* Amity.ServerError.ITEM_NOT_FOUND */) {
23689
- dropFromCache(['comment', 'get', commentId], true);
23850
+ if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
23851
+ pushToTombstone('comment', commentId);
23690
23852
  }
23691
23853
  throw error;
23692
23854
  }
@@ -23820,9 +23982,7 @@ const deleteComment = async (commentId, permanent = false) => {
23820
23982
  fireEvent('post.updated', { posts: [post.data] });
23821
23983
  fireEvent('comment.deleted', { comments: [deleted] });
23822
23984
  if (permanent) {
23823
- setTimeout(() => {
23824
- dropFromCache(['comment', 'get', commentId], true);
23825
- }, 0);
23985
+ scheduleTask(() => pushToTombstone('comment', commentId));
23826
23986
  }
23827
23987
  else {
23828
23988
  upsertInCache(['comment', 'get', commentId], { isDeleted: true });
@@ -24818,13 +24978,7 @@ const createReport = async (referenceType, referenceId) => {
24818
24978
  const { data } = await client.http.post(getAPIUrl());
24819
24979
  if (client.cache)
24820
24980
  ingestInCache(referenceType === 'message' ? prepareMessagePayload(data) : data);
24821
- if (referenceType === 'message') {
24822
- fireEvent('message.flagged', data);
24823
- }
24824
- else {
24825
- // @ts-ignore
24826
- fireEvent(`${referenceType}.flagged`, data);
24827
- }
24981
+ fireEvent(`${referenceType}.flagged`, data);
24828
24982
  return !!data;
24829
24983
  };
24830
24984
 
@@ -24857,13 +25011,8 @@ const deleteReport = async (referenceType, referenceId) => {
24857
25011
  const { data } = await client.http.delete(getAPIUrl());
24858
25012
  if (client.cache)
24859
25013
  ingestInCache(referenceType === 'message' ? prepareMessagePayload(data) : data);
24860
- if (referenceType === 'message') {
24861
- fireEvent('message.unflagged', data);
24862
- }
24863
- else {
24864
- // @ts-ignore
24865
- fireEvent(`${referenceType}.unflagged`, data);
24866
- }
25014
+ // @ts-ignore
25015
+ fireEvent(`${referenceType}.unflagged`, data);
24867
25016
  return !!data;
24868
25017
  };
24869
25018
 
@@ -26245,55 +26394,13 @@ const onMessageReactionRemoved = (callback) => {
26245
26394
  * @category Message Live Object
26246
26395
  */
26247
26396
  const liveChannel = (channelId, callback) => {
26248
- const { log, cache } = getActiveClient();
26249
- const timestamp = Date.now();
26250
- log(`liveChannel(tmpid: ${timestamp}) > listen`);
26251
- if (!cache) {
26252
- console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
26253
- }
26254
- let channel;
26255
- let isUnsyncedObject = false;
26256
- const disposers = [];
26257
- const dispatcher = (data) => {
26258
- channel = data.data;
26259
- callback(data);
26260
- };
26261
- const realtimeRouter = (eventChannel) => {
26262
- if (channelId !== eventChannel.channelId) {
26263
- return;
26264
- }
26265
- if (channel && !hasUpdates(channel, eventChannel)) {
26266
- return;
26267
- }
26268
- dispatcher({ loading: false, data: eventChannel, origin: 'event' });
26269
- };
26270
- const onFetch = () => {
26271
- const query = createQuery(getChannel, channelId);
26272
- runQuery(query, ({ loading, data, error, origin, cachedAt }) => {
26273
- if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
26274
- dispatcher({
26275
- data,
26276
- origin,
26277
- loading: false,
26278
- error: new ASCApiError(UNSYNCED_OBJECT_CACHED_AT_MESSAGE, 800800 /* Amity.ClientError.DISALOOW_UNSYNCED_OBJECT */, "error" /* Amity.ErrorLevel.ERROR */),
26279
- });
26280
- isUnsyncedObject = true;
26281
- disposers.forEach(fn => fn());
26282
- }
26283
- else if (!isUnsyncedObject) {
26284
- dispatcher({ loading, data, origin, error });
26285
- }
26286
- if (error) {
26287
- disposers.forEach(fn => fn());
26288
- }
26289
- });
26290
- };
26291
- disposers.push(onChannelUpdated(realtimeRouter), onChannelDeleted(realtimeRouter), onChannelJoined(realtimeRouter), onChannelMuted(realtimeRouter), onMessageCreated(() => null));
26292
- onFetch();
26293
- return () => {
26294
- log(`liveChannel(tmpid: ${timestamp}) > dispose`);
26295
- disposers.forEach(fn => fn());
26296
- };
26397
+ return liveObject(channelId, callback, 'channelId', getChannel, [
26398
+ onChannelUpdated,
26399
+ onChannelDeleted,
26400
+ onChannelJoined,
26401
+ onChannelMuted,
26402
+ () => onMessageCreated(() => null), // watch unread count
26403
+ ]);
26297
26404
  };
26298
26405
 
26299
26406
  /**
@@ -26347,22 +26454,29 @@ const liveChannels = (params, callback, config) => {
26347
26454
  if (params.membership && userId) {
26348
26455
  channels = filterByChannelMembership(channels, params.membership, userId);
26349
26456
  }
26350
- const sortBy = params.sortBy || 'lastCreated';
26351
- if (sortBy === 'lastCreated' || sortBy === 'firstCreated') {
26352
- channels = channels.sort(sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated);
26353
- }
26354
- /*
26355
- * The server returns channels with empty | null displayName's first before
26356
- * returning sorted list of channels with displayNames
26357
- *
26358
- * This section needs to be updated as displayNames can be null as well
26359
- */
26360
- if (sortBy === 'displayName') {
26361
- channels = channels
26362
- // this needs to be aligned with the backend data type
26363
- .map(c => (c.displayName ? c : Object.assign(Object.assign({}, c), { displayName: '' })))
26364
- // @ts-ignore
26365
- .sort(sortByDisplayName);
26457
+ switch (params.sortBy) {
26458
+ case 'firstCreated':
26459
+ channels = channels.sort(sortByFirstCreated);
26460
+ break;
26461
+ case 'lastCreated':
26462
+ channels = channels.sort(sortByLastCreated);
26463
+ break;
26464
+ case 'displayName':
26465
+ /*
26466
+ * The server returns channels with empty | null displayName's first before
26467
+ * returning sorted list of channels with displayNames
26468
+ *
26469
+ * This section needs to be updated as displayNames can be null as well
26470
+ */
26471
+ channels = channels
26472
+ // this needs to be aligned with the backend data type
26473
+ .map(c => (c.displayName ? c : Object.assign(Object.assign({}, c), { displayName: '' })))
26474
+ // @ts-ignore
26475
+ .sort(sortByDisplayName);
26476
+ break;
26477
+ default:
26478
+ channels = channels.sort(sortByLastActivity);
26479
+ break;
26366
26480
  }
26367
26481
  callback({
26368
26482
  onNextPage: onFetch,
@@ -26372,17 +26486,12 @@ const liveChannels = (params, callback, config) => {
26372
26486
  error: data.error,
26373
26487
  });
26374
26488
  };
26375
- const realtimeRouter = (action) => (channel) => {
26489
+ const realtimeRouter = (_) => (channel) => {
26376
26490
  var _a;
26377
26491
  const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
26378
26492
  if (!collection)
26379
26493
  return;
26380
- if (action === 'onDelete' && params.isDeleted === false) {
26381
- collection.data = collection.data.filter(c => c !== channel.channelId);
26382
- }
26383
- else {
26384
- collection.data = [...new Set([channel.channelId, ...collection.data])];
26385
- }
26494
+ collection.data = [...new Set([channel.channelId, ...collection.data])];
26386
26495
  pushToCache(cacheKey, collection);
26387
26496
  responder(collection);
26388
26497
  };
@@ -26407,7 +26516,7 @@ const liveChannels = (params, callback, config) => {
26407
26516
  responder(data);
26408
26517
  }, queryOptions(policy));
26409
26518
  };
26410
- disposers.push(onChannelCreated(realtimeRouter('onCreate')), onChannelDeleted(realtimeRouter('onDelete')), onChannelUpdated(realtimeRouter('onUpdate')), onChannelMuted(realtimeRouter('onMute')), onChannelJoined(realtimeRouter('onJoin')), onChannelLeft(realtimeRouter('onLeft')), onChannelMemberAdded(realtimeRouter('onMemberAdded')), onChannelMemberRemoved(realtimeRouter('onMemberRemoved')), onMessageCreated(() => null));
26519
+ disposers.push(onChannelCreated(realtimeRouter()), onChannelDeleted(realtimeRouter()), onChannelUpdated(realtimeRouter()), onChannelMuted(realtimeRouter()), onChannelJoined(realtimeRouter()), onChannelLeft(realtimeRouter()), onChannelMemberAdded(realtimeRouter()), onChannelMemberRemoved(realtimeRouter()), onMessageCreated(() => null));
26411
26520
  onFetch();
26412
26521
  return () => {
26413
26522
  log(`liveChannels(tmpid: ${timestamp}) > dispose`);
@@ -26954,42 +27063,11 @@ const onSubChannelFetched = (callback) => {
26954
27063
  * @category SubChannel Live Object
26955
27064
  */
26956
27065
  const liveSubChannel = (subChannelId, callback) => {
26957
- const { log, cache } = getActiveClient();
26958
- const timestamp = Date.now();
26959
- log(`liveSubChannel(tmpid: ${timestamp}) > listen`);
26960
- if (!cache) {
26961
- console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
26962
- }
26963
- let subChannel;
26964
- const disposers = [];
26965
- const dispatcher = (data) => {
26966
- subChannel = data.data;
26967
- callback(data);
26968
- };
26969
- const realtimeRouter = (eventSubChannel) => {
26970
- if (subChannelId !== eventSubChannel.subChannelId) {
26971
- return;
26972
- }
26973
- if (subChannel && !hasUpdates(subChannel, eventSubChannel)) {
26974
- return;
26975
- }
26976
- dispatcher({ loading: false, data: eventSubChannel, origin: 'event' });
26977
- };
26978
- const onFetch = () => {
26979
- const query = createQuery(getSubChannel, subChannelId);
26980
- runQuery(query, ({ error, data, loading, origin }) => {
26981
- dispatcher({ error, data, loading, origin });
26982
- if (error) {
26983
- disposers.forEach(fn => fn());
26984
- }
26985
- });
26986
- };
26987
- disposers.push(onSubChannelFetched(realtimeRouter), onSubChannelUpdated(realtimeRouter), onSubChannelDeleted(realtimeRouter));
26988
- onFetch();
26989
- return () => {
26990
- log(`liveSubChannel(tmpid: ${timestamp}) > dispose`);
26991
- disposers.forEach(fn => fn());
26992
- };
27066
+ return liveObject(subChannelId, callback, 'subChannelId', getSubChannel, [
27067
+ onSubChannelFetched,
27068
+ onSubChannelUpdated,
27069
+ onSubChannelDeleted,
27070
+ ]);
26993
27071
  };
26994
27072
 
26995
27073
  /**
@@ -27120,55 +27198,16 @@ const onMessageFetched = (callback) => {
27120
27198
  * @category Message Live Object
27121
27199
  */
27122
27200
  const liveMessage = (messageId, callback) => {
27123
- const { log, cache } = getActiveClient();
27124
- const timestamp = Date.now();
27125
- log(`liveMessage(tmpid: ${timestamp}) > listen`);
27126
- if (!cache) {
27127
- console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
27128
- }
27129
- let message;
27130
- let isUnsyncedObject = false;
27131
- const disposers = [];
27132
- const dispatcher = (data) => {
27133
- message = data.data;
27134
- callback(data);
27135
- };
27136
- const realtimeRouter = (eventMessage) => {
27137
- if (messageId !== eventMessage.messageId) {
27138
- return;
27139
- }
27140
- if (message && !hasUpdates(message, eventMessage)) {
27141
- return;
27142
- }
27143
- dispatcher({ loading: false, data: eventMessage, origin: 'event' });
27144
- };
27145
- const onFetch = () => {
27146
- const query = createQuery(getMessage, messageId, true);
27147
- runQuery(query, ({ loading, data, error, origin, cachedAt }) => {
27148
- if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
27149
- dispatcher({
27150
- data,
27151
- origin,
27152
- loading: false,
27153
- error: new ASCApiError(UNSYNCED_OBJECT_CACHED_AT_MESSAGE, 800800 /* Amity.ClientError.DISALOOW_UNSYNCED_OBJECT */, "error" /* Amity.ErrorLevel.ERROR */),
27154
- });
27155
- isUnsyncedObject = true;
27156
- disposers.forEach(fn => fn());
27157
- }
27158
- else if (!isUnsyncedObject) {
27159
- dispatcher({ loading, data, origin, error });
27160
- }
27161
- if (error) {
27162
- disposers.forEach(fn => fn());
27163
- }
27164
- });
27165
- };
27166
- disposers.push(onMessageFetched(realtimeRouter), onMessageUpdated(realtimeRouter), onMessageDeleted(realtimeRouter), onMessageFlagged(realtimeRouter), onMessageUnflagged(realtimeRouter), onMessageFlagCleared(realtimeRouter), onMessageReactionAdded(realtimeRouter), onMessageReactionRemoved(realtimeRouter));
27167
- onFetch();
27168
- return () => {
27169
- log(`liveMessage(tmpid: ${timestamp}) > dispose`);
27170
- disposers.forEach(fn => fn());
27171
- };
27201
+ return liveObject(messageId, callback, 'messageId', getMessage, [
27202
+ onMessageFetched,
27203
+ onMessageUpdated,
27204
+ onMessageDeleted,
27205
+ onMessageFlagged,
27206
+ onMessageUnflagged,
27207
+ onMessageFlagCleared,
27208
+ onMessageReactionAdded,
27209
+ onMessageReactionRemoved,
27210
+ ]);
27172
27211
  };
27173
27212
 
27174
27213
  /**
@@ -27369,6 +27408,30 @@ const createCommunityEventSubscriber = (event, callback) => {
27369
27408
  };
27370
27409
  return createEventSubscriber(client, event, event, filter);
27371
27410
  };
27411
+ /*
27412
+ * verifies membership status
27413
+ */
27414
+ function isMember(membership) {
27415
+ return membership !== 'none';
27416
+ }
27417
+ /*
27418
+ * checks if currently logged in user is part of the community
27419
+ */
27420
+ function isCurrentUserPartOfCommunity(c, m) {
27421
+ const { userId } = getActiveUser();
27422
+ return c.communityId === m.communityId && m.userId === userId;
27423
+ }
27424
+ /*
27425
+ * For mqtt events server will not send user specific data as it's broadcasted
27426
+ * to multiple users. Althought this can be calculated, it's not scalable. Hence
27427
+ * the client SDK needs to calculate this info
27428
+ */
27429
+ function updateMembershipStatus(communities, communityUsers) {
27430
+ return communities.map(c => {
27431
+ const isJoined = communityUsers.some(m => isCurrentUserPartOfCommunity(c, m) && isMember(m.communityMembership));
27432
+ return Object.assign(Object.assign({}, c), { isJoined });
27433
+ });
27434
+ }
27372
27435
  function hasPermission(member, payload, permission) {
27373
27436
  if (member.permissions.some(x => x === permission)) {
27374
27437
  return true;
@@ -27399,7 +27462,15 @@ const createCommunityMemberEventSubscriber = (event, callback) => {
27399
27462
  const client = getActiveClient();
27400
27463
  const filter = (payload) => {
27401
27464
  const communityPayload = unpackCommunityPayload(payload);
27465
+ const { communities } = communityPayload;
27402
27466
  const preparedPayload = prepareMembershipPayload(communityPayload, 'communityUsers');
27467
+ const { communityUsers } = preparedPayload;
27468
+ /*
27469
+ * community.isJoined is not part of the communityMembership payload, and needs
27470
+ * to be calculated based on the communityMembership value
27471
+ */
27472
+ const communitiesWithMembership = updateMembershipStatus(communities, communityUsers);
27473
+ preparedPayload.communities = communitiesWithMembership;
27403
27474
  if (!client.cache) {
27404
27475
  // TODO: here we are missing specific properties here!
27405
27476
  callback(preparedPayload.communities[0], getEventRelatedMember(event, preparedPayload));
@@ -27541,6 +27612,23 @@ const onCommunityUserAdded = (callback) => createCommunityMemberEventSubscriber(
27541
27612
  */
27542
27613
  const onCommunityUserRemoved = (callback) => createCommunityMemberEventSubscriber('community.userRemoved', callback);
27543
27614
 
27615
+ /**
27616
+ * ```js
27617
+ * import { onCommunityUserChanged } from '@amityco/ts-sdk'
27618
+ * const dispose = onCommunityUserChanged((community, member) => {
27619
+ * // ...
27620
+ * })
27621
+ * ```
27622
+ *
27623
+ * Fired when a user has been added or removed from a {@link Amity.Community}
27624
+ *
27625
+ * @param callback The function to call when the event was fired
27626
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
27627
+ *
27628
+ * @category Community Events
27629
+ */
27630
+ const onCommunityUserChanged = (callback) => createCommunityMemberEventSubscriber('community.userChanged', callback);
27631
+
27544
27632
  /**
27545
27633
  * ```js
27546
27634
  * import { onCommunityUserBanned } from '@amityco/ts-sdk'
@@ -27619,6 +27707,122 @@ const observeCommunity = (communityId, callback) => {
27619
27707
  };
27620
27708
  };
27621
27709
 
27710
+ /**
27711
+ * ```js
27712
+ * import { liveCommunities } from '@amityco/ts-sdk'
27713
+ *
27714
+ * let communities = []
27715
+ * const unsub = liveCommunities({
27716
+ * displayName: Amity.Community['displayName'],
27717
+ * }, response => merge(communities, response.data))
27718
+ * ```
27719
+ *
27720
+ * Observe all mutations on a list of {@link Amity.Community}s
27721
+ *
27722
+ * @param params for querying communities
27723
+ * @param callback the function to call when new data are available
27724
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the communities
27725
+ *
27726
+ * @category Community Live Collection
27727
+ */
27728
+ const liveCommunities = (params, callback, config) => {
27729
+ const { log, cache } = getActiveClient();
27730
+ if (!cache) {
27731
+ console.log(ENABLE_CACHE_MESSAGE);
27732
+ }
27733
+ const timestamp = Date.now();
27734
+ log(`liveCommunities(tmpid: ${timestamp}) > listen`);
27735
+ const { limit: queryLimit } = params, queryParams = __rest(params, ["limit"]);
27736
+ const limit = queryLimit !== null && queryLimit !== void 0 ? queryLimit : COLLECTION_DEFAULT_PAGINATION_LIMIT;
27737
+ const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config !== null && config !== void 0 ? config : {};
27738
+ const disposers = [];
27739
+ const cacheKey = ['community', 'collection', {}];
27740
+ const responder = (data) => {
27741
+ var _a, _b;
27742
+ let communities = (_a = data.data
27743
+ .map(communityId => pullFromCache(['community', 'get', communityId]))
27744
+ .filter(Boolean)
27745
+ .map(({ data }) => data)) !== null && _a !== void 0 ? _a : [];
27746
+ communities = filterByPropEquality(communities, 'isDeleted', params.isDeleted);
27747
+ communities = filterByPropEquality(communities, 'displayName', params.displayName);
27748
+ if (params.categoryId) {
27749
+ communities = communities.filter(c => { var _a; return (_a = c.categoryIds) === null || _a === void 0 ? void 0 : _a.includes(params.categoryId); });
27750
+ }
27751
+ if (params.tags) {
27752
+ communities = communities.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); }); });
27753
+ }
27754
+ if (params.membership === 'member') {
27755
+ communities = filterByPropEquality(communities, 'isJoined', true);
27756
+ }
27757
+ if (params.membership === 'notMember') {
27758
+ communities = filterByPropEquality(communities, 'isJoined', false);
27759
+ }
27760
+ const sortBy = params.sortBy || 'lastCreated';
27761
+ if (sortBy === 'lastCreated' || sortBy === 'firstCreated') {
27762
+ communities = communities.sort(sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated);
27763
+ }
27764
+ /*
27765
+ * The server returns communities with empty | null displayName's first before
27766
+ * returning sorted list of communities with displayNames
27767
+ *
27768
+ * This section needs to be updated as displayNames can be null as well
27769
+ */
27770
+ if (sortBy === 'displayName') {
27771
+ communities = communities
27772
+ // this needs to be aligned with the backend data type
27773
+ .map(c => (c.displayName ? c : Object.assign(Object.assign({}, c), { displayName: '' })))
27774
+ // @ts-ignore
27775
+ .sort(sortByDisplayName);
27776
+ }
27777
+ callback({
27778
+ onNextPage: onFetch,
27779
+ data: communities,
27780
+ hasNextPage: !!((_b = data.params) === null || _b === void 0 ? void 0 : _b.page),
27781
+ loading: data.loading,
27782
+ error: data.error,
27783
+ });
27784
+ };
27785
+ const realtimeRouter = (_) => (community) => {
27786
+ var _a;
27787
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
27788
+ if (!collection)
27789
+ return;
27790
+ /*
27791
+ * Simply update collection and let responder decide what to do with data
27792
+ */
27793
+ collection.data = [...new Set([community.communityId, ...collection.data])];
27794
+ pushToCache(cacheKey, collection);
27795
+ responder(collection);
27796
+ };
27797
+ const onFetch = () => {
27798
+ var _a, _b, _c;
27799
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
27800
+ const communities = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
27801
+ if (communities.length > 0 && !(collection === null || collection === void 0 ? void 0 : collection.params.page))
27802
+ return;
27803
+ const query = createQuery(queryCommunities, Object.assign(Object.assign({}, queryParams), { page: (_c = collection === null || collection === void 0 ? void 0 : collection.params.page) !== null && _c !== void 0 ? _c : { limit } }));
27804
+ runQuery(query, ({ data: result, error, loading, nextPage: page }) => {
27805
+ const data = {
27806
+ loading,
27807
+ error,
27808
+ params: { page },
27809
+ data: communities,
27810
+ };
27811
+ if (result) {
27812
+ data.data = [...new Set([...communities, ...result.map(getResolver('community'))])];
27813
+ }
27814
+ pushToCache(cacheKey, data);
27815
+ responder(data);
27816
+ }, queryOptions(policy));
27817
+ };
27818
+ disposers.push(onCommunityCreated(realtimeRouter()), onCommunityDeleted(realtimeRouter()), onCommunityUpdated(realtimeRouter()), onCommunityJoined(realtimeRouter()), onCommunityLeft(realtimeRouter()), onCommunityUserChanged(realtimeRouter()));
27819
+ onFetch();
27820
+ return () => {
27821
+ log(`liveCommunities(tmpid: ${timestamp}) > dispose`);
27822
+ disposers.forEach(fn => fn());
27823
+ };
27824
+ };
27825
+
27622
27826
  /**
27623
27827
  * ```js
27624
27828
  * import { queryCategories } from '@amityco/ts-sdk'
@@ -27747,6 +27951,96 @@ getCategory.locally = (categoryId) => {
27747
27951
  };
27748
27952
  };
27749
27953
 
27954
+ /**
27955
+ * ```js
27956
+ * import { liveCategories } from '@amityco/ts-sdk'
27957
+ *
27958
+ * let categories = []
27959
+ * const unsub = liveCategories({}, response => merge(categories, response.data))
27960
+ * ```
27961
+ *
27962
+ * Observe all mutations on a list of {@link Amity.Category}s
27963
+ *
27964
+ * @param params for querying categories
27965
+ * @param callback the function to call when new data are available
27966
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the categories
27967
+ *
27968
+ * @category Category Live Collection
27969
+ */
27970
+ const liveCategories = (params, callback, config) => {
27971
+ const { log, cache } = getActiveClient();
27972
+ if (!cache) {
27973
+ console.log(ENABLE_CACHE_MESSAGE);
27974
+ }
27975
+ const timestamp = Date.now();
27976
+ log(`liveCategories(tmpid: ${timestamp}) > listen`);
27977
+ const { limit: queryLimit } = params, queryParams = __rest(params, ["limit"]);
27978
+ const limit = queryLimit !== null && queryLimit !== void 0 ? queryLimit : COLLECTION_DEFAULT_PAGINATION_LIMIT;
27979
+ const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config !== null && config !== void 0 ? config : {};
27980
+ const disposers = [];
27981
+ const cacheKey = ['category', 'collection', {}];
27982
+ const responder = (data) => {
27983
+ var _a, _b;
27984
+ let categories = (_a = data.data
27985
+ .map(categoryId => pullFromCache(['category', 'get', categoryId]))
27986
+ .filter(Boolean)
27987
+ .map(({ data }) => data)) !== null && _a !== void 0 ? _a : [];
27988
+ categories = filterByPropEquality(categories, 'isDeleted', params.isDeleted);
27989
+ switch (params.sortBy) {
27990
+ case 'firstCreated':
27991
+ categories = categories.sort(sortByFirstCreated);
27992
+ break;
27993
+ case 'lastCreated':
27994
+ categories = categories.sort(sortByLastCreated);
27995
+ break;
27996
+ default:
27997
+ categories = categories.sort(sortByName);
27998
+ }
27999
+ callback({
28000
+ onNextPage: onFetch,
28001
+ data: categories,
28002
+ hasNextPage: !!((_b = data.params) === null || _b === void 0 ? void 0 : _b.page),
28003
+ loading: data.loading,
28004
+ error: data.error,
28005
+ });
28006
+ };
28007
+ /*
28008
+ * const realtimeRouter = () => {
28009
+ * @TODO: At the time of creating this method category does not have any
28010
+ * observers
28011
+ *};
28012
+ */
28013
+ const onFetch = () => {
28014
+ var _a, _b, _c;
28015
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
28016
+ const categories = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
28017
+ if (categories.length > 0 && !(collection === null || collection === void 0 ? void 0 : collection.params.page))
28018
+ return;
28019
+ const query = createQuery(queryCategories, Object.assign(Object.assign({}, queryParams), { page: (_c = collection === null || collection === void 0 ? void 0 : collection.params.page) !== null && _c !== void 0 ? _c : { limit } }));
28020
+ runQuery(query, ({ data: result, error, loading, nextPage: page }) => {
28021
+ const data = {
28022
+ loading,
28023
+ error,
28024
+ params: { page },
28025
+ data: categories,
28026
+ };
28027
+ if (result) {
28028
+ data.data = [...new Set([...categories, ...result.map(getResolver('category'))])];
28029
+ }
28030
+ pushToCache(cacheKey, data);
28031
+ responder(data);
28032
+ }, queryOptions(policy));
28033
+ };
28034
+ disposers.push(() => {
28035
+ // @TODO -> update once observers added
28036
+ });
28037
+ onFetch();
28038
+ return () => {
28039
+ log(`liveCategories(tmpid: ${timestamp}) > dispose`);
28040
+ disposers.forEach(fn => fn());
28041
+ };
28042
+ };
28043
+
27750
28044
  /**
27751
28045
  * ```js
27752
28046
  * import { queryGlobalFeed } from '@amityco/ts-sdk'
@@ -28671,6 +28965,38 @@ const observePost = (postId, callback, policy = 'cache_then_server') => {
28671
28965
  };
28672
28966
  };
28673
28967
 
28968
+ /**
28969
+ * ```js
28970
+ * import { livePost } from '@amityco/ts-sdk';
28971
+ *
28972
+ * let post;
28973
+ *
28974
+ * const unsubscribe = livePost(postId, response => {
28975
+ * post = response.data;
28976
+ * });
28977
+ * ```
28978
+ *
28979
+ * Observe all mutation on a given {@link Amity.Post}
28980
+ *
28981
+ * @param postId the ID of the message to observe
28982
+ * @param callback the function to call when new data are available
28983
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the sub channel
28984
+ *
28985
+ * @category Post Live Object
28986
+ */
28987
+ const livePost = (postId, callback) => {
28988
+ return liveObject(postId, callback, 'postId', getPost, [
28989
+ onPostApproved,
28990
+ onPostDeclined,
28991
+ onPostDeleted,
28992
+ onPostFlagged,
28993
+ onPostReactionAdded,
28994
+ onPostReactionRemoved,
28995
+ onPostUnflagged,
28996
+ onPostUpdated,
28997
+ ]);
28998
+ };
28999
+
28674
29000
  /**
28675
29001
  * ```js
28676
29002
  * import { livePosts } from '@amityco/ts-sdk'
@@ -28684,8 +29010,8 @@ const observePost = (postId, callback, policy = 'cache_then_server') => {
28684
29010
  *
28685
29011
  * Observe all mutations on a list of {@link Amity.Post} for a given target object
28686
29012
  *
28687
- * @param targetType the type of the target
28688
- * @param targetId the ID of the target
29013
+ * @param param.targetType the type of the target
29014
+ * @param param.targetId the ID of the target
28689
29015
  * @param callback the function to call when new data are available
28690
29016
  * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the messages
28691
29017
  *
@@ -28719,6 +29045,9 @@ const livePosts = (params, callback, config) => {
28719
29045
  if (params.tags) {
28720
29046
  posts = posts.filter(p => { var _a; return (_a = p.tags) === null || _a === void 0 ? void 0 : _a.some(t => { var _a; return (_a = params.tags) === null || _a === void 0 ? void 0 : _a.includes(t); }); });
28721
29047
  }
29048
+ if (params.targetType === 'community' && params.feedType) {
29049
+ posts = filterByFeedType(posts, params.feedType);
29050
+ }
28722
29051
  callback({
28723
29052
  onNextPage: onFetch,
28724
29053
  data: posts,
@@ -28732,27 +29061,16 @@ const livePosts = (params, callback, config) => {
28732
29061
  const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
28733
29062
  if (params.targetId !== post.targetId || params.targetType !== post.targetType || !collection)
28734
29063
  return;
28735
- if (['onCreate', 'onApproved'].includes(action)) {
28736
- collection.data = [...new Set([post.postId, ...collection.data])];
28737
- }
28738
- else if (['onDelete', 'onDeclined'].includes(action)) {
28739
- collection.data = collection.data.filter(p => p !== post.postId);
28740
- /*
28741
- * if isDeleted is true, collection should add deleted items to the
28742
- * begining of the collection
28743
- */
28744
- if (params.isDeleted)
28745
- collection.data.unshift(post.postId);
28746
- }
28747
29064
  /*
28748
- * FIX-ME
28749
- * This is a shortcoming as the feed object is not saved to the cache.
28750
- * The responder should pull the feed from cache once available and should
28751
- * match the collection to feedType param
28752
- * https://ekoapp.atlassian.net/browse/ASC-9382
29065
+ * This is not ideal, but currently this is the only way to update the
29066
+ * collection on post declined
28753
29067
  */
28754
- if (params.feedType === 'reviewing' && action === 'onApproved')
28755
- collection.data = collection.data.filter(p => p !== post.postId);
29068
+ if (action === 'onDeclined') {
29069
+ collection.data = collection.data.filter(postId => postId !== post.postId);
29070
+ }
29071
+ else {
29072
+ collection.data = [...new Set([post.postId, ...collection.data])];
29073
+ }
28756
29074
  pushToCache(cacheKey, collection);
28757
29075
  responder(collection);
28758
29076
  };
@@ -28866,6 +29184,36 @@ const observeComment = (commentId, callback, policy = 'cache_then_server') => {
28866
29184
  };
28867
29185
  };
28868
29186
 
29187
+ /**
29188
+ * ```js
29189
+ * import { liveComment } from '@amityco/ts-sdk';
29190
+ *
29191
+ * let comment;
29192
+ *
29193
+ * const unsubscribe = liveComment(commentId, response => {
29194
+ * comment = response.data;
29195
+ * });
29196
+ * ```
29197
+ *
29198
+ * Observe all mutation on a given {@link Amity.Comment}
29199
+ *
29200
+ * @param commentId the ID of the comment to observe
29201
+ * @param callback the function to call when new data are available
29202
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the comment
29203
+ *
29204
+ * @category Comment Live Object
29205
+ */
29206
+ const liveComment = (commentId, callback) => {
29207
+ return liveObject(commentId, callback, 'commentId', getComment, [
29208
+ onCommentDeleted,
29209
+ onCommentFlagged,
29210
+ onCommentReactionAdded,
29211
+ onCommentReactionRemoved,
29212
+ onCommentUnflagged,
29213
+ onCommentUpdated,
29214
+ ]);
29215
+ };
29216
+
28869
29217
  /**
28870
29218
  * ```js
28871
29219
  * import { liveComments } from '@amityco/ts-sdk'
@@ -29550,4 +29898,4 @@ const createUserToken = async (apiKey, apiRegion, params) => {
29550
29898
  return { accessToken: data.accessToken };
29551
29899
  };
29552
29900
 
29553
- 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, createSubChannel, createUserToken, createVideo, declineFollower, declinePost, deleteChannel, deleteComment, deleteCommunity, deleteFile, deleteMessage, deletePoll, deletePost, deleteReport, deleteStream, deleteSubChannel, disableCache, disconnectClient, disposeStream, dropFromCache, enableCache, fileUrlWithSize, filterByChannelMembership, filterByPropEquality, filterByPropInclusion, follow, getActiveClient, getCategory, getChannel, getChannelTopic, getChannels, getComment, getCommentTopic, getComments, getCommunities, getCommunity, getCommunityTopic, getFeedSettings, getFile, getFollowInfo, getMessage, getMessageTopic, getMessages, getMyFollowersTopic, getMyFollowingsTopic, getNetworkTopic, getPoll, getPost, getPostTopic, getPosts, getRecommendedCommunities, getRole, getSmartFeedChannelTopic, getSmartFeedMessageTopic, getSmartFeedSubChannelTopic, getStream, getSubChannel, getSubChannelTopic, getSubChannels, getTopTrendingCommunities, getUser, getUserTopic, getUsers, isAfterBefore, isAfterBeforeRaw, isCachable, isConnected, isFetcher, isFresh, isLocal, isMutator, isOffline, isPaged, isReportedByMe, isSkipLimit, joinChannel, joinCommunity, leaveChannel, leaveCommunity, liveChannel, liveChannelMembers, liveChannels, liveComments, liveFollowers, liveFollowings, liveMessage, liveMessages, livePosts, liveReactions, liveSubChannel, liveSubChannels, liveUser, mergeInCache, observeChannel, observeChannels, observeComment, observeComments, observeCommunity, observeFile, observeFollowInfo, observeFollowers, observeFollowings, observeMessage, observeMessages, observePoll, observePost, observePosts, observeUser, onChannelCreated, onChannelDeleted, onChannelJoined, onChannelLeft, onChannelMemberAdded, onChannelMemberBanned, onChannelMemberRemoved, onChannelMemberUnbanned, onChannelMuted, 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, onMessageFlagCleared, onMessageFlagged, onMessageReactionAdded, onMessageReactionRemoved, onMessageUnflagged, onMessageUpdated, onPollDeleted, onPollUpdated, onPostApproved, onPostCreated, onPostDeclined, onPostDeleted, onPostFlagged, onPostReactionAdded, onPostReactionRemoved, onPostUnflagged, onPostUpdated, onReactionAdded, onReactionRemoved, onReactorAdded, onReactorRemoved, onSessionStateChange, onStreamRecorded, onStreamStarted, onStreamStopped, onSubChannelCreated, onSubChannelDeleted, onSubChannelUpdated, 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, querySubChannels, queryUsers, removeChannelMembers, removeChannelMembersRole, removeCommunityMembers, removeCommunityMembersRoles, removeReaction, renewal, restoreCache, runQuery, sortByChannelSegment, sortByDisplayName, sortByFirstCreated, sortByLastActivity, sortByLastCreated, sortBySegmentNumber, startReading, stopReading, subscribeTopic, toPage, toPageRaw, toToken, unbanChannelMembers, unfollow, updateChannel, updateComment, updateCommunity, updateMessage, updatePost, updateStream, updateSubChannel, updateUser, upsertInCache, votePoll, wipeCache };
29901
+ 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, createSubChannel, createUserToken, createVideo, declineFollower, declinePost, deleteChannel, deleteComment, deleteCommunity, deleteFile, deleteMessage, deletePoll, deletePost, deleteReport, deleteStream, deleteSubChannel, disableCache, disconnectClient, disposeStream, dropFromCache, enableCache, fileUrlWithSize, filterByChannelMembership, filterByFeedType, filterByPropEquality, filterByPropInclusion, follow, getActiveClient, getCategory, getChannel, getChannelTopic, getChannels, getComment, getCommentTopic, getComments, getCommunities, getCommunity, getCommunityTopic, getFeedSettings, getFile, getFollowInfo, getMessage, getMessageTopic, getMessages, getMyFollowersTopic, getMyFollowingsTopic, getNetworkTopic, getPoll, getPost, getPostTopic, getPosts, getRecommendedCommunities, getRole, getSmartFeedChannelTopic, getSmartFeedMessageTopic, getSmartFeedSubChannelTopic, getStream, getSubChannel, getSubChannelTopic, getSubChannels, getTopTrendingCommunities, getUser, getUserTopic, getUsers, isAfterBefore, isAfterBeforeRaw, isCachable, isConnected, isFetcher, isFresh, isLocal, isMutator, isOffline, isPaged, isReportedByMe, isSkip, joinChannel, joinCommunity, leaveChannel, leaveCommunity, liveCategories, liveChannel, liveChannelMembers, liveChannels, liveComment, liveComments, liveCommunities, liveFollowers, liveFollowings, liveMessage, liveMessages, livePost, livePosts, liveReactions, liveSubChannel, liveSubChannels, liveUser, liveUsers, mergeInCache, observeChannel, observeChannels, observeComment, observeComments, observeCommunity, observeFile, observeFollowInfo, observeFollowers, observeFollowings, observeMessage, observeMessages, observePoll, observePost, observePosts, observeUser, onChannelCreated, onChannelDeleted, onChannelJoined, onChannelLeft, onChannelMemberAdded, onChannelMemberBanned, onChannelMemberRemoved, onChannelMemberUnbanned, onChannelMuted, onChannelUpdated, onClientBanned, onClientDisconnected, onCommentCreated, onCommentDeleted, onCommentFlagged, onCommentReactionAdded, onCommentReactionRemoved, onCommentUnflagged, onCommentUpdated, onCommunityCreated, onCommunityDeleted, onCommunityJoined, onCommunityLeft, onCommunityUpdated, onCommunityUserAdded, onCommunityUserBanned, onCommunityUserChanged, onCommunityUserRemoved, onCommunityUserUnbanned, onConnectionError, onFollowInfoUpdated, onFollowRequestAccepted, onFollowRequestCanceled, onFollowRequestDeclined, onFollowerDeleted, onFollowerRequested, onMessageCreated, onMessageDeleted, onMessageFlagCleared, onMessageFlagged, onMessageReactionAdded, onMessageReactionRemoved, onMessageUnflagged, onMessageUpdated, onPollDeleted, onPollUpdated, onPostApproved, onPostCreated, onPostDeclined, onPostDeleted, onPostFlagged, onPostReactionAdded, onPostReactionRemoved, onPostUnflagged, onPostUpdated, onReactionAdded, onReactionRemoved, onReactorAdded, onReactorRemoved, onSessionStateChange, onStreamRecorded, onStreamStarted, onStreamStopped, onSubChannelCreated, onSubChannelDeleted, onSubChannelUpdated, 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, querySubChannels, queryUsers, removeChannelMembers, removeChannelMembersRole, removeCommunityMembers, removeCommunityMembersRoles, removeReaction, renewal, restoreCache, runQuery, sortByChannelSegment, sortByDisplayName, sortByFirstCreated, sortByLastActivity, sortByLastCreated, sortByName, sortBySegmentNumber, startReading, stopReading, subscribeTopic, toPage, toPageRaw, toToken, unbanChannelMembers, unfollow, updateChannel, updateComment, updateCommunity, updateMessage, updatePost, updateStream, updateSubChannel, updateUser, upsertInCache, votePoll, wipeCache };