@amityco/ts-sdk 7.13.1-e261145.0 → 7.14.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 (102) hide show
  1. package/dist/@types/domains/client.d.ts +10 -1
  2. package/dist/@types/domains/client.d.ts.map +1 -1
  3. package/dist/@types/domains/feed.d.ts +17 -1
  4. package/dist/@types/domains/feed.d.ts.map +1 -1
  5. package/dist/@types/domains/message.d.ts +1 -1
  6. package/dist/@types/domains/message.d.ts.map +1 -1
  7. package/dist/@types/domains/post.d.ts +5 -0
  8. package/dist/@types/domains/post.d.ts.map +1 -1
  9. package/dist/client/api/accessTokenExpiryWatcher.d.ts +1 -1
  10. package/dist/client/api/accessTokenExpiryWatcher.d.ts.map +1 -1
  11. package/dist/client/api/index.d.ts +2 -0
  12. package/dist/client/api/index.d.ts.map +1 -1
  13. package/dist/client/api/isSameUserId.d.ts +2 -0
  14. package/dist/client/api/isSameUserId.d.ts.map +1 -0
  15. package/dist/client/api/login.d.ts.map +1 -1
  16. package/dist/client/api/loginAsBot.d.ts.map +1 -1
  17. package/dist/client/api/loginAsVisitor.d.ts.map +1 -1
  18. package/dist/client/api/loginWithAccessToken.d.ts +28 -0
  19. package/dist/client/api/loginWithAccessToken.d.ts.map +1 -0
  20. package/dist/client/api/logout.d.ts.map +1 -1
  21. package/dist/client/api/renewTokenWithHandler.d.ts +11 -0
  22. package/dist/client/api/renewTokenWithHandler.d.ts.map +1 -0
  23. package/dist/client/api/renewWithAccessToken.d.ts +2 -0
  24. package/dist/client/api/renewWithAccessToken.d.ts.map +1 -0
  25. package/dist/client/api/resumeSession.d.ts.map +1 -1
  26. package/dist/client/api/setAccessTokenHandler.d.ts +31 -0
  27. package/dist/client/api/setAccessTokenHandler.d.ts.map +1 -0
  28. package/dist/client/api/setupLoginSubscriptions.d.ts +11 -0
  29. package/dist/client/api/setupLoginSubscriptions.d.ts.map +1 -0
  30. package/dist/client/api/tests/loginWithAccessToken.test.d.ts +2 -0
  31. package/dist/client/api/tests/loginWithAccessToken.test.d.ts.map +1 -0
  32. package/dist/client/api/validateAccessToken.d.ts +11 -0
  33. package/dist/client/api/validateAccessToken.d.ts.map +1 -0
  34. package/dist/commentRepository/api/createComment.d.ts.map +1 -1
  35. package/dist/commentRepository/api/deleteComment.d.ts.map +1 -1
  36. package/dist/commentRepository/events/utils.d.ts.map +1 -1
  37. package/dist/core/subscription.d.ts +2 -2
  38. package/dist/core/subscription.d.ts.map +1 -1
  39. package/dist/feedRepository/index.d.ts +1 -1
  40. package/dist/feedRepository/index.d.ts.map +1 -1
  41. package/dist/feedRepository/observers/getCommunityFeed/LiveCollectionController.d.ts +13 -0
  42. package/dist/feedRepository/observers/getCommunityFeed/LiveCollectionController.d.ts.map +1 -0
  43. package/dist/feedRepository/observers/getCommunityFeed/PaginationController.d.ts +5 -0
  44. package/dist/feedRepository/observers/getCommunityFeed/PaginationController.d.ts.map +1 -0
  45. package/dist/feedRepository/observers/getCommunityFeed/QueryStreamController.d.ts +15 -0
  46. package/dist/feedRepository/observers/getCommunityFeed/QueryStreamController.d.ts.map +1 -0
  47. package/dist/feedRepository/observers/getCommunityFeed.d.ts +34 -0
  48. package/dist/feedRepository/observers/getCommunityFeed.d.ts.map +1 -0
  49. package/dist/feedRepository/observers/index.d.ts +1 -0
  50. package/dist/feedRepository/observers/index.d.ts.map +1 -1
  51. package/dist/feedRepository/observers/utils.d.ts.map +1 -1
  52. package/dist/index.cjs.js +996 -386
  53. package/dist/index.esm.js +980 -370
  54. package/dist/index.umd.js +3 -3
  55. package/dist/postRepository/events/utils.d.ts.map +1 -1
  56. package/dist/postRepository/observers/utils.d.ts.map +1 -1
  57. package/dist/postRepository/utils/PostCommentCountEngine/CommentChange.d.ts +11 -0
  58. package/dist/postRepository/utils/PostCommentCountEngine/CommentChange.d.ts.map +1 -0
  59. package/dist/postRepository/utils/PostCommentCountEngine/CreateTask.d.ts +8 -0
  60. package/dist/postRepository/utils/PostCommentCountEngine/CreateTask.d.ts.map +1 -0
  61. package/dist/postRepository/utils/PostCommentCountEngine/DeleteTask.d.ts +7 -0
  62. package/dist/postRepository/utils/PostCommentCountEngine/DeleteTask.d.ts.map +1 -0
  63. package/dist/postRepository/utils/PostCommentCountEngine/PostCommentCountEngine.d.ts +19 -0
  64. package/dist/postRepository/utils/PostCommentCountEngine/PostCommentCountEngine.d.ts.map +1 -0
  65. package/dist/postRepository/utils/PostCommentCountEngine/ResetTask.d.ts +8 -0
  66. package/dist/postRepository/utils/PostCommentCountEngine/ResetTask.d.ts.map +1 -0
  67. package/dist/postRepository/utils/payload.d.ts.map +1 -1
  68. package/package.json +3 -1
  69. package/dist/commentRepository/internalApi/createComment.d.ts +0 -2
  70. package/dist/commentRepository/internalApi/createComment.d.ts.map +0 -1
  71. package/dist/commentRepository/internalApi/deleteComment.d.ts +0 -2
  72. package/dist/commentRepository/internalApi/deleteComment.d.ts.map +0 -1
  73. package/dist/commentRepository/internalApi/flagComment.d.ts +0 -2
  74. package/dist/commentRepository/internalApi/flagComment.d.ts.map +0 -1
  75. package/dist/commentRepository/internalApi/hardDeleteComment.d.ts +0 -2
  76. package/dist/commentRepository/internalApi/hardDeleteComment.d.ts.map +0 -1
  77. package/dist/commentRepository/internalApi/isCommentFlaggedByMe.d.ts +0 -2
  78. package/dist/commentRepository/internalApi/isCommentFlaggedByMe.d.ts.map +0 -1
  79. package/dist/commentRepository/internalApi/queryComments.d.ts +0 -2
  80. package/dist/commentRepository/internalApi/queryComments.d.ts.map +0 -1
  81. package/dist/commentRepository/internalApi/softDeleteComment.d.ts +0 -2
  82. package/dist/commentRepository/internalApi/softDeleteComment.d.ts.map +0 -1
  83. package/dist/commentRepository/internalApi/tests/createComment.test.d.ts +0 -2
  84. package/dist/commentRepository/internalApi/tests/createComment.test.d.ts.map +0 -1
  85. package/dist/commentRepository/internalApi/tests/deleteComment.test.d.ts +0 -2
  86. package/dist/commentRepository/internalApi/tests/deleteComment.test.d.ts.map +0 -1
  87. package/dist/commentRepository/internalApi/tests/getCommentByIds.test.d.ts +0 -2
  88. package/dist/commentRepository/internalApi/tests/getCommentByIds.test.d.ts.map +0 -1
  89. package/dist/commentRepository/internalApi/tests/getComments.test.d.ts +0 -2
  90. package/dist/commentRepository/internalApi/tests/getComments.test.d.ts.map +0 -1
  91. package/dist/commentRepository/internalApi/tests/hardDeleteComment.test.d.ts +0 -2
  92. package/dist/commentRepository/internalApi/tests/hardDeleteComment.test.d.ts.map +0 -1
  93. package/dist/commentRepository/internalApi/tests/queryComments.test.d.ts +0 -2
  94. package/dist/commentRepository/internalApi/tests/queryComments.test.d.ts.map +0 -1
  95. package/dist/commentRepository/internalApi/tests/softDeleteComment.test.d.ts +0 -2
  96. package/dist/commentRepository/internalApi/tests/softDeleteComment.test.d.ts.map +0 -1
  97. package/dist/commentRepository/internalApi/tests/updateComment.test.d.ts +0 -2
  98. package/dist/commentRepository/internalApi/tests/updateComment.test.d.ts.map +0 -1
  99. package/dist/commentRepository/internalApi/unflagComment.d.ts +0 -2
  100. package/dist/commentRepository/internalApi/unflagComment.d.ts.map +0 -1
  101. package/dist/commentRepository/internalApi/updateComment.d.ts +0 -2
  102. package/dist/commentRepository/internalApi/updateComment.d.ts.map +0 -1
package/dist/index.esm.js CHANGED
@@ -188,6 +188,12 @@ var FeedSourceEnum;
188
188
  FeedSourceEnum["Community"] = "community";
189
189
  FeedSourceEnum["User"] = "user";
190
190
  })(FeedSourceEnum || (FeedSourceEnum = {}));
191
+ var FeedTypeEnum;
192
+ (function (FeedTypeEnum) {
193
+ FeedTypeEnum["Reviewing"] = "reviewing";
194
+ FeedTypeEnum["Published"] = "published";
195
+ FeedTypeEnum["Declined"] = "declined";
196
+ })(FeedTypeEnum || (FeedTypeEnum = {}));
191
197
 
192
198
  var AmityEventType;
193
199
  (function (AmityEventType) {
@@ -224,8 +230,8 @@ var AmityEventOrderOption;
224
230
 
225
231
  function getVersion() {
226
232
  try {
227
- // the string ''v7.13.0-esm'' should be replaced by actual value by @rollup/plugin-replace
228
- return 'v7.13.0-esm';
233
+ // the string ''v7.14.0-esm'' should be replaced by actual value by @rollup/plugin-replace
234
+ return 'v7.14.0-esm';
229
235
  }
230
236
  catch (error) {
231
237
  return '__dev__';
@@ -1667,10 +1673,14 @@ const getLiveReactionTopic = (post) => {
1667
1673
  };
1668
1674
  const getRoomWatcherTopic = (room) => {
1669
1675
  const user = getCurrentUser();
1676
+ if (!user)
1677
+ return;
1670
1678
  return `${getNetworkId(user)}/room/${room._id}`;
1671
1679
  };
1672
1680
  const getRoomStreamerTopic = (room) => {
1673
1681
  const user = getCurrentUser();
1682
+ if (!user)
1683
+ return;
1674
1684
  return `${getNetworkId(user)}/room/${room.roomId}/streamer`;
1675
1685
  };
1676
1686
  function subscribeTopic(topic, callback) {
@@ -1765,13 +1775,13 @@ class NetworkActivitiesWatcher {
1765
1775
  this._listener.clear();
1766
1776
  }
1767
1777
  }
1768
- let instance$7;
1778
+ let instance$8;
1769
1779
  var NetworkActivitiesWatcher$1 = {
1770
1780
  getInstance: () => {
1771
- if (!instance$7) {
1772
- instance$7 = new NetworkActivitiesWatcher();
1781
+ if (!instance$8) {
1782
+ instance$8 = new NetworkActivitiesWatcher();
1773
1783
  }
1774
- return instance$7;
1784
+ return instance$8;
1775
1785
  },
1776
1786
  };
1777
1787
 
@@ -22930,13 +22940,13 @@ class SessionWatcher {
22930
22940
  this._listener.clear();
22931
22941
  }
22932
22942
  }
22933
- let instance$6;
22943
+ let instance$7;
22934
22944
  var SessionWatcher$1 = {
22935
22945
  getInstance: () => {
22936
- if (!instance$6) {
22937
- instance$6 = new SessionWatcher();
22946
+ if (!instance$7) {
22947
+ instance$7 = new SessionWatcher();
22938
22948
  }
22939
- return instance$6;
22949
+ return instance$7;
22940
22950
  },
22941
22951
  };
22942
22952
 
@@ -23513,6 +23523,108 @@ const setVisitorClientToken = async (params) => {
23513
23523
  return { accessToken, users, userType };
23514
23524
  };
23515
23525
 
23526
+ /* begin_public_function
23527
+ id: client.logout
23528
+ */
23529
+ /**
23530
+ * ```js
23531
+ * import { Client } from '@amityco/ts-sdk';
23532
+ * const success = await Client.logout()
23533
+ * ```
23534
+ *
23535
+ * Disconnects an {@link Amity.Client} instance from ASC servers
23536
+ *
23537
+ * @returns a success boolean if disconnected
23538
+ *
23539
+ * @category Client API
23540
+ * @async
23541
+ */
23542
+ const logout = async () => {
23543
+ var _a;
23544
+ const client = getActiveClient();
23545
+ client.log('client/api/disconnectClient');
23546
+ if (client.mqtt && client.mqtt.connected) {
23547
+ client.mqtt.disconnect();
23548
+ }
23549
+ /*
23550
+ * for cases when session state is terminated (example on ban) or token expired,
23551
+ * the terminating block will set session state to terminated or for the or
23552
+ * in the case of expired token the same happens
23553
+ *
23554
+ * establishing state also ignored in cases where accessTokenExpiryWatcher
23555
+ * calls renewal. There is a possibility that renewal will be called before
23556
+ * disconnectClient finishes execution
23557
+ *
23558
+ * IMPORTANT: call this before `emitter.all.clear()`, otherwise the session
23559
+ * event will never be triggered
23560
+ */
23561
+ if (client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */)
23562
+ setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
23563
+ client.emitter.all.clear();
23564
+ (_a = client.mqtt) === null || _a === void 0 ? void 0 : _a.removeAllListeners();
23565
+ client.userId = undefined;
23566
+ client.token = undefined;
23567
+ client.loginType = undefined;
23568
+ client.http.defaults.headers.common.Authorization = '';
23569
+ client.http.defaults.metadata = {
23570
+ tokenExpiry: '',
23571
+ isGlobalBanned: false,
23572
+ isUserDeleted: false,
23573
+ };
23574
+ if (typeof document !== 'undefined') {
23575
+ document.cookie = '_ascSession=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
23576
+ }
23577
+ /*
23578
+ * Cache should be usable if tokenExpired
23579
+ * https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#SDK-usability-based-on-Session-State
23580
+ */
23581
+ if (client.sessionState !== "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.cache) {
23582
+ client.cache = { data: {} };
23583
+ }
23584
+ return true;
23585
+ };
23586
+ /* end_public_function */
23587
+
23588
+ /**
23589
+ * Terminates {@link Amity.Client} instance
23590
+ *
23591
+ *
23592
+ *
23593
+ * @category private
23594
+ */
23595
+ const terminateClient = (terminationReason) => {
23596
+ const client = getActiveClient();
23597
+ setSessionState("terminated" /* Amity.SessionStates.TERMINATED */, terminationReason);
23598
+ if (client.http.defaults.metadata) {
23599
+ if (terminationReason === "globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */)
23600
+ client.http.defaults.metadata.isGlobalBanned = true;
23601
+ if (terminationReason === "userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */)
23602
+ client.http.defaults.metadata.isUserDeleted = true;
23603
+ }
23604
+ client.sessionHandler = undefined;
23605
+ logout();
23606
+ };
23607
+
23608
+ let currentUserType = null;
23609
+ /* begin_public_function
23610
+ id: client.get_current_user_type
23611
+ */
23612
+ const getCurrentUserType = () => {
23613
+ if (!currentUserType) {
23614
+ throw new ASCError('Connect client first', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "fatal" /* Amity.ErrorLevel.FATAL */);
23615
+ }
23616
+ return currentUserType;
23617
+ };
23618
+ /* end_public_function */
23619
+ const setCurrentUserType = (userType) => {
23620
+ currentUserType = userType;
23621
+ };
23622
+
23623
+ const setCurrentUser = ({ user, userType, }) => {
23624
+ setActiveUser(user);
23625
+ setCurrentUserType(userType);
23626
+ };
23627
+
23516
23628
  const createUserEventSubscriber = (event, callback) => {
23517
23629
  const client = getActiveClient();
23518
23630
  const filter = (data) => {
@@ -23831,13 +23943,13 @@ class AnalyticsEngine {
23831
23943
  this._eventCapturer.resetAllBuckets();
23832
23944
  }
23833
23945
  }
23834
- let instance$5;
23946
+ let instance$6;
23835
23947
  var AnalyticsEngine$1 = {
23836
23948
  getInstance: () => {
23837
- if (!instance$5) {
23838
- instance$5 = new AnalyticsEngine();
23949
+ if (!instance$6) {
23950
+ instance$6 = new AnalyticsEngine();
23839
23951
  }
23840
- return instance$5;
23952
+ return instance$6;
23841
23953
  },
23842
23954
  };
23843
23955
 
@@ -24065,12 +24177,12 @@ class MessageReadReceiptSyncEngine {
24065
24177
  }
24066
24178
  }
24067
24179
  }
24068
- let instance$4 = null;
24180
+ let instance$5 = null;
24069
24181
  var ReadReceiptSyncEngine = {
24070
24182
  getInstance: () => {
24071
- if (!instance$4)
24072
- instance$4 = new MessageReadReceiptSyncEngine();
24073
- return instance$4;
24183
+ if (!instance$5)
24184
+ instance$5 = new MessageReadReceiptSyncEngine();
24185
+ return instance$5;
24074
24186
  },
24075
24187
  };
24076
24188
 
@@ -24324,12 +24436,12 @@ class LegacyMessageReadReceiptSyncEngine {
24324
24436
  }
24325
24437
  }
24326
24438
  }
24327
- let instance$3 = null;
24439
+ let instance$4 = null;
24328
24440
  var LegacyReadReceiptSyncEngine = {
24329
24441
  getInstance: () => {
24330
- if (!instance$3)
24331
- instance$3 = new LegacyMessageReadReceiptSyncEngine();
24332
- return instance$3;
24442
+ if (!instance$4)
24443
+ instance$4 = new LegacyMessageReadReceiptSyncEngine();
24444
+ return instance$4;
24333
24445
  },
24334
24446
  };
24335
24447
 
@@ -24575,12 +24687,12 @@ class ObjectResolverEngine {
24575
24687
  this.stopResolver();
24576
24688
  }
24577
24689
  }
24578
- let instance$2 = null;
24690
+ let instance$3 = null;
24579
24691
  var ObjectResolverEngine$1 = {
24580
24692
  getInstance: () => {
24581
- if (!instance$2)
24582
- instance$2 = new ObjectResolverEngine();
24583
- return instance$2;
24693
+ if (!instance$3)
24694
+ instance$3 = new ObjectResolverEngine();
24695
+ return instance$3;
24584
24696
  },
24585
24697
  };
24586
24698
 
@@ -24730,13 +24842,13 @@ class LiveReactionSyncEngine {
24730
24842
  this.stopReactionsSync();
24731
24843
  }
24732
24844
  }
24733
- let instance$1;
24845
+ let instance$2;
24734
24846
  var ReactionSyncEngine = {
24735
24847
  getInstance: () => {
24736
- if (!instance$1) {
24737
- instance$1 = new LiveReactionSyncEngine();
24848
+ if (!instance$2) {
24849
+ instance$2 = new LiveReactionSyncEngine();
24738
24850
  }
24739
- return instance$1;
24851
+ return instance$2;
24740
24852
  },
24741
24853
  };
24742
24854
 
@@ -24758,87 +24870,6 @@ var reactionSyncEngineOnLoginHandler = () => {
24758
24870
  };
24759
24871
  };
24760
24872
 
24761
- /* begin_public_function
24762
- id: client.logout
24763
- */
24764
- /**
24765
- * ```js
24766
- * import { Client } from '@amityco/ts-sdk';
24767
- * const success = await Client.logout()
24768
- * ```
24769
- *
24770
- * Disconnects an {@link Amity.Client} instance from ASC servers
24771
- *
24772
- * @returns a success boolean if disconnected
24773
- *
24774
- * @category Client API
24775
- * @async
24776
- */
24777
- const logout = async () => {
24778
- var _a;
24779
- const client = getActiveClient();
24780
- client.log('client/api/disconnectClient');
24781
- if (client.mqtt && client.mqtt.connected) {
24782
- client.mqtt.disconnect();
24783
- }
24784
- /*
24785
- * for cases when session state is terminated (example on ban) or token expired,
24786
- * the terminating block will set session state to terminated or for the or
24787
- * in the case of expired token the same happens
24788
- *
24789
- * establishing state also ignored in cases where accessTokenExpiryWatcher
24790
- * calls renewal. There is a possibility that renewal will be called before
24791
- * disconnectClient finishes execution
24792
- *
24793
- * IMPORTANT: call this before `emitter.all.clear()`, otherwise the session
24794
- * event will never be triggered
24795
- */
24796
- if (client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */)
24797
- setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
24798
- client.emitter.all.clear();
24799
- (_a = client.mqtt) === null || _a === void 0 ? void 0 : _a.removeAllListeners();
24800
- client.userId = undefined;
24801
- client.token = undefined;
24802
- client.http.defaults.headers.common.Authorization = '';
24803
- client.http.defaults.metadata = {
24804
- tokenExpiry: '',
24805
- isGlobalBanned: false,
24806
- isUserDeleted: false,
24807
- };
24808
- if (typeof document !== 'undefined') {
24809
- document.cookie = '_ascSession=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
24810
- }
24811
- /*
24812
- * Cache should be usable if tokenExpired
24813
- * https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#SDK-usability-based-on-Session-State
24814
- */
24815
- if (client.sessionState !== "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.cache) {
24816
- client.cache = { data: {} };
24817
- }
24818
- return true;
24819
- };
24820
- /* end_public_function */
24821
-
24822
- /**
24823
- * Terminates {@link Amity.Client} instance
24824
- *
24825
- *
24826
- *
24827
- * @category private
24828
- */
24829
- const terminateClient = (terminationReason) => {
24830
- const client = getActiveClient();
24831
- setSessionState("terminated" /* Amity.SessionStates.TERMINATED */, terminationReason);
24832
- if (client.http.defaults.metadata) {
24833
- if (terminationReason === "globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */)
24834
- client.http.defaults.metadata.isGlobalBanned = true;
24835
- if (terminationReason === "userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */)
24836
- client.http.defaults.metadata.isUserDeleted = true;
24837
- }
24838
- client.sessionHandler = undefined;
24839
- logout();
24840
- };
24841
-
24842
24873
  const EVENTS = [
24843
24874
  'disconnected',
24844
24875
  'error',
@@ -24968,24 +24999,50 @@ const removeChannelMarkerCache = (channel) => {
24968
24999
  dropFromCache(['channelMarker', 'get', id], true);
24969
25000
  };
24970
25001
 
24971
- let currentUserType = null;
24972
- /* begin_public_function
24973
- id: client.get_current_user_type
24974
- */
24975
- const getCurrentUserType = () => {
24976
- if (!currentUserType) {
24977
- throw new ASCError('Connect client first', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "fatal" /* Amity.ErrorLevel.FATAL */);
25002
+ /**
25003
+ * Sets up all login-related event subscriptions
25004
+ * This includes handlers for user bans, deletions, token events, and various engine initializations
25005
+ *
25006
+ * @param unsubWatcher - The unsubscriber function for the access token expiry watcher
25007
+ * @returns Array of unsubscriber functions for all registered subscriptions
25008
+ *
25009
+ * @category private
25010
+ */
25011
+ const setupLoginSubscriptions = (unsubWatcher) => {
25012
+ const client = getActiveClient();
25013
+ const subscriptions = [];
25014
+ subscriptions.push(
25015
+ // GLOBAL_BAN
25016
+ onClientBanned((_) => {
25017
+ terminateClient("globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */);
25018
+ subscriptions.forEach(fn => fn());
25019
+ unsubWatcher();
25020
+ }), onTokenTerminated(_ => {
25021
+ terminateClient();
25022
+ subscriptions.forEach(fn => fn());
25023
+ unsubWatcher();
25024
+ }), onUserDeleted$2((user) => {
25025
+ if (user.userId === client.userId) {
25026
+ terminateClient("userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */);
25027
+ subscriptions.forEach(fn => fn());
25028
+ unsubWatcher();
25029
+ }
25030
+ }), onTokenExpired(state => {
25031
+ SessionWatcher$1.getInstance().setSessionState(state);
25032
+ logout();
25033
+ subscriptions.forEach(fn => fn());
25034
+ }),
25035
+ // NOTE: This is a temporary solution to handle the channel marker when the user is forced to leave
25036
+ // the channel because currently backend can't handle this, so every time a user is banned from
25037
+ // a channel or the channel is deleted the channel's unread count will not be reset to zero
25038
+ onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler(), reactionSyncEngineOnLoginHandler());
25039
+ if (client.useLegacyUnreadCount) {
25040
+ subscriptions.push(readReceiptSyncEngineOnLoginHandler());
24978
25041
  }
24979
- return currentUserType;
24980
- };
24981
- /* end_public_function */
24982
- const setCurrentUserType = (userType) => {
24983
- currentUserType = userType;
24984
- };
24985
-
24986
- const setCurrentUser = ({ user, userType, }) => {
24987
- setActiveUser(user);
24988
- setCurrentUserType(userType);
25042
+ else {
25043
+ subscriptions.push(legacyReadReceiptSyncEngineOnLoginHandler());
25044
+ }
25045
+ return subscriptions;
24989
25046
  };
24990
25047
 
24991
25048
  /* eslint-disable no-param-reassign */
@@ -24994,8 +25051,8 @@ const setCurrentUser = ({ user, userType, }) => {
24994
25051
  * than the one already connected, in which case the existing subscriptions need
24995
25052
  * to be cleared
24996
25053
  */
24997
- let subscriptions$3 = [];
24998
- async function runMqtt$1() {
25054
+ let subscriptions$4 = [];
25055
+ async function runMqtt$2() {
24999
25056
  await modifyMqttConnection();
25000
25057
  }
25001
25058
  /* begin_public_function
@@ -25029,8 +25086,8 @@ const login = async (params, sessionHandler, config) => {
25029
25086
  if (client.userId && client.userId !== params.userId) {
25030
25087
  await logout();
25031
25088
  // Remove subscription to ban and delete
25032
- subscriptions$3.forEach(fn => fn());
25033
- subscriptions$3 = [];
25089
+ subscriptions$4.forEach(fn => fn());
25090
+ subscriptions$4 = [];
25034
25091
  }
25035
25092
  // default values
25036
25093
  const defaultDeviceId = await getDeviceId();
@@ -25055,11 +25112,12 @@ const login = async (params, sessionHandler, config) => {
25055
25112
  }
25056
25113
  client.userId = user.userId;
25057
25114
  client.sessionHandler = sessionHandler;
25115
+ client.loginType = 'userId';
25058
25116
  /*
25059
25117
  * Cannot push to subscriptions as watcher needs to continue working even if
25060
25118
  * token expires
25061
25119
  */
25062
- unsubWatcher = client.accessTokenExpiryWatcher(sessionHandler);
25120
+ unsubWatcher = client.accessTokenExpiryWatcher();
25063
25121
  setCurrentUser({ user, userType });
25064
25122
  }
25065
25123
  catch (error) {
@@ -25072,40 +25130,11 @@ const login = async (params, sessionHandler, config) => {
25072
25130
  throw error;
25073
25131
  }
25074
25132
  if ((config === null || config === void 0 ? void 0 : config.disableRTE) !== true) {
25075
- runMqtt$1();
25133
+ runMqtt$2();
25076
25134
  }
25077
25135
  await initializeMessagePreviewSetting();
25078
- if (subscriptions$3.length === 0) {
25079
- subscriptions$3.push(
25080
- // GLOBAL_BAN
25081
- onClientBanned((_) => {
25082
- terminateClient("globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */);
25083
- subscriptions$3.forEach(fn => fn());
25084
- unsubWatcher();
25085
- }), onTokenTerminated(_ => {
25086
- terminateClient();
25087
- subscriptions$3.forEach(fn => fn());
25088
- unsubWatcher();
25089
- }), onUserDeleted$2((user) => {
25090
- if (user.userId === client.userId) {
25091
- terminateClient("userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */);
25092
- subscriptions$3.forEach(fn => fn());
25093
- unsubWatcher();
25094
- }
25095
- }), onTokenExpired(state => {
25096
- SessionWatcher$1.getInstance().setSessionState(state);
25097
- logout();
25098
- subscriptions$3.forEach(fn => fn());
25099
- }),
25100
- // NOTE: This is a temporary solution to handle the channel marker when the user is forced to leave
25101
- // the channel because currently backend can't handle this, so every time a user is banned from
25102
- // a channel or the channel is deleted the channel's unread count will not be reset to zero
25103
- onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler(), reactionSyncEngineOnLoginHandler());
25104
- if (client.useLegacyUnreadCount) {
25105
- subscriptions$3.push(readReceiptSyncEngineOnLoginHandler());
25106
- }
25107
- else
25108
- subscriptions$3.push(legacyReadReceiptSyncEngineOnLoginHandler());
25136
+ if (subscriptions$4.length === 0) {
25137
+ subscriptions$4 = setupLoginSubscriptions(unsubWatcher);
25109
25138
  }
25110
25139
  return true;
25111
25140
  };
@@ -25117,7 +25146,7 @@ const login = async (params, sessionHandler, config) => {
25117
25146
  * than the one already connected, in which case the existing subscriptions need
25118
25147
  * to be cleared
25119
25148
  */
25120
- const subscriptions$2 = [];
25149
+ const subscriptions$3 = [];
25121
25150
  /* begin_public_function
25122
25151
  id: client.loginAsVisitor
25123
25152
  */
@@ -25160,11 +25189,12 @@ const loginAsVisitor = async (params) => {
25160
25189
  [user] = users;
25161
25190
  client.userId = user.userId;
25162
25191
  client.sessionHandler = params.sessionHandler;
25192
+ client.loginType = 'userId';
25163
25193
  /*
25164
25194
  * Cannot push to subscriptions as watcher needs to continue working even if
25165
25195
  * token expires
25166
25196
  */
25167
- unsubWatcher = client.accessTokenExpiryWatcher(params.sessionHandler);
25197
+ unsubWatcher = client.accessTokenExpiryWatcher();
25168
25198
  setCurrentUser({ user, userType });
25169
25199
  }
25170
25200
  catch (error) {
@@ -25177,16 +25207,16 @@ const loginAsVisitor = async (params) => {
25177
25207
  throw error;
25178
25208
  }
25179
25209
  await initializeMessagePreviewSetting();
25180
- if (subscriptions$2.length === 0) {
25210
+ if (subscriptions$3.length === 0) {
25181
25211
  // handling internal SDK events
25182
- subscriptions$2.push(onTokenTerminated(_ => {
25212
+ subscriptions$3.push(onTokenTerminated(_ => {
25183
25213
  terminateClient();
25184
- subscriptions$2.forEach(fn => fn());
25214
+ subscriptions$3.forEach(fn => fn());
25185
25215
  unsubWatcher();
25186
25216
  }), onTokenExpired(state => {
25187
25217
  SessionWatcher$1.getInstance().setSessionState(state);
25188
25218
  logout();
25189
- subscriptions$2.forEach(fn => fn());
25219
+ subscriptions$3.forEach(fn => fn());
25190
25220
  }));
25191
25221
  }
25192
25222
  return true;
@@ -25215,7 +25245,7 @@ const renewal = () => {
25215
25245
  * Per instance of Renewal, only one renewal is allowed
25216
25246
  */
25217
25247
  const renewToken = async (authToken) => {
25218
- const { userId, displayName } = getCurrentUser();
25248
+ const { userId, displayName } = getActiveUser();
25219
25249
  const deviceId = await getDeviceId();
25220
25250
  const params = { userId, displayName, authToken, deviceId };
25221
25251
  if (client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.sessionHandler) {
@@ -25290,6 +25320,242 @@ const renewal = () => {
25290
25320
  };
25291
25321
  /* end_public_function */
25292
25322
 
25323
+ const validateAccessToken = async ({ token, userId }) => {
25324
+ const client = getActiveClient();
25325
+ // Validate token using sessions API
25326
+ await client.http.get('/api/v3/sessions', {
25327
+ headers: {
25328
+ Authorization: `Bearer ${token.accessToken}`,
25329
+ },
25330
+ });
25331
+ // Get user details
25332
+ const { data: { users }, } = await client.http.get(`/api/v3/users/${userId}`, {
25333
+ headers: {
25334
+ Authorization: `Bearer ${token.accessToken}`,
25335
+ },
25336
+ });
25337
+ const user = users.find((u) => u.userId === userId);
25338
+ client.http.defaults.headers.common.Authorization = `Bearer ${token.accessToken}`;
25339
+ client.http.defaults.metadata = {
25340
+ tokenExpiry: token.expiresAt,
25341
+ isGlobalBanned: false,
25342
+ isUserDeleted: false,
25343
+ };
25344
+ client.upload.defaults.headers.common.Authorization = `Bearer ${token.accessToken}`;
25345
+ client.upload.defaults.metadata = {
25346
+ tokenExpiry: token.expiresAt,
25347
+ isGlobalBanned: false,
25348
+ isUserDeleted: false,
25349
+ };
25350
+ client.token = token;
25351
+ return user;
25352
+ };
25353
+
25354
+ const isSameUserId = (token) => {
25355
+ var _a;
25356
+ const client = getActiveClient();
25357
+ const decoded = jwtDecode(token);
25358
+ return ((_a = decoded === null || decoded === void 0 ? void 0 : decoded.user) === null || _a === void 0 ? void 0 : _a.publicUserId) === client.userId;
25359
+ };
25360
+
25361
+ let subscriptions$2 = [];
25362
+ async function runMqtt$1() {
25363
+ await modifyMqttConnection();
25364
+ }
25365
+ /* begin_public_function
25366
+ id: client.loginWithAccessToken
25367
+ */
25368
+ /**
25369
+ * ```js
25370
+ * import { loginWithAccessToken } from '@amityco/ts-sdk'
25371
+ * const success = await loginWithAccessToken('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...')
25372
+ * ```
25373
+ *
25374
+ * Authenticates a user using a pre-existing access token, allowing direct login without user credentials.
25375
+ * Designed for customers who manage access tokens on their own backend.
25376
+ *
25377
+ * @param accessToken JWT access token signed by customer's backend containing user identity
25378
+ * @returns true if authentication is successful
25379
+ *
25380
+ * @category Client API
25381
+ * @async
25382
+ */
25383
+ const loginWithAccessToken = async (accessToken) => {
25384
+ var _a, _b;
25385
+ const client = getActiveClient();
25386
+ let unsubWatcher;
25387
+ client.log('client/api/loginWithAccessToken', {
25388
+ apiKey: client.apiKey,
25389
+ sessionState: client.sessionState,
25390
+ });
25391
+ // Validate input
25392
+ if (!accessToken || typeof accessToken !== 'string' || accessToken.trim() === '') {
25393
+ throw new ASCError('Access token must be a non-empty string', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
25394
+ }
25395
+ let decoded;
25396
+ try {
25397
+ decoded = jwtDecode(accessToken);
25398
+ }
25399
+ catch (error) {
25400
+ throw new ASCError('Invalid access token format', 400100 /* Amity.ServerError.UNAUTHORIZED */, "error" /* Amity.ErrorLevel.ERROR */);
25401
+ }
25402
+ // Extract userId from token
25403
+ const userId = ((_a = decoded === null || decoded === void 0 ? void 0 : decoded.user) === null || _a === void 0 ? void 0 : _a.publicUserId) || ((_b = decoded === null || decoded === void 0 ? void 0 : decoded.user) === null || _b === void 0 ? void 0 : _b.userId);
25404
+ if (!userId) {
25405
+ throw new ASCError('Access token does not contain userId', 400100 /* Amity.ServerError.UNAUTHORIZED */, "error" /* Amity.ErrorLevel.ERROR */);
25406
+ }
25407
+ // Handle existing connected user
25408
+ if (client.userId) {
25409
+ const sameUser = isSameUserId(accessToken);
25410
+ if (!sameUser) {
25411
+ // Different user - do full logout
25412
+ await logout();
25413
+ }
25414
+ }
25415
+ try {
25416
+ // Set state to establishing
25417
+ setSessionState("establishing" /* Amity.SessionStates.ESTABLISHING */);
25418
+ // Prepare token object for validation
25419
+ const tokenObject = {
25420
+ accessToken,
25421
+ issuedAt: decoded.iat ? new Date(decoded.iat * 1000).toISOString() : new Date().toISOString(),
25422
+ expiresAt: new Date(decoded.exp * 1000).toISOString(),
25423
+ };
25424
+ // Validate token and get user
25425
+ const user = await validateAccessToken({
25426
+ token: tokenObject,
25427
+ userId,
25428
+ });
25429
+ if (user == null) {
25430
+ setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
25431
+ throw new ASCError(`User ${userId} has not been found`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
25432
+ }
25433
+ if (user.isDeleted) {
25434
+ setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
25435
+ throw new ASCError(`User ${userId} has been deleted`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
25436
+ }
25437
+ if (user.isGlobalBanned) {
25438
+ setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
25439
+ throw new ASCError(`User ${userId} is globally banned`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
25440
+ }
25441
+ // Set userId and login method flag
25442
+ client.userId = user.userId;
25443
+ // Set login method flag to 'accessToken' in platform-specific login session
25444
+ client.loginType = 'accessToken';
25445
+ // This will be used by the access token handler to determine if token renewal should be invoked
25446
+ // Set active user
25447
+ setActiveUser(user);
25448
+ unsubWatcher = client.accessTokenExpiryWatcher();
25449
+ setSessionState("established" /* Amity.SessionStates.ESTABLISHED */);
25450
+ }
25451
+ catch (error) {
25452
+ // If error occurs, revert session state to not logged in
25453
+ setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
25454
+ // Re-throw if it's already an ASCError
25455
+ if (error instanceof ASCError) {
25456
+ throw error;
25457
+ }
25458
+ // Wrap other errors
25459
+ throw new ASCError((error instanceof Error ? error.message : undefined) || 'Login with access token failed', 400100 /* Amity.ServerError.UNAUTHORIZED */, "error" /* Amity.ErrorLevel.ERROR */);
25460
+ }
25461
+ runMqtt$1();
25462
+ await initializeMessagePreviewSetting();
25463
+ if (subscriptions$2.length === 0) {
25464
+ subscriptions$2 = setupLoginSubscriptions(unsubWatcher);
25465
+ }
25466
+ return true;
25467
+ };
25468
+ /* end_public_function */
25469
+
25470
+ /* begin_public_function
25471
+ id: client.renew_with_accessToken
25472
+ */
25473
+ /*
25474
+ * Renewal defintion accepted by SessionHandler interface
25475
+ *
25476
+ * Tech Spec:
25477
+ * https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Session-Handler
25478
+ *
25479
+ * @category private
25480
+ */
25481
+ const renewWithAccessToken = async (accessToken) => {
25482
+ var _a, _b;
25483
+ const client = getActiveClient();
25484
+ client.log('initiating access token renewal');
25485
+ /*
25486
+ * Renews a token if it is hasn't been renewed before. Also marks token as
25487
+ * renewed once done
25488
+ * Per instance of Renewal, only one renewal is allowed
25489
+ */
25490
+ // Validate input
25491
+ if (!accessToken || typeof accessToken !== 'string' || accessToken.trim() === '') {
25492
+ throw new ASCError('Access token must be a non-empty string', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
25493
+ }
25494
+ let decoded;
25495
+ try {
25496
+ decoded = jwtDecode(accessToken);
25497
+ }
25498
+ catch (error) {
25499
+ throw new ASCError('Invalid access token format', 400100 /* Amity.ServerError.UNAUTHORIZED */, "error" /* Amity.ErrorLevel.ERROR */);
25500
+ }
25501
+ // Extract userId from token
25502
+ const userId = ((_a = decoded === null || decoded === void 0 ? void 0 : decoded.user) === null || _a === void 0 ? void 0 : _a.publicUserId) || ((_b = decoded === null || decoded === void 0 ? void 0 : decoded.user) === null || _b === void 0 ? void 0 : _b.userId);
25503
+ if (!userId) {
25504
+ throw new ASCError('Access token does not contain userId', 400100 /* Amity.ServerError.UNAUTHORIZED */, "error" /* Amity.ErrorLevel.ERROR */);
25505
+ }
25506
+ // Handle existing connected user
25507
+ if (client.userId) {
25508
+ const sameUser = isSameUserId(accessToken);
25509
+ if (!sameUser) {
25510
+ // Different user - do full logout
25511
+ await logout();
25512
+ }
25513
+ }
25514
+ const tokenObject = {
25515
+ accessToken,
25516
+ issuedAt: decoded.iat ? new Date(decoded.iat * 1000).toISOString() : new Date().toISOString(),
25517
+ expiresAt: new Date(decoded.exp * 1000).toISOString(),
25518
+ };
25519
+ if (client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.sessionHandler) {
25520
+ await loginWithAccessToken(accessToken);
25521
+ }
25522
+ else {
25523
+ // about to expire
25524
+ await validateAccessToken({
25525
+ token: tokenObject,
25526
+ userId,
25527
+ });
25528
+ }
25529
+ };
25530
+ /* end_public_function */
25531
+
25532
+ /**
25533
+ * Helper function to renew access token using the accessTokenHandler
25534
+ * Handles error catching and logging
25535
+ *
25536
+ * @param useScheduledTask - Whether to wrap renewal in scheduleTask (for token expired case)
25537
+ * @category private
25538
+ */
25539
+ const renewTokenWithHandler = async ({ useScheduledTask = false, }) => {
25540
+ const client = getActiveClient();
25541
+ if (!client.userId || !client.accessTokenHandler) {
25542
+ return;
25543
+ }
25544
+ try {
25545
+ const newToken = await client.accessTokenHandler.onTokenRenew(client.userId);
25546
+ if (useScheduledTask) {
25547
+ scheduleTask(() => renewWithAccessToken(newToken));
25548
+ }
25549
+ else {
25550
+ renewWithAccessToken(newToken);
25551
+ }
25552
+ }
25553
+ catch (error) {
25554
+ client.log('Proactive token renewal failed, will retry when token expires', error);
25555
+ // Will fallback to expired token flow
25556
+ }
25557
+ };
25558
+
25293
25559
  const ABOUT_TO_EXPIRE_THRESHOLD = 80 / 100;
25294
25560
  const COMPENSATED_DELAY = 5 * MINUTE;
25295
25561
  /*
@@ -25325,10 +25591,11 @@ const isAboutToExpire = (params) => {
25325
25591
  *
25326
25592
  * @category private
25327
25593
  */
25328
- const accessTokenExpiryWatcher = (sessionHandler) => {
25329
- const interval = setInterval(() => {
25594
+ const accessTokenExpiryWatcher = () => {
25595
+ const interval = setInterval(async () => {
25330
25596
  const client = getActiveClient();
25331
- if (!client.token)
25597
+ const { sessionHandler, accessTokenHandler, loginType } = client;
25598
+ if (!client.token || !client.userId)
25332
25599
  return;
25333
25600
  const { issuedAt, expiresAt } = client.token;
25334
25601
  if (isExpired(expiresAt)) {
@@ -25339,18 +25606,38 @@ const accessTokenExpiryWatcher = (sessionHandler) => {
25339
25606
  */
25340
25607
  fireEvent('tokenExpired', "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */);
25341
25608
  /*
25342
- * https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Automatically-initiate-renewal-flow
25343
- *
25344
- * Why sechduled task?
25345
- * Since fireEvent is scheduled, it will be called
25346
- * after sessionHandler leading to an invalid state change from
25347
- * establishing to tokenExpired
25609
+ * Check loginType to determine which handler to use:
25610
+ * - 'accessToken' = use accessTokenHandler
25611
+ * - 'userId' = use sessionHandler
25348
25612
  */
25349
- scheduleTask(() => sessionHandler.sessionWillRenewAccessToken(renewal()));
25613
+ if (loginType === 'accessToken' && accessTokenHandler) {
25614
+ await renewTokenWithHandler({ useScheduledTask: false });
25615
+ }
25616
+ else if (loginType === 'userId' && sessionHandler) {
25617
+ /*
25618
+ * https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Automatically-initiate-renewal-flow
25619
+ *
25620
+ * Why scheduled task?
25621
+ * Since fireEvent is scheduled, it will be called
25622
+ * after sessionHandler leading to an invalid state change from
25623
+ * establishing to tokenExpired
25624
+ */
25625
+ scheduleTask(() => sessionHandler.sessionWillRenewAccessToken(renewal()));
25626
+ }
25350
25627
  return;
25351
25628
  }
25352
25629
  if (isAboutToExpire({ expiresAt, issuedAt })) {
25353
- sessionHandler.sessionWillRenewAccessToken(renewal());
25630
+ /*
25631
+ * Check loginType to determine which handler to use for proactive renewal:
25632
+ * - 'accessToken' = use accessTokenHandler
25633
+ * - 'userId' = use sessionHandler
25634
+ */
25635
+ if (loginType === 'accessToken' && accessTokenHandler) {
25636
+ await renewTokenWithHandler({ useScheduledTask: false });
25637
+ }
25638
+ else if (loginType === 'userId' && sessionHandler) {
25639
+ sessionHandler.sessionWillRenewAccessToken(renewal());
25640
+ }
25354
25641
  }
25355
25642
  }, ACCESS_TOKEN_WATCHER_INTERVAL);
25356
25643
  return () => clearInterval(interval);
@@ -25883,6 +26170,7 @@ const secureLogout = async () => {
25883
26170
  };
25884
26171
  /* end_public_function */
25885
26172
 
26173
+ /* eslint-disable no-param-reassign */
25886
26174
  /*
25887
26175
  * declared earlier to accomodate case when logging in with a different user
25888
26176
  * than the one already connected, in which case the existing subscriptions need
@@ -25892,38 +26180,6 @@ let subscriptions$1 = [];
25892
26180
  async function runMqtt() {
25893
26181
  await modifyMqttConnection();
25894
26182
  }
25895
- const isSameUserId = (token) => {
25896
- var _a;
25897
- const client = getActiveClient();
25898
- const decoded = jwtDecode(token);
25899
- return ((_a = decoded === null || decoded === void 0 ? void 0 : decoded.user) === null || _a === void 0 ? void 0 : _a.publicUserId) === client.userId;
25900
- };
25901
- const validateAccessToken = async ({ token, userId }) => {
25902
- const client = getActiveClient();
25903
- // begin establishing session
25904
- setSessionState("establishing" /* Amity.SessionStates.ESTABLISHING */);
25905
- const { data: { users }, } = await client.http.get(`/api/v3/users/${userId}`, {
25906
- headers: {
25907
- Authorization: `Bearer ${token.accessToken}`,
25908
- },
25909
- });
25910
- const user = users.find((u) => u.userId === userId);
25911
- client.http.defaults.headers.common.Authorization = `Bearer ${token.accessToken}`;
25912
- client.http.defaults.metadata = {
25913
- tokenExpiry: token.expiresAt,
25914
- isGlobalBanned: false,
25915
- isUserDeleted: false,
25916
- };
25917
- client.upload.defaults.headers.common.Authorization = `Bearer ${token.accessToken}`;
25918
- client.upload.defaults.metadata = {
25919
- tokenExpiry: token.expiresAt,
25920
- isGlobalBanned: false,
25921
- isUserDeleted: false,
25922
- };
25923
- client.token = token;
25924
- setSessionState("established" /* Amity.SessionStates.ESTABLISHED */);
25925
- return user;
25926
- };
25927
26183
  /* begin_public_function
25928
26184
  id: client.resumeSession
25929
26185
  */
@@ -25972,6 +26228,7 @@ const resumeSession = async (params, sessionHandler, config) => {
25972
26228
  }
25973
26229
  }
25974
26230
  try {
26231
+ setSessionState("establishing" /* Amity.SessionStates.ESTABLISHING */);
25975
26232
  const user = await validateAccessToken(params);
25976
26233
  if (user == null) {
25977
26234
  throw new ASCError(`${params.userId} has not been found`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
@@ -26078,13 +26335,13 @@ class GlobalFileAccessType {
26078
26335
  }
26079
26336
  }
26080
26337
  _GlobalFileAccessType_fileAccessType = new WeakMap();
26081
- let instance;
26338
+ let instance$1;
26082
26339
  var GlobalFileAccessType$1 = {
26083
26340
  getInstance: () => {
26084
- if (!instance) {
26085
- instance = new GlobalFileAccessType();
26341
+ if (!instance$1) {
26342
+ instance$1 = new GlobalFileAccessType();
26086
26343
  }
26087
- return instance;
26344
+ return instance$1;
26088
26345
  },
26089
26346
  };
26090
26347
 
@@ -26262,11 +26519,12 @@ const loginAsBot = async (params) => {
26262
26519
  [user] = users;
26263
26520
  client.userId = user.userId;
26264
26521
  client.sessionHandler = params.sessionHandler;
26522
+ client.loginType = 'userId';
26265
26523
  /*
26266
26524
  * Cannot push to subscriptions as watcher needs to continue working even if
26267
26525
  * token expires
26268
26526
  */
26269
- unsubWatcher = client.accessTokenExpiryWatcher(params.sessionHandler);
26527
+ unsubWatcher = client.accessTokenExpiryWatcher();
26270
26528
  setCurrentUser({ user, userType });
26271
26529
  }
26272
26530
  catch (error) {
@@ -26295,6 +26553,53 @@ const loginAsBot = async (params) => {
26295
26553
  };
26296
26554
  /* end_public_function */
26297
26555
 
26556
+ /* begin_public_function
26557
+ id: client.setAccessTokenHandler
26558
+ */
26559
+ /**
26560
+ * ```js
26561
+ * import { setAccessTokenHandler } from '@amityco/ts-sdk'
26562
+ *
26563
+ * const tokenHandler = {
26564
+ * async onTokenRenew() {
26565
+ * const response = await fetch('https://your-backend.com/api/refresh-token', {
26566
+ * method: 'POST',
26567
+ * credentials: 'include',
26568
+ * });
26569
+ * const data = await response.json();
26570
+ * return data.accessToken;
26571
+ * }
26572
+ * };
26573
+ *
26574
+ * setAccessTokenHandler(tokenHandler);
26575
+ * ```
26576
+ *
26577
+ * Registers a custom handler for managing access token renewal and expiration events.
26578
+ * This enables automatic token refresh and graceful handling of expired tokens.
26579
+ *
26580
+ * Must be called before loginWithAccessToken() to ensure the handler is available
26581
+ * when token expiry is detected.
26582
+ *
26583
+ * @param accessTokenHandler Handler object implementing token renewal callbacks
26584
+ * @returns void
26585
+ *
26586
+ * @category Client API
26587
+ */
26588
+ const setAccessTokenHandler = (accessTokenHandler) => {
26589
+ const client = getActiveClient();
26590
+ client.log('client/api/setAccessTokenHandler', {
26591
+ apiKey: client.apiKey,
26592
+ sessionState: client.sessionState,
26593
+ hasOnTokenRenew: typeof (accessTokenHandler === null || accessTokenHandler === void 0 ? void 0 : accessTokenHandler.onTokenRenew) === 'function',
26594
+ });
26595
+ // Validate handler has required method
26596
+ if (!accessTokenHandler || typeof accessTokenHandler.onTokenRenew !== 'function') {
26597
+ throw new Error('AccessTokenHandler must implement onTokenRenew() method');
26598
+ }
26599
+ // Register the handler
26600
+ client.accessTokenHandler = accessTokenHandler;
26601
+ };
26602
+
26298
26603
  /**
26299
26604
  * ```js
26300
26605
  * import { onChannelMarkerFetched } from '@amityco/ts-sdk'
@@ -26654,6 +26959,7 @@ var index$r = /*#__PURE__*/Object.freeze({
26654
26959
  setActiveUser: setActiveUser,
26655
26960
  createClient: createClient,
26656
26961
  login: login,
26962
+ loginWithAccessToken: loginWithAccessToken,
26657
26963
  logout: logout,
26658
26964
  secureLogout: secureLogout,
26659
26965
  resumeSession: resumeSession,
@@ -26672,6 +26978,7 @@ var index$r = /*#__PURE__*/Object.freeze({
26672
26978
  getCurrentUser: getCurrentUser,
26673
26979
  getCurrentUserType: getCurrentUserType,
26674
26980
  setCurrentUserType: setCurrentUserType,
26981
+ setAccessTokenHandler: setAccessTokenHandler,
26675
26982
  onConnectionError: onConnectionError,
26676
26983
  onClientDisconnected: onClientDisconnected,
26677
26984
  onClientBanned: onClientBanned,
@@ -28704,7 +29011,7 @@ const getWatchSessionStorage = () => {
28704
29011
  return storageInstance;
28705
29012
  };
28706
29013
 
28707
- const privateKey = "MIIEpQIBAAKCAQEAwAEc/oZgYIvKSUG/C3mONYLR4ZPgAjMEX4bJ+xqqakUDRtqlNO+eZs2blQ1Ko0DBkqPExyQezvjibH5W2UZBV5RaBTlTcNVKTToMBEGesAfaEcM3qUyQHxdbFYZv6P4sb14dcwxTQ8usmaV8ooiR1Fcaso5ZWYcZ8Hb46FbQ7OoVumsBtPWwfZ4f003o5VCl6AIM6lcLv9UDLlFVYhE+PeXpRHtfWlGqxMvqC9oinlwhL6nWv6VjQXW4nhcib72dPBzfHT7k/PMKto2SxALYdb68ENiAGuJLWi3AUHSyYCJK2w7wIlWfJUAI0v26ub10IpExr6D5QuW2577jjP93iwIDAQABAoIBAFWfqXhwIIatkFY+9Z1+ZcbDQimgsmMIsUiQaX6Lk7e0cxOj6czDlxYtVtaPiNtow2pLkjNkjkCqiP7tEHnwdK9DvylZOTa2R15NJpK3WLcTqVIGhsn/FL5owfvFah6zSsmXZParZm5zY9NZE03ALZhOB9/cz0e3kf/EbpfeL2mW7MApyiUt5i09ycchroOpcWp73ipIxvgigtZyUGFmsQicWhUs28F0D7w4Qfk76yG3nqXeb+BAMhCaIaa/k/aAxhiZG/ygEQWQrcC8gfe+jyicMAQPDEVS9YuUMGsLjIjKuVLZzp2xirQnhc2i2zVNEIvG6soprPOBEMQugzrtX5ECgYEA3b7KAbBIbDl1e4ZSCWhHdHkiWVZHaopsR/LhqDDNhXjWjq3AesgV6k0j9EdziMn/HmmOso0bz99GTV3JZf4A9ztTLumJlkHbdVtlgOqSjrFLj12rH9KXTheyIhWSpUmm8+WB1xasFbqpvJaGo7F3pd2Fqj1XR4mp5BO7c/t7LJ0CgYEA3aouEzXQ9THRKYocdfY69EI1Il1t/d/RSqqd9BxEjxBgxkM13ZiYIn/R4WW/nCUrlmhxG44Aa2Gob4Ahfsui2xKTg/g/3Zk/rAxAEGkfOLGoenaJMD41fH4wUq3FRYwkvnaMb9Hd6f/TlBHslIRa2NN58bSBGJCyBP2b59+2+EcCgYEAixDVRXvV37GlYUOa/XVdosk5Zoe6oDGRuQm0xbNdoUBoZvDHDvme7ONWEiQha/8qtVsD+CyQ7awcPfb8kK9c0bBt+bTS6d4BkTcxkEkMgtrkBVR8Nqfu5jXsLH4VCv4G61zbMhZw8+ut+az5YX2yCN7Frj9sFlxapMRPQmzMEe0CgYEAumsAzM8ZqNv4mAK65Mnr0rhLj1cbxcKRdUYACOgtEFQpzxN/HZnTeFAe5nx3pI3uFlRHq3DFEYnT6dHMWaJQmAULYpVIwMi9L6gtyJ9fzoI6uqMtxRDMUqKdaSsTGOY/kJ6KhQ/unXi1K3XXjR+yd1+C0q+HUm1+CYxvrZYLfskCgYEArsEy+IQOiqniJ0NE2vVUF+UK/IRZaic9YKcpov5Ot7Vvzm/MnnW4N1ljVskocETBWMmPUvNSExVjPebi+rxd8fa5kY8BJScPTzMFbunZn/wjtGdcM10qdlVQ9doG61A/9P3ezFKCfS4AvF/H/59LcSx2Bh28fp3/efiVIOpVd4Y=";
29014
+ const privateKey = "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDHo80SecH7FuF2\nhFYnb+l26/VN8UMLXAQFLnxciNTEwkGVFMpdezlH8rU2HtUJL4RETogbAOLVY0XM\njs6sPn8G1nALmh9qeDpUtVqFOVtBHxEZ910TLOtQiunjqJKO5nWdqZ71EC3OFluR\niGQkO84BiIFbv37ub7xl3S8XarbtKoLcyVpkDHi+1wx1pgCAn6gtBUgckPL5NR8j\nLseabl3HAXQfhTCKo4tmOFM2Dxwl1IUMmIJrJg/aIU/U0tj/1Eoo7mG0JcNWX19l\nW3EecCbi0ncCJOrkUdwlBrcjaMayaX/ubEwyUeTGiLdyc4L3GRLHjyK8xgVNXRMH\nbZWJ2a5NAgMBAAECggEASxuE+35zTFO/XydKgmvIGcWL9FbgMlXb7Vcf0nBoG945\nbiz0NVc2paraIhJXc608xbYF3qLmtAE1MVBI0ORyRdBHNxY024l/6H6SH60Ed+uI\nM4ysp5ourY6Vj+DLwpdRiI9YDjqYAQDIUmhNxJP7XPhOMoZI6st+xZQBM34ic/bv\nAMSJm9OZphSp3+qXVkFZztr2mxD2EZSJJLYxi8BCdgM2qhazalbcJ6zDKHCZWVWm\n8RRxDGldyMb/237JxETzP40tAlzOZDmBAbUgEnurDJ93RVDIE3rbZUshwgeQd18a\nem096mWgvB1AIKYgsTAR3pw+V19YWAjq/glP6fz8wQKBgQD/oQq+ukKF0PRgBeM5\ngeTjSwsdGppQLmf5ndujvoiz/TpdjDEPu6R8kigQr1rG2t4K/yfdZoI8RdmJD1al\n3Q7N9hofooSy4rj6E3txzWZCHJjHad2cnCp/O26HiReGAl7wTcfTmNdiFHhZQzm5\nJBkvWAiwuvQMNfEbnXxw6/vIDwKBgQDH7fX8gsc77JLvAWgp1MaQN/sbqVb6JeT1\nFQfR8E/WFCSmzQBtNzd5KgYuCeelwr/8DyYytvN2BzCYZXp73gI1jF3YlW5jVn74\nOY6TwQ095digwo6Z0yuxopdIOApKgAkL9PRKgNrqAf3NAyMua6lOGifzjDojC3KU\nfylQmxMn4wKBgHp2B9O/H0dEBw5JQ8W0+JX6yWQz7mEjGiR2/1W+XXb8hQ1zr709\nw1r6Gb+EghRpnZ3fBpYGGbYOMFx8wKHM+N6qW3F0ReX8v2juFGE8aRSa5oYBrWzt\nU16Idjbv8hj84cZ1PJmdyvDtpYn9rpWHOZl4rxEbPvbqkIsOMyNVqdT5AoGAOSge\nmwIIU2le2FVeohbibXiToWTYKMuMmURZ5/r72AgKMmWJKbAPe+Q3wBG01/7FRBpQ\noU8Ma0HC8s6QJbliiEyIx9JwrJWd1vkdecBHONrtA4ibm/5zD2WcOllLF+FitLhi\n3qnX6+6F0IaFGFBPJrTzlv0P4dTz/OAdv52V7GECgYEA2TttOKBAqWllgOaZOkql\nLVMJVmgR7s6tLi1+cEP8ZcapV9aRbRzTAKXm4f8AEhtlG9F9kCOvHYCYGi6JaiWJ\nZkHjeex3T+eE6Di6y5Bm/Ift5jtVhJ4jCVwHOKTMej79NPUFTJfv8hCo29haBDv6\nRXFrv+T21KCcw8k3sJeJWWQ=\n-----END PRIVATE KEY-----";
28708
29015
  /*
28709
29016
  * The crypto algorithm used for importing key and signing string
28710
29017
  */
@@ -33029,6 +33336,147 @@ removeReaction.optimistically = (referenceType, referenceId, reactionName) => {
33029
33336
  return !((_d = reaction === null || reaction === void 0 ? void 0 : reaction.myReactions) === null || _d === void 0 ? void 0 : _d.includes(reactionName));
33030
33337
  };
33031
33338
 
33339
+ class ResetTask {
33340
+ constructor(postId, latestCreatedAt, serverCommentCount) {
33341
+ this.postId = postId;
33342
+ this.latestCreatedAt = latestCreatedAt;
33343
+ this.serverCommentCount = serverCommentCount;
33344
+ }
33345
+ }
33346
+
33347
+ // Task to track comment creation
33348
+ class CreateTask {
33349
+ constructor(postId, commentId, createdAt) {
33350
+ this.postId = postId;
33351
+ this.commentId = commentId;
33352
+ this.createdAt = createdAt;
33353
+ }
33354
+ }
33355
+
33356
+ // Task to track comment deletion
33357
+ class DeleteTask {
33358
+ constructor(postId, commentId) {
33359
+ this.postId = postId;
33360
+ this.commentId = commentId;
33361
+ }
33362
+ }
33363
+
33364
+ class CommentChange {
33365
+ constructor(latestCreatedAt, serverCommentCount) {
33366
+ this.latestCommentCreatedAt = latestCreatedAt;
33367
+ this.serverCommentCount = serverCommentCount;
33368
+ this.createdCommentIds = new Set();
33369
+ this.deletedCommentIds = new Set();
33370
+ }
33371
+ }
33372
+
33373
+ class PostCommentCountEngine {
33374
+ constructor() {
33375
+ this.isProcessing = false;
33376
+ this.tasks = [];
33377
+ this.commentChangeTracker = new Map();
33378
+ }
33379
+ queueCommentChangeTask(task) {
33380
+ this.tasks.push(task);
33381
+ if (!this.isProcessing) {
33382
+ this.processCommentChangeTask();
33383
+ }
33384
+ }
33385
+ processCommentChangeTask() {
33386
+ if (this.isProcessing) {
33387
+ return;
33388
+ }
33389
+ this.isProcessing = true;
33390
+ if (this.tasks.length === 0) {
33391
+ this.isProcessing = false;
33392
+ return;
33393
+ }
33394
+ // Process in capped batches, coalescing updates
33395
+ const batch = this.tasks.splice(0, PostCommentCountEngine.BATCH_SIZE);
33396
+ const modifiedPostIds = new Set();
33397
+ batch.forEach(task => {
33398
+ let modified = false;
33399
+ if (task instanceof ResetTask) {
33400
+ modified = this.processResetTaskInternal(task);
33401
+ }
33402
+ else if (task instanceof CreateTask) {
33403
+ modified = this.processCreateTaskInternal(task);
33404
+ }
33405
+ else if (task instanceof DeleteTask) {
33406
+ modified = this.processDeleteTaskInternal(task);
33407
+ }
33408
+ if (modified) {
33409
+ modifiedPostIds.add(task.postId);
33410
+ }
33411
+ });
33412
+ // Publish one update per modified post
33413
+ modifiedPostIds.forEach(postId => {
33414
+ const count = this.computeCommentCount(postId);
33415
+ PostCommentCountEngine.publishUpdate(postId, count);
33416
+ });
33417
+ this.isProcessing = false;
33418
+ // Recurse if more tasks remain
33419
+ if (this.tasks.length > 0) {
33420
+ this.processCommentChangeTask();
33421
+ }
33422
+ }
33423
+ processResetTaskInternal(task) {
33424
+ // Always creates/overwrites tracker
33425
+ this.commentChangeTracker.set(task.postId, new CommentChange(task.latestCreatedAt, task.serverCommentCount));
33426
+ return true;
33427
+ }
33428
+ processCreateTaskInternal(task) {
33429
+ const tracker = this.commentChangeTracker.get(task.postId);
33430
+ if (!tracker)
33431
+ return false; // No tracker, skip
33432
+ if (tracker.createdCommentIds.has(task.commentId))
33433
+ return false; // Deduplication
33434
+ if (task.createdAt <= tracker.latestCommentCreatedAt)
33435
+ return false; // Timestamp filtering
33436
+ tracker.createdCommentIds.add(task.commentId);
33437
+ return true;
33438
+ }
33439
+ processDeleteTaskInternal(task) {
33440
+ const tracker = this.commentChangeTracker.get(task.postId);
33441
+ if (!tracker)
33442
+ return false; // No tracker, skip
33443
+ if (tracker.deletedCommentIds.has(task.commentId))
33444
+ return false; // Deduplication
33445
+ tracker.deletedCommentIds.add(task.commentId);
33446
+ return true;
33447
+ }
33448
+ computeCommentCount(postId) {
33449
+ const tracker = this.commentChangeTracker.get(postId);
33450
+ if (!tracker)
33451
+ return 0;
33452
+ const count = tracker.serverCommentCount + tracker.createdCommentIds.size - tracker.deletedCommentIds.size;
33453
+ return Math.max(0, count);
33454
+ }
33455
+ static publishUpdate(postId, newCount) {
33456
+ var _a;
33457
+ const queryKey = ['post', 'get', postId];
33458
+ mergeInCache(queryKey, {
33459
+ localCommentCount: newCount,
33460
+ });
33461
+ const postPayload = (_a = pullFromCache(queryKey)) === null || _a === void 0 ? void 0 : _a.data;
33462
+ if (!postPayload)
33463
+ return;
33464
+ fireEvent('local.post.updated', {
33465
+ posts: [postPayload],
33466
+ });
33467
+ }
33468
+ }
33469
+ PostCommentCountEngine.BATCH_SIZE = 50;
33470
+ let instance;
33471
+ var PostCommentCountEngine$1 = {
33472
+ getInstance: () => {
33473
+ if (!instance) {
33474
+ instance = new PostCommentCountEngine();
33475
+ }
33476
+ return instance;
33477
+ },
33478
+ };
33479
+
33032
33480
  const updateStreamReferences = (streams, streamId, postId) => {
33033
33481
  if (!streamId)
33034
33482
  return streams;
@@ -33048,14 +33496,26 @@ const preparePostPayload = (payload) => {
33048
33496
  let mappedNewStream = [];
33049
33497
  // feed type
33050
33498
  const posts = postsData.map(post => {
33051
- var _a, _b;
33499
+ var _a, _b, _c, _d;
33052
33500
  const feedType = (_a = postPayload.feeds.find(feed => feed.feedId === post.feedId)) === null || _a === void 0 ? void 0 : _a.feedType;
33053
33501
  const childPosts = payload.postChildren.filter(children => children.parentPostId === post.postId);
33054
33502
  if (childPosts.length > 0 && isAmityLivestreamPost(childPosts[0])) {
33055
33503
  mappedNewStream = updateStreamReferences(videoStreamings, (_b = childPosts[0].data) === null || _b === void 0 ? void 0 : _b.streamId, post.postId);
33056
33504
  }
33505
+ // --- Computed Comment Count: ResetTask integration ---
33506
+ // Find all comments for this post (referenceType === 'post' && referenceId === postId)
33507
+ const allComments = (payload.comments || []).filter((c) => c.referenceType === 'post' && c.referenceId === post.postId);
33508
+ // Compute latestCreatedAt
33509
+ const latestCreatedAt = allComments.length === 0
33510
+ ? new Date().toISOString()
33511
+ : allComments
33512
+ .map(c => c.createdAt)
33513
+ .sort()
33514
+ .at(-1);
33515
+ // Queue ResetTask for this post
33516
+ PostCommentCountEngine$1.getInstance().queueCommentChangeTask(new ResetTask(post.postId, latestCreatedAt, (_c = post.commentsCount) !== null && _c !== void 0 ? _c : 0));
33057
33517
  return Object.assign(Object.assign({}, post), { childPosts,
33058
- feedType });
33518
+ feedType, localCommentCount: (_d = post.localCommentCount) !== null && _d !== void 0 ? _d : post.commentsCount });
33059
33519
  });
33060
33520
  return Object.assign(Object.assign({}, postPayload), { postChildren, videoStreamings: mappedNewStream, posts, communities: communityWithMembershipStatus, communityUsers: mappedCommunityUsers });
33061
33521
  };
@@ -33157,14 +33617,12 @@ const createLocalPostEventSubscriber = (event, callback) => {
33157
33617
  callback(payload.posts[0]);
33158
33618
  }
33159
33619
  else {
33160
- const data = preparePostPayload(payload);
33161
- const { communities } = data;
33162
- ingestInCache(data);
33620
+ const { communities } = payload;
33163
33621
  if ((communities === null || communities === void 0 ? void 0 : communities[0]) && !['local.post.updated'].includes(event)) {
33164
33622
  fireEvent('community.updated', {
33165
33623
  communities,
33166
33624
  categories: [],
33167
- communityUsers: data.communityUsers,
33625
+ communityUsers: payload.communityUsers,
33168
33626
  feeds: [],
33169
33627
  files: [],
33170
33628
  users: [],
@@ -33435,7 +33893,7 @@ const createCommentEventSubscriber = (event, callback) => {
33435
33893
  const createLocalCommentEventSubscriber = (event, callback) => {
33436
33894
  const client = getActiveClient();
33437
33895
  const filter = (payload) => {
33438
- var _a, _b;
33896
+ var _a, _b, _c, _d, _e;
33439
33897
  if (!client.cache) {
33440
33898
  // TODO: here we are missing specific properties here!
33441
33899
  callback(LinkedObject.comment(payload.comments[0]));
@@ -33475,7 +33933,13 @@ const createLocalCommentEventSubscriber = (event, callback) => {
33475
33933
  }
33476
33934
  }
33477
33935
  }
33478
- const queries = (_a = queryCache(['comment', 'query'])) === null || _a === void 0 ? void 0 : _a.filter(({ key }) => { var _a; return ((_a = key[2]) === null || _a === void 0 ? void 0 : _a.referenceId) === comment.data.referenceId; });
33936
+ else {
33937
+ const postCacheKey = ['post', 'get', comments[0].referenceId];
33938
+ const postCache = (_a = pullFromCache(postCacheKey)) === null || _a === void 0 ? void 0 : _a.data;
33939
+ postCache === null || postCache === void 0 ? void 0 : postCache.comments.push((_b = comments[0]) === null || _b === void 0 ? void 0 : _b.commentId);
33940
+ pushToCache(postCacheKey, postCache);
33941
+ }
33942
+ const queries = (_c = queryCache(['comment', 'query'])) === null || _c === void 0 ? void 0 : _c.filter(({ key }) => { var _a; return ((_a = key[2]) === null || _a === void 0 ? void 0 : _a.referenceId) === comment.data.referenceId; });
33479
33943
  queries === null || queries === void 0 ? void 0 : queries.map(({ key, data }) => upsertInCache(key, data, { cachedAt: -1 }));
33480
33944
  }
33481
33945
  if (['local.comment.deleted'].includes(event)) {
@@ -33507,7 +33971,13 @@ const createLocalCommentEventSubscriber = (event, callback) => {
33507
33971
  }
33508
33972
  }
33509
33973
  }
33510
- const queries = (_b = queryCache(['comment', 'query'])) === null || _b === void 0 ? void 0 : _b.filter(({ key }) => { var _a; return ((_a = key[2]) === null || _a === void 0 ? void 0 : _a.referenceId) === comment.data.referenceId; });
33974
+ else {
33975
+ const postCacheKey = ['post', 'get', comments[0].referenceId];
33976
+ const postCache = (_d = pullFromCache(postCacheKey)) === null || _d === void 0 ? void 0 : _d.data;
33977
+ const updatedPost = Object.assign(Object.assign({}, postCache), { comments: postCache === null || postCache === void 0 ? void 0 : postCache.comments.filter(commentId => { var _a; return commentId !== ((_a = comments[0]) === null || _a === void 0 ? void 0 : _a.commentId); }) });
33978
+ pushToCache(postCacheKey, updatedPost);
33979
+ }
33980
+ const queries = (_e = queryCache(['comment', 'query'])) === null || _e === void 0 ? void 0 : _e.filter(({ key }) => { var _a; return ((_a = key[2]) === null || _a === void 0 ? void 0 : _a.referenceId) === comment.data.referenceId; });
33511
33981
  queries === null || queries === void 0 ? void 0 : queries.map(({ key, data }) => upsertInCache(key, data, { cachedAt: -1 }));
33512
33982
  }
33513
33983
  callback(LinkedObject.comment(comment.data));
@@ -41217,7 +41687,6 @@ getCommentByIds.locally = (commentIds) => {
41217
41687
  * @async
41218
41688
  */
41219
41689
  const createComment = async (bundle) => {
41220
- var _a;
41221
41690
  const client = getActiveClient();
41222
41691
  client.log('comment/createComment', bundle);
41223
41692
  const { data } = await client.http.post('/api/v3/comments', bundle);
@@ -41229,22 +41698,7 @@ const createComment = async (bundle) => {
41229
41698
  if (client.cache)
41230
41699
  ingestInCache(data, { cachedAt });
41231
41700
  if (['post', 'content'].includes(bundle.referenceType)) {
41232
- const post = (_a = pullFromCache(['post', 'get', bundle.referenceId])) === null || _a === void 0 ? void 0 : _a.data;
41233
- if (post) {
41234
- post.commentsCount += 1;
41235
- fireEvent('local.post.updated', {
41236
- posts: [post],
41237
- categories: [],
41238
- comments: [],
41239
- communities: [],
41240
- communityUsers: data.communityUsers,
41241
- feeds: [],
41242
- files: data.files,
41243
- postChildren: [],
41244
- users: data.users,
41245
- videoStreamings: [],
41246
- });
41247
- }
41701
+ PostCommentCountEngine$1.getInstance().queueCommentChangeTask(new CreateTask(bundle.referenceId, comments[0].commentId, data.comments[0].createdAt));
41248
41702
  }
41249
41703
  else if (bundle.referenceType === 'story') {
41250
41704
  const storyIndex = pullFromCache([
@@ -41403,7 +41857,7 @@ getStoryByStoryId$1.locally = (storyId) => {
41403
41857
  * @async
41404
41858
  */
41405
41859
  const deleteComment = async (commentId, permanent = false) => {
41406
- var _a;
41860
+ var _a, _b;
41407
41861
  const client = getActiveClient();
41408
41862
  const comment = await getComment$2(commentId);
41409
41863
  // API-FIX: This endpoint has not been implemented yet.
@@ -41436,26 +41890,14 @@ const deleteComment = async (commentId, permanent = false) => {
41436
41890
  else {
41437
41891
  const post = (_a = pullFromCache(['post', 'get', comment.data.referenceId])) === null || _a === void 0 ? void 0 : _a.data;
41438
41892
  if (post) {
41439
- let removeCount;
41440
- if (!deleted.parentId) {
41441
- // NOTE: delete the parent comment will remove all children comments
41442
- removeCount = deleted.childrenNumber + 1;
41893
+ const engine = PostCommentCountEngine$1.getInstance();
41894
+ engine.queueCommentChangeTask(new DeleteTask(post.postId, commentId));
41895
+ if (!deleted.parentId && ((_b = deleted.children) === null || _b === void 0 ? void 0 : _b.length) > 0) {
41896
+ // NOTE: delete the parent comment will also remove all children comments
41897
+ deleted.children.forEach((childCommentId) => {
41898
+ engine.queueCommentChangeTask(new DeleteTask(post.postId, childCommentId));
41899
+ });
41443
41900
  }
41444
- else
41445
- removeCount = 1;
41446
- post.commentsCount -= removeCount;
41447
- fireEvent('local.post.updated', {
41448
- posts: [post],
41449
- categories: [],
41450
- comments: [],
41451
- communities: [],
41452
- communityUsers: [],
41453
- feeds: [],
41454
- files: [],
41455
- postChildren: [],
41456
- users: [],
41457
- videoStreamings: [],
41458
- });
41459
41901
  }
41460
41902
  }
41461
41903
  fireEvent('local.comment.deleted', {
@@ -42021,47 +42463,6 @@ var index$d = /*#__PURE__*/Object.freeze({
42021
42463
  getComments: getComments
42022
42464
  });
42023
42465
 
42024
- const getPost$1 = async (postId) => {
42025
- const client = getActiveClient();
42026
- client.log('post/getPost', postId);
42027
- isInTombstone('post', postId);
42028
- let payload;
42029
- try {
42030
- // API-FIX: endpoint should not be /list, parameters should be querystring.
42031
- const response = await client.http.get(`/api/v3/posts/${encodeURIComponent(postId)}`);
42032
- payload = response.data;
42033
- }
42034
- catch (error) {
42035
- if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
42036
- pushToTombstone('post', postId);
42037
- }
42038
- throw error;
42039
- }
42040
- const data = prepareMembershipPayload(payload, 'communityUsers');
42041
- const cachedAt = client.cache && Date.now();
42042
- if (client.cache)
42043
- ingestInCache(data, { cachedAt });
42044
- const { posts } = data;
42045
- const result = posts.find(post => post.postId === postId);
42046
- return {
42047
- data: result,
42048
- cachedAt,
42049
- };
42050
- };
42051
- getPost$1.locally = (postId) => {
42052
- const client = getActiveClient();
42053
- client.log('post/getPost.locally', postId);
42054
- if (!client.cache)
42055
- return;
42056
- const cached = pullFromCache(['post', 'get', postId]);
42057
- if (!cached)
42058
- return;
42059
- return {
42060
- data: cached.data,
42061
- cachedAt: cached.cachedAt,
42062
- };
42063
- };
42064
-
42065
42466
  /**
42066
42467
  * ```js
42067
42468
  * import { onLocalPostDeleted } from '@amityco/ts-sdk'
@@ -42160,7 +42561,6 @@ const commentEventHandler$1 = (callback, eventHandler, cacheKey) => {
42160
42561
  const currentCollection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
42161
42562
  if (!currentCollection || !currentCollection.data.includes(comment.referenceId))
42162
42563
  return;
42163
- await getPost$1(comment.referenceId);
42164
42564
  callback(comment);
42165
42565
  });
42166
42566
  };
@@ -42168,12 +42568,8 @@ const generateCommentSubscriptions$1 = (cacheKey) => {
42168
42568
  const eventHandlers = [
42169
42569
  onCommentCreated,
42170
42570
  onCommentDeleted,
42171
- onCommentReactionAdded,
42172
- onCommentReactionRemoved,
42173
42571
  onCommentCreatedLocal,
42174
42572
  onCommentDeleteLocal,
42175
- onLocalCommentReactionAdded,
42176
- onLocalCommentReactionRemoved,
42177
42573
  ];
42178
42574
  return eventHandlers.map(handler => ({
42179
42575
  fn: convertEventPayload((callback) => commentEventHandler$1(callback, handler, cacheKey), 'referenceId', 'post'),
@@ -42537,6 +42933,47 @@ class UserFeedQueryStreamController extends QueryStreamController {
42537
42933
  }
42538
42934
  }
42539
42935
 
42936
+ const getPost$1 = async (postId) => {
42937
+ const client = getActiveClient();
42938
+ client.log('post/getPost', postId);
42939
+ isInTombstone('post', postId);
42940
+ let payload;
42941
+ try {
42942
+ // API-FIX: endpoint should not be /list, parameters should be querystring.
42943
+ const response = await client.http.get(`/api/v3/posts/${encodeURIComponent(postId)}`);
42944
+ payload = response.data;
42945
+ }
42946
+ catch (error) {
42947
+ if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
42948
+ pushToTombstone('post', postId);
42949
+ }
42950
+ throw error;
42951
+ }
42952
+ const data = prepareMembershipPayload(payload, 'communityUsers');
42953
+ const cachedAt = client.cache && Date.now();
42954
+ if (client.cache)
42955
+ ingestInCache(data, { cachedAt });
42956
+ const { posts } = data;
42957
+ const result = posts.find(post => post.postId === postId);
42958
+ return {
42959
+ data: result,
42960
+ cachedAt,
42961
+ };
42962
+ };
42963
+ getPost$1.locally = (postId) => {
42964
+ const client = getActiveClient();
42965
+ client.log('post/getPost.locally', postId);
42966
+ if (!client.cache)
42967
+ return;
42968
+ const cached = pullFromCache(['post', 'get', postId]);
42969
+ if (!cached)
42970
+ return;
42971
+ return {
42972
+ data: cached.data,
42973
+ cachedAt: cached.cachedAt,
42974
+ };
42975
+ };
42976
+
42540
42977
  class UserFeedLiveCollectionController extends LiveCollectionController {
42541
42978
  constructor(query, callback) {
42542
42979
  const queryStreamId = hash(query);
@@ -42670,12 +43107,240 @@ const getUserFeed = (params, callback, config) => {
42670
43107
  };
42671
43108
  /* end_public_function */
42672
43109
 
43110
+ class CommunityFeedPaginationController extends PaginationController {
43111
+ async getRequest(queryParams, token) {
43112
+ const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT, includeDeleted, communityId } = queryParams, params = __rest(queryParams, ["limit", "includeDeleted", "communityId"]);
43113
+ const options = token ? { token } : { limit };
43114
+ const { data: queryResponse } = await this.http.get(`/api/v5/posts`, {
43115
+ params: Object.assign(Object.assign({}, params), { targetId: communityId, targetType: 'community', isDeleted: inferIsDeleted(includeDeleted), matchingOnlyParentPost: true, options }),
43116
+ });
43117
+ return queryResponse;
43118
+ }
43119
+ }
43120
+
43121
+ class CommunityFeedQueryStreamController extends QueryStreamController {
43122
+ constructor(query, cacheKey, notifyChange, preparePayload) {
43123
+ super(query, cacheKey);
43124
+ this.notifyChange = notifyChange;
43125
+ this.preparePayload = preparePayload;
43126
+ }
43127
+ async saveToMainDB(response) {
43128
+ const processedPayload = await this.preparePayload(response);
43129
+ const client = getActiveClient();
43130
+ const cachedAt = client.cache && Date.now();
43131
+ if (client.cache) {
43132
+ ingestInCache(processedPayload, { cachedAt });
43133
+ }
43134
+ }
43135
+ appendToQueryStream(response, direction, refresh = false) {
43136
+ var _a, _b;
43137
+ if (refresh) {
43138
+ pushToCache(this.cacheKey, {
43139
+ data: response.posts.map(getResolver('post')),
43140
+ });
43141
+ }
43142
+ else {
43143
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
43144
+ const posts = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
43145
+ pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [...new Set([...posts, ...response.posts.map(getResolver('post'))])] }));
43146
+ }
43147
+ }
43148
+ reactor(action) {
43149
+ return (post) => {
43150
+ var _a, _b;
43151
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
43152
+ if (!collection)
43153
+ return;
43154
+ if (action === EnumPostActions.OnPostDeleted) {
43155
+ collection.data = collection.data.filter(postId => postId !== post.postId);
43156
+ }
43157
+ if (post.parentPostId && post.isDeleted) {
43158
+ const parentPost = (_b = pullFromCache([
43159
+ 'post',
43160
+ 'get',
43161
+ post.parentPostId,
43162
+ ])) === null || _b === void 0 ? void 0 : _b.data;
43163
+ if (!parentPost)
43164
+ return;
43165
+ parentPost.children = parentPost.children.filter(childId => childId !== post.postId);
43166
+ pushToCache(['post', 'get', parentPost.postId], parentPost);
43167
+ }
43168
+ if (action === EnumPostActions.OnPostDeclined) {
43169
+ collection.data = collection.data.filter(postId => postId !== post.postId);
43170
+ }
43171
+ if (action === EnumPostActions.OnPostCreated || action === EnumPostActions.OnPostApproved) {
43172
+ collection.data = [...new Set([post.postId, ...collection.data])];
43173
+ }
43174
+ pushToCache(this.cacheKey, collection);
43175
+ this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
43176
+ };
43177
+ }
43178
+ subscribeRTE(createSubscriber) {
43179
+ return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
43180
+ }
43181
+ }
43182
+
43183
+ const commentEventHandler = (callback, eventHandler, cacheKey, resolveId) => {
43184
+ return eventHandler(async (comment) => {
43185
+ var _a;
43186
+ const currentCollection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
43187
+ if (!currentCollection ||
43188
+ !currentCollection.data.includes(resolveId ? resolveId(comment.referenceId) : comment.referenceId))
43189
+ return;
43190
+ callback(comment);
43191
+ });
43192
+ };
43193
+ const generateCommentSubscriptions = ({ cacheKey, resolveId, }) => {
43194
+ const eventHandlers = [
43195
+ onCommentCreated,
43196
+ onCommentDeleted,
43197
+ onCommentCreatedLocal,
43198
+ onCommentDeleteLocal,
43199
+ ];
43200
+ return eventHandlers.map(handler => ({
43201
+ fn: convertEventPayload((callback) => commentEventHandler(callback, handler, cacheKey, resolveId), 'referenceId', 'post'),
43202
+ action: EnumPostActions.OnPostUpdated,
43203
+ }));
43204
+ };
43205
+ const getPostSubscription = (cacheKey) => {
43206
+ return [
43207
+ { fn: onPostCreated, action: EnumPostActions.OnPostCreated },
43208
+ { fn: onPostUpdated, action: EnumPostActions.OnPostUpdated },
43209
+ { fn: onPostUpdatedLocal, action: EnumPostActions.OnPostUpdated },
43210
+ { fn: onPostDeleted, action: EnumPostActions.OnPostDeleted },
43211
+ { fn: onPostFlagged, action: EnumPostActions.OnPostFlagged },
43212
+ { fn: onPostUnflagged, action: EnumPostActions.OnPostUnflagged },
43213
+ { fn: onPostApproved, action: EnumPostActions.OnPostApproved },
43214
+ { fn: onPostDeclined, action: EnumPostActions.OnPostDeclined },
43215
+ { fn: onPostReactionAdded, action: EnumPostActions.OnPostReactionAdded },
43216
+ { fn: onPostReactionRemoved, action: EnumPostActions.OnPostReactionRemoved },
43217
+ { fn: onLocalPostReactionAdded, action: EnumPostActions.OnPostReactionAdded },
43218
+ { fn: onLocalPostReactionRemoved, action: EnumPostActions.OnPostReactionRemoved },
43219
+ { fn: onLocalPostDeleted, action: EnumPostActions.OnPostDeleted },
43220
+ ...generateCommentSubscriptions({ cacheKey }),
43221
+ ];
43222
+ };
43223
+ const resolvePostIdsFromRooms = (rooms, posts) => {
43224
+ var _a;
43225
+ return ((_a = rooms
43226
+ .map(room => {
43227
+ const post = posts.find(post => post.postId === room.referenceId);
43228
+ return post ? getResolver('post')({ postId: post === null || post === void 0 ? void 0 : post.postId }) : undefined;
43229
+ })
43230
+ .filter(isNonNullable)) !== null && _a !== void 0 ? _a : []);
43231
+ };
43232
+
43233
+ class CommunityFeedLiveCollectionController extends LiveCollectionController {
43234
+ constructor(query, callback) {
43235
+ const queryStreamId = hash(query);
43236
+ const cacheKey = ['communityFeed', 'collection', queryStreamId];
43237
+ const paginationController = new CommunityFeedPaginationController(query);
43238
+ super(paginationController, queryStreamId, cacheKey, callback);
43239
+ this.query = query;
43240
+ this.queryStreamController = new CommunityFeedQueryStreamController(this.query, this.cacheKey, this.notifyChange.bind(this), preparePostPayload);
43241
+ this.callback = callback.bind(this);
43242
+ this.loadPage({ initial: true });
43243
+ }
43244
+ setup() {
43245
+ var _a;
43246
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
43247
+ if (!collection) {
43248
+ pushToCache(this.cacheKey, {
43249
+ data: [],
43250
+ params: {},
43251
+ });
43252
+ }
43253
+ }
43254
+ async persistModel(queryPayload) {
43255
+ await this.queryStreamController.saveToMainDB(queryPayload);
43256
+ }
43257
+ persistQueryStream({ response, direction, refresh, }) {
43258
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
43259
+ }
43260
+ startSubscription() {
43261
+ return this.queryStreamController.subscribeRTE(getPostSubscription(this.cacheKey));
43262
+ }
43263
+ notifyChange({ origin, loading, error }) {
43264
+ var _a, _b;
43265
+ const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
43266
+ if (!collection)
43267
+ return;
43268
+ const data = ((_b = collection.data
43269
+ .map(id => pullFromCache(['post', 'get', id]))
43270
+ .filter(isNonNullable)
43271
+ .map(({ data }) => data)) !== null && _b !== void 0 ? _b : []).map(LinkedObject.post);
43272
+ if (!this.shouldNotify(data) && origin === 'event')
43273
+ return;
43274
+ this.callback({
43275
+ onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
43276
+ data,
43277
+ hasNextPage: !!this.paginationController.getNextToken(),
43278
+ loading,
43279
+ error,
43280
+ });
43281
+ }
43282
+ }
43283
+
43284
+ /* begin_public_function
43285
+ id: feed.query.community_feed
43286
+ */
43287
+ /**
43288
+ * ```js
43289
+ * import { FeedRepository } from '@amityco/ts-sdk'
43290
+ *
43291
+ * let posts = []
43292
+ * const unsubscribe = FeedRepository.getCommunityFeed({
43293
+ * communityId: 'community-id',
43294
+ * sortBy?: 'lastCreated' | 'firstCreated' | 'lastUpdated' | 'firstUpdated',
43295
+ * includeDeleted?: boolean,
43296
+ * feedType?: 'reviewing' | 'published' | 'declined',
43297
+ * tags?: string[],
43298
+ * includeMixedStructure?: boolean,
43299
+ * limit?: number,
43300
+ * }, response => processResponse(response))
43301
+ * ```
43302
+ *
43303
+ * Observe all mutations on a list of {@link Amity.Post} for a given community feed.
43304
+ *
43305
+ * @param params - Parameters for querying the community feed:
43306
+ * @param params.communityId The ID of the community (required)
43307
+ * @param params.sortBy The sorting order of the feed (optional)
43308
+ * @param params.includeDeleted Whether to include deleted posts (optional)
43309
+ * @param params.feedType The type of the feed: 'reviewing', 'published', or 'declined' (optional)
43310
+ * @param params.tags Array of tags to filter posts (optional)
43311
+ * @param params.includeMixedStructure Whether to include mixed structure posts (optional)
43312
+ * @param params.limit The maximum number of posts to retrieve (optional)
43313
+ * @param callback The function to call when new data are available
43314
+ * @param config Additional live collection configuration (optional)
43315
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the feed
43316
+ *
43317
+ * @category Posts Live Collection
43318
+ */
43319
+ const getCommunityFeed = (params, callback, config) => {
43320
+ const { log, cache } = getActiveClient();
43321
+ if (!cache) {
43322
+ console.log(ENABLE_CACHE_MESSAGE);
43323
+ }
43324
+ const timestamp = Date.now();
43325
+ log(`getCommunityFeed(tmpid: ${timestamp}) > listen`);
43326
+ const communityFeedLiveCollection = new CommunityFeedLiveCollectionController(params, callback);
43327
+ const disposers = communityFeedLiveCollection.startSubscription();
43328
+ const cacheKey = communityFeedLiveCollection.getCacheKey();
43329
+ disposers.push(() => dropFromCache(cacheKey));
43330
+ return () => {
43331
+ log(`getCommunityFeed(tmpid: ${timestamp}) > dispose`);
43332
+ disposers.forEach(fn => fn());
43333
+ };
43334
+ };
43335
+ /* end_public_function */
43336
+
42673
43337
  var index$c = /*#__PURE__*/Object.freeze({
42674
43338
  __proto__: null,
42675
43339
  queryGlobalFeed: queryGlobalFeed,
42676
43340
  getCustomRankingGlobalFeed: getCustomRankingGlobalFeed,
42677
43341
  getGlobalFeed: getGlobalFeed,
42678
- getUserFeed: getUserFeed
43342
+ getUserFeed: getUserFeed,
43343
+ getCommunityFeed: getCommunityFeed
42679
43344
  });
42680
43345
 
42681
43346
  /* begin_public_function
@@ -43421,61 +44086,6 @@ class PostQueryStreamController extends QueryStreamController {
43421
44086
  }
43422
44087
  }
43423
44088
 
43424
- const commentEventHandler = (callback, eventHandler, cacheKey, resolveId) => {
43425
- return eventHandler(async (comment) => {
43426
- var _a;
43427
- const currentCollection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
43428
- if (!currentCollection ||
43429
- !currentCollection.data.includes(resolveId ? resolveId(comment.referenceId) : comment.referenceId))
43430
- return;
43431
- await getPost$1(comment.referenceId);
43432
- callback(comment);
43433
- });
43434
- };
43435
- const generateCommentSubscriptions = ({ cacheKey, resolveId, }) => {
43436
- const eventHandlers = [
43437
- onCommentCreated,
43438
- onCommentDeleted,
43439
- onCommentReactionAdded,
43440
- onCommentReactionRemoved,
43441
- onCommentCreatedLocal,
43442
- onCommentDeleteLocal,
43443
- onLocalCommentReactionAdded,
43444
- onLocalCommentReactionRemoved,
43445
- ];
43446
- return eventHandlers.map(handler => ({
43447
- fn: convertEventPayload((callback) => commentEventHandler(callback, handler, cacheKey, resolveId), 'referenceId', 'post'),
43448
- action: EnumPostActions.OnPostUpdated,
43449
- }));
43450
- };
43451
- const getPostSubscription = (cacheKey) => {
43452
- return [
43453
- { fn: onPostCreated, action: EnumPostActions.OnPostCreated },
43454
- { fn: onPostUpdated, action: EnumPostActions.OnPostUpdated },
43455
- { fn: onPostUpdatedLocal, action: EnumPostActions.OnPostUpdated },
43456
- { fn: onPostDeleted, action: EnumPostActions.OnPostDeleted },
43457
- { fn: onPostFlagged, action: EnumPostActions.OnPostFlagged },
43458
- { fn: onPostUnflagged, action: EnumPostActions.OnPostUnflagged },
43459
- { fn: onPostApproved, action: EnumPostActions.OnPostApproved },
43460
- { fn: onPostDeclined, action: EnumPostActions.OnPostDeclined },
43461
- { fn: onPostReactionAdded, action: EnumPostActions.OnPostReactionAdded },
43462
- { fn: onPostReactionRemoved, action: EnumPostActions.OnPostReactionRemoved },
43463
- { fn: onLocalPostReactionAdded, action: EnumPostActions.OnPostReactionAdded },
43464
- { fn: onLocalPostReactionRemoved, action: EnumPostActions.OnPostReactionRemoved },
43465
- { fn: onLocalPostDeleted, action: EnumPostActions.OnPostDeleted },
43466
- ...generateCommentSubscriptions({ cacheKey }),
43467
- ];
43468
- };
43469
- const resolvePostIdsFromRooms = (rooms, posts) => {
43470
- var _a;
43471
- return ((_a = rooms
43472
- .map(room => {
43473
- const post = posts.find(post => post.postId === room.referenceId);
43474
- return post ? getResolver('post')({ postId: post === null || post === void 0 ? void 0 : post.postId }) : undefined;
43475
- })
43476
- .filter(isNonNullable)) !== null && _a !== void 0 ? _a : []);
43477
- };
43478
-
43479
44089
  class PostLiveCollectionController extends LiveCollectionController {
43480
44090
  constructor(query, callback) {
43481
44091
  const queryStreamId = hash(query);
@@ -49839,4 +50449,4 @@ var index = /*#__PURE__*/Object.freeze({
49839
50449
  getRSVPs: getRSVPs
49840
50450
  });
49841
50451
 
49842
- export { API_REGIONS, index$4 as AdRepository, AmityCommunityType, AmityEventOrderOption, AmityEventOriginType, AmityEventResponseStatus, AmityEventSortOption, AmityEventStatus, AmityEventType, index$e as CategoryRepository, index$i as ChannelRepository, index$r as Client, index$d as CommentRepository, CommunityPostSettingMaps, CommunityPostSettings, index$f as CommunityRepository, ContentFeedType, ContentFlagReasonEnum, DefaultCommunityPostSetting, index as EventRepository, FeedDataTypeEnum, index$c as FeedRepository, FeedSortByEnum, FeedSourceEnum, FileAccessTypeEnum, index$o as FileRepository, FileType, GET_WATCHER_URLS, index$2 as InvitationRepository, InvitationSortByEnum, InvitationStatusEnum, InvitationTargetTypeEnum, InvitationTypeEnum, JoinRequestStatusEnum, JoinResultStatusEnum, index$1 as LiveReactionRepository, index$6 as LiveStreamPlayer, MembershipAcceptanceTypeEnum, MessageContentType, index$m as MessageRepository, index$7 as PollRepository, PostContentType, index$a as PostRepository, PostStructureType, index$n as ReactionRepository, index$8 as RoomPresenceRepository, index$b as RoomRepository, index$5 as StoryRepository, index$9 as StreamRepository, index$l as SubChannelRepository, SubscriptionLevels, index$p as UserRepository, UserTypeEnum, VERSION, VideoResolution, VideoSize, VideoTranscodingStatus, backupCache, createQuery, createReport, createUserToken, deleteReport, disableCache, dropFromCache, enableCache, filterByChannelMembership, filterByCommunityMembership, filterByFeedType, filterByPostDataTypes, filterByPropEquality, filterByPropInclusion, filterByPropIntersection, filterBySearchTerm, filterByStringComparePartially, getChannelTopic, getCommentTopic, getCommunityStoriesTopic, getCommunityTopic, getLiveReactionTopic, getLiveStreamTopic, getMarkedMessageTopic, getMarkerUserFeedTopic, getMessageTopic, getMyFollowersTopic, getMyFollowingsTopic, getNetworkTopic, getPostTopic, getRole, getRoomStreamerTopic, getRoomWatcherTopic, getSmartFeedChannelTopic, getSmartFeedMessageTopic, getSmartFeedSubChannelTopic, getStoryTopic, getSubChannelTopic, getUserTopic, isAfterBefore, isAfterBeforeRaw, isCachable, isFetcher, isFresh, isLocal, isMutator, isOffline, isPaged, isReportedByMe, isSkip, mergeInCache, index$3 as notificationTray, onChannelMarkerFetched, onFeedMarkerFetched, onFeedMarkerUpdated, onMessageMarked, onMessageMarkerFetched, onSubChannelMarkerFetched, onSubChannelMarkerUpdated, onUserMarkerFetched, onUserMarkerFetchedLegacy, pullFromCache, pushToCache, queryCache, queryOptions, queryRoles, restoreCache, runQuery, sortByChannelSegment, sortByDisplayName, sortByFirstCreated, sortByFirstUpdated, sortByLastActivity, sortByLastCreated, sortByLastUpdated, sortByLocalSortingDate, sortByName, sortBySegmentNumber, subscribeTopic, toPage, toPageRaw, toToken, upsertInCache, wipeCache };
50452
+ export { API_REGIONS, index$4 as AdRepository, AmityCommunityType, AmityEventOrderOption, AmityEventOriginType, AmityEventResponseStatus, AmityEventSortOption, AmityEventStatus, AmityEventType, index$e as CategoryRepository, index$i as ChannelRepository, index$r as Client, index$d as CommentRepository, CommunityPostSettingMaps, CommunityPostSettings, index$f as CommunityRepository, ContentFeedType, ContentFlagReasonEnum, DefaultCommunityPostSetting, index as EventRepository, FeedDataTypeEnum, index$c as FeedRepository, FeedSortByEnum, FeedSourceEnum, FeedTypeEnum, FileAccessTypeEnum, index$o as FileRepository, FileType, GET_WATCHER_URLS, index$2 as InvitationRepository, InvitationSortByEnum, InvitationStatusEnum, InvitationTargetTypeEnum, InvitationTypeEnum, JoinRequestStatusEnum, JoinResultStatusEnum, index$1 as LiveReactionRepository, index$6 as LiveStreamPlayer, MembershipAcceptanceTypeEnum, MessageContentType, index$m as MessageRepository, index$7 as PollRepository, PostContentType, index$a as PostRepository, PostStructureType, index$n as ReactionRepository, index$8 as RoomPresenceRepository, index$b as RoomRepository, index$5 as StoryRepository, index$9 as StreamRepository, index$l as SubChannelRepository, SubscriptionLevels, index$p as UserRepository, UserTypeEnum, VERSION, VideoResolution, VideoSize, VideoTranscodingStatus, backupCache, createQuery, createReport, createUserToken, deleteReport, disableCache, dropFromCache, enableCache, filterByChannelMembership, filterByCommunityMembership, filterByFeedType, filterByPostDataTypes, filterByPropEquality, filterByPropInclusion, filterByPropIntersection, filterBySearchTerm, filterByStringComparePartially, getChannelTopic, getCommentTopic, getCommunityStoriesTopic, getCommunityTopic, getLiveReactionTopic, getLiveStreamTopic, getMarkedMessageTopic, getMarkerUserFeedTopic, getMessageTopic, getMyFollowersTopic, getMyFollowingsTopic, getNetworkTopic, getPostTopic, getRole, getRoomStreamerTopic, getRoomWatcherTopic, getSmartFeedChannelTopic, getSmartFeedMessageTopic, getSmartFeedSubChannelTopic, getStoryTopic, getSubChannelTopic, getUserTopic, isAfterBefore, isAfterBeforeRaw, isCachable, isFetcher, isFresh, isLocal, isMutator, isOffline, isPaged, isReportedByMe, isSkip, mergeInCache, index$3 as notificationTray, onChannelMarkerFetched, onFeedMarkerFetched, onFeedMarkerUpdated, onMessageMarked, onMessageMarkerFetched, onSubChannelMarkerFetched, onSubChannelMarkerUpdated, onUserMarkerFetched, onUserMarkerFetchedLegacy, pullFromCache, pushToCache, queryCache, queryOptions, queryRoles, restoreCache, runQuery, sortByChannelSegment, sortByDisplayName, sortByFirstCreated, sortByFirstUpdated, sortByLastActivity, sortByLastCreated, sortByLastUpdated, sortByLocalSortingDate, sortByName, sortBySegmentNumber, subscribeTopic, toPage, toPageRaw, toToken, upsertInCache, wipeCache };