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

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 (279) hide show
  1. package/.eslintrc.json +3 -5
  2. package/dist/@types/core/errors.d.ts +1 -0
  3. package/dist/@types/core/errors.d.ts.map +1 -1
  4. package/dist/@types/core/events.d.ts +5 -0
  5. package/dist/@types/core/events.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/client.d.ts +21 -1
  9. package/dist/@types/domains/client.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/global.d.ts +12 -0
  13. package/dist/@types/global.d.ts.map +1 -1
  14. package/dist/category/api/queryCategories.d.ts +1 -5
  15. package/dist/category/api/queryCategories.d.ts.map +1 -1
  16. package/dist/category/observers/index.d.ts +2 -0
  17. package/dist/category/observers/index.d.ts.map +1 -0
  18. package/dist/category/observers/liveCategories.d.ts +18 -0
  19. package/dist/category/observers/liveCategories.d.ts.map +1 -0
  20. package/dist/category/observers/tests/liveCategories.test.d.ts +2 -0
  21. package/dist/category/observers/tests/liveCategories.test.d.ts.map +1 -0
  22. package/dist/channel/api/tests/getChannels.test.d.ts +2 -0
  23. package/dist/channel/api/tests/getChannels.test.d.ts.map +1 -0
  24. package/dist/channel/api/tests/leaveChannel.test.d.ts +2 -0
  25. package/dist/channel/api/tests/leaveChannel.test.d.ts.map +1 -0
  26. package/dist/channel/observers/liveChannel.d.ts.map +1 -1
  27. package/dist/client/api/accessTokenExpiryWatcher.d.ts +7 -0
  28. package/dist/client/api/accessTokenExpiryWatcher.d.ts.map +1 -0
  29. package/dist/client/api/activeUser.d.ts +1 -1
  30. package/dist/client/api/activeUser.d.ts.map +1 -1
  31. package/dist/client/api/connectClient.d.ts +1 -1
  32. package/dist/client/api/connectClient.d.ts.map +1 -1
  33. package/dist/client/api/createClient.d.ts +1 -1
  34. package/dist/client/api/createClient.d.ts.map +1 -1
  35. package/dist/client/api/disconnectClient.d.ts +0 -1
  36. package/dist/client/api/disconnectClient.d.ts.map +1 -1
  37. package/dist/client/api/getToken.d.ts +7 -5
  38. package/dist/client/api/getToken.d.ts.map +1 -1
  39. package/dist/client/api/index.d.ts +1 -0
  40. package/dist/client/api/index.d.ts.map +1 -1
  41. package/dist/client/api/renewal.d.ts +2 -0
  42. package/dist/client/api/renewal.d.ts.map +1 -0
  43. package/dist/client/api/setSessionState.d.ts +12 -0
  44. package/dist/client/api/setSessionState.d.ts.map +1 -0
  45. package/dist/client/api/terminateClient.d.ts +9 -0
  46. package/dist/client/api/terminateClient.d.ts.map +1 -0
  47. package/dist/client/api/tests/accessTokenExpiryWatcher.test.d.ts +2 -0
  48. package/dist/client/api/tests/accessTokenExpiryWatcher.test.d.ts.map +1 -0
  49. package/dist/client/api/tests/connectClient.test.d.ts +2 -0
  50. package/dist/client/api/tests/connectClient.test.d.ts.map +1 -0
  51. package/dist/client/api/tests/disconnectClient.test.d.ts +2 -0
  52. package/dist/client/api/tests/disconnectClient.test.d.ts.map +1 -0
  53. package/dist/client/api/tests/getToken.test.d.ts +2 -0
  54. package/dist/client/api/tests/getToken.test.d.ts.map +1 -0
  55. package/dist/client/api/tests/renewal.test.d.ts +2 -0
  56. package/dist/client/api/tests/renewal.test.d.ts.map +1 -0
  57. package/dist/client/api/tests/setSessionState.test.d.ts +2 -0
  58. package/dist/client/api/tests/setSessionState.test.d.ts.map +1 -0
  59. package/dist/client/api/tests/terminateClient.test.d.ts +2 -0
  60. package/dist/client/api/tests/terminateClient.test.d.ts.map +1 -0
  61. package/dist/client/events/index.d.ts +1 -0
  62. package/dist/client/events/index.d.ts.map +1 -1
  63. package/dist/client/events/onClientBanned.d.ts +1 -1
  64. package/dist/client/events/onClientBanned.d.ts.map +1 -1
  65. package/dist/client/events/onSessionStateChange.d.ts +17 -0
  66. package/dist/client/events/onSessionStateChange.d.ts.map +1 -0
  67. package/dist/client/events/onTokenExpired.d.ts +17 -0
  68. package/dist/client/events/onTokenExpired.d.ts.map +1 -0
  69. package/dist/client/events/onTokenTerminated.d.ts +11 -0
  70. package/dist/client/events/onTokenTerminated.d.ts.map +1 -0
  71. package/dist/client/events/tests/onSessionStateChange.test.d.ts +2 -0
  72. package/dist/client/events/tests/onSessionStateChange.test.d.ts.map +1 -0
  73. package/dist/client/events/tests/onTokenTerminated.test.d.ts +2 -0
  74. package/dist/client/events/tests/onTokenTerminated.test.d.ts.map +1 -0
  75. package/dist/client/utils/setClientToken.d.ts +19 -0
  76. package/dist/client/utils/setClientToken.d.ts.map +1 -0
  77. package/dist/comment/api/deleteComment.d.ts.map +1 -1
  78. package/dist/comment/api/getComment.d.ts.map +1 -1
  79. package/dist/comment/events/tests/onCommentDeleted.test.d.ts +2 -0
  80. package/dist/comment/events/tests/onCommentDeleted.test.d.ts.map +1 -0
  81. package/dist/comment/observers/index.d.ts +1 -0
  82. package/dist/comment/observers/index.d.ts.map +1 -1
  83. package/dist/comment/observers/liveComment.d.ts +21 -0
  84. package/dist/comment/observers/liveComment.d.ts.map +1 -0
  85. package/dist/comment/observers/tests/liveComment.test.d.ts +2 -0
  86. package/dist/comment/observers/tests/liveComment.test.d.ts.map +1 -0
  87. package/dist/community/api/queryCommunities.d.ts +1 -10
  88. package/dist/community/api/queryCommunities.d.ts.map +1 -1
  89. package/dist/community/events/index.d.ts +1 -0
  90. package/dist/community/events/index.d.ts.map +1 -1
  91. package/dist/community/events/onCommunityUserChanged.d.ts +17 -0
  92. package/dist/community/events/onCommunityUserChanged.d.ts.map +1 -0
  93. package/dist/community/events/utils.d.ts +1 -0
  94. package/dist/community/events/utils.d.ts.map +1 -1
  95. package/dist/community/observers/index.d.ts +1 -0
  96. package/dist/community/observers/index.d.ts.map +1 -1
  97. package/dist/community/observers/liveCommunities.d.ts +20 -0
  98. package/dist/community/observers/liveCommunities.d.ts.map +1 -0
  99. package/dist/community/observers/tests/liveCommunities.test.d.ts +2 -0
  100. package/dist/community/observers/tests/liveCommunities.test.d.ts.map +1 -0
  101. package/dist/core/events.d.ts +3 -3
  102. package/dist/core/events.d.ts.map +1 -1
  103. package/dist/core/query/sorting.d.ts +6 -0
  104. package/dist/core/query/sorting.d.ts.map +1 -1
  105. package/dist/core/subscription.d.ts.map +1 -1
  106. package/dist/core/transports/http.d.ts +0 -5
  107. package/dist/core/transports/http.d.ts.map +1 -1
  108. package/dist/file/api/test/createImage.test.d.ts +2 -0
  109. package/dist/file/api/test/createImage.test.d.ts.map +1 -0
  110. package/dist/file/api/test/createVideo.test.d.ts +2 -0
  111. package/dist/file/api/test/createVideo.test.d.ts.map +1 -0
  112. package/dist/index.cjs.js +944 -332
  113. package/dist/index.d.ts +1 -0
  114. package/dist/index.d.ts.map +1 -1
  115. package/dist/index.esm.js +937 -332
  116. package/dist/index.umd.js +4 -4
  117. package/dist/message/observers/liveMessage.d.ts.map +1 -1
  118. package/dist/post/observers/index.d.ts +1 -0
  119. package/dist/post/observers/index.d.ts.map +1 -1
  120. package/dist/post/observers/livePost.d.ts +21 -0
  121. package/dist/post/observers/livePost.d.ts.map +1 -0
  122. package/dist/post/observers/tests/livePost.test.d.ts +2 -0
  123. package/dist/post/observers/tests/livePost.test.d.ts.map +1 -0
  124. package/dist/stream/api/tests/createStream.test.d.ts +2 -0
  125. package/dist/stream/api/tests/createStream.test.d.ts.map +1 -0
  126. package/dist/stream/api/tests/deleteStream.test.d.ts +2 -0
  127. package/dist/stream/api/tests/deleteStream.test.d.ts.map +1 -0
  128. package/dist/stream/api/tests/getStream.test.d.ts +2 -0
  129. package/dist/stream/api/tests/getStream.test.d.ts.map +1 -0
  130. package/dist/subChannel/api/tests/createSubChannel.test.d.ts +2 -0
  131. package/dist/subChannel/api/tests/createSubChannel.test.d.ts.map +1 -0
  132. package/dist/subChannel/api/tests/deleteSubChannel.test.d.ts +2 -0
  133. package/dist/subChannel/api/tests/deleteSubChannel.test.d.ts.map +1 -0
  134. package/dist/subChannel/api/tests/getSubChannel.test.d.ts +2 -0
  135. package/dist/subChannel/api/tests/getSubChannel.test.d.ts.map +1 -0
  136. package/dist/subChannel/api/tests/getSubChannels.test.d.ts +2 -0
  137. package/dist/subChannel/api/tests/getSubChannels.test.d.ts.map +1 -0
  138. package/dist/subChannel/api/tests/updateSubChannel.test.d.ts +2 -0
  139. package/dist/subChannel/api/tests/updateSubChannel.test.d.ts.map +1 -0
  140. package/dist/subChannel/observers/liveSubChannel.d.ts.map +1 -1
  141. package/dist/user/api/tests/updateUser.test.d.ts +2 -0
  142. package/dist/user/api/tests/updateUser.test.d.ts.map +1 -0
  143. package/dist/user/observers/liveUser.d.ts.map +1 -1
  144. package/dist/utils/constants.d.ts +2 -0
  145. package/dist/utils/constants.d.ts.map +1 -1
  146. package/dist/utils/liveObject.d.ts +2 -0
  147. package/dist/utils/liveObject.d.ts.map +1 -0
  148. package/dist/utils/tests/client.d.ts.map +1 -1
  149. package/dist/utils/tests/dummy/category.d.ts +64 -0
  150. package/dist/utils/tests/dummy/category.d.ts.map +1 -0
  151. package/dist/utils/tests/dummy/channel.d.ts +50 -0
  152. package/dist/utils/tests/dummy/channel.d.ts.map +1 -1
  153. package/dist/utils/tests/dummy/community.d.ts +132 -0
  154. package/dist/utils/tests/dummy/community.d.ts.map +1 -1
  155. package/dist/utils/tests/dummy/file.d.ts +3 -0
  156. package/dist/utils/tests/dummy/file.d.ts.map +1 -1
  157. package/dist/utils/tests/dummy/index.d.ts +3 -0
  158. package/dist/utils/tests/dummy/index.d.ts.map +1 -1
  159. package/dist/utils/tests/dummy/post.d.ts +2 -0
  160. package/dist/utils/tests/dummy/post.d.ts.map +1 -1
  161. package/dist/utils/tests/dummy/stream.d.ts +83 -0
  162. package/dist/utils/tests/dummy/stream.d.ts.map +1 -0
  163. package/dist/utils/tests/dummy/token.d.ts +11 -0
  164. package/dist/utils/tests/dummy/token.d.ts.map +1 -0
  165. package/dist/utils/tests/dummy/user.d.ts +18 -0
  166. package/dist/utils/tests/dummy/user.d.ts.map +1 -1
  167. package/dist/utils/tests/liveObject.test.d.ts +2 -0
  168. package/dist/utils/tests/liveObject.test.d.ts.map +1 -0
  169. package/package.json +4 -4
  170. package/src/@types/core/errors.ts +1 -0
  171. package/src/@types/core/events.ts +7 -0
  172. package/src/@types/domains/category.ts +13 -0
  173. package/src/@types/domains/client.ts +45 -1
  174. package/src/@types/domains/community.ts +25 -0
  175. package/src/@types/global.ts +19 -0
  176. package/src/category/api/queryCategories.ts +3 -5
  177. package/src/category/observers/index.ts +1 -0
  178. package/src/category/observers/liveCategories.ts +141 -0
  179. package/src/category/observers/tests/liveCategories.test.ts +147 -0
  180. package/src/channel/api/tests/createChannel.test.ts +30 -6
  181. package/src/channel/api/tests/getChannel.test.ts +3 -1
  182. package/src/channel/api/tests/getChannels.test.ts +97 -0
  183. package/src/channel/api/tests/joinChannel.test.ts +62 -3
  184. package/src/channel/api/tests/leaveChannel.test.ts +90 -0
  185. package/src/channel/api/tests/queryChannels.test.ts +38 -1
  186. package/src/channel/observers/liveChannel.ts +8 -80
  187. package/src/client/api/accessTokenExpiryWatcher.ts +85 -0
  188. package/src/client/api/activeUser.ts +1 -1
  189. package/src/client/api/connectClient.ts +105 -24
  190. package/src/client/api/createClient.ts +9 -1
  191. package/src/client/api/disconnectClient.ts +26 -2
  192. package/src/client/api/getToken.ts +6 -6
  193. package/src/client/api/index.ts +2 -0
  194. package/src/client/api/renewal.ts +74 -0
  195. package/src/client/api/setSessionState.ts +75 -0
  196. package/src/client/api/terminateClient.ts +20 -0
  197. package/src/client/api/tests/accessTokenExpiryWatcher.test.ts +132 -0
  198. package/src/client/api/tests/connectClient.test.ts +84 -0
  199. package/src/client/api/tests/createClient.test.ts +8 -0
  200. package/src/client/api/tests/disconnectClient.test.ts +78 -0
  201. package/src/client/api/tests/getToken.test.ts +36 -0
  202. package/src/client/api/tests/renewal.test.ts +67 -0
  203. package/src/client/api/tests/setSessionState.test.ts +62 -0
  204. package/src/client/api/tests/terminateClient.test.ts +29 -0
  205. package/src/client/events/index.ts +2 -0
  206. package/src/client/events/onClientBanned.ts +12 -5
  207. package/src/client/events/onSessionStateChange.ts +31 -0
  208. package/src/client/events/onTokenExpired.ts +26 -0
  209. package/src/client/events/onTokenTerminated.ts +20 -0
  210. package/src/client/events/tests/onSessionStateChange.test.ts +37 -0
  211. package/src/client/events/tests/onTokenTerminated.test.ts +37 -0
  212. package/src/client/tests/connectClient.test.ts +6 -1
  213. package/src/client/utils/setClientToken.ts +39 -0
  214. package/src/comment/api/deleteComment.ts +5 -5
  215. package/src/comment/api/getComment.ts +8 -3
  216. package/src/comment/events/tests/onCommentDeleted.test.ts +27 -0
  217. package/src/comment/observers/index.ts +1 -0
  218. package/src/comment/observers/liveComment.ts +43 -0
  219. package/src/comment/observers/tests/liveComment.test.ts +95 -0
  220. package/src/community/api/queryCommunities.ts +3 -10
  221. package/src/community/api/test/addCommunityMember.test.ts +14 -2
  222. package/src/community/api/test/joinCommunity.test.ts +14 -2
  223. package/src/community/api/test/leaveCommunity.test.ts +11 -1
  224. package/src/community/api/test/removeCommunityMembers.test.ts +11 -1
  225. package/src/community/events/index.ts +1 -0
  226. package/src/community/events/onCommunityUserChanged.ts +20 -0
  227. package/src/community/events/test/onCommunityJoined.test.ts +1 -1
  228. package/src/community/events/test/onCommunityUserAdded.test.ts +1 -1
  229. package/src/community/events/test/onCommunityUserBanned.test.ts +1 -1
  230. package/src/community/events/test/onCommunityUserUnbaned.test.ts +1 -1
  231. package/src/community/events/test/utils.test.ts +52 -3
  232. package/src/community/events/utils.ts +49 -0
  233. package/src/community/observers/index.ts +1 -0
  234. package/src/community/observers/liveCommunities.ts +188 -0
  235. package/src/community/observers/tests/liveCommunities.test.ts +284 -0
  236. package/src/core/events.ts +5 -3
  237. package/src/core/query/sorting.ts +8 -0
  238. package/src/core/subscription.ts +3 -1
  239. package/src/core/transports/http.ts +52 -13
  240. package/src/core/transports/mqtt.ts +1 -1
  241. package/src/core/transports/test/http.test.ts +49 -60
  242. package/src/external/api/createUserToken.ts +2 -2
  243. package/src/file/api/createFile.ts +1 -1
  244. package/src/file/api/createImage.ts +1 -1
  245. package/src/file/api/createVideo.ts +1 -1
  246. package/src/file/api/test/createImage.test.ts +69 -0
  247. package/src/file/api/test/createVideo.test.ts +81 -0
  248. package/src/index.ts +1 -0
  249. package/src/message/observers/liveMessage.ts +11 -83
  250. package/src/message/tests/observers/liveMessage.test.ts +1 -143
  251. package/src/post/observers/index.ts +1 -0
  252. package/src/post/observers/livePost.ts +47 -0
  253. package/src/post/observers/tests/livePost.test.ts +97 -0
  254. package/src/stream/api/tests/createStream.test.ts +22 -0
  255. package/src/stream/api/tests/deleteStream.test.ts +50 -0
  256. package/src/stream/api/tests/getStream.test.ts +23 -0
  257. package/src/subChannel/api/tests/createSubChannel.test.ts +110 -0
  258. package/src/subChannel/api/tests/deleteSubChannel.test.ts +112 -0
  259. package/src/subChannel/api/tests/getSubChannel.test.ts +97 -0
  260. package/src/subChannel/api/tests/getSubChannels.test.ts +97 -0
  261. package/src/subChannel/api/tests/updateSubChannel.test.ts +86 -0
  262. package/src/subChannel/observers/liveSubChannel.ts +6 -56
  263. package/src/subChannel/observers/tests/liveSubChannel.test.ts +0 -82
  264. package/src/user/api/tests/updateUser.test.ts +60 -0
  265. package/src/user/observers/liveUser.ts +9 -61
  266. package/src/user/tests/observers/liveUser.test.ts +1 -154
  267. package/src/utils/constants.ts +2 -0
  268. package/src/utils/liveObject.ts +86 -0
  269. package/src/utils/tests/client.ts +18 -2
  270. package/src/utils/tests/dummy/category.ts +57 -0
  271. package/src/utils/tests/dummy/channel.ts +51 -1
  272. package/src/utils/tests/dummy/community.ts +94 -0
  273. package/src/utils/tests/dummy/file.ts +32 -0
  274. package/src/utils/tests/dummy/index.ts +4 -0
  275. package/src/utils/tests/dummy/post.ts +56 -45
  276. package/src/utils/tests/dummy/stream.ts +86 -0
  277. package/src/utils/tests/dummy/token.ts +12 -0
  278. package/src/utils/tests/dummy/user.ts +21 -0
  279. 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';
