@amityco/ts-sdk 0.0.1-beta.37 → 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 (179) hide show
  1. package/.eslintrc.json +3 -5
  2. package/dist/@types/core/events.d.ts +1 -0
  3. package/dist/@types/core/events.d.ts.map +1 -1
  4. package/dist/@types/domains/category.d.ts +7 -0
  5. package/dist/@types/domains/category.d.ts.map +1 -1
  6. package/dist/@types/domains/community.d.ts +12 -0
  7. package/dist/@types/domains/community.d.ts.map +1 -1
  8. package/dist/@types/global.d.ts +5 -0
  9. package/dist/@types/global.d.ts.map +1 -1
  10. package/dist/category/api/queryCategories.d.ts +1 -5
  11. package/dist/category/api/queryCategories.d.ts.map +1 -1
  12. package/dist/category/observers/index.d.ts +2 -0
  13. package/dist/category/observers/index.d.ts.map +1 -0
  14. package/dist/category/observers/liveCategories.d.ts +18 -0
  15. package/dist/category/observers/liveCategories.d.ts.map +1 -0
  16. package/dist/category/observers/tests/liveCategories.test.d.ts +2 -0
  17. package/dist/category/observers/tests/liveCategories.test.d.ts.map +1 -0
  18. package/dist/channel/api/tests/getChannels.test.d.ts +2 -0
  19. package/dist/channel/api/tests/getChannels.test.d.ts.map +1 -0
  20. package/dist/channel/api/tests/leaveChannel.test.d.ts +2 -0
  21. package/dist/channel/api/tests/leaveChannel.test.d.ts.map +1 -0
  22. package/dist/channel/observers/liveChannel.d.ts.map +1 -1
  23. package/dist/client/api/accessTokenExpiryWatcher.d.ts +4 -1
  24. package/dist/client/api/accessTokenExpiryWatcher.d.ts.map +1 -1
  25. package/dist/client/api/getToken.d.ts +3 -1
  26. package/dist/client/api/getToken.d.ts.map +1 -1
  27. package/dist/client/utils/setClientToken.d.ts +3 -3
  28. package/dist/comment/api/deleteComment.d.ts.map +1 -1
  29. package/dist/comment/api/getComment.d.ts.map +1 -1
  30. package/dist/comment/observers/index.d.ts +1 -0
  31. package/dist/comment/observers/index.d.ts.map +1 -1
  32. package/dist/comment/observers/liveComment.d.ts +21 -0
  33. package/dist/comment/observers/liveComment.d.ts.map +1 -0
  34. package/dist/comment/observers/tests/liveComment.test.d.ts +2 -0
  35. package/dist/comment/observers/tests/liveComment.test.d.ts.map +1 -0
  36. package/dist/community/api/queryCommunities.d.ts +1 -10
  37. package/dist/community/api/queryCommunities.d.ts.map +1 -1
  38. package/dist/community/events/index.d.ts +1 -0
  39. package/dist/community/events/index.d.ts.map +1 -1
  40. package/dist/community/events/onCommunityUserChanged.d.ts +17 -0
  41. package/dist/community/events/onCommunityUserChanged.d.ts.map +1 -0
  42. package/dist/community/events/utils.d.ts +1 -0
  43. package/dist/community/events/utils.d.ts.map +1 -1
  44. package/dist/community/observers/index.d.ts +1 -0
  45. package/dist/community/observers/index.d.ts.map +1 -1
  46. package/dist/community/observers/liveCommunities.d.ts +20 -0
  47. package/dist/community/observers/liveCommunities.d.ts.map +1 -0
  48. package/dist/community/observers/tests/liveCommunities.test.d.ts +2 -0
  49. package/dist/community/observers/tests/liveCommunities.test.d.ts.map +1 -0
  50. package/dist/core/events.d.ts +3 -3
  51. package/dist/core/events.d.ts.map +1 -1
  52. package/dist/core/query/sorting.d.ts +6 -0
  53. package/dist/core/query/sorting.d.ts.map +1 -1
  54. package/dist/core/transports/http.d.ts +0 -5
  55. package/dist/core/transports/http.d.ts.map +1 -1
  56. package/dist/file/api/test/createImage.test.d.ts +2 -0
  57. package/dist/file/api/test/createImage.test.d.ts.map +1 -0
  58. package/dist/file/api/test/createVideo.test.d.ts +2 -0
  59. package/dist/file/api/test/createVideo.test.d.ts.map +1 -0
  60. package/dist/index.cjs.js +441 -195
  61. package/dist/index.d.ts +1 -0
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.esm.js +436 -195
  64. package/dist/index.umd.js +4 -4
  65. package/dist/message/observers/liveMessage.d.ts.map +1 -1
  66. package/dist/post/observers/index.d.ts +1 -0
  67. package/dist/post/observers/index.d.ts.map +1 -1
  68. package/dist/post/observers/livePost.d.ts +21 -0
  69. package/dist/post/observers/livePost.d.ts.map +1 -0
  70. package/dist/post/observers/tests/livePost.test.d.ts +2 -0
  71. package/dist/post/observers/tests/livePost.test.d.ts.map +1 -0
  72. package/dist/subChannel/api/tests/deleteSubChannel.test.d.ts +2 -0
  73. package/dist/subChannel/api/tests/deleteSubChannel.test.d.ts.map +1 -0
  74. package/dist/subChannel/api/tests/getSubChannel.test.d.ts +2 -0
  75. package/dist/subChannel/api/tests/getSubChannel.test.d.ts.map +1 -0
  76. package/dist/subChannel/api/tests/getSubChannels.test.d.ts +2 -0
  77. package/dist/subChannel/api/tests/getSubChannels.test.d.ts.map +1 -0
  78. package/dist/subChannel/api/tests/updateSubChannel.test.d.ts +2 -0
  79. package/dist/subChannel/api/tests/updateSubChannel.test.d.ts.map +1 -0
  80. package/dist/subChannel/observers/liveSubChannel.d.ts.map +1 -1
  81. package/dist/user/api/tests/updateUser.test.d.ts +2 -0
  82. package/dist/user/api/tests/updateUser.test.d.ts.map +1 -0
  83. package/dist/user/observers/liveUser.d.ts.map +1 -1
  84. package/dist/utils/liveObject.d.ts +2 -0
  85. package/dist/utils/liveObject.d.ts.map +1 -0
  86. package/dist/utils/tests/dummy/category.d.ts +64 -0
  87. package/dist/utils/tests/dummy/category.d.ts.map +1 -0
  88. package/dist/utils/tests/dummy/channel.d.ts +50 -0
  89. package/dist/utils/tests/dummy/channel.d.ts.map +1 -1
  90. package/dist/utils/tests/dummy/community.d.ts +132 -0
  91. package/dist/utils/tests/dummy/community.d.ts.map +1 -1
  92. package/dist/utils/tests/dummy/file.d.ts +3 -0
  93. package/dist/utils/tests/dummy/file.d.ts.map +1 -1
  94. package/dist/utils/tests/dummy/index.d.ts +1 -0
  95. package/dist/utils/tests/dummy/index.d.ts.map +1 -1
  96. package/dist/utils/tests/dummy/post.d.ts +2 -0
  97. package/dist/utils/tests/dummy/post.d.ts.map +1 -1
  98. package/dist/utils/tests/dummy/subChannel.d.ts +0 -20
  99. package/dist/utils/tests/dummy/subChannel.d.ts.map +1 -1
  100. package/dist/utils/tests/dummy/user.d.ts +18 -0
  101. package/dist/utils/tests/dummy/user.d.ts.map +1 -1
  102. package/dist/utils/tests/liveObject.test.d.ts +2 -0
  103. package/dist/utils/tests/liveObject.test.d.ts.map +1 -0
  104. package/package.json +4 -4
  105. package/src/@types/core/events.ts +1 -0
  106. package/src/@types/domains/category.ts +13 -0
  107. package/src/@types/domains/community.ts +25 -0
  108. package/src/@types/global.ts +5 -0
  109. package/src/category/api/queryCategories.ts +3 -5
  110. package/src/category/observers/index.ts +1 -0
  111. package/src/category/observers/liveCategories.ts +141 -0
  112. package/src/category/observers/tests/liveCategories.test.ts +147 -0
  113. package/src/channel/api/tests/createChannel.test.ts +30 -6
  114. package/src/channel/api/tests/getChannel.test.ts +3 -1
  115. package/src/channel/api/tests/getChannels.test.ts +97 -0
  116. package/src/channel/api/tests/joinChannel.test.ts +62 -3
  117. package/src/channel/api/tests/leaveChannel.test.ts +90 -0
  118. package/src/channel/api/tests/queryChannels.test.ts +38 -1
  119. package/src/channel/observers/liveChannel.ts +8 -80
  120. package/src/client/api/accessTokenExpiryWatcher.ts +7 -5
  121. package/src/client/api/tests/accessTokenExpiryWatcher.test.ts +8 -5
  122. package/src/comment/api/deleteComment.ts +5 -5
  123. package/src/comment/api/getComment.ts +8 -3
  124. package/src/comment/observers/index.ts +1 -0
  125. package/src/comment/observers/liveComment.ts +43 -0
  126. package/src/comment/observers/tests/liveComment.test.ts +95 -0
  127. package/src/community/api/queryCommunities.ts +3 -10
  128. package/src/community/api/test/addCommunityMember.test.ts +14 -2
  129. package/src/community/api/test/joinCommunity.test.ts +14 -2
  130. package/src/community/api/test/leaveCommunity.test.ts +11 -1
  131. package/src/community/api/test/removeCommunityMembers.test.ts +11 -1
  132. package/src/community/events/index.ts +1 -0
  133. package/src/community/events/onCommunityUserChanged.ts +20 -0
  134. package/src/community/events/test/onCommunityJoined.test.ts +1 -1
  135. package/src/community/events/test/onCommunityUserAdded.test.ts +1 -1
  136. package/src/community/events/test/onCommunityUserBanned.test.ts +1 -1
  137. package/src/community/events/test/onCommunityUserUnbaned.test.ts +1 -1
  138. package/src/community/events/test/utils.test.ts +52 -3
  139. package/src/community/events/utils.ts +49 -0
  140. package/src/community/observers/index.ts +1 -0
  141. package/src/community/observers/liveCommunities.ts +188 -0
  142. package/src/community/observers/tests/liveCommunities.test.ts +284 -0
  143. package/src/core/query/sorting.ts +8 -0
  144. package/src/core/transports/http.ts +17 -13
  145. package/src/core/transports/test/http.test.ts +49 -60
  146. package/src/file/api/createFile.ts +1 -1
  147. package/src/file/api/createImage.ts +1 -1
  148. package/src/file/api/createVideo.ts +1 -1
  149. package/src/file/api/test/createImage.test.ts +69 -0
  150. package/src/file/api/test/createVideo.test.ts +81 -0
  151. package/src/index.ts +1 -0
  152. package/src/message/observers/liveMessage.ts +11 -83
  153. package/src/message/tests/observers/liveMessage.test.ts +1 -143
  154. package/src/post/observers/index.ts +1 -0
  155. package/src/post/observers/livePost.ts +47 -0
  156. package/src/post/observers/tests/livePost.test.ts +97 -0
  157. package/src/stream/api/tests/createStream.test.ts +3 -11
  158. package/src/stream/api/tests/deleteStream.test.ts +5 -3
  159. package/src/subChannel/api/tests/createSubChannel.test.ts +21 -14
  160. package/src/subChannel/api/tests/deleteSubChannel.test.ts +112 -0
  161. package/src/subChannel/api/tests/getSubChannel.test.ts +97 -0
  162. package/src/subChannel/api/tests/getSubChannels.test.ts +97 -0
  163. package/src/subChannel/api/tests/updateSubChannel.test.ts +86 -0
  164. package/src/subChannel/observers/liveSubChannel.ts +6 -56
  165. package/src/subChannel/observers/tests/liveSubChannel.test.ts +0 -82
  166. package/src/user/api/tests/updateUser.test.ts +60 -0
  167. package/src/user/observers/liveUser.ts +9 -61
  168. package/src/user/tests/observers/liveUser.test.ts +1 -154
  169. package/src/utils/liveObject.ts +86 -0
  170. package/src/utils/tests/dummy/category.ts +57 -0
  171. package/src/utils/tests/dummy/channel.ts +51 -1
  172. package/src/utils/tests/dummy/community.ts +94 -0
  173. package/src/utils/tests/dummy/file.ts +32 -0
  174. package/src/utils/tests/dummy/index.ts +1 -0
  175. package/src/utils/tests/dummy/post.ts +56 -45
  176. package/src/utils/tests/dummy/stream.ts +73 -73
  177. package/src/utils/tests/dummy/subChannel.ts +0 -22
  178. package/src/utils/tests/dummy/user.ts +21 -0
  179. package/src/utils/tests/liveObject.test.ts +172 -0
package/dist/index.cjs.js CHANGED
@@ -7,7 +7,6 @@ var AsyncStorage = require('@react-native-async-storage/async-storage');
7
7
  var mitt = require('mitt');
8
8
  var debug = require('debug');
9
9
  var axios = require('axios');
10
- var qs = require('qs');
11
10
  var HttpAgent = require('agentkeepalive');
12
11
  var io = require('socket.io-client');
13
12
  var nativeIdGenerator = require('react-native-uuid');
@@ -18,7 +17,6 @@ var AsyncStorage__default = /*#__PURE__*/_interopDefaultLegacy(AsyncStorage);
18
17
  var mitt__default = /*#__PURE__*/_interopDefaultLegacy(mitt);
19
18
  var debug__default = /*#__PURE__*/_interopDefaultLegacy(debug);
20
19
  var axios__default = /*#__PURE__*/_interopDefaultLegacy(axios);
21
- var qs__default = /*#__PURE__*/_interopDefaultLegacy(qs);
22
20
  var HttpAgent__default = /*#__PURE__*/_interopDefaultLegacy(HttpAgent);
23
21
  var io__default = /*#__PURE__*/_interopDefaultLegacy(io);
24
22
  var nativeIdGenerator__default = /*#__PURE__*/_interopDefaultLegacy(nativeIdGenerator);
@@ -1094,6 +1092,14 @@ const sortByDisplayName = ({ displayName: a }, { displayName: b }) => {
1094
1092
  return 0;
1095
1093
  return a < b ? -1 : 1;
1096
1094
  };
1095
+ /**
1096
+ * Alphabetic sorting of objects having a name
1097
+ */
1098
+ const sortByName = ({ name: a }, { name: b }) => {
1099
+ if (a === b)
1100
+ return 0;
1101
+ return a < b ? -1 : 1;
1102
+ };
1097
1103
  /**
1098
1104
  * Sorting a collection by their apparition order (oldest first)
1099
1105
  */
@@ -1397,13 +1403,6 @@ const unwrapPayload = (response) => {
1397
1403
  return undefined;
1398
1404
  };
1399
1405
 
1400
- /**
1401
- * Axios param serializer (for querystring)
1402
- * @hidden
1403
- */
1404
- const stringify = (params) => {
1405
- return qs__default["default"].stringify(params, { arrayFormat: 'brackets' });
1406
- };
1407
1406
  /**
1408
1407
  * Creates a pre-configured axios instance
1409
1408
  *
@@ -1424,7 +1423,14 @@ const createHttpTransport = (endpoint) => {
1424
1423
  baseURL: endpoint,
1425
1424
  httpAgent: new HttpAgent__default["default"](options),
1426
1425
  httpsAgent: new HttpAgent.HttpsAgent(options),
1427
- paramsSerializer: stringify,
1426
+ /*
1427
+ * If paramSerializer is required, use the serialize option to stringify
1428
+ * params. The encode option will pass complex params as string only whereas
1429
+ * the serialize option will pass params in the format Record<string, any>
1430
+ *
1431
+ * For more details:
1432
+ * https://github.com/axios/axios#request-config
1433
+ */
1428
1434
  });
1429
1435
  instance.interceptors.request.use(config => {
1430
1436
  var _a;
@@ -1438,10 +1444,8 @@ const createHttpTransport = (endpoint) => {
1438
1444
  return config;
1439
1445
  });
1440
1446
  instance.interceptors.response.use(response => response, error => {
1441
- var _a;
1447
+ var _a, _b;
1442
1448
  const { response } = error;
1443
- // eslint-disable-next-line no-console
1444
- console.error((_a = response === null || response === void 0 ? void 0 : response.data) !== null && _a !== void 0 ? _a : error);
1445
1449
  // handle unauthorized request
1446
1450
  if (response.data.code === 400100 /* Amity.ServerError.UNAUTHORIZED */) {
1447
1451
  fireEvent('tokenTerminated', "terminated" /* Amity.SessionStates.TERMINATED */);
@@ -1451,8 +1455,15 @@ const createHttpTransport = (endpoint) => {
1451
1455
  fireEvent('tokenExpired', "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */);
1452
1456
  throw new ASCError('Token expired', 800403 /* Amity.ClientError.TOKEN_EXPIRED */, "fatal" /* Amity.ErrorLevel.FATAL */);
1453
1457
  }
1454
- if (response === null || response === void 0 ? void 0 : response.data)
1455
- unwrapPayload(response.data);
1458
+ // if it's an error with status in the response payload,
1459
+ // then it's an expected error.
1460
+ if ((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.status) {
1461
+ unwrapPayload(response === null || response === void 0 ? void 0 : response.data);
1462
+ }
1463
+ // unexpected error.
1464
+ else {
1465
+ throw new Error((_b = response === null || response === void 0 ? void 0 : response.data) !== null && _b !== void 0 ? _b : error);
1466
+ }
1456
1467
  });
1457
1468
  return instance;
1458
1469
  };
@@ -20892,7 +20903,8 @@ const isExpired = (expiresAt) => Date.now() > Date.parse(expiresAt) - COMPENSATE
20892
20903
  *
20893
20904
  * @category private
20894
20905
  */
20895
- const isAboutToExpire = (expiresAt, issuedAt) => {
20906
+ const isAboutToExpire = (params) => {
20907
+ const { expiresAt, issuedAt } = params;
20896
20908
  const expires = Date.parse(expiresAt);
20897
20909
  const issued = Date.parse(issuedAt);
20898
20910
  const now = Date.now();
@@ -20927,7 +20939,7 @@ const accessTokenExpiryWatcher = (expiresAt, issuedAt, sessionHandler) => {
20927
20939
  scheduleTask(() => sessionHandler.sessionWillRenewAccessToken(renewal()));
20928
20940
  return;
20929
20941
  }
20930
- if (isAboutToExpire(issuedAt, expiresAt)) {
20942
+ if (isAboutToExpire({ expiresAt, issuedAt })) {
20931
20943
  sessionHandler.sessionWillRenewAccessToken(renewal());
20932
20944
  }
20933
20945
  }, ACCESS_TOKEN_WATCHER_INTERVAL);
@@ -21398,6 +21410,58 @@ const onUserUnflagged = (callback) => createUserEventSubscriber('user.unflagged'
21398
21410
  */
21399
21411
  const onUserFlagCleared = (callback) => createUserEventSubscriber('user.flagCleared', callback);
21400
21412
 
21413
+ const liveObject = (id, callback, key, fetcher, eventHandlers) => {
21414
+ const { cache } = getActiveClient();
21415
+ if (!cache) {
21416
+ console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
21417
+ }
21418
+ let model;
21419
+ let isUnsyncedModel = false; // for messages
21420
+ const disposers = [];
21421
+ const dispatcher = (data) => {
21422
+ model = data.data;
21423
+ callback(data);
21424
+ };
21425
+ const realtimeRouter = (eventModel) => {
21426
+ if (id !== eventModel[key]) {
21427
+ return;
21428
+ }
21429
+ if (model && !hasUpdates(model, eventModel)) {
21430
+ return;
21431
+ }
21432
+ dispatcher({ loading: false, data: eventModel, origin: 'event' });
21433
+ };
21434
+ const onFetch = () => {
21435
+ // @ts-ignore
21436
+ const query = createQuery(fetcher, id, true);
21437
+ runQuery(query, ({ error, data, loading, origin, cachedAt }) => {
21438
+ if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
21439
+ dispatcher({
21440
+ // @ts-ignore
21441
+ data,
21442
+ origin,
21443
+ loading: false,
21444
+ error: new ASCApiError(UNSYNCED_OBJECT_CACHED_AT_MESSAGE, 800800 /* Amity.ClientError.DISALOOW_UNSYNCED_OBJECT */, "error" /* Amity.ErrorLevel.ERROR */),
21445
+ });
21446
+ isUnsyncedModel = true;
21447
+ disposers.forEach(fn => fn());
21448
+ }
21449
+ else if (!isUnsyncedModel) {
21450
+ // @ts-ignore
21451
+ dispatcher({ loading, data, origin, error });
21452
+ }
21453
+ if (error) {
21454
+ disposers.forEach(fn => fn());
21455
+ }
21456
+ });
21457
+ };
21458
+ disposers.push(...eventHandlers.map(fn => fn(realtimeRouter)));
21459
+ onFetch();
21460
+ return () => {
21461
+ disposers.forEach(fn => fn());
21462
+ };
21463
+ };
21464
+
21401
21465
  /**
21402
21466
  * ```js
21403
21467
  * import { onUserFetched } from '@amityco/ts-sdk'
@@ -21435,42 +21499,14 @@ const onUserFetched = (callback) => createUserEventSubscriber('user.fetched', ca
21435
21499
  * @category Message Live Object
21436
21500
  */
21437
21501
  const liveUser = (userId, callback) => {
21438
- const { log, cache } = getActiveClient();
21439
- const timestamp = Date.now();
21440
- log(`liveUser(tmpid: ${timestamp}) > listen`);
21441
- if (!cache) {
21442
- console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
21443
- }
21444
- let user;
21445
- const disposers = [];
21446
- const dispatcher = (data) => {
21447
- user = data.data;
21448
- callback(data);
21449
- };
21450
- const realtimeRouter = (eventUser) => {
21451
- if (userId !== eventUser.userId) {
21452
- return;
21453
- }
21454
- if (user && !hasUpdates(user, eventUser)) {
21455
- return;
21456
- }
21457
- dispatcher({ loading: false, data: eventUser, origin: 'event' });
21458
- };
21459
- const onFetch = () => {
21460
- const query = createQuery(getUser, userId, true);
21461
- runQuery(query, ({ loading, data, error, origin }) => {
21462
- dispatcher({ loading, data, origin, error });
21463
- if (error) {
21464
- disposers.forEach(fn => fn());
21465
- }
21466
- });
21467
- };
21468
- disposers.push(onUserFetched(realtimeRouter), onUserUpdated(realtimeRouter), onUserDeleted(realtimeRouter), onUserFlagged(realtimeRouter), onUserUnflagged(realtimeRouter), onUserFlagCleared(realtimeRouter));
21469
- onFetch();
21470
- return () => {
21471
- log(`liveUser(tmpid: ${timestamp}) > dispose`);
21472
- disposers.forEach(fn => fn());
21473
- };
21502
+ return liveObject(userId, callback, 'userId', getUser, [
21503
+ onUserFetched,
21504
+ onUserUpdated,
21505
+ onUserDeleted,
21506
+ onUserFlagged,
21507
+ onUserUnflagged,
21508
+ onUserFlagCleared,
21509
+ ]);
21474
21510
  };
21475
21511
 
21476
21512
  /**
@@ -21594,7 +21630,7 @@ const createFile = async (formData, onProgress) => {
21594
21630
  : { 'content-type': 'multipart/form-data' };
21595
21631
  const { data } = await client.http.post('/api/v4/files', formData, {
21596
21632
  headers,
21597
- onUploadProgress({ loaded, total }) {
21633
+ onUploadProgress({ loaded, total = 100 }) {
21598
21634
  onProgress && onProgress(Math.round((loaded * 100) / total));
21599
21635
  },
21600
21636
  });
@@ -21673,7 +21709,7 @@ const createVideo = async (formData, feedType, onProgress) => {
21673
21709
  : { 'content-type': 'multipart/form-data' };
21674
21710
  const { data } = await client.http.post('/api/v4/videos', formData, {
21675
21711
  headers,
21676
- onUploadProgress({ loaded, total }) {
21712
+ onUploadProgress({ loaded, total = 100 }) {
21677
21713
  onProgress && onProgress(Math.round((loaded * 100) / total));
21678
21714
  },
21679
21715
  });
@@ -21714,7 +21750,7 @@ const createImage = async (formData, onProgress) => {
21714
21750
  : { 'content-type': 'multipart/form-data' };
21715
21751
  const { data } = await client.http.post('/api/v4/images', formData, {
21716
21752
  headers,
21717
- onUploadProgress({ loaded, total }) {
21753
+ onUploadProgress({ loaded, total = 100 }) {
21718
21754
  onProgress && onProgress(Math.round((loaded * 100) / total));
21719
21755
  },
21720
21756
  });
@@ -23693,6 +23729,7 @@ getComments.locally = (commentIds) => {
23693
23729
  const getComment = async (commentId) => {
23694
23730
  const client = getActiveClient();
23695
23731
  client.log('comment/getComment', commentId);
23732
+ isInTombstone('comment', commentId);
23696
23733
  let data;
23697
23734
  try {
23698
23735
  // API-FIX: endpoint should not be /list, parameters should be querystring.
@@ -23700,8 +23737,8 @@ const getComment = async (commentId) => {
23700
23737
  data = response.data;
23701
23738
  }
23702
23739
  catch (error) {
23703
- if ((error === null || error === void 0 ? void 0 : error.code) === 400400 /* Amity.ServerError.ITEM_NOT_FOUND */) {
23704
- dropFromCache(['comment', 'get', commentId], true);
23740
+ if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
23741
+ pushToTombstone('comment', commentId);
23705
23742
  }
23706
23743
  throw error;
23707
23744
  }
@@ -23835,9 +23872,7 @@ const deleteComment = async (commentId, permanent = false) => {
23835
23872
  fireEvent('post.updated', { posts: [post.data] });
23836
23873
  fireEvent('comment.deleted', { comments: [deleted] });
23837
23874
  if (permanent) {
23838
- setTimeout(() => {
23839
- dropFromCache(['comment', 'get', commentId], true);
23840
- }, 0);
23875
+ scheduleTask(() => pushToTombstone('comment', commentId));
23841
23876
  }
23842
23877
  else {
23843
23878
  upsertInCache(['comment', 'get', commentId], { isDeleted: true });
@@ -26260,55 +26295,13 @@ const onMessageReactionRemoved = (callback) => {
26260
26295
  * @category Message Live Object
26261
26296
  */
26262
26297
  const liveChannel = (channelId, callback) => {
26263
- const { log, cache } = getActiveClient();
26264
- const timestamp = Date.now();
26265
- log(`liveChannel(tmpid: ${timestamp}) > listen`);
26266
- if (!cache) {
26267
- console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
26268
- }
26269
- let channel;
26270
- let isUnsyncedObject = false;
26271
- const disposers = [];
26272
- const dispatcher = (data) => {
26273
- channel = data.data;
26274
- callback(data);
26275
- };
26276
- const realtimeRouter = (eventChannel) => {
26277
- if (channelId !== eventChannel.channelId) {
26278
- return;
26279
- }
26280
- if (channel && !hasUpdates(channel, eventChannel)) {
26281
- return;
26282
- }
26283
- dispatcher({ loading: false, data: eventChannel, origin: 'event' });
26284
- };
26285
- const onFetch = () => {
26286
- const query = createQuery(getChannel, channelId);
26287
- runQuery(query, ({ loading, data, error, origin, cachedAt }) => {
26288
- if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
26289
- dispatcher({
26290
- data,
26291
- origin,
26292
- loading: false,
26293
- error: new ASCApiError(UNSYNCED_OBJECT_CACHED_AT_MESSAGE, 800800 /* Amity.ClientError.DISALOOW_UNSYNCED_OBJECT */, "error" /* Amity.ErrorLevel.ERROR */),
26294
- });
26295
- isUnsyncedObject = true;
26296
- disposers.forEach(fn => fn());
26297
- }
26298
- else if (!isUnsyncedObject) {
26299
- dispatcher({ loading, data, origin, error });
26300
- }
26301
- if (error) {
26302
- disposers.forEach(fn => fn());
26303
- }
26304
- });
26305
- };
26306
- disposers.push(onChannelUpdated(realtimeRouter), onChannelDeleted(realtimeRouter), onChannelJoined(realtimeRouter), onChannelMuted(realtimeRouter), onMessageCreated(() => null));
26307
- onFetch();
26308
- return () => {
26309
- log(`liveChannel(tmpid: ${timestamp}) > dispose`);
26310
- disposers.forEach(fn => fn());
26311
- };
26298
+ return liveObject(channelId, callback, 'channelId', getChannel, [
26299
+ onChannelUpdated,
26300
+ onChannelDeleted,
26301
+ onChannelJoined,
26302
+ onChannelMuted,
26303
+ () => onMessageCreated(() => null), // watch unread count
26304
+ ]);
26312
26305
  };
26313
26306
 
26314
26307
  /**
@@ -26969,42 +26962,11 @@ const onSubChannelFetched = (callback) => {
26969
26962
  * @category SubChannel Live Object
26970
26963
  */
26971
26964
  const liveSubChannel = (subChannelId, callback) => {
26972
- const { log, cache } = getActiveClient();
26973
- const timestamp = Date.now();
26974
- log(`liveSubChannel(tmpid: ${timestamp}) > listen`);
26975
- if (!cache) {
26976
- console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
26977
- }
26978
- let subChannel;
26979
- const disposers = [];
26980
- const dispatcher = (data) => {
26981
- subChannel = data.data;
26982
- callback(data);
26983
- };
26984
- const realtimeRouter = (eventSubChannel) => {
26985
- if (subChannelId !== eventSubChannel.subChannelId) {
26986
- return;
26987
- }
26988
- if (subChannel && !hasUpdates(subChannel, eventSubChannel)) {
26989
- return;
26990
- }
26991
- dispatcher({ loading: false, data: eventSubChannel, origin: 'event' });
26992
- };
26993
- const onFetch = () => {
26994
- const query = createQuery(getSubChannel, subChannelId);
26995
- runQuery(query, ({ error, data, loading, origin }) => {
26996
- dispatcher({ error, data, loading, origin });
26997
- if (error) {
26998
- disposers.forEach(fn => fn());
26999
- }
27000
- });
27001
- };
27002
- disposers.push(onSubChannelFetched(realtimeRouter), onSubChannelUpdated(realtimeRouter), onSubChannelDeleted(realtimeRouter));
27003
- onFetch();
27004
- return () => {
27005
- log(`liveSubChannel(tmpid: ${timestamp}) > dispose`);
27006
- disposers.forEach(fn => fn());
27007
- };
26965
+ return liveObject(subChannelId, callback, 'subChannelId', getSubChannel, [
26966
+ onSubChannelFetched,
26967
+ onSubChannelUpdated,
26968
+ onSubChannelDeleted,
26969
+ ]);
27008
26970
  };
27009
26971
 
27010
26972
  /**
@@ -27135,55 +27097,16 @@ const onMessageFetched = (callback) => {
27135
27097
  * @category Message Live Object
27136
27098
  */
27137
27099
  const liveMessage = (messageId, callback) => {
27138
- const { log, cache } = getActiveClient();
27139
- const timestamp = Date.now();
27140
- log(`liveMessage(tmpid: ${timestamp}) > listen`);
27141
- if (!cache) {
27142
- console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
27143
- }
27144
- let message;
27145
- let isUnsyncedObject = false;
27146
- const disposers = [];
27147
- const dispatcher = (data) => {
27148
- message = data.data;
27149
- callback(data);
27150
- };
27151
- const realtimeRouter = (eventMessage) => {
27152
- if (messageId !== eventMessage.messageId) {
27153
- return;
27154
- }
27155
- if (message && !hasUpdates(message, eventMessage)) {
27156
- return;
27157
- }
27158
- dispatcher({ loading: false, data: eventMessage, origin: 'event' });
27159
- };
27160
- const onFetch = () => {
27161
- const query = createQuery(getMessage, messageId, true);
27162
- runQuery(query, ({ loading, data, error, origin, cachedAt }) => {
27163
- if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
27164
- dispatcher({
27165
- data,
27166
- origin,
27167
- loading: false,
27168
- error: new ASCApiError(UNSYNCED_OBJECT_CACHED_AT_MESSAGE, 800800 /* Amity.ClientError.DISALOOW_UNSYNCED_OBJECT */, "error" /* Amity.ErrorLevel.ERROR */),
27169
- });
27170
- isUnsyncedObject = true;
27171
- disposers.forEach(fn => fn());
27172
- }
27173
- else if (!isUnsyncedObject) {
27174
- dispatcher({ loading, data, origin, error });
27175
- }
27176
- if (error) {
27177
- disposers.forEach(fn => fn());
27178
- }
27179
- });
27180
- };
27181
- disposers.push(onMessageFetched(realtimeRouter), onMessageUpdated(realtimeRouter), onMessageDeleted(realtimeRouter), onMessageFlagged(realtimeRouter), onMessageUnflagged(realtimeRouter), onMessageFlagCleared(realtimeRouter), onMessageReactionAdded(realtimeRouter), onMessageReactionRemoved(realtimeRouter));
27182
- onFetch();
27183
- return () => {
27184
- log(`liveMessage(tmpid: ${timestamp}) > dispose`);
27185
- disposers.forEach(fn => fn());
27186
- };
27100
+ return liveObject(messageId, callback, 'messageId', getMessage, [
27101
+ onMessageFetched,
27102
+ onMessageUpdated,
27103
+ onMessageDeleted,
27104
+ onMessageFlagged,
27105
+ onMessageUnflagged,
27106
+ onMessageFlagCleared,
27107
+ onMessageReactionAdded,
27108
+ onMessageReactionRemoved,
27109
+ ]);
27187
27110
  };
27188
27111
 
27189
27112
  /**
@@ -27384,6 +27307,30 @@ const createCommunityEventSubscriber = (event, callback) => {
27384
27307
  };
27385
27308
  return createEventSubscriber(client, event, event, filter);
27386
27309
  };
27310
+ /*
27311
+ * verifies membership status
27312
+ */
27313
+ function isMember(membership) {
27314
+ return membership !== 'none';
27315
+ }
27316
+ /*
27317
+ * checks if currently logged in user is part of the community
27318
+ */
27319
+ function isCurrentUserPartOfCommunity(c, m) {
27320
+ const { userId } = getActiveUser();
27321
+ return c.communityId === m.communityId && m.userId === userId;
27322
+ }
27323
+ /*
27324
+ * For mqtt events server will not send user specific data as it's broadcasted
27325
+ * to multiple users. Althought this can be calculated, it's not scalable. Hence
27326
+ * the client SDK needs to calculate this info
27327
+ */
27328
+ function updateMembershipStatus(communities, communityUsers) {
27329
+ return communities.map(c => {
27330
+ const isJoined = communityUsers.some(m => isCurrentUserPartOfCommunity(c, m) && isMember(m.communityMembership));
27331
+ return Object.assign(Object.assign({}, c), { isJoined });
27332
+ });
27333
+ }
27387
27334
  function hasPermission(member, payload, permission) {
27388
27335
  if (member.permissions.some(x => x === permission)) {
27389
27336
  return true;
@@ -27414,7 +27361,15 @@ const createCommunityMemberEventSubscriber = (event, callback) => {
27414
27361
  const client = getActiveClient();
27415
27362
  const filter = (payload) => {
27416
27363
  const communityPayload = unpackCommunityPayload(payload);
27364
+ const { communities } = communityPayload;
27417
27365
  const preparedPayload = prepareMembershipPayload(communityPayload, 'communityUsers');
27366
+ const { communityUsers } = preparedPayload;
27367
+ /*
27368
+ * community.isJoined is not part of the communityMembership payload, and needs
27369
+ * to be calculated based on the communityMembership value
27370
+ */
27371
+ const communitiesWithMembership = updateMembershipStatus(communities, communityUsers);
27372
+ preparedPayload.communities = communitiesWithMembership;
27418
27373
  if (!client.cache) {
27419
27374
  // TODO: here we are missing specific properties here!
27420
27375
  callback(preparedPayload.communities[0], getEventRelatedMember(event, preparedPayload));
@@ -27556,6 +27511,23 @@ const onCommunityUserAdded = (callback) => createCommunityMemberEventSubscriber(
27556
27511
  */
27557
27512
  const onCommunityUserRemoved = (callback) => createCommunityMemberEventSubscriber('community.userRemoved', callback);
27558
27513
 
27514
+ /**
27515
+ * ```js
27516
+ * import { onCommunityUserChanged } from '@amityco/ts-sdk'
27517
+ * const dispose = onCommunityUserChanged((community, member) => {
27518
+ * // ...
27519
+ * })
27520
+ * ```
27521
+ *
27522
+ * Fired when a user has been added or removed from a {@link Amity.Community}
27523
+ *
27524
+ * @param callback The function to call when the event was fired
27525
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
27526
+ *
27527
+ * @category Community Events
27528
+ */
27529
+ const onCommunityUserChanged = (callback) => createCommunityMemberEventSubscriber('community.userChanged', callback);
27530
+
27559
27531
  /**
27560
27532
  * ```js
27561
27533
  * import { onCommunityUserBanned } from '@amityco/ts-sdk'
@@ -27634,6 +27606,122 @@ const observeCommunity = (communityId, callback) => {
27634
27606
  };
27635
27607
  };
27636
27608
 
27609
+ /**
27610
+ * ```js
27611
+ * import { liveCommunities } from '@amityco/ts-sdk'
27612
+ *
27613
+ * let communities = []
27614
+ * const unsub = liveCommunities({
27615
+ * displayName: Amity.Community['displayName'],
27616
+ * }, response => merge(communities, response.data))
27617
+ * ```
27618
+ *
27619
+ * Observe all mutations on a list of {@link Amity.Community}s
27620
+ *
27621
+ * @param params for querying communities
27622
+ * @param callback the function to call when new data are available
27623
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the communities
27624
+ *
27625
+ * @category Community Live Collection
27626
+ */
27627
+ const liveCommunities = (params, callback, config) => {
27628
+ const { log, cache } = getActiveClient();
27629
+ if (!cache) {
27630
+ console.log(ENABLE_CACHE_MESSAGE);
27631
+ }
27632
+ const timestamp = Date.now();
27633
+ log(`liveCommunities(tmpid: ${timestamp}) > listen`);
27634
+ const { limit: queryLimit } = params, queryParams = __rest(params, ["limit"]);
27635
+ const limit = queryLimit !== null && queryLimit !== void 0 ? queryLimit : COLLECTION_DEFAULT_PAGINATION_LIMIT;
27636
+ const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config !== null && config !== void 0 ? config : {};
27637
+ const disposers = [];
27638
+ const cacheKey = ['community', 'collection', {}];
27639
+ const responder = (data) => {
27640
+ var _a, _b;
27641
+ let communities = (_a = data.data
27642
+ .map(communityId => pullFromCache(['community', 'get', communityId]))
27643
+ .filter(Boolean)
27644
+ .map(({ data }) => data)) !== null && _a !== void 0 ? _a : [];
27645
+ communities = filterByPropEquality(communities, 'isDeleted', params.isDeleted);
27646
+ communities = filterByPropEquality(communities, 'displayName', params.displayName);
27647
+ if (params.categoryId) {
27648
+ communities = communities.filter(c => { var _a; return (_a = c.categoryIds) === null || _a === void 0 ? void 0 : _a.includes(params.categoryId); });
27649
+ }
27650
+ if (params.tags) {
27651
+ 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); }); });
27652
+ }
27653
+ if (params.membership === 'member') {
27654
+ communities = filterByPropEquality(communities, 'isJoined', true);
27655
+ }
27656
+ if (params.membership === 'notMember') {
27657
+ communities = filterByPropEquality(communities, 'isJoined', false);
27658
+ }
27659
+ const sortBy = params.sortBy || 'lastCreated';
27660
+ if (sortBy === 'lastCreated' || sortBy === 'firstCreated') {
27661
+ communities = communities.sort(sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated);
27662
+ }
27663
+ /*
27664
+ * The server returns communities with empty | null displayName's first before
27665
+ * returning sorted list of communities with displayNames
27666
+ *
27667
+ * This section needs to be updated as displayNames can be null as well
27668
+ */
27669
+ if (sortBy === 'displayName') {
27670
+ communities = communities
27671
+ // this needs to be aligned with the backend data type
27672
+ .map(c => (c.displayName ? c : Object.assign(Object.assign({}, c), { displayName: '' })))
27673
+ // @ts-ignore
27674
+ .sort(sortByDisplayName);
27675
+ }
27676
+ callback({
27677
+ onNextPage: onFetch,
27678
+ data: communities,
27679
+ hasNextPage: !!((_b = data.params) === null || _b === void 0 ? void 0 : _b.page),
27680
+ loading: data.loading,
27681
+ error: data.error,
27682
+ });
27683
+ };
27684
+ const realtimeRouter = (_) => (community) => {
27685
+ var _a;
27686
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
27687
+ if (!collection)
27688
+ return;
27689
+ /*
27690
+ * Simply update collection and let responder decide what to do with data
27691
+ */
27692
+ collection.data = [...new Set([community.communityId, ...collection.data])];
27693
+ pushToCache(cacheKey, collection);
27694
+ responder(collection);
27695
+ };
27696
+ const onFetch = () => {
27697
+ var _a, _b, _c;
27698
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
27699
+ const communities = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
27700
+ if (communities.length > 0 && !(collection === null || collection === void 0 ? void 0 : collection.params.page))
27701
+ return;
27702
+ 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 } }));
27703
+ runQuery(query, ({ data: result, error, loading, nextPage: page }) => {
27704
+ const data = {
27705
+ loading,
27706
+ error,
27707
+ params: { page },
27708
+ data: communities,
27709
+ };
27710
+ if (result) {
27711
+ data.data = [...new Set([...communities, ...result.map(getResolver('community'))])];
27712
+ }
27713
+ pushToCache(cacheKey, data);
27714
+ responder(data);
27715
+ }, queryOptions(policy));
27716
+ };
27717
+ disposers.push(onCommunityCreated(realtimeRouter()), onCommunityDeleted(realtimeRouter()), onCommunityUpdated(realtimeRouter()), onCommunityJoined(realtimeRouter()), onCommunityLeft(realtimeRouter()), onCommunityUserChanged(realtimeRouter()));
27718
+ onFetch();
27719
+ return () => {
27720
+ log(`liveCommunities(tmpid: ${timestamp}) > dispose`);
27721
+ disposers.forEach(fn => fn());
27722
+ };
27723
+ };
27724
+
27637
27725
  /**
27638
27726
  * ```js
27639
27727
  * import { queryCategories } from '@amityco/ts-sdk'
@@ -27762,6 +27850,96 @@ getCategory.locally = (categoryId) => {
27762
27850
  };
27763
27851
  };
27764
27852
 
27853
+ /**
27854
+ * ```js
27855
+ * import { liveCategories } from '@amityco/ts-sdk'
27856
+ *
27857
+ * let categories = []
27858
+ * const unsub = liveCategories({}, response => merge(categories, response.data))
27859
+ * ```
27860
+ *
27861
+ * Observe all mutations on a list of {@link Amity.Category}s
27862
+ *
27863
+ * @param params for querying categories
27864
+ * @param callback the function to call when new data are available
27865
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the categories
27866
+ *
27867
+ * @category Category Live Collection
27868
+ */
27869
+ const liveCategories = (params, callback, config) => {
27870
+ const { log, cache } = getActiveClient();
27871
+ if (!cache) {
27872
+ console.log(ENABLE_CACHE_MESSAGE);
27873
+ }
27874
+ const timestamp = Date.now();
27875
+ log(`liveCategories(tmpid: ${timestamp}) > listen`);
27876
+ const { limit: queryLimit } = params, queryParams = __rest(params, ["limit"]);
27877
+ const limit = queryLimit !== null && queryLimit !== void 0 ? queryLimit : COLLECTION_DEFAULT_PAGINATION_LIMIT;
27878
+ const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config !== null && config !== void 0 ? config : {};
27879
+ const disposers = [];
27880
+ const cacheKey = ['category', 'collection', {}];
27881
+ const responder = (data) => {
27882
+ var _a, _b;
27883
+ let categories = (_a = data.data
27884
+ .map(categoryId => pullFromCache(['category', 'get', categoryId]))
27885
+ .filter(Boolean)
27886
+ .map(({ data }) => data)) !== null && _a !== void 0 ? _a : [];
27887
+ categories = filterByPropEquality(categories, 'isDeleted', params.isDeleted);
27888
+ switch (params.sortBy) {
27889
+ case 'firstCreated':
27890
+ categories = categories.sort(sortByFirstCreated);
27891
+ break;
27892
+ case 'lastCreated':
27893
+ categories = categories.sort(sortByLastCreated);
27894
+ break;
27895
+ default:
27896
+ categories = categories.sort(sortByName);
27897
+ }
27898
+ callback({
27899
+ onNextPage: onFetch,
27900
+ data: categories,
27901
+ hasNextPage: !!((_b = data.params) === null || _b === void 0 ? void 0 : _b.page),
27902
+ loading: data.loading,
27903
+ error: data.error,
27904
+ });
27905
+ };
27906
+ /*
27907
+ * const realtimeRouter = () => {
27908
+ * @TODO: At the time of creating this method category does not have any
27909
+ * observers
27910
+ *};
27911
+ */
27912
+ const onFetch = () => {
27913
+ var _a, _b, _c;
27914
+ const collection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
27915
+ const categories = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
27916
+ if (categories.length > 0 && !(collection === null || collection === void 0 ? void 0 : collection.params.page))
27917
+ return;
27918
+ 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 } }));
27919
+ runQuery(query, ({ data: result, error, loading, nextPage: page }) => {
27920
+ const data = {
27921
+ loading,
27922
+ error,
27923
+ params: { page },
27924
+ data: categories,
27925
+ };
27926
+ if (result) {
27927
+ data.data = [...new Set([...categories, ...result.map(getResolver('category'))])];
27928
+ }
27929
+ pushToCache(cacheKey, data);
27930
+ responder(data);
27931
+ }, queryOptions(policy));
27932
+ };
27933
+ disposers.push(() => {
27934
+ // @TODO -> update once observers added
27935
+ });
27936
+ onFetch();
27937
+ return () => {
27938
+ log(`liveCategories(tmpid: ${timestamp}) > dispose`);
27939
+ disposers.forEach(fn => fn());
27940
+ };
27941
+ };
27942
+
27765
27943
  /**
27766
27944
  * ```js
27767
27945
  * import { queryGlobalFeed } from '@amityco/ts-sdk'
@@ -28686,6 +28864,38 @@ const observePost = (postId, callback, policy = 'cache_then_server') => {
28686
28864
  };
28687
28865
  };
28688
28866
 
28867
+ /**
28868
+ * ```js
28869
+ * import { livePost } from '@amityco/ts-sdk';
28870
+ *
28871
+ * let post;
28872
+ *
28873
+ * const unsubscribe = livePost(postId, response => {
28874
+ * post = response.data;
28875
+ * });
28876
+ * ```
28877
+ *
28878
+ * Observe all mutation on a given {@link Amity.Post}
28879
+ *
28880
+ * @param postId the ID of the message to observe
28881
+ * @param callback the function to call when new data are available
28882
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the sub channel
28883
+ *
28884
+ * @category Post Live Object
28885
+ */
28886
+ const livePost = (postId, callback) => {
28887
+ return liveObject(postId, callback, 'postId', getPost, [
28888
+ onPostApproved,
28889
+ onPostDeclined,
28890
+ onPostDeleted,
28891
+ onPostFlagged,
28892
+ onPostReactionAdded,
28893
+ onPostReactionRemoved,
28894
+ onPostUnflagged,
28895
+ onPostUpdated,
28896
+ ]);
28897
+ };
28898
+
28689
28899
  /**
28690
28900
  * ```js
28691
28901
  * import { livePosts } from '@amityco/ts-sdk'
@@ -28881,6 +29091,36 @@ const observeComment = (commentId, callback, policy = 'cache_then_server') => {
28881
29091
  };
28882
29092
  };
28883
29093
 
29094
+ /**
29095
+ * ```js
29096
+ * import { liveComment } from '@amityco/ts-sdk';
29097
+ *
29098
+ * let comment;
29099
+ *
29100
+ * const unsubscribe = liveComment(commentId, response => {
29101
+ * comment = response.data;
29102
+ * });
29103
+ * ```
29104
+ *
29105
+ * Observe all mutation on a given {@link Amity.Comment}
29106
+ *
29107
+ * @param commentId the ID of the comment to observe
29108
+ * @param callback the function to call when new data are available
29109
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the comment
29110
+ *
29111
+ * @category Comment Live Object
29112
+ */
29113
+ const liveComment = (commentId, callback) => {
29114
+ return liveObject(commentId, callback, 'commentId', getComment, [
29115
+ onCommentDeleted,
29116
+ onCommentFlagged,
29117
+ onCommentReactionAdded,
29118
+ onCommentReactionRemoved,
29119
+ onCommentUnflagged,
29120
+ onCommentUpdated,
29121
+ ]);
29122
+ };
29123
+
28884
29124
  /**
28885
29125
  * ```js
28886
29126
  * import { liveComments } from '@amityco/ts-sdk'
@@ -29678,14 +29918,18 @@ exports.joinChannel = joinChannel;
29678
29918
  exports.joinCommunity = joinCommunity;
29679
29919
  exports.leaveChannel = leaveChannel;
29680
29920
  exports.leaveCommunity = leaveCommunity;
29921
+ exports.liveCategories = liveCategories;
29681
29922
  exports.liveChannel = liveChannel;
29682
29923
  exports.liveChannelMembers = liveChannelMembers;
29683
29924
  exports.liveChannels = liveChannels;
29925
+ exports.liveComment = liveComment;
29684
29926
  exports.liveComments = liveComments;
29927
+ exports.liveCommunities = liveCommunities;
29685
29928
  exports.liveFollowers = liveFollowers;
29686
29929
  exports.liveFollowings = liveFollowings;
29687
29930
  exports.liveMessage = liveMessage;
29688
29931
  exports.liveMessages = liveMessages;
29932
+ exports.livePost = livePost;
29689
29933
  exports.livePosts = livePosts;
29690
29934
  exports.liveReactions = liveReactions;
29691
29935
  exports.liveSubChannel = liveSubChannel;
@@ -29733,6 +29977,7 @@ exports.onCommunityLeft = onCommunityLeft;
29733
29977
  exports.onCommunityUpdated = onCommunityUpdated;
29734
29978
  exports.onCommunityUserAdded = onCommunityUserAdded;
29735
29979
  exports.onCommunityUserBanned = onCommunityUserBanned;
29980
+ exports.onCommunityUserChanged = onCommunityUserChanged;
29736
29981
  exports.onCommunityUserRemoved = onCommunityUserRemoved;
29737
29982
  exports.onCommunityUserUnbanned = onCommunityUserUnbanned;
29738
29983
  exports.onConnectionError = onConnectionError;
@@ -29812,6 +30057,7 @@ exports.sortByDisplayName = sortByDisplayName;
29812
30057
  exports.sortByFirstCreated = sortByFirstCreated;
29813
30058
  exports.sortByLastActivity = sortByLastActivity;
29814
30059
  exports.sortByLastCreated = sortByLastCreated;
30060
+ exports.sortByName = sortByName;
29815
30061
  exports.sortBySegmentNumber = sortBySegmentNumber;
29816
30062
  exports.startReading = startReading;
29817
30063
  exports.stopReading = stopReading;