@amityco/ts-sdk 6.17.1-e9b6af1.0 → 6.17.2-ea577e1.0

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 (86) hide show
  1. package/dist/@types/core/payload.d.ts +1 -0
  2. package/dist/@types/core/payload.d.ts.map +1 -1
  3. package/dist/@types/core/permissions.d.ts +5 -0
  4. package/dist/@types/core/permissions.d.ts.map +1 -1
  5. package/dist/@types/domains/client.d.ts +1 -0
  6. package/dist/@types/domains/client.d.ts.map +1 -1
  7. package/dist/@types/domains/story.d.ts +4 -0
  8. package/dist/@types/domains/story.d.ts.map +1 -1
  9. package/dist/channelRepository/observers/getChannel.d.ts.map +1 -1
  10. package/dist/channelRepository/observers/getChannels/ChannelLiveCollectionController.d.ts.map +1 -1
  11. package/dist/client/api/createClient.d.ts.map +1 -1
  12. package/dist/client/observers/getTotalUnreadCount.d.ts.map +1 -1
  13. package/dist/client/observers/getUserUnread.d.ts.map +1 -1
  14. package/dist/client/utils/hasPermission/checkChannelPermission.d.ts +2 -0
  15. package/dist/client/utils/hasPermission/checkChannelPermission.d.ts.map +1 -0
  16. package/dist/client/utils/hasPermission/checkCommunityPermission.d.ts +2 -0
  17. package/dist/client/utils/hasPermission/checkCommunityPermission.d.ts.map +1 -0
  18. package/dist/client/utils/hasPermission/checkUserPermission.d.ts +2 -0
  19. package/dist/client/utils/hasPermission/checkUserPermission.d.ts.map +1 -0
  20. package/dist/client/utils/hasPermission/hasPermission.d.ts +6 -0
  21. package/dist/client/utils/hasPermission/hasPermission.d.ts.map +1 -0
  22. package/dist/client/utils/hasPermission/index.d.ts +2 -0
  23. package/dist/client/utils/hasPermission/index.d.ts.map +1 -0
  24. package/dist/client/utils/markerSyncEngine.d.ts.map +1 -1
  25. package/dist/index.cjs.js +510 -70
  26. package/dist/index.esm.js +510 -71
  27. package/dist/index.umd.js +4 -4
  28. package/dist/marker/api/getUserMarker.d.ts +1 -1
  29. package/dist/marker/api/getUserMarker.d.ts.map +1 -1
  30. package/dist/marker/events/onChannelMarkerFetched.d.ts.map +1 -1
  31. package/dist/marker/events/onUserMarkerFetched.d.ts +2 -1
  32. package/dist/marker/events/onUserMarkerFetched.d.ts.map +1 -1
  33. package/dist/messageRepository/events/onMessageCreated.d.ts +2 -1
  34. package/dist/messageRepository/events/onMessageCreated.d.ts.map +1 -1
  35. package/dist/messageRepository/observers/observeMessages.d.ts.map +1 -1
  36. package/dist/messageRepository/utils/prepareMessagePayload.d.ts.map +1 -1
  37. package/dist/storyRepository/constants.d.ts +1 -0
  38. package/dist/storyRepository/constants.d.ts.map +1 -1
  39. package/dist/storyRepository/observers/getStoriesByTargetIds/StoryLiveCollectionController.d.ts +14 -0
  40. package/dist/storyRepository/observers/getStoriesByTargetIds/StoryLiveCollectionController.d.ts.map +1 -0
  41. package/dist/storyRepository/observers/getStoriesByTargetIds/StoryPaginationNoPageController.d.ts +5 -0
  42. package/dist/storyRepository/observers/getStoriesByTargetIds/StoryPaginationNoPageController.d.ts.map +1 -0
  43. package/dist/storyRepository/observers/getStoriesByTargetIds/StoryQueryStreamController.d.ts +16 -0
  44. package/dist/storyRepository/observers/getStoriesByTargetIds/StoryQueryStreamController.d.ts.map +1 -0
  45. package/dist/storyRepository/observers/getStoriesByTargetIds/getStoriesByTargetIds.d.ts +5 -0
  46. package/dist/storyRepository/observers/getStoriesByTargetIds/getStoriesByTargetIds.d.ts.map +1 -0
  47. package/dist/storyRepository/observers/getStoriesByTargetIds/index.d.ts +2 -0
  48. package/dist/storyRepository/observers/getStoriesByTargetIds/index.d.ts.map +1 -0
  49. package/dist/storyRepository/observers/index.d.ts +1 -0
  50. package/dist/storyRepository/observers/index.d.ts.map +1 -1
  51. package/dist/subChannelRepository/observers/getSubChannel.d.ts.map +1 -1
  52. package/dist/subChannelRepository/observers/getSubChannels/SubChannelLiveCollectionController.d.ts.map +1 -1
  53. package/package.json +1 -1
  54. package/src/@types/core/payload.ts +1 -0
  55. package/src/@types/core/permissions.ts +6 -0
  56. package/src/@types/domains/client.ts +2 -0
  57. package/src/@types/domains/story.ts +5 -0
  58. package/src/channelRepository/observers/getChannel.ts +30 -2
  59. package/src/channelRepository/observers/getChannels/ChannelLiveCollectionController.ts +65 -3
  60. package/src/client/api/createClient.ts +3 -1
  61. package/src/client/observers/getTotalUnreadCount.ts +14 -4
  62. package/src/client/observers/getUserUnread.ts +95 -11
  63. package/src/client/utils/hasPermission/checkChannelPermission.ts +22 -0
  64. package/src/client/utils/hasPermission/checkCommunityPermission.ts +22 -0
  65. package/src/client/utils/hasPermission/checkUserPermission.ts +12 -0
  66. package/src/client/utils/hasPermission/hasPermission.ts +18 -0
  67. package/src/client/utils/hasPermission/index.ts +1 -0
  68. package/src/client/utils/markerSyncEngine.ts +46 -32
  69. package/src/marker/api/getUserMarker.ts +15 -4
  70. package/src/marker/events/onChannelMarkerFetched.ts +3 -1
  71. package/src/marker/events/onUserMarkerFetched.ts +17 -0
  72. package/src/messageRepository/api/tests/createMessage.test.ts +4 -4
  73. package/src/messageRepository/events/onMessageCreated.ts +20 -8
  74. package/src/messageRepository/events/tests/events.test.ts +2 -2
  75. package/src/messageRepository/observers/getMessages/MessageLiveCollectionController.ts +2 -2
  76. package/src/messageRepository/observers/observeMessages.ts +8 -2
  77. package/src/messageRepository/utils/prepareMessagePayload.ts +14 -4
  78. package/src/storyRepository/constants.ts +1 -0
  79. package/src/storyRepository/observers/getStoriesByTargetIds/StoryLiveCollectionController.ts +113 -0
  80. package/src/storyRepository/observers/getStoriesByTargetIds/StoryPaginationNoPageController.ts +18 -0
  81. package/src/storyRepository/observers/getStoriesByTargetIds/StoryQueryStreamController.ts +97 -0
  82. package/src/storyRepository/observers/getStoriesByTargetIds/getStoriesByTargetIds.ts +32 -0
  83. package/src/storyRepository/observers/getStoriesByTargetIds/index.ts +1 -0
  84. package/src/storyRepository/observers/index.ts +1 -0
  85. package/src/subChannelRepository/observers/getSubChannel.ts +35 -2
  86. package/src/subChannelRepository/observers/getSubChannels/SubChannelLiveCollectionController.ts +53 -2
package/dist/index.cjs.js CHANGED
@@ -98,8 +98,8 @@ const PostContentType = Object.freeze({
98
98
 
99
99
  function getVersion() {
100
100
  try {
101
- // the string ''v6.17.0-cjs'' should be replaced by actual value by @rollup/plugin-replace
102
- return 'v6.17.0-cjs';
101
+ // the string ''v6.17.1-cjs'' should be replaced by actual value by @rollup/plugin-replace
102
+ return 'v6.17.1-cjs';
103
103
  }
104
104
  catch (error) {
105
105
  return '__dev__';
@@ -5826,7 +5826,14 @@ const getUserMarker = async () => {
5826
5826
  if (client.cache)
5827
5827
  ingestInCache({ userMarkers }, { cachedAt });
5828
5828
  fireEvent('local.userMarker.fetched', { userMarkers });
5829
- return { data: userMarkers[0], cachedAt };
5829
+ const latestUserMarker = userMarkers.reduce((maxUserMarker, userMarker) => {
5830
+ if (maxUserMarker == null ||
5831
+ new Date(maxUserMarker.lastSyncAt).getTime() < new Date(userMarker.lastSyncAt).getTime()) {
5832
+ return userMarker;
5833
+ }
5834
+ return maxUserMarker;
5835
+ }, null);
5836
+ return { data: latestUserMarker, cachedAt };
5830
5837
  };
5831
5838
 
5832
5839
  /** @hidden */
@@ -6001,17 +6008,25 @@ const preUpdateMessageCache = (rawPayload) => {
6001
6008
  messages: rawPayload.messages.map(message => convertFromRaw(message, rawPayload.reactions)),
6002
6009
  });
6003
6010
  };
6011
+ const DEBOUNCE_TIME = 2000;
6012
+ const currentDebounceMap = {};
6004
6013
  const prepareMessagePayload = async (payload, event) => {
6005
6014
  const markerIds = payload.messages.map(({ messageId }) => messageId);
6006
6015
  if (markerIds.length > 0) {
6007
6016
  // since the get markers method requires a channel cache to function with the reducer.
6008
6017
  preUpdateMessageCache(payload);
6009
- try {
6010
- await getMessageMarkers(markerIds);
6011
- }
6012
- catch (e) {
6013
- // empty block (from the spec, allow marker fetch to fail without having to do anything)
6018
+ const markerIdsKey = markerIds.join('');
6019
+ if (currentDebounceMap[markerIdsKey]) {
6020
+ clearTimeout(currentDebounceMap[markerIdsKey]);
6014
6021
  }
6022
+ currentDebounceMap[markerIdsKey] = setTimeout(() => {
6023
+ try {
6024
+ getMessageMarkers(markerIds);
6025
+ }
6026
+ catch (_error) {
6027
+ // do nothing
6028
+ }
6029
+ }, DEBOUNCE_TIME);
6015
6030
  }
6016
6031
  const { messageFeeds } = payload, restPayload = __rest(payload, ["messageFeeds"]);
6017
6032
  // upsert messageFeeds to subchannel cache because messageFeeds from event payload not include messagePreviewId
@@ -6617,43 +6632,92 @@ const initializeMessagePreviewSetting = async () => {
6617
6632
 
6618
6633
  /**
6619
6634
  * ```js
6620
- * import { getFeedSettings } from '@amityco/ts-sdk'
6621
- * const feedSettings = await getFeedSettings()
6622
- * const postFeedSetting = feedSettings.post
6635
+ * import { getSocialSettings } from '@amityco/ts-sdk'
6636
+ * const socialSettings = await getSocialSettings()
6623
6637
  * ```
6624
6638
  *
6625
- * Fetches a {@link Amity.FeedSettings} object
6639
+ * Fetches a {@link Amity.SocialSettings} object
6626
6640
  *
6627
- * @returns A Promise of {@link Amity.FeedSettings} object
6641
+ * @returns A Promise of {@link Amity.SocialSettings} object
6628
6642
  *
6629
6643
  * @category Client API
6630
6644
  * @async
6631
6645
  */
6632
- const getFeedSettings = async () => {
6646
+ const getSocialSettings = async () => {
6633
6647
  const client = getActiveClient();
6634
- const { data } = await client.http.get(`/api/v3/network-settings/feed-setting`);
6635
- return Object.fromEntries(data.feedSettings.map(({ feedType, contentSettings }) => {
6636
- return [feedType, contentSettings];
6637
- }));
6648
+ const { data } = await client.http.get(`/api/v3/network-settings/social`);
6649
+ return data.socialNetworkSetting;
6650
+ };
6651
+
6652
+ const checkUserPermission = (userId, permission) => {
6653
+ var _a;
6654
+ const user = (_a = pullFromCache(['users', 'get', userId])) === null || _a === void 0 ? void 0 : _a.data;
6655
+ if (!user)
6656
+ return false;
6657
+ return user.permissions.some(x => x === permission);
6658
+ };
6659
+
6660
+ const checkCommunityPermission = (userId, permission, communityId) => {
6661
+ var _a;
6662
+ if (!userId)
6663
+ return false;
6664
+ const member = (_a = pullFromCache([
6665
+ 'communityUsers',
6666
+ 'get',
6667
+ `${communityId}#${userId}`,
6668
+ ])) === null || _a === void 0 ? void 0 : _a.data;
6669
+ if (!member)
6670
+ return false;
6671
+ if (member.permissions.some(x => x === permission))
6672
+ return true;
6673
+ return checkUserPermission(userId, permission);
6674
+ };
6675
+
6676
+ const checkChannelPermission = (userId, permission, channelId) => {
6677
+ var _a;
6678
+ if (!userId)
6679
+ return false;
6680
+ const member = (_a = pullFromCache([
6681
+ 'channelUsers',
6682
+ 'get',
6683
+ `${channelId}#${userId}`,
6684
+ ])) === null || _a === void 0 ? void 0 : _a.data;
6685
+ if (!member)
6686
+ return false;
6687
+ if (member.permissions.some(x => x === permission))
6688
+ return true;
6689
+ return checkUserPermission(userId, permission);
6690
+ };
6691
+
6692
+ const hasPermission$1 = (permission) => {
6693
+ const { userId } = getActiveClient();
6694
+ return {
6695
+ currentUser: () => checkUserPermission(userId, permission),
6696
+ community: (communityId) => checkCommunityPermission(userId, permission, communityId),
6697
+ channel: (channelId) => checkChannelPermission(userId, permission, channelId),
6698
+ };
6638
6699
  };
6639
6700
 
6640
6701
  /**
6641
6702
  * ```js
6642
- * import { getSocialSettings } from '@amityco/ts-sdk'
6643
- * const socialSettings = await getSocialSettings()
6703
+ * import { getFeedSettings } from '@amityco/ts-sdk'
6704
+ * const feedSettings = await getFeedSettings()
6705
+ * const postFeedSetting = feedSettings.post
6644
6706
  * ```
6645
6707
  *
6646
- * Fetches a {@link Amity.SocialSettings} object
6708
+ * Fetches a {@link Amity.FeedSettings} object
6647
6709
  *
6648
- * @returns A Promise of {@link Amity.SocialSettings} object
6710
+ * @returns A Promise of {@link Amity.FeedSettings} object
6649
6711
  *
6650
6712
  * @category Client API
6651
6713
  * @async
6652
6714
  */
6653
- const getSocialSettings = async () => {
6715
+ const getFeedSettings = async () => {
6654
6716
  const client = getActiveClient();
6655
- const { data } = await client.http.get(`/api/v3/network-settings/social`);
6656
- return data.socialNetworkSetting;
6717
+ const { data } = await client.http.get(`/api/v3/network-settings/feed-setting`);
6718
+ return Object.fromEntries(data.feedSettings.map(({ feedType, contentSettings }) => {
6719
+ return [feedType, contentSettings];
6720
+ }));
6657
6721
  };
6658
6722
 
6659
6723
  /*
@@ -7358,6 +7422,7 @@ const createClient = (apiKey, apiRegion = API_REGIONS.SG, { debugSession = DEFAU
7358
7422
  sessionState,
7359
7423
  accessTokenExpiryWatcher,
7360
7424
  sessionHandler,
7425
+ hasPermission: hasPermission$1,
7361
7426
  getFeedSettings,
7362
7427
  getSocialSettings,
7363
7428
  getMessagePreviewSetting,
@@ -7452,7 +7517,9 @@ const markerSync = async (deviceLastSyncAt) => {
7452
7517
  const onChannelMarkerFetched = (callback) => {
7453
7518
  const client = getActiveClient();
7454
7519
  const filter = (payload) => {
7455
- callback(payload.userEntityMarkers[0]);
7520
+ payload.userEntityMarkers.forEach(marker => {
7521
+ callback(marker);
7522
+ });
7456
7523
  };
7457
7524
  return createEventSubscriber(client, 'channelMarker/onChannelMarkerFetched', 'local.channelMarker.fetched', filter);
7458
7525
  };
@@ -7566,6 +7633,13 @@ const onFeedMarkerUpdated = (callback) => {
7566
7633
  * @category UserMarker Events
7567
7634
  */
7568
7635
  const onUserMarkerFetched = (callback) => {
7636
+ const client = getActiveClient();
7637
+ const filter = (payload) => {
7638
+ callback(payload.userMarkers);
7639
+ };
7640
+ return createEventSubscriber(client, 'userMarker/onUserMarkerFetched', 'local.userMarker.fetched', filter);
7641
+ };
7642
+ const onUserMarkerFetchedLegacy = (callback) => {
7569
7643
  const client = getActiveClient();
7570
7644
  const filter = (payload) => {
7571
7645
  callback(payload.userMarkers[0]);
@@ -7821,7 +7895,10 @@ const getTotalUnreadCount = (callback) => {
7821
7895
  if (!userId)
7822
7896
  throw new ASCError('The _id has not been defined in ActiveUser', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
7823
7897
  const callbackDataSelector = (data) => { var _a; return (_a = data === null || data === void 0 ? void 0 : data.unreadCount) !== null && _a !== void 0 ? _a : 0; };
7824
- return liveObject(userId, callback, 'userId', getUserMarker, [onUserMarkerFetched], {
7898
+ return liveObject(userId, callback, 'userId', async () => {
7899
+ const { data: userMarker, cachedAt } = await getUserMarker();
7900
+ return { data: userMarker, cachedAt };
7901
+ }, [onUserMarkerFetchedLegacy], {
7825
7902
  callbackDataSelector,
7826
7903
  });
7827
7904
  };
@@ -7847,16 +7924,77 @@ const getUserUnread = (callback) => {
7847
7924
  const { _id: userId } = getActiveUser();
7848
7925
  if (!userId)
7849
7926
  throw new ASCError('The _id has not been defined in ActiveUser', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
7850
- const callbackDataSelector = (data) => {
7927
+ const { log, cache } = getActiveClient();
7928
+ if (!cache) {
7929
+ console.log('For using Live Object feature you need to enable Cache!');
7930
+ }
7931
+ const timestamp = Date.now();
7932
+ log(`liveUserUnread(tmpid: ${timestamp}) > listen`);
7933
+ const disposers = [];
7934
+ let isUnsyncedModel = false; // for messages
7935
+ const dispatcher = (data) => {
7936
+ const userUnread = data.data;
7937
+ callback({
7938
+ data: {
7939
+ hasMentioned: userUnread.hasMentioned,
7940
+ unreadCount: userUnread.unreadCount,
7941
+ },
7942
+ loading: data.loading,
7943
+ error: data.error,
7944
+ });
7945
+ };
7946
+ const realtimeRouter = (userMarkers) => {
7851
7947
  var _a;
7852
- return {
7853
- unreadCount: (_a = data === null || data === void 0 ? void 0 : data.unreadCount) !== null && _a !== void 0 ? _a : 0,
7854
- hasMentioned: !!(data === null || data === void 0 ? void 0 : data.hasMentioned),
7855
- };
7948
+ const filterUserMarkers = userMarkers.filter(userMarker => userId === userMarker.userId);
7949
+ const latestUserMarker = filterUserMarkers.reduce((currentMaxUserMarker, userMarker) => {
7950
+ if (currentMaxUserMarker == null ||
7951
+ new Date(userMarker.lastSyncAt).getTime() >
7952
+ new Date(currentMaxUserMarker.lastSyncAt).getTime()) {
7953
+ return userMarker;
7954
+ }
7955
+ return currentMaxUserMarker;
7956
+ }, null);
7957
+ dispatcher({
7958
+ loading: false,
7959
+ data: {
7960
+ unreadCount: (_a = latestUserMarker === null || latestUserMarker === void 0 ? void 0 : latestUserMarker.unreadCount) !== null && _a !== void 0 ? _a : 0,
7961
+ hasMentioned: filterUserMarkers.some(userMarker => !!userMarker.hasMentioned),
7962
+ },
7963
+ });
7964
+ };
7965
+ function isAmityUserMarkerData(data) {
7966
+ if (data == null)
7967
+ return false;
7968
+ return data.data != null;
7969
+ }
7970
+ const onFetch = () => {
7971
+ const query = createQuery(getUserMarker);
7972
+ runQuery(query, ({ error, data, loading, origin, cachedAt }) => {
7973
+ if (!isAmityUserMarkerData(data))
7974
+ return;
7975
+ if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
7976
+ dispatcher({
7977
+ data,
7978
+ origin,
7979
+ loading: false,
7980
+ error: new ASCApiError(UNSYNCED_OBJECT_CACHED_AT_MESSAGE, 800800 /* Amity.ClientError.DISALOOW_UNSYNCED_OBJECT */, "error" /* Amity.ErrorLevel.ERROR */),
7981
+ });
7982
+ isUnsyncedModel = true;
7983
+ disposers.forEach(fn => fn());
7984
+ }
7985
+ else if (!isUnsyncedModel) {
7986
+ dispatcher({ loading, data, origin, error });
7987
+ }
7988
+ if (error) {
7989
+ disposers.forEach(fn => fn());
7990
+ }
7991
+ });
7992
+ };
7993
+ disposers.push(onUserMarkerFetched(userMarkers => realtimeRouter(userMarkers)));
7994
+ onFetch();
7995
+ return () => {
7996
+ disposers.forEach(fn => fn());
7856
7997
  };
7857
- return liveObject(userId, callback, 'userId', getUserMarker, [onUserMarkerFetched], {
7858
- callbackDataSelector,
7859
- });
7860
7998
  };
7861
7999
 
7862
8000
  /**
@@ -8167,21 +8305,30 @@ const onUserMarkerSync = (callback) => {
8167
8305
  *
8168
8306
  * @category Message Events
8169
8307
  */
8170
- const onMessageCreated = (callback, local = true) => {
8308
+ const onMessageCreatedMqtt = (callback) => {
8171
8309
  const client = getActiveClient();
8172
8310
  const filter = async (rawPayload) => {
8173
8311
  const payload = await prepareMessagePayload(rawPayload);
8174
- const message = payload.messages[0];
8175
8312
  // Update in cache
8176
8313
  ingestInCache(payload);
8177
- callback(message);
8314
+ payload.messages.forEach(message => {
8315
+ callback(message);
8316
+ });
8178
8317
  };
8179
8318
  const disposers = [
8180
8319
  createEventSubscriber(client, 'message/onMessageCreated', 'message.created', filter),
8181
8320
  ];
8182
- if (local) {
8183
- createEventSubscriber(client, 'message/onMessageCreated', 'local.message.created', payload => callback(payload.messages[0]));
8184
- }
8321
+ return () => {
8322
+ disposers.forEach(fn => fn());
8323
+ };
8324
+ };
8325
+ const onMessageCreatedLocal = (callback) => {
8326
+ const client = getActiveClient();
8327
+ const disposers = [
8328
+ createEventSubscriber(client, 'message/onMessageCreated', 'local.message.created', payload => payload.messages.forEach(message => {
8329
+ callback(message);
8330
+ })),
8331
+ ];
8185
8332
  return () => {
8186
8333
  disposers.forEach(fn => fn());
8187
8334
  };
@@ -8495,18 +8642,22 @@ let isWaitingForResponse = false;
8495
8642
  let deviceLastSyncAt = null;
8496
8643
  const getDeviceLastSyncAt = () => {
8497
8644
  if (deviceLastSyncAt == null) {
8498
- return new Date().toISOString();
8645
+ return new Date();
8499
8646
  }
8500
8647
  return deviceLastSyncAt;
8501
8648
  };
8502
8649
  const saveDeviceLastSyncAt = (lastSyncAt) => {
8503
- if (!deviceLastSyncAt || new Date(lastSyncAt).getTime() > new Date(deviceLastSyncAt).getTime()) {
8650
+ if (lastSyncAt == null)
8651
+ return;
8652
+ if (!deviceLastSyncAt || lastSyncAt.getTime() > deviceLastSyncAt.getTime()) {
8504
8653
  deviceLastSyncAt = lastSyncAt;
8505
8654
  }
8506
8655
  };
8507
8656
  const fetchDeviceLastSyncAt = async () => {
8508
8657
  const { data: userMarker } = await getUserMarker();
8509
- saveDeviceLastSyncAt(userMarker.lastSyncAt);
8658
+ if (userMarker == null)
8659
+ return;
8660
+ saveDeviceLastSyncAt(new Date(userMarker.lastSyncAt));
8510
8661
  };
8511
8662
  /**
8512
8663
  * list of conditions that make timer still trigger the syncing process.
@@ -8544,18 +8695,33 @@ const markerSyncTrigger = async () => {
8544
8695
  // no event that require to call marker sync API
8545
8696
  return;
8546
8697
  }
8547
- isWaitingForResponse = true;
8548
- // any past events are considered processed here.
8549
- // however during waiting for the response, RTE could add the new message event;
8550
- // which will make the engine trigger another call next round.
8551
- events = [];
8552
- const response = await markerSync(getDeviceLastSyncAt());
8553
- saveDeviceLastSyncAt(response.data.userMarkers[0].lastSyncAt);
8554
- if (response.hasMore) {
8555
- events.push("has_more" /* Amity.MarkerSyncEvent.HAS_MORE */);
8556
- }
8557
- // eslint-disable-next-line require-atomic-updates
8558
- isWaitingForResponse = false;
8698
+ try {
8699
+ isWaitingForResponse = true;
8700
+ // any past events are considered processed here.
8701
+ // however during waiting for the response, RTE could add the new message event;
8702
+ // which will make the engine trigger another call next round.
8703
+ events = [];
8704
+ const response = await markerSync(getDeviceLastSyncAt().toISOString());
8705
+ const latestLastSyncAt = response.data.userMarkers.reduce((maxLastSyncAt, userMarker) => {
8706
+ if (maxLastSyncAt == null ||
8707
+ maxLastSyncAt.getTime() < new Date(userMarker.lastSyncAt).getTime()) {
8708
+ return new Date(userMarker.lastSyncAt);
8709
+ }
8710
+ return maxLastSyncAt;
8711
+ }, null);
8712
+ saveDeviceLastSyncAt(latestLastSyncAt);
8713
+ if (response.hasMore) {
8714
+ events.push("has_more" /* Amity.MarkerSyncEvent.HAS_MORE */);
8715
+ }
8716
+ }
8717
+ catch (_a) {
8718
+ // prevent sync from stopping
8719
+ }
8720
+ finally {
8721
+ if (isWaitingForResponse) {
8722
+ isWaitingForResponse = false;
8723
+ }
8724
+ }
8559
8725
  };
8560
8726
  const registerEventListeners = () => {
8561
8727
  if (disposers.length > 0) {
@@ -8569,14 +8735,11 @@ const registerEventListeners = () => {
8569
8735
  disposers.push(onOnline(() => {
8570
8736
  // should add RESUME to the event to trigger marker syncing again
8571
8737
  events.push("resume" /* Amity.MarkerSyncEvent.RESUME */);
8572
- }), onMessageCreated(message => {
8738
+ }), onMessageCreatedMqtt(message => {
8573
8739
  // only conversation, community and broadcast types can sync
8574
8740
  if (isUnreadCountSupport(message))
8575
8741
  events.push("new message" /* Amity.MarkerSyncEvent.NEW_MESSAGE */);
8576
- },
8577
- // only trigger sync from remote events to prevent an unread count equal `-1`
8578
- // when an optimistic message creation is performed.
8579
- false), onChannelCreated(() => events.push("subchannel is created" /* Amity.MarkerSyncEvent.CHANNEL_CREATED */)), onChannelDeleted(() => events.push("subchannel is deleted" /* Amity.MarkerSyncEvent.CHANNEL_DELETED */)), onChannelJoined(() => events.push("subchannel is joined" /* Amity.MarkerSyncEvent.CHANNEL_JOINED */)), onChannelLeft(() => events.push("subchannel is left" /* Amity.MarkerSyncEvent.CHANNEL_LEFT */)), onSubChannelCreated(() => events.push("subchannel is created" /* Amity.MarkerSyncEvent.SUB_CHANNEL_CREATED */)), onSubChannelDeleted(() =>
8742
+ }), onChannelCreated(() => events.push("subchannel is created" /* Amity.MarkerSyncEvent.CHANNEL_CREATED */)), onChannelDeleted(() => events.push("subchannel is deleted" /* Amity.MarkerSyncEvent.CHANNEL_DELETED */)), onChannelJoined(() => events.push("subchannel is joined" /* Amity.MarkerSyncEvent.CHANNEL_JOINED */)), onChannelLeft(() => events.push("subchannel is left" /* Amity.MarkerSyncEvent.CHANNEL_LEFT */)), onSubChannelCreated(() => events.push("subchannel is created" /* Amity.MarkerSyncEvent.SUB_CHANNEL_CREATED */)), onSubChannelDeleted(() =>
8580
8743
  /*
8581
8744
  workaround: when receiving the event for sub-channel deletion,
8582
8745
  before triggering marker update, the SDK will have to add a 2-second delay.
@@ -13117,7 +13280,26 @@ const getChannel = (channelId, callback) => {
13117
13280
  });
13118
13281
  callback(message);
13119
13282
  };
13120
- return onMessageCreated(updateMessagePreview);
13283
+ return onMessageCreatedMqtt(updateMessagePreview);
13284
+ }, 'channelId', 'channel'),
13285
+ convertEventPayload((callback) => {
13286
+ const updateMessagePreview = async (message) => {
13287
+ var _a;
13288
+ const messagePreviewSetting = await client.getMessagePreviewSetting(false);
13289
+ if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */)
13290
+ return;
13291
+ await handleMessageCreated(message);
13292
+ if (message.channelId !== channelId)
13293
+ return;
13294
+ const channel = (_a = pullFromCache(['channel', 'get', channelId])) === null || _a === void 0 ? void 0 : _a.data;
13295
+ if (!channel)
13296
+ return;
13297
+ updateChannelCache(channel, {
13298
+ messagePreviewId: message.messageId,
13299
+ });
13300
+ callback(message);
13301
+ };
13302
+ return onMessageCreatedLocal(updateMessagePreview);
13121
13303
  }, 'channelId', 'channel'),
13122
13304
  convertEventPayload((callback) => {
13123
13305
  const updateMessagePreview = async (message) => {
@@ -13556,7 +13738,27 @@ class ChannelLiveCollectionController extends LiveCollectionController {
13556
13738
  {
13557
13739
  // TODO: merge this code to another onMessageCreated in this file
13558
13740
  fn: convertEventPayload((callback) => {
13559
- return onMessageCreated(message => {
13741
+ return onMessageCreatedMqtt(message => {
13742
+ var _a;
13743
+ const cacheData = (_a = pullFromCache([
13744
+ 'channel',
13745
+ 'get',
13746
+ message.channelId,
13747
+ ])) === null || _a === void 0 ? void 0 : _a.data;
13748
+ if (!cacheData)
13749
+ return;
13750
+ updateChannelCache(cacheData, {
13751
+ lastActivity: message.createdAt,
13752
+ });
13753
+ callback(message);
13754
+ });
13755
+ }, 'messageId', 'channel'),
13756
+ action: 'onUpdate',
13757
+ },
13758
+ {
13759
+ // TODO: merge this code to another onMessageCreated in this file
13760
+ fn: convertEventPayload((callback) => {
13761
+ return onMessageCreatedLocal(message => {
13560
13762
  var _a;
13561
13763
  const cacheData = (_a = pullFromCache([
13562
13764
  'channel',
@@ -13610,7 +13812,33 @@ class ChannelLiveCollectionController extends LiveCollectionController {
13610
13812
  });
13611
13813
  callback(message);
13612
13814
  };
13613
- return onMessageCreated(updateMessagePreview);
13815
+ return onMessageCreatedMqtt(updateMessagePreview);
13816
+ }, 'channelId', 'channel'),
13817
+ action: 'onUpdate',
13818
+ },
13819
+ {
13820
+ fn: convertEventPayload((callback) => {
13821
+ const updateMessagePreview = async (message) => {
13822
+ var _a;
13823
+ const messagePreviewSetting = await ChannelLiveCollectionController.getMessagePreviewSetting();
13824
+ if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */)
13825
+ return;
13826
+ handleMessageCreated(message);
13827
+ if (this.shouldAbort(message.channelId))
13828
+ return;
13829
+ const channel = (_a = pullFromCache([
13830
+ 'channel',
13831
+ 'get',
13832
+ message.channelId,
13833
+ ])) === null || _a === void 0 ? void 0 : _a.data;
13834
+ if (!channel)
13835
+ return;
13836
+ updateChannelCache(channel, {
13837
+ messagePreviewId: message.messageId,
13838
+ });
13839
+ callback(message);
13840
+ };
13841
+ return onMessageCreatedLocal(updateMessagePreview);
13614
13842
  }, 'channelId', 'channel'),
13615
13843
  action: 'onUpdate',
13616
13844
  },
@@ -15112,7 +15340,7 @@ class MessageLiveCollectionController extends LiveCollectionController {
15112
15340
  }
15113
15341
  startSubscription() {
15114
15342
  return this.queryStreamController.subscribeRTE([
15115
- { fn: onMessageCreated, action: 'onCreate' },
15343
+ { fn: onMessageCreatedMqtt, action: 'onCreate' },
15116
15344
  { fn: onMessageDeleted, action: 'onDelete' },
15117
15345
  { fn: onMessageUpdated, action: 'onUpdate' },
15118
15346
  { fn: onMessageFlagged, action: 'onFlagged' },
@@ -15311,7 +15539,7 @@ const observeMessages = (subChannelId, callback) => {
15311
15539
  (_b = callback.onEvent) === null || _b === void 0 ? void 0 : _b.call(callback, action, message);
15312
15540
  (_c = callback[action]) === null || _c === void 0 ? void 0 : _c.call(callback, message);
15313
15541
  };
15314
- disposers.push(onMessageCreated(data => router({ data, loading: false, origin: 'event' }, 'onCreate')), onMessageUpdated(data => router({ data, loading: false, origin: 'event' }, 'onUpdate')), onMessageDeleted(data => router({ data, loading: false, origin: 'event' }, 'onDelete')), convertEventPayload(onMessageMarkerFetched, 'contentId', 'message')(data => router({ data, loading: false, origin: 'event' }, 'onCreate')), convertEventPayload(onMessageMarked, 'contentId', 'message')(data => router({ data, loading: false, origin: 'event' }, 'onCreate')));
15542
+ disposers.push(onMessageCreatedMqtt(data => router({ data, loading: false, origin: 'event' }, 'onCreate')), onMessageCreatedLocal(data => router({ data, loading: false, origin: 'event' }, 'onCreate')), onMessageUpdated(data => router({ data, loading: false, origin: 'event' }, 'onUpdate')), onMessageDeleted(data => router({ data, loading: false, origin: 'event' }, 'onDelete')), convertEventPayload(onMessageMarkerFetched, 'contentId', 'message')(data => router({ data, loading: false, origin: 'event' }, 'onCreate')), convertEventPayload(onMessageMarked, 'contentId', 'message')(data => router({ data, loading: false, origin: 'event' }, 'onCreate')));
15315
15543
  return () => {
15316
15544
  log(`observeMessages(tmpid: ${timestamp}) > dispose`);
15317
15545
  disposers.forEach(fn => fn());
@@ -15332,7 +15560,8 @@ var index$c = /*#__PURE__*/Object.freeze({
15332
15560
  flagMessage: flagMessage,
15333
15561
  unflagMessage: unflagMessage,
15334
15562
  isMessageFlaggedByMe: isMessageFlaggedByMe,
15335
- onMessageCreated: onMessageCreated,
15563
+ onMessageCreatedMqtt: onMessageCreatedMqtt,
15564
+ onMessageCreatedLocal: onMessageCreatedLocal,
15336
15565
  onMessageUpdated: onMessageUpdated,
15337
15566
  onMessageDeleted: onMessageDeleted,
15338
15567
  onMessageFlagged: onMessageFlagged,
@@ -15600,7 +15829,30 @@ const getSubChannel = (subChannelId, callback) => {
15600
15829
  });
15601
15830
  callback(message);
15602
15831
  };
15603
- return onMessageCreated(updateMessagePreview);
15832
+ return onMessageCreatedMqtt(updateMessagePreview);
15833
+ }, 'subChannelId', 'subChannel'),
15834
+ convertEventPayload((callback) => {
15835
+ const updateMessagePreview = async (message) => {
15836
+ var _a;
15837
+ const messagePreviewSetting = await client.getMessagePreviewSetting(false);
15838
+ if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */)
15839
+ return;
15840
+ await handleMessageCreated(message);
15841
+ if (message.subChannelId !== subChannelId)
15842
+ return;
15843
+ const subChannel = (_a = pullFromCache([
15844
+ 'subChannel',
15845
+ 'get',
15846
+ subChannelId,
15847
+ ])) === null || _a === void 0 ? void 0 : _a.data;
15848
+ if (!subChannel)
15849
+ return;
15850
+ updateSubChannelCache(message.subChannelId, subChannel, {
15851
+ messagePreviewId: message.messageId,
15852
+ });
15853
+ callback(message);
15854
+ };
15855
+ return onMessageCreatedLocal(updateMessagePreview);
15604
15856
  }, 'subChannelId', 'subChannel'),
15605
15857
  convertEventPayload((callback) => {
15606
15858
  const updateMessagePreview = async (message) => {
@@ -15765,7 +16017,42 @@ class SubChannelLiveCollectionController extends LiveCollectionController {
15765
16017
  },
15766
16018
  {
15767
16019
  fn: callback => {
15768
- return onMessageCreated(async (message) => {
16020
+ return onMessageCreatedMqtt(async (message) => {
16021
+ var _a, _b;
16022
+ const cacheData = pullFromCache([
16023
+ 'subChannel',
16024
+ 'get',
16025
+ message.subChannelId,
16026
+ ]);
16027
+ if (!cacheData)
16028
+ return;
16029
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
16030
+ if (!collection || !collection.data.includes(message.subChannelId))
16031
+ return;
16032
+ const client = getActiveClient();
16033
+ const messagePreviewSetting = await client.getMessagePreviewSetting(false);
16034
+ if (messagePreviewSetting === "no-message-preview" /* Amity.MessagePreviewSetting.NO_MESSAGE_PREVIEW */)
16035
+ return;
16036
+ handleMessageCreated(message);
16037
+ const subChannelCache = (_b = pullFromCache([
16038
+ 'subChannel',
16039
+ 'get',
16040
+ message.subChannelId,
16041
+ ])) === null || _b === void 0 ? void 0 : _b.data;
16042
+ if (!subChannelCache)
16043
+ return;
16044
+ updateSubChannelCache(message.subChannelId, subChannelCache, {
16045
+ lastActivity: message.createdAt,
16046
+ messagePreviewId: message.messageId,
16047
+ });
16048
+ callback(Object.assign(Object.assign({}, cacheData.data), { messagePreviewId: message.messageId, subChannelId: message.subChannelId, lastActivity: message.createdAt }));
16049
+ });
16050
+ },
16051
+ action: 'onUpdate',
16052
+ },
16053
+ {
16054
+ fn: callback => {
16055
+ return onMessageCreatedLocal(async (message) => {
15769
16056
  var _a, _b;
15770
16057
  const cacheData = pullFromCache([
15771
16058
  'subChannel',
@@ -21404,6 +21691,157 @@ const getTargetsByTargetIds = (params, callback) => {
21404
21691
  };
21405
21692
  };
21406
21693
 
21694
+ class StoryQueryStreamController extends QueryStreamController {
21695
+ constructor(query, cacheKey, notifyChange, paginationController) {
21696
+ super(query, cacheKey);
21697
+ this.notifyChange = notifyChange;
21698
+ this.paginationController = paginationController;
21699
+ }
21700
+ // eslint-disable-next-line class-methods-use-this
21701
+ saveToMainDB(response) {
21702
+ const client = getActiveClient();
21703
+ const cachedAt = client.cache && Date.now();
21704
+ const convertedData = convertStoryRawToInternal(response);
21705
+ if (client.cache) {
21706
+ ingestInCache(convertedData, { cachedAt });
21707
+ // Update local last story expires
21708
+ updateLocalLastStoryExpires(convertedData.stories);
21709
+ // Map storyId to referenceId
21710
+ mappingStoryIdToReferenceId(convertedData.stories);
21711
+ }
21712
+ }
21713
+ // eslint-disable-next-line class-methods-use-this
21714
+ getStoryReferenceIds(story) {
21715
+ if (story === null || story === void 0 ? void 0 : story.referenceId) {
21716
+ return story.referenceId;
21717
+ }
21718
+ return story.storyId;
21719
+ }
21720
+ appendToQueryStream(response, direction, refresh = false) {
21721
+ var _a, _b;
21722
+ if (refresh) {
21723
+ pushToCache(this.cacheKey, {
21724
+ data: response.stories.map(this.getStoryReferenceIds),
21725
+ });
21726
+ }
21727
+ else {
21728
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
21729
+ const stories = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
21730
+ pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [...new Set([...stories, ...response.stories.map(this.getStoryReferenceIds)])] }));
21731
+ }
21732
+ }
21733
+ reactor(action) {
21734
+ return (payload) => {
21735
+ var _a;
21736
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
21737
+ if (!collection)
21738
+ return;
21739
+ const newReferenceIds = payload.map(({ referenceId }) => referenceId);
21740
+ collection.data = [...new Set([...newReferenceIds, ...collection.data])];
21741
+ pushToCache(this.cacheKey, collection);
21742
+ this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
21743
+ };
21744
+ }
21745
+ subscribeRTE(createSubscriber) {
21746
+ return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
21747
+ }
21748
+ }
21749
+
21750
+ /* eslint-disable no-use-before-define */
21751
+ class StoryPaginationNoPageController extends PaginationNoPageController {
21752
+ async getRequest(queryParams) {
21753
+ const { data: queryResponse } = await this.http.get('/api/v4/stories-by-targets', {
21754
+ params: Object.assign({}, queryParams),
21755
+ });
21756
+ return queryResponse;
21757
+ }
21758
+ }
21759
+
21760
+ class StoryLiveCollectionController extends LiveCollectionController {
21761
+ constructor(query, callback) {
21762
+ const queryStreamId = hash__default["default"](query);
21763
+ const cacheKey = ["story-target-ids" /* STORY_KEY_CACHE.STORY_TARGET_IDS */, 'collection', queryStreamId];
21764
+ const paginationController = new StoryPaginationNoPageController(query);
21765
+ super(paginationController, queryStreamId, cacheKey, callback);
21766
+ this.query = query;
21767
+ this.queryStreamController = new StoryQueryStreamController(this.query, this.cacheKey, this.notifyChange.bind(this), paginationController);
21768
+ this.paginationController = paginationController;
21769
+ this.callback = callback.bind(this);
21770
+ this.loadPage(true);
21771
+ }
21772
+ setup() {
21773
+ var _a;
21774
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
21775
+ if (!collection) {
21776
+ pushToCache(this.cacheKey, {
21777
+ data: [],
21778
+ params: {},
21779
+ });
21780
+ }
21781
+ }
21782
+ persistModel(response) {
21783
+ this.queryStreamController.saveToMainDB(response);
21784
+ }
21785
+ persistQueryStream({ response, direction, refresh, }) {
21786
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
21787
+ }
21788
+ notifyChange({ origin, loading, error }) {
21789
+ var _a;
21790
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
21791
+ if (!collection)
21792
+ return;
21793
+ let data = collection.data
21794
+ .map(referenceId => pullFromCache(["story" /* STORY_KEY_CACHE.STORY */, 'get', referenceId]))
21795
+ .filter(Boolean)
21796
+ .map(internStory => LinkedObject.story(internStory.data));
21797
+ if (!this.shouldNotify(data) && origin === 'event')
21798
+ return;
21799
+ data = this.applyFilter(data);
21800
+ this.callback({
21801
+ onNextPage: undefined,
21802
+ data,
21803
+ hasNextPage: false,
21804
+ loading,
21805
+ error,
21806
+ });
21807
+ }
21808
+ applyFilter(data) {
21809
+ var _a, _b;
21810
+ const internalStories = data;
21811
+ const orderBy = ((_b = (_a = this.query) === null || _a === void 0 ? void 0 : _a.options) === null || _b === void 0 ? void 0 : _b.orderBy) || 'desc';
21812
+ return orderBy === 'asc'
21813
+ ? internalStories.sort(sortByFirstCreated)
21814
+ : internalStories.sort(sortByLastCreated);
21815
+ }
21816
+ startSubscription() {
21817
+ return this.queryStreamController.subscribeRTE([
21818
+ { fn: onStoryCreated, action: "onCreate" /* Amity.StoryActionType.OnCreate */ },
21819
+ { fn: onStoryUpdated, action: "onUpdate" /* Amity.StoryActionType.OnUpdate */ },
21820
+ { fn: onStoryDeleted, action: "onDelete" /* Amity.StoryActionType.OnDelete */ },
21821
+ { fn: onStoryError, action: "onError" /* Amity.StoryActionType.OnError */ },
21822
+ ]);
21823
+ }
21824
+ }
21825
+
21826
+ const getStoriesByTargetIds = (params, callback, config) => {
21827
+ const { log, cache, userId } = getActiveClient();
21828
+ if (!cache) {
21829
+ console.log(ENABLE_CACHE_MESSAGE);
21830
+ }
21831
+ const timestamp = Date.now();
21832
+ log(`getStoriesByTargetIds(tmpid: ${timestamp}) > listen`);
21833
+ const storyLiveCollection = new StoryLiveCollectionController(params, callback);
21834
+ const disposers = storyLiveCollection.startSubscription();
21835
+ const cacheKey = storyLiveCollection.getCacheKey();
21836
+ disposers.push(() => {
21837
+ dropFromCache(cacheKey);
21838
+ });
21839
+ return () => {
21840
+ log(`getStoriesByTargetIds(tmpid: ${timestamp}) > dispose`);
21841
+ disposers.forEach(fn => fn());
21842
+ };
21843
+ };
21844
+
21407
21845
  var index = /*#__PURE__*/Object.freeze({
21408
21846
  __proto__: null,
21409
21847
  createImageStory: createImageStory,
@@ -21413,7 +21851,8 @@ var index = /*#__PURE__*/Object.freeze({
21413
21851
  getActiveStoriesByTarget: getActiveStoriesByTarget,
21414
21852
  getStoryByStoryId: getStoryByStoryId,
21415
21853
  getTargetById: getTargetById,
21416
- getTargetsByTargetIds: getTargetsByTargetIds
21854
+ getTargetsByTargetIds: getTargetsByTargetIds,
21855
+ getStoriesByTargetIds: getStoriesByTargetIds
21417
21856
  });
21418
21857
 
21419
21858
  /**
@@ -21518,6 +21957,7 @@ exports.onMessageMarkerFetched = onMessageMarkerFetched;
21518
21957
  exports.onSubChannelMarkerFetched = onSubChannelMarkerFetched;
21519
21958
  exports.onSubChannelMarkerUpdated = onSubChannelMarkerUpdated;
21520
21959
  exports.onUserMarkerFetched = onUserMarkerFetched;
21960
+ exports.onUserMarkerFetchedLegacy = onUserMarkerFetchedLegacy;
21521
21961
  exports.pullFromCache = pullFromCache;
21522
21962
  exports.pushToCache = pushToCache;
21523
21963
  exports.queryCache = queryCache;