@@ -1079,6 +1078,14 @@ const sortByDisplayName = ({ displayName: a }, { displayName: b }) => {
1079
1078
  return 0;
1080
1079
  return a < b ? -1 : 1;
1081
1080
  };
1081
+ /**
1082
+ * Alphabetic sorting of objects having a name
1083
+ */
1084
+ const sortByName = ({ name: a }, { name: b }) => {
1085
+ if (a === b)
1086
+ return 0;
1087
+ return a < b ? -1 : 1;
1088
+ };
1082
1089
  /**
1083
1090
  * Sorting a collection by their apparition order (oldest first)
1084
1091
  */
@@ -1125,6 +1132,9 @@ const WS_EVENTS = [
1125
1132
  'connect_error',
1126
1133
  'reconnect_error',
1127
1134
  'reconnect_failed',
1135
+ 'sessionStateChange',
1136
+ // for internal use by accessTokenExpiryWatcher
1137
+ 'tokenExpired',
1128
1138
  ];
1129
1139
  const MQTT_EVENTS = [
1130
1140
  'connect',
@@ -1134,6 +1144,7 @@ const MQTT_EVENTS = [
1134
1144
  'close',
1135
1145
  'end',
1136
1146
  'reconnect',
1147
+ 'user.didGlobalBan',
1137
1148
  ];
1138
1149
  /** @hidden */
1139
1150
  const createEventEmitter = () => {
@@ -1152,7 +1163,6 @@ const createEventEmitter = () => {
1152
1163
  const proxyWebsocketEvents = (ws, emitter) => {
1153
1164
  WS_EVENTS.forEach(event => {
1154
1165
  ws.on(event, (param) => {
1155
- console.log('ws', event, param);
1156
1166
  emitter.emit(event, param);
1157
1167
  });
1158
1168
  });
@@ -1160,14 +1170,12 @@ const proxyWebsocketEvents = (ws, emitter) => {
1160
1170
  const proxyMqttEvents = (mqttClient, emitter) => {
1161
1171
  MQTT_EVENTS.forEach(event => {
1162
1172
  mqttClient.on(event, (...params) => {
1163
- console.log('mqtt', event, params);
1164
1173
  emitter.emit(event, params.length === 1 ? params[0] : params);
1165
1174
  });
1166
1175
  });
1167
1176
  // @ts-ignore
1168
1177
  mqttClient.on('message', (topic, payload) => {
1169
1178
  const message = JSON.parse(payload.toString());
1170
- console.log('mqtt message', message);
1171
1179
  emitter.emit(message.eventType, message.data);
1172
1180
  });
1173
1181
  };
@@ -1310,7 +1318,9 @@ const getSmartFeedMessageTopic = () => {
1310
1318
  let mqttAccessToken;
1311
1319
  let mqttUserId;
1312
1320
  function subscribeTopic(topic, callback) {
1313
- const { mqtt, emitter, accessToken } = getActiveClient();
1321
+ var _a;
1322
+ const { mqtt, emitter, token } = getActiveClient();
1323
+ const accessToken = (_a = token === null || token === void 0 ? void 0 : token.accessToken) !== null && _a !== void 0 ? _a : '';
1314
1324
  const user = getActiveUser();
1315
1325
  if (mqttAccessToken !== accessToken || mqttUserId !== user._id) {
1316
1326
  mqttAccessToken = accessToken;
@@ -1379,13 +1389,6 @@ const unwrapPayload = (response) => {
1379
1389
  return undefined;
1380
1390
  };
1381
1391
 
1382
- /**
1383
- * Axios param serializer (for querystring)
1384
- * @hidden
1385
- */
1386
- const stringify = (params) => {
1387
- return qs.stringify(params, { arrayFormat: 'brackets' });
1388
- };
1389
1392
  /**
1390
1393
  * Creates a pre-configured axios instance
1391
1394
  *
@@ -1406,15 +1409,47 @@ const createHttpTransport = (endpoint) => {
1406
1409
  baseURL: endpoint,
1407
1410
  httpAgent: new HttpAgent(options),
1408
1411
  httpsAgent: new HttpsAgent(options),
1409
- paramsSerializer: stringify,
1412
+ /*
1413
+ * If paramSerializer is required, use the serialize option to stringify
1414
+ * params. The encode option will pass complex params as string only whereas
1415
+ * the serialize option will pass params in the format Record<string, any>
1416
+ *
1417
+ * For more details:
1418
+ * https://github.com/axios/axios#request-config
1419
+ */
1410
1420
  });
1411
- instance.interceptors.response.use(response => response, error => {
1421
+ instance.interceptors.request.use(config => {
1412
1422
  var _a;
1423
+ // check global.ts for the extension of AxiosRequestConfig
1424
+ const tokenExpiry = (_a = config.metadata) === null || _a === void 0 ? void 0 : _a.tokenExpiry;
1425
+ if (tokenExpiry) {
1426
+ if (Date.now() >= Date.parse(tokenExpiry)) {
1427
+ return Object.assign(Object.assign({}, config), { cancelToken: new axios.CancelToken(cancel => cancel('Token Expired')) });
1428
+ }
1429
+ }
1430
+ return config;
1431
+ });
1432
+ instance.interceptors.response.use(response => response, error => {
1433
+ var _a, _b;
1413
1434
  const { response } = error;
1414
- // eslint-disable-next-line no-console
1415
- console.error((_a = response === null || response === void 0 ? void 0 : response.data) !== null && _a !== void 0 ? _a : error);
1416
- if (response)
1417
- unwrapPayload(response.data);
1435
+ // handle unauthorized request
1436
+ if (response.data.code === 400100 /* Amity.ServerError.UNAUTHORIZED */) {
1437
+ fireEvent('tokenTerminated', "terminated" /* Amity.SessionStates.TERMINATED */);
1438
+ }
1439
+ // handle request cancellation
1440
+ if (axios.isCancel(error)) {
1441
+ fireEvent('tokenExpired', "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */);
1442
+ throw new ASCError('Token expired', 800403 /* Amity.ClientError.TOKEN_EXPIRED */, "fatal" /* Amity.ErrorLevel.FATAL */);
1443
+ }
1444
+ // if it's an error with status in the response payload,
1445
+ // then it's an expected error.
1446
+ if ((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.status) {
1447
+ unwrapPayload(response === null || response === void 0 ? void 0 : response.data);
1448
+ }
1449
+ // unexpected error.
1450
+ else {
1451
+ throw new Error((_b = response === null || response === void 0 ? void 0 : response.data) !== null && _b !== void 0 ? _b : error);
1452
+ }
1418
1453
  });
1419
1454
  return instance;
1420
1455
  };
@@ -20148,7 +20183,7 @@ var MqttError;
20148
20183
  MqttError[MqttError["NOT_AUTHORIZED"] = 5] = "NOT_AUTHORIZED";
20149
20184
  })(MqttError || (MqttError = {}));
20150
20185
  function getMqttOptions(params) {
20151
- return Object.assign({ clean: false, clientId: `mqttjs_ + ${Math.random().toString(16).substr(2, 8)}`, protocolId: 'MQTT', protocolVersion: 4, reconnectPeriod: 0, will: {
20186
+ return Object.assign({ clean: false, clientId: `mqttjs_ + ${Math.random().toString(16).substring(2, 10)}`, protocolId: 'MQTT', protocolVersion: 4, reconnectPeriod: 0, will: {
20152
20187
  topic: 'WillMsg',
20153
20188
  payload: 'Connection Closed abnormally..!',
20154
20189
  qos: 0,
@@ -20279,54 +20314,153 @@ const getFeedSettings = async () => {
20279
20314
  }));
20280
20315
  };
20281
20316
 
20282
- const DEFAULT_DEBUG_SESSION = 'amity';
20317
+ const COLLECTION_DEFAULT_PAGINATION_LIMIT = 5;
20318
+ const COLLECTION_DEFAULT_CACHING_POLICY = 'cache_then_server';
20319
+ const ENABLE_CACHE_MESSAGE = 'For using Live Collection feature you need to enable Cache!';
20320
+ const LIVE_OBJECT_ENABLE_CACHE_MESSAGE = 'For using Live Object feature you need to enable Cache!';
20321
+ const UNSYNCED_OBJECT_CACHED_AT_MESSAGE = 'Observing unsynced object is not supported by Live Object.';
20322
+ const UNSYNCED_OBJECT_CACHED_AT_VALUE = -5;
20323
+ const MINUTE = 60 * 1000;
20324
+ const ACCESS_TOKEN_WATCHER_INTERVAL = 10 * MINUTE;
20325
+
20326
+ // TODO: find a way to uniquely identify the device
20327
+ /** @hidden */
20328
+ const VERSION = '11.0.0';
20329
+ /** @hidden */
20330
+ const getDeviceId = () => {
20331
+ // here maybe put some auto detection of the device id based on if it's react or not?
20332
+ // anyhow we let consumer branch out if they want, but it doesn't mean we shouldn't try to be nice
20333
+ // and do things automatically
20334
+ // https://www.npmjs.com/package/react-native-device-info#getuniqueid
20335
+ // how to make sure that the react native package will not be included when build is for web
20336
+ return `ascWebSdk#${Math.random().toString(16)}`;
20337
+ };
20338
+ /** @hidden */
20339
+ const getDeviceModel = () => {
20340
+ var _a, _b;
20341
+ if ((_a = safeProcess.versions) === null || _a === void 0 ? void 0 : _a.node)
20342
+ return safeProcess.versions.node;
20343
+ if (navigator)
20344
+ return `${navigator.product.toLowerCase()}#${(_b = navigator.userAgent) !== null && _b !== void 0 ? _b : 'unknown_agent'}`;
20345
+ return 'unknown_model';
20346
+ };
20347
+ /** @hidden */
20348
+ const getDeviceInfo = () => {
20349
+ const model = getDeviceModel();
20350
+ return {
20351
+ version: VERSION,
20352
+ // TODO: replace with: kind: process.versions ? 'node' : 'web', when backend has fixed this
20353
+ kind: 'web',
20354
+ model,
20355
+ };
20356
+ };
20357
+
20358
+ /*
20359
+ * Session States cannot be set arbitarily.
20360
+ * These are the possible new states based on the current state
20361
+ * Check tech spec for details:
20362
+ * https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Session-State
20363
+ */
20364
+ const sessisonStateTransitions = {
20365
+ // notLoggedIn -> establishing
20366
+ ["notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */]: ["establishing" /* Amity.SessionStates.ESTABLISHING */],
20367
+ // terminated -> establishing
20368
+ ["terminated" /* Amity.SessionStates.TERMINATED */]: ["establishing" /* Amity.SessionStates.ESTABLISHING */],
20369
+ // establishing -> notLoggedIn, established
20370
+ ["establishing" /* Amity.SessionStates.ESTABLISHING */]: [
20371
+ "notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */,
20372
+ "established" /* Amity.SessionStates.ESTABLISHED */,
20373
+ ],
20374
+ /*
20375
+ * established -> notLoggedIn, terminated, tokenExpired, establishing (for
20376
+ * cases when logging in same user)
20377
+ */
20378
+ ["established" /* Amity.SessionStates.ESTABLISHED */]: [
20379
+ "notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */,
20380
+ "terminated" /* Amity.SessionStates.TERMINATED */,
20381
+ "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */,
20382
+ "establishing" /* Amity.SessionStates.ESTABLISHING */,
20383
+ ],
20384
+ // tokenExpired -> establishing
20385
+ ["tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */]: ["establishing" /* Amity.SessionStates.ESTABLISHING */],
20386
+ };
20387
+ const isValidStateChange = (prevState, nextState) => {
20388
+ return sessisonStateTransitions[prevState].includes(nextState);
20389
+ };
20283
20390
  /**
20284
- * ```js
20285
- * import { createClient } from '@amityco/ts-sdk'
20286
- * const client = createClient(apiKey, 'https://asc.server/', 'myClient')
20287
- * ```
20391
+ * Checks if a {@link Amity.Client} instance is connected to ASC servers
20288
20392
  *
20289
- * Creates a new {@link Amity.Client} instance
20290
20393
  *
20291
- * @param apiKey for the {@link Amity.Client} instance
20292
- * @param apiRegion endpoint to connect to
20293
- * @param apiEndpoint custom endpoint in case you don't want to use a preset endpoint
20294
- * @param debugSession session's identifier for the client's logger instance
20295
- * @returns A {@link Amity.Client} instance
20394
+ * @param state the new session state
20395
+ * @returns a success boolean if connected
20396
+ *
20397
+ * @category private
20398
+ */
20399
+ const setSessionState = (state) => {
20400
+ const client = getActiveClient();
20401
+ client.log('client/api/setSessionState', state);
20402
+ const { sessionState: prevState } = client;
20403
+ if (prevState === state)
20404
+ return false;
20405
+ // check if transition is valid
20406
+ if (!isValidStateChange(prevState, state)) {
20407
+ throw new ASCError(`Session state cannot change from ${prevState} to ${state}`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
20408
+ }
20409
+ client.sessionState = state;
20410
+ fireEvent('sessionStateChange', state);
20411
+ return true;
20412
+ };
20413
+
20414
+ /**
20415
+ * Retrieves a pair of {@link Amity.Tokens} necessary for connection
20416
+ *
20417
+ * @param params.userId The userId to use to issue a token
20418
+ * @param params.displayName The user's displayName
20419
+ * @param params.deviceId The user's device Id (can be manually set for native users)
20420
+ * @param params.authToken The authentication token - necessary when network option is set to secure
20421
+ * @return The accessToken for the given userId
20296
20422
  *
20297
20423
  * @category Client API
20298
- * */
20299
- const createClient = (apiKey, apiRegion = API_REGIONS.SG, { debugSession = DEFAULT_DEBUG_SESSION, apiEndpoint, } = {}) => {
20300
- var _a, _b;
20301
- const log = createLogger(debugSession);
20302
- log('client/api/createClient', {
20303
- apiKey: apiKey.replace(/.{5}$/g, 'xxxxx'),
20304
- apiRegion,
20424
+ * @hidden
20425
+ */
20426
+ const getToken = async (params) => {
20427
+ const client = getActiveClient();
20428
+ client.log('client/api/getToken', params);
20429
+ const deviceInfo = getDeviceInfo();
20430
+ const { data } = await client.http.post('/api/v3/sessions', Object.assign(Object.assign({}, params), { deviceInfo }), {
20431
+ // @ts-ignore
20432
+ headers: { 'X-API-Key': client.apiKey },
20305
20433
  });
20306
- const httpEndpoint = (_a = apiEndpoint === null || apiEndpoint === void 0 ? void 0 : apiEndpoint.http) !== null && _a !== void 0 ? _a : computeUrl('http', apiRegion);
20307
- const mqttEndpoint = (_b = apiEndpoint === null || apiEndpoint === void 0 ? void 0 : apiEndpoint.mqtt) !== null && _b !== void 0 ? _b : computeUrl('mqtt', apiRegion);
20308
- const http = createHttpTransport(httpEndpoint);
20309
- const ws = createWebsocketTransport(httpEndpoint);
20310
- const mqtt = createMqttTransport(mqttEndpoint);
20311
- const emitter = createEventEmitter();
20312
- const client = {
20313
- version: `${VERSION$1}`,
20314
- apiKey,
20315
- log,
20316
- http,
20317
- ws,
20318
- mqtt,
20319
- emitter,
20320
- use: () => setActiveClient(client),
20321
- getFeedSettings,
20322
- };
20323
- try {
20324
- return getActiveClient();
20325
- }
20326
- catch (_c) {
20327
- setActiveClient(client);
20328
- }
20329
- return client;
20434
+ return data;
20435
+ };
20436
+
20437
+ /**
20438
+ * A util to set or refresh client token
20439
+ *
20440
+ * @param params.userId the user ID for the current session
20441
+ * @param params.displayName the user's displayName for the current session
20442
+ * @param params.deviceId Manual override of the user's device id (for device management)
20443
+ * @param params.authToken The authentication token - necessary when network option is set to secure
20444
+ * @returns token & user info
20445
+ *
20446
+ * @category private
20447
+ * @async
20448
+ */
20449
+ const setClientToken = async (params) => {
20450
+ const client = getActiveClient();
20451
+ // begin establishing session
20452
+ setSessionState("establishing" /* Amity.SessionStates.ESTABLISHING */);
20453
+ // @ts-ignore: in that particular case, typing can be
20454
+ // ignored since we enforce default values just before.
20455
+ const { accessToken, users, expiresAt, issuedAt, refreshToken } = await getToken(params);
20456
+ // manually setup the token for http transport
20457
+ client.http.defaults.headers.common.Authorization = `Bearer ${accessToken}`;
20458
+ client.http.defaults.metadata = { tokenExpiry: expiresAt };
20459
+ // manually setup the token for ws transport
20460
+ client.ws.io.opts.query = { token: accessToken };
20461
+ client.token = { accessToken, issuedAt, expiresAt };
20462
+ setSessionState("established" /* Amity.SessionStates.ESTABLISHED */);
20463
+ return { accessToken, users, refreshToken };
20330
20464
  };
20331
20465
 
20332
20466
  /**
@@ -20337,7 +20471,6 @@ const createClient = (apiKey, apiRegion = API_REGIONS.SG, { debugSession = DEFAU
20337
20471
  *
20338
20472
  * Disconnects an {@link Amity.Client} instance from ASC servers
20339
20473
  *
20340
- * @param client The {@link Amity.Client} instance to disconnect
20341
20474
  * @returns a success boolean if disconnected
20342
20475
  *
20343
20476
  * @category Client API
@@ -20356,42 +20489,30 @@ const disconnectClient = async () => {
20356
20489
  client.ws.removeAllListeners();
20357
20490
  client.mqtt.removeAllListeners();
20358
20491
  client.userId = undefined;
20359
- client.accessToken = undefined;
20492
+ client.token = undefined;
20493
+ client.http.defaults.headers.common.Authorization = '';
20494
+ client.ws.io.opts.query = { token: '' };
20495
+ /*
20496
+ * for cases when session state is terminated (example on ban) or token expired,
20497
+ * the terminating block will set session state to terminated or for the or
20498
+ * in the case of expired token the same happens
20499
+ *
20500
+ * establishing state also ignored in cases where accessTokenExpiryWatcher
20501
+ * calls renewal. There is a possibility that renewal will be called before
20502
+ * disconnectClient finishes execution
20503
+ */
20504
+ if (client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */)
20505
+ setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
20506
+ /*
20507
+ * Cache should be usable if tokenExpired
20508
+ * https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#SDK-usability-based-on-Session-State
20509
+ */
20510
+ if (client.sessionState !== "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.cache) {
20511
+ client.cache = { data: {} };
20512
+ }
20360
20513
  return !client.ws.connected;
20361
20514
  };
20362
20515
 
20363
- // TODO: find a way to uniquely identify the device
20364
- /** @hidden */
20365
- const VERSION = '11.0.0';
20366
- /** @hidden */
20367
- const getDeviceId = () => {
20368
- // here maybe put some auto detection of the device id based on if it's react or not?
20369
- // anyhow we let consumer branch out if they want, but it doesn't mean we shouldn't try to be nice
20370
- // and do things automatically
20371
- // https://www.npmjs.com/package/react-native-device-info#getuniqueid
20372
- // how to make sure that the react native package will not be included when build is for web
20373
- return `ascWebSdk#${Math.random().toString(16)}`;
20374
- };
20375
- /** @hidden */
20376
- const getDeviceModel = () => {
20377
- var _a, _b;
20378
- if ((_a = safeProcess.versions) === null || _a === void 0 ? void 0 : _a.node)
20379
- return safeProcess.versions.node;
20380
- if (navigator)
20381
- return `${navigator.product.toLowerCase()}#${(_b = navigator.userAgent) !== null && _b !== void 0 ? _b : 'unknown_agent'}`;
20382
- return 'unknown_model';
20383
- };
20384
- /** @hidden */
20385
- const getDeviceInfo = () => {
20386
- const model = getDeviceModel();
20387
- return {
20388
- version: VERSION,
20389
- // TODO: replace with: kind: process.versions ? 'node' : 'web', when backend has fixed this
20390
- kind: 'web',
20391
- model,
20392
- };
20393
- };
20394
-
20395
20516
  /**
20396
20517
  * Ingest a payload (v3) into the cache
20397
20518
  *
@@ -20443,26 +20564,17 @@ const createUserEventSubscriber = (event, callback) => {
20443
20564
  const onUserDeleted = (callback) => createUserEventSubscriber('user.deleted', callback);
20444
20565
 
20445
20566
  /**
20446
- * Retrieves a pair of {@link Amity.Tokens} necessary for connection
20567
+ * Terminates {@link Amity.Client} instance
20447
20568
  *
20448
- * @param userId The userId to use to issue a token
20449
- * @param displayName The user's displayName
20450
- * @param deviceId The user's device Id (can be manually set for native users)
20451
- * @param authToken The authentication token - necessary when network option is set to secure
20452
- * @return The accessToken for the given userId
20453
20569
  *
20454
- * @category Client API
20455
- * @hidden
20570
+ *
20571
+ * @category private
20456
20572
  */
20457
- const getToken = async (params) => {
20573
+ const terminateClient = () => {
20458
20574
  const client = getActiveClient();
20459
- client.log('client/api/getToken', params);
20460
- const deviceInfo = await getDeviceInfo();
20461
- const { data } = await client.http.post('/v1/device', Object.assign(Object.assign({}, params), { deviceInfo }), {
20462
- // @ts-ignore
20463
- headers: { 'X-API-Key': client.apiKey },
20464
- });
20465
- return data;
20575
+ setSessionState("terminated" /* Amity.SessionStates.TERMINATED */);
20576
+ client.sessionHandler = undefined;
20577
+ disconnectClient();
20466
20578
  };
20467
20579
 
20468
20580
  const EVENTS = [
@@ -20537,12 +20649,71 @@ const onClientDisconnected = (callback) => {
20537
20649
  * @category Client Events
20538
20650
  */
20539
20651
  const onClientBanned = (callback) => {
20540
- return onConnectionError(({ code }) => {
20541
- code === 400312 /* Amity.ServerError.GLOBAL_BAN */ && callback();
20542
- });
20652
+ const client = getActiveClient();
20653
+ return createEventSubscriber(client, `client/onConnectionError(user.didGlobalBan)`, 'user.didGlobalBan', callback);
20654
+ };
20655
+
20656
+ /**
20657
+ * ```js
20658
+ * import { onSessionStateChange } from '@amityco/ts-sdk'
20659
+ * const dispose = onSessionStateChange((state: Amity.SessionStates) => {
20660
+ * // ...
20661
+ * })
20662
+ * ```
20663
+ *
20664
+ * Fired when any {@link Amity.Client} has a session state change
20665
+ *
20666
+ * @param callback The function to call when the event was fired
20667
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
20668
+ *
20669
+ * @category Client Events
20670
+ */
20671
+ const onSessionStateChange = (callback) => {
20672
+ const client = getActiveClient();
20673
+ return createEventSubscriber(client, `client/onSessionStateChange`, 'sessionStateChange', callback);
20674
+ };
20675
+
20676
+ /**
20677
+ * ```js
20678
+ * import { onTokenExpired } from '@amityco/ts-sdk'
20679
+ * const dispose = onTokenExpired((state: Amity.SessionStates.TOKEN_EXPIRED) => {
20680
+ * // ...
20681
+ * })
20682
+ * ```
20683
+ *
20684
+ * Fired when any {@link Amity.Client} session state has expired
20685
+ *
20686
+ * @param callback The function to call when the event was fired
20687
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
20688
+ *
20689
+ * @category private
20690
+ */
20691
+ const onTokenExpired = (callback) => {
20692
+ const client = getActiveClient();
20693
+ return createEventSubscriber(client, `client/onTokenExpired`, 'tokenExpired', callback);
20694
+ };
20695
+
20696
+ /**
20697
+ *
20698
+ * Fired when any {@link Amity.Client} session state has terminated
20699
+ *
20700
+ * @param callback The function to call when the event was fired
20701
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
20702
+ *
20703
+ * @category private
20704
+ */
20705
+ const onTokenTerminated = (callback) => {
20706
+ const client = getActiveClient();
20707
+ return createEventSubscriber(client, `client/onTokenTerminated`, 'tokenTerminated', callback);
20543
20708
  };
20544
20709
 
20545
20710
  /* eslint-disable no-param-reassign */
20711
+ /*
20712
+ * declared earlier to accomodate case when logging in with a different user
20713
+ * than the one already connected, in which case the existing subscriptions need
20714
+ * to be cleared
20715
+ */
20716
+ const subscriptions = [];
20546
20717
  /**
20547
20718
  * ```js
20548
20719
  * import { connectClient } from '@amityco/ts-sdk/client/api'
@@ -20563,46 +20734,259 @@ const onClientBanned = (callback) => {
20563
20734
  * @category Client API
20564
20735
  * @async
20565
20736
  */
20566
- const connectClient = async (params, config) => {
20567
- var _a;
20737
+ const connectClient = async (params, sessionHandler, config) => {
20738
+ var _a, _b, _c;
20568
20739
  const client = getActiveClient();
20569
- client.log('client/api/connectClient', Object.assign({ apiKey: client.apiKey }, params));
20740
+ let unsubWatcher;
20741
+ client.log('client/api/connectClient', Object.assign({ apiKey: client.apiKey, sessionState: client.sessionState }, params));
20742
+ // if connecting to a different userId than the one that is connected currently
20743
+ if (client.userId && client.userId !== params.userId) {
20744
+ await disconnectClient();
20745
+ // Remove subscription to ban and delete
20746
+ subscriptions.forEach(fn => fn());
20747
+ }
20570
20748
  // default values
20571
20749
  (_a = params.deviceId) !== null && _a !== void 0 ? _a : (params.deviceId = getDeviceId());
20572
- // @ts-ignore: in that particular case, typing can be
20573
- // ignored since we enforce default values just before.
20574
- const { accessToken, users } = await getToken(params);
20575
- // manually setup the token for http, ws transport
20576
- client.http.defaults.headers.common.Authorization = `Bearer ${accessToken}`;
20577
- client.ws.io.opts.query = { token: accessToken };
20578
- // FIXME: events are duplicated if connectClient is called few times without disconnectClient
20579
- // wire websocket events to our event emitter
20580
- proxyWebsocketEvents(client.ws, client.emitter);
20581
- // TODO: in phase 2, this should not be necessary. we should have WS
20582
- // to be connected "on demand" rather than "by default"
20583
- await new Promise(resolve => {
20584
- client.ws.once('connect', resolve);
20585
- client.ws.open();
20586
- });
20587
- client.userId = params.userId;
20588
- client.accessToken = accessToken;
20589
- setActiveUser(users[0]);
20590
- if ((config === null || config === void 0 ? void 0 : config.disableRTE) !== true) {
20591
- subscribeTopic(getNetworkTopic());
20592
- subscribeTopic(getSmartFeedChannelTopic());
20593
- subscribeTopic(getSmartFeedSubChannelTopic());
20750
+ try {
20751
+ // @ts-ignore: in that particular case, typing can be
20752
+ // ignored since we enforce default values just before.
20753
+ const { users } = await setClientToken(params);
20754
+ // FIXME: events are duplicated if connectClient is called few times without disconnectClient
20755
+ // wire websocket events to our event emitter
20756
+ proxyWebsocketEvents(client.ws, client.emitter);
20757
+ // TODO: in phase 2, this should not be necessary. we should have WS
20758
+ // to be connected "on demand" rather than "by default"
20759
+ await new Promise(resolve => {
20760
+ client.ws.once('connect', resolve);
20761
+ client.ws.open();
20762
+ });
20763
+ client.userId = params.userId;
20764
+ client.sessionHandler = sessionHandler;
20765
+ /*
20766
+ * Cannot push to subscriptions as watcher needs to continue working even if
20767
+ * token expires
20768
+ */
20769
+ unsubWatcher = client.accessTokenExpiryWatcher((_b = client.token) === null || _b === void 0 ? void 0 : _b.issuedAt, (_c = client.token) === null || _c === void 0 ? void 0 : _c.expiresAt, sessionHandler);
20770
+ setActiveUser(users[0]);
20771
+ }
20772
+ catch (error) {
20773
+ /*
20774
+ * if getting token failed session state reverts to initial state when app
20775
+ * is first launched
20776
+ */
20777
+ setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
20778
+ // pass error down tree so the calling function handle it
20779
+ throw error;
20780
+ }
20781
+ if ((config === null || config === void 0 ? void 0 : config.disableRTE) !== true) {
20782
+ subscribeTopic(getNetworkTopic());
20783
+ subscribeTopic(getSmartFeedChannelTopic());
20784
+ subscribeTopic(getSmartFeedSubChannelTopic());
20594
20785
  subscribeTopic(getSmartFeedMessageTopic());
20786
+ // subscribing to user topic is necessary to handle ban event
20787
+ subscribeTopic(getUserTopic(getActiveUser()));
20595
20788
  }
20596
- const subscriptions = [
20597
- onClientBanned(() => {
20598
- disconnectClient();
20789
+ subscriptions.push(
20790
+ // GLOBAL_BAN
20791
+ onClientBanned((_) => {
20792
+ terminateClient();
20793
+ subscriptions.forEach(fn => fn());
20794
+ unsubWatcher();
20795
+ }), onTokenTerminated(_ => {
20796
+ terminateClient();
20797
+ subscriptions.forEach(fn => fn());
20798
+ unsubWatcher();
20799
+ }), onUserDeleted((user) => {
20800
+ if (user.userId === client.userId) {
20801
+ terminateClient();
20599
20802
  subscriptions.forEach(fn => fn());
20600
- }),
20601
- onUserDeleted(() => null),
20602
- ];
20803
+ unsubWatcher();
20804
+ }
20805
+ }), onTokenExpired(state => {
20806
+ setSessionState(state);
20807
+ disconnectClient();
20808
+ subscriptions.forEach(fn => fn());
20809
+ }), onUserDeleted(() => null));
20603
20810
  return client.ws.connected;
20604
20811
  };
20605
20812
 
20813
+ /*
20814
+ * Renewal defintion accepted by SessionHandler interface
20815
+ *
20816
+ * Tech Spec:
20817
+ * https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Session-Handler
20818
+ *
20819
+ * @category private
20820
+ */
20821
+ const renewal = () => {
20822
+ let tokenRenewed = false;
20823
+ let renewTimeoutId;
20824
+ const client = getActiveClient();
20825
+ client.log('initiating access token renewal');
20826
+ /*
20827
+ * Renews a token if it is hasn't been renewed before. Also marks token as
20828
+ * renewed once done
20829
+ * Per instance of Renewal, only one renewal is allowed
20830
+ */
20831
+ const renewToken = async (authToken) => {
20832
+ const { userId, displayName } = getActiveUser();
20833
+ const deviceId = getDeviceId();
20834
+ const params = { userId, displayName, authToken, deviceId };
20835
+ if (client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */) {
20836
+ // sessionHandler will never be empty when renewal is instantiatied
20837
+ await connectClient(params, client.sessionHandler);
20838
+ }
20839
+ else {
20840
+ // about to expire
20841
+ // @ts-ignore: in that particular case, typing can be
20842
+ // ignored since we enforce default values just before.
20843
+ await setClientToken(params);
20844
+ }
20845
+ tokenRenewed = true;
20846
+ if (renewTimeoutId)
20847
+ clearTimeout(renewTimeoutId);
20848
+ };
20849
+ return {
20850
+ renew: () => {
20851
+ if (tokenRenewed) {
20852
+ console.log("'renew' method can be called only once per renewal instance");
20853
+ return;
20854
+ }
20855
+ renewToken();
20856
+ },
20857
+ renewWithAuthToken: (authToken) => {
20858
+ if (tokenRenewed) {
20859
+ console.log("'renewWithAuthToken' method can be called only once per renewal instance");
20860
+ return;
20861
+ }
20862
+ renewToken(authToken);
20863
+ },
20864
+ unableToRetrieveAuthToken: () => {
20865
+ renewTimeoutId = setTimeout(() => {
20866
+ var _a;
20867
+ (_a = client.sessionHandler) === null || _a === void 0 ? void 0 : _a.sessionWillRenewAccessToken(renewal());
20868
+ }, ACCESS_TOKEN_WATCHER_INTERVAL);
20869
+ },
20870
+ };
20871
+ };
20872
+
20873
+ const ABOUT_TO_EXPIRE_THRESHOLD = 80 / 100;
20874
+ const COMPENSATED_DELAY = 5 * MINUTE;
20875
+ /*
20876
+ * a helper function to check if the token has expires
20877
+ *
20878
+ * @param token to be checked
20879
+ * @returns boolean indicating if token expires
20880
+ *
20881
+ * @category private
20882
+ */
20883
+ const isExpired = (expiresAt) => Date.now() > Date.parse(expiresAt) - COMPENSATED_DELAY;
20884
+ /*
20885
+ * a helper function to check if the token is about to expire
20886
+ *
20887
+ * @param token to be checked
20888
+ * @returns boolean indicating if token is aboutToExpire
20889
+ *
20890
+ * @category private
20891
+ */
20892
+ const isAboutToExpire = (params) => {
20893
+ const { expiresAt, issuedAt } = params;
20894
+ const expires = Date.parse(expiresAt);
20895
+ const issued = Date.parse(issuedAt);
20896
+ const now = Date.now();
20897
+ const duration = expires - issued - COMPENSATED_DELAY;
20898
+ const aboutToExpireAt = issued + duration * ABOUT_TO_EXPIRE_THRESHOLD;
20899
+ return now > aboutToExpireAt && now < expires;
20900
+ };
20901
+ /*
20902
+ * Monitors time to expire of token and updates session state to aboutToExpire
20903
+ *
20904
+ * @returns intervalId to be cleared after trigger
20905
+ *
20906
+ * @category private
20907
+ */
20908
+ const accessTokenExpiryWatcher = (expiresAt, issuedAt, sessionHandler) => {
20909
+ const interval = setInterval(() => {
20910
+ if (isExpired(expiresAt)) {
20911
+ /*
20912
+ * the event handler will take care of updating session state
20913
+ * Note, this will also clear the interval id, so this event will only be
20914
+ * fired once
20915
+ */
20916
+ fireEvent('tokenExpired', "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */);
20917
+ /*
20918
+ * https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Automatically-initiate-renewal-flow
20919
+ *
20920
+ * Why sechduled task?
20921
+ * Since fireEvent is scheduled, it will be called
20922
+ * after sessionHandler leading to an invalid state change from
20923
+ * establishing to tokenExpired
20924
+ */
20925
+ scheduleTask(() => sessionHandler.sessionWillRenewAccessToken(renewal()));
20926
+ return;
20927
+ }
20928
+ if (isAboutToExpire({ expiresAt, issuedAt })) {
20929
+ sessionHandler.sessionWillRenewAccessToken(renewal());
20930
+ }
20931
+ }, ACCESS_TOKEN_WATCHER_INTERVAL);
20932
+ return () => clearInterval(interval);
20933
+ };
20934
+
20935
+ const DEFAULT_DEBUG_SESSION = 'amity';
20936
+ /**
20937
+ * ```js
20938
+ * import { createClient } from '@amityco/ts-sdk'
20939
+ * const client = createClient(apiKey, 'https://asc.server/', 'myClient')
20940
+ * ```
20941
+ *
20942
+ * Creates a new {@link Amity.Client} instance
20943
+ *
20944
+ * @param apiKey for the {@link Amity.Client} instance
20945
+ * @param apiRegion endpoint to connect to
20946
+ * @param apiEndpoint custom endpoint in case you don't want to use a preset endpoint
20947
+ * @param param.debugSession session's identifier for the client's logger instance
20948
+ * @returns A {@link Amity.Client} instance
20949
+ *
20950
+ * @category Client API
20951
+ * */
20952
+ const createClient = (apiKey, apiRegion = API_REGIONS.SG, { debugSession = DEFAULT_DEBUG_SESSION, apiEndpoint, } = {}) => {
20953
+ var _a, _b;
20954
+ const log = createLogger(debugSession);
20955
+ log('client/api/createClient', {
20956
+ apiKey: apiKey.replace(/.{5}$/g, 'xxxxx'),
20957
+ apiRegion,
20958
+ });
20959
+ const httpEndpoint = (_a = apiEndpoint === null || apiEndpoint === void 0 ? void 0 : apiEndpoint.http) !== null && _a !== void 0 ? _a : computeUrl('http', apiRegion);
20960
+ const mqttEndpoint = (_b = apiEndpoint === null || apiEndpoint === void 0 ? void 0 : apiEndpoint.mqtt) !== null && _b !== void 0 ? _b : computeUrl('mqtt', apiRegion);
20961
+ const http = createHttpTransport(httpEndpoint);
20962
+ const ws = createWebsocketTransport(httpEndpoint);
20963
+ const mqtt = createMqttTransport(mqttEndpoint);
20964
+ const emitter = createEventEmitter();
20965
+ const sessionState = "notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */;
20966
+ const sessionHandler = undefined;
20967
+ const client = {
20968
+ version: `${VERSION$1}`,
20969
+ apiKey,
20970
+ log,
20971
+ http,
20972
+ ws,
20973
+ mqtt,
20974
+ emitter,
20975
+ accessTokenExpiryWatcher,
20976
+ use: () => setActiveClient(client),
20977
+ sessionState,
20978
+ sessionHandler,
20979
+ getFeedSettings,
20980
+ };
20981
+ try {
20982
+ return getActiveClient();
20983
+ }
20984
+ catch (_c) {
20985
+ setActiveClient(client);
20986
+ }
20987
+ return client;
20988
+ };
20989
+
20606
20990
  /**
20607
20991
  * ```js
20608
20992
  * import { isConnected } from '@amityco/ts-sdk'
@@ -21012,12 +21396,57 @@ const onUserUnflagged = (callback) => createUserEventSubscriber('user.unflagged'
21012
21396
  */
21013
21397
  const onUserFlagCleared = (callback) => createUserEventSubscriber('user.flagCleared', callback);
21014
21398
 
21015
- const COLLECTION_DEFAULT_PAGINATION_LIMIT = 5;
21016
- const COLLECTION_DEFAULT_CACHING_POLICY = 'cache_then_server';
21017
- const ENABLE_CACHE_MESSAGE = 'For using Live Collection feature you need to enable Cache!';
21018
- const LIVE_OBJECT_ENABLE_CACHE_MESSAGE = 'For using Live Object feature you need to enable Cache!';
21019
- const UNSYNCED_OBJECT_CACHED_AT_MESSAGE = 'Observing unsynced object is not supported by Live Object.';
21020
- const UNSYNCED_OBJECT_CACHED_AT_VALUE = -5;
21399
+ const liveObject = (id, callback, key, fetcher, eventHandlers) => {
21400
+ const { cache } = getActiveClient();
21401
+ if (!cache) {
21402
+ console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
21403
+ }
21404
+ let model;
21405
+ let isUnsyncedModel = false; // for messages
21406
+ const disposers = [];
21407
+ const dispatcher = (data) => {
21408
+ model = data.data;
21409
+ callback(data);
21410
+ };
21411
+ const realtimeRouter = (eventModel) => {
21412
+ if (id !== eventModel[key]) {
21413
+ return;
21414
+ }
21415
+ if (model && !hasUpdates(model, eventModel)) {
21416
+ return;
21417
+ }
21418
+ dispatcher({ loading: false, data: eventModel, origin: 'event' });
21419
+ };
21420
+ const onFetch = () => {
21421
+ // @ts-ignore
21422
+ const query = createQuery(fetcher, id, true);
21423
+ runQuery(query, ({ error, data, loading, origin, cachedAt }) => {
21424
+ if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
21425
+ dispatcher({
21426
+ // @ts-ignore
21427
+ data,
21428
+ origin,
21429
+ loading: false,
21430
+ error: new ASCApiError(UNSYNCED_OBJECT_CACHED_AT_MESSAGE, 800800 /* Amity.ClientError.DISALOOW_UNSYNCED_OBJECT */, "error" /* Amity.ErrorLevel.ERROR */),
21431
+ });
21432
+ isUnsyncedModel = true;
21433
+ disposers.forEach(fn => fn());
21434
+ }
21435
+ else if (!isUnsyncedModel) {
21436
+ // @ts-ignore
21437
+ dispatcher({ loading, data, origin, error });
21438
+ }
21439
+ if (error) {
21440
+ disposers.forEach(fn => fn());
21441
+ }
21442
+ });
21443
+ };
21444
+ disposers.push(...eventHandlers.map(fn => fn(realtimeRouter)));
21445
+ onFetch();
21446
+ return () => {
21447
+ disposers.forEach(fn => fn());
21448
+ };
21449
+ };
21021
21450
 
21022
21451
  /**
21023
21452
  * ```js
@@ -21056,42 +21485,14 @@ const onUserFetched = (callback) => createUserEventSubscriber('user.fetched', ca
21056
21485
  * @category Message Live Object
21057
21486
  */
21058
21487
  const liveUser = (userId, callback) => {
21059
- const { log, cache } = getActiveClient();
21060
- const timestamp = Date.now();
21061
- log(`liveUser(tmpid: ${timestamp}) > listen`);
21062
- if (!cache) {
21063
- console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
21064
- }
21065
- let user;
21066
- const disposers = [];
21067
- const dispatcher = (data) => {
21068
- user = data.data;
21069
- callback(data);
21070
- };
21071
- const realtimeRouter = (eventUser) => {
21072
- if (userId !== eventUser.userId) {
21073
- return;
21074
- }
21075
- if (user && !hasUpdates(user, eventUser)) {
21076
- return;
21077
- }
21078
- dispatcher({ loading: false, data: eventUser, origin: 'event' });
21079
- };
21080
- const onFetch = () => {
21081
- const query = createQuery(getUser, userId, true);
21082
- runQuery(query, ({ loading, data, error, origin }) => {
21083
- dispatcher({ loading, data, origin, error });
21084
- if (error) {
21085
- disposers.forEach(fn => fn());
21086
- }
21087
- });
21088
- };
21089
- disposers.push(onUserFetched(realtimeRouter), onUserUpdated(realtimeRouter), onUserDeleted(realtimeRouter), onUserFlagged(realtimeRouter), onUserUnflagged(realtimeRouter), onUserFlagCleared(realtimeRouter));
21090
- onFetch();
21091
- return () => {
21092
- log(`liveUser(tmpid: ${timestamp}) > dispose`);
21093
- disposers.forEach(fn => fn());
21094
- };
21488
+ return liveObject(userId, callback, 'userId', getUser, [
21489
+ onUserFetched,
21490
+ onUserUpdated,
21491
+ onUserDeleted,
21492
+ onUserFlagged,
21493
+ onUserUnflagged,
21494
+ onUserFlagCleared,
21495
+ ]);
21095
21496
  };
21096
21497
 
21097
21498
  /**
@@ -21215,7 +21616,7 @@ const createFile = async (formData, onProgress) => {
21215
21616
  : { 'content-type': 'multipart/form-data' };
21216
21617
  const { data } = await client.http.post('/api/v4/files', formData, {
21217
21618
  headers,
21218
- onUploadProgress({ loaded, total }) {
21619
+ onUploadProgress({ loaded, total = 100 }) {
21219
21620
  onProgress && onProgress(Math.round((loaded * 100) / total));
21220
21621
  },
21221
21622
  });
@@ -21294,7 +21695,7 @@ const createVideo = async (formData, feedType, onProgress) => {
21294
21695
  : { 'content-type': 'multipart/form-data' };
21295
21696
  const { data } = await client.http.post('/api/v4/videos', formData, {
21296
21697
  headers,
21297
- onUploadProgress({ loaded, total }) {
21698
+ onUploadProgress({ loaded, total = 100 }) {
21298
21699
  onProgress && onProgress(Math.round((loaded * 100) / total));
21299
21700
  },
21300
21701
  });
@@ -21335,7 +21736,7 @@ const createImage = async (formData, onProgress) => {
21335
21736
  : { 'content-type': 'multipart/form-data' };
21336
21737
  const { data } = await client.http.post('/api/v4/images', formData, {
21337
21738
  headers,
21338
- onUploadProgress({ loaded, total }) {
21739
+ onUploadProgress({ loaded, total = 100 }) {
21339
21740
  onProgress && onProgress(Math.round((loaded * 100) / total));
21340
21741
  },
21341
21742
  });
@@ -23314,6 +23715,7 @@ getComments.locally = (commentIds) => {
23314
23715
  const getComment = async (commentId) => {
23315
23716
  const client = getActiveClient();
23316
23717
  client.log('comment/getComment', commentId);
23718
+ isInTombstone('comment', commentId);
23317
23719
  let data;
23318
23720
  try {
23319
23721
  // API-FIX: endpoint should not be /list, parameters should be querystring.
@@ -23321,8 +23723,8 @@ const getComment = async (commentId) => {
23321
23723
  data = response.data;
23322
23724
  }
23323
23725
  catch (error) {
23324
- if ((error === null || error === void 0 ? void 0 : error.code) === 400400 /* Amity.ServerError.ITEM_NOT_FOUND */) {
23325
- dropFromCache(['comment', 'get', commentId], true);
23726
+ if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
23727
+ pushToTombstone('comment', commentId);
23326
23728
  }
23327
23729
  throw error;
23328
23730
  }
@@ -23456,9 +23858,7 @@ const deleteComment = async (commentId, permanent = false) => {
23456
23858
  fireEvent('post.updated', { posts: [post.data] });
23457
23859
  fireEvent('comment.deleted', { comments: [deleted] });
23458
23860
  if (permanent) {
23459
- setTimeout(() => {
23460
- dropFromCache(['comment', 'get', commentId], true);
23461
- }, 0);
23861
+ scheduleTask(() => pushToTombstone('comment', commentId));
23462
23862
  }
23463
23863
  else {
23464
23864
  upsertInCache(['comment', 'get', commentId], { isDeleted: true });
@@ -25881,55 +26281,13 @@ const onMessageReactionRemoved = (callback) => {
25881
26281
  * @category Message Live Object
25882
26282
  */
25883
26283
  const liveChannel = (channelId, callback) => {
25884
- const { log, cache } = getActiveClient();
25885
- const timestamp = Date.now();
25886
- log(`liveChannel(tmpid: ${timestamp}) > listen`);
25887
- if (!cache) {
25888
- console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
25889
- }
25890
- let channel;
25891
- let isUnsyncedObject = false;
25892
- const disposers = [];
25893
- const dispatcher = (data) => {
25894
- channel = data.data;
25895
- callback(data);
25896
- };
25897
- const realtimeRouter = (eventChannel) => {
25898
- if (channelId !== eventChannel.channelId) {
25899
- return;
25900
- }
25901
- if (channel && !hasUpdates(channel, eventChannel)) {
25902
- return;
25903
- }
25904
- dispatcher({ loading: false, data: eventChannel, origin: 'event' });
25905
- };
25906
- const onFetch = () => {
25907
- const query = createQuery(getChannel, channelId);
25908
- runQuery(query, ({ loading, data, error, origin, cachedAt }) => {
25909
- if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
25910
- dispatcher({
25911
- data,
25912
- origin,
25913
- loading: false,
25914
- error: new ASCApiError(UNSYNCED_OBJECT_CACHED_AT_MESSAGE, 800800 /* Amity.ClientError.DISALOOW_UNSYNCED_OBJECT */, "error" /* Amity.ErrorLevel.ERROR */),
25915
- });
25916
- isUnsyncedObject = true;
25917
- disposers.forEach(fn => fn());
25918
- }
25919
- else if (!isUnsyncedObject) {
25920
- dispatcher({ loading, data, origin, error });
25921
- }
25922
- if (error) {
25923
- disposers.forEach(fn => fn());
25924
- }
25925
- });
25926
- };
25927
- disposers.push(onChannelUpdated(realtimeRouter), onChannelDeleted(realtimeRouter), onChannelJoined(realtimeRouter), onChannelMuted(realtimeRouter), onMessageCreated(() => null));
25928
- onFetch();
25929
- return () => {
25930
- log(`liveChannel(tmpid: ${timestamp}) > dispose`);
25931
- disposers.forEach(fn => fn());
25932
- };
26284
+ return liveObject(channelId, callback, 'channelId', getChannel, [
26285
+ onChannelUpdated,
26286
+ onChannelDeleted,
26287
+ onChannelJoined,
26288
+ onChannelMuted,
26289
+ () => onMessageCreated(() => null), // watch unread count
26290
+ ]);
25933
26291
  };
25934
26292
 
25935
26293
  /**
@@ -26590,42 +26948,11 @@ const onSubChannelFetched = (callback) => {
26590
26948
  * @category SubChannel Live Object
26591
26949
  */
26592
26950
  const liveSubChannel = (subChannelId, callback) => {
26593
- const { log, cache } = getActiveClient();
26594
- const timestamp = Date.now();
26595
- log(`liveSubChannel(tmpid: ${timestamp}) > listen`);
26596
- if (!cache) {
26597
- console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
26598
- }
26599
- let subChannel;
26600
- const disposers = [];
26601
- const dispatcher = (data) => {
26602
- subChannel = data.data;
26603
- callback(data);
26604
- };
26605
- const realtimeRouter = (eventSubChannel) => {
26606
- if (subChannelId !== eventSubChannel.subChannelId) {
26607
- return;
26608
- }
26609
- if (subChannel && !hasUpdates(subChannel, eventSubChannel)) {
26610
- return;
26611
- }
26612
- dispatcher({ loading: false, data: eventSubChannel, origin: 'event' });
26613
- };
26614
- const onFetch = () => {
26615
- const query = createQuery(getSubChannel, subChannelId);
26616
- runQuery(query, ({ error, data, loading, origin }) => {
26617
- dispatcher({ error, data, loading, origin });
26618
- if (error) {
26619
- disposers.forEach(fn => fn());
26620
- }
26621
- });
26622
- };
26623
- disposers.push(onSubChannelFetched(realtimeRouter), onSubChannelUpdated(realtimeRouter), onSubChannelDeleted(realtimeRouter));
26624
- onFetch();
26625
- return () => {
26626
- log(`liveSubChannel(tmpid: ${timestamp}) > dispose`);
26627
- disposers.forEach(fn => fn());
26628
- };
26951
+ return liveObject(subChannelId, callback, 'subChannelId', getSubChannel, [
26952
+ onSubChannelFetched,
26953
+ onSubChannelUpdated,
26954
+ onSubChannelDeleted,
26955
+ ]);
26629
26956
  };
26630
26957
 
26631
26958
  /**
@@ -26756,55 +27083,16 @@ const onMessageFetched = (callback) => {
26756
27083
  * @category Message Live Object
26757
27084
  */
26758
27085
  const liveMessage = (messageId, callback) => {
26759
- const { log, cache } = getActiveClient();
26760
- const timestamp = Date.now();
26761
- log(`liveMessage(tmpid: ${timestamp}) > listen`);
26762
- if (!cache) {
26763
- console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
26764
- }
26765
- let message;
26766
- let isUnsyncedObject = false;
26767
- const disposers = [];
26768
- const dispatcher = (data) => {
26769
- message = data.data;
26770
- callback(data);
26771
- };
26772
- const realtimeRouter = (eventMessage) => {
26773
- if (messageId !== eventMessage.messageId) {
26774
- return;
26775
- }
26776
- if (message && !hasUpdates(message, eventMessage)) {
26777
- return;
26778
- }
26779
- dispatcher({ loading: false, data: eventMessage, origin: 'event' });
26780
- };
26781
- const onFetch = () => {
26782
- const query = createQuery(getMessage, messageId, true);
26783
- runQuery(query, ({ loading, data, error, origin, cachedAt }) => {
26784
- if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
26785
- dispatcher({
26786
- data,
26787
- origin,
26788
- loading: false,
26789
- error: new ASCApiError(UNSYNCED_OBJECT_CACHED_AT_MESSAGE, 800800 /* Amity.ClientError.DISALOOW_UNSYNCED_OBJECT */, "error" /* Amity.ErrorLevel.ERROR */),
26790
- });
26791
- isUnsyncedObject = true;
26792
- disposers.forEach(fn => fn());
26793
- }
26794
- else if (!isUnsyncedObject) {
26795
- dispatcher({ loading, data, origin, error });
26796
- }
26797
- if (error) {
26798
- disposers.forEach(fn => fn());
26799
- }
26800
- });
26801
- };
26802
- disposers.push(onMessageFetched(realtimeRouter), onMessageUpdated(realtimeRouter), onMessageDeleted(realtimeRouter), onMessageFlagged(realtimeRouter), onMessageUnflagged(realtimeRouter), onMessageFlagCleared(realtimeRouter), onMessageReactionAdded(realtimeRouter), onMessageReactionRemoved(realtimeRouter));
26803
- onFetch();
26804
- return () => {
26805
- log(`liveMessage(tmpid: ${timestamp}) > dispose`);
26806
- disposers.forEach(fn => fn());
26807
- };
27086
+ return liveObject(messageId, callback, 'messageId', getMessage, [
27087
+ onMessageFetched,
27088
+ onMessageUpdated,
27089
+ onMessageDeleted,
27090
+ onMessageFlagged,
27091
+ onMessageUnflagged,
27092
+ onMessageFlagCleared,
27093
+ onMessageReactionAdded,
27094
+ onMessageReactionRemoved,
27095
+ ]);
26808
27096
  };
26809
27097
 
26810
27098
  /**
@@ -27005,6 +27293,30 @@ const createCommunityEventSubscriber = (event, callback) => {
27005
27293
  };
27006
27294
  return createEventSubscriber(client, event, event, filter);
27007
27295
  };
27296
+ /*
27297
+ * verifies membership status
27298
+ */
27299
+ function isMember(membership) {
27300
+ return membership !== 'none';
27301
+ }
27302
+ /*
27303
+ * checks if currently logged in user is part of the community
27304
+ */
27305
+ function isCurrentUserPartOfCommunity(c, m) {
27306
+ const { userId } = getActiveUser();
27307
+ return c.communityId === m.communityId && m.userId === userId;
27308
+ }
27309
+ /*
27310
+ * For mqtt events server will not send user specific data as it's broadcasted
27311
+ * to multiple users. Althought this can be calculated, it's not scalable. Hence
27312
+ * the client SDK needs to calculate this info
27313
+ */
27314
+ function updateMembershipStatus(communities, communityUsers) {
27315
+ return communities.map(c => {
27316
+ const isJoined = communityUsers.some(m => isCurrentUserPartOfCommunity(c, m) && isMember(m.communityMembership));
27317
+ return Object.assign(Object.assign({}, c), { isJoined });
27318
+ });
27319
+ }
27008
27320
  function hasPermission(member, payload, permission) {
27009
27321
  if (member.permissions.some(x => x === permission)) {
27010
27322
  return true;
@@ -27035,7 +27347,15 @@ const createCommunityMemberEventSubscriber = (event, callback) => {
27035
27347
  const client = getActiveClient();
27036
27348
  const filter = (payload) => {
27037
27349
  const communityPayload = unpackCommunityPayload(payload);
27350
+ const { communities } = communityPayload;
27038
27351
  const preparedPayload = prepareMembershipPayload(communityPayload, 'communityUsers');
27352
+ const { communityUsers } = preparedPayload;
27353
+ /*
27354
+ * community.isJoined is not part of the communityMembership payload, and needs
27355
+ * to be calculated based on the communityMembership value
27356
+ */
27357
+ const communitiesWithMembership = updateMembershipStatus(communities, communityUsers);
27358
+ preparedPayload.communities = communitiesWithMembership;
27039
27359
  if (!client.cache) {
27040
27360
  // TODO: here we are missing specific properties here!
27041
27361
  callback(preparedPayload.communities[0], getEventRelatedMember(event, preparedPayload));
@@ -27177,6 +27497,23 @@ const onCommunityUserAdded = (callback) => createCommunityMemberEventSubscriber(
27177
27497
  */
27178
27498
  const onCommunityUserRemoved = (callback) => createCommunityMemberEventSubscriber('community.userRemoved', callback);
27179
27499
 
27500
+ /**
27501
+ * ```js
27502
+ * import { onCommunityUserChanged } from '@amityco/ts-sdk'
27503
+ * const dispose = onCommunityUserChanged((community, member) => {
27504
+ * // ...
27505
+ * })
27506
+ * ```
27507
+ *
27508
+ * Fired when a user has been added or removed from a {@link Amity.Community}
27509
+ *
27510
+ * @param callback The function to call when the event was fired
27511
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
27512
+ *
27513
+ * @category Community Events
27514
+ */
27515
+ const onCommunityUserChanged = (callback) => createCommunityMemberEventSubscriber('community.userChanged', callback);
27516
+
27180
27517
  /**
27181
27518
  * ```js
27182
27519
  * import { onCommunityUserBanned } from '@amityco/ts-sdk'
@@ -27255,6 +27592,122 @@ const observeCommunity = (communityId, callback) => {
27255
27592
  };
27256
27593
  };
27257
27594
 
27595
+ /**
27596
+ * ```js
27597
+ * import { liveCommunities } from '@amityco/ts-sdk'
27598
+ *
27599
+ * let communities = []
27600
+ * const unsub = liveCommunities({
27601
+ * displayName: Amity.Community['displayName'],
27602
+ * }, response => merge(communities, response.data))
27603
+ * ```
27604
+ *
27605
+ * Observe all mutations on a list of {@link Amity.Community}s
27606
+ *
27607
+ * @param params for querying communities
27608
+ * @param callback the function to call when new data are available
27609
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the communities
27610
+ *
27611
+ * @category Community Live Collection
27612
+ */
27613
+ const liveCommunities = (params, callback, config) => {
27614
+ const { log, cache } = getActiveClient();
27615
+ if (!cache) {
27616
+ console.log(ENABLE_CACHE_MESSAGE);
27617
+ }
27618
+ const timestamp = Date.now();
27619
+ log(`liveCommunities(tmpid: ${timestamp}) > listen`);
27620
+ const { limit: queryLimit } = params, queryParams = __rest(params, ["limit"]);
27621
+ const limit = queryLimit !== null && queryLimit !== void 0 ? queryLimit : COLLECTION_DEFAULT_PAGINATION_LIMIT;
27622
+ const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config !== null && config !== void 0 ? config : {};
27623
+ const disposers = [];
27624
+ const cacheKey = ['community', 'collection', {}];
27625
+ const responder = (data) => {
27626
+ var _a, _b;
27627
+ let communities = (_a = data.data
27628
+ .map(communityId => pullFromCache(['community', 'get', communityId]))
27629
+ .filter(Boolean)
27630
+ .map(({ data }) => data)) !== null && _a !== void 0 ? _a : [];
27631
+ communities = filterByPropEquality(communities, 'isDeleted', params.isDeleted);
27632
+ communities = filterByPropEquality(communities, 'displayName', params.displayName);
27633
+ if (params.categoryId) {
27634
+ communities = communities.filter(c => { var _a; return (_a = c.categoryIds) === null || _a === void 0 ? void 0 : _a.includes(params.categoryId); });
27635
+ }
27636
+ if (params.tags) {
27637
+ 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); }); });
27638
+ }
27639
+ if (params.membership === 'member') {
27640
+ communities = filterByPropEquality(communities, 'isJoined', true);
27641
+ }
27642
+ if (params.membership === 'notMember') {
27643
+ communities = filterByPropEquality(communities, 'isJoined', false);
27644
+ }
27645
+ const sortBy = params.sortBy || 'lastCreated';
27646
+ if (sortBy === 'lastCreated' || sortBy === 'firstCreated') {
27647
+ communities = communities.sort(sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated);
27648
+ }
27649
+ /*
27650
+ * The server returns communities with empty | null displayName's first before
27651
+ * returning sorted list of communities with displayNames
27652
+ *
27653
+ * This section needs to be updated as displayNames can be null as well
27654
+ */
27655
+ if (sortBy === 'displayName') {
27656
+ communities = communities
27657
+ // this needs to be aligned with the backend data type
27658
+ .map(c => (c.displayName ? c : Object.assign(Object.assign({}, c), { displayName: '' })))
27659
+ // @ts-ignore
27660
+ .sort(sortByDisplayName);
27661
+ }
27662
+ callback({
27663
+ onNextPage: onFetch,
27664
+ data: communities,
27665
+ hasNextPage: !!((_b = data.params) === null || _b === void 0 ? void 0 : _b.page),
27666
+ loading: data.loading,
27667
+ error: data.error,
27668
+ });
27669
+ };
27670
+ const realtimeRouter = (_) => (community) => {
27671
+ var _a;
27672
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
27673
+ if (!collection)
27674
+ return;
27675
+ /*
27676
+ * Simply update collection and let responder decide what to do with data
27677
+ */
27678
+ collection.data = [...new Set([community.communityId, ...collection.data])];
27679
+ pushToCache(cacheKey, collection);
27680
+ responder(collection);
27681
+ };
27682
+ const onFetch = () => {
27683
+ var _a, _b, _c;
27684
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
27685
+ const communities = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
27686
+ if (communities.length > 0 && !(collection === null || collection === void 0 ? void 0 : collection.params.page))
27687
+ return;
27688
+ 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 } }));
27689
+ runQuery(query, ({ data: result, error, loading, nextPage: page }) => {
27690
+ const data = {
27691
+ loading,
27692
+ error,
27693
+ params: { page },
27694
+ data: communities,
27695
+ };
27696
+ if (result) {
27697
+ data.data = [...new Set([...communities, ...result.map(getResolver('community'))])];
27698
+ }
27699
+ pushToCache(cacheKey, data);
27700
+ responder(data);
27701
+ }, queryOptions(policy));
27702
+ };
27703
+ disposers.push(onCommunityCreated(realtimeRouter()), onCommunityDeleted(realtimeRouter()), onCommunityUpdated(realtimeRouter()), onCommunityJoined(realtimeRouter()), onCommunityLeft(realtimeRouter()), onCommunityUserChanged(realtimeRouter()));
27704
+ onFetch();
27705
+ return () => {
27706
+ log(`liveCommunities(tmpid: ${timestamp}) > dispose`);
27707
+ disposers.forEach(fn => fn());
27708
+ };
27709
+ };
27710
+
27258
27711
  /**
27259
27712
  * ```js
27260
27713
  * import { queryCategories } from '@amityco/ts-sdk'
@@ -27383,6 +27836,96 @@ getCategory.locally = (categoryId) => {
27383
27836
  };
27384
27837
  };
27385
27838
 
27839
+ /**
27840
+ * ```js
27841
+ * import { liveCategories } from '@amityco/ts-sdk'
27842
+ *
27843
+ * let categories = []
27844
+ * const unsub = liveCategories({}, response => merge(categories, response.data))
27845
+ * ```
27846
+ *
27847
+ * Observe all mutations on a list of {@link Amity.Category}s
27848
+ *
27849
+ * @param params for querying categories
27850
+ * @param callback the function to call when new data are available
27851
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the categories
27852
+ *
27853
+ * @category Category Live Collection
27854
+ */
27855
+ const liveCategories = (params, callback, config) => {
27856
+ const { log, cache } = getActiveClient();
27857
+ if (!cache) {
27858
+ console.log(ENABLE_CACHE_MESSAGE);
27859
+ }
27860
+ const timestamp = Date.now();
27861
+ log(`liveCategories(tmpid: ${timestamp}) > listen`);
27862
+ const { limit: queryLimit } = params, queryParams = __rest(params, ["limit"]);
27863
+ const limit = queryLimit !== null && queryLimit !== void 0 ? queryLimit : COLLECTION_DEFAULT_PAGINATION_LIMIT;
27864
+ const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config !== null && config !== void 0 ? config : {};
27865
+ const disposers = [];
27866
+ const cacheKey = ['category', 'collection', {}];
27867
+ const responder = (data) => {
27868
+ var _a, _b;
27869
+ let categories = (_a = data.data
27870
+ .map(categoryId => pullFromCache(['category', 'get', categoryId]))
27871
+ .filter(Boolean)
27872
+ .map(({ data }) => data)) !== null && _a !== void 0 ? _a : [];
27873
+ categories = filterByPropEquality(categories, 'isDeleted', params.isDeleted);
27874
+ switch (params.sortBy) {
27875
+ case 'firstCreated':
27876
+ categories = categories.sort(sortByFirstCreated);
27877
+ break;
27878
+ case 'lastCreated':
27879
+ categories = categories.sort(sortByLastCreated);
27880
+ break;
27881
+ default:
27882
+ categories = categories.sort(sortByName);
27883
+ }
27884
+ callback({
27885
+ onNextPage: onFetch,
27886
+ data: categories,
27887
+ hasNextPage: !!((_b = data.params) === null || _b === void 0 ? void 0 : _b.page),
27888
+ loading: data.loading,
27889
+ error: data.error,
27890
+ });
27891
+ };
27892
+ /*
27893
+ * const realtimeRouter = () => {
27894
+ * @TODO: At the time of creating this method category does not have any
27895
+ * observers
27896
+ *};
27897
+ */
27898
+ const onFetch = () => {
27899
+ var _a, _b, _c;
27900
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
27901
+ const categories = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
27902
+ if (categories.length > 0 && !(collection === null || collection === void 0 ? void 0 : collection.params.page))
27903
+ return;
27904
+ 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 } }));
27905
+ runQuery(query, ({ data: result, error, loading, nextPage: page }) => {
27906
+ const data = {
27907
+ loading,
27908
+ error,
27909
+ params: { page },
27910
+ data: categories,
27911
+ };
27912
+ if (result) {
27913
+ data.data = [...new Set([...categories, ...result.map(getResolver('category'))])];
27914
+ }
27915
+ pushToCache(cacheKey, data);
27916
+ responder(data);
27917
+ }, queryOptions(policy));
27918
+ };
27919
+ disposers.push(() => {
27920
+ // @TODO -> update once observers added
27921
+ });
27922
+ onFetch();
27923
+ return () => {
27924
+ log(`liveCategories(tmpid: ${timestamp}) > dispose`);
27925
+ disposers.forEach(fn => fn());
27926
+ };
27927
+ };
27928
+
27386
27929
  /**
27387
27930
  * ```js
27388
27931
  * import { queryGlobalFeed } from '@amityco/ts-sdk'
@@ -28307,6 +28850,38 @@ const observePost = (postId, callback, policy = 'cache_then_server') => {
28307
28850
  };
28308
28851
  };
28309
28852
 
28853
+ /**
28854
+ * ```js
28855
+ * import { livePost } from '@amityco/ts-sdk';
28856
+ *
28857
+ * let post;
28858
+ *
28859
+ * const unsubscribe = livePost(postId, response => {
28860
+ * post = response.data;
28861
+ * });
28862
+ * ```
28863
+ *
28864
+ * Observe all mutation on a given {@link Amity.Post}
28865
+ *
28866
+ * @param postId the ID of the message to observe
28867
+ * @param callback the function to call when new data are available
28868
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the sub channel
28869
+ *
28870
+ * @category Post Live Object
28871
+ */
28872
+ const livePost = (postId, callback) => {
28873
+ return liveObject(postId, callback, 'postId', getPost, [
28874
+ onPostApproved,
28875
+ onPostDeclined,
28876
+ onPostDeleted,
28877
+ onPostFlagged,
28878
+ onPostReactionAdded,
28879
+ onPostReactionRemoved,
28880
+ onPostUnflagged,
28881
+ onPostUpdated,
28882
+ ]);
28883
+ };
28884
+
28310
28885
  /**
28311
28886
  * ```js
28312
28887
  * import { livePosts } from '@amityco/ts-sdk'
@@ -28502,6 +29077,36 @@ const observeComment = (commentId, callback, policy = 'cache_then_server') => {
28502
29077
  };
28503
29078
  };
28504
29079
 
29080
+ /**
29081
+ * ```js
29082
+ * import { liveComment } from '@amityco/ts-sdk';
29083
+ *
29084
+ * let comment;
29085
+ *
29086
+ * const unsubscribe = liveComment(commentId, response => {
29087
+ * comment = response.data;
29088
+ * });
29089
+ * ```
29090
+ *
29091
+ * Observe all mutation on a given {@link Amity.Comment}
29092
+ *
29093
+ * @param commentId the ID of the comment to observe
29094
+ * @param callback the function to call when new data are available
29095
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the comment
29096
+ *
29097
+ * @category Comment Live Object
29098
+ */
29099
+ const liveComment = (commentId, callback) => {
29100
+ return liveObject(commentId, callback, 'commentId', getComment, [
29101
+ onCommentDeleted,
29102
+ onCommentFlagged,
29103
+ onCommentReactionAdded,
29104
+ onCommentReactionRemoved,
29105
+ onCommentUnflagged,
29106
+ onCommentUpdated,
29107
+ ]);
29108
+ };
29109
+
28505
29110
  /**
28506
29111
  * ```js
28507
29112
  * import { liveComments } from '@amityco/ts-sdk'
@@ -29180,10 +29785,10 @@ const onStreamRecorded = (callback) => {
29180
29785
  */
29181
29786
  const createUserToken = async (apiKey, apiRegion, params) => {
29182
29787
  const deviceId = getDeviceId();
29183
- const deviceInfo = await getDeviceInfo();
29788
+ const deviceInfo = getDeviceInfo();
29184
29789
  const http = createHttpTransport(computeUrl('http', apiRegion));
29185
- const { data } = await http.post('/api/v3/sessions', Object.assign(Object.assign({}, params), { deviceId, deviceInfo: Object.assign(Object.assign({}, deviceInfo), { model: 'token management API on TS-SDK' }) }), { headers: { 'X-API-Key': apiKey } });
29790
+ const { data } = await http.post('/api/v4/sessions', Object.assign(Object.assign({}, params), { deviceId, deviceInfo: Object.assign(Object.assign({}, deviceInfo), { model: 'token management API on TS-SDK' }) }), { headers: { 'X-API-Key': apiKey } });
29186
29791
  return { accessToken: data.accessToken };
29187
29792
  };
29188
29793
 
29189
- 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, 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, 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 };
29794
+ 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, liveCategories, liveChannel, liveChannelMembers, liveChannels, liveComment, liveComments, liveCommunities, liveFollowers, liveFollowings, liveMessage, liveMessages, livePost, 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, 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 };