@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.cjs.js CHANGED
@@ -7,7 +7,6 @@ var AsyncStorage = require('@react-native-async-storage/async-storage');
7
7
  var mitt = require('mitt');
8
8
  var debug = require('debug');
9
9
  var axios = require('axios');
10
- var qs = require('qs');
11
10
  var HttpAgent = require('agentkeepalive');
12
11
  var io = require('socket.io-client');
13
12
  var nativeIdGenerator = require('react-native-uuid');
@@ -18,7 +17,6 @@ var AsyncStorage__default = /*#__PURE__*/_interopDefaultLegacy(AsyncStorage);
18
17
  var mitt__default = /*#__PURE__*/_interopDefaultLegacy(mitt);
19
18
  var debug__default = /*#__PURE__*/_interopDefaultLegacy(debug);
20
19
  var axios__default = /*#__PURE__*/_interopDefaultLegacy(axios);
21
- var qs__default = /*#__PURE__*/_interopDefaultLegacy(qs);
22
20
  var HttpAgent__default = /*#__PURE__*/_interopDefaultLegacy(HttpAgent);
23
21
  var io__default = /*#__PURE__*/_interopDefaultLegacy(io);
24
22
  var nativeIdGenerator__default = /*#__PURE__*/_interopDefaultLegacy(nativeIdGenerator);
@@ -179,14 +177,14 @@ const partialMatch = (predicate, candidate) => {
179
177
  const checkIfShouldGoesToTombstone = (errorCode) => [400400 /* Amity.ServerError.ITEM_NOT_FOUND */, 400300 /* Amity.ServerError.FORBIDDEN */].includes(errorCode);
180
178
 
181
179
  /**
182
- * Type guard to find if the a given decoded backend token uses "skip/limit" pagination style
180
+ * Type guard to find if the a given decoded backend token uses "skip" pagination style
183
181
  *
184
182
  * @param json any json object as extracted from the backend
185
183
  * @returns success boolean if the token has either "skip" or "limit" props
186
184
  *
187
185
  * @hidden
188
186
  */
189
- const isSkipLimit = (json) => ['skip', 'limit'].some(prop => prop in json);
187
+ const isSkip = (json) => ['skip'].some(prop => prop in json);
190
188
  /**
191
189
  * Type guard to find if the a given decoded backend token uses "after/before" pagination style
192
190
  *
@@ -286,7 +284,7 @@ const toPage = (token) => {
286
284
  return undefined;
287
285
  // don't try catch, let it throw
288
286
  const json = JSON.parse(jsBase64.decode(token));
289
- if (isSkipLimit(json)) {
287
+ if (isSkip(json)) {
290
288
  return {
291
289
  after: json.skip,
292
290
  limit: json.limit,
@@ -513,6 +511,7 @@ const idResolvers = {
513
511
  stream: ({ streamId }) => streamId,
514
512
  follow: ({ from, to }) => `${from}#${to}`,
515
513
  followCount: ({ userId }) => userId,
514
+ feed: ({ targetId, feedId }) => `${targetId}#${feedId}`,
516
515
  };
517
516
  /**
518
517
  * Retrieve the id resolver matching a domain name
@@ -550,6 +549,7 @@ const CRITERIAS = {
550
549
  stream: ['streamId'],
551
550
  follow: ['from', 'to'],
552
551
  followCount: ['userId', 'followerCount'],
552
+ feed: ['feedId', 'feedType'],
553
553
  };
554
554
  /** @hidden */
555
555
  const hasKeys = (object, needles) => {
@@ -610,6 +610,7 @@ const PAYLOAD2MODEL = {
610
610
  videoStreamings: 'stream',
611
611
  follows: 'follow',
612
612
  followCounts: 'followCount',
613
+ feeds: 'feed',
613
614
  };
614
615
  /** hidden */
615
616
  const hasUpdates = (prevData, nextData) => {
@@ -1076,10 +1077,36 @@ const filterByChannelMembership = (collection, membership, userId) => {
1076
1077
  'get',
1077
1078
  channelUserCacheKey,
1078
1079
  ])) === null || _a === void 0 ? void 0 : _a.data;
1079
- if (membership === 'member' && channelUser && channelUser.membership !== 'none') {
1080
- return true;
1080
+ if (membership === 'member') {
1081
+ return channelUser && channelUser.membership !== 'none';
1081
1082
  }
1082
- return membership === 'notMember' && (!channelUser || channelUser.membership === 'none');
1083
+ // only membership value remainging is 'notMember'
1084
+ return !channelUser || channelUser.membership === 'none';
1085
+ });
1086
+ };
1087
+ /**
1088
+ * Filter a channel collection by membership of the userId
1089
+ *
1090
+ * @param collection the channel collection to filter
1091
+ * @param feedType to be filtered by
1092
+ * @returns a filtered collection with items only matching the criteria
1093
+ *
1094
+ * @hidden
1095
+ */
1096
+ const filterByFeedType = (collection, feedType) => {
1097
+ /*
1098
+ * It is possible that the targetId & feedId are the same for most of the posts
1099
+ * But since cache is in-memory, i've avoided memoizing, to avoid premature
1100
+ * optimization. Can be revisited if performance issues arise
1101
+ */
1102
+ return collection.filter(({ targetId, feedId }) => {
1103
+ var _a;
1104
+ const feed = (_a = pullFromCache([
1105
+ 'feed',
1106
+ 'get',
1107
+ getResolver('feed')({ targetId, feedId }),
1108
+ ])) === null || _a === void 0 ? void 0 : _a.data;
1109
+ return feed && feed.feedType === feedType;
1083
1110
  });
1084
1111
  };
1085
1112
 
@@ -1094,6 +1121,14 @@ const sortByDisplayName = ({ displayName: a }, { displayName: b }) => {
1094
1121
  return 0;
1095
1122
  return a < b ? -1 : 1;
1096
1123
  };
1124
+ /**
1125
+ * Alphabetic sorting of objects having a name
1126
+ */
1127
+ const sortByName = ({ name: a }, { name: b }) => {
1128
+ if (a === b)
1129
+ return 0;
1130
+ return a < b ? -1 : 1;
1131
+ };
1097
1132
  /**
1098
1133
  * Sorting a collection by their apparition order (oldest first)
1099
1134
  */
@@ -1397,13 +1432,6 @@ const unwrapPayload = (response) => {
1397
1432
  return undefined;
1398
1433
  };
1399
1434
 
1400
- /**
1401
- * Axios param serializer (for querystring)
1402
- * @hidden
1403
- */
1404
- const stringify = (params) => {
1405
- return qs__default["default"].stringify(params, { arrayFormat: 'brackets' });
1406
- };
1407
1435
  /**
1408
1436
  * Creates a pre-configured axios instance
1409
1437
  *
@@ -1424,7 +1452,14 @@ const createHttpTransport = (endpoint) => {
1424
1452
  baseURL: endpoint,
1425
1453
  httpAgent: new HttpAgent__default["default"](options),
1426
1454
  httpsAgent: new HttpAgent.HttpsAgent(options),
1427
- paramsSerializer: stringify,
1455
+ /*
1456
+ * If paramSerializer is required, use the serialize option to stringify
1457
+ * params. The encode option will pass complex params as string only whereas
1458
+ * the serialize option will pass params in the format Record<string, any>
1459
+ *
1460
+ * For more details:
1461
+ * https://github.com/axios/axios#request-config
1462
+ */
1428
1463
  });
1429
1464
  instance.interceptors.request.use(config => {
1430
1465
  var _a;
@@ -1438,10 +1473,8 @@ const createHttpTransport = (endpoint) => {
1438
1473
  return config;
1439
1474
  });
1440
1475
  instance.interceptors.response.use(response => response, error => {
1441
- var _a;
1476
+ var _a, _b;
1442
1477
  const { response } = error;
1443
- // eslint-disable-next-line no-console
1444
- console.error((_a = response === null || response === void 0 ? void 0 : response.data) !== null && _a !== void 0 ? _a : error);
1445
1478
  // handle unauthorized request
1446
1479
  if (response.data.code === 400100 /* Amity.ServerError.UNAUTHORIZED */) {
1447
1480
  fireEvent('tokenTerminated', "terminated" /* Amity.SessionStates.TERMINATED */);
@@ -1451,8 +1484,15 @@ const createHttpTransport = (endpoint) => {
1451
1484
  fireEvent('tokenExpired', "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */);
1452
1485
  throw new ASCError('Token expired', 800403 /* Amity.ClientError.TOKEN_EXPIRED */, "fatal" /* Amity.ErrorLevel.FATAL */);
1453
1486
  }
1454
- if (response === null || response === void 0 ? void 0 : response.data)
1455
- unwrapPayload(response.data);
1487
+ // if it's an error with status in the response payload,
1488
+ // then it's an expected error.
1489
+ if ((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.status) {
1490
+ unwrapPayload(response === null || response === void 0 ? void 0 : response.data);
1491
+ }
1492
+ // unexpected error.
1493
+ else {
1494
+ throw new Error((_b = response === null || response === void 0 ? void 0 : response.data) !== null && _b !== void 0 ? _b : error);
1495
+ }
1456
1496
  });
1457
1497
  return instance;
1458
1498
  };
@@ -20809,7 +20849,7 @@ const connectClient = async (params, sessionHandler, config) => {
20809
20849
  setSessionState(state);
20810
20850
  disconnectClient();
20811
20851
  subscriptions.forEach(fn => fn());
20812
- }), onUserDeleted(() => null));
20852
+ }));
20813
20853
  return client.ws.connected;
20814
20854
  };
20815
20855
 
@@ -20892,7 +20932,8 @@ const isExpired = (expiresAt) => Date.now() > Date.parse(expiresAt) - COMPENSATE
20892
20932
  *
20893
20933
  * @category private
20894
20934
  */
20895
- const isAboutToExpire = (expiresAt, issuedAt) => {
20935
+ const isAboutToExpire = (params) => {
20936
+ const { expiresAt, issuedAt } = params;
20896
20937
  const expires = Date.parse(expiresAt);
20897
20938
  const issued = Date.parse(issuedAt);
20898
20939
  const now = Date.now();
@@ -20927,7 +20968,7 @@ const accessTokenExpiryWatcher = (expiresAt, issuedAt, sessionHandler) => {
20927
20968
  scheduleTask(() => sessionHandler.sessionWillRenewAccessToken(renewal()));
20928
20969
  return;
20929
20970
  }
20930
- if (isAboutToExpire(issuedAt, expiresAt)) {
20971
+ if (isAboutToExpire({ expiresAt, issuedAt })) {
20931
20972
  sessionHandler.sessionWillRenewAccessToken(renewal());
20932
20973
  }
20933
20974
  }, ACCESS_TOKEN_WATCHER_INTERVAL);
@@ -21398,6 +21439,58 @@ const onUserUnflagged = (callback) => createUserEventSubscriber('user.unflagged'
21398
21439
  */
21399
21440
  const onUserFlagCleared = (callback) => createUserEventSubscriber('user.flagCleared', callback);
21400
21441
 
21442
+ const liveObject = (id, callback, key, fetcher, eventHandlers) => {
21443
+ const { cache } = getActiveClient();
21444
+ if (!cache) {
21445
+ console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
21446
+ }
21447
+ let model;
21448
+ let isUnsyncedModel = false; // for messages
21449
+ const disposers = [];
21450
+ const dispatcher = (data) => {
21451
+ model = data.data;
21452
+ callback(data);
21453
+ };
21454
+ const realtimeRouter = (eventModel) => {
21455
+ if (id !== eventModel[key]) {
21456
+ return;
21457
+ }
21458
+ if (model && !hasUpdates(model, eventModel)) {
21459
+ return;
21460
+ }
21461
+ dispatcher({ loading: false, data: eventModel, origin: 'event' });
21462
+ };
21463
+ const onFetch = () => {
21464
+ // @ts-ignore
21465
+ const query = createQuery(fetcher, id, true);
21466
+ runQuery(query, ({ error, data, loading, origin, cachedAt }) => {
21467
+ if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
21468
+ dispatcher({
21469
+ // @ts-ignore
21470
+ data,
21471
+ origin,
21472
+ loading: false,
21473
+ error: new ASCApiError(UNSYNCED_OBJECT_CACHED_AT_MESSAGE, 800800 /* Amity.ClientError.DISALOOW_UNSYNCED_OBJECT */, "error" /* Amity.ErrorLevel.ERROR */),
21474
+ });
21475
+ isUnsyncedModel = true;
21476
+ disposers.forEach(fn => fn());
21477
+ }
21478
+ else if (!isUnsyncedModel) {
21479
+ // @ts-ignore
21480
+ dispatcher({ loading, data, origin, error });
21481
+ }
21482
+ if (error) {
21483
+ disposers.forEach(fn => fn());
21484
+ }
21485
+ });
21486
+ };
21487
+ disposers.push(...eventHandlers.map(fn => fn(realtimeRouter)));
21488
+ onFetch();
21489
+ return () => {
21490
+ disposers.forEach(fn => fn());
21491
+ };
21492
+ };
21493
+
21401
21494
  /**
21402
21495
  * ```js
21403
21496
  * import { onUserFetched } from '@amityco/ts-sdk'
@@ -21435,40 +21528,107 @@ const onUserFetched = (callback) => createUserEventSubscriber('user.fetched', ca
21435
21528
  * @category Message Live Object
21436
21529
  */
21437
21530
  const liveUser = (userId, callback) => {
21531
+ return liveObject(userId, callback, 'userId', getUser, [
21532
+ onUserFetched,
21533
+ onUserUpdated,
21534
+ onUserDeleted,
21535
+ onUserFlagged,
21536
+ onUserUnflagged,
21537
+ onUserFlagCleared,
21538
+ ]);
21539
+ };
21540
+
21541
+ /**
21542
+ * ```js
21543
+ * import { liveUsers } from '@amityco/ts-sdk'
21544
+ *
21545
+ * let users = []
21546
+ * const unsub = liveUsers({}, response => merge(users, response.data))
21547
+ * ```
21548
+ *
21549
+ * Observe all mutations on a list of {@link Amity.User}s
21550
+ *
21551
+ * @param params for querying users
21552
+ * @param callback the function to call when new data are available
21553
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the users
21554
+ *
21555
+ * @category Category Live Collection
21556
+ */
21557
+ const liveUsers = (params, callback, config) => {
21438
21558
  const { log, cache } = getActiveClient();
21439
- const timestamp = Date.now();
21440
- log(`liveUser(tmpid: ${timestamp}) > listen`);
21441
21559
  if (!cache) {
21442
- console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
21560
+ console.log(ENABLE_CACHE_MESSAGE);
21443
21561
  }
21444
- let user;
21562
+ const timestamp = Date.now();
21563
+ log(`liveUsers(tmpid: ${timestamp}) > listen`);
21564
+ const { limit: queryLimit } = params, queryParams = __rest(params, ["limit"]);
21565
+ const limit = queryLimit !== null && queryLimit !== void 0 ? queryLimit : COLLECTION_DEFAULT_PAGINATION_LIMIT;
21566
+ const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config !== null && config !== void 0 ? config : {};
21445
21567
  const disposers = [];
21446
- const dispatcher = (data) => {
21447
- user = data.data;
21448
- callback(data);
21449
- };
21450
- const realtimeRouter = (eventUser) => {
21451
- if (userId !== eventUser.userId) {
21452
- return;
21568
+ const cacheKey = ['user', 'collection', {}];
21569
+ const responder = (data) => {
21570
+ var _a, _b;
21571
+ let users = (_a = data.data
21572
+ .map(userId => pullFromCache(['user', 'get', userId]))
21573
+ .filter(Boolean)
21574
+ .map(({ data }) => data)) !== null && _a !== void 0 ? _a : [];
21575
+ users = filterByPropEquality(users, 'displayName', params.displayName);
21576
+ switch (params.sortBy) {
21577
+ case 'firstCreated':
21578
+ users = users.sort(sortByFirstCreated);
21579
+ break;
21580
+ case 'lastCreated':
21581
+ users = users.sort(sortByLastCreated);
21582
+ break;
21583
+ default:
21584
+ users = users
21585
+ // this needs to be aligned with the backend data type
21586
+ .map(u => (u.displayName ? u : Object.assign(Object.assign({}, u), { displayName: '' })))
21587
+ // @ts-ignore
21588
+ .sort(sortByDisplayName);
21453
21589
  }
21454
- if (user && !hasUpdates(user, eventUser)) {
21590
+ callback({
21591
+ onNextPage: onFetch,
21592
+ data: users,
21593
+ hasNextPage: !!((_b = data.params) === null || _b === void 0 ? void 0 : _b.page),
21594
+ loading: data.loading,
21595
+ error: data.error,
21596
+ });
21597
+ };
21598
+ const realtimeRouter = (_) => (user) => {
21599
+ var _a;
21600
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
21601
+ if (!collection)
21455
21602
  return;
21456
- }
21457
- dispatcher({ loading: false, data: eventUser, origin: 'event' });
21603
+ collection.data = [...new Set([user.userId, ...collection.data])];
21604
+ pushToCache(cacheKey, collection);
21605
+ responder(collection);
21458
21606
  };
21459
21607
  const onFetch = () => {
21460
- const query = createQuery(getUser, userId, true);
21461
- runQuery(query, ({ loading, data, error, origin }) => {
21462
- dispatcher({ loading, data, origin, error });
21463
- if (error) {
21464
- disposers.forEach(fn => fn());
21608
+ var _a, _b, _c;
21609
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
21610
+ const users = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
21611
+ if (users.length > 0 && !(collection === null || collection === void 0 ? void 0 : collection.params.page))
21612
+ return;
21613
+ 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 } }));
21614
+ runQuery(query, ({ data: result, error, loading, nextPage: page }) => {
21615
+ const data = {
21616
+ loading,
21617
+ error,
21618
+ params: { page },
21619
+ data: users,
21620
+ };
21621
+ if (result) {
21622
+ data.data = [...new Set([...users, ...result.map(getResolver('user'))])];
21465
21623
  }
21466
- });
21624
+ pushToCache(cacheKey, data);
21625
+ responder(data);
21626
+ }, queryOptions(policy));
21467
21627
  };
21468
- disposers.push(onUserFetched(realtimeRouter), onUserUpdated(realtimeRouter), onUserDeleted(realtimeRouter), onUserFlagged(realtimeRouter), onUserUnflagged(realtimeRouter), onUserFlagCleared(realtimeRouter));
21628
+ disposers.push(onUserUpdated(realtimeRouter()), onUserDeleted(realtimeRouter()), onUserFlagged(realtimeRouter()), onUserUnflagged(realtimeRouter()), onUserFlagCleared(realtimeRouter()));
21469
21629
  onFetch();
21470
21630
  return () => {
21471
- log(`liveUser(tmpid: ${timestamp}) > dispose`);
21631
+ log(`liveUsers(tmpid: ${timestamp}) > dispose`);
21472
21632
  disposers.forEach(fn => fn());
21473
21633
  };
21474
21634
  };
@@ -21594,7 +21754,7 @@ const createFile = async (formData, onProgress) => {
21594
21754
  : { 'content-type': 'multipart/form-data' };
21595
21755
  const { data } = await client.http.post('/api/v4/files', formData, {
21596
21756
  headers,
21597
- onUploadProgress({ loaded, total }) {
21757
+ onUploadProgress({ loaded, total = 100 }) {
21598
21758
  onProgress && onProgress(Math.round((loaded * 100) / total));
21599
21759
  },
21600
21760
  });
@@ -21673,7 +21833,7 @@ const createVideo = async (formData, feedType, onProgress) => {
21673
21833
  : { 'content-type': 'multipart/form-data' };
21674
21834
  const { data } = await client.http.post('/api/v4/videos', formData, {
21675
21835
  headers,
21676
- onUploadProgress({ loaded, total }) {
21836
+ onUploadProgress({ loaded, total = 100 }) {
21677
21837
  onProgress && onProgress(Math.round((loaded * 100) / total));
21678
21838
  },
21679
21839
  });
@@ -21714,7 +21874,7 @@ const createImage = async (formData, onProgress) => {
21714
21874
  : { 'content-type': 'multipart/form-data' };
21715
21875
  const { data } = await client.http.post('/api/v4/images', formData, {
21716
21876
  headers,
21717
- onUploadProgress({ loaded, total }) {
21877
+ onUploadProgress({ loaded, total = 100 }) {
21718
21878
  onProgress && onProgress(Math.round((loaded * 100) / total));
21719
21879
  },
21720
21880
  });
@@ -22154,8 +22314,8 @@ const queryMessages = async (query) => {
22154
22314
  pushToCache(cacheKey, { messages: messages.map(getResolver('message')), paging });
22155
22315
  }
22156
22316
  fireEvent('local.message.fetched', { messages });
22157
- const nextPage = toPage(paging.next);
22158
- const prevPage = toPage(paging.previous);
22317
+ const nextPage = toPageRaw(paging.next);
22318
+ const prevPage = toPageRaw(paging.previous);
22159
22319
  return { data: messages, cachedAt, prevPage, nextPage };
22160
22320
  };
22161
22321
  /**
@@ -22186,8 +22346,8 @@ queryMessages.locally = (query) => {
22186
22346
  .map(messageId => pullFromCache(['message', 'get', messageId]))
22187
22347
  .filter(Boolean)
22188
22348
  .map(({ data }) => data);
22189
- const prevPage = toPage(data === null || data === void 0 ? void 0 : data.paging.previous);
22190
- const nextPage = toPage(data === null || data === void 0 ? void 0 : data.paging.next);
22349
+ const prevPage = toPageRaw(data === null || data === void 0 ? void 0 : data.paging.previous);
22350
+ const nextPage = toPageRaw(data === null || data === void 0 ? void 0 : data.paging.next);
22191
22351
  return messages.length === ((_b = data === null || data === void 0 ? void 0 : data.messages) === null || _b === void 0 ? void 0 : _b.length)
22192
22352
  ? { data: messages, cachedAt, prevPage, nextPage }
22193
22353
  : undefined;
@@ -23693,6 +23853,7 @@ getComments.locally = (commentIds) => {
23693
23853
  const getComment = async (commentId) => {
23694
23854
  const client = getActiveClient();
23695
23855
  client.log('comment/getComment', commentId);
23856
+ isInTombstone('comment', commentId);
23696
23857
  let data;
23697
23858
  try {
23698
23859
  // API-FIX: endpoint should not be /list, parameters should be querystring.
@@ -23700,8 +23861,8 @@ const getComment = async (commentId) => {
23700
23861
  data = response.data;
23701
23862
  }
23702
23863
  catch (error) {
23703
- if ((error === null || error === void 0 ? void 0 : error.code) === 400400 /* Amity.ServerError.ITEM_NOT_FOUND */) {
23704
- dropFromCache(['comment', 'get', commentId], true);
23864
+ if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
23865
+ pushToTombstone('comment', commentId);
23705
23866
  }
23706
23867
  throw error;
23707
23868
  }
@@ -23835,9 +23996,7 @@ const deleteComment = async (commentId, permanent = false) => {
23835
23996
  fireEvent('post.updated', { posts: [post.data] });
23836
23997
  fireEvent('comment.deleted', { comments: [deleted] });
23837
23998
  if (permanent) {
23838
- setTimeout(() => {
23839
- dropFromCache(['comment', 'get', commentId], true);
23840
- }, 0);
23999
+ scheduleTask(() => pushToTombstone('comment', commentId));
23841
24000
  }
23842
24001
  else {
23843
24002
  upsertInCache(['comment', 'get', commentId], { isDeleted: true });
@@ -24833,13 +24992,7 @@ const createReport = async (referenceType, referenceId) => {
24833
24992
  const { data } = await client.http.post(getAPIUrl());
24834
24993
  if (client.cache)
24835
24994
  ingestInCache(referenceType === 'message' ? prepareMessagePayload(data) : data);
24836
- if (referenceType === 'message') {
24837
- fireEvent('message.flagged', data);
24838
- }
24839
- else {
24840
- // @ts-ignore
24841
- fireEvent(`${referenceType}.flagged`, data);
24842
- }
24995
+ fireEvent(`${referenceType}.flagged`, data);
24843
24996
  return !!data;
24844
24997
  };
24845
24998
 
@@ -24872,13 +25025,8 @@ const deleteReport = async (referenceType, referenceId) => {
24872
25025
  const { data } = await client.http.delete(getAPIUrl());
24873
25026
  if (client.cache)
24874
25027
  ingestInCache(referenceType === 'message' ? prepareMessagePayload(data) : data);
24875
- if (referenceType === 'message') {
24876
- fireEvent('message.unflagged', data);
24877
- }
24878
- else {
24879
- // @ts-ignore
24880
- fireEvent(`${referenceType}.unflagged`, data);
24881
- }
25028
+ // @ts-ignore
25029
+ fireEvent(`${referenceType}.unflagged`, data);
24882
25030
  return !!data;
24883
25031
  };
24884
25032
 
@@ -26260,55 +26408,13 @@ const onMessageReactionRemoved = (callback) => {
26260
26408
  * @category Message Live Object
26261
26409
  */
26262
26410
  const liveChannel = (channelId, callback) => {
26263
- const { log, cache } = getActiveClient();
26264
- const timestamp = Date.now();
26265
- log(`liveChannel(tmpid: ${timestamp}) > listen`);
26266
- if (!cache) {
26267
- console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
26268
- }
26269
- let channel;
26270
- let isUnsyncedObject = false;
26271
- const disposers = [];
26272
- const dispatcher = (data) => {
26273
- channel = data.data;
26274
- callback(data);
26275
- };
26276
- const realtimeRouter = (eventChannel) => {
26277
- if (channelId !== eventChannel.channelId) {
26278
- return;
26279
- }
26280
- if (channel && !hasUpdates(channel, eventChannel)) {
26281
- return;
26282
- }
26283
- dispatcher({ loading: false, data: eventChannel, origin: 'event' });
26284
- };
26285
- const onFetch = () => {
26286
- const query = createQuery(getChannel, channelId);
26287
- runQuery(query, ({ loading, data, error, origin, cachedAt }) => {
26288
- if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
26289
- dispatcher({
26290
- data,
26291
- origin,
26292
- loading: false,
26293
- error: new ASCApiError(UNSYNCED_OBJECT_CACHED_AT_MESSAGE, 800800 /* Amity.ClientError.DISALOOW_UNSYNCED_OBJECT */, "error" /* Amity.ErrorLevel.ERROR */),
26294
- });
26295
- isUnsyncedObject = true;
26296
- disposers.forEach(fn => fn());
26297
- }
26298
- else if (!isUnsyncedObject) {
26299
- dispatcher({ loading, data, origin, error });
26300
- }
26301
- if (error) {
26302
- disposers.forEach(fn => fn());
26303
- }
26304
- });
26305
- };
26306
- disposers.push(onChannelUpdated(realtimeRouter), onChannelDeleted(realtimeRouter), onChannelJoined(realtimeRouter), onChannelMuted(realtimeRouter), onMessageCreated(() => null));
26307
- onFetch();
26308
- return () => {
26309
- log(`liveChannel(tmpid: ${timestamp}) > dispose`);
26310
- disposers.forEach(fn => fn());
26311
- };
26411
+ return liveObject(channelId, callback, 'channelId', getChannel, [
26412
+ onChannelUpdated,
26413
+ onChannelDeleted,
26414
+ onChannelJoined,
26415
+ onChannelMuted,
26416
+ () => onMessageCreated(() => null), // watch unread count
26417
+ ]);
26312
26418
  };
26313
26419
 
26314
26420
  /**
@@ -26362,22 +26468,29 @@ const liveChannels = (params, callback, config) => {
26362
26468
  if (params.membership && userId) {
26363
26469
  channels = filterByChannelMembership(channels, params.membership, userId);
26364
26470
  }
26365
- const sortBy = params.sortBy || 'lastCreated';
26366
- if (sortBy === 'lastCreated' || sortBy === 'firstCreated') {
26367
- channels = channels.sort(sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated);
26368
- }
26369
- /*
26370
- * The server returns channels with empty | null displayName's first before
26371
- * returning sorted list of channels with displayNames
26372
- *
26373
- * This section needs to be updated as displayNames can be null as well
26374
- */
26375
- if (sortBy === 'displayName') {
26376
- channels = channels
26377
- // this needs to be aligned with the backend data type
26378
- .map(c => (c.displayName ? c : Object.assign(Object.assign({}, c), { displayName: '' })))
26379
- // @ts-ignore
26380
- .sort(sortByDisplayName);
26471
+ switch (params.sortBy) {
26472
+ case 'firstCreated':
26473
+ channels = channels.sort(sortByFirstCreated);
26474
+ break;
26475
+ case 'lastCreated':
26476
+ channels = channels.sort(sortByLastCreated);
26477
+ break;
26478
+ case 'displayName':
26479
+ /*
26480
+ * The server returns channels with empty | null displayName's first before
26481
+ * returning sorted list of channels with displayNames
26482
+ *
26483
+ * This section needs to be updated as displayNames can be null as well
26484
+ */
26485
+ channels = channels
26486
+ // this needs to be aligned with the backend data type
26487
+ .map(c => (c.displayName ? c : Object.assign(Object.assign({}, c), { displayName: '' })))
26488
+ // @ts-ignore
26489
+ .sort(sortByDisplayName);
26490
+ break;
26491
+ default:
26492
+ channels = channels.sort(sortByLastActivity);
26493
+ break;
26381
26494
  }
26382
26495
  callback({
26383
26496
  onNextPage: onFetch,
@@ -26387,17 +26500,12 @@ const liveChannels = (params, callback, config) => {
26387
26500
  error: data.error,
26388
26501
  });
26389
26502
  };
26390
- const realtimeRouter = (action) => (channel) => {
26503
+ const realtimeRouter = (_) => (channel) => {
26391
26504
  var _a;
26392
26505
  const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
26393
26506
  if (!collection)
26394
26507
  return;
26395
- if (action === 'onDelete' && params.isDeleted === false) {
26396
- collection.data = collection.data.filter(c => c !== channel.channelId);
26397
- }
26398
- else {
26399
- collection.data = [...new Set([channel.channelId, ...collection.data])];
26400
- }
26508
+ collection.data = [...new Set([channel.channelId, ...collection.data])];
26401
26509
  pushToCache(cacheKey, collection);
26402
26510
  responder(collection);
26403
26511
  };
@@ -26422,7 +26530,7 @@ const liveChannels = (params, callback, config) => {
26422
26530
  responder(data);
26423
26531
  }, queryOptions(policy));
26424
26532
  };
26425
- 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));
26533
+ disposers.push(onChannelCreated(realtimeRouter()), onChannelDeleted(realtimeRouter()), onChannelUpdated(realtimeRouter()), onChannelMuted(realtimeRouter()), onChannelJoined(realtimeRouter()), onChannelLeft(realtimeRouter()), onChannelMemberAdded(realtimeRouter()), onChannelMemberRemoved(realtimeRouter()), onMessageCreated(() => null));
26426
26534
  onFetch();
26427
26535
  return () => {
26428
26536
  log(`liveChannels(tmpid: ${timestamp}) > dispose`);
@@ -26969,42 +27077,11 @@ const onSubChannelFetched = (callback) => {
26969
27077
  * @category SubChannel Live Object
26970
27078
  */
26971
27079
  const liveSubChannel = (subChannelId, callback) => {
26972
- const { log, cache } = getActiveClient();
26973
- const timestamp = Date.now();
26974
- log(`liveSubChannel(tmpid: ${timestamp}) > listen`);
26975
- if (!cache) {
26976
- console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
26977
- }
26978
- let subChannel;
26979
- const disposers = [];
26980
- const dispatcher = (data) => {
26981
- subChannel = data.data;
26982
- callback(data);
26983
- };
26984
- const realtimeRouter = (eventSubChannel) => {
26985
- if (subChannelId !== eventSubChannel.subChannelId) {
26986
- return;
26987
- }
26988
- if (subChannel && !hasUpdates(subChannel, eventSubChannel)) {
26989
- return;
26990
- }
26991
- dispatcher({ loading: false, data: eventSubChannel, origin: 'event' });
26992
- };
26993
- const onFetch = () => {
26994
- const query = createQuery(getSubChannel, subChannelId);
26995
- runQuery(query, ({ error, data, loading, origin }) => {
26996
- dispatcher({ error, data, loading, origin });
26997
- if (error) {
26998
- disposers.forEach(fn => fn());
26999
- }
27000
- });
27001
- };
27002
- disposers.push(onSubChannelFetched(realtimeRouter), onSubChannelUpdated(realtimeRouter), onSubChannelDeleted(realtimeRouter));
27003
- onFetch();
27004
- return () => {
27005
- log(`liveSubChannel(tmpid: ${timestamp}) > dispose`);
27006
- disposers.forEach(fn => fn());
27007
- };
27080
+ return liveObject(subChannelId, callback, 'subChannelId', getSubChannel, [
27081
+ onSubChannelFetched,
27082
+ onSubChannelUpdated,
27083
+ onSubChannelDeleted,
27084
+ ]);
27008
27085
  };
27009
27086
 
27010
27087
  /**
@@ -27135,55 +27212,16 @@ const onMessageFetched = (callback) => {
27135
27212
  * @category Message Live Object
27136
27213
  */
27137
27214
  const liveMessage = (messageId, callback) => {
27138
- const { log, cache } = getActiveClient();
27139
- const timestamp = Date.now();
27140
- log(`liveMessage(tmpid: ${timestamp}) > listen`);
27141
- if (!cache) {
27142
- console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
27143
- }
27144
- let message;
27145
- let isUnsyncedObject = false;
27146
- const disposers = [];
27147
- const dispatcher = (data) => {
27148
- message = data.data;
27149
- callback(data);
27150
- };
27151
- const realtimeRouter = (eventMessage) => {
27152
- if (messageId !== eventMessage.messageId) {
27153
- return;
27154
- }
27155
- if (message && !hasUpdates(message, eventMessage)) {
27156
- return;
27157
- }
27158
- dispatcher({ loading: false, data: eventMessage, origin: 'event' });
27159
- };
27160
- const onFetch = () => {
27161
- const query = createQuery(getMessage, messageId, true);
27162
- runQuery(query, ({ loading, data, error, origin, cachedAt }) => {
27163
- if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
27164
- dispatcher({
27165
- data,
27166
- origin,
27167
- loading: false,
27168
- error: new ASCApiError(UNSYNCED_OBJECT_CACHED_AT_MESSAGE, 800800 /* Amity.ClientError.DISALOOW_UNSYNCED_OBJECT */, "error" /* Amity.ErrorLevel.ERROR */),
27169
- });
27170
- isUnsyncedObject = true;
27171
- disposers.forEach(fn => fn());
27172
- }
27173
- else if (!isUnsyncedObject) {
27174
- dispatcher({ loading, data, origin, error });
27175
- }
27176
- if (error) {
27177
- disposers.forEach(fn => fn());
27178
- }
27179
- });
27180
- };
27181
- disposers.push(onMessageFetched(realtimeRouter), onMessageUpdated(realtimeRouter), onMessageDeleted(realtimeRouter), onMessageFlagged(realtimeRouter), onMessageUnflagged(realtimeRouter), onMessageFlagCleared(realtimeRouter), onMessageReactionAdded(realtimeRouter), onMessageReactionRemoved(realtimeRouter));
27182
- onFetch();
27183
- return () => {
27184
- log(`liveMessage(tmpid: ${timestamp}) > dispose`);
27185
- disposers.forEach(fn => fn());
27186
- };
27215
+ return liveObject(messageId, callback, 'messageId', getMessage, [
27216
+ onMessageFetched,
27217
+ onMessageUpdated,
27218
+ onMessageDeleted,
27219
+ onMessageFlagged,
27220
+ onMessageUnflagged,
27221
+ onMessageFlagCleared,
27222
+ onMessageReactionAdded,
27223
+ onMessageReactionRemoved,
27224
+ ]);
27187
27225
  };
27188
27226
 
27189
27227
  /**
@@ -27384,6 +27422,30 @@ const createCommunityEventSubscriber = (event, callback) => {
27384
27422
  };
27385
27423
  return createEventSubscriber(client, event, event, filter);
27386
27424
  };
27425
+ /*
27426
+ * verifies membership status
27427
+ */
27428
+ function isMember(membership) {
27429
+ return membership !== 'none';
27430
+ }
27431
+ /*
27432
+ * checks if currently logged in user is part of the community
27433
+ */
27434
+ function isCurrentUserPartOfCommunity(c, m) {
27435
+ const { userId } = getActiveUser();
27436
+ return c.communityId === m.communityId && m.userId === userId;
27437
+ }
27438
+ /*
27439
+ * For mqtt events server will not send user specific data as it's broadcasted
27440
+ * to multiple users. Althought this can be calculated, it's not scalable. Hence
27441
+ * the client SDK needs to calculate this info
27442
+ */
27443
+ function updateMembershipStatus(communities, communityUsers) {
27444
+ return communities.map(c => {
27445
+ const isJoined = communityUsers.some(m => isCurrentUserPartOfCommunity(c, m) && isMember(m.communityMembership));
27446
+ return Object.assign(Object.assign({}, c), { isJoined });
27447
+ });
27448
+ }
27387
27449
  function hasPermission(member, payload, permission) {
27388
27450
  if (member.permissions.some(x => x === permission)) {
27389
27451
  return true;
@@ -27414,7 +27476,15 @@ const createCommunityMemberEventSubscriber = (event, callback) => {
27414
27476
  const client = getActiveClient();
27415
27477
  const filter = (payload) => {
27416
27478
  const communityPayload = unpackCommunityPayload(payload);
27479
+ const { communities } = communityPayload;
27417
27480
  const preparedPayload = prepareMembershipPayload(communityPayload, 'communityUsers');
27481
+ const { communityUsers } = preparedPayload;
27482
+ /*
27483
+ * community.isJoined is not part of the communityMembership payload, and needs
27484
+ * to be calculated based on the communityMembership value
27485
+ */
27486
+ const communitiesWithMembership = updateMembershipStatus(communities, communityUsers);
27487
+ preparedPayload.communities = communitiesWithMembership;
27418
27488
  if (!client.cache) {
27419
27489
  // TODO: here we are missing specific properties here!
27420
27490
  callback(preparedPayload.communities[0], getEventRelatedMember(event, preparedPayload));
@@ -27556,6 +27626,23 @@ const onCommunityUserAdded = (callback) => createCommunityMemberEventSubscriber(
27556
27626
  */
27557
27627
  const onCommunityUserRemoved = (callback) => createCommunityMemberEventSubscriber('community.userRemoved', callback);
27558
27628
 
27629
+ /**
27630
+ * ```js
27631
+ * import { onCommunityUserChanged } from '@amityco/ts-sdk'
27632
+ * const dispose = onCommunityUserChanged((community, member) => {
27633
+ * // ...
27634
+ * })
27635
+ * ```
27636
+ *
27637
+ * Fired when a user has been added or removed from a {@link Amity.Community}
27638
+ *
27639
+ * @param callback The function to call when the event was fired
27640
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
27641
+ *
27642
+ * @category Community Events
27643
+ */
27644
+ const onCommunityUserChanged = (callback) => createCommunityMemberEventSubscriber('community.userChanged', callback);
27645
+
27559
27646
  /**
27560
27647
  * ```js
27561
27648
  * import { onCommunityUserBanned } from '@amityco/ts-sdk'
@@ -27634,6 +27721,122 @@ const observeCommunity = (communityId, callback) => {
27634
27721
  };
27635
27722
  };
27636
27723
 
27724
+ /**
27725
+ * ```js
27726
+ * import { liveCommunities } from '@amityco/ts-sdk'
27727
+ *
27728
+ * let communities = []
27729
+ * const unsub = liveCommunities({
27730
+ * displayName: Amity.Community['displayName'],
27731
+ * }, response => merge(communities, response.data))
27732
+ * ```
27733
+ *
27734
+ * Observe all mutations on a list of {@link Amity.Community}s
27735
+ *
27736
+ * @param params for querying communities
27737
+ * @param callback the function to call when new data are available
27738
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the communities
27739
+ *
27740
+ * @category Community Live Collection
27741
+ */
27742
+ const liveCommunities = (params, callback, config) => {
27743
+ const { log, cache } = getActiveClient();
27744
+ if (!cache) {
27745
+ console.log(ENABLE_CACHE_MESSAGE);
27746
+ }
27747
+ const timestamp = Date.now();
27748
+ log(`liveCommunities(tmpid: ${timestamp}) > listen`);
27749
+ const { limit: queryLimit } = params, queryParams = __rest(params, ["limit"]);
27750
+ const limit = queryLimit !== null && queryLimit !== void 0 ? queryLimit : COLLECTION_DEFAULT_PAGINATION_LIMIT;
27751
+ const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config !== null && config !== void 0 ? config : {};
27752
+ const disposers = [];
27753
+ const cacheKey = ['community', 'collection', {}];
27754
+ const responder = (data) => {
27755
+ var _a, _b;
27756
+ let communities = (_a = data.data
27757
+ .map(communityId => pullFromCache(['community', 'get', communityId]))
27758
+ .filter(Boolean)
27759
+ .map(({ data }) => data)) !== null && _a !== void 0 ? _a : [];
27760
+ communities = filterByPropEquality(communities, 'isDeleted', params.isDeleted);
27761
+ communities = filterByPropEquality(communities, 'displayName', params.displayName);
27762
+ if (params.categoryId) {
27763
+ communities = communities.filter(c => { var _a; return (_a = c.categoryIds) === null || _a === void 0 ? void 0 : _a.includes(params.categoryId); });
27764
+ }
27765
+ if (params.tags) {
27766
+ 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); }); });
27767
+ }
27768
+ if (params.membership === 'member') {
27769
+ communities = filterByPropEquality(communities, 'isJoined', true);
27770
+ }
27771
+ if (params.membership === 'notMember') {
27772
+ communities = filterByPropEquality(communities, 'isJoined', false);
27773
+ }
27774
+ const sortBy = params.sortBy || 'lastCreated';
27775
+ if (sortBy === 'lastCreated' || sortBy === 'firstCreated') {
27776
+ communities = communities.sort(sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated);
27777
+ }
27778
+ /*
27779
+ * The server returns communities with empty | null displayName's first before
27780
+ * returning sorted list of communities with displayNames
27781
+ *
27782
+ * This section needs to be updated as displayNames can be null as well
27783
+ */
27784
+ if (sortBy === 'displayName') {
27785
+ communities = communities
27786
+ // this needs to be aligned with the backend data type
27787
+ .map(c => (c.displayName ? c : Object.assign(Object.assign({}, c), { displayName: '' })))
27788
+ // @ts-ignore
27789
+ .sort(sortByDisplayName);
27790
+ }
27791
+ callback({
27792
+ onNextPage: onFetch,
27793
+ data: communities,
27794
+ hasNextPage: !!((_b = data.params) === null || _b === void 0 ? void 0 : _b.page),
27795
+ loading: data.loading,
27796
+ error: data.error,
27797
+ });
27798
+ };
27799
+ const realtimeRouter = (_) => (community) => {
27800
+ var _a;
27801
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
27802
+ if (!collection)
27803
+ return;
27804
+ /*
27805
+ * Simply update collection and let responder decide what to do with data
27806
+ */
27807
+ collection.data = [...new Set([community.communityId, ...collection.data])];
27808
+ pushToCache(cacheKey, collection);
27809
+ responder(collection);
27810
+ };
27811
+ const onFetch = () => {
27812
+ var _a, _b, _c;
27813
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
27814
+ const communities = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
27815
+ if (communities.length > 0 && !(collection === null || collection === void 0 ? void 0 : collection.params.page))
27816
+ return;
27817
+ 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 } }));
27818
+ runQuery(query, ({ data: result, error, loading, nextPage: page }) => {
27819
+ const data = {
27820
+ loading,
27821
+ error,
27822
+ params: { page },
27823
+ data: communities,
27824
+ };
27825
+ if (result) {
27826
+ data.data = [...new Set([...communities, ...result.map(getResolver('community'))])];
27827
+ }
27828
+ pushToCache(cacheKey, data);
27829
+ responder(data);
27830
+ }, queryOptions(policy));
27831
+ };
27832
+ disposers.push(onCommunityCreated(realtimeRouter()), onCommunityDeleted(realtimeRouter()), onCommunityUpdated(realtimeRouter()), onCommunityJoined(realtimeRouter()), onCommunityLeft(realtimeRouter()), onCommunityUserChanged(realtimeRouter()));
27833
+ onFetch();
27834
+ return () => {
27835
+ log(`liveCommunities(tmpid: ${timestamp}) > dispose`);
27836
+ disposers.forEach(fn => fn());
27837
+ };
27838
+ };
27839
+
27637
27840
  /**
27638
27841
  * ```js
27639
27842
  * import { queryCategories } from '@amityco/ts-sdk'
@@ -27762,6 +27965,96 @@ getCategory.locally = (categoryId) => {
27762
27965
  };
27763
27966
  };
27764
27967
 
27968
+ /**
27969
+ * ```js
27970
+ * import { liveCategories } from '@amityco/ts-sdk'
27971
+ *
27972
+ * let categories = []
27973
+ * const unsub = liveCategories({}, response => merge(categories, response.data))
27974
+ * ```
27975
+ *
27976
+ * Observe all mutations on a list of {@link Amity.Category}s
27977
+ *
27978
+ * @param params for querying categories
27979
+ * @param callback the function to call when new data are available
27980
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the categories
27981
+ *
27982
+ * @category Category Live Collection
27983
+ */
27984
+ const liveCategories = (params, callback, config) => {
27985
+ const { log, cache } = getActiveClient();
27986
+ if (!cache) {
27987
+ console.log(ENABLE_CACHE_MESSAGE);
27988
+ }
27989
+ const timestamp = Date.now();
27990
+ log(`liveCategories(tmpid: ${timestamp}) > listen`);
27991
+ const { limit: queryLimit } = params, queryParams = __rest(params, ["limit"]);
27992
+ const limit = queryLimit !== null && queryLimit !== void 0 ? queryLimit : COLLECTION_DEFAULT_PAGINATION_LIMIT;
27993
+ const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config !== null && config !== void 0 ? config : {};
27994
+ const disposers = [];
27995
+ const cacheKey = ['category', 'collection', {}];
27996
+ const responder = (data) => {
27997
+ var _a, _b;
27998
+ let categories = (_a = data.data
27999
+ .map(categoryId => pullFromCache(['category', 'get', categoryId]))
28000
+ .filter(Boolean)
28001
+ .map(({ data }) => data)) !== null && _a !== void 0 ? _a : [];
28002
+ categories = filterByPropEquality(categories, 'isDeleted', params.isDeleted);
28003
+ switch (params.sortBy) {
28004
+ case 'firstCreated':
28005
+ categories = categories.sort(sortByFirstCreated);
28006
+ break;
28007
+ case 'lastCreated':
28008
+ categories = categories.sort(sortByLastCreated);
28009
+ break;
28010
+ default:
28011
+ categories = categories.sort(sortByName);
28012
+ }
28013
+ callback({
28014
+ onNextPage: onFetch,
28015
+ data: categories,
28016
+ hasNextPage: !!((_b = data.params) === null || _b === void 0 ? void 0 : _b.page),
28017
+ loading: data.loading,
28018
+ error: data.error,
28019
+ });
28020
+ };
28021
+ /*
28022
+ * const realtimeRouter = () => {
28023
+ * @TODO: At the time of creating this method category does not have any
28024
+ * observers
28025
+ *};
28026
+ */
28027
+ const onFetch = () => {
28028
+ var _a, _b, _c;
28029
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
28030
+ const categories = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
28031
+ if (categories.length > 0 && !(collection === null || collection === void 0 ? void 0 : collection.params.page))
28032
+ return;
28033
+ 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 } }));
28034
+ runQuery(query, ({ data: result, error, loading, nextPage: page }) => {
28035
+ const data = {
28036
+ loading,
28037
+ error,
28038
+ params: { page },
28039
+ data: categories,
28040
+ };
28041
+ if (result) {
28042
+ data.data = [...new Set([...categories, ...result.map(getResolver('category'))])];
28043
+ }
28044
+ pushToCache(cacheKey, data);
28045
+ responder(data);
28046
+ }, queryOptions(policy));
28047
+ };
28048
+ disposers.push(() => {
28049
+ // @TODO -> update once observers added
28050
+ });
28051
+ onFetch();
28052
+ return () => {
28053
+ log(`liveCategories(tmpid: ${timestamp}) > dispose`);
28054
+ disposers.forEach(fn => fn());
28055
+ };
28056
+ };
28057
+
27765
28058
  /**
27766
28059
  * ```js
27767
28060
  * import { queryGlobalFeed } from '@amityco/ts-sdk'
@@ -28686,6 +28979,38 @@ const observePost = (postId, callback, policy = 'cache_then_server') => {
28686
28979
  };
28687
28980
  };
28688
28981
 
28982
+ /**
28983
+ * ```js
28984
+ * import { livePost } from '@amityco/ts-sdk';
28985
+ *
28986
+ * let post;
28987
+ *
28988
+ * const unsubscribe = livePost(postId, response => {
28989
+ * post = response.data;
28990
+ * });
28991
+ * ```
28992
+ *
28993
+ * Observe all mutation on a given {@link Amity.Post}
28994
+ *
28995
+ * @param postId the ID of the message to observe
28996
+ * @param callback the function to call when new data are available
28997
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the sub channel
28998
+ *
28999
+ * @category Post Live Object
29000
+ */
29001
+ const livePost = (postId, callback) => {
29002
+ return liveObject(postId, callback, 'postId', getPost, [
29003
+ onPostApproved,
29004
+ onPostDeclined,
29005
+ onPostDeleted,
29006
+ onPostFlagged,
29007
+ onPostReactionAdded,
29008
+ onPostReactionRemoved,
29009
+ onPostUnflagged,
29010
+ onPostUpdated,
29011
+ ]);
29012
+ };
29013
+
28689
29014
  /**
28690
29015
  * ```js
28691
29016
  * import { livePosts } from '@amityco/ts-sdk'
@@ -28699,8 +29024,8 @@ const observePost = (postId, callback, policy = 'cache_then_server') => {
28699
29024
  *
28700
29025
  * Observe all mutations on a list of {@link Amity.Post} for a given target object
28701
29026
  *
28702
- * @param targetType the type of the target
28703
- * @param targetId the ID of the target
29027
+ * @param param.targetType the type of the target
29028
+ * @param param.targetId the ID of the target
28704
29029
  * @param callback the function to call when new data are available
28705
29030
  * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the messages
28706
29031
  *
@@ -28734,6 +29059,9 @@ const livePosts = (params, callback, config) => {
28734
29059
  if (params.tags) {
28735
29060
  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); }); });
28736
29061
  }
29062
+ if (params.targetType === 'community' && params.feedType) {
29063
+ posts = filterByFeedType(posts, params.feedType);
29064
+ }
28737
29065
  callback({
28738
29066
  onNextPage: onFetch,
28739
29067
  data: posts,
@@ -28747,27 +29075,16 @@ const livePosts = (params, callback, config) => {
28747
29075
  const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
28748
29076
  if (params.targetId !== post.targetId || params.targetType !== post.targetType || !collection)
28749
29077
  return;
28750
- if (['onCreate', 'onApproved'].includes(action)) {
28751
- collection.data = [...new Set([post.postId, ...collection.data])];
28752
- }
28753
- else if (['onDelete', 'onDeclined'].includes(action)) {
28754
- collection.data = collection.data.filter(p => p !== post.postId);
28755
- /*
28756
- * if isDeleted is true, collection should add deleted items to the
28757
- * begining of the collection
28758
- */
28759
- if (params.isDeleted)
28760
- collection.data.unshift(post.postId);
28761
- }
28762
29078
  /*
28763
- * FIX-ME
28764
- * This is a shortcoming as the feed object is not saved to the cache.
28765
- * The responder should pull the feed from cache once available and should
28766
- * match the collection to feedType param
28767
- * https://ekoapp.atlassian.net/browse/ASC-9382
29079
+ * This is not ideal, but currently this is the only way to update the
29080
+ * collection on post declined
28768
29081
  */
28769
- if (params.feedType === 'reviewing' && action === 'onApproved')
28770
- collection.data = collection.data.filter(p => p !== post.postId);
29082
+ if (action === 'onDeclined') {
29083
+ collection.data = collection.data.filter(postId => postId !== post.postId);
29084
+ }
29085
+ else {
29086
+ collection.data = [...new Set([post.postId, ...collection.data])];
29087
+ }
28771
29088
  pushToCache(cacheKey, collection);
28772
29089
  responder(collection);
28773
29090
  };
@@ -28881,6 +29198,36 @@ const observeComment = (commentId, callback, policy = 'cache_then_server') => {
28881
29198
  };
28882
29199
  };
28883
29200
 
29201
+ /**
29202
+ * ```js
29203
+ * import { liveComment } from '@amityco/ts-sdk';
29204
+ *
29205
+ * let comment;
29206
+ *
29207
+ * const unsubscribe = liveComment(commentId, response => {
29208
+ * comment = response.data;
29209
+ * });
29210
+ * ```
29211
+ *
29212
+ * Observe all mutation on a given {@link Amity.Comment}
29213
+ *
29214
+ * @param commentId the ID of the comment to observe
29215
+ * @param callback the function to call when new data are available
29216
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the comment
29217
+ *
29218
+ * @category Comment Live Object
29219
+ */
29220
+ const liveComment = (commentId, callback) => {
29221
+ return liveObject(commentId, callback, 'commentId', getComment, [
29222
+ onCommentDeleted,
29223
+ onCommentFlagged,
29224
+ onCommentReactionAdded,
29225
+ onCommentReactionRemoved,
29226
+ onCommentUnflagged,
29227
+ onCommentUpdated,
29228
+ ]);
29229
+ };
29230
+
28884
29231
  /**
28885
29232
  * ```js
28886
29233
  * import { liveComments } from '@amityco/ts-sdk'
@@ -29622,6 +29969,7 @@ exports.dropFromCache = dropFromCache;
29622
29969
  exports.enableCache = enableCache;
29623
29970
  exports.fileUrlWithSize = fileUrlWithSize;
29624
29971
  exports.filterByChannelMembership = filterByChannelMembership;
29972
+ exports.filterByFeedType = filterByFeedType;
29625
29973
  exports.filterByPropEquality = filterByPropEquality;
29626
29974
  exports.filterByPropInclusion = filterByPropInclusion;
29627
29975
  exports.follow = follow;
@@ -29673,24 +30021,29 @@ exports.isMutator = isMutator;
29673
30021
  exports.isOffline = isOffline;
29674
30022
  exports.isPaged = isPaged;
29675
30023
  exports.isReportedByMe = isReportedByMe;
29676
- exports.isSkipLimit = isSkipLimit;
30024
+ exports.isSkip = isSkip;
29677
30025
  exports.joinChannel = joinChannel;
29678
30026
  exports.joinCommunity = joinCommunity;
29679
30027
  exports.leaveChannel = leaveChannel;
29680
30028
  exports.leaveCommunity = leaveCommunity;
30029
+ exports.liveCategories = liveCategories;
29681
30030
  exports.liveChannel = liveChannel;
29682
30031
  exports.liveChannelMembers = liveChannelMembers;
29683
30032
  exports.liveChannels = liveChannels;
30033
+ exports.liveComment = liveComment;
29684
30034
  exports.liveComments = liveComments;
30035
+ exports.liveCommunities = liveCommunities;
29685
30036
  exports.liveFollowers = liveFollowers;
29686
30037
  exports.liveFollowings = liveFollowings;
29687
30038
  exports.liveMessage = liveMessage;
29688
30039
  exports.liveMessages = liveMessages;
30040
+ exports.livePost = livePost;
29689
30041
  exports.livePosts = livePosts;
29690
30042
  exports.liveReactions = liveReactions;
29691
30043
  exports.liveSubChannel = liveSubChannel;
29692
30044
  exports.liveSubChannels = liveSubChannels;
29693
30045
  exports.liveUser = liveUser;
30046
+ exports.liveUsers = liveUsers;
29694
30047
  exports.mergeInCache = mergeInCache;
29695
30048
  exports.observeChannel = observeChannel;
29696
30049
  exports.observeChannels = observeChannels;
@@ -29733,6 +30086,7 @@ exports.onCommunityLeft = onCommunityLeft;
29733
30086
  exports.onCommunityUpdated = onCommunityUpdated;
29734
30087
  exports.onCommunityUserAdded = onCommunityUserAdded;
29735
30088
  exports.onCommunityUserBanned = onCommunityUserBanned;
30089
+ exports.onCommunityUserChanged = onCommunityUserChanged;
29736
30090
  exports.onCommunityUserRemoved = onCommunityUserRemoved;
29737
30091
  exports.onCommunityUserUnbanned = onCommunityUserUnbanned;
29738
30092
  exports.onConnectionError = onConnectionError;
@@ -29812,6 +30166,7 @@ exports.sortByDisplayName = sortByDisplayName;
29812
30166
  exports.sortByFirstCreated = sortByFirstCreated;
29813
30167
  exports.sortByLastActivity = sortByLastActivity;
29814
30168
  exports.sortByLastCreated = sortByLastCreated;
30169
+ exports.sortByName = sortByName;
29815
30170
  exports.sortBySegmentNumber = sortBySegmentNumber;
29816
30171
  exports.startReading = startReading;
29817
30172
  exports.stopReading = stopReading